diff --git a/.pipelines/azure-pipeline-build.yml b/.pipelines/azure-pipeline-build.yml index a6c35a5f2..ffe747837 100644 --- a/.pipelines/azure-pipeline-build.yml +++ b/.pipelines/azure-pipeline-build.yml @@ -4,6 +4,7 @@ trigger: - main - bot/otelcollector-upgrade-* - dependabot* + - grace/single-change-for-new-default-config pr: autoCancel: true branches: @@ -324,6 +325,47 @@ extends: test-cluster-yamls/** TargetFolder: '$(Build.ArtifactStagingDirectory)/testkube-files' + + - job: Run_Unit_Tests + displayName: "Test: Run unit tests" + pool: + name: Azure-Pipelines-CI-Test-EO + image: ci-1es-managed-ubuntu-2204 + os: linux + variables: + skipComponentGovernanceDetection: true + steps: + - checkout: self + persistCredentials: true + - task: GoTool@0 + displayName: "Test: specify golang version" + inputs: + version: $(GOLANG_VERSION) + - bash: | + go test -v . + workingDirectory: $(Build.SourcesDirectory)/otelcollector/shared/configmap/mp + displayName: "Test: run configmap processing unit tests" + + - job: Run_CCP_Unit_Tests + displayName: "Test: Run CCP unit tests" + pool: + name: Azure-Pipelines-CI-Test-EO + image: ci-1es-managed-ubuntu-2204 + os: linux + variables: + skipComponentGovernanceDetection: true + steps: + - checkout: self + persistCredentials: true + - task: GoTool@0 + displayName: "Test: specify golang version" + inputs: + version: $(GOLANG_VERSION) + - bash: | + go test -v . + workingDirectory: $(Build.SourcesDirectory)/otelcollector/shared/configmap/ccp + displayName: "Test: run configmap processing unit tests" + - job: Linux_Golang_Reference_App displayName: "Build: linux golang reference app image" pool: diff --git a/otelcollector/build/linux/Dockerfile b/otelcollector/build/linux/Dockerfile index 8cb031ce8..273e5e4df 100644 --- a/otelcollector/build/linux/Dockerfile +++ b/otelcollector/build/linux/Dockerfile @@ -2,10 +2,12 @@ ARG GOLANG_VERSION ARG FLUENTBIT_GOLANG_VERSION FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang:${FLUENTBIT_GOLANG_VERSION} as fluent-bit-builder WORKDIR /src -COPY ./fluent-bit/src/go.mod ./fluent-bit/src/go.sum . -RUN go version +COPY ./fluent-bit/src/ ./fluent-bit/src/ +COPY ./shared/ ./shared/ +WORKDIR /src/shared/ +RUN go mod download +WORKDIR /src/fluent-bit/src/ RUN go mod download -COPY ./fluent-bit/src/ . RUN apt-get update && apt-get install gcc-aarch64-linux-gnu -y ARG TARGETOS TARGETARCH RUN if [ "$TARGETARCH" = "arm64" ] ; then CC=aarch64-linux-gnu-gcc CGO_ENABLED=1 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -buildmode=c-shared -ldflags '-extldflags=-Wl,-z,now' -o out_appinsights.so . ; else CGO_ENABLED=1 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -buildmode=c-shared -ldflags '-extldflags=-Wl,-z,now' -o out_appinsights.so . ; fi @@ -63,17 +65,10 @@ FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang:${GOLAN WORKDIR / # Create directories RUN mkdir -p ./shared/configmap/mp/ +RUN mkdir -p ./shared/configmap/common/ RUN mkdir -p ./main/ -# Copy shared go files -COPY ../shared/*.go ./main/shared/ -COPY ./shared/go.mod ./main/shared/ -COPY ./shared/go.sum ./main/shared/ -COPY ../shared/configmap/mp/*.go ./main/shared/configmap/mp/ -COPY ../shared/configmap/ccp/*.go ./main/shared/configmap/ccp/ -COPY ./shared/configmap/mp/go.mod ./main/shared/configmap/mp/ -COPY ./shared/configmap/mp/go.sum ./main/shared/configmap/mp/ -COPY ./shared/configmap/ccp/go.mod ./main/shared/configmap/ccp/ -COPY ./shared/configmap/ccp/go.sum ./main/shared/configmap/ccp/ +# Copy shared module (includes mp, ccp, common, and test helpers) +COPY ./shared/ ./main/shared/ # Copy main go files COPY ./main/*.go ./main/ COPY ./go.mod ./main/ @@ -160,7 +155,7 @@ COPY --from=main-builder --chmod=777 /main/main.exe $tmpdir/main COPY ./scripts/*.sh $tmpdir/ COPY ./metricextension/me.config ./metricextension/me_internal.config ./metricextension/me_ds.config ./metricextension/me_ds_setdim.config ./metricextension/me_ds_internal.config ./metricextension/me_ds_internal_setdim.config /usr/sbin/ COPY ./fluent-bit/fluent-bit.yaml ./fluent-bit/fluent-bit-daemonset.yaml ./fluent-bit/fluent-bit-parsers.conf $tmpdir/fluent-bit/ -COPY --from=fluent-bit-builder /src/out_appinsights.so $tmpdir/fluent-bit/bin/ +COPY --from=fluent-bit-builder /src/fluent-bit/src/out_appinsights.so $tmpdir/fluent-bit/bin/ COPY --from=fluent-bit-binary-builder /usr/local/bin/fluent-bit /usr/local/bin/fluent-bit COPY --from=fluent-bit-binary-builder /usr/local/etc/fluent-bit /usr/local/etc/fluent-bit COPY ./LICENSE $tmpdir/microsoft diff --git a/otelcollector/build/linux/ccp/Dockerfile b/otelcollector/build/linux/ccp/Dockerfile index a479b69a2..8f24d5f70 100644 --- a/otelcollector/build/linux/ccp/Dockerfile +++ b/otelcollector/build/linux/ccp/Dockerfile @@ -39,17 +39,10 @@ FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang:${GOLAN WORKDIR / # Create directories RUN mkdir -p ./shared/configmap/mp/ +RUN mkdir -p ./shared/configmap/common/ RUN mkdir -p ./main/ -# Copy shared go files -COPY ../shared/*.go ./main/shared/ -COPY ./shared/go.mod ./main/shared/ -COPY ./shared/go.sum ./main/shared/ -COPY ../shared/configmap/mp/*.go ./main/shared/configmap/mp/ -COPY ../shared/configmap/ccp/*.go ./main/shared/configmap/ccp/ -COPY ./shared/configmap/mp/go.mod ./main/shared/configmap/mp/ -COPY ./shared/configmap/mp/go.sum ./main/shared/configmap/mp/ -COPY ./shared/configmap/ccp/go.mod ./main/shared/configmap/ccp/ -COPY ./shared/configmap/ccp/go.sum ./main/shared/configmap/ccp/ +# Copy shared module (includes mp, ccp, common, and helpers) +COPY ./shared/ ./main/shared/ # Copy main go files COPY ./main/*.go ./main/ COPY ./go.mod ./main/ diff --git a/otelcollector/configmapparser/default-prom-configs/podannotationsDefault.yml b/otelcollector/configmapparser/default-prom-configs/podannotationsDefault.yml index 49afd2c76..64745cc53 100644 --- a/otelcollector/configmapparser/default-prom-configs/podannotationsDefault.yml +++ b/otelcollector/configmapparser/default-prom-configs/podannotationsDefault.yml @@ -27,3 +27,6 @@ - source_labels: [__meta_kubernetes_pod_name] action: replace target_label: kubernetes_pod_name + - source_labels: [__meta_kubernetes_namespace] + action: keep + regex: $$AZMON_PROMETHEUS_POD_ANNOTATION_NAMESPACES_REGEX$$ diff --git a/otelcollector/fluent-bit/src/go.mod b/otelcollector/fluent-bit/src/go.mod index 19324fca4..b6302c337 100644 --- a/otelcollector/fluent-bit/src/go.mod +++ b/otelcollector/fluent-bit/src/go.mod @@ -1,13 +1,15 @@ module Docker-Provider/source/plugins/go/src +replace github.com/prometheus-collector/shared => ../../shared + go 1.24.0 -toolchain go1.24.1 require ( github.com/fluent/fluent-bit-go v0.0.0-20220311094233-780004bf5562 github.com/microsoft/ApplicationInsights-Go v0.4.4 github.com/mitchellh/mapstructure v1.5.0 + github.com/prometheus-collector/shared v0.0.0-00010101000000-000000000000 github.com/prometheus/client_golang v1.23.2 github.com/shirou/gopsutil/v4 v4.26.1 github.com/ugorji/go/codec v1.3.0 diff --git a/otelcollector/fluent-bit/src/go.sum b/otelcollector/fluent-bit/src/go.sum index 5c269287b..8366315f6 100644 --- a/otelcollector/fluent-bit/src/go.sum +++ b/otelcollector/fluent-bit/src/go.sum @@ -220,6 +220,8 @@ k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8 k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= diff --git a/otelcollector/fluent-bit/src/telemetry.go b/otelcollector/fluent-bit/src/telemetry.go index aa33dbf4c..fef749835 100644 --- a/otelcollector/fluent-bit/src/telemetry.go +++ b/otelcollector/fluent-bit/src/telemetry.go @@ -20,6 +20,7 @@ import ( "github.com/fluent/fluent-bit-go/output" "github.com/microsoft/ApplicationInsights-Go/appinsights" "github.com/microsoft/ApplicationInsights-Go/appinsights/contracts" + "github.com/prometheus-collector/shared" yaml "gopkg.in/yaml.v2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" @@ -904,132 +905,15 @@ func PushMEProcessedAndReceivedCountToAppInsightsMetrics() { } if os.Getenv(envControllerType) == "ReplicaSet" { - if KubeletKeepListRegex != "" { - metric.Properties["KubeletKeepListRegex"] = KubeletKeepListRegex - } - if CoreDNSKeepListRegex != "" { - metric.Properties["CoreDNSKeepListRegex"] = CoreDNSKeepListRegex - } - if CAdvisorKeepListRegex != "" { - metric.Properties["CAdvisorKeepListRegex"] = CAdvisorKeepListRegex - } - if KubeProxyKeepListRegex != "" { - metric.Properties["KubeProxyKeepListRegex"] = KubeProxyKeepListRegex - } - if ApiServerKeepListRegex != "" { - metric.Properties["ApiServerKeepListRegex"] = ApiServerKeepListRegex - } - if KubeStateKeepListRegex != "" { - metric.Properties["KubeStateKeepListRegex"] = KubeStateKeepListRegex - } - if NodeExporterKeepListRegex != "" { - metric.Properties["NodeExporterKeepListRegex"] = NodeExporterKeepListRegex - } - if WinExporterKeepListRegex != "" { - metric.Properties["WinExporterKeepListRegex"] = WinExporterKeepListRegex - } - if WinKubeProxyKeepListRegex != "" { - metric.Properties["WinKubeProxyKeepListRegex"] = WinKubeProxyKeepListRegex - } - if PodannotationKeepListRegex != "" { - metric.Properties["PodannotationKeepListRegex"] = PodannotationKeepListRegex - } - if KappieBasicKeepListRegex != "" { - metric.Properties["KappieBasicKeepListRegex"] = KappieBasicKeepListRegex - } - if AcstorCapacityProvisionerKeepListRegex != "" { - metric.Properties["AcstorCapacityProvisionerRegex"] = AcstorCapacityProvisionerKeepListRegex - } - if AcstorMetricsExporterKeepListRegex != "" { - metric.Properties["AcstorMetricsExporterRegex"] = AcstorMetricsExporterKeepListRegex - } - if LocalCSIDriverKeepListRegex != "" { - metric.Properties["LocalCSIDriverExporterRegex"] = LocalCSIDriverKeepListRegex - } - if ZtunnelKeepListRegex != "" { - metric.Properties["ZtunnelKeepListRegex"] = ZtunnelKeepListRegex - } - if IstioCniKeepListRegex != "" { - metric.Properties["IstioCniKeepListRegex"] = IstioCniKeepListRegex - } - if WaypointProxyKeepListRegex != "" { - metric.Properties["WaypointProxyKeepListRegex"] = WaypointProxyKeepListRegex - } - if DCGMExporterKeepListRegex != "" { - metric.Properties["DCGMExporterRegex"] = DCGMExporterKeepListRegex - } - if NetworkObservabilityCiliumKeepListRegex != "" { - metric.Properties["NetworkObservabilityCiliumRegex"] = NetworkObservabilityCiliumKeepListRegex - } - if NetworkObservabilityHubbleKeepListRegex != "" { - metric.Properties["NetworkObservabilityHubbleRegex"] = NetworkObservabilityHubbleKeepListRegex - } - if NetworkObservabilityRetinaKeepListRegex != "" { - metric.Properties["NetworkObservabilityRetinaRegex"] = NetworkObservabilityRetinaKeepListRegex - } - if KubeletScrapeInterval != "" { - metric.Properties["KubeletScrapeInterval"] = KubeletScrapeInterval - } - if CoreDNSScrapeInterval != "" { - metric.Properties["CoreDNSScrapeInterval"] = CoreDNSScrapeInterval - } - if CAdvisorScrapeInterval != "" { - metric.Properties["CAdvisorScrapeInterval"] = CAdvisorScrapeInterval - } - if KubeProxyScrapeInterval != "" { - metric.Properties["KubeProxyScrapeInterval"] = KubeProxyScrapeInterval - } - if ApiServerScrapeInterval != "" { - metric.Properties["ApiServerScrapeInterval"] = ApiServerScrapeInterval - } - if KubeStateScrapeInterval != "" { - metric.Properties["KubeStateScrapeInterval"] = KubeStateScrapeInterval - } - if NodeExporterScrapeInterval != "" { - metric.Properties["NodeExporterScrapeInterval"] = NodeExporterScrapeInterval - } - if WinExporterScrapeInterval != "" { - metric.Properties["WinExporterScrapeInterval"] = WinExporterScrapeInterval - } - if WinKubeProxyScrapeInterval != "" { - metric.Properties["WinKubeProxyScrapeInterval"] = WinKubeProxyScrapeInterval - } - if PromHealthScrapeInterval != "" { - metric.Properties["PromHealthScrapeInterval"] = PromHealthScrapeInterval - } - if PodAnnotationScrapeInterval != "" { - metric.Properties["PodAnnotationScrapeInterval"] = PodAnnotationScrapeInterval - } - if KappieBasicScrapeInterval != "" { - metric.Properties["KappieBasicScrapeInterval"] = KappieBasicScrapeInterval - } - if AcstorCapacityProvisionerScrapeInterval != "" { - metric.Properties["AcstorCapacityProvisionerScrapeInterval"] = AcstorCapacityProvisionerScrapeInterval - } - if AcstorMetricsExporterScrapeInterval != "" { - metric.Properties["AcstorMetricsExporterScrapeInterval"] = AcstorMetricsExporterScrapeInterval - } - if ZtunnelScrapeInterval != "" { - metric.Properties["ZtunnelScrapeInterval"] = ZtunnelScrapeInterval - } - if IstioCniScrapeInterval != "" { - metric.Properties["IstioCniScrapeInterval"] = IstioCniScrapeInterval - } - if WaypointProxyScrapeInterval != "" { - metric.Properties["WaypointProxyScrapeInterval"] = WaypointProxyScrapeInterval - } - if DCGMExporterScrapeInterval != "" { - metric.Properties["DCGMExporterScrapeInterval"] = DCGMExporterScrapeInterval - } - if NetworkObservabilityCiliumScrapeInterval != "" { - metric.Properties["NetworkObservabilityCiliumScrapeInterval"] = NetworkObservabilityCiliumScrapeInterval - } - if NetworkObservabilityHubbleScrapeInterval != "" { - metric.Properties["NetworkObservabilityHubbleScrapeInterval"] = NetworkObservabilityHubbleScrapeInterval - } - if NetworkObservabilityRetinaScrapeInterval != "" { - metric.Properties["NetworkObservabilityRetinaScrapeInterval"] = NetworkObservabilityRetinaScrapeInterval + for jobName, job := range shared.DefaultScrapeJobs { + metric.Properties[fmt.Sprintf("%sEnabled", jobName)] = strconv.FormatBool(job.Enabled) + if job.KeepListRegex != "" { + metric.Properties[fmt.Sprintf("%sKeepListRegex", jobName)] = job.KeepListRegex + } + if job.ScrapeInterval != "" { + metric.Properties[fmt.Sprintf("%sScrapeInterval", jobName)] = job.ScrapeInterval + } } } diff --git a/otelcollector/go.mod b/otelcollector/go.mod index cb6c7b4b2..917cab7a1 100644 --- a/otelcollector/go.mod +++ b/otelcollector/go.mod @@ -10,29 +10,39 @@ replace github.com/prometheus-collector/shared/configmap/mp => ./shared/configma replace github.com/prometheus-collector/shared/configmap/ccp => ./shared/configmap/ccp +replace github.com/prometheus-collector/shared/configmap/common/testhelpers => ./shared/configmap/common/testhelpers + require ( github.com/prometheus-collector/shared v0.0.0-00010101000000-000000000000 github.com/prometheus-collector/shared/configmap/ccp v0.0.0-00010101000000-000000000000 github.com/prometheus-collector/shared/configmap/mp v0.0.0-00010101000000-000000000000 + github.com/prometheus-collector/shared/configmap/common/testhelpers v0.0.0-00010101000000-000000000000 ) require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-logr/logr v1.4.2 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/google/gofuzz v1.2.0 // indirect + github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/onsi/ginkgo/v2 v2.21.0 // indirect + github.com/onsi/gomega v1.35.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.63.0 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.65.0 // indirect github.com/stretchr/testify v1.10.0 // indirect github.com/x448/float16 v0.8.4 // indirect - golang.org/x/net v0.38.0 // indirect - golang.org/x/text v0.23.0 // indirect - google.golang.org/protobuf v1.36.5 // indirect + golang.org/x/net v0.40.0 // indirect + golang.org/x/sys v0.33.0 // indirect + golang.org/x/text v0.25.0 // indirect + golang.org/x/tools v0.26.0 // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/otelcollector/go.sum b/otelcollector/go.sum index 663bb6b7b..5f9ea89aa 100644 --- a/otelcollector/go.sum +++ b/otelcollector/go.sum @@ -38,10 +38,10 @@ github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7y github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= -github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE= +github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -63,20 +63,20 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= +golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -87,8 +87,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T 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= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/otelcollector/shared/configmap/ccp/configmapparserforccp.go b/otelcollector/shared/configmap/ccp/configmapparserforccp.go index 29b6bd6e4..78e90ab4b 100644 --- a/otelcollector/shared/configmap/ccp/configmapparserforccp.go +++ b/otelcollector/shared/configmap/ccp/configmapparserforccp.go @@ -3,11 +3,15 @@ package ccpconfigmapsettings import ( "fmt" "os" - "strings" "time" - // "prometheus-collector/shared" "github.com/prometheus-collector/shared" + cmcommon "github.com/prometheus-collector/shared/configmap/common" +) + +const ( + defaultConfigSchemaVersion = "v1" + defaultConfigFileVersion = "ver1" ) func Configmapparserforccp() { @@ -15,10 +19,30 @@ func Configmapparserforccp() { fmt.Printf("waiting for 30 secs...") time.Sleep(30 * time.Second) //needed to save a restart at times when config watcher sidecar starts up later than us and hence config map wasn't yet projected into emptydir volume yet during pod startups. - configVersionPath := "/etc/config/settings/config-version" - configSchemaPath := "/etc/config/settings/schema-version" + processAndMergeConfigFiles() + + shared.SetEnvAndSourceBashrcOrPowershell("AZMON_INVALID_CUSTOM_PROMETHEUS_CONFIG", "false", true) + shared.SetEnvAndSourceBashrcOrPowershell("CONFIG_VALIDATOR_RUNNING_IN_AGENT", "true", true) + + // No need to merge custom prometheus config, only merging in the default configs + shared.SetEnvAndSourceBashrcOrPowershell("AZMON_USE_DEFAULT_PROMETHEUS_CONFIG", "true", true) + shared.StartCommandAndWait("/opt/promconfigvalidator", "--config", "/opt/defaultsMergedConfig.yml", "--output", "/opt/ccp-collector-config-with-defaults.yml", "--otelTemplate", "/opt/microsoft/otelcollector/ccp-collector-config-template.yml") + if !shared.Exists("/opt/ccp-collector-config-with-defaults.yml") { + fmt.Println("prom-config-validator::Prometheus default scrape config validation failed. No scrape configs will be used") + } else { + sourcePath := "/opt/ccp-collector-config-with-defaults.yml" + destinationPath := "/opt/microsoft/otelcollector/ccp-collector-config-default.yml" + err := shared.CopyFile(sourcePath, destinationPath) + if err != nil { + fmt.Printf("Error copying file: %v\n", err) + } else { + fmt.Println("File copied successfully.") + } + } +} - entries, er := os.ReadDir("/etc/config/settings") +func processAndMergeConfigFiles() { + entries, er := os.ReadDir(configSettingsPrefix) if er != nil { fmt.Println("error listing /etc/config/settings", er) } @@ -29,70 +53,27 @@ func Configmapparserforccp() { fmt.Println("done listing /etc/config/settings") - // Set agent config schema version - if shared.ExistsAndNotEmpty(configSchemaPath) { - configVersion, err := shared.ReadAndTrim(configVersionPath) - if err != nil { - fmt.Println("Error reading config version file:", err) - return - } - // Remove all spaces and take the first 10 characters - configVersion = strings.ReplaceAll(configVersion, " ", "") - if len(configVersion) >= 10 { - configVersion = configVersion[:10] - } - // Set the environment variable - fmt.Println("Configmapparserforccp setting env var AZMON_AGENT_CFG_FILE_VERSION:", configVersion) - shared.SetEnvAndSourceBashrcOrPowershell("AZMON_AGENT_CFG_FILE_VERSION", configVersion, true) - } else { - fmt.Println("Configmapparserforccp fileversion file doesn't exist. or configmap doesn't exist:", configVersionPath) - } + schemaVersion := cmcommon.SetEnvFromFile(schemaVersionFile, "AZMON_AGENT_CFG_SCHEMA_VERSION", defaultConfigSchemaVersion) + cmcommon.SetEnvFromFile(configVersionFile, "AZMON_AGENT_CFG_FILE_VERSION", defaultConfigFileVersion) - // Set agent config file version - if shared.ExistsAndNotEmpty(configVersionPath) { - configSchemaVersion, err := shared.ReadAndTrim(configSchemaPath) - if err != nil { - fmt.Println("Error reading config schema version file:", err) - return - } - // Remove all spaces and take the first 10 characters - configSchemaVersion = strings.ReplaceAll(configSchemaVersion, " ", "") - if len(configSchemaVersion) >= 10 { - configSchemaVersion = configSchemaVersion[:10] - } - // Set the environment variable - fmt.Println("Configmapparserforccp setting env var AZMON_AGENT_CFG_SCHEMA_VERSION:", configSchemaVersion) - shared.SetEnvAndSourceBashrcOrPowershell("AZMON_AGENT_CFG_SCHEMA_VERSION", configSchemaVersion, true) - } else { - fmt.Println("Configmapparserforccp schemaversion file doesn't exist. or configmap doesn't exist:", configSchemaPath) + metricsConfigBySection, err := cmcommon.LoadMetricsConfiguration( + schemaVersion, + []string{configSettingsPrefix + "controlplane-metrics", configSettingsPrefix + "prometheus-collector-settings"}, + configSettingsPrefix, + ) + if err != nil { + fmt.Printf("Error parsing config: %v\n", err) + return } - var metricsConfigBySection map[string]map[string]string - var err error - if os.Getenv("AZMON_AGENT_CFG_SCHEMA_VERSION") == "v2" { - filePaths := []string{"/etc/config/settings/controlplane-metrics", "/etc/config/settings/prometheus-collector-settings"} - metricsConfigBySection, err = shared.ParseMetricsFiles(filePaths) - if err != nil { - fmt.Printf("Error parsing files: %v\n", err) - return - } - } else if os.Getenv("AZMON_AGENT_CFG_SCHEMA_VERSION") == "v1" { - configDir := "/etc/config/settings" - metricsConfigBySection, err = shared.ParseV1Config(configDir) - if err != nil { - fmt.Printf("Error parsing config: %v\n", err) - return - } - } else { - fmt.Println("Invalid schema version or no configmap present. Using defaults.") - } + parsedSchema := shared.ParseSchemaVersion(schemaVersion) // Parse the configmap to set the right environment variables for prometheus collector settings - parseConfigAndSetEnvInFile(metricsConfigBySection) - filename := "/opt/microsoft/configmapparser/config_prometheus_collector_settings_env_var" + parseConfigAndSetEnvInFile(metricsConfigBySection, parsedSchema) + filename := collectorSettingsEnvVarPath err = shared.SetEnvVarsFromFile(filename) if err != nil { - fmt.Printf("Error when settinng env for /opt/microsoft/configmapparser/config_prometheus_collector_settings_env_var: %v\n", err) + fmt.Printf("Error when settinng env for %s: %v\n", collectorSettingsEnvVarPath, err) } ConfigureOpentelemetryMetricsSettings(metricsConfigBySection) @@ -103,34 +84,15 @@ func Configmapparserforccp() { } // Parse the settings for default scrape configs - tomlparserCCPDefaultScrapeSettings(metricsConfigBySection) - filename = "/opt/microsoft/configmapparser/config_default_scrape_settings_env_var" + tomlparserCCPDefaultScrapeSettings(metricsConfigBySection, parsedSchema) + filename = defaultSettingsEnvVarPath err = shared.SetEnvVarsFromFile(filename) if err != nil { - fmt.Printf("Error when settinng env for /opt/microsoft/configmapparser/config_default_scrape_settings_env_var: %v\n", err) + fmt.Printf("Error when settinng env for %s: %v\n", defaultSettingsEnvVarPath, err) } // Parse the settings for default targets metrics keep list config - tomlparserCCPTargetsMetricsKeepList(metricsConfigBySection) + tomlparserCCPTargetsMetricsKeepList(metricsConfigBySection, parsedSchema) prometheusCcpConfigMerger() - - shared.SetEnvAndSourceBashrcOrPowershell("AZMON_INVALID_CUSTOM_PROMETHEUS_CONFIG", "false", true) - shared.SetEnvAndSourceBashrcOrPowershell("CONFIG_VALIDATOR_RUNNING_IN_AGENT", "true", true) - - // No need to merge custom prometheus config, only merging in the default configs - shared.SetEnvAndSourceBashrcOrPowershell("AZMON_USE_DEFAULT_PROMETHEUS_CONFIG", "true", true) - shared.StartCommandAndWait("/opt/promconfigvalidator", "--config", "/opt/defaultsMergedConfig.yml", "--output", "/opt/ccp-collector-config-with-defaults.yml", "--otelTemplate", "/opt/microsoft/otelcollector/ccp-collector-config-template.yml") - if !shared.Exists("/opt/ccp-collector-config-with-defaults.yml") { - fmt.Printf("prom-config-validator::Prometheus default scrape config validation failed. No scrape configs will be used") - } else { - sourcePath := "/opt/ccp-collector-config-with-defaults.yml" - destinationPath := "/opt/microsoft/otelcollector/ccp-collector-config-default.yml" - err := shared.CopyFile(sourcePath, destinationPath) - if err != nil { - fmt.Printf("Error copying file: %v\n", err) - } else { - fmt.Println("File copied successfully.") - } - } } diff --git a/otelcollector/shared/configmap/ccp/configmapparserforccp_test.go b/otelcollector/shared/configmap/ccp/configmapparserforccp_test.go new file mode 100644 index 000000000..25460d388 --- /dev/null +++ b/otelcollector/shared/configmap/ccp/configmapparserforccp_test.go @@ -0,0 +1,609 @@ +package ccpconfigmapsettings + +import ( + "fmt" + "os" + "sort" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/prometheus-collector/shared" + "github.com/prometheus-collector/shared/configmap/common/testhelpers" + "gopkg.in/yaml.v2" +) + +type TestConfig struct { + // Setup parameters + EnvVars map[string]string + UseConfigFiles bool + IsDefaultConfig bool + ConfigMapFiles map[string]string + ConfigMapMountPath string + + // Expected results + ExpectedEnvVars map[string]string + ExpectedKeepListHashMap map[string]string + ExpectedScrapeIntervalMap map[string]string + ExpectedDefaultContentsPath string + ExpectedMergedContentsPath string +} + +func setupTest() { + var originalDefaultScrapeJobs map[string]shared.DefaultScrapeJob + BeforeEach(func() { + testhelpers.UnsetEnvVars(testhelpers.DefaultCollectorEnvVarKeys()) + configSettingsPrefix = "/tmp/settings/" + configMapParserPrefix = "/tmp/configmapparser/" + os.RemoveAll(configSettingsPrefix) + os.RemoveAll(configMapParserPrefix) + _ = os.MkdirAll(configSettingsPrefix, 0755) + _ = os.MkdirAll(configMapParserPrefix, 0755) + // Save a copy of the original DefaultScrapeJobs for restoring later + originalDefaultScrapeJobs = make(map[string]shared.DefaultScrapeJob) + for key, job := range shared.ControlPlaneDefaultScrapeJobs { + originalDefaultScrapeJobs[key] = *job + } + }) + AfterEach(func() { + testhelpers.UnsetEnvVars(testhelpers.DefaultCollectorEnvVarKeys()) + // Remove any temporary files created during the tests + os.RemoveAll(configSettingsPrefix) + os.RemoveAll(configMapParserPrefix) + // Restore the original DefaultScrapeJobs + for key, job := range originalDefaultScrapeJobs { + shared.ControlPlaneDefaultScrapeJobs[key] = &job + } + os.RemoveAll("../../../configmapparser/default-prom-configs/test/") + }) +} + +var _ = Describe("Configmapparserforccp", Ordered, func() { + setupTest() + + Context("when the settings configmap does not exist", func() { + It("should process the config with defaults for the Linux ReplicaSet", func() { + Expect(testhelpers.SetControlPlaneEnvVars(shared.ControllerType.ReplicaSet, shared.OSType.Linux)).To(Succeed()) + + expectedEnvVars := testhelpers.DefaultControlPlaneEnvVars() + expectedKeepListHashMap := testhelpers.ExpectedKeepListMap(shared.ControlPlaneDefaultScrapeJobs, true, "", false) + expectedScrapeIntervalHashMap := testhelpers.ExpectedScrapeIntervalMap(shared.ControlPlaneDefaultScrapeJobs, "") + expectedContentsFilePath := "./testdata/default-linux-rs.yaml" + isDefaultConfig := true + + checkResults(true, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "") + }) + }) + + Context("when the settings configmap sections exist but are empty", func() { + It("should process the config with defaults for the Linux ReplicaSet", func() { + Expect(testhelpers.SetControlPlaneEnvVars(shared.ControllerType.ReplicaSet, shared.OSType.Linux)).To(Succeed()) + + expectedEnvVars := testhelpers.DefaultControlPlaneEnvVars() + expectedKeepListHashMap := testhelpers.ExpectedKeepListMap(shared.ControlPlaneDefaultScrapeJobs, true, "", false) + expectedScrapeIntervalHashMap := testhelpers.ExpectedScrapeIntervalMap(shared.ControlPlaneDefaultScrapeJobs, "") + expectedContentsFilePath := "./testdata/default-linux-rs.yaml" + isDefaultConfig := true + + checkResults(false, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "") + }) + }) + + Context("when the settings configmap sections exist and are not default", func() { + It("should process the config for the Linux ReplicaSet", func() { + Expect(testhelpers.SetControlPlaneEnvVars(shared.ControllerType.ReplicaSet, shared.OSType.Linux)).To(Succeed()) + expectedEnvVars := testhelpers.DefaultControlPlaneEnvVars() + extraEnvVars := map[string]string{ + "AZMON_AGENT_CFG_SCHEMA_VERSION": "v1", + "AZMON_AGENT_CFG_FILE_VERSION": "ver1", + "AZMON_CLUSTER_LABEL": "alias", + "AZMON_CLUSTER_ALIAS": "alias", + "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "false", + "AZMON_PROMETHEUS_CLUSTER-AUTOSCALER_ENABLED": "true", + "AZMON_PROMETHEUS_KUBE-SCHEDULER_ENABLED": "true", + "AZMON_PROMETHEUS_KUBE-CONTROLLER-MANAGER_ENABLED": "true", + "AZMON_PROMETHEUS_ETCD_ENABLED": "true", + "AZMON_PROMETHEUS_NODE-AUTO-PROVISIONING_ENABLED": "true", + } + for key, value := range extraEnvVars { + expectedEnvVars[key] = value + } + expectedKeepListHashMap := testhelpers.ExpectedKeepListMap(shared.ControlPlaneDefaultScrapeJobs, true, "test.*|test2", false) + + schemaVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "schema-version", "v1") + configVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "config-version", "ver1") + collectorSettingsMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "prometheus-collector-settings", `cluster_alias = "alias"`) + defaultSettingsMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "default-scrape-settings-enabled", ` + kubelet = true + coredns = false + cadvisor = true + kubeproxy = false + apiserver = false + kubestate = true + nodeexporter = true + windowsexporter = false + windowskubeproxy = false + kappiebasic = true + networkobservabilityRetina = true + networkobservabilityHubble = true + networkobservabilityCilium = true + prometheuscollectorhealth = false + controlplane-apiserver = true + controlplane-cluster-autoscaler = true + controlplane-kube-scheduler = true + controlplane-kube-controller-manager = true + controlplane-node-auto-provisioning = true + controlplane-etcd = true + acstor-capacity-provisioner = true + acstor-metrics-exporter = true + `) + configMapKeepListMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "default-targets-metrics-keep-list", ` + kubelet = "test.*|test2" + coredns = "test.*|test2" + cadvisor = "test.*|test2" + kubeproxy = "test.*|test2" + apiserver = "test.*|test2" + kubestate = "test.*|test2" + nodeexporter = "test.*|test2" + windowsexporter = "test.*|test2" + windowskubeproxy = "test.*|test2" + podannotations = "test.*|test2" + kappiebasic = "test.*|test2" + networkobservabilityRetina = "test.*|test2" + networkobservabilityHubble = "test.*|test2" + networkobservabilityCilium = "test.*|test2" + acstor-capacity-provisioner = "test.*|test2" + acstor-metrics-exporter = "test.*|test2" + prometheuscollectorhealth = "test.*|test2" + controlplane-apiserver = "test.*|test2" + controlplane-cluster-autoscaler = "test.*|test2" + controlplane-kube-scheduler = "test.*|test2" + controlplane-kube-controller-manager = "test.*|test2" + controlplane-etcd = "test.*|test2" + controlplane-node-auto-provisioning = "test.*|test2" + acstor-capacity-provisioner = "test.*|test2" + acstor-metrics-exporter = "test.*|test2" + minimalingestionprofile = true + `) + + checkResults(false, false, expectedEnvVars, expectedKeepListHashMap, nil, "./testdata/advanced-linux-rs.yaml", "") + }) + }) + + Context("when the configmap sections exist but all scrape jobs are false", func() { + It("should process the config with no scrape jobs enabled for the Linux ReplicaSet", func() { + Expect(testhelpers.SetControlPlaneEnvVars(shared.ControllerType.ReplicaSet, shared.OSType.Linux)).To(Succeed()) + expectedEnvVars := testhelpers.DefaultControlPlaneEnvVars() + extraEnvVars := map[string]string{ + "AZMON_AGENT_CFG_SCHEMA_VERSION": "v1", + "AZMON_AGENT_CFG_FILE_VERSION": "ver1", + "AZMON_PROMETHEUS_APISERVER_ENABLED": "false", + "AZMON_PROMETHEUS_CLUSTER-AUTOSCALER_ENABLED": "false", + "AZMON_PROMETHEUS_KUBE-SCHEDULER_ENABLED": "false", + "AZMON_PROMETHEUS_KUBE-CONTROLLER-MANAGER_ENABLED": "false", + "AZMON_PROMETHEUS_ETCD_ENABLED": "false", + "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "true", + } + for key, value := range extraEnvVars { + expectedEnvVars[key] = value + } + expectedKeepListHashMap := testhelpers.ExpectedKeepListMap(shared.ControlPlaneDefaultScrapeJobs, true, "", false) + expectedScrapeIntervalHashMap := testhelpers.ExpectedScrapeIntervalMap(shared.ControlPlaneDefaultScrapeJobs, "") + schemaVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "schema-version", "v1") + configVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "config-version", "ver1") + defaultSettingsMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "default-scrape-settings-enabled", ` + kubelet = false + coredns = false + cadvisor = false + kubeproxy = false + apiserver = false + kubestate = false + nodeexporter = false + windowsexporter = false + windowskubeproxy = false + kappiebasic = false + networkobservabilityRetina = false + networkobservabilityHubble = false + networkobservabilityCilium = false + acstor-capacity-provisioner = false + acstor-metrics-exporter = false + controlplane-apiserver = false + controlplane-cluster-autoscaler = false + controlplane-kube-scheduler = false + controlplane-kube-controller-manager = false + controlplane-node-auto-provisioning = false + controlplane-etcd = false + prometheuscollectorhealth = false + `) + isDefaultConfig := false + expectedContentsFilePath := "./testdata/no-scrape-jobs-linux-rs.yaml" + checkResults(false, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "") + }) + }) + + Context("when minimal ingestion is not true", func() { + It("should handle it being set to false with the keeplist regex values", func() { + Expect(testhelpers.SetControlPlaneEnvVars(shared.ControllerType.ReplicaSet, shared.OSType.Linux)).To(Succeed()) + expectedKeepListHashMap := testhelpers.ExpectedKeepListMap(shared.ControlPlaneDefaultScrapeJobs, false, "test.*|test2", false) + expectedScrapeIntervalHashMap := testhelpers.ExpectedScrapeIntervalMap(shared.ControlPlaneDefaultScrapeJobs, "") + + schemaVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "schema-version", "v1") + configVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "config-version", "ver1") + collectorSettingsMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "prometheus-collector-settings", "") + defaultSettingsMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "default-scrape-settings-enabled", "") + configMapKeepListMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "default-targets-metrics-keep-list", ` + kubelet = "test.*|test2" + coredns = "test.*|test2" + cadvisor = "test.*|test2" + kubeproxy = "test.*|test2" + apiserver = "test.*|test2" + kubestate = "test.*|test2" + nodeexporter = "test.*|test2" + windowsexporter = "test.*|test2" + windowskubeproxy = "test.*|test2" + podannotations = "test.*|test2" + kappiebasic = "test.*|test2" + networkobservabilityRetina = "test.*|test2" + networkobservabilityHubble = "test.*|test2" + networkobservabilityCilium = "test.*|test2" + acstor-capacity-provisioner = "test.*|test2" + acstor-metrics-exporter = "test.*|test2" + prometheuscollectorhealth = "test.*|test2" + controlplane-apiserver = "test.*|test2" + controlplane-cluster-autoscaler = "test.*|test2" + controlplane-kube-scheduler = "test.*|test2" + controlplane-kube-controller-manager = "test.*|test2" + controlplane-node-auto-provisioning = "test.*|test2" + controlplane-etcd = "test.*|test2" + minimalingestionprofile = false + `) + checkResults(false, false, nil, expectedKeepListHashMap, expectedScrapeIntervalHashMap, "./testdata/no-minimal-linux-rs.yaml", "") + }) + }) + + Context("when the settings configmap uses v2 and the sections are not default", Label("v2"), func() { + It("should process the config with custom settings for the Linux ReplicaSet", func() { + Expect(testhelpers.SetControlPlaneEnvVars(shared.ControllerType.ReplicaSet, shared.OSType.Linux)).To(Succeed()) + + expectedEnvVars := testhelpers.DefaultControlPlaneEnvVars() + extraEnvVars := map[string]string{ + "AZMON_AGENT_CFG_SCHEMA_VERSION": "v2", + "AZMON_AGENT_CFG_FILE_VERSION": "ver1", + "AZMON_CLUSTER_LABEL": "alias", + "AZMON_CLUSTER_ALIAS": "alias", + "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "false", + "AZMON_PROMETHEUS_CLUSTER-AUTOSCALER_ENABLED": "true", + "AZMON_PROMETHEUS_KUBE-SCHEDULER_ENABLED": "true", + "AZMON_PROMETHEUS_KUBE-CONTROLLER-MANAGER_ENABLED": "true", + "AZMON_PROMETHEUS_ETCD_ENABLED": "true", + "AZMON_PROMETHEUS_NODE-AUTO-PROVISIONING_ENABLED": "true", + } + for key, value := range extraEnvVars { + expectedEnvVars[key] = value + } + expectedKeepListHashMap := testhelpers.ExpectedKeepListMap(shared.ControlPlaneDefaultScrapeJobs, true, "test.*|test2", false) + expectedContentsFilePath := "./testdata/advanced-linux-rs.yaml" + + schemaVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "schema-version", "v2") + fmt.Println("Schema version file created at:", schemaVersionFile) + configVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "config-version", "ver1") + fmt.Println("Config version file created at:", configVersionFile) + _ = testhelpers.MustCreateTempFile(configSettingsPrefix, "prometheus-collector-settings", ` + cluster_alias = "alias" + debug-mode = true + https_config = true + `) + _ = testhelpers.MustCreateTempFile(configSettingsPrefix, "controlplane-metrics", ` + default-targets-scrape-enabled: |- + apiserver = true + cluster-autoscaler = true + kube-scheduler = true + kube-controller-manager = true + etcd = true + node-auto-provisioning = true + default-targets-metrics-keep-list: |- + apiserver = "test.*|test2" + cluster-autoscaler = "test.*|test2" + kube-scheduler = "test.*|test2" + kube-controller-manager = "test.*|test2" + etcd = "test.*|test2" + node-auto-provisioning = "test.*|test2" + minimal-ingestion-profile: |- + enabled = true + `) + _ = testhelpers.MustCreateTempFile(configSettingsPrefix, "cluster-metrics", ` + default-targets-scrape-enabled: |- + kubelet = true + coredns = true + cadvisor = true + kubeproxy = true + apiserver = true + kubestate = true + nodeexporter = true + windowsexporter = true + windowskubeproxy = true + kappiebasic = true + networkobservabilityRetina = true + networkobservabilityHubble = true + networkobservabilityCilium = true + acstor-capacity-provisioner = true + acstor-metrics-exporter = true + prometheuscollectorhealth = false + pod-annotation-based-scraping: |- + podannotationnamespaceregex = ".*|value" + default-targets-metrics-keep-list: |- + kubelet = "test.*|test2" + coredns = "test.*|test2" + cadvisor = "test.*|test2" + kubeproxy = "test.*|test2" + apiserver = "test.*|test2" + kubestate = "test.*|test2" + nodeexporter = "test.*|test2" + windowsexporter = "test.*|test2" + windowskubeproxy = "test.*|test2" + podannotations = "test.*|test2" + kappiebasic = "test.*|test2" + networkobservabilityRetina = "test.*|test2" + networkobservabilityHubble = "test.*|test2" + networkobservabilityCilium = "test.*|test2" + acstor-capacity-provisioner = "test.*|test2" + acstor-metrics-exporter = "test.*|test2" + prometheuscollectorhealth = "test.*|test2" + minimal-ingestion-profile: |- + enabled = true + default-targets-scrape-interval-settings: |- + kubelet = "15s" + coredns = "15s" + cadvisor = "15s" + kubeproxy = "15s" + apiserver = "15s" + kubestate = "15s" + nodeexporter = "15s" + windowsexporter = "15s" + windowskubeproxy = "15s" + kappiebasic = "15s" + networkobservabilityRetina = "15s" + networkobservabilityHubble = "15s" + networkobservabilityCilium = "15s" + prometheuscollectorhealth = "15s" + podannotations = "15s" + acstor-capacity-provisioner = "15s" + acstor-metrics-exporter = "15s" + `) + + isDefaultConfig := false + checkResults(false, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, nil, expectedContentsFilePath, "") + }) + It("should process when the minimal ingestion profile is false for CCP", func() { + Expect(testhelpers.SetControlPlaneEnvVars(shared.ControllerType.ReplicaSet, shared.OSType.Linux)).To(Succeed()) + + expectedEnvVars := testhelpers.DefaultControlPlaneEnvVars() + extraEnvVars := map[string]string{ + "AZMON_AGENT_CFG_SCHEMA_VERSION": "v2", + "AZMON_AGENT_CFG_FILE_VERSION": "ver1", + "AZMON_CLUSTER_LABEL": "alias", + "AZMON_CLUSTER_ALIAS": "alias", + "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "false", + "AZMON_PROMETHEUS_CLUSTER-AUTOSCALER_ENABLED": "true", + "AZMON_PROMETHEUS_KUBE-SCHEDULER_ENABLED": "true", + "AZMON_PROMETHEUS_KUBE-CONTROLLER-MANAGER_ENABLED": "true", + "AZMON_PROMETHEUS_ETCD_ENABLED": "true", + "AZMON_PROMETHEUS_NODE-AUTO-PROVISIONING_ENABLED": "true", + } + for key, value := range extraEnvVars { + expectedEnvVars[key] = value + } + expectedKeepListHashMap := testhelpers.ExpectedKeepListMap(shared.ControlPlaneDefaultScrapeJobs, false, "test.*|test2", false) + expectedContentsFilePath := "./testdata/advanced-no-minimal-linux-rs.yaml" + + schemaVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "schema-version", "v2") + fmt.Println("Schema version file created at:", schemaVersionFile) + configVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "config-version", "ver1") + fmt.Println("Config version file created at:", configVersionFile) + _ = testhelpers.MustCreateTempFile(configSettingsPrefix, "prometheus-collector-settings", ` + cluster_alias = "alias" + debug-mode = true + https_config = true + `) + _ = testhelpers.MustCreateTempFile(configSettingsPrefix, "controlplane-metrics", ` + default-targets-scrape-enabled: |- + apiserver = true + cluster-autoscaler = true + kube-scheduler = true + kube-controller-manager = true + etcd = true + node-auto-provisioning = true + default-targets-metrics-keep-list: |- + apiserver = "test.*|test2" + cluster-autoscaler = "test.*|test2" + kube-scheduler = "test.*|test2" + kube-controller-manager = "test.*|test2" + etcd = "test.*|test2" + node-auto-provisioning = "test.*|test2" + minimal-ingestion-profile: |- + enabled = false + `) + _ = testhelpers.MustCreateTempFile(configSettingsPrefix, "cluster-metrics", ` + default-targets-scrape-enabled: |- + kubelet = true + coredns = true + cadvisor = true + kubeproxy = true + apiserver = true + kubestate = true + nodeexporter = true + windowsexporter = true + windowskubeproxy = true + kappiebasic = true + networkobservabilityRetina = true + networkobservabilityHubble = true + networkobservabilityCilium = true + acstor-capacity-provisioner = true + acstor-metrics-exporter = true + prometheuscollectorhealth = false + pod-annotation-based-scraping: |- + podannotationnamespaceregex = ".*|value" + default-targets-metrics-keep-list: |- + kubelet = "test.*|test2" + coredns = "test.*|test2" + cadvisor = "test.*|test2" + kubeproxy = "test.*|test2" + apiserver = "test.*|test2" + kubestate = "test.*|test2" + nodeexporter = "test.*|test2" + windowsexporter = "test.*|test2" + windowskubeproxy = "test.*|test2" + podannotations = "test.*|test2" + kappiebasic = "test.*|test2" + networkobservabilityRetina = "test.*|test2" + networkobservabilityHubble = "test.*|test2" + networkobservabilityCilium = "test.*|test2" + acstor-capacity-provisioner = "test.*|test2" + acstor-metrics-exporter = "test.*|test2" + prometheuscollectorhealth = "test.*|test2" + minimal-ingestion-profile: |- + enabled = true + default-targets-scrape-interval-settings: |- + kubelet = "15s" + coredns = "15s" + cadvisor = "15s" + kubeproxy = "15s" + apiserver = "15s" + kubestate = "15s" + nodeexporter = "15s" + windowsexporter = "15s" + windowskubeproxy = "15s" + kappiebasic = "15s" + networkobservabilityRetina = "15s" + networkobservabilityHubble = "15s" + networkobservabilityCilium = "15s" + prometheuscollectorhealth = "15s" + podannotations = "15s" + acstor-capacity-provisioner = "15s" + acstor-metrics-exporter = "15s" + `) + + isDefaultConfig := false + checkResults(false, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, nil, expectedContentsFilePath, "") + }) + It("should process the config with no scrape jobs enabled and without all sections for the Linux ReplicaSet", func() { + Expect(testhelpers.SetControlPlaneEnvVars(shared.ControllerType.ReplicaSet, shared.OSType.Linux)).To(Succeed()) + expectedEnvVars := testhelpers.DefaultControlPlaneEnvVars() + extraEnvVars := map[string]string{ + "AZMON_AGENT_CFG_SCHEMA_VERSION": "v2", + "AZMON_AGENT_CFG_FILE_VERSION": "ver1", + "AZMON_PROMETHEUS_APISERVER_ENABLED": "false", + "AZMON_PROMETHEUS_CLUSTER-AUTOSCALER_ENABLED": "false", + "AZMON_PROMETHEUS_KUBE-SCHEDULER_ENABLED": "false", + "AZMON_PROMETHEUS_KUBE-CONTROLLER-MANAGER_ENABLED": "false", + "AZMON_PROMETHEUS_ETCD_ENABLED": "false", + "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "true", + } + for key, value := range extraEnvVars { + expectedEnvVars[key] = value + } + expectedKeepListHashMap := testhelpers.ExpectedKeepListMap(shared.ControlPlaneDefaultScrapeJobs, false, "", false) + expectedScrapeIntervalHashMap := testhelpers.ExpectedScrapeIntervalMap(shared.ControlPlaneDefaultScrapeJobs, "") + schemaVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "schema-version", "v2") + configVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "config-version", "ver1") + _ = testhelpers.MustCreateTempFile(configSettingsPrefix, "controlplane-metrics", ` + default-targets-scrape-enabled: |- + apiserver = false + cluster-autoscaler = false + kube-scheduler = false + kube-controller-manager = false + etcd = false + node-auto-provisioning = false + minimal-ingestion-profile: |- + enabled = false + `) + isDefaultConfig := false + expectedContentsFilePath := "./testdata/no-scrape-jobs-linux-rs.yaml" + checkResults(false, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "") + }) + }) +}) + +// Helper functions (these should mirror the ones in the MP test file) + +func checkResults(useConfigFiles bool, isDefaultConfig bool, expectedEnvVars map[string]string, expectedKeepListHashMap map[string]string, expectedScrapeIntervalHashMap map[string]string, expectedDefaultContentsFilePath string, expectedMergedContentsFilePath string) { + if useConfigFiles { + setupConfigFiles(isDefaultConfig) + } + setupProcessedFiles() + processAndMergeConfigFiles() + + if expectedEnvVars != nil { + Expect(testhelpers.CheckEnvVars(expectedEnvVars)).To(Succeed()) + } + + keepListHash, err := testhelpers.ReadYAMLStringMap(configMapKeepListEnvVarPath) + Expect(err).NotTo(HaveOccurred()) + Expect(keepListHash).To(BeComparableTo(expectedKeepListHashMap)) + + mergedFileContents, err := os.ReadFile(mergedDefaultConfigPath) + Expect(err).NotTo(HaveOccurred()) + fmt.Println(string(mergedFileContents)) + expectedDefaultFileContents, err := os.ReadFile(expectedDefaultContentsFilePath) + Expect(err).NotTo(HaveOccurred()) + + var mergedConfig, expectedConfig, customMergedConfig, expectedCustomConfig map[string]interface{} + + err = yaml.Unmarshal(mergedFileContents, &mergedConfig) + Expect(err).NotTo(HaveOccurred()) + + fmt.Println("Merged Config:", mergedConfig) + + err = yaml.Unmarshal(expectedDefaultFileContents, &expectedConfig) + Expect(err).NotTo(HaveOccurred()) + + // Order the scrape_configs by job_name for consistent comparison + for _, config := range []map[string]interface{}{mergedConfig, expectedConfig, customMergedConfig, expectedCustomConfig} { + if config != nil { + if scrapeConfigs, ok := config["scrape_configs"].([]interface{}); ok { + sort.Slice(scrapeConfigs, func(i, j int) bool { + iConfig := scrapeConfigs[i].(map[interface{}]interface{}) + jConfig := scrapeConfigs[j].(map[interface{}]interface{}) + return iConfig["job_name"].(string) < jConfig["job_name"].(string) + }) + config["scrape_configs"] = scrapeConfigs + } + } + } + + // Use BeEquivalentTo which compares content without requiring same order + Expect(mergedConfig).To(BeEquivalentTo(expectedConfig), "Prometheus config content doesn't match") + if expectedMergedContentsFilePath != "" { + Expect(customMergedConfig).To(BeEquivalentTo(expectedCustomConfig), "Expected Custom Prometheus config content doesn't match") + } +} + +func setupConfigFiles(defaultPath bool) { + prefixes := testhelpers.CollectorPrefixesFor(configSettingsPrefix, configMapParserPrefix, false) + paths := testhelpers.CollectorConfigPaths{ + CollectorSettingsMountPath: &collectorSettingsMountPath, + DefaultSettingsMountPath: &defaultSettingsMountPath, + ConfigMapKeepListMountPath: &configMapKeepListMountPath, + } + + if err := testhelpers.SetupCollectorConfigFiles(defaultPath, prefixes, paths); err != nil { + panic(err) + } + + testhelpers.MustCreateTempFile(configSettingsPrefix, "controlplane-metrics", "") +} + +func setupProcessedFiles() { + prefixes := testhelpers.CollectorPrefixesFor(configSettingsPrefix, configMapParserPrefix, false) + paths := testhelpers.CollectorProcessedPaths{ + CollectorSettingsEnvVarPath: &collectorSettingsEnvVarPath, + DefaultSettingsEnvVarPath: &defaultSettingsEnvVarPath, + ConfigMapKeepListEnvVarPath: &configMapKeepListEnvVarPath, + ScrapeConfigDefinitionPathPrefix: &scrapeConfigDefinitionPathPrefix, + MergedDefaultConfigPath: &mergedDefaultConfigPath, + OpentelemetryMetricsEnvVarPath: &opentelemetryMetricsEnvVarPath, + } + + if err := testhelpers.SetupCollectorProcessedFiles(prefixes, paths); err != nil { + panic(err) + } +} diff --git a/otelcollector/shared/configmap/ccp/configmapsettings_suite_test.go b/otelcollector/shared/configmap/ccp/configmapsettings_suite_test.go new file mode 100644 index 000000000..9378b2798 --- /dev/null +++ b/otelcollector/shared/configmap/ccp/configmapsettings_suite_test.go @@ -0,0 +1,13 @@ +package ccpconfigmapsettings + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestConfigmapSettings(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Configmap Settings Suite") +} diff --git a/otelcollector/shared/configmap/ccp/definitions.go b/otelcollector/shared/configmap/ccp/definitions.go index 7b5ed75a8..42d7468c7 100644 --- a/otelcollector/shared/configmap/ccp/definitions.go +++ b/otelcollector/shared/configmap/ccp/definitions.go @@ -1,14 +1,20 @@ package ccpconfigmapsettings -type RegexValues struct { - ControlplaneKubeControllerManager string - ControlplaneKubeScheduler string - ControlplaneApiserver string - ControlplaneClusterAutoscaler string - ControlplaneNodeAutoProvisioning string - ControlplaneEtcd string - MinimalIngestionProfile string -} +var ( + configSettingsPrefix = "/etc/config/settings/" + configMapParserPrefix = "/opt/microsoft/configmapparser/" + schemaVersionFile = configSettingsPrefix + "schema-version" + configVersionFile = configSettingsPrefix + "config-version" + collectorSettingsEnvVarPath = configMapParserPrefix + "config_prometheus_collector_settings_env_var" + defaultSettingsEnvVarPath = configMapParserPrefix + "config_default_scrape_settings_env_var" + defaultSettingsMountPath = configSettingsPrefix + "default-scrape-settings-enabled" + defaultSettingsMountPathv2 = configSettingsPrefix + "default-targets-scrape-enabled" + collectorSettingsMountPath = configSettingsPrefix + "prometheus-collector-settings" + configMapKeepListMountPath = configSettingsPrefix + "default-targets-metrics-keep-list" + configMapKeepListEnvVarPath = configMapParserPrefix + "config_def_targets_metrics_keep_list_hash" + scrapeConfigDefinitionPathPrefix = "/opt/microsoft/otelcollector/default-prom-configs/" + mergedDefaultConfigPath = "/opt/defaultsMergedConfig.yml" +) // FilesystemConfigLoader implements ConfigLoader for file-based configuration loading. type FilesystemConfigLoader struct { diff --git a/otelcollector/shared/configmap/ccp/go.mod b/otelcollector/shared/configmap/ccp/go.mod index 50876ed08..02ac44cde 100644 --- a/otelcollector/shared/configmap/ccp/go.mod +++ b/otelcollector/shared/configmap/ccp/go.mod @@ -2,12 +2,17 @@ module github.com/prometheus-collector/shared/configmap/ccp replace github.com/prometheus-collector/shared => ../../../shared +replace github.com/prometheus-collector/shared/configmap/common/testhelpers => ../../../shared/configmap/common/testhelpers + go 1.23.0 toolchain go1.23.2 require ( + github.com/onsi/ginkgo/v2 v2.21.0 + github.com/onsi/gomega v1.35.1 github.com/prometheus-collector/shared v0.0.0-00010101000000-000000000000 + github.com/prometheus-collector/shared/configmap/common/testhelpers v0.0.0-00010101000000-000000000000 github.com/stretchr/testify v1.10.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -16,19 +21,24 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-logr/logr v1.4.2 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/google/gofuzz v1.2.0 // indirect + github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kr/text v0.2.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.62.0 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.65.0 // indirect github.com/x448/float16 v0.8.4 // indirect - golang.org/x/net v0.38.0 // indirect - golang.org/x/text v0.23.0 // indirect - google.golang.org/protobuf v1.36.5 // indirect + golang.org/x/net v0.40.0 // indirect + golang.org/x/sys v0.33.0 // indirect + golang.org/x/text v0.25.0 // indirect + golang.org/x/tools v0.26.0 // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apimachinery v0.32.0 // indirect diff --git a/otelcollector/shared/configmap/ccp/go.sum b/otelcollector/shared/configmap/ccp/go.sum index a04b4b52c..7e0d4a5d3 100644 --- a/otelcollector/shared/configmap/ccp/go.sum +++ b/otelcollector/shared/configmap/ccp/go.sum @@ -7,14 +7,18 @@ github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -28,13 +32,17 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= +github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= +github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= -github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE= +github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -56,28 +64,32 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= +golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= 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= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/otelcollector/shared/configmap/ccp/prometheus-ccp-config-merger-test.go b/otelcollector/shared/configmap/ccp/prometheus-ccp-config-merger-test.go index 7350eea83..129d395cc 100644 --- a/otelcollector/shared/configmap/ccp/prometheus-ccp-config-merger-test.go +++ b/otelcollector/shared/configmap/ccp/prometheus-ccp-config-merger-test.go @@ -5,6 +5,7 @@ import ( "strings" "testing" + cmcommon "github.com/prometheus-collector/shared/configmap/common" "github.com/stretchr/testify/require" ) @@ -85,8 +86,8 @@ func TestMergeYAML_WithMultipleJobsEnabled_ThenMergedConfigIsComplete(t *testing } // Act - mergedDefaultConfigs = deepMerge(mergedDefaultConfigs, config1) - mergedDefaultConfigs = deepMerge(mergedDefaultConfigs, config2) + mergedDefaultConfigs = cmcommon.DeepMerge(mergedDefaultConfigs, config1) + mergedDefaultConfigs = cmcommon.DeepMerge(mergedDefaultConfigs, config2) // Assert require.Equal(t, 1, len(mergedDefaultConfigs), "Exactly one root element") diff --git a/otelcollector/shared/configmap/ccp/prometheus-ccp-config-merger.go b/otelcollector/shared/configmap/ccp/prometheus-ccp-config-merger.go index 561788b21..d3dcde202 100644 --- a/otelcollector/shared/configmap/ccp/prometheus-ccp-config-merger.go +++ b/otelcollector/shared/configmap/ccp/prometheus-ccp-config-merger.go @@ -5,311 +5,85 @@ import ( "io/fs" "log" "os" - "reflect" "strings" - "gopkg.in/yaml.v2" -) - -const ( - mergedDefaultConfigPath = "/opt/defaultsMergedConfig.yml" - replicasetControllerType = "replicaset" - defaultPromConfigPathPrefix = "/opt/microsoft/otelcollector/default-prom-configs/" - regexHashFile = "/opt/microsoft/configmapparser/config_def_targets_metrics_keep_list_hash" - controlplaneApiserverDefaultFile = defaultPromConfigPathPrefix + "controlplane_apiserver.yml" - controlplaneKubeSchedulerDefaultFile = defaultPromConfigPathPrefix + "controlplane_kube_scheduler.yml" - controlplaneKubeControllerManagerFile = defaultPromConfigPathPrefix + "controlplane_kube_controller_manager.yml" - controlplaneClusterAutoscalerFile = defaultPromConfigPathPrefix + "controlplane_cluster_autoscaler.yml" - controlplaneNodeAutoProvisioningFile = defaultPromConfigPathPrefix + "controlplane_node_auto_provisioning.yml" - controlplaneEtcdDefaultFile = defaultPromConfigPathPrefix + "controlplane_etcd.yml" -) - -var ( - regexHash = make(map[string]string) - intervalHash = make(map[string]string) + "github.com/prometheus-collector/shared" + cmcommon "github.com/prometheus-collector/shared/configmap/common" ) var mergedDefaultConfigs map[interface{}]interface{} -func loadRegexHash() { - data, err := os.ReadFile(regexHashFile) - if err != nil { - fmt.Printf("Exception in loadRegexHash for prometheus config: %v. Keep list regexes will not be used\n", err) - return - } - - err = yaml.Unmarshal(data, ®exHash) - if err != nil { - fmt.Printf("Exception in loadRegexHash for prometheus config: %v. Keep list regexes will not be used\n", err) - } -} - func appendMetricRelabelConfig(yamlConfigFile, keepListRegex string) { - fmt.Printf("Adding keep list regex or minimal ingestion regex for %s\n", yamlConfigFile) - - content, err := os.ReadFile(yamlConfigFile) - if err != nil { - fmt.Printf("Error reading config file %s: %v. The keep list regex will not be used\n", yamlConfigFile, err) - return - } - - var config map[string]interface{} - if err := yaml.Unmarshal(content, &config); err != nil { - fmt.Printf("Error unmarshalling YAML for %s: %v. The keep list regex will not be used\n", yamlConfigFile, err) - return - } - - keepListMetricRelabelConfig := map[string]interface{}{ - "source_labels": []interface{}{"__name__"}, - "action": "keep", - "regex": keepListRegex, - } - - if scrapeConfigs, ok := config["scrape_configs"].([]interface{}); ok { - for i, scfg := range scrapeConfigs { - // Ensure scfg is a map with string keys - if scfgMap, ok := scfg.(map[interface{}]interface{}); ok { - // Convert to map[string]interface{} - stringScfgMap := make(map[string]interface{}) - for k, v := range scfgMap { - if key, ok := k.(string); ok { - stringScfgMap[key] = v - } else { - fmt.Printf("Encountered non-string key in scrape config map: %v\n", k) - return - } - } - - // Update or add metric_relabel_configs - if metricRelabelCfgs, ok := stringScfgMap["metric_relabel_configs"].([]interface{}); ok { - stringScfgMap["metric_relabel_configs"] = append(metricRelabelCfgs, keepListMetricRelabelConfig) - } else { - stringScfgMap["metric_relabel_configs"] = []interface{}{keepListMetricRelabelConfig} - } - - // Convert back to map[interface{}]interface{} for YAML marshalling - interfaceScfgMap := make(map[interface{}]interface{}) - for k, v := range stringScfgMap { - interfaceScfgMap[k] = v - } - - // Update the scrape_configs list - scrapeConfigs[i] = interfaceScfgMap - } - } - - // Write updated scrape_configs back to config - config["scrape_configs"] = scrapeConfigs - - // Marshal the updated config to YAML - cfgYamlWithMetricRelabelConfig, err := yaml.Marshal(config) - if err != nil { - fmt.Printf("Error marshalling YAML for %s: %v. The keep list regex will not be used\n", yamlConfigFile, err) - return - } - - // Write the updated YAML back to the file - if err := os.WriteFile(yamlConfigFile, cfgYamlWithMetricRelabelConfig, fs.FileMode(0644)); err != nil { - fmt.Printf("Error writing to file %s: %v. The keep list regex will not be used\n", yamlConfigFile, err) - return - } - } else { - fmt.Printf("No 'scrape_configs' found in the YAML. The keep list regex will not be used.\n") + if err := cmcommon.AppendMetricRelabelConfig(yamlConfigFile, keepListRegex, log.Printf); err != nil { + log.Printf("Error updating metric relabel config for %s: %v\n", yamlConfigFile, err) } } func populateDefaultPrometheusConfig() { - loadRegexHash() defaultConfigs := []string{} - currentControllerType := strings.TrimSpace(strings.ToLower(os.Getenv("CONTROLLER_TYPE"))) - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_CONTROLPLANE_KUBE_CONTROLLER_MANAGER_ENABLED"); exists && strings.ToLower(enabled) == "true" && currentControllerType == replicasetControllerType { - fmt.Println("Kube Controller Manager enabled.") - kubeControllerManagerMetricsKeepListRegex, exists := regexHash["CONTROLPLANE_KUBE_CONTROLLER_MANAGER_KEEP_LIST_REGEX"] - if exists && kubeControllerManagerMetricsKeepListRegex != "" { - fmt.Printf("Using regex for Kube Controller Manager: %s\n", kubeControllerManagerMetricsKeepListRegex) - appendMetricRelabelConfig(controlplaneKubeControllerManagerFile, kubeControllerManagerMetricsKeepListRegex) - } - contents, err := os.ReadFile(controlplaneKubeControllerManagerFile) - if err == nil { - contents = []byte(strings.Replace(string(contents), "$$POD_NAMESPACE$$", os.Getenv("POD_NAMESPACE"), -1)) - err = os.WriteFile(controlplaneKubeControllerManagerFile, contents, fs.FileMode(0644)) - } - defaultConfigs = append(defaultConfigs, controlplaneKubeControllerManagerFile) - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_CONTROLPLANE_KUBE_SCHEDULER_ENABLED"); exists && strings.ToLower(enabled) == "true" && currentControllerType == replicasetControllerType { - controlplaneKubeSchedulerKeepListRegex, exists := regexHash["CONTROLPLANE_KUBE_SCHEDULER_KEEP_LIST_REGEX"] - if exists && controlplaneKubeSchedulerKeepListRegex != "" { - appendMetricRelabelConfig(controlplaneKubeSchedulerDefaultFile, controlplaneKubeSchedulerKeepListRegex) - } - contents, err := os.ReadFile(controlplaneKubeSchedulerDefaultFile) - if err == nil { - contents = []byte(strings.Replace(string(contents), "$$POD_NAMESPACE$$", os.Getenv("POD_NAMESPACE"), -1)) - err = os.WriteFile(controlplaneKubeSchedulerDefaultFile, contents, fs.FileMode(0644)) - } - defaultConfigs = append(defaultConfigs, controlplaneKubeSchedulerDefaultFile) - } + currentControllerType := os.Getenv("CONTROLLER_TYPE") - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_CONTROLPLANE_APISERVER_ENABLED"); exists && strings.ToLower(enabled) == "true" && currentControllerType == replicasetControllerType { - controlplaneApiserverKeepListRegex, exists := regexHash["CONTROLPLANE_APISERVER_KEEP_LIST_REGEX"] - if exists && controlplaneApiserverKeepListRegex != "" { - appendMetricRelabelConfig(controlplaneApiserverDefaultFile, controlplaneApiserverKeepListRegex) - } - contents, err := os.ReadFile(controlplaneApiserverDefaultFile) - if err == nil { - contents = []byte(strings.Replace(string(contents), "$$POD_NAMESPACE$$", os.Getenv("POD_NAMESPACE"), -1)) - err = os.WriteFile(controlplaneApiserverDefaultFile, contents, fs.FileMode(0644)) - } - defaultConfigs = append(defaultConfigs, controlplaneApiserverDefaultFile) - } + for jobName, job := range shared.ControlPlaneDefaultScrapeJobs { + if job.Enabled && job.ControllerType == currentControllerType { + fmt.Printf("%s job enabled\n", jobName) - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_CONTROLPLANE_CLUSTER_AUTOSCALER_ENABLED"); exists && strings.ToLower(enabled) == "true" && currentControllerType == replicasetControllerType { - controlplaneClusterAutoscalerKeepListRegex, exists := regexHash["CONTROLPLANE_CLUSTER_AUTOSCALER_KEEP_LIST_REGEX"] - if exists && controlplaneClusterAutoscalerKeepListRegex != "" { - appendMetricRelabelConfig(controlplaneClusterAutoscalerFile, controlplaneClusterAutoscalerKeepListRegex) - } - contents, err := os.ReadFile(controlplaneClusterAutoscalerFile) - if err == nil { - contents = []byte(strings.Replace(string(contents), "$$POD_NAMESPACE$$", os.Getenv("POD_NAMESPACE"), -1)) - err = os.WriteFile(controlplaneClusterAutoscalerFile, contents, fs.FileMode(0644)) - } - defaultConfigs = append(defaultConfigs, controlplaneClusterAutoscalerFile) - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_CONTROLPLANE_NODE_AUTO_PROVISIONING_ENABLED"); exists && strings.ToLower(enabled) == "true" && currentControllerType == replicasetControllerType { - controlplaneNodeAutoProvisioningKeepListRegex, exists := regexHash["CONTROLPLANE_NODE_AUTO_PROVISIONING_KEEP_LIST_REGEX"] - if exists && controlplaneNodeAutoProvisioningKeepListRegex != "" { - appendMetricRelabelConfig(controlplaneNodeAutoProvisioningFile, controlplaneNodeAutoProvisioningKeepListRegex) - } - contents, err := os.ReadFile(controlplaneNodeAutoProvisioningFile) - if err == nil { - contents = []byte(strings.Replace(string(contents), "$$POD_NAMESPACE$$", os.Getenv("POD_NAMESPACE"), -1)) - err = os.WriteFile(controlplaneNodeAutoProvisioningFile, contents, fs.FileMode(0644)) - } - defaultConfigs = append(defaultConfigs, controlplaneNodeAutoProvisioningFile) - } + if job.CustomerKeepListRegex != "" { + fmt.Printf("Using regex for %s: %s\n", jobName, job.CustomerKeepListRegex) + appendMetricRelabelConfig(scrapeConfigDefinitionPathPrefix+job.ScrapeConfigDefinitionFile, job.CustomerKeepListRegex) + } - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_CONTROLPLANE_ETCD_ENABLED"); exists && strings.ToLower(enabled) == "true" && currentControllerType == replicasetControllerType { - controlplaneEtcdKeepListRegex, exists := regexHash["CONTROLPLANE_ETCD_KEEP_LIST_REGEX"] - if exists && controlplaneEtcdKeepListRegex != "" { - appendMetricRelabelConfig(controlplaneEtcdDefaultFile, controlplaneEtcdKeepListRegex) - } - contents, err := os.ReadFile(controlplaneEtcdDefaultFile) - if err == nil { - contents = []byte(strings.Replace(string(contents), "$$POD_NAMESPACE$$", os.Getenv("POD_NAMESPACE"), -1)) - err = os.WriteFile(controlplaneEtcdDefaultFile, contents, fs.FileMode(0644)) + if err := cmcommon.ReplacePlaceholders(scrapeConfigDefinitionPathPrefix+job.ScrapeConfigDefinitionFile, job.PlaceholderNames); err != nil { + log.Printf("Error replacing placeholders for %s: %v\n", jobName, err) + } + defaultConfigs = append(defaultConfigs, scrapeConfigDefinitionPathPrefix+job.ScrapeConfigDefinitionFile) } - defaultConfigs = append(defaultConfigs, controlplaneEtcdDefaultFile) } mergedDefaultConfigs = mergeDefaultScrapeConfigs(defaultConfigs) - // if mergedDefaultConfigs != nil { - // fmt.Printf("Merged default scrape targets: %v\n", mergedDefaultConfigs) - // } } func mergeDefaultScrapeConfigs(defaultScrapeConfigs []string) map[interface{}]interface{} { - mergedDefaultConfigs := make(map[interface{}]interface{}) + merged := make(map[interface{}]interface{}) if len(defaultScrapeConfigs) > 0 { - mergedDefaultConfigs["scrape_configs"] = make([]interface{}, 0) + merged["scrape_configs"] = make([]interface{}, 0) for _, defaultScrapeConfig := range defaultScrapeConfigs { - defaultConfigYaml, err := loadYAMLFromFile(defaultScrapeConfig) + defaultConfigYaml, err := cmcommon.LoadYAMLFromFile(defaultScrapeConfig) if err != nil { log.Printf("Error loading YAML from file %s: %s\n", defaultScrapeConfig, err) continue } - mergedDefaultConfigs = deepMerge(mergedDefaultConfigs, defaultConfigYaml) + merged = cmcommon.DeepMerge(merged, defaultConfigYaml) } } fmt.Printf("Done merging %d default prometheus config(s)\n", len(defaultScrapeConfigs)) - return mergedDefaultConfigs -} - -func loadYAMLFromFile(filename string) (map[interface{}]interface{}, error) { - fileContent, err := os.ReadFile(filename) - if err != nil { - return nil, err - } - - var yamlData map[interface{}]interface{} - err = yaml.Unmarshal(fileContent, &yamlData) - if err != nil { - return nil, err - } - - return yamlData, nil -} - -// This needs unit tests - -func deepMerge(target, source map[interface{}]interface{}) map[interface{}]interface{} { - for key, sourceValue := range source { - targetValue, exists := target[key] - - if !exists { - target[key] = sourceValue - continue - } - - targetMap, targetMapOk := targetValue.(map[interface{}]interface{}) - sourceMap, sourceMapOk := sourceValue.(map[interface{}]interface{}) - - if targetMapOk && sourceMapOk { - target[key] = deepMerge(targetMap, sourceMap) - } else if reflect.TypeOf(targetValue) == reflect.TypeOf(sourceValue) { - // Both are slices, concatenate them - if targetSlice, targetSliceOk := targetValue.([]interface{}); targetSliceOk { - if sourceSlice, sourceSliceOk := sourceValue.([]interface{}); sourceSliceOk { - target[key] = append(targetSlice, sourceSlice...) - } - } - } else { - // If types are different, simply overwrite with the source value - target[key] = sourceValue - } - } - - return target + return merged } func writeDefaultScrapeTargetsFile() { fmt.Printf("Start Updating Default Prometheus Config\n") noDefaultScrapingEnabled := os.Getenv("AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED") if noDefaultScrapingEnabled != "" && strings.ToLower(noDefaultScrapingEnabled) == "false" { - loadRegexHash() populateDefaultPrometheusConfig() - if mergedDefaultConfigs != nil && len(mergedDefaultConfigs) > 0 { + if len(mergedDefaultConfigs) > 0 { fmt.Printf("Starting to merge default prometheus config values in collector template as backup\n") - mergedDefaultConfigYaml, err := yaml.Marshal(mergedDefaultConfigs) - if err == nil { - err = os.WriteFile(mergedDefaultConfigPath, []byte(mergedDefaultConfigYaml), fs.FileMode(0644)) - if err != nil { - fmt.Printf("Error writing merged default prometheus config to file: %v\n", err) - } - } else { - fmt.Printf("Error marshalling merged default prometheus config: %v\n", err) + if err := cmcommon.WriteYAML(mergedDefaultConfigPath, mergedDefaultConfigs); err != nil { + fmt.Printf("Error writing merged default prometheus config to file: %v\n", err) } } } else { - mergedDefaultConfigs = nil + mergedDefaultConfigs = make(map[interface{}]interface{}) } - fmt.Printf("Done creating default targets file\n") } func setDefaultFileScrapeInterval(scrapeInterval string) { - defaultFilesArray := []string{ - controlplaneApiserverDefaultFile, controlplaneKubeSchedulerDefaultFile, controlplaneKubeControllerManagerFile, - controlplaneClusterAutoscalerFile, controlplaneNodeAutoProvisioningFile, controlplaneEtcdDefaultFile, - } - - for _, currentFile := range defaultFilesArray { + for _, job := range shared.ControlPlaneDefaultScrapeJobs { + currentFile := scrapeConfigDefinitionPathPrefix + job.ScrapeConfigDefinitionFile contents, err := os.ReadFile(currentFile) if err != nil { fmt.Printf("Error reading file %s: %v\n", currentFile, err) diff --git a/otelcollector/shared/configmap/ccp/testdata/advanced-linux-rs.yaml b/otelcollector/shared/configmap/ccp/testdata/advanced-linux-rs.yaml new file mode 100644 index 000000000..0d67497c3 --- /dev/null +++ b/otelcollector/shared/configmap/ccp/testdata/advanced-linux-rs.yaml @@ -0,0 +1,379 @@ +scrape_configs: +- job_name: controlplane-apiserver + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: endpoints + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: hashmod + modulus: 10000000000000000000 + regex: (.+) + source_labels: + - host + target_label: hostalias + - regex: ^(localhost|\[::1\]):443$ + replacement: kube-apiserver + source_labels: + - host + target_label: hostalias + - action: replace + regex: ^(.+);(.+)$ + source_labels: + - hostalias + - host + target_label: host + - action: drop + regex: (go_.*|process_(cpu|max|resident|virtual|open)_.*) + source_labels: + - __name__ + - action: labeldrop + regex: hostalias + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-apiserver;kube-apiserver + source_labels: + - __meta_kubernetes_pod_label_k8s_app + - __meta_kubernetes_pod_container_name + - action: replace + regex: (.*) + source_labels: + - __meta_kubernetes_pod_name + target_label: instance + scheme: https + scrape_interval: 30s + tls_config: + ca_file: /etc/kubernetes/secrets/ca.pem + cert_file: /etc/kubernetes/secrets/client.pem + insecure_skip_verify: true + key_file: /etc/kubernetes/secrets/client-key.pem +- follow_redirects: false + job_name: controlplane-cluster-autoscaler + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: pod + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: hashmod + modulus: 10000000000000000000 + regex: ^(.+)$ + source_labels: + - host + target_label: hostalias + - regex: ^hcp-kubernetes.*.svc.cluster.local:443$ + replacement: kube-apiserver + source_labels: + - host + target_label: hostalias + - action: replace + regex: ^(.+);(.+)$ + source_labels: + - hostalias + - host + target_label: host + - action: drop + regex: (go_.*|process_(cpu|max|resident|virtual|open)_.*) + source_labels: + - __name__ + - action: labeldrop + regex: hostalias + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: cluster-autoscaler;cluster-autoscaler + source_labels: + - __meta_kubernetes_pod_label_app + - __meta_kubernetes_pod_container_name + - action: keep + regex: true + source_labels: + - __meta_kubernetes_pod_annotation_aks_prometheus_io_scrape + - action: replace + regex: (.+) + source_labels: + - __meta_kubernetes_pod_annotation_aks_prometheus_io_path + target_label: __metrics_path__ + - action: replace + separator: ':' + source_labels: + - __address__ + - __meta_kubernetes_pod_annotation_aks_prometheus_io_port + target_label: __address__ + - action: replace + regex: (.*) + source_labels: + - __meta_kubernetes_pod_name + target_label: instance + scrape_interval: 30s + tls_config: + ca_file: /etc/kubernetes/secrets/ca.pem + cert_file: /etc/kubernetes/secrets/client.pem + insecure_skip_verify: true + key_file: /etc/kubernetes/secrets/client-key.pem +- follow_redirects: false + job_name: controlplane-kube-scheduler + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: pod + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: hashmod + modulus: 10000000000000000000 + regex: ^(.+)$ + source_labels: + - host + target_label: hostalias + - regex: ^hcp-kubernetes.*.svc.cluster.local:443$ + replacement: kube-apiserver + source_labels: + - host + target_label: hostalias + - action: replace + regex: ^(.+);(.+)$ + source_labels: + - hostalias + - host + target_label: host + - action: drop + regex: (go_.*|process_(cpu|max|resident|virtual|open)_.*) + source_labels: + - __name__ + - action: labeldrop + regex: hostalias + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-scheduler;kube-scheduler + source_labels: + - __meta_kubernetes_pod_label_k8s_app + - __meta_kubernetes_pod_container_name + - action: keep + regex: true + source_labels: + - __meta_kubernetes_pod_annotation_aks_prometheus_io_scrape + - action: replace + regex: (.+) + source_labels: + - __meta_kubernetes_pod_annotation_aks_prometheus_io_path + target_label: __metrics_path__ + - action: replace + separator: ':' + source_labels: + - __address__ + - __meta_kubernetes_pod_annotation_aks_prometheus_io_port + target_label: __address__ + - action: replace + regex: (.*) + source_labels: + - __meta_kubernetes_pod_name + target_label: instance + scheme: https + scrape_interval: 30s + tls_config: + ca_file: /etc/kubernetes/secrets/ca.pem + cert_file: /etc/kubernetes/secrets/client.pem + insecure_skip_verify: true + key_file: /etc/kubernetes/secrets/client-key.pem +- follow_redirects: false + job_name: controlplane-kube-controller-manager + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: pod + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: hashmod + modulus: 10000000000000000000 + regex: ^(.+)$ + source_labels: + - host + target_label: hostalias + - regex: ^hcp-kubernetes.*.svc.cluster.local:443$ + replacement: kube-apiserver + source_labels: + - host + target_label: hostalias + - action: replace + regex: ^(.+);(.+)$ + source_labels: + - hostalias + - host + target_label: host + - action: drop + regex: (go_.*|process_(cpu|max|resident|virtual|open)_.*) + source_labels: + - __name__ + - action: labeldrop + regex: hostalias + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-controller-manager;kube-controller-manager + source_labels: + - __meta_kubernetes_pod_label_k8s_app + - __meta_kubernetes_pod_container_name + - action: keep + regex: true + source_labels: + - __meta_kubernetes_pod_annotation_aks_prometheus_io_scrape + - action: replace + regex: (.+) + source_labels: + - __meta_kubernetes_pod_annotation_aks_prometheus_io_path + target_label: __metrics_path__ + - action: replace + separator: ':' + source_labels: + - __address__ + - __meta_kubernetes_pod_annotation_aks_prometheus_io_port + target_label: __address__ + - action: replace + regex: (.*) + source_labels: + - __meta_kubernetes_pod_name + target_label: instance + scheme: https + scrape_interval: 30s + tls_config: + ca_file: /etc/kubernetes/secrets/ca.pem + cert_file: /etc/kubernetes/secrets/client.pem + insecure_skip_verify: true + key_file: /etc/kubernetes/secrets/client-key.pem +- follow_redirects: false + job_name: controlplane-etcd + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: endpoints + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: hashmod + modulus: 10000000000000000000 + regex: ^(.+)$ + source_labels: + - host + target_label: hostalias + - regex: ^hcp-kubernetes.*.svc.cluster.local:443$ + replacement: kube-apiserver + source_labels: + - host + target_label: hostalias + - action: replace + regex: ^(.+);(.+)$ + source_labels: + - hostalias + - host + target_label: host + - action: drop + regex: (go_.*|process_(cpu|max|resident|virtual|open)_.*) + source_labels: + - __name__ + - action: labeldrop + regex: hostalias + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: etcd;2379 + source_labels: + - __meta_kubernetes_service_label_app + - __meta_kubernetes_pod_container_port_number + - action: replace + regex: (.*) + source_labels: + - __meta_kubernetes_pod_name + target_label: instance + - action: drop + regex: (etcd2-.*) + source_labels: + - __meta_kubernetes_pod_name + scheme: https + scrape_interval: 30s + tls_config: + ca_file: /etc/kubernetes/secrets/etcd-client-ca.crt + cert_file: /etc/kubernetes/secrets/etcd-client.crt + insecure_skip_verify: true + key_file: /etc/kubernetes/secrets/etcd-client.key +- follow_redirects: false + job_name: controlplane-node-auto-provisioning + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: pod + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: hashmod + modulus: 10000000000000000000 + regex: ^(.+)$ + source_labels: + - host + target_label: hostalias + - regex: ^hcp-kubernetes.*.svc.cluster.local:443$ + replacement: kube-apiserver + source_labels: + - host + target_label: hostalias + - action: replace + regex: ^(.+);(.+)$ + source_labels: + - hostalias + - host + target_label: host + - action: drop + regex: (go_.*|process_(cpu|max|resident|virtual|open)_.*) + source_labels: + - __name__ + - action: labeldrop + regex: hostalias + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: karpenter;controller;8000 + source_labels: + - __meta_kubernetes_pod_label_app + - __meta_kubernetes_pod_container_name + - __meta_kubernetes_pod_container_port_number + - action: replace + regex: (.*) + source_labels: + - __meta_kubernetes_pod_name + target_label: instance + scrape_interval: 30s diff --git a/otelcollector/shared/configmap/ccp/testdata/advanced-no-minimal-linux-rs.yaml b/otelcollector/shared/configmap/ccp/testdata/advanced-no-minimal-linux-rs.yaml new file mode 100644 index 000000000..900df1248 --- /dev/null +++ b/otelcollector/shared/configmap/ccp/testdata/advanced-no-minimal-linux-rs.yaml @@ -0,0 +1,379 @@ +scrape_configs: +- follow_redirects: false + job_name: controlplane-node-auto-provisioning + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: pod + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: hashmod + modulus: 10000000000000000000 + regex: ^(.+)$ + source_labels: + - host + target_label: hostalias + - regex: ^hcp-kubernetes.*.svc.cluster.local:443$ + replacement: kube-apiserver + source_labels: + - host + target_label: hostalias + - action: replace + regex: ^(.+);(.+)$ + source_labels: + - hostalias + - host + target_label: host + - action: drop + regex: (go_.*|process_(cpu|max|resident|virtual|open)_.*) + source_labels: + - __name__ + - action: labeldrop + regex: hostalias + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: karpenter;controller;8000 + source_labels: + - __meta_kubernetes_pod_label_app + - __meta_kubernetes_pod_container_name + - __meta_kubernetes_pod_container_port_number + - action: replace + regex: (.*) + source_labels: + - __meta_kubernetes_pod_name + target_label: instance + scrape_interval: 30s +- job_name: controlplane-apiserver + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: endpoints + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: hashmod + modulus: 10000000000000000000 + regex: (.+) + source_labels: + - host + target_label: hostalias + - regex: ^(localhost|\[::1\]):443$ + replacement: kube-apiserver + source_labels: + - host + target_label: hostalias + - action: replace + regex: ^(.+);(.+)$ + source_labels: + - hostalias + - host + target_label: host + - action: drop + regex: (go_.*|process_(cpu|max|resident|virtual|open)_.*) + source_labels: + - __name__ + - action: labeldrop + regex: hostalias + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-apiserver;kube-apiserver + source_labels: + - __meta_kubernetes_pod_label_k8s_app + - __meta_kubernetes_pod_container_name + - action: replace + regex: (.*) + source_labels: + - __meta_kubernetes_pod_name + target_label: instance + scheme: https + scrape_interval: 30s + tls_config: + ca_file: /etc/kubernetes/secrets/ca.pem + cert_file: /etc/kubernetes/secrets/client.pem + insecure_skip_verify: true + key_file: /etc/kubernetes/secrets/client-key.pem +- follow_redirects: false + job_name: controlplane-cluster-autoscaler + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: pod + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: hashmod + modulus: 10000000000000000000 + regex: ^(.+)$ + source_labels: + - host + target_label: hostalias + - regex: ^hcp-kubernetes.*.svc.cluster.local:443$ + replacement: kube-apiserver + source_labels: + - host + target_label: hostalias + - action: replace + regex: ^(.+);(.+)$ + source_labels: + - hostalias + - host + target_label: host + - action: drop + regex: (go_.*|process_(cpu|max|resident|virtual|open)_.*) + source_labels: + - __name__ + - action: labeldrop + regex: hostalias + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: cluster-autoscaler;cluster-autoscaler + source_labels: + - __meta_kubernetes_pod_label_app + - __meta_kubernetes_pod_container_name + - action: keep + regex: true + source_labels: + - __meta_kubernetes_pod_annotation_aks_prometheus_io_scrape + - action: replace + regex: (.+) + source_labels: + - __meta_kubernetes_pod_annotation_aks_prometheus_io_path + target_label: __metrics_path__ + - action: replace + separator: ':' + source_labels: + - __address__ + - __meta_kubernetes_pod_annotation_aks_prometheus_io_port + target_label: __address__ + - action: replace + regex: (.*) + source_labels: + - __meta_kubernetes_pod_name + target_label: instance + scrape_interval: 30s + tls_config: + ca_file: /etc/kubernetes/secrets/ca.pem + cert_file: /etc/kubernetes/secrets/client.pem + insecure_skip_verify: true + key_file: /etc/kubernetes/secrets/client-key.pem +- follow_redirects: false + job_name: controlplane-kube-scheduler + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: pod + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: hashmod + modulus: 10000000000000000000 + regex: ^(.+)$ + source_labels: + - host + target_label: hostalias + - regex: ^hcp-kubernetes.*.svc.cluster.local:443$ + replacement: kube-apiserver + source_labels: + - host + target_label: hostalias + - action: replace + regex: ^(.+);(.+)$ + source_labels: + - hostalias + - host + target_label: host + - action: drop + regex: (go_.*|process_(cpu|max|resident|virtual|open)_.*) + source_labels: + - __name__ + - action: labeldrop + regex: hostalias + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-scheduler;kube-scheduler + source_labels: + - __meta_kubernetes_pod_label_k8s_app + - __meta_kubernetes_pod_container_name + - action: keep + regex: true + source_labels: + - __meta_kubernetes_pod_annotation_aks_prometheus_io_scrape + - action: replace + regex: (.+) + source_labels: + - __meta_kubernetes_pod_annotation_aks_prometheus_io_path + target_label: __metrics_path__ + - action: replace + separator: ':' + source_labels: + - __address__ + - __meta_kubernetes_pod_annotation_aks_prometheus_io_port + target_label: __address__ + - action: replace + regex: (.*) + source_labels: + - __meta_kubernetes_pod_name + target_label: instance + scheme: https + scrape_interval: 30s + tls_config: + ca_file: /etc/kubernetes/secrets/ca.pem + cert_file: /etc/kubernetes/secrets/client.pem + insecure_skip_verify: true + key_file: /etc/kubernetes/secrets/client-key.pem +- follow_redirects: false + job_name: controlplane-kube-controller-manager + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: pod + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: hashmod + modulus: 10000000000000000000 + regex: ^(.+)$ + source_labels: + - host + target_label: hostalias + - regex: ^hcp-kubernetes.*.svc.cluster.local:443$ + replacement: kube-apiserver + source_labels: + - host + target_label: hostalias + - action: replace + regex: ^(.+);(.+)$ + source_labels: + - hostalias + - host + target_label: host + - action: drop + regex: (go_.*|process_(cpu|max|resident|virtual|open)_.*) + source_labels: + - __name__ + - action: labeldrop + regex: hostalias + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-controller-manager;kube-controller-manager + source_labels: + - __meta_kubernetes_pod_label_k8s_app + - __meta_kubernetes_pod_container_name + - action: keep + regex: true + source_labels: + - __meta_kubernetes_pod_annotation_aks_prometheus_io_scrape + - action: replace + regex: (.+) + source_labels: + - __meta_kubernetes_pod_annotation_aks_prometheus_io_path + target_label: __metrics_path__ + - action: replace + separator: ':' + source_labels: + - __address__ + - __meta_kubernetes_pod_annotation_aks_prometheus_io_port + target_label: __address__ + - action: replace + regex: (.*) + source_labels: + - __meta_kubernetes_pod_name + target_label: instance + scheme: https + scrape_interval: 30s + tls_config: + ca_file: /etc/kubernetes/secrets/ca.pem + cert_file: /etc/kubernetes/secrets/client.pem + insecure_skip_verify: true + key_file: /etc/kubernetes/secrets/client-key.pem +- follow_redirects: false + job_name: controlplane-etcd + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: endpoints + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: hashmod + modulus: 10000000000000000000 + regex: ^(.+)$ + source_labels: + - host + target_label: hostalias + - regex: ^hcp-kubernetes.*.svc.cluster.local:443$ + replacement: kube-apiserver + source_labels: + - host + target_label: hostalias + - action: replace + regex: ^(.+);(.+)$ + source_labels: + - hostalias + - host + target_label: host + - action: drop + regex: (go_.*|process_(cpu|max|resident|virtual|open)_.*) + source_labels: + - __name__ + - action: labeldrop + regex: hostalias + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: etcd;2379 + source_labels: + - __meta_kubernetes_service_label_app + - __meta_kubernetes_pod_container_port_number + - action: replace + regex: (.*) + source_labels: + - __meta_kubernetes_pod_name + target_label: instance + - action: drop + regex: (etcd2-.*) + source_labels: + - __meta_kubernetes_pod_name + scheme: https + scrape_interval: 30s + tls_config: + ca_file: /etc/kubernetes/secrets/etcd-client-ca.crt + cert_file: /etc/kubernetes/secrets/etcd-client.crt + insecure_skip_verify: true + key_file: /etc/kubernetes/secrets/etcd-client.key diff --git a/otelcollector/shared/configmap/ccp/testdata/default-linux-rs.yaml b/otelcollector/shared/configmap/ccp/testdata/default-linux-rs.yaml new file mode 100644 index 000000000..4638df4d3 --- /dev/null +++ b/otelcollector/shared/configmap/ccp/testdata/default-linux-rs.yaml @@ -0,0 +1,108 @@ +scrape_configs: +- job_name: controlplane-apiserver + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: endpoints + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: hashmod + modulus: 10000000000000000000 + regex: (.+) + source_labels: + - host + target_label: hostalias + - regex: ^(localhost|\[::1\]):443$ + replacement: kube-apiserver + source_labels: + - host + target_label: hostalias + - action: replace + regex: ^(.+);(.+)$ + source_labels: + - hostalias + - host + target_label: host + - action: drop + regex: (go_.*|process_(cpu|max|resident|virtual|open)_.*) + source_labels: + - __name__ + - action: labeldrop + regex: hostalias + relabel_configs: + - action: keep + regex: kube-apiserver;kube-apiserver + source_labels: + - __meta_kubernetes_pod_label_k8s_app + - __meta_kubernetes_pod_container_name + - action: replace + regex: (.*) + source_labels: + - __meta_kubernetes_pod_name + target_label: instance + scheme: https + scrape_interval: 30s + tls_config: + ca_file: /etc/kubernetes/secrets/ca.pem + cert_file: /etc/kubernetes/secrets/client.pem + insecure_skip_verify: true + key_file: /etc/kubernetes/secrets/client-key.pem +- follow_redirects: false + job_name: controlplane-etcd + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: endpoints + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: hashmod + modulus: 10000000000000000000 + regex: ^(.+)$ + source_labels: + - host + target_label: hostalias + - regex: ^hcp-kubernetes.*.svc.cluster.local:443$ + replacement: kube-apiserver + source_labels: + - host + target_label: hostalias + - action: replace + regex: ^(.+);(.+)$ + source_labels: + - hostalias + - host + target_label: host + - action: drop + regex: (go_.*|process_(cpu|max|resident|virtual|open)_.*) + source_labels: + - __name__ + - action: labeldrop + regex: hostalias + relabel_configs: + - action: keep + regex: etcd;2379 + source_labels: + - __meta_kubernetes_service_label_app + - __meta_kubernetes_pod_container_port_number + - action: replace + regex: (.*) + source_labels: + - __meta_kubernetes_pod_name + target_label: instance + - action: drop + regex: (etcd2-.*) + source_labels: + - __meta_kubernetes_pod_name + scheme: https + scrape_interval: 30s + tls_config: + ca_file: /etc/kubernetes/secrets/etcd-client-ca.crt + cert_file: /etc/kubernetes/secrets/etcd-client.crt + insecure_skip_verify: true + key_file: /etc/kubernetes/secrets/etcd-client.key diff --git a/otelcollector/shared/configmap/ccp/testdata/no-minimal-linux-rs.yaml b/otelcollector/shared/configmap/ccp/testdata/no-minimal-linux-rs.yaml new file mode 100644 index 000000000..7269e2be0 --- /dev/null +++ b/otelcollector/shared/configmap/ccp/testdata/no-minimal-linux-rs.yaml @@ -0,0 +1,116 @@ +scrape_configs: +- job_name: controlplane-apiserver + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: endpoints + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: hashmod + modulus: 10000000000000000000 + regex: (.+) + source_labels: + - host + target_label: hostalias + - regex: ^(localhost|\[::1\]):443$ + replacement: kube-apiserver + source_labels: + - host + target_label: hostalias + - action: replace + regex: ^(.+);(.+)$ + source_labels: + - hostalias + - host + target_label: host + - action: drop + regex: (go_.*|process_(cpu|max|resident|virtual|open)_.*) + source_labels: + - __name__ + - action: labeldrop + regex: hostalias + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-apiserver;kube-apiserver + source_labels: + - __meta_kubernetes_pod_label_k8s_app + - __meta_kubernetes_pod_container_name + - action: replace + regex: (.*) + source_labels: + - __meta_kubernetes_pod_name + target_label: instance + scheme: https + scrape_interval: 30s + tls_config: + ca_file: /etc/kubernetes/secrets/ca.pem + cert_file: /etc/kubernetes/secrets/client.pem + insecure_skip_verify: true + key_file: /etc/kubernetes/secrets/client-key.pem +- follow_redirects: false + job_name: controlplane-etcd + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: endpoints + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: hashmod + modulus: 10000000000000000000 + regex: ^(.+)$ + source_labels: + - host + target_label: hostalias + - regex: ^hcp-kubernetes.*.svc.cluster.local:443$ + replacement: kube-apiserver + source_labels: + - host + target_label: hostalias + - action: replace + regex: ^(.+);(.+)$ + source_labels: + - hostalias + - host + target_label: host + - action: drop + regex: (go_.*|process_(cpu|max|resident|virtual|open)_.*) + source_labels: + - __name__ + - action: labeldrop + regex: hostalias + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: etcd;2379 + source_labels: + - __meta_kubernetes_service_label_app + - __meta_kubernetes_pod_container_port_number + - action: replace + regex: (.*) + source_labels: + - __meta_kubernetes_pod_name + target_label: instance + - action: drop + regex: (etcd2-.*) + source_labels: + - __meta_kubernetes_pod_name + scheme: https + scrape_interval: 30s + tls_config: + ca_file: /etc/kubernetes/secrets/etcd-client-ca.crt + cert_file: /etc/kubernetes/secrets/etcd-client.crt + insecure_skip_verify: true + key_file: /etc/kubernetes/secrets/etcd-client.key diff --git a/otelcollector/shared/configmap/ccp/testdata/no-scrape-jobs-linux-rs.yaml b/otelcollector/shared/configmap/ccp/testdata/no-scrape-jobs-linux-rs.yaml new file mode 100644 index 000000000..e69de29bb diff --git a/otelcollector/shared/configmap/ccp/tomlparser-ccp-default-scrape-settings.go b/otelcollector/shared/configmap/ccp/tomlparser-ccp-default-scrape-settings.go index f519decf8..957e1cd70 100644 --- a/otelcollector/shared/configmap/ccp/tomlparser-ccp-default-scrape-settings.go +++ b/otelcollector/shared/configmap/ccp/tomlparser-ccp-default-scrape-settings.go @@ -3,198 +3,86 @@ package ccpconfigmapsettings import ( "fmt" "os" - "regexp" "strings" -) - -// SetDefaultScrapeSettings sets the default values for control plane scrape settings. -func (fcl *FilesystemConfigLoader) SetDefaultScrapeSettings() (map[string]string, error) { - config := make(map[string]string) - - // Set default values - fmt.Println("SetDefaultScrapeSettings::Setting default scrape settings:") - config["controlplane-apiserver"] = "true" - config["controlplane-cluster-autoscaler"] = "false" - config["controlplane-node-auto-provisioning"] = "false" - config["controlplane-kube-scheduler"] = "false" - config["controlplane-kube-controller-manager"] = "false" - config["controlplane-etcd"] = "true" - - return config, nil -} - -// ParseConfigMapForDefaultScrapeSettings extracts the control plane scrape settings from metricsConfigBySection. -func (fcl *FilesystemConfigLoader) ParseConfigMapForDefaultScrapeSettings(metricsConfigBySection map[string]map[string]string, schemaVersion string) (map[string]string, error) { - config := make(map[string]string) - // Set default values - config["controlplane-apiserver"] = "true" - config["controlplane-cluster-autoscaler"] = "false" - config["controlplane-node-auto-provisioning"] = "false" - config["controlplane-kube-scheduler"] = "false" - config["controlplane-kube-controller-manager"] = "false" - config["controlplane-etcd"] = "true" - - // Override defaults with values from metricsConfigBySection - if schemaVersion == "v1" { - fmt.Println("ParseConfigMapForDefaultScrapeSettings::Processing v1 schema") - // For v1, control plane jobs are under "default-scrape-settings-enabled" with "controlplane-" prefix - if settings, ok := metricsConfigBySection["default-scrape-settings-enabled"]; ok { - fmt.Println("ParseConfigMapForDefaultScrapeSettings::Found default-scrape-settings-enabled section") - for key, value := range settings { - if strings.HasPrefix(key, "controlplane-") { - fmt.Printf("ParseConfigMapForDefaultScrapeSettings::Adding key: %s, value: %s\n", key, value) - config[key] = value - } - } - } - } else if schemaVersion == "v2" { - fmt.Println("ParseConfigMapForDefaultScrapeSettings::Processing v2 schema") - // For v2, control plane jobs are under "controlplane-metrics" without "controlplane-" prefix - if settings, ok := metricsConfigBySection["default-targets-scrape-enabled"]; ok { - fmt.Println("ParseConfigMapForDefaultScrapeSettings::Found default scrape settings section") - // Map v2 keys to v1 keys - v2ToV1KeyMap := map[string]string{ - "apiserver": "controlplane-apiserver", - "cluster-autoscaler": "controlplane-cluster-autoscaler", - "node-auto-provisioning": "controlplane-node-auto-provisioning", - "kube-scheduler": "controlplane-kube-scheduler", - "kube-controller-manager": "controlplane-kube-controller-manager", - "etcd": "controlplane-etcd", - } - for key, value := range settings { - if v1Key, ok := v2ToV1KeyMap[key]; ok { - fmt.Printf("ParseConfigMapForDefaultScrapeSettings::Adding key: %s, value: %s\n", v1Key, value) - config[v1Key] = value - } - } - } - } - fmt.Println("ParseConfigMapForDefaultScrapeSettings::Final scrape settings:") - fmt.Printf("controlplane-apiserver: %s\n", config["controlplane-apiserver"]) - fmt.Printf("controlplane-cluster-autoscaler: %s\n", config["controlplane-cluster-autoscaler"]) - fmt.Printf("controlplane-node-auto-provisioning: %s\n", config["controlplane-node-auto-provisioning"]) - fmt.Printf("controlplane-kube-scheduler: %s\n", config["controlplane-kube-scheduler"]) - fmt.Printf("controlplane-kube-controller-manager: %s\n", config["controlplane-kube-controller-manager"]) - fmt.Printf("controlplane-etcd: %s\n", config["controlplane-etcd"]) - - return config, nil -} + "github.com/prometheus-collector/shared" + cmcommon "github.com/prometheus-collector/shared/configmap/common" +) -// PopulateSettingValues populates settings from the parsed configuration. -func (cp *ConfigProcessor) PopulateSettingValues(parsedConfig map[string]string, schemaVersion string) { - fmt.Println("PopulateSettingValues::Populating settings from parsed configuration") +var NoDefaultsEnabled bool - if val, ok := parsedConfig["controlplane-kube-controller-manager"]; ok && val != "" { - cp.ControlplaneKubeControllerManager = val - fmt.Printf("PopulateSettingValues::Using scrape settings for controlplane-kube-controller-manager: %v\n", cp.ControlplaneKubeControllerManager) - } - if val, ok := parsedConfig["controlplane-kube-scheduler"]; ok && val != "" { - cp.ControlplaneKubeScheduler = val - fmt.Printf("PopulateSettingValues::Using scrape settings for controlplane-kube-scheduler: %v\n", cp.ControlplaneKubeScheduler) - } - if val, ok := parsedConfig["controlplane-apiserver"]; ok && val != "" { - cp.ControlplaneApiserver = val - fmt.Printf("PopulateSettingValues::Using scrape settings for controlplane-apiserver: %v\n", cp.ControlplaneApiserver) +func PopulateSettingValues(metricsConfigBySection map[string]map[string]string, schemaVersion string) error { + configSectionName := "default-scrape-settings-enabled" + if schemaVersion == shared.SchemaVersion.V2 { + configSectionName = "default-targets-scrape-enabled" } - if val, ok := parsedConfig["controlplane-cluster-autoscaler"]; ok && val != "" { - cp.ControlplaneClusterAutoscaler = val - fmt.Printf("PopulateSettingValues::Using scrape settings for controlplane-cluster-autoscaler: %v\n", cp.ControlplaneClusterAutoscaler) - } - if val, ok := parsedConfig["controlplane-node-auto-provisioning"]; ok && val != "" { - cp.ControlplaneNodeAutoProvisioning = val - fmt.Printf("PopulateSettingValues::Using scrape settings for controlplane-node-auto-provisioning: %v\n", cp.ControlplaneNodeAutoProvisioning) - } - if val, ok := parsedConfig["controlplane-etcd"]; ok && val != "" { - cp.ControlplaneEtcd = val - fmt.Printf("PopulateSettingValues::Using scrape settings for controlplane-etcd: %v\n", cp.ControlplaneEtcd) + settings, ok := metricsConfigBySection[configSectionName] + if !ok { + fmt.Println("ParseConfigMapForDefaultScrapeSettings::No default-targets-scrape-enabled section found, using defaults") + NoDefaultsEnabled = false + return nil } - // Check advanced mode - if os.Getenv("MODE") == "" && strings.ToLower(strings.TrimSpace(os.Getenv("MODE"))) == "advanced" { - fmt.Println("PopulateSettingValues::Advanced mode detected") - controllerType := os.Getenv("CONTROLLER_TYPE") - if controllerType == "ReplicaSet" && strings.ToLower(os.Getenv("OS_TYPE")) == "linux" && - cp.ControlplaneKubeControllerManager == "" && cp.ControlplaneKubeScheduler == "" && - cp.ControlplaneApiserver == "" && cp.ControlplaneClusterAutoscaler == "" && - cp.ControlplaneNodeAutoProvisioning == "" && cp.ControlplaneEtcd == "" { - cp.NoDefaultsEnabled = true - fmt.Println("PopulateSettingValues::No defaults enabled due to advanced mode and missing settings") + if err := cmcommon.UpdateJobEnablement(settings, shared.ControlPlaneDefaultScrapeJobs, schemaVersion, func(jobName string, schema string) string { + if schema == shared.SchemaVersion.V1 { + return "controlplane-" + jobName } - } else if cp.ControlplaneKubeControllerManager == "" && cp.ControlplaneKubeScheduler == "" && - cp.ControlplaneApiserver == "" && cp.ControlplaneClusterAutoscaler == "" && - cp.ControlplaneNodeAutoProvisioning == "" && cp.ControlplaneEtcd == "" { - cp.NoDefaultsEnabled = true - fmt.Println("PopulateSettingValues::No defaults enabled due to missing settings") + return jobName + }); err != nil { + return fmt.Errorf("ParseConfigMapForDefaultScrapeSettings::%w", err) } - if cp.NoDefaultsEnabled { - fmt.Println("PopulateSettingValues::No default scrape configs enabled") + NoDefaultsEnabled = cmcommon.DetermineNoDefaultsEnabled( + shared.ControlPlaneDefaultScrapeJobs, + os.Getenv("CONTROLLER_TYPE"), + os.Getenv("CONTAINER_TYPE"), + strings.ToLower(os.Getenv("OS_TYPE")), + ) + if NoDefaultsEnabled { + fmt.Printf("No default scrape configs enabled\n") } + return nil } // WriteDefaultScrapeSettingsToFile writes the configuration settings to a file. func (fcw *FileConfigWriter) WriteDefaultScrapeSettingsToFile(filename string, cp *ConfigProcessor) error { fmt.Printf("WriteDefaultScrapeSettingsToFile::Writing settings to file: %s\n", filename) - file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) - if err != nil { - return fmt.Errorf("exception while opening file for writing prometheus-collector config environment variables: %s", err) + formatter := func(jobName string) string { + return strings.ToUpper(jobName) + "_ENABLED" } - defer file.Close() - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_CONTROLPLANE_KUBE_CONTROLLER_MANAGER_ENABLED=%v\n", cp.ControlplaneKubeControllerManager)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_CONTROLPLANE_KUBE_SCHEDULER_ENABLED=%v\n", cp.ControlplaneKubeScheduler)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_CONTROLPLANE_APISERVER_ENABLED=%v\n", cp.ControlplaneApiserver)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_CONTROLPLANE_CLUSTER_AUTOSCALER_ENABLED=%v\n", cp.ControlplaneClusterAutoscaler)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_CONTROLPLANE_NODE_AUTO_PROVISIONING_ENABLED=%v\n", cp.ControlplaneNodeAutoProvisioning)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_CONTROLPLANE_ETCD_ENABLED=%v\n", cp.ControlplaneEtcd)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED=%v\n", cp.NoDefaultsEnabled)) + if err := cmcommon.WriteEnabledEnvFile(filename, shared.ControlPlaneDefaultScrapeJobs, formatter, NoDefaultsEnabled); err != nil { + return err + } fmt.Println("WriteDefaultScrapeSettingsToFile::Settings written to file successfully") return nil } // ConfigureDefaultScrapeSettings processes the configuration and writes it to a file. -func (c *Configurator) ConfigureDefaultScrapeSettings(metricsConfigBySection map[string]map[string]string) { - configSchemaVersion := os.Getenv("AZMON_AGENT_CFG_SCHEMA_VERSION") +func (c *Configurator) ConfigureDefaultScrapeSettings(metricsConfigBySection map[string]map[string]string, configSchemaVersion string) { fmt.Printf("ConfigureDefaultScrapeSettings::Config schema version: %s\n", configSchemaVersion) - fmt.Println("ConfigureDefaultScrapeSettings::Start prometheus-collector-settings Processing") // Load default settings based on the schema version - var defaultSettings map[string]string - var err error - if configSchemaVersion != "" && (strings.TrimSpace(configSchemaVersion) == "v1" || strings.TrimSpace(configSchemaVersion) == "v2") { + if configSchemaVersion == shared.SchemaVersion.V1 || configSchemaVersion == shared.SchemaVersion.V2 { fmt.Println("ConfigureDefaultScrapeSettings::Loading settings from config map") - defaultSettings, err = c.ConfigLoader.ParseConfigMapForDefaultScrapeSettings(metricsConfigBySection, configSchemaVersion) } else { + // Initialize with an empty metrics config map if none is provided fmt.Println("ConfigureDefaultScrapeSettings::Loading default settings") - defaultSettings, err = c.ConfigLoader.SetDefaultScrapeSettings() + metricsConfigBySection = make(map[string]map[string]string) } + // Populate and print setting values + err := PopulateSettingValues(metricsConfigBySection, configSchemaVersion) if err != nil { - fmt.Printf("ConfigureDefaultScrapeSettings::Error loading default settings: %v\n", err) - return + fmt.Println(err.Error()) } - // Populate and print setting values - c.ConfigParser.PopulateSettingValues(defaultSettings, configSchemaVersion) - // Set cluster alias - if mac := os.Getenv("MAC"); mac != "" && strings.TrimSpace(mac) == "true" { - fmt.Println("ConfigureDefaultScrapeSettings::MAC environment variable is true") - clusterArray := strings.Split(strings.TrimSpace(os.Getenv("CLUSTER")), "/") - c.ConfigParser.ClusterAlias = clusterArray[len(clusterArray)-1] - } else { - c.ConfigParser.ClusterAlias = os.Getenv("CLUSTER") - } - - if c.ConfigParser.ClusterAlias != "" && len(c.ConfigParser.ClusterAlias) > 0 { - fmt.Printf("ConfigureDefaultScrapeSettings::Original cluster alias: %s\n", c.ConfigParser.ClusterAlias) - // Replace all non-alphanumeric characters with "_" - c.ConfigParser.ClusterAlias = regexp.MustCompile(`[^0-9a-zA-Z]+`).ReplaceAllString(c.ConfigParser.ClusterAlias, "_") - c.ConfigParser.ClusterAlias = strings.Trim(c.ConfigParser.ClusterAlias, "_") + c.ConfigParser.ClusterAlias = cmcommon.ComputeClusterAlias(os.Getenv("CLUSTER"), os.Getenv("MAC")) + if c.ConfigParser.ClusterAlias != "" { fmt.Printf("ConfigureDefaultScrapeSettings::Sanitized cluster alias: %s\n", c.ConfigParser.ClusterAlias) } @@ -209,22 +97,21 @@ func (c *Configurator) ConfigureDefaultScrapeSettings(metricsConfigBySection map } // TomlparserCCPDefaultScrapeSettings initializes the configurator and processes the configuration. -func tomlparserCCPDefaultScrapeSettings(metricsConfigBySection map[string]map[string]string) { +func tomlparserCCPDefaultScrapeSettings(metricsConfigBySection map[string]map[string]string, schemaVersion string) { fmt.Println("tomlparserCCPDefaultScrapeSettings::Start ccp-default-scrape-settings Processing") - configSchemaVersion := os.Getenv("AZMON_AGENT_CFG_SCHEMA_VERSION") - configLoaderPath := "/etc/config/settings/default-targets-scrape-enabled" - if configSchemaVersion != "" && strings.TrimSpace(configSchemaVersion) == "v2" { - configLoaderPath = "/etc/config/settings/default-targets-scrape-enabled" + configLoaderPath := defaultSettingsMountPath + if schemaVersion == shared.SchemaVersion.V2 { + configLoaderPath = defaultSettingsMountPathv2 } configurator := &Configurator{ ConfigLoader: &FilesystemConfigLoader{ConfigMapMountPath: configLoaderPath}, ConfigWriter: &FileConfigWriter{}, - ConfigFilePath: "/opt/microsoft/configmapparser/config_default_scrape_settings_env_var", + ConfigFilePath: defaultSettingsEnvVarPath, ConfigParser: &ConfigProcessor{}, } - configurator.ConfigureDefaultScrapeSettings(metricsConfigBySection) + configurator.ConfigureDefaultScrapeSettings(metricsConfigBySection, schemaVersion) fmt.Println("tomlparserCCPDefaultScrapeSettings::End ccp-default-scrape-settings Processing") } diff --git a/otelcollector/shared/configmap/ccp/tomlparser-ccp-default-targets-metrics-keep-list.go b/otelcollector/shared/configmap/ccp/tomlparser-ccp-default-targets-metrics-keep-list.go index 4e8b83e4e..df8c87d62 100644 --- a/otelcollector/shared/configmap/ccp/tomlparser-ccp-default-targets-metrics-keep-list.go +++ b/otelcollector/shared/configmap/ccp/tomlparser-ccp-default-targets-metrics-keep-list.go @@ -2,267 +2,39 @@ package ccpconfigmapsettings import ( "fmt" - "io/fs" - "os" "strings" "github.com/prometheus-collector/shared" - "gopkg.in/yaml.v2" + cmcommon "github.com/prometheus-collector/shared/configmap/common" ) -var ( - configMapMountPath = "/etc/config/settings/default-targets-metrics-keep-list" - configSchemaVersion, minimalIngestionProfile string - controlplaneApiserverRegex, controlplaneClusterAutoscalerRegex string - controlplaneKubeSchedulerRegex, controlplaneKubeControllerManagerRegex string - controlplaneNodeAutoProvisioningRegex, controlplaneEtcdRegex string - controlplaneKubeControllerManagerMinMac = "rest_client_request_duration_seconds|rest_client_requests_total|workqueue_depth" - controlplaneKubeSchedulerMinMac = "scheduler_pending_pods|scheduler_unschedulable_pods|scheduler_pod_scheduling_attempts|scheduler_queue_incoming_pods_total|scheduler_preemption_attempts_total|scheduler_preemption_victims|scheduler_scheduling_attempt_duration_seconds|scheduler_schedule_attempts_total|scheduler_pod_scheduling_duration_seconds" - controlplaneApiserverMinMac = "apiserver_request_total|apiserver_cache_list_fetched_objects_total|apiserver_cache_list_returned_objects_total|apiserver_flowcontrol_demand_seats_average|apiserver_flowcontrol_current_limit_seats|apiserver_request_sli_duration_seconds_count|apiserver_request_sli_duration_seconds_sum|process_start_time_seconds|apiserver_request_duration_seconds_count|apiserver_request_duration_seconds_sum|apiserver_storage_list_fetched_objects_total|apiserver_storage_list_returned_objects_total|apiserver_current_inflight_requests" - controlplaneClusterAutoscalerMinMac = "rest_client_requests_total|cluster_autoscaler_(last_activity|cluster_safe_to_autoscale|scale_down_in_cooldown|scaled_up_nodes_total|unneeded_nodes_count|unschedulable_pods_count|nodes_count)|cloudprovider_azure_api_request_(errors|duration_seconds_(bucket|count))" - controlplaneNodeAutoProvisioningMinMac = "karpenter_(nodes_created_total|nodes_terminated_total|voluntary_disruption_eligible_nodes|nodeclaims_disrupted_total|voluntary_disruption_decisions_total|pods_state)" - controlplaneEtcdMinMac = "etcd_server_has_leader|rest_client_requests_total|etcd_mvcc_db_total_size_in_bytes|etcd_mvcc_db_total_size_in_use_in_bytes|etcd_server_slow_read_indexes_total|etcd_server_slow_apply_total|etcd_network_client_grpc_sent_bytes_total|etcd_server_heartbeat_send_failures_total" -) - -// getStringValue checks the type of the value and returns it as a string if possible. -func getStringValue(value interface{}) string { - if value == nil { - return "" - } - switch v := value.(type) { - case string: - return v - case bool: - return fmt.Sprintf("%t", v) // Convert boolean to string representation - default: - // Handle other types if needed - return fmt.Sprintf("%v", v) // Convert any other type to its default string representation - } -} - -// parseConfigMapForKeepListRegex extracts the control plane metrics keep list from metricsConfigBySection. -func parseConfigMapForKeepListRegex(metricsConfigBySection map[string]map[string]string, schemaVersion string) map[string]interface{} { - configMap := make(map[string]interface{}) - // set default to true in case there is no configmap - configMap["minimalingestionprofile"] = "true" - - fmt.Printf("parseConfigMapForKeepListRegex::schemaVersion: %s\n", schemaVersion) - - if schemaVersion == "v1" { - fmt.Println("parseConfigMapForKeepListRegex::Processing v1 schema") - // For v1, control plane jobs are under "default-targets-metrics-keep-list" with "controlplane-" prefix - if settings, ok := metricsConfigBySection["default-targets-metrics-keep-list"]; ok { - fmt.Println("parseConfigMapForKeepListRegex::Found default-targets-metrics-keep-list section") - for key, value := range settings { - if strings.HasPrefix(key, "controlplane-") { - fmt.Printf("parseConfigMapForKeepListRegex::Adding key: %s, value: %s\n", key, value) - configMap[key] = value - } - } - } - - // Handle minimalingestionprofile for v1 - if settings, ok := metricsConfigBySection["default-targets-metrics-keep-list"]; ok { - if minimalProfile, ok := settings["minimalingestionprofile"]; ok { - fmt.Printf("parseConfigMapForKeepListRegex::Found minimalingestionprofile: %s\n", minimalProfile) - configMap["minimalingestionprofile"] = minimalProfile - } else { - fmt.Println("parseConfigMapForKeepListRegex::minimalingestionprofile not found, setting default to true") - configMap["minimalingestionprofile"] = "true" // Setting the default value - } - } else { - fmt.Println("parseConfigMapForKeepListRegex::default-targets-metrics-keep-list section not found, setting default to true") - configMap["minimalingestionprofile"] = "true" // Setting the default value - } - } else if schemaVersion == "v2" { - fmt.Println("parseConfigMapForKeepListRegex::Processing v2 schema") - // For v2, control plane jobs are under "controlplane-metrics" without "controlplane-" prefix - if settings, ok := metricsConfigBySection["default-targets-metrics-keep-list"]; ok { - fmt.Println("parseConfigMapForKeepListRegex::Found default-targets-metrics-keep-list section") - // Map v2 keys to v1 keys - v2ToV1KeyMap := map[string]string{ - "apiserver": "controlplane-apiserver", - "cluster-autoscaler": "controlplane-cluster-autoscaler", - "node-auto-provisioning": "controlplane-node-auto-provisioning", - "kube-scheduler": "controlplane-kube-scheduler", - "kube-controller-manager": "controlplane-kube-controller-manager", - "etcd": "controlplane-etcd", - } - for key, value := range settings { - if v1Key, ok := v2ToV1KeyMap[key]; ok { - fmt.Printf("parseConfigMapForKeepListRegex::Adding key: %s, value: %s\n", v1Key, value) - configMap[v1Key] = value - } - } - - // Handle minimal-ingestion-profile for v2 - if minimalProfileSection, ok := metricsConfigBySection["minimal-ingestion-profile"]; ok { - if enabledValue, ok := minimalProfileSection["enabled"]; ok { - fmt.Printf("parseConfigMapForKeepListRegex::Found minimal-ingestion-profile enabled: %s\n", enabledValue) - configMap["minimalingestionprofile"] = enabledValue - } else { - fmt.Println("parseConfigMapForKeepListRegex::minimal-ingestion-profile enabled not found, setting default to true") - configMap["minimalingestionprofile"] = "true" // Setting the default value - } - } else { - fmt.Println("parseConfigMapForKeepListRegex::minimal-ingestion-profile section not found, setting default to true") - configMap["minimalingestionprofile"] = "true" // Setting the default value - } - - } - } - - fmt.Printf("parseConfigMapForKeepListRegex::Final configMap: %+v\n", configMap) - return configMap -} - -// populateSettingValuesFromConfigMap populates settings from the parsed configuration. -func populateSettingValuesFromConfigMap(parsedConfig map[string]interface{}, schemaVersion string) (RegexValues, error) { - regexValues := RegexValues{} - - // v2ToV1KeyMap for mapping v2 keys to v1 keys - v2ToV1KeyMap := map[string]string{ - "apiserver": "controlplane-apiserver", - "cluster-autoscaler": "controlplane-cluster-autoscaler", - "node-auto-provisioning": "controlplane-node-auto-provisioning", - "kube-scheduler": "controlplane-kube-scheduler", - "kube-controller-manager": "controlplane-kube-controller-manager", - "etcd": "controlplane-etcd", - "minimalingestionprofile": "minimalingestionprofile", - } - - for key, value := range parsedConfig { - // Map v2 key to v1 if schemaVersion == v2 - if configSchemaVersion != "" && strings.TrimSpace(configSchemaVersion) == "v2" { - key = v2ToV1KeyMap[key] - } - - switch key { - case "controlplane-kube-controller-manager": - regexValues.ControlplaneKubeControllerManager = getStringValue(value) - case "controlplane-kube-scheduler": - regexValues.ControlplaneKubeScheduler = getStringValue(value) - case "controlplane-apiserver": - regexValues.ControlplaneApiserver = getStringValue(value) - case "controlplane-cluster-autoscaler": - regexValues.ControlplaneClusterAutoscaler = getStringValue(value) - case "controlplane-node-auto-provisioning": - regexValues.ControlplaneNodeAutoProvisioning = getStringValue(value) - case "controlplane-etcd": - regexValues.ControlplaneEtcd = getStringValue(value) - case "minimalingestionprofile": - regexValues.MinimalIngestionProfile = getStringValue(value) - } - } - - fmt.Printf("populateSettingValuesFromConfigMap::Initial regexValues: %+v\n", regexValues) - - // Validate regex values - if regexValues.ControlplaneKubeControllerManager != "" && !shared.IsValidRegex(regexValues.ControlplaneKubeControllerManager) { - return regexValues, fmt.Errorf("invalid regex for controlplane-kube-controller-manager: %s", regexValues.ControlplaneKubeControllerManager) - } - if regexValues.ControlplaneKubeScheduler != "" && !shared.IsValidRegex(regexValues.ControlplaneKubeScheduler) { - return regexValues, fmt.Errorf("invalid regex for controlplane-kube-scheduler: %s", regexValues.ControlplaneKubeScheduler) - } - if regexValues.ControlplaneApiserver != "" && !shared.IsValidRegex(regexValues.ControlplaneApiserver) { - return regexValues, fmt.Errorf("invalid regex for controlplane-apiserver: %s", regexValues.ControlplaneApiserver) - } - if regexValues.ControlplaneClusterAutoscaler != "" && !shared.IsValidRegex(regexValues.ControlplaneClusterAutoscaler) { - return regexValues, fmt.Errorf("invalid regex for controlplane-cluster-autoscaler: %s", regexValues.ControlplaneClusterAutoscaler) - } - if regexValues.ControlplaneNodeAutoProvisioning != "" && !shared.IsValidRegex(regexValues.ControlplaneNodeAutoProvisioning) { - return regexValues, fmt.Errorf("invalid regex for controlplane-node-auto-provisioning: %s", regexValues.ControlplaneNodeAutoProvisioning) - } - if regexValues.ControlplaneEtcd != "" && !shared.IsValidRegex(regexValues.ControlplaneEtcd) { - return regexValues, fmt.Errorf("invalid regex for controlplane-etcd: %s", regexValues.ControlplaneEtcd) - } - if regexValues.MinimalIngestionProfile != "" && !shared.IsValidRegex(regexValues.MinimalIngestionProfile) { - return regexValues, fmt.Errorf("invalid regex for MinimalIngestionProfile: %s", regexValues.MinimalIngestionProfile) - } - - // Logging the values being set - fmt.Printf("populateSettingValuesFromConfigMap::controlplaneKubeControllerManagerRegex: %s\n", regexValues.ControlplaneKubeControllerManager) - fmt.Printf("populateSettingValuesFromConfigMap::controlplaneKubeSchedulerRegex: %s\n", regexValues.ControlplaneKubeScheduler) - fmt.Printf("populateSettingValuesFromConfigMap::controlplaneApiserverRegex: %s\n", regexValues.ControlplaneApiserver) - fmt.Printf("populateSettingValuesFromConfigMap::controlplaneClusterAutoscalerRegex: %s\n", regexValues.ControlplaneClusterAutoscaler) - fmt.Printf("populateSettingValuesFromConfigMap::controlplaneNodeAutoProvisioningRegex: %s\n", regexValues.ControlplaneNodeAutoProvisioning) - fmt.Printf("populateSettingValuesFromConfigMap::controlplaneEtcdRegex: %s\n", regexValues.ControlplaneEtcd) - fmt.Printf("populateSettingValuesFromConfigMap::minimalIngestionProfile: %s\n", regexValues.MinimalIngestionProfile) - - return regexValues, nil // Return regex values and nil error if everything is valid -} - -// populateRegexValuesWithMinimalIngestionProfile updates regex values based on minimal ingestion profile. -func populateRegexValuesWithMinimalIngestionProfile(regexValues RegexValues) { - fmt.Println("populateRegexValuesWithMinimalIngestionProfile::minimalIngestionProfile:", regexValues.MinimalIngestionProfile) - - if regexValues.MinimalIngestionProfile == "false" { - fmt.Println("populateRegexValuesWithMinimalIngestionProfile::Minimal ingestion profile is false, appending values") - controlplaneKubeControllerManagerRegex += regexValues.ControlplaneKubeControllerManager - controlplaneKubeSchedulerRegex += regexValues.ControlplaneKubeScheduler - controlplaneApiserverRegex += regexValues.ControlplaneApiserver - controlplaneClusterAutoscalerRegex += regexValues.ControlplaneClusterAutoscaler - controlplaneNodeAutoProvisioningRegex += regexValues.ControlplaneNodeAutoProvisioning - controlplaneEtcdRegex += regexValues.ControlplaneEtcd - } else { // else accounts for "true" and any other values including "nil" (meaning no configmap or no minimal setting in the configmap) - fmt.Println("populateRegexValuesWithMinimalIngestionProfile::Minimal ingestion profile is true or not set, appending minimal metrics") - controlplaneKubeControllerManagerRegex += regexValues.ControlplaneKubeControllerManager + "|" + controlplaneKubeControllerManagerMinMac - controlplaneKubeSchedulerRegex += regexValues.ControlplaneKubeScheduler + "|" + controlplaneKubeSchedulerMinMac - controlplaneApiserverRegex += regexValues.ControlplaneApiserver + "|" + controlplaneApiserverMinMac - controlplaneClusterAutoscalerRegex += regexValues.ControlplaneClusterAutoscaler + "|" + controlplaneClusterAutoscalerMinMac - controlplaneNodeAutoProvisioningRegex += regexValues.ControlplaneNodeAutoProvisioning + "|" + controlplaneNodeAutoProvisioningMinMac - controlplaneEtcdRegex += regexValues.ControlplaneEtcd + "|" + controlplaneEtcdMinMac - } -} - // tomlparserCCPTargetsMetricsKeepList processes the configuration and writes it to a file. -func tomlparserCCPTargetsMetricsKeepList(metricsConfigBySection map[string]map[string]string) { - configSchemaVersion = os.Getenv("AZMON_AGENT_CFG_SCHEMA_VERSION") +func tomlparserCCPTargetsMetricsKeepList(metricsConfigBySection map[string]map[string]string, configSchemaVersion string) { fmt.Println("Start default-targets-metrics-keep-list Processing") - var regexValues RegexValues - - if configSchemaVersion != "" && (strings.TrimSpace(configSchemaVersion) == "v1" || strings.TrimSpace(configSchemaVersion) == "v2") { - fmt.Printf("tomlparserCCPTargetsMetricsKeepList::Processing with schema version: %s\n", configSchemaVersion) - configMapSettings := parseConfigMapForKeepListRegex(metricsConfigBySection, configSchemaVersion) - if configMapSettings != nil { - var err error - regexValues, err = populateSettingValuesFromConfigMap(configMapSettings, configSchemaVersion) // Capture the returned RegexValues - if err != nil { - fmt.Printf("Error populating setting values: %v\n", err) - return + opts := cmcommon.KeepListOptions{ + Jobs: shared.ControlPlaneDefaultScrapeJobs, + MetricsConfig: metricsConfigBySection, + SchemaVersion: configSchemaVersion, + KeepListSection: "default-targets-metrics-keep-list", + MinimalProfileSection: "minimal-ingestion-profile", + MinimalProfileKeyV1: "minimalingestionprofile", + MinimalProfileKeyV2: "enabled", + OutputPath: configMapKeepListEnvVarPath, + EnvVarFormatter: func(jobName string) string { + return fmt.Sprintf("CONTROLPLANE_%s_KEEP_LIST_REGEX", strings.ToUpper(jobName)) + }, + JobKeyFormatter: func(jobName, schema string) string { + if schema == shared.SchemaVersion.V1 { + return "controlplane-" + jobName } - } - } else { - if _, err := os.Stat(configMapMountPath); err == nil { - fmt.Printf("Unsupported/missing config schema version - '%s', using defaults, please use supported schema version\n", configSchemaVersion) - } - } - - populateRegexValuesWithMinimalIngestionProfile(regexValues) // Pass the captured regexValues - - // Write settings to a YAML file. - data := map[string]string{ - "CONTROLPLANE_KUBE_CONTROLLER_MANAGER_KEEP_LIST_REGEX": controlplaneKubeControllerManagerRegex, - "CONTROLPLANE_KUBE_SCHEDULER_KEEP_LIST_REGEX": controlplaneKubeSchedulerRegex, - "CONTROLPLANE_APISERVER_KEEP_LIST_REGEX": controlplaneApiserverRegex, - "CONTROLPLANE_CLUSTER_AUTOSCALER_KEEP_LIST_REGEX": controlplaneClusterAutoscalerRegex, - "CONTROLPLANE_NODE_AUTO_PROVISIONING_KEEP_LIST_REGEX": controlplaneNodeAutoProvisioningRegex, - "CONTROLPLANE_ETCD_KEEP_LIST_REGEX": controlplaneEtcdRegex, - } - - fmt.Printf("tomlparserCCPTargetsMetricsKeepList::Final data to write: %+v\n", data) - - out, err := yaml.Marshal(data) - if err != nil { - fmt.Println(err.Error()) - return + return jobName + }, + MinimalProfileDefaultBool: true, } - err = os.WriteFile("/opt/microsoft/configmapparser/config_def_targets_metrics_keep_list_hash", []byte(out), fs.FileMode(0644)) - if err != nil { - fmt.Printf("Exception while writing to file: %v\n", err) - return + if err := cmcommon.PopulateKeepLists(opts); err != nil { + fmt.Println("tomlparserCCPTargetsMetricsKeepList::error populating keep list", err) } fmt.Println("End default-targets-metrics-keep-list Processing") diff --git a/otelcollector/shared/configmap/ccp/tomlparser-ccp-opentelemetry-metrics.go b/otelcollector/shared/configmap/ccp/tomlparser-ccp-opentelemetry-metrics.go index e3ab44c66..676cf3730 100644 --- a/otelcollector/shared/configmap/ccp/tomlparser-ccp-opentelemetry-metrics.go +++ b/otelcollector/shared/configmap/ccp/tomlparser-ccp-opentelemetry-metrics.go @@ -1,9 +1,9 @@ package ccpconfigmapsettings import ( - "fmt" - "os" - "strconv" + "log" + + cmcommon "github.com/prometheus-collector/shared/configmap/common" ) var ( @@ -11,42 +11,7 @@ var ( ) func ConfigureOpentelemetryMetricsSettings(metricsConfigBySection map[string]map[string]string) error { - if metricsConfigBySection == nil { - return fmt.Errorf("configmap section not mounted, using defaults") - } - - enabled := populateOpentelemetryMetricsSettingValuesFromConfigMap(metricsConfigBySection) - - file, err := os.Create(opentelemetryMetricsEnvVarPath) - if err != nil { - return fmt.Errorf("Exception while opening file for writing prometheus-collector config environment variables: %v\n", err) - } - defer file.Close() - - file.WriteString(fmt.Sprintf("AZMON_FULL_OTLP_ENABLED=%v\n", enabled)) - - fmt.Printf("Setting AZMON_FULL_OTLP_ENABLED environment variable: %v\n", enabled) - - return nil -} - -func populateOpentelemetryMetricsSettingValuesFromConfigMap(metricsConfigBySection map[string]map[string]string) bool { - enabled := false - - // Access the nested map and value - innerMap, ok := metricsConfigBySection["opentelemetry-metrics"] - if !ok { - return enabled - } - - if val, ok := innerMap["enabled"]; ok { - enabledBool, err := strconv.ParseBool(val) - if err != nil { - fmt.Printf("Invalid value for opentelemetry-metrics enabled: %s, defaulting to %b\n", enabled) - return enabled - } - enabled = enabledBool - fmt.Printf("Using configmap setting for opentelemetry-metrics: %v\n", enabled) - } - return enabled + return cmcommon.WriteOtelMetricsEnvFile(metricsConfigBySection, opentelemetryMetricsEnvVarPath, func(format string, args ...interface{}) { + log.Printf(format, args...) + }) } diff --git a/otelcollector/shared/configmap/ccp/tomlparser-ccp-prometheus-collector-settings.go b/otelcollector/shared/configmap/ccp/tomlparser-ccp-prometheus-collector-settings.go index 6439e2998..8c332ab89 100644 --- a/otelcollector/shared/configmap/ccp/tomlparser-ccp-prometheus-collector-settings.go +++ b/otelcollector/shared/configmap/ccp/tomlparser-ccp-prometheus-collector-settings.go @@ -3,42 +3,26 @@ package ccpconfigmapsettings import ( "fmt" "os" - "regexp" "strings" + + "github.com/prometheus-collector/shared" + cmcommon "github.com/prometheus-collector/shared/configmap/common" ) // PopulateSettingValuesFromConfigMap populates settings from the parsed configuration. func (cp *ConfigProcessor) PopulateSettingValuesFromConfigMap(metricsConfigBySection map[string]map[string]string) { - // Extract the prometheus-collector-settings section - if settings, ok := metricsConfigBySection["cluster_alias"]; ok { - if value, ok := settings["default_metric_account_name"]; ok { - cp.DefaultMetricAccountName = value - fmt.Printf("Using configmap setting for default metric account name: %s\n", cp.DefaultMetricAccountName) - } - - if value, ok := settings["cluster_alias"]; ok { - cp.ClusterAlias = strings.TrimSpace(value) - fmt.Printf("Got configmap setting for cluster_alias: %s\n", cp.ClusterAlias) - if cp.ClusterAlias != "" { - cp.ClusterAlias = regexp.MustCompile(`[^0-9a-zA-Z]+`).ReplaceAllString(cp.ClusterAlias, "_") - cp.ClusterAlias = strings.Trim(cp.ClusterAlias, "_") - fmt.Printf("After replacing non-alpha-numeric characters with '_': %s\n", cp.ClusterAlias) - } - } - - if operatorEnabled := os.Getenv("AZMON_OPERATOR_ENABLED"); operatorEnabled != "" && strings.ToLower(operatorEnabled) == "true" { - cp.IsOperatorEnabledChartSetting = true - if value, ok := settings["operator_enabled"]; ok { - cp.IsOperatorEnabled = value == "true" - fmt.Printf("Configmap setting enabling operator: %t\n", cp.IsOperatorEnabled) - } - } else { - cp.IsOperatorEnabledChartSetting = false - } - } else { - cp.IsOperatorEnabledChartSetting = false - fmt.Println("prometheus-collector-settings section not found in metricsConfigBySection, using defaults") - } + fmt.Println("metricsConfigBySection:", metricsConfigBySection) + + sharedSettings := cmcommon.CollectorSettings{} + cmcommon.PopulateSharedCollectorSettings(&sharedSettings, metricsConfigBySection, func(format string, args ...interface{}) { + fmt.Printf(format, args...) + }) + + cp.DefaultMetricAccountName = sharedSettings.MetricAccountName + cp.ClusterAlias = sharedSettings.ClusterAlias + cp.ClusterLabel = sharedSettings.ClusterLabel + cp.IsOperatorEnabled = sharedSettings.OperatorEnabled + cp.IsOperatorEnabledChartSetting = sharedSettings.OperatorEnabledChart } // WriteConfigToFile writes the configuration settings to a file. @@ -49,25 +33,26 @@ func (fcw *FileConfigWriter) WriteConfigToFile(filename string, configParser *Co } defer file.Close() - file.WriteString(fmt.Sprintf("AZMON_DEFAULT_METRIC_ACCOUNT_NAME=%s\n", configParser.DefaultMetricAccountName)) - file.WriteString(fmt.Sprintf("AZMON_CLUSTER_LABEL=%s\n", configParser.ClusterLabel)) - file.WriteString(fmt.Sprintf("AZMON_CLUSTER_ALIAS=%s\n", configParser.ClusterAlias)) - file.WriteString(fmt.Sprintf("AZMON_OPERATOR_ENABLED_CHART_SETTING=%t\n", configParser.IsOperatorEnabledChartSetting)) - if configParser.IsOperatorEnabled { - file.WriteString(fmt.Sprintf("AZMON_OPERATOR_ENABLED=%t\n", configParser.IsOperatorEnabled)) - file.WriteString(fmt.Sprintf("AZMON_OPERATOR_ENABLED_CFG_MAP_SETTING=%t\n", configParser.IsOperatorEnabled)) + sharedSettings := cmcommon.CollectorSettings{ + MetricAccountName: configParser.DefaultMetricAccountName, + ClusterAlias: configParser.ClusterAlias, + ClusterLabel: configParser.ClusterLabel, + OperatorEnabled: configParser.IsOperatorEnabled, + OperatorEnabledChart: configParser.IsOperatorEnabledChartSetting, + } + + if err := cmcommon.WriteSharedCollectorSettings(file, sharedSettings); err != nil { + return err } return nil } // Configure processes the configuration and writes it to a file. -func (c *Configurator) Configure(metricsConfigBySection map[string]map[string]string) { - configSchemaVersion := os.Getenv("AZMON_AGENT_CFG_SCHEMA_VERSION") - +func (c *Configurator) Configure(metricsConfigBySection map[string]map[string]string, configSchemaVersion string) { fmt.Printf("Start prometheus-collector-settings Processing\n") - if configSchemaVersion != "" && (strings.TrimSpace(configSchemaVersion) == "v1" || strings.TrimSpace(configSchemaVersion) == "v2") { + if configSchemaVersion == shared.SchemaVersion.V1 || configSchemaVersion == shared.SchemaVersion.V2 { if len(metricsConfigBySection) > 0 { c.ConfigParser.PopulateSettingValuesFromConfigMap(metricsConfigBySection) } @@ -102,13 +87,13 @@ func (c *Configurator) Configure(metricsConfigBySection map[string]map[string]st } // parseConfigAndSetEnvInFile initializes the configurator and processes the configuration. -func parseConfigAndSetEnvInFile(metricsConfigBySection map[string]map[string]string) { +func parseConfigAndSetEnvInFile(metricsConfigBySection map[string]map[string]string, schemaVersion string) { configurator := &Configurator{ - ConfigLoader: &FilesystemConfigLoader{ConfigMapMountPath: "/etc/config/settings/prometheus-collector-settings"}, + ConfigLoader: &FilesystemConfigLoader{ConfigMapMountPath: collectorSettingsMountPath}, ConfigParser: &ConfigProcessor{}, ConfigWriter: &FileConfigWriter{ConfigProcessor: &ConfigProcessor{}}, - ConfigFilePath: "/opt/microsoft/configmapparser/config_prometheus_collector_settings_env_var", + ConfigFilePath: collectorSettingsEnvVarPath, } - configurator.Configure(metricsConfigBySection) + configurator.Configure(metricsConfigBySection, schemaVersion) } diff --git a/otelcollector/shared/configmap/common/configmapparser-shared.go b/otelcollector/shared/configmap/common/configmapparser-shared.go new file mode 100644 index 000000000..f36a9897d --- /dev/null +++ b/otelcollector/shared/configmap/common/configmapparser-shared.go @@ -0,0 +1,71 @@ +package common + +import ( + "log" + "os" + "path/filepath" + "strings" + + "github.com/prometheus-collector/shared" +) + +const maxVersionLength = 10 + +// SetEnvFromFile reads the value from the provided file, sanitizes it, and sets +// the environment variable using shared.SetEnvAndSourceBashrcOrPowershell. If +// the file does not exist or is empty, the defaultValue is used instead. The +// sanitized value is returned to the caller for further use. +func SetEnvFromFile(filePath, envVarName, defaultValue string) string { + info, err := os.Stat(filePath) + if err != nil || info.Size() == 0 { + shared.SetEnvAndSourceBashrcOrPowershell(envVarName, defaultValue, true) + return defaultValue + } + + content, err := os.ReadFile(filePath) + if err != nil { + shared.EchoError("Error reading " + filepath.Base(filePath) + ":" + err.Error()) + shared.SetEnvAndSourceBashrcOrPowershell(envVarName, defaultValue, true) + return defaultValue + } + + trimmed := strings.TrimSpace(string(content)) + sanitized := strings.ReplaceAll(trimmed, " ", "") + if len(sanitized) > maxVersionLength { + sanitized = sanitized[:maxVersionLength] + } + + shared.SetEnvAndSourceBashrcOrPowershell(envVarName, sanitized, true) + return sanitized +} + +// LoadMetricsConfiguration parses the config map contents based on the schema +// version. For v2 schema, it reads the files listed in v2FilePaths. For v1, it +// parses the directory pointed by configDir. When no schema version is set or +// an unsupported value is provided, an empty map and SchemaVersion.Nil are +// returned so callers can gracefully fall back to defaults. +func LoadMetricsConfiguration(schemaVersion string, v2FilePaths []string, configDir string) (map[string]map[string]string, error) { + parsedSchema := shared.ParseSchemaVersion(schemaVersion) + switch parsedSchema { + case shared.SchemaVersion.V2: + if len(v2FilePaths) == 0 { + log.Println("LoadMetricsConfiguration::v2 schema detected but no file paths provided") + return map[string]map[string]string{}, nil + } + + metricsConfigBySection, err := shared.ParseMetricsFiles(v2FilePaths) + if err != nil { + return nil, err + } + return metricsConfigBySection, nil + case shared.SchemaVersion.V1: + metricsConfigBySection, err := shared.ParseV1Config(configDir) + if err != nil { + return nil, err + } + return metricsConfigBySection, nil + default: + log.Println("LoadMetricsConfiguration::Invalid schema version or no configmap present. Using defaults.") + return map[string]map[string]string{}, nil + } +} diff --git a/otelcollector/shared/configmap/common/prometheus-config-merger-shared.go b/otelcollector/shared/configmap/common/prometheus-config-merger-shared.go new file mode 100644 index 000000000..68c96bb00 --- /dev/null +++ b/otelcollector/shared/configmap/common/prometheus-config-merger-shared.go @@ -0,0 +1,210 @@ +package common + +import ( + "fmt" + "io/fs" + "log" + "os" + "strings" + + "gopkg.in/yaml.v2" +) + +// LogFunc allows callers to customize how messages are emitted. When nil, the +// helper falls back to log.Printf to preserve existing behaviour. +type LogFunc func(string, ...interface{}) + +func ensureLogFunc(logFn LogFunc) LogFunc { + if logFn != nil { + return logFn + } + return log.Printf +} + +// UpdateScrapeIntervalConfig rewrites the scrape interval of every scrape +// config contained in the supplied YAML file. +func UpdateScrapeIntervalConfig(yamlConfigFile, scrapeIntervalSetting string, logFn LogFunc) error { + logger := ensureLogFunc(logFn) + logger("Updating scrape interval config for %s\n", yamlConfigFile) + + data, err := os.ReadFile(yamlConfigFile) + if err != nil { + return fmt.Errorf("common.UpdateScrapeIntervalConfig::read %s: %w", yamlConfigFile, err) + } + + var config map[interface{}]interface{} + if err := yaml.Unmarshal(data, &config); err != nil { + return fmt.Errorf("common.UpdateScrapeIntervalConfig::unmarshal %s: %w", yamlConfigFile, err) + } + + scrapeConfigs, ok := config["scrape_configs"].([]interface{}) + if !ok { + logger("common.UpdateScrapeIntervalConfig::no scrape_configs found in %s\n", yamlConfigFile) + return nil + } + + for _, scfg := range scrapeConfigs { + if scfgMap, ok := scfg.(map[interface{}]interface{}); ok { + scfgMap["scrape_interval"] = scrapeIntervalSetting + } + } + + updated, err := yaml.Marshal(config) + if err != nil { + return fmt.Errorf("common.UpdateScrapeIntervalConfig::marshal %s: %w", yamlConfigFile, err) + } + + if err := os.WriteFile(yamlConfigFile, updated, fs.FileMode(0644)); err != nil { + return fmt.Errorf("common.UpdateScrapeIntervalConfig::write %s: %w", yamlConfigFile, err) + } + + return nil +} + +// AppendMetricRelabelConfig adds or augments the metric_relabel_configs stanza +// for every scrape config contained in yamlConfigFile. +func AppendMetricRelabelConfig(yamlConfigFile, keepListRegex string, logFn LogFunc) error { + logger := ensureLogFunc(logFn) + logger("Adding keep list regex or minimal ingestion regex for %s\n", yamlConfigFile) + + content, err := os.ReadFile(yamlConfigFile) + if err != nil { + return fmt.Errorf("common.AppendMetricRelabelConfig::read %s: %w", yamlConfigFile, err) + } + + var config map[string]interface{} + if err := yaml.Unmarshal(content, &config); err != nil { + return fmt.Errorf("common.AppendMetricRelabelConfig::unmarshal %s: %w", yamlConfigFile, err) + } + + keepListMetricRelabelConfig := map[string]interface{}{ + "source_labels": []interface{}{"__name__"}, + "action": "keep", + "regex": keepListRegex, + } + + scrapeConfigs, ok := config["scrape_configs"].([]interface{}) + if !ok { + logger("common.AppendMetricRelabelConfig::no scrape_configs found in %s\n", yamlConfigFile) + return nil + } + + for idx, scfg := range scrapeConfigs { + stringMap := make(map[string]interface{}) + scfgMap, ok := scfg.(map[interface{}]interface{}) + if !ok { + continue + } + for k, v := range scfgMap { + key, ok := k.(string) + if !ok { + return fmt.Errorf("common.AppendMetricRelabelConfig::non-string key in scrape config: %v", k) + } + stringMap[key] = v + } + + if metricRelabelCfgs, ok := stringMap["metric_relabel_configs"].([]interface{}); ok { + stringMap["metric_relabel_configs"] = append(metricRelabelCfgs, keepListMetricRelabelConfig) + } else { + stringMap["metric_relabel_configs"] = []interface{}{keepListMetricRelabelConfig} + } + + interfaceMap := make(map[interface{}]interface{}) + for k, v := range stringMap { + interfaceMap[k] = v + } + scrapeConfigs[idx] = interfaceMap + } + + config["scrape_configs"] = scrapeConfigs + + updated, err := yaml.Marshal(config) + if err != nil { + return fmt.Errorf("common.AppendMetricRelabelConfig::marshal %s: %w", yamlConfigFile, err) + } + + if err := os.WriteFile(yamlConfigFile, updated, fs.FileMode(0644)); err != nil { + return fmt.Errorf("common.AppendMetricRelabelConfig::write %s: %w", yamlConfigFile, err) + } + + return nil +} + +// ReplacePlaceholders substitutes $$PLACEHOLDER$$ tokens in yamlConfigFile with +// the corresponding environment variable values. +func ReplacePlaceholders(yamlConfigFile string, placeholders []string) error { + contents, err := os.ReadFile(yamlConfigFile) + if err != nil { + return fmt.Errorf("common.ReplacePlaceholders::read %s: %w", yamlConfigFile, err) + } + + replaced := string(contents) + for _, placeholder := range placeholders { + replaced = strings.ReplaceAll(replaced, fmt.Sprintf("$$%s$$", placeholder), os.Getenv(placeholder)) + } + + if err := os.WriteFile(yamlConfigFile, []byte(replaced), fs.FileMode(0644)); err != nil { + return fmt.Errorf("common.ReplacePlaceholders::write %s: %w", yamlConfigFile, err) + } + return nil +} + +// LoadYAMLFromFile loads the provided YAML file into a map representation. +func LoadYAMLFromFile(filename string) (map[interface{}]interface{}, error) { + fileContent, err := os.ReadFile(filename) + if err != nil { + return nil, fmt.Errorf("common.LoadYAMLFromFile::read %s: %w", filename, err) + } + + var yamlData map[interface{}]interface{} + if err := yaml.Unmarshal(fileContent, &yamlData); err != nil { + return nil, fmt.Errorf("common.LoadYAMLFromFile::unmarshal %s: %w", filename, err) + } + + return yamlData, nil +} + +// DeepMerge merges source into target recursively and returns target. +func DeepMerge(target, source map[interface{}]interface{}) map[interface{}]interface{} { + for key, sourceValue := range source { + targetValue, exists := target[key] + + if !exists { + target[key] = sourceValue + continue + } + + targetMap, targetMapOk := targetValue.(map[interface{}]interface{}) + sourceMap, sourceMapOk := sourceValue.(map[interface{}]interface{}) + + if targetMapOk && sourceMapOk { + target[key] = DeepMerge(targetMap, sourceMap) + continue + } + + targetSlice, targetSliceOk := targetValue.([]interface{}) + sourceSlice, sourceSliceOk := sourceValue.([]interface{}) + if targetSliceOk && sourceSliceOk { + target[key] = append(targetSlice, sourceSlice...) + continue + } + + target[key] = sourceValue + } + + return target +} + +// WriteYAML writes the provided map to the destination file as YAML. +func WriteYAML(dst string, data map[interface{}]interface{}) error { + serialized, err := yaml.Marshal(data) + if err != nil { + return fmt.Errorf("common.WriteYAML::marshal %s: %w", dst, err) + } + + if err := os.WriteFile(dst, serialized, fs.FileMode(0644)); err != nil { + return fmt.Errorf("common.WriteYAML::write %s: %w", dst, err) + } + + return nil +} diff --git a/otelcollector/shared/configmap/common/testhelpers/go.mod b/otelcollector/shared/configmap/common/testhelpers/go.mod new file mode 100644 index 000000000..68b63936d --- /dev/null +++ b/otelcollector/shared/configmap/common/testhelpers/go.mod @@ -0,0 +1,12 @@ +module github.com/prometheus-collector/shared/configmap/common/testhelpers + +go 1.23.0 + +toolchain go1.23.2 + +replace github.com/prometheus-collector/shared => ../../../../shared + +require ( + github.com/prometheus-collector/shared v0.0.0-00010101000000-000000000000 + gopkg.in/yaml.v2 v2.4.0 +) diff --git a/otelcollector/shared/configmap/common/testhelpers/go.sum b/otelcollector/shared/configmap/common/testhelpers/go.sum new file mode 100644 index 000000000..dd0bc19f1 --- /dev/null +++ b/otelcollector/shared/configmap/common/testhelpers/go.sum @@ -0,0 +1,4 @@ +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/otelcollector/shared/configmap/common/testhelpers/testhelpers.go b/otelcollector/shared/configmap/common/testhelpers/testhelpers.go new file mode 100644 index 000000000..c689b2e6b --- /dev/null +++ b/otelcollector/shared/configmap/common/testhelpers/testhelpers.go @@ -0,0 +1,686 @@ +package testhelpers + +import ( + "fmt" + "os" + "path/filepath" + "strconv" + "strings" + + "github.com/prometheus-collector/shared" + "gopkg.in/yaml.v2" +) + +var collectorBaseEnvKeys = []string{ + "AZMON_AGENT_CFG_FILE_VERSION", + "AZMON_AGENT_CFG_SCHEMA_VERSION", + "AZMON_CLUSTER_ALIAS", + "AZMON_CLUSTER_LABEL", + "AZMON_DEFAULT_METRIC_ACCOUNT_NAME", + "AZMON_INVALID_CUSTOM_PROMETHEUS_CONFIG", + "AZMON_KSM_CONFIG_ENABLED", + "AZMON_OPERATOR_ENABLED", + "AZMON_OPERATOR_ENABLED_CHART_SETTING", + "AZMON_OPERATOR_ENABLED_CFG_MAP_SETTING", + "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED", + "AZMON_PROMETHEUS_POD_ANNOTATION_NAMESPACES_REGEX", + "AZMON_PROMETHEUS_POD_ANNOTATION_SCRAPING_ENABLED", + "AZMON_SET_GLOBAL_SETTINGS", + "AZMON_USE_DEFAULT_PROMETHEUS_CONFIG", + "CONFIGMAP_VERSION", + "CONFIG_VALIDATOR_RUNNING_IN_AGENT", + "CONTAINER_TYPE", + "CONTROLLER_TYPE", + "DEBUG_MODE_ENABLED", + "KUBE_STATE_NAME", + "MAC", + "MODE", + "NODE_EXPORTER_TARGETPORT", + "NODE_IP", + "NODE_NAME", + "OS_TYPE", + "POD_NAMESPACE", +} + +var controlPlaneEnvAlternateKeys = []string{ + "AZMON_PROMETHEUS_CLUSTER_AUTOSCALER_ENABLED", + "AZMON_PROMETHEUS_KUBECONTROLLERMANAGER_ENABLED", + "AZMON_PROMETHEUS_KUBESCHEDULER_ENABLED", + "AZMON_PROMETHEUS_NODE_AUTO_PROVISIONING_ENABLED", +} + +// CollectorPrefixes contains the configurable root directories used while setting up +// test artifacts for the configmap parser. +type CollectorPrefixes struct { + ConfigSettingsPrefix string + ConfigMapParserPrefix string +} + +// CollectorConfigPaths groups the mutable config map mount paths that need to be +// redirected to temporary files during tests. Fields can be left nil when the +// corresponding path is not used by a particular test suite. +type CollectorConfigPaths struct { + ConfigMapDebugMountPath *string + ReplicaSetCollectorConfig *string + DefaultSettingsMountPath *string + ConfigMapMountPathForPodAnnotation *string + CollectorSettingsMountPath *string + ConfigMapKeepListMountPath *string + ConfigMapScrapeIntervalMountPath *string + ConfigMapOpentelemetryMetricsPath *string +} + +// CollectorPrefixesFor builds the prefixes used by the configmap parser tests +// and selects between Managed Prometheus (data plane) and control-plane +// variants based on isDataPlane. +func CollectorPrefixesFor(configSettingsPrefix, configMapParserPrefix string, isDataPlane bool) CollectorPrefixes { + mpPrefixes := CollectorPrefixes{ + ConfigSettingsPrefix: configSettingsPrefix, + ConfigMapParserPrefix: configMapParserPrefix, + } + + ccpPrefixes := CollectorPrefixes{ + ConfigSettingsPrefix: configSettingsPrefix, + } + if configMapParserPrefix != "" { + ccpPrefixes.ConfigMapParserPrefix = configMapParserPrefix + } + + if isDataPlane { + return mpPrefixes + } + return ccpPrefixes +} + +// CollectorProcessedPaths groups the generated file paths produced while the +// configmap parser materializes intermediate results. +type CollectorProcessedPaths struct { + PodAnnotationEnvVarPath *string + CollectorSettingsEnvVarPath *string + DefaultSettingsEnvVarPath *string + DebugModeEnvVarPath *string + ConfigMapKeepListEnvVarPath *string + ScrapeIntervalEnvVarPath *string + OpentelemetryMetricsEnvVarPath *string + KsmConfigEnvVarPath *string + ScrapeConfigDefinitionPathPrefix *string + MergedDefaultConfigPath *string + PromMergedConfigPath *string + RegexHashFile *string + IntervalHashFile *string +} + +// DefaultCollectorEnvVarKeys returns the environment variable names that need to +// be reset between data-plane config map parser tests. +func DefaultCollectorEnvVarKeys() []string { + keys := append([]string{}, collectorBaseEnvKeys...) + keys = append(keys, CollectorJobEnvVarNames(shared.DefaultScrapeJobs, func(jobName string) string { + return BuildEnvVarName(jobName, "_SCRAPING_ENABLED") + })...) + return uniqueStrings(keys) +} + +// ControlPlaneCollectorEnvVarKeys returns the environment variables used by the +// control-plane config map parser tests. +func ControlPlaneCollectorEnvVarKeys() []string { + keys := append([]string{}, collectorBaseEnvKeys...) + keys = append(keys, CollectorJobEnvVarNames(shared.ControlPlaneDefaultScrapeJobs, func(jobName string) string { + return BuildEnvVarName(jobName, "_ENABLED") + })...) + keys = append(keys, controlPlaneEnvAlternateKeys...) + return uniqueStrings(keys) +} + +// BuildEnvVarName composes an AZMON_PROMETHEUS environment variable name for a +// job following the supplied suffix convention. +func BuildEnvVarName(jobName, suffix string) string { + return fmt.Sprintf("AZMON_PROMETHEUS_%s%s", strings.ToUpper(jobName), suffix) +} + +// CollectorJobEnvVarNames converts a job catalog into environment variable +// names using the provided formatter. +func CollectorJobEnvVarNames(jobs map[string]*shared.DefaultScrapeJob, formatter func(string) string) []string { + names := make([]string, 0, len(jobs)) + for jobName := range jobs { + names = append(names, formatter(jobName)) + } + return names +} + +func uniqueStrings(values []string) []string { + if len(values) == 0 { + return nil + } + seen := make(map[string]struct{}, len(values)) + unique := make([]string, 0, len(values)) + for _, value := range values { + if _, ok := seen[value]; ok { + continue + } + seen[value] = struct{}{} + unique = append(unique, value) + } + return unique +} + +// CloneJobEnabledStates copies the enabled flags for the supplied job catalog. +func CloneJobEnabledStates(jobs map[string]*shared.DefaultScrapeJob) map[string]bool { + clone := make(map[string]bool, len(jobs)) + for jobName, job := range jobs { + clone[jobName] = job.Enabled + } + return clone +} + +// BuildEnvVarOverrides renders a map of environment variable overrides from the +// provided enablement map. +func BuildEnvVarOverrides(values map[string]bool, formatter func(string) string) map[string]string { + overrides := make(map[string]string, len(values)) + for jobName, enabled := range values { + overrides[formatter(jobName)] = strconv.FormatBool(enabled) + } + return overrides +} + +// JobEnabledEnvVars generates the default job enablement environment variables +// for the provided job catalog. +func JobEnabledEnvVars(jobs map[string]*shared.DefaultScrapeJob, formatter func(string) string) map[string]string { + result := make(map[string]string, len(jobs)) + for jobName, job := range jobs { + result[formatter(jobName)] = strconv.FormatBool(job.Enabled) + } + return result +} + +// DefaultManagedPrometheusEnvVars returns the baseline environment variables +// expected for Managed Prometheus tests before any overrides are applied. +func DefaultManagedPrometheusEnvVars() map[string]string { + envVars := map[string]string{ + "AZMON_AGENT_CFG_SCHEMA_VERSION": "v1", + "AZMON_AGENT_CFG_FILE_VERSION": "ver1", + "AZMON_PROMETHEUS_POD_ANNOTATION_NAMESPACES_REGEX": "", + "AZMON_DEFAULT_METRIC_ACCOUNT_NAME": "", + "AZMON_CLUSTER_LABEL": "", + "AZMON_CLUSTER_ALIAS": "", + "AZMON_OPERATOR_ENABLED_CHART_SETTING": "true", + "AZMON_OPERATOR_ENABLED": "true", + "AZMON_OPERATOR_ENABLED_CFG_MAP_SETTING": "", + "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "false", + "DEBUG_MODE_ENABLED": "false", + "CONFIGMAP_VERSION": "not_present", + } + + jobEnvVars := JobEnabledEnvVars(shared.DefaultScrapeJobs, func(jobName string) string { + return BuildEnvVarName(jobName, "_SCRAPING_ENABLED") + }) + for key, value := range jobEnvVars { + envVars[key] = value + } + + return envVars +} + +// DefaultControlPlaneEnvVars returns the baseline environment variables +// expected for control-plane (CCP) tests before overrides are applied. +func DefaultControlPlaneEnvVars() map[string]string { + envVars := map[string]string{ + "AZMON_AGENT_CFG_SCHEMA_VERSION": "v1", + "AZMON_AGENT_CFG_FILE_VERSION": "ver1", + "AZMON_PROMETHEUS_POD_ANNOTATION_NAMESPACES_REGEX": "", + "AZMON_DEFAULT_METRIC_ACCOUNT_NAME": "", + "AZMON_CLUSTER_LABEL": "", + "AZMON_CLUSTER_ALIAS": "", + "AZMON_OPERATOR_ENABLED_CHART_SETTING": "false", + "AZMON_OPERATOR_ENABLED": "false", + "AZMON_OPERATOR_ENABLED_CFG_MAP_SETTING": "", + "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "false", + "AZMON_PROMETHEUS_APISERVER_ENABLED": "true", + "AZMON_PROMETHEUS_CLUSTER-AUTOSCALER_ENABLED": "false", + "AZMON_PROMETHEUS_KUBE-SCHEDULER_ENABLED": "false", + "AZMON_PROMETHEUS_KUBE-CONTROLLER-MANAGER_ENABLED": "false", + "AZMON_PROMETHEUS_ETCD_ENABLED": "true", + "AZMON_PROMETHEUS_NODE-AUTO-PROVISIONING_ENABLED": "false", + "DEBUG_MODE_ENABLED": "", + "AZMON_INVALID_CUSTOM_PROMETHEUS_CONFIG": "", + "CONFIG_VALIDATOR_RUNNING_IN_AGENT": "", + "AZMON_USE_DEFAULT_PROMETHEUS_CONFIG": "", + } + + jobEnvVars := JobEnabledEnvVars(shared.ControlPlaneDefaultScrapeJobs, func(jobName string) string { + return BuildEnvVarName(jobName, "_ENABLED") + }) + for key, value := range jobEnvVars { + envVars[key] = value + } + + return envVars +} + +// ManagedPrometheusEnvVars returns the environment variables that should be +// present for Managed Prometheus tests based on controller type and OS. +func ManagedPrometheusEnvVars(controllerType, osType string) map[string]string { + switch osType { + case shared.OSType.Windows: + return map[string]string{ + "AZMON_OPERATOR_ENABLED": "true", + "CONTAINER_TYPE": "", + "CONTROLLER_TYPE": shared.ControllerType.DaemonSet, + "OS_TYPE": "windows", + "MODE": "advanced", + "KUBE_STATE_NAME": "ama-metrics-ksm", + "POD_NAMESPACE": "kube-system", + "MAC": "true", + "NODE_NAME": "test-node", + "NODE_IP": "192.168.1.1", + "NODE_EXPORTER_TARGETPORT": "9100", + "AZMON_SET_GLOBAL_SETTINGS": "true", + } + case shared.OSType.Linux: + switch controllerType { + case shared.ControllerType.ReplicaSet: + return map[string]string{ + "AZMON_OPERATOR_ENABLED": "true", + "CONTAINER_TYPE": "", + "CONTROLLER_TYPE": shared.ControllerType.ReplicaSet, + "OS_TYPE": "linux", + "MODE": "advanced", + "KUBE_STATE_NAME": "ama-metrics-ksm", + "POD_NAMESPACE": "kube-system", + "MAC": "true", + "AZMON_SET_GLOBAL_SETTINGS": "true", + } + case shared.ControllerType.ConfigReaderSidecar: + return map[string]string{ + "AZMON_OPERATOR_ENABLED": "true", + "CONTAINER_TYPE": shared.ControllerType.ConfigReaderSidecar, + "CONTROLLER_TYPE": shared.ControllerType.ConfigReaderSidecar, + "OS_TYPE": "linux", + "MODE": "advanced", + "KUBE_STATE_NAME": "ama-metrics-ksm", + "POD_NAMESPACE": "kube-system", + "MAC": "true", + "AZMON_SET_GLOBAL_SETTINGS": "true", + } + case shared.ControllerType.DaemonSet: + return map[string]string{ + "AZMON_OPERATOR_ENABLED": "true", + "CONTAINER_TYPE": "", + "CONTROLLER_TYPE": shared.ControllerType.DaemonSet, + "OS_TYPE": "linux", + "MODE": "advanced", + "KUBE_STATE_NAME": "ama-metrics-ksm", + "POD_NAMESPACE": "kube-system", + "MAC": "true", + "NODE_NAME": "test-node", + "NODE_IP": "192.168.1.1", + "NODE_EXPORTER_TARGETPORT": "9100", + "AZMON_SET_GLOBAL_SETTINGS": "true", + } + } + } + + return map[string]string{} +} + +// SetManagedPrometheusEnvVars configures the Managed Prometheus environment +// variables for the supplied controller and OS combination. +func SetManagedPrometheusEnvVars(controllerType, osType string) error { + return SetEnvVars(ManagedPrometheusEnvVars(controllerType, osType)) +} + +// ControlPlaneEnvVars returns the environment variables that should be present +// for control-plane tests based on controller type and OS. +func ControlPlaneEnvVars(controllerType, osType string) map[string]string { + if osType != shared.OSType.Linux { + return map[string]string{} + } + + switch controllerType { + case shared.ControllerType.ReplicaSet: + return map[string]string{ + "AZMON_OPERATOR_ENABLED": "false", + "CONTAINER_TYPE": "", + "CONTROLLER_TYPE": shared.ControllerType.ReplicaSet, + "OS_TYPE": "linux", + "MODE": "advanced", + "KUBE_STATE_NAME": "ama-metrics-ksm", + "POD_NAMESPACE": "kube-system", + "MAC": "true", + "AZMON_SET_GLOBAL_SETTINGS": "true", + } + default: + return map[string]string{} + } +} + +// SetControlPlaneEnvVars configures the control-plane environment variables for +// the supplied controller and OS combination. +func SetControlPlaneEnvVars(controllerType, osType string) error { + return SetEnvVars(ControlPlaneEnvVars(controllerType, osType)) +} + +// MergeStringMaps copies the provided maps into a freshly allocated one. +func MergeStringMaps(maps ...map[string]string) map[string]string { + merged := make(map[string]string) + for _, m := range maps { + for key, value := range m { + merged[key] = value + } + } + return merged +} + +// SetupCollectorConfigFiles updates the supplied config map mount paths so that +// the configmap parser writes into temporary files during tests. +func SetupCollectorConfigFiles(defaultPath bool, prefixes CollectorPrefixes, paths CollectorConfigPaths) error { + if err := os.MkdirAll(prefixes.ConfigSettingsPrefix, 0755); err != nil { + return fmt.Errorf("failed to create config settings directory %s: %w", prefixes.ConfigSettingsPrefix, err) + } + + if defaultPath { + if paths.ConfigMapDebugMountPath != nil { + *paths.ConfigMapDebugMountPath = "/etc/config/settings/debug-mode" + } + if paths.ReplicaSetCollectorConfig != nil { + *paths.ReplicaSetCollectorConfig = "/opt/microsoft/otelcollector/collector-config-replicaset.yml" + } + if paths.DefaultSettingsMountPath != nil { + *paths.DefaultSettingsMountPath = "/etc/config/settings/default-scrape-settings" + } + if paths.ConfigMapKeepListMountPath != nil { + *paths.ConfigMapKeepListMountPath = "/etc/config/settings/default-targets-metrics-keep-list" + } + if paths.ConfigMapMountPathForPodAnnotation != nil { + *paths.ConfigMapMountPathForPodAnnotation = "/etc/config/settings/pod-annotation-based-scraping" + } + if paths.CollectorSettingsMountPath != nil { + *paths.CollectorSettingsMountPath = "/etc/config/settings/prometheus-collector-settings" + } + if paths.ConfigMapOpentelemetryMetricsPath != nil { + *paths.ConfigMapOpentelemetryMetricsPath = "/etc/config/settings/opentelemetry-metrics" + } + if paths.ConfigMapScrapeIntervalMountPath != nil { + *paths.ConfigMapScrapeIntervalMountPath = "/etc/config/settings/default-targets-scrape-interval-settings" + } + + if _, err := CreateTempFile(prefixes.ConfigSettingsPrefix, "cluster-metrics", ""); err != nil { + return err + } + if _, err := CreateTempFile(prefixes.ConfigSettingsPrefix, "prometheus-collector-settings", ""); err != nil { + return err + } + return nil + } + + create := func(target *string, name string) error { + if target == nil { + return nil + } + path, err := CreateTempFile(prefixes.ConfigSettingsPrefix, name, "") + if err != nil { + return err + } + *target = path + return nil + } + + if err := create(paths.ConfigMapMountPathForPodAnnotation, "pod-annotation-based-scraping"); err != nil { + return err + } + if err := create(paths.CollectorSettingsMountPath, "prometheus-collector-settings"); err != nil { + return err + } + if err := create(paths.DefaultSettingsMountPath, "default-scrape-settings-enabled"); err != nil { + return err + } + if err := create(paths.ConfigMapDebugMountPath, "debug-mode"); err != nil { + return err + } + if err := create(paths.ConfigMapKeepListMountPath, "default-targets-metrics-keep-list"); err != nil { + return err + } + if err := create(paths.ConfigMapScrapeIntervalMountPath, "default-targets-scrape-interval-settings"); err != nil { + return err + } + if err := create(paths.ConfigMapOpentelemetryMetricsPath, "opentelemetry-metrics"); err != nil { + return err + } + if _, err := CreateTempFile(prefixes.ConfigSettingsPrefix, "cluster-metrics", ""); err != nil { + return err + } + if _, err := CreateTempFile(prefixes.ConfigSettingsPrefix, "prometheus-collector-settings", ""); err != nil { + return err + } + if paths.ReplicaSetCollectorConfig != nil { + *paths.ReplicaSetCollectorConfig = "./testdata/collector-config-replicaset.yml" + } + return nil +} + +// SetupCollectorProcessedFiles prepares the intermediate files consumed by the +// configmap parser during tests. +func SetupCollectorProcessedFiles(prefixes CollectorPrefixes, paths CollectorProcessedPaths) error { + if err := os.MkdirAll(prefixes.ConfigMapParserPrefix, 0755); err != nil { + return fmt.Errorf("failed to create configmap parser directory %s: %w", prefixes.ConfigMapParserPrefix, err) + } + + create := func(target *string, name string) error { + if target == nil { + return nil + } + path, err := CreateTempFile(prefixes.ConfigMapParserPrefix, name, "") + if err != nil { + return err + } + *target = path + return nil + } + + if err := create(paths.PodAnnotationEnvVarPath, "config_def_pod_annotation_based_scraping"); err != nil { + return err + } + if err := create(paths.CollectorSettingsEnvVarPath, "config_prometheus_collector_settings_env_var"); err != nil { + return err + } + if err := create(paths.DefaultSettingsEnvVarPath, "config_default_scrape_settings_env_var"); err != nil { + return err + } + if err := create(paths.DebugModeEnvVarPath, "config_debug_mode_env_var"); err != nil { + return err + } + if err := create(paths.ConfigMapKeepListEnvVarPath, "config_def_targets_metrics_keep_list_hash"); err != nil { + return err + } + if err := create(paths.ScrapeIntervalEnvVarPath, "config_def_targets_scrape_intervals_hash"); err != nil { + return err + } + if err := create(paths.OpentelemetryMetricsEnvVarPath, "config_opentelemetry_metrics_env_var"); err != nil { + return err + } + if err := create(paths.KsmConfigEnvVarPath, "config_ksm_config_env_var"); err != nil { + return err + } + + srcDir := "../../../configmapparser/default-prom-configs/" + testDir := "../../../configmapparser/default-prom-configs/test/" + if err := CopyDirectoryFiles(srcDir, testDir); err != nil { + return err + } + if paths.ScrapeConfigDefinitionPathPrefix != nil { + *paths.ScrapeConfigDefinitionPathPrefix = testDir + } + + if err := create(paths.MergedDefaultConfigPath, "defaultsMergedConfig.yaml"); err != nil { + return err + } + if err := create(paths.PromMergedConfigPath, "promMergedConfig.yaml"); err != nil { + return err + } + + if paths.RegexHashFile != nil && paths.ConfigMapKeepListEnvVarPath != nil { + *paths.RegexHashFile = *paths.ConfigMapKeepListEnvVarPath + } + if paths.IntervalHashFile != nil && paths.ScrapeIntervalEnvVarPath != nil { + *paths.IntervalHashFile = *paths.ScrapeIntervalEnvVarPath + } + + return nil +} + +// CreateTempFile writes content to a file at dir/name, ensuring the directory exists. +func CreateTempFile(dir, name, content string) (string, error) { + if err := os.MkdirAll(dir, 0755); err != nil { + return "", fmt.Errorf("failed to create directory %s: %w", dir, err) + } + + path := filepath.Join(dir, name) + if err := os.WriteFile(path, []byte(content), 0644); err != nil { + return "", fmt.Errorf("failed to write file %s: %w", path, err) + } + + info, err := os.Stat(path) + if err != nil { + return "", fmt.Errorf("failed to stat file %s: %w", path, err) + } + if info.Size() != int64(len(content)) { + return "", fmt.Errorf("file %s has incorrect size: expected %d, got %d", path, len(content), info.Size()) + } + + return path, nil +} + +// MustCreateTempFile wraps CreateTempFile and panics if any error occurs. +// Intended for use in tests where panics fail the test immediately. +func MustCreateTempFile(dir, name, content string) string { + path, err := CreateTempFile(dir, name, content) + if err != nil { + panic(err) + } + return path +} + +// CopyDirectoryFiles copies all non-directory files from srcDir into dstDir. +func CopyDirectoryFiles(srcDir, dstDir string) error { + if err := os.MkdirAll(dstDir, 0755); err != nil { + return fmt.Errorf("failed to create destination directory %s: %w", dstDir, err) + } + + entries, err := os.ReadDir(srcDir) + if err != nil { + return fmt.Errorf("failed to read source directory %s: %w", srcDir, err) + } + + for _, entry := range entries { + if entry.IsDir() { + continue + } + + srcPath := filepath.Join(srcDir, entry.Name()) + dstPath := filepath.Join(dstDir, entry.Name()) + + data, err := os.ReadFile(srcPath) + if err != nil { + return fmt.Errorf("failed to read file %s: %w", srcPath, err) + } + + if err := os.WriteFile(dstPath, data, 0644); err != nil { + return fmt.Errorf("failed to write file %s: %w", dstPath, err) + } + } + + return nil +} + +// CheckEnvVars verifies that the environment matches the expected key/value pairs. +func CheckEnvVars(expected map[string]string) error { + for key, value := range expected { + if os.Getenv(key) != value { + return fmt.Errorf("expected %s to be %s, but got %s", key, value, os.Getenv(key)) + } + } + return nil +} + +// SetEnvVars applies the provided environment variables. +func SetEnvVars(values map[string]string) error { + for key, value := range values { + if err := os.Setenv(key, value); err != nil { + return fmt.Errorf("failed setting %s: %w", key, err) + } + } + return nil +} + +// UnsetEnvVars removes the supplied environment variables. +func UnsetEnvVars(keys []string) { + for _, key := range keys { + _ = os.Unsetenv(key) + } +} + +// ReadYAMLStringMap loads a YAML file containing a string -> string map. +func ReadYAMLStringMap(path string) (map[string]string, error) { + data, err := os.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("failed to read file %s: %w", path, err) + } + + if len(data) == 0 { + return map[string]string{}, nil + } + + result := make(map[string]string) + if err := yaml.Unmarshal(data, &result); err != nil { + return nil, fmt.Errorf("failed to unmarshal YAML from %s: %w", path, err) + } + + return result, nil +} + +// ExpectedKeepListMap returns the desired keep-list map for the supplied jobs. +// When includeMinimalKeepList is true the resulting value combines the provided +// value and the minimal keep list regex via "value|minimal" to mirror legacy +// behaviour. The collector selector distinguishes between data-plane (Managed +// Prometheus) and control-plane collectors when deriving environment variable +// names. +func ExpectedKeepListMap( + jobs map[string]*shared.DefaultScrapeJob, + includeMinimalKeepList bool, + value string, + isDataPlane bool, +) map[string]string { + expected := make(map[string]string, len(jobs)) + for jobName, job := range jobs { + var key string + if isDataPlane { + key = fmt.Sprintf("%s_METRICS_KEEP_LIST_REGEX", strings.ToUpper(jobName)) + } else { + key = fmt.Sprintf("CONTROLPLANE_%s_KEEP_LIST_REGEX", strings.ToUpper(jobName)) + } + if includeMinimalKeepList { + expected[key] = fmt.Sprintf("%s|%s", value, job.MinimalKeepListRegex) + } else { + expected[key] = value + } + } + return expected +} + +// ExpectedScrapeIntervalMap returns the desired scrape interval map for the +// supplied jobs. When override is empty the job's configured scrape interval is +// used. +func ExpectedScrapeIntervalMap( + jobs map[string]*shared.DefaultScrapeJob, + override string, +) map[string]string { + expected := make(map[string]string, len(jobs)) + for jobName, job := range jobs { + key := strings.ToUpper(jobName) + "_SCRAPE_INTERVAL" + if override == "" { + expected[key] = job.ScrapeInterval + } else { + expected[key] = override + } + } + return expected +} diff --git a/otelcollector/shared/configmap/common/tomlparser-default-scrape-settings-shared.go b/otelcollector/shared/configmap/common/tomlparser-default-scrape-settings-shared.go new file mode 100644 index 000000000..9b37229f2 --- /dev/null +++ b/otelcollector/shared/configmap/common/tomlparser-default-scrape-settings-shared.go @@ -0,0 +1,99 @@ +package common + +import ( + "fmt" + "os" + "regexp" + "strconv" + "strings" + + "github.com/prometheus-collector/shared" +) + +// JobKeyFormatter is used to translate a job name into the key expected in the +// customer-provided config map based on the schema version. +type JobKeyFormatter func(jobName string, schemaVersion string) string + +// EnvVarFormatter generates the environment variable name that should be +// written for a given job. +type EnvVarFormatter func(jobName string) string + +// UpdateJobEnablement reads enablement flags from the provided settings map and +// applies them to the supplied job catalog. The map is expected to contain the +// job name (formatted through jobKeyFormatter) as the key. +func UpdateJobEnablement(settings map[string]string, jobs map[string]*shared.DefaultScrapeJob, schemaVersion string, jobKeyFormatter JobKeyFormatter) error { + if settings == nil { + return nil + } + + for jobName, job := range jobs { + key := jobKeyFormatter(jobName, schemaVersion) + if key == "" { + key = jobName + } + + if value, ok := settings[key]; ok { + enabled, err := strconv.ParseBool(value) + if err != nil { + return fmt.Errorf("common.UpdateJobEnablement::error parsing value for %s: %w", key, err) + } + job.Enabled = enabled + } + } + + return nil +} + +// DetermineNoDefaultsEnabled inspects the supplied jobs and returns true when +// none of them is enabled for the effective controller and OS. +func DetermineNoDefaultsEnabled(jobs map[string]*shared.DefaultScrapeJob, controllerType, containerType, osType string) bool { + effectiveController := controllerType + if strings.EqualFold(containerType, shared.ControllerType.ConfigReaderSidecar) { + effectiveController = shared.ControllerType.ReplicaSet + } + + for _, job := range jobs { + if job.ControllerType == effectiveController && strings.EqualFold(job.OSType, osType) && job.Enabled { + return false + } + } + return true +} + +// ComputeClusterAlias mirrors the cluster alias normalization logic used by +// both CCP and MP variants. +func ComputeClusterAlias(cluster, macEnv string) string { + trimmedCluster := strings.TrimSpace(cluster) + if strings.EqualFold(strings.TrimSpace(macEnv), "true") { + segments := strings.Split(trimmedCluster, "/") + trimmedCluster = segments[len(segments)-1] + } + + if trimmedCluster == "" { + return "" + } + + alias := regexp.MustCompile(`[^0-9a-zA-Z]+`).ReplaceAllString(trimmedCluster, "_") + return strings.Trim(alias, "_") +} + +// WriteEnabledEnvFile persists the job enablement flags along with the +// NoDefaultsEnabled marker. +func WriteEnabledEnvFile(filePath string, jobs map[string]*shared.DefaultScrapeJob, envVarFormatter EnvVarFormatter, noDefaults bool) error { + file, err := os.OpenFile(filePath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + return fmt.Errorf("common.WriteEnabledEnvFile::opening file failed: %w", err) + } + defer file.Close() + + for jobName, job := range jobs { + if _, err := fmt.Fprintf(file, "AZMON_PROMETHEUS_%s=%v\n", envVarFormatter(jobName), job.Enabled); err != nil { + return fmt.Errorf("common.WriteEnabledEnvFile::writing flag for %s failed: %w", jobName, err) + } + } + if _, err := fmt.Fprintf(file, "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED=%v\n", noDefaults); err != nil { + return fmt.Errorf("common.WriteEnabledEnvFile::writing no defaults flag failed: %w", err) + } + + return nil +} diff --git a/otelcollector/shared/configmap/common/tomlparser-default-targets-metrics-keep-list-shared.go b/otelcollector/shared/configmap/common/tomlparser-default-targets-metrics-keep-list-shared.go new file mode 100644 index 000000000..271a71586 --- /dev/null +++ b/otelcollector/shared/configmap/common/tomlparser-default-targets-metrics-keep-list-shared.go @@ -0,0 +1,120 @@ +package common + +import ( + "fmt" + "io/fs" + "os" + "strconv" + "strings" + + "github.com/prometheus-collector/shared" + "gopkg.in/yaml.v2" +) + +// KeepListOptions describes how to interpret keep list data for a given variant. +type KeepListOptions struct { + Jobs map[string]*shared.DefaultScrapeJob + MetricsConfig map[string]map[string]string + SchemaVersion string + KeepListSection string + MinimalProfileSection string + MinimalProfileKeyV1 string + MinimalProfileKeyV2 string + OutputPath string + EnvVarFormatter EnvVarFormatter + JobKeyFormatter JobKeyFormatter + MinimalProfileDefaultBool bool +} + +// MinimalProfileSetting extracts the value that indicates whether the minimal +// ingestion profile should be enforced. The config map layout differs between +// schema versions, so the caller provides both the section and key to read. If +// the value cannot be parsed, defaultValue is returned. +func MinimalProfileSetting(metricsConfig map[string]map[string]string, sectionName, keyName string, defaultValue bool) bool { + section, ok := metricsConfig[sectionName] + if !ok { + return defaultValue + } + + value, ok := section[strings.ToLower(keyName)] + if !ok { + value, ok = section[keyName] + if !ok { + return defaultValue + } + } + + parsed, err := strconv.ParseBool(value) + if err != nil { + return defaultValue + } + return parsed +} + +// PopulateKeepLists updates the job catalog with customer-provided and minimal +// keep list expressions and writes the resulting values to a YAML file that can +// be consumed by downstream components. +func PopulateKeepLists(opts KeepListOptions) error { + var keeplist map[string]string + if opts.MetricsConfig != nil { + keeplist = opts.MetricsConfig[opts.KeepListSection] + } + + minimalProfileEnabled := opts.MinimalProfileDefaultBool + + switch opts.SchemaVersion { + case shared.SchemaVersion.V1: + minimalProfileEnabled = MinimalProfileSetting(opts.MetricsConfig, opts.KeepListSection, opts.MinimalProfileKeyV1, opts.MinimalProfileDefaultBool) + case shared.SchemaVersion.V2: + minimalProfileEnabled = MinimalProfileSetting(opts.MetricsConfig, opts.MinimalProfileSection, opts.MinimalProfileKeyV2, opts.MinimalProfileDefaultBool) + } + + if err := shared.SetEnvAndSourceBashrcOrPowershell( + "MINIMAL_INGESTION_PROFILE", + strconv.FormatBool(minimalProfileEnabled), + true, + ); err != nil { + return fmt.Errorf("common.PopulateKeepLists::setting MINIMAL_INGESTION_PROFILE failed: %w", err) + } + + for jobName, job := range opts.Jobs { + job.CustomerKeepListRegex = "" + job.KeepListRegex = "" + + key := opts.JobKeyFormatter(jobName, opts.SchemaVersion) + if keeplist != nil { + if value, ok := keeplist[key]; ok { + if !shared.IsValidRegex(value) { + continue + } + job.CustomerKeepListRegex = value + } + } + + regexParts := []string{job.CustomerKeepListRegex} + if minimalProfileEnabled { + regexParts = append(regexParts, job.MinimalKeepListRegex) + } + job.KeepListRegex = strings.Join(regexParts, "|") + } + + data := map[string]string{} + for jobName, job := range opts.Jobs { + envName := opts.EnvVarFormatter(jobName) + if envName == "" { + continue + } + data[envName] = job.KeepListRegex + } + + out, err := yaml.Marshal(data) + if err != nil { + return fmt.Errorf("common.PopulateKeepLists::marshal failed: %w", err) + } + + if err := os.WriteFile(opts.OutputPath, out, fs.FileMode(0644)); err != nil { + return fmt.Errorf("common.PopulateKeepLists::write file failed: %w", err) + } + + return nil +} diff --git a/otelcollector/shared/configmap/common/tomlparser-opentelemetry-metrics-shared.go b/otelcollector/shared/configmap/common/tomlparser-opentelemetry-metrics-shared.go new file mode 100644 index 000000000..20c9d55c7 --- /dev/null +++ b/otelcollector/shared/configmap/common/tomlparser-opentelemetry-metrics-shared.go @@ -0,0 +1,69 @@ +package common + +import ( + "fmt" + "io" + "os" + "strconv" +) + +// ResolveOtelMetricsEnabled inspects the "opentelemetry-metrics" section and +// returns true when the "enabled" entry parses to true. Missing or invalid +// values fall back to false. +func ResolveOtelMetricsEnabled(metricsConfig map[string]map[string]string, logFn LogFunc) bool { + logger := ensureLogFunc(logFn) + + section, ok := metricsConfig["opentelemetry-metrics"] + if !ok { + return false + } + + raw, ok := section["enabled"] + if !ok { + return false + } + + enabled, err := strconv.ParseBool(raw) + if err != nil { + logger("Invalid value for opentelemetry-metrics enabled: %s, defaulting to false\n", raw) + return false + } + + logger("Using configmap setting for opentelemetry-metrics: %v\n", enabled) + return enabled +} + +// WriteOtelMetricsEnv writes the AZMON_FULL_OTLP_ENABLED flag to the provided +// writer, mirroring previous behaviour in both CCP and MP flows. +func WriteOtelMetricsEnv(w io.Writer, enabled bool, logFn LogFunc) error { + if _, err := fmt.Fprintf(w, "AZMON_FULL_OTLP_ENABLED=%v\n", enabled); err != nil { + return err + } + + logger := ensureLogFunc(logFn) + logger("Setting AZMON_FULL_OTLP_ENABLED environment variable: %v\n", enabled) + + return nil +} + +// WriteOtelMetricsEnvFile is a convenience that resolves the enabled flag and +// writes directly to the target file path. +func WriteOtelMetricsEnvFile(metricsConfig map[string]map[string]string, dstPath string, logFn LogFunc) error { + if metricsConfig == nil { + return fmt.Errorf("configmap section not mounted, using defaults") + } + + enabled := ResolveOtelMetricsEnabled(metricsConfig, logFn) + + file, err := os.Create(dstPath) + if err != nil { + return fmt.Errorf("exception while opening file for writing prometheus-collector config environment variables: %w", err) + } + defer file.Close() + + if err := WriteOtelMetricsEnv(file, enabled, logFn); err != nil { + return err + } + + return nil +} diff --git a/otelcollector/shared/configmap/common/tomlparser-prometheus-collector-settings-shared.go b/otelcollector/shared/configmap/common/tomlparser-prometheus-collector-settings-shared.go new file mode 100644 index 000000000..0cdd935bc --- /dev/null +++ b/otelcollector/shared/configmap/common/tomlparser-prometheus-collector-settings-shared.go @@ -0,0 +1,107 @@ +package common + +import ( + "fmt" + "io" + "os" + "regexp" + "strings" +) + +// CollectorSettings captures the shared prometheus-collector-settings values +// that both MP and CCP flows care about. +type CollectorSettings struct { + MetricAccountName string + ClusterAlias string + ClusterLabel string + OperatorEnabled bool + OperatorEnabledChart bool +} + +var nonAlphaNumeric = regexp.MustCompile(`[^0-9a-zA-Z]+`) + +// PopulateSharedCollectorSettings hydrates the supplied CollectorSettings with +// values from the prometheus-collector-settings section and relevant +// environment variables. +func PopulateSharedCollectorSettings(result *CollectorSettings, metricsConfig map[string]map[string]string, logFn LogFunc) { + logger := ensureLogFunc(logFn) + + settingsSection, ok := metricsConfig["prometheus-collector-settings"] + if !ok { + logger("prometheus-collector-settings section not found in metricsConfigBySection, using defaults\n") + } + + if ok { + if value, exists := settingsSection["default_metric_account_name"]; exists { + result.MetricAccountName = value + logger("Using configmap setting for default metric account name: %s\n", result.MetricAccountName) + } + + if value, exists := settingsSection["cluster_alias"]; exists { + alias := strings.TrimSpace(value) + logger("Got configmap setting for cluster_alias: %s\n", alias) + if alias != "" { + alias = nonAlphaNumeric.ReplaceAllString(alias, "_") + alias = strings.Trim(alias, "_") + logger("After replacing non-alpha-numeric characters with '_': %s\n", alias) + } + result.ClusterAlias = alias + } + } + + operatorEnabledEnv := strings.ToLower(strings.TrimSpace(os.Getenv("AZMON_OPERATOR_ENABLED"))) + if operatorEnabledEnv == "true" { + result.OperatorEnabledChart = true + if ok { + if value, exists := settingsSection["operator_enabled"]; exists { + result.OperatorEnabled = strings.ToLower(strings.TrimSpace(value)) == "true" + logger("Configmap setting enabling operator: %t\n", result.OperatorEnabled) + } + } + } else { + result.OperatorEnabledChart = false + result.OperatorEnabled = false + } + + result.ClusterLabel = deriveClusterLabel(result.ClusterAlias) +} + +func deriveClusterLabel(clusterAlias string) string { + cluster := strings.TrimSpace(os.Getenv("CLUSTER")) + if strings.EqualFold(strings.TrimSpace(os.Getenv("MAC")), "true") && cluster != "" { + segments := strings.Split(cluster, "/") + cluster = segments[len(segments)-1] + } + + if clusterAlias != "" { + cluster = clusterAlias + } + + return cluster +} + +// WriteSharedCollectorSettings writes the shared collector settings to the +// provided writer. +func WriteSharedCollectorSettings(w io.Writer, settings CollectorSettings) error { + if _, err := fmt.Fprintf(w, "AZMON_DEFAULT_METRIC_ACCOUNT_NAME=%s\n", settings.MetricAccountName); err != nil { + return err + } + if _, err := fmt.Fprintf(w, "AZMON_CLUSTER_LABEL=%s\n", settings.ClusterLabel); err != nil { + return err + } + if _, err := fmt.Fprintf(w, "AZMON_CLUSTER_ALIAS=%s\n", settings.ClusterAlias); err != nil { + return err + } + if _, err := fmt.Fprintf(w, "AZMON_OPERATOR_ENABLED_CHART_SETTING=%t\n", settings.OperatorEnabledChart); err != nil { + return err + } + if settings.OperatorEnabled { + if _, err := fmt.Fprintf(w, "AZMON_OPERATOR_ENABLED=%t\n", settings.OperatorEnabled); err != nil { + return err + } + if _, err := fmt.Fprintf(w, "AZMON_OPERATOR_ENABLED_CFG_MAP_SETTING=%t\n", settings.OperatorEnabled); err != nil { + return err + } + } + return nil +} diff --git a/otelcollector/shared/configmap/mp/README.md b/otelcollector/shared/configmap/mp/README.md new file mode 100644 index 000000000..009ce5ab8 --- /dev/null +++ b/otelcollector/shared/configmap/mp/README.md @@ -0,0 +1,64 @@ +# Managed Prometheus Configmap Tests + +This package contains the Ginkgo-based integration tests that guard the Managed Prometheus (MP) configmap parser. The tests simulate every combination of platform (Linux ReplicaSet, Linux DaemonSet, Windows DaemonSet) and configmap settings to ensure that: + +1. The configmapparser writes the correct environment variables for the agent pods. +2. The generated Prometheus configuration matches the expected fixtures under `./testdata`. + +## Repository layout + +- `configmapparser_test.go` – master spec that drives all scenarios via helper contexts. +- `testdata/` – canonical Prometheus config fixtures that every scenario compares against. +- `configmap-test-cases/` – TOML snippets used by some contexts to mimic multi-section configmaps (both v1 and v2 schemas). +- `../common/testhelpers` – shared helpers that provides temp file helpers, env overrides, and comparison utilities. + +## Running the tests + +```bash +cd otelcollector/shared/configmap/mp +go test . +``` + + +## How the specs work + +Each context builds a scenario by writing synthetic configmap files into `/tmp/settings`, seeding env vars via `testhelpers.SetManagedPrometheusEnvVars`, and then calling the configmapparser's main function `processConfigFiles()`. + +The common `checkResults(...)` helper performs three validations: + +1. **Env vars** – compares actual vars against `expectedEnvVars` using `testhelpers.CheckEnvVars`. +2. **Keep-list and scrape-interval hashes** – parses the generated YAML files and diff-checks them against maps built by `testhelpers.ExpectedKeepListMap` / `ExpectedScrapeIntervalMap`. +3. **Prometheus configs** – reads `mergedDefaultConfigPath` (and optionally the merged custom config) and asserts equivalence against the YAML in `./testdata`. + +All scrape configs are sorted by `job_name` prior to comparison so fixture ordering does not depend on the ordering that the configmapparser produces. + +## Test coverage + +The suite currently exercises the following scenarios (each runs across Linux ReplicaSet, Linux DaemonSet, and Windows DaemonSet): + +- When the settings configmap does not exist +- When the settings configmap sections exist but are empty +- When the settings configmap sections exist and are not default +- When some of the configmap sections exist but not all +- When the configmap sections exist but all scrape jobs are false +- When minimal ingestion is false and has keeplist regex values +- When minimal ingestion is false and has no keeplist regex values +- When the custom configmap exists + - And the settings configmap sections do not exist + - And the settings configmap sections have all default scrape configs set to false +- When the settings configmap uses v2 and the sections exist but are empty +- When the settings configmap uses v2 and the sections are not default +- When the settings configmap uses v2, minimal ingestion is false, and not all sections are present + + +## Adding or updating scenarios + +Use the following checklist whenever you add a new scenario or update an existing one: + +1. **Decide the context** – pick the closest existing `Context(...)` block in `configmapparser_test.go` or add a new one if the behavior differs materially (new schema version, new feature gate, etc.). +2. **Author temp config files** – leverage `testhelpers.MustCreateTempFile` to write the configmap sections (default scrape settings, keep-list, scrape intervals, pod annotation regex, etc.). Remember that anything omitted defaults to empty. +3. **Set env expectations** – start with `testhelpers.DefaultManagedPrometheusEnvVars()` and override only what the scenario mutates. If the scenario toggles scrape jobs, use `testhelpers.BuildEnvVarOverrides` so both tests and parser stay in sync. +4. **Capture expected Prometheus output** – run the parser once (e.g., `go test -run '' .`), grab the generated content from the output, and copy it into `testdata/.yaml`. +5. **Update `configmap-test-cases` if needed** – some contexts drive the parser by pointing at TOML fixtures. If your scenario depends on a new setting, add it to both v1 and v2 directories so upgrade tests stay aligned. +6. **Add assertions** – point your new `It(...)` block at `checkResults(...)`, passing the expected env/keep-list/scrape interval maps and the paths of any fixtures you created. +7. **Run the suite** – execute `go test .` (or a focused subset) until everything passes. diff --git a/otelcollector/shared/configmap/mp/configmap-test-cases/v1/all-default-configs-false.yaml b/otelcollector/shared/configmap/mp/configmap-test-cases/v1/all-default-configs-false.yaml new file mode 100644 index 000000000..64edc72e2 --- /dev/null +++ b/otelcollector/shared/configmap/mp/configmap-test-cases/v1/all-default-configs-false.yaml @@ -0,0 +1,28 @@ +schema-version: + v1 +config-version: + ver1 +default-scrape-settings-enabled: + kubelet = false + coredns = false + cadvisor = false + kubeproxy = false + apiserver = false + kubestate = false + nodeexporter = false + windowsexporter = false + windowskubeproxy = false + kappiebasic = false + networkobservabilityRetina = false + networkobservabilityHubble = false + networkobservabilityCilium = false + acstor-capacity-provisioner = false + acstor-metrics-exporter = false + dcgmexporter = false + prometheuscollectorhealth = false + controlplane-apiserver = false + controlplane-cluster-autoscaler = false + controlplane-node-auto-provisioning = false + controlplane-kube-scheduler = false + controlplane-kube-controller-manager = false + controlplane-etcd = false diff --git a/otelcollector/shared/configmap/mp/configmap-test-cases/v1/all-sections-defined-but-empty.yaml b/otelcollector/shared/configmap/mp/configmap-test-cases/v1/all-sections-defined-but-empty.yaml new file mode 100644 index 000000000..6536748f7 --- /dev/null +++ b/otelcollector/shared/configmap/mp/configmap-test-cases/v1/all-sections-defined-but-empty.yaml @@ -0,0 +1,8 @@ +schema-version: +config-version: +prometheus-collector-settings: +default-scrape-settings-enabled: +pod-annotation-based-scraping: +default-targets-metrics-keep-list: +default-targets-scrape-interval-settings: +debug-mode: \ No newline at end of file diff --git a/otelcollector/shared/configmap/mp/configmap-test-cases/v1/minimal-ingestion-false-with-keeplist.yaml b/otelcollector/shared/configmap/mp/configmap-test-cases/v1/minimal-ingestion-false-with-keeplist.yaml new file mode 100644 index 000000000..5fd8bf210 --- /dev/null +++ b/otelcollector/shared/configmap/mp/configmap-test-cases/v1/minimal-ingestion-false-with-keeplist.yaml @@ -0,0 +1,30 @@ +schema-version: + v1 +config-version: + ver1 +default-targets-metrics-keep-list: + kubelet = "test.*|test2" + coredns = "test.*|test2" + cadvisor = "test.*|test2" + kubeproxy = "test.*|test2" + apiserver = "test.*|test2" + kubestate = "test.*|test2" + nodeexporter = "test.*|test2" + windowsexporter = "test.*|test2" + windowskubeproxy = "test.*|test2" + podannotations = "test.*|test2" + kappiebasic = "test.*|test2" + networkobservabilityRetina = "test.*|test2" + networkobservabilityHubble = "test.*|test2" + networkobservabilityCilium = "test.*|test2" + acstor-capacity-provisioner = "test.*|test2" + acstor-metrics-exporter = "test.*|test2" + dcgmexporter = "test.*|test2" + prometheuscollectorhealth = "test.*|test2" + controlplane-apiserver = "test.*|test2" + controlplane-cluster-autoscaler = "test.*|test2" + controlplane-node-auto-provisioning = "test.*|test2" + controlplane-kube-scheduler = "test.*|test2" + controlplane-kube-controller-manager = "test.*|test2" + controlplane-etcd = "test.*|test2" + minimalingestionprofile = false diff --git a/otelcollector/shared/configmap/mp/configmap-test-cases/v1/minimal-ingestion-false-without-keeplist.yaml b/otelcollector/shared/configmap/mp/configmap-test-cases/v1/minimal-ingestion-false-without-keeplist.yaml new file mode 100644 index 000000000..6d55fef30 --- /dev/null +++ b/otelcollector/shared/configmap/mp/configmap-test-cases/v1/minimal-ingestion-false-without-keeplist.yaml @@ -0,0 +1,6 @@ +schema-version: + v1 +config-version: + ver1 +default-targets-metrics-keep-list: + minimalingestionprofile = false diff --git a/otelcollector/shared/configmap/mp/configmap-test-cases/v1/missing-schema-and-config-version-all-custom.yaml b/otelcollector/shared/configmap/mp/configmap-test-cases/v1/missing-schema-and-config-version-all-custom.yaml new file mode 100644 index 000000000..0d7fa98f8 --- /dev/null +++ b/otelcollector/shared/configmap/mp/configmap-test-cases/v1/missing-schema-and-config-version-all-custom.yaml @@ -0,0 +1,76 @@ + +prometheus-collector-settings: |- + cluster_alias = "alias" + https_config = true +default-scrape-settings-enabled: |- + kubelet = true + coredns = true + cadvisor = true + kubeproxy = true + apiserver = true + kubestate = true + nodeexporter = true + windowsexporter = true + windowskubeproxy = true + kappiebasic = true + networkobservabilityRetina = true + networkobservabilityHubble = true + networkobservabilityCilium = true + prometheuscollectorhealth = true + controlplane-apiserver = true + controlplane-cluster-autoscaler = true + controlplane-node-auto-provisioning = true + controlplane-kube-scheduler = true + controlplane-kube-controller-manager = true + controlplane-etcd = true + acstor-capacity-provisioner = true + acstor-metrics-exporter = true + dcgmexporter = true +pod-annotation-based-scraping: |- + podannotationnamespaceregex = ".*|value" +default-targets-metrics-keep-list: |- + kubelet = "test1.*|test2" + coredns = "test1.*|test2" + cadvisor = "test1.*|test2" + kubeproxy = "test1.*|test2" + apiserver = "test1.*|test2" + kubestate = "test1.*|test2" + nodeexporter = "test1.*|test2" + windowsexporter = "test1.*|test2" + windowskubeproxy = "test1.*|test2" + podannotations = "test1.*|test2" + kappiebasic = "test1.*|test2" + networkobservabilityRetina = "test1.*|test2" + networkobservabilityHubble = "test1.*|test2" + networkobservabilityCilium = "test1.*|test2" + controlplane-apiserver = "test1.*|test2" + controlplane-cluster-autoscaler = "test1.*|test2" + controlplane-node-auto-provisioning = "test1.*|test2" + controlplane-kube-scheduler = "test1.*|test2" + controlplane-kube-controller-manager = "test1.*|test2" + controlplane-etcd = "test1.*|test2" + acstor-capacity-provisioner = "test1.*|test2" + acstor-metrics-exporter = "test1.*|test2" + dcgmexporter = "test1.*|test2" + minimalingestionprofile = true +default-targets-scrape-interval-settings: |- + kubelet = "15s" + coredns = "15s" + cadvisor = "15s" + kubeproxy = "15s" + apiserver = "15s" + kubestate = "15s" + nodeexporter = "15s" + windowsexporter = "15s" + windowskubeproxy = "15s" + kappiebasic = "15s" + networkobservabilityRetina = "15s" + networkobservabilityHubble = "15s" + networkobservabilityCilium = "15s" + prometheuscollectorhealth = "15s" + acstor-capacity-provisioner = "15s" + acstor-metrics-exporter = "15s" + dcgmexporter = "15s" + podannotations = "15s" +debug-mode: |- + enabled = true \ No newline at end of file diff --git a/otelcollector/shared/configmap/mp/configmap-test-cases/v2/all-default-configs-false.yaml b/otelcollector/shared/configmap/mp/configmap-test-cases/v2/all-default-configs-false.yaml new file mode 100644 index 000000000..0d0e35c2c --- /dev/null +++ b/otelcollector/shared/configmap/mp/configmap-test-cases/v2/all-default-configs-false.yaml @@ -0,0 +1,31 @@ +schema-version: + v2 +config-version: + ver1 +cluster-metrics: |- + default-targets-scrape-enabled: + kubelet = false + coredns = false + cadvisor = false + kubeproxy = false + apiserver = false + kubestate = false + nodeexporter = false + windowsexporter = false + windowskubeproxy = false + kappiebasic = false + networkobservabilityRetina = false + networkobservabilityHubble = false + networkobservabilityCilium = false + acstor-capacity-provisioner = false + acstor-metrics-exporter = false + dcgmexporter = false + prometheuscollectorhealth = false +controlplane-metrics: |- + default-targets-scrape-enabled: |- + apiserver = false + cluster-autoscaler = false + node-auto-provisioning = false + kube-scheduler = false + kube-controller-manager = false + etcd = false diff --git a/otelcollector/shared/configmap/mp/configmap-test-cases/v2/all-sections-defined-but-empty.yaml b/otelcollector/shared/configmap/mp/configmap-test-cases/v2/all-sections-defined-but-empty.yaml new file mode 100644 index 000000000..ff581a529 --- /dev/null +++ b/otelcollector/shared/configmap/mp/configmap-test-cases/v2/all-sections-defined-but-empty.yaml @@ -0,0 +1,15 @@ +schema-version: + #string.used by agent to parse config. supported versions are {v1, v2}. Configs with other schema versions will be rejected by the agent. + v2 +config-version: +cluster-metrics: |- + default-targets-scrape-enabled: + pod-annotation-based-scraping: + default-targets-metrics-keep-list: + minimal-ingestion-profile: + default-targets-scrape-interval-settings: +controlplane-metrics: |- + default-targets-scrape-enabled: + default-targets-metrics-keep-list: + minimal-ingestion-profile: +prometheus-collector-settings: \ No newline at end of file diff --git a/otelcollector/shared/configmap/mp/configmap-test-cases/v2/minimal-ingestion-false-with-keeplist.yaml b/otelcollector/shared/configmap/mp/configmap-test-cases/v2/minimal-ingestion-false-with-keeplist.yaml new file mode 100644 index 000000000..0a2fd4494 --- /dev/null +++ b/otelcollector/shared/configmap/mp/configmap-test-cases/v2/minimal-ingestion-false-with-keeplist.yaml @@ -0,0 +1,37 @@ +schema-version: + #string.used by agent to parse config. supported versions are {v1, v2}. Configs with other schema versions will be rejected by the agent. + v2 +config-version: + #string.used by customer to keep track of this config file's version in their source control/repository (max allowed 10 chars, other chars will be truncated) + ver1 +cluster-metrics: |- + default-targets-metrics-keep-list: |- + kubelet = "test1.*|test2" + coredns = "test1.*|test2" + cadvisor = "test1.*|test2" + kubeproxy = "test1.*|test2" + apiserver = "test1.*|test2" + kubestate = "test1.*|test2" + nodeexporter = "test1.*|test2" + windowsexporter = "test1.*|test2" + windowskubeproxy = "test1.*|test2" + podannotations = "test1.*|test2" + kappiebasic = "test1.*|test2" + networkobservabilityRetina = "test1.*|test2" + networkobservabilityHubble = "test1.*|test2" + networkobservabilityCilium = "test1.*|test2" + acstor-capacity-provisioner = "test1.*|test2" + acstor-metrics-exporter = "test1.*|test2" + dcgmexporter = "test1.*|test2" + minimal-ingestion-profile: |- + enabled = true +controlplane-metrics: |- + default-targets-metrics-keep-list: |- + apiserver = "test1.*|test2.*" + cluster-autoscaler = "test1.*|test2.*" + node-auto-provisioning = "test1.*|test2.*" + kube-scheduler = "test1.*|test2.*" + kube-controller-manager = "test1.*|test2.*" + etcd = "test1.*|test2.*" + minimal-ingestion-profile: |- + enabled = false \ No newline at end of file diff --git a/otelcollector/shared/configmap/mp/configmap-test-cases/v2/minimal-ingestion-false-without-keeplist.yaml b/otelcollector/shared/configmap/mp/configmap-test-cases/v2/minimal-ingestion-false-without-keeplist.yaml new file mode 100644 index 000000000..593a99a80 --- /dev/null +++ b/otelcollector/shared/configmap/mp/configmap-test-cases/v2/minimal-ingestion-false-without-keeplist.yaml @@ -0,0 +1,12 @@ +schema-version: + #string.used by agent to parse config. supported versions are {v1, v2}. Configs with other schema versions will be rejected by the agent. + v2 +config-version: + #string.used by customer to keep track of this config file's version in their source control/repository (max allowed 10 chars, other chars will be truncated) + ver1 +cluster-metrics: |- + minimal-ingestion-profile: |- + enabled = true +controlplane-metrics: |- + minimal-ingestion-profile: |- + enabled = false \ No newline at end of file diff --git a/otelcollector/shared/configmap/mp/configmap-test-cases/v2/missing-schema-and-config-version-all-custom.yaml b/otelcollector/shared/configmap/mp/configmap-test-cases/v2/missing-schema-and-config-version-all-custom.yaml new file mode 100644 index 000000000..4b8c1f179 --- /dev/null +++ b/otelcollector/shared/configmap/mp/configmap-test-cases/v2/missing-schema-and-config-version-all-custom.yaml @@ -0,0 +1,87 @@ +schema-version: + #string.used by agent to parse config. supported versions are {v1, v2}. Configs with other schema versions will be rejected by the agent. + v2 +config-version: + #string.used by customer to keep track of this config file's version in their source control/repository (max allowed 10 chars, other chars will be truncated) + ver1 +cluster-metrics: |- + default-targets-scrape-enabled: |- + kubelet = true + coredns = true + cadvisor = true + kubeproxy = true + apiserver = true + kubestate = true + nodeexporter = true + windowsexporter = true + windowskubeproxy = true + kappiebasic = true + networkobservabilityRetina = true + networkobservabilityHubble = true + networkobservabilityCilium = true + prometheuscollectorhealth = true + acstor-capacity-provisioner = true + acstor-metrics-exporter = true + dcgmexporter = true + pod-annotation-based-scraping: |- + podannotationnamespaceregex = ".*|value" + default-targets-metrics-keep-list: |- + kubelet = "test1.*|test2" + coredns = "test1.*|test2" + cadvisor = "test1.*|test2" + kubeproxy = "test1.*|test2" + apiserver = "test1.*|test2" + kubestate = "test1.*|test2" + nodeexporter = "test1.*|test2" + windowsexporter = "test1.*|test2" + windowskubeproxy = "test1.*|test2" + podannotations = "test1.*|test2" + kappiebasic = "test1.*|test2" + networkobservabilityRetina = "test1.*|test2" + networkobservabilityHubble = "test1.*|test2" + networkobservabilityCilium = "test1.*|test2" + acstor-capacity-provisioner = "test1.*|test2" + acstor-metrics-exporter = "test1.*|test2" + dcgmexporter = "test1.*|test2" + minimal-ingestion-profile: |- + enabled = true + default-targets-scrape-interval-settings: |- + kubelet = "30s" + coredns = "30s" + cadvisor = "30s" + kubeproxy = "30s" + apiserver = "30s" + kubestate = "30s" + nodeexporter = "30s" + windowsexporter = "30s" + windowskubeproxy = "30s" + kappiebasic = "30s" + networkobservabilityRetina = "30s" + networkobservabilityHubble = "30s" + networkobservabilityCilium = "30s" + acstor-capacity-provisioner = "30s" + acstor-metrics-exporter = "30s" + dcgmexporter = "30s" + prometheuscollectorhealth = "30s" + podannotations = "30s" +controlplane-metrics: |- + default-targets-scrape-enabled: |- + apiserver = true + cluster-autoscaler = true + node-auto-provisioning = true + kube-scheduler = true + kube-controller-manager = true + etcd = true + default-targets-metrics-keep-list: |- + apiserver = "test1.*|test2.*" + cluster-autoscaler = "test1.*|test2.*" + node-auto-provisioning = "test1.*|test2.*" + kube-scheduler = "test1.*|test2.*" + kube-controller-manager = "test1.*|test2.*" + etcd = "test1.*|test2.*" + minimal-ingestion-profile: |- + enabled = true +prometheus-collector-settings: |- + cluster_alias = "alias" + debug-mode = true + https_config = true diff --git a/otelcollector/shared/configmap/mp/configmapparser.go b/otelcollector/shared/configmap/mp/configmapparser.go index 1599133c2..345e9b502 100644 --- a/otelcollector/shared/configmap/mp/configmapparser.go +++ b/otelcollector/shared/configmap/mp/configmapparser.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/prometheus-collector/shared" + cmcommon "github.com/prometheus-collector/shared/configmap/common" ) const ( @@ -15,46 +16,6 @@ const ( defaultConfigFileVersion = "ver1" ) -func setConfigSchemaVersionEnv() { - fileInfo, err := os.Stat(schemaVersionFile) - if err != nil || fileInfo.Size() == 0 { - shared.SetEnvAndSourceBashrcOrPowershell("AZMON_AGENT_CFG_SCHEMA_VERSION", defaultConfigSchemaVersion, true) - return - } - content, err := os.ReadFile(schemaVersionFile) - if err != nil { - shared.EchoError("Error reading schema version file:" + err.Error()) - shared.SetEnvAndSourceBashrcOrPowershell("AZMON_AGENT_CFG_SCHEMA_VERSION", defaultConfigSchemaVersion, true) - return - } - trimmedContent := strings.TrimSpace(string(content)) - configSchemaVersion := strings.ReplaceAll(trimmedContent, " ", "") - if len(configSchemaVersion) > 10 { - configSchemaVersion = configSchemaVersion[:10] - } - shared.SetEnvAndSourceBashrcOrPowershell("AZMON_AGENT_CFG_SCHEMA_VERSION", configSchemaVersion, true) -} - -func setConfigFileVersionEnv() { - fileInfo, err := os.Stat(configVersionFile) - if err != nil || fileInfo.Size() == 0 { - shared.SetEnvAndSourceBashrcOrPowershell("AZMON_AGENT_CFG_FILE_VERSION", defaultConfigFileVersion, true) - return - } - content, err := os.ReadFile(configVersionFile) - if err != nil { - shared.EchoError("Error reading config version file:" + err.Error()) - shared.SetEnvAndSourceBashrcOrPowershell("AZMON_AGENT_CFG_FILE_VERSION", defaultConfigFileVersion, true) - return - } - trimmedContent := strings.TrimSpace(string(content)) - configFileVersion := strings.ReplaceAll(trimmedContent, " ", "") - if len(configFileVersion) > 10 { - configFileVersion = configFileVersion[:10] - } - shared.SetEnvAndSourceBashrcOrPowershell("AZMON_AGENT_CFG_FILE_VERSION", configFileVersion, true) -} - func parseSettingsForPodAnnotations(metricsConfigBySection map[string]map[string]string) { shared.EchoSectionDivider("Start Processing - parseSettingsForPodAnnotations") if err := configurePodAnnotationSettings(metricsConfigBySection); err != nil { @@ -114,9 +75,9 @@ func parsePrometheusCollectorConfig(metricsConfigBySection map[string]map[string shared.EchoSectionDivider("End Processing - parsePrometheusCollectorConfig") } -func parseDefaultScrapeSettings(metricsConfigBySection map[string]map[string]string) { +func parseDefaultScrapeSettings(metricsConfigBySection map[string]map[string]string, schemaVersion string) { shared.EchoSectionDivider("Start Processing - parseDefaultScrapeSettings") - tomlparserDefaultScrapeSettings(metricsConfigBySection) + tomlparserDefaultScrapeSettings(metricsConfigBySection, schemaVersion) handleEnvFileError(defaultSettingsEnvVarPath) shared.EchoSectionDivider("End Processing - parseDefaultScrapeSettings") } @@ -125,7 +86,6 @@ func parseDebugModeSettings(metricsConfigBySection map[string]map[string]string) shared.EchoSectionDivider("Start Processing - parseDebugModeSettings") if err := ConfigureDebugModeSettings(metricsConfigBySection); err != nil { shared.EchoError(err.Error()) - return } handleEnvFileError(debugModeEnvVarPath) shared.EchoSectionDivider("End Processing - parseDebugModeSettings") @@ -167,40 +127,34 @@ func handleEnvFileError(filename string) { } } -func Configmapparser() { - setConfigFileVersionEnv() - setConfigSchemaVersionEnv() - - var metricsConfigBySection map[string]map[string]string - var err error - if os.Getenv("AZMON_AGENT_CFG_SCHEMA_VERSION") == "v2" { - filePaths := []string{"/etc/config/settings/cluster-metrics", "/etc/config/settings/prometheus-collector-settings"} - metricsConfigBySection, err = shared.ParseMetricsFiles(filePaths) - if err != nil { - log.Printf("Using defaults as error parsing files: %v\n", err) - } - } else if os.Getenv("AZMON_AGENT_CFG_SCHEMA_VERSION") == "v1" { - configDir := "/etc/config/settings" - metricsConfigBySection, err = shared.ParseV1Config(configDir) - if err != nil { - log.Printf("Using defaults as error parsing config: %v\n", err) - } - } else { - log.Println("Invalid schema version. Using defaults.") +func processConfigFiles() { + schemaVersion := cmcommon.SetEnvFromFile(schemaVersionFile, "AZMON_AGENT_CFG_SCHEMA_VERSION", defaultConfigSchemaVersion) + _ = cmcommon.SetEnvFromFile(configVersionFile, "AZMON_AGENT_CFG_FILE_VERSION", defaultConfigFileVersion) + + metricsConfigBySection, err := cmcommon.LoadMetricsConfiguration( + schemaVersion, + []string{configSettingsPrefix + "cluster-metrics", configSettingsPrefix + "prometheus-collector-settings"}, + configSettingsPrefix, + ) + if err != nil { + log.Printf("Error parsing config: %v\n", err) + return } + parsedSchema := shared.ParseSchemaVersion(schemaVersion) + // Detect configmap presence and set CONFIGMAP_VERSION configmapVer := "not_present" - if os.Getenv("AZMON_AGENT_CFG_SCHEMA_VERSION") == "v2" { - configmapVer = "v2" - } else if os.Getenv("AZMON_AGENT_CFG_SCHEMA_VERSION") == "v1" { - files, err := os.ReadDir("/etc/config/settings") + if parsedSchema == shared.SchemaVersion.V2 { + configmapVer = shared.SchemaVersion.V2 + } else if parsedSchema == shared.SchemaVersion.V1 { + files, err := os.ReadDir(configSettingsPrefix) if err == nil { for _, file := range files { if file.IsDir() || strings.HasPrefix(file.Name(), ".") { continue } - configmapVer = "v1" + configmapVer = shared.SchemaVersion.V1 break } } @@ -209,13 +163,13 @@ func Configmapparser() { parseSettingsForPodAnnotations(metricsConfigBySection) parsePrometheusCollectorConfig(metricsConfigBySection) - parseDefaultScrapeSettings(metricsConfigBySection) + parseDefaultScrapeSettings(metricsConfigBySection, parsedSchema) parseDebugModeSettings(metricsConfigBySection) parseOpentelemetryMetricsSettings(metricsConfigBySection) parseKSMSettings(metricsConfigBySection) - tomlparserTargetsMetricsKeepList(metricsConfigBySection) - tomlparserScrapeInterval(metricsConfigBySection) + tomlparserTargetsMetricsKeepList(metricsConfigBySection, parsedSchema) + tomlparserScrapeInterval(metricsConfigBySection, parsedSchema) azmonOperatorEnabled := os.Getenv("AZMON_OPERATOR_ENABLED") containerType := os.Getenv("CONTAINER_TYPE") @@ -228,6 +182,11 @@ func Configmapparser() { shared.SetEnvAndSourceBashrcOrPowershell("AZMON_INVALID_CUSTOM_PROMETHEUS_CONFIG", "false", true) shared.SetEnvAndSourceBashrcOrPowershell("CONFIG_VALIDATOR_RUNNING_IN_AGENT", "true", true) +} + +func Configmapparser() { + + processConfigFiles() // Running promconfigvalidator if promMergedConfig.yml exists if shared.FileExists("/opt/promMergedConfig.yml") { diff --git a/otelcollector/shared/configmap/mp/configmapparser_test.go b/otelcollector/shared/configmap/mp/configmapparser_test.go index e82bf0204..2252123fc 100644 --- a/otelcollector/shared/configmap/mp/configmapparser_test.go +++ b/otelcollector/shared/configmap/mp/configmapparser_test.go @@ -2,11 +2,13 @@ package configmapsettings import ( "fmt" - "io/ioutil" "os" + "sort" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "github.com/prometheus-collector/shared" + "github.com/prometheus-collector/shared/configmap/common/testhelpers" "gopkg.in/yaml.v2" ) @@ -15,337 +17,281 @@ import ( * 1) Test that the settings from the configmaps are correctly parsed and set to environment variables. * 2) Test that the Prometheus config created is as expected for the settings given. */ -var _ = Describe("Configmapparser", Ordered, func() { + +// PlatformConfig represents a platform/controller type combination +type PlatformConfig struct { + ControllerType string + OSType string + Name string +} + +// TestScenario defines a complete test scenario with setup and expectations +type TestScenario struct { + Name string + Description string + UseConfigFiles bool + IsDefaultConfig bool + ConfigMapMountPath string + ExtraEnvVars map[string]string + KeepListRegex string + ScrapeInterval string + MinimalIngestion *bool // nil means use default + SchemaVersion string + ConfigVersion string + ConfigMapContents map[string]string + ExpectedConfigPaths map[string]string // platform name -> expected config file path + ExpectedMergedConfigPaths map[string]string // platform name -> expected merged config file path +} + +// Platform definitions for reuse across tests +var ( + LinuxReplicaSet = PlatformConfig{ + ControllerType: shared.ControllerType.ConfigReaderSidecar, + OSType: shared.OSType.Linux, + Name: "Linux ReplicaSet", + } + LinuxDaemonSet = PlatformConfig{ + ControllerType: shared.ControllerType.DaemonSet, + OSType: shared.OSType.Linux, + Name: "Linux DaemonSet", + } + WindowsDaemonSet = PlatformConfig{ + ControllerType: shared.ControllerType.DaemonSet, + OSType: shared.OSType.Windows, + Name: "Windows DaemonSet", + } + + AllPlatforms = []PlatformConfig{LinuxReplicaSet, LinuxDaemonSet, WindowsDaemonSet} +) + +func setupTest() { + var originalDefaultScrapeJobs map[string]shared.DefaultScrapeJob + BeforeEach(func() { + testhelpers.UnsetEnvVars(testhelpers.DefaultCollectorEnvVarKeys()) + configSettingsPrefix = "/tmp/settings/" + configMapParserPrefix = "/tmp/configmapparser/" + configMapMountPath = "" + os.RemoveAll(configSettingsPrefix) + os.RemoveAll(configMapParserPrefix) + _ = os.MkdirAll(configSettingsPrefix, 0755) + // Save a copy of the original DefaultScrapeJobs for restoring later + originalDefaultScrapeJobs = make(map[string]shared.DefaultScrapeJob) + for key, job := range shared.DefaultScrapeJobs { + originalDefaultScrapeJobs[key] = *job + } + }) AfterEach(func() { - cleanupEnvVars() + testhelpers.UnsetEnvVars(testhelpers.DefaultCollectorEnvVarKeys()) + // Remove any temporary files created during the tests + os.RemoveAll(configSettingsPrefix) + os.RemoveAll(configMapParserPrefix) + // Restore the original DefaultScrapeJobs + for key, job := range originalDefaultScrapeJobs { + shared.DefaultScrapeJobs[key] = &job + } + os.RemoveAll("../../../configmapparser/default-prom-configs/test/") }) +} - Context("when the settings configmap does not exist", func() { - AfterEach(func() { - cleanupEnvVars() - }) +func setupConfigFiles(defaultPath bool) { + prefixes := testhelpers.CollectorPrefixesFor(configSettingsPrefix, configMapParserPrefix, true) + paths := testhelpers.CollectorConfigPaths{ + ConfigMapDebugMountPath: &configMapDebugMountPath, + ReplicaSetCollectorConfig: &replicaSetCollectorConfig, + DefaultSettingsMountPath: &defaultSettingsMountPath, + ConfigMapMountPathForPodAnnotation: &configMapMountPathForPodAnnotation, + CollectorSettingsMountPath: &collectorSettingsMountPath, + ConfigMapKeepListMountPath: &configMapKeepListMountPath, + ConfigMapScrapeIntervalMountPath: &configMapScrapeIntervalMountPath, + ConfigMapOpentelemetryMetricsPath: &configMapOpentelemetryMetricsMountPath, + } - It("should process the config with defaults for the Linux ReplicaSet", func() { - setEnvVars(map[string]string { - "AZMON_OPERATOR_ENABLED": "true", - "CONTAINER_TYPE": "ConfigReaderSidecar", - "CONTROLLER_TYPE": "ReplicaSet", - "OS_TYPE": "linux", - "MODE": "advanced", - "KUBE_STATE_NAME": "ama-metrics-ksm", - "POD_NAMESPACE": "kube-system", - "MAC": "true", - }) - setupConfigFiles(true) - setupProcessedFiles() + if err := testhelpers.SetupCollectorConfigFiles(defaultPath, prefixes, paths); err != nil { + panic(err) + } +} - expectedContentsFilePath := "./testdata/default-linux-rs.yaml" +func setupProcessedFiles() { + prefixes := testhelpers.CollectorPrefixesFor(configSettingsPrefix, configMapParserPrefix, true) + paths := testhelpers.CollectorProcessedPaths{ + PodAnnotationEnvVarPath: &podAnnotationEnvVarPath, + CollectorSettingsEnvVarPath: &collectorSettingsEnvVarPath, + DefaultSettingsEnvVarPath: &defaultSettingsEnvVarPath, + DebugModeEnvVarPath: &debugModeEnvVarPath, + ConfigMapKeepListEnvVarPath: &configMapKeepListEnvVarPath, + ScrapeIntervalEnvVarPath: &scrapeIntervalEnvVarPath, + OpentelemetryMetricsEnvVarPath: &opentelemetryMetricsEnvVarPath, + KsmConfigEnvVarPath: &ksmConfigEnvVarPath, + ScrapeConfigDefinitionPathPrefix: &scrapeConfigDefinitionPathPrefix, + MergedDefaultConfigPath: &mergedDefaultConfigPath, + PromMergedConfigPath: &promMergedConfigPath, + RegexHashFile: ®exHashFile, + IntervalHashFile: &intervalHashFile, + } - Configmapparser() - - envVars := map[string]string { - "AZMON_AGENT_CFG_SCHEMA_VERSION": "v1", - "AZMON_AGENT_CFG_FILE_VERSION": "ver1", - "AZMON_PROMETHEUS_POD_ANNOTATION_NAMESPACES_REGEX": "", - "AZMON_DEFAULT_METRIC_ACCOUNT_NAME": "", - "AZMON_CLUSTER_LABEL": "", - "AZMON_CLUSTER_ALIAS": "", - "AZMON_OPERATOR_ENABLED_CHART_SETTING": "false", - "AZMON_OPERATOR_ENABLED": "true", - "AZMON_OPERATOR_ENABLED_CFG_MAP_SETTING": "", - "AZMON_PROMETHEUS_KUBELET_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_COREDNS_SCRAPING_ENABLED": "false", - "AZMON_PROMETHEUS_CADVISOR_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_KUBEPROXY_SCRAPING_ENABLED": "false", - "AZMON_PROMETHEUS_APISERVER_SCRAPING_ENABLED": "false", - "AZMON_PROMETHEUS_KUBESTATE_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_NODEEXPORTER_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_COLLECTOR_HEALTH_SCRAPING_ENABLED": "false", - "AZMON_PROMETHEUS_POD_ANNOTATION_SCRAPING_ENABLED": "", - "AZMON_PROMETHEUS_WINDOWSEXPORTER_SCRAPING_ENABLED": "false", - "AZMON_PROMETHEUS_WINDOWSKUBEPROXY_SCRAPING_ENABLED": "false", - "AZMON_PROMETHEUS_KAPPIEBASIC_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_NETWORKOBSERVABILITYRETINA_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_NETWORKOBSERVABILITYHUBBLE_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_NETWORKOBSERVABILITYCILIUM_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "false", - "DEBUG_MODE_ENABLED": "", - "AZMON_INVALID_CUSTOM_PROMETHEUS_CONFIG": "false", - "CONFIG_VALIDATOR_RUNNING_IN_AGENT": "true", - "AZMON_USE_DEFAULT_PROMETHEUS_CONFIG": "true", - } - err := checkEnvVars(envVars) - Expect(err).NotTo(HaveOccurred()) - - checkHashMaps(configMapKeepListEnvVarPath, map[string]string { - "KUBELET_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",kubeletRegex_minimal_mac), - "COREDNS_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",coreDNSRegex_minimal_mac), - "CADVISOR_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",cadvisorRegex_minimal_mac), - "KUBEPROXY_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",kubeproxyRegex_minimal_mac), - "APISERVER_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",apiserverRegex_minimal_mac), - "KUBESTATE_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",kubestateRegex_minimal_mac), - "NODEEXPORTER_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",nodeexporterRegex_minimal_mac), - "WINDOWSEXPORTER_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",windowsexporterRegex_minimal_mac), - "WINDOWSKUBEPROXY_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",windowskubeproxyRegex_minimal_mac), - "POD_ANNOTATION_METRICS_KEEP_LIST_REGEX": "", - "KAPPIEBASIC_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",kappiebasicRegex_minimal_mac), - "NETWORKOBSERVABILITYRETINA_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",networkobservabilityRetinaRegex_minimal_mac), - "NETWORKOBSERVABILITYHUBBLE_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",networkobservabilityHubbleRegex_minimal_mac), - "NETWORKOBSERVABILITYCILIUM_METRICS_KEEP_LIST_REGEX": "", - }) + if err := testhelpers.SetupCollectorProcessedFiles(prefixes, paths); err != nil { + panic(err) + } +} - checkHashMaps(scrapeIntervalEnvVarPath, map[string]string { - "KUBELET_SCRAPE_INTERVAL": "30s", - "COREDNS_SCRAPE_INTERVAL": "30s", - "CADVISOR_SCRAPE_INTERVAL": "30s", - "KUBEPROXY_SCRAPE_INTERVAL": "30s", - "APISERVER_SCRAPE_INTERVAL": "30s", - "KUBESTATE_SCRAPE_INTERVAL": "30s", - "NODEEXPORTER_SCRAPE_INTERVAL": "30s", - "WINDOWSEXPORTER_SCRAPE_INTERVAL": "30s", - "WINDOWSKUBEPROXY_SCRAPE_INTERVAL": "30s", - "PROMETHEUS_COLLECTOR_HEALTH_SCRAPE_INTERVAL": "30s", - "POD_ANNOTATION_SCRAPE_INTERVAL": "30s", - "KAPPIEBASIC_SCRAPE_INTERVAL": "30s", - "NETWORKOBSERVABILITYRETINA_SCRAPE_INTERVAL": "30s", - "NETWORKOBSERVABILITYHUBBLE_SCRAPE_INTERVAL": "30s", - "NETWORKOBSERVABILITYCILIUM_SCRAPE_INTERVAL": "30s", - }) +var _ = Describe("Configmapparser", Ordered, func() { + setupTest() - mergedFileContents, err := ioutil.ReadFile(mergedDefaultConfigPath) - Expect(err).NotTo(HaveOccurred()) - expectedFileContents, err := ioutil.ReadFile(expectedContentsFilePath) - Expect(err).NotTo(HaveOccurred()) - Expect(string(mergedFileContents)).To(Equal(string(expectedFileContents))) + Context("when the settings configmap does not exist", func() { + var expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap map[string]string + var isDefaultConfig, useConfigFiles bool + BeforeEach(func() { + expectedEnvVars = testhelpers.DefaultManagedPrometheusEnvVars() + expectedKeepListHashMap = testhelpers.ExpectedKeepListMap(shared.DefaultScrapeJobs, true, "", true) + expectedScrapeIntervalHashMap = testhelpers.ExpectedScrapeIntervalMap(shared.DefaultScrapeJobs, "") + isDefaultConfig = true + useConfigFiles = false + }) + + It("should process the config with defaults for the Linux ReplicaSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.ConfigReaderSidecar, shared.OSType.Linux)).To(Succeed()) + expectedContentsFilePath := "./testdata/default-linux-rs.yaml" + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "") }) It("should process the config with defaults for the Linux DaemonSet", func() { - setEnvVars(map[string]string { - "AZMON_OPERATOR_ENABLED": "true", - "CONTAINER_TYPE": "", - "CONTROLLER_TYPE": "DaemonSet", - "OS_TYPE": "linux", - "MODE": "advanced", - "KUBE_STATE_NAME": "ama-metrics-ksm", - "POD_NAMESPACE": "kube-system", - "MAC": "true", - }) - setupConfigFiles(true) - setupProcessedFiles() + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Linux)).To(Succeed()) expectedContentsFilePath := "./testdata/default-linux-ds.yaml" - - Configmapparser() - - envVars := map[string]string { - "AZMON_AGENT_CFG_SCHEMA_VERSION": "v1", - "AZMON_AGENT_CFG_FILE_VERSION": "ver1", - "AZMON_PROMETHEUS_POD_ANNOTATION_NAMESPACES_REGEX": "", - "AZMON_DEFAULT_METRIC_ACCOUNT_NAME": "", - "AZMON_CLUSTER_LABEL": "", - "AZMON_CLUSTER_ALIAS": "", - "AZMON_OPERATOR_ENABLED_CHART_SETTING": "false", - "AZMON_OPERATOR_ENABLED": "true", - "AZMON_OPERATOR_ENABLED_CFG_MAP_SETTING": "", - "AZMON_PROMETHEUS_KUBELET_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_COREDNS_SCRAPING_ENABLED": "false", - "AZMON_PROMETHEUS_CADVISOR_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_KUBEPROXY_SCRAPING_ENABLED": "false", - "AZMON_PROMETHEUS_APISERVER_SCRAPING_ENABLED": "false", - "AZMON_PROMETHEUS_KUBESTATE_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_NODEEXPORTER_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_COLLECTOR_HEALTH_SCRAPING_ENABLED": "false", - "AZMON_PROMETHEUS_POD_ANNOTATION_SCRAPING_ENABLED": "", - "AZMON_PROMETHEUS_WINDOWSEXPORTER_SCRAPING_ENABLED": "false", - "AZMON_PROMETHEUS_WINDOWSKUBEPROXY_SCRAPING_ENABLED": "false", - "AZMON_PROMETHEUS_KAPPIEBASIC_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_NETWORKOBSERVABILITYRETINA_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_NETWORKOBSERVABILITYHUBBLE_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_NETWORKOBSERVABILITYCILIUM_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "false", - "DEBUG_MODE_ENABLED": "", - "AZMON_INVALID_CUSTOM_PROMETHEUS_CONFIG": "false", - "CONFIG_VALIDATOR_RUNNING_IN_AGENT": "true", - "AZMON_USE_DEFAULT_PROMETHEUS_CONFIG": "true", - } - err := checkEnvVars(envVars) - Expect(err).NotTo(HaveOccurred()) - - checkHashMaps(configMapKeepListEnvVarPath, map[string]string { - "KUBELET_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",kubeletRegex_minimal_mac), - "COREDNS_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",coreDNSRegex_minimal_mac), - "CADVISOR_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",cadvisorRegex_minimal_mac), - "KUBEPROXY_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",kubeproxyRegex_minimal_mac), - "APISERVER_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",apiserverRegex_minimal_mac), - "KUBESTATE_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",kubestateRegex_minimal_mac), - "NODEEXPORTER_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",nodeexporterRegex_minimal_mac), - "WINDOWSEXPORTER_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",windowsexporterRegex_minimal_mac), - "WINDOWSKUBEPROXY_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",windowskubeproxyRegex_minimal_mac), - "POD_ANNOTATION_METRICS_KEEP_LIST_REGEX": "", - "KAPPIEBASIC_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",kappiebasicRegex_minimal_mac), - "NETWORKOBSERVABILITYRETINA_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",networkobservabilityRetinaRegex_minimal_mac), - "NETWORKOBSERVABILITYHUBBLE_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",networkobservabilityHubbleRegex_minimal_mac), - "NETWORKOBSERVABILITYCILIUM_METRICS_KEEP_LIST_REGEX": "", - }) - - checkHashMaps(scrapeIntervalEnvVarPath, map[string]string { - "KUBELET_SCRAPE_INTERVAL": "30s", - "COREDNS_SCRAPE_INTERVAL": "30s", - "CADVISOR_SCRAPE_INTERVAL": "30s", - "KUBEPROXY_SCRAPE_INTERVAL": "30s", - "APISERVER_SCRAPE_INTERVAL": "30s", - "KUBESTATE_SCRAPE_INTERVAL": "30s", - "NODEEXPORTER_SCRAPE_INTERVAL": "30s", - "WINDOWSEXPORTER_SCRAPE_INTERVAL": "30s", - "WINDOWSKUBEPROXY_SCRAPE_INTERVAL": "30s", - "PROMETHEUS_COLLECTOR_HEALTH_SCRAPE_INTERVAL": "30s", - "POD_ANNOTATION_SCRAPE_INTERVAL": "30s", - "KAPPIEBASIC_SCRAPE_INTERVAL": "30s", - "NETWORKOBSERVABILITYRETINA_SCRAPE_INTERVAL": "30s", - "NETWORKOBSERVABILITYHUBBLE_SCRAPE_INTERVAL": "30s", - "NETWORKOBSERVABILITYCILIUM_SCRAPE_INTERVAL": "30s", - }) - - mergedFileContents, err := ioutil.ReadFile(mergedDefaultConfigPath) - Expect(err).NotTo(HaveOccurred()) - expectedFileContents, err := ioutil.ReadFile(expectedContentsFilePath) - Expect(err).NotTo(HaveOccurred()) - Expect(string(mergedFileContents)).To(Equal(string(expectedFileContents))) + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "") }) It("should process the config with defaults for the Windows DaemonSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Windows)).To(Succeed()) + extraEnvVars := map[string]string{ + "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "true", + } + for key, value := range extraEnvVars { + expectedEnvVars[key] = value + } + expectedContentsFilePath := "./testdata/no-scrape-jobs-linux-rs.yaml" + + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "") }) }) - Context("when the settings configmap sections exist but are empty", func() { - AfterEach(func() { - cleanupEnvVars() + var expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap map[string]string + var isDefaultConfig, useConfigFiles bool + BeforeEach(func() { + expectedKeepListHashMap = testhelpers.ExpectedKeepListMap(shared.DefaultScrapeJobs, true, "", true) + expectedScrapeIntervalHashMap = testhelpers.ExpectedScrapeIntervalMap(shared.DefaultScrapeJobs, "") + isDefaultConfig = true + useConfigFiles = true }) - It("should process the config with defaults for the Linux ReplicaSet", func() { - setEnvVars(map[string]string { - "AZMON_OPERATOR_ENABLED": "true", - "CONTAINER_TYPE": "ConfigReaderSidecar", - "CONTROLLER_TYPE": "ReplicaSet", - "OS_TYPE": "linux", - "MODE": "advanced", - "KUBE_STATE_NAME": "ama-metrics-ksm", - "POD_NAMESPACE": "kube-system", - "MAC": "true", - }) - setupConfigFiles(false) - setupProcessedFiles() - - fmt.Println("testing replicaset defaults empty") - - Configmapparser() - - envVars := map[string]string { - "AZMON_AGENT_CFG_SCHEMA_VERSION": "v1", - "AZMON_AGENT_CFG_FILE_VERSION": "ver1", - "AZMON_PROMETHEUS_POD_ANNOTATION_NAMESPACES_REGEX": "", - "AZMON_DEFAULT_METRIC_ACCOUNT_NAME": "", - "AZMON_CLUSTER_LABEL": "", - "AZMON_CLUSTER_ALIAS": "", - "AZMON_OPERATOR_ENABLED_CHART_SETTING": "false", - "AZMON_OPERATOR_ENABLED": "true", - "AZMON_OPERATOR_ENABLED_CFG_MAP_SETTING": "", - "AZMON_PROMETHEUS_KUBELET_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_COREDNS_SCRAPING_ENABLED": "false", - "AZMON_PROMETHEUS_CADVISOR_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_KUBEPROXY_SCRAPING_ENABLED": "false", - "AZMON_PROMETHEUS_APISERVER_SCRAPING_ENABLED": "false", - "AZMON_PROMETHEUS_KUBESTATE_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_NODEEXPORTER_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_COLLECTOR_HEALTH_SCRAPING_ENABLED": "false", - "AZMON_PROMETHEUS_POD_ANNOTATION_SCRAPING_ENABLED": "", - "AZMON_PROMETHEUS_WINDOWSEXPORTER_SCRAPING_ENABLED": "false", - "AZMON_PROMETHEUS_WINDOWSKUBEPROXY_SCRAPING_ENABLED": "false", - "AZMON_PROMETHEUS_KAPPIEBASIC_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_NETWORKOBSERVABILITYRETINA_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_NETWORKOBSERVABILITYHUBBLE_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_NETWORKOBSERVABILITYCILIUM_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "false", - "DEBUG_MODE_ENABLED": "false", - "AZMON_INVALID_CUSTOM_PROMETHEUS_CONFIG": "false", - "CONFIG_VALIDATOR_RUNNING_IN_AGENT": "true", - "AZMON_USE_DEFAULT_PROMETHEUS_CONFIG": "true", - } - err := checkEnvVars(envVars) - Expect(err).NotTo(HaveOccurred()) - - checkHashMaps(configMapKeepListEnvVarPath, map[string]string { - "KUBELET_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",kubeletRegex_minimal_mac), - "COREDNS_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",coreDNSRegex_minimal_mac), - "CADVISOR_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",cadvisorRegex_minimal_mac), - "KUBEPROXY_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",kubeproxyRegex_minimal_mac), - "APISERVER_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",apiserverRegex_minimal_mac), - "KUBESTATE_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",kubestateRegex_minimal_mac), - "NODEEXPORTER_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",nodeexporterRegex_minimal_mac), - "WINDOWSEXPORTER_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",windowsexporterRegex_minimal_mac), - "WINDOWSKUBEPROXY_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",windowskubeproxyRegex_minimal_mac), - "POD_ANNOTATION_METRICS_KEEP_LIST_REGEX": "", - "KAPPIEBASIC_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",kappiebasicRegex_minimal_mac), - "NETWORKOBSERVABILITYRETINA_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",networkobservabilityRetinaRegex_minimal_mac), - "NETWORKOBSERVABILITYHUBBLE_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("|%s",networkobservabilityHubbleRegex_minimal_mac), - "NETWORKOBSERVABILITYCILIUM_METRICS_KEEP_LIST_REGEX": "", - }) - - checkHashMaps(scrapeIntervalEnvVarPath, map[string]string { - "KUBELET_SCRAPE_INTERVAL": "30s", - "COREDNS_SCRAPE_INTERVAL": "30s", - "CADVISOR_SCRAPE_INTERVAL": "30s", - "KUBEPROXY_SCRAPE_INTERVAL": "30s", - "APISERVER_SCRAPE_INTERVAL": "30s", - "KUBESTATE_SCRAPE_INTERVAL": "30s", - "NODEEXPORTER_SCRAPE_INTERVAL": "30s", - "WINDOWSEXPORTER_SCRAPE_INTERVAL": "30s", - "WINDOWSKUBEPROXY_SCRAPE_INTERVAL": "30s", - "PROMETHEUS_COLLECTOR_HEALTH_SCRAPE_INTERVAL": "30s", - "POD_ANNOTATION_SCRAPE_INTERVAL": "30s", - "KAPPIEBASIC_SCRAPE_INTERVAL": "30s", - "NETWORKOBSERVABILITYRETINA_SCRAPE_INTERVAL": "30s", - "NETWORKOBSERVABILITYHUBBLE_SCRAPE_INTERVAL": "30s", - "NETWORKOBSERVABILITYCILIUM_SCRAPE_INTERVAL": "30s", - }) - - mergedFileContents, err := ioutil.ReadFile(mergedDefaultConfigPath) - Expect(err).NotTo(HaveOccurred()) - expectedFileContents, err := ioutil.ReadFile("./testdata/default-linux-rs.yaml") - Expect(err).NotTo(HaveOccurred()) - Expect(string(mergedFileContents)).To(Equal(string(expectedFileContents))) + expectedEnvVars = testhelpers.DefaultManagedPrometheusEnvVars() + extraEnvVars := map[string]string{ + "CONFIGMAP_VERSION": "v1", + } + for key, value := range extraEnvVars { + expectedEnvVars[key] = value + } + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.ConfigReaderSidecar, shared.OSType.Linux)).To(Succeed()) + expectedContentsFilePath := "./testdata/default-linux-rs.yaml" + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "") }) It("should process the config with defaults for the Linux DaemonSet", func() { - + expectedEnvVars = testhelpers.DefaultManagedPrometheusEnvVars() + extraEnvVars := map[string]string{ + "CONFIGMAP_VERSION": "v1", + } + for key, value := range extraEnvVars { + expectedEnvVars[key] = value + } + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Linux)).To(Succeed()) + expectedContentsFilePath := "./testdata/default-linux-ds.yaml" + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "") }) It("should process the config with defaults for the Windows DaemonSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Windows)).To(Succeed()) + + expectedEnvVars = testhelpers.DefaultManagedPrometheusEnvVars() + extraEnvVars := map[string]string{ + "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "true", + "CONFIGMAP_VERSION": "v1", + } + for key, value := range extraEnvVars { + expectedEnvVars[key] = value + } + expectedContentsFilePath := "./testdata/no-scrape-jobs-linux-rs.yaml" + isDefaultConfig := true + + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "") }) }) Context("when the settings configmap sections exist and are not default", func() { - AfterEach(func() { - cleanupEnvVars() - }) + var expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, extraEnvVars map[string]string + var isDefaultConfig, useConfigFiles bool + BeforeEach(func() { + expectedEnvVars = testhelpers.DefaultManagedPrometheusEnvVars() + extraEnvVars = map[string]string{ + "AZMON_AGENT_CFG_SCHEMA_VERSION": "v1", + "AZMON_AGENT_CFG_FILE_VERSION": "ver1", + "AZMON_PROMETHEUS_POD_ANNOTATION_NAMESPACES_REGEX": "'.*|value'", + "AZMON_CLUSTER_LABEL": "alias", + "AZMON_CLUSTER_ALIAS": "alias", + "AZMON_OPERATOR_ENABLED_CHART_SETTING": "true", + "AZMON_PROMETHEUS_POD_ANNOTATION_SCRAPING_ENABLED": "true", + "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "false", + "DEBUG_MODE_ENABLED": "true", + "AZMON_KSM_CONFIG_ENABLED": "true", + "CONFIGMAP_VERSION": "v1", + } - It("should process the config for the Linux ReplicaSet", func() { - setEnvVars(map[string]string { - "AZMON_OPERATOR_ENABLED": "true", - "CONTAINER_TYPE": "ConfigReaderSidecar", - "CONTROLLER_TYPE": "ReplicaSet", - "OS_TYPE": "linux", - "MODE": "advanced", - "KUBE_STATE_NAME": "ama-metrics-ksm", - "POD_NAMESPACE": "kube-system", - "MAC": "true", + scrapeOverrides := testhelpers.CloneJobEnabledStates(shared.DefaultScrapeJobs) + for _, job := range []string{ + "podannotations", + "kubelet", + "coredns", + "cadvisor", + "kubeproxy", + "apiserver", + "kubestate", + "nodeexporter", + "windowsexporter", + "windowskubeproxy", + "kappiebasic", + "networkobservabilityRetina", + "networkobservabilityHubble", + "networkobservabilityCilium", + "acstor-capacity-provisioner", + "local-csi-driver", + "acstor-metrics-exporter", + "dcgmexporter", + "prometheuscollectorhealth", + } { + scrapeOverrides[job] = true + } + + overrides := testhelpers.BuildEnvVarOverrides(scrapeOverrides, func(jobName string) string { + return testhelpers.BuildEnvVarName(jobName, "_SCRAPING_ENABLED") }) + for key, value := range overrides { + extraEnvVars[key] = value + } - schemaVersionFile = createTempFile("schema-version", "v1") - configVersionFile = createTempFile("config-version", "ver1") - configMapMountPathForPodAnnotation = createTempFile("podannotation", `podannotationnamespaceregex = ".*|value"`) - collectorSettingsMountPath = createTempFile("collector-settings", `cluster_alias = "alias"`) - defaultSettingsMountPath = createTempFile("default-settings", ` + for k, v := range extraEnvVars { + expectedEnvVars[k] = v + } + + expectedKeepListHashMap = testhelpers.ExpectedKeepListMap(shared.DefaultScrapeJobs, true, "test.*|test2", true) + expectedScrapeIntervalHashMap = testhelpers.ExpectedScrapeIntervalMap(shared.DefaultScrapeJobs, "15s") + + schemaVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "schema-version", "v1") + configVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "config-version", "ver1") + configMapMountPathForPodAnnotation = testhelpers.MustCreateTempFile(configSettingsPrefix, "pod-annotation-based-scraping", `podannotationnamespaceregex = ".*|value"`) + collectorSettingsMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "prometheus-collector-settings", `cluster_alias = "alias"`) + ksmConfigYaml := "resources:\n secrets: {}\n configmaps: {}\nlabels_allow_list:\n pods:\n - app8\nannotations_allow_list:\n namespaces:\n - kube-system\n - default\n" + _ = testhelpers.MustCreateTempFile(configSettingsPrefix, "ksm-config", ksmConfigYaml) + defaultSettingsMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "default-scrape-settings-enabled", ` kubelet = true coredns = true cadvisor = true @@ -359,10 +305,14 @@ var _ = Describe("Configmapparser", Ordered, func() { networkobservabilityRetina = true networkobservabilityHubble = true networkobservabilityCilium = true + acstor-capacity-provisioner = true + local-csi-driver = true + acstor-metrics-exporter = true + dcgmexporter = true prometheuscollectorhealth = true `) - configMapDebugMountPath = createTempFile("debug-mode", `enabled = true`) - configMapKeepListMountPath = createTempFile("keep-list", ` + configMapDebugMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "debug-mode", `enabled = true`) + configMapKeepListMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "default-targets-metrics-keep-list", ` kubelet = "test.*|test2" coredns = "test.*|test2" cadvisor = "test.*|test2" @@ -377,9 +327,17 @@ var _ = Describe("Configmapparser", Ordered, func() { networkobservabilityRetina = "test.*|test2" networkobservabilityHubble = "test.*|test2" networkobservabilityCilium = "test.*|test2" + acstor-capacity-provisioner = "test.*|test2" + local-csi-driver = "test.*|test2" + acstor-metrics-exporter = "test.*|test2" + dcgmexporter = "test.*|test2" + prometheuscollectorhealth = "test.*|test2" + ztunnel = "test.*|test2" + istio-cni = "test.*|test2" + waypoint-proxy = "test.*|test2" minimalingestionprofile = true `) - configMapScrapeIntervalMountPath = createTempFile("scrape-interval", ` + configMapScrapeIntervalMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "default-targets-scrape-interval-settings", ` kubelet = "15s" coredns = "15s" cadvisor = "15s" @@ -395,115 +353,225 @@ var _ = Describe("Configmapparser", Ordered, func() { networkobservabilityCilium = "15s" prometheuscollectorhealth = "15s" podannotations = "15s" + acstor-capacity-provisioner = "15s" + local-csi-driver = "15s" + acstor-metrics-exporter = "15s" + dcgmexporter = "15s" + ztunnel = "15s" + istio-cni = "15s" + waypoint-proxy = "15s" `) + isDefaultConfig = false + useConfigFiles = false + }) - setupProcessedFiles() - - Configmapparser() + It("should process the config for the Linux ReplicaSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.ConfigReaderSidecar, shared.OSType.Linux)).To(Succeed()) + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, "./testdata/advanced-linux-rs.yaml", "") + }) - envVars := map[string]string { - "AZMON_AGENT_CFG_SCHEMA_VERSION": "v1", - "AZMON_AGENT_CFG_FILE_VERSION": "ver1", - "AZMON_PROMETHEUS_POD_ANNOTATION_NAMESPACES_REGEX": "'.*|value'", - "AZMON_DEFAULT_METRIC_ACCOUNT_NAME": "", - "AZMON_CLUSTER_LABEL": "alias", - "AZMON_CLUSTER_ALIAS": "alias", - "AZMON_OPERATOR_ENABLED_CHART_SETTING": "true", - "AZMON_OPERATOR_ENABLED": "true", - "AZMON_OPERATOR_ENABLED_CFG_MAP_SETTING": "", - "AZMON_PROMETHEUS_KUBELET_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_COREDNS_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_CADVISOR_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_KUBEPROXY_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_APISERVER_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_KUBESTATE_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_NODEEXPORTER_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_COLLECTOR_HEALTH_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_POD_ANNOTATION_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_WINDOWSEXPORTER_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_WINDOWSKUBEPROXY_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_KAPPIEBASIC_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_NETWORKOBSERVABILITYRETINA_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_NETWORKOBSERVABILITYHUBBLE_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_NETWORKOBSERVABILITYCILIUM_SCRAPING_ENABLED": "true", - "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "false", - //"DEBUG_MODE_ENABLED": "true", - "AZMON_INVALID_CUSTOM_PROMETHEUS_CONFIG": "false", - "CONFIG_VALIDATOR_RUNNING_IN_AGENT": "true", - "AZMON_USE_DEFAULT_PROMETHEUS_CONFIG": "true", - } - err := checkEnvVars(envVars) - Expect(err).NotTo(HaveOccurred()) - - checkHashMaps(configMapKeepListEnvVarPath, map[string]string { - "KUBELET_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("test.*|test2|%s",kubeletRegex_minimal_mac), - "COREDNS_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("test.*|test2|%s",coreDNSRegex_minimal_mac), - "CADVISOR_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("test.*|test2|%s",cadvisorRegex_minimal_mac), - "KUBEPROXY_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("test.*|test2|%s",kubeproxyRegex_minimal_mac), - "APISERVER_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("test.*|test2|%s",apiserverRegex_minimal_mac), - "KUBESTATE_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("test.*|test2|%s",kubestateRegex_minimal_mac), - "NODEEXPORTER_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("test.*|test2|%s",nodeexporterRegex_minimal_mac), - "WINDOWSEXPORTER_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("test.*|test2|%s",windowsexporterRegex_minimal_mac), - "WINDOWSKUBEPROXY_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("test.*|test2|%s",windowskubeproxyRegex_minimal_mac), - "POD_ANNOTATION_METRICS_KEEP_LIST_REGEX": "test.*|test2", - "KAPPIEBASIC_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("test.*|test2|%s",kappiebasicRegex_minimal_mac), - "NETWORKOBSERVABILITYRETINA_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("test.*|test2|%s",networkobservabilityRetinaRegex_minimal_mac), - "NETWORKOBSERVABILITYHUBBLE_METRICS_KEEP_LIST_REGEX": fmt.Sprintf("test.*|test2|%s",networkobservabilityHubbleRegex_minimal_mac), - "NETWORKOBSERVABILITYCILIUM_METRICS_KEEP_LIST_REGEX": "test.*|test2", - }) + It("should process the config for the Linux Daemonset", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Linux)).To(Succeed()) + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, "./testdata/advanced-linux-ds.yaml", "") + }) - checkHashMaps(scrapeIntervalEnvVarPath, map[string]string { - "KUBELET_SCRAPE_INTERVAL": "15s", - "COREDNS_SCRAPE_INTERVAL": "15s", - "CADVISOR_SCRAPE_INTERVAL": "15s", - "KUBEPROXY_SCRAPE_INTERVAL": "15s", - "APISERVER_SCRAPE_INTERVAL": "15s", - "KUBESTATE_SCRAPE_INTERVAL": "15s", - "NODEEXPORTER_SCRAPE_INTERVAL": "15s", - "WINDOWSEXPORTER_SCRAPE_INTERVAL": "15s", - "WINDOWSKUBEPROXY_SCRAPE_INTERVAL": "15s", - "PROMETHEUS_COLLECTOR_HEALTH_SCRAPE_INTERVAL": "15s", - "POD_ANNOTATION_SCRAPE_INTERVAL": "15s", - "KAPPIEBASIC_SCRAPE_INTERVAL": "15s", - "NETWORKOBSERVABILITYRETINA_SCRAPE_INTERVAL": "15s", - "NETWORKOBSERVABILITYHUBBLE_SCRAPE_INTERVAL": "15s", - "NETWORKOBSERVABILITYCILIUM_SCRAPE_INTERVAL": "15s", - }) + It("should process the config for the Windows Daemonset", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Windows)).To(Succeed()) + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, "./testdata/advanced-windows-ds.yaml", "") }) + }) - It("should process the config for the Linux Daemonset", func() { + Context("when some of the configmap sections exist but not all", func() { + var expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap map[string]string + var isDefaultConfig, useConfigFiles bool + BeforeEach(func() { + expectedEnvVars = testhelpers.DefaultManagedPrometheusEnvVars() + extraEnvVars := map[string]string{ + "AZMON_AGENT_CFG_SCHEMA_VERSION": "v1", + "AZMON_PROMETHEUS_POD_ANNOTATION_NAMESPACES_REGEX": "'.*|value'", + "AZMON_OPERATOR_ENABLED_CHART_SETTING": "true", + "AZMON_PROMETHEUS_POD_ANNOTATION_SCRAPING_ENABLED": "true", + "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "false", + "DEBUG_MODE_ENABLED": "true", + "CONFIGMAP_VERSION": "v1", + } + for key, value := range extraEnvVars { + expectedEnvVars[key] = value + } + expectedEnvVars[testhelpers.BuildEnvVarName("podannotations", "_SCRAPING_ENABLED")] = "true" + expectedKeepListHashMap = testhelpers.ExpectedKeepListMap(shared.DefaultScrapeJobs, true, "test.*|test2", true) + expectedScrapeIntervalHashMap = testhelpers.ExpectedScrapeIntervalMap(shared.DefaultScrapeJobs, "15s") + + schemaVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "schema-version", "v1") + configMapMountPathForPodAnnotation = testhelpers.MustCreateTempFile(configSettingsPrefix, "pod-annotation-based-scraping", `podannotationnamespaceregex = ".*|value"`) + configMapDebugMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "debug-mode", `enabled = true`) + configMapKeepListMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "default-targets-metrics-keep-list", ` + kubelet = "test.*|test2" + coredns = "test.*|test2" + cadvisor = "test.*|test2" + kubeproxy = "test.*|test2" + apiserver = "test.*|test2" + kubestate = "test.*|test2" + nodeexporter = "test.*|test2" + windowsexporter = "test.*|test2" + windowskubeproxy = "test.*|test2" + podannotations = "test.*|test2" + kappiebasic = "test.*|test2" + networkobservabilityRetina = "test.*|test2" + networkobservabilityHubble = "test.*|test2" + networkobservabilityCilium = "test.*|test2" + acstor-capacity-provisioner = "test.*|test2" + local-csi-driver = "test.*|test2" + acstor-metrics-exporter = "test.*|test2" + dcgmexporter = "test.*|test2" + prometheuscollectorhealth = "test.*|test2" + ztunnel = "test.*|test2" + istio-cni = "test.*|test2" + waypoint-proxy = "test.*|test2" + minimalingestionprofile = true + `) + configMapScrapeIntervalMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "default-targets-scrape-interval-settings", ` + kubelet = "15s" + coredns = "15s" + cadvisor = "15s" + kubeproxy = "15s" + apiserver = "15s" + kubestate = "15s" + nodeexporter = "15s" + windowsexporter = "15s" + windowskubeproxy = "15s" + kappiebasic = "15s" + networkobservabilityRetina = "15s" + networkobservabilityHubble = "15s" + networkobservabilityCilium = "15s" + prometheuscollectorhealth = "15s" + podannotations = "15s" + acstor-capacity-provisioner = "15s" + local-csi-driver = "15s" + acstor-metrics-exporter = "15s" + dcgmexporter = "15s" + ztunnel = "15s" + istio-cni = "15s" + waypoint-proxy = "15s" + `) + isDefaultConfig = false + useConfigFiles = false + }) + It("should process the config with some sections missing for the Linux ReplicaSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.ConfigReaderSidecar, shared.OSType.Linux)).To(Succeed()) + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, "./testdata/not-all-sections-linux-rs.yaml", "") }) - It("should process the config for the Windows Daemonset", func() { + It("should process the config with some sections missing for the Linux DaemonSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Linux)).To(Succeed()) + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, "./testdata/not-all-sections-linux-ds.yaml", "") + }) + It("should process the config with some sections missing for the Windows DaemonSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Windows)).To(Succeed()) + extraEnvVars := map[string]string{ + "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "true", + } + for key, value := range extraEnvVars { + expectedEnvVars[key] = value + } + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, "./testdata/no-scrape-jobs-linux-rs.yaml", "") }) }) - Context("when minimal ingestion is not true", func() { - AfterEach(func() { - cleanupEnvVars() - }) - - It("should handle it being set to false with the keeplist regex values", func() { - setEnvVars(map[string]string { - "AZMON_OPERATOR_ENABLED": "true", - "CONTAINER_TYPE": "ConfigReaderSidecar", - "CONTROLLER_TYPE": "ReplicaSet", - "OS_TYPE": "linux", - "MODE": "advanced", - "KUBE_STATE_NAME": "ama-metrics-ksm", - "POD_NAMESPACE": "kube-system", - "MAC": "true", + Context("when the configmap sections exist but all scrape jobs are false", func() { + var expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap map[string]string + var isDefaultConfig, useConfigFiles bool + BeforeEach(func() { + expectedEnvVars = testhelpers.DefaultManagedPrometheusEnvVars() + extraEnvVars := map[string]string{ + "AZMON_AGENT_CFG_SCHEMA_VERSION": "v1", + "AZMON_AGENT_CFG_FILE_VERSION": "ver1", + "AZMON_OPERATOR_ENABLED_CHART_SETTING": "true", + "AZMON_PROMETHEUS_POD_ANNOTATION_SCRAPING_ENABLED": "", + "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "true", + "DEBUG_MODE_ENABLED": "false", + "CONFIGMAP_VERSION": "v1", + } + + scrapeOverrides := testhelpers.CloneJobEnabledStates(shared.DefaultScrapeJobs) + for jobName := range scrapeOverrides { + scrapeOverrides[jobName] = false + } + + overrides := testhelpers.BuildEnvVarOverrides(scrapeOverrides, func(jobName string) string { + return testhelpers.BuildEnvVarName(jobName, "_SCRAPING_ENABLED") }) + for key, value := range overrides { + extraEnvVars[key] = value + } + + for key, value := range extraEnvVars { + expectedEnvVars[key] = value + } + expectedKeepListHashMap = testhelpers.ExpectedKeepListMap(shared.DefaultScrapeJobs, true, "", true) + expectedScrapeIntervalHashMap = testhelpers.ExpectedScrapeIntervalMap(shared.DefaultScrapeJobs, "") + schemaVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "schema-version", "v1") + configVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "config-version", "ver1") + defaultSettingsMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "default-scrape-settings-enabled", ` + kubelet = false + coredns = false + cadvisor = false + kubeproxy = false + apiserver = false + kubestate = false + nodeexporter = false + windowsexporter = false + windowskubeproxy = false + kappiebasic = false + networkobservabilityRetina = false + networkobservabilityHubble = false + networkobservabilityCilium = false + acstor-capacity-provisioner = false + local-csi-driver = false + acstor-metrics-exporter = false + dcgmexporter = false + prometheuscollectorhealth = false + `) + isDefaultConfig = false + useConfigFiles = false + }) + + It("should process the config with no scrape jobs enabled for the Linux ReplicaSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.ConfigReaderSidecar, shared.OSType.Linux)).To(Succeed()) + expectedContentsFilePath := "./testdata/no-scrape-jobs-linux-rs.yaml" + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "") + }) - schemaVersionFile = createTempFile("schema-version", "v1") - configVersionFile = createTempFile("config-version", "ver1") - configMapMountPathForPodAnnotation = createTempFile("podannotation", "") - collectorSettingsMountPath = createTempFile("collector-settings", "") - defaultSettingsMountPath = createTempFile("default-settings", "") - configMapDebugMountPath = createTempFile("debug-mode", "") - configMapKeepListMountPath = createTempFile("keep-list", ` + It("should process the config with no scrape jobs enabled for the Linux DaemonSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Linux)).To(Succeed()) + expectedContentsFilePath := "./testdata/no-scrape-jobs-linux-rs.yaml" + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "") + }) + + It("should process the config with no scrape jobs enabled for the Windows DaemonSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Windows)).To(Succeed()) + expectedContentsFilePath := "./testdata/no-scrape-jobs-linux-rs.yaml" + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "") + }) + }) + + Context("when minimal ingestion is false and has keeplist regex values", func() { + var expectedKeepListHashMap, expectedScrapeIntervalHashMap map[string]string + var useConfigFiles, isDefaultConfig bool + + BeforeEach(func() { + expectedKeepListHashMap = testhelpers.ExpectedKeepListMap(shared.DefaultScrapeJobs, false, "test.*|test2", true) + expectedScrapeIntervalHashMap = testhelpers.ExpectedScrapeIntervalMap(shared.DefaultScrapeJobs, "") + + schemaVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "schema-version", "v1") + configVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "config-version", "") + configMapMountPathForPodAnnotation = testhelpers.MustCreateTempFile(configSettingsPrefix, "pod-annotation-based-scraping", "") + collectorSettingsMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "prometheus-collector-settings", "") + defaultSettingsMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "default-scrape-settings-enabled", "") + configMapDebugMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "debug-mode", "") + configMapKeepListMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "default-targets-metrics-keep-list", ` kubelet = "test.*|test2" coredns = "test.*|test2" cadvisor = "test.*|test2" @@ -518,194 +586,573 @@ var _ = Describe("Configmapparser", Ordered, func() { networkobservabilityRetina = "test.*|test2" networkobservabilityHubble = "test.*|test2" networkobservabilityCilium = "test.*|test2" + acstor-capacity-provisioner = "test.*|test2" + local-csi-driver = "test.*|test2" + acstor-metrics-exporter = "test.*|test2" + dcgmexporter = "test.*|test2" + prometheuscollectorhealth = "test.*|test2" + ztunnel = "test.*|test2" + istio-cni = "test.*|test2" + waypoint-proxy = "test.*|test2" + minimalingestionprofile = false + `) + configMapScrapeIntervalMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "default-targets-scrape-interval-settings", ``) + useConfigFiles = false + isDefaultConfig = false + }) + + It("should process the scrape jobs enabled for the Linux ReplicaSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.ConfigReaderSidecar, shared.OSType.Linux)).To(Succeed()) + checkResults(useConfigFiles, isDefaultConfig, nil, expectedKeepListHashMap, expectedScrapeIntervalHashMap, "./testdata/no-minimal-linux-rs.yaml", "") + }) + + It("should process the scrape jobs enabled for the Linux DaemonSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Linux)).To(Succeed()) + checkResults(useConfigFiles, isDefaultConfig, nil, expectedKeepListHashMap, expectedScrapeIntervalHashMap, "./testdata/no-minimal-linux-ds.yaml", "") + }) + + It("should process the scrape jobs enabled for the Windows DaemonSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Windows)).To(Succeed()) + checkResults(useConfigFiles, isDefaultConfig, nil, expectedKeepListHashMap, expectedScrapeIntervalHashMap, "./testdata/no-scrape-jobs-linux-rs.yaml", "") + }) + }) + + Context("when minimal ingestion is false and has no keeplist regex values", func() { + var expectedKeepListHashMap, expectedScrapeIntervalHashMap map[string]string + var useConfigFiles, isDefaultConfig bool + BeforeEach(func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.ConfigReaderSidecar, shared.OSType.Linux)).To(Succeed()) + expectedKeepListHashMap = testhelpers.ExpectedKeepListMap(shared.DefaultScrapeJobs, false, "", true) + expectedScrapeIntervalHashMap = testhelpers.ExpectedScrapeIntervalMap(shared.DefaultScrapeJobs, "") + + schemaVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "schema-version", "v1") + configVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "config-version", "ver1") + configMapMountPathForPodAnnotation = testhelpers.MustCreateTempFile(configSettingsPrefix, "pod-annotation-based-scraping", "") + collectorSettingsMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "prometheus-collector-settings", "") + defaultSettingsMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "default-scrape-settings-enabled", "") + configMapDebugMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "debug-mode", "") + configMapKeepListMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "default-targets-metrics-keep-list", ` minimalingestionprofile = false `) - configMapScrapeIntervalMountPath = createTempFile("scrape-interval", ``) - - setupProcessedFiles() - - Configmapparser() - - checkHashMaps(configMapKeepListEnvVarPath, map[string]string { - "KUBELET_METRICS_KEEP_LIST_REGEX": "test.*|test2", - "COREDNS_METRICS_KEEP_LIST_REGEX": "test.*|test2", - "CADVISOR_METRICS_KEEP_LIST_REGEX": "test.*|test2", - "KUBEPROXY_METRICS_KEEP_LIST_REGEX": "test.*|test2", - "APISERVER_METRICS_KEEP_LIST_REGEX": "test.*|test2", - "KUBESTATE_METRICS_KEEP_LIST_REGEX": "test.*|test2", - "NODEEXPORTER_METRICS_KEEP_LIST_REGEX": "test.*|test2", - "WINDOWSEXPORTER_METRICS_KEEP_LIST_REGEX": "test.*|test2", - "WINDOWSKUBEPROXY_METRICS_KEEP_LIST_REGEX": "test.*|test2", - "POD_ANNOTATION_METRICS_KEEP_LIST_REGEX": "test.*|test2", - "KAPPIEBASIC_METRICS_KEEP_LIST_REGEX": "test.*|test2", - "NETWORKOBSERVABILITYRETINA_METRICS_KEEP_LIST_REGEX": "test.*|test2", - "NETWORKOBSERVABILITYHUBBLE_METRICS_KEEP_LIST_REGEX": "test.*|test2", - "NETWORKOBSERVABILITYCILIUM_METRICS_KEEP_LIST_REGEX": "test.*|test2", + configMapScrapeIntervalMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "default-targets-scrape-interval-settings", ``) + useConfigFiles = false + isDefaultConfig = false + }) + + It("should process the scrape jobs enabled for the Linux ReplicaSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.ConfigReaderSidecar, shared.OSType.Linux)).To(Succeed()) + checkResults(useConfigFiles, isDefaultConfig, nil, expectedKeepListHashMap, expectedScrapeIntervalHashMap, "./testdata/no-minimal-no-keeplist-rs.yaml", "") + }) + + It("should process the scrape jobs enabled for the Linux DaemonSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Linux)).To(Succeed()) + checkResults(useConfigFiles, isDefaultConfig, nil, expectedKeepListHashMap, expectedScrapeIntervalHashMap, "./testdata/no-minimal-no-keeplist-ds.yaml", "") + }) + + It("should process the scrape jobs enabled for the Windows DaemonSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Windows)).To(Succeed()) + checkResults(useConfigFiles, isDefaultConfig, nil, expectedKeepListHashMap, expectedScrapeIntervalHashMap, "./testdata/no-scrape-jobs-linux-rs.yaml", "") + }) + }) + + Context("when the custom configmap exists", Label("custom-config"), func() { + Context("and the settings configmap sections do not exist", func() { + var expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap map[string]string + var isDefaultConfig, useConfigFiles bool + BeforeEach(func() { + expectedEnvVars = testhelpers.DefaultManagedPrometheusEnvVars() + expectedKeepListHashMap = testhelpers.ExpectedKeepListMap(shared.DefaultScrapeJobs, true, "", true) + expectedScrapeIntervalHashMap = testhelpers.ExpectedScrapeIntervalMap(shared.DefaultScrapeJobs, "") + isDefaultConfig = true + useConfigFiles = false + }) + It("should process the config with defaults for the Linux ReplicaSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.ConfigReaderSidecar, shared.OSType.Linux)).To(Succeed()) + configMapMountPath = "./testdata/custom-prometheus-config.yaml" + expectedContentsFilePath := "./testdata/default-linux-rs.yaml" + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "./testdata/custom-prometheus-config-and-defaults-rs.yaml") + }) + It("should process the config with defaults for the Linux DaemonSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Linux)).To(Succeed()) + configMapMountPath = "./testdata/custom-prometheus-config.yaml" + expectedContentsFilePath := "./testdata/default-linux-ds.yaml" + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "./testdata/custom-prometheus-config-and-defaults-ds.yaml") + }) + It("should process the config with defaults for the Windows DaemonSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Windows)).To(Succeed()) + configMapMountPath = "./testdata/custom-prometheus-config.yaml" + expectedEnvVars := testhelpers.DefaultManagedPrometheusEnvVars() + extraEnvVars := map[string]string{ + "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "true", + } + for key, value := range extraEnvVars { + expectedEnvVars[key] = value + } + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, "./testdata/no-scrape-jobs-linux-rs.yaml", "./testdata/custom-prometheus-config-windows-ds.yaml") }) }) + Context("and the settings configmap sections have all default scrape configs set to false", func() { + var expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap map[string]string + var isDefaultConfig, useConfigFiles bool + BeforeEach(func() { + expectedEnvVars := testhelpers.DefaultManagedPrometheusEnvVars() + extraEnvVars := map[string]string{ + "AZMON_AGENT_CFG_SCHEMA_VERSION": "v1", + "AZMON_AGENT_CFG_FILE_VERSION": "ver1", + "AZMON_OPERATOR_ENABLED_CHART_SETTING": "true", + "AZMON_PROMETHEUS_POD_ANNOTATION_SCRAPING_ENABLED": "", + "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "true", + "DEBUG_MODE_ENABLED": "false", + "CONFIGMAP_VERSION": "v1", + } + + scrapeOverrides := testhelpers.CloneJobEnabledStates(shared.DefaultScrapeJobs) + for jobName := range scrapeOverrides { + scrapeOverrides[jobName] = false + } + + overrides := testhelpers.BuildEnvVarOverrides(scrapeOverrides, func(jobName string) string { + return testhelpers.BuildEnvVarName(jobName, "_SCRAPING_ENABLED") + }) + for key, value := range overrides { + extraEnvVars[key] = value + } + + for key, value := range extraEnvVars { + expectedEnvVars[key] = value + } + expectedKeepListHashMap = testhelpers.ExpectedKeepListMap(shared.DefaultScrapeJobs, true, "", true) + expectedScrapeIntervalHashMap = testhelpers.ExpectedScrapeIntervalMap(shared.DefaultScrapeJobs, "") - It("should handle it being set to false with no keeplist regex values", func() { - setEnvVars(map[string]string { - "AZMON_OPERATOR_ENABLED": "true", - "CONTAINER_TYPE": "ConfigReaderSidecar", - "CONTROLLER_TYPE": "ReplicaSet", - "OS_TYPE": "linux", - "MODE": "advanced", - "KUBE_STATE_NAME": "ama-metrics-ksm", - "POD_NAMESPACE": "kube-system", - "MAC": "true", + schemaVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "schema-version", "v1") + configVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "config-version", "ver1") + defaultSettingsMountPath = testhelpers.MustCreateTempFile(configSettingsPrefix, "default-scrape-settings-enabled", ` + kubelet = false + coredns = false + cadvisor = false + kubeproxy = false + apiserver = false + kubestate = false + nodeexporter = false + windowsexporter = false + windowskubeproxy = false + kappiebasic = false + networkobservabilityRetina = false + networkobservabilityHubble = false + networkobservabilityCilium = false + acstor-capacity-provisioner = false + local-csi-driver = false + acstor-metrics-exporter = false + dcgmexporter = false + prometheuscollectorhealth = false + `) + isDefaultConfig = false + useConfigFiles = false + configMapMountPath = "./testdata/custom-prometheus-config.yaml" }) + It("should process the config with defaults for the Linux ReplicaSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.ConfigReaderSidecar, shared.OSType.Linux)).To(Succeed()) + expectedContentsFilePath := "./testdata/no-scrape-jobs-linux-rs.yaml" - schemaVersionFile = createTempFile("schema-version", "v1") - configVersionFile = createTempFile("config-version", "ver1") - configMapMountPathForPodAnnotation = createTempFile("podannotation", "") - collectorSettingsMountPath = createTempFile("collector-settings", "") - defaultSettingsMountPath = createTempFile("default-settings", "") - configMapDebugMountPath = createTempFile("debug-mode", "") - configMapKeepListMountPath = createTempFile("keep-list", ` - minimalingestionprofile = false + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "./testdata/custom-prometheus-config-no-defaults-rs.yaml") + }) + It("should process the config with defaults for the Linux DaemonSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Linux)).To(Succeed()) + expectedContentsFilePath := "./testdata/no-scrape-jobs-linux-rs.yaml" + + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "./testdata/custom-prometheus-config-no-defaults-rs.yaml") + }) + It("should process the config with defaults for the Windows DaemonSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Windows)).To(Succeed()) + expectedContentsFilePath := "./testdata/no-scrape-jobs-linux-rs.yaml" + + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "./testdata/custom-prometheus-config-no-defaults-rs.yaml") + }) + }) + }) + + Context("when the settings configmap uses v2 and the sections exist but are empty", func() { + var expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap map[string]string + var isDefaultConfig, useConfigFiles bool + BeforeEach(func() { + expectedEnvVars = testhelpers.DefaultManagedPrometheusEnvVars() + extraEnvVars := map[string]string{ + "AZMON_AGENT_CFG_SCHEMA_VERSION": "v2", + "AZMON_AGENT_CFG_FILE_VERSION": "ver1", + "AZMON_OPERATOR_ENABLED_CHART_SETTING": "true", + "CONFIGMAP_VERSION": "v2", + } + for key, value := range extraEnvVars { + expectedEnvVars[key] = value + } + expectedKeepListHashMap = testhelpers.ExpectedKeepListMap(shared.DefaultScrapeJobs, true, "", true) + expectedScrapeIntervalHashMap = testhelpers.ExpectedScrapeIntervalMap(shared.DefaultScrapeJobs, "") + isDefaultConfig = true + useConfigFiles = true + + schemaVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "schema-version", "v2") + configVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "config-version", "ver1") + }) + It("should process the config with defaults for the Linux ReplicaSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.ConfigReaderSidecar, shared.OSType.Linux)).To(Succeed()) + expectedContentsFilePath := "./testdata/default-linux-rs.yaml" + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "") + }) + + It("should process the config with defaults for the Linux DaemonSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Linux)).To(Succeed()) + expectedContentsFilePath := "./testdata/default-linux-ds.yaml" + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "") + }) + + It("should process the config with defaults for the Windows DaemonSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Windows)).To(Succeed()) + extraEnvVars := map[string]string{ + "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "true", + } + for key, value := range extraEnvVars { + expectedEnvVars[key] = value + } + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, "./testdata/no-scrape-jobs-linux-rs.yaml", "") + }) + }) + + Context("when the settings configmap uses v2 and the sections are not default", Label("v2"), func() { + var expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap map[string]string + var isDefaultConfig, useConfigFiles bool + BeforeEach(func() { + expectedEnvVars = testhelpers.DefaultManagedPrometheusEnvVars() + extraEnvVars := map[string]string{ + "AZMON_AGENT_CFG_SCHEMA_VERSION": "v2", + "AZMON_AGENT_CFG_FILE_VERSION": "ver1", + "AZMON_PROMETHEUS_POD_ANNOTATION_NAMESPACES_REGEX": "'.*|value'", + "AZMON_CLUSTER_LABEL": "alias", + "AZMON_CLUSTER_ALIAS": "alias", + "AZMON_OPERATOR_ENABLED_CHART_SETTING": "true", + "AZMON_PROMETHEUS_PODANNOTATIONS_SCRAPING_ENABLED": "true", + "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "false", + "DEBUG_MODE_ENABLED": "true", + "AZMON_KSM_CONFIG_ENABLED": "true", + "CONFIGMAP_VERSION": "v2", + } + + scrapeOverrides := testhelpers.CloneJobEnabledStates(shared.DefaultScrapeJobs) + for _, job := range []string{ + "kubelet", + "coredns", + "cadvisor", + "kubeproxy", + "apiserver", + "kubestate", + "nodeexporter", + "windowsexporter", + "windowskubeproxy", + "kappiebasic", + "networkobservabilityRetina", + "networkobservabilityHubble", + "networkobservabilityCilium", + "podannotations", + "acstor-capacity-provisioner", + "local-csi-driver", + "acstor-metrics-exporter", + "dcgmexporter", + } { + scrapeOverrides[job] = true + } + scrapeOverrides["prometheuscollectorhealth"] = false + + overrides := testhelpers.BuildEnvVarOverrides(scrapeOverrides, func(jobName string) string { + return testhelpers.BuildEnvVarName(jobName, "_SCRAPING_ENABLED") + }) + for key, value := range overrides { + extraEnvVars[key] = value + } + + for key, value := range extraEnvVars { + expectedEnvVars[key] = value + } + expectedKeepListHashMap = testhelpers.ExpectedKeepListMap(shared.DefaultScrapeJobs, true, "test.*|test2", true) + expectedScrapeIntervalHashMap = testhelpers.ExpectedScrapeIntervalMap(shared.DefaultScrapeJobs, "15s") + schemaVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "schema-version", "v2") + fmt.Println("Schema version file created at:", schemaVersionFile) + configVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "config-version", "ver1") + fmt.Println("Config version file created at:", configVersionFile) + _ = testhelpers.MustCreateTempFile(configSettingsPrefix, "prometheus-collector-settings", ` + cluster_alias = "alias" + debug-mode = true + https_config = true `) - configMapScrapeIntervalMountPath = createTempFile("scrape-interval", ``) - - podAnnotationEnvVarPath = createTempFile("podannotation-envvar", "") - collectorSettingsEnvVarPath = createTempFile("collector-settings-envvar", "") - defaultSettingsEnvVarPath = createTempFile("default-settings-envvar", "") - debugModeEnvVarPath = createTempFile("debug-mode-envvar", "") - configMapKeepListEnvVarPath = createTempFile("keep-list-envvar", "") - scrapeIntervalEnvVarPath = createTempFile("scrape-interval-envvar", "") - - Configmapparser() - - checkHashMaps(configMapKeepListEnvVarPath, map[string]string { - "KUBELET_METRICS_KEEP_LIST_REGEX": "", - "COREDNS_METRICS_KEEP_LIST_REGEX": "", - "CADVISOR_METRICS_KEEP_LIST_REGEX": "", - "KUBEPROXY_METRICS_KEEP_LIST_REGEX": "", - "APISERVER_METRICS_KEEP_LIST_REGEX": "", - "KUBESTATE_METRICS_KEEP_LIST_REGEX": "", - "NODEEXPORTER_METRICS_KEEP_LIST_REGEX": "", - "WINDOWSEXPORTER_METRICS_KEEP_LIST_REGEX": "", - "WINDOWSKUBEPROXY_METRICS_KEEP_LIST_REGEX": "", - "POD_ANNOTATION_METRICS_KEEP_LIST_REGEX": "", - "KAPPIEBASIC_METRICS_KEEP_LIST_REGEX": "", - "NETWORKOBSERVABILITYRETINA_METRICS_KEEP_LIST_REGEX": "", - "NETWORKOBSERVABILITYHUBBLE_METRICS_KEEP_LIST_REGEX": "", - "NETWORKOBSERVABILITYCILIUM_METRICS_KEEP_LIST_REGEX": "", + _ = testhelpers.MustCreateTempFile(configSettingsPrefix, "cluster-metrics", ` + default-targets-scrape-enabled: |- + kubelet = true + coredns = true + cadvisor = true + kubeproxy = true + apiserver = true + kubestate = true + nodeexporter = true + windowsexporter = true + windowskubeproxy = true + kappiebasic = true + networkobservabilityRetina = true + networkobservabilityHubble = true + networkobservabilityCilium = true + acstor-capacity-provisioner = true + local-csi-driver = true + acstor-metrics-exporter = true + dcgmexporter = true + prometheuscollectorhealth = false + pod-annotation-based-scraping: |- + podannotationnamespaceregex = ".*|value" + ksm-config: |- + resources: + secrets: {} + configmaps: {} + labels_allow_list: + pods: + - app8 + annotations_allow_list: + namespaces: + - kube-system + - default + default-targets-metrics-keep-list: |- + kubelet = "test.*|test2" + coredns = "test.*|test2" + cadvisor = "test.*|test2" + kubeproxy = "test.*|test2" + apiserver = "test.*|test2" + kubestate = "test.*|test2" + nodeexporter = "test.*|test2" + windowsexporter = "test.*|test2" + windowskubeproxy = "test.*|test2" + podannotations = "test.*|test2" + kappiebasic = "test.*|test2" + networkobservabilityRetina = "test.*|test2" + networkobservabilityHubble = "test.*|test2" + networkobservabilityCilium = "test.*|test2" + acstor-capacity-provisioner = "test.*|test2" + local-csi-driver = "test.*|test2" + acstor-metrics-exporter = "test.*|test2" + dcgmexporter = "test.*|test2" + prometheuscollectorhealth = "test.*|test2" + ztunnel = "test.*|test2" + istio-cni = "test.*|test2" + waypoint-proxy = "test.*|test2" + minimal-ingestion-profile: |- + enabled = true + default-targets-scrape-interval-settings: |- + kubelet = "15s" + coredns = "15s" + cadvisor = "15s" + kubeproxy = "15s" + apiserver = "15s" + kubestate = "15s" + nodeexporter = "15s" + windowsexporter = "15s" + windowskubeproxy = "15s" + kappiebasic = "15s" + networkobservabilityRetina = "15s" + networkobservabilityHubble = "15s" + networkobservabilityCilium = "15s" + prometheuscollectorhealth = "15s" + podannotations = "15s" + acstor-capacity-provisioner = "15s" + local-csi-driver = "15s" + acstor-metrics-exporter = "15s" + dcgmexporter = "15s" + ztunnel = "15s" + istio-cni = "15s" + waypoint-proxy = "15s" + `) + configMapMountPath = "./testdata/advanced-linux-rs.yaml" + isDefaultConfig = false + useConfigFiles = false + }) + + It("should process the config with custom settings for the Linux ReplicaSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.ConfigReaderSidecar, shared.OSType.Linux)).To(Succeed()) + expectedContentsFilePath := "./testdata/advanced-linux-rs.yaml" + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "") + }) + + It("should process the config with custom settings for the Linux DaemonSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Linux)).To(Succeed()) + expectedContentsFilePath := "./testdata/advanced-linux-ds.yaml" + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "") + }) + + It("should process the config with custom settings for the Windows DaemonSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Windows)).To(Succeed()) + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, "./testdata/advanced-windows-ds.yaml", "") + }) + }) + + Context("when the settings configmap uses v2, minimal ingestion is false, and not all sections are present", func() { + var expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap map[string]string + var isDefaultConfig, useConfigFiles bool + BeforeEach(func() { + expectedEnvVars := testhelpers.DefaultManagedPrometheusEnvVars() + extraEnvVars := map[string]string{ + "AZMON_AGENT_CFG_SCHEMA_VERSION": "v2", + "AZMON_AGENT_CFG_FILE_VERSION": "ver1", + "AZMON_OPERATOR_ENABLED_CHART_SETTING": "true", + "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED": "false", + "DEBUG_MODE_ENABLED": "false", + "CONFIGMAP_VERSION": "v2", + } + + scrapeOverrides := testhelpers.CloneJobEnabledStates(shared.DefaultScrapeJobs) + for _, job := range []string{ + "kubelet", + "coredns", + "cadvisor", + "kubeproxy", + "apiserver", + "kubestate", + "nodeexporter", + "windowsexporter", + "windowskubeproxy", + "kappiebasic", + "networkobservabilityRetina", + "networkobservabilityHubble", + "networkobservabilityCilium", + "acstor-capacity-provisioner", + "local-csi-driver", + "acstor-metrics-exporter", + "dcgmexporter", + } { + scrapeOverrides[job] = true + } + scrapeOverrides["prometheuscollectorhealth"] = false + + overrides := testhelpers.BuildEnvVarOverrides(scrapeOverrides, func(jobName string) string { + return testhelpers.BuildEnvVarName(jobName, "_SCRAPING_ENABLED") }) + for key, value := range overrides { + extraEnvVars[key] = value + } + + for key, value := range extraEnvVars { + expectedEnvVars[key] = value + } + expectedKeepListHashMap = testhelpers.ExpectedKeepListMap(shared.DefaultScrapeJobs, false, "", true) + expectedScrapeIntervalHashMap = testhelpers.ExpectedScrapeIntervalMap(shared.DefaultScrapeJobs, "") + schemaVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "schema-version", "v2") + fmt.Println("Schema version file created at:", schemaVersionFile) + configVersionFile = testhelpers.MustCreateTempFile(configSettingsPrefix, "config-version", "ver1") + fmt.Println("Config version file created at:", configVersionFile) + _ = testhelpers.MustCreateTempFile(configSettingsPrefix, "cluster-metrics", ` + default-targets-scrape-enabled: |- + kubelet = true + coredns = true + cadvisor = true + kubeproxy = true + apiserver = true + kubestate = true + nodeexporter = true + windowsexporter = true + windowskubeproxy = true + kappiebasic = true + networkobservabilityRetina = true + networkobservabilityHubble = true + networkobservabilityCilium = true + acstor-capacity-provisioner = true + local-csi-driver = true + acstor-metrics-exporter = true + dcgmexporter = true + prometheuscollectorhealth = false + minimal-ingestion-profile: |- + enabled = false + `) + configMapMountPath = "./testdata/advanced-linux-rs.yaml" + isDefaultConfig = false + useConfigFiles = false }) - }) + It("should process the settings for the Linux ReplicaSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.ConfigReaderSidecar, shared.OSType.Linux)).To(Succeed()) + expectedContentsFilePath := "./testdata/advanced-no-minimal-linux-rs.yaml" + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "") + }) + + It("should process the settings for the Linux DaemonSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Linux)).To(Succeed()) + expectedContentsFilePath := "./testdata/advanced-no-minimal-linux-ds.yaml" + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, expectedContentsFilePath, "") + }) + + It("should process the settings for the Windows DaemonSet", func() { + Expect(testhelpers.SetManagedPrometheusEnvVars(shared.ControllerType.DaemonSet, shared.OSType.Windows)).To(Succeed()) + checkResults(useConfigFiles, isDefaultConfig, expectedEnvVars, expectedKeepListHashMap, expectedScrapeIntervalHashMap, "./testdata/advanced-no-minimal-windows-ds.yaml", "") + }) + }) }) -func createTempFile(name string, content string) string { - tempFile, err := ioutil.TempFile("", name) +func checkResults(useConfigFiles bool, isDefaultConfig bool, expectedEnvVars map[string]string, expectedKeepListHashMap map[string]string, expectedScrapeIntervalHashMap map[string]string, expectedDefaultContentsFilePath string, expectedMergedContentsFilePath string) { + if useConfigFiles { + setupConfigFiles(isDefaultConfig) + } + setupProcessedFiles() + processConfigFiles() + + err := testhelpers.CheckEnvVars(expectedEnvVars) Expect(err).NotTo(HaveOccurred()) - _, err = tempFile.WriteString(content) + + keepListHash, err := testhelpers.ReadYAMLStringMap(configMapKeepListEnvVarPath) Expect(err).NotTo(HaveOccurred()) - return tempFile.Name() -} + Expect(keepListHash).To(BeComparableTo(expectedKeepListHashMap)) -func checkEnvVars(envVars map[string]string) error { - for key, value := range envVars { - if os.Getenv(key) != value { - return fmt.Errorf("Expected %s to be %s, but got %s", key, value, os.Getenv(key)) - } - } - return nil -} + scrapeIntervalHash, err := testhelpers.ReadYAMLStringMap(scrapeIntervalEnvVarPath) + Expect(err).NotTo(HaveOccurred()) + Expect(scrapeIntervalHash).To(BeComparableTo(expectedScrapeIntervalHashMap)) -func checkHashMaps(filepath string, expectedHash map[string]string) { - regexFileContents, err := ioutil.ReadFile(filepath) + mergedFileContents, err := os.ReadFile(mergedDefaultConfigPath) Expect(err).NotTo(HaveOccurred()) - var hash map[string]string - err = yaml.Unmarshal([]byte(regexFileContents), &hash) + fmt.Println(string(mergedFileContents)) + expectedDefaultFileContents, err := os.ReadFile(expectedDefaultContentsFilePath) Expect(err).NotTo(HaveOccurred()) - Expect(hash).To(BeComparableTo(expectedHash)) -} -func setEnvVars(envVars map[string]string) { - for key, value := range envVars { - os.Setenv(key, value) - } -} + var customMergedConfigFileContents, expectedCustomMergedConfigFileContents []byte + if expectedMergedContentsFilePath != "" { + customMergedConfigFileContents, err = os.ReadFile(promMergedConfigPath) + Expect(err).NotTo(HaveOccurred()) + fmt.Println(string(customMergedConfigFileContents)) -func setupConfigFiles(defaultPath bool) { - if defaultPath { - configMapDebugMountPath = "/etc/config/settings/debug-mode" - replicaSetCollectorConfig = "/opt/microsoft/otelcollector/collector-config-replicaset.yml" - defaultSettingsMountPath = "/etc/config/settings/default-scrape-settings" - configMapKeepListMountPath = "/etc/config/settings/default-targets-metrics-keep-list" - configMapMountPathForPodAnnotation = "/etc/config/settings/pod-annotation-based-scraping" - collectorSettingsMountPath = "/etc/config/settings/prometheus-collector-settings" - schemaVersionFile = "/etc/config/settings/schema-version" - configVersionFile = "/etc/config/settings/config-version" - configMapScrapeIntervalMountPath = "/etc/config/settings/default-targets-scrape-interval-settings" - } else { - schemaVersionFile = createTempFile("schema-version", "v1") - configVersionFile = createTempFile("config-version", "ver1") - configMapMountPathForPodAnnotation = createTempFile("podannotation", "") - collectorSettingsMountPath = createTempFile("collector-settings", "") - defaultSettingsMountPath = createTempFile("default-settings", "") - configMapDebugMountPath = createTempFile("debug-mode", "") - configMapKeepListMountPath = createTempFile("keep-list", "") - configMapScrapeIntervalMountPath = createTempFile("scrape-interval", "") - replicaSetCollectorConfig = "./testdata/collector-config-replicaset.yml" + expectedCustomMergedConfigFileContents, err = os.ReadFile(expectedMergedContentsFilePath) + Expect(err).NotTo(HaveOccurred()) } -} -func setupProcessedFiles() { - podAnnotationEnvVarPath = createTempFile("podannotation-envvar", "") - collectorSettingsEnvVarPath = createTempFile("collector-settings-envvar", "") - defaultSettingsEnvVarPath = createTempFile("default-settings-envvar", "") - debugModeEnvVarPath = createTempFile("debug-mode-envvar", "") - configMapKeepListEnvVarPath = createTempFile("keep-list-envvar", "") - scrapeIntervalEnvVarPath = createTempFile("scrape-interval-envvar", "") - - defaultPromConfigPathPrefix = "../../../configmapparser/default-prom-configs/" - mergedDefaultConfigPath = createTempFile("merged-default-config", "") - regexHashFile = configMapKeepListEnvVarPath - intervalHashFile = scrapeIntervalEnvVarPath -} + var mergedConfig, expectedConfig, customMergedConfig, expectedCustomConfig map[string]interface{} + + err = yaml.Unmarshal(mergedFileContents, &mergedConfig) + Expect(err).NotTo(HaveOccurred()) + + err = yaml.Unmarshal(expectedDefaultFileContents, &expectedConfig) + Expect(err).NotTo(HaveOccurred()) + + err = yaml.Unmarshal(customMergedConfigFileContents, &customMergedConfig) + Expect(err).NotTo(HaveOccurred()) + + err = yaml.Unmarshal(expectedCustomMergedConfigFileContents, &expectedCustomConfig) + Expect(err).NotTo(HaveOccurred()) -func cleanupEnvVars() { - allEnvVars := []string { - "CONTAINER_TYPE", - "CONTROLLER_TYPE", - "OS_TYPE", - "MODE", - "KUBE_STATE_NAME", - "POD_NAMESPACE", - "MAC", - "AZMON_AGENT_CFG_SCHEMA_VERSION", - "AZMON_AGENT_CFG_FILE_VERSION", - "AZMON_PROMETHEUS_POD_ANNOTATION_NAMESPACES_REGEX", - "AZMON_DEFAULT_METRIC_ACCOUNT_NAME", - "AZMON_CLUSTER_LABEL", - "AZMON_CLUSTER_ALIAS", - "AZMON_OPERATOR_ENABLED_CHART_SETTING", - "AZMON_OPERATOR_ENABLED", - "AZMON_OPERATOR_ENABLED_CFG_MAP_SETTING", - "AZMON_PROMETHEUS_KUBELET_SCRAPING_ENABLED", - "AZMON_PROMETHEUS_COREDNS_SCRAPING_ENABLED", - "AZMON_PROMETHEUS_CADVISOR_SCRAPING_ENABLED", - "AZMON_PROMETHEUS_KUBEPROXY_SCRAPING_ENABLED", - "AZMON_PROMETHEUS_APISERVER_SCRAPING_ENABLED", - "AZMON_PROMETHEUS_KUBESTATE_SCRAPING_ENABLED", - "AZMON_PROMETHEUS_NODEEXPORTER_SCRAPING_ENABLED", - "AZMON_PROMETHEUS_COLLECTOR_HEALTH_SCRAPING_ENABLED", - "AZMON_PROMETHEUS_POD_ANNOTATION_SCRAPING_ENABLED", - "AZMON_PROMETHEUS_WINDOWSEXPORTER_SCRAPING_ENABLED", - "AZMON_PROMETHEUS_WINDOWSKUBEPROXY_SCRAPING_ENABLED", - "AZMON_PROMETHEUS_KAPPIEBASIC_SCRAPING_ENABLED", - "AZMON_PROMETHEUS_NETWORKOBSERVABILITYRETINA_SCRAPING_ENABLED", - "AZMON_PROMETHEUS_NETWORKOBSERVABILITYHUBBLE_SCRAPING_ENABLED", - "AZMON_PROMETHEUS_NETWORKOBSERVABILITYCILIUM_SCRAPING_ENABLED", - "AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED", - "DEBUG_MODE_ENABLED", - "AZMON_INVALID_CUSTOM_PROMETHEUS_CONFIG", - "CONFIG_VALIDATOR_RUNNING_IN_AGENT", - "AZMON_USE_DEFAULT_PROMETHEUS_CONFIG", + // Order the scrape_configs by job_name for consistent comparison + for _, config := range []map[string]interface{}{mergedConfig, expectedConfig, customMergedConfig, expectedCustomConfig} { + if scrapeConfigs, ok := config["scrape_configs"].([]interface{}); ok { + sort.Slice(scrapeConfigs, func(i, j int) bool { + iConfig := scrapeConfigs[i].(map[interface{}]interface{}) + jConfig := scrapeConfigs[j].(map[interface{}]interface{}) + return iConfig["job_name"].(string) < jConfig["job_name"].(string) + }) + config["scrape_configs"] = scrapeConfigs + } } - for _, envVar := range allEnvVars { - os.Unsetenv(envVar) + + // Use BeEquivalentTo which compares content without requiring same order + // Only compare default configs when there's no custom config expected + if expectedMergedContentsFilePath == "" { + Expect(mergedConfig).To(BeEquivalentTo(expectedConfig), "Prometheus config content doesn't match") + } else { + // When custom config is expected, compare the custom merged config instead + Expect(customMergedConfig).To(BeEquivalentTo(expectedCustomConfig), "Expected Custom Prometheus config content doesn't match") } -} \ No newline at end of file +} diff --git a/otelcollector/shared/configmap/mp/definitions.go b/otelcollector/shared/configmap/mp/definitions.go index 2a3c518c4..4a4ad58a1 100644 --- a/otelcollector/shared/configmap/mp/definitions.go +++ b/otelcollector/shared/configmap/mp/definitions.go @@ -1,88 +1,34 @@ package configmapsettings var ( - schemaVersionFile = "/etc/config/settings/schema-version" - configVersionFile = "/etc/config/settings/config-version" - configMapDebugMountPath = "/etc/config/settings/debug-mode" - configMapOpentelemetryMetricsMountPath = "/etc/config/settings/opentelemetry-metrics" - replicaSetCollectorConfig = "/opt/microsoft/otelcollector/collector-config-replicaset.yml" - debugModeEnvVarPath = "/opt/microsoft/configmapparser/config_debug_mode_env_var" - defaultSettingsMountPath = "/etc/config/settings/default-scrape-settings-enabled" - defaultSettingsMountPathv2 = "/etc/config/settings/default-targets-scrape-enabled" - defaultSettingsEnvVarPath = "/opt/microsoft/configmapparser/config_default_scrape_settings_env_var" - configMapMountPathForPodAnnotation = "/etc/config/settings/pod-annotation-based-scraping" - podAnnotationEnvVarPath = "/opt/microsoft/configmapparser/config_def_pod_annotation_based_scraping" - collectorSettingsMountPath = "/etc/config/settings/prometheus-collector-settings" - collectorSettingsEnvVarPath = "/opt/microsoft/configmapparser/config_prometheus_collector_settings_env_var" - opentelemetryMetricsEnvVarPath = "/opt/microsoft/configmapparser/config_opentelemetry_metrics_env_var" - ksmConfigEnvVarPath = "/opt/microsoft/configmapparser/config_ksm_config_env_var" - configMapKeepListMountPath = "/etc/config/settings/default-targets-metrics-keep-list" - configMapKeepListEnvVarPath = "/opt/microsoft/configmapparser/config_def_targets_metrics_keep_list_hash" - configMapScrapeIntervalMountPath = "/etc/config/settings/default-targets-scrape-interval-settings" - scrapeIntervalEnvVarPath = "/opt/microsoft/configmapparser/config_def_targets_scrape_intervals_hash" - promMergedConfigPath = "/opt/promMergedConfig.yml" - mergedDefaultConfigPath = "/opt/defaultsMergedConfig.yml" - defaultPromConfigPathPrefix = "/opt/microsoft/otelcollector/default-prom-configs/" - regexHashFile = "/opt/microsoft/configmapparser/config_def_targets_metrics_keep_list_hash" - intervalHashFile = "/opt/microsoft/configmapparser/config_def_targets_scrape_intervals_hash" - kubeletDefaultFileRsSimple = "kubeletDefaultRsSimple.yml" - kubeletDefaultFileRsAdvanced = "kubeletDefaultRsAdvanced.yml" - kubeletDefaultFileDs = "kubeletDefaultDs.yml" - kubeletDefaultFileRsAdvancedWindowsDaemonset = "kubeletDefaultRsAdvancedWindowsDaemonset.yml" - coreDNSDefaultFile = "corednsDefault.yml" - cadvisorDefaultFileRsSimple = "cadvisorDefaultRsSimple.yml" - cadvisorDefaultFileRsAdvanced = "cadvisorDefaultRsAdvanced.yml" - cadvisorDefaultFileDs = "cadvisorDefaultDs.yml" - kubeProxyDefaultFile = "kubeproxyDefault.yml" - apiserverDefaultFile = "apiserverDefault.yml" - kubeStateDefaultFile = "kubestateDefault.yml" - nodeExporterDefaultFileRsSimple = "nodeexporterDefaultRsSimple.yml" - nodeExporterDefaultFileRsAdvanced = "nodeexporterDefaultRsAdvanced.yml" - nodeExporterDefaultFileDs = "nodeexporterDefaultDs.yml" - prometheusCollectorHealthDefaultFile = "prometheusCollectorHealth.yml" - windowsExporterDefaultRsSimpleFile = "windowsexporterDefaultRsSimple.yml" - windowsExporterDefaultDsFile = "windowsexporterDefaultDs.yml" - windowsKubeProxyDefaultFileRsSimpleFile = "windowskubeproxyDefaultRsSimple.yml" - windowsKubeProxyDefaultDsFile = "windowskubeproxyDefaultDs.yml" - podAnnotationsDefaultFile = "podannotationsDefault.yml" - kappieBasicDefaultFileDs = "kappieBasicDefaultDs.yml" - networkObservabilityRetinaDefaultFileDs = "networkobservabilityRetinaDefaultDs.yml" - networkObservabilityHubbleDefaultFileDs = "networkobservabilityHubbleDefaultDs.yml" - networkObservabilityCiliumDefaultFileDs = "networkobservabilityCiliumDefaultDs.yml" - acstorCapacityProvisionerDefaultFile = "acstorCapacityProvisionerDefaultFile.yml" - acstorMetricsExporterDefaultFile = "acstorMetricsExporterDefaultFile.yml" - LocalCSIDriverDefaultFile = "localCSIDriverDefaultFile.yml" - ztunnelDefaultFile = "ztunnelDefault.yml" - istioCniDefaultFile = "istioCniDefault.yml" - waypointProxyDefaultFile = "waypointProxyDefault.yml" - dcgmExporterDefaultFile = "dcgmExporterDefault.yml" + configSettingsPrefix = "/etc/config/settings/" + configMapParserPrefix = "/opt/microsoft/configmapparser/" + schemaVersionFile = configSettingsPrefix + "schema-version" + configVersionFile = configSettingsPrefix + "config-version" + configMapDebugMountPath = configSettingsPrefix + "debug-mode" + replicaSetCollectorConfig = "/opt/microsoft/otelcollector/collector-config-replicaset.yml" + debugModeEnvVarPath = configMapParserPrefix + "config_debug_mode_env_var" + defaultSettingsMountPath = configSettingsPrefix + "default-scrape-settings-enabled" + defaultSettingsMountPathv2 = configSettingsPrefix + "default-targets-scrape-enabled" + defaultSettingsEnvVarPath = configMapParserPrefix + "config_default_scrape_settings_env_var" + configMapMountPathForPodAnnotation = configSettingsPrefix + "pod-annotation-based-scraping" + podAnnotationEnvVarPath = configMapParserPrefix + "config_def_pod_annotation_based_scraping" + collectorSettingsMountPath = configSettingsPrefix + "prometheus-collector-settings" + collectorSettingsEnvVarPath = configMapParserPrefix + "config_prometheus_collector_settings_env_var" + configMapKeepListMountPath = configSettingsPrefix + "default-targets-metrics-keep-list" + configMapKeepListEnvVarPath = configMapParserPrefix + "config_def_targets_metrics_keep_list_hash" + configMapScrapeIntervalMountPath = configSettingsPrefix + "default-targets-scrape-interval-settings" + scrapeIntervalEnvVarPath = configMapParserPrefix + "config_def_targets_scrape_intervals_hash" + configMapOpentelemetryMetricsMountPath = configMapParserPrefix + "opentelemetry-metrics" + opentelemetryMetricsEnvVarPath = configMapParserPrefix + "config_opentelemetry_metrics_env_var" + ksmConfigEnvVarPath = configMapParserPrefix + "config_ksm_config_env_var" + promMergedConfigPath = "/opt/promMergedConfig.yaml" + mergedDefaultConfigPath = "/opt/defaultsMergedConfig.yaml" + defaultPromConfigPathPrefix = "/opt/microsoft/otelcollector/default-prom-configs/" + regexHashFile = "/opt/microsoft/configmapparser/config_def_targets_metrics_keep_list_hash" + intervalHashFile = "/opt/microsoft/configmapparser/config_def_targets_scrape_intervals_hash" ) -type RegexValues struct { - kubelet string - coredns string - cadvisor string - kubeproxy string - apiserver string - kubestate string - nodeexporter string - kappiebasic string - windowsexporter string - windowskubeproxy string - networkobservabilityretina string - networkobservabilityhubble string - networkobservabilitycilium string - podannotations string - minimalingestionprofile string - acstorcapacityprovisioner string - acstormetricsexporter string - localcsidriver string - ztunnel string - istiocni string - waypoint string - dcgmexporter string -} - // FilesystemConfigLoader implements ConfigLoader for file-based configuration loading. type FilesystemConfigLoader struct { ConfigMapMountPath string @@ -104,29 +50,6 @@ type ConfigProcessor struct { NoDefaultsEnabled bool TargetallocatorHttpsEnabled bool TargetallocatorHttpsEnabledChartSetting bool - - Kubelet string - Coredns string - Cadvisor string - Kubeproxy string - Apiserver string - Kubestate string - NodeExporter string - PrometheusCollectorHealth string - PodAnnotation string - Windowsexporter string - Windowskubeproxy string - Kappiebasic string - NetworkObservabilityRetina string - NetworkObservabilityHubble string - NetworkObservabilityCilium string - AcstorCapacityProvisioner string - AcstorMetricsExporter string - LocalCSIDriver string - Ztunnel string - IstioCni string - WaypointProxy string - DcgmExporter string } // ConfigParser is an interface for parsing configurations. diff --git a/otelcollector/shared/configmap/mp/go.mod b/otelcollector/shared/configmap/mp/go.mod index 0416a078e..c6cab899b 100644 --- a/otelcollector/shared/configmap/mp/go.mod +++ b/otelcollector/shared/configmap/mp/go.mod @@ -2,6 +2,8 @@ module github.com/prometheus-collector/shared/configmap/mp replace github.com/prometheus-collector/shared => ../../../shared +replace github.com/prometheus-collector/shared/configmap/common/testhelpers => ../../../shared/configmap/common/testhelpers + go 1.23.0 toolchain go1.24.3 @@ -10,6 +12,7 @@ require ( github.com/onsi/ginkgo/v2 v2.21.0 github.com/onsi/gomega v1.35.1 github.com/prometheus-collector/shared v0.0.0-00010101000000-000000000000 + github.com/prometheus-collector/shared/configmap/common/testhelpers v0.0.0-00010101000000-000000000000 gopkg.in/yaml.v2 v2.4.0 ) @@ -19,21 +22,21 @@ require ( github.com/go-logr/logr v1.4.2 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kr/text v0.2.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.62.0 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.65.0 // indirect github.com/x448/float16 v0.8.4 // indirect - golang.org/x/net v0.38.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect + golang.org/x/net v0.40.0 // indirect + golang.org/x/sys v0.33.0 // indirect + golang.org/x/text v0.25.0 // indirect golang.org/x/tools v0.26.0 // indirect - google.golang.org/protobuf v1.36.5 // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apimachinery v0.32.0 // indirect diff --git a/otelcollector/shared/configmap/mp/go.sum b/otelcollector/shared/configmap/mp/go.sum index e30b5dcf5..7e0d4a5d3 100644 --- a/otelcollector/shared/configmap/mp/go.sum +++ b/otelcollector/shared/configmap/mp/go.sum @@ -12,8 +12,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -39,10 +39,10 @@ github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7y github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= -github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE= +github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -64,20 +64,20 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= +golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -88,8 +88,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T 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= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/otelcollector/shared/configmap/mp/prometheus-config-merger.go b/otelcollector/shared/configmap/mp/prometheus-config-merger.go index b54b9dbcf..f6b299970 100644 --- a/otelcollector/shared/configmap/mp/prometheus-config-merger.go +++ b/otelcollector/shared/configmap/mp/prometheus-config-merger.go @@ -5,30 +5,24 @@ import ( "io/fs" "log" "os" - "reflect" "regexp" "strings" "github.com/prometheus-collector/shared" + cmcommon "github.com/prometheus-collector/shared/configmap/common" "gopkg.in/yaml.v2" ) -const ( +var ( configMapMountPath = "/etc/config/settings/prometheus/prometheus-config" replicasetControllerType = "replicaset" daemonsetControllerType = "daemonset" configReaderSidecarContainerType = "configreadersidecar" - supportedSchemaVersion = true - sendDSUpMetric = false -) - -var ( - regexHash = make(map[string]string) - intervalHash = make(map[string]string) + scrapeConfigDefinitionPathPrefix = "/opt/microsoft/otelcollector/default-prom-configs/" ) -var mergedDefaultConfigs map[interface{}]interface{} +var mergedDefaultConfigs = make(map[interface{}]interface{}) func parseConfigMap() string { defer func() { @@ -37,6 +31,7 @@ func parseConfigMap() string { } }() + log.Println("Starting to parse prometheus configmap", configMapMountPath) if _, err := os.Stat(configMapMountPath); os.IsNotExist(err) { shared.EchoWarning("Custom prometheus config does not exist, using only default scrape targets if they are enabled") return "" @@ -48,36 +43,9 @@ func parseConfigMap() string { return "" } - // shared.EchoVar("Successfully parsed configmap for prometheus config", string(config)) return string(config) } -func loadRegexHash() { - data, err := os.ReadFile(regexHashFile) - if err != nil { - log.Printf("Exception in loadRegexHash for prometheus config: %v. Keep list regexes will not be used\n", err) - return - } - - err = yaml.Unmarshal(data, ®exHash) - if err != nil { - log.Printf("Exception in loadRegexHash for prometheus config: %v. Keep list regexes will not be used\n", err) - } -} - -func loadIntervalHash() { - data, err := os.ReadFile(intervalHashFile) - if err != nil { - log.Printf("Exception in loadIntervalHash for prometheus config: %v. Scrape interval will not be used\n", err) - return - } - - err = yaml.Unmarshal(data, &intervalHash) - if err != nil { - log.Printf("Exception in loadIntervalHash for prometheus config: %v. Scrape interval will not be used\n", err) - } -} - func isConfigReaderSidecar() bool { containerType := os.Getenv("CONTAINER_TYPE") if containerType != "" { @@ -89,1282 +57,63 @@ func isConfigReaderSidecar() bool { return false } -func UpdateScrapeIntervalConfig(yamlConfigFile string, scrapeIntervalSetting string) { - log.Printf("Updating scrape interval config for %s\n", yamlConfigFile) - - // Read YAML config file - data, err := os.ReadFile(yamlConfigFile) - if err != nil { - log.Printf("Error reading config file %s: %v. The scrape interval will not be updated\n", yamlConfigFile, err) - return - } - - // Unmarshal YAML data - var config map[string]interface{} - err = yaml.Unmarshal(data, &config) - if err != nil { - log.Printf("Error unmarshalling YAML for %s: %v. The scrape interval will not be updated\n", yamlConfigFile, err) - return - } - - // Update scrape interval config - if scrapeConfigs, ok := config["scrape_configs"].([]interface{}); ok { - for _, scfg := range scrapeConfigs { - if scfgMap, ok := scfg.(map[interface{}]interface{}); ok { - log.Printf("scrapeInterval %s\n", scrapeIntervalSetting) - scfgMap["scrape_interval"] = scrapeIntervalSetting - } - } - - // Marshal updated config back to YAML - cfgYamlWithScrapeConfig, err := yaml.Marshal(config) - if err != nil { - log.Printf("Error marshalling YAML for %s: %v. The scrape interval will not be updated\n", yamlConfigFile, err) - return - } - - // Write updated YAML back to file - err = os.WriteFile(yamlConfigFile, []byte(cfgYamlWithScrapeConfig), fs.FileMode(0644)) - if err != nil { - log.Printf("Error writing to file %s: %v. The scrape interval will not be updated\n", yamlConfigFile, err) - return - } - } else { - log.Printf("No 'scrape_configs' found in the YAML. The scrape interval will not be updated.\n") +func UpdateScrapeIntervalConfig(yamlConfigFile, scrapeIntervalSetting string) { + if err := cmcommon.UpdateScrapeIntervalConfig(yamlConfigFile, scrapeIntervalSetting, log.Printf); err != nil { + log.Printf("UpdateScrapeIntervalConfig::error updating %s: %v\n", yamlConfigFile, err) } } func AppendMetricRelabelConfig(yamlConfigFile, keepListRegex string) error { - log.Printf("Starting to append keep list regex or minimal ingestion regex to %s\n", yamlConfigFile) - - content, err := os.ReadFile(yamlConfigFile) - if err != nil { - return fmt.Errorf("error reading config file %s: %v. The keep list regex will not be used", yamlConfigFile, err) - } - - var config map[string]interface{} - if err := yaml.Unmarshal(content, &config); err != nil { - return fmt.Errorf("error unmarshalling YAML for %s: %v. The keep list regex will not be used", yamlConfigFile, err) - } - - keepListMetricRelabelConfig := map[string]interface{}{ - "source_labels": []interface{}{"__name__"}, - "action": "keep", - "regex": keepListRegex, - } - - if scrapeConfigs, ok := config["scrape_configs"].([]interface{}); ok { - for i, scfg := range scrapeConfigs { - // Ensure scfg is a map with string keys - if scfgMap, ok := scfg.(map[interface{}]interface{}); ok { - // Convert to map[string]interface{} - stringScfgMap := make(map[string]interface{}) - for k, v := range scfgMap { - if key, ok := k.(string); ok { - stringScfgMap[key] = v - } else { - return fmt.Errorf("encountered non-string key in scrape config map: %v", k) - } - } - - // Update or add metric_relabel_configs - if metricRelabelCfgs, ok := stringScfgMap["metric_relabel_configs"].([]interface{}); ok { - stringScfgMap["metric_relabel_configs"] = append(metricRelabelCfgs, keepListMetricRelabelConfig) - } else { - stringScfgMap["metric_relabel_configs"] = []interface{}{keepListMetricRelabelConfig} - } - - // Convert back to map[interface{}]interface{} for YAML marshalling - interfaceScfgMap := make(map[interface{}]interface{}) - for k, v := range stringScfgMap { - interfaceScfgMap[k] = v - } - - // Update the scrape_configs list - scrapeConfigs[i] = interfaceScfgMap - } - } - - // Write updated scrape_configs back to config - config["scrape_configs"] = scrapeConfigs - } else { - log.Println("No 'scrape_configs' found in the YAML. Skipping updates.") - return nil - } - - cfgYamlWithMetricRelabelConfig, err := yaml.Marshal(config) - if err != nil { - return fmt.Errorf("error marshalling YAML for %s: %v. The keep list regex will not be used", yamlConfigFile, err) - } - - if err := os.WriteFile(yamlConfigFile, cfgYamlWithMetricRelabelConfig, os.ModePerm); err != nil { - return fmt.Errorf("error writing to file %s: %v. The keep list regex will not be used", yamlConfigFile, err) - } - - return nil -} - -func AppendRelabelConfig(yamlConfigFile string, relabelConfig []map[string]interface{}, keepRegex string) { - log.Printf("Adding relabel config for %s\n", yamlConfigFile) - - // Read YAML config file - data, err := os.ReadFile(yamlConfigFile) - if err != nil { - log.Printf("Error reading config file %s: %v. The relabel config will not be added\n", yamlConfigFile, err) - return - } - - // Unmarshal YAML data - var config map[string]interface{} - err = yaml.Unmarshal(data, &config) - if err != nil { - log.Printf("Error unmarshalling YAML for %s: %v. The relabel config will not be added\n", yamlConfigFile, err) - return - } - - // Append relabel config for keep list to each scrape config - if scrapeConfigs, ok := config["scrape_configs"].([]interface{}); ok { - for _, scfg := range scrapeConfigs { - if scfgMap, ok := scfg.(map[interface{}]interface{}); ok { - relabelCfgs, exists := scfgMap["relabel_configs"] - if !exists { - scfgMap["relabel_configs"] = relabelConfig - } else if relabelCfgsSlice, ok := relabelCfgs.([]interface{}); ok { - for _, rc := range relabelConfig { - relabelCfgsSlice = append(relabelCfgsSlice, rc) - } - scfgMap["relabel_configs"] = relabelCfgsSlice - } - } - } - - // Marshal updated config back to YAML - cfgYamlWithRelabelConfig, err := yaml.Marshal(config) - if err != nil { - log.Printf("Error marshalling YAML for %s: %v. The relabel config will not be added\n", yamlConfigFile, err) - return - } - - // Write updated YAML back to file - err = os.WriteFile(yamlConfigFile, []byte(cfgYamlWithRelabelConfig), fs.FileMode(0644)) - if err != nil { - log.Printf("Error writing to file %s: %v. The relabel config will not be added\n", yamlConfigFile, err) - return - } - } else { - log.Printf("No 'scrape_configs' found in the YAML. The relabel config will not be added.\n") - } + return cmcommon.AppendMetricRelabelConfig(yamlConfigFile, keepListRegex, log.Printf) } func populateDefaultPrometheusConfig() { defaultConfigs := []string{} - currentControllerType := strings.TrimSpace(strings.ToLower(os.Getenv("CONTROLLER_TYPE"))) - - // Default values - advancedMode := false - windowsDaemonset := false - - // Get current mode (advanced or not...) - currentMode := strings.TrimSpace(strings.ToLower(os.Getenv("MODE"))) - if currentMode == "advanced" { - advancedMode = true - } - - // Get if windowsdaemonset is enabled or not (i.e., WINMODE env = advanced or not...) - winMode := strings.TrimSpace(strings.ToLower(os.Getenv("WINMODE"))) - if winMode == "advanced" { - windowsDaemonset = true - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_KUBELET_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - kubeletMetricsKeepListRegex, exists := regexHash["KUBELET_METRICS_KEEP_LIST_REGEX"] - kubeletScrapeInterval := intervalHash["KUBELET_SCRAPE_INTERVAL"] - if currentControllerType == replicasetControllerType { - if !advancedMode { - UpdateScrapeIntervalConfig(kubeletDefaultFileRsSimple, kubeletScrapeInterval) - if exists && kubeletMetricsKeepListRegex != "" { - log.Printf("Using regex for Kubelet: %s\n", kubeletMetricsKeepListRegex) - AppendMetricRelabelConfig(kubeletDefaultFileRsSimple, kubeletMetricsKeepListRegex) - } - defaultConfigs = append(defaultConfigs, kubeletDefaultFileRsSimple) - } else if windowsDaemonset && sendDSUpMetric { - UpdateScrapeIntervalConfig(kubeletDefaultFileRsAdvancedWindowsDaemonset, kubeletScrapeInterval) - defaultConfigs = append(defaultConfigs, kubeletDefaultFileRsAdvancedWindowsDaemonset) - } else if sendDSUpMetric { - UpdateScrapeIntervalConfig(kubeletDefaultFileRsAdvanced, kubeletScrapeInterval) - defaultConfigs = append(defaultConfigs, kubeletDefaultFileRsAdvanced) - } - } else { - if advancedMode && (windowsDaemonset || strings.ToLower(os.Getenv("OS_TYPE")) == "linux") { - UpdateScrapeIntervalConfig(kubeletDefaultFileDs, kubeletScrapeInterval) - if exists && kubeletMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(kubeletDefaultFileDs, kubeletMetricsKeepListRegex) - } - contents, err := os.ReadFile(kubeletDefaultFileDs) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$OS_TYPE$$", os.Getenv("OS_TYPE"))) - err = os.WriteFile(kubeletDefaultFileDs, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, kubeletDefaultFileDs) - } - } - } - } - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_COREDNS_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" && currentControllerType == replicasetControllerType { - corednsMetricsKeepListRegex, exists := regexHash["COREDNS_METRICS_KEEP_LIST_REGEX"] - corednsScrapeInterval, intervalExists := intervalHash["COREDNS_SCRAPE_INTERVAL"] - if intervalExists { - UpdateScrapeIntervalConfig(coreDNSDefaultFile, corednsScrapeInterval) - } - if exists && corednsMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(coreDNSDefaultFile, corednsMetricsKeepListRegex) - } - defaultConfigs = append(defaultConfigs, coreDNSDefaultFile) - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_CADVISOR_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - cadvisorMetricsKeepListRegex, exists := regexHash["CADVISOR_METRICS_KEEP_LIST_REGEX"] - cadvisorScrapeInterval, intervalExists := intervalHash["CADVISOR_SCRAPE_INTERVAL"] - if intervalExists { - if currentControllerType == replicasetControllerType { - if !advancedMode { - UpdateScrapeIntervalConfig(cadvisorDefaultFileRsSimple, cadvisorScrapeInterval) - if exists && cadvisorMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(cadvisorDefaultFileRsSimple, cadvisorMetricsKeepListRegex) - } - defaultConfigs = append(defaultConfigs, cadvisorDefaultFileRsSimple) - } else if sendDSUpMetric { - UpdateScrapeIntervalConfig(cadvisorDefaultFileRsAdvanced, cadvisorScrapeInterval) - defaultConfigs = append(defaultConfigs, cadvisorDefaultFileRsAdvanced) - } - } else { - if advancedMode && strings.ToLower(os.Getenv("OS_TYPE")) == "linux" { - UpdateScrapeIntervalConfig(cadvisorDefaultFileDs, cadvisorScrapeInterval) - if exists && cadvisorMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(cadvisorDefaultFileDs, cadvisorMetricsKeepListRegex) - } - contents, err := os.ReadFile(cadvisorDefaultFileDs) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(cadvisorDefaultFileDs, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, cadvisorDefaultFileDs) - } - } - } - } - } - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_KUBEPROXY_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" && currentControllerType == replicasetControllerType { - kubeproxyMetricsKeepListRegex, exists := regexHash["KUBEPROXY_METRICS_KEEP_LIST_REGEX"] - kubeproxyScrapeInterval, intervalExists := intervalHash["KUBEPROXY_SCRAPE_INTERVAL"] - if intervalExists { - UpdateScrapeIntervalConfig(kubeProxyDefaultFile, kubeproxyScrapeInterval) - } - if exists && kubeproxyMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(kubeProxyDefaultFile, kubeproxyMetricsKeepListRegex) - } - defaultConfigs = append(defaultConfigs, kubeProxyDefaultFile) - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_APISERVER_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" && currentControllerType == replicasetControllerType { - apiserverMetricsKeepListRegex, exists := regexHash["APISERVER_METRICS_KEEP_LIST_REGEX"] - apiserverScrapeInterval, intervalExists := intervalHash["APISERVER_SCRAPE_INTERVAL"] - if intervalExists { - UpdateScrapeIntervalConfig(apiserverDefaultFile, apiserverScrapeInterval) - } - if exists && apiserverMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(apiserverDefaultFile, apiserverMetricsKeepListRegex) - } - defaultConfigs = append(defaultConfigs, apiserverDefaultFile) - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_KUBESTATE_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" && currentControllerType == replicasetControllerType { - kubestateMetricsKeepListRegex, exists := regexHash["KUBESTATE_METRICS_KEEP_LIST_REGEX"] - kubestateScrapeInterval, intervalExists := intervalHash["KUBESTATE_SCRAPE_INTERVAL"] - log.Printf("path %s: %s\n", "kubeStateDefaultFile", kubeStateDefaultFile) - - if intervalExists { - UpdateScrapeIntervalConfig(kubeStateDefaultFile, kubestateScrapeInterval) - } - if exists && kubestateMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(kubeStateDefaultFile, kubestateMetricsKeepListRegex) - } - contents, err := os.ReadFile(kubeStateDefaultFile) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$KUBE_STATE_NAME$$", os.Getenv("KUBE_STATE_NAME"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$POD_NAMESPACE$$", os.Getenv("POD_NAMESPACE"))) - err = os.WriteFile(kubeStateDefaultFile, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, kubeStateDefaultFile) - } - } - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_NODEEXPORTER_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - nodeexporterMetricsKeepListRegex, exists := regexHash["NODEEXPORTER_METRICS_KEEP_LIST_REGEX"] - nodeexporterScrapeInterval := intervalHash["NODEEXPORTER_SCRAPE_INTERVAL"] - if currentControllerType == replicasetControllerType { - if advancedMode && sendDSUpMetric { - UpdateScrapeIntervalConfig(nodeExporterDefaultFileRsAdvanced, nodeexporterScrapeInterval) - contents, err := os.ReadFile(nodeExporterDefaultFileRsAdvanced) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_EXPORTER_NAME$$", os.Getenv("NODE_EXPORTER_NAME"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$POD_NAMESPACE$$", os.Getenv("POD_NAMESPACE"))) - err = os.WriteFile(nodeExporterDefaultFileRsAdvanced, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, nodeExporterDefaultFileRsAdvanced) - } - } - } else if !advancedMode { - UpdateScrapeIntervalConfig(nodeExporterDefaultFileRsSimple, nodeexporterScrapeInterval) - if exists && nodeexporterMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(nodeExporterDefaultFileRsSimple, nodeexporterMetricsKeepListRegex) - } - contents, err := os.ReadFile(nodeExporterDefaultFileRsSimple) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_EXPORTER_NAME$$", os.Getenv("NODE_EXPORTER_NAME"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$POD_NAMESPACE$$", os.Getenv("POD_NAMESPACE"))) - err = os.WriteFile(nodeExporterDefaultFileRsSimple, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, nodeExporterDefaultFileRsSimple) - } - } - } - } else { - if advancedMode && strings.ToLower(os.Getenv("OS_TYPE")) == "linux" { - UpdateScrapeIntervalConfig(nodeExporterDefaultFileDs, nodeexporterScrapeInterval) - if exists && nodeexporterMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(nodeExporterDefaultFileDs, nodeexporterMetricsKeepListRegex) - } - contents, err := os.ReadFile(nodeExporterDefaultFileDs) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_EXPORTER_TARGETPORT$$", os.Getenv("NODE_EXPORTER_TARGETPORT"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(nodeExporterDefaultFileDs, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, nodeExporterDefaultFileDs) - } - } - } - } - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_KAPPIEBASIC_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - kappiebasicMetricsKeepListRegex, exists := regexHash["KAPPIEBASIC_METRICS_KEEP_LIST_REGEX"] - kappiebasicScrapeInterval := intervalHash["KAPPIEBASIC_SCRAPE_INTERVAL"] - if currentControllerType == replicasetControllerType { - // Do nothing - Kappie is not supported to be scrapped automatically outside ds. - // If needed, the customer can disable this ds target and enable rs scraping through custom config map - } else { - if advancedMode && strings.ToLower(os.Getenv("MAC")) == "true" { - UpdateScrapeIntervalConfig(kappieBasicDefaultFileDs, kappiebasicScrapeInterval) - if exists && kappiebasicMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(kappieBasicDefaultFileDs, kappiebasicMetricsKeepListRegex) - } - contents, err := os.ReadFile(kappieBasicDefaultFileDs) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(kappieBasicDefaultFileDs, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, kappieBasicDefaultFileDs) - } - } - } - } - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_NETWORKOBSERVABILITYRETINA_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - networkobservabilityRetinaMetricsKeepListRegex, exists := regexHash["NETWORKOBSERVABILITYRETINA_METRICS_KEEP_LIST_REGEX"] - networkobservabilityRetinaScrapeInterval, intervalExists := intervalHash["NETWORKOBSERVABILITYRETINA_SCRAPE_INTERVAL"] - if currentControllerType == replicasetControllerType { - // Do nothing - Network observability Retina is not supported to be scrapped automatically outside ds. - // If needed, the customer can disable this ds target and enable rs scraping through custom config map - } else { - if advancedMode && strings.ToLower(os.Getenv("MAC")) == "true" { - if intervalExists { - UpdateScrapeIntervalConfig(networkObservabilityRetinaDefaultFileDs, networkobservabilityRetinaScrapeInterval) - } - if exists && networkobservabilityRetinaMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(networkObservabilityRetinaDefaultFileDs, networkobservabilityRetinaMetricsKeepListRegex) - } - contents, err := os.ReadFile(networkObservabilityRetinaDefaultFileDs) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(networkObservabilityRetinaDefaultFileDs, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, networkObservabilityRetinaDefaultFileDs) - } - } - } - } - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_NETWORKOBSERVABILITYHUBBLE_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - networkobservabilityHubbleMetricsKeepListRegex, exists := regexHash["NETWORKOBSERVABILITYHUBBLE_METRICS_KEEP_LIST_REGEX"] - networkobservabilityHubbleScrapeInterval, intervalExists := intervalHash["NETWORKOBSERVABILITYHUBBLE_SCRAPE_INTERVAL"] - if currentControllerType == replicasetControllerType { - // Do nothing - Network observability Hubble is not supported to be scrapped automatically outside ds. - // If needed, the customer can disable this ds target and enable rs scraping through custom config map - } else { - if advancedMode && strings.ToLower(os.Getenv("MAC")) == "true" && strings.ToLower(os.Getenv("OS_TYPE")) == "linux" { - if intervalExists { - UpdateScrapeIntervalConfig(networkObservabilityHubbleDefaultFileDs, networkobservabilityHubbleScrapeInterval) - } - if exists && networkobservabilityHubbleMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(networkObservabilityHubbleDefaultFileDs, networkobservabilityHubbleMetricsKeepListRegex) - } - contents, err := os.ReadFile(networkObservabilityHubbleDefaultFileDs) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(networkObservabilityHubbleDefaultFileDs, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, networkObservabilityHubbleDefaultFileDs) - } - } - } - } - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_NETWORKOBSERVABILITYCILIUM_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - networkobservabilityCiliumMetricsKeepListRegex, exists := regexHash["NETWORKOBSERVABILITYCILIUM_METRICS_KEEP_LIST_REGEX"] - networkobservabilityCiliumScrapeInterval, intervalExists := intervalHash["NETWORKOBSERVABILITYCILIUM_SCRAPE_INTERVAL"] - if currentControllerType == replicasetControllerType { - // Do nothing - Network observability Cilium is not supported to be scrapped automatically outside ds. - // If needed, the customer can disable this ds target and enable rs scraping through custom config map - } else { - if advancedMode && strings.ToLower(os.Getenv("MAC")) == "true" && strings.ToLower(os.Getenv("OS_TYPE")) == "linux" { - if intervalExists { - UpdateScrapeIntervalConfig(networkObservabilityCiliumDefaultFileDs, networkobservabilityCiliumScrapeInterval) - } - if exists && networkobservabilityCiliumMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(networkObservabilityCiliumDefaultFileDs, networkobservabilityCiliumMetricsKeepListRegex) - } - contents, err := os.ReadFile(networkObservabilityCiliumDefaultFileDs) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(networkObservabilityCiliumDefaultFileDs, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, networkObservabilityCiliumDefaultFileDs) - } - } - } - } - } - - // Add ztunnel support - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_ZTUNNEL_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - ztunnelMetricsKeepListRegex, exists := regexHash["ZTUNNEL_METRICS_KEEP_LIST_REGEX"] - ztunnelScrapeInterval, intervalExists := intervalHash["ZTUNNEL_SCRAPE_INTERVAL"] - if currentControllerType == replicasetControllerType && strings.ToLower(os.Getenv("OS_TYPE")) == "linux" { - fullZtunnelPath := fmt.Sprintf("%s%s", defaultPromConfigPathPrefix, ztunnelDefaultFile) - if intervalExists { - UpdateScrapeIntervalConfig(fullZtunnelPath, ztunnelScrapeInterval) - } - if exists && ztunnelMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(fullZtunnelPath, ztunnelMetricsKeepListRegex) - } - contents, err := os.ReadFile(fullZtunnelPath) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(fullZtunnelPath, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, fullZtunnelPath) - } - } - } - } - - // Add istio-cni support - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_ISTIOCNI_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - istiocniMetricsKeepListRegex, exists := regexHash["ISTIOCNI_METRICS_KEEP_LIST_REGEX"] - istiocniScrapeInterval, intervalExists := intervalHash["ISTIOCNI_SCRAPE_INTERVAL"] - if currentControllerType == replicasetControllerType && strings.ToLower(os.Getenv("OS_TYPE")) == "linux" { - fullIstioCniPath := fmt.Sprintf("%s%s", defaultPromConfigPathPrefix, istioCniDefaultFile) - if intervalExists { - UpdateScrapeIntervalConfig(fullIstioCniPath, istiocniScrapeInterval) - } - if exists && istiocniMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(fullIstioCniPath, istiocniMetricsKeepListRegex) - } - contents, err := os.ReadFile(fullIstioCniPath) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(fullIstioCniPath, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, fullIstioCniPath) - } - } - } - } - - // Add waypoint-proxy support - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_WAYPOINT_PROXY_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - waypointproxyMetricsKeepListRegex, exists := regexHash["WAYPOINT_PROXY_METRICS_KEEP_LIST_REGEX"] - waypointproxyScrapeInterval, intervalExists := intervalHash["WAYPOINT_PROXY_SCRAPE_INTERVAL"] - if currentControllerType == replicasetControllerType && strings.ToLower(os.Getenv("OS_TYPE")) == "linux" { - fullWaypointProxyPath := fmt.Sprintf("%s%s", defaultPromConfigPathPrefix, waypointProxyDefaultFile) - if intervalExists { - UpdateScrapeIntervalConfig(fullWaypointProxyPath, waypointproxyScrapeInterval) - } - if exists && waypointproxyMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(fullWaypointProxyPath, waypointproxyMetricsKeepListRegex) - } - contents, err := os.ReadFile(fullWaypointProxyPath) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(fullWaypointProxyPath, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, fullWaypointProxyPath) - } - } - } - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_COLLECTOR_HEALTH_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - prometheusCollectorHealthInterval, intervalExists := intervalHash["PROMETHEUS_COLLECTOR_HEALTH_SCRAPE_INTERVAL"] - if intervalExists { - UpdateScrapeIntervalConfig(prometheusCollectorHealthDefaultFile, prometheusCollectorHealthInterval) - } - defaultConfigs = append(defaultConfigs, prometheusCollectorHealthDefaultFile) - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_WINDOWSEXPORTER_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - winexporterMetricsKeepListRegex, exists := regexHash["WINDOWSEXPORTER_METRICS_KEEP_LIST_REGEX"] - windowsexporterScrapeInterval, intervalExists := intervalHash["WINDOWSEXPORTER_SCRAPE_INTERVAL"] - if currentControllerType == replicasetControllerType && !advancedMode && strings.ToLower(os.Getenv("OS_TYPE")) == "linux" { - if intervalExists { - UpdateScrapeIntervalConfig(windowsExporterDefaultRsSimpleFile, windowsexporterScrapeInterval) - } - if exists && winexporterMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(windowsExporterDefaultRsSimpleFile, winexporterMetricsKeepListRegex) - } - contents, err := os.ReadFile(windowsExporterDefaultRsSimpleFile) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(windowsExporterDefaultRsSimpleFile, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, windowsExporterDefaultRsSimpleFile) - } - } - } else if currentControllerType == daemonsetControllerType && advancedMode && windowsDaemonset && strings.ToLower(os.Getenv("OS_TYPE")) == "windows" { - if intervalExists { - UpdateScrapeIntervalConfig(windowsExporterDefaultDsFile, windowsexporterScrapeInterval) - } - if exists && winexporterMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(windowsExporterDefaultDsFile, winexporterMetricsKeepListRegex) - } - contents, err := os.ReadFile(windowsExporterDefaultDsFile) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(windowsExporterDefaultDsFile, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, windowsExporterDefaultDsFile) - } - } - } - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_WINDOWSKUBEPROXY_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - winkubeproxyMetricsKeepListRegex, exists := regexHash["WINDOWSKUBEPROXY_METRICS_KEEP_LIST_REGEX"] - windowskubeproxyScrapeInterval, intervalExists := intervalHash["WINDOWSKUBEPROXY_SCRAPE_INTERVAL"] - if currentControllerType == replicasetControllerType && !advancedMode && strings.ToLower(os.Getenv("OS_TYPE")) == "linux" { - if intervalExists { - UpdateScrapeIntervalConfig(windowsKubeProxyDefaultFileRsSimpleFile, windowskubeproxyScrapeInterval) - } - if exists && winkubeproxyMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(windowsKubeProxyDefaultFileRsSimpleFile, winkubeproxyMetricsKeepListRegex) - } - contents, err := os.ReadFile(windowsKubeProxyDefaultFileRsSimpleFile) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(windowsKubeProxyDefaultFileRsSimpleFile, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, windowsKubeProxyDefaultFileRsSimpleFile) - } - } - } else if currentControllerType == daemonsetControllerType && advancedMode && windowsDaemonset && strings.ToLower(os.Getenv("OS_TYPE")) == "windows" { - if intervalExists { - UpdateScrapeIntervalConfig(windowsKubeProxyDefaultDsFile, windowskubeproxyScrapeInterval) - } - if exists && winkubeproxyMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(windowsKubeProxyDefaultDsFile, winkubeproxyMetricsKeepListRegex) - } - contents, err := os.ReadFile(windowsKubeProxyDefaultDsFile) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(windowsKubeProxyDefaultDsFile, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, windowsKubeProxyDefaultDsFile) - } - } - } + currentControllerType := strings.TrimSpace(os.Getenv("CONTROLLER_TYPE")) + if isConfigReaderSidecar() { + currentControllerType = shared.ControllerType.ReplicaSet } + osType := strings.ToLower(os.Getenv("OS_TYPE")) - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_POD_ANNOTATION_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" && currentControllerType == replicasetControllerType { - if podannotationNamespacesRegex, exists := os.LookupEnv("AZMON_PROMETHEUS_POD_ANNOTATION_NAMESPACES_REGEX"); exists { - podannotationMetricsKeepListRegex := regexHash["POD_ANNOTATION_METRICS_KEEP_LIST_REGEX"] - podannotationScrapeInterval, intervalExists := intervalHash["POD_ANNOTATION_SCRAPE_INTERVAL"] - - if intervalExists { - UpdateScrapeIntervalConfig(podAnnotationsDefaultFile, podannotationScrapeInterval) - } - if podannotationMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(podAnnotationsDefaultFile, podannotationMetricsKeepListRegex) - } - // Trim the first and last escaped quotes if they exist - if len(podannotationNamespacesRegex) > 1 && podannotationNamespacesRegex[0] == '"' && podannotationNamespacesRegex[len(podannotationNamespacesRegex)-1] == '"' { - podannotationNamespacesRegex = podannotationNamespacesRegex[1 : len(podannotationNamespacesRegex)-1] - } - // Additional trim to remove single quotes if present - podannotationNamespacesRegex = strings.Trim(podannotationNamespacesRegex, "'") - - if podannotationNamespacesRegex != "" { - relabelConfig := []map[string]interface{}{ - {"source_labels": []string{"__meta_kubernetes_namespace"}, "action": "keep", "regex": podannotationNamespacesRegex}, - } - AppendRelabelConfig(podAnnotationsDefaultFile, relabelConfig, podannotationNamespacesRegex) - } - defaultConfigs = append(defaultConfigs, podAnnotationsDefaultFile) - } - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_ACSTORCAPACITYPROVISIONER_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" && currentControllerType == replicasetControllerType { - acstorCapacityProvisionerKeepListRegex, exists := regexHash["ACSTORCAPACITYPROVISONER_KEEP_LIST_REGEX"] - acstorCapacityProvisionerScrapeInterval, intervalExists := intervalHash["ACSTORCAPACITYPROVISIONER_SCRAPE_INTERVAL"] - if intervalExists { - UpdateScrapeIntervalConfig(acstorCapacityProvisionerDefaultFile, acstorCapacityProvisionerScrapeInterval) - } - if exists && acstorCapacityProvisionerKeepListRegex != "" { - AppendMetricRelabelConfig(acstorCapacityProvisionerDefaultFile, acstorCapacityProvisionerKeepListRegex) - } - defaultConfigs = append(defaultConfigs, acstorCapacityProvisionerDefaultFile) - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_ACSTORMETRICSEXPORTER_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" && currentControllerType == replicasetControllerType { - acstorMetricsExporterKeepListRegex, exists := regexHash["ACSTORMETRICSEXPORTER_KEEP_LIST_REGEX"] - acstorMetricsExporterScrapeInterval, intervalExists := intervalHash["ACSTORMETRICSEXPORTER_SCRAPE_INTERVAL"] - if intervalExists { - UpdateScrapeIntervalConfig(acstorMetricsExporterDefaultFile, acstorMetricsExporterScrapeInterval) - } - if exists && acstorMetricsExporterKeepListRegex != "" { - AppendMetricRelabelConfig(acstorMetricsExporterDefaultFile, acstorMetricsExporterKeepListRegex) - } - defaultConfigs = append(defaultConfigs, acstorMetricsExporterDefaultFile) - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_LOCALCSIDRIVER_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" && currentControllerType == replicasetControllerType { - LocalCSIDriverKeepListRegex, exists := regexHash["LOCALCSIDRIVER_KEEP_LIST_REGEX"] - LocalCSIDriverScrapeInterval, intervalExists := intervalHash["LOCALCSIDRIVER_SCRAPE_INTERVAL"] - if intervalExists { - UpdateScrapeIntervalConfig(LocalCSIDriverDefaultFile, LocalCSIDriverScrapeInterval) - } - if exists && LocalCSIDriverKeepListRegex != "" { - AppendMetricRelabelConfig(LocalCSIDriverDefaultFile, LocalCSIDriverKeepListRegex) + for _, job := range shared.DefaultScrapeJobs { + if job.Enabled && job.ControllerType == currentControllerType && job.OSType == osType { + processDefaultJob(job) + defaultConfigs = append(defaultConfigs, scrapeConfigDefinitionPathPrefix+job.ScrapeConfigDefinitionFile) } - defaultConfigs = append(defaultConfigs, LocalCSIDriverDefaultFile) } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_DCGMEXPORTER_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - dcgmexporterMetricsKeepListRegex, exists := regexHash["DCGMEXPORTER_METRICS_KEEP_LIST_REGEX"] - dcgmexporterScrapeInterval := intervalHash["DCGMEXPORTER_SCRAPE_INTERVAL"] - if currentControllerType == replicasetControllerType && strings.ToLower(os.Getenv("OS_TYPE")) == "linux" { - UpdateScrapeIntervalConfig(dcgmExporterDefaultFile, dcgmexporterScrapeInterval) - if exists && dcgmexporterMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(dcgmExporterDefaultFile, dcgmexporterMetricsKeepListRegex) - } - defaultConfigs = append(defaultConfigs, dcgmExporterDefaultFile) - } - } - mergedDefaultConfigs = mergeDefaultScrapeConfigs(defaultConfigs) - // if mergedDefaultConfigs != nil { - // fmt.Printf("Merged default scrape targets: %v\n", mergedDefaultConfigs) - // } } -func populateDefaultPrometheusConfigWithOperator() { - defaultConfigs := []string{} - - envControllerType := os.Getenv("CONTROLLER_TYPE") - currentControllerType := "" - if envControllerType != "" { - currentControllerType = strings.TrimSpace(strings.ToLower(envControllerType)) - } - - // Default values - advancedMode := false - windowsDaemonset := false - - envMode := os.Getenv("MODE") - currentMode := "default" - if envMode != "" { - currentMode = strings.TrimSpace(strings.ToLower(envMode)) - } - if currentMode == "advanced" { - advancedMode = true - } - - // Get if windowsdaemonset is enabled or not (i.e., WINMODE env = advanced or not...) - winMode := "default" - if envWinMode := os.Getenv("WINMODE"); envWinMode != "" { - winMode = strings.TrimSpace(strings.ToLower(envWinMode)) - } - if winMode == "advanced" { - windowsDaemonset = true - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_KUBELET_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - kubeletMetricsKeepListRegex, exists := regexHash["KUBELET_METRICS_KEEP_LIST_REGEX"] - kubeletScrapeInterval := intervalHash["KUBELET_SCRAPE_INTERVAL"] - if isConfigReaderSidecar() || currentControllerType == replicasetControllerType { - if !advancedMode { - UpdateScrapeIntervalConfig(kubeletDefaultFileRsSimple, kubeletScrapeInterval) - if exists && kubeletMetricsKeepListRegex != "" { - log.Printf("Using regex for Kubelet: %s\n", kubeletMetricsKeepListRegex) - AppendMetricRelabelConfig(kubeletDefaultFileRsSimple, kubeletMetricsKeepListRegex) - } - defaultConfigs = append(defaultConfigs, kubeletDefaultFileRsSimple) - } else if windowsDaemonset && sendDSUpMetric { - UpdateScrapeIntervalConfig(kubeletDefaultFileRsAdvancedWindowsDaemonset, kubeletScrapeInterval) - defaultConfigs = append(defaultConfigs, kubeletDefaultFileRsAdvancedWindowsDaemonset) - } else if sendDSUpMetric { - UpdateScrapeIntervalConfig(kubeletDefaultFileRsAdvanced, kubeletScrapeInterval) - defaultConfigs = append(defaultConfigs, kubeletDefaultFileRsAdvanced) - } - } else { - if advancedMode && currentControllerType == daemonsetControllerType && (windowsDaemonset || strings.ToLower(os.Getenv("OS_TYPE")) == "linux") { - UpdateScrapeIntervalConfig(kubeletDefaultFileDs, kubeletScrapeInterval) - if exists && kubeletMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(kubeletDefaultFileDs, kubeletMetricsKeepListRegex) - } - contents, err := os.ReadFile(kubeletDefaultFileDs) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$OS_TYPE$$", os.Getenv("OS_TYPE"))) - err = os.WriteFile(kubeletDefaultFileDs, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, kubeletDefaultFileDs) - } - } - } - } - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_COREDNS_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" && (isConfigReaderSidecar() || currentControllerType == replicasetControllerType) { - corednsMetricsKeepListRegex, exists := regexHash["COREDNS_METRICS_KEEP_LIST_REGEX"] - corednsScrapeInterval, intervalExists := intervalHash["COREDNS_SCRAPE_INTERVAL"] - if intervalExists { - UpdateScrapeIntervalConfig(coreDNSDefaultFile, corednsScrapeInterval) - } - if exists && corednsMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(coreDNSDefaultFile, corednsMetricsKeepListRegex) - } - defaultConfigs = append(defaultConfigs, coreDNSDefaultFile) - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_CADVISOR_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - cadvisorMetricsKeepListRegex, exists := regexHash["CADVISOR_METRICS_KEEP_LIST_REGEX"] - cadvisorScrapeInterval, intervalExists := intervalHash["CADVISOR_SCRAPE_INTERVAL"] - if intervalExists { - if isConfigReaderSidecar() || currentControllerType == replicasetControllerType { - if !advancedMode { - UpdateScrapeIntervalConfig(cadvisorDefaultFileRsSimple, cadvisorScrapeInterval) - if exists && cadvisorMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(cadvisorDefaultFileRsSimple, cadvisorMetricsKeepListRegex) - } - defaultConfigs = append(defaultConfigs, cadvisorDefaultFileRsSimple) - } else if sendDSUpMetric { - UpdateScrapeIntervalConfig(cadvisorDefaultFileRsAdvanced, cadvisorScrapeInterval) - defaultConfigs = append(defaultConfigs, cadvisorDefaultFileRsAdvanced) - } - } else { - if advancedMode && strings.ToLower(os.Getenv("OS_TYPE")) == "linux" && currentControllerType == daemonsetControllerType { - UpdateScrapeIntervalConfig(cadvisorDefaultFileDs, cadvisorScrapeInterval) - if exists && cadvisorMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(cadvisorDefaultFileDs, cadvisorMetricsKeepListRegex) - } - contents, err := os.ReadFile(cadvisorDefaultFileDs) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(cadvisorDefaultFileDs, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, cadvisorDefaultFileDs) - } - } - } - } - } - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_KUBEPROXY_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" && (isConfigReaderSidecar() || currentControllerType == replicasetControllerType) { - kubeproxyMetricsKeepListRegex, exists := regexHash["KUBEPROXY_METRICS_KEEP_LIST_REGEX"] - kubeproxyScrapeInterval, intervalExists := intervalHash["KUBEPROXY_SCRAPE_INTERVAL"] - if intervalExists { - UpdateScrapeIntervalConfig(kubeProxyDefaultFile, kubeproxyScrapeInterval) - } - if exists && kubeproxyMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(kubeProxyDefaultFile, kubeproxyMetricsKeepListRegex) - } - defaultConfigs = append(defaultConfigs, kubeProxyDefaultFile) - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_APISERVER_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" && (isConfigReaderSidecar() || currentControllerType == replicasetControllerType) { - apiserverMetricsKeepListRegex, exists := regexHash["APISERVER_METRICS_KEEP_LIST_REGEX"] - apiserverScrapeInterval, intervalExists := intervalHash["APISERVER_SCRAPE_INTERVAL"] - if intervalExists { - UpdateScrapeIntervalConfig(apiserverDefaultFile, apiserverScrapeInterval) - } - if exists && apiserverMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(apiserverDefaultFile, apiserverMetricsKeepListRegex) - } - defaultConfigs = append(defaultConfigs, apiserverDefaultFile) - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_KUBESTATE_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" && (isConfigReaderSidecar() || currentControllerType == replicasetControllerType) { - kubestateMetricsKeepListRegex, exists := regexHash["KUBESTATE_METRICS_KEEP_LIST_REGEX"] - kubestateScrapeInterval, intervalExists := intervalHash["KUBESTATE_SCRAPE_INTERVAL"] - - if intervalExists { - UpdateScrapeIntervalConfig(kubeStateDefaultFile, kubestateScrapeInterval) - } - if exists && kubestateMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(kubeStateDefaultFile, kubestateMetricsKeepListRegex) - } - contents, err := os.ReadFile(kubeStateDefaultFile) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$KUBE_STATE_NAME$$", os.Getenv("KUBE_STATE_NAME"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$POD_NAMESPACE$$", os.Getenv("POD_NAMESPACE"))) - err = os.WriteFile(kubeStateDefaultFile, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, kubeStateDefaultFile) - } - } - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_NODEEXPORTER_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - nodeexporterMetricsKeepListRegex, exists := regexHash["NODEEXPORTER_METRICS_KEEP_LIST_REGEX"] - nodeexporterScrapeInterval := intervalHash["NODEEXPORTER_SCRAPE_INTERVAL"] - if isConfigReaderSidecar() || currentControllerType == replicasetControllerType { - if advancedMode && sendDSUpMetric { - UpdateScrapeIntervalConfig(nodeExporterDefaultFileRsAdvanced, nodeexporterScrapeInterval) - contents, err := os.ReadFile(nodeExporterDefaultFileRsAdvanced) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_EXPORTER_NAME$$", os.Getenv("NODE_EXPORTER_NAME"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$POD_NAMESPACE$$", os.Getenv("POD_NAMESPACE"))) - err = os.WriteFile(nodeExporterDefaultFileRsAdvanced, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, nodeExporterDefaultFileRsAdvanced) - } - } - } else if !advancedMode { - UpdateScrapeIntervalConfig(nodeExporterDefaultFileRsSimple, nodeexporterScrapeInterval) - if exists && nodeexporterMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(nodeExporterDefaultFileRsSimple, nodeexporterMetricsKeepListRegex) - } - contents, err := os.ReadFile(nodeExporterDefaultFileRsSimple) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_EXPORTER_NAME$$", os.Getenv("NODE_EXPORTER_NAME"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$POD_NAMESPACE$$", os.Getenv("POD_NAMESPACE"))) - err = os.WriteFile(nodeExporterDefaultFileRsSimple, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, nodeExporterDefaultFileRsSimple) - } - } - } - } else { - if advancedMode && strings.ToLower(os.Getenv("OS_TYPE")) == "linux" && currentControllerType == daemonsetControllerType { - UpdateScrapeIntervalConfig(nodeExporterDefaultFileDs, nodeexporterScrapeInterval) - if exists && nodeexporterMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(nodeExporterDefaultFileDs, nodeexporterMetricsKeepListRegex) - } - contents, err := os.ReadFile(nodeExporterDefaultFileDs) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_EXPORTER_TARGETPORT$$", os.Getenv("NODE_EXPORTER_TARGETPORT"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(nodeExporterDefaultFileDs, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, nodeExporterDefaultFileDs) - } - } - } - } - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_KAPPIEBASIC_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - kappiebasicMetricsKeepListRegex, exists := regexHash["KAPPIEBASIC_METRICS_KEEP_LIST_REGEX"] - kappiebasicScrapeInterval := intervalHash["KAPPIEBASIC_SCRAPE_INTERVAL"] - if isConfigReaderSidecar() || currentControllerType == replicasetControllerType { - // Do nothing - Kappie is not supported to be scrapped automatically outside ds. - // If needed, the customer can disable this ds target and enable rs scraping through custom config map - } else { - if currentControllerType == daemonsetControllerType && advancedMode && strings.ToLower(os.Getenv("MAC")) == "true" { - UpdateScrapeIntervalConfig(kappieBasicDefaultFileDs, kappiebasicScrapeInterval) - if exists && kappiebasicMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(kappieBasicDefaultFileDs, kappiebasicMetricsKeepListRegex) - } - contents, err := os.ReadFile(kappieBasicDefaultFileDs) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(kappieBasicDefaultFileDs, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, kappieBasicDefaultFileDs) - } - } - } - } - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_NETWORKOBSERVABILITYRETINA_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - networkobservabilityRetinaMetricsKeepListRegex, exists := regexHash["NETWORKOBSERVABILITYRETINA_METRICS_KEEP_LIST_REGEX"] - networkobservabilityRetinaScrapeInterval, intervalExists := intervalHash["NETWORKOBSERVABILITYRETINA_SCRAPE_INTERVAL"] - if isConfigReaderSidecar() || currentControllerType == replicasetControllerType { - // Do nothing - Network observability Retina is not supported to be scrapped automatically outside ds. - // If needed, the customer can disable this ds target and enable rs scraping through custom config map - } else { - if advancedMode && strings.ToLower(os.Getenv("MAC")) == "true" { - if intervalExists { - UpdateScrapeIntervalConfig(networkObservabilityRetinaDefaultFileDs, networkobservabilityRetinaScrapeInterval) - } - if exists && networkobservabilityRetinaMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(networkObservabilityRetinaDefaultFileDs, networkobservabilityRetinaMetricsKeepListRegex) - } - contents, err := os.ReadFile(networkObservabilityRetinaDefaultFileDs) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(networkObservabilityRetinaDefaultFileDs, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, networkObservabilityRetinaDefaultFileDs) - } - } - } - } - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_NETWORKOBSERVABILITYHUBBLE_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - networkobservabilityHubbleMetricsKeepListRegex, exists := regexHash["NETWORKOBSERVABILITYHUBBLE_METRICS_KEEP_LIST_REGEX"] - networkobservabilityHubbleScrapeInterval, intervalExists := intervalHash["NETWORKOBSERVABILITYHUBBLE_SCRAPE_INTERVAL"] - if isConfigReaderSidecar() || currentControllerType == replicasetControllerType { - // Do nothing - Network observability Hubble is not supported to be scrapped automatically outside ds. - // If needed, the customer can disable this ds target and enable rs scraping through custom config map - } else { - if advancedMode && strings.ToLower(os.Getenv("MAC")) == "true" && strings.ToLower(os.Getenv("OS_TYPE")) == "linux" { - if intervalExists { - UpdateScrapeIntervalConfig(networkObservabilityHubbleDefaultFileDs, networkobservabilityHubbleScrapeInterval) - } - if exists && networkobservabilityHubbleMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(networkObservabilityHubbleDefaultFileDs, networkobservabilityHubbleMetricsKeepListRegex) - } - contents, err := os.ReadFile(networkObservabilityHubbleDefaultFileDs) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(networkObservabilityHubbleDefaultFileDs, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, networkObservabilityHubbleDefaultFileDs) - } - } - } - } - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_NETWORKOBSERVABILITYCILIUM_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - networkobservabilityCiliumMetricsKeepListRegex, exists := regexHash["NETWORKOBSERVABILITYCILIUM_METRICS_KEEP_LIST_REGEX"] - networkobservabilityCiliumScrapeInterval, intervalExists := intervalHash["NETWORKOBSERVABILITYCILIUM_SCRAPE_INTERVAL"] - if isConfigReaderSidecar() || currentControllerType == replicasetControllerType { - // Do nothing - Network observability Cilium is not supported to be scrapped automatically outside ds. - // If needed, the customer can disable this ds target and enable rs scraping through custom config map - } else { - if advancedMode && strings.ToLower(os.Getenv("MAC")) == "true" && strings.ToLower(os.Getenv("OS_TYPE")) == "linux" { - if intervalExists { - UpdateScrapeIntervalConfig(networkObservabilityCiliumDefaultFileDs, networkobservabilityCiliumScrapeInterval) - } - if exists && networkobservabilityCiliumMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(networkObservabilityCiliumDefaultFileDs, networkobservabilityCiliumMetricsKeepListRegex) - } - contents, err := os.ReadFile(networkObservabilityCiliumDefaultFileDs) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(networkObservabilityCiliumDefaultFileDs, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, networkObservabilityCiliumDefaultFileDs) - } - } - } - } - } - - // Add ztunnel support - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_ZTUNNEL_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - ztunnelMetricsKeepListRegex, exists := regexHash["ZTUNNEL_METRICS_KEEP_LIST_REGEX"] - ztunnelScrapeInterval, intervalExists := intervalHash["ZTUNNEL_SCRAPE_INTERVAL"] - if isConfigReaderSidecar() || (currentControllerType == replicasetControllerType && strings.ToLower(os.Getenv("OS_TYPE")) == "linux") { - fullZtunnelPath := fmt.Sprintf("%s%s", defaultPromConfigPathPrefix, ztunnelDefaultFile) - if intervalExists { - UpdateScrapeIntervalConfig(fullZtunnelPath, ztunnelScrapeInterval) - } - if exists && ztunnelMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(fullZtunnelPath, ztunnelMetricsKeepListRegex) - } - contents, err := os.ReadFile(fullZtunnelPath) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(fullZtunnelPath, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, fullZtunnelPath) - } - } - } - } - - // Add istio-cni support - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_ISTIOCNI_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - istiocniMetricsKeepListRegex, exists := regexHash["ISTIOCNI_METRICS_KEEP_LIST_REGEX"] - istiocniScrapeInterval, intervalExists := intervalHash["ISTIOCNI_SCRAPE_INTERVAL"] - if isConfigReaderSidecar() || (currentControllerType == replicasetControllerType && strings.ToLower(os.Getenv("OS_TYPE")) == "linux") { - fullIstioCniPath := fmt.Sprintf("%s%s", defaultPromConfigPathPrefix, istioCniDefaultFile) - if intervalExists { - UpdateScrapeIntervalConfig(fullIstioCniPath, istiocniScrapeInterval) - } - if exists && istiocniMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(fullIstioCniPath, istiocniMetricsKeepListRegex) - } - contents, err := os.ReadFile(fullIstioCniPath) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(fullIstioCniPath, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, fullIstioCniPath) - } - } - } - } - - // Add waypoint-proxy support - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_WAYPOINT_PROXY_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - waypointproxyMetricsKeepListRegex, exists := regexHash["WAYPOINT_PROXY_METRICS_KEEP_LIST_REGEX"] - waypointproxyScrapeInterval, intervalExists := intervalHash["WAYPOINT_PROXY_SCRAPE_INTERVAL"] - if isConfigReaderSidecar() || (currentControllerType == replicasetControllerType && strings.ToLower(os.Getenv("OS_TYPE")) == "linux") { - fullWaypointProxyPath := fmt.Sprintf("%s%s", defaultPromConfigPathPrefix, waypointProxyDefaultFile) - if intervalExists { - UpdateScrapeIntervalConfig(fullWaypointProxyPath, waypointproxyScrapeInterval) - } - if exists && waypointproxyMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(fullWaypointProxyPath, waypointproxyMetricsKeepListRegex) - } - contents, err := os.ReadFile(fullWaypointProxyPath) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(fullWaypointProxyPath, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, fullWaypointProxyPath) - } - } - } - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_COLLECTOR_HEALTH_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - prometheusCollectorHealthInterval, intervalExists := intervalHash["PROMETHEUS_COLLECTOR_HEALTH_SCRAPE_INTERVAL"] - if intervalExists { - UpdateScrapeIntervalConfig(prometheusCollectorHealthDefaultFile, prometheusCollectorHealthInterval) - } - defaultConfigs = append(defaultConfigs, prometheusCollectorHealthDefaultFile) - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_WINDOWSEXPORTER_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - winexporterMetricsKeepListRegex, exists := regexHash["WINDOWSEXPORTER_METRICS_KEEP_LIST_REGEX"] - windowsexporterScrapeInterval, intervalExists := intervalHash["WINDOWSEXPORTER_SCRAPE_INTERVAL"] - // Not adding the isConfigReaderSidecar check instead of replicaset check since this is legacy 1P chart path and not relevant anymore. - if currentControllerType == replicasetControllerType && !advancedMode && strings.ToLower(os.Getenv("OS_TYPE")) == "linux" { - if intervalExists { - UpdateScrapeIntervalConfig(windowsExporterDefaultRsSimpleFile, windowsexporterScrapeInterval) - } - if exists && winexporterMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(windowsExporterDefaultRsSimpleFile, winexporterMetricsKeepListRegex) - } - contents, err := os.ReadFile(windowsExporterDefaultRsSimpleFile) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(windowsExporterDefaultRsSimpleFile, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, windowsExporterDefaultRsSimpleFile) - } - } - } else if currentControllerType == daemonsetControllerType && advancedMode && windowsDaemonset && strings.ToLower(os.Getenv("OS_TYPE")) == "windows" { - if intervalExists { - UpdateScrapeIntervalConfig(windowsExporterDefaultDsFile, windowsexporterScrapeInterval) - } - if exists && winexporterMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(windowsExporterDefaultDsFile, winexporterMetricsKeepListRegex) - } - contents, err := os.ReadFile(windowsExporterDefaultDsFile) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(windowsExporterDefaultDsFile, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, windowsExporterDefaultDsFile) - } - } - } - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_WINDOWSKUBEPROXY_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - winkubeproxyMetricsKeepListRegex, exists := regexHash["WINDOWSKUBEPROXY_METRICS_KEEP_LIST_REGEX"] - windowskubeproxyScrapeInterval, intervalExists := intervalHash["WINDOWSKUBEPROXY_SCRAPE_INTERVAL"] - // Not adding the isConfigReaderSidecar check instead of replicaset check since this is legacy 1P chart path and not relevant anymore. - if currentControllerType == replicasetControllerType && !advancedMode && strings.ToLower(os.Getenv("OS_TYPE")) == "linux" { - if intervalExists { - UpdateScrapeIntervalConfig(windowsKubeProxyDefaultFileRsSimpleFile, windowskubeproxyScrapeInterval) - } - if exists && winkubeproxyMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(windowsKubeProxyDefaultFileRsSimpleFile, winkubeproxyMetricsKeepListRegex) - } - contents, err := os.ReadFile(windowsKubeProxyDefaultFileRsSimpleFile) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(windowsKubeProxyDefaultFileRsSimpleFile, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, windowsKubeProxyDefaultFileRsSimpleFile) - } - } - } else if currentControllerType == daemonsetControllerType && advancedMode && windowsDaemonset && strings.ToLower(os.Getenv("OS_TYPE")) == "windows" { - if intervalExists { - UpdateScrapeIntervalConfig(windowsKubeProxyDefaultDsFile, windowskubeproxyScrapeInterval) - } - if exists && winkubeproxyMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(windowsKubeProxyDefaultDsFile, winkubeproxyMetricsKeepListRegex) - } - contents, err := os.ReadFile(windowsKubeProxyDefaultDsFile) - if err == nil { - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_IP$$", os.Getenv("NODE_IP"))) - contents = []byte(strings.ReplaceAll(string(contents), "$$NODE_NAME$$", os.Getenv("NODE_NAME"))) - err = os.WriteFile(windowsKubeProxyDefaultDsFile, contents, 0644) - if err == nil { - defaultConfigs = append(defaultConfigs, windowsKubeProxyDefaultDsFile) - } - } - } - } - - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_POD_ANNOTATION_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" && (isConfigReaderSidecar() || currentControllerType == replicasetControllerType) { - if podannotationNamespacesRegex, exists := os.LookupEnv("AZMON_PROMETHEUS_POD_ANNOTATION_NAMESPACES_REGEX"); exists { - podannotationMetricsKeepListRegex := regexHash["POD_ANNOTATION_METRICS_KEEP_LIST_REGEX"] - podannotationScrapeInterval, intervalExists := intervalHash["POD_ANNOTATION_SCRAPE_INTERVAL"] - - if intervalExists { - UpdateScrapeIntervalConfig(podAnnotationsDefaultFile, podannotationScrapeInterval) - } - if podannotationMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(podAnnotationsDefaultFile, podannotationMetricsKeepListRegex) - } - // Trim the first and last escaped quotes if they exist - if len(podannotationNamespacesRegex) > 1 && podannotationNamespacesRegex[0] == '"' && podannotationNamespacesRegex[len(podannotationNamespacesRegex)-1] == '"' { - podannotationNamespacesRegex = podannotationNamespacesRegex[1 : len(podannotationNamespacesRegex)-1] - } - // Additional trim to remove single quotes if present - podannotationNamespacesRegex = strings.Trim(podannotationNamespacesRegex, "'") - - if podannotationNamespacesRegex != "" { - relabelConfig := []map[string]interface{}{ - {"source_labels": []string{"__meta_kubernetes_namespace"}, "action": "keep", "regex": podannotationNamespacesRegex}, - } - AppendRelabelConfig(podAnnotationsDefaultFile, relabelConfig, podannotationNamespacesRegex) - } - defaultConfigs = append(defaultConfigs, podAnnotationsDefaultFile) - } +func UpdatePlaceholders(yamlConfigFile string, placeholders []string) error { + if err := cmcommon.ReplacePlaceholders(yamlConfigFile, placeholders); err != nil { + return fmt.Errorf("UpdatePlaceholders::%w", err) } + return nil +} - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_ACSTORCAPACITYPROVISIONER_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" && (isConfigReaderSidecar() || currentControllerType == replicasetControllerType) { - acstorCapacityProvisionerKeepListRegex, exists := regexHash["ACSTORCAPACITYPROVISONER_KEEP_LIST_REGEX"] - acstorCapacityProvisionerScrapeInterval, intervalExists := intervalHash["ACSTORCAPACITYPROVISIONER_SCRAPE_INTERVAL"] - log.Printf("path %s: %s\n", "acstorCapacityProvisionerDefaultFile", acstorCapacityProvisionerDefaultFile) - if intervalExists { - UpdateScrapeIntervalConfig(acstorCapacityProvisionerDefaultFile, acstorCapacityProvisionerScrapeInterval) - } - if exists && acstorCapacityProvisionerKeepListRegex != "" { - AppendMetricRelabelConfig(acstorCapacityProvisionerDefaultFile, acstorCapacityProvisionerKeepListRegex) - } - defaultConfigs = append(defaultConfigs, acstorCapacityProvisionerDefaultFile) +func processDefaultJob(job *shared.DefaultScrapeJob) { + if job.ScrapeInterval != "" { + UpdateScrapeIntervalConfig(scrapeConfigDefinitionPathPrefix+job.ScrapeConfigDefinitionFile, job.ScrapeInterval) } - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_ACSTORMETRICSEXPORTER_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" && (isConfigReaderSidecar() || currentControllerType == replicasetControllerType) { - acstorMetricsExporterKeepListRegex, exists := regexHash["ACSTORMETRICSEXPORTER_KEEP_LIST_REGEX"] - acstorMetricsExporterScrapeInterval, intervalExists := intervalHash["ACSTORMETRICSEXPORTER_SCRAPE_INTERVAL"] - log.Printf("path %s: %s\n", "acstorMetricsExporterDefaultFile", acstorMetricsExporterDefaultFile) - if intervalExists { - UpdateScrapeIntervalConfig(acstorMetricsExporterDefaultFile, acstorMetricsExporterScrapeInterval) - } - if exists && acstorMetricsExporterKeepListRegex != "" { - AppendMetricRelabelConfig(acstorMetricsExporterDefaultFile, acstorMetricsExporterKeepListRegex) - } - defaultConfigs = append(defaultConfigs, acstorMetricsExporterDefaultFile) + if job.KeepListRegex != "" { + AppendMetricRelabelConfig(scrapeConfigDefinitionPathPrefix+job.ScrapeConfigDefinitionFile, job.KeepListRegex) } - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_LOCALCSIDRIVER_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" && (isConfigReaderSidecar() || currentControllerType == replicasetControllerType) { - LocalCSIDriverKeepListRegex, exists := regexHash["LOCALCSIDRIVER_KEEP_LIST_REGEX"] - LocalCSIDriverScrapeInterval, intervalExists := intervalHash["LOCALCSIDRIVER_SCRAPE_INTERVAL"] - log.Printf("path %s: %s\n", "LocalCSIDriverDefaultFile", LocalCSIDriverDefaultFile) - if intervalExists { - UpdateScrapeIntervalConfig(LocalCSIDriverDefaultFile, LocalCSIDriverScrapeInterval) + if job.ControllerType == shared.ControllerType.DaemonSet { + if err := UpdatePlaceholders(scrapeConfigDefinitionPathPrefix+job.ScrapeConfigDefinitionFile, []string{"NODE_IP", "NODE_NAME"}); err != nil { + log.Printf("Error updating placeholders for DaemonSet: %v\n", err) } - if exists && LocalCSIDriverKeepListRegex != "" { - AppendMetricRelabelConfig(LocalCSIDriverDefaultFile, LocalCSIDriverKeepListRegex) - } - defaultConfigs = append(defaultConfigs, LocalCSIDriverDefaultFile) } - if enabled, exists := os.LookupEnv("AZMON_PROMETHEUS_DCGMEXPORTER_SCRAPING_ENABLED"); exists && strings.ToLower(enabled) == "true" { - dcgmexporterMetricsKeepListRegex, exists := regexHash["DCGMEXPORTER_METRICS_KEEP_LIST_REGEX"] - dcgmexporterScrapeInterval := intervalHash["DCGMEXPORTER_SCRAPE_INTERVAL"] - if isConfigReaderSidecar() || currentControllerType == replicasetControllerType { - log.Printf("path %s: %s\n", "dcgmExporterDefaultFile", dcgmExporterDefaultFile) - UpdateScrapeIntervalConfig(dcgmExporterDefaultFile, dcgmexporterScrapeInterval) - if exists && dcgmexporterMetricsKeepListRegex != "" { - AppendMetricRelabelConfig(dcgmExporterDefaultFile, dcgmexporterMetricsKeepListRegex) - } - defaultConfigs = append(defaultConfigs, dcgmExporterDefaultFile) + if job.PlaceholderNames != nil { + if err := UpdatePlaceholders(scrapeConfigDefinitionPathPrefix+job.ScrapeConfigDefinitionFile, job.PlaceholderNames); err != nil { + log.Printf("Error updating placeholders: %v\n", err) } } - - mergedDefaultConfigs = mergeDefaultScrapeConfigs(defaultConfigs) - // if mergedDefaultConfigs != nil { - // fmt.Printf("Merged default scrape targets: %v\n", mergedDefaultConfigs) - // } } func mergeDefaultScrapeConfigs(defaultScrapeConfigs []string) map[interface{}]interface{} { - mergedDefaultConfigs := make(map[interface{}]interface{}) - if len(defaultScrapeConfigs) > 0 { mergedDefaultConfigs["scrape_configs"] = make([]interface{}, 0) @@ -1385,62 +134,20 @@ func mergeDefaultScrapeConfigs(defaultScrapeConfigs []string) map[interface{}]in } func loadYAMLFromFile(filename string) (map[interface{}]interface{}, error) { - fileContent, err := os.ReadFile(filename) - if err != nil { - return nil, err - } - - var yamlData map[interface{}]interface{} - err = yaml.Unmarshal(fileContent, &yamlData) - if err != nil { - return nil, err - } - - return yamlData, nil + return cmcommon.LoadYAMLFromFile(filename) } // This needs unit tests func deepMerge(target, source map[interface{}]interface{}) map[interface{}]interface{} { - for key, sourceValue := range source { - targetValue, exists := target[key] - - if !exists { - target[key] = sourceValue - continue - } - - targetMap, targetMapOk := targetValue.(map[interface{}]interface{}) - sourceMap, sourceMapOk := sourceValue.(map[interface{}]interface{}) - - if targetMapOk && sourceMapOk { - target[key] = deepMerge(targetMap, sourceMap) - } else if reflect.TypeOf(targetValue) == reflect.TypeOf(sourceValue) { - // Both are slices, concatenate them - if targetSlice, targetSliceOk := targetValue.([]interface{}); targetSliceOk { - if sourceSlice, sourceSliceOk := sourceValue.([]interface{}); sourceSliceOk { - target[key] = append(targetSlice, sourceSlice...) - } - } - } else { - // If types are different, simply overwrite with the source value - target[key] = sourceValue - } - } - - return target + return cmcommon.DeepMerge(target, source) } func writeDefaultScrapeTargetsFile(operatorEnabled bool) map[interface{}]interface{} { noDefaultScrapingEnabled := os.Getenv("AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED") - if noDefaultScrapingEnabled != "" && strings.ToLower(noDefaultScrapingEnabled) == "false" { - loadRegexHash() - loadIntervalHash() - if operatorEnabled { - populateDefaultPrometheusConfigWithOperator() - } else { - populateDefaultPrometheusConfig() - } + log.Println("No Default Scraping Enabled:", noDefaultScrapingEnabled) + if noDefaultScrapingEnabled != "true" { + populateDefaultPrometheusConfig() if mergedDefaultConfigs != nil && len(mergedDefaultConfigs) > 0 { log.Printf("Starting to merge default prometheus config values in collector template as backup\n") mergedDefaultConfigYaml, err := yaml.Marshal(mergedDefaultConfigs) @@ -1458,38 +165,29 @@ func writeDefaultScrapeTargetsFile(operatorEnabled bool) map[interface{}]interfa return mergedDefaultConfigs } } else { - mergedDefaultConfigs = nil + mergedDefaultConfigs = make(map[interface{}]interface{}) } log.Printf("Done creating default targets file\n") return nil } func setDefaultFileScrapeInterval(scrapeInterval string) { - defaultFilesArray := []string{ - kubeletDefaultFileRsSimple, kubeletDefaultFileRsAdvanced, kubeletDefaultFileDs, - kubeletDefaultFileRsAdvancedWindowsDaemonset, coreDNSDefaultFile, - cadvisorDefaultFileRsSimple, cadvisorDefaultFileRsAdvanced, cadvisorDefaultFileDs, - kubeProxyDefaultFile, apiserverDefaultFile, kubeStateDefaultFile, - nodeExporterDefaultFileRsSimple, nodeExporterDefaultFileRsAdvanced, nodeExporterDefaultFileDs, - prometheusCollectorHealthDefaultFile, windowsExporterDefaultRsSimpleFile, windowsExporterDefaultDsFile, - windowsKubeProxyDefaultFileRsSimpleFile, windowsKubeProxyDefaultDsFile, podAnnotationsDefaultFile, - kappieBasicDefaultFileDs, networkObservabilityRetinaDefaultFileDs, networkObservabilityHubbleDefaultFileDs, - networkObservabilityCiliumDefaultFileDs, acstorMetricsExporterDefaultFile, acstorCapacityProvisionerDefaultFile, - LocalCSIDriverDefaultFile, dcgmExporterDefaultFile, - } - - for _, currentFile := range defaultFilesArray { - contents, err := os.ReadFile(fmt.Sprintf("%s%s", defaultPromConfigPathPrefix, currentFile)) - if err != nil { - log.Printf("Error reading file %s: %v\n", currentFile, err) - continue + for _, job := range shared.DefaultScrapeJobs { + if job.ScrapeInterval != "" { + scrapeInterval = job.ScrapeInterval } - - contents = []byte(strings.Replace(string(contents), "$$SCRAPE_INTERVAL$$", scrapeInterval, -1)) - - err = os.WriteFile(currentFile, contents, fs.FileMode(0644)) - if err != nil { - log.Printf("Error writing to file %s: %v\n", currentFile, err) + if job.ScrapeConfigDefinitionFile != "" { + currentFile := scrapeConfigDefinitionPathPrefix + job.ScrapeConfigDefinitionFile + contents, err := os.ReadFile(currentFile) + if err != nil { + log.Printf("Error reading file %s: %v\n", currentFile, err) + continue + } + contents = []byte(strings.Replace(string(contents), "$$SCRAPE_INTERVAL$$", scrapeInterval, -1)) + err = os.WriteFile(currentFile, contents, fs.FileMode(0644)) + if err != nil { + log.Printf("Error writing to file %s: %v\n", currentFile, err) + } } } } @@ -1608,7 +306,6 @@ func setGlobalScrapeConfigInDefaultFilesIfExists(configString string) string { func prometheusConfigMerger(operatorEnabled bool) { shared.EchoSectionDivider("Start Processing - prometheusConfigMerger") - mergedDefaultConfigs = make(map[interface{}]interface{}) // Initialize mergedDefaultConfigs prometheusConfigMap := parseConfigMap() if len(prometheusConfigMap) > 0 { diff --git a/otelcollector/shared/configmap/mp/testdata/advanced-linux-ds.yaml b/otelcollector/shared/configmap/mp/testdata/advanced-linux-ds.yaml new file mode 100644 index 000000000..fa609e5a8 --- /dev/null +++ b/otelcollector/shared/configmap/mp/testdata/advanced-linux-ds.yaml @@ -0,0 +1,207 @@ +scrape_configs: +- job_name: networkobservability-hubble + kubernetes_sd_configs: + - role: service + metric_relabel_configs: + - action: keep + regex: test.*|test2|hubble.* + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-system;network-observability;hubble + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_service_port_name + - action: replace + replacement: 192.168.1.1 + source_labels: + - __address__ + target_label: __address__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_port_number + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 15s +- job_name: networkobservability-cilium + kubernetes_sd_configs: + - role: service + metric_relabel_configs: + - action: keep + regex: test.*|test2|cilium_drop.*|cilium_forward.* + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-system;network-observability;cilium + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_service_port_name + - action: replace + replacement: 192.168.1.1 + source_labels: + - __address__ + target_label: __address__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_port_number + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 15s +- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: kubelet + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2|kubelet_volume_stats_capacity_bytes|kubelet_volume_stats_used_bytes|kubelet_node_name|kubelet_running_pods|kubelet_running_pod_count|kubelet_running_sum_containers|kubelet_running_containers|kubelet_running_container_count|volume_manager_total_volumes|kubelet_node_config_error|kubelet_runtime_operations_total|kubelet_runtime_operations_errors_total|kubelet_runtime_operations_duration_seconds_bucket|kubelet_runtime_operations_duration_seconds_sum|kubelet_runtime_operations_duration_seconds_count|kubelet_pod_start_duration_seconds_bucket|kubelet_pod_start_duration_seconds_sum|kubelet_pod_start_duration_seconds_count|kubelet_pod_worker_duration_seconds_bucket|kubelet_pod_worker_duration_seconds_sum|kubelet_pod_worker_duration_seconds_count|storage_operation_duration_seconds_bucket|storage_operation_duration_seconds_sum|storage_operation_duration_seconds_count|storage_operation_errors_total|kubelet_cgroup_manager_duration_seconds_bucket|kubelet_cgroup_manager_duration_seconds_sum|kubelet_cgroup_manager_duration_seconds_count|kubelet_pleg_relist_interval_seconds_bucket|kubelet_pleg_relist_interval_seconds_count|kubelet_pleg_relist_interval_seconds_sum|kubelet_pleg_relist_duration_seconds_bucket|kubelet_pleg_relist_duration_seconds_count|kubelet_pleg_relist_duration_seconds_sum|rest_client_requests_total|rest_client_request_duration_seconds_bucket|rest_client_request_duration_seconds_sum|rest_client_request_duration_seconds_count|process_resident_memory_bytes|process_cpu_seconds_total|go_goroutines|kubernetes_build_info|kubelet_certificate_manager_client_ttl_seconds|kubelet_certificate_manager_client_expiration_renew_errors|kubelet_server_expiration_renew_errors|kubelet_certificate_manager_server_ttl_seconds|kubelet_volume_stats_available_bytes|kubelet_volume_stats_capacity_bytes|kubelet_volume_stats_inodes_free|kubelet_volume_stats_inodes_used|kubelet_volume_stats_inodes|kube_persistentvolumeclaim_access_mode|kube_persistentvolumeclaim_labels|kube_persistentvolume_status_phase + source_labels: + - __name__ + metrics_path: /metrics + relabel_configs: + - regex: (.*) + source_labels: + - __metrics_path__ + target_label: metrics_path + - replacement: test-node + source_labels: + - __address__ + target_label: instance + - replacement: linux + source_labels: + - __address__ + target_label: kubernetes_io_os + scheme: https + scrape_interval: 15s + static_configs: + - targets: + - 192.168.1.1:10250 + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true +- job_name: kappie-basic + kubernetes_sd_configs: + - role: service + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2|kappie.* + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-system;kappie-svc + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - action: replace + replacement: 192.168.1.1:10093 + source_labels: + - __address__ + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 15s +- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: cadvisor + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2|container_spec_cpu_quota|container_spec_cpu_period|container_memory_rss|container_network_receive_bytes_total|container_network_transmit_bytes_total|container_network_receive_packets_total|container_network_transmit_packets_total|container_network_receive_packets_dropped_total|container_network_transmit_packets_dropped_total|container_fs_reads_total|container_fs_writes_total|container_fs_reads_bytes_total|container_fs_writes_bytes_total|container_cpu_usage_seconds_total|container_memory_working_set_bytes|container_memory_cache|container_memory_swap|container_cpu_cfs_throttled_periods_total|container_cpu_cfs_periods_total|container_memory_rss|kubernetes_build_info|container_start_time_seconds + source_labels: + - __name__ + metrics_path: /metrics/cadvisor + relabel_configs: + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: https + scrape_interval: 15s + static_configs: + - targets: + - 192.168.1.1:10250 + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true +- job_name: node + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2|node_filesystem_readonly|node_memory_MemTotal_bytes|node_cpu_seconds_total|node_memory_MemAvailable_bytes|node_memory_Buffers_bytes|node_memory_Cached_bytes|node_memory_MemFree_bytes|node_memory_Slab_bytes|node_filesystem_avail_bytes|node_filesystem_size_bytes|node_time_seconds|node_exporter_build_info|node_load1|node_vmstat_pgmajfault|node_network_receive_bytes_total|node_network_transmit_bytes_total|node_network_receive_drop_total|node_network_transmit_drop_total|node_disk_io_time_seconds_total|node_disk_io_time_weighted_seconds_total|node_load5|node_load15|node_disk_read_bytes_total|node_disk_written_bytes_total|node_uname_info|kubernetes_build_info|node_boot_time_seconds + source_labels: + - __name__ + relabel_configs: + - regex: (.*) + source_labels: + - __metrics_path__ + target_label: metrics_path + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 15s + static_configs: + - targets: + - 192.168.1.1:9100 +- job_name: networkobservability-retina + kubernetes_sd_configs: + - role: service + metric_relabel_configs: + - action: keep + regex: test.*|test2|networkobservability.* + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-system;network-observability;retina + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_service_port_name + - action: replace + replacement: 192.168.1.1 + source_labels: + - __address__ + target_label: __address__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_port_number + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 15s diff --git a/otelcollector/shared/configmap/mp/testdata/advanced-linux-rs.yaml b/otelcollector/shared/configmap/mp/testdata/advanced-linux-rs.yaml new file mode 100644 index 000000000..2cf9f3769 --- /dev/null +++ b/otelcollector/shared/configmap/mp/testdata/advanced-linux-rs.yaml @@ -0,0 +1,273 @@ +scrape_configs: +- job_name: kubernetes-pods + kubernetes_sd_configs: + - role: pod + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2| + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: true + source_labels: + - __meta_kubernetes_pod_annotation_prometheus_io_scrape + - action: replace + regex: (.+) + source_labels: + - __meta_kubernetes_pod_annotation_prometheus_io_path + target_label: __metrics_path__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_pod_annotation_prometheus_io_port + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: kubernetes_namespace + - action: replace + source_labels: + - __meta_kubernetes_pod_name + target_label: kubernetes_pod_name + - action: keep + regex: .*|value + source_labels: + - __meta_kubernetes_namespace + scrape_interval: 15s +- honor_labels: true + job_name: acstor-metrics-exporter + kubernetes_sd_configs: + - namespaces: + names: + - acstor + - kube-system + role: pod + metric_relabel_configs: + - action: keep + regex: test.*|test2|disk_read_operations_completed_total|disk_write_operations_completed_total|disk_read_operations_time_seconds_total|disk_write_operations_time_seconds_total|disk_read_bytes_total|disk_written_bytes_total|disk_reads_merged_total|disk_writes_merged_total|disk_io_now|disk_io_time_seconds_total|disk_io_time_weighted_seconds_total|disk_discard_operations_completed_total|disk_discards_merged_total|disk_discarded_sectors_total|disk_discard_operations_time_seconds_total|disk_flush_requests_total|disk_flush_requests_time_seconds_total|disk_errors_total|disk_readonly_errors_gauge|disk_readonly_status_gauge + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: acstor|kube-system + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: (metrics-exporter;monitor)|(storage-operator;node-agent)|(node-agent;node-agent) + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_name + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 15s +- job_name: dcgm-exporter + kubernetes_sd_configs: + - role: node + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2|DCGM_.* + source_labels: + - __name__ + metrics_path: /metrics + relabel_configs: + - action: keep + regex: enabled + source_labels: + - __meta_kubernetes_node_label_kubernetes_azure_com_dcgm_exporter + - action: replace + regex: (.+) + replacement: $1:19400 + source_labels: + - __meta_kubernetes_node_address_InternalIP + target_label: __address__ + - action: replace + source_labels: + - __meta_kubernetes_node_name + target_label: instance + - action: labeldrop + regex: (?i)cluster + - action: labeldrop + regex: (?i)dcgm_fi_driver_version + - action: labeldrop + regex: (?i)device + - action: labeldrop + regex: (?i)hostname + - action: labeldrop + regex: microsoft.resourceid + - action: labeldrop + regex: (?i)modelName + - action: labeldrop + regex: (?i)pci_bus_id + - action: labeldrop + regex: (?i)uuid + scheme: http + scrape_interval: 15s + +- job_name: kube-proxy + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: pod + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2|kubeproxy_sync_proxy_rules_duration_seconds|kubeproxy_sync_proxy_rules_duration_seconds_bucket|kubeproxy_sync_proxy_rules_duration_seconds_sum|kubeproxy_sync_proxy_rules_duration_seconds_count|kubeproxy_network_programming_duration_seconds|kubeproxy_network_programming_duration_seconds_bucket|kubeproxy_network_programming_duration_seconds_sum|kubeproxy_network_programming_duration_seconds_count|rest_client_requests_total|rest_client_request_duration_seconds|rest_client_request_duration_seconds_bucket|rest_client_request_duration_seconds_sum|rest_client_request_duration_seconds_count|process_resident_memory_bytes|process_cpu_seconds_total|go_goroutines|kubernetes_build_info + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-system/kube-proxy.+ + separator: / + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_pod_name + - action: replace + regex: (.+?)(\:\d+)? + replacement: $$1:10249 + source_labels: + - __address__ + target_label: __address__ + scrape_interval: 15s +- job_name: kube-state-metrics + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2|kube_job_status_succeeded|kube_job_spec_completions|kube_daemonset_status_desired_number_scheduled|kube_daemonset_status_current_number_scheduled|kube_daemonset_status_number_misscheduled|kube_daemonset_status_number_ready|kube_deployment_status_replicas_ready|kube_pod_container_status_last_terminated_reason|kube_pod_container_status_waiting_reason|kube_pod_container_status_restarts_total|kube_node_status_allocatable|kube_pod_owner|kube_pod_container_resource_requests|kube_pod_status_phase|kube_pod_container_resource_limits|kube_replicaset_owner|kube_resourcequota|kube_namespace_status_phase|kube_node_status_capacity|kube_node_info|kube_pod_info|kube_deployment_spec_replicas|kube_deployment_status_replicas_available|kube_deployment_status_replicas_updated|kube_statefulset_status_replicas_ready|kube_statefulset_status_replicas|kube_statefulset_status_replicas_updated|kube_job_status_start_time|kube_job_status_active|kube_job_failed|kube_horizontalpodautoscaler_status_desired_replicas|kube_horizontalpodautoscaler_status_current_replicas|kube_horizontalpodautoscaler_spec_min_replicas|kube_horizontalpodautoscaler_spec_max_replicas|kubernetes_build_info|kube_node_status_condition|kube_node_spec_taint|kube_pod_container_info|kube_.*_labels|kube_.*_annotations|kube_service_info|kube_pod_container_status_running|kube_pod_container_status_waiting|kube_pod_container_status_terminated|kube_pod_container_state_started|kube_pod_created|kube_pod_start_time|kube_pod_init_container_info|kube_pod_init_container_status_terminated|kube_pod_init_container_status_terminated_reason|kube_pod_init_container_status_ready|kube_pod_init_container_resource_limits|kube_pod_init_container_status_running|kube_pod_init_container_status_waiting|kube_pod_init_container_status_restarts_total|kube_pod_container_status_ready|kube_pod_init_container_*|kube_pod_deletion_timestamp|kube_pod_status_reason|kube_pod_init_container_resource_requests + source_labels: + - __name__ + scrape_interval: 15s + static_configs: + - targets: + - ama-metrics-ksm.kube-system.svc.cluster.local:8080 +- honor_labels: true + job_name: acstor-capacity-provisioner + kubernetes_sd_configs: + - namespaces: + names: + - acstor + role: pod + metric_relabel_configs: + - action: keep + regex: test.*|test2|storage_pool_ready_state|storage_pool_capacity_used_bytes|storage_pool_capacity_provisioned_bytes|storage_pool_snapshot_capacity_reserved_bytes + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: acstor + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: capacity-provisioner;capacity-provisoner + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_name + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 15s +- honor_labels: true + job_name: local-csi-driver + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: pod + metric_relabel_configs: + - action: keep + regex: test.*|test2|rpc.server.duration_milliseconds_bucket|rpc.server.duration_milliseconds_sum|rpc.server.duration_milliseconds_count|rpc_server_duration_milliseconds_bucket|rpc_server_duration_milliseconds_sum|rpc_server_duration_milliseconds_count + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-system + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: csi-local-node + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 15s +- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: kube-apiserver + kubernetes_sd_configs: + - namespaces: + names: + - default + role: endpoints + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2|apiserver_request_duration_seconds|apiserver_request_duration_seconds_bucket|apiserver_request_duration_seconds_sum|apiserver_request_duration_seconds_count|apiserver_request_total|workqueue_adds_total|workqueue_depth|workqueue_queue_duration_seconds|workqueue_queue_duration_seconds_bucket|workqueue_queue_duration_seconds_sum|workqueue_queue_duration_seconds_count|process_resident_memory_bytes|process_cpu_seconds_total|go_goroutines|kubernetes_build_info|apiserver_request_slo_duration_seconds_bucket|apiserver_request_slo_duration_seconds_sum|apiserver_request_slo_duration_seconds_count + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: default;kubernetes;https + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_endpoint_port_name + scheme: https + scrape_interval: 15s + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true +- job_name: kube-dns + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: pod + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2|coredns_build_info|coredns_panics_total|coredns_dns_responses_total|coredns_forward_responses_total|coredns_dns_request_duration_seconds|coredns_dns_request_duration_seconds_bucket|coredns_dns_request_duration_seconds_sum|coredns_dns_request_duration_seconds_count|coredns_forward_request_duration_seconds|coredns_forward_request_duration_seconds_bucket|coredns_forward_request_duration_seconds_sum|coredns_forward_request_duration_seconds_count|coredns_dns_requests_total|coredns_forward_requests_total|coredns_cache_hits_total|coredns_cache_misses_total|coredns_cache_entries|coredns_plugin_enabled|coredns_dns_request_size_bytes|coredns_dns_request_size_bytes_bucket|coredns_dns_request_size_bytes_sum|coredns_dns_request_size_bytes_count|coredns_dns_response_size_bytes|coredns_dns_response_size_bytes_bucket|coredns_dns_response_size_bytes_sum|coredns_dns_response_size_bytes_count|coredns_dns_response_size_bytes_bucket|coredns_dns_response_size_bytes_sum|coredns_dns_response_size_bytes_count|process_resident_memory_bytes|process_cpu_seconds_total|go_goroutines|kubernetes_build_info + source_labels: + - __name__ + metrics_path: /metrics + relabel_configs: + - action: keep + regex: kube-system/coredns.+ + separator: / + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_pod_name + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + - source_labels: + - __meta_kubernetes_pod_name + target_label: pod + scheme: http + scrape_interval: 15s diff --git a/otelcollector/shared/configmap/mp/testdata/advanced-no-minimal-linux-ds.yaml b/otelcollector/shared/configmap/mp/testdata/advanced-no-minimal-linux-ds.yaml new file mode 100644 index 000000000..c06d127ae --- /dev/null +++ b/otelcollector/shared/configmap/mp/testdata/advanced-no-minimal-linux-ds.yaml @@ -0,0 +1,172 @@ +scrape_configs: +- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: cadvisor + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metrics_path: /metrics/cadvisor + relabel_configs: + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: https + scrape_interval: 30s + static_configs: + - targets: + - 192.168.1.1:10250 + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true +- job_name: networkobservability-cilium + kubernetes_sd_configs: + - role: service + relabel_configs: + - action: keep + regex: kube-system;network-observability;cilium + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_service_port_name + - action: replace + replacement: 192.168.1.1 + source_labels: + - __address__ + target_label: __address__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_port_number + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 30s +- job_name: networkobservability-retina + kubernetes_sd_configs: + - role: service + relabel_configs: + - action: keep + regex: kube-system;network-observability;retina + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_service_port_name + - action: replace + replacement: 192.168.1.1 + source_labels: + - __address__ + target_label: __address__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_port_number + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 30s +- job_name: networkobservability-hubble + kubernetes_sd_configs: + - role: service + relabel_configs: + - action: keep + regex: kube-system;network-observability;hubble + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_service_port_name + - action: replace + replacement: 192.168.1.1 + source_labels: + - __address__ + target_label: __address__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_port_number + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 30s +- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: kubelet + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metrics_path: /metrics + relabel_configs: + - regex: (.*) + source_labels: + - __metrics_path__ + target_label: metrics_path + - replacement: test-node + source_labels: + - __address__ + target_label: instance + - replacement: linux + source_labels: + - __address__ + target_label: kubernetes_io_os + scheme: https + scrape_interval: 30s + static_configs: + - targets: + - 192.168.1.1:10250 + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true +- job_name: node + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + relabel_configs: + - regex: (.*) + source_labels: + - __metrics_path__ + target_label: metrics_path + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 30s + static_configs: + - targets: + - 192.168.1.1:9100 +- job_name: kappie-basic + kubernetes_sd_configs: + - role: service + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + relabel_configs: + - action: keep + regex: kube-system;kappie-svc + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - action: replace + replacement: 192.168.1.1:10093 + source_labels: + - __address__ + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 30s diff --git a/otelcollector/shared/configmap/mp/testdata/advanced-no-minimal-linux-rs.yaml b/otelcollector/shared/configmap/mp/testdata/advanced-no-minimal-linux-rs.yaml new file mode 100644 index 000000000..f7cb0592c --- /dev/null +++ b/otelcollector/shared/configmap/mp/testdata/advanced-no-minimal-linux-rs.yaml @@ -0,0 +1,190 @@ +scrape_configs: +- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: kube-apiserver + kubernetes_sd_configs: + - namespaces: + names: + - default + role: endpoints + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + relabel_configs: + - action: keep + regex: default;kubernetes;https + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_endpoint_port_name + scheme: https + scrape_interval: 30s + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true +- job_name: kube-state-metrics + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + scrape_interval: 30s + static_configs: + - targets: + - ama-metrics-ksm.kube-system.svc.cluster.local:8080 +- honor_labels: true + job_name: acstor-capacity-provisioner + kubernetes_sd_configs: + - namespaces: + names: + - acstor + role: pod + relabel_configs: + - action: keep + regex: acstor + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: capacity-provisioner;capacity-provisoner + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_name + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 30s +- honor_labels: true + job_name: acstor-metrics-exporter + kubernetes_sd_configs: + - namespaces: + names: + - acstor + - kube-system + role: pod + relabel_configs: + - action: keep + regex: acstor|kube-system + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: (metrics-exporter;monitor)|(storage-operator;node-agent)|(node-agent;node-agent) + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_name + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 30s +- honor_labels: true + job_name: local-csi-driver + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: pod + relabel_configs: + - action: keep + regex: kube-system + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: csi-local-node + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 30s +- job_name: dcgm-exporter + kubernetes_sd_configs: + - role: node + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metrics_path: /metrics + relabel_configs: + - action: keep + regex: enabled + source_labels: + - __meta_kubernetes_node_label_kubernetes_azure_com_dcgm_exporter + - action: replace + regex: (.+) + replacement: $1:19400 + source_labels: + - __meta_kubernetes_node_address_InternalIP + target_label: __address__ + - action: replace + source_labels: + - __meta_kubernetes_node_name + target_label: instance + - action: labeldrop + regex: (?i)cluster + - action: labeldrop + regex: (?i)dcgm_fi_driver_version + - action: labeldrop + regex: (?i)device + - action: labeldrop + regex: (?i)hostname + - action: labeldrop + regex: microsoft.resourceid + - action: labeldrop + regex: (?i)modelName + - action: labeldrop + regex: (?i)pci_bus_id + - action: labeldrop + regex: (?i)uuid + scheme: http + scrape_interval: 30s + +- job_name: kube-dns + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: pod + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metrics_path: /metrics + relabel_configs: + - action: keep + regex: kube-system/coredns.+ + separator: / + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_pod_name + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + - source_labels: + - __meta_kubernetes_pod_name + target_label: pod + scheme: http + scrape_interval: 30s +- job_name: kube-proxy + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: pod + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + relabel_configs: + - action: keep + regex: kube-system/kube-proxy.+ + separator: / + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_pod_name + - action: replace + regex: (.+?)(\:\d+)? + replacement: $$1:10249 + source_labels: + - __address__ + target_label: __address__ + scrape_interval: 30s diff --git a/otelcollector/shared/configmap/mp/testdata/advanced-no-minimal-windows-ds.yaml b/otelcollector/shared/configmap/mp/testdata/advanced-no-minimal-windows-ds.yaml new file mode 100644 index 000000000..029202989 --- /dev/null +++ b/otelcollector/shared/configmap/mp/testdata/advanced-no-minimal-windows-ds.yaml @@ -0,0 +1,29 @@ +scrape_configs: +- job_name: windows-exporter + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + relabel_configs: + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 30s + static_configs: + - targets: + - 192.168.1.1:9182 +- job_name: kube-proxy-windows + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + relabel_configs: + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 30s + static_configs: + - targets: + - 192.168.1.1:10249 diff --git a/otelcollector/shared/configmap/mp/testdata/advanced-windows-ds.yaml b/otelcollector/shared/configmap/mp/testdata/advanced-windows-ds.yaml new file mode 100644 index 000000000..28adf7138 --- /dev/null +++ b/otelcollector/shared/configmap/mp/testdata/advanced-windows-ds.yaml @@ -0,0 +1,39 @@ +scrape_configs: +- job_name: kube-proxy-windows + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2|kubeproxy_sync_proxy_rules_duration_seconds|kubeproxy_sync_proxy_rules_duration_seconds_bucket|kubeproxy_sync_proxy_rules_duration_seconds_sum|kubeproxy_sync_proxy_rules_duration_seconds_count|rest_client_requests_total|rest_client_request_duration_seconds|rest_client_request_duration_seconds_bucket|rest_client_request_duration_seconds_sum|rest_client_request_duration_seconds_count|process_resident_memory_bytes|process_cpu_seconds_total|go_goroutines + source_labels: + - __name__ + relabel_configs: + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 15s + static_configs: + - targets: + - 192.168.1.1:10249 +- job_name: windows-exporter + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2|windows_system_system_up_time|windows_cpu_time_total|windows_memory_available_bytes|windows_os_visible_memory_bytes|windows_memory_cache_bytes|windows_memory_modified_page_list_bytes|windows_memory_standby_cache_core_bytes|windows_memory_standby_cache_normal_priority_bytes|windows_memory_standby_cache_reserve_bytes|windows_memory_swap_page_operations_total|windows_logical_disk_read_seconds_total|windows_logical_disk_write_seconds_total|windows_logical_disk_size_bytes|windows_logical_disk_free_bytes|windows_net_bytes_total|windows_net_packets_received_discarded_total|windows_net_packets_outbound_discarded_total|windows_container_available|windows_container_cpu_usage_seconds_total|windows_container_memory_usage_commit_bytes|windows_container_memory_usage_private_working_set_bytes|windows_container_network_receive_bytes_total|windows_container_network_transmit_bytes_total + source_labels: + - __name__ + relabel_configs: + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 15s + static_configs: + - targets: + - 192.168.1.1:9182 diff --git a/otelcollector/shared/configmap/mp/testdata/custom-prometheus-config-and-defaults-ds.yaml b/otelcollector/shared/configmap/mp/testdata/custom-prometheus-config-and-defaults-ds.yaml new file mode 100644 index 000000000..d634f908d --- /dev/null +++ b/otelcollector/shared/configmap/mp/testdata/custom-prometheus-config-and-defaults-ds.yaml @@ -0,0 +1,208 @@ +global: + external_labels: + external_label_1: external_label_value + external_label_123: external_label_value + scrape_interval: 15s +scrape_configs: +- job_name: node + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: '|node_filesystem_readonly|node_memory_MemTotal_bytes|node_cpu_seconds_total|node_memory_MemAvailable_bytes|node_memory_Buffers_bytes|node_memory_Cached_bytes|node_memory_MemFree_bytes|node_memory_Slab_bytes|node_filesystem_avail_bytes|node_filesystem_size_bytes|node_time_seconds|node_exporter_build_info|node_load1|node_vmstat_pgmajfault|node_network_receive_bytes_total|node_network_transmit_bytes_total|node_network_receive_drop_total|node_network_transmit_drop_total|node_disk_io_time_seconds_total|node_disk_io_time_weighted_seconds_total|node_load5|node_load15|node_disk_read_bytes_total|node_disk_written_bytes_total|node_uname_info|kubernetes_build_info|node_boot_time_seconds' + source_labels: + - __name__ + relabel_configs: + - regex: (.*) + source_labels: + - __metrics_path__ + target_label: metrics_path + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 30s + static_configs: + - targets: + - 192.168.1.1:9100 +- job_name: networkobservability-cilium + kubernetes_sd_configs: + - role: service + metric_relabel_configs: + - action: keep + regex: '|cilium_drop.*|cilium_forward.*' + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-system;network-observability;cilium + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_service_port_name + - action: replace + replacement: 192.168.1.1 + source_labels: + - __address__ + target_label: __address__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_port_number + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 30s +- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: kubelet + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: '|kubelet_volume_stats_capacity_bytes|kubelet_volume_stats_used_bytes|kubelet_node_name|kubelet_running_pods|kubelet_running_pod_count|kubelet_running_sum_containers|kubelet_running_containers|kubelet_running_container_count|volume_manager_total_volumes|kubelet_node_config_error|kubelet_runtime_operations_total|kubelet_runtime_operations_errors_total|kubelet_runtime_operations_duration_seconds_bucket|kubelet_runtime_operations_duration_seconds_sum|kubelet_runtime_operations_duration_seconds_count|kubelet_pod_start_duration_seconds_bucket|kubelet_pod_start_duration_seconds_sum|kubelet_pod_start_duration_seconds_count|kubelet_pod_worker_duration_seconds_bucket|kubelet_pod_worker_duration_seconds_sum|kubelet_pod_worker_duration_seconds_count|storage_operation_duration_seconds_bucket|storage_operation_duration_seconds_sum|storage_operation_duration_seconds_count|storage_operation_errors_total|kubelet_cgroup_manager_duration_seconds_bucket|kubelet_cgroup_manager_duration_seconds_sum|kubelet_cgroup_manager_duration_seconds_count|kubelet_pleg_relist_interval_seconds_bucket|kubelet_pleg_relist_interval_seconds_count|kubelet_pleg_relist_interval_seconds_sum|kubelet_pleg_relist_duration_seconds_bucket|kubelet_pleg_relist_duration_seconds_count|kubelet_pleg_relist_duration_seconds_sum|rest_client_requests_total|rest_client_request_duration_seconds_bucket|rest_client_request_duration_seconds_sum|rest_client_request_duration_seconds_count|process_resident_memory_bytes|process_cpu_seconds_total|go_goroutines|kubernetes_build_info|kubelet_certificate_manager_client_ttl_seconds|kubelet_certificate_manager_client_expiration_renew_errors|kubelet_server_expiration_renew_errors|kubelet_certificate_manager_server_ttl_seconds|kubelet_volume_stats_available_bytes|kubelet_volume_stats_capacity_bytes|kubelet_volume_stats_inodes_free|kubelet_volume_stats_inodes_used|kubelet_volume_stats_inodes|kube_persistentvolumeclaim_access_mode|kube_persistentvolumeclaim_labels|kube_persistentvolume_status_phase' + source_labels: + - __name__ + metrics_path: /metrics + relabel_configs: + - regex: (.*) + source_labels: + - __metrics_path__ + target_label: metrics_path + - replacement: test-node + source_labels: + - __address__ + target_label: instance + - replacement: linux + source_labels: + - __address__ + target_label: kubernetes_io_os + scheme: https + scrape_interval: 30s + static_configs: + - targets: + - 192.168.1.1:10250 + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true +- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: cadvisor + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: '|container_spec_cpu_quota|container_spec_cpu_period|container_memory_rss|container_network_receive_bytes_total|container_network_transmit_bytes_total|container_network_receive_packets_total|container_network_transmit_packets_total|container_network_receive_packets_dropped_total|container_network_transmit_packets_dropped_total|container_fs_reads_total|container_fs_writes_total|container_fs_reads_bytes_total|container_fs_writes_bytes_total|container_cpu_usage_seconds_total|container_memory_working_set_bytes|container_memory_cache|container_memory_swap|container_cpu_cfs_throttled_periods_total|container_cpu_cfs_periods_total|container_memory_rss|kubernetes_build_info|container_start_time_seconds' + source_labels: + - __name__ + metrics_path: /metrics/cadvisor + relabel_configs: + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: https + scrape_interval: 30s + static_configs: + - targets: + - 192.168.1.1:10250 + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true +- job_name: networkobservability-retina + kubernetes_sd_configs: + - role: service + metric_relabel_configs: + - action: keep + regex: '|networkobservability.*' + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-system;network-observability;retina + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_service_port_name + - action: replace + replacement: 192.168.1.1 + source_labels: + - __address__ + target_label: __address__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_port_number + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 30s +- job_name: networkobservability-hubble + kubernetes_sd_configs: + - role: service + metric_relabel_configs: + - action: keep + regex: '|hubble.*' + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-system;network-observability;hubble + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_service_port_name + - action: replace + replacement: 192.168.1.1 + source_labels: + - __address__ + target_label: __address__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_port_number + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 30s +- job_name: prometheus_ref_app + kubernetes_sd_configs: + - role: pod + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + relabel_configs: + - action: keep + regex: prometheus-reference-app + source_labels: + - __meta_kubernetes_pod_label_app + - action: replace + regex: (.*) + replacement: $$1 + source_labels: + - __meta_kubernetes_pod_label_app + target_label: double_dollar_sign + - action: replace + regex: (.*) + replacement: $1 + source_labels: + - __meta_kubernetes_pod_label_app + target_label: single_dollar_sign + scheme: http diff --git a/otelcollector/shared/configmap/mp/testdata/custom-prometheus-config-and-defaults-rs.yaml b/otelcollector/shared/configmap/mp/testdata/custom-prometheus-config-and-defaults-rs.yaml new file mode 100644 index 000000000..1571b2045 --- /dev/null +++ b/otelcollector/shared/configmap/mp/testdata/custom-prometheus-config-and-defaults-rs.yaml @@ -0,0 +1,127 @@ +global: + external_labels: + external_label_1: external_label_value + external_label_123: external_label_value + scrape_interval: 15s +scrape_configs: +- honor_labels: true + job_name: local-csi-driver + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: pod + metric_relabel_configs: + - action: keep + regex: '|rpc.server.duration_milliseconds_bucket|rpc.server.duration_milliseconds_sum|rpc.server.duration_milliseconds_count|rpc_server_duration_milliseconds_bucket|rpc_server_duration_milliseconds_sum|rpc_server_duration_milliseconds_count' + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-system + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: csi-local-node + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 30s +- job_name: kube-state-metrics + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: '|kube_job_status_succeeded|kube_job_spec_completions|kube_daemonset_status_desired_number_scheduled|kube_daemonset_status_current_number_scheduled|kube_daemonset_status_number_misscheduled|kube_daemonset_status_number_ready|kube_deployment_status_replicas_ready|kube_pod_container_status_last_terminated_reason|kube_pod_container_status_waiting_reason|kube_pod_container_status_restarts_total|kube_node_status_allocatable|kube_pod_owner|kube_pod_container_resource_requests|kube_pod_status_phase|kube_pod_container_resource_limits|kube_replicaset_owner|kube_resourcequota|kube_namespace_status_phase|kube_node_status_capacity|kube_node_info|kube_pod_info|kube_deployment_spec_replicas|kube_deployment_status_replicas_available|kube_deployment_status_replicas_updated|kube_statefulset_status_replicas_ready|kube_statefulset_status_replicas|kube_statefulset_status_replicas_updated|kube_job_status_start_time|kube_job_status_active|kube_job_failed|kube_horizontalpodautoscaler_status_desired_replicas|kube_horizontalpodautoscaler_status_current_replicas|kube_horizontalpodautoscaler_spec_min_replicas|kube_horizontalpodautoscaler_spec_max_replicas|kubernetes_build_info|kube_node_status_condition|kube_node_spec_taint|kube_pod_container_info|kube_.*_labels|kube_.*_annotations|kube_service_info|kube_pod_container_status_running|kube_pod_container_status_waiting|kube_pod_container_status_terminated|kube_pod_container_state_started|kube_pod_created|kube_pod_start_time|kube_pod_init_container_info|kube_pod_init_container_status_terminated|kube_pod_init_container_status_terminated_reason|kube_pod_init_container_status_ready|kube_pod_init_container_resource_limits|kube_pod_init_container_status_running|kube_pod_init_container_status_waiting|kube_pod_init_container_status_restarts_total|kube_pod_container_status_ready|kube_pod_init_container_*|kube_pod_deletion_timestamp|kube_pod_status_reason|kube_pod_init_container_resource_requests' + source_labels: + - __name__ + scrape_interval: 30s + static_configs: + - targets: + - ama-metrics-ksm.kube-system.svc.cluster.local:8080 +- honor_labels: true + job_name: acstor-metrics-exporter + kubernetes_sd_configs: + - namespaces: + names: + - acstor + - kube-system + role: pod + metric_relabel_configs: + - action: keep + regex: '|disk_read_operations_completed_total|disk_write_operations_completed_total|disk_read_operations_time_seconds_total|disk_write_operations_time_seconds_total|disk_read_bytes_total|disk_written_bytes_total|disk_reads_merged_total|disk_writes_merged_total|disk_io_now|disk_io_time_seconds_total|disk_io_time_weighted_seconds_total|disk_discard_operations_completed_total|disk_discards_merged_total|disk_discarded_sectors_total|disk_discard_operations_time_seconds_total|disk_flush_requests_total|disk_flush_requests_time_seconds_total|disk_errors_total|disk_readonly_errors_gauge|disk_readonly_status_gauge' + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: acstor|kube-system + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: (metrics-exporter;monitor)|(storage-operator;node-agent)|(node-agent;node-agent) + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_name + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 30s +- honor_labels: true + job_name: acstor-capacity-provisioner + kubernetes_sd_configs: + - namespaces: + names: + - acstor + role: pod + metric_relabel_configs: + - action: keep + regex: '|storage_pool_ready_state|storage_pool_capacity_used_bytes|storage_pool_capacity_provisioned_bytes|storage_pool_snapshot_capacity_reserved_bytes' + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: acstor + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: capacity-provisioner;capacity-provisoner + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_name + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 30s +- job_name: prometheus_ref_app + kubernetes_sd_configs: + - role: pod + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + relabel_configs: + - action: keep + regex: prometheus-reference-app + source_labels: + - __meta_kubernetes_pod_label_app + - action: replace + regex: (.*) + replacement: $$1 + source_labels: + - __meta_kubernetes_pod_label_app + target_label: double_dollar_sign + - action: replace + regex: (.*) + replacement: $1 + source_labels: + - __meta_kubernetes_pod_label_app + target_label: single_dollar_sign + scheme: http diff --git a/otelcollector/shared/configmap/mp/testdata/custom-prometheus-config-no-defaults-rs.yaml b/otelcollector/shared/configmap/mp/testdata/custom-prometheus-config-no-defaults-rs.yaml new file mode 100644 index 000000000..3fbb05b0c --- /dev/null +++ b/otelcollector/shared/configmap/mp/testdata/custom-prometheus-config-no-defaults-rs.yaml @@ -0,0 +1,30 @@ +global: + external_labels: + external_label_1: external_label_value + external_label_123: external_label_value + scrape_interval: 15s +scrape_configs: +- job_name: prometheus_ref_app + kubernetes_sd_configs: + - role: pod + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + relabel_configs: + - action: keep + regex: prometheus-reference-app + source_labels: + - __meta_kubernetes_pod_label_app + - action: replace + regex: (.*) + replacement: $$1 + source_labels: + - __meta_kubernetes_pod_label_app + target_label: double_dollar_sign + - action: replace + regex: (.*) + replacement: $1 + source_labels: + - __meta_kubernetes_pod_label_app + target_label: single_dollar_sign + scheme: http diff --git a/otelcollector/shared/configmap/mp/testdata/custom-prometheus-config-windows-ds.yaml b/otelcollector/shared/configmap/mp/testdata/custom-prometheus-config-windows-ds.yaml new file mode 100644 index 000000000..3fbb05b0c --- /dev/null +++ b/otelcollector/shared/configmap/mp/testdata/custom-prometheus-config-windows-ds.yaml @@ -0,0 +1,30 @@ +global: + external_labels: + external_label_1: external_label_value + external_label_123: external_label_value + scrape_interval: 15s +scrape_configs: +- job_name: prometheus_ref_app + kubernetes_sd_configs: + - role: pod + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + relabel_configs: + - action: keep + regex: prometheus-reference-app + source_labels: + - __meta_kubernetes_pod_label_app + - action: replace + regex: (.*) + replacement: $$1 + source_labels: + - __meta_kubernetes_pod_label_app + target_label: double_dollar_sign + - action: replace + regex: (.*) + replacement: $1 + source_labels: + - __meta_kubernetes_pod_label_app + target_label: single_dollar_sign + scheme: http diff --git a/otelcollector/shared/configmap/mp/testdata/custom-prometheus-config.yaml b/otelcollector/shared/configmap/mp/testdata/custom-prometheus-config.yaml new file mode 100644 index 000000000..671128ba5 --- /dev/null +++ b/otelcollector/shared/configmap/mp/testdata/custom-prometheus-config.yaml @@ -0,0 +1,24 @@ +global: + external_labels: + external_label_1: "external_label_value" + external_label_123: "external_label_value" + scrape_interval: 15s +scrape_configs: +- job_name: prometheus_ref_app + scheme: http + kubernetes_sd_configs: + - role: pod + relabel_configs: + - source_labels: [__meta_kubernetes_pod_label_app] + action: keep + regex: "prometheus-reference-app" + - source_labels: [__meta_kubernetes_pod_label_app] + action: replace + regex: (.*) + replacement: $$1 + target_label: double_dollar_sign + - source_labels: [__meta_kubernetes_pod_label_app] + action: replace + regex: (.*) + replacement: $1 + target_label: single_dollar_sign \ No newline at end of file diff --git a/otelcollector/shared/configmap/mp/testdata/default-linux-ds.yaml b/otelcollector/shared/configmap/mp/testdata/default-linux-ds.yaml index 3675b55d5..2ad0722aa 100644 --- a/otelcollector/shared/configmap/mp/testdata/default-linux-ds.yaml +++ b/otelcollector/shared/configmap/mp/testdata/default-linux-ds.yaml @@ -1,36 +1,60 @@ scrape_configs: -- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token - job_name: kubelet +- job_name: node label_limit: 63 label_name_length_limit: 511 label_value_length_limit: 1023 metric_relabel_configs: - action: keep - regex: '|kubelet_volume_stats_capacity_bytes|kubelet_volume_stats_used_bytes|kubelet_node_name|kubelet_running_pods|kubelet_running_pod_count|kubelet_running_sum_containers|kubelet_running_containers|kubelet_running_container_count|volume_manager_total_volumes|kubelet_node_config_error|kubelet_runtime_operations_total|kubelet_runtime_operations_errors_total|kubelet_runtime_operations_duration_seconds_bucket|kubelet_runtime_operations_duration_seconds_sum|kubelet_runtime_operations_duration_seconds_count|kubelet_pod_start_duration_seconds_bucket|kubelet_pod_start_duration_seconds_sum|kubelet_pod_start_duration_seconds_count|kubelet_pod_worker_duration_seconds_bucket|kubelet_pod_worker_duration_seconds_sum|kubelet_pod_worker_duration_seconds_count|storage_operation_duration_seconds_bucket|storage_operation_duration_seconds_sum|storage_operation_duration_seconds_count|storage_operation_errors_total|kubelet_cgroup_manager_duration_seconds_bucket|kubelet_cgroup_manager_duration_seconds_sum|kubelet_cgroup_manager_duration_seconds_count|kubelet_pleg_relist_interval_seconds_bucket|kubelet_pleg_relist_interval_seconds_count|kubelet_pleg_relist_interval_seconds_sum|kubelet_pleg_relist_duration_seconds_bucket|kubelet_pleg_relist_duration_seconds_count|kubelet_pleg_relist_duration_seconds_sum|rest_client_requests_total|rest_client_request_duration_seconds_bucket|rest_client_request_duration_seconds_sum|rest_client_request_duration_seconds_count|process_resident_memory_bytes|process_cpu_seconds_total|go_goroutines|kubernetes_build_info|kubelet_certificate_manager_client_ttl_seconds|kubelet_certificate_manager_client_expiration_renew_errors|kubelet_server_expiration_renew_errors|kubelet_certificate_manager_server_ttl_seconds|kubelet_volume_stats_available_bytes|kubelet_volume_stats_capacity_bytes|kubelet_volume_stats_inodes_free|kubelet_volume_stats_inodes_used|kubelet_volume_stats_inodes|kube_persistentvolumeclaim_access_mode|kube_persistentvolumeclaim_labels|kube_persistentvolume_status_phase' + regex: '|node_filesystem_readonly|node_memory_MemTotal_bytes|node_cpu_seconds_total|node_memory_MemAvailable_bytes|node_memory_Buffers_bytes|node_memory_Cached_bytes|node_memory_MemFree_bytes|node_memory_Slab_bytes|node_filesystem_avail_bytes|node_filesystem_size_bytes|node_time_seconds|node_exporter_build_info|node_load1|node_vmstat_pgmajfault|node_network_receive_bytes_total|node_network_transmit_bytes_total|node_network_receive_drop_total|node_network_transmit_drop_total|node_disk_io_time_seconds_total|node_disk_io_time_weighted_seconds_total|node_load5|node_load15|node_disk_read_bytes_total|node_disk_written_bytes_total|node_uname_info|kubernetes_build_info|node_boot_time_seconds' source_labels: - __name__ - metrics_path: /metrics relabel_configs: - regex: (.*) source_labels: - __metrics_path__ target_label: metrics_path - - replacement: null + - replacement: test-node source_labels: - __address__ target_label: instance - - replacement: linux - source_labels: - - __address__ - target_label: kubernetes_io_os - scheme: https + scheme: http scrape_interval: 30s static_configs: - targets: - - :10250 - tls_config: - ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - insecure_skip_verify: true + - 192.168.1.1:9100 +- job_name: networkobservability-hubble + kubernetes_sd_configs: + - role: service + metric_relabel_configs: + - action: keep + regex: '|hubble.*' + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-system;network-observability;hubble + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_service_port_name + - action: replace + replacement: 192.168.1.1 + source_labels: + - __address__ + target_label: __address__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_port_number + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 30s - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token job_name: cadvisor label_limit: 63 @@ -43,7 +67,7 @@ scrape_configs: - __name__ metrics_path: /metrics/cadvisor relabel_configs: - - replacement: null + - replacement: test-node source_labels: - __address__ target_label: instance @@ -51,38 +75,10 @@ scrape_configs: scrape_interval: 30s static_configs: - targets: - - :10250 + - 192.168.1.1:10250 tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt insecure_skip_verify: true -- job_name: kappie-basic - kubernetes_sd_configs: - - role: service - label_limit: 63 - label_name_length_limit: 511 - label_value_length_limit: 1023 - metric_relabel_configs: - - action: keep - regex: '|kappie.*' - source_labels: - - __name__ - relabel_configs: - - action: keep - regex: kube-system;kappie-svc - source_labels: - - __meta_kubernetes_namespace - - __meta_kubernetes_service_name - - action: replace - replacement: :10093 - source_labels: - - __address__ - target_label: __address__ - - replacement: null - source_labels: - - __address__ - target_label: instance - scheme: http - scrape_interval: 30s - job_name: networkobservability-retina kubernetes_sd_configs: - role: service @@ -99,7 +95,7 @@ scrape_configs: - __meta_kubernetes_service_name - __meta_kubernetes_service_port_name - action: replace - replacement: null + replacement: 192.168.1.1 source_labels: - __address__ target_label: __address__ @@ -110,48 +106,52 @@ scrape_configs: - __address__ - __meta_kubernetes_service_port_number target_label: __address__ - - replacement: null + - replacement: test-node source_labels: - __address__ target_label: instance scheme: http scrape_interval: 30s -- job_name: networkobservability-hubble - kubernetes_sd_configs: - - role: service +- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: kubelet + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 metric_relabel_configs: - action: keep - regex: '|hubble.*' + regex: '|kubelet_volume_stats_capacity_bytes|kubelet_volume_stats_used_bytes|kubelet_node_name|kubelet_running_pods|kubelet_running_pod_count|kubelet_running_sum_containers|kubelet_running_containers|kubelet_running_container_count|volume_manager_total_volumes|kubelet_node_config_error|kubelet_runtime_operations_total|kubelet_runtime_operations_errors_total|kubelet_runtime_operations_duration_seconds_bucket|kubelet_runtime_operations_duration_seconds_sum|kubelet_runtime_operations_duration_seconds_count|kubelet_pod_start_duration_seconds_bucket|kubelet_pod_start_duration_seconds_sum|kubelet_pod_start_duration_seconds_count|kubelet_pod_worker_duration_seconds_bucket|kubelet_pod_worker_duration_seconds_sum|kubelet_pod_worker_duration_seconds_count|storage_operation_duration_seconds_bucket|storage_operation_duration_seconds_sum|storage_operation_duration_seconds_count|storage_operation_errors_total|kubelet_cgroup_manager_duration_seconds_bucket|kubelet_cgroup_manager_duration_seconds_sum|kubelet_cgroup_manager_duration_seconds_count|kubelet_pleg_relist_interval_seconds_bucket|kubelet_pleg_relist_interval_seconds_count|kubelet_pleg_relist_interval_seconds_sum|kubelet_pleg_relist_duration_seconds_bucket|kubelet_pleg_relist_duration_seconds_count|kubelet_pleg_relist_duration_seconds_sum|rest_client_requests_total|rest_client_request_duration_seconds_bucket|rest_client_request_duration_seconds_sum|rest_client_request_duration_seconds_count|process_resident_memory_bytes|process_cpu_seconds_total|go_goroutines|kubernetes_build_info|kubelet_certificate_manager_client_ttl_seconds|kubelet_certificate_manager_client_expiration_renew_errors|kubelet_server_expiration_renew_errors|kubelet_certificate_manager_server_ttl_seconds|kubelet_volume_stats_available_bytes|kubelet_volume_stats_capacity_bytes|kubelet_volume_stats_inodes_free|kubelet_volume_stats_inodes_used|kubelet_volume_stats_inodes|kube_persistentvolumeclaim_access_mode|kube_persistentvolumeclaim_labels|kube_persistentvolume_status_phase' source_labels: - __name__ + metrics_path: /metrics relabel_configs: - - action: keep - regex: kube-system;network-observability;hubble - source_labels: - - __meta_kubernetes_namespace - - __meta_kubernetes_service_name - - __meta_kubernetes_service_port_name - - action: replace - replacement: null + - regex: (.*) source_labels: - - __address__ - target_label: __address__ - - action: replace - regex: ([^:]+)(?::\d+)?;(\d+) - replacement: $1:$2 + - __metrics_path__ + target_label: metrics_path + - replacement: test-node source_labels: - __address__ - - __meta_kubernetes_service_port_number - target_label: __address__ - - replacement: null + target_label: instance + - replacement: linux source_labels: - __address__ - target_label: instance - scheme: http + target_label: kubernetes_io_os + scheme: https scrape_interval: 30s + static_configs: + - targets: + - 192.168.1.1:10250 + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true - job_name: networkobservability-cilium kubernetes_sd_configs: - role: service + metric_relabel_configs: + - action: keep + regex: '|cilium_drop.*|cilium_forward.*' + source_labels: + - __name__ relabel_configs: - action: keep regex: kube-system;network-observability;cilium @@ -160,7 +160,7 @@ scrape_configs: - __meta_kubernetes_service_name - __meta_kubernetes_service_port_name - action: replace - replacement: null + replacement: 192.168.1.1 source_labels: - __address__ target_label: __address__ @@ -171,7 +171,7 @@ scrape_configs: - __address__ - __meta_kubernetes_service_port_number target_label: __address__ - - replacement: null + - replacement: test-node source_labels: - __address__ target_label: instance diff --git a/otelcollector/shared/configmap/mp/testdata/default-linux-rs.yaml b/otelcollector/shared/configmap/mp/testdata/default-linux-rs.yaml index 466155858..b9b6674fe 100644 --- a/otelcollector/shared/configmap/mp/testdata/default-linux-rs.yaml +++ b/otelcollector/shared/configmap/mp/testdata/default-linux-rs.yaml @@ -12,3 +12,87 @@ scrape_configs: static_configs: - targets: - ama-metrics-ksm.kube-system.svc.cluster.local:8080 +- honor_labels: true + job_name: acstor-capacity-provisioner + kubernetes_sd_configs: + - namespaces: + names: + - acstor + role: pod + metric_relabel_configs: + - action: keep + regex: '|storage_pool_ready_state|storage_pool_capacity_used_bytes|storage_pool_capacity_provisioned_bytes|storage_pool_snapshot_capacity_reserved_bytes' + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: acstor + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: capacity-provisioner;capacity-provisoner + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_name + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 30s +- honor_labels: true + job_name: local-csi-driver + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: pod + metric_relabel_configs: + - action: keep + regex: '|rpc.server.duration_milliseconds_bucket|rpc.server.duration_milliseconds_sum|rpc.server.duration_milliseconds_count|rpc_server_duration_milliseconds_bucket|rpc_server_duration_milliseconds_sum|rpc_server_duration_milliseconds_count' + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-system + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: csi-local-node + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 30s +- honor_labels: true + job_name: acstor-metrics-exporter + kubernetes_sd_configs: + - namespaces: + names: + - acstor + - kube-system + role: pod + metric_relabel_configs: + - action: keep + regex: '|disk_read_operations_completed_total|disk_write_operations_completed_total|disk_read_operations_time_seconds_total|disk_write_operations_time_seconds_total|disk_read_bytes_total|disk_written_bytes_total|disk_reads_merged_total|disk_writes_merged_total|disk_io_now|disk_io_time_seconds_total|disk_io_time_weighted_seconds_total|disk_discard_operations_completed_total|disk_discards_merged_total|disk_discarded_sectors_total|disk_discard_operations_time_seconds_total|disk_flush_requests_total|disk_flush_requests_time_seconds_total|disk_errors_total|disk_readonly_errors_gauge|disk_readonly_status_gauge' + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: acstor|kube-system + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: (metrics-exporter;monitor)|(storage-operator;node-agent)|(node-agent;node-agent) + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_name + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 30s \ No newline at end of file diff --git a/otelcollector/shared/configmap/mp/testdata/no-minimal-linux-ds.yaml b/otelcollector/shared/configmap/mp/testdata/no-minimal-linux-ds.yaml new file mode 100644 index 000000000..722571fe0 --- /dev/null +++ b/otelcollector/shared/configmap/mp/testdata/no-minimal-linux-ds.yaml @@ -0,0 +1,179 @@ +scrape_configs: +- job_name: networkobservability-retina + kubernetes_sd_configs: + - role: service + metric_relabel_configs: + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-system;network-observability;retina + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_service_port_name + - action: replace + replacement: 192.168.1.1 + source_labels: + - __address__ + target_label: __address__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_port_number + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 30s +- job_name: networkobservability-cilium + kubernetes_sd_configs: + - role: service + metric_relabel_configs: + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-system;network-observability;cilium + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_service_port_name + - action: replace + replacement: 192.168.1.1 + source_labels: + - __address__ + target_label: __address__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_port_number + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 30s +- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: kubelet + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + metrics_path: /metrics + relabel_configs: + - regex: (.*) + source_labels: + - __metrics_path__ + target_label: metrics_path + - replacement: test-node + source_labels: + - __address__ + target_label: instance + - replacement: linux + source_labels: + - __address__ + target_label: kubernetes_io_os + scheme: https + scrape_interval: 30s + static_configs: + - targets: + - 192.168.1.1:10250 + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true +- job_name: node + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - regex: (.*) + source_labels: + - __metrics_path__ + target_label: metrics_path + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 30s + static_configs: + - targets: + - 192.168.1.1:9100 +- job_name: networkobservability-hubble + kubernetes_sd_configs: + - role: service + metric_relabel_configs: + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-system;network-observability;hubble + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_service_port_name + - action: replace + replacement: 192.168.1.1 + source_labels: + - __address__ + target_label: __address__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_port_number + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 30s +- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: cadvisor + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + metrics_path: /metrics/cadvisor + relabel_configs: + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: https + scrape_interval: 30s + static_configs: + - targets: + - 192.168.1.1:10250 + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true diff --git a/otelcollector/shared/configmap/mp/testdata/no-minimal-linux-rs.yaml b/otelcollector/shared/configmap/mp/testdata/no-minimal-linux-rs.yaml new file mode 100644 index 000000000..83411beeb --- /dev/null +++ b/otelcollector/shared/configmap/mp/testdata/no-minimal-linux-rs.yaml @@ -0,0 +1,98 @@ +scrape_configs: +- job_name: kube-state-metrics + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + scrape_interval: 30s + static_configs: + - targets: + - ama-metrics-ksm.kube-system.svc.cluster.local:8080 +- honor_labels: true + job_name: acstor-capacity-provisioner + kubernetes_sd_configs: + - namespaces: + names: + - acstor + role: pod + metric_relabel_configs: + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: acstor + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: capacity-provisioner;capacity-provisoner + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_name + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 30s +- honor_labels: true + job_name: local-csi-driver + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: pod + metric_relabel_configs: + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-system + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: csi-local-node + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 30s +- honor_labels: true + job_name: acstor-metrics-exporter + kubernetes_sd_configs: + - namespaces: + names: + - acstor + - kube-system + role: pod + metric_relabel_configs: + - action: keep + regex: test.*|test2 + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: acstor|kube-system + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: (metrics-exporter;monitor)|(storage-operator;node-agent)|(node-agent;node-agent) + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_name + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 30s diff --git a/otelcollector/shared/configmap/mp/testdata/no-minimal-no-keeplist-ds.yaml b/otelcollector/shared/configmap/mp/testdata/no-minimal-no-keeplist-ds.yaml new file mode 100644 index 000000000..af066e54c --- /dev/null +++ b/otelcollector/shared/configmap/mp/testdata/no-minimal-no-keeplist-ds.yaml @@ -0,0 +1,149 @@ +scrape_configs: +- job_name: networkobservability-retina + kubernetes_sd_configs: + - role: service + relabel_configs: + - action: keep + regex: kube-system;network-observability;retina + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_service_port_name + - action: replace + replacement: 192.168.1.1 + source_labels: + - __address__ + target_label: __address__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_port_number + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 30s +- job_name: networkobservability-cilium + kubernetes_sd_configs: + - role: service + relabel_configs: + - action: keep + regex: kube-system;network-observability;cilium + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_service_port_name + - action: replace + replacement: 192.168.1.1 + source_labels: + - __address__ + target_label: __address__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_port_number + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 30s +- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: kubelet + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metrics_path: /metrics + relabel_configs: + - regex: (.*) + source_labels: + - __metrics_path__ + target_label: metrics_path + - replacement: test-node + source_labels: + - __address__ + target_label: instance + - replacement: linux + source_labels: + - __address__ + target_label: kubernetes_io_os + scheme: https + scrape_interval: 30s + static_configs: + - targets: + - 192.168.1.1:10250 + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true +- job_name: node + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + relabel_configs: + - regex: (.*) + source_labels: + - __metrics_path__ + target_label: metrics_path + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 30s + static_configs: + - targets: + - 192.168.1.1:9100 +- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: cadvisor + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metrics_path: /metrics/cadvisor + relabel_configs: + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: https + scrape_interval: 30s + static_configs: + - targets: + - 192.168.1.1:10250 + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true +- job_name: networkobservability-hubble + kubernetes_sd_configs: + - role: service + relabel_configs: + - action: keep + regex: kube-system;network-observability;hubble + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_service_port_name + - action: replace + replacement: 192.168.1.1 + source_labels: + - __address__ + target_label: __address__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_port_number + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 30s diff --git a/otelcollector/shared/configmap/mp/testdata/no-minimal-no-keeplist-rs.yaml b/otelcollector/shared/configmap/mp/testdata/no-minimal-no-keeplist-rs.yaml new file mode 100644 index 000000000..deabdb6b1 --- /dev/null +++ b/otelcollector/shared/configmap/mp/testdata/no-minimal-no-keeplist-rs.yaml @@ -0,0 +1,78 @@ +scrape_configs: +- job_name: kube-state-metrics + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + scrape_interval: 30s + static_configs: + - targets: + - ama-metrics-ksm.kube-system.svc.cluster.local:8080 +- honor_labels: true + job_name: acstor-capacity-provisioner + kubernetes_sd_configs: + - namespaces: + names: + - acstor + role: pod + relabel_configs: + - action: keep + regex: acstor + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: capacity-provisioner;capacity-provisoner + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_name + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 30s +- honor_labels: true + job_name: acstor-metrics-exporter + kubernetes_sd_configs: + - namespaces: + names: + - acstor + - kube-system + role: pod + relabel_configs: + - action: keep + regex: acstor|kube-system + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: (metrics-exporter;monitor)|(storage-operator;node-agent)|(node-agent;node-agent) + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_name + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 30s +- honor_labels: true + job_name: local-csi-driver + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: pod + relabel_configs: + - action: keep + regex: kube-system + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: csi-local-node + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 30s diff --git a/otelcollector/shared/configmap/mp/testdata/no-scrape-jobs-linux-rs.yaml b/otelcollector/shared/configmap/mp/testdata/no-scrape-jobs-linux-rs.yaml new file mode 100644 index 000000000..e69de29bb diff --git a/otelcollector/shared/configmap/mp/testdata/not-all-sections-linux-ds.yaml b/otelcollector/shared/configmap/mp/testdata/not-all-sections-linux-ds.yaml new file mode 100644 index 000000000..ddade707f --- /dev/null +++ b/otelcollector/shared/configmap/mp/testdata/not-all-sections-linux-ds.yaml @@ -0,0 +1,179 @@ +scrape_configs: +- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: cadvisor + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2|container_spec_cpu_quota|container_spec_cpu_period|container_memory_rss|container_network_receive_bytes_total|container_network_transmit_bytes_total|container_network_receive_packets_total|container_network_transmit_packets_total|container_network_receive_packets_dropped_total|container_network_transmit_packets_dropped_total|container_fs_reads_total|container_fs_writes_total|container_fs_reads_bytes_total|container_fs_writes_bytes_total|container_cpu_usage_seconds_total|container_memory_working_set_bytes|container_memory_cache|container_memory_swap|container_cpu_cfs_throttled_periods_total|container_cpu_cfs_periods_total|container_memory_rss|kubernetes_build_info|container_start_time_seconds + source_labels: + - __name__ + metrics_path: /metrics/cadvisor + relabel_configs: + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: https + scrape_interval: 15s + static_configs: + - targets: + - 192.168.1.1:10250 + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true +- job_name: networkobservability-cilium + kubernetes_sd_configs: + - role: service + metric_relabel_configs: + - action: keep + regex: test.*|test2|cilium_drop.*|cilium_forward.* + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-system;network-observability;cilium + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_service_port_name + - action: replace + replacement: 192.168.1.1 + source_labels: + - __address__ + target_label: __address__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_port_number + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 15s +- job_name: networkobservability-retina + kubernetes_sd_configs: + - role: service + metric_relabel_configs: + - action: keep + regex: test.*|test2|networkobservability.* + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-system;network-observability;retina + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_service_port_name + - action: replace + replacement: 192.168.1.1 + source_labels: + - __address__ + target_label: __address__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_port_number + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 15s +- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: kubelet + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2|kubelet_volume_stats_capacity_bytes|kubelet_volume_stats_used_bytes|kubelet_node_name|kubelet_running_pods|kubelet_running_pod_count|kubelet_running_sum_containers|kubelet_running_containers|kubelet_running_container_count|volume_manager_total_volumes|kubelet_node_config_error|kubelet_runtime_operations_total|kubelet_runtime_operations_errors_total|kubelet_runtime_operations_duration_seconds_bucket|kubelet_runtime_operations_duration_seconds_sum|kubelet_runtime_operations_duration_seconds_count|kubelet_pod_start_duration_seconds_bucket|kubelet_pod_start_duration_seconds_sum|kubelet_pod_start_duration_seconds_count|kubelet_pod_worker_duration_seconds_bucket|kubelet_pod_worker_duration_seconds_sum|kubelet_pod_worker_duration_seconds_count|storage_operation_duration_seconds_bucket|storage_operation_duration_seconds_sum|storage_operation_duration_seconds_count|storage_operation_errors_total|kubelet_cgroup_manager_duration_seconds_bucket|kubelet_cgroup_manager_duration_seconds_sum|kubelet_cgroup_manager_duration_seconds_count|kubelet_pleg_relist_interval_seconds_bucket|kubelet_pleg_relist_interval_seconds_count|kubelet_pleg_relist_interval_seconds_sum|kubelet_pleg_relist_duration_seconds_bucket|kubelet_pleg_relist_duration_seconds_count|kubelet_pleg_relist_duration_seconds_sum|rest_client_requests_total|rest_client_request_duration_seconds_bucket|rest_client_request_duration_seconds_sum|rest_client_request_duration_seconds_count|process_resident_memory_bytes|process_cpu_seconds_total|go_goroutines|kubernetes_build_info|kubelet_certificate_manager_client_ttl_seconds|kubelet_certificate_manager_client_expiration_renew_errors|kubelet_server_expiration_renew_errors|kubelet_certificate_manager_server_ttl_seconds|kubelet_volume_stats_available_bytes|kubelet_volume_stats_capacity_bytes|kubelet_volume_stats_inodes_free|kubelet_volume_stats_inodes_used|kubelet_volume_stats_inodes|kube_persistentvolumeclaim_access_mode|kube_persistentvolumeclaim_labels|kube_persistentvolume_status_phase + source_labels: + - __name__ + metrics_path: /metrics + relabel_configs: + - regex: (.*) + source_labels: + - __metrics_path__ + target_label: metrics_path + - replacement: test-node + source_labels: + - __address__ + target_label: instance + - replacement: linux + source_labels: + - __address__ + target_label: kubernetes_io_os + scheme: https + scrape_interval: 15s + static_configs: + - targets: + - 192.168.1.1:10250 + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true +- job_name: node + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2|node_filesystem_readonly|node_memory_MemTotal_bytes|node_cpu_seconds_total|node_memory_MemAvailable_bytes|node_memory_Buffers_bytes|node_memory_Cached_bytes|node_memory_MemFree_bytes|node_memory_Slab_bytes|node_filesystem_avail_bytes|node_filesystem_size_bytes|node_time_seconds|node_exporter_build_info|node_load1|node_vmstat_pgmajfault|node_network_receive_bytes_total|node_network_transmit_bytes_total|node_network_receive_drop_total|node_network_transmit_drop_total|node_disk_io_time_seconds_total|node_disk_io_time_weighted_seconds_total|node_load5|node_load15|node_disk_read_bytes_total|node_disk_written_bytes_total|node_uname_info|kubernetes_build_info|node_boot_time_seconds + source_labels: + - __name__ + relabel_configs: + - regex: (.*) + source_labels: + - __metrics_path__ + target_label: metrics_path + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 15s + static_configs: + - targets: + - 192.168.1.1:9100 +- job_name: networkobservability-hubble + kubernetes_sd_configs: + - role: service + metric_relabel_configs: + - action: keep + regex: test.*|test2|hubble.* + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-system;network-observability;hubble + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_service_port_name + - action: replace + replacement: 192.168.1.1 + source_labels: + - __address__ + target_label: __address__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_port_number + target_label: __address__ + - replacement: test-node + source_labels: + - __address__ + target_label: instance + scheme: http + scrape_interval: 15s diff --git a/otelcollector/shared/configmap/mp/testdata/not-all-sections-linux-rs.yaml b/otelcollector/shared/configmap/mp/testdata/not-all-sections-linux-rs.yaml new file mode 100644 index 000000000..25606e653 --- /dev/null +++ b/otelcollector/shared/configmap/mp/testdata/not-all-sections-linux-rs.yaml @@ -0,0 +1,141 @@ +scrape_configs: +- job_name: kubernetes-pods + kubernetes_sd_configs: + - role: pod + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2| + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: true + source_labels: + - __meta_kubernetes_pod_annotation_prometheus_io_scrape + - action: replace + regex: (.+) + source_labels: + - __meta_kubernetes_pod_annotation_prometheus_io_path + target_label: __metrics_path__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_pod_annotation_prometheus_io_port + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: kubernetes_namespace + - action: replace + source_labels: + - __meta_kubernetes_pod_name + target_label: kubernetes_pod_name + - action: keep + regex: .*|value + source_labels: + - __meta_kubernetes_namespace + scrape_interval: 15s +- honor_labels: true + job_name: acstor-capacity-provisioner + kubernetes_sd_configs: + - namespaces: + names: + - acstor + role: pod + metric_relabel_configs: + - action: keep + regex: test.*|test2|storage_pool_ready_state|storage_pool_capacity_used_bytes|storage_pool_capacity_provisioned_bytes|storage_pool_snapshot_capacity_reserved_bytes + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: acstor + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: capacity-provisioner;capacity-provisoner + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_name + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 15s +- job_name: kube-state-metrics + label_limit: 63 + label_name_length_limit: 511 + label_value_length_limit: 1023 + metric_relabel_configs: + - action: keep + regex: test.*|test2|kube_job_status_succeeded|kube_job_spec_completions|kube_daemonset_status_desired_number_scheduled|kube_daemonset_status_current_number_scheduled|kube_daemonset_status_number_misscheduled|kube_daemonset_status_number_ready|kube_deployment_status_replicas_ready|kube_pod_container_status_last_terminated_reason|kube_pod_container_status_waiting_reason|kube_pod_container_status_restarts_total|kube_node_status_allocatable|kube_pod_owner|kube_pod_container_resource_requests|kube_pod_status_phase|kube_pod_container_resource_limits|kube_replicaset_owner|kube_resourcequota|kube_namespace_status_phase|kube_node_status_capacity|kube_node_info|kube_pod_info|kube_deployment_spec_replicas|kube_deployment_status_replicas_available|kube_deployment_status_replicas_updated|kube_statefulset_status_replicas_ready|kube_statefulset_status_replicas|kube_statefulset_status_replicas_updated|kube_job_status_start_time|kube_job_status_active|kube_job_failed|kube_horizontalpodautoscaler_status_desired_replicas|kube_horizontalpodautoscaler_status_current_replicas|kube_horizontalpodautoscaler_spec_min_replicas|kube_horizontalpodautoscaler_spec_max_replicas|kubernetes_build_info|kube_node_status_condition|kube_node_spec_taint|kube_pod_container_info|kube_.*_labels|kube_.*_annotations|kube_service_info|kube_pod_container_status_running|kube_pod_container_status_waiting|kube_pod_container_status_terminated|kube_pod_container_state_started|kube_pod_created|kube_pod_start_time|kube_pod_init_container_info|kube_pod_init_container_status_terminated|kube_pod_init_container_status_terminated_reason|kube_pod_init_container_status_ready|kube_pod_init_container_resource_limits|kube_pod_init_container_status_running|kube_pod_init_container_status_waiting|kube_pod_init_container_status_restarts_total|kube_pod_container_status_ready|kube_pod_init_container_*|kube_pod_deletion_timestamp|kube_pod_status_reason|kube_pod_init_container_resource_requests + source_labels: + - __name__ + scrape_interval: 15s + static_configs: + - targets: + - ama-metrics-ksm.kube-system.svc.cluster.local:8080 +- honor_labels: true + job_name: local-csi-driver + kubernetes_sd_configs: + - namespaces: + names: + - kube-system + role: pod + metric_relabel_configs: + - action: keep + regex: test.*|test2|rpc.server.duration_milliseconds_bucket|rpc.server.duration_milliseconds_sum|rpc.server.duration_milliseconds_count|rpc_server_duration_milliseconds_bucket|rpc_server_duration_milliseconds_sum|rpc_server_duration_milliseconds_count + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: kube-system + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: csi-local-node + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 15s +- honor_labels: true + job_name: acstor-metrics-exporter + kubernetes_sd_configs: + - namespaces: + names: + - acstor + - kube-system + role: pod + metric_relabel_configs: + - action: keep + regex: test.*|test2|disk_read_operations_completed_total|disk_write_operations_completed_total|disk_read_operations_time_seconds_total|disk_write_operations_time_seconds_total|disk_read_bytes_total|disk_written_bytes_total|disk_reads_merged_total|disk_writes_merged_total|disk_io_now|disk_io_time_seconds_total|disk_io_time_weighted_seconds_total|disk_discard_operations_completed_total|disk_discards_merged_total|disk_discarded_sectors_total|disk_discard_operations_time_seconds_total|disk_flush_requests_total|disk_flush_requests_time_seconds_total|disk_errors_total|disk_readonly_errors_gauge|disk_readonly_status_gauge + source_labels: + - __name__ + relabel_configs: + - action: keep + regex: acstor|kube-system + source_labels: + - __meta_kubernetes_namespace + - action: keep + regex: (metrics-exporter;monitor)|(storage-operator;node-agent)|(node-agent;node-agent) + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_name + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - action: keep + regex: metrics + source_labels: + - __meta_kubernetes_pod_container_port_name + scheme: http + scrape_interval: 15s diff --git a/otelcollector/shared/configmap/mp/tomlparser-default-scrape-settings.go b/otelcollector/shared/configmap/mp/tomlparser-default-scrape-settings.go index 361e26277..d5e3eb45d 100644 --- a/otelcollector/shared/configmap/mp/tomlparser-default-scrape-settings.go +++ b/otelcollector/shared/configmap/mp/tomlparser-default-scrape-settings.go @@ -4,271 +4,89 @@ import ( "fmt" "log" "os" - "regexp" "strings" -) - -func (fcl *FilesystemConfigLoader) SetDefaultScrapeSettings() (map[string]string, error) { - config := make(map[string]string) - // Set default values - config["kubelet"] = "true" - config["coredns"] = "false" - config["cadvisor"] = "true" - config["kubeproxy"] = "false" - config["apiserver"] = "false" - config["kubestate"] = "true" - config["nodeexporter"] = "true" - config["prometheuscollectorhealth"] = "false" - config["windowsexporter"] = "false" - config["windowskubeproxy"] = "false" - config["kappiebasic"] = "true" - config["networkobservabilityRetina"] = "true" - config["networkobservabilityHubble"] = "true" - config["networkobservabilityCilium"] = "true" - config["noDefaultsEnabled"] = "false" - config["acstor-capacity-provisioner"] = "true" - config["acstor-metrics-exporter"] = "true" - config["local-csi-driver"] = "true" - config["ztunnel"] = "false" - config["istio-cni"] = "false" - config["waypoint-proxy"] = "false" - config["dcgmexporter"] = "false" - return config, nil -} + "github.com/prometheus-collector/shared" + cmcommon "github.com/prometheus-collector/shared/configmap/common" +) -func (fcl *FilesystemConfigLoader) ParseConfigMapForDefaultScrapeSettings(metricsConfigBySection map[string]map[string]string, schemaVersion string) (map[string]string, error) { - config := make(map[string]string) - // Set default values - config["kubelet"] = "true" - config["coredns"] = "false" - config["cadvisor"] = "true" - config["kubeproxy"] = "false" - config["apiserver"] = "false" - config["kubestate"] = "true" - config["nodeexporter"] = "true" - config["prometheuscollectorhealth"] = "false" - config["windowsexporter"] = "false" - config["windowskubeproxy"] = "false" - config["kappiebasic"] = "true" - config["networkobservabilityRetina"] = "true" - config["networkobservabilityHubble"] = "true" - config["networkobservabilityCilium"] = "true" - config["noDefaultsEnabled"] = "false" - config["acstor-capacity-provisioner"] = "true" - config["acstor-metrics-exporter"] = "true" - config["local-csi-driver"] = "true" - config["ztunnel"] = "false" - config["istio-cni"] = "false" - config["waypoint-proxy"] = "false" - config["dcgmexporter"] = "false" +var NoDefaultsEnabled bool +func PopulateSettingValues(metricsConfigBySection map[string]map[string]string, schemaVersion string) error { configSectionName := "default-scrape-settings-enabled" - if schemaVersion == "v2" { + if schemaVersion == shared.SchemaVersion.V2 { configSectionName = "default-targets-scrape-enabled" } - // Override defaults with values from metricsConfigBySection - if settings, ok := metricsConfigBySection[configSectionName]; ok { - for key, value := range settings { - if _, ok := config[key]; ok { - config[key] = value - } + settings, ok := metricsConfigBySection[configSectionName] + if !ok { + log.Println("ParseConfigMapForDefaultScrapeSettings::No default-targets-scrape-enabled section found, using defaults") + NoDefaultsEnabled = cmcommon.DetermineNoDefaultsEnabled( + shared.DefaultScrapeJobs, + os.Getenv("CONTROLLER_TYPE"), + os.Getenv("CONTAINER_TYPE"), + strings.ToLower(os.Getenv("OS_TYPE")), + ) + if NoDefaultsEnabled { + log.Printf("No default scrape configs enabled\n") } + return nil } - log.Println("Using configmap for default scrape settings...") - return config, nil -} - -func (cp *ConfigProcessor) PopulateSettingValues(parsedConfig map[string]string) { - if val, ok := parsedConfig["kubelet"]; ok && val != "" { - cp.Kubelet = val - log.Printf("config::Using scrape settings for kubelet: %v\n", cp.Kubelet) - } - - if val, ok := parsedConfig["coredns"]; ok && val != "" { - cp.Coredns = val - log.Printf("config::Using scrape settings for coredns: %v\n", cp.Coredns) - } - - if val, ok := parsedConfig["cadvisor"]; ok && val != "" { - cp.Cadvisor = val - log.Printf("config::Using scrape settings for cadvisor: %v\n", cp.Cadvisor) - } - - if val, ok := parsedConfig["kubeproxy"]; ok && val != "" { - cp.Kubeproxy = val - log.Printf("config::Using scrape settings for kubeproxy: %v\n", cp.Kubeproxy) - } - - if val, ok := parsedConfig["apiserver"]; ok && val != "" { - cp.Apiserver = val - log.Printf("config::Using scrape settings for apiserver: %v\n", cp.Apiserver) - } - - if val, ok := parsedConfig["kubestate"]; ok && val != "" { - cp.Kubestate = val - log.Printf("config::Using scrape settings for kubestate: %v\n", cp.Kubestate) - } - - if val, ok := parsedConfig["nodeexporter"]; ok && val != "" { - cp.NodeExporter = val - log.Printf("config::Using scrape settings for nodeexporter: %v\n", cp.NodeExporter) - } - - if val, ok := parsedConfig["prometheuscollectorhealth"]; ok && val != "" { - cp.PrometheusCollectorHealth = val - log.Printf("config::Using scrape settings for prometheuscollectorhealth: %v\n", cp.PrometheusCollectorHealth) - } - - if val, ok := parsedConfig["windowsexporter"]; ok && val != "" { - cp.Windowsexporter = val - log.Printf("config::Using scrape settings for windowsexporter: %v\n", cp.Windowsexporter) - } - - if val, ok := parsedConfig["windowskubeproxy"]; ok && val != "" { - cp.Windowskubeproxy = val - log.Printf("config::Using scrape settings for windowskubeproxy: %v\n", cp.Windowskubeproxy) - } - - if val, ok := parsedConfig["kappiebasic"]; ok && val != "" { - cp.Kappiebasic = val - log.Printf("config::Using scrape settings for kappiebasic: %v\n", cp.Kappiebasic) - } - - if val, ok := parsedConfig["networkobservabilityRetina"]; ok && val != "" { - cp.NetworkObservabilityRetina = val - log.Printf("config::Using scrape settings for networkobservabilityRetina: %v\n", cp.NetworkObservabilityRetina) - } - - if val, ok := parsedConfig["networkobservabilityHubble"]; ok && val != "" { - cp.NetworkObservabilityHubble = val - log.Printf("config::Using scrape settings for networkobservabilityHubble: %v\n", cp.NetworkObservabilityHubble) + if err := cmcommon.UpdateJobEnablement(settings, shared.DefaultScrapeJobs, schemaVersion, func(name string, schema string) string { + return name + }); err != nil { + return fmt.Errorf("ParseConfigMapForDefaultScrapeSettings::%w", err) } - if val, ok := parsedConfig["networkobservabilityCilium"]; ok && val != "" { - cp.NetworkObservabilityCilium = val - log.Printf("config::Using scrape settings for networkobservabilityCilium: %v\n", cp.NetworkObservabilityCilium) + NoDefaultsEnabled = cmcommon.DetermineNoDefaultsEnabled( + shared.DefaultScrapeJobs, + os.Getenv("CONTROLLER_TYPE"), + os.Getenv("CONTAINER_TYPE"), + strings.ToLower(os.Getenv("OS_TYPE")), + ) + if NoDefaultsEnabled { + log.Printf("No default scrape configs enabled\n") } - if val, ok := parsedConfig["acstor-capacity-provisioner"]; ok && val != "" { - cp.AcstorCapacityProvisioner = val - log.Printf("config:: Using scrape settings for acstor-capacity-provisioner: %v\n", cp.AcstorCapacityProvisioner) - } - - if val, ok := parsedConfig["acstor-metrics-exporter"]; ok && val != "" { - cp.AcstorMetricsExporter = val - log.Printf("config:: Using scrape settings for acstor-metrics-exporter: %v\n", cp.AcstorMetricsExporter) - } - - if val, ok := parsedConfig["local-csi-driver"]; ok && val != "" { - cp.LocalCSIDriver = val - log.Printf("config:: Using scrape settings for local-csi-driver: %v\n", cp.LocalCSIDriver) - } - - if val, ok := parsedConfig["ztunnel"]; ok && val != "" { - cp.Ztunnel = val - fmt.Printf("config:: Using scrape settings for ztunnel: %v\n", cp.Ztunnel) - } - - if val, ok := parsedConfig["istio-cni"]; ok && val != "" { - cp.IstioCni = val - fmt.Printf("config:: Using scrape settings for istio-cni: %v\n", cp.IstioCni) - } - - if val, ok := parsedConfig["waypoint-proxy"]; ok && val != "" { - cp.WaypointProxy = val - fmt.Printf("config:: Using scrape settings for waypoint-proxy: %v\n", cp.WaypointProxy) - } - - if val, ok := parsedConfig["dcgmexporter"]; ok && val != "" { - cp.DcgmExporter = val - fmt.Printf("config:: Using scrape settings for dcgmexporter: %v\n", cp.DcgmExporter) - } - - if os.Getenv("MODE") == "" && strings.ToLower(strings.TrimSpace(os.Getenv("MODE"))) == "advanced" { - controllerType := os.Getenv("CONTROLLER_TYPE") - if controllerType == "ReplicaSet" && strings.ToLower(os.Getenv("OS_TYPE")) == "linux" && - cp.Kubelet == "" && cp.Cadvisor == "" && - cp.NodeExporter == "" && cp.PrometheusCollectorHealth == "" && cp.Kappiebasic == "" { - cp.NoDefaultsEnabled = true - } - } else if cp.Kubelet == "" && cp.Cadvisor == "" && - cp.NodeExporter == "" && cp.PrometheusCollectorHealth == "" && cp.Kappiebasic == "" { - cp.NoDefaultsEnabled = true - } - - if cp.NoDefaultsEnabled { - log.Printf("No default scrape configs enabled") - } + return nil } func (fcw *FileConfigWriter) WriteDefaultScrapeSettingsToFile(filename string, cp *ConfigProcessor) error { - file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) - if err != nil { - return fmt.Errorf("Exception while opening file for writing prometheus-collector config environment variables: %s", err) + formatter := func(jobName string) string { + return strings.ToUpper(jobName) + "_SCRAPING_ENABLED" } - defer file.Close() - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_KUBELET_SCRAPING_ENABLED=%v\n", cp.Kubelet)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_COREDNS_SCRAPING_ENABLED=%v\n", cp.Coredns)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_CADVISOR_SCRAPING_ENABLED=%v\n", cp.Cadvisor)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_KUBEPROXY_SCRAPING_ENABLED=%v\n", cp.Kubeproxy)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_APISERVER_SCRAPING_ENABLED=%v\n", cp.Apiserver)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_KUBESTATE_SCRAPING_ENABLED=%v\n", cp.Kubestate)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_NODEEXPORTER_SCRAPING_ENABLED=%v\n", cp.NodeExporter)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_COLLECTOR_HEALTH_SCRAPING_ENABLED=%v\n", cp.PrometheusCollectorHealth)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_WINDOWSEXPORTER_SCRAPING_ENABLED=%v\n", cp.Windowsexporter)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_WINDOWSKUBEPROXY_SCRAPING_ENABLED=%v\n", cp.Windowskubeproxy)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_KAPPIEBASIC_SCRAPING_ENABLED=%v\n", cp.Kappiebasic)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_NETWORKOBSERVABILITYRETINA_SCRAPING_ENABLED=%v\n", cp.NetworkObservabilityRetina)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_NETWORKOBSERVABILITYHUBBLE_SCRAPING_ENABLED=%v\n", cp.NetworkObservabilityHubble)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_NETWORKOBSERVABILITYCILIUM_SCRAPING_ENABLED=%v\n", cp.NetworkObservabilityCilium)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_NO_DEFAULT_SCRAPING_ENABLED=%v\n", cp.NoDefaultsEnabled)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_ACSTORCAPACITYPROVISIONER_SCRAPING_ENABLED=%v\n", cp.AcstorCapacityProvisioner)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_ACSTORMETRICSEXPORTER_SCRAPING_ENABLED=%v\n", cp.AcstorMetricsExporter)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_LOCALCSIDRIVER_SCRAPING_ENABLED=%v\n", cp.LocalCSIDriver)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_ZTUNNEL_SCRAPING_ENABLED=%v\n", cp.Ztunnel)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_ISTIOCNI_SCRAPING_ENABLED=%v\n", cp.IstioCni)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_WAYPOINT_PROXY_SCRAPING_ENABLED=%v\n", cp.WaypointProxy)) - file.WriteString(fmt.Sprintf("AZMON_PROMETHEUS_DCGMEXPORTER_SCRAPING_ENABLED=%v\n", cp.DcgmExporter)) + if err := cmcommon.WriteEnabledEnvFile(filename, shared.DefaultScrapeJobs, formatter, NoDefaultsEnabled); err != nil { + return err + } + log.Println("No default scrape configs enabled:", NoDefaultsEnabled) return nil } -func (c *Configurator) ConfigureDefaultScrapeSettings(metricsConfigBySection map[string]map[string]string) { - configSchemaVersion := os.Getenv("AZMON_AGENT_CFG_SCHEMA_VERSION") - - log.Printf("Start prometheus-collector-settings Processing\n") +func (c *Configurator) ConfigureDefaultScrapeSettings(metricsConfigBySection map[string]map[string]string, configSchemaVersion string) { + log.Println("Start prometheus-collector-settings Processing") // Load default settings based on the schema version - var defaultSettings map[string]string var err error - if configSchemaVersion != "" && (strings.TrimSpace(configSchemaVersion) == "v1" || strings.TrimSpace(configSchemaVersion) == "v2") { - defaultSettings, err = c.ConfigLoader.ParseConfigMapForDefaultScrapeSettings(metricsConfigBySection, configSchemaVersion) + if configSchemaVersion == shared.SchemaVersion.V1 || configSchemaVersion == shared.SchemaVersion.V2 { + log.Println("ConfigureDefaultScrapeSettings::Loading settings from config map") } else { - defaultSettings, err = c.ConfigLoader.SetDefaultScrapeSettings() + // Initialize with an empty metrics config map if none is provided + log.Println("ConfigureDefaultScrapeSettings::Loading default settings") + metricsConfigBySection = make(map[string]map[string]string) } + // Populate and print setting values + err = PopulateSettingValues(metricsConfigBySection, configSchemaVersion) if err != nil { log.Printf("Error loading default settings: %v\n", err) return } - // Populate and print setting values - c.ConfigParser.PopulateSettingValues(defaultSettings) - // Set cluster alias - if mac := os.Getenv("MAC"); mac != "" && strings.TrimSpace(mac) == "true" { - clusterArray := strings.Split(strings.TrimSpace(os.Getenv("CLUSTER")), "/") - c.ConfigParser.ClusterAlias = clusterArray[len(clusterArray)-1] - } else { - c.ConfigParser.ClusterAlias = os.Getenv("CLUSTER") - } - - if c.ConfigParser.ClusterAlias != "" && len(c.ConfigParser.ClusterAlias) > 0 { - c.ConfigParser.ClusterAlias = regexp.MustCompile(`[^0-9a-zA-Z]+`).ReplaceAllString(c.ConfigParser.ClusterAlias, "_") - c.ConfigParser.ClusterAlias = strings.Trim(c.ConfigParser.ClusterAlias, "_") + c.ConfigParser.ClusterAlias = cmcommon.ComputeClusterAlias(os.Getenv("CLUSTER"), os.Getenv("MAC")) + if c.ConfigParser.ClusterAlias != "" { log.Printf("After replacing non-alpha-numeric characters with '_': %s\n", c.ConfigParser.ClusterAlias) } @@ -282,11 +100,9 @@ func (c *Configurator) ConfigureDefaultScrapeSettings(metricsConfigBySection map log.Printf("End prometheus-collector-settings Processing\n") } -func tomlparserDefaultScrapeSettings(metricsConfigBySection map[string]map[string]string) { - - configSchemaVersion := os.Getenv("AZMON_AGENT_CFG_SCHEMA_VERSION") +func tomlparserDefaultScrapeSettings(metricsConfigBySection map[string]map[string]string, configSchemaVersion string) { configLoaderPath := defaultSettingsMountPath - if configSchemaVersion != "" && strings.TrimSpace(configSchemaVersion) == "v2" { + if configSchemaVersion == shared.SchemaVersion.V2 { configLoaderPath = defaultSettingsMountPathv2 } @@ -297,5 +113,5 @@ func tomlparserDefaultScrapeSettings(metricsConfigBySection map[string]map[strin ConfigParser: &ConfigProcessor{}, } - configurator.ConfigureDefaultScrapeSettings(metricsConfigBySection) + configurator.ConfigureDefaultScrapeSettings(metricsConfigBySection, configSchemaVersion) } diff --git a/otelcollector/shared/configmap/mp/tomlparser-default-targets-metrics-keep-list.go b/otelcollector/shared/configmap/mp/tomlparser-default-targets-metrics-keep-list.go index f5a1117be..8dc67af81 100644 --- a/otelcollector/shared/configmap/mp/tomlparser-default-targets-metrics-keep-list.go +++ b/otelcollector/shared/configmap/mp/tomlparser-default-targets-metrics-keep-list.go @@ -2,301 +2,36 @@ package configmapsettings import ( "fmt" - "io/fs" "log" - "os" "strings" "github.com/prometheus-collector/shared" - "gopkg.in/yaml.v2" + cmcommon "github.com/prometheus-collector/shared/configmap/common" ) -var ( - configSchemaVersion string - kubeletRegex, coreDNSRegex, cAdvisorRegex, kubeProxyRegex string - apiserverRegex, kubeStateRegex, nodeExporterRegex, kappieBasicRegex string - windowsExporterRegex, windowsKubeProxyRegex string - networkobservabilityRetinaRegex, networkobservabilityHubbleRegex string - networkobservabilityCiliumRegex, podAnnotationsRegex string - acstorCapacityProvisionerRegex, acstorMetricsExporterRegex string - localCSIDriverRegex string - ztunnelRegex, istioCniRegex, waypointRegex string - dcgmExporterRegex string - kubeletRegex_minimal_mac = "kubelet_volume_stats_capacity_bytes|kubelet_volume_stats_used_bytes|kubelet_node_name|kubelet_running_pods|kubelet_running_pod_count|kubelet_running_sum_containers|kubelet_running_containers|kubelet_running_container_count|volume_manager_total_volumes|kubelet_node_config_error|kubelet_runtime_operations_total|kubelet_runtime_operations_errors_total|kubelet_runtime_operations_duration_seconds_bucket|kubelet_runtime_operations_duration_seconds_sum|kubelet_runtime_operations_duration_seconds_count|kubelet_pod_start_duration_seconds_bucket|kubelet_pod_start_duration_seconds_sum|kubelet_pod_start_duration_seconds_count|kubelet_pod_worker_duration_seconds_bucket|kubelet_pod_worker_duration_seconds_sum|kubelet_pod_worker_duration_seconds_count|storage_operation_duration_seconds_bucket|storage_operation_duration_seconds_sum|storage_operation_duration_seconds_count|storage_operation_errors_total|kubelet_cgroup_manager_duration_seconds_bucket|kubelet_cgroup_manager_duration_seconds_sum|kubelet_cgroup_manager_duration_seconds_count|kubelet_pleg_relist_interval_seconds_bucket|kubelet_pleg_relist_interval_seconds_count|kubelet_pleg_relist_interval_seconds_sum|kubelet_pleg_relist_duration_seconds_bucket|kubelet_pleg_relist_duration_seconds_count|kubelet_pleg_relist_duration_seconds_sum|rest_client_requests_total|rest_client_request_duration_seconds_bucket|rest_client_request_duration_seconds_sum|rest_client_request_duration_seconds_count|process_resident_memory_bytes|process_cpu_seconds_total|go_goroutines|kubernetes_build_info|kubelet_certificate_manager_client_ttl_seconds|kubelet_certificate_manager_client_expiration_renew_errors|kubelet_server_expiration_renew_errors|kubelet_certificate_manager_server_ttl_seconds|kubelet_volume_stats_available_bytes|kubelet_volume_stats_capacity_bytes|kubelet_volume_stats_inodes_free|kubelet_volume_stats_inodes_used|kubelet_volume_stats_inodes|kube_persistentvolumeclaim_access_mode|kube_persistentvolumeclaim_labels|kube_persistentvolume_status_phase" - coreDNSRegex_minimal_mac = "coredns_build_info|coredns_panics_total|coredns_dns_responses_total|coredns_forward_responses_total|coredns_dns_request_duration_seconds|coredns_dns_request_duration_seconds_bucket|coredns_dns_request_duration_seconds_sum|coredns_dns_request_duration_seconds_count|coredns_forward_request_duration_seconds|coredns_forward_request_duration_seconds_bucket|coredns_forward_request_duration_seconds_sum|coredns_forward_request_duration_seconds_count|coredns_dns_requests_total|coredns_forward_requests_total|coredns_cache_hits_total|coredns_cache_misses_total|coredns_cache_entries|coredns_plugin_enabled|coredns_dns_request_size_bytes|coredns_dns_request_size_bytes_bucket|coredns_dns_request_size_bytes_sum|coredns_dns_request_size_bytes_count|coredns_dns_response_size_bytes|coredns_dns_response_size_bytes_bucket|coredns_dns_response_size_bytes_sum|coredns_dns_response_size_bytes_count|coredns_dns_response_size_bytes_bucket|coredns_dns_response_size_bytes_sum|coredns_dns_response_size_bytes_count|process_resident_memory_bytes|process_cpu_seconds_total|go_goroutines|kubernetes_build_info" - cadvisorRegex_minimal_mac = "container_spec_cpu_quota|container_spec_cpu_period|container_memory_rss|container_network_receive_bytes_total|container_network_transmit_bytes_total|container_network_receive_packets_total|container_network_transmit_packets_total|container_network_receive_packets_dropped_total|container_network_transmit_packets_dropped_total|container_fs_reads_total|container_fs_writes_total|container_fs_reads_bytes_total|container_fs_writes_bytes_total|container_cpu_usage_seconds_total|container_memory_working_set_bytes|container_memory_cache|container_memory_swap|container_cpu_cfs_throttled_periods_total|container_cpu_cfs_periods_total|container_memory_rss|kubernetes_build_info|container_start_time_seconds" - kubeproxyRegex_minimal_mac = "kubeproxy_sync_proxy_rules_duration_seconds|kubeproxy_sync_proxy_rules_duration_seconds_bucket|kubeproxy_sync_proxy_rules_duration_seconds_sum|kubeproxy_sync_proxy_rules_duration_seconds_count|kubeproxy_network_programming_duration_seconds|kubeproxy_network_programming_duration_seconds_bucket|kubeproxy_network_programming_duration_seconds_sum|kubeproxy_network_programming_duration_seconds_count|rest_client_requests_total|rest_client_request_duration_seconds|rest_client_request_duration_seconds_bucket|rest_client_request_duration_seconds_sum|rest_client_request_duration_seconds_count|process_resident_memory_bytes|process_cpu_seconds_total|go_goroutines|kubernetes_build_info" - apiserverRegex_minimal_mac = "apiserver_request_duration_seconds|apiserver_request_duration_seconds_bucket|apiserver_request_duration_seconds_sum|apiserver_request_duration_seconds_count|apiserver_request_total|workqueue_adds_total|workqueue_depth|workqueue_queue_duration_seconds|workqueue_queue_duration_seconds_bucket|workqueue_queue_duration_seconds_sum|workqueue_queue_duration_seconds_count|process_resident_memory_bytes|process_cpu_seconds_total|go_goroutines|kubernetes_build_info|apiserver_request_slo_duration_seconds_bucket|apiserver_request_slo_duration_seconds_sum|apiserver_request_slo_duration_seconds_count" - kubestateRegex_minimal_mac = "kube_job_status_succeeded|kube_job_spec_completions|kube_daemonset_status_desired_number_scheduled|kube_daemonset_status_current_number_scheduled|kube_daemonset_status_number_misscheduled|kube_daemonset_status_number_ready|kube_deployment_status_replicas_ready|kube_pod_container_status_last_terminated_reason|kube_pod_container_status_waiting_reason|kube_pod_container_status_restarts_total|kube_node_status_allocatable|kube_pod_owner|kube_pod_container_resource_requests|kube_pod_status_phase|kube_pod_container_resource_limits|kube_replicaset_owner|kube_resourcequota|kube_namespace_status_phase|kube_node_status_capacity|kube_node_info|kube_pod_info|kube_deployment_spec_replicas|kube_deployment_status_replicas_available|kube_deployment_status_replicas_updated|kube_statefulset_status_replicas_ready|kube_statefulset_status_replicas|kube_statefulset_status_replicas_updated|kube_job_status_start_time|kube_job_status_active|kube_job_failed|kube_horizontalpodautoscaler_status_desired_replicas|kube_horizontalpodautoscaler_status_current_replicas|kube_horizontalpodautoscaler_spec_min_replicas|kube_horizontalpodautoscaler_spec_max_replicas|kubernetes_build_info|kube_node_status_condition|kube_node_spec_taint|kube_pod_container_info|kube_.*_labels|kube_.*_annotations|kube_service_info|kube_pod_container_status_running|kube_pod_container_status_waiting|kube_pod_container_status_terminated|kube_pod_container_state_started|kube_pod_created|kube_pod_start_time|kube_pod_init_container_info|kube_pod_init_container_status_terminated|kube_pod_init_container_status_terminated_reason|kube_pod_init_container_status_ready|kube_pod_init_container_resource_limits|kube_pod_init_container_status_running|kube_pod_init_container_status_waiting|kube_pod_init_container_status_restarts_total|kube_pod_container_status_ready|kube_pod_init_container_*|kube_pod_deletion_timestamp|kube_pod_status_reason|kube_pod_init_container_resource_requests" - nodeexporterRegex_minimal_mac = "node_filesystem_readonly|node_memory_MemTotal_bytes|node_cpu_seconds_total|node_memory_MemAvailable_bytes|node_memory_Buffers_bytes|node_memory_Cached_bytes|node_memory_MemFree_bytes|node_memory_Slab_bytes|node_filesystem_avail_bytes|node_filesystem_size_bytes|node_time_seconds|node_exporter_build_info|node_load1|node_vmstat_pgmajfault|node_network_receive_bytes_total|node_network_transmit_bytes_total|node_network_receive_drop_total|node_network_transmit_drop_total|node_disk_io_time_seconds_total|node_disk_io_time_weighted_seconds_total|node_load5|node_load15|node_disk_read_bytes_total|node_disk_written_bytes_total|node_uname_info|kubernetes_build_info|node_boot_time_seconds" - kappiebasicRegex_minimal_mac = "kappie.*" - networkobservabilityRetinaRegex_minimal_mac = "networkobservability.*" - networkobservabilityHubbleRegex_minimal_mac = "hubble_dns_queries_total|hubble_dns_responses_total|hubble_drop_total|hubble_tcp_flags_total" - networkobservabilityCiliumRegex_minimal_mac = "cilium_drop.*|cilium_forward.*" - windowsexporterRegex_minimal_mac = "windows_system_boot_time_timestamp_seconds|windows_system_system_up_time|windows_cpu_time_total|windows_memory_available_bytes|windows_os_visible_memory_bytes|windows_memory_cache_bytes|windows_memory_modified_page_list_bytes|windows_memory_standby_cache_core_bytes|windows_memory_standby_cache_normal_priority_bytes|windows_memory_standby_cache_reserve_bytes|windows_memory_swap_page_operations_total|windows_logical_disk_read_seconds_total|windows_logical_disk_write_seconds_total|windows_logical_disk_size_bytes|windows_logical_disk_free_bytes|windows_net_bytes_total|windows_net_packets_received_discarded_total|windows_net_packets_outbound_discarded_total|windows_container_available|windows_container_cpu_usage_seconds_total|windows_container_memory_usage_commit_bytes|windows_container_memory_usage_private_working_set_bytes|windows_container_network_receive_bytes_total|windows_container_network_transmit_bytes_total" - windowskubeproxyRegex_minimal_mac = "kubeproxy_sync_proxy_rules_duration_seconds|kubeproxy_sync_proxy_rules_duration_seconds_bucket|kubeproxy_sync_proxy_rules_duration_seconds_sum|kubeproxy_sync_proxy_rules_duration_seconds_count|rest_client_requests_total|rest_client_request_duration_seconds|rest_client_request_duration_seconds_bucket|rest_client_request_duration_seconds_sum|rest_client_request_duration_seconds_count|process_resident_memory_bytes|process_cpu_seconds_total|go_goroutines" - acstorCapacityProvisionerRegex_minimal_mac = "storage_pool_ready_state|storage_pool_capacity_used_bytes|storage_pool_capacity_provisioned_bytes|storage_pool_snapshot_capacity_reserved_bytes" - acstorMetricsExporter_minimal_mac = "disk_read_operations_completed_total|disk_write_operations_completed_total|disk_read_operations_time_seconds_total|disk_write_operations_time_seconds_total|disk_read_bytes_total|disk_written_bytes_total|disk_reads_merged_total|disk_writes_merged_total|disk_io_now|disk_io_time_seconds_total|disk_io_time_weighted_seconds_total|disk_discard_operations_completed_total|disk_discards_merged_total|disk_discarded_sectors_total|disk_discard_operations_time_seconds_total|disk_flush_requests_total|disk_flush_requests_time_seconds_total|disk_errors_total|disk_readonly_errors_gauge|disk_readonly_status_gauge" - //These metrics are somewhere getting transformed from rpc_server.duration_milliseconds_bucket to rpc.server.duration_milliseconds_bucket. - // It's not clear where this is happening, so we are keeping both regexes for now. Once we find the root cause, we can remove one of them. - localCsiDriver_minimal_mac = "rpc.server.duration_milliseconds_bucket|rpc.server.duration_milliseconds_sum|rpc.server.duration_milliseconds_count|rpc_server_duration_milliseconds_bucket|rpc_server_duration_milliseconds_sum|rpc_server_duration_milliseconds_count" - ztunnel_minimal_mac = "istio_build|istio_xds_connection_terminations_total|istio_xds_message_total|istio_tcp_connections_opened_total|istio_tcp_connections_closed_total|istio_tcp_sent_bytes_total|istio_tcp_received_bytes_total|istio_dns_requests_total|workload_manager_active_proxy_count|workload_manager_pending_proxy_count" - istioCni_minimal_mac = "istio_cni_install_ready|istio_cni_installs_total|nodeagent_reconcile_events_total|ztunnel_connected" - waypoint_minimal_mac = "istio_build|istio_requests_total|istio_request_duration_milliseconds_sum|istio_request_duration_milliseconds_count|envoy_cluster_upstream_cx_active|envoy_cluster_upstream_cx_connect_fail|envoy_server_memory_allocated" - dcgmexporter_minimal_mac = "DCGM_.*" -) - -// getStringValue checks the type of the value and returns it as a string if possible. -func getStringValue(value interface{}) string { - switch v := value.(type) { - case string: - return v - case bool: - return fmt.Sprintf("%t", v) // Convert boolean to string representation - case nil: - return "" - default: - // Handle other types if needed - return fmt.Sprintf("%v", v) // Convert any other type to its default string representation - } -} - -// populateKeepList initializes the regex keep list with values from metricsConfigBySection. -func populateKeepList(metricsConfigBySection map[string]map[string]string) (RegexValues, error) { - - var keeplist map[string]string - minimalingestionprofile_value := "true" // Default value - - // Handle case when no configmap is present (metricsConfigBySection is nil) - if metricsConfigBySection == nil { - shared.SetEnvAndSourceBashrcOrPowershell("MINIMAL_INGESTION_PROFILE", minimalingestionprofile_value, true) - keeplist = make(map[string]string) // Empty keeplist for other values - } else { - // Configmap is present, proceed with normal logic - keeplist = metricsConfigBySection["default-targets-metrics-keep-list"] - - configSchemaVersion := os.Getenv("AZMON_AGENT_CFG_SCHEMA_VERSION") - if configSchemaVersion != "" && strings.TrimSpace(configSchemaVersion) == "v1" { - // default value of schema version is v1 for no configmap + partial configmap with missing schema version scenario + configmap with v1 schema version - val := getStringValue(keeplist["minimalingestionprofile"]) - if val == "false" { - minimalingestionprofile_value = "false" - } else if val == "true" { - minimalingestionprofile_value = "true" - } else { - minimalingestionprofile_value = "true" - } - shared.SetEnvAndSourceBashrcOrPowershell("MINIMAL_INGESTION_PROFILE", minimalingestionprofile_value, true) - } else if configSchemaVersion != "" && strings.TrimSpace(configSchemaVersion) == "v2" { - // configmap with v2 schema version - if minimalProfile := metricsConfigBySection["minimal-ingestion-profile"]; minimalProfile != nil { - val := getStringValue(minimalProfile["enabled"]) - if val == "false" { - minimalingestionprofile_value = "false" - } else if val == "true" { - minimalingestionprofile_value = "true" - } else { - minimalingestionprofile_value = "true" - } - shared.SetEnvAndSourceBashrcOrPowershell("MINIMAL_INGESTION_PROFILE", minimalingestionprofile_value, true) - } - } else { - // handle the case when the schema version is defined but not supported - minimalingestionprofile_value = "true" // Default value for unsupported schema versions - shared.SetEnvAndSourceBashrcOrPowershell("MINIMAL_INGESTION_PROFILE", "true", true) - return RegexValues{}, fmt.Errorf("unsupported/missing config schema version - '%s', using defaults, please use supported schema version", configSchemaVersion) - } - } - - regexValues := RegexValues{ - kubelet: getStringValue(keeplist["kubelet"]), - coredns: getStringValue(keeplist["coredns"]), - cadvisor: getStringValue(keeplist["cadvisor"]), - kubeproxy: getStringValue(keeplist["kubeproxy"]), - apiserver: getStringValue(keeplist["apiserver"]), - kubestate: getStringValue(keeplist["kubestate"]), - nodeexporter: getStringValue(keeplist["nodeexporter"]), - kappiebasic: getStringValue(keeplist["kappiebasic"]), - windowsexporter: getStringValue(keeplist["windowsexporter"]), - windowskubeproxy: getStringValue(keeplist["windowskubeproxy"]), - networkobservabilityretina: getStringValue(keeplist["networkobservabilityRetina"]), - networkobservabilityhubble: getStringValue(keeplist["networkobservabilityHubble"]), - networkobservabilitycilium: getStringValue(keeplist["networkobservabilityCilium"]), - podannotations: getStringValue(keeplist["podannotations"]), - acstorcapacityprovisioner: getStringValue(keeplist["acstor-capacity-provisioner"]), - acstormetricsexporter: getStringValue(keeplist["acstor-metrics-exporter"]), - localcsidriver: getStringValue(keeplist["local-csi-driver"]), - ztunnel: getStringValue(keeplist["ztunnel"]), - istiocni: getStringValue(keeplist["istio-cni"]), - waypoint: getStringValue(keeplist["waypoint-proxy"]), - dcgmexporter: getStringValue(keeplist["dcgmexporter"]), - minimalingestionprofile: minimalingestionprofile_value, - } - - // Validate regex values - if err := validateRegexValues(regexValues); err != nil { - return regexValues, err - } - - return regexValues, nil -} - -func validateRegexValues(regexValues RegexValues) error { - // Define a map of field names to their corresponding values - fields := map[string]string{ - "kubelet": regexValues.kubelet, - "coredns": regexValues.coredns, - "cadvisor": regexValues.cadvisor, - "kubeproxy": regexValues.kubeproxy, - "apiserver": regexValues.apiserver, - "kubestate": regexValues.kubestate, - "nodeexporter": regexValues.nodeexporter, - "kappiebasic": regexValues.kappiebasic, - "windowsexporter": regexValues.windowsexporter, - "windowskubeproxy": regexValues.windowskubeproxy, - "networkobservabilityretina": regexValues.networkobservabilityretina, - "networkobservabilityhubble": regexValues.networkobservabilityhubble, - "networkobservabilitycilium": regexValues.networkobservabilitycilium, - "podannotations": regexValues.podannotations, - "minimalingestionprofile": regexValues.minimalingestionprofile, - "acstor-capacity-provisioner": regexValues.acstorcapacityprovisioner, - "acstor-metrics-exporter": regexValues.acstormetricsexporter, - "local-csi-driver": regexValues.localcsidriver, - "ztunnel": regexValues.ztunnel, - "istio-cni": regexValues.istiocni, - "waypoint-proxy": regexValues.waypoint, - "dcgmexporter": regexValues.dcgmexporter, - } - - // Iterate over the fields and validate each regex - for key, value := range fields { - if value != "" && !isValidRegex(value) { - return fmt.Errorf("invalid regex for %s: %s", key, value) - } - } - - return nil -} - -func populateRegexValuesWithMinimalIngestionProfile(regexValues RegexValues) { - if regexValues.minimalingestionprofile == "true" { - kubeletRegex = fmt.Sprintf("%s|%s", regexValues.kubelet, kubeletRegex_minimal_mac) - coreDNSRegex = fmt.Sprintf("%s|%s", regexValues.coredns, coreDNSRegex_minimal_mac) - cAdvisorRegex = fmt.Sprintf("%s|%s", regexValues.cadvisor, cadvisorRegex_minimal_mac) - kubeProxyRegex = fmt.Sprintf("%s|%s", regexValues.kubeproxy, kubeproxyRegex_minimal_mac) - apiserverRegex = fmt.Sprintf("%s|%s", regexValues.apiserver, apiserverRegex_minimal_mac) - kubeStateRegex = fmt.Sprintf("%s|%s", regexValues.kubestate, kubestateRegex_minimal_mac) - nodeExporterRegex = fmt.Sprintf("%s|%s", regexValues.nodeexporter, nodeexporterRegex_minimal_mac) - kappieBasicRegex = fmt.Sprintf("%s|%s", regexValues.kappiebasic, kappiebasicRegex_minimal_mac) - windowsExporterRegex = fmt.Sprintf("%s|%s", regexValues.windowsexporter, windowsexporterRegex_minimal_mac) - windowsKubeProxyRegex = fmt.Sprintf("%s|%s", regexValues.windowskubeproxy, windowskubeproxyRegex_minimal_mac) - networkobservabilityRetinaRegex = fmt.Sprintf( - "%s|%s", - regexValues.networkobservabilityretina, - networkobservabilityRetinaRegex_minimal_mac, - ) - networkobservabilityHubbleRegex = fmt.Sprintf( - "%s|%s", - regexValues.networkobservabilityhubble, - networkobservabilityHubbleRegex_minimal_mac, - ) - networkobservabilityCiliumRegex = fmt.Sprintf( - "%s|%s", - regexValues.networkobservabilitycilium, - networkobservabilityCiliumRegex_minimal_mac, - ) - podAnnotationsRegex = regexValues.podannotations - acstorCapacityProvisionerRegex = fmt.Sprintf( - "%s|%s", - regexValues.acstorcapacityprovisioner, - acstorCapacityProvisionerRegex_minimal_mac, - ) - acstorMetricsExporterRegex = fmt.Sprintf( - "%s|%s", - regexValues.acstormetricsexporter, - acstorMetricsExporter_minimal_mac, - ) - localCSIDriverRegex = fmt.Sprintf("%s|%s", regexValues.localcsidriver, localCsiDriver_minimal_mac) - ztunnelRegex = fmt.Sprintf("%s|%s", regexValues.ztunnel, ztunnel_minimal_mac) - istioCniRegex = fmt.Sprintf("%s|%s", regexValues.istiocni, istioCni_minimal_mac) - waypointRegex = fmt.Sprintf("%s|%s", regexValues.waypoint, waypoint_minimal_mac) - dcgmExporterRegex = fmt.Sprintf("%s|%s", regexValues.dcgmexporter, dcgmexporter_minimal_mac) - - } else { - log.Println("minimalIngestionProfile:", regexValues.minimalingestionprofile) - - kubeletRegex = regexValues.kubelet - coreDNSRegex = regexValues.coredns - cAdvisorRegex = regexValues.cadvisor - kubeProxyRegex = regexValues.kubeproxy - apiserverRegex = regexValues.apiserver - kubeStateRegex = regexValues.kubestate - nodeExporterRegex = regexValues.nodeexporter - kappieBasicRegex = regexValues.kappiebasic - windowsExporterRegex = regexValues.windowsexporter - windowsKubeProxyRegex = regexValues.windowskubeproxy - networkobservabilityRetinaRegex = regexValues.networkobservabilityretina - networkobservabilityHubbleRegex = regexValues.networkobservabilityhubble - networkobservabilityCiliumRegex = regexValues.networkobservabilitycilium - podAnnotationsRegex = regexValues.podannotations - acstorCapacityProvisionerRegex = regexValues.acstorcapacityprovisioner - acstorMetricsExporterRegex = regexValues.acstormetricsexporter - localCSIDriverRegex = regexValues.localcsidriver - ztunnelRegex = regexValues.ztunnel - istioCniRegex = regexValues.istiocni - waypointRegex = regexValues.waypoint - dcgmExporterRegex = regexValues.dcgmexporter - } -} - -func tomlparserTargetsMetricsKeepList(metricsConfigBySection map[string]map[string]string) { - configSchemaVersion = os.Getenv("AZMON_AGENT_CFG_SCHEMA_VERSION") +func tomlparserTargetsMetricsKeepList(metricsConfigBySection map[string]map[string]string, configSchemaVersion string) { shared.EchoSectionDivider("Start Processing - tomlparserTargetsMetricsKeepList") - var regexValues RegexValues - - regexValues, err := populateKeepList(metricsConfigBySection) - if err != nil { - log.Println("Error populating keep list:", err) - return - } - populateRegexValuesWithMinimalIngestionProfile(regexValues) - - // Write settings to a YAML file. - data := map[string]string{ - "KUBELET_METRICS_KEEP_LIST_REGEX": kubeletRegex, - "COREDNS_METRICS_KEEP_LIST_REGEX": coreDNSRegex, - "CADVISOR_METRICS_KEEP_LIST_REGEX": cAdvisorRegex, - "KUBEPROXY_METRICS_KEEP_LIST_REGEX": kubeProxyRegex, - "APISERVER_METRICS_KEEP_LIST_REGEX": apiserverRegex, - "KUBESTATE_METRICS_KEEP_LIST_REGEX": kubeStateRegex, - "NODEEXPORTER_METRICS_KEEP_LIST_REGEX": nodeExporterRegex, - "WINDOWSEXPORTER_METRICS_KEEP_LIST_REGEX": windowsExporterRegex, - "WINDOWSKUBEPROXY_METRICS_KEEP_LIST_REGEX": windowsKubeProxyRegex, - "POD_ANNOTATION_METRICS_KEEP_LIST_REGEX": podAnnotationsRegex, - "KAPPIEBASIC_METRICS_KEEP_LIST_REGEX": kappieBasicRegex, - "NETWORKOBSERVABILITYRETINA_METRICS_KEEP_LIST_REGEX": networkobservabilityRetinaRegex, - "NETWORKOBSERVABILITYHUBBLE_METRICS_KEEP_LIST_REGEX": networkobservabilityHubbleRegex, - "NETWORKOBSERVABILITYCILIUM_METRICS_KEEP_LIST_REGEX": networkobservabilityCiliumRegex, - "ACSTORCAPACITYPROVISONER_KEEP_LIST_REGEX": acstorCapacityProvisionerRegex, - "ACSTORMETRICSEXPORTER_KEEP_LIST_REGEX": acstorMetricsExporterRegex, - "LOCALCSIDRIVER_KEEP_LIST_REGEX": localCSIDriverRegex, - "ZTUNNEL_METRICS_KEEP_LIST_REGEX": ztunnelRegex, - "ISTIOCNI_METRICS_KEEP_LIST_REGEX": istioCniRegex, - "WAYPOINT_PROXY_METRICS_KEEP_LIST_REGEX": waypointRegex, - "DCGMEXPORTER_METRICS_KEEP_LIST_REGEX": dcgmExporterRegex, + formatter := func(jobName string) string { + return fmt.Sprintf("%s_METRICS_KEEP_LIST_REGEX", strings.ToUpper(jobName)) } - out, err := yaml.Marshal(data) - if err != nil { - log.Println(err.Error()) - return + opts := cmcommon.KeepListOptions{ + Jobs: shared.DefaultScrapeJobs, + MetricsConfig: metricsConfigBySection, + SchemaVersion: configSchemaVersion, + KeepListSection: "default-targets-metrics-keep-list", + MinimalProfileSection: "minimal-ingestion-profile", + MinimalProfileKeyV1: "minimalingestionprofile", + MinimalProfileKeyV2: "enabled", + OutputPath: configMapKeepListEnvVarPath, + EnvVarFormatter: func(jobName string) string { return formatter(jobName) }, + JobKeyFormatter: func(jobName, _ string) string { return jobName }, + MinimalProfileDefaultBool: true, } - err = os.WriteFile(configMapKeepListEnvVarPath, []byte(out), fs.FileMode(0644)) - if err != nil { - log.Printf("Exception while writing to file: %v\n", err) - return + if err := cmcommon.PopulateKeepLists(opts); err != nil { + log.Printf("tomlparserTargetsMetricsKeepList::error populating keep list: %s\n", err.Error()) } shared.EchoSectionDivider("End Processing - tomlparserTargetsMetricsKeepList") diff --git a/otelcollector/shared/configmap/mp/tomlparser-opentelemetry-metrics.go b/otelcollector/shared/configmap/mp/tomlparser-opentelemetry-metrics.go index 25017050a..5be473f02 100644 --- a/otelcollector/shared/configmap/mp/tomlparser-opentelemetry-metrics.go +++ b/otelcollector/shared/configmap/mp/tomlparser-opentelemetry-metrics.go @@ -1,49 +1,13 @@ package configmapsettings import ( - "fmt" "log" - "os" - "strconv" + + cmcommon "github.com/prometheus-collector/shared/configmap/common" ) func ConfigureOpentelemetryMetricsSettings(metricsConfigBySection map[string]map[string]string) error { - if metricsConfigBySection == nil { - return fmt.Errorf("configmap section not mounted, using defaults") - } - - enabled := populateOpentelemetryMetricsSettingValuesFromConfigMap(metricsConfigBySection) - - file, err := os.Create(opentelemetryMetricsEnvVarPath) - if err != nil { - return fmt.Errorf("Exception while opening file for writing prometheus-collector config environment variables: %v\n", err) - } - defer file.Close() - - file.WriteString(fmt.Sprintf("AZMON_FULL_OTLP_ENABLED=%v\n", enabled)) - - log.Printf("Setting AZMON_FULL_OTLP_ENABLED environment variable: %v\n", enabled) - - return nil -} - -func populateOpentelemetryMetricsSettingValuesFromConfigMap(metricsConfigBySection map[string]map[string]string) bool { - enabled := false - - // Access the nested map and value - innerMap, ok := metricsConfigBySection["opentelemetry-metrics"] - if !ok { - return enabled - } - - if val, ok := innerMap["enabled"]; ok { - enabledBool, err := strconv.ParseBool(val) - if err != nil { - log.Printf("Invalid value for opentelemetry-metrics enabled: %s, defaulting to %b\n", enabled) - return enabled - } - enabled = enabledBool - log.Printf("Using configmap setting for opentelemetry-metrics: %v\n", enabled) - } - return enabled + return cmcommon.WriteOtelMetricsEnvFile(metricsConfigBySection, opentelemetryMetricsEnvVarPath, func(format string, args ...interface{}) { + log.Printf(format, args...) + }) } diff --git a/otelcollector/shared/configmap/mp/tomlparser-pod-annotation-based-scraping.go b/otelcollector/shared/configmap/mp/tomlparser-pod-annotation-based-scraping.go index 1bfe663c1..cd7db4d08 100644 --- a/otelcollector/shared/configmap/mp/tomlparser-pod-annotation-based-scraping.go +++ b/otelcollector/shared/configmap/mp/tomlparser-pod-annotation-based-scraping.go @@ -5,6 +5,8 @@ import ( "log" "os" "regexp" + + "github.com/prometheus-collector/shared" ) const ( @@ -34,7 +36,8 @@ func writeConfigToFile(podannotationNamespaceRegex string) error { // Writes the variable to the file in the format: AZMON_PROMETHEUS_POD_ANNOTATION_NAMESPACES_REGEX='value' envVarString := fmt.Sprintf("%s%s='%s'\n", linuxPrefix, envVariableTemplateName, podannotationNamespaceRegex) envVarAnnotationsEnabled := fmt.Sprintf("%s%s=%s\n", linuxPrefix, envVariableAnnotationsEnabledName, "true") - log.Printf("Writing to file: %s%s", envVarString, envVarAnnotationsEnabled) + fmt.Printf("Writing to file: %s%s", envVarString, envVarAnnotationsEnabled) + shared.DefaultScrapeJobs["podannotations"].Enabled = true if _, err := file.WriteString(envVarString); err != nil { return fmt.Errorf("error writing to file: %v", err) diff --git a/otelcollector/shared/configmap/mp/tomlparser-pod-annotation-based-scraping_test.go b/otelcollector/shared/configmap/mp/tomlparser-pod-annotation-based-scraping_test.go deleted file mode 100644 index adf3786bd..000000000 --- a/otelcollector/shared/configmap/mp/tomlparser-pod-annotation-based-scraping_test.go +++ /dev/null @@ -1,183 +0,0 @@ -package configmapsettings - -import ( - "bufio" - "fmt" - "os" - "strings" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" -) - -var _ = Describe("ConfigMapSettings", func() { - Describe("parseConfigMapForPodAnnotations", func() { - AfterEach(func() { - cleanupEnvVars() - }) - - Context("when the config map file exists", func() { - BeforeEach(func() { - // Create a temporary file with the desired content - fileContent := `podannotationnamespaceregex = "^namespace-regex|namespace-regex-2$"` - file, err := os.CreateTemp("", "configmap") - Expect(err).NotTo(HaveOccurred()) - defer file.Close() - - _, err = file.WriteString(fileContent) - Expect(err).NotTo(HaveOccurred()) - - // Set the configMapMountPathForPodAnnotation to the temporary file path - configMapMountPathForPodAnnotation = file.Name() - podAnnotationEnvVarPath = fmt.Sprintf("%s_out", configMapMountPathForPodAnnotation) - - setEnvVars(map[string]string { - "AZMON_OPERATOR_ENABLED": "true", - "CONTAINER_TYPE": "ConfigReaderSidecar", - "CONTROLLER_TYPE": "ReplicaSet", - "OS_TYPE": "linux", - "MODE": "advanced", - "KUBE_STATE_NAME": "ama-metrics-ksm", - "POD_NAMESPACE": "kube-system", - "MAC": "true", - }) - }) - - AfterEach(func() { - Expect(os.Remove(configMapMountPathForPodAnnotation)).To(Succeed()) - }) - - It("should print the configmap namespace regex", func() { - capturedOutput := captureOutput(func() { - err := configurePodAnnotationSettings() - Expect(err).NotTo(HaveOccurred()) - }) - - Expect(capturedOutput).To(ContainSubstring("Using configmap namespace regex for podannotations: ^namespace-regex|namespace-regex-2$")) - }) - - It("should write the config to the output file", func() { - err := configurePodAnnotationSettings() - Expect(err).NotTo(HaveOccurred()) - - content, err := os.ReadFile(podAnnotationEnvVarPath) - Expect(err).NotTo(HaveOccurred()) - Expect(string(content)).To(Equal("AZMON_PROMETHEUS_POD_ANNOTATION_NAMESPACES_REGEX='^namespace-regex|namespace-regex-2$'\nAZMON_PROMETHEUS_POD_ANNOTATION_SCRAPING_ENABLED=true\n")) - }) - }) - - Context("when the config map file does not exist", func() { - BeforeEach(func() { - configMapMountPathForPodAnnotation = "/path/to/nonexistent/file" - setEnvVars(map[string]string { - "AZMON_OPERATOR_ENABLED": "true", - "CONTAINER_TYPE": "ConfigReaderSidecar", - "CONTROLLER_TYPE": "ReplicaSet", - "OS_TYPE": "linux", - "MODE": "advanced", - "KUBE_STATE_NAME": "ama-metrics-ksm", - "POD_NAMESPACE": "kube-system", - "MAC": "true", - }) - }) - - It("should return an error", func() { - err := configurePodAnnotationSettings() - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("configmap section not mounted, using defaults")) - }) - }) - - Context("when the out file does not exist", func() { - BeforeEach(func() { - // Create a temporary file with the desired content - fileContent := `podannotationnamespaceregex = "^namespace-regex|namespace-regex-2$"` - file, err := os.CreateTemp("", "configmap") - Expect(err).NotTo(HaveOccurred()) - defer file.Close() - - _, err = file.WriteString(fileContent) - Expect(err).NotTo(HaveOccurred()) - - // Set the configMapMountPathForPodAnnotation to the temporary file path - configMapMountPathForPodAnnotation = file.Name() - podAnnotationEnvVarPath = "/path/to/nonexistent/file" - - setEnvVars(map[string]string { - "AZMON_OPERATOR_ENABLED": "true", - "CONTAINER_TYPE": "ConfigReaderSidecar", - "CONTROLLER_TYPE": "ReplicaSet", - "OS_TYPE": "linux", - "MODE": "advanced", - "KUBE_STATE_NAME": "ama-metrics-ksm", - "POD_NAMESPACE": "kube-system", - "MAC": "true", - }) - }) - - It("should return an error", func() { - err := configurePodAnnotationSettings() - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("error opening file")) - }) - }) - - Context("when the config map file contains an invalid namespace regex", func() { - BeforeEach(func() { - // Create a temporary file with an invalid regex - fileContent := `podannotationnamespaceregex = "invalid-regex("` - file, err := os.CreateTemp("", "configmap") - Expect(err).NotTo(HaveOccurred()) - defer file.Close() - - _, err = file.WriteString(fileContent) - Expect(err).NotTo(HaveOccurred()) - - // Set the configMapMountPathForPodAnnotation to the temporary file path - configMapMountPathForPodAnnotation = file.Name() - - setEnvVars(map[string]string { - "AZMON_OPERATOR_ENABLED": "true", - "CONTAINER_TYPE": "ConfigReaderSidecar", - "CONTROLLER_TYPE": "ReplicaSet", - "OS_TYPE": "linux", - "MODE": "advanced", - "KUBE_STATE_NAME": "ama-metrics-ksm", - "POD_NAMESPACE": "kube-system", - "MAC": "true", - }) - }) - - AfterEach(func() { - Expect(os.Remove(configMapMountPathForPodAnnotation)).To(Succeed()) - }) - - It("should return an error", func() { - err := configurePodAnnotationSettings() - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("Invalid namespace regex for podannotations")) - }) - }) - }) -}) - -// Helper function to capture the output of fmt.Printf -func captureOutput(f func()) string { - old := os.Stdout - r, w, _ := os.Pipe() - os.Stdout = w - - f() - - w.Close() - os.Stdout = old - - var buf strings.Builder - scanner := bufio.NewScanner(r) - for scanner.Scan() { - buf.WriteString(scanner.Text()) - buf.WriteString("\n") - } - - return buf.String() -} diff --git a/otelcollector/shared/configmap/mp/tomlparser-prometheus-collector-settings.go b/otelcollector/shared/configmap/mp/tomlparser-prometheus-collector-settings.go index 0fa68e744..10bf2d27e 100644 --- a/otelcollector/shared/configmap/mp/tomlparser-prometheus-collector-settings.go +++ b/otelcollector/shared/configmap/mp/tomlparser-prometheus-collector-settings.go @@ -4,44 +4,22 @@ import ( "fmt" "log" "os" - "regexp" "strings" + + cmcommon "github.com/prometheus-collector/shared/configmap/common" ) func (cp *ConfigProcessor) PopulateSettingValuesFromConfigMap(metricsConfigBySection map[string]map[string]string) { - // Populate default metric account name - if settings, ok := metricsConfigBySection["prometheus-collector-settings"]; ok { - if value, ok := settings["default_metric_account_name"]; ok { - cp.DefaultMetricAccountName = value - log.Printf("Using configmap setting for default metric account name: %s\n", cp.DefaultMetricAccountName) - } - } + sharedSettings := cmcommon.CollectorSettings{} + cmcommon.PopulateSharedCollectorSettings(&sharedSettings, metricsConfigBySection, func(format string, args ...interface{}) { + log.Printf(format, args...) + }) - // Populate cluster alias - if settings, ok := metricsConfigBySection["prometheus-collector-settings"]; ok { - if value, ok := settings["cluster_alias"]; ok { - cp.ClusterAlias = strings.TrimSpace(value) - log.Printf("Got configmap setting for cluster_alias: %s\n", cp.ClusterAlias) - if cp.ClusterAlias != "" { - cp.ClusterAlias = regexp.MustCompile(`[^0-9a-zA-Z]+`).ReplaceAllString(cp.ClusterAlias, "_") - cp.ClusterAlias = strings.Trim(cp.ClusterAlias, "_") - log.Printf("After replacing non-alpha-numeric characters with '_': %s\n", cp.ClusterAlias) - } - } - } - - // Populate operator settings - if operatorEnabled := os.Getenv("AZMON_OPERATOR_ENABLED"); operatorEnabled != "" && strings.ToLower(operatorEnabled) == "true" { - cp.IsOperatorEnabledChartSetting = true - if settings, ok := metricsConfigBySection["prometheus-collector-settings"]; ok { - if value, ok := settings["operator_enabled"]; ok { - cp.IsOperatorEnabled = value == "true" - log.Printf("Configmap setting enabling operator: %t\n", cp.IsOperatorEnabled) - } - } - } else { - cp.IsOperatorEnabledChartSetting = false - } + cp.DefaultMetricAccountName = sharedSettings.MetricAccountName + cp.ClusterAlias = sharedSettings.ClusterAlias + cp.ClusterLabel = sharedSettings.ClusterLabel + cp.IsOperatorEnabled = sharedSettings.OperatorEnabled + cp.IsOperatorEnabledChartSetting = sharedSettings.OperatorEnabledChart if operatorHttpsEnabled := os.Getenv("OPERATOR_TARGETS_HTTPS_ENABLED"); operatorHttpsEnabled != "" && strings.ToLower(operatorHttpsEnabled) == "true" { cp.TargetallocatorHttpsEnabledChartSetting = true @@ -68,14 +46,18 @@ func (fcw *FileConfigWriter) WriteConfigToFile(filename string, configParser *Co } defer file.Close() - file.WriteString(fmt.Sprintf("AZMON_DEFAULT_METRIC_ACCOUNT_NAME=%s\n", configParser.DefaultMetricAccountName)) - file.WriteString(fmt.Sprintf("AZMON_CLUSTER_LABEL=%s\n", configParser.ClusterLabel)) - file.WriteString(fmt.Sprintf("AZMON_CLUSTER_ALIAS=%s\n", configParser.ClusterAlias)) - file.WriteString(fmt.Sprintf("AZMON_OPERATOR_ENABLED_CHART_SETTING=%t\n", configParser.IsOperatorEnabledChartSetting)) - if configParser.IsOperatorEnabled { - file.WriteString(fmt.Sprintf("AZMON_OPERATOR_ENABLED=%t\n", configParser.IsOperatorEnabled)) - file.WriteString(fmt.Sprintf("AZMON_OPERATOR_ENABLED_CFG_MAP_SETTING=%t\n", configParser.IsOperatorEnabled)) + sharedSettings := cmcommon.CollectorSettings{ + MetricAccountName: configParser.DefaultMetricAccountName, + ClusterAlias: configParser.ClusterAlias, + ClusterLabel: configParser.ClusterLabel, + OperatorEnabled: configParser.IsOperatorEnabled, + OperatorEnabledChart: configParser.IsOperatorEnabledChartSetting, } + + if err := cmcommon.WriteSharedCollectorSettings(file, sharedSettings); err != nil { + return err + } + file.WriteString(fmt.Sprintf("AZMON_OPERATOR_HTTPS_ENABLED_CHART_SETTING=%t\n", configParser.TargetallocatorHttpsEnabledChartSetting)) file.WriteString(fmt.Sprintf("AZMON_OPERATOR_HTTPS_ENABLED=%t\n", configParser.TargetallocatorHttpsEnabled)) return nil @@ -85,8 +67,10 @@ func (c *Configurator) Configure(metricsConfigBySection map[string]map[string]st configSchemaVersion := os.Getenv("AZMON_AGENT_CFG_SCHEMA_VERSION") log.Printf("Configure:Print the value of AZMON_AGENT_CFG_SCHEMA_VERSION: %s\n", configSchemaVersion) - if configSchemaVersion != "" && (strings.TrimSpace(configSchemaVersion) == "v1" || strings.TrimSpace(configSchemaVersion) == "v2") { - if len(metricsConfigBySection) > 0 { + trimmedSchemaVersion := strings.TrimSpace(configSchemaVersion) + if trimmedSchemaVersion != "" { + normalizedSchema := strings.ToLower(trimmedSchemaVersion) + if normalizedSchema == "v1" || normalizedSchema == "v2" { c.ConfigParser.PopulateSettingValuesFromConfigMap(metricsConfigBySection) } } else { diff --git a/otelcollector/shared/configmap/mp/tomlparser-scrape-interval.go b/otelcollector/shared/configmap/mp/tomlparser-scrape-interval.go index 5e88d4876..d2958660b 100644 --- a/otelcollector/shared/configmap/mp/tomlparser-scrape-interval.go +++ b/otelcollector/shared/configmap/mp/tomlparser-scrape-interval.go @@ -1,13 +1,12 @@ package configmapsettings import ( + "fmt" "log" "os" "regexp" "strings" - "io/fs" - "github.com/prometheus-collector/shared" "gopkg.in/yaml.v2" ) @@ -27,66 +26,22 @@ func checkDuration(duration string) string { return duration } -func getParsedDataValue(metricsConfigBySection map[string]map[string]string, key string) string { - if value, exists := metricsConfigBySection["default-targets-scrape-interval-settings"][key]; exists { - return checkDuration(value) - } - return defaultScrapeInterval -} - -func processConfigMap(metricsConfigBySection map[string]map[string]string) map[string]string { - intervalHash := make(map[string]string) - - configSchemaVersion := os.Getenv("AZMON_AGENT_CFG_SCHEMA_VERSION") - - if configSchemaVersion != "" && (strings.TrimSpace(configSchemaVersion) == "v1" || strings.TrimSpace(configSchemaVersion) == "v2") { - // Use metricsConfigBySection instead of reading from file - intervalHash["KUBELET_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "kubelet") - intervalHash["COREDNS_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "coredns") - intervalHash["CADVISOR_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "cadvisor") - intervalHash["KUBEPROXY_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "kubeproxy") - intervalHash["APISERVER_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "apiserver") - intervalHash["KUBESTATE_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "kubestate") - intervalHash["NODEEXPORTER_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "nodeexporter") - intervalHash["WINDOWSEXPORTER_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "windowsexporter") - intervalHash["WINDOWSKUBEPROXY_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "windowskubeproxy") - intervalHash["PROMETHEUS_COLLECTOR_HEALTH_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "prometheuscollectorhealth") - intervalHash["POD_ANNOTATION_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "podannotations") - intervalHash["KAPPIEBASIC_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "kappiebasic") - intervalHash["NETWORKOBSERVABILITYRETINA_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "networkobservabilityRetina") - intervalHash["NETWORKOBSERVABILITYHUBBLE_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "networkobservabilityHubble") - intervalHash["NETWORKOBSERVABILITYCILIUM_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "networkobservabilityCilium") - intervalHash["ACSTORCAPACITYPROVISIONER_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "acstor-capacity-provisioner") - intervalHash["ACSTORMETRICSEXPORTER_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "acstor-metrics-exporter") - intervalHash["LOCALCSIDRIVER_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "local-csi-driver") - intervalHash["ZTUNNEL_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "ztunnel") - intervalHash["ISTIOCNI_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "istio-cni") - intervalHash["WAYPOINT_PROXY_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "waypoint-proxy") - intervalHash["DCGMEXPORTER_SCRAPE_INTERVAL"] = getParsedDataValue(metricsConfigBySection, "dcgmexporter") - - return intervalHash - } +func processConfigMap(metricsConfigBySection map[string]map[string]string, configSchemaVersion string) { - log.Printf("Setting default scrape interval (%s) for all jobs as no config map is present \n", defaultScrapeInterval) - // Set each value in intervalHash to "30s" from default - keys := []string{ - "KUBELET_SCRAPE_INTERVAL", "COREDNS_SCRAPE_INTERVAL", "CADVISOR_SCRAPE_INTERVAL", - "KUBEPROXY_SCRAPE_INTERVAL", "APISERVER_SCRAPE_INTERVAL", "KUBESTATE_SCRAPE_INTERVAL", - "NODEEXPORTER_SCRAPE_INTERVAL", "WINDOWSEXPORTER_SCRAPE_INTERVAL", - "WINDOWSKUBEPROXY_SCRAPE_INTERVAL", "PROMETHEUS_COLLECTOR_HEALTH_SCRAPE_INTERVAL", - "POD_ANNOTATION_SCRAPE_INTERVAL", "KAPPIEBASIC_SCRAPE_INTERVAL", - "NETWORKOBSERVABILITYRETINA_SCRAPE_INTERVAL", "NETWORKOBSERVABILITYHUBBLE_SCRAPE_INTERVAL", - "NETWORKOBSERVABILITYCILIUM_SCRAPE_INTERVAL", "ACSTORCAPACITYPROVISIONER_SCRAPE_INTERVAL", - "ACSTORMETRICSEXPORTER_SCRAPE_INTERVAL", "LOCALCSIDRIVER_SCRAPE_INTERVAL", - "ZTUNNEL_SCRAPE_INTERVAL", "ISTIOCNI_SCRAPE_INTERVAL", "WAYPOINT_PROXY_SCRAPE_INTERVAL", - "DCGMEXPORTER_SCRAPE_INTERVAL", + if configSchemaVersion == shared.SchemaVersion.Nil { + log.Printf("Setting default scrape interval (%s) for all jobs as no config map is present \n", defaultScrapeInterval) + metricsConfigBySection = map[string]map[string]string{} } - for _, key := range keys { - intervalHash[key] = defaultScrapeInterval + // Process all default jobs + for jobName, job := range shared.DefaultScrapeJobs { + if value, exists := metricsConfigBySection["default-targets-scrape-interval-settings"][jobName]; exists { + interval := checkDuration(value) + if interval != "" { + job.ScrapeInterval = interval + } + } } - - return intervalHash } func writeIntervalHashToFile(intervalHash map[string]string, filePath string) error { @@ -94,21 +49,20 @@ func writeIntervalHashToFile(intervalHash map[string]string, filePath string) er if err != nil { return err } - - err = os.WriteFile(filePath, []byte(out), fs.FileMode(0644)) - if err != nil { - return err - } - return nil + return os.WriteFile(filePath, out, 0644) } -func tomlparserScrapeInterval(metricsConfigBySection map[string]map[string]string) { +func tomlparserScrapeInterval(metricsConfigBySection map[string]map[string]string, configSchemaVersion string) { shared.EchoSectionDivider("Start Processing - tomlparserScrapeInterval") - intervalHash := processConfigMap(metricsConfigBySection) - err := writeIntervalHashToFile(intervalHash, scrapeIntervalEnvVarPath) + processConfigMap(metricsConfigBySection, configSchemaVersion) + + data := map[string]string{} + for jobName, job := range shared.DefaultScrapeJobs { + data[fmt.Sprintf("%s_SCRAPE_INTERVAL", strings.ToUpper(jobName))] = job.ScrapeInterval + } + err := writeIntervalHashToFile(data, scrapeIntervalEnvVarPath) if err != nil { log.Printf("Error writing to file: %v\n", err) - return } shared.EchoSectionDivider("End Processing - tomlparserScrapeInterval") } diff --git a/otelcollector/shared/configmap/mp/tomlparser_debug_mode_test.go b/otelcollector/shared/configmap/mp/tomlparser_debug_mode_test.go deleted file mode 100644 index 14a874adb..000000000 --- a/otelcollector/shared/configmap/mp/tomlparser_debug_mode_test.go +++ /dev/null @@ -1,231 +0,0 @@ -package configmapsettings - -import ( - "fmt" - "io" - "math/rand" - "os" - - ginkgo "github.com/onsi/ginkgo/v2" - gomega "github.com/onsi/gomega" - "gopkg.in/yaml.v2" -) - -var _ = ginkgo.Describe("When parsing debug mode settings", func() { - ginkgo.Context("when debug mode is enabled", func() { - - ginkgo.BeforeEach(func() { - suffix := createRandomString(5) - err := createTempFiles(suffix, `enabled = true`) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - }) - - ginkgo.It("should configure debug mode settings for a linux replica", func() { - os.Setenv("CONTROLLER_TYPE", "ReplicaSet") - os.Setenv("OS_TYPE", "linux") - - err := ConfigureDebugModeSettings() - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - - // Verify that the environment variable file is created - _, err = os.Stat(debugModeEnvVarPath) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - - // Verify the content of the environment variable file - content, err := os.ReadFile(debugModeEnvVarPath) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - gomega.Expect(string(content)).To(gomega.Equal("DEBUG_MODE_ENABLED=true\n")) - - // Verify the modification of the YAML configuration file - config, err := parseYAMLConfigFile(replicaSetCollectorConfig) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - gomega.Expect(config).NotTo(gomega.BeNil()) - gomega.Expect(config["service"].(map[interface{}]interface{})["pipelines"].(map[interface{}]interface{})["metrics"].(map[interface{}]interface{})["exporters"]).To(gomega.Equal([]interface{}{"otlp", "prometheus"})) - }) - - ginkgo.It("should configure debug mode settings for a linux daemonset", func() { - os.Setenv("CONTROLLER_TYPE", "DaemonSet") - os.Setenv("OS_TYPE", "linux") - - err := ConfigureDebugModeSettings() - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - - // Verify that the environment variable file is created - _, err = os.Stat(debugModeEnvVarPath) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - - // Verify the content of the environment variable file - content, err := os.ReadFile(debugModeEnvVarPath) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - gomega.Expect(string(content)).To(gomega.Equal("DEBUG_MODE_ENABLED=true\n")) - - // Verify the modification of the YAML configuration file - config, err := parseYAMLConfigFile(replicaSetCollectorConfig) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - gomega.Expect(config).NotTo(gomega.BeNil()) - gomega.Expect(config["service"].(map[interface{}]interface{})["pipelines"].(map[interface{}]interface{})["metrics"].(map[interface{}]interface{})["exporters"]).To(gomega.Equal([]interface{}{"otlp", "prometheus"})) - }) - - ginkgo.It("should configure debug mode settings for a windows daemonset", func() { - os.Setenv("CONTROLLER_TYPE", "DaemonSet") - os.Setenv("OS_TYPE", "windows") - - err := ConfigureDebugModeSettings() - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - - // Verify that the environment variable file is created - _, err = os.Stat(debugModeEnvVarPath) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - - // Verify the content of the environment variable file - content, err := os.ReadFile(debugModeEnvVarPath) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - gomega.Expect(string(content)).To(gomega.Equal("DEBUG_MODE_ENABLED=true\n")) - - // Verify the modification of the YAML configuration file - config, err := parseYAMLConfigFile(replicaSetCollectorConfig) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - gomega.Expect(config).NotTo(gomega.BeNil()) - gomega.Expect(config["service"].(map[interface{}]interface{})["pipelines"].(map[interface{}]interface{})["metrics"].(map[interface{}]interface{})["exporters"]).To(gomega.Equal([]interface{}{"otlp", "prometheus"})) - }) - - ginkgo.AfterEach(func() { - os.Unsetenv("CONTROLLER_TYPE") - os.Unsetenv("OS_TYPE") - configMapDebugMountPath = "" - debugModeEnvVarPath = "" - replicaSetCollectorConfig = "" - fmt.Println("Cleaning up temp files") - cleanupTempFiles() - }) - }) - - ginkgo.It("should handle a missing config map file", func() { - os.Setenv("CONTROLLER_TYPE", "ReplicaSet") - suffix := createRandomString(5) - ginkgo.DeferCleanup(func() { - cleanupTempFiles() - }) - err := createTempFiles(suffix, "") - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - err = os.Remove(fmt.Sprintf("temp/debug-mode-%s", suffix)) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - - err = ConfigureDebugModeSettings() - gomega.Expect(err).To(gomega.HaveOccurred()) - gomega.Expect(err.Error()).To(gomega.ContainSubstring("configmap section not mounted, using defaults")) - }) - - ginkgo.It("should handle an error while parsing config map", func() { - os.Setenv("CONTROLLER_TYPE", "ReplicaSet") - suffix := createRandomString(5) - ginkgo.DeferCleanup(func() { - cleanupTempFiles() - }) - err := createTempFiles(suffix, ` [ invalid_key = true `) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - - err = ConfigureDebugModeSettings() - gomega.Expect(err).To(gomega.HaveOccurred()) - gomega.Expect(err.Error()).To(gomega.ContainSubstring("exception while parsing config map for debug mode")) - }) - - ginkgo.It("should handle an error while opening environment variable file", func() { - os.Setenv("CONTROLLER_TYPE", "ReplicaSet") - suffix := createRandomString(5) - ginkgo.DeferCleanup(func() { - cleanupTempFiles() - }) - err := createTempFiles(suffix, `enabled = true`) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - debugModeEnvVarPath = "/nonexistant-path/envvarpath" - - err = ConfigureDebugModeSettings() - gomega.Expect(err).To(gomega.HaveOccurred()) - gomega.Expect(err.Error()).To(gomega.ContainSubstring("Exception while opening file for writing prometheus-collector config environment variables")) - }) - - ginkgo.It("should handle an error while reading the replicaset collector config file", func() { - os.Setenv("CONTROLLER_TYPE", "ReplicaSet") - suffix := createRandomString(5) - ginkgo.DeferCleanup(func() { - cleanupTempFiles() - }) - err := createTempFiles(suffix, `enabled = true`) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - replicaSetCollectorConfig = "/nonexistant-path/replicasetconfig" - - err = ConfigureDebugModeSettings() - gomega.Expect(err).To(gomega.HaveOccurred()) - gomega.Expect(err.Error()).To(gomega.ContainSubstring("Exception while setting otlp in the exporter metrics for service pipeline when debug mode is enabled")) - }) -}) - -func parseYAMLConfigFile(filePath string) (map[string]interface{}, error) { - content, err := os.ReadFile(filePath) - if err != nil { - return nil, fmt.Errorf("Exception while reading YAML config file: %v", err) - } - - var config map[string]interface{} - err = yaml.Unmarshal(content, &config) - if err != nil { - return nil, fmt.Errorf("Exception while parsing YAML config file: %v", err) - } - - return config, nil -} - -func createTempFiles(suffix string, debugModeString string) (error) { - err := os.Mkdir("temp", os.ModePerm) - if err != nil { - return err - } - - configMapDebugMountPath = fmt.Sprintf("temp/debug-mode-%s", suffix) - debugModeEnvVarPath = fmt.Sprintf("temp/config_debug_mode_env_var-%s", suffix) - replicaSetCollectorConfig = fmt.Sprintf("temp/collector-config-replicaset-%s.yml", suffix) - sourceFile := "testdata/collector-config-replicaset.yml" - - source, err := os.Open(sourceFile) - if err != nil { - return err - } - defer source.Close() - destination, err := os.Create(replicaSetCollectorConfig) - if err != nil { - return err - } - defer destination.Close() - _, err = io.Copy(destination, source) - if err != nil { - return err - } - - debugModeFile, err := os.Create(configMapDebugMountPath) - if err != nil { - return err - } - defer debugModeFile.Close() - - _, err = debugModeFile.WriteString(debugModeString) - if err != nil { - return err - } - - return nil -} - -func cleanupTempFiles() (error) { - return os.RemoveAll("temp") -} - -func createRandomString(length int) string { - charset := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" - result := make([]byte, length) - for i := 0; i < length; i++ { - result[i] = charset[rand.Intn(len(charset))] - } - - return string(result) -} \ No newline at end of file diff --git a/otelcollector/shared/configmap/testhelpers/go.mod b/otelcollector/shared/configmap/testhelpers/go.mod new file mode 100644 index 000000000..4033b5fd0 --- /dev/null +++ b/otelcollector/shared/configmap/testhelpers/go.mod @@ -0,0 +1,7 @@ +module github.com/prometheus-collector/shared/configmap/testhelpers + +go 1.23.0 + +toolchain go1.23.2 + +require gopkg.in/yaml.v2 v2.4.0 diff --git a/otelcollector/shared/configmap/testhelpers/testhelpers.go b/otelcollector/shared/configmap/testhelpers/testhelpers.go new file mode 100644 index 000000000..e6a66b0d0 --- /dev/null +++ b/otelcollector/shared/configmap/testhelpers/testhelpers.go @@ -0,0 +1,119 @@ +package testhelpers + +import ( + "fmt" + "os" + "path/filepath" + + "gopkg.in/yaml.v2" +) + +// CreateTempFile writes content to a file at dir/name, ensuring the directory exists. +func CreateTempFile(dir, name, content string) (string, error) { + if err := os.MkdirAll(dir, 0755); err != nil { + return "", fmt.Errorf("failed to create directory %s: %w", dir, err) + } + + path := filepath.Join(dir, name) + if err := os.WriteFile(path, []byte(content), 0644); err != nil { + return "", fmt.Errorf("failed to write file %s: %w", path, err) + } + + info, err := os.Stat(path) + if err != nil { + return "", fmt.Errorf("failed to stat file %s: %w", path, err) + } + if info.Size() != int64(len(content)) { + return "", fmt.Errorf("file %s has incorrect size: expected %d, got %d", path, len(content), info.Size()) + } + + return path, nil +} + +// MustCreateTempFile wraps CreateTempFile and panics if any error occurs. +// Intended for use in tests where panics fail the test immediately. +func MustCreateTempFile(dir, name, content string) string { + path, err := CreateTempFile(dir, name, content) + if err != nil { + panic(err) + } + return path +} + +// CopyDirectoryFiles copies all non-directory files from srcDir into dstDir. +func CopyDirectoryFiles(srcDir, dstDir string) error { + if err := os.MkdirAll(dstDir, 0755); err != nil { + return fmt.Errorf("failed to create destination directory %s: %w", dstDir, err) + } + + entries, err := os.ReadDir(srcDir) + if err != nil { + return fmt.Errorf("failed to read source directory %s: %w", srcDir, err) + } + + for _, entry := range entries { + if entry.IsDir() { + continue + } + + srcPath := filepath.Join(srcDir, entry.Name()) + dstPath := filepath.Join(dstDir, entry.Name()) + + data, err := os.ReadFile(srcPath) + if err != nil { + return fmt.Errorf("failed to read file %s: %w", srcPath, err) + } + + if err := os.WriteFile(dstPath, data, 0644); err != nil { + return fmt.Errorf("failed to write file %s: %w", dstPath, err) + } + } + + return nil +} + +// CheckEnvVars verifies that the environment matches the expected key/value pairs. +func CheckEnvVars(expected map[string]string) error { + for key, value := range expected { + if os.Getenv(key) != value { + return fmt.Errorf("expected %s to be %s, but got %s", key, value, os.Getenv(key)) + } + } + return nil +} + +// SetEnvVars applies the provided environment variables. +func SetEnvVars(values map[string]string) error { + for key, value := range values { + if err := os.Setenv(key, value); err != nil { + return fmt.Errorf("failed setting %s: %w", key, err) + } + } + return nil +} + +// UnsetEnvVars removes the supplied environment variables. +func UnsetEnvVars(keys []string) { + for _, key := range keys { + _ = os.Unsetenv(key) + } +} + +// ReadYAMLStringMap loads a YAML file containing a string -> string map. +func ReadYAMLStringMap(path string) (map[string]string, error) { + data, err := os.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("failed to read file %s: %w", path, err) + } + + if len(data) == 0 { + return map[string]string{}, nil + } + + result := make(map[string]string) + if err := yaml.Unmarshal(data, &result); err != nil { + return nil, fmt.Errorf("failed to unmarshal YAML from %s: %w", path, err) + } + + return result, nil +} diff --git a/otelcollector/shared/definitions.go b/otelcollector/shared/definitions.go new file mode 100644 index 000000000..3d3bccc49 --- /dev/null +++ b/otelcollector/shared/definitions.go @@ -0,0 +1,414 @@ +package shared + +import "strings" + +type DefaultScrapeJob struct { + JobName string + Enabled bool + OSType string + KubernetesPlane string + ControllerType string + ScrapeConfigDefinitionFile string + PlaceholderNames []string + MinimalKeepListRegex string + CustomerKeepListRegex string + KeepListRegex string + ScrapeInterval string +} + +type ControllerTypeStrings struct { + ReplicaSet string + DaemonSet string + ConfigReaderSidecar string +} + +var ControllerType = ControllerTypeStrings{ + ReplicaSet: "ReplicaSet", + DaemonSet: "DaemonSet", + ConfigReaderSidecar: "ConfigReaderSidecar", +} + +type OSTypeStrings struct { + Linux string + Windows string +} + +var OSType = OSTypeStrings{ + Linux: "linux", + Windows: "windows", +} + +type KubernetesPlaneStrings struct { + ControlPlane string + DataPlane string +} + +var KubernetesPlane = KubernetesPlaneStrings{ + ControlPlane: "controlplane", + DataPlane: "dataplane", +} + +type SchemaVersionStrings struct { + V1 string + V2 string + Nil string +} + +var SchemaVersion = SchemaVersionStrings{ + V1: "v1", + V2: "v2", + Nil: "", +} + +func ParseSchemaVersion(schema string) string { + sanitizedSchema := strings.ToLower(strings.TrimSpace(schema)) + switch sanitizedSchema { + case "v1": + return SchemaVersion.V1 + case "v2": + return SchemaVersion.V2 + default: + return SchemaVersion.Nil + } +} + +var DefaultScrapeJobs = map[string]*DefaultScrapeJob{ + "kubelet": { + JobName: "kubelet", + Enabled: true, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.DaemonSet, + ScrapeConfigDefinitionFile: "kubeletDefaultDs.yml", + PlaceholderNames: []string{"NODE_NAME", "NODE_IP", "OS_TYPE"}, + MinimalKeepListRegex: "kubelet_volume_stats_capacity_bytes|kubelet_volume_stats_used_bytes|kubelet_node_name|kubelet_running_pods|kubelet_running_pod_count|kubelet_running_sum_containers|kubelet_running_containers|kubelet_running_container_count|volume_manager_total_volumes|kubelet_node_config_error|kubelet_runtime_operations_total|kubelet_runtime_operations_errors_total|kubelet_runtime_operations_duration_seconds_bucket|kubelet_runtime_operations_duration_seconds_sum|kubelet_runtime_operations_duration_seconds_count|kubelet_pod_start_duration_seconds_bucket|kubelet_pod_start_duration_seconds_sum|kubelet_pod_start_duration_seconds_count|kubelet_pod_worker_duration_seconds_bucket|kubelet_pod_worker_duration_seconds_sum|kubelet_pod_worker_duration_seconds_count|storage_operation_duration_seconds_bucket|storage_operation_duration_seconds_sum|storage_operation_duration_seconds_count|storage_operation_errors_total|kubelet_cgroup_manager_duration_seconds_bucket|kubelet_cgroup_manager_duration_seconds_sum|kubelet_cgroup_manager_duration_seconds_count|kubelet_pleg_relist_interval_seconds_bucket|kubelet_pleg_relist_interval_seconds_count|kubelet_pleg_relist_interval_seconds_sum|kubelet_pleg_relist_duration_seconds_bucket|kubelet_pleg_relist_duration_seconds_count|kubelet_pleg_relist_duration_seconds_sum|rest_client_requests_total|rest_client_request_duration_seconds_bucket|rest_client_request_duration_seconds_sum|rest_client_request_duration_seconds_count|process_resident_memory_bytes|process_cpu_seconds_total|go_goroutines|kubernetes_build_info|kubelet_certificate_manager_client_ttl_seconds|kubelet_certificate_manager_client_expiration_renew_errors|kubelet_server_expiration_renew_errors|kubelet_certificate_manager_server_ttl_seconds|kubelet_volume_stats_available_bytes|kubelet_volume_stats_capacity_bytes|kubelet_volume_stats_inodes_free|kubelet_volume_stats_inodes_used|kubelet_volume_stats_inodes|kube_persistentvolumeclaim_access_mode|kube_persistentvolumeclaim_labels|kube_persistentvolume_status_phase", + ScrapeInterval: "30s", + }, + "coredns": { + JobName: "coredns", + Enabled: false, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.ReplicaSet, + ScrapeConfigDefinitionFile: "corednsDefault.yml", + PlaceholderNames: []string{}, + MinimalKeepListRegex: "coredns_build_info|coredns_panics_total|coredns_dns_responses_total|coredns_forward_responses_total|coredns_dns_request_duration_seconds|coredns_dns_request_duration_seconds_bucket|coredns_dns_request_duration_seconds_sum|coredns_dns_request_duration_seconds_count|coredns_forward_request_duration_seconds|coredns_forward_request_duration_seconds_bucket|coredns_forward_request_duration_seconds_sum|coredns_forward_request_duration_seconds_count|coredns_dns_requests_total|coredns_forward_requests_total|coredns_cache_hits_total|coredns_cache_misses_total|coredns_cache_entries|coredns_plugin_enabled|coredns_dns_request_size_bytes|coredns_dns_request_size_bytes_bucket|coredns_dns_request_size_bytes_sum|coredns_dns_request_size_bytes_count|coredns_dns_response_size_bytes|coredns_dns_response_size_bytes_bucket|coredns_dns_response_size_bytes_sum|coredns_dns_response_size_bytes_count|coredns_dns_response_size_bytes_bucket|coredns_dns_response_size_bytes_sum|coredns_dns_response_size_bytes_count|process_resident_memory_bytes|process_cpu_seconds_total|go_goroutines|kubernetes_build_info", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "cadvisor": { + JobName: "cadvisor", + Enabled: true, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.DaemonSet, + ScrapeConfigDefinitionFile: "cadvisorDefaultDs.yml", + PlaceholderNames: []string{}, + MinimalKeepListRegex: "container_spec_cpu_quota|container_spec_cpu_period|container_memory_rss|container_network_receive_bytes_total|container_network_transmit_bytes_total|container_network_receive_packets_total|container_network_transmit_packets_total|container_network_receive_packets_dropped_total|container_network_transmit_packets_dropped_total|container_fs_reads_total|container_fs_writes_total|container_fs_reads_bytes_total|container_fs_writes_bytes_total|container_cpu_usage_seconds_total|container_memory_working_set_bytes|container_memory_cache|container_memory_swap|container_cpu_cfs_throttled_periods_total|container_cpu_cfs_periods_total|container_memory_rss|kubernetes_build_info|container_start_time_seconds", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "kubeproxy": { + JobName: "kubeproxy", + Enabled: false, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.ReplicaSet, + ScrapeConfigDefinitionFile: "kubeproxyDefault.yml", + PlaceholderNames: []string{}, + MinimalKeepListRegex: "kubeproxy_sync_proxy_rules_duration_seconds|kubeproxy_sync_proxy_rules_duration_seconds_bucket|kubeproxy_sync_proxy_rules_duration_seconds_sum|kubeproxy_sync_proxy_rules_duration_seconds_count|kubeproxy_network_programming_duration_seconds|kubeproxy_network_programming_duration_seconds_bucket|kubeproxy_network_programming_duration_seconds_sum|kubeproxy_network_programming_duration_seconds_count|rest_client_requests_total|rest_client_request_duration_seconds|rest_client_request_duration_seconds_bucket|rest_client_request_duration_seconds_sum|rest_client_request_duration_seconds_count|process_resident_memory_bytes|process_cpu_seconds_total|go_goroutines|kubernetes_build_info", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "apiserver": { + JobName: "apiserver", + Enabled: false, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.ReplicaSet, + ScrapeConfigDefinitionFile: "apiserverDefault.yml", + PlaceholderNames: []string{}, + MinimalKeepListRegex: "apiserver_request_duration_seconds|apiserver_request_duration_seconds_bucket|apiserver_request_duration_seconds_sum|apiserver_request_duration_seconds_count|apiserver_request_total|workqueue_adds_total|workqueue_depth|workqueue_queue_duration_seconds|workqueue_queue_duration_seconds_bucket|workqueue_queue_duration_seconds_sum|workqueue_queue_duration_seconds_count|process_resident_memory_bytes|process_cpu_seconds_total|go_goroutines|kubernetes_build_info|apiserver_request_slo_duration_seconds_bucket|apiserver_request_slo_duration_seconds_sum|apiserver_request_slo_duration_seconds_count", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "kubestate": { + JobName: "kubestate", + Enabled: true, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.ReplicaSet, + ScrapeConfigDefinitionFile: "kubestateDefault.yml", + PlaceholderNames: []string{"KUBE_STATE_NAME", "POD_NAMESPACE"}, + MinimalKeepListRegex: "kube_job_status_succeeded|kube_job_spec_completions|kube_daemonset_status_desired_number_scheduled|kube_daemonset_status_current_number_scheduled|kube_daemonset_status_number_misscheduled|kube_daemonset_status_number_ready|kube_deployment_status_replicas_ready|kube_pod_container_status_last_terminated_reason|kube_pod_container_status_waiting_reason|kube_pod_container_status_restarts_total|kube_node_status_allocatable|kube_pod_owner|kube_pod_container_resource_requests|kube_pod_status_phase|kube_pod_container_resource_limits|kube_replicaset_owner|kube_resourcequota|kube_namespace_status_phase|kube_node_status_capacity|kube_node_info|kube_pod_info|kube_deployment_spec_replicas|kube_deployment_status_replicas_available|kube_deployment_status_replicas_updated|kube_statefulset_status_replicas_ready|kube_statefulset_status_replicas|kube_statefulset_status_replicas_updated|kube_job_status_start_time|kube_job_status_active|kube_job_failed|kube_horizontalpodautoscaler_status_desired_replicas|kube_horizontalpodautoscaler_status_current_replicas|kube_horizontalpodautoscaler_spec_min_replicas|kube_horizontalpodautoscaler_spec_max_replicas|kubernetes_build_info|kube_node_status_condition|kube_node_spec_taint|kube_pod_container_info|kube_.*_labels|kube_.*_annotations|kube_service_info|kube_pod_container_status_running|kube_pod_container_status_waiting|kube_pod_container_status_terminated|kube_pod_container_state_started|kube_pod_created|kube_pod_start_time|kube_pod_init_container_info|kube_pod_init_container_status_terminated|kube_pod_init_container_status_terminated_reason|kube_pod_init_container_status_ready|kube_pod_init_container_resource_limits|kube_pod_init_container_status_running|kube_pod_init_container_status_waiting|kube_pod_init_container_status_restarts_total|kube_pod_container_status_ready|kube_pod_init_container_*|kube_pod_deletion_timestamp|kube_pod_status_reason|kube_pod_init_container_resource_requests", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "nodeexporter": { + JobName: "nodeexporter", + Enabled: true, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.DaemonSet, + ScrapeConfigDefinitionFile: "nodeexporterDefaultDs.yml", + PlaceholderNames: []string{"NODE_NAME", "NODE_IP", "NODE_EXPORTER_TARGETPORT"}, + MinimalKeepListRegex: "node_filesystem_readonly|node_memory_MemTotal_bytes|node_cpu_seconds_total|node_memory_MemAvailable_bytes|node_memory_Buffers_bytes|node_memory_Cached_bytes|node_memory_MemFree_bytes|node_memory_Slab_bytes|node_filesystem_avail_bytes|node_filesystem_size_bytes|node_time_seconds|node_exporter_build_info|node_load1|node_vmstat_pgmajfault|node_network_receive_bytes_total|node_network_transmit_bytes_total|node_network_receive_drop_total|node_network_transmit_drop_total|node_disk_io_time_seconds_total|node_disk_io_time_weighted_seconds_total|node_load5|node_load15|node_disk_read_bytes_total|node_disk_written_bytes_total|node_uname_info|kubernetes_build_info|node_boot_time_seconds", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "kappiebasic": { + JobName: "kappiebasic", + Enabled: false, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.DaemonSet, + ScrapeConfigDefinitionFile: "kappieBasicDefaultDs.yml", + PlaceholderNames: []string{}, + MinimalKeepListRegex: "kappie.*", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "windowsexporter": { + JobName: "windowsexporter", + Enabled: false, + OSType: OSType.Windows, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.DaemonSet, + ScrapeConfigDefinitionFile: "windowsexporterDefaultDs.yml", + PlaceholderNames: []string{}, + MinimalKeepListRegex: "windows_system_system_up_time|windows_cpu_time_total|windows_memory_available_bytes|windows_os_visible_memory_bytes|windows_memory_cache_bytes|windows_memory_modified_page_list_bytes|windows_memory_standby_cache_core_bytes|windows_memory_standby_cache_normal_priority_bytes|windows_memory_standby_cache_reserve_bytes|windows_memory_swap_page_operations_total|windows_logical_disk_read_seconds_total|windows_logical_disk_write_seconds_total|windows_logical_disk_size_bytes|windows_logical_disk_free_bytes|windows_net_bytes_total|windows_net_packets_received_discarded_total|windows_net_packets_outbound_discarded_total|windows_container_available|windows_container_cpu_usage_seconds_total|windows_container_memory_usage_commit_bytes|windows_container_memory_usage_private_working_set_bytes|windows_container_network_receive_bytes_total|windows_container_network_transmit_bytes_total", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "windowskubeproxy": { + JobName: "windowskubeproxy", + Enabled: false, + OSType: OSType.Windows, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.DaemonSet, + ScrapeConfigDefinitionFile: "windowskubeproxyDefaultDs.yml", + PlaceholderNames: []string{}, + MinimalKeepListRegex: "kubeproxy_sync_proxy_rules_duration_seconds|kubeproxy_sync_proxy_rules_duration_seconds_bucket|kubeproxy_sync_proxy_rules_duration_seconds_sum|kubeproxy_sync_proxy_rules_duration_seconds_count|rest_client_requests_total|rest_client_request_duration_seconds|rest_client_request_duration_seconds_bucket|rest_client_request_duration_seconds_sum|rest_client_request_duration_seconds_count|process_resident_memory_bytes|process_cpu_seconds_total|go_goroutines", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "dcgmexporter": { + JobName: "dcgmexporter", + Enabled: false, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.ReplicaSet, + ScrapeConfigDefinitionFile: "dcgmExporterDefault.yml", + PlaceholderNames: []string{}, + MinimalKeepListRegex: "DCGM_.*", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "networkobservabilityRetina": { + JobName: "networkobservabilityRetina", + Enabled: true, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.DaemonSet, + ScrapeConfigDefinitionFile: "networkobservabilityRetinaDefaultDs.yml", + PlaceholderNames: []string{}, + MinimalKeepListRegex: "networkobservability.*", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "networkobservabilityHubble": { + JobName: "networkobservabilityHubble", + Enabled: true, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.DaemonSet, + ScrapeConfigDefinitionFile: "networkobservabilityHubbleDefaultDs.yml", + PlaceholderNames: []string{}, + MinimalKeepListRegex: "hubble.*", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "networkobservabilityCilium": { + JobName: "networkobservabilityCilium", + Enabled: true, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.DaemonSet, + ScrapeConfigDefinitionFile: "networkobservabilityCiliumDefaultDs.yml", + PlaceholderNames: []string{}, + MinimalKeepListRegex: "cilium_drop.*|cilium_forward.*", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "podannotations": { + JobName: "podannotations", + Enabled: false, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.ReplicaSet, + ScrapeConfigDefinitionFile: "podannotationsDefault.yml", + PlaceholderNames: []string{"AZMON_PROMETHEUS_POD_ANNOTATION_NAMESPACES_REGEX"}, + MinimalKeepListRegex: "", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "acstor-capacity-provisioner": { + JobName: "acstor-capacity-provisioner", + Enabled: true, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.ReplicaSet, + ScrapeConfigDefinitionFile: "acstorCapacityProvisionerDefaultFile.yml", + PlaceholderNames: []string{}, + MinimalKeepListRegex: "storage_pool_ready_state|storage_pool_capacity_used_bytes|storage_pool_capacity_provisioned_bytes|storage_pool_snapshot_capacity_reserved_bytes", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "acstor-metrics-exporter": { + JobName: "acstor-metrics-exporter", + Enabled: true, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.ReplicaSet, + ScrapeConfigDefinitionFile: "acstorMetricsExporterDefaultFile.yml", + PlaceholderNames: []string{}, + MinimalKeepListRegex: "disk_read_operations_completed_total|disk_write_operations_completed_total|disk_read_operations_time_seconds_total|disk_write_operations_time_seconds_total|disk_read_bytes_total|disk_written_bytes_total|disk_reads_merged_total|disk_writes_merged_total|disk_io_now|disk_io_time_seconds_total|disk_io_time_weighted_seconds_total|disk_discard_operations_completed_total|disk_discards_merged_total|disk_discarded_sectors_total|disk_discard_operations_time_seconds_total|disk_flush_requests_total|disk_flush_requests_time_seconds_total|disk_errors_total|disk_readonly_errors_gauge|disk_readonly_status_gauge", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "local-csi-driver": { + JobName: "local-csi-driver", + Enabled: true, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.ReplicaSet, + ScrapeConfigDefinitionFile: "localCSIDriverDefaultFile.yml", + PlaceholderNames: []string{}, + MinimalKeepListRegex: "rpc.server.duration_milliseconds_bucket|rpc.server.duration_milliseconds_sum|rpc.server.duration_milliseconds_count|rpc_server_duration_milliseconds_bucket|rpc_server_duration_milliseconds_sum|rpc_server_duration_milliseconds_count", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "prometheuscollectorhealth": { + JobName: "prometheuscollectorhealth", + Enabled: false, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.ReplicaSet, + ScrapeConfigDefinitionFile: "prometheusCollectorHealthDefault.yml", + PlaceholderNames: []string{}, + MinimalKeepListRegex: "", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "ztunnel": { + JobName: "ztunnel", + Enabled: false, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.ReplicaSet, + ScrapeConfigDefinitionFile: "ztunnelDefault.yml", + PlaceholderNames: []string{}, + MinimalKeepListRegex: "istio_build|istio_xds_connection_terminations_total|istio_xds_message_total|istio_tcp_connections_opened_total|istio_tcp_connections_closed_total|istio_tcp_sent_bytes_total|istio_tcp_received_bytes_total|istio_dns_requests_total|workload_manager_active_proxy_count|workload_manager_pending_proxy_count", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "istio-cni": { + JobName: "istio-cni", + Enabled: false, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.ReplicaSet, + ScrapeConfigDefinitionFile: "istioCniDefault.yml", + PlaceholderNames: []string{}, + MinimalKeepListRegex: "istio_cni_install_ready|istio_cni_installs_total|nodeagent_reconcile_events_total|ztunnel_connected", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "waypoint-proxy": { + JobName: "waypoint-proxy", + Enabled: false, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.DataPlane, + ControllerType: ControllerType.ReplicaSet, + ScrapeConfigDefinitionFile: "waypointProxyDefault.yml", + PlaceholderNames: []string{}, + MinimalKeepListRegex: "istio_build|istio_requests_total|istio_request_duration_milliseconds_sum|istio_request_duration_milliseconds_count|envoy_cluster_upstream_cx_active|envoy_cluster_upstream_cx_connect_fail|envoy_server_memory_allocated", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, +} + +var ControlPlaneDefaultScrapeJobs = map[string]*DefaultScrapeJob{ + "apiserver": { + JobName: "apiserver", + Enabled: true, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.ControlPlane, + ControllerType: ControllerType.ReplicaSet, + ScrapeConfigDefinitionFile: "controlplane_apiserver.yml", + PlaceholderNames: []string{"POD_NAMESPACE"}, + MinimalKeepListRegex: "apiserver_request_total|apiserver_cache_list_fetched_objects_total|apiserver_cache_list_returned_objects_total|apiserver_flowcontrol_demand_seats_average|apiserver_flowcontrol_current_limit_seats|apiserver_request_sli_duration_seconds_count|apiserver_request_sli_duration_seconds_sum|process_start_time_seconds|apiserver_request_duration_seconds_count|apiserver_request_duration_seconds_sum|apiserver_storage_list_fetched_objects_total|apiserver_storage_list_returned_objects_total|apiserver_current_inflight_requests", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "cluster-autoscaler": { + JobName: "cluster-autoscaler", + Enabled: false, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.ControlPlane, + ControllerType: ControllerType.ReplicaSet, + ScrapeConfigDefinitionFile: "controlplane_cluster_autoscaler.yml", + PlaceholderNames: []string{"POD_NAMESPACE"}, + MinimalKeepListRegex: "rest_client_requests_total|cluster_autoscaler_(last_activity|cluster_safe_to_autoscale|scale_down_in_cooldown|scaled_up_nodes_total|unneeded_nodes_count|unschedulable_pods_count|nodes_count)|cloudprovider_azure_api_request_(errors|duration_seconds_(bucket|count))", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "kube-scheduler": { + JobName: "kube-scheduler", + Enabled: false, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.ControlPlane, + ControllerType: ControllerType.ReplicaSet, + ScrapeConfigDefinitionFile: "controlplane_kube_scheduler.yml", + PlaceholderNames: []string{"POD_NAMESPACE"}, + MinimalKeepListRegex: "scheduler_pending_pods|scheduler_unschedulable_pods|scheduler_pod_scheduling_attempts|scheduler_queue_incoming_pods_total|scheduler_preemption_attempts_total|scheduler_preemption_victims|scheduler_scheduling_attempt_duration_seconds|scheduler_schedule_attempts_total|scheduler_pod_scheduling_duration_seconds", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "kube-controller-manager": { + JobName: "kube-controller-manager", + Enabled: false, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.ControlPlane, + ControllerType: ControllerType.ReplicaSet, + ScrapeConfigDefinitionFile: "controlplane_kube_controller_manager.yml", + PlaceholderNames: []string{"POD_NAMESPACE"}, + MinimalKeepListRegex: "rest_client_request_duration_seconds|rest_client_requests_total|workqueue_depth", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "etcd": { + JobName: "etcd", + Enabled: true, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.ControlPlane, + ControllerType: ControllerType.ReplicaSet, + ScrapeConfigDefinitionFile: "controlplane_etcd.yml", + PlaceholderNames: []string{"POD_NAMESPACE"}, + MinimalKeepListRegex: "etcd_server_has_leader|rest_client_requests_total|etcd_mvcc_db_total_size_in_bytes|etcd_mvcc_db_total_size_in_use_in_bytes|etcd_server_slow_read_indexes_total|etcd_server_slow_apply_total|etcd_network_client_grpc_sent_bytes_total|etcd_server_heartbeat_send_failures_total", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, + "node-auto-provisioning": { + JobName: "node-auto-provisioning", + Enabled: false, + OSType: OSType.Linux, + KubernetesPlane: KubernetesPlane.ControlPlane, + ControllerType: ControllerType.ReplicaSet, + ScrapeConfigDefinitionFile: "controlplane_node_auto_provisioning.yml", + PlaceholderNames: []string{"POD_NAMESPACE"}, + MinimalKeepListRegex: "karpenter_(nodes_created_total|nodes_terminated_total|voluntary_disruption_eligible_nodes|nodeclaims_disrupted_total|voluntary_disruption_decisions_total|pods_state)", + CustomerKeepListRegex: "", + ScrapeInterval: "30s", + }, +} diff --git a/otelcollector/shared/go.mod b/otelcollector/shared/go.mod index 312fd248a..ba0551cb5 100644 --- a/otelcollector/shared/go.mod +++ b/otelcollector/shared/go.mod @@ -5,7 +5,9 @@ go 1.23.0 toolchain go1.23.2 require ( - github.com/prometheus/common v0.62.0 + github.com/prometheus/common v0.65.0 + golang.org/x/sys v0.33.0 + gopkg.in/yaml.v2 v2.4.0 k8s.io/apimachinery v0.32.0 ) @@ -18,15 +20,15 @@ require ( github.com/kr/pretty v0.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/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/client_model v0.6.2 // indirect github.com/x448/float16 v0.8.4 // indirect - golang.org/x/net v0.38.0 // indirect - golang.org/x/text v0.23.0 // indirect - google.golang.org/protobuf v1.36.5 // indirect + golang.org/x/net v0.40.0 // indirect + golang.org/x/text v0.25.0 // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/inf.v0 v0.9.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/otelcollector/shared/go.sum b/otelcollector/shared/go.sum index c08e590d2..aa3f135f0 100644 --- a/otelcollector/shared/go.sum +++ b/otelcollector/shared/go.sum @@ -10,8 +10,8 @@ github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ4 github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -32,10 +32,10 @@ github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsK github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= -github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE= +github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= @@ -58,18 +58,20 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= +golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -78,13 +80,15 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T 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= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg= @@ -95,8 +99,7 @@ k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6J k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= -sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc= -sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/otelcollector/shared/helpers.go b/otelcollector/shared/helpers.go index abcdf74dc..e2c5b160c 100644 --- a/otelcollector/shared/helpers.go +++ b/otelcollector/shared/helpers.go @@ -246,7 +246,8 @@ func ParseMetricsFiles(filePaths []string) (map[string]map[string]string, error) for _, filePath := range filePaths { file, err := os.Open(filePath) if err != nil { - return nil, fmt.Errorf("failed to open file %s: %w", filePath, err) + log.Printf("failed to open file %s: %v\n", filePath, err) + continue } defer func() { if cerr := file.Close(); cerr != nil {