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