Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile.rhtpa-operator.rh
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ LABEL features.operators.openshift.io/proxy-aware="false"
LABEL features.operators.openshift.io/cnf="false"
LABEL features.operators.openshift.io/csi="false"
LABEL features.operators.openshift.io/tls-profiles="false"
LABEL features.operators.openshift.io/token-auth-aws="false"
LABEL features.operators.openshift.io/token-auth-aws="true"
LABEL features.operators.openshift.io/token-auth-azure="false"
LABEL features.operators.openshift.io/token-auth-gcp="false"

Expand Down
4 changes: 2 additions & 2 deletions bundle.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ LABEL features.operators.openshift.io/proxy-aware="false"
LABEL features.operators.openshift.io/cnf="false"
LABEL features.operators.openshift.io/csi="false"
LABEL features.operators.openshift.io/tls-profiles="false"
LABEL features.operators.openshift.io/token-auth-aws="false"
LABEL features.operators.openshift.io/token-auth-aws="true"
LABEL features.operators.openshift.io/token-auth-azure="false"
LABEL features.operators.openshift.io/token-auth-gcp="false"
LABEL features.operators.openshift.io/token-auth-gcp="true"
# Core bundle labels.
LABEL operators.operatorframework.io.bundle.mediatype.v1=registry+v1
LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/
Expand Down
4 changes: 2 additions & 2 deletions bundle/manifests/rhtpa-operator.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ metadata:
features.operators.openshift.io/fips-compliant: "false"
features.operators.openshift.io/proxy-aware: "false"
features.operators.openshift.io/tls-profiles: "false"
features.operators.openshift.io/token-auth-aws: "false"
features.operators.openshift.io/token-auth-aws: "true"
features.operators.openshift.io/token-auth-azure: "false"
features.operators.openshift.io/token-auth-gcp: "false"
features.operators.openshift.io/token-auth-gcp: "true"
operators.openshift.io/valid-subscription: '["Red Hat Trusted Profile Analyzer"]'
operators.operatorframework.io/builder: operator-sdk-v1.42.0
operators.operatorframework.io/project_layout: helm.sdk.operatorframework.io/v1
Expand Down
4 changes: 2 additions & 2 deletions bundle/metadata/annotations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ annotations:
features.operators.openshift.io/cnf: "false"
features.operators.openshift.io/csi: "false"
features.operators.openshift.io/tls-profiles: "false"
features.operators.openshift.io/token-auth-aws: "false"
features.operators.openshift.io/token-auth-aws: "true"
features.operators.openshift.io/token-auth-azure: "false"
features.operators.openshift.io/token-auth-gcp: "false"
features.operators.openshift.io/token-auth-gcp: "true"
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ metadata:
features.operators.openshift.io/fips-compliant: "false"
features.operators.openshift.io/proxy-aware: "false"
features.operators.openshift.io/tls-profiles: "false"
features.operators.openshift.io/token-auth-aws: "false"
features.operators.openshift.io/token-auth-aws: "true"
features.operators.openshift.io/token-auth-azure: "false"
features.operators.openshift.io/token-auth-gcp: "false"
features.operators.openshift.io/token-auth-gcp: "true"
operators.openshift.io/valid-subscription: '["Red Hat Trusted Profile Analyzer"]'
name: rhtpa-operator.v0.0.0
namespace: placeholder
Expand Down
8 changes: 8 additions & 0 deletions config/rbac/clusterrole.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cco-credentialsrequest-access
rules:
- apiGroups: ["cloudcredential.openshift.io"]
resources: ["credentialsrequests"]
verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
15 changes: 15 additions & 0 deletions config/rbac/clusterrolebinding_cco.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
app.kubernetes.io/name: rhtpa-operator
app.kubernetes.io/managed-by: kustomize
name: cco-credentialsrequest-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cco-credentialsrequest-access
subjects:
- kind: ServiceAccount
name: rhtpa-operator-controller-manager
namespace: placeholder
2 changes: 2 additions & 0 deletions config/rbac/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ resources:
- rolebinding_job.yaml
- role_cluster_ingress.yaml
- role_cluster_ingress_binding.yaml
- clusterrole.yaml
- clusterrolebinding_cco.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
Expand Down
24 changes: 24 additions & 0 deletions devel/cco/credentialRequest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: cloudcredential.openshift.io/v1
kind: CredentialsRequest
metadata:
name: my-operator-credentials
namespace: openshift-cloud-credential-operator
spec:
secretRef:
name: my-cloud-creds
namespace: my-operator-namespace
providerSpec:
apiVersion: cloudcredential.openshift.io/v1
kind: AWSProviderSpec # AWS
statementEntries:
- effect: Allow
action:
- "s3:GetObject"
- "s3:PutObject"
- "s3:DeleteObject"
- "s3:ListBucket"
- "s3:GetBucketLocation"
- "s3:ListBucketMultipartUploads"
- "s3:AbortMultipartUpload"
- "s3:ListMultipartUploadParts"
resource: "*"
100 changes: 100 additions & 0 deletions extensions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Tokenize with Cloud Credentials Operator

