mirror of
https://github.com/ansible-collections/kubernetes.core.git
synced 2026-03-27 05:43:02 +00:00
* Rename from community.kubernetes to kubernetes.core This goes through and renames community.kubernetes to kubernetes.core. Most of this was generated from the downstream build script that was used on the community repository, plus whatever hand edits I could find that were needed. The downstream build and test process has also been removed as this repository is now the downstream repository. * Fix CONTRIBUTING.md
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 >= 2.7"
|
|
- "openshift >= 0.6"
|
|
- "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()
|