diff --git a/plugins/module_utils/common.py b/plugins/module_utils/common.py index 2a8ad206..58bb0855 100644 --- a/plugins/module_utils/common.py +++ b/plugins/module_utils/common.py @@ -156,6 +156,15 @@ AUTH_ARG_MAP = { class K8sAnsibleMixin(object): + def __init__(self, *args, **kwargs): + if not HAS_K8S_MODULE_HELPER: + self.fail_json(msg=missing_required_lib('openshift'), exception=K8S_IMP_ERR, + error=to_native(k8s_import_exception)) + self.openshift_version = openshift.__version__ + + if not HAS_YAML: + self.fail_json(msg=missing_required_lib("PyYAML"), exception=YAML_IMP_ERR) + def get_api_client(self, **auth_params): auth_params = auth_params or getattr(self, 'params', {}) auth = {} @@ -284,28 +293,6 @@ class K8sAnsibleMixin(object): return True, result - -class KubernetesAnsibleModule(AnsibleModule, K8sAnsibleMixin): - resource_definition = None - api_version = None - kind = None - - def __init__(self, *args, **kwargs): - - kwargs['argument_spec'] = self.argspec - AnsibleModule.__init__(self, *args, **kwargs) - - if not HAS_K8S_MODULE_HELPER: - self.fail_json(msg=missing_required_lib('openshift'), exception=K8S_IMP_ERR, - error=to_native(k8s_import_exception)) - self.openshift_version = openshift.__version__ - - if not HAS_YAML: - self.fail_json(msg=missing_required_lib("PyYAML"), exception=YAML_IMP_ERR) - - def execute_module(self): - raise NotImplementedError() - def fail(self, msg=None): self.fail_json(msg=msg) @@ -429,3 +416,17 @@ class KubernetesAnsibleModule(AnsibleModule, K8sAnsibleMixin): if self.namespace: implicit_definition['metadata']['namespace'] = self.namespace self.resource_definitions = [implicit_definition] + + +class KubernetesAnsibleModule(AnsibleModule, K8sAnsibleMixin): + # NOTE: This class KubernetesAnsibleModule is deprecated in favor of + # class K8sAnsibleMixin and will be removed 2.0.0 release. + # Please use K8sAnsibleMixin instead. + + def __init__(self, *args, **kwargs): + kwargs['argument_spec'] = self.argspec + AnsibleModule.__init__(self, *args, **kwargs) + K8sAnsibleMixin.__init__(self, *args, **kwargs) + + self.warn("class KubernetesAnsibleModule is deprecated" + " and will be removed in 2.0.0. Please use K8sAnsibleMixin instead.") diff --git a/plugins/module_utils/raw.py b/plugins/module_utils/raw.py index dc8e8aa0..bbe2b2d1 100644 --- a/plugins/module_utils/raw.py +++ b/plugins/module_utils/raw.py @@ -24,11 +24,11 @@ from distutils.version import LooseVersion import sys import traceback -from ansible.module_utils.basic import missing_required_lib -from ansible_collections.community.kubernetes.plugins.module_utils.common import AUTH_ARG_SPEC, COMMON_ARG_SPEC, RESOURCE_ARG_SPEC, NAME_ARG_SPEC +from ansible.module_utils.basic import missing_required_lib, AnsibleModule from ansible.module_utils._text import to_native -from ansible_collections.community.kubernetes.plugins.module_utils.common import KubernetesAnsibleModule from ansible.module_utils.common.dict_transformations import dict_merge +from ansible_collections.community.kubernetes.plugins.module_utils.common import ( + AUTH_ARG_SPEC, COMMON_ARG_SPEC, RESOURCE_ARG_SPEC, NAME_ARG_SPEC, K8sAnsibleMixin) try: @@ -55,7 +55,7 @@ except ImportError: HAS_K8S_APPLY = False -class KubernetesRawModule(KubernetesAnsibleModule): +class KubernetesRawModule(K8sAnsibleMixin): @property def validate_spec(self): @@ -98,10 +98,21 @@ class KubernetesRawModule(KubernetesAnsibleModule): ('merge_type', 'apply'), ] - KubernetesAnsibleModule.__init__(self, *args, - mutually_exclusive=mutually_exclusive, - supports_check_mode=True, - **kwargs) + module = AnsibleModule( + argument_spec=self.argspec, + mutually_exclusive=mutually_exclusive, + supports_check_mode=True, + ) + + self.module = module + self.check_mode = self.module.check_mode + self.params = self.module.params + self.fail_json = self.module.fail_json + self.fail = self.module.fail_json + self.exit_json = self.module.exit_json + + super(KubernetesRawModule, self).__init__() + self.kind = k8s_kind or self.params.get('kind') self.api_version = self.params.get('api_version') self.name = self.params.get('name') diff --git a/plugins/module_utils/scale.py b/plugins/module_utils/scale.py index b989894d..55bab010 100644 --- a/plugins/module_utils/scale.py +++ b/plugins/module_utils/scale.py @@ -21,8 +21,9 @@ __metaclass__ = type import copy -from ansible_collections.community.kubernetes.plugins.module_utils.common import AUTH_ARG_SPEC, RESOURCE_ARG_SPEC, NAME_ARG_SPEC -from ansible_collections.community.kubernetes.plugins.module_utils.common import KubernetesAnsibleModule +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.community.kubernetes.plugins.module_utils.common import ( + AUTH_ARG_SPEC, RESOURCE_ARG_SPEC, NAME_ARG_SPEC, K8sAnsibleMixin) try: from openshift.dynamic.exceptions import NotFoundError @@ -39,7 +40,7 @@ SCALE_ARG_SPEC = { } -class KubernetesAnsibleScaleModule(KubernetesAnsibleModule): +class KubernetesAnsibleScaleModule(K8sAnsibleMixin): def __init__(self, k8s_kind=None, *args, **kwargs): self.client = None @@ -49,10 +50,20 @@ class KubernetesAnsibleScaleModule(KubernetesAnsibleModule): ('resource_definition', 'src'), ] - KubernetesAnsibleModule.__init__(self, *args, - mutually_exclusive=mutually_exclusive, - supports_check_mode=True, - **kwargs) + module = AnsibleModule( + argument_spec=self.argspec, + mutually_exclusive=mutually_exclusive, + supports_check_mode=True, + ) + + self.module = module + self.params = self.module.params + self.check_mode = self.module.check_mode + self.fail_json = self.module.fail_json + self.fail = self.module.fail_json + self.exit_json = self.module.exit_json + super(KubernetesAnsibleScaleModule, self).__init__() + self.kind = k8s_kind or self.params.get('kind') self.api_version = self.params.get('api_version') self.name = self.params.get('name') diff --git a/plugins/modules/k8s_exec.py b/plugins/modules/k8s_exec.py index 4c850764..e540b9b6 100644 --- a/plugins/modules/k8s_exec.py +++ b/plugins/modules/k8s_exec.py @@ -109,18 +109,18 @@ result: import copy import shlex -import traceback try: import yaml - IMP_YAML = True except ImportError: - IMP_YAML_ERR = traceback.format_exc() - IMP_YAML = False + # ImportError are managed by the common module already. + pass -from ansible.module_utils.basic import missing_required_lib -from ansible_collections.community.kubernetes.plugins.module_utils.common import KubernetesAnsibleModule -from ansible_collections.community.kubernetes.plugins.module_utils.common import AUTH_ARG_SPEC +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native +from ansible_collections.community.kubernetes.plugins.module_utils.common import ( + K8sAnsibleMixin, AUTH_ARG_SPEC +) try: from kubernetes.client.apis import core_v1_api @@ -130,7 +130,18 @@ except ImportError: pass -class KubernetesExecCommand(KubernetesAnsibleModule): +class KubernetesExecCommand(K8sAnsibleMixin): + + def __init__(self): + module = AnsibleModule( + argument_spec=self.argspec, + supports_check_mode=True, + ) + self.module = module + self.params = self.module.params + self.fail_json = self.module.fail_json + super(KubernetesExecCommand, self).__init__() + @property def argspec(self): spec = copy.deepcopy(AUTH_ARG_SPEC) @@ -140,52 +151,54 @@ class KubernetesExecCommand(KubernetesAnsibleModule): spec['command'] = dict(type='str', required=True) return spec + def execute_module(self): + # Load kubernetes.client.Configuration + self.get_api_client() + api = core_v1_api.CoreV1Api() + + # hack because passing the container as None breaks things + optional_kwargs = {} + if self.params.get('container'): + optional_kwargs['container'] = self.params['container'] + try: + resp = stream( + api.connect_get_namespaced_pod_exec, + self.params["pod"], + self.params["namespace"], + command=shlex.split(self.params["command"]), + stdout=True, + stderr=True, + stdin=False, + tty=False, + _preload_content=False, **optional_kwargs) + except Exception as e: + self.module.fail_json(msg="Failed to execute on pod %s" + " due to : %s" % (self.params.get('pod'), to_native(e))) + stdout, stderr, rc = [], [], 0 + while resp.is_open(): + resp.update(timeout=1) + if resp.peek_stdout(): + stdout.append(resp.read_stdout()) + if resp.peek_stderr(): + stderr.append(resp.read_stderr()) + err = resp.read_channel(3) + err = yaml.safe_load(err) + if err['status'] == 'Success': + rc = 0 + else: + rc = int(err['details']['causes'][0]['message']) + + self.module.exit_json( + # Some command might change environment, but ultimately failing at end + changed=True, + stdout="".join(stdout), + stderr="".join(stderr), + return_code=rc + ) + def main(): - module = KubernetesExecCommand() - - if not IMP_YAML: - module.fail_json(msg=missing_required_lib("yaml"), exception=IMP_YAML_ERR) - - # Load kubernetes.client.Configuration - module.get_api_client() - api = core_v1_api.CoreV1Api() - - # hack because passing the container as None breaks things - optional_kwargs = {} - if module.params.get('container'): - optional_kwargs['container'] = module.params['container'] - resp = stream( - api.connect_get_namespaced_pod_exec, - module.params["pod"], - module.params["namespace"], - command=shlex.split(module.params["command"]), - stdout=True, - stderr=True, - stdin=False, - tty=False, - _preload_content=False, **optional_kwargs) - stdout, stderr, rc = [], [], 0 - while resp.is_open(): - resp.update(timeout=1) - if resp.peek_stdout(): - stdout.append(resp.read_stdout()) - if resp.peek_stderr(): - stderr.append(resp.read_stderr()) - err = resp.read_channel(3) - err = yaml.safe_load(err) - if err['status'] == 'Success': - rc = 0 - else: - rc = int(err['details']['causes'][0]['message']) - - module.exit_json( - # Some command might change environment, but ultimately failing at end - changed=True, - stdout="".join(stdout), - stderr="".join(stderr), - return_code=rc - ) + KubernetesExecCommand().execute_module() if __name__ == '__main__': diff --git a/plugins/modules/k8s_info.py b/plugins/modules/k8s_info.py index 2811f534..219c4eec 100644 --- a/plugins/modules/k8s_info.py +++ b/plugins/modules/k8s_info.py @@ -130,17 +130,25 @@ resources: type: dict ''' - -from ansible_collections.community.kubernetes.plugins.module_utils.common import KubernetesAnsibleModule, AUTH_ARG_SPEC import copy +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.community.kubernetes.plugins.module_utils.common import ( + K8sAnsibleMixin, AUTH_ARG_SPEC) -class KubernetesInfoModule(KubernetesAnsibleModule): + +class KubernetesInfoModule(K8sAnsibleMixin): def __init__(self, *args, **kwargs): - KubernetesAnsibleModule.__init__(self, *args, - supports_check_mode=True, - **kwargs) + module = AnsibleModule( + argument_spec=self.argspec, + supports_check_mode=True, + ) + self.module = module + self.params = self.module.params + self.fail_json = self.module.fail_json + self.exit_json = self.module.exit_json + super(KubernetesInfoModule, self).__init__() def execute_module(self): self.client = self.get_api_client() diff --git a/plugins/modules/k8s_log.py b/plugins/modules/k8s_log.py index 6470d066..e7b75711 100644 --- a/plugins/modules/k8s_log.py +++ b/plugins/modules/k8s_log.py @@ -111,18 +111,26 @@ log_lines: import copy +from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.six import PY2 -from ansible_collections.community.kubernetes.plugins.module_utils.common import KubernetesAnsibleModule -from ansible_collections.community.kubernetes.plugins.module_utils.common import AUTH_ARG_SPEC, NAME_ARG_SPEC +from ansible_collections.community.kubernetes.plugins.module_utils.common import ( + K8sAnsibleMixin, AUTH_ARG_SPEC, NAME_ARG_SPEC) -class KubernetesLogModule(KubernetesAnsibleModule): +class KubernetesLogModule(K8sAnsibleMixin): - def __init__(self, *args, **kwargs): - KubernetesAnsibleModule.__init__(self, *args, - supports_check_mode=True, - **kwargs) + def __init__(self): + module = AnsibleModule( + argument_spec=self.argspec, + supports_check_mode=True, + ) + self.module = module + self.params = self.module.params + self.fail_json = self.module.fail_json + self.fail = self.module.fail_json + self.exit_json = self.module.exit_json + super(KubernetesLogModule, self).__init__() @property def argspec(self):