diff --git a/changelogs/fragments/873-deprecation-removals.yml b/changelogs/fragments/873-deprecation-removals.yml new file mode 100644 index 00000000..7b83dd75 --- /dev/null +++ b/changelogs/fragments/873-deprecation-removals.yml @@ -0,0 +1,14 @@ +removed_features: + - "openssl_csr_pipe - the module now ignores check mode and will always behave as if check mode is not active (https://github.com/ansible-collections/community.crypto/pull/873)." + - "openssl_privatekey_pipe - the module now ignores check mode and will always behave as if check mode is not active (https://github.com/ansible-collections/community.crypto/pull/873)." + - "x509_certificate_pipe - the module now ignores check mode and will always behave as if check mode is not active (https://github.com/ansible-collections/community.crypto/pull/873)." + - "openssl_pkcs12 - support for the ``pyopenssl`` backend has been removed (https://github.com/ansible-collections/community.crypto/pull/873)." + - "crypto.module_backends.common module utils - this module utils has been removed. Use the ``argspec`` module utils instead (https://github.com/ansible-collections/community.crypto/pull/873)." + - "acme.acme module utils - the ``get_default_argspec()`` function has been removed. Use ``create_default_argspec()`` instead (https://github.com/ansible-collections/community.crypto/pull/873)." + - "acme.backends module utils - the methods ``get_ordered_csr_identifiers()`` and ``get_cert_information()`` of ``CryptoBackend`` now must be implemented (https://github.com/ansible-collections/community.crypto/pull/873)." + - "acme_* modules - support for ACME v1 has been removed (https://github.com/ansible-collections/community.crypto/pull/873)." + - "acme.documentation docs fragment - the ``documentation`` docs fragment has been removed. Use both the ``basic`` and ``account`` docs fragments in ``acme`` instead (https://github.com/ansible-collections/community.crypto/pull/873)." +breaking_changes: + - "get_certificate - the default for ``asn1_base64`` changed from ``false`` to ``true`` (https://github.com/ansible-collections/community.crypto/pull/873)." + - "acme.certificates module utils - the ``retrieve_acme_v1_certificate()`` helper function has been removed (https://github.com/ansible-collections/community.crypto/pull/873)." + - "x509_crl - the ``mode`` parameter no longer denotes the update mode, but the CRL file mode. Use ``crl_mode`` instead for the update mode (https://github.com/ansible-collections/community.crypto/pull/873)." diff --git a/galaxy.yml b/galaxy.yml index d21a52a0..9b7f0866 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -5,7 +5,7 @@ namespace: community name: crypto -version: 2.26.1 +version: 3.0.0-dev0 readme: README.md authors: - Ansible (github.com/ansible) diff --git a/plugins/action/openssl_privatekey_pipe.py b/plugins/action/openssl_privatekey_pipe.py index df79dd91..2043f47b 100644 --- a/plugins/action/openssl_privatekey_pipe.py +++ b/plugins/action/openssl_privatekey_pipe.py @@ -50,37 +50,15 @@ class PrivateKeyModule(object): if self.module_backend.needs_regeneration(): # Regenerate - if not self.check_mode: - self.module_backend.generate_private_key() - privatekey_data = self.module_backend.get_private_key_data() - self.privatekey_bytes = privatekey_data - else: - self.module.deprecate( - "Check mode support for openssl_privatekey_pipe will change in community.crypto 3.0.0" - " to behave the same as without check mode. You can get that behavior right now" - " by adding `check_mode: false` to the openssl_privatekey_pipe task. If you think this" - " breaks your use-case of this module, please create an issue in the" - " community.crypto repository", - version="3.0.0", - collection_name="community.crypto", - ) + self.module_backend.generate_private_key() + privatekey_data = self.module_backend.get_private_key_data() + self.privatekey_bytes = privatekey_data self.changed = True elif self.module_backend.needs_conversion(): # Convert - if not self.check_mode: - self.module_backend.convert_private_key() - privatekey_data = self.module_backend.get_private_key_data() - self.privatekey_bytes = privatekey_data - else: - self.module.deprecate( - "Check mode support for openssl_privatekey_pipe will change in community.crypto 3.0.0" - " to behave the same as without check mode. You can get that behavior right now" - " by adding `check_mode: false` to the openssl_privatekey_pipe task. If you think this" - " breaks your use-case of this module, please create an issue in the" - " community.crypto repository", - version="3.0.0", - collection_name="community.crypto", - ) + self.module_backend.convert_private_key() + privatekey_data = self.module_backend.get_private_key_data() + self.privatekey_bytes = privatekey_data self.changed = True def dump(self): diff --git a/plugins/doc_fragments/acme.py b/plugins/doc_fragments/acme.py index c6a600f4..6d2ab842 100644 --- a/plugins/doc_fragments/acme.py +++ b/plugins/doc_fragments/acme.py @@ -12,107 +12,6 @@ __metaclass__ = type class ModuleDocFragment(object): - # Standard files documentation fragment - # - # NOTE: This document fragment is DEPRECATED and will be removed from community.crypto 3.0.0. - # Use both the BASIC and ACCOUNT fragments as a replacement. - DOCUMENTATION = r""" -notes: - - If a new enough version of the C(cryptography) library is available (see Requirements for details), it will be used instead - of the C(openssl) binary. This can be explicitly disabled or enabled with the O(select_crypto_backend) option. Note that - using the C(openssl) binary will be slower and less secure, as private key contents always have to be stored on disk (see - O(account_key_content)). - - Although the defaults are chosen so that the module can be used with the L(Let's Encrypt,https://letsencrypt.org/) CA, - the module can in principle be used with any CA providing an ACME endpoint, such as L(Buypass Go SSL,https://www.buypass.com/ssl/products/acme). - - So far, the ACME modules have only been tested by the developers against Let's Encrypt (staging and production), Buypass - (staging and production), ZeroSSL (production), and L(Pebble testing server,https://github.com/letsencrypt/Pebble). We - have got community feedback that they also work with Sectigo ACME Service for InCommon. If you experience problems with - another ACME server, please L(create an issue,https://github.com/ansible-collections/community.crypto/issues/new/choose) - to help us supporting it. Feedback that an ACME server not mentioned does work is also appreciated. -requirements: - - either openssl or L(cryptography,https://cryptography.io/) >= 1.5 - - ipaddress -options: - account_key_src: - description: - - Path to a file containing the ACME account RSA or Elliptic Curve key. - - 'Private keys can be created with the M(community.crypto.openssl_privatekey) or M(community.crypto.openssl_privatekey_pipe) - modules. If the requisite (cryptography) is not available, keys can also be created directly with the C(openssl) command - line tool: RSA keys can be created with C(openssl genrsa ...). Elliptic curve keys can be created with C(openssl ecparam - -genkey ...). Any other tool creating private keys in PEM format can be used as well.' - - Mutually exclusive with O(account_key_content). - - Required if O(account_key_content) is not used. - type: path - aliases: [account_key] - account_key_content: - description: - - Content of the ACME account RSA or Elliptic Curve key. - - Mutually exclusive with O(account_key_src). - - Required if O(account_key_src) is not used. - - B(Warning:) the content will be written into a temporary file, which will be deleted by Ansible when the module completes. - Since this is an important private key — it can be used to change the account key, or to revoke your certificates - without knowing their private keys —, this might not be acceptable. - - In case C(cryptography) is used, the content is not written into a temporary file. It can still happen that it is - written to disk by Ansible in the process of moving the module with its argument to the node where it is executed. - type: str - account_key_passphrase: - description: - - Phassphrase to use to decode the account key. - - B(Note:) this is not supported by the C(openssl) backend, only by the C(cryptography) backend. - type: str - version_added: 1.6.0 - account_uri: - description: - - If specified, assumes that the account URI is as given. If the account key does not match this account, or an account - with this URI does not exist, the module fails. - type: str - acme_version: - description: - - The ACME version of the endpoint. - - Must be V(1) for the classic Let's Encrypt and Buypass ACME endpoints, or V(2) for standardized ACME v2 endpoints. - - The value V(1) is deprecated since community.crypto 2.0.0 and will be removed from community.crypto 3.0.0. - required: true - type: int - choices: [1, 2] - acme_directory: - description: - - The ACME directory to use. This is the entry point URL to access the ACME CA server API. - - For safety reasons the default is set to the Let's Encrypt staging server (for the ACME v1 protocol). This will create - technically correct, but untrusted certificates. - - "For Let's Encrypt, all staging endpoints can be found here: U(https://letsencrypt.org/docs/staging-environment/). - For Buypass, all endpoints can be found here: U(https://community.buypass.com/t/63d4ay/buypass-go-ssl-endpoints)." - - For B(Let's Encrypt), the production directory URL for ACME v2 is U(https://acme-v02.api.letsencrypt.org/directory). - - For B(Buypass), the production directory URL for ACME v2 and v1 is U(https://api.buypass.com/acme/directory). - - For B(ZeroSSL), the production directory URL for ACME v2 is U(https://acme.zerossl.com/v2/DV90). - - For B(Sectigo), the production directory URL for ACME v2 is U(https://acme-qa.secure.trust-provider.com/v2/DV). - - The notes for this module contain a list of ACME services this module has been tested against. - required: true - type: str - validate_certs: - description: - - Whether calls to the ACME directory will validate TLS certificates. - - B(Warning:) Should B(only ever) be set to V(false) for testing purposes, for example when testing against a local - Pebble server. - type: bool - default: true - select_crypto_backend: - description: - - Determines which crypto backend to use. - - The default choice is V(auto), which tries to use C(cryptography) if available, and falls back to C(openssl). - - If set to V(openssl), will try to use the C(openssl) binary. - - If set to V(cryptography), will try to use the L(cryptography,https://cryptography.io/) library. - type: str - default: auto - choices: [auto, cryptography, openssl] - request_timeout: - description: - - The time Ansible should wait for a response from the ACME API. - - This timeout is applied to all HTTP(S) requests (HEAD, GET, POST). - type: int - default: 10 - version_added: 2.3.0 -""" - # Basic documentation fragment without account data BASIC = r""" notes: @@ -130,11 +29,12 @@ options: acme_version: description: - The ACME version of the endpoint. - - Must be V(1) for the classic Let's Encrypt and Buypass ACME endpoints, or V(2) for standardized ACME v2 endpoints. - - The value V(1) is deprecated since community.crypto 2.0.0 and will be removed from community.crypto 3.0.0. - required: true + - Must be V(2) for standardized ACME v2 endpoints. + - The value V(1) is no longer supported since community.crypto 3.0.0. type: int - choices: [1, 2] + default: 2 + choices: + - 2 acme_directory: description: - The ACME directory to use. This is the entry point URL to access the ACME CA server API. diff --git a/plugins/module_utils/acme/account.py b/plugins/module_utils/acme/account.py index 5f7c4623..8c8742f5 100644 --- a/plugins/module_utils/acme/account.py +++ b/plugins/module_utils/acme/account.py @@ -53,61 +53,49 @@ class ACMEAccount(object): """ contact = contact or [] - if self.client.version == 1: - new_reg = {"resource": "new-reg", "contact": contact} - if agreement: - new_reg["agreement"] = agreement - else: - new_reg["agreement"] = self.client.directory["meta"]["terms-of-service"] - if external_account_binding is not None: - raise ModuleFailException( - "External account binding is not supported for ACME v1" - ) - url = self.client.directory["new-reg"] - else: - if ( - external_account_binding is not None - or self.client.directory["meta"].get("externalAccountRequired") - ) and allow_creation: - # Some ACME servers such as ZeroSSL do not like it when you try to register an existing account - # and provide external_account_binding credentials. Thus we first send a request with allow_creation=False - # to see whether the account already exists. + if ( + external_account_binding is not None + or self.client.directory["meta"].get("externalAccountRequired") + ) and allow_creation: + # Some ACME servers such as ZeroSSL do not like it when you try to register an existing account + # and provide external_account_binding credentials. Thus we first send a request with allow_creation=False + # to see whether the account already exists. - # Note that we pass contact here: ZeroSSL does not accept registration calls without contacts, even - # if onlyReturnExisting is set to true. - created, data = self._new_reg(contact=contact, allow_creation=False) - if data: - # An account already exists! Return data - return created, data - # An account does not yet exist. Try to create one next. + # Note that we pass contact here: ZeroSSL does not accept registration calls without contacts, even + # if onlyReturnExisting is set to true. + created, data = self._new_reg(contact=contact, allow_creation=False) + if data: + # An account already exists! Return data + return created, data + # An account does not yet exist. Try to create one next. - new_reg = {"contact": contact} - if not allow_creation: - # https://tools.ietf.org/html/rfc8555#section-7.3.1 - new_reg["onlyReturnExisting"] = True - if terms_agreed: - new_reg["termsOfServiceAgreed"] = True - url = self.client.directory["newAccount"] - if external_account_binding is not None: - new_reg["externalAccountBinding"] = self.client.sign_request( - { - "alg": external_account_binding["alg"], - "kid": external_account_binding["kid"], - "url": url, - }, - self.client.account_jwk, - self.client.backend.create_mac_key( - external_account_binding["alg"], external_account_binding["key"] - ), - ) - elif ( - self.client.directory["meta"].get("externalAccountRequired") - and allow_creation - ): - raise ModuleFailException( - "To create an account, an external account binding must be specified. " - "Use the acme_account module with the external_account_binding option." - ) + new_reg = {"contact": contact} + if not allow_creation: + # https://tools.ietf.org/html/rfc8555#section-7.3.1 + new_reg["onlyReturnExisting"] = True + if terms_agreed: + new_reg["termsOfServiceAgreed"] = True + url = self.client.directory["newAccount"] + if external_account_binding is not None: + new_reg["externalAccountBinding"] = self.client.sign_request( + { + "alg": external_account_binding["alg"], + "kid": external_account_binding["kid"], + "url": url, + }, + self.client.account_jwk, + self.client.backend.create_mac_key( + external_account_binding["alg"], external_account_binding["key"] + ), + ) + elif ( + self.client.directory["meta"].get("externalAccountRequired") + and allow_creation + ): + raise ModuleFailException( + "To create an account, an external account binding must be specified. " + "Use the acme_account module with the external_account_binding option." + ) result, info = self.client.send_signed_request( url, new_reg, fail_on_error=False @@ -120,12 +108,12 @@ class ACMEAccount(object): content=result, ) - if info["status"] in ([200, 201] if self.client.version == 1 else [201]): + if info["status"] == 201: # Account did not exist if "location" in info: self.client.set_account_uri(info["location"]) return True, result - elif info["status"] == (409 if self.client.version == 1 else 200): + elif info["status"] == 200: # Account did exist if result.get("status") == "deactivated": # A bug in Pebble (https://github.com/letsencrypt/pebble/issues/179) and @@ -178,28 +166,21 @@ class ACMEAccount(object): """ if self.client.account_uri is None: raise ModuleFailException("Account URI unknown") - if self.client.version == 1: + # try POST-as-GET first (draft-15 or newer) + data = None + result, info = self.client.send_signed_request( + self.client.account_uri, data, fail_on_error=False + ) + # check whether that failed with a malformed request error + if ( + info["status"] >= 400 + and result.get("type") == "urn:ietf:params:acme:error:malformed" + ): + # retry as a regular POST (with no changed data) for pre-draft-15 ACME servers data = {} - data["resource"] = "reg" result, info = self.client.send_signed_request( self.client.account_uri, data, fail_on_error=False ) - else: - # try POST-as-GET first (draft-15 or newer) - data = None - result, info = self.client.send_signed_request( - self.client.account_uri, data, fail_on_error=False - ) - # check whether that failed with a malformed request error - if ( - info["status"] >= 400 - and result.get("type") == "urn:ietf:params:acme:error:malformed" - ): - # retry as a regular POST (with no changed data) for pre-draft-15 ACME servers - data = {} - result, info = self.client.send_signed_request( - self.client.account_uri, data, fail_on_error=False - ) if not isinstance(result, Mapping): raise ACMEProtocolException( self.client.module, @@ -319,8 +300,6 @@ class ACMEAccount(object): account_data = dict(account_data) account_data.update(update_request) else: - if self.client.version == 1: - update_request["resource"] = "reg" account_data, info = self.client.send_signed_request( self.client.account_uri, update_request ) diff --git a/plugins/module_utils/acme/acme.py b/plugins/module_utils/acme/acme.py index caded1d5..8c3cfa27 100644 --- a/plugins/module_utils/acme/acme.py +++ b/plugins/module_utils/acme/acme.py @@ -142,12 +142,6 @@ class ACMEDirectory(object): self.request_timeout = module.params["request_timeout"] # Check whether self.version matches what we expect - if self.version == 1: - for key in ("new-reg", "new-authz", "new-cert"): - if key not in self.directory: - raise ModuleFailException( - "ACME directory does not seem to follow protocol ACME v1" - ) if self.version == 2: for key in ("newNonce", "newAccount", "newOrder"): if key not in self.directory: @@ -168,7 +162,7 @@ class ACMEDirectory(object): return self.directory.get(key, default_value) def get_nonce(self, resource=None): - url = self.directory_root if self.version == 1 else self.directory["newNonce"] + url = self.directory["newNonce"] if resource is not None: url = resource retry_count = 0 @@ -260,9 +254,8 @@ class ACMEClient(object): requests. """ self.account_uri = uri - if self.version != 1: - self.account_jws_header.pop("jwk") - self.account_jws_header["kid"] = self.account_uri + self.account_jws_header.pop("jwk") + self.account_jws_header["kid"] = self.account_uri def parse_key(self, key_file=None, key_content=None, passphrase=None): """ @@ -339,8 +332,7 @@ class ACMEClient(object): while True: protected = copy.deepcopy(jws_header) protected["nonce"] = self.directory.get_nonce() - if self.version != 1: - protected["url"] = url + protected["url"] = url self._log("URL", url) self._log("protected", protected) @@ -348,10 +340,6 @@ class ACMEClient(object): data = self.sign_request( protected, payload, key_data, encode_payload=encode_payload ) - if self.version == 1: - data["header"] = jws_header.copy() - for k, v in protected.items(): - data["header"].pop(k, None) self._log("signed request", data) data = self.module.jsonify(data) @@ -440,7 +428,7 @@ class ACMEClient(object): Perform a GET-like request. Will try POST-as-GET for ACMEv2, with fallback to GET if server replies with a status code of 405. """ - if not get_only and self.version != 1: + if not get_only: # Try POST-as-GET content, info = self.send_signed_request( uri, None, parse_json_result=False, fail_on_error=False @@ -551,27 +539,6 @@ class ACMEClient(object): return data -def get_default_argspec(): - """ - Provides default argument spec for the options documented in the acme doc fragment. - - DEPRECATED: will be removed in community.crypto 3.0.0 - """ - return dict( - acme_directory=dict(type="str", required=True), - acme_version=dict(type="int", required=True, choices=[1, 2]), - validate_certs=dict(type="bool", default=True), - select_crypto_backend=dict( - type="str", default="auto", choices=["auto", "openssl", "cryptography"] - ), - request_timeout=dict(type="int", default=10), - account_key_src=dict(type="path", aliases=["account_key"]), - account_key_content=dict(type="str", no_log=True), - account_key_passphrase=dict(type="str", no_log=True), - account_uri=dict(type="str"), - ) - - def create_default_argspec( with_account=True, require_account_key=True, @@ -583,7 +550,7 @@ def create_default_argspec( result = ArgumentSpec( argument_spec=dict( acme_directory=dict(type="str", required=True), - acme_version=dict(type="int", required=True, choices=[1, 2]), + acme_version=dict(type="int", choices=[2], default=2), validate_certs=dict(type="bool", default=True), select_crypto_backend=dict( type="str", default="auto", choices=["auto", "openssl", "cryptography"] @@ -613,7 +580,7 @@ def create_default_argspec( return result -def create_backend(module, needs_acme_v2): +def create_backend(module, needs_acme_v2=True): if not HAS_IPADDRESS: module.fail_json( msg=missing_required_lib("ipaddress"), exception=IPADDRESS_IMPORT_ERROR @@ -666,18 +633,6 @@ def create_backend(module, needs_acme_v2): "development purposes, but *never* for production purposes." ) - if needs_acme_v2 and module.params["acme_version"] < 2: - module.fail_json( - msg="The {0} module requires the ACME v2 protocol!".format(module._name) - ) - - if module.params["acme_version"] == 1: - module.deprecate( - "The value 1 for 'acme_version' is deprecated. Please switch to ACME v2", - version="3.0.0", - collection_name="community.crypto", - ) - # AnsibleModule() changes the locale, so change it back to C because we rely # on datetime.datetime.strptime() when parsing certificate dates. locale.setlocale(locale.LC_ALL, "C") diff --git a/plugins/module_utils/acme/backends.py b/plugins/module_utils/acme/backends.py index 8e19fa65..c7213b05 100644 --- a/plugins/module_utils/acme/backends.py +++ b/plugins/module_utils/acme/backends.py @@ -150,6 +150,7 @@ class CryptoBackend(object): def create_mac_key(self, alg, key): """Create a MAC key.""" + @abc.abstractmethod def get_ordered_csr_identifiers(self, csr_filename=None, csr_content=None): """ Return a list of requested identifiers (CN and SANs) for the CSR. @@ -159,15 +160,6 @@ class CryptoBackend(object): The list is deduplicated, and if a CNAME is present, it will be returned as the first element in the result. """ - self.module.deprecate( - "Every backend must override the get_ordered_csr_identifiers() method." - " The default implementation will be removed in 3.0.0 and this method will be marked as `abstractmethod` by then.", - version="3.0.0", - collection_name="community.crypto", - ) - return sorted( - self.get_csr_identifiers(csr_filename=csr_filename, csr_content=csr_content) - ) @abc.abstractmethod def get_csr_identifiers(self, csr_filename=None, csr_content=None): @@ -193,11 +185,8 @@ class CryptoBackend(object): Given a Criterium object, creates a ChainMatcher object. """ + @abc.abstractmethod def get_cert_information(self, cert_filename=None, cert_content=None): """ Return some information on a X.509 certificate as a CertificateInformation object. """ - # Not implementing this method in a backend is DEPRECATED and will be - # disallowed in community.crypto 3.0.0. This method will be marked as - # @abstractmethod by then. - raise BackendException("This backend does not support get_cert_information()") diff --git a/plugins/module_utils/acme/certificates.py b/plugins/module_utils/acme/certificates.py index f8d8867d..c1c135aa 100644 --- a/plugins/module_utils/acme/certificates.py +++ b/plugins/module_utils/acme/certificates.py @@ -19,7 +19,6 @@ from ansible_collections.community.crypto.plugins.module_utils.acme.errors impor ) from ansible_collections.community.crypto.plugins.module_utils.acme.utils import ( der_to_pem, - nopad_b64, process_links, ) from ansible_collections.community.crypto.plugins.module_utils.crypto.pem import ( @@ -116,33 +115,3 @@ class ChainMatcher(object): """ Check whether a certificate chain (CertificateChain instance) matches. """ - - -def retrieve_acme_v1_certificate(client, csr_der): - """ - Create a new certificate based on the CSR (ACME v1 protocol). - Return the certificate object as dict - https://tools.ietf.org/html/draft-ietf-acme-acme-02#section-6.5 - """ - new_cert = { - "resource": "new-cert", - "csr": nopad_b64(csr_der), - } - result, info = client.send_signed_request( - client.directory["new-cert"], - new_cert, - error_msg="Failed to receive certificate", - expected_status_codes=[200, 201], - ) - cert = CertificateChain(info["location"]) - cert.cert = der_to_pem(result) - - def f(link, relation): - if relation == "up": - chain_result, chain_info = client.get_request(link, parse_json_result=False) - if chain_info["status"] in [200, 201]: - del cert.chain[:] - cert.chain.append(der_to_pem(chain_result)) - - process_links(info, f) - return cert diff --git a/plugins/module_utils/acme/challenges.py b/plugins/module_utils/acme/challenges.py index 701ed1a2..adb2fd7c 100644 --- a/plugins/module_utils/acme/challenges.py +++ b/plugins/module_utils/acme/challenges.py @@ -79,16 +79,10 @@ class Challenge(object): @classmethod def from_json(cls, client, data, url=None): - return cls(data, url or (data["uri"] if client.version == 1 else data["url"])) + return cls(data, url or data["url"]) def call_validate(self, client): challenge_response = {} - if client.version == 1: - token = re.sub(r"[^A-Za-z0-9_\-]", "_", self.token) - key_authorization = create_key_authorization(client, token) - challenge_response["resource"] = "challenge" - challenge_response["keyAuthorization"] = key_authorization - challenge_response["type"] = self.type client.send_signed_request( self.url, challenge_response, @@ -160,13 +154,7 @@ class Authorization(object): ] else: self.challenges = [] - if client.version == 1 and "status" not in data: - # https://tools.ietf.org/html/draft-ietf-acme-acme-02#section-6.1.2 - # "status (required, string): ... - # If this field is missing, then the default value is "pending"." - self.status = "pending" - else: - self.status = data["status"] + self.status = data["status"] self.identifier = data["identifier"]["value"] self.identifier_type = data["identifier"]["type"] if data.get("wildcard", False): @@ -206,15 +194,11 @@ class Authorization(object): "value": identifier, }, } - if client.version == 1: - url = client.directory["new-authz"] - new_authz["resource"] = "new-authz" - else: - if "newAuthz" not in client.directory.directory: - raise ACMEProtocolException( - client.module, "ACME endpoint does not support pre-authorization" - ) - url = client.directory["newAuthz"] + if "newAuthz" not in client.directory.directory: + raise ACMEProtocolException( + client.module, "ACME endpoint does not support pre-authorization" + ) + url = client.directory["newAuthz"] result, info = client.send_signed_request( url, @@ -338,8 +322,6 @@ class Authorization(object): if not self.can_deactivate(): return authz_deactivate = {"status": "deactivated"} - if client.version == 1: - authz_deactivate["resource"] = "authz" result, info = client.send_signed_request( self.url, authz_deactivate, fail_on_error=False ) @@ -357,8 +339,6 @@ class Authorization(object): """ authz = cls(url) authz_deactivate = {"status": "deactivated"} - if client.version == 1: - authz_deactivate["resource"] = "authz" result, info = client.send_signed_request( url, authz_deactivate, fail_on_error=True ) diff --git a/plugins/module_utils/crypto/module_backends/common.py b/plugins/module_utils/crypto/module_backends/common.py deleted file mode 100644 index 808f2642..00000000 --- a/plugins/module_utils/crypto/module_backends/common.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (c) 2020, Felix Fontein -# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) -# SPDX-License-Identifier: GPL-3.0-or-later - -from __future__ import absolute_import, division, print_function - - -__metaclass__ = type - - -from ansible.module_utils.basic import AnsibleModule -from ansible_collections.community.crypto.plugins.module_utils.argspec import ( - ArgumentSpec as _ArgumentSpec, -) - - -class ArgumentSpec(_ArgumentSpec): - def create_ansible_module_helper(self, clazz, args, **kwargs): - result = super(ArgumentSpec, self).create_ansible_module_helper( - clazz, args, **kwargs - ) - result.deprecate( - "The crypto.module_backends.common module utils is deprecated and will be removed from community.crypto 3.0.0." - " Use the argspec module utils from community.crypto instead.", - version="3.0.0", - collection_name="community.crypto", - ) - return result - - -__all__ = ("AnsibleModule", "ArgumentSpec") diff --git a/plugins/modules/acme_certificate.py b/plugins/modules/acme_certificate.py index 47d0c2db..10126b33 100644 --- a/plugins/modules/acme_certificate.py +++ b/plugins/modules/acme_certificate.py @@ -102,13 +102,13 @@ options: description: - URI to a terms of service document you agree to when using the ACME v1 service at O(acme_directory). - Default is latest gathered from O(acme_directory) URL. - - This option will only be used when O(acme_version) is 1. + - This option has no longer any effect. + # TODO: deprecate! type: str terms_agreed: description: - Boolean indicating whether you agree to the terms of service document. - ACME servers can require this to be true. - - This option will only be used when O(acme_version) is not 1. type: bool default: false modify_account: @@ -433,7 +433,6 @@ EXAMPLES = r""" data: "{{ sample_com_challenge }}" # We use Let's Encrypt's ACME v2 endpoint acme_directory: https://acme-v02.api.letsencrypt.org/directory - acme_version: 2 # The following makes sure that if a chain with /CN=DST Root CA X3 in its issuer is provided # as an alternative, it will be selected. These are the roots cross-signed by IdenTrust. # As long as Let's Encrypt provides alternate chains with the cross-signed root(s) when @@ -580,10 +579,8 @@ from ansible_collections.community.crypto.plugins.module_utils.acme.acme import from ansible_collections.community.crypto.plugins.module_utils.acme.certificates import ( CertificateChain, Criterium, - retrieve_acme_v1_certificate, ) from ansible_collections.community.crypto.plugins.module_utils.acme.challenges import ( - Authorization, combine_identifier, normalize_combined_identifier, split_identifier, @@ -669,33 +666,21 @@ class ACMECertificateClient(object): # Make sure account exists modify_account = module.params["modify_account"] - if modify_account or self.version > 1: - contact = [] - if module.params["account_email"]: - contact.append("mailto:" + module.params["account_email"]) - created, account_data = self.account.setup_account( - contact, - agreement=module.params.get("agreement"), - terms_agreed=module.params.get("terms_agreed"), - allow_creation=modify_account, - ) - if account_data is None: - raise ModuleFailException( - msg="Account does not exist or is deactivated." - ) - updated = False - if not created and account_data and modify_account: - updated, account_data = self.account.update_account( - account_data, contact - ) - self.changed = created or updated - else: - # This happens if modify_account is False and the ACME v1 - # protocol is used. In this case, we do not call setup_account() - # to avoid accidental creation of an account. This is OK - # since for ACME v1, the account URI is not needed to send a - # signed ACME request. - pass + contact = [] + if module.params["account_email"]: + contact.append("mailto:" + module.params["account_email"]) + created, account_data = self.account.setup_account( + contact, + agreement=module.params.get("agreement"), + terms_agreed=module.params.get("terms_agreed"), + allow_creation=modify_account, + ) + if account_data is None: + raise ModuleFailException(msg="Account does not exist or is deactivated.") + updated = False + if not created and account_data and modify_account: + updated, account_data = self.account.update_account(account_data, contact) + self.changed = created or updated if self.csr is not None and not os.path.exists(self.csr): raise ModuleFailException("CSR %s not found" % (self.csr)) @@ -712,13 +697,9 @@ class ACMECertificateClient(object): """ if self.data is None: return True - if self.version == 1: - # As soon as self.data is a non-empty object, we are in the second stage. - return not self.data - else: - # We are in the second stage if data.order_uri is given (which has been - # stored in self.order_uri by the constructor). - return self.order_uri is None + # We are in the second stage if data.order_uri is given (which has been + # stored in self.order_uri by the constructor). + return self.order_uri is None def _get_cert_info_or_none(self): if self.module.params.get("dest"): @@ -735,40 +716,30 @@ class ACMECertificateClient(object): respectively start a new order for ACME v2. """ self.authorizations = {} - if self.version == 1: - for identifier_type, identifier in self.identifiers: - if identifier_type != "dns": - raise ModuleFailException("ACME v1 only supports DNS identifiers!") - for identifier_type, identifier in self.identifiers: - authz = Authorization.create(self.client, identifier_type, identifier) - self.authorizations[ - normalize_combined_identifier(authz.combined_identifier) - ] = authz - else: - replaces_cert_id = None - if self.include_renewal_cert_id == "always" or ( - self.include_renewal_cert_id == "when_ari_supported" - and self.client.directory.has_renewal_info_endpoint() - ): - cert_info = self._get_cert_info_or_none() - if cert_info is not None: - replaces_cert_id = compute_cert_id( - self.client.backend, - cert_info=cert_info, - none_if_required_information_is_missing=True, - ) - self.order = Order.create_with_error_handling( - self.client, - self.identifiers, - error_strategy=self.order_creation_error_strategy, - error_max_retries=self.order_creation_max_retries, - replaces_cert_id=replaces_cert_id, - profile=self.profile, - message_callback=self.module.warn, - ) - self.order_uri = self.order.url - self.order.load_authorizations(self.client) - self.authorizations.update(self.order.authorizations) + replaces_cert_id = None + if self.include_renewal_cert_id == "always" or ( + self.include_renewal_cert_id == "when_ari_supported" + and self.client.directory.has_renewal_info_endpoint() + ): + cert_info = self._get_cert_info_or_none() + if cert_info is not None: + replaces_cert_id = compute_cert_id( + self.client.backend, + cert_info=cert_info, + none_if_required_information_is_missing=True, + ) + self.order = Order.create_with_error_handling( + self.client, + self.identifiers, + error_strategy=self.order_creation_error_strategy, + error_max_retries=self.order_creation_max_retries, + replaces_cert_id=replaces_cert_id, + profile=self.profile, + message_callback=self.module.warn, + ) + self.order_uri = self.order.url + self.order.load_authorizations(self.client) + self.authorizations.update(self.order.authorizations) self.changed = True def get_challenges_data(self, first_step): @@ -815,20 +786,11 @@ class ACMECertificateClient(object): self.authorizations = {} # Step 1: obtain challenge information - if self.version == 1: - # For ACME v1, we attempt to create new authzs. Existing ones - # will be returned instead. - for identifier_type, identifier in self.identifiers: - authz = Authorization.create(self.client, identifier_type, identifier) - self.authorizations[combine_identifier(identifier_type, identifier)] = ( - authz - ) - else: - # For ACME v2, we obtain the order object by fetching the - # order URI, and extract the information from there. - self.order = Order.from_url(self.client, self.order_uri) - self.order.load_authorizations(self.client) - self.authorizations.update(self.order.authorizations) + # For ACME v2, we obtain the order object by fetching the + # order URI, and extract the information from there. + self.order = Order.from_url(self.client, self.order_uri) + self.order.load_authorizations(self.client) + self.authorizations.update(self.order.authorizations) # Step 2: validate pending challenges authzs_to_wait_for = [] @@ -897,33 +859,25 @@ class ACMECertificateClient(object): module=self.module, ) - if self.version == 1: - cert = retrieve_acme_v1_certificate( - self.client, pem_to_der(self.csr, self.csr_content) - ) - else: - self.order.finalize(self.client, pem_to_der(self.csr, self.csr_content)) - cert = CertificateChain.download(self.client, self.order.certificate_uri) - if ( - self.module.params["retrieve_all_alternates"] - or self.select_chain_matcher - ): - # Retrieve alternate chains - alternate_chains = self.download_alternate_chains(cert) + self.order.finalize(self.client, pem_to_der(self.csr, self.csr_content)) + cert = CertificateChain.download(self.client, self.order.certificate_uri) + if self.module.params["retrieve_all_alternates"] or self.select_chain_matcher: + # Retrieve alternate chains + alternate_chains = self.download_alternate_chains(cert) - # Prepare return value for all alternate chains - if self.module.params["retrieve_all_alternates"]: - self.all_chains = [cert.to_json()] - for alt_chain in alternate_chains: - self.all_chains.append(alt_chain.to_json()) + # Prepare return value for all alternate chains + if self.module.params["retrieve_all_alternates"]: + self.all_chains = [cert.to_json()] + for alt_chain in alternate_chains: + self.all_chains.append(alt_chain.to_json()) - # Try to select alternate chain depending on criteria - if self.select_chain_matcher: - matching_chain = self.find_matching_chain([cert] + alternate_chains) - if matching_chain: - cert = matching_chain - else: - self.module.debug("Found no matching alternative chain") + # Try to select alternate chain depending on criteria + if self.select_chain_matcher: + matching_chain = self.find_matching_chain([cert] + alternate_chains) + if matching_chain: + cert = matching_chain + else: + self.module.debug("Found no matching alternative chain") if cert.cert is not None: pem_cert = cert.cert diff --git a/plugins/modules/acme_certificate_deactivate_authz.py b/plugins/modules/acme_certificate_deactivate_authz.py index 189e710a..5185f255 100644 --- a/plugins/modules/acme_certificate_deactivate_authz.py +++ b/plugins/modules/acme_certificate_deactivate_authz.py @@ -76,8 +76,6 @@ def main(): order_uri=dict(type="str", required=True), ) module = argument_spec.create_ansible_module(supports_check_mode=True) - if module.params["acme_version"] == 1: - module.fail_json("The module does not support acme_version=1") backend = create_backend(module, False) diff --git a/plugins/modules/acme_certificate_order_create.py b/plugins/modules/acme_certificate_order_create.py index 971f602b..22de4fde 100644 --- a/plugins/modules/acme_certificate_order_create.py +++ b/plugins/modules/acme_certificate_order_create.py @@ -215,7 +215,6 @@ EXAMPLES = r""" - name: Create a challenge for sample.com using a account key file. community.crypto.acme_certificate_order_create: acme_directory: https://acme-v01.api.letsencrypt.org/directory - acme_version: 2 account_key_src: /etc/pki/cert/private/account.key csr: /etc/pki/cert/csr/sample.com.csr register: sample_com_challenge @@ -238,7 +237,6 @@ EXAMPLES = r""" - name: Let the challenge be validated community.crypto.acme_certificate_order_validate: acme_directory: https://acme-v01.api.letsencrypt.org/directory - acme_version: 2 account_key_src: /etc/pki/cert/private/account.key order_uri: "{{ sample_com_challenge.order_uri }}" challenge: dns-01 @@ -246,7 +244,6 @@ EXAMPLES = r""" - name: Retrieve the cert and intermediate certificate community.crypto.acme_certificate_order_finalize: acme_directory: https://acme-v01.api.letsencrypt.org/directory - acme_version: 2 account_key_src: /etc/pki/cert/private/account.key csr: /etc/pki/cert/csr/sample.com.csr order_uri: "{{ sample_com_challenge.order_uri }}" @@ -405,8 +402,6 @@ def main(): order_creation_max_retries=dict(type="int", default=3), ) module = argument_spec.create_ansible_module() - if module.params["acme_version"] == 1: - module.fail_json("The module does not support acme_version=1") backend = create_backend(module, False) diff --git a/plugins/modules/acme_certificate_order_finalize.py b/plugins/modules/acme_certificate_order_finalize.py index 0ee42944..5944cd13 100644 --- a/plugins/modules/acme_certificate_order_finalize.py +++ b/plugins/modules/acme_certificate_order_finalize.py @@ -227,7 +227,6 @@ EXAMPLES = r""" - name: Create a challenge for sample.com using a account key file. community.crypto.acme_certificate_order_create: acme_directory: https://acme-v01.api.letsencrypt.org/directory - acme_version: 2 account_key_src: /etc/pki/cert/private/account.key csr: /etc/pki/cert/csr/sample.com.csr register: sample_com_challenge @@ -250,7 +249,6 @@ EXAMPLES = r""" - name: Let the challenge be validated community.crypto.acme_certificate_order_validate: acme_directory: https://acme-v01.api.letsencrypt.org/directory - acme_version: 2 account_key_src: /etc/pki/cert/private/account.key order_uri: "{{ sample_com_challenge.order_uri }}" challenge: dns-01 @@ -258,7 +256,6 @@ EXAMPLES = r""" - name: Retrieve the cert and intermediate certificate community.crypto.acme_certificate_order_finalize: acme_directory: https://acme-v01.api.letsencrypt.org/directory - acme_version: 2 account_key_src: /etc/pki/cert/private/account.key csr: /etc/pki/cert/csr/sample.com.csr order_uri: "{{ sample_com_challenge.order_uri }}" @@ -365,8 +362,6 @@ def main(): ), ) module = argument_spec.create_ansible_module() - if module.params["acme_version"] == 1: - module.fail_json("The module does not support acme_version=1") backend = create_backend(module, False) diff --git a/plugins/modules/acme_certificate_order_info.py b/plugins/modules/acme_certificate_order_info.py index 8786b0ba..e04d248b 100644 --- a/plugins/modules/acme_certificate_order_info.py +++ b/plugins/modules/acme_certificate_order_info.py @@ -380,8 +380,6 @@ def main(): order_uri=dict(type="str", required=True), ) module = argument_spec.create_ansible_module(supports_check_mode=True) - if module.params["acme_version"] == 1: - module.fail_json("The module does not support acme_version=1") backend = create_backend(module, False) diff --git a/plugins/modules/acme_certificate_order_validate.py b/plugins/modules/acme_certificate_order_validate.py index 9ac0c184..0dcd225b 100644 --- a/plugins/modules/acme_certificate_order_validate.py +++ b/plugins/modules/acme_certificate_order_validate.py @@ -152,7 +152,6 @@ EXAMPLES = r""" - name: Create a challenge for sample.com using a account key file. community.crypto.acme_certificate_order_create: acme_directory: https://acme-v01.api.letsencrypt.org/directory - acme_version: 2 account_key_src: /etc/pki/cert/private/account.key csr: /etc/pki/cert/csr/sample.com.csr register: sample_com_challenge @@ -175,7 +174,6 @@ EXAMPLES = r""" - name: Let the challenge be validated community.crypto.acme_certificate_order_validate: acme_directory: https://acme-v01.api.letsencrypt.org/directory - acme_version: 2 account_key_src: /etc/pki/cert/private/account.key order_uri: "{{ sample_com_challenge.order_uri }}" challenge: dns-01 @@ -183,7 +181,6 @@ EXAMPLES = r""" - name: Retrieve the cert and intermediate certificate community.crypto.acme_certificate_order_finalize: acme_directory: https://acme-v01.api.letsencrypt.org/directory - acme_version: 2 account_key_src: /etc/pki/cert/private/account.key csr: /etc/pki/cert/csr/sample.com.csr order_uri: "{{ sample_com_challenge.order_uri }}" @@ -257,8 +254,6 @@ def main(): deactivate_authzs=dict(type="bool", default=True), ) module = argument_spec.create_ansible_module() - if module.params["acme_version"] == 1: - module.fail_json("The module does not support acme_version=1") backend = create_backend(module, False) diff --git a/plugins/modules/acme_certificate_revoke.py b/plugins/modules/acme_certificate_revoke.py index b6510f8e..01cccfdf 100644 --- a/plugins/modules/acme_certificate_revoke.py +++ b/plugins/modules/acme_certificate_revoke.py @@ -174,12 +174,7 @@ def main(): payload = {"certificate": certificate} if module.params.get("revoke_reason") is not None: payload["reason"] = module.params.get("revoke_reason") - # Determine endpoint - if module.params.get("acme_version") == 1: - endpoint = client.directory["revoke-cert"] - payload["resource"] = "revoke-cert" - else: - endpoint = client.directory["revokeCert"] + endpoint = client.directory["revokeCert"] # Get hold of private key (if available) and make sure it comes from disk private_key = module.params.get("private_key_src") private_key_content = module.params.get("private_key_content") @@ -227,12 +222,8 @@ def main(): already_revoked = True else: # Hack for Boulder errors - if module.params.get("acme_version") == 1: - error_type = "urn:acme:error:malformed" - else: - error_type = "urn:ietf:params:acme:error:malformed" if ( - result.get("type") == error_type + result.get("type") == "urn:ietf:params:acme:error:malformed" and result.get("detail") == "Certificate already revoked" ): # Fallback: boulder returns this in case the certificate was already revoked. diff --git a/plugins/modules/acme_inspect.py b/plugins/modules/acme_inspect.py index b84abaa5..745aa339 100644 --- a/plugins/modules/acme_inspect.py +++ b/plugins/modules/acme_inspect.py @@ -27,7 +27,7 @@ notes: - "Using the C(ansible) tool, M(community.crypto.acme_inspect) can be used to directly execute ACME requests without the need of writing a playbook. For example, the following command retrieves the ACME account with ID 1 from Let's Encrypt (assuming C(/path/to/key) is the correct private account key): C(ansible localhost -m acme_inspect -a \"account_key_src=/path/to/key - acme_directory=https://acme-v02.api.letsencrypt.org/directory acme_version=2 account_uri=https://acme-v02.api.letsencrypt.org/acme/acct/1 + acme_directory=https://acme-v02.api.letsencrypt.org/directory account_uri=https://acme-v02.api.letsencrypt.org/acme/acct/1 method=get url=https://acme-v02.api.letsencrypt.org/acme/acct/1\")." seealso: - name: Automatic Certificate Management Environment (ACME) @@ -83,14 +83,12 @@ EXAMPLES = r""" - name: Get directory community.crypto.acme_inspect: acme_directory: https://acme-staging-v02.api.letsencrypt.org/directory - acme_version: 2 method: directory-only register: directory - name: Create an account community.crypto.acme_inspect: acme_directory: https://acme-staging-v02.api.letsencrypt.org/directory - acme_version: 2 account_key_src: /etc/pki/cert/private/account.key url: "{{ directory.newAccount}}" method: post @@ -102,7 +100,6 @@ EXAMPLES = r""" - name: Get account information community.crypto.acme_inspect: acme_directory: https://acme-staging-v02.api.letsencrypt.org/directory - acme_version: 2 account_key_src: /etc/pki/cert/private/account.key account_uri: "{{ account_creation.headers.location }}" url: "{{ account_creation.headers.location }}" @@ -111,7 +108,6 @@ EXAMPLES = r""" - name: Update account contacts community.crypto.acme_inspect: acme_directory: https://acme-staging-v02.api.letsencrypt.org/directory - acme_version: 2 account_key_src: /etc/pki/cert/private/account.key account_uri: "{{ account_creation.headers.location }}" url: "{{ account_creation.headers.location }}" @@ -127,7 +123,6 @@ EXAMPLES = r""" - name: Create certificate order community.crypto.acme_certificate: acme_directory: https://acme-staging-v02.api.letsencrypt.org/directory - acme_version: 2 account_key_src: /etc/pki/cert/private/account.key account_uri: "{{ account_creation.headers.location }}" csr: /etc/pki/cert/csr/sample.com.csr @@ -141,7 +136,6 @@ EXAMPLES = r""" - name: Get order information community.crypto.acme_inspect: acme_directory: https://acme-staging-v02.api.letsencrypt.org/directory - acme_version: 2 account_key_src: /etc/pki/cert/private/account.key account_uri: "{{ account_creation.headers.location }}" url: "{{ certificate_request.order_uri }}" @@ -151,7 +145,6 @@ EXAMPLES = r""" - name: Get first authz for order community.crypto.acme_inspect: acme_directory: https://acme-staging-v02.api.letsencrypt.org/directory - acme_version: 2 account_key_src: /etc/pki/cert/private/account.key account_uri: "{{ account_creation.headers.location }}" url: "{{ order.output_json.authorizations[0] }}" @@ -161,7 +154,6 @@ EXAMPLES = r""" - name: Get HTTP-01 challenge for authz community.crypto.acme_inspect: acme_directory: https://acme-staging-v02.api.letsencrypt.org/directory - acme_version: 2 account_key_src: /etc/pki/cert/private/account.key account_uri: "{{ account_creation.headers.location }}" url: "{{ authz.output_json.challenges | selectattr('type', 'equalto', 'http-01') }}" @@ -171,7 +163,6 @@ EXAMPLES = r""" - name: Activate HTTP-01 challenge manually community.crypto.acme_inspect: acme_directory: https://acme-staging-v02.api.letsencrypt.org/directory - acme_version: 2 account_key_src: /etc/pki/cert/private/account.key account_uri: "{{ account_creation.headers.location }}" url: "{{ http01challenge.url }}" diff --git a/plugins/modules/get_certificate.py b/plugins/modules/get_certificate.py index 4df56a47..eb98c235 100644 --- a/plugins/modules/get_certificate.py +++ b/plugins/modules/get_certificate.py @@ -100,8 +100,9 @@ options: - Whether to encode the ASN.1 values in the RV(extensions) return value with Base64 or not. - The documentation claimed for a long time that the values are Base64 encoded, but they never were. For compatibility this option is set to V(false). - - The default value V(false) is B(deprecated) and will change to V(true) in community.crypto 3.0.0. + - The default value was changed from V(false) to V(true) incommunity.crypto 3.0.0. type: bool + default: true version_added: 2.12.0 tls_ctx_options: description: @@ -351,7 +352,7 @@ def main(): ), starttls=dict(type="str", choices=["mysql"]), ciphers=dict(type="list", elements="str"), - asn1_base64=dict(type="bool"), + asn1_base64=dict(type="bool", default=True), tls_ctx_options=dict(type="list", elements="raw"), get_certificate_chain=dict(type="bool", default=False), ), @@ -370,16 +371,6 @@ def main(): tls_ctx_options = module.params["tls_ctx_options"] get_certificate_chain = module.params["get_certificate_chain"] - if asn1_base64 is None: - module.deprecate( - "The default value `false` for asn1_base64 is deprecated and will change to `true` in " - "community.crypto 3.0.0. If you need this value, it is best to set the value explicitly " - "and adjust your roles/playbooks to use `asn1_base64=true` as soon as possible", - version="3.0.0", - collection_name="community.crypto", - ) - asn1_base64 = False - if get_certificate_chain and sys.version_info < (3, 10): module.fail_json( msg="get_certificate_chain=true can only be used with Python 3.10 (Python 3.13+ officially supports this). " diff --git a/plugins/modules/openssl_csr_pipe.py b/plugins/modules/openssl_csr_pipe.py index fbc5f232..d7e8673a 100644 --- a/plugins/modules/openssl_csr_pipe.py +++ b/plugins/modules/openssl_csr_pipe.py @@ -29,10 +29,7 @@ attributes: check_mode: support: full details: - - Currently in check mode, private keys will not be (re-)generated, only the changed status is set. This will change - in community.crypto 3.0.0. - - From community.crypto 3.0.0 on, the module will ignore check mode and always behave as if check mode is not active. - If you think this breaks your use-case of this module, please create an issue in the community.crypto repository. + - Since community.crypto 3.0.0, the module ignores check mode and always behaves as if check mode is not active. options: content: description: @@ -157,18 +154,7 @@ class CertificateSigningRequestModule(object): def generate(self, module): """Generate the certificate signing request.""" if self.module_backend.needs_regeneration(): - if not self.check_mode: - self.module_backend.generate_csr() - else: - self.module.deprecate( - "Check mode support for openssl_csr_pipe will change in community.crypto 3.0.0" - " to behave the same as without check mode. You can get that behavior right now" - " by adding `check_mode: false` to the openssl_csr_pipe task. If you think this" - " breaks your use-case of this module, please create an issue in the" - " community.crypto repository", - version="3.0.0", - collection_name="community.crypto", - ) + self.module_backend.generate_csr() self.changed = True def dump(self): diff --git a/plugins/modules/openssl_pkcs12.py b/plugins/modules/openssl_pkcs12.py index 8590ce29..eecc9de2 100644 --- a/plugins/modules/openssl_pkcs12.py +++ b/plugins/modules/openssl_pkcs12.py @@ -18,11 +18,9 @@ author: short_description: Generate OpenSSL PKCS#12 archive description: - This module allows one to (re-)generate PKCS#12. - - The module can use the cryptography Python library, or the pyOpenSSL Python library. By default, it tries to detect which - one is available, assuming none of the O(iter_size) and O(maciter_size) options are used. This can be overridden with - the O(select_crypto_backend) option. + - The module uses the cryptography Python library. requirements: - - PyOpenSSL >= 0.15, < 23.3.0 or cryptography >= 3.0 + - cryptography >= 3.0 extends_documentation_fragment: - ansible.builtin.files - community.crypto.attributes @@ -95,15 +93,16 @@ options: description: - Number of times to repeat the encryption step. - This is B(not considered during idempotency checks). - - This is only used by the C(pyopenssl) backend, or when O(encryption_level=compatibility2022). - - When using it, the default is V(2048) for C(pyopenssl) and V(50000) for C(cryptography). + - This is only used when O(encryption_level=compatibility2022). + - When using it, the default is V(50000). type: int maciter_size: description: - Number of times to repeat the MAC step. - This is B(not considered during idempotency checks). - - This is only used by the C(pyopenssl) backend. When using it, the default is V(1). + - This value is B(not used). type: int + # TODO: deprecate! encryption_level: description: - Determines the encryption level used. @@ -170,15 +169,12 @@ options: select_crypto_backend: description: - Determines which crypto backend to use. - - The default choice is V(auto), which tries to use C(cryptography) if available, and falls back to C(pyopenssl). If - O(iter_size) is used together with O(encryption_level) is not V(compatibility2022), or if O(maciter_size) is used, - V(auto) will always result in C(pyopenssl) to be chosen for backwards compatibility. - - If set to V(pyopenssl), will try to use the L(pyOpenSSL,https://pypi.org/project/pyOpenSSL/) library. + - The default choice is V(auto), which tries to use C(cryptography) if available. - If set to V(cryptography), will try to use the L(cryptography,https://cryptography.io/) library. - - B(Note) that the V(pyopenssl) backend is deprecated and will be removed from community.crypto 3.0.0. + - The value V(pyopenssl) has been removed for community.crypto 3.0.0. type: str default: auto - choices: [auto, cryptography, pyopenssl] + choices: [auto, cryptography] version_added: 1.7.0 seealso: - module: community.crypto.x509_certificate @@ -315,23 +311,6 @@ from ansible_collections.community.crypto.plugins.module_utils.version import ( MINIMAL_CRYPTOGRAPHY_VERSION = "3.0" -MINIMAL_PYOPENSSL_VERSION = "0.15" -MAXIMAL_PYOPENSSL_VERSION = "23.3.0" - -PYOPENSSL_IMP_ERR = None -try: - import OpenSSL - from OpenSSL import crypto - from OpenSSL.crypto import ( - load_pkcs12 as _load_pkcs12, # this got removed in pyOpenSSL 23.3.0 - ) - - PYOPENSSL_VERSION = LooseVersion(OpenSSL.__version__) -except (ImportError, AttributeError): - PYOPENSSL_IMP_ERR = traceback.format_exc() - PYOPENSSL_FOUND = False -else: - PYOPENSSL_FOUND = True CRYPTOGRAPHY_IMP_ERR = None try: @@ -628,88 +607,6 @@ class Pkcs(OpenSSLObject): self.pkcs12_bytes = content -class PkcsPyOpenSSL(Pkcs): - def __init__(self, module): - super(PkcsPyOpenSSL, self).__init__(module, "pyopenssl") - if self.encryption_level != "auto": - module.fail_json( - msg="The PyOpenSSL backend only supports encryption_level = auto" - ) - - def generate_bytes(self, module): - """Generate PKCS#12 file archive.""" - self.pkcs12 = crypto.PKCS12() - - if self.other_certificates: - self.pkcs12.set_ca_certificates(self.other_certificates) - - if self.certificate_content: - self.pkcs12.set_certificate( - load_certificate( - None, content=self.certificate_content, backend=self.backend - ) - ) - - if self.friendly_name: - self.pkcs12.set_friendlyname(to_bytes(self.friendly_name)) - - if self.privatekey_content: - try: - self.pkcs12.set_privatekey( - load_privatekey( - None, - content=self.privatekey_content, - passphrase=self.privatekey_passphrase, - backend=self.backend, - ) - ) - except OpenSSLBadPassphraseError as exc: - raise PkcsError(exc) - - return self.pkcs12.export(self.passphrase, self.iter_size, self.maciter_size) - - def parse_bytes(self, pkcs12_content): - try: - p12 = crypto.load_pkcs12(pkcs12_content, self.passphrase) - pkey = p12.get_privatekey() - if pkey is not None: - pkey = crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey) - crt = p12.get_certificate() - if crt is not None: - crt = crypto.dump_certificate(crypto.FILETYPE_PEM, crt) - other_certs = [] - if p12.get_ca_certificates() is not None: - other_certs = [ - crypto.dump_certificate(crypto.FILETYPE_PEM, other_cert) - for other_cert in p12.get_ca_certificates() - ] - - friendly_name = p12.get_friendlyname() - - return (pkey, crt, other_certs, friendly_name) - except crypto.Error as exc: - raise PkcsError(exc) - - def _dump_privatekey(self, pkcs12): - pk = pkcs12.get_privatekey() - return crypto.dump_privatekey(crypto.FILETYPE_PEM, pk) if pk else None - - def _dump_certificate(self, pkcs12): - cert = pkcs12.get_certificate() - return crypto.dump_certificate(crypto.FILETYPE_PEM, cert) if cert else None - - def _dump_other_certificates(self, pkcs12): - if pkcs12.get_ca_certificates() is None: - return [] - return [ - crypto.dump_certificate(crypto.FILETYPE_PEM, other_cert) - for other_cert in pkcs12.get_ca_certificates() - ] - - def _get_friendly_name(self, pkcs12): - return pkcs12.get_friendlyname() - - class PkcsCryptography(Pkcs): def __init__(self, module): super(PkcsCryptography, self).__init__( @@ -839,52 +736,20 @@ def select_backend(module, backend): CRYPTOGRAPHY_FOUND and CRYPTOGRAPHY_VERSION >= LooseVersion(MINIMAL_CRYPTOGRAPHY_VERSION) ) - can_use_pyopenssl = ( - PYOPENSSL_FOUND - and PYOPENSSL_VERSION >= LooseVersion(MINIMAL_PYOPENSSL_VERSION) - and PYOPENSSL_VERSION < LooseVersion(MAXIMAL_PYOPENSSL_VERSION) - ) - - # If no restrictions are provided, first try cryptography, then pyOpenSSL - if ( - module.params["iter_size"] is not None - and module.params["encryption_level"] != "compatibility2022" - ) or module.params["maciter_size"] is not None: - # If iter_size (for encryption_level != compatibility2022) or maciter_size is specified, use pyOpenSSL backend - backend = "pyopenssl" - elif can_use_cryptography: + if can_use_cryptography: backend = "cryptography" - elif can_use_pyopenssl: - backend = "pyopenssl" # Success? if backend == "auto": module.fail_json( msg=( - "Cannot detect any of the required Python libraries " - "cryptography (>= {0}) or PyOpenSSL (>= {1}, < {2})" + "Cannot detect the required Python library cryptography (>= {0})" ).format( MINIMAL_CRYPTOGRAPHY_VERSION, - MINIMAL_PYOPENSSL_VERSION, - MAXIMAL_PYOPENSSL_VERSION, ) ) - if backend == "pyopenssl": - if not PYOPENSSL_FOUND: - msg = missing_required_lib( - "pyOpenSSL >= {0}, < {1}".format( - MINIMAL_PYOPENSSL_VERSION, MAXIMAL_PYOPENSSL_VERSION - ) - ) - module.fail_json(msg=msg, exception=PYOPENSSL_IMP_ERR) - module.deprecate( - "The module is using the PyOpenSSL backend. This backend has been deprecated", - version="3.0.0", - collection_name="community.crypto", - ) - return backend, PkcsPyOpenSSL(module) - elif backend == "cryptography": + if backend == "cryptography": if not CRYPTOGRAPHY_FOUND: module.fail_json( msg=missing_required_lib( @@ -924,7 +789,7 @@ def main(): backup=dict(type="bool", default=False), return_content=dict(type="bool", default=False), select_crypto_backend=dict( - type="str", default="auto", choices=["auto", "cryptography", "pyopenssl"] + type="str", default="auto", choices=["auto", "cryptography"] ), ) diff --git a/plugins/modules/openssl_privatekey_pipe.py b/plugins/modules/openssl_privatekey_pipe.py index 86f51baa..b0c97bf2 100644 --- a/plugins/modules/openssl_privatekey_pipe.py +++ b/plugins/modules/openssl_privatekey_pipe.py @@ -39,10 +39,7 @@ attributes: check_mode: support: full details: - - Currently in check mode, private keys will not be (re-)generated, only the changed status is set. This will change - in community.crypto 3.0.0. - - From community.crypto 3.0.0 on, the module will ignore check mode and always behave as if check mode is not active. - If you think this breaks your use-case of this module, please create an issue in the community.crypto repository. + - Since community.crypto 3.0.0, the module ignores check mode and always behaves as if check mode is not active. options: content: description: diff --git a/plugins/modules/x509_certificate_pipe.py b/plugins/modules/x509_certificate_pipe.py index 1cde994b..b31af10c 100644 --- a/plugins/modules/x509_certificate_pipe.py +++ b/plugins/modules/x509_certificate_pipe.py @@ -33,10 +33,7 @@ attributes: check_mode: support: full details: - - Currently in check mode, private keys will not be (re-)generated, only the changed status is set. This will change - in community.crypto 3.0.0. - - From community.crypto 3.0.0 on, the module will ignore check mode and always behave as if check mode is not active. - If you think this breaks your use-case of this module, please create an issue in the community.crypto repository. + - Since community.crypto 3.0.0 the module ignores check mode and always behaves as if check mode is not active. options: provider: description: @@ -162,18 +159,7 @@ class GenericCertificate(object): def generate(self, module): if self.module_backend.needs_regeneration(): - if not self.check_mode: - self.module_backend.generate_certificate() - else: - self.module.deprecate( - "Check mode support for x509_certificate_pipe will change in community.crypto 3.0.0" - " to behave the same as without check mode. You can get that behavior right now" - " by adding `check_mode: false` to the x509_certificate_pipe task. If you think this" - " breaks your use-case of this module, please create an issue in the" - " community.crypto repository", - version="3.0.0", - collection_name="community.crypto", - ) + self.module_backend.generate_certificate() self.changed = True def dump(self, check_mode=False): diff --git a/plugins/modules/x509_crl.py b/plugins/modules/x509_crl.py index 2eb93d0c..094f599c 100644 --- a/plugins/modules/x509_crl.py +++ b/plugins/modules/x509_crl.py @@ -59,17 +59,9 @@ options: - This parameter was called O(mode) before community.crypto 2.13.0. It has been renamed to avoid a collision with the common O(mode) parameter for setting the CRL file's access mode. type: str - # default: generate + default: generate choices: [generate, update] version_added: 2.13.0 - mode: - description: - - This parameter has been renamed to O(crl_mode). The old name O(mode) is now deprecated and will be removed in community.crypto - 3.0.0. Replace usage of this parameter with O(crl_mode). - - Note that from community.crypto 3.0.0 on, O(mode) will be used for the CRL file's mode. - type: str - # default: generate - choices: [generate, update] force: description: @@ -968,16 +960,9 @@ def main(): state=dict(type="str", default="present", choices=["present", "absent"]), crl_mode=dict( type="str", - # default='generate', + default="generate", choices=["generate", "update"], ), - mode=dict( - type="str", - # default='generate', - choices=["generate", "update"], - removed_in_version="3.0.0", - removed_from_collection="community.crypto", - ), force=dict(type="bool", default=False), backup=dict(type="bool", default=False), path=dict(type="path", required=True), @@ -1044,16 +1029,6 @@ def main(): add_file_common_args=True, ) - if module.params["mode"]: - if module.params["crl_mode"]: - module.fail_json( - "You cannot use both `mode` and `crl_mode`. Use `crl_mode`." - ) - module.params["crl_mode"] = module.params["mode"] - # TODO: in 3.0.0, once the option `mode` has been removed, remove this: - module.params.pop("mode", None) - # From then on, `mode` will be the file mode of the CRL file - if not CRYPTOGRAPHY_FOUND: module.fail_json( msg=missing_required_lib( diff --git a/tests/integration/targets/acme_certificate/meta/main.yml b/tests/integration/targets/acme_certificate/meta/main.yml index d7164458..84b7f3f9 100644 --- a/tests/integration/targets/acme_certificate/meta/main.yml +++ b/tests/integration/targets/acme_certificate/meta/main.yml @@ -5,6 +5,5 @@ dependencies: - setup_acme - - setup_pyopenssl # needed for Ubuntu 16.04 - setup_remote_tmp_dir - prepare_jinja2_compat diff --git a/tests/integration/targets/openssl_pkcs12/meta/main.yml b/tests/integration/targets/openssl_pkcs12/meta/main.yml index 26fa5f7d..54bf29e9 100644 --- a/tests/integration/targets/openssl_pkcs12/meta/main.yml +++ b/tests/integration/targets/openssl_pkcs12/meta/main.yml @@ -5,5 +5,4 @@ dependencies: - setup_openssl - - setup_pyopenssl - setup_remote_tmp_dir diff --git a/tests/integration/targets/openssl_pkcs12/tasks/main.yml b/tests/integration/targets/openssl_pkcs12/tasks/main.yml index 26673bea..da8f86fa 100644 --- a/tests/integration/targets/openssl_pkcs12/tasks/main.yml +++ b/tests/integration/targets/openssl_pkcs12/tasks/main.yml @@ -62,17 +62,6 @@ path: '{{ remote_tmp_dir }}/ansible.p12' state: absent - - block: - - name: Running tests with pyOpenSSL backend - include_tasks: impl.yml - vars: - select_crypto_backend: pyopenssl - - when: >- - (pyopenssl_version.stdout | default('0.0')) is version('0.15', '>=') - and - (pyopenssl_version.stdout | default('0.0')) is version('23.3.0', '<') - - block: - name: Running tests with cryptography backend include_tasks: impl.yml @@ -82,10 +71,4 @@ when: cryptography_version.stdout is version('3.0', '>=') when: >- - ( - (pyopenssl_version.stdout | default('0.0')) is version('0.15', '>=') - and - (pyopenssl_version.stdout | default('0.0')) is version('23.3.0', '<') - ) - or cryptography_version.stdout is version('3.0', '>=') diff --git a/tests/integration/targets/openssl_pkcs12/tests/validate.yml b/tests/integration/targets/openssl_pkcs12/tests/validate.yml index 8ba598ee..bf7a8f0a 100644 --- a/tests/integration/targets/openssl_pkcs12/tests/validate.yml +++ b/tests/integration/targets/openssl_pkcs12/tests/validate.yml @@ -81,8 +81,7 @@ - name: '({{ select_crypto_backend }}) Load "empty" file' set_fact: empty_contents: "{{ slurp.results[0].content | b64decode }}" - empty_expected_pyopenssl: "{{ (slurp.results[2].content | b64decode) ~ (slurp.results[1].content | b64decode) }}" - empty_expected_cryptography: "{{ (slurp.results[1].content | b64decode) ~ (slurp.results[2].content | b64decode) }}" + empty_expected: "{{ (slurp.results[1].content | b64decode) ~ (slurp.results[2].content | b64decode) }}" - name: '({{ select_crypto_backend }}) Check "empty" file' assert: @@ -91,7 +90,7 @@ - p12_empty_idem is not changed - p12_empty_concat_idem is not changed - p12_empty_concat_content_idem is not changed - - (empty_contents == empty_expected_cryptography) or (empty_contents == empty_expected_pyopenssl and select_crypto_backend == 'pyopenssl') + - empty_contents == empty_expected - name: '({{ select_crypto_backend }}) PKCS#12 with compatibility2022 settings' when: diff --git a/tests/integration/targets/openssl_privatekey_pipe/tasks/impl.yml b/tests/integration/targets/openssl_privatekey_pipe/tasks/impl.yml index 477db2a1..e11e4064 100644 --- a/tests/integration/targets/openssl_privatekey_pipe/tasks/impl.yml +++ b/tests/integration/targets/openssl_privatekey_pipe/tasks/impl.yml @@ -91,9 +91,11 @@ - assert: that: - update_check is changed - - update_check.privatekey == 'VALUE_SPECIFIED_IN_NO_LOG_PARAMETER' + - update_check.privatekey != 'VALUE_SPECIFIED_IN_NO_LOG_PARAMETER' + - update_check.privatekey != result.privatekey - update_check_return is changed - - update_check_return.privatekey == result.privatekey + - update_check_return.privatekey != 'VALUE_SPECIFIED_IN_NO_LOG_PARAMETER' + - update_check_return.privatekey != result.privatekey - update is changed - update.privatekey != result.privatekey - update_info.public_data.size == default_rsa_key_size diff --git a/tests/integration/targets/setup_pyopenssl/defaults/main.yml b/tests/integration/targets/setup_pyopenssl/defaults/main.yml deleted file mode 100644 index 33e171d0..00000000 --- a/tests/integration/targets/setup_pyopenssl/defaults/main.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -# Copyright (c) Ansible Project -# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) -# SPDX-License-Identifier: GPL-3.0-or-later - -has_pyopenssl: true diff --git a/tests/integration/targets/setup_pyopenssl/meta/main.yml b/tests/integration/targets/setup_pyopenssl/meta/main.yml deleted file mode 100644 index b9b2b3b5..00000000 --- a/tests/integration/targets/setup_pyopenssl/meta/main.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -# Copyright (c) Ansible Project -# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) -# SPDX-License-Identifier: GPL-3.0-or-later - -dependencies: - - setup_python_info - - setup_remote_constraints - - setup_pkg_mgr diff --git a/tests/integration/targets/setup_pyopenssl/tasks/main.yml b/tests/integration/targets/setup_pyopenssl/tasks/main.yml deleted file mode 100644 index aed2fe0a..00000000 --- a/tests/integration/targets/setup_pyopenssl/tasks/main.yml +++ /dev/null @@ -1,71 +0,0 @@ ---- -# Copyright (c) Ansible Project -# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) -# SPDX-License-Identifier: GPL-3.0-or-later - -#################################################################### -# WARNING: These are designed specifically for Ansible tests # -# and should not be used as examples of how to write Ansible roles # -#################################################################### - -- name: Install from system packages - when: ansible_os_family != "Darwin" and target_system_python - block: - - - name: Include OS-specific variables - include_vars: '{{ lookup("first_found", search) }}' - vars: - search: - files: - - '{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml' - - '{{ ansible_distribution }}-{{ ansible_distribution_version }}.yml' - - '{{ ansible_distribution }}.yml' - - '{{ ansible_os_family }}.yml' - paths: - - vars - - - when: has_pyopenssl - block: - - - name: Install pyOpenSSL (Python 3 from system packages) - become: true - package: - name: '{{ pyopenssl_package_name_python3 }}' - when: ansible_python_version is version('3.0', '>=') - - - name: Install pyOpenSSL (Python 2 from system packages) - become: true - package: - name: '{{ pyopenssl_package_name }}' - when: ansible_python_version is version('3.0', '<') - -- name: Install from PyPi - when: ansible_os_family == "Darwin" or not target_system_python - block: - - - name: Install pyOpenSSL (PyPi) - become: true - pip: - name: pyOpenSSL - state: "{{ 'latest' if not target_system_python_cannot_upgrade_cryptography else omit }}" - extra_args: "-c {{ remote_constraints }}" - -- when: has_pyopenssl - block: - - - name: Register pyOpenSSL version - command: "{{ ansible_python.executable }} -c 'import OpenSSL; print(OpenSSL.__version__)'" - register: pyopenssl_version - - - name: Register pyOpenSSL debug details - command: "{{ ansible_python.executable }} -m OpenSSL.debug" - register: pyopenssl_debug_version - ignore_errors: true - -# Depending on which pyOpenSSL version has been installed, it could be that cryptography has -# been upgraded to a newer version. Make sure to register cryptography_version another time here -# to avoid strange testing behavior due to wrong values of cryptography_version. -- name: Register cryptography version - command: "{{ ansible_python.executable }} -c 'import cryptography; print(cryptography.__version__)'" - register: cryptography_version - ignore_errors: true # in case cryptography was not installed, and setup_openssl hasn't been run before, ignore errors diff --git a/tests/integration/targets/setup_pyopenssl/vars/Alpine.yml b/tests/integration/targets/setup_pyopenssl/vars/Alpine.yml deleted file mode 100644 index e0aa3658..00000000 --- a/tests/integration/targets/setup_pyopenssl/vars/Alpine.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -# Copyright (c) Ansible Project -# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) -# SPDX-License-Identifier: GPL-3.0-or-later - -pyopenssl_package_name: py-openssl -pyopenssl_package_name_python3: py3-openssl diff --git a/tests/integration/targets/setup_pyopenssl/vars/Archlinux.yml b/tests/integration/targets/setup_pyopenssl/vars/Archlinux.yml deleted file mode 100644 index 08ca08f1..00000000 --- a/tests/integration/targets/setup_pyopenssl/vars/Archlinux.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -# Copyright (c) Ansible Project -# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) -# SPDX-License-Identifier: GPL-3.0-or-later - -pyopenssl_package_name: python-pyopenssl -pyopenssl_package_name_python3: python-pyopenssl diff --git a/tests/integration/targets/setup_pyopenssl/vars/Debian.yml b/tests/integration/targets/setup_pyopenssl/vars/Debian.yml deleted file mode 100644 index 85c86de2..00000000 --- a/tests/integration/targets/setup_pyopenssl/vars/Debian.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -# Copyright (c) Ansible Project -# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) -# SPDX-License-Identifier: GPL-3.0-or-later - -pyopenssl_package_name: python-openssl -pyopenssl_package_name_python3: python3-openssl diff --git a/tests/integration/targets/setup_pyopenssl/vars/FreeBSD.yml b/tests/integration/targets/setup_pyopenssl/vars/FreeBSD.yml deleted file mode 100644 index 6d4cbbdb..00000000 --- a/tests/integration/targets/setup_pyopenssl/vars/FreeBSD.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -# Copyright (c) Ansible Project -# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) -# SPDX-License-Identifier: GPL-3.0-or-later - -pyopenssl_package_name: py27-openssl -pyopenssl_package_name_python3: "py{{ ansible_python.version.major }}{{ ansible_python.version.minor }}-openssl" diff --git a/tests/integration/targets/setup_pyopenssl/vars/RedHat-9.yml b/tests/integration/targets/setup_pyopenssl/vars/RedHat-9.yml deleted file mode 100644 index 4de0ee22..00000000 --- a/tests/integration/targets/setup_pyopenssl/vars/RedHat-9.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -# Copyright (c) Ansible Project -# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) -# SPDX-License-Identifier: GPL-3.0-or-later - -has_pyopenssl: false diff --git a/tests/integration/targets/setup_pyopenssl/vars/RedHat.yml b/tests/integration/targets/setup_pyopenssl/vars/RedHat.yml deleted file mode 100644 index aaeea70f..00000000 --- a/tests/integration/targets/setup_pyopenssl/vars/RedHat.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -# Copyright (c) Ansible Project -# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) -# SPDX-License-Identifier: GPL-3.0-or-later - -pyopenssl_package_name: pyOpenSSL -pyopenssl_package_name_python3: python3-pyOpenSSL diff --git a/tests/integration/targets/setup_pyopenssl/vars/Suse.yml b/tests/integration/targets/setup_pyopenssl/vars/Suse.yml deleted file mode 100644 index 4bdfa322..00000000 --- a/tests/integration/targets/setup_pyopenssl/vars/Suse.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -# Copyright (c) Ansible Project -# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) -# SPDX-License-Identifier: GPL-3.0-or-later - -pyopenssl_package_name: python-pyOpenSSL -pyopenssl_package_name_python3: python3-pyOpenSSL diff --git a/tests/integration/targets/x509_certificate-acme/meta/main.yml b/tests/integration/targets/x509_certificate-acme/meta/main.yml index d7164458..84b7f3f9 100644 --- a/tests/integration/targets/x509_certificate-acme/meta/main.yml +++ b/tests/integration/targets/x509_certificate-acme/meta/main.yml @@ -5,6 +5,5 @@ dependencies: - setup_acme - - setup_pyopenssl # needed for Ubuntu 16.04 - setup_remote_tmp_dir - prepare_jinja2_compat diff --git a/tests/unit/plugins/module_utils/acme/test_challenges.py b/tests/unit/plugins/module_utils/acme/test_challenges.py index 224e96a2..6328321c 100644 --- a/tests/unit/plugins/module_utils/acme/test_challenges.py +++ b/tests/unit/plugins/module_utils/acme/test_challenges.py @@ -68,20 +68,6 @@ def test_challenge_from_to_json(): assert challenge.token == "foo" assert challenge.to_json() == data - data = { - "uri": "xxx", - "type": "type", - "status": "valid", - } - client.version = 1 - challenge = Challenge.from_json(client, data) - assert challenge.data == data - assert challenge.type == "type" - assert challenge.url == "xxx" - assert challenge.status == "valid" - assert challenge.token is None - assert challenge.to_json() == data - def test_authorization_from_to_json(): client = MagicMock() @@ -154,30 +140,6 @@ def test_authorization_from_to_json(): "wildcard": True, } - client.version = 1 - - data = { - "challenges": [], - "identifier": { - "type": "dns", - "value": "example.com", - }, - } - authz = Authorization.from_json(client, data, "xxx") - assert authz.url == "xxx" - assert authz.status == "pending" - assert authz.identifier == "example.com" - assert authz.identifier_type == "dns" - assert authz.challenges == [] - assert authz.to_json() == { - "uri": "xxx", - "challenges": [], - "identifier": { - "type": "dns", - "value": "example.com", - }, - } - def test_authorization_create_error(): client = MagicMock()