Add ensure-quay-repo role

This adds a new role that can be used to ensure a quay repo exists
before publishing to it. This is particularly useful for creating public
repos in quay as simply pushing to a repo with quay will create a
private repo by default.

Change-Id: I979f1b9b64f901bb8d54b8991bb9142b18b6330f
This commit is contained in:
Clark Boylan 2023-03-17 12:29:36 -07:00
parent 0354a8c52d
commit 18b32703ed
4 changed files with 127 additions and 0 deletions

View File

@ -10,6 +10,7 @@ Container Roles
.. zuul:autorole:: ensure-openshift
.. zuul:autorole:: ensure-podman
.. zuul:autorole:: ensure-skopeo
.. zuul:autorole:: ensure-quay-repo
.. zuul:autorole:: pause-buildset-registry
.. zuul:autorole:: promote-container-image
.. zuul:autorole:: promote-docker-image

View File

@ -0,0 +1,52 @@
This role primarily exists to create a new public repository in quay.
This role can be used to create private repos as well, but repos are
created by default in quay if you simply push to them.
Users of this role will need to generate an application token with
`create repository` permissions. Additional permissions are not
necessary.
When invoking this role you should set no_log: true on the
`include_role` task to prevent disclosure of your token.
** Role Variables **
.. zuul:rolevar:: container_registry_credentials
:type: dict
Required. This is expected to be a Zuul secret in dictionary form.
For convenience this is in the same format as the
``container_registry_credentials`` variable used by the other container
roles. Specify an ``api_token`` which is issued from an application
assigned to an organisation. See `<https://docs.quay.io/api/>`__
Example:
.. code-block:: yaml
container_registry_credentials:
quay.io:
api_token: 'abcd1234'
.. zuul:rolevar:: container_images
:type: list
Required. A list of dictionaries. This provides info about the image
repositories to be created in a quay registry. For convenience this
is in the same format as the ``container_images`` variable used by other
container roles. Specify a ``registry`` (this should match up with your
credentials to locate the api token), ``namespace``, ``repo_shortname``,
``repo_description``, ``visibility``, and ``api_url`` attributes.
By default visibility will be ``public`` and ``api_url`` will be
``https://{{ registry }}``.
Example:
.. code-block:: yaml
container_images:
- registry: quay.io
namespace: myquayorg
repo_shortname: myimage
repo_description: The best container image

View File

@ -0,0 +1,49 @@
- name: Set quay_root_url
set_fact:
quay_root_url: "https://{{ zj_image.registry }}"
when: zj_image.api_url is not defined
- name: Alias api_url
set_fact:
quay_root_url: "{{ zj_image.api_url }}"
when: zj_image.api_url is defined
- name: Set quay_repo_visibility
set_fact:
quay_repo_visibility: "public"
when: zj_image.visibility is not defined
- name: Alias visibility
set_fact:
quay_repo_visibility: "{{ zj_image.visibility }}"
when: zj_image.visibility is defined
- name: Create the repo in quay
no_log: true
uri:
url: "{{ quay_root_url }}/api/v1/repository"
method: POST
body_format: json
body:
namespace: "{{ zj_image.namespace }}"
repository: "{{ zj_image.repo_shortname}}"
description: "{{ zj_image.repo_description }}"
visibility: "{{ quay_repo_visibility }}"
headers:
Content-Type: application/json
Authorization: "Bearer {{ container_registry_credentials[zj_image.registry].api_token }}"
status_code:
- 201
# 400 is returned when the repo already exists.
# We double check this below.
- 400
register: quay_repo_create
delay: 5
retries: 3
- name: Fail if repo doesn't exist and we got a 400 status code
when:
- quay_repo_create.status == 400
- "'error_message' not in quay_repo_create.json or ('error_message' in quay_repo_create.json and quay_repo_create.json.error_message != 'Repository already exists')"
fail:
msg: "Could not create {{ quay_root_url }}/{{ zj_image.namespace }}/{{ zj_image.repo_shortname }}"

View File

@ -0,0 +1,25 @@
- name: Verify repository names
when: |
container_registry_credentials is defined
and zj_image.registry not in container_registry_credentials
loop: "{{ container_images }}"
loop_control:
loop_var: zj_image
fail:
msg: "{{ zj_image.registry }} credentials not found"
- name: Verify repository permission
when: |
container_registry_credentials[zj_image.registry].repository is defined and
not zj_image.repository | regex_search(container_registry_credentials[zj_image.registry].repository)
loop: "{{ container_images }}"
loop_control:
loop_var: zj_image
fail:
msg: "{{ zj_image.repository }} not permitted by {{ container_registry_credentials[zj_image.registry].repository }}"
- name: Create repository in quay registry
loop: "{{ container_images }}"
loop_control:
loop_var: zj_image
include_tasks: create.yaml