ansible-core 2.20: avoid deprecated functionality (#953)

* Avoid deprecated functionality.

* Lint.

* Fix typing.

* Python 3.7/3.8 compat.
This commit is contained in:
Felix Fontein
2025-08-17 22:30:10 +02:00
committed by GitHub
parent 1bfee3c23b
commit c0072d29f5
4 changed files with 27 additions and 17 deletions

View File

@@ -0,0 +1,2 @@
bugfixes:
- "Avoid deprecated functionality in ansible-core 2.20 (https://github.com/ansible-collections/community.crypto/pull/953)."

View File

@@ -9,8 +9,8 @@
from __future__ import annotations from __future__ import annotations
import typing as t import typing as t
from collections.abc import Mapping
from ansible.module_utils.common._collections_compat import Mapping
from ansible_collections.community.crypto.plugins.module_utils._acme.errors import ( from ansible_collections.community.crypto.plugins.module_utils._acme.errors import (
ACMEProtocolException, ACMEProtocolException,
ModuleFailException, ModuleFailException,
@@ -22,6 +22,11 @@ if t.TYPE_CHECKING:
ACMEClient, ACMEClient,
) )
_JsonMapping = Mapping[str, t.Any]
else:
# Since we need to pass this to t.cast(), we need a version that doesn't break with Python 3.7 and 3.8
_JsonMapping = Mapping
class ACMEAccount: class ACMEAccount:
""" """
@@ -42,7 +47,7 @@ class ACMEAccount:
terms_agreed: bool = False, terms_agreed: bool = False,
allow_creation: bool = True, allow_creation: bool = True,
external_account_binding: dict[str, t.Any] | None = None, external_account_binding: dict[str, t.Any] | None = None,
) -> tuple[bool, dict[str, t.Any] | None]: ) -> tuple[bool, Mapping[str, t.Any] | None]:
""" """
Registers a new ACME account. Returns a pair ``(created, data)``. Registers a new ACME account. Returns a pair ``(created, data)``.
Here, ``created`` is ``True`` if the account was created and Here, ``created`` is ``True`` if the account was created and
@@ -132,7 +137,7 @@ class ACMEAccount:
# Account did not exist # Account did not exist
if "location" in info: if "location" in info:
self.client.set_account_uri(info["location"]) self.client.set_account_uri(info["location"])
return True, result return True, t.cast(_JsonMapping, result)
if info["status"] == 200: if info["status"] == 200:
# Account did exist # Account did exist
if result.get("status") == "deactivated": if result.get("status") == "deactivated":
@@ -147,7 +152,7 @@ class ACMEAccount:
raise ModuleFailException("Account is deactivated") raise ModuleFailException("Account is deactivated")
if "location" in info: if "location" in info:
self.client.set_account_uri(info["location"]) self.client.set_account_uri(info["location"])
return False, result return False, t.cast(_JsonMapping, result)
if ( if (
info["status"] in (400, 404) info["status"] in (400, 404)
and result["type"] == "urn:ietf:params:acme:error:accountDoesNotExist" and result["type"] == "urn:ietf:params:acme:error:accountDoesNotExist"
@@ -236,7 +241,7 @@ class ACMEAccount:
allow_creation: t.Literal[True] = True, allow_creation: t.Literal[True] = True,
remove_account_uri_if_not_exists: bool = False, remove_account_uri_if_not_exists: bool = False,
external_account_binding: dict[str, t.Any] | None = None, external_account_binding: dict[str, t.Any] | None = None,
) -> tuple[bool, dict[str, t.Any]]: ... ) -> tuple[bool, Mapping[str, t.Any]]: ...
@t.overload @t.overload
def setup_account( def setup_account(
@@ -247,7 +252,7 @@ class ACMEAccount:
allow_creation: bool = True, allow_creation: bool = True,
remove_account_uri_if_not_exists: bool = False, remove_account_uri_if_not_exists: bool = False,
external_account_binding: dict[str, t.Any] | None = None, external_account_binding: dict[str, t.Any] | None = None,
) -> tuple[bool, dict[str, t.Any] | None]: ... ) -> tuple[bool, Mapping[str, t.Any] | None]: ...
def setup_account( def setup_account(
self, self,
@@ -257,7 +262,7 @@ class ACMEAccount:
allow_creation: bool = True, allow_creation: bool = True,
remove_account_uri_if_not_exists: bool = False, remove_account_uri_if_not_exists: bool = False,
external_account_binding: dict[str, t.Any] | None = None, external_account_binding: dict[str, t.Any] | None = None,
) -> tuple[bool, dict[str, t.Any] | None]: ) -> tuple[bool, Mapping[str, t.Any] | None]:
""" """
Detect or create an account on the ACME server. For ACME v1, Detect or create an account on the ACME server. For ACME v1,
as the only way (without knowing an account URI) to test if an as the only way (without knowing an account URI) to test if an
@@ -288,7 +293,7 @@ class ACMEAccount:
created = False created = False
# Verify that the account key belongs to the URI. # Verify that the account key belongs to the URI.
# (If update_contact is True, this will be done below.) # (If update_contact is True, this will be done below.)
account_data = self.get_account_data() account_data: Mapping[str, t.Any] | None = self.get_account_data()
if account_data is None: if account_data is None:
if remove_account_uri_if_not_exists and not allow_creation: if remove_account_uri_if_not_exists and not allow_creation:
self.client.account_uri = None self.client.account_uri = None
@@ -314,7 +319,7 @@ class ACMEAccount:
def update_account( def update_account(
self, *, account_data: dict[str, t.Any], contact: list[str] | None = None self, *, account_data: dict[str, t.Any], contact: list[str] | None = None
) -> tuple[bool, dict[str, t.Any]]: ) -> tuple[bool, Mapping[str, t.Any]]:
""" """
Update an account on the ACME server. Check mode is fully respected. Update an account on the ACME server. Check mode is fully respected.
@@ -340,9 +345,11 @@ class ACMEAccount:
return False, dict(account_data) return False, dict(account_data)
# Apply change # Apply change
account_data_res: Mapping[str, t.Any]
if self.client.module.check_mode: if self.client.module.check_mode:
account_data = dict(account_data) account_data_dict = dict(account_data)
account_data.update(update_request) account_data_dict.update(update_request)
account_data_res = account_data_dict
else: else:
raw_account_data, info = self.client.send_signed_request( raw_account_data, info = self.client.send_signed_request(
self.client.account_uri, update_request self.client.account_uri, update_request
@@ -354,9 +361,9 @@ class ACMEAccount:
info=info, info=info,
content_json=account_data, content_json=account_data,
) )
account_data = raw_account_data account_data_res = raw_account_data
return True, account_data return True, account_data_res
__all__ = ("ACMEAccount",) __all__ = ("ACMEAccount",)

