|
|
|
|
@ -109,7 +109,7 @@ from traceback import format_exc
|
|
|
|
|
|
|
|
|
|
from ansible.module_utils.basic import AnsibleModule
|
|
|
|
|
from ansible.module_utils.netapp import request, eseries_host_argument_spec
|
|
|
|
|
from ansible.module_utils.pycompat24 import get_exception
|
|
|
|
|
from ansible.module_utils._text import to_native
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def select(predicate, iterable):
|
|
|
|
|
@ -380,17 +380,15 @@ class NetAppESeriesStoragePool(object):
|
|
|
|
|
(rc, resp) = request(self.api_url + "/storage-systems/%s/storage-pools" % (self.ssid),
|
|
|
|
|
headers=dict(Accept="application/json"), url_username=self.api_usr,
|
|
|
|
|
url_password=self.api_pwd, validate_certs=self.validate_certs)
|
|
|
|
|
except Exception:
|
|
|
|
|
err = get_exception()
|
|
|
|
|
except Exception as err:
|
|
|
|
|
rc = err.args[0]
|
|
|
|
|
if rc == 404 and self.state == 'absent':
|
|
|
|
|
self.module.exit_json(
|
|
|
|
|
msg="Storage pool [%s] did not exist." % (self.name))
|
|
|
|
|
else:
|
|
|
|
|
err = get_exception()
|
|
|
|
|
self.module.exit_json(
|
|
|
|
|
msg="Failed to get storage pools. Array id [%s]. Error[%s]. State[%s]. RC[%s]." %
|
|
|
|
|
(self.ssid, str(err), self.state, rc))
|
|
|
|
|
(self.ssid, to_native(err), self.state, rc))
|
|
|
|
|
|
|
|
|
|
self.debug("searching for storage pool '%s'", storage_pool_name)
|
|
|
|
|
|
|
|
|
|
@ -435,10 +433,9 @@ class NetAppESeriesStoragePool(object):
|
|
|
|
|
(rc, drives_resp) = request(self.api_url + "/storage-systems/%s/drives" % (self.ssid), method='GET',
|
|
|
|
|
url_username=self.api_usr, url_password=self.api_pwd,
|
|
|
|
|
validate_certs=self.validate_certs)
|
|
|
|
|
except:
|
|
|
|
|
err = get_exception()
|
|
|
|
|
except Exception as err:
|
|
|
|
|
self.module.exit_json(
|
|
|
|
|
msg="Failed to fetch disk drives. Array id [%s]. Error[%s]." % (self.ssid, str(err)))
|
|
|
|
|
msg="Failed to fetch disk drives. Array id [%s]. Error[%s]." % (self.ssid, to_native(err)))
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
candidate_set = self.filter_drives(drives_resp,
|
|
|
|
|
@ -451,10 +448,9 @@ class NetAppESeriesStoragePool(object):
|
|
|
|
|
interface_type=self.criteria_drive_interface_type,
|
|
|
|
|
fde_required=self.criteria_drive_require_fde
|
|
|
|
|
)
|
|
|
|
|
except:
|
|
|
|
|
err = get_exception()
|
|
|
|
|
except Exception as err:
|
|
|
|
|
self.module.fail_json(
|
|
|
|
|
msg="Failed to allocate adequate drive count. Id [%s]. Error [%s]." % (self.ssid, str(err)))
|
|
|
|
|
msg="Failed to allocate adequate drive count. Id [%s]. Error [%s]." % (self.ssid, to_native(err)))
|
|
|
|
|
|
|
|
|
|
disk_ids = [d['id'] for d in candidate_set]
|
|
|
|
|
|
|
|
|
|
@ -478,13 +474,12 @@ class NetAppESeriesStoragePool(object):
|
|
|
|
|
url_username=self.api_usr, url_password=self.api_pwd,
|
|
|
|
|
validate_certs=self.validate_certs,
|
|
|
|
|
timeout=120)
|
|
|
|
|
except:
|
|
|
|
|
err = get_exception()
|
|
|
|
|
except Exception as err:
|
|
|
|
|
pool_id = self.pool_detail['id']
|
|
|
|
|
self.module.exit_json(
|
|
|
|
|
msg="Failed to create storage pool. Pool id [%s]. Array id [%s]. Error[%s]." % (pool_id,
|
|
|
|
|
self.ssid,
|
|
|
|
|
str(err)))
|
|
|
|
|
to_native(err)))
|
|
|
|
|
|
|
|
|
|
self.pool_detail = self.get_storage_pool(self.name)
|
|
|
|
|
|
|
|
|
|
@ -496,13 +491,12 @@ class NetAppESeriesStoragePool(object):
|
|
|
|
|
data=json.dumps(secure_pool_data), headers=self.post_headers, method='POST',
|
|
|
|
|
url_username=self.api_usr,
|
|
|
|
|
url_password=self.api_pwd, validate_certs=self.validate_certs, timeout=120, ignore_errors=True)
|
|
|
|
|
except:
|
|
|
|
|
err = get_exception()
|
|
|
|
|
except Exception as err:
|
|
|
|
|
pool_id = self.pool_detail['id']
|
|
|
|
|
self.module.exit_json(
|
|
|
|
|
msg="Failed to update storage pool. Pool id [%s]. Array id [%s]. Error[%s]." % (pool_id,
|
|
|
|
|
self.ssid,
|
|
|
|
|
str(err)))
|
|
|
|
|
to_native(err)))
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def needs_raid_level_migration(self):
|
|
|
|
|
@ -527,12 +521,11 @@ class NetAppESeriesStoragePool(object):
|
|
|
|
|
data=json.dumps(sp_raid_migrate_req), headers=self.post_headers, method='POST',
|
|
|
|
|
url_username=self.api_usr,
|
|
|
|
|
url_password=self.api_pwd, validate_certs=self.validate_certs, timeout=120)
|
|
|
|
|
except:
|
|
|
|
|
err = get_exception()
|
|
|
|
|
except Exception as err:
|
|
|
|
|
pool_id = self.pool_detail['id']
|
|
|
|
|
self.module.exit_json(
|
|
|
|
|
msg="Failed to change the raid level of storage pool. Pool id [%s]. Array id [%s]. Error[%s]." % (
|
|
|
|
|
pool_id, self.ssid, str(err)))
|
|
|
|
|
pool_id, self.ssid, to_native(err)))
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def sp_drives(self, exclude_hotspares=True):
|
|
|
|
|
@ -543,11 +536,10 @@ class NetAppESeriesStoragePool(object):
|
|
|
|
|
(rc, resp) = request(self.api_url + "/storage-systems/%s/drives" % (self.ssid), method='GET',
|
|
|
|
|
url_username=self.api_usr, url_password=self.api_pwd,
|
|
|
|
|
validate_certs=self.validate_certs)
|
|
|
|
|
except:
|
|
|
|
|
err = get_exception()
|
|
|
|
|
except Exception as err:
|
|
|
|
|
pool_id = self.pool_detail['id']
|
|
|
|
|
self.module.exit_json(
|
|
|
|
|
msg="Failed to fetch disk drives. Pool id [%s]. Array id [%s]. Error[%s]." % (pool_id, self.ssid, str(err)))
|
|
|
|
|
msg="Failed to fetch disk drives. Pool id [%s]. Array id [%s]. Error[%s]." % (pool_id, self.ssid, to_native(err)))
|
|
|
|
|
|
|
|
|
|
sp_id = self.pool_detail['id']
|
|
|
|
|
if exclude_hotspares:
|
|
|
|
|
@ -586,12 +578,11 @@ class NetAppESeriesStoragePool(object):
|
|
|
|
|
self.pool_detail['id']),
|
|
|
|
|
method='GET', url_username=self.api_usr, url_password=self.api_pwd, validate_certs=self.validate_certs,
|
|
|
|
|
timeout=120)
|
|
|
|
|
except:
|
|
|
|
|
err = get_exception()
|
|
|
|
|
except Exception as err:
|
|
|
|
|
pool_id = self.pool_detail['id']
|
|
|
|
|
self.module.exit_json(
|
|
|
|
|
msg="Failed to fetch candidate drives for storage pool. Pool id [%s]. Array id [%s]. Error[%s]." % (
|
|
|
|
|
pool_id, self.ssid, str(err)))
|
|
|
|
|
pool_id, self.ssid, to_native(err)))
|
|
|
|
|
|
|
|
|
|
current_drive_count = len(self.sp_drives)
|
|
|
|
|
current_capacity_bytes = int(self.pool_detail['totalRaidedSpace']) # TODO: is this the right attribute to use?
|
|
|
|
|
@ -649,14 +640,12 @@ class NetAppESeriesStoragePool(object):
|
|
|
|
|
self.pool_detail['id']),
|
|
|
|
|
data=json.dumps(sp_expand_req), headers=self.post_headers, method='POST', url_username=self.api_usr,
|
|
|
|
|
url_password=self.api_pwd, validate_certs=self.validate_certs, timeout=120)
|
|
|
|
|
except:
|
|
|
|
|
err = get_exception()
|
|
|
|
|
except Exception as err:
|
|
|
|
|
pool_id = self.pool_detail['id']
|
|
|
|
|
self.module.exit_json(
|
|
|
|
|
msg="Failed to add drives to storage pool. Pool id [%s]. Array id [%s]. Error[%s]." % (pool_id,
|
|
|
|
|
self.ssid,
|
|
|
|
|
str(
|
|
|
|
|
err)))
|
|
|
|
|
to_native(err)))
|
|
|
|
|
|
|
|
|
|
# TODO: check response
|
|
|
|
|
# TODO: support blocking wait?
|
|
|
|
|
@ -675,12 +664,11 @@ class NetAppESeriesStoragePool(object):
|
|
|
|
|
self.pool_detail['id']),
|
|
|
|
|
data=json.dumps(drive_list), headers=self.post_headers, method='POST', url_username=self.api_usr,
|
|
|
|
|
url_password=self.api_pwd, validate_certs=self.validate_certs, timeout=120)
|
|
|
|
|
except:
|
|
|
|
|
err = get_exception()
|
|
|
|
|
except Exception as err:
|
|
|
|
|
pool_id = self.pool_detail['id']
|
|
|
|
|
self.module.exit_json(
|
|
|
|
|
msg="Failed to remove drives from storage pool. Pool id [%s]. Array id [%s]. Error[%s]." % (
|
|
|
|
|
pool_id, self.ssid, str(err)))
|
|
|
|
|
pool_id, self.ssid, to_native(err)))
|
|
|
|
|
|
|
|
|
|
def update_reserve_drive_count(self, qty):
|
|
|
|
|
data = dict(reservedDriveCount=qty)
|
|
|
|
|
@ -689,14 +677,12 @@ class NetAppESeriesStoragePool(object):
|
|
|
|
|
self.api_url + "/storage-systems/%s/storage-pools/%s" % (self.ssid, self.pool_detail['id']),
|
|
|
|
|
data=json.dumps(data), headers=self.post_headers, method='POST', url_username=self.api_usr,
|
|
|
|
|
url_password=self.api_pwd, validate_certs=self.validate_certs, timeout=120)
|
|
|
|
|
except:
|
|
|
|
|
err = get_exception()
|
|
|
|
|
except Exception as err:
|
|
|
|
|
pool_id = self.pool_detail['id']
|
|
|
|
|
self.module.exit_json(
|
|
|
|
|
msg="Failed to update reserve drive count. Pool id [%s]. Array id [%s]. Error[%s]." % (pool_id,
|
|
|
|
|
self.ssid,
|
|
|
|
|
str(
|
|
|
|
|
err)))
|
|
|
|
|
to_native(err)))
|
|
|
|
|
|
|
|
|
|
def apply(self):
|
|
|
|
|
changed = False
|
|
|
|
|
@ -777,11 +763,10 @@ class NetAppESeriesStoragePool(object):
|
|
|
|
|
data=json.dumps(secure_pool_data), headers=self.post_headers, method='POST',
|
|
|
|
|
url_username=self.api_usr, url_password=self.api_pwd,
|
|
|
|
|
validate_certs=self.validate_certs, timeout=120, ignore_errors=True)
|
|
|
|
|
except:
|
|
|
|
|
err = get_exception()
|
|
|
|
|
except Exception as err:
|
|
|
|
|
self.module.exit_json(
|
|
|
|
|
msg="Failed to delete storage pool. Pool id [%s]. Array id [%s]. Error[%s]." % (
|
|
|
|
|
pool_id, self.ssid, str(err)))
|
|
|
|
|
pool_id, self.ssid, to_native(err)))
|
|
|
|
|
|
|
|
|
|
if int(retc) == 422:
|
|
|
|
|
self.module.fail_json(
|
|
|
|
|
@ -799,12 +784,11 @@ class NetAppESeriesStoragePool(object):
|
|
|
|
|
method='DELETE',
|
|
|
|
|
url_username=self.api_usr, url_password=self.api_pwd, validate_certs=self.validate_certs,
|
|
|
|
|
timeout=120)
|
|
|
|
|
except:
|
|
|
|
|
err = get_exception()
|
|
|
|
|
except Exception as err:
|
|
|
|
|
self.module.exit_json(
|
|
|
|
|
msg="Failed to delete storage pool. Pool id [%s]. Array id [%s]. Error[%s]." % (pool_id,
|
|
|
|
|
self.ssid,
|
|
|
|
|
str(err)))
|
|
|
|
|
to_native(err)))
|
|
|
|
|
|
|
|
|
|
self.module.exit_json(changed=changed, **self.pool_detail)
|
|
|
|
|
|
|
|
|
|
@ -813,9 +797,8 @@ def main():
|
|
|
|
|
sp = NetAppESeriesStoragePool()
|
|
|
|
|
try:
|
|
|
|
|
sp.apply()
|
|
|
|
|
except Exception:
|
|
|
|
|
e = get_exception()
|
|
|
|
|
sp.debug("Exception in apply(): \n%s", format_exc(e))
|
|
|
|
|
except Exception as e:
|
|
|
|
|
sp.debug("Exception in apply(): \n%s", format_exc())
|
|
|
|
|
raise
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|