Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support of local environmental variable on Ansible Controller that populated from ansible variables for kubectl connection plugin #698

Closed
yurnov opened this issue Apr 18, 2024 · 12 comments
Labels
type/enhancement New feature or request

Comments

@yurnov
Copy link
Contributor

yurnov commented Apr 18, 2024

SUMMARY

kubernetes.core.kubectl connection plugin can be used to execute the content of plays inside pods in the Kubernetes cluster, it's easy to use an efficient tool. But sometimes clusters require local environmental variables for authorization, i.e. AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY for authorization, even we have a kubeconfig.

So, it's will be nice to have support of local environment variable for kubectl connection plug-in. Importantly, I talking about the local variable that required for kubectl binary (technically aws binary in case of AWS, but other cases may require another enviromental variable for another cluster type), not for remote enviromental variable that is natively supported by Ansible.

ISSUE TYPE
  • Feature Idea
COMPONENT NAME

kubernetes.core.kubectl connection plugin

ADDITIONAL INFORMATION

In some cases kubectl require not only kubeconfig file, but some additional credentionals (i.e. platform/cloud specific) for anothentication/authorization, and enviromental variable is conviniant place to store them, i.e. AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY in case of AWS EKS with kubeconfig that invoke aws binary. AWS is only one example, the similar can be conviniant for another cloud providers as well.

It's not a issue in case if Ansible is used to manage something just in one cluster, but in case of multiple clusters mentioned in inventory, kubectl connection plug can't be used.

So, this issue it for request support of local environment variable, to have working something like:

- hosts: cluster1:cluster2
  gather_facts: no
  any_errors_fatal: yes
  vars:
    ansible_connection: "kubernetes.core.kubectl"
    ansible_kubectl_namespace: "test"
    ansible_kubectl_config: "{{ kubeconfig }}"
    ansible_kubectl_pod: "shell"
    ansible_kubectl_container: "shell"
    ansible_kubectl_local_env:
       AWS_ACCESS_KEY_ID: "{{ aws_access_key_id }}"
       AWS_SECRET_ACCESS_KEY: "{{ aws_secret_access_key }}"
  environment:
    TEST_ENV1: value1
    TEST_ENV2: value2

  tasks:
  - name: test
    ansible.builtin.shell: env
    register: result
  - debug:
      var: result.stdout_lines

Expected result for this snippet is getting enviromental variable on running container in two clusters.
Actual result (as on version 3.0.1 of kubernetes.core collection) is failing connection at least to one cluster.

It's important specifically for kubernetes.core.kubectl to have ability to use same playbook in multi-cluster (and multi public cluster provider) scenario.

Update:

to be fully clear, this issue is request of implementation support of:

    ansible_kubectl_local_env:
       AWS_ACCESS_KEY_ID: "{{ aws_access_key_id }}"
       AWS_SECRET_ACCESS_KEY: "{{ aws_secret_access_key }}"

from a example above, and it's a local environmental variable on the ansible controller, not on on target host

@yurnov
Copy link
Contributor Author

yurnov commented Apr 18, 2024

I tried to test this way with test playbook, but it doesn't work:

root@ubuntu-shell:/# cat test2.yaml
- hosts: localhost
  gather_facts: no
  any_errors_fatal: yes
  vars:
    ansible_connection: "kubectl"
    ansible_kubectl_namespace: "test"
    ansible_kubectl_config: "/.kube/config"
    ansible_kubectl_pod: "ubuntu"
    ansible_kubectl_container: "ubuntu"
    ansible_kubectl_local_shell_args: "EKS_TOKEN=test"
  environment:
    TEST_ENV1: value1
    TEST_ENV2: value2

  tasks:
  - name: test
    ansible.builtin.shell: env
    register: result
  - debug:
      var: result.stdout_lines
root@ubuntu-shell:/# ansible-playbook -vvv test2.yaml
ansible-playbook [core 2.14.5]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.10/dist-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] (/usr/bin/python3)
  jinja version = 3.1.3
  libyaml = True
No config file found; using defaults
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
yaml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
ini declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
toml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.

PLAYBOOK: test2.yaml ***************************************************************************************************************************
1 plays in test2.yaml

PLAY [localhost] *******************************************************************************************************************************

