diff --git a/.rhdh/bundle/manifests/rhdh-operator.clusterserviceversion.yaml b/.rhdh/bundle/manifests/rhdh-operator.clusterserviceversion.yaml index bf738e86..25996bd5 100644 --- a/.rhdh/bundle/manifests/rhdh-operator.clusterserviceversion.yaml +++ b/.rhdh/bundle/manifests/rhdh-operator.clusterserviceversion.yaml @@ -222,32 +222,10 @@ spec: - linux automountServiceAccountToken: true containers: - - args: - - --secure-listen-address=0.0.0.0:8443 - - --upstream=http://127.0.0.1:8080/ - - --logtostderr=true - - --v=0 - image: registry.redhat.io/openshift4/ose-kube-rbac-proxy-rhel9:v4.16 - name: kube-rbac-proxy - ports: - - containerPort: 8443 - name: https - protocol: TCP - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 5m - memory: 64Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - args: - --health-probe-bind-address=:8081 - - --metrics-bind-address=127.0.0.1:8080 + - --metrics-bind-address=:8443 + - --metrics-secure=true - --leader-elect command: - /manager @@ -263,17 +241,22 @@ spec: - name: RELATED_IMAGE_backstage value: registry.redhat.io/rhdh/rhdh-hub-rhel9:1.4 image: registry.redhat.io/rhdh/rhdh-rhel9-operator:1.4 + ports: + - name: health + containerPort: 8081 + - name: metrics + containerPort: 8443 livenessProbe: httpGet: path: /healthz - port: 8081 + port: health initialDelaySeconds: 15 periodSeconds: 20 name: manager readinessProbe: httpGet: path: /readyz - port: 8081 + port: health initialDelaySeconds: 5 periodSeconds: 10 resources: diff --git a/bundle/backstage.io/manifests/backstage-controller-manager-metrics-service_v1_service.yaml b/bundle/backstage.io/manifests/backstage-controller-manager-metrics-service_v1_service.yaml index ac0353f4..e15b50e5 100644 --- a/bundle/backstage.io/manifests/backstage-controller-manager-metrics-service_v1_service.yaml +++ b/bundle/backstage.io/manifests/backstage-controller-manager-metrics-service_v1_service.yaml @@ -3,7 +3,7 @@ kind: Service metadata: creationTimestamp: null labels: - app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/component: metrics app.kubernetes.io/created-by: backstage-operator app.kubernetes.io/instance: controller-manager-metrics-service app.kubernetes.io/managed-by: kustomize @@ -13,10 +13,10 @@ metadata: name: backstage-controller-manager-metrics-service spec: ports: - - name: https + - name: metrics port: 8443 protocol: TCP - targetPort: https + targetPort: metrics selector: control-plane: controller-manager status: diff --git a/bundle/backstage.io/manifests/backstage-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml b/bundle/backstage.io/manifests/backstage-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml index 735c7796..57ea9007 100644 --- a/bundle/backstage.io/manifests/backstage-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml +++ b/bundle/backstage.io/manifests/backstage-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -3,7 +3,7 @@ kind: ClusterRole metadata: creationTimestamp: null labels: - app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/component: metrics-rbac app.kubernetes.io/created-by: backstage-operator app.kubernetes.io/instance: metrics-reader app.kubernetes.io/managed-by: kustomize diff --git a/bundle/backstage.io/manifests/backstage-operator.clusterserviceversion.yaml b/bundle/backstage.io/manifests/backstage-operator.clusterserviceversion.yaml index 7822804b..c7e2de94 100644 --- a/bundle/backstage.io/manifests/backstage-operator.clusterserviceversion.yaml +++ b/bundle/backstage.io/manifests/backstage-operator.clusterserviceversion.yaml @@ -25,7 +25,7 @@ metadata: } } ] - createdAt: "2024-10-14T11:21:00Z" + createdAt: "2024-10-16T20:54:13Z" description: Backstage Operator operators.operatorframework.io/builder: operator-sdk-v1.36.0 operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 @@ -172,41 +172,16 @@ spec: operator: In values: - amd64 - - arm64 - - ppc64le - - s390x - key: kubernetes.io/os operator: In values: - linux automountServiceAccountToken: true containers: - - args: - - --secure-listen-address=0.0.0.0:8443 - - --upstream=http://127.0.0.1:8080/ - - --logtostderr=true - - --v=0 - image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.0 - name: kube-rbac-proxy - ports: - - containerPort: 8443 - name: https - protocol: TCP - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 5m - memory: 64Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - args: - --health-probe-bind-address=:8081 - - --metrics-bind-address=127.0.0.1:8080 + - --metrics-bind-address=:8443 + - --metrics-secure=true - --leader-elect command: - /manager @@ -214,14 +189,19 @@ spec: livenessProbe: httpGet: path: /healthz - port: 8081 + port: health initialDelaySeconds: 15 periodSeconds: 20 name: manager + ports: + - containerPort: 8081 + name: health + - containerPort: 8443 + name: metrics readinessProbe: httpGet: path: /readyz - port: 8081 + port: health initialDelaySeconds: 5 periodSeconds: 10 resources: diff --git a/bundle/rhdh/manifests/backstage-operator.clusterserviceversion.yaml b/bundle/rhdh/manifests/backstage-operator.clusterserviceversion.yaml index 91add360..a4b1dfd4 100644 --- a/bundle/rhdh/manifests/backstage-operator.clusterserviceversion.yaml +++ b/bundle/rhdh/manifests/backstage-operator.clusterserviceversion.yaml @@ -29,7 +29,7 @@ metadata: categories: Developer Tools certified: "true" containerImage: registry-proxy.engineering.redhat.com/rh-osbs/rhdh-rhdh-rhel9-operator:1.3 - createdAt: "2024-10-16T16:51:27Z" + createdAt: "2024-10-16T20:54:18Z" description: Red Hat Developer Hub is a Red Hat supported version of Backstage. It comes with pre-built plug-ins and configuration settings, supports use of an external database, and can help streamline the process of setting up a self-managed @@ -211,41 +211,16 @@ spec: operator: In values: - amd64 - - arm64 - - ppc64le - - s390x - key: kubernetes.io/os operator: In values: - linux automountServiceAccountToken: true containers: - - args: - - --secure-listen-address=0.0.0.0:8443 - - --upstream=http://127.0.0.1:8080/ - - --logtostderr=true - - --v=0 - image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.0 - name: kube-rbac-proxy - ports: - - containerPort: 8443 - name: https - protocol: TCP - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 5m - memory: 64Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - args: - --health-probe-bind-address=:8081 - - --metrics-bind-address=127.0.0.1:8080 + - --metrics-bind-address=:8443 + - --metrics-secure=true - --leader-elect command: - /manager @@ -253,14 +228,19 @@ spec: livenessProbe: httpGet: path: /healthz - port: 8081 + port: health initialDelaySeconds: 15 periodSeconds: 20 name: manager + ports: + - containerPort: 8081 + name: health + - containerPort: 8443 + name: metrics readinessProbe: httpGet: path: /readyz - port: 8081 + port: health initialDelaySeconds: 5 periodSeconds: 10 resources: diff --git a/bundle/rhdh/manifests/rhdh-controller-manager-metrics-service_v1_service.yaml b/bundle/rhdh/manifests/rhdh-controller-manager-metrics-service_v1_service.yaml index 53766e5f..0773ab84 100644 --- a/bundle/rhdh/manifests/rhdh-controller-manager-metrics-service_v1_service.yaml +++ b/bundle/rhdh/manifests/rhdh-controller-manager-metrics-service_v1_service.yaml @@ -3,7 +3,7 @@ kind: Service metadata: creationTimestamp: null labels: - app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/component: metrics app.kubernetes.io/created-by: backstage-operator app.kubernetes.io/instance: controller-manager-metrics-service app.kubernetes.io/managed-by: kustomize @@ -13,10 +13,10 @@ metadata: name: rhdh-controller-manager-metrics-service spec: ports: - - name: https + - name: metrics port: 8443 protocol: TCP - targetPort: https + targetPort: metrics selector: control-plane: controller-manager status: diff --git a/bundle/rhdh/manifests/rhdh-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml b/bundle/rhdh/manifests/rhdh-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml index 630bdd6e..1ee5de04 100644 --- a/bundle/rhdh/manifests/rhdh-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml +++ b/bundle/rhdh/manifests/rhdh-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -3,7 +3,7 @@ kind: ClusterRole metadata: creationTimestamp: null labels: - app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/component: metrics-rbac app.kubernetes.io/created-by: backstage-operator app.kubernetes.io/instance: metrics-reader app.kubernetes.io/managed-by: kustomize diff --git a/config/profile/backstage.io/kustomization.yaml b/config/profile/backstage.io/kustomization.yaml index 93b0e05f..54aba44d 100644 --- a/config/profile/backstage.io/kustomization.yaml +++ b/config/profile/backstage.io/kustomization.yaml @@ -16,16 +16,6 @@ resources: - ../../rbac - manager.yaml -patches: -- path: manager_auth_proxy_patch.yaml - target: - group: apps - kind: Deployment - name: controller-manager - version: v1 -# name: controller-manager -# namespace: system - images: - name: controller newName: quay.io/rhdh-community/operator diff --git a/config/profile/backstage.io/manager.yaml b/config/profile/backstage.io/manager.yaml index 586ea633..fdbe9482 100644 --- a/config/profile/backstage.io/manager.yaml +++ b/config/profile/backstage.io/manager.yaml @@ -38,26 +38,26 @@ spec: spec: # Required because the operator does not work without a Service Account Token automountServiceAccountToken: true # NOSONAR - # (user): Uncomment the following code to configure the nodeAffinity expression + # Configure the nodeAffinity expression # according to the platforms which are supported by your solution. # It is considered best practice to support multiple architectures. You can # build your manager image using the makefile target docker-buildx. - # affinity: - # nodeAffinity: - # requiredDuringSchedulingIgnoredDuringExecution: - # nodeSelectorTerms: - # - matchExpressions: - # - key: kubernetes.io/arch - # operator: In - # values: - # - amd64 - # - arm64 - # - ppc64le - # - s390x - # - key: kubernetes.io/os - # operator: In - # values: - # - linux + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 +# - arm64 +# - ppc64le +# - s390x + - key: kubernetes.io/os + operator: In + values: + - linux securityContext: runAsNonRoot: true # (user): For common cases that do not require escalating privileges @@ -71,7 +71,10 @@ spec: - command: - /manager args: - - --leader-elect + - --health-probe-bind-address=:8081 + - --metrics-bind-address=:8443 + - --metrics-secure=true + - --leader-elect image: controller:latest name: manager securityContext: @@ -79,16 +82,21 @@ spec: capabilities: drop: - "ALL" + ports: + - name: health + containerPort: 8081 + - name: metrics + containerPort: 8443 livenessProbe: httpGet: path: /healthz - port: 8081 + port: health initialDelaySeconds: 15 periodSeconds: 20 readinessProbe: httpGet: path: /readyz - port: 8081 + port: health initialDelaySeconds: 5 periodSeconds: 10 resources: diff --git a/config/profile/backstage.io/manager_auth_proxy_patch.yaml b/config/profile/backstage.io/manager_auth_proxy_patch.yaml deleted file mode 100644 index 687c4a7a..00000000 --- a/config/profile/backstage.io/manager_auth_proxy_patch.yaml +++ /dev/null @@ -1,55 +0,0 @@ -# This patch inject a sidecar container which is a HTTP proxy for the -# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system -spec: - template: - spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/arch - operator: In - values: - - amd64 - - arm64 - - ppc64le - - s390x - - key: kubernetes.io/os - operator: In - values: - - linux - containers: - - name: kube-rbac-proxy - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "ALL" - image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.0 - args: - - "--secure-listen-address=0.0.0.0:8443" - - "--upstream=http://127.0.0.1:8080/" - - "--logtostderr=true" - - "--v=0" - ports: - - containerPort: 8443 - protocol: TCP - name: https - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 5m - memory: 64Mi - - name: manager - args: - - "--health-probe-bind-address=:8081" - - "--metrics-bind-address=127.0.0.1:8080" - - "--leader-elect" diff --git a/config/profile/external/kustomization.yaml b/config/profile/external/kustomization.yaml index 8e7fc68f..491da94a 100644 --- a/config/profile/external/kustomization.yaml +++ b/config/profile/external/kustomization.yaml @@ -10,11 +10,7 @@ resources: - ../../crd - ../../rbac - ../../manager - -patches: -- path: manager_auth_proxy_patch.yaml - target: - group: apps - version: v1 - kind: Deployment - name: controller-manager +images: +- name: controller + newName: quay.io/rhdh-community/operator + newTag: 0.4.0 diff --git a/config/profile/external/manager_auth_proxy_patch.yaml b/config/profile/external/manager_auth_proxy_patch.yaml deleted file mode 100644 index 687c4a7a..00000000 --- a/config/profile/external/manager_auth_proxy_patch.yaml +++ /dev/null @@ -1,55 +0,0 @@ -# This patch inject a sidecar container which is a HTTP proxy for the -# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system -spec: - template: - spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/arch - operator: In - values: - - amd64 - - arm64 - - ppc64le - - s390x - - key: kubernetes.io/os - operator: In - values: - - linux - containers: - - name: kube-rbac-proxy - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "ALL" - image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.0 - args: - - "--secure-listen-address=0.0.0.0:8443" - - "--upstream=http://127.0.0.1:8080/" - - "--logtostderr=true" - - "--v=0" - ports: - - containerPort: 8443 - protocol: TCP - name: https - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 5m - memory: 64Mi - - name: manager - args: - - "--health-probe-bind-address=:8081" - - "--metrics-bind-address=127.0.0.1:8080" - - "--leader-elect" diff --git a/config/profile/rhdh/kustomization.yaml b/config/profile/rhdh/kustomization.yaml index 17d73e8d..16922094 100644 --- a/config/profile/rhdh/kustomization.yaml +++ b/config/profile/rhdh/kustomization.yaml @@ -17,15 +17,6 @@ resources: - manager.yaml # - ../../manager -patches: -- path: manager_auth_proxy_patch.yaml - target: - group: apps - kind: Deployment - name: controller-manager - version: v1 - - images: - name: controller newName: quay.io/rhdh-community/operator diff --git a/config/profile/rhdh/manager.yaml b/config/profile/rhdh/manager.yaml index c9dd71e8..80dc9f0f 100644 --- a/config/profile/rhdh/manager.yaml +++ b/config/profile/rhdh/manager.yaml @@ -38,26 +38,26 @@ spec: spec: # Required because the operator does not work without a Service Account Token automountServiceAccountToken: true # NOSONAR - # (user): Uncomment the following code to configure the nodeAffinity expression - # according to the platforms which are supported by your solution. + # Configure the nodeAffinity expression + # according to the platforms which are supported by your solution. # It is considered best practice to support multiple architectures. You can # build your manager image using the makefile target docker-buildx. - # affinity: - # nodeAffinity: - # requiredDuringSchedulingIgnoredDuringExecution: - # nodeSelectorTerms: - # - matchExpressions: - # - key: kubernetes.io/arch - # operator: In - # values: - # - amd64 - # - arm64 - # - ppc64le - # - s390x - # - key: kubernetes.io/os - # operator: In - # values: - # - linux + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 +# - arm64 +# - ppc64le +# - s390x + - key: kubernetes.io/os + operator: In + values: + - linux securityContext: runAsNonRoot: true # (user): For common cases that do not require escalating privileges @@ -71,7 +71,10 @@ spec: - command: - /manager args: - - --leader-elect + - --health-probe-bind-address=:8081 + - --metrics-bind-address=:8443 + - --metrics-secure=true + - --leader-elect # env: # - name: OPERATOR_NAME # value: rhdh-operator @@ -90,16 +93,21 @@ spec: capabilities: drop: - "ALL" + ports: + - name: health + containerPort: 8081 + - name: metrics + containerPort: 8443 livenessProbe: httpGet: path: /healthz - port: 8081 + port: health initialDelaySeconds: 15 periodSeconds: 20 readinessProbe: httpGet: path: /readyz - port: 8081 + port: health initialDelaySeconds: 5 periodSeconds: 10 resources: diff --git a/config/profile/rhdh/manager_auth_proxy_patch.yaml b/config/profile/rhdh/manager_auth_proxy_patch.yaml deleted file mode 100644 index 68b5a10f..00000000 --- a/config/profile/rhdh/manager_auth_proxy_patch.yaml +++ /dev/null @@ -1,56 +0,0 @@ -# This patch inject a sidecar container which is a HTTP proxy for the -# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: operator -spec: - template: - spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/arch - operator: In - values: - - amd64 - - arm64 - - ppc64le - - s390x - - key: kubernetes.io/os - operator: In - values: - - linux - containers: - - name: kube-rbac-proxy - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "ALL" - #image: registry.redhat.io/openshift4/ose-kube-rbac-proxy:v4.12 - image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.0 - args: - - "--secure-listen-address=0.0.0.0:8443" - - "--upstream=http://127.0.0.1:8080/" - - "--logtostderr=true" - - "--v=0" - ports: - - containerPort: 8443 - protocol: TCP - name: https - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 5m - memory: 64Mi - - name: manager - args: - - "--health-probe-bind-address=:8081" - - "--metrics-bind-address=127.0.0.1:8080" - - "--leader-elect" diff --git a/config/rbac/auth_proxy_role.yaml b/config/rbac/auth_proxy_role.yaml deleted file mode 100644 index 71791530..00000000 --- a/config/rbac/auth_proxy_role.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: proxy-role - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: backstage-operator - app.kubernetes.io/part-of: backstage-operator - app.kubernetes.io/managed-by: kustomize - name: proxy-role -rules: -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create diff --git a/config/rbac/kustomization.yaml b/config/rbac/kustomization.yaml index 731832a6..5adafc9b 100644 --- a/config/rbac/kustomization.yaml +++ b/config/rbac/kustomization.yaml @@ -9,10 +9,14 @@ resources: - role_binding.yaml - leader_election_role.yaml - leader_election_role_binding.yaml -# Comment the following 4 lines if you want to disable -# the auth proxy (https://github.com/brancz/kube-rbac-proxy) -# which protects your /metrics endpoint. -- auth_proxy_service.yaml -- auth_proxy_role.yaml -- auth_proxy_role_binding.yaml -- auth_proxy_client_clusterrole.yaml +# Metrics +- metrics_service.yaml +# The following RBAC configurations are used to protect +# the metrics endpoint with authn/authz. These configurations +# ensure that only authorized users and service accounts +# can access the metrics endpoint. Comment the following +# permissions if you want to disable this protection. +# More info: https://book.kubebuilder.io/reference/metrics.html +- metrics_auth_role.yaml +- metrics_auth_role_binding.yaml +- metrics_reader.yaml diff --git a/config/rbac/metrics_auth_role.yaml b/config/rbac/metrics_auth_role.yaml new file mode 100644 index 00000000..15f4a01a --- /dev/null +++ b/config/rbac/metrics_auth_role.yaml @@ -0,0 +1,24 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: metrics-auth-role + app.kubernetes.io/instance: metrics-auth-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: backstage-operator + app.kubernetes.io/part-of: backstage-operator + app.kubernetes.io/managed-by: kustomize + name: metrics-auth-role +rules: + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create diff --git a/config/rbac/auth_proxy_role_binding.yaml b/config/rbac/metrics_auth_role_binding.yaml similarity index 52% rename from config/rbac/auth_proxy_role_binding.yaml rename to config/rbac/metrics_auth_role_binding.yaml index e0622714..e36a2868 100644 --- a/config/rbac/auth_proxy_role_binding.yaml +++ b/config/rbac/metrics_auth_role_binding.yaml @@ -2,18 +2,18 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: - app.kubernetes.io/name: clusterrolebinding - app.kubernetes.io/instance: proxy-rolebinding - app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/name: metrics-auth-rolebinding + app.kubernetes.io/instance: metrics-auth-rolebinding + app.kubernetes.io/component: rbac app.kubernetes.io/created-by: backstage-operator app.kubernetes.io/part-of: backstage-operator app.kubernetes.io/managed-by: kustomize - name: proxy-rolebinding + name: metrics-auth-rolebinding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: proxy-role + name: metrics-auth-role subjects: -- kind: ServiceAccount - name: controller-manager - namespace: system + - kind: ServiceAccount + name: controller-manager + namespace: system diff --git a/config/rbac/auth_proxy_client_clusterrole.yaml b/config/rbac/metrics_reader.yaml similarity index 75% rename from config/rbac/auth_proxy_client_clusterrole.yaml rename to config/rbac/metrics_reader.yaml index b65ff634..abc753f0 100644 --- a/config/rbac/auth_proxy_client_clusterrole.yaml +++ b/config/rbac/metrics_reader.yaml @@ -4,13 +4,13 @@ metadata: labels: app.kubernetes.io/name: clusterrole app.kubernetes.io/instance: metrics-reader - app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/component: metrics-rbac app.kubernetes.io/created-by: backstage-operator app.kubernetes.io/part-of: backstage-operator app.kubernetes.io/managed-by: kustomize name: metrics-reader rules: -- nonResourceURLs: - - "/metrics" - verbs: - - get + - nonResourceURLs: + - "/metrics" + verbs: + - get diff --git a/config/rbac/auth_proxy_service.yaml b/config/rbac/metrics_service.yaml similarity index 78% rename from config/rbac/auth_proxy_service.yaml rename to config/rbac/metrics_service.yaml index af2fe092..ef89017a 100644 --- a/config/rbac/auth_proxy_service.yaml +++ b/config/rbac/metrics_service.yaml @@ -5,7 +5,7 @@ metadata: control-plane: controller-manager app.kubernetes.io/name: service app.kubernetes.io/instance: controller-manager-metrics-service - app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/component: metrics app.kubernetes.io/created-by: backstage-operator app.kubernetes.io/part-of: backstage-operator app.kubernetes.io/managed-by: kustomize @@ -13,9 +13,9 @@ metadata: namespace: system spec: ports: - - name: https - port: 8443 - protocol: TCP - targetPort: https + - name: metrics + port: 8443 + protocol: TCP + targetPort: metrics selector: control-plane: controller-manager diff --git a/go.mod b/go.mod index 28abb2ec..4ffc7292 100644 --- a/go.mod +++ b/go.mod @@ -18,14 +18,19 @@ require ( ) require ( + github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect + github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch/v5 v5.8.0 // indirect + github.com/felixge/httpsnoop v1.0.3 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect @@ -34,12 +39,14 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect + github.com/google/cel-go v0.17.7 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect github.com/google/uuid v1.3.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -57,11 +64,21 @@ require ( github.com/prometheus/common v0.45.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stoewer/go-strcase v1.2.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 // indirect + go.opentelemetry.io/otel v1.19.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 // indirect + go.opentelemetry.io/otel/metric v1.19.0 // indirect + go.opentelemetry.io/otel/sdk v1.19.0 // indirect + go.opentelemetry.io/otel/trace v1.19.0 // indirect + go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.12.0 // indirect + golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.23.0 // indirect golang.org/x/term v0.23.0 // indirect golang.org/x/text v0.17.0 // indirect @@ -69,13 +86,18 @@ require ( golang.org/x/tools v0.24.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/grpc v1.58.3 // indirect google.golang.org/protobuf v1.34.1 // 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 + k8s.io/apiserver v0.29.2 // indirect k8s.io/component-base v0.29.2 // indirect k8s.io/klog/v2 v2.110.1 // indirect k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect ) diff --git a/go.sum b/go.sum index 46640ae4..6ae309b9 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,13 @@ +github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18= +github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -15,13 +21,18 @@ github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.8.0 h1:lRj6N9Nci7MvzrXuX6HFzU8XjmhPiXPlsKEy1u0KQro= github.com/evanphx/json-patch/v5 v5.8.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= @@ -35,11 +46,15 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v 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/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/cel-go v0.17.7 h1:6ebJFzu1xO2n7TLtN+UBqShGBhlD85bhvglh5DpcfqQ= +github.com/google/cel-go v0.17.7/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -55,6 +70,8 @@ github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -110,10 +127,13 @@ github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDN github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= @@ -123,6 +143,22 @@ github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 h1:KfYpVmrjI7JuToy5k8XV3nkapjWx48k4E4JOtVstzQI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0/go.mod h1:SeQhzAEccGVZVEy7aH87Nh0km+utSpo1pTv6eMMop48= +go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= +go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 h1:3d+S281UTjM+AbF31XSOYn1qXn3BgIdWl8HNEpx08Jk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0/go.mod h1:0+KuTDyKL4gjKCF75pHOX4wuzYDUZYfAQdSu43o+Z2I= +go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= +go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= +go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= +go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= +go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= +go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= +go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -148,6 +184,8 @@ golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba 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/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-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= @@ -176,6 +214,14 @@ gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g= +google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8= +google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e h1:z3vDksarJxsAKM5dmEGv0GHwE2hKJ096wZra71Vs4sw= +google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -183,6 +229,7 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/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.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= @@ -196,6 +243,8 @@ k8s.io/apiextensions-apiserver v0.29.2 h1:UK3xB5lOWSnhaCk0RFZ0LUacPZz9RY4wi/yt2I k8s.io/apiextensions-apiserver v0.29.2/go.mod h1:aLfYjpA5p3OwtqNXQFkhJ56TB+spV8Gc4wfMhUA3/b8= k8s.io/apimachinery v0.29.4 h1:RaFdJiDmuKs/8cm1M6Dh1Kvyh59YQFDcFuFTSmXes6Q= k8s.io/apimachinery v0.29.4/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y= +k8s.io/apiserver v0.29.2 h1:+Z9S0dSNr+CjnVXQePG8TcBWHr3Q7BmAr7NraHvsMiQ= +k8s.io/apiserver v0.29.2/go.mod h1:B0LieKVoyU7ykQvPFm7XSdIHaCHSzCzQWPFa5bqbeMQ= k8s.io/client-go v0.29.4 h1:79ytIedxVfyXV8rpH3jCBW0u+un0fxHDwX5F9K8dPR8= k8s.io/client-go v0.29.4/go.mod h1:kC1thZQ4zQWYwldsfI088BbK6RkxK+aF5ebV8y9Q4tk= k8s.io/component-base v0.29.2 h1:lpiLyuvPA9yV1aQwGLENYyK7n/8t6l3nn3zAtFTJYe8= @@ -206,6 +255,8 @@ k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/A k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 h1:MDF6h2H/h4tbzmtIKTuctcwZmY0tY9mD9fNT47QO6HI= k8s.io/utils v0.0.0-20240921022957-49e7df575cb6/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0 h1:TgtAeesdhpm2SGwkQasmbeqDo8th5wOBA5h/AjTKA4I= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0/go.mod h1:VHVDI/KrK4fjnV61bE2g3sA7tiETLn8sooImelsCx3Y= sigs.k8s.io/controller-runtime v0.17.3 h1:65QmN7r3FWgTxDMz9fvGnO1kbf2nu+acg9p2R9oYYYk= sigs.k8s.io/controller-runtime v0.17.3/go.mod h1:N0jpP5Lo7lMTF9aL56Z/B2oWBJjey6StQM0jRbKQXtY= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= diff --git a/main.go b/main.go index 5cd3fd2d..5dbcd4ec 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,7 @@ import ( // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) // to ensure that exec-entrypoint and run can make use of them. _ "k8s.io/client-go/plugin/pkg/client/auth" + "sigs.k8s.io/controller-runtime/pkg/metrics/filters" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" @@ -41,10 +42,14 @@ func init() { func main() { var metricsAddr string + var secureMetrics bool var enableLeaderElection bool var probeAddr string var ownRuntime bool - flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") + flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", + "The address the metrics endpoint binds to. Use 0 to disable the metrics service.") + flag.BoolVar(&secureMetrics, "metrics-secure", false, + "If set, the metrics endpoint is served securely over HTTPS and requires authentication and authorization.") flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") flag.BoolVar(&enableLeaderElection, "leader-elect", false, "Enable leader election for controller manager. "+ @@ -60,11 +65,20 @@ func main() { ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) + metricsServerOpts := metricsserver.Options{ + BindAddress: metricsAddr, + SecureServing: secureMetrics, + } + if secureMetrics { + // FilterProvider is used to protect the metrics endpoint with authn/authz. + // These configurations ensure that only authorized users and service accounts + // can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info: + // https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/metrics/filters#WithAuthenticationAndAuthorization + metricsServerOpts.FilterProvider = filters.WithAuthenticationAndAuthorization + } mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ - Scheme: scheme, - Metrics: metricsserver.Options{ - BindAddress: metricsAddr, - }, + Scheme: scheme, + Metrics: metricsServerOpts, WebhookServer: webhook.NewServer(webhook.Options{ Port: 9443, }), diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 7c5f63df..e2378409 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -9,12 +9,14 @@ import ( "os/exec" "path/filepath" "strconv" + "strings" "time" "redhat-developer/red-hat-developer-hub-operator/tests/helper" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "github.com/onsi/gomega/types" ) var _ = Describe("Backstage Operator E2E", func() { @@ -37,6 +39,182 @@ var _ = Describe("Backstage Operator E2E", func() { helper.DeleteNamespace(ns, false) }) + Context("operator metrics endpoint", func() { + + var metricsEndpoint string + + BeforeEach(func() { + if testMode != olmDeployTestMode && testMode != defaultDeployTestMode { + Skip(fmt.Sprintf("testing operator metrics endpoint not supported for this mode: %q", testMode)) + } + + By("not creating a kube-rbac-proxy sidecar", func() { + Eventually(func(g Gomega) { + cmd := exec.Command(helper.GetPlatformTool(), "get", + "pods", "-l", "control-plane=controller-manager", + "-o", "jsonpath={.items[*].spec.containers[*].name}", + "-n", _namespace, + ) + containerListOutput, err := helper.Run(cmd) + g.Expect(err).ShouldNot(HaveOccurred()) + containerListNames := helper.GetNonEmptyLines(string(containerListOutput)) + g.Expect(containerListNames).Should(HaveLen(1), + fmt.Sprintf("expected 1 container(s) in the controller pod, but got %d", len(containerListNames))) + }, 3*time.Minute, time.Second).Should(Succeed()) + }) + + By("creating a Service to access the metrics") + var metricsServiceName string + Eventually(func(g Gomega) { + cmd := exec.Command(helper.GetPlatformTool(), "get", "services", + "-l", "control-plane=controller-manager", + "-l", "app.kubernetes.io/component=metrics", + "-o", "jsonpath={.items[*].metadata.name}", + "-n", _namespace, + ) + svcListOutput, err := helper.Run(cmd) + g.Expect(err).ShouldNot(HaveOccurred()) + svcListNames := helper.GetNonEmptyLines(string(svcListOutput)) + g.Expect(svcListNames).Should(HaveLen(1), + fmt.Sprintf("expected 1 service exposing the controller metrics, but got %d", len(svcListNames))) + metricsServiceName = svcListNames[0] + g.Expect(metricsServiceName).ToNot(BeEmpty()) + }, 3*time.Minute, time.Second).Should(Succeed()) + + metricsEndpoint = fmt.Sprintf("https://%s.%s.svc.cluster.local:8443/metrics", metricsServiceName, _namespace) + }) + + buildMetricsTesterPod := func(ns string, withBearerAuth bool) string { + var authHdr string + if withBearerAuth { + authHdr = `-H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"` + } + + return fmt.Sprintf(` +apiVersion: v1 +kind: Pod +metadata: + name: test-controller-metrics-%[1]s + labels: + app: test-controller-metrics-%[1]s +spec: + restartPolicy: OnFailure + securityContext: + runAsNonRoot: %[2]s + seccompProfile: + type: RuntimeDefault + containers: + - name: curl + image: registry.access.redhat.com/ubi9-minimal:latest + command: [ '/bin/sh' ] + args: [ '-c', 'curl -v -s -k -i --fail %[3]s %[4]s' ] + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: [ALL] +`, ns, strconv.FormatBool(helper.IsOpenShift()), authHdr, metricsEndpoint) + } + + for _, tt := range []struct { + description string + withBearerAuth bool + additionalManifests func(ns string) []string + expectedLogsMatcher types.GomegaMatcher + }{ + { + description: "reject unauthenticated requests to the metrics endpoint", + expectedLogsMatcher: SatisfyAll( + SatisfyAny( + ContainSubstring("HTTP/1.1 401 Unauthorized"), + ContainSubstring("HTTP/2 401"), + ), + Not(ContainSubstring(`workqueue_work_duration_seconds_count`)), + ), + }, + { + description: "reject authenticated requests to the metrics endpoint with a service account token lacking RBAC permission", + withBearerAuth: true, + expectedLogsMatcher: SatisfyAll( + SatisfyAny( + ContainSubstring("HTTP/1.1 403 Forbidden"), + ContainSubstring("HTTP/2 403"), + ), + Not(ContainSubstring(`workqueue_work_duration_seconds_count`)), + ), + }, + { + description: "allow authenticated requests to the metrics endpoint with a service account token that has the expected RBAC permission", + withBearerAuth: true, + additionalManifests: func(ns string) []string { + return []string{ + fmt.Sprintf(` +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: metrics-reader-sa-rolebinding-%[1]s +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: rhdh-metrics-reader +subjects: + - kind: ServiceAccount + name: default + namespace: %[1]s +`, ns), + } + }, + expectedLogsMatcher: ContainSubstring(`workqueue_work_duration_seconds_count{name="backstage"}`), + }, + } { + tt := tt + When("creating a Pod that accesses the controller metrics endpoint", func() { + var manifests string + + BeforeEach(func() { + if tt.expectedLogsMatcher == nil { + Fail("test case needs to specify an expectedLogsMatcher to verify the test pod logs") + } + var manifestList []string + if tt.additionalManifests != nil { + manifestList = append(manifestList, tt.additionalManifests(ns)...) + } + manifestList = append(manifestList, buildMetricsTesterPod(ns, tt.withBearerAuth)) + manifests = strings.Join(manifestList, "\n---\n") + + cmd := exec.Command(helper.GetPlatformTool(), "-n", ns, "apply", "-f", "-") + stdin, err := cmd.StdinPipe() + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + go func() { + defer stdin.Close() + _, _ = io.WriteString(stdin, manifests) + }() + _, err = helper.Run(cmd) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + }) + + AfterEach(func() { + if manifests == "" { + return + } + cmd := exec.Command(helper.GetPlatformTool(), "-n", ns, "delete", "-f", "-") + stdin, err := cmd.StdinPipe() + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + go func() { + defer stdin.Close() + _, _ = io.WriteString(stdin, manifests) + }() + _, _ = helper.Run(cmd) + }) + + It("should "+tt.description, func() { + Eventually(func(g Gomega) { + g.Expect(getPodLogs(ns, fmt.Sprintf("app=test-controller-metrics-%s", ns))).Should(tt.expectedLogsMatcher) + }, 3*time.Minute, 5*time.Second).Should(Succeed()) + }) + }) + } + }) + Context("Examples CRs", func() { for _, tt := range []struct {