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

@@ -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'
)