Replace % and str.format() with f-strings (#875)

* Replace % and str.format() with f-strings.

* Apply suggestions from review.
This commit is contained in:
Felix Fontein
2025-05-01 11:50:10 +02:00
committed by GitHub
parent d8f838c365
commit 641e63b08c
86 changed files with 544 additions and 1036 deletions

View File

@@ -32,9 +32,7 @@ class PrivateKeyModule:
try:
data = base64.b64decode(module.params["content"])
except Exception as e:
module.fail_json(
msg="Cannot decode Base64 encoded data: {0}".format(e)
)
module.fail_json(msg=f"Cannot decode Base64 encoded data: {e}")
else:
data = to_bytes(module.params["content"])
module_backend.set_existing(data)

View File

@@ -54,9 +54,7 @@ from ansible_collections.community.crypto.plugins.plugin_utils.gnupg import (
def gpg_fingerprint(input):
if not isinstance(input, string_types):
raise AnsibleFilterError(
"The input for the community.crypto.gpg_fingerprint filter must be a string; got {type} instead".format(
type=type(input)
)
f"The input for the community.crypto.gpg_fingerprint filter must be a string; got {type(input)} instead"
)
try:
gpg = PluginGPGRunner()

View File

@@ -292,19 +292,16 @@ def openssl_csr_info_filter(data, name_encoding="ignore"):
"""Extract information from X.509 PEM certificate."""
if not isinstance(data, string_types):
raise AnsibleFilterError(
"The community.crypto.openssl_csr_info input must be a text type, not %s"
% type(data)
f"The community.crypto.openssl_csr_info input must be a text type, not {type(data)}"
)
if not isinstance(name_encoding, string_types):
raise AnsibleFilterError(
"The name_encoding option must be of a text type, not %s"
% type(name_encoding)
f"The name_encoding option must be of a text type, not {type(name_encoding)}"
)
name_encoding = to_native(name_encoding)
if name_encoding not in ("ignore", "idna", "unicode"):
raise AnsibleFilterError(
'The name_encoding option must be one of the values "ignore", "idna", or "unicode", not "%s"'
% name_encoding
f'The name_encoding option must be one of the values "ignore", "idna", or "unicode", not "{name_encoding}"'
)
module = FilterModuleMock({"name_encoding": name_encoding})

View File

@@ -167,17 +167,15 @@ def openssl_privatekey_info_filter(
"""Extract information from X.509 PEM certificate."""
if not isinstance(data, string_types):
raise AnsibleFilterError(
"The community.crypto.openssl_privatekey_info input must be a text type, not %s"
% type(data)
f"The community.crypto.openssl_privatekey_info input must be a text type, not {type(data)}"
)
if passphrase is not None and not isinstance(passphrase, string_types):
raise AnsibleFilterError(
"The passphrase option must be a text type, not %s" % type(passphrase)
f"The passphrase option must be a text type, not {type(passphrase)}"
)
if not isinstance(return_private_key_data, bool):
raise AnsibleFilterError(
"The return_private_key_data option must be a boolean, not %s"
% type(return_private_key_data)
f"The return_private_key_data option must be a boolean, not {type(return_private_key_data)}"
)
module = FilterModuleMock({})

View File

@@ -142,8 +142,7 @@ def openssl_publickey_info_filter(data):
"""Extract information from OpenSSL PEM public key."""
if not isinstance(data, string_types):
raise AnsibleFilterError(
"The community.crypto.openssl_publickey_info input must be a text type, not %s"
% type(data)
f"The community.crypto.openssl_publickey_info input must be a text type, not {type(data)}"
)
module = FilterModuleMock({})

View File

@@ -50,9 +50,7 @@ from ansible_collections.community.crypto.plugins.module_utils.serial import (
def parse_serial_filter(input):
if not isinstance(input, string_types):
raise AnsibleFilterError(
"The input for the community.crypto.parse_serial filter must be a string; got {type} instead".format(
type=type(input)
)
f"The input for the community.crypto.parse_serial filter must be a string; got {type(input)} instead"
)
try:
return parse_serial(to_native(input))

View File

@@ -50,8 +50,7 @@ def split_pem_filter(data):
"""Split PEM file."""
if not isinstance(data, string_types):
raise AnsibleFilterError(
"The community.crypto.split_pem input must be a text type, not %s"
% type(data)
f"The community.crypto.split_pem input must be a text type, not {type(data)}"
)
data = to_text(data)

View File

@@ -48,9 +48,7 @@ from ansible_collections.community.crypto.plugins.module_utils.serial import to_
def to_serial_filter(input):
if not isinstance(input, integer_types):
raise AnsibleFilterError(
"The input for the community.crypto.to_serial filter must be an integer; got {type} instead".format(
type=type(input)
)
f"The input for the community.crypto.to_serial filter must be an integer; got {type(input)} instead"
)
if input < 0:
raise AnsibleFilterError(

View File

@@ -326,19 +326,16 @@ def x509_certificate_info_filter(data, name_encoding="ignore"):
"""Extract information from X.509 PEM certificate."""
if not isinstance(data, string_types):
raise AnsibleFilterError(
"The community.crypto.x509_certificate_info input must be a text type, not %s"
% type(data)
f"The community.crypto.x509_certificate_info input must be a text type, not {type(data)}"
)
if not isinstance(name_encoding, string_types):
raise AnsibleFilterError(
"The name_encoding option must be of a text type, not %s"
% type(name_encoding)
f"The name_encoding option must be of a text type, not {type(name_encoding)}"
)
name_encoding = to_native(name_encoding)
if name_encoding not in ("ignore", "idna", "unicode"):
raise AnsibleFilterError(
'The name_encoding option must be one of the values "ignore", "idna", or "unicode", not "%s"'
% name_encoding
f'The name_encoding option must be one of the values "ignore", "idna", or "unicode", not "{name_encoding}"'
)
module = FilterModuleMock({"name_encoding": name_encoding})

View File

@@ -177,24 +177,20 @@ def x509_crl_info_filter(data, name_encoding="ignore", list_revoked_certificates
"""Extract information from X.509 PEM certificate."""
if not isinstance(data, string_types):
raise AnsibleFilterError(
"The community.crypto.x509_crl_info input must be a text type, not %s"
% type(data)
f"The community.crypto.x509_crl_info input must be a text type, not {type(data)}"
)
if not isinstance(name_encoding, string_types):
raise AnsibleFilterError(
"The name_encoding option must be of a text type, not %s"
% type(name_encoding)
f"The name_encoding option must be of a text type, not {type(name_encoding)}"
)
if not isinstance(list_revoked_certificates, bool):
raise AnsibleFilterError(
"The list_revoked_certificates option must be a boolean, not %s"
% type(list_revoked_certificates)
f"The list_revoked_certificates option must be a boolean, not {type(list_revoked_certificates)}"
)
name_encoding = to_native(name_encoding)
if name_encoding not in ("ignore", "idna", "unicode"):
raise AnsibleFilterError(
'The name_encoding option must be one of the values "ignore", "idna", or "unicode", not "%s"'
% name_encoding
f'The name_encoding option must be one of the values "ignore", "idna", or "unicode", not "{name_encoding}"'
)
data = to_bytes(data)

View File

@@ -66,7 +66,7 @@ def _decode_retry(module, response, info, retry_count):
if retry_count >= RETRY_COUNT:
raise ACMEProtocolException(
module,
msg="Giving up after {retry} retries".format(retry=RETRY_COUNT),
msg=f"Giving up after {RETRY_COUNT} retries",
info=info,
response=response,
)
@@ -77,8 +77,7 @@ def _decode_retry(module, response, info, retry_count):
except (TypeError, ValueError):
retry_after = 10
module.log(
"Retrieved a %s HTTP status on %s, retrying in %s seconds"
% (format_http_status(info["status"]), info["url"], retry_after)
f"Retrieved a {format_http_status(info['status'])} HTTP status on {info['url']}, retrying in {retry_after} seconds"
)
time.sleep(retry_after)
@@ -94,9 +93,7 @@ def _assert_fetch_url_success(
allow_server_error=True,
):
if info["status"] < 0:
raise NetworkException(
msg="Failure downloading %s, %s" % (info["url"], info["msg"])
)
raise NetworkException(msg=f"Failure downloading {info['url']}, {info['msg']}")
if (
(300 <= info["status"] < 400 and not allow_redirect)
@@ -169,16 +166,12 @@ class ACMEDirectory:
continue
if info["status"] not in (200, 204):
raise NetworkException(
"Failed to get replay-nonce, got status {0}".format(
format_http_status(info["status"])
)
f"Failed to get replay-nonce, got status {format_http_status(info['status'])}"
)
if "replay-nonce" in info:
return info["replay-nonce"]
self.module.log(
"HEAD to {0} did return status {1}, but no replay-nonce header!".format(
url, format_http_status(info["status"])
)
f"HEAD to {url} did return status {format_http_status(info['status'])}, but no replay-nonce header!"
)
if retry_count >= 5:
raise ACMEProtocolException(
@@ -228,9 +221,7 @@ class ACMEClient:
passphrase=self.account_key_passphrase,
)
except KeyParsingError as e:
raise ModuleFailException(
"Error while parsing account key: {msg}".format(msg=e.msg)
)
raise ModuleFailException(f"Error while parsing account key: {e.msg}")
self.account_jwk = self.account_key_data["jwk"]
self.account_jws_header = {
"alg": self.account_key_data["alg"],
@@ -276,7 +267,7 @@ class ACMEClient:
protected64 = nopad_b64(self.module.jsonify(protected).encode("utf8"))
except Exception as e:
raise ModuleFailException(
"Failed to encode payload / headers as JSON: {0}".format(e)
f"Failed to encode payload / headers as JSON: {e}"
)
return self.backend.sign(payload64, protected64, key_data)
@@ -287,16 +278,13 @@ class ACMEClient:
"""
if self._debug:
with open("acme.log", "ab") as f:
f.write(
"[{0}] {1}\n".format(
datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%s"), msg
).encode("utf-8")
)
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%s")
f.write(f"[{timestamp}] {msg}\n".encode("utf-8"))
if data is not None:
f.write(
"{0}\n\n".format(
json.dumps(data, indent=2, sort_keys=True)
).encode("utf-8")
f"{json.dumps(data, indent=2, sort_keys=True)}\n\n".encode(
"utf-8"
)
)
def send_signed_request(
@@ -389,9 +377,7 @@ class ACMEClient:
result = content
except ValueError:
raise NetworkException(
"Failed to parse the ACME response: {0} {1}".format(
url, content
)
f"Failed to parse the ACME response: {url} {content}"
)
else:
result = content
@@ -471,9 +457,7 @@ class ACMEClient:
parsed_json_result = True
except ValueError:
raise NetworkException(
"Failed to parse the ACME response: {0} {1}".format(
uri, content
)
f"Failed to parse the ACME response: {uri} {content}"
)
else:
result = content
@@ -513,9 +497,7 @@ class ACMEClient:
cert_filename=cert_filename,
cert_content=cert_content,
)
url = "{base}/{cert_id}".format(
base=self.directory.directory["renewalInfo"].rstrip("/"), cert_id=cert_id
)
url = f"{self.directory.directory['renewalInfo'].rstrip('/')}/{cert_id}"
data, info = self.get_request(
url, parse_json_result=True, fail_on_error=True, get_only=True
@@ -593,31 +575,25 @@ def create_backend(module, needs_acme_v2=True):
if CRYPTOGRAPHY_VERSION is None:
msg = missing_required_lib("cryptography")
else:
msg = "Unexpected error while preparing cryptography: {0}".format(
CRYPTOGRAPHY_ERROR.splitlines()[-1]
)
msg = f"Unexpected error while preparing cryptography: {CRYPTOGRAPHY_ERROR.splitlines()[-1]}"
module.fail_json(msg=msg, exception=CRYPTOGRAPHY_ERROR)
if not HAS_CURRENT_CRYPTOGRAPHY:
# We succeeded importing cryptography, but its version is too old.
mrl = missing_required_lib(
f"cryptography >= {CRYPTOGRAPHY_MINIMAL_VERSION}"
)
module.fail_json(
msg="Found cryptography, but only version {0}. {1}".format(
CRYPTOGRAPHY_VERSION,
missing_required_lib(
"cryptography >= {0}".format(CRYPTOGRAPHY_MINIMAL_VERSION)
),
)
msg=f"Found cryptography, but only version {CRYPTOGRAPHY_VERSION}. {mrl}"
)
module.debug(
"Using cryptography backend (library version {0})".format(
CRYPTOGRAPHY_VERSION
)
f"Using cryptography backend (library version {CRYPTOGRAPHY_VERSION})"
)
module_backend = CryptographyBackend(module)
elif backend == "openssl":
module.debug("Using OpenSSL binary backend")
module_backend = OpenSSLCLIBackend(module)
else:
module.fail_json(msg='Unknown crypto backend "{0}"!'.format(backend))
module.fail_json(msg=f'Unknown crypto backend "{backend}"!')
# Check common module parameters
if not module.params["validate_certs"]:

View File

@@ -91,14 +91,12 @@ class CryptographyChainMatcher(ChainMatcher):
except Exception:
if criterium_idx is None:
module.warn(
"Criterium has invalid {0} value. Ignoring criterium.".format(
name
)
f"Criterium has invalid {name} value. Ignoring criterium."
)
else:
module.warn(
"Criterium {0} in select_chain has invalid {1} value. "
"Ignoring criterium.".format(criterium_idx, name)
f"Criterium {criterium_idx} in select_chain has invalid {name} value. "
"Ignoring criterium."
)
return None
@@ -181,9 +179,7 @@ class CryptographyChainMatcher(ChainMatcher):
if matches:
return True
except Exception as e:
self.module.warn(
"Error while loading certificate {0}: {1}".format(cert, e)
)
self.module.warn(f"Error while loading certificate {cert}: {e}")
return False
@@ -211,7 +207,7 @@ class CryptographyBackend(CryptoBackend):
backend=_cryptography_backend,
)
except Exception as e:
raise KeyParsingError("error while loading key: {0}".format(e))
raise KeyParsingError(f"error while loading key: {e}")
if isinstance(key, cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey):
pk = key.public_key().public_numbers()
return {
@@ -250,9 +246,7 @@ class CryptographyBackend(CryptoBackend):
point_size = 66
curve = "P-521"
else:
raise KeyParsingError(
"unknown elliptic curve: {0}".format(pk.curve.name)
)
raise KeyParsingError(f"unknown elliptic curve: {pk.curve.name}")
num_bytes = (bits + 7) // 8
return {
"key_obj": key,
@@ -268,10 +262,10 @@ class CryptographyBackend(CryptoBackend):
"point_size": point_size,
}
else:
raise KeyParsingError('unknown key type "{0}"'.format(type(key)))
raise KeyParsingError(f'unknown key type "{type(key)}"')
def sign(self, payload64, protected64, key_data):
sign_payload = "{0}.{1}".format(protected64, payload64).encode("utf8")
sign_payload = f"{protected64}.{payload64}".encode("utf8")
if "mac_obj" in key_data:
mac = key_data["mac_obj"]()
mac.update(sign_payload)
@@ -320,16 +314,12 @@ class CryptographyBackend(CryptoBackend):
hashbytes = 64
else:
raise BackendException(
"Unsupported MAC key algorithm for cryptography backend: {0}".format(
alg
)
f"Unsupported MAC key algorithm for cryptography backend: {alg}"
)
key_bytes = base64.urlsafe_b64decode(key)
if len(key_bytes) < hashbytes:
raise BackendException(
"{0} key must be at least {1} bytes long (after Base64 decoding)".format(
alg, hashbytes
)
f"{alg} key must be at least {hashbytes} bytes long (after Base64 decoding)"
)
return {
"mac_obj": lambda: cryptography.hazmat.primitives.hmac.HMAC(
@@ -382,7 +372,7 @@ class CryptographyBackend(CryptoBackend):
add_identifier(("ip", name.value.compressed))
else:
raise BackendException(
"Found unsupported SAN identifier {0}".format(name)
f"Found unsupported SAN identifier {name}"
)
return result
@@ -425,10 +415,8 @@ class CryptographyBackend(CryptoBackend):
)
except Exception as e:
if cert_filename is None:
raise BackendException("Cannot parse certificate: {0}".format(e))
raise BackendException(
"Cannot parse certificate {0}: {1}".format(cert_filename, e)
)
raise BackendException(f"Cannot parse certificate: {e}")
raise BackendException(f"Cannot parse certificate {cert_filename}: {e}")
if now is None:
now = self.get_now()
@@ -460,10 +448,8 @@ class CryptographyBackend(CryptoBackend):
)
except Exception as e:
if cert_filename is None:
raise BackendException("Cannot parse certificate: {0}".format(e))
raise BackendException(
"Cannot parse certificate {0}: {1}".format(cert_filename, e)
)
raise BackendException(f"Cannot parse certificate: {e}")
raise BackendException(f"Cannot parse certificate {cert_filename}: {e}")
ski = None
try:

View File

@@ -44,7 +44,7 @@ _OPENSSL_ENVIRONMENT_UPDATE = dict(LANG="C", LC_ALL="C", LC_MESSAGES="C", LC_CTY
def _extract_date(out_text, name, cert_filename_suffix=""):
try:
date_str = re.search(r"\s+%s\s*:\s+(.*)" % name, out_text).group(1)
date_str = re.search(rf"\s+{name}\s*:\s+(.*)", out_text).group(1)
# For some reason Python's strptime() does not return any timezone information,
# even though the information is there and a supported timezone for all supported
# Python implementations (GMT). So we have to modify the datetime object by
@@ -53,12 +53,10 @@ def _extract_date(out_text, name, cert_filename_suffix=""):
datetime.datetime.strptime(date_str, "%b %d %H:%M:%S %Y %Z")
)
except AttributeError:
raise BackendException(
"No '{0}' date found{1}".format(name, cert_filename_suffix)
)
raise BackendException(f"No '{name}' date found{cert_filename_suffix}")
except ValueError as exc:
raise BackendException(
"Failed to parse '{0}' date{1}: {2}".format(name, cert_filename_suffix, exc)
f"Failed to parse '{name}' date{cert_filename_suffix}: {exc}"
)
@@ -67,20 +65,18 @@ def _decode_octets(octets_text):
def _extract_octets(out_text, name, required=True, potential_prefixes=None):
regexp = r"\s+%s:\s*\n\s+%s([A-Fa-f0-9]{2}(?::[A-Fa-f0-9]{2})*)\s*\n" % (
name,
(
("(?:%s)" % "|".join(re.escape(pp) for pp in potential_prefixes))
if potential_prefixes
else ""
),
part = (
f"(?:{'|'.join(re.escape(pp) for pp in potential_prefixes)})"
if potential_prefixes
else ""
)
regexp = rf"\s+{name}:\s*\n\s+{part}([A-Fa-f0-9]{{2}}(?::[A-Fa-f0-9]{{2}})*)\s*\n"
match = re.search(regexp, out_text, re.MULTILINE | re.DOTALL)
if match is not None:
return _decode_octets(match.group(1))
if not required:
return None
raise BackendException("No '{0}' octet string found".format(name))
raise BackendException(f"No '{name}' octet string found")
class OpenSSLCLIBackend(CryptoBackend):
@@ -111,7 +107,7 @@ class OpenSSLCLIBackend(CryptoBackend):
except Exception:
pass
raise KeyParsingError(
"failed to create temporary content file: %s" % to_native(err),
f"failed to create temporary content file: {err}",
exception=traceback.format_exc(),
)
f.close()
@@ -132,7 +128,7 @@ class OpenSSLCLIBackend(CryptoBackend):
# FIXME: add some kind of auto-detection
account_key_type = "rsa"
if account_key_type not in ("rsa", "ec"):
raise KeyParsingError('unknown key type "%s"' % account_key_type)
raise KeyParsingError(f'unknown key type "{account_key_type}"')
openssl_keydump_cmd = [
self.openssl_binary,
@@ -149,9 +145,7 @@ class OpenSSLCLIBackend(CryptoBackend):
)
if rc != 0:
raise BackendException(
"Error while running {cmd}: {stderr}".format(
cmd=" ".join(openssl_keydump_cmd), stderr=to_text(err)
)
f"Error while running {' '.join(openssl_keydump_cmd)}: {to_text(err)}"
)
out_text = to_text(out, errors="surrogate_or_strict")
@@ -166,9 +160,9 @@ class OpenSSLCLIBackend(CryptoBackend):
pub_exp = re.search(
r"\npublicExponent: ([0-9]+)", out_text, re.MULTILINE | re.DOTALL
).group(1)
pub_exp = "{0:x}".format(int(pub_exp))
pub_exp = f"{int(pub_exp):x}"
if len(pub_exp) % 2:
pub_exp = "0{0}".format(pub_exp)
pub_exp = f"0{pub_exp}"
return {
"key_file": key_file,
@@ -214,12 +208,12 @@ class OpenSSLCLIBackend(CryptoBackend):
curve = "P-521"
else:
raise KeyParsingError(
"unknown elliptic curve: %s / %s" % (asn1_oid_curve, nist_curve)
f"unknown elliptic curve: {asn1_oid_curve} / {nist_curve}"
)
num_bytes = (bits + 7) // 8
if len(pub_hex) != 2 * num_bytes:
raise KeyParsingError(
"bad elliptic curve point (%s / %s)" % (asn1_oid_curve, nist_curve)
f"bad elliptic curve point ({asn1_oid_curve} / {nist_curve})"
)
return {
"key_file": key_file,
@@ -236,7 +230,7 @@ class OpenSSLCLIBackend(CryptoBackend):
}
def sign(self, payload64, protected64, key_data):
sign_payload = "{0}.{1}".format(protected64, payload64).encode("utf8")
sign_payload = f"{protected64}.{payload64}".encode("utf8")
if key_data["type"] == "hmac":
hex_key = to_native(
binascii.hexlify(base64.urlsafe_b64decode(key_data["jwk"]["k"]))
@@ -245,7 +239,7 @@ class OpenSSLCLIBackend(CryptoBackend):
"-mac",
"hmac",
"-macopt",
"hexkey:{0}".format(hex_key),
f"hexkey:{hex_key}",
"-binary",
]
else:
@@ -253,7 +247,7 @@ class OpenSSLCLIBackend(CryptoBackend):
openssl_sign_cmd = [
self.openssl_binary,
"dgst",
"-{0}".format(key_data["hash"]),
f"-{key_data['hash']}",
] + cmd_postfix
rc, out, err = self.module.run_command(
@@ -265,9 +259,7 @@ class OpenSSLCLIBackend(CryptoBackend):
)
if rc != 0:
raise BackendException(
"Error while running {cmd}: {stderr}".format(
cmd=" ".join(openssl_sign_cmd), stderr=to_text(err)
)
f"Error while running {' '.join(openssl_sign_cmd)}: {to_text(err)}"
)
if key_data["type"] == "ec":
@@ -279,14 +271,13 @@ class OpenSSLCLIBackend(CryptoBackend):
)
expected_len = 2 * key_data["point_size"]
sig = re.findall(
r"prim:\s+INTEGER\s+:([0-9A-F]{1,%s})\n" % expected_len,
rf"prim:\s+INTEGER\s+:([0-9A-F]{{1,{expected_len}}})\n",
to_text(der_out, errors="surrogate_or_strict"),
)
if len(sig) != 2:
der_output = to_text(der_out, errors="surrogate_or_strict")
raise BackendException(
"failed to generate Elliptic Curve signature; cannot parse DER output: {0}".format(
to_text(der_out, errors="surrogate_or_strict")
)
f"failed to generate Elliptic Curve signature; cannot parse DER output: {der_output}"
)
sig[0] = (expected_len - len(sig[0])) * "0" + sig[0]
sig[1] = (expected_len - len(sig[1])) * "0" + sig[1]
@@ -311,14 +302,12 @@ class OpenSSLCLIBackend(CryptoBackend):
hashbytes = 64
else:
raise BackendException(
"Unsupported MAC key algorithm for OpenSSL backend: {0}".format(alg)
f"Unsupported MAC key algorithm for OpenSSL backend: {alg}"
)
key_bytes = base64.urlsafe_b64decode(key)
if len(key_bytes) < hashbytes:
raise BackendException(
"{0} key must be at least {1} bytes long (after Base64 decoding)".format(
alg, hashbytes
)
f"{alg} key must be at least {hashbytes} bytes long (after Base64 decoding)"
)
return {
"type": "hmac",
@@ -370,9 +359,7 @@ class OpenSSLCLIBackend(CryptoBackend):
)
if rc != 0:
raise BackendException(
"Error while running {cmd}: {stderr}".format(
cmd=" ".join(openssl_csr_cmd), stderr=to_text(err)
)
f"Error while running {' '.join(openssl_csr_cmd)}: {to_text(err)}"
)
identifiers = set()
@@ -404,9 +391,7 @@ class OpenSSLCLIBackend(CryptoBackend):
elif san.lower().startswith("ip address:"):
add_identifier(("ip", self._normalize_ip(san[11:])))
else:
raise BackendException(
'Found unsupported SAN identifier "{0}"'.format(san)
)
raise BackendException(f'Found unsupported SAN identifier "{san}"')
return result
def get_csr_identifiers(self, csr_filename=None, csr_content=None):
@@ -438,7 +423,7 @@ class OpenSSLCLIBackend(CryptoBackend):
elif cert_filename is not None:
if not os.path.exists(cert_filename):
return -1
cert_filename_suffix = " in {0}".format(cert_filename)
cert_filename_suffix = f" in {cert_filename}"
else:
return -1
@@ -459,9 +444,7 @@ class OpenSSLCLIBackend(CryptoBackend):
)
if rc != 0:
raise BackendException(
"Error while running {cmd}: {stderr}".format(
cmd=" ".join(openssl_cert_cmd), stderr=to_text(err)
)
f"Error while running {' '.join(openssl_cert_cmd)}: {to_text(err)}"
)
out_text = to_text(out, errors="surrogate_or_strict")
@@ -489,7 +472,7 @@ class OpenSSLCLIBackend(CryptoBackend):
filename = cert_filename
data = None
if cert_filename is not None:
cert_filename_suffix = " in {0}".format(cert_filename)
cert_filename_suffix = f" in {cert_filename}"
else:
filename = "/dev/stdin"
data = to_bytes(cert_content)
@@ -512,9 +495,7 @@ class OpenSSLCLIBackend(CryptoBackend):
)
if rc != 0:
raise BackendException(
"Error while running {cmd}: {stderr}".format(
cmd=" ".join(openssl_cert_cmd), stderr=to_text(err)
)
f"Error while running {' '.join(openssl_cert_cmd)}: {to_text(err)}"
)
out_text = to_text(out, errors="surrogate_or_strict")

View File

@@ -53,15 +53,13 @@ def _reduce_fractional_digits(timestamp_str):
# RFC 3339 (https://www.rfc-editor.org/info/rfc3339)
m = _FRACTIONAL_MATCHER.match(timestamp_str)
if not m:
raise BackendException(
"Cannot parse ISO 8601 timestamp {0!r}".format(timestamp_str)
)
raise BackendException(f"Cannot parse ISO 8601 timestamp {timestamp_str!r}")
timestamp, fractional, timezone = m.groups()
if len(fractional) > 7:
# Python does not support anything smaller than microseconds
# (Golang supports nanoseconds, Boulder often emits more fractional digits, which Python chokes on)
fractional = fractional[:7]
return "%s%s%s" % (timestamp, fractional, timezone)
return f"{timestamp}{fractional}{timezone}"
def _parse_acme_timestamp(timestamp_str, with_timezone):
@@ -87,9 +85,7 @@ def _parse_acme_timestamp(timestamp_str, with_timezone):
if with_timezone
else remove_timezone(result)
)
raise BackendException(
"Cannot parse ISO 8601 timestamp {0!r}".format(timestamp_str)
)
raise BackendException(f"Cannot parse ISO 8601 timestamp {timestamp_str!r}")
@six.add_metaclass(abc.ABCMeta)

View File

@@ -62,7 +62,7 @@ class ACMECertificateClient:
raise ModuleFailException(msg="Account does not exist or is deactivated.")
if self.csr is not None and not os.path.exists(self.csr):
raise ModuleFailException("CSR %s not found" % (self.csr))
raise ModuleFailException(f"CSR {self.csr} not found")
# Extract list of identifiers from CSR
if self.csr is not None or self.csr_content is not None:
@@ -84,9 +84,7 @@ class ACMECertificateClient:
)
except ValueError as exc:
self.module.warn(
"Error while parsing criterium: {error}. Ignoring criterium.".format(
error=exc
)
f"Error while parsing criterium: {exc}. Ignoring criterium."
)
return select_chain_matcher
@@ -154,17 +152,13 @@ class ACMECertificateClient:
for authz in order.authorizations.values():
if authz.status not in ("valid", "pending"):
bad_authzs.append(
"{authz} (status={status!r})".format(
authz=authz.combined_identifier,
status=authz.status,
)
f"{authz.combined_identifier} (status={authz.status!r})"
)
if bad_authzs:
bad_authzs = ", ".join(sorted(bad_authzs))
raise ModuleFailException(
"Some of the authorizations for the order are in a bad state, so the order"
" can no longer be satisfied: {bad_authzs}".format(
bad_authzs=", ".join(sorted(bad_authzs)),
),
f" can no longer be satisfied: {bad_authzs}",
)
def collect_invalid_authzs(self, order):
@@ -201,18 +195,14 @@ class ACMECertificateClient:
alt_cert = CertificateChain.download(self.client, alternate)
except ModuleFailException as e:
self.module.warn(
"Error while downloading alternative certificate {0}: {1}".format(
alternate, e
)
f"Error while downloading alternative certificate {alternate}: {e}"
)
continue
if alt_cert.cert is not None:
alternate_chains.append(alt_cert)
else:
self.module.warn(
"Error while downloading alternative certificate {0}: no certificate found".format(
alternate
)
f"Error while downloading alternative certificate {alternate}: no certificate found"
)
return alternate_chains
@@ -222,22 +212,18 @@ class ACMECertificateClient:
"""
if order.status != "valid":
raise ModuleFailException(
"The order must be valid, but has state {state!r}!".format(
state=order.state
)
f"The order must be valid, but has state {order.state!r}!"
)
if not order.certificate_uri:
raise ModuleFailException(
"Order's crtificate URL {url!r} is empty!".format(
url=order.certificate_uri
)
f"Order's crtificate URL {order.certificate_uri!r} is empty!"
)
cert = CertificateChain.download(self.client, order.certificate_uri)
if cert.cert is None:
raise ModuleFailException(
"Certificate at {url} is empty!".format(url=order.certificate_uri)
f"Certificate at {order.certificate_uri} is empty!"
)
alternate_chains = None
@@ -256,7 +242,7 @@ class ACMECertificateClient:
for identifier, authz in order.authorizations.items():
if authz.status != "valid":
authz.raise_error(
'Status is {status!r} and not "valid"'.format(status=authz.status),
f'Status is {authz.status!r} and not "valid"',
module=self.module,
)
@@ -269,7 +255,7 @@ class ACMECertificateClient:
for chain in chains:
if matcher.match(chain):
self.module.debug(
"Found matching chain for criterium {0}".format(criterium_idx)
f"Found matching chain for criterium {criterium_idx}"
)
return chain
return None
@@ -312,9 +298,7 @@ class ACMECertificateClient:
pass
if authz is None or authz.status != "deactivated":
self.module.warn(
warning="Could not deactivate authz object {0}.".format(
authz_uri
)
warning=f"Could not deactivate authz object {authz_uri}."
)
else:
for authz in order.authorizations.values():
@@ -325,7 +309,5 @@ class ACMECertificateClient:
pass
if authz.status != "deactivated":
self.module.warn(
warning="Could not deactivate authz object {0}.".format(
authz.url
)
warning=f"Could not deactivate authz object {authz.url}."
)

View File

@@ -44,9 +44,7 @@ class CertificateChain:
"application/pem-certificate-chain"
):
raise ModuleFailException(
"Cannot download certificate chain from {0}, as content type is not application/pem-certificate-chain: {1} (headers: {2})".format(
url, content, info
)
f"Cannot download certificate chain from {url}, as content type is not application/pem-certificate-chain: {content} (headers: {info})"
)
result = cls(url)
@@ -63,9 +61,7 @@ class CertificateChain:
if result.cert is None:
raise ModuleFailException(
"Failed to parse certificate chain download from {0}: {1} (headers: {2})".format(
url, content, info
)
f"Failed to parse certificate chain download from {url}: {content} (headers: {info})"
)
return result

View File

@@ -37,11 +37,11 @@ def create_key_authorization(client, token):
client.account_jwk, sort_keys=True, separators=(",", ":")
)
thumbprint = nopad_b64(hashlib.sha256(accountkey_json.encode("utf8")).digest())
return "{0}.{1}".format(token, thumbprint)
return f"{token}.{thumbprint}"
def combine_identifier(identifier_type, identifier):
return "{type}:{identifier}".format(type=identifier_type, identifier=identifier)
return f"{identifier_type}:{identifier}"
def normalize_combined_identifier(identifier):
@@ -55,9 +55,7 @@ def split_identifier(identifier):
parts = identifier.split(":", 1)
if len(parts) != 2:
raise ModuleFailException(
'Identifier "{identifier}" is not of the form <type>:<identifier>'.format(
identifier=identifier
)
f'Identifier "{identifier}" is not of the form <type>:<identifier>'
)
return parts
@@ -94,7 +92,7 @@ class Challenge:
if self.type == "http-01":
# https://tools.ietf.org/html/rfc8555#section-8.3
return {
"resource": ".well-known/acme-challenge/{token}".format(token=token),
"resource": f".well-known/acme-challenge/{token}",
"resource_value": key_authorization,
}
@@ -104,9 +102,7 @@ class Challenge:
# https://tools.ietf.org/html/rfc8555#section-8.4
resource = "_acme-challenge"
value = nopad_b64(hashlib.sha256(to_bytes(key_authorization)).digest())
record = "{0}.{1}".format(
resource, identifier[2:] if identifier.startswith("*.") else identifier
)
record = f"{resource}.{identifier[2:] if identifier.startswith('*.') else identifier}"
return {
"resource": resource,
"resource_value": value,
@@ -152,7 +148,7 @@ class Authorization:
self.identifier = data["identifier"]["value"]
self.identifier_type = data["identifier"]["type"]
if data.get("wildcard", False):
self.identifier = "*.{0}".format(self.identifier)
self.identifier = f"*.{self.identifier}"
def __init__(self, url):
self.url = url
@@ -238,23 +234,17 @@ class Authorization:
# details for all of them before failing
for challenge in self.challenges:
if challenge.status == "invalid":
msg = "Challenge {type}".format(type=challenge.type)
msg = f"Challenge {challenge.type}"
if "error" in challenge.data:
msg = "{msg}: {problem}".format(
msg=msg,
problem=format_error_problem(
challenge.data["error"],
subproblem_prefix="{0}.".format(challenge.type),
),
problem = format_error_problem(
challenge.data["error"],
subproblem_prefix=f"{challenge.type}.",
)
msg = f"{msg}: {problem}"
error_details.append(msg)
raise ACMEProtocolException(
module,
"Failed to validate challenge for {identifier}: {error}. {details}".format(
identifier=self.combined_identifier,
error=error_msg,
details="; ".join(error_details),
),
f"Failed to validate challenge for {self.combined_identifier}: {error_msg}. {'; '.join(error_details)}",
extras=dict(
identifier=self.combined_identifier,
authorization=self.data,
@@ -287,10 +277,7 @@ class Authorization:
challenge = self.find_challenge(challenge_type)
if challenge is None:
raise ModuleFailException(
'Found no challenge of type "{challenge}" for identifier {identifier}!'.format(
challenge=challenge_type,
identifier=self.combined_identifier,
)
f'Found no challenge of type "{challenge_type}" for identifier {self.combined_identifier}!'
)
challenge.call_validate(client)

View File

@@ -14,7 +14,7 @@ def format_http_status(status_code):
expl = http_responses.get(status_code)
if not expl:
return str(status_code)
return "%d %s" % (status_code, expl)
return f"{status_code} {expl}"
def format_error_problem(problem, subproblem_prefix=""):
@@ -22,26 +22,18 @@ def format_error_problem(problem, subproblem_prefix=""):
"type", "about:blank"
) # https://www.rfc-editor.org/rfc/rfc7807#section-3.1
if "title" in problem:
msg = 'Error "{title}" ({type})'.format(
type=error_type,
title=problem["title"],
)
msg = f'Error "{problem["title"]}" ({error_type})'
else:
msg = "Error {type}".format(type=error_type)
msg = f"Error {error_type}"
if "detail" in problem:
msg += ': "{detail}"'.format(detail=problem["detail"])
msg += f': "{problem["detail"]}"'
subproblems = problem.get("subproblems")
if subproblems is not None:
msg = "{msg} Subproblems:".format(msg=msg)
msg = f"{msg} Subproblems:"
for index, problem in enumerate(subproblems):
index_str = "{prefix}{index}".format(prefix=subproblem_prefix, index=index)
msg = "{msg}\n({index}) {problem}".format(
msg=msg,
index=index_str,
problem=format_error_problem(
problem, subproblem_prefix="{0}.".format(index_str)
),
)
index_str = f"{subproblem_prefix}{index}"
problem = format_error_problem(problem, subproblem_prefix=f"{index_str}.")
msg = f"{msg}\n({index_str}) {problem}"
return msg
@@ -116,55 +108,37 @@ class ACMEProtocolException(ModuleFailException):
):
error_type = content_json["type"]
if "status" in content_json and content_json["status"] != code:
code_msg = (
"status {problem_code} (HTTP status: {http_code})".format(
http_code=format_http_status(code),
problem_code=content_json["status"],
)
)
code_msg = f"status {content_json['status']} (HTTP status: {format_http_status(code)})"
else:
code_msg = "status {problem_code}".format(
problem_code=format_http_status(code)
)
code_msg = f"status {format_http_status(code)}"
if code == -1 and info.get("msg"):
code_msg = "error: {msg}".format(msg=info["msg"])
code_msg = f"error: {info['msg']}"
subproblems = content_json.pop("subproblems", None)
add_msg = " {problem}.".format(
problem=format_error_problem(content_json)
)
add_msg = f" {format_error_problem(content_json)}."
extras["problem"] = content_json
extras["subproblems"] = subproblems or []
if subproblems is not None:
add_msg = "{add_msg} Subproblems:".format(add_msg=add_msg)
add_msg = f"{add_msg} Subproblems:"
for index, problem in enumerate(subproblems):
add_msg = "{add_msg}\n({index}) {problem}.".format(
add_msg=add_msg,
index=index,
problem=format_error_problem(
problem, subproblem_prefix="{0}.".format(index)
),
problem = format_error_problem(
problem, subproblem_prefix=f"{index}."
)
add_msg = f"{add_msg}\n({index}) {problem}."
else:
code_msg = "HTTP status {code}".format(code=format_http_status(code))
code_msg = f"HTTP status {format_http_status(code)}"
if code == -1 and info.get("msg"):
code_msg = "error: {msg}".format(msg=info["msg"])
code_msg = f"error: {info['msg']}"
if content_json is not None:
add_msg = " The JSON error result: {content}".format(
content=content_json
)
add_msg = f" The JSON error result: {content_json}"
elif content is not None:
add_msg = " The raw error result: {content}".format(
content=to_text(content)
)
msg = "{msg} for {url} with {code}".format(msg=msg, url=url, code=code_msg)
add_msg = f" The raw error result: {to_text(content)}"
msg = f"{msg} for {url} with {code_msg}"
elif content_json is not None:
add_msg = " The JSON result: {content}".format(content=content_json)
add_msg = f" The JSON result: {content_json}"
elif content is not None:
add_msg = " The raw result: {content}".format(content=to_text(content))
add_msg = f" The raw result: {to_text(content)}"
super(ACMEProtocolException, self).__init__(
"{msg}.{add_msg}".format(msg=msg, add_msg=add_msg), **extras
)
super(ACMEProtocolException, self).__init__(f"{msg}.{add_msg}", **extras)
self.problem = {}
self.subproblems = []
self.error_code = error_code

View File

@@ -22,7 +22,7 @@ def read_file(fn, mode="b"):
with open(fn, "r" + mode) as f:
return f.read()
except Exception as e:
raise ModuleFailException('Error while reading file "{0}": {1}'.format(fn, e))
raise ModuleFailException(f'Error while reading file "{fn}": {e}')
# This function was adapted from an earlier version of https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/uri.py
@@ -44,7 +44,7 @@ def write_file(module, dest, content):
pass
os.remove(tmpsrc)
raise ModuleFailException(
"failed to create temporary content file: %s" % to_native(err),
f"failed to create temporary content file: {err}",
exception=traceback.format_exc(),
)
f.close()
@@ -56,26 +56,26 @@ def write_file(module, dest, content):
os.remove(tmpsrc)
except Exception:
pass
raise ModuleFailException("Source %s does not exist" % (tmpsrc))
raise ModuleFailException(f"Source {tmpsrc} does not exist")
if not os.access(tmpsrc, os.R_OK):
os.remove(tmpsrc)
raise ModuleFailException("Source %s not readable" % (tmpsrc))
raise ModuleFailException(f"Source {tmpsrc} not readable")
checksum_src = module.sha1(tmpsrc)
# check if there is no dest file
if os.path.exists(dest):
# raise an error if copy has no permission on dest
if not os.access(dest, os.W_OK):
os.remove(tmpsrc)
raise ModuleFailException("Destination %s not writable" % (dest))
raise ModuleFailException(f"Destination {dest} not writable")
if not os.access(dest, os.R_OK):
os.remove(tmpsrc)
raise ModuleFailException("Destination %s not readable" % (dest))
raise ModuleFailException(f"Destination {dest} not readable")
checksum_dest = module.sha1(dest)
else:
dirname = os.path.dirname(dest) or "."
if not os.access(dirname, os.W_OK):
os.remove(tmpsrc)
raise ModuleFailException("Destination dir %s not writable" % (dirname))
raise ModuleFailException(f"Destination dir {dirname} not writable")
if checksum_src != checksum_dest:
try:
shutil.copyfile(tmpsrc, dest)
@@ -83,7 +83,7 @@ def write_file(module, dest, content):
except Exception as err:
os.remove(tmpsrc)
raise ModuleFailException(
"failed to copy %s to %s: %s" % (tmpsrc, dest, to_native(err)),
f"failed to copy {tmpsrc} to {dest}: {to_native(err)}",
exception=traceback.format_exc(),
)
os.remove(tmpsrc)

View File

@@ -133,11 +133,7 @@ class Order:
):
if message_callback:
message_callback(
"Stop passing `replaces={replaces}` due to error {code} {type} when creating ACME order".format(
code=exc.error_code,
type=exc.error_type,
replaces=replaces_cert_id,
)
f"Stop passing `replaces={replaces_cert_id}` due to error {exc.error_code} {exc.error_type} when creating ACME order"
)
replaces_cert_id = None
continue
@@ -167,9 +163,7 @@ class Order:
if self.status != "valid":
raise ACMEProtocolException(
client.module,
'Failed to wait for order to complete; got status "{status}"'.format(
status=self.status
),
f'Failed to wait for order to complete; got status "{self.status}"',
content_json=self.data,
)
@@ -198,9 +192,7 @@ class Order:
if self.status not in ["procesing", "valid", "invalid"]:
raise ACMEProtocolException(
client.module,
'Failed to finalize order; got status "{status}"'.format(
status=self.status
),
f'Failed to finalize order; got status "{self.status}"',
info=info,
content_json=result,
)

View File

@@ -32,9 +32,8 @@ def der_to_pem(der_cert):
"""
Convert the DER format certificate in der_cert to a PEM format certificate and return it.
"""
return """-----BEGIN CERTIFICATE-----\n{0}\n-----END CERTIFICATE-----\n""".format(
"\n".join(textwrap.wrap(base64.b64encode(der_cert).decode("utf8"), 64))
)
content = "\n".join(textwrap.wrap(base64.b64encode(der_cert).decode("utf8"), 64))
return f"-----BEGIN CERTIFICATE-----\n{content}\n-----END CERTIFICATE-----\n"
def pem_to_der(pem_filename=None, pem_content=None):
@@ -52,7 +51,7 @@ def pem_to_der(pem_filename=None, pem_content=None):
lines = list(f)
except Exception as err:
raise ModuleFailException(
"cannot load PEM file {0}: {1}".format(pem_filename, to_native(err)),
f"cannot load PEM file {pem_filename}: {to_native(err)}",
exception=traceback.format_exc(),
)
else:
@@ -104,7 +103,7 @@ def parse_retry_after(value, relative_with_timezone=True, now=None):
except ValueError:
pass
raise ValueError("Cannot parse Retry-After header value %s" % repr(value))
raise ValueError(f"Cannot parse Retry-After header value {repr(value)}")
def compute_cert_id(
@@ -138,4 +137,4 @@ def compute_cert_id(
serial = to_native(base64.urlsafe_b64encode(serial_bytes)).replace("=", "")
# Compose cert ID
return "{aki}.{serial}".format(aki=aki, serial=serial)
return f"{aki}.{serial}"

View File

@@ -82,8 +82,7 @@ def serialize_asn1_string_as_der(value):
if value_type != "UTF8":
raise ValueError(
'The ASN.1 serialized string is not a known type "{0}", only UTF8 types are '
"supported".format(value_type)
f'The ASN.1 serialized string is not a known type "{value_type}", only UTF8 types are supported'
)
b_value = to_bytes(asn1_value, encoding="utf-8", errors="surrogate_or_strict")
@@ -117,7 +116,7 @@ def pack_asn1(tag_class, constructed, tag_number, b_data):
b_asn1_data = bytearray()
if tag_class < 0 or tag_class > 3:
raise ValueError("tag_class must be between 0 and 3 not %s" % tag_class)
raise ValueError(f"tag_class must be between 0 and 3 not {tag_class}")
# Bit 8 and 7 denotes the class.
identifier_octets = tag_class << 6

View File

@@ -15,9 +15,7 @@ for dotted, names in OID_MAP.items():
for name in names:
if name in NORMALIZE_NAMES and OID_LOOKUP[name] != dotted:
raise AssertionError(
'Name collision during setup: "{0}" for OIDs {1} and {2}'.format(
name, dotted, OID_LOOKUP[name]
)
f'Name collision during setup: "{name}" for OIDs {dotted} and {OID_LOOKUP[name]}'
)
NORMALIZE_NAMES[name] = names[0]
NORMALIZE_NAMES_SHORT[name] = names[-1]
@@ -25,9 +23,7 @@ for dotted, names in OID_MAP.items():
for alias, original in [("userID", "userId")]:
if alias in NORMALIZE_NAMES:
raise AssertionError(
'Name collision during adding aliases: "{0}" (alias for "{1}") is already mapped to OID {2}'.format(
alias, original, OID_LOOKUP[alias]
)
f'Name collision during adding aliases: "{alias}" (alias for "{original}") is already mapped to OID {OID_LOOKUP[alias]}'
)
NORMALIZE_NAMES[alias] = original
NORMALIZE_NAMES_SHORT[alias] = NORMALIZE_NAMES_SHORT[original]

View File

@@ -242,7 +242,7 @@ def cryptography_name_to_oid(name):
if dotted is None:
if DOTTED_OID.match(name):
return x509.oid.ObjectIdentifier(name)
raise OpenSSLObjectError('Cannot find OID for "{0}"'.format(name))
raise OpenSSLObjectError(f'Cannot find OID for "{name}"')
return x509.oid.ObjectIdentifier(dotted)
@@ -297,7 +297,7 @@ else:
def _parse_dn_component(name, sep=b",", decode_remainder=True):
m = DN_COMPONENT_START_RE.match(name)
if not m:
raise OpenSSLObjectError('cannot start part in "{0}"'.format(to_text(name)))
raise OpenSSLObjectError(f'cannot start part in "{to_text(name)}"')
oid = cryptography_name_to_oid(to_text(m.group(1)))
idx = len(m.group(0))
decoded_name = []
@@ -314,7 +314,7 @@ def _parse_dn_component(name, sep=b",", decode_remainder=True):
idx2 = DN_HEX_LETTER.find(ch2.lower())
if idx1 < 0 or idx2 < 0:
raise OpenSSLObjectError(
'Invalid hex sequence entry "{0}"'.format(to_text(ch1 + ch2))
f'Invalid hex sequence entry "{to_text(ch1 + ch2)}"'
)
idx += 2
decoded_name.append(_int_to_byte(idx1 * 16 + idx2))
@@ -333,17 +333,13 @@ def _parse_dn_component(name, sep=b",", decode_remainder=True):
if idx1 >= 0:
if idx + 2 >= length:
raise OpenSSLObjectError(
'Hex escape sequence "\\{0}" incomplete at end of string'.format(
to_text(ch)
)
f'Hex escape sequence "\\{to_text(ch)}" incomplete at end of string'
)
ch2 = name[idx + 2 : idx + 3]
idx2 = DN_HEX_LETTER.find(ch2.lower())
if idx2 < 0:
raise OpenSSLObjectError(
'Hex escape sequence "\\{0}" has invalid second letter'.format(
to_text(ch + ch2)
)
f'Hex escape sequence "\\{to_text(ch + ch2)}" has invalid second letter'
)
ch = _int_to_byte(idx1 * 16 + idx2)
idx += 1
@@ -375,17 +371,13 @@ def _parse_dn(name):
attribute, name = _parse_dn_component(name, sep=sep)
except OpenSSLObjectError as e:
raise OpenSSLObjectError(
'Error while parsing distinguished name "{0}": {1}'.format(
to_text(original_name), e
)
f'Error while parsing distinguished name "{to_text(original_name)}": {e}'
)
result.append(attribute)
if name:
if name[0:1] != sep or len(name) < 2:
raise OpenSSLObjectError(
'Error while parsing distinguished name "{0}": unexpected end of string'.format(
to_text(original_name)
)
f'Error while parsing distinguished name "{to_text(original_name)}": unexpected end of string'
)
name = name[1:]
return result
@@ -398,9 +390,7 @@ def cryptography_parse_relative_distinguished_name(rdn):
names.append(_parse_dn_component(to_bytes(part), decode_remainder=False)[0])
except OpenSSLObjectError as e:
raise OpenSSLObjectError(
'Error while parsing relative distinguished name "{0}": {1}'.format(
part, e
)
f'Error while parsing relative distinguished name "{part}": {e}'
)
return cryptography.x509.RelativeDistinguishedName(names)
@@ -420,16 +410,14 @@ def _adjust_idn(value, idn_rewrite):
if idn_rewrite == "idna" and _is_ascii(value):
return value
if idn_rewrite not in ("idna", "unicode"):
raise ValueError('Invalid value for idn_rewrite: "{0}"'.format(idn_rewrite))
raise ValueError(f'Invalid value for idn_rewrite: "{idn_rewrite}"')
if not HAS_IDNA:
what = "IDNA" if idn_rewrite == "unicode" else "Unicode"
dest = "Unicode" if idn_rewrite == "unicode" else "IDNA"
raise OpenSSLObjectError(
missing_required_lib(
"idna",
reason='to transform {what} DNS name "{name}" to {dest}'.format(
name=value,
what="IDNA" if idn_rewrite == "unicode" else "Unicode",
dest="Unicode" if idn_rewrite == "unicode" else "IDNA",
),
reason=f'to transform {what} DNS name "{value}" to {dest}',
)
)
# Since IDNA does not like '*' or empty labels (except one empty label at the end),
@@ -450,16 +438,11 @@ def _adjust_idn(value, idn_rewrite):
elif idn_rewrite == "unicode" and part.startswith("xn--"):
parts[index] = part.encode("ascii").decode("idna")
except Exception as exc2003:
what = "IDNA" if idn_rewrite == "unicode" else "Unicode"
dest = "Unicode" if idn_rewrite == "unicode" else "IDNA"
raise OpenSSLObjectError(
'Error while transforming part "{part}" of {what} DNS name "{name}" to {dest}.'
' IDNA2008 transformation resulted in "{exc2008}", IDNA2003 transformation resulted in "{exc2003}".'.format(
part=part,
name=value,
what="IDNA" if idn_rewrite == "unicode" else "Unicode",
dest="Unicode" if idn_rewrite == "unicode" else "IDNA",
exc2003=exc2003,
exc2008=exc2008,
)
f'Error while transforming part "{part}" of {what} DNS name "{value}" to {dest}.'
f' IDNA2008 transformation resulted in "{exc2008}", IDNA2003 transformation resulted in "{exc2003}".'
)
return ".".join(parts)
@@ -468,18 +451,18 @@ def _adjust_idn_email(value, idn_rewrite):
idx = value.find("@")
if idx < 0:
return value
return "{0}@{1}".format(value[:idx], _adjust_idn(value[idx + 1 :], idn_rewrite))
return f"{value[:idx]}@{_adjust_idn(value[idx + 1:], idn_rewrite)}"
def _adjust_idn_url(value, idn_rewrite):
url = urlparse(value)
host = _adjust_idn(url.hostname, idn_rewrite)
if url.username is not None and url.password is not None:
host = "{0}:{1}@{2}".format(url.username, url.password, host)
host = f"{url.username}:{url.password}@{host}"
elif url.username is not None:
host = "{0}@{1}".format(url.username, host)
host = f"{url.username}@{host}"
if url.port is not None:
host = "{0}:{1}".format(host, url.port)
host = f"{host}:{url.port}"
return urlunparse(
ParseResult(
scheme=url.scheme,
@@ -514,9 +497,7 @@ def cryptography_get_name(name, what="Subject Alternative Name"):
if name.startswith("RID:"):
m = re.match(r"^([0-9]+(?:\.[0-9]+)*)$", to_text(name[4:]))
if not m:
raise OpenSSLObjectError(
'Cannot parse {what} "{name}"'.format(name=name, what=what)
)
raise OpenSSLObjectError(f'Cannot parse {what} "{name}"')
return x509.RegisteredID(x509.oid.ObjectIdentifier(m.group(1)))
if name.startswith("otherName:"):
# otherName can either be a raw ASN.1 hex string or in the format that OpenSSL works with.
@@ -534,9 +515,9 @@ def cryptography_get_name(name, what="Subject Alternative Name"):
name = to_text(name[10:], errors="surrogate_or_strict")
if ";" not in name:
raise OpenSSLObjectError(
'Cannot parse {what} otherName "{name}", must be in the '
f'Cannot parse {what} otherName "{name}", must be in the '
'format "otherName:<OID>;<ASN.1 OpenSSL Encoded String>" or '
'"otherName:<OID>;<hex string>"'.format(name=name, what=what)
'"otherName:<OID>;<hex string>"'
)
oid, value = name.split(";", 1)
@@ -547,21 +528,13 @@ def cryptography_get_name(name, what="Subject Alternative Name"):
x509.Name(reversed(_parse_dn(to_bytes(name[8:]))))
)
except Exception as e:
raise OpenSSLObjectError(
'Cannot parse {what} "{name}": {error}'.format(
name=name, what=what, error=e
)
)
raise OpenSSLObjectError(f'Cannot parse {what} "{name}": {e}')
if ":" not in name:
raise OpenSSLObjectError(
'Cannot parse {what} "{name}" (forgot "DNS:" prefix?)'.format(
name=name, what=what
)
f'Cannot parse {what} "{name}" (forgot "DNS:" prefix?)'
)
raise OpenSSLObjectError(
'Cannot parse {what} "{name}" (potentially unsupported by cryptography backend)'.format(
name=name, what=what
)
f'Cannot parse {what} "{name}" (potentially unsupported by cryptography backend)'
)
@@ -571,12 +544,12 @@ def _dn_escape_value(value):
"""
value = value.replace("\\", "\\\\")
for ch in [",", "+", "<", ">", ";", '"']:
value = value.replace(ch, "\\%s" % ch)
value = value.replace(ch, f"\\{ch}")
value = value.replace("\0", "\\00")
if value.startswith((" ", "#")):
value = "\\%s" % value[0] + value[1:]
value = f"\\{value[0]}{value[1:]}"
if value.endswith(" "):
value = value[:-1] + "\\ "
value = f"{value[:-1]}\\ "
return value
@@ -590,36 +563,29 @@ def cryptography_decode_name(name, idn_rewrite="ignore"):
'idn_rewrite must be one of "ignore", "idna", or "unicode"'
)
if isinstance(name, x509.DNSName):
return "DNS:{0}".format(_adjust_idn(name.value, idn_rewrite))
return f"DNS:{_adjust_idn(name.value, idn_rewrite)}"
if isinstance(name, x509.IPAddress):
if isinstance(name.value, (ipaddress.IPv4Network, ipaddress.IPv6Network)):
return "IP:{0}/{1}".format(
name.value.network_address.compressed, name.value.prefixlen
)
return "IP:{0}".format(name.value.compressed)
return f"IP:{name.value.network_address.compressed}/{name.value.prefixlen}"
return f"IP:{name.value.compressed}"
if isinstance(name, x509.RFC822Name):
return "email:{0}".format(_adjust_idn_email(name.value, idn_rewrite))
return f"email:{_adjust_idn_email(name.value, idn_rewrite)}"
if isinstance(name, x509.UniformResourceIdentifier):
return "URI:{0}".format(_adjust_idn_url(name.value, idn_rewrite))
return f"URI:{_adjust_idn_url(name.value, idn_rewrite)}"
if isinstance(name, x509.DirectoryName):
# According to https://datatracker.ietf.org/doc/html/rfc4514.html#section-2.1 the
# list needs to be reversed, and joined by commas
return "dirName:" + ",".join(
[
"{0}={1}".format(
to_text(cryptography_oid_to_name(attribute.oid, short=True)),
_dn_escape_value(attribute.value),
)
f"{to_text(cryptography_oid_to_name(attribute.oid, short=True))}={_dn_escape_value(attribute.value)}"
for attribute in reversed(list(name.value))
]
)
if isinstance(name, x509.RegisteredID):
return "RID:{0}".format(name.value.dotted_string)
return f"RID:{name.value.dotted_string}"
if isinstance(name, x509.OtherName):
return "otherName:{0};{1}".format(
name.type_id.dotted_string, _get_hex(name.value)
)
raise OpenSSLObjectError('Cannot decode name "{0}"'.format(name))
return f"otherName:{name.type_id.dotted_string};{_get_hex(name.value)}"
raise OpenSSLObjectError(f'Cannot decode name "{name}"')
def _cryptography_get_keyusage(usage):
@@ -645,7 +611,7 @@ def _cryptography_get_keyusage(usage):
return "encipher_only"
if usage in ("Decipher Only", "decipherOnly"):
return "decipher_only"
raise OpenSSLObjectError('Unknown key usage "{0}"'.format(usage))
raise OpenSSLObjectError(f'Unknown key usage "{usage}"')
def cryptography_parse_key_usage_params(usages):
@@ -685,9 +651,7 @@ def cryptography_get_basic_constraints(constraints):
ca = False
else:
raise OpenSSLObjectError(
'Unknown basic constraint value "{0}" for CA'.format(
constraint[3:]
)
f'Unknown basic constraint value "{constraint[3:]}" for CA'
)
elif constraint.startswith("pathlen:"):
v = constraint[len("pathlen:") :]
@@ -695,12 +659,10 @@ def cryptography_get_basic_constraints(constraints):
path_length = int(v)
except Exception as e:
raise OpenSSLObjectError(
'Cannot parse path length constraint "{0}" ({1})'.format(v, e)
f'Cannot parse path length constraint "{v}" ({e})'
)
else:
raise OpenSSLObjectError(
'Unknown basic constraint "{0}"'.format(constraint)
)
raise OpenSSLObjectError(f'Unknown basic constraint "{constraint}"')
return ca, path_length
@@ -958,7 +920,7 @@ def cryptography_verify_signature(signature, data, hash_algorithm, signer_public
signer_public_key.verify(signature, data)
return True
raise OpenSSLObjectError(
"Unsupported public key type {0}".format(type(signer_public_key))
f"Unsupported public key type {type(signer_public_key)}"
)
except InvalidSignature:
return False

View File

@@ -162,9 +162,9 @@ else:
def _convert_int_to_bytes(count, n):
if n == 0 and count == 0:
return ""
h = "%x" % n
h = f"{n:x}"
if len(h) > 2 * count:
raise Exception("Number {1} needs more than {0} bytes!".format(count, n))
raise Exception(f"Number {n} needs more than {count} bytes!")
return ("0" * (2 * count - len(h)) + h).decode("hex")
def _convert_bytes_to_int(data):
@@ -174,7 +174,7 @@ else:
return v
def _to_hex(no):
return "%x" % no
return f"{no:x}"
def convert_int_to_bytes(no, count=None):

View File

@@ -363,16 +363,14 @@ def select_backend(module, backend, provider):
# Fail if no backend has been found
if backend == "auto":
module.fail_json(
msg=(
"Cannot detect the required Python library " "cryptography (>= {0})"
).format(MINIMAL_CRYPTOGRAPHY_VERSION)
msg=f"Cannot detect the required Python library cryptography (>= {MINIMAL_CRYPTOGRAPHY_VERSION})"
)
if backend == "cryptography":
if not CRYPTOGRAPHY_FOUND:
module.fail_json(
msg=missing_required_lib(
"cryptography >= {0}".format(MINIMAL_CRYPTOGRAPHY_VERSION)
f"cryptography >= {MINIMAL_CRYPTOGRAPHY_VERSION}"
),
exception=CRYPTOGRAPHY_IMP_ERR,
)

View File

@@ -31,17 +31,17 @@ class AcmeCertificateBackend(CertificateBackend):
)
if self.csr_content is None and not os.path.exists(self.csr_path):
raise CertificateError(
"The certificate signing request file %s does not exist" % self.csr_path
f"The certificate signing request file {self.csr_path} does not exist"
)
if not os.path.exists(self.accountkey_path):
raise CertificateError(
"The account key %s does not exist" % self.accountkey_path
f"The account key {self.accountkey_path} does not exist"
)
if not os.path.exists(self.challenge_path):
raise CertificateError(
"The challenge path %s does not exist" % self.challenge_path
f"The challenge path {self.challenge_path} does not exist"
)
self.acme_tiny_path = self.module.get_bin_path("acme-tiny", required=True)
@@ -66,7 +66,7 @@ class AcmeCertificateBackend(CertificateBackend):
except Exception:
pass
self.module.fail_json(
msg="failed to create temporary CSR file: %s" % to_native(err),
msg=f"failed to create temporary CSR file: {to_native(err)}",
exception=traceback.format_exc(),
)
f.close()

View File

@@ -56,9 +56,7 @@ class EntrustCertificateBackend(CertificateBackend):
)
if self.csr_content is None and not os.path.exists(self.csr_path):
raise CertificateError(
"The certificate signing request file {0} does not exist".format(
self.csr_path
)
f"The certificate signing request file {self.csr_path} does not exist"
)
self._ensure_csr_loaded()
@@ -77,7 +75,7 @@ class EntrustCertificateBackend(CertificateBackend):
self.module.fail_json(
msg=(
"Entrust provider does not currently support multiple validated organizations. Multiple organizations found in "
"Subject DN: '{0}'. ".format(self.csr.subject)
f"Subject DN: '{self.csr.subject}'. "
)
)
# If no organization in the CSR, explicitly tell ECS that it should be blank in issued cert, not defaulted to
@@ -98,11 +96,7 @@ class EntrustCertificateBackend(CertificateBackend):
],
)
except SessionConfigurationException as e:
module.fail_json(
msg="Failed to initialize Entrust Provider: {0}".format(
to_native(e.message)
)
)
module.fail_json(msg=f"Failed to initialize Entrust Provider: {e.message}")
def generate_certificate(self):
"""(Re-)Generate certificate."""
@@ -138,9 +132,7 @@ class EntrustCertificateBackend(CertificateBackend):
self.trackingId = result.get("trackingId")
except RestOperationException as e:
self.module.fail_json(
msg="Failed to request new certificate from Entrust Certificate Services (ECS): {0}".format(
to_native(e.message)
)
msg=f"Failed to request new certificate from Entrust Certificate Services (ECS): {e.message}"
)
self.cert_bytes = to_bytes(result.get("endEntityCert"))
@@ -159,9 +151,7 @@ class EntrustCertificateBackend(CertificateBackend):
cert_details = self._get_cert_details()
except RestOperationException as e:
self.module.fail_json(
msg="Failed to get status of existing certificate from Entrust Certificate Services (ECS): {0}.".format(
to_native(e.message)
)
msg=f"Failed to get status of existing certificate from Entrust Certificate Services (ECS): {e.message}."
)
# Always issue a new certificate if the certificate is expired, suspended or revoked
@@ -189,8 +179,8 @@ class EntrustCertificateBackend(CertificateBackend):
serial_number = None
expiry = None
if self.backend == "cryptography":
serial_number = "{0:X}".format(
cryptography_serial_number_of_cert(self.existing_certificate)
serial_number = (
f"{cryptography_serial_number_of_cert(self.existing_certificate):X}"
)
expiry = get_not_valid_after(self.existing_certificate)

View File

@@ -332,11 +332,9 @@ class CertificateInfoRetrievalCryptography(CertificateInfoRetrieval):
x509.BasicConstraints
)
result = []
result.append(
"CA:{0}".format("TRUE" if ext_keyusage_ext.value.ca else "FALSE")
)
result.append(f"CA:{'TRUE' if ext_keyusage_ext.value.ca else 'FALSE'}")
if ext_keyusage_ext.value.path_length is not None:
result.append("pathlen:{0}".format(ext_keyusage_ext.value.path_length))
result.append(f"pathlen:{ext_keyusage_ext.value.path_length}")
return sorted(result), ext_keyusage_ext.critical
except cryptography.x509.ExtensionNotFound:
return None, False
@@ -474,20 +472,17 @@ def select_backend(module, backend, content):
# Success?
if backend == "auto":
module.fail_json(
msg=(
"Cannot detect any of the required Python libraries "
"cryptography (>= {0})"
).format(MINIMAL_CRYPTOGRAPHY_VERSION)
msg=f"Cannot detect any of the required Python libraries cryptography (>= {MINIMAL_CRYPTOGRAPHY_VERSION})"
)
if backend == "cryptography":
if not CRYPTOGRAPHY_FOUND:
module.fail_json(
msg=missing_required_lib(
"cryptography >= {0}".format(MINIMAL_CRYPTOGRAPHY_VERSION)
f"cryptography >= {MINIMAL_CRYPTOGRAPHY_VERSION}"
),
exception=CRYPTOGRAPHY_IMP_ERR,
)
return backend, CertificateInfoRetrievalCryptography(module, content)
else:
raise ValueError("Unsupported value for backend: {0}".format(backend))
raise ValueError(f"Unsupported value for backend: {backend}")

View File

@@ -93,21 +93,17 @@ class OwnCACertificateBackendCryptography(CertificateBackend):
)
if self.csr_content is None and not os.path.exists(self.csr_path):
raise CertificateError(
"The certificate signing request file {0} does not exist".format(
self.csr_path
)
f"The certificate signing request file {self.csr_path} does not exist"
)
if self.ca_cert_content is None and not os.path.exists(self.ca_cert_path):
raise CertificateError(
"The CA certificate file {0} does not exist".format(self.ca_cert_path)
f"The CA certificate file {self.ca_cert_path} does not exist"
)
if self.ca_privatekey_content is None and not os.path.exists(
self.ca_privatekey_path
):
raise CertificateError(
"The CA private key file {0} does not exist".format(
self.ca_privatekey_path
)
f"The CA private key file {self.ca_privatekey_path} does not exist"
)
self._ensure_csr_loaded()
@@ -134,8 +130,7 @@ class OwnCACertificateBackendCryptography(CertificateBackend):
if cryptography_key_needs_digest_for_signing(self.ca_private_key):
if self.digest is None:
raise CertificateError(
"The digest %s is not supported with the cryptography backend"
% module.params["ownca_digest"]
f"The digest {module.params['ownca_digest']} is not supported with the cryptography backend"
)
else:
self.digest = None

View File

@@ -67,13 +67,11 @@ class SelfSignedCertificateBackendCryptography(CertificateBackend):
if self.csr_path is not None and not os.path.exists(self.csr_path):
raise CertificateError(
"The certificate signing request file {0} does not exist".format(
self.csr_path
)
f"The certificate signing request file {self.csr_path} does not exist"
)
if self.privatekey_content is None and not os.path.exists(self.privatekey_path):
raise CertificateError(
"The private key file {0} does not exist".format(self.privatekey_path)
f"The private key file {self.privatekey_path} does not exist"
)
self._module = module
@@ -90,9 +88,7 @@ class SelfSignedCertificateBackendCryptography(CertificateBackend):
digest = self.digest
if digest is None:
self.module.fail_json(
msg='Unsupported digest "{0}"'.format(
module.params["selfsigned_digest"]
)
msg=f'Unsupported digest "{module.params["selfsigned_digest"]}"'
)
try:
self.csr = csr.sign(self.privatekey, digest, default_backend())
@@ -109,8 +105,7 @@ class SelfSignedCertificateBackendCryptography(CertificateBackend):
if cryptography_key_needs_digest_for_signing(self.privatekey):
if self.digest is None:
raise CertificateError(
"The digest %s is not supported with the cryptography backend"
% module.params["selfsigned_digest"]
f"The digest {module.params['selfsigned_digest']} is not supported with the cryptography backend"
)
else:
self.digest = None

View File

@@ -58,7 +58,7 @@ class CRLInfoRetrieval:
else:
self.crl = x509.load_der_x509_crl(self.content, default_backend())
except ValueError as e:
self.module.fail_json(msg="Error while decoding CRL: {0}".format(e))
self.module.fail_json(msg=f"Error while decoding CRL: {e}")
result = {
"changed": False,
@@ -96,9 +96,7 @@ class CRLInfoRetrieval:
def get_crl_info(module, content, list_revoked_certificates=True):
if not CRYPTOGRAPHY_FOUND:
module.fail_json(
msg=missing_required_lib(
"cryptography >= {0}".format(MINIMAL_CRYPTOGRAPHY_VERSION)
),
msg=missing_required_lib(f"cryptography >= {MINIMAL_CRYPTOGRAPHY_VERSION}"),
exception=CRYPTOGRAPHY_IMP_ERR,
)

View File

@@ -163,7 +163,7 @@ class CertificateSigningRequestBackend:
if not self.subjectAltName and module.params["use_common_name_for_san"]:
for sub in self.subject:
if sub[0] in ("commonName", "CN"):
self.subjectAltName = ["DNS:%s" % sub[1]]
self.subjectAltName = [f"DNS:{sub[1]}"]
self.using_common_name_for_san = True
break
@@ -174,7 +174,7 @@ class CertificateSigningRequestBackend:
)
except Exception as e:
raise CertificateSigningRequestError(
"Cannot parse subject_key_identifier: {0}".format(e)
f"Cannot parse subject_key_identifier: {e}"
)
if self.authority_key_identifier is not None:
@@ -184,7 +184,7 @@ class CertificateSigningRequestBackend:
)
except Exception as e:
raise CertificateSigningRequestError(
"Cannot parse authority_key_identifier: {0}".format(e)
f"Cannot parse authority_key_identifier: {e}"
)
self.existing_csr = None
@@ -337,9 +337,7 @@ def parse_crl_distribution_points(module, crl_distribution_points):
result.append(cryptography.x509.DistributionPoint(**params))
except (OpenSSLObjectError, ValueError) as e:
raise OpenSSLObjectError(
"Error while parsing CRL distribution point #{index}: {error}".format(
index=index, error=e
)
f"Error while parsing CRL distribution point #{index}: {e}"
)
return result
@@ -446,9 +444,7 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
critical=self.name_constraints_critical,
)
except TypeError as e:
raise OpenSSLObjectError(
"Error while parsing name constraint: {0}".format(e)
)
raise OpenSSLObjectError(f"Error while parsing name constraint: {e}")
if self.create_subject_key_identifier:
csr = csr.add_extension(
@@ -494,7 +490,7 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
digest = select_message_digest(self.digest)
if digest is None:
raise CertificateSigningRequestError(
'Unsupported digest "{0}"'.format(self.digest)
f'Unsupported digest "{self.digest}"'
)
try:
self.csr = csr.sign(self.privatekey, digest, self.cryptography_backend)
@@ -518,7 +514,7 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
# https://github.com/kjd/idna/commit/ebefacd3134d0f5da4745878620a6a1cba86d130
# and then
# https://github.com/kjd/idna/commit/ea03c7b5db7d2a99af082e0239da2b68aeea702a).
msg = "Error while creating CSR: {0}\n".format(e)
msg = f"Error while creating CSR: {e}\n"
if self.using_common_name_for_san:
self.module.fail_json(
msg=msg
@@ -813,23 +809,20 @@ def select_backend(module, backend):
# Success?
if backend == "auto":
module.fail_json(
msg=(
"Cannot detect any of the required Python libraries "
"cryptography (>= {0})"
).format(MINIMAL_CRYPTOGRAPHY_VERSION)
msg=f"Cannot detect any of the required Python libraries cryptography (>= {MINIMAL_CRYPTOGRAPHY_VERSION})"
)
if backend == "cryptography":
if not CRYPTOGRAPHY_FOUND:
module.fail_json(
msg=missing_required_lib(
"cryptography >= {0}".format(MINIMAL_CRYPTOGRAPHY_VERSION)
f"cryptography >= {MINIMAL_CRYPTOGRAPHY_VERSION}"
),
exception=CRYPTOGRAPHY_IMP_ERR,
)
return backend, CertificateSigningRequestCryptographyBackend(module)
else:
raise Exception("Unsupported value for backend: {0}".format(backend))
raise Exception(f"Unsupported value for backend: {backend}")
def get_csr_argument_spec():

View File

@@ -258,9 +258,9 @@ class CSRInfoRetrievalCryptography(CSRInfoRetrieval):
ext_keyusage_ext = self.csr.extensions.get_extension_for_class(
x509.BasicConstraints
)
result = ["CA:{0}".format("TRUE" if ext_keyusage_ext.value.ca else "FALSE")]
result = [f"CA:{'TRUE' if ext_keyusage_ext.value.ca else 'FALSE'}"]
if ext_keyusage_ext.value.path_length is not None:
result.append("pathlen:{0}".format(ext_keyusage_ext.value.path_length))
result.append(f"pathlen:{ext_keyusage_ext.value.path_length}")
return sorted(result), ext_keyusage_ext.critical
except cryptography.x509.ExtensionNotFound:
return None, False
@@ -380,16 +380,14 @@ def select_backend(module, backend, content, validate_signature=True):
# Success?
if backend == "auto":
module.fail_json(
msg=(
"Cannot detect the required Python library " "cryptography (>= {0})"
).format(MINIMAL_CRYPTOGRAPHY_VERSION)
msg=f"Cannot detect the required Python library cryptography (>= {MINIMAL_CRYPTOGRAPHY_VERSION})"
)
if backend == "cryptography":
if not CRYPTOGRAPHY_FOUND:
module.fail_json(
msg=missing_required_lib(
"cryptography >= {0}".format(MINIMAL_CRYPTOGRAPHY_VERSION)
f"cryptography >= {MINIMAL_CRYPTOGRAPHY_VERSION}"
),
exception=CRYPTOGRAPHY_IMP_ERR,
)
@@ -397,4 +395,4 @@ def select_backend(module, backend, content, validate_signature=True):
module, content, validate_signature=validate_signature
)
else:
raise ValueError("Unsupported value for backend: {0}".format(backend))
raise ValueError(f"Unsupported value for backend: {backend}")

View File

@@ -273,7 +273,7 @@ class PrivateKeyCryptographyBackend(PrivateKeyBackend):
ecclass = cryptography.hazmat.primitives.asymmetric.ec.__dict__.get(ectype)
if ecclass is None:
self.module.fail_json(
msg="Your cryptography version does not support {0}".format(ectype)
msg=f"Your cryptography version does not support {ectype}"
)
return ecclass
@@ -385,9 +385,7 @@ class PrivateKeyCryptographyBackend(PrivateKeyBackend):
if self.type == "ECC" and self.curve in self.curves:
if self.curves[self.curve]["deprecated"]:
self.module.warn(
"Elliptic curves of type {0} should not be used for new keys!".format(
self.curve
)
f"Elliptic curves of type {self.curve} should not be used for new keys!"
)
self.private_key = (
cryptography.hazmat.primitives.asymmetric.ec.generate_private_key(
@@ -397,9 +395,7 @@ class PrivateKeyCryptographyBackend(PrivateKeyBackend):
)
except cryptography.exceptions.UnsupportedAlgorithm:
self.module.fail_json(
msg="Cryptography backend does not support the algorithm required for {0}".format(
self.type
)
msg=f"Cryptography backend does not support the algorithm required for {self.type}"
)
def get_private_key_data(self):
@@ -426,9 +422,7 @@ class PrivateKeyCryptographyBackend(PrivateKeyBackend):
)
except AttributeError:
self.module.fail_json(
msg='Cryptography backend does not support the selected output format "{0}"'.format(
self.format
)
msg=f'Cryptography backend does not support the selected output format "{self.format}"'
)
# Select key encryption
@@ -454,15 +448,11 @@ class PrivateKeyCryptographyBackend(PrivateKeyBackend):
)
except ValueError:
self.module.fail_json(
msg='Cryptography backend cannot serialize the private key in the required format "{0}"'.format(
self.format
)
msg=f'Cryptography backend cannot serialize the private key in the required format "{self.format}"'
)
except Exception:
self.module.fail_json(
msg='Error while serializing the private key in the required format "{0}"'.format(
self.format
),
msg=f'Error while serializing the private key in the required format "{self.format}"',
exception=traceback.format_exc(),
)
@@ -611,21 +601,19 @@ def select_backend(module, backend):
# Success?
if backend == "auto":
module.fail_json(
msg=(
"Cannot detect the required Python library " "cryptography (>= {0})"
).format(MINIMAL_CRYPTOGRAPHY_VERSION)
msg=f"Cannot detect the required Python library cryptography (>= {MINIMAL_CRYPTOGRAPHY_VERSION})"
)
if backend == "cryptography":
if not CRYPTOGRAPHY_FOUND:
module.fail_json(
msg=missing_required_lib(
"cryptography >= {0}".format(MINIMAL_CRYPTOGRAPHY_VERSION)
f"cryptography >= {MINIMAL_CRYPTOGRAPHY_VERSION}"
),
exception=CRYPTOGRAPHY_IMP_ERR,
)
return backend, PrivateKeyCryptographyBackend(module)
else:
raise Exception("Unsupported value for backend: {0}".format(backend))
raise Exception(f"Unsupported value for backend: {backend}")
def get_privatekey_argument_spec():

View File

@@ -161,9 +161,7 @@ class PrivateKeyConvertCryptographyBackend(PrivateKeyConvertBackend):
)
except AttributeError:
self.module.fail_json(
msg='Cryptography backend does not support the selected output format "{0}"'.format(
self.format
)
msg=f'Cryptography backend does not support the selected output format "{self.format}"'
)
# Select key encryption
@@ -186,15 +184,11 @@ class PrivateKeyConvertCryptographyBackend(PrivateKeyConvertBackend):
)
except ValueError:
self.module.fail_json(
msg='Cryptography backend cannot serialize the private key in the required format "{0}"'.format(
self.format
)
msg=f'Cryptography backend cannot serialize the private key in the required format "{self.format}"'
)
except Exception:
self.module.fail_json(
msg='Error while serializing the private key in the required format "{0}"'.format(
self.format
),
msg=f'Error while serializing the private key in the required format "{self.format}"',
exception=traceback.format_exc(),
)
@@ -285,9 +279,7 @@ class PrivateKeyConvertCryptographyBackend(PrivateKeyConvertBackend):
def select_backend(module):
if not CRYPTOGRAPHY_FOUND:
module.fail_json(
msg=missing_required_lib(
"cryptography >= {0}".format(MINIMAL_CRYPTOGRAPHY_VERSION)
),
msg=missing_required_lib(f"cryptography >= {MINIMAL_CRYPTOGRAPHY_VERSION}"),
exception=CRYPTOGRAPHY_IMP_ERR,
)
return PrivateKeyConvertCryptographyBackend(module)

View File

@@ -173,7 +173,7 @@ def _is_cryptography_key_consistent(
return False
# For X25519 and X448, there's no test yet.
if warn_func is not None:
warn_func("Cannot determine consistency for key of type %s" % type(key))
warn_func(f"Cannot determine consistency for key of type {type(key)}")
return None
@@ -338,16 +338,14 @@ def select_backend(
# Success?
if backend == "auto":
module.fail_json(
msg=(
"Cannot detect the required Python library " "cryptography (>= {0})"
).format(MINIMAL_CRYPTOGRAPHY_VERSION)
msg=f"Cannot detect the required Python library cryptography (>= {MINIMAL_CRYPTOGRAPHY_VERSION})"
)
if backend == "cryptography":
if not CRYPTOGRAPHY_FOUND:
module.fail_json(
msg=missing_required_lib(
"cryptography >= {0}".format(MINIMAL_CRYPTOGRAPHY_VERSION)
f"cryptography >= {MINIMAL_CRYPTOGRAPHY_VERSION}"
),
exception=CRYPTOGRAPHY_IMP_ERR,
)
@@ -359,4 +357,4 @@ def select_backend(
check_consistency=check_consistency,
)
else:
raise ValueError("Unsupported value for backend: {0}".format(backend))
raise ValueError(f"Unsupported value for backend: {backend}")

View File

@@ -84,7 +84,7 @@ def _get_cryptography_public_key_info(key):
key_public_data["y"] = public_numbers.y
key_public_data["exponent_size"] = key.curve.key_size
else:
key_type = "unknown ({0})".format(type(key))
key_type = f"unknown ({type(key)})"
return key_type, key_public_data
@@ -174,17 +174,14 @@ def select_backend(module, backend, content=None, key=None):
# Success?
if backend == "auto":
module.fail_json(
msg=(
"Cannot detect any of the required Python libraries "
"cryptography (>= {0})"
).format(MINIMAL_CRYPTOGRAPHY_VERSION)
msg=f"Cannot detect any of the required Python libraries cryptography (>= {MINIMAL_CRYPTOGRAPHY_VERSION})"
)
if backend == "cryptography":
if not CRYPTOGRAPHY_FOUND:
module.fail_json(
msg=missing_required_lib(
"cryptography >= {0}".format(MINIMAL_CRYPTOGRAPHY_VERSION)
f"cryptography >= {MINIMAL_CRYPTOGRAPHY_VERSION}"
),
exception=CRYPTOGRAPHY_IMP_ERR,
)
@@ -192,4 +189,4 @@ def select_backend(module, backend, content=None, key=None):
module, content=content, key=key
)
else:
raise ValueError("Unsupported value for backend: {0}".format(backend))
raise ValueError(f"Unsupported value for backend: {backend}")

View File

@@ -98,36 +98,24 @@ def _extract_type(line, start=PEM_START):
def extract_pem(content, strict=False):
lines = content.splitlines()
if len(lines) < 3:
raise ValueError(
"PEM must have at least 3 lines, have only {count}".format(count=len(lines))
)
raise ValueError(f"PEM must have at least 3 lines, have only {len(lines)}")
header_type = _extract_type(lines[0])
if header_type is None:
raise ValueError(
"First line is not of format {start}...{end}: {line!r}".format(
start=PEM_START, end=PEM_END, line=lines[0]
)
f"First line is not of format {PEM_START}...{PEM_END}: {lines[0]!r}"
)
footer_type = _extract_type(lines[-1], start=PEM_END_START)
if strict:
if header_type != footer_type:
raise ValueError(
"Header type ({header}) is different from footer type ({footer})".format(
header=header_type, footer=footer_type
)
f"Header type ({header_type}) is different from footer type ({footer_type})"
)
for idx, line in enumerate(lines[1:-2]):
if len(line) != 64:
raise ValueError(
"Line {idx} has length {len} instead of 64".format(
idx=idx, len=len(line)
)
)
raise ValueError(f"Line {idx} has length {len(line)} instead of 64")
if not (0 < len(lines[-2]) <= 64):
raise ValueError(
"Last line has length {len}, should be in (0, 64]".format(
len=len(lines[-2])
)
f"Last line has length {len(lines[-2])}, should be in (0, 64]"
)
content = lines[1:-1]
return header_type, "".join(content)

View File

@@ -179,7 +179,7 @@ def load_publickey(path=None, content=None, backend=None):
content, backend=cryptography_backend()
)
except Exception as e:
raise OpenSSLObjectError("Error while deserializing key: {0}".format(e))
raise OpenSSLObjectError(f"Error while deserializing key: {e}")
def load_certificate(
@@ -209,9 +209,7 @@ def load_certificate(
cert_content, cryptography_backend()
)
except ValueError as exc:
raise OpenSSLObjectError(
"Cannot parse DER certificate: {0}".format(exc)
)
raise OpenSSLObjectError(f"Cannot parse DER certificate: {exc}")
def load_certificate_request(path, content=None, backend="cryptography"):
@@ -241,31 +239,30 @@ def parse_name_field(input_dict, name_field_name=None):
for entry in value:
if not isinstance(entry, six.string_types):
raise TypeError(
("Values %s must be strings" % error_str).format(
f"Values {error_str} must be strings".format(
key=key, name=name_field_name
)
)
if not entry:
raise ValueError(
("Values for %s must not be empty strings" % error_str).format(
key=key
f"Values for {error_str} must not be empty strings".format(
key=key, name=name_field_name
)
)
result.append((key, entry))
elif isinstance(value, six.string_types):
if not value:
raise ValueError(
("Value for %s must not be an empty string" % error_str).format(
key=key
f"Value for {error_str} must not be an empty string".format(
key=key, name=name_field_name
)
)
result.append((key, value))
else:
raise TypeError(
(
"Value for %s must be either a string or a list of strings"
% error_str
).format(key=key)
f"Value for {error_str} must be either a string or a list of strings"
).format(key=key, name=name_field_name)
)
return result
@@ -277,17 +274,13 @@ def parse_ordered_name_field(input_list, name_field_name):
for index, entry in enumerate(input_list):
if len(entry) != 1:
raise ValueError(
"Entry #{index} in {name} must be a dictionary with exactly one key-value pair".format(
name=name_field_name, index=index + 1
)
f"Entry #{index + 1} in {name_field_name} must be a dictionary with exactly one key-value pair"
)
try:
result.extend(parse_name_field(entry, name_field_name=name_field_name))
except (TypeError, ValueError) as exc:
raise ValueError(
"Error while processing entry #{index} in {name}: {error}".format(
name=name_field_name, index=index + 1, error=exc
)
f"Error while processing entry #{index + 1} in {name_field_name}: {exc}"
)
return result

View File

@@ -73,12 +73,8 @@ def generate_docstring(operation_spec):
if len(parameters) != 0:
docs += "\tArguments:\n\n"
for parameter in parameters:
docs += "{0} ({1}:{2}): {3}\n".format(
parameter.get("name"),
parameter.get("type", "No Type"),
"Required" if parameter.get("required", False) else "Not Required",
parameter.get("description"),
)
req = "Required" if parameter.get("required", False) else "Not Required"
docs += f"{parameter.get('name')} ({parameter.get('type', 'No Type')}:{req}): {parameter.get('description')}\n"
return docs
@@ -104,11 +100,8 @@ class RestOperation:
self.parameters = {}
else:
self.parameters = parameters
self.url = "{scheme}://{host}{base_path}{uri}".format(
scheme="https",
host=session._spec.get("host"),
base_path=session._spec.get("basePath"),
uri=uri,
self.url = (
f"https://{session._spec.get('host')}{session._spec.get('basePath')}{uri}"
)
def restmethod(self, *args, **kwargs):
@@ -204,7 +197,7 @@ class Resource:
operation_name = "Patch"
else:
raise SessionConfigurationException(
to_native("Invalid REST method type {0}".format(method))
to_native(f"Invalid REST method type {method}")
)
# Get the non-parameter parts of the URL and append to the operation name
@@ -286,9 +279,7 @@ class ECSSession:
):
raise SessionConfigurationException(
to_native(
"OpenAPI specification was not found at location {0}.".format(
entrust_api_specification_path
)
f"OpenAPI specification was not found at location {entrust_api_specification_path}."
)
)
if not valid_file_format.match(entrust_api_specification_path):
@@ -315,9 +306,7 @@ class ECSSession:
except HTTPError as e:
raise SessionConfigurationException(
to_native(
"Error downloading specification from address '{0}', received error code '{1}'".format(
entrust_api_specification_path, e.getcode()
)
f"Error downloading specification from address '{entrust_api_specification_path}', received error code '{e.getcode()}'"
)
)
else:
@@ -344,9 +333,8 @@ class ECSSession:
):
raise SessionConfigurationException(
to_native(
"Parameter provided for entrust_api_specification_path of value '{0}' was not a valid file path or HTTPS address.".format(
entrust_api_specification_path
)
f"Parameter provided for entrust_api_specification_path of value '{entrust_api_specification_path}'"
" was not a valid file path or HTTPS address."
)
)
@@ -355,18 +343,14 @@ class ECSSession:
if not file_path or not os.path.isfile(file_path):
raise SessionConfigurationException(
to_native(
"Parameter provided for {0} of value '{1}' was not a valid file path.".format(
required_file, file_path
)
f"Parameter provided for {required_file} of value '{file_path}' was not a valid file path."
)
)
for required_var in ["entrust_api_user", "entrust_api_key"]:
if not kwargs.get(required_var):
raise SessionConfigurationException(
to_native(
"Parameter provided for {0} was missing.".format(required_var)
)
to_native(f"Parameter provided for {required_var} was missing.")
)
config["entrust_api_cert"] = kwargs.get("entrust_api_cert")

View File

@@ -39,19 +39,15 @@ def get_fingerprint_from_stdout(stdout):
parts = line.split(":")
if len(parts) <= 9 or not parts[9]:
raise GPGError(
'Result line "{line}" does not have fingerprint as 10th component'.format(
line=line
)
f'Result line "{line}" does not have fingerprint as 10th component'
)
return parts[9]
raise GPGError(
'Cannot extract fingerprint from stdout "{stdout}"'.format(stdout=stdout)
)
raise GPGError(f'Cannot extract fingerprint from stdout "{stdout}"')
def get_fingerprint_from_file(gpg_runner, path):
if not os.path.exists(path):
raise GPGError("{path} does not exist".format(path=path))
raise GPGError(f"{path} does not exist")
stdout = gpg_runner.run_command(
[
"--no-keyring",

View File

@@ -19,7 +19,7 @@ def load_file(path, module=None):
except Exception as exc:
if module is None:
raise
module.fail_json("Error while loading {0} - {1}".format(path, str(exc)))
module.fail_json(f"Error while loading {path} - {exc}")
def load_file_if_exists(path, module=None, ignore_errors=False):
@@ -40,13 +40,13 @@ def load_file_if_exists(path, module=None, ignore_errors=False):
return None
if module is None:
raise
module.fail_json("Error while loading {0} - {1}".format(path, str(exc)))
module.fail_json(f"Error while loading {path} - {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)))
module.fail_json(f"Error while loading {path} - {exc}")
def write_file(module, content, default_mode=None, path=None):
@@ -83,9 +83,7 @@ def write_file(module, content, default_mode=None, path=None):
os.remove(tmp_name)
except Exception:
pass
module.fail_json(
msg="Error while writing result into temporary file: {0}".format(e)
)
module.fail_json(msg=f"Error while writing result into temporary file: {e}")
# Update destination to wanted permissions
if os.path.exists(file_args["path"]):
module.set_fs_attributes_if_different(file_args, False)
@@ -101,4 +99,4 @@ def write_file(module, content, default_mode=None, path=None):
os.remove(tmp_name)
except Exception:
pass
module.fail_json(msg="Error while writing result: {0}".format(e))
module.fail_json(msg=f"Error while writing result: {e}")

View File

@@ -73,7 +73,7 @@ class OpensshModule:
self._execute()
except Exception as e:
self.module.fail_json(
msg="unexpected error occurred: %s" % to_native(e),
msg=f"unexpected error occurred: {to_native(e)}",
exception=traceback.format_exc(),
)
@@ -125,8 +125,7 @@ class OpensshModule:
if not os.path.isdir(base_dir):
self.module.fail_json(
name=base_dir,
msg="The directory %s does not exist or the file is not a directory"
% base_dir,
msg=f"The directory {base_dir} does not exist or the file is not a directory",
)
def _get_ssh_version(self):
@@ -253,8 +252,7 @@ class KeygenCommand:
os.chmod(private_key_path, stat.S_IWUSR + stat.S_IRUSR)
except (IOError, OSError) as e:
raise e(
"The private key at %s is not writeable preventing a comment update"
% private_key_path
f"The private key at {private_key_path} is not writeable preventing a comment update"
)
command = [self._bin_path, "-q"]
@@ -332,7 +330,7 @@ class PublicKey:
return not self == other
def __str__(self):
return "%s %s" % (self._type_string, self._data)
return f"{self._type_string} {self._data}"
@property
def comment(self):

View File

@@ -90,7 +90,7 @@ class KeypairBackend(OpensshModule):
result = 256
else:
return self.module.fail_json(
msg="%s is not a valid value for key type" % self.type
msg=f"{self.type} is not a valid value for key type"
)
return result
@@ -100,8 +100,7 @@ class KeypairBackend(OpensshModule):
if os.path.isdir(self.private_key_path):
self.module.fail_json(
msg="%s is a directory. Please specify a path to a file."
% self.private_key_path
msg=f"{self.private_key_path} is a directory. Please specify a path to a file."
)
def _execute(self):
@@ -562,4 +561,4 @@ def select_backend(module, backend):
module.fail_json(msg=missing_required_lib("cryptography >= 2.6"))
return backend, KeypairBackendCryptography(module)
else:
raise ValueError("Unsupported value for backend: {0}".format(backend))
raise ValueError(f"Unsupported value for backend: {backend}")

View File

@@ -110,8 +110,7 @@ class OpensshCertificateTimeParameters:
if self._valid_from > self._valid_to:
raise ValueError(
"Valid from: %s must not be greater than Valid to: %s"
% (valid_from, valid_to)
f"Valid from: {valid_from} must not be greater than Valid to: {valid_to}"
)
def __eq__(self, other):
@@ -129,10 +128,7 @@ class OpensshCertificateTimeParameters:
@property
def validity_string(self):
if not (self._valid_from == _ALWAYS and self._valid_to == _FOREVER):
return "%s:%s" % (
self.valid_from(date_format="openssh"),
self.valid_to(date_format="openssh"),
)
return f"{self.valid_from(date_format='openssh')}:{self.valid_to(date_format='openssh')}"
return ""
def valid_from(self, date_format):
@@ -166,7 +162,7 @@ class OpensshCertificateTimeParameters:
(td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6
)
else:
raise ValueError("%s is not a valid format" % date_format)
raise ValueError(f"{date_format} is not a valid format")
return result
@staticmethod
@@ -182,8 +178,7 @@ class OpensshCertificateTimeParameters:
)
else:
raise ValueError(
"Value must be of type (str, unicode, int, long) not %s"
% type(time_string_or_timestamp)
f"Value must be of type (str, unicode, int, long) not {type(time_string_or_timestamp)}"
)
except ValueError:
raise
@@ -238,10 +233,10 @@ class OpensshCertificateOption:
raise ValueError("type must be either 'critical' or 'extension'")
if not isinstance(name, six.string_types):
raise TypeError("name must be a string not %s" % type(name))
raise TypeError(f"name must be a string not {type(name)}")
if not isinstance(data, six.string_types):
raise TypeError("data must be a string not %s" % type(data))
raise TypeError(f"data must be a string not {type(data)}")
self._option_type = option_type
self._name = name.lower()
@@ -267,7 +262,7 @@ class OpensshCertificateOption:
def __str__(self):
if self._data:
return "%s=%s" % (self._name, self._data)
return f"{self._name}={self._data}"
return self._name
@property
@@ -286,7 +281,7 @@ class OpensshCertificateOption:
def from_string(cls, option_string):
if not isinstance(option_string, six.string_types):
raise ValueError(
"option_string must be a string not %s" % type(option_string)
f"option_string must be a string not {type(option_string)}"
)
option_type = None
@@ -356,7 +351,7 @@ class OpensshCertificateInfo:
elif cert_type == "host" or cert_type == _HOST_TYPE:
self._cert_type = _HOST_TYPE
else:
raise ValueError("%s is not a valid certificate type" % cert_type)
raise ValueError(f"{cert_type} is not a valid certificate type")
def signing_key_fingerprint(self):
return fingerprint(self.signing_key)
@@ -447,8 +442,7 @@ class OpensshECDSACertificateInfo(OpensshCertificateInfo):
)
else:
raise ValueError(
"Curve must be one of %s"
% (b",".join(list(_ECDSA_CURVE_IDENTIFIERS.values()))).decode("UTF-8")
"Curve must be one of {(b','.join(_ECDSA_CURVE_IDENTIFIERS.values())).decode('UTF-8')}"
)
# See https://datatracker.ietf.org/doc/html/rfc4253#section-6.6
@@ -500,13 +494,13 @@ class OpensshCertificate:
@classmethod
def load(cls, path):
if not os.path.exists(path):
raise ValueError("%s is not a valid path." % path)
raise ValueError(f"{path} is not a valid path.")
try:
with open(path, "rb") as cert_file:
data = cert_file.read()
except (IOError, OSError) as e:
raise ValueError("%s cannot be opened for reading: %s" % (path, e))
raise ValueError(f"{path} cannot be opened for reading: {e}")
try:
format_identifier, b64_cert = data.split(b" ")[:2]
@@ -520,7 +514,7 @@ class OpensshCertificate:
break
else:
raise ValueError(
"Invalid certificate format identifier: %s" % format_identifier
f"Invalid certificate format identifier: {format_identifier}"
)
parser = OpensshParser(cert)
@@ -532,12 +526,11 @@ class OpensshCertificate:
cert_info = cls._parse_cert_info(pub_key_type, parser)
signature = parser.string()
except (TypeError, ValueError) as e:
raise ValueError("Invalid certificate data: %s" % e)
raise ValueError(f"Invalid certificate data: {e}")
if parser.remaining_bytes():
raise ValueError(
"%s bytes of additional data was not parsed while loading %s"
% (parser.remaining_bytes(), path)
f"{parser.remaining_bytes()} bytes of additional data was not parsed while loading {path}"
)
return cls(
@@ -651,7 +644,7 @@ class OpensshCertificate:
def apply_directives(directives):
if any(d not in _DIRECTIVES for d in directives):
raise ValueError("directives must be one of %s" % ", ".join(_DIRECTIVES))
raise ValueError(f"directives must be one of {', '.join(_DIRECTIVES)}")
directive_to_option = {
"no-x11-forwarding": OpensshCertificateOption(
@@ -696,7 +689,7 @@ def get_cert_info_object(key_type):
elif key_type == "ed25519":
cert_info = OpensshED25519CertificateInfo()
else:
raise ValueError("%s is not a valid key type" % key_type)
raise ValueError(f"{key_type} is not a valid key type")
return cert_info
@@ -708,8 +701,8 @@ def get_option_type(name):
result = "extension"
else:
raise ValueError(
"%s is not a valid option. " % name
+ "Custom options must start with 'critical:' or 'extension:' to indicate type"
f"{name} is not a valid option. "
"Custom options must start with 'critical:' or 'extension:' to indicate type"
)
return result

View File

@@ -137,8 +137,7 @@ class AsymmetricKeypair:
if keytype not in _ALGORITHM_PARAMETERS.keys():
raise InvalidKeyTypeError(
"%s is not a valid keytype. Valid keytypes are %s"
% (keytype, ", ".join(_ALGORITHM_PARAMETERS.keys()))
f"{keytype} is not a valid keytype. Valid keytypes are {', '.join(_ALGORITHM_PARAMETERS)}"
)
if not size:
@@ -146,7 +145,7 @@ class AsymmetricKeypair:
else:
if size not in _ALGORITHM_PARAMETERS[keytype]["valid_sizes"]:
raise InvalidKeySizeError(
"%s is not a valid key size for %s keys" % (size, keytype)
f"{size} is not a valid key size for {keytype} keys"
)
if passphrase:
@@ -229,9 +228,7 @@ class AsymmetricKeypair:
elif isinstance(privatekey, Ed25519PrivateKey):
keytype = "ed25519"
else:
raise InvalidKeyTypeError(
"Key type '%s' is not supported" % type(privatekey)
)
raise InvalidKeyTypeError(f"Key type '{type(privatekey)}' is not supported")
return cls(
keytype=keytype,
@@ -363,7 +360,7 @@ class OpensshKeypair:
"""
if comment is None:
comment = "%s@%s" % (getuser(), gethostname())
comment = f"{getuser()}@{gethostname()}"
asym_keypair = AsymmetricKeypair.generate(keytype, size, passphrase)
openssh_privatekey = cls.encode_openssh_privatekey(asym_keypair, "SSH")
@@ -457,7 +454,7 @@ class OpensshKeypair:
validate_comment(comment)
encoded_publickey += (
(" %s" % comment).encode(encoding=_TEXT_ENCODING) if comment else b""
f" {comment}".encode(encoding=_TEXT_ENCODING) if comment else b""
)
return encoded_publickey
@@ -541,7 +538,7 @@ class OpensshKeypair:
self.__comment = comment
encoded_comment = (
(" %s" % self.__comment).encode(encoding=_TEXT_ENCODING)
f" {self.__comment}".encode(encoding=_TEXT_ENCODING)
if self.__comment
else b""
)
@@ -578,12 +575,11 @@ def load_privatekey(path, passphrase, key_format):
privatekey_loader = privatekey_loaders[key_format]
except KeyError:
raise InvalidKeyFormatError(
"%s is not a valid key format (%s)"
% (key_format, ",".join(privatekey_loaders.keys()))
f"{key_format} is not a valid key format ({','.join(privatekey_loaders)})"
)
if not os.path.exists(path):
raise InvalidPrivateKeyFileError("No file was found at %s" % path)
raise InvalidPrivateKeyFileError(f"No file was found at {path}")
try:
with open(path, "rb") as f:
@@ -631,12 +627,11 @@ def load_publickey(path, key_format):
publickey_loader = publickey_loaders[key_format]
except KeyError:
raise InvalidKeyFormatError(
"%s is not a valid key format (%s)"
% (key_format, ",".join(publickey_loaders.keys()))
f"{key_format} is not a valid key format ({','.join(publickey_loaders)})"
)
if not os.path.exists(path):
raise InvalidPublicKeyFileError("No file was found at %s" % path)
raise InvalidPublicKeyFileError(f"No file was found at {path}")
try:
with open(path, "rb") as f:
@@ -689,13 +684,13 @@ def get_encryption_algorithm(passphrase):
def validate_comment(comment):
if not hasattr(comment, "encode"):
raise InvalidCommentError("%s cannot be encoded to text" % comment)
raise InvalidCommentError(f"{comment} cannot be encoded to text")
def extract_comment(path):
if not os.path.exists(path):
raise InvalidPublicKeyFileError("No file was found at %s" % path)
raise InvalidPublicKeyFileError(f"No file was found at {path}")
try:
with open(path, "rb") as f:
@@ -715,6 +710,5 @@ def calculate_fingerprint(openssh_publickey):
decoded_pubkey = b64decode(openssh_publickey.split(b" ")[1])
digest.update(decoded_pubkey)
return "SHA256:%s" % b64encode(digest.finalize()).decode(
encoding=_TEXT_ENCODING
).rstrip("=")
value = b64encode(digest.finalize()).decode(encoding=_TEXT_ENCODING).rstrip("=")
return f"SHA256:{value}"

View File

@@ -91,7 +91,7 @@ class OpensshParser:
def __init__(self, data):
if not isinstance(data, (bytes, bytearray)):
raise TypeError("Data must be bytes-like not %s" % type(data))
raise TypeError(f"Data must be bytes-like not {type(data)}")
self._data = memoryview(data) if PY3 else data
self._pos = 0
@@ -174,7 +174,7 @@ class OpensshParser:
def _check_position(self, offset):
if self._pos + offset > len(self._data):
raise ValueError("Insufficient data remaining at position: %s" % self._pos)
raise ValueError(f"Insufficient data remaining at position: {self._pos}")
elif self._pos + offset < 0:
raise ValueError("Position cannot be less than zero.")
else:
@@ -210,7 +210,7 @@ class OpensshParser:
signature_data["R"] = cls._big_int(signature_blob[:32], "little")
signature_data["S"] = cls._big_int(signature_blob[32:], "little")
else:
raise ValueError("%s is not a valid signature type" % signature_type)
raise ValueError(f"{signature_type} is not a valid signature type")
signature_data["signature_type"] = signature_type
@@ -220,7 +220,7 @@ class OpensshParser:
def _big_int(cls, raw_string, byte_order, signed=False):
if byte_order not in ("big", "little"):
raise ValueError(
"Byte_order must be one of (big, little) not %s" % byte_order
f"Byte_order must be one of (big, little) not {byte_order}"
)
if PY3:
@@ -279,7 +279,7 @@ class _OpensshWriter:
if buffer is not None:
if not isinstance(buffer, (bytes, bytearray)):
raise TypeError(
"Buffer must be a bytes-like object not %s" % type(buffer)
f"Buffer must be a bytes-like object not {type(buffer)}"
)
else:
buffer = bytearray()
@@ -288,7 +288,7 @@ class _OpensshWriter:
def boolean(self, value):
if not isinstance(value, bool):
raise TypeError("Value must be of type bool not %s" % type(value))
raise TypeError(f"Value must be of type bool not {type(value)}")
self._buff.extend(_BOOLEAN.pack(value))
@@ -296,10 +296,10 @@ class _OpensshWriter:
def uint32(self, value):
if not isinstance(value, int):
raise TypeError("Value must be of type int not %s" % type(value))
raise TypeError(f"Value must be of type int not {type(value)}")
if value < 0 or value > _UINT32_MAX:
raise ValueError(
"Value must be a positive integer less than %s" % _UINT32_MAX
f"Value must be a positive integer less than {_UINT32_MAX}"
)
self._buff.extend(_UINT32.pack(value))
@@ -308,10 +308,10 @@ class _OpensshWriter:
def uint64(self, value):
if not isinstance(value, (long, int)):
raise TypeError("Value must be of type (long, int) not %s" % type(value))
raise TypeError(f"Value must be of type (long, int) not {type(value)}")
if value < 0 or value > _UINT64_MAX:
raise ValueError(
"Value must be a positive integer less than %s" % _UINT64_MAX
f"Value must be a positive integer less than {_UINT64_MAX}"
)
self._buff.extend(_UINT64.pack(value))
@@ -320,7 +320,7 @@ class _OpensshWriter:
def string(self, value):
if not isinstance(value, (bytes, bytearray)):
raise TypeError("Value must be bytes-like not %s" % type(value))
raise TypeError(f"Value must be bytes-like not {type(value)}")
self.uint32(len(value))
self._buff.extend(value)
@@ -328,7 +328,7 @@ class _OpensshWriter:
def mpint(self, value):
if not isinstance(value, (int, long)):
raise TypeError("Value must be of type (long, int) not %s" % type(value))
raise TypeError(f"Value must be of type (long, int) not {type(value)}")
self.string(self._int_to_mpint(value))
@@ -336,18 +336,18 @@ class _OpensshWriter:
def name_list(self, value):
if not isinstance(value, list):
raise TypeError("Value must be a list of byte strings not %s" % type(value))
raise TypeError(f"Value must be a list of byte strings not {type(value)}")
try:
self.string(",".join(value).encode("ASCII"))
except UnicodeEncodeError as e:
raise ValueError("Name-list's must consist of US-ASCII characters: %s" % e)
raise ValueError(f"Name-list's must consist of US-ASCII characters: {e}")
return self
def string_list(self, value):
if not isinstance(value, list):
raise TypeError("Value must be a list of byte string not %s" % type(value))
raise TypeError(f"Value must be a list of byte string not {type(value)}")
writer = _OpensshWriter()
for s in value:

View File

@@ -37,9 +37,7 @@ def parse_serial(value):
raise ValueError("the value is not in range [0, 255]")
except ValueError as exc:
raise ValueError(
"The {idx}{th} part {part!r} is not a hexadecimal number in range [0, 255]: {exc}".format(
idx=i + 1, th=th(i + 1), part=part, exc=exc
)
f"The {i + 1}{th(i + 1)} part {part!r} is not a hexadecimal number in range [0, 255]: {exc}"
)
result = (result << 8) | part_value
return result

View File

@@ -146,7 +146,7 @@ def get_relative_time_option(
result = to_native(input_string)
if result is None:
raise OpenSSLObjectError(
'The timespec "%s" for %s is not valid' % input_string, input_name
f'The timespec "{input_string}" for {input_name} is not valid'
)
# Relative time
if result.startswith("+") or result.startswith("-"):
@@ -179,5 +179,5 @@ def get_relative_time_option(
return add_or_remove_timezone(res, with_timezone=with_timezone)
raise OpenSSLObjectError(
'The time spec "%s" for %s is invalid' % (input_string, input_name)
f'The time spec "{input_string}" for {input_name} is invalid'
)

View File

@@ -229,8 +229,7 @@ def main():
base64.urlsafe_b64decode(key)
except Exception as e:
module.fail_json(
msg="Key for external_account_binding must be Base64 URL encoded (%s)"
% e
msg=f"Key for external_account_binding must be Base64 URL encoded ({e})"
)
module.params["external_account_binding"]["key"] = key
@@ -296,7 +295,7 @@ def main():
)
except KeyParsingError as e:
raise ModuleFailException(
"Error while parsing new account key: {msg}".format(msg=e.msg)
f"Error while parsing new account key: {e.msg}"
)
# Verify that the account exists and has not been deactivated
created, account_data = account.setup_account(allow_creation=False)

View File

@@ -233,9 +233,7 @@ def get_orders_list(module, client, orders_url):
if not res.get("orders"):
if orders:
module.warn(
"When retrieving orders list part {0}, got empty result list".format(
orders_url
)
f"When retrieving orders list part {orders_url}, got empty result list"
)
break
# Add order URLs to result list

View File

@@ -643,9 +643,7 @@ class ACMECertificateClient:
)
except ValueError as exc:
self.module.warn(
"Error while parsing criterium: {error}. Ignoring criterium.".format(
error=exc
)
f"Error while parsing criterium: {exc}. Ignoring criterium."
)
if self.profile is not None:
@@ -654,9 +652,7 @@ class ACMECertificateClient:
raise ModuleFailException(msg="The ACME CA does not support profiles.")
if self.profile not in meta_profiles:
raise ModuleFailException(
msg="The ACME CA does not support selected profile {0!r}.".format(
self.profile
)
msg=f"The ACME CA does not support selected profile {self.profile!r}."
)
# Make sure account exists
@@ -678,7 +674,7 @@ class ACMECertificateClient:
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))
raise ModuleFailException(f"CSR {self.csr} not found")
# Extract list of identifiers from CSR
self.identifiers = self.client.backend.get_ordered_csr_identifiers(
@@ -758,9 +754,7 @@ class ACMECertificateClient:
and self.challenge not in data[authz.identifier]
):
raise ModuleFailException(
"Found no challenge of type '{0}' for identifier {1}!".format(
self.challenge, type_identifier
)
f"Found no challenge of type '{self.challenge}' for identifier {type_identifier}!"
)
# Get DNS challenge data
data_dns = {}
@@ -812,9 +806,7 @@ class ACMECertificateClient:
alt_cert = CertificateChain.download(self.client, alternate)
except ModuleFailException as e:
self.module.warn(
"Error while downloading alternative certificate {0}: {1}".format(
alternate, e
)
f"Error while downloading alternative certificate {alternate}: {e}"
)
continue
alternate_chains.append(alt_cert)
@@ -825,7 +817,7 @@ class ACMECertificateClient:
for chain in chains:
if matcher.match(chain):
self.module.debug(
"Found matching chain for criterium {0}".format(criterium_idx)
f"Found matching chain for criterium {criterium_idx}"
)
return chain
return None
@@ -844,13 +836,11 @@ class ACMECertificateClient:
)
if authz is None:
raise ModuleFailException(
'Found no authorization information for "{identifier}"!'.format(
identifier=combine_identifier(identifier_type, identifier)
)
f'Found no authorization information for "{combine_identifier(identifier_type, identifier)}"!'
)
if authz.status != "valid":
authz.raise_error(
'Status is "{status}" and not "valid"'.format(status=authz.status),
f'Status is "{authz.status}" and not "valid"',
module=self.module,
)
@@ -911,7 +901,7 @@ class ACMECertificateClient:
pass
if authz.status != "deactivated":
self.module.warn(
warning="Could not deactivate authz object {0}.".format(authz.url)
warning=f"Could not deactivate authz object {authz.url}."
)

View File

@@ -98,9 +98,7 @@ def main():
# ignore errors
pass
if authz.status != "deactivated":
module.warn(
warning="Could not deactivate authz object {0}.".format(authz.url)
)
module.warn(warning=f"Could not deactivate authz object {authz.url}.")
module.exit_json(changed=changed)
except ModuleFailException as e:

View File

@@ -414,9 +414,7 @@ def main():
)
if profile not in meta_profiles:
raise ModuleFailException(
msg="The ACME CA does not support selected profile {0!r}.".format(
profile
)
msg=f"The ACME CA does not support selected profile {profile!r}."
)
order = None

View File

@@ -271,13 +271,10 @@ def main():
missing_challenge_authzs = [k for k, v in challenges.items() if v is None]
if missing_challenge_authzs:
missing_challenge_authzs = ", ".join(sorted(missing_challenge_authzs))
raise ModuleFailException(
"The challenge parameter must be supplied if there are pending authorizations."
" The following authorizations are pending: {missing_challenge_authzs}".format(
missing_challenge_authzs=", ".join(
sorted(missing_challenge_authzs)
),
)
f" The following authorizations are pending: {missing_challenge_authzs}"
)
bad_challenge_authzs = [
@@ -286,18 +283,15 @@ def main():
if authz.find_challenge(challenges[authz.combined_identifier]) is None
]
if bad_challenge_authzs:
raise ModuleFailException(
"The following authorizations do not support the selected challenges: {authz_challenges_pairs}".format(
authz_challenges_pairs=", ".join(
sorted(
"{authz} with {challenge}".format(
authz=authz, challenge=challenges[authz]
)
for authz in bad_challenge_authzs
)
),
authz_challenges_pairs = ", ".join(
sorted(
f"{authz} with {challenges[authz]}"
for authz in bad_challenge_authzs
)
)
raise ModuleFailException(
f"The following authorizations do not support the selected challenges: {authz_challenges_pairs}"
)
really_pending_authzs = [
authz

View File

@@ -231,7 +231,7 @@ def main():
)
except ModuleFailException as e:
if module.params["treat_parsing_error_as_non_existing"]:
complete(True, msg="Certificate cannot be parsed: {0}".format(e.msg))
complete(True, msg=f"Certificate cannot be parsed: {e.msg}")
e.do_fail(module)
result["parsable"] = True
@@ -265,24 +265,18 @@ def main():
)
msg_append = ""
if "explanationURL" in renewal_info:
msg_append = ". Information on renewal interval: {0}".format(
renewal_info["explanationURL"]
)
msg_append = f". Information on renewal interval: {renewal_info['explanationURL']}"
result["supports_ari"] = True
if now > window_end:
complete(
True,
msg="The suggested renewal interval provided by ARI is in the past{0}".format(
msg_append
),
msg=f"The suggested renewal interval provided by ARI is in the past{msg_append}",
)
if module.params["ari_algorithm"] == "start":
if now > window_start:
complete(
True,
msg="The suggested renewal interval provided by ARI has begun{0}".format(
msg_append
),
msg=f"The suggested renewal interval provided by ARI has begun{msg_append}",
)
else:
random_time = backend.interpolate_timestamp(
@@ -291,10 +285,7 @@ def main():
if now > random_time:
complete(
True,
msg="The picked random renewal time {0} in sugested renewal internal provided by ARI is in the past{1}".format(
random_time,
msg_append,
),
msg=f"The picked random renewal time {random_time} in sugested renewal internal provided by ARI is in the past{msg_append}",
)
if module.params["remaining_days"] is not None:
@@ -302,7 +293,7 @@ def main():
if remaining_days < module.params["remaining_days"]:
complete(
True,
msg="The certificate expires in {0} days".format(remaining_days),
msg=f"The certificate expires in {remaining_days} days",
)
if module.params["remaining_percentage"] is not None:
@@ -314,10 +305,8 @@ def main():
if timestamp < now:
complete(
True,
msg="The remaining percentage {0}% of the certificate's lifespan was reached on {1}".format(
module.params["remaining_percentage"] * 100,
timestamp,
),
msg=f"The remaining percentage {module.params['remaining_percentage'] * 100}%"
f" of the certificate's lifespan was reached on {timestamp}",
)
complete(False)

View File

@@ -182,9 +182,7 @@ def main():
private_key, private_key_content, passphrase=passphrase
)
except KeyParsingError as e:
raise ModuleFailException(
"Error while parsing private key: {msg}".format(msg=e.msg)
)
raise ModuleFailException(f"Error while parsing private key: {e.msg}")
# Step 2: sign revokation request with private key
jws_header = {
"alg": private_key_data["alg"],

View File

@@ -259,7 +259,7 @@ def main():
)
)
except Exception as e:
raise ModuleFailException("Error while loading private key: {0}".format(e))
raise ModuleFailException(f"Error while loading private key: {e}")
# Some common attributes
domain = to_text(challenge_data["resource"])
@@ -276,7 +276,7 @@ def main():
san = cryptography.x509.IPAddress(ipaddress.ip_address(identifier))
else:
raise ModuleFailException(
'Unsupported identifier type "{0}"'.format(identifier_type)
f'Unsupported identifier type "{identifier_type}"'
)
# Generate regular self-signed certificate

View File

@@ -212,18 +212,16 @@ def is_parent(module, cert, potential_parent):
public_key.verify(cert.cert.signature, cert.cert.tbs_certificate_bytes)
else:
# Unknown public key type
module.warn('Unknown public key type "{0}"'.format(public_key))
module.warn(f'Unknown public key type "{public_key}"')
return False
return True
except cryptography.exceptions.InvalidSignature:
return False
except cryptography.exceptions.UnsupportedAlgorithm:
module.warn(
'Unsupported algorithm "{0}"'.format(cert.cert.signature_hash_algorithm)
)
module.warn(f'Unsupported algorithm "{cert.cert.signature_hash_algorithm}"')
return False
except Exception as e:
module.fail_json(msg="Unknown error on signature validation: {0}".format(e))
module.fail_json(msg=f"Unknown error on signature validation: {e}")
def parse_PEM_list(module, text, source, fail_on_error=True):
@@ -239,9 +237,7 @@ def parse_PEM_list(module, text, source, fail_on_error=True):
)
result.append(Certificate(cert_pem, cert))
except Exception as e:
msg = "Cannot parse certificate #{0} from {1}: {2}".format(
len(result) + 1, source, e
)
msg = f"Cannot parse certificate #{len(result) + 1} from {source}: {e}"
if fail_on_error:
module.fail_json(msg=msg)
else:
@@ -262,7 +258,7 @@ def load_PEM_list(module, path, fail_on_error=True):
fail_on_error=fail_on_error,
)
except Exception as e:
msg = "Cannot read certificate file {0}: {1}".format(path, e)
msg = f"Cannot read certificate file {path}: {e}"
if fail_on_error:
module.fail_json(msg=msg)
else:
@@ -357,9 +353,9 @@ def main():
if not is_parent(module, chain[i - 1], parent):
module.fail_json(
msg=(
"Cannot verify input chain: certificate #{2}: {3} is not issuer "
+ "of certificate #{0}: {1}"
).format(i, format_cert(chain[i - 1]), i + 1, format_cert(parent))
f"Cannot verify input chain: certificate #{i + 1}: {format_cert(parent)} is not issuer "
f"of certificate #{i}: {format_cert(chain[i - 1])}"
)
)
# Load intermediate certificates
@@ -392,9 +388,7 @@ def main():
current = intermediate
else:
module.fail_json(
msg="Cannot complete chain. Stuck at certificate {0}".format(
format_cert(current)
)
msg=f"Cannot complete chain. Stuck at certificate {format_cert(current)}"
)
# Return results

View File

@@ -665,16 +665,12 @@ class EcsCertificate:
],
)
except SessionConfigurationException as e:
module.fail_json(
msg="Failed to initialize Entrust Provider: {0}".format(to_native(e))
)
module.fail_json(msg=f"Failed to initialize Entrust Provider: {e}")
try:
self.ecs_client.GetAppVersion()
except RestOperationException as e:
module.fail_json(
msg="Please verify credential information. Received exception when testing ECS connection: {0}".format(
to_native(e.message)
)
msg=f"Please verify credential information. Received exception when testing ECS connection: {e.message}"
)
# Conversion of the fields that go into the 'tracking' parameter of the request object
@@ -744,7 +740,7 @@ class EcsCertificate:
try:
# Use serial_number to identify if certificate is an Entrust Certificate
# with an associated tracking ID
serial_number = "{0:X}".format(self.cert.serial_number)
serial_number = f"{self.cert.serial_number:X}"
cert_results = self.ecs_client.GetCertificates(
serialNumber=serial_number
).get("certificates", {})
@@ -764,9 +760,7 @@ class EcsCertificate:
self.cert_days = calculate_cert_days(self.cert_details.get("expiresAfter"))
except RestOperationException as e:
module.fail_json(
'Failed to get details of certificate with tracking_id="{0}", Error: '.format(
self.tracking_id
),
f'Failed to get details of certificate with tracking_id="{self.tracking_id}", Error: ',
to_native(e.message),
)
@@ -782,10 +776,9 @@ class EcsCertificate:
and module.params["tracking_id"] != self.tracking_id
):
module.warn(
'tracking_id parameter of "{0}" provided, but will be ignored. Valid certificate was present in path "{1}" with '
'tracking_id of "{2}".'.format(
module.params["tracking_id"], self.path, self.tracking_id
)
f'tracking_id parameter of "{module.params["tracking_id"]}" provided, but will be ignored.'
f' Valid certificate was present in path "{self.path}" with '
f'tracking_id of "{self.tracking_id}".'
)
# If we did not end up setting tracking_id based on existing cert, get from module params
@@ -822,10 +815,10 @@ class EcsCertificate:
# We will be performing a reissue operation.
if self.request_type != "new" and not self.tracking_id:
module.warn(
'No existing Entrust certificate found in path={0} and no tracking_id was provided, setting request_type to "new" for this task'
"run. Future playbook runs that point to the pathination file in {1} will use request_type={2}".format(
self.path, self.path, self.request_type
)
f"No existing Entrust certificate found in path={self.path}"
' and no tracking_id was provided, setting request_type to "new" for this task'
"run. Future playbook runs that point to the pathination file"
f" in {self.path} will use request_type={self.request_type}"
)
self.request_type = "new"
elif self.request_type == "new" and self.tracking_id:
@@ -860,9 +853,7 @@ class EcsCertificate:
self.set_cert_details(module)
except RestOperationException as e:
module.fail_json(
msg="Failed to request new certificate from Entrust (ECS) {0}".format(
e.message
)
msg=f"Failed to request new certificate from Entrust (ECS) {e.message}"
)
if self.request_type != "validate_only":
@@ -1020,9 +1011,7 @@ def main():
MINIMAL_CRYPTOGRAPHY_VERSION
):
module.fail_json(
msg=missing_required_lib(
"cryptography >= {0}".format(MINIMAL_CRYPTOGRAPHY_VERSION)
),
msg=missing_required_lib(f"cryptography >= {MINIMAL_CRYPTOGRAPHY_VERSION}"),
exception=CRYPTOGRAPHY_IMP_ERR,
)
@@ -1033,9 +1022,7 @@ def main():
or module.params["request_type"] == "validate_only"
):
module.fail_json(
msg='The tracking_id field is invalid when request_type="{0}".'.format(
module.params["request_type"]
)
msg=f'The tracking_id field is invalid when request_type="{module.params["request_type"]}".'
)
# A reissued request can not specify an expiration date or lifetime
@@ -1053,15 +1040,12 @@ def main():
module_params_csr = module.params["csr"]
if module_params_csr is None:
module.fail_json(
msg="The csr field is required when request_type={0}".format(
module.params["request_type"]
)
msg=f"The csr field is required when request_type={module.params['request_type']}"
)
elif not os.path.exists(module_params_csr):
module.fail_json(
msg="The csr field of {0} was not a valid path. csr is required when request_type={1}".format(
module_params_csr, module.params["request_type"]
)
msg=f"The csr field of {module_params_csr} was not a valid path."
f" csr is required when request_type={module.params['request_type']}"
)
if module.params["ou"] and len(module.params["ou"]) > 1:
@@ -1088,9 +1072,7 @@ def main():
if module.params["cert_expiry"]:
if not validate_cert_expiry(module.params["cert_expiry"]):
module.fail_json(
msg='The "cert_expiry" parameter of "{0}" is not a valid date or date-time'.format(
module.params["cert_expiry"]
)
msg=f'The "cert_expiry" parameter of "{module.params["cert_expiry"]}" is not a valid date or date-time'
)
certificate = EcsCertificate(module)

