1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2026-02-04 07:51:50 +00:00

Add more module_utils typing (#11283)

Add more module_utils typing.
This commit is contained in:
Felix Fontein 2025-12-15 19:46:51 +01:00 committed by GitHub
parent df34945991
commit ef632145e9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 340 additions and 274 deletions

File diff suppressed because it is too large Load diff

View file

@ -5,13 +5,17 @@
from __future__ import annotations
import typing as t
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak import keycloak_argument_spec
from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak import (
keycloak_argument_spec,
KeycloakAPI,
)
def keycloak_clientsecret_module():
def keycloak_clientsecret_module() -> AnsibleModule:
"""
Returns an AnsibleModule definition for modules that interact with a client
secret.
@ -44,7 +48,7 @@ def keycloak_clientsecret_module():
return module
def keycloak_clientsecret_module_resolve_params(module, kc):
def keycloak_clientsecret_module_resolve_params(module: AnsibleModule, kc: KeycloakAPI) -> tuple[str, dict[str, t.Any]]:
"""
Given an AnsibleModule definition for keycloak_clientsecret_*, and a
KeycloakAPI client, resolve the params needed to interact with the Keycloak

View file

@ -40,7 +40,7 @@ class ModuleHelperBase:
def verbosity(self):
return self.module._verbosity
def do_raise(self, *args, **kwargs):
def do_raise(self, *args, **kwargs) -> t.NoReturn:
raise _MHE(*args, **kwargs)
def __getattr__(self, attr):
@ -61,14 +61,14 @@ class ModuleHelperBase:
raise NotImplementedError()
@property
def changed(self):
def changed(self) -> bool:
try:
return self.__changed__()
except NotImplementedError:
return self._changed
@changed.setter
def changed(self, value):
def changed(self, value: bool) -> None:
self._changed = value
def has_changed(self):

View file

@ -9,7 +9,7 @@ import typing as t
class ModuleHelperException(Exception):
def __init__(self, msg: str, update_output: dict[str, t.Any] | None = None, *args, **kwargs):
def __init__(self, msg: str, update_output: dict[str, t.Any] | None = None, *args, **kwargs) -> None:
self.msg: str = msg or f"Module failed with exception: {self}"
if update_output is None:
update_output = {}

View file

@ -5,12 +5,15 @@
from __future__ import annotations
import typing as t
from ansible.module_utils.basic import AnsibleModule
class DeprecateAttrsMixin:
def _deprecate_setup(self, attr, target, module):
def _deprecate_setup(
self, attr: str, target: object | None, module: AnsibleModule | None
) -> tuple[object, AnsibleModule, dict[str, t.Any], dict[str, t.Any]]:
if target is None:
target = self
if not hasattr(target, attr):
@ -37,8 +40,16 @@ class DeprecateAttrsMixin:
return target, module, value_dict, trigger_dict
def _deprecate_attr(
self, attr, msg, version=None, date=None, collection_name=None, target=None, value=None, module=None
):
self,
attr: str,
msg: str,
version: str | None = None,
date: str | None = None,
collection_name: str | None = None,
target: object | None = None,
value=None,
module: AnsibleModule | None = None,
) -> None:
target, module, value_dict, trigger_dict = self._deprecate_setup(attr, target, module)
value_dict[attr] = getattr(target, attr, value)

View file

@ -5,16 +5,18 @@
from __future__ import annotations
import typing as t
class StateMixin:
state_param: str = "state"
default_state: str | None = None
def _state(self):
state = self.module.params.get(self.state_param)
def _state(self) -> str:
state: str = self.module.params.get(self.state_param) # type: ignore[attr-defined]
return self.default_state if state is None else state
def _method(self, state):
def _method(self, state: str) -> str:
return f"{self.state_param}_{state}"
def __run__(self):
@ -34,5 +36,5 @@ class StateMixin:
func = getattr(self, method)
return func()
def __state_fallback__(self):
def __state_fallback__(self) -> t.NoReturn:
raise ValueError(f"Cannot find method: {self._method(self._state())}")

