mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Adding CreateVolume functionality (#6813)
* Adding create volume functionality * Adding changelog fragment * Sanity Fix * Sanity fix * Update 6813-redfish-config-add-create-volume.yml * Sanity fix * Sanity fix * Removing capabilities check and correcting controllers terminology to storage subsystem * Updating as per PR suggestions * sanity fix * Update plugins/modules/redfish_config.py Co-authored-by: Felix Fontein <felix@fontein.de> * Update plugins/modules/redfish_config.py Agreed Co-authored-by: Felix Fontein <felix@fontein.de> * Fixing merge issue * Fixing sanity issues * Adding CapacityBytes as a mandatory parameter and adding failure message when run for server below iLO6 * Sanity fix * Sanity fix * Updating vendor specific failure * Update plugins/modules/redfish_config.py Agreed Co-authored-by: Felix Fontein <felix@fontein.de> * Removing vendor specific failure case * removing unused import --------- Co-authored-by: Kushal <t-s.kushal@hpe.com> Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
parent
0ca07b0b05
commit
55893f27c9
3 changed files with 115 additions and 2 deletions
|
@ -0,0 +1,2 @@
|
|||
minor_changes:
|
||||
- redfish_config - add ``CreateVolume`` command to allow creation of volumes on servers (https://github.com/ansible-collections/community.general/pull/6813).
|
|
@ -3547,3 +3547,86 @@ class RedfishUtils(object):
|
|||
|
||||
return {'ret': True, 'changed': True,
|
||||
'msg': "The following volumes were deleted: %s" % str(volume_ids)}
|
||||
|
||||
def create_volume(self, volume_details, storage_subsystem_id):
|
||||
# Find the Storage resource from the requested ComputerSystem resource
|
||||
response = self.get_request(self.root_uri + self.systems_uri)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
data = response['data']
|
||||
storage_uri = data.get('Storage', {}).get('@odata.id')
|
||||
if storage_uri is None:
|
||||
return {'ret': False, 'msg': 'Storage resource not found'}
|
||||
|
||||
# Get Storage Collection
|
||||
response = self.get_request(self.root_uri + storage_uri)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
data = response['data']
|
||||
|
||||
# Collect Storage Subsystems
|
||||
self.storage_subsystems_uris = [i['@odata.id'] for i in response['data'].get('Members', [])]
|
||||
if not self.storage_subsystems_uris:
|
||||
return {
|
||||
'ret': False,
|
||||
'msg': "StorageCollection's Members array is either empty or missing"}
|
||||
|
||||
# Matching Storage Subsystem ID with user input
|
||||
self.storage_subsystem_uri = ""
|
||||
for storage_subsystem_uri in self.storage_subsystems_uris:
|
||||
if storage_subsystem_uri.split("/")[-2] == storage_subsystem_id:
|
||||
self.storage_subsystem_uri = storage_subsystem_uri
|
||||
|
||||
if not self.storage_subsystem_uri:
|
||||
return {
|
||||
'ret': False,
|
||||
'msg': "Provided Storage Subsystem ID %s does not exist on the server" % storage_subsystem_id}
|
||||
|
||||
# Validate input parameters
|
||||
required_parameters = ['RAIDType', 'Drives', 'CapacityBytes']
|
||||
allowed_parameters = ['DisplayName', 'InitializeMethod', 'MediaSpanCount',
|
||||
'Name', 'ReadCachePolicy', 'StripSizeBytes', 'VolumeUsage', 'WriteCachePolicy']
|
||||
|
||||
for parameter in required_parameters:
|
||||
if not volume_details.get(parameter):
|
||||
return {
|
||||
'ret': False,
|
||||
'msg': "%s are required parameter to create a volume" % str(required_parameters)}
|
||||
|
||||
# Navigate to the volume uri of the correct storage subsystem
|
||||
response = self.get_request(self.root_uri + self.storage_subsystem_uri)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
data = response['data']
|
||||
|
||||
# Deleting any volumes of RAIDType None present on the Storage Subsystem
|
||||
response = self.get_request(self.root_uri + data['Volumes']['@odata.id'])
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
volume_data = response['data']
|
||||
|
||||
if "Members" in volume_data:
|
||||
for member in volume_data["Members"]:
|
||||
response = self.get_request(self.root_uri + member['@odata.id'])
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
member_data = response['data']
|
||||
|
||||
if member_data["RAIDType"] == "None":
|
||||
response = self.delete_request(self.root_uri + member['@odata.id'])
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
|
||||
# Construct payload and issue POST command to create volume
|
||||
volume_details["Links"] = {}
|
||||
volume_details["Links"]["Drives"] = []
|
||||
for drive in volume_details["Drives"]:
|
||||
volume_details["Links"]["Drives"].append({"@odata.id": drive})
|
||||
del volume_details["Drives"]
|
||||
payload = volume_details
|
||||
response = self.post_request(self.root_uri + data['Volumes']['@odata.id'], payload)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
|
||||
return {'ret': True, 'changed': True,
|
||||
'msg': "Volume Created"}
|
||||
|
|
|
@ -153,6 +153,13 @@ options:
|
|||
type: bool
|
||||
default: True
|
||||
version_added: '7.5.0'
|
||||
volume_details:
|
||||
required: false
|
||||
description:
|
||||
- Setting dict of volume to be created.
|
||||
type: dict
|
||||
default: {}
|
||||
version_added: '7.5.0'
|
||||
author:
|
||||
- "Jose Delarosa (@jose-delarosa)"
|
||||
- "T S Kushal (@TSKushal)"
|
||||
|
@ -313,6 +320,20 @@ EXAMPLES = '''
|
|||
password: "{{ password }}"
|
||||
storage_subsystem_id: "DExxxxxx"
|
||||
volume_ids: ["volume1", "volume2"]
|
||||
|
||||
- name: Create Volume
|
||||
community.general.redfish_config:
|
||||
category: Systems
|
||||
command: CreateVolume
|
||||
baseuri: "{{ baseuri }}"
|
||||
username: "{{ username }}"
|
||||
password: "{{ password }}"
|
||||
storage_subsystem_id: "DExxxxxx"
|
||||
volume_details:
|
||||
Name: "MR Volume"
|
||||
RAIDType: "RAID0"
|
||||
Drives:
|
||||
- "/redfish/v1/Systems/1/Storage/DE00B000/Drives/1"
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
|
@ -331,7 +352,7 @@ from ansible.module_utils.common.text.converters import to_native
|
|||
# More will be added as module features are expanded
|
||||
CATEGORY_COMMANDS_ALL = {
|
||||
"Systems": ["SetBiosDefaultSettings", "SetBiosAttributes", "SetBootOrder",
|
||||
"SetDefaultBootOrder", "EnableSecureBoot", "SetSecureBoot", "DeleteVolumes"],
|
||||
"SetDefaultBootOrder", "EnableSecureBoot", "SetSecureBoot", "DeleteVolumes", "CreateVolume"],
|
||||
"Manager": ["SetNetworkProtocols", "SetManagerNic", "SetHostInterface"],
|
||||
"Sessions": ["SetSessionService"],
|
||||
}
|
||||
|
@ -366,7 +387,8 @@ def main():
|
|||
sessions_config=dict(type='dict', default={}),
|
||||
storage_subsystem_id=dict(type='str', default=''),
|
||||
volume_ids=dict(type='list', default=[], elements='str'),
|
||||
secure_boot_enable=dict(type='bool', default=True)
|
||||
secure_boot_enable=dict(type='bool', default=True),
|
||||
volume_details=dict(type='dict', default={})
|
||||
),
|
||||
required_together=[
|
||||
('username', 'password'),
|
||||
|
@ -433,6 +455,10 @@ def main():
|
|||
# Set SecureBoot options
|
||||
secure_boot_enable = module.params['secure_boot_enable']
|
||||
|
||||
# Volume creation options
|
||||
volume_details = module.params['volume_details']
|
||||
storage_subsystem_id = module.params['storage_subsystem_id']
|
||||
|
||||
# Build root URI
|
||||
root_uri = "https://" + module.params['baseuri']
|
||||
rf_utils = RedfishUtils(creds, root_uri, timeout, module,
|
||||
|
@ -470,6 +496,8 @@ def main():
|
|||
result = rf_utils.set_secure_boot(secure_boot_enable)
|
||||
elif command == "DeleteVolumes":
|
||||
result = rf_utils.delete_volumes(storage_subsystem_id, volume_ids)
|
||||
elif command == "CreateVolume":
|
||||
result = rf_utils.create_volume(volume_details, storage_subsystem_id)
|
||||
|
||||
elif category == "Manager":
|
||||
# execute only if we find a Manager service resource
|
||||
|
|
Loading…
Reference in a new issue