diff --git a/lib/ansible/module_utils/cloudscale.py b/lib/ansible/module_utils/cloudscale.py index 405933cde54..ef4eb1c5dc5 100644 --- a/lib/ansible/module_utils/cloudscale.py +++ b/lib/ansible/module_utils/cloudscale.py @@ -47,6 +47,12 @@ class AnsibleCloudscaleBase(object): '"%s".' % api_call, fetch_url_info=info) def _post_or_patch(self, api_call, method, data): + # This helps with tags when we have the full API resource href to update. + if API_URL not in api_call: + api_endpoint = API_URL + api_call + else: + api_endpoint = api_call + headers = self._auth_header.copy() if data is not None: # Sanitize data dictionary @@ -60,7 +66,7 @@ class AnsibleCloudscaleBase(object): headers['Content-type'] = 'application/json' resp, info = fetch_url(self._module, - API_URL + api_call, + api_endpoint, headers=headers, method=method, data=data, @@ -93,6 +99,31 @@ class AnsibleCloudscaleBase(object): self._module.fail_json(msg='Failure while calling the cloudscale.ch API with DELETE for ' '"%s".' % api_call, fetch_url_info=info) + def _param_updated(self, key, resource): + param = self._module.params.get(key) + if param is None: + return False + + if resource and key in resource: + if param != resource[key]: + self._result['changed'] = True + + patch_data = { + key: param + } + + self._result['diff']['before'].update({key: resource[key]}) + self._result['diff']['after'].update(patch_data) + + if not self._module.check_mode: + href = resource.get('href') + if not href: + self._module.fail_json(msg='Unable to update %s, no href found.' % key) + + self._patch(href, patch_data) + return True + return False + def get_result(self, resource): if resource: for k, v in resource.items(): diff --git a/lib/ansible/modules/cloud/cloudscale/cloudscale_server_group.py b/lib/ansible/modules/cloud/cloudscale/cloudscale_server_group.py index 832561bba17..ebbfe471479 100644 --- a/lib/ansible/modules/cloud/cloudscale/cloudscale_server_group.py +++ b/lib/ansible/modules/cloud/cloudscale/cloudscale_server_group.py @@ -44,6 +44,11 @@ options: choices: [ present, absent ] default: present type: str + tags: + description: + - Tags assosiated with the server groups. Set this to C({}) to clear any tags. + type: dict + version_added: '2.9' extends_documentation_fragment: cloudscale ''' @@ -94,6 +99,12 @@ state: returned: always type: str sample: present +tags: + description: Tags assosiated with the server group. + returned: success + type: dict + sample: { 'project': 'my project' } + version_added: '2.9' ''' from ansible.module_utils.basic import AnsibleModule @@ -119,21 +130,19 @@ class AnsibleCloudscaleServerGroup(AnsibleCloudscaleBase): data = { 'name': self._module.params.get('name'), 'type': self._module.params.get('type'), + 'tags': self._module.params.get('tags'), } if not self._module.check_mode: server_group = self._post('server-groups', data) return server_group def _update_server_group(self, server_group): - data = { - 'name': self._module.params.get('name'), - } - if server_group['name'] != data['name']: - self._result['changed'] = True + updated = self._param_updated('name', server_group) + updated = self._param_updated('tags', server_group) or updated - if not self._module.check_mode: - self._patch('server-groups/%s' % server_group['uuid'], data) - server_group = self.get_server_group() + # Refresh if resource was updated in live mode + if updated and not self._module.check_mode: + server_group = self.get_server_group() return server_group def get_server_group(self): @@ -184,6 +193,7 @@ def main(): name=dict(), uuid=dict(), type=dict(default='anti-affinity'), + tags=dict(type='dict'), state=dict(default='present', choices=['absent', 'present']), )) diff --git a/test/integration/targets/cloudscale_server_group/tasks/tests.yml b/test/integration/targets/cloudscale_server_group/tasks/tests.yml index 6cf1a252e95..c27badfcb40 100644 --- a/test/integration/targets/cloudscale_server_group/tasks/tests.yml +++ b/test/integration/targets/cloudscale_server_group/tasks/tests.yml @@ -2,6 +2,10 @@ - name: Create server group in check mode cloudscale_server_group: name: '{{ cloudscale_resource_prefix }}-grp' + tags: + project: ansible-test + stage: production + sla: 24-7 register: grp check_mode: yes - name: 'VERIFY: Create server group in check mode' @@ -14,6 +18,10 @@ - name: Create server group cloudscale_server_group: name: '{{ cloudscale_resource_prefix }}-grp' + tags: + project: ansible-test + stage: production + sla: 24-7 register: grp - name: 'VERIFY: Create server group' assert: @@ -22,6 +30,9 @@ - grp.type == 'anti-affinity' - grp.name == '{{ cloudscale_resource_prefix }}-grp' - grp.uuid + - grp.tags.project == 'ansible-test' + - grp.tags.stage == 'production' + - grp.tags.sla == '24-7' - name: Remember uuid set_fact: @@ -30,6 +41,10 @@ - name: Create server group idempotence cloudscale_server_group: name: '{{ cloudscale_resource_prefix }}-grp' + tags: + project: ansible-test + stage: production + sla: 24-7 register: grp - name: 'VERIFY: Create server group idempotence' assert: @@ -37,11 +52,18 @@ - grp is not changed - grp.name == '{{ cloudscale_resource_prefix }}-grp' - grp.uuid == server_group_uuid + - grp.tags.project == 'ansible-test' + - grp.tags.stage == 'production' + - grp.tags.sla == '24-7' - name: Update server group in check mode cloudscale_server_group: uuid: '{{ server_group_uuid }}' name: '{{ cloudscale_resource_prefix }}-grp2' + tags: + project: ansible-test + stage: staging + sla: 8-5 register: grp check_mode: yes - name: 'VERIFY: Update server group in check mode' @@ -50,11 +72,18 @@ - grp is changed - grp.name == '{{ cloudscale_resource_prefix }}-grp' - grp.uuid == server_group_uuid + - grp.tags.project == 'ansible-test' + - grp.tags.stage == 'production' + - grp.tags.sla == '24-7' - name: Update server group cloudscale_server_group: uuid: '{{ server_group_uuid }}' name: '{{ cloudscale_resource_prefix }}-grp2' + tags: + project: ansible-test + stage: staging + sla: 8-5 register: grp - name: 'VERIFY: Update server group' assert: @@ -62,11 +91,18 @@ - grp is changed - grp.name == '{{ cloudscale_resource_prefix }}-grp2' - grp.uuid == server_group_uuid + - grp.tags.project == 'ansible-test' + - grp.tags.stage == 'staging' + - grp.tags.sla == '8-5' - name: Update server group idempotence cloudscale_server_group: uuid: '{{ server_group_uuid }}' name: '{{ cloudscale_resource_prefix }}-grp2' + tags: + project: ansible-test + stage: staging + sla: 8-5 register: grp - name: 'VERIFY: Update server group idempotence' assert: @@ -74,6 +110,9 @@ - grp is not changed - grp.name == '{{ cloudscale_resource_prefix }}-grp2' - grp.uuid == server_group_uuid + - grp.tags.project == 'ansible-test' + - grp.tags.stage == 'staging' + - grp.tags.sla == '8-5' - name: Delete server group in check mode cloudscale_server_group: