Merge "Migrating volume from AnsibleModule to OpenStackModule"

This commit is contained in:
Zuul
2020-12-08 16:05:03 +00:00
committed by Gerrit Code Review

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__':