Skip to content

Commit

Permalink
ISV-5645: Signing pipeline for image bootstrapping
Browse files Browse the repository at this point in the history
A new pipeline is created that will server for the automating of index
image bootstrapping process. The new pipeline allow signing only images
that haven't been configured in Pyxis as GA.

The new pipeline will be deployed into separate namespace which will be
restricted only to a service account that can trigger a pipeline.

JIRA: ISV-6546

Signed-off-by: Ales Raszka <[email protected]>
  • Loading branch information
Allda committed Feb 25, 2025
1 parent 39dc9a6 commit 0bc764d
Show file tree
Hide file tree
Showing 12 changed files with 724 additions and 0 deletions.
3 changes: 3 additions & 0 deletions ansible/inventory/group_vars/operator-pipeline-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,6 @@ tekton_pruner_keep: 50
# Settings for importing index imagestreams
certified_operator_index: registry.redhat.io/redhat/certified-operator-index
redhat_marketplace_index: registry.redhat.io/redhat/redhat-marketplace-index

# Settings for the index image bootstrap signing pipeline
index_img_bootstrap_signing_pipeline_registry_auth_path: ../../vaults/common/index-bootstrap-signing-pipeline.json
3 changes: 3 additions & 0 deletions ansible/inventory/group_vars/operator-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ ansible_connection: local
env: unset
oc_namespace: "operator-pipeline-{{ env }}"
oc_signing_namespace: "signing-pipeline-{{ env }}"
oc_index_bootstrap_namespace: "index-bootstrap-{{ env }}"
service_account_name: operator-pipeline-admin
branch: "{{ env }}"
preflight_trigger_environment: preprod
Expand Down Expand Up @@ -51,6 +52,8 @@ kerberos_keytab_community_pending: ../../vaults/common/nonprod-community-operato
index_img_signing_pipeline_private_key_local_path: ../../vaults/{{ env }}/community-operator-signing-pipeline.key
index_img_signing_pipeline_private_cert_local_path: ../../vaults/{{ env }}/community-operator-signing-pipeline.pem

index_img_bootstrap_signing_pipeline_registry_auth_path: ../../vaults/common/nonprod-index-bootstrap-signing-pipeline.json


community_operator_hosted_pipeline_registry_auth_path: ../../vaults/{{ env }}/registry-auth/community-hosted-pipeline.json
community_operator_pipeline_pending_namespace: "community-operator-pipeline-{{ env }}"
Expand Down
9 changes: 9 additions & 0 deletions ansible/roles/operator-pipeline/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,12 @@
## General settings
namespace_state: present # noqa: var-naming[no-role-prefix]
github_webhook_state: present # noqa: var-naming[no-role-prefix]

## Index image signing pipeline settings
index_img_bootstrap_service_accounts:
- index-img-bootstrap-sa

index_img_bootstrap_labels:
app: index-img-bootstrap
suffix: "{{ suffix }}"
env: "{{ env }}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---

- name: Create index image bootstrap signing pipeline cert secret
no_log: true
kubernetes.core.k8s:
state: present
force: true
namespace: "{{ oc_index_bootstrap_namespace }}"
definition:
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: index-img-signing-pipeline-certs
labels: "{{ index_img_bootstrap_labels }}"
data:
index-img-signing-pipeline.key: "{{ lookup('file', index_img_signing_pipeline_private_key_local_path, rstrip=False) | b64encode }}"
index-img-signing-pipeline.pem: "{{ lookup('file', index_img_signing_pipeline_private_cert_local_path, rstrip=False) | b64encode }}"

- name: Create signing pub key secret
no_log: true
tags:
- secrets
kubernetes.core.k8s:
state: present
force: true
namespace: "{{ oc_index_bootstrap_namespace }}"
definition:
apiVersion: v1
kind: Secret
type: opaque
metadata:
name: signing-pub-key
labels: "{{ index_img_bootstrap_labels }}"
data:
sig-key.pub: "{{ lookup('file', signing_pub_key_local_path, rstrip=False) | b64encode }}"