TASK [test] ************************************************************************************************************************************
task path: /test2.yaml:16
redirecting (type: connection) ansible.builtin.kubectl to kubernetes.core.kubectl
<127.0.0.1> ESTABLISH kubectl CONNECTION
<127.0.0.1> EXEC ['/usr/bin/bash', '-c', 'EKS_TOKEN=test', '', '&&', '', '/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'echo ~ && sleep 0'"]
<127.0.0.1> EXEC ['/usr/bin/bash', '-c', 'EKS_TOKEN=test', '', '&&', '', '/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', '/bin/sh -c \'echo "`pwd`" && sleep 0\'']
<127.0.0.1> EXEC ['/usr/bin/bash', '-c', 'EKS_TOKEN=test', '', '&&', '', '/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', '/bin/sh -c \'( umask 77 && mkdir -p "` echo ~/.ansible/tmp `"&& mkdir "` echo ~/.ansible/tmp/ansible-tmp-1713438683.4774194-5211-164264421022768 `" && echo ansible-tmp-1713438683.4774194-5211-164264421022768="` echo ~/.ansible/tmp/ansible-tmp-1713438683.4774194-5211-164264421022768 `" ) && sleep 0\'']
fatal: [localhost]: FAILED! => {
    "msg": "failed to resolve remote temporary directory from ansible-tmp-1713442333.866006-5231-217269445930807: `( umask 77 && mkdir -p \"` echo ~/.ansible/tmp `\"&& mkdir \"` echo ~/.ansible/tmp/ansible-tmp-1713442333.866006-5231-217269445930807 `\" && echo ansible-tmp-1713442333.866006-5231-217269445930807=\"` echo ~/.ansible/tmp/ansible-tmp-1713442333.866006-5231-217269445930807 `\" )` returned empty string"
}

NO MORE HOSTS LEFT *****************************************************************************************************************************
PLAY RECAP *************************************************************************************************************************************localhost                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

@yurnov
Copy link
Contributor Author

yurnov commented Apr 18, 2024

Hi @abikouo and @Akasurde, could you, as active contributor to this repo, please check this issue?

@gravesm
Copy link
Member

gravesm commented Apr 18, 2024

Why wouldn't you just do:

- hosts: localhost
  gather_facts: false
  vars:
    ansible_connection: kubectl
    ansible_kubectl_namespace: default
    ansible_kubectl_pod: mypod
    ansible_kubectl_container: ubuntu
  tasks:
    - ansible.builtin.shell: echo $TEST_ENV
      register: result
      environment:
        TEST_ENV: value

    - debug:
        var: result

@gravesm gravesm added the type/enhancement New feature or request label Apr 18, 2024
@avelytchko
Copy link

avelytchko commented Apr 18, 2024

ansible_connection: kubectl

The plugin requires a successful connection before passing any tasks and environment variables, but AWS environment variables are necessary for the connection, resulting in a failure. We encountered an unreachable state, causing any task to fail immediately. EKS kubeconfig relies on AWS CLI for RBAC, so AWS environment variables must be exposed before ansible_connection: kubectl execution. Unfortunately, we're unable to expose these variables on the host itself, so we're looking to accomplish this solely through Ansible.

@yurnov
Copy link
Contributor Author

yurnov commented Apr 18, 2024

Hi @gravesm,

it works in general cases, and TEST_ENV will be populated into target container after connection, but my ticket is for local (not target) environmental variable that requried for esbalishing connection and need to be set on local (ansible controller) before connection will be established in general case. That environmental variable required for authentication for connection isfelf.

@gravesm
Copy link
Member

gravesm commented Apr 18, 2024

Sorry, maybe I'm not understanding your problem. The connection plugin is just spawning a kubectl child process and will inherit whatever environment your initial ansible process has. If you just need, for example, AWS_ACCESS_KEY_ID in the environment that the kubectl process is run in, just make sure it's set in whatever environment you are running ansible-playbook.

@yurnov
Copy link
Contributor Author

yurnov commented Apr 18, 2024

Hi @gravesm, you are correct, this connection plugin just uses kubectl binary, and the local env variable is inherited, and playbook like that:

- hosts: cluster1
  gather_facts: no
  any_errors_fatal: yes
  vars:
    ansible_connection: "kubernetes.core.kubectl"
    ansible_kubectl_namespace: "test"
    ansible_kubectl_config: "{{ kubeconfig }}"
    ansible_kubectl_pod: "shell"
    ansible_kubectl_container: "shell"
  environment:
    TEST_ENV1: value1
    TEST_ENV2: value2

  tasks:
  - name: test
    ansible.builtin.shell: env
    register: result
  - debug:
      var: result.stdout_lines

works fine when I have local environment variable required for kubectl, i.e. AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY that mentioned earlier, or any other that is required by kubectl in specific case. But it works perfectly when I have only one host (kubernetes cluster in case on kubernetes.core.kubectl), but if I have a few hosts with different credentials, it will not work.

Please have an example:

root@ubuntu-shell:/# cat inventory.ini
[k8s]
foo.example.com ansible_connection=kubernetes.core.kubectl  kubeconfig=/root/.kube/foo.example.com.config  aws_access_key_id=foo.id aws_secret_access_key=foo.key
bar.example.com ansible_connection=kubernetes.core.kubectl  kubeconfig=/root/.kube/bar.example.com.config  aws_access_key_id=bar.id aws_secret_access_key=bar.key
baz.example.com ansible_connection=kubernetes.core.kubectl  kubeconfig=/root/.kube/baz.example.com.config
root@ubuntu-shell:/# cat playbook.yaml
---
- hosts: k8s
  gather_facts: no
  any_errors_fatal: yes
  vars:
    ansible_connection: "kubernetes.core.kubectl"
    ansible_kubectl_namespace: "test"
    ansible_kubectl_config: "{{ kubeconfig }}"
    ansible_kubectl_pod: "shell"
    ansible_kubectl_container: "shell"
    ansible_kubectl_local_env:
       AWS_ACCESS_KEY_ID: "{{ aws_access_key_id | default('') }}"
       AWS_SECRET_ACCESS_KEY: "{{ aws_secret_access_key | default('') }}"
  environment:
    TEST_ENV1: value1
    TEST_ENV2: value2

  tasks:
  - name: test
    ansible.builtin.shell: env
    register: result
  - debug:
      var: result.stdout_lines

That will not work

update: updated the comment with some typo, and added a foo.example.com that does not require any additional variable for authentication as the example of a complex real-world scenario with few clusters with different authentication.

@yurnov
Copy link
Contributor Author

yurnov commented Apr 22, 2024

I tried to implement support of local env variable on my side, please find #699

yurnov added a commit to yurnov/kubernetes.core that referenced this issue Apr 26, 2024
the aim of this commit a add support of local enviroment variable
that will be used for kubectl and requried for connections ifself
i.e. cloud-provider or cluester/enviroment specific authorization
data
@yurnov
Copy link
Contributor Author

yurnov commented Apr 26, 2024

Hi @gravesm,

would you like to review PR #702 where the support of the local environmental variable requested in that issue was added? That was tested locally with some debug output, to do so _connect method modified to:

    def _connect(self, port=None):
        """Connect to the container. Nothing to do"""
        super(Connection, self)._connect()
        if not self._connected:
            display.vvv(
              "ESTABLISH {0} CONNECTION".format(self.transport),
              host=self._play_context.remote_addr,
            )
            local_env = self._local_env()
            for key, value in local_env.items():
              display.vvv("ENV: {0}={1}".format(key, value), host=self._play_context.remote_addr)
            self._connected = True

(so, part

local_env = self._local_env()
            for key, value in local_env.items():
              display.vvv("ENV: {0}={1}".format(key, value), host=self._play_context.remote_addr)

was added)

Also, it was tested with AWS EKS and real environmental variables with AWS credentials that is my real case of why I created this issue.

BR/Yuriy

@yurnov
Copy link
Contributor Author

yurnov commented Apr 29, 2024

Hi @gravesm,

any chance to have PR reviewed soon?

BR/Yuriy

softwarefactory-project-zuul bot pushed a commit that referenced this issue May 7, 2024
add support of kubectl_local_env_vars (#698)

SUMMARY
Support of local environmental variable that may be required to be set on Ansible Controller before the connection is set and may be used for kubectl command. This PR addressed for #698
The main idea is to have the support of  additional/extra local environmental variable that may be required for kubectl itself, i.e. for authorization in case of public clouds
ISSUE TYPE

Feature Pull Request

COMPONENT NAME
kubernetes.core.kubectl connection plugin
ADDITIONAL INFORMATION
This PR attempts to implement local env support for the kubectl connection plugin that may be useful in case of using kubectl against public cloud kubernetes environment that uses some authorization (i.e. aws cli) additionally to kubeconfig file. More detail in #698
The output that shows that the connection plugin can use local environment variable for kubectl command (with some debug that used during development but removed then):
root@ubuntu-shell:/# cat test.yaml
- hosts: localhost
  gather_facts: no
  any_errors_fatal: yes
  vars:
    ansible_connection: "kubectl"
    ansible_kubectl_namespace: "test"
    ansible_kubectl_config: "/.kube/config"
    ansible_kubectl_pod: "ubuntu"
    ansible_kubectl_container: "ubuntu"
    ansible_kubectl_local_env_vars:
      TESTVAR1: "test"
      TESTVAR2: "test"
      TESTVAR3: "test"
  environment:
    TEST_ENV1: value1
    TEST_ENV2: value2

  tasks:
  - name: test
    ansible.builtin.shell: env
    register: result
  - debug:
      var: result.stdout_lines
root@ubuntu-shell:/# ansible-playbook test.yaml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [localhost] **************************************************************************************************************************************

TASK [test] *******************************************************************************************************************************************
changed: [localhost]

TASK [debug] ******************************************************************************************************************************************
ok: [localhost] => {
    "result.stdout_lines": [
        "KUBERNETES_PORT=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_PORT=443",
        "HOSTNAME=ubuntu",
        "HOME=/root",
        "LC_CTYPE=C.UTF-8",
        "TEST_ENV1=value1",
        "TEST_ENV2=value2",
        "TERM=xterm",
        "KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1",
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "KUBERNETES_PORT_443_TCP_PORT=443",
        "KUBERNETES_PORT_443_TCP_PROTO=tcp",
        "KUBERNETES_SERVICE_PORT_HTTPS=443",
        "KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_HOST=10.96.0.1",
        "PWD=/"
    ]
}

PLAY RECAP ********************************************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

root@ubuntu-shell:/# ansible-playbook test.yaml -vvv
ansible-playbook [core 2.14.5]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.10/dist-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] (/usr/bin/python3)
  jinja version = 3.1.3
  libyaml = True
No config file found; using defaults
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
yaml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
ini declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
toml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.

PLAYBOOK: test.yaml ***********************************************************************************************************************************
1 plays in test.yaml

PLAY [localhost] **************************************************************************************************************************************

TASK [test] *******************************************************************************************************************************************
task path: /test.yaml:19
redirecting (type: connection) ansible.builtin.kubectl to kubernetes.core.kubectl
<127.0.0.1> ESTABLISH kubectl CONNECTION
<127.0.0.1> ENV: KUBERNETES_SERVICE_PORT_HTTPS=443
<127.0.0.1> ENV: KUBERNETES_SERVICE_PORT=443
<127.0.0.1> ENV: HOSTNAME=ubuntu-shell
<127.0.0.1> ENV: PWD=/
<127.0.0.1> ENV: HOME=/root
<127.0.0.1> ENV: KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
<127.0.0.1> ENV: LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
<127.0.0.1> ENV: TERM=xterm
<127.0.0.1> ENV: SHLVL=1
<127.0.0.1> ENV: KUBERNETES_PORT_443_TCP_PROTO=tcp
<127.0.0.1> ENV: KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
<127.0.0.1> ENV: KUBERNETES_SERVICE_HOST=10.96.0.1
<127.0.0.1> ENV: KUBERNETES_PORT=tcp://10.96.0.1:443
<127.0.0.1> ENV: KUBERNETES_PORT_443_TCP_PORT=443
<127.0.0.1> ENV: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
<127.0.0.1> ENV: _=/usr/local/bin/ansible-playbook
<127.0.0.1> ENV: LC_CTYPE=C.UTF-8
<127.0.0.1> ENV: TESTVAR1=test
<127.0.0.1> ENV: TESTVAR2=test
<127.0.0.1> ENV: TESTVAR3=test
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'echo ~ && sleep 0'"]
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', '/bin/sh -c \'( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133 `" && echo ansible-tmp-1713785852.548581-6866-69007595335133="` echo /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133 `" ) && sleep 0\'']
Using module file /usr/local/lib/python3.10/dist-packages/ansible/modules/command.py
<127.0.0.1> PUT /root/.ansible/tmp/ansible-local-6862s5_lr_wb/tmpxwmx0qeh TO /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/AnsiballZ_command.py
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/ /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/AnsiballZ_command.py && sleep 0'"]
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'TEST_ENV1=value1 TEST_ENV2=value2 /usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/AnsiballZ_command.py && sleep 0'"]
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/ > /dev/null 2>&1 && sleep 0'"]
changed: [localhost] => {
    "changed": true,
    "cmd": "env",
    "delta": "0:00:00.005088",
    "end": "2024-04-22 11:37:33.655340",
    "invocation": {
        "module_args": {
            "_raw_params": "env",
            "_uses_shell": true,
            "argv": null,
            "chdir": null,
            "creates": null,
            "executable": null,
            "removes": null,
            "stdin": null,
            "stdin_add_newline": true,
            "strip_empty_ends": true
        }
    },
    "msg": "",
    "rc": 0,
    "start": "2024-04-22 11:37:33.650252",
    "stderr": "",
    "stderr_lines": [],
    "stdout": "KUBERNETES_PORT=tcp://10.96.0.1:443\nKUBERNETES_SERVICE_PORT=443\nHOSTNAME=ubuntu\nHOME=/root\nLC_CTYPE=C.UTF-8\nTEST_ENV1=value1\nTEST_ENV2=value2\nTERM=xterm\nKUBERNETES_PORT_443_TCP_ADDR=10.96.0.1\nPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\nKUBERNETES_PORT_443_TCP_PORT=443\nKUBERNETES_PORT_443_TCP_PROTO=tcp\nKUBERNETES_SERVICE_PORT_HTTPS=443\nKUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443\nKUBERNETES_SERVICE_HOST=10.96.0.1\nPWD=/",
    "stdout_lines": [
        "KUBERNETES_PORT=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_PORT=443",
        "HOSTNAME=ubuntu",
        "HOME=/root",
        "LC_CTYPE=C.UTF-8",
        "TEST_ENV1=value1",
        "TEST_ENV2=value2",
        "TERM=xterm",
        "KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1",
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "KUBERNETES_PORT_443_TCP_PORT=443",
        "KUBERNETES_PORT_443_TCP_PROTO=tcp",
        "KUBERNETES_SERVICE_PORT_HTTPS=443",
        "KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_HOST=10.96.0.1",
        "PWD=/"
    ]
}

