Zanzana: bump openfga version (#94485)

* Bump openfga

* Remove internall sqlite implementation for openfga

* Use sqlite implementation from openfga
This commit is contained in:
Karl Persson
2024-10-10 09:07:40 +02:00
committed by GitHub
parent bc7386e815
commit 9ece88d585
26 changed files with 362 additions and 1683 deletions
+12 -12
View File
@@ -23,7 +23,7 @@ require (
require (
github.com/BurntSushi/toml v1.4.0 // indirect
github.com/NYTimes/gziphandler v1.1.1 // indirect
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
github.com/apache/arrow/go/v15 v15.0.2 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/beorn7/perks v1.0.1 // indirect
@@ -53,7 +53,7 @@ require (
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/cel-go v0.20.1 // indirect
github.com/google/cel-go v0.21.0 // indirect
github.com/google/flatbuffers v24.3.25+incompatible // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
@@ -98,7 +98,7 @@ require (
github.com/pierrec/lz4/v4 v4.1.21 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.20.3 // indirect
github.com/prometheus/client_golang v1.20.4 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
@@ -118,21 +118,21 @@ require (
go.etcd.io/etcd/api/v3 v3.5.14 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect
go.etcd.io/etcd/client/v3 v3.5.14 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.55.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 // indirect
go.opentelemetry.io/contrib/propagators/jaeger v1.30.0 // indirect
go.opentelemetry.io/contrib/samplers/jaegerremote v0.23.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 // indirect
go.opentelemetry.io/otel/metric v1.30.0 // indirect
go.opentelemetry.io/otel/sdk v1.29.0 // indirect
go.opentelemetry.io/otel/sdk v1.30.0 // indirect
go.opentelemetry.io/otel/trace v1.30.0 // indirect
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/crypto v0.27.0 // indirect
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e // indirect
golang.org/x/mod v0.20.0 // indirect
golang.org/x/net v0.29.0 // indirect
golang.org/x/oauth2 v0.23.0 // indirect
@@ -143,11 +143,11 @@ require (
golang.org/x/time v0.6.0 // indirect
golang.org/x/tools v0.24.0 // indirect
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect
gonum.org/v1/gonum v0.14.0 // indirect
gonum.org/v1/gonum v0.15.1 // indirect
google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect
google.golang.org/grpc v1.66.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/grpc v1.67.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect
+24 -24
View File
@@ -5,8 +5,8 @@ github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
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=
github.com/apache/arrow/go/v15 v15.0.2 h1:60IliRbiyTWCWjERBCkO1W4Qun9svcYoZrSLcyOsMLE=
github.com/apache/arrow/go/v15 v15.0.2/go.mod h1:DGXsR3ajT524njufqf95822i+KTh+yea1jass9YXgjA=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
@@ -106,8 +106,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84=
github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg=
github.com/google/cel-go v0.21.0 h1:cl6uW/gxN+Hy50tNYvI691+sXxioCnstFzLp2WO4GCI=
github.com/google/cel-go v0.21.0/go.mod h1:rHUlWCcBKgyEk+eV03RPdZUekPp6YcJwV0FxuUksYxc=
github.com/google/flatbuffers v24.3.25+incompatible h1:CX395cjN9Kke9mmalRoL3d81AtFUxJM+yDthflgJGkI=
github.com/google/flatbuffers v24.3.25+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
@@ -247,8 +247,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4=
github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI=
github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@@ -342,8 +342,8 @@ go.etcd.io/etcd/raft/v3 v3.5.13 h1:7r/NKAOups1YnKcfro2RvGGo2PTuizF/xh26Z2CTAzA=
go.etcd.io/etcd/raft/v3 v3.5.13/go.mod h1:uUFibGLn2Ksm2URMxN1fICGhk8Wu96EfDQyuLhAcAmw=
go.etcd.io/etcd/server/v3 v3.5.13 h1:V6KG+yMfMSqWt+lGnhFpP5z5dRUj1BDRJ5k1fQ9DFok=
go.etcd.io/etcd/server/v3 v3.5.13/go.mod h1:K/8nbsGupHqmr5MkgaZpLlH1QdX1pcNQLAkODy44XcQ=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0 h1:hCq2hNMwsegUvPzI7sPOvtO9cqyy5GbWt/Ybp2xrx8Q=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0/go.mod h1:LqaApwGx/oUmzsbqxkzuBvyoPpkxk3JQWnqfVrJ3wCA=
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.55.0 h1:sqmsIQ75l6lfZjjpnXXT9DFVtYEDg6CH0/Cn4/3A1Wg=
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.55.0/go.mod h1:rsg1EO8LXSs2po50PB5CeY/MSVlhghuKBgXlKnqm6ks=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 h1:ZIg3ZT/aQ7AfKqdwp7ECpOK6vHqquXXuyTjIO8ZdmPs=
@@ -355,16 +355,16 @@ go.opentelemetry.io/contrib/samplers/jaegerremote v0.23.0/go.mod h1:1kbAgQa5lgYC
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts=
go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 h1:nSiV3s7wiCam610XcLbYOmMfJxB9gO4uK3Xgv5gmTgg=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0/go.mod h1:hKn/e/Nmd19/x1gvIHwtOwVWM+VhuITSWip3JUDghj0=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 h1:lsInsfvhVIfOI6qHVyysXMNDnjO9Npvl7tlDPJFBVd4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0/go.mod h1:KQsVNh4OjgjTG0G6EiNi1jVpnaeeKsKMRwbLN+f1+8M=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 h1:m0yTiGDLUvVYaTFbAvCkVYIYcvwKt3G7OLoN77NUs/8=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0/go.mod h1:wBQbT4UekBfegL2nx0Xk1vBcnzyBPsIVm9hRG4fYcr4=
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w=
go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ=
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo=
go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok=
go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE=
go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg=
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc=
go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o=
@@ -386,8 +386,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI=
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk=
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
@@ -462,8 +462,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk=
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0=
gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU=
gonum.org/v1/gonum v0.15.1 h1:FNy7N6OUZVUaWG9pTiD+jlhdQ3lMP+/LcTpJ6+a8sQ0=
gonum.org/v1/gonum v0.15.1/go.mod h1:eZTZuRFrzu5pcyjN5wJhcIhnUdNijYxX1T2IcrOGY0o=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
@@ -471,18 +471,18 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988 h1:CT2Thj5AuPV9phrYMtzX11k+XkzMGfRAet42PmoTATM=
google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988/go.mod h1:7uvplUBj4RjHAxIZ//98LzOvrQ04JBkaixRmCMI29hc=
google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo=
google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc=
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c=
google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw=
google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+2 -2
View File
@@ -39,8 +39,8 @@ require (
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/text v0.18.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect
google.golang.org/grpc v1.66.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/grpc v1.67.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
+4 -4
View File
@@ -135,10 +135,10 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c=
google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw=
google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+9 -9
View File
@@ -6,7 +6,7 @@ require (
github.com/google/go-cmp v0.6.0
github.com/grafana/authlib/claims v0.0.0-20240903121118-16441568af1e
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240701135906-559738ce6ae1
github.com/prometheus/client_golang v1.20.3
github.com/prometheus/client_golang v1.20.4
github.com/stretchr/testify v1.9.0
go.opentelemetry.io/contrib/propagators/jaeger v1.30.0
go.opentelemetry.io/otel v1.30.0
@@ -64,16 +64,16 @@ require (
go.etcd.io/etcd/api/v3 v3.5.14 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect
go.etcd.io/etcd/client/v3 v3.5.14 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 // indirect
go.opentelemetry.io/otel/metric v1.30.0 // indirect
go.opentelemetry.io/otel/sdk v1.29.0 // indirect
go.opentelemetry.io/otel/sdk v1.30.0 // indirect
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e // indirect
golang.org/x/net v0.29.0 // indirect
golang.org/x/oauth2 v0.23.0 // indirect
golang.org/x/sys v0.25.0 // indirect
@@ -82,9 +82,9 @@ require (
golang.org/x/time v0.6.0 // indirect
golang.org/x/tools v0.24.0 // indirect
google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect
google.golang.org/grpc v1.66.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/grpc v1.67.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
+18 -18
View File
@@ -132,8 +132,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4=
github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI=
github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@@ -188,22 +188,22 @@ go.etcd.io/etcd/raft/v3 v3.5.13 h1:7r/NKAOups1YnKcfro2RvGGo2PTuizF/xh26Z2CTAzA=
go.etcd.io/etcd/raft/v3 v3.5.13/go.mod h1:uUFibGLn2Ksm2URMxN1fICGhk8Wu96EfDQyuLhAcAmw=
go.etcd.io/etcd/server/v3 v3.5.13 h1:V6KG+yMfMSqWt+lGnhFpP5z5dRUj1BDRJ5k1fQ9DFok=
go.etcd.io/etcd/server/v3 v3.5.13/go.mod h1:K/8nbsGupHqmr5MkgaZpLlH1QdX1pcNQLAkODy44XcQ=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0 h1:hCq2hNMwsegUvPzI7sPOvtO9cqyy5GbWt/Ybp2xrx8Q=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0/go.mod h1:LqaApwGx/oUmzsbqxkzuBvyoPpkxk3JQWnqfVrJ3wCA=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 h1:ZIg3ZT/aQ7AfKqdwp7ECpOK6vHqquXXuyTjIO8ZdmPs=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0/go.mod h1:DQAwmETtZV00skUwgD6+0U89g80NKsJE3DCKeLLPQMI=
go.opentelemetry.io/contrib/propagators/jaeger v1.30.0 h1:g8+Y+7lnhH1DB0THjPPthzQ+RlzAntmTz8+TH2sRU0k=
go.opentelemetry.io/contrib/propagators/jaeger v1.30.0/go.mod h1:lRMaD/FjOQJ2yz/MwOHYxP/BTCMFodNW/wuYDkJvdA4=
go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts=
go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 h1:nSiV3s7wiCam610XcLbYOmMfJxB9gO4uK3Xgv5gmTgg=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0/go.mod h1:hKn/e/Nmd19/x1gvIHwtOwVWM+VhuITSWip3JUDghj0=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 h1:lsInsfvhVIfOI6qHVyysXMNDnjO9Npvl7tlDPJFBVd4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0/go.mod h1:KQsVNh4OjgjTG0G6EiNi1jVpnaeeKsKMRwbLN+f1+8M=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 h1:m0yTiGDLUvVYaTFbAvCkVYIYcvwKt3G7OLoN77NUs/8=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0/go.mod h1:wBQbT4UekBfegL2nx0Xk1vBcnzyBPsIVm9hRG4fYcr4=
go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w=
go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ=
go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo=
go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok=
go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE=
go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg=
go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc=
go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o=
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
@@ -224,8 +224,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI=
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk=
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
@@ -290,18 +290,18 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988 h1:CT2Thj5AuPV9phrYMtzX11k+XkzMGfRAet42PmoTATM=
google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988/go.mod h1:7uvplUBj4RjHAxIZ//98LzOvrQ04JBkaixRmCMI29hc=
google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo=
google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc=
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c=
google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw=
google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+9 -9
View File
@@ -20,7 +20,7 @@ require (
github.com/Masterminds/semver/v3 v3.2.0 // @grafana/grafana-release-guild
github.com/aws/aws-sdk-go v1.55.5 // @grafana/aws-datasources
github.com/blang/semver/v4 v4.0.0 // @grafana/grafana-release-guild
github.com/docker/docker v26.0.2+incompatible // @grafana/grafana-release-guild
github.com/docker/docker v27.3.1+incompatible // @grafana/grafana-release-guild
github.com/drone/drone-cli v1.6.1 // @grafana/grafana-release-guild
github.com/gogo/protobuf v1.3.2 // indirect; @grafana/alerting-backend
github.com/google/go-cmp v0.6.0 // @grafana/grafana-backend-group
@@ -32,9 +32,9 @@ require (
github.com/stretchr/testify v1.9.0 // @grafana/grafana-backend-group
github.com/urfave/cli v1.22.15 // @grafana/grafana-backend-group
github.com/urfave/cli/v2 v2.27.1 // @grafana/grafana-backend-group
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect; @grafana/plugins-platform-backend
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0 // indirect; @grafana/plugins-platform-backend
go.opentelemetry.io/otel v1.30.0 // indirect; @grafana/grafana-backend-group
go.opentelemetry.io/otel/sdk v1.29.0 // indirect; @grafana/grafana-backend-group
go.opentelemetry.io/otel/sdk v1.30.0 // indirect; @grafana/grafana-backend-group
go.opentelemetry.io/otel/trace v1.30.0 // indirect; @grafana/grafana-backend-group
golang.org/x/crypto v0.27.0 // indirect; @grafana/grafana-backend-group
golang.org/x/mod v0.20.0 // @grafana/grafana-backend-group
@@ -45,7 +45,7 @@ require (
golang.org/x/time v0.6.0 // indirect; @grafana/grafana-backend-group
golang.org/x/tools v0.24.0 // indirect; @grafana/grafana-as-code
google.golang.org/api v0.191.0 // @grafana/grafana-backend-group
google.golang.org/grpc v1.66.0 // indirect; @grafana/plugins-platform-backend
google.golang.org/grpc v1.67.0 // indirect; @grafana/plugins-platform-backend
google.golang.org/protobuf v1.34.2 // indirect; @grafana/plugins-platform-backend
gopkg.in/yaml.v3 v3.0.1 // @grafana/alerting-backend
)
@@ -87,8 +87,8 @@ require (
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
golang.org/x/sys v0.25.0 // indirect
google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988 // indirect; @grafana/grafana-backend-group
google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
@@ -110,13 +110,13 @@ require (
github.com/vektah/gqlparser/v2 v2.5.11 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.2.0-alpha // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0 // indirect
go.opentelemetry.io/otel/log v0.2.0-alpha // indirect
go.opentelemetry.io/otel/sdk/log v0.2.0-alpha // indirect
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e // indirect
gotest.tools/v3 v3.5.1 // indirect
)
+16 -16
View File
@@ -227,8 +227,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0 h1:hCq2hNMwsegUvPzI7sPOvtO9cqyy5GbWt/Ybp2xrx8Q=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0/go.mod h1:LqaApwGx/oUmzsbqxkzuBvyoPpkxk3JQWnqfVrJ3wCA=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 h1:ZIg3ZT/aQ7AfKqdwp7ECpOK6vHqquXXuyTjIO8ZdmPs=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0/go.mod h1:DQAwmETtZV00skUwgD6+0U89g80NKsJE3DCKeLLPQMI=
go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts=
@@ -237,18 +237,18 @@ go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-2024051809000
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY=
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.2.0-alpha h1:z2s6Zba+OUyayRv5m1AXWNUTGh57K1iMhy6emU5QT5Y=
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.2.0-alpha/go.mod h1:paOXXyUgPW6jYxYkP0pB47H2zHE1fPvMJ4E4G9LHOi0=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 h1:nSiV3s7wiCam610XcLbYOmMfJxB9gO4uK3Xgv5gmTgg=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0/go.mod h1:hKn/e/Nmd19/x1gvIHwtOwVWM+VhuITSWip3JUDghj0=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 h1:lsInsfvhVIfOI6qHVyysXMNDnjO9Npvl7tlDPJFBVd4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0/go.mod h1:KQsVNh4OjgjTG0G6EiNi1jVpnaeeKsKMRwbLN+f1+8M=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 h1:m0yTiGDLUvVYaTFbAvCkVYIYcvwKt3G7OLoN77NUs/8=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0/go.mod h1:wBQbT4UekBfegL2nx0Xk1vBcnzyBPsIVm9hRG4fYcr4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0 h1:JAv0Jwtl01UFiyWZEMiJZBiTlv5A50zNs8lsthXqIio=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0/go.mod h1:QNKLmUEAq2QUbPQUfvw4fmv0bgbK7UlOSFCnXyfvSNc=
go.opentelemetry.io/otel/log v0.2.0-alpha h1:ixOPvMzserpqA07SENHvRzkZOsnG0XbPr74hv1AQ+n0=
go.opentelemetry.io/otel/log v0.2.0-alpha/go.mod h1:vbFZc65yq4c4ssvXY43y/nIqkNJLxORrqw0L85P59LA=
go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w=
go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ=
go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo=
go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok=
go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE=
go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg=
go.opentelemetry.io/otel/sdk/log v0.2.0-alpha h1:jGTkL/jroJ31jnP6jDl34N/mDOfRGGYZHcHsCM+5kWA=
go.opentelemetry.io/otel/sdk/log v0.2.0-alpha/go.mod h1:Hd8Lw9FPGUM3pfY7iGMRvFaC2Nyau4Ajb5WnQ9OdIho=
go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc=
@@ -266,8 +266,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI=
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk=
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
@@ -339,18 +339,18 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988 h1:CT2Thj5AuPV9phrYMtzX11k+XkzMGfRAet42PmoTATM=
google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988/go.mod h1:7uvplUBj4RjHAxIZ//98LzOvrQ04JBkaixRmCMI29hc=
google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo=
google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc=
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c=
google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw=
google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+10 -10
View File
@@ -7,13 +7,13 @@ require (
github.com/grafana/grafana-plugin-sdk-go v0.251.0
github.com/json-iterator/go v1.1.12
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/prometheus/client_golang v1.20.3
github.com/prometheus/client_golang v1.20.4
github.com/prometheus/common v0.55.0
github.com/prometheus/prometheus v1.8.2-0.20221021121301-51a44e6657c3
github.com/stretchr/testify v1.9.0
go.opentelemetry.io/otel v1.30.0
go.opentelemetry.io/otel/trace v1.30.0
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e
k8s.io/apimachinery v0.31.1
)
@@ -101,14 +101,14 @@ require (
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/zeebo/xxh3 v1.0.2 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.55.0 // indirect
go.opentelemetry.io/contrib/propagators/jaeger v1.30.0 // indirect
go.opentelemetry.io/contrib/samplers/jaegerremote v0.23.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 // indirect
go.opentelemetry.io/otel/metric v1.30.0 // indirect
go.opentelemetry.io/otel/sdk v1.29.0 // indirect
go.opentelemetry.io/otel/sdk v1.30.0 // indirect
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/goleak v1.3.0 // indirect
@@ -119,10 +119,10 @@ require (
golang.org/x/text v0.18.0 // indirect
golang.org/x/tools v0.24.0 // indirect
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect
gonum.org/v1/gonum v0.14.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect
google.golang.org/grpc v1.66.0 // indirect
gonum.org/v1/gonum v0.15.1 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/grpc v1.67.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
+20 -20
View File
@@ -199,8 +199,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4=
github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI=
github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
@@ -262,8 +262,8 @@ github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0 h1:hCq2hNMwsegUvPzI7sPOvtO9cqyy5GbWt/Ybp2xrx8Q=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0/go.mod h1:LqaApwGx/oUmzsbqxkzuBvyoPpkxk3JQWnqfVrJ3wCA=
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.55.0 h1:sqmsIQ75l6lfZjjpnXXT9DFVtYEDg6CH0/Cn4/3A1Wg=
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.55.0/go.mod h1:rsg1EO8LXSs2po50PB5CeY/MSVlhghuKBgXlKnqm6ks=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 h1:ZIg3ZT/aQ7AfKqdwp7ECpOK6vHqquXXuyTjIO8ZdmPs=
@@ -275,16 +275,16 @@ go.opentelemetry.io/contrib/samplers/jaegerremote v0.23.0/go.mod h1:1kbAgQa5lgYC
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts=
go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 h1:nSiV3s7wiCam610XcLbYOmMfJxB9gO4uK3Xgv5gmTgg=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0/go.mod h1:hKn/e/Nmd19/x1gvIHwtOwVWM+VhuITSWip3JUDghj0=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 h1:lsInsfvhVIfOI6qHVyysXMNDnjO9Npvl7tlDPJFBVd4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0/go.mod h1:KQsVNh4OjgjTG0G6EiNi1jVpnaeeKsKMRwbLN+f1+8M=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 h1:m0yTiGDLUvVYaTFbAvCkVYIYcvwKt3G7OLoN77NUs/8=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0/go.mod h1:wBQbT4UekBfegL2nx0Xk1vBcnzyBPsIVm9hRG4fYcr4=
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w=
go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ=
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo=
go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok=
go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE=
go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg=
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc=
go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o=
@@ -297,8 +297,8 @@ go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
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/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI=
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk=
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
@@ -349,14 +349,14 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk=
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0=
gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU=
google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo=
google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c=
google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
gonum.org/v1/gonum v0.15.1 h1:FNy7N6OUZVUaWG9pTiD+jlhdQ3lMP+/LcTpJ6+a8sQ0=
gonum.org/v1/gonum v0.15.1/go.mod h1:eZTZuRFrzu5pcyjN5wJhcIhnUdNijYxX1T2IcrOGY0o=
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc=
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw=
google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -4,10 +4,14 @@ import (
"context"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/openfga/openfga/pkg/logger"
)
var _ logger.Logger = (*ZanzanaLogger)(nil)
// ZanzanaLogger is a grafana logger wrapper compatible with OpenFGA logger interface
type ZanzanaLogger struct {
logger log.Logger
@@ -36,6 +40,13 @@ func zapFieldsToArgs(fields []zap.Field) []any {
return args
}
// With implements logger.Logger.
func (l *ZanzanaLogger) With(fields ...zapcore.Field) logger.Logger {
return &ZanzanaLogger{
logger: l.logger.New(zapFieldsToArgs(fields)...),
}
}
func (l *ZanzanaLogger) Debug(msg string, fields ...zap.Field) {
l.logger.Debug(msg, zapFieldsToArgs(fields)...)
}
@@ -1,10 +0,0 @@
package assets
import "embed"
// EmbedMigrations within the grafana binary.
//
//go:embed migrations/*
var EmbedMigrations embed.FS
const SQLiteMigrationDir = "migrations/sqlite"
@@ -1,56 +0,0 @@
-- +goose Up
CREATE TABLE tuple (
store CHAR(26) NOT NULL,
object_type VARCHAR(128) NOT NULL,
object_id VARCHAR(128) NOT NULL,
relation VARCHAR(50) NOT NULL,
_user VARCHAR(256) NOT NULL,
user_type VARCHAR(7) NOT NULL,
ulid CHAR(26) NOT NULL,
inserted_at TIMESTAMP NOT NULL,
PRIMARY KEY (store, object_type, object_id, relation, _user)
);
CREATE UNIQUE INDEX idx_tuple_ulid ON tuple (ulid);
CREATE TABLE authorization_model (
store CHAR(26) NOT NULL,
authorization_model_id CHAR(26) NOT NULL,
type VARCHAR(256) NOT NULL,
type_definition BLOB,
PRIMARY KEY (store, authorization_model_id, type)
);
CREATE TABLE store (
id CHAR(26) PRIMARY KEY,
name VARCHAR(64) NOT NULL,
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP,
deleted_at TIMESTAMP
);
CREATE TABLE assertion (
store CHAR(26) NOT NULL,
authorization_model_id CHAR(26) NOT NULL,
assertions BLOB,
PRIMARY KEY (store, authorization_model_id)
);
CREATE TABLE changelog (
store CHAR(26) NOT NULL,
object_type VARCHAR(256) NOT NULL,
object_id VARCHAR(256) NOT NULL,
relation VARCHAR(50) NOT NULL,
_user VARCHAR(512) NOT NULL,
operation INTEGER NOT NULL,
ulid CHAR(26) NOT NULL,
inserted_at TIMESTAMP NOT NULL,
PRIMARY KEY (store, ulid, object_type)
);
-- +goose Down
DROP TABLE tuple;
DROP TABLE authorization_model;
DROP TABLE store;
DROP TABLE assertion;
DROP TABLE changelog;
@@ -1,5 +0,0 @@
-- +goose Up
ALTER TABLE authorization_model ADD COLUMN schema_version VARCHAR(5) NOT NULL DEFAULT '1.0';
-- +goose Down
ALTER TABLE authorization_model DROP COLUMN schema_version;
@@ -1,5 +0,0 @@
-- +goose Up
CREATE INDEX idx_reverse_lookup_user on tuple (store, object_type, relation, _user);
-- +goose Down
DROP INDEX idx_reverse_lookup_user on tuple;
@@ -1,5 +0,0 @@
-- +goose Up
ALTER TABLE authorization_model ADD COLUMN serialized_protobuf LONGBLOB;
-- +goose Down
ALTER TABLE authorization_model DROP COLUMN serialized_protobuf;
@@ -1,11 +0,0 @@
-- +goose Up
ALTER TABLE tuple ADD COLUMN condition_name VARCHAR(256);
ALTER TABLE tuple ADD COLUMN condition_context LONGBLOB;
ALTER TABLE changelog ADD COLUMN condition_name VARCHAR(256);
ALTER TABLE changelog ADD COLUMN condition_context LONGBLOB;
-- +goose Down
ALTER TABLE tuple DROP COLUMN condition_name;
ALTER TABLE tuple DROP COLUMN condition_context;
ALTER TABLE changelog DROP COLUMN condition_name;
ALTER TABLE changelog DROP COLUMN condition_context;
@@ -15,13 +15,17 @@ import (
func Run(cfg *setting.Cfg, typ, connStr string, fs embed.FS, path string) error {
engine, err := xorm.NewEngine(typ, connStr)
if err != nil {
return fmt.Errorf("failed to parse database config: %w", err)
return fmt.Errorf("failed to create db engine: %w", err)
}
m := migrator.NewMigrator(engine, cfg)
m.AddCreateMigration()
return RunWithMigrator(m, cfg, fs, path)
if err := RunWithMigrator(m, cfg, fs, path); err != nil {
return err
}
return engine.Close()
}
func RunWithMigrator(m *migrator.Migrator, cfg *setting.Cfg, fs embed.FS, path string) error {
@@ -1,15 +0,0 @@
package sqlite
import "github.com/openfga/openfga/pkg/storage/sqlcommon"
type Config struct {
*sqlcommon.Config
QueryRetries int
}
func NewConfig() *Config {
return &Config{
Config: sqlcommon.NewConfig(),
QueryRetries: 0,
}
}
@@ -1,821 +0,0 @@
package sqlite
import (
"context"
"database/sql"
"encoding/json"
"errors"
"fmt"
"net/url"
"strings"
"time"
sq "github.com/Masterminds/squirrel"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/collectors"
"go.opentelemetry.io/otel"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/structpb"
"google.golang.org/protobuf/types/known/timestamppb"
// Pull in sqlite driver.
"github.com/mattn/go-sqlite3"
openfgav1 "github.com/openfga/api/proto/openfga/v1"
"github.com/openfga/openfga/pkg/logger"
"github.com/openfga/openfga/pkg/storage"
"github.com/openfga/openfga/pkg/storage/sqlcommon"
tupleUtils "github.com/openfga/openfga/pkg/tuple"
)
var tracer = otel.Tracer("openfga/pkg/storage/sqlite")
// SQLite provides a SQLite based implementation of [storage.OpenFGADatastore].
type SQLite struct {
stbl sq.StatementBuilderType
cfg *Config
db *sql.DB
dbInfo *sqlcommon.DBInfo
sqlTime sq.Sqlizer
logger logger.Logger
dbStatsCollector prometheus.Collector
}
// Ensures that SQLite implements the OpenFGADatastore interface.
var _ storage.OpenFGADatastore = (*SQLite)(nil)
// New creates a new [SQLite] storage.
func New(uri string, cfg *Config) (*SQLite, error) {
// Set journal mode and busy timeout pragmas if not specified.
query := url.Values{}
var err error
if i := strings.Index(uri, "?"); i != -1 {
query, err = url.ParseQuery(uri[i+1:])
if err != nil {
return nil, fmt.Errorf("error parsing dsn: %w", err)
}
uri = uri[:i]
}
foundJournalMode := false
foundBusyTimeout := false
for _, val := range query["_pragma"] {
if strings.HasPrefix(val, "journal_mode") {
foundJournalMode = true
} else if strings.HasPrefix(val, "busy_timeout") {
foundBusyTimeout = true
}
}
if !foundJournalMode {
query.Add("_pragma", "journal_mode(WAL)")
}
if !foundBusyTimeout {
query.Add("_pragma", "busy_timeout(500)")
}
uri += "?" + query.Encode()
db, err := sql.Open("sqlite", uri)
if err != nil {
return nil, fmt.Errorf("initialize sqlite connection: %w", err)
}
return NewWithDB(db, cfg)
}
// NewWithDB creates a new [SQLite] storage using provided [*sql.DB]
func NewWithDB(db *sql.DB, cfg *Config) (*SQLite, error) {
var collector prometheus.Collector
if cfg.ExportMetrics {
collector = collectors.NewDBStatsCollector(db, "openfga")
if err := prometheus.Register(collector); err != nil {
return nil, fmt.Errorf("initialize metrics: %w", err)
}
}
sqlTime := sq.Expr("datetime('subsec')")
stbl := sq.StatementBuilder.RunWith(db)
dbInfo := sqlcommon.NewDBInfo(db, stbl, sqlTime)
return &SQLite{
cfg: cfg,
stbl: stbl,
db: db,
sqlTime: sqlTime,
dbInfo: dbInfo,
logger: cfg.Logger,
dbStatsCollector: collector,
}, nil
}
// Close see [storage.OpenFGADatastore].Close.
func (m *SQLite) Close() {
if m.dbStatsCollector != nil {
prometheus.Unregister(m.dbStatsCollector)
}
_ = m.db.Close()
}
// Read see [storage.RelationshipTupleReader].Read.
func (m *SQLite) Read(ctx context.Context, store string, tupleKey *openfgav1.TupleKey) (storage.TupleIterator, error) {
ctx, span := tracer.Start(ctx, "sqlite.Read")
defer span.End()
return m.read(ctx, store, tupleKey, nil)
}
// ReadPage see [storage.RelationshipTupleReader].ReadPage.
func (m *SQLite) ReadPage(
ctx context.Context,
store string,
tupleKey *openfgav1.TupleKey,
opts storage.PaginationOptions,
) ([]*openfgav1.Tuple, []byte, error) {
ctx, span := tracer.Start(ctx, "sqlite.ReadPage")
defer span.End()
iter, err := m.read(ctx, store, tupleKey, &opts)
if err != nil {
return nil, nil, err
}
defer iter.Stop()
return iter.ToArray(opts)
}
func (m *SQLite) read(ctx context.Context, store string, tupleKey *openfgav1.TupleKey, opts *storage.PaginationOptions) (*sqlcommon.SQLTupleIterator, error) {
ctx, span := tracer.Start(ctx, "sqlite.read")
defer span.End()
sb := m.stbl.
Select(
"store", "object_type", "object_id", "relation", "_user",
"condition_name", "condition_context", "ulid", "inserted_at",
).
From("tuple").
Where(sq.Eq{"store": store})
if opts != nil {
sb = sb.OrderBy("ulid")
}
objectType, objectID := tupleUtils.SplitObject(tupleKey.GetObject())
if objectType != "" {
sb = sb.Where(sq.Eq{"object_type": objectType})
}
if objectID != "" {
sb = sb.Where(sq.Eq{"object_id": objectID})
}
if tupleKey.GetRelation() != "" {
sb = sb.Where(sq.Eq{"relation": tupleKey.GetRelation()})
}
if tupleKey.GetUser() != "" {
sb = sb.Where(sq.Eq{"_user": tupleKey.GetUser()})
}
if opts != nil && opts.From != "" {
token, err := sqlcommon.UnmarshallContToken(opts.From)
if err != nil {
return nil, err
}
sb = sb.Where(sq.GtOrEq{"ulid": token.Ulid})
}
if opts != nil && opts.PageSize != 0 {
sb = sb.Limit(uint64(opts.PageSize + 1)) // + 1 is used to determine whether to return a continuation token.
}
rows, err := sb.QueryContext(ctx)
if err != nil {
return nil, handleSQLError(err)
}
return sqlcommon.NewSQLTupleIterator(rows), nil
}
// Write see [storage.RelationshipTupleWriter].Write.
func (m *SQLite) Write(ctx context.Context, store string, deletes storage.Deletes, writes storage.Writes) error {
ctx, span := tracer.Start(ctx, "sqlite.Write")
defer span.End()
if len(deletes)+len(writes) > m.MaxTuplesPerWrite() {
return storage.ErrExceededWriteBatchLimit
}
return m.busyRetry(func() error {
now := time.Now().UTC()
return write(ctx, m.db, m.stbl, m.sqlTime, store, deletes, writes, now)
})
}
// ReadUserTuple see [storage.RelationshipTupleReader].ReadUserTuple.
func (m *SQLite) ReadUserTuple(ctx context.Context, store string, tupleKey *openfgav1.TupleKey) (*openfgav1.Tuple, error) {
ctx, span := tracer.Start(ctx, "sqlite.ReadUserTuple")
defer span.End()
objectType, objectID := tupleUtils.SplitObject(tupleKey.GetObject())
userType := tupleUtils.GetUserTypeFromUser(tupleKey.GetUser())
var conditionName sql.NullString
var conditionContext []byte
var record storage.TupleRecord
err := m.stbl.
Select(
"object_type", "object_id", "relation", "_user",
"condition_name", "condition_context",
).
From("tuple").
Where(sq.Eq{
"store": store,
"object_type": objectType,
"object_id": objectID,
"relation": tupleKey.GetRelation(),
"_user": tupleKey.GetUser(),
"user_type": userType,
}).
QueryRowContext(ctx).
Scan(
&record.ObjectType,
&record.ObjectID,
&record.Relation,
&record.User,
&conditionName,
&conditionContext,
)
if err != nil {
return nil, handleSQLError(err)
}
if conditionName.String != "" {
record.ConditionName = conditionName.String
if conditionContext != nil {
var conditionContextStruct structpb.Struct
if err := proto.Unmarshal(conditionContext, &conditionContextStruct); err != nil {
return nil, err
}
record.ConditionContext = &conditionContextStruct
}
}
return record.AsTuple(), nil
}
// ReadUsersetTuples see [storage.RelationshipTupleReader].ReadUsersetTuples.
func (m *SQLite) ReadUsersetTuples(
ctx context.Context,
store string,
filter storage.ReadUsersetTuplesFilter,
) (storage.TupleIterator, error) {
ctx, span := tracer.Start(ctx, "sqlite.ReadUsersetTuples")
defer span.End()
sb := m.stbl.
Select(
"store", "object_type", "object_id", "relation", "_user",
"condition_name", "condition_context", "ulid", "inserted_at",
).
From("tuple").
Where(sq.Eq{"store": store}).
Where(sq.Eq{"user_type": tupleUtils.UserSet})
objectType, objectID := tupleUtils.SplitObject(filter.Object)
if objectType != "" {
sb = sb.Where(sq.Eq{"object_type": objectType})
}
if objectID != "" {
sb = sb.Where(sq.Eq{"object_id": objectID})
}
if filter.Relation != "" {
sb = sb.Where(sq.Eq{"relation": filter.Relation})
}
if len(filter.AllowedUserTypeRestrictions) > 0 {
orConditions := sq.Or{}
for _, userset := range filter.AllowedUserTypeRestrictions {
if _, ok := userset.GetRelationOrWildcard().(*openfgav1.RelationReference_Relation); ok {
orConditions = append(orConditions, sq.Like{"_user": userset.GetType() + ":%#" + userset.GetRelation()})
}
if _, ok := userset.GetRelationOrWildcard().(*openfgav1.RelationReference_Wildcard); ok {
orConditions = append(orConditions, sq.Eq{"_user": userset.GetType() + ":*"})
}
}
sb = sb.Where(orConditions)
}
rows, err := sb.QueryContext(ctx)
if err != nil {
return nil, handleSQLError(err)
}
return sqlcommon.NewSQLTupleIterator(rows), nil
}
// ReadStartingWithUser see [storage.RelationshipTupleReader].ReadStartingWithUser.
func (m *SQLite) ReadStartingWithUser(
ctx context.Context,
store string,
opts storage.ReadStartingWithUserFilter,
) (storage.TupleIterator, error) {
ctx, span := tracer.Start(ctx, "sqlite.ReadStartingWithUser")
defer span.End()
targetUsersArg := make([]string, 0, len(opts.UserFilter))
for _, u := range opts.UserFilter {
targetUser := u.GetObject()
if u.GetRelation() != "" {
targetUser = strings.Join([]string{u.GetObject(), u.GetRelation()}, "#")
}
targetUsersArg = append(targetUsersArg, targetUser)
}
rows, err := m.stbl.
Select(
"store", "object_type", "object_id", "relation", "_user",
"condition_name", "condition_context", "ulid", "inserted_at",
).
From("tuple").
Where(sq.Eq{
"store": store,
"object_type": opts.ObjectType,
"relation": opts.Relation,
"_user": targetUsersArg,
}).QueryContext(ctx)
if err != nil {
return nil, handleSQLError(err)
}
return sqlcommon.NewSQLTupleIterator(rows), nil
}
// MaxTuplesPerWrite see [storage.RelationshipTupleWriter].MaxTuplesPerWrite.
func (m *SQLite) MaxTuplesPerWrite() int {
return m.cfg.MaxTuplesPerWriteField
}
// ReadAuthorizationModel see [storage.AuthorizationModelReadBackend].ReadAuthorizationModel.
func (m *SQLite) ReadAuthorizationModel(ctx context.Context, store string, modelID string) (*openfgav1.AuthorizationModel, error) {
ctx, span := tracer.Start(ctx, "sqlite.ReadAuthorizationModel")
defer span.End()
return sqlcommon.ReadAuthorizationModel(ctx, m.dbInfo, store, modelID)
}
// ReadAuthorizationModels see [storage.AuthorizationModelReadBackend].ReadAuthorizationModels.
func (m *SQLite) ReadAuthorizationModels(
ctx context.Context,
store string,
opts storage.PaginationOptions,
) ([]*openfgav1.AuthorizationModel, []byte, error) {
ctx, span := tracer.Start(ctx, "sqlite.ReadAuthorizationModels")
defer span.End()
sb := m.stbl.Select("authorization_model_id").
Distinct().
From("authorization_model").
Where(sq.Eq{"store": store}).
OrderBy("authorization_model_id desc")
if opts.From != "" {
token, err := sqlcommon.UnmarshallContToken(opts.From)
if err != nil {
return nil, nil, err
}
sb = sb.Where(sq.LtOrEq{"authorization_model_id": token.Ulid})
}
if opts.PageSize > 0 {
sb = sb.Limit(uint64(opts.PageSize + 1)) // + 1 is used to determine whether to return a continuation token.
}
rows, err := sb.QueryContext(ctx)
if err != nil {
return nil, nil, handleSQLError(err)
}
defer func() { _ = rows.Close() }()
var modelIDs []string
var modelID string
for rows.Next() {
err = rows.Scan(&modelID)
if err != nil {
return nil, nil, handleSQLError(err)
}
modelIDs = append(modelIDs, modelID)
}
if err := rows.Err(); err != nil {
return nil, nil, handleSQLError(err)
}
var token []byte
numModelIDs := len(modelIDs)
if len(modelIDs) > opts.PageSize {
numModelIDs = opts.PageSize
token, err = json.Marshal(sqlcommon.NewContToken(modelID, ""))
if err != nil {
return nil, nil, err
}
}
// TODO: make this concurrent with a maximum of 5 goroutines. This may be helpful:
// https://stackoverflow.com/questions/25306073/always-have-x-number-of-goroutines-running-at-any-time
models := make([]*openfgav1.AuthorizationModel, 0, numModelIDs)
// We use numModelIDs here to avoid retrieving possibly one extra model.
for i := 0; i < numModelIDs; i++ {
model, err := m.ReadAuthorizationModel(ctx, store, modelIDs[i])
if err != nil {
return nil, nil, err
}
models = append(models, model)
}
return models, token, nil
}
// FindLatestAuthorizationModel see [storage.AuthorizationModelReadBackend].FindLatestAuthorizationModel.
func (m *SQLite) FindLatestAuthorizationModel(ctx context.Context, store string) (*openfgav1.AuthorizationModel, error) {
ctx, span := tracer.Start(ctx, "sqlite.FindLatestAuthorizationModel")
defer span.End()
return sqlcommon.FindLatestAuthorizationModel(ctx, m.dbInfo, store)
}
// MaxTypesPerAuthorizationModel see [storage.TypeDefinitionWriteBackend].MaxTypesPerAuthorizationModel.
func (m *SQLite) MaxTypesPerAuthorizationModel() int {
return m.cfg.MaxTypesPerModelField
}
// WriteAuthorizationModel see [storage.TypeDefinitionWriteBackend].WriteAuthorizationModel.
func (m *SQLite) WriteAuthorizationModel(ctx context.Context, store string, model *openfgav1.AuthorizationModel) error {
ctx, span := tracer.Start(ctx, "sqlite.WriteAuthorizationModel")
defer span.End()
typeDefinitions := model.GetTypeDefinitions()
if len(typeDefinitions) > m.MaxTypesPerAuthorizationModel() {
return storage.ExceededMaxTypeDefinitionsLimitError(m.MaxTypesPerAuthorizationModel())
}
return m.busyRetry(func() error {
return sqlcommon.WriteAuthorizationModel(ctx, m.dbInfo, store, model)
})
}
// CreateStore adds a new store to the SQLite storage.
func (m *SQLite) CreateStore(ctx context.Context, store *openfgav1.Store) (*openfgav1.Store, error) {
ctx, span := tracer.Start(ctx, "sqlite.CreateStore")
defer span.End()
txn, err := m.db.BeginTx(ctx, &sql.TxOptions{})
if err != nil {
return nil, handleSQLError(err)
}
defer func() {
_ = txn.Rollback()
}()
_, err = m.stbl.
Insert("store").
Columns("id", "name", "created_at", "updated_at").
Values(store.GetId(), store.GetName(), sq.Expr("datetime('subsec')"), sq.Expr("datetime('subsec')")).
RunWith(txn).
ExecContext(ctx)
if err != nil {
return nil, handleSQLError(err)
}
var createdAt time.Time
var id, name string
err = m.stbl.
Select("id", "name", "created_at").
From("store").
Where(sq.Eq{"id": store.GetId()}).
RunWith(txn).
QueryRowContext(ctx).
Scan(&id, &name, &createdAt)
if err != nil {
return nil, handleSQLError(err)
}
err = txn.Commit()
if err != nil {
return nil, handleSQLError(err)
}
return &openfgav1.Store{
Id: id,
Name: name,
CreatedAt: timestamppb.New(createdAt),
UpdatedAt: timestamppb.New(createdAt),
}, nil
}
// GetStore retrieves the details of a specific store from the SQLite using its storeID.
func (m *SQLite) GetStore(ctx context.Context, id string) (*openfgav1.Store, error) {
ctx, span := tracer.Start(ctx, "sqlite.GetStore")
defer span.End()
row := m.stbl.
Select("id", "name", "created_at", "updated_at").
From("store").
Where(sq.Eq{
"id": id,
"deleted_at": nil,
}).
QueryRowContext(ctx)
var storeID, name string
var createdAt, updatedAt time.Time
err := row.Scan(&storeID, &name, &createdAt, &updatedAt)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, storage.ErrNotFound
}
return nil, handleSQLError(err)
}
return &openfgav1.Store{
Id: storeID,
Name: name,
CreatedAt: timestamppb.New(createdAt),
UpdatedAt: timestamppb.New(updatedAt),
}, nil
}
// ListStores provides a paginated list of all stores present in the SQLite storage.
func (m *SQLite) ListStores(ctx context.Context, opts storage.PaginationOptions) ([]*openfgav1.Store, []byte, error) {
ctx, span := tracer.Start(ctx, "sqlite.ListStores")
defer span.End()
sb := m.stbl.
Select("id", "name", "created_at", "updated_at").
From("store").
Where(sq.Eq{"deleted_at": nil}).
OrderBy("id")
if opts.From != "" {
token, err := sqlcommon.UnmarshallContToken(opts.From)
if err != nil {
return nil, nil, err
}
sb = sb.Where(sq.GtOrEq{"id": token.Ulid})
}
if opts.PageSize > 0 {
sb = sb.Limit(uint64(opts.PageSize + 1)) // + 1 is used to determine whether to return a continuation token.
}
rows, err := sb.QueryContext(ctx)
if err != nil {
return nil, nil, handleSQLError(err)
}
defer func() { _ = rows.Close() }()
var stores []*openfgav1.Store
var id string
for rows.Next() {
var name string
var createdAt, updatedAt time.Time
err := rows.Scan(&id, &name, &createdAt, &updatedAt)
if err != nil {
return nil, nil, handleSQLError(err)
}
stores = append(stores, &openfgav1.Store{
Id: id,
Name: name,
CreatedAt: timestamppb.New(createdAt),
UpdatedAt: timestamppb.New(updatedAt),
})
}
if err := rows.Err(); err != nil {
return nil, nil, handleSQLError(err)
}
if len(stores) > opts.PageSize {
contToken, err := json.Marshal(sqlcommon.NewContToken(id, ""))
if err != nil {
return nil, nil, err
}
return stores[:opts.PageSize], contToken, nil
}
return stores, nil, nil
}
// DeleteStore removes a store from the SQLite storage.
func (m *SQLite) DeleteStore(ctx context.Context, id string) error {
ctx, span := tracer.Start(ctx, "sqlite.DeleteStore")
defer span.End()
_, err := m.stbl.
Update("store").
Set("deleted_at", sq.Expr("datetime('subsec')")).
Where(sq.Eq{"id": id}).
ExecContext(ctx)
if err != nil {
return handleSQLError(err)
}
return nil
}
// WriteAssertions see [storage.AssertionsBackend].WriteAssertions.
func (m *SQLite) WriteAssertions(ctx context.Context, store, modelID string, assertions []*openfgav1.Assertion) error {
ctx, span := tracer.Start(ctx, "sqlite.WriteAssertions")
defer span.End()
marshalledAssertions, err := proto.Marshal(&openfgav1.Assertions{Assertions: assertions})
if err != nil {
return err
}
return m.busyRetry(func() error {
_, err = m.stbl.
Insert("assertion").
Columns("store", "authorization_model_id", "assertions").
Values(store, modelID, marshalledAssertions).
Suffix("ON CONFLICT(store,authorization_model_id) DO UPDATE SET assertions = ?", marshalledAssertions).
ExecContext(ctx)
if err != nil {
return handleSQLError(err)
}
return nil
})
}
// ReadAssertions see [storage.AssertionsBackend].ReadAssertions.
func (m *SQLite) ReadAssertions(ctx context.Context, store, modelID string) ([]*openfgav1.Assertion, error) {
ctx, span := tracer.Start(ctx, "sqlite.ReadAssertions")
defer span.End()
var marshalledAssertions []byte
err := m.stbl.
Select("assertions").
From("assertion").
Where(sq.Eq{
"store": store,
"authorization_model_id": modelID,
}).
QueryRowContext(ctx).
Scan(&marshalledAssertions)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return []*openfgav1.Assertion{}, nil
}
return nil, handleSQLError(err)
}
var assertions openfgav1.Assertions
err = proto.Unmarshal(marshalledAssertions, &assertions)
if err != nil {
return nil, err
}
return assertions.GetAssertions(), nil
}
// ReadChanges see [storage.ChangelogBackend].ReadChanges.
func (m *SQLite) ReadChanges(
ctx context.Context,
store, objectTypeFilter string,
opts storage.PaginationOptions,
horizonOffset time.Duration,
) ([]*openfgav1.TupleChange, []byte, error) {
ctx, span := tracer.Start(ctx, "sqlite.ReadChanges")
defer span.End()
sb := m.stbl.
Select(
"ulid", "object_type", "object_id", "relation", "_user", "operation",
"condition_name", "condition_context", "inserted_at",
).
From("changelog").
Where(sq.Eq{"store": store}).
Where(fmt.Sprintf("inserted_at <= datetime('subsec','-%f seconds')", horizonOffset.Seconds())).
OrderBy("ulid asc")
if objectTypeFilter != "" {
sb = sb.Where(sq.Eq{"object_type": objectTypeFilter})
}
if opts.From != "" {
token, err := sqlcommon.UnmarshallContToken(opts.From)
if err != nil {
return nil, nil, err
}
if token.ObjectType != objectTypeFilter {
return nil, nil, storage.ErrMismatchObjectType
}
sb = sb.Where(sq.Gt{"ulid": token.Ulid}) // > as we always return a continuation token.
}
if opts.PageSize > 0 {
sb = sb.Limit(uint64(opts.PageSize)) // + 1 is NOT used here as we always return a continuation token.
}
rows, err := sb.QueryContext(ctx)
if err != nil {
return nil, nil, handleSQLError(err)
}
defer func() { _ = rows.Close() }()
var changes []*openfgav1.TupleChange
var ulid string
for rows.Next() {
var objectType, objectID, relation, user string
var operation int
var insertedAt time.Time
var conditionName sql.NullString
var conditionContext []byte
err = rows.Scan(
&ulid,
&objectType,
&objectID,
&relation,
&user,
&operation,
&conditionName,
&conditionContext,
&insertedAt,
)
if err != nil {
return nil, nil, handleSQLError(err)
}
var conditionContextStruct structpb.Struct
if conditionName.String != "" {
if conditionContext != nil {
if err := proto.Unmarshal(conditionContext, &conditionContextStruct); err != nil {
return nil, nil, err
}
}
}
tk := tupleUtils.NewTupleKeyWithCondition(
tupleUtils.BuildObject(objectType, objectID),
relation,
user,
conditionName.String,
&conditionContextStruct,
)
changes = append(changes, &openfgav1.TupleChange{
TupleKey: tk,
Operation: openfgav1.TupleOperation(operation),
Timestamp: timestamppb.New(insertedAt.UTC()),
})
}
if len(changes) == 0 {
return nil, nil, storage.ErrNotFound
}
contToken, err := json.Marshal(sqlcommon.NewContToken(ulid, objectTypeFilter))
if err != nil {
return nil, nil, err
}
return changes, contToken, nil
}
func (m *SQLite) IsReady(ctx context.Context) (storage.ReadinessStatus, error) {
if err := m.db.PingContext(ctx); err != nil {
return storage.ReadinessStatus{}, err
}
return storage.ReadinessStatus{
IsReady: true,
}, nil
}
// SQLite will return an SQLITE_BUSY error when the database is locked rather than waiting for the lock.
// This function retries the operation up to 5 times before returning the error.
func (m *SQLite) busyRetry(fn func() error) error {
for retries := 0; ; retries++ {
err := fn()
if err == nil || retries == m.cfg.QueryRetries {
return err
}
var sqliteErr *sqlite3.Error
if errors.As(err, &sqliteErr) && (sqliteErr.Code == sqlite3.ErrLocked || sqliteErr.Code == sqlite3.ErrBusy) {
time.Sleep(10 * time.Millisecond)
continue
}
return err
}
}
func handleSQLError(err error, args ...any) error {
if strings.Contains(err.Error(), "UNIQUE constraint failed:") {
if len(args) > 0 {
if tk, ok := args[0].(*openfgav1.TupleKey); ok {
return storage.InvalidWriteInputError(tk, openfgav1.TupleOperation_TUPLE_OPERATION_WRITE)
}
}
return storage.ErrCollision
}
return sqlcommon.HandleSQLError(err, args...)
}
@@ -1,295 +0,0 @@
package sqlite
import (
"context"
"database/sql"
"testing"
"time"
sq "github.com/Masterminds/squirrel"
"github.com/oklog/ulid/v2"
openfgav1 "github.com/openfga/api/proto/openfga/v1"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
"github.com/openfga/openfga/pkg/storage"
"github.com/openfga/openfga/pkg/storage/sqlcommon"
"github.com/openfga/openfga/pkg/storage/test"
"github.com/openfga/openfga/pkg/tuple"
"github.com/openfga/openfga/pkg/typesystem"
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
"github.com/grafana/grafana/pkg/tests/testsuite"
zassets "github.com/grafana/grafana/pkg/services/authz/zanzana/store/assets"
"github.com/grafana/grafana/pkg/services/authz/zanzana/store/migration"
)
func TestMain(m *testing.M) {
testsuite.Run(m)
}
// TestIntegrationDatastore runs open fga default datastore test suite
func TestIntegrationDatastore(t *testing.T) {
db := sqliteIntegrationTest(t)
ds, err := NewWithDB(db, NewConfig())
require.NoError(t, err)
test.RunAllTests(t, ds)
}
// TestIntegrationReadEnsureNoOrder asserts that the read response is not ordered by ulid.
func TestIntegrationReadEnsureNoOrder(t *testing.T) {
db := sqliteIntegrationTest(t)
ds, err := NewWithDB(db, NewConfig())
require.NoError(t, err)
ctx := context.Background()
store := "store"
firstTuple := tuple.NewTupleKey("doc:object_id_1", "relation", "user:user_1")
secondTuple := tuple.NewTupleKey("doc:object_id_2", "relation", "user:user_2")
err = sqlcommon.Write(ctx,
sqlcommon.NewDBInfo(ds.db, ds.stbl, sq.Expr("datetime('subsec')")),
store,
[]*openfgav1.TupleKeyWithoutCondition{},
[]*openfgav1.TupleKey{firstTuple},
time.Now())
require.NoError(t, err)
// Tweak time so that ULID is smaller.
err = sqlcommon.Write(ctx,
sqlcommon.NewDBInfo(ds.db, ds.stbl, sq.Expr("datetime('subsec')")),
store,
[]*openfgav1.TupleKeyWithoutCondition{},
[]*openfgav1.TupleKey{secondTuple},
time.Now().Add(time.Minute*-1))
require.NoError(t, err)
iter, err := ds.Read(ctx,
store,
tuple.NewTupleKey("doc:", "relation", ""))
defer iter.Stop()
require.NoError(t, err)
// We expect that objectID1 will return first because it is inserted first.
curTuple, err := iter.Next(ctx)
require.NoError(t, err)
require.Equal(t, firstTuple, curTuple.GetKey())
curTuple, err = iter.Next(ctx)
require.NoError(t, err)
require.Equal(t, secondTuple, curTuple.GetKey())
}
// TestIntegrationReadPageEnsureNoOrder asserts that the read page is ordered by ulid.
func TestIntegrationReadPageEnsureOrder(t *testing.T) {
db := sqliteIntegrationTest(t)
ds, err := NewWithDB(db, NewConfig())
require.NoError(t, err)
ctx := context.Background()
store := "store"
firstTuple := tuple.NewTupleKey("doc:object_id_1", "relation", "user:user_1")
secondTuple := tuple.NewTupleKey("doc:object_id_2", "relation", "user:user_2")
err = sqlcommon.Write(ctx,
sqlcommon.NewDBInfo(ds.db, ds.stbl, sq.Expr("datetime('subsec')")),
store,
[]*openfgav1.TupleKeyWithoutCondition{},
[]*openfgav1.TupleKey{firstTuple},
time.Now())
require.NoError(t, err)
// Tweak time so that ULID is smaller.
err = sqlcommon.Write(ctx,
sqlcommon.NewDBInfo(ds.db, ds.stbl, sq.Expr("datetime('subsec')")),
store,
[]*openfgav1.TupleKeyWithoutCondition{},
[]*openfgav1.TupleKey{secondTuple},
time.Now().Add(time.Minute*-1))
require.NoError(t, err)
tuples, _, err := ds.ReadPage(ctx,
store,
tuple.NewTupleKey("doc:", "relation", ""),
storage.NewPaginationOptions(0, ""))
require.NoError(t, err)
require.Len(t, tuples, 2)
// We expect that objectID2 will return first because it has a smaller ulid.
require.Equal(t, secondTuple, tuples[0].GetKey())
require.Equal(t, firstTuple, tuples[1].GetKey())
}
func TestIntegrationReadAuthorizationModelUnmarshallError(t *testing.T) {
db := sqliteIntegrationTest(t)
ds, err := NewWithDB(db, NewConfig())
require.NoError(t, err)
ctx := context.Background()
store := "store"
modelID := "foo"
schemaVersion := typesystem.SchemaVersion1_0
bytes, err := proto.Marshal(&openfgav1.TypeDefinition{Type: "document"})
require.NoError(t, err)
pbdata := []byte{0x01, 0x02, 0x03}
_, err = ds.db.ExecContext(ctx, "INSERT INTO authorization_model (store, authorization_model_id, schema_version, type, type_definition, serialized_protobuf) VALUES (?, ?, ?, ?, ?, ?)", store, modelID, schemaVersion, "document", bytes, pbdata)
require.NoError(t, err)
_, err = ds.ReadAuthorizationModel(ctx, store, modelID)
require.Error(t, err)
require.Contains(t, err.Error(), "cannot parse invalid wire-format data")
}
// TestIntegrationAllowNullCondition tests that tuple and changelog rows existing before
// migration 005_add_conditions_to_tuples can be successfully read.
func TestIntegrationAllowNullCondition(t *testing.T) {
db := sqliteIntegrationTest(t)
ds, err := NewWithDB(db, NewConfig())
require.NoError(t, err)
ctx := context.Background()
stmt := `
INSERT INTO tuple (
store, object_type, object_id, relation, _user, user_type, ulid,
condition_name, condition_context, inserted_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('subsec'));
`
_, err = ds.db.ExecContext(
ctx, stmt, "store", "folder", "2021-budget", "owner", "user:anne", "user",
ulid.Make().String(), nil, nil,
)
require.NoError(t, err)
tk := tuple.NewTupleKey("folder:2021-budget", "owner", "user:anne")
iter, err := ds.Read(ctx, "store", tk)
require.NoError(t, err)
defer iter.Stop()
curTuple, err := iter.Next(ctx)
require.NoError(t, err)
require.Equal(t, tk, curTuple.GetKey())
tuples, _, err := ds.ReadPage(ctx, "store", &openfgav1.TupleKey{}, storage.PaginationOptions{
PageSize: 2,
})
require.NoError(t, err)
require.Len(t, tuples, 1)
require.Equal(t, tk, tuples[0].GetKey())
userTuple, err := ds.ReadUserTuple(ctx, "store", tk)
require.NoError(t, err)
require.Equal(t, tk, userTuple.GetKey())
tk2 := tuple.NewTupleKey("folder:2022-budget", "viewer", "user:anne")
_, err = ds.db.ExecContext(
ctx, stmt, "store", "folder", "2022-budget", "viewer", "user:anne", "userset",
ulid.Make().String(), nil, nil,
)
require.NoError(t, err)
iter, err = ds.ReadUsersetTuples(ctx, "store", storage.ReadUsersetTuplesFilter{Object: "folder:2022-budget"})
require.NoError(t, err)
defer iter.Stop()
curTuple, err = iter.Next(ctx)
require.NoError(t, err)
require.Equal(t, tk2, curTuple.GetKey())
iter, err = ds.ReadStartingWithUser(ctx, "store", storage.ReadStartingWithUserFilter{
ObjectType: "folder",
Relation: "owner",
UserFilter: []*openfgav1.ObjectRelation{
{Object: "user:anne"},
},
})
require.NoError(t, err)
defer iter.Stop()
curTuple, err = iter.Next(ctx)
require.NoError(t, err)
require.Equal(t, tk, curTuple.GetKey())
stmt = `
INSERT INTO changelog (
store, object_type, object_id, relation, _user, ulid,
condition_name, condition_context, inserted_at, operation
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, datetime('subsec'), ?);
`
_, err = ds.db.ExecContext(
ctx, stmt, "store", "folder", "2021-budget", "owner", "user:anne",
ulid.Make().String(), nil, nil, openfgav1.TupleOperation_TUPLE_OPERATION_WRITE,
)
require.NoError(t, err)
_, err = ds.db.ExecContext(
ctx, stmt, "store", "folder", "2021-budget", "owner", "user:anne",
ulid.Make().String(), nil, nil, openfgav1.TupleOperation_TUPLE_OPERATION_DELETE,
)
require.NoError(t, err)
changes, _, err := ds.ReadChanges(ctx, "store", "folder", storage.PaginationOptions{}, 0)
require.NoError(t, err)
require.Len(t, changes, 2)
require.Equal(t, tk, changes[0].GetTupleKey())
require.Equal(t, tk, changes[1].GetTupleKey())
}
// TestIntegrationMarshalledAssertions tests that previously persisted marshalled
// assertions can be read back. In any case where the Assertions proto model
// needs to change, we'll likely need to introduce a series of data migrations.
func TestIntegrationMarshalledAssertions(t *testing.T) {
db := sqliteIntegrationTest(t)
ds, err := NewWithDB(db, NewConfig())
require.NoError(t, err)
ctx := context.Background()
// Note: this represents an assertion written on v1.3.7.
stmt := `
INSERT INTO assertion (
store, authorization_model_id, assertions
) VALUES (?, ?, UNHEX('0A2B0A270A12666F6C6465723A323032312D62756467657412056F776E65721A0A757365723A616E6E657A1001'));
`
_, err = ds.db.ExecContext(ctx, stmt, "store", "model")
require.NoError(t, err)
assertions, err := ds.ReadAssertions(ctx, "store", "model")
require.NoError(t, err)
expectedAssertions := []*openfgav1.Assertion{
{
TupleKey: &openfgav1.AssertionTupleKey{
Object: "folder:2021-budget",
Relation: "owner",
User: "user:annez",
},
Expectation: true,
},
}
require.Equal(t, expectedAssertions, assertions)
}
func sqliteIntegrationTest(tb testing.TB) *sql.DB {
if testing.Short() || !db.IsTestDbSQLite() {
tb.Skip("skipping integration test")
}
db, cfg := db.InitTestDBWithCfg(tb)
m := migrator.NewMigrator(db.GetEngine(), cfg)
err := migration.RunWithMigrator(m, cfg, zassets.EmbedMigrations, zassets.SQLiteMigrationDir)
require.NoError(tb, err)
return db.GetEngine().DB().DB
}
@@ -1,165 +0,0 @@
package sqlite
import (
"context"
"database/sql"
"time"
sq "github.com/Masterminds/squirrel"
"github.com/oklog/ulid/v2"
"google.golang.org/protobuf/proto"
openfgav1 "github.com/openfga/api/proto/openfga/v1"
"github.com/openfga/openfga/pkg/storage"
tupleUtils "github.com/openfga/openfga/pkg/tuple"
)
// write is copied from https://github.com/openfga/openfga/blob/main/pkg/storage/sqlcommon/sqlcommon.go#L330-L456
// but uses custom handleSQLError.
func write(
ctx context.Context,
db *sql.DB,
stbl sq.StatementBuilderType,
sqlTime any,
store string,
deletes storage.Deletes,
writes storage.Writes,
now time.Time,
) error {
txn, err := db.BeginTx(ctx, nil)
if err != nil {
return handleSQLError(err)
}
defer func() {
_ = txn.Rollback()
}()
changelogBuilder := stbl.
Insert("changelog").
Columns(
"store", "object_type", "object_id", "relation", "_user",
"condition_name", "condition_context", "operation", "ulid", "inserted_at",
)
deleteBuilder := stbl.Delete("tuple")
for _, tk := range deletes {
id := ulid.MustNew(ulid.Timestamp(now), ulid.DefaultEntropy()).String()
objectType, objectID := tupleUtils.SplitObject(tk.GetObject())
res, err := deleteBuilder.
Where(sq.Eq{
"store": store,
"object_type": objectType,
"object_id": objectID,
"relation": tk.GetRelation(),
"_user": tk.GetUser(),
"user_type": tupleUtils.GetUserTypeFromUser(tk.GetUser()),
}).
RunWith(txn). // Part of a txn.
ExecContext(ctx)
if err != nil {
return handleSQLError(err, tk)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return handleSQLError(err)
}
if rowsAffected != 1 {
return storage.InvalidWriteInputError(
tk,
openfgav1.TupleOperation_TUPLE_OPERATION_DELETE,
)
}
changelogBuilder = changelogBuilder.Values(
store, objectType, objectID,
tk.GetRelation(), tk.GetUser(),
"", nil, // Redact condition info for deletes since we only need the base triplet (object, relation, user).
openfgav1.TupleOperation_TUPLE_OPERATION_DELETE,
id, sqlTime,
)
}
insertBuilder := stbl.
Insert("tuple").
Columns(
"store", "object_type", "object_id", "relation", "_user", "user_type",
"condition_name", "condition_context", "ulid", "inserted_at",
)
for _, tk := range writes {
id := ulid.MustNew(ulid.Timestamp(now), ulid.DefaultEntropy()).String()
objectType, objectID := tupleUtils.SplitObject(tk.GetObject())
conditionName, conditionContext, err := marshalRelationshipCondition(tk.GetCondition())
if err != nil {
return err
}
_, err = insertBuilder.
Values(
store,
objectType,
objectID,
tk.GetRelation(),
tk.GetUser(),
tupleUtils.GetUserTypeFromUser(tk.GetUser()),
conditionName,
conditionContext,
id,
sqlTime,
).
RunWith(txn). // Part of a txn.
ExecContext(ctx)
if err != nil {
return handleSQLError(err, tk)
}
changelogBuilder = changelogBuilder.Values(
store,
objectType,
objectID,
tk.GetRelation(),
tk.GetUser(),
conditionName,
conditionContext,
openfgav1.TupleOperation_TUPLE_OPERATION_WRITE,
id,
sqlTime,
)
}
if len(writes) > 0 || len(deletes) > 0 {
_, err := changelogBuilder.RunWith(txn).ExecContext(ctx) // Part of a txn.
if err != nil {
return handleSQLError(err)
}
}
if err := txn.Commit(); err != nil {
return handleSQLError(err)
}
return nil
}
// copied from https://github.com/openfga/openfga/blob/main/pkg/storage/sqlcommon/encoding.go#L8-L24
func marshalRelationshipCondition(
rel *openfgav1.RelationshipCondition,
) (name string, context []byte, err error) {
if rel != nil {
if rel.GetContext() != nil && len(rel.GetContext().GetFields()) > 0 {
context, err = proto.Marshal(rel.GetContext())
if err != nil {
return name, context, err
}
}
return rel.GetName(), context, err
}
return name, context, err
}
+15 -25
View File
@@ -2,15 +2,15 @@ package store
import (
"fmt"
"strings"
"time"
"xorm.io/xorm"
"github.com/openfga/openfga/assets"
"github.com/openfga/openfga/pkg/storage"
"github.com/openfga/openfga/pkg/storage/mysql"
"github.com/openfga/openfga/pkg/storage/postgres"
"github.com/openfga/openfga/pkg/storage/sqlcommon"
"github.com/openfga/openfga/pkg/storage/sqlite"
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/infra/log"
@@ -19,9 +19,7 @@ import (
"github.com/grafana/grafana/pkg/setting"
zlogger "github.com/grafana/grafana/pkg/services/authz/zanzana/logger"
zassets "github.com/grafana/grafana/pkg/services/authz/zanzana/store/assets"
"github.com/grafana/grafana/pkg/services/authz/zanzana/store/migration"
"github.com/grafana/grafana/pkg/services/authz/zanzana/store/sqlite"
)
func NewStore(cfg *setting.Cfg, logger log.Logger) (storage.OpenFGADatastore, error) {
@@ -32,22 +30,12 @@ func NewStore(cfg *setting.Cfg, logger log.Logger) (storage.OpenFGADatastore, er
switch grafanaDBCfg.Type {
case migrator.SQLite:
connStr := grafanaDBCfg.ConnectionString
// Initilize connection using xorm engine so we can reuse it for both migrations and data store
engine, err := xorm.NewEngine(grafanaDBCfg.Type, connStr)
if err != nil {
return nil, fmt.Errorf("failed to connect to database: %w", err)
}
m := migrator.NewMigrator(engine, cfg)
if err := migration.RunWithMigrator(m, cfg, zassets.EmbedMigrations, zassets.SQLiteMigrationDir); err != nil {
connStr := sqliteConnectionString(grafanaDBCfg.ConnectionString)
if err := migration.Run(cfg, migrator.SQLite, connStr, assets.EmbedMigrations, assets.SqliteMigrationDir); err != nil {
return nil, fmt.Errorf("failed to run migrations: %w", err)
}
return sqlite.NewWithDB(engine.DB().DB, &sqlite.Config{
Config: zanzanaDBCfg,
QueryRetries: grafanaDBCfg.QueryRetries,
})
return sqlite.New(connStr, zanzanaDBCfg)
case migrator.MySQL:
// For mysql we need to pass parseTime parameter in connection string
connStr := grafanaDBCfg.ConnectionString + "&parseTime=true"
@@ -75,20 +63,16 @@ func NewEmbeddedStore(cfg *setting.Cfg, db db.DB, logger log.Logger) (storage.Op
return nil, fmt.Errorf("failed to parse database config: %w", err)
}
m := migrator.NewMigrator(db.GetEngine(), cfg)
switch grafanaDBCfg.Type {
case migrator.SQLite:
if err := migration.RunWithMigrator(m, cfg, zassets.EmbedMigrations, zassets.SQLiteMigrationDir); err != nil {
grafanaDBCfg.ConnectionString = sqliteConnectionString(grafanaDBCfg.ConnectionString)
if err := migration.Run(cfg, migrator.SQLite, grafanaDBCfg.ConnectionString, assets.EmbedMigrations, assets.SqliteMigrationDir); err != nil {
return nil, fmt.Errorf("failed to run migrations: %w", err)
}
// FIXME(kalleep): We should work on getting sqlite implemtation merged upstream and replace this one
return sqlite.NewWithDB(db.GetEngine().DB().DB, &sqlite.Config{
Config: zanzanaDBCfg,
QueryRetries: grafanaDBCfg.QueryRetries,
})
return sqlite.New(grafanaDBCfg.ConnectionString, zanzanaDBCfg)
case migrator.MySQL:
m := migrator.NewMigrator(db.GetEngine(), cfg)
if err := migration.RunWithMigrator(m, cfg, assets.EmbedMigrations, assets.MySQLMigrationDir); err != nil {
return nil, fmt.Errorf("failed to run migrations: %w", err)
}
@@ -96,6 +80,7 @@ func NewEmbeddedStore(cfg *setting.Cfg, db db.DB, logger log.Logger) (storage.Op
// For mysql we need to pass parseTime parameter in connection string
return mysql.New(grafanaDBCfg.ConnectionString+"&parseTime=true", zanzanaDBCfg)
case migrator.Postgres:
m := migrator.NewMigrator(db.GetEngine(), cfg)
if err := migration.RunWithMigrator(m, cfg, assets.EmbedMigrations, assets.PostgresMigrationDir); err != nil {
return nil, fmt.Errorf("failed to run migrations: %w", err)
}
@@ -126,3 +111,8 @@ func parseConfig(cfg *setting.Cfg, logger log.Logger) (*sqlstore.DatabaseConfig,
return grafanaDBCfg, zanzanaDBCfg, nil
}
func sqliteConnectionString(v string) string {
// hardcode zanzana.db for now
return v[0:strings.LastIndex(v, "/")+1] + "zanzana.db"
}