diff --git a/assets/optional/kube-state-metrics/00-namespace.yaml b/assets/optional/kube-state-metrics/00-namespace.yaml new file mode 100644 index 0000000000..17f727565a --- /dev/null +++ b/assets/optional/kube-state-metrics/00-namespace.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: openshift-monitoring + labels: + name: openshift-monitoring + pod-security.kubernetes.io/enforce: privileged + pod-security.kubernetes.io/audit: privileged + pod-security.kubernetes.io/warn: privileged diff --git a/assets/optional/kube-state-metrics/01-cluster-role-binding.yaml b/assets/optional/kube-state-metrics/01-cluster-role-binding.yaml new file mode 100644 index 0000000000..c22bfc34ab --- /dev/null +++ b/assets/optional/kube-state-metrics/01-cluster-role-binding.yaml @@ -0,0 +1,18 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/managed-by: cluster-monitoring-operator + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: openshift-monitoring + app.kubernetes.io/version: 2.19.1 + name: kube-state-metrics +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: kube-state-metrics +subjects: +- kind: ServiceAccount + name: kube-state-metrics + namespace: openshift-monitoring diff --git a/assets/optional/kube-state-metrics/01-cluster-role.yaml b/assets/optional/kube-state-metrics/01-cluster-role.yaml new file mode 100644 index 0000000000..75cd4e5d26 --- /dev/null +++ b/assets/optional/kube-state-metrics/01-cluster-role.yaml @@ -0,0 +1,153 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/managed-by: cluster-monitoring-operator + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: openshift-monitoring + app.kubernetes.io/version: 2.19.1 + name: kube-state-metrics +rules: +- apiGroups: + - "" + resources: + - configmaps + - secrets + - nodes + - pods + - services + - serviceaccounts + - resourcequotas + - replicationcontrollers + - limitranges + - persistentvolumeclaims + - persistentvolumes + - namespaces + - endpoints + verbs: + - list + - watch +- apiGroups: + - apps + resources: + - statefulsets + - daemonsets + - deployments + - replicasets + verbs: + - list + - watch +- apiGroups: + - batch + resources: + - cronjobs + - jobs + verbs: + - list + - watch +- apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - list + - watch +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +- apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - list + - watch +- apiGroups: + - certificates.k8s.io + resources: + - certificatesigningrequests + verbs: + - list + - watch +- apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - list + - watch +- apiGroups: + - storage.k8s.io + resources: + - storageclasses + - volumeattachments + verbs: + - list + - watch +- apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + verbs: + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - networkpolicies + - ingressclasses + - ingresses + verbs: + - list + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - list + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + - rolebindings + - roles + verbs: + - list + - watch +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - get + - list + - watch +- apiGroups: + - autoscaling.k8s.io + resources: + - verticalpodautoscalers + verbs: + - list + - watch +- apiGroups: + - gateway.networking.k8s.io + resources: + - gatewayclasses + - gateways + verbs: + - list + - watch diff --git a/assets/optional/kube-state-metrics/01-service-account.yaml b/assets/optional/kube-state-metrics/01-service-account.yaml new file mode 100644 index 0000000000..0bfe63ad0e --- /dev/null +++ b/assets/optional/kube-state-metrics/01-service-account.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +automountServiceAccountToken: false +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/managed-by: cluster-monitoring-operator + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: openshift-monitoring + app.kubernetes.io/version: 2.19.1 + name: kube-state-metrics + namespace: openshift-monitoring diff --git a/assets/optional/kube-state-metrics/02-custom-resource-state-configmap.yaml b/assets/optional/kube-state-metrics/02-custom-resource-state-configmap.yaml new file mode 100644 index 0000000000..4d0f548939 --- /dev/null +++ b/assets/optional/kube-state-metrics/02-custom-resource-state-configmap.yaml @@ -0,0 +1,544 @@ +apiVersion: v1 +data: + custom-resource-state-configmap.yaml: |- + "kind": "CustomResourceStateMetrics" + "spec": + "resources": + - "groupVersionKind": + "group": "autoscaling.k8s.io" + "kind": "VerticalPodAutoscaler" + "version": "v1" + "metrics": + - "commonLabels": null + "each": + "stateSet": + "labelName": "updatemode" + "list": + - "Off" + - "Initial" + - "Recreate" + - "Auto" + "path": + - "spec" + - "updatePolicy" + - "updateMode" + "type": "StateSet" + "help": "Update mode of the VerticalPodAutoscaler." + "labelsFromPath": + "namespace": + - "metadata" + - "namespace" + "target_api_version": + - "spec" + - "targetRef" + - "apiVersion" + "target_kind": + - "spec" + - "targetRef" + - "kind" + "target_name": + - "spec" + - "targetRef" + - "name" + "verticalpodautoscaler": + - "metadata" + - "name" + "name": "verticalpodautoscaler_spec_updatepolicy_updatemode" + - "commonLabels": + "resource": "cpu" + "unit": "cores" + "each": + "gauge": + "labelsFromPath": + "container": + - "containerName" + "path": + - "status" + - "recommendation" + - "containerRecommendations" + "valueFrom": + - "lowerBound" + - "cpu" + "type": "Gauge" + "help": "Minimum cpu resources the container can use before the VerticalPodAutoscaler updater evicts it." + "labelsFromPath": + "namespace": + - "metadata" + - "namespace" + "target_api_version": + - "spec" + - "targetRef" + - "apiVersion" + "target_kind": + - "spec" + - "targetRef" + - "kind" + "target_name": + - "spec" + - "targetRef" + - "name" + "verticalpodautoscaler": + - "metadata" + - "name" + "name": "verticalpodautoscaler_status_recommendation_containerrecommendations_lowerbound_cpu" + - "commonLabels": + "resource": "memory" + "unit": "bytes" + "each": + "gauge": + "labelsFromPath": + "container": + - "containerName" + "path": + - "status" + - "recommendation" + - "containerRecommendations" + "valueFrom": + - "lowerBound" + - "memory" + "type": "Gauge" + "help": "Minimum memory resources the container can use before the VerticalPodAutoscaler updater evicts it." + "labelsFromPath": + "namespace": + - "metadata" + - "namespace" + "target_api_version": + - "spec" + - "targetRef" + - "apiVersion" + "target_kind": + - "spec" + - "targetRef" + - "kind" + "target_name": + - "spec" + - "targetRef" + - "name" + "verticalpodautoscaler": + - "metadata" + - "name" + "name": "verticalpodautoscaler_status_recommendation_containerrecommendations_lowerbound_memory" + - "commonLabels": + "resource": "cpu" + "unit": "cores" + "each": + "gauge": + "labelsFromPath": + "container": + - "containerName" + "path": + - "status" + - "recommendation" + - "containerRecommendations" + "valueFrom": + - "upperBound" + - "cpu" + "type": "Gauge" + "help": "Maximum cpu resources the container can use before the VerticalPodAutoscaler updater evicts it." + "labelsFromPath": + "namespace": + - "metadata" + - "namespace" + "target_api_version": + - "spec" + - "targetRef" + - "apiVersion" + "target_kind": + - "spec" + - "targetRef" + - "kind" + "target_name": + - "spec" + - "targetRef" + - "name" + "verticalpodautoscaler": + - "metadata" + - "name" + "name": "verticalpodautoscaler_status_recommendation_containerrecommendations_upperbound_cpu" + - "commonLabels": + "resource": "memory" + "unit": "bytes" + "each": + "gauge": + "labelsFromPath": + "container": + - "containerName" + "path": + - "status" + - "recommendation" + - "containerRecommendations" + "valueFrom": + - "upperBound" + - "memory" + "type": "Gauge" + "help": "Maximum memory resources the container can use before the VerticalPodAutoscaler updater evicts it." + "labelsFromPath": + "namespace": + - "metadata" + - "namespace" + "target_api_version": + - "spec" + - "targetRef" + - "apiVersion" + "target_kind": + - "spec" + - "targetRef" + - "kind" + "target_name": + - "spec" + - "targetRef" + - "name" + "verticalpodautoscaler": + - "metadata" + - "name" + "name": "verticalpodautoscaler_status_recommendation_containerrecommendations_upperbound_memory" + - "commonLabels": + "resource": "cpu" + "unit": "cores" + "each": + "gauge": + "labelsFromPath": + "container": + - "containerName" + "path": + - "status" + - "recommendation" + - "containerRecommendations" + "valueFrom": + - "target" + - "cpu" + "type": "Gauge" + "help": "Target cpu resources the VerticalPodAutoscaler recommends for the container." + "labelsFromPath": + "namespace": + - "metadata" + - "namespace" + "target_api_version": + - "spec" + - "targetRef" + - "apiVersion" + "target_kind": + - "spec" + - "targetRef" + - "kind" + "target_name": + - "spec" + - "targetRef" + - "name" + "verticalpodautoscaler": + - "metadata" + - "name" + "name": "verticalpodautoscaler_status_recommendation_containerrecommendations_target_cpu" + - "commonLabels": + "resource": "memory" + "unit": "bytes" + "each": + "gauge": + "labelsFromPath": + "container": + - "containerName" + "path": + - "status" + - "recommendation" + - "containerRecommendations" + "valueFrom": + - "target" + - "memory" + "type": "Gauge" + "help": "Target memory resources the VerticalPodAutoscaler recommends for the container." + "labelsFromPath": + "namespace": + - "metadata" + - "namespace" + "target_api_version": + - "spec" + - "targetRef" + - "apiVersion" + "target_kind": + - "spec" + - "targetRef" + - "kind" + "target_name": + - "spec" + - "targetRef" + - "name" + "verticalpodautoscaler": + - "metadata" + - "name" + "name": "verticalpodautoscaler_status_recommendation_containerrecommendations_target_memory" + - "commonLabels": + "resource": "cpu" + "unit": "cores" + "each": + "gauge": + "labelsFromPath": + "container": + - "containerName" + "path": + - "status" + - "recommendation" + - "containerRecommendations" + "valueFrom": + - "uncappedTarget" + - "cpu" + "type": "Gauge" + "help": "Target cpu resources the VerticalPodAutoscaler recommends for the container ignoring bounds." + "labelsFromPath": + "namespace": + - "metadata" + - "namespace" + "target_api_version": + - "spec" + - "targetRef" + - "apiVersion" + "target_kind": + - "spec" + - "targetRef" + - "kind" + "target_name": + - "spec" + - "targetRef" + - "name" + "verticalpodautoscaler": + - "metadata" + - "name" + "name": "verticalpodautoscaler_status_recommendation_containerrecommendations_uncappedtarget_cpu" + - "commonLabels": + "resource": "memory" + "unit": "bytes" + "each": + "gauge": + "labelsFromPath": + "container": + - "containerName" + "path": + - "status" + - "recommendation" + - "containerRecommendations" + "valueFrom": + - "uncappedTarget" + - "memory" + "type": "Gauge" + "help": "Target memory resources the VerticalPodAutoscaler recommends for the container ignoring bounds." + "labelsFromPath": + "namespace": + - "metadata" + - "namespace" + "target_api_version": + - "spec" + - "targetRef" + - "apiVersion" + "target_kind": + - "spec" + - "targetRef" + - "kind" + "target_name": + - "spec" + - "targetRef" + - "name" + "verticalpodautoscaler": + - "metadata" + - "name" + "name": "verticalpodautoscaler_status_recommendation_containerrecommendations_uncappedtarget_memory" + - "commonLabels": + "resource": "cpu" + "unit": "cores" + "each": + "gauge": + "labelsFromPath": + "container": + - "containerName" + "path": + - "spec" + - "resourcePolicy" + - "containerPolicies" + "valueFrom": + - "minAllowed" + - "cpu" + "type": "Gauge" + "help": "Minimum cpu resources the VerticalPodAutoscaler can set for containers matching the name." + "labelsFromPath": + "namespace": + - "metadata" + - "namespace" + "target_api_version": + - "spec" + - "targetRef" + - "apiVersion" + "target_kind": + - "spec" + - "targetRef" + - "kind" + "target_name": + - "spec" + - "targetRef" + - "name" + "verticalpodautoscaler": + - "metadata" + - "name" + "name": "verticalpodautoscaler_spec_resourcepolicy_container_policies_minallowed_cpu" + - "commonLabels": + "resource": "memory" + "unit": "bytes" + "each": + "gauge": + "labelsFromPath": + "container": + - "containerName" + "path": + - "spec" + - "resourcePolicy" + - "containerPolicies" + "valueFrom": + - "minAllowed" + - "memory" + "type": "Gauge" + "help": "Minimum memory resources the VerticalPodAutoscaler can set for containers matching the name." + "labelsFromPath": + "namespace": + - "metadata" + - "namespace" + "target_api_version": + - "spec" + - "targetRef" + - "apiVersion" + "target_kind": + - "spec" + - "targetRef" + - "kind" + "target_name": + - "spec" + - "targetRef" + - "name" + "verticalpodautoscaler": + - "metadata" + - "name" + "name": "verticalpodautoscaler_spec_resourcepolicy_container_policies_minallowed_memory" + - "commonLabels": + "resource": "cpu" + "unit": "cores" + "each": + "gauge": + "labelsFromPath": + "container": + - "containerName" + "path": + - "spec" + - "resourcePolicy" + - "containerPolicies" + "valueFrom": + - "maxAllowed" + - "cpu" + "type": "Gauge" + "help": "Minimum cpu resources the VerticalPodAutoscaler can set for containers matching the name." + "labelsFromPath": + "namespace": + - "metadata" + - "namespace" + "target_api_version": + - "spec" + - "targetRef" + - "apiVersion" + "target_kind": + - "spec" + - "targetRef" + - "kind" + "target_name": + - "spec" + - "targetRef" + - "name" + "verticalpodautoscaler": + - "metadata" + - "name" + "name": "verticalpodautoscaler_spec_resourcepolicy_container_policies_maxallowed_cpu" + - "commonLabels": + "resource": "memory" + "unit": "bytes" + "each": + "gauge": + "labelsFromPath": + "container": + - "containerName" + "path": + - "spec" + - "resourcePolicy" + - "containerPolicies" + "valueFrom": + - "maxAllowed" + - "memory" + "type": "Gauge" + "help": "Minimum memory resources the VerticalPodAutoscaler can set for containers matching the name." + "labelsFromPath": + "namespace": + - "metadata" + - "namespace" + "target_api_version": + - "spec" + - "targetRef" + - "apiVersion" + "target_kind": + - "spec" + - "targetRef" + - "kind" + "target_name": + - "spec" + - "targetRef" + - "name" + "verticalpodautoscaler": + - "metadata" + - "name" + "name": "verticalpodautoscaler_spec_resourcepolicy_container_policies_maxallowed_memory" + - "groupVersionKind": + "group": "gateway.networking.k8s.io" + "kind": "GatewayClass" + "version": "v1" + "metrics": + - "each": + "info": + "labelsFromPath": + "accepted": + - "status" + - "conditions" + - "[type=Accepted]" + - "status" + "controller": + - "spec" + - "controllerName" + "gateway_class": + - "metadata" + - "name" + "type": "Info" + "help": "Information about GatewayClasses" + "name": "gateway_class_info" + - "groupVersionKind": + "group": "gateway.networking.k8s.io" + "kind": "Gateway" + "version": "v1" + "metrics": + - "each": + "info": + "labelsFromPath": + "gateway": + - "metadata" + - "name" + "gateway_class": + - "spec" + - "gatewayClassName" + "namespace": + - "metadata" + - "namespace" + "programmed": + - "status" + - "conditions" + - "[type=Programmed]" + - "status" + "type": "Info" + "help": "Information about Gateways" + "name": "gateway_info" +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/managed-by: cluster-monitoring-operator + app.kubernetes.io/part-of: openshift-monitoring + name: kube-state-metrics-custom-resource-state-configmap + namespace: openshift-monitoring diff --git a/assets/optional/kube-state-metrics/02-kube-rbac-proxy-secret.yaml b/assets/optional/kube-state-metrics/02-kube-rbac-proxy-secret.yaml new file mode 100644 index 0000000000..38b8df0c9c --- /dev/null +++ b/assets/optional/kube-state-metrics/02-kube-rbac-proxy-secret.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +data: {} +kind: Secret +metadata: + labels: + app.kubernetes.io/managed-by: cluster-monitoring-operator + app.kubernetes.io/part-of: openshift-monitoring + name: kube-state-metrics-kube-rbac-proxy-config + namespace: openshift-monitoring +stringData: + config.yaml: |- + "authorization": + "static": + - "path": "/metrics" + "resourceRequest": false + "verb": "get" +type: Opaque diff --git a/assets/optional/kube-state-metrics/03-deployment.yaml b/assets/optional/kube-state-metrics/03-deployment.yaml new file mode 100644 index 0000000000..adc5538666 --- /dev/null +++ b/assets/optional/kube-state-metrics/03-deployment.yaml @@ -0,0 +1,172 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/managed-by: cluster-monitoring-operator + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: openshift-monitoring + app.kubernetes.io/version: 2.19.1 + name: kube-state-metrics + namespace: openshift-monitoring +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: openshift-monitoring + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: kube-state-metrics + openshift.io/required-scc: restricted-v2 + target.workload.openshift.io/management: '{"effect": "PreferredDuringScheduling"}' + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/managed-by: cluster-monitoring-operator + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: openshift-monitoring + app.kubernetes.io/version: 2.19.1 + spec: + automountServiceAccountToken: true + containers: + - args: + - --host=127.0.0.1 + - --port=8081 + - --telemetry-host=127.0.0.1 + - --telemetry-port=8082 + - --custom-resource-state-config-file=/etc/kube-state-metrics/custom-resource-state-configmap.yaml + - | + --metric-denylist= + ^kube_secret_labels$, + ^kube_.+_annotations$, + ^kube_customresource_.+_annotations_info$, + ^kube_customresource_.+_labels_info$ + - --metric-labels-allowlist=pods=[*],nodes=[*],namespaces=[*],persistentvolumes=[*],persistentvolumeclaims=[*],poddisruptionbudgets=[*] + - | + --metric-denylist= + ^kube_.+_created$, + ^kube_.+_metadata_resource_version$, + ^kube_replicaset_metadata_generation$, + ^kube_replicaset_status_observed_generation$, + ^kube_pod_restart_policy$, + ^kube_pod_init_container_status_terminated$, + ^kube_pod_init_container_status_running$, + ^kube_pod_container_status_terminated$, + ^kube_pod_container_status_running$, + ^kube_pod_completion_time$, + ^kube_pod_status_scheduled$ + image: "quay.io/openshift/kube-state-metrics" + name: kube-state-metrics + resources: + requests: + cpu: 2m + memory: 80Mi + limits: + cpu: 100m + memory: 200Mi + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /tmp + name: volume-directive-shadow + readOnly: false + - mountPath: /etc/kube-state-metrics + name: kube-state-metrics-custom-resource-state-configmap + readOnly: true + - args: + - --secure-listen-address=:8443 + - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 + - --upstream=http://127.0.0.1:8081/ + - --tls-cert-file=/etc/tls/private/tls.crt + - --tls-private-key-file=/etc/tls/private/tls.key + - --client-ca-file=/etc/tls/client-ca/ca.crt + - --config-file=/etc/kube-rbac-policy/config.yaml + image: "quay.io/openshift/kube-rbac-proxy" + name: kube-rbac-proxy-main + ports: + - containerPort: 8443 + name: https-main + resources: + requests: + cpu: 1m + memory: 15Mi + limits: + cpu: 20m + memory: 40Mi + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /etc/tls/private + name: kube-state-metrics-tls + readOnly: true + - mountPath: /etc/kube-rbac-policy + name: kube-state-metrics-kube-rbac-proxy-config + readOnly: true + - mountPath: /etc/tls/client-ca/ca.crt + name: admin-kubeconfig-signer-ca + readOnly: true + - args: + - --secure-listen-address=:9443 + - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 + - --upstream=http://127.0.0.1:8082/ + - --tls-cert-file=/etc/tls/private/tls.crt + - --tls-private-key-file=/etc/tls/private/tls.key + - --client-ca-file=/etc/tls/client-ca/ca.crt + - --config-file=/etc/kube-rbac-policy/config.yaml + image: "quay.io/openshift/kube-rbac-proxy" + name: kube-rbac-proxy-self + ports: + - containerPort: 9443 + name: https-self + resources: + requests: + cpu: 1m + memory: 15Mi + limits: + cpu: 20m + memory: 40Mi + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /etc/tls/private + name: kube-state-metrics-tls + readOnly: true + - mountPath: /etc/kube-rbac-policy + name: kube-state-metrics-kube-rbac-proxy-config + readOnly: true + - mountPath: /etc/tls/client-ca/ca.crt + name: admin-kubeconfig-signer-ca + readOnly: true + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-cluster-critical + securityContext: + runAsNonRoot: true + serviceAccountName: kube-state-metrics + volumes: + - emptyDir: {} + name: volume-directive-shadow + - name: kube-state-metrics-tls + secret: + secretName: kube-state-metrics-tls + - name: kube-state-metrics-kube-rbac-proxy-config + secret: + secretName: kube-state-metrics-kube-rbac-proxy-config + - configMap: + name: kube-state-metrics-custom-resource-state-configmap + name: kube-state-metrics-custom-resource-state-configmap + - hostPath: + path: /var/lib/microshift/certs/admin-kubeconfig-signer/ca.crt + type: File + name: admin-kubeconfig-signer-ca diff --git a/assets/optional/kube-state-metrics/04-service.yaml b/assets/optional/kube-state-metrics/04-service.yaml new file mode 100644 index 0000000000..75fddc4371 --- /dev/null +++ b/assets/optional/kube-state-metrics/04-service.yaml @@ -0,0 +1,30 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + openshift.io/description: |- + Expose kube-state-metrics `/metrics` endpoints within the cluster on the following ports: + * Port 8443 provides access to the Kubernetes resource metrics. This port is for internal use, and no other usage is guaranteed. + * Port 9443 provides access to the internal kube-state-metrics metrics. This port is for internal use, and no other usage is guaranteed. + service.beta.openshift.io/serving-cert-secret-name: kube-state-metrics-tls + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/managed-by: cluster-monitoring-operator + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: openshift-monitoring + app.kubernetes.io/version: 2.19.1 + name: kube-state-metrics + namespace: openshift-monitoring +spec: + clusterIP: None + ports: + - name: https-main + port: 8443 + targetPort: https-main + - name: https-self + port: 9443 + targetPort: https-self + selector: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: openshift-monitoring diff --git a/assets/optional/kube-state-metrics/kustomization.aarch64.yaml b/assets/optional/kube-state-metrics/kustomization.aarch64.yaml new file mode 100644 index 0000000000..b400ac1e80 --- /dev/null +++ b/assets/optional/kube-state-metrics/kustomization.aarch64.yaml @@ -0,0 +1,7 @@ +images: + - name: quay.io/openshift/kube-rbac-proxy + newName: quay.io/openshift-release-dev/ocp-v5.0-art-dev + digest: sha256:8a74d54a45421f51cfc1d50b7fca04e177c8601cec4cf5ecfdac250e36904819 + - name: quay.io/openshift/kube-state-metrics + newName: quay.io/openshift-release-dev/ocp-v5.0-art-dev + digest: sha256:c01bcfe85cec4ea6a2c93f71793d292fd0f2be9d7176fa9b8b5fb63d3a773373 diff --git a/assets/optional/kube-state-metrics/kustomization.x86_64.yaml b/assets/optional/kube-state-metrics/kustomization.x86_64.yaml new file mode 100644 index 0000000000..a080d292b4 --- /dev/null +++ b/assets/optional/kube-state-metrics/kustomization.x86_64.yaml @@ -0,0 +1,7 @@ +images: + - name: quay.io/openshift/kube-rbac-proxy + newName: quay.io/openshift-release-dev/ocp-v5.0-art-dev + digest: sha256:b23eabd4a8578c71398ccde56be77ded55c7cbea36e592f3800347c33ca47c55 + - name: quay.io/openshift/kube-state-metrics + newName: quay.io/openshift-release-dev/ocp-v5.0-art-dev + digest: sha256:4a633470960127f9545b5509dafd8d423108edb74ca7013c9cddde4ff5b0332d diff --git a/assets/optional/kube-state-metrics/kustomization.yaml b/assets/optional/kube-state-metrics/kustomization.yaml new file mode 100644 index 0000000000..17942badc5 --- /dev/null +++ b/assets/optional/kube-state-metrics/kustomization.yaml @@ -0,0 +1,11 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - 00-namespace.yaml + - 01-service-account.yaml + - 01-cluster-role.yaml + - 01-cluster-role-binding.yaml + - 02-kube-rbac-proxy-secret.yaml + - 02-custom-resource-state-configmap.yaml + - 03-deployment.yaml + - 04-service.yaml diff --git a/assets/optional/kube-state-metrics/release-kube-state-metrics-aarch64.json b/assets/optional/kube-state-metrics/release-kube-state-metrics-aarch64.json new file mode 100644 index 0000000000..da01a2f081 --- /dev/null +++ b/assets/optional/kube-state-metrics/release-kube-state-metrics-aarch64.json @@ -0,0 +1,8 @@ +{ + "release": { + "base": "5.0.0-0.nightly-arm64-2026-06-19-154904" + }, + "images": { + "kube_state_metrics": "quay.io/openshift-release-dev/ocp-v5.0-art-dev@sha256:c01bcfe85cec4ea6a2c93f71793d292fd0f2be9d7176fa9b8b5fb63d3a773373" + } +} diff --git a/assets/optional/kube-state-metrics/release-kube-state-metrics-x86_64.json b/assets/optional/kube-state-metrics/release-kube-state-metrics-x86_64.json new file mode 100644 index 0000000000..dfdae05ea2 --- /dev/null +++ b/assets/optional/kube-state-metrics/release-kube-state-metrics-x86_64.json @@ -0,0 +1,8 @@ +{ + "release": { + "base": "5.0.0-0.nightly-2026-06-19-155631" + }, + "images": { + "kube_state_metrics": "quay.io/openshift-release-dev/ocp-v5.0-art-dev@sha256:4a633470960127f9545b5509dafd8d423108edb74ca7013c9cddde4ff5b0332d" + } +} diff --git a/packaging/rpm/microshift.spec b/packaging/rpm/microshift.spec index 6362e4f552..b7fcd50dd9 100644 --- a/packaging/rpm/microshift.spec +++ b/packaging/rpm/microshift.spec @@ -261,6 +261,25 @@ The microshift-cert-manager-release-info package provides release information fi release. These files contain the list of container image references used by Cert Manager and can be used to embed those images into osbuilder blueprints or bootc containerfiles. +%package metrics-kube-state +Summary: Kubernetes kube-state-metrics for MicroShift +ExclusiveArch: x86_64 aarch64 +Requires: microshift = %{version} + +%description metrics-kube-state +The microshift-metrics-kube-state package provides kube-state-metrics for MicroShift. +Install this package to expose Kubernetes object state metrics via a secure endpoint. + +%package metrics-kube-state-release-info +Summary: Release information for kube-state-metrics for MicroShift +BuildArch: noarch +Requires: microshift-release-info = %{version} + +%description metrics-kube-state-release-info +The microshift-metrics-kube-state-release-info package provides release information files for this +release. These files contain the list of container image references used by kube-state-metrics +and can be used to embed those images into osbuilder blueprints or bootc containerfiles. + %package sriov Summary: SR-IOV Network Operator for MicroShift ExclusiveArch: x86_64 aarch64 @@ -599,6 +618,29 @@ cat assets/optional/cert-manager/manager/images-x86_64.yaml >> %{buildroot}/%{_p mkdir -p -m755 %{buildroot}%{_datadir}/microshift/release install -p -m644 assets/optional/cert-manager/release-cert-manager-{x86_64,aarch64}.json %{buildroot}%{_datadir}/microshift/release/ +# kube-state-metrics +install -d -m755 %{buildroot}/%{_prefix}/lib/microshift/manifests.d/081-microshift-kube-state-metrics +install -p -m644 assets/optional/kube-state-metrics/00-namespace.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/081-microshift-kube-state-metrics +install -p -m644 assets/optional/kube-state-metrics/01-service-account.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/081-microshift-kube-state-metrics +install -p -m644 assets/optional/kube-state-metrics/01-cluster-role.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/081-microshift-kube-state-metrics +install -p -m644 assets/optional/kube-state-metrics/01-cluster-role-binding.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/081-microshift-kube-state-metrics +install -p -m644 assets/optional/kube-state-metrics/02-kube-rbac-proxy-secret.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/081-microshift-kube-state-metrics +install -p -m644 assets/optional/kube-state-metrics/02-custom-resource-state-configmap.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/081-microshift-kube-state-metrics +install -p -m644 assets/optional/kube-state-metrics/03-deployment.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/081-microshift-kube-state-metrics +install -p -m644 assets/optional/kube-state-metrics/04-service.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/081-microshift-kube-state-metrics +install -p -m644 assets/optional/kube-state-metrics/kustomization.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/081-microshift-kube-state-metrics + +%ifarch %{arm} aarch64 +cat assets/optional/kube-state-metrics/kustomization.aarch64.yaml >> %{buildroot}/%{_prefix}/lib/microshift/manifests.d/081-microshift-kube-state-metrics/kustomization.yaml +%endif +%ifarch x86_64 +cat assets/optional/kube-state-metrics/kustomization.x86_64.yaml >> %{buildroot}/%{_prefix}/lib/microshift/manifests.d/081-microshift-kube-state-metrics/kustomization.yaml +%endif + +# kube-state-metrics-release-info +mkdir -p -m755 %{buildroot}%{_datadir}/microshift/release +install -p -m644 assets/optional/kube-state-metrics/release-kube-state-metrics-{x86_64,aarch64}.json %{buildroot}%{_datadir}/microshift/release/ + # sriov install -d -m755 %{buildroot}/%{_prefix}/lib/microshift/manifests.d/070-microshift-sriov install -d -m755 %{buildroot}/%{_prefix}/lib/microshift/manifests.d/070-microshift-sriov/crd @@ -802,6 +844,13 @@ fi %files cert-manager-release-info %{_datadir}/microshift/release/release-cert-manager-{x86_64,aarch64}.json +%files metrics-kube-state +%dir %{_prefix}/lib/microshift/manifests.d/081-microshift-kube-state-metrics +%{_prefix}/lib/microshift/manifests.d/081-microshift-kube-state-metrics/* + +%files metrics-kube-state-release-info +%{_datadir}/microshift/release/release-kube-state-metrics-{x86_64,aarch64}.json + %files sriov %dir %{_prefix}/lib/microshift/manifests.d/070-microshift-sriov %dir %{_prefix}/lib/microshift/manifests.d/070-microshift-sriov/crd diff --git a/pkg/healthcheck/microshift_optional_workloads.go b/pkg/healthcheck/microshift_optional_workloads.go index 80e2d9a3b0..e2501d9a19 100644 --- a/pkg/healthcheck/microshift_optional_workloads.go +++ b/pkg/healthcheck/microshift_optional_workloads.go @@ -1,6 +1,8 @@ package healthcheck import ( + "slices" + "github.com/openshift/microshift/pkg/config" "github.com/openshift/microshift/pkg/util" "k8s.io/klog/v2" @@ -38,6 +40,20 @@ var optionalWorkloadPaths = map[string]optionalWorkloads{ Namespace: "sriov-network-operator", Workloads: NamespaceWorkloads{Deployments: []string{"sriov-network-operator"}}, }, + + "/usr/lib/microshift/manifests.d/081-microshift-kube-state-metrics": { + Namespace: "openshift-monitoring", + Workloads: NamespaceWorkloads{Deployments: []string{"kube-state-metrics"}}, + }, +} + +// mergeWorkloads combines two NamespaceWorkloads into one. +func mergeWorkloads(existing, incoming NamespaceWorkloads) NamespaceWorkloads { + return NamespaceWorkloads{ + Deployments: slices.Concat(existing.Deployments, incoming.Deployments), + DaemonSets: slices.Concat(existing.DaemonSets, incoming.DaemonSets), + StatefulSets: slices.Concat(existing.StatefulSets, incoming.StatefulSets), + } } // fillOptionalMicroShiftWorkloads assembles list of optional MicroShift workloads @@ -73,7 +89,7 @@ func fillOptionalMicroShiftWorkloads(workloadsToCheck map[string]NamespaceWorklo } klog.Infof("Optional component path exists and is configured: %s - expecting %v in namespace %q", path, ow.Workloads.String(), ow.Namespace) - workloadsToCheck[ow.Namespace] = ow.Workloads + workloadsToCheck[ow.Namespace] = mergeWorkloads(workloadsToCheck[ow.Namespace], ow.Workloads) } return nil } diff --git a/scripts/auto-rebase/assets_cluster_monitoring_operator.yaml b/scripts/auto-rebase/assets_cluster_monitoring_operator.yaml new file mode 100644 index 0000000000..62babfc169 --- /dev/null +++ b/scripts/auto-rebase/assets_cluster_monitoring_operator.yaml @@ -0,0 +1,33 @@ +assets: + - dir: optional/kube-state-metrics/ + no_clean: True + src: cluster-monitoring-operator/assets/kube-state-metrics/ + files: + - file: 00-namespace.yaml + ignore: "MicroShift-specific, no upstream equivalent" + git_restore: True + - file: 01-cluster-role.yaml + src: cluster-role.yaml + - file: 01-cluster-role-binding.yaml + src: cluster-role-binding.yaml + - file: 01-service-account.yaml + src: service-account.yaml + - file: 02-custom-resource-state-configmap.yaml + src: custom-resource-state-configmap.yaml + - file: 02-kube-rbac-proxy-secret.yaml + src: kube-rbac-proxy-secret.yaml + - file: 03-deployment.yaml + src: deployment.yaml + - file: 04-service.yaml + src: service.yaml + - file: kustomization.yaml + ignore: "MicroShift-specific kustomization" + git_restore: True + - file: kustomization.x86_64.yaml + ignore: "gets generated during image rebase" + - file: kustomization.aarch64.yaml + ignore: "gets generated during image rebase" + - file: release-kube-state-metrics-x86_64.json + ignore: "gets generated during image rebase" + - file: release-kube-state-metrics-aarch64.json + ignore: "gets generated during image rebase" diff --git a/scripts/auto-rebase/last_rebase_cluster_monitoring_operator.sh b/scripts/auto-rebase/last_rebase_cluster_monitoring_operator.sh new file mode 100755 index 0000000000..f61200df82 --- /dev/null +++ b/scripts/auto-rebase/last_rebase_cluster_monitoring_operator.sh @@ -0,0 +1,2 @@ +#!/bin/bash -x +./scripts/auto-rebase/rebase_cluster_monitoring_operator.sh to "registry.ci.openshift.org/ocp/release-5:5.0.0-0.nightly-2026-06-19-155631" "registry.ci.openshift.org/ocp-arm64/release-5-arm64:5.0.0-0.nightly-arm64-2026-06-19-154904" diff --git a/scripts/auto-rebase/presubmit.py b/scripts/auto-rebase/presubmit.py index 5e90ed4639..ea3f6199b4 100755 --- a/scripts/auto-rebase/presubmit.py +++ b/scripts/auto-rebase/presubmit.py @@ -29,6 +29,7 @@ "./scripts/auto-rebase/assets_ai_model_serving.yaml", "./scripts/auto-rebase/assets_cert_manager.yaml", "./scripts/auto-rebase/assets_sriov.yaml", + "./scripts/auto-rebase/assets_cluster_monitoring_operator.yaml", ] diff --git a/scripts/auto-rebase/rebase_cluster_monitoring_operator.sh b/scripts/auto-rebase/rebase_cluster_monitoring_operator.sh new file mode 100755 index 0000000000..be1124f04e --- /dev/null +++ b/scripts/auto-rebase/rebase_cluster_monitoring_operator.sh @@ -0,0 +1,375 @@ +#!/usr/bin/env bash +# shellcheck disable=all +# Copyright 2022 The MicroShift authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail + +shopt -s expand_aliases +shopt -s extglob + +#debugging options +#trap 'echo "#L$LINENO: $BASH_COMMAND" >&2' DEBUG +#set -xo functrace +#PS4='+ $LINENO ' +REPOROOT="$(readlink -f "$(dirname "${BASH_SOURCE[0]}")/../..")" +STAGING_DIR="$REPOROOT/_output/staging" +PULL_SECRET_FILE="${HOME}/.pull-secret.json" +REBASE_USE_SSH="${REBASE_USE_SSH:-false}" + +declare -a ARCHS=("amd64" "arm64") +declare -A GOARCH_TO_UNAME_MAP=( ["amd64"]="x86_64" ["arm64"]="aarch64" ) + +# Maps kustomization image name -> OCP release tag name +declare -A IMAGE_MAP=( + ["quay.io/openshift/kube-metrics-server"]="kube-metrics-server" + ["quay.io/openshift/kube-state-metrics"]="kube-state-metrics" + ["quay.io/openshift/node-exporter"]="prometheus-node-exporter" + ["quay.io/openshift/kube-rbac-proxy"]="kube-rbac-proxy" +) + +# Maps component dir -> release JSON key +declare -A COMPONENT_JSON_KEY=( + ["metrics-server"]="metrics_server" + ["kube-state-metrics"]="kube_state_metrics" + ["node-exporter"]="node_exporter" +) + +# Maps release JSON key -> OCP release tag name +declare -A EXPORTER_TAG_MAP=( + ["metrics_server"]="kube-metrics-server" + ["kube_state_metrics"]="kube-state-metrics" + ["node_exporter"]="prometheus-node-exporter" +) + +title() { + echo -e "\E[34m$1\E[00m"; +} + +retry_cmd() { + local -r max_attempts=5 + local timeout=1 + local attempt=1 + local exit_code=0 + + while (( attempt <= max_attempts )); do + if "$@"; then + return 0 + else + exit_code=$? + fi + echo "Attempt ${attempt} of ${max_attempts} failed (exit code ${exit_code}). Retrying in ${timeout}s..." + sleep "${timeout}" + attempt=$(( attempt + 1 )) + timeout=$(( timeout * 2 )) + done + + echo "Command failed after ${max_attempts} attempts: $@" + return "${exit_code}" +} + +check_preconditions() { + if ! hash yq; then + title "Installing yq" + sudo DEST_DIR=/usr/bin/ "${REPOROOT}/scripts/fetch_tools.sh" yq + fi + + if ! hash python3; then + echo "ERROR: python3 is not present on the system - please install" + exit 1 + fi + + if ! python3 -c "import yaml"; then + echo "ERROR: missing python's yaml library - please install" + exit 1 + fi +} + +clone_repo() { + local repo="$1" + local commit="$2" + local destdir="$3" + + local repodir="${destdir}/${repo##*/}" + + if [[ -d "${repodir}" ]]; then + return + fi + + if "${REBASE_USE_SSH}"; then + repo="git@github.com:${repo#https://github.com/}" + fi + + git init "${repodir}" + pushd "${repodir}" >/dev/null + git remote add origin "${repo}" + retry_cmd git fetch origin --quiet --filter=tree:0 --tags "${commit}" + git checkout "${commit}" + popd >/dev/null +} + +download_cluster_monitoring_operator() { + local release_image_amd64="$1" + local release_image_arm64="$2" + + rm -rf "${STAGING_DIR}" + mkdir -p "${STAGING_DIR}" + pushd "${STAGING_DIR}" >/dev/null + + local authentication="" + if [[ -f "${PULL_SECRET_FILE}" ]]; then + authentication="-a ${PULL_SECRET_FILE}" + else + >&2 echo "Warning: no pull secret found at ${PULL_SECRET_FILE}" + fi + + title "# Fetching release info for ${release_image_amd64} (amd64)" + oc adm release info ${authentication} "${release_image_amd64}" -o json > release_amd64.json + title "# Fetching release info for ${release_image_arm64} (arm64)" + oc adm release info ${authentication} "${release_image_arm64}" -o json > release_arm64.json + + title "# Extracting cluster-monitoring-operator source commit" + cat release_amd64.json \ + | jq -r '.references.spec.tags[] | "\(.name) \(.annotations."io.openshift.build.source-location") \(.annotations."io.openshift.build.commit.id")"' > source-commits + + local cmo_line + cmo_line=$(grep '^cluster-monitoring-operator ' source-commits) || { + >&2 echo "ERROR: cluster-monitoring-operator not found in release payload" + return 1 + } + + local repo commit + repo=$(echo "${cmo_line}" | cut -d ' ' -f 2) + commit=$(echo "${cmo_line}" | cut -d ' ' -f 3) + + title "# Cloning cluster-monitoring-operator at ${commit}" + clone_repo "${repo}" "${commit}" "." + + popd >/dev/null +} + +update_metrics_server_manifests() { + [[ -d "${REPOROOT}/assets/optional/metrics-server" ]] || return 0 + + title "Rebasing metrics-server manifests" + + local ms_crb="${REPOROOT}/assets/optional/metrics-server/01-cluster-role-binding.yaml" + yq -i '.subjects += [{"kind": "User", "name": "system:metrics-server"}]' "$ms_crb" + + local ms_deploy="${REPOROOT}/assets/optional/metrics-server/03-deployment.yaml" + yq -i '.spec.replicas = 1' "$ms_deploy" + yq -i '.spec.strategy = {"type": "Recreate"}' "$ms_deploy" + yq -i 'del(.spec.template.spec.affinity)' "$ms_deploy" + yq -i '.spec.template.spec.containers[0].image = "quay.io/openshift/kube-metrics-server"' "$ms_deploy" + yq -i '.spec.template.spec.containers[0].securityContext.capabilities.drop = ["ALL"]' "$ms_deploy" +} + +update_kube_state_metrics_manifests() { + [[ -d "${REPOROOT}/assets/optional/kube-state-metrics" ]] || return 0 + + title "Rebasing kube-state-metrics manifests" + + local ksm_deploy="${REPOROOT}/assets/optional/kube-state-metrics/03-deployment.yaml" + + yq -i '.spec.template.spec.containers[0].image = "quay.io/openshift/kube-state-metrics"' "$ksm_deploy" + yq -i '.spec.template.spec.containers[1].image = "quay.io/openshift/kube-rbac-proxy"' "$ksm_deploy" + yq -i '.spec.template.spec.containers[2].image = "quay.io/openshift/kube-rbac-proxy"' "$ksm_deploy" + + yq -i '.spec.template.spec.containers[0].securityContext = {"allowPrivilegeEscalation": false, "readOnlyRootFilesystem": true, "runAsNonRoot": true}' "$ksm_deploy" + yq -i '.spec.template.spec.containers[1].securityContext = {"allowPrivilegeEscalation": false, "readOnlyRootFilesystem": true, "runAsNonRoot": true}' "$ksm_deploy" + yq -i '.spec.template.spec.containers[2].securityContext = {"allowPrivilegeEscalation": false, "readOnlyRootFilesystem": true, "runAsNonRoot": true}' "$ksm_deploy" + yq -i '.spec.template.spec.securityContext = {"runAsNonRoot": true}' "$ksm_deploy" + + yq -i '.spec.template.spec.containers[0].resources.limits = {"cpu": "100m", "memory": "200Mi"}' "$ksm_deploy" + yq -i '.spec.template.spec.containers[1].resources.limits = {"cpu": "20m", "memory": "40Mi"}' "$ksm_deploy" + yq -i '.spec.template.spec.containers[2].resources.limits = {"cpu": "20m", "memory": "40Mi"}' "$ksm_deploy" + + yq -i '(.spec.template.spec.containers[1].volumeMounts[] | select(.name == "kube-state-metrics-tls")).readOnly = true' "$ksm_deploy" + yq -i '(.spec.template.spec.containers[2].volumeMounts[] | select(.name == "kube-state-metrics-tls")).readOnly = true' "$ksm_deploy" + + yq -i '(.spec.template.spec.containers[1].args[] | select(test("--client-ca-file="))) |= "--client-ca-file=/etc/tls/client-ca/ca.crt"' "$ksm_deploy" + yq -i '(.spec.template.spec.containers[2].args[] | select(test("--client-ca-file="))) |= "--client-ca-file=/etc/tls/client-ca/ca.crt"' "$ksm_deploy" + yq -i 'del(.spec.template.spec.volumes[] | select(.name == "metrics-client-ca"))' "$ksm_deploy" + yq -i '.spec.template.spec.volumes += [{"hostPath": {"path": "/var/lib/microshift/certs/admin-kubeconfig-signer/ca.crt", "type": "File"}, "name": "admin-kubeconfig-signer-ca"}]' "$ksm_deploy" + yq -i 'del(.spec.template.spec.containers[1].volumeMounts[] | select(.name == "metrics-client-ca"))' "$ksm_deploy" + yq -i 'del(.spec.template.spec.containers[2].volumeMounts[] | select(.name == "metrics-client-ca"))' "$ksm_deploy" + yq -i '.spec.template.spec.containers[1].volumeMounts += [{"mountPath": "/etc/tls/client-ca/ca.crt", "name": "admin-kubeconfig-signer-ca", "readOnly": true}]' "$ksm_deploy" + yq -i '.spec.template.spec.containers[2].volumeMounts += [{"mountPath": "/etc/tls/client-ca/ca.crt", "name": "admin-kubeconfig-signer-ca", "readOnly": true}]' "$ksm_deploy" + + local ksm_secret="${REPOROOT}/assets/optional/kube-state-metrics/02-kube-rbac-proxy-secret.yaml" + sed -i '/"user":/,/"name":/d' "$ksm_secret" +} + +update_node_exporter_manifests() { + [[ -d "${REPOROOT}/assets/optional/node-exporter" ]] || return 0 + + title "Rebasing node-exporter manifests" + + local ne_ds="${REPOROOT}/assets/optional/node-exporter/03-daemonset.yaml" + + yq -i '.spec.template.spec.containers[0].image = "quay.io/openshift/node-exporter"' "$ne_ds" + yq -i '.spec.template.spec.containers[1].image = "quay.io/openshift/kube-rbac-proxy"' "$ne_ds" + yq -i '.spec.template.spec.initContainers[0].image = "quay.io/openshift/node-exporter"' "$ne_ds" + + yq -i '(.spec.template.spec.containers[1].args[] | select(test("--secure-listen-address="))) |= "--secure-listen-address=0.0.0.0:9100"' "$ne_ds" + + yq -i '(.spec.template.spec.containers[1].args[] | select(test("--client-ca-file="))) |= "--client-ca-file=/etc/tls/client-ca/ca.crt"' "$ne_ds" + yq -i 'del(.spec.template.spec.volumes[] | select(.name == "metrics-client-ca"))' "$ne_ds" + yq -i '.spec.template.spec.volumes += [{"hostPath": {"path": "/var/lib/microshift/certs/admin-kubeconfig-signer/ca.crt", "type": "File"}, "name": "admin-kubeconfig-signer-ca"}]' "$ne_ds" + yq -i 'del(.spec.template.spec.containers[1].volumeMounts[] | select(.name == "metrics-client-ca"))' "$ne_ds" + yq -i '.spec.template.spec.containers[1].volumeMounts += [{"mountPath": "/etc/tls/client-ca/ca.crt", "name": "admin-kubeconfig-signer-ca", "readOnly": true}]' "$ne_ds" + + yq -i '(.spec.template.spec.containers[1].volumeMounts[] | select(.name == "node-exporter-tls")).readOnly = true' "$ne_ds" + + local ne_secret="${REPOROOT}/assets/optional/node-exporter/02-kube-rbac-proxy-secret.yaml" + sed -i '/"user":/,/"name":/d' "$ne_secret" +} + +update_cluster_monitoring_operator_images() { + title "Rebasing metrics component images" + + for goarch in amd64 arm64; do + local arch=${GOARCH_TO_UNAME_MAP["${goarch}"]:-noarch} + local release_file="${STAGING_DIR}/release_${goarch}.json" + + local base_release + base_release=$(jq -r ".metadata.version" "${release_file}") + + for component_dir in metrics-server kube-state-metrics node-exporter; do + [[ -d "${REPOROOT}/assets/optional/${component_dir}" ]] || continue + + local json_key="${COMPONENT_JSON_KEY[$component_dir]}" + local release_tag="${EXPORTER_TAG_MAP[$json_key]}" + local new_image + new_image=$(jq -r ".references.spec.tags[] | select(.name == \"${release_tag}\") | .from.name" "${release_file}") + if [[ -z "${new_image}" || "${new_image}" == "null" ]]; then + >&2 echo "ERROR: Release tag '${release_tag}' not found in payload for ${component_dir}" + return 1 + fi + local component_release_json="${REPOROOT}/assets/optional/${component_dir}/release-${component_dir}-${arch}.json" + jq -n --arg base "$base_release" --arg img "${new_image}" \ + "{\"release\": {\"base\": \$base}, \"images\": {\"${json_key}\": \$img}}" > "${component_release_json}" + + local kustomization_arch_file="${REPOROOT}/assets/optional/${component_dir}/kustomization.${arch}.yaml" + + cat < "${kustomization_arch_file}" +images: +EOF + + local image_names + image_names=$(grep -h 'image:' "${REPOROOT}/assets/optional/${component_dir}/"*.yaml 2>/dev/null \ + | sed 's/.*image: *//; s/"//g; s/:.*//; s/@.*//' | sort -u | grep -v '^$') + + for orig_image in ${image_names}; do + local release_tag="${IMAGE_MAP[$orig_image]:-}" + if [[ -z "${release_tag}" ]]; then + >&2 echo "ERROR: Unknown metrics image '${orig_image}' in ${component_dir}" + return 1 + fi + + local new_image + new_image=$(jq -r ".references.spec.tags[] | select(.name == \"${release_tag}\") | .from.name" "${release_file}") + if [[ -z "${new_image}" || "${new_image}" == "null" ]]; then + >&2 echo "ERROR: Image for release tag '${release_tag}' not found in payload for ${component_dir}" + return 1 + fi + local new_image_name="${new_image%@*}" + local new_image_digest="${new_image#*@}" + + cat <> "${kustomization_arch_file}" + - name: ${orig_image} + newName: ${new_image_name} + digest: ${new_image_digest} +EOF + done + done + done +} + +copy_manifests() { + title "Copying manifests" + "$REPOROOT/scripts/auto-rebase/handle_assets.py" "./scripts/auto-rebase/assets_cluster_monitoring_operator.yaml" +} + +update_last_rebase() { + local release_image_amd64="$1" + local release_image_arm64="$2" + + title "## Updating last_rebase_cluster_monitoring_operator.sh" + + local last_rebase_script="${REPOROOT}/scripts/auto-rebase/last_rebase_cluster_monitoring_operator.sh" + + rm -f "${last_rebase_script}" + cat - >"${last_rebase_script}" <