TASK [debug] ******************************************************************************************************************************************
task path: /test.yaml:22
redirecting (type: connection) ansible.builtin.kubectl to kubernetes.core.kubectl
ok: [localhost] => {
    "result.stdout_lines": [
        "KUBERNETES_PORT=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_PORT=443",
        "HOSTNAME=ubuntu",
        "HOME=/root",
        "LC_CTYPE=C.UTF-8",
        "TEST_ENV1=value1",
        "TEST_ENV2=value2",
        "TERM=xterm",
        "KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1",
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "KUBERNETES_PORT_443_TCP_PORT=443",
        "KUBERNETES_PORT_443_TCP_PROTO=tcp",
        "KUBERNETES_SERVICE_PORT_HTTPS=443",
        "KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_HOST=10.96.0.1",
        "PWD=/"
    ]
}

PLAY RECAP ********************************************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

root@ubuntu-shell:/#

Reviewed-by: Bikouo Aubin
Reviewed-by: Yuriy Novostavskiy
Reviewed-by: Mike Graves <[email protected]>
patchback bot pushed a commit that referenced this issue May 7, 2024
add support of kubectl_local_env_vars (#698)

SUMMARY
Support of local environmental variable that may be required to be set on Ansible Controller before the connection is set and may be used for kubectl command. This PR addressed for #698
The main idea is to have the support of  additional/extra local environmental variable that may be required for kubectl itself, i.e. for authorization in case of public clouds
ISSUE TYPE

Feature Pull Request

COMPONENT NAME
kubernetes.core.kubectl connection plugin
ADDITIONAL INFORMATION
This PR attempts to implement local env support for the kubectl connection plugin that may be useful in case of using kubectl against public cloud kubernetes environment that uses some authorization (i.e. aws cli) additionally to kubeconfig file. More detail in #698
The output that shows that the connection plugin can use local environment variable for kubectl command (with some debug that used during development but removed then):
root@ubuntu-shell:/# cat test.yaml
- hosts: localhost
  gather_facts: no
  any_errors_fatal: yes
  vars:
    ansible_connection: "kubectl"
    ansible_kubectl_namespace: "test"
    ansible_kubectl_config: "/.kube/config"
    ansible_kubectl_pod: "ubuntu"
    ansible_kubectl_container: "ubuntu"
    ansible_kubectl_local_env_vars:
      TESTVAR1: "test"
      TESTVAR2: "test"
      TESTVAR3: "test"
  environment:
    TEST_ENV1: value1
    TEST_ENV2: value2

  tasks:
  - name: test
    ansible.builtin.shell: env
    register: result
  - debug:
      var: result.stdout_lines
root@ubuntu-shell:/# ansible-playbook test.yaml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [localhost] **************************************************************************************************************************************

TASK [test] *******************************************************************************************************************************************
changed: [localhost]

TASK [debug] ******************************************************************************************************************************************
ok: [localhost] => {
    "result.stdout_lines": [
        "KUBERNETES_PORT=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_PORT=443",
        "HOSTNAME=ubuntu",
        "HOME=/root",
        "LC_CTYPE=C.UTF-8",
        "TEST_ENV1=value1",
        "TEST_ENV2=value2",
        "TERM=xterm",
        "KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1",
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "KUBERNETES_PORT_443_TCP_PORT=443",
        "KUBERNETES_PORT_443_TCP_PROTO=tcp",
        "KUBERNETES_SERVICE_PORT_HTTPS=443",
        "KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_HOST=10.96.0.1",
        "PWD=/"
    ]
}

PLAY RECAP ********************************************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

root@ubuntu-shell:/# ansible-playbook test.yaml -vvv
ansible-playbook [core 2.14.5]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.10/dist-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] (/usr/bin/python3)
  jinja version = 3.1.3
  libyaml = True
