mirror of
https://github.com/grafana/grafana.git
synced 2026-02-03 20:49:50 -05:00
Advisor: App installer setup (#113525)
This commit is contained in:
parent
6c512dabdc
commit
d83c35fd71
25 changed files with 125 additions and 487 deletions
|
|
@ -152,28 +152,3 @@ Check [`security_config_step.go`](./pkg/app/checks/configchecks/security_config_
|
|||
## Testing
|
||||
|
||||
Create tests for your check and its steps to ensure they work as expected. Test both successful and failure scenarios.
|
||||
|
||||
## Running the Standalone Mode
|
||||
|
||||
To run the standalone mode, you can use the `make run` command. This will start the advisor app in standalone mode, which means it will not be running in a Kubernetes cluster.
|
||||
|
||||
```bash
|
||||
make etcd # Start etcd in a docker container
|
||||
make run # Start the advisor app in standalone mode
|
||||
```
|
||||
|
||||
This will start the advisor app on port 7445. You can then access the advisor app at `http://localhost:7445`.
|
||||
|
||||
To see some sample checks, you can run the following command:
|
||||
|
||||
```bash
|
||||
make create-checks
|
||||
```
|
||||
|
||||
Then you can see list in the URL: `http://localhost:7445/apis/advisor.grafana.app/v0alpha1/namespaces/stacks-1/checks`
|
||||
|
||||
To delete all checks, you can run the following command:
|
||||
|
||||
```bash
|
||||
make delete-checks
|
||||
```
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@ require (
|
|||
github.com/stretchr/testify v1.11.1
|
||||
k8s.io/apimachinery v0.34.1
|
||||
k8s.io/apiserver v0.34.1
|
||||
k8s.io/client-go v0.34.1
|
||||
k8s.io/component-base v0.34.1
|
||||
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912
|
||||
)
|
||||
|
||||
|
|
@ -45,7 +43,6 @@ replace github.com/grafana/grafana/apps/plugins => ../plugins
|
|||
replace github.com/prometheus/alertmanager => github.com/grafana/prometheus-alertmanager v0.25.1-0.20250911094103-5456b6e45604
|
||||
|
||||
require (
|
||||
cel.dev/expr v0.24.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.7.0 // indirect
|
||||
dario.cat/mergo v1.0.2 // indirect
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
|
|
@ -58,7 +55,6 @@ require (
|
|||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver v1.5.0 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.3.0 // indirect
|
||||
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.1.6 // indirect
|
||||
github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f // indirect
|
||||
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect
|
||||
|
|
@ -89,7 +85,6 @@ require (
|
|||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cheekybits/genny v1.0.0 // indirect
|
||||
github.com/cloudflare/circl v1.6.1 // indirect
|
||||
github.com/coreos/go-semver v0.3.1 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
|
|
@ -105,7 +100,6 @@ require (
|
|||
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
|
||||
github.com/gchaincl/sqlhooks v1.3.0 // indirect
|
||||
github.com/getkin/kin-openapi v0.133.0 // indirect
|
||||
|
|
@ -148,7 +142,6 @@ require (
|
|||
github.com/golang-migrate/migrate/v4 v4.7.0 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/cel-go v0.26.1 // indirect
|
||||
github.com/google/flatbuffers v25.2.10+incompatible // indirect
|
||||
github.com/google/gnostic-models v0.7.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
|
|
@ -168,7 +161,6 @@ require (
|
|||
github.com/grafana/sqlds/v4 v4.2.7 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
||||
|
|
@ -183,7 +175,6 @@ require (
|
|||
github.com/hashicorp/memberlist v0.5.2 // indirect
|
||||
github.com/hashicorp/yamux v0.1.2 // indirect
|
||||
github.com/huandu/xstrings v1.5.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jaegertracing/jaeger-idl v0.5.0 // indirect
|
||||
github.com/jessevdk/go-flags v1.6.1 // indirect
|
||||
github.com/jmespath-community/go-jmespath v1.1.1 // indirect
|
||||
|
|
@ -256,9 +247,7 @@ require (
|
|||
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
github.com/spf13/cobra v1.10.1 // indirect
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
github.com/stoewer/go-strcase v1.3.1 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/tetratelabs/wazero v1.8.2 // indirect
|
||||
github.com/thomaspoignant/go-feature-flag v1.42.0 // indirect
|
||||
|
|
@ -266,9 +255,6 @@ require (
|
|||
github.com/woodsbury/decimal128 v1.3.0 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/zeebo/xxh3 v1.0.2 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.6.4 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.6.4 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.6.4 // indirect
|
||||
go.mongodb.org/mongo-driver v1.17.4 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect
|
||||
|
|
@ -287,8 +273,6 @@ require (
|
|||
go.opentelemetry.io/proto/otlp v1.7.1 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/mock v0.6.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/crypto v0.43.0 // indirect
|
||||
|
|
@ -311,25 +295,23 @@ require (
|
|||
google.golang.org/grpc v1.76.0 // indirect
|
||||
google.golang.org/protobuf v1.36.10 // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/mail.v2 v2.3.1 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/src-d/go-errors.v1 v1.0.0 // indirect
|
||||
gopkg.in/telebot.v3 v3.3.8 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/api v0.34.1 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.34.1 // indirect
|
||||
k8s.io/client-go v0.34.1 // indirect
|
||||
k8s.io/component-base v0.34.1 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/kms v0.34.1 // indirect
|
||||
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect
|
||||
modernc.org/libc v1.66.10 // indirect
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
modernc.org/memory v1.11.0 // indirect
|
||||
modernc.org/sqlite v1.39.1 // indirect
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
|
||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
|
||||
|
|
|
|||
|
|
@ -321,7 +321,6 @@ github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03V
|
|||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8=
|
||||
github.com/cznic/fileutil v0.0.0-20180108211300-6a051e75936f/go.mod h1:8S58EK26zhXSxzv7NQFpnliaOQsmDUxvoQO3rt154Vg=
|
||||
|
|
@ -446,8 +445,6 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
|||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
|
||||
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
|
||||
github.com/go-openapi/analysis v0.24.0 h1:vE/VFFkICKyYuTWYnplQ+aVr45vlG6NcZKC7BdIXhsA=
|
||||
github.com/go-openapi/analysis v0.24.0/go.mod h1:GLyoJA+bvmGGaHgpfeDh8ldpGo69fAJg7eeMDMRCIrw=
|
||||
github.com/go-openapi/errors v0.22.3 h1:k6Hxa5Jg1TUyZnOwV2Lh81j8ayNw5VVYLvKrp4zFKFs=
|
||||
|
|
@ -650,8 +647,6 @@ github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z
|
|||
github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
||||
github.com/grafana/alerting v0.0.0-20251009192429-9427c24835ae h1:NLPwY3tIP0lg0g9wTRiMcypm6VRXW6W+MOLBsq8JSVA=
|
||||
github.com/grafana/alerting v0.0.0-20251009192429-9427c24835ae/go.mod h1:VGjS5gDwWEADPP6pF/drqLxEImgeuHlEW5u8E5EfIrM=
|
||||
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f h1:Cbm6OKkOcJ+7CSZsGsEJzktC/SIa5bxVeYKQLuYK86o=
|
||||
|
|
@ -795,8 +790,6 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw
|
|||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
|
||||
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
|
||||
github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I=
|
||||
github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
||||
|
|
@ -1029,7 +1022,6 @@ github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSg
|
|||
github.com/pressly/goose/v3 v3.25.0 h1:6WeYhMWGRCzpyd89SpODFnCBCKz41KrVbRT58nVjGng=
|
||||
github.com/pressly/goose/v3 v3.25.0/go.mod h1:4hC1KrritdCxtuFsqgs1R4AU5bWtTAf+cnWvfhf2DNY=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
|
||||
|
|
@ -1047,7 +1039,6 @@ github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T
|
|||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||
|
|
@ -1062,7 +1053,6 @@ github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57J
|
|||
github.com/prometheus/exporter-toolkit v0.14.0 h1:NMlswfibpcZZ+H0sZBiTjrA3/aBFHkNZqE+iCj5EmRg=
|
||||
github.com/prometheus/exporter-toolkit v0.14.0/go.mod h1:Gu5LnVvt7Nr/oqTBUC23WILZepW0nffNo10XdhQcwWA=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
|
|
@ -1089,7 +1079,6 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t
|
|||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
|
||||
github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8=
|
||||
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||
|
|
@ -1112,8 +1101,6 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
|
|||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
|
||||
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
|
|
@ -1127,7 +1114,6 @@ github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
|
|||
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.13.0/go.mod h1:Icm2xNL3/8uyh/wFuB1jI7TiTNKp8632Nwegu+zgdYw=
|
||||
|
|
@ -1153,7 +1139,6 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
|
|
@ -1170,8 +1155,6 @@ github.com/thomaspoignant/go-feature-flag v1.42.0/go.mod h1:y0QiWH7chHWhGATb/+Xq
|
|||
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tjhop/slog-gokit v0.1.5 h1:ayloIUi5EK2QYB8eY4DOPO95/mRtMW42lUkp3quJohc=
|
||||
github.com/tjhop/slog-gokit v0.1.5/go.mod h1:yA48zAHvV+Sg4z4VRyeFyFUNNXd3JY5Zg84u3USICq0=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk=
|
||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
|
|
@ -1189,8 +1172,6 @@ github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcY
|
|||
github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs=
|
||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||
github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510 h1:S2dVYn90KE98chqDkyE9Z4N61UnQd+KOfgp5Iu53llk=
|
||||
github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
|
|
@ -1215,12 +1196,6 @@ go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+
|
|||
go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY=
|
||||
go.etcd.io/etcd/client/v3 v3.6.4 h1:YOMrCfMhRzY8NgtzUsHl8hC2EBSnuqbR3dh84Uryl7A=
|
||||
go.etcd.io/etcd/client/v3 v3.6.4/go.mod h1:jaNNHCyg2FdALyKWnd7hxZXZxZANb0+KGY+YQaEMISo=
|
||||
go.etcd.io/etcd/pkg/v3 v3.6.4 h1:fy8bmXIec1Q35/jRZ0KOes8vuFxbvdN0aAFqmEfJZWA=
|
||||
go.etcd.io/etcd/pkg/v3 v3.6.4/go.mod h1:kKcYWP8gHuBRcteyv6MXWSN0+bVMnfgqiHueIZnKMtE=
|
||||
go.etcd.io/etcd/server/v3 v3.6.4 h1:LsCA7CzjVt+8WGrdsnh6RhC0XqCsLkBly3ve5rTxMAU=
|
||||
go.etcd.io/etcd/server/v3 v3.6.4/go.mod h1:aYCL/h43yiONOv0QIR82kH/2xZ7m+IWYjzRmyQfnCAg=
|
||||
go.etcd.io/raft/v3 v3.6.0 h1:5NtvbDVYpnfZWcIHgGRk9DyzkBIXOi8j+DDp1IcnUWQ=
|
||||
go.etcd.io/raft/v3 v3.6.0/go.mod h1:nLvLevg6+xrVtHUmVaTcTz603gQPHfh7kUAwV6YpfGo=
|
||||
go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.mongodb.org/mongo-driver v1.17.4 h1:jUorfmVzljjr0FLzYQsGP8cgN/qzzxlY9Vh0C9KFXVw=
|
||||
go.mongodb.org/mongo-driver v1.17.4/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
|
||||
|
|
@ -1373,7 +1348,6 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r
|
|||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
|
@ -1785,7 +1759,6 @@ google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090/go.
|
|||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251002232023-7c0ddcbb5797 h1:CirRxTOwnRWVLKzDNrs0CXAaVozJoR4G9xvdRecrdpk=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251002232023-7c0ddcbb5797/go.mod h1:HSkG/KdJWusxU1F6CNrwNDjBMgisKxGnc5dAZfT0mjQ=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
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.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@ import (
|
|||
)
|
||||
|
||||
func New(cfg app.Config) (app.App, error) {
|
||||
// Needed until https://github.com/grafana/grafana-app-sdk/pull/1077
|
||||
if cfg.KubeConfig.APIPath == "" {
|
||||
cfg.KubeConfig.APIPath = "apis"
|
||||
}
|
||||
// Read config
|
||||
specificConfig, ok := cfg.SpecificConfig.(checkregistry.AdvisorAppConfig)
|
||||
if !ok {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package app
|
|||
import (
|
||||
"context"
|
||||
|
||||
claims "github.com/grafana/authlib/types"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
)
|
||||
|
|
@ -15,7 +16,22 @@ func GetAuthorizer() authorizer.Authorizer {
|
|||
return authorizer.DecisionNoOpinion, "", nil
|
||||
}
|
||||
|
||||
// require a user
|
||||
// Check for service identity
|
||||
if identity.IsServiceIdentity(ctx) {
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
}
|
||||
|
||||
// Check for access policy identity
|
||||
info, ok := claims.AuthInfoFrom(ctx)
|
||||
if ok && claims.IsIdentityType(info.GetIdentityType(), claims.TypeAccessPolicy) {
|
||||
// For access policy identities, we need to use ResourceAuthorizer
|
||||
// This requires an AccessClient, which should be provided by the API server
|
||||
// For now, we'll use the default ResourceAuthorizer from the API server
|
||||
// This will be set up by the API server's authorization chain
|
||||
return authorizer.DecisionNoOpinion, "", nil
|
||||
}
|
||||
|
||||
// For regular Grafana users, check if they are admin
|
||||
u, err := identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
return authorizer.DecisionDeny, "valid user is required", err
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"testing"
|
||||
|
||||
claims "github.com/grafana/authlib/types"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
|
|
@ -79,4 +80,12 @@ func (m *mockUser) HasRole(role identity.RoleType) bool {
|
|||
return role == identity.RoleAdmin && m.isGrafanaAdmin
|
||||
}
|
||||
|
||||
func (m *mockUser) GetUID() string {
|
||||
return "test-uid"
|
||||
}
|
||||
|
||||
func (m *mockUser) GetIdentityType() claims.IdentityType {
|
||||
return claims.TypeUser
|
||||
}
|
||||
|
||||
// Implement other methods of identity.Requester as needed
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
package mockchecks
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checks/datasourcecheck"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checks/plugincheck"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/repo"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginchecker"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||
)
|
||||
|
||||
// mockchecks.CheckRegistry is a mock implementation of the checkregistry.CheckService interface
|
||||
// TODO: Add mocked checks here
|
||||
type CheckRegistry struct {
|
||||
datasourceSvc datasources.DataSourceService
|
||||
pluginStore pluginstore.Store
|
||||
pluginClient plugins.Client
|
||||
pluginRepo repo.Service
|
||||
GrafanaVersion string
|
||||
pluginContextProvider datasourcecheck.PluginContextProvider
|
||||
updateChecker pluginchecker.PluginUpdateChecker
|
||||
pluginErrorResolver plugins.ErrorResolver
|
||||
}
|
||||
|
||||
func (m *CheckRegistry) Checks() []checks.Check {
|
||||
return []checks.Check{
|
||||
datasourcecheck.New(
|
||||
m.datasourceSvc,
|
||||
m.pluginStore,
|
||||
m.pluginContextProvider,
|
||||
m.pluginClient,
|
||||
m.pluginRepo,
|
||||
m.GrafanaVersion,
|
||||
),
|
||||
plugincheck.New(
|
||||
m.pluginStore,
|
||||
m.pluginRepo,
|
||||
m.updateChecker,
|
||||
m.pluginErrorResolver,
|
||||
m.GrafanaVersion,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func New() *CheckRegistry {
|
||||
return &CheckRegistry{
|
||||
datasourceSvc: &mocksvcs.DatasourceSvc{},
|
||||
pluginStore: &mocksvcs.PluginStore{},
|
||||
pluginClient: &mocksvcs.PluginClient{},
|
||||
pluginRepo: &mocksvcs.PluginRepo{},
|
||||
pluginContextProvider: &mocksvcs.PluginContextProvider{},
|
||||
updateChecker: &mocksvcs.UpdateChecker{},
|
||||
pluginErrorResolver: &mocksvcs.PluginErrorResolver{},
|
||||
GrafanaVersion: "1.0.0",
|
||||
}
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
package mocksvcs
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
)
|
||||
|
||||
var dss = map[string]*datasources.DataSource{
|
||||
"prometheus-uid": {
|
||||
ID: 1,
|
||||
UID: "prometheus-uid",
|
||||
Name: "Prometheus",
|
||||
Type: "prometheus",
|
||||
},
|
||||
"mysql-uid": {
|
||||
ID: 2,
|
||||
UID: "mysql-uid",
|
||||
Name: "MySQL",
|
||||
Type: "mysql",
|
||||
},
|
||||
"unknown-uid": {
|
||||
ID: 3,
|
||||
UID: "unknown-uid",
|
||||
Name: "Unknown",
|
||||
Type: "unknown",
|
||||
},
|
||||
}
|
||||
|
||||
type DatasourceSvc struct {
|
||||
datasources.DataSourceService
|
||||
}
|
||||
|
||||
func (m *DatasourceSvc) GetDataSources(ctx context.Context, query *datasources.GetDataSourcesQuery) ([]*datasources.DataSource, error) {
|
||||
sources := make([]*datasources.DataSource, 0, len(dss))
|
||||
for _, ds := range dss {
|
||||
sources = append(sources, ds)
|
||||
}
|
||||
return sources, nil
|
||||
}
|
||||
|
||||
func (m *DatasourceSvc) GetDataSource(ctx context.Context, query *datasources.GetDataSourceQuery) (*datasources.DataSource, error) {
|
||||
return dss[query.UID], nil
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
package mocksvcs
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
)
|
||||
|
||||
type PluginClient struct {
|
||||
plugins.Client
|
||||
}
|
||||
|
||||
func (m *PluginClient) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
|
||||
return &backend.CheckHealthResult{
|
||||
Status: backend.HealthStatusOk,
|
||||
Message: "Plugin is healthy",
|
||||
}, nil
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
package mocksvcs
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
)
|
||||
|
||||
type PluginContextProvider struct {
|
||||
}
|
||||
|
||||
// ACTUALLY USED by datasourcecheck
|
||||
func (m *PluginContextProvider) GetWithDataSource(ctx context.Context, pluginID string, user identity.Requester, ds *datasources.DataSource) (backend.PluginContext, error) {
|
||||
// Create a plugin context with sample data based on the datasource
|
||||
pluginContext := backend.PluginContext{
|
||||
PluginID: pluginID,
|
||||
PluginVersion: "1.0.0",
|
||||
OrgID: 1,
|
||||
DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{
|
||||
ID: ds.ID,
|
||||
UID: ds.UID,
|
||||
Name: ds.Name,
|
||||
URL: ds.URL,
|
||||
JSONData: []byte(`{
|
||||
"httpMethod": "GET",
|
||||
"timeout": "30s",
|
||||
"keepCookies": []
|
||||
}`),
|
||||
DecryptedSecureJSONData: map[string]string{
|
||||
"password": "sample-password",
|
||||
"apiKey": "sample-api-key",
|
||||
},
|
||||
},
|
||||
GrafanaConfig: backend.NewGrafanaCfg(map[string]string{
|
||||
"app_url": "http://localhost:3000",
|
||||
"default_timezone": "UTC",
|
||||
}),
|
||||
}
|
||||
|
||||
// Add user context if provided
|
||||
if user != nil && !user.IsNil() {
|
||||
pluginContext.User = &backend.User{
|
||||
Login: user.GetLogin(),
|
||||
Name: user.GetName(),
|
||||
Email: user.GetEmail(),
|
||||
Role: string(user.GetOrgRole()),
|
||||
}
|
||||
}
|
||||
|
||||
return pluginContext, nil
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
package mocksvcs
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
)
|
||||
|
||||
type PluginErrorResolver struct {
|
||||
}
|
||||
|
||||
// Assume no plugin with errors
|
||||
func (m *PluginErrorResolver) PluginErrors(ctx context.Context) []*plugins.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *PluginErrorResolver) PluginError(ctx context.Context, pluginID string) *plugins.Error {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
package mocksvcs
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins/repo"
|
||||
)
|
||||
|
||||
type PluginRepo struct {
|
||||
repo.Service
|
||||
}
|
||||
|
||||
func (m *PluginRepo) GetPluginsInfo(ctx context.Context, options repo.GetPluginsInfoOptions, compatOpts repo.CompatOpts) ([]repo.PluginInfo, error) {
|
||||
return []repo.PluginInfo{
|
||||
{
|
||||
ID: 1,
|
||||
Slug: "grafana-piechart-panel",
|
||||
Version: "1.6.0",
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Slug: "prometheus",
|
||||
Version: "10.0.0",
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
package mocksvcs
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||
)
|
||||
|
||||
type PluginStore struct {
|
||||
}
|
||||
|
||||
var ps = map[string]pluginstore.Plugin{
|
||||
"prometheus": {
|
||||
JSONData: plugins.JSONData{
|
||||
ID: "prometheus",
|
||||
Type: plugins.TypeDataSource,
|
||||
Name: "Prometheus",
|
||||
Info: plugins.Info{
|
||||
Author: plugins.InfoLink{
|
||||
Name: "Grafana Labs",
|
||||
},
|
||||
Version: "10.0.0",
|
||||
},
|
||||
Category: "Time series databases",
|
||||
State: plugins.ReleaseStateAlpha,
|
||||
Backend: true,
|
||||
Metrics: true,
|
||||
Logs: true,
|
||||
Alerting: true,
|
||||
Explore: true,
|
||||
},
|
||||
Class: plugins.ClassCore,
|
||||
Signature: plugins.SignatureStatusInternal,
|
||||
SignatureType: plugins.SignatureTypeGrafana,
|
||||
SignatureOrg: "grafana.com",
|
||||
},
|
||||
"test-datasource": {
|
||||
JSONData: plugins.JSONData{
|
||||
ID: "grafana-piechart-panel",
|
||||
Type: plugins.TypePanel,
|
||||
Name: "Pie Chart",
|
||||
Info: plugins.Info{
|
||||
Author: plugins.InfoLink{
|
||||
Name: "Grafana Labs",
|
||||
},
|
||||
Version: "1.6.0",
|
||||
},
|
||||
Category: "Visualization",
|
||||
State: plugins.ReleaseStateAlpha,
|
||||
},
|
||||
Class: plugins.ClassCore,
|
||||
Signature: plugins.SignatureStatusInternal,
|
||||
SignatureType: plugins.SignatureTypeGrafana,
|
||||
SignatureOrg: "grafana.com",
|
||||
},
|
||||
"grafana-piechart-panel": {
|
||||
JSONData: plugins.JSONData{
|
||||
ID: "prometheus",
|
||||
Type: plugins.TypeDataSource,
|
||||
Name: "Prometheus",
|
||||
Info: plugins.Info{
|
||||
Author: plugins.InfoLink{
|
||||
Name: "Grafana Labs",
|
||||
},
|
||||
Version: "10.0.0",
|
||||
},
|
||||
Category: "Time series databases",
|
||||
State: plugins.ReleaseStateAlpha,
|
||||
Backend: true,
|
||||
Metrics: true,
|
||||
Logs: true,
|
||||
Alerting: true,
|
||||
Explore: true,
|
||||
},
|
||||
Class: plugins.ClassCore,
|
||||
Signature: plugins.SignatureStatusInternal,
|
||||
SignatureType: plugins.SignatureTypeGrafana,
|
||||
SignatureOrg: "grafana.com",
|
||||
},
|
||||
"test-app": {
|
||||
JSONData: plugins.JSONData{
|
||||
ID: "test-app",
|
||||
Type: plugins.TypeApp,
|
||||
Name: "Test App",
|
||||
Info: plugins.Info{
|
||||
Author: plugins.InfoLink{
|
||||
Name: "Test Author",
|
||||
},
|
||||
Version: "2.0.0",
|
||||
},
|
||||
Category: "Application",
|
||||
State: plugins.ReleaseStateAlpha,
|
||||
AutoEnabled: true,
|
||||
},
|
||||
Class: plugins.ClassExternal,
|
||||
Signature: plugins.SignatureStatusValid,
|
||||
SignatureType: plugins.SignatureTypeCommercial,
|
||||
SignatureOrg: "test.com",
|
||||
},
|
||||
}
|
||||
|
||||
func (s *PluginStore) Plugin(ctx context.Context, pluginID string) (pluginstore.Plugin, bool) {
|
||||
p, ok := ps[pluginID]
|
||||
return p, ok
|
||||
}
|
||||
|
||||
func (s *PluginStore) Plugins(ctx context.Context, pluginTypes ...plugins.Type) []pluginstore.Plugin {
|
||||
plugins := make([]pluginstore.Plugin, 0, len(ps))
|
||||
for _, p := range ps {
|
||||
plugins = append(plugins, p)
|
||||
}
|
||||
return plugins
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
package mocksvcs
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||
)
|
||||
|
||||
type UpdateChecker struct {
|
||||
}
|
||||
|
||||
func (m *UpdateChecker) IsUpdatable(ctx context.Context, plugin pluginstore.Plugin) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (m *UpdateChecker) CanUpdate(pluginId string, currentVersion string, targetVersion string, onlyMinor bool) bool {
|
||||
return true
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/component-base/cli"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/app"
|
||||
"github.com/grafana/grafana-app-sdk/k8s/apiserver"
|
||||
"github.com/grafana/grafana-app-sdk/k8s/apiserver/cmd/server"
|
||||
"github.com/grafana/grafana-app-sdk/logging"
|
||||
"github.com/grafana/grafana-app-sdk/simple"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis"
|
||||
advisorapp "github.com/grafana/grafana/apps/advisor/pkg/app"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checkregistry"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checkregistry/mockchecks"
|
||||
)
|
||||
|
||||
func main() {
|
||||
logging.DefaultLogger = logging.NewSLogLogger(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
|
||||
Level: slog.LevelDebug,
|
||||
}))
|
||||
provider := simple.NewAppProvider(apis.LocalManifest(), nil, advisorapp.New)
|
||||
config := app.Config{
|
||||
KubeConfig: rest.Config{}, // this will be replaced by the apiserver loopback config
|
||||
ManifestData: *apis.LocalManifest().ManifestData,
|
||||
SpecificConfig: checkregistry.AdvisorAppConfig{
|
||||
CheckRegistry: mockchecks.New(),
|
||||
PluginConfig: map[string]string{},
|
||||
StackID: "1", // Numeric stack ID for standalone mode
|
||||
OrgService: nil, // Not needed when StackID is set
|
||||
},
|
||||
}
|
||||
installer, err := apiserver.NewDefaultAppInstaller(provider, config, &apis.GoTypeAssociator{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ctx := genericapiserver.SetupSignalContext()
|
||||
opts := apiserver.NewOptions([]apiserver.AppInstaller{installer})
|
||||
opts.RecommendedOptions.Authentication = nil
|
||||
opts.RecommendedOptions.Authorization = nil
|
||||
opts.RecommendedOptions.CoreAPI = nil
|
||||
opts.RecommendedOptions.EgressSelector = nil
|
||||
opts.RecommendedOptions.Admission.Plugins = admission.NewPlugins()
|
||||
opts.RecommendedOptions.Admission.RecommendedPluginOrder = []string{}
|
||||
opts.RecommendedOptions.Admission.EnablePlugins = []string{}
|
||||
opts.RecommendedOptions.Features.EnablePriorityAndFairness = false
|
||||
opts.RecommendedOptions.ExtraAdmissionInitializers = func(_ *genericapiserver.RecommendedConfig) ([]admission.PluginInitializer, error) {
|
||||
return nil, nil
|
||||
}
|
||||
cmd := server.NewCommandStartServer(ctx, opts)
|
||||
code := cli.Run(cmd)
|
||||
os.Exit(code)
|
||||
}
|
||||
|
|
@ -1222,6 +1222,10 @@ export interface FeatureToggles {
|
|||
*/
|
||||
dashboardTemplates?: boolean;
|
||||
/**
|
||||
* Enables Advisor app installer
|
||||
*/
|
||||
grafanaAdvisorAppInstaller?: boolean;
|
||||
/**
|
||||
* Enables app platform API for annotations
|
||||
* @default false
|
||||
*/
|
||||
|
|
|
|||
45
pkg/registry/apps/advisor/appinstaller.go
Normal file
45
pkg/registry/apps/advisor/appinstaller.go
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
package advisor
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana-app-sdk/app"
|
||||
appsdkapiserver "github.com/grafana/grafana-app-sdk/k8s/apiserver"
|
||||
"github.com/grafana/grafana-app-sdk/simple"
|
||||
advisorapi "github.com/grafana/grafana/apps/advisor/pkg/apis"
|
||||
advisorapp "github.com/grafana/grafana/apps/advisor/pkg/app"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checkregistry"
|
||||
"github.com/grafana/grafana/pkg/services/apiserver/appinstaller"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
var (
|
||||
_ appsdkapiserver.AppInstaller = (*AdvisorAppInstaller)(nil)
|
||||
_ appinstaller.AuthorizerProvider = (*AdvisorAppInstaller)(nil)
|
||||
)
|
||||
|
||||
type AdvisorAppInstaller struct {
|
||||
appsdkapiserver.AppInstaller
|
||||
}
|
||||
|
||||
// GetAuthorizer returns the authorizer for the plugins app.
|
||||
func (a *AdvisorAppInstaller) GetAuthorizer() authorizer.Authorizer {
|
||||
return advisorapp.GetAuthorizer()
|
||||
}
|
||||
|
||||
func ProvideAppInstaller() (*AdvisorAppInstaller, error) {
|
||||
provider := simple.NewAppProvider(advisorapi.LocalManifest(), nil, advisorapp.New)
|
||||
specificConfig := checkregistry.AdvisorAppConfig{}
|
||||
appConfig := app.Config{
|
||||
KubeConfig: rest.Config{},
|
||||
ManifestData: *advisorapi.LocalManifest().ManifestData,
|
||||
SpecificConfig: specificConfig,
|
||||
}
|
||||
|
||||
installer := &AdvisorAppInstaller{}
|
||||
i, err := appsdkapiserver.NewDefaultAppInstaller(provider, appConfig, advisorapi.NewGoTypeAssociator())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
installer.AppInstaller = i
|
||||
return installer, nil
|
||||
}
|
||||
|
|
@ -42,6 +42,7 @@ func ProvideAppInstallers(
|
|||
logsdrilldownAppInstaller *logsdrilldown.LogsDrilldownAppInstaller,
|
||||
annotationAppInstaller *annotation.AnnotationAppInstaller,
|
||||
exampleAppInstaller *example.ExampleAppInstaller,
|
||||
advisorAppInstaller *advisor.AdvisorAppInstaller,
|
||||
) []appsdkapiserver.AppInstaller {
|
||||
installers := []appsdkapiserver.AppInstaller{
|
||||
playlistAppInstaller,
|
||||
|
|
@ -71,6 +72,10 @@ func ProvideAppInstallers(
|
|||
if features.IsEnabledGlobally(featuremgmt.FlagKubernetesAnnotations) {
|
||||
installers = append(installers, annotationAppInstaller)
|
||||
}
|
||||
//nolint:staticcheck // not yet migrated to OpenFeature
|
||||
if features.IsEnabledGlobally(featuremgmt.FlagGrafanaAdvisor) && features.IsEnabledGlobally(featuremgmt.FlagGrafanaAdvisorAppInstaller) {
|
||||
installers = append(installers, advisorAppInstaller)
|
||||
}
|
||||
|
||||
return installers
|
||||
}
|
||||
|
|
@ -118,6 +123,7 @@ func ProvideBuilderRunners(
|
|||
}
|
||||
//nolint:staticcheck // not yet migrated to OpenFeature
|
||||
if features.IsEnabledGlobally(featuremgmt.FlagGrafanaAdvisor) &&
|
||||
!features.IsEnabledGlobally(featuremgmt.FlagGrafanaAdvisorAppInstaller) &&
|
||||
!slices.Contains(grafanaCfg.DisablePlugins, "grafana-advisor-app") {
|
||||
providers = append(providers, advisorAppProvider)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/registry/apps/advisor"
|
||||
"github.com/grafana/grafana/pkg/registry/apps/alerting/notifications"
|
||||
"github.com/grafana/grafana/pkg/registry/apps/alerting/rules"
|
||||
"github.com/grafana/grafana/pkg/registry/apps/annotation"
|
||||
|
|
@ -23,7 +24,7 @@ func TestProvideAppInstallers_Table(t *testing.T) {
|
|||
notificationsAppInstaller := ¬ifications.AlertingNotificationsAppInstaller{}
|
||||
annotationAppInstaller := &annotation.AnnotationAppInstaller{}
|
||||
exampleAppInstaller := &example.ExampleAppInstaller{}
|
||||
|
||||
advisorAppInstaller := &advisor.AdvisorAppInstaller{}
|
||||
tests := []struct {
|
||||
name string
|
||||
flags []any
|
||||
|
|
@ -39,7 +40,7 @@ func TestProvideAppInstallers_Table(t *testing.T) {
|
|||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
features := featuremgmt.WithFeatures(tt.flags...)
|
||||
got := ProvideAppInstallers(features, playlistInstaller, pluginsInstaller, nil, tt.rulesInst, correlationsAppInstaller, notificationsAppInstaller, nil, annotationAppInstaller, exampleAppInstaller)
|
||||
got := ProvideAppInstallers(features, playlistInstaller, pluginsInstaller, nil, tt.rulesInst, correlationsAppInstaller, notificationsAppInstaller, nil, annotationAppInstaller, exampleAppInstaller, advisorAppInstaller)
|
||||
if tt.expectRulesApp {
|
||||
require.Contains(t, got, tt.rulesInst)
|
||||
} else {
|
||||
|
|
|
|||
12
pkg/server/wire_gen.go
generated
12
pkg/server/wire_gen.go
generated
|
|
@ -807,7 +807,11 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v2 := appregistry.ProvideAppInstallers(featureToggles, playlistAppInstaller, pluginsAppInstaller, shortURLAppInstaller, alertingRulesAppInstaller, appInstaller, alertingNotificationsAppInstaller, logsDrilldownAppInstaller, annotationAppInstaller, exampleAppInstaller)
|
||||
advisorAppInstaller, err := advisor2.ProvideAppInstaller()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v2 := appregistry.ProvideAppInstallers(featureToggles, playlistAppInstaller, pluginsAppInstaller, shortURLAppInstaller, alertingRulesAppInstaller, appInstaller, alertingNotificationsAppInstaller, logsDrilldownAppInstaller, annotationAppInstaller, exampleAppInstaller, advisorAppInstaller)
|
||||
builderMetrics := builder.ProvideBuilderMetrics(registerer)
|
||||
apiserverService, err := apiserver.ProvideService(cfg, featureToggles, routeRegisterImpl, tracingService, serverLockService, sqlStore, kvStore, middlewareHandler, scopedPluginDatasourceProvider, plugincontextProvider, pluginstoreService, dualwriteService, resourceClient, inlineSecureValueSupport, eventualRestConfigProvider, v, eventualRestConfigProvider, registerer, aggregatorRunner, v2, builderMetrics)
|
||||
if err != nil {
|
||||
|
|
@ -1445,7 +1449,11 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v2 := appregistry.ProvideAppInstallers(featureToggles, playlistAppInstaller, pluginsAppInstaller, shortURLAppInstaller, alertingRulesAppInstaller, appInstaller, alertingNotificationsAppInstaller, logsDrilldownAppInstaller, annotationAppInstaller, exampleAppInstaller)
|
||||
advisorAppInstaller, err := advisor2.ProvideAppInstaller()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v2 := appregistry.ProvideAppInstallers(featureToggles, playlistAppInstaller, pluginsAppInstaller, shortURLAppInstaller, alertingRulesAppInstaller, appInstaller, alertingNotificationsAppInstaller, logsDrilldownAppInstaller, annotationAppInstaller, exampleAppInstaller, advisorAppInstaller)
|
||||
builderMetrics := builder.ProvideBuilderMetrics(registerer)
|
||||
apiserverService, err := apiserver.ProvideService(cfg, featureToggles, routeRegisterImpl, tracingService, serverLockService, sqlStore, kvStore, middlewareHandler, scopedPluginDatasourceProvider, plugincontextProvider, pluginstoreService, dualwriteService, resourceClient, inlineSecureValueSupport, eventualRestConfigProvider, v, eventualRestConfigProvider, registerer, aggregatorRunner, v2, builderMetrics)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import (
|
|||
gsmKMSProviders "github.com/grafana/grafana/pkg/registry/apis/secret/encryption/kmsproviders"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/secret/secretkeeper"
|
||||
secretService "github.com/grafana/grafana/pkg/registry/apis/secret/service"
|
||||
"github.com/grafana/grafana/pkg/registry/apps/advisor"
|
||||
"github.com/grafana/grafana/pkg/registry/backgroundsvcs"
|
||||
"github.com/grafana/grafana/pkg/registry/usagestatssvcs"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
|
|
@ -150,6 +151,7 @@ var wireExtsBasicSet = wire.NewSet(
|
|||
secret.ProvideSecureValueClient,
|
||||
provisioningExtras,
|
||||
configProviderExtras,
|
||||
advisor.ProvideAppInstaller,
|
||||
)
|
||||
|
||||
var wireExtsSet = wire.NewSet(
|
||||
|
|
|
|||
|
|
@ -2120,6 +2120,12 @@ var (
|
|||
Owner: grafanaSharingSquad,
|
||||
FrontendOnly: false,
|
||||
},
|
||||
{
|
||||
Name: "grafanaAdvisorAppInstaller",
|
||||
Description: "Enables Advisor app installer",
|
||||
Stage: FeatureStageExperimental,
|
||||
Owner: grafanaPluginsPlatformSquad,
|
||||
},
|
||||
{
|
||||
Name: "kubernetesAnnotations",
|
||||
Description: "Enables app platform API for annotations",
|
||||
|
|
|
|||
|
|
@ -272,4 +272,5 @@ pluginStoreServiceLoading,experimental,@grafana/plugins-platform-backend,false,f
|
|||
onlyStoreActionSets,GA,@grafana/identity-access-team,false,false,false
|
||||
panelTimeSettings,experimental,@grafana/dashboards-squad,false,false,false
|
||||
dashboardTemplates,experimental,@grafana/sharing-squad,false,false,false
|
||||
grafanaAdvisorAppInstaller,experimental,@grafana/plugins-platform-backend,false,false,false
|
||||
kubernetesAnnotations,experimental,@grafana/grafana-backend-services-squad,false,false,false
|
||||
|
|
|
|||
|
4
pkg/services/featuremgmt/toggles_gen.go
generated
4
pkg/services/featuremgmt/toggles_gen.go
generated
|
|
@ -1098,6 +1098,10 @@ const (
|
|||
// Enable template dashboards
|
||||
FlagDashboardTemplates = "dashboardTemplates"
|
||||
|
||||
// FlagGrafanaAdvisorAppInstaller
|
||||
// Enables Advisor app installer
|
||||
FlagGrafanaAdvisorAppInstaller = "grafanaAdvisorAppInstaller"
|
||||
|
||||
// FlagKubernetesAnnotations
|
||||
// Enables app platform API for annotations
|
||||
FlagKubernetesAnnotations = "kubernetesAnnotations"
|
||||
|
|
|
|||
|
|
@ -1808,6 +1808,18 @@
|
|||
"codeowner": "@grafana/plugins-platform-backend"
|
||||
}
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"name": "grafanaAdvisorAppInstaller",
|
||||
"resourceVersion": "1762790554324",
|
||||
"creationTimestamp": "2025-11-10T16:02:34Z"
|
||||
},
|
||||
"spec": {
|
||||
"description": "Enables Advisor app installer",
|
||||
"stage": "experimental",
|
||||
"codeowner": "@grafana/plugins-platform-backend"
|
||||
}
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"name": "grafanaAssistantInProfilesDrilldown",
|
||||
|
|
|
|||
Loading…
Reference in a new issue