From d83c35fd71f435dc0fdc83b6af43dd7bc3682d22 Mon Sep 17 00:00:00 2001 From: Andres Martinez Gotor Date: Wed, 12 Nov 2025 15:32:21 +0100 Subject: [PATCH] Advisor: App installer setup (#113525) --- apps/advisor/README.md | 25 ---- apps/advisor/go.mod | 22 +--- apps/advisor/go.sum | 27 ----- apps/advisor/pkg/app/app.go | 4 + apps/advisor/pkg/app/authorizer.go | 18 ++- apps/advisor/pkg/app/authorizer_test.go | 9 ++ .../checkregistry/mockchecks/checkregistry.go | 59 --------- .../mockchecks/mocksvcs/datasourcesvc.go | 44 ------- .../mockchecks/mocksvcs/pluginclient.go | 19 --- .../mocksvcs/plugincontextprovider.go | 53 -------- .../mocksvcs/pluginerrorresolver.go | 19 --- .../mockchecks/mocksvcs/pluginrepo.go | 26 ---- .../mockchecks/mocksvcs/pluginstore.go | 114 ------------------ .../mockchecks/mocksvcs/updatechecker.go | 18 --- apps/advisor/pkg/standalone/server.go | 58 --------- .../src/types/featureToggles.gen.ts | 4 + pkg/registry/apps/advisor/appinstaller.go | 45 +++++++ pkg/registry/apps/apps.go | 6 + pkg/registry/apps/apps_test.go | 5 +- pkg/server/wire_gen.go | 12 +- pkg/server/wireexts_oss.go | 2 + pkg/services/featuremgmt/registry.go | 6 + pkg/services/featuremgmt/toggles_gen.csv | 1 + pkg/services/featuremgmt/toggles_gen.go | 4 + pkg/services/featuremgmt/toggles_gen.json | 12 ++ 25 files changed, 125 insertions(+), 487 deletions(-) delete mode 100644 apps/advisor/pkg/app/checkregistry/mockchecks/checkregistry.go delete mode 100644 apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/datasourcesvc.go delete mode 100644 apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/pluginclient.go delete mode 100644 apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/plugincontextprovider.go delete mode 100644 apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/pluginerrorresolver.go delete mode 100644 apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/pluginrepo.go delete mode 100644 apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/pluginstore.go delete mode 100644 apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/updatechecker.go delete mode 100644 apps/advisor/pkg/standalone/server.go create mode 100644 pkg/registry/apps/advisor/appinstaller.go diff --git a/apps/advisor/README.md b/apps/advisor/README.md index 410a54f89e3..c7929d9db62 100644 --- a/apps/advisor/README.md +++ b/apps/advisor/README.md @@ -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 -``` diff --git a/apps/advisor/go.mod b/apps/advisor/go.mod index d646f81e055..834540f5f67 100644 --- a/apps/advisor/go.mod +++ b/apps/advisor/go.mod @@ -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 diff --git a/apps/advisor/go.sum b/apps/advisor/go.sum index 8d52f655960..b6232c51680 100644 --- a/apps/advisor/go.sum +++ b/apps/advisor/go.sum @@ -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= diff --git a/apps/advisor/pkg/app/app.go b/apps/advisor/pkg/app/app.go index 0e423957b82..d4019631ef6 100644 --- a/apps/advisor/pkg/app/app.go +++ b/apps/advisor/pkg/app/app.go @@ -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 { diff --git a/apps/advisor/pkg/app/authorizer.go b/apps/advisor/pkg/app/authorizer.go index 4d216ee9edd..576773330e3 100644 --- a/apps/advisor/pkg/app/authorizer.go +++ b/apps/advisor/pkg/app/authorizer.go @@ -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 diff --git a/apps/advisor/pkg/app/authorizer_test.go b/apps/advisor/pkg/app/authorizer_test.go index 1384176969e..de8c0fad2db 100644 --- a/apps/advisor/pkg/app/authorizer_test.go +++ b/apps/advisor/pkg/app/authorizer_test.go @@ -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 diff --git a/apps/advisor/pkg/app/checkregistry/mockchecks/checkregistry.go b/apps/advisor/pkg/app/checkregistry/mockchecks/checkregistry.go deleted file mode 100644 index e1b9cf88bf4..00000000000 --- a/apps/advisor/pkg/app/checkregistry/mockchecks/checkregistry.go +++ /dev/null @@ -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", - } -} diff --git a/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/datasourcesvc.go b/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/datasourcesvc.go deleted file mode 100644 index 73122e53adb..00000000000 --- a/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/datasourcesvc.go +++ /dev/null @@ -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 -} diff --git a/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/pluginclient.go b/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/pluginclient.go deleted file mode 100644 index a8ce175a687..00000000000 --- a/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/pluginclient.go +++ /dev/null @@ -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 -} diff --git a/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/plugincontextprovider.go b/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/plugincontextprovider.go deleted file mode 100644 index b5bb6f88e8e..00000000000 --- a/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/plugincontextprovider.go +++ /dev/null @@ -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 -} diff --git a/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/pluginerrorresolver.go b/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/pluginerrorresolver.go deleted file mode 100644 index db545827991..00000000000 --- a/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/pluginerrorresolver.go +++ /dev/null @@ -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 -} diff --git a/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/pluginrepo.go b/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/pluginrepo.go deleted file mode 100644 index 0ab8d225314..00000000000 --- a/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/pluginrepo.go +++ /dev/null @@ -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 -} diff --git a/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/pluginstore.go b/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/pluginstore.go deleted file mode 100644 index 782d93024f3..00000000000 --- a/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/pluginstore.go +++ /dev/null @@ -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 -} diff --git a/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/updatechecker.go b/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/updatechecker.go deleted file mode 100644 index efbeb217e74..00000000000 --- a/apps/advisor/pkg/app/checkregistry/mockchecks/mocksvcs/updatechecker.go +++ /dev/null @@ -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 -} diff --git a/apps/advisor/pkg/standalone/server.go b/apps/advisor/pkg/standalone/server.go deleted file mode 100644 index 80dd82418ef..00000000000 --- a/apps/advisor/pkg/standalone/server.go +++ /dev/null @@ -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) -} diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index a0f00b98b19..d52694ffaa1 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -1222,6 +1222,10 @@ export interface FeatureToggles { */ dashboardTemplates?: boolean; /** + * Enables Advisor app installer + */ + grafanaAdvisorAppInstaller?: boolean; + /** * Enables app platform API for annotations * @default false */ diff --git a/pkg/registry/apps/advisor/appinstaller.go b/pkg/registry/apps/advisor/appinstaller.go new file mode 100644 index 00000000000..31afbed23c5 --- /dev/null +++ b/pkg/registry/apps/advisor/appinstaller.go @@ -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 +} diff --git a/pkg/registry/apps/apps.go b/pkg/registry/apps/apps.go index 5c039264a4b..db165c752f5 100644 --- a/pkg/registry/apps/apps.go +++ b/pkg/registry/apps/apps.go @@ -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) } diff --git a/pkg/registry/apps/apps_test.go b/pkg/registry/apps/apps_test.go index 3c92bda62ad..5f46fd349be 100644 --- a/pkg/registry/apps/apps_test.go +++ b/pkg/registry/apps/apps_test.go @@ -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 { diff --git a/pkg/server/wire_gen.go b/pkg/server/wire_gen.go index 75aca8fcc9a..b10e7b81e3d 100644 --- a/pkg/server/wire_gen.go +++ b/pkg/server/wire_gen.go @@ -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 { diff --git a/pkg/server/wireexts_oss.go b/pkg/server/wireexts_oss.go index 1152431b320..b2b134ee4a9 100644 --- a/pkg/server/wireexts_oss.go +++ b/pkg/server/wireexts_oss.go @@ -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( diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index cf7202d4120..b614d7ab63f 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -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", diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index 317eff8c6bc..2865eb650c1 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -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 diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index 758d42e01ef..84e88452a10 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -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" diff --git a/pkg/services/featuremgmt/toggles_gen.json b/pkg/services/featuremgmt/toggles_gen.json index 4011467144c..7642f454ce3 100644 --- a/pkg/services/featuremgmt/toggles_gen.json +++ b/pkg/services/featuremgmt/toggles_gen.json @@ -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",