Provisioning: Use go-git wrapper for export (#100333)
This commit is contained in:
1 parent
3810aea532
commit
f464dc79e0
18 files changed
+630
-135
No files matched your search
+17
-17
@@ -2212,8 +2212,7 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "7"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "8"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "9"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "10"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "11"]
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "10"]
|
||||
],
|
||||
"public/app/features/alerting/unified/components/rule-editor/GrafanaFolderAndLabelsStep.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
|
||||
@@ -5727,18 +5726,7 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "29"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "30"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "31"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "32"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "33"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "34"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "35"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "36"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "37"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "38"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "39"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "40"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "41"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "42"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "43"]
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "32"]
|
||||
],
|
||||
"public/app/features/provisioning/DeleteRepositoryButton.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
|
||||
@@ -5760,9 +5748,8 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "8"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "9"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "10"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "11"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "12"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "13"]
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "11"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "12"]
|
||||
],
|
||||
"public/app/features/provisioning/FileHistoryPage.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
|
||||
@@ -5840,6 +5827,19 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"]
|
||||
],
|
||||
"public/app/features/provisioning/TokenPermissionsInfo.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "3"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "4"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "5"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "6"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "7"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "8"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "9"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "10"]
|
||||
],
|
||||
"public/app/features/provisioning/api/index.ts:5381": [
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
|
||||
|
||||
@@ -22,7 +22,7 @@ require (
|
||||
github.com/Masterminds/semver v1.5.0 // @grafana/grafana-backend-group
|
||||
github.com/Masterminds/semver/v3 v3.3.0 // @grafana/grafana-developer-enablement-squad
|
||||
github.com/Masterminds/sprig/v3 v3.3.0 // @grafana/grafana-backend-group
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // @grafana/plugins-platform-backend
|
||||
github.com/ProtonMail/go-crypto v1.1.5 // @grafana/plugins-platform-backend
|
||||
github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f // @grafana/grafana-backend-group
|
||||
github.com/alicebob/miniredis/v2 v2.33.0 // @grafana/alerting-backend
|
||||
github.com/andybalholm/brotli v1.1.1 // @grafana/partner-datasources
|
||||
@@ -47,6 +47,8 @@ require (
|
||||
github.com/fullstorydev/grpchan v1.1.1 // @grafana/grafana-backend-group
|
||||
github.com/gchaincl/sqlhooks v1.3.0 // @grafana/grafana-search-and-storage
|
||||
github.com/getkin/kin-openapi v0.129.0 // @grafana/grafana-app-platform-squad
|
||||
github.com/go-git/go-billy/v5 v5.6.2 // @grafana/grafana-app-platform-squad
|
||||
github.com/go-git/go-git/v5 v5.13.2 // @grafana/grafana-app-platform-squad
|
||||
github.com/go-jose/go-jose/v3 v3.0.3 // @grafana/identity-access-team
|
||||
github.com/go-kit/log v0.2.1 // @grafana/grafana-backend-group
|
||||
github.com/go-ldap/ldap/v3 v3.4.4 // @grafana/identity-access-team
|
||||
@@ -244,6 +246,7 @@ require (
|
||||
github.com/FZambia/eagle v0.1.0 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/squirrel v1.5.4 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
||||
github.com/RoaringBitmap/roaring v1.9.3 // indirect
|
||||
github.com/Yiling-J/theine-go v0.6.0 // indirect
|
||||
@@ -312,6 +315,7 @@ require (
|
||||
github.com/coreos/go-semver v0.3.1 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.3.6 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dennwc/varint v1.0.0 // indirect
|
||||
github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc // indirect
|
||||
@@ -334,6 +338,7 @@ require (
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||
github.com/gammazero/deque v0.2.1 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
@@ -386,6 +391,7 @@ require (
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
github.com/jackc/pgx/v5 v5.7.2 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
|
||||
github.com/jcmturner/gofork v1.7.6 // indirect
|
||||
@@ -399,6 +405,7 @@ require (
|
||||
github.com/jpillora/backoff v1.0.0 // indirect
|
||||
github.com/jszwedko/go-datemath v0.1.1-0.20230526204004-640a500621d6 // indirect
|
||||
github.com/jtolds/gls v4.20.0+incompatible // indirect
|
||||
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
@@ -447,6 +454,7 @@ require (
|
||||
github.com/perimeterx/marshmallow v1.1.5 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.21 // indirect
|
||||
github.com/pires/go-proxyproto v0.7.0 // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.2 // indirect
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
|
||||
@@ -476,6 +484,7 @@ require (
|
||||
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c // indirect
|
||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/skeema/knownhosts v1.3.0 // indirect
|
||||
github.com/sony/gobreaker v0.5.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
@@ -493,6 +502,7 @@ require (
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
|
||||
github.com/yudai/pp v2.0.1+incompatible // indirect
|
||||
@@ -526,6 +536,7 @@ require (
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/src-d/go-errors.v1 v1.0.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.32.1 // indirect
|
||||
k8s.io/kms v0.32.1 // indirect
|
||||
|
||||
@@ -722,6 +722,7 @@ github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSC
|
||||
github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM=
|
||||
github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
@@ -731,8 +732,8 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/OneOfOne/xxhash v1.2.5 h1:zl/OfRA6nftbBK9qTohYBJ5xvw6C/oNKizR7cZGl3cI=
|
||||
github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
|
||||
github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4=
|
||||
github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
|
||||
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
@@ -777,6 +778,8 @@ github.com/alicebob/miniredis/v2 v2.33.0/go.mod h1:MhP4a3EU7aENRi9aO+tHfTBZicLqQ
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
||||
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
|
||||
@@ -941,7 +944,6 @@ github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZ
|
||||
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
|
||||
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
|
||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||
github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
|
||||
github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
|
||||
github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500 h1:6lhrsTEnloDPXyeZBvSYvQf8u86jbKehZPVDDlkgDl4=
|
||||
@@ -975,7 +977,6 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
|
||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
|
||||
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
|
||||
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
@@ -1013,6 +1014,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM=
|
||||
github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||
github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8=
|
||||
github.com/cznic/fileutil v0.0.0-20180108211300-6a051e75936f/go.mod h1:8S58EK26zhXSxzv7NQFpnliaOQsmDUxvoQO3rt154Vg=
|
||||
github.com/cznic/golex v0.0.0-20170803123110-4ab7c5e190e4/go.mod h1:+bmmJDNmKlhWNG+gwWCkaBoTy39Fs+bzRxVBzoTQbIc=
|
||||
@@ -1147,6 +1150,8 @@ github.com/getkin/kin-openapi v0.129.0 h1:QGYTNcmyP5X0AtFQ2Dkou9DGBJsUETeLH9rFrJ
|
||||
github.com/getkin/kin-openapi v0.129.0/go.mod h1:gmWI+b/J45xqpyK5wJmRRZse5wefA5H0RDMK46kLUtI=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
|
||||
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
|
||||
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A=
|
||||
@@ -1156,6 +1161,14 @@ github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3
|
||||
github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY=
|
||||
github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY=
|
||||
github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
||||
github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM=
|
||||
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
||||
github.com/go-git/go-git/v5 v5.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0=
|
||||
github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
@@ -1733,6 +1746,8 @@ github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI=
|
||||
github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
|
||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
|
||||
@@ -1793,6 +1808,8 @@ github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+
|
||||
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
||||
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs=
|
||||
github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
@@ -2079,6 +2096,8 @@ github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ
|
||||
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs=
|
||||
github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4=
|
||||
github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=
|
||||
github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
@@ -2251,8 +2270,11 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY=
|
||||
github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M=
|
||||
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY=
|
||||
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
|
||||
@@ -2371,6 +2393,8 @@ github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+x
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs=
|
||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
|
||||
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
|
||||
@@ -2545,7 +2569,6 @@ golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
@@ -3374,6 +3397,8 @@ gopkg.in/src-d/go-errors.v1 v1.0.0/go.mod h1:q1cBlomlw2FnDBDNGlnh6X0jPihy+QxZfMM
|
||||
gopkg.in/telebot.v3 v3.2.1/go.mod h1:GJKwwWqp9nSkIVN51eRKU78aB5f5OnQuWdwiIZfPbko=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
||||
+1
-3
@@ -1197,6 +1197,7 @@ github.com/brianvoe/gofakeit/v6 v6.25.0/go.mod h1:Xj58BMSnFqcn/fAQeSK+/PLtC5kSb7
|
||||
github.com/bufbuild/protovalidate-go v0.2.1 h1:pJr07sYhliyfj/STAM7hU4J3FKpVeLVKvOBmOTN8j+s=
|
||||
github.com/bufbuild/protovalidate-go v0.2.1/go.mod h1:e7XXDtlxj5vlEyAgsrxpzayp4cEMKCSSb8ZCkin+MVA=
|
||||
github.com/bwesterb/go-ristretto v1.2.3 h1:1w53tCkGhCQ5djbat3+MH0BAQ5Kfgbt56UZQ/JMzngw=
|
||||
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||
github.com/bytedance/sonic v1.10.0-rc3 h1:uNSnscRapXTwUgTyOF0GVljYD08p9X/Lbr9MweSV3V0=
|
||||
github.com/bytedance/sonic v1.10.0-rc3/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
|
||||
github.com/campoy/embedmd v1.0.0 h1:V4kI2qTJJLf4J29RzI/MAt2c3Bl4dQSYPuflzwFH2hY=
|
||||
@@ -1545,7 +1546,6 @@ github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grafana/alerting v0.0.0-20250115195200-209e052dba64/go.mod h1:QsnoKX/iYZxA4Cv+H+wC7uxutBD8qi8ZW5UJvD2TYmU=
|
||||
github.com/grafana/alerting v0.0.0-20250117230852-a5e8136407d4/go.mod h1:QsnoKX/iYZxA4Cv+H+wC7uxutBD8qi8ZW5UJvD2TYmU=
|
||||
github.com/grafana/alerting v0.0.0-20250117230852-a5e8136407d4/go.mod h1:QsnoKX/iYZxA4Cv+H+wC7uxutBD8qi8ZW5UJvD2TYmU=
|
||||
github.com/grafana/authlib v0.0.0-20250120144156-d6737a7dc8f5/go.mod h1:V63rh3udd7sqXJeaG+nGUmViwVnM/bY6t8U9Tols2GU=
|
||||
github.com/grafana/authlib/claims v0.0.0-20241202085737-df90af04f335 h1:3DHH81RJCi8Bcgn2MdBh7vgWUshmAFjZzBCVuxiQ0uk=
|
||||
github.com/grafana/authlib/claims v0.0.0-20241202085737-df90af04f335/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A=
|
||||
@@ -2713,8 +2713,6 @@ gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76
|
||||
gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg=
|
||||
gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98=
|
||||
gopkg.in/telebot.v3 v3.2.1 h1:3I4LohaAyJBiivGmkfB+CiVu7QFOWkuZ4+KHgO/G3rs=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||
|
||||
@@ -36,6 +36,8 @@ github.com/grafana/authlib v0.0.0-20250204100101-00a7f40e4029 h1:0C0a1FEkecxDk60
|
||||
github.com/grafana/authlib v0.0.0-20250204100101-00a7f40e4029/go.mod h1:/gYfphsNu9v1qYWXxpv1NSvMEMSwvdf8qb8YlgwIRl8=
|
||||
github.com/grafana/authlib/types v0.0.0-20250120145936-5f0e28e7a87c h1:b0sPDtt33uFdmvUJjSCld3kwE2E49dUvevuUDSJsEuo=
|
||||
github.com/grafana/authlib/types v0.0.0-20250120145936-5f0e28e7a87c/go.mod h1:qYjSd1tmJiuVoSICp7Py9/zD54O9uQQA3wuM6Gg4DFM=
|
||||
github.com/grafana/grafana-app-sdk/logging v0.30.0 h1:K/P/bm7Cp7Di4tqIJ3EQz2+842JozQGRaz62r95ApME=
|
||||
github.com/grafana/grafana-app-sdk/logging v0.30.0/go.mod h1:xy6ZyVXl50Z3DBDLybvBPphbykPhuVNed/VNmen9DQM=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
|
||||
@@ -699,6 +699,18 @@ func (m *grafanaMetaAccessor) FindTitle(defaultTitle string) string {
|
||||
}
|
||||
}
|
||||
|
||||
obj, ok := m.obj.(*unstructured.Unstructured)
|
||||
if ok {
|
||||
title, ok, _ := unstructured.NestedString(obj.Object, "spec", "title")
|
||||
if ok && title != "" {
|
||||
return title
|
||||
}
|
||||
title, ok, _ = unstructured.NestedString(obj.Object, "spec", "name")
|
||||
if ok && title != "" {
|
||||
return title
|
||||
}
|
||||
}
|
||||
|
||||
title := m.r.FieldByName("Title")
|
||||
if title.IsValid() && title.Kind() == reflect.String {
|
||||
return title.String()
|
||||
|
||||
@@ -194,6 +194,7 @@ func TestMetaAccessor(t *testing.T) {
|
||||
res.Object = map[string]any{
|
||||
"spec": map[string]any{
|
||||
"hello": "world",
|
||||
"title": "Title",
|
||||
},
|
||||
"status": map[string]any{
|
||||
"sloth": "🦥",
|
||||
@@ -218,6 +219,7 @@ func TestMetaAccessor(t *testing.T) {
|
||||
rv, err := meta.GetResourceVersionInt64()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, int64(12345), rv)
|
||||
require.Equal(t, "Title", meta.FindTitle(""))
|
||||
|
||||
// Make sure access to spec works for Unstructured
|
||||
spec, err = meta.GetSpec()
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
package export
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand/v2"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/logging"
|
||||
provisioning "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/provisioning/jobs"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/provisioning/repository"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
func dummyExport(
|
||||
ctx context.Context,
|
||||
repo repository.Repository,
|
||||
job provisioning.Job,
|
||||
progress jobs.ProgressFn,
|
||||
) (*provisioning.JobStatus, error) {
|
||||
options := job.Spec.Export
|
||||
logger := logging.FromContext(ctx).With("logger", "exporter", "repository", repo.Config().Name, "namespace", repo.Config().Name)
|
||||
logger.Info("start export", "folder", options.Folder)
|
||||
|
||||
size := 5 + rand.IntN(15)
|
||||
|
||||
dashboards := &provisioning.JobResourceSummary{
|
||||
Group: "dashboard.grafana.app",
|
||||
Resource: "dashboards",
|
||||
}
|
||||
status := provisioning.JobStatus{
|
||||
State: provisioning.JobStateWorking,
|
||||
Message: "exporting..." + repo.Config().Spec.Title,
|
||||
Progress: 0,
|
||||
}
|
||||
|
||||
if err := progress(ctx, status); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
for i := 0; i < size; i++ {
|
||||
status.Progress = (float64(i) / float64(size)) * 100
|
||||
sleep := time.Duration(400+rand.IntN(800)) * time.Millisecond
|
||||
status.Message, _ = util.GetRandomString(rand.IntN(10 + 15))
|
||||
time.Sleep(sleep)
|
||||
|
||||
for j := 0; j < (4 + rand.IntN(10)); j++ {
|
||||
switch rand.IntN(9) {
|
||||
case 0, 1, 2:
|
||||
dashboards.Create++
|
||||
case 3, 4:
|
||||
dashboards.Update++
|
||||
case 5:
|
||||
dashboards.Delete++
|
||||
case 6, 7, 8:
|
||||
dashboards.Noop++
|
||||
}
|
||||
}
|
||||
status.Summary = []*provisioning.JobResourceSummary{
|
||||
dashboards,
|
||||
}
|
||||
|
||||
if err := progress(ctx, status); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
status.State = provisioning.JobStateSuccess
|
||||
status.Message = fmt.Sprintf("pretended to export %d", size)
|
||||
status.Progress = 0
|
||||
|
||||
logger.Info("finished export", "folder", options.Folder)
|
||||
return &status, nil
|
||||
}
|
||||
@@ -39,6 +39,7 @@ type exportJob struct {
|
||||
prefix string // from options (now clean+safe)
|
||||
ref string // from options (only git)
|
||||
keepIdentifier bool
|
||||
addAuthorInfo bool
|
||||
|
||||
jobStatus *provisioning.JobStatus
|
||||
summary map[string]*provisioning.JobResourceSummary
|
||||
@@ -65,6 +66,7 @@ func newExportJob(ctx context.Context,
|
||||
prefix: prefix,
|
||||
ref: options.Branch,
|
||||
keepIdentifier: options.Identifier,
|
||||
addAuthorInfo: options.History,
|
||||
|
||||
jobStatus: &provisioning.JobStatus{
|
||||
State: provisioning.JobStateWorking,
|
||||
@@ -194,9 +196,15 @@ func (r *exportJob) add(ctx context.Context, summary *provisioning.JobResourceSu
|
||||
return err
|
||||
}
|
||||
|
||||
// Message from annotations
|
||||
commitMessage := item.GetMessage()
|
||||
if commitMessage == "" {
|
||||
commitMessage = "exported from grafana"
|
||||
g := item.GetGeneration()
|
||||
if g > 0 {
|
||||
commitMessage = fmt.Sprintf("Generation: %d, ResourceVersion: %s", g, item.GetResourceVersion())
|
||||
} else {
|
||||
commitMessage = "exported from grafana"
|
||||
}
|
||||
}
|
||||
|
||||
name := item.GetName()
|
||||
@@ -243,6 +251,9 @@ func (r *exportJob) add(ctx context.Context, summary *provisioning.JobResourceSu
|
||||
}
|
||||
}
|
||||
|
||||
// Add the author in context (if available)
|
||||
ctx = r.withAuthorSignature(ctx, item)
|
||||
|
||||
// Write the file
|
||||
err = r.target.Write(ctx, fileName, r.ref, body, commitMessage)
|
||||
if err != nil {
|
||||
@@ -257,3 +268,26 @@ func (r *exportJob) add(ctx context.Context, summary *provisioning.JobResourceSu
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *exportJob) withAuthorSignature(ctx context.Context, item utils.GrafanaMetaAccessor) context.Context {
|
||||
if !r.addAuthorInfo {
|
||||
return ctx
|
||||
}
|
||||
|
||||
sig := repository.CommitSignature{
|
||||
Name: item.GetUpdatedBy(),
|
||||
When: item.GetCreationTimestamp().Time,
|
||||
}
|
||||
if sig.Name == "" {
|
||||
sig.Name = item.GetCreatedBy()
|
||||
}
|
||||
if sig.Name == "" {
|
||||
return ctx // no user info
|
||||
}
|
||||
// TODO: convert internal id to name+email
|
||||
updated, _ := item.GetUpdatedTimestamp()
|
||||
if updated != nil {
|
||||
sig.When = *updated
|
||||
}
|
||||
return repository.WithAuthorSignature(ctx, sig)
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package export
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
@@ -10,15 +11,17 @@ import (
|
||||
provisioning "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/provisioning/jobs"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/provisioning/repository"
|
||||
gogit "github.com/grafana/grafana/pkg/registry/apis/provisioning/repository/go-git"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/provisioning/resources"
|
||||
)
|
||||
|
||||
type ExportWorker struct {
|
||||
clients *resources.ClientFactory
|
||||
clients *resources.ClientFactory
|
||||
clonedir string
|
||||
}
|
||||
|
||||
func NewExportWorker(clients *resources.ClientFactory) *ExportWorker {
|
||||
return &ExportWorker{clients}
|
||||
func NewExportWorker(clients *resources.ClientFactory, clonedir string) *ExportWorker {
|
||||
return &ExportWorker{clients, clonedir}
|
||||
}
|
||||
|
||||
func (r *ExportWorker) IsSupported(ctx context.Context, job provisioning.Job) bool {
|
||||
@@ -42,9 +45,32 @@ func (r *ExportWorker) Process(ctx context.Context, repo repository.Repository,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// TODO: remove this dummy export
|
||||
if job.Spec.Export.Branch == "*dummy*" {
|
||||
return dummyExport(ctx, repo, job, progress)
|
||||
var err error
|
||||
var buffered *gogit.GoGitRepo
|
||||
if repo.Config().Spec.GitHub != nil {
|
||||
buffered, err = gogit.Clone(ctx, repo.Config(), gogit.GoGitCloneOptions{
|
||||
Root: r.clonedir,
|
||||
SingleCommitBeforePush: !options.History,
|
||||
}, os.Stdout)
|
||||
if err != nil {
|
||||
return &provisioning.JobStatus{
|
||||
State: provisioning.JobStateError,
|
||||
Errors: []string{"Unable to clone target", err.Error()},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// New empty branch
|
||||
if options.Branch != "" {
|
||||
_, err := buffered.NewEmptyBranch(ctx, options.Branch)
|
||||
if err != nil {
|
||||
return &provisioning.JobStatus{
|
||||
State: provisioning.JobStateError,
|
||||
Errors: []string{"Unable to create empty branch", err.Error()},
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
repo = buffered // send all writes to the buffered repo
|
||||
options.Branch = "" // :( the branch is now baked into the repo
|
||||
}
|
||||
|
||||
dynamicClient, _, err := r.clients.New(repo.Config().Namespace)
|
||||
@@ -72,8 +98,15 @@ func (r *ExportWorker) Process(ctx context.Context, repo repository.Repository,
|
||||
}
|
||||
}
|
||||
|
||||
// Add summary info to response
|
||||
status := worker.jobStatus
|
||||
if buffered != nil && status.State != provisioning.JobStateError {
|
||||
status.Message = "pushing changes..."
|
||||
worker.maybeNotify(ctx) // force notify?
|
||||
err = buffered.Push(ctx, os.Stdout)
|
||||
status.Message = ""
|
||||
}
|
||||
|
||||
// Add summary info to response
|
||||
if !status.State.Finished() && err == nil {
|
||||
status.State = provisioning.JobStateSuccess
|
||||
status.Message = ""
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -72,6 +73,7 @@ type APIBuilder struct {
|
||||
client *resources.ClientFactory
|
||||
parsers *resources.ParserFactory
|
||||
ghFactory github.ClientFactory
|
||||
clonedir string // where repo clones are managed
|
||||
jobs jobs.JobQueue
|
||||
tester *RepositoryTester
|
||||
resourceLister resources.ResourceLister
|
||||
@@ -89,6 +91,7 @@ func NewAPIBuilder(
|
||||
render rendering.Service,
|
||||
index resource.RepositoryIndexClient,
|
||||
blobstore blob.PublicBlobStore,
|
||||
clonedir string, // where repo clones are managed
|
||||
configProvider apiserver.RestConfigProvider,
|
||||
ghFactory github.ClientFactory,
|
||||
) *APIBuilder {
|
||||
@@ -104,6 +107,7 @@ func NewAPIBuilder(
|
||||
Client: clientFactory,
|
||||
},
|
||||
render: render,
|
||||
clonedir: clonedir,
|
||||
resourceLister: resources.NewResourceLister(index),
|
||||
blobstore: blobstore,
|
||||
}
|
||||
@@ -141,7 +145,10 @@ func RegisterAPIService(
|
||||
return cfg.AppURL
|
||||
}
|
||||
|
||||
builder := NewAPIBuilder(folderResolver, urlProvider, cfg.SecretKey, features, render, client, store, configProvider, ghFactory)
|
||||
builder := NewAPIBuilder(folderResolver, urlProvider, cfg.SecretKey, features,
|
||||
render, client, store,
|
||||
filepath.Join(cfg.DataPath, "clone"), // where repositories are cloned (temporarialy for now)
|
||||
configProvider, ghFactory)
|
||||
apiregistration.RegisterAPI(builder)
|
||||
return builder, nil
|
||||
}
|
||||
@@ -448,7 +455,7 @@ func (b *APIBuilder) GetPostStartHooks() (map[string]genericapiserver.PostStartH
|
||||
}
|
||||
b.repositoryLister = repoInformer.Lister()
|
||||
|
||||
b.jobs.Register(export.NewExportWorker(b.client))
|
||||
b.jobs.Register(export.NewExportWorker(b.client, b.clonedir))
|
||||
b.jobs.Register(sync.NewSyncWorker(
|
||||
c.ProvisioningV0alpha1(),
|
||||
b.parsers,
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
// When writing values from history, we want the metadata to match Legacy grafana SQL
|
||||
type CommitSignature struct {
|
||||
// Name represents a person name. It is an arbitrary string.
|
||||
Name string
|
||||
// Email is an email, but it cannot be assumed to be well-formed.
|
||||
Email string
|
||||
// When is the timestamp of the signature.
|
||||
When time.Time
|
||||
}
|
||||
|
||||
type ctxAuthorKey struct{}
|
||||
|
||||
func WithAuthorSignature(ctx context.Context, sig CommitSignature) context.Context {
|
||||
return context.WithValue(ctx, ctxAuthorKey{}, sig)
|
||||
}
|
||||
|
||||
func GetAuthorSignature(ctx context.Context) *CommitSignature {
|
||||
u, ok := ctx.Value(ctxAuthorKey{}).(CommitSignature)
|
||||
if ok {
|
||||
copy := u
|
||||
return ©
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,344 @@
|
||||
package gogit
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/go-git/go-billy/v5/util"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
"github.com/go-git/go-git/v5/plumbing/object"
|
||||
githttp "github.com/go-git/go-git/v5/plumbing/transport/http"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
|
||||
provisioning "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/provisioning/repository"
|
||||
)
|
||||
|
||||
var (
|
||||
_ repository.Repository = (*GoGitRepo)(nil)
|
||||
)
|
||||
|
||||
type GoGitCloneOptions struct {
|
||||
Root string // tempdir (when empty, memory??)
|
||||
|
||||
// Skip intermediate commits and commit all before push
|
||||
SingleCommitBeforePush bool
|
||||
}
|
||||
|
||||
type GoGitRepo struct {
|
||||
config *provisioning.Repository
|
||||
opts GoGitCloneOptions
|
||||
|
||||
repo *git.Repository
|
||||
tree *git.Worktree
|
||||
dir string // file path to worktree root (necessary? should use billy)
|
||||
}
|
||||
|
||||
// This will create a new clone every time
|
||||
// As structured, it is valid for one context and should not be shared across multiple requests
|
||||
func Clone(
|
||||
ctx context.Context,
|
||||
config *provisioning.Repository,
|
||||
opts GoGitCloneOptions,
|
||||
progress io.Writer, // os.Stdout
|
||||
) (*GoGitRepo, error) {
|
||||
gitcfg := config.Spec.GitHub
|
||||
if gitcfg == nil {
|
||||
return nil, fmt.Errorf("missing github config")
|
||||
}
|
||||
if opts.Root == "" {
|
||||
return nil, fmt.Errorf("missing root config")
|
||||
}
|
||||
err := os.MkdirAll(opts.Root, 0700)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dir, err := mkdirTempClone(opts.Root, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("https://github.com/%s/%s.git", gitcfg.Owner, gitcfg.Repository)
|
||||
|
||||
repo, err := git.PlainOpen(dir)
|
||||
if err != nil {
|
||||
if !errors.Is(err, git.ErrRepositoryNotExists) {
|
||||
return nil, fmt.Errorf("error opening repository %w", err)
|
||||
}
|
||||
|
||||
repo, err = git.PlainCloneContext(ctx, dir, false, &git.CloneOptions{
|
||||
Auth: &githttp.BasicAuth{
|
||||
Username: "grafana", // this can be anything except an empty string for PAT
|
||||
Password: gitcfg.Token, // TODO... will need to get from a service!
|
||||
},
|
||||
URL: url,
|
||||
ReferenceName: plumbing.ReferenceName(gitcfg.Branch),
|
||||
Progress: progress,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("clone error %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
rcfg, err := repo.Config()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error readign repository config %w", err)
|
||||
}
|
||||
|
||||
origin := rcfg.Remotes["origin"]
|
||||
if origin == nil {
|
||||
return nil, fmt.Errorf("missing origin remote %w", err)
|
||||
}
|
||||
if url != origin.URLs[0] {
|
||||
return nil, fmt.Errorf("unexpected remote (expected:%s, found: %s)", url, origin.URLs[0])
|
||||
}
|
||||
|
||||
worktree, err := repo.Worktree()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = worktree.Checkout(&git.CheckoutOptions{
|
||||
Branch: plumbing.NewBranchReferenceName(gitcfg.Branch),
|
||||
Force: true, // clear any local changes
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to open branch %w", err)
|
||||
}
|
||||
|
||||
return &GoGitRepo{
|
||||
config: config,
|
||||
opts: opts,
|
||||
tree: worktree,
|
||||
repo: repo,
|
||||
dir: dir,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func mkdirTempClone(root string, config *provisioning.Repository) (string, error) {
|
||||
if config.Namespace == "" {
|
||||
return "", fmt.Errorf("config is missing namespace")
|
||||
}
|
||||
if config.Name == "" {
|
||||
return "", fmt.Errorf("config is missing name")
|
||||
}
|
||||
return os.MkdirTemp(root, fmt.Sprintf("clone-%s-%s-", config.Namespace, config.Name))
|
||||
}
|
||||
|
||||
// Remove everything from the tree
|
||||
func (g *GoGitRepo) NewEmptyBranch(ctx context.Context, branch string) (int64, error) {
|
||||
err := g.tree.Checkout(&git.CheckoutOptions{
|
||||
Branch: plumbing.NewBranchReferenceName(branch),
|
||||
Force: true, // clear any local changes
|
||||
Create: true,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
count := int64(0)
|
||||
return count, util.Walk(g.tree.Filesystem, "/", func(path string, info fs.FileInfo, err error) error {
|
||||
if err != nil || strings.HasPrefix(path, "/.git") || path == "/" {
|
||||
return err
|
||||
}
|
||||
if !info.IsDir() {
|
||||
count++
|
||||
_, err = g.tree.Remove(strings.TrimLeft(path, "/"))
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
// Affer making changes to the worktree, push changes
|
||||
func (g *GoGitRepo) Push(ctx context.Context, progress io.Writer) error {
|
||||
if g.opts.SingleCommitBeforePush {
|
||||
_, err := g.tree.Commit("exported from grafana", &git.CommitOptions{
|
||||
All: true, // Add everything that changed
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return g.repo.PushContext(ctx, &git.PushOptions{
|
||||
Progress: progress,
|
||||
Auth: &githttp.BasicAuth{ // reuse logic from clone?
|
||||
Username: "grafana",
|
||||
Password: g.config.Spec.GitHub.Token,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Config implements repository.Repository.
|
||||
func (g *GoGitRepo) Config() *provisioning.Repository {
|
||||
return g.config
|
||||
}
|
||||
|
||||
// ReadTree implements repository.Repository.
|
||||
func (g *GoGitRepo) ReadTree(ctx context.Context, ref string) ([]repository.FileTreeEntry, error) {
|
||||
entries := make([]repository.FileTreeEntry, 0, 100)
|
||||
err := util.Walk(g.tree.Filesystem, "/", func(path string, info fs.FileInfo, err error) error {
|
||||
if err != nil || strings.HasPrefix(path, "/.git") || path == "/" {
|
||||
return err
|
||||
}
|
||||
entry := repository.FileTreeEntry{
|
||||
Path: strings.TrimLeft(path, "/"),
|
||||
Size: info.Size(),
|
||||
}
|
||||
if !info.IsDir() {
|
||||
entry.Blob = true
|
||||
// For a real instance, this will likely be based on:
|
||||
// https://github.com/go-git/go-git/blob/main/_examples/ls/main.go#L25
|
||||
entry.Hash = fmt.Sprintf("TODO/%d", info.Size()) // but not used for
|
||||
}
|
||||
entries = append(entries, entry)
|
||||
return err
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return entries, err
|
||||
}
|
||||
|
||||
func (g *GoGitRepo) Test(ctx context.Context) (*provisioning.TestResults, error) {
|
||||
return &provisioning.TestResults{
|
||||
Success: g.tree != nil,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Update implements repository.Repository.
|
||||
func (g *GoGitRepo) Update(ctx context.Context, path string, ref string, data []byte, message string) error {
|
||||
return g.Write(ctx, path, ref, data, message)
|
||||
}
|
||||
|
||||
// Create implements repository.Repository.
|
||||
func (g *GoGitRepo) Create(ctx context.Context, path string, ref string, data []byte, message string) error {
|
||||
return g.Write(ctx, path, ref, data, message)
|
||||
}
|
||||
|
||||
// Write implements repository.Repository.
|
||||
func (g *GoGitRepo) Write(ctx context.Context, fpath string, ref string, data []byte, message string) error {
|
||||
if err := verifyPathWithoutRef(fpath, ref); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// For folders, just create the folder and ignore the commit
|
||||
if strings.HasSuffix(fpath, "/") {
|
||||
return g.tree.Filesystem.MkdirAll(fpath, 0750)
|
||||
}
|
||||
|
||||
dir := path.Dir(fpath)
|
||||
if dir != "" {
|
||||
err := g.tree.Filesystem.MkdirAll(dir, 0750)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
file, err := g.tree.Filesystem.Create(fpath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = file.Write(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = g.tree.Add(fpath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Skip commit for each file
|
||||
if g.opts.SingleCommitBeforePush {
|
||||
return nil
|
||||
}
|
||||
|
||||
opts := &git.CommitOptions{}
|
||||
sig := repository.GetAuthorSignature(ctx)
|
||||
if sig != nil {
|
||||
opts.Author = &object.Signature{
|
||||
Name: sig.Name,
|
||||
Email: sig.Email,
|
||||
When: sig.When,
|
||||
}
|
||||
}
|
||||
_, err = g.tree.Commit(message, opts)
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete implements repository.Repository.
|
||||
func (g *GoGitRepo) Delete(ctx context.Context, path string, ref string, message string) error {
|
||||
return g.tree.Filesystem.Remove(path) // missing slash
|
||||
}
|
||||
|
||||
// Read implements repository.Repository.
|
||||
func (g *GoGitRepo) Read(ctx context.Context, path string, ref string) (*repository.FileInfo, error) {
|
||||
stat, err := g.tree.Filesystem.Lstat(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
info := &repository.FileInfo{
|
||||
Path: path,
|
||||
Modified: &metav1.Time{
|
||||
Time: stat.ModTime(),
|
||||
},
|
||||
}
|
||||
if !stat.IsDir() {
|
||||
f, err := g.tree.Filesystem.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
info.Data, err = io.ReadAll(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return info, err
|
||||
}
|
||||
|
||||
func verifyPathWithoutRef(path string, ref string) error {
|
||||
if path == "" {
|
||||
return fmt.Errorf("expected path")
|
||||
}
|
||||
if ref != "" {
|
||||
return fmt.Errorf("ref unsupported")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// History implements repository.Repository.
|
||||
func (g *GoGitRepo) History(ctx context.Context, path string, ref string) ([]provisioning.HistoryItem, error) {
|
||||
return nil, &apierrors.StatusError{
|
||||
ErrStatus: metav1.Status{
|
||||
Message: "history is not yet implemented",
|
||||
Code: http.StatusNotImplemented,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Validate implements repository.Repository.
|
||||
func (g *GoGitRepo) Validate() field.ErrorList {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Webhook implements repository.Repository.
|
||||
func (g *GoGitRepo) Webhook(ctx context.Context, req *http.Request) (*provisioning.WebhookResponse, error) {
|
||||
return nil, &apierrors.StatusError{
|
||||
ErrStatus: metav1.Status{
|
||||
Message: "history is not yet implemented",
|
||||
Code: http.StatusNotImplemented,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package gogit
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/provisioning/repository"
|
||||
)
|
||||
|
||||
// FIXME!! NOTE!!!!!
|
||||
// This is really just a sketchpad while trying to get things working
|
||||
// the test makes destructive changes to a real git repository :)
|
||||
// this should be removed before commiting to main (likely sooner)
|
||||
// and replaced with integratino tests that check the more specific results
|
||||
func TestGoGitWrapper(t *testing.T) {
|
||||
token, ok := os.LookupEnv("gitwraptoken")
|
||||
if !ok {
|
||||
t.Skipf("no token found in environment")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
wrap, err := Clone(ctx, &v0alpha1.Repository{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Namespace: "ns",
|
||||
Name: "unit-tester",
|
||||
},
|
||||
Spec: v0alpha1.RepositorySpec{
|
||||
GitHub: &v0alpha1.GitHubRepositoryConfig{
|
||||
Owner: "grafana",
|
||||
Repository: "git-ui-sync-demo",
|
||||
Branch: "ryan-test",
|
||||
Token: token,
|
||||
},
|
||||
},
|
||||
},
|
||||
GoGitCloneOptions{
|
||||
Root: "testdata/clone", // where things are cloned,
|
||||
// one commit (not 11)
|
||||
SingleCommitBeforePush: true,
|
||||
},
|
||||
os.Stdout)
|
||||
require.NoError(t, err)
|
||||
|
||||
tree, err := wrap.ReadTree(ctx, "")
|
||||
require.NoError(t, err)
|
||||
|
||||
jj, err := json.MarshalIndent(tree, "", " ")
|
||||
require.NoError(t, err)
|
||||
|
||||
fmt.Printf("TREE:%s\n", string(jj))
|
||||
|
||||
branch := fmt.Sprintf("unit-test-%s", time.Now().Format("20060102-150405")) // the branch name to create
|
||||
|
||||
count, err := wrap.NewEmptyBranch(ctx, branch)
|
||||
require.NoError(t, err)
|
||||
fmt.Printf("REMOVED: %d\n", count)
|
||||
|
||||
ctx = repository.WithAuthorSignature(ctx, repository.CommitSignature{
|
||||
Name: "xxxxx",
|
||||
Email: "rrr@yyyy.zzz",
|
||||
When: time.Now(),
|
||||
})
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
fname := fmt.Sprintf("deep/path/in/test_%d.txt", i)
|
||||
fmt.Printf("Write:%s\n", fname)
|
||||
err = wrap.Write(ctx, fname, "", []byte(fmt.Sprintf("body/%d %s", i, time.Now())), "the commit message")
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
fmt.Printf("push...\n")
|
||||
err = wrap.Push(ctx, os.Stdout)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
@@ -51,8 +51,7 @@ require (
|
||||
github.com/Masterminds/semver/v3 v3.3.0 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.3.0 // indirect
|
||||
github.com/Masterminds/squirrel v1.5.4 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.1.5 // indirect
|
||||
github.com/RoaringBitmap/roaring v1.9.3 // indirect
|
||||
github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f // indirect
|
||||
github.com/Yiling-J/theine-go v0.6.0 // indirect
|
||||
|
||||
@@ -103,8 +103,8 @@ github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA
|
||||
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
||||
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
|
||||
github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4=
|
||||
github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
|
||||
github.com/RoaringBitmap/roaring v1.9.3 h1:t4EbC5qQwnisr5PrP9nt0IRhRTb9gMUgQF4t4S2OByM=
|
||||
github.com/RoaringBitmap/roaring v1.9.3/go.mod h1:6AXUsoIEzDTFFQCe1RbGA6uFONMhvejWj5rqITANK90=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
@@ -237,7 +237,6 @@ github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZ
|
||||
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
|
||||
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
|
||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||
github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
|
||||
github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
@@ -256,7 +255,6 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
|
||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
|
||||
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
|
||||
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
@@ -1151,8 +1149,6 @@ golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
@@ -1236,9 +1232,7 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
@@ -1327,8 +1321,6 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -1340,9 +1332,7 @@ golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
||||
@@ -1356,9 +1346,7 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
|
||||
@@ -67,8 +67,8 @@ github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8
|
||||
github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
|
||||
github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4=
|
||||
github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f h1:HR5nRmUQgXrwqZOwZ2DAc/aCi3Bu3xENpspW935vxu0=
|
||||
|
||||
@@ -16,9 +16,8 @@ export function ExportToRepository({ repo }: Props) {
|
||||
|
||||
const { register, control, formState, handleSubmit } = useForm<ExportJobOptions>({
|
||||
defaultValues: {
|
||||
branch: '*dummy*', // << triggers a fake exporter
|
||||
history: true,
|
||||
prefix: 'prefix/in/remote/tree',
|
||||
prefix: '',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -32,6 +31,8 @@ export function ExportToRepository({ repo }: Props) {
|
||||
return <ExportJobStatus name={exportName} />;
|
||||
}
|
||||
|
||||
const isGit = repo.spec?.type === 'github';
|
||||
|
||||
return (
|
||||
<Box paddingTop={2}>
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
@@ -44,9 +45,11 @@ export function ExportToRepository({ repo }: Props) {
|
||||
/>
|
||||
</Field>
|
||||
|
||||
<Field label="Target Branch" description={'the target branch (use *dummy* to simulate long export)'}>
|
||||
<Input placeholder="branch name" {...register('branch')} />
|
||||
</Field>
|
||||
{isGit && (
|
||||
<Field label="Target Branch" description={'The target branch. This will be created and emptied first'}>
|
||||
<Input placeholder={repo.spec?.github?.branch} {...register('branch')} />
|
||||
</Field>
|
||||
)}
|
||||
|
||||
<Field label="Prefix">
|
||||
<Input placeholder="Prefix in the remote system" {...register('prefix')} />
|
||||
|
||||
Reference in new issue
Block a user