#!/usr/bin/python # Copyright (c) 2018 Catalyst IT Ltd. # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) DOCUMENTATION = ''' --- module: coe_cluster short_description: Add/Remove COE cluster from OpenStack Cloud author: OpenStack Ansible SIG description: - Add or Remove COE cluster from the OpenStack Container Infra service. options: cluster_template_id: description: - The template ID of cluster template. required: true type: str discovery_url: description: - Url used for cluster node discovery type: str docker_volume_size: description: - The size in GB of the docker volume type: int flavor_id: description: - The flavor of the minion node for this ClusterTemplate type: str keypair: description: - Name of the keypair to use. type: str labels: description: - One or more key/value pairs type: raw master_flavor_id: description: - The flavor of the master node for this ClusterTemplate type: str master_count: description: - The number of master nodes for this cluster default: 1 type: int name: description: - Name that has to be given to the cluster template required: true type: str node_count: description: - The number of nodes for this cluster default: 1 type: int state: description: - Indicate desired state of the resource. choices: [present, absent] default: present type: str timeout: description: - Timeout for creating the cluster in minutes. Default to 60 mins if not set default: 60 type: int requirements: - "python >= 3.6" - "openstacksdk" extends_documentation_fragment: - openstack.cloud.openstack ''' RETURN = ''' id: description: The cluster UUID. returned: On success when I(state) is 'present' type: str sample: "39007a7e-ee4f-4d13-8283-b4da2e037c69" cluster: description: Dictionary describing the cluster. returned: On success when I(state) is 'present' type: complex contains: api_address: description: - Api address of cluster master node type: str sample: https://172.24.4.30:6443 cluster_template_id: description: The cluster_template UUID type: str sample: '7b1418c8-cea8-48fc-995d-52b66af9a9aa' coe_version: description: - Version of the COE software currently running in this cluster type: str sample: v1.11.1 container_version: description: - "Version of the container software. Example: docker version." type: str sample: 1.12.6 created_at: description: - The time in UTC at which the cluster is created type: str sample: "2018-08-16T10:29:45+00:00" create_timeout: description: - Timeout for creating the cluster in minutes. Default to 60 if not set. type: int sample: 60 discovery_url: description: - Url used for cluster node discovery type: str sample: https://discovery.etcd.io/a42ee38e7113f31f4d6324f24367aae5 faults: description: - Fault info collected from the Heat resources of this cluster type: dict sample: {'0': 'ResourceInError: resources[0].resources...'} flavor_id: description: - The flavor of the minion node for this cluster type: str sample: c1.c1r1 keypair: description: - Name of the keypair to use. type: str sample: mykey labels: description: One or more key/value pairs type: dict sample: {'key1': 'value1', 'key2': 'value2'} master_addresses: description: - IP addresses of cluster master nodes type: list sample: ['172.24.4.5'] master_count: description: - The number of master nodes for this cluster. type: int sample: 1 master_flavor_id: description: - The flavor of the master node for this cluster type: str sample: c1.c1r1 name: description: - Name that has to be given to the cluster type: str sample: k8scluster node_addresses: description: - IP addresses of cluster slave nodes type: list sample: ['172.24.4.8'] node_count: description: - The number of master nodes for this cluster. type: int sample: 1 stack_id: description: - Stack id of the Heat stack type: str sample: '07767ec6-85f5-44cb-bd63-242a8e7f0d9d' status: description: Status of the cluster from the heat stack type: str sample: 'CREATE_COMLETE' status_reason: description: - Status reason of the cluster from the heat stack type: str sample: 'Stack CREATE completed successfully' updated_at: description: - The time in UTC at which the cluster is updated type: str sample: '2018-08-16T10:39:25+00:00' id: description: - Unique UUID for this cluster type: str sample: '86246a4d-a16c-4a58-9e96ad7719fe0f9d' ''' EXAMPLES = ''' # Create a new Kubernetes cluster - openstack.cloud.coe_cluster: name: k8s cluster_template_id: k8s-ha keypair: mykey master_count: 3 node_count: 5 ''' from ansible.module_utils.basic import AnsibleModule from ansible_collections.openstack.cloud.plugins.module_utils.openstack import (openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module) def _parse_labels(labels): if isinstance(labels, str): labels_dict = {} for kv_str in labels.split(","): k, v = kv_str.split("=") labels_dict[k] = v return labels_dict if not labels: return {} return labels def main(): argument_spec = openstack_full_argument_spec( cluster_template_id=dict(required=True), discovery_url=dict(default=None), docker_volume_size=dict(type='int'), flavor_id=dict(default=None), keypair=dict(default=None), labels=dict(default=None, type='raw'), master_count=dict(type='int', default=1), master_flavor_id=dict(default=None), name=dict(required=True), node_count=dict(type='int', default=1), state=dict(default='present', choices=['absent', 'present']), timeout=dict(type='int', default=60), ) module_kwargs = openstack_module_kwargs() module = AnsibleModule(argument_spec, **module_kwargs) params = module.params.copy() state = module.params['state'] name = module.params['name'] cluster_template_id = module.params['cluster_template_id'] kwargs = dict( discovery_url=module.params['discovery_url'], docker_volume_size=module.params['docker_volume_size'], flavor_id=module.params['flavor_id'], keypair=module.params['keypair'], labels=_parse_labels(params['labels']), master_count=module.params['master_count'], master_flavor_id=module.params['master_flavor_id'], node_count=module.params['node_count'], create_timeout=module.params['timeout'], ) sdk, cloud = openstack_cloud_from_module(module) try: changed = False cluster = cloud.get_coe_cluster(name_or_id=name, filters={'cluster_template_id': cluster_template_id}) if state == 'present': if not cluster: cluster = cloud.create_coe_cluster(name, cluster_template_id=cluster_template_id, **kwargs) changed = True else: changed = False # NOTE (brtknr): At present, create_coe_cluster request returns # cluster_id as `uuid` whereas get_coe_cluster request returns the # same field as `id`. This behaviour may change in the future # therefore try `id` first then `uuid`. cluster_id = cluster.get('id', cluster.get('uuid')) cluster['id'] = cluster['uuid'] = cluster_id module.exit_json(changed=changed, cluster=cluster, id=cluster_id) elif state == 'absent': if not cluster: module.exit_json(changed=False) else: cloud.delete_coe_cluster(name) module.exit_json(changed=True) except sdk.exceptions.OpenStackCloudException as e: module.fail_json(msg=str(e), extra_data=e.extra_data) if __name__ == "__main__": main()