ansible-collections / community.kubernetes

Kubernetes Collection for Ansible
https://galaxy.ansible.com/community/kubernetes
GNU General Public License v3.0
265 stars 104 forks source link

k8s modules lose configuration when using python-kubernetes v12 #315

Closed richm closed 3 years ago

richm commented 3 years ago
SUMMARY

When using python-kubernetes v12, the k8s module does not read the configuration from ~/.kube/config correctly - attempts to use the module will give some odd error because it will default to localhost.

ansible -m k8s -u root -a 'name=my-namespace api_version=v1 kind=Namespace state=present validate_certs=no' localhost 
localhost | FAILED! => {
    "changed": false,
    "msg": "Failed to get client due to HTTPConnectionPool(host='localhost', port=80): Max retries exceeded with url: /version (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f1a3a04d1f0>: Failed to establish a new connection: [Errno 111] Connection refused'))"
}

When using python-kubernetes v11, it works as expected - it correctly looks up the current context and configuration and uses it.

The ansible k8s module first uses the load_kube_config method to load the configuration from the ~/.kube/config file and store it in the Configuration._default class variable: https://github.com/ansible/ansible/blob/stable-2.9/lib/ansible/module_utils/k8s/common.py#L178-L188 It then calls kubernetes.client.Configuration() expecting that to return the default configuration that it just loaded: https://github.com/ansible/ansible/blob/stable-2.9/lib/ansible/module_utils/k8s/common.py#L191

This works when using python-kubernetes v11 because the call to Configuration() is really a method call, not a constructor call: https://github.com/kubernetes-client/python/blob/v11.0.0/kubernetes/client/configuration.py#L30 which returns Configuration._default if set, otherwise, it calls the constructor. But in python-kubernetes v12, it is strictly a constructor: https://github.com/kubernetes-client/python/blob/release-12.0/kubernetes/client/configuration.py - so when using v12, it returns an empty configuration object, essentially throwing away the configuration just loaded from ~/.kube/config.

One possible solution is to use Configuration.get_default_copy(), then fallback to kubernetes.client.Configuration():

        # Override any values in the default configuration with Ansible parameters
        try:
            configuration = kubernetes.client.Configuration.get_default_copy()
        except AttributeError:
            configuration = kubernetes.client.Configuration()
ISSUE TYPE
COMPONENT NAME

k8s

ANSIBLE VERSION
ansible 2.9.14
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/rmeggins/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.8/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.8.6 (default, Sep 25 2020, 00:00:00) [GCC 10.2.1 20200723 (Red Hat 10.2.1-1)]

also affects ansible 2.10:

ansible 2.10.3
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/rmeggins/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/rmeggins/linux-system-roles/test-harness/.venv/lib64/python3.8/site-packages/ansible
  executable location = /home/rmeggins/linux-system-roles/test-harness/.venv/bin/ansible
  python version = 3.8.6 (default, Sep 25 2020, 00:00:00) [GCC 10.2.1 20200723 (Red Hat 10.2.1-1)]
CONFIGURATION

empty

OS / ENVIRONMENT

Fedora 32 - both the standard RPM ansible package and pip install ansible

STEPS TO REPRODUCE
ansible -m k8s -u root -a 'name=my-namespace api_version=v1 kind=Namespace state=present validate_certs=no' localhost
EXPECTED RESULTS

Should not get error Failed to get client due to HTTPConnectionPool(host='localhost', port=80):

ACTUAL RESULTS
tima commented 3 years ago

@richm Have you upgraded the community.kubernetes then what shipped with those versions or installed the kubernetes.core collection? I'm just verifying which version you are running with here.

richm commented 3 years ago

@richm Have you upgraded the community.kubernetes then what shipped with those versions or installed the kubernetes.core collection? I'm just verifying which version you are running with here.

I see that it is fixed (in the way I suggested) in the latest code: https://github.com/ansible-collections/community.kubernetes/blob/main/plugins/module_utils/common.py#L256-L261

So perhaps I can close this issue, but I would request that this fix is backported to ansible 2.9, and that the public python packages on pypi get the fix. https://github.com/ansible/ansible/issues/72784