No config file found; using defaults
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
yaml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
ini declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
toml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.

PLAYBOOK: test.yaml ***********************************************************************************************************************************
1 plays in test.yaml

PLAY [localhost] **************************************************************************************************************************************

TASK [test] *******************************************************************************************************************************************
task path: /test.yaml:19
redirecting (type: connection) ansible.builtin.kubectl to kubernetes.core.kubectl
<127.0.0.1> ESTABLISH kubectl CONNECTION
<127.0.0.1> ENV: KUBERNETES_SERVICE_PORT_HTTPS=443
<127.0.0.1> ENV: KUBERNETES_SERVICE_PORT=443
<127.0.0.1> ENV: HOSTNAME=ubuntu-shell
<127.0.0.1> ENV: PWD=/
<127.0.0.1> ENV: HOME=/root
<127.0.0.1> ENV: KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
<127.0.0.1> ENV: LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
<127.0.0.1> ENV: TERM=xterm
<127.0.0.1> ENV: SHLVL=1
<127.0.0.1> ENV: KUBERNETES_PORT_443_TCP_PROTO=tcp
<127.0.0.1> ENV: KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
<127.0.0.1> ENV: KUBERNETES_SERVICE_HOST=10.96.0.1
<127.0.0.1> ENV: KUBERNETES_PORT=tcp://10.96.0.1:443
<127.0.0.1> ENV: KUBERNETES_PORT_443_TCP_PORT=443
<127.0.0.1> ENV: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
<127.0.0.1> ENV: _=/usr/local/bin/ansible-playbook
<127.0.0.1> ENV: LC_CTYPE=C.UTF-8
<127.0.0.1> ENV: TESTVAR1=test
<127.0.0.1> ENV: TESTVAR2=test
<127.0.0.1> ENV: TESTVAR3=test
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'echo ~ && sleep 0'"]
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', '/bin/sh -c \'( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133 `" && echo ansible-tmp-1713785852.548581-6866-69007595335133="` echo /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133 `" ) && sleep 0\'']
Using module file /usr/local/lib/python3.10/dist-packages/ansible/modules/command.py
<127.0.0.1> PUT /root/.ansible/tmp/ansible-local-6862s5_lr_wb/tmpxwmx0qeh TO /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/AnsiballZ_command.py
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/ /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/AnsiballZ_command.py && sleep 0'"]
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'TEST_ENV1=value1 TEST_ENV2=value2 /usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/AnsiballZ_command.py && sleep 0'"]
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/ > /dev/null 2>&1 && sleep 0'"]
changed: [localhost] => {
    "changed": true,
    "cmd": "env",
    "delta": "0:00:00.005088",
    "end": "2024-04-22 11:37:33.655340",
    "invocation": {
        "module_args": {
            "_raw_params": "env",
            "_uses_shell": true,
            "argv": null,
            "chdir": null,
            "creates": null,
            "executable": null,
            "removes": null,
            "stdin": null,
            "stdin_add_newline": true,
            "strip_empty_ends": true
        }
    },
    "msg": "",
    "rc": 0,
    "start": "2024-04-22 11:37:33.650252",
    "stderr": "",
    "stderr_lines": [],
    "stdout": "KUBERNETES_PORT=tcp://10.96.0.1:443\nKUBERNETES_SERVICE_PORT=443\nHOSTNAME=ubuntu\nHOME=/root\nLC_CTYPE=C.UTF-8\nTEST_ENV1=value1\nTEST_ENV2=value2\nTERM=xterm\nKUBERNETES_PORT_443_TCP_ADDR=10.96.0.1\nPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\nKUBERNETES_PORT_443_TCP_PORT=443\nKUBERNETES_PORT_443_TCP_PROTO=tcp\nKUBERNETES_SERVICE_PORT_HTTPS=443\nKUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443\nKUBERNETES_SERVICE_HOST=10.96.0.1\nPWD=/",
    "stdout_lines": [
        "KUBERNETES_PORT=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_PORT=443",
        "HOSTNAME=ubuntu",
        "HOME=/root",
        "LC_CTYPE=C.UTF-8",
        "TEST_ENV1=value1",
        "TEST_ENV2=value2",
        "TERM=xterm",
        "KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1",
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "KUBERNETES_PORT_443_TCP_PORT=443",
        "KUBERNETES_PORT_443_TCP_PROTO=tcp",
        "KUBERNETES_SERVICE_PORT_HTTPS=443",
        "KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_HOST=10.96.0.1",
        "PWD=/"
    ]
}

