Add RAID management
Change-Id: Id342bf5de2cf06fa7a9c125a4fac15df21a1f5fe
This commit is contained in:
parent
da78c87db2
commit
617d5d7e1b
@ -21,6 +21,7 @@ from dracclient import exceptions
|
||||
from dracclient.resources import bios
|
||||
from dracclient.resources import job
|
||||
from dracclient.resources import lifecycle_controller
|
||||
from dracclient.resources import raid
|
||||
from dracclient.resources import uris
|
||||
from dracclient import utils
|
||||
from dracclient import wsman
|
||||
@ -50,6 +51,7 @@ class DRACClient(object):
|
||||
self._power_mgmt = bios.PowerManagement(self.client)
|
||||
self._boot_mgmt = bios.BootManagement(self.client)
|
||||
self._bios_cfg = bios.BIOSConfiguration(self.client)
|
||||
self._raid_mgmt = raid.RAIDManagement(self.client)
|
||||
|
||||
def get_power_state(self):
|
||||
"""Returns the current power state of the node
|
||||
@ -288,6 +290,118 @@ class DRACClient(object):
|
||||
return lifecycle_controller.LifecycleControllerManagement(
|
||||
self.client).get_version()
|
||||
|
||||
def list_raid_controllers(self):
|
||||
"""Returns the list of RAID controllers
|
||||
|
||||
:returns: a list of RAIDController objects
|
||||
:raises: WSManRequestFailure on request failures
|
||||
:raises: WSManInvalidResponse when receiving invalid response
|
||||
:raises: DRACOperationFailed on error reported back by the DRAC
|
||||
interface
|
||||
"""
|
||||
return self._raid_mgmt.list_raid_controllers()
|
||||
|
||||
def list_virtual_disks(self):
|
||||
"""Returns the list of RAID arrays
|
||||
|
||||
:returns: a list of VirtualDisk objects
|
||||
:raises: WSManRequestFailure on request failures
|
||||
:raises: WSManInvalidResponse when receiving invalid response
|
||||
:raises: DRACOperationFailed on error reported back by the DRAC
|
||||
interface
|
||||
"""
|
||||
return self._raid_mgmt.list_virtual_disks()
|
||||
|
||||
def list_physical_disks(self):
|
||||
"""Returns the list of physical disks
|
||||
|
||||
:returns: a list of PhysicalDisk objects
|
||||
:raises: WSManRequestFailure on request failures
|
||||
:raises: WSManInvalidResponse when receiving invalid response
|
||||
:raises: DRACOperationFailed on error reported back by the DRAC
|
||||
interface
|
||||
"""
|
||||
return self._raid_mgmt.list_physical_disks()
|
||||
|
||||
def create_virtual_disk(self, raid_controller, physical_disks, raid_level,
|
||||
size_mb, disk_name=None, span_length=None,
|
||||
span_depth=None):
|
||||
"""Creates a virtual disk
|
||||
|
||||
The created virtual disk will be in pending state.
|
||||
|
||||
:param raid_controller: id of the RAID controller
|
||||
:param physical_disks: ids of the physical disks
|
||||
:param raid_level: RAID level of the virtual disk
|
||||
:param size_mb: size of the virtual disk in megabytes
|
||||
:param disk_name: name of the virtual disk (optional)
|
||||
:param span_length: number of disks per span (optional)
|
||||
:param span_depth: number of spans in virtual disk (optional)
|
||||
:returns: a dictionary containing the commit_needed key with a boolean
|
||||
value indicating whether a config job must be created for the
|
||||
values to be applied.
|
||||
:raises: WSManRequestFailure on request failures
|
||||
:raises: WSManInvalidResponse when receiving invalid response
|
||||
:raises: DRACOperationFailed on error reported back by the DRAC
|
||||
interface
|
||||
:raises: DRACUnexpectedReturnValue on return value mismatch
|
||||
:raises: InvalidParameterValue on invalid input parameter
|
||||
"""
|
||||
return self._raid_mgmt.create_virtual_disk(
|
||||
raid_controller, physical_disks, raid_level, size_mb, disk_name,
|
||||
span_length, span_depth)
|
||||
|
||||
def delete_virtual_disk(self, virtual_disk):
|
||||
"""Deletes a virtual disk
|
||||
|
||||
The deleted virtual disk will be in pending state. For the changes to
|
||||
be applied, a config job must be created and the node must be rebooted.
|
||||
|
||||
:param virtual_disk: id of the virtual disk
|
||||
:returns: a dictionary containing the commit_needed key with a boolean
|
||||
value indicating whether a config job must be created for the
|
||||
values to be applied.
|
||||
:raises: WSManRequestFailure on request failures
|
||||
:raises: WSManInvalidResponse when receiving invalid response
|
||||
:raises: DRACOperationFailed on error reported back by the DRAC
|
||||
interface
|
||||
:raises: DRACUnexpectedReturnValue on return value mismatch
|
||||
"""
|
||||
return self._raid_mgmt.delete_virtual_disk(virtual_disk)
|
||||
|
||||
def commit_pending_raid_changes(self, raid_controller, reboot=False):
|
||||
"""Applies all pending changes on a RAID controller
|
||||
|
||||
...by creating a config job.
|
||||
|
||||
:param: reboot: indicates whether a RebootJob should be also be
|
||||
created or not
|
||||
:returns: id of the created job
|
||||
:raises: WSManRequestFailure on request failures
|
||||
:raises: WSManInvalidResponse when receiving invalid response
|
||||
:raises: DRACOperationFailed on error reported back by the DRAC
|
||||
interface
|
||||
:raises: DRACUnexpectedReturnValue on return value mismatch
|
||||
"""
|
||||
return self._job_mgmt.create_config_job(
|
||||
resource_uri=uris.DCIM_RAIDService,
|
||||
cim_creation_class_name='DCIM_RAIDService',
|
||||
cim_name='DCIM:RAIDService', target=raid_controller, reboot=reboot)
|
||||
|
||||
def abandon_pending_raid_changes(self, raid_controller):
|
||||
"""Deletes all pending changes on a RAID controller
|
||||
|
||||
:raises: WSManRequestFailure on request failures
|
||||
:raises: WSManInvalidResponse when receiving invalid response
|
||||
:raises: DRACOperationFailed on error reported back by the DRAC
|
||||
interface
|
||||
:raises: DRACUnexpectedReturnValue on return value mismatch
|
||||
"""
|
||||
self._job_mgmt.delete_pending_config(
|
||||
resource_uri=uris.DCIM_RAIDService,
|
||||
cim_creation_class_name='DCIM_RAIDService',
|
||||
cim_name='DCIM:RAIDService', target=raid_controller)
|
||||
|
||||
|
||||
class WSManClient(wsman.Client):
|
||||
"""Wrapper for wsman.Client with return value checking"""
|
||||
|
@ -573,12 +573,5 @@ class BIOSConfiguration(object):
|
||||
doc = self.client.invoke(uris.DCIM_BIOSService, 'SetAttributes',
|
||||
selectors, properties)
|
||||
|
||||
# Checking for RebootRequired attribute in the response, which
|
||||
# indicates whether we need to create a config job and then reboot, so
|
||||
# that the Lifecycle controller can commit the BIOS config changes that
|
||||
# have been proposed.
|
||||
reboot_required = utils.find_xml(doc, 'RebootRequired',
|
||||
uris.DCIM_BIOSService)
|
||||
commit_required = (reboot_required.text == 'Yes')
|
||||
|
||||
return {'commit_required': commit_required}
|
||||
return {'commit_required': utils.is_reboot_required(
|
||||
doc, uris.DCIM_BIOSService)}
|
||||
|
356
dracclient/resources/raid.py
Normal file
356
dracclient/resources/raid.py
Normal file
@ -0,0 +1,356 @@
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import collections
|
||||
|
||||
from dracclient import exceptions
|
||||
from dracclient.resources import uris
|
||||
from dracclient import utils
|
||||
|
||||
RAID_LEVELS = {
|
||||
'non-raid': '1',
|
||||
'0': '2',
|
||||
'1': '4',
|
||||
'5': '64',
|
||||
'6': '128',
|
||||
'1+0': '2048',
|
||||
'5+0': '8192',
|
||||
'6+0': '16384',
|
||||
}
|
||||
|
||||
REVERSE_RAID_LEVELS = dict((v, k) for (k, v) in RAID_LEVELS.items())
|
||||
|
||||
DISK_STATUS = {
|
||||
'0': 'unknown',
|
||||
'1': 'ok',
|
||||
'2': 'degraded',
|
||||
'3': 'error'
|
||||
}
|
||||
|
||||
DISK_RAID_STATUS = {
|
||||
'0': 'unknown',
|
||||
'1': 'ready',
|
||||
'2': 'online',
|
||||
'3': 'foreign',
|
||||
'4': 'offline',
|
||||
'5': 'blocked',
|
||||
'6': 'failed',
|
||||
'7': 'degraded',
|
||||
'8': 'non-RAID'
|
||||
}
|
||||
|
||||
VIRTUAL_DISK_PENDING_OPERATIONS = {
|
||||
'0': None,
|
||||
'1': 'fast_init',
|
||||
'2': 'pending_delete',
|
||||
'3': 'pending_create'
|
||||
}
|
||||
|
||||
PHYSICAL_DISK_MEDIA_TYPE = {
|
||||
'0': 'hdd',
|
||||
'1': 'ssd'
|
||||
}
|
||||
|
||||
PHYSICAL_DISK_BUS_PROTOCOL = {
|
||||
'0': 'unknown',
|
||||
'1': 'scsi',
|
||||
'2': 'pata',
|
||||
'3': 'fibre',
|
||||
'4': 'usb',
|
||||
'5': 'sata',
|
||||
'6': 'sas'
|
||||
}
|
||||
|
||||
PhysicalDisk = collections.namedtuple(
|
||||
'PhysicalDisk',
|
||||
['id', 'description', 'controller', 'manufacturer', 'model', 'media_type',
|
||||
'interface_type', 'size_mb', 'free_size_mb', 'serial_number',
|
||||
'firmware_version', 'state', 'raid_state'])
|
||||
|
||||
RAIDController = collections.namedtuple(
|
||||
'RAIDController', ['id', 'description', 'manufacturer', 'model',
|
||||
'firmware_version'])
|
||||
|
||||
VirtualDisk = collections.namedtuple(
|
||||
'VirtualDisk',
|
||||
['id', 'name', 'description', 'controller', 'raid_level', 'size_mb',
|
||||
'state', 'raid_state', 'span_depth', 'span_length', 'pending_operations'])
|
||||
|
||||
|
||||
class RAIDManagement(object):
|
||||
|
||||
def __init__(self, client):
|
||||
"""Creates RAIDManagement object
|
||||
|
||||
:param client: an instance of WSManClient
|
||||
"""
|
||||
self.client = client
|
||||
|
||||
def list_raid_controllers(self):
|
||||
"""Returns the list of RAID controllers
|
||||
|
||||
:returns: a list of RAIDController objects
|
||||
:raises: WSManRequestFailure on request failures
|
||||
:raises: WSManInvalidResponse when receiving invalid response
|
||||
:raises: DRACOperationFailed on error reported back by the DRAC
|
||||
interface
|
||||
"""
|
||||
|
||||
doc = self.client.enumerate(uris.DCIM_ControllerView)
|
||||
|
||||
drac_raid_controllers = utils.find_xml(doc, 'DCIM_ControllerView',
|
||||
uris.DCIM_ControllerView,
|
||||
find_all=True)
|
||||
|
||||
return [self._parse_drac_raid_controller(controller)
|
||||
for controller in drac_raid_controllers]
|
||||
|
||||
def _parse_drac_raid_controller(self, drac_controller):
|
||||
return RAIDController(
|
||||
id=self._get_raid_controller_attr(drac_controller, 'FQDD'),
|
||||
description=self._get_raid_controller_attr(
|
||||
drac_controller, 'DeviceDescription'),
|
||||
manufacturer=self._get_raid_controller_attr(
|
||||
drac_controller, 'DeviceCardManufacturer'),
|
||||
model=self._get_raid_controller_attr(
|
||||
drac_controller, 'ProductName'),
|
||||
firmware_version=self._get_raid_controller_attr(
|
||||
drac_controller, 'ControllerFirmwareVersion'))
|
||||
|
||||
def _get_raid_controller_attr(self, drac_controller, attr_name):
|
||||
return utils.get_wsman_resource_attr(
|
||||
drac_controller, uris.DCIM_ControllerView, attr_name)
|
||||
|
||||
def list_virtual_disks(self):
|
||||
"""Returns the list of virtual disks
|
||||
|
||||
:returns: a list of VirtualDisk objects
|
||||
:raises: WSManRequestFailure on request failures
|
||||
:raises: WSManInvalidResponse when receiving invalid response
|
||||
:raises: DRACOperationFailed on error reported back by the DRAC
|
||||
interface
|
||||
"""
|
||||
|
||||
doc = self.client.enumerate(uris.DCIM_VirtualDiskView)
|
||||
|
||||
drac_virtual_disks = utils.find_xml(doc, 'DCIM_VirtualDiskView',
|
||||
uris.DCIM_VirtualDiskView,
|
||||
find_all=True)
|
||||
|
||||
return [self._parse_drac_virtual_disk(disk)
|
||||
for disk in drac_virtual_disks]
|
||||
|
||||
def _parse_drac_virtual_disk(self, drac_disk):
|
||||
fqdd = self._get_virtual_disk_attr(drac_disk, 'FQDD')
|
||||
drac_raid_level = self._get_virtual_disk_attr(drac_disk, 'RAIDTypes')
|
||||
size_b = self._get_virtual_disk_attr(drac_disk, 'SizeInBytes')
|
||||
drac_status = self._get_virtual_disk_attr(drac_disk, 'PrimaryStatus')
|
||||
drac_raid_status = self._get_virtual_disk_attr(drac_disk, 'RAIDStatus')
|
||||
drac_pending_operations = self._get_virtual_disk_attr(
|
||||
drac_disk, 'PendingOperations')
|
||||
|
||||
return VirtualDisk(
|
||||
id=fqdd,
|
||||
name=self._get_virtual_disk_attr(drac_disk, 'Name'),
|
||||
description=self._get_virtual_disk_attr(drac_disk,
|
||||
'DeviceDescription'),
|
||||
controller=fqdd.split(':')[1],
|
||||
raid_level=REVERSE_RAID_LEVELS[drac_raid_level],
|
||||
size_mb=int(size_b) / 2 ** 20,
|
||||
state=DISK_STATUS[drac_status],
|
||||
raid_state=DISK_RAID_STATUS[drac_raid_status],
|
||||
span_depth=int(self._get_virtual_disk_attr(drac_disk,
|
||||
'SpanDepth')),
|
||||
span_length=int(self._get_virtual_disk_attr(drac_disk,
|
||||
'SpanLength')),
|
||||
pending_operations=(
|
||||
VIRTUAL_DISK_PENDING_OPERATIONS[drac_pending_operations]))
|
||||
|
||||
def _get_virtual_disk_attr(self, drac_disk, attr_name):
|
||||
return utils.get_wsman_resource_attr(
|
||||
drac_disk, uris.DCIM_VirtualDiskView, attr_name)
|
||||
|
||||
def list_physical_disks(self):
|
||||
"""Returns the list of physical disks
|
||||
|
||||
:returns: a list of PhysicalDisk objects
|
||||
:raises: WSManRequestFailure on request failures
|
||||
:raises: WSManInvalidResponse when receiving invalid response
|
||||
:raises: DRACOperationFailed on error reported back by the DRAC
|
||||
interface
|
||||
"""
|
||||
|
||||
doc = self.client.enumerate(uris.DCIM_PhysicalDiskView)
|
||||
|
||||
drac_physical_disks = utils.find_xml(doc, 'DCIM_PhysicalDiskView',
|
||||
uris.DCIM_PhysicalDiskView,
|
||||
find_all=True)
|
||||
|
||||
return [self._parse_drac_physical_disk(disk)
|
||||
for disk in drac_physical_disks]
|
||||
|
||||
def _parse_drac_physical_disk(self, drac_disk):
|
||||
fqdd = self._get_physical_disk_attr(drac_disk, 'FQDD')
|
||||
size_b = self._get_physical_disk_attr(drac_disk, 'SizeInBytes')
|
||||
free_size_b = self._get_physical_disk_attr(drac_disk,
|
||||
'FreeSizeInBytes')
|
||||
drac_status = self._get_physical_disk_attr(drac_disk, 'PrimaryStatus')
|
||||
drac_raid_status = self._get_physical_disk_attr(drac_disk,
|
||||
'RaidStatus')
|
||||
drac_media_type = self._get_physical_disk_attr(drac_disk, 'MediaType')
|
||||
drac_bus_protocol = self._get_physical_disk_attr(drac_disk,
|
||||
'BusProtocol')
|
||||
|
||||
return PhysicalDisk(
|
||||
id=fqdd,
|
||||
description=self._get_physical_disk_attr(drac_disk,
|
||||
'DeviceDescription'),
|
||||
controller=fqdd.split(':')[2],
|
||||
manufacturer=self._get_physical_disk_attr(drac_disk,
|
||||
'Manufacturer'),
|
||||
model=self._get_physical_disk_attr(drac_disk, 'Model'),
|
||||
media_type=PHYSICAL_DISK_MEDIA_TYPE[drac_media_type],
|
||||
interface_type=PHYSICAL_DISK_BUS_PROTOCOL[drac_bus_protocol],
|
||||
size_mb=int(size_b) / 2 ** 20,
|
||||
free_size_mb=int(free_size_b) / 2 ** 20,
|
||||
serial_number=self._get_physical_disk_attr(drac_disk,
|
||||
'SerialNumber'),
|
||||
firmware_version=self._get_physical_disk_attr(drac_disk,
|
||||
'Revision'),
|
||||
state=DISK_STATUS[drac_status],
|
||||
raid_state=DISK_RAID_STATUS[drac_raid_status])
|
||||
|
||||
def _get_physical_disk_attr(self, drac_disk, attr_name):
|
||||
return utils.get_wsman_resource_attr(
|
||||
drac_disk, uris.DCIM_PhysicalDiskView, attr_name)
|
||||
|
||||
def create_virtual_disk(self, raid_controller, physical_disks, raid_level,
|
||||
size_mb, disk_name=None, span_length=None,
|
||||
span_depth=None):
|
||||
"""Creates a virtual disk
|
||||
|
||||
The created virtual disk will be in pending state. For the changes to
|
||||
be applied, a config job must be created and the node must be rebooted.
|
||||
|
||||
:param raid_controller: id of the RAID controller
|
||||
:param physical_disks: ids of the physical disks
|
||||
:param raid_level: RAID level of the virtual disk
|
||||
:param size_mb: size of the virtual disk in megabytes
|
||||
:param disk_name: name of the virtual disk (optional)
|
||||
:param span_length: number of disks per span (optional)
|
||||
:param span_depth: number of spans in virtual disk (optional)
|
||||
:returns: a dictionary containing the commit_needed key with a boolean
|
||||
value indicating whether a config job must be created for the
|
||||
values to be applied.
|
||||
:raises: WSManRequestFailure on request failures
|
||||
:raises: WSManInvalidResponse when receiving invalid response
|
||||
:raises: DRACOperationFailed on error reported back by the DRAC
|
||||
interface
|
||||
:raises: DRACUnexpectedReturnValue on return value mismatch
|
||||
:raises: InvalidParameterValue on invalid input parameter
|
||||
"""
|
||||
|
||||
virtual_disk_prop_names = []
|
||||
virtual_disk_prop_values = []
|
||||
error_msgs = []
|
||||
|
||||
# RAID controller validation
|
||||
if not raid_controller:
|
||||
error_msgs.append("'raid_controller' is not supplied")
|
||||
|
||||
# physical disks validation
|
||||
if not physical_disks:
|
||||
error_msgs.append("'physical_disks' is not supplied")
|
||||
|
||||
# size validation
|
||||
if not size_mb:
|
||||
error_msgs.append("'size_mb' is not supplied")
|
||||
else:
|
||||
utils.validate_integer_value(size_mb, 'size_mb', error_msgs)
|
||||
|
||||
virtual_disk_prop_names.append('Size')
|
||||
virtual_disk_prop_values.append(str(size_mb))
|
||||
|
||||
# RAID level validation
|
||||
virtual_disk_prop_names.append('RAIDLevel')
|
||||
try:
|
||||
virtual_disk_prop_values.append(RAID_LEVELS[str(raid_level)])
|
||||
except KeyError:
|
||||
error_msgs.append("'raid_level' is invalid")
|
||||
|
||||
if disk_name is not None:
|
||||
virtual_disk_prop_names.append('VirtualDiskName')
|
||||
virtual_disk_prop_values.append(disk_name)
|
||||
|
||||
if span_depth is not None:
|
||||
utils.validate_integer_value(span_depth, 'span_depth', error_msgs)
|
||||
|
||||
virtual_disk_prop_names.append('SpanDepth')
|
||||
virtual_disk_prop_values.append(str(span_depth))
|
||||
|
||||
if span_length is not None:
|
||||
utils.validate_integer_value(span_length, 'span_length',
|
||||
error_msgs)
|
||||
|
||||
virtual_disk_prop_names.append('SpanLength')
|
||||
virtual_disk_prop_values.append(str(span_length))
|
||||
|
||||
if error_msgs:
|
||||
msg = ('The following errors were encountered while parsing '
|
||||
'the provided parameters: %r') % ','.join(error_msgs)
|
||||
raise exceptions.InvalidParameterValue(reason=msg)
|
||||
|
||||
selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
|
||||
'CreationClassName': 'DCIM_RAIDService',
|
||||
'SystemName': 'DCIM:ComputerSystem',
|
||||
'Name': 'DCIM:RAIDService'}
|
||||
properties = {'Target': raid_controller,
|
||||
'PDArray': physical_disks,
|
||||
'VDPropNameArray': virtual_disk_prop_names,
|
||||
'VDPropValueArray': virtual_disk_prop_values}
|
||||
doc = self.client.invoke(uris.DCIM_RAIDService, 'CreateVirtualDisk',
|
||||
selectors, properties,
|
||||
expected_return_value=utils.RET_SUCCESS)
|
||||
|
||||
return {'commit_required': utils.is_reboot_required(
|
||||
doc, uris.DCIM_RAIDService)}
|
||||
|
||||
def delete_virtual_disk(self, virtual_disk):
|
||||
"""Deletes a virtual disk
|
||||
|
||||
The deleted virtual disk will be in pending state. For the changes to
|
||||
be applied, a config job must be created and the node must be rebooted.
|
||||
|
||||
:param virtual_disk: id of the virtual disk
|
||||
:returns: a dictionary containing the commit_needed key with a boolean
|
||||
value indicating whether a config job must be created for the
|
||||
values to be applied.
|
||||
:raises: WSManRequestFailure on request failures
|
||||
:raises: WSManInvalidResponse when receiving invalid response
|
||||
:raises: DRACOperationFailed on error reported back by the DRAC
|
||||
interface
|
||||
:raises: DRACUnexpectedReturnValue on return value mismatch
|
||||
"""
|
||||
|
||||
selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
|
||||
'CreationClassName': 'DCIM_RAIDService',
|
||||
'SystemName': 'DCIM:ComputerSystem',
|
||||
'Name': 'DCIM:RAIDService'}
|
||||
properties = {'Target': virtual_disk}
|
||||
|
||||
doc = self.client.invoke(uris.DCIM_RAIDService, 'DeleteVirtualDisk',
|
||||
selectors, properties,
|
||||
expected_return_value=utils.RET_SUCCESS)
|
||||
|
||||
return {'commit_required': utils.is_reboot_required(
|
||||
doc, uris.DCIM_RAIDService)}
|
@ -37,11 +37,20 @@ DCIM_BootSourceSetting = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
|
||||
DCIM_ComputerSystem = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2'
|
||||
'/DCIM_ComputerSystem')
|
||||
|
||||
DCIM_ControllerView = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
|
||||
'DCIM_ControllerView')
|
||||
|
||||
DCIM_LifecycleJob = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
|
||||
'DCIM_LifecycleJob')
|
||||
|
||||
DCIM_PhysicalDiskView = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
|
||||
'DCIM_PhysicalDiskView')
|
||||
|
||||
DCIM_RAIDService = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
|
||||
'DCIM_RAIDService')
|
||||
|
||||
DCIM_SystemView = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
|
||||
'DCIM_SystemView')
|
||||
|
||||
DCIM_VirtualDiskView = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
|
||||
'DCIM_VirtualDiskView')
|
||||
|
@ -22,6 +22,7 @@ from dracclient import exceptions
|
||||
from dracclient.resources import bios
|
||||
import dracclient.resources.job
|
||||
from dracclient.resources import lifecycle_controller
|
||||
from dracclient.resources import raid
|
||||
from dracclient.resources import uris
|
||||
from dracclient.tests import base
|
||||
from dracclient.tests import utils as test_utils
|
||||
@ -632,6 +633,261 @@ class ClientLifecycleControllerManagementTestCase(base.BaseTest):
|
||||
self.assertEqual((2, 1, 0), version)
|
||||
|
||||
|
||||
@requests_mock.Mocker()
|
||||
class ClientRAIDManagementTestCase(base.BaseTest):
|
||||
|
||||
def setUp(self):
|
||||
super(ClientRAIDManagementTestCase, self).setUp()
|
||||
self.drac_client = dracclient.client.DRACClient(
|
||||
**test_utils.FAKE_ENDPOINT)
|
||||
|
||||
def test_list_raid_controllers(self, mock_requests):
|
||||
expected_raid_controller = raid.RAIDController(
|
||||
id='RAID.Integrated.1-1',
|
||||
description='Integrated RAID Controller 1',
|
||||
manufacturer='DELL',
|
||||
model='PERC H710 Mini',
|
||||
firmware_version='21.3.0-0009')
|
||||
|
||||
mock_requests.post(
|
||||
'https://1.2.3.4:443/wsman',
|
||||
text=test_utils.RAIDEnumerations[uris.DCIM_ControllerView]['ok'])
|
||||
|
||||
self.assertIn(expected_raid_controller,
|
||||
self.drac_client.list_raid_controllers())
|
||||
|
||||
def test_list_virtual_disks(self, mock_requests):
|
||||
expected_virtual_disk = raid.VirtualDisk(
|
||||
id='Disk.Virtual.0:RAID.Integrated.1-1',
|
||||
name='disk 0',
|
||||
description='Virtual Disk 0 on Integrated RAID Controller 1',
|
||||
controller='RAID.Integrated.1-1',
|
||||
raid_level='1',
|
||||
size_mb=571776,
|
||||
state='ok',
|
||||
raid_state='online',
|
||||
span_depth=1,
|
||||
span_length=2,
|
||||
pending_operations=None)
|
||||
|
||||
mock_requests.post(
|
||||
'https://1.2.3.4:443/wsman',
|
||||
text=test_utils.RAIDEnumerations[uris.DCIM_VirtualDiskView]['ok'])
|
||||
|
||||
self.assertIn(expected_virtual_disk,
|
||||
self.drac_client.list_virtual_disks())
|
||||
|
||||
def test_list_physical_disks(self, mock_requests):
|
||||
expected_physical_disk = raid.PhysicalDisk(
|
||||
id='Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1',
|
||||
description=('Disk 1 in Backplane 1 of '
|
||||
'Integrated RAID Controller 1'),
|
||||
controller='RAID.Integrated.1-1',
|
||||
manufacturer='SEAGATE',
|
||||
model='ST600MM0006',
|
||||
media_type='hdd',
|
||||
interface_type='sas',
|
||||
size_mb=571776,
|
||||
free_size_mb=571776,
|
||||
serial_number='S0M3EY2Z',
|
||||
firmware_version='LS0A',
|
||||
state='ok',
|
||||
raid_state='ready')
|
||||
|
||||
mock_requests.post(
|
||||
'https://1.2.3.4:443/wsman',
|
||||
text=test_utils.RAIDEnumerations[uris.DCIM_PhysicalDiskView]['ok'])
|
||||
|
||||
self.assertIn(expected_physical_disk,
|
||||
self.drac_client.list_physical_disks())
|
||||
|
||||
@mock.patch.object(dracclient.client.WSManClient, 'invoke',
|
||||
spec_set=True, autospec=True)
|
||||
def test_create_virtual_disk(self, mock_requests, mock_invoke):
|
||||
expected_selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
|
||||
'CreationClassName': 'DCIM_RAIDService',
|
||||
'SystemName': 'DCIM:ComputerSystem',
|
||||
'Name': 'DCIM:RAIDService'}
|
||||
expected_properties = {'Target': 'controller',
|
||||
'PDArray': ['disk1', 'disk2'],
|
||||
'VDPropNameArray': ['Size', 'RAIDLevel'],
|
||||
'VDPropValueArray': ['42', '4']}
|
||||
mock_invoke.return_value = lxml.etree.fromstring(
|
||||
test_utils.RAIDInvocations[uris.DCIM_RAIDService][
|
||||
'CreateVirtualDisk']['ok'])
|
||||
|
||||
result = self.drac_client.create_virtual_disk(
|
||||
raid_controller='controller', physical_disks=['disk1', 'disk2'],
|
||||
raid_level='1', size_mb=42)
|
||||
|
||||
self.assertEqual({'commit_required': True}, result)
|
||||
mock_invoke.assert_called_once_with(
|
||||
mock.ANY, uris.DCIM_RAIDService, 'CreateVirtualDisk',
|
||||
expected_selectors, expected_properties,
|
||||
expected_return_value=utils.RET_SUCCESS)
|
||||
|
||||
@mock.patch.object(dracclient.client.WSManClient, 'invoke',
|
||||
spec_set=True, autospec=True)
|
||||
def test_create_virtual_disk_with_extra_params(self, mock_requests,
|
||||
mock_invoke):
|
||||
expected_selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
|
||||
'CreationClassName': 'DCIM_RAIDService',
|
||||
'SystemName': 'DCIM:ComputerSystem',
|
||||
'Name': 'DCIM:RAIDService'}
|
||||
expected_properties = {'Target': 'controller',
|
||||
'PDArray': ['disk1', 'disk2'],
|
||||
'VDPropNameArray': ['Size', 'RAIDLevel',
|
||||
'VirtualDiskName',
|
||||
'SpanDepth', 'SpanLength'],
|
||||
'VDPropValueArray': ['42', '4', 'name', '3',
|
||||
'2']}
|
||||
mock_invoke.return_value = lxml.etree.fromstring(
|
||||
test_utils.RAIDInvocations[uris.DCIM_RAIDService][
|
||||
'CreateVirtualDisk']['ok'])
|
||||
|
||||
result = self.drac_client.create_virtual_disk(
|
||||
raid_controller='controller', physical_disks=['disk1', 'disk2'],
|
||||
raid_level='1', size_mb=42, disk_name='name', span_length=2,
|
||||
span_depth=3)
|
||||
|
||||
self.assertEqual({'commit_required': True}, result)
|
||||
mock_invoke.assert_called_once_with(
|
||||
mock.ANY, uris.DCIM_RAIDService, 'CreateVirtualDisk',
|
||||
expected_selectors, expected_properties,
|
||||
expected_return_value=utils.RET_SUCCESS)
|
||||
|
||||
def test_create_virtual_disk_fail(self, mock_requests):
|
||||
mock_requests.post(
|
||||
'https://1.2.3.4:443/wsman',
|
||||
text=test_utils.RAIDInvocations[
|
||||
uris.DCIM_RAIDService]['CreateVirtualDisk']['error'])
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.DRACOperationFailed,
|
||||
self.drac_client.create_virtual_disk, raid_controller='controller',
|
||||
physical_disks=['disk1', 'disk2'], raid_level='1', size_mb=42,
|
||||
disk_name='name', span_length=2, span_depth=3)
|
||||
|
||||
def test_create_virtual_disk_missing_controller(self, mock_requests):
|
||||
self.assertRaises(
|
||||
exceptions.InvalidParameterValue,
|
||||
self.drac_client.create_virtual_disk, raid_controller=None,
|
||||
physical_disks=['disk1', 'disk2'], raid_level='1', size_mb=42,
|
||||
disk_name='name', span_length=2, span_depth=3)
|
||||
|
||||
def test_create_virtual_disk_missing_physical_disks(self, mock_requests):
|
||||
self.assertRaises(
|
||||
exceptions.InvalidParameterValue,
|
||||
self.drac_client.create_virtual_disk, raid_controller='controller',
|
||||
physical_disks=None, raid_level='1', size_mb=42,
|
||||
disk_name='name', span_length=2, span_depth=3)
|
||||
|
||||
def test_create_virtual_disk_missing_raid_level(self, mock_requests):
|
||||
self.assertRaises(
|
||||
exceptions.InvalidParameterValue,
|
||||
self.drac_client.create_virtual_disk, raid_controller='controller',
|
||||
physical_disks=['disk1', 'disk2'], raid_level=None, size_mb=42,
|
||||
disk_name='name', span_length=2, span_depth=3)
|
||||
|
||||
def test_create_virtual_disk_invalid_raid_level(self, mock_requests):
|
||||
self.assertRaises(
|
||||
exceptions.InvalidParameterValue,
|
||||
self.drac_client.create_virtual_disk, raid_controller='controller',
|
||||
physical_disks=['disk1', 'disk2'], raid_level='foo', size_mb=42,
|
||||
disk_name='name', span_length=2, span_depth=3)
|
||||
|
||||
def test_create_virtual_disk_missing_size(self, mock_requests):
|
||||
self.assertRaises(
|
||||
exceptions.InvalidParameterValue,
|
||||
self.drac_client.create_virtual_disk, raid_controller='controller',
|
||||
physical_disks=['disk1', 'disk2'], raid_level='1', size_mb=None,
|
||||
disk_name='name', span_length=2, span_depth=3)
|
||||
|
||||
def test_create_virtual_disk_invalid_size(self, mock_requests):
|
||||
self.assertRaises(
|
||||
exceptions.InvalidParameterValue,
|
||||
self.drac_client.create_virtual_disk, raid_controller='controller',
|
||||
physical_disks=['disk1', 'disk2'], raid_level='1',
|
||||
size_mb='foo', disk_name='name', span_length=2, span_depth=3)
|
||||
|
||||
def test_create_virtual_disk_invalid_span_length(self, mock_requests):
|
||||
self.assertRaises(
|
||||
exceptions.InvalidParameterValue,
|
||||
self.drac_client.create_virtual_disk, raid_controller='controller',
|
||||
physical_disks=['disk1', 'disk2'], raid_level='1', size_mb=42,
|
||||
disk_name='name', span_length='foo', span_depth=3)
|
||||
|
||||
def test_create_virtual_disk_invalid_span_depth(self, mock_requests):
|
||||
self.assertRaises(
|
||||
exceptions.InvalidParameterValue,
|
||||
self.drac_client.create_virtual_disk, raid_controller='controller',
|
||||
physical_disks=['disk1', 'disk2'], raid_level='1', size_mb=42,
|
||||
disk_name='name', span_length=2, span_depth='foo')
|
||||
|
||||
@mock.patch.object(dracclient.client.WSManClient, 'invoke',
|
||||
spec_set=True, autospec=True)
|
||||
def test_delete_virtual_disk(self, mock_requests, mock_invoke):
|
||||
expected_selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
|
||||
'CreationClassName': 'DCIM_RAIDService',
|
||||
'SystemName': 'DCIM:ComputerSystem',
|
||||
'Name': 'DCIM:RAIDService'}
|
||||
expected_properties = {'Target': 'disk1'}
|
||||
mock_invoke.return_value = lxml.etree.fromstring(
|
||||
test_utils.RAIDInvocations[uris.DCIM_RAIDService][
|
||||
'DeleteVirtualDisk']['ok'])
|
||||
|
||||
result = self.drac_client.delete_virtual_disk('disk1')
|
||||
|
||||
self.assertEqual({'commit_required': True}, result)
|
||||
mock_invoke.assert_called_once_with(
|
||||
mock.ANY, uris.DCIM_RAIDService, 'DeleteVirtualDisk',
|
||||
expected_selectors, expected_properties,
|
||||
expected_return_value=utils.RET_SUCCESS)
|
||||
|
||||
def test_delete_virtual_disk_fail(self, mock_requests):
|
||||
mock_requests.post(
|
||||
'https://1.2.3.4:443/wsman',
|
||||
text=test_utils.RAIDInvocations[
|
||||
uris.DCIM_RAIDService]['DeleteVirtualDisk']['error'])
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.DRACOperationFailed,
|
||||
self.drac_client.delete_virtual_disk, 'disk1')
|
||||
|
||||
@mock.patch.object(dracclient.resources.job.JobManagement,
|
||||
'create_config_job', spec_set=True, autospec=True)
|
||||
def test_commit_pending_raid_changes(self, mock_requests,
|
||||
mock_create_config_job):
|
||||
self.drac_client.commit_pending_raid_changes('controller')
|
||||
|
||||
mock_create_config_job.assert_called_once_with(
|
||||
mock.ANY, resource_uri=uris.DCIM_RAIDService,
|
||||
cim_creation_class_name='DCIM_RAIDService',
|
||||
cim_name='DCIM:RAIDService', target='controller', reboot=False)
|
||||
|
||||
@mock.patch.object(dracclient.resources.job.JobManagement,
|
||||
'create_config_job', spec_set=True, autospec=True)
|
||||
def test_commit_pending_raid_changes_with_reboot(self, mock_requests,
|
||||
mock_create_config_job):
|
||||
self.drac_client.commit_pending_raid_changes('controller', reboot=True)
|
||||
|
||||
mock_create_config_job.assert_called_once_with(
|
||||
mock.ANY, resource_uri=uris.DCIM_RAIDService,
|
||||
cim_creation_class_name='DCIM_RAIDService',
|
||||
cim_name='DCIM:RAIDService', target='controller', reboot=True)
|
||||
|
||||
@mock.patch.object(dracclient.resources.job.JobManagement,
|
||||
'delete_pending_config', spec_set=True, autospec=True)
|
||||
def test_abandon_pending_bios_changes(self, mock_requests,
|
||||
mock_delete_pending_config):
|
||||
self.drac_client.abandon_pending_raid_changes('controller')
|
||||
|
||||
mock_delete_pending_config.assert_called_once_with(
|
||||
mock.ANY, resource_uri=uris.DCIM_RAIDService,
|
||||
cim_creation_class_name='DCIM_RAIDService',
|
||||
cim_name='DCIM:RAIDService', target='controller')
|
||||
|
||||
|
||||
@requests_mock.Mocker()
|
||||
class WSManClientTestCase(base.BaseTest):
|
||||
|
||||
|
@ -126,3 +126,32 @@ LifecycleControllerEnumerations = {
|
||||
'ok': load_wsman_xml('system_view-enum-ok')
|
||||
},
|
||||
}
|
||||
|
||||
RAIDEnumerations = {
|
||||
uris.DCIM_ControllerView: {
|
||||
'ok': load_wsman_xml('controller_view-enum-ok')
|
||||
},
|
||||
uris.DCIM_PhysicalDiskView: {
|
||||
'ok': load_wsman_xml('physical_disk_view-enum-ok')
|
||||
},
|
||||
uris.DCIM_VirtualDiskView: {
|
||||
'ok': load_wsman_xml('virtual_disk_view-enum-ok')
|
||||
}
|
||||
}
|
||||
|
||||
RAIDInvocations = {
|
||||
uris.DCIM_RAIDService: {
|
||||
'CreateVirtualDisk': {
|
||||
'ok': load_wsman_xml(
|
||||
'raid_service-invoke-create_virtual_disk-ok'),
|
||||
'error': load_wsman_xml(
|
||||
'raid_service-invoke-create_virtual_disk-error'),
|
||||
},
|
||||
'DeleteVirtualDisk': {
|
||||
'ok': load_wsman_xml(
|
||||
'raid_service-invoke-delete_virtual_disk-ok'),
|
||||
'error': load_wsman_xml(
|
||||
'raid_service-invoke-delete_virtual_disk-error'),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
60
dracclient/tests/wsman_mocks/controller_view-enum-ok.xml
Normal file
60
dracclient/tests/wsman_mocks/controller_view-enum-ok.xml
Normal file
@ -0,0 +1,60 @@
|
||||
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
|
||||
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
|
||||
xmlns:wsen="http://schemas.xmlsoap.org/ws/2004/09/enumeration"
|
||||
xmlns:wsman="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"
|
||||
xmlns:n1="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_ControllerView"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<s:Header>
|
||||
<wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
|
||||
<wsa:Action>http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse</wsa:Action>
|
||||
<wsa:RelatesTo>uuid:4eccb42a-103a-103a-8002-fd0aa2bdb228</wsa:RelatesTo>
|
||||
<wsa:MessageID>uuid:55b0f8ed-103f-103f-8988-a36fc6fe83b0</wsa:MessageID>
|
||||
</s:Header>
|
||||
<s:Body>
|
||||
<wsen:EnumerateResponse>
|
||||
<wsman:Items>
|
||||
<n1:DCIM_ControllerView>
|
||||
<n1:Bus>1</n1:Bus>
|
||||
<n1:CacheSizeInMB>512</n1:CacheSizeInMB>
|
||||
<n1:CachecadeCapability>1</n1:CachecadeCapability>
|
||||
<n1:ControllerFirmwareVersion>21.3.0-0009</n1:ControllerFirmwareVersion>
|
||||
<n1:Device>0</n1:Device>
|
||||
<n1:DeviceCardDataBusWidth>Unknown</n1:DeviceCardDataBusWidth>
|
||||
<n1:DeviceCardManufacturer>DELL</n1:DeviceCardManufacturer>
|
||||
<n1:DeviceCardSlotLength>2</n1:DeviceCardSlotLength>
|
||||
<n1:DeviceCardSlotType>Unknown</n1:DeviceCardSlotType>
|
||||
<n1:DeviceDescription>Integrated RAID Controller 1</n1:DeviceDescription>
|
||||
<n1:DriverVersion xsi:nil="true"/>
|
||||
<n1:EncryptionCapability>1</n1:EncryptionCapability>
|
||||
<n1:EncryptionMode>0</n1:EncryptionMode>
|
||||
<n1:FQDD>RAID.Integrated.1-1</n1:FQDD>
|
||||
<n1:Function>0</n1:Function>
|
||||
<n1:InstanceID>RAID.Integrated.1-1</n1:InstanceID>
|
||||
<n1:KeyID xsi:nil="true"/>
|
||||
<n1:LastSystemInventoryTime>20150226175957.000000+000</n1:LastSystemInventoryTime>
|
||||
<n1:LastUpdateTime>20150226175950.000000+000</n1:LastUpdateTime>
|
||||
<n1:MaxAvailablePCILinkSpeed>Generation 2</n1:MaxAvailablePCILinkSpeed>
|
||||
<n1:MaxPossiblePCILinkSpeed>Generation 3</n1:MaxPossiblePCILinkSpeed>
|
||||
<n1:PCIDeviceID>5B</n1:PCIDeviceID>
|
||||
<n1:PCISlot>1</n1:PCISlot>
|
||||
<n1:PCISubDeviceID>1F38</n1:PCISubDeviceID>
|
||||
<n1:PCISubVendorID>1028</n1:PCISubVendorID>
|
||||
<n1:PCIVendorID>1000</n1:PCIVendorID>
|
||||
<n1:PatrolReadState>0</n1:PatrolReadState>
|
||||
<n1:PrimaryStatus>1</n1:PrimaryStatus>
|
||||
<n1:ProductName>PERC H710 Mini</n1:ProductName>
|
||||
<n1:RollupStatus>1</n1:RollupStatus>
|
||||
<n1:SASAddress>5B083FE0D2D0F200</n1:SASAddress>
|
||||
<n1:SecurityStatus>1</n1:SecurityStatus>
|
||||
<n1:SlicedVDCapability>1</n1:SlicedVDCapability>
|
||||
<n1:SupportControllerBootMode>1</n1:SupportControllerBootMode>
|
||||
<n1:SupportEnhancedAutoForeignImport>1</n1:SupportEnhancedAutoForeignImport>
|
||||
<n1:SupportRAID10UnevenSpans>0</n1:SupportRAID10UnevenSpans>
|
||||
<n1:T10PICapability>0</n1:T10PICapability>
|
||||
</n1:DCIM_ControllerView>
|
||||
</wsman:Items>
|
||||
<wsen:EnumerationContext/>
|
||||
<wsman:EndOfSequence/>
|
||||
</wsen:EnumerateResponse>
|
||||
</s:Body>
|
||||
</s:Envelope>
|
94
dracclient/tests/wsman_mocks/physical_disk_view-enum-ok.xml
Normal file
94
dracclient/tests/wsman_mocks/physical_disk_view-enum-ok.xml
Normal file
@ -0,0 +1,94 @@
|
||||
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
|
||||
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
|
||||
xmlns:wsen="http://schemas.xmlsoap.org/ws/2004/09/enumeration"
|
||||
xmlns:wsman="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"
|
||||
xmlns:n1="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_PhysicalDiskView">
|
||||
<s:Header>
|
||||
<wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
|
||||
<wsa:Action>http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse</wsa:Action>
|
||||
<wsa:RelatesTo>uuid:4b2950f9-1036-1036-8002-fd0aa2bdb228</wsa:RelatesTo>
|
||||
<wsa:MessageID>uuid:5221deee-103b-103b-8986-a36fc6fe83b0</wsa:MessageID>
|
||||
</s:Header>
|
||||
<s:Body>
|
||||
<wsen:EnumerateResponse>
|
||||
<wsman:Items>
|
||||
<n1:DCIM_PhysicalDiskView>
|
||||
<n1:BlockSizeInBytes>512</n1:BlockSizeInBytes>
|
||||
<n1:BusProtocol>6</n1:BusProtocol>
|
||||
<n1:Connector>0</n1:Connector>
|
||||
<n1:DeviceDescription>Disk 0 in Backplane 1 of Integrated RAID Controller 1</n1:DeviceDescription>
|
||||
<n1:DriveFormFactor>2</n1:DriveFormFactor>
|
||||
<n1:FQDD>Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1</n1:FQDD>
|
||||
<n1:FreeSizeInBytes>599550590976</n1:FreeSizeInBytes>
|
||||
<n1:HotSpareStatus>0</n1:HotSpareStatus>
|
||||
<n1:InstanceID>Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1</n1:InstanceID>
|
||||
<n1:LastSystemInventoryTime>20150226180025.000000+000</n1:LastSystemInventoryTime>
|
||||
<n1:LastUpdateTime>20150226180025.000000+000</n1:LastUpdateTime>
|
||||
<n1:Manufacturer>SEAGATE </n1:Manufacturer>
|
||||
<n1:ManufacturingDay>2</n1:ManufacturingDay>
|
||||
<n1:ManufacturingWeek>33</n1:ManufacturingWeek>
|
||||
<n1:ManufacturingYear>2014</n1:ManufacturingYear>
|
||||
<n1:MaxCapableSpeed>3</n1:MaxCapableSpeed>
|
||||
<n1:MediaType>0</n1:MediaType>
|
||||
<n1:Model>ST600MM0006 </n1:Model>
|
||||
<n1:OperationName>None</n1:OperationName>
|
||||
<n1:OperationPercentComplete>0</n1:OperationPercentComplete>
|
||||
<n1:PPID>CN07YX587262248G01MHA02 </n1:PPID>
|
||||
<n1:PredictiveFailureState>0</n1:PredictiveFailureState>
|
||||
<n1:PrimaryStatus>1</n1:PrimaryStatus>
|
||||
<n1:RaidStatus>1</n1:RaidStatus>
|
||||
<n1:RemainingRatedWriteEndurance>255</n1:RemainingRatedWriteEndurance>
|
||||
<n1:Revision>LS0A</n1:Revision>
|
||||
<n1:RollupStatus>1</n1:RollupStatus>
|
||||
<n1:SASAddress>5000C5007764FF6D</n1:SASAddress>
|
||||
<n1:SecurityState>0</n1:SecurityState>
|
||||
<n1:SerialNumber>S0M3EVL6 </n1:SerialNumber>
|
||||
<n1:SizeInBytes>599550590976</n1:SizeInBytes>
|
||||
<n1:Slot>0</n1:Slot>
|
||||
<n1:SupportedEncryptionTypes>None</n1:SupportedEncryptionTypes>
|
||||
<n1:T10PICapability>0</n1:T10PICapability>
|
||||
<n1:UsedSizeInBytes>0</n1:UsedSizeInBytes>
|
||||
</n1:DCIM_PhysicalDiskView>
|
||||
<n1:DCIM_PhysicalDiskView>
|
||||
<n1:BlockSizeInBytes>512</n1:BlockSizeInBytes>
|
||||
<n1:BusProtocol>6</n1:BusProtocol>
|
||||
<n1:Connector>0</n1:Connector>
|
||||
<n1:DeviceDescription>Disk 1 in Backplane 1 of Integrated RAID Controller 1</n1:DeviceDescription>
|
||||
<n1:DriveFormFactor>2</n1:DriveFormFactor>
|
||||
<n1:FQDD>Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1</n1:FQDD>
|
||||
<n1:FreeSizeInBytes>599550590976</n1:FreeSizeInBytes>
|
||||
<n1:HotSpareStatus>0</n1:HotSpareStatus>
|
||||
<n1:InstanceID>Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1</n1:InstanceID>
|
||||
<n1:LastSystemInventoryTime>20150226180025.000000+000</n1:LastSystemInventoryTime>
|
||||
<n1:LastUpdateTime>20150226180025.000000+000</n1:LastUpdateTime>
|
||||
<n1:Manufacturer>SEAGATE </n1:Manufacturer>
|
||||
<n1:ManufacturingDay>2</n1:ManufacturingDay>
|
||||
<n1:ManufacturingWeek>33</n1:ManufacturingWeek>
|
||||
<n1:ManufacturingYear>2014</n1:ManufacturingYear>
|
||||
<n1:MaxCapableSpeed>3</n1:MaxCapableSpeed>
|
||||
<n1:MediaType>0</n1:MediaType>
|
||||
<n1:Model>ST600MM0006 </n1:Model>
|
||||
<n1:OperationName>None</n1:OperationName>
|
||||
<n1:OperationPercentComplete>0</n1:OperationPercentComplete>
|
||||
<n1:PPID>CN07YX587262248G01PZA02 </n1:PPID>
|
||||
<n1:PredictiveFailureState>0</n1:PredictiveFailureState>
|
||||
<n1:PrimaryStatus>1</n1:PrimaryStatus>
|
||||
<n1:RaidStatus>1</n1:RaidStatus>
|
||||
<n1:RemainingRatedWriteEndurance>255</n1:RemainingRatedWriteEndurance>
|
||||
<n1:Revision>LS0A</n1:Revision>
|
||||
<n1:RollupStatus>1</n1:RollupStatus>
|
||||
<n1:SASAddress>5000C5007764F409</n1:SASAddress>
|
||||
<n1:SecurityState>0</n1:SecurityState>
|
||||
<n1:SerialNumber>S0M3EY2Z </n1:SerialNumber>
|
||||
<n1:SizeInBytes>599550590976</n1:SizeInBytes>
|
||||
<n1:Slot>1</n1:Slot>
|
||||
<n1:SupportedEncryptionTypes>None</n1:SupportedEncryptionTypes>
|
||||
<n1:T10PICapability>0</n1:T10PICapability>
|
||||
<n1:UsedSizeInBytes>0</n1:UsedSizeInBytes>
|
||||
</n1:DCIM_PhysicalDiskView>
|
||||
</wsman:Items>
|
||||
<wsen:EnumerationContext/>
|
||||
<wsman:EndOfSequence/>
|
||||
</wsen:EnumerateResponse>
|
||||
</s:Body>
|
||||
</s:Envelope>
|
@ -0,0 +1,17 @@
|
||||
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
|
||||
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
|
||||
xmlns:n1="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_RAIDService">
|
||||
<s:Header>
|
||||
<wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
|
||||
<wsa:Action>http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_RAIDService/CreateVirtualDiskResponse</wsa:Action>
|
||||
<wsa:RelatesTo>uuid:1a12188d-103b-103b-8002-fd0aa2bdb228</wsa:RelatesTo>
|
||||
<wsa:MessageID>uuid:20ade7ab-1040-1040-89a6-a36fc6fe83b0</wsa:MessageID>
|
||||
</s:Header>
|
||||
<s:Body>
|
||||
<n1:CreateVirtualDisk_OUTPUT>
|
||||
<n1:Message>Physical disk not found</n1:Message>
|
||||
<n1:MessageID>STOR029</n1:MessageID>
|
||||
<n1:ReturnValue>2</n1:ReturnValue>
|
||||
</n1:CreateVirtualDisk_OUTPUT>
|
||||
</s:Body>
|
||||
</s:Envelope>
|
@ -0,0 +1,29 @@
|
||||
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
|
||||
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
|
||||
xmlns:n1="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_RAIDService"
|
||||
xmlns:wsman="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd">
|
||||
<s:Header>
|
||||
<wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
|
||||
<wsa:Action>http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_RAIDService/CreateVirtualDiskResponse</wsa:Action>
|
||||
<wsa:RelatesTo>uuid:2a48cc56-103b-103b-8002-fd0aa2bdb228</wsa:RelatesTo>
|
||||
<wsa:MessageID>uuid:31086b42-1040-1040-89ab-a36fc6fe83b0</wsa:MessageID>
|
||||
</s:Header>
|
||||
<s:Body>
|
||||
<n1:CreateVirtualDisk_OUTPUT>
|
||||
<n1:NewVirtualDisk>
|
||||
<wsa:EndpointReference>
|
||||
<wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>
|
||||
<wsa:ReferenceParameters>
|
||||
<wsman:ResourceURI>http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_VirtualDiskView</wsman:ResourceURI>
|
||||
<wsman:SelectorSet>
|
||||
<wsman:Selector Name="InstanceID">DISK.Virtual.267386880:RAID.Integrated.1-1</wsman:Selector>
|
||||
<wsman:Selector Name="__cimnamespace">root/dcim</wsman:Selector>
|
||||
</wsman:SelectorSet>
|
||||
</wsa:ReferenceParameters>
|
||||
</wsa:EndpointReference>
|
||||
</n1:NewVirtualDisk>
|
||||
<n1:RebootRequired>YES</n1:RebootRequired>
|
||||
<n1:ReturnValue>0</n1:ReturnValue>
|
||||
</n1:CreateVirtualDisk_OUTPUT>
|
||||
</s:Body>
|
||||
</s:Envelope>
|
@ -0,0 +1,17 @@
|
||||
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
|
||||
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
|
||||
xmlns:n1="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_RAIDService">
|
||||
<s:Header>
|
||||
<wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
|
||||
<wsa:Action>http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_RAIDService/DeleteVirtualDiskResponse</wsa:Action>
|
||||
<wsa:RelatesTo>uuid:f9487fcf-103a-103a-8002-fd0aa2bdb228</wsa:RelatesTo>
|
||||
<wsa:MessageID>uuid:000852e6-1040-1040-8997-a36fc6fe83b0</wsa:MessageID>
|
||||
</s:Header>
|
||||
<s:Body>
|
||||
<n1:DeleteVirtualDisk_OUTPUT>
|
||||
<n1:Message>Virtual Disk not found</n1:Message>
|
||||
<n1:MessageID>STOR028</n1:MessageID>
|
||||
<n1:ReturnValue>2</n1:ReturnValue>
|
||||
</n1:DeleteVirtualDisk_OUTPUT>
|
||||
</s:Body>
|
||||
</s:Envelope>
|
@ -0,0 +1,16 @@
|
||||
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
|
||||
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
|
||||
xmlns:n1="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_RAIDService">
|
||||
<s:Header>
|
||||
<wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
|
||||
<wsa:Action>http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_RAIDService/DeleteVirtualDiskResponse</wsa:Action>
|
||||
<wsa:RelatesTo>uuid:fefa06de-103a-103a-8002-fd0aa2bdb228</wsa:RelatesTo>
|
||||
<wsa:MessageID>uuid:05bc00f4-1040-1040-899d-a36fc6fe83b0</wsa:MessageID>
|
||||
</s:Header>
|
||||
<s:Body>
|
||||
<n1:DeleteVirtualDisk_OUTPUT>
|
||||
<n1:RebootRequired>YES</n1:RebootRequired>
|
||||
<n1:ReturnValue>0</n1:ReturnValue>
|
||||
</n1:DeleteVirtualDisk_OUTPUT>
|
||||
</s:Body>
|
||||
</s:Envelope>
|
54
dracclient/tests/wsman_mocks/virtual_disk_view-enum-ok.xml
Normal file
54
dracclient/tests/wsman_mocks/virtual_disk_view-enum-ok.xml
Normal file
@ -0,0 +1,54 @@
|
||||
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
|
||||
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
|
||||
xmlns:wsen="http://schemas.xmlsoap.org/ws/2004/09/enumeration"
|
||||
xmlns:wsman="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"
|
||||
xmlns:n1="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_VirtualDiskView"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<s:Header>
|
||||
<wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
|
||||
<wsa:Action>http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse</wsa:Action>
|
||||
<wsa:RelatesTo>uuid:b182f1ee-103a-103a-8002-fd0aa2bdb228</wsa:RelatesTo>
|
||||
<wsa:MessageID>uuid:b80f21ed-103f-103f-8992-a36fc6fe83b0</wsa:MessageID>
|
||||
</s:Header>
|
||||
<s:Body>
|
||||
<wsen:EnumerateResponse>
|
||||
<wsman:Items>
|
||||
<n1:DCIM_VirtualDiskView>
|
||||
<n1:BlockSizeInBytes>512</n1:BlockSizeInBytes>
|
||||
<n1:BusProtocol>6</n1:BusProtocol>
|
||||
<n1:Cachecade>0</n1:Cachecade>
|
||||
<n1:DeviceDescription>Virtual Disk 0 on Integrated RAID Controller 1</n1:DeviceDescription>
|
||||
<n1:DiskCachePolicy>1024</n1:DiskCachePolicy>
|
||||
<n1:FQDD>Disk.Virtual.0:RAID.Integrated.1-1</n1:FQDD>
|
||||
<n1:InstanceID>Disk.Virtual.0:RAID.Integrated.1-1</n1:InstanceID>
|
||||
<n1:LastSystemInventoryTime>20150301200527.000000+000</n1:LastSystemInventoryTime>
|
||||
<n1:LastUpdateTime>20150301200527.000000+000</n1:LastUpdateTime>
|
||||
<n1:LockStatus>0</n1:LockStatus>
|
||||
<n1:MediaType>1</n1:MediaType>
|
||||
<n1:Name>disk 0</n1:Name>
|
||||
<n1:ObjectStatus>0</n1:ObjectStatus>
|
||||
<n1:OperationName>Background Intialization</n1:OperationName>
|
||||
<n1:OperationPercentComplete>8</n1:OperationPercentComplete>
|
||||
<n1:PendingOperations>0</n1:PendingOperations>
|
||||
<n1:PhysicalDiskIDs xsi:nil="true"/>
|
||||
<n1:PrimaryStatus>1</n1:PrimaryStatus>
|
||||
<n1:RAIDStatus>2</n1:RAIDStatus>
|
||||
<n1:RAIDTypes>4</n1:RAIDTypes>
|
||||
<n1:ReadCachePolicy>16</n1:ReadCachePolicy>
|
||||
<n1:RemainingRedundancy>1</n1:RemainingRedundancy>
|
||||
<n1:RollupStatus>1</n1:RollupStatus>
|
||||
<n1:SizeInBytes>599550590976</n1:SizeInBytes>
|
||||
<n1:SpanDepth>1</n1:SpanDepth>
|
||||
<n1:SpanLength>2</n1:SpanLength>
|
||||
<n1:StartingLBAinBlocks>0</n1:StartingLBAinBlocks>
|
||||
<n1:StripeSize>128</n1:StripeSize>
|
||||
<n1:T10PIStatus>0</n1:T10PIStatus>
|
||||
<n1:VirtualDiskTargetID>0</n1:VirtualDiskTargetID>
|
||||
<n1:WriteCachePolicy>2</n1:WriteCachePolicy>
|
||||
</n1:DCIM_VirtualDiskView>
|
||||
</wsman:Items>
|
||||
<wsen:EnumerationContext/>
|
||||
<wsman:EndOfSequence/>
|
||||
</wsen:EnumerateResponse>
|
||||
</s:Body>
|
||||
</s:Envelope>
|
@ -63,3 +63,32 @@ def get_wsman_resource_attr(doc, resource_uri, attr_name, nullable=False):
|
||||
nil_attr = item.attrib.get('{%s}nil' % NS_XMLSchema_Instance)
|
||||
if nil_attr != 'true':
|
||||
return item.text.strip()
|
||||
|
||||
|
||||
def is_reboot_required(doc, resource_uri):
|
||||
"""Check the response document if reboot is requested.
|
||||
|
||||
RebootRequired attribute in the response indicates whether a config job
|
||||
needs to be created and the node needs to be rebooted, so that the
|
||||
Lifecycle controller can commit the pending changes.
|
||||
|
||||
:param doc: the element tree object.
|
||||
:param resource_uri: the resource URI of the namespace.
|
||||
:returns: a boolean value indicating reboot was requested or not.
|
||||
"""
|
||||
|
||||
reboot_required = find_xml(doc, 'RebootRequired', resource_uri)
|
||||
return reboot_required.text.lower() == 'yes'
|
||||
|
||||
|
||||
def validate_integer_value(value, attr_name, error_msgs):
|
||||
"""Validate integer value"""
|
||||
|
||||
if value is None:
|
||||
error_msgs.append("'%s' is not supplied" % attr_name)
|
||||
return
|
||||
|
||||
try:
|
||||
int(value)
|
||||
except ValueError:
|
||||
error_msgs.append("'%s' is not an integer value" % attr_name)
|
||||
|
Loading…
Reference in New Issue
Block a user