From bd5b53a3b01fd72de54b488033501786c86fa390 Mon Sep 17 00:00:00 2001 From: Toan Nguyen Date: Wed, 25 Sep 2024 15:02:19 +0700 Subject: [PATCH] Support Google Cloud and other authentication strategies (#9) --- Makefile | 5 +- README.md | 58 +++++ compose.yaml | 3 + configuration/cli.go | 12 +- configuration/update.go | 19 +- connector-definition/configuration.yaml | 2 +- connector/client/client.go | 34 ++- connector/client/config.go | 255 +++++++++++++++++++ connector/connector.go | 12 +- connector/metadata/configuration.go | 7 +- connector/metadata/connection.go | 69 ----- connector/{metadata => types}/environment.go | 6 +- go.mod | 19 +- go.sum | 159 +++++++++--- jsonschema/configuration.json | 116 +++++---- jsonschema/generator.go | 3 + tests/configuration/configuration.yaml | 39 ++- tests/prometheus/web.yml | 2 + 18 files changed, 608 insertions(+), 212 deletions(-) create mode 100644 connector/client/config.go delete mode 100644 connector/metadata/connection.go rename connector/{metadata => types}/environment.go (89%) create mode 100644 tests/prometheus/web.yml diff --git a/Makefile b/Makefile index 0320dd9..52bd25f 100644 --- a/Makefile +++ b/Makefile @@ -50,4 +50,7 @@ generate-api-types: .PHONY: generate-test-config generate-test-config: - CONNECTION_URL=http://localhost:9090 go run ./configuration update -d ./tests/configuration --log-level debug \ No newline at end of file + CONNECTION_URL=http://localhost:9090 \ + PROMETHEUS_USERNAME=admin \ + PROMETHEUS_PASSWORD=test \ + go run ./configuration update -d ./tests/configuration --log-level debug \ No newline at end of file diff --git a/README.md b/README.md index ae23c1c..188d605 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,8 @@ The connector can detect if you want to request an instant query or range query The range query mode is default If none of the timestamp operators is set. +The `timestamp` and `value` fields are the result of the instant query. If the request is a range query, `timestamp` and `value` are picked the last item of the `values` series. + #### Common arguments - `step`: the query resolution step width in duration format or float number of seconds. The step should be explicitly set for range queries. Even though the connector can estimate the approximate step width the result may be empty due to too far interval. @@ -188,6 +190,62 @@ Execute a raw PromQL query directly. This API should be used by the admin only. | prometheus_targets | [/api/v1/targets](https://prometheus.io/docs/prometheus/latest/querying/api/#targets) | | prometheus_targets_metadata | [/api/v1/targets/metadata](https://prometheus.io/docs/prometheus/latest/querying/api/#querying-target-metadata) | +## Configuration + +### Authentication + +#### Basic Authentication + +```yaml +connection_settings: + authentication: + basic: + username: + env: PROMETHEUS_USERNAME + password: + env: PROMETHEUS_PASSWORD +``` + +#### HTTP Authorization + +```yaml +connection_settings: + authentication: + authorization: + type: + value: Bearer + credentials: + env: PROMETHEUS_AUTH_TOKEN +``` + +#### OAuth2 + +```yaml +connection_settings: + authentication: + oauth2: + token_url: + value: http://example.com/oauth2/token + client_id: + env: PROMETHEUS_OAUTH2_CLIENT_ID + client_secret: + env: PROMETHEUS_OAUTH2_CLIENT_SECRET +``` + +#### Google Cloud + +The configuration accepts either the Google application credentials JSON string or file path. If the object is empty the client automatically loads the credential file from the `GOOGLE_APPLICATION_CREDENTIALS` environment variable. + +```yaml +connection_settings: + authentication: + google: + # credentials: + # env: GOOGLE_APPLICATION_CREDENTIALS_JSON + # credentials_file: + # env: GOOGLE_APPLICATION_CREDENTIALS +``` + ## Development ### Get started diff --git a/compose.yaml b/compose.yaml index 8a23e89..15ff754 100644 --- a/compose.yaml +++ b/compose.yaml @@ -12,6 +12,8 @@ services: - local.hasura.dev=host-gateway environment: CONNECTION_URL: http://prometheus:9090 + PROMETHEUS_USERNAME: admin + PROMETHEUS_PASSWORD: test OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: http://jaeger:4317 OTEL_METRICS_EXPORTER: prometheus HASURA_LOG_LEVEL: debug @@ -27,6 +29,7 @@ services: - "--web.console.libraries=/usr/share/prometheus/console_libraries" - "--web.console.templates=/usr/share/prometheus/consoles" - "--web.enable-lifecycle" + - "--web.config.file=/etc/prometheus/web.yml" - "--enable-feature=promql-experimental-functions" ports: - 9090:9090 diff --git a/configuration/cli.go b/configuration/cli.go index b449f30..ad1dcc3 100644 --- a/configuration/cli.go +++ b/configuration/cli.go @@ -3,7 +3,6 @@ package main import ( "context" "fmt" - "log" "log/slog" "os" "os/signal" @@ -31,19 +30,22 @@ func main() { defer stop() cmd := kong.Parse(&cli, kong.UsageOnError()) - _, err := initLogger(cli.LogLevel) + logger, err := initLogger(cli.LogLevel) if err != nil { - log.Fatalf("failed to initialize: %s", err) + logger.Error(fmt.Sprintf("failed to initialize: %s", err)) + os.Exit(1) } switch cmd.Command() { case "update": if err := introspectSchema(ctx, &cli.Update); err != nil { - log.Fatalf("failed to update configuration: %s", err) + logger.Error(fmt.Sprintf("failed to update configuration: %s", err)) + os.Exit(1) } case "version": _, _ = fmt.Print(version.BuildVersion) default: - log.Fatalf("unknown command <%s>", cmd.Command()) + logger.Error(fmt.Sprintf("unknown command <%s>", cmd.Command())) + os.Exit(1) } } diff --git a/configuration/update.go b/configuration/update.go index f00520e..364ea3f 100644 --- a/configuration/update.go +++ b/configuration/update.go @@ -14,6 +14,7 @@ import ( "github.com/hasura/ndc-prometheus/connector/client" "github.com/hasura/ndc-prometheus/connector/metadata" + "github.com/hasura/ndc-prometheus/connector/types" "github.com/prometheus/common/model" "go.opentelemetry.io/otel" "gopkg.in/yaml.v3" @@ -41,12 +42,7 @@ func introspectSchema(ctx context.Context, args *UpdateArguments) error { originalConfig = &defaultConfiguration } - endpoint, err := originalConfig.ConnectionSettings.URL.Get() - if err != nil { - return err - } - - apiClient, err := client.NewClient(endpoint, originalConfig.ConnectionSettings.ToHTTPClientConfig(), clientTracer, nil) + apiClient, err := client.NewClient(ctx, originalConfig.ConnectionSettings, clientTracer, nil) if err != nil { return err } @@ -76,19 +72,22 @@ func introspectSchema(ctx context.Context, args *UpdateArguments) error { } func (uc *updateCommand) updateMetricsMetadata(ctx context.Context) error { - metricsInfo, err := uc.Client.API.Metadata(ctx, "", "") + metricsInfo, err := uc.Client.Metadata(ctx, "", "10000000") if err != nil { return err } newMetrics := map[string]metadata.MetricInfo{} for key, info := range metricsInfo { + if len(info) == 0 { + continue + } if (len(uc.Include) > 0 && !validateRegularExpressions(uc.Include, key)) || validateRegularExpressions(uc.Exclude, key) || len(info) == 0 { continue } - slog.Debug(key, slog.String("type", "metrics")) + slog.Info(key, slog.String("type", string(info[0].Type))) labels, err := uc.getAllLabelsOfMetric(ctx, key) if err != nil { return fmt.Errorf("error when fetching labels for metric `%s`: %s", key, err) @@ -170,8 +169,8 @@ func (uc *updateCommand) writeConfigFile() error { } var defaultConfiguration = metadata.Configuration{ - ConnectionSettings: metadata.ClientSettings{ - URL: metadata.NewEnvironmentVariable("CONNECTION_URL"), + ConnectionSettings: client.ClientSettings{ + URL: types.NewEnvironmentVariable("CONNECTION_URL"), }, Generator: metadata.GeneratorSettings{ Metrics: metadata.MetricsGeneratorSettings{ diff --git a/connector-definition/configuration.yaml b/connector-definition/configuration.yaml index 3b78462..d688ac9 100644 --- a/connector-definition/configuration.yaml +++ b/connector-definition/configuration.yaml @@ -1,7 +1,7 @@ # yaml-language-server: $schema=https://raw.githubusercontent.com/hasura/ndc-prometheus/main/jsonschema/configuration.json connection_settings: url: - variable: CONNECTION_URL + env: CONNECTION_URL generator: metrics: enabled: true diff --git a/connector/client/client.go b/connector/client/client.go index e27375d..fa93035 100644 --- a/connector/client/client.go +++ b/connector/client/client.go @@ -2,13 +2,16 @@ package client import ( "context" + "errors" "fmt" + "log/slog" "net/http" + "strings" "time" + "github.com/hasura/ndc-sdk-go/utils" "github.com/prometheus/client_golang/api" v1 "github.com/prometheus/client_golang/api/prometheus/v1" - "github.com/prometheus/common/config" "github.com/prometheus/common/model" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/codes" @@ -26,8 +29,17 @@ type Client struct { } // NewClient creates a new Prometheus client instance -func NewClient(endpoint string, clientConfig config.HTTPClientConfig, tracer trace.Tracer, timeout *model.Duration) (*Client, error) { - httpClient, err := config.NewClientFromConfig(clientConfig, "ndc-prometheus") +func NewClient(ctx context.Context, cfg ClientSettings, tracer trace.Tracer, timeout *model.Duration) (*Client, error) { + + endpoint, err := cfg.URL.Get() + if err != nil { + return nil, fmt.Errorf("url: %s", err) + } + if endpoint == "" { + return nil, errors.New("the endpoint setting is empty") + } + + httpClient, err := cfg.createHttpClient(ctx) if err != nil { return nil, err } @@ -87,5 +99,19 @@ func createHTTPClient(c api.Client) *httpClient { // Do wraps the api.Client with trace context headers injection func (ac *httpClient) Do(ctx context.Context, req *http.Request) (*http.Response, []byte, error) { ac.propagator.Inject(ctx, propagation.HeaderCarrier(req.Header)) - return ac.Client.Do(ctx, req) + r, bs, err := ac.Client.Do(ctx, req) + if utils.IsDebug(slog.Default()) { + attrs := []any{} + if r != nil { + attrs = append(attrs, slog.Int("status_code", r.StatusCode)) + } + if len(bs) > 0 { + attrs = append(attrs, slog.String("response", string(bs))) + } + if err != nil { + attrs = append(attrs, slog.String("error", err.Error())) + } + slog.Debug(fmt.Sprintf("%s %s", strings.ToUpper(req.Method), req.RequestURI), attrs...) + } + return r, bs, err } diff --git a/connector/client/config.go b/connector/client/config.go new file mode 100644 index 0000000..29e7868 --- /dev/null +++ b/connector/client/config.go @@ -0,0 +1,255 @@ +package client + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + + "github.com/hasura/ndc-prometheus/connector/types" + "github.com/prometheus/common/config" + "github.com/prometheus/common/model" + "google.golang.org/api/option" + apihttp "google.golang.org/api/transport/http" +) + +// ClientSettings contain information for the Prometheus server that the client connects to +type ClientSettings struct { + // The endpoint of the Prometheus server. + URL types.EnvironmentValue `json:"url" yaml:"url"` + // The authentication configuration + Authentication *AuthConfig `json:"authentication,omitempty" yaml:"authentication,omitempty"` + // The default timeout in seconds for Prometheus requests. The default is no timeout. + Timeout *model.Duration `json:"timeout,omitempty" yaml:"timeout,omitempty"` + // TLSConfig to use to connect to the targets. + TLSConfig config.TLSConfig `yaml:"tls_config,omitempty" json:"tls_config,omitempty"` + // FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + // The omitempty flag is not set, because it would be hidden from the + // marshalled configuration when set to false. + FollowRedirects bool `yaml:"follow_redirects,omitempty" json:"follow_redirects,omitempty"` + // EnableHTTP2 specifies whether the client should configure HTTP2. + // The omitempty flag is not set, because it would be hidden from the + // marshalled configuration when set to false. + EnableHTTP2 bool `yaml:"enable_http2,omitempty" json:"enable_http2,omitempty"` + // Proxy configuration. + config.ProxyConfig `yaml:",inline"` + // HTTPHeaders specify headers to inject in the requests. Those headers + // could be marshalled back to the users. + HTTPHeaders *config.Headers `yaml:"http_headers,omitempty" json:"http_headers,omitempty"` +} + +// UnmarshalJSON implements json.Unmarshaler. +func (cs *ClientSettings) UnmarshalJSON(b []byte) error { + type Plain ClientSettings + var plain Plain + if err := json.Unmarshal(b, &plain); err != nil { + return err + } + + u, err := plain.URL.Get() + if err != nil || u == "" { + return fmt.Errorf("invalid client URL %s", err) + } + + *cs = ClientSettings(plain) + return nil +} + +// getHTTPClientConfig converts client settings to Prometheus client's HTTPClientConfig +func (cs ClientSettings) getHTTPClientConfig() (*config.HTTPClientConfig, error) { + result := &config.HTTPClientConfig{ + TLSConfig: cs.TLSConfig, + FollowRedirects: cs.FollowRedirects, + EnableHTTP2: cs.EnableHTTP2, + ProxyConfig: cs.ProxyConfig, + HTTPHeaders: cs.HTTPHeaders, + } + + if cs.Authentication == nil { + return result, nil + } + if cs.Authentication.Authorization != nil { + au, err := cs.Authentication.Authorization.toClientConfig() + if err != nil { + return nil, err + } + result.Authorization = au + } + if cs.Authentication.OAuth2 != nil { + au, err := cs.Authentication.OAuth2.toClientConfig() + if err != nil { + return nil, err + } + result.OAuth2 = au + } + if cs.Authentication.BasicAuth != nil { + au, err := cs.Authentication.BasicAuth.toClientConfig() + if err != nil { + return nil, err + } + result.BasicAuth = au + } + + return result, nil +} + +func (cs ClientSettings) createHttpClient(ctx context.Context) (*http.Client, error) { + httpClient, err := cs.createGoogleHttpClient(ctx) + if err != nil { + return nil, fmt.Errorf("failed to initialize the google http client: %w", err) + } + if httpClient != nil { + return httpClient, nil + } + + clientConfig, err := cs.getHTTPClientConfig() + if err != nil { + return nil, fmt.Errorf("failed to initialize the prometheus client config: %w", err) + } + return config.NewClientFromConfig(*clientConfig, "ndc-prometheus") +} + +func (cs ClientSettings) createGoogleHttpClient(ctx context.Context) (*http.Client, error) { + if cs.Authentication == nil || cs.Authentication.Google == nil { + return nil, nil + } + + opts := []option.ClientOption{ + option.WithScopes("https://www.googleapis.com/auth/monitoring.read"), + } + if cs.Authentication.Google.Credentials != nil { + credJSON, err := cs.Authentication.Google.Credentials.Get() + if err != nil { + return nil, err + } + if credJSON != "" { + opts = append(opts, option.WithCredentialsJSON([]byte(credJSON))) + } + } else if cs.Authentication.Google.CredentialsFile != nil { + credFile, err := cs.Authentication.Google.CredentialsFile.Get() + if err != nil { + return nil, err + } + if credFile != "" { + opts = append(opts, option.WithCredentialsFile(credFile)) + } + } + + rt, err := config.NewRoundTripperFromConfigWithContext(ctx, config.HTTPClientConfig{ + TLSConfig: cs.TLSConfig, + EnableHTTP2: cs.EnableHTTP2, + ProxyConfig: cs.ProxyConfig, + FollowRedirects: cs.FollowRedirects, + HTTPHeaders: cs.HTTPHeaders, + }, "ndc-prometheus") + if err != nil { + return nil, err + } + + transport, err := apihttp.NewTransport(ctx, rt, opts...) + if err != nil { + return nil, fmt.Errorf("error occurred while fetching GCP transport while setting up client for prometheus: %w", err) + } + + return &http.Client{ + Transport: transport, + }, nil +} + +// AuthConfig the authentication configuration +type AuthConfig struct { + // The HTTP basic authentication credentials for the targets. + BasicAuth *BasicAuthConfig `yaml:"basic,omitempty" json:"basic,omitempty"` + // The HTTP authorization credentials for the targets. + Authorization *AuthorizationConfig `yaml:"authorization,omitempty" json:"authorization,omitempty"` + // The OAuth2 client credentials used to fetch a token for the targets. + OAuth2 *OAuth2Config `yaml:"oauth2,omitempty" json:"oauth2,omitempty"` + // The Google client credentials used to fetch a token for the targets. + Google *GoogleAuthConfig `yaml:"google,omitempty" json:"google,omitempty"` +} + +// BasicAuth the HTTP basic authentication credentials for the targets +type BasicAuthConfig struct { + Username types.EnvironmentValue `yaml:"username" json:"username"` + Password types.EnvironmentValue `yaml:"password" json:"password"` +} + +func (bac BasicAuthConfig) toClientConfig() (*config.BasicAuth, error) { + username, err := bac.Username.Get() + if err != nil { + return nil, err + } + password, err := bac.Password.Get() + if err != nil { + return nil, err + } + return &config.BasicAuth{ + Username: username, + Password: config.Secret(password), + }, nil +} + +// AuthorizationConfig the HTTP authorization credentials for the targets +type AuthorizationConfig struct { + Type types.EnvironmentValue `yaml:"type" json:"type"` + Credentials types.EnvironmentValue `yaml:"credentials" json:"credentials"` +} + +func (hac AuthorizationConfig) toClientConfig() (*config.Authorization, error) { + authType, err := hac.Type.Get() + if err != nil { + return nil, err + } + cred, err := hac.Credentials.Get() + if err != nil { + return nil, err + } + return &config.Authorization{ + Type: authType, + Credentials: config.Secret(cred), + }, nil +} + +// OAuth2Config the OAuth2 client credentials used to fetch a token for the targets +type OAuth2Config struct { + ClientID types.EnvironmentValue `yaml:"client_id" json:"client_id"` + ClientSecret types.EnvironmentValue `yaml:"client_secret" json:"client_secret"` + TokenURL types.EnvironmentValue `yaml:"token_url" json:"token_url"` + Scopes []string `yaml:"scopes,omitempty" json:"scopes,omitempty"` + EndpointParams map[string]string `yaml:"endpoint_params,omitempty" json:"endpoint_params,omitempty"` + TLSConfig config.TLSConfig `yaml:"tls_config,omitempty"` + config.ProxyConfig `yaml:",inline"` +} + +func (oc OAuth2Config) toClientConfig() (*config.OAuth2, error) { + clientId, err := oc.ClientID.Get() + if err != nil { + return nil, err + } + clientSecret, err := oc.ClientSecret.Get() + if err != nil { + return nil, err + } + tokenURL, err := oc.TokenURL.Get() + if err != nil { + return nil, err + } + + return &config.OAuth2{ + ClientID: clientId, + ClientSecret: config.Secret(clientSecret), + TokenURL: tokenURL, + Scopes: oc.Scopes, + EndpointParams: oc.EndpointParams, + TLSConfig: oc.TLSConfig, + ProxyConfig: oc.ProxyConfig, + }, nil +} + +// GoogleAuth the Google client credentials used to fetch a token for the targets +type GoogleAuthConfig struct { + // Text of the Google credential JSON + Credentials *types.EnvironmentValue `yaml:"credentials,omitempty" json:"credentials,omitempty"` + // Path of the Google credential file + CredentialsFile *types.EnvironmentValue `yaml:"credentials_file,omitempty" json:"credentials_file,omitempty"` +} diff --git a/connector/connector.go b/connector/connector.go index f7e502f..1349e12 100644 --- a/connector/connector.go +++ b/connector/connector.go @@ -3,7 +3,6 @@ package connector import ( "context" "encoding/json" - "errors" "fmt" "log/slog" @@ -68,7 +67,7 @@ func (c *PrometheusConnector) ParseConfiguration(ctx context.Context, configurat // In addition, this function should register any // connector-specific metrics with the metrics registry. func (c *PrometheusConnector) TryInitState(ctx context.Context, conf *metadata.Configuration, metrics *connector.TelemetryState) (*metadata.State, error) { - _, span := metrics.Tracer.StartInternal(ctx, "Initialize") + ctx, span := metrics.Tracer.StartInternal(ctx, "Initialize") defer span.End() promSchema, err := metadata.BuildConnectorSchema(&conf.Metadata) @@ -86,14 +85,7 @@ func (c *PrometheusConnector) TryInitState(ctx context.Context, conf *metadata.C } c.rawSchema = schema.NewRawSchemaResponseUnsafe(rawSchema) - endpoint, err := conf.ConnectionSettings.URL.Get() - if err != nil { - return nil, fmt.Errorf("url: %s", err) - } - if endpoint == "" { - return nil, errors.New("the endpoint setting is empty") - } - client, err := client.NewClient(endpoint, conf.ConnectionSettings.ToHTTPClientConfig(), metrics.Tracer, conf.ConnectionSettings.Timeout) + client, err := client.NewClient(ctx, conf.ConnectionSettings, metrics.Tracer, conf.ConnectionSettings.Timeout) if err != nil { return nil, err } diff --git a/connector/metadata/configuration.go b/connector/metadata/configuration.go index f1afe36..446dd6a 100644 --- a/connector/metadata/configuration.go +++ b/connector/metadata/configuration.go @@ -4,14 +4,15 @@ import ( "fmt" "os" + "github.com/hasura/ndc-prometheus/connector/client" "gopkg.in/yaml.v3" ) // Configuration the configuration of Prometheus connector type Configuration struct { - ConnectionSettings ClientSettings `json:"connection_settings" yaml:"connection_settings"` - Generator GeneratorSettings `json:"generator" yaml:"generator"` - Metadata Metadata `json:"metadata" yaml:"metadata"` + ConnectionSettings client.ClientSettings `json:"connection_settings" yaml:"connection_settings"` + Generator GeneratorSettings `json:"generator" yaml:"generator"` + Metadata Metadata `json:"metadata" yaml:"metadata"` } // MetricsGeneratorSettings contain settings for the metrics generation diff --git a/connector/metadata/connection.go b/connector/metadata/connection.go deleted file mode 100644 index f5092e4..0000000 --- a/connector/metadata/connection.go +++ /dev/null @@ -1,69 +0,0 @@ -package metadata - -import ( - "encoding/json" - "fmt" - - "github.com/prometheus/common/config" - "github.com/prometheus/common/model" -) - -// ClientSettings contain information for the Prometheus server that the client connects to -type ClientSettings struct { - // The endpoint of the Prometheus server. - URL EnvironmentValue `json:"url" yaml:"url"` - // The default timeout in seconds for Prometheus requests. The default is no timeout. - Timeout *model.Duration `json:"timeout,omitempty" yaml:"timeout,omitempty"` - // The HTTP basic authentication credentials for the targets. - BasicAuth *config.BasicAuth `yaml:"basic_auth,omitempty" json:"basic_auth,omitempty"` - // The HTTP authorization credentials for the targets. - Authorization *config.Authorization `yaml:"authorization,omitempty" json:"authorization,omitempty"` - // The OAuth2 client credentials used to fetch a token for the targets. - OAuth2 *config.OAuth2 `yaml:"oauth2,omitempty" json:"oauth2,omitempty"` - // TLSConfig to use to connect to the targets. - TLSConfig config.TLSConfig `yaml:"tls_config,omitempty" json:"tls_config,omitempty"` - // FollowRedirects specifies whether the client should follow HTTP 3xx redirects. - // The omitempty flag is not set, because it would be hidden from the - // marshalled configuration when set to false. - FollowRedirects bool `yaml:"follow_redirects,omitempty" json:"follow_redirects,omitempty"` - // EnableHTTP2 specifies whether the client should configure HTTP2. - // The omitempty flag is not set, because it would be hidden from the - // marshalled configuration when set to false. - EnableHTTP2 bool `yaml:"enable_http2,omitempty" json:"enable_http2,omitempty"` - // Proxy configuration. - config.ProxyConfig `yaml:",inline"` - // HTTPHeaders specify headers to inject in the requests. Those headers - // could be marshalled back to the users. - HTTPHeaders *config.Headers `yaml:"http_headers,omitempty" json:"http_headers,omitempty"` -} - -// UnmarshalJSON implements json.Unmarshaler. -func (cs *ClientSettings) UnmarshalJSON(b []byte) error { - type Plain ClientSettings - var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { - return err - } - - u, err := plain.URL.Get() - if err != nil || u == "" { - return fmt.Errorf("invalid client URL %s", err) - } - - *cs = ClientSettings(plain) - return nil -} - -// ToHTTPClientConfig converts client settings to Prometheus client's HTTPClientConfig -func (cs ClientSettings) ToHTTPClientConfig() config.HTTPClientConfig { - return config.HTTPClientConfig{ - BasicAuth: cs.BasicAuth, - Authorization: cs.Authorization, - OAuth2: cs.OAuth2, - TLSConfig: cs.TLSConfig, - FollowRedirects: cs.FollowRedirects, - EnableHTTP2: cs.EnableHTTP2, - ProxyConfig: cs.ProxyConfig, - HTTPHeaders: cs.HTTPHeaders, - } -} diff --git a/connector/metadata/environment.go b/connector/types/environment.go similarity index 89% rename from connector/metadata/environment.go rename to connector/types/environment.go index 3ab6594..0c6b9d0 100644 --- a/connector/metadata/environment.go +++ b/connector/types/environment.go @@ -1,4 +1,4 @@ -package metadata +package types import ( "errors" @@ -7,8 +7,8 @@ import ( // EnvironmentValue represents either a literal string or an environment reference type EnvironmentValue struct { - Value *string `json:"value,omitempty" yaml:"value,omitempty"` - Variable *string `json:"variable,omitempty" yaml:"variable,omitempty"` + Value *string `json:"value,omitempty" yaml:"value,omitempty" jsonschema:"oneof_required=value"` + Variable *string `json:"env,omitempty" yaml:"env,omitempty" jsonschema:"oneof_required=env"` } // NewEnvironmentValue create an EnvironmentValue with a literal value diff --git a/go.mod b/go.mod index 056b432..541fda8 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.23.0 require ( github.com/alecthomas/kong v1.2.1 - github.com/go-viper/mapstructure/v2 v2.2.0 + github.com/go-viper/mapstructure/v2 v2.2.1 github.com/hasura/ndc-sdk-go v1.3.1-0.20240924031613-bf965d014b44 github.com/iancoleman/strcase v0.3.0 github.com/invopop/jsonschema v0.12.0 @@ -13,24 +13,32 @@ require ( github.com/prometheus/common v0.59.1 go.opentelemetry.io/otel v1.30.0 go.opentelemetry.io/otel/trace v1.30.0 + google.golang.org/api v0.198.0 gopkg.in/yaml.v3 v3.0.1 gotest.tools/v3 v3.5.1 ) require ( + cloud.google.com/go/auth v0.9.4 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect + cloud.google.com/go/compute/metadata v0.5.2 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/go-cmp v0.6.0 // indirect + github.com/google/s2a-go v0.1.8 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/compress v1.17.10 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -39,6 +47,8 @@ require ( github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect + go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.30.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.30.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.30.0 // indirect @@ -50,12 +60,13 @@ require ( go.opentelemetry.io/otel/sdk v1.30.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.30.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect + golang.org/x/crypto v0.27.0 // indirect golang.org/x/net v0.29.0 // indirect golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/text v0.18.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect google.golang.org/grpc v1.67.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 8b3577b..2dae50e 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,14 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.115.1 h1:Jo0SM9cQnSkYfp44+v+NQXHpcHqlnRJk2qxh6yvxxxQ= +cloud.google.com/go/auth v0.9.4 h1:DxF7imbEbiFu9+zdKC6cKBko1e8XeJnipNqIbWZ+kDI= +cloud.google.com/go/auth v0.9.4/go.mod h1:SHia8n6//Ya940F1rLimhJCjjx7KE17t0ctFEci3HkA= +cloud.google.com/go/auth/oauth2adapt v0.2.4 h1:0GWE/FUsXhf6C+jAkWgYm7X9tK8cuEIfy19DBn6B6bY= +cloud.google.com/go/auth/oauth2adapt v0.2.4/go.mod h1:jC/jOpwFP6JBxhB3P5Rr0a9HLMC/Pe3eaL4NmdvqPtc= +cloud.google.com/go/compute/metadata v0.5.1 h1:NM6oZeZNlYjiwYje+sYFjEpP0Q0zCan1bmQW/KmIrGs= +cloud.google.com/go/compute/metadata v0.5.1/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k= +cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixAHn3fyqngqo= +cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/alecthomas/assert/v2 v2.10.0 h1:jjRCHsj6hBJhkmhznrCzoNpbA3zqy0fYiUcYZP/GkPY= github.com/alecthomas/assert/v2 v2.10.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/kong v1.2.1 h1:E8jH4Tsgv6wCRX2nGrdPyHDUCSG83WH2qE4XLACD33Q= @@ -12,29 +23,61 @@ github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMU github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= 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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 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/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/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= +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/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/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-viper/mapstructure/v2 v2.1.0 h1:gHnMa2Y/pIxElCH2GlZZ1lZSsn6XMtufpGyP1XxdC/w= -github.com/go-viper/mapstructure/v2 v2.1.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-viper/mapstructure/v2 v2.2.0 h1:zGE1Kaz78LVwzU0kOfZuqwKKiG1gLkHTZ/cZioHp9po= github.com/go-viper/mapstructure/v2 v2.2.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= +github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +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.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +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.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/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= +github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM= +github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw= +github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= -github.com/hasura/ndc-sdk-go v1.3.1-0.20240922072552-9808dacbcee4 h1:iAHA7iUI6U24OlM2EZR+gk6lj1rxFyxwZnnXNmhtWbI= -github.com/hasura/ndc-sdk-go v1.3.1-0.20240922072552-9808dacbcee4/go.mod h1:HYlvIl0qvoUupwb0MfDY9JZnltab+qSDQapEeSC70jY= github.com/hasura/ndc-sdk-go v1.3.1-0.20240924031613-bf965d014b44 h1:2sjWUqUlhiGsn4OaoAGKWyleq0ArWDBB33M6rEyWNpg= github.com/hasura/ndc-sdk-go v1.3.1-0.20240924031613-bf965d014b44/go.mod h1:HYlvIl0qvoUupwb0MfDY9JZnltab+qSDQapEeSC70jY= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= @@ -50,6 +93,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0= +github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -71,10 +116,9 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 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.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4= -github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 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.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= @@ -84,85 +128,121 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG 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/stretchr/objx v0.1.0/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/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= -go.opentelemetry.io/contrib/propagators/b3 v1.28.0 h1:XR6CFQrQ/ttAYmTBX2loUEFGdk1h17pxYI8828dk/1Y= -go.opentelemetry.io/contrib/propagators/b3 v1.28.0/go.mod h1:DWRkzJONLquRz7OJPh2rRbZ7MugQj62rk7g6HRnEqh0= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 h1:ZIg3ZT/aQ7AfKqdwp7ECpOK6vHqquXXuyTjIO8ZdmPs= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0/go.mod h1:DQAwmETtZV00skUwgD6+0U89g80NKsJE3DCKeLLPQMI= go.opentelemetry.io/contrib/propagators/b3 v1.30.0 h1:vumy4r1KMyaoQRltX7cJ37p3nluzALX9nugCjNNefuY= go.opentelemetry.io/contrib/propagators/b3 v1.30.0/go.mod h1:fRbvRsaeVZ82LIl3u0rIvusIel2UUf+JcaaIpy5taho= -go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 h1:U2guen0GhqH8o/G2un8f/aG/y++OuW6MyCo6hT9prXk= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0/go.mod h1:yeGZANgEcpdx/WK0IvvRFC+2oLiMS2u4L/0Rj2M2Qr0= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.30.0 h1:WypxHH02KX2poqqbaadmkMYalGyy/vil4HE4PM4nRJc= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.30.0/go.mod h1:U79SV99vtvGSEBeeHnpgGJfTsnsdkWLpPN/CcHAzBSI= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.28.0 h1:aLmmtjRke7LPDQ3lvpFz+kNEH43faFhzW7v8BFIEydg= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.28.0/go.mod h1:TC1pyCt6G9Sjb4bQpShH+P5R53pO6ZuGnHuuln9xMeE= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.30.0 h1:VrMAbeJz4gnVDg2zEzjHG4dEH86j4jO6VYB+NgtGD8s= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.30.0/go.mod h1:qqN/uFdpeitTvm+JDqqnjm517pmQRYxTORbETHq5tOc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 h1:lsInsfvhVIfOI6qHVyysXMNDnjO9Npvl7tlDPJFBVd4= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0/go.mod h1:KQsVNh4OjgjTG0G6EiNi1jVpnaeeKsKMRwbLN+f1+8M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 h1:m0yTiGDLUvVYaTFbAvCkVYIYcvwKt3G7OLoN77NUs/8= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0/go.mod h1:wBQbT4UekBfegL2nx0Xk1vBcnzyBPsIVm9hRG4fYcr4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 h1:j9+03ymgYhPKmeXGk5Zu+cIZOlVzd9Zv7QIiyItjFBU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0/go.mod h1:Y5+XiUG4Emn1hTfciPzGPJaSI+RpDts6BnCIir0SLqk= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 h1:umZgi92IyxfXd/l4kaDhnKgY8rnN/cZcF1LKc6I8OQ8= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0/go.mod h1:4lVs6obhSVRb1EW5FhOuBTyiQhtRtAnnva9vD3yRfq8= -go.opentelemetry.io/otel/exporters/prometheus v0.50.0 h1:2Ewsda6hejmbhGFyUvWZjUThC98Cf8Zy6g0zkIimOng= -go.opentelemetry.io/otel/exporters/prometheus v0.50.0/go.mod h1:pMm5PkUo5YwbLiuEf7t2xg4wbP0/eSJrMxIMxKosynY= go.opentelemetry.io/otel/exporters/prometheus v0.52.0 h1:kmU3H0b9ufFSi8IQCcxack+sWUblKkFbqWYs6YiACGQ= go.opentelemetry.io/otel/exporters/prometheus v0.52.0/go.mod h1:+wsAp2+JhuGXX7YRkjlkx6hyWY3ogFPfNA4x3nyiAh0= -go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= -go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= -go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= -go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE= go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg= -go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= -go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/sdk/metric v1.30.0 h1:QJLT8Pe11jyHBHfSAgYH7kEmT24eX792jZO1bo4BXkM= go.opentelemetry.io/otel/sdk/metric v1.30.0/go.mod h1:waS6P3YqFNzeP01kuo/MBBYqaoBJl7efRQHOaydhy1Y= -go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= -go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +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/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-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +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/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto/googleapis/api v0.0.0-20240820151423-278611b39280 h1:YDFM9oOjiFhaMAVgbDxfxW+66nRrsvzQzJ51wp3OxC0= -google.golang.org/genproto/googleapis/api v0.0.0-20240820151423-278611b39280/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= +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-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.198.0 h1:OOH5fZatk57iN0A7tjJQzt6aPfYQ1JiWkt1yGseazks= +google.golang.org/api v0.198.0/go.mod h1:/Lblzl3/Xqqk9hw/yS97TImKTUwnf1bv89v7+OagJzc= +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/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-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240820151423-278611b39280 h1:XQMA2e105XNlEZ8NRF0HqnUOZzP14sUSsgL09kpdNnU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240820151423-278611b39280/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/api v0.0.0-20240924160255-9d4c2d233b61 h1:pAjq8XSSzXoP9ya73v/w+9QEAAJNluLrpmMq5qFJQNY= +google.golang.org/genproto/googleapis/api v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:O6rP0uBq4k0mdi/b4ZEMAZjkhYWhS815kCvaMha4VN8= google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +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.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -170,7 +250,10 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +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= diff --git a/jsonschema/configuration.json b/jsonschema/configuration.json index 4ec46a8..bab4070 100644 --- a/jsonschema/configuration.json +++ b/jsonschema/configuration.json @@ -3,49 +3,54 @@ "$id": "https://github.com/hasura/ndc-prometheus/connector/metadata/configuration", "$ref": "#/$defs/Configuration", "$defs": { - "Authorization": { + "AuthConfig": { "properties": { - "type": { - "type": "string" + "basic": { + "$ref": "#/$defs/BasicAuthConfig" }, - "credentials": { - "type": "string" + "authorization": { + "$ref": "#/$defs/AuthorizationConfig" }, - "credentials_file": { - "type": "string" + "oauth2": { + "$ref": "#/$defs/OAuth2Config" }, - "credentials_ref": { - "type": "string" + "google": { + "$ref": "#/$defs/GoogleAuthConfig" } }, "additionalProperties": false, "type": "object" }, - "BasicAuth": { + "AuthorizationConfig": { "properties": { - "username": { - "type": "string" - }, - "username_file": { - "type": "string" + "type": { + "$ref": "#/$defs/EnvironmentValue" }, - "username_ref": { - "type": "string" + "credentials": { + "$ref": "#/$defs/EnvironmentValue" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "type", + "credentials" + ] + }, + "BasicAuthConfig": { + "properties": { + "username": { + "$ref": "#/$defs/EnvironmentValue" }, "password": { - "type": "string" - }, - "password_file": { - "type": "string" - }, - "password_ref": { - "type": "string" + "$ref": "#/$defs/EnvironmentValue" } }, "additionalProperties": false, "type": "object", "required": [ - "username" + "username", + "password" ] }, "ClientSettings": { @@ -53,21 +58,12 @@ "url": { "$ref": "#/$defs/EnvironmentValue" }, - "timeout": { - "type": "integer" + "authentication": { + "$ref": "#/$defs/AuthConfig" }, - "keep_alive": { + "timeout": { "type": "integer" }, - "basic_auth": { - "$ref": "#/$defs/BasicAuth" - }, - "authorization": { - "$ref": "#/$defs/Authorization" - }, - "oauth2": { - "$ref": "#/$defs/OAuth2" - }, "tls_config": { "$ref": "#/$defs/TLSConfig" }, @@ -120,11 +116,25 @@ ] }, "EnvironmentValue": { + "oneOf": [ + { + "required": [ + "value" + ], + "title": "value" + }, + { + "required": [ + "env" + ], + "title": "env" + } + ], "properties": { "value": { "type": "string" }, - "variable": { + "env": { "type": "string" } }, @@ -143,6 +153,18 @@ "metrics" ] }, + "GoogleAuthConfig": { + "properties": { + "credentials": { + "$ref": "#/$defs/EnvironmentValue" + }, + "credentials_file": { + "$ref": "#/$defs/EnvironmentValue" + } + }, + "additionalProperties": false, + "type": "object" + }, "Header": { "properties": { "values": { @@ -323,19 +345,16 @@ "type" ] }, - "OAuth2": { + "OAuth2Config": { "properties": { "client_id": { - "type": "string" + "$ref": "#/$defs/EnvironmentValue" }, "client_secret": { - "type": "string" - }, - "client_secret_file": { - "type": "string" + "$ref": "#/$defs/EnvironmentValue" }, - "client_secret_ref": { - "type": "string" + "token_url": { + "$ref": "#/$defs/EnvironmentValue" }, "scopes": { "items": { @@ -343,9 +362,6 @@ }, "type": "array" }, - "token_url": { - "type": "string" - }, "endpoint_params": { "additionalProperties": { "type": "string" @@ -373,8 +389,6 @@ "required": [ "client_id", "client_secret", - "client_secret_file", - "client_secret_ref", "token_url", "TLSConfig" ] diff --git a/jsonschema/generator.go b/jsonschema/generator.go index 8fafbfc..f245c82 100644 --- a/jsonschema/generator.go +++ b/jsonschema/generator.go @@ -23,6 +23,9 @@ func jsonSchemaConfiguration() error { if err := r.AddGoComments("github.com/hasura/ndc-prometheus/connector/metadata", "../connector/metadata"); err != nil { return err } + if err := r.AddGoComments("github.com/hasura/ndc-prometheus/connector/types", "../connector/types"); err != nil { + return err + } reflectSchema := r.Reflect(&metadata.Configuration{}) diff --git a/tests/configuration/configuration.yaml b/tests/configuration/configuration.yaml index b00304b..4128f0c 100644 --- a/tests/configuration/configuration.yaml +++ b/tests/configuration/configuration.yaml @@ -1,7 +1,13 @@ # yaml-language-server: $schema=../../jsonschema/configuration.json connection_settings: url: - variable: CONNECTION_URL + env: CONNECTION_URL + authentication: + basic: + username: + env: PROMETHEUS_USERNAME + password: + env: PROMETHEUS_PASSWORD generator: metrics: enabled: true @@ -12,6 +18,20 @@ generator: - ^node_+ metadata: metrics: + ndc_prometheus_query_total: + type: counter + description: Total number of query requests + labels: + collection: {} + http_status: {} + instance: {} + job: {} + otel_scope_name: {} + status: {} + ndc_prometheus_query_total_time: + type: histogram + description: Total time taken to plan and execute a query, in seconds + labels: {} net_conntrack_dialer_conn_attempted_total: type: counter description: Total number of connections attempted by the given dialer a given name. @@ -41,20 +61,13 @@ metadata: instance: {} job: {} reason: {} - net_conntrack_listener_conn_accepted_total: - type: counter - description: Total number of connections opened to the listener of a given name. - labels: - instance: {} - job: {} - listener_name: {} - net_conntrack_listener_conn_closed_total: - type: counter - description: Total number of connections closed that were made to the listener of a given name. + otel_scope_info: + type: gauge + description: Instrumentation Scope metadata labels: instance: {} job: {} - listener_name: {} + otel_scope_name: {} process_cpu_seconds_total: type: counter description: Total user and system CPU time spent in seconds. @@ -145,8 +158,8 @@ metadata: service_up: query: up{job="${job}", instance="${instance}"} labels: - job: {} instance: {} + job: {} arguments: instance: type: String diff --git a/tests/prometheus/web.yml b/tests/prometheus/web.yml new file mode 100644 index 0000000..38e4749 --- /dev/null +++ b/tests/prometheus/web.yml @@ -0,0 +1,2 @@ +basic_auth_users: + admin: $2b$12$hNf2lSsxfm0.i4a.1kVpSOVyBCfIB51VRjgBUyv6kdnyTlgWj81Ay