Cloud Credentials Operator (CCO) is installed by default on OCP.
To check the CCO status

```console
oc get clusteroperator cloud-credential
```
it shows something like

```console
NAME VERSION AVAILABLE PROGRESSING DEGRADED SINCE
cloud-credential 4.x.x True False False ...
```
Pod status
```console
oc get pods -n openshift-cloud-credential-operator
```

Credential requests checks
```console
oc get credentialsrequests -n openshift-cloud-credential-operator
```

CCO details
```console
oc describe clusteroperator cloud-credential
```

CCO Modality
```console
oc get cloudcredential cluster -o yaml
```
On spec.credentialsMode will be the configured setting (Mint,
Passthrough, Manual, or empty for default).

## How the Operator interacts with the CCO

1. Operator declares permissions needed in a CredentialsRequest CR in the namespace openshift-cloud-credential-operator

```console
apiVersion: cloudcredential.openshift.io/v1
kind: CredentialsRequest
metadata:
name: my-operator-credentials
namespace: openshift-cloud-credential-operator
spec:
secretRef:
name: my-cloud-creds
namespace: my-operator-namespace
providerSpec:
apiVersion: cloudcredential.openshift.io/v1
kind: AWSProviderSpec # esempio per AWS
statementEntries:
- effect: Allow
action:
- "s3:GetObject"
- "s3:PutObject"
resource: "*"
```

2. CCO processes the CR and create a Kubernetes Secret with the cloud credentails
in the namespace specified in spec.secretRef.

3. Operator reads the Secret and uses the credentials to interact with the cloud API.
The Operator must tolerate the non-immediate availability of the Secret because it takes time to create.

## How to integrate the CCO with the Helm Chart Operator

1. Define Credential Request in the chart
2.
2. Configure Deployment to use the secret created by the CCO

3. Handling the delay of the creation of the secret
first approach: init container
```console
initContainers:
- name: wait-for-creds
image: registry.redhat.io/openshift4/ose-cli
command:
- /bin/bash
- -c
- |
until oc get secret {{ .Release.Name }}-cloud-creds -n {{
.Release.Namespace }} 2>/dev/null; do
echo "Waiting for cloud credentials..."
sleep 5
done
```
second approach Retry in the Operator's code, but this is available on a full Go Operator

4. Support different cloud providers with values configurations

