Update host_aggregate to be compatible with new sdk

- Change the implementation to use the proxy layer
- Update the module to return an aggregate object
- Adds a role to test the module

Change-Id: I6a98ba8466863b41fc996855fd12cf9f3097abe0
This commit is contained in:
Rafael Castillo 2022-05-12 21:36:45 -07:00 committed by Jakob Meng
parent dee39a71b6
commit 4ea2c5b50d
5 changed files with 197 additions and 51 deletions

View File

@ -70,6 +70,7 @@
dns_zone_info
floating_ip_info
group
host_aggregate
identity_domain_info
identity_group_info
identity_role

View File

@ -0,0 +1,11 @@
expected_fields:
- availability_zone
- created_at
- deleted_at
- hosts
- id
- is_deleted
- metadata
- name
- updated_at
- uuid

View File

@ -0,0 +1,99 @@
---
- name: ensure aggregate doesn't exist before tests
openstack.cloud.host_aggregate:
cloud: "{{ cloud }}"
state: absent
name: test_aggregate
register: aggregate
- block:
- name: create aggregate
openstack.cloud.host_aggregate:
cloud: "{{ cloud }}"
state: present
name: test_aggregate
hosts:
- "{{ ansible_hostname }}"
register: aggregate
- name: assert aggregate is changed
assert:
that: aggregate is changed
- name: assert aggregate fields
assert:
that: item in aggregate.aggregate
loop: "{{ expected_fields }}"
- block:
- name: recreate aggregate
openstack.cloud.host_aggregate:
cloud: "{{ cloud }}"
state: present
name: test_aggregate
hosts:
- "{{ ansible_hostname }}"
register: aggregate
- name: assert aggregate is not changed
assert:
that: aggregate is not changed
- name: assert aggregate fields
assert:
that: item in aggregate.aggregate
loop: "{{ expected_fields }}"
- block:
- name: update aggregate
openstack.cloud.host_aggregate:
cloud: "{{ cloud }}"
state: present
name: test_aggregate
metadata:
ssd: "true"
hosts:
- "{{ ansible_hostname }}"
register: aggregate
- name: assert aggregate is changed
assert:
that: aggregate is changed
- name: assert aggregate fields
assert:
that: item in aggregate.aggregate
loop: "{{ expected_fields }}"
- block:
- name: purge hosts
openstack.cloud.host_aggregate:
cloud: "{{ cloud }}"
state: present
name: test_aggregate
hosts: []
purge_hosts: true
register: aggregate
- name: assert hosts were purged
assert:
that:
- aggregate is changed
- aggregate.aggregate.hosts | length == 0
- name: assert aggregate fields
assert:
that: item in aggregate.aggregate
loop: "{{ expected_fields }}"
- block:
- name: delete aggregate
openstack.cloud.host_aggregate:
cloud: "{{ cloud }}"
state: absent
name: test_aggregate
register: aggregate
- name: assert aggregate is changed
assert:
that: aggregate is changed

View File

@ -15,6 +15,7 @@
- role: dns
tags: dns
when: sdk_version is version(0.28, '>=')
- { role: host_aggregate, tags: host_aggregate }
- { role: floating_ip_info, tags: floating_ip_info }
- { role: identity_domain_info, tags: identity_domain_info }
- { role: identity_group_info, tags: identity_group_info }

View File

