Azure: Use SSO settings in plugin context (#112058)
* Bump grafana-azure-sdk-go * Set override values * Add Azure settings helper covering SSO cases * Ensure Azure settings are correctly created - Add mock for sso settings service - Add tests - Update wire * Minor improvements * Test updates * Move fake implementation * add interface to limit leakage * rename * work sync * Fix wire * Add fake provider * Update tests * Actually fix the workspace * More go dependency fixes * Update tests * Update workspace, again * Add missing tests * Fix dependencies * These dependencies.. * More dependency things * Okay now dependencies really are fixed * Lint * Update pkg/services/pluginsintegration/pluginconfig/request.go Co-authored-by: Misi <mgyongyosi@users.noreply.github.com> --------- Co-authored-by: Will Browne <wbrowne@tcd.ie> Co-authored-by: Misi <mgyongyosi@users.noreply.github.com>
This commit is contained in:
co-authored by
Misi
Will Browne
parent
59459560c2
commit
fa9d6be255
@@ -13,8 +13,8 @@ require (
|
||||
filippo.io/age v1.2.1 // @grafana/identity-access-team
|
||||
github.com/1NCE-GmbH/grpc-go-pool v0.0.0-20231117122434-2a5bb974daa2 // @grafana/grafana-search-and-storage
|
||||
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // @grafana/partner-datasources
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.1 // @grafana/identity-access-team
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 // @grafana/grafana-backend-group
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1 // @grafana/identity-access-team
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0 // @grafana/grafana-backend-group
|
||||
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0 // @grafana/grafana-backend-group
|
||||
github.com/Azure/azure-storage-blob-go v0.15.0 // @grafana/grafana-backend-group
|
||||
github.com/Azure/go-autorest/autorest v0.11.29 // @grafana/grafana-backend-group
|
||||
@@ -99,7 +99,7 @@ require (
|
||||
github.com/grafana/grafana-app-sdk v0.46.0 // @grafana/grafana-app-platform-squad
|
||||
github.com/grafana/grafana-app-sdk/logging v0.45.0 // @grafana/grafana-app-platform-squad
|
||||
github.com/grafana/grafana-aws-sdk v1.2.0 // @grafana/aws-datasources
|
||||
github.com/grafana/grafana-azure-sdk-go/v2 v2.2.0 // @grafana/partner-datasources
|
||||
github.com/grafana/grafana-azure-sdk-go/v2 v2.3.1 // @grafana/partner-datasources
|
||||
github.com/grafana/grafana-cloud-migration-snapshot v1.9.0 // @grafana/grafana-operator-experience-squad
|
||||
github.com/grafana/grafana-google-sdk-go v0.4.2 // @grafana/partner-datasources
|
||||
github.com/grafana/grafana-openapi-client-go v0.0.0-20231213163343-bd475d63fb79 // @grafana/grafana-backend-group
|
||||
@@ -296,7 +296,7 @@ require (
|
||||
cloud.google.com/go/monitoring v1.24.2 // indirect
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20240906074133-82eb438dd565 // indirect
|
||||
github.com/Azure/azure-pipeline-go v0.2.3 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.1 // indirect
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||
@@ -306,7 +306,7 @@ require (
|
||||
github.com/Azure/go-autorest/logger v0.2.1 // indirect
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 // indirect
|
||||
github.com/FZambia/eagle v0.2.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 // indirect
|
||||
|
||||
@@ -648,14 +648,14 @@ github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl
|
||||
github.com/Azure/azure-sdk-for-go v23.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU=
|
||||
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.1 h1:Wc1ml6QlJs2BHQ/9Bqu1jiyggbsSjramq2oUmp5WeIo=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.1/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 h1:B+blDbyVIG3WaikNxPnhPiJ1MThR03b3vKGtER95TP4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1/go.mod h1:JdM5psgjfBf5fo2uWOZhflPWyDBZ/O/CNAH9CtsuZE4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1 h1:5YTBM8QDVIBN3sxBil89WfdAAqDZbyJTgh688DSxX5w=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1/go.mod h1:YD5h/ldMsG0XiIw7PdyNhLxaM317eFh5yNLccNfGdyw=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0 h1:wL5IEG5zb7BVv1Kv0Xm92orq+5hB5Nipn3B5tn4Rqfk=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0/go.mod h1:J7MUC/wtRpfGVbQ5sIItY5/FuVWmvzlY21WAOfQnq/I=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 h1:FPKJS1T+clwv+OLGt13a8UjqeRuh0O4SJ3lUriThc+4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1/go.mod h1:j2chePtV91HrC22tGoRX3sGY42uF13WzmmV80/OdVAA=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0 h1:m/sWOGCREuSBqg2htVQTBY8nOZpyajYztF0vUvSZTuM=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0/go.mod h1:Pu5Zksi2KrU7LPbZbNINx6fuVrUp/ffvpxdDj+i8LeE=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1 h1:FbH3BbSb4bvGluTesZZ+ttN/MDsnMmQP36OSnDuSXqw=
|
||||
@@ -703,8 +703,8 @@ github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e h1:NeAW1fUYUEWhft
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM=
|
||||
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 h1:XkkQbfMyuH2jTSjQjSoihryI8GINRcs4xp8lNawg0FI=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk=
|
||||
github.com/Bose/minisentinel v0.0.0-20200130220412-917c5a9223bb h1:ZVN4Iat3runWOFLaBCDVU5a9X/XikSRBosye++6gojw=
|
||||
github.com/Bose/minisentinel v0.0.0-20200130220412-917c5a9223bb/go.mod h1:WsAABbY4HQBgd3mGuG4KMNTbHJCPvx9IVBHzysbknss=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
@@ -1611,8 +1611,8 @@ github.com/grafana/grafana-app-sdk/logging v0.45.0 h1:0SH6nYZpiLBZRwUq4J6+1vo8xu
|
||||
github.com/grafana/grafana-app-sdk/logging v0.45.0/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA=
|
||||
github.com/grafana/grafana-aws-sdk v1.2.0 h1:LLR4/g91WBuCRwm2cbWfCREq565+GxIFe08nqqIcIuw=
|
||||
github.com/grafana/grafana-aws-sdk v1.2.0/go.mod h1:bBo7qOmM3f61vO+2JxTolNUph1l2TmtzmWcU9/Im+8A=
|
||||
github.com/grafana/grafana-azure-sdk-go/v2 v2.2.0 h1:0TYrkzAc3u0HX+9GK86cGrLTUAcmQfl3/LEB3tL+SOA=
|
||||
github.com/grafana/grafana-azure-sdk-go/v2 v2.2.0/go.mod h1:H9sVh9A4yg5egMGZeh0mifxT1Q/uqwKe1LBjBJU6pN8=
|
||||
github.com/grafana/grafana-azure-sdk-go/v2 v2.3.1 h1:FFcEA01tW+SmuJIuDbHOdgUBL+d7DPrZ2N4zwzPhfGk=
|
||||
github.com/grafana/grafana-azure-sdk-go/v2 v2.3.1/go.mod h1:Oi4anANlCuTCc66jCyqIzfVbgLXFll8Wja+Y4vfANlc=
|
||||
github.com/grafana/grafana-cloud-migration-snapshot v1.9.0 h1:JOzchPgptwJdruYoed7x28lFDwhzs7kssResYsnC0iI=
|
||||
github.com/grafana/grafana-cloud-migration-snapshot v1.9.0/go.mod h1:nOHgq4Oa829qmBKA5KIXw5Ipo3rhLs0d6A8UI9Nw8Zk=
|
||||
github.com/grafana/grafana-google-sdk-go v0.4.2 h1:F44hQF1y6UVJhlJPi+Mz+GCJsioVgezEgPMMEQbUZRo=
|
||||
|
||||
@@ -1224,6 +1224,8 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNU
|
||||
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
|
||||
github.com/kevinmbeaulieu/eq-go v1.0.0 h1:AQgYHURDOmnVJ62jnEk0W/7yFKEn+Lv8RHN6t7mB0Zo=
|
||||
github.com/kevinmbeaulieu/eq-go v1.0.0/go.mod h1:G3S8ajA56gKBZm4UB9AOyoOS37JO3roToPzKNM8dtdM=
|
||||
github.com/keybase/dbus v0.0.0-20220506165403-5aa21ea2c23a h1:K0EAzgzEQHW4Y5lxrmvPMltmlRDzlhLfGmots9EHUTI=
|
||||
github.com/keybase/dbus v0.0.0-20220506165403-5aa21ea2c23a/go.mod h1:YPNKjjE7Ubp9dTbnWvsP3HT+hYnY6TfXzubYTBeUxc8=
|
||||
github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY=
|
||||
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
|
||||
github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46 h1:veS9QfglfvqAw2e+eeNT/SbGySq8ajECXJ9e4fPoLhY=
|
||||
@@ -1336,6 +1338,7 @@ github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs=
|
||||
github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
|
||||
github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
|
||||
github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
|
||||
github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
|
||||
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
|
||||
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
|
||||
github.com/mostynb/go-grpc-compression v1.2.3 h1:42/BKWMy0KEJGSdWvzqIyOZ95YcR9mLPqKctH7Uo//I=
|
||||
@@ -1453,6 +1456,7 @@ github.com/phpdave11/gofpdf v1.4.2 h1:KPKiIbfwbvC/wOncwhrpRdXVj2CZTCFlw4wnoyjtHf
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
|
||||
github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM=
|
||||
github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A=
|
||||
github.com/pkg/sftp v1.13.1 h1:I2qBYMChEhIjOgazfJmV3/mZM256btk6wkCDRmW7JYs=
|
||||
github.com/pkg/sftp v1.13.7 h1:uv+I3nNJvlKZIQGSr8JVQLNHFU9YhhNpvC14Y6KgmSM=
|
||||
@@ -1995,6 +1999,7 @@ golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
||||
+2
-3
@@ -18,8 +18,8 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.1 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0 // indirect
|
||||
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||
github.com/apache/arrow-go/v18 v18.4.0 // indirect
|
||||
github.com/aws/aws-sdk-go v1.55.7 // indirect
|
||||
@@ -48,7 +48,6 @@ require (
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/gogo/googleapis v1.4.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/flatbuffers v25.2.10+incompatible // indirect
|
||||
github.com/google/gnostic-models v0.7.0 // indirect
|
||||
|
||||
+8
-8
@@ -5,14 +5,14 @@ cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIi
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
||||
cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU=
|
||||
cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.1 h1:Wc1ml6QlJs2BHQ/9Bqu1jiyggbsSjramq2oUmp5WeIo=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.1/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 h1:B+blDbyVIG3WaikNxPnhPiJ1MThR03b3vKGtER95TP4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1/go.mod h1:JdM5psgjfBf5fo2uWOZhflPWyDBZ/O/CNAH9CtsuZE4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 h1:FPKJS1T+clwv+OLGt13a8UjqeRuh0O4SJ3lUriThc+4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1/go.mod h1:j2chePtV91HrC22tGoRX3sGY42uF13WzmmV80/OdVAA=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1 h1:5YTBM8QDVIBN3sxBil89WfdAAqDZbyJTgh688DSxX5w=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1/go.mod h1:YD5h/ldMsG0XiIw7PdyNhLxaM317eFh5yNLccNfGdyw=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0 h1:wL5IEG5zb7BVv1Kv0Xm92orq+5hB5Nipn3B5tn4Rqfk=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0/go.mod h1:J7MUC/wtRpfGVbQ5sIItY5/FuVWmvzlY21WAOfQnq/I=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 h1:XkkQbfMyuH2jTSjQjSoihryI8GINRcs4xp8lNawg0FI=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
|
||||
+11
-8
@@ -188,6 +188,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginexternal"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller"
|
||||
service6 "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings/service"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsso"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/provisionedplugins"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/renderer"
|
||||
@@ -342,7 +343,10 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api
|
||||
hooksService := hooks.ProvideService()
|
||||
ossLicensingService := licensing.ProvideService(cfg, hooksService)
|
||||
licensingService := licensing2.ProvideLicensing(cfg, ossLicensingService)
|
||||
envVarsProvider := pluginconfig.NewEnvVarsProvider(pluginInstanceCfg, licensingService)
|
||||
registerer := metrics.ProvideRegisterer()
|
||||
ssosettingsimplService := ssosettingsimpl.ProvideService(cfg, sqlStore, accessControl, routeRegisterImpl, featureToggles, secretsService, usageStats, registerer, ossImpl, ossLicensingService)
|
||||
defaultSettingsProvider := pluginsso.ProvideDefaultSettingsProvider(ssosettingsimplService)
|
||||
envVarsProvider := pluginconfig.NewEnvVarsProvider(pluginInstanceCfg, licensingService, defaultSettingsProvider)
|
||||
inMemory := registry.ProvideService()
|
||||
rendererManager, err := renderer.ProvideService(pluginManagementCfg, envVarsProvider, inMemory, tracingService)
|
||||
if err != nil {
|
||||
@@ -424,7 +428,6 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api
|
||||
}
|
||||
publicDashboardStoreImpl := database3.ProvideStore(sqlStore, cfg, featureToggles)
|
||||
publicDashboardServiceWrapperImpl := service3.ProvideServiceWrapper(publicDashboardStoreImpl)
|
||||
registerer := metrics.ProvideRegisterer()
|
||||
apikeyService, err := apikeyimpl.ProvideService(sqlStore, cfg, quotaService)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -559,7 +562,6 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api
|
||||
pluginService := service7.ProvideDashboardPluginService(featureToggles, dashboardServiceImpl)
|
||||
service14 := service8.ProvideService(fileStoreManager, pluginService)
|
||||
orgRoleMapper := connectors.ProvideOrgRoleMapper(cfg, orgService)
|
||||
ssosettingsimplService := ssosettingsimpl.ProvideService(cfg, sqlStore, accessControl, routeRegisterImpl, featureToggles, secretsService, usageStats, registerer, ossImpl, ossLicensingService)
|
||||
socialService := socialimpl.ProvideService(cfg, featureToggles, usageStats, bundleregistryService, remoteCache, orgRoleMapper, ssosettingsimplService)
|
||||
loginStore := authinfoimpl.ProvideStore(sqlStore, secretsService)
|
||||
authinfoimplService := authinfoimpl.ProvideService(loginStore, remoteCache, secretsService)
|
||||
@@ -599,7 +601,7 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api
|
||||
return nil, err
|
||||
}
|
||||
datasourcePermissionsService := ossaccesscontrol.ProvideDatasourcePermissionsService(cfg, featureToggles, sqlStore)
|
||||
requestConfigProvider := pluginconfig.NewRequestConfigProvider(pluginInstanceCfg)
|
||||
requestConfigProvider := pluginconfig.NewRequestConfigProvider(pluginInstanceCfg, defaultSettingsProvider)
|
||||
baseProvider := plugincontext.ProvideBaseService(cfg, requestConfigProvider)
|
||||
service15, err := service9.ProvideService(sqlStore, secretsService, secretsKVStore, cfg, featureToggles, accessControl, datasourcePermissionsService, quotaService, pluginstoreService, middlewareHandler, baseProvider)
|
||||
if err != nil {
|
||||
@@ -943,7 +945,10 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
|
||||
hooksService := hooks.ProvideService()
|
||||
ossLicensingService := licensing.ProvideService(cfg, hooksService)
|
||||
licensingService := licensing2.ProvideLicensing(cfg, ossLicensingService)
|
||||
envVarsProvider := pluginconfig.NewEnvVarsProvider(pluginInstanceCfg, licensingService)
|
||||
registerer := metrics.ProvideRegistererForTest()
|
||||
ssosettingsimplService := ssosettingsimpl.ProvideService(cfg, sqlStore, accessControl, routeRegisterImpl, featureToggles, secretsService, usageStats, registerer, ossImpl, ossLicensingService)
|
||||
defaultSettingsProvider := pluginsso.ProvideDefaultSettingsProvider(ssosettingsimplService)
|
||||
envVarsProvider := pluginconfig.NewEnvVarsProvider(pluginInstanceCfg, licensingService, defaultSettingsProvider)
|
||||
inMemory := registry.ProvideService()
|
||||
rendererManager, err := renderer.ProvideService(pluginManagementCfg, envVarsProvider, inMemory, tracingService)
|
||||
if err != nil {
|
||||
@@ -1025,7 +1030,6 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
|
||||
}
|
||||
publicDashboardStoreImpl := database3.ProvideStore(sqlStore, cfg, featureToggles)
|
||||
publicDashboardServiceWrapperImpl := service3.ProvideServiceWrapper(publicDashboardStoreImpl)
|
||||
registerer := metrics.ProvideRegistererForTest()
|
||||
apikeyService, err := apikeyimpl.ProvideService(sqlStore, cfg, quotaService)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1195,7 +1199,7 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
|
||||
return nil, err
|
||||
}
|
||||
datasourcePermissionsService := ossaccesscontrol.ProvideDatasourcePermissionsService(cfg, featureToggles, sqlStore)
|
||||
requestConfigProvider := pluginconfig.NewRequestConfigProvider(pluginInstanceCfg)
|
||||
requestConfigProvider := pluginconfig.NewRequestConfigProvider(pluginInstanceCfg, defaultSettingsProvider)
|
||||
baseProvider := plugincontext.ProvideBaseService(cfg, requestConfigProvider)
|
||||
service15, err := service9.ProvideService(sqlStore, secretsService, secretsKVStore, cfg, featureToggles, accessControl, datasourcePermissionsService, quotaService, pluginstoreService, middlewareHandler, baseProvider)
|
||||
if err != nil {
|
||||
@@ -1227,7 +1231,6 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
|
||||
return nil, err
|
||||
}
|
||||
orgRoleMapper := connectors.ProvideOrgRoleMapper(cfg, orgService)
|
||||
ssosettingsimplService := ssosettingsimpl.ProvideService(cfg, sqlStore, accessControl, routeRegisterImpl, featureToggles, secretsService, usageStats, registerer, ossImpl, ossLicensingService)
|
||||
socialService := socialimpl.ProvideService(cfg, featureToggles, usageStats, bundleregistryService, remoteCache, orgRoleMapper, ssosettingsimplService)
|
||||
loginStore := authinfoimpl.ProvideStore(sqlStore, secretsService)
|
||||
authinfoimplService := authinfoimpl.ProvideService(loginStore, remoteCache, secretsService)
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package pluginconfig
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana-azure-sdk-go/v2/azsettings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsso"
|
||||
)
|
||||
|
||||
// mergeAzureSettings merges the Azure AD settings from the SSO settings DB with the Azure AD settings from the config.
|
||||
// Azure AD settings can be changed via the UI or SSO settings API
|
||||
// They can also be overridden in the [azure] config section
|
||||
// The order of precedence is:
|
||||
// 1. [azure] config section (if the override flag is set)
|
||||
// 2. SSO settings from the DB (if they exist)
|
||||
// 3. [auth.azuread] config section (if enabled)
|
||||
func mergeAzureSettings(currSettings *azsettings.AzureSettings, azureAdSettings *pluginsso.Settings) *azsettings.AzureSettings {
|
||||
if azureAdSettings != nil {
|
||||
settings := azureAdSettings.Values
|
||||
tokenEndpointSettings := currSettings.UserIdentityTokenEndpoint
|
||||
if tokenEndpointSettings == nil {
|
||||
tokenEndpointSettings = &azsettings.TokenEndpointSettings{}
|
||||
currSettings.UserIdentityTokenEndpoint = tokenEndpointSettings
|
||||
}
|
||||
|
||||
tokenUrl, ok := settings["token_url"].(string)
|
||||
if ok {
|
||||
if !currSettings.UserIdentityTokenEndpoint.TokenUrlOverride {
|
||||
currSettings.UserIdentityTokenEndpoint.TokenUrl = tokenUrl
|
||||
}
|
||||
}
|
||||
clientAuth, ok := settings["client_authentication"].(string)
|
||||
if ok {
|
||||
if !currSettings.UserIdentityTokenEndpoint.ClientAuthenticationOverride {
|
||||
if clientAuth != "none" {
|
||||
currSettings.UserIdentityTokenEndpoint.ClientAuthentication = clientAuth
|
||||
}
|
||||
}
|
||||
}
|
||||
clientId, ok := settings["client_id"].(string)
|
||||
if ok {
|
||||
if !currSettings.UserIdentityTokenEndpoint.ClientIdOverride {
|
||||
currSettings.UserIdentityTokenEndpoint.ClientId = clientId
|
||||
}
|
||||
}
|
||||
clientSecret, ok := settings["client_secret"].(string)
|
||||
if ok {
|
||||
if !currSettings.UserIdentityTokenEndpoint.ClientSecretOverride {
|
||||
currSettings.UserIdentityTokenEndpoint.ClientSecret = clientSecret
|
||||
}
|
||||
}
|
||||
managedIdentityClientId, ok := settings["managed_identity_client_id"].(string)
|
||||
if ok {
|
||||
if !currSettings.UserIdentityTokenEndpoint.ManagedIdentityClientIdOverride {
|
||||
currSettings.UserIdentityTokenEndpoint.ManagedIdentityClientId = managedIdentityClientId
|
||||
}
|
||||
}
|
||||
federatedCredentialAudience, ok := settings["federated_credential_audience"].(string)
|
||||
if ok {
|
||||
if !currSettings.UserIdentityTokenEndpoint.FederatedCredentialAudienceOverride {
|
||||
currSettings.UserIdentityTokenEndpoint.FederatedCredentialAudience = federatedCredentialAudience
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return currSettings
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
package pluginconfig
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana-azure-sdk-go/v2/azsettings"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsso"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestGetAzureSettings(t *testing.T) {
|
||||
t.Run("no Azure settings input", func(t *testing.T) {
|
||||
result := mergeAzureSettings(nil, nil)
|
||||
|
||||
assert.Nil(t, result)
|
||||
})
|
||||
|
||||
t.Run("no SSO settings or override settings", func(t *testing.T) {
|
||||
currSettings := &azsettings.AzureSettings{
|
||||
UserIdentityTokenEndpoint: &azsettings.TokenEndpointSettings{
|
||||
TokenUrl: "original-token-url",
|
||||
ClientAuthentication: "original-auth",
|
||||
ClientId: "original-client-id",
|
||||
ClientSecret: "original-client-secret",
|
||||
},
|
||||
}
|
||||
|
||||
azureAdSettings := &pluginsso.Settings{
|
||||
Values: map[string]any{},
|
||||
}
|
||||
|
||||
result := mergeAzureSettings(currSettings, azureAdSettings)
|
||||
|
||||
assert.Equal(t, "original-token-url", result.UserIdentityTokenEndpoint.TokenUrl)
|
||||
assert.Equal(t, "original-auth", result.UserIdentityTokenEndpoint.ClientAuthentication)
|
||||
assert.Equal(t, "original-client-id", result.UserIdentityTokenEndpoint.ClientId)
|
||||
assert.Equal(t, "original-client-secret", result.UserIdentityTokenEndpoint.ClientSecret)
|
||||
})
|
||||
|
||||
t.Run("with SSO settings but no overrides", func(t *testing.T) {
|
||||
currSettings := &azsettings.AzureSettings{
|
||||
UserIdentityTokenEndpoint: &azsettings.TokenEndpointSettings{
|
||||
TokenUrl: "original-token-url",
|
||||
ClientAuthentication: "original-auth",
|
||||
ClientId: "original-client-id",
|
||||
ClientSecret: "original-client-secret",
|
||||
ManagedIdentityClientId: "original-managed-id",
|
||||
FederatedCredentialAudience: "original-audience",
|
||||
TokenUrlOverride: false,
|
||||
ClientAuthenticationOverride: false,
|
||||
ClientIdOverride: false,
|
||||
ClientSecretOverride: false,
|
||||
ManagedIdentityClientIdOverride: false,
|
||||
FederatedCredentialAudienceOverride: false,
|
||||
},
|
||||
}
|
||||
|
||||
azureAdSettings := &pluginsso.Settings{
|
||||
Values: map[string]any{
|
||||
"token_url": "sso-token-url",
|
||||
"client_authentication": "sso-auth",
|
||||
"client_id": "sso-client-id",
|
||||
"client_secret": "sso-client-secret",
|
||||
"managed_identity_client_id": "sso-managed-id",
|
||||
"federated_credential_audience": "sso-audience",
|
||||
},
|
||||
}
|
||||
|
||||
result := mergeAzureSettings(currSettings, azureAdSettings)
|
||||
|
||||
assert.Equal(t, "sso-token-url", result.UserIdentityTokenEndpoint.TokenUrl)
|
||||
assert.Equal(t, "sso-auth", result.UserIdentityTokenEndpoint.ClientAuthentication)
|
||||
assert.Equal(t, "sso-client-id", result.UserIdentityTokenEndpoint.ClientId)
|
||||
assert.Equal(t, "sso-client-secret", result.UserIdentityTokenEndpoint.ClientSecret)
|
||||
assert.Equal(t, "sso-managed-id", result.UserIdentityTokenEndpoint.ManagedIdentityClientId)
|
||||
assert.Equal(t, "sso-audience", result.UserIdentityTokenEndpoint.FederatedCredentialAudience)
|
||||
})
|
||||
|
||||
t.Run("with both overrides and SSO settings", func(t *testing.T) {
|
||||
currSettings := &azsettings.AzureSettings{
|
||||
UserIdentityTokenEndpoint: &azsettings.TokenEndpointSettings{
|
||||
TokenUrl: "override-token-url",
|
||||
ClientAuthentication: "override-auth",
|
||||
ClientId: "override-client-id",
|
||||
ClientSecret: "override-client-secret",
|
||||
ManagedIdentityClientId: "override-managed-id",
|
||||
FederatedCredentialAudience: "override-audience",
|
||||
TokenUrlOverride: true,
|
||||
ClientAuthenticationOverride: true,
|
||||
ClientIdOverride: true,
|
||||
ClientSecretOverride: true,
|
||||
ManagedIdentityClientIdOverride: true,
|
||||
FederatedCredentialAudienceOverride: true,
|
||||
},
|
||||
}
|
||||
|
||||
azureAdSettings := &pluginsso.Settings{
|
||||
Values: map[string]any{
|
||||
"token_url": "sso-token-url",
|
||||
"client_authentication": "sso-auth",
|
||||
"client_id": "sso-client-id",
|
||||
"client_secret": "sso-client-secret",
|
||||
"managed_identity_client_id": "sso-managed-id",
|
||||
"federated_credential_audience": "sso-audience",
|
||||
},
|
||||
}
|
||||
|
||||
result := mergeAzureSettings(currSettings, azureAdSettings)
|
||||
|
||||
// Should keep override values, not SSO values
|
||||
assert.Equal(t, "override-token-url", result.UserIdentityTokenEndpoint.TokenUrl)
|
||||
assert.Equal(t, "override-auth", result.UserIdentityTokenEndpoint.ClientAuthentication)
|
||||
assert.Equal(t, "override-client-id", result.UserIdentityTokenEndpoint.ClientId)
|
||||
assert.Equal(t, "override-client-secret", result.UserIdentityTokenEndpoint.ClientSecret)
|
||||
assert.Equal(t, "override-managed-id", result.UserIdentityTokenEndpoint.ManagedIdentityClientId)
|
||||
assert.Equal(t, "override-audience", result.UserIdentityTokenEndpoint.FederatedCredentialAudience)
|
||||
})
|
||||
|
||||
t.Run("client authentication 'none' should be ignored", func(t *testing.T) {
|
||||
currSettings := &azsettings.AzureSettings{
|
||||
UserIdentityTokenEndpoint: &azsettings.TokenEndpointSettings{
|
||||
ClientAuthentication: "original-auth",
|
||||
ClientAuthenticationOverride: false,
|
||||
},
|
||||
}
|
||||
|
||||
azureAdSettings := &pluginsso.Settings{
|
||||
Values: map[string]any{
|
||||
"client_authentication": "none",
|
||||
},
|
||||
}
|
||||
|
||||
result := mergeAzureSettings(currSettings, azureAdSettings)
|
||||
|
||||
assert.Equal(t, "original-auth", result.UserIdentityTokenEndpoint.ClientAuthentication)
|
||||
})
|
||||
|
||||
t.Run("non-string values should be ignored", func(t *testing.T) {
|
||||
currSettings := &azsettings.AzureSettings{
|
||||
UserIdentityTokenEndpoint: &azsettings.TokenEndpointSettings{
|
||||
TokenUrl: "original-token-url",
|
||||
ClientId: "original-client-id",
|
||||
TokenUrlOverride: false,
|
||||
ClientIdOverride: false,
|
||||
},
|
||||
}
|
||||
|
||||
azureAdSettings := &pluginsso.Settings{
|
||||
Values: map[string]any{
|
||||
"token_url": 12345,
|
||||
"client_id": []string{"array", "value"},
|
||||
},
|
||||
}
|
||||
|
||||
result := mergeAzureSettings(currSettings, azureAdSettings)
|
||||
|
||||
assert.Equal(t, "original-token-url", result.UserIdentityTokenEndpoint.TokenUrl)
|
||||
assert.Equal(t, "original-client-id", result.UserIdentityTokenEndpoint.ClientId)
|
||||
})
|
||||
|
||||
t.Run("Nil UserIdentityTokenEndpoint should not panic", func(t *testing.T) {
|
||||
currSettings := &azsettings.AzureSettings{
|
||||
UserIdentityTokenEndpoint: nil,
|
||||
}
|
||||
|
||||
azureAdSettings := &pluginsso.Settings{
|
||||
Values: map[string]any{
|
||||
"token_url": "sso-token-url",
|
||||
},
|
||||
}
|
||||
|
||||
require.NotPanics(t, func() {
|
||||
mergeAzureSettings(currSettings, azureAdSettings)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Empty SSO settings map", func(t *testing.T) {
|
||||
currSettings := &azsettings.AzureSettings{
|
||||
UserIdentityTokenEndpoint: &azsettings.TokenEndpointSettings{
|
||||
TokenUrl: "original-token-url",
|
||||
ClientAuthentication: "original-auth",
|
||||
ClientId: "original-client-id",
|
||||
},
|
||||
}
|
||||
|
||||
azureAdSettings := &pluginsso.Settings{
|
||||
Values: map[string]any{},
|
||||
}
|
||||
|
||||
result := mergeAzureSettings(currSettings, azureAdSettings)
|
||||
|
||||
assert.Equal(t, "original-token-url", result.UserIdentityTokenEndpoint.TokenUrl)
|
||||
assert.Equal(t, "original-auth", result.UserIdentityTokenEndpoint.ClientAuthentication)
|
||||
assert.Equal(t, "original-client-id", result.UserIdentityTokenEndpoint.ClientId)
|
||||
})
|
||||
}
|
||||
@@ -13,23 +13,27 @@ import (
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/proxy"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/login/social"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/envvars"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsso"
|
||||
)
|
||||
|
||||
var _ envvars.Provider = (*EnvVarsProvider)(nil)
|
||||
|
||||
type EnvVarsProvider struct {
|
||||
cfg *PluginInstanceCfg
|
||||
license plugins.Licensing
|
||||
logger log.Logger
|
||||
cfg *PluginInstanceCfg
|
||||
license plugins.Licensing
|
||||
logger log.Logger
|
||||
ssoSettings pluginsso.SettingsProvider
|
||||
}
|
||||
|
||||
func NewEnvVarsProvider(cfg *PluginInstanceCfg, license plugins.Licensing) *EnvVarsProvider {
|
||||
func NewEnvVarsProvider(cfg *PluginInstanceCfg, license plugins.Licensing, ssoSettings pluginsso.SettingsProvider) *EnvVarsProvider {
|
||||
return &EnvVarsProvider{
|
||||
cfg: cfg,
|
||||
license: license,
|
||||
logger: log.New("plugins.envvars"),
|
||||
cfg: cfg,
|
||||
license: license,
|
||||
logger: log.New("plugins.envvars"),
|
||||
ssoSettings: ssoSettings,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +67,7 @@ func (p *EnvVarsProvider) PluginEnvVars(ctx context.Context, plugin *plugins.Plu
|
||||
hostEnv = append(hostEnv, p.featureToggleEnableVars(ctx)...)
|
||||
hostEnv = append(hostEnv, p.awsEnvVars(plugin.PluginID())...)
|
||||
hostEnv = append(hostEnv, p.secureSocksProxyEnvVars()...)
|
||||
hostEnv = append(hostEnv, azsettings.WriteToEnvStr(p.cfg.Azure)...)
|
||||
hostEnv = append(hostEnv, azsettings.WriteToEnvStr(p.getAzureSettings())...)
|
||||
hostEnv = append(hostEnv, p.tracingEnvVars(plugin)...)
|
||||
hostEnv = append(hostEnv, p.pluginSettingsEnvVars(plugin.PluginID())...)
|
||||
|
||||
@@ -189,3 +193,15 @@ func (p *EnvVarsProvider) envVar(key, value string) string {
|
||||
}
|
||||
return fmt.Sprintf("%s=%s", key, value)
|
||||
}
|
||||
|
||||
func (p *EnvVarsProvider) getAzureSettings() *azsettings.AzureSettings {
|
||||
azureSettings := p.cfg.Azure
|
||||
if azureSettings == nil {
|
||||
azureSettings = &azsettings.AzureSettings{}
|
||||
}
|
||||
azureAdSettings, err := p.ssoSettings.GetForProvider(context.Background(), social.AzureADProviderName)
|
||||
if err != nil {
|
||||
p.logger.Error("Failed to get SSO settings", "error", err)
|
||||
}
|
||||
return mergeAzureSettings(azureSettings, azureAdSettings)
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ func TestPluginEnvVarsProvider_PluginEnvVars(t *testing.T) {
|
||||
Features: featuremgmt.WithFeatures(),
|
||||
}
|
||||
|
||||
provider := NewEnvVarsProvider(cfg, licensing)
|
||||
provider := NewEnvVarsProvider(cfg, licensing, &fakeSSOSettingsProvider{})
|
||||
envVars := provider.PluginEnvVars(context.Background(), p)
|
||||
assert.Len(t, envVars, 6)
|
||||
assert.Equal(t, "GF_VERSION=", envVars[0])
|
||||
@@ -77,7 +77,7 @@ func TestPluginEnvVarsProvider_skipHostEnvVars(t *testing.T) {
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
|
||||
provider := NewEnvVarsProvider(pCfg, nil)
|
||||
provider := NewEnvVarsProvider(pCfg, nil, &fakeSSOSettingsProvider{})
|
||||
envVars := provider.PluginEnvVars(context.Background(), p)
|
||||
|
||||
// We want to test that the envvars.Provider does not add any of the host env vars.
|
||||
@@ -93,7 +93,7 @@ func TestPluginEnvVarsProvider_skipHostEnvVars(t *testing.T) {
|
||||
cfg := setting.NewCfg()
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
provider := NewEnvVarsProvider(pCfg, nil)
|
||||
provider := NewEnvVarsProvider(pCfg, nil, &fakeSSOSettingsProvider{})
|
||||
|
||||
t.Run("should populate allowed host env vars", func(t *testing.T) {
|
||||
// Set all allowed variables
|
||||
@@ -418,7 +418,7 @@ func TestPluginEnvVarsProvider_tracingEnvironmentVariables(t *testing.T) {
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
p := NewEnvVarsProvider(tc.cfg, nil)
|
||||
p := NewEnvVarsProvider(tc.cfg, nil, &fakeSSOSettingsProvider{})
|
||||
envVars := p.PluginEnvVars(context.Background(), tc.plugin)
|
||||
tc.exp(t, envVars)
|
||||
})
|
||||
@@ -473,7 +473,7 @@ func TestPluginEnvVarsProvider_authEnvVars(t *testing.T) {
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
|
||||
provider := NewEnvVarsProvider(pCfg, nil)
|
||||
provider := NewEnvVarsProvider(pCfg, nil, &fakeSSOSettingsProvider{})
|
||||
envVars := provider.PluginEnvVars(context.Background(), p)
|
||||
assert.Equal(t, "GF_VERSION=", envVars[0])
|
||||
assert.Equal(t, "GF_APP_URL=https://myorg.com/", envVars[1])
|
||||
@@ -521,7 +521,7 @@ func TestPluginEnvVarsProvider_awsEnvVars(t *testing.T) {
|
||||
Features: featuremgmt.WithFeatures(),
|
||||
}
|
||||
|
||||
provider := NewEnvVarsProvider(cfg, nil)
|
||||
provider := NewEnvVarsProvider(cfg, nil, &fakeSSOSettingsProvider{})
|
||||
envVars := provider.PluginEnvVars(context.Background(), p)
|
||||
assert.ElementsMatch(t, tc.expected, envVars)
|
||||
}
|
||||
@@ -540,7 +540,7 @@ func TestPluginEnvVarsProvider_featureToggleEnvVar(t *testing.T) {
|
||||
Features: featuremgmt.WithFeatures(expectedFeatures[0], true, expectedFeatures[1], true),
|
||||
}
|
||||
|
||||
p := NewEnvVarsProvider(cfg, nil)
|
||||
p := NewEnvVarsProvider(cfg, nil, &fakeSSOSettingsProvider{})
|
||||
envVars := p.PluginEnvVars(context.Background(), &plugins.Plugin{})
|
||||
assert.Equal(t, 2, len(envVars))
|
||||
|
||||
@@ -591,7 +591,7 @@ func TestPluginEnvVarsProvider_azureEnvVars(t *testing.T) {
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
|
||||
provider := NewEnvVarsProvider(pCfg, nil)
|
||||
provider := NewEnvVarsProvider(pCfg, nil, &fakeSSOSettingsProvider{})
|
||||
envVars := provider.PluginEnvVars(context.Background(), &plugins.Plugin{})
|
||||
assert.ElementsMatch(t, []string{"GF_VERSION=", "GFAZPL_AZURE_CLOUD=AzureCloud", "GFAZPL_AZURE_AUTH_ENABLED=true",
|
||||
"GFAZPL_MANAGED_IDENTITY_ENABLED=true",
|
||||
@@ -608,4 +608,113 @@ func TestPluginEnvVarsProvider_azureEnvVars(t *testing.T) {
|
||||
"GFAZPL_USER_IDENTITY_ASSERTION=username",
|
||||
}, envVars)
|
||||
})
|
||||
|
||||
t.Run("sets user token endpoint settings from SSO settings for an Azure plugin", func(t *testing.T) {
|
||||
cfg := &setting.Cfg{
|
||||
Raw: ini.Empty(),
|
||||
Azure: &azsettings.AzureSettings{
|
||||
AzureAuthEnabled: true,
|
||||
Cloud: azsettings.AzurePublic,
|
||||
ManagedIdentityEnabled: true,
|
||||
ManagedIdentityClientId: "mock_managed_identity_client_id",
|
||||
WorkloadIdentityEnabled: true,
|
||||
WorkloadIdentitySettings: &azsettings.WorkloadIdentitySettings{
|
||||
TenantId: "mock_workload_identity_tenant_id",
|
||||
ClientId: "mock_workload_identity_client_id",
|
||||
TokenFile: "mock_workload_identity_token_file",
|
||||
},
|
||||
UserIdentityEnabled: true,
|
||||
UserIdentityFallbackCredentialsEnabled: true,
|
||||
UserIdentityTokenEndpoint: &azsettings.TokenEndpointSettings{
|
||||
TokenUrl: "mock_user_identity_token_url",
|
||||
ClientId: "mock_user_identity_client_id",
|
||||
ClientSecret: "mock_user_identity_client_secret",
|
||||
UsernameAssertion: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
|
||||
provider := NewEnvVarsProvider(pCfg, nil, &fakeSSOSettingsProvider{
|
||||
GetForProviderFunc: getAzureSSOSettings,
|
||||
})
|
||||
envVars := provider.PluginEnvVars(context.Background(), &plugins.Plugin{})
|
||||
assert.ElementsMatch(t, []string{"GF_VERSION=", "GFAZPL_AZURE_CLOUD=AzureCloud", "GFAZPL_AZURE_AUTH_ENABLED=true",
|
||||
"GFAZPL_MANAGED_IDENTITY_ENABLED=true",
|
||||
"GFAZPL_MANAGED_IDENTITY_CLIENT_ID=mock_managed_identity_client_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_ENABLED=true",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_TENANT_ID=mock_workload_identity_tenant_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_CLIENT_ID=mock_workload_identity_client_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_TOKEN_FILE=mock_workload_identity_token_file",
|
||||
"GFAZPL_USER_IDENTITY_ENABLED=true",
|
||||
"GFAZPL_USER_IDENTITY_FALLBACK_SERVICE_CREDENTIALS_ENABLED=true",
|
||||
"GFAZPL_USER_IDENTITY_TOKEN_URL=sso_user_identity_token_url",
|
||||
"GFAZPL_USER_IDENTITY_CLIENT_AUTHENTICATION=sso_user_client_authentication",
|
||||
"GFAZPL_USER_IDENTITY_CLIENT_ID=sso_user_identity_client_id",
|
||||
"GFAZPL_USER_IDENTITY_CLIENT_SECRET=sso_user_identity_client_secret",
|
||||
"GFAZPL_USER_IDENTITY_MANAGED_IDENTITY_CLIENT_ID=sso_user_identity_managed_identity_client_id",
|
||||
"GFAZPL_USER_IDENTITY_FEDERATED_CREDENTIAL_AUDIENCE=sso_user_identity_federated_credential_audience",
|
||||
"GFAZPL_USER_IDENTITY_ASSERTION=username",
|
||||
}, envVars)
|
||||
})
|
||||
|
||||
t.Run("does not use SSO settings if overrides have been set for an Azure plugin", func(t *testing.T) {
|
||||
cfg := &setting.Cfg{
|
||||
Raw: ini.Empty(),
|
||||
Azure: &azsettings.AzureSettings{
|
||||
AzureAuthEnabled: true,
|
||||
Cloud: azsettings.AzurePublic,
|
||||
ManagedIdentityEnabled: true,
|
||||
ManagedIdentityClientId: "mock_managed_identity_client_id",
|
||||
WorkloadIdentityEnabled: true,
|
||||
WorkloadIdentitySettings: &azsettings.WorkloadIdentitySettings{
|
||||
TenantId: "mock_workload_identity_tenant_id",
|
||||
ClientId: "mock_workload_identity_client_id",
|
||||
TokenFile: "mock_workload_identity_token_file",
|
||||
},
|
||||
UserIdentityEnabled: true,
|
||||
UserIdentityFallbackCredentialsEnabled: true,
|
||||
UserIdentityTokenEndpoint: &azsettings.TokenEndpointSettings{
|
||||
TokenUrl: "override_user_identity_token_url",
|
||||
TokenUrlOverride: true,
|
||||
ClientAuthentication: "override_user_client_authentication",
|
||||
ClientAuthenticationOverride: true,
|
||||
ClientId: "override_user_identity_client_id",
|
||||
ClientIdOverride: true,
|
||||
ClientSecret: "override_user_identity_client_secret",
|
||||
ClientSecretOverride: true,
|
||||
ManagedIdentityClientId: "override_user_identity_managed_identity_client_id",
|
||||
ManagedIdentityClientIdOverride: true,
|
||||
FederatedCredentialAudience: "override_user_identity_federated_credential_audience",
|
||||
FederatedCredentialAudienceOverride: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
|
||||
provider := NewEnvVarsProvider(pCfg, nil, &fakeSSOSettingsProvider{
|
||||
GetForProviderFunc: getAzureSSOSettings,
|
||||
})
|
||||
envVars := provider.PluginEnvVars(context.Background(), &plugins.Plugin{})
|
||||
assert.ElementsMatch(t, []string{"GF_VERSION=", "GFAZPL_AZURE_CLOUD=AzureCloud", "GFAZPL_AZURE_AUTH_ENABLED=true",
|
||||
"GFAZPL_MANAGED_IDENTITY_ENABLED=true",
|
||||
"GFAZPL_MANAGED_IDENTITY_CLIENT_ID=mock_managed_identity_client_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_ENABLED=true",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_TENANT_ID=mock_workload_identity_tenant_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_CLIENT_ID=mock_workload_identity_client_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_TOKEN_FILE=mock_workload_identity_token_file",
|
||||
"GFAZPL_USER_IDENTITY_ENABLED=true",
|
||||
"GFAZPL_USER_IDENTITY_FALLBACK_SERVICE_CREDENTIALS_ENABLED=true",
|
||||
"GFAZPL_USER_IDENTITY_TOKEN_URL=override_user_identity_token_url",
|
||||
"GFAZPL_USER_IDENTITY_CLIENT_AUTHENTICATION=override_user_client_authentication",
|
||||
"GFAZPL_USER_IDENTITY_CLIENT_ID=override_user_identity_client_id",
|
||||
"GFAZPL_USER_IDENTITY_CLIENT_SECRET=override_user_identity_client_secret",
|
||||
"GFAZPL_USER_IDENTITY_MANAGED_IDENTITY_CLIENT_ID=override_user_identity_managed_identity_client_id",
|
||||
"GFAZPL_USER_IDENTITY_FEDERATED_CREDENTIAL_AUDIENCE=override_user_identity_federated_credential_audience",
|
||||
}, envVars)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -9,11 +9,14 @@ import (
|
||||
|
||||
"github.com/grafana/grafana-aws-sdk/pkg/awsds"
|
||||
"github.com/grafana/grafana-azure-sdk-go/v2/azsettings"
|
||||
"github.com/grafana/grafana/pkg/plugins/auth"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/proxy"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/experimental/featuretoggles"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/login/social"
|
||||
"github.com/grafana/grafana/pkg/plugins/auth"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsso"
|
||||
)
|
||||
|
||||
var _ PluginRequestConfigProvider = (*RequestConfigProvider)(nil)
|
||||
@@ -23,12 +26,16 @@ type PluginRequestConfigProvider interface {
|
||||
}
|
||||
|
||||
type RequestConfigProvider struct {
|
||||
cfg *PluginInstanceCfg
|
||||
cfg *PluginInstanceCfg
|
||||
ssoSettings pluginsso.SettingsProvider
|
||||
logger log.Logger
|
||||
}
|
||||
|
||||
func NewRequestConfigProvider(cfg *PluginInstanceCfg) *RequestConfigProvider {
|
||||
func NewRequestConfigProvider(cfg *PluginInstanceCfg, ssoSettings pluginsso.SettingsProvider) *RequestConfigProvider {
|
||||
return &RequestConfigProvider{
|
||||
cfg: cfg,
|
||||
cfg: cfg,
|
||||
ssoSettings: ssoSettings,
|
||||
logger: log.New("pluginrequestconfig"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,8 +96,19 @@ func (s *RequestConfigProvider) PluginRequestConfig(ctx context.Context, pluginI
|
||||
if s.cfg.AzureAuthEnabled {
|
||||
m[azsettings.AzureAuthEnabled] = strconv.FormatBool(s.cfg.AzureAuthEnabled)
|
||||
}
|
||||
|
||||
azureSettings := s.cfg.Azure
|
||||
if azureSettings != nil && slices.Contains[[]string, string](azureSettings.ForwardSettingsPlugins, pluginID) {
|
||||
if azureSettings == nil {
|
||||
azureSettings = &azsettings.AzureSettings{}
|
||||
}
|
||||
|
||||
if slices.Contains(azureSettings.ForwardSettingsPlugins, pluginID) {
|
||||
azureAdSettings, err := s.ssoSettings.GetForProvider(ctx, social.AzureADProviderName)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to get SSO settings", "error", err)
|
||||
}
|
||||
azureSettings = mergeAzureSettings(azureSettings, azureAdSettings)
|
||||
|
||||
if azureSettings.Cloud != "" {
|
||||
m[azsettings.AzureCloud] = azureSettings.Cloud
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins/auth"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsso"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
@@ -19,7 +20,7 @@ func TestRequestConfigProvider_PluginRequestConfig_Defaults(t *testing.T) {
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
|
||||
p := NewRequestConfigProvider(pCfg)
|
||||
p := NewRequestConfigProvider(pCfg, &fakeSSOSettingsProvider{})
|
||||
require.Equal(t, map[string]string{
|
||||
"GF_SQL_MAX_OPEN_CONNS_DEFAULT": "0",
|
||||
"GF_SQL_MAX_IDLE_CONNS_DEFAULT": "0",
|
||||
@@ -133,7 +134,7 @@ func TestRequestConfigProvider_PluginRequestConfig(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
p := NewRequestConfigProvider(tc.cfg)
|
||||
p := NewRequestConfigProvider(tc.cfg, &fakeSSOSettingsProvider{})
|
||||
require.Subset(t, p.PluginRequestConfig(context.Background(), "", nil), tc.expected)
|
||||
})
|
||||
}
|
||||
@@ -168,7 +169,7 @@ func TestRequestConfigProvider_PluginRequestConfig_featureToggles(t *testing.T)
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), tc.features)
|
||||
require.NoError(t, err)
|
||||
|
||||
p := NewRequestConfigProvider(pCfg)
|
||||
p := NewRequestConfigProvider(pCfg, &fakeSSOSettingsProvider{})
|
||||
require.Subset(t, p.PluginRequestConfig(context.Background(), "", nil), tc.expectedConfig)
|
||||
}
|
||||
})
|
||||
@@ -182,7 +183,7 @@ func TestRequestConfigProvider_PluginRequestConfig_appURL(t *testing.T) {
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
|
||||
p := NewRequestConfigProvider(pCfg)
|
||||
p := NewRequestConfigProvider(pCfg, &fakeSSOSettingsProvider{})
|
||||
require.Subset(t, p.PluginRequestConfig(context.Background(), "", nil), map[string]string{"GF_APP_URL": "https://myorg.com/"})
|
||||
})
|
||||
}
|
||||
@@ -198,7 +199,7 @@ func TestRequestConfigProvider_PluginRequestConfig_SQL(t *testing.T) {
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
|
||||
p := NewRequestConfigProvider(pCfg)
|
||||
p := NewRequestConfigProvider(pCfg, &fakeSSOSettingsProvider{})
|
||||
require.Subset(t, p.PluginRequestConfig(context.Background(), "", nil), map[string]string{
|
||||
"GF_SQL_ROW_LIMIT": "23",
|
||||
"GF_SQL_MAX_OPEN_CONNS_DEFAULT": "24",
|
||||
@@ -216,7 +217,7 @@ func TestRequestConfigProvider_PluginRequestConfig_SQL(t *testing.T) {
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
|
||||
p := NewRequestConfigProvider(pCfg)
|
||||
p := NewRequestConfigProvider(pCfg, &fakeSSOSettingsProvider{})
|
||||
require.Equal(t, map[string]string{
|
||||
"GF_SQL_MAX_OPEN_CONNS_DEFAULT": "0",
|
||||
"GF_SQL_MAX_IDLE_CONNS_DEFAULT": "0",
|
||||
@@ -233,7 +234,7 @@ func TestRequestConfigProvider_PluginRequestConfig_concurrentQueryCount(t *testi
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
|
||||
p := NewRequestConfigProvider(pCfg)
|
||||
p := NewRequestConfigProvider(pCfg, &fakeSSOSettingsProvider{})
|
||||
require.Subset(t, p.PluginRequestConfig(context.Background(), "", nil), map[string]string{"GF_CONCURRENT_QUERY_COUNT": "42"})
|
||||
})
|
||||
|
||||
@@ -242,7 +243,7 @@ func TestRequestConfigProvider_PluginRequestConfig_concurrentQueryCount(t *testi
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
|
||||
p := NewRequestConfigProvider(pCfg)
|
||||
p := NewRequestConfigProvider(pCfg, &fakeSSOSettingsProvider{})
|
||||
require.NotContains(t, p.PluginRequestConfig(context.Background(), "", nil), "GF_CONCURRENT_QUERY_COUNT")
|
||||
})
|
||||
|
||||
@@ -253,7 +254,7 @@ func TestRequestConfigProvider_PluginRequestConfig_concurrentQueryCount(t *testi
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
|
||||
p := NewRequestConfigProvider(pCfg)
|
||||
p := NewRequestConfigProvider(pCfg, &fakeSSOSettingsProvider{})
|
||||
require.NotContains(t, p.PluginRequestConfig(context.Background(), "", nil), "GF_CONCURRENT_QUERY_COUNT")
|
||||
})
|
||||
}
|
||||
@@ -265,7 +266,7 @@ func TestRequestConfigProvider_PluginRequestConfig_azureAuthEnabled(t *testing.T
|
||||
Features: featuremgmt.WithFeatures(),
|
||||
}
|
||||
|
||||
p := NewRequestConfigProvider(cfg)
|
||||
p := NewRequestConfigProvider(cfg, &fakeSSOSettingsProvider{})
|
||||
require.Subset(t, p.PluginRequestConfig(context.Background(), "", nil), map[string]string{"GFAZPL_AZURE_AUTH_ENABLED": "true"})
|
||||
})
|
||||
|
||||
@@ -274,7 +275,7 @@ func TestRequestConfigProvider_PluginRequestConfig_azureAuthEnabled(t *testing.T
|
||||
Features: featuremgmt.WithFeatures(),
|
||||
}
|
||||
|
||||
p := NewRequestConfigProvider(cfg)
|
||||
p := NewRequestConfigProvider(cfg, &fakeSSOSettingsProvider{})
|
||||
require.NotContains(t, p.PluginRequestConfig(context.Background(), "", nil), "GFAZPL_AZURE_AUTH_ENABLED")
|
||||
})
|
||||
|
||||
@@ -284,7 +285,7 @@ func TestRequestConfigProvider_PluginRequestConfig_azureAuthEnabled(t *testing.T
|
||||
Features: featuremgmt.WithFeatures(),
|
||||
}
|
||||
|
||||
p := NewRequestConfigProvider(cfg)
|
||||
p := NewRequestConfigProvider(cfg, &fakeSSOSettingsProvider{})
|
||||
require.NotContains(t, p.PluginRequestConfig(context.Background(), "", nil), "GFAZPL_AZURE_AUTH_ENABLED")
|
||||
})
|
||||
}
|
||||
@@ -322,7 +323,7 @@ func TestRequestConfigProvider_PluginRequestConfig_azure(t *testing.T) {
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
|
||||
p := NewRequestConfigProvider(pCfg)
|
||||
p := NewRequestConfigProvider(pCfg, &fakeSSOSettingsProvider{})
|
||||
require.Subset(t, p.PluginRequestConfig(context.Background(), "grafana-azure-monitor-datasource", nil), map[string]string{
|
||||
"GFAZPL_AZURE_CLOUD": "AzureCloud", "GFAZPL_MANAGED_IDENTITY_ENABLED": "true",
|
||||
"GFAZPL_MANAGED_IDENTITY_CLIENT_ID": "mock_managed_identity_client_id",
|
||||
@@ -356,7 +357,7 @@ func TestRequestConfigProvider_PluginRequestConfig_azure(t *testing.T) {
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
|
||||
p := NewRequestConfigProvider(pCfg)
|
||||
p := NewRequestConfigProvider(pCfg, &fakeSSOSettingsProvider{})
|
||||
require.Subset(t, p.PluginRequestConfig(context.Background(), "grafana-azure-monitor-datasource", nil), map[string]string{
|
||||
"GFAZPL_AZURE_CLOUD": "AzureCloud", "GFAZPL_MANAGED_IDENTITY_ENABLED": "true",
|
||||
"GFAZPL_MANAGED_IDENTITY_CLIENT_ID": "mock_managed_identity_client_id",
|
||||
@@ -384,7 +385,7 @@ func TestRequestConfigProvider_PluginRequestConfig_azure(t *testing.T) {
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
|
||||
p := NewRequestConfigProvider(pCfg)
|
||||
p := NewRequestConfigProvider(pCfg, &fakeSSOSettingsProvider{})
|
||||
m := p.PluginRequestConfig(context.Background(), "", nil)
|
||||
require.NotContains(t, m, "GFAZPL_AZURE_CLOUD")
|
||||
require.NotContains(t, m, "GFAZPL_MANAGED_IDENTITY_ENABLED")
|
||||
@@ -413,7 +414,7 @@ func TestRequestConfigProvider_PluginRequestConfig_azure(t *testing.T) {
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
|
||||
p := NewRequestConfigProvider(pCfg)
|
||||
p := NewRequestConfigProvider(pCfg, &fakeSSOSettingsProvider{})
|
||||
require.Subset(t, p.PluginRequestConfig(context.Background(), "test-datasource", nil), map[string]string{
|
||||
"GFAZPL_AZURE_CLOUD": "AzureCloud", "GFAZPL_MANAGED_IDENTITY_ENABLED": "true",
|
||||
"GFAZPL_MANAGED_IDENTITY_CLIENT_ID": "mock_managed_identity_client_id",
|
||||
@@ -433,6 +434,108 @@ func TestRequestConfigProvider_PluginRequestConfig_azure(t *testing.T) {
|
||||
"GFAZPL_AZURE_ENTRA_PASSWORD_CREDENTIALS_ENABLED": "true",
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("sets user token endpoint settings from SSO settings for an Azure plugin", func(t *testing.T) {
|
||||
cfg := setting.NewCfg()
|
||||
cfg.Azure = azSettings
|
||||
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
|
||||
p := NewRequestConfigProvider(pCfg, &fakeSSOSettingsProvider{
|
||||
GetForProviderFunc: getAzureSSOSettings,
|
||||
})
|
||||
require.Subset(t, p.PluginRequestConfig(context.Background(), "grafana-azure-monitor-datasource", nil), map[string]string{
|
||||
"GFAZPL_AZURE_CLOUD": "AzureCloud", "GFAZPL_MANAGED_IDENTITY_ENABLED": "true",
|
||||
"GFAZPL_MANAGED_IDENTITY_CLIENT_ID": "mock_managed_identity_client_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_ENABLED": "true",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_TENANT_ID": "mock_workload_identity_tenant_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_CLIENT_ID": "mock_workload_identity_client_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_TOKEN_FILE": "mock_workload_identity_token_file",
|
||||
"GFAZPL_USER_IDENTITY_ENABLED": "true",
|
||||
"GFAZPL_USER_IDENTITY_FALLBACK_SERVICE_CREDENTIALS_ENABLED": "true",
|
||||
"GFAZPL_USER_IDENTITY_TOKEN_URL": "sso_user_identity_token_url",
|
||||
"GFAZPL_USER_IDENTITY_CLIENT_AUTHENTICATION": "sso_user_client_authentication",
|
||||
"GFAZPL_USER_IDENTITY_CLIENT_ID": "sso_user_identity_client_id",
|
||||
"GFAZPL_USER_IDENTITY_CLIENT_SECRET": "sso_user_identity_client_secret",
|
||||
"GFAZPL_USER_IDENTITY_MANAGED_IDENTITY_CLIENT_ID": "sso_user_identity_managed_identity_client_id",
|
||||
"GFAZPL_USER_IDENTITY_FEDERATED_CREDENTIAL_AUDIENCE": "sso_user_identity_federated_credential_audience",
|
||||
"GFAZPL_USER_IDENTITY_ASSERTION": "username",
|
||||
"GFAZPL_AZURE_ENTRA_PASSWORD_CREDENTIALS_ENABLED": "true",
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("does not use SSO settings if overrides have been set for an Azure plugin", func(t *testing.T) {
|
||||
cfg := setting.NewCfg()
|
||||
cfg.Azure = &azsettings.AzureSettings{
|
||||
Cloud: azsettings.AzurePublic,
|
||||
ManagedIdentityEnabled: true,
|
||||
ManagedIdentityClientId: "mock_managed_identity_client_id",
|
||||
WorkloadIdentityEnabled: true,
|
||||
WorkloadIdentitySettings: &azsettings.WorkloadIdentitySettings{
|
||||
TenantId: "mock_workload_identity_tenant_id",
|
||||
ClientId: "mock_workload_identity_client_id",
|
||||
TokenFile: "mock_workload_identity_token_file",
|
||||
},
|
||||
UserIdentityEnabled: true,
|
||||
UserIdentityTokenEndpoint: &azsettings.TokenEndpointSettings{
|
||||
TokenUrl: "override_user_identity_token_url",
|
||||
TokenUrlOverride: true,
|
||||
ClientAuthentication: "override_user_client_authentication",
|
||||
ClientAuthenticationOverride: true,
|
||||
ClientId: "override_user_identity_client_id",
|
||||
ClientIdOverride: true,
|
||||
ClientSecret: "override_user_identity_client_secret",
|
||||
ClientSecretOverride: true,
|
||||
ManagedIdentityClientId: "override_user_identity_managed_identity_client_id",
|
||||
ManagedIdentityClientIdOverride: true,
|
||||
FederatedCredentialAudience: "override_user_identity_federated_credential_audience",
|
||||
FederatedCredentialAudienceOverride: true,
|
||||
UsernameAssertion: true,
|
||||
},
|
||||
UserIdentityFallbackCredentialsEnabled: true,
|
||||
ForwardSettingsPlugins: []string{"grafana-azure-monitor-datasource", "prometheus", "grafana-azure-data-explorer-datasource", "mssql", "grafana-azureprometheus-datasource"},
|
||||
AzureEntraPasswordCredentialsEnabled: true,
|
||||
}
|
||||
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
|
||||
p := NewRequestConfigProvider(pCfg, &fakeSSOSettingsProvider{
|
||||
GetForProviderFunc: getAzureSSOSettings,
|
||||
})
|
||||
require.Subset(t, p.PluginRequestConfig(context.Background(), "grafana-azure-monitor-datasource", nil), map[string]string{
|
||||
"GFAZPL_AZURE_CLOUD": "AzureCloud", "GFAZPL_MANAGED_IDENTITY_ENABLED": "true",
|
||||
"GFAZPL_MANAGED_IDENTITY_CLIENT_ID": "mock_managed_identity_client_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_ENABLED": "true",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_TENANT_ID": "mock_workload_identity_tenant_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_CLIENT_ID": "mock_workload_identity_client_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_TOKEN_FILE": "mock_workload_identity_token_file",
|
||||
"GFAZPL_USER_IDENTITY_ENABLED": "true",
|
||||
"GFAZPL_USER_IDENTITY_FALLBACK_SERVICE_CREDENTIALS_ENABLED": "true",
|
||||
"GFAZPL_USER_IDENTITY_TOKEN_URL": "override_user_identity_token_url",
|
||||
"GFAZPL_USER_IDENTITY_CLIENT_AUTHENTICATION": "override_user_client_authentication",
|
||||
"GFAZPL_USER_IDENTITY_CLIENT_ID": "override_user_identity_client_id",
|
||||
"GFAZPL_USER_IDENTITY_CLIENT_SECRET": "override_user_identity_client_secret",
|
||||
"GFAZPL_USER_IDENTITY_MANAGED_IDENTITY_CLIENT_ID": "override_user_identity_managed_identity_client_id",
|
||||
"GFAZPL_USER_IDENTITY_FEDERATED_CREDENTIAL_AUDIENCE": "override_user_identity_federated_credential_audience",
|
||||
"GFAZPL_USER_IDENTITY_ASSERTION": "username",
|
||||
"GFAZPL_AZURE_ENTRA_PASSWORD_CREDENTIALS_ENABLED": "true",
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func getAzureSSOSettings(ctx context.Context, provider string) (*pluginsso.Settings, error) {
|
||||
return &pluginsso.Settings{
|
||||
Values: map[string]any{
|
||||
"token_url": "sso_user_identity_token_url",
|
||||
"client_authentication": "sso_user_client_authentication",
|
||||
"client_id": "sso_user_identity_client_id",
|
||||
"client_secret": "sso_user_identity_client_secret",
|
||||
"managed_identity_client_id": "sso_user_identity_managed_identity_client_id",
|
||||
"federated_credential_audience": "sso_user_identity_federated_credential_audience",
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func TestRequestConfigProvider_PluginRequestConfig_aws(t *testing.T) {
|
||||
@@ -447,7 +550,7 @@ func TestRequestConfigProvider_PluginRequestConfig_aws(t *testing.T) {
|
||||
cfg.AWSListMetricsPageLimit = "100"
|
||||
cfg.AWSForwardSettingsPlugins = []string{"cloudwatch", "prometheus", "elasticsearch"}
|
||||
|
||||
p := NewRequestConfigProvider(cfg)
|
||||
p := NewRequestConfigProvider(cfg, &fakeSSOSettingsProvider{})
|
||||
|
||||
t.Run("uses the aws settings for an AWS plugin", func(t *testing.T) {
|
||||
require.Subset(t, p.PluginRequestConfig(context.Background(), "cloudwatch", nil), map[string]string{
|
||||
@@ -471,7 +574,7 @@ func TestRequestConfigProvider_PluginRequestConfig_aws(t *testing.T) {
|
||||
t.Run("uses the aws settings for a non-aws user-specified plugin", func(t *testing.T) {
|
||||
cfg.AWSForwardSettingsPlugins = append(cfg.AWSForwardSettingsPlugins, "test-datasource")
|
||||
|
||||
p = NewRequestConfigProvider(cfg)
|
||||
p = NewRequestConfigProvider(cfg, &fakeSSOSettingsProvider{})
|
||||
require.Subset(t, p.PluginRequestConfig(context.Background(), "test-datasource", nil), map[string]string{
|
||||
"AWS_AUTH_AssumeRoleEnabled": "false",
|
||||
"AWS_AUTH_AllowedAuthProviders": "grafana_assume_role,keys",
|
||||
@@ -489,9 +592,20 @@ func TestRequestConfigProvider_PluginRequestConfig_appClientSecret(t *testing.T)
|
||||
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
|
||||
p := NewRequestConfigProvider(pCfg)
|
||||
p := NewRequestConfigProvider(pCfg, &fakeSSOSettingsProvider{})
|
||||
require.Subset(t, p.PluginRequestConfig(context.Background(), "", &auth.ExternalService{
|
||||
ClientSecret: "mysecret",
|
||||
}), map[string]string{backend.AppClientSecret: "mysecret"})
|
||||
})
|
||||
}
|
||||
|
||||
type fakeSSOSettingsProvider struct {
|
||||
GetForProviderFunc func(ctx context.Context, provider string) (*pluginsso.Settings, error)
|
||||
}
|
||||
|
||||
func (m *fakeSSOSettingsProvider) GetForProvider(ctx context.Context, provider string) (*pluginsso.Settings, error) {
|
||||
if m.GetForProviderFunc != nil {
|
||||
return m.GetForProviderFunc(ctx, provider)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings"
|
||||
pluginSettings "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings/service"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsso"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/provisionedplugins"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/renderer"
|
||||
@@ -134,6 +135,8 @@ var WireSet = wire.NewSet(
|
||||
wire.Bind(new(advisor.AdvisorStats), new(*advisor.Service)),
|
||||
pluginchecker.ProvideService,
|
||||
wire.Bind(new(pluginchecker.PluginUpdateChecker), new(*pluginchecker.Service)),
|
||||
pluginsso.ProvideDefaultSettingsProvider,
|
||||
wire.Bind(new(pluginsso.SettingsProvider), new(*pluginsso.DefaultSettingsProvider)),
|
||||
)
|
||||
|
||||
// WireExtensionSet provides a wire.ProviderSet of plugin providers that can be
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package pluginsso
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/ssosettings"
|
||||
)
|
||||
|
||||
// SettingsProvider is used to get the SSO settings for a given provider.
|
||||
type SettingsProvider interface {
|
||||
GetForProvider(ctx context.Context, provider string) (*Settings, error)
|
||||
}
|
||||
|
||||
type Settings struct {
|
||||
Values map[string]any
|
||||
}
|
||||
|
||||
// DefaultSettingsProvider is the default implementation of the SettingsProvider interface.
|
||||
// It uses the SSO settings service to get the settings for a given provider.
|
||||
type DefaultSettingsProvider struct {
|
||||
ssoSettings ssosettings.Service
|
||||
}
|
||||
|
||||
func ProvideDefaultSettingsProvider(ssoSettings ssosettings.Service) *DefaultSettingsProvider {
|
||||
return &DefaultSettingsProvider{
|
||||
ssoSettings: ssoSettings,
|
||||
}
|
||||
}
|
||||
|
||||
// GetForProvider returns the SSO settings for a given provider.
|
||||
// The settings are fetched from the cache if available, otherwise they are fetched from the database.
|
||||
func (p *DefaultSettingsProvider) GetForProvider(ctx context.Context, provider string) (*Settings, error) {
|
||||
settings, err := p.ssoSettings.GetForProviderFromCache(ctx, provider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Settings{
|
||||
Values: settings.Settings,
|
||||
}, nil
|
||||
}
|
||||
@@ -59,22 +59,28 @@ func (cfg *Cfg) readAzureSettings() {
|
||||
// Override individual settings
|
||||
if val := azureSection.Key("user_identity_token_url").String(); val != "" {
|
||||
tokenEndpointSettings.TokenUrl = val
|
||||
tokenEndpointSettings.TokenUrlOverride = true
|
||||
}
|
||||
if val := azureSection.Key("user_identity_client_authentication").String(); val != "" {
|
||||
tokenEndpointSettings.ClientAuthentication = val
|
||||
tokenEndpointSettings.ClientAuthenticationOverride = true
|
||||
}
|
||||
if val := azureSection.Key("user_identity_client_id").String(); val != "" {
|
||||
tokenEndpointSettings.ClientId = val
|
||||
tokenEndpointSettings.ClientIdOverride = true
|
||||
tokenEndpointSettings.ClientSecret = ""
|
||||
}
|
||||
if val := azureSection.Key("user_identity_client_secret").String(); val != "" {
|
||||
tokenEndpointSettings.ClientSecret = val
|
||||
tokenEndpointSettings.ClientSecretOverride = true
|
||||
}
|
||||
if val := azureSection.Key("user_identity_managed_identity_client_id").String(); val != "" {
|
||||
tokenEndpointSettings.ManagedIdentityClientId = val
|
||||
tokenEndpointSettings.ManagedIdentityClientIdOverride = true
|
||||
}
|
||||
if val := azureSection.Key("user_identity_federated_credential_audience").String(); val != "" {
|
||||
tokenEndpointSettings.FederatedCredentialAudience = val
|
||||
tokenEndpointSettings.FederatedCredentialAudienceOverride = true
|
||||
}
|
||||
if val := azureSection.Key("username_assertion").String(); val != "" && val == "username" {
|
||||
tokenEndpointSettings.UsernameAssertion = true
|
||||
|
||||
Reference in New Issue
Block a user