From b8d97afce153a758bb18147c541d79ba38cdabd7 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 23:23:28 +0100 Subject: [PATCH] acme_certificate tests: fix tests for listing orders (#992) (#993) * All orders created with the ec384 account have deactivated authz. According to the spec, these orders are invalid and should not be listed when listing orders. With the latest Pebble version, which handles this correctly, this causes the current tests to fail, since they expect orders to be present. * Orders cannot be deactivated, they are invalid. * Make compatible with newest Pebble. (cherry picked from commit 670d0b4dcfa2163a9b75bdce52a7e8a789e7d25f) Co-authored-by: Felix Fontein --- .../targets/acme_certificate/tasks/impl.yml | 8 +- .../tests/validate.yml | 6 +- .../acme_certificate_order/tasks/impl.yml | 150 ++++++++++-------- 3 files changed, 93 insertions(+), 71 deletions(-) diff --git a/tests/integration/targets/acme_certificate/tasks/impl.yml b/tests/integration/targets/acme_certificate/tasks/impl.yml index ffd168e5..c5c41ecc 100644 --- a/tests/integration/targets/acme_certificate/tasks/impl.yml +++ b/tests/integration/targets/acme_certificate/tasks/impl.yml @@ -140,7 +140,7 @@ account_key_content: "{{ slurp_account_key.content | b64decode }}" challenge: dns-01 modify_account: false - deactivate_authzs: false + deactivate_authzs: true force: false remaining_days: 1 terms_agreed: false @@ -167,7 +167,7 @@ account_key: account-rsa challenge: http-01 modify_account: false - deactivate_authzs: true + deactivate_authzs: false force: true remaining_days: 1 terms_agreed: false @@ -492,7 +492,7 @@ - name: Retrieve orders as URL list (2/2) community.crypto.acme_account_info: select_crypto_backend: "{{ select_crypto_backend }}" - account_key_src: "{{ remote_tmp_dir }}/account-ec384.pem" + account_key_src: "{{ remote_tmp_dir }}/account-rsa.pem" acme_version: 2 acme_directory: "{{ acme_directory_url }}" validate_certs: false @@ -510,7 +510,7 @@ - name: Retrieve orders as object list (2/2) community.crypto.acme_account_info: select_crypto_backend: "{{ select_crypto_backend }}" - account_key_src: "{{ remote_tmp_dir }}/account-ec384.pem" + account_key_src: "{{ remote_tmp_dir }}/account-rsa.pem" acme_version: 2 acme_directory: "{{ acme_directory_url }}" validate_certs: false diff --git a/tests/integration/targets/acme_certificate_deactivate_authz/tests/validate.yml b/tests/integration/targets/acme_certificate_deactivate_authz/tests/validate.yml index 96ca27d6..62135341 100644 --- a/tests/integration/targets/acme_certificate_deactivate_authz/tests/validate.yml +++ b/tests/integration/targets/acme_certificate_deactivate_authz/tests/validate.yml @@ -10,8 +10,8 @@ - deactivate_1 is changed - order_2.output_json.status == 'pending' - deactivate_2 is changed - - order_3.output_json.status == 'deactivated' + - order_3.output_json.status in ('deactivated', 'invalid') - deactivate_3 is not changed - - order_4.output_json.status == 'deactivated' + - order_4.output_json.status in ('deactivated', 'invalid') - deactivate_4 is not changed - - order_5.output_json.status == 'deactivated' + - order_5.output_json.status in ('deactivated', 'invalid') diff --git a/tests/integration/targets/acme_certificate_order/tasks/impl.yml b/tests/integration/targets/acme_certificate_order/tasks/impl.yml index 298d9b56..afb22849 100644 --- a/tests/integration/targets/acme_certificate_order/tasks/impl.yml +++ b/tests/integration/targets/acme_certificate_order/tasks/impl.yml @@ -347,7 +347,7 @@ - order_info_4.order.authorizations | length == 1 - order_info_4.order.authorizations[0] == order_info_4.authorizations_by_identifier['dns:' ~ domain_name].uri - "'certificate' in order_info_4.order" - - order_info_4.order.status == 'deactivated' + - order_info_4.order.status in ('deactivated', 'invalid') - order_info_4.order_uri == order_1.order_uri - order_info_4.account_uri == account.account_uri @@ -466,7 +466,7 @@ replacement_order_2.msg.startswith( 'Failed to start new order for ' ~ acme_directory_url - ~ '/order-plz with status 409 Conflict. Error urn:ietf:params:acme:error:malformed:' + ~ '/order-plz with status 409 Conflict. Error urn:ietf:params:acme:error:alreadyReplaced:' ) - name: "({{ select_crypto_backend }}) Create replacement order 3 with error handling" @@ -512,7 +512,7 @@ - replacement_order_3.account_uri == account.account_uri - replacement_order_3.order_uri not in [order_1.order_uri, replacement_order_1.order_uri] - >- - ('Stop passing `replaces=' ~ cert_info.cert_id ~ '` due to error 409 urn:ietf:params:acme:error:malformed when creating ACME order') in replacement_order_3.warnings + ('Stop passing `replaces=' ~ cert_info.cert_id ~ '` due to error 409 urn:ietf:params:acme:error:alreadyReplaced when creating ACME order') in replacement_order_3.warnings - name: "({{ select_crypto_backend }}) Check replacement order 3 information" ansible.builtin.assert: @@ -609,6 +609,8 @@ - replacement_order_4.msg.startswith('Failed to start new order for https://' ~ acme_host) - >- ' with status 409 Conflict. Error urn:ietf:params:acme:error:malformed: ' in replacement_order_4.msg + or + ' with status 409 Conflict. Error urn:ietf:params:acme:error:alreadyReplaced: ' in replacement_order_4.msg - name: "({{ select_crypto_backend }}) Create replacement order 5 with error handling" community.crypto.acme_certificate_order_create: @@ -621,73 +623,93 @@ replaces_cert_id: "{{ cert_info.cert_id }}" order_creation_error_strategy: retry_without_replaces_cert_id register: replacement_order_5 + ignore_errors: true - - name: "({{ select_crypto_backend }}) Get replacement order 5 information" - community.crypto.acme_certificate_order_info: - acme_directory: "{{ acme_directory_url }}" - acme_version: 2 - validate_certs: false - account_key_src: "{{ remote_tmp_dir }}/accountkey.pem" - select_crypto_backend: "{{ select_crypto_backend }}" - order_uri: "{{ replacement_order_5.order_uri }}" - register: order_info_7 - - - name: "({{ select_crypto_backend }}) Check replacement order 5" + # Only the latest Pebble returns the correct error message, which makes the above fail + - name: "({{ select_crypto_backend }}) Check that replacement order 5 worked" + when: false + # TODO: use the following once Pebble is updated + # when: ansible_version.full is version('2.21', '>=') ansible.builtin.assert: that: - - replacement_order_5 is changed - - replacement_order_5.order_uri.startswith('https://' ~ acme_host ~ ':14000/') - - replacement_order_5.challenge_data | length == 1 - - replacement_order_5.challenge_data[0].identifier_type == 'dns' - - replacement_order_5.challenge_data[0].identifier == domain_name - - replacement_order_5.challenge_data[0].challenges | length >= 2 - - "'http-01' in replacement_order_5.challenge_data[0].challenges" - - "'dns-01' in replacement_order_5.challenge_data[0].challenges" - - replacement_order_5.challenge_data[0].challenges['http-01'].resource.startswith('.well-known/acme-challenge/') - - replacement_order_5.challenge_data[0].challenges['http-01'].resource_value is string - - replacement_order_5.challenge_data[0].challenges['dns-01'].record == '_acme-challenge.' ~ domain_name - - replacement_order_5.challenge_data[0].challenges['dns-01'].resource == '_acme-challenge' - - replacement_order_5.challenge_data[0].challenges['dns-01'].resource_value is string - - replacement_order_5.challenge_data_dns | length == 1 - - replacement_order_5.challenge_data_dns['_acme-challenge.' ~ domain_name] | length == 1 - - replacement_order_5.account_uri == account.account_uri - - replacement_order_5.order_uri not in [order_1.order_uri, replacement_order_1.order_uri, replacement_order_3.order_uri | default('')] + - replacement_order_5 is failed + - replacement_order_5.msg.startswith('Failed to start new order for https://' ~ acme_host) - >- - ('Stop passing `replaces=' ~ cert_info.cert_id ~ '` due to error 409 urn:ietf:params:acme:error:malformed when creating ACME order') in replacement_order_5.warnings + ' with status 409 Conflict. Error urn:ietf:params:acme:error:alreadyReplaced: ' in replacement_order_5.msg - - name: "({{ select_crypto_backend }}) Check replacement order 5 information" - ansible.builtin.assert: - that: - - order_info_7 is not changed - - order_info_7.authorizations_by_identifier | length == 1 - - order_info_7.authorizations_by_identifier['dns:' ~ domain_name].identifier.type == 'dns' - - order_info_7.authorizations_by_identifier['dns:' ~ domain_name].identifier.value == domain_name - - order_info_7.authorizations_by_identifier['dns:' ~ domain_name].status == 'pending' - - (order_info_7.authorizations_by_identifier['dns:' ~ domain_name].challenges | selectattr('type', 'equalto', 'http-01') | first).status == 'pending' - - (order_info_7.authorizations_by_identifier['dns:' ~ domain_name].challenges | selectattr('type', 'equalto', 'dns-01') | first).status == 'pending' - - order_info_7.authorizations_by_status['deactivated'] | length == 0 - - order_info_7.authorizations_by_status['expired'] | length == 0 - - order_info_7.authorizations_by_status['invalid'] | length == 0 - - order_info_7.authorizations_by_status['pending'] | length == 1 - - order_info_7.authorizations_by_status['pending'][0] == 'dns:' ~ domain_name - - order_info_7.authorizations_by_status['revoked'] | length == 0 - - order_info_7.authorizations_by_status['valid'] | length == 0 - - order_info_7.order.authorizations | length == 1 - - order_info_7.order.authorizations[0] == order_info_7.authorizations_by_identifier['dns:' ~ domain_name].uri - - "'certificate' not in order_info_7.order" - - order_info_7.order.status == 'pending' - - order_info_7.order.replaces is not defined - - order_info_7.order_uri == replacement_order_5.order_uri - - order_info_7.account_uri == account.account_uri + - when: ansible_version.full is version('2.21', '<') + block: + - name: "({{ select_crypto_backend }}) Check that replacement order 5 worked" + ansible.builtin.assert: + that: + - replacement_order_5 is success - - name: "({{ select_crypto_backend }}) Deactivate authzs for replacement order 5" - community.crypto.acme_certificate_deactivate_authz: - acme_directory: "{{ acme_directory_url }}" - acme_version: 2 - validate_certs: false - account_key_src: "{{ remote_tmp_dir }}/accountkey.pem" - select_crypto_backend: "{{ select_crypto_backend }}" - order_uri: "{{ replacement_order_5.order_uri }}" + - name: "({{ select_crypto_backend }}) Get replacement order 5 information" + community.crypto.acme_certificate_order_info: + acme_directory: "{{ acme_directory_url }}" + acme_version: 2 + validate_certs: false + account_key_src: "{{ remote_tmp_dir }}/accountkey.pem" + select_crypto_backend: "{{ select_crypto_backend }}" + order_uri: "{{ replacement_order_5.order_uri }}" + register: order_info_7 + + - name: "({{ select_crypto_backend }}) Check replacement order 5" + ansible.builtin.assert: + that: + - replacement_order_5 is changed + - replacement_order_5.order_uri.startswith('https://' ~ acme_host ~ ':14000/') + - replacement_order_5.challenge_data | length == 1 + - replacement_order_5.challenge_data[0].identifier_type == 'dns' + - replacement_order_5.challenge_data[0].identifier == domain_name + - replacement_order_5.challenge_data[0].challenges | length >= 2 + - "'http-01' in replacement_order_5.challenge_data[0].challenges" + - "'dns-01' in replacement_order_5.challenge_data[0].challenges" + - replacement_order_5.challenge_data[0].challenges['http-01'].resource.startswith('.well-known/acme-challenge/') + - replacement_order_5.challenge_data[0].challenges['http-01'].resource_value is string + - replacement_order_5.challenge_data[0].challenges['dns-01'].record == '_acme-challenge.' ~ domain_name + - replacement_order_5.challenge_data[0].challenges['dns-01'].resource == '_acme-challenge' + - replacement_order_5.challenge_data[0].challenges['dns-01'].resource_value is string + - replacement_order_5.challenge_data_dns | length == 1 + - replacement_order_5.challenge_data_dns['_acme-challenge.' ~ domain_name] | length == 1 + - replacement_order_5.account_uri == account.account_uri + - replacement_order_5.order_uri not in [order_1.order_uri, replacement_order_1.order_uri, replacement_order_3.order_uri | default('')] + - >- + ('Stop passing `replaces=' ~ cert_info.cert_id ~ '` due to error 409 urn:ietf:params:acme:error:malformed when creating ACME order') in replacement_order_5.warnings + + - name: "({{ select_crypto_backend }}) Check replacement order 5 information" + ansible.builtin.assert: + that: + - order_info_7 is not changed + - order_info_7.authorizations_by_identifier | length == 1 + - order_info_7.authorizations_by_identifier['dns:' ~ domain_name].identifier.type == 'dns' + - order_info_7.authorizations_by_identifier['dns:' ~ domain_name].identifier.value == domain_name + - order_info_7.authorizations_by_identifier['dns:' ~ domain_name].status == 'pending' + - (order_info_7.authorizations_by_identifier['dns:' ~ domain_name].challenges | selectattr('type', 'equalto', 'http-01') | first).status == 'pending' + - (order_info_7.authorizations_by_identifier['dns:' ~ domain_name].challenges | selectattr('type', 'equalto', 'dns-01') | first).status == 'pending' + - order_info_7.authorizations_by_status['deactivated'] | length == 0 + - order_info_7.authorizations_by_status['expired'] | length == 0 + - order_info_7.authorizations_by_status['invalid'] | length == 0 + - order_info_7.authorizations_by_status['pending'] | length == 1 + - order_info_7.authorizations_by_status['pending'][0] == 'dns:' ~ domain_name + - order_info_7.authorizations_by_status['revoked'] | length == 0 + - order_info_7.authorizations_by_status['valid'] | length == 0 + - order_info_7.order.authorizations | length == 1 + - order_info_7.order.authorizations[0] == order_info_7.authorizations_by_identifier['dns:' ~ domain_name].uri + - "'certificate' not in order_info_7.order" + - order_info_7.order.status == 'pending' + - order_info_7.order.replaces is not defined + - order_info_7.order_uri == replacement_order_5.order_uri + - order_info_7.account_uri == account.account_uri + + - name: "({{ select_crypto_backend }}) Deactivate authzs for replacement order 5" + community.crypto.acme_certificate_deactivate_authz: + acme_directory: "{{ acme_directory_url }}" + acme_version: 2 + validate_certs: false + account_key_src: "{{ remote_tmp_dir }}/accountkey.pem" + select_crypto_backend: "{{ select_crypto_backend }}" + order_uri: "{{ replacement_order_5.order_uri }}" # Test invalid profile