diff --git a/changelogs/fragments/58-add-support-for-proxy_headers-on-authentication.yaml b/changelogs/fragments/58-add-support-for-proxy_headers-on-authentication.yaml new file mode 100644 index 0000000000..a887cb1d47 --- /dev/null +++ b/changelogs/fragments/58-add-support-for-proxy_headers-on-authentication.yaml @@ -0,0 +1,3 @@ +--- +minor_changes: + - add ``proxy_headers`` option for authentication on k8s_xxx modules (https://github.com/ansible-collections/kubernetes.core/pull/58). diff --git a/plugins/doc_fragments/k8s_auth_options.py b/plugins/doc_fragments/k8s_auth_options.py index d572108a6f..d63fbbc25d 100644 --- a/plugins/doc_fragments/k8s_auth_options.py +++ b/plugins/doc_fragments/k8s_auth_options.py @@ -75,6 +75,28 @@ class ModuleDocFragment(object): - The URL of an HTTP proxy to use for the connection. Can also be specified via 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 + proxy_headers: + description: + - The Header used for the HTTP proxy. + - Documentation can be found here U(https://urllib3.readthedocs.io/en/latest/reference/urllib3.util.html?highlight=proxy_headers#urllib3.util.make_headers). + type: dict + version_added: 2.0.0 + suboptions: + proxy_basic_auth: + type: str + description: + - Colon-separated username:password for proxy basic authentication header. + - Can also be specified via K8S_AUTH_PROXY_HEADERS_PROXY_BASIC_AUTH environment. + basic_auth: + type: str + description: + - Colon-separated username:password for basic authentication header. + - Can also be specified via K8S_AUTH_PROXY_HEADERS_BASIC_AUTH environment. + user_agent: + type: str + description: + - String representing the user-agent you want, such as foo/1.0. + - Can also be specified via K8S_AUTH_PROXY_HEADERS_USER_AGENT environment. persist_config: description: - Whether or not to save the kube config refresh tokens. diff --git a/plugins/module_utils/args_common.py b/plugins/module_utils/args_common.py index fadaf44e66..67c183db74 100644 --- a/plugins/module_utils/args_common.py +++ b/plugins/module_utils/args_common.py @@ -11,6 +11,12 @@ def list_dict_str(value): raise TypeError +AUTH_PROXY_HEADERS_SPEC = dict( + proxy_basic_auth=dict(type='str', no_log=True), + basic_auth=dict(type='str', no_log=True), + user_agent=dict(type='str') +) + AUTH_ARG_SPEC = { 'kubeconfig': { 'type': 'path', @@ -43,6 +49,10 @@ def list_dict_str(value): 'proxy': { 'type': 'str', }, + 'proxy_headers': { + 'type': 'dict', + 'options': AUTH_PROXY_HEADERS_SPEC + }, 'persist_config': { 'type': 'bool', }, @@ -76,6 +86,7 @@ def list_dict_str(value): 'cert_file': 'client_cert', 'key_file': 'client_key', 'proxy': 'proxy', + 'proxy_headers': 'proxy_headers', 'persist_config': 'persist_config', } diff --git a/plugins/module_utils/common.py b/plugins/module_utils/common.py index 4474eed3b4..14d13e5c39 100644 --- a/plugins/module_utils/common.py +++ b/plugins/module_utils/common.py @@ -28,7 +28,7 @@ from datetime import datetime from distutils.version import LooseVersion -from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (AUTH_ARG_MAP, AUTH_ARG_SPEC) +from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (AUTH_ARG_MAP, AUTH_ARG_SPEC, AUTH_PROXY_HEADERS_SPEC) from ansible_collections.kubernetes.core.plugins.module_utils.hashes import generate_hash from ansible_collections.kubernetes.core.plugins.module_utils.cache import get_default_cache_id @@ -38,7 +38,6 @@ from ansible.module_utils.common.dict_transformations import dict_merge from ansible.module_utils.parsing.convert_bool import boolean - K8S_IMP_ERR = None try: import kubernetes @@ -138,6 +137,17 @@ def _raise_or_fail(exc, msg): auth[true_name] = module.params.get(arg_name) elif arg_name in kwargs and kwargs.get(arg_name) is not None: auth[true_name] = kwargs.get(arg_name) + elif arg_name == "proxy_headers": + # specific case for 'proxy_headers' which is a dictionary + proxy_headers = {} + for key in AUTH_PROXY_HEADERS_SPEC.keys(): + env_value = os.getenv('K8S_AUTH_PROXY_HEADERS_{0}'.format(key.upper()), None) + if env_value is not None: + if AUTH_PROXY_HEADERS_SPEC[key].get('type') == 'bool': + env_value = env_value.lower() not in ['0', 'false', 'no'] + proxy_headers[key] = env_value + if proxy_headers is not {}: + auth[true_name] = proxy_headers else: env_value = os.getenv('K8S_AUTH_{0}'.format(arg_name.upper()), None) or os.getenv('K8S_AUTH_{0}'.format(true_name.upper()), None) if env_value is not None: @@ -182,6 +192,9 @@ def auth_set(*names): if key in AUTH_ARG_MAP.keys() and value is not None: if key == 'api_key': setattr(configuration, key, {'authorization': "Bearer {0}".format(value)}) + elif key == 'proxy_headers': + headers = urllib3.util.make_headers(**value) + setattr(configuration, key, headers) else: setattr(configuration, key, value)