View file

@ -16,6 +16,7 @@ from ansible_collections.community.general.plugins.module_utils.mh.mixins.deprec
if t.TYPE_CHECKING:
from collections.abc import Sequence
from ansible.module_utils.basic import AnsibleModule
class ModuleHelper(DeprecateAttrsMixin, ModuleHelperBase):
@ -25,11 +26,11 @@ class ModuleHelper(DeprecateAttrsMixin, ModuleHelperBase):
change_params: Sequence[str] = ()
facts_params: Sequence[str] = ()
def __init__(self, module=None):
def __init__(self, module: AnsibleModule | dict[str, t.Any] | None = None) -> None:
super().__init__(module)
self.vars = VarDict()
for name, value in self.module.params.items():
for name, value in self.module.params.items(): # type: ignore[union-attr]
self.vars.set(
name,
value,
@ -39,26 +40,26 @@ class ModuleHelper(DeprecateAttrsMixin, ModuleHelperBase):
fact=name in self.facts_params,
)
def update_vars(self, meta=None, **kwargs):
def update_vars(self, meta: dict[str, t.Any] | None = None, **kwargs: t.Any) -> None:
if meta is None:
meta = {}
for k, v in kwargs.items():
self.vars.set(k, v, **meta)
def update_output(self, **kwargs):
def update_output(self, **kwargs: t.Any) -> None:
self.update_vars(meta={"output": True}, **kwargs)
def update_facts(self, **kwargs):
def update_facts(self, **kwargs: t.Any) -> None:
self.update_vars(meta={"fact": True}, **kwargs)
def _vars_changed(self):
def _vars_changed(self) -> bool:
return self.vars.has_changed
def has_changed(self):
def has_changed(self) -> bool:
return self.changed or self._vars_changed()
@property
def output(self):
def output(self) -> dict[str, t.Any]:
result = dict(self.vars.output())
if self.facts_name:
facts = self.vars.facts()

View file

@ -14,15 +14,19 @@ import hmac
import json
import time
import uuid
import typing as t
from ansible.module_utils.urls import open_url
if t.TYPE_CHECKING:
from ansible.module_utils.basic import AnsibleModule
class PritunlException(Exception):
pass
def pritunl_argument_spec():
def pritunl_argument_spec() -> dict[str, t.Any]:
return dict(
pritunl_url=dict(required=True, type="str"),
pritunl_api_token=dict(required=True, type="str", no_log=False),
@ -31,7 +35,7 @@ def pritunl_argument_spec():
)
def get_pritunl_settings(module):
def get_pritunl_settings(module: AnsibleModule) -> dict[str, t.Any]:
"""
Helper function to set required Pritunl request params from module arguments.
"""
@ -43,7 +47,7 @@ def get_pritunl_settings(module):
}
def _get_pritunl_organizations(api_token, api_secret, base_url, validate_certs=True):
def _get_pritunl_organizations(api_token, api_secret, base_url: str, validate_certs: bool = True):
return pritunl_auth_request(
base_url=base_url,
api_token=api_token,
@ -54,7 +58,9 @@ def _get_pritunl_organizations(api_token, api_secret, base_url, validate_certs=T
)
def _delete_pritunl_organization(api_token, api_secret, base_url, organization_id, validate_certs=True):
def _delete_pritunl_organization(
api_token, api_secret, base_url: str, organization_id: str, validate_certs: bool = True
):
return pritunl_auth_request(
base_url=base_url,
api_token=api_token,
@ -65,7 +71,9 @@ def _delete_pritunl_organization(api_token, api_secret, base_url, organization_i
)
def _post_pritunl_organization(api_token, api_secret, base_url, organization_data, validate_certs=True):
def _post_pritunl_organization(
api_token, api_secret, base_url: str, organization_data: object, validate_certs: bool = True
):
return pritunl_auth_request(
api_token=api_token,
api_secret=api_secret,
@ -78,7 +86,7 @@ def _post_pritunl_organization(api_token, api_secret, base_url, organization_dat
)
def _get_pritunl_users(api_token, api_secret, base_url, organization_id, validate_certs=True):
def _get_pritunl_users(api_token, api_secret, base_url: str, organization_id: str, validate_certs: bool = True):
return pritunl_auth_request(
api_token=api_token,
api_secret=api_secret,
@ -89,7 +97,9 @@ def _get_pritunl_users(api_token, api_secret, base_url, organization_id, validat
)
def _delete_pritunl_user(api_token, api_secret, base_url, organization_id, user_id, validate_certs=True):
def _delete_pritunl_user(
api_token, api_secret, base_url: str, organization_id: str, user_id: str, validate_certs: bool = True
):
return pritunl_auth_request(
api_token=api_token,
api_secret=api_secret,
@ -100,7 +110,9 @@ def _delete_pritunl_user(api_token, api_secret, base_url, organization_id, user_
)
def _post_pritunl_user(api_token, api_secret, base_url, organization_id, user_data, validate_certs=True):
def _post_pritunl_user(
api_token, api_secret, base_url: str, organization_id: str, user_data: object, validate_certs=True
):
return pritunl_auth_request(
api_token=api_token,
api_secret=api_secret,
@ -116,11 +128,11 @@ def _post_pritunl_user(api_token, api_secret, base_url, organization_id, user_da
def _put_pritunl_user(
api_token,
api_secret,
base_url,
organization_id,
user_id,
user_data,
validate_certs=True,
base_url: str,
organization_id: str,
user_id: str,
user_data: object,
validate_certs: bool = True,
):
return pritunl_auth_request(
api_token=api_token,
@ -134,7 +146,9 @@ def _put_pritunl_user(
)
def list_pritunl_organizations(api_token, api_secret, base_url, validate_certs=True, filters=None):
def list_pritunl_organizations(
api_token, api_secret, base_url: str, validate_certs: bool = True, filters: dict[str, t.Any] | None = None
) -> list:
orgs = []
response = _get_pritunl_organizations(
@ -158,7 +172,14 @@ def list_pritunl_organizations(api_token, api_secret, base_url, validate_certs=T
return orgs
def list_pritunl_users(api_token, api_secret, base_url, organization_id, validate_certs=True, filters=None):
def list_pritunl_users(
api_token,
api_secret,
base_url: str,
organization_id: str,
validate_certs: bool = True,
filters: dict[str, t.Any] | None = None,
):
users = []
response = _get_pritunl_users(
@ -187,9 +208,9 @@ def list_pritunl_users(api_token, api_secret, base_url, organization_id, validat
def post_pritunl_organization(
api_token,
api_secret,
base_url,
organization_name,
validate_certs=True,
base_url: str,
organization_name: str,
validate_certs: bool = True,
):
response = _post_pritunl_organization(
api_token=api_token,
@ -208,11 +229,11 @@ def post_pritunl_organization(
def post_pritunl_user(
api_token,
api_secret,
base_url,
organization_id,
user_data,
user_id=None,
validate_certs=True,
base_url: str,
organization_id: str,
user_data: object,
user_id: str | None = None,
validate_certs: bool = True,
):
# If user_id is provided will do PUT otherwise will do POST
if user_id is None:
@ -247,7 +268,9 @@ def post_pritunl_user(
return json.loads(response.read())
def delete_pritunl_organization(api_token, api_secret, base_url, organization_id, validate_certs=True):
def delete_pritunl_organization(
api_token, api_secret, base_url: str, organization_id: str, validate_certs: bool = True
):
response = _delete_pritunl_organization(
api_token=api_token,
api_secret=api_secret,
@ -262,7 +285,9 @@ def delete_pritunl_organization(api_token, api_secret, base_url, organization_id
return json.loads(response.read())
def delete_pritunl_user(api_token, api_secret, base_url, organization_id, user_id, validate_certs=True):
def delete_pritunl_user(
api_token, api_secret, base_url: str, organization_id: str, user_id: str, validate_certs: bool = True
):
response = _delete_pritunl_user(
api_token=api_token,
api_secret=api_secret,
@ -281,12 +306,12 @@ def delete_pritunl_user(api_token, api_secret, base_url, organization_id, user_i
def pritunl_auth_request(
api_token,
api_secret,
base_url,
method,
path,
validate_certs=True,
headers=None,
data=None,
base_url: str,
method: str,
path: str,
validate_certs: bool = True,
headers: dict[str, str] | None = None,
data: bytes | str | None = None,
):
"""
Send an API call to a Pritunl server.

View file

@ -14,13 +14,13 @@ import logging
import logging.config
import os
import tempfile
import time
import typing as t
# (TODO: remove next line!)
from datetime import datetime # noqa: F401, pylint: disable=unused-import
from operator import eq
import time
try:
import yaml # noqa: F401, pylint: disable=unused-import
@ -48,6 +48,9 @@ except ImportError:
from ansible.module_utils.common.text.converters import to_bytes
if t.TYPE_CHECKING:
from ansible.module_utils.basic import AnsibleModule
__version__ = "1.6.0-dev"
MAX_WAIT_TIMEOUT_IN_SECONDS = 1200
@ -81,7 +84,7 @@ DEFAULT_READY_STATES = [
DEFAULT_TERMINATED_STATES = ["TERMINATED", "DETACHED", "DELETED"]
def get_common_arg_spec(supports_create=False, supports_wait=False):
def get_common_arg_spec(supports_create: bool = False, supports_wait: bool = False) -> dict[str, t.Any]:
"""
Return the common set of module arguments for all OCI cloud modules.
:param supports_create: Variable to decide whether to add options related to idempotency of create operation.
@ -125,7 +128,7 @@ def get_common_arg_spec(supports_create=False, supports_wait=False):
return common_args
def get_facts_module_arg_spec(filter_by_name=False):
def get_facts_module_arg_spec(filter_by_name: bool = False) -> dict[str, t.Any]:
# Note: This method is used by most OCI ansible fact modules during initialization. When making changes to this
# method, ensure that no `oci` python sdk dependencies are introduced in this method. This ensures that the modules
# can check for absence of OCI Python SDK and fail with an appropriate message. Introducing an OCI dependency in
@ -138,7 +141,7 @@ def get_facts_module_arg_spec(filter_by_name=False):
return facts_module_arg_spec
def get_oci_config(module, service_client_class=None):
def get_oci_config(module: AnsibleModule, service_client_class=None):
"""Return the OCI configuration to use for all OCI API calls. The effective OCI configuration is derived by merging
any overrides specified for configuration attributes through Ansible module options or environment variables. The
order of precedence for deriving the effective configuration dict is:
@ -241,7 +244,7 @@ def get_oci_config(module, service_client_class=None):
return config
def create_service_client(module, service_client_class):
def create_service_client(module: AnsibleModule, service_client_class):
"""
Creates a service client using the common module options provided by the user.
:param module: An AnsibleModule that represents user provided options for a Task
@ -275,7 +278,7 @@ def create_service_client(module, service_client_class):
return client
def _is_instance_principal_auth(module):
def _is_instance_principal_auth(module: AnsibleModule):
# check if auth type is overridden via module params
instance_principal_auth = "auth_type" in module.params and module.params["auth_type"] == "instance_principal"
if not instance_principal_auth:
@ -285,7 +288,9 @@ def _is_instance_principal_auth(module):
return instance_principal_auth
def _merge_auth_option(config, module, module_option_name, env_var_name, config_attr_name):
def _merge_auth_option(
config, module: AnsibleModule, module_option_name: str, env_var_name: str, config_attr_name: str
) -> None:
"""Merge the values for an authentication attribute from ansible module options and
environment variables with the values specified in a configuration file"""
_debug(f"Merging {module_option_name}")
@ -305,7 +310,7 @@ def _merge_auth_option(config, module, module_option_name, env_var_name, config_
config.update({config_attr_name: auth_attribute})
def bucket_details_factory(bucket_details_type, module):
def bucket_details_factory(bucket_details_type: t.Literal["create", "update"], module: AnsibleModule):
bucket_details = None
if bucket_details_type == "create":
bucket_details = CreateBucketDetails()
@ -320,7 +325,7 @@ def bucket_details_factory(bucket_details_type, module):
return bucket_details
def filter_resources(all_resources, filter_params):
def filter_resources(all_resources, filter_params) -> list:
if not filter_params:
return all_resources
filtered_resources = []
@ -335,7 +340,7 @@ def filter_resources(all_resources, filter_params):
return filtered_resources
def list_all_resources(target_fn, **kwargs):
def list_all_resources(target_fn, **kwargs) -> list:
"""
Return all resources after paging through all results returned by target_fn. If a `display_name` or `name` is
provided as a kwarg, then only resources matching the specified name are returned.
@ -371,17 +376,17 @@ def list_all_resources(target_fn, **kwargs):
return filter_resources(existing_resources, filter_params)
def _debug(s):
def _debug(s) -> None:
get_logger("oci_utils").debug(s)
def get_logger(module_name):
def get_logger(module_name: str):
oci_logging = setup_logging()
return oci_logging.getLogger(module_name)
def setup_logging(
default_level="INFO",
default_level: str = "INFO",
):
"""Setup logging configuration"""
env_log_path = "LOG_PATH"
@ -396,7 +401,7 @@ def setup_logging(
return logging
def check_and_update_attributes(target_instance, attr_name, input_value, existing_value, changed):
def check_and_update_attributes(target_instance, attr_name: str, input_value, existing_value, changed: bool) -> bool:
"""
This function checks the difference between two resource attributes of literal types and sets the attribute
value in the target instance type holding the attribute.
@ -422,13 +427,13 @@ def check_and_update_resource(
update_fn,
primitive_params_update,
kwargs_non_primitive_update,
module,
module: AnsibleModule,
update_attributes,
client=None,
sub_attributes_of_update_model=None,
wait_applicable=True,
states=None,
):
) -> dict[str, t.Any]:
"""
This function handles update operation on a resource. It checks whether update is required and accordingly returns
the resource and the changed status.
@ -481,10 +486,10 @@ def check_and_update_resource(
def get_kwargs_update(
attributes_to_update,
kwargs_non_primitive_update,
module,
module: AnsibleModule,
primitive_params_update,
sub_attributes_of_update_model=None,
):
) -> dict[str, t.Any]:
kwargs_update = dict()
for param in primitive_params_update:
kwargs_update[param] = module.params[param]
@ -500,7 +505,7 @@ def get_kwargs_update(
return kwargs_update
def is_dictionary_subset(sub, super_dict):
def is_dictionary_subset(sub: dict, super_dict: dict) -> bool:
"""
This function checks if `sub` dictionary is a subset of `super` dictionary.
:param sub: subset dictionary, for example user_provided_attr_value.
@ -510,7 +515,7 @@ def is_dictionary_subset(sub, super_dict):
return all(sub[key] == super_dict[key] for key in sub)
def are_lists_equal(s, t):
def are_lists_equal(s: list | None, t: list | None):
if s is None and t is None:
return True
@ -541,7 +546,7 @@ def are_lists_equal(s, t):
return not t
def get_attr_to_update(get_fn, kwargs_get, module, update_attributes):
def get_attr_to_update(get_fn, kwargs_get, module: AnsibleModule, update_attributes) -> tuple:
try:
resource = call_with_backoff(get_fn, **kwargs_get).data
except ServiceError as ex:
@ -569,7 +574,7 @@ def get_attr_to_update(get_fn, kwargs_get, module, update_attributes):
return attributes_to_update, resource
def get_taggable_arg_spec(supports_create=False, supports_wait=False):
def get_taggable_arg_spec(supports_create: bool = False, supports_wait: bool = False) -> dict[str, t.Any]:
"""
Returns an arg_spec that is valid for taggable OCI resources.
:return: A dict that represents an ansible arg spec that builds over the common_arg_spec and adds free-form and
@ -580,7 +585,7 @@ def get_taggable_arg_spec(supports_create=False, supports_wait=False):
return tag_arg_spec
def add_tags_to_model_from_module(model, module):
def add_tags_to_model_from_module(model, module: AnsibleModule):
"""
Adds free-form and defined tags from an ansible module to a resource model
:param model: A resource model instance that supports 'freeform_tags' and 'defined_tags' as attributes
@ -620,7 +625,7 @@ def check_and_create_resource(
kwargs_create,
list_fn,
kwargs_list,
module,
module: AnsibleModule,
model,
existing_resources=None,
exclude_attributes=None,
@ -709,7 +714,7 @@ def check_and_create_resource(
return result
def _get_attributes_to_consider(exclude_attributes, model, module):
def _get_attributes_to_consider(exclude_attributes, model, module: AnsibleModule):
"""
Determine the attributes to detect if an existing resource already matches the requested resource state
:param exclude_attributes: Attributes to not consider for matching
@ -770,7 +775,7 @@ def is_attr_assigned_default(default_attribute_values, attr, assigned_value):
return True
def create_resource(resource_type, create_fn, kwargs_create, module):
def create_resource(resource_type, create_fn, kwargs_create, module: AnsibleModule):
"""
Create an OCI resource
:param resource_type: Type of the resource to be created. e.g.: "vcn"
@ -791,7 +796,7 @@ def create_resource(resource_type, create_fn, kwargs_create, module):
def does_existing_resource_match_user_inputs(
existing_resource,
module,
module: AnsibleModule,
attributes_to_compare,
exclude_attributes,
default_attribute_values=None,
@ -858,13 +863,13 @@ def does_existing_resource_match_user_inputs(
return True
def tuplize(d):
def tuplize(d) -> list[tuple]:
"""
This function takes a dictionary and converts it to a list of tuples recursively.
:param d: A dictionary.
:return: List of tuples.
"""
list_of_tuples = []
list_of_tuples: list[tuple] = []
key_list = sorted(list(d.keys()))
for key in key_list:
if isinstance(d[key], list):
@ -887,18 +892,18 @@ def tuplize(d):
return list_of_tuples
def get_key_for_comparing_dict(d):
def get_key_for_comparing_dict(d) -> list[tuple]:
tuple_form_of_d = tuplize(d)
return tuple_form_of_d
def sort_dictionary(d):
def sort_dictionary(d: dict) -> dict:
"""
This function sorts values of a dictionary recursively.
:param d: A dictionary.
:return: Dictionary with sorted elements.
"""
sorted_d = {}
sorted_d: dict = {}
for key in d:
if isinstance(d[key], list):
if d[key] and isinstance(d[key][0], dict):
@ -913,7 +918,7 @@ def sort_dictionary(d):
return sorted_d
def sort_list_of_dictionary(list_of_dict):
def sort_list_of_dictionary(list_of_dict: list[dict]) -> list[dict]:
"""
This functions sorts a list of dictionaries. It first sorts each value of the dictionary and then sorts the list of
individually sorted dictionaries. For sorting, each dictionary's tuple equivalent is used.
@ -1103,7 +1108,7 @@ def create_and_wait(
kwargs_create,
get_fn,
get_param,
module,
module: AnsibleModule,
states=None,
wait_applicable=True,
kwargs_get=None,
@ -1151,7 +1156,7 @@ def update_and_wait(
kwargs_update,
get_fn,
get_param,
module,
module: AnsibleModule,
states=None,
wait_applicable=True,
kwargs_get=None,
@ -1196,7 +1201,7 @@ def create_or_update_resource_and_wait(
resource_type,
function,
kwargs_function,
module,
module: AnsibleModule,
wait_applicable,
get_fn,
get_param,
@ -1240,7 +1245,7 @@ def create_or_update_resource_and_wait(
def wait_for_resource_lifecycle_state(
client,
module,
module: AnsibleModule,
wait_applicable,
kwargs_get,
get_fn,
@ -1291,7 +1296,7 @@ def wait_for_resource_lifecycle_state(
return resource
def wait_on_work_request(client, response, module):
def wait_on_work_request(client, response, module: AnsibleModule):
try:
if module.params.get("wait", None):
_debug(f"Waiting for work request with id {response.data.id} to reach SUCCEEDED state.")
@ -1325,11 +1330,11 @@ def delete_and_wait(
kwargs_get,
delete_fn,
kwargs_delete,
module,
module: AnsibleModule,
states=None,
wait_applicable=True,
process_work_request=False,
):
) -> dict[str, t.Any]:
"""A utility function to delete a resource and wait for the resource to get into the state as specified in the
module options.
:param wait_applicable: Specifies if wait for delete is applicable for this resource
@ -1348,7 +1353,7 @@ def delete_and_wait(
"""
states_set = set(["DETACHING", "DETACHED", "DELETING", "DELETED", "TERMINATING", "TERMINATED"])
result = dict(changed=False)
result: dict[str, t.Any] = dict(changed=False)
result[resource_type] = dict()
try:
resource = to_dict(call_with_backoff(get_fn, **kwargs_get).data)
@ -1412,7 +1417,7 @@ def delete_and_wait(
return result
def are_attrs_equal(current_resource, module, attributes):
def are_attrs_equal(current_resource, module: AnsibleModule, attributes):
"""
Check if the specified attributes are equal in the specified 'model' and 'module'. This is used to check if an OCI
Model instance already has the values specified by an Ansible user while invoking an OCI Ansible module and if a
@ -1440,7 +1445,7 @@ def are_attrs_equal(current_resource, module, attributes):
return True
def _get_user_provided_value(module, attribute_name):
def _get_user_provided_value(module: AnsibleModule, attribute_name):
"""
Returns the user provided value for "attribute_name". We consider aliases in the module.
"""
@ -1456,7 +1461,7 @@ def _get_user_provided_value(module, attribute_name):
return user_provided_value
def update_model_with_user_options(curr_model, update_model, module):
def update_model_with_user_options(curr_model, update_model, module: AnsibleModule):
"""
Update the 'update_model' with user provided values in 'module' for the specified 'attributes' if they are different
from the values in the 'curr_model'.
@ -1520,7 +1525,7 @@ def call_with_backoff(fn, **kwargs):
raise
def generic_hash(obj):
def generic_hash(obj) -> int:
"""
Compute a hash of all the fields in the object
:param obj: Object whose hash needs to be computed
@ -1540,7 +1545,7 @@ def generic_hash(obj):
return sum
def generic_eq(s, other):
def generic_eq(s, other) -> bool:
if other is None:
return False
return s.__dict__ == other.__dict__
@ -1640,7 +1645,7 @@ def update_class_type_attr_difference(update_class_details, existing_instance, a
return changed
def get_existing_resource(target_fn, module, **kwargs):
def get_existing_resource(target_fn, module: AnsibleModule, **kwargs):
"""
Returns the requested resource if it exists based on the input arguments.
:param target_fn The function which should be used to find the requested resource
@ -1659,7 +1664,9 @@ def get_existing_resource(target_fn, module, **kwargs):
return existing_resource
def get_attached_instance_info(module, lookup_attached_instance, list_attachments_fn, list_attachments_args):
def get_attached_instance_info(
module: AnsibleModule, lookup_attached_instance, list_attachments_fn, list_attachments_args
):
config = get_oci_config(module)
identity_client = create_service_client(module, IdentityClient)
@ -1747,12 +1754,12 @@ def get_component_list_difference(input_component_list, existing_components, pur
return None, False
def write_to_file(path, content):
def write_to_file(path: str | bytes, content: bytes) -> None:
with open(to_bytes(path), "wb") as dest_file:
dest_file.write(content)
def get_target_resource_from_list(module, list_resource_fn, target_resource_id=None, **kwargs):
def get_target_resource_from_list(module: AnsibleModule, list_resource_fn, target_resource_id=None, **kwargs):
"""
Returns a resource filtered by identifier from a list of resources. This method should be
used as an alternative of 'get resource' method when 'get resource' is nor provided by

View file

@ -14,6 +14,7 @@
from __future__ import annotations
import traceback
import typing as t
try:
from pylxca import connect, disconnect
@ -22,11 +23,14 @@ try:
except ImportError:
HAS_PYLXCA = False
if t.TYPE_CHECKING:
from ansible.module_utils.basic import AnsibleModule
PYLXCA_REQUIRED = "Lenovo xClarity Administrator Python Client (Python package 'pylxca') is required for this module."
def has_pylxca(module):
def has_pylxca(module: AnsibleModule) -> None:
"""
Check pylxca is installed
:param module:
@ -43,17 +47,17 @@ LXCA_COMMON_ARGS = dict(
class connection_object:
def __init__(self, module):
def __init__(self, module: AnsibleModule) -> None:
self.module = module
def __enter__(self):
return setup_conn(self.module)
def __exit__(self, type, value, traceback):
def __exit__(self, type, value, traceback) -> None:
close_conn()
def setup_conn(module):
def setup_conn(module: AnsibleModule):
"""
this function create connection to LXCA
:param module:
@ -70,7 +74,7 @@ def setup_conn(module):
return lxca_con
def close_conn():
def close_conn() -> None:
"""
this function close connection to LXCA
:param module:

View file

@ -5,20 +5,24 @@
from __future__ import annotations
import json
import typing as t
from ansible.module_utils.basic import env_fallback
from ansible.module_utils.urls import fetch_url, basic_auth_header
if t.TYPE_CHECKING:
from ansible.module_utils.basic import AnsibleModule
class BitbucketHelper:
BITBUCKET_API_URL = "https://api.bitbucket.org"
def __init__(self, module):
def __init__(self, module: AnsibleModule) -> None:
self.module = module
self.access_token = None
self.access_token: str | None = None
@staticmethod
def bitbucket_argument_spec():
def bitbucket_argument_spec() -> dict[str, t.Any]:
return dict(
client_id=dict(type="str", fallback=(env_fallback, ["BITBUCKET_CLIENT_ID"])),
client_secret=dict(type="str", no_log=True, fallback=(env_fallback, ["BITBUCKET_CLIENT_SECRET"])),
@ -30,14 +34,14 @@ class BitbucketHelper:
)
@staticmethod
def bitbucket_required_one_of():
def bitbucket_required_one_of() -> list[list[str]]:
return [["client_id", "client_secret", "user", "password"]]
@staticmethod
def bitbucket_required_together():
def bitbucket_required_together() -> list[list[str]]:
return [["client_id", "client_secret"], ["user", "password"]]
def fetch_access_token(self):
def fetch_access_token(self) -> None:
if self.module.params["client_id"] and self.module.params["client_secret"]:
headers = {
"Authorization": basic_auth_header(
@ -57,7 +61,9 @@ class BitbucketHelper:
else:
self.module.fail_json(msg=f"Failed to retrieve access token: {info}")
def request(self, api_url, method, data=None, headers=None):
def request(
self, api_url: str, method: str, data: bytes | str | dict | None = None, headers: dict[str, str] | None = None
):
headers = headers or {}
if self.access_token:

View file

@ -4,11 +4,12 @@
from __future__ import annotations
import typing as t
from ansible.module_utils import basic
def convert_to_binary_multiple(size_with_unit):
def convert_to_binary_multiple(size_with_unit: str | None) -> int:
if size_with_unit is None:
return -1
valid_units = ["MiB", "GiB", "TiB"]
@ -35,7 +36,7 @@ storage_system_spec = {
}
def cpg_argument_spec():
def cpg_argument_spec() -> dict[str, t.Any]:
spec = {
"state": {"required": True, "choices": ["present", "absent"], "type": "str"},
"cpg_name": {"required": True, "type": "str"},