TASK [debug] ******************************************************************************************************************************************
task path: /test.yaml:22
redirecting (type: connection) ansible.builtin.kubectl to kubernetes.core.kubectl
ok: [localhost] => {
    "result.stdout_lines": [
        "KUBERNETES_PORT=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_PORT=443",
        "HOSTNAME=ubuntu",
        "HOME=/root",
        "LC_CTYPE=C.UTF-8",
        "TEST_ENV1=value1",
        "TEST_ENV2=value2",
        "TERM=xterm",
        "KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1",
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "KUBERNETES_PORT_443_TCP_PORT=443",
        "KUBERNETES_PORT_443_TCP_PROTO=tcp",
        "KUBERNETES_SERVICE_PORT_HTTPS=443",
        "KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_HOST=10.96.0.1",
        "PWD=/"
    ]
}

PLAY RECAP ********************************************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

root@ubuntu-shell:/#

Reviewed-by: Bikouo Aubin
Reviewed-by: Yuriy Novostavskiy
Reviewed-by: Mike Graves <[email protected]>
(cherry picked from commit fb25ff4)
gravesm pushed a commit that referenced this issue May 8, 2024
add support of kubectl_local_env_vars (#698)

SUMMARY
Support of local environmental variable that may be required to be set on Ansible Controller before the connection is set and may be used for kubectl command. This PR addressed for #698
The main idea is to have the support of  additional/extra local environmental variable that may be required for kubectl itself, i.e. for authorization in case of public clouds
ISSUE TYPE

Feature Pull Request

COMPONENT NAME
kubernetes.core.kubectl connection plugin
ADDITIONAL INFORMATION
This PR attempts to implement local env support for the kubectl connection plugin that may be useful in case of using kubectl against public cloud kubernetes environment that uses some authorization (i.e. aws cli) additionally to kubeconfig file. More detail in #698
The output that shows that the connection plugin can use local environment variable for kubectl command (with some debug that used during development but removed then):
root@ubuntu-shell:/# cat test.yaml
- hosts: localhost
  gather_facts: no
  any_errors_fatal: yes
  vars:
    ansible_connection: "kubectl"
    ansible_kubectl_namespace: "test"
    ansible_kubectl_config: "/.kube/config"
    ansible_kubectl_pod: "ubuntu"
    ansible_kubectl_container: "ubuntu"
    ansible_kubectl_local_env_vars:
      TESTVAR1: "test"
      TESTVAR2: "test"
      TESTVAR3: "test"
  environment:
    TEST_ENV1: value1
    TEST_ENV2: value2

  tasks:
  - name: test
    ansible.builtin.shell: env
    register: result
  - debug:
      var: result.stdout_lines
root@ubuntu-shell:/# ansible-playbook test.yaml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [localhost] **************************************************************************************************************************************

TASK [test] *******************************************************************************************************************************************
changed: [localhost]

TASK [debug] ******************************************************************************************************************************************
ok: [localhost] => {
    "result.stdout_lines": [
        "KUBERNETES_PORT=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_PORT=443",
        "HOSTNAME=ubuntu",
        "HOME=/root",
        "LC_CTYPE=C.UTF-8",
        "TEST_ENV1=value1",
        "TEST_ENV2=value2",
        "TERM=xterm",
        "KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1",
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "KUBERNETES_PORT_443_TCP_PORT=443",
        "KUBERNETES_PORT_443_TCP_PROTO=tcp",
        "KUBERNETES_SERVICE_PORT_HTTPS=443",
        "KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_HOST=10.96.0.1",
        "PWD=/"
    ]
}

PLAY RECAP ********************************************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

root@ubuntu-shell:/# ansible-playbook test.yaml -vvv
ansible-playbook [core 2.14.5]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.10/dist-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] (/usr/bin/python3)
  jinja version = 3.1.3
  libyaml = True
