kubernetes: handle ConfigMap resources

Allow kubenetes' ConfigMap resources to be managed by salt

Signed-off-by: Flavio Castelli <fcastelli@suse.com>
This commit is contained in:
Flavio Castelli 2017-06-21 10:32:14 +02:00
parent 6e6a393c95
commit c8714a9be2
No known key found for this signature in database
GPG Key ID: F1020D69DC004F48
2 changed files with 284 additions and 0 deletions

View File

@ -297,6 +297,32 @@ def secrets(namespace='default', **kwargs):
raise CommandExecutionError(exc)
def configmaps(namespace='default', **kwargs):
'''
Return a list of kubernetes configmaps defined in the namespace
CLI Examples::
salt '*' kubernetes.configmaps
salt '*' kubernetes.configmaps namespace=default
'''
_setup_conn(**kwargs)
try:
api_instance = kubernetes.client.CoreV1Api()
api_response = api_instance.list_namespaced_config_map(namespace)
return [secret['metadata']['name'] for secret in api_response.to_dict().get('items')]
except (ApiException, HTTPError) as exc:
if isinstance(exc, ApiException) and exc.status == 404:
return None
else:
log.exception(
'Exception when calling '
'CoreV1Api->list_namespaced_config_map: {0}'.format(exc)
)
raise CommandExecutionError(exc)
def show_deployment(name, namespace='default', **kwargs):
'''
Return the kubernetes deployment defined by name and namespace
@ -434,6 +460,32 @@ def show_secret(name, namespace='default', decode=False, **kwargs):
'{0}'.format(exc)
)
raise CommandExecutionError(exc)
def show_configmap(name, namespace='default', **kwargs):
'''
Return the kubernetes configmap defined by name and namespace.
CLI Examples::
salt '*' kubernetes.show_configmap game-config default
salt '*' kubernetes.show_configmap name=game-config namespace=default
'''
_setup_conn(**kwargs)
try:
api_instance = kubernetes.client.CoreV1Api()
api_response = api_instance.read_namespaced_config_map(
name,
namespace)
return api_response.to_dict()
except (ApiException, HTTPError) as exc:
if isinstance(exc, ApiException) and exc.status == 404:
return None
else:
log.exception(
'Exception when calling '
'ExtensionsV1beta1Api->read_namespaced_config_map: '
'{0}'.format(exc)
)
raise CommandExecutionError(exc)
@ -589,6 +641,38 @@ def delete_secret(name, namespace='default', **kwargs):
raise CommandExecutionError(exc)
def delete_configmap(name, namespace='default', **kwargs):
'''
Deletes the kubernetes configmap defined by name and namespace
CLI Examples::
salt '*' kubernetes.delete_configmap settings default
salt '*' kubernetes.delete_configmap name=settings namespace=default
'''
_setup_conn(**kwargs)
body = kubernetes.client.V1DeleteOptions(orphan_dependents=True)
try:
api_instance = kubernetes.client.CoreV1Api()
api_response = api_instance.delete_namespaced_config_map(
name=name,
namespace=namespace,
body=body)
return api_response.to_dict()
except (ApiException, HTTPError) as exc:
if isinstance(exc, ApiException) and exc.status == 404:
return None
else:
log.exception(
'Exception when calling '
'CoreV1Api->delete_namespaced_config_map: '
'{0}'.format(exc)
)
raise CommandExecutionError(exc)
def create_deployment(
name,
namespace,
@ -721,6 +805,47 @@ def create_secret(
raise CommandExecutionError(exc)
def create_configmap(
name,
namespace,
data,
source,
template,
saltenv,
**kwargs):
'''
Creates the kubernetes configmap as defined by the user.
'''
if source:
data = __read_and_render_yaml_file(source, template, saltenv)
elif data is None:
data = {}
data = __enforce_only_strings_dict(data)
body = kubernetes.client.V1ConfigMap(
metadata=__dict_to_object_meta(name, namespace, {}),
data=data)
_setup_conn(**kwargs)
try:
api_instance = kubernetes.client.CoreV1Api()
api_response = api_instance.create_namespaced_config_map(
namespace, body)
return api_response.to_dict()
except (ApiException, HTTPError) as exc:
if isinstance(exc, ApiException) and exc.status == 404:
return None
else:
log.exception(
'Exception when calling '
'CoreV1Api->create_namespaced_config_map: {0}'.format(exc)
)
raise CommandExecutionError(exc)
def create_namespace(
name,
**kwargs):
@ -893,6 +1018,45 @@ def replace_secret(name,
raise CommandExecutionError(exc)
def replace_configmap(name,
data,
source,
template,
saltenv,
namespace='default',
**kwargs):
'''
Replaces an existing configmap with a new one defined by name and
namespace, having the specificed data.
'''
if source:
data = __read_and_render_yaml_file(source, template, saltenv)
data = __enforce_only_strings_dict(data)
body = kubernetes.client.V1ConfigMap(
metadata=__dict_to_object_meta(name, namespace, {}),
data=data)
_setup_conn(**kwargs)
try:
api_instance = kubernetes.client.CoreV1Api()
api_response = api_instance.replace_namespaced_config_map(
name, namespace, body)
return api_response.to_dict()
except (ApiException, HTTPError) as exc:
if isinstance(exc, ApiException) and exc.status == 404:
return None
else:
log.exception(
'Exception when calling '
'CoreV1Api->replace_namespaced_configmap: {0}'.format(exc)
)
raise CommandExecutionError(exc)
def __create_object_body(kind,
obj_class,
spec_creator,

View File

@ -571,3 +571,123 @@ def secret_present(
ret['result'] = True
return ret
def configmap_absent(name, namespace='default', **kwargs):
'''
Ensures that the named configmap is absent from the given namespace.
name
The name of the configmap
namespace
The name of the namespace
'''
ret = {'name': name,
'changes': {},
'result': False,
'comment': ''}
configmap = __salt__['kubernetes.show_configmap'](name, namespace, **kwargs)
if configmap is None:
ret['result'] = True if not __opts__['test'] else None
ret['comment'] = 'The configmap does not exist'
return ret
if __opts__['test']:
ret['comment'] = 'The configmap is going to be deleted'
ret['result'] = None
return ret
__salt__['kubernetes.delete_configmap'](name, namespace, **kwargs)
# As for kubernetes 1.6.4 doesn't set a code when deleting a configmap
# The kubernetes module will raise an exception if the kubernetes
# server will return an error
ret['result'] = True
ret['changes'] = {
'kubernetes.configmap': {
'new': 'absent', 'old': 'present'}}
ret['comment'] = 'ConfigMap deleted'
return ret
def configmap_present(
name,
namespace='default',
data=None,
source='',
template='',
**kwargs):
'''
Ensures that the named configmap is present inside of the specified namespace
with the given data.
If the configmap exists it will be replaced.
name
The name of the configmap.
namespace
The namespace holding the configmap. The 'default' one is going to be
used unless a different one is specified.
data
The dictionary holding the configmaps.
source
A file containing the data of the configmap in plain format.
template
Template engine to be used to render the source file.
'''
ret = {'name': name,
'changes': {},
'result': False,
'comment': ''}
if data and source:
return _error(
ret,
'\'source\' cannot be used in combination with \'data\''
)
configmap = __salt__['kubernetes.show_configmap'](name, namespace, **kwargs)
if configmap is None:
if __opts__['test']:
ret['result'] = None
ret['comment'] = 'The configmap is going to be created'
return ret
res = __salt__['kubernetes.create_configmap'](name=name,
namespace=namespace,
data=data,
source=source,
template=template,
saltenv=__env__,
**kwargs)
ret['changes']['{0}.{1}'.format(namespace, name)] = {
'old': {},
'new': res}
else:
if __opts__['test']:
ret['result'] = None
return ret
# TODO: improve checks # pylint: disable=fixme
log.info('Forcing the recreation of the service')
ret['comment'] = 'The configmap is already present. Forcing recreation'
res = __salt__['kubernetes.replace_configmap'](
name=name,
namespace=namespace,
data=data,
source=source,
template=template,
saltenv=__env__,
**kwargs)
ret['changes'] = {
'data': res['data']
}
ret['result'] = True
return ret