View File

@@ -320,11 +320,12 @@ def main() -> t.NoReturn:
result["account_uri"] = client.account_uri result["account_uri"] = client.account_uri
result["exists"] = True result["exists"] = True
# Make sure promised data is there # Make sure promised data is there
account_data_dict = dict(account_data)
if "contact" not in account_data: if "contact" not in account_data:
account_data["contact"] = [] account_data_dict["contact"] = []
if client.account_key_data: if client.account_key_data:
account_data["public_account_key"] = client.account_key_data["jwk"] account_data_dict["public_account_key"] = client.account_key_data["jwk"]
result["account"] = account_data result["account"] = account_data_dict
# Retrieve orders list # Retrieve orders list
if ( if (
account_data.get("orders") account_data.get("orders")

View File

@@ -19,10 +19,10 @@ import abc
import copy import copy
import traceback import traceback
import typing as t import typing as t
from collections.abc import Mapping
from ansible.errors import AnsibleError from ansible.errors import AnsibleError
from ansible.module_utils.basic import SEQUENCETYPE, remove_values from ansible.module_utils.basic import SEQUENCETYPE, remove_values
from ansible.module_utils.common._collections_compat import Mapping
from ansible.module_utils.common.arg_spec import ArgumentSpecValidator from ansible.module_utils.common.arg_spec import ArgumentSpecValidator
from ansible.module_utils.errors import UnsupportedError from ansible.module_utils.errors import UnsupportedError
from ansible.plugins.action import ActionBase from ansible.plugins.action import ActionBase