Cleanup with ruff check (#963)

* Implement improvements suggested by ruff check.

* Add ruff check to CI.

* Add changelog fragment.
This commit is contained in:
Felix Fontein
2025-10-28 07:21:11 +01:00
committed by GitHub
parent 6f0c58f483
commit 5420f9baaf
39 changed files with 198 additions and 199 deletions

View File

@@ -16,6 +16,8 @@ stable_branches = [ "stable-*" ]
run_isort = true
isort_config = ".isort.cfg"
run_black = true
run_ruff_check = true
ruff_check_config = "ruff.toml"
run_flake8 = true
flake8_config = ".flake8"
run_pylint = true

View File

@@ -0,0 +1,2 @@
bugfixes:
- "Smaller code cleanup (https://github.com/ansible-collections/community.crypto/pull/963)."

View File

@@ -56,9 +56,6 @@ if t.TYPE_CHECKING:
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
from ansible_collections.community.crypto.plugins.module_utils._acme.account import ( # pragma: no cover
ACMEAccount,
)
from ansible_collections.community.crypto.plugins.module_utils._acme.backends import ( # pragma: no cover
CertificateInformation,
CryptoBackend,
@@ -132,12 +129,10 @@ def _is_failed(
) -> bool:
if info["status"] < 200 or info["status"] >= 400:
return True
if (
return bool(
expected_status_codes is not None
and info["status"] not in expected_status_codes
):
return True
return False
)
class ACMEDirectory:

View File

@@ -46,7 +46,7 @@ class CertificateChain:
@classmethod
def download(
cls: t.Type[_CertificateChain], *, client: ACMEClient, url: str
cls: type[_CertificateChain], *, client: ACMEClient, url: str
) -> _CertificateChain:
content, info = client.get_request(
url,

View File

@@ -82,7 +82,7 @@ class Challenge:
@classmethod
def from_json(
cls: t.Type[_Challenge],
cls: type[_Challenge],
*,
client: ACMEClient,
data: dict[str, t.Any],
@@ -188,7 +188,7 @@ class Authorization:
@classmethod
def from_json(
cls: t.Type[_Authorization],
cls: type[_Authorization],
*,
client: ACMEClient,
data: dict[str, t.Any],
@@ -200,7 +200,7 @@ class Authorization:
@classmethod
def from_url(
cls: t.Type[_Authorization], *, client: ACMEClient, url: str
cls: type[_Authorization], *, client: ACMEClient, url: str
) -> _Authorization:
result = cls(url=url)
result.refresh(client=client)
@@ -208,7 +208,7 @@ class Authorization:
@classmethod
def create(
cls: t.Type[_Authorization],
cls: type[_Authorization],
*,
client: ACMEClient,
identifier_type: str,
@@ -384,7 +384,7 @@ class Authorization:
@classmethod
def deactivate_url(
cls: t.Type[_Authorization], *, client: ACMEClient, url: str
cls: type[_Authorization], *, client: ACMEClient, url: str
) -> _Authorization:
"""
Deactivates this authorization.

View File

@@ -63,21 +63,21 @@ class Order:
@classmethod
def from_json(
cls: t.Type[_Order], *, client: ACMEClient, data: dict[str, t.Any], url: str
cls: type[_Order], *, client: ACMEClient, data: dict[str, t.Any], url: str
) -> _Order:
result = cls(url=url)
result._setup(client=client, data=data)
return result
@classmethod
def from_url(cls: t.Type[_Order], *, client: ACMEClient, url: str) -> _Order:
def from_url(cls: type[_Order], *, client: ACMEClient, url: str) -> _Order:
result = cls(url=url)
result.refresh(client=client)
return result
@classmethod
def create(
cls: t.Type[_Order],
cls: type[_Order],
*,
client: ACMEClient,
identifiers: list[tuple[str, str]],
@@ -117,7 +117,7 @@ class Order:
@classmethod
def create_with_error_handling(
cls: t.Type[_Order],
cls: type[_Order],
*,
client: ACMEClient,
identifiers: list[tuple[str, str]],

View File

@@ -114,19 +114,16 @@ if t.TYPE_CHECKING:
PrivateKeyTypes,
PublicKeyTypes,
)
from cryptography.hazmat.primitives.serialization.pkcs12 import ( # pragma: no cover
PKCS12KeyAndCertificates,
)
CertificatePrivateKeyTypes = t.Union[
CertificatePrivateKeyTypes = t.Union[ # noqa: UP007
CertificateIssuerPrivateKeyTypes,
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey,
cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey,
] # pragma: no cover
PublicKeyTypesWOEdwards = t.Union[ # pylint: disable=invalid-name
PublicKeyTypesWOEdwards = t.Union[ # noqa: UP007 # pylint: disable=invalid-name
DHPublicKey, DSAPublicKey, EllipticCurvePublicKey, RSAPublicKey
] # pragma: no cover
PrivateKeyTypesWOEdwards = t.Union[ # pylint: disable=invalid-name
PrivateKeyTypesWOEdwards = t.Union[ # noqa: UP007 # pylint: disable=invalid-name
DHPrivateKey, DSAPrivateKey, EllipticCurvePrivateKey, RSAPrivateKey
] # pragma: no cover
else:
@@ -727,9 +724,9 @@ def cryptography_key_needs_digest_for_signing(
key, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey
):
return False
if isinstance(key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey):
return False
return True
return not isinstance(
key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey
)
def _compare_public_keys(

View File

@@ -41,9 +41,6 @@ if t.TYPE_CHECKING:
import datetime # pragma: no cover
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
from cryptography.hazmat.primitives.asymmetric.types import ( # pragma: no cover
CertificateIssuerPrivateKeyTypes,
)
from ansible_collections.community.crypto.plugins.module_utils._crypto.cryptography_support import ( # pragma: no cover
CertificatePrivateKeyTypes,
@@ -324,15 +321,19 @@ class CertificateBackend(metaclass=abc.ABCMeta):
return True
# Check not before
if not_before is not None and not self.ignore_timestamps:
if get_not_valid_before(self.existing_certificate) != not_before:
return True
if (
not_before is not None
and not self.ignore_timestamps
and get_not_valid_before(self.existing_certificate) != not_before
):
return True
# Check not after
if not_after is not None and not self.ignore_timestamps:
if get_not_valid_after(self.existing_certificate) != not_after:
return True
return False
return bool(
not_after is not None
and not self.ignore_timestamps
and get_not_valid_after(self.existing_certificate) != not_after
)
def dump(self, *, include_certificate: bool) -> dict[str, t.Any]:
"""Serialize the object into a dictionary."""

View File

@@ -46,9 +46,6 @@ if t.TYPE_CHECKING:
PublicKeyTypes, # pragma: no cover
)
from ansible_collections.community.crypto.plugins.module_utils._argspec import ( # pragma: no cover
ArgumentSpec,
)
from ansible_collections.community.crypto.plugins.plugin_utils._action_module import ( # pragma: no cover
AnsibleActionModule,
)
@@ -56,7 +53,7 @@ if t.TYPE_CHECKING:
FilterModuleMock,
)
GeneralAnsibleModule = t.Union[
GeneralAnsibleModule = t.Union[ # noqa: UP007
AnsibleModule, AnsibleActionModule, FilterModuleMock
] # pragma: no cover
@@ -270,9 +267,11 @@ class CertificateInfoRetrieval:
x509.AuthorityInformationAccess
)
for desc in ext.value:
if desc.access_method == x509.oid.AuthorityInformationAccessOID.OCSP:
if isinstance(desc.access_location, x509.UniformResourceIdentifier):
return desc.access_location.value
if (
desc.access_method == x509.oid.AuthorityInformationAccessOID.OCSP
and isinstance(desc.access_location, x509.UniformResourceIdentifier)
):
return desc.access_location.value
except x509.ExtensionNotFound:
pass
return None
@@ -286,9 +285,8 @@ class CertificateInfoRetrieval:
if (
desc.access_method
== x509.oid.AuthorityInformationAccessOID.CA_ISSUERS
):
if isinstance(desc.access_location, x509.UniformResourceIdentifier):
return desc.access_location.value
) and isinstance(desc.access_location, x509.UniformResourceIdentifier):
return desc.access_location.value
except x509.ExtensionNotFound:
pass
return None

View File

@@ -45,9 +45,6 @@ if t.TYPE_CHECKING:
import datetime # pragma: no cover
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
from cryptography.hazmat.primitives.asymmetric.types import ( # pragma: no cover
CertificateIssuerPrivateKeyTypes,
)
from ansible_collections.community.crypto.plugins.module_utils._argspec import ( # pragma: no cover
ArgumentSpec,

View File

@@ -181,7 +181,7 @@ class SelfSignedCertificateBackendCryptography(CertificateBackend):
assert self.existing_certificate is not None
# Check whether certificate is signed by private key
if not cryptography_verify_certificate_signature(
if not cryptography_verify_certificate_signature( # noqa: SIM103
certificate=self.existing_certificate,
signer_public_key=self.privatekey.public_key(),
):

View File

@@ -29,9 +29,6 @@ from ansible_collections.community.crypto.plugins.module_utils._cryptography_dep
if t.TYPE_CHECKING:
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
from cryptography.hazmat.primitives.asymmetric.types import ( # pragma: no cover
PrivateKeyTypes,
)
from ansible_collections.community.crypto.plugins.plugin_utils._action_module import ( # pragma: no cover
AnsibleActionModule,
@@ -40,7 +37,7 @@ if t.TYPE_CHECKING:
FilterModuleMock,
)
GeneralAnsibleModule = t.Union[
GeneralAnsibleModule = t.Union[ # noqa: UP007
AnsibleModule, AnsibleActionModule, FilterModuleMock
] # pragma: no cover

View File

@@ -52,11 +52,6 @@ if t.TYPE_CHECKING:
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
from cryptography.hazmat.primitives.asymmetric.types import ( # pragma: no cover
CertificateIssuerPrivateKeyTypes,
PrivateKeyTypes,
)
from ansible_collections.community.crypto.plugins.module_utils._crypto.cryptography_support import ( # pragma: no cover
CertificatePrivateKeyTypes,
)
_ET = t.TypeVar("_ET", bound="cryptography.x509.ExtensionType") # pragma: no cover
@@ -533,10 +528,11 @@ class CertificateSigningRequestBackend:
)
if set(altnames) != set(current_altnames):
return False
if altnames and current_altnames_ext:
if current_altnames_ext.critical != self.subject_alt_name_critical:
return False
return True
return not (
altnames
and current_altnames_ext
and current_altnames_ext.critical != self.subject_alt_name_critical
)
def _check_key_usage(extensions: cryptography.x509.Extensions) -> bool:
current_keyusage_ext = _find_extension(
@@ -578,10 +574,11 @@ class CertificateSigningRequestBackend:
)
if set(current_usages) != set(usages):
return False
if usages and current_usages_ext:
if current_usages_ext.critical != self.extended_key_usage_critical:
return False
return True
return not (
usages
and current_usages_ext
and current_usages_ext.critical != self.extended_key_usage_critical
)
def _check_basic_constraints(extensions: cryptography.x509.Extensions) -> bool:
bc_ext = _find_extension(extensions, cryptography.x509.BasicConstraints)
@@ -652,10 +649,11 @@ class CertificateSigningRequestBackend:
current_nc_excl
):
return False
if (nc_perm or nc_excl) and current_nc_ext:
if current_nc_ext.critical != self.name_constraints_critical:
return False
return True
return not (
(nc_perm or nc_excl)
and current_nc_ext
and current_nc_ext.critical != self.name_constraints_critical
)
def _check_subject_key_identifier(
extensions: cryptography.x509.Extensions,

View File

@@ -35,7 +35,6 @@ if t.TYPE_CHECKING:
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
from cryptography.hazmat.primitives.asymmetric.types import ( # pragma: no cover
CertificatePublicKeyTypes,
PrivateKeyTypes,
)
from ansible_collections.community.crypto.plugins.plugin_utils._action_module import ( # pragma: no cover
@@ -45,7 +44,7 @@ if t.TYPE_CHECKING:
FilterModuleMock,
)
GeneralAnsibleModule = t.Union[
GeneralAnsibleModule = t.Union[ # noqa: UP007
AnsibleModule, AnsibleActionModule, FilterModuleMock
] # pragma: no cover

View File

@@ -47,7 +47,7 @@ if t.TYPE_CHECKING:
AnsibleActionModule,
)
GeneralAnsibleModule = t.Union[
GeneralAnsibleModule = t.Union[ # noqa: UP007
AnsibleModule, AnsibleActionModule
] # pragma: no cover
@@ -495,26 +495,28 @@ class PrivateKeyBackend:
" set to `full_idempotence` or `always`, or with `force=true`."
)
self._ensure_existing_private_key_loaded()
if self.regenerate != "never":
if not self._check_size_and_type():
if self.regenerate in ("partial_idempotence", "full_idempotence"):
return True
self.module.fail_json(
msg="Key has wrong type and/or size."
" Will not proceed. To force regeneration, call the module with `generate`"
" set to `partial_idempotence`, `full_idempotence` or `always`, or with `force=true`."
)
if self.regenerate != "never" and not self._check_size_and_type():
if self.regenerate in ("partial_idempotence", "full_idempotence"):
return True
self.module.fail_json(
msg="Key has wrong type and/or size."
" Will not proceed. To force regeneration, call the module with `generate`"
" set to `partial_idempotence`, `full_idempotence` or `always`, or with `force=true`."
)
# During generation step, regenerate if format does not match and format_mismatch == 'regenerate'
if self.format_mismatch == "regenerate" and self.regenerate != "never":
if not self._check_format():
if self.regenerate in ("partial_idempotence", "full_idempotence"):
return True
self.module.fail_json(
msg="Key has wrong format."
" Will not proceed. To force regeneration, call the module with `generate`"
" set to `partial_idempotence`, `full_idempotence` or `always`, or with `force=true`."
" To convert the key, set `format_mismatch` to `convert`."
)
if (
self.format_mismatch == "regenerate"
and self.regenerate != "never"
and not self._check_format()
):
if self.regenerate in ("partial_idempotence", "full_idempotence"):
return True
self.module.fail_json(
msg="Key has wrong format."
" Will not proceed. To force regeneration, call the module with `generate`"
" set to `partial_idempotence`, `full_idempotence` or `always`, or with `force=true`."
" To convert the key, set `format_mismatch` to `convert`."
)
return False
def needs_conversion(self) -> bool:

View File

@@ -47,7 +47,7 @@ if t.TYPE_CHECKING:
FilterModuleMock,
)
GeneralAnsibleModule = t.Union[
GeneralAnsibleModule = t.Union[ # noqa: UP007
AnsibleModule, AnsibleActionModule, FilterModuleMock
] # pragma: no cover
@@ -122,9 +122,7 @@ def _check_dsa_consistency(
if binary_exp_mod(g, x, m=p) != y:
return False
# Check (quickly) whether p or q are not primes
if quick_is_not_prime(q) or quick_is_not_prime(p):
return False
return True
return not (quick_is_not_prime(q) or quick_is_not_prime(p))
def _is_cryptography_key_consistent(

View File

@@ -35,7 +35,7 @@ if t.TYPE_CHECKING:
FilterModuleMock,
)
GeneralAnsibleModule = t.Union[
GeneralAnsibleModule = t.Union[ # noqa: UP007
AnsibleModule, AnsibleActionModule, FilterModuleMock
] # pragma: no cover

View File

@@ -33,7 +33,7 @@ if t.TYPE_CHECKING:
FilterModuleMock,
)
GeneralAnsibleModule = t.Union[
GeneralAnsibleModule = t.Union[ # noqa: UP007
AnsibleModule, AnsibleActionModule, FilterModuleMock
] # pragma: no cover
@@ -69,7 +69,7 @@ def assert_required_cryptography_version(
msg=missing_required_lib(f"cryptography >= {minimum_cryptography_version}"),
exception=_CRYPTOGRAPHY_IMP_ERR,
)
if CRYPTOGRAPHY_VERSION < LooseVersion(minimum_cryptography_version):
if LooseVersion(minimum_cryptography_version) > CRYPTOGRAPHY_VERSION:
module.fail_json(
msg=(
f"Cannot detect the required Python library cryptography (>= {minimum_cryptography_version})."

View File

@@ -21,10 +21,6 @@ from ansible_collections.community.crypto.plugins.module_utils._openssh.utils im
if t.TYPE_CHECKING:
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
from cryptography.hazmat.primitives.asymmetric.types import ( # pragma: no cover
CertificateIssuerPrivateKeyTypes,
PrivateKeyTypes,
)
from ansible_collections.community.crypto.plugins.module_utils._openssh.certificate import ( # pragma: no cover
OpensshCertificateTimeParameters,
@@ -96,7 +92,7 @@ def _restore_all_on_failure(
os.path.abspath(backup), os.path.abspath(destination)
)
raise
for destination, backup in backups:
for dummy_destination, backup in backups:
self.module.add_cleanup_file(backup)
return backup_and_restore
@@ -373,7 +369,9 @@ class PrivateKey:
return self._format
@classmethod
def from_string(cls: t.Type[_PrivateKey], string: str) -> _PrivateKey:
def from_string(
cls: t.Type[_PrivateKey], string: str # noqa: UP006
) -> _PrivateKey:
properties = string.split()
return cls(
@@ -439,7 +437,7 @@ class PublicKey:
return self._type_string
@classmethod
def from_string(cls: t.Type[_PublicKey], string: str) -> _PublicKey:
def from_string(cls: type[_PublicKey], string: str) -> _PublicKey:
properties = string.strip("\n").split(" ", 2)
return cls(
@@ -449,7 +447,7 @@ class PublicKey:
)
@classmethod
def load(cls: t.Type[_PublicKey], path: str | os.PathLike) -> _PublicKey | None:
def load(cls: type[_PublicKey], path: str | os.PathLike) -> _PublicKey | None:
with open(path, "r", encoding="utf-8") as f:
properties = f.read().strip(" \n").split(" ", 2)

View File

@@ -46,10 +46,6 @@ from ansible_collections.community.crypto.plugins.module_utils._version import (
if t.TYPE_CHECKING:
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
from cryptography.hazmat.primitives.asymmetric.types import ( # pragma: no cover
CertificateIssuerPrivateKeyTypes,
PrivateKeyTypes,
)
class KeypairBackend(OpensshModule, metaclass=abc.ABCMeta):

View File

@@ -312,7 +312,7 @@ class OpensshCertificateOption:
@classmethod
def from_string(
cls: t.Type[_OpensshCertificateOption], option_string: str
cls: t.Type[_OpensshCertificateOption], option_string: str # noqa: UP006
) -> _OpensshCertificateOption:
if not isinstance(option_string, str):
raise ValueError(
@@ -573,7 +573,7 @@ class OpensshCertificate:
@classmethod
def load(
cls: t.Type[_OpensshCertificate], path: str | os.PathLike
cls: t.Type[_OpensshCertificate], path: str | os.PathLike # noqa: UP006
) -> _OpensshCertificate:
if not os.path.exists(path):
raise ValueError(f"{path} is not a valid path.")

View File

@@ -79,13 +79,13 @@ if t.TYPE_CHECKING:
KeySerializationFormat = t.Literal["PEM", "DER", "SSH"] # pragma: no cover
KeyType = t.Literal["rsa", "dsa", "ed25519", "ecdsa"] # pragma: no cover
PrivateKeyTypes = t.Union[
PrivateKeyTypes = t.Union[ # noqa: UP007
rsa.RSAPrivateKey,
dsa.DSAPrivateKey,
ec.EllipticCurvePrivateKey,
Ed25519PrivateKey,
] # pragma: no cover
PublicKeyTypes = t.Union[
PublicKeyTypes = t.Union[ # noqa: UP007
rsa.RSAPublicKey, dsa.DSAPublicKey, ec.EllipticCurvePublicKey, Ed25519PublicKey
] # pragma: no cover
@@ -149,7 +149,7 @@ class AsymmetricKeypair:
@classmethod
def generate(
cls: t.Type[_AsymmetricKeypair],
cls: type[_AsymmetricKeypair],
*,
keytype: KeyType = "rsa",
size: int | None = None,
@@ -213,7 +213,7 @@ class AsymmetricKeypair:
@classmethod
def load(
cls: t.Type[_AsymmetricKeypair],
cls: type[_AsymmetricKeypair],
*,
path: str | os.PathLike,
passphrase: bytes | None = None,
@@ -412,7 +412,7 @@ class OpensshKeypair:
@classmethod
def generate(
cls: t.Type[_OpensshKeypair],
cls: type[_OpensshKeypair],
*,
keytype: KeyType = "rsa",
size: int | None = None,
@@ -451,7 +451,7 @@ class OpensshKeypair:
@classmethod
def load(
cls: t.Type[_OpensshKeypair],
cls: type[_OpensshKeypair],
*,
path: str | os.PathLike,
passphrase: bytes | None = None,

View File

@@ -331,7 +331,7 @@ class _OpensshWriter:
for name, data in value:
writer.string(name)
# SSH option data is encoded twice though this behavior is not documented
writer.string(_OpensshWriter().string(data).bytes() if data else bytes())
writer.string(_OpensshWriter().string(data).bytes() if data else b"")
self.string(writer.bytes())

View File

@@ -227,6 +227,17 @@ if t.TYPE_CHECKING:
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
def _collect_next(info: dict[str, t.Any]) -> list[str]:
result: list[str] = []
def f(link: str, relation: str) -> None:
if relation == "next":
result.append(link)
process_links(info=info, callback=f)
return result
def get_orders_list(
module: AnsibleModule, client: ACMEClient, orders_url: str
) -> list[str]:
@@ -257,12 +268,7 @@ def get_orders_list(
orders.extend(res["orders"])
# Extract URL of next part of results list
new_orders_url: list[str | None] = []
def f(link: str, relation: str) -> None:
if relation == "next":
new_orders_url.append(link)
process_links(info=info, callback=f)
new_orders_url.extend(_collect_next(info))
new_orders_url.append(None)
previous_orders_url, next_orders_url = next_orders_url, new_orders_url.pop(0)
if next_orders_url == previous_orders_url:

View File

@@ -795,13 +795,12 @@ class ACMECertificateClient:
raise ModuleFailException(
f"Found no challenge of type '{self.challenge}' for identifier {type_identifier}!"
)
if self.challenge == "dns-01":
if self.challenge in challenges:
values = data_dns.get(challenges[self.challenge]["record"])
if values is None:
values = []
data_dns[challenges[self.challenge]["record"]] = values
values.append(challenges[self.challenge]["resource_value"])
if self.challenge == "dns-01" and self.challenge in challenges:
values = data_dns.get(challenges[self.challenge]["record"])
if values is None:
values = []
data_dns[challenges[self.challenge]["record"]] = values
values.append(challenges[self.challenge]["resource_value"])
return data, data_dns
def finish_challenges(self) -> None:

View File

@@ -440,9 +440,8 @@ def main() -> t.NoReturn:
module.params["deactivate_authzs"] == "always"
or (module.params["deactivate_authzs"] == "on_success" and done)
or (module.params["deactivate_authzs"] == "on_error" and not done)
):
if order:
client.deactivate_authzs(order)
) and order:
client.deactivate_authzs(order)
module.exit_json(
changed=changed,
account_uri=client.client.account_uri,

View File

@@ -206,11 +206,10 @@ def is_parent(
)
elif isinstance(
public_key,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey,
):
public_key.verify(cert.cert.signature, cert.cert.tbs_certificate_bytes)
elif isinstance(
public_key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey
(
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey,
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey,
),
):
public_key.verify(cert.cert.signature, cert.cert.tbs_certificate_bytes)
else:
@@ -365,13 +364,12 @@ def main() -> t.NoReturn:
# Check chain
for i, parent in enumerate(chain):
if i > 0:
if not is_parent(module, chain[i - 1], parent):
module.fail_json(
msg=(
f"Cannot verify input chain: certificate #{i + 1}: {format_cert(parent)} is not issuer of certificate #{i}: {format_cert(chain[i - 1])}"
)
if i > 0 and not is_parent(module, chain[i - 1], parent):
module.fail_json(
msg=(
f"Cannot verify input chain: certificate #{i + 1}: {format_cert(parent)} is not issuer of certificate #{i}: {format_cert(chain[i - 1])}"
)
)
# Load intermediate certificates
intermediates = CertificateSet(module)

View File

@@ -222,7 +222,7 @@ def add_crypto_information(module: AnsibleModule) -> dict[str, t.Any]:
has_dsa = True
try:
# added later in 1.5
dsa.DSAPrivateKey.sign # pylint: disable=pointless-statement
dsa.DSAPrivateKey.sign # noqa: B018 # pylint: disable=pointless-statement
has_dsa_sign = True
except AttributeError:
pass
@@ -239,7 +239,7 @@ def add_crypto_information(module: AnsibleModule) -> dict[str, t.Any]:
has_rsa = True
try:
# added later in 1.4
rsa.RSAPrivateKey.sign # pylint: disable=pointless-statement
rsa.RSAPrivateKey.sign # noqa: B018 # pylint: disable=pointless-statement
has_rsa_sign = True
except AttributeError:
pass
@@ -261,7 +261,7 @@ def add_crypto_information(module: AnsibleModule) -> dict[str, t.Any]:
has_ed25519 = True
try:
# added with the primitive in 2.6
ed25519.Ed25519PrivateKey.sign # pylint: disable=pointless-statement
ed25519.Ed25519PrivateKey.sign # noqa: B018 # pylint: disable=pointless-statement
has_ed25519_sign = True
except AttributeError:
pass
@@ -283,7 +283,7 @@ def add_crypto_information(module: AnsibleModule) -> dict[str, t.Any]:
has_ed448 = True
try:
# added with the primitive in 2.6
ed448.Ed448PrivateKey.sign # pylint: disable=pointless-statement
ed448.Ed448PrivateKey.sign # noqa: B018 # pylint: disable=pointless-statement
has_ed448_sign = True
except AttributeError:
pass
@@ -299,7 +299,7 @@ def add_crypto_information(module: AnsibleModule) -> dict[str, t.Any]:
try:
# added later in 2.5
x25519.X25519PrivateKey.private_bytes # pylint: disable=pointless-statement
x25519.X25519PrivateKey.private_bytes # noqa: B018 # pylint: disable=pointless-statement
full = True
except AttributeError:
full = False
@@ -344,7 +344,7 @@ def add_crypto_information(module: AnsibleModule) -> dict[str, t.Any]:
has_ec = True
try:
# added later in 1.5
ec.EllipticCurvePrivateKey.sign # pylint: disable=pointless-statement
ec.EllipticCurvePrivateKey.sign # noqa: B018 # pylint: disable=pointless-statement
has_ec_sign = True
except AttributeError:
pass

View File

@@ -376,9 +376,8 @@ def main() -> t.NoReturn:
if timeout:
setdefaulttimeout(timeout)
if ca_cert:
if not isfile(ca_cert):
module.fail_json(msg="ca_cert file does not exist")
if ca_cert and not isfile(ca_cert):
module.fail_json(msg="ca_cert file does not exist")
verified_chain = None
unverified_chain = None

View File

@@ -936,9 +936,7 @@ class ConditionsHandler(Handler):
name = self.opened_luks_name(self.device)
if name is None:
return True
return False
return name is None
def luks_close(self) -> bool:
if (

View File

@@ -391,7 +391,7 @@ def main() -> t.NoReturn:
# Detection what is possible
can_use_cryptography = (
CRYPTOGRAPHY_FOUND
and CRYPTOGRAPHY_VERSION >= LooseVersion(MINIMAL_CRYPTOGRAPHY_VERSION)
and LooseVersion(MINIMAL_CRYPTOGRAPHY_VERSION) <= CRYPTOGRAPHY_VERSION
)
can_use_openssl = module.get_bin_path("openssl", False) is not None

View File

@@ -342,10 +342,10 @@ if t.TYPE_CHECKING:
)
PKCS12 = tuple[
t.Union[CertificateIssuerPrivateKeyTypes, None],
t.Union[cryptography.x509.Certificate, None],
t.Union[CertificateIssuerPrivateKeyTypes, None], # noqa: UP007
t.Union[cryptography.x509.Certificate, None], # noqa: UP007
list[cryptography.x509.Certificate],
t.Union[bytes, None],
t.Union[bytes, None], # noqa: UP007
] # pragma: no cover
@@ -823,9 +823,9 @@ def main() -> t.NoReturn:
changed = True
file_args = module.load_file_common_arguments(module.params)
if module.check_file_absent_if_check_mode(file_args["path"]):
changed = True
elif module.set_fs_attributes_if_different(file_args, changed):
if module.check_file_absent_if_check_mode(
file_args["path"]
) or module.set_fs_attributes_if_different(file_args, changed):
changed = True
else:
if module.check_mode:

View File

@@ -325,9 +325,9 @@ class PublicKey(OpenSSLObject):
passphrase=self.privatekey_passphrase,
)
file_args = module.load_file_common_arguments(module.params)
if module.check_file_absent_if_check_mode(file_args["path"]):
self.changed = True
elif module.set_fs_attributes_if_different(file_args, False):
if module.check_file_absent_if_check_mode(
file_args["path"]
) or module.set_fs_attributes_if_different(file_args, False):
self.changed = True
def check(self, module: AnsibleModule, *, perms_required: bool = True) -> bool:

View File

@@ -200,13 +200,10 @@ class SignatureCryptography(SignatureBase):
elif isinstance(
private_key,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey,
):
signature = private_key.sign(_in)
elif isinstance(
private_key,
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey,
(
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey,
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey,
),
):
signature = private_key.sign(_in)

View File

@@ -197,15 +197,10 @@ class SignatureInfoCryptography(SignatureInfoBase):
elif isinstance(
public_key,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey,
):
public_key.verify(_signature, _in)
verified = True
valid = True
elif isinstance(
public_key,
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey,
(
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey,
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey,
),
):
public_key.verify(_signature, _in)
verified = True

View File

@@ -244,9 +244,9 @@ class X509CertificateConvertModule(OpenSSLObject):
return True
if self.input != self.dest_content:
return True
if self.format == "pem" and self.dest_content_pem_type != self.wanted_pem_type:
return True
return False
return bool(
self.format == "pem" and self.dest_content_pem_type != self.wanted_pem_type
)
def get_dest_certificate(self) -> bytes:
if self.format == "der":

View File

@@ -823,10 +823,7 @@ class CRL(OpenSSLObject):
if old_entries != new_entries:
return False
if self.format != self.actual_format and not ignore_conversion:
return False
return True
return not (self.format != self.actual_format and not ignore_conversion)
def _generate_crl(self) -> bytes:
crl = CertificateRevocationListBuilder()
@@ -919,9 +916,9 @@ class CRL(OpenSSLObject):
self.changed = True
file_args = self.module.load_file_common_arguments(self.module.params)
if self.module.check_file_absent_if_check_mode(file_args["path"]):
self.changed = True
elif self.module.set_fs_attributes_if_different(file_args, False):
if self.module.check_file_absent_if_check_mode(
file_args["path"]
) or self.module.set_fs_attributes_if_different(file_args, False):
self.changed = True
def dump(self, check_mode: bool = False) -> dict[str, t.Any]:

31
ruff.toml Normal file
View File

@@ -0,0 +1,31 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2025 Felix Fontein <felix@fontein.de>
line-length = 160
[lint]
# https://docs.astral.sh/ruff/rules/
select = ["A", "B", "E", "F", "FA", "FLY", "UP", "SIM"]
ignore = [
# Better keep ignored (for now)
"F811", # Redefinition of unused `xxx` (happens a lot for fixtures in unit tests)
"E402", # Module level import not at top of file
"E741", # Ambiguous variable name
"UP012", # unnecessary-encode-utf8
"UP015", # Unnecessary mode argument
"SIM105", # suppressible-exception
"SIM108", # if-else-block-instead-of-if-exp
# To fix later:
"B905", # zip-without-explicit-strict - needs Python 3.10+
# To fix:
"UP024", # Replace aliased errors with `OSError`
]
# Allow fix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"]
unfixable = []
# Allow unused variables when underscore-prefixed or starting with dummy
dummy-variable-rgx = "^(_|dummy).*$"

View File

@@ -37,9 +37,9 @@ if t.TYPE_CHECKING:
def cartesian_product(
list1: list[_S], list2: "list[tuple[*_Ts]]"
) -> "list[tuple[_S, *_Ts]]":
result: "list[tuple[_S, *_Ts]]" = []
list1: list[_S], list2: "list[tuple[*_Ts]]" # noqa: UP037
) -> "list[tuple[_S, *_Ts]]": # noqa: UP037
result: "list[tuple[_S, *_Ts]]" = [] # noqa: UP037
for item1 in list1:
item1_tuple = (item1,)
for item2 in list2: