diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 26a6791..a3e68dc 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,14 @@ Quay Container Registry Collection Release Notes .. contents:: Topics +v2.5.2 +====== + +Bugfixes +-------- + +- quay_organization - setting the ``time_machine_expiration`` parameter failed when Quay administrators customize the ``TAG_EXPIRATION_OPTIONS`` option in ``config.yaml``. Fix now allows any value for the ``time_machine_expiration`` parameter. The Quay API might return an error if the given value is not defined in the ``TAG_EXPIRATION_OPTIONS`` option. + v2.5.1 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index af006e1..33ba788 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -293,3 +293,14 @@ releases: fragments: - 19-v2.5.1-summary.yml release_date: '2024-12-14' + 2.5.2: + changes: + bugfixes: + - quay_organization - setting the ``time_machine_expiration`` parameter failed + when Quay administrators customize the ``TAG_EXPIRATION_OPTIONS`` option in + ``config.yaml``. Fix now allows any value for the ``time_machine_expiration`` + parameter. The Quay API might return an error if the given value is not defined + in the ``TAG_EXPIRATION_OPTIONS`` option. + fragments: + - 20-v2.5.2-summary.yml + release_date: '2024-12-23' diff --git a/galaxy.yml b/galaxy.yml index 4695009..d8df37d 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: infra name: quay_configuration -version: 2.5.1 +version: 2.5.2 readme: README.md authors: - Hervé Quatremain diff --git a/plugins/modules/quay_organization.py b/plugins/modules/quay_organization.py index f08add7..c508ba7 100644 --- a/plugins/modules/quay_organization.py +++ b/plugins/modules/quay_organization.py @@ -56,10 +56,16 @@ type: str time_machine_expiration: description: - - The amount of time, after a tag is deleted, that the tag is accessible + - After a tag is deleted, the amount of time in seconds it is kept in time machine before being garbage collected. + - The O(time_machine_expiration) parameter accepts a time unit as a + suffix; C(s) for seconds, C(m) for minutes, C(h) for hours, C(d) for + days, and C(w) for weeks. For example, C(2w) for two weeks. + - Only the expiration times that your Quay administrator declares in + C(config.yaml) with the C(TAG_EXPIRATION_OPTIONS) option are allowed. + The default value for the C(TAG_EXPIRATION_OPTIONS) option is C(0s), + C(1d), C(1w), C(2w), and C(4w). type: str - choices: [0s, 1d, 7d, 14d, 1month] state: description: - If V(absent), then the module deletes the organization. @@ -72,6 +78,9 @@ default: present choices: [absent, present] notes: + - To use the O(time_machine_expiration) parameter, your Quay administrator + must set C(FEATURE_CHANGE_TAG_EXPIRATION) to C(true), which is the default, + in C(config.yaml). - The token that you provide in O(quay_token) must have the "Administer Organization" and "Administer User" permissions. - To rename organizations, the token must also have the "Super User Access" @@ -96,7 +105,7 @@ infra.quay_configuration.quay_organization: name: production email: prodlist@example.com - time_machine_expiration: "7d" + time_machine_expiration: 1w state: present quay_host: https://quay.example.com quay_token: vgfH9zH5q6eV16Con7SvDQYSr0KPYQimMHVehZv7 @@ -125,18 +134,11 @@ def main(): - tm_allowed_values = { - "0s": 0, - "1d": 86400, - "7d": 604800, - "14d": 1209600, - "1month": 2419200, - } argument_spec = dict( name=dict(required=True), new_name=dict(), email=dict(), - time_machine_expiration=dict(choices=list(tm_allowed_values.keys())), + time_machine_expiration=dict(), auto_prune_method=dict( choices=["none", "tags", "date"], removed_at_date="2025-12-01", @@ -200,6 +202,14 @@ def main(): ) auto_prune_value = value + # Verify that the expiration is valid and convert it to an integer (seconds) + # Even though the user might provide a valid value, the API will rejects the + # value if it is not in the TAG_EXPIRATION_OPTIONS array (in config.yaml) + if tm_expiration: + tag_expiration_s = module.str_period_to_second( + "time_machine_expiration", tm_expiration + ) + org_details = module.get_organization(name) new_org_details = module.get_organization(new_name) if new_name else None @@ -286,7 +296,7 @@ def main(): # Prepare the data that gets set for update new_fields = {} if tm_expiration: - new_fields["tag_expiration_s"] = tm_allowed_values[tm_expiration] + new_fields["tag_expiration_s"] = tag_expiration_s if email: new_fields["email"] = email diff --git a/tests/docker-compose.yml b/tests/docker-compose.yml index 74216be..5ca1055 100644 --- a/tests/docker-compose.yml +++ b/tests/docker-compose.yml @@ -26,7 +26,7 @@ services: - "8089:8080" quay: - image: quay.io/projectquay/quay:v3.13.1 + image: quay.io/projectquay/quay:3.13.2 volumes: - "./quay-config:/conf/stack:Z" - "./quay-delay.sh:/quay-registry/conf/init/a-delay.sh:ro" diff --git a/tests/integration/targets/quay_organization/tasks/main.yml b/tests/integration/targets/quay_organization/tasks/main.yml index 45183b2..9d3ea7f 100644 --- a/tests/integration/targets/quay_organization/tasks/main.yml +++ b/tests/integration/targets/quay_organization/tasks/main.yml @@ -1,4 +1,20 @@ --- +- name: ERROR EXPECTED Wrong time machine expiration + infra.quay_configuration.quay_organization: + name: testansible1 + time_machine_expiration: 12345s + state: present + quay_host: "{{ quay_url }}" + quay_token: "{{ quay_token }}" + validate_certs: false + ignore_errors: true + register: result + +- name: Ensure that the task failed (wrong time machine expiration) + ansible.builtin.assert: + that: result['failed'] + fail_msg: The preceding task should have failed (wrong expiration) + - name: Ensure organization testansible1 exists infra.quay_configuration.quay_organization: name: testansible1 @@ -7,12 +23,18 @@ quay_host: "{{ quay_url }}" quay_token: "{{ quay_token }}" validate_certs: false + register: result + +- name: Ensure that the task did change something + ansible.builtin.assert: + that: result['changed'] + fail_msg: The preceding task should have changed something - name: Ensure organization testansible2 exists infra.quay_configuration.quay_organization: name: testansible2 email: testansible2@example.com - time_machine_expiration: "7d" + time_machine_expiration: 7d quay_host: "{{ quay_url }}" quay_token: "{{ quay_token }}" validate_certs: false @@ -43,7 +65,7 @@ - name: Ensure organization testansible3 has a new time machine expiration infra.quay_configuration.quay_organization: name: testansible3 - time_machine_expiration: "1d" + time_machine_expiration: "1 day" quay_host: "{{ quay_url }}" quay_token: "{{ quay_token }}" validate_certs: false @@ -51,7 +73,7 @@ - name: Ensure organization testansible3 has the same expiration (no change) infra.quay_configuration.quay_organization: name: testansible3 - time_machine_expiration: "1d" + time_machine_expiration: 1d auto_prune_method: none quay_host: "{{ quay_url }}" quay_token: "{{ quay_token }}" @@ -69,7 +91,7 @@ email: testansible4@example.com new_name: testansible4 state: present - time_machine_expiration: "1month" + time_machine_expiration: "4w" quay_host: "{{ quay_url }}" quay_token: "{{ quay_token }}" validate_certs: false @@ -79,7 +101,7 @@ name: testansible5 email: testansible5@example.com state: present - time_machine_expiration: "1month" + time_machine_expiration: "4weeks" auto_prune_method: tags auto_prune_value: 30 quay_host: "{{ quay_url }}" @@ -116,7 +138,7 @@ infra.quay_configuration.quay_organization: name: testansible5 state: present - time_machine_expiration: "1month" + time_machine_expiration: "4 w" quay_host: "{{ quay_url }}" quay_token: "{{ quay_token }}" validate_certs: false