AzureMonitor: User authentication support (#81918)
* Stub out frontend user auth * Stub out backend user auth * Add context * Reorganise files * Refactor app registration form * Alert for user auth service principal credentials * AzureMonitor: Add flag for enabling/disabling fallback credentials for current user authentication (#82332) * Rename field * Add fallback setting * Update tests and mock * Remove duplicate setting line * Update name of property * Update frontend settings * Update docs and default config files * Update azure-sdk * Fix lint * Update test * Bump dependency * Update configuration * Update docs/sources/setup-grafana/configure-grafana/_index.md Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com> * Docs review * AzureMonitor: User authentication frontend updates (#83107) * Rename field * Add fallback setting * Update tests and mock * Remove duplicate setting line * Update name of property * Update frontend settings * Update docs and default config files * Add alerts to query editor - Add authenticatedBy property to grafana/data - Update mocks - Update query editor to disable it under certain circumstances - Update tests * Add separate FallbackCredentials component - Reset AppRegistrationCredentials component to only handle clientsecret credentials - Update AzureCredentialsForm - Update selectors - Update tests - Update credentials utility functions logic * Alert when fallback credentials disabled * Update condition * Update azure-sdk * Fix lint * Update test * Remove unneeded conditions * Set auth type correctly * Legacy cloud options * Fix client secret * Remove accidental import * Bump dependency * Add tests * Don't use VerticalGroup component * Remove unused import * Fix lint * Appropriately set oAuthPassThru and disableGrafanaCache properties * Clear azureCredentials on authType change * Correctly retrieve secret * Fix bug in authTypeOptions * Update public/app/plugins/datasource/azuremonitor/components/ConfigEditor/CurrentUserFallbackCredentials.tsx Co-authored-by: Andrew Hackmann <5140848+bossinc@users.noreply.github.com> * Update public/app/plugins/datasource/azuremonitor/components/QueryEditor/QueryEditor.tsx Co-authored-by: Andrew Hackmann <5140848+bossinc@users.noreply.github.com> * Update public/app/plugins/datasource/azuremonitor/components/ConfigEditor/CurrentUserFallbackCredentials.tsx Co-authored-by: Andrew Hackmann <5140848+bossinc@users.noreply.github.com> * Add documentation links * Fix broken link --------- Co-authored-by: Andrew Hackmann <5140848+bossinc@users.noreply.github.com> * AzureMonitor: Update docs for current user authentication (#83440) * Rename field * Add fallback setting * Update tests and mock * Remove duplicate setting line * Update name of property * Update frontend settings * Update docs and default config files * Add alerts to query editor - Add authenticatedBy property to grafana/data - Update mocks - Update query editor to disable it under certain circumstances - Update tests * Add separate FallbackCredentials component - Reset AppRegistrationCredentials component to only handle clientsecret credentials - Update AzureCredentialsForm - Update selectors - Update tests - Update credentials utility functions logic * Alert when fallback credentials disabled * Update condition * Update azure-sdk * Fix lint * Update test * Remove unneeded conditions * Set auth type correctly * Legacy cloud options * Fix client secret * Remove accidental import * Bump dependency * Add tests * Don't use VerticalGroup component * Remove unused import * Update docs * Fix lint * Appropriately set oAuthPassThru and disableGrafanaCache properties * Clear azureCredentials on authType change * Correctly retrieve secret * Feedback * Spelling * Update docs/sources/datasources/azure-monitor/_index.md Co-authored-by: Larissa Wandzura <126723338+lwandz13@users.noreply.github.com> * Update docs/sources/datasources/azure-monitor/_index.md Co-authored-by: Larissa Wandzura <126723338+lwandz13@users.noreply.github.com> * Update docs/sources/datasources/azure-monitor/_index.md Co-authored-by: Larissa Wandzura <126723338+lwandz13@users.noreply.github.com> * Update docs/sources/datasources/azure-monitor/_index.md Co-authored-by: Larissa Wandzura <126723338+lwandz13@users.noreply.github.com> --------- Co-authored-by: Larissa Wandzura <126723338+lwandz13@users.noreply.github.com> * Docs review * Update docs with additional configuration information * Fix to appropriately hide the query editor * Typo * Update isCredentialsComplete * Update test --------- Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com> Co-authored-by: Andrew Hackmann <5140848+bossinc@users.noreply.github.com> Co-authored-by: Larissa Wandzura <126723338+lwandz13@users.noreply.github.com>
This commit is contained in:
co-authored by
Larissa Wandzura
Christopher Moyer
Andrew Hackmann
parent
2a6a1fb3b3
commit
6bb7ab261a
@@ -65,10 +65,11 @@ type FrontendSettingsLicenseInfoDTO struct {
|
||||
}
|
||||
|
||||
type FrontendSettingsAzureDTO struct {
|
||||
Cloud string `json:"cloud"`
|
||||
ManagedIdentityEnabled bool `json:"managedIdentityEnabled"`
|
||||
WorkloadIdentityEnabled bool `json:"workloadIdentityEnabled"`
|
||||
UserIdentityEnabled bool `json:"userIdentityEnabled"`
|
||||
Cloud string `json:"cloud"`
|
||||
ManagedIdentityEnabled bool `json:"managedIdentityEnabled"`
|
||||
WorkloadIdentityEnabled bool `json:"workloadIdentityEnabled"`
|
||||
UserIdentityEnabled bool `json:"userIdentityEnabled"`
|
||||
UserIdentityFallbackCredentialsEnabled bool `json:"userIdentityFallbackCredentialsEnabled"`
|
||||
}
|
||||
|
||||
type FrontendSettingsCachingDTO struct {
|
||||
|
||||
@@ -269,10 +269,11 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro
|
||||
SupportBundlesEnabled: isSupportBundlesEnabled(hs),
|
||||
|
||||
Azure: dtos.FrontendSettingsAzureDTO{
|
||||
Cloud: hs.Cfg.Azure.Cloud,
|
||||
ManagedIdentityEnabled: hs.Cfg.Azure.ManagedIdentityEnabled,
|
||||
WorkloadIdentityEnabled: hs.Cfg.Azure.WorkloadIdentityEnabled,
|
||||
UserIdentityEnabled: hs.Cfg.Azure.UserIdentityEnabled,
|
||||
Cloud: hs.Cfg.Azure.Cloud,
|
||||
ManagedIdentityEnabled: hs.Cfg.Azure.ManagedIdentityEnabled,
|
||||
WorkloadIdentityEnabled: hs.Cfg.Azure.WorkloadIdentityEnabled,
|
||||
UserIdentityEnabled: hs.Cfg.Azure.UserIdentityEnabled,
|
||||
UserIdentityFallbackCredentialsEnabled: hs.Cfg.Azure.UserIdentityFallbackCredentialsEnabled,
|
||||
},
|
||||
|
||||
Caching: dtos.FrontendSettingsCachingDTO{
|
||||
|
||||
@@ -101,6 +101,7 @@ func (s *RequestConfigProvider) PluginRequestConfig(ctx context.Context, pluginI
|
||||
|
||||
if azureSettings.UserIdentityEnabled {
|
||||
m[azsettings.UserIdentityEnabled] = "true"
|
||||
m[azsettings.UserIdentityFallbackCredentialsEnabled] = strconv.FormatBool(azureSettings.UserIdentityFallbackCredentialsEnabled)
|
||||
|
||||
if azureSettings.UserIdentityTokenEndpoint != nil {
|
||||
if azureSettings.UserIdentityTokenEndpoint.TokenUrl != "" {
|
||||
|
||||
@@ -276,7 +276,8 @@ func TestRequestConfigProvider_PluginRequestConfig_azure(t *testing.T) {
|
||||
ClientSecret: "mock_user_identity_client_secret",
|
||||
UsernameAssertion: true,
|
||||
},
|
||||
ForwardSettingsPlugins: []string{"grafana-azure-monitor-datasource", "prometheus", "grafana-azure-data-explorer-datasource", "mssql"},
|
||||
UserIdentityFallbackCredentialsEnabled: true,
|
||||
ForwardSettingsPlugins: []string{"grafana-azure-monitor-datasource", "prometheus", "grafana-azure-data-explorer-datasource", "mssql"},
|
||||
}
|
||||
|
||||
t.Run("uses the azure settings for an Azure plugin", func(t *testing.T) {
|
||||
@@ -289,16 +290,17 @@ func TestRequestConfigProvider_PluginRequestConfig_azure(t *testing.T) {
|
||||
p := NewRequestConfigProvider(pCfg)
|
||||
require.Subset(t, p.PluginRequestConfig(context.Background(), "grafana-azure-monitor-datasource"), map[string]string{
|
||||
"GFAZPL_AZURE_CLOUD": "AzureCloud", "GFAZPL_MANAGED_IDENTITY_ENABLED": "true",
|
||||
"GFAZPL_MANAGED_IDENTITY_CLIENT_ID": "mock_managed_identity_client_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_ENABLED": "true",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_TENANT_ID": "mock_workload_identity_tenant_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_CLIENT_ID": "mock_workload_identity_client_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_TOKEN_FILE": "mock_workload_identity_token_file",
|
||||
"GFAZPL_USER_IDENTITY_ENABLED": "true",
|
||||
"GFAZPL_USER_IDENTITY_TOKEN_URL": "mock_user_identity_token_url",
|
||||
"GFAZPL_USER_IDENTITY_CLIENT_ID": "mock_user_identity_client_id",
|
||||
"GFAZPL_USER_IDENTITY_CLIENT_SECRET": "mock_user_identity_client_secret",
|
||||
"GFAZPL_USER_IDENTITY_ASSERTION": "username",
|
||||
"GFAZPL_MANAGED_IDENTITY_CLIENT_ID": "mock_managed_identity_client_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_ENABLED": "true",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_TENANT_ID": "mock_workload_identity_tenant_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_CLIENT_ID": "mock_workload_identity_client_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_TOKEN_FILE": "mock_workload_identity_token_file",
|
||||
"GFAZPL_USER_IDENTITY_ENABLED": "true",
|
||||
"GFAZPL_USER_IDENTITY_FALLBACK_SERVICE_CREDENTIALS_ENABLED": "true",
|
||||
"GFAZPL_USER_IDENTITY_TOKEN_URL": "mock_user_identity_token_url",
|
||||
"GFAZPL_USER_IDENTITY_CLIENT_ID": "mock_user_identity_client_id",
|
||||
"GFAZPL_USER_IDENTITY_CLIENT_SECRET": "mock_user_identity_client_secret",
|
||||
"GFAZPL_USER_IDENTITY_ASSERTION": "username",
|
||||
})
|
||||
})
|
||||
|
||||
@@ -319,6 +321,7 @@ func TestRequestConfigProvider_PluginRequestConfig_azure(t *testing.T) {
|
||||
require.NotContains(t, m, "GFAZPL_WORKLOAD_IDENTITY_CLIENT_ID")
|
||||
require.NotContains(t, m, "GFAZPL_WORKLOAD_IDENTITY_TOKEN_FILE")
|
||||
require.NotContains(t, m, "GFAZPL_USER_IDENTITY_ENABLED")
|
||||
require.NotContains(t, m, "GFAZPL_USER_IDENTITY_FALLBACK_SERVICE_CREDENTIALS_ENABLED")
|
||||
require.NotContains(t, m, "GFAZPL_USER_IDENTITY_TOKEN_URL")
|
||||
require.NotContains(t, m, "GFAZPL_USER_IDENTITY_CLIENT_ID")
|
||||
require.NotContains(t, m, "GFAZPL_USER_IDENTITY_CLIENT_SECRET")
|
||||
@@ -336,16 +339,17 @@ func TestRequestConfigProvider_PluginRequestConfig_azure(t *testing.T) {
|
||||
p := NewRequestConfigProvider(pCfg)
|
||||
require.Subset(t, p.PluginRequestConfig(context.Background(), "test-datasource"), map[string]string{
|
||||
"GFAZPL_AZURE_CLOUD": "AzureCloud", "GFAZPL_MANAGED_IDENTITY_ENABLED": "true",
|
||||
"GFAZPL_MANAGED_IDENTITY_CLIENT_ID": "mock_managed_identity_client_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_ENABLED": "true",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_TENANT_ID": "mock_workload_identity_tenant_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_CLIENT_ID": "mock_workload_identity_client_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_TOKEN_FILE": "mock_workload_identity_token_file",
|
||||
"GFAZPL_USER_IDENTITY_ENABLED": "true",
|
||||
"GFAZPL_USER_IDENTITY_TOKEN_URL": "mock_user_identity_token_url",
|
||||
"GFAZPL_USER_IDENTITY_CLIENT_ID": "mock_user_identity_client_id",
|
||||
"GFAZPL_USER_IDENTITY_CLIENT_SECRET": "mock_user_identity_client_secret",
|
||||
"GFAZPL_USER_IDENTITY_ASSERTION": "username",
|
||||
"GFAZPL_MANAGED_IDENTITY_CLIENT_ID": "mock_managed_identity_client_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_ENABLED": "true",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_TENANT_ID": "mock_workload_identity_tenant_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_CLIENT_ID": "mock_workload_identity_client_id",
|
||||
"GFAZPL_WORKLOAD_IDENTITY_TOKEN_FILE": "mock_workload_identity_token_file",
|
||||
"GFAZPL_USER_IDENTITY_ENABLED": "true",
|
||||
"GFAZPL_USER_IDENTITY_FALLBACK_SERVICE_CREDENTIALS_ENABLED": "true",
|
||||
"GFAZPL_USER_IDENTITY_TOKEN_URL": "mock_user_identity_token_url",
|
||||
"GFAZPL_USER_IDENTITY_CLIENT_ID": "mock_user_identity_client_id",
|
||||
"GFAZPL_USER_IDENTITY_CLIENT_SECRET": "mock_user_identity_client_secret",
|
||||
"GFAZPL_USER_IDENTITY_ASSERTION": "username",
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ func (cfg *Cfg) readAzureSettings() {
|
||||
}
|
||||
|
||||
azureSettings.UserIdentityTokenEndpoint = tokenEndpointSettings
|
||||
azureSettings.UserIdentityFallbackCredentialsEnabled = azureSection.Key("user_identity_fallback_credentials_enabled").MustBool(true)
|
||||
}
|
||||
|
||||
azureSettings.ForwardSettingsPlugins = util.SplitString(azureSection.Key("forward_settings_to_plugins").String())
|
||||
|
||||
@@ -109,6 +109,32 @@ func TestAzureSettings(t *testing.T) {
|
||||
|
||||
assert.True(t, cfg.Azure.UserIdentityEnabled)
|
||||
})
|
||||
t.Run("enables service credentials by default", func(t *testing.T) {
|
||||
cfg := NewCfg()
|
||||
|
||||
azureSection, err := cfg.Raw.NewSection("azure")
|
||||
require.NoError(t, err)
|
||||
_, err = azureSection.NewKey("user_identity_enabled", "true")
|
||||
require.NoError(t, err)
|
||||
|
||||
cfg.readAzureSettings()
|
||||
|
||||
assert.True(t, cfg.Azure.UserIdentityFallbackCredentialsEnabled)
|
||||
})
|
||||
t.Run("disables service credentials", func(t *testing.T) {
|
||||
cfg := NewCfg()
|
||||
|
||||
azureSection, err := cfg.Raw.NewSection("azure")
|
||||
require.NoError(t, err)
|
||||
_, err = azureSection.NewKey("user_identity_enabled", "true")
|
||||
require.NoError(t, err)
|
||||
_, err = azureSection.NewKey("user_identity_fallback_credentials_enabled", "false")
|
||||
require.NoError(t, err)
|
||||
|
||||
cfg.readAzureSettings()
|
||||
|
||||
assert.False(t, cfg.Azure.UserIdentityFallbackCredentialsEnabled)
|
||||
})
|
||||
|
||||
t.Run("should use token endpoint from Azure AD if enabled", func(t *testing.T) {
|
||||
cfg := NewCfg()
|
||||
|
||||
@@ -62,6 +62,27 @@ func getFromLegacy(data map[string]interface{}, secureData map[string]string) (a
|
||||
credentials := &azcredentials.AzureWorkloadIdentityCredentials{}
|
||||
return credentials, nil
|
||||
|
||||
case azcredentials.AzureAuthCurrentUserIdentity:
|
||||
legacyCloud, err := maputil.GetStringOptional(data, "cloudName")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cloud, err := resolveLegacyCloudName(legacyCloud)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clientSecret := secureData["clientSecret"]
|
||||
|
||||
credentials := &azcredentials.AadCurrentUserCredentials{
|
||||
ServiceCredentials: &azcredentials.AzureClientSecretCredentials{
|
||||
AzureCloud: cloud,
|
||||
TenantId: tenantId,
|
||||
ClientId: clientId,
|
||||
ClientSecret: clientSecret,
|
||||
},
|
||||
}
|
||||
|
||||
return credentials, nil
|
||||
case azcredentials.AzureAuthClientSecret:
|
||||
legacyCloud, err := maputil.GetStringOptional(data, "cloudName")
|
||||
if err != nil {
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/grafana/grafana-azure-sdk-go/v2/azsettings"
|
||||
"github.com/grafana/grafana-azure-sdk-go/v2/azusercontext"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/datasource"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
||||
@@ -52,11 +53,11 @@ func ProvideService(httpClientProvider *httpclient.Provider) *Service {
|
||||
}
|
||||
|
||||
func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
||||
return s.queryMux.QueryData(ctx, req)
|
||||
return s.queryMux.QueryData(azusercontext.WithUserFromQueryReq(ctx, req), req)
|
||||
}
|
||||
|
||||
func (s *Service) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
|
||||
return s.resourceHandler.CallResource(ctx, req, sender)
|
||||
return s.resourceHandler.CallResource(azusercontext.WithUserFromResourceReq(ctx, req), req, sender)
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
@@ -191,10 +192,10 @@ func (s *Service) getDSInfo(ctx context.Context, pluginCtx backend.PluginContext
|
||||
return instance, nil
|
||||
}
|
||||
|
||||
func queryMetricHealth(dsInfo types.DatasourceInfo) (*http.Response, error) {
|
||||
func queryMetricHealth(ctx context.Context, dsInfo types.DatasourceInfo) (*http.Response, error) {
|
||||
subscriptionsApiVersion := "2020-01-01"
|
||||
url := fmt.Sprintf("%v/subscriptions?api-version=%v", dsInfo.Routes["Azure Monitor"].URL, subscriptionsApiVersion)
|
||||
request, err := http.NewRequest(http.MethodGet, url, nil)
|
||||
request, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -207,9 +208,9 @@ func queryMetricHealth(dsInfo types.DatasourceInfo) (*http.Response, error) {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func checkAzureLogAnalyticsHealth(dsInfo types.DatasourceInfo, subscription string) (*http.Response, error) {
|
||||
func checkAzureLogAnalyticsHealth(ctx context.Context, dsInfo types.DatasourceInfo, subscription string) (*http.Response, error) {
|
||||
workspacesUrl := fmt.Sprintf("%v/subscriptions/%v/providers/Microsoft.OperationalInsights/workspaces?api-version=2017-04-26-preview", dsInfo.Routes["Azure Monitor"].URL, subscription)
|
||||
workspacesReq, err := http.NewRequest(http.MethodGet, workspacesUrl, nil)
|
||||
workspacesReq, err := http.NewRequestWithContext(ctx, http.MethodGet, workspacesUrl, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -238,7 +239,7 @@ func checkAzureLogAnalyticsHealth(dsInfo types.DatasourceInfo, subscription stri
|
||||
}
|
||||
|
||||
workspaceUrl := fmt.Sprintf("%v/v1/workspaces/%v/query", dsInfo.Routes["Azure Log Analytics"].URL, defaultWorkspaceId)
|
||||
workspaceReq, err := http.NewRequest(http.MethodPost, workspaceUrl, bytes.NewBuffer(body))
|
||||
workspaceReq, err := http.NewRequestWithContext(ctx, http.MethodPost, workspaceUrl, bytes.NewBuffer(body))
|
||||
workspaceReq.Header.Set("Content-Type", "application/json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -252,7 +253,7 @@ func checkAzureLogAnalyticsHealth(dsInfo types.DatasourceInfo, subscription stri
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func checkAzureMonitorResourceGraphHealth(dsInfo types.DatasourceInfo, subscription string) (*http.Response, error) {
|
||||
func checkAzureMonitorResourceGraphHealth(ctx context.Context, dsInfo types.DatasourceInfo, subscription string) (*http.Response, error) {
|
||||
body, err := json.Marshal(map[string]any{
|
||||
"query": "Resources | project id | limit 1",
|
||||
"subscriptions": []string{subscription},
|
||||
@@ -261,7 +262,7 @@ func checkAzureMonitorResourceGraphHealth(dsInfo types.DatasourceInfo, subscript
|
||||
return nil, err
|
||||
}
|
||||
url := fmt.Sprintf("%v/providers/Microsoft.ResourceGraph/resources?api-version=%v", dsInfo.Routes["Azure Resource Graph"].URL, resourcegraph.ArgAPIVersion)
|
||||
request, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(body))
|
||||
request, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewBuffer(body))
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -275,9 +276,9 @@ func checkAzureMonitorResourceGraphHealth(dsInfo types.DatasourceInfo, subscript
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func metricCheckHealth(dsInfo types.DatasourceInfo, logger log.Logger) (message string, defaultSubscription string, status backend.HealthStatus) {
|
||||
func metricCheckHealth(ctx context.Context, dsInfo types.DatasourceInfo, logger log.Logger) (message string, defaultSubscription string, status backend.HealthStatus) {
|
||||
defaultSubscription = dsInfo.Settings.SubscriptionId
|
||||
metricsRes, err := queryMetricHealth(dsInfo)
|
||||
metricsRes, err := queryMetricHealth(ctx, dsInfo)
|
||||
if err != nil {
|
||||
if ok := errors.Is(err, types.ErrorAzureHealthCheck); ok {
|
||||
return fmt.Sprintf("Error connecting to Azure Monitor endpoint: %s", err.Error()), defaultSubscription, backend.HealthStatusError
|
||||
@@ -309,8 +310,8 @@ func metricCheckHealth(dsInfo types.DatasourceInfo, logger log.Logger) (message
|
||||
return "Successfully connected to Azure Monitor endpoint.", defaultSubscription, backend.HealthStatusOk
|
||||
}
|
||||
|
||||
func logAnalyticsCheckHealth(dsInfo types.DatasourceInfo, defaultSubscription string) (message string, status backend.HealthStatus) {
|
||||
logsRes, err := checkAzureLogAnalyticsHealth(dsInfo, defaultSubscription)
|
||||
func logAnalyticsCheckHealth(ctx context.Context, dsInfo types.DatasourceInfo, defaultSubscription string) (message string, status backend.HealthStatus) {
|
||||
logsRes, err := checkAzureLogAnalyticsHealth(ctx, dsInfo, defaultSubscription)
|
||||
if err != nil {
|
||||
if err.Error() == "no default workspace found" {
|
||||
return "No Log Analytics workspaces found.", backend.HealthStatusUnknown
|
||||
@@ -337,8 +338,8 @@ func logAnalyticsCheckHealth(dsInfo types.DatasourceInfo, defaultSubscription st
|
||||
return "Successfully connected to Azure Log Analytics endpoint.", backend.HealthStatusOk
|
||||
}
|
||||
|
||||
func graphLogHealthCheck(dsInfo types.DatasourceInfo, defaultSubscription string) (message string, status backend.HealthStatus) {
|
||||
resourceGraphRes, err := checkAzureMonitorResourceGraphHealth(dsInfo, defaultSubscription)
|
||||
func graphLogHealthCheck(ctx context.Context, dsInfo types.DatasourceInfo, defaultSubscription string) (message string, status backend.HealthStatus) {
|
||||
resourceGraphRes, err := checkAzureMonitorResourceGraphHealth(ctx, dsInfo, defaultSubscription)
|
||||
if err != nil {
|
||||
if ok := errors.Is(err, types.ErrorAzureHealthCheck); ok {
|
||||
return fmt.Sprintf("Error connecting to Azure Resource Graph endpoint: %s", err.Error()), backend.HealthStatusError
|
||||
@@ -387,6 +388,7 @@ func parseSubscriptions(res *http.Response, logger log.Logger) ([]string, error)
|
||||
}
|
||||
|
||||
func (s *Service) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
|
||||
ctx = azusercontext.WithUserFromHealthCheckReq(ctx, req)
|
||||
dsInfo, err := s.getDSInfo(ctx, req.PluginContext)
|
||||
if err != nil {
|
||||
return &backend.CheckHealthResult{
|
||||
@@ -397,17 +399,17 @@ func (s *Service) CheckHealth(ctx context.Context, req *backend.CheckHealthReque
|
||||
|
||||
status := backend.HealthStatusOk
|
||||
|
||||
metricsLog, defaultSubscription, metricsStatus := metricCheckHealth(dsInfo, s.logger)
|
||||
metricsLog, defaultSubscription, metricsStatus := metricCheckHealth(ctx, dsInfo, s.logger)
|
||||
if metricsStatus != backend.HealthStatusOk {
|
||||
status = metricsStatus
|
||||
}
|
||||
|
||||
logAnalyticsLog, logAnalyticsStatus := logAnalyticsCheckHealth(dsInfo, defaultSubscription)
|
||||
logAnalyticsLog, logAnalyticsStatus := logAnalyticsCheckHealth(ctx, dsInfo, defaultSubscription)
|
||||
if logAnalyticsStatus != backend.HealthStatusOk {
|
||||
status = logAnalyticsStatus
|
||||
}
|
||||
|
||||
graphLog, graphStatus := graphLogHealthCheck(dsInfo, defaultSubscription)
|
||||
graphLog, graphStatus := graphLogHealthCheck(ctx, dsInfo, defaultSubscription)
|
||||
if graphStatus != backend.HealthStatusOk {
|
||||
status = graphStatus
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ func newHTTPClient(ctx context.Context, route types.AzRoute, model types.Datasou
|
||||
}
|
||||
|
||||
authOpts := azhttpclient.NewAuthOptions(azureSettings)
|
||||
authOpts.AllowUserIdentity()
|
||||
authOpts.Scopes(route.Scopes)
|
||||
azhttpclient.AddAzureAuthentication(&clientOpts, authOpts, model.Credentials)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user