From bfad0f5051521a42efec61ade8ed5aad0dfe4d25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Sun, 3 Mar 2024 00:07:55 +0100 Subject: [PATCH 01/10] Add support for native Azure authentication MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan-Otto Kröpke --- .changeset/serious-badgers-fetch.md | 5 ++ docs/sources/examples/azure.md | 12 ++- go.mod | 6 ++ go.sum | 18 ++-- pkg/infinity/azure.go | 81 ++++++++++++++++++ pkg/infinity/client.go | 17 ++-- pkg/models/settings.go | 85 +++++++++++++------ pkg/models/settings_test.go | 10 +++ src/editors/config/Auth.tsx | 4 + src/editors/config/MicrosoftInput.tsx | 118 ++++++++++++++++++++++++++ src/types/config.types.ts | 11 ++- 11 files changed, 322 insertions(+), 45 deletions(-) create mode 100644 .changeset/serious-badgers-fetch.md create mode 100644 pkg/infinity/azure.go create mode 100644 src/editors/config/MicrosoftInput.tsx diff --git a/.changeset/serious-badgers-fetch.md b/.changeset/serious-badgers-fetch.md new file mode 100644 index 000000000..b45a1e922 --- /dev/null +++ b/.changeset/serious-badgers-fetch.md @@ -0,0 +1,5 @@ +--- +'grafana-infinity-datasource': minor +--- + +Add native Azure authentication diff --git a/docs/sources/examples/azure.md b/docs/sources/examples/azure.md index bac0a8d41..fa201cbd0 100644 --- a/docs/sources/examples/azure.md +++ b/docs/sources/examples/azure.md @@ -33,15 +33,13 @@ Here are the detailed steps on how to connect Microsoft Azure APIs 3. Note down the Client ID, Client Secret and Tenant ID 4. Give reader/monitoring reader access to the resources/subscriptions as necessary 5. Install the infinity plugin in Grafana and add data source for the same - 1. Expand Authentication section and select "OAuth2" - 2. Select "Client Credentials" as OAuth2 type + 1. Expand Authentication section and select "Microsoft Entra ID" + 2. Select "Client Credentials" as Auth type 3. Specify the Client ID 4. Specify the Client Secret - 5. Specify the Token URL `https://login.microsoftonline.com//oauth2/token`. Replace `` with yours - 6. Leave the Scopes section empty - 7. Add the following Endpoint param - 1. Key : `resource` Value: `https://management.azure.com/` - 8. If you are using Infinity 1.0.0+, then also specify `https://management.azure.com/` as an allowed URL. + 5. Specify the Tenant ID + 6. Add the Scope `https://management.azure.com/.default`. + 7. If you are using Infinity 1.0.0+, then also specify `https://management.azure.com/` as an allowed URL. 6. Click Save and Test. 7. Click the `Explore` button 8. Configure the query diff --git a/go.mod b/go.mod index e124c449e..8fd3d448e 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.1 github.com/gorilla/mux v1.8.1 github.com/grafana/grafana-aws-sdk v0.23.1 + github.com/grafana/grafana-azure-sdk-go v1.13.0 github.com/grafana/grafana-plugin-sdk-go v0.206.0 github.com/graphql-go/graphql v0.8.1 github.com/graphql-go/handler v0.2.3 @@ -25,7 +26,9 @@ require ( require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 // indirect github.com/BurntSushi/toml v1.3.2 // indirect github.com/apache/arrow/go/v13 v13.0.0 // indirect github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de // indirect @@ -50,6 +53,7 @@ require ( github.com/goccy/go-json v0.10.2 // indirect github.com/goccy/go-yaml v1.11.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt/v5 v5.2.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/flatbuffers v23.5.26+incompatible // indirect github.com/google/go-cmp v0.6.0 // indirect @@ -74,6 +78,7 @@ require ( github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/klauspost/compress v1.17.3 // indirect github.com/klauspost/cpuid/v2 v2.2.6 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect github.com/lib/pq v1.10.9 // indirect github.com/magefile/mage v1.15.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect @@ -101,6 +106,7 @@ require ( github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pierrec/lz4 v2.6.1+incompatible // indirect github.com/pierrec/lz4/v4 v4.1.18 // indirect + github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.18.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect diff --git a/go.sum b/go.sum index 07ec18ce6..6dfd9c7fb 100644 --- a/go.sum +++ b/go.sum @@ -6,16 +6,16 @@ cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGB cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1 h1:lGlwhPtrX6EVml1hO0ivjkUxsSyl4dsiw9qcA1k/3IQ= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1/go.mod h1:RKUqNu35KJYcVG/fqTRqmuXJZYNhYkBrnC/hX7yGbTA= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 h1:BMAjVKJM0U/CYF27gA0ZMmXGkOcvfFtD0oHVZ1TIPRI= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0/go.mod h1:1fXstnBMas5kzG+S3q8UoJcmyU6nUeunJcMDHcRYHhs= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 h1:sO0/P7g68FrryJzljemN+6GTssUXdANk6aJ7T1ZxnsQ= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1/go.mod h1:h8hyGFDsU5HMivxiS2iYFZsgDbU9OnnJ163x5UGVKYo= github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1 h1:6oNBlSdi1QqM1PNW7FPA6xOGA5UNsXnkaYZz9vdPGhA= github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1/go.mod h1:s4kgfzA0covAXNicZHDMN58jExvcng2mC/DepXiF1EI= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0 h1:AifHbc4mg0x9zW52WOpKbsHaDKuRhlI7TVl47thgQ70= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0/go.mod h1:T5RfihdXtBDxt1Ch2wobif3TvzTdumDy29kahv6AV9A= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.1 h1:AMf7YbZOZIW5b66cXNHMWWT/zkjhz5+a+k/3x40EO7E= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.1/go.mod h1:uwfk06ZBcvL/g4VHNjurPfVln9NMbsk2XIZxJ+hu81k= -github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 h1:WpB/QDNLpMw72xHJc34BNNykqSOeEJDAWkhf0u12/Jk= -github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 h1:DzHpqpoJVaCgOUdVHxE8QB52S6NiVdDQvGlny1qvPqA= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= @@ -108,8 +108,8 @@ github.com/goccy/go-yaml v1.11.2 h1:joq77SxuyIs9zzxEjgyLBugMQ9NEgTWxXfz2wVqwAaQ= github.com/goccy/go-yaml v1.11.2/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE= -github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= +github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -140,6 +140,8 @@ github.com/grafana/dataplane/sdata v0.0.7 h1:CImITypIyS1jxijCR6xqKx71JnYAxcwpH9C github.com/grafana/dataplane/sdata v0.0.7/go.mod h1:Jvs5ddpGmn6vcxT7tCTWAZ1mgi4sbcdFt9utQx5uMAU= github.com/grafana/grafana-aws-sdk v0.23.1 h1:YP6DqzB36fp8fXno0r+X9BxNB3apNfJnQxu8tdhYMH8= github.com/grafana/grafana-aws-sdk v0.23.1/go.mod h1:iTbW395xv26qy6L17SjtZlVwxQTIZbmupBTe0sPHv7k= +github.com/grafana/grafana-azure-sdk-go v1.13.0 h1:2II2kXyHsBOCWkSQBYXrhhzuZpAn+viaesz3y+AyOSM= +github.com/grafana/grafana-azure-sdk-go v1.13.0/go.mod h1:SAlwLdEuox4vw8ZaeQwnepYXnhznnQQdstJbcw8LH68= github.com/grafana/grafana-plugin-sdk-go v0.206.0 h1:DQK2M07/q0t7wqcJBSw6O/FQJZC1tm24uzGfHbA71+A= github.com/grafana/grafana-plugin-sdk-go v0.206.0/go.mod h1:MetVbF3bGwmUvxulWsl0SskJFUq3+ZGnyjDH0dQ4sSg= github.com/grafana/sqlds/v3 v3.2.0 h1:WXuYEaFfiCvgm8kK2ixx44/zAEjFzCylA2+RF3GBqZA= @@ -273,8 +275,8 @@ github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9F github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ= github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= -github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/pkg/infinity/azure.go b/pkg/infinity/azure.go new file mode 100644 index 000000000..8a7c4ce55 --- /dev/null +++ b/pkg/infinity/azure.go @@ -0,0 +1,81 @@ +package infinity + +import ( + "context" + "fmt" + "net/http" + "os" + + "github.com/grafana/grafana-azure-sdk-go/azcredentials" + "github.com/grafana/grafana-azure-sdk-go/azhttpclient" + "github.com/grafana/grafana-azure-sdk-go/azsettings" + "github.com/grafana/grafana-infinity-datasource/pkg/models" + "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" + "github.com/grafana/grafana-plugin-sdk-go/backend/tracing" +) + +func ApplyAzureAuth(ctx context.Context, httpClient *http.Client, settings models.InfinitySettings) (*http.Client, error) { + ctx, span := tracing.DefaultTracer().Start(ctx, "ApplyAzureAuth") + defer span.End() + + if IsAzureAuthConfigured(settings) { + azSettings := &azsettings.AzureSettings{ + Cloud: string(settings.MicrosoftSettings.Cloud), + ManagedIdentityEnabled: true, + WorkloadIdentityEnabled: true, + } + + tenantID := settings.MicrosoftSettings.TenantID + if tenantID == "" { + tenantID = os.Getenv("AZURE_TENANT_ID") + } + + clientID := settings.OAuth2Settings.ClientID + if clientID == "" { + clientID = os.Getenv("AZURE_CLIENT_ID") + } + + var credentials azcredentials.AzureCredentials + + switch settings.MicrosoftSettings.AuthType { + case models.MicrosoftAuthTypeClientSecret: + clientSecret := settings.OAuth2Settings.ClientSecret + if clientSecret == "" { + clientSecret = os.Getenv("AZURE_CLIENT_SECRET") + } + + credentials = &azcredentials.AzureClientSecretCredentials{ + AzureCloud: string(settings.MicrosoftSettings.Cloud), + TenantId: tenantID, + ClientId: clientID, + ClientSecret: clientSecret, + } + case models.MicrosoftAuthTypeManagedIdentity: + azSettings.ManagedIdentityClientId = clientID + + credentials = &azcredentials.AzureManagedIdentityCredentials{ + ClientId: clientID, + } + case models.MicrosoftAuthTypeWorkloadIdentity: + azSettings.WorkloadIdentitySettings = &azsettings.WorkloadIdentitySettings{ + TenantId: tenantID, + ClientId: clientID, + } + + credentials = &azcredentials.AzureWorkloadIdentityCredentials{} + default: + panic(fmt.Errorf("invalid auth type '%s'", settings.MicrosoftSettings.AuthType)) + } + + authOpts := azhttpclient.NewAuthOptions(azSettings) + authOpts.Scopes(settings.OAuth2Settings.Scopes) + + httpClient.Transport = azhttpclient.AzureMiddleware(authOpts, credentials). + CreateMiddleware(httpclient.Options{}, httpClient.Transport) + } + return httpClient, nil +} + +func IsAzureAuthConfigured(settings models.InfinitySettings) bool { + return settings.AuthenticationMethod == models.AuthenticationMethodMicrosoft +} diff --git a/pkg/infinity/client.go b/pkg/infinity/client.go index ce7a53650..df740e7f5 100644 --- a/pkg/infinity/client.go +++ b/pkg/infinity/client.go @@ -105,6 +105,10 @@ func NewClient(ctx context.Context, settings models.InfinitySettings) (client *C httpClient = ApplyOAuthClientCredentials(ctx, httpClient, settings) httpClient = ApplyOAuthJWT(ctx, httpClient, settings) httpClient = ApplyAWSAuth(ctx, httpClient, settings) + httpClient, err = ApplyAzureAuth(ctx, httpClient, settings) + if err != nil { + return nil, err + } httpClient, err = ApplySecureSocksProxyConfiguration(httpClient, settings) if err != nil { @@ -159,12 +163,15 @@ func ApplySecureSocksProxyConfiguration(httpClient *http.Client, settings models t = t.(*oauth2.Transport).Base } - // secure socks proxy configuration - checks if enabled inside the function - err := proxy.New(settings.ProxyOpts.ProxyOptions).ConfigureSecureSocksHTTPProxy(t.(*http.Transport)) - if err != nil { - backend.Logger.Error("error configuring secure socks proxy", "err", err.Error()) - return nil, fmt.Errorf("error configuring secure socks proxy. %s", err) + if t, ok := t.(*http.Transport); ok { + // secure socks proxy configuration - checks if enabled inside the function + err := proxy.New(settings.ProxyOpts.ProxyOptions).ConfigureSecureSocksHTTPProxy(t) + if err != nil { + backend.Logger.Error("error configuring secure socks proxy", "err", err.Error()) + return nil, fmt.Errorf("error configuring secure socks proxy. %s", err) + } } + return httpClient, nil } diff --git a/pkg/models/settings.go b/pkg/models/settings.go index b80e7cc57..ba9813600 100644 --- a/pkg/models/settings.go +++ b/pkg/models/settings.go @@ -8,6 +8,8 @@ import ( "net/textproto" "strings" + "github.com/grafana/grafana-azure-sdk-go/azcredentials" + "github.com/grafana/grafana-azure-sdk-go/azsettings" "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" "golang.org/x/oauth2" @@ -22,6 +24,7 @@ const ( AuthenticationMethodDigestAuth = "digestAuth" AuthenticationMethodOAuth = "oauth2" AuthenticationMethodAWS = "aws" + AuthenticationMethodMicrosoft = "microsoft" AuthenticationMethodAzureBlob = "azureBlob" ) @@ -62,6 +65,28 @@ type AWSSettings struct { Service string `json:"service"` } +type MicrosoftAuthType string + +const ( + MicrosoftAuthTypeManagedIdentity MicrosoftAuthType = azcredentials.AzureAuthManagedIdentity + MicrosoftAuthTypeWorkloadIdentity MicrosoftAuthType = azcredentials.AzureAuthWorkloadIdentity + MicrosoftAuthTypeClientSecret MicrosoftAuthType = azcredentials.AzureAuthClientSecret +) + +type MicrosoftCloudType string + +const ( + MicrosoftCloudPublic MicrosoftCloudType = azsettings.AzurePublic + MicrosoftCloudChina MicrosoftCloudType = azsettings.AzureChina + MicrosoftCloudUSGovernment MicrosoftCloudType = azsettings.AzureUSGovernment +) + +type MicrosoftSettings struct { + Cloud MicrosoftCloudType `json:"cloud"` + AuthType MicrosoftAuthType `json:"auth_type"` + TenantID string `json:"tenant_id"` +} + type ProxyType string const ( @@ -81,6 +106,7 @@ type InfinitySettings struct { AWSSettings AWSSettings AWSAccessKey string AWSSecretKey string + MicrosoftSettings MicrosoftSettings URL string BasicAuthEnabled bool UserName string @@ -157,30 +183,31 @@ type RefData struct { } type InfinitySettingsJson struct { - IsMock bool `json:"is_mock,omitempty"` - AuthenticationMethod string `json:"auth_method,omitempty"` - APIKeyKey string `json:"apiKeyKey,omitempty"` - APIKeyType string `json:"apiKeyType,omitempty"` - OAuth2Settings OAuth2Settings `json:"oauth2,omitempty"` - AWSSettings AWSSettings `json:"aws,omitempty"` - ForwardOauthIdentity bool `json:"oauthPassThru,omitempty"` - InsecureSkipVerify bool `json:"tlsSkipVerify,omitempty"` - ServerName string `json:"serverName,omitempty"` - TLSClientAuth bool `json:"tlsAuth,omitempty"` - TLSAuthWithCACert bool `json:"tlsAuthWithCACert,omitempty"` - TimeoutInSeconds int64 `json:"timeoutInSeconds,omitempty"` - ProxyType ProxyType `json:"proxy_type,omitempty"` - ProxyUrl string `json:"proxy_url,omitempty"` - AllowedHosts []string `json:"allowedHosts,omitempty"` - EnableOpenAPI bool `json:"enableOpenApi,omitempty"` - OpenAPIVersion string `json:"openApiVersion,omitempty"` - OpenAPIUrl string `json:"openApiUrl,omitempty"` - OpenAPIBaseUrl string `json:"openAPIBaseURL,omitempty"` - ReferenceData []RefData `json:"refData,omitempty"` - CustomHealthCheckEnabled bool `json:"customHealthCheckEnabled,omitempty"` - CustomHealthCheckUrl string `json:"customHealthCheckUrl,omitempty"` - AzureBlobAccountUrl string `json:"azureBlobAccountUrl,omitempty"` - AzureBlobAccountName string `json:"azureBlobAccountName,omitempty"` + IsMock bool `json:"is_mock,omitempty"` + AuthenticationMethod string `json:"auth_method,omitempty"` + APIKeyKey string `json:"apiKeyKey,omitempty"` + APIKeyType string `json:"apiKeyType,omitempty"` + OAuth2Settings OAuth2Settings `json:"oauth2,omitempty"` + AWSSettings AWSSettings `json:"aws,omitempty"` + MicrosoftSettings MicrosoftSettings `json:"microsoft,omitempty"` + ForwardOauthIdentity bool `json:"oauthPassThru,omitempty"` + InsecureSkipVerify bool `json:"tlsSkipVerify,omitempty"` + ServerName string `json:"serverName,omitempty"` + TLSClientAuth bool `json:"tlsAuth,omitempty"` + TLSAuthWithCACert bool `json:"tlsAuthWithCACert,omitempty"` + TimeoutInSeconds int64 `json:"timeoutInSeconds,omitempty"` + ProxyType ProxyType `json:"proxy_type,omitempty"` + ProxyUrl string `json:"proxy_url,omitempty"` + AllowedHosts []string `json:"allowedHosts,omitempty"` + EnableOpenAPI bool `json:"enableOpenApi,omitempty"` + OpenAPIVersion string `json:"openApiVersion,omitempty"` + OpenAPIUrl string `json:"openApiUrl,omitempty"` + OpenAPIBaseUrl string `json:"openAPIBaseURL,omitempty"` + ReferenceData []RefData `json:"refData,omitempty"` + CustomHealthCheckEnabled bool `json:"customHealthCheckEnabled,omitempty"` + CustomHealthCheckUrl string `json:"customHealthCheckUrl,omitempty"` + AzureBlobAccountUrl string `json:"azureBlobAccountUrl,omitempty"` + AzureBlobAccountName string `json:"azureBlobAccountName,omitempty"` } func LoadSettings(ctx context.Context, config backend.DataSourceInstanceSettings) (settings InfinitySettings, err error) { @@ -227,6 +254,16 @@ func LoadSettings(ctx context.Context, config backend.DataSourceInstanceSettings if len(infJson.AllowedHosts) > 0 { settings.AllowedHosts = infJson.AllowedHosts } + + settings.MicrosoftSettings = infJson.MicrosoftSettings + if settings.AuthenticationMethod == "microsoft" { + if settings.MicrosoftSettings.AuthType == "" { + settings.MicrosoftSettings.AuthType = "clientsecret" + } + if settings.MicrosoftSettings.Cloud == "" { + settings.MicrosoftSettings.Cloud = MicrosoftCloudPublic + } + } } settings.EnableOpenAPI = infJson.EnableOpenAPI settings.OpenAPIVersion = infJson.OpenAPIVersion diff --git a/pkg/models/settings_test.go b/pkg/models/settings_test.go index aa569825b..d5f79044a 100644 --- a/pkg/models/settings_test.go +++ b/pkg/models/settings_test.go @@ -160,6 +160,11 @@ func TestAllSettingsAgainstFrontEnd(t *testing.T) { "region" : "region1", "service" : "service1" }, + "microsoft" : { + "cloud" : "AzureUSGovernment", + "auth_type" : "clientsecret", + "tenant_id" : "tenant1" + }, "oauth2" : { "client_id":"myClientID", "email":"myEmail", @@ -212,6 +217,11 @@ func TestAllSettingsAgainstFrontEnd(t *testing.T) { Service: "service1", Region: "region1", }, + MicrosoftSettings: models.MicrosoftSettings{ + Cloud: models.MicrosoftCloudUSGovernment, + AuthType: models.MicrosoftAuthTypeClientSecret, + TenantID: "tenant1", + }, OAuth2Settings: models.OAuth2Settings{ ClientID: "myClientID", OAuth2Type: "client_credentials", diff --git a/src/editors/config/Auth.tsx b/src/editors/config/Auth.tsx index 35057cd7d..5f15015c8 100644 --- a/src/editors/config/Auth.tsx +++ b/src/editors/config/Auth.tsx @@ -4,6 +4,7 @@ import { Icon, InlineFormLabel, LegacyForms, RadioButtonGroup, Select, useTheme2 import React, { useState } from 'react'; import { AllowedHostsEditor } from './AllowedHosts'; import { OAuthInputsEditor } from './OAuthInput'; +import { MicrosoftInputsEditor } from './MicrosoftInput'; import { OthersAuthentication } from './OtherAuthProviders'; import { AWSRegions } from './../../constants'; import type { APIKeyType, AuthType, InfinityOptions, InfinitySecureOptions } from './../../types'; @@ -17,6 +18,7 @@ const authTypes: Array & { logo?: string }> { value: 'oauthPassThru', label: 'Forward OAuth' }, { value: 'oauth2', label: 'OAuth2', logo: '/public/plugins/yesoreyeram-infinity-datasource/img/oauth-2-sm.png' }, { value: 'aws', label: 'AWS', logo: '/public/plugins/yesoreyeram-infinity-datasource/img/aws.jpg' }, + { value: 'microsoft', label: 'Microsoft Entra ID' }, { value: 'azureBlob', label: 'Azure Blob' }, { value: 'others', label: 'Other Auth Providers' }, ]; @@ -76,6 +78,7 @@ export const AuthEditor = (props: DataSourcePluginOptionsEditorProps )} {authType === 'oauth2' && } + {authType === 'microsoft' && } {authType === 'azureBlob' && ( <>
diff --git a/src/editors/config/MicrosoftInput.tsx b/src/editors/config/MicrosoftInput.tsx new file mode 100644 index 000000000..c69af16ef --- /dev/null +++ b/src/editors/config/MicrosoftInput.tsx @@ -0,0 +1,118 @@ +import { onUpdateDatasourceSecureJsonDataOption, DataSourcePluginOptionsEditorProps, SelectableValue } from '@grafana/data'; +import {InlineFormLabel, Input, LegacyForms, RadioButtonGroup, Select} from '@grafana/ui'; +import React from 'react'; +import type { + InfinityOptions, + InfinitySecureOptions, + MicrosoftAuthType, MicrosoftCloudType, + MicrosoftProps, + OAuth2Props +} from './../../types'; + +const microsoftCloudTypes: Array> = [ + { value: 'AzureCloud', label: 'Azure' }, + { value: 'AzureUSGovernment', label: 'Azure US Government' }, + { value: 'AzureChinaCloud', label: 'Azure China Cloud' }, +]; + +const microsoftAuthTypes: Array> = [ + { value: 'clientsecret', label: 'Client Secret' }, + { value: 'msi', label: 'Managed Identity' }, + { value: 'workloadidentity', label: 'Workload Identity' }, +]; + +export const MicrosoftInputsEditor = (props: DataSourcePluginOptionsEditorProps) => { + const { options, onOptionsChange } = props; + const { secureJsonFields } = options; + const secureJsonData = (options.secureJsonData || {}) as InfinitySecureOptions; + let oauth2: OAuth2Props = options?.jsonData?.oauth2 || {}; + let microsoft: MicrosoftProps = options?.jsonData?.microsoft || {}; + + const onMicrosoftPropsChange = (key: T, value: V) => { + onOptionsChange({ ...options, jsonData: { ...options.jsonData, microsoft: { ...microsoft, [key]: value } } }); + }; + + const onOAuth2PropsChange = (key: T, value: V) => { + onOptionsChange({ ...options, jsonData: { ...options.jsonData, oauth2: { ...oauth2, [key]: value } } }); + }; + const onResetClientSecret = () => { + onOptionsChange({ + ...options, + secureJsonFields: { ...options.secureJsonFields, oauth2ClientSecret: false }, + secureJsonData: { ...options.secureJsonData, oauth2ClientSecret: '' }, + }); + }; + return ( + <> +
+ + Cloud + + +
+
+ Tenant ID + onMicrosoftPropsChange('tenant_id', v.currentTarget.value)} value={microsoft.tenant_id} width={60} placeholder={'Tenant ID'} /> +
+
+ + Authentication Type + + + options={microsoftAuthTypes} + onChange={(v) => onMicrosoftPropsChange('auth_type', v)} + value={microsoft.auth_type || 'clientsecret'}> +
+
+ Client ID + onOAuth2PropsChange('client_id', v.currentTarget.value)} value={oauth2.client_id} width={60} placeholder={'Client ID'} /> +
+ {(microsoft.auth_type === 'clientsecret' || !microsoft?.auth_type) && ( + <> +
+ +
+ + )} +
+ + {`For accessing the Microsoft Azure Resource Manager, use https://management.azure.com/.default`} +
+
+ {`For accessing the Microsoft Graph API, use: https://graph.microsoft.com/.default`} +
+
+ {`For accessing other API, use: https://[hostname]/.default`} + + } + {...{interactive: true }} + >Scopes
+ onOAuth2PropsChange('scopes', (v.currentTarget.value || '').split(','))} + value={(oauth2.scopes || []).join(',')} + width={60} + placeholder={'Comma separated values of scopes'} + /> +
+ + ); +}; diff --git a/src/types/config.types.ts b/src/types/config.types.ts index 48eeb89b4..5a05eae3f 100644 --- a/src/types/config.types.ts +++ b/src/types/config.types.ts @@ -7,7 +7,7 @@ export interface GlobalInfinityQuery { id: string; query: InfinityQuery; } -export type AuthType = 'none' | 'basicAuth' | 'apiKey' | 'bearerToken' | 'oauthPassThru' | 'digestAuth' | 'aws' | 'azureBlob' | 'oauth2'; +export type AuthType = 'none' | 'basicAuth' | 'apiKey' | 'bearerToken' | 'oauthPassThru' | 'digestAuth' | 'aws' | 'azureBlob' | 'oauth2' | 'microsoft'; export type OAuth2Type = 'client_credentials' | 'jwt' | 'others'; export type APIKeyType = 'header' | 'query'; export type OAuth2Props = { @@ -25,6 +25,14 @@ export type AWSAuthProps = { region?: string; service?: string; }; + +export type MicrosoftCloudType = 'AzureCloud' | 'AzureChinaCloud' | 'AzureUSGovernment'; +export type MicrosoftAuthType = 'clientsecret' | 'msi' | 'workloadidentity'; +export type MicrosoftProps = { + cloud?: MicrosoftCloudType; + auth_type?: MicrosoftAuthType; + tenant_id?: string; +}; export type InfinityReferenceData = { name: string; data: string }; export type ProxyType = 'none' | 'env' | 'url'; export interface InfinityOptions extends DataSourceJsonData { @@ -33,6 +41,7 @@ export interface InfinityOptions extends DataSourceJsonData { apiKeyType?: APIKeyType; oauth2?: OAuth2Props; aws?: AWSAuthProps; + microsoft?: MicrosoftProps; tlsSkipVerify?: boolean; tlsAuth?: boolean; serverName?: string; From 5c11907ac1a9e7bd71cd17a5a8fd5155157c92fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Mon, 15 Apr 2024 17:42:43 +0200 Subject: [PATCH 02/10] go mod tidy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan-Otto Kröpke --- go.sum | 2 ++ 1 file changed, 2 insertions(+) diff --git a/go.sum b/go.sum index 1a8754f8d..8e97646b2 100644 --- a/go.sum +++ b/go.sum @@ -131,6 +131,8 @@ github.com/grafana/dataplane/sdata v0.0.7 h1:CImITypIyS1jxijCR6xqKx71JnYAxcwpH9C github.com/grafana/dataplane/sdata v0.0.7/go.mod h1:Jvs5ddpGmn6vcxT7tCTWAZ1mgi4sbcdFt9utQx5uMAU= github.com/grafana/grafana-aws-sdk v0.24.0 h1:0RKCJTeIkpEUvLCTjGOK1+jYZpaE2nJaGghGLvtUsFs= github.com/grafana/grafana-aws-sdk v0.24.0/go.mod h1:3zghFF6edrxn0d6k6X9HpGZXDH+VfA+MwD2Pc/9X0ec= +github.com/grafana/grafana-azure-sdk-go v1.13.0 h1:2II2kXyHsBOCWkSQBYXrhhzuZpAn+viaesz3y+AyOSM= +github.com/grafana/grafana-azure-sdk-go v1.13.0/go.mod h1:SAlwLdEuox4vw8ZaeQwnepYXnhznnQQdstJbcw8LH68= github.com/grafana/grafana-plugin-sdk-go v0.220.0 h1:0UgyATMH9em+qk1YVqplzZpDSMFcRjx6YBjnl2cIe+E= github.com/grafana/grafana-plugin-sdk-go v0.220.0/go.mod h1:epJ5s1UeH/mzBpRrkiO8iz9xc6uuQ8f4zwdmCA4kYmo= github.com/grafana/sqlds/v3 v3.2.0 h1:WXuYEaFfiCvgm8kK2ixx44/zAEjFzCylA2+RF3GBqZA= From 38bf447974f81cd40aca8f6ecf393fb9db901302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Mon, 15 Apr 2024 19:27:38 +0200 Subject: [PATCH 03/10] Rewrite credential handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan-Otto Kröpke --- .changeset/serious-badgers-fetch.md | 2 +- docker-compose.yaml | 3 ++ pkg/infinity/azure.go | 60 ++++++++++++----------- pkg/infinity/client.go | 14 +++--- pkg/models/settings.go | 63 +++++++++++++++++++++--- pkg/models/settings_test.go | 18 ++++--- src/editors/config/Auth.tsx | 4 +- src/editors/config/MicrosoftInput.tsx | 70 ++++++++++++++++++--------- src/types/config.types.ts | 5 +- 9 files changed, 163 insertions(+), 76 deletions(-) diff --git a/.changeset/serious-badgers-fetch.md b/.changeset/serious-badgers-fetch.md index b45a1e922..3eb73f5de 100644 --- a/.changeset/serious-badgers-fetch.md +++ b/.changeset/serious-badgers-fetch.md @@ -2,4 +2,4 @@ 'grafana-infinity-datasource': minor --- -Add native Azure authentication +Add native Microsoft authentication diff --git a/docker-compose.yaml b/docker-compose.yaml index ec84914e4..6ede3cc35 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -22,3 +22,6 @@ services: - GF_SECURITY_ANGULAR_SUPPORT_ENABLED=false - GF_SECURITY_CSRF_ALWAYS_CHECK=true - GF_ENTERPRISE_LICENSE_TEXT=$GF_ENTERPRISE_LICENSE_TEXT + - GF_AZURE_FORWARD_SETTINGS_TO_PLUGINS= + - GF_AZURE_WORKLOAD_IDENTITY_ENABLED=true + - GF_AZURE_USER_IDENTITY_ENABLED=true diff --git a/pkg/infinity/azure.go b/pkg/infinity/azure.go index 8a7c4ce55..302cec516 100644 --- a/pkg/infinity/azure.go +++ b/pkg/infinity/azure.go @@ -4,7 +4,7 @@ import ( "context" "fmt" "net/http" - "os" + "strings" "github.com/grafana/grafana-azure-sdk-go/azcredentials" "github.com/grafana/grafana-azure-sdk-go/azhttpclient" @@ -19,56 +19,62 @@ func ApplyAzureAuth(ctx context.Context, httpClient *http.Client, settings model defer span.End() if IsAzureAuthConfigured(settings) { - azSettings := &azsettings.AzureSettings{ - Cloud: string(settings.MicrosoftSettings.Cloud), - ManagedIdentityEnabled: true, - WorkloadIdentityEnabled: true, - } - - tenantID := settings.MicrosoftSettings.TenantID - if tenantID == "" { - tenantID = os.Getenv("AZURE_TENANT_ID") - } - - clientID := settings.OAuth2Settings.ClientID - if clientID == "" { - clientID = os.Getenv("AZURE_CLIENT_ID") + azSettings, err := azsettings.ReadFromEnv() + if err != nil { + return nil, err } var credentials azcredentials.AzureCredentials switch settings.MicrosoftSettings.AuthType { case models.MicrosoftAuthTypeClientSecret: - clientSecret := settings.OAuth2Settings.ClientSecret - if clientSecret == "" { - clientSecret = os.Getenv("AZURE_CLIENT_SECRET") + + if strings.TrimSpace(settings.MicrosoftSettings.TenantID) == "" { + return nil, fmt.Errorf("Tenant ID %w ", models.MicrosoftRequiredForClientSecretErrHelp) + } + + if strings.TrimSpace(settings.MicrosoftSettings.ClientID) == "" { + return nil, fmt.Errorf("Client ID %w ", models.MicrosoftRequiredForClientSecretErrHelp) + } + + if strings.TrimSpace(settings.MicrosoftSettings.ClientSecret) == "" { + return nil, fmt.Errorf("Client secret %w ", models.MicrosoftRequiredForClientSecretErrHelp) } credentials = &azcredentials.AzureClientSecretCredentials{ AzureCloud: string(settings.MicrosoftSettings.Cloud), - TenantId: tenantID, - ClientId: clientID, - ClientSecret: clientSecret, + TenantId: settings.MicrosoftSettings.TenantID, + ClientId: settings.MicrosoftSettings.ClientID, + ClientSecret: settings.MicrosoftSettings.ClientSecret, } case models.MicrosoftAuthTypeManagedIdentity: - azSettings.ManagedIdentityClientId = clientID + if !azSettings.ManagedIdentityEnabled { + return nil, fmt.Errorf("Managed Identity %w ", models.MicrosoftDisabledAuthErrHelp) + } credentials = &azcredentials.AzureManagedIdentityCredentials{ - ClientId: clientID, + // ClientId is optional for managed identity, because it can be inferred from the environment + // https://github.com/grafana/grafana-azure-sdk-go/blob/21e2891b4190eb7c255c8cd275836def8200faf8/aztokenprovider/retriever_msi.go#L20-L30 + ClientId: settings.MicrosoftSettings.ClientID, } case models.MicrosoftAuthTypeWorkloadIdentity: - azSettings.WorkloadIdentitySettings = &azsettings.WorkloadIdentitySettings{ - TenantId: tenantID, - ClientId: clientID, + if !azSettings.WorkloadIdentityEnabled { + return nil, fmt.Errorf("Workload Identity %w ", models.MicrosoftDisabledAuthErrHelp) } credentials = &azcredentials.AzureWorkloadIdentityCredentials{} + case models.MicrosoftAuthTypeCurrentUserIdentity: + if !azSettings.UserIdentityEnabled { + return nil, fmt.Errorf("User Identity %w ", models.MicrosoftDisabledAuthErrHelp) + } + + credentials = &azcredentials.AadCurrentUserCredentials{} default: panic(fmt.Errorf("invalid auth type '%s'", settings.MicrosoftSettings.AuthType)) } authOpts := azhttpclient.NewAuthOptions(azSettings) - authOpts.Scopes(settings.OAuth2Settings.Scopes) + authOpts.Scopes(settings.MicrosoftSettings.Scopes) httpClient.Transport = azhttpclient.AzureMiddleware(authOpts, credentials). CreateMiddleware(httpclient.Options{}, httpClient.Transport) diff --git a/pkg/infinity/client.go b/pkg/infinity/client.go index 9682d3d21..c40b35361 100644 --- a/pkg/infinity/client.go +++ b/pkg/infinity/client.go @@ -159,7 +159,7 @@ func NewClient(ctx context.Context, settings models.InfinitySettings) (client *C } func ApplySecureSocksProxyConfiguration(httpClient *http.Client, settings models.InfinitySettings) (*http.Client, error) { - if IsAwsAuthConfigured(settings) { + if IsAwsAuthConfigured(settings) || IsAzureAuthConfigured(settings) { return httpClient, nil } t := httpClient.Transport @@ -171,13 +171,11 @@ func ApplySecureSocksProxyConfiguration(httpClient *http.Client, settings models t = t.(*oauth2.Transport).Base } - if t, ok := t.(*http.Transport); ok { - // secure socks proxy configuration - checks if enabled inside the function - err := proxy.New(settings.ProxyOpts.ProxyOptions).ConfigureSecureSocksHTTPProxy(t) - if err != nil { - backend.Logger.Error("error configuring secure socks proxy", "err", err.Error()) - return nil, fmt.Errorf("error configuring secure socks proxy. %s", err) - } + // secure socks proxy configuration - checks if enabled inside the function + err := proxy.New(settings.ProxyOpts.ProxyOptions).ConfigureSecureSocksHTTPProxy(t.(*http.Transport)) + if err != nil { + backend.Logger.Error("error configuring secure socks proxy", "err", err.Error()) + return nil, fmt.Errorf("error configuring secure socks proxy. %s", err) } return httpClient, nil diff --git a/pkg/models/settings.go b/pkg/models/settings.go index d21b506b0..6bc475213 100644 --- a/pkg/models/settings.go +++ b/pkg/models/settings.go @@ -68,9 +68,10 @@ type AWSSettings struct { type MicrosoftAuthType string const ( - MicrosoftAuthTypeManagedIdentity MicrosoftAuthType = azcredentials.AzureAuthManagedIdentity - MicrosoftAuthTypeWorkloadIdentity MicrosoftAuthType = azcredentials.AzureAuthWorkloadIdentity - MicrosoftAuthTypeClientSecret MicrosoftAuthType = azcredentials.AzureAuthClientSecret + MicrosoftAuthTypeManagedIdentity MicrosoftAuthType = azcredentials.AzureAuthManagedIdentity + MicrosoftAuthTypeWorkloadIdentity MicrosoftAuthType = azcredentials.AzureAuthWorkloadIdentity + MicrosoftAuthTypeClientSecret MicrosoftAuthType = azcredentials.AzureAuthClientSecret + MicrosoftAuthTypeCurrentUserIdentity MicrosoftAuthType = azcredentials.AzureAuthCurrentUserIdentity ) type MicrosoftCloudType string @@ -81,10 +82,20 @@ const ( MicrosoftCloudUSGovernment MicrosoftCloudType = azsettings.AzureUSGovernment ) +var ( + MicrosoftRequiredForClientSecretErrHelp = errors.New(` is required for Microsoft client secret authentication`) + MicrosoftDisabledAuthErrHelp = errors.New(` is not enabled in the Grafana Azure settings. For more information, please refer to the Grafana documentation at +https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#azure. +Additionally, this plugin needs to be added to the grafana.ini setting azure.forward_settings_to_plugins.`) +) + type MicrosoftSettings struct { - Cloud MicrosoftCloudType `json:"cloud"` - AuthType MicrosoftAuthType `json:"auth_type"` - TenantID string `json:"tenant_id"` + Cloud MicrosoftCloudType `json:"cloud"` + AuthType MicrosoftAuthType `json:"auth_type"` + TenantID string `json:"tenant_id"` + ClientID string `json:"client_id"` + ClientSecret string + Scopes []string `json:"scopes,omitempty"` } type ProxyType string @@ -165,6 +176,42 @@ func (s *InfinitySettings) Validate() error { } return nil } + if s.AuthenticationMethod == AuthenticationMethodMicrosoft { + azSettings, err := azsettings.ReadFromEnv() + if err != nil { + return err + } + + switch s.MicrosoftSettings.AuthType { + case MicrosoftAuthTypeClientSecret: + if strings.TrimSpace(s.MicrosoftSettings.TenantID) == "" { + return fmt.Errorf("Tenant ID %w ", MicrosoftRequiredForClientSecretErrHelp) + } + + if strings.TrimSpace(s.MicrosoftSettings.ClientID) == "" { + return fmt.Errorf("Client ID %w ", MicrosoftRequiredForClientSecretErrHelp) + } + + if strings.TrimSpace(s.MicrosoftSettings.ClientSecret) == "" { + return fmt.Errorf("Client secret %w ", MicrosoftRequiredForClientSecretErrHelp) + } + case MicrosoftAuthTypeManagedIdentity: + if !azSettings.ManagedIdentityEnabled { + return errors.New("managed identity authentication is not enabled in Grafana config. " + + "Refer https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#azure") + } + case MicrosoftAuthTypeWorkloadIdentity: + if !azSettings.WorkloadIdentityEnabled { + return errors.New("workload identity authentication is not enabled in Grafana config." + + "Refer https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#azure") + } + case MicrosoftAuthTypeCurrentUserIdentity: + if !azSettings.UserIdentityEnabled { + return errors.New("user identity authentication is not enabled in Grafana config." + + "Refer https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#azure") + } + } + } if s.AuthenticationMethod != AuthenticationMethodNone && len(s.AllowedHosts) < 1 { return errors.New("configure allowed hosts in the authentication section") } @@ -212,7 +259,6 @@ type InfinitySettingsJson struct { ProxyType ProxyType `json:"proxy_type,omitempty"` ProxyUrl string `json:"proxy_url,omitempty"` AllowedHosts []string `json:"allowedHosts,omitempty"` - ReferenceData []RefData `json:"refData,omitempty"` CustomHealthCheckEnabled bool `json:"customHealthCheckEnabled,omitempty"` CustomHealthCheckUrl string `json:"customHealthCheckUrl,omitempty"` @@ -312,6 +358,9 @@ func LoadSettings(ctx context.Context, config backend.DataSourceInstanceSettings if val, ok := config.DecryptedSecureJSONData["azureBlobAccountKey"]; ok { settings.AzureBlobAccountKey = val } + if val, ok := config.DecryptedSecureJSONData["microsoftClientSecret"]; ok { + settings.MicrosoftSettings.ClientSecret = val + } settings.CustomHeaders = GetSecrets(config, "httpHeaderName", "httpHeaderValue") settings.SecureQueryFields = GetSecrets(config, "secureQueryName", "secureQueryValue") settings.OAuth2Settings.EndpointParams = GetSecrets(config, "oauth2EndPointParamsName", "oauth2EndPointParamsValue") diff --git a/pkg/models/settings_test.go b/pkg/models/settings_test.go index d5f79044a..7b2083877 100644 --- a/pkg/models/settings_test.go +++ b/pkg/models/settings_test.go @@ -161,9 +161,11 @@ func TestAllSettingsAgainstFrontEnd(t *testing.T) { "service" : "service1" }, "microsoft" : { - "cloud" : "AzureUSGovernment", - "auth_type" : "clientsecret", - "tenant_id" : "tenant1" + "cloud" : "AzureUSGovernment", + "auth_type" : "clientsecret", + "tenant_id" : "tenant1", + "client_id" : "myMicrosoftClientID", + "scopes" : ["msscope1","msscope2"] }, "oauth2" : { "client_id":"myClientID", @@ -186,6 +188,7 @@ func TestAllSettingsAgainstFrontEnd(t *testing.T) { "awsAccessKey": "awsAccessKey1", "awsSecretKey": "awsSecretKey1", "oauth2ClientSecret": "myOauth2ClientSecret", + "microsoftClientSecret": "myMicrosoftClientSecret", "oauth2JWTPrivateKey": "myOauth2JWTPrivateKey", "oauth2EndPointParamsValue1": "Resource1", "oauth2EndPointParamsValue2": "Resource2", @@ -218,9 +221,12 @@ func TestAllSettingsAgainstFrontEnd(t *testing.T) { Region: "region1", }, MicrosoftSettings: models.MicrosoftSettings{ - Cloud: models.MicrosoftCloudUSGovernment, - AuthType: models.MicrosoftAuthTypeClientSecret, - TenantID: "tenant1", + Cloud: models.MicrosoftCloudUSGovernment, + AuthType: models.MicrosoftAuthTypeClientSecret, + TenantID: "tenant1", + ClientID: "myMicrosoftClientID", + ClientSecret: "myMicrosoftClientSecret", + Scopes: []string{"msscope1", "msscope2"}, }, OAuth2Settings: models.OAuth2Settings{ ClientID: "myClientID", diff --git a/src/editors/config/Auth.tsx b/src/editors/config/Auth.tsx index 5f15015c8..fc8bc1759 100644 --- a/src/editors/config/Auth.tsx +++ b/src/editors/config/Auth.tsx @@ -18,7 +18,7 @@ const authTypes: Array & { logo?: string }> { value: 'oauthPassThru', label: 'Forward OAuth' }, { value: 'oauth2', label: 'OAuth2', logo: '/public/plugins/yesoreyeram-infinity-datasource/img/oauth-2-sm.png' }, { value: 'aws', label: 'AWS', logo: '/public/plugins/yesoreyeram-infinity-datasource/img/aws.jpg' }, - { value: 'microsoft', label: 'Microsoft Entra ID' }, + { value: 'microsoft', label: 'Microsoft Entra ID', logo: '/public/img/microsoft_auth_icon.svg' }, { value: 'azureBlob', label: 'Azure Blob' }, { value: 'others', label: 'Other Auth Providers' }, ]; @@ -137,7 +137,7 @@ export const AuthEditor = (props: DataSourcePluginOptionsEditorProps - {a.logo ? : } + {a.logo ? : } {a.label} ))} diff --git a/src/editors/config/MicrosoftInput.tsx b/src/editors/config/MicrosoftInput.tsx index c69af16ef..2cb313f96 100644 --- a/src/editors/config/MicrosoftInput.tsx +++ b/src/editors/config/MicrosoftInput.tsx @@ -5,13 +5,12 @@ import type { InfinityOptions, InfinitySecureOptions, MicrosoftAuthType, MicrosoftCloudType, - MicrosoftProps, - OAuth2Props + MicrosoftProps } from './../../types'; const microsoftCloudTypes: Array> = [ { value: 'AzureCloud', label: 'Azure' }, - { value: 'AzureUSGovernment', label: 'Azure US Government' }, + { value: 'AzureUSGovernment', label: 'Azure US Government' }, { value: 'AzureChinaCloud', label: 'Azure China Cloud' }, ]; @@ -19,27 +18,24 @@ const microsoftAuthTypes: Array> = [ { value: 'clientsecret', label: 'Client Secret' }, { value: 'msi', label: 'Managed Identity' }, { value: 'workloadidentity', label: 'Workload Identity' }, + { value: 'currentuser', label: 'User Identity' }, ]; export const MicrosoftInputsEditor = (props: DataSourcePluginOptionsEditorProps) => { const { options, onOptionsChange } = props; const { secureJsonFields } = options; const secureJsonData = (options.secureJsonData || {}) as InfinitySecureOptions; - let oauth2: OAuth2Props = options?.jsonData?.oauth2 || {}; let microsoft: MicrosoftProps = options?.jsonData?.microsoft || {}; const onMicrosoftPropsChange = (key: T, value: V) => { onOptionsChange({ ...options, jsonData: { ...options.jsonData, microsoft: { ...microsoft, [key]: value } } }); }; - const onOAuth2PropsChange = (key: T, value: V) => { - onOptionsChange({ ...options, jsonData: { ...options.jsonData, oauth2: { ...oauth2, [key]: value } } }); - }; const onResetClientSecret = () => { onOptionsChange({ ...options, - secureJsonFields: { ...options.secureJsonFields, oauth2ClientSecret: false }, - secureJsonData: { ...options.secureJsonData, oauth2ClientSecret: '' }, + secureJsonFields: { ...options.secureJsonFields, microsoftClientSecret: false }, + secureJsonData: { ...options.secureJsonData, microsoftClientSecret: '' }, }); }; return ( @@ -55,11 +51,28 @@ export const MicrosoftInputsEditor = (props: DataSourcePluginOptionsEditorProps< isClearable={false} menuShouldPortal={true}>
- Tenant ID - onMicrosoftPropsChange('tenant_id', v.currentTarget.value)} value={microsoft.tenant_id} width={60} placeholder={'Tenant ID'} /> -
-
- + + {`Managed Identity, Workload Identity and User Identity requires ambient credentials. `} + {`An Grafana admin has to explicit opt-in via `} + grafana.ini + {` to allow the authentication methods.`} +
+
+ {`For more information, please refer to the `} + Grafana documentation. +
+
+ {`Additionally, this plugin needs to be added to the grafana.ini setting `} + azure.forward_settings_to_plugins. +
+                    [azure]
+                    {`\nforward_settings_to_plugins = grafana-azure-monitor-datasource, prometheus, grafana-azure-data-explorer-datasource, mssql, yesoreyeram-infinity-datasource`}
+                    
+ + } + {...{interactive: true }}> Authentication Type
@@ -67,10 +80,20 @@ export const MicrosoftInputsEditor = (props: DataSourcePluginOptionsEditorProps< onChange={(v) => onMicrosoftPropsChange('auth_type', v)} value={microsoft.auth_type || 'clientsecret'}>
-
- Client ID - onOAuth2PropsChange('client_id', v.currentTarget.value)} value={oauth2.client_id} width={60} placeholder={'Client ID'} /> -
+ {(microsoft.auth_type === 'clientsecret' || !microsoft?.auth_type) && ( + <> +
+ Tenant ID + onMicrosoftPropsChange('tenant_id', v.currentTarget.value)} value={microsoft.tenant_id} width={60} placeholder={'Tenant ID'} /> +
+ + )} + {(microsoft.auth_type === 'clientsecret' || microsoft.auth_type === 'msi' || !microsoft?.auth_type) && ( +
+ Client ID + onMicrosoftPropsChange('client_id', v.currentTarget.value)} value={microsoft.client_id} width={60} placeholder={'Client ID'} /> +
+ )} {(microsoft.auth_type === 'clientsecret' || !microsoft?.auth_type) && ( <>
@@ -78,12 +101,11 @@ export const MicrosoftInputsEditor = (props: DataSourcePluginOptionsEditorProps< labelWidth={10} inputWidth={60} required - value={secureJsonData.oauth2ClientSecret || ''} - isConfigured={(secureJsonFields && secureJsonFields.oauth2ClientSecret) as boolean} + value={secureJsonData.microsoftClientSecret || ''} + isConfigured={(secureJsonFields && secureJsonFields.microsoftClientSecret) as boolean} onReset={onResetClientSecret} - onChange={onUpdateDatasourceSecureJsonDataOption(props, 'oauth2ClientSecret')} + onChange={onUpdateDatasourceSecureJsonDataOption(props, 'microsoftClientSecret')} label="Client Secret" - tooltip="If empty, the AZURE_CLIENT_SECRET environemnt variables will be used" aria-label="client secret" placeholder="Client secret" /> @@ -107,8 +129,8 @@ export const MicrosoftInputsEditor = (props: DataSourcePluginOptionsEditorProps< {...{interactive: true }} >Scopes onOAuth2PropsChange('scopes', (v.currentTarget.value || '').split(','))} - value={(oauth2.scopes || []).join(',')} + onChange={(v) => onMicrosoftPropsChange('scopes', (v.currentTarget.value || '').split(','))} + value={(microsoft.scopes || []).join(',')} width={60} placeholder={'Comma separated values of scopes'} /> diff --git a/src/types/config.types.ts b/src/types/config.types.ts index 2ed58f5fc..90dc52984 100644 --- a/src/types/config.types.ts +++ b/src/types/config.types.ts @@ -27,11 +27,13 @@ export type AWSAuthProps = { }; export type MicrosoftCloudType = 'AzureCloud' | 'AzureChinaCloud' | 'AzureUSGovernment'; -export type MicrosoftAuthType = 'clientsecret' | 'msi' | 'workloadidentity'; +export type MicrosoftAuthType = 'clientsecret' | 'msi' | 'workloadidentity' | 'currentuser'; export type MicrosoftProps = { cloud?: MicrosoftCloudType; auth_type?: MicrosoftAuthType; tenant_id?: string; + client_id?: string; + scopes?: string[]; }; export type InfinityReferenceData = { name: string; data: string }; export type ProxyType = 'none' | 'env' | 'url'; @@ -70,6 +72,7 @@ export interface InfinitySecureOptions { awsAccessKey?: string; awsSecretKey?: string; oauth2ClientSecret?: string; + microsoftClientSecret?: string; oauth2JWTPrivateKey?: string; azureBlobAccountKey?: string; } From 7c5873fbb549c44c7705da47383839d49df6cd5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Mon, 20 May 2024 15:25:58 +0200 Subject: [PATCH 04/10] fix: error strings must not capitalised MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan-Otto Kröpke --- pkg/infinity/client.go | 5 +-- pkg/infinity/{azure.go => microsoft.go} | 19 ++++++------ pkg/models/settings.go | 41 +++++++++++++------------ 3 files changed, 34 insertions(+), 31 deletions(-) rename pkg/infinity/{azure.go => microsoft.go} (82%) diff --git a/pkg/infinity/client.go b/pkg/infinity/client.go index c40b35361..90f856574 100644 --- a/pkg/infinity/client.go +++ b/pkg/infinity/client.go @@ -16,12 +16,13 @@ import ( "time" "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob" - "github.com/grafana/grafana-infinity-datasource/pkg/models" "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend/proxy" "github.com/grafana/grafana-plugin-sdk-go/backend/tracing" "github.com/icholy/digest" "golang.org/x/oauth2" + + "github.com/grafana/grafana-infinity-datasource/pkg/models" ) type Client struct { @@ -106,7 +107,7 @@ func NewClient(ctx context.Context, settings models.InfinitySettings) (client *C httpClient = ApplyOAuthClientCredentials(ctx, httpClient, settings) httpClient = ApplyOAuthJWT(ctx, httpClient, settings) httpClient = ApplyAWSAuth(ctx, httpClient, settings) - httpClient, err = ApplyAzureAuth(ctx, httpClient, settings) + httpClient, err = ApplyMicrosoftAuth(ctx, httpClient, settings) if err != nil { return nil, err } diff --git a/pkg/infinity/azure.go b/pkg/infinity/microsoft.go similarity index 82% rename from pkg/infinity/azure.go rename to pkg/infinity/microsoft.go index 302cec516..7354b972a 100644 --- a/pkg/infinity/azure.go +++ b/pkg/infinity/microsoft.go @@ -9,13 +9,14 @@ import ( "github.com/grafana/grafana-azure-sdk-go/azcredentials" "github.com/grafana/grafana-azure-sdk-go/azhttpclient" "github.com/grafana/grafana-azure-sdk-go/azsettings" - "github.com/grafana/grafana-infinity-datasource/pkg/models" "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" "github.com/grafana/grafana-plugin-sdk-go/backend/tracing" + + "github.com/grafana/grafana-infinity-datasource/pkg/models" ) -func ApplyAzureAuth(ctx context.Context, httpClient *http.Client, settings models.InfinitySettings) (*http.Client, error) { - ctx, span := tracing.DefaultTracer().Start(ctx, "ApplyAzureAuth") +func ApplyMicrosoftAuth(ctx context.Context, httpClient *http.Client, settings models.InfinitySettings) (*http.Client, error) { + ctx, span := tracing.DefaultTracer().Start(ctx, "ApplyMicrosoftAuth") defer span.End() if IsAzureAuthConfigured(settings) { @@ -30,15 +31,15 @@ func ApplyAzureAuth(ctx context.Context, httpClient *http.Client, settings model case models.MicrosoftAuthTypeClientSecret: if strings.TrimSpace(settings.MicrosoftSettings.TenantID) == "" { - return nil, fmt.Errorf("Tenant ID %w ", models.MicrosoftRequiredForClientSecretErrHelp) + return nil, fmt.Errorf("tenant id %w ", models.MicrosoftRequiredForClientSecretErrHelp) } if strings.TrimSpace(settings.MicrosoftSettings.ClientID) == "" { - return nil, fmt.Errorf("Client ID %w ", models.MicrosoftRequiredForClientSecretErrHelp) + return nil, fmt.Errorf("client id %w ", models.MicrosoftRequiredForClientSecretErrHelp) } if strings.TrimSpace(settings.MicrosoftSettings.ClientSecret) == "" { - return nil, fmt.Errorf("Client secret %w ", models.MicrosoftRequiredForClientSecretErrHelp) + return nil, fmt.Errorf("client secret %w ", models.MicrosoftRequiredForClientSecretErrHelp) } credentials = &azcredentials.AzureClientSecretCredentials{ @@ -49,7 +50,7 @@ func ApplyAzureAuth(ctx context.Context, httpClient *http.Client, settings model } case models.MicrosoftAuthTypeManagedIdentity: if !azSettings.ManagedIdentityEnabled { - return nil, fmt.Errorf("Managed Identity %w ", models.MicrosoftDisabledAuthErrHelp) + return nil, fmt.Errorf("managed identity %w ", models.MicrosoftDisabledAuthErrHelp) } credentials = &azcredentials.AzureManagedIdentityCredentials{ @@ -59,13 +60,13 @@ func ApplyAzureAuth(ctx context.Context, httpClient *http.Client, settings model } case models.MicrosoftAuthTypeWorkloadIdentity: if !azSettings.WorkloadIdentityEnabled { - return nil, fmt.Errorf("Workload Identity %w ", models.MicrosoftDisabledAuthErrHelp) + return nil, fmt.Errorf("workload identity %w ", models.MicrosoftDisabledAuthErrHelp) } credentials = &azcredentials.AzureWorkloadIdentityCredentials{} case models.MicrosoftAuthTypeCurrentUserIdentity: if !azSettings.UserIdentityEnabled { - return nil, fmt.Errorf("User Identity %w ", models.MicrosoftDisabledAuthErrHelp) + return nil, fmt.Errorf("user identity %w ", models.MicrosoftDisabledAuthErrHelp) } credentials = &azcredentials.AadCurrentUserCredentials{} diff --git a/pkg/models/settings.go b/pkg/models/settings.go index bacb48733..c4677f4ce 100644 --- a/pkg/models/settings.go +++ b/pkg/models/settings.go @@ -253,26 +253,27 @@ type RefData struct { } type InfinitySettingsJson struct { - IsMock bool `json:"is_mock,omitempty"` - AuthenticationMethod string `json:"auth_method,omitempty"` - APIKeyKey string `json:"apiKeyKey,omitempty"` - APIKeyType string `json:"apiKeyType,omitempty"` - OAuth2Settings OAuth2Settings `json:"oauth2,omitempty"` - AWSSettings AWSSettings `json:"aws,omitempty"` - ForwardOauthIdentity bool `json:"oauthPassThru,omitempty"` - InsecureSkipVerify bool `json:"tlsSkipVerify,omitempty"` - ServerName string `json:"serverName,omitempty"` - TLSClientAuth bool `json:"tlsAuth,omitempty"` - TLSAuthWithCACert bool `json:"tlsAuthWithCACert,omitempty"` - TimeoutInSeconds int64 `json:"timeoutInSeconds,omitempty"` - ProxyType ProxyType `json:"proxy_type,omitempty"` - ProxyUrl string `json:"proxy_url,omitempty"` - ReferenceData []RefData `json:"refData,omitempty"` - CustomHealthCheckEnabled bool `json:"customHealthCheckEnabled,omitempty"` - CustomHealthCheckUrl string `json:"customHealthCheckUrl,omitempty"` - AzureBlobAccountUrl string `json:"azureBlobAccountUrl,omitempty"` - AzureBlobAccountName string `json:"azureBlobAccountName,omitempty"` - PathEncodedURLsEnabled bool `json:"pathEncodedUrlsEnabled,omitempty"` + IsMock bool `json:"is_mock,omitempty"` + AuthenticationMethod string `json:"auth_method,omitempty"` + APIKeyKey string `json:"apiKeyKey,omitempty"` + APIKeyType string `json:"apiKeyType,omitempty"` + OAuth2Settings OAuth2Settings `json:"oauth2,omitempty"` + AWSSettings AWSSettings `json:"aws,omitempty"` + MicrosoftSettings MicrosoftSettings `json:"microsoft,omitempty"` + ForwardOauthIdentity bool `json:"oauthPassThru,omitempty"` + InsecureSkipVerify bool `json:"tlsSkipVerify,omitempty"` + ServerName string `json:"serverName,omitempty"` + TLSClientAuth bool `json:"tlsAuth,omitempty"` + TLSAuthWithCACert bool `json:"tlsAuthWithCACert,omitempty"` + TimeoutInSeconds int64 `json:"timeoutInSeconds,omitempty"` + ProxyType ProxyType `json:"proxy_type,omitempty"` + ProxyUrl string `json:"proxy_url,omitempty"` + ReferenceData []RefData `json:"refData,omitempty"` + CustomHealthCheckEnabled bool `json:"customHealthCheckEnabled,omitempty"` + CustomHealthCheckUrl string `json:"customHealthCheckUrl,omitempty"` + AzureBlobAccountUrl string `json:"azureBlobAccountUrl,omitempty"` + AzureBlobAccountName string `json:"azureBlobAccountName,omitempty"` + PathEncodedURLsEnabled bool `json:"pathEncodedUrlsEnabled,omitempty"` // Security AllowedHosts []string `json:"allowedHosts,omitempty"` UnsecuredQueryHandling UnsecuredQueryHandlingMode `json:"unsecuredQueryHandling,omitempty"` From 6cc9e014d4ee6b7a85a53b5edfa0128a6ad1243a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Mon, 20 May 2024 17:12:41 +0200 Subject: [PATCH 05/10] build Grafana Azure SDK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan-Otto Kröpke --- .changeset/serious-badgers-fetch.md | 2 +- docker-compose.yaml | 1 - docs/sources/examples/azure.md | 5 +- go.mod | 76 +++--- go.sum | 236 ++++++------------ pkg/infinity/azure.go | 86 +++++++ pkg/infinity/client.go | 6 +- pkg/infinity/microsoft.go | 88 ------- pkg/models/settings.go | 138 +++------- pkg/models/settings_test.go | 17 +- src/editors/config/Auth.tsx | 8 +- .../{MicrosoftInput.tsx => AzureInput.tsx} | 57 +++-- src/types/config.types.ts | 24 +- 13 files changed, 294 insertions(+), 450 deletions(-) create mode 100644 pkg/infinity/azure.go delete mode 100644 pkg/infinity/microsoft.go rename src/editors/config/{MicrosoftInput.tsx => AzureInput.tsx} (65%) diff --git a/.changeset/serious-badgers-fetch.md b/.changeset/serious-badgers-fetch.md index 3eb73f5de..b45a1e922 100644 --- a/.changeset/serious-badgers-fetch.md +++ b/.changeset/serious-badgers-fetch.md @@ -2,4 +2,4 @@ 'grafana-infinity-datasource': minor --- -Add native Microsoft authentication +Add native Azure authentication diff --git a/docker-compose.yaml b/docker-compose.yaml index 6ede3cc35..cc9eccb28 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -24,4 +24,3 @@ services: - GF_ENTERPRISE_LICENSE_TEXT=$GF_ENTERPRISE_LICENSE_TEXT - GF_AZURE_FORWARD_SETTINGS_TO_PLUGINS= - GF_AZURE_WORKLOAD_IDENTITY_ENABLED=true - - GF_AZURE_USER_IDENTITY_ENABLED=true diff --git a/docs/sources/examples/azure.md b/docs/sources/examples/azure.md index af0f162d2..35d127abb 100644 --- a/docs/sources/examples/azure.md +++ b/docs/sources/examples/azure.md @@ -31,13 +31,12 @@ Here are the detailed steps on how to connect Microsoft Azure APIs 3. Note down the Client ID, Client Secret and Tenant ID 4. Give reader/monitoring reader access to the resources/subscriptions as necessary 5. Install the infinity plugin in Grafana and add data source for the same - 1. Expand Authentication section and select "Microsoft Entra ID" + 1. Expand Authentication section and select "Azure" 2. Select "Client Credentials" as Auth type 3. Specify the Client ID 4. Specify the Client Secret 5. Specify the Tenant ID - 6. Add the Scope `https://management.azure.com/.default`. - 7. If you are using Infinity 1.0.0+, then also specify `https://management.azure.com/` as an allowed URL. + 6. If you are using Infinity 1.0.0+, then also specify `https://management.azure.com/` as an allowed URL. 6. Click Save and Test. 7. Click the `Explore` button 8. Configure the query diff --git a/go.mod b/go.mod index b428e164c..3af93b7a8 100644 --- a/go.mod +++ b/go.mod @@ -5,8 +5,8 @@ go 1.22 require ( github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.1 github.com/grafana/grafana-aws-sdk v0.24.0 - github.com/grafana/grafana-azure-sdk-go v1.13.0 - github.com/grafana/grafana-plugin-sdk-go v0.225.0 + github.com/grafana/grafana-azure-sdk-go/v2 v2.0.4 + github.com/grafana/grafana-plugin-sdk-go v0.230.0 github.com/icholy/digest v0.1.22 github.com/stretchr/testify v1.9.0 github.com/yesoreyeram/grafana-plugins/lib/go/csvframer v0.0.2 @@ -15,9 +15,9 @@ require ( github.com/yesoreyeram/grafana-plugins/lib/go/macros v0.1.0 github.com/yesoreyeram/grafana-plugins/lib/go/transformations v0.0.1 github.com/yesoreyeram/grafana-plugins/lib/go/xmlframer v0.0.6 - go.opentelemetry.io/otel v1.24.0 - go.opentelemetry.io/otel/trace v1.24.0 - golang.org/x/oauth2 v0.18.0 + go.opentelemetry.io/otel v1.26.0 + go.opentelemetry.io/otel/trace v1.26.0 + golang.org/x/oauth2 v0.20.0 moul.io/http2curl v1.0.0 ) @@ -32,35 +32,35 @@ require ( github.com/aws/aws-sdk-go v1.44.323 // indirect github.com/basgys/goxml2json v1.1.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cenkalti/backoff/v4 v4.2.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cheekybits/genny v1.0.0 // indirect github.com/chromedp/cdproto v0.0.0-20231126232103-8e31ff06e23b // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5 // indirect github.com/fatih/color v1.16.0 // indirect - github.com/getkin/kin-openapi v0.121.0 // indirect + github.com/getkin/kin-openapi v0.124.0 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.20.0 // indirect - github.com/go-openapi/swag v0.22.4 // indirect + github.com/go-openapi/jsonpointer v0.20.2 // indirect + github.com/go-openapi/swag v0.22.8 // indirect github.com/go-sql-driver/mysql v1.7.1 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/goccy/go-yaml v1.11.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt/v5 v5.2.0 // indirect + github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/flatbuffers v23.5.26+incompatible // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/gorilla/mux v1.8.0 // indirect + github.com/gorilla/mux v1.8.1 // indirect github.com/grafana/dataplane/sdata v0.0.7 // indirect github.com/grafana/sqlds/v3 v3.2.0 // indirect - github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect - github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-plugin v1.6.0 // indirect github.com/hashicorp/yamux v0.1.1 // indirect @@ -106,10 +106,10 @@ require ( github.com/pierrec/lz4/v4 v4.1.18 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.18.0 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.46.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/client_golang v1.19.0 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.53.0 // indirect + github.com/prometheus/procfs v0.14.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect @@ -122,34 +122,32 @@ require ( github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8 // indirect github.com/unknwon/com v1.0.1 // indirect github.com/unknwon/log v0.0.0-20200308114134-929b1006e34a // indirect - github.com/urfave/cli v1.22.14 // indirect + github.com/urfave/cli v1.22.15 // indirect github.com/xiatechs/jsonata-go v1.8.0 // indirect github.com/yesoreyeram/grafana-plugins/lib/go/framesql v0.0.1 // indirect github.com/yesoreyeram/grafana-plugins/lib/go/utils v0.0.1 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.49.0 // indirect - go.opentelemetry.io/contrib/propagators/jaeger v1.22.0 // indirect - go.opentelemetry.io/contrib/samplers/jaegerremote v0.18.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 // indirect - go.opentelemetry.io/otel/metric v1.24.0 // indirect - go.opentelemetry.io/otel/sdk v1.24.0 // indirect - go.opentelemetry.io/proto/otlp v1.1.0 // indirect - golang.org/x/crypto v0.21.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.51.0 // indirect + go.opentelemetry.io/contrib/propagators/jaeger v1.26.0 // indirect + go.opentelemetry.io/contrib/samplers/jaegerremote v0.20.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 // indirect + go.opentelemetry.io/otel/metric v1.26.0 // indirect + go.opentelemetry.io/otel/sdk v1.26.0 // indirect + go.opentelemetry.io/proto/otlp v1.2.0 // indirect + golang.org/x/crypto v0.22.0 // indirect golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/term v0.19.0 // indirect + golang.org/x/text v0.15.0 // indirect golang.org/x/tools v0.16.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.14.0 // indirect - google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect google.golang.org/grpc v1.63.2 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/Knetic/govaluate.v3 v3.0.0 // indirect diff --git a/go.sum b/go.sum index 9135d5d9d..78248a1e0 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,3 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0 h1:n1DH8TPV4qqPTje2RcUBYwtrTWlabVp4n46+74X2pn4= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0/go.mod h1:HDcZnuGbiyppErN6lB+idp4CKhjbc8gwjto6OPpyggM= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 h1:sO0/P7g68FrryJzljemN+6GTssUXdANk6aJ7T1ZxnsQ= @@ -22,28 +21,23 @@ github.com/aws/aws-sdk-go v1.44.323 h1:97/dn93DWrN1VfhAWQ2tV+xuE6oO/LO9rSsEsuC4P github.com/aws/aws-sdk-go v1.44.323/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/basgys/goxml2json v1.1.0 h1:4ln5i4rseYfXNd86lGEB+Vi652IsIXIvggKM/BhUKVw= github.com/basgys/goxml2json v1.1.0/go.mod h1:wH7a5Np/Q4QoECFIU8zTQlZwZkrilY0itPfecMw41Dw= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bitly/go-simplejson v0.5.1 h1:xgwPbetQScXt1gh9BmoJ6j9JMr3TElvuIyjR8pgdoow= github.com/bitly/go-simplejson v0.5.1/go.mod h1:YOPVLzCfwK14b4Sff3oP1AmGhI9T9Vsg84etUnlyp+Q= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= -github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= -github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/chromedp/cdproto v0.0.0-20231126232103-8e31ff06e23b h1:SywfM3985mh0PaXhiZbgR+VQFSfFXJSNLX2p+3vBvOc= github.com/chromedp/cdproto v0.0.0-20231126232103-8e31ff06e23b/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -56,10 +50,6 @@ github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5/go.mod h1:Ro8st/El github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= github.com/elazarl/goproxy/ext v0.0.0-20220115173737-adb46da277ac h1:9yrT5tmn9Zc0ytWPASlaPwQfQMQYnRf0RSDe1XvHw0Q= github.com/elazarl/goproxy/ext v0.0.0-20220115173737-adb46da277ac/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= @@ -69,19 +59,17 @@ github.com/frankban/quicktest v1.7.2 h1:2QxQoC1TS09S7fhCPsrvqYdvP1H5M1P1ih5ABm3B github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/getkin/kin-openapi v0.121.0 h1:KbQmTugy+lQF+ed5H3tikjT4prqx5+KCLAq4U81Hkcw= -github.com/getkin/kin-openapi v0.121.0/go.mod h1:PCWw/lfBrJY4HcdqE3jj+QFkaFK8ABoqo7PvqVhXXqw= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/getkin/kin-openapi v0.124.0 h1:VSFNMB9C9rTKBnQ/fpyDU8ytMTr4dWI9QovSKj9kz/M= +github.com/getkin/kin-openapi v0.124.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/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-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= -github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= -github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= -github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= +github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= +github.com/go-openapi/swag v0.22.8 h1:/9RjDSQ0vbFR+NyjGMkFTsA1IA0fmhKSThmfGZjicbw= +github.com/go-openapi/swag v0.22.8/go.mod h1:6QT22icPLEqAM/z/TChgb4WAveCHF92+2gF0CNjHpPI= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= @@ -90,7 +78,6 @@ github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7a github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= @@ -99,22 +86,13 @@ github.com/goccy/go-yaml v1.11.2 h1:joq77SxuyIs9zzxEjgyLBugMQ9NEgTWxXfz2wVqwAaQ= github.com/goccy/go-yaml v1.11.2/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= -github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/flatbuffers v23.5.26+incompatible h1:M9dgRyhJemaM4Sw8+66GHBu8ioaQmyPLg1b8VwK5WJg= github.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -125,24 +103,24 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/grafana/dataplane/sdata v0.0.7 h1:CImITypIyS1jxijCR6xqKx71JnYAxcwpH9ChK0gH164= github.com/grafana/dataplane/sdata v0.0.7/go.mod h1:Jvs5ddpGmn6vcxT7tCTWAZ1mgi4sbcdFt9utQx5uMAU= github.com/grafana/grafana-aws-sdk v0.24.0 h1:0RKCJTeIkpEUvLCTjGOK1+jYZpaE2nJaGghGLvtUsFs= github.com/grafana/grafana-aws-sdk v0.24.0/go.mod h1:3zghFF6edrxn0d6k6X9HpGZXDH+VfA+MwD2Pc/9X0ec= -github.com/grafana/grafana-azure-sdk-go v1.13.0 h1:2II2kXyHsBOCWkSQBYXrhhzuZpAn+viaesz3y+AyOSM= -github.com/grafana/grafana-azure-sdk-go v1.13.0/go.mod h1:SAlwLdEuox4vw8ZaeQwnepYXnhznnQQdstJbcw8LH68= -github.com/grafana/grafana-plugin-sdk-go v0.225.0 h1:m+mVt/MttHUmPFVTsOsAdYh5z+140Zkh1YIweDovr8Y= -github.com/grafana/grafana-plugin-sdk-go v0.225.0/go.mod h1:lpIXBVypJnOO2lAxkilRCan5zhTotPuDxMLmUMd9DAM= +github.com/grafana/grafana-azure-sdk-go/v2 v2.0.4 h1:z6amQ286IJSBctHf6c+ibJq/v0+TvmEjVkrdMNBd4uY= +github.com/grafana/grafana-azure-sdk-go/v2 v2.0.4/go.mod h1:aKlFPE36IDa8qccRg3KbgZX3MQ5xymS3RelT4j6kkVU= +github.com/grafana/grafana-plugin-sdk-go v0.230.0 h1:Y4IL+eT1jXqTCctlNzdCvxAozpBZ8xEsRGWjGAVRXxo= +github.com/grafana/grafana-plugin-sdk-go v0.230.0/go.mod h1:6V6ikT4ryva8MrAp7Bdz5fTJx3/ztzKvpMJFfpzr4CI= github.com/grafana/sqlds/v3 v3.2.0 h1:WXuYEaFfiCvgm8kK2ixx44/zAEjFzCylA2+RF3GBqZA= github.com/grafana/sqlds/v3 v3.2.0/go.mod h1:kH0WuHUR3j0Q7IEymbm2JiaPckUhRCbqjV9ajaBAnmM= -github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= -github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpSQwGEnkcRpTqNOIR6bJbR0gAorgP9CSALpRcKoAA= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A= @@ -185,12 +163,8 @@ github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4s github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= @@ -255,7 +229,6 @@ github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= @@ -269,15 +242,14 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= -github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= -github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y= -github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= +github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= +github.com/prometheus/procfs v0.14.0 h1:Lw4VdGGoKEZilJsayHf0B+9YgLGREba2C6xr+Fdfq6s= +github.com/prometheus/procfs v0.14.0/go.mod h1:XL+Iwz8k8ZabyZfMFHPiilCniixqQarAy5Mu67pHlNQ= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -285,8 +257,8 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -294,7 +266,6 @@ github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7 github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= @@ -303,14 +274,11 @@ github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hg github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= @@ -337,8 +305,8 @@ github.com/unknwon/log v0.0.0-20150304194804-e617c87089d3/go.mod h1:1xEUf2abjfP9 github.com/unknwon/log v0.0.0-20200308114134-929b1006e34a h1:vcrhXnj9g9PIE+cmZgaPSwOyJ8MAQTRmsgGrB0x5rF4= github.com/unknwon/log v0.0.0-20200308114134-929b1006e34a/go.mod h1:1xEUf2abjfP92w2GZTV+GgaRxXErwRXcClbUwrNJffU= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= -github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= +github.com/urfave/cli v1.22.15 h1:nuqt+pdC/KqswQKhETJjo7pvn/k4xMUxgW6liI7XpnM= +github.com/urfave/cli v1.22.15/go.mod h1:wSan1hmo5zeyLGBjRJbzRTNk8gwoYa2B9n4q9dmRIc0= github.com/xiatechs/jsonata-go v1.8.0 h1:RZxM16WXwcSLvmmgG57zlpGAHuXMp8oLUjrO+wUBtSA= github.com/xiatechs/jsonata-go v1.8.0/go.mod h1:qc/5uRtTKE5mil6PncK/ogxFQyhqlI6YnxvdyAz57Xw= github.com/yesoreyeram/grafana-plugins/lib/go/csvframer v0.0.2 h1:bRIge6sn+clMoDhZg0txsupbjNnX9huXsXqSmjuRxpI= @@ -364,58 +332,46 @@ github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= -go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.49.0 h1:RtcvQ4iw3w9NBB5yRwgA4sSa82rfId7n4atVpvKx3bY= -go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.49.0/go.mod h1:f/PbKbRd4cdUICWell6DmzvVJ7QrmBgFrRHjXmAXbK4= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= -go.opentelemetry.io/contrib/propagators/jaeger v1.22.0 h1:bAHX+zN/inu+Rbqk51REmC8oXLl+Dw6pp9ldQf/onaY= -go.opentelemetry.io/contrib/propagators/jaeger v1.22.0/go.mod h1:bH9GkgkN21mscXcQP6lQJYI8XnEPDxlTN/ZOBuHDjqE= -go.opentelemetry.io/contrib/samplers/jaegerremote v0.18.0 h1:Q9PrD94WoMolBx44ef5UWWvufpVSME0MiSymXZfedso= -go.opentelemetry.io/contrib/samplers/jaegerremote v0.18.0/go.mod h1:tjp49JHNvreAAoWjdCHIVD7NXMjuJ3Dp/9iNOuPPlC8= -go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= -go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 h1:t6wl9SPayj+c7lEIFgm4ooDBZVb01IhLB4InpomhRw8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0/go.mod h1:iSDOcsnSA5INXzZtwaBPrKp/lWu/V14Dd+llD0oI2EA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 h1:Mw5xcxMwlqoJd97vwPxA8isEaIoxsta9/Q51+TTJLGE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0/go.mod h1:CQNu9bj7o7mC6U7+CA/schKEYakYXWr79ucDHTMGhCM= -go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= -go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= -go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw= -go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= -go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= -go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= -go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI= -go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 h1:A3SayB3rNyt+1S6qpI9mHPkeHTZbD7XILEqWnYZb2l0= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0/go.mod h1:27iA5uvhuRNmalO+iEUdVn5ZMj2qy10Mm+XRIpRmyuU= +go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.51.0 h1:974XTyIwHI4nHa1+uSLxHtUnlJ2DiVtAJjk7fd07p/8= +go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.51.0/go.mod h1:ZvX/taFlN6TGaOOM6D42wrNwPKUV1nGO2FuUXkityBU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 h1:Xs2Ncz0gNihqu9iosIZ5SkBbWo5T8JhhLJFMQL1qmLI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc= +go.opentelemetry.io/contrib/propagators/jaeger v1.26.0 h1:RH76Cl2pfOLLoCtxAPax9c7oYzuL1tiI7/ZPJEmEmOw= +go.opentelemetry.io/contrib/propagators/jaeger v1.26.0/go.mod h1:W/cylm0ZtJK1uxsuTqoYGYPnqpZ8CeVGgW7TwfXPsGw= +go.opentelemetry.io/contrib/samplers/jaegerremote v0.20.0 h1:ja+d7Aea/9PgGxB63+E0jtRFpma717wubS0KFkZpmYw= +go.opentelemetry.io/contrib/samplers/jaegerremote v0.20.0/go.mod h1:Yc1eg51SJy7xZdOTyg1xyFcwE+ghcWh3/0hKeLo6Wlo= +go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= +go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 h1:1u/AyyOqAWzy+SkPxDpahCNZParHV8Vid1RnI2clyDE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0/go.mod h1:z46paqbJ9l7c9fIPCXTqTGwhQZ5XoTIsfeFYWboizjs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 h1:Waw9Wfpo/IXzOI8bCB7DIk+0JZcqqsyn1JFnAc+iam8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0/go.mod h1:wnJIG4fOqyynOnnQF/eQb4/16VlX2EJAHhHgqIqWfAo= +go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30= +go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4= +go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8= +go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs= +go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA= +go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= +go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= +go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -425,23 +381,18 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= -golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= +golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191020152052-9984515f0562/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -453,7 +404,6 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211004093028-2c5d950f24ef/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -461,30 +411,24 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -499,34 +443,17 @@ golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSm golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= -google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= -google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0= -google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be h1:Zz7rLWqp0ApfsR/l7+zSHhY3PMiH2xqgxlfYfAfNpoU= +google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be/go.mod h1:dvdCTIoAGbkWbcIKBniID56/7XHTt6WfxXNMxuziJ+w= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be h1:LG9vZxsWGOmUKieR8wPAUR3u3MpnYFQZROPIMaXh7/A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/Knetic/govaluate.v3 v3.0.0 h1:18mUyIt4ZlRlFZAAfVetz4/rzlJs9yhN+U02F4u1AOc= gopkg.in/Knetic/govaluate.v3 v3.0.0/go.mod h1:csKLBORsPbafmSCGTEh3U7Ozmsuq8ZSIlKk1bcqph0E= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify/fsnotify.v1 v1.4.7 h1:XNNYLJHt73EyYiCZi6+xjupS9CpvmiDgjPTAjrBlQbo= @@ -536,14 +463,11 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo= lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q= diff --git a/pkg/infinity/azure.go b/pkg/infinity/azure.go new file mode 100644 index 000000000..cd185c902 --- /dev/null +++ b/pkg/infinity/azure.go @@ -0,0 +1,86 @@ +package infinity + +import ( + "context" + "fmt" + "github.com/grafana/grafana-azure-sdk-go/v2/azcredentials" + "github.com/grafana/grafana-azure-sdk-go/v2/azhttpclient" + "github.com/grafana/grafana-azure-sdk-go/v2/azsettings" + "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" + "github.com/grafana/grafana-plugin-sdk-go/backend/tracing" + "github.com/grafana/grafana-plugin-sdk-go/data/utils/maputil" + "net/http" + + "github.com/grafana/grafana-infinity-datasource/pkg/models" +) + +func ApplyAzureAuth(ctx context.Context, httpClient *http.Client, settings models.InfinitySettings) (*http.Client, error) { + ctx, span := tracing.DefaultTracer().Start(ctx, "ApplyAzureAuth") + defer span.End() + + if !IsAzureAuthConfigured(settings) { + return httpClient, nil + } + + credentialsObj, err := maputil.GetMapOptional(settings.RawData, "azureCredentials") + if err != nil { + return nil, err + } else if credentialsObj == nil { + return httpClient, nil + } + + azSettings, err := azsettings.ReadFromEnv() + if err != nil { + return nil, err + } + + // set authType if not set + // this can happen if the user manually provisions the datasource without setting the authType + if credentialsObj["authType"] == nil || credentialsObj["authType"] == "" { + credentialsObj["authType"] = azcredentials.AzureAuthClientSecret + } + + // set azureCloud if not set + // this can happen if the user manually provisions the datasource without setting the azureCloud + if credentialsObj["azureCloud"] == nil || credentialsObj["azureCloud"] == "" { + credentialsObj["azureCloud"] = azSettings.GetDefaultCloud() + } + + azCredentials, err := azcredentials.FromDatasourceData(settings.RawData, settings.RawSecureData) + if err != nil { + return nil, err + } + + authOpts := azhttpclient.NewAuthOptions(azSettings) + + // set scopes + if scopes, ok := credentialsObj["scopes"].([]any); ok { + stringScopes, err := toStringSlice(scopes) + if err != nil { + return nil, err + } + + authOpts.Scopes(stringScopes) + } + + httpClient.Transport = azhttpclient.AzureMiddleware(authOpts, azCredentials). + CreateMiddleware(httpclient.Options{}, httpClient.Transport) + + return httpClient, nil +} + +func IsAzureAuthConfigured(settings models.InfinitySettings) bool { + return settings.AuthenticationMethod == models.AuthenticationMethodAzure +} + +func toStringSlice(arr []any) ([]string, error) { + result := make([]string, len(arr)) + for i, v := range arr { + if s, ok := v.(string); ok { + result[i] = s + } else { + return nil, fmt.Errorf("expected string, got %T", v) + } + } + return result, nil +} diff --git a/pkg/infinity/client.go b/pkg/infinity/client.go index 90f856574..bc1fefe58 100644 --- a/pkg/infinity/client.go +++ b/pkg/infinity/client.go @@ -16,13 +16,12 @@ import ( "time" "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob" + "github.com/grafana/grafana-infinity-datasource/pkg/models" "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend/proxy" "github.com/grafana/grafana-plugin-sdk-go/backend/tracing" "github.com/icholy/digest" "golang.org/x/oauth2" - - "github.com/grafana/grafana-infinity-datasource/pkg/models" ) type Client struct { @@ -107,7 +106,7 @@ func NewClient(ctx context.Context, settings models.InfinitySettings) (client *C httpClient = ApplyOAuthClientCredentials(ctx, httpClient, settings) httpClient = ApplyOAuthJWT(ctx, httpClient, settings) httpClient = ApplyAWSAuth(ctx, httpClient, settings) - httpClient, err = ApplyMicrosoftAuth(ctx, httpClient, settings) + httpClient, err = ApplyAzureAuth(ctx, httpClient, settings) if err != nil { return nil, err } @@ -178,7 +177,6 @@ func ApplySecureSocksProxyConfiguration(httpClient *http.Client, settings models backend.Logger.Error("error configuring secure socks proxy", "err", err.Error()) return nil, fmt.Errorf("error configuring secure socks proxy. %s", err) } - return httpClient, nil } diff --git a/pkg/infinity/microsoft.go b/pkg/infinity/microsoft.go deleted file mode 100644 index 7354b972a..000000000 --- a/pkg/infinity/microsoft.go +++ /dev/null @@ -1,88 +0,0 @@ -package infinity - -import ( - "context" - "fmt" - "net/http" - "strings" - - "github.com/grafana/grafana-azure-sdk-go/azcredentials" - "github.com/grafana/grafana-azure-sdk-go/azhttpclient" - "github.com/grafana/grafana-azure-sdk-go/azsettings" - "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" - "github.com/grafana/grafana-plugin-sdk-go/backend/tracing" - - "github.com/grafana/grafana-infinity-datasource/pkg/models" -) - -func ApplyMicrosoftAuth(ctx context.Context, httpClient *http.Client, settings models.InfinitySettings) (*http.Client, error) { - ctx, span := tracing.DefaultTracer().Start(ctx, "ApplyMicrosoftAuth") - defer span.End() - - if IsAzureAuthConfigured(settings) { - azSettings, err := azsettings.ReadFromEnv() - if err != nil { - return nil, err - } - - var credentials azcredentials.AzureCredentials - - switch settings.MicrosoftSettings.AuthType { - case models.MicrosoftAuthTypeClientSecret: - - if strings.TrimSpace(settings.MicrosoftSettings.TenantID) == "" { - return nil, fmt.Errorf("tenant id %w ", models.MicrosoftRequiredForClientSecretErrHelp) - } - - if strings.TrimSpace(settings.MicrosoftSettings.ClientID) == "" { - return nil, fmt.Errorf("client id %w ", models.MicrosoftRequiredForClientSecretErrHelp) - } - - if strings.TrimSpace(settings.MicrosoftSettings.ClientSecret) == "" { - return nil, fmt.Errorf("client secret %w ", models.MicrosoftRequiredForClientSecretErrHelp) - } - - credentials = &azcredentials.AzureClientSecretCredentials{ - AzureCloud: string(settings.MicrosoftSettings.Cloud), - TenantId: settings.MicrosoftSettings.TenantID, - ClientId: settings.MicrosoftSettings.ClientID, - ClientSecret: settings.MicrosoftSettings.ClientSecret, - } - case models.MicrosoftAuthTypeManagedIdentity: - if !azSettings.ManagedIdentityEnabled { - return nil, fmt.Errorf("managed identity %w ", models.MicrosoftDisabledAuthErrHelp) - } - - credentials = &azcredentials.AzureManagedIdentityCredentials{ - // ClientId is optional for managed identity, because it can be inferred from the environment - // https://github.com/grafana/grafana-azure-sdk-go/blob/21e2891b4190eb7c255c8cd275836def8200faf8/aztokenprovider/retriever_msi.go#L20-L30 - ClientId: settings.MicrosoftSettings.ClientID, - } - case models.MicrosoftAuthTypeWorkloadIdentity: - if !azSettings.WorkloadIdentityEnabled { - return nil, fmt.Errorf("workload identity %w ", models.MicrosoftDisabledAuthErrHelp) - } - - credentials = &azcredentials.AzureWorkloadIdentityCredentials{} - case models.MicrosoftAuthTypeCurrentUserIdentity: - if !azSettings.UserIdentityEnabled { - return nil, fmt.Errorf("user identity %w ", models.MicrosoftDisabledAuthErrHelp) - } - - credentials = &azcredentials.AadCurrentUserCredentials{} - default: - panic(fmt.Errorf("invalid auth type '%s'", settings.MicrosoftSettings.AuthType)) - } - - authOpts := azhttpclient.NewAuthOptions(azSettings) - authOpts.Scopes(settings.MicrosoftSettings.Scopes) - - httpClient.Transport = azhttpclient.AzureMiddleware(authOpts, credentials). - CreateMiddleware(httpclient.Options{}, httpClient.Transport) - } - return httpClient, nil -} - -func IsAzureAuthConfigured(settings models.InfinitySettings) bool { - return settings.AuthenticationMethod == models.AuthenticationMethodMicrosoft -} diff --git a/pkg/models/settings.go b/pkg/models/settings.go index c4677f4ce..7bcaef797 100644 --- a/pkg/models/settings.go +++ b/pkg/models/settings.go @@ -8,8 +8,8 @@ import ( "net/textproto" "strings" - "github.com/grafana/grafana-azure-sdk-go/azcredentials" - "github.com/grafana/grafana-azure-sdk-go/azsettings" + "github.com/grafana/grafana-azure-sdk-go/v2/azcredentials" + "github.com/grafana/grafana-azure-sdk-go/v2/azsettings" "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" "golang.org/x/oauth2" @@ -24,7 +24,7 @@ const ( AuthenticationMethodDigestAuth = "digestAuth" AuthenticationMethodOAuth = "oauth2" AuthenticationMethodAWS = "aws" - AuthenticationMethodMicrosoft = "microsoft" + AuthenticationMethodAzure = "azure" AuthenticationMethodAzureBlob = "azureBlob" ) @@ -65,39 +65,6 @@ type AWSSettings struct { Service string `json:"service"` } -type MicrosoftAuthType string - -const ( - MicrosoftAuthTypeManagedIdentity MicrosoftAuthType = azcredentials.AzureAuthManagedIdentity - MicrosoftAuthTypeWorkloadIdentity MicrosoftAuthType = azcredentials.AzureAuthWorkloadIdentity - MicrosoftAuthTypeClientSecret MicrosoftAuthType = azcredentials.AzureAuthClientSecret - MicrosoftAuthTypeCurrentUserIdentity MicrosoftAuthType = azcredentials.AzureAuthCurrentUserIdentity -) - -type MicrosoftCloudType string - -const ( - MicrosoftCloudPublic MicrosoftCloudType = azsettings.AzurePublic - MicrosoftCloudChina MicrosoftCloudType = azsettings.AzureChina - MicrosoftCloudUSGovernment MicrosoftCloudType = azsettings.AzureUSGovernment -) - -var ( - MicrosoftRequiredForClientSecretErrHelp = errors.New(` is required for Microsoft client secret authentication`) - MicrosoftDisabledAuthErrHelp = errors.New(` is not enabled in the Grafana Azure settings. For more information, please refer to the Grafana documentation at -https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#azure. -Additionally, this plugin needs to be added to the grafana.ini setting azure.forward_settings_to_plugins.`) -) - -type MicrosoftSettings struct { - Cloud MicrosoftCloudType `json:"cloud"` - AuthType MicrosoftAuthType `json:"auth_type"` - TenantID string `json:"tenant_id"` - ClientID string `json:"client_id"` - ClientSecret string - Scopes []string `json:"scopes,omitempty"` -} - type ProxyType string const ( @@ -127,7 +94,6 @@ type InfinitySettings struct { AWSSettings AWSSettings AWSAccessKey string AWSSecretKey string - MicrosoftSettings MicrosoftSettings URL string BasicAuthEnabled bool UserName string @@ -156,6 +122,9 @@ type InfinitySettings struct { PathEncodedURLsEnabled bool // ProxyOpts is used for Secure Socks Proxy configuration ProxyOpts httpclient.Options + + RawData map[string]interface{} + RawSecureData map[string]string } func (s *InfinitySettings) Validate() error { @@ -186,40 +155,15 @@ func (s *InfinitySettings) Validate() error { } return nil } - if s.AuthenticationMethod == AuthenticationMethodMicrosoft { - azSettings, err := azsettings.ReadFromEnv() + if s.AuthenticationMethod == AuthenticationMethodAzure { + _, err := azsettings.ReadFromEnv() if err != nil { return err } - switch s.MicrosoftSettings.AuthType { - case MicrosoftAuthTypeClientSecret: - if strings.TrimSpace(s.MicrosoftSettings.TenantID) == "" { - return fmt.Errorf("Tenant ID %w ", MicrosoftRequiredForClientSecretErrHelp) - } - - if strings.TrimSpace(s.MicrosoftSettings.ClientID) == "" { - return fmt.Errorf("Client ID %w ", MicrosoftRequiredForClientSecretErrHelp) - } - - if strings.TrimSpace(s.MicrosoftSettings.ClientSecret) == "" { - return fmt.Errorf("Client secret %w ", MicrosoftRequiredForClientSecretErrHelp) - } - case MicrosoftAuthTypeManagedIdentity: - if !azSettings.ManagedIdentityEnabled { - return errors.New("managed identity authentication is not enabled in Grafana config. " + - "Refer https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#azure") - } - case MicrosoftAuthTypeWorkloadIdentity: - if !azSettings.WorkloadIdentityEnabled { - return errors.New("workload identity authentication is not enabled in Grafana config." + - "Refer https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#azure") - } - case MicrosoftAuthTypeCurrentUserIdentity: - if !azSettings.UserIdentityEnabled { - return errors.New("user identity authentication is not enabled in Grafana config." + - "Refer https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#azure") - } + _, err = azcredentials.FromDatasourceData(s.RawData, s.RawSecureData) + if err != nil { + return err } } if s.AuthenticationMethod != AuthenticationMethodNone && len(s.AllowedHosts) < 1 { @@ -253,27 +197,26 @@ type RefData struct { } type InfinitySettingsJson struct { - IsMock bool `json:"is_mock,omitempty"` - AuthenticationMethod string `json:"auth_method,omitempty"` - APIKeyKey string `json:"apiKeyKey,omitempty"` - APIKeyType string `json:"apiKeyType,omitempty"` - OAuth2Settings OAuth2Settings `json:"oauth2,omitempty"` - AWSSettings AWSSettings `json:"aws,omitempty"` - MicrosoftSettings MicrosoftSettings `json:"microsoft,omitempty"` - ForwardOauthIdentity bool `json:"oauthPassThru,omitempty"` - InsecureSkipVerify bool `json:"tlsSkipVerify,omitempty"` - ServerName string `json:"serverName,omitempty"` - TLSClientAuth bool `json:"tlsAuth,omitempty"` - TLSAuthWithCACert bool `json:"tlsAuthWithCACert,omitempty"` - TimeoutInSeconds int64 `json:"timeoutInSeconds,omitempty"` - ProxyType ProxyType `json:"proxy_type,omitempty"` - ProxyUrl string `json:"proxy_url,omitempty"` - ReferenceData []RefData `json:"refData,omitempty"` - CustomHealthCheckEnabled bool `json:"customHealthCheckEnabled,omitempty"` - CustomHealthCheckUrl string `json:"customHealthCheckUrl,omitempty"` - AzureBlobAccountUrl string `json:"azureBlobAccountUrl,omitempty"` - AzureBlobAccountName string `json:"azureBlobAccountName,omitempty"` - PathEncodedURLsEnabled bool `json:"pathEncodedUrlsEnabled,omitempty"` + IsMock bool `json:"is_mock,omitempty"` + AuthenticationMethod string `json:"auth_method,omitempty"` + APIKeyKey string `json:"apiKeyKey,omitempty"` + APIKeyType string `json:"apiKeyType,omitempty"` + OAuth2Settings OAuth2Settings `json:"oauth2,omitempty"` + AWSSettings AWSSettings `json:"aws,omitempty"` + ForwardOauthIdentity bool `json:"oauthPassThru,omitempty"` + InsecureSkipVerify bool `json:"tlsSkipVerify,omitempty"` + ServerName string `json:"serverName,omitempty"` + TLSClientAuth bool `json:"tlsAuth,omitempty"` + TLSAuthWithCACert bool `json:"tlsAuthWithCACert,omitempty"` + TimeoutInSeconds int64 `json:"timeoutInSeconds,omitempty"` + ProxyType ProxyType `json:"proxy_type,omitempty"` + ProxyUrl string `json:"proxy_url,omitempty"` + ReferenceData []RefData `json:"refData,omitempty"` + CustomHealthCheckEnabled bool `json:"customHealthCheckEnabled,omitempty"` + CustomHealthCheckUrl string `json:"customHealthCheckUrl,omitempty"` + AzureBlobAccountUrl string `json:"azureBlobAccountUrl,omitempty"` + AzureBlobAccountName string `json:"azureBlobAccountName,omitempty"` + PathEncodedURLsEnabled bool `json:"pathEncodedUrlsEnabled,omitempty"` // Security AllowedHosts []string `json:"allowedHosts,omitempty"` UnsecuredQueryHandling UnsecuredQueryHandlingMode `json:"unsecuredQueryHandling,omitempty"` @@ -331,15 +274,14 @@ func LoadSettings(ctx context.Context, config backend.DataSourceInstanceSettings settings.AllowedHosts = infJson.AllowedHosts } - settings.MicrosoftSettings = infJson.MicrosoftSettings - if settings.AuthenticationMethod == "microsoft" { - if settings.MicrosoftSettings.AuthType == "" { - settings.MicrosoftSettings.AuthType = "clientsecret" - } - if settings.MicrosoftSettings.Cloud == "" { - settings.MicrosoftSettings.Cloud = MicrosoftCloudPublic - } + var rawData map[string]interface{} + + if err := json.Unmarshal(config.JSONData, &rawData); err != nil { + return settings, err } + + settings.RawData = rawData + settings.RawSecureData = config.DecryptedSecureJSONData } settings.ReferenceData = infJson.ReferenceData settings.CustomHealthCheckEnabled = infJson.CustomHealthCheckEnabled @@ -376,9 +318,7 @@ func LoadSettings(ctx context.Context, config backend.DataSourceInstanceSettings if val, ok := config.DecryptedSecureJSONData["azureBlobAccountKey"]; ok { settings.AzureBlobAccountKey = val } - if val, ok := config.DecryptedSecureJSONData["microsoftClientSecret"]; ok { - settings.MicrosoftSettings.ClientSecret = val - } + settings.CustomHeaders = GetSecrets(config, "httpHeaderName", "httpHeaderValue") settings.SecureQueryFields = GetSecrets(config, "secureQueryName", "secureQueryValue") settings.OAuth2Settings.EndpointParams = GetSecrets(config, "oauth2EndPointParamsName", "oauth2EndPointParamsValue") diff --git a/pkg/models/settings_test.go b/pkg/models/settings_test.go index 4761fc861..c2055a863 100644 --- a/pkg/models/settings_test.go +++ b/pkg/models/settings_test.go @@ -163,13 +163,6 @@ func TestAllSettingsAgainstFrontEnd(t *testing.T) { "region" : "region1", "service" : "service1" }, - "microsoft" : { - "cloud" : "AzureUSGovernment", - "auth_type" : "clientsecret", - "tenant_id" : "tenant1", - "client_id" : "myMicrosoftClientID", - "scopes" : ["msscope1","msscope2"] - }, "oauth2" : { "client_id":"myClientID", "email":"myEmail", @@ -191,7 +184,7 @@ func TestAllSettingsAgainstFrontEnd(t *testing.T) { "awsAccessKey": "awsAccessKey1", "awsSecretKey": "awsSecretKey1", "oauth2ClientSecret": "myOauth2ClientSecret", - "microsoftClientSecret": "myMicrosoftClientSecret", + "azureClientSecret": "myMicrosoftClientSecret", "oauth2JWTPrivateKey": "myOauth2JWTPrivateKey", "oauth2EndPointParamsValue1": "Resource1", "oauth2EndPointParamsValue2": "Resource2", @@ -223,14 +216,6 @@ func TestAllSettingsAgainstFrontEnd(t *testing.T) { Service: "service1", Region: "region1", }, - MicrosoftSettings: models.MicrosoftSettings{ - Cloud: models.MicrosoftCloudUSGovernment, - AuthType: models.MicrosoftAuthTypeClientSecret, - TenantID: "tenant1", - ClientID: "myMicrosoftClientID", - ClientSecret: "myMicrosoftClientSecret", - Scopes: []string{"msscope1", "msscope2"}, - }, OAuth2Settings: models.OAuth2Settings{ ClientID: "myClientID", OAuth2Type: "client_credentials", diff --git a/src/editors/config/Auth.tsx b/src/editors/config/Auth.tsx index fc8bc1759..1aecbb76c 100644 --- a/src/editors/config/Auth.tsx +++ b/src/editors/config/Auth.tsx @@ -4,7 +4,7 @@ import { Icon, InlineFormLabel, LegacyForms, RadioButtonGroup, Select, useTheme2 import React, { useState } from 'react'; import { AllowedHostsEditor } from './AllowedHosts'; import { OAuthInputsEditor } from './OAuthInput'; -import { MicrosoftInputsEditor } from './MicrosoftInput'; +import { AzureInputsEditor } from './AzureInput'; import { OthersAuthentication } from './OtherAuthProviders'; import { AWSRegions } from './../../constants'; import type { APIKeyType, AuthType, InfinityOptions, InfinitySecureOptions } from './../../types'; @@ -18,7 +18,7 @@ const authTypes: Array & { logo?: string }> { value: 'oauthPassThru', label: 'Forward OAuth' }, { value: 'oauth2', label: 'OAuth2', logo: '/public/plugins/yesoreyeram-infinity-datasource/img/oauth-2-sm.png' }, { value: 'aws', label: 'AWS', logo: '/public/plugins/yesoreyeram-infinity-datasource/img/aws.jpg' }, - { value: 'microsoft', label: 'Microsoft Entra ID', logo: '/public/img/microsoft_auth_icon.svg' }, + { value: 'azure', label: 'Azure', logo: '/public/img/microsoft_auth_icon.svg' }, { value: 'azureBlob', label: 'Azure Blob' }, { value: 'others', label: 'Other Auth Providers' }, ]; @@ -78,7 +78,7 @@ export const AuthEditor = (props: DataSourcePluginOptionsEditorProps )} {authType === 'oauth2' && } - {authType === 'microsoft' && } + {authType === 'azure' && } {authType === 'azureBlob' && ( <>
diff --git a/src/editors/config/MicrosoftInput.tsx b/src/editors/config/AzureInput.tsx similarity index 65% rename from src/editors/config/MicrosoftInput.tsx rename to src/editors/config/AzureInput.tsx index 2cb313f96..ac0b7f4e9 100644 --- a/src/editors/config/MicrosoftInput.tsx +++ b/src/editors/config/AzureInput.tsx @@ -4,38 +4,37 @@ import React from 'react'; import type { InfinityOptions, InfinitySecureOptions, - MicrosoftAuthType, MicrosoftCloudType, - MicrosoftProps + AzureAuthType, AzureCloudType, + AzureProps } from './../../types'; -const microsoftCloudTypes: Array> = [ +const azureCloudTypes: Array> = [ { value: 'AzureCloud', label: 'Azure' }, { value: 'AzureUSGovernment', label: 'Azure US Government' }, { value: 'AzureChinaCloud', label: 'Azure China Cloud' }, ]; -const microsoftAuthTypes: Array> = [ +const azureAuthTypes: Array> = [ { value: 'clientsecret', label: 'Client Secret' }, { value: 'msi', label: 'Managed Identity' }, { value: 'workloadidentity', label: 'Workload Identity' }, - { value: 'currentuser', label: 'User Identity' }, ]; -export const MicrosoftInputsEditor = (props: DataSourcePluginOptionsEditorProps) => { +export const AzureInputsEditor = (props: DataSourcePluginOptionsEditorProps) => { const { options, onOptionsChange } = props; const { secureJsonFields } = options; const secureJsonData = (options.secureJsonData || {}) as InfinitySecureOptions; - let microsoft: MicrosoftProps = options?.jsonData?.microsoft || {}; + let azure: AzureProps = options?.jsonData?.azureCredentials || {}; - const onMicrosoftPropsChange = (key: T, value: V) => { - onOptionsChange({ ...options, jsonData: { ...options.jsonData, microsoft: { ...microsoft, [key]: value } } }); + const onAzurePropsChange = (key: T, value: V) => { + onOptionsChange({ ...options, jsonData: { ...options.jsonData, azureCredentials: { ...azure, [key]: value } } }); }; const onResetClientSecret = () => { onOptionsChange({ ...options, - secureJsonFields: { ...options.secureJsonFields, microsoftClientSecret: false }, - secureJsonData: { ...options.secureJsonData, microsoftClientSecret: '' }, + secureJsonFields: { ...options.secureJsonFields, azureClientSecret: false }, + secureJsonData: { ...options.secureJsonData, azureClientSecret: '' }, }); }; return ( @@ -44,17 +43,17 @@ export const MicrosoftInputsEditor = (props: DataSourcePluginOptionsEditorProps< Cloud -
- {`Managed Identity, Workload Identity and User Identity requires ambient credentials. `} + {`Managed Identity, Workload Identity requires ambient credentials. `} {`An Grafana admin has to explicit opt-in via `} grafana.ini {` to allow the authentication methods.`} @@ -75,36 +74,36 @@ export const MicrosoftInputsEditor = (props: DataSourcePluginOptionsEditorProps< {...{interactive: true }}> Authentication Type - - options={microsoftAuthTypes} - onChange={(v) => onMicrosoftPropsChange('auth_type', v)} - value={microsoft.auth_type || 'clientsecret'}> + + options={azureAuthTypes} + onChange={(v) => onAzurePropsChange('authType', v)} + value={azure.authType || 'clientsecret'}>
- {(microsoft.auth_type === 'clientsecret' || !microsoft?.auth_type) && ( + {(azure.authType !== 'msi' || !azure?.authType) && ( <>
Tenant ID - onMicrosoftPropsChange('tenant_id', v.currentTarget.value)} value={microsoft.tenant_id} width={60} placeholder={'Tenant ID'} /> + onAzurePropsChange('tenantId', v.currentTarget.value)} value={azure.tenantId} width={60} placeholder={'Tenant ID'} />
)} - {(microsoft.auth_type === 'clientsecret' || microsoft.auth_type === 'msi' || !microsoft?.auth_type) && ( + {(azure.authType !== 'msi' || !azure?.authType) && (
Client ID - onMicrosoftPropsChange('client_id', v.currentTarget.value)} value={microsoft.client_id} width={60} placeholder={'Client ID'} /> + onAzurePropsChange('clientId', v.currentTarget.value)} value={azure.clientId} width={60} placeholder={'Client ID'} />
)} - {(microsoft.auth_type === 'clientsecret' || !microsoft?.auth_type) && ( + {(azure.authType === 'clientsecret' || !azure?.authType) && ( <>
Scopes onMicrosoftPropsChange('scopes', (v.currentTarget.value || '').split(','))} - value={(microsoft.scopes || []).join(',')} + onChange={(v) => onAzurePropsChange('scopes', (v.currentTarget.value || '').split(','))} + value={(azure.scopes || []).join(',')} width={60} placeholder={'Comma separated values of scopes'} /> diff --git a/src/types/config.types.ts b/src/types/config.types.ts index a6202621f..6f135e4cf 100644 --- a/src/types/config.types.ts +++ b/src/types/config.types.ts @@ -7,7 +7,7 @@ export interface GlobalInfinityQuery { id: string; query: InfinityQuery; } -export type AuthType = 'none' | 'basicAuth' | 'apiKey' | 'bearerToken' | 'oauthPassThru' | 'digestAuth' | 'aws' | 'azureBlob' | 'oauth2' | 'microsoft'; +export type AuthType = 'none' | 'basicAuth' | 'apiKey' | 'bearerToken' | 'oauthPassThru' | 'digestAuth' | 'aws' | 'azureBlob' | 'oauth2' | 'azure'; export type OAuth2Type = 'client_credentials' | 'jwt' | 'others'; export type APIKeyType = 'header' | 'query'; export type OAuth2Props = { @@ -26,13 +26,15 @@ export type AWSAuthProps = { service?: string; }; -export type MicrosoftCloudType = 'AzureCloud' | 'AzureChinaCloud' | 'AzureUSGovernment'; -export type MicrosoftAuthType = 'clientsecret' | 'msi' | 'workloadidentity' | 'currentuser'; -export type MicrosoftProps = { - cloud?: MicrosoftCloudType; - auth_type?: MicrosoftAuthType; - tenant_id?: string; - client_id?: string; +export type AzureCloudType = 'AzureCloud' | 'AzureChinaCloud' | 'AzureUSGovernment'; +export type AzureAuthType = 'clientsecret' | 'msi' | 'workloadidentity'; + +// the keys are used to align with the Grafana Azure SDK +export type AzureProps = { + azureCloud?: AzureCloudType; + authType?: AzureAuthType; + tenantId?: string; + clientId?: string; scopes?: string[]; }; export type InfinityReferenceData = { name: string; data: string }; @@ -44,7 +46,8 @@ export interface InfinityOptions extends DataSourceJsonData { apiKeyType?: APIKeyType; oauth2?: OAuth2Props; aws?: AWSAuthProps; - microsoft?: MicrosoftProps; + // azureCredentials is used to align with the Grafana Azure SDK + azureCredentials?: AzureProps; tlsSkipVerify?: boolean; tlsAuth?: boolean; serverName?: string; @@ -75,7 +78,8 @@ export interface InfinitySecureOptions { awsAccessKey?: string; awsSecretKey?: string; oauth2ClientSecret?: string; - microsoftClientSecret?: string; + // azureClientSecret is used to align with the Grafana Azure SDK + azureClientSecret?: string; oauth2JWTPrivateKey?: string; azureBlobAccountKey?: string; } From c717b144c112a51f71c741ae8f347117df5738ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Tue, 25 Jun 2024 20:56:47 +0200 Subject: [PATCH 06/10] fix mr conflicts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan-Otto Kröpke --- go.mod | 6 ++++++ go.sum | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index f805bbe17..cf013eb12 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.22 require ( github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.1 github.com/grafana/grafana-aws-sdk v0.24.0 + github.com/grafana/grafana-azure-sdk-go/v2 v2.0.4 github.com/grafana/grafana-plugin-sdk-go v0.231.0 github.com/icholy/digest v0.1.22 github.com/stretchr/testify v1.9.0 @@ -22,7 +23,9 @@ require ( require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 // indirect github.com/BurntSushi/toml v1.3.2 // indirect github.com/apache/arrow/go/v15 v15.0.2 // indirect github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de // indirect @@ -47,6 +50,7 @@ require ( github.com/goccy/go-json v0.10.3 // indirect github.com/goccy/go-yaml v1.11.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/flatbuffers v24.3.25+incompatible // indirect github.com/google/go-cmp v0.6.0 // indirect @@ -72,6 +76,7 @@ require ( github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/klauspost/compress v1.17.8 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect github.com/lib/pq v1.10.9 // indirect github.com/magefile/mage v1.15.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect @@ -99,6 +104,7 @@ require ( github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pierrec/lz4 v2.6.1+incompatible // indirect github.com/pierrec/lz4/v4 v4.1.21 // indirect + github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect diff --git a/go.sum b/go.sum index 563dfef1a..da904f4a5 100644 --- a/go.sum +++ b/go.sum @@ -87,8 +87,8 @@ github.com/goccy/go-yaml v1.11.2 h1:joq77SxuyIs9zzxEjgyLBugMQ9NEgTWxXfz2wVqwAaQ= github.com/goccy/go-yaml v1.11.2/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= -github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/flatbuffers v24.3.25+incompatible h1:CX395cjN9Kke9mmalRoL3d81AtFUxJM+yDthflgJGkI= @@ -110,6 +110,8 @@ github.com/grafana/dataplane/sdata v0.0.7 h1:CImITypIyS1jxijCR6xqKx71JnYAxcwpH9C github.com/grafana/dataplane/sdata v0.0.7/go.mod h1:Jvs5ddpGmn6vcxT7tCTWAZ1mgi4sbcdFt9utQx5uMAU= github.com/grafana/grafana-aws-sdk v0.24.0 h1:0RKCJTeIkpEUvLCTjGOK1+jYZpaE2nJaGghGLvtUsFs= github.com/grafana/grafana-aws-sdk v0.24.0/go.mod h1:3zghFF6edrxn0d6k6X9HpGZXDH+VfA+MwD2Pc/9X0ec= +github.com/grafana/grafana-azure-sdk-go/v2 v2.0.4 h1:z6amQ286IJSBctHf6c+ibJq/v0+TvmEjVkrdMNBd4uY= +github.com/grafana/grafana-azure-sdk-go/v2 v2.0.4/go.mod h1:aKlFPE36IDa8qccRg3KbgZX3MQ5xymS3RelT4j6kkVU= github.com/grafana/grafana-plugin-sdk-go v0.231.0 h1:Qt4PBDR8b4MTUxL48EaZw1fHI1rXUNNhvTU/Nf0Ex2g= github.com/grafana/grafana-plugin-sdk-go v0.231.0/go.mod h1:8fJk+5J1hMkpqY/7vrXHKgAsqELWNkQvLQ5A5xCVZHk= github.com/grafana/sqlds/v3 v3.2.0 h1:WXuYEaFfiCvgm8kK2ixx44/zAEjFzCylA2+RF3GBqZA= From 4f30d6d538ff199551b6f2e3f2297ada69a485da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Sun, 7 Jul 2024 00:17:09 +0200 Subject: [PATCH 07/10] fix cspell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan-Otto Kröpke --- cspell.config.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cspell.config.json b/cspell.config.json index 74f99f076..dedce7b12 100644 --- a/cspell.config.json +++ b/cspell.config.json @@ -26,6 +26,9 @@ "words": [ "ANSIC", "azblob", + "azcredentials", + "azhttpclient", + "azsettings", "basgys", "Bauch", "bigpanda", @@ -33,6 +36,7 @@ "builtins", "Chelsey", "clientcredentials", + "clientsecret", "clsx", "cmdk", "Collapsable", @@ -84,6 +88,7 @@ "lucide", "magefile", "mainbg", + "maputil", "maxif", "microsocks", "Milli", @@ -169,6 +174,7 @@ "visualisation", "vlookup", "vuepress", + "workloadidentity", "xinsnake", "xmlframer", "yesoreyeram", From f700aeebd0aa8ffef3f8e2cb4a26da81cc0ab9c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Tue, 16 Jul 2024 16:12:33 +0200 Subject: [PATCH 08/10] fix lint + go mod tidy. --- go.mod | 1 - go.sum | 2 -- pkg/infinity/azure.go | 5 +++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 9b761b129..f2e203c79 100644 --- a/go.mod +++ b/go.mod @@ -73,7 +73,6 @@ require ( github.com/klauspost/compress v1.17.8 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/kylelemons/godebug v1.1.0 // indirect - github.com/lib/pq v1.10.9 // indirect github.com/magefile/mage v1.15.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattetti/filebuffer v1.0.1 // indirect diff --git a/go.sum b/go.sum index 545b16b9a..f47956e74 100644 --- a/go.sum +++ b/go.sum @@ -99,8 +99,6 @@ github.com/grafana/grafana-aws-sdk v0.24.0 h1:0RKCJTeIkpEUvLCTjGOK1+jYZpaE2nJaGg github.com/grafana/grafana-aws-sdk v0.24.0/go.mod h1:3zghFF6edrxn0d6k6X9HpGZXDH+VfA+MwD2Pc/9X0ec= github.com/grafana/grafana-azure-sdk-go/v2 v2.0.4 h1:z6amQ286IJSBctHf6c+ibJq/v0+TvmEjVkrdMNBd4uY= github.com/grafana/grafana-azure-sdk-go/v2 v2.0.4/go.mod h1:aKlFPE36IDa8qccRg3KbgZX3MQ5xymS3RelT4j6kkVU= -github.com/grafana/grafana-plugin-sdk-go v0.239.0 h1:q/AWw+3HlgoXRnXkZuHxxSP7ujyCRRl8YIfWDW3KOAg= -github.com/grafana/grafana-plugin-sdk-go v0.239.0/go.mod h1:GTw4Fgs9rFe0bR8zmqaTqnVEcQx+Rk5fJvWULyzigCM= github.com/grafana/grafana-plugin-sdk-go v0.240.0 h1:jhv2TqfBWoi5ZTksg/fdY5Mi8FDsaE8XGxjS1Rgi6nk= github.com/grafana/grafana-plugin-sdk-go v0.240.0/go.mod h1:GTw4Fgs9rFe0bR8zmqaTqnVEcQx+Rk5fJvWULyzigCM= github.com/grafana/infinity-libs/lib/go/csvframer v1.0.0 h1:PGM6BkwU1You9zFShVTtNvQcnQDabJ4jg9TLhqAdC/k= diff --git a/pkg/infinity/azure.go b/pkg/infinity/azure.go index cd185c902..0ccab9f13 100644 --- a/pkg/infinity/azure.go +++ b/pkg/infinity/azure.go @@ -3,19 +3,20 @@ package infinity import ( "context" "fmt" + "net/http" + "github.com/grafana/grafana-azure-sdk-go/v2/azcredentials" "github.com/grafana/grafana-azure-sdk-go/v2/azhttpclient" "github.com/grafana/grafana-azure-sdk-go/v2/azsettings" "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" "github.com/grafana/grafana-plugin-sdk-go/backend/tracing" "github.com/grafana/grafana-plugin-sdk-go/data/utils/maputil" - "net/http" "github.com/grafana/grafana-infinity-datasource/pkg/models" ) func ApplyAzureAuth(ctx context.Context, httpClient *http.Client, settings models.InfinitySettings) (*http.Client, error) { - ctx, span := tracing.DefaultTracer().Start(ctx, "ApplyAzureAuth") + _, span := tracing.DefaultTracer().Start(ctx, "ApplyAzureAuth") defer span.End() if !IsAzureAuthConfigured(settings) { From 533956e1338b1f439340b4c53e338eada7150b8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Wed, 17 Jul 2024 00:06:30 +0200 Subject: [PATCH 09/10] fix lint + go mod tidy. --- go.mod | 2 +- go.sum | 2 + pkg/models/settings_test.go | 78 +++++++++++++++++++++++++++++++++++++ src/types/config.types.ts | 2 - 4 files changed, 81 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f2e203c79..75b8b0f4f 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.22.1 require ( github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.1 github.com/grafana/grafana-aws-sdk v0.24.0 - github.com/grafana/grafana-azure-sdk-go/v2 v2.0.4 + github.com/grafana/grafana-azure-sdk-go/v2 v2.1.0 github.com/grafana/grafana-plugin-sdk-go v0.240.0 github.com/grafana/infinity-libs/lib/go/csvframer v1.0.0 github.com/grafana/infinity-libs/lib/go/gframer v1.0.0 diff --git a/go.sum b/go.sum index f47956e74..cd2911d9b 100644 --- a/go.sum +++ b/go.sum @@ -99,6 +99,8 @@ github.com/grafana/grafana-aws-sdk v0.24.0 h1:0RKCJTeIkpEUvLCTjGOK1+jYZpaE2nJaGg github.com/grafana/grafana-aws-sdk v0.24.0/go.mod h1:3zghFF6edrxn0d6k6X9HpGZXDH+VfA+MwD2Pc/9X0ec= github.com/grafana/grafana-azure-sdk-go/v2 v2.0.4 h1:z6amQ286IJSBctHf6c+ibJq/v0+TvmEjVkrdMNBd4uY= github.com/grafana/grafana-azure-sdk-go/v2 v2.0.4/go.mod h1:aKlFPE36IDa8qccRg3KbgZX3MQ5xymS3RelT4j6kkVU= +github.com/grafana/grafana-azure-sdk-go/v2 v2.1.0 h1:lajVqTWaE96MpbjZToj7EshvqgRWOfYNkD4MbIZizaY= +github.com/grafana/grafana-azure-sdk-go/v2 v2.1.0/go.mod h1:aKlFPE36IDa8qccRg3KbgZX3MQ5xymS3RelT4j6kkVU= github.com/grafana/grafana-plugin-sdk-go v0.240.0 h1:jhv2TqfBWoi5ZTksg/fdY5Mi8FDsaE8XGxjS1Rgi6nk= github.com/grafana/grafana-plugin-sdk-go v0.240.0/go.mod h1:GTw4Fgs9rFe0bR8zmqaTqnVEcQx+Rk5fJvWULyzigCM= github.com/grafana/infinity-libs/lib/go/csvframer v1.0.0 h1:PGM6BkwU1You9zFShVTtNvQcnQDabJ4jg9TLhqAdC/k= diff --git a/pkg/models/settings_test.go b/pkg/models/settings_test.go index c2055a863..ea4795090 100644 --- a/pkg/models/settings_test.go +++ b/pkg/models/settings_test.go @@ -72,6 +72,16 @@ func TestLoadSettings(t *testing.T) { SecureQueryFields: map[string]string{ "foo": "bar", }, + RawData: map[string]interface{}{ + "datasource_mode": "advanced", + "httpHeaderName1": "header1", + "secureQueryName1": "foo", + }, + RawSecureData: map[string]string{ + "basicAuthPassword": "password", + "httpHeaderValue1": "headervalue1", + "secureQueryValue1": "bar", + }, }, }, { @@ -111,6 +121,17 @@ func TestLoadSettings(t *testing.T) { SecureQueryFields: map[string]string{ "foo": "bar", }, + RawData: map[string]interface{}{ + "datasource_mode": "advanced", + "httpHeaderName1": "header1", + "secureQueryName1": "foo", + "timeoutInSeconds": float64(30), + }, + RawSecureData: map[string]string{ + "basicAuthPassword": "password", + "httpHeaderValue1": "headervalue1", + "secureQueryValue1": "bar", + }, }, }, } @@ -251,6 +272,63 @@ func TestAllSettingsAgainstFrontEnd(t *testing.T) { SecureQueryFields: map[string]string{ "foo": "bar", }, + RawData: map[string]interface{}{ + "allowedHosts": []interface{}{ + "host1", + "host2", + }, + "apiKeyKey": "hello", + "apiKeyType": "query", + "auth_method": "oauth2", + "aws": map[string]interface{}{ + "authType": "keys", + "region": "region1", + "service": "service1", + }, + "customHealthCheckEnabled": true, + "customHealthCheckUrl": "https://foo-check/", + "datasource_mode": "advanced", + "httpHeaderName1": "header1", + "oauth2": map[string]interface{}{ + "client_id": "myClientID", + "email": "myEmail", + "private_key_id": "saturn", + "scopes": []interface{}{ + "scope1", + "scope2", + }, + "subject": "mySubject", + "token_url": "TOKEN_URL", + }, + "oauth2EndPointParamsName1": "resource", + "oauth2EndPointParamsName2": "name", + "oauthPassThru": true, + "proxy_type": "url", + "proxy_url": "https://foo.com", + "secureQueryName1": "foo", + "timeoutInSeconds": float64(30), + "tlsAuth": true, + "tlsAuthWithCACert": true, + "tlsSkipVerify": true, + "unsecuredQueryHandling": "deny", + }, + RawSecureData: map[string]string{ + "apiKeyValue": "earth", + "awsAccessKey": "awsAccessKey1", + "awsSecretKey": "awsSecretKey1", + "azureClientSecret": "myMicrosoftClientSecret", + "basicAuthPassword": "password", + "bearerToken": "myBearerToken", + "httpHeaderValue1": "headervalue1", + "oauth2ClientSecret": "myOauth2ClientSecret", + "oauth2EndPointParamsValue1": "Resource1", + "oauth2EndPointParamsValue2": "Resource2", + "oauth2JWTPrivateKey": "myOauth2JWTPrivateKey", + "secureQueryValue1": "bar", + "tlsCACert": "myTlsCACert", + "tlsClientCert": "myTlsClientCert", + "tlsClientKey": "myTlsClientKey", + }, }, gotSettings) } diff --git a/src/types/config.types.ts b/src/types/config.types.ts index 6f135e4cf..ba6dba46f 100644 --- a/src/types/config.types.ts +++ b/src/types/config.types.ts @@ -46,7 +46,6 @@ export interface InfinityOptions extends DataSourceJsonData { apiKeyType?: APIKeyType; oauth2?: OAuth2Props; aws?: AWSAuthProps; - // azureCredentials is used to align with the Grafana Azure SDK azureCredentials?: AzureProps; tlsSkipVerify?: boolean; tlsAuth?: boolean; @@ -78,7 +77,6 @@ export interface InfinitySecureOptions { awsAccessKey?: string; awsSecretKey?: string; oauth2ClientSecret?: string; - // azureClientSecret is used to align with the Grafana Azure SDK azureClientSecret?: string; oauth2JWTPrivateKey?: string; azureBlobAccountKey?: string; From bbd39830721046c9e8fe2babc1f5d21c0309ba46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Sun, 28 Jul 2024 08:31:18 +0200 Subject: [PATCH 10/10] build Grafana Azure SDK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan-Otto Kröpke --- go.mod | 1 + go.sum | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 391f0db5e..472c19a60 100644 --- a/go.mod +++ b/go.mod @@ -72,6 +72,7 @@ require ( github.com/jszwedko/go-datemath v0.1.1-0.20230526204004-640a500621d6 // indirect github.com/klauspost/compress v1.17.9 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect github.com/magefile/mage v1.15.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattetti/filebuffer v1.0.1 // indirect diff --git a/go.sum b/go.sum index 946245570..13d9ede19 100644 --- a/go.sum +++ b/go.sum @@ -97,12 +97,10 @@ github.com/grafana/dataplane/sdata v0.0.7 h1:CImITypIyS1jxijCR6xqKx71JnYAxcwpH9C github.com/grafana/dataplane/sdata v0.0.7/go.mod h1:Jvs5ddpGmn6vcxT7tCTWAZ1mgi4sbcdFt9utQx5uMAU= github.com/grafana/grafana-aws-sdk v0.24.0 h1:0RKCJTeIkpEUvLCTjGOK1+jYZpaE2nJaGghGLvtUsFs= github.com/grafana/grafana-aws-sdk v0.24.0/go.mod h1:3zghFF6edrxn0d6k6X9HpGZXDH+VfA+MwD2Pc/9X0ec= -github.com/grafana/grafana-azure-sdk-go/v2 v2.0.4 h1:z6amQ286IJSBctHf6c+ibJq/v0+TvmEjVkrdMNBd4uY= -github.com/grafana/grafana-azure-sdk-go/v2 v2.0.4/go.mod h1:aKlFPE36IDa8qccRg3KbgZX3MQ5xymS3RelT4j6kkVU= github.com/grafana/grafana-azure-sdk-go/v2 v2.1.0 h1:lajVqTWaE96MpbjZToj7EshvqgRWOfYNkD4MbIZizaY= github.com/grafana/grafana-azure-sdk-go/v2 v2.1.0/go.mod h1:aKlFPE36IDa8qccRg3KbgZX3MQ5xymS3RelT4j6kkVU= -github.com/grafana/grafana-plugin-sdk-go v0.240.0 h1:jhv2TqfBWoi5ZTksg/fdY5Mi8FDsaE8XGxjS1Rgi6nk= -github.com/grafana/grafana-plugin-sdk-go v0.240.0/go.mod h1:GTw4Fgs9rFe0bR8zmqaTqnVEcQx+Rk5fJvWULyzigCM= +github.com/grafana/grafana-plugin-sdk-go v0.241.0 h1:zBcSW9xV9gA9hD8UN+HjJtD7tESMZcaQhA1BI76MTxM= +github.com/grafana/grafana-plugin-sdk-go v0.241.0/go.mod h1:2HjNwzGCfaFAyR2HGoECTwAmq8vSIn2L1/1yOt4XRS4= github.com/grafana/infinity-libs/lib/go/csvframer v1.0.0 h1:PGM6BkwU1You9zFShVTtNvQcnQDabJ4jg9TLhqAdC/k= github.com/grafana/infinity-libs/lib/go/csvframer v1.0.0/go.mod h1:aIYewhI82TGS5x4JcvU9qLfmzEtpwoPI7k0fiZv1Wgk= github.com/grafana/infinity-libs/lib/go/framesql v1.0.0 h1:NqmTfpAsp1dQnJy4fbRHZuJUfxqT4tsKNbq+O5LMgEQ=