6 Commits

Author SHA1 Message Date
Sergey Shubin svs1370
2c95c6ef0c Add extra checks for compute data disks management 2021-04-06 14:49:09 +03:00
Sergey Shubin svs1370
18067b82b7 Fix pool_name argument name in call to provision_disk 2021-04-06 13:32:25 +03:00
Sergey Shubin svs1370
bc317d1438 Change default pool name for disk provisioning to empty string 2021-03-29 10:14:43 +03:00
Sergey Shubin svs1370
e17c8be53a Rework conditions which cause compute_network method to fail module execution 2021-03-25 21:34:53 +03:00
Sergey Shubin svs1370
2014863c37 Fix incorrect condition when listing ext nets in compute_networks 2021-03-25 18:49:04 +03:00
Sergey Shubin svs1370
4b57777a2c Change external network list API URL to use new group extnet 2020-12-21 09:48:12 +03:00
3 changed files with 48 additions and 23 deletions

View File

@@ -1,5 +1,5 @@
# decort-ansible
Ansible modules for Digital Energy Orchestration Technology (DECORT) platform v3.4.2 and above
Ansible modules for Digital Energy Orchestration Technology (DECORT) platform v3.5.0 and above
Note that this module may produce unreliable results when used with older DECORT API versions.
@@ -9,4 +9,4 @@ Requirements:
* PyJWT Python module
* requests Python module
* netaddr Python module
* DECORT cloud platform version 3.4.2 or higher
* DECORT cloud platform version 3.5.0 or higher

View File

@@ -139,7 +139,7 @@ options:
description:
- Name of the pool where to place new disk. Once disk is created, its pool cannot be changed.
- This parameter is used when creating new disk and igonred for all other operations.
default: default
default: empty string
required: no
sep_id:
description:
@@ -209,7 +209,6 @@ EXAMPLES = '''
controller_url: "https://cloud.digitalenergy.online"
name: "MyDataDisk01"
sep_id: 1
pool: "default"
size: 50
account_name: "MyAccount"
state: present
@@ -316,7 +315,7 @@ def decort_disk_parameters():
fallback=(env_fallback, ['DECORT_PASSWORD']),
no_log=True),
place_with=dict(type='int', required=False, default=0),
pool=dict(type='str', required=False, default='default'),
pool=dict(type='str', required=False, default=''),
sep_id=dict(type='int', required=False, default=0),
size=dict(type='int', required=False),
state=dict(type='str',
@@ -402,7 +401,7 @@ def main():
disk_should_exist = False
target_sep_id = 0
target_pool = "default"
# target_pool = ""
if disk_id:
disk_should_exist = True
@@ -509,7 +508,7 @@ def main():
size=amodule.params['size'],
account_id=validated_acc_id,
sep_id=target_sep_id,
pool=amodule.params['pool'],
pool_name=amodule.params['pool'],
desc=amodule.params['annotation'],
location="")
disk_should_exist = True

View File

@@ -518,8 +518,11 @@ class DecortController(object):
#
# then all values when entering this method will be of type string. We need to
# explicitly cast int type on all of them.
for idx, repair in enumerate(new_data_disks):
new_data_disks[idx] = int(repair)
if new_data_disks is not None:
for idx, repair in enumerate(new_data_disks):
new_data_disks[idx] = int(repair)
else:
new_data_disks = []
for disk in comp_dict['disks']:
if disk['type'] == 'B':
@@ -864,19 +867,28 @@ class DecortController(object):
api_params = dict(accountId = comp_dict['accountId'])
api_resp = self.decort_api_call(requests.post, "/restmachine/cloudapi/vins/search", api_params)
vins_list = json.loads(api_resp.content.decode('utf8'))
if not len(vins_list):
self.result['failed'] = True
self.result['msg'] = ("compute_networks() cannot obtain VINS list for Account ID {}, "
"Compute ID {}.").format(comp_dict['accountId'], comp_dict['id'])
return
#
# We should not fail the module if ViNS list is empty - it is not an error, as in case of
# API failure "decort_api_call" will abort the module execution on its own. Hence the
# following code fragment is commented out
#
# if not len(vins_list):
# self.result['failed'] = True
# self.result['msg'] = ("compute_networks() cannot obtain VINS list for Account ID {}, "
# "Compute ID {}.").format(comp_dict['accountId'], comp_dict['id'])
# return
api_resp = self.decort_api_call(requests.post, "/restmachine/cloudapi/externalnetwork/list", api_params)
api_resp = self.decort_api_call(requests.post, "/restmachine/cloudapi/extnet/list", api_params)
extnet_list = json.loads(api_resp.content.decode('utf8')) # list of dicts: "name" holds "NET_ADDR/NETMASK", "id" is ID
if not len(vins_list):
self.result['failed'] = True
self.result['msg'] = ("compute_networks() cannot obtain External networks list for Account ID {}, "
"Compute ID {}.").format(comp_dict['accountId'], comp_dict['id'])
return
#
# Empty extnet_list does not constitute error condition, so we should not fail the module in
# this case. Therefore the following code fragment is commented out.
#
# if not len(extnet_list):
# self.result['failed'] = True
# self.result['msg'] = ("compute_networks() cannot obtain External networks list for Account ID {}, "
# "Compute ID {}.").format(comp_dict['accountId'], comp_dict['id'])
# return
# Prepare the lists of network interfaces for the compute instance:
vins_iface_list = [] # will contain dict(id=<int>, ipAddress=<str>, mac=<str>) for ifaces connected to ViNS(es)
@@ -902,6 +914,19 @@ class DecortController(object):
mac=iface['mac'])
enet_iface_list.append(iface_data)
# If at this point compt_dict["interfaces"] lists some interfaces, but neither vins_iface_list
# nor enet_iface_list contain any members, it means that none of the ViNS or Ext Nets currently
# available to us match existing interfaces of the Compute instance.
# This is abnormal condition and we should not proceed any further.
if len(comp_dict['interfaces']) and (not len(vins_iface_list) and not len(enet_iface_list)):
self.result['failed'] = True
self.result['msg'] = ("compute_networks() no match between {} interface(s) of Compute ID {}"
"and available {} ViNS(es) or {} ExtNet(s).").format(len(comp_dict['interfaces']),
comp_dict['id'],
len(vins_list),
len(extnet_list))
return
vins_id_list = [ rec['id'] for rec in vins_iface_list ]
enet_id_list = [ rec['id'] for rec in enet_iface_list ]
@@ -2301,7 +2326,7 @@ class DecortController(object):
return 0, None
def disk_provision(self, disk_name, size, account_id, sep_id, pool="default", desc="", location=""):
def disk_provision(self, disk_name, size, account_id, sep_id, pool_name="", desc="", location=""):
"""Provision Disk according to the specified arguments.
Note that disks created by this method will be of type 'D' (data disks).
If critical error occurs the embedded call to API function will abort further execution
@@ -2339,8 +2364,9 @@ class DecortController(object):
description=desc,
size=size,
type='D',
sep_id=sep_id,
pool=pool,)
sep_id=sep_id,)
if pool_name != "":
api_params['pool'] = pool_name
api_resp = self.decort_api_call(requests.post, "/restmachine/cloudapi/disks/create", api_params)
if api_resp.status_code == 200:
ret_disk_id = json.loads(api_resp.content.decode('utf8'))