- name: Create registry secret
no_log: true
tags:
- secrets
kubernetes.core.k8s:
state: present
force: true
namespace: "{{ oc_index_bootstrap_namespace }}"
definition:
apiVersion: v1
kind: Secret
type: opaque
metadata:
name: index-img-signing-pipeline-registry-auth
labels: "{{ index_img_bootstrap_labels }}"
data:
config.json: "{{ lookup('file', index_img_bootstrap_signing_pipeline_registry_auth_path, rstrip=False) | b64encode }}"
133 changes: 133 additions & 0 deletions ansible/roles/operator-pipeline/tasks/index-img-bootstrap-signing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
---

- name: Configure signing namespace
tags:
- namespace
kubernetes.core.k8s:
state: "{{ namespace_state }}"
definition:
kind: Namespace
apiVersion: v1
metadata:
name: "{{ oc_index_bootstrap_namespace }}"
annotations:
operator.tekton.dev/prune.keep: "{{ tekton_pruner_keep | int }}"

- name: Create Tekton access role
tags:
- tekton-role
kubernetes.core.k8s:
state: present
apply: true
namespace: "{{ oc_index_bootstrap_namespace }}"
definition: "{{ lookup('template', '../templates/openshift/tekton-access-role.yml') }}"

- name: Create bootstrapping SA
tags:
- signing-sa
kubernetes.core.k8s:
state: present
apply: true
namespace: "{{ oc_index_bootstrap_namespace }}"
definition:
apiVersion: v1
kind: ServiceAccount
metadata:
name: "{{ item }}"
namespace: "{{ oc_index_bootstrap_namespace }}"
labels: "{{ index_img_bootstrap_labels }}"
with_items: "{{ index_img_bootstrap_service_accounts }}"

- name: Create SA token secret
tags:
- signing-sa
kubernetes.core.k8s:
state: present
apply: true
namespace: "{{ oc_index_bootstrap_namespace }}"
definition:
apiVersion: v1
kind: Secret
metadata:
name: "{{ item }}-token"
namespace: "{{ oc_index_bootstrap_namespace }}"
annotations:
kubernetes.io/service-account.name: "{{ item }}"
labels: "{{ index_img_bootstrap_labels }}"
type: kubernetes.io/service-account-token
with_items: "{{ index_img_bootstrap_service_accounts }}"

- name: Grant SA view access to the namespace
tags:
- signing-sa
kubernetes.core.k8s:
state: present
apply: true
namespace: "{{ oc_index_bootstrap_namespace }}"
definition:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: view
namespace: "{{ oc_index_bootstrap_namespace }}"
labels: "{{ index_img_bootstrap_labels }}"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: view
subjects:
- kind: ServiceAccount
name: "{{ item }}"
namespace: "{{ oc_index_bootstrap_namespace }}"
with_items: "{{ index_img_bootstrap_service_accounts }}"

- name: Create Tekton access role binding
tags:
- signing-sa
kubernetes.core.k8s:
state: present
apply: true
namespace: "{{ oc_index_bootstrap_namespace }}"
definition:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: tekton-pipeline-executor-binding
namespace: "{{ oc_index_bootstrap_namespace }}"
labels: "{{ index_img_bootstrap_labels }}"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: tekton-pipeline-executor
subjects:
- kind: ServiceAccount
name: "{{ item}}"
namespace: "{{ oc_index_bootstrap_namespace }}"
with_items: "{{ index_img_bootstrap_service_accounts }}"

- name: Include signing secrets
ansible.builtin.include_tasks: tasks/index-img-bootstrap-signing-secrets.yml

- name: Deploy pipeline tasks
tags:
- tekton-task
kubernetes.core.k8s:
state: present
apply: true
namespace: "{{ oc_index_bootstrap_namespace }}"
definition: "{{ lookup('template', '{{ item }}') }}"
with_items:
- ../templates/openshift/tasks/set-env.yml
- ../templates/openshift/tasks/index-signing-image-check.yml

- name: Deploy signing pipeline
tags:
- tekton-pipeline
- signing
kubernetes.core.k8s:
state: present
apply: true
namespace: "{{ oc_index_bootstrap_namespace }}"
definition: "{{ lookup('template', '{{ item }}') }}"
with_items:
- ../templates/openshift/pipelines/index-img-bootstrap-signing-pipeline.yml
6 changes: 6 additions & 0 deletions ansible/roles/operator-pipeline/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,11 @@
tags:
- signing-pipeline

- name: Import index image bootstrap signing task
ansible.builtin.import_tasks: tasks/index-img-bootstrap-signing.yml
tags:
- signing-pipeline
- bootstrap-signing

- name: Import operator release webhooks
ansible.builtin.import_tasks: tasks/operator-pipeline-webhooks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
---
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: index-img-bootstrap-signing-pipeline
spec:
description: |
This pipeline is used to sign the index image for the certified, marketplace
and community operators after a new OCP version/index is bootstrapped.
The pipeline will fail if the image is already marked as GA in Pyxis.
params:
- name: env
description: Which environment to run in. Can be one of [dev, qa, stage, prod]
default: "dev"

- name: pipeline_image
description: An image of operator-pipeline-images.
default: "quay.io/redhat-isv/operator-pipelines-images:released"

- name: image_pullspec
description: The pullspec for the image to be signed in the format registry/image:tag

- name: requester
description: Name of the user or service account that requested the signing, for auditing purposes

- name: ssl_cert_secret_name
default: index-img-signing-pipeline-certs

- name: ssl_cert_secret_key
default: index-img-signing-pipeline.pem

- name: ssl_key_secret_key
default: index-img-signing-pipeline.key

- name: signing_pub_secret_name
description: The name of the Kubernetes Secret that contains the public key for verifying signatures.
default: signing-pub-key

- name: signing_pub_secret_key
description: The key within the Kubernetes Secret that contains the public key for verifying signatures.
default: sig-key.pub

workspaces:
- name: pipeline

tasks:
- name: set-env
taskRef:
name: set-env
kind: Task
params:
- name: env
value: $(params.env)
- name: access_type
value: "internal"

- name: index-signing-image-check
taskRef:
name: index-signing-image-check
kind: Task
runAfter:
- set-env
params:
- name: pipeline_image
value: "$(params.pipeline_image)"
- name: image_pullspec
value: "$(params.image_pullspec)"
- name: pyxis_env
value: "$(params.env)"

- name: request-signature
taskRef:
resolver: bundles
params:
- name: bundle
value: "quay.io/redhat-isv/tkn-signing-bundle:4692680007"
- name: name
value: request-signature
- name: kind
value: Task
runAfter:
- index-signing-image-check
params:
- name: pipeline_image
value: "$(params.pipeline_image)"
- name: manifest_digest
value: "$(tasks.index-signing-image-check.results.manifest_digests)"
- name: reference
value: "$(tasks.index-signing-image-check.results.docker_references)"
- name: requester
value: "$(params.requester)"
- name: sig_key_id
value: "$(tasks.set-env.results.sig_key_id)"
- name: sig_key_name
value: "$(tasks.set-env.results.sig_key_name)"
- name: umb_ssl_secret_name
value: "$(params.ssl_cert_secret_name)"
- name: umb_ssl_cert_secret_key
value: "$(params.ssl_cert_secret_key)"
- name: umb_ssl_key_secret_key
value: "$(params.ssl_key_secret_key)"
- name: umb_client_name
value: "$(tasks.set-env.results.umb_client_name_signing)"
- name: umb_url
value: "$(tasks.set-env.results.umb_url)"
workspaces:
- name: source
workspace: pipeline
subPath: signing

- name: upload-signature
taskRef:
resolver: bundles
params:
- name: bundle
value: "quay.io/redhat-isv/tkn-signing-bundle:4692680007"
- name: name
value: upload-signature
- name: kind
value: Task
runAfter:
- request-signature
params:
- name: pipeline_image
value: "$(params.pipeline_image)"
- name: signature_data_file
value: "$(tasks.request-signature.results.signature_data_file)"
- name: pyxis_ssl_secret_name
value: "$(params.ssl_cert_secret_name)"
- name: pyxis_ssl_cert_secret_key
value: "$(params.ssl_cert_secret_key)"
- name: pyxis_ssl_key_secret_key
value: "$(params.ssl_key_secret_key)"
- name: pyxis_url
value: "$(tasks.set-env.results.pyxis_url)"
- name: signing_pub_secret_name
value: "$(params.signing_pub_secret_name)"
- name: signing_pub_secret_key
value: "$(params.signing_pub_secret_key)"
workspaces:
- name: source
workspace: pipeline
subPath: signing
Loading

0 comments on commit 0bc764d

Please sign in to comment.