openssl_* modules: allow direct input and output for some files (#65400)
* Allow to return generated object. * Use slurp module instead of file lookup + b64encode. * Rename return_xxx_content -> return_content.
This commit is contained in:
parent
4d345813ea
commit
d6fb9da8ed
23 changed files with 346 additions and 4 deletions
7
changelogs/fragments/65400-openssl-output.yml
Normal file
7
changelogs/fragments/65400-openssl-output.yml
Normal file
|
@ -0,0 +1,7 @@
|
|||
minor_changes:
|
||||
- "openssl_certificate - allow to return the existing/generated certificate directly as ``certificate`` by setting ``return_content`` to ``yes``."
|
||||
- "openssl_csr - allow to return the existing/generated CSR directly as ``csr`` by setting ``return_content`` to ``yes``."
|
||||
- "openssl_dhparam - allow to return the existing/generated DH params directly as ``dhparams`` by setting ``return_content`` to ``yes``."
|
||||
- "openssl_pkcs12 - allow to return the existing/generated PKCS#12 directly as ``pkcs12`` by setting ``return_content`` to ``yes``."
|
||||
- "openssl_privatekey - allow to return the existing/generated private key directly as ``privatekey`` by setting ``return_content`` to ``yes``."
|
||||
- "openssl_publickey - allow to return the existing/generated public key directly as ``publickey`` by setting ``return_content`` to ``yes``."
|
|
@ -187,6 +187,26 @@ def get_fingerprint(path, passphrase=None, content=None):
|
|||
return get_fingerprint_of_bytes(publickey)
|
||||
|
||||
|
||||
def load_file_if_exists(path, module=None, ignore_errors=False):
|
||||
try:
|
||||
with open(path, 'rb') as f:
|
||||
return f.read()
|
||||
except EnvironmentError as exc:
|
||||
if exc.errno == errno.ENOENT:
|
||||
return None
|
||||
if ignore_errors:
|
||||
return None
|
||||
if module is None:
|
||||
raise
|
||||
module.fail_json('Error while loading {0} - {1}'.format(path, str(exc)))
|
||||
except Exception as exc:
|
||||
if ignore_errors:
|
||||
return None
|
||||
if module is None:
|
||||
raise
|
||||
module.fail_json('Error while loading {0} - {1}'.format(path, str(exc)))
|
||||
|
||||
|
||||
def load_privatekey(path, passphrase=None, check_passphrase=True, content=None, backend='pyopenssl'):
|
||||
"""Load the specified OpenSSL private key.
|
||||
|
||||
|
|
|
@ -590,6 +590,13 @@ options:
|
|||
default: https://cloud.entrust.net/EntrustCloud/documentation/cms-api-2.1.0.yaml
|
||||
version_added: "2.9"
|
||||
|
||||
return_content:
|
||||
description:
|
||||
- If set to C(yes), will return the (current or generated) certificate's content as I(certificate).
|
||||
type: bool
|
||||
default: no
|
||||
version_added: "2.10"
|
||||
|
||||
extends_documentation_fragment: files
|
||||
notes:
|
||||
- All ASN.1 TIME values should be specified following the YYYYMMDDHHMMSSZ pattern.
|
||||
|
@ -852,6 +859,11 @@ backup_file:
|
|||
returned: changed and if I(backup) is C(yes)
|
||||
type: str
|
||||
sample: /path/to/www.ansible.com.crt.2019-03-09@11:22~
|
||||
certificate:
|
||||
description: The (current or generated) certificate's content.
|
||||
returned: if I(state) is C(present) and I(return_content) is C(yes)
|
||||
type: str
|
||||
version_added: "2.10"
|
||||
'''
|
||||
|
||||
|
||||
|
@ -929,6 +941,7 @@ class Certificate(crypto_utils.OpenSSLObject):
|
|||
self.csr = None
|
||||
self.backend = backend
|
||||
self.module = module
|
||||
self.return_content = module.params['return_content']
|
||||
|
||||
# The following are default values which make sure check() works as
|
||||
# before if providers do not explicitly change these properties.
|
||||
|
@ -1115,6 +1128,8 @@ class CertificateAbsent(Certificate):
|
|||
}
|
||||
if self.backup_file:
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
result['certificate'] = None
|
||||
|
||||
return result
|
||||
|
||||
|
@ -1230,6 +1245,9 @@ class SelfSignedCertificateCryptography(Certificate):
|
|||
}
|
||||
if self.backup_file:
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
content = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['certificate'] = content.decode('utf-8') if content else None
|
||||
|
||||
if check_mode:
|
||||
result.update({
|
||||
|
@ -1327,6 +1345,9 @@ class SelfSignedCertificate(Certificate):
|
|||
}
|
||||
if self.backup_file:
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
content = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['certificate'] = content.decode('utf-8') if content else None
|
||||
|
||||
if check_mode:
|
||||
result.update({
|
||||
|
@ -1521,6 +1542,9 @@ class OwnCACertificateCryptography(Certificate):
|
|||
}
|
||||
if self.backup_file:
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
content = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['certificate'] = content.decode('utf-8') if content else None
|
||||
|
||||
if check_mode:
|
||||
result.update({
|
||||
|
@ -1644,6 +1668,9 @@ class OwnCACertificate(Certificate):
|
|||
}
|
||||
if self.backup_file:
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
content = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['certificate'] = content.decode('utf-8') if content else None
|
||||
|
||||
if check_mode:
|
||||
result.update({
|
||||
|
@ -1959,6 +1986,9 @@ class AssertOnlyCertificateBase(Certificate):
|
|||
'privatekey': self.privatekey_path,
|
||||
'csr': self.csr_path,
|
||||
}
|
||||
if self.return_content:
|
||||
content = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['certificate'] = content.decode('utf-8') if content else None
|
||||
return result
|
||||
|
||||
|
||||
|
@ -2424,6 +2454,9 @@ class EntrustCertificate(Certificate):
|
|||
|
||||
if self.backup_file:
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
content = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['certificate'] = content.decode('utf-8') if content else None
|
||||
|
||||
result.update(self._get_cert_details())
|
||||
|
||||
|
@ -2511,6 +2544,9 @@ class AcmeCertificate(Certificate):
|
|||
}
|
||||
if self.backup_file:
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
content = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['certificate'] = content.decode('utf-8') if content else None
|
||||
|
||||
return result
|
||||
|
||||
|
@ -2526,6 +2562,7 @@ def main():
|
|||
csr_content=dict(type='str'),
|
||||
backup=dict(type='bool', default=False),
|
||||
select_crypto_backend=dict(type='str', default='auto', choices=['auto', 'cryptography', 'pyopenssl']),
|
||||
return_content=dict(type='bool', default=False),
|
||||
|
||||
# General properties of a certificate
|
||||
privatekey_path=dict(type='path'),
|
||||
|
|
|
@ -280,6 +280,12 @@ options:
|
|||
I(authority_cert_issuer) and I(authority_cert_serial_number) is specified.
|
||||
type: int
|
||||
version_added: "2.9"
|
||||
return_content:
|
||||
description:
|
||||
- If set to C(yes), will return the (current or generated) CSR's content as I(csr).
|
||||
type: bool
|
||||
default: no
|
||||
version_added: "2.10"
|
||||
extends_documentation_fragment:
|
||||
- files
|
||||
notes:
|
||||
|
@ -419,6 +425,11 @@ backup_file:
|
|||
returned: changed and if I(backup) is C(yes)
|
||||
type: str
|
||||
sample: /path/to/www.ansible.com.csr.2019-03-09@11:22~
|
||||
csr:
|
||||
description: The (current or generated) CSR's content.
|
||||
returned: if I(state) is C(present) and I(return_content) is C(yes)
|
||||
type: str
|
||||
version_added: "2.10"
|
||||
'''
|
||||
|
||||
import abc
|
||||
|
@ -510,6 +521,8 @@ class CertificateSigningRequestBase(crypto_utils.OpenSSLObject):
|
|||
self.authority_cert_serial_number = module.params['authority_cert_serial_number']
|
||||
self.request = None
|
||||
self.privatekey = None
|
||||
self.csr_bytes = None
|
||||
self.return_content = module.params['return_content']
|
||||
|
||||
if self.create_subject_key_identifier and self.subject_key_identifier is not None:
|
||||
module.fail_json(msg='subject_key_identifier cannot be specified if create_subject_key_identifier is true')
|
||||
|
@ -559,6 +572,8 @@ class CertificateSigningRequestBase(crypto_utils.OpenSSLObject):
|
|||
result = self._generate_csr()
|
||||
if self.backup:
|
||||
self.backup_file = module.backup_local(self.path)
|
||||
if self.return_content:
|
||||
self.csr_bytes = result
|
||||
crypto_utils.write_file(module, result)
|
||||
self.changed = True
|
||||
|
||||
|
@ -606,6 +621,10 @@ class CertificateSigningRequestBase(crypto_utils.OpenSSLObject):
|
|||
}
|
||||
if self.backup_file:
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
if self.csr_bytes is None:
|
||||
self.csr_bytes = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['csr'] = self.csr_bytes.decode('utf-8') if self.csr_bytes else None
|
||||
|
||||
return result
|
||||
|
||||
|
@ -1059,6 +1078,7 @@ def main():
|
|||
authority_cert_issuer=dict(type='list', elements='str'),
|
||||
authority_cert_serial_number=dict(type='int'),
|
||||
select_crypto_backend=dict(type='str', default='auto', choices=['auto', 'cryptography', 'pyopenssl']),
|
||||
return_content=dict(type='bool', default=False),
|
||||
),
|
||||
required_together=[('authority_cert_issuer', 'authority_cert_serial_number')],
|
||||
required_if=[('state', 'present', ['privatekey_path', 'privatekey_content'], True)],
|
||||
|
|
|
@ -70,6 +70,12 @@ options:
|
|||
default: auto
|
||||
choices: [ auto, cryptography, openssl ]
|
||||
version_added: '2.10'
|
||||
return_content:
|
||||
description:
|
||||
- If set to C(yes), will return the (current or generated) DH params' content as I(dhparams).
|
||||
type: bool
|
||||
default: no
|
||||
version_added: "2.10"
|
||||
extends_documentation_fragment:
|
||||
- files
|
||||
seealso:
|
||||
|
@ -112,6 +118,11 @@ backup_file:
|
|||
returned: changed and if I(backup) is C(yes)
|
||||
type: str
|
||||
sample: /path/to/dhparams.pem.2019-03-09@11:22~
|
||||
dhparams:
|
||||
description: The (current or generated) DH params' content.
|
||||
returned: if I(state) is C(present) and I(return_content) is C(yes)
|
||||
type: str
|
||||
version_added: "2.10"
|
||||
'''
|
||||
|
||||
import abc
|
||||
|
@ -155,6 +166,7 @@ class DHParameterBase(object):
|
|||
self.size = module.params['size']
|
||||
self.force = module.params['force']
|
||||
self.changed = False
|
||||
self.return_content = module.params['return_content']
|
||||
|
||||
self.backup = module.params['backup']
|
||||
self.backup_file = None
|
||||
|
@ -218,6 +230,9 @@ class DHParameterBase(object):
|
|||
}
|
||||
if self.backup_file:
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
content = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['dhparams'] = content.decode('utf-8') if content else None
|
||||
|
||||
return result
|
||||
|
||||
|
@ -332,6 +347,7 @@ def main():
|
|||
path=dict(type='path', required=True),
|
||||
backup=dict(type='bool', default=False),
|
||||
select_crypto_backend=dict(type='str', default='auto', choices=['auto', 'cryptography', 'openssl']),
|
||||
return_content=dict(type='bool', default=False),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
add_file_common_args=True,
|
||||
|
|
|
@ -95,6 +95,12 @@ options:
|
|||
type: bool
|
||||
default: no
|
||||
version_added: "2.8"
|
||||
return_content:
|
||||
description:
|
||||
- If set to C(yes), will return the (current or generated) PKCS#12's content as I(pkcs12).
|
||||
type: bool
|
||||
default: no
|
||||
version_added: "2.10"
|
||||
extends_documentation_fragment:
|
||||
- files
|
||||
seealso:
|
||||
|
@ -169,8 +175,14 @@ backup_file:
|
|||
returned: changed and if I(backup) is C(yes)
|
||||
type: str
|
||||
sample: /path/to/ansible.com.pem.2019-03-09@11:22~
|
||||
pkcs12:
|
||||
description: The (current or generated) PKCS#12's content Base64 encoded.
|
||||
returned: if I(state) is C(present) and I(return_content) is C(yes)
|
||||
type: str
|
||||
version_added: "2.10"
|
||||
'''
|
||||
|
||||
import base64
|
||||
import stat
|
||||
import os
|
||||
import traceback
|
||||
|
@ -212,6 +224,8 @@ class Pkcs(crypto_utils.OpenSSLObject):
|
|||
self.pkcs12 = None
|
||||
self.privatekey_passphrase = module.params['privatekey_passphrase']
|
||||
self.privatekey_path = module.params['privatekey_path']
|
||||
self.pkcs12_bytes = None
|
||||
self.return_content = module.params['return_content']
|
||||
self.src = module.params['src']
|
||||
|
||||
if module.params['mode'] is None:
|
||||
|
@ -294,6 +308,10 @@ class Pkcs(crypto_utils.OpenSSLObject):
|
|||
result['privatekey_path'] = self.privatekey_path
|
||||
if self.backup_file:
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
if self.pkcs12_bytes is None:
|
||||
self.pkcs12_bytes = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['pkcs12'] = base64.b64encode(self.pkcs12_bytes) if self.pkcs12_bytes else None
|
||||
|
||||
return result
|
||||
|
||||
|
@ -358,6 +376,8 @@ class Pkcs(crypto_utils.OpenSSLObject):
|
|||
if self.backup:
|
||||
self.backup_file = module.backup_local(self.path)
|
||||
crypto_utils.write_file(module, content, mode)
|
||||
if self.return_content:
|
||||
self.pkcs12_bytes = content
|
||||
|
||||
|
||||
def main():
|
||||
|
@ -376,6 +396,7 @@ def main():
|
|||
state=dict(type='str', default='present', choices=['absent', 'present']),
|
||||
src=dict(type='path'),
|
||||
backup=dict(type='bool', default=False),
|
||||
return_content=dict(type='bool', default=False),
|
||||
)
|
||||
|
||||
required_if = [
|
||||
|
|
|
@ -156,6 +156,14 @@ options:
|
|||
type: bool
|
||||
default: no
|
||||
version_added: "2.8"
|
||||
return_content:
|
||||
description:
|
||||
- If set to C(yes), will return the (current or generated) private key's content as I(privatekey).
|
||||
- Note that especially if the private key is not encrypted, you have to make sure that the returned
|
||||
value is treated appropriately and not accidentally written to logs etc.! Use with care!
|
||||
type: bool
|
||||
default: no
|
||||
version_added: "2.10"
|
||||
extends_documentation_fragment:
|
||||
- files
|
||||
seealso:
|
||||
|
@ -232,9 +240,17 @@ backup_file:
|
|||
returned: changed and if I(backup) is C(yes)
|
||||
type: str
|
||||
sample: /path/to/privatekey.pem.2019-03-09@11:22~
|
||||
privatekey:
|
||||
description:
|
||||
- The (current or generated) private key's content.
|
||||
- Will be Base64-encoded if the key is in raw format.
|
||||
returned: if I(state) is C(present) and I(return_content) is C(yes)
|
||||
type: str
|
||||
version_added: "2.10"
|
||||
'''
|
||||
|
||||
import abc
|
||||
import base64
|
||||
import os
|
||||
import traceback
|
||||
from distutils.version import LooseVersion
|
||||
|
@ -303,6 +319,8 @@ class PrivateKeyBase(crypto_utils.OpenSSLObject):
|
|||
self.fingerprint = {}
|
||||
self.format = module.params['format']
|
||||
self.format_mismatch = module.params['format_mismatch']
|
||||
self.privatekey_bytes = None
|
||||
self.return_content = module.params['return_content']
|
||||
|
||||
self.backup = module.params['backup']
|
||||
self.backup_file = None
|
||||
|
@ -333,6 +351,8 @@ class PrivateKeyBase(crypto_utils.OpenSSLObject):
|
|||
self.backup_file = module.backup_local(self.path)
|
||||
self._generate_private_key()
|
||||
privatekey_data = self._get_private_key_data()
|
||||
if self.return_content:
|
||||
self.privatekey_bytes = privatekey_data
|
||||
crypto_utils.write_file(module, privatekey_data, 0o600)
|
||||
self.changed = True
|
||||
elif not self.check(module, perms_required=False, ignore_conversion=False):
|
||||
|
@ -340,6 +360,8 @@ class PrivateKeyBase(crypto_utils.OpenSSLObject):
|
|||
if self.backup:
|
||||
self.backup_file = module.backup_local(self.path)
|
||||
privatekey_data = self._get_private_key_data()
|
||||
if self.return_content:
|
||||
self.privatekey_bytes = privatekey_data
|
||||
crypto_utils.write_file(module, privatekey_data, 0o600)
|
||||
self.changed = True
|
||||
|
||||
|
@ -393,6 +415,16 @@ class PrivateKeyBase(crypto_utils.OpenSSLObject):
|
|||
}
|
||||
if self.backup_file:
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
if self.privatekey_bytes is None:
|
||||
self.privatekey_bytes = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
if self.privatekey_bytes:
|
||||
if crypto_utils.identify_private_key_format(self.privatekey_bytes) == 'raw':
|
||||
result['privatekey'] = base64.b64encode(self.privatekey_bytes)
|
||||
else:
|
||||
result['privatekey'] = self.privatekey_bytes.decode('utf-8')
|
||||
else:
|
||||
result['privatekey'] = None
|
||||
|
||||
return result
|
||||
|
||||
|
@ -744,6 +776,7 @@ def main():
|
|||
format=dict(type='str', default='auto_ignore', choices=['pkcs1', 'pkcs8', 'raw', 'auto', 'auto_ignore']),
|
||||
format_mismatch=dict(type='str', default='regenerate', choices=['regenerate', 'convert']),
|
||||
select_crypto_backend=dict(type='str', choices=['auto', 'pyopenssl', 'cryptography'], default='auto'),
|
||||
return_content=dict(type='bool', default=False),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
add_file_common_args=True,
|
||||
|
|
|
@ -90,6 +90,12 @@ options:
|
|||
default: auto
|
||||
choices: [ auto, cryptography, pyopenssl ]
|
||||
version_added: "2.9"
|
||||
return_content:
|
||||
description:
|
||||
- If set to C(yes), will return the (current or generated) public key's content as I(publickey).
|
||||
type: bool
|
||||
default: no
|
||||
version_added: "2.10"
|
||||
extends_documentation_fragment:
|
||||
- files
|
||||
seealso:
|
||||
|
@ -171,6 +177,11 @@ backup_file:
|
|||
returned: changed and if I(backup) is C(yes)
|
||||
type: str
|
||||
sample: /path/to/publickey.pem.2019-03-09@11:22~
|
||||
publickey:
|
||||
description: The (current or generated) public key's content.
|
||||
returned: if I(state) is C(present) and I(return_content) is C(yes)
|
||||
type: str
|
||||
version_added: "2.10"
|
||||
'''
|
||||
|
||||
import os
|
||||
|
@ -229,6 +240,8 @@ class PublicKey(crypto_utils.OpenSSLObject):
|
|||
self.privatekey_content = self.privatekey_content.encode('utf-8')
|
||||
self.privatekey_passphrase = module.params['privatekey_passphrase']
|
||||
self.privatekey = None
|
||||
self.publickey_bytes = None
|
||||
self.return_content = module.params['return_content']
|
||||
self.fingerprint = {}
|
||||
self.backend = backend
|
||||
|
||||
|
@ -270,6 +283,8 @@ class PublicKey(crypto_utils.OpenSSLObject):
|
|||
if not self.check(module, perms_required=False) or self.force:
|
||||
try:
|
||||
publickey_content = self._create_publickey(module)
|
||||
if self.return_content:
|
||||
self.publickey_bytes = publickey_content
|
||||
|
||||
if self.backup:
|
||||
self.backup_file = module.backup_local(self.path)
|
||||
|
@ -302,6 +317,8 @@ class PublicKey(crypto_utils.OpenSSLObject):
|
|||
try:
|
||||
with open(self.path, 'rb') as public_key_fh:
|
||||
publickey_content = public_key_fh.read()
|
||||
if self.return_content:
|
||||
self.publickey_bytes = publickey_content
|
||||
if self.backend == 'cryptography':
|
||||
if self.format == 'OpenSSH':
|
||||
# Read and dump public key. Makes sure that the comment is stripped off.
|
||||
|
@ -353,6 +370,10 @@ class PublicKey(crypto_utils.OpenSSLObject):
|
|||
}
|
||||
if self.backup_file:
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
if self.publickey_bytes is None:
|
||||
self.publickey_bytes = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['publickey'] = self.publickey_bytes.decode('utf-8') if self.publickey_bytes else None
|
||||
|
||||
return result
|
||||
|
||||
|
@ -370,6 +391,7 @@ def main():
|
|||
privatekey_passphrase=dict(type='str', no_log=True),
|
||||
backup=dict(type='bool', default=False),
|
||||
select_crypto_backend=dict(type='str', choices=['auto', 'pyopenssl', 'cryptography'], default='auto'),
|
||||
return_content=dict(type='bool', default=False),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
add_file_common_args=True,
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
provider: ownca
|
||||
ownca_digest: sha256
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
return_content: yes
|
||||
register: ownca_certificate
|
||||
|
||||
- name: (OwnCA, {{select_crypto_backend}}) Generate ownca certificate (idempotent)
|
||||
|
@ -74,6 +75,7 @@
|
|||
provider: ownca
|
||||
ownca_digest: sha256
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
return_content: yes
|
||||
register: ownca_certificate_idempotence
|
||||
|
||||
- name: (OwnCA, {{select_crypto_backend}}) Generate ownca certificate (check mode)
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
path: "{{ output_dir }}/removal_cert.pem"
|
||||
state: absent
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
return_content: yes
|
||||
register: removal_1
|
||||
|
||||
- name: "(Removal, {{select_crypto_backend}}) Check that file is gone"
|
||||
|
@ -48,3 +49,4 @@
|
|||
- removal_1 is changed
|
||||
- not removal_1_poststat.stat.exists
|
||||
- removal_2 is not changed
|
||||
- removal_1.certificate is none
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
provider: selfsigned
|
||||
selfsigned_digest: sha256
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
return_content: yes
|
||||
register: selfsigned_certificate
|
||||
|
||||
- name: (Selfsigned, {{select_crypto_backend}}) Generate selfsigned certificate - idempotency
|
||||
|
@ -42,6 +43,7 @@
|
|||
provider: selfsigned
|
||||
selfsigned_digest: sha256
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
return_content: yes
|
||||
register: selfsigned_certificate_idempotence
|
||||
|
||||
- name: (Selfsigned, {{select_crypto_backend}}) Generate selfsigned certificate (check mode)
|
||||
|
|
|
@ -31,6 +31,12 @@
|
|||
- ownca_certificate.notBefore == ownca_certificate_idempotence.notBefore
|
||||
- ownca_certificate.notAfter == ownca_certificate_idempotence.notAfter
|
||||
|
||||
- name: (OwnCA validation, {{select_crypto_backend}}) Validate ownca data return
|
||||
assert:
|
||||
that:
|
||||
- ownca_certificate.certificate == lookup('file', output_dir ~ '/ownca_cert.pem', rstrip=False)
|
||||
- ownca_certificate.certificate == ownca_certificate_idempotence.certificate
|
||||
|
||||
- block:
|
||||
- name: (OwnCA validation, {{select_crypto_backend}}) Validate ownca certificate v2 (test - ownca certificate version == 2)
|
||||
shell: 'openssl x509 -noout -in {{ output_dir}}/ownca_cert_v2.pem -text | grep "Version" | sed "s/.*: \(.*\) .*/\1/g"'
|
||||
|
|
|
@ -30,6 +30,12 @@
|
|||
- selfsigned_certificate.notBefore == selfsigned_certificate_idempotence.notBefore
|
||||
- selfsigned_certificate.notAfter == selfsigned_certificate_idempotence.notAfter
|
||||
|
||||
- name: (Selfsigned validation, {{select_crypto_backend}}) Validate data retrieval
|
||||
assert:
|
||||
that:
|
||||
- selfsigned_certificate.certificate == lookup('file', output_dir ~ '/cert.pem', rstrip=False)
|
||||
- selfsigned_certificate.certificate == selfsigned_certificate_idempotence.certificate
|
||||
|
||||
- name: Make sure that changes in CSR are detected even if private key is specified
|
||||
assert:
|
||||
that:
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
subject:
|
||||
commonName: www.ansible.com
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
return_content: yes
|
||||
check_mode: yes
|
||||
register: generate_csr_check
|
||||
|
||||
|
@ -20,6 +21,7 @@
|
|||
subject:
|
||||
commonName: www.ansible.com
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
return_content: yes
|
||||
register: generate_csr
|
||||
|
||||
- name: Generate CSR (idempotent)
|
||||
|
@ -29,7 +31,8 @@
|
|||
subject:
|
||||
commonName: www.ansible.com
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
register: generate_csr_check_idempotent
|
||||
return_content: yes
|
||||
register: generate_csr_idempotent
|
||||
|
||||
- name: Generate CSR (idempotent, check mode)
|
||||
openssl_csr:
|
||||
|
@ -38,8 +41,9 @@
|
|||
subject:
|
||||
commonName: www.ansible.com
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
return_content: yes
|
||||
check_mode: yes
|
||||
register: generate_csr_check_idempotent_check
|
||||
register: generate_csr_idempotent_check
|
||||
|
||||
- name: Generate CSR without SAN (check mode)
|
||||
openssl_csr:
|
||||
|
@ -330,6 +334,7 @@
|
|||
state: absent
|
||||
backup: yes
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
return_content: yes
|
||||
register: csr_backup_4
|
||||
- name: Generate CSR (remove, idempotent)
|
||||
openssl_csr:
|
||||
|
|
|
@ -22,8 +22,16 @@
|
|||
that:
|
||||
- generate_csr_check is changed
|
||||
- generate_csr is changed
|
||||
- generate_csr_check_idempotent is not changed
|
||||
- generate_csr_check_idempotent_check is not changed
|
||||
- generate_csr_idempotent is not changed
|
||||
- generate_csr_idempotent_check is not changed
|
||||
|
||||
- name: Validate CSR (data retrieval)
|
||||
assert:
|
||||
that:
|
||||
- generate_csr_check.csr is none
|
||||
- generate_csr.csr == lookup('file', output_dir ~ '/csr.csr', rstrip=False)
|
||||
- generate_csr.csr == generate_csr_idempotent.csr
|
||||
- generate_csr.csr == generate_csr_idempotent_check.csr
|
||||
|
||||
- name: Validate CSR without SAN (check mode, idempotency)
|
||||
assert:
|
||||
|
@ -168,6 +176,7 @@
|
|||
- csr_backup_4.backup_file is string
|
||||
- csr_backup_5 is not changed
|
||||
- csr_backup_5.backup_file is undefined
|
||||
- csr_backup_4.csr is none
|
||||
|
||||
- name: Check CSR with everything
|
||||
assert:
|
||||
|
|
|
@ -6,12 +6,15 @@
|
|||
size: 768
|
||||
path: '{{ output_dir }}/dh768.pem'
|
||||
select_crypto_backend: "{{ select_crypto_backend }}"
|
||||
return_content: yes
|
||||
register: dhparam
|
||||
|
||||
- name: "[{{ select_crypto_backend }}] Don't regenerate parameters with no change"
|
||||
openssl_dhparam:
|
||||
size: 768
|
||||
path: '{{ output_dir }}/dh768.pem'
|
||||
select_crypto_backend: "{{ select_crypto_backend }}"
|
||||
return_content: yes
|
||||
register: dhparam_changed
|
||||
|
||||
- name: "[{{ select_crypto_backend }}] Generate parameters with size option"
|
||||
|
@ -87,6 +90,7 @@
|
|||
state: absent
|
||||
backup: yes
|
||||
select_crypto_backend: "{{ select_crypto_backend }}"
|
||||
return_content: yes
|
||||
register: dhparam_backup_4
|
||||
- name: "[{{ select_crypto_backend }}] Generate params (remove, idempotent)"
|
||||
openssl_dhparam:
|
||||
|
|
|
@ -31,6 +31,12 @@
|
|||
- dhparam_changed_to_512 is changed
|
||||
- dhparam_changed_force is changed
|
||||
|
||||
- name: "[{{ select_crypto_backend }}] Make sure correct values are returned"
|
||||
assert:
|
||||
that:
|
||||
- dhparam.dhparams == lookup('file', output_dir ~ '/dh768.pem', rstrip=False)
|
||||
- dhparam.dhparams == dhparam_changed.dhparams
|
||||
|
||||
- name: "[{{ select_crypto_backend }}] Verify that broken params will be regenerated"
|
||||
assert:
|
||||
that:
|
||||
|
@ -49,3 +55,4 @@
|
|||
- dhparam_backup_4.backup_file is string
|
||||
- dhparam_backup_5 is not changed
|
||||
- dhparam_backup_5.backup_file is undefined
|
||||
- dhparam_backup_4.dhparams is none
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
privatekey_path: "{{ output_dir }}/ansible_pkey.pem"
|
||||
certificate_path: "{{ output_dir }}/ansible.crt"
|
||||
state: present
|
||||
return_content: yes
|
||||
register: p12_standard
|
||||
|
||||
- name: 'Generate PKCS#12 file again, idempotency'
|
||||
|
@ -60,8 +61,20 @@
|
|||
privatekey_path: "{{ output_dir }}/ansible_pkey.pem"
|
||||
certificate_path: "{{ output_dir }}/ansible.crt"
|
||||
state: present
|
||||
return_content: yes
|
||||
register: p12_standard_idempotency
|
||||
|
||||
- name: Read ansible.p12
|
||||
slurp:
|
||||
src: "{{ output_dir }}/ansible.p12"
|
||||
register: ansible_p12_content
|
||||
|
||||
- name: 'Validate PKCS#12'
|
||||
assert:
|
||||
that:
|
||||
- p12_standard.pkcs12 == ansible_p12_content.content
|
||||
- p12_standard_idempotency.pkcs12 == p12_standard.pkcs12
|
||||
|
||||
- name: 'Generate PKCS#12 file (force)'
|
||||
openssl_pkcs12:
|
||||
path: "{{ output_dir }}/ansible.p12"
|
||||
|
@ -216,6 +229,7 @@
|
|||
path: "{{ output_dir }}/ansible_backup.p12"
|
||||
state: absent
|
||||
backup: yes
|
||||
return_content: yes
|
||||
register: p12_backup_4
|
||||
- name: 'Generate PKCS#12 file (remove, idempotent)'
|
||||
openssl_pkcs12:
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
---
|
||||
- name: 'Validate PKCS#12'
|
||||
command: "openssl pkcs12 -info -in {{ output_dir }}/ansible.p12 -nodes -passin pass:''"
|
||||
register: p12
|
||||
|
@ -53,3 +54,4 @@
|
|||
- p12_backup_4.backup_file is string
|
||||
- p12_backup_5 is not changed
|
||||
- p12_backup_5.backup_file is undefined
|
||||
- p12_backup_4.pkcs12 is none
|
||||
|
|
|
@ -3,6 +3,15 @@
|
|||
openssl_privatekey:
|
||||
path: '{{ output_dir }}/privatekey1.pem'
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
return_content: yes
|
||||
register: privatekey1
|
||||
|
||||
- name: Generate privatekey1 - standard (idempotence)
|
||||
openssl_privatekey:
|
||||
path: '{{ output_dir }}/privatekey1.pem'
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
return_content: yes
|
||||
register: privatekey1_idempotence
|
||||
|
||||
- name: Generate privatekey2 - size 2048
|
||||
openssl_privatekey:
|
||||
|
@ -27,6 +36,15 @@
|
|||
state: absent
|
||||
path: '{{ output_dir }}/privatekey4.pem'
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
return_content: yes
|
||||
register: privatekey4_delete
|
||||
|
||||
- name: Delete privatekey4 - standard (idempotence)
|
||||
openssl_privatekey:
|
||||
state: absent
|
||||
path: '{{ output_dir }}/privatekey4.pem'
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
register: privatekey4_delete_idempotence
|
||||
|
||||
- name: Generate privatekey5 - standard - with passphrase
|
||||
openssl_privatekey:
|
||||
|
@ -381,30 +399,69 @@
|
|||
type: X448
|
||||
format: raw
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
return_content: yes
|
||||
register: privatekey_fmt_2_step_3
|
||||
|
||||
- name: Read privatekey_fmt_2.pem
|
||||
slurp:
|
||||
src: "{{ output_dir }}/privatekey_fmt_2.pem"
|
||||
register: content
|
||||
|
||||
- name: Generate privatekey_fmt_2 - verify that returned content is base64 encoded
|
||||
assert:
|
||||
that:
|
||||
- privatekey_fmt_2_step_3.privatekey == content.content
|
||||
|
||||
- name: Generate privatekey_fmt_2 - raw format (idempotent)
|
||||
openssl_privatekey:
|
||||
path: '{{ output_dir }}/privatekey_fmt_2.pem'
|
||||
type: X448
|
||||
format: raw
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
return_content: yes
|
||||
register: privatekey_fmt_2_step_4
|
||||
|
||||
- name: Read privatekey_fmt_2.pem
|
||||
slurp:
|
||||
src: "{{ output_dir }}/privatekey_fmt_2.pem"
|
||||
register: content
|
||||
|
||||
- name: Generate privatekey_fmt_2 - verify that returned content is base64 encoded
|
||||
assert:
|
||||
that:
|
||||
- privatekey_fmt_2_step_4.privatekey == content.content
|
||||
|
||||
- name: Generate privatekey_fmt_2 - auto format (ignore)
|
||||
openssl_privatekey:
|
||||
path: '{{ output_dir }}/privatekey_fmt_2.pem'
|
||||
type: X448
|
||||
format: auto_ignore
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
return_content: yes
|
||||
register: privatekey_fmt_2_step_5
|
||||
|
||||
- name: Read privatekey_fmt_2.pem
|
||||
slurp:
|
||||
src: "{{ output_dir }}/privatekey_fmt_2.pem"
|
||||
register: content
|
||||
|
||||
- name: Generate privatekey_fmt_2 - verify that returned content is base64 encoded
|
||||
assert:
|
||||
that:
|
||||
- privatekey_fmt_2_step_5.privatekey == content.content
|
||||
|
||||
- name: Generate privatekey_fmt_2 - auto format (no ignore)
|
||||
openssl_privatekey:
|
||||
path: '{{ output_dir }}/privatekey_fmt_2.pem'
|
||||
type: X448
|
||||
format: auto
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
return_content: yes
|
||||
register: privatekey_fmt_2_step_6
|
||||
|
||||
- name: Generate privatekey_fmt_2 - verify that returned content is not base64 encoded
|
||||
assert:
|
||||
that:
|
||||
- privatekey_fmt_2_step_6.privatekey == lookup('file', output_dir ~ '/privatekey_fmt_2.pem', rstrip=False)
|
||||
|
||||
when: 'select_crypto_backend == "cryptography" and cryptography_version.stdout is version("2.6", ">=")'
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
---
|
||||
- name: Validate privatekey1 idempotency and content returned
|
||||
assert:
|
||||
that:
|
||||
- privatekey1_idempotence is not changed
|
||||
- privatekey1.privatekey == lookup('file', output_dir ~ '/privatekey1.pem', rstrip=False)
|
||||
- privatekey1.privatekey == privatekey1_idempotence.privatekey
|
||||
|
||||
|
||||
- name: Validate privatekey1 (test - RSA key with size 4096 bits)
|
||||
shell: "openssl rsa -noout -text -in {{ output_dir }}/privatekey1.pem | grep Private | sed 's/\\(RSA *\\)*Private-Key: (\\(.*\\) bit.*)/\\2/'"
|
||||
register: privatekey1
|
||||
|
@ -39,6 +47,13 @@
|
|||
that:
|
||||
- privatekey4.stat.exists == False
|
||||
|
||||
- name: Validate privatekey4 removal behavior
|
||||
assert:
|
||||
that:
|
||||
- privatekey4_delete is changed
|
||||
- privatekey4_delete.privatekey is none
|
||||
- privatekey4_delete_idempotence is not changed
|
||||
|
||||
|
||||
- name: Validate privatekey5 (test - Passphrase protected key + idempotence)
|
||||
shell: "openssl rsa -noout -text -in {{ output_dir }}/privatekey5.pem -passin pass:ansible | grep Private | sed 's/\\(RSA *\\)*Private-Key: (\\(.*\\) bit.*)/\\2/'"
|
||||
|
|
|
@ -8,6 +8,16 @@
|
|||
path: '{{ output_dir }}/publickey.pub'
|
||||
privatekey_path: '{{ output_dir }}/privatekey.pem'
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
return_content: yes
|
||||
register: publickey
|
||||
|
||||
- name: Generate publickey - PEM format (idempotence)
|
||||
openssl_publickey:
|
||||
path: '{{ output_dir }}/publickey.pub'
|
||||
privatekey_path: '{{ output_dir }}/privatekey.pem'
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
return_content: yes
|
||||
register: publickey_idempotence
|
||||
|
||||
- name: Generate publickey - OpenSSH format
|
||||
openssl_publickey:
|
||||
|
@ -38,6 +48,16 @@
|
|||
path: '{{ output_dir }}/publickey2.pub'
|
||||
privatekey_path: '{{ output_dir }}/privatekey.pem'
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
return_content: yes
|
||||
register: publickey2_absent
|
||||
|
||||
- name: Delete publickey2 - standard (idempotence)
|
||||
openssl_publickey:
|
||||
state: absent
|
||||
path: '{{ output_dir }}/publickey2.pub'
|
||||
privatekey_path: '{{ output_dir }}/privatekey.pem'
|
||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||
register: publickey2_absent_idempotence
|
||||
|
||||
- name: Generate privatekey3 - with passphrase
|
||||
openssl_privatekey:
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
---
|
||||
- name: Validate publickey 1 idempotence and result behavior
|
||||
assert:
|
||||
that:
|
||||
- publickey is changed
|
||||
- publickey_idempotence is not changed
|
||||
- publickey.publickey == lookup('file', output_dir ~ '/publickey.pub', rstrip=False)
|
||||
- publickey.publickey == publickey_idempotence.publickey
|
||||
|
||||
- name: Validate public key (test - privatekey modulus)
|
||||
shell: 'openssl rsa -noout -modulus -in {{ output_dir }}/privatekey.pem'
|
||||
register: privatekey_modulus
|
||||
|
@ -45,6 +53,13 @@
|
|||
that:
|
||||
- publickey2.stat.exists == False
|
||||
|
||||
- name: Validate publickey2 removal behavior
|
||||
assert:
|
||||
that:
|
||||
- publickey2_absent is changed
|
||||
- publickey2_absent_idempotence is not changed
|
||||
- publickey2_absent.publickey is none
|
||||
|
||||
|
||||
- name: Validate publickey3 (test - privatekey modulus)
|
||||
shell: 'openssl rsa -noout -modulus -in {{ output_dir }}/privatekey3.pem -passin pass:ansible'
|
||||
|
|
Loading…
Reference in a new issue