diff --git a/charts/github-platform-operator/README.md b/charts/github-platform-operator/README.md index 677e668..344561c 100644 --- a/charts/github-platform-operator/README.md +++ b/charts/github-platform-operator/README.md @@ -155,6 +155,10 @@ metrics: enabled: true secure: true port: 8443 + serviceMonitor: + enabled: false + interval: 30s + scrapeTimeout: 10s networkPolicy: enabled: false @@ -176,6 +180,46 @@ repository at `dashboards/grafana/github-platform-operator.json`. See the [operations guide](https://github.com/pierinho13/github-platform-operator/blob/main/docs/operations.md#metrics-and-grafana) for scraping and dashboard details. +### Prometheus Operator ServiceMonitor + +When the Prometheus Operator CRDs are installed, the chart can create a +`ServiceMonitor` for the metrics Service: + +```yaml +metrics: + enabled: true + secure: true + port: 8443 + serviceMonitor: + enabled: true + namespace: monitoring + additionalLabels: + release: kube-prometheus-stack + interval: 30s + scrapeTimeout: 10s + prometheusServiceAccount: + name: kube-prometheus-stack-prometheus + namespace: monitoring +``` + +`serviceMonitor.namespace` defaults to the Helm release namespace. Use +`additionalLabels` when the Prometheus installation selects ServiceMonitors by +label. + +For secure metrics, the ServiceMonitor uses the Prometheus Pod's projected +ServiceAccount token by default. When `prometheusServiceAccount.name` and +`prometheusServiceAccount.namespace` are both set and `rbac.create=true`, the +chart creates a ClusterRoleBinding granting that ServiceAccount `GET /metrics`. +Leave both fields empty when equivalent metrics-reader RBAC is managed +externally. + +The default secure scrape skips certificate verification because +controller-runtime serves the metrics endpoint with its runtime TLS +certificate unless a trusted certificate is configured separately. + +If `networkPolicy.enabled=true`, make sure the Prometheus namespace matches the +configured metrics ingress policy. + ## CRDs and upgrades The chart includes generated CRDs under `crds/`. Helm installs them before the diff --git a/charts/github-platform-operator/templates/metrics-rbac.yaml b/charts/github-platform-operator/templates/metrics-rbac.yaml index 68078dc..783d6a1 100644 --- a/charts/github-platform-operator/templates/metrics-rbac.yaml +++ b/charts/github-platform-operator/templates/metrics-rbac.yaml @@ -48,3 +48,21 @@ rules: verbs: - get {{- end }} + +{{- if and .Values.rbac.create .Values.metrics.enabled .Values.metrics.secure .Values.metrics.serviceMonitor.enabled .Values.metrics.serviceMonitor.prometheusServiceAccount.name .Values.metrics.serviceMonitor.prometheusServiceAccount.namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "github-platform-operator.fullname" . }}-prometheus-metrics + labels: + {{- include "github-platform-operator.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "github-platform-operator.metricsReaderRoleName" . }} +subjects: + - kind: ServiceAccount + name: {{ .Values.metrics.serviceMonitor.prometheusServiceAccount.name }} + namespace: {{ .Values.metrics.serviceMonitor.prometheusServiceAccount.namespace }} +{{- end }} diff --git a/charts/github-platform-operator/templates/servicemonitor.yaml b/charts/github-platform-operator/templates/servicemonitor.yaml new file mode 100644 index 0000000..eeb7101 --- /dev/null +++ b/charts/github-platform-operator/templates/servicemonitor.yaml @@ -0,0 +1,36 @@ +{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "github-platform-operator.fullname" . }} + namespace: {{ default .Release.Namespace .Values.metrics.serviceMonitor.namespace }} + labels: + {{- include "github-platform-operator.labels" . | nindent 4 }} + {{- with .Values.metrics.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.metrics.serviceMonitor.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + {{- include "github-platform-operator.selectorLabels" . | nindent 6 }} + endpoints: + - port: {{ ternary "https" "http" .Values.metrics.secure }} + path: /metrics + scheme: {{ ternary "https" "http" .Values.metrics.secure }} + interval: {{ .Values.metrics.serviceMonitor.interval }} + scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }} + {{- if .Values.metrics.secure }} + {{- with .Values.metrics.serviceMonitor.bearerTokenFile }} + bearerTokenFile: {{ . | quote }} + {{- end }} + tlsConfig: + insecureSkipVerify: {{ .Values.metrics.serviceMonitor.tlsConfig.insecureSkipVerify }} + {{- end }} +{{- end }} diff --git a/charts/github-platform-operator/values.schema.json b/charts/github-platform-operator/values.schema.json index e03315d..cd4db5c 100644 --- a/charts/github-platform-operator/values.schema.json +++ b/charts/github-platform-operator/values.schema.json @@ -128,7 +128,7 @@ "description": "Controller metrics endpoint configuration.", "type": "object", "additionalProperties": false, - "required": ["enabled", "secure", "port", "service"], + "required": ["enabled", "secure", "port", "service", "serviceMonitor"], "properties": { "enabled": { "description": "Expose the controller metrics endpoint.", @@ -160,8 +160,128 @@ "description": "Annotations added to the metrics Service." } } + }, + "serviceMonitor": { + "description": "Prometheus Operator ServiceMonitor configuration.", + "type": "object", + "additionalProperties": false, + "required": [ + "enabled", + "namespace", + "additionalLabels", + "annotations", + "interval", + "scrapeTimeout", + "bearerTokenFile", + "tlsConfig", + "prometheusServiceAccount" + ], + "properties": { + "enabled": { + "description": "Create a ServiceMonitor for Prometheus Operator.", + "type": "boolean" + }, + "namespace": { + "description": "Namespace where the ServiceMonitor is created. Empty uses the Helm release namespace.", + "type": "string" + }, + "additionalLabels": { + "$ref": "#/definitions/stringMap", + "description": "Additional labels used by Prometheus to select the ServiceMonitor." + }, + "annotations": { + "$ref": "#/definitions/stringMap", + "description": "Annotations added to the ServiceMonitor." + }, + "interval": { + "description": "Prometheus scrape interval.", + "type": "string", + "minLength": 1 + }, + "scrapeTimeout": { + "description": "Prometheus scrape timeout. It must not exceed the scrape interval.", + "type": "string", + "minLength": 1 + }, + "bearerTokenFile": { + "description": "Bearer token file used by Prometheus when metrics are secure. Empty disables file-based bearer authentication.", + "type": "string" + }, + "tlsConfig": { + "description": "TLS configuration used by the ServiceMonitor for secure metrics.", + "type": "object", + "additionalProperties": false, + "required": ["insecureSkipVerify"], + "properties": { + "insecureSkipVerify": { + "description": "Disable verification of the metrics endpoint TLS certificate.", + "type": "boolean" + } + } + }, + "prometheusServiceAccount": { + "description": "Prometheus ServiceAccount to bind to the metrics-reader ClusterRole. Leave both fields empty when RBAC is managed externally.", + "type": "object", + "additionalProperties": false, + "required": ["name", "namespace"], + "properties": { + "name": { + "description": "Prometheus ServiceAccount name.", + "type": "string" + }, + "namespace": { + "description": "Prometheus ServiceAccount namespace.", + "type": "string" + } + }, + "allOf": [ + { + "if": { + "properties": { + "name": {"minLength": 1} + } + }, + "then": { + "properties": { + "namespace": {"minLength": 1} + } + } + }, + { + "if": { + "properties": { + "namespace": {"minLength": 1} + } + }, + "then": { + "properties": { + "name": {"minLength": 1} + } + } + } + ] + } + } } - } + }, + "allOf": [ + { + "if": { + "properties": { + "serviceMonitor": { + "properties": { + "enabled": {"const": true} + } + } + } + }, + "then": { + "properties": { + "enabled": {"const": true} + } + } + } + ] }, "networkPolicy": { "description": "NetworkPolicy configuration for the metrics endpoint.", diff --git a/charts/github-platform-operator/values.yaml b/charts/github-platform-operator/values.yaml index 7768a08..241fc64 100644 --- a/charts/github-platform-operator/values.yaml +++ b/charts/github-platform-operator/values.yaml @@ -28,6 +28,19 @@ metrics: service: type: ClusterIP annotations: {} + serviceMonitor: + enabled: false + namespace: "" + additionalLabels: {} + annotations: {} + interval: 30s + scrapeTimeout: 10s + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + tlsConfig: + insecureSkipVerify: true + prometheusServiceAccount: + name: "" + namespace: "" networkPolicy: enabled: false