5. RBAC needed to create the CredentialsRequest
6. Support Manual Mode (STS/WIF): if the cluster uses STS mode, CCO doesn’t create the secret automatically.
In STS mode the user must :
1. Extract CredentialsRequest from chart
2. Use ccoctl tool to generate the credentials
3. Create the secrets manually before installing the chart.

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{{- if .Values.cloudProvider }}
apiVersion: cloudcredential.openshift.io/v1
kind: CredentialsRequest
metadata:
name: {{ .Release.Name }}-cloud-creds
namespace: openshift-cloud-credential-operator
spec:
secretRef:
name: {{ .Release.Name }}-cloud-creds
namespace: {{ .Release.Namespace }}
{{- if eq (toString .Values.ccoMode) "manual" }}
cloudTokenPath: /var/run/secrets/openshift/serviceaccount/token
{{- end }}
{{- if eq .Values.cloudProvider "aws" }}
providerSpec:
apiVersion: cloudcredential.openshift.io/v1
kind: AWSProviderSpec
statementEntries:
{{- toYaml .Values.cloudCredentials.aws.statementEntries | nindent 6 }}
{{- if eq (toString .Values.ccoMode) "manual" }}
stsIAMRoleARN: {{ .Values.cloudCredentials.aws.stsIAMRoleARN | default "" | quote }}
{{- end }}
{{- else if eq .Values.cloudProvider "gcp" }}
providerSpec:
apiVersion: cloudcredential.openshift.io/v1
kind: GCPProviderSpec
predefinedRoles:
{{- toYaml .Values.cloudCredentials.gcp.permissions | nindent 6 }}
{{- if eq (toString .Values.ccoMode) "manual" }}
serviceAccountEmail: {{ .Values.cloudCredentials.gcp.serviceAccountEmail | default "" | quote }}
{{- end }}
{{- end }}
{{- end }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{{/*
Cloud Credentials Operator (CCO) helpers for manual/STS/WIF mode.

These templates emit volumes, volume mounts, and environment variables
needed when ccoMode is "manual". For mint/passthrough/default modes
they emit nothing — credentials are handled via _storage.tpl.

Arguments (dict):
* root - .
*/}}

{{/*
Returns "true" when CCO manual mode is active (cloudProvider set AND ccoMode is "manual").
*/}}
{{- define "trustification.cco.isManualMode" -}}
{{- if and .root.Values.cloudProvider (eq (toString .root.Values.ccoMode) "manual") -}}true{{- end -}}
{{- end -}}

{{/*
Returns the CCO secret name.
*/}}
{{- define "trustification.cco.secretName" -}}
{{ .root.Release.Name }}-cloud-creds
{{- end -}}

{{/*
Volumes for CCO manual mode: CCO credentials secret + projected SA token.
*/}}
{{- define "trustification.cco.volumes" -}}
{{- if eq (include "trustification.cco.isManualMode" .) "true" }}
- name: cloud-credentials
secret:
secretName: {{ include "trustification.cco.secretName" . }}
- name: bound-sa-token
projected:
sources:
- serviceAccountToken:
audience: openshift
expirationSeconds: 3600
path: token
{{- end }}
{{- end -}}

{{/*
Volume mounts for CCO manual mode.
*/}}
{{- define "trustification.cco.volumeMounts" -}}
{{- if eq (include "trustification.cco.isManualMode" .) "true" }}
- name: cloud-credentials
mountPath: /var/run/secrets/cloud
readOnly: true
- name: bound-sa-token
mountPath: /var/run/secrets/openshift/serviceaccount
readOnly: true
{{- end }}
{{- end -}}

{{/*
Environment variables for CCO manual mode, branched by cloud provider.
For mint/passthrough/default modes this emits nothing.
*/}}
{{- define "trustification.cco.envVars" -}}
{{- if eq (include "trustification.cco.isManualMode" .) "true" }}
{{- if eq .root.Values.cloudProvider "aws" }}
- name: AWS_SHARED_CREDENTIALS_FILE
value: /var/run/secrets/cloud/credentials
- name: AWS_WEB_IDENTITY_TOKEN_FILE
value: /var/run/secrets/openshift/serviceaccount/token
{{- with .root.Values.cloudCredentials.aws.stsIAMRoleARN }}
- name: AWS_ROLE_ARN
value: {{ . | quote }}
{{- end }}
{{- else if eq .root.Values.cloudProvider "gcp" }}
- name: GOOGLE_APPLICATION_CREDENTIALS
value: /var/run/secrets/cloud/service_account.json
{{- end }}
{{- end }}
{{- end -}}
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,26 @@ Arguments (dict):
- name: TRUSTD_STORAGE_STRATEGY
value: s3

{{- if not (eq (include "trustification.cco.isManualMode" .) "true") }}
- name: TRUSTD_S3_ACCESS_KEY
{{- if and .root.Values.cloudProvider (not .storage.accessKey) }}
valueFrom:
secretKeyRef:
name: {{ .root.Release.Name }}-cloud-creds
key: aws_access_key_id
{{- else }}
{{- include "trustification.common.envVarValue" .storage.accessKey | nindent 2 }}
{{- end }}
- name: TRUSTD_S3_SECRET_KEY
{{- if and .root.Values.cloudProvider (not .storage.secretKey) }}
valueFrom:
secretKeyRef:
name: {{ .root.Release.Name }}-cloud-creds
key: aws_secret_access_key
{{- else }}
{{- include "trustification.common.envVarValue" .storage.secretKey | nindent 2 }}
{{- end }}
{{- end }}
- name: TRUSTD_S3_REGION
{{- include "trustification.common.envVarValue" .storage.region | nindent 2 }}
- name: TRUSTD_S3_BUCKET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ spec:
{{- include "trustification.application.infrastructure.envVars" $mod | nindent 12 }}
{{- include "trustification.postgres.envVars" (dict "root" . "database" .Values.database) | nindent 12 }}
{{- include "trustification.storage.envVars" $mod | nindent 12 }}
{{- include "trustification.cco.envVars" $mod | nindent 12 }}

ports:
{{- include "trustification.application.infrastructure.podPorts" $mod | nindent 12 }}
Expand All @@ -57,6 +58,7 @@ spec:
- name: workdir
mountPath: /data/workdir
{{- include "trustification.storage.volumeMount" $mod | nindent 12 }}
{{- include "trustification.cco.volumeMounts" $mod | nindent 12 }}
{{- include "trustification.application.extraVolumeMounts" $mod | nindent 12 }}

volumes:
Expand All @@ -75,6 +77,7 @@ spec:
requests:
storage: {{ $mod.module.workingDirectory.size | quote }}
{{- include "trustification.storage.volume" $mod | nindent 8 }}
{{- include "trustification.cco.volumes" $mod | nindent 8 }}
{{- include "trustification.application.extraVolumes" $mod | nindent 8 }}

{{ end }}
Loading
Loading