mirror of
https://github.com/ansible-collections/kubernetes.core.git
synced 2026-05-07 05:22:39 +00:00
add support for in-memory kubeconfig (#212)
add support for in-memory kubeconfig SUMMARY k8s module support now authentication with kubeconfig parameter as file and dict. Closes #139 ISSUE TYPE Feature Pull Request COMPONENT NAME ADDITIONAL INFORMATION Reviewed-by: Mike Graves <mgraves@redhat.com> Reviewed-by: None <None>
This commit is contained in:
@@ -194,6 +194,24 @@ class ActionModule(ActionBase):
|
||||
except AnsibleError:
|
||||
raise AnsibleActionFail("%s does not exist in local filesystem" % local_path)
|
||||
|
||||
def get_kubeconfig(self, kubeconfig, remote_transport, new_module_args):
|
||||
if isinstance(kubeconfig, string_types):
|
||||
# find the kubeconfig in the expected search path
|
||||
if not remote_transport:
|
||||
# kubeconfig is local
|
||||
# find in expected paths
|
||||
kubeconfig = self._find_needle('files', kubeconfig)
|
||||
|
||||
# decrypt kubeconfig found
|
||||
actual_file = self._loader.get_real_file(kubeconfig, decrypt=True)
|
||||
new_module_args['kubeconfig'] = actual_file
|
||||
|
||||
elif isinstance(kubeconfig, dict):
|
||||
new_module_args['kubeconfig'] = kubeconfig
|
||||
else:
|
||||
raise AnsibleActionFail("Error while reading kubeconfig parameter - "
|
||||
"a string or dict expected, but got %s instead" % type(kubeconfig))
|
||||
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
''' handler for k8s options '''
|
||||
if task_vars is None:
|
||||
@@ -211,22 +229,15 @@ class ActionModule(ActionBase):
|
||||
new_module_args = copy.deepcopy(self._task.args)
|
||||
|
||||
kubeconfig = self._task.args.get('kubeconfig', None)
|
||||
# find the kubeconfig in the expected search path
|
||||
if kubeconfig and not remote_transport:
|
||||
# kubeconfig is local
|
||||
if kubeconfig:
|
||||
try:
|
||||
# find in expected paths
|
||||
kubeconfig = self._find_needle('files', kubeconfig)
|
||||
self.get_kubeconfig(kubeconfig, remote_transport, new_module_args)
|
||||
except AnsibleError as e:
|
||||
result['failed'] = True
|
||||
result['msg'] = to_text(e)
|
||||
result['exception'] = traceback.format_exc()
|
||||
return result
|
||||
|
||||
# decrypt kubeconfig found
|
||||
actual_file = self._loader.get_real_file(kubeconfig, decrypt=True)
|
||||
new_module_args['kubeconfig'] = actual_file
|
||||
|
||||
# find the file in the expected search path
|
||||
src = self._task.args.get('src', None)
|
||||
|
||||
|
||||
@@ -27,7 +27,8 @@ options:
|
||||
options are provided, the Kubernetes client will attempt to load the default
|
||||
configuration file from I(~/.kube/config). Can also be specified via K8S_AUTH_KUBECONFIG environment
|
||||
variable.
|
||||
type: path
|
||||
- The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version >= 17.17.0. Added in version 2.2.0.
|
||||
type: raw
|
||||
context:
|
||||
description:
|
||||
- The name of a context found in the config file. Can also be specified via K8S_AUTH_CONTEXT environment variable.
|
||||
|
||||
@@ -19,7 +19,7 @@ AUTH_PROXY_HEADERS_SPEC = dict(
|
||||
|
||||
AUTH_ARG_SPEC = {
|
||||
'kubeconfig': {
|
||||
'type': 'path',
|
||||
'type': 'raw',
|
||||
},
|
||||
'context': {},
|
||||
'host': {},
|
||||
|
||||
@@ -120,9 +120,8 @@ def get_api_client(module=None, **kwargs):
|
||||
|
||||
def _raise_or_fail(exc, msg):
|
||||
if module:
|
||||
module.fail_json(msg % to_native(exc))
|
||||
module.fail_json(msg=msg % to_native(exc))
|
||||
raise exc
|
||||
|
||||
# If authorization variables aren't defined, look for them in environment variables
|
||||
for true_name, arg_name in AUTH_ARG_MAP.items():
|
||||
if module and module.params.get(arg_name) is not None:
|
||||
@@ -150,6 +149,22 @@ def get_api_client(module=None, **kwargs):
|
||||
def auth_set(*names):
|
||||
return all(auth.get(name) for name in names)
|
||||
|
||||
def _load_config():
|
||||
kubeconfig = auth.get('kubeconfig')
|
||||
optional_arg = {
|
||||
'context': auth.get('context'),
|
||||
'persist_config': auth.get('persist_config'),
|
||||
}
|
||||
if kubeconfig:
|
||||
if isinstance(kubeconfig, string_types):
|
||||
kubernetes.config.load_kube_config(config_file=kubeconfig, **optional_arg)
|
||||
elif isinstance(kubeconfig, dict):
|
||||
if LooseVersion(kubernetes.__version__) < LooseVersion("17.17"):
|
||||
_raise_or_fail(Exception("kubernetes >= 17.17.0 is required to use in-memory kubeconfig."), 'Failed to load kubeconfig due to: %s')
|
||||
kubernetes.config.load_kube_config_from_dict(config_dict=kubeconfig, **optional_arg)
|
||||
else:
|
||||
kubernetes.config.load_kube_config(config_file=None, **optional_arg)
|
||||
|
||||
if auth_set('host'):
|
||||
# Removing trailing slashes if any from hostname
|
||||
auth['host'] = auth.get('host').rstrip('/')
|
||||
@@ -159,7 +174,7 @@ def get_api_client(module=None, **kwargs):
|
||||
pass
|
||||
elif auth_set('kubeconfig') or auth_set('context'):
|
||||
try:
|
||||
kubernetes.config.load_kube_config(auth.get('kubeconfig'), auth.get('context'), persist_config=auth.get('persist_config'))
|
||||
_load_config()
|
||||
except Exception as err:
|
||||
_raise_or_fail(err, 'Failed to load kubeconfig due to %s')
|
||||
|
||||
@@ -169,7 +184,7 @@ def get_api_client(module=None, **kwargs):
|
||||
kubernetes.config.load_incluster_config()
|
||||
except kubernetes.config.ConfigException:
|
||||
try:
|
||||
kubernetes.config.load_kube_config(auth.get('kubeconfig'), auth.get('context'), persist_config=auth.get('persist_config'))
|
||||
_load_config()
|
||||
except Exception as err:
|
||||
_raise_or_fail(err, 'Failed to load kubeconfig due to %s')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user