@ -73,8 +73,54 @@ EXAMPLES = '''
name: db_aggregate
'''
RETURN = '''
RETURN = r'''
aggregate:
description: A host aggregate resource.
type: dict
returned: On success, when I(state) is present
contains:
availability_zone:
description: Availability zone of the aggregate
type: str
returned: always
created_at:
description: The date and time when the resource was created
type: str
returned: always
deleted_at:
description:
- The date and time when the resource was deleted
- Null unless I(is_deleted) is true
type: str
returned: always
hosts:
description: Hosts belonging to the aggregate
type: str
returned: always
id:
description: The UUID of the aggregate.
type: str
returned: always
is_deleted:
description: Whether or not the resource is deleted
type: bool
returned: always
metadata:
description: Metadata attached to the aggregate
type: str
returned: always
name:
description: Name of the aggregate
type: str
returned: always
updated_at:
description: The date and time when the resource was updated
type: str
returned: always
uuid:
description: UUID of the aggregate
type: str
returned: always
'''
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule
@ -95,13 +141,11 @@ class ComputeHostAggregateModule(OpenStackModule):
)
def _needs_update(self, aggregate):
new_metadata = (self.params['metadata'] or {})
new_metadata = self.params['metadata'] or {}
if self.params['availability_zone'] is not None:
new_metadata['availability_zone'] = self.params['availability_zone']
if self.params['name'] != aggregate.name:
return True
if self.params['hosts'] is not None:
if self.params['purge_hosts']:
if set(self.params['hosts']) != set(aggregate.hosts):
@ -110,11 +154,10 @@ class ComputeHostAggregateModule(OpenStackModule):
intersection = set(self.params['hosts']).intersection(set(aggregate.hosts))
if set(self.params['hosts']) != intersection:
return True
if self.params['availability_zone'] is not None:
if self.params['availability_zone'] != aggregate.availability_zone:
return True
if self.params['metadata'] is not None:
if new_metadata != aggregate.metadata:
for param in ('availability_zone', 'metadata'):
if self.params[param] is not None and \
self.params[param] != aggregate[param]:
return True
return False
@ -135,16 +178,16 @@ class ComputeHostAggregateModule(OpenStackModule):
if hosts is None:
return
hosts_to_add = set(hosts) - set(aggregate.get("hosts") or [])
for i in hosts_to_add:
self.conn.add_host_to_aggregate(aggregate.id, i)
hosts_to_add = set(hosts) - set(aggregate['hosts'] or [])
for host in hosts_to_add:
self.conn.compute.add_host_to_aggregate(aggregate.id, host)
if not purge_hosts:
return
hosts_to_remove = set(aggregate.get("hosts") or []) - set(hosts)
for i in hosts_to_remove:
self.conn.remove_host_from_aggregate(aggregate.id, i)
hosts_to_remove = set(aggregate["hosts"] or []) - set(hosts)
for host in hosts_to_remove:
self.conn.compute.remove_host_from_aggregate(aggregate.id, host)
def run(self):
name = self.params['name']
@ -157,52 +200,43 @@ class ComputeHostAggregateModule(OpenStackModule):
if metadata is not None:
metadata.pop('availability_zone', None)
aggregates = self.conn.search_aggregates(name_or_id=name)
if len(aggregates) == 1:
aggregate = aggregates[0]
elif len(aggregates) == 0:
aggregate = None
else:
raise Exception("Should not happen")
aggregate = self.conn.compute.find_aggregate(name)
if self.ansible.check_mode:
self.exit_json(changed=self._system_state_change(aggregate))
changed = False
if state == 'present':
if aggregate is None:
aggregate = self.conn.create_aggregate(
aggregate = self.conn.compute.create_aggregate(
name=name, availability_zone=availability_zone)
self._update_hosts(aggregate, hosts, False)
if metadata:
self.conn.set_aggregate_metadata(aggregate.id, metadata)
self.conn.compute.set_aggregate_metadata(aggregate, metadata)
changed = True
else:
if self._needs_update(aggregate):
if availability_zone is not None:
aggregate = self.conn.update_aggregate(
aggregate.id, name=name,
availability_zone=availability_zone)
if metadata is not None:
metas = metadata
for i in (set(aggregate.metadata.keys()) - set(metadata.keys())):
if i != 'availability_zone':
metas[i] = None
self.conn.set_aggregate_metadata(aggregate.id, metas)
self._update_hosts(aggregate, hosts, purge_hosts)
changed = True
else:
changed = False
self.exit_json(changed=changed)
elif self._needs_update(aggregate):
if availability_zone is not None:
aggregate = self.conn.compute.update_aggregate(
aggregate, name=name,
availability_zone=availability_zone)
if metadata is not None:
metas = metadata
for i in set(aggregate.metadata.keys() - set(metadata.keys())):
if i != 'availability_zone':
metas[i] = None
self.conn.compute.set_aggregate_metadata(aggregate, metas)
self._update_hosts(aggregate, hosts, purge_hosts)
changed = True
aggregate = self.conn.compute.find_aggregate(name)
if aggregate:
aggregate = aggregate.to_dict(computed=False)
self.exit_json(changed=changed, aggregate=aggregate)
elif state == 'absent':
if aggregate is None:
changed = False
else:
self._update_hosts(aggregate, [], True)
self.conn.delete_aggregate(aggregate.id)
changed = True
self.exit_json(changed=changed)
elif state == 'absent' and aggregate is not None:
self._update_hosts(aggregate, [], True)
self.conn.compute.delete_aggregate(aggregate.id)
changed = True
self.exit_json(changed=changed)
def main():