diff --git a/.chloggen/add-collector-pool-healthy.yaml b/.chloggen/add-collector-pool-healthy.yaml new file mode 100755 index 0000000000..1bc8ca48ed --- /dev/null +++ b/.chloggen/add-collector-pool-healthy.yaml @@ -0,0 +1,16 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action) +component: opamp + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add healthy field at collector pool level in opamp bridge heartbeat + +# One or more tracking issues related to the change +issues: [2936] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/.chloggen/cleanup-roles.yaml b/.chloggen/cleanup-roles.yaml new file mode 100755 index 0000000000..51be6f2675 --- /dev/null +++ b/.chloggen/cleanup-roles.yaml @@ -0,0 +1,16 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: bug_fix + +# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action) +component: collector + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Cleanup ClusterRoles and ClusterRoleBindings created by the operator + +# One or more tracking issues related to the change +issues: [2938] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: The operator uses finalizer on the collector to run the cleanup diff --git a/.chloggen/collector-readiness-support.yaml b/.chloggen/collector-readiness-support.yaml new file mode 100644 index 0000000000..e27a8d00d6 --- /dev/null +++ b/.chloggen/collector-readiness-support.yaml @@ -0,0 +1,17 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action) +component: collector + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add support for readinessProbe on OpenTelemetryCollector CRD. + +# One or more tracking issues related to the change +issues: [2943] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: | + Add support for readinessProbe on `OpenTelemetryCollector` and its default similar to the already supported livenessProbe. diff --git a/.chloggen/customized-log-encoder.yaml b/.chloggen/customized-log-encoder.yaml new file mode 100755 index 0000000000..b51a8bc593 --- /dev/null +++ b/.chloggen/customized-log-encoder.yaml @@ -0,0 +1,16 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: 'enhancement' + +# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action) +component: operator + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Enabling new Logs Enconder Configuration parameters. + +# One or more tracking issues related to the change +issues: [268] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/.chloggen/fix-collector-node-selector.yaml b/.chloggen/fix-collector-node-selector.yaml new file mode 100644 index 0000000000..3674ea046c --- /dev/null +++ b/.chloggen/fix-collector-node-selector.yaml @@ -0,0 +1,17 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: bug_fix + +# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action) +component: collector + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Fix to reflect changes of OpenTelemetryCollector.spec.nodeSelector in the collector Pods + +# One or more tracking issues related to the change +issues: [2940] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: | + When updating `OpenTelemetryCollector.spec.nodeSelector` it was not removing previous selector from the final collector pod (Deployment/Daemonset/Statefulset). diff --git a/.chloggen/fix-ta-check-policy.yaml b/.chloggen/fix-ta-check-policy.yaml new file mode 100755 index 0000000000..bb35c6d77a --- /dev/null +++ b/.chloggen/fix-ta-check-policy.yaml @@ -0,0 +1,16 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: 'bug_fix' + +# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action) +component: target-allocator + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Fixed non-expected warnings on TA webhook. + +# One or more tracking issues related to the change +issues: [2685] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/.chloggen/ta-add-https.yaml b/.chloggen/ta-add-https.yaml new file mode 100755 index 0000000000..1c231c3c18 --- /dev/null +++ b/.chloggen/ta-add-https.yaml @@ -0,0 +1,18 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action) +component: target allocator + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Added option for creating an mTLS-configured HTTPS server to fetch scrape config with real secret values. + +# One or more tracking issues related to the change +issues: [1669] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: | + The change introduces an option to create an additional HTTPS server with mTLS configuration. + This server is specifically utilized for obtaining the scrape configuration with actual secret values. diff --git a/.chloggen/verify-prom-crd-resources.yaml b/.chloggen/verify-prom-crd-resources.yaml new file mode 100755 index 0000000000..1adfe693f9 --- /dev/null +++ b/.chloggen/verify-prom-crd-resources.yaml @@ -0,0 +1,16 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: bug_fix + +# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action) +component: collector + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Ensure all Prometheus CRDs are installed + +# One or more tracking issues related to the change +issues: [2964] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/DEBUG.md b/DEBUG.md new file mode 100644 index 0000000000..cba2dd3229 --- /dev/null +++ b/DEBUG.md @@ -0,0 +1,34 @@ +# Debug tips to the OpenTelemetry Operator + +A tip during a troubleshooting process is always welcome. Therefore, we prepared this documentation to help you identify possible issues and improve the application's reliability. + +## Customizing Logs Output +By the default the Operator's log format is console like you can see below: +```bash +2024-05-06T11:55:11+02:00 INFO setup Prometheus CRDs are installed, adding to scheme. +2024-05-06T11:55:11+02:00 INFO setup Openshift CRDs are not installed, skipping adding to scheme. +2024-05-06T11:55:11+02:00 INFO setup the env var WATCH_NAMESPACE isn't set, watching all namespaces +2024-05-06T11:55:11+02:00 INFO Webhooks are disabled, operator is running an unsupported mode {"ENABLE_WEBHOOKS": "false"} +2024-05-06T11:55:11+02:00 INFO setup starting manager +``` + +If it is necessary to customize the log format, so you can use one of the following parameters: +- `--zap-devel`: Development Mode defaults(encoder=consoleEncoder,logLevel=Debug,stackTraceLevel=Warn). Production Mode defaults(encoder=jsonEncoder,logLevel=Info,stackTraceLevel=Error) (default false) +- `--zap-encoder`: Zap log encoding (one of 'json' or 'console') +- `--zap-log-level` Zap Level to configure the verbosity of logging. Can be one of 'debug', 'info', 'error', or any integer value > 0 which corresponds to custom debug levels of increasing verbosity +- `--zap-stacktrace-level` Zap Level at and above which stacktraces are captured (one of 'info', 'error', 'panic'). +- `--zap-time-encoding` Zap time encoding (one of 'epoch', 'millis', 'nano', 'iso8601', 'rfc3339' or 'rfc3339nano'). Defaults to 'epoch'. +- The following parameters are effective only if the `--zap-encoder=json`: + - `zap-message-key`: The message key to be used in the customized Log Encoder + - `zap-level-key`: The level key to be used in the customized Log Encoder + - `zap-time-key`: The time key to be used in the customized Log Encoder + - `zap-level-format`: The level format to be used in the customized Log Encoder + +Running the Operator with the parameters `--zap-encoder=json`, `--zap-message-key="msg"`, `zap-level-key="severity"`,`zap-time-key="timestamp"`,`zap-level-format="uppercase"` you should see the following output: +```bash +{"severity":"INFO","timestamp":"2024-05-07T16:23:35+02:00","logger":"setup","msg":"Prometheus CRDs are installed, adding to scheme."} +{"severity":"INFO","timestamp":"2024-05-07T16:23:35+02:00","logger":"setup","msg":"Openshift CRDs are not installed, skipping adding to scheme."} +{"severity":"INFO","timestamp":"2024-05-07T16:23:35+02:00","logger":"setup","msg":"the env var WATCH_NAMESPACE isn't set, watching all namespaces"} +{"severity":"INFO","timestamp":"2024-05-07T16:23:35+02:00","msg":"Webhooks are disabled, operator is running an unsupported mode","ENABLE_WEBHOOKS":"false"} +{"severity":"INFO","timestamp":"2024-05-07T16:23:35+02:00","logger":"setup","msg":"starting manager"} +``` diff --git a/README.md b/README.md index 9d8a1e40d9..8b175b9c08 100644 --- a/README.md +++ b/README.md @@ -777,16 +777,18 @@ Emeritus Approvers: Target Allocator Maintainers ([@open-telemetry/operator-ta-maintainers](https://github.com/orgs/open-telemetry/teams/operator-ta-maintainers)): -- [Anthony Mirabella](https://github.com/Aneurysm9), AWS - [Kristina Pathak](https://github.com/kristinapathak), Lightstep - [Sebastian Poxhofer](https://github.com/secustor) +Emeritus Target Allocator Maintainers + +- [Anthony Mirabella](https://github.com/Aneurysm9), AWS + Maintainers ([@open-telemetry/operator-maintainers](https://github.com/orgs/open-telemetry/teams/operator-maintainers)): - [Jacob Aronoff](https://github.com/jaronoff97), Lightstep - [Mikołaj Świątek](https://github.com/swiatekm-sumo), Sumo Logic - [Pavol Loffay](https://github.com/pavolloffay), Red Hat -- [Vineeth Pothulapati](https://github.com/VineethReddy02), Timescale Emeritus Maintainers @@ -794,6 +796,7 @@ Emeritus Maintainers - [Bogdan Drutu](https://github.com/BogdanDrutu), Splunk - [Juraci Paixão Kröhling](https://github.com/jpkrohling), Grafana Labs - [Tigran Najaryan](https://github.com/tigrannajaryan), Splunk +- [Vineeth Pothulapati](https://github.com/VineethReddy02), Timescale Learn more about roles in the [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md). diff --git a/RELEASE.md b/RELEASE.md index 9a4ba1d87c..94cfcbd777 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -44,10 +44,9 @@ The operator should be released within a week after the [OpenTelemetry collector | Version | Release manager | |----------|-----------------| -| v0.100.0 | @VineethReddy02 | -| v0.101.0 | @TylerHelmuth | -| v0.102.0 | @swiatekm-sumo | -| v0.103.0 | @frzifus | -| v0.104.0 | @jaronoff97 | -| v0.105.0 | @pavolloffay | -| v0.106.0 | @yuriolisa | +| v0.100.0 | @TylerHelmuth | +| v0.101.0 | @swiatekm-sumo | +| v0.102.0 | @frzifus | +| v0.103.0 | @jaronoff97 | +| v0.104.0 | @pavolloffay | +| v0.105.0 | @yuriolisa | diff --git a/apis/v1beta1/collector_webhook.go b/apis/v1beta1/collector_webhook.go index 99fefdaee8..2c4bc80d85 100644 --- a/apis/v1beta1/collector_webhook.go +++ b/apis/v1beta1/collector_webhook.go @@ -190,7 +190,7 @@ func (c CollectorWebhook) validate(ctx context.Context, r *OpenTelemetryCollecto nullObjects := r.Spec.Config.nullObjects() if len(nullObjects) > 0 { - warnings = append(warnings, fmt.Sprintf("Collector config spec.config has null objects: %s. For compatibility tooling (kustomize and kubectl edit) it is recommended to use empty obejects e.g. batch: {}.", strings.Join(nullObjects, ", "))) + warnings = append(warnings, fmt.Sprintf("Collector config spec.config has null objects: %s. For compatibility with other tooling, such as kustomize and kubectl edit, it is recommended to use empty objects e.g. batch: {}.", strings.Join(nullObjects, ", "))) } // validate volumeClaimTemplates @@ -289,25 +289,14 @@ func (c CollectorWebhook) validate(ctx context.Context, r *OpenTelemetryCollecto return warnings, fmt.Errorf("a valid Ingress hostname has to be defined for subdomain ruleType") } - if r.Spec.LivenessProbe != nil { - if r.Spec.LivenessProbe.InitialDelaySeconds != nil && *r.Spec.LivenessProbe.InitialDelaySeconds < 0 { - return warnings, fmt.Errorf("the OpenTelemetry Spec LivenessProbe InitialDelaySeconds configuration is incorrect. InitialDelaySeconds should be greater than or equal to 0") - } - if r.Spec.LivenessProbe.PeriodSeconds != nil && *r.Spec.LivenessProbe.PeriodSeconds < 1 { - return warnings, fmt.Errorf("the OpenTelemetry Spec LivenessProbe PeriodSeconds configuration is incorrect. PeriodSeconds should be greater than or equal to 1") - } - if r.Spec.LivenessProbe.TimeoutSeconds != nil && *r.Spec.LivenessProbe.TimeoutSeconds < 1 { - return warnings, fmt.Errorf("the OpenTelemetry Spec LivenessProbe TimeoutSeconds configuration is incorrect. TimeoutSeconds should be greater than or equal to 1") - } - if r.Spec.LivenessProbe.SuccessThreshold != nil && *r.Spec.LivenessProbe.SuccessThreshold < 1 { - return warnings, fmt.Errorf("the OpenTelemetry Spec LivenessProbe SuccessThreshold configuration is incorrect. SuccessThreshold should be greater than or equal to 1") - } - if r.Spec.LivenessProbe.FailureThreshold != nil && *r.Spec.LivenessProbe.FailureThreshold < 1 { - return warnings, fmt.Errorf("the OpenTelemetry Spec LivenessProbe FailureThreshold configuration is incorrect. FailureThreshold should be greater than or equal to 1") - } - if r.Spec.LivenessProbe.TerminationGracePeriodSeconds != nil && *r.Spec.LivenessProbe.TerminationGracePeriodSeconds < 1 { - return warnings, fmt.Errorf("the OpenTelemetry Spec LivenessProbe TerminationGracePeriodSeconds configuration is incorrect. TerminationGracePeriodSeconds should be greater than or equal to 1") - } + // validate probes Liveness/Readiness + err := validateProbe("LivenessProbe", r.Spec.LivenessProbe) + if err != nil { + return warnings, err + } + err = validateProbe("ReadinessProbe", r.Spec.ReadinessProbe) + if err != nil { + return warnings, err } // validate updateStrategy for DaemonSet @@ -355,7 +344,7 @@ func (c CollectorWebhook) validateTargetAllocatorConfig(ctx context.Context, r * } // if the prometheusCR is enabled, it needs a suite of permissions to function if r.Spec.TargetAllocator.PrometheusCR.Enabled { - if subjectAccessReviews, err := c.reviewer.CheckPolicyRules(ctx, r.GetNamespace(), r.Spec.TargetAllocator.ServiceAccount, targetAllocatorCRPolicyRules...); err != nil { + if subjectAccessReviews, err := c.reviewer.CheckPolicyRules(ctx, r.Spec.TargetAllocator.ServiceAccount, r.GetNamespace(), targetAllocatorCRPolicyRules...); err != nil { return nil, fmt.Errorf("unable to check rbac rules %w", err) } else if allowed, deniedReviews := rbac.AllSubjectAccessReviewsAllowed(subjectAccessReviews); !allowed { return rbac.WarningsGroupedByResource(deniedReviews), nil @@ -365,6 +354,30 @@ func (c CollectorWebhook) validateTargetAllocatorConfig(ctx context.Context, r * return nil, nil } +func validateProbe(probeName string, probe *Probe) error { + if probe != nil { + if probe.InitialDelaySeconds != nil && *probe.InitialDelaySeconds < 0 { + return fmt.Errorf("the OpenTelemetry Spec %s InitialDelaySeconds configuration is incorrect. InitialDelaySeconds should be greater than or equal to 0", probeName) + } + if probe.PeriodSeconds != nil && *probe.PeriodSeconds < 1 { + return fmt.Errorf("the OpenTelemetry Spec %s PeriodSeconds configuration is incorrect. PeriodSeconds should be greater than or equal to 1", probeName) + } + if probe.TimeoutSeconds != nil && *probe.TimeoutSeconds < 1 { + return fmt.Errorf("the OpenTelemetry Spec %s TimeoutSeconds configuration is incorrect. TimeoutSeconds should be greater than or equal to 1", probeName) + } + if probe.SuccessThreshold != nil && *probe.SuccessThreshold < 1 { + return fmt.Errorf("the OpenTelemetry Spec %s SuccessThreshold configuration is incorrect. SuccessThreshold should be greater than or equal to 1", probeName) + } + if probe.FailureThreshold != nil && *probe.FailureThreshold < 1 { + return fmt.Errorf("the OpenTelemetry Spec %s FailureThreshold configuration is incorrect. FailureThreshold should be greater than or equal to 1", probeName) + } + if probe.TerminationGracePeriodSeconds != nil && *probe.TerminationGracePeriodSeconds < 1 { + return fmt.Errorf("the OpenTelemetry Spec %s TerminationGracePeriodSeconds configuration is incorrect. TerminationGracePeriodSeconds should be greater than or equal to 1", probeName) + } + } + return nil +} + func checkAutoscalerSpec(autoscaler *AutoscalerSpec) error { if autoscaler.Behavior != nil { if autoscaler.Behavior.ScaleDown != nil && autoscaler.Behavior.ScaleDown.StabilizationWindowSeconds != nil && diff --git a/apis/v1beta1/collector_webhook_test.go b/apis/v1beta1/collector_webhook_test.go index 253ae99971..b3b8ade472 100644 --- a/apis/v1beta1/collector_webhook_test.go +++ b/apis/v1beta1/collector_webhook_test.go @@ -72,7 +72,7 @@ func TestValidate(t *testing.T) { }, warnings: []string{ - "Collector config spec.config has null objects: extensions.foo:, processors.batch:, processors.foo:. For compatibility tooling (kustomize and kubectl edit) it is recommended to use empty obejects e.g. batch: {}.", + "Collector config spec.config has null objects: extensions.foo:, processors.batch:, processors.foo:. For compatibility with other tooling, such as kustomize and kubectl edit, it is recommended to use empty objects e.g. batch: {}.", }, }, } @@ -1026,6 +1026,17 @@ func TestOTELColValidatingWebhook(t *testing.T) { }, expectedErr: "the OpenTelemetry Spec LivenessProbe InitialDelaySeconds configuration is incorrect", }, + { + name: "invalid InitialDelaySeconds readiness", + otelcol: OpenTelemetryCollector{ + Spec: OpenTelemetryCollectorSpec{ + ReadinessProbe: &Probe{ + InitialDelaySeconds: &minusOne, + }, + }, + }, + expectedErr: "the OpenTelemetry Spec ReadinessProbe InitialDelaySeconds configuration is incorrect", + }, { name: "invalid PeriodSeconds", otelcol: OpenTelemetryCollector{ @@ -1037,6 +1048,17 @@ func TestOTELColValidatingWebhook(t *testing.T) { }, expectedErr: "the OpenTelemetry Spec LivenessProbe PeriodSeconds configuration is incorrect", }, + { + name: "invalid PeriodSeconds readiness", + otelcol: OpenTelemetryCollector{ + Spec: OpenTelemetryCollectorSpec{ + ReadinessProbe: &Probe{ + PeriodSeconds: &zero, + }, + }, + }, + expectedErr: "the OpenTelemetry Spec ReadinessProbe PeriodSeconds configuration is incorrect", + }, { name: "invalid TimeoutSeconds", otelcol: OpenTelemetryCollector{ @@ -1048,6 +1070,17 @@ func TestOTELColValidatingWebhook(t *testing.T) { }, expectedErr: "the OpenTelemetry Spec LivenessProbe TimeoutSeconds configuration is incorrect", }, + { + name: "invalid TimeoutSeconds readiness", + otelcol: OpenTelemetryCollector{ + Spec: OpenTelemetryCollectorSpec{ + ReadinessProbe: &Probe{ + TimeoutSeconds: &zero, + }, + }, + }, + expectedErr: "the OpenTelemetry Spec ReadinessProbe TimeoutSeconds configuration is incorrect", + }, { name: "invalid SuccessThreshold", otelcol: OpenTelemetryCollector{ @@ -1059,6 +1092,17 @@ func TestOTELColValidatingWebhook(t *testing.T) { }, expectedErr: "the OpenTelemetry Spec LivenessProbe SuccessThreshold configuration is incorrect", }, + { + name: "invalid SuccessThreshold readiness", + otelcol: OpenTelemetryCollector{ + Spec: OpenTelemetryCollectorSpec{ + ReadinessProbe: &Probe{ + SuccessThreshold: &zero, + }, + }, + }, + expectedErr: "the OpenTelemetry Spec ReadinessProbe SuccessThreshold configuration is incorrect", + }, { name: "invalid FailureThreshold", otelcol: OpenTelemetryCollector{ @@ -1070,6 +1114,17 @@ func TestOTELColValidatingWebhook(t *testing.T) { }, expectedErr: "the OpenTelemetry Spec LivenessProbe FailureThreshold configuration is incorrect", }, + { + name: "invalid FailureThreshold readiness", + otelcol: OpenTelemetryCollector{ + Spec: OpenTelemetryCollectorSpec{ + ReadinessProbe: &Probe{ + FailureThreshold: &zero, + }, + }, + }, + expectedErr: "the OpenTelemetry Spec ReadinessProbe FailureThreshold configuration is incorrect", + }, { name: "invalid TerminationGracePeriodSeconds", otelcol: OpenTelemetryCollector{ @@ -1081,6 +1136,17 @@ func TestOTELColValidatingWebhook(t *testing.T) { }, expectedErr: "the OpenTelemetry Spec LivenessProbe TerminationGracePeriodSeconds configuration is incorrect", }, + { + name: "invalid TerminationGracePeriodSeconds readiness", + otelcol: OpenTelemetryCollector{ + Spec: OpenTelemetryCollectorSpec{ + ReadinessProbe: &Probe{ + TerminationGracePeriodSeconds: &zero64, + }, + }, + }, + expectedErr: "the OpenTelemetry Spec ReadinessProbe TerminationGracePeriodSeconds configuration is incorrect", + }, { name: "invalid AdditionalContainers", otelcol: OpenTelemetryCollector{ diff --git a/apis/v1beta1/opentelemetrycollector_types.go b/apis/v1beta1/opentelemetrycollector_types.go index 4421165944..141178895f 100644 --- a/apis/v1beta1/opentelemetrycollector_types.go +++ b/apis/v1beta1/opentelemetrycollector_types.go @@ -103,6 +103,10 @@ type OpenTelemetryCollectorSpec struct { // It is only effective when healthcheckextension is configured in the OpenTelemetry Collector pipeline. // +optional LivenessProbe *Probe `json:"livenessProbe,omitempty"` + // Readiness config for the OpenTelemetry Collector except the probe handler which is auto generated from the health extension of the collector. + // It is only effective when healthcheckextension is configured in the OpenTelemetry Collector pipeline. + // +optional + ReadinessProbe *Probe `json:"readinessProbe,omitempty"` // ObservabilitySpec defines how telemetry data gets handled. // @@ -206,7 +210,7 @@ type TargetAllocatorEmbedded struct { PodDisruptionBudget *PodDisruptionBudgetSpec `json:"podDisruptionBudget,omitempty"` } -// Probe defines the OpenTelemetry's pod probe config. Only Liveness probe is supported currently. +// Probe defines the OpenTelemetry's pod probe config. type Probe struct { // Number of seconds after the container has started before liveness probes are initiated. // Defaults to 0 seconds. Minimum value is 0. diff --git a/apis/v1beta1/zz_generated.deepcopy.go b/apis/v1beta1/zz_generated.deepcopy.go index c5e574127c..9690ef897d 100644 --- a/apis/v1beta1/zz_generated.deepcopy.go +++ b/apis/v1beta1/zz_generated.deepcopy.go @@ -306,6 +306,11 @@ func (in *OpenTelemetryCollectorSpec) DeepCopyInto(out *OpenTelemetryCollectorSp *out = new(Probe) (*in).DeepCopyInto(*out) } + if in.ReadinessProbe != nil { + in, out := &in.ReadinessProbe, &out.ReadinessProbe + *out = new(Probe) + (*in).DeepCopyInto(*out) + } out.Observability = in.Observability if in.ConfigMaps != nil { in, out := &in.ConfigMaps, &out.ConfigMaps diff --git a/bundle/manifests/opentelemetry.io_opentelemetrycollectors.yaml b/bundle/manifests/opentelemetry.io_opentelemetrycollectors.yaml index 5688544892..092ca2428e 100644 --- a/bundle/manifests/opentelemetry.io_opentelemetrycollectors.yaml +++ b/bundle/manifests/opentelemetry.io_opentelemetrycollectors.yaml @@ -6654,6 +6654,27 @@ spec: x-kubernetes-list-type: atomic priorityClassName: type: string + readinessProbe: + properties: + failureThreshold: + format: int32 + type: integer + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object replicas: format: int32 type: integer diff --git a/cmd/operator-opamp-bridge/agent/agent.go b/cmd/operator-opamp-bridge/agent/agent.go index cab16f7728..792c2d23de 100644 --- a/cmd/operator-opamp-bridge/agent/agent.go +++ b/cmd/operator-opamp-bridge/agent/agent.go @@ -119,11 +119,17 @@ func (agent *Agent) generateCollectorPoolHealth() (map[string]*protobufs.Compone if err != nil { return nil, err } + + isPoolHealthy := true + for _, pod := range podMap { + isPoolHealthy = isPoolHealthy && pod.Healthy + } healthMap[key.String()] = &protobufs.ComponentHealth{ StartTimeUnixNano: uint64(col.ObjectMeta.GetCreationTimestamp().UnixNano()), StatusTimeUnixNano: uint64(agent.clock.Now().UnixNano()), Status: col.Status.Scale.StatusReplicas, ComponentHealthMap: podMap, + Healthy: isPoolHealthy, } } return healthMap, nil diff --git a/cmd/operator-opamp-bridge/agent/agent_test.go b/cmd/operator-opamp-bridge/agent/agent_test.go index d883e49965..75d533eae1 100644 --- a/cmd/operator-opamp-bridge/agent/agent_test.go +++ b/cmd/operator-opamp-bridge/agent/agent_test.go @@ -272,7 +272,7 @@ func TestAgent_getHealth(t *testing.T) { StatusTimeUnixNano: uint64(fakeClock.Now().UnixNano()), ComponentHealthMap: map[string]*protobufs.ComponentHealth{ "testnamespace/collector": { - Healthy: false, // we're working with mocks so the status will never be reconciled. + Healthy: true, StartTimeUnixNano: collectorStartTime, LastError: "", Status: "", @@ -305,7 +305,7 @@ func TestAgent_getHealth(t *testing.T) { StatusTimeUnixNano: uint64(fakeClock.Now().UnixNano()), ComponentHealthMap: map[string]*protobufs.ComponentHealth{ "testnamespace/collector": { - Healthy: false, // we're working with mocks so the status will never be reconciled. + Healthy: true, StartTimeUnixNano: collectorStartTime, LastError: "", Status: "", @@ -313,7 +313,7 @@ func TestAgent_getHealth(t *testing.T) { ComponentHealthMap: map[string]*protobufs.ComponentHealth{}, }, "testnamespace/other": { - Healthy: false, // we're working with mocks so the status will never be reconciled. + Healthy: true, StartTimeUnixNano: collectorStartTime, LastError: "", Status: "", @@ -345,7 +345,7 @@ func TestAgent_getHealth(t *testing.T) { StatusTimeUnixNano: uint64(fakeClock.Now().UnixNano()), ComponentHealthMap: map[string]*protobufs.ComponentHealth{ "other/third": { - Healthy: false, // we're working with mocks so the status will never be reconciled. + Healthy: true, StartTimeUnixNano: collectorStartTime, LastError: "", Status: "", diff --git a/cmd/otel-allocator/config/config.go b/cmd/otel-allocator/config/config.go index 03368d1b60..e772eadc45 100644 --- a/cmd/otel-allocator/config/config.go +++ b/cmd/otel-allocator/config/config.go @@ -15,6 +15,8 @@ package config import ( + "crypto/tls" + "crypto/x509" "errors" "fmt" "io/fs" @@ -53,6 +55,7 @@ type Config struct { AllocationStrategy string `yaml:"allocation_strategy,omitempty"` FilterStrategy string `yaml:"filter_strategy,omitempty"` PrometheusCR PrometheusCRConfig `yaml:"prometheus_cr,omitempty"` + HTTPS HTTPSServerConfig `yaml:"https,omitempty"` } type PrometheusCRConfig struct { @@ -64,6 +67,14 @@ type PrometheusCRConfig struct { ScrapeInterval model.Duration `yaml:"scrape_interval,omitempty"` } +type HTTPSServerConfig struct { + Enabled bool `yaml:"enabled,omitempty"` + ListenAddr string `yaml:"listen_addr,omitempty"` + CAFilePath string `yaml:"ca_file_path,omitempty"` + TLSCertFilePath string `yaml:"tls_cert_file_path,omitempty"` + TLSKeyFilePath string `yaml:"tls_key_file_path,omitempty"` +} + func LoadFromFile(file string, target *Config) error { return unmarshal(target, file) } @@ -103,6 +114,31 @@ func LoadFromCLI(target *Config, flagSet *pflag.FlagSet) error { return err } + target.HTTPS.Enabled, err = getHttpsEnabled(flagSet) + if err != nil { + return err + } + + target.HTTPS.ListenAddr, err = getHttpsListenAddr(flagSet) + if err != nil { + return err + } + + target.HTTPS.CAFilePath, err = getHttpsCAFilePath(flagSet) + if err != nil { + return err + } + + target.HTTPS.TLSCertFilePath, err = getHttpsTLSCertFilePath(flagSet) + if err != nil { + return err + } + + target.HTTPS.TLSKeyFilePath, err = getHttpsTLSKeyFilePath(flagSet) + if err != nil { + return err + } + return nil } @@ -164,3 +200,26 @@ func ValidateConfig(config *Config) error { } return nil } + +func (c HTTPSServerConfig) NewTLSConfig() (*tls.Config, error) { + cert, err := tls.LoadX509KeyPair(c.TLSCertFilePath, c.TLSKeyFilePath) + if err != nil { + return nil, err + } + + caCert, err := os.ReadFile(c.CAFilePath) + if err != nil { + return nil, err + } + + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + + tlsConfig := &tls.Config{ + Certificates: []tls.Certificate{cert}, + ClientAuth: tls.RequireAndVerifyClientCert, + ClientCAs: caCertPool, + MinVersion: tls.VersionTLS12, + } + return tlsConfig, nil +} diff --git a/cmd/otel-allocator/config/config_test.go b/cmd/otel-allocator/config/config_test.go index fda73793e2..fec1bcdd36 100644 --- a/cmd/otel-allocator/config/config_test.go +++ b/cmd/otel-allocator/config/config_test.go @@ -61,6 +61,12 @@ func TestLoad(t *testing.T) { PrometheusCR: PrometheusCRConfig{ ScrapeInterval: model.Duration(time.Second * 60), }, + HTTPS: HTTPSServerConfig{ + Enabled: true, + CAFilePath: "/path/to/ca.pem", + TLSCertFilePath: "/path/to/cert.pem", + TLSKeyFilePath: "/path/to/key.pem", + }, PromConfig: &promconfig.Config{ GlobalConfig: promconfig.GlobalConfig{ ScrapeInterval: model.Duration(60 * time.Second), diff --git a/cmd/otel-allocator/config/flags.go b/cmd/otel-allocator/config/flags.go index bb7dbbb344..9a928cb958 100644 --- a/cmd/otel-allocator/config/flags.go +++ b/cmd/otel-allocator/config/flags.go @@ -25,11 +25,16 @@ import ( // Flag names. const ( - targetAllocatorName = "target-allocator" - configFilePathFlagName = "config-file" - listenAddrFlagName = "listen-addr" - prometheusCREnabledFlagName = "enable-prometheus-cr-watcher" - kubeConfigPathFlagName = "kubeconfig-path" + targetAllocatorName = "target-allocator" + configFilePathFlagName = "config-file" + listenAddrFlagName = "listen-addr" + prometheusCREnabledFlagName = "enable-prometheus-cr-watcher" + kubeConfigPathFlagName = "kubeconfig-path" + httpsEnabledFlagName = "enable-https-server" + listenAddrHttpsFlagName = "listen-addr-https" + httpsCAFilePathFlagName = "https-ca-file" + httpsTLSCertFilePathFlagName = "https-tls-cert-file" + httpsTLSKeyFilePathFlagName = "https-tls-key-file" ) // We can't bind this flag to our FlagSet, so we need to handle it separately. @@ -41,6 +46,11 @@ func getFlagSet(errorHandling pflag.ErrorHandling) *pflag.FlagSet { flagSet.String(listenAddrFlagName, ":8080", "The address where this service serves.") flagSet.Bool(prometheusCREnabledFlagName, false, "Enable Prometheus CRs as target sources") flagSet.String(kubeConfigPathFlagName, filepath.Join(homedir.HomeDir(), ".kube", "config"), "absolute path to the KubeconfigPath file") + flagSet.Bool(httpsEnabledFlagName, false, "Enable HTTPS additional server") + flagSet.String(listenAddrHttpsFlagName, ":8443", "The address where this service serves over HTTPS.") + flagSet.String(httpsCAFilePathFlagName, "", "The path to the HTTPS server TLS CA file.") + flagSet.String(httpsTLSCertFilePathFlagName, "", "The path to the HTTPS server TLS certificate file.") + flagSet.String(httpsTLSKeyFilePathFlagName, "", "The path to the HTTPS server TLS key file.") zapFlagSet := flag.NewFlagSet("", flag.ErrorHandling(errorHandling)) zapCmdLineOpts.BindFlags(zapFlagSet) flagSet.AddGoFlagSet(zapFlagSet) @@ -62,3 +72,23 @@ func getListenAddr(flagSet *pflag.FlagSet) (string, error) { func getPrometheusCREnabled(flagSet *pflag.FlagSet) (bool, error) { return flagSet.GetBool(prometheusCREnabledFlagName) } + +func getHttpsListenAddr(flagSet *pflag.FlagSet) (string, error) { + return flagSet.GetString(listenAddrHttpsFlagName) +} + +func getHttpsEnabled(flagSet *pflag.FlagSet) (bool, error) { + return flagSet.GetBool(httpsEnabledFlagName) +} + +func getHttpsCAFilePath(flagSet *pflag.FlagSet) (string, error) { + return flagSet.GetString(httpsCAFilePathFlagName) +} + +func getHttpsTLSCertFilePath(flagSet *pflag.FlagSet) (string, error) { + return flagSet.GetString(httpsTLSCertFilePathFlagName) +} + +func getHttpsTLSKeyFilePath(flagSet *pflag.FlagSet) (string, error) { + return flagSet.GetString(httpsTLSKeyFilePathFlagName) +} diff --git a/cmd/otel-allocator/config/flags_test.go b/cmd/otel-allocator/config/flags_test.go index b1bf11b6ce..fe83863569 100644 --- a/cmd/otel-allocator/config/flags_test.go +++ b/cmd/otel-allocator/config/flags_test.go @@ -70,6 +70,18 @@ func TestFlagGetters(t *testing.T) { expectedErr: true, getterFunc: func(fs *pflag.FlagSet) (interface{}, error) { return getConfigFilePath(fs) }, }, + { + name: "HttpsServer", + flagArgs: []string{"--" + httpsEnabledFlagName, "true"}, + expectedValue: true, + getterFunc: func(fs *pflag.FlagSet) (interface{}, error) { return getHttpsEnabled(fs) }, + }, + { + name: "HttpsServerKey", + flagArgs: []string{"--" + httpsTLSKeyFilePathFlagName, "/path/to/tls.key"}, + expectedValue: "/path/to/tls.key", + getterFunc: func(fs *pflag.FlagSet) (interface{}, error) { return getHttpsTLSKeyFilePath(fs) }, + }, } for _, tt := range tests { diff --git a/cmd/otel-allocator/config/testdata/config_test.yaml b/cmd/otel-allocator/config/testdata/config_test.yaml index 8d4a427133..6f55a99dac 100644 --- a/cmd/otel-allocator/config/testdata/config_test.yaml +++ b/cmd/otel-allocator/config/testdata/config_test.yaml @@ -4,6 +4,11 @@ collector_selector: app.kubernetes.io/managed-by: opentelemetry-operator prometheus_cr: scrape_interval: 60s +https: + enabled: true + ca_file_path: /path/to/ca.pem + tls_cert_file_path: /path/to/cert.pem + tls_key_file_path: /path/to/key.pem config: scrape_configs: - job_name: prometheus diff --git a/cmd/otel-allocator/main.go b/cmd/otel-allocator/main.go index efb43e541c..f9531d6740 100644 --- a/cmd/otel-allocator/main.go +++ b/cmd/otel-allocator/main.go @@ -86,7 +86,17 @@ func main() { setupLog.Error(err, "Unable to initialize allocation strategy") os.Exit(1) } - srv := server.NewServer(log, allocator, cfg.ListenAddr) + + httpOptions := []server.Option{} + if cfg.HTTPS.Enabled { + tlsConfig, confErr := cfg.HTTPS.NewTLSConfig() + if confErr != nil { + setupLog.Error(confErr, "Unable to initialize TLS configuration") + os.Exit(1) + } + httpOptions = append(httpOptions, server.WithTLSConfig(tlsConfig, cfg.HTTPS.ListenAddr)) + } + srv := server.NewServer(log, allocator, cfg.ListenAddr, httpOptions...) discoveryCtx, discoveryCancel := context.WithCancel(ctx) sdMetrics, err := discovery.CreateAndRegisterSDMetrics(prometheus.DefaultRegisterer) @@ -189,6 +199,20 @@ func main() { setupLog.Error(shutdownErr, "Error on server shutdown") } }) + if cfg.HTTPS.Enabled { + runGroup.Add( + func() error { + err := srv.StartHTTPS() + setupLog.Info("HTTPS Server failed to start") + return err + }, + func(_ error) { + setupLog.Info("Closing HTTPS server") + if shutdownErr := srv.ShutdownHTTPS(ctx); shutdownErr != nil { + setupLog.Error(shutdownErr, "Error on HTTPS server shutdown") + } + }) + } runGroup.Add( func() error { for { diff --git a/cmd/otel-allocator/server/server.go b/cmd/otel-allocator/server/server.go index 90771839a8..33e845103f 100644 --- a/cmd/otel-allocator/server/server.go +++ b/cmd/otel-allocator/server/server.go @@ -16,6 +16,7 @@ package server import ( "context" + "crypto/tls" "encoding/json" "fmt" "net/http" @@ -32,6 +33,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" + promcommconfig "github.com/prometheus/common/config" promconfig "github.com/prometheus/prometheus/config" "gopkg.in/yaml.v2" @@ -63,28 +65,36 @@ type Server struct { logger logr.Logger allocator allocation.Allocator server *http.Server + httpsServer *http.Server jsonMarshaller jsoniter.API // Use RWMutex to protect scrapeConfigResponse, since it // will be predominantly read and only written when config // is applied. - mtx sync.RWMutex - scrapeConfigResponse []byte + mtx sync.RWMutex + scrapeConfigResponse []byte + ScrapeConfigMarshalledSecretResponse []byte } -func NewServer(log logr.Logger, allocator allocation.Allocator, listenAddr string) *Server { - s := &Server{ - logger: log, - allocator: allocator, - jsonMarshaller: jsonConfig, +type Option func(*Server) + +// Option to create an additional https server with mTLS configuration. +// Used for getting the scrape config with real secret values. +func WithTLSConfig(tlsConfig *tls.Config, httpsListenAddr string) Option { + return func(s *Server) { + httpsRouter := gin.New() + s.setRouter(httpsRouter) + + s.httpsServer = &http.Server{Addr: httpsListenAddr, Handler: httpsRouter, ReadHeaderTimeout: 90 * time.Second, TLSConfig: tlsConfig} } +} - gin.SetMode(gin.ReleaseMode) - router := gin.New() +func (s *Server) setRouter(router *gin.Engine) { router.Use(gin.Recovery()) router.UseRawPath = true router.UnescapePathValues = false router.Use(s.PrometheusMiddleware) + router.GET("/scrape_configs", s.ScrapeConfigsHandler) router.GET("/jobs", s.JobHandler) router.GET("/jobs/:job_id/targets", s.TargetsHandler) @@ -92,8 +102,25 @@ func NewServer(log logr.Logger, allocator allocation.Allocator, listenAddr strin router.GET("/livez", s.LivenessProbeHandler) router.GET("/readyz", s.ReadinessProbeHandler) registerPprof(router.Group("/debug/pprof/")) +} + +func NewServer(log logr.Logger, allocator allocation.Allocator, listenAddr string, options ...Option) *Server { + s := &Server{ + logger: log, + allocator: allocator, + jsonMarshaller: jsonConfig, + } + + gin.SetMode(gin.ReleaseMode) + router := gin.New() + s.setRouter(router) s.server = &http.Server{Addr: listenAddr, Handler: router, ReadHeaderTimeout: 90 * time.Second} + + for _, opt := range options { + opt(s) + } + return s } @@ -107,6 +134,16 @@ func (s *Server) Shutdown(ctx context.Context) error { return s.server.Shutdown(ctx) } +func (s *Server) StartHTTPS() error { + s.logger.Info("Starting HTTPS server...") + return s.httpsServer.ListenAndServeTLS("", "") +} + +func (s *Server) ShutdownHTTPS(ctx context.Context) error { + s.logger.Info("Shutting down HTTPS server...") + return s.httpsServer.Shutdown(ctx) +} + // RemoveRegexFromRelabelAction is needed specifically for keepequal/dropequal actions because even though the user doesn't specify the // regex field for these actions the unmarshalling implementations of prometheus adds back the default regex fields // which in turn causes the receiver to error out since the unmarshaling of the json response doesn't expect anything in the regex fields @@ -151,15 +188,14 @@ func RemoveRegexFromRelabelAction(jsonConfig []byte) ([]byte, error) { return jsonConfigNew, nil } -// UpdateScrapeConfigResponse updates the scrape config response. The target allocator first marshals these -// configurations such that the underlying prometheus marshaling is used. After that, the YAML is converted -// in to a JSON format for consumers to use. -func (s *Server) UpdateScrapeConfigResponse(configs map[string]*promconfig.ScrapeConfig) error { - var configBytes []byte +func (s *Server) MarshalScrapeConfig(configs map[string]*promconfig.ScrapeConfig, marshalSecretValue bool) error { + promcommconfig.MarshalSecretValue = marshalSecretValue + configBytes, err := yaml.Marshal(configs) if err != nil { return err } + var jsonConfig []byte jsonConfig, err = yaml2.YAMLToJSON(configBytes) if err != nil { @@ -172,8 +208,28 @@ func (s *Server) UpdateScrapeConfigResponse(configs map[string]*promconfig.Scrap } s.mtx.Lock() - s.scrapeConfigResponse = jsonConfigNew + if marshalSecretValue { + s.ScrapeConfigMarshalledSecretResponse = jsonConfigNew + } else { + s.scrapeConfigResponse = jsonConfigNew + } s.mtx.Unlock() + + return nil +} + +// UpdateScrapeConfigResponse updates the scrape config response. The target allocator first marshals these +// configurations such that the underlying prometheus marshaling is used. After that, the YAML is converted +// in to a JSON format for consumers to use. +func (s *Server) UpdateScrapeConfigResponse(configs map[string]*promconfig.ScrapeConfig) error { + err := s.MarshalScrapeConfig(configs, false) + if err != nil { + return err + } + err = s.MarshalScrapeConfig(configs, true) + if err != nil { + return err + } return nil } @@ -181,6 +237,9 @@ func (s *Server) UpdateScrapeConfigResponse(configs map[string]*promconfig.Scrap func (s *Server) ScrapeConfigsHandler(c *gin.Context) { s.mtx.RLock() result := s.scrapeConfigResponse + if c.Request.TLS != nil { + result = s.ScrapeConfigMarshalledSecretResponse + } s.mtx.RUnlock() // We don't use the jsonHandler method because we don't want our bytes to be re-encoded diff --git a/cmd/otel-allocator/server/server_test.go b/cmd/otel-allocator/server/server_test.go index 1a83875cf5..88b8ad9368 100644 --- a/cmd/otel-allocator/server/server_test.go +++ b/cmd/otel-allocator/server/server_test.go @@ -15,6 +15,7 @@ package server import ( + "crypto/tls" "encoding/json" "fmt" "io" @@ -194,11 +195,14 @@ func TestServer_TargetsHandler(t *testing.T) { } func TestServer_ScrapeConfigsHandler(t *testing.T) { + svrConfig := allocatorconfig.HTTPSServerConfig{} + tlsConfig, _ := svrConfig.NewTLSConfig() tests := []struct { description string scrapeConfigs map[string]*promconfig.ScrapeConfig expectedCode int expectedBody []byte + serverOptions []Option }{ { description: "nil scrape config", @@ -455,17 +459,67 @@ func TestServer_ScrapeConfigsHandler(t *testing.T) { }, expectedCode: http.StatusOK, }, + { + description: "https secret handling", + scrapeConfigs: map[string]*promconfig.ScrapeConfig{ + "serviceMonitor/testapp/testapp3/0": { + JobName: "serviceMonitor/testapp/testapp3/0", + HonorTimestamps: true, + ScrapeInterval: model.Duration(30 * time.Second), + ScrapeTimeout: model.Duration(30 * time.Second), + MetricsPath: "/metrics", + Scheme: "http", + HTTPClientConfig: config.HTTPClientConfig{ + FollowRedirects: true, + BasicAuth: &config.BasicAuth{ + Username: "test", + Password: "P@$$w0rd1!?", + }, + }, + }, + }, + expectedCode: http.StatusOK, + serverOptions: []Option{ + WithTLSConfig(tlsConfig, ""), + }, + }, + { + description: "http secret handling", + scrapeConfigs: map[string]*promconfig.ScrapeConfig{ + "serviceMonitor/testapp/testapp3/0": { + JobName: "serviceMonitor/testapp/testapp3/0", + HonorTimestamps: true, + ScrapeInterval: model.Duration(30 * time.Second), + ScrapeTimeout: model.Duration(30 * time.Second), + MetricsPath: "/metrics", + Scheme: "http", + HTTPClientConfig: config.HTTPClientConfig{ + FollowRedirects: true, + BasicAuth: &config.BasicAuth{ + Username: "test", + Password: "P@$$w0rd1!?", + }, + }, + }, + }, + expectedCode: http.StatusOK, + }, } for _, tc := range tests { t.Run(tc.description, func(t *testing.T) { listenAddr := ":8080" - s := NewServer(logger, nil, listenAddr) + s := NewServer(logger, nil, listenAddr, tc.serverOptions...) assert.NoError(t, s.UpdateScrapeConfigResponse(tc.scrapeConfigs)) request := httptest.NewRequest("GET", "/scrape_configs", nil) w := httptest.NewRecorder() - s.server.Handler.ServeHTTP(w, request) + if s.httpsServer != nil { + request.TLS = &tls.ConnectionState{} + s.httpsServer.Handler.ServeHTTP(w, request) + } else { + s.server.Handler.ServeHTTP(w, request) + } result := w.Result() assert.Equal(t, tc.expectedCode, result.StatusCode) @@ -478,6 +532,19 @@ func TestServer_ScrapeConfigsHandler(t *testing.T) { scrapeConfigs := map[string]*promconfig.ScrapeConfig{} err = yaml.Unmarshal(bodyBytes, scrapeConfigs) require.NoError(t, err) + + for _, c := range scrapeConfigs { + if s.httpsServer == nil && c.HTTPClientConfig.BasicAuth != nil { + assert.Equal(t, c.HTTPClientConfig.BasicAuth.Password, config.Secret("")) + } + } + + for _, c := range tc.scrapeConfigs { + if s.httpsServer == nil && c.HTTPClientConfig.BasicAuth != nil { + c.HTTPClientConfig.BasicAuth.Password = "" + } + } + assert.Equal(t, tc.scrapeConfigs, scrapeConfigs) }) } diff --git a/config/crd/bases/opentelemetry.io_opentelemetrycollectors.yaml b/config/crd/bases/opentelemetry.io_opentelemetrycollectors.yaml index 03a1360bfa..ad8c35a81b 100644 --- a/config/crd/bases/opentelemetry.io_opentelemetrycollectors.yaml +++ b/config/crd/bases/opentelemetry.io_opentelemetrycollectors.yaml @@ -6640,6 +6640,27 @@ spec: x-kubernetes-list-type: atomic priorityClassName: type: string + readinessProbe: + properties: + failureThreshold: + format: int32 + type: integer + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object replicas: format: int32 type: integer diff --git a/controllers/common.go b/controllers/common.go index 7885fa8a3a..7a2763002d 100644 --- a/controllers/common.go +++ b/controllers/common.go @@ -122,9 +122,18 @@ func reconcileDesiredObjects(ctx context.Context, kubeClient client.Client, logg if len(errs) > 0 { return fmt.Errorf("failed to create objects for %s: %w", owner.GetName(), errors.Join(errs...)) } + // Pruning owned objects in the cluster which are not should not be present after the reconciliation. + err := deleteObjects(ctx, kubeClient, logger, ownedObjects) + if err != nil { + return fmt.Errorf("failed to prune objects for %s: %w", owner.GetName(), err) + } + return nil +} + +func deleteObjects(ctx context.Context, kubeClient client.Client, logger logr.Logger, objects map[types.UID]client.Object) error { // Pruning owned objects in the cluster which are not should not be present after the reconciliation. pruneErrs := []error{} - for _, obj := range ownedObjects { + for _, obj := range objects { l := logger.WithValues( "object_name", obj.GetName(), "object_kind", obj.GetObjectKind().GroupVersionKind(), @@ -137,8 +146,5 @@ func reconcileDesiredObjects(ctx context.Context, kubeClient client.Client, logg pruneErrs = append(pruneErrs, err) } } - if len(pruneErrs) > 0 { - return fmt.Errorf("failed to prune objects for %s: %w", owner.GetName(), errors.Join(pruneErrs...)) - } - return nil + return errors.Join(pruneErrs...) } diff --git a/controllers/opentelemetrycollector_controller.go b/controllers/opentelemetrycollector_controller.go index a713e15dfd..56e229b50b 100644 --- a/controllers/opentelemetrycollector_controller.go +++ b/controllers/opentelemetrycollector_controller.go @@ -35,6 +35,7 @@ import ( "k8s.io/client-go/tools/record" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "github.com/open-telemetry/opentelemetry-operator/apis/v1beta1" "github.com/open-telemetry/opentelemetry-operator/internal/autodetect/openshift" @@ -127,7 +128,42 @@ func (r *OpenTelemetryCollectorReconciler) findOtelOwnedObjects(ctx context.Cont for i := range pdbList.Items { ownedObjects[pdbList.Items[i].GetUID()] = &pdbList.Items[i] } + if params.Config.CreateRBACPermissions() == rbac.Available { + clusterObjects, err := r.findClusterRoleObjects(ctx, params) + if err != nil { + return nil, err + } + for k, v := range clusterObjects { + ownedObjects[k] = v + } + } + return ownedObjects, nil +} +// The cluster scope objects do not have owner reference. +func (r *OpenTelemetryCollectorReconciler) findClusterRoleObjects(ctx context.Context, params manifests.Params) (map[types.UID]client.Object, error) { + ownedObjects := map[types.UID]client.Object{} + // Remove cluster roles and bindings. + // Users might switch off the RBAC creation feature on the operator which should remove existing RBAC. + listOpsCluster := &client.ListOptions{ + LabelSelector: labels.SelectorFromSet(manifestutils.SelectorLabels(params.OtelCol.ObjectMeta, collector.ComponentOpenTelemetryCollector)), + } + clusterroleList := &rbacv1.ClusterRoleList{} + err := r.List(ctx, clusterroleList, listOpsCluster) + if err != nil { + return nil, fmt.Errorf("error listing ClusterRoles: %w", err) + } + for i := range clusterroleList.Items { + ownedObjects[clusterroleList.Items[i].GetUID()] = &clusterroleList.Items[i] + } + clusterrolebindingList := &rbacv1.ClusterRoleBindingList{} + err = r.List(ctx, clusterrolebindingList, listOpsCluster) + if err != nil { + return nil, fmt.Errorf("error listing ClusterRoleBIndings: %w", err) + } + for i := range clusterrolebindingList.Items { + ownedObjects[clusterrolebindingList.Items[i].GetUID()] = &clusterrolebindingList.Items[i] + } return ownedObjects, nil } @@ -193,8 +229,32 @@ func (r *OpenTelemetryCollectorReconciler) Reconcile(ctx context.Context, req ct // on deleted requests. return ctrl.Result{}, client.IgnoreNotFound(err) } + + params, err := r.getParams(instance) + if err != nil { + log.Error(err, "Failed to create manifest.Params") + return ctrl.Result{}, err + } + // We have a deletion, short circuit and let the deletion happen if deletionTimestamp := instance.GetDeletionTimestamp(); deletionTimestamp != nil { + if controllerutil.ContainsFinalizer(&instance, collectorFinalizer) { + // If the finalization logic fails, don't remove the finalizer so + // that we can retry during the next reconciliation. + if err = r.finalizeCollector(ctx, params); err != nil { + return ctrl.Result{}, err + } + + // Once all finalizers have been + // removed, the object will be deleted. + if controllerutil.RemoveFinalizer(&instance, collectorFinalizer) { + err = r.Update(ctx, &instance) + if err != nil { + return ctrl.Result{}, err + } + } + } + return ctrl.Result{}, nil } @@ -204,10 +264,14 @@ func (r *OpenTelemetryCollectorReconciler) Reconcile(ctx context.Context, req ct return ctrl.Result{}, nil } - params, err := r.getParams(instance) - if err != nil { - log.Error(err, "Failed to create manifest.Params") - return ctrl.Result{}, err + // Add finalizer for this CR + if !controllerutil.ContainsFinalizer(&instance, collectorFinalizer) { + if controllerutil.AddFinalizer(&instance, collectorFinalizer) { + err = r.Update(ctx, &instance) + if err != nil { + return ctrl.Result{}, err + } + } } desiredObjects, buildErr := BuildCollector(params) @@ -255,3 +319,17 @@ func (r *OpenTelemetryCollectorReconciler) SetupWithManager(mgr ctrl.Manager) er return builder.Complete(r) } + +const collectorFinalizer = "opentelemetrycollector.opentelemetry.io/finalizer" + +func (r *OpenTelemetryCollectorReconciler) finalizeCollector(ctx context.Context, params manifests.Params) error { + // The cluster scope objects do not have owner reference. They need to be deleted explicitly + if params.Config.CreateRBACPermissions() == rbac.Available { + objects, err := r.findClusterRoleObjects(ctx, params) + if err != nil { + return err + } + return deleteObjects(ctx, r.Client, r.log, objects) + } + return nil +} diff --git a/controllers/reconcile_test.go b/controllers/reconcile_test.go index 8dd272e77f..db6cfb267b 100644 --- a/controllers/reconcile_test.go +++ b/controllers/reconcile_test.go @@ -28,6 +28,7 @@ import ( v1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" policyV1 "k8s.io/api/policy/v1" + rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" @@ -43,6 +44,7 @@ import ( "github.com/open-telemetry/opentelemetry-operator/controllers" "github.com/open-telemetry/opentelemetry-operator/internal/autodetect/openshift" "github.com/open-telemetry/opentelemetry-operator/internal/autodetect/prometheus" + autoRBAC "github.com/open-telemetry/opentelemetry-operator/internal/autodetect/rbac" "github.com/open-telemetry/opentelemetry-operator/internal/config" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" ta "github.com/open-telemetry/opentelemetry-operator/internal/manifests/targetallocator/adapters" @@ -73,14 +75,14 @@ var ( type check[T any] func(t *testing.T, params T) func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { - addedMetadataDeployment := testCollectorWithMode(v1alpha1.ModeDeployment) + addedMetadataDeployment := testCollectorWithMode("test-deployment", v1alpha1.ModeDeployment) addedMetadataDeployment.Labels = map[string]string{ labelName: labelVal, } addedMetadataDeployment.Annotations = map[string]string{ annotationName: annotationVal, } - deploymentExtraPorts := testCollectorWithModeAndReplicas(v1alpha1.ModeDeployment, 3) + deploymentExtraPorts := testCollectorWithModeAndReplicas("test-deployment", v1alpha1.ModeDeployment, 3) deploymentExtraPorts.Spec.Ports = append(deploymentExtraPorts.Spec.Ports, extraPorts) deploymentExtraPorts.Spec.DeploymentUpdateStrategy = appsv1.DeploymentStrategy{ RollingUpdate: &appsv1.RollingUpdateDeployment{ @@ -94,20 +96,20 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { }, }, } - ingressParams := testCollectorAssertNoErr(t, "", testFileIngress) + ingressParams := testCollectorAssertNoErr(t, "test-ingress", "", testFileIngress) ingressParams.Spec.Ingress.Type = "ingress" - updatedIngressParams := testCollectorAssertNoErr(t, "", testFileIngress) + updatedIngressParams := testCollectorAssertNoErr(t, "test-ingress", "", testFileIngress) updatedIngressParams.Spec.Ingress.Type = "ingress" updatedIngressParams.Spec.Ingress.Annotations = map[string]string{"blub": "blob"} updatedIngressParams.Spec.Ingress.Hostname = expectHostname - routeParams := testCollectorAssertNoErr(t, "", testFileIngress) + routeParams := testCollectorAssertNoErr(t, "test-route", "", testFileIngress) routeParams.Spec.Ingress.Type = v1alpha1.IngressTypeRoute routeParams.Spec.Ingress.Route.Termination = v1alpha1.TLSRouteTerminationTypeInsecure - updatedRouteParams := testCollectorAssertNoErr(t, "", testFileIngress) + updatedRouteParams := testCollectorAssertNoErr(t, "test-route", "", testFileIngress) updatedRouteParams.Spec.Ingress.Type = v1alpha1.IngressTypeRoute updatedRouteParams.Spec.Ingress.Route.Termination = v1alpha1.TLSRouteTerminationTypeInsecure updatedRouteParams.Spec.Ingress.Hostname = expectHostname - deletedParams := testCollectorWithMode(v1alpha1.ModeDeployment) + deletedParams := testCollectorWithMode("test2", v1alpha1.ModeDeployment) now := metav1.NewTime(time.Now()) deletedParams.DeletionTimestamp = &now @@ -158,7 +160,7 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { assert.True(t, exists) assert.Equal(t, svc.Spec.Selector, map[string]string{ "app.kubernetes.io/component": "opentelemetry-collector", - "app.kubernetes.io/instance": "default.test", + "app.kubernetes.io/instance": "default.test-deployment", "app.kubernetes.io/managed-by": "opentelemetry-operator", "app.kubernetes.io/part-of": "opentelemetry", }) @@ -192,7 +194,7 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { assert.Contains(t, actual.Spec.Ports, extraPorts.ServicePort) assert.Equal(t, actual.Spec.Selector, map[string]string{ "app.kubernetes.io/component": "opentelemetry-collector", - "app.kubernetes.io/instance": "default.test", + "app.kubernetes.io/instance": "default.test-deployment", "app.kubernetes.io/managed-by": "opentelemetry-operator", "app.kubernetes.io/part-of": "opentelemetry", }) @@ -206,7 +208,7 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { { name: "invalid mode", args: args{ - params: testCollectorWithMode("bad"), + params: testCollectorWithMode("test-invalid", "bad"), updates: []v1alpha1.OpenTelemetryCollector{}, }, want: []want{ @@ -223,7 +225,7 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { { name: "invalid prometheus configuration", args: args{ - params: testCollectorAssertNoErr(t, baseTaImage, testFileIngress), + params: testCollectorAssertNoErr(t, "test-invalid-prom", baseTaImage, testFileIngress), updates: []v1alpha1.OpenTelemetryCollector{}, }, want: []want{ @@ -285,7 +287,7 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { checks: []check[v1alpha1.OpenTelemetryCollector]{ func(t *testing.T, params v1alpha1.OpenTelemetryCollector) { got := routev1.Route{} - nsn := types.NamespacedName{Namespace: params.Namespace, Name: "otlp-grpc-test-route"} + nsn := types.NamespacedName{Namespace: params.Namespace, Name: "otlp-grpc-test-route-route"} exists, err := populateObjectIfExists(t, &got, nsn) assert.NoError(t, err) assert.True(t, exists) @@ -299,7 +301,7 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { checks: []check[v1alpha1.OpenTelemetryCollector]{ func(t *testing.T, params v1alpha1.OpenTelemetryCollector) { got := routev1.Route{} - nsn := types.NamespacedName{Namespace: params.Namespace, Name: "otlp-grpc-test-route"} + nsn := types.NamespacedName{Namespace: params.Namespace, Name: "otlp-grpc-test-route-route"} exists, err := populateObjectIfExists(t, &got, nsn) assert.NoError(t, err) assert.True(t, exists) @@ -396,7 +398,7 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { { name: "daemonset collector", args: args{ - params: testCollectorWithMode(v1alpha1.ModeDaemonSet), + params: testCollectorWithMode("test-daemonset", v1alpha1.ModeDaemonSet), }, want: []want{ { @@ -416,11 +418,11 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { { name: "stateful should update collector with TA", args: args{ - params: testCollectorWithMode(v1alpha1.ModeStatefulSet), + params: testCollectorWithMode("test-stateful-ta", v1alpha1.ModeStatefulSet), updates: []v1alpha1.OpenTelemetryCollector{ - testCollectorAssertNoErr(t, baseTaImage, promFile), - testCollectorAssertNoErr(t, baseTaImage, updatedPromFile), - testCollectorAssertNoErr(t, updatedTaImage, updatedPromFile), + testCollectorAssertNoErr(t, "test-stateful-ta", baseTaImage, promFile), + testCollectorAssertNoErr(t, "test-stateful-ta", baseTaImage, updatedPromFile), + testCollectorAssertNoErr(t, "test-stateful-ta", updatedTaImage, updatedPromFile), }, }, want: []want{ @@ -463,13 +465,13 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { exists, err = populateObjectIfExists(t, &v1.ServiceAccount{}, namespacedObjectName(naming.TargetAllocatorServiceAccount(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) - promConfig, err := ta.ConfigToPromConfig(testCollectorAssertNoErr(t, baseTaImage, promFile).Spec.Config) + promConfig, err := ta.ConfigToPromConfig(testCollectorAssertNoErr(t, "test-stateful-ta", baseTaImage, promFile).Spec.Config) assert.NoError(t, err) taConfig := make(map[interface{}]interface{}) taConfig["collector_selector"] = metav1.LabelSelector{ MatchLabels: map[string]string{ - "app.kubernetes.io/instance": "default.test", + "app.kubernetes.io/instance": "default.test-stateful-ta", "app.kubernetes.io/managed-by": "opentelemetry-operator", "app.kubernetes.io/component": "opentelemetry-collector", "app.kubernetes.io/part-of": "opentelemetry", @@ -681,7 +683,7 @@ func TestOpAMPBridgeReconciler_Reconcile(t *testing.T) { exists, err = populateObjectIfExists(t, &v1.Service{}, namespacedObjectName(naming.OpAMPBridgeService(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) - exists, err = populateObjectIfExists(t, &v1.ServiceAccount{}, namespacedObjectName(naming.ServiceAccount(params.Name), params.Namespace)) + exists, err = populateObjectIfExists(t, &v1.ServiceAccount{}, namespacedObjectName(naming.OpAMPBridgeServiceAccount(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) }, @@ -821,6 +823,94 @@ func TestRegisterWithManager(t *testing.T) { assert.NoError(t, err) } +func TestOpenTelemetryCollectorReconciler_Finalizer(t *testing.T) { + otelcol := &v1alpha1.OpenTelemetryCollector{ + ObjectMeta: metav1.ObjectMeta{ + Name: "otel-k8sattrs", + Namespace: "test-finalizer", + }, + Spec: v1alpha1.OpenTelemetryCollectorSpec{ + Mode: v1alpha1.ModeDeployment, + Config: ` +processors: + k8sattributes: +receivers: + otlp: + protocols: + grpc: + +exporters: + debug: + +service: + pipelines: + traces: + receivers: [otlp] + processors: [k8sattributes] + exporters: [debug] +`, + }, + } + + ns := &v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: otelcol.Namespace, + }, + } + clientErr := k8sClient.Create(context.Background(), ns) + require.NoError(t, clientErr) + clientErr = k8sClient.Create(context.Background(), otelcol) + require.NoError(t, clientErr) + + reconciler := controllers.NewReconciler(controllers.Params{ + Client: k8sClient, + Log: logger, + Scheme: testScheme, + Recorder: record.NewFakeRecorder(20), + Config: config.New( + config.WithCollectorImage("default-collector"), + config.WithTargetAllocatorImage("default-ta-allocator"), + config.WithRBACPermissions(autoRBAC.Available), + ), + }) + + nsn := types.NamespacedName{Name: otelcol.Name, Namespace: otelcol.Namespace} + req := k8sreconcile.Request{ + NamespacedName: nsn, + } + reconcile, reconcileErr := reconciler.Reconcile(context.Background(), req) + require.NoError(t, reconcileErr) + require.False(t, reconcile.Requeue) + + colClusterRole := &rbacv1.ClusterRole{} + clientErr = k8sClient.Get(context.Background(), types.NamespacedName{ + Name: naming.ClusterRole(otelcol.Name, otelcol.Namespace), + }, colClusterRole) + require.NoError(t, clientErr) + colClusterRoleBinding := &rbacv1.ClusterRoleBinding{} + clientErr = k8sClient.Get(context.Background(), types.NamespacedName{ + Name: naming.ClusterRoleBinding(otelcol.Name, otelcol.Namespace), + }, colClusterRoleBinding) + require.NoError(t, clientErr) + + // delete collector and check if the cluster role was deleted + clientErr = k8sClient.Delete(context.Background(), otelcol) + require.NoError(t, clientErr) + + reconcile, reconcileErr = reconciler.Reconcile(context.Background(), req) + require.NoError(t, reconcileErr) + require.False(t, reconcile.Requeue) + + clientErr = k8sClient.Get(context.Background(), types.NamespacedName{ + Name: naming.ClusterRole(otelcol.Name, otelcol.Namespace), + }, colClusterRole) + require.Error(t, clientErr) + clientErr = k8sClient.Get(context.Background(), types.NamespacedName{ + Name: naming.ClusterRoleBinding(otelcol.Name, otelcol.Namespace), + }, colClusterRoleBinding) + require.Error(t, clientErr) +} + func namespacedObjectName(name string, namespace string) types.NamespacedName { return types.NamespacedName{ Namespace: namespace, diff --git a/controllers/suite_test.go b/controllers/suite_test.go index a9d82248e9..b9c2aebfce 100644 --- a/controllers/suite_test.go +++ b/controllers/suite_test.go @@ -235,12 +235,12 @@ func TestMain(m *testing.M) { os.Exit(code) } -func testCollectorWithMode(mode v1alpha1.Mode) v1alpha1.OpenTelemetryCollector { +func testCollectorWithMode(name string, mode v1alpha1.Mode) v1alpha1.OpenTelemetryCollector { replicas := int32(2) - return testCollectorWithModeAndReplicas(mode, replicas) + return testCollectorWithModeAndReplicas(name, mode, replicas) } -func testCollectorWithModeAndReplicas(mode v1alpha1.Mode, replicas int32) v1alpha1.OpenTelemetryCollector { +func testCollectorWithModeAndReplicas(name string, mode v1alpha1.Mode, replicas int32) v1alpha1.OpenTelemetryCollector { configYAML, err := os.ReadFile("testdata/test.yaml") if err != nil { fmt.Printf("Error getting yaml file: %v", err) @@ -251,7 +251,7 @@ func testCollectorWithModeAndReplicas(mode v1alpha1.Mode, replicas int32) v1alph APIVersion: "v1", }, ObjectMeta: metav1.ObjectMeta{ - Name: "test", + Name: name, Namespace: "default", }, Spec: v1alpha1.OpenTelemetryCollectorSpec{ @@ -273,8 +273,8 @@ func testCollectorWithModeAndReplicas(mode v1alpha1.Mode, replicas int32) v1alph } } -func testCollectorAssertNoErr(t *testing.T, taContainerImage string, file string) v1alpha1.OpenTelemetryCollector { - p, err := testCollectorWithConfigFile(taContainerImage, file) +func testCollectorAssertNoErr(t *testing.T, name string, taContainerImage string, file string) v1alpha1.OpenTelemetryCollector { + p, err := testCollectorWithConfigFile(name, taContainerImage, file) assert.NoError(t, err) if len(taContainerImage) == 0 { p.Spec.TargetAllocator.Enabled = false @@ -282,7 +282,7 @@ func testCollectorAssertNoErr(t *testing.T, taContainerImage string, file string return p } -func testCollectorWithConfigFile(taContainerImage string, file string) (v1alpha1.OpenTelemetryCollector, error) { +func testCollectorWithConfigFile(name string, taContainerImage string, file string) (v1alpha1.OpenTelemetryCollector, error) { replicas := int32(1) var configYAML []byte var err error @@ -301,7 +301,7 @@ func testCollectorWithConfigFile(taContainerImage string, file string) (v1alpha1 APIVersion: "v1", }, ObjectMeta: metav1.ObjectMeta{ - Name: "test", + Name: name, Namespace: "default", }, Spec: v1alpha1.OpenTelemetryCollectorSpec{ diff --git a/docs/api.md b/docs/api.md index 06494cbf29..c6ca926ef6 100644 --- a/docs/api.md +++ b/docs/api.md @@ -30145,6 +30145,14 @@ If not specified, the pod priority will be default or zero if there is no default.
false + + readinessProbe + object + + Readiness config for the OpenTelemetry Collector except the probe handler which is auto generated from the health extension of the collector. +It is only effective when healthcheckextension is configured in the OpenTelemetry Collector pipeline.
+ + false replicas integer @@ -40138,6 +40146,97 @@ More info: https://kubernetes.io/docs/concepts/services-networking/service/#defi +### OpenTelemetryCollector.spec.readinessProbe +[↩ Parent](#opentelemetrycollectorspec-1) + + + +Readiness config for the OpenTelemetry Collector except the probe handler which is auto generated from the health extension of the collector. +It is only effective when healthcheckextension is configured in the OpenTelemetry Collector pipeline. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
failureThresholdinteger + Minimum consecutive failures for the probe to be considered failed after having succeeded. +Defaults to 3. Minimum value is 1.
+
+ Format: int32
+
false
initialDelaySecondsinteger + Number of seconds after the container has started before liveness probes are initiated. +Defaults to 0 seconds. Minimum value is 0. +More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+
+ Format: int32
+
false
periodSecondsinteger + How often (in seconds) to perform the probe. +Default to 10 seconds. Minimum value is 1.
+
+ Format: int32
+
false
successThresholdinteger + Minimum consecutive successes for the probe to be considered successful after having failed. +Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.
+
+ Format: int32
+
false
terminationGracePeriodSecondsinteger + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. +The grace period is the duration in seconds after the processes running in the pod are sent +a termination signal and the time when the processes are forcibly halted with a kill signal. +Set this value longer than the expected cleanup time for your process. +If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this +value overrides the value provided by the pod spec. +Value must be non-negative integer. The value zero indicates stop immediately via +the kill signal (no opportunity to shut down). +This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. +Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.
+
+ Format: int64
+
false
timeoutSecondsinteger + Number of seconds after which the probe times out. +Defaults to 1 second. Minimum value is 1. +More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+
+ Format: int32
+
false
+ + ### OpenTelemetryCollector.spec.resources [↩ Parent](#opentelemetrycollectorspec-1) diff --git a/go.mod b/go.mod index 20aad7b197..24a05ad3f2 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/buraksezer/consistent v0.10.0 github.com/cespare/xxhash/v2 v2.3.0 github.com/ghodss/yaml v1.0.0 - github.com/gin-gonic/gin v1.9.1 + github.com/gin-gonic/gin v1.10.0 github.com/go-kit/log v0.2.1 github.com/go-logr/logr v1.4.1 github.com/json-iterator/go v1.1.12 @@ -22,13 +22,13 @@ require ( github.com/prometheus-operator/prometheus-operator v0.71.2 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.72.0 github.com/prometheus-operator/prometheus-operator/pkg/client v0.72.0 - github.com/prometheus/client_golang v1.19.0 + github.com/prometheus/client_golang v1.19.1 github.com/prometheus/common v0.53.0 - github.com/prometheus/prometheus v0.51.2 + github.com/prometheus/prometheus v0.52.0 github.com/shirou/gopsutil v3.21.11+incompatible github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 - go.opentelemetry.io/collector/featuregate v1.3.0 + go.opentelemetry.io/collector/featuregate v1.5.0 go.opentelemetry.io/otel v1.26.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.26.0 go.opentelemetry.io/otel/metric v1.26.0 @@ -50,32 +50,35 @@ require ( ) require ( - cloud.google.com/go/compute v1.24.0 // indirect - cloud.google.com/go/compute/metadata v0.2.3 // indirect - 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 + cloud.google.com/go/auth v0.2.0 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.0 // indirect + cloud.google.com/go/compute/metadata v0.3.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect - github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.5.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.6.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0 // indirect - github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 // indirect - github.com/Code-Hex/go-generics-cache v1.3.1 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect + github.com/Code-Hex/go-generics-cache v1.5.1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/aws/aws-sdk-go v1.50.32 // indirect + github.com/aws/aws-sdk-go v1.51.25 // indirect github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/bytedance/sonic v1.9.1 // indirect + github.com/bytedance/sonic v1.11.6 // indirect + github.com/bytedance/sonic/loader v0.1.1 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dennwc/varint v1.0.0 // indirect - github.com/digitalocean/godo v1.109.0 // indirect + github.com/digitalocean/godo v1.113.0 // indirect github.com/distribution/reference v0.5.0 // indirect - github.com/docker/docker v25.0.5+incompatible // indirect + github.com/docker/docker v26.0.2+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/edsrzf/mmap-go v1.1.0 // indirect @@ -89,30 +92,30 @@ require ( github.com/fatih/color v1.15.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/analysis v0.22.2 // indirect - github.com/go-openapi/errors v0.21.1 // indirect + github.com/go-openapi/errors v0.22.0 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect github.com/go-openapi/jsonreference v0.20.4 // indirect github.com/go-openapi/loads v0.21.5 // indirect github.com/go-openapi/runtime v0.27.1 // indirect github.com/go-openapi/spec v0.20.14 // indirect - github.com/go-openapi/strfmt v0.22.2 // indirect + github.com/go-openapi/strfmt v0.23.0 // indirect github.com/go-openapi/swag v0.22.9 // indirect github.com/go-openapi/validate v0.23.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.14.0 // indirect - github.com/go-resty/resty/v2 v2.11.0 // indirect + github.com/go-playground/validator/v10 v10.20.0 // indirect + github.com/go-resty/resty/v2 v2.12.0 // indirect github.com/go-zookeeper/zk v1.0.3 // indirect github.com/goccy/go-json v0.10.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/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect @@ -123,8 +126,8 @@ require ( github.com/google/s2a-go v0.1.7 // indirect github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect - github.com/googleapis/gax-go/v2 v2.12.2 // indirect - github.com/gophercloud/gophercloud v1.8.0 // indirect + github.com/googleapis/gax-go/v2 v2.12.3 // indirect + github.com/gophercloud/gophercloud v1.11.0 // indirect github.com/gorilla/websocket v1.5.1 // indirect github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect @@ -139,28 +142,29 @@ require ( github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/golang-lru v0.6.0 // indirect - github.com/hashicorp/nomad/api v0.0.0-20240306004928-3e7191ccb702 // indirect + github.com/hashicorp/nomad/api v0.0.0-20240418183417-ea5f2f6748c7 // indirect github.com/hashicorp/serf v0.10.1 // indirect - github.com/hetznercloud/hcloud-go/v2 v2.6.0 // indirect + github.com/hetznercloud/hcloud-go/v2 v2.7.2 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ionos-cloud/sdk-go/v6 v6.1.11 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect - github.com/klauspost/compress v1.17.7 // indirect - github.com/klauspost/cpuid/v2 v2.2.5 // indirect + github.com/klauspost/compress v1.17.8 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b // indirect github.com/kylelemons/godebug v1.1.0 // indirect - github.com/leodido/go-urn v1.2.4 // indirect - github.com/linode/linodego v1.29.0 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/linode/linodego v1.32.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a // indirect - github.com/miekg/dns v1.1.58 // indirect + github.com/miekg/dns v1.1.59 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/moby/docker-image-spec v1.3.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect @@ -170,7 +174,7 @@ require ( github.com/opencontainers/image-spec v1.0.2 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/ovh/go-ovh v1.4.3 // indirect - github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect @@ -179,44 +183,43 @@ require ( github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common/sigv4 v0.1.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect - github.com/scaleway/scaleway-sdk-go v1.0.0-beta.25 // indirect + github.com/scaleway/scaleway-sdk-go v1.0.0-beta.26 // indirect github.com/spf13/cobra v1.7.0 // indirect github.com/tklauser/go-sysconf v0.3.13 // indirect github.com/tklauser/numcpus v0.7.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.11 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect github.com/vultr/govultr/v2 v2.17.2 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.mongodb.org/mongo-driver v1.14.0 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 // indirect go.opentelemetry.io/otel/trace v1.26.0 // indirect go.opentelemetry.io/proto/otlp v1.2.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/goleak v1.3.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.21.0 // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/crypto v0.23.0 // indirect golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect - golang.org/x/mod v0.16.0 // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/oauth2 v0.18.0 // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.19.0 // indirect - golang.org/x/term v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/oauth2 v0.19.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/term v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.19.0 // indirect + golang.org/x/tools v0.20.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/api v0.168.0 // indirect - google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240304212257-790db918fca8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect + google.golang.org/api v0.174.0 // 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 + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - k8s.io/kube-openapi v0.0.0-20240221221325-2ac9dc51f3f1 // indirect + k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect ) diff --git a/go.sum b/go.sum index dd71ff5e6f..27abe09e4c 100644 --- a/go.sum +++ b/go.sum @@ -13,16 +13,18 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go/auth v0.2.0 h1:y6oTcpMSbOcXbwYgUUrvI+mrQ2xbrcdpPgtVbCGTLTk= +cloud.google.com/go/auth v0.2.0/go.mod h1:+yb+oy3/P0geX6DLKlqiGHARGR6EX2GRtYCzWOCQSbU= +cloud.google.com/go/auth/oauth2adapt v0.2.0 h1:FR8zevgQwu+8CqiOT5r6xCmJa3pJC/wdXEEPF1OkNhA= +cloud.google.com/go/auth/oauth2adapt v0.2.0/go.mod h1:AfqujpDAlTfLfeCIl/HJZZlIxD8+nJoZ5e0x1IxGq5k= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= -cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= -cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= @@ -37,14 +39,14 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -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= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1/go.mod h1:h8hyGFDsU5HMivxiS2iYFZsgDbU9OnnJ163x5UGVKYo= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 h1:E+OJmp2tPvt1W+amx48v1eqbjDYsgN+RzP4q16yV5eM= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1/go.mod h1:a6xsAQUZg+VsS3TJ05SRp524Hs4pZ/AeFSr5ENf0Yjo= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2 h1:FDif4R1+UUR+00q6wquyX90K7A8dN+R5E8GEadoP7sU= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2/go.mod h1:aiYBYui4BJ/BJCAIKs92XiPyQfTaBWqvHujDwKb6CBU= github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 h1:LqbJ/WzJUwBf8UiaSzgX7aMclParm9/5Vgp+TY51uBQ= github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2/go.mod h1:yInRyqWXAuaPrgI7p70+lDDgh3mlBohis29jGMISnmc= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.5.0 h1:MxA59PGoCFb+vCwRQi3PhQEwHj4+r2dhuv9HG+vM7iM= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.5.0/go.mod h1:uYt4CfhkJA9o0FN7jfE5minm/i4nUE4MjGUJkzB6Zs8= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.6.0 h1:ui3YNbxfW7J3tTFIZMH6LIGRjCngp+J+nIFlnizfNTE= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.6.0/go.mod h1:gZmgV+qBqygoznvqo2J9oKZAFziqhLZ2xE/WVUmzkHA= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0 h1:PTFGRSlMKCQelWwxUyYVEUqseBJVemLyqWJjvMyt0do= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0/go.mod h1:LRr2FzBTQlONPPa5HREE5+RjSCTXl7BwOvYOaWTqCaI= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0 h1:bXwSugBiSbgtz7rOtbfGf+woewp4f06orW9OP5BjHLA= @@ -53,12 +55,12 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1. github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.1.1/go.mod h1:c/wcGeGx5FUPbM/JltUYHZcKmigwyVLJlDq+4HdtXaw= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -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/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/Code-Hex/go-generics-cache v1.3.1 h1:i8rLwyhoyhaerr7JpjtYjJZUcCbWOdiYO3fZXLiEC4g= -github.com/Code-Hex/go-generics-cache v1.3.1/go.mod h1:qxcC9kRVrct9rHeiYpFWSoW1vxyillCVzX13KZG8dl4= +github.com/Code-Hex/go-generics-cache v1.5.1 h1:6vhZGc5M7Y/YD8cIUcY8kcuQLB4cHR7U+0KMqAA0KcU= +github.com/Code-Hex/go-generics-cache v1.5.1/go.mod h1:qxcC9kRVrct9rHeiYpFWSoW1vxyillCVzX13KZG8dl4= github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= @@ -81,8 +83,8 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go v1.50.32 h1:POt81DvegnpQKM4DMDLlHz1CO6OBnEoQ1gRhYFd7QRY= -github.com/aws/aws-sdk-go v1.50.32/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.51.25 h1:DjTT8mtmsachhV6yrXR8+yhnG6120dazr720nopRsls= +github.com/aws/aws-sdk-go v1.51.25/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3 h1:6df1vn4bBlDDo4tARvBm7l6KA9iVMnE3NWizDeWSrps= github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3/go.mod h1:CIWtjkly68+yqLPbvwwR/fjNJA/idrtULjZWh2v1ys0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -94,24 +96,26 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/buraksezer/consistent v0.10.0 h1:hqBgz1PvNLC5rkWcEBVAL9dFMBWz6I0VgUCW25rrZlU= github.com/buraksezer/consistent v0.10.0/go.mod h1:6BrVajWq7wbKZlTOUPs/XVfR8c0maujuPowduSpZqmw= -github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= -github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= +github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= +github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= 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.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 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/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= @@ -124,14 +128,14 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE= github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA= -github.com/digitalocean/godo v1.109.0 h1:4W97RJLJSUQ3veRZDNbp1Ol3Rbn6Lmt9bKGvfqYI5SU= -github.com/digitalocean/godo v1.109.0/go.mod h1:R6EmmWI8CT1+fCtjWY9UCB+L5uufuZH13wk3YhxycCs= +github.com/digitalocean/godo v1.113.0 h1:CLtCxlP4wDAjKIQ+Hshht/UNbgAp8/J/XBH1ZtDCF9Y= +github.com/digitalocean/godo v1.113.0/go.mod h1:Z2mTP848Vi3IXXl5YbPekUgr4j4tOePomA+OE1Ag98w= github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/docker v25.0.5+incompatible h1:UmQydMduGkrD5nQde1mecF/YnSbTOaPeFIeP5C4W+DE= -github.com/docker/docker v25.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v26.0.2+incompatible h1:yGVmKUFGgcxA6PXWAokO0sQL22BrQ67cgVjko8tGdXE= +github.com/docker/docker v26.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -165,14 +169,14 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= -github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= +github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -197,8 +201,8 @@ github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/analysis v0.22.2 h1:ZBmNoP2h5omLKr/srIC9bfqrUGzT6g6gNv03HE9Vpj0= github.com/go-openapi/analysis v0.22.2/go.mod h1:pDF4UbZsQTo/oNuRfAWWd4dAh4yuYf//LYorPTjrpvo= -github.com/go-openapi/errors v0.21.1 h1:rVisxQPdETctjlYntm0Ek4dKf68nAQocCloCT50vWuI= -github.com/go-openapi/errors v0.21.1/go.mod h1:LyiY9bgc7AVVh6wtVvMYEyoj3KJYNoRw92mmvnMWgj8= +github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w= +github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE= 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/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= @@ -209,8 +213,8 @@ github.com/go-openapi/runtime v0.27.1 h1:ae53yaOoh+fx/X5Eaq8cRmavHgDma65XPZuvBqv github.com/go-openapi/runtime v0.27.1/go.mod h1:fijeJEiEclyS8BRurYE1DE5TLb9/KZl6eAdbzjsrlLU= github.com/go-openapi/spec v0.20.14 h1:7CBlRnw+mtjFGlPDRZmAMnq35cRzI91xj03HVyUi/Do= github.com/go-openapi/spec v0.20.14/go.mod h1:8EOhTpBoFiask8rrgwbLC3zmJfz4zsCUueRuPM6GNkw= -github.com/go-openapi/strfmt v0.22.2 h1:DPYOrm6gexCfZZfXUaXFS4+Jw6HAaIIG0SZ5630f8yw= -github.com/go-openapi/strfmt v0.22.2/go.mod h1:HB/b7TCm91rno75Dembc1dFW/0FPLk5CEXsoF9ReNc4= +github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c= +github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4= github.com/go-openapi/swag v0.22.9 h1:XX2DssF+mQKM2DHsbgZK74y/zj4mo9I99+89xUmuZCE= github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE= github.com/go-openapi/validate v0.23.0 h1:2l7PJLzCis4YUGEoW6eoQw3WhyM65WSIcjX6SQnlfDw= @@ -221,10 +225,10 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= -github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8= -github.com/go-resty/resty/v2 v2.11.0/go.mod h1:iiP/OpA0CkcL3IGt1O0+/SIItFUbkkyw5BGXiVdTu+A= +github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= +github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-resty/resty/v2 v2.12.0 h1:rsVL8P90LFvkUYq/V5BTVe203WfRIU4gvcf+yfzJzGA= +github.com/go-resty/resty/v2 v2.12.0/go.mod h1:o0yGPrkS3lOe1+eFajk6kBW8ScXzwU3hD69/gt2yB/0= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= @@ -235,8 +239,8 @@ github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MG github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 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/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -264,8 +268,6 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -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/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= @@ -304,8 +306,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7 h1:y3N7Bm7Y9/CtpiVkw/ZWj6lSlDF3F74SfKwfTCer72Q= -github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20240416155748-26353dc0451f h1:WpZiq8iqvGjJ3m3wzAVKL6+0vz7VkE79iSy9GII00II= +github.com/google/pprof v0.0.0-20240416155748-26353dc0451f/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= @@ -316,10 +318,10 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= -github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= -github.com/gophercloud/gophercloud v1.8.0 h1:TM3Jawprb2NrdOnvcHhWJalmKmAmOGgfZElM/3oBYCk= -github.com/gophercloud/gophercloud v1.8.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= +github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= +github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= +github.com/gophercloud/gophercloud v1.11.0 h1:ls0O747DIq1D8SUHc7r2vI8BFbMLeLFuENaAIfEx7OM= +github.com/gophercloud/gophercloud v1.11.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww= @@ -374,12 +376,12 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= -github.com/hashicorp/nomad/api v0.0.0-20240306004928-3e7191ccb702 h1:fI1LXuBaS1d9z1kmb++Og6YD8uMRwadXorCwE+xgOFA= -github.com/hashicorp/nomad/api v0.0.0-20240306004928-3e7191ccb702/go.mod h1:z71gkJdrkAt/Rl6C7Q79VE7AwJ5lUF+M+fzFTyIHYB0= +github.com/hashicorp/nomad/api v0.0.0-20240418183417-ea5f2f6748c7 h1:pjE59CS2C9Bg+Xby0ROrnZSSBWtKwx3Sf9gqsrvIFSA= +github.com/hashicorp/nomad/api v0.0.0-20240418183417-ea5f2f6748c7/go.mod h1:svtxn6QnrQ69P23VvIWMR34tg3vmwLz4UdUzm1dSCgE= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= -github.com/hetznercloud/hcloud-go/v2 v2.6.0 h1:RJOA2hHZ7rD1pScA4O1NF6qhkHyUdbbxjHgFNot8928= -github.com/hetznercloud/hcloud-go/v2 v2.6.0/go.mod h1:4J1cSE57+g0WS93IiHLV7ubTHItcp+awzeBp5bM9mfA= +github.com/hetznercloud/hcloud-go/v2 v2.7.2 h1:UlE7n1GQZacCfyjv9tDVUN7HZfOXErPIfM/M039u9A0= +github.com/hetznercloud/hcloud-go/v2 v2.7.2/go.mod h1:49tIV+pXRJTUC7fbFZ03s45LKqSQdOPP5y91eOnJo/k= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= @@ -387,8 +389,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ionos-cloud/sdk-go/v6 v6.1.11 h1:J/uRN4UWO3wCyGOeDdMKv8LWRzKu6UIkLEaes38Kzh8= github.com/ionos-cloud/sdk-go/v6 v6.1.11/go.mod h1:EzEgRIDxBELvfoa/uBN0kOQaqovLjUWEB7iW4/Q+t4k= -github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc= -github.com/jarcoal/httpmock v1.3.0/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= +github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww= +github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= @@ -409,11 +411,12 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= -github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= -github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -428,10 +431,10 @@ 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= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/linode/linodego v1.29.0 h1:gDSQWAbKMAQX8db9FDCXHhodQPrJmLcmthjx6m+PyV4= -github.com/linode/linodego v1.29.0/go.mod h1:3k6WvCM10gillgYcnoLqIL23ST27BD9HhMsCJWb3Bpk= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/linode/linodego v1.32.0 h1:OmZzB3iON6uu84VtLFf64uKmAQqJJarvmsVguroioPI= +github.com/linode/linodego v1.32.0/go.mod h1:y8GDP9uLVH4jTB9qyrgw79qfKdYJmNCGUOJmfuiOcmI= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -447,8 +450,8 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g= github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM= @@ -456,8 +459,8 @@ github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a h1:0usWxe5SGXKQo github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a/go.mod h1:3OETvrxfELvGsU2RoGGWercfeZ4bCL3+SOwzIWtJH/Q= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= -github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= +github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs= +github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -466,6 +469,8 @@ github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= +github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -510,8 +515,8 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= 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.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -539,8 +544,8 @@ github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3O github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -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_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -563,15 +568,15 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/prometheus/prometheus v0.51.2 h1:U0faf1nT4CB9DkBW87XLJCBi2s8nwWXdTbyzRUAkX0w= -github.com/prometheus/prometheus v0.51.2/go.mod h1:yv4MwOn3yHMQ6MZGHPg/U7Fcyqf+rxqiZfSur6myVtc= +github.com/prometheus/prometheus v0.52.0 h1:f7kHJgr7+zShpWdTCeKqbCWR7nKTScgLYQwRux9h1V0= +github.com/prometheus/prometheus v0.52.0/go.mod h1:3z74cVsmVH0iXOR5QBjB7Pa6A0KJeEAK5A6UsmAFb1g= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 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/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.25 h1:/8rfZAdFfafRXOgz+ZpMZZWZ5pYggCY9t7e/BvjaBHM= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.25/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.26 h1:F+GIVtGqCFxPxO46ujf8cEOP574MBoRm3gNbPXECbxs= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.26/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= @@ -602,8 +607,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= 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.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 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/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4= @@ -613,8 +617,8 @@ github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDgu github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs= github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -633,18 +637,18 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/collector/featuregate v1.3.0 h1:nrFSx+zfjdisjE9oCx25Aep3nJ9RaUjeE1qFL6eovoU= -go.opentelemetry.io/collector/featuregate v1.3.0/go.mod h1:mm8+xyQfgDmqhyegZRNIQmoKsNnDTwWKFLsdMoXAb7A= -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/collector/featuregate v1.5.0 h1:uK8qnYQKz1TMkK+FDTFsywg/EybW/gbnOUaPNUkRznM= +go.opentelemetry.io/collector/featuregate v1.5.0/go.mod h1:w7nUODKxEi3FLf1HslCiE6YWtMtOOrMnSwsDam8Mg9w= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 h1:cEPbyTSEHlQR89XVlyo78gqluF8Y3oMeBkXGWzQsfXY= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0/go.mod h1:DKdbWcT4GH1D0Y3Sqt/PFXt2naRKDWtU+eE6oLdFNA8= 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/otlpmetric/otlpmetrichttp v1.26.0 h1:HGZWGmCVRCVyAs2GQaiHQPbDHo+ObFWeUEOd+zDnp64= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.26.0/go.mod h1:SaH+v38LSCHddyk7RGlU9uZyQoRrKao6IBnJw6Kbn+c= -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/otlptracehttp v1.24.0 h1:Xw8U6u2f8DK2XAkGRFV7BBLENgnTGX9i4rQRxJf+/vs= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0/go.mod h1:6KW1Fm6R/s6Z3PGXwSJN2K4eT6wQB3vXX6CVnYX9NmM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0 h1:dT33yIHtmsqpixFsSQPwNeY5drM9wTcoL8h0FWF4oGM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0/go.mod h1:h95q0LBGh7hlAC08X2DhSeyIG02YQ0UyioTCVAqRPmc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.25.0 h1:Mbi5PKN7u322woPa85d7ebZ+SOvEoPvoiBu+ryHWgfA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.25.0/go.mod h1:e7ciERRhZaOZXVjx5MiL8TK5+Xv7G5Gv5PA2ZDEJdL8= 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= @@ -664,8 +668,8 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8 go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= -golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -675,9 +679,10 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U 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-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -712,8 +717,8 @@ 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.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= -golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.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-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -752,17 +757,18 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= -golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= +golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= +golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= 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-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -776,8 +782,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/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.1.0/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/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-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -835,16 +841,18 @@ 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.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -852,16 +860,14 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -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/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -909,8 +915,8 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= -golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -933,16 +939,14 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.168.0 h1:MBRe+Ki4mMN93jhDDbpuRLjRddooArz4FeSObvUMmjY= -google.golang.org/api v0.168.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= +google.golang.org/api v0.174.0 h1:zB1BWl7ocxfTea2aQ9mgdzXjnfPySllpPOskdnO+q34= +google.golang.org/api v0.174.0/go.mod h1:aC7tB6j0HR1Nl0ni5ghpx6iLasmAX78Zkh/wgxAAjLg= 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.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -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-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -972,10 +976,10 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/api v0.0.0-20240304212257-790db918fca8 h1:8eadJkXbwDEMNwcB5O0s5Y5eCfyuCLdvaiOIaGTrWmQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240304212257-790db918fca8/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +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.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1002,9 +1006,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 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= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 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= @@ -1048,12 +1051,13 @@ k8s.io/component-base v0.29.3 h1:Oq9/nddUxlnrCuuR2K/jp6aflVvc0uDvxMzAWxnGzAo= k8s.io/component-base v0.29.3/go.mod h1:Yuj33XXjuOk2BAaHsIGHhCKZQAgYKhqIxIjIr2UXYio= k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20240221221325-2ac9dc51f3f1 h1:rtdnaWfP40MTKv7izH81gkWpZB45pZrwIxyZdPSn1mI= -k8s.io/kube-openapi v0.0.0-20240221221325-2ac9dc51f3f1/go.mod h1:Pa1PvrP7ACSkuX6I7KYomY6cmMA0Tx86waBhDUgoKPw= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= k8s.io/kubectl v0.29.3 h1:RuwyyIU42MAISRIePaa8Q7A3U74Q9P4MoJbDFz9o3us= k8s.io/kubectl v0.29.3/go.mod h1:yCxfY1dbwgVdEt2zkJ6d5NNLOhhWgTyrqACIoFhpdd4= k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/internal/autodetect/main.go b/internal/autodetect/main.go index 359843dcd0..8682a6c27d 100644 --- a/internal/autodetect/main.go +++ b/internal/autodetect/main.go @@ -65,13 +65,32 @@ func (a *autoDetect) PrometheusCRsAvailability() (prometheus.Availability, error return prometheus.NotAvailable, err } + foundServiceMonitor := false + foundPodMonitor := false apiGroups := apiList.Groups for i := 0; i < len(apiGroups); i++ { if apiGroups[i].Name == "monitoring.coreos.com" { - return prometheus.Available, nil + for _, version := range apiGroups[i].Versions { + resources, err := a.dcl.ServerResourcesForGroupVersion(version.GroupVersion) + if err != nil { + return prometheus.NotAvailable, err + } + + for _, resource := range resources.APIResources { + if resource.Kind == "ServiceMonitor" { + foundServiceMonitor = true + } else if resource.Kind == "PodMonitor" { + foundPodMonitor = true + } + } + } } } + if foundServiceMonitor && foundPodMonitor { + return prometheus.Available, nil + } + return prometheus.NotAvailable, nil } diff --git a/internal/autodetect/main_test.go b/internal/autodetect/main_test.go index d5dbbc707e..cae05f1563 100644 --- a/internal/autodetect/main_test.go +++ b/internal/autodetect/main_test.go @@ -85,25 +85,65 @@ func TestDetectPlatformBasedOnAvailableAPIGroups(t *testing.T) { func TestDetectPlatformBasedOnAvailableAPIGroupsPrometheus(t *testing.T) { for _, tt := range []struct { apiGroupList *metav1.APIGroupList + resources *metav1.APIResourceList expected prometheus.Availability }{ { &metav1.APIGroupList{}, + &metav1.APIResourceList{}, prometheus.NotAvailable, }, { &metav1.APIGroupList{ Groups: []metav1.APIGroup{ { - Name: "monitoring.coreos.com", + Name: "monitoring.coreos.com", + Versions: []metav1.GroupVersionForDiscovery{{GroupVersion: "monitoring.coreos.com/v1"}}, }, }, }, + &metav1.APIResourceList{ + APIResources: []metav1.APIResource{{Kind: "ServiceMonitor"}}, + }, + prometheus.NotAvailable, + }, + { + &metav1.APIGroupList{ + Groups: []metav1.APIGroup{ + { + Name: "monitoring.coreos.com", + Versions: []metav1.GroupVersionForDiscovery{{GroupVersion: "monitoring.coreos.com/v1"}}, + }, + }, + }, + &metav1.APIResourceList{ + APIResources: []metav1.APIResource{{Kind: "PodMonitor"}}, + }, + prometheus.NotAvailable, + }, + { + &metav1.APIGroupList{ + Groups: []metav1.APIGroup{ + { + Name: "monitoring.coreos.com", + Versions: []metav1.GroupVersionForDiscovery{{GroupVersion: "monitoring.coreos.com/v1"}}, + }, + }, + }, + &metav1.APIResourceList{ + APIResources: []metav1.APIResource{{Kind: "PodMonitor"}, {Kind: "ServiceMonitor"}}, + }, prometheus.Available, }, } { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - output, err := json.Marshal(tt.apiGroupList) + var output []byte + var err error + if req.URL.Path == "/apis" { + output, err = json.Marshal(tt.apiGroupList) + } else { + output, err = json.Marshal(tt.resources) + } require.NoError(t, err) w.Header().Set("Content-Type", "application/json") diff --git a/internal/config/main.go b/internal/config/main.go index a0dbe533b9..48a09faa67 100644 --- a/internal/config/main.go +++ b/internal/config/main.go @@ -117,6 +117,7 @@ func New(opts ...Option) Config { autoInstrumentationNginxImage: o.autoInstrumentationNginxImage, labelsFilter: o.labelsFilter, annotationsFilter: o.annotationsFilter, + createRBACPermissions: o.createRBACPermissions, } } diff --git a/internal/config/options.go b/internal/config/options.go index 7635059413..9212084930 100644 --- a/internal/config/options.go +++ b/internal/config/options.go @@ -19,6 +19,7 @@ import ( "strings" "github.com/go-logr/logr" + "go.uber.org/zap/zapcore" "github.com/open-telemetry/opentelemetry-operator/internal/autodetect" "github.com/open-telemetry/opentelemetry-operator/internal/autodetect/openshift" @@ -255,3 +256,11 @@ func WithAnnotationFilters(annotationFilters []string) Option { o.annotationsFilter = filters } } + +func WithEncodeLevelFormat(s string) zapcore.LevelEncoder { + if s == "lowercase" { + return zapcore.LowercaseLevelEncoder + } else { + return zapcore.CapitalLevelEncoder + } +} diff --git a/internal/manifests/collector/container.go b/internal/manifests/collector/container.go index d0585ff9d8..193596f038 100644 --- a/internal/manifests/collector/container.go +++ b/internal/manifests/collector/container.go @@ -140,8 +140,9 @@ func Container(cfg config.Config, logger logr.Logger, otelcol v1beta1.OpenTeleme } var livenessProbe *corev1.Probe + var readinessProbe *corev1.Probe if configFromString, err := adapters.ConfigFromString(configYaml); err == nil { - if probe, err := getLivenessProbe(configFromString, otelcol.Spec.LivenessProbe); err == nil { + if probe, err := getProbe(configFromString, otelcol.Spec.LivenessProbe); err == nil { livenessProbe = probe } else if errors.Is(err, adapters.ErrNoServiceExtensions) { logger.V(4).Info("extensions not configured, skipping liveness probe creation") @@ -150,6 +151,16 @@ func Container(cfg config.Config, logger logr.Logger, otelcol v1beta1.OpenTeleme } else { logger.Error(err, "cannot create liveness probe.") } + + if probe, err := getProbe(configFromString, otelcol.Spec.ReadinessProbe); err == nil { + readinessProbe = probe + } else if errors.Is(err, adapters.ErrNoServiceExtensions) { + logger.V(4).Info("extensions not configured, skipping readiness probe creation") + } else if errors.Is(err, adapters.ErrNoServiceExtensionHealthCheck) { + logger.V(4).Info("healthcheck extension not configured, skipping readiness probe creation") + } else { + logger.Error(err, "cannot create readiness probe.") + } } envVars = append(envVars, proxy.ReadProxyVarsFromEnv()...) @@ -165,6 +176,7 @@ func Container(cfg config.Config, logger logr.Logger, otelcol v1beta1.OpenTeleme Resources: otelcol.Spec.Resources, SecurityContext: otelcol.Spec.SecurityContext, LivenessProbe: livenessProbe, + ReadinessProbe: readinessProbe, Lifecycle: otelcol.Spec.Lifecycle, } } @@ -227,7 +239,7 @@ func portMapToList(portMap map[string]corev1.ContainerPort) []corev1.ContainerPo return ports } -func getLivenessProbe(config map[interface{}]interface{}, probeConfig *v1beta1.Probe) (*corev1.Probe, error) { +func getProbe(config map[interface{}]interface{}, probeConfig *v1beta1.Probe) (*corev1.Probe, error) { probe, err := adapters.ConfigToContainerProbe(config) if err != nil { return nil, err diff --git a/internal/manifests/collector/container_test.go b/internal/manifests/collector/container_test.go index e2cd24639d..597e98c1e7 100644 --- a/internal/manifests/collector/container_test.go +++ b/internal/manifests/collector/container_test.go @@ -728,6 +728,14 @@ service: FailureThreshold: &failureThreshold, TerminationGracePeriodSeconds: &terminationGracePeriodSeconds, }, + ReadinessProbe: &v1beta1.Probe{ + InitialDelaySeconds: &initialDelaySeconds, + TimeoutSeconds: &timeoutSeconds, + PeriodSeconds: &periodSeconds, + SuccessThreshold: &successThreshold, + FailureThreshold: &failureThreshold, + TerminationGracePeriodSeconds: &terminationGracePeriodSeconds, + }, }, } cfg := config.New() @@ -736,6 +744,7 @@ service: c := Container(cfg, logger, otelcol, true) // verify + // liveness assert.Equal(t, "/", c.LivenessProbe.HTTPGet.Path) assert.Equal(t, int32(13133), c.LivenessProbe.HTTPGet.Port.IntVal) assert.Equal(t, "", c.LivenessProbe.HTTPGet.Host) @@ -746,6 +755,18 @@ service: assert.Equal(t, successThreshold, c.LivenessProbe.SuccessThreshold) assert.Equal(t, failureThreshold, c.LivenessProbe.FailureThreshold) assert.Equal(t, terminationGracePeriodSeconds, *c.LivenessProbe.TerminationGracePeriodSeconds) + + // rediness + assert.Equal(t, "/", c.ReadinessProbe.HTTPGet.Path) + assert.Equal(t, int32(13133), c.ReadinessProbe.HTTPGet.Port.IntVal) + assert.Equal(t, "", c.ReadinessProbe.HTTPGet.Host) + + assert.Equal(t, initialDelaySeconds, c.ReadinessProbe.InitialDelaySeconds) + assert.Equal(t, timeoutSeconds, c.ReadinessProbe.TimeoutSeconds) + assert.Equal(t, periodSeconds, c.ReadinessProbe.PeriodSeconds) + assert.Equal(t, successThreshold, c.ReadinessProbe.SuccessThreshold) + assert.Equal(t, failureThreshold, c.ReadinessProbe.FailureThreshold) + assert.Equal(t, terminationGracePeriodSeconds, *c.ReadinessProbe.TerminationGracePeriodSeconds) } func TestContainerProbeEmptyConfig(t *testing.T) { @@ -757,7 +778,8 @@ func TestContainerProbeEmptyConfig(t *testing.T) { health_check: service: extensions: [health_check]`), - LivenessProbe: &v1beta1.Probe{}, + LivenessProbe: &v1beta1.Probe{}, + ReadinessProbe: &v1beta1.Probe{}, }, } cfg := config.New() @@ -766,9 +788,14 @@ service: c := Container(cfg, logger, otelcol, true) // verify + // liveness assert.Equal(t, "/", c.LivenessProbe.HTTPGet.Path) assert.Equal(t, int32(13133), c.LivenessProbe.HTTPGet.Port.IntVal) assert.Equal(t, "", c.LivenessProbe.HTTPGet.Host) + // readiness + assert.Equal(t, "/", c.ReadinessProbe.HTTPGet.Path) + assert.Equal(t, int32(13133), c.ReadinessProbe.HTTPGet.Port.IntVal) + assert.Equal(t, "", c.ReadinessProbe.HTTPGet.Host) } func TestContainerProbeNoConfig(t *testing.T) { diff --git a/internal/manifests/mutate.go b/internal/manifests/mutate.go index 227af1ebda..9ac2d04fd2 100644 --- a/internal/manifests/mutate.go +++ b/internal/manifests/mutate.go @@ -178,6 +178,10 @@ func mergeWithOverride(dst, src interface{}) error { return mergo.Merge(dst, src, mergo.WithOverride) } +func mergeWithOverwriteWithEmptyValue(dst, src interface{}) error { + return mergo.Merge(dst, src, mergo.WithOverwriteWithEmptyValue) +} + func mutateSecret(existing, desired *corev1.Secret) { existing.Labels = desired.Labels existing.Annotations = desired.Annotations @@ -270,10 +274,12 @@ func mutateDaemonset(existing, desired *appsv1.DaemonSet) error { if existing.CreationTimestamp.IsZero() { existing.Spec.Selector = desired.Spec.Selector } - if err := mergeWithOverride(&existing.Spec, desired.Spec); err != nil { return err } + if err := mergeWithOverwriteWithEmptyValue(&existing.Spec.Template.Spec.NodeSelector, desired.Spec.Template.Spec.NodeSelector); err != nil { + return err + } return nil } @@ -290,6 +296,9 @@ func mutateDeployment(existing, desired *appsv1.Deployment) error { if err := mergeWithOverride(&existing.Spec.Template, desired.Spec.Template); err != nil { return err } + if err := mergeWithOverwriteWithEmptyValue(&existing.Spec.Template.Spec.NodeSelector, desired.Spec.Template.Spec.NodeSelector); err != nil { + return err + } if err := mergeWithOverride(&existing.Spec.Strategy, desired.Spec.Strategy); err != nil { return err } @@ -316,6 +325,9 @@ func mutateStatefulSet(existing, desired *appsv1.StatefulSet) error { if err := mergeWithOverride(&existing.Spec.Template, desired.Spec.Template); err != nil { return err } + if err := mergeWithOverwriteWithEmptyValue(&existing.Spec.Template.Spec.NodeSelector, desired.Spec.Template.Spec.NodeSelector); err != nil { + return err + } return nil } diff --git a/main.go b/main.go index fb856fd123..07add5acc6 100644 --- a/main.go +++ b/main.go @@ -29,6 +29,7 @@ import ( monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" "github.com/spf13/pflag" colfeaturegate "go.opentelemetry.io/collector/featuregate" + "go.uber.org/zap/zapcore" networkingv1 "k8s.io/api/networking/v1" k8sruntime "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" @@ -132,6 +133,10 @@ func main() { annotationsFilter []string webhookPort int tlsOpt tlsConfig + encodeMessageKey string + encodeLevelKey string + encodeTimeKey string + encodeLevelFormat string ) pflag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") @@ -163,8 +168,19 @@ func main() { pflag.StringArrayVar(&annotationsFilter, "annotations-filter", []string{}, "Annotations to filter away from propagating onto deploys. It should be a string array containing patterns, which are literal strings optionally containing a * wildcard character. Example: --annotations-filter=.*filter.out will filter out annotations that looks like: annotation.filter.out: true") pflag.StringVar(&tlsOpt.minVersion, "tls-min-version", "VersionTLS12", "Minimum TLS version supported. Value must match version names from https://golang.org/pkg/crypto/tls/#pkg-constants.") pflag.StringSliceVar(&tlsOpt.cipherSuites, "tls-cipher-suites", nil, "Comma-separated list of cipher suites for the server. Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants). If omitted, the default Go cipher suites will be used") + pflag.StringVar(&encodeMessageKey, "zap-message-key", "message", "The message key to be used in the customized Log Encoder") + pflag.StringVar(&encodeLevelKey, "zap-level-key", "level", "The level key to be used in the customized Log Encoder") + pflag.StringVar(&encodeTimeKey, "zap-time-key", "timestamp", "The time key to be used in the customized Log Encoder") + pflag.StringVar(&encodeLevelFormat, "zap-level-format", "uppercase", "The level format to be used in the customized Log Encoder") pflag.Parse() + opts.EncoderConfigOptions = append(opts.EncoderConfigOptions, func(ec *zapcore.EncoderConfig) { + ec.MessageKey = encodeMessageKey + ec.LevelKey = encodeLevelKey + ec.TimeKey = encodeTimeKey + ec.EncodeLevel = config.WithEncodeLevelFormat(encodeLevelFormat) + }) + logger := zap.New(zap.UseFlagOptions(&opts)) ctrl.SetLogger(logger) @@ -195,6 +211,10 @@ func main() { "enable-nginx-instrumentation", enableNginxInstrumentation, "enable-nodejs-instrumentation", enableNodeJSInstrumentation, "enable-java-instrumentation", enableJavaInstrumentation, + "zap-message-key", encodeMessageKey, + "zap-level-key", encodeLevelKey, + "zap-time-key", encodeTimeKey, + "zap-level-format", encodeLevelFormat, ) restConfig := ctrl.GetConfigOrDie() diff --git a/tests/e2e/node-selector-collector/00-assert-daemonset-without-node-selector.yaml b/tests/e2e/node-selector-collector/00-assert-daemonset-without-node-selector.yaml new file mode 100644 index 0000000000..db73d845b1 --- /dev/null +++ b/tests/e2e/node-selector-collector/00-assert-daemonset-without-node-selector.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: daemonset-collector + app.kubernetes.io/part-of: opentelemetry + node-selector-mode: without +spec: + (nodeSelector == null): true \ No newline at end of file diff --git a/tests/e2e/node-selector-collector/00-assert-deployment-without-node-selector.yaml b/tests/e2e/node-selector-collector/00-assert-deployment-without-node-selector.yaml new file mode 100644 index 0000000000..135638d131 --- /dev/null +++ b/tests/e2e/node-selector-collector/00-assert-deployment-without-node-selector.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: deployment-collector + app.kubernetes.io/part-of: opentelemetry + node-selector-mode: without +spec: + (nodeSelector == null): true \ No newline at end of file diff --git a/tests/e2e/node-selector-collector/00-assert-statefulset-without-node-selector.yaml b/tests/e2e/node-selector-collector/00-assert-statefulset-without-node-selector.yaml new file mode 100644 index 0000000000..bf1efe1767 --- /dev/null +++ b/tests/e2e/node-selector-collector/00-assert-statefulset-without-node-selector.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: statefulset-collector + app.kubernetes.io/part-of: opentelemetry + node-selector-mode: without +spec: + (nodeSelector == null): true \ No newline at end of file diff --git a/tests/e2e/node-selector-collector/00-install-collectors-without-node-selector.yaml b/tests/e2e/node-selector-collector/00-install-collectors-without-node-selector.yaml new file mode 100644 index 0000000000..6bc7c860a4 --- /dev/null +++ b/tests/e2e/node-selector-collector/00-install-collectors-without-node-selector.yaml @@ -0,0 +1,79 @@ +apiVersion: opentelemetry.io/v1alpha1 +kind: OpenTelemetryCollector +metadata: + name: deployment + labels: + node-selector-mode: without +spec: + mode: deployment + config: | + receivers: + otlp: + protocols: + grpc: + http: + processors: + + exporters: + debug: + + service: + pipelines: + traces: + receivers: [otlp] + processors: [] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1alpha1 +kind: OpenTelemetryCollector +metadata: + name: daemonset + labels: + node-selector-mode: without +spec: + mode: daemonset + config: | + receivers: + otlp: + protocols: + grpc: + http: + processors: + + exporters: + debug: + + service: + pipelines: + traces: + receivers: [otlp] + processors: [] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1alpha1 +kind: OpenTelemetryCollector +metadata: + name: statefulset + labels: + node-selector-mode: without +spec: + mode: statefulset + config: | + receivers: + otlp: + protocols: + grpc: + http: + processors: + + exporters: + debug: + + service: + pipelines: + traces: + receivers: [otlp] + processors: [] + exporters: [debug] \ No newline at end of file diff --git a/tests/e2e/node-selector-collector/01-assert-daemonset-with-node-selector.yaml b/tests/e2e/node-selector-collector/01-assert-daemonset-with-node-selector.yaml new file mode 100644 index 0000000000..51b3e20402 --- /dev/null +++ b/tests/e2e/node-selector-collector/01-assert-daemonset-with-node-selector.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Pod +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: daemonset-collector + app.kubernetes.io/part-of: opentelemetry + node-selector-mode: with +spec: + nodeSelector: + kubernetes.io/os: linux \ No newline at end of file diff --git a/tests/e2e/node-selector-collector/01-assert-deployment-with-node-selector.yaml b/tests/e2e/node-selector-collector/01-assert-deployment-with-node-selector.yaml new file mode 100644 index 0000000000..d1100e79f5 --- /dev/null +++ b/tests/e2e/node-selector-collector/01-assert-deployment-with-node-selector.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Pod +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: deployment-collector + app.kubernetes.io/part-of: opentelemetry + node-selector-mode: with +spec: + nodeSelector: + kubernetes.io/os: linux \ No newline at end of file diff --git a/tests/e2e/node-selector-collector/01-assert-statefulset-with-node-selector.yaml b/tests/e2e/node-selector-collector/01-assert-statefulset-with-node-selector.yaml new file mode 100644 index 0000000000..e9fe9f0a90 --- /dev/null +++ b/tests/e2e/node-selector-collector/01-assert-statefulset-with-node-selector.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Pod +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: statefulset-collector + app.kubernetes.io/part-of: opentelemetry + node-selector-mode: with +spec: + nodeSelector: + kubernetes.io/os: linux \ No newline at end of file diff --git a/tests/e2e/node-selector-collector/01-install-collectors-with-node-selector.yaml b/tests/e2e/node-selector-collector/01-install-collectors-with-node-selector.yaml new file mode 100644 index 0000000000..11ed93ad07 --- /dev/null +++ b/tests/e2e/node-selector-collector/01-install-collectors-with-node-selector.yaml @@ -0,0 +1,85 @@ +apiVersion: opentelemetry.io/v1alpha1 +kind: OpenTelemetryCollector +metadata: + name: deployment + labels: + node-selector-mode: with +spec: + mode: deployment + nodeSelector: + kubernetes.io/os: linux + config: | + receivers: + otlp: + protocols: + grpc: + http: + processors: + + exporters: + debug: + + service: + pipelines: + traces: + receivers: [otlp] + processors: [] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1alpha1 +kind: OpenTelemetryCollector +metadata: + name: daemonset + labels: + node-selector-mode: with +spec: + mode: daemonset + nodeSelector: + kubernetes.io/os: linux + config: | + receivers: + otlp: + protocols: + grpc: + http: + processors: + + exporters: + debug: + + service: + pipelines: + traces: + receivers: [otlp] + processors: [] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1alpha1 +kind: OpenTelemetryCollector +metadata: + name: statefulset + labels: + node-selector-mode: with +spec: + mode: statefulset + nodeSelector: + kubernetes.io/os: linux + config: | + receivers: + otlp: + protocols: + grpc: + http: + processors: + + exporters: + debug: + + service: + pipelines: + traces: + receivers: [otlp] + processors: [] + exporters: [debug] \ No newline at end of file diff --git a/tests/e2e/node-selector-collector/chainsaw-test.yaml b/tests/e2e/node-selector-collector/chainsaw-test.yaml new file mode 100644 index 0000000000..60559e2c5e --- /dev/null +++ b/tests/e2e/node-selector-collector/chainsaw-test.yaml @@ -0,0 +1,58 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: node-selector-collector +spec: + steps: + - name: step-00 + description: collectors without nodeSelector + try: + - apply: + file: 00-install-collectors-without-node-selector.yaml + # deployment + - assert: + file: 00-assert-deployment-without-node-selector.yaml + # daemonset + - assert: + file: 00-assert-daemonset-without-node-selector.yaml + # statefulset + - assert: + file: 00-assert-statefulset-without-node-selector.yaml + + - name: step-01 + description: collectors with nodeSelector + try: + - apply: + file: 01-install-collectors-with-node-selector.yaml + # deployment + - assert: + file: 01-assert-deployment-with-node-selector.yaml + # daemonset + - assert: + file: 01-assert-daemonset-with-node-selector.yaml + # statefulset + - assert: + file: 01-assert-statefulset-with-node-selector.yaml + + - name: step-02 + description: back to no nodeSelector + try: + - command: # while update is not supported on 0.1.7, but 0.1.9 https://kyverno.github.io/chainsaw/0.1.9/operations/update/ + entrypoint: kubectl + args: + - -n + - ${NAMESPACE} + - replace + - -f + - 00-install-collectors-without-node-selector.yaml + # deployment + - assert: + file: 00-assert-deployment-without-node-selector.yaml + # daemonset + - assert: + file: 00-assert-daemonset-without-node-selector.yaml + # statefulset + - assert: + file: 00-assert-statefulset-without-node-selector.yaml