No config file found; using defaults
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
yaml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
ini declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
toml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.

PLAYBOOK: test.yaml ***********************************************************************************************************************************
1 plays in test.yaml

PLAY [localhost] **************************************************************************************************************************************

TASK [test] *******************************************************************************************************************************************
task path: /test.yaml:19
redirecting (type: connection) ansible.builtin.kubectl to kubernetes.core.kubectl
<127.0.0.1> ESTABLISH kubectl CONNECTION
<127.0.0.1> ENV: KUBERNETES_SERVICE_PORT_HTTPS=443
<127.0.0.1> ENV: KUBERNETES_SERVICE_PORT=443
<127.0.0.1> ENV: HOSTNAME=ubuntu-shell
<127.0.0.1> ENV: PWD=/
<127.0.0.1> ENV: HOME=/root
<127.0.0.1> ENV: KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
<127.0.0.1> ENV: LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
<127.0.0.1> ENV: TERM=xterm
<127.0.0.1> ENV: SHLVL=1
<127.0.0.1> ENV: KUBERNETES_PORT_443_TCP_PROTO=tcp
<127.0.0.1> ENV: KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
<127.0.0.1> ENV: KUBERNETES_SERVICE_HOST=10.96.0.1
<127.0.0.1> ENV: KUBERNETES_PORT=tcp://10.96.0.1:443
<127.0.0.1> ENV: KUBERNETES_PORT_443_TCP_PORT=443
<127.0.0.1> ENV: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
<127.0.0.1> ENV: _=/usr/local/bin/ansible-playbook
<127.0.0.1> ENV: LC_CTYPE=C.UTF-8
<127.0.0.1> ENV: TESTVAR1=test
<127.0.0.1> ENV: TESTVAR2=test
<127.0.0.1> ENV: TESTVAR3=test
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'echo ~ && sleep 0'"]
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', '/bin/sh -c \'( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133 `" && echo ansible-tmp-1713785852.548581-6866-69007595335133="` echo /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133 `" ) && sleep 0\'']
Using module file /usr/local/lib/python3.10/dist-packages/ansible/modules/command.py
<127.0.0.1> PUT /root/.ansible/tmp/ansible-local-6862s5_lr_wb/tmpxwmx0qeh TO /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/AnsiballZ_command.py
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/ /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/AnsiballZ_command.py && sleep 0'"]
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'TEST_ENV1=value1 TEST_ENV2=value2 /usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/AnsiballZ_command.py && sleep 0'"]
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/ > /dev/null 2>&1 && sleep 0'"]
changed: [localhost] => {
    "changed": true,
    "cmd": "env",
    "delta": "0:00:00.005088",
    "end": "2024-04-22 11:37:33.655340",
    "invocation": {
        "module_args": {
            "_raw_params": "env",
            "_uses_shell": true,
            "argv": null,
            "chdir": null,
            "creates": null,
            "executable": null,
            "removes": null,
            "stdin": null,
            "stdin_add_newline": true,
            "strip_empty_ends": true
        }
    },
    "msg": "",
    "rc": 0,
    "start": "2024-04-22 11:37:33.650252",
    "stderr": "",
    "stderr_lines": [],
    "stdout": "KUBERNETES_PORT=tcp://10.96.0.1:443\nKUBERNETES_SERVICE_PORT=443\nHOSTNAME=ubuntu\nHOME=/root\nLC_CTYPE=C.UTF-8\nTEST_ENV1=value1\nTEST_ENV2=value2\nTERM=xterm\nKUBERNETES_PORT_443_TCP_ADDR=10.96.0.1\nPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\nKUBERNETES_PORT_443_TCP_PORT=443\nKUBERNETES_PORT_443_TCP_PROTO=tcp\nKUBERNETES_SERVICE_PORT_HTTPS=443\nKUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443\nKUBERNETES_SERVICE_HOST=10.96.0.1\nPWD=/",
    "stdout_lines": [
        "KUBERNETES_PORT=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_PORT=443",
        "HOSTNAME=ubuntu",
        "HOME=/root",
        "LC_CTYPE=C.UTF-8",
        "TEST_ENV1=value1",
        "TEST_ENV2=value2",
        "TERM=xterm",
        "KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1",
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "KUBERNETES_PORT_443_TCP_PORT=443",
        "KUBERNETES_PORT_443_TCP_PROTO=tcp",
        "KUBERNETES_SERVICE_PORT_HTTPS=443",
        "KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_HOST=10.96.0.1",
        "PWD=/"
    ]
}

