
Collections are new. openstacksdk as of now doesn't support python2. We shouldn't pretend to support python2 either. If you're using ansible new enough to use collections, you can use python3. This release of openstacksdk only supports 3.6 and onwards, so set that as our min. Change-Id: I34d544ce48f25bffde8e6e0cf82cdf9a85e681c3
179 lines
5.7 KiB
Python
179 lines
5.7 KiB
Python
#!/usr/bin/python
|
|
# coding: utf-8 -*-
|
|
|
|
# Copyright (c) 2016, Mario Santos <mario.rf.santos@gmail.com>
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
|
|
ANSIBLE_METADATA = {'status': ['preview'],
|
|
'supported_by': 'community',
|
|
'metadata_version': '1.1'}
|
|
|
|
DOCUMENTATION = '''
|
|
---
|
|
module: os_volume_snapshot
|
|
short_description: Create/Delete Cinder Volume Snapshots
|
|
author: "Mario Santos (@ruizink)"
|
|
description:
|
|
- Create or Delete cinder block storage volume snapshots
|
|
options:
|
|
display_name:
|
|
description:
|
|
- Name of the snapshot
|
|
required: true
|
|
aliases: ['name']
|
|
display_description:
|
|
description:
|
|
- String describing the snapshot
|
|
aliases: ['description']
|
|
volume:
|
|
description:
|
|
- The volume name or id to create/delete the snapshot
|
|
required: True
|
|
force:
|
|
description:
|
|
- Allows or disallows snapshot of a volume to be created when the volume
|
|
is attached to an instance.
|
|
type: bool
|
|
default: 'no'
|
|
state:
|
|
description:
|
|
- Should the resource be present or absent.
|
|
choices: [present, absent]
|
|
default: present
|
|
availability_zone:
|
|
description:
|
|
- Availability zone in which to create the snapshot.
|
|
requirements:
|
|
- "python >= 3.6""
|
|
- "openstacksdk"
|
|
|
|
extends_documentation_fragment:
|
|
- openstack.cloud.openstack
|
|
'''
|
|
|
|
EXAMPLES = '''
|
|
# Creates a snapshot on volume 'test_volume'
|
|
- name: create and delete snapshot
|
|
hosts: localhost
|
|
tasks:
|
|
- name: create snapshot
|
|
os_volume_snapshot:
|
|
state: present
|
|
cloud: mordred
|
|
availability_zone: az2
|
|
display_name: test_snapshot
|
|
volume: test_volume
|
|
- name: delete snapshot
|
|
os_volume_snapshot:
|
|
state: absent
|
|
cloud: mordred
|
|
availability_zone: az2
|
|
display_name: test_snapshot
|
|
volume: test_volume
|
|
'''
|
|
|
|
RETURN = '''
|
|
snapshot:
|
|
description: The snapshot instance after the change
|
|
returned: success
|
|
type: dict
|
|
sample:
|
|
id: 837aca54-c0ee-47a2-bf9a-35e1b4fdac0c
|
|
name: test_snapshot
|
|
volume_id: ec646a7c-6a35-4857-b38b-808105a24be6
|
|
size: 2
|
|
status: available
|
|
display_name: test_snapshot
|
|
'''
|
|
|
|
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,
|
|
)
|
|
|
|
|
|
def _present_volume_snapshot(module, cloud):
|
|
volume = cloud.get_volume(module.params['volume'])
|
|
snapshot = cloud.get_volume_snapshot(module.params['display_name'],
|
|
filters={'volume_id': volume.id})
|
|
if not snapshot:
|
|
snapshot = cloud.create_volume_snapshot(volume.id,
|
|
force=module.params['force'],
|
|
wait=module.params['wait'],
|
|
timeout=module.params[
|
|
'timeout'],
|
|
name=module.params['display_name'],
|
|
description=module.params.get(
|
|
'display_description')
|
|
)
|
|
module.exit_json(changed=True, snapshot=snapshot)
|
|
else:
|
|
module.exit_json(changed=False, snapshot=snapshot)
|
|
|
|
|
|
def _absent_volume_snapshot(module, cloud):
|
|
volume = cloud.get_volume(module.params['volume'])
|
|
snapshot = cloud.get_volume_snapshot(module.params['display_name'],
|
|
filters={'volume_id': volume.id})
|
|
if not snapshot:
|
|
module.exit_json(changed=False)
|
|
else:
|
|
cloud.delete_volume_snapshot(name_or_id=snapshot.id,
|
|
wait=module.params['wait'],
|
|
timeout=module.params['timeout'],
|
|
)
|
|
module.exit_json(changed=True, snapshot_id=snapshot.id)
|
|
|
|
|
|
def _system_state_change(module, cloud):
|
|
volume = cloud.get_volume(module.params['volume'])
|
|
snapshot = cloud.get_volume_snapshot(module.params['display_name'],
|
|
filters={'volume_id': volume.id})
|
|
state = module.params['state']
|
|
|
|
if state == 'present':
|
|
return snapshot is None
|
|
if state == 'absent':
|
|
return snapshot is not None
|
|
|
|
|
|
def main():
|
|
argument_spec = openstack_full_argument_spec(
|
|
display_name=dict(required=True, aliases=['name']),
|
|
display_description=dict(default=None, aliases=['description']),
|
|
volume=dict(required=True),
|
|
force=dict(required=False, default=False, type='bool'),
|
|
state=dict(default='present', choices=['absent', 'present']),
|
|
)
|
|
|
|
module_kwargs = openstack_module_kwargs()
|
|
module = AnsibleModule(argument_spec,
|
|
supports_check_mode=True,
|
|
**module_kwargs)
|
|
|
|
sdk, cloud = openstack_cloud_from_module(module)
|
|
|
|
state = module.params['state']
|
|
|
|
try:
|
|
if cloud.volume_exists(module.params['volume']):
|
|
if module.check_mode:
|
|
module.exit_json(changed=_system_state_change(module, cloud))
|
|
if state == 'present':
|
|
_present_volume_snapshot(module, cloud)
|
|
if state == 'absent':
|
|
_absent_volume_snapshot(module, cloud)
|
|
else:
|
|
module.fail_json(
|
|
msg="No volume with name or id '{0}' was found.".format(
|
|
module.params['volume']))
|
|
except (sdk.exceptions.OpenStackCloudException, sdk.exceptions.ResourceTimeout) as e:
|
|
module.fail_json(msg=e.message)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|