diff --git a/bindata/v4.1.0/aws-pod-identity-webhook/mutatingwebhook.yaml b/bindata/v4.1.0/aws-pod-identity-webhook/mutatingwebhook.yaml deleted file mode 100644 index 852e03ecd..000000000 --- a/bindata/v4.1.0/aws-pod-identity-webhook/mutatingwebhook.yaml +++ /dev/null @@ -1,28 +0,0 @@ -apiVersion: admissionregistration.k8s.io/v1 -kind: MutatingWebhookConfiguration -metadata: - name: pod-identity-webhook - annotations: - service.beta.openshift.io/inject-cabundle: "true" -webhooks: -- name: pod-identity-webhook.amazonaws.com - admissionReviewVersions: - - v1beta1 - failurePolicy: Ignore - sideEffects: None - clientConfig: - service: - name: pod-identity-webhook - namespace: openshift-cloud-credential-operator - path: "/mutate" - namespaceSelector: - matchExpressions: - - key: openshift.io/run-level - operator: NotIn - values: - - "0" - rules: - - operations: [ "CREATE" ] - apiGroups: [""] - apiVersions: ["v1"] - resources: ["pods"] diff --git a/bindata/v4.1.0/azure-pod-identity-webhook/deployment.yaml b/bindata/v4.1.0/azure-pod-identity-webhook/deployment.yaml new file mode 100644 index 000000000..b0995fa18 --- /dev/null +++ b/bindata/v4.1.0/azure-pod-identity-webhook/deployment.yaml @@ -0,0 +1,99 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + azure-workload-identity.io/system: "true" + name: pod-identity-webhook + namespace: openshift-cloud-credential-operator +spec: + replicas: 2 + selector: + matchLabels: + app: pod-identity-webhook + template: + metadata: + labels: + app: pod-identity-webhook + spec: + containers: + - args: + - --log-level=info + - --disable-cert-rotation=true + command: + - /usr/bin/azure-workload-identity-webhook + env: + - name: AZURE_TENANT_ID + valueFrom: + secretKeyRef: + name: azure-credentials + key: azure_tenant_id + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + image: ${IMAGE} + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 6 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 15 + periodSeconds: 20 + name: pod-identity-webhook + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + - containerPort: 8095 + name: metrics + protocol: TCP + - containerPort: 9440 + name: healthz + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: healthz + initialDelaySeconds: 5 + periodSeconds: 5 + resources: + limits: + cpu: 100m + memory: 30Mi + requests: + cpu: 100m + memory: 20Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: [ "ALL" ] + volumeMounts: + - mountPath: /certs + name: webhook-certs + readOnly: true + nodeSelector: + node-role.kubernetes.io/master: "" + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/master + operator: Exists + - effect: NoExecute + key: node.kubernetes.io/unreachable + operator: Exists + tolerationSeconds: 120 + - effect: NoExecute + key: node.kubernetes.io/not-ready + operator: Exists + tolerationSeconds: 120 + priorityClassName: system-cluster-critical + serviceAccountName: pod-identity-webhook + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumes: + - name: webhook-certs + secret: + secretName: pod-identity-webhook diff --git a/bindata/v4.1.0/aws-pod-identity-webhook/clusterrole.yaml b/bindata/v4.1.0/common/clusterrole.yaml similarity index 100% rename from bindata/v4.1.0/aws-pod-identity-webhook/clusterrole.yaml rename to bindata/v4.1.0/common/clusterrole.yaml diff --git a/bindata/v4.1.0/aws-pod-identity-webhook/clusterrolebinding.yaml b/bindata/v4.1.0/common/clusterrolebinding.yaml similarity index 100% rename from bindata/v4.1.0/aws-pod-identity-webhook/clusterrolebinding.yaml rename to bindata/v4.1.0/common/clusterrolebinding.yaml diff --git a/bindata/v4.1.0/common/mutatingwebhook.yaml b/bindata/v4.1.0/common/mutatingwebhook.yaml new file mode 100644 index 000000000..1d4d66cd5 --- /dev/null +++ b/bindata/v4.1.0/common/mutatingwebhook.yaml @@ -0,0 +1,28 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: pod-identity-webhook + annotations: + service.beta.openshift.io/inject-cabundle: "true" +webhooks: + - name: pod-identity-webhook.mutate.io + admissionReviewVersions: + - v1beta1 + failurePolicy: Ignore + sideEffects: None + clientConfig: + service: + name: pod-identity-webhook + namespace: openshift-cloud-credential-operator + path: "/mutate" + namespaceSelector: + matchExpressions: + - key: openshift.io/run-level + operator: NotIn + values: + - "0" + rules: + - operations: [ "CREATE" ] + apiGroups: [""] + apiVersions: ["v1"] + resources: ["pods"] diff --git a/bindata/v4.1.0/aws-pod-identity-webhook/poddisruptionbudget.yaml b/bindata/v4.1.0/common/poddisruptionbudget.yaml similarity index 100% rename from bindata/v4.1.0/aws-pod-identity-webhook/poddisruptionbudget.yaml rename to bindata/v4.1.0/common/poddisruptionbudget.yaml diff --git a/bindata/v4.1.0/aws-pod-identity-webhook/role.yaml b/bindata/v4.1.0/common/role.yaml similarity index 100% rename from bindata/v4.1.0/aws-pod-identity-webhook/role.yaml rename to bindata/v4.1.0/common/role.yaml diff --git a/bindata/v4.1.0/aws-pod-identity-webhook/rolebinding.yaml b/bindata/v4.1.0/common/rolebinding.yaml similarity index 100% rename from bindata/v4.1.0/aws-pod-identity-webhook/rolebinding.yaml rename to bindata/v4.1.0/common/rolebinding.yaml diff --git a/bindata/v4.1.0/aws-pod-identity-webhook/sa.yaml b/bindata/v4.1.0/common/sa.yaml similarity index 100% rename from bindata/v4.1.0/aws-pod-identity-webhook/sa.yaml rename to bindata/v4.1.0/common/sa.yaml diff --git a/bindata/v4.1.0/aws-pod-identity-webhook/svc.yaml b/bindata/v4.1.0/common/svc.yaml similarity index 100% rename from bindata/v4.1.0/aws-pod-identity-webhook/svc.yaml rename to bindata/v4.1.0/common/svc.yaml diff --git a/pkg/assets/v410_00_assets/bindata.go b/pkg/assets/v410_00_assets/bindata.go index d41d88f27..817c7ae4b 100644 --- a/pkg/assets/v410_00_assets/bindata.go +++ b/pkg/assets/v410_00_assets/bindata.go @@ -1,14 +1,15 @@ // Code generated for package v410_00_assets by go-bindata DO NOT EDIT. (@generated) // sources: -// bindata/v4.1.0/aws-pod-identity-webhook/clusterrole.yaml -// bindata/v4.1.0/aws-pod-identity-webhook/clusterrolebinding.yaml // bindata/v4.1.0/aws-pod-identity-webhook/deployment.yaml -// bindata/v4.1.0/aws-pod-identity-webhook/mutatingwebhook.yaml -// bindata/v4.1.0/aws-pod-identity-webhook/poddisruptionbudget.yaml -// bindata/v4.1.0/aws-pod-identity-webhook/role.yaml -// bindata/v4.1.0/aws-pod-identity-webhook/rolebinding.yaml -// bindata/v4.1.0/aws-pod-identity-webhook/sa.yaml -// bindata/v4.1.0/aws-pod-identity-webhook/svc.yaml +// bindata/v4.1.0/azure-pod-identity-webhook/deployment.yaml +// bindata/v4.1.0/common/clusterrole.yaml +// bindata/v4.1.0/common/clusterrolebinding.yaml +// bindata/v4.1.0/common/mutatingwebhook.yaml +// bindata/v4.1.0/common/poddisruptionbudget.yaml +// bindata/v4.1.0/common/role.yaml +// bindata/v4.1.0/common/rolebinding.yaml +// bindata/v4.1.0/common/sa.yaml +// bindata/v4.1.0/common/svc.yaml package v410_00_assets import ( @@ -62,65 +63,6 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _v410AwsPodIdentityWebhookClusterroleYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: pod-identity-webhook -rules: -- apiGroups: - - "" - resources: - - serviceaccounts - verbs: - - get - - watch - - list -`) - -func v410AwsPodIdentityWebhookClusterroleYamlBytes() ([]byte, error) { - return _v410AwsPodIdentityWebhookClusterroleYaml, nil -} - -func v410AwsPodIdentityWebhookClusterroleYaml() (*asset, error) { - bytes, err := v410AwsPodIdentityWebhookClusterroleYamlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "v4.1.0/aws-pod-identity-webhook/clusterrole.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _v410AwsPodIdentityWebhookClusterrolebindingYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: pod-identity-webhook -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: pod-identity-webhook -subjects: -- kind: ServiceAccount - name: pod-identity-webhook - namespace: openshift-cloud-credential-operator -`) - -func v410AwsPodIdentityWebhookClusterrolebindingYamlBytes() ([]byte, error) { - return _v410AwsPodIdentityWebhookClusterrolebindingYaml, nil -} - -func v410AwsPodIdentityWebhookClusterrolebindingYaml() (*asset, error) { - bytes, err := v410AwsPodIdentityWebhookClusterrolebindingYamlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "v4.1.0/aws-pod-identity-webhook/clusterrolebinding.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - var _v410AwsPodIdentityWebhookDeploymentYaml = []byte(`apiVersion: apps/v1 kind: Deployment metadata: @@ -207,52 +149,227 @@ func v410AwsPodIdentityWebhookDeploymentYaml() (*asset, error) { return a, nil } -var _v410AwsPodIdentityWebhookMutatingwebhookYaml = []byte(`apiVersion: admissionregistration.k8s.io/v1 +var _v410AzurePodIdentityWebhookDeploymentYaml = []byte(`apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + azure-workload-identity.io/system: "true" + name: pod-identity-webhook + namespace: openshift-cloud-credential-operator +spec: + replicas: 2 + selector: + matchLabels: + app: pod-identity-webhook + template: + metadata: + labels: + app: pod-identity-webhook + spec: + containers: + - args: + - --log-level=info + - --disable-cert-rotation=true + command: + - /usr/bin/azure-workload-identity-webhook + env: + - name: AZURE_TENANT_ID + valueFrom: + secretKeyRef: + name: azure-credentials + key: azure_tenant_id + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + image: ${IMAGE} + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 6 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 15 + periodSeconds: 20 + name: pod-identity-webhook + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + - containerPort: 8095 + name: metrics + protocol: TCP + - containerPort: 9440 + name: healthz + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: healthz + initialDelaySeconds: 5 + periodSeconds: 5 + resources: + limits: + cpu: 100m + memory: 30Mi + requests: + cpu: 100m + memory: 20Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: [ "ALL" ] + volumeMounts: + - mountPath: /certs + name: webhook-certs + readOnly: true + nodeSelector: + node-role.kubernetes.io/master: "" + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/master + operator: Exists + - effect: NoExecute + key: node.kubernetes.io/unreachable + operator: Exists + tolerationSeconds: 120 + - effect: NoExecute + key: node.kubernetes.io/not-ready + operator: Exists + tolerationSeconds: 120 + priorityClassName: system-cluster-critical + serviceAccountName: pod-identity-webhook + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumes: + - name: webhook-certs + secret: + secretName: pod-identity-webhook +`) + +func v410AzurePodIdentityWebhookDeploymentYamlBytes() ([]byte, error) { + return _v410AzurePodIdentityWebhookDeploymentYaml, nil +} + +func v410AzurePodIdentityWebhookDeploymentYaml() (*asset, error) { + bytes, err := v410AzurePodIdentityWebhookDeploymentYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "v4.1.0/azure-pod-identity-webhook/deployment.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _v410CommonClusterroleYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: pod-identity-webhook +rules: +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - get + - watch + - list +`) + +func v410CommonClusterroleYamlBytes() ([]byte, error) { + return _v410CommonClusterroleYaml, nil +} + +func v410CommonClusterroleYaml() (*asset, error) { + bytes, err := v410CommonClusterroleYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "v4.1.0/common/clusterrole.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _v410CommonClusterrolebindingYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: pod-identity-webhook +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: pod-identity-webhook +subjects: +- kind: ServiceAccount + name: pod-identity-webhook + namespace: openshift-cloud-credential-operator +`) + +func v410CommonClusterrolebindingYamlBytes() ([]byte, error) { + return _v410CommonClusterrolebindingYaml, nil +} + +func v410CommonClusterrolebindingYaml() (*asset, error) { + bytes, err := v410CommonClusterrolebindingYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "v4.1.0/common/clusterrolebinding.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _v410CommonMutatingwebhookYaml = []byte(`apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: name: pod-identity-webhook annotations: service.beta.openshift.io/inject-cabundle: "true" webhooks: -- name: pod-identity-webhook.amazonaws.com - admissionReviewVersions: - - v1beta1 - failurePolicy: Ignore - sideEffects: None - clientConfig: - service: - name: pod-identity-webhook - namespace: openshift-cloud-credential-operator - path: "/mutate" - namespaceSelector: - matchExpressions: - - key: openshift.io/run-level - operator: NotIn - values: - - "0" - rules: - - operations: [ "CREATE" ] - apiGroups: [""] - apiVersions: ["v1"] - resources: ["pods"] + - name: pod-identity-webhook.mutate.io + admissionReviewVersions: + - v1beta1 + failurePolicy: Ignore + sideEffects: None + clientConfig: + service: + name: pod-identity-webhook + namespace: openshift-cloud-credential-operator + path: "/mutate" + namespaceSelector: + matchExpressions: + - key: openshift.io/run-level + operator: NotIn + values: + - "0" + rules: + - operations: [ "CREATE" ] + apiGroups: [""] + apiVersions: ["v1"] + resources: ["pods"] `) -func v410AwsPodIdentityWebhookMutatingwebhookYamlBytes() ([]byte, error) { - return _v410AwsPodIdentityWebhookMutatingwebhookYaml, nil +func v410CommonMutatingwebhookYamlBytes() ([]byte, error) { + return _v410CommonMutatingwebhookYaml, nil } -func v410AwsPodIdentityWebhookMutatingwebhookYaml() (*asset, error) { - bytes, err := v410AwsPodIdentityWebhookMutatingwebhookYamlBytes() +func v410CommonMutatingwebhookYaml() (*asset, error) { + bytes, err := v410CommonMutatingwebhookYamlBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "v4.1.0/aws-pod-identity-webhook/mutatingwebhook.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "v4.1.0/common/mutatingwebhook.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _v410AwsPodIdentityWebhookPoddisruptionbudgetYaml = []byte(`apiVersion: policy/v1 +var _v410CommonPoddisruptionbudgetYaml = []byte(`apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: pod-identity-webhook @@ -264,22 +381,22 @@ spec: app: pod-identity-webhook `) -func v410AwsPodIdentityWebhookPoddisruptionbudgetYamlBytes() ([]byte, error) { - return _v410AwsPodIdentityWebhookPoddisruptionbudgetYaml, nil +func v410CommonPoddisruptionbudgetYamlBytes() ([]byte, error) { + return _v410CommonPoddisruptionbudgetYaml, nil } -func v410AwsPodIdentityWebhookPoddisruptionbudgetYaml() (*asset, error) { - bytes, err := v410AwsPodIdentityWebhookPoddisruptionbudgetYamlBytes() +func v410CommonPoddisruptionbudgetYaml() (*asset, error) { + bytes, err := v410CommonPoddisruptionbudgetYamlBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "v4.1.0/aws-pod-identity-webhook/poddisruptionbudget.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "v4.1.0/common/poddisruptionbudget.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _v410AwsPodIdentityWebhookRoleYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1 +var _v410CommonRoleYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: pod-identity-webhook @@ -303,22 +420,22 @@ rules: - "pod-identity-webhook" `) -func v410AwsPodIdentityWebhookRoleYamlBytes() ([]byte, error) { - return _v410AwsPodIdentityWebhookRoleYaml, nil +func v410CommonRoleYamlBytes() ([]byte, error) { + return _v410CommonRoleYaml, nil } -func v410AwsPodIdentityWebhookRoleYaml() (*asset, error) { - bytes, err := v410AwsPodIdentityWebhookRoleYamlBytes() +func v410CommonRoleYaml() (*asset, error) { + bytes, err := v410CommonRoleYamlBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "v4.1.0/aws-pod-identity-webhook/role.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "v4.1.0/common/role.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _v410AwsPodIdentityWebhookRolebindingYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1 +var _v410CommonRolebindingYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: pod-identity-webhook @@ -333,44 +450,44 @@ subjects: namespace: openshift-cloud-credential-operator `) -func v410AwsPodIdentityWebhookRolebindingYamlBytes() ([]byte, error) { - return _v410AwsPodIdentityWebhookRolebindingYaml, nil +func v410CommonRolebindingYamlBytes() ([]byte, error) { + return _v410CommonRolebindingYaml, nil } -func v410AwsPodIdentityWebhookRolebindingYaml() (*asset, error) { - bytes, err := v410AwsPodIdentityWebhookRolebindingYamlBytes() +func v410CommonRolebindingYaml() (*asset, error) { + bytes, err := v410CommonRolebindingYamlBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "v4.1.0/aws-pod-identity-webhook/rolebinding.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "v4.1.0/common/rolebinding.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _v410AwsPodIdentityWebhookSaYaml = []byte(`apiVersion: v1 +var _v410CommonSaYaml = []byte(`apiVersion: v1 kind: ServiceAccount metadata: name: pod-identity-webhook namespace: openshift-cloud-credential-operator `) -func v410AwsPodIdentityWebhookSaYamlBytes() ([]byte, error) { - return _v410AwsPodIdentityWebhookSaYaml, nil +func v410CommonSaYamlBytes() ([]byte, error) { + return _v410CommonSaYaml, nil } -func v410AwsPodIdentityWebhookSaYaml() (*asset, error) { - bytes, err := v410AwsPodIdentityWebhookSaYamlBytes() +func v410CommonSaYaml() (*asset, error) { + bytes, err := v410CommonSaYamlBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "v4.1.0/aws-pod-identity-webhook/sa.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "v4.1.0/common/sa.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _v410AwsPodIdentityWebhookSvcYaml = []byte(`apiVersion: v1 +var _v410CommonSvcYaml = []byte(`apiVersion: v1 kind: Service metadata: name: pod-identity-webhook @@ -388,17 +505,17 @@ spec: app: pod-identity-webhook `) -func v410AwsPodIdentityWebhookSvcYamlBytes() ([]byte, error) { - return _v410AwsPodIdentityWebhookSvcYaml, nil +func v410CommonSvcYamlBytes() ([]byte, error) { + return _v410CommonSvcYaml, nil } -func v410AwsPodIdentityWebhookSvcYaml() (*asset, error) { - bytes, err := v410AwsPodIdentityWebhookSvcYamlBytes() +func v410CommonSvcYaml() (*asset, error) { + bytes, err := v410CommonSvcYamlBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "v4.1.0/aws-pod-identity-webhook/svc.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "v4.1.0/common/svc.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -455,15 +572,16 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ - "v4.1.0/aws-pod-identity-webhook/clusterrole.yaml": v410AwsPodIdentityWebhookClusterroleYaml, - "v4.1.0/aws-pod-identity-webhook/clusterrolebinding.yaml": v410AwsPodIdentityWebhookClusterrolebindingYaml, - "v4.1.0/aws-pod-identity-webhook/deployment.yaml": v410AwsPodIdentityWebhookDeploymentYaml, - "v4.1.0/aws-pod-identity-webhook/mutatingwebhook.yaml": v410AwsPodIdentityWebhookMutatingwebhookYaml, - "v4.1.0/aws-pod-identity-webhook/poddisruptionbudget.yaml": v410AwsPodIdentityWebhookPoddisruptionbudgetYaml, - "v4.1.0/aws-pod-identity-webhook/role.yaml": v410AwsPodIdentityWebhookRoleYaml, - "v4.1.0/aws-pod-identity-webhook/rolebinding.yaml": v410AwsPodIdentityWebhookRolebindingYaml, - "v4.1.0/aws-pod-identity-webhook/sa.yaml": v410AwsPodIdentityWebhookSaYaml, - "v4.1.0/aws-pod-identity-webhook/svc.yaml": v410AwsPodIdentityWebhookSvcYaml, + "v4.1.0/aws-pod-identity-webhook/deployment.yaml": v410AwsPodIdentityWebhookDeploymentYaml, + "v4.1.0/azure-pod-identity-webhook/deployment.yaml": v410AzurePodIdentityWebhookDeploymentYaml, + "v4.1.0/common/clusterrole.yaml": v410CommonClusterroleYaml, + "v4.1.0/common/clusterrolebinding.yaml": v410CommonClusterrolebindingYaml, + "v4.1.0/common/mutatingwebhook.yaml": v410CommonMutatingwebhookYaml, + "v4.1.0/common/poddisruptionbudget.yaml": v410CommonPoddisruptionbudgetYaml, + "v4.1.0/common/role.yaml": v410CommonRoleYaml, + "v4.1.0/common/rolebinding.yaml": v410CommonRolebindingYaml, + "v4.1.0/common/sa.yaml": v410CommonSaYaml, + "v4.1.0/common/svc.yaml": v410CommonSvcYaml, } // AssetDir returns the file names below a certain @@ -511,15 +629,20 @@ type bintree struct { var _bintree = &bintree{nil, map[string]*bintree{ "v4.1.0": {nil, map[string]*bintree{ "aws-pod-identity-webhook": {nil, map[string]*bintree{ - "clusterrole.yaml": {v410AwsPodIdentityWebhookClusterroleYaml, map[string]*bintree{}}, - "clusterrolebinding.yaml": {v410AwsPodIdentityWebhookClusterrolebindingYaml, map[string]*bintree{}}, - "deployment.yaml": {v410AwsPodIdentityWebhookDeploymentYaml, map[string]*bintree{}}, - "mutatingwebhook.yaml": {v410AwsPodIdentityWebhookMutatingwebhookYaml, map[string]*bintree{}}, - "poddisruptionbudget.yaml": {v410AwsPodIdentityWebhookPoddisruptionbudgetYaml, map[string]*bintree{}}, - "role.yaml": {v410AwsPodIdentityWebhookRoleYaml, map[string]*bintree{}}, - "rolebinding.yaml": {v410AwsPodIdentityWebhookRolebindingYaml, map[string]*bintree{}}, - "sa.yaml": {v410AwsPodIdentityWebhookSaYaml, map[string]*bintree{}}, - "svc.yaml": {v410AwsPodIdentityWebhookSvcYaml, map[string]*bintree{}}, + "deployment.yaml": {v410AwsPodIdentityWebhookDeploymentYaml, map[string]*bintree{}}, + }}, + "azure-pod-identity-webhook": {nil, map[string]*bintree{ + "deployment.yaml": {v410AzurePodIdentityWebhookDeploymentYaml, map[string]*bintree{}}, + }}, + "common": {nil, map[string]*bintree{ + "clusterrole.yaml": {v410CommonClusterroleYaml, map[string]*bintree{}}, + "clusterrolebinding.yaml": {v410CommonClusterrolebindingYaml, map[string]*bintree{}}, + "mutatingwebhook.yaml": {v410CommonMutatingwebhookYaml, map[string]*bintree{}}, + "poddisruptionbudget.yaml": {v410CommonPoddisruptionbudgetYaml, map[string]*bintree{}}, + "role.yaml": {v410CommonRoleYaml, map[string]*bintree{}}, + "rolebinding.yaml": {v410CommonRolebindingYaml, map[string]*bintree{}}, + "sa.yaml": {v410CommonSaYaml, map[string]*bintree{}}, + "svc.yaml": {v410CommonSvcYaml, map[string]*bintree{}}, }}, }}, }} diff --git a/pkg/operator/controller.go b/pkg/operator/controller.go index f7c180755..557400eb8 100644 --- a/pkg/operator/controller.go +++ b/pkg/operator/controller.go @@ -23,13 +23,13 @@ import ( gcpactuator "github.com/openshift/cloud-credential-operator/pkg/gcp/actuator" "github.com/openshift/cloud-credential-operator/pkg/kubevirt" "github.com/openshift/cloud-credential-operator/pkg/openstack" - "github.com/openshift/cloud-credential-operator/pkg/operator/awspodidentity" "github.com/openshift/cloud-credential-operator/pkg/operator/cleanup" "github.com/openshift/cloud-credential-operator/pkg/operator/credentialsrequest" "github.com/openshift/cloud-credential-operator/pkg/operator/credentialsrequest/actuator" "github.com/openshift/cloud-credential-operator/pkg/operator/loglevel" "github.com/openshift/cloud-credential-operator/pkg/operator/metrics" "github.com/openshift/cloud-credential-operator/pkg/operator/platform" + "github.com/openshift/cloud-credential-operator/pkg/operator/podidentity" "github.com/openshift/cloud-credential-operator/pkg/operator/secretannotator" "github.com/openshift/cloud-credential-operator/pkg/operator/status" "github.com/openshift/cloud-credential-operator/pkg/ovirt" @@ -50,7 +50,7 @@ const ( func init() { AddToManagerFuncs = append(AddToManagerFuncs, metrics.Add) AddToManagerFuncs = append(AddToManagerFuncs, secretannotator.Add) - AddToManagerFuncs = append(AddToManagerFuncs, awspodidentity.Add) + AddToManagerFuncs = append(AddToManagerFuncs, podidentity.Add) AddToManagerFuncs = append(AddToManagerFuncs, status.Add) AddToManagerFuncs = append(AddToManagerFuncs, loglevel.Add) AddToManagerFuncs = append(AddToManagerFuncs, cleanup.Add) diff --git a/pkg/operator/podidentity/awspodidentitywebhook.go b/pkg/operator/podidentity/awspodidentitywebhook.go new file mode 100644 index 000000000..5051aebea --- /dev/null +++ b/pkg/operator/podidentity/awspodidentitywebhook.go @@ -0,0 +1,22 @@ +package podidentity + +import ( + "os" + + "k8s.io/client-go/kubernetes" +) + +type AwsPodIdentity struct { +} + +func (a AwsPodIdentity) ShouldBeDeployed(clientSet kubernetes.Interface, namespace string) (bool, error) { + return true, nil +} + +func (a AwsPodIdentity) Deployment() string { + return "v4.1.0/aws-pod-identity-webhook/deployment.yaml" +} + +func (a AwsPodIdentity) GetImagePullSpec() string { + return os.Getenv("AWS_POD_IDENTITY_WEBHOOK_IMAGE") +} diff --git a/pkg/operator/podidentity/azurepodidentitywebhook.go b/pkg/operator/podidentity/azurepodidentitywebhook.go new file mode 100644 index 000000000..bef584cc0 --- /dev/null +++ b/pkg/operator/podidentity/azurepodidentitywebhook.go @@ -0,0 +1,38 @@ +package podidentity + +import ( + "context" + "os" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" +) + +const ( + azureTenantIdKey = "azure_tenant_id" +) + +type AzurePodIdentity struct { +} + +func (a AzurePodIdentity) ShouldBeDeployed(clientSet kubernetes.Interface, namespace string) (bool, error) { + secret, err := clientSet.CoreV1().Secrets(namespace).Get(context.TODO(), + "azure-credentials", metav1.GetOptions{}) + if apierrors.IsNotFound(err) { + return false, nil + } + if err != nil { + return false, err + } + _, ok := secret.Data[azureTenantIdKey] + return ok, nil +} + +func (a AzurePodIdentity) Deployment() string { + return "v4.1.0/azure-pod-identity-webhook/deployment.yaml" +} + +func (a AzurePodIdentity) GetImagePullSpec() string { + return os.Getenv("AZURE_POD_IDENTITY_WEBHOOK_IMAGE") +} diff --git a/pkg/operator/awspodidentity/awspodidentitywebhook_controller.go b/pkg/operator/podidentity/podidentitywebhook_controller.go similarity index 78% rename from pkg/operator/awspodidentity/awspodidentitywebhook_controller.go rename to pkg/operator/podidentity/podidentitywebhook_controller.go index af11dcbd4..82f97596a 100644 --- a/pkg/operator/awspodidentity/awspodidentitywebhook_controller.go +++ b/pkg/operator/podidentity/podidentitywebhook_controller.go @@ -1,13 +1,12 @@ -package awspodidentity +package podidentity import ( "context" "fmt" - "os" + "strings" "time" log "github.com/sirupsen/logrus" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/serializer" @@ -36,28 +35,29 @@ import ( ) const ( - controllerName = "awspodidentity" + controllerName = "podidentity" deploymentName = "cloud-credential-operator" operatorNamespace = "openshift-cloud-credential-operator" retryInterval = 10 * time.Second reasonStaticResourceReconcileFailed = "StaticResourceReconcileFailed" + pdb = "v4.1.0/common/poddisruptionbudget.yaml" + webhook = "v4.1.0/common/mutatingwebhook.yaml" ) var ( defaultCodecs = serializer.NewCodecFactory(scheme.Scheme) defaultCodec = defaultCodecs.UniversalDeserializer() staticFiles = []string{ - "v4.1.0/aws-pod-identity-webhook/sa.yaml", - "v4.1.0/aws-pod-identity-webhook/clusterrole.yaml", - "v4.1.0/aws-pod-identity-webhook/role.yaml", - "v4.1.0/aws-pod-identity-webhook/clusterrolebinding.yaml", - "v4.1.0/aws-pod-identity-webhook/rolebinding.yaml", - "v4.1.0/aws-pod-identity-webhook/svc.yaml", + "v4.1.0/common/sa.yaml", + "v4.1.0/common/clusterrole.yaml", + "v4.1.0/common/role.yaml", + "v4.1.0/common/clusterrolebinding.yaml", + "v4.1.0/common/rolebinding.yaml", + "v4.1.0/common/svc.yaml", } - templateFiles = []string{ - "v4.1.0/aws-pod-identity-webhook/deployment.yaml", - "v4.1.0/aws-pod-identity-webhook/mutatingwebhook.yaml", - "v4.1.0/aws-pod-identity-webhook/poddisruptionbudget.yaml", + commonFiles = []string{ + webhook, + pdb, } relatedObjects = []configv1.ObjectReference{ { @@ -106,13 +106,19 @@ var ( } ) -type awsPodIdentityController struct { +type PodIdentityInterface interface { + Deployment() string + GetImagePullSpec() string + ShouldBeDeployed(clientSet kubernetes.Interface, namespace string) (bool, error) +} + +type podIdentityController struct { reconciler *staticResourceReconciler cache cache.Cache logger log.FieldLogger } -func (c *awsPodIdentityController) Start(ctx context.Context) error { +func (c *podIdentityController) Start(ctx context.Context) error { retryTimer := time.NewTimer(retryInterval) for { err := c.reconciler.ReconcileResources(ctx) @@ -133,16 +139,23 @@ func Add(mgr, rootCredentialManager manager.Manager, kubeconfig string) error { if err != nil { return err } - // Only add controller when PlatformType is AWS - platformType := platform.GetType(infraStatus) - if platformType != configv1.AWSPlatformType { - return nil - } // Do not add controller when ControlPlaneTopology is External if infraStatus.ControlPlaneTopology == configv1.ExternalTopologyMode { return nil } - log.Info("setting up AWS pod identity controller") + + var podIdentityObj PodIdentityInterface + platformType := platform.GetType(infraStatus) + switch platformType { + case configv1.AWSPlatformType: + // aws + podIdentityObj = AwsPodIdentity{} + case configv1.AzurePlatformType: + // azure + podIdentityObj = AzurePodIdentity{} + default: + return nil + } config := mgr.GetConfig() clientset, err := kubernetes.NewForConfig(config) @@ -150,6 +163,17 @@ func Add(mgr, rootCredentialManager manager.Manager, kubeconfig string) error { return err } + shouldBeDeployed, err := podIdentityObj.ShouldBeDeployed(clientset, operatorNamespace) + if err != nil { + return err + } + if !shouldBeDeployed { + log.Infof("%s pod identity was not enabled, nothing to deploy", platformType) + return nil + } + + log.Infof("setting up %s pod identity controller", platformType) + controllerRef := &corev1.ObjectReference{ Kind: "deployment", Namespace: operatorNamespace, @@ -157,20 +181,23 @@ func Add(mgr, rootCredentialManager manager.Manager, kubeconfig string) error { } eventRecorder := events.NewKubeRecorder(clientset.CoreV1().Events(operatorNamespace), deploymentName, controllerRef) logger := log.WithFields(log.Fields{"controller": controllerName}) - imagePullSpec := os.Getenv("AWS_POD_IDENTITY_WEBHOOK_IMAGE") + + imagePullSpec := podIdentityObj.GetImagePullSpec() if len(imagePullSpec) == 0 { - logger.Warn("AWS_POD_IDENTITY_WEBHOOK_IMAGE is not set, AWS pod identity webhook will not be deployed") + logger.Warnf("%s_POD_IDENTITY_WEBHOOK_IMAGE is not set, AWS pod identity webhook will not be deployed", + strings.ToUpper(string(platformType))) return nil } r := &staticResourceReconciler{ - client: mgr.GetClient(), - clientset: clientset, - logger: logger, - eventRecorder: eventRecorder, - imagePullSpec: imagePullSpec, - conditions: []configv1.ClusterOperatorStatusCondition{}, - cache: resourceapply.NewResourceCache(), + client: mgr.GetClient(), + clientset: clientset, + logger: logger, + eventRecorder: eventRecorder, + imagePullSpec: imagePullSpec, + conditions: []configv1.ClusterOperatorStatusCondition{}, + cache: resourceapply.NewResourceCache(), + podIdentityObj: podIdentityObj, } c, err := controller.New(controllerName, mgr, controller.Options{Reconciler: r}) @@ -193,11 +220,12 @@ func Add(mgr, rootCredentialManager manager.Manager, kubeconfig string) error { // Create a namespace local cache separate from the Manager cache // A namespace scoped cache can still handle cluster scoped resources - cache, err := cache.New(config, cache.Options{Namespaces: namespaces}) + controllerCache, err := cache.New(config, cache.Options{Namespaces: namespaces}) if err != nil { return err } - allFiles := append(staticFiles, templateFiles...) + allFiles := append(staticFiles, commonFiles...) + allFiles = append(allFiles, podIdentityObj.Deployment()) for _, file := range allFiles { objBytes := v410_00_assets.MustAsset(file) obj, _, err := defaultCodec.Decode(objBytes, nil, nil) @@ -209,7 +237,7 @@ func Add(mgr, rootCredentialManager manager.Manager, kubeconfig string) error { if !ok { return fmt.Errorf("failed to convert runtime.Object to client.Object") } - informer, err := cache.GetInformer(context.TODO(), co) + informer, err := controllerCache.GetInformer(context.TODO(), co) if err != nil { return err } @@ -221,7 +249,7 @@ func Add(mgr, rootCredentialManager manager.Manager, kubeconfig string) error { } status.AddHandler(controllerName, r) - if err := mgr.Add(&awsPodIdentityController{reconciler: r, cache: cache, logger: logger}); err != nil { + if err := mgr.Add(&podIdentityController{reconciler: r, cache: controllerCache, logger: logger}); err != nil { return err } @@ -245,6 +273,7 @@ type staticResourceReconciler struct { imagePullSpec string conditions []configv1.ClusterOperatorStatusCondition cache resourceapply.ResourceCache + podIdentityObj PodIdentityInterface } var _ reconcile.Reconciler = &staticResourceReconciler{} @@ -293,8 +322,8 @@ func (r *staticResourceReconciler) ReconcileResources(ctx context.Context) error r.logger.Infof("%s reconciled successfully", result.Type) } - // "v4.1.0/aws-pod-identity-webhook/deployment.yaml" - requestedDeployment := resourceread.ReadDeploymentV1OrDie(v410_00_assets.MustAsset("v4.1.0/aws-pod-identity-webhook/deployment.yaml")) + // "v4.1.0//deployment.yaml" + requestedDeployment := resourceread.ReadDeploymentV1OrDie(v410_00_assets.MustAsset(r.podIdentityObj.Deployment())) if topology == configv1.SingleReplicaTopologyMode { // Set replicas=1 for deployment on single replica topology clusters requestedDeployment.Spec.Replicas = pointer.Int32(1) @@ -310,8 +339,8 @@ func (r *staticResourceReconciler) ReconcileResources(ctx context.Context) error r.logger.Infof("Deployment reconciled successfully") } - // "v4.1.0/aws-pod-identity-webhook/mutatingwebhook.yaml" - requestedMutatingWebhookConfiguration := resourceread.ReadMutatingWebhookConfigurationV1OrDie(v410_00_assets.MustAsset("v4.1.0/aws-pod-identity-webhook/mutatingwebhook.yaml")) + // "v4.1.0/common/mutatingwebhook.yaml" + requestedMutatingWebhookConfiguration := resourceread.ReadMutatingWebhookConfigurationV1OrDie(v410_00_assets.MustAsset(webhook)) _, modified, err = resourceapply.ApplyMutatingWebhookConfigurationImproved(context.TODO(), r.clientset.AdmissionregistrationV1(), r.eventRecorder, requestedMutatingWebhookConfiguration, r.cache) if err != nil { r.logger.WithError(err).Error("error applying MutatingWebhookConfiguration") @@ -325,8 +354,8 @@ func (r *staticResourceReconciler) ReconcileResources(ctx context.Context) error // Don't deploy the PDB to single replica topology clusters r.logger.Debugf("not deploying PodDisruptionBudget to single replica topology") } else { - // "v4.1.0/aws-pod-identity-webhook/poddisruptionbudget.yaml" - requestedPDB := resourceread.ReadPodDisruptionBudgetV1OrDie(v410_00_assets.MustAsset("v4.1.0/aws-pod-identity-webhook/poddisruptionbudget.yaml")) + // "v4.1.0/common/poddisruptionbudget.yaml" + requestedPDB := resourceread.ReadPodDisruptionBudgetV1OrDie(v410_00_assets.MustAsset(pdb)) _, modified, err = resourceapply.ApplyPodDisruptionBudget(context.TODO(), r.clientset.PolicyV1(), r.eventRecorder, requestedPDB) if err != nil { r.logger.WithError(err).Error("error applying PodDisruptionBudget") diff --git a/pkg/operator/awspodidentity/awspodidentitywebhook_controller_test.go b/pkg/operator/podidentity/podidentitywebhook_controller_test.go similarity index 53% rename from pkg/operator/awspodidentity/awspodidentitywebhook_controller_test.go rename to pkg/operator/podidentity/podidentitywebhook_controller_test.go index 8043ca64a..42013611b 100644 --- a/pkg/operator/awspodidentity/awspodidentitywebhook_controller_test.go +++ b/pkg/operator/podidentity/podidentitywebhook_controller_test.go @@ -14,10 +14,14 @@ See the License for the specific language governing permissions and limitations under the License. */ -package awspodidentity +package podidentity import ( "context" + "fmt" + corev1 "k8s.io/api/core/v1" + clientgotesting "k8s.io/client-go/testing" + "strings" "testing" log "github.com/sirupsen/logrus" @@ -46,7 +50,7 @@ func init() { log.SetLevel(log.DebugLevel) } -func TestAWSPodIdentityWebhookController(t *testing.T) { +func TestPodIdentityWebhookController(t *testing.T) { schemeutils.SetupScheme(scheme.Scheme) getDeployment := func(c kubernetes.Interface, name, namespace string) *appsv1.Deployment { @@ -65,12 +69,16 @@ func TestAWSPodIdentityWebhookController(t *testing.T) { return nil } + t.Setenv("AWS_POD_IDENTITY_WEBHOOK_IMAGE", "aws_identity_image") + t.Setenv("AZURE_POD_IDENTITY_WEBHOOK_IMAGE", "azure_identity_image") + tests := []struct { name string existing []runtime.Object expectErr bool expectedReplicas int32 expectPDB bool + platformType configv1.PlatformType }{ { name: "Cluster infrastructure topology is SingleReplica", @@ -86,6 +94,7 @@ func TestAWSPodIdentityWebhookController(t *testing.T) { expectErr: false, expectedReplicas: 1, expectPDB: false, + platformType: configv1.AWSPlatformType, }, { name: "Cluster infrastructure topology is HighlyAvailable", @@ -101,6 +110,7 @@ func TestAWSPodIdentityWebhookController(t *testing.T) { expectErr: false, expectedReplicas: 2, expectPDB: true, + platformType: configv1.AWSPlatformType, }, { name: "Cluster infrastructure object has no infrastructure topology set", @@ -114,10 +124,28 @@ func TestAWSPodIdentityWebhookController(t *testing.T) { expectErr: false, expectedReplicas: 2, expectPDB: true, + platformType: configv1.AWSPlatformType, + }, + { + name: "Cluster infrastructure object doesn't exist", + expectErr: true, + platformType: configv1.AWSPlatformType, }, { - name: "Cluster infrastructure object doesn't exist", - expectErr: true, + name: "Azure platform", + existing: []runtime.Object{ + &configv1.Infrastructure{ + ObjectMeta: v1.ObjectMeta{ + Name: "cluster", + }, + Status: configv1.InfrastructureStatus{ + InfrastructureTopology: configv1.HighlyAvailableTopologyMode, + }, + }}, + expectErr: false, + expectedReplicas: 2, + expectPDB: true, + platformType: configv1.AzurePlatformType, }, } @@ -125,18 +153,29 @@ func TestAWSPodIdentityWebhookController(t *testing.T) { t.Run(test.name, func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() + var podIdentityObj PodIdentityInterface + + switch test.platformType { + case configv1.AWSPlatformType: + // aws + podIdentityObj = AwsPodIdentity{} + case configv1.AzurePlatformType: + // azure + podIdentityObj = AzurePodIdentity{} + } - logger := log.WithField("controller", "awspodidentitywebhookcontrollertest") + logger := log.WithField("controller", "podidentitywebhookcontrollertest") fakeClient := fake.NewClientBuilder().WithRuntimeObjects(test.existing...).Build() fakeClientset := fakeclientgo.NewSimpleClientset() r := &staticResourceReconciler{ - client: fakeClient, - clientset: fakeClientset, - logger: logger, - eventRecorder: events.NewInMemoryRecorder(""), - cache: resourceapply.NewResourceCache(), - conditions: []configv1.ClusterOperatorStatusCondition{}, - imagePullSpec: "testimagepullspec", + client: fakeClient, + clientset: fakeClientset, + logger: logger, + eventRecorder: events.NewInMemoryRecorder(""), + cache: resourceapply.NewResourceCache(), + conditions: []configv1.ClusterOperatorStatusCondition{}, + imagePullSpec: podIdentityObj.GetImagePullSpec(), + podIdentityObj: podIdentityObj, } _, err := r.Reconcile(context.TODO(), reconcile.Request{ @@ -145,6 +184,9 @@ func TestAWSPodIdentityWebhookController(t *testing.T) { Namespace: "testNamespace", }, }) + switch { + + } if err != nil && !test.expectErr { require.NoError(t, err, "Unexpected error: %v", err) @@ -154,6 +196,9 @@ func TestAWSPodIdentityWebhookController(t *testing.T) { } if !test.expectErr { + expectedImage := fmt.Sprintf("%s_identity_image", strings.ToLower(string(test.platformType))) + assert.Equal(t, r.imagePullSpec, expectedImage) + podIdentityWebhookDeployment := getDeployment(fakeClientset, "pod-identity-webhook", "openshift-cloud-credential-operator") assert.NotNil(t, podIdentityWebhookDeployment, "did not find expected pod-identity-webhook Deployment") @@ -161,6 +206,8 @@ func TestAWSPodIdentityWebhookController(t *testing.T) { assert.Equal(t, *podIdentityWebhookDeployment.Spec.Replicas, test.expectedReplicas, "found unexpected pod-identity-webhook deployment replicas") } + assert.Equal(t, podIdentityWebhookDeployment.Spec.Template.Spec.Containers[0].Image, expectedImage, "container image matches expected one") + podDisruptionBudget := getPDB(fakeClientset, "pod-identity-webhook", "openshift-cloud-credential-operator") if test.expectPDB { assert.NotNil(t, podDisruptionBudget, "did not find expected pod-identity-webhook PodDisruptionBudget") @@ -171,3 +218,84 @@ func TestAWSPodIdentityWebhookController(t *testing.T) { }) } } + +func TestPodIdentityShouldDeploy(t *testing.T) { + schemeutils.SetupScheme(scheme.Scheme) + + azureCredsSecretName := "azure-credentials" + tests := []struct { + name string + existing []runtime.Object + expectedResult bool + expectErr bool + podIdentityObj PodIdentityInterface + }{{ + name: "Azure secret with credentials exists", + existing: []runtime.Object{ + &corev1.Secret{ + ObjectMeta: v1.ObjectMeta{ + Name: azureCredsSecretName, + }, + Data: map[string][]byte{ + azureTenantIdKey: {}, + }, + }}, + podIdentityObj: AzurePodIdentity{}, + expectedResult: true, + expectErr: false, + }, + { + name: "Azure secret with credentials without tenant id", + existing: []runtime.Object{ + &corev1.Secret{ + ObjectMeta: v1.ObjectMeta{ + Name: azureCredsSecretName, + }, + Data: map[string][]byte{}, + }}, + podIdentityObj: AzurePodIdentity{}, + expectedResult: false, + expectErr: false, + }, + { + name: "Azure no secret with credentials", + existing: []runtime.Object{}, + podIdentityObj: AzurePodIdentity{}, + expectedResult: false, + expectErr: false, + }, + { + name: "Azure fails to get secret and error is not NotFound", + existing: []runtime.Object{ + &corev1.Secret{ + ObjectMeta: v1.ObjectMeta{ + Name: azureCredsSecretName, + }, + Data: map[string][]byte{}, + }}, + podIdentityObj: AzurePodIdentity{}, + expectedResult: false, + expectErr: true, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + fakeClientset := fakeclientgo.NewSimpleClientset(test.existing...) + if test.expectErr { + fakeClientset.PrependReactor("get", "secrets", func(action clientgotesting.Action) (handled bool, ret runtime.Object, err error) { + return true, &corev1.Secret{}, fmt.Errorf("error getting secret") + }) + } + + result, err := test.podIdentityObj.ShouldBeDeployed(fakeClientset, "") + if err != nil && !test.expectErr { + require.NoError(t, err, "Unexpected error: %v", err) + } + if err == nil && test.expectErr { + t.Errorf("Expected error but got none") + } + assert.Equal(t, result, test.expectedResult) + }) + } +}