TASK [debug] ******************************************************************************************************************************************
task path: /test.yaml:22
redirecting (type: connection) ansible.builtin.kubectl to kubernetes.core.kubectl
ok: [localhost] => {
    "result.stdout_lines": [
        "KUBERNETES_PORT=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_PORT=443",
        "HOSTNAME=ubuntu",
        "HOME=/root",
        "LC_CTYPE=C.UTF-8",
        "TEST_ENV1=value1",
        "TEST_ENV2=value2",
        "TERM=xterm",
        "KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1",
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "KUBERNETES_PORT_443_TCP_PORT=443",
        "KUBERNETES_PORT_443_TCP_PROTO=tcp",
        "KUBERNETES_SERVICE_PORT_HTTPS=443",
        "KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_HOST=10.96.0.1",
        "PWD=/"
    ]
}

PLAY RECAP ********************************************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

root@ubuntu-shell:/#

Reviewed-by: Bikouo Aubin
Reviewed-by: Yuriy Novostavskiy
Reviewed-by: Mike Graves <[email protected]>
(cherry picked from commit fb25ff4)
softwarefactory-project-zuul bot pushed a commit that referenced this issue May 8, 2024
[PR #702/fb25ff44 backport][stable-3] add support of kubectl_local_env_vars (#698)

This is a backport of PR #702 as merged into main (fb25ff4).
SUMMARY
Support of local environmental variable that may be required to be set on Ansible Controller before the connection is set and may be used for kubectl command. This PR addressed for #698
The main idea is to have the support of  additional/extra local environmental variable that may be required for kubectl itself, i.e. for authorization in case of public clouds
ISSUE TYPE

Feature Pull Request

COMPONENT NAME
kubernetes.core.kubectl connection plugin
ADDITIONAL INFORMATION
This PR attempts to implement local env support for the kubectl connection plugin that may be useful in case of using kubectl against public cloud kubernetes environment that uses some authorization (i.e. aws cli) additionally to kubeconfig file. More detail in #698
The output that shows that the connection plugin can use local environment variable for kubectl command (with some debug that used during development but removed then):
root@ubuntu-shell:/# cat test.yaml
- hosts: localhost
  gather_facts: no
  any_errors_fatal: yes
  vars:
    ansible_connection: "kubectl"
    ansible_kubectl_namespace: "test"
    ansible_kubectl_config: "/.kube/config"
    ansible_kubectl_pod: "ubuntu"
    ansible_kubectl_container: "ubuntu"
    ansible_kubectl_local_env_vars:
      TESTVAR1: "test"
      TESTVAR2: "test"
      TESTVAR3: "test"
  environment:
    TEST_ENV1: value1
    TEST_ENV2: value2

  tasks:
  - name: test
    ansible.builtin.shell: env
    register: result
  - debug:
      var: result.stdout_lines
root@ubuntu-shell:/# ansible-playbook test.yaml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [localhost] **************************************************************************************************************************************

TASK [test] *******************************************************************************************************************************************
changed: [localhost]

TASK [debug] ******************************************************************************************************************************************
ok: [localhost] => {
    "result.stdout_lines": [
        "KUBERNETES_PORT=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_PORT=443",
        "HOSTNAME=ubuntu",
        "HOME=/root",
        "LC_CTYPE=C.UTF-8",
        "TEST_ENV1=value1",
        "TEST_ENV2=value2",
        "TERM=xterm",
        "KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1",
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "KUBERNETES_PORT_443_TCP_PORT=443",
        "KUBERNETES_PORT_443_TCP_PROTO=tcp",
        "KUBERNETES_SERVICE_PORT_HTTPS=443",
        "KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_HOST=10.96.0.1",
        "PWD=/"
    ]
}

PLAY RECAP ********************************************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

root@ubuntu-shell:/# ansible-playbook test.yaml -vvv
ansible-playbook [core 2.14.5]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.10/dist-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] (/usr/bin/python3)
  jinja version = 3.1.3
  libyaml = True
No config file found; using defaults
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
yaml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
ini declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
toml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.

PLAYBOOK: test.yaml ***********************************************************************************************************************************
1 plays in test.yaml

