mirror of
https://github.com/ansible-collections/kubernetes.core.git
synced 2026-03-31 07:43:02 +00:00
* Replace openshift client with kubernetes client This commit primarily just removes mentions of openshift from the docs and updates the requirements. Most of the work to replace the client has been done through the following commits:edc48ee577c214376cac48c51700182b6a989cf9* Add changelog fragment * Update changelogs/fragments/96-replace-openshift-client.yaml Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com> * Update plugins/modules/k8s.py Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com> * Update plugins/modules/k8s_info.py Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com> * Update plugins/modules/k8s_service.py Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com> * Bump minimum kubernetes version to 12.0.0 Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
248 lines
7.7 KiB
Python
248 lines
7.7 KiB
Python
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# (c) 2018, Chris Houseknecht <@chouseknecht>
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
|
|
|
|
__metaclass__ = type
|
|
|
|
|
|
DOCUMENTATION = r'''
|
|
|
|
module: k8s_scale
|
|
|
|
short_description: Set a new size for a Deployment, ReplicaSet, Replication Controller, or Job.
|
|
|
|
author:
|
|
- "Chris Houseknecht (@chouseknecht)"
|
|
- "Fabian von Feilitzsch (@fabianvf)"
|
|
|
|
description:
|
|
- Similar to the kubectl scale command. Use to set the number of replicas for a Deployment, ReplicaSet,
|
|
or Replication Controller, or the parallelism attribute of a Job. Supports check mode.
|
|
|
|
extends_documentation_fragment:
|
|
- kubernetes.core.k8s_name_options
|
|
- kubernetes.core.k8s_auth_options
|
|
- kubernetes.core.k8s_resource_options
|
|
- kubernetes.core.k8s_scale_options
|
|
|
|
requirements:
|
|
- "python >= 3.6"
|
|
- "kubernetes >= 12.0.0"
|
|
- "PyYAML >= 3.11"
|
|
'''
|
|
|
|
EXAMPLES = r'''
|
|
- name: Scale deployment up, and extend timeout
|
|
kubernetes.core.k8s_scale:
|
|
api_version: v1
|
|
kind: Deployment
|
|
name: elastic
|
|
namespace: myproject
|
|
replicas: 3
|
|
wait_timeout: 60
|
|
|
|
- name: Scale deployment down when current replicas match
|
|
kubernetes.core.k8s_scale:
|
|
api_version: v1
|
|
kind: Deployment
|
|
name: elastic
|
|
namespace: myproject
|
|
current_replicas: 3
|
|
replicas: 2
|
|
|
|
- name: Increase job parallelism
|
|
kubernetes.core.k8s_scale:
|
|
api_version: batch/v1
|
|
kind: job
|
|
name: pi-with-timeout
|
|
namespace: testing
|
|
replicas: 2
|
|
|
|
# Match object using local file or inline definition
|
|
|
|
- name: Scale deployment based on a file from the local filesystem
|
|
kubernetes.core.k8s_scale:
|
|
src: /myproject/elastic_deployment.yml
|
|
replicas: 3
|
|
wait: no
|
|
|
|
- name: Scale deployment based on a template output
|
|
kubernetes.core.k8s_scale:
|
|
resource_definition: "{{ lookup('template', '/myproject/elastic_deployment.yml') | from_yaml }}"
|
|
replicas: 3
|
|
wait: no
|
|
|
|
- name: Scale deployment based on a file from the Ansible controller filesystem
|
|
kubernetes.core.k8s_scale:
|
|
resource_definition: "{{ lookup('file', '/myproject/elastic_deployment.yml') | from_yaml }}"
|
|
replicas: 3
|
|
wait: no
|
|
'''
|
|
|
|
RETURN = r'''
|
|
result:
|
|
description:
|
|
- If a change was made, will return the patched object, otherwise returns the existing object.
|
|
returned: success
|
|
type: complex
|
|
contains:
|
|
api_version:
|
|
description: The versioned schema of this representation of an object.
|
|
returned: success
|
|
type: str
|
|
kind:
|
|
description: Represents the REST resource this object represents.
|
|
returned: success
|
|
type: str
|
|
metadata:
|
|
description: Standard object metadata. Includes name, namespace, annotations, labels, etc.
|
|
returned: success
|
|
type: complex
|
|
spec:
|
|
description: Specific attributes of the object. Will vary based on the I(api_version) and I(kind).
|
|
returned: success
|
|
type: complex
|
|
status:
|
|
description: Current status details for the object.
|
|
returned: success
|
|
type: complex
|
|
duration:
|
|
description: elapsed time of task in seconds
|
|
returned: when C(wait) is true
|
|
type: int
|
|
sample: 48
|
|
'''
|
|
|
|
import copy
|
|
|
|
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import AnsibleModule
|
|
from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
|
|
AUTH_ARG_SPEC, RESOURCE_ARG_SPEC, NAME_ARG_SPEC)
|
|
|
|
|
|
SCALE_ARG_SPEC = {
|
|
'replicas': {'type': 'int', 'required': True},
|
|
'current_replicas': {'type': 'int'},
|
|
'resource_version': {},
|
|
'wait': {'type': 'bool', 'default': True},
|
|
'wait_timeout': {'type': 'int', 'default': 20},
|
|
}
|
|
|
|
|
|
def execute_module(module, k8s_ansible_mixin,):
|
|
k8s_ansible_mixin.set_resource_definitions(module)
|
|
|
|
definition = k8s_ansible_mixin.resource_definitions[0]
|
|
|
|
name = definition['metadata']['name']
|
|
namespace = definition['metadata'].get('namespace')
|
|
api_version = definition['apiVersion']
|
|
kind = definition['kind']
|
|
current_replicas = module.params.get('current_replicas')
|
|
replicas = module.params.get('replicas')
|
|
resource_version = module.params.get('resource_version')
|
|
|
|
wait = module.params.get('wait')
|
|
wait_time = module.params.get('wait_timeout')
|
|
existing = None
|
|
existing_count = None
|
|
return_attributes = dict(changed=False, result=dict(), diff=dict())
|
|
if wait:
|
|
return_attributes['duration'] = 0
|
|
|
|
resource = k8s_ansible_mixin.find_resource(kind, api_version, fail=True)
|
|
|
|
from ansible_collections.kubernetes.core.plugins.module_utils.common import NotFoundError
|
|
|
|
try:
|
|
existing = resource.get(name=name, namespace=namespace)
|
|
return_attributes['result'] = existing.to_dict()
|
|
except NotFoundError as exc:
|
|
module.fail_json(msg='Failed to retrieve requested object: {0}'.format(exc),
|
|
error=exc.value.get('status'))
|
|
|
|
if module.params['kind'] == 'job':
|
|
existing_count = existing.spec.parallelism
|
|
elif hasattr(existing.spec, 'replicas'):
|
|
existing_count = existing.spec.replicas
|
|
|
|
if existing_count is None:
|
|
module.fail_json(msg='Failed to retrieve the available count for the requested object.')
|
|
|
|
if resource_version and resource_version != existing.metadata.resourceVersion:
|
|
module.exit_json(**return_attributes)
|
|
|
|
if current_replicas is not None and existing_count != current_replicas:
|
|
module.exit_json(**return_attributes)
|
|
|
|
if existing_count != replicas:
|
|
return_attributes['changed'] = True
|
|
if not module.check_mode:
|
|
if module.params['kind'] == 'job':
|
|
existing.spec.parallelism = replicas
|
|
return_attributes['result'] = resource.patch(existing.to_dict()).to_dict()
|
|
else:
|
|
return_attributes = scale(module, k8s_ansible_mixin, resource, existing, replicas, wait, wait_time)
|
|
|
|
module.exit_json(**return_attributes)
|
|
|
|
|
|
def argspec():
|
|
args = copy.deepcopy(SCALE_ARG_SPEC)
|
|
args.update(RESOURCE_ARG_SPEC)
|
|
args.update(NAME_ARG_SPEC)
|
|
args.update(AUTH_ARG_SPEC)
|
|
return args
|
|
|
|
|
|
def scale(module, k8s_ansible_mixin, resource, existing_object, replicas, wait, wait_time):
|
|
name = existing_object.metadata.name
|
|
namespace = existing_object.metadata.namespace
|
|
kind = existing_object.kind
|
|
|
|
if not hasattr(resource, 'scale'):
|
|
module.fail_json(
|
|
msg="Cannot perform scale on resource of kind {0}".format(resource.kind)
|
|
)
|
|
|
|
scale_obj = {'kind': kind, 'metadata': {'name': name, 'namespace': namespace}, 'spec': {'replicas': replicas}}
|
|
|
|
existing = resource.get(name=name, namespace=namespace)
|
|
|
|
try:
|
|
resource.scale.patch(body=scale_obj)
|
|
except Exception as exc:
|
|
module.fail_json(msg="Scale request failed: {0}".format(exc))
|
|
|
|
k8s_obj = resource.get(name=name, namespace=namespace).to_dict()
|
|
match, diffs = k8s_ansible_mixin.diff_objects(existing.to_dict(), k8s_obj)
|
|
result = dict()
|
|
result['result'] = k8s_obj
|
|
result['changed'] = not match
|
|
result['diff'] = diffs
|
|
|
|
if wait:
|
|
success, result['result'], result['duration'] = k8s_ansible_mixin.wait(resource, scale_obj, 5, wait_time)
|
|
if not success:
|
|
module.fail_json(msg="Resource scaling timed out", **result)
|
|
return result
|
|
|
|
|
|
def main():
|
|
module = AnsibleModule(argument_spec=argspec(), supports_check_mode=True)
|
|
from ansible_collections.kubernetes.core.plugins.module_utils.common import (
|
|
K8sAnsibleMixin, get_api_client)
|
|
|
|
k8s_ansible_mixin = K8sAnsibleMixin(module)
|
|
k8s_ansible_mixin.client = get_api_client(module=module)
|
|
execute_module(module, k8s_ansible_mixin)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|