View File

@@ -275,15 +275,13 @@ class EcsDomain:
)
except SessionConfigurationException as e:
module.fail_json(
msg="Failed to initialize Entrust Provider: {0}".format(to_native(e))
msg=f"Failed to initialize Entrust Provider: {to_native(e)}"
)
try:
self.ecs_client.GetAppVersion()
except RestOperationException as e:
module.fail_json(
msg="Please verify credential information. Received exception when testing ECS connection: {0}".format(
to_native(e.message)
)
msg=f"Please verify credential information. Received exception when testing ECS connection: {e.message}"
)
def set_domain_details(self, domain_details):
@@ -405,9 +403,7 @@ class EcsDomain:
self.set_domain_details(result)
except RestOperationException as e:
module.fail_json(
msg="Failed to request domain validation from Entrust (ECS) {0}".format(
e.message
)
msg=f"Failed to request domain validation from Entrust (ECS) {e.message}"
)
def dump(self):
@@ -467,9 +463,7 @@ def main():
and module.params["verification_method"] != "email"
):
module.fail_json(
msg='The verification_email field is invalid when verification_method="{0}".'.format(
module.params["verification_method"]
)
msg=f'The verification_email field is invalid when verification_method="{module.params["verification_method"]}".'
)
domain = EcsDomain(module)

View File

@@ -369,8 +369,7 @@ def main():
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). "
"The Python version used to run the get_certificate module is %s"
% sys.version
f"The Python version used to run the get_certificate module is {sys.version}"
)
backend = module.params.get("select_crypto_backend")
@@ -388,16 +387,14 @@ def main():
# Success?
if backend == "auto":
module.fail_json(
msg=(
"Cannot detect the required Python library " "cryptography (>= {0})"
).format(MINIMAL_CRYPTOGRAPHY_VERSION)
msg=f"Cannot detect the required Python library cryptography (>= {MINIMAL_CRYPTOGRAPHY_VERSION})"
)
if backend == "cryptography":
if not CRYPTOGRAPHY_FOUND:
module.fail_json(
msg=missing_required_lib(
"cryptography >= {0}".format(MINIMAL_CRYPTOGRAPHY_VERSION)
f"cryptography >= {MINIMAL_CRYPTOGRAPHY_VERSION}"
),
exception=CRYPTOGRAPHY_IMP_ERR,
)
@@ -437,14 +434,12 @@ def main():
# Note: get_server_certificate does not support SNI!
cert = get_server_certificate((host, port), ca_certs=ca_cert)
except Exception as e:
module.fail_json(
msg="Failed to get cert from {0}:{1}, error: {2}".format(host, port, e)
)
module.fail_json(msg=f"Failed to get cert from {host}:{port}, error: {e}")
else:
# Python >= 2.7.9
try:
if proxy_host:
connect = "CONNECT %s:%s HTTP/1.0\r\n\r\n" % (host, port)
connect = f"CONNECT {host}:{port} HTTP/1.0\r\n\r\n"
sock = socket()
atexit.register(sock.close)
sock.connect((proxy_host, proxy_port))
@@ -489,9 +484,7 @@ def main():
# If tls_ctx_option_attr is not an integer
else:
module.fail_json(
msg="Failed to determine the numeric value for {0}".format(
tls_ctx_option_str
)
msg=f"Failed to determine the numeric value for {tls_ctx_option_str}"
)
# If the item is an integer
elif isinstance(tls_ctx_option, int):
@@ -500,9 +493,7 @@ def main():
# If the item is not a string nor integer
else:
module.fail_json(
msg="tls_ctx_options must be a string or integer, got {0!r}".format(
tls_ctx_option
)
msg=f"tls_ctx_options must be a string or integer, got {tls_ctx_option!r}"
)
tls_ctx_option_int = (
0 # make pylint happy; this code is actually unreachable
@@ -513,9 +504,7 @@ def main():
ctx.options |= tls_ctx_option_int
except Exception:
module.fail_json(
msg="Failed to add {0} to CTX options".format(
tls_ctx_option_str or tls_ctx_option_int
)
msg=f"Failed to add {tls_ctx_option_str or tls_ctx_option_int} to CTX options"
)
tls_sock = ctx.wrap_socket(sock, server_hostname=server_name or host)
@@ -568,15 +557,11 @@ def main():
except Exception as e:
if proxy_host:
module.fail_json(
msg="Failed to get cert via proxy {0}:{1} from {2}:{3}, error: {4}".format(
proxy_host, proxy_port, host, port, e
)
msg=f"Failed to get cert via proxy {proxy_host}:{proxy_port} from {host}:{port}, error: {e}"
)
else:
module.fail_json(
msg="Failed to get cert from {0}:{1}, error: {2}".format(
host, port, e
)
msg=f"Failed to get cert from {host}:{port}, error: {e}"
)
result["cert"] = cert

View File

@@ -493,9 +493,7 @@ class Handler:
return b64decode(to_native(passphrase))
except Exception as exc:
self._module.fail_json(
"Error while base64-decoding '{parameter_name}': {exc}".format(
parameter_name=parameter_name, exc=exc
)
f"Error while base64-decoding '{parameter_name}': {exc}"
)
def _run_command(self, command, data=None):
@@ -531,10 +529,10 @@ class Handler:
if result[RETURN_CODE] != 0:
raise ValueError(
"Error while generating LUKS name for %s: %s" % (device, result[STDERR])
f"Error while generating LUKS name for {device}: {result[STDERR]}"
)
dev_uuid = result[STDOUT].strip()
return "luks-%s" % dev_uuid
return f"luks-{dev_uuid}"
class CryptHandler(Handler):
@@ -551,7 +549,7 @@ class CryptHandler(Handler):
result = self._run_command([self._lsblk_bin, device, "-nlo", "type,name"])
if result[RETURN_CODE] != 0:
raise ValueError(
"Error while obtaining LUKS name for %s: %s" % (device, result[STDERR])
f"Error while obtaining LUKS name for {device}: {result[STDERR]}"
)
for line in result[STDOUT].splitlines(False):
@@ -595,9 +593,9 @@ class CryptHandler(Handler):
"""check if a keyslot is set"""
result = self._run_command([self._cryptsetup_bin, "luksDump", device])
if result[RETURN_CODE] != 0:
raise ValueError("Error while dumping LUKS header from %s" % (device,))
result_luks1 = "Key Slot %d: ENABLED" % (keyslot) in result[STDOUT]
result_luks2 = " %d: luks2" % (keyslot) in result[STDOUT]
raise ValueError(f"Error while dumping LUKS header from {device}")
result_luks1 = f"Key Slot {keyslot}: ENABLED" in result[STDOUT]
result_luks2 = f" {keyslot}: luks2" in result[STDOUT]
return result_luks1 or result_luks2
def _add_pbkdf_options(self, options, pbkdf):
@@ -657,9 +655,7 @@ class CryptHandler(Handler):
result = self._run_command(args, data=passphrase)
if result[RETURN_CODE] != 0:
raise ValueError(
"Error while creating LUKS on %s: %s" % (device, result[STDERR])
)
raise ValueError(f"Error while creating LUKS on {device}: {result[STDERR]}")
def run_luks_open(
self,
@@ -696,14 +692,13 @@ class CryptHandler(Handler):
result = self._run_command(args, data=passphrase)
if result[RETURN_CODE] != 0:
raise ValueError(
"Error while opening LUKS container on %s: %s"
% (device, result[STDERR])
f"Error while opening LUKS container on {device}: {result[STDERR]}"
)
def run_luks_close(self, name):
result = self._run_command([self._cryptsetup_bin, "close", name])
if result[RETURN_CODE] != 0:
raise ValueError("Error while closing LUKS container %s" % (name))
raise ValueError(f"Error while closing LUKS container {name}")
def run_luks_remove(self, device):
wipefs_bin = self._module.get_bin_path("wipefs", True)
@@ -714,8 +709,7 @@ class CryptHandler(Handler):
result = self._run_command([wipefs_bin, "--all", device])
if result[RETURN_CODE] != 0:
raise ValueError(
"Error while wiping LUKS container signatures for %s: %s"
% (device, result[STDERR])
f"Error while wiping LUKS container signatures for {device}: {result[STDERR]}"
)
# For LUKS2, sometimes both `cryptsetup erase` and `wipefs` do **not**
@@ -725,8 +719,7 @@ class CryptHandler(Handler):
wipe_luks_headers(device)
except Exception as exc:
raise ValueError(
"Error while wiping LUKS container signatures for %s: %s"
% (device, exc)
f"Error while wiping LUKS container signatures for {device}: {exc}"
)
def run_luks_add_key(
@@ -766,8 +759,7 @@ class CryptHandler(Handler):
result = self._run_command(args, data=b"".join(data) or None)
if result[RETURN_CODE] != 0:
raise ValueError(
"Error while adding new LUKS keyslot to %s: %s"
% (device, result[STDERR])
f"Error while adding new LUKS keyslot to {device}: {result[STDERR]}"
)
def run_luks_remove_key(
@@ -779,7 +771,7 @@ class CryptHandler(Handler):
if not force_remove_last_key:
result = self._run_command([self._cryptsetup_bin, "luksDump", device])
if result[RETURN_CODE] != 0:
raise ValueError("Error while dumping LUKS header from %s" % (device,))
raise ValueError(f"Error while dumping LUKS header from {device}")
keyslot_count = 0
keyslot_area = False
keyslot_re = re.compile(r"^Key Slot [0-9]+: ENABLED")
@@ -802,9 +794,8 @@ class CryptHandler(Handler):
keyslot_area = False
if keyslot_count < 2:
self._module.fail_json(
msg="LUKS device %s has less than two active keyslots. "
"To be able to remove a key, please set "
"`force_remove_last_key` to `true`." % device
msg=f"LUKS device {device} has less than two active keyslots. "
"To be able to remove a key, please set `force_remove_last_key` to `true`."
)
if keyslot is None:
@@ -820,7 +811,7 @@ class CryptHandler(Handler):
result = self._run_command(args, data=passphrase)
if result[RETURN_CODE] != 0:
raise ValueError(
"Error while removing LUKS key from %s: %s" % (device, result[STDERR])
f"Error while removing LUKS key from {device}: {result[STDERR]}"
)
def luks_test_key(self, device, keyfile, passphrase, keyslot=None):
@@ -859,8 +850,7 @@ class CryptHandler(Handler):
return False
raise ValueError(
"Error while testing whether keyslot exists on %s: %s"
% (device, result[STDERR])
f"Error while testing whether keyslot exists on {device}: {result[STDERR]}"
)
@@ -921,8 +911,7 @@ class ConditionsHandler(Handler):
# the container is already open but with different name:
# suspicious. back off
self._module.fail_json(
msg="LUKS container is already opened "
"under different name '%s'." % name
msg=f"LUKS container is already opened under different name '{name}'."
)
# container is opened and the names match
@@ -1069,13 +1058,11 @@ class ConditionsHandler(Handler):
if luks_type == "luks1" and not 0 <= self._module.params[param] <= 7:
self._module.fail_json(
msg="%s must be between 0 and 7 when using LUKS1."
% self._module.params[param]
msg=f"{self._module.params[param]} must be between 0 and 7 when using LUKS1."
)
elif luks_type == "luks2" and not 0 <= self._module.params[param] <= 31:
self._module.fail_json(
msg="%s must be between 0 and 31 when using LUKS2."
% self._module.params[param]
msg=f"{self._module.params[param]} must be between 0 and 31 when using LUKS2."
)
@@ -1151,7 +1138,7 @@ def run_module():
statinfo = os.stat(module.params["device"])
mode = statinfo.st_mode
if not stat.S_ISBLK(mode) and not stat.S_ISCHR(mode):
raise Exception("{0} is not a device".format(module.params["device"]))
raise Exception(f"{module.params['device']} is not a device")
except Exception as e:
module.fail_json(msg=str(e))
@@ -1202,7 +1189,7 @@ def run_module():
module.params["pbkdf"],
)
except ValueError as e:
module.fail_json(msg="luks_device error: %s" % e)
module.fail_json(msg=f"luks_device error: {e}")
result["changed"] = True
if module.check_mode:
module.exit_json(**result)
@@ -1219,7 +1206,7 @@ def run_module():
try:
name = crypt.generate_luks_name(conditions.device)
except ValueError as e:
module.fail_json(msg="luks_device error: %s" % e)
module.fail_json(msg=f"luks_device error: {e}")
if not module.check_mode:
try:
crypt.run_luks_open(
@@ -1235,7 +1222,7 @@ def run_module():
name,
)
except ValueError as e:
module.fail_json(msg="luks_device error: %s" % e)
module.fail_json(msg=f"luks_device error: {e}")
result["name"] = name
result["changed"] = True
if module.check_mode:
@@ -1247,14 +1234,14 @@ def run_module():
try:
name = crypt.get_container_name_by_device(conditions.device)
except ValueError as e:
module.fail_json(msg="luks_device error: %s" % e)
module.fail_json(msg=f"luks_device error: {e}")
else:
name = module.params["name"]
if not module.check_mode:
try:
crypt.run_luks_close(name)
except ValueError as e:
module.fail_json(msg="luks_device error: %s" % e)
module.fail_json(msg=f"luks_device error: {e}")
result["name"] = name
result["changed"] = True
if module.check_mode:
@@ -1274,7 +1261,7 @@ def run_module():
module.params["pbkdf"],
)
except ValueError as e:
module.fail_json(msg="luks_device error: %s" % e)
module.fail_json(msg=f"luks_device error: {e}")
result["changed"] = True
if module.check_mode:
module.exit_json(**result)
@@ -1292,7 +1279,7 @@ def run_module():
force_remove_last_key=last_key,
)
except ValueError as e:
module.fail_json(msg="luks_device error: %s" % e)
module.fail_json(msg=f"luks_device error: {e}")
result["changed"] = True
if module.check_mode:
module.exit_json(**result)
@@ -1303,7 +1290,7 @@ def run_module():
try:
crypt.run_luks_remove(conditions.device)
except ValueError as e:
module.fail_json(msg="luks_device error: %s" % e)
module.fail_json(msg=f"luks_device error: {e}")
result["changed"] = True
if module.check_mode:
module.exit_json(**result)

View File

@@ -360,7 +360,7 @@ class Certificate(OpensshModule):
elif LooseVersion(ssh_version) < LooseVersion("7.6"):
self.module.fail_json(
msg="Signing with CA key in ssh agent requires ssh 7.6 or newer."
+ " Your version is: %s" % ssh_version
+ f" Your version is: {ssh_version}"
)
def _exists(self):
@@ -371,10 +371,8 @@ class Certificate(OpensshModule):
self.original_data = OpensshCertificate.load(self.path)
except (TypeError, ValueError) as e:
if self.regenerate in ("never", "fail"):
self.module.fail_json(
msg="Unable to read existing certificate: %s" % to_native(e)
)
self.module.warn("Unable to read existing certificate: %s" % to_native(e))
self.module.fail_json(msg=f"Unable to read existing certificate: {e}")
self.module.warn(f"Unable to read existing certificate: {e}")
def _set_time_parameters(self):
try:
@@ -486,15 +484,13 @@ class Certificate(OpensshModule):
self._safe_secure_move([(temp_certificate, self.path)])
except OSError as e:
self.module.fail_json(
msg="Unable to write certificate to %s: %s" % (self.path, to_native(e))
msg=f"Unable to write certificate to {self.path}: {e}"
)
try:
self.data = OpensshCertificate.load(self.path)
except (TypeError, ValueError) as e:
self.module.fail_json(
msg="Unable to read new certificate: %s" % to_native(e)
)
self.module.fail_json(msg=f"Unable to read new certificate: {e}")
def _generate_temp_certificate(self):
key_copy = os.path.join(self.module.tmpdir, os.path.basename(self.public_key))
@@ -502,9 +498,7 @@ class Certificate(OpensshModule):
try:
self.module.preserved_copy(self.public_key, key_copy)
except OSError as e:
self.module.fail_json(
msg="Unable to stage temporary key: %s" % to_native(e)
)
self.module.fail_json(msg=f"Unable to stage temporary key: {e}")
self.module.add_cleanup_file(key_copy)
self.ssh_keygen.generate_certificate(
@@ -535,7 +529,7 @@ class Certificate(OpensshModule):
os.remove(self.path)
except OSError as e:
self.module.fail_json(
msg="Unable to remove existing certificate: %s" % to_native(e)
msg=f"Unable to remove existing certificate: {to_native(e)}"
)
@property

View File

@@ -337,8 +337,7 @@ def main():
if not os.path.isdir(base_dir):
module.fail_json(
name=base_dir,
msg="The directory %s does not exist or the file is not a directory"
% base_dir,
msg=f"The directory {base_dir} does not exist or the file is not a directory",
)
try:

View File

@@ -341,9 +341,7 @@ def main():
with open(module.params["path"], "rb") as f:
data = f.read()
except (IOError, OSError) as e:
module.fail_json(
msg="Error while reading CSR file from disk: {0}".format(e)
)
module.fail_json(msg=f"Error while reading CSR file from disk: {e}")
backend, module_backend = select_backend(
module, module.params["select_crypto_backend"], data, validate_signature=True

View File

@@ -285,7 +285,7 @@ class DHParameterOpenSSL(DHParameterBase):
try:
module.atomic_move(os.path.abspath(tmpsrc), os.path.abspath(self.path))
except Exception as e:
module.fail_json(msg="Failed to write to file %s: %s" % (self.path, str(e)))
module.fail_json(msg=f"Failed to write to file {self.path}: {str(e)}")
def _check_params_valid(self, module):
"""Check if the params are in the correct state"""
@@ -381,8 +381,7 @@ def main():
if not os.path.isdir(base_dir):
module.fail_json(
name=base_dir,
msg="The directory '%s' does not exist or the file is not a directory"
% base_dir,
msg=f"The directory '{base_dir}' does not exist or the file is not a directory",
)
if module.params["state"] == "present":
@@ -405,9 +404,9 @@ def main():
if backend == "auto":
module.fail_json(
msg=(
"Cannot detect either the required Python library cryptography (>= {0}) "
f"Cannot detect either the required Python library cryptography (>= {MINIMAL_CRYPTOGRAPHY_VERSION}) "
"or the OpenSSL binary openssl"
).format(MINIMAL_CRYPTOGRAPHY_VERSION)
)
)
if backend == "openssl":
@@ -416,7 +415,7 @@ def main():
if not CRYPTOGRAPHY_FOUND:
module.fail_json(
msg=missing_required_lib(
"cryptography >= {0}".format(MINIMAL_CRYPTOGRAPHY_VERSION)
f"cryptography >= {MINIMAL_CRYPTOGRAPHY_VERSION}"
),
exception=CRYPTOGRAPHY_IMP_ERR,
)

View File

@@ -737,24 +737,20 @@ def select_backend(module, backend):
# Success?
if backend == "auto":
module.fail_json(
msg=(
"Cannot detect the required Python library cryptography (>= {0})"
).format(
MINIMAL_CRYPTOGRAPHY_VERSION,
)
msg=f"Cannot detect the required Python library cryptography (>= {MINIMAL_CRYPTOGRAPHY_VERSION})"
)
if backend == "cryptography":
if not CRYPTOGRAPHY_FOUND:
module.fail_json(
msg=missing_required_lib(
"cryptography >= {0}".format(MINIMAL_CRYPTOGRAPHY_VERSION)
f"cryptography >= {MINIMAL_CRYPTOGRAPHY_VERSION}"
),
exception=CRYPTOGRAPHY_IMP_ERR,
)
return backend, PkcsCryptography(module)
else:
raise ValueError("Unsupported value for backend: {0}".format(backend))
raise ValueError(f"Unsupported value for backend: {backend}")
def main():
@@ -812,8 +808,7 @@ def main():
if not os.path.isdir(base_dir):
module.fail_json(
name=base_dir,
msg="The directory '%s' does not exist or the path is not a directory"
% base_dir,
msg=f"The directory '{base_dir}' does not exist or the path is not a directory",
)
try:
@@ -862,7 +857,7 @@ def main():
result = pkcs12.dump()
result["changed"] = changed
if os.path.exists(module.params["path"]):
file_mode = "%04o" % stat.S_IMODE(os.stat(module.params["path"]).st_mode)
file_mode = f"{stat.S_IMODE(os.stat(module.params['path']).st_mode):04o}"
result["mode"] = file_mode
module.exit_json(**result)

View File

@@ -268,8 +268,7 @@ def main():
if not os.path.isdir(base_dir):
module.fail_json(
name=base_dir,
msg="The directory %s does not exist or the file is not a directory"
% base_dir,
msg=f"The directory {base_dir} does not exist or the file is not a directory",
)
backend, module_backend = select_backend(

View File

@@ -146,8 +146,7 @@ def main():
if not os.path.isdir(base_dir):
module.fail_json(
name=base_dir,
msg="The directory %s does not exist or the file is not a directory"
% base_dir,
msg=f"The directory {base_dir} does not exist or the file is not a directory",
)
module_backend = select_backend(module=module)

View File

@@ -242,8 +242,7 @@ def main():
data = f.read()
except (IOError, OSError) as e:
module.fail_json(
msg="Error while reading private key file from disk: {0}".format(e),
**result,
msg=f"Error while reading private key file from disk: {e}", **result
)
result["can_load_key"] = True

View File

@@ -301,7 +301,7 @@ class PublicKey(OpenSSLObject):
if self.privatekey_content is None and not os.path.exists(self.privatekey_path):
raise PublicKeyError(
"The private key %s does not exist" % self.privatekey_path
f"The private key {self.privatekey_path} does not exist"
)
if not self.check(module, perms_required=False) or self.force:
@@ -461,9 +461,7 @@ def main():
# Success?
if backend == "auto":
module.fail_json(
msg=(
"Cannot detect the required Python library " "cryptography (>= {0})"
).format(minimal_cryptography_version)
msg=f"Cannot detect the required Python library cryptography (>= {minimal_cryptography_version})",
)
if module.params["format"] == "OpenSSH" and backend != "cryptography":
@@ -473,7 +471,7 @@ def main():
if not CRYPTOGRAPHY_FOUND:
module.fail_json(
msg=missing_required_lib(
"cryptography >= {0}".format(minimal_cryptography_version)
f"cryptography >= {minimal_cryptography_version}"
),
exception=CRYPTOGRAPHY_IMP_ERR,
)
@@ -482,8 +480,7 @@ def main():
if not os.path.isdir(base_dir):
module.fail_json(
name=base_dir,
msg="The directory '%s' does not exist or the file is not a directory"
% base_dir,
msg=f"The directory '{base_dir}' does not exist or the file is not a directory",
)
try:

View File

@@ -190,8 +190,7 @@ def main():
data = f.read()
except (IOError, OSError) as e:
module.fail_json(
msg="Error while reading public key file from disk: {0}".format(e),
**result,
msg=f"Error while reading public key file from disk: {e}", **result
)
backend, module_backend = select_backend(

View File

@@ -230,9 +230,7 @@ class SignatureCryptography(SignatureBase):
if signature is None:
self.module.fail_json(
msg="Unsupported key type. Your cryptography version is {0}".format(
CRYPTOGRAPHY_VERSION
)
msg=f"Unsupported key type. Your cryptography version is {CRYPTOGRAPHY_VERSION}"
)
result["signature"] = base64.b64encode(signature)
@@ -261,7 +259,7 @@ def main():
if not os.path.isfile(module.params["path"]):
module.fail_json(
name=module.params["path"],
msg="The file {0} does not exist".format(module.params["path"]),
msg=f"The file {module.params['path']} does not exist",
)
backend = module.params["select_crypto_backend"]
@@ -279,16 +277,14 @@ def main():
# Success?
if backend == "auto":
module.fail_json(
msg=(
"Cannot detect the required Python library " "cryptography (>= {0})"
).format(MINIMAL_CRYPTOGRAPHY_VERSION)
msg=f"Cannot detect the required Python library cryptography (>= {MINIMAL_CRYPTOGRAPHY_VERSION})",
)
try:
if backend == "cryptography":
if not CRYPTOGRAPHY_FOUND:
module.fail_json(
msg=missing_required_lib(
"cryptography >= {0}".format(MINIMAL_CRYPTOGRAPHY_VERSION)
f"cryptography >= {MINIMAL_CRYPTOGRAPHY_VERSION}"
),
exception=CRYPTOGRAPHY_IMP_ERR,
)

View File

@@ -252,9 +252,7 @@ class SignatureInfoCryptography(SignatureInfoBase):
if not verified:
self.module.fail_json(
msg="Unsupported key type. Your cryptography version is {0}".format(
CRYPTOGRAPHY_VERSION
)
msg=f"Unsupported key type. Your cryptography version is {CRYPTOGRAPHY_VERSION}"
)
result["valid"] = valid
return result
@@ -282,7 +280,7 @@ def main():
if not os.path.isfile(module.params["path"]):
module.fail_json(
name=module.params["path"],
msg="The file {0} does not exist".format(module.params["path"]),
msg=f"The file {module.params['path']} does not exist",
)
backend = module.params["select_crypto_backend"]
@@ -300,17 +298,14 @@ def main():
# Success?
if backend == "auto":
module.fail_json(
msg=(
"Cannot detect any of the required Python libraries "
"cryptography (>= {0})"
).format(MINIMAL_CRYPTOGRAPHY_VERSION)
msg=f"Cannot detect any of the required Python libraries cryptography (>= {MINIMAL_CRYPTOGRAPHY_VERSION})"
)
try:
if backend == "cryptography":
if not CRYPTOGRAPHY_FOUND:
module.fail_json(
msg=missing_required_lib(
"cryptography >= {0}".format(MINIMAL_CRYPTOGRAPHY_VERSION)
f"cryptography >= {MINIMAL_CRYPTOGRAPHY_VERSION}"
),
exception=CRYPTOGRAPHY_IMP_ERR,
)

View File

@@ -386,8 +386,7 @@ def main():
if not os.path.isdir(base_dir):
module.fail_json(
name=base_dir,
msg="The directory %s does not exist or the file is not a directory"
% base_dir,
msg=f"The directory {base_dir} does not exist or the file is not a directory",
)
provider = module.params["provider"]

View File

@@ -152,16 +152,12 @@ def parse_certificate(input, strict=False):
pems = split_pem_list(to_text(input))
if len(pems) > 1 and strict:
raise ValueError(
"The input contains {count} PEM objects, expecting only one since strict=true".format(
count=len(pems)
)
f"The input contains {len(pems)} PEM objects, expecting only one since strict=true"
)
pem_header_type, content = extract_pem(pems[0], strict=strict)
if strict and pem_header_type not in ("CERTIFICATE", "X509 CERTIFICATE"):
raise ValueError(
"type is {type!r}, expecting CERTIFICATE or X509 CERTIFICATE".format(
type=pem_header_type
)
f"type is {pem_header_type!r}, expecting CERTIFICATE or X509 CERTIFICATE"
)
input = base64.b64decode(content)
else:
@@ -187,18 +183,14 @@ class X509CertificateConvertModule(OpenSSLObject):
try:
self.input = base64.b64decode(self.input)
except Exception as exc:
module.fail_json(
msg="Cannot Base64 decode src_content: {exc}".format(exc=exc)
)
module.fail_json(msg=f"Cannot Base64 decode src_content: {exc}")
else:
try:
with open(self.src_path, "rb") as f:
self.input = f.read()
except Exception as exc:
module.fail_json(
msg="Failure while reading file {fn}: {exc}".format(
fn=self.src_path, exc=exc
)
msg=f"Failure while reading file {self.src_path}: {exc}"
)
self.format = module.params["format"]
@@ -210,7 +202,7 @@ class X509CertificateConvertModule(OpenSSLObject):
self.input, strict=self.strict
)
except Exception as exc:
module.fail_json(msg="Error while parsing PEM: {exc}".format(exc=exc))
module.fail_json(msg=f"Error while parsing PEM: {exc}")
if module.params["verify_cert_parsable"]:
self.verify_cert_parsable(module)
@@ -237,16 +229,14 @@ class X509CertificateConvertModule(OpenSSLObject):
if not CRYPTOGRAPHY_FOUND:
module.fail_json(
msg=missing_required_lib(
"cryptography >= {0}".format(MINIMAL_CRYPTOGRAPHY_VERSION)
f"cryptography >= {MINIMAL_CRYPTOGRAPHY_VERSION}"
),
exception=CRYPTOGRAPHY_IMP_ERR,
)
try:
load_der_x509_certificate(self.input, default_backend())
except Exception as exc:
module.fail_json(
msg="Error while parsing certificate: {exc}".format(exc=exc)
)
module.fail_json(msg=f"Error while parsing certificate: {exc}")
def needs_conversion(self):
if self.dest_content is None or self.dest_content_format is None:
@@ -263,11 +253,9 @@ class X509CertificateConvertModule(OpenSSLObject):
if self.format == "der":
return self.input
data = to_bytes(base64.b64encode(self.input))
lines = [to_bytes("{0}{1}{2}".format(PEM_START, self.wanted_pem_type, PEM_END))]
lines = [to_bytes(f"{PEM_START}{self.wanted_pem_type}{PEM_END}")]
lines += [data[i : i + 64] for i in range(0, len(data), 64)]
lines.append(
to_bytes("{0}{1}{2}\n".format(PEM_END_START, self.wanted_pem_type, PEM_END))
)
lines.append(to_bytes(f"{PEM_END_START}{self.wanted_pem_type}{PEM_END}\n"))
return b"\n".join(lines)
def generate(self, module):
@@ -323,8 +311,7 @@ def main():
if not os.path.isdir(base_dir):
module.fail_json(
name=base_dir,
msg="The directory %s does not exist or the file is not a directory"
% base_dir,
msg=f"The directory {base_dir} does not exist or the file is not a directory",
)
try:

View File

@@ -431,9 +431,7 @@ def main():
with open(module.params["path"], "rb") as f:
data = f.read()
except (IOError, OSError) as e:
module.fail_json(
msg="Error while reading certificate file from disk: {0}".format(e)
)
module.fail_json(msg=f"Error while reading certificate file from disk: {e}")
backend, module_backend = select_backend(
module, module.params["select_crypto_backend"], data
@@ -444,12 +442,10 @@ def main():
for k, v in valid_at.items():
if not isinstance(v, string_types):
module.fail_json(
msg="The value for valid_at.{0} must be of type string (got {1})".format(
k, type(v)
)
msg=f"The value for valid_at.{k} must be of type string (got {type(v)})"
)
valid_at[k] = get_relative_time_option(
v, "valid_at.{0}".format(k), with_timezone=CRYPTOGRAPHY_TIMEZONE
v, f"valid_at.{k}", with_timezone=CRYPTOGRAPHY_TIMEZONE
)
try:

View File

@@ -560,9 +560,7 @@ class CRL(OpenSSLObject):
self.digest = select_message_digest(module.params["digest"])
if self.digest is None:
raise CRLError(
'The digest "{0}" is not supported'.format(module.params["digest"])
)
raise CRLError(f'The digest "{module.params["digest"]}" is not supported')
self.module = module
@@ -578,7 +576,7 @@ class CRL(OpenSSLObject):
"invalidity_date": None,
"invalidity_date_critical": False,
}
path_prefix = "revoked_certificates[{0}].".format(i)
path_prefix = f"revoked_certificates[{i}]."
if rc["path"] is not None or rc["content"] is not None:
# Load certificate from file or content
try:
@@ -591,15 +589,11 @@ class CRL(OpenSSLObject):
except OpenSSLObjectError as e:
if rc["content"] is not None:
module.fail_json(
msg="Cannot parse certificate from {0}content: {1}".format(
path_prefix, to_native(e)
)
msg=f"Cannot parse certificate from {path_prefix}content: {e}"
)
else:
module.fail_json(
msg='Cannot read certificate "{1}" from {0}path: {2}'.format(
path_prefix, rc["path"], to_native(e)
)
msg=f'Cannot read certificate "{rc["path"]}" from {path_prefix}path: {e}'
)
else:
# Specify serial_number (and potentially issuer) directly
@@ -668,23 +662,17 @@ class CRL(OpenSSLObject):
return check_type_int(value)
except TypeError as exc:
self.module.fail_json(
msg="Error while parsing revoked_certificates[{idx}].serial_number as an integer: {exc}".format(
idx=index + 1,
exc=to_native(exc),
)
msg=f"Error while parsing revoked_certificates[{index + 1}].serial_number as an integer: {exc}"
)
if self.serial_numbers_format == "hex-octets":
try:
return parse_serial(check_type_str(value))
except (TypeError, ValueError) as exc:
self.module.fail_json(
msg="Error while parsing revoked_certificates[{idx}].serial_number as an colon-separated hex octet string: {exc}".format(
idx=index + 1,
exc=to_native(exc),
)
msg=f"Error while parsing revoked_certificates[{index + 1}].serial_number as an colon-separated hex octet string: {exc}"
)
raise RuntimeError(
"Unexpected value %s of serial_numbers" % (self.serial_numbers_format,)
f"Unexpected value {self.serial_numbers_format} of serial_numbers"
)
def _get_info(self, data):
@@ -1026,9 +1014,7 @@ def main():
if not CRYPTOGRAPHY_FOUND:
module.fail_json(
msg=missing_required_lib(
"cryptography >= {0}".format(MINIMAL_CRYPTOGRAPHY_VERSION)
),
msg=missing_required_lib(f"cryptography >= {MINIMAL_CRYPTOGRAPHY_VERSION}"),
exception=CRYPTOGRAPHY_IMP_ERR,
)

View File

@@ -207,18 +207,14 @@ def main():
with open(module.params["path"], "rb") as f:
data = f.read()
except (IOError, OSError) as e:
module.fail_json(
msg="Error while reading CRL file from disk: {0}".format(e)
)
module.fail_json(msg=f"Error while reading CRL file from disk: {e}")
else:
data = module.params["content"].encode("utf-8")
if not identify_pem_format(data):
try:
data = base64.b64decode(module.params["content"])
except (binascii.Error, TypeError) as e:
module.fail_json(
msg="Error while Base64 decoding content: {0}".format(e)
)
module.fail_json(msg=f"Error while Base64 decoding content: {e}")
try:
result = get_crl_info(

View File

@@ -99,9 +99,7 @@ class AnsibleActionModule:
# Before ansible-core 2.14.2, deprecations were always for aliases:
if "name" in d:
self.deprecate(
"Alias '{name}' is deprecated. See the module docs for more information".format(
name=d["name"]
),
f"Alias '{d['name']}' is deprecated. See the module docs for more information",
version=d.get("version"),
date=d.get("date"),
collection_name=d.get("collection_name"),
@@ -116,19 +114,13 @@ class AnsibleActionModule:
)
for w in self._validation_result._warnings:
self.warn(
"Both option {option} and its alias {alias} are set.".format(
option=w["option"], alias=w["alias"]
)
)
self.warn(f"Both option {w['option']} and its alias {w['alias']} are set.")
# Fail for validation errors, even in check mode
if error:
msg = self._validation_result.errors.msg
if isinstance(error, UnsupportedError):
msg = "Unsupported parameters for ({name}) {kind}: {msg}".format(
name=self._name, kind="module", msg=msg
)
msg = f"Unsupported parameters for ({self._name}) module: {msg}"
self.fail_json(msg=msg)
@@ -140,7 +132,7 @@ class AnsibleActionModule:
if isinstance(warning, string_types):
self.__warnings.append(warning)
else:
raise TypeError("warn requires a string not a %s" % type(warning))
raise TypeError(f"warn requires a string not a {type(warning)}")
def deprecate(self, msg, version=None, date=None, collection_name=None):
if version is not None and date is not None:
@@ -161,7 +153,7 @@ class AnsibleActionModule:
{"msg": msg, "version": version, "collection_name": collection_name}
)
else:
raise TypeError("deprecate requires a string not a %s" % type(msg))
raise TypeError(f"deprecate requires a string not a {type(msg)}")
def _return_formatted(self, kwargs):
if "invocation" not in kwargs:

View File

@@ -44,12 +44,9 @@ class PluginGPGRunner(GPGRunner):
stdout = to_native(stdout, errors="surrogate_or_replace")
stderr = to_native(stderr, errors="surrogate_or_replace")
if check_rc and p.returncode != 0:
stdout_n = (to_native(stdout, errors="surrogate_or_replace"),)
stderr_n = (to_native(stderr, errors="surrogate_or_replace"),)
raise GPGError(
'Running {cmd} yielded return code {rc} with stdout: "{stdout}" and stderr: "{stderr}")'.format(
cmd=" ".join(command),
rc=p.returncode,
stdout=to_native(stdout, errors="surrogate_or_replace"),
stderr=to_native(stderr, errors="surrogate_or_replace"),
)
f'Running {" ".join(command)} yielded return code {p.returncode} with stdout: "{stdout_n}" and stderr: "{stderr_n}")'
)
return p.returncode, stdout, stderr

View File

@@ -78,7 +78,7 @@ TEST_CASES = [
@pytest.mark.parametrize("value, expected", TEST_CASES)
def test_serialize_asn1_string_as_der(value, expected):
actual = serialize_asn1_string_as_der(value)
print("%s | %s" % (value, base64.b16encode(actual).decode()))
print(f"{value} | {base64.b16encode(actual).decode()}")
assert actual == expected
@@ -121,10 +121,8 @@ def test_test_cases(value, expected, tmp_path):
b_data = fd.read()
hex_str = base64.b16encode(b_data).decode().lower()
print(
"%s | \\x%s"
% (value, "\\x".join([hex_str[i : i + 2] for i in range(0, len(hex_str), 2)]))
)
value = "\\x".join([hex_str[i : i + 2] for i in range(0, len(hex_str), 2)])
print(f"{value} | \\x{value}")
# This is a know edge case where openssl asn1parse does not work properly.
if value != "UTF8:café":

View File

@@ -201,7 +201,7 @@ if (
],
)
def test_parse_dn_component_failure(name, options, message):
with pytest.raises(OpenSSLObjectError, match="^%s$" % re.escape(message)):
with pytest.raises(OpenSSLObjectError, match=f"^{re.escape(message)}$"):
_parse_dn_component(name, **options)
@@ -245,5 +245,5 @@ def test_parse_dn(name, expected):
],
)
def test_parse_dn_failure(name, message):
with pytest.raises(OpenSSLObjectError, match="^%s$" % re.escape(message)):
with pytest.raises(OpenSSLObjectError, match=f"^{re.escape(message)}$"):
_parse_dn(name)

View File

@@ -144,7 +144,7 @@ def test_default_key_params(keytype, size, passphrase, comment):
"ed25519": 256,
}
default_comment = "%s@%s" % (getuser(), gethostname())
default_comment = f"{getuser()}@{gethostname()}"
pair = OpensshKeypair.generate(
keytype=keytype, size=size, passphrase=passphrase, comment=comment
)