PLAY [localhost] **************************************************************************************************************************************

TASK [test] *******************************************************************************************************************************************
task path: /test.yaml:19
redirecting (type: connection) ansible.builtin.kubectl to kubernetes.core.kubectl
<127.0.0.1> ESTABLISH kubectl CONNECTION
<127.0.0.1> ENV: KUBERNETES_SERVICE_PORT_HTTPS=443
<127.0.0.1> ENV: KUBERNETES_SERVICE_PORT=443
<127.0.0.1> ENV: HOSTNAME=ubuntu-shell
<127.0.0.1> ENV: PWD=/
<127.0.0.1> ENV: HOME=/root
<127.0.0.1> ENV: KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
<127.0.0.1> ENV: LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
<127.0.0.1> ENV: TERM=xterm
<127.0.0.1> ENV: SHLVL=1
<127.0.0.1> ENV: KUBERNETES_PORT_443_TCP_PROTO=tcp
<127.0.0.1> ENV: KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
<127.0.0.1> ENV: KUBERNETES_SERVICE_HOST=10.96.0.1
<127.0.0.1> ENV: KUBERNETES_PORT=tcp://10.96.0.1:443
<127.0.0.1> ENV: KUBERNETES_PORT_443_TCP_PORT=443
<127.0.0.1> ENV: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
<127.0.0.1> ENV: _=/usr/local/bin/ansible-playbook
<127.0.0.1> ENV: LC_CTYPE=C.UTF-8
<127.0.0.1> ENV: TESTVAR1=test
<127.0.0.1> ENV: TESTVAR2=test
<127.0.0.1> ENV: TESTVAR3=test
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'echo ~ && sleep 0'"]
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', '/bin/sh -c \'( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133 `" && echo ansible-tmp-1713785852.548581-6866-69007595335133="` echo /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133 `" ) && sleep 0\'']
Using module file /usr/local/lib/python3.10/dist-packages/ansible/modules/command.py
<127.0.0.1> PUT /root/.ansible/tmp/ansible-local-6862s5_lr_wb/tmpxwmx0qeh TO /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/AnsiballZ_command.py
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/ /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/AnsiballZ_command.py && sleep 0'"]
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'TEST_ENV1=value1 TEST_ENV2=value2 /usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/AnsiballZ_command.py && sleep 0'"]
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/ > /dev/null 2>&1 && sleep 0'"]
changed: [localhost] => {
    "changed": true,
    "cmd": "env",
    "delta": "0:00:00.005088",
    "end": "2024-04-22 11:37:33.655340",
    "invocation": {
        "module_args": {
            "_raw_params": "env",
            "_uses_shell": true,
            "argv": null,
            "chdir": null,
            "creates": null,
            "executable": null,
            "removes": null,
            "stdin": null,
            "stdin_add_newline": true,
            "strip_empty_ends": true
        }
    },
    "msg": "",
    "rc": 0,
    "start": "2024-04-22 11:37:33.650252",
    "stderr": "",
    "stderr_lines": [],
    "stdout": "KUBERNETES_PORT=tcp://10.96.0.1:443\nKUBERNETES_SERVICE_PORT=443\nHOSTNAME=ubuntu\nHOME=/root\nLC_CTYPE=C.UTF-8\nTEST_ENV1=value1\nTEST_ENV2=value2\nTERM=xterm\nKUBERNETES_PORT_443_TCP_ADDR=10.96.0.1\nPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\nKUBERNETES_PORT_443_TCP_PORT=443\nKUBERNETES_PORT_443_TCP_PROTO=tcp\nKUBERNETES_SERVICE_PORT_HTTPS=443\nKUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443\nKUBERNETES_SERVICE_HOST=10.96.0.1\nPWD=/",
    "stdout_lines": [
        "KUBERNETES_PORT=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_PORT=443",
        "HOSTNAME=ubuntu",
        "HOME=/root",
        "LC_CTYPE=C.UTF-8",
        "TEST_ENV1=value1",
        "TEST_ENV2=value2",
        "TERM=xterm",
        "KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1",
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "KUBERNETES_PORT_443_TCP_PORT=443",
        "KUBERNETES_PORT_443_TCP_PROTO=tcp",
        "KUBERNETES_SERVICE_PORT_HTTPS=443",
        "KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_HOST=10.96.0.1",
        "PWD=/"
    ]
}

TASK [debug] ******************************************************************************************************************************************
task path: /test.yaml:22
redirecting (type: connection) ansible.builtin.kubectl to kubernetes.core.kubectl
ok: [localhost] => {
    "result.stdout_lines": [
        "KUBERNETES_PORT=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_PORT=443",
        "HOSTNAME=ubuntu",
        "HOME=/root",
        "LC_CTYPE=C.UTF-8",
        "TEST_ENV1=value1",
        "TEST_ENV2=value2",
        "TERM=xterm",
        "KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1",
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "KUBERNETES_PORT_443_TCP_PORT=443",
        "KUBERNETES_PORT_443_TCP_PROTO=tcp",
        "KUBERNETES_SERVICE_PORT_HTTPS=443",
        "KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_HOST=10.96.0.1",
        "PWD=/"
    ]
}

PLAY RECAP ********************************************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

root@ubuntu-shell:/#

Reviewed-by: Mike Graves <[email protected]>
@yurnov
Copy link
Contributor Author

yurnov commented May 9, 2024

PR #702 is merged to main and backported to stable-3 as #705, so, it will be included in version 3.1.0 or any other minor further release.

Thanks, @gravesm and @abikouo for their review and support

@yurnov
Copy link
Contributor Author

yurnov commented May 17, 2024

Added in release 3.1.0 by the PR #702

Changelog is here

Closing ticket as completed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants