1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00
community.general/plugins/modules/hwc_evs_disk.py
Alexei Znamensky 7e978c77b4
use dict comprehension in plugins, part 2 (#8822)
* use dict comprehension in plugins

* add changelog frag
2024-09-05 21:47:28 +02:00

1216 lines
35 KiB
Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2019 Huawei
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
###############################################################################
# Documentation
###############################################################################
DOCUMENTATION = '''
---
module: hwc_evs_disk
description:
- block storage management.
short_description: Creates a resource of Evs/Disk in Huawei Cloud
version_added: '0.2.0'
author: Huawei Inc. (@huaweicloud)
requirements:
- keystoneauth1 >= 3.6.0
attributes:
check_mode:
support: full
diff_mode:
support: none
options:
state:
description:
- Whether the given object should exist in Huaweicloud Cloud.
type: str
choices: ['present', 'absent']
default: 'present'
timeouts:
description:
- The timeouts for each operations.
type: dict
default: {}
suboptions:
create:
description:
- The timeouts for create operation.
type: str
default: '30m'
update:
description:
- The timeouts for update operation.
type: str
default: '30m'
delete:
description:
- The timeouts for delete operation.
type: str
default: '30m'
availability_zone:
description:
- Specifies the AZ where you want to create the disk.
type: str
required: true
name:
description:
- Specifies the disk name. The value can contain a maximum of 255
bytes.
type: str
required: true
volume_type:
description:
- Specifies the disk type. Currently, the value can be SSD, SAS, or
SATA.
- SSD specifies the ultra-high I/O disk type.
- SAS specifies the high I/O disk type.
- SATA specifies the common I/O disk type.
- If the specified disk type is not available in the AZ, the
disk will fail to create. If the EVS disk is created from a
snapshot, the volume_type field must be the same as that of the
snapshot's source disk.
type: str
required: true
backup_id:
description:
- Specifies the ID of the backup that can be used to create a disk.
This parameter is mandatory when you use a backup to create the
disk.
type: str
required: false
description:
description:
- Specifies the disk description. The value can contain a maximum
of 255 bytes.
type: str
required: false
enable_full_clone:
description:
- If the disk is created from a snapshot and linked cloning needs
to be used, set this parameter to True.
type: bool
required: false
enable_scsi:
description:
- If this parameter is set to True, the disk device type will be
SCSI, which allows ECS OSs to directly access underlying storage
media. SCSI reservation command is supported. If this parameter
is set to False, the disk device type will be VBD, which supports
only simple SCSI read/write commands.
- If parameter enable_share is set to True and this parameter
is not specified, shared SCSI disks are created. SCSI EVS disks
cannot be created from backups, which means that this parameter
cannot be True if backup_id has been specified.
type: bool
required: false
enable_share:
description:
- Specifies whether the disk is shareable. The default value is
False.
type: bool
required: false
encryption_id:
description:
- Specifies the encryption ID. The length of it fixes at 36 bytes.
type: str
required: false
enterprise_project_id:
description:
- Specifies the enterprise project ID. This ID is associated with
the disk during the disk creation. If it is not specified, the
disk is bound to the default enterprise project.
type: str
required: false
image_id:
description:
- Specifies the image ID. If this parameter is specified, the disk
is created from an image. BMS system disks cannot be
created from BMS images.
type: str
required: false
size:
description:
- Specifies the disk size, in GB. Its values are as follows, System
disk 1 GB to 1024 GB, Data disk 10 GB to 32768 GB. This
parameter is mandatory when you create an empty disk or use an
image or a snapshot to create a disk. If you use an image or a
snapshot to create a disk, the disk size must be greater than or
equal to the image or snapshot size. This parameter is optional
when you use a backup to create a disk. If this parameter is not
specified, the disk size is equal to the backup size.
type: int
required: false
snapshot_id:
description:
- Specifies the snapshot ID. If this parameter is specified, the
disk is created from a snapshot.
type: str
required: false
extends_documentation_fragment:
- community.general.hwc
- community.general.attributes
'''
EXAMPLES = '''
# test create disk
- name: Create a disk
community.general.hwc_evs_disk:
availability_zone: "cn-north-1a"
name: "ansible_evs_disk_test"
volume_type: "SATA"
size: 10
'''
RETURN = '''
availability_zone:
description:
- Specifies the AZ where you want to create the disk.
type: str
returned: success
name:
description:
- Specifies the disk name. The value can contain a maximum of 255
bytes.
type: str
returned: success
volume_type:
description:
- Specifies the disk type. Currently, the value can be SSD, SAS, or
SATA.
- SSD specifies the ultra-high I/O disk type.
- SAS specifies the high I/O disk type.
- SATA specifies the common I/O disk type.
- If the specified disk type is not available in the AZ, the
disk will fail to create. If the EVS disk is created from a
snapshot, the volume_type field must be the same as that of the
snapshot's source disk.
type: str
returned: success
backup_id:
description:
- Specifies the ID of the backup that can be used to create a disk.
This parameter is mandatory when you use a backup to create the
disk.
type: str
returned: success
description:
description:
- Specifies the disk description. The value can contain a maximum
of 255 bytes.
type: str
returned: success
enable_full_clone:
description:
- If the disk is created from a snapshot and linked cloning needs
to be used, set this parameter to True.
type: bool
returned: success
enable_scsi:
description:
- If this parameter is set to True, the disk device type will be
SCSI, which allows ECS OSs to directly access underlying storage
media. SCSI reservation command is supported. If this parameter
is set to False, the disk device type will be VBD, which supports
only simple SCSI read/write commands.
- If parameter enable_share is set to True and this parameter
is not specified, shared SCSI disks are created. SCSI EVS disks
cannot be created from backups, which means that this parameter
cannot be True if backup_id has been specified.
type: bool
returned: success
enable_share:
description:
- Specifies whether the disk is shareable. The default value is
False.
type: bool
returned: success
encryption_id:
description:
- Specifies the encryption ID. The length of it fixes at 36 bytes.
type: str
returned: success
enterprise_project_id:
description:
- Specifies the enterprise project ID. This ID is associated with
the disk during the disk creation. If it is not specified, the
disk is bound to the default enterprise project.
type: str
returned: success
image_id:
description:
- Specifies the image ID. If this parameter is specified, the disk
is created from an image. BMS system disks cannot be
created from BMS images.
type: str
returned: success
size:
description:
- Specifies the disk size, in GB. Its values are as follows, System
disk 1 GB to 1024 GB, Data disk 10 GB to 32768 GB. This
parameter is mandatory when you create an empty disk or use an
image or a snapshot to create a disk. If you use an image or a
snapshot to create a disk, the disk size must be greater than or
equal to the image or snapshot size. This parameter is optional
when you use a backup to create a disk. If this parameter is not
specified, the disk size is equal to the backup size.
type: int
returned: success
snapshot_id:
description:
- Specifies the snapshot ID. If this parameter is specified, the
disk is created from a snapshot.
type: str
returned: success
attachments:
description:
- Specifies the disk attachment information.
type: complex
returned: success
contains:
attached_at:
description:
- Specifies the time when the disk was attached. Time
format is 'UTC YYYY-MM-DDTHH:MM:SS'.
type: str
returned: success
attachment_id:
description:
- Specifies the ID of the attachment information.
type: str
returned: success
device:
description:
- Specifies the device name.
type: str
returned: success
server_id:
description:
- Specifies the ID of the server to which the disk is
attached.
type: str
returned: success
backup_policy_id:
description:
- Specifies the backup policy ID.
type: str
returned: success
created_at:
description:
- Specifies the time when the disk was created. Time format is 'UTC
YYYY-MM-DDTHH:MM:SS'.
type: str
returned: success
is_bootable:
description:
- Specifies whether the disk is bootable.
type: bool
returned: success
is_readonly:
description:
- Specifies whether the disk is read-only or read/write. True
indicates that the disk is read-only. False indicates that the
disk is read/write.
type: bool
returned: success
source_volume_id:
description:
- Specifies the source disk ID. This parameter has a value if the
disk is created from a source disk.
type: str
returned: success
status:
description:
- Specifies the disk status.
type: str
returned: success
tags:
description:
- Specifies the disk tags.
type: dict
returned: success
'''
from ansible_collections.community.general.plugins.module_utils.hwc_utils import (
Config, HwcClientException, HwcModule, are_different_dicts, build_path,
get_region, is_empty_value, navigate_value, wait_to_finish)
def build_module():
return HwcModule(
argument_spec=dict(
state=dict(default='present', choices=['present', 'absent'],
type='str'),
timeouts=dict(type='dict', options=dict(
create=dict(default='30m', type='str'),
update=dict(default='30m', type='str'),
delete=dict(default='30m', type='str'),
), default=dict()),
availability_zone=dict(type='str', required=True),
name=dict(type='str', required=True),
volume_type=dict(type='str', required=True),
backup_id=dict(type='str'),
description=dict(type='str'),
enable_full_clone=dict(type='bool'),
enable_scsi=dict(type='bool'),
enable_share=dict(type='bool'),
encryption_id=dict(type='str'),
enterprise_project_id=dict(type='str'),
image_id=dict(type='str'),
size=dict(type='int'),
snapshot_id=dict(type='str')
),
supports_check_mode=True,
)
def main():
"""Main function"""
module = build_module()
config = Config(module, "evs")
try:
_init(config)
is_exist = module.params.get('id')
result = None
changed = False
if module.params['state'] == 'present':
if not is_exist:
if not module.check_mode:
create(config)
changed = True
inputv = user_input_parameters(module)
resp, array_index = read_resource(config)
result = build_state(inputv, resp, array_index)
set_readonly_options(inputv, result)
if are_different_dicts(inputv, result):
if not module.check_mode:
update(config, inputv, result)
inputv = user_input_parameters(module)
resp, array_index = read_resource(config)
result = build_state(inputv, resp, array_index)
set_readonly_options(inputv, result)
if are_different_dicts(inputv, result):
raise Exception("Update resource failed, "
"some attributes are not updated")
changed = True
result['id'] = module.params.get('id')
else:
result = dict()
if is_exist:
if not module.check_mode:
delete(config)
changed = True
except Exception as ex:
module.fail_json(msg=str(ex))
else:
result['changed'] = changed
module.exit_json(**result)
def _init(config):
module = config.module
if module.params.get('id'):
return
v = search_resource(config)
n = len(v)
if n > 1:
raise Exception("find more than one resources(%s)" % ", ".join([
navigate_value(i, ["id"])
for i in v
]))
if n == 1:
module.params['id'] = navigate_value(v[0], ["id"])
def user_input_parameters(module):
return {
"availability_zone": module.params.get("availability_zone"),
"backup_id": module.params.get("backup_id"),
"description": module.params.get("description"),
"enable_full_clone": module.params.get("enable_full_clone"),
"enable_scsi": module.params.get("enable_scsi"),
"enable_share": module.params.get("enable_share"),
"encryption_id": module.params.get("encryption_id"),
"enterprise_project_id": module.params.get("enterprise_project_id"),
"image_id": module.params.get("image_id"),
"name": module.params.get("name"),
"size": module.params.get("size"),
"snapshot_id": module.params.get("snapshot_id"),
"volume_type": module.params.get("volume_type"),
}
def create(config):
module = config.module
client = config.client(get_region(module), "volumev3", "project")
timeout = 60 * int(module.params['timeouts']['create'].rstrip('m'))
opts = user_input_parameters(module)
opts["ansible_module"] = module
params = build_create_parameters(opts)
r = send_create_request(module, params, client)
client1 = config.client(get_region(module), "volume", "project")
client1.endpoint = client1.endpoint.replace("/v2/", "/v1/")
obj = async_wait(config, r, client1, timeout)
module.params['id'] = navigate_value(obj, ["entities", "volume_id"])
def update(config, expect_state, current_state):
module = config.module
expect_state["current_state"] = current_state
current_state["current_state"] = current_state
client = config.client(get_region(module), "evs", "project")
timeout = 60 * int(module.params['timeouts']['update'].rstrip('m'))
params = build_update_parameters(expect_state)
params1 = build_update_parameters(current_state)
if params and are_different_dicts(params, params1):
send_update_request(module, params, client)
params = build_extend_disk_parameters(expect_state)
params1 = build_extend_disk_parameters(current_state)
if params and are_different_dicts(params, params1):
client1 = config.client(get_region(module), "evsv2.1", "project")
r = send_extend_disk_request(module, params, client1)
client1 = config.client(get_region(module), "volume", "project")
client1.endpoint = client1.endpoint.replace("/v2/", "/v1/")
async_wait(config, r, client1, timeout)
def delete(config):
module = config.module
client = config.client(get_region(module), "evs", "project")
timeout = 60 * int(module.params['timeouts']['delete'].rstrip('m'))
r = send_delete_request(module, None, client)
client = config.client(get_region(module), "volume", "project")
client.endpoint = client.endpoint.replace("/v2/", "/v1/")
async_wait(config, r, client, timeout)
def read_resource(config):
module = config.module
client = config.client(get_region(module), "volumev3", "project")
res = {}
r = send_read_request(module, client)
res["read"] = fill_read_resp_body(r)
return res, None
def build_state(opts, response, array_index):
states = flatten_options(response, array_index)
set_unreadable_options(opts, states)
return states
def _build_query_link(opts):
query_params = []
v = navigate_value(opts, ["enable_share"])
if v or v in [False, 0]:
query_params.append(
"multiattach=" + (str(v) if v else str(v).lower()))
v = navigate_value(opts, ["name"])
if v or v in [False, 0]:
query_params.append(
"name=" + (str(v) if v else str(v).lower()))
v = navigate_value(opts, ["availability_zone"])
if v or v in [False, 0]:
query_params.append(
"availability_zone=" + (str(v) if v else str(v).lower()))
query_link = "?limit=10&offset={start}"
if query_params:
query_link += "&" + "&".join(query_params)
return query_link
def search_resource(config):
module = config.module
client = config.client(get_region(module), "volumev3", "project")
opts = user_input_parameters(module)
name = module.params.get("name")
query_link = _build_query_link(opts)
link = "os-vendor-volumes/detail" + query_link
result = []
p = {'start': 0}
while True:
url = link.format(**p)
r = send_list_request(module, client, url)
if not r:
break
for item in r:
if name == item.get("name"):
result.append(item)
if len(result) > 1:
break
p['start'] += len(r)
return result
def build_create_parameters(opts):
params = dict()
v = navigate_value(opts, ["availability_zone"], None)
if not is_empty_value(v):
params["availability_zone"] = v
v = navigate_value(opts, ["backup_id"], None)
if not is_empty_value(v):
params["backup_id"] = v
v = navigate_value(opts, ["description"], None)
if not is_empty_value(v):
params["description"] = v
v = navigate_value(opts, ["enterprise_project_id"], None)
if not is_empty_value(v):
params["enterprise_project_id"] = v
v = navigate_value(opts, ["image_id"], None)
if not is_empty_value(v):
params["imageRef"] = v
v = expand_create_metadata(opts, None)
if not is_empty_value(v):
params["metadata"] = v
v = navigate_value(opts, ["enable_share"], None)
if not is_empty_value(v):
params["multiattach"] = v
v = navigate_value(opts, ["name"], None)
if not is_empty_value(v):
params["name"] = v
v = navigate_value(opts, ["size"], None)
if not is_empty_value(v):
params["size"] = v
v = navigate_value(opts, ["snapshot_id"], None)
if not is_empty_value(v):
params["snapshot_id"] = v
v = navigate_value(opts, ["volume_type"], None)
if not is_empty_value(v):
params["volume_type"] = v
if not params:
return params
params = {"volume": params}
return params
def expand_create_metadata(d, array_index):
r = dict()
v = navigate_value(d, ["encryption_id"], array_index)
if not is_empty_value(v):
r["__system__cmkid"] = v
v = expand_create_metadata_system_encrypted(d, array_index)
if not is_empty_value(v):
r["__system__encrypted"] = v
v = expand_create_metadata_full_clone(d, array_index)
if not is_empty_value(v):
r["full_clone"] = v
v = expand_create_metadata_hw_passthrough(d, array_index)
if not is_empty_value(v):
r["hw:passthrough"] = v
return r
def expand_create_metadata_system_encrypted(d, array_index):
v = navigate_value(d, ["encryption_id"], array_index)
return "1" if v else ""
def expand_create_metadata_full_clone(d, array_index):
v = navigate_value(d, ["enable_full_clone"], array_index)
return "0" if v else ""
def expand_create_metadata_hw_passthrough(d, array_index):
v = navigate_value(d, ["enable_scsi"], array_index)
if v is None:
return v
return "true" if v else "false"
def send_create_request(module, params, client):
url = "cloudvolumes"
try:
r = client.post(url, params)
except HwcClientException as ex:
msg = ("module(hwc_evs_disk): error running "
"api(create), error: %s" % str(ex))
module.fail_json(msg=msg)
return r
def build_update_parameters(opts):
params = dict()
v = navigate_value(opts, ["description"], None)
if v is not None:
params["description"] = v
v = navigate_value(opts, ["name"], None)
if not is_empty_value(v):
params["name"] = v
if not params:
return params
params = {"volume": params}
return params
def send_update_request(module, params, client):
url = build_path(module, "cloudvolumes/{id}")
try:
r = client.put(url, params)
except HwcClientException as ex:
msg = ("module(hwc_evs_disk): error running "
"api(update), error: %s" % str(ex))
module.fail_json(msg=msg)
return r
def send_delete_request(module, params, client):
url = build_path(module, "cloudvolumes/{id}")
try:
r = client.delete(url, params)
except HwcClientException as ex:
msg = ("module(hwc_evs_disk): error running "
"api(delete), error: %s" % str(ex))
module.fail_json(msg=msg)
return r
def build_extend_disk_parameters(opts):
params = dict()
v = expand_extend_disk_os_extend(opts, None)
if not is_empty_value(v):
params["os-extend"] = v
return params
def expand_extend_disk_os_extend(d, array_index):
r = dict()
v = navigate_value(d, ["size"], array_index)
if not is_empty_value(v):
r["new_size"] = v
return r
def send_extend_disk_request(module, params, client):
url = build_path(module, "cloudvolumes/{id}/action")
try:
r = client.post(url, params)
except HwcClientException as ex:
msg = ("module(hwc_evs_disk): error running "
"api(extend_disk), error: %s" % str(ex))
module.fail_json(msg=msg)
return r
def async_wait(config, result, client, timeout):
module = config.module
path_parameters = {
"job_id": ["job_id"],
}
data = {key: navigate_value(result, path) for key, path in path_parameters.items()}
url = build_path(module, "jobs/{job_id}", data)
def _query_status():
r = None
try:
r = client.get(url, timeout=timeout)
except HwcClientException:
return None, ""
try:
s = navigate_value(r, ["status"])
return r, s
except Exception:
return None, ""
try:
return wait_to_finish(
["SUCCESS"],
["RUNNING", "INIT"],
_query_status, timeout)
except Exception as ex:
module.fail_json(msg="module(hwc_evs_disk): error "
"waiting to be done, error= %s" % str(ex))
def send_read_request(module, client):
url = build_path(module, "os-vendor-volumes/{id}")
r = None
try:
r = client.get(url)
except HwcClientException as ex:
msg = ("module(hwc_evs_disk): error running "
"api(read), error: %s" % str(ex))
module.fail_json(msg=msg)
return navigate_value(r, ["volume"], None)
def fill_read_resp_body(body):
result = dict()
v = fill_read_resp_attachments(body.get("attachments"))
result["attachments"] = v
result["availability_zone"] = body.get("availability_zone")
result["bootable"] = body.get("bootable")
result["created_at"] = body.get("created_at")
result["description"] = body.get("description")
result["enterprise_project_id"] = body.get("enterprise_project_id")
result["id"] = body.get("id")
v = fill_read_resp_metadata(body.get("metadata"))
result["metadata"] = v
result["multiattach"] = body.get("multiattach")
result["name"] = body.get("name")
result["size"] = body.get("size")
result["snapshot_id"] = body.get("snapshot_id")
result["source_volid"] = body.get("source_volid")
result["status"] = body.get("status")
result["tags"] = body.get("tags")
v = fill_read_resp_volume_image_metadata(body.get("volume_image_metadata"))
result["volume_image_metadata"] = v
result["volume_type"] = body.get("volume_type")
return result
def fill_read_resp_attachments(value):
if not value:
return None
result = []
for item in value:
val = dict()
val["attached_at"] = item.get("attached_at")
val["attachment_id"] = item.get("attachment_id")
val["device"] = item.get("device")
val["server_id"] = item.get("server_id")
result.append(val)
return result
def fill_read_resp_metadata(value):
if not value:
return None
result = dict()
result["__system__cmkid"] = value.get("__system__cmkid")
result["attached_mode"] = value.get("attached_mode")
result["full_clone"] = value.get("full_clone")
result["hw:passthrough"] = value.get("hw:passthrough")
result["policy"] = value.get("policy")
result["readonly"] = value.get("readonly")
return result
def fill_read_resp_volume_image_metadata(value):
if not value:
return None
result = dict()
result["id"] = value.get("id")
return result
def flatten_options(response, array_index):
r = dict()
v = flatten_attachments(response, array_index)
r["attachments"] = v
v = navigate_value(response, ["read", "availability_zone"], array_index)
r["availability_zone"] = v
v = navigate_value(response, ["read", "metadata", "policy"], array_index)
r["backup_policy_id"] = v
v = navigate_value(response, ["read", "created_at"], array_index)
r["created_at"] = v
v = navigate_value(response, ["read", "description"], array_index)
r["description"] = v
v = flatten_enable_full_clone(response, array_index)
r["enable_full_clone"] = v
v = flatten_enable_scsi(response, array_index)
r["enable_scsi"] = v
v = navigate_value(response, ["read", "multiattach"], array_index)
r["enable_share"] = v
v = navigate_value(
response, ["read", "metadata", "__system__cmkid"], array_index)
r["encryption_id"] = v
v = navigate_value(
response, ["read", "enterprise_project_id"], array_index)
r["enterprise_project_id"] = v
v = navigate_value(
response, ["read", "volume_image_metadata", "id"], array_index)
r["image_id"] = v
v = flatten_is_bootable(response, array_index)
r["is_bootable"] = v
v = flatten_is_readonly(response, array_index)
r["is_readonly"] = v
v = navigate_value(response, ["read", "name"], array_index)
r["name"] = v
v = navigate_value(response, ["read", "size"], array_index)
r["size"] = v
v = navigate_value(response, ["read", "snapshot_id"], array_index)
r["snapshot_id"] = v
v = navigate_value(response, ["read", "source_volid"], array_index)
r["source_volume_id"] = v
v = navigate_value(response, ["read", "status"], array_index)
r["status"] = v
v = navigate_value(response, ["read", "tags"], array_index)
r["tags"] = v
v = navigate_value(response, ["read", "volume_type"], array_index)
r["volume_type"] = v
return r
def flatten_attachments(d, array_index):
v = navigate_value(d, ["read", "attachments"],
array_index)
if not v:
return None
n = len(v)
result = []
new_ai = dict()
if array_index:
new_ai.update(array_index)
for i in range(n):
new_ai["read.attachments"] = i
val = dict()
v = navigate_value(d, ["read", "attachments", "attached_at"], new_ai)
val["attached_at"] = v
v = navigate_value(d, ["read", "attachments", "attachment_id"], new_ai)
val["attachment_id"] = v
v = navigate_value(d, ["read", "attachments", "device"], new_ai)
val["device"] = v
v = navigate_value(d, ["read", "attachments", "server_id"], new_ai)
val["server_id"] = v
for v in val.values():
if v is not None:
result.append(val)
break
return result if result else None
def flatten_enable_full_clone(d, array_index):
v = navigate_value(d, ["read", "metadata", "full_clone"],
array_index)
if v is None:
return v
return True if v == "0" else False
def flatten_enable_scsi(d, array_index):
v = navigate_value(d, ["read", "metadata", "hw:passthrough"],
array_index)
if v is None:
return v
return True if v in ["true", "True"] else False
def flatten_is_bootable(d, array_index):
v = navigate_value(d, ["read", "bootable"], array_index)
if v is None:
return v
return True if v in ["true", "True"] else False
def flatten_is_readonly(d, array_index):
v = navigate_value(d, ["read", "metadata", "readonly"],
array_index)
if v is None:
return v
return True if v in ["true", "True"] else False
def set_unreadable_options(opts, states):
states["backup_id"] = opts.get("backup_id")
def set_readonly_options(opts, states):
opts["attachments"] = states.get("attachments")
opts["backup_policy_id"] = states.get("backup_policy_id")
opts["created_at"] = states.get("created_at")
opts["is_bootable"] = states.get("is_bootable")
opts["is_readonly"] = states.get("is_readonly")
opts["source_volume_id"] = states.get("source_volume_id")
opts["status"] = states.get("status")
opts["tags"] = states.get("tags")
def send_list_request(module, client, url):
r = None
try:
r = client.get(url)
except HwcClientException as ex:
msg = ("module(hwc_evs_disk): error running "
"api(list), error: %s" % str(ex))
module.fail_json(msg=msg)
return navigate_value(r, ["volumes"], None)
def expand_list_metadata(d, array_index):
r = dict()
v = navigate_value(d, ["encryption_id"], array_index)
r["__system__cmkid"] = v
r["attached_mode"] = None
v = navigate_value(d, ["enable_full_clone"], array_index)
r["full_clone"] = v
v = navigate_value(d, ["enable_scsi"], array_index)
r["hw:passthrough"] = v
r["policy"] = None
r["readonly"] = None
for v in r.values():
if v is not None:
return r
return None
def expand_list_volume_image_metadata(d, array_index):
r = dict()
v = navigate_value(d, ["image_id"], array_index)
r["id"] = v
for v in r.values():
if v is not None:
return r
return None
def fill_list_resp_body(body):
result = dict()
v = fill_list_resp_attachments(body.get("attachments"))
result["attachments"] = v
result["availability_zone"] = body.get("availability_zone")
result["bootable"] = body.get("bootable")
result["created_at"] = body.get("created_at")
result["description"] = body.get("description")
result["enterprise_project_id"] = body.get("enterprise_project_id")
result["id"] = body.get("id")
v = fill_list_resp_metadata(body.get("metadata"))
result["metadata"] = v
result["multiattach"] = body.get("multiattach")
result["name"] = body.get("name")
result["size"] = body.get("size")
result["snapshot_id"] = body.get("snapshot_id")
result["source_volid"] = body.get("source_volid")
result["status"] = body.get("status")
result["tags"] = body.get("tags")
v = fill_list_resp_volume_image_metadata(body.get("volume_image_metadata"))
result["volume_image_metadata"] = v
result["volume_type"] = body.get("volume_type")
return result
def fill_list_resp_attachments(value):
if not value:
return None
result = []
for item in value:
val = dict()
val["attached_at"] = item.get("attached_at")
val["attachment_id"] = item.get("attachment_id")
val["device"] = item.get("device")
val["server_id"] = item.get("server_id")
result.append(val)
return result
def fill_list_resp_metadata(value):
if not value:
return None
result = dict()
result["__system__cmkid"] = value.get("__system__cmkid")
result["attached_mode"] = value.get("attached_mode")
result["full_clone"] = value.get("full_clone")
result["hw:passthrough"] = value.get("hw:passthrough")
result["policy"] = value.get("policy")
result["readonly"] = value.get("readonly")
return result
def fill_list_resp_volume_image_metadata(value):
if not value:
return None
result = dict()
result["id"] = value.get("id")
return result
if __name__ == '__main__':
main()