Ensure that *everything* is typed in community.crypto (#917)

* Ensure that *everything* is typed in community.crypto.

* Fix comment.

* Ignore type definitions/imports and AssertionErrors for code coverage.
This commit is contained in:
Felix Fontein
2025-06-09 10:10:19 +02:00
committed by GitHub
parent ec063d8515
commit d83a923325
73 changed files with 494 additions and 317 deletions

View File

@@ -38,13 +38,13 @@ from ansible_collections.community.crypto.plugins.module_utils._cryptography_dep
if t.TYPE_CHECKING:
import datetime
import datetime # pragma: no cover
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.crypto.plugins.module_utils._crypto.cryptography_support import (
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
from ansible_collections.community.crypto.plugins.module_utils._crypto.cryptography_support import ( # pragma: no cover
CertificatePrivateKeyTypes,
)
from cryptography.hazmat.primitives.asymmetric.types import (
from cryptography.hazmat.primitives.asymmetric.types import ( # pragma: no cover
CertificateIssuerPrivateKeyTypes,
)
@@ -170,11 +170,11 @@ class CertificateBackend(metaclass=abc.ABCMeta):
def _check_privatekey(self) -> bool:
"""Check whether provided parameters match, assuming self.existing_certificate and self.privatekey have been populated."""
if self.existing_certificate is None:
raise AssertionError(
raise AssertionError( # pragma: no cover
"Contract violation: existing_certificate has not been populated"
)
if self.privatekey is None:
raise AssertionError(
raise AssertionError( # pragma: no cover
"Contract violation: privatekey has not been populated"
)
return cryptography_compare_public_keys(
@@ -184,11 +184,13 @@ class CertificateBackend(metaclass=abc.ABCMeta):
def _check_csr(self) -> bool:
"""Check whether provided parameters match, assuming self.existing_certificate and self.csr have been populated."""
if self.existing_certificate is None:
raise AssertionError(
raise AssertionError( # pragma: no cover
"Contract violation: existing_certificate has not been populated"
)
if self.csr is None:
raise AssertionError("Contract violation: csr has not been populated")
raise AssertionError(
"Contract violation: csr has not been populated"
) # pragma: no cover
# Verify that CSR is signed by certificate's private key
if not self.csr.is_signature_valid:
return False
@@ -249,11 +251,13 @@ class CertificateBackend(metaclass=abc.ABCMeta):
def _check_subject_key_identifier(self) -> bool:
"""Check whether Subject Key Identifier matches, assuming self.existing_certificate and self.csr have been populated."""
if self.existing_certificate is None:
raise AssertionError(
raise AssertionError( # pragma: no cover
"Contract violation: existing_certificate has not been populated"
)
if self.csr is None:
raise AssertionError("Contract violation: csr has not been populated")
raise AssertionError(
"Contract violation: csr has not been populated"
) # pragma: no cover
# Get hold of certificate's SKI
try:
ext = self.existing_certificate.extensions.get_extension_for_class(

View File

@@ -22,8 +22,8 @@ from ansible_collections.community.crypto.plugins.module_utils._crypto.module_ba
if t.TYPE_CHECKING:
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.crypto.plugins.module_utils._argspec import (
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
from ansible_collections.community.crypto.plugins.module_utils._argspec import ( # pragma: no cover
ArgumentSpec,
)
@@ -100,7 +100,9 @@ class AcmeCertificateBackend(CertificateBackend):
def get_certificate_data(self) -> bytes:
"""Return bytes for self.cert."""
if self.cert_bytes is None:
raise AssertionError("Contract violation: cert_bytes is None")
raise AssertionError(
"Contract violation: cert_bytes is None"
) # pragma: no cover
return self.cert_bytes
def dump(self, *, include_certificate: bool) -> dict[str, t.Any]:

View File

@@ -38,21 +38,25 @@ from ansible_collections.community.crypto.plugins.module_utils._time import (
if t.TYPE_CHECKING:
import datetime
import datetime # pragma: no cover
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.crypto.plugins.module_utils._argspec import (
from ansible.module_utils.basic import AnsibleModule # 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 (
from ansible_collections.community.crypto.plugins.plugin_utils._action_module import ( # pragma: no cover
AnsibleActionModule,
)
from ansible_collections.community.crypto.plugins.plugin_utils._filter_module import (
from ansible_collections.community.crypto.plugins.plugin_utils._filter_module import ( # pragma: no cover
FilterModuleMock,
)
from cryptography.hazmat.primitives.asymmetric.types import PublicKeyTypes
from cryptography.hazmat.primitives.asymmetric.types import (
PublicKeyTypes, # pragma: no cover
)
GeneralAnsibleModule = t.Union[AnsibleModule, AnsibleActionModule, FilterModuleMock]
GeneralAnsibleModule = t.Union[
AnsibleModule, AnsibleActionModule, FilterModuleMock
] # pragma: no cover
MINIMAL_CRYPTOGRAPHY_VERSION = COLLECTION_MINIMUM_CRYPTOGRAPHY_VERSION

View File

@@ -42,13 +42,13 @@ from ansible_collections.community.crypto.plugins.module_utils._time import (
if t.TYPE_CHECKING:
import datetime
import datetime # pragma: no cover
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.crypto.plugins.module_utils._argspec import (
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
from ansible_collections.community.crypto.plugins.module_utils._argspec import ( # pragma: no cover
ArgumentSpec,
)
from cryptography.hazmat.primitives.asymmetric.types import (
from cryptography.hazmat.primitives.asymmetric.types import ( # pragma: no cover
CertificateIssuerPrivateKeyTypes,
)
@@ -157,7 +157,9 @@ class OwnCACertificateBackendCryptography(CertificateBackend):
def generate_certificate(self) -> None:
"""(Re-)Generate certificate."""
if self.csr is None:
raise AssertionError("Contract violation: csr has not been populated")
raise AssertionError(
"Contract violation: csr has not been populated"
) # pragma: no cover
cert_builder = x509.CertificateBuilder()
cert_builder = cert_builder.subject_name(self.csr.subject)
cert_builder = cert_builder.issuer_name(self.ca_cert.subject)
@@ -214,7 +216,9 @@ class OwnCACertificateBackendCryptography(CertificateBackend):
def get_certificate_data(self) -> bytes:
"""Return bytes for self.cert."""
if self.cert is None:
raise AssertionError("Contract violation: cert has not been populated")
raise AssertionError(
"Contract violation: cert has not been populated"
) # pragma: no cover
return self.cert.public_bytes(Encoding.PEM)
def needs_regeneration(

View File

@@ -36,13 +36,13 @@ from ansible_collections.community.crypto.plugins.module_utils._time import (
if t.TYPE_CHECKING:
import datetime
import datetime # pragma: no cover
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.crypto.plugins.module_utils._argspec import (
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
from ansible_collections.community.crypto.plugins.module_utils._argspec import ( # pragma: no cover
ArgumentSpec,
)
from cryptography.hazmat.primitives.asymmetric.types import (
from cryptography.hazmat.primitives.asymmetric.types import ( # pragma: no cover
CertificateIssuerPrivateKeyTypes,
)
@@ -114,9 +114,11 @@ class SelfSignedCertificateBackendCryptography(CertificateBackend):
def generate_certificate(self) -> None:
"""(Re-)Generate certificate."""
if self.csr is None:
raise AssertionError("Contract violation: csr has not been populated")
if self.privatekey is None:
raise AssertionError(
"Contract violation: csr has not been populated"
) # pragma: no cover
if self.privatekey is None:
raise AssertionError( # pragma: no cover
"Contract violation: privatekey has not been populated"
)
try:
@@ -156,7 +158,9 @@ class SelfSignedCertificateBackendCryptography(CertificateBackend):
def get_certificate_data(self) -> bytes:
"""Return bytes for self.cert."""
if self.cert is None:
raise AssertionError("Contract violation: cert has not been populated")
raise AssertionError(
"Contract violation: cert has not been populated"
) # pragma: no cover
return self.cert.public_bytes(Encoding.PEM)
def needs_regeneration(

View File

@@ -28,18 +28,20 @@ from ansible_collections.community.crypto.plugins.module_utils._cryptography_dep
if t.TYPE_CHECKING:
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.crypto.plugins.plugin_utils._action_module import (
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
from ansible_collections.community.crypto.plugins.plugin_utils._action_module import ( # pragma: no cover
AnsibleActionModule,
)
from ansible_collections.community.crypto.plugins.plugin_utils._filter_module import (
from ansible_collections.community.crypto.plugins.plugin_utils._filter_module import ( # pragma: no cover
FilterModuleMock,
)
from cryptography.hazmat.primitives.asymmetric.types import (
from cryptography.hazmat.primitives.asymmetric.types import ( # pragma: no cover
PrivateKeyTypes,
)
GeneralAnsibleModule = t.Union[AnsibleModule, AnsibleActionModule, FilterModuleMock]
GeneralAnsibleModule = t.Union[
AnsibleModule, AnsibleActionModule, FilterModuleMock
] # pragma: no cover
# crypto_utils

View File

@@ -48,16 +48,16 @@ from ansible_collections.community.crypto.plugins.module_utils._cryptography_dep
if t.TYPE_CHECKING:
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.crypto.plugins.module_utils._crypto.cryptography_support import (
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
from ansible_collections.community.crypto.plugins.module_utils._crypto.cryptography_support import ( # pragma: no cover
CertificatePrivateKeyTypes,
)
from cryptography.hazmat.primitives.asymmetric.types import (
from cryptography.hazmat.primitives.asymmetric.types import ( # pragma: no cover
CertificateIssuerPrivateKeyTypes,
PrivateKeyTypes,
)
_ET = t.TypeVar("_ET", bound="cryptography.x509.ExtensionType")
_ET = t.TypeVar("_ET", bound="cryptography.x509.ExtensionType") # pragma: no cover
MINIMAL_CRYPTOGRAPHY_VERSION = COLLECTION_MINIMUM_CRYPTOGRAPHY_VERSION
@@ -453,7 +453,9 @@ class CertificateSigningRequestBackend:
def get_csr_data(self) -> bytes:
"""Return bytes for self.csr."""
if self.csr is None:
raise AssertionError("Violated contract: csr is not populated")
raise AssertionError(
"Violated contract: csr is not populated"
) # pragma: no cover
return self.csr.public_bytes(
cryptography.hazmat.primitives.serialization.Encoding.PEM
)
@@ -485,9 +487,13 @@ class CertificateSigningRequestBackend:
def _check_csr(self) -> bool:
"""Check whether provided parameters, assuming self.existing_csr and self.privatekey have been populated."""
if self.existing_csr is None:
raise AssertionError("Violated contract: existing_csr is not populated")
raise AssertionError(
"Violated contract: existing_csr is not populated"
) # pragma: no cover
if self.privatekey is None:
raise AssertionError("Violated contract: privatekey is not populated")
raise AssertionError(
"Violated contract: privatekey is not populated"
) # pragma: no cover
def _check_subject(csr: cryptography.x509.CertificateSigningRequest) -> bool:
subject = [

View File

@@ -31,19 +31,21 @@ from ansible_collections.community.crypto.plugins.module_utils._cryptography_dep
if t.TYPE_CHECKING:
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.crypto.plugins.plugin_utils._action_module import (
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
from ansible_collections.community.crypto.plugins.plugin_utils._action_module import ( # pragma: no cover
AnsibleActionModule,
)
from ansible_collections.community.crypto.plugins.plugin_utils._filter_module import (
from ansible_collections.community.crypto.plugins.plugin_utils._filter_module import ( # pragma: no cover
FilterModuleMock,
)
from cryptography.hazmat.primitives.asymmetric.types import (
from cryptography.hazmat.primitives.asymmetric.types import ( # pragma: no cover
CertificatePublicKeyTypes,
PrivateKeyTypes,
)
GeneralAnsibleModule = t.Union[AnsibleModule, AnsibleActionModule, FilterModuleMock]
GeneralAnsibleModule = t.Union[
AnsibleModule, AnsibleActionModule, FilterModuleMock
] # pragma: no cover
MINIMAL_CRYPTOGRAPHY_VERSION = COLLECTION_MINIMUM_CRYPTOGRAPHY_VERSION

View File

@@ -37,15 +37,17 @@ from ansible_collections.community.crypto.plugins.module_utils._cryptography_dep
if t.TYPE_CHECKING:
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.crypto.plugins.plugin_utils._action_module import (
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
from ansible_collections.community.crypto.plugins.plugin_utils._action_module import ( # pragma: no cover
AnsibleActionModule,
)
from cryptography.hazmat.primitives.asymmetric.types import (
from cryptography.hazmat.primitives.asymmetric.types import ( # pragma: no cover
PrivateKeyTypes,
)
GeneralAnsibleModule = t.Union[AnsibleModule, AnsibleActionModule]
GeneralAnsibleModule = t.Union[
AnsibleModule, AnsibleActionModule
] # pragma: no cover
MINIMAL_CRYPTOGRAPHY_VERSION = COLLECTION_MINIMUM_CRYPTOGRAPHY_VERSION
@@ -267,7 +269,7 @@ class PrivateKeyBackend:
def get_private_key_data(self) -> bytes:
"""Return bytes for self.private_key"""
if self.private_key is None:
raise AssertionError("private_key not set")
raise AssertionError("private_key not set") # pragma: no cover
# Select export format and encoding
try:
export_format_txt = self._get_wanted_format()
@@ -341,7 +343,9 @@ class PrivateKeyBackend:
def _load_privatekey(self) -> PrivateKeyTypes:
data = self.existing_private_key_bytes
if data is None:
raise AssertionError("existing_private_key_bytes not set")
raise AssertionError(
"existing_private_key_bytes not set"
) # pragma: no cover
try:
# Interpret bytes depending on format.
key_format = identify_private_key_format(data)
@@ -388,7 +392,9 @@ class PrivateKeyBackend:
def _check_passphrase(self) -> bool:
"""Check whether provided passphrase matches, assuming self.existing_private_key_bytes has been populated."""
if self.existing_private_key_bytes is None:
raise AssertionError("existing_private_key_bytes not set")
raise AssertionError(
"existing_private_key_bytes not set"
) # pragma: no cover
try:
key_format = identify_private_key_format(self.existing_private_key_bytes)
if key_format == "raw":
@@ -460,7 +466,9 @@ class PrivateKeyBackend:
def _check_format(self) -> bool:
"""Check whether the key file format, assuming self.existing_private_key and self.existing_private_key_bytes has been populated."""
if self.existing_private_key_bytes is None:
raise AssertionError("existing_private_key_bytes not set")
raise AssertionError(
"existing_private_key_bytes not set"
) # pragma: no cover
if self.format == "auto_ignore":
return True
try:

View File

@@ -31,8 +31,8 @@ from ansible_collections.community.crypto.plugins.module_utils._io import load_f
if t.TYPE_CHECKING:
from ansible.module_utils.basic import AnsibleModule
from cryptography.hazmat.primitives.asymmetric.types import (
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
from cryptography.hazmat.primitives.asymmetric.types import ( # pragma: no cover
PrivateKeyTypes,
)
@@ -81,7 +81,7 @@ class PrivateKeyConvertBackend:
self.src_private_key_bytes = load_file(path=self.src_path, module=module)
else:
if self.src_content is None:
raise AssertionError("src_content is None")
raise AssertionError("src_content is None") # pragma: no cover
self.src_private_key_bytes = self.src_content.encode("utf-8")
self.dest_private_key: PrivateKeyTypes | None = None
@@ -90,7 +90,7 @@ class PrivateKeyConvertBackend:
def get_private_key_data(self) -> bytes:
"""Return bytes for self.src_private_key in output format"""
if self.src_private_key is None:
raise AssertionError("src_private_key not set")
raise AssertionError("src_private_key not set") # pragma: no cover
# Select export format and encoding
try:
export_encoding = cryptography.hazmat.primitives.serialization.Encoding.PEM

View File

@@ -33,18 +33,20 @@ from ansible_collections.community.crypto.plugins.module_utils._cryptography_dep
if t.TYPE_CHECKING:
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.crypto.plugins.plugin_utils._action_module import (
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
from ansible_collections.community.crypto.plugins.plugin_utils._action_module import ( # pragma: no cover
AnsibleActionModule,
)
from ansible_collections.community.crypto.plugins.plugin_utils._filter_module import (
from ansible_collections.community.crypto.plugins.plugin_utils._filter_module import ( # pragma: no cover
FilterModuleMock,
)
from cryptography.hazmat.primitives.asymmetric.types import (
from cryptography.hazmat.primitives.asymmetric.types import ( # pragma: no cover
PrivateKeyTypes,
)
GeneralAnsibleModule = t.Union[AnsibleModule, AnsibleActionModule, FilterModuleMock]
GeneralAnsibleModule = t.Union[
AnsibleModule, AnsibleActionModule, FilterModuleMock
] # pragma: no cover
MINIMAL_CRYPTOGRAPHY_VERSION = COLLECTION_MINIMUM_CRYPTOGRAPHY_VERSION

View File

@@ -23,18 +23,20 @@ from ansible_collections.community.crypto.plugins.module_utils._cryptography_dep
if t.TYPE_CHECKING:
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.crypto.plugins.plugin_utils._action_module import (
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
from ansible_collections.community.crypto.plugins.plugin_utils._action_module import ( # pragma: no cover
AnsibleActionModule,
)
from ansible_collections.community.crypto.plugins.plugin_utils._filter_module import (
from ansible_collections.community.crypto.plugins.plugin_utils._filter_module import ( # pragma: no cover
FilterModuleMock,
)
from cryptography.hazmat.primitives.asymmetric.types import (
from cryptography.hazmat.primitives.asymmetric.types import ( # pragma: no cover
PublicKeyTypes,
)
GeneralAnsibleModule = t.Union[AnsibleModule, AnsibleActionModule, FilterModuleMock]
GeneralAnsibleModule = t.Union[
AnsibleModule, AnsibleActionModule, FilterModuleMock
] # pragma: no cover
MINIMAL_CRYPTOGRAPHY_VERSION = COLLECTION_MINIMUM_CRYPTOGRAPHY_VERSION
@@ -119,7 +121,7 @@ class PublicKeyInfoRetrieval:
def _get_public_key(self, binary: bool) -> bytes:
if self.key is None:
raise AssertionError("key must be set")
raise AssertionError("key must be set") # pragma: no cover
return self.key.public_bytes(
serialization.Encoding.DER if binary else serialization.Encoding.PEM,
serialization.PublicFormat.SubjectPublicKeyInfo,
@@ -127,7 +129,7 @@ class PublicKeyInfoRetrieval:
def _get_key_info(self) -> tuple[str, dict[str, t.Any]]:
if self.key is None:
raise AssertionError("key must be set")
raise AssertionError("key must be set") # pragma: no cover
return _get_cryptography_public_key_info(self.key)
def get_info(self, *, prefer_one_fingerprint: bool = False) -> dict[str, t.Any]: