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
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)
|
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'):
|
def load_privatekey(path, passphrase=None, check_passphrase=True, content=None, backend='pyopenssl'):
|
||||||
"""Load the specified OpenSSL private key.
|
"""Load the specified OpenSSL private key.
|
||||||
|
|
||||||
|
|
|
@ -590,6 +590,13 @@ options:
|
||||||
default: https://cloud.entrust.net/EntrustCloud/documentation/cms-api-2.1.0.yaml
|
default: https://cloud.entrust.net/EntrustCloud/documentation/cms-api-2.1.0.yaml
|
||||||
version_added: "2.9"
|
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
|
extends_documentation_fragment: files
|
||||||
notes:
|
notes:
|
||||||
- All ASN.1 TIME values should be specified following the YYYYMMDDHHMMSSZ pattern.
|
- 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)
|
returned: changed and if I(backup) is C(yes)
|
||||||
type: str
|
type: str
|
||||||
sample: /path/to/www.ansible.com.crt.2019-03-09@11:22~
|
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.csr = None
|
||||||
self.backend = backend
|
self.backend = backend
|
||||||
self.module = module
|
self.module = module
|
||||||
|
self.return_content = module.params['return_content']
|
||||||
|
|
||||||
# The following are default values which make sure check() works as
|
# The following are default values which make sure check() works as
|
||||||
# before if providers do not explicitly change these properties.
|
# before if providers do not explicitly change these properties.
|
||||||
|
@ -1115,6 +1128,8 @@ class CertificateAbsent(Certificate):
|
||||||
}
|
}
|
||||||
if self.backup_file:
|
if self.backup_file:
|
||||||
result['backup_file'] = self.backup_file
|
result['backup_file'] = self.backup_file
|
||||||
|
if self.return_content:
|
||||||
|
result['certificate'] = None
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -1230,6 +1245,9 @@ class SelfSignedCertificateCryptography(Certificate):
|
||||||
}
|
}
|
||||||
if self.backup_file:
|
if self.backup_file:
|
||||||
result['backup_file'] = 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:
|
if check_mode:
|
||||||
result.update({
|
result.update({
|
||||||
|
@ -1327,6 +1345,9 @@ class SelfSignedCertificate(Certificate):
|
||||||
}
|
}
|
||||||
if self.backup_file:
|
if self.backup_file:
|
||||||
result['backup_file'] = 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:
|
if check_mode:
|
||||||
result.update({
|
result.update({
|
||||||
|
@ -1521,6 +1542,9 @@ class OwnCACertificateCryptography(Certificate):
|
||||||
}
|
}
|
||||||
if self.backup_file:
|
if self.backup_file:
|
||||||
result['backup_file'] = 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:
|
if check_mode:
|
||||||
result.update({
|
result.update({
|
||||||
|
@ -1644,6 +1668,9 @@ class OwnCACertificate(Certificate):
|
||||||
}
|
}
|
||||||
if self.backup_file:
|
if self.backup_file:
|
||||||
result['backup_file'] = 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:
|
if check_mode:
|
||||||
result.update({
|
result.update({
|
||||||
|
@ -1959,6 +1986,9 @@ class AssertOnlyCertificateBase(Certificate):
|
||||||
'privatekey': self.privatekey_path,
|
'privatekey': self.privatekey_path,
|
||||||
'csr': self.csr_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
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
@ -2424,6 +2454,9 @@ class EntrustCertificate(Certificate):
|
||||||
|
|
||||||
if self.backup_file:
|
if self.backup_file:
|
||||||
result['backup_file'] = 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())
|
result.update(self._get_cert_details())
|
||||||
|
|
||||||
|
@ -2511,6 +2544,9 @@ class AcmeCertificate(Certificate):
|
||||||
}
|
}
|
||||||
if self.backup_file:
|
if self.backup_file:
|
||||||
result['backup_file'] = 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
|
return result
|
||||||
|
|
||||||
|
@ -2526,6 +2562,7 @@ def main():
|
||||||
csr_content=dict(type='str'),
|
csr_content=dict(type='str'),
|
||||||
backup=dict(type='bool', default=False),
|
backup=dict(type='bool', default=False),
|
||||||
select_crypto_backend=dict(type='str', default='auto', choices=['auto', 'cryptography', 'pyopenssl']),
|
select_crypto_backend=dict(type='str', default='auto', choices=['auto', 'cryptography', 'pyopenssl']),
|
||||||
|
return_content=dict(type='bool', default=False),
|
||||||
|
|
||||||
# General properties of a certificate
|
# General properties of a certificate
|
||||||
privatekey_path=dict(type='path'),
|
privatekey_path=dict(type='path'),
|
||||||
|
|
|
@ -280,6 +280,12 @@ options:
|
||||||
I(authority_cert_issuer) and I(authority_cert_serial_number) is specified.
|
I(authority_cert_issuer) and I(authority_cert_serial_number) is specified.
|
||||||
type: int
|
type: int
|
||||||
version_added: "2.9"
|
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:
|
extends_documentation_fragment:
|
||||||
- files
|
- files
|
||||||
notes:
|
notes:
|
||||||
|
@ -419,6 +425,11 @@ backup_file:
|
||||||
returned: changed and if I(backup) is C(yes)
|
returned: changed and if I(backup) is C(yes)
|
||||||
type: str
|
type: str
|
||||||
sample: /path/to/www.ansible.com.csr.2019-03-09@11:22~
|
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
|
import abc
|
||||||
|
@ -510,6 +521,8 @@ class CertificateSigningRequestBase(crypto_utils.OpenSSLObject):
|
||||||
self.authority_cert_serial_number = module.params['authority_cert_serial_number']
|
self.authority_cert_serial_number = module.params['authority_cert_serial_number']
|
||||||
self.request = None
|
self.request = None
|
||||||
self.privatekey = 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:
|
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')
|
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()
|
result = self._generate_csr()
|
||||||
if self.backup:
|
if self.backup:
|
||||||
self.backup_file = module.backup_local(self.path)
|
self.backup_file = module.backup_local(self.path)
|
||||||
|
if self.return_content:
|
||||||
|
self.csr_bytes = result
|
||||||
crypto_utils.write_file(module, result)
|
crypto_utils.write_file(module, result)
|
||||||
self.changed = True
|
self.changed = True
|
||||||
|
|
||||||
|
@ -606,6 +621,10 @@ class CertificateSigningRequestBase(crypto_utils.OpenSSLObject):
|
||||||
}
|
}
|
||||||
if self.backup_file:
|
if self.backup_file:
|
||||||
result['backup_file'] = 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
|
return result
|
||||||
|
|
||||||
|
@ -1059,6 +1078,7 @@ def main():
|
||||||
authority_cert_issuer=dict(type='list', elements='str'),
|
authority_cert_issuer=dict(type='list', elements='str'),
|
||||||
authority_cert_serial_number=dict(type='int'),
|
authority_cert_serial_number=dict(type='int'),
|
||||||
select_crypto_backend=dict(type='str', default='auto', choices=['auto', 'cryptography', 'pyopenssl']),
|
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_together=[('authority_cert_issuer', 'authority_cert_serial_number')],
|
||||||
required_if=[('state', 'present', ['privatekey_path', 'privatekey_content'], True)],
|
required_if=[('state', 'present', ['privatekey_path', 'privatekey_content'], True)],
|
||||||
|
|
|
@ -70,6 +70,12 @@ options:
|
||||||
default: auto
|
default: auto
|
||||||
choices: [ auto, cryptography, openssl ]
|
choices: [ auto, cryptography, openssl ]
|
||||||
version_added: '2.10'
|
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:
|
extends_documentation_fragment:
|
||||||
- files
|
- files
|
||||||
seealso:
|
seealso:
|
||||||
|
@ -112,6 +118,11 @@ backup_file:
|
||||||
returned: changed and if I(backup) is C(yes)
|
returned: changed and if I(backup) is C(yes)
|
||||||
type: str
|
type: str
|
||||||
sample: /path/to/dhparams.pem.2019-03-09@11:22~
|
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
|
import abc
|
||||||
|
@ -155,6 +166,7 @@ class DHParameterBase(object):
|
||||||
self.size = module.params['size']
|
self.size = module.params['size']
|
||||||
self.force = module.params['force']
|
self.force = module.params['force']
|
||||||
self.changed = False
|
self.changed = False
|
||||||
|
self.return_content = module.params['return_content']
|
||||||
|
|
||||||
self.backup = module.params['backup']
|
self.backup = module.params['backup']
|
||||||
self.backup_file = None
|
self.backup_file = None
|
||||||
|
@ -218,6 +230,9 @@ class DHParameterBase(object):
|
||||||
}
|
}
|
||||||
if self.backup_file:
|
if self.backup_file:
|
||||||
result['backup_file'] = 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
|
return result
|
||||||
|
|
||||||
|
@ -332,6 +347,7 @@ def main():
|
||||||
path=dict(type='path', required=True),
|
path=dict(type='path', required=True),
|
||||||
backup=dict(type='bool', default=False),
|
backup=dict(type='bool', default=False),
|
||||||
select_crypto_backend=dict(type='str', default='auto', choices=['auto', 'cryptography', 'openssl']),
|
select_crypto_backend=dict(type='str', default='auto', choices=['auto', 'cryptography', 'openssl']),
|
||||||
|
return_content=dict(type='bool', default=False),
|
||||||
),
|
),
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
add_file_common_args=True,
|
add_file_common_args=True,
|
||||||
|
|
|
@ -95,6 +95,12 @@ options:
|
||||||
type: bool
|
type: bool
|
||||||
default: no
|
default: no
|
||||||
version_added: "2.8"
|
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:
|
extends_documentation_fragment:
|
||||||
- files
|
- files
|
||||||
seealso:
|
seealso:
|
||||||
|
@ -169,8 +175,14 @@ backup_file:
|
||||||
returned: changed and if I(backup) is C(yes)
|
returned: changed and if I(backup) is C(yes)
|
||||||
type: str
|
type: str
|
||||||
sample: /path/to/ansible.com.pem.2019-03-09@11:22~
|
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 stat
|
||||||
import os
|
import os
|
||||||
import traceback
|
import traceback
|
||||||
|
@ -212,6 +224,8 @@ class Pkcs(crypto_utils.OpenSSLObject):
|
||||||
self.pkcs12 = None
|
self.pkcs12 = None
|
||||||
self.privatekey_passphrase = module.params['privatekey_passphrase']
|
self.privatekey_passphrase = module.params['privatekey_passphrase']
|
||||||
self.privatekey_path = module.params['privatekey_path']
|
self.privatekey_path = module.params['privatekey_path']
|
||||||
|
self.pkcs12_bytes = None
|
||||||
|
self.return_content = module.params['return_content']
|
||||||
self.src = module.params['src']
|
self.src = module.params['src']
|
||||||
|
|
||||||
if module.params['mode'] is None:
|
if module.params['mode'] is None:
|
||||||
|
@ -294,6 +308,10 @@ class Pkcs(crypto_utils.OpenSSLObject):
|
||||||
result['privatekey_path'] = self.privatekey_path
|
result['privatekey_path'] = self.privatekey_path
|
||||||
if self.backup_file:
|
if self.backup_file:
|
||||||
result['backup_file'] = 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
|
return result
|
||||||
|
|
||||||
|
@ -358,6 +376,8 @@ class Pkcs(crypto_utils.OpenSSLObject):
|
||||||
if self.backup:
|
if self.backup:
|
||||||
self.backup_file = module.backup_local(self.path)
|
self.backup_file = module.backup_local(self.path)
|
||||||
crypto_utils.write_file(module, content, mode)
|
crypto_utils.write_file(module, content, mode)
|
||||||
|
if self.return_content:
|
||||||
|
self.pkcs12_bytes = content
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -376,6 +396,7 @@ def main():
|
||||||
state=dict(type='str', default='present', choices=['absent', 'present']),
|
state=dict(type='str', default='present', choices=['absent', 'present']),
|
||||||
src=dict(type='path'),
|
src=dict(type='path'),
|
||||||
backup=dict(type='bool', default=False),
|
backup=dict(type='bool', default=False),
|
||||||
|
return_content=dict(type='bool', default=False),
|
||||||
)
|
)
|
||||||
|
|
||||||
required_if = [
|
required_if = [
|
||||||
|
|
|
@ -156,6 +156,14 @@ options:
|
||||||
type: bool
|
type: bool
|
||||||
default: no
|
default: no
|
||||||
version_added: "2.8"
|
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:
|
extends_documentation_fragment:
|
||||||
- files
|
- files
|
||||||
seealso:
|
seealso:
|
||||||
|
@ -232,9 +240,17 @@ backup_file:
|
||||||
returned: changed and if I(backup) is C(yes)
|
returned: changed and if I(backup) is C(yes)
|
||||||
type: str
|
type: str
|
||||||
sample: /path/to/privatekey.pem.2019-03-09@11:22~
|
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 abc
|
||||||
|
import base64
|
||||||
import os
|
import os
|
||||||
import traceback
|
import traceback
|
||||||
from distutils.version import LooseVersion
|
from distutils.version import LooseVersion
|
||||||
|
@ -303,6 +319,8 @@ class PrivateKeyBase(crypto_utils.OpenSSLObject):
|
||||||
self.fingerprint = {}
|
self.fingerprint = {}
|
||||||
self.format = module.params['format']
|
self.format = module.params['format']
|
||||||
self.format_mismatch = module.params['format_mismatch']
|
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 = module.params['backup']
|
||||||
self.backup_file = None
|
self.backup_file = None
|
||||||
|
@ -333,6 +351,8 @@ class PrivateKeyBase(crypto_utils.OpenSSLObject):
|
||||||
self.backup_file = module.backup_local(self.path)
|
self.backup_file = module.backup_local(self.path)
|
||||||
self._generate_private_key()
|
self._generate_private_key()
|
||||||
privatekey_data = self._get_private_key_data()
|
privatekey_data = self._get_private_key_data()
|
||||||
|
if self.return_content:
|
||||||
|
self.privatekey_bytes = privatekey_data
|
||||||
crypto_utils.write_file(module, privatekey_data, 0o600)
|
crypto_utils.write_file(module, privatekey_data, 0o600)
|
||||||
self.changed = True
|
self.changed = True
|
||||||
elif not self.check(module, perms_required=False, ignore_conversion=False):
|
elif not self.check(module, perms_required=False, ignore_conversion=False):
|
||||||
|
@ -340,6 +360,8 @@ class PrivateKeyBase(crypto_utils.OpenSSLObject):
|
||||||
if self.backup:
|
if self.backup:
|
||||||
self.backup_file = module.backup_local(self.path)
|
self.backup_file = module.backup_local(self.path)
|
||||||
privatekey_data = self._get_private_key_data()
|
privatekey_data = self._get_private_key_data()
|
||||||
|
if self.return_content:
|
||||||
|
self.privatekey_bytes = privatekey_data
|
||||||
crypto_utils.write_file(module, privatekey_data, 0o600)
|
crypto_utils.write_file(module, privatekey_data, 0o600)
|
||||||
self.changed = True
|
self.changed = True
|
||||||
|
|
||||||
|
@ -393,6 +415,16 @@ class PrivateKeyBase(crypto_utils.OpenSSLObject):
|
||||||
}
|
}
|
||||||
if self.backup_file:
|
if self.backup_file:
|
||||||
result['backup_file'] = 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
|
return result
|
||||||
|
|
||||||
|
@ -744,6 +776,7 @@ def main():
|
||||||
format=dict(type='str', default='auto_ignore', choices=['pkcs1', 'pkcs8', 'raw', 'auto', 'auto_ignore']),
|
format=dict(type='str', default='auto_ignore', choices=['pkcs1', 'pkcs8', 'raw', 'auto', 'auto_ignore']),
|
||||||
format_mismatch=dict(type='str', default='regenerate', choices=['regenerate', 'convert']),
|
format_mismatch=dict(type='str', default='regenerate', choices=['regenerate', 'convert']),
|
||||||
select_crypto_backend=dict(type='str', choices=['auto', 'pyopenssl', 'cryptography'], default='auto'),
|
select_crypto_backend=dict(type='str', choices=['auto', 'pyopenssl', 'cryptography'], default='auto'),
|
||||||
|
return_content=dict(type='bool', default=False),
|
||||||
),
|
),
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
add_file_common_args=True,
|
add_file_common_args=True,
|
||||||
|
|
|
@ -90,6 +90,12 @@ options:
|
||||||
default: auto
|
default: auto
|
||||||
choices: [ auto, cryptography, pyopenssl ]
|
choices: [ auto, cryptography, pyopenssl ]
|
||||||
version_added: "2.9"
|
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:
|
extends_documentation_fragment:
|
||||||
- files
|
- files
|
||||||
seealso:
|
seealso:
|
||||||
|
@ -171,6 +177,11 @@ backup_file:
|
||||||
returned: changed and if I(backup) is C(yes)
|
returned: changed and if I(backup) is C(yes)
|
||||||
type: str
|
type: str
|
||||||
sample: /path/to/publickey.pem.2019-03-09@11:22~
|
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
|
import os
|
||||||
|
@ -229,6 +240,8 @@ class PublicKey(crypto_utils.OpenSSLObject):
|
||||||
self.privatekey_content = self.privatekey_content.encode('utf-8')
|
self.privatekey_content = self.privatekey_content.encode('utf-8')
|
||||||
self.privatekey_passphrase = module.params['privatekey_passphrase']
|
self.privatekey_passphrase = module.params['privatekey_passphrase']
|
||||||
self.privatekey = None
|
self.privatekey = None
|
||||||
|
self.publickey_bytes = None
|
||||||
|
self.return_content = module.params['return_content']
|
||||||
self.fingerprint = {}
|
self.fingerprint = {}
|
||||||
self.backend = backend
|
self.backend = backend
|
||||||
|
|
||||||
|
@ -270,6 +283,8 @@ class PublicKey(crypto_utils.OpenSSLObject):
|
||||||
if not self.check(module, perms_required=False) or self.force:
|
if not self.check(module, perms_required=False) or self.force:
|
||||||
try:
|
try:
|
||||||
publickey_content = self._create_publickey(module)
|
publickey_content = self._create_publickey(module)
|
||||||
|
if self.return_content:
|
||||||
|
self.publickey_bytes = publickey_content
|
||||||
|
|
||||||
if self.backup:
|
if self.backup:
|
||||||
self.backup_file = module.backup_local(self.path)
|
self.backup_file = module.backup_local(self.path)
|
||||||
|
@ -302,6 +317,8 @@ class PublicKey(crypto_utils.OpenSSLObject):
|
||||||
try:
|
try:
|
||||||
with open(self.path, 'rb') as public_key_fh:
|
with open(self.path, 'rb') as public_key_fh:
|
||||||
publickey_content = public_key_fh.read()
|
publickey_content = public_key_fh.read()
|
||||||
|
if self.return_content:
|
||||||
|
self.publickey_bytes = publickey_content
|
||||||
if self.backend == 'cryptography':
|
if self.backend == 'cryptography':
|
||||||
if self.format == 'OpenSSH':
|
if self.format == 'OpenSSH':
|
||||||
# Read and dump public key. Makes sure that the comment is stripped off.
|
# 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:
|
if self.backup_file:
|
||||||
result['backup_file'] = 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
|
return result
|
||||||
|
|
||||||
|
@ -370,6 +391,7 @@ def main():
|
||||||
privatekey_passphrase=dict(type='str', no_log=True),
|
privatekey_passphrase=dict(type='str', no_log=True),
|
||||||
backup=dict(type='bool', default=False),
|
backup=dict(type='bool', default=False),
|
||||||
select_crypto_backend=dict(type='str', choices=['auto', 'pyopenssl', 'cryptography'], default='auto'),
|
select_crypto_backend=dict(type='str', choices=['auto', 'pyopenssl', 'cryptography'], default='auto'),
|
||||||
|
return_content=dict(type='bool', default=False),
|
||||||
),
|
),
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
add_file_common_args=True,
|
add_file_common_args=True,
|
||||||
|
|
|
@ -62,6 +62,7 @@
|
||||||
provider: ownca
|
provider: ownca
|
||||||
ownca_digest: sha256
|
ownca_digest: sha256
|
||||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
|
return_content: yes
|
||||||
register: ownca_certificate
|
register: ownca_certificate
|
||||||
|
|
||||||
- name: (OwnCA, {{select_crypto_backend}}) Generate ownca certificate (idempotent)
|
- name: (OwnCA, {{select_crypto_backend}}) Generate ownca certificate (idempotent)
|
||||||
|
@ -74,6 +75,7 @@
|
||||||
provider: ownca
|
provider: ownca
|
||||||
ownca_digest: sha256
|
ownca_digest: sha256
|
||||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
|
return_content: yes
|
||||||
register: ownca_certificate_idempotence
|
register: ownca_certificate_idempotence
|
||||||
|
|
||||||
- name: (OwnCA, {{select_crypto_backend}}) Generate ownca certificate (check mode)
|
- name: (OwnCA, {{select_crypto_backend}}) Generate ownca certificate (check mode)
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
path: "{{ output_dir }}/removal_cert.pem"
|
path: "{{ output_dir }}/removal_cert.pem"
|
||||||
state: absent
|
state: absent
|
||||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
|
return_content: yes
|
||||||
register: removal_1
|
register: removal_1
|
||||||
|
|
||||||
- name: "(Removal, {{select_crypto_backend}}) Check that file is gone"
|
- name: "(Removal, {{select_crypto_backend}}) Check that file is gone"
|
||||||
|
@ -48,3 +49,4 @@
|
||||||
- removal_1 is changed
|
- removal_1 is changed
|
||||||
- not removal_1_poststat.stat.exists
|
- not removal_1_poststat.stat.exists
|
||||||
- removal_2 is not changed
|
- removal_2 is not changed
|
||||||
|
- removal_1.certificate is none
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
provider: selfsigned
|
provider: selfsigned
|
||||||
selfsigned_digest: sha256
|
selfsigned_digest: sha256
|
||||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
|
return_content: yes
|
||||||
register: selfsigned_certificate
|
register: selfsigned_certificate
|
||||||
|
|
||||||
- name: (Selfsigned, {{select_crypto_backend}}) Generate selfsigned certificate - idempotency
|
- name: (Selfsigned, {{select_crypto_backend}}) Generate selfsigned certificate - idempotency
|
||||||
|
@ -42,6 +43,7 @@
|
||||||
provider: selfsigned
|
provider: selfsigned
|
||||||
selfsigned_digest: sha256
|
selfsigned_digest: sha256
|
||||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
|
return_content: yes
|
||||||
register: selfsigned_certificate_idempotence
|
register: selfsigned_certificate_idempotence
|
||||||
|
|
||||||
- name: (Selfsigned, {{select_crypto_backend}}) Generate selfsigned certificate (check mode)
|
- name: (Selfsigned, {{select_crypto_backend}}) Generate selfsigned certificate (check mode)
|
||||||
|
|
|
@ -31,6 +31,12 @@
|
||||||
- ownca_certificate.notBefore == ownca_certificate_idempotence.notBefore
|
- ownca_certificate.notBefore == ownca_certificate_idempotence.notBefore
|
||||||
- ownca_certificate.notAfter == ownca_certificate_idempotence.notAfter
|
- 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:
|
- block:
|
||||||
- name: (OwnCA validation, {{select_crypto_backend}}) Validate ownca certificate v2 (test - ownca certificate version == 2)
|
- 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"'
|
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.notBefore == selfsigned_certificate_idempotence.notBefore
|
||||||
- selfsigned_certificate.notAfter == selfsigned_certificate_idempotence.notAfter
|
- 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
|
- name: Make sure that changes in CSR are detected even if private key is specified
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
subject:
|
subject:
|
||||||
commonName: www.ansible.com
|
commonName: www.ansible.com
|
||||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
|
return_content: yes
|
||||||
check_mode: yes
|
check_mode: yes
|
||||||
register: generate_csr_check
|
register: generate_csr_check
|
||||||
|
|
||||||
|
@ -20,6 +21,7 @@
|
||||||
subject:
|
subject:
|
||||||
commonName: www.ansible.com
|
commonName: www.ansible.com
|
||||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
|
return_content: yes
|
||||||
register: generate_csr
|
register: generate_csr
|
||||||
|
|
||||||
- name: Generate CSR (idempotent)
|
- name: Generate CSR (idempotent)
|
||||||
|
@ -29,7 +31,8 @@
|
||||||
subject:
|
subject:
|
||||||
commonName: www.ansible.com
|
commonName: www.ansible.com
|
||||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
register: generate_csr_check_idempotent
|
return_content: yes
|
||||||
|
register: generate_csr_idempotent
|
||||||
|
|
||||||
- name: Generate CSR (idempotent, check mode)
|
- name: Generate CSR (idempotent, check mode)
|
||||||
openssl_csr:
|
openssl_csr:
|
||||||
|
@ -38,8 +41,9 @@
|
||||||
subject:
|
subject:
|
||||||
commonName: www.ansible.com
|
commonName: www.ansible.com
|
||||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
|
return_content: yes
|
||||||
check_mode: yes
|
check_mode: yes
|
||||||
register: generate_csr_check_idempotent_check
|
register: generate_csr_idempotent_check
|
||||||
|
|
||||||
- name: Generate CSR without SAN (check mode)
|
- name: Generate CSR without SAN (check mode)
|
||||||
openssl_csr:
|
openssl_csr:
|
||||||
|
@ -330,6 +334,7 @@
|
||||||
state: absent
|
state: absent
|
||||||
backup: yes
|
backup: yes
|
||||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
|
return_content: yes
|
||||||
register: csr_backup_4
|
register: csr_backup_4
|
||||||
- name: Generate CSR (remove, idempotent)
|
- name: Generate CSR (remove, idempotent)
|
||||||
openssl_csr:
|
openssl_csr:
|
||||||
|
|
|
@ -22,8 +22,16 @@
|
||||||
that:
|
that:
|
||||||
- generate_csr_check is changed
|
- generate_csr_check is changed
|
||||||
- generate_csr is changed
|
- generate_csr is changed
|
||||||
- generate_csr_check_idempotent is not changed
|
- generate_csr_idempotent is not changed
|
||||||
- generate_csr_check_idempotent_check 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)
|
- name: Validate CSR without SAN (check mode, idempotency)
|
||||||
assert:
|
assert:
|
||||||
|
@ -168,6 +176,7 @@
|
||||||
- csr_backup_4.backup_file is string
|
- csr_backup_4.backup_file is string
|
||||||
- csr_backup_5 is not changed
|
- csr_backup_5 is not changed
|
||||||
- csr_backup_5.backup_file is undefined
|
- csr_backup_5.backup_file is undefined
|
||||||
|
- csr_backup_4.csr is none
|
||||||
|
|
||||||
- name: Check CSR with everything
|
- name: Check CSR with everything
|
||||||
assert:
|
assert:
|
||||||
|
|
|
@ -6,12 +6,15 @@
|
||||||
size: 768
|
size: 768
|
||||||
path: '{{ output_dir }}/dh768.pem'
|
path: '{{ output_dir }}/dh768.pem'
|
||||||
select_crypto_backend: "{{ select_crypto_backend }}"
|
select_crypto_backend: "{{ select_crypto_backend }}"
|
||||||
|
return_content: yes
|
||||||
|
register: dhparam
|
||||||
|
|
||||||
- name: "[{{ select_crypto_backend }}] Don't regenerate parameters with no change"
|
- name: "[{{ select_crypto_backend }}] Don't regenerate parameters with no change"
|
||||||
openssl_dhparam:
|
openssl_dhparam:
|
||||||
size: 768
|
size: 768
|
||||||
path: '{{ output_dir }}/dh768.pem'
|
path: '{{ output_dir }}/dh768.pem'
|
||||||
select_crypto_backend: "{{ select_crypto_backend }}"
|
select_crypto_backend: "{{ select_crypto_backend }}"
|
||||||
|
return_content: yes
|
||||||
register: dhparam_changed
|
register: dhparam_changed
|
||||||
|
|
||||||
- name: "[{{ select_crypto_backend }}] Generate parameters with size option"
|
- name: "[{{ select_crypto_backend }}] Generate parameters with size option"
|
||||||
|
@ -87,6 +90,7 @@
|
||||||
state: absent
|
state: absent
|
||||||
backup: yes
|
backup: yes
|
||||||
select_crypto_backend: "{{ select_crypto_backend }}"
|
select_crypto_backend: "{{ select_crypto_backend }}"
|
||||||
|
return_content: yes
|
||||||
register: dhparam_backup_4
|
register: dhparam_backup_4
|
||||||
- name: "[{{ select_crypto_backend }}] Generate params (remove, idempotent)"
|
- name: "[{{ select_crypto_backend }}] Generate params (remove, idempotent)"
|
||||||
openssl_dhparam:
|
openssl_dhparam:
|
||||||
|
|
|
@ -31,6 +31,12 @@
|
||||||
- dhparam_changed_to_512 is changed
|
- dhparam_changed_to_512 is changed
|
||||||
- dhparam_changed_force 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"
|
- name: "[{{ select_crypto_backend }}] Verify that broken params will be regenerated"
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
|
@ -49,3 +55,4 @@
|
||||||
- dhparam_backup_4.backup_file is string
|
- dhparam_backup_4.backup_file is string
|
||||||
- dhparam_backup_5 is not changed
|
- dhparam_backup_5 is not changed
|
||||||
- dhparam_backup_5.backup_file is undefined
|
- dhparam_backup_5.backup_file is undefined
|
||||||
|
- dhparam_backup_4.dhparams is none
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
privatekey_path: "{{ output_dir }}/ansible_pkey.pem"
|
privatekey_path: "{{ output_dir }}/ansible_pkey.pem"
|
||||||
certificate_path: "{{ output_dir }}/ansible.crt"
|
certificate_path: "{{ output_dir }}/ansible.crt"
|
||||||
state: present
|
state: present
|
||||||
|
return_content: yes
|
||||||
register: p12_standard
|
register: p12_standard
|
||||||
|
|
||||||
- name: 'Generate PKCS#12 file again, idempotency'
|
- name: 'Generate PKCS#12 file again, idempotency'
|
||||||
|
@ -60,8 +61,20 @@
|
||||||
privatekey_path: "{{ output_dir }}/ansible_pkey.pem"
|
privatekey_path: "{{ output_dir }}/ansible_pkey.pem"
|
||||||
certificate_path: "{{ output_dir }}/ansible.crt"
|
certificate_path: "{{ output_dir }}/ansible.crt"
|
||||||
state: present
|
state: present
|
||||||
|
return_content: yes
|
||||||
register: p12_standard_idempotency
|
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)'
|
- name: 'Generate PKCS#12 file (force)'
|
||||||
openssl_pkcs12:
|
openssl_pkcs12:
|
||||||
path: "{{ output_dir }}/ansible.p12"
|
path: "{{ output_dir }}/ansible.p12"
|
||||||
|
@ -216,6 +229,7 @@
|
||||||
path: "{{ output_dir }}/ansible_backup.p12"
|
path: "{{ output_dir }}/ansible_backup.p12"
|
||||||
state: absent
|
state: absent
|
||||||
backup: yes
|
backup: yes
|
||||||
|
return_content: yes
|
||||||
register: p12_backup_4
|
register: p12_backup_4
|
||||||
- name: 'Generate PKCS#12 file (remove, idempotent)'
|
- name: 'Generate PKCS#12 file (remove, idempotent)'
|
||||||
openssl_pkcs12:
|
openssl_pkcs12:
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
---
|
||||||
- name: 'Validate PKCS#12'
|
- name: 'Validate PKCS#12'
|
||||||
command: "openssl pkcs12 -info -in {{ output_dir }}/ansible.p12 -nodes -passin pass:''"
|
command: "openssl pkcs12 -info -in {{ output_dir }}/ansible.p12 -nodes -passin pass:''"
|
||||||
register: p12
|
register: p12
|
||||||
|
@ -53,3 +54,4 @@
|
||||||
- p12_backup_4.backup_file is string
|
- p12_backup_4.backup_file is string
|
||||||
- p12_backup_5 is not changed
|
- p12_backup_5 is not changed
|
||||||
- p12_backup_5.backup_file is undefined
|
- p12_backup_5.backup_file is undefined
|
||||||
|
- p12_backup_4.pkcs12 is none
|
||||||
|
|
|
@ -3,6 +3,15 @@
|
||||||
openssl_privatekey:
|
openssl_privatekey:
|
||||||
path: '{{ output_dir }}/privatekey1.pem'
|
path: '{{ output_dir }}/privatekey1.pem'
|
||||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
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
|
- name: Generate privatekey2 - size 2048
|
||||||
openssl_privatekey:
|
openssl_privatekey:
|
||||||
|
@ -27,6 +36,15 @@
|
||||||
state: absent
|
state: absent
|
||||||
path: '{{ output_dir }}/privatekey4.pem'
|
path: '{{ output_dir }}/privatekey4.pem'
|
||||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
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
|
- name: Generate privatekey5 - standard - with passphrase
|
||||||
openssl_privatekey:
|
openssl_privatekey:
|
||||||
|
@ -381,30 +399,69 @@
|
||||||
type: X448
|
type: X448
|
||||||
format: raw
|
format: raw
|
||||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
|
return_content: yes
|
||||||
register: privatekey_fmt_2_step_3
|
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)
|
- name: Generate privatekey_fmt_2 - raw format (idempotent)
|
||||||
openssl_privatekey:
|
openssl_privatekey:
|
||||||
path: '{{ output_dir }}/privatekey_fmt_2.pem'
|
path: '{{ output_dir }}/privatekey_fmt_2.pem'
|
||||||
type: X448
|
type: X448
|
||||||
format: raw
|
format: raw
|
||||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
|
return_content: yes
|
||||||
register: privatekey_fmt_2_step_4
|
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)
|
- name: Generate privatekey_fmt_2 - auto format (ignore)
|
||||||
openssl_privatekey:
|
openssl_privatekey:
|
||||||
path: '{{ output_dir }}/privatekey_fmt_2.pem'
|
path: '{{ output_dir }}/privatekey_fmt_2.pem'
|
||||||
type: X448
|
type: X448
|
||||||
format: auto_ignore
|
format: auto_ignore
|
||||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
|
return_content: yes
|
||||||
register: privatekey_fmt_2_step_5
|
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)
|
- name: Generate privatekey_fmt_2 - auto format (no ignore)
|
||||||
openssl_privatekey:
|
openssl_privatekey:
|
||||||
path: '{{ output_dir }}/privatekey_fmt_2.pem'
|
path: '{{ output_dir }}/privatekey_fmt_2.pem'
|
||||||
type: X448
|
type: X448
|
||||||
format: auto
|
format: auto
|
||||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
|
return_content: yes
|
||||||
register: privatekey_fmt_2_step_6
|
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", ">=")'
|
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)
|
- 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/'"
|
shell: "openssl rsa -noout -text -in {{ output_dir }}/privatekey1.pem | grep Private | sed 's/\\(RSA *\\)*Private-Key: (\\(.*\\) bit.*)/\\2/'"
|
||||||
register: privatekey1
|
register: privatekey1
|
||||||
|
@ -39,6 +47,13 @@
|
||||||
that:
|
that:
|
||||||
- privatekey4.stat.exists == False
|
- 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)
|
- 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/'"
|
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'
|
path: '{{ output_dir }}/publickey.pub'
|
||||||
privatekey_path: '{{ output_dir }}/privatekey.pem'
|
privatekey_path: '{{ output_dir }}/privatekey.pem'
|
||||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
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
|
- name: Generate publickey - OpenSSH format
|
||||||
openssl_publickey:
|
openssl_publickey:
|
||||||
|
@ -38,6 +48,16 @@
|
||||||
path: '{{ output_dir }}/publickey2.pub'
|
path: '{{ output_dir }}/publickey2.pub'
|
||||||
privatekey_path: '{{ output_dir }}/privatekey.pem'
|
privatekey_path: '{{ output_dir }}/privatekey.pem'
|
||||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
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
|
- name: Generate privatekey3 - with passphrase
|
||||||
openssl_privatekey:
|
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)
|
- name: Validate public key (test - privatekey modulus)
|
||||||
shell: 'openssl rsa -noout -modulus -in {{ output_dir }}/privatekey.pem'
|
shell: 'openssl rsa -noout -modulus -in {{ output_dir }}/privatekey.pem'
|
||||||
register: privatekey_modulus
|
register: privatekey_modulus
|
||||||
|
@ -45,6 +53,13 @@
|
||||||
that:
|
that:
|
||||||
- publickey2.stat.exists == False
|
- 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)
|
- name: Validate publickey3 (test - privatekey modulus)
|
||||||
shell: 'openssl rsa -noout -modulus -in {{ output_dir }}/privatekey3.pem -passin pass:ansible'
|
shell: 'openssl rsa -noout -modulus -in {{ output_dir }}/privatekey3.pem -passin pass:ansible'
|
||||||
|
|
Loading…
Reference in a new issue