mirror of
https://github.com/grafana/grafana.git
synced 2025-07-29 22:32:24 +08:00
90 lines
2.5 KiB
Go
90 lines
2.5 KiB
Go
package utils
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
|
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
|
|
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
|
|
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/types"
|
|
)
|
|
|
|
const SubscriptionsApiVersion = "2020-01-01"
|
|
|
|
func GetFirstSubscriptionOrDefault(ctx context.Context, dsInfo types.DatasourceInfo, logger log.Logger) (string, error) {
|
|
if dsInfo.Settings.SubscriptionId != "" {
|
|
return dsInfo.Settings.SubscriptionId, nil
|
|
}
|
|
|
|
url := fmt.Sprintf("%v/subscriptions?api-version=%v", dsInfo.Routes["Azure Monitor"].URL, SubscriptionsApiVersion)
|
|
request, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
res, err := dsInfo.Services["Azure Monitor"].HTTPClient.Do(request)
|
|
if err != nil {
|
|
return "", errorsource.DownstreamError(fmt.Errorf("failed to retrieve subscriptions: %v", err), false)
|
|
}
|
|
defer func() {
|
|
if err := res.Body.Close(); err != nil {
|
|
logger.Warn("Failed to close response body", "err", err)
|
|
}
|
|
}()
|
|
|
|
subscriptions, err := ParseSubscriptions(res, logger)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to parse subscriptions: %v", err)
|
|
}
|
|
|
|
if len(subscriptions) == 0 {
|
|
return "", errorsource.DownstreamError(fmt.Errorf("no subscriptions found: %v", err), false)
|
|
}
|
|
|
|
return subscriptions[0], nil
|
|
}
|
|
|
|
func ParseSubscriptions(res *http.Response, logger log.Logger) ([]string, error) {
|
|
var target struct {
|
|
Value []struct {
|
|
SubscriptionId string `json:"subscriptionId"`
|
|
}
|
|
}
|
|
err := json.NewDecoder(res.Body).Decode(&target)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer func() {
|
|
if err := res.Body.Close(); err != nil {
|
|
logger.Warn("Failed to close response body", "err", err)
|
|
}
|
|
}()
|
|
|
|
result := make([]string, len(target.Value))
|
|
for i, v := range target.Value {
|
|
result[i] = v.SubscriptionId
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
func ApplySourceFromError(errorMessage error, err error) error {
|
|
var sourceError errorsource.Error
|
|
if errors.As(err, &sourceError) {
|
|
return errorsource.SourceError(sourceError.Source(), errorMessage, false)
|
|
}
|
|
return errorMessage
|
|
}
|
|
|
|
func CreateResponseErrorFromStatusCode(statusCode int, status string, body []byte) error {
|
|
statusErr := fmt.Errorf("request failed, status: %s, body: %s", status, string(body))
|
|
if backend.ErrorSourceFromHTTPStatus(statusCode) == backend.ErrorSourceDownstream {
|
|
return backend.DownstreamError(statusErr)
|
|
}
|
|
return backend.PluginError(statusErr)
|
|
}
|