Skip to content

Commit c0c1cc7

Browse files
committed
ISV-5645: Signing pipeline for image bootstrapping
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]>
1 parent 00b28bd commit c0c1cc7

12 files changed

+724
-0
lines changed

ansible/inventory/group_vars/operator-pipeline-prod.yml

+3
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,6 @@ tekton_pruner_keep: 50
3030
# Settings for importing index imagestreams
3131
certified_operator_index: registry.redhat.io/redhat/certified-operator-index
3232
redhat_marketplace_index: registry.redhat.io/redhat/redhat-marketplace-index
33+
34+
# Settings for the index image bootstrap signing pipeline
35+
index_img_bootstrap_signing_pipeline_registry_auth_path: ../../vaults/common/index-bootstrap-signing-pipeline.json

ansible/inventory/group_vars/operator-pipeline.yml

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ ansible_connection: local
44
env: unset
55
oc_namespace: "operator-pipeline-{{ env }}"
66
oc_signing_namespace: "signing-pipeline-{{ env }}"
7+
oc_index_bootstrap_namespace: "index-bootstrap-{{ env }}"
78
service_account_name: operator-pipeline-admin
89
branch: "{{ env }}"
910
preflight_trigger_environment: preprod
@@ -51,6 +52,8 @@ kerberos_keytab_community_pending: ../../vaults/common/nonprod-community-operato
5152
index_img_signing_pipeline_private_key_local_path: ../../vaults/{{ env }}/community-operator-signing-pipeline.key
5253
index_img_signing_pipeline_private_cert_local_path: ../../vaults/{{ env }}/community-operator-signing-pipeline.pem
5354

55+
index_img_bootstrap_signing_pipeline_registry_auth_path: ../../vaults/common/nonprod-index-bootstrap-signing-pipeline.json
56+
5457

5558
community_operator_hosted_pipeline_registry_auth_path: ../../vaults/{{ env }}/registry-auth/community-hosted-pipeline.json
5659
community_operator_pipeline_pending_namespace: "community-operator-pipeline-{{ env }}"

ansible/roles/operator-pipeline/defaults/main.yml

