Migrating volume from AnsibleModule to OpenStackModule

A bit restructed structure so decision logic whether volume will be created or updated is now in run method

Change-Id: I83e03787b3cea65f07dc83764743702d59e8656d
This commit is contained in:
Vladimir Hasko 2020-12-04 14:14:30 +00:00
parent d5c403cded
commit faada98ed9

View File

@ -99,13 +99,35 @@ volume:
type: dict
sample: {'...'}
'''
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)
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule
def _needs_update(module, volume):
class VolumeModule(OpenStackModule):
argument_spec = dict(
size=dict(type='int'),
volume_type=dict(type='str'),
display_name=dict(required=True, aliases=['name'], type='str'),
display_description=dict(aliases=['description'], type='str'),
image=dict(type='str'),
snapshot_id=dict(type='str'),
volume=dict(type='str'),
state=dict(default='present', choices=['absent', 'present'], type='str'),
scheduler_hints=dict(type='dict'),
metadata=dict(type='dict'),
bootable=dict(type='bool', default=False)
)
module_kwargs = dict(
mutually_exclusive=[
['image', 'snapshot_id', 'volume'],
],
required_if=[
['state', 'present', ['size']],
],
)
def _needs_update(self, volume):
'''
check for differences in updatable values, at the moment
openstacksdk only supports extending the volume size, this
@ -115,145 +137,124 @@ def _needs_update(module, volume):
compare_simple = ['size']
for k in compare_simple:
if module.params[k] is not None and module.params[k] != volume.get(k):
if self.params[k] is not None and self.params[k] != volume.get(k):
return True
return False
def _modify_volume(module, cloud):
def _modify_volume(self, volume):
'''
modify volume, the only modification to an existing volume
available at the moment is extending the size, this is
limited by the openstacksdk and may change whenever the
functionality is extended.
'''
volume = cloud.get_volume(module.params['display_name'])
volume = self.conn.get_volume(self.params['display_name'])
diff = {'before': volume, 'after': ''}
size = module.params['size']
size = self.params['size']
if size < volume.get('size'):
module.fail_json(
self.fail_json(
msg='Cannot shrink volumes, size: {0} < {1}'.format(size, volume.get('size'))
)
if not _needs_update(module, volume):
if not self._needs_update(volume):
diff['after'] = volume
module.exit_json(changed=False, id=volume['id'], volume=volume, diff=diff)
self.exit_json(changed=False, id=volume['id'], volume=volume, diff=diff)
if module.check_mode:
if self.ansible.check_mode:
diff['after'] = volume
module.exit_json(changed=True, id=volume['id'], volume=volume, diff=diff)
self.exit_json(changed=True, id=volume['id'], volume=volume, diff=diff)
cloud.volume.extend_volume(
self.conn.volume.extend_volume(
volume.id,
size
)
diff['after'] = cloud.get_volume(module.params['display_name'])
module.exit_json(changed=True, id=volume['id'], volume=volume, diff=diff)
diff['after'] = self.conn.get_volume(self.params['display_name'])
self.exit_json(changed=True, id=volume['id'], volume=volume, diff=diff)
def _present_volume(module, cloud):
if cloud.volume_exists(module.params['display_name']):
v = cloud.get_volume(module.params['display_name'])
if not _needs_update(module, v):
module.exit_json(changed=False, id=v['id'], volume=v)
_modify_volume(module, cloud)
def _present_volume(self):
diff = {'before': '', 'after': ''}
volume_args = dict(
size=module.params['size'],
volume_type=module.params['volume_type'],
display_name=module.params['display_name'],
display_description=module.params['display_description'],
snapshot_id=module.params['snapshot_id'],
bootable=module.params['bootable'],
availability_zone=module.params['availability_zone'],
size=self.params['size'],
volume_type=self.params['volume_type'],
display_name=self.params['display_name'],
display_description=self.params['display_description'],
snapshot_id=self.params['snapshot_id'],
bootable=self.params['bootable'],
availability_zone=self.params['availability_zone'],
)
if module.params['image']:
image_id = cloud.get_image_id(module.params['image'])
if self.params['image']:
image_id = self.conn.get_image_id(self.params['image'])
volume_args['imageRef'] = image_id
if module.params['volume']:
volume_id = cloud.get_volume_id(module.params['volume'])
if self.params['volume']:
volume_id = self.conn.get_volume_id(self.params['volume'])
if not volume_id:
module.fail_json(msg="Failed to find volume '%s'" % module.params['volume'])
self.fail_json(msg="Failed to find volume '%s'" % self.params['volume'])
volume_args['source_volid'] = volume_id
if module.params['scheduler_hints']:
volume_args['scheduler_hints'] = module.params['scheduler_hints']
if self.params['scheduler_hints']:
volume_args['scheduler_hints'] = self.params['scheduler_hints']
if module.params['metadata']:
volume_args['metadata'] = module.params['metadata']
if self.params['metadata']:
volume_args['metadata'] = self.params['metadata']
if module.check_mode:
if self.ansible.check_mode:
diff['after'] = volume_args
module.exit_json(changed=True, id=None, volume=volume_args, diff=diff)
self.exit_json(changed=True, id=None, volume=volume_args, diff=diff)
volume = cloud.create_volume(
wait=module.params['wait'], timeout=module.params['timeout'],
volume = self.conn.create_volume(
wait=self.params['wait'], timeout=self.params['timeout'],
**volume_args)
diff['after'] = volume
module.exit_json(changed=True, id=volume['id'], volume=volume, diff=diff)
self.exit_json(changed=True, id=volume['id'], volume=volume, diff=diff)
def _absent_volume(module, cloud, sdk):
def _absent_volume(self, volume):
changed = False
diff = {'before': '', 'after': ''}
if cloud.volume_exists(module.params['display_name']):
volume = cloud.get_volume(module.params['display_name'])
if self.conn.volume_exists(self.params['display_name']):
volume = self.conn.get_volume(self.params['display_name'])
diff['before'] = volume
if module.check_mode:
module.exit_json(changed=True, diff=diff)
if self.ansible.check_mode:
self.exit_json(changed=True, diff=diff)
try:
changed = cloud.delete_volume(name_or_id=module.params['display_name'],
wait=module.params['wait'],
timeout=module.params['timeout'])
except sdk.exceptions.ResourceTimeout:
changed = self.conn.delete_volume(name_or_id=self.params['display_name'],
wait=self.params['wait'],
timeout=self.params['timeout'])
except self.sdk.exceptions.ResourceTimeout:
diff['after'] = volume
module.exit_json(changed=changed, diff=diff)
self.exit_json(changed=changed, diff=diff)
module.exit_json(changed=changed, diff=diff)
self.exit_json(changed=changed, diff=diff)
def run(self):
state = self.params['state']
if self.conn.volume_exists(self.params['display_name']):
volume = self.conn.get_volume(self.params['display_name'])
else:
volume = None
if state == 'present':
if not volume:
self._present_volume()
elif self._needs_update(volume):
self._modify_volume(volume)
else:
self.exit_json(changed=False, id=volume['id'], volume=volume)
if state == 'absent':
self._absent_volume(volume)
def main():
argument_spec = openstack_full_argument_spec(
size=dict(default=None, type='int'),
volume_type=dict(default=None),
display_name=dict(required=True, aliases=['name']),
display_description=dict(default=None, aliases=['description']),
image=dict(default=None),
snapshot_id=dict(default=None),
volume=dict(default=None),
state=dict(default='present', choices=['absent', 'present']),
scheduler_hints=dict(default=None, type='dict'),
metadata=dict(default=None, type='dict'),
bootable=dict(type='bool', default=False)
)
module_kwargs = openstack_module_kwargs(
mutually_exclusive=[
['image', 'snapshot_id', 'volume'],
],
)
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True, **module_kwargs)
state = module.params['state']
if state == 'present' and not module.params['size']:
module.fail_json(msg="Size is required when state is 'present'")
sdk, cloud = openstack_cloud_from_module(module)
try:
if state == 'present':
_present_volume(module, cloud)
if state == 'absent':
_absent_volume(module, cloud, sdk)
except sdk.exceptions.OpenStackCloudException as e:
module.fail_json(msg=str(e))
module = VolumeModule()
module()
if __name__ == '__main__':