mirror of
https://github.com/ansible-collections/kubernetes.core.git
synced 2026-03-27 05:43:02 +00:00
* Replace openshift client with kubernetes client This commit primarily just removes mentions of openshift from the docs and updates the requirements. Most of the work to replace the client has been done through the following commits:edc48ee577c214376cac48c51700182b6a989cf9* Add changelog fragment * Update changelogs/fragments/96-replace-openshift-client.yaml Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com> * Update plugins/modules/k8s.py Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com> * Update plugins/modules/k8s_info.py Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com> * Update plugins/modules/k8s_service.py Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com> * Bump minimum kubernetes version to 12.0.0 Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
205 lines
5.3 KiB
Python
205 lines
5.3 KiB
Python
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# Copyright (c) 2020, Red Hat
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
|
|
__metaclass__ = type
|
|
|
|
|
|
DOCUMENTATION = r'''
|
|
|
|
module: k8s_exec
|
|
|
|
short_description: Execute command in Pod
|
|
|
|
version_added: "0.10.0"
|
|
|
|
author: "Tristan de Cacqueray (@tristanC)"
|
|
|
|
description:
|
|
- Use the Kubernetes Python client to execute command on K8s pods.
|
|
|
|
extends_documentation_fragment:
|
|
- kubernetes.core.k8s_auth_options
|
|
|
|
requirements:
|
|
- "python >= 3.6"
|
|
- "kubernetes >= 12.0.0"
|
|
- "PyYAML >= 3.11"
|
|
|
|
notes:
|
|
- Return code C(return_code) for the command executed is added in output in version 1.0.0.
|
|
- The authenticated user must have at least read access to the pods resource and write access to the pods/exec resource.
|
|
|
|
options:
|
|
proxy:
|
|
description:
|
|
- The URL of an HTTP proxy to use for the connection.
|
|
- Can also be specified via I(K8S_AUTH_PROXY) environment variable.
|
|
- Please note that this module does not pick up typical proxy settings from the environment (e.g. HTTP_PROXY).
|
|
type: str
|
|
namespace:
|
|
description:
|
|
- The pod namespace name
|
|
type: str
|
|
required: yes
|
|
pod:
|
|
description:
|
|
- The pod name
|
|
type: str
|
|
required: yes
|
|
container:
|
|
description:
|
|
- The name of the container in the pod to connect to.
|
|
- Defaults to only container if there is only one container in the pod.
|
|
type: str
|
|
required: no
|
|
command:
|
|
description:
|
|
- The command to execute
|
|
type: str
|
|
required: yes
|
|
'''
|
|
|
|
EXAMPLES = r'''
|
|
- name: Execute a command
|
|
kubernetes.core.k8s_exec:
|
|
namespace: myproject
|
|
pod: zuul-scheduler
|
|
command: zuul-scheduler full-reconfigure
|
|
|
|
- name: Check RC status of command executed
|
|
kubernetes.core.k8s_exec:
|
|
namespace: myproject
|
|
pod: busybox-test
|
|
command: cmd_with_non_zero_exit_code
|
|
register: command_status
|
|
ignore_errors: True
|
|
|
|
- name: Check last command status
|
|
debug:
|
|
msg: "cmd failed"
|
|
when: command_status.return_code != 0
|
|
'''
|
|
|
|
RETURN = r'''
|
|
result:
|
|
description:
|
|
- The command object
|
|
returned: success
|
|
type: complex
|
|
contains:
|
|
stdout:
|
|
description: The command stdout
|
|
type: str
|
|
stdout_lines:
|
|
description: The command stdout
|
|
type: str
|
|
stderr:
|
|
description: The command stderr
|
|
type: str
|
|
stderr_lines:
|
|
description: The command stderr
|
|
type: str
|
|
return_code:
|
|
description: The command status code
|
|
type: int
|
|
'''
|
|
|
|
import copy
|
|
import shlex
|
|
|
|
try:
|
|
import yaml
|
|
except ImportError:
|
|
# ImportError are managed by the common module already.
|
|
pass
|
|
|
|
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import AnsibleModule
|
|
from ansible.module_utils._text import to_native
|
|
from ansible_collections.kubernetes.core.plugins.module_utils.common import (
|
|
AUTH_ARG_SPEC
|
|
)
|
|
|
|
try:
|
|
from kubernetes.client.apis import core_v1_api
|
|
from kubernetes.stream import stream
|
|
except ImportError:
|
|
# ImportError are managed by the common module already.
|
|
pass
|
|
|
|
|
|
def argspec():
|
|
spec = copy.deepcopy(AUTH_ARG_SPEC)
|
|
spec['namespace'] = dict(type='str', required=True)
|
|
spec['pod'] = dict(type='str', required=True)
|
|
spec['container'] = dict(type='str')
|
|
spec['command'] = dict(type='str', required=True)
|
|
return spec
|
|
|
|
|
|
def execute_module(module, k8s_ansible_mixin):
|
|
|
|
# Load kubernetes.client.Configuration
|
|
api = core_v1_api.CoreV1Api(k8s_ansible_mixin.client.client)
|
|
|
|
# hack because passing the container as None breaks things
|
|
optional_kwargs = {}
|
|
if module.params.get('container'):
|
|
optional_kwargs['container'] = module.params['container']
|
|
try:
|
|
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)
|
|
except Exception as e:
|
|
module.fail_json(msg="Failed to execute on pod %s"
|
|
" due to : %s" % (module.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'])
|
|
|
|
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 = AnsibleModule(
|
|
argument_spec=argspec(),
|
|
supports_check_mode=True,
|
|
)
|
|
from ansible_collections.kubernetes.core.plugins.module_utils.common import (
|
|
K8sAnsibleMixin, get_api_client)
|
|
|
|
k8s_ansible_mixin = K8sAnsibleMixin(module)
|
|
k8s_ansible_mixin.client = get_api_client(module=module)
|
|
execute_module(module, k8s_ansible_mixin)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|