+9
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,12 @@
44
## General settings
55
namespace_state: present # noqa: var-naming[no-role-prefix]
66
github_webhook_state: present # noqa: var-naming[no-role-prefix]
7+
8+
## Index image signing pipeline settings
9+
index_img_bootstrap_service_accounts:
10+
- index-img-bootstrap-sa
11+
12+
index_img_bootstrap_labels:
13+
app: index-img-bootstrap
14+
suffix: "{{ suffix }}"
15+
env: "{{ env }}"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
3+
- name: Create index image bootstrap signing pipeline cert secret
4+
no_log: true
5+
kubernetes.core.k8s:
6+
state: present
7+
force: true
8+
namespace: "{{ oc_index_bootstrap_namespace }}"
9+
definition:
10+
apiVersion: v1
11+
kind: Secret
12+
type: Opaque
13+
metadata:
14+
name: index-img-signing-pipeline-certs
15+
labels: "{{ index_img_bootstrap_labels }}"
16+
data:
17+
index-img-signing-pipeline.key: "{{ lookup('file', index_img_signing_pipeline_private_key_local_path, rstrip=False) | b64encode }}"
18+
index-img-signing-pipeline.pem: "{{ lookup('file', index_img_signing_pipeline_private_cert_local_path, rstrip=False) | b64encode }}"
19+
20+
- name: Create signing pub key secret
21+
no_log: true
22+
tags:
23+
- secrets
24+
kubernetes.core.k8s:
25+
state: present
26+
force: true
27+
namespace: "{{ oc_index_bootstrap_namespace }}"
28+
definition:
29+
apiVersion: v1
30+
kind: Secret
31+
type: opaque
32+
metadata:
33+
name: signing-pub-key
34+
labels: "{{ index_img_bootstrap_labels }}"
35+
data:
36+
sig-key.pub: "{{ lookup('file', signing_pub_key_local_path, rstrip=False) | b64encode }}"
37+
38+
- name: Create registry secret
39+
no_log: true
40+
tags:
41+
- secrets
42+
kubernetes.core.k8s:
43+
state: present
44+
force: true
45+
namespace: "{{ oc_index_bootstrap_namespace }}"
46+
definition:
47+
apiVersion: v1
48+
kind: Secret
49+
type: opaque
50+
metadata:
51+
name: index-img-signing-pipeline-registry-auth
52+
labels: "{{ index_img_bootstrap_labels }}"
53+
data:
54+
config.json: "{{ lookup('file', index_img_bootstrap_signing_pipeline_registry_auth_path, rstrip=False) | b64encode }}"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
---
2+
3+
- name: Configure signing namespace
4+
tags:
5+
- namespace
6+
kubernetes.core.k8s:
7+
state: "{{ namespace_state }}"
8+
definition:
9+
kind: Namespace
10+
apiVersion: v1
11+
metadata:
12+
name: "{{ oc_index_bootstrap_namespace }}"
13+
annotations:
14+
operator.tekton.dev/prune.keep: "{{ tekton_pruner_keep | int }}"
15+
16+
- name: Create Tekton access role
17+
tags:
18+
- tekton-role
19+
kubernetes.core.k8s:
20+
state: present
21+
apply: true
22+
namespace: "{{ oc_index_bootstrap_namespace }}"
23+
definition: "{{ lookup('template', '../templates/openshift/tekton-access-role.yml') }}"
24+
25+
- name: Create bootstrapping SA
26+
tags:
27+
- signing-sa
28+
kubernetes.core.k8s:
29+
state: present
30+
apply: true
31+
namespace: "{{ oc_index_bootstrap_namespace }}"
32+
definition:
33+
apiVersion: v1
34+
kind: ServiceAccount
35+
metadata:
36+
name: "{{ item }}"
37+
namespace: "{{ oc_index_bootstrap_namespace }}"
38+
labels: "{{ index_img_bootstrap_labels }}"
39+
with_items: "{{ index_img_bootstrap_service_accounts }}"
40+
41+
- name: Create SA token secret
42+
tags:
43+
- signing-sa
44+
kubernetes.core.k8s:
45+
state: present
46+
apply: true
47+
namespace: "{{ oc_index_bootstrap_namespace }}"
48+
definition:
49+
apiVersion: v1
50+
kind: Secret
51+
metadata:
52+
name: "{{ item }}-token"
53+
namespace: "{{ oc_index_bootstrap_namespace }}"
54+
annotations:
55+
kubernetes.io/service-account.name: "{{ item }}"
56+
labels: "{{ index_img_bootstrap_labels }}"
57+
type: kubernetes.io/service-account-token
58+
with_items: "{{ index_img_bootstrap_service_accounts }}"
59+
60+
- name: Grant SA view access to the namespace
61+
tags:
62+
- signing-sa
63+
kubernetes.core.k8s:
64+
state: present
65+
apply: true
66+
namespace: "{{ oc_index_bootstrap_namespace }}"
67+
definition:
68+
apiVersion: rbac.authorization.k8s.io/v1
69+
kind: RoleBinding
70+
metadata:
71+
name: view
72+
namespace: "{{ oc_index_bootstrap_namespace }}"
73+
labels: "{{ index_img_bootstrap_labels }}"
74+
roleRef:
75+
apiGroup: rbac.authorization.k8s.io
76+
kind: ClusterRole
77+
name: view
78+
subjects:
79+
- kind: ServiceAccount
80+
name: "{{ item }}"
81+
namespace: "{{ oc_index_bootstrap_namespace }}"
82+
with_items: "{{ index_img_bootstrap_service_accounts }}"
83+
84+
- name: Create Tekton access role binding
85+
tags:
86+
- signing-sa
87+
kubernetes.core.k8s:
88+
state: present
89+
apply: true
90+
namespace: "{{ oc_index_bootstrap_namespace }}"
91+
definition:
92+
apiVersion: rbac.authorization.k8s.io/v1
93+
kind: RoleBinding
94+
metadata:
95+
name: tekton-pipeline-executor-binding
96+
namespace: "{{ oc_index_bootstrap_namespace }}"
97+
labels: "{{ index_img_bootstrap_labels }}"
98+
roleRef:
99+
apiGroup: rbac.authorization.k8s.io
100+
kind: Role
101+
name: tekton-pipeline-executor
102+
subjects:
103+
- kind: ServiceAccount
104+
name: "{{ item}}"
105+
namespace: "{{ oc_index_bootstrap_namespace }}"
106+
with_items: "{{ index_img_bootstrap_service_accounts }}"
107+
108+
- name: Include signing secrets
109+
ansible.builtin.include_tasks: tasks/index-img-bootstrap-signing-secrets.yml
110+
111+
- name: Deploy pipeline tasks
112+
tags:
113+
- tekton-task
114+
kubernetes.core.k8s:
115+
state: present
116+
apply: true
117+
namespace: "{{ oc_index_bootstrap_namespace }}"
118+
definition: "{{ lookup('template', '{{ item }}') }}"
119+
with_items:
120+
- ../templates/openshift/tasks/set-env.yml
121+
- ../templates/openshift/tasks/index-signing-image-check.yml
122+
123+
- name: Deploy signing pipeline
124+
tags:
125+
- tekton-pipeline
126+
- signing
127+
kubernetes.core.k8s:
128+
state: present
129+
apply: true
130+
namespace: "{{ oc_index_bootstrap_namespace }}"
131+
definition: "{{ lookup('template', '{{ item }}') }}"
132+
with_items:
133+
- ../templates/openshift/pipelines/index-img-bootstrap-signing-pipeline.yml

ansible/roles/operator-pipeline/tasks/main.yml

+6
Original file line numberDiff line numberDiff line change
@@ -74,5 +74,11 @@
7474
tags:
7575
- signing-pipeline
7676

77+
- name: Import index image bootstrap signing task
78+
ansible.builtin.import_tasks: tasks/index-img-bootstrap-signing.yml
79+
tags:
80+
- signing-pipeline
81+
- bootstrap-signing
82+
7783
- name: Import operator release webhooks
7884
ansible.builtin.import_tasks: tasks/operator-pipeline-webhooks.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
---
2+
apiVersion: tekton.dev/v1
3+
kind: Pipeline
4+
metadata:
5+
name: index-img-bootstrap-signing-pipeline
6+
spec:
7+
description: |
8+
This pipeline is used to sign the index image for the certified, marketplace
9+
and community operators after a new OCP version/index is bootstrapped.
10+
11+
The pipeline will fail if the image is already marked as GA in Pyxis.
12+
13+
params:
14+
- name: env
15+
description: Which environment to run in. Can be one of [dev, qa, stage, prod]
16+
default: "dev"
17+
18+
- name: pipeline_image
19+
description: An image of operator-pipeline-images.
20+
default: "quay.io/redhat-isv/operator-pipelines-images:released"
21+
22+
- name: image_pullspec
23+
description: The pullspec for the image to be signed in the format registry/image:tag
24+
25+
- name: requester
26+
description: Name of the user or service account that requested the signing, for auditing purposes
27+
28+
- name: ssl_cert_secret_name
29+
default: index-img-signing-pipeline-certs
30+
31+
- name: ssl_cert_secret_key
32+
default: index-img-signing-pipeline.pem
33+
34+
- name: ssl_key_secret_key
35+
default: index-img-signing-pipeline.key
36+
37+
- name: signing_pub_secret_name
38+
description: The name of the Kubernetes Secret that contains the public key for verifying signatures.
39+
default: signing-pub-key
40+
41+
- name: signing_pub_secret_key
42+
description: The key within the Kubernetes Secret that contains the public key for verifying signatures.
43+
default: sig-key.pub
44+
45+
workspaces:
46+
- name: pipeline
47+
48+
tasks:
49+
- name: set-env
50+
taskRef:
51+
name: set-env
52+
kind: Task
53+
params:
54+
- name: env
55+
value: $(params.env)
56+
- name: access_type
57+
value: "internal"
58+
59+
- name: index-signing-image-check
60+
taskRef:
61+
name: index-signing-image-check
62+
kind: Task
63+
runAfter:
64+
- set-env
65+
params:
66+
- name: pipeline_image
67+
value: "$(params.pipeline_image)"
68+
- name: image_pullspec
69+
value: "$(params.image_pullspec)"
70+
- name: pyxis_env
71+
value: "$(params.env)"
72+
73+
- name: request-signature
74+
taskRef:
75+
resolver: bundles
76+
params:
77+
- name: bundle
78+
value: "quay.io/redhat-isv/tkn-signing-bundle:4692680007"
79+
- name: name
80+
value: request-signature
81+
- name: kind
82+
value: Task
83+
runAfter:
84+
- index-signing-image-check
85+
params:
86+
- name: pipeline_image
87+
value: "$(params.pipeline_image)"
88+
- name: manifest_digest
89+
value: "$(tasks.index-signing-image-check.results.manifest_digests)"
90+
- name: reference
91+
value: "$(tasks.index-signing-image-check.results.docker_references)"
92+
- name: requester
93+
value: "$(params.requester)"
94+
- name: sig_key_id
95+
value: "$(tasks.set-env.results.sig_key_id)"
96+
- name: sig_key_name
97+
value: "$(tasks.set-env.results.sig_key_name)"
98+
- name: umb_ssl_secret_name
99+
value: "$(params.ssl_cert_secret_name)"
100+
- name: umb_ssl_cert_secret_key
101+
value: "$(params.ssl_cert_secret_key)"
102+
- name: umb_ssl_key_secret_key
103+
value: "$(params.ssl_key_secret_key)"
104+
- name: umb_client_name
105+
value: "$(tasks.set-env.results.umb_client_name_signing)"
106+
- name: umb_url
107+
value: "$(tasks.set-env.results.umb_url)"
108+
workspaces:
109+
- name: source
110+
workspace: pipeline
111+
subPath: signing
112+
113+
- name: upload-signature
114+
taskRef:
115+
resolver: bundles
116+
params:
117+
- name: bundle
118+
value: "quay.io/redhat-isv/tkn-signing-bundle:4692680007"
119+
- name: name
120+
value: upload-signature
121+
- name: kind
122+
value: Task
123+
runAfter:
124+
- request-signature
125+
params:
126+
- name: pipeline_image
127+
value: "$(params.pipeline_image)"
128+
- name: signature_data_file
129+
value: "$(tasks.request-signature.results.signature_data_file)"
130+
- name: pyxis_ssl_secret_name
131+
value: "$(params.ssl_cert_secret_name)"
132+
- name: pyxis_ssl_cert_secret_key
133+
value: "$(params.ssl_cert_secret_key)"
134+
- name: pyxis_ssl_key_secret_key
135+
value: "$(params.ssl_key_secret_key)"
136+
- name: pyxis_url
137+
value: "$(tasks.set-env.results.pyxis_url)"
138+
- name: signing_pub_secret_name
139+
value: "$(params.signing_pub_secret_name)"
140+
- name: signing_pub_secret_key
141+
value: "$(params.signing_pub_secret_key)"
142+
workspaces:
143+
- name: source
144+
workspace: pipeline
145+
subPath: signing

0 commit comments

Comments
 (0)