diff --git a/.gitreview b/.gitreview
index ff78bb3..aa50766 100644
--- a/.gitreview
+++ b/.gitreview
@@ -1,4 +1,4 @@
[gerrit]
-host=review.openstack.org
+host=review.opendev.org
port=29418
project=openstack/python-dracclient.git
diff --git a/HACKING.rst b/HACKING.rst
index cd153f3..29aff6c 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -1,4 +1,4 @@
python-dracclient Style Commandments
====================================
-Read the OpenStack Style Commandments http://docs.openstack.org/developer/hacking/
+Read the OpenStack Style Commandments https://docs.openstack.org/hacking/latest/
diff --git a/README.rst b/README.rst
index f956341..b906b5e 100644
--- a/README.rst
+++ b/README.rst
@@ -1,9 +1,18 @@
+========================
+Team and repository tags
+========================
+
+.. image:: https://governance.openstack.org/tc/badges/python-dracclient.svg
+ :target: https://governance.openstack.org/tc/reference/tags/index.html
+
+.. Change things from this point on
+
python-dracclient
=================
Library for managing machines with Dell iDRAC cards.
* Free software: Apache license
-* Documentation: http://docs.openstack.org/developer/python-dracclient
-* Source: http://git.openstack.org/cgit/openstack/python-dracclient
-* Bugs: http://bugs.launchpad.net/python-dracclient
+* Documentation: https://docs.openstack.org/python-dracclient/latest
+* Source: http://opendev.org/openstack/python-dracclient
+* Bugs: https://bugs.launchpad.net/python-dracclient
diff --git a/doc/requirements.txt b/doc/requirements.txt
new file mode 100644
index 0000000..c481145
--- /dev/null
+++ b/doc/requirements.txt
@@ -0,0 +1,6 @@
+# The order of packages is significant, because pip processes them in the order
+# of appearance. Changing the order has an impact on the overall integration
+# process, which may cause wedges in the gate later.
+
+sphinx!=1.6.6,!=1.6.7,!=2.1.0;python_version>='3.4' # BSD
+openstackdocstheme # Apache-2.0
diff --git a/doc/source/conf.py b/doc/source/conf.py
index dddd322..6665e41 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# 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
@@ -22,7 +21,7 @@
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = [
'sphinx.ext.autodoc',
- 'oslosphinx'
+ 'openstackdocstheme'
]
# autodoc generation is a bit aggressive and a nuisance when doing heavy
@@ -56,6 +55,7 @@
# html_theme_path = ["."]
# html_theme = '_theme'
# html_static_path = ['static']
+html_theme = 'openstackdocs'
# Output file base name for HTML help builder.
htmlhelp_basename = '%sdoc' % project
@@ -72,3 +72,6 @@
# Example configuration for intersphinx: refer to the Python standard library.
#intersphinx_mapping = {'http://docs.python.org/': None}
+
+# openstackdocstheme options
+repository_name = 'openstack/python-dracclient'
diff --git a/dracclient/client.py b/dracclient/client.py
index 18d308f..413276d 100644
--- a/dracclient/client.py
+++ b/dracclient/client.py
@@ -16,17 +16,25 @@
"""
import logging
+import subprocess
+import time
+from dracclient import constants
from dracclient import exceptions
from dracclient.resources import bios
+from dracclient.resources import idrac_card
from dracclient.resources import inventory
from dracclient.resources import job
from dracclient.resources import lifecycle_controller
+from dracclient.resources import nic
from dracclient.resources import raid
+from dracclient.resources import system
from dracclient.resources import uris
from dracclient import utils
from dracclient import wsman
+IDRAC_IS_READY = "0"
+
LOG = logging.getLogger(__name__)
@@ -34,9 +42,16 @@ class DRACClient(object):
"""Client for managing DRAC nodes"""
BIOS_DEVICE_FQDD = 'BIOS.Setup.1-1'
-
- def __init__(self, host, username, password, port=443, path='/wsman',
- protocol='https'):
+ IDRAC_FQDD = 'iDRAC.Embedded.1'
+
+ def __init__(
+ self, host, username, password, port=443, path='/wsman',
+ protocol='https',
+ ssl_retries=constants.DEFAULT_WSMAN_SSL_ERROR_RETRIES,
+ ssl_retry_delay=constants.DEFAULT_WSMAN_SSL_ERROR_RETRY_DELAY_SEC,
+ ready_retries=constants.DEFAULT_IDRAC_IS_READY_RETRIES,
+ ready_retry_delay=(
+ constants.DEFAULT_IDRAC_IS_READY_RETRY_DELAY_SEC)):
"""Creates client object
:param host: hostname or IP of the DRAC interface
@@ -45,15 +60,27 @@ def __init__(self, host, username, password, port=443, path='/wsman',
:param port: port for accessing the DRAC interface
:param path: path for accessing the DRAC interface
:param protocol: protocol for accessing the DRAC interface
+ :param ssl_retries: number of resends to attempt on SSL failures
+ :param ssl_retry_delay: number of seconds to wait between
+ retries on SSL failures
+ :param ready_retries: number of times to check if the iDRAC is
+ ready
+ :param ready_retry_delay: number of seconds to wait between
+ checks if the iDRAC is ready
"""
self.client = WSManClient(host, username, password, port, path,
- protocol)
+ protocol, ssl_retries, ssl_retry_delay,
+ ready_retries, ready_retry_delay)
self._job_mgmt = job.JobManagement(self.client)
self._power_mgmt = bios.PowerManagement(self.client)
self._boot_mgmt = bios.BootManagement(self.client)
self._bios_cfg = bios.BIOSConfiguration(self.client)
+ self._lifecycle_cfg = lifecycle_controller.LCConfiguration(self.client)
+ self._idrac_cfg = idrac_card.iDRACCardConfiguration(self.client)
self._raid_mgmt = raid.RAIDManagement(self.client)
+ self._system_cfg = system.SystemConfiguration(self.client)
self._inventory_mgmt = inventory.InventoryManagement(self.client)
+ self._nic_cfg = nic.NICConfiguration(self.client)
def get_power_state(self):
"""Returns the current power state of the node
@@ -147,9 +174,13 @@ def set_bios_settings(self, settings):
:param settings: a dictionary containing the proposed values, with
each key being the name of attribute and the value
being the proposed value.
- :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.
+ :returns: a dictionary containing:
+ - The is_commit_required key with a boolean value indicating
+ whether a config job must be created for the values to be
+ applied.
+ - The is_reboot_required key with a RebootRequired enumerated
+ value indicating whether the server must be rebooted for the
+ values to be applied. Possible values are true and false.
:raises: WSManRequestFailure on request failures
:raises: WSManInvalidResponse when receiving invalid response
:raises: DRACOperationFailed on error reported back by the DRAC
@@ -159,6 +190,270 @@ def set_bios_settings(self, settings):
"""
return self._bios_cfg.set_bios_settings(settings)
+ def list_idrac_settings(self, by_name=False, fqdd_filter=IDRAC_FQDD):
+ """List the iDRAC configuration settings
+
+ :param by_name: Controls whether returned dictionary uses iDRAC card
+ attribute name as key. If set to False, instance_id
+ will be used. If set to True the keys will be of the
+ form "group_id#name".
+ :param fqdd_filter: An FQDD used to filter the instances. Note that
+ this is only used when by_name is True.
+ :returns: a dictionary with the iDRAC settings using instance_id as the
+ key except when by_name is True. The attributes are either
+ iDRACCardEnumerableAttribute, iDRACCardStringAttribute or
+ iDRACCardIntegerAttribute objects.
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the DRAC
+ interface
+ """
+ return self._idrac_cfg.list_idrac_settings(by_name=by_name,
+ fqdd_filter=fqdd_filter)
+
+ def set_idrac_settings(self, settings, idrac_fqdd=IDRAC_FQDD):
+ """Sets the iDRAC configuration settings
+
+ To be more precise, it sets the pending_value parameter for each of the
+ attributes passed in. For the values to be applied, a config job may
+ need to be created and the node may need to be rebooted.
+
+ :param settings: a dictionary containing the proposed values, with
+ each key being the name of attribute qualified with
+ the group ID in the form "group_id#name" and the value
+ being the proposed value.
+ :param idrac_fqdd: the FQDD of the iDRAC.
+ :returns: a dictionary containing:
+ - The is_commit_required key with a boolean value indicating
+ whether a config job must be created for the values to be
+ applied.
+ - The is_reboot_required key with a RebootRequired enumerated
+ value indicating whether the server must be rebooted for the
+ values to be applied. Possible values are true and false.
+ :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 attribute
+ """
+ return self._idrac_cfg.set_idrac_settings(settings, idrac_fqdd)
+
+ def reset_idrac(self, force=False, wait=False,
+ ready_wait_time=30):
+ """Resets the iDRAC and optionally block until reset is complete.
+
+ :param force: does a force reset when True and a graceful reset when
+ False
+ :param wait: returns immediately after reset if False, or waits
+ for the iDRAC to return to operational state if True
+ :param ready_wait_time: the amount of time in seconds to wait after
+ the reset before starting to check on the iDRAC's status
+ :returns: True on success, raises exception on failure
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on failure to reset iDRAC
+ """
+ return_value = self._idrac_cfg.reset_idrac(force)
+ if not wait and return_value:
+ return return_value
+
+ if not return_value:
+ raise exceptions.DRACOperationFailed(
+ drac_messages="Failed to reset iDRAC")
+
+ LOG.debug("iDRAC was reset, waiting for return to operational state")
+
+ state_reached = self._wait_for_host_state(
+ self.client.host,
+ alive=False,
+ ping_count=2,
+ retries=24)
+
+ if not state_reached:
+ raise exceptions.DRACOperationFailed(
+ drac_messages="Timed out waiting for the %s iDRAC to become "
+ "not pingable" % self.client.host)
+
+ LOG.info("The iDRAC has become not pingable")
+
+ state_reached = self._wait_for_host_state(
+ self.client.host,
+ alive=True,
+ ping_count=3,
+ retries=24)
+
+ if not state_reached:
+ raise exceptions.DRACOperationFailed(
+ drac_messages="Timed out waiting for the %s iDRAC to become "
+ "pingable" % self.client.host)
+
+ LOG.info("The iDRAC has become pingable")
+ LOG.info("Waiting for the iDRAC to become ready")
+ time.sleep(ready_wait_time)
+
+ self.client.wait_until_idrac_is_ready()
+
+ def _ping_host(self, host):
+ response = subprocess.call(
+ "ping -c 1 {} 2>&1 1>/dev/null".format(host), shell=True)
+ return (response == 0)
+
+ def _wait_for_host_state(self,
+ host,
+ alive=True,
+ ping_count=3,
+ retries=24):
+ if alive:
+ ping_type = "pingable"
+
+ else:
+ ping_type = "not pingable"
+
+ LOG.info("Waiting for the iDRAC to become %s", ping_type)
+
+ response_count = 0
+ state_reached = False
+
+ while retries > 0 and not state_reached:
+ response = self._ping_host(host)
+ retries -= 1
+ if response == alive:
+ response_count += 1
+ LOG.debug("The iDRAC is %s, count=%s",
+ ping_type,
+ response_count)
+ if response_count == ping_count:
+ LOG.debug("Reached specified ping count")
+ state_reached = True
+ else:
+ response_count = 0
+ if alive:
+ LOG.debug("The iDRAC is still not pingable")
+ else:
+ LOG.debug("The iDRAC is still pingable")
+ time.sleep(10)
+
+ return state_reached
+
+ def commit_pending_idrac_changes(
+ self,
+ idrac_fqdd=IDRAC_FQDD,
+ reboot=False,
+ start_time='TIME_NOW'):
+ """Create a config job for applying all pending iDRAC changes.
+
+ :param idrac_fqdd: the FQDD of the iDRAC.
+ :param reboot: indication of whether to also create a reboot job
+ :param start_time: start time for job execution in format
+ yyyymmddhhmmss, the string 'TIME_NOW' which
+ means execute immediately or None which means
+ the job will not execute until
+ schedule_job_execution is called
+ :returns: id of the created configuration job
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the iDRAC
+ interface
+ :raises: DRACUnexpectedReturnValue on return value mismatch
+ """
+ return self._job_mgmt.create_config_job(
+ resource_uri=uris.DCIM_iDRACCardService,
+ cim_creation_class_name='DCIM_iDRACCardService',
+ cim_name='DCIM:iDRACCardService',
+ target=idrac_fqdd,
+ reboot=reboot,
+ start_time=start_time)
+
+ def abandon_pending_idrac_changes(self, idrac_fqdd=IDRAC_FQDD):
+ """Abandon all pending changes to an iDRAC
+
+ Once a config job has been submitted, it can no longer be abandoned.
+
+ :param idrac_fqdd: the FQDD of the iDRAC.
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the iDRAC
+ interface
+ :raises: DRACUnexpectedReturnValue on return value mismatch
+ """
+ self._job_mgmt.delete_pending_config(
+ resource_uri=uris.DCIM_iDRACCardService,
+ cim_creation_class_name='DCIM_iDRACCardService',
+ cim_name='DCIM:iDRACCardService',
+ target=idrac_fqdd)
+
+ def list_lifecycle_settings(self, by_name=False):
+ """List the Lifecycle Controller configuration settings
+
+ :param by_name: Controls whether returned dictionary uses Lifecycle
+ attribute name as key. If set to False, instance_id
+ will be used.
+ :returns: a dictionary with the Lifecycle Controller settings using its
+ InstanceID as the key. The attributes are either
+ LCEnumerableAttribute or LCStringAttribute objects.
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the DRAC
+ interface
+ """
+ return self._lifecycle_cfg.list_lifecycle_settings(by_name)
+
+ def is_lifecycle_in_recovery(self):
+ """Checks if Lifecycle Controller in recovery mode or not
+
+ This method checks the LCStatus value to determine if lifecycle
+ controller is in recovery mode by invoking GetRemoteServicesAPIStatus
+ from iDRAC.
+
+ :returns: a boolean indicating if lifecycle controller is in recovery
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the DRAC
+ interface
+ """
+
+ return self._lifecycle_cfg.is_lifecycle_in_recovery()
+
+ def set_lifecycle_settings(self, settings):
+ """Sets lifecycle controller configuration
+
+ It sets the pending_value parameter for each of the attributes
+ passed in. For the values to be applied, a config job must
+ be created.
+
+ :param settings: a dictionary containing the proposed values, with
+ each key being the name of attribute and the value
+ being the proposed value.
+ :returns: a dictionary containing:
+ - The is_commit_required key with a boolean value indicating
+ whether a config job must be created for the values to be
+ applied.
+ - The is_reboot_required key with a RebootRequired enumerated
+ value indicating whether the server must be rebooted for the
+ values to be applied. Possible values are true and false.
+ :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 Lifecycle attribute
+ """
+ return self._lifecycle_cfg.set_lifecycle_settings(settings)
+
+ def list_system_settings(self):
+ """List the System configuration settings
+
+ :returns: a dictionary with the System settings using its instance id
+ as key. The attributes are either SystemEnumerableAttribute,
+ SystemStringAttribute or SystemIntegerAttribute objects.
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the DRAC
+ interface
+ """
+ return self._system_cfg.list_system_settings()
+
def list_jobs(self, only_unfinished=False):
"""Returns a list of jobs from the job queue
@@ -184,12 +479,40 @@ def get_job(self, job_id):
"""
return self._job_mgmt.get_job(job_id)
- def create_config_job(self, resource_uri, cim_creation_class_name,
- cim_name, target,
+ def delete_jobs(self, job_ids=['JID_CLEARALL']):
+ """Deletes the given jobs, or all jobs if none specified
+
+ :param job_ids: a list of job ids to delete. Clearing all the
+ jobs may be accomplished using the keyword JID_CLEARALL
+ as the job_id, or JID_CLEARALL_FORCE if a job is in
+ Scheduled state and there is another job for the same
+ component in Completed or Failed state,
+ (http://en.community.dell.com/techcenter/extras/m/white_papers/20444501/download)
+ Deletion of each job id will be attempted, even if there
+ are errors in deleting any in the list.
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the iDRAC
+ interface. There will be one message for each job_id
+ that had a failure in the exception.
+ :raises: DRACUnexpectedReturnValue on non-success
+ """
+
+ return self._job_mgmt.delete_jobs(job_ids)
+
+ def create_config_job(self,
+ resource_uri,
+ cim_creation_class_name,
+ cim_name,
+ target,
cim_system_creation_class_name='DCIM_ComputerSystem',
cim_system_name='DCIM:ComputerSystem',
- reboot=False):
- """Creates a config job
+ reboot=False,
+ start_time='TIME_NOW',
+ realtime=False,
+ wait_for_idrac=True,
+ method_name='CreateTargetedConfigJob'):
+ """Creates a configuration job.
In CIM (Common Information Model), weak association is used to name an
instance of one class in the context of an instance of another class.
@@ -205,18 +528,99 @@ def create_config_job(self, resource_uri, cim_creation_class_name,
:param cim_system_creation_class_name: creation class name of the
scoping system
:param cim_system_name: name of the scoping system
- :param reboot: indicates whether a RebootJob should also be
- created or not
+ :param reboot: indicates whether or not a RebootJob should also be
+ created
+ :param start_time: start time for job execution in format
+ yyyymmddhhmmss, the string 'TIME_NOW' which
+ means execute immediately or None which means
+ the job will not execute until
+ schedule_job_execution is called
+ :param realtime: Indicates if reatime mode should be used.
+ Valid values are True and False.
+ :param wait_for_idrac: indicates whether or not to wait for the
+ iDRAC to be ready to accept commands before
+ issuing the command.
+ :param method_name: method of CIM object to invoke
: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
+ :raises: DRACOperationFailed on error reported back by the iDRAC
interface
:raises: DRACUnexpectedReturnValue on return value mismatch
"""
+
return self._job_mgmt.create_config_job(
- resource_uri, cim_creation_class_name, cim_name, target,
- cim_system_creation_class_name, cim_system_name, reboot)
+ resource_uri=resource_uri,
+ cim_creation_class_name=cim_creation_class_name,
+ cim_name=cim_name,
+ target=target,
+ cim_system_creation_class_name=cim_system_creation_class_name,
+ cim_system_name=cim_system_name,
+ reboot=reboot,
+ start_time=start_time,
+ realtime=realtime,
+ wait_for_idrac=wait_for_idrac,
+ method_name=method_name)
+
+ def create_nic_config_job(
+ self,
+ nic_id,
+ reboot=False,
+ start_time='TIME_NOW'):
+ """Creates config job for applying pending changes to a NIC.
+
+ :param nic_id: id of the network interface controller (NIC)
+ :param reboot: indication of whether to also create a reboot job
+ :param start_time: start time for job execution in format
+ yyyymmddhhmmss; the string 'TIME_NOW' means
+ immediately and None means unspecified
+ :returns: id of the created configuration job
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the iDRAC
+ interface
+ :raises: DRACUnexpectedReturnValue on return value mismatch
+ """
+ return self._job_mgmt.create_config_job(
+ resource_uri=uris.DCIM_NICService,
+ cim_creation_class_name='DCIM_NICService',
+ cim_name='DCIM:NICService',
+ target=nic_id,
+ reboot=reboot,
+ start_time=start_time)
+
+ def create_reboot_job(
+ self,
+ reboot_type=constants.RebootJobType.reboot_forced_shutdown):
+ """Creates a reboot job.
+
+ :param reboot_type: type of reboot
+ :returns id of the created job
+ :raises: InvalidParameterValue on invalid reboot type
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the iDRAC
+ interface
+ :raises: DRACUnexpectedReturnValue on return value mismatch
+ """
+ return self._job_mgmt.create_reboot_job(reboot_type)
+
+ def schedule_job_execution(self, job_ids, start_time='TIME_NOW'):
+ """Schedules jobs for execution in a specified order.
+
+ :param job_ids: list of job identifiers
+ :param start_time: start time for job execution in format
+ yyyymmddhhmmss or the string 'TIME_NOW' which
+ means execute immediately. None is not a
+ valid option for this request.
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the iDRAC
+ interface, including start_time being in the past or
+ badly formatted start_time
+ :raises: DRACUnexpectedReturnValue on return value mismatch
+ """
+ return self._job_mgmt.schedule_job_execution(job_ids, start_time)
def delete_pending_config(
self, resource_uri, cim_creation_class_name, cim_name, target,
@@ -250,23 +654,34 @@ def delete_pending_config(
resource_uri, cim_creation_class_name, cim_name, target,
cim_system_creation_class_name, cim_system_name)
- def commit_pending_bios_changes(self, reboot=False):
+ def commit_pending_bios_changes(
+ self,
+ reboot=False,
+ start_time='TIME_NOW'):
"""Applies all pending changes on the BIOS by creating a config job
:param reboot: indicates whether a RebootJob should also be
created or not
+ :param start_time: start time for job execution in format
+ yyyymmddhhmmss, the string 'TIME_NOW' which
+ means execute immediately or None which means
+ the job will not execute until
+ schedule_job_execution is called
: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
+ interface, including start_time being in the past or
+ badly formatted start_time
:raises: DRACUnexpectedReturnValue on return value mismatch
"""
return self._job_mgmt.create_config_job(
resource_uri=uris.DCIM_BIOSService,
cim_creation_class_name='DCIM_BIOSService',
- cim_name='DCIM:BIOSService', target=self.BIOS_DEVICE_FQDD,
- reboot=reboot)
+ cim_name='DCIM:BIOSService',
+ target=self.BIOS_DEVICE_FQDD,
+ reboot=reboot,
+ start_time=start_time)
def abandon_pending_bios_changes(self):
"""Deletes all pending changes on the BIOS
@@ -284,6 +699,37 @@ def abandon_pending_bios_changes(self):
cim_creation_class_name='DCIM_BIOSService',
cim_name='DCIM:BIOSService', target=self.BIOS_DEVICE_FQDD)
+ def commit_pending_lifecycle_changes(
+ self,
+ reboot=False,
+ start_time='TIME_NOW'):
+ """Applies all pending changes on Lifecycle by creating a config job
+
+ :param reboot: indicates whether a RebootJob should also be
+ created or not
+ :param start_time: start time for job execution in format
+ yyyymmddhhmmss, the string 'TIME_NOW' which
+ means execute immediately or None which means
+ the job will not execute until
+ schedule_job_execution is called
+ :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, including start_time being in the past or
+ badly formatted start_time
+ :raises: DRACUnexpectedReturnValue on return value mismatch
+ """
+ return self._job_mgmt.create_config_job(
+ resource_uri=uris.DCIM_LCService,
+ cim_creation_class_name='DCIM_LCService',
+ cim_name='DCIM:LCService',
+ target='',
+ reboot=reboot,
+ start_time=start_time,
+ wait_for_idrac=False,
+ method_name='CreateConfigJob')
+
def get_lifecycle_controller_version(self):
"""Returns the Lifecycle controller version
@@ -307,6 +753,43 @@ def list_raid_controllers(self):
"""
return self._raid_mgmt.list_raid_controllers()
+ def list_raid_settings(self):
+ """List the RAID configuration settings
+
+ :returns: a dictionary with the RAID settings using InstanceID as the
+ key. The attributes are either RAIDEnumerableAttribute,
+ RAIDStringAttribute 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_settings()
+
+ def set_raid_settings(self, raid_fqdd, settings):
+ """Sets the RAID configuration
+
+ It sets the pending_value parameter for each of the attributes
+ passed in. For the values to be applied, a config job must
+ be created.
+ :param raid_fqdd: the FQDD of the RAID setting.
+ :param settings: a dictionary containing the proposed values, with
+ each key being the name of attribute and the value
+ being the proposed value.
+ :returns: a dictionary containing:
+ - The is_commit_required key with a boolean value indicating
+ whether a config job must be created for the values to be
+ applied.
+ - The is_reboot_required key with a RebootRequired enumerated
+ value indicating whether the server must be rebooted for the
+ values to be applied. Possible values are true and false.
+ :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.set_raid_settings(raid_fqdd, settings)
+
def list_virtual_disks(self):
"""Returns the list of RAID arrays
@@ -341,12 +824,16 @@ def convert_physical_disks(self, raid_controller, physical_disks,
:param raid_enable: boolean flag, set to True if the disk is to
become part of the RAID. The same flag is applied to all
listed disks
- :returns: a dictionary containing the commit_required key with a
- boolean value indicating whether a config job must be
- created for the values to be applied.
+ :returns: a dictionary containing:
+ - The is_commit_required key with the value always set to
+ True indicating that a config job must be created to
+ complete disk conversion.
+ - The is_reboot_required key with a RebootRequired enumerated
+ value indicating whether the server must be rebooted to
+ complete disk conversion.
"""
- return self._raid_mgmt.convert_physical_disks(
- physical_disks, raid_enable)
+ return self._raid_mgmt.convert_physical_disks(physical_disks,
+ raid_enable)
def create_virtual_disk(self, raid_controller, physical_disks, raid_level,
size_mb, disk_name=None, span_length=None,
@@ -362,9 +849,13 @@ def create_virtual_disk(self, raid_controller, physical_disks, raid_level,
: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.
+ :returns: a dictionary containing:
+ - The is_commit_required key with the value always set to
+ True indicating that a config job must be created to
+ complete virtual disk creation.
+ - The is_reboot_required key with a RebootRequired enumerated
+ value indicating whether the server must be rebooted to
+ complete virtual disk creation.
:raises: WSManRequestFailure on request failures
:raises: WSManInvalidResponse when receiving invalid response
:raises: DRACOperationFailed on error reported back by the DRAC
@@ -383,9 +874,13 @@ def delete_virtual_disk(self, virtual_disk):
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.
+ :returns: a dictionary containing:
+ - The is_commit_required key with the value always set to
+ True indicating that a config job must be created to
+ complete virtual disk deletion.
+ - The is_reboot_required key with a RebootRequired enumerated
+ value indicating whether the server must be rebooted to
+ complete virtual disk deletion.
:raises: WSManRequestFailure on request failures
:raises: WSManInvalidResponse when receiving invalid response
:raises: DRACOperationFailed on error reported back by the DRAC
@@ -394,7 +889,52 @@ def delete_virtual_disk(self, virtual_disk):
"""
return self._raid_mgmt.delete_virtual_disk(virtual_disk)
- def commit_pending_raid_changes(self, raid_controller, reboot=False):
+ def reset_raid_config(self, raid_controller):
+ """Delete all the virtual disks and unassign all hot spare physical disks
+
+ The job to reset the RAID controller config will be in pending state.
+ For the changes to be applied, a config job must be created.
+
+ :param raid_controller: id of the RAID controller
+ :returns: a dictionary containing:
+ - The is_commit_required key with the value always set to
+ True indicating that a config job must be created to
+ reset configuration.
+ - The is_reboot_required key with a RebootRequired enumerated
+ value indicating whether the server must be rebooted to
+ reset configuration.
+ :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.reset_raid_config(raid_controller)
+
+ def clear_foreign_config(self, raid_controller):
+ """Free up foreign drives
+
+ The job to clear foreign config will be in pending state.
+ For the changes to be applied, a config job must be created.
+
+ :param raid_controller: id of the RAID controller
+ :returns: a dictionary containing:
+ - The is_commit_required key with the value always set to
+ True indicating that a config job must be created to
+ clear foreign configuration.
+ - The is_reboot_required key with a RebootRequired enumerated
+ value indicating whether the server must be rebooted to
+ clear foreign configuration.
+ :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.clear_foreign_config(raid_controller)
+
+ def commit_pending_raid_changes(self, raid_controller, reboot=False,
+ start_time='TIME_NOW', realtime=False):
"""Applies all pending changes on a RAID controller
...by creating a config job.
@@ -402,6 +942,13 @@ def commit_pending_raid_changes(self, raid_controller, reboot=False):
:param raid_controller: id of the RAID controller
:param reboot: indicates whether a RebootJob should also be
created or not
+ :param start_time: start time for job execution in format
+ yyyymmddhhmmss, the string 'TIME_NOW' which
+ means execute immediately or None which means
+ the job will not execute until
+ schedule_job_execution is called
+ :param realtime: Indicates if reatime mode should be used.
+ Valid values are True and False.
:returns: id of the created job
:raises: WSManRequestFailure on request failures
:raises: WSManInvalidResponse when receiving invalid response
@@ -412,7 +959,11 @@ def commit_pending_raid_changes(self, raid_controller, reboot=False):
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)
+ cim_name='DCIM:RAIDService',
+ target=raid_controller,
+ reboot=reboot,
+ start_time=start_time,
+ realtime=realtime)
def abandon_pending_raid_changes(self, raid_controller):
"""Deletes all pending changes on a RAID controller
@@ -431,6 +982,14 @@ def abandon_pending_raid_changes(self, raid_controller):
cim_creation_class_name='DCIM_RAIDService',
cim_name='DCIM:RAIDService', target=raid_controller)
+ def is_realtime_supported(self, raid_controller):
+ """Find if controller supports realtime or not
+
+ :param raid_controller: ID of RAID controller
+ :returns: True or False
+ """
+ return self._raid_mgmt.is_realtime_supported(raid_controller)
+
def list_cpus(self):
"""Returns the list of CPUs
@@ -454,9 +1013,10 @@ def list_memory(self):
return self._inventory_mgmt.list_memory()
- def list_nics(self):
+ def list_nics(self, sort=False):
"""Returns a list of NICs
+ :param sort: indicates if the list should be sorted or not.
:returns: a list of NIC objects
:raises: WSManRequestFailure on request failures
:raises: WSManInvalidResponse when receiving invalid response
@@ -464,14 +1024,249 @@ def list_nics(self):
interface
"""
- return self._inventory_mgmt.list_nics()
+ return self._inventory_mgmt.list_nics(sort=sort)
+
+ def list_nic_settings(self, nic_id):
+ """Return the list of attribute settings of a NIC.
+
+ :param nic_id: id of the network interface controller (NIC)
+ :returns: dictionary containing the NIC settings. The keys are
+ attribute names. Each value is a
+ NICEnumerationAttribute, NICIntegerAttribute, or
+ NICStringAttribute object.
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the iDRAC
+ interface
+ """
+ return self._nic_cfg.list_nic_settings(nic_id)
+
+ def set_nic_settings(self, nic_id, settings):
+ """Modify one or more settings of a NIC.
+
+ If successful, the pending values of the attributes are set. For
+ the new values to be applied, a configuration job must be
+ created and the node must be rebooted.
+
+ :param nic_id: id of the network interface controller (NIC)
+ :param settings: dictionary containing the proposed values, with
+ each key being the name of an attribute and the
+ value being the proposed value
+ :returns: dictionary containing:
+ - The is_commit_required key with a boolean value
+ indicating whether a config job must be created for
+ the values to be applied.
+ - The is_reboot_required key with a RebootRequired
+ enumerated value indicating whether the server must
+ be rebooted 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 iDRAC
+ interface
+ :raises: InvalidParameterValue on invalid NIC attribute
+ """
+ return self._nic_cfg.set_nic_settings(nic_id, settings)
+
+ def get_system(self):
+ """Return a Systen object.
+
+ :returns: a System object
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ """
+ return self._inventory_mgmt.get_system()
+
+ def is_idrac_ready(self):
+ """Indicates if the iDRAC is ready to accept commands
+
+ Returns a boolean indicating if the iDRAC is ready to accept
+ commands.
+
+ :returns: Boolean indicating iDRAC readiness
+ :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.client.is_idrac_ready()
+
+ def wait_until_idrac_is_ready(self, retries=None, retry_delay=None):
+ """Waits until the iDRAC is in a ready state
+
+ :param retries: The number of times to check if the iDRAC is
+ ready. If None, the value of ready_retries that
+ was provided when the object was created is
+ used.
+ :param retry_delay: The number of seconds to wait between
+ retries. If None, the value of
+ ready_retry_delay that was provided
+ when the object was created is used.
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the DRAC
+ interface or timeout
+ :raises: DRACUnexpectedReturnValue on return value mismatch
+ """
+
+ return self.client.wait_until_idrac_is_ready(retries, retry_delay)
+
+ def is_jbod_capable(self, raid_controller_fqdd):
+ """Find out if raid controller supports jbod
+
+ :param raid_controller_fqdd: The raid controller's fqdd
+ being checked to see if it is jbod
+ capable.
+ :raises: DRACRequestFailed if unable to find any disks in the Ready
+ or non-RAID states
+ :raises: DRACOperationFailed on error reported back by the DRAC
+ and the exception message does not contain
+ NOT_SUPPORTED_MSG constant
+ """
+ return self._raid_mgmt.is_jbod_capable(raid_controller_fqdd)
+
+ def is_raid_controller(self, raid_controller_fqdd, raid_controllers=None):
+ """Determine if the given controller is a RAID controller
+
+ Since a BOSS controller is a type of RAID controller, this method will
+ return True for both BOSS and RAID controllers.
+
+ :param raid_controller_fqdd: The object's fqdd we are testing to see
+ if it is a raid controller or not.
+ :param raid_controllers: A list of RAIDControllers used to check for
+ the presence of BOSS cards. If None, the
+ iDRAC will be queried for the list of
+ controllers.
+ :returns: boolean, True if the device is a RAID controller,
+ False if not.
+ """
+ return self._raid_mgmt.is_raid_controller(raid_controller_fqdd,
+ raid_controllers)
+
+ def is_boss_controller(self, raid_controller_fqdd, raid_controllers=None):
+ """Find out if a RAID controller a BOSS card or not
+
+ :param raid_controller_fqdd: The object's fqdd we are testing to see
+ if it is a BOSS card or not.
+ :param raid_controllers: A list of RAIDController to scan for presence
+ of BOSS card, if None the drac will be queried
+ for the list of controllers which will then be
+ scanned.
+ :returns: boolean, True if the device is a BOSS card, False if not.
+ :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.is_boss_controller(raid_controller_fqdd,
+ raid_controllers)
+
+ def change_physical_disk_state(self, mode,
+ controllers_to_physical_disk_ids=None):
+ """Convert disks RAID status
+
+ This method intelligently converts the requested physical disks from
+ RAID to JBOD or vice versa. It does this by only converting the
+ disks that are not already in the correct state.
+
+ :param mode: constants.RaidStatus enumeration that indicates the mode
+ to change the disks to.
+ :param controllers_to_physical_disk_ids: Dictionary of controllers and
+ corresponding disk ids to convert to the requested mode.
+ :returns: a dictionary containing:
+ - conversion_results, a dictionary that maps controller ids
+ to the conversion results for that controller. The
+ conversion results are a dict that contains:
+ - The is_commit_required key with the value always set to
+ True indicating that a config job must be created to
+ complete disk conversion.
+ - The is_reboot_required key with a RebootRequired
+ enumerated value indicating whether the server must be
+ rebooted to complete disk conversion.
+ :raises: DRACOperationFailed on error reported back by the DRAC and the
+ exception message does not contain NOT_SUPPORTED_MSG constant.
+ :raises: Exception on unknown error.
+ """
+ return (self._raid_mgmt
+ .change_physical_disk_state(mode,
+ controllers_to_physical_disk_ids))
class WSManClient(wsman.Client):
- """Wrapper for wsman.Client with return value checking"""
+ """Wrapper for wsman.Client that can wait until iDRAC is ready
+
+ Additionally, the Invoke operation offers return value checking.
+ """
+
+ def __init__(
+ self, host, username, password, port=443, path='/wsman',
+ protocol='https',
+ ssl_retries=constants.DEFAULT_WSMAN_SSL_ERROR_RETRIES,
+ ssl_retry_delay=constants.DEFAULT_WSMAN_SSL_ERROR_RETRY_DELAY_SEC,
+ ready_retries=constants.DEFAULT_IDRAC_IS_READY_RETRIES,
+ ready_retry_delay=(
+ constants.DEFAULT_IDRAC_IS_READY_RETRY_DELAY_SEC)):
+ """Creates client object
- def invoke(self, resource_uri, method, selectors=None, properties=None,
- expected_return_value=None):
+ :param host: hostname or IP of the DRAC interface
+ :param username: username for accessing the DRAC interface
+ :param password: password for accessing the DRAC interface
+ :param port: port for accessing the DRAC interface
+ :param path: path for accessing the DRAC interface
+ :param protocol: protocol for accessing the DRAC interface
+ :param ssl_retries: number of resends to attempt on SSL failures
+ :param ssl_retry_delay: number of seconds to wait between
+ retries on SSL failures
+ :param ready_retries: number of times to check if the iDRAC is
+ ready
+ :param ready_retry_delay: number of seconds to wait between
+ checks if the iDRAC is ready
+ """
+ super(WSManClient, self).__init__(host, username, password,
+ port, path, protocol, ssl_retries,
+ ssl_retry_delay)
+
+ self._ready_retries = ready_retries
+ self._ready_retry_delay = ready_retry_delay
+
+ def enumerate(self, resource_uri, optimization=True, max_elems=100,
+ auto_pull=True, filter_query=None, filter_dialect='cql',
+ wait_for_idrac=True):
+ """Executes enumerate operation over WS-Man
+
+ :param resource_uri: URI of resource to enumerate
+ :param optimization: flag to enable enumeration optimization. If
+ disabled, the enumeration returns only an
+ enumeration context.
+ :param max_elems: maximum number of elements returned by the operation
+ :param auto_pull: flag to enable automatic pull on the enumeration
+ context, merging the items returned
+ :param filter_query: filter query string
+ :param filter_dialect: filter dialect. Valid options are: 'cql' and
+ 'wql'.
+ :param wait_for_idrac: indicates whether or not to wait for the
+ iDRAC to be ready to accept commands before issuing the
+ command
+ :returns: an lxml.etree.Element object of the response received
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ """
+ if wait_for_idrac:
+ self.wait_until_idrac_is_ready()
+
+ return super(WSManClient, self).enumerate(resource_uri, optimization,
+ max_elems, auto_pull,
+ filter_query, filter_dialect)
+
+ def invoke(self,
+ resource_uri,
+ method,
+ selectors=None,
+ properties=None,
+ expected_return_value=None,
+ wait_for_idrac=True,
+ check_return_value=True):
"""Invokes a remote WS-Man method
:param resource_uri: URI of the resource
@@ -482,6 +1277,11 @@ def invoke(self, resource_uri, method, selectors=None, properties=None,
the DRAC card. For return value codes check the profile
documentation of the resource used in the method call. If not set,
return value checking is skipped.
+ :param wait_for_idrac: indicates whether or not to wait for the
+ iDRAC to be ready to accept commands before issuing the
+ command
+ :param check_return_value: indicates if the ReturnValue should be
+ checked and an exception thrown on an unexpected value
:returns: an lxml.etree.Element object of the response received
:raises: WSManRequestFailure on request failures
:raises: WSManInvalidResponse when receiving invalid response
@@ -489,6 +1289,9 @@ def invoke(self, resource_uri, method, selectors=None, properties=None,
interface
:raises: DRACUnexpectedReturnValue on return value mismatch
"""
+ if wait_for_idrac:
+ self.wait_until_idrac_is_ready()
+
if selectors is None:
selectors = {}
@@ -498,16 +1301,94 @@ def invoke(self, resource_uri, method, selectors=None, properties=None,
resp = super(WSManClient, self).invoke(resource_uri, method, selectors,
properties)
- return_value = utils.find_xml(resp, 'ReturnValue', resource_uri).text
- if return_value == utils.RET_ERROR:
- message_elems = utils.find_xml(resp, 'Message', resource_uri, True)
- messages = [message_elem.text for message_elem in message_elems]
- raise exceptions.DRACOperationFailed(drac_messages=messages)
-
- if (expected_return_value is not None and
- return_value != expected_return_value):
- raise exceptions.DRACUnexpectedReturnValue(
- expected_return_value=expected_return_value,
- actual_return_value=return_value)
+ if check_return_value:
+ return_value = utils.find_xml(resp, 'ReturnValue',
+ resource_uri).text
+ if return_value == utils.RET_ERROR:
+ message_elems = utils.find_xml(resp, 'Message',
+ resource_uri, True)
+ messages = [message_elem.text for message_elem in
+ message_elems]
+ raise exceptions.DRACOperationFailed(drac_messages=messages)
+
+ if (expected_return_value is not None
+ and return_value != expected_return_value):
+ raise exceptions.DRACUnexpectedReturnValue(
+ expected_return_value=expected_return_value,
+ actual_return_value=return_value)
return resp
+
+ def is_idrac_ready(self):
+ """Indicates if the iDRAC is ready to accept commands
+
+ Returns a boolean indicating if the iDRAC is ready to accept
+ commands.
+
+ :returns: Boolean indicating iDRAC readiness
+ :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',
+ 'SystemName': 'DCIM:ComputerSystem',
+ 'CreationClassName': 'DCIM_LCService',
+ 'Name': 'DCIM:LCService'}
+
+ result = self.invoke(uris.DCIM_LCService,
+ 'GetRemoteServicesAPIStatus',
+ selectors,
+ {},
+ expected_return_value=utils.RET_SUCCESS,
+ wait_for_idrac=False)
+
+ lc_status = utils.find_xml(result,
+ 'LCStatus',
+ uris.DCIM_LCService).text
+
+ return lc_status == IDRAC_IS_READY
+
+ def wait_until_idrac_is_ready(self, retries=None, retry_delay=None):
+ """Waits until the iDRAC is in a ready state
+
+ :param retries: The number of times to check if the iDRAC is
+ ready. If None, the value of ready_retries that
+ was provided when the object was created is
+ used.
+ :param retry_delay: The number of seconds to wait between
+ retries. If None, the value of
+ ready_retry_delay that was provided when the
+ object was created is used.
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the DRAC
+ interface or timeout
+ :raises: DRACUnexpectedReturnValue on return value mismatch
+ """
+
+ if retries is None:
+ retries = self._ready_retries
+
+ if retry_delay is None:
+ retry_delay = self._ready_retry_delay
+
+ # Try every 10 seconds over 4 minutes for the iDRAC to become ready
+ while retries > 0:
+ LOG.debug("Checking to see if the iDRAC is ready")
+
+ if self.is_idrac_ready():
+ LOG.debug("The iDRAC is ready")
+ return
+
+ LOG.debug("The iDRAC is not ready")
+ retries -= 1
+ if retries > 0:
+ time.sleep(retry_delay)
+
+ if retries == 0:
+ err_msg = "Timed out waiting for the iDRAC to become ready"
+ LOG.error(err_msg)
+ raise exceptions.DRACOperationFailed(drac_messages=err_msg)
diff --git a/dracclient/constants.py b/dracclient/constants.py
index 5705d76..ecaffa1 100644
--- a/dracclient/constants.py
+++ b/dracclient/constants.py
@@ -11,6 +11,17 @@
# License for the specific language governing permissions and limitations
# under the License.
+# iDRAC is ready retry constants
+DEFAULT_IDRAC_IS_READY_RETRIES = 96
+DEFAULT_IDRAC_IS_READY_RETRY_DELAY_SEC = 10
+
+# Web Services Management (WS-Management and WS-Man) SSL retry on error
+# behavior constants
+DEFAULT_WSMAN_SSL_ERROR_RETRIES = 3
+DEFAULT_WSMAN_SSL_ERROR_RETRY_DELAY_SEC = 0
+
+NOT_SUPPORTED_MSG = " operation is not supported on th"
+
# power states
POWER_ON = 'POWER_ON'
POWER_OFF = 'POWER_OFF'
@@ -25,3 +36,58 @@
# binary unit constants
UNITS_KI = 2 ** 10
+
+# Lifecycle Controller status constant
+LC_IN_RECOVERY = '4'
+
+
+# Reboot required indicator
+# Note: When the iDRAC returns optional for this value, this indicates that
+# either a reboot may be performed to complete the operation or a real time
+# config job may be created to complete the operation without performing a
+# reboot. This library does not currently support creating a real time config
+# job, so a reboot must be performed when a value of "optional" is returned.
+class RebootRequired(object):
+ true = 'true'
+ optional = 'optional'
+ false = 'false'
+
+ @classmethod
+ def all(cls):
+ return [cls.true, cls.optional, cls.false]
+
+
+class RebootJobType(object):
+ """Enumeration of different reboot job types."""
+
+ power_cycle = 'power_cycle'
+ """Hard power off, power on cycle"""
+
+ graceful_reboot = 'graceful_reboot'
+ """OS level reboot and wait for OS shutdown"""
+
+ reboot_forced_shutdown = 'reboot_forced_shutdown'
+ """OS level reboot and force power cycle if OS does not shut
+ down
+ """
+
+ @classmethod
+ def all(cls):
+ return [cls.power_cycle,
+ cls.graceful_reboot,
+ cls.reboot_forced_shutdown]
+
+
+class RaidStatus(object):
+ """Enumeration of different volume types."""
+
+ jbod = 'JBOD'
+ """Just a Bunch of Disks"""
+
+ raid = 'RAID'
+ """Redundant Array of Independent Disks"""
+
+ @classmethod
+ def all(cls):
+ return [cls.jbod,
+ cls.raid]
diff --git a/dracclient/resources/bios.py b/dracclient/resources/bios.py
index 263ef65..194d029 100644
--- a/dracclient/resources/bios.py
+++ b/dracclient/resources/bios.py
@@ -20,7 +20,6 @@
from dracclient.resources import lifecycle_controller
from dracclient.resources import uris
from dracclient import utils
-from dracclient import wsman
LOG = logging.getLogger(__name__)
@@ -74,8 +73,7 @@ def get_power_state(self):
interface
"""
- filter_query = ('select EnabledState from '
- 'DCIM_ComputerSystem where Name="srv:system"')
+ filter_query = ('select EnabledState from DCIM_ComputerSystem')
doc = self.client.enumerate(uris.DCIM_ComputerSystem,
filter_query=filter_query)
enabled_state = utils.find_xml(doc, 'EnabledState',
@@ -421,7 +419,7 @@ def __init__(self, name, instance_id, current_value, pending_value,
an unprocessed change (eg. config job not completed)
:param read_only: indicates whether this BIOS attribute can be changed
:param lower_bound: minimum value for the BIOS attribute
- :param upper_bound: maximum value for the BOIS attribute
+ :param upper_bound: maximum value for the BIOS attribute
"""
super(BIOSIntegerAttribute, self).__init__(name, instance_id,
current_value,
@@ -464,6 +462,10 @@ def validate(self, new_value):
class BIOSConfiguration(object):
+ NAMESPACES = [(uris.DCIM_BIOSEnumeration, BIOSEnumerableAttribute),
+ (uris.DCIM_BIOSString, BIOSStringAttribute),
+ (uris.DCIM_BIOSInteger, BIOSIntegerAttribute)]
+
def __init__(self, client):
"""Creates BIOSConfiguration object
@@ -485,33 +487,7 @@ def list_bios_settings(self, by_name=True):
interface
"""
- result = {}
- namespaces = [(uris.DCIM_BIOSEnumeration, BIOSEnumerableAttribute),
- (uris.DCIM_BIOSString, BIOSStringAttribute),
- (uris.DCIM_BIOSInteger, BIOSIntegerAttribute)]
- for (namespace, attr_cls) in namespaces:
- attribs = self._get_config(namespace, attr_cls, by_name)
- if not set(result).isdisjoint(set(attribs)):
- raise exceptions.DRACOperationFailed(
- drac_messages=('Colliding attributes %r' % (
- set(result) & set(attribs))))
- result.update(attribs)
- return result
-
- def _get_config(self, resource, attr_cls, by_name):
- result = {}
-
- doc = self.client.enumerate(resource)
- items = doc.find('.//{%s}Items' % wsman.NS_WSMAN)
-
- for item in items:
- attribute = attr_cls.parse(item)
- if by_name:
- result[attribute.name] = attribute
- else:
- result[attribute.instance_id] = attribute
-
- return result
+ return utils.list_settings(self.client, self.NAMESPACES, by_name)
def set_bios_settings(self, new_settings):
"""Sets the BIOS configuration
@@ -523,9 +499,13 @@ def set_bios_settings(self, new_settings):
:param new_settings: a dictionary containing the proposed values, with
each key being the name of attribute and the
value being the proposed value.
- :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.
+ :returns: a dictionary containing:
+ - The is_commit_required key with a boolean value indicating
+ whether a config job must be created for the values to be
+ applied.
+ - The is_reboot_required key with a RebootRequired enumerated
+ value indicating whether the server must be rebooted for the
+ values to be applied. Possible values are true and false.
:raises: WSManRequestFailure on request failures
:raises: WSManInvalidResponse when receiving invalid response
:raises: DRACOperationFailed on error reported back by the DRAC
@@ -534,68 +514,11 @@ def set_bios_settings(self, new_settings):
:raises: InvalidParameterValue on invalid BIOS attribute
"""
- current_settings = self.list_bios_settings(by_name=True)
- # BIOS settings are returned as dict indexed by InstanceID.
- # However DCIM_BIOSService requires attribute name, not instance id
- # so recreate this as a dict indexed by attribute name
- # TODO(anish) : Enable this code if/when by_name gets deprecated
- # bios_settings = self.list_bios_settings(by_name=False)
- # current_settings = dict((value.name, value)
- # for key, value in bios_settings.items())
- unknown_keys = set(new_settings) - set(current_settings)
- if unknown_keys:
- msg = ('Unknown BIOS attributes found: %(unknown_keys)r' %
- {'unknown_keys': unknown_keys})
- raise exceptions.InvalidParameterValue(reason=msg)
-
- read_only_keys = []
- unchanged_attribs = []
- invalid_attribs_msgs = []
- attrib_names = []
- candidates = set(new_settings)
-
- for attr in candidates:
- if str(new_settings[attr]) == str(
- current_settings[attr].current_value):
- unchanged_attribs.append(attr)
- elif current_settings[attr].read_only:
- read_only_keys.append(attr)
- else:
- validation_msg = current_settings[attr].validate(
- new_settings[attr])
- if validation_msg is None:
- attrib_names.append(attr)
- else:
- invalid_attribs_msgs.append(validation_msg)
-
- if unchanged_attribs:
- LOG.warning('Ignoring unchanged BIOS attributes: %r',
- unchanged_attribs)
-
- if invalid_attribs_msgs or read_only_keys:
- if read_only_keys:
- read_only_msg = ['Cannot set read-only BIOS attributes: %r.'
- % read_only_keys]
- else:
- read_only_msg = []
-
- drac_messages = '\n'.join(invalid_attribs_msgs + read_only_msg)
- raise exceptions.DRACOperationFailed(
- drac_messages=drac_messages)
-
- if not attrib_names:
- return {'commit_required': False}
-
- selectors = {'CreationClassName': 'DCIM_BIOSService',
- 'Name': 'DCIM:BIOSService',
- 'SystemCreationClassName': 'DCIM_ComputerSystem',
- 'SystemName': 'DCIM:ComputerSystem'}
- properties = {'Target': 'BIOS.Setup.1-1',
- 'AttributeName': attrib_names,
- 'AttributeValue': [new_settings[attr] for attr
- in attrib_names]}
- doc = self.client.invoke(uris.DCIM_BIOSService, 'SetAttributes',
- selectors, properties)
-
- return {'commit_required': utils.is_reboot_required(
- doc, uris.DCIM_BIOSService)}
+ return utils.set_settings('BIOS',
+ self.client,
+ self.NAMESPACES,
+ new_settings,
+ uris.DCIM_BIOSService,
+ "DCIM_BIOSService",
+ "DCIM:BIOSService",
+ 'BIOS.Setup.1-1')
diff --git a/dracclient/resources/idrac_card.py b/dracclient/resources/idrac_card.py
new file mode 100644
index 0000000..c4c69ca
--- /dev/null
+++ b/dracclient/resources/idrac_card.py
@@ -0,0 +1,353 @@
+#
+# 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.
+
+from dracclient.resources import uris
+from dracclient import utils
+
+
+class iDRACCardAttribute(object):
+ """Generic iDRACCard attribute class"""
+
+ def __init__(self, name, instance_id, current_value, pending_value,
+ read_only, fqdd, group_id):
+ """Creates iDRACCardAttribute object
+
+ :param name: name of the iDRACCard attribute
+ :param instance_id: InstanceID of the iDRACCard attribute
+ :param current_value: current value of the iDRACCard attribute
+ :param pending_value: pending value of the iDRACCard attribute,
+ reflecting an unprocessed change (eg. config job not completed)
+ :param read_only: indicates whether this iDRACCard attribute can be
+ changed
+ :param fqdd: Fully Qualified Device Description of the iDRACCard
+ Attribute
+ :param group_id: GroupID of the iDRACCard Attribute
+ """
+ self.name = name
+ self.instance_id = instance_id
+ self.current_value = current_value
+ self.pending_value = pending_value
+ self.read_only = read_only
+ self.fqdd = fqdd
+ self.group_id = group_id
+
+ def __eq__(self, other):
+ return self.__dict__ == other.__dict__
+
+ @classmethod
+ def parse(cls, namespace, idrac_attr_xml):
+ """Parses XML and creates iDRACCardAttribute object"""
+
+ name = utils.get_wsman_resource_attr(
+ idrac_attr_xml, namespace, 'AttributeName')
+ instance_id = utils.get_wsman_resource_attr(
+ idrac_attr_xml, namespace, 'InstanceID')
+ current_value = utils.get_wsman_resource_attr(
+ idrac_attr_xml, namespace, 'CurrentValue', nullable=True)
+ pending_value = utils.get_wsman_resource_attr(
+ idrac_attr_xml, namespace, 'PendingValue', nullable=True)
+ read_only = utils.get_wsman_resource_attr(
+ idrac_attr_xml, namespace, 'IsReadOnly').lower()
+ fqdd = utils.get_wsman_resource_attr(
+ idrac_attr_xml, namespace, 'FQDD')
+ group_id = utils.get_wsman_resource_attr(
+ idrac_attr_xml, namespace, 'GroupID')
+
+ return cls(name, instance_id, current_value, pending_value,
+ (read_only == 'true'), fqdd, group_id)
+
+
+class iDRACCardEnumerableAttribute(iDRACCardAttribute):
+ """Enumerable iDRACCard attribute class"""
+
+ namespace = uris.DCIM_iDRACCardEnumeration
+
+ def __init__(self, name, instance_id, current_value, pending_value,
+ read_only, fqdd, group_id, possible_values):
+ """Creates iDRACCardEnumerableAttribute object
+
+ :param name: name of the iDRACCard attribute
+ :param instance_id: InstanceID of the iDRACCard attribute
+ :param current_value: current value of the iDRACCard attribute
+ :param pending_value: pending value of the iDRACCard attribute,
+ reflecting an unprocessed change (eg. config job not completed)
+ :param read_only: indicates whether this iDRACCard attribute can be
+ changed
+ :param fqdd: Fully Qualified Device Description of the iDRACCard
+ Attribute
+ :param group_id: GroupID of the iDRACCard Attribute
+ :param possible_values: list containing the allowed values for the
+ iDRACCard attribute
+ """
+ super(iDRACCardEnumerableAttribute, self).__init__(name, instance_id,
+ current_value,
+ pending_value,
+ read_only, fqdd,
+ group_id)
+ self.possible_values = possible_values
+
+ @classmethod
+ def parse(cls, idrac_attr_xml):
+ """Parses XML and creates iDRACCardEnumerableAttribute object"""
+
+ idrac_attr = iDRACCardAttribute.parse(cls.namespace, idrac_attr_xml)
+ possible_values = [attr.text for attr
+ in utils.find_xml(idrac_attr_xml, 'PossibleValues',
+ cls.namespace, find_all=True)]
+
+ return cls(idrac_attr.name, idrac_attr.instance_id,
+ idrac_attr.current_value, idrac_attr.pending_value,
+ idrac_attr.read_only, idrac_attr.fqdd, idrac_attr.group_id,
+ possible_values)
+
+ def validate(self, new_value):
+ """Validates new value"""
+
+ if str(new_value) not in self.possible_values:
+ msg = ("Attribute '%(attr)s' cannot be set to value '%(val)s'."
+ " It must be in %(possible_values)r.") % {
+ 'attr': self.name,
+ 'val': new_value,
+ 'possible_values': self.possible_values}
+ return msg
+
+
+class iDRACCardStringAttribute(iDRACCardAttribute):
+ """String iDRACCard attribute class"""
+
+ namespace = uris.DCIM_iDRACCardString
+
+ def __init__(self, name, instance_id, current_value, pending_value,
+ read_only, fqdd, group_id, min_length, max_length):
+ """Creates iDRACCardStringAttribute object
+
+ :param name: name of the iDRACCard attribute
+ :param instance_id: InstanceID of the iDRACCard attribute
+ :param current_value: current value of the iDRACCard attribute
+ :param pending_value: pending value of the iDRACCard attribute,
+ reflecting an unprocessed change (eg. config job not completed)
+ :param read_only: indicates whether this iDRACCard attribute can be
+ changed
+ :param fqdd: Fully Qualified Device Description of the iDRACCard
+ Attribute
+ :param group_id: GroupID of the iDRACCard Attribute
+ :param min_length: minimum length of the string
+ :param max_length: maximum length of the string
+ """
+ super(iDRACCardStringAttribute, self).__init__(name, instance_id,
+ current_value,
+ pending_value,
+ read_only, fqdd,
+ group_id)
+ self.min_length = min_length
+ self.max_length = max_length
+
+ @classmethod
+ def parse(cls, idrac_attr_xml):
+ """Parses XML and creates iDRACCardStringAttribute object"""
+
+ idrac_attr = iDRACCardAttribute.parse(cls.namespace, idrac_attr_xml)
+ min_length = int(utils.get_wsman_resource_attr(
+ idrac_attr_xml, cls.namespace, 'MinLength'))
+ max_length = int(utils.get_wsman_resource_attr(
+ idrac_attr_xml, cls.namespace, 'MaxLength'))
+
+ return cls(idrac_attr.name, idrac_attr.instance_id,
+ idrac_attr.current_value, idrac_attr.pending_value,
+ idrac_attr.read_only, idrac_attr.fqdd, idrac_attr.group_id,
+ min_length, max_length)
+
+ def validate(self, new_value):
+ """Validates new value"""
+
+ val_len = len(new_value)
+ if val_len < self.min_length or val_len > self.max_length:
+ msg = ("Attribute '%(attr)s' cannot be set to value '%(val)s'."
+ " It must be between %(lower)d and %(upper)d characters in "
+ "length.") % {
+ 'attr': self.name,
+ 'val': new_value,
+ 'lower': self.min_length,
+ 'upper': self.max_length}
+ return msg
+
+
+class iDRACCardIntegerAttribute(iDRACCardAttribute):
+ """Integer iDRACCard attribute class"""
+
+ namespace = uris.DCIM_iDRACCardInteger
+
+ def __init__(self, name, instance_id, current_value, pending_value,
+ read_only, fqdd, group_id, lower_bound, upper_bound):
+ """Creates iDRACCardIntegerAttribute object
+
+ :param name: name of the iDRACCard attribute
+ :param instance_id: InstanceID of the iDRACCard attribute
+ :param current_value: current value of the iDRACCard attribute
+ :param pending_value: pending value of the iDRACCard attribute,
+ reflecting an unprocessed change (eg. config job not completed)
+ :param read_only: indicates whether this iDRACCard attribute can be
+ changed
+ :param fqdd: Fully Qualified Device Description of the iDRACCard
+ Attribute
+ :param group_id: GroupID of the iDRACCard Attribute
+ :param lower_bound: minimum value for the iDRACCard attribute
+ :param upper_bound: maximum value for the iDRACCard attribute
+ """
+ super(iDRACCardIntegerAttribute, self).__init__(name, instance_id,
+ current_value,
+ pending_value,
+ read_only, fqdd,
+ group_id)
+ self.lower_bound = lower_bound
+ self.upper_bound = upper_bound
+
+ @classmethod
+ def parse(cls, idrac_attr_xml):
+ """Parses XML and creates iDRACCardIntegerAttribute object"""
+
+ idrac_attr = iDRACCardAttribute.parse(cls.namespace, idrac_attr_xml)
+ lower_bound = utils.get_wsman_resource_attr(
+ idrac_attr_xml, cls.namespace, 'LowerBound')
+ upper_bound = utils.get_wsman_resource_attr(
+ idrac_attr_xml, cls.namespace, 'UpperBound')
+
+ if idrac_attr.current_value:
+ idrac_attr.current_value = int(idrac_attr.current_value)
+ if idrac_attr.pending_value:
+ idrac_attr.pending_value = int(idrac_attr.pending_value)
+
+ return cls(idrac_attr.name, idrac_attr.instance_id,
+ idrac_attr.current_value, idrac_attr.pending_value,
+ idrac_attr.read_only, idrac_attr.fqdd, idrac_attr.group_id,
+ int(lower_bound), int(upper_bound))
+
+ def validate(self, new_value):
+ """Validates new value"""
+
+ val = int(new_value)
+ if val < self.lower_bound or val > self.upper_bound:
+ msg = ('Attribute %(attr)s cannot be set to value %(val)d.'
+ ' It must be between %(lower)d and %(upper)d.') % {
+ 'attr': self.name,
+ 'val': new_value,
+ 'lower': self.lower_bound,
+ 'upper': self.upper_bound}
+ return msg
+
+
+class iDRACCardConfiguration(object):
+
+ NAMESPACES = [(uris.DCIM_iDRACCardEnumeration,
+ iDRACCardEnumerableAttribute),
+ (uris.DCIM_iDRACCardString, iDRACCardStringAttribute),
+ (uris.DCIM_iDRACCardInteger, iDRACCardIntegerAttribute)]
+
+ def __init__(self, client):
+ """Creates an iDRACCardConfiguration object
+
+ :param client: an instance of WSManClient
+ """
+ self.client = client
+
+ def list_idrac_settings(self, by_name=False, fqdd_filter=None):
+ """List the iDRACCard configuration settings
+
+ :param by_name: Controls whether returned dictionary uses iDRAC card
+ attribute name as key. If set to False, instance_id
+ will be used. If set to True the keys will be of the
+ form "group_id#name".
+ :param fqdd_filter: An FQDD used to filter the instances. Note that
+ this is only used when by_name is True.
+ :returns: a dictionary with the iDRAC settings using instance_id as the
+ key except when by_name is True. The attributes are either
+ iDRACCArdEnumerableAttribute, iDRACCardStringAttribute or
+ iDRACCardIntegerAttribute objects.
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the DRAC
+ interface
+ """
+
+ return utils.list_settings(self.client,
+ self.NAMESPACES,
+ by_name=by_name,
+ fqdd_filter=fqdd_filter,
+ name_formatter=_name_formatter)
+
+ def set_idrac_settings(self, new_settings, idrac_fqdd):
+ """Set the iDRACCard configuration settings
+
+ To be more precise, it sets the pending_value parameter for each of the
+ attributes passed in. For the values to be applied, a config job may
+ need to be created and the node may need to be rebooted.
+
+ :param new_settings: a dictionary containing the proposed values, with
+ each key being the name of attribute qualified
+ with the group ID in the form "group_id#name" and
+ the value being the proposed value.
+ :param idrac_fqdd: the FQDD of the iDRAC.
+ :returns: a dictionary containing:
+ - The is_commit_required key with a boolean value indicating
+ whether a config job must be created for the values to be
+ applied.
+ - The is_reboot_required key with a RebootRequired enumerated
+ value indicating whether the server must be rebooted for the
+ values to be applied. Possible values are true and false.
+ :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 attribute
+ """
+ return utils.set_settings('iDRAC Card',
+ self.client,
+ self.NAMESPACES,
+ new_settings,
+ uris.DCIM_iDRACCardService,
+ "DCIM_iDRACCardService",
+ "DCIM:iDRACCardService",
+ idrac_fqdd,
+ name_formatter=_name_formatter)
+
+ def reset_idrac(self, force=False):
+ """Resets the iDRAC
+
+ :param force: does a force reset when True and a graceful reset when
+ False.
+ :returns: True on success and False on failure.
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ """
+ selectors = {'CreationClassName': "DCIM_iDRACCardService",
+ 'Name': "DCIM:iDRACCardService",
+ 'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'DCIM:ComputerSystem'}
+
+ properties = {'Force': "1" if force else "0"}
+
+ doc = self.client.invoke(uris.DCIM_iDRACCardService,
+ 'iDRACReset',
+ selectors,
+ properties,
+ check_return_value=False)
+
+ message_id = utils.find_xml(doc,
+ 'MessageID',
+ uris.DCIM_iDRACCardService).text
+ return "RAC064" == message_id
+
+
+def _name_formatter(attribute):
+ return "{}#{}".format(attribute.group_id, attribute.name)
diff --git a/dracclient/resources/inventory.py b/dracclient/resources/inventory.py
index 4ce4eae..b29452a 100644
--- a/dracclient/resources/inventory.py
+++ b/dracclient/resources/inventory.py
@@ -47,7 +47,7 @@
CPU = collections.namedtuple(
'CPU',
['id', 'cores', 'speed_mhz', 'model', 'status', 'ht_enabled',
- 'turbo_enabled', 'vt_enabled', 'arch64'])
+ 'cpu_count', 'turbo_enabled', 'vt_enabled', 'arch64'])
Memory = collections.namedtuple(
'Memory',
@@ -57,6 +57,10 @@
'NIC',
['id', 'mac', 'model', 'speed_mbps', 'duplex', 'media_type'])
+System = collections.namedtuple(
+ 'System',
+ ['id', 'lcc_version', 'model', 'service_tag', 'uuid'])
+
class InventoryManagement(object):
@@ -99,10 +103,20 @@ def _parse_cpus(self, cpu):
allow_missing=True)),
turbo_enabled=bool(self._get_cpu_attr(cpu, 'TurboModeEnabled',
allow_missing=True)),
+ cpu_count=self._get_cpu_count(
+ int(self._get_cpu_attr(cpu, 'NumberOfProcessorCores')),
+ bool(self._get_cpu_attr(cpu, 'HyperThreadingEnabled',
+ allow_missing=True))),
vt_enabled=bool(self._get_cpu_attr(
cpu, 'VirtualizationTechnologyEnabled', allow_missing=True)),
arch64=arch64)
+ def _get_cpu_count(self, cores, ht_enabled):
+ if ht_enabled:
+ return int(cores * 2)
+ else:
+ return int(cores)
+
def _get_cpu_attr(self, cpu, attr_name, allow_missing=False):
return utils.get_wsman_resource_attr(
cpu, uris.DCIM_CPUView, attr_name, allow_missing=allow_missing)
@@ -138,7 +152,7 @@ def _get_memory_attr(self, memory, attr_name):
return utils.get_wsman_resource_attr(memory, uris.DCIM_MemoryView,
attr_name)
- def list_nics(self):
+ def list_nics(self, sort=False):
"""Returns the list of NICs
:returns: a list of NIC objects
@@ -151,8 +165,11 @@ def list_nics(self):
doc = self.client.enumerate(uris.DCIM_NICView)
drac_nics = utils.find_xml(doc, 'DCIM_NICView', uris.DCIM_NICView,
find_all=True)
+ nics = [self._parse_drac_nic(nic) for nic in drac_nics]
+ if sort:
+ nics.sort(key=lambda nic: nic.id)
- return [self._parse_drac_nic(nic) for nic in drac_nics]
+ return nics
def _parse_drac_nic(self, drac_nic):
fqdd = self._get_nic_attr(drac_nic, 'FQDD')
@@ -170,3 +187,32 @@ def _parse_drac_nic(self, drac_nic):
def _get_nic_attr(self, drac_nic, attr_name):
return utils.get_wsman_resource_attr(drac_nic, uris.DCIM_NICView,
attr_name)
+
+ def get_system(self):
+ """Returns a System object
+
+ :returns: a System object
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidRespons when receiving invalid response
+ """
+ doc = self.client.enumerate(uris.DCIM_SystemView)
+ drac_system = utils.find_xml(doc,
+ 'DCIM_SystemView',
+ uris.DCIM_SystemView,
+ find_all=False)
+
+ return self._parse_drac_system(drac_system)
+
+ def _parse_drac_system(self, drac_system):
+ return System(
+ id=self._get_system_attr(drac_system, 'InstanceID'),
+ uuid=self._get_system_attr(drac_system, 'UUID'),
+ service_tag=self._get_system_attr(drac_system, 'ServiceTag'),
+ model=self._get_system_attr(drac_system, 'Model'),
+ lcc_version=self._get_system_attr(drac_system,
+ 'LifecycleControllerVersion'))
+
+ def _get_system_attr(self, drac_system, attr_name):
+ return utils.get_wsman_resource_attr(drac_system,
+ uris.DCIM_SystemView,
+ attr_name)
diff --git a/dracclient/resources/job.py b/dracclient/resources/job.py
index 2961075..5ec3443 100644
--- a/dracclient/resources/job.py
+++ b/dracclient/resources/job.py
@@ -14,32 +14,24 @@
import collections
import logging
+from dracclient import constants
+import dracclient.exceptions as exceptions
from dracclient.resources import uris
from dracclient import utils
from dracclient import wsman
LOG = logging.getLogger(__name__)
-JobTuple = collections.namedtuple(
+Job = collections.namedtuple(
'Job',
['id', 'name', 'start_time', 'until_time', 'message', 'status',
'percent_complete'])
-
-class Job(JobTuple):
-
- def __new__(cls, **kwargs):
- if 'state' in kwargs:
- LOG.warning('Job.state is deprecated. Use Job.status instead.')
- kwargs['status'] = kwargs['state']
- del kwargs['state']
-
- return super(Job, cls).__new__(cls, **kwargs)
-
- @property
- def state(self):
- LOG.warning('Job.state is deprecated. Use Job.status instead.')
- return self.status
+REBOOT_TYPES = {
+ constants.RebootJobType.power_cycle: '1',
+ constants.RebootJobType.graceful_reboot: '2',
+ constants.RebootJobType.reboot_forced_shutdown: '3',
+}
class JobManagement(object):
@@ -68,6 +60,7 @@ def list_jobs(self, only_unfinished=False):
filter_query = ('select * from DCIM_LifecycleJob '
'where Name != "CLEARALL" and '
'JobStatus != "Reboot Completed" and '
+ 'JobStatus != "Reboot Failed" and '
'JobStatus != "Completed" and '
'JobStatus != "Completed with Errors" and '
'JobStatus != "Failed"')
@@ -107,7 +100,11 @@ def create_config_job(self, resource_uri, cim_creation_class_name,
cim_name, target,
cim_system_creation_class_name='DCIM_ComputerSystem',
cim_system_name='DCIM:ComputerSystem',
- reboot=False):
+ reboot=False,
+ start_time='TIME_NOW',
+ realtime=False,
+ wait_for_idrac=True,
+ method_name='CreateTargetedConfigJob'):
"""Creates a config job
In CIM (Common Information Model), weak association is used to name an
@@ -126,6 +123,18 @@ def create_config_job(self, resource_uri, cim_creation_class_name,
:param cim_system_name: name of the scoping system
:param reboot: indicates whether a RebootJob should also be created or
not
+ :param start_time: start time for job execution in format
+ yyyymmddhhmmss; the string 'TIME_NOW' means
+ immediately and None means the job is registered
+ but will not start execution until
+ schedule_job_execution is called with the returned
+ job id.
+ :param realtime: Indicates if reatime mode should be used.
+ Valid values are True and False. Default value is False.
+ :param wait_for_idrac: indicates whether or not to wait for the
+ iDRAC to be ready to accept commands before
+ issuing the command.
+ :param method_name: method of CIM object to invoke
:returns: id of the created job
:raises: WSManRequestFailure on request failures
:raises: WSManInvalidResponse when receiving invalid response
@@ -139,24 +148,142 @@ def create_config_job(self, resource_uri, cim_creation_class_name,
'CreationClassName': cim_creation_class_name,
'Name': cim_name}
- properties = {'Target': target,
- 'ScheduledStartTime': 'TIME_NOW'}
+ properties = {'Target': target}
+
+ if realtime:
+ properties['RealTime'] = '1'
- if reboot:
+ if not realtime and reboot:
properties['RebootJobType'] = '3'
- doc = self.client.invoke(resource_uri, 'CreateTargetedConfigJob',
+ if start_time is not None:
+ properties['ScheduledStartTime'] = start_time
+
+ doc = self.client.invoke(resource_uri, method_name,
selectors, properties,
+ expected_return_value=utils.RET_CREATED,
+ wait_for_idrac=wait_for_idrac)
+ return self._get_job_id(doc)
+
+ def create_reboot_job(
+ self,
+ reboot_type=constants.RebootJobType.reboot_forced_shutdown):
+ """Creates a reboot job.
+
+ :param reboot_type: type of reboot
+ :returns id of the created job
+ :raises: InvalidParameterValue on invalid reboot type
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the iDRAC
+ interface
+ :raises: DRACUnexpectedReturnValue on return value mismatch
+ """
+
+ try:
+ drac_reboot_type = REBOOT_TYPES[reboot_type]
+ except KeyError:
+ msg = ("'%(reboot_type)s' is not supported. "
+ "Supported reboot types: %(supported_reboot_types)r") % {
+ 'reboot_type': reboot_type,
+ 'supported_reboot_types': list(REBOOT_TYPES)}
+ raise exceptions.InvalidParameterValue(reason=msg)
+
+ selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'idrac',
+ 'CreationClassName': 'DCIM_JobService',
+ 'Name': 'JobService'}
+
+ properties = {'RebootJobType': drac_reboot_type}
+
+ doc = self.client.invoke(uris.DCIM_JobService,
+ 'CreateRebootJob',
+ selectors,
+ properties,
expected_return_value=utils.RET_CREATED)
- query = ('.//{%(namespace)s}%(item)s[@%(attribute_name)s='
- '"%(attribute_value)s"]' %
- {'namespace': wsman.NS_WSMAN, 'item': 'Selector',
- 'attribute_name': 'Name',
- 'attribute_value': 'InstanceID'})
+ return self._get_job_id(doc)
+
+ def schedule_job_execution(self, job_ids, start_time='TIME_NOW'):
+ """Schedules jobs for execution in a specified order.
+
+ :param job_ids: list of job identifiers
+ :param start_time: start time for job execution in format
+ yyyymmddhhmmss; the string 'TIME_NOW' means
+ immediately
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the iDRAC
+ interface
+ :raises: DRACUnexpectedReturnValue on return value mismatch
+ """
+
+ # If the list of job identifiers is empty, there is nothing to do.
+ if not job_ids:
+ return
+
+ selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'idrac',
+ 'CreationClassName': 'DCIM_JobService',
+ 'Name': 'JobService'}
+
+ properties = {'JobArray': job_ids,
+ 'StartTimeInterval': start_time}
+
+ self.client.invoke(uris.DCIM_JobService,
+ 'SetupJobQueue',
+ selectors,
+ properties,
+ expected_return_value=utils.RET_SUCCESS)
+
+ def _get_job_id(self, doc):
+ query = (
+ './/{%(namespace)s}%(item)s[@%(attribute_name)s='
+ '"%(attribute_value)s"]' % {
+ 'namespace': wsman.NS_WSMAN,
+ 'item': 'Selector',
+ 'attribute_name': 'Name',
+ 'attribute_value': 'InstanceID'})
job_id = doc.find(query).text
return job_id
+ def delete_jobs(self, job_ids=['JID_CLEARALL']):
+ """Deletes the given jobs, or all jobs if none specified
+
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the iDRAC
+ interface
+ :raises: DRACUnexpectedReturnValue on non-success
+ """
+
+ selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'idrac',
+ 'CreationClassName': 'DCIM_JobService',
+ 'Name': 'JobService'}
+
+ if job_ids is None:
+ return
+
+ messages = []
+
+ for job_id in job_ids:
+ properties = {'JobID': job_id}
+
+ try:
+ self.client.invoke(
+ uris.DCIM_JobService,
+ 'DeleteJobQueue',
+ selectors,
+ properties,
+ expected_return_value=utils.RET_SUCCESS)
+ except exceptions.DRACOperationFailed as dof:
+ for message in dof.args:
+ messages.append(message + " " + job_id)
+
+ if len(messages):
+ raise exceptions.DRACOperationFailed(drac_messages=messages)
+
def delete_pending_config(
self, resource_uri, cim_creation_class_name, cim_name, target,
cim_system_creation_class_name='DCIM_ComputerSystem',
diff --git a/dracclient/resources/lifecycle_controller.py b/dracclient/resources/lifecycle_controller.py
index b8a715c..c42bfd1 100644
--- a/dracclient/resources/lifecycle_controller.py
+++ b/dracclient/resources/lifecycle_controller.py
@@ -11,6 +11,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+from dracclient import constants
from dracclient.resources import uris
from dracclient import utils
@@ -34,11 +35,230 @@ def get_version(self):
interface
"""
- filter_query = ('select LifecycleControllerVersion '
- 'from DCIM_SystemView')
- doc = self.client.enumerate(uris.DCIM_SystemView,
- filter_query=filter_query)
+ doc = self.client.enumerate(uris.DCIM_SystemView, wait_for_idrac=False)
lc_version_str = utils.find_xml(doc, 'LifecycleControllerVersion',
uris.DCIM_SystemView).text
return tuple(map(int, (lc_version_str.split('.'))))
+
+
+class LCAttribute(object):
+ """Generic LC attribute class"""
+
+ def __init__(self, name, instance_id, current_value, pending_value,
+ read_only):
+ """Creates LCAttribute object
+
+ :param name: name of the LC attribute
+ :param instance_id: InstanceID of the LC attribute
+ :param current_value: current value of the LC attribute
+ :param pending_value: pending value of the LC attribute, reflecting
+ an unprocessed change (eg. config job not completed)
+ :param read_only: indicates whether this LC attribute can be changed
+ """
+ self.name = name
+ self.instance_id = instance_id
+ self.current_value = current_value
+ self.pending_value = pending_value
+ self.read_only = read_only
+
+ def __eq__(self, other):
+ return self.__dict__ == other.__dict__
+
+ @classmethod
+ def parse(cls, namespace, lifecycle_attr_xml):
+ """Parses XML and creates LCAttribute object"""
+
+ name = utils.get_wsman_resource_attr(
+ lifecycle_attr_xml, namespace, 'AttributeName')
+ instance_id = utils.get_wsman_resource_attr(
+ lifecycle_attr_xml, namespace, 'InstanceID')
+ current_value = utils.get_wsman_resource_attr(
+ lifecycle_attr_xml, namespace, 'CurrentValue', nullable=True)
+ pending_value = utils.get_wsman_resource_attr(
+ lifecycle_attr_xml, namespace, 'PendingValue', nullable=True)
+ read_only = utils.get_wsman_resource_attr(
+ lifecycle_attr_xml, namespace, 'IsReadOnly')
+
+ return cls(name, instance_id, current_value, pending_value,
+ (read_only == 'true'))
+
+
+class LCEnumerableAttribute(LCAttribute):
+ """Enumerable LC attribute class"""
+
+ namespace = uris.DCIM_LCEnumeration
+
+ def __init__(self, name, instance_id, current_value, pending_value,
+ read_only, possible_values):
+ """Creates LCEnumerableAttribute object
+
+ :param name: name of the LC attribute
+ :param current_value: current value of the LC attribute
+ :param pending_value: pending value of the LC attribute, reflecting
+ an unprocessed change (eg. config job not completed)
+ :param read_only: indicates whether this LC attribute can be changed
+ :param possible_values: list containing the allowed values for the LC
+ attribute
+ """
+ super(LCEnumerableAttribute, self).__init__(name, instance_id,
+ current_value,
+ pending_value, read_only)
+ self.possible_values = possible_values
+
+ @classmethod
+ def parse(cls, lifecycle_attr_xml):
+ """Parses XML and creates LCEnumerableAttribute object"""
+
+ lifecycle_attr = LCAttribute.parse(cls.namespace, lifecycle_attr_xml)
+ possible_values = [attr.text for attr
+ in utils.find_xml(lifecycle_attr_xml,
+ 'PossibleValues',
+ cls.namespace, find_all=True)]
+
+ return cls(lifecycle_attr.name, lifecycle_attr.instance_id,
+ lifecycle_attr.current_value, lifecycle_attr.pending_value,
+ lifecycle_attr.read_only, possible_values)
+
+ def validate(self, new_value):
+ """Validates new value"""
+
+ if str(new_value) not in self.possible_values:
+ msg = ("Attribute '%(attr)s' cannot be set to value '%(val)s'."
+ " It must be in %(possible_values)r.") % {
+ 'attr': self.name,
+ 'val': new_value,
+ 'possible_values': self.possible_values}
+ return msg
+
+
+class LCStringAttribute(LCAttribute):
+ """String LC attribute class"""
+
+ namespace = uris.DCIM_LCString
+
+ def __init__(self, name, instance_id, current_value, pending_value,
+ read_only, min_length, max_length):
+ """Creates LCStringAttribute object
+
+ :param name: name of the LC attribute
+ :param instance_id: InstanceID of the LC attribute
+ :param current_value: current value of the LC attribute
+ :param pending_value: pending value of the LC attribute, reflecting
+ an unprocessed change (eg. config job not completed)
+ :param read_only: indicates whether this LC attribute can be changed
+ :param min_length: minimum length of the string
+ :param max_length: maximum length of the string
+ """
+ super(LCStringAttribute, self).__init__(name, instance_id,
+ current_value, pending_value,
+ read_only)
+ self.min_length = min_length
+ self.max_length = max_length
+
+ @classmethod
+ def parse(cls, lifecycle_attr_xml):
+ """Parses XML and creates LCStringAttribute object"""
+
+ lifecycle_attr = LCAttribute.parse(cls.namespace, lifecycle_attr_xml)
+ min_length = int(utils.get_wsman_resource_attr(
+ lifecycle_attr_xml, cls.namespace, 'MinLength'))
+ max_length = int(utils.get_wsman_resource_attr(
+ lifecycle_attr_xml, cls.namespace, 'MaxLength'))
+
+ return cls(lifecycle_attr.name, lifecycle_attr.instance_id,
+ lifecycle_attr.current_value, lifecycle_attr.pending_value,
+ lifecycle_attr.read_only, min_length, max_length)
+
+
+class LCConfiguration(object):
+
+ NAMESPACES = [(uris.DCIM_LCEnumeration, LCEnumerableAttribute),
+ (uris.DCIM_LCString, LCStringAttribute)]
+
+ def __init__(self, client):
+ """Creates LifecycleControllerManagement object
+
+ :param client: an instance of WSManClient
+ """
+ self.client = client
+
+ def list_lifecycle_settings(self, by_name=False):
+ """List the LC configuration settings
+
+ :param by_name: Controls whether returned dictionary uses Lifecycle
+ attribute name or instance_id as key.
+ :returns: a dictionary with the LC settings using InstanceID as the
+ key. The attributes are either LCEnumerableAttribute,
+ LCStringAttribute or LCIntegerAttribute objects.
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the DRAC
+ interface
+ """
+ return utils.list_settings(self.client, self.NAMESPACES, by_name)
+
+ def is_lifecycle_in_recovery(self):
+ """Check if Lifecycle Controller in recovery mode or not
+
+ This method checks the LCStatus value to determine if lifecycle
+ controller is in recovery mode by invoking GetRemoteServicesAPIStatus
+ from iDRAC.
+
+ :returns: a boolean indicating if lifecycle controller is in recovery
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the DRAC
+ interface
+ """
+
+ selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'DCIM:ComputerSystem',
+ 'CreationClassName': 'DCIM_LCService',
+ 'Name': 'DCIM:LCService'}
+
+ doc = self.client.invoke(uris.DCIM_LCService,
+ 'GetRemoteServicesAPIStatus',
+ selectors,
+ {},
+ expected_return_value=utils.RET_SUCCESS,
+ wait_for_idrac=False)
+
+ lc_status = utils.find_xml(doc,
+ 'LCStatus',
+ uris.DCIM_LCService).text
+
+ return lc_status == constants.LC_IN_RECOVERY
+
+ def set_lifecycle_settings(self, settings):
+ """Sets the Lifecycle Controller configuration
+
+ It sets the pending_value parameter for each of the attributes
+ passed in. For the values to be applied, a config job must
+ be created.
+
+ :param settings: a dictionary containing the proposed values, with
+ each key being the name of attribute and the value
+ being the proposed value.
+ :returns: a dictionary containing:
+ - The is_commit_required key with a boolean value indicating
+ whether a config job must be created for the values to be
+ applied.
+ - The is_reboot_required key with a RebootRequired enumerated
+ value indicating whether the server must be rebooted for the
+ values to be applied. Possible values are true and false.
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the DRAC
+ interface
+ """
+
+ return utils.set_settings('Lifecycle',
+ self.client,
+ self.NAMESPACES,
+ settings,
+ uris.DCIM_LCService,
+ "DCIM_LCService",
+ "DCIM:LCService",
+ '',
+ wait_for_idrac=False)
diff --git a/dracclient/resources/nic.py b/dracclient/resources/nic.py
new file mode 100644
index 0000000..bf8f292
--- /dev/null
+++ b/dracclient/resources/nic.py
@@ -0,0 +1,378 @@
+# Copyright (c) 2016-2018 Dell Inc. or its subsidiaries.
+#
+# 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 logging
+import re
+
+import dracclient.utils as utils
+
+from dracclient.resources import uris
+
+LOG = logging.getLogger(__name__)
+
+
+class NICAttribute(object):
+ """Generic NIC attribute class"""
+
+ def __init__(self, name, instance_id, current_value, pending_value,
+ read_only, fqdd):
+ """Construct a NICAttribute object.
+
+ :param name: name of the NIC attribute
+ :param instance_id: opaque and unique identifier of the BIOS attribute
+ :param current_value: current value of the NIC attribute
+ :param pending_value: pending value of the NIC attribute, reflecting
+ an unprocessed change (eg. config job not completed)
+ :param read_only: indicates whether this NIC attribute can be changed
+ :param fqdd: Fully Qualified Device Description of the NICCard
+ Attribute
+ """
+ self.name = name
+ self.instance_id = instance_id
+ self.current_value = current_value
+ self.pending_value = pending_value
+ self.read_only = read_only
+ self.fqdd = fqdd
+
+ def __eq__(self, other):
+ return self.__dict__ == other.__dict__
+
+ @classmethod
+ def parse(cls, namespace, nic_attr_xml):
+ """Parses XML and creates a NICAttribute object."""
+
+ name = utils.get_wsman_resource_attr(nic_attr_xml,
+ namespace,
+ 'AttributeName')
+ instance_id = utils.get_wsman_resource_attr(nic_attr_xml,
+ namespace,
+ 'InstanceID')
+ current_value = utils.get_wsman_resource_attr(nic_attr_xml,
+ namespace,
+ 'CurrentValue',
+ nullable=True)
+ pending_value = utils.get_wsman_resource_attr(nic_attr_xml,
+ namespace,
+ 'PendingValue',
+ nullable=True)
+ read_only = utils.get_wsman_resource_attr(nic_attr_xml,
+ namespace,
+ 'IsReadOnly')
+
+ fqdd = utils.get_wsman_resource_attr(nic_attr_xml,
+ namespace,
+ 'FQDD')
+
+ return cls(name, instance_id, current_value, pending_value,
+ (read_only == 'true'), fqdd)
+
+
+class NICEnumerationAttribute(NICAttribute):
+ """Enumeration NIC attribute class"""
+
+ namespace = uris.DCIM_NICEnumeration
+
+ def __init__(self,
+ name,
+ instance_id,
+ current_value,
+ pending_value,
+ read_only,
+ fqdd,
+ possible_values):
+ """Construct a NICEnumerationAttribute object.
+
+ :param name: name of the NIC attribute
+ :param instance_id: opaque and unique identifier of the BIOS attribute
+ :param current_value: current value of the NIC attribute
+ :param pending_value: pending value of the NIC attribute, reflecting
+ an unprocessed change (eg. config job not completed)
+ :param read_only: indicates whether this NIC attribute can be changed
+ :param fqdd: Fully Qualified Device Description of the NICCard
+ Attribute
+ :param possible_values: list containing the allowed values for the NIC
+ attribute
+ """
+ super(NICEnumerationAttribute, self).__init__(name,
+ instance_id,
+ current_value,
+ pending_value,
+ read_only,
+ fqdd)
+ self.possible_values = possible_values
+
+ @classmethod
+ def parse(cls, nic_attr_xml):
+ """Parse XML and create a NICEnumerationAttribute object."""
+
+ nic_attr = NICAttribute.parse(cls.namespace, nic_attr_xml)
+ possible_values = [attr.text for attr
+ in utils.find_xml(nic_attr_xml,
+ 'PossibleValues',
+ cls.namespace,
+ find_all=True)]
+
+ return cls(nic_attr.name,
+ nic_attr.instance_id,
+ nic_attr.current_value,
+ nic_attr.pending_value,
+ nic_attr.read_only,
+ nic_attr.fqdd,
+ possible_values)
+
+ def validate(self, value):
+ """Validate new value."""
+
+ if str(value) not in self.possible_values:
+ msg = ("Attribute '%(attr)s' cannot be set to value '%(val)s'."
+ " It must be in %(possible_values)r.") % {
+ 'attr': self.name,
+ 'val': value,
+ 'possible_values': self.possible_values}
+ return msg
+
+ return None
+
+
+class NICStringAttribute(NICAttribute):
+ """String NIC attribute class."""
+
+ namespace = uris.DCIM_NICString
+
+ def __init__(self,
+ name,
+ instance_id,
+ current_value,
+ pending_value,
+ read_only,
+ fqdd,
+ min_length,
+ max_length,
+ pcre_regex):
+ """Construct a NICStringAttribute object.
+
+ :param name: name of the NIC attribute
+ :param instance_id: opaque and unique identifier of the BIOS attribute
+ :param current_value: current value of the NIC attribute
+ :param pending_value: pending value of the NIC attribute, reflecting
+ an unprocessed change (eg. config job not completed)
+ :param read_only: indicates whether this NIC attribute can be changed
+ :param fqdd: Fully Qualified Device Description of the NICCard
+ Attribute
+ :param min_length: minimum length of the string
+ :param max_length: maximum length of the string
+ :param pcre_regex: is a PCRE compatible regular expression that the
+ string must match
+ """
+ super(NICStringAttribute, self).__init__(name,
+ instance_id,
+ current_value,
+ pending_value,
+ read_only,
+ fqdd)
+ self.min_length = min_length
+ self.max_length = max_length
+ self.pcre_regex = pcre_regex
+
+ @classmethod
+ def parse(cls, nic_attr_xml):
+ """Parse XML and create a NICStringAttribute object."""
+
+ nic_attr = NICAttribute.parse(cls.namespace, nic_attr_xml)
+ min_length = int(utils.get_wsman_resource_attr(nic_attr_xml,
+ cls.namespace,
+ 'MinLength'))
+ max_length = int(utils.get_wsman_resource_attr(nic_attr_xml,
+ cls.namespace,
+ 'MaxLength'))
+ pcre_regex = utils.get_wsman_resource_attr(nic_attr_xml,
+ cls.namespace,
+ 'ValueExpression',
+ nullable=True)
+
+ return cls(nic_attr.name,
+ nic_attr.instance_id,
+ nic_attr.current_value,
+ nic_attr.pending_value,
+ nic_attr.read_only,
+ nic_attr.fqdd,
+ min_length,
+ max_length,
+ pcre_regex)
+
+ def validate(self, value):
+ """Validate new value."""
+
+ if self.pcre_regex is not None:
+ regex = re.compile(self.pcre_regex)
+
+ if regex.search(str(value)) is None:
+ msg = ("Attribute '%(attr)s' cannot be set to value '%(val)s.'"
+ " It must match regex '%(re)s'.") % {
+ 'attr': self.name,
+ 'val': value,
+ 're': self.pcre_regex}
+ return msg
+
+ return None
+
+
+class NICIntegerAttribute(NICAttribute):
+ """Integer NIC attribute class."""
+
+ namespace = uris.DCIM_NICInteger
+
+ def __init__(self,
+ name,
+ instance_id,
+ current_value,
+ pending_value,
+ read_only,
+ fqdd,
+ lower_bound,
+ upper_bound):
+ """Construct a NICIntegerAttribute object.
+
+ :param name: name of the NIC attribute
+ :param instance_id: opaque and unique identifier of the BIOS attribute
+ :param current_value: current value of the NIC attribute
+ :param pending_value: pending value of the NIC attribute, reflecting
+ an unprocessed change (eg. config job not completed)
+ :param read_only: indicates whether this NIC attribute can be changed
+ :param fqdd: Fully Qualified Device Description of the NICCard
+ Attribute
+ :param lower_bound: minimum value for the NIC attribute
+ :param upper_bound: maximum value for the NIC attribute
+ """
+ super(NICIntegerAttribute, self).__init__(name,
+ instance_id,
+ current_value,
+ pending_value,
+ read_only,
+ fqdd)
+ self.lower_bound = lower_bound
+ self.upper_bound = upper_bound
+
+ @classmethod
+ def parse(cls, nic_attr_xml):
+ """Parse XML and create a NICIntegerAttribute object."""
+
+ nic_attr = NICAttribute.parse(cls.namespace, nic_attr_xml)
+ lower_bound = utils.get_wsman_resource_attr(nic_attr_xml,
+ cls.namespace,
+ 'LowerBound')
+ upper_bound = utils.get_wsman_resource_attr(nic_attr_xml,
+ cls.namespace,
+ 'UpperBound')
+
+ if nic_attr.current_value:
+ nic_attr.current_value = int(nic_attr.current_value)
+
+ if nic_attr.pending_value:
+ nic_attr.pending_value = int(nic_attr.pending_value)
+
+ return cls(nic_attr.name,
+ nic_attr.instance_id,
+ nic_attr.current_value,
+ nic_attr.pending_value,
+ nic_attr.read_only,
+ nic_attr.fqdd,
+ int(lower_bound),
+ int(upper_bound))
+
+ def validate(self, value):
+ """Validate new value."""
+
+ val = int(value)
+
+ if val < self.lower_bound or val > self.upper_bound:
+ msg = ('Attribute %(attr)s cannot be set to value %(val)d.'
+ ' It must be between %(lower)d and %(upper)d.') % {
+ 'attr': self.name,
+ 'val': value,
+ 'lower': self.lower_bound,
+ 'upper': self.upper_bound}
+ return msg
+
+ return None
+
+
+class NICConfiguration(object):
+
+ NAMESPACES = [(uris.DCIM_NICEnumeration, NICEnumerationAttribute),
+ (uris.DCIM_NICString, NICStringAttribute),
+ (uris.DCIM_NICInteger, NICIntegerAttribute)]
+
+ def __init__(self, client):
+ """Construct a NICConfiguration object.
+
+ :param client: an instance of WSManClient
+ """
+ self.client = client
+
+ def list_nic_settings(self, nic_id):
+ """Return the list of attribute settings of a NIC.
+
+ :param nic_id: id of the network interface controller (NIC)
+ :returns: dictionary containing the NIC settings. The keys are
+ attribute names. Each value is a
+ NICEnumerationAttribute, NICIntegerAttribute, or
+ NICStringAttribute object.
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the iDRAC
+ interface
+ """
+
+ result = utils.list_settings(self.client,
+ self.NAMESPACES,
+ fqdd_filter=nic_id)
+
+ return result
+
+ def set_nic_settings(self, nic_id, new_settings):
+ """Modify one or more settings of a NIC.
+
+ To be more precise, it sets the pending_value parameter for each of the
+ attributes passed in. For the values to be applied, a config job may
+ need to be created and the node may need to be rebooted.
+
+ :param nic_id: id of the network interface controller,
+ :param new_settings: a dictionary containing the proposed values, with
+ each key being the name of attribute qualified
+ with the group ID in the form "group_id#name" and
+ the value being the proposed value.
+ :returns: a dictionary containing:
+ - The is_commit_required key with a boolean value indicating
+ whether a config job must be created for the values to be
+ applied.
+ - The is_reboot_required key with a RebootRequired enumerated
+ value indicating whether the server must be rebooted for the
+ values to be applied. Possible values are true and false.
+ :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 attribute
+ """
+
+ return utils.set_settings('iDRAC Card',
+ self.client,
+ self.NAMESPACES,
+ new_settings,
+ uris.DCIM_NICService,
+ "DCIM_NICService",
+ "DCIM:NICService",
+ nic_id)
diff --git a/dracclient/resources/raid.py b/dracclient/resources/raid.py
index d16501e..3522158 100644
--- a/dracclient/resources/raid.py
+++ b/dracclient/resources/raid.py
@@ -12,6 +12,7 @@
# under the License.
import collections
+import copy
import logging
from dracclient import constants
@@ -34,6 +35,11 @@
REVERSE_RAID_LEVELS = dict((v, k) for (k, v) in RAID_LEVELS.items())
+RAID_CONTROLLER_IS_REALTIME = {
+ '1': True,
+ '0': False
+}
+
DISK_RAID_STATUS = {
'0': 'unknown',
'1': 'ready',
@@ -66,88 +72,248 @@
'3': 'fibre',
'4': 'usb',
'5': 'sata',
- '6': 'sas'
+ '6': 'sas',
+ '7': 'pcie',
+ '8': 'nvme'
}
-PhysicalDiskTuple = collections.namedtuple(
+PhysicalDisk = collections.namedtuple(
'PhysicalDisk',
['id', 'description', 'controller', 'manufacturer', 'model', 'media_type',
'interface_type', 'size_mb', 'free_size_mb', 'serial_number',
- 'firmware_version', 'status', 'raid_status'])
-
-
-class PhysicalDisk(PhysicalDiskTuple):
-
- def __new__(cls, **kwargs):
- if 'state' in kwargs:
- LOG.warning('PhysicalDisk.state is deprecated. '
- 'Use PhysicalDisk.status instead.')
- kwargs['status'] = kwargs['state']
- del kwargs['state']
-
- if 'raid_state' in kwargs:
- LOG.warning('PhysicalDisk.raid_state is deprecated. '
- 'Use PhysicalDisk.raid_status instead.')
- kwargs['raid_status'] = kwargs['raid_state']
- del kwargs['raid_state']
-
- return super(PhysicalDisk, cls).__new__(cls, **kwargs)
-
- @property
- def state(self):
- LOG.warning('PhysicalDisk.state is deprecated. '
- 'Use PhysicalDisk.status instead.')
- return self.status
-
- @property
- def raid_state(self):
- LOG.warning('PhysicalDisk.raid_state is deprecated. '
- 'Use PhysicalDisk.raid_status instead.')
- return self.raid_status
+ 'firmware_version', 'status', 'raid_status', 'sas_address',
+ 'device_protocol', 'bus'])
RAIDController = collections.namedtuple(
'RAIDController', ['id', 'description', 'manufacturer', 'model',
- 'primary_status', 'firmware_version'])
+ 'primary_status', 'firmware_version', 'bus',
+ 'supports_realtime'])
-VirtualDiskTuple = collections.namedtuple(
+VirtualDisk = collections.namedtuple(
'VirtualDisk',
['id', 'name', 'description', 'controller', 'raid_level', 'size_mb',
'status', 'raid_status', 'span_depth', 'span_length',
- 'pending_operations'])
+ 'pending_operations', 'physical_disks'])
+NO_FOREIGN_DRIVES = ["STOR058", "STOR018"]
-class VirtualDisk(VirtualDiskTuple):
- def __new__(cls, **kwargs):
- if 'state' in kwargs:
- LOG.warning('VirtualDisk.state is deprecated. '
- 'Use VirtualDisk.status instead.')
- kwargs['status'] = kwargs['state']
- del kwargs['state']
+class RAIDAttribute(object):
+ """Generic RAID attribute class"""
- if 'raid_state' in kwargs:
- LOG.warning('VirtualDisk.raid_state is deprecated. '
- 'Use VirtualDisk.raid_status instead.')
- kwargs['raid_status'] = kwargs['raid_state']
- del kwargs['raid_state']
+ def __init__(self, name, instance_id, current_value, pending_value,
+ read_only, fqdd):
+ """Creates RAIDAttribute object
- return super(VirtualDisk, cls).__new__(cls, **kwargs)
-
- @property
- def state(self):
- LOG.warning('VirtualDisk.state is deprecated. '
- 'Use VirtualDisk.status instead.')
- return self.status
+ :param name: name of the RAID attribute
+ :param instance_id: InstanceID of the RAID attribute
+ :param current_value: list containing the current values of the
+ RAID attribute
+ :param pending_value: pending value of the RAID attribute, reflecting
+ an unprocessed change (eg. config job not completed)
+ :param read_only: indicates whether this RAID attribute can be changed
+ :param fqdd: Fully Qualified Device Description of the RAID Attribute
+ """
- @property
- def raid_state(self):
- LOG.warning('VirtualDisk.raid_state is deprecated. '
- 'Use VirtualDisk.raid_status instead.')
- return self.raid_status
+ self.name = name
+ self.instance_id = instance_id
+ self.current_value = current_value
+ self.pending_value = pending_value
+ self.read_only = read_only
+ self.fqdd = fqdd
+
+ def __eq__(self, other):
+ return self.__dict__ == other.__dict__
+
+ @classmethod
+ def parse(cls, namespace, raid_attr_xml):
+ """Parses XML and creates RAIDAttribute object"""
+
+ name = utils.get_wsman_resource_attr(
+ raid_attr_xml, namespace, 'AttributeName')
+ instance_id = utils.get_wsman_resource_attr(
+ raid_attr_xml, namespace, 'InstanceID')
+ current_value = [attr.text for attr in
+ utils.find_xml(raid_attr_xml, 'CurrentValue',
+ namespace, find_all=True)]
+ pending_value = utils.get_wsman_resource_attr(
+ raid_attr_xml, namespace, 'PendingValue', nullable=True)
+ read_only = utils.get_wsman_resource_attr(
+ raid_attr_xml, namespace, 'IsReadOnly')
+ fqdd = utils.get_wsman_resource_attr(
+ raid_attr_xml, namespace, 'FQDD')
+
+ return cls(name, instance_id, current_value, pending_value,
+ (read_only == 'true'), fqdd)
+
+
+class RAIDEnumerableAttribute(RAIDAttribute):
+ """Enumerable RAID attribute class"""
+
+ namespace = uris.DCIM_RAIDEnumeration
+
+ def __init__(self, name, instance_id, current_value, pending_value,
+ read_only, fqdd, possible_values):
+ """Creates RAIDEnumerableAttribute object
+
+ :param name: name of the RAID attribute
+ :param instance_id: InstanceID of the RAID attribute
+ :param current_value: list containing the current values of the
+ RAID attribute
+ :param pending_value: pending value of the RAID attribute, reflecting
+ an unprocessed change (eg. config job not completed)
+ :param read_only: indicates whether this RAID attribute can be changed
+ :param fqdd: Fully Qualified Device Description of the RAID
+ Attribute
+ :param possible_values: list containing the allowed values for the RAID
+ attribute
+ """
+ super(RAIDEnumerableAttribute, self).__init__(name, instance_id,
+ current_value,
+ pending_value,
+ read_only, fqdd)
+
+ self.possible_values = possible_values
+
+ @classmethod
+ def parse(cls, raid_attr_xml):
+ """Parses XML and creates RAIDEnumerableAttribute object"""
+
+ raid_attr = RAIDAttribute.parse(cls.namespace, raid_attr_xml)
+ possible_values = [attr.text for attr
+ in utils.find_xml(raid_attr_xml,
+ 'PossibleValues',
+ cls.namespace, find_all=True)]
+
+ return cls(raid_attr.name, raid_attr.instance_id,
+ raid_attr.current_value, raid_attr.pending_value,
+ raid_attr.read_only, raid_attr.fqdd, possible_values)
+
+ def validate(self, new_value):
+ """Validates new value"""
+
+ if str(new_value) not in self.possible_values:
+ msg = ("Attribute '%(attr)s' cannot be set to value '%(val)s'."
+ " It must be in %(possible_values)r.") % {
+ 'attr': self.name,
+ 'val': new_value,
+ 'possible_values': self.possible_values}
+ return msg
+
+
+class RAIDStringAttribute(RAIDAttribute):
+ """String RAID attribute class"""
+
+ namespace = uris.DCIM_RAIDString
+
+ def __init__(self, name, instance_id, current_value, pending_value,
+ read_only, fqdd, min_length, max_length):
+ """Creates RAIDStringAttribute object
+
+ :param name: name of the RAID attribute
+ :param instance_id: InstanceID of the RAID attribute
+ :param current_value: list containing the current values of the
+ RAID attribute
+ :param pending_value: pending value of the RAID attribute, reflecting
+ an unprocessed change (eg. config job not completed)
+ :param read_only: indicates whether this RAID attribute can be changed
+ :param fqdd: Fully Qualified Device Description of the RAID
+ Attribute
+ :param min_length: minimum length of the string
+ :param max_length: maximum length of the string
+ """
+ super(RAIDStringAttribute, self).__init__(name, instance_id,
+ current_value, pending_value,
+ read_only, fqdd)
+ self.min_length = min_length
+ self.max_length = max_length
+
+ @classmethod
+ def parse(cls, raid_attr_xml):
+ """Parses XML and creates RAIDStringAttribute object"""
+
+ raid_attr = RAIDAttribute.parse(cls.namespace, raid_attr_xml)
+ min_length = int(utils.get_wsman_resource_attr(
+ raid_attr_xml, cls.namespace, 'MinLength'))
+ max_length = int(utils.get_wsman_resource_attr(
+ raid_attr_xml, cls.namespace, 'MaxLength'))
+
+ return cls(raid_attr.name, raid_attr.instance_id,
+ raid_attr.current_value, raid_attr.pending_value,
+ raid_attr.read_only, raid_attr.fqdd,
+ min_length, max_length)
+
+
+class RAIDIntegerAttribute(RAIDAttribute):
+ """Integer RAID attribute class"""
+
+ namespace = uris.DCIM_RAIDInteger
+
+ def __init__(self, name, instance_id, current_value, pending_value,
+ read_only, fqdd, lower_bound, upper_bound):
+ """Creates RAIDIntegerAttribute object
+
+ :param name: name of the RAID attribute
+ :param instance_id: InstanceID of the RAID attribute
+ :param current_value: list containing the current value of the
+ RAID attribute
+ :param pending_value: pending value of the RAID attribute,
+ reflecting an unprocessed change
+ (eg. config job not completed)
+ :param read_only: indicates whether this RAID attribute can be
+ changed
+ :param fqdd: Fully Qualified Device Description of the RAID
+ Attribute
+ :param lower_bound: minimum value for the RAID attribute
+ :param upper_bound: maximum value for the RAID attribute
+ """
+ super(RAIDIntegerAttribute, self).__init__(name, instance_id,
+ current_value,
+ pending_value,
+ read_only, fqdd)
+ self.lower_bound = lower_bound
+ self.upper_bound = upper_bound
+
+ @classmethod
+ def parse(cls, raid_attr_xml):
+ """Parses XML and creates RAIDIntegerAttribute object"""
+
+ raid_attr = RAIDAttribute.parse(cls.namespace, raid_attr_xml)
+ lower_bound = utils.get_wsman_resource_attr(
+ raid_attr_xml, cls.namespace, 'LowerBound')
+ upper_bound = utils.get_wsman_resource_attr(
+ raid_attr_xml, cls.namespace, 'UpperBound')
+
+ if raid_attr.current_value:
+ raid_attr.current_value = int(raid_attr.current_value[0])
+ if raid_attr.pending_value:
+ raid_attr.pending_value = int(raid_attr.pending_value)
+
+ return cls(raid_attr.name, raid_attr.instance_id,
+ raid_attr.current_value, raid_attr.pending_value,
+ raid_attr.read_only, raid_attr.fqdd,
+ int(lower_bound), int(upper_bound))
+
+ def validate(self, new_value):
+ """Validates new value"""
+
+ val = int(new_value)
+ if val < self.lower_bound or val > self.upper_bound:
+ msg = ('Attribute %(attr)s cannot be set to value %(val)d.'
+ ' It must be between %(lower)d and %(upper)d.') % {
+ 'attr': self.name,
+ 'val': new_value,
+ 'lower': self.lower_bound,
+ 'upper': self.upper_bound}
+ return msg
class RAIDManagement(object):
+ NAMESPACES = [(uris.DCIM_RAIDEnumeration, RAIDEnumerableAttribute),
+ (uris.DCIM_RAIDString, RAIDStringAttribute),
+ (uris.DCIM_RAIDInteger, RAIDIntegerAttribute)]
+
def __init__(self, client):
"""Creates RAIDManagement object
@@ -155,6 +321,54 @@ def __init__(self, client):
"""
self.client = client
+ def list_raid_settings(self):
+ """List the RAID configuration settings
+
+ :returns: a dictionary with the RAID settings using InstanceID as the
+ key. The attributes are either RAIDEnumerableAttribute,
+ RAIDStringAttribute objects.
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the DRAC
+ interface
+ """
+
+ return utils.list_settings(self.client, self.NAMESPACES,
+ by_name=False)
+
+ def set_raid_settings(self, raid_fqdd, new_settings):
+ """Sets the RAID configuration
+
+ It sets the pending_value parameter for each of the attributes
+ passed in. For the values to be applied, a config job must
+ be created.
+ :param raid_fqdd: the FQDD of the RAID setting.
+ :param new_settings: a dictionary containing the proposed values, with
+ each key being the name of attribute and the value
+ being the proposed value.
+ :returns: a dictionary containing:
+ - The is_commit_required key with a boolean value indicating
+ whether a config job must be created for the values to be
+ applied.
+ - The is_reboot_required key with a RebootRequired enumerated
+ value indicating whether the server must be rebooted for the
+ values to be applied. Possible values are true and false.
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the DRAC
+ interface
+ """
+
+ return utils.set_settings('RAID',
+ self.client,
+ self.NAMESPACES,
+ new_settings,
+ uris.DCIM_RAIDService,
+ "DCIM_RAIDService",
+ "DCIM:RAIDService",
+ raid_fqdd,
+ by_name=False)
+
def list_raid_controllers(self):
"""Returns the list of RAID controllers
@@ -187,7 +401,11 @@ def _parse_drac_raid_controller(self, drac_controller):
self._get_raid_controller_attr(drac_controller,
'PrimaryStatus')],
firmware_version=self._get_raid_controller_attr(
- drac_controller, 'ControllerFirmwareVersion'))
+ drac_controller, 'ControllerFirmwareVersion'),
+ bus=self._get_raid_controller_attr(drac_controller, 'Bus').upper(),
+ supports_realtime=RAID_CONTROLLER_IS_REALTIME[
+ self._get_raid_controller_attr(
+ drac_controller, 'RealtimeCapability')])
def _get_raid_controller_attr(self, drac_controller, attr_name):
return utils.get_wsman_resource_attr(
@@ -218,7 +436,12 @@ def _parse_drac_virtual_disk(self, drac_disk):
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_raid_status = self._get_virtual_disk_attr(
+ drac_disk, 'RAIDStatus', allow_missing=True)
+ if drac_raid_status is None:
+ drac_raid_status = self._get_virtual_disk_attr(
+ drac_disk, 'RaidStatus')
+
drac_pending_operations = self._get_virtual_disk_attr(
drac_disk, 'PendingOperations')
@@ -231,7 +454,7 @@ def _parse_drac_virtual_disk(self, drac_disk):
nullable=True),
controller=fqdd.split(':')[-1],
raid_level=REVERSE_RAID_LEVELS[drac_raid_level],
- size_mb=int(size_b) / 2 ** 20,
+ size_mb=int(size_b) // 2 ** 20,
status=constants.PRIMARY_STATUS[drac_status],
raid_status=DISK_RAID_STATUS[drac_raid_status],
span_depth=int(self._get_virtual_disk_attr(drac_disk,
@@ -239,12 +462,19 @@ def _parse_drac_virtual_disk(self, drac_disk):
span_length=int(self._get_virtual_disk_attr(drac_disk,
'SpanLength')),
pending_operations=(
- VIRTUAL_DISK_PENDING_OPERATIONS[drac_pending_operations]))
+ VIRTUAL_DISK_PENDING_OPERATIONS[drac_pending_operations]),
+ physical_disks=self._get_virtual_disk_attrs(drac_disk,
+ 'PhysicalDiskIDs'))
- def _get_virtual_disk_attr(self, drac_disk, attr_name, nullable=False):
+ def _get_virtual_disk_attr(
+ self, drac_disk, attr_name, nullable=False, allow_missing=False):
return utils.get_wsman_resource_attr(
drac_disk, uris.DCIM_VirtualDiskView, attr_name,
- nullable=nullable)
+ nullable=nullable, allow_missing=allow_missing)
+
+ def _get_virtual_disk_attrs(self, drac_disk, attr_name):
+ return utils.get_all_wsman_resource_attrs(
+ drac_disk, uris.DCIM_VirtualDiskView, attr_name, nullable=False)
def list_physical_disks(self):
"""Returns the list of physical disks
@@ -261,44 +491,80 @@ def list_physical_disks(self):
drac_physical_disks = utils.find_xml(doc, 'DCIM_PhysicalDiskView',
uris.DCIM_PhysicalDiskView,
find_all=True)
+ physical_disks = [self._parse_drac_physical_disk(disk)
+ for disk in drac_physical_disks]
+
+ drac_pcie_disks = utils.find_xml(doc, 'DCIM_PCIeSSDView',
+ uris.DCIM_PCIeSSDView,
+ find_all=True)
+ pcie_disks = [self._parse_drac_physical_disk(disk,
+ uris.DCIM_PCIeSSDView) for disk in drac_pcie_disks]
+
+ return physical_disks + pcie_disks
- return [self._parse_drac_physical_disk(disk)
- for disk in drac_physical_disks]
+ def _parse_drac_physical_disk(self,
+ drac_disk,
+ uri=uris.DCIM_PhysicalDiskView):
+ fqdd = self._get_physical_disk_attr(drac_disk, 'FQDD', uri)
+ size_b = self._get_physical_disk_attr(drac_disk, 'SizeInBytes', uri)
- 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')
+ 'FreeSizeInBytes', uri)
+ if free_size_b is not None:
+ free_size_mb = int(free_size_b) // 2 ** 20
+ else:
+ free_size_mb = None
+
+ drac_status = self._get_physical_disk_attr(drac_disk, 'PrimaryStatus',
+ uri)
drac_raid_status = self._get_physical_disk_attr(drac_disk,
- 'RaidStatus')
- drac_media_type = self._get_physical_disk_attr(drac_disk, 'MediaType')
+ 'RaidStatus', uri)
+ if drac_raid_status is not None:
+ raid_status = DISK_RAID_STATUS[drac_raid_status]
+ else:
+ raid_status = None
+ drac_media_type = self._get_physical_disk_attr(drac_disk, 'MediaType',
+ uri)
drac_bus_protocol = self._get_physical_disk_attr(drac_disk,
- 'BusProtocol')
+ 'BusProtocol', uri)
+ bus = self._get_physical_disk_attr(drac_disk,
+ 'Bus', uri, allow_missing=True)
+
+ if bus is not None:
+ bus = bus.upper()
return PhysicalDisk(
id=fqdd,
description=self._get_physical_disk_attr(drac_disk,
- 'DeviceDescription'),
+ 'DeviceDescription',
+ uri),
controller=fqdd.split(':')[-1],
manufacturer=self._get_physical_disk_attr(drac_disk,
- 'Manufacturer'),
- model=self._get_physical_disk_attr(drac_disk, 'Model'),
+ 'Manufacturer', uri),
+ model=self._get_physical_disk_attr(drac_disk, 'Model', uri),
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,
+ size_mb=int(size_b) // 2 ** 20,
+ free_size_mb=free_size_mb,
serial_number=self._get_physical_disk_attr(drac_disk,
- 'SerialNumber'),
+ 'SerialNumber', uri),
firmware_version=self._get_physical_disk_attr(drac_disk,
- 'Revision'),
+ 'Revision', uri),
status=constants.PRIMARY_STATUS[drac_status],
- raid_status=DISK_RAID_STATUS[drac_raid_status])
-
- def _get_physical_disk_attr(self, drac_disk, attr_name):
+ raid_status=raid_status,
+ sas_address=self._get_physical_disk_attr(drac_disk, 'SASAddress',
+ uri, allow_missing=True),
+ device_protocol=self._get_physical_disk_attr(drac_disk,
+ 'DeviceProtocol',
+ uri,
+ allow_missing=True),
+ bus=bus)
+
+ def _get_physical_disk_attr(self, drac_disk, attr_name, uri,
+ allow_missing=False):
return utils.get_wsman_resource_attr(
- drac_disk, uris.DCIM_PhysicalDiskView, attr_name, nullable=True)
+ drac_disk, uri, attr_name, nullable=True,
+ allow_missing=allow_missing)
def convert_physical_disks(self, physical_disks, raid_enable):
"""Converts a list of physical disks into or out of RAID mode.
@@ -306,13 +572,17 @@ def convert_physical_disks(self, physical_disks, raid_enable):
Disks can be enabled or disabled for RAID mode.
:param physical_disks: list of FQDD ID strings of the physical disks
- to update
+ to update
:param raid_enable: boolean flag, set to True if the disk is to
- become part of the RAID. The same flag is applied to all
- listed disks
- :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.
+ become part of the RAID. The same flag is applied
+ to all listed disks
+ :returns: a dictionary containing:
+ - The is_commit_required key with the value always set to
+ True indicating that a config job must be created to
+ complete disk conversion.
+ - The is_reboot_required key with a RebootRequired enumerated
+ value indicating whether the server must be rebooted to
+ complete disk conversion.
"""
invocation = 'ConvertToRAID' if raid_enable else 'ConvertToNonRAID'
@@ -327,8 +597,8 @@ def convert_physical_disks(self, physical_disks, raid_enable):
selectors, properties,
expected_return_value=utils.RET_SUCCESS)
- return {'commit_required':
- utils.is_reboot_required(doc, uris.DCIM_RAIDService)}
+ return utils.build_return_dict(doc, uris.DCIM_RAIDService,
+ is_commit_required_value=True)
def create_virtual_disk(self, raid_controller, physical_disks, raid_level,
size_mb, disk_name=None, span_length=None,
@@ -345,9 +615,13 @@ def create_virtual_disk(self, raid_controller, physical_disks, raid_level,
: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.
+ :returns: a dictionary containing:
+ - The is_commit_required key with the value always set to
+ True indicating that a config job must be created to
+ complete virtual disk creation.
+ - The is_reboot_required key with a RebootRequired enumerated
+ value indicating whether the server must be rebooted to
+ complete virtual disk creation.
:raises: WSManRequestFailure on request failures
:raises: WSManInvalidResponse when receiving invalid response
:raises: DRACOperationFailed on error reported back by the DRAC
@@ -369,10 +643,7 @@ def create_virtual_disk(self, raid_controller, physical_disks, raid_level,
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)
+ utils.validate_integer_value(size_mb, 'size_mb', error_msgs)
virtual_disk_prop_names.append('Size')
virtual_disk_prop_values.append(str(size_mb))
@@ -418,8 +689,8 @@ def create_virtual_disk(self, raid_controller, physical_disks, raid_level,
selectors, properties,
expected_return_value=utils.RET_SUCCESS)
- return {'commit_required': utils.is_reboot_required(
- doc, uris.DCIM_RAIDService)}
+ return utils.build_return_dict(doc, uris.DCIM_RAIDService,
+ is_commit_required_value=True)
def delete_virtual_disk(self, virtual_disk):
"""Deletes a virtual disk
@@ -428,9 +699,13 @@ def delete_virtual_disk(self, virtual_disk):
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.
+ :returns: a dictionary containing:
+ - The is_commit_required key with the value always set to
+ True indicating that a config job must be created to
+ complete virtual disk deletion.
+ - The is_reboot_required key with a RebootRequired enumerated
+ value indicating whether the server must be rebooted to
+ complete virtual disk deletion.
:raises: WSManRequestFailure on request failures
:raises: WSManInvalidResponse when receiving invalid response
:raises: DRACOperationFailed on error reported back by the DRAC
@@ -448,5 +723,382 @@ def delete_virtual_disk(self, virtual_disk):
selectors, properties,
expected_return_value=utils.RET_SUCCESS)
- return {'commit_required': utils.is_reboot_required(
- doc, uris.DCIM_RAIDService)}
+ return utils.build_return_dict(doc, uris.DCIM_RAIDService,
+ is_commit_required_value=True)
+
+ def is_jbod_capable(self, raid_controller_fqdd):
+ """Find out if raid controller supports jbod
+
+ :param raid_controller_fqdd: The raid controller's fqdd
+ being being checked to see if it is jbod
+ capable.
+ :raises: DRACRequestFailed if unable to find any disks in the Ready
+ or non-RAID states
+ :raises: DRACOperationFailed on error reported back by the DRAC
+ and the exception message does not contain
+ NOT_SUPPORTED_MSG constant
+ """
+ is_jbod_capable = False
+
+ # Grab all the disks associated with the RAID controller
+ all_physical_disks = self.list_physical_disks()
+ physical_disks = [physical_disk for physical_disk in all_physical_disks
+ if physical_disk.controller == raid_controller_fqdd]
+
+ # If there is a disk in the Non-RAID state, then the controller is JBOD
+ # capable
+ ready_disk = None
+ for physical_disk in physical_disks:
+ if physical_disk.raid_status == 'non-RAID':
+ is_jbod_capable = True
+ break
+ elif not ready_disk and physical_disk.raid_status == 'ready':
+ ready_disk = physical_disk
+
+ if not is_jbod_capable:
+ if not ready_disk:
+ msg = "Unable to find a disk in the Ready state"
+ raise exceptions.DRACRequestFailed(msg)
+
+ # Try moving a disk in the Ready state to JBOD mode
+ try:
+ self.convert_physical_disks([ready_disk.id], False)
+ is_jbod_capable = True
+
+ # Flip the disk back to the Ready state. This results in the
+ # pending value being reset to nothing, so it effectively
+ # undoes the last command and makes the check non-destructive
+ self.convert_physical_disks([ready_disk.id], True)
+ except exceptions.DRACOperationFailed as ex:
+ # Fix for python 3, Exception.message no longer
+ # a valid attribute, str(ex) works for both 2.7
+ # and 3.x
+ if constants.NOT_SUPPORTED_MSG in str(ex):
+ pass
+ else:
+ raise
+
+ return is_jbod_capable
+
+ def is_raid_controller(self, raid_controller_fqdd, raid_controllers=None):
+ """Find out if object's fqdd is for a raid controller or not
+
+ :param raid_controller_fqdd: The object's fqdd we are testing to see
+ if it is a raid controller or not.
+ :param raid_controllers: A list of RAIDControllers used to check for
+ the presence of BOSS cards. If None, the
+ iDRAC will be queried for the list of
+ controllers.
+ :returns: boolean, True if the device is a RAID controller,
+ False if not.
+ """
+ return raid_controller_fqdd.startswith('RAID.') or \
+ self.is_boss_controller(raid_controller_fqdd, raid_controllers)
+
+ def is_boss_controller(self, raid_controller_fqdd, raid_controllers=None):
+ """Find out if a RAID controller a BOSS card or not
+
+ :param raid_controller_fqdd: The object's fqdd we are testing to see
+ if it is a BOSS card or not.
+ :param raid_controllers: A list of RAIDController to scan for presence
+ of BOSS card, if None the drac will be queried
+ for the list of controllers which will then be
+ scanned.
+ :returns: boolean, True if the device is a BOSS card, False if not.
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the DRAC
+ interface
+ """
+ if raid_controllers is None:
+ raid_controllers = self.list_raid_controllers()
+ boss_raid_controllers = [
+ c.id for c in raid_controllers if c.model.startswith('BOSS')]
+ return raid_controller_fqdd in boss_raid_controllers
+
+ def _check_disks_status(self, mode, physical_disks,
+ controllers_to_physical_disk_ids):
+ """Find disks that failed, need to be configured, or need no change.
+
+ Inspect all the controllers drives and:
+ - See if there are any disks in a failed or unknown state and raise
+ a ValueException where appropriate.
+ - If a controller has disks that still need to be configured add
+ them to the controllers_to_physical_disk_ids dict for the
+ appropriate controller.
+ - If a disk is already in the appropriate state, do nothing, this
+ function should behave in an idempotent manner.
+
+ :param mode: constants.RaidStatus enumeration used to
+ determine what raid status to check for.
+ :param physical_disks: all physical disks
+ :param controllers_to_physical_disk_ids: Dictionary of controllers and
+ corresponding disk ids to convert to the requested mode.
+ :returns: a dictionary mapping controller FQDDs to the list of
+ physical disks that need to be converted for that controller.
+ :raises: ValueError: Exception message will list failed drives and
+ drives whose state cannot be changed at this time, drive
+ state is not "ready" or "non-RAID".
+ """
+ controllers_to_physical_disk_ids = copy.deepcopy(
+ controllers_to_physical_disk_ids)
+
+ p_disk_id_to_status = {}
+ for physical_disk in physical_disks:
+ p_disk_id_to_status[physical_disk.id] = physical_disk.raid_status
+ failed_disks = []
+ bad_disks = []
+
+ jbod = constants.RaidStatus.jbod
+ raid = constants.RaidStatus.raid
+ for controller, physical_disk_ids \
+ in controllers_to_physical_disk_ids.items():
+ final_physical_disk_ids = []
+ for physical_disk_id in physical_disk_ids:
+ raid_status = p_disk_id_to_status[physical_disk_id]
+ LOG.debug("RAID status for disk id: %s is: %s",
+ physical_disk_id, raid_status)
+ if ((mode == jbod and raid_status == "non-RAID") or
+ (mode == raid and raid_status == "ready")):
+ # This means the disk is already in the desired state,
+ # so skip it
+ continue
+ elif ((mode == jbod and raid_status == "ready") or
+ (mode == raid and raid_status == "non-RAID")):
+ # This disk is moving from a state we expect to RAID or
+ # JBOD, so keep it
+ final_physical_disk_ids.append(physical_disk_id)
+ elif raid_status == "failed":
+ failed_disks.append(physical_disk_id)
+ else:
+ # This disk is in one of many states that we don't know
+ # what to do with, so pitch it
+ bad_disks.append("{} ({})".format(physical_disk_id,
+ raid_status))
+
+ controllers_to_physical_disk_ids[controller] = (
+ final_physical_disk_ids)
+
+ if failed_disks or bad_disks:
+ error_msg = ""
+
+ if failed_disks:
+ error_msg += ("The following drives have failed: "
+ "{failed_disks}. Manually check the status"
+ " of all drives and replace as necessary, then"
+ " try again.").format(
+ failed_disks=" ".join(failed_disks))
+
+ if bad_disks:
+ if failed_disks:
+ error_msg += "\n"
+ error_msg += ("Unable to change the state of the following "
+ "drives because their status is not ready "
+ "or non-RAID: {}. Bring up the RAID "
+ "controller GUI on this node and change the "
+ "drives' status to ready or non-RAID.").format(
+ ", ".join(bad_disks))
+
+ raise ValueError(error_msg)
+
+ return controllers_to_physical_disk_ids
+
+ def change_physical_disk_state(self, mode,
+ controllers_to_physical_disk_ids=None):
+ """Convert disks RAID status
+
+ This method intelligently converts the requested physical disks from
+ RAID to JBOD or vice versa. It does this by only converting the
+ disks that are not already in the correct state.
+
+ :param mode: constants.RaidStatus enumeration that indicates the mode
+ to change the disks to.
+ :param controllers_to_physical_disk_ids: Dictionary of controllers and
+ corresponding disk ids to convert to the requested mode.
+ :returns: a dictionary containing:
+ - conversion_results, a dictionary that maps controller ids
+ to the conversion results for that controller. The
+ conversion results are a dict that contains:
+ - The is_commit_required key with the value always set to
+ True indicating that a config job must be created to
+ complete disk conversion.
+ - The is_reboot_required key with a RebootRequired
+ enumerated value indicating whether the server must be
+ rebooted to complete disk conversion.
+ :raises: DRACOperationFailed on error reported back by the DRAC and the
+ exception message does not contain NOT_SUPPORTED_MSG constant.
+ :raises: Exception on unknown error.
+ """
+ physical_disks = self.list_physical_disks()
+
+ raid = constants.RaidStatus.raid
+
+ if not controllers_to_physical_disk_ids:
+ controllers_to_physical_disk_ids = collections.defaultdict(list)
+
+ all_controllers = self.list_raid_controllers()
+ for physical_d in physical_disks:
+ # Weed out disks that are not attached to a RAID controller
+ if self.is_raid_controller(physical_d.controller,
+ all_controllers):
+ physical_disk_ids = controllers_to_physical_disk_ids[
+ physical_d.controller]
+
+ physical_disk_ids.append(physical_d.id)
+
+ '''Modify controllers_to_physical_disk_ids dict by inspecting desired
+ status vs current status of each controller's disks.
+ Raise exception if there are any failed drives or
+ drives not in status 'ready' or 'non-RAID'
+ '''
+ final_ctls_to_phys_disk_ids = self._check_disks_status(
+ mode, physical_disks, controllers_to_physical_disk_ids)
+
+ controllers_to_results = {}
+ for controller, physical_disk_ids \
+ in final_ctls_to_phys_disk_ids.items():
+ if physical_disk_ids:
+ LOG.debug("Converting the following disks to {} on RAID "
+ "controller {}: {}".format(
+ mode, controller, str(physical_disk_ids)))
+ try:
+ conversion_results = \
+ self.convert_physical_disks(physical_disk_ids,
+ mode == raid)
+ except exceptions.DRACOperationFailed as ex:
+ if constants.NOT_SUPPORTED_MSG in str(ex):
+ LOG.debug("Controller {} does not support "
+ "JBOD mode".format(controller))
+ controllers_to_results[controller] = \
+ utils.build_return_dict(
+ doc=None,
+ resource_uri=None,
+ is_commit_required_value=False,
+ is_reboot_required_value=constants.
+ RebootRequired.false)
+ else:
+ raise
+ else:
+ controllers_to_results[controller] = conversion_results
+ else:
+ controllers_to_results[controller] = \
+ utils.build_return_dict(
+ doc=None,
+ resource_uri=None,
+ is_commit_required_value=False,
+ is_reboot_required_value=constants.
+ RebootRequired.false)
+
+ return {'conversion_results': controllers_to_results}
+
+ def is_realtime_supported(self, raid_controller_fqdd):
+ """Find if controller supports realtime or not
+
+ :param raid_controller_fqdd: ID of RAID controller
+ :returns: True or False
+ """
+ drac_raid_controllers = self.list_raid_controllers()
+ realtime_controller = [cnt.id for cnt in drac_raid_controllers
+ if cnt.supports_realtime]
+
+ if raid_controller_fqdd in realtime_controller:
+ return True
+
+ return False
+
+ def reset_raid_config(self, raid_controller):
+ """Delete all virtual disk and unassign all hotspares
+
+ The job to reset the RAID controller config will be in pending state.
+ For the changes to be applied, a config job must be created.
+
+ :param raid_controller: id of the RAID controller
+ :returns: a dictionary containing:
+ - The is_commit_required key with the value always set to
+ True indicating that a config job must be created to
+ reset configuration.
+ - The is_reboot_required key with a RebootRequired enumerated
+ value indicating whether the server must be rebooted to
+ reset configuration.
+ :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': raid_controller}
+
+ doc = self.client.invoke(uris.DCIM_RAIDService, 'ResetConfig',
+ selectors, properties,
+ expected_return_value=utils.RET_SUCCESS)
+
+ return utils.build_return_dict(doc, uris.DCIM_RAIDService,
+ is_commit_required_value=True)
+
+ def clear_foreign_config(self, raid_controller):
+ """Free up foreign drives
+
+ The job to clear foreign config will be in pending state.
+ For the changes to be applied, a config job must be created.
+
+ :param raid_controller: id of the RAID controller
+ :returns: a dictionary containing:
+ - The is_commit_required key with the value always set to
+ True indicating that a config job must be created to
+ clear foreign configuration.
+ - The is_reboot_required key with a RebootRequired enumerated
+ value indicating whether the server must be rebooted to
+ clear foreign configuration.
+ :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': raid_controller}
+
+ doc = self.client.invoke(uris.DCIM_RAIDService, 'ClearForeignConfig',
+ selectors, properties,
+ check_return_value=False)
+
+ is_commit_required_value = True
+ is_reboot_required_value = None
+
+ ret_value = utils.find_xml(doc,
+ 'ReturnValue',
+ uris.DCIM_RAIDService).text
+
+ if ret_value == utils.RET_ERROR:
+ message_id = utils.find_xml(doc,
+ 'MessageID',
+ uris.DCIM_RAIDService).text
+
+ # A MessageID 'STOR018'/'STOR058' indicates no foreign drive was
+ # detected. Return a value which informs the caller nothing
+ # further needs to be done.
+ no_foreign_drives_detected = any(
+ stor_id == message_id for stor_id in NO_FOREIGN_DRIVES)
+ if no_foreign_drives_detected:
+ is_commit_required_value = False
+ is_reboot_required_value = constants.RebootRequired.false
+ else:
+ message = utils.find_xml(doc,
+ 'Message',
+ uris.DCIM_RAIDService).text
+ raise exceptions.DRACOperationFailed(
+ drac_messages=message)
+
+ return utils.build_return_dict(
+ doc, uris.DCIM_RAIDService,
+ is_commit_required_value=is_commit_required_value,
+ is_reboot_required_value=is_reboot_required_value)
diff --git a/dracclient/resources/system.py b/dracclient/resources/system.py
new file mode 100644
index 0000000..1069cc3
--- /dev/null
+++ b/dracclient/resources/system.py
@@ -0,0 +1,279 @@
+#
+# 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.
+
+from dracclient.resources import uris
+from dracclient import utils
+from dracclient import wsman
+
+
+class SystemConfiguration(object):
+
+ def __init__(self, client):
+ """Creates SystemManagement object
+
+ :param client: an instance of WSManClient
+ """
+ self.client = client
+
+ def list_system_settings(self):
+ """List the System configuration settings
+
+ :returns: a dictionary with the System settings using its name as the
+ key. The attributes are either SystemEnumerableAttribute,
+ SystemStringAttribute or SystemIntegerAttribute objects.
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the DRAC
+ interface
+ """
+ result = {}
+ namespaces = [(uris.DCIM_SystemEnumeration, SystemEnumerableAttribute),
+ (uris.DCIM_SystemString, SystemStringAttribute),
+ (uris.DCIM_SystemInteger, SystemIntegerAttribute)]
+ for (namespace, attr_cls) in namespaces:
+ attribs = self._get_config(namespace, attr_cls)
+ result.update(attribs)
+ return result
+
+ def _get_config(self, resource, attr_cls):
+ result = {}
+
+ doc = self.client.enumerate(resource)
+
+ items = doc.find('.//{%s}Items' % wsman.NS_WSMAN)
+
+ if items is not None:
+ for item in items:
+ attribute = attr_cls.parse(item)
+ result[attribute.instance_id] = attribute
+ return result
+
+
+class SystemAttribute(object):
+ """Generic System attribute class"""
+
+ def __init__(self, name, instance_id, current_value, pending_value,
+ read_only, fqdd, group_id):
+ """Creates SystemAttribute object
+
+ :param name: name of the System attribute
+ :param instance_id: InstanceID of the System attribute
+ :param current_value: current value of the System attribute
+ :param pending_value: pending value of the System attribute, reflecting
+ an unprocessed change (eg. config job not completed)
+ :param read_only: indicates whether this System attribute can be
+ changed
+ :param fqdd: Fully Qualified Device Description of the System attribute
+ :param group_id: GroupID of System attribute
+ """
+ self.name = name
+ self.instance_id = instance_id
+ self.current_value = current_value
+ self.pending_value = pending_value
+ self.read_only = read_only
+ self.fqdd = fqdd
+ self.group_id = group_id
+
+ def __eq__(self, other):
+ return self.__dict__ == other.__dict__
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+ @classmethod
+ def parse(cls, namespace, system_attr_xml):
+ """Parses XML and creates SystemAttribute object"""
+
+ name = utils.get_wsman_resource_attr(
+ system_attr_xml, namespace, 'AttributeName')
+ instance_id = utils.get_wsman_resource_attr(
+ system_attr_xml, namespace, 'InstanceID')
+ current_value = utils.get_wsman_resource_attr(
+ system_attr_xml, namespace, 'CurrentValue', nullable=True)
+ pending_value = utils.get_wsman_resource_attr(
+ system_attr_xml, namespace, 'PendingValue', nullable=True)
+ read_only = utils.get_wsman_resource_attr(
+ system_attr_xml, namespace, 'IsReadOnly')
+ fqdd = utils.get_wsman_resource_attr(
+ system_attr_xml, namespace, 'FQDD')
+ group_id = utils.get_wsman_resource_attr(
+ system_attr_xml, namespace, 'GroupID')
+
+ return cls(name, instance_id, current_value, pending_value,
+ (read_only == 'true'), fqdd, group_id)
+
+
+class SystemEnumerableAttribute(SystemAttribute):
+ """Enumerable System attribute class"""
+
+ namespace = uris.DCIM_SystemEnumeration
+
+ def __init__(self, name, instance_id, current_value, pending_value,
+ read_only, fqdd, group_id, possible_values):
+ """Creates SystemEnumerableAttribute object
+
+ :param name: name of the System attribute
+ :param instance_id: InstanceID of the System attribute
+ :param current_value: current value of the System attribute
+ :param pending_value: pending value of the System attribute, reflecting
+ an unprocessed change (eg. config job not completed)
+ :param read_only: indicates whether this System attribute can be
+ changed
+ :param fqdd: Fully Qualified Device Description of the System attribute
+ :param group_id: GroupID of System attribute
+ :param possible_values: list containing the allowed values for the
+ System attribute
+ """
+ super(SystemEnumerableAttribute, self).__init__(name, instance_id,
+ current_value,
+ pending_value,
+ read_only, fqdd,
+ group_id)
+ self.possible_values = possible_values
+
+ @classmethod
+ def parse(cls, system_attr_xml):
+ """Parses XML and creates SystemEnumerableAttribute object"""
+
+ system_attr = SystemAttribute.parse(
+ cls.namespace, system_attr_xml)
+ possible_values = [attr.text for attr
+ in utils.find_xml(system_attr_xml, 'PossibleValues',
+ cls.namespace, find_all=True)]
+
+ return cls(system_attr.name, system_attr.instance_id,
+ system_attr.current_value, system_attr.pending_value,
+ system_attr.read_only, system_attr.fqdd,
+ system_attr.group_id, possible_values)
+
+ def validate(self, new_value):
+ """Validates new value"""
+
+ if str(new_value) not in self.possible_values:
+ msg = ("Attribute '%(attr)s' cannot be set to value '%(val)s'."
+ " It must be in %(possible_values)r.") % {
+ 'attr': self.name,
+ 'val': new_value,
+ 'possible_values': self.possible_values}
+ return msg
+
+
+class SystemStringAttribute(SystemAttribute):
+ """String System attribute class"""
+
+ namespace = uris.DCIM_SystemString
+
+ def __init__(self, name, instance_id, current_value, pending_value,
+ read_only, fqdd, group_id, min_length, max_length):
+ """Creates SystemStringAttribute object
+
+ :param name: name of the System attribute
+ :param instance_id: InstanceID of the System attribute
+ :param current_value: current value of the System attribute
+ :param pending_value: pending value of the System attribute, reflecting
+ an unprocessed change (eg. config job not completed)
+ :param read_only: indicates whether this System attribute can be
+ changed
+ :param fqdd: Fully Qualified Device Description of the System attribute
+ :param group_id: GroupID of System attribute
+ :param min_length: minimum length of the string
+ :param max_length: maximum length of the string
+ """
+ super(SystemStringAttribute, self).__init__(name, instance_id,
+ current_value,
+ pending_value, read_only,
+ fqdd, group_id)
+ self.min_length = min_length
+ self.max_length = max_length
+
+ @classmethod
+ def parse(cls, system_attr_xml):
+ """Parses XML and creates SystemStringAttribute object"""
+
+ system_attr = SystemAttribute.parse(
+ cls.namespace, system_attr_xml)
+ min_length = int(utils.get_wsman_resource_attr(
+ system_attr_xml, cls.namespace, 'MinLength'))
+ max_length = int(utils.get_wsman_resource_attr(
+ system_attr_xml, cls.namespace, 'MaxLength'))
+
+ return cls(system_attr.name, system_attr.instance_id,
+ system_attr.current_value, system_attr.pending_value,
+ system_attr.read_only, system_attr.fqdd,
+ system_attr.group_id, min_length, max_length)
+
+
+class SystemIntegerAttribute(SystemAttribute):
+ """Integer System attribute class"""
+
+ namespace = uris.DCIM_SystemInteger
+
+ def __init__(self, name, instance_id, current_value, pending_value,
+ read_only, fqdd, group_id, lower_bound, upper_bound):
+ """Creates SystemIntegerAttribute object
+
+ :param name: name of the System attribute
+ :param instance_id: InstanceID of the System attribute
+ :param current_value: current value of the System attribute
+ :param pending_value: pending value of the System attribute, reflecting
+ an unprocessed change (eg. config job not completed)
+ :param read_only: indicates whether this System attribute can be
+ changed
+ :param fqdd: Fully Qualified Device Description of the System attribute
+ :param group_id: GroupID of System attribute
+ :param lower_bound: minimum value for the System attribute
+ :param upper_bound: maximum value for the BOIS attribute
+ """
+ super(SystemIntegerAttribute, self).__init__(name, instance_id,
+ current_value,
+ pending_value, read_only,
+ fqdd, group_id)
+ self.lower_bound = lower_bound
+ self.upper_bound = upper_bound
+
+ @classmethod
+ def parse(cls, system_attr_xml):
+ """Parses XML and creates SystemIntegerAttribute object"""
+
+ system_attr = SystemAttribute.parse(cls.namespace, system_attr_xml)
+ lower_bound = utils.get_wsman_resource_attr(
+ system_attr_xml, cls.namespace, 'LowerBound', nullable=True)
+ upper_bound = utils.get_wsman_resource_attr(
+ system_attr_xml, cls.namespace, 'UpperBound', nullable=True)
+
+ if system_attr.current_value:
+ system_attr.current_value = int(system_attr.current_value)
+ if system_attr.pending_value:
+ system_attr.pending_value = int(system_attr.pending_value)
+
+ if lower_bound:
+ lower_bound = int(lower_bound)
+ if upper_bound:
+ upper_bound = int(upper_bound)
+ return cls(system_attr.name, system_attr.instance_id,
+ system_attr.current_value, system_attr.pending_value,
+ system_attr.read_only, system_attr.fqdd,
+ system_attr.group_id, lower_bound, upper_bound)
+
+ def validate(self, new_value):
+ """Validates new value"""
+
+ val = int(new_value)
+ if val < self.lower_bound or val > self.upper_bound:
+ msg = ('Attribute %(attr)s cannot be set to value %(val)d.'
+ ' It must be between %(lower)d and %(upper)d.') % {
+ 'attr': self.name,
+ 'val': new_value,
+ 'lower': self.lower_bound,
+ 'upper': self.upper_bound}
+ return msg
diff --git a/dracclient/resources/uris.py b/dracclient/resources/uris.py
index b1dea17..218d85d 100644
--- a/dracclient/resources/uris.py
+++ b/dracclient/resources/uris.py
@@ -43,21 +43,79 @@
DCIM_CPUView = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
'DCIM_CPUView')
+DCIM_iDRACCardEnumeration = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/'
+ '2/DCIM_iDRACCardEnumeration')
+
+DCIM_iDRACCardInteger = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
+ 'DCIM_iDRACCardInteger')
+
+DCIM_iDRACCardService = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
+ 'DCIM_iDRACCardService')
+
+DCIM_iDRACCardString = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
+ 'DCIM_iDRACCardString')
+
+DCIM_JobService = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
+ 'DCIM_JobService')
+
+DCIM_LCEnumeration = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
+ 'DCIM_LCEnumeration')
+
+DCIM_LCService = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
+ 'DCIM_LCService')
+
+DCIM_LCString = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
+ 'DCIM_LCString')
+
DCIM_LifecycleJob = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
'DCIM_LifecycleJob')
DCIM_MemoryView = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
'DCIM_MemoryView')
+DCIM_NICEnumeration = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
+ 'DCIM_NICEnumeration')
+
+DCIM_NICInteger = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
+ 'DCIM_NICInteger')
+
+DCIM_NICService = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
+ 'DCIM_NICService')
+
+DCIM_NICString = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
+ 'DCIM_NICString')
+
DCIM_NICView = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
'DCIM_NICView')
+DCIM_PCIeSSDView = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
+ 'DCIM_PCIeSSDView')
+
DCIM_PhysicalDiskView = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
'DCIM_PhysicalDiskView')
+DCIM_RAIDEnumeration = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
+ 'DCIM_RAIDEnumeration')
+
+DCIM_RAIDInteger = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
+ 'DCIM_RAIDInteger')
+
DCIM_RAIDService = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
'DCIM_RAIDService')
+
+DCIM_RAIDString = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
+ 'DCIM_RAIDString')
+
+DCIM_SystemEnumeration = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
+ 'DCIM_SystemEnumeration')
+
+DCIM_SystemInteger = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
+ 'DCIM_SystemInteger')
+
+DCIM_SystemString = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
+ 'DCIM_SystemString')
+
DCIM_SystemView = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
'DCIM_SystemView')
diff --git a/dracclient/tests/test_bios.py b/dracclient/tests/test_bios.py
index 6aead8b..0cc4c25 100644
--- a/dracclient/tests/test_bios.py
+++ b/dracclient/tests/test_bios.py
@@ -12,12 +12,13 @@
# under the License.
import re
+from unittest import mock
import lxml.etree
-import mock
import requests_mock
import dracclient.client
+from dracclient import constants
from dracclient import exceptions
from dracclient.resources import bios
import dracclient.resources.job
@@ -29,6 +30,8 @@
@requests_mock.Mocker()
+@mock.patch.object(dracclient.client.WSManClient, 'wait_until_idrac_is_ready',
+ spec_set=True, autospec=True)
class ClientPowerManagementTestCase(base.BaseTest):
def setUp(self):
@@ -36,14 +39,16 @@ def setUp(self):
self.drac_client = dracclient.client.DRACClient(
**test_utils.FAKE_ENDPOINT)
- def test_get_power_state(self, mock_requests):
+ def test_get_power_state(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
mock_requests.post(
'https://1.2.3.4:443/wsman',
text=test_utils.BIOSEnumerations[uris.DCIM_ComputerSystem]['ok'])
self.assertEqual('POWER_ON', self.drac_client.get_power_state())
- def test_set_power_state(self, mock_requests):
+ def test_set_power_state(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
mock_requests.post(
'https://1.2.3.4:443/wsman',
text=test_utils.BIOSInvocations[
@@ -51,7 +56,8 @@ def test_set_power_state(self, mock_requests):
self.assertIsNone(self.drac_client.set_power_state('POWER_ON'))
- def test_set_power_state_fail(self, mock_requests):
+ def test_set_power_state_fail(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
mock_requests.post(
'https://1.2.3.4:443/wsman',
text=test_utils.BIOSInvocations[
@@ -60,11 +66,15 @@ def test_set_power_state_fail(self, mock_requests):
self.assertRaises(exceptions.DRACOperationFailed,
self.drac_client.set_power_state, 'POWER_ON')
- def test_set_power_state_invalid_target_state(self, mock_requests):
+ def test_set_power_state_invalid_target_state(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
self.assertRaises(exceptions.InvalidParameterValue,
self.drac_client.set_power_state, 'foo')
+@requests_mock.Mocker()
+@mock.patch.object(dracclient.client.WSManClient, 'wait_until_idrac_is_ready',
+ spec_set=True, autospec=True)
class ClientBootManagementTestCase(base.BaseTest):
def setUp(self):
@@ -72,8 +82,8 @@ def setUp(self):
self.drac_client = dracclient.client.DRACClient(
**test_utils.FAKE_ENDPOINT)
- @requests_mock.Mocker()
- def test_list_boot_modes(self, mock_requests):
+ def test_list_boot_modes(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
expected_boot_mode = bios.BootMode(id='IPL', name='BootSeq',
is_current=True, is_next=True)
mock_requests.post(
@@ -86,8 +96,8 @@ def test_list_boot_modes(self, mock_requests):
self.assertEqual(5, len(boot_modes))
self.assertIn(expected_boot_mode, boot_modes)
- @requests_mock.Mocker()
- def test_list_boot_devices(self, mock_requests):
+ def test_list_boot_devices(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
expected_boot_device = bios.BootDevice(
id=('IPL:BIOS.Setup.1-1#BootSeq#NIC.Embedded.1-1-1#'
'fbeeb18f19fd4e768c941e66af4fc424'),
@@ -116,11 +126,11 @@ def test_list_boot_devices(self, mock_requests):
self.assertEqual(
2, boot_devices['IPL'][2].pending_assigned_sequence)
- @requests_mock.Mocker()
@mock.patch.object(lifecycle_controller.LifecycleControllerManagement,
'get_version', spec_set=True, autospec=True)
def test_list_boot_devices_11g(self, mock_requests,
- mock_get_lifecycle_controller_version):
+ mock_get_lifecycle_controller_version,
+ mock_wait_until_idrac_is_ready):
expected_boot_device = bios.BootDevice(
id=('IPL:NIC.Embedded.1-1:082927b7c62a9f52ef0d65a33416d76c'),
boot_mode='IPL',
@@ -150,8 +160,8 @@ def test_list_boot_devices_11g(self, mock_requests,
self.assertEqual(
2, boot_devices['IPL'][2].pending_assigned_sequence)
- @requests_mock.Mocker()
- def test_change_boot_device_order(self, mock_requests):
+ def test_change_boot_device_order(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
mock_requests.post(
'https://1.2.3.4:443/wsman',
text=test_utils.BIOSInvocations[
@@ -163,7 +173,8 @@ def test_change_boot_device_order(self, mock_requests):
@mock.patch.object(dracclient.client.WSManClient, 'invoke',
spec_set=True, autospec=True)
- def test_change_boot_device_order_list(self, mock_invoke):
+ def test_change_boot_device_order_list(self, mock_requests, mock_invoke,
+ mock_wait_until_idrac_is_ready):
expected_selectors = {'InstanceID': 'IPL'}
expected_properties = {'source': ['foo', 'bar', 'baz']}
mock_invoke.return_value = lxml.etree.fromstring(
@@ -178,8 +189,8 @@ def test_change_boot_device_order_list(self, mock_invoke):
'ChangeBootOrderByInstanceID', expected_selectors,
expected_properties, expected_return_value=utils.RET_SUCCESS)
- @requests_mock.Mocker()
- def test_change_boot_device_order_error(self, mock_requests):
+ def test_change_boot_device_order_error(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
mock_requests.post(
'https://1.2.3.4:443/wsman',
text=test_utils.BIOSInvocations[
@@ -191,6 +202,9 @@ def test_change_boot_device_order_error(self, mock_requests):
self.drac_client.change_boot_device_order, 'IPL', 'foo')
+@requests_mock.Mocker()
+@mock.patch.object(dracclient.client.WSManClient, 'wait_until_idrac_is_ready',
+ spec_set=True, autospec=True)
class ClientBIOSConfigurationTestCase(base.BaseTest):
def setUp(self):
@@ -198,8 +212,8 @@ def setUp(self):
self.drac_client = dracclient.client.DRACClient(
**test_utils.FAKE_ENDPOINT)
- @requests_mock.Mocker()
- def test_list_bios_settings_by_instance_id(self, mock_requests):
+ def test_list_bios_settings_by_instance_id(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
expected_enum_attr = bios.BIOSEnumerableAttribute(
name='MemTest',
instance_id='BIOS.Setup.1-1:MemTest',
@@ -248,8 +262,8 @@ def test_list_bios_settings_by_instance_id(self, mock_requests):
self.assertEqual(expected_integer_attr, bios_settings[
'BIOS.Setup.1-1:Proc1NumCores'])
- @requests_mock.Mocker()
- def test_list_bios_settings_by_name(self, mock_requests):
+ def test_list_bios_settings_by_name(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
expected_enum_attr = bios.BIOSEnumerableAttribute(
name='MemTest',
instance_id='BIOS.Setup.1-1:MemTest',
@@ -296,9 +310,8 @@ def test_list_bios_settings_by_name(self, mock_requests):
self.assertIn('Proc1NumCores', bios_settings)
self.assertEqual(expected_integer_attr, bios_settings['Proc1NumCores'])
- @requests_mock.Mocker()
def test_list_bios_settings_by_name_with_colliding_attrs(
- self, mock_requests):
+ self, mock_requests, mock_wait_until_idrac_is_ready):
mock_requests.post('https://1.2.3.4:443/wsman', [
{'text': test_utils.BIOSEnumerations[
uris.DCIM_BIOSEnumeration]['ok']},
@@ -310,10 +323,10 @@ def test_list_bios_settings_by_name_with_colliding_attrs(
self.assertRaises(exceptions.DRACOperationFailed,
self.drac_client.list_bios_settings, by_name=True)
- @requests_mock.Mocker()
@mock.patch.object(dracclient.client.WSManClient, 'invoke',
spec_set=True, autospec=True)
- def test_set_bios_settings(self, mock_requests, mock_invoke):
+ def test_set_bios_settings(self, mock_requests, mock_invoke,
+ mock_wait_until_idrac_is_ready):
expected_selectors = {'CreationClassName': 'DCIM_BIOSService',
'SystemName': 'DCIM:ComputerSystem',
'Name': 'DCIM:BIOSService',
@@ -333,15 +346,19 @@ def test_set_bios_settings(self, mock_requests, mock_invoke):
'SetAttributes']['ok'])
result = self.drac_client.set_bios_settings(
- {'ProcVirtualization': 'Disabled'})
+ {'ProcVirtualization': 'Disabled',
+ 'DynamicCoreAllocation': 'Disabled'})
- self.assertEqual({'commit_required': True}, result)
+ self.assertEqual({'is_commit_required': True,
+ 'is_reboot_required': constants.RebootRequired.true},
+ result)
mock_invoke.assert_called_once_with(
mock.ANY, uris.DCIM_BIOSService, 'SetAttributes',
- expected_selectors, expected_properties)
+ expected_selectors, expected_properties,
+ wait_for_idrac=True)
- @requests_mock.Mocker()
- def test_set_bios_settings_error(self, mock_requests):
+ def test_set_bios_settings_error(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
mock_requests.post('https://1.2.3.4:443/wsman', [
{'text': test_utils.BIOSEnumerations[
uris.DCIM_BIOSEnumeration]['ok']},
@@ -356,8 +373,8 @@ def test_set_bios_settings_error(self, mock_requests):
self.drac_client.set_bios_settings,
{'ProcVirtualization': 'Disabled'})
- @requests_mock.Mocker()
- def test_set_bios_settings_with_unknown_attr(self, mock_requests):
+ def test_set_bios_settings_with_unknown_attr(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
mock_requests.post('https://1.2.3.4:443/wsman', [
{'text': test_utils.BIOSEnumerations[
uris.DCIM_BIOSEnumeration]['ok']},
@@ -369,8 +386,8 @@ def test_set_bios_settings_with_unknown_attr(self, mock_requests):
self.assertRaises(exceptions.InvalidParameterValue,
self.drac_client.set_bios_settings, {'foo': 'bar'})
- @requests_mock.Mocker()
- def test_set_bios_settings_with_unchanged_attr(self, mock_requests):
+ def test_set_bios_settings_with_unchanged_attr(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
mock_requests.post('https://1.2.3.4:443/wsman', [
{'text': test_utils.BIOSEnumerations[
uris.DCIM_BIOSEnumeration]['ok']},
@@ -382,10 +399,13 @@ def test_set_bios_settings_with_unchanged_attr(self, mock_requests):
result = self.drac_client.set_bios_settings(
{'ProcVirtualization': 'Enabled'})
- self.assertEqual({'commit_required': False}, result)
+ self.assertEqual({'is_commit_required': False,
+ 'is_reboot_required':
+ constants.RebootRequired.false},
+ result)
- @requests_mock.Mocker()
- def test_set_bios_settings_with_readonly_attr(self, mock_requests):
+ def test_set_bios_settings_with_readonly_attr(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
expected_message = ("Cannot set read-only BIOS attributes: "
"['Proc1NumCores'].")
mock_requests.post('https://1.2.3.4:443/wsman', [
@@ -400,8 +420,8 @@ def test_set_bios_settings_with_readonly_attr(self, mock_requests):
exceptions.DRACOperationFailed, re.escape(expected_message),
self.drac_client.set_bios_settings, {'Proc1NumCores': 42})
- @requests_mock.Mocker()
- def test_set_bios_settings_with_incorrect_enum_value(self, mock_requests):
+ def test_set_bios_settings_with_incorrect_enum_value(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
expected_message = ("Attribute 'MemTest' cannot be set to value "
"'foo'. It must be in ['Enabled', 'Disabled'].")
mock_requests.post('https://1.2.3.4:443/wsman', [
@@ -416,8 +436,8 @@ def test_set_bios_settings_with_incorrect_enum_value(self, mock_requests):
exceptions.DRACOperationFailed, re.escape(expected_message),
self.drac_client.set_bios_settings, {'MemTest': 'foo'})
- @requests_mock.Mocker()
- def test_set_bios_settings_with_incorrect_regexp(self, mock_requests):
+ def test_set_bios_settings_with_incorrect_regexp(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
expected_message = ("Attribute 'SystemModelName' cannot be set to "
"value 'bar.' It must match regex 'foo'.")
mock_requests.post('https://1.2.3.4:443/wsman', [
@@ -432,8 +452,8 @@ def test_set_bios_settings_with_incorrect_regexp(self, mock_requests):
exceptions.DRACOperationFailed, re.escape(expected_message),
self.drac_client.set_bios_settings, {'SystemModelName': 'bar'})
- @requests_mock.Mocker()
- def test_set_bios_settings_with_out_of_bounds_value(self, mock_requests):
+ def test_set_bios_settings_with_out_of_bounds_value(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
expected_message = ('Attribute Proc1NumCores cannot be set to value '
'-42. It must be between 0 and 65535.')
mock_requests.post('https://1.2.3.4:443/wsman', [
@@ -464,7 +484,8 @@ def test_commit_pending_bios_changes(self, mock_create_config_job):
mock_create_config_job.assert_called_once_with(
mock.ANY, resource_uri=uris.DCIM_BIOSService,
cim_creation_class_name='DCIM_BIOSService',
- cim_name='DCIM:BIOSService', target='BIOS.Setup.1-1', reboot=False)
+ cim_name='DCIM:BIOSService', target='BIOS.Setup.1-1',
+ reboot=False, start_time='TIME_NOW')
@mock.patch.object(dracclient.resources.job.JobManagement,
'create_config_job', spec_set=True, autospec=True)
@@ -475,7 +496,38 @@ def test_commit_pending_bios_changes_with_reboot(self,
mock_create_config_job.assert_called_once_with(
mock.ANY, resource_uri=uris.DCIM_BIOSService,
cim_creation_class_name='DCIM_BIOSService',
- cim_name='DCIM:BIOSService', target='BIOS.Setup.1-1', reboot=True)
+ cim_name='DCIM:BIOSService', target='BIOS.Setup.1-1',
+ reboot=True, start_time='TIME_NOW')
+
+ @mock.patch.object(dracclient.resources.job.JobManagement,
+ 'create_config_job', spec_set=True, autospec=True)
+ def test_commit_pending_bios_changes_with_time(
+ self, mock_create_config_job):
+ timestamp = '20140924140201'
+ self.drac_client.commit_pending_bios_changes(
+ start_time=timestamp)
+
+ mock_create_config_job.assert_called_once_with(
+ mock.ANY, resource_uri=uris.DCIM_BIOSService,
+ cim_creation_class_name='DCIM_BIOSService',
+ cim_name='DCIM:BIOSService', target='BIOS.Setup.1-1',
+ reboot=False, start_time=timestamp)
+
+ @mock.patch.object(dracclient.resources.job.JobManagement,
+ 'create_config_job', spec_set=True, autospec=True)
+ def test_commit_pending_bios_changes_with_reboot_and_time(
+ self,
+ mock_create_config_job):
+ timestamp = '20140924140201'
+ self.drac_client.commit_pending_bios_changes(
+ reboot=True,
+ start_time=timestamp)
+
+ mock_create_config_job.assert_called_once_with(
+ mock.ANY, resource_uri=uris.DCIM_BIOSService,
+ cim_creation_class_name='DCIM_BIOSService',
+ cim_name='DCIM:BIOSService', target='BIOS.Setup.1-1',
+ reboot=True, start_time=timestamp)
@mock.patch.object(dracclient.resources.job.JobManagement,
'delete_pending_config', spec_set=True, autospec=True)
diff --git a/dracclient/tests/test_client.py b/dracclient/tests/test_client.py
index e9395c8..5e0801b 100644
--- a/dracclient/tests/test_client.py
+++ b/dracclient/tests/test_client.py
@@ -11,10 +11,14 @@
# License for the specific language governing permissions and limitations
# under the License.
+from unittest import mock
+
import requests_mock
import dracclient.client
+from dracclient import constants
from dracclient import exceptions
+from dracclient.resources import uris
from dracclient.tests import base
from dracclient.tests import utils as test_utils
@@ -22,15 +26,35 @@
@requests_mock.Mocker()
class WSManClientTestCase(base.BaseTest):
- def test_enumerate(self, mock_requests):
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_enumerate(self, mock_requests, mock_wait_until_idrac_is_ready):
mock_requests.post('https://1.2.3.4:443/wsman',
text='yay!')
client = dracclient.client.WSManClient(**test_utils.FAKE_ENDPOINT)
resp = client.enumerate('http://resource')
+ mock_wait_until_idrac_is_ready.assert_called_once_with(client)
+ self.assertEqual('yay!', resp.text)
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_enumerate_without_wait_for_idrac(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ mock_requests.post('https://1.2.3.4:443/wsman',
+ text='yay!')
+
+ client = dracclient.client.WSManClient(**test_utils.FAKE_ENDPOINT)
+ resp = client.enumerate('http://resource', wait_for_idrac=False)
+ self.assertFalse(mock_wait_until_idrac_is_ready.called)
self.assertEqual('yay!', resp.text)
- def test_invoke(self, mock_requests):
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_invoke(self, mock_requests, mock_wait_until_idrac_is_ready):
xml = """
42
@@ -41,6 +65,25 @@ def test_invoke(self, mock_requests):
client = dracclient.client.WSManClient(**test_utils.FAKE_ENDPOINT)
resp = client.invoke('http://resource', 'Foo')
+ mock_wait_until_idrac_is_ready.assert_called_once_with(client)
+ self.assertEqual('yay!', resp.find('result').text)
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_invoke_without_wait_for_idrac(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ xml = """
+
+ 42
+ yay!
+
+""" # noqa
+ mock_requests.post('https://1.2.3.4:443/wsman', text=xml)
+
+ client = dracclient.client.WSManClient(**test_utils.FAKE_ENDPOINT)
+ resp = client.invoke('http://resource', 'Foo', wait_for_idrac=False)
+ self.assertFalse(mock_wait_until_idrac_is_ready.called)
self.assertEqual('yay!', resp.find('result').text)
def test_invoke_with_expected_return_value(self, mock_requests):
@@ -54,7 +97,7 @@ def test_invoke_with_expected_return_value(self, mock_requests):
client = dracclient.client.WSManClient(**test_utils.FAKE_ENDPOINT)
resp = client.invoke('http://resource', 'Foo',
- expected_return_value='42')
+ expected_return_value='42', wait_for_idrac=False)
self.assertEqual('yay!', resp.find('result').text)
def test_invoke_with_error_return_value(self, mock_requests):
@@ -68,7 +111,21 @@ def test_invoke_with_error_return_value(self, mock_requests):
client = dracclient.client.WSManClient(**test_utils.FAKE_ENDPOINT)
self.assertRaises(exceptions.DRACOperationFailed, client.invoke,
- 'http://resource', 'Foo')
+ 'http://resource', 'Foo', wait_for_idrac=False)
+
+ def test_invoke_with_unchecked_return_value(self, mock_requests):
+ xml = """
+
+ 2
+ yay!
+
+""" # noqa
+ mock_requests.post('https://1.2.3.4:443/wsman', text=xml)
+
+ client = dracclient.client.WSManClient(**test_utils.FAKE_ENDPOINT)
+ resp = client.invoke('http://resource', 'Foo',
+ wait_for_idrac=False, check_return_value=False)
+ self.assertEqual('yay!', resp.find('result').text)
def test_invoke_with_unexpected_return_value(self, mock_requests):
xml = """
@@ -82,4 +139,101 @@ def test_invoke_with_unexpected_return_value(self, mock_requests):
client = dracclient.client.WSManClient(**test_utils.FAKE_ENDPOINT)
self.assertRaises(exceptions.DRACUnexpectedReturnValue, client.invoke,
'http://resource', 'Foo',
- expected_return_value='4242')
+ expected_return_value='4242', wait_for_idrac=False)
+
+ def test_is_idrac_ready_ready(self, mock_requests):
+ expected_text = test_utils.LifecycleControllerInvocations[
+ uris.DCIM_LCService]['GetRemoteServicesAPIStatus']['is_ready']
+ mock_requests.post('https://1.2.3.4:443/wsman',
+ text=expected_text)
+
+ client = dracclient.client.WSManClient(**test_utils.FAKE_ENDPOINT)
+ self.assertTrue(client.is_idrac_ready())
+
+ def test_is_idrac_ready_not_ready(self, mock_requests):
+ expected_text = test_utils.LifecycleControllerInvocations[
+ uris.DCIM_LCService]['GetRemoteServicesAPIStatus']['is_not_ready']
+ mock_requests.post('https://1.2.3.4:443/wsman',
+ text=expected_text)
+
+ client = dracclient.client.WSManClient(**test_utils.FAKE_ENDPOINT)
+ self.assertFalse(client.is_idrac_ready())
+
+ @mock.patch.object(dracclient.client.WSManClient, 'is_idrac_ready',
+ autospec=True)
+ @mock.patch('time.sleep', autospec=True)
+ def test_wait_until_idrac_is_ready_with_none_arguments(
+ self, mock_requests, mock_ts, mock_is_idrac_ready):
+ ready_retries = 2
+ ready_retry_delay = 1
+
+ side_effect = (ready_retries - 1) * [False]
+ side_effect.append(True)
+ mock_is_idrac_ready.side_effect = side_effect
+
+ fake_endpoint = test_utils.FAKE_ENDPOINT.copy()
+ fake_endpoint['ready_retries'] = ready_retries
+ fake_endpoint['ready_retry_delay'] = ready_retry_delay
+
+ client = dracclient.client.WSManClient(**fake_endpoint)
+ client.wait_until_idrac_is_ready(retries=None, retry_delay=None)
+
+ self.assertEqual(mock_is_idrac_ready.call_count, ready_retries)
+ self.assertEqual(mock_ts.call_count, ready_retries - 1)
+ mock_ts.assert_called_with(ready_retry_delay)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'is_idrac_ready',
+ autospec=True)
+ @mock.patch('time.sleep', autospec=True)
+ def test_wait_until_idrac_is_ready_with_non_none_arguments(
+ self, mock_requests, mock_ts, mock_is_idrac_ready):
+ retries = 2
+ self.assertNotEqual(retries, constants.DEFAULT_IDRAC_IS_READY_RETRIES)
+
+ retry_delay = 1
+ self.assertNotEqual(
+ retry_delay, constants.DEFAULT_IDRAC_IS_READY_RETRY_DELAY_SEC)
+
+ side_effect = (retries - 1) * [False]
+ side_effect.append(True)
+ mock_is_idrac_ready.side_effect = side_effect
+
+ fake_endpoint = test_utils.FAKE_ENDPOINT.copy()
+ fake_endpoint['ready_retries'] = (
+ constants.DEFAULT_IDRAC_IS_READY_RETRIES)
+ fake_endpoint['ready_retry_delay'] = (
+ constants.DEFAULT_IDRAC_IS_READY_RETRY_DELAY_SEC)
+
+ client = dracclient.client.WSManClient(**fake_endpoint)
+ client.wait_until_idrac_is_ready(retries, retry_delay)
+
+ self.assertEqual(mock_is_idrac_ready.call_count, retries)
+ self.assertEqual(mock_ts.call_count, retries - 1)
+ mock_ts.assert_called_with(retry_delay)
+
+ def test_wait_until_idrac_is_ready_ready(self, mock_requests):
+ expected_text = test_utils.LifecycleControllerInvocations[
+ uris.DCIM_LCService]['GetRemoteServicesAPIStatus']['is_ready']
+ mock_requests.post('https://1.2.3.4:443/wsman',
+ text=expected_text)
+
+ client = dracclient.client.WSManClient(**test_utils.FAKE_ENDPOINT)
+
+ try:
+ client.wait_until_idrac_is_ready()
+ except exceptions.DRACOperationFailed:
+ self.fail('wait_until_idrac_is_ready() timed out when it should '
+ 'not have!')
+
+ @mock.patch('time.sleep', autospec=True)
+ def test_wait_until_idrac_is_ready_timeout(self,
+ mock_requests,
+ mock_ts):
+ expected_text = test_utils.LifecycleControllerInvocations[
+ uris.DCIM_LCService]['GetRemoteServicesAPIStatus']['is_not_ready']
+ mock_requests.post('https://1.2.3.4:443/wsman',
+ text=expected_text)
+
+ client = dracclient.client.WSManClient(**test_utils.FAKE_ENDPOINT)
+ self.assertRaises(exceptions.DRACOperationFailed,
+ client.wait_until_idrac_is_ready)
diff --git a/dracclient/tests/test_idrac_card.py b/dracclient/tests/test_idrac_card.py
new file mode 100644
index 0000000..d3db623
--- /dev/null
+++ b/dracclient/tests/test_idrac_card.py
@@ -0,0 +1,640 @@
+#
+# 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 lxml.etree
+import re
+from unittest import mock
+
+import requests_mock
+
+import dracclient.client
+from dracclient import constants
+from dracclient import exceptions
+from dracclient.resources import idrac_card
+from dracclient.resources import job
+from dracclient.resources import uris
+from dracclient.tests import base
+from dracclient.tests import utils as test_utils
+
+
+@requests_mock.Mocker()
+@mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+class ClientiDRACCardConfigurationTestCase(base.BaseTest):
+
+ def setUp(self):
+ super(ClientiDRACCardConfigurationTestCase, self).setUp()
+ self.drac_client = dracclient.client.DRACClient(
+ **test_utils.FAKE_ENDPOINT)
+
+ def test_list_idrac_settings_by_instance_id(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ expected_enum_attr = idrac_card.iDRACCardEnumerableAttribute(
+ name='Type',
+ instance_id='iDRAC.Embedded.1#Info.1#Type',
+ read_only=True,
+ current_value='13G Monolithic',
+ pending_value=None,
+ fqdd='iDRAC.Embedded.1',
+ group_id='Info.1',
+ possible_values=['12G/13G', '12G Monolithic', '12G Modular',
+ '13G Monolithic', '13G Modular', '12G DCS',
+ '13G DCS'])
+ expected_string_attr = idrac_card.iDRACCardStringAttribute(
+ name='Version',
+ instance_id='iDRAC.Embedded.1#Info.1#Version',
+ read_only=True,
+ current_value='2.40.40.40',
+ pending_value=None,
+ fqdd='iDRAC.Embedded.1',
+ group_id='Info.1',
+ min_length=0,
+ max_length=63)
+ expected_integer_attr = idrac_card.iDRACCardIntegerAttribute(
+ name='Port',
+ instance_id='iDRAC.Embedded.1#SSH.1#Port',
+ read_only=False,
+ current_value=22,
+ pending_value=None,
+ fqdd='iDRAC.Embedded.1',
+ group_id='SSH.1',
+ lower_bound=1,
+ upper_bound=65535)
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.iDracCardEnumerations[
+ uris.DCIM_iDRACCardEnumeration]['ok']},
+ {'text': test_utils.iDracCardEnumerations[
+ uris.DCIM_iDRACCardString]['ok']},
+ {'text': test_utils.iDracCardEnumerations[
+ uris.DCIM_iDRACCardInteger]['ok']}])
+
+ idrac_settings = self.drac_client.list_idrac_settings()
+
+ self.assertEqual(631, len(idrac_settings))
+ # enumerable attribute
+ self.assertIn('iDRAC.Embedded.1#Info.1#Type', idrac_settings)
+ self.assertEqual(expected_enum_attr, idrac_settings[
+ 'iDRAC.Embedded.1#Info.1#Type'])
+ # string attribute
+ self.assertIn('iDRAC.Embedded.1#Info.1#Version', idrac_settings)
+ self.assertEqual(expected_string_attr,
+ idrac_settings['iDRAC.Embedded.1#Info.1#Version'])
+ # integer attribute
+ self.assertIn('iDRAC.Embedded.1#SSH.1#Port', idrac_settings)
+ self.assertEqual(expected_integer_attr, idrac_settings[
+ 'iDRAC.Embedded.1#SSH.1#Port'])
+
+ def test_list_idrac_settings_by_name(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ expected_enum_attr = idrac_card.iDRACCardEnumerableAttribute(
+ name='Type',
+ instance_id='iDRAC.Embedded.1#Info.1#Type',
+ read_only=True,
+ current_value='13G Monolithic',
+ pending_value=None,
+ fqdd='iDRAC.Embedded.1',
+ group_id='Info.1',
+ possible_values=['12G/13G', '12G Monolithic', '12G Modular',
+ '13G Monolithic', '13G Modular', '12G DCS',
+ '13G DCS'])
+ expected_string_attr = idrac_card.iDRACCardStringAttribute(
+ name='Version',
+ instance_id='iDRAC.Embedded.1#Info.1#Version',
+ read_only=True,
+ current_value='2.40.40.40',
+ pending_value=None,
+ fqdd='iDRAC.Embedded.1',
+ group_id='Info.1',
+ min_length=0,
+ max_length=63)
+ expected_integer_attr = idrac_card.iDRACCardIntegerAttribute(
+ name='Port',
+ instance_id='iDRAC.Embedded.1#SSH.1#Port',
+ read_only=False,
+ current_value=22,
+ pending_value=None,
+ fqdd='iDRAC.Embedded.1',
+ group_id='SSH.1',
+ lower_bound=1,
+ upper_bound=65535)
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.iDracCardEnumerations[
+ uris.DCIM_iDRACCardEnumeration]['ok']},
+ {'text': test_utils.iDracCardEnumerations[
+ uris.DCIM_iDRACCardString]['ok']},
+ {'text': test_utils.iDracCardEnumerations[
+ uris.DCIM_iDRACCardInteger]['ok']}])
+
+ idrac_settings = self.drac_client.list_idrac_settings(by_name=True)
+
+ self.assertEqual(630, len(idrac_settings))
+
+ # enumerable attribute
+ self.assertIn('Info.1#Type', idrac_settings)
+ self.assertEqual(expected_enum_attr, idrac_settings[
+ 'Info.1#Type'])
+ # string attribute
+ self.assertIn('Info.1#Version', idrac_settings)
+ self.assertEqual(expected_string_attr,
+ idrac_settings['Info.1#Version'])
+ # integer attribute
+ self.assertIn('SSH.1#Port', idrac_settings)
+ self.assertEqual(expected_integer_attr, idrac_settings[
+ 'SSH.1#Port'])
+
+ def test_list_multi_idrac_settings_by_name(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ expected_enum_attr = idrac_card.iDRACCardEnumerableAttribute(
+ name='Type',
+ instance_id='iDRAC.Embedded.2#Info.1#Type',
+ read_only=True,
+ current_value='13G Monolithic',
+ pending_value=None,
+ fqdd='iDRAC.Embedded.2',
+ group_id='Info.1',
+ possible_values=['12G/13G', '12G Monolithic', '12G Modular',
+ '13G Monolithic', '13G Modular', '12G DCS',
+ '13G DCS'])
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.iDracCardEnumerations[
+ uris.DCIM_iDRACCardEnumeration]['ok']},
+ {'text': test_utils.iDracCardEnumerations[
+ uris.DCIM_iDRACCardString]['ok']},
+ {'text': test_utils.iDracCardEnumerations[
+ uris.DCIM_iDRACCardInteger]['ok']}])
+
+ idrac_settings = self.drac_client.list_idrac_settings(
+ by_name=True, fqdd_filter='iDRAC.Embedded.2')
+
+ self.assertEqual(1, len(idrac_settings))
+
+ # enumerable attribute
+ self.assertIn('Info.1#Type', idrac_settings)
+ self.assertEqual(expected_enum_attr, idrac_settings[
+ 'Info.1#Type'])
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_set_idrac_settings(
+ self, mock_requests, mock_invoke, mock_wait_until_idrac_is_ready):
+ expected_selectors = {'CreationClassName': 'DCIM_iDRACCardService',
+ 'SystemName': 'DCIM:ComputerSystem',
+ 'Name': 'DCIM:iDRACCardService',
+ 'SystemCreationClassName': 'DCIM_ComputerSystem'}
+ expected_properties = {'Target': 'iDRAC.Embedded.1',
+ 'AttributeName': ['LDAP.1#GroupAttributeIsDN'],
+ 'AttributeValue': ['Disabled']}
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.iDracCardEnumerations[
+ uris.DCIM_iDRACCardEnumeration]['ok']},
+ {'text': test_utils.iDracCardEnumerations[
+ uris.DCIM_iDRACCardString]['ok']},
+ {'text': test_utils.iDracCardEnumerations[
+ uris.DCIM_iDRACCardInteger]['ok']}])
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.iDracCardInvocations[uris.DCIM_iDRACCardService][
+ 'SetAttributes']['ok'])
+
+ result = self.drac_client.set_idrac_settings(
+ {'LDAP.1#GroupAttributeIsDN': 'Disabled'})
+
+ self.assertEqual({'is_commit_required': True,
+ 'is_reboot_required':
+ constants.RebootRequired.false},
+ result)
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_iDRACCardService, 'SetAttributes',
+ expected_selectors, expected_properties,
+ wait_for_idrac=True)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_set_idrac_settings_with_valid_length_string(
+ self, mock_requests, mock_invoke, mock_wait_until_idrac_is_ready):
+ expected_selectors = {'CreationClassName': 'DCIM_iDRACCardService',
+ 'SystemName': 'DCIM:ComputerSystem',
+ 'Name': 'DCIM:iDRACCardService',
+ 'SystemCreationClassName': 'DCIM_ComputerSystem'}
+ expected_properties = {'Target': 'iDRAC.Embedded.1',
+ 'AttributeName': ['Users.16#Password'],
+ 'AttributeValue': ['12345678901234567890']}
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.iDracCardEnumerations[
+ uris.DCIM_iDRACCardEnumeration]['ok']},
+ {'text': test_utils.iDracCardEnumerations[
+ uris.DCIM_iDRACCardString]['ok']},
+ {'text': test_utils.iDracCardEnumerations[
+ uris.DCIM_iDRACCardInteger]['ok']}])
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.iDracCardInvocations[uris.DCIM_iDRACCardService][
+ 'SetAttributes']['ok'])
+ result = self.drac_client.set_idrac_settings(
+ {'Users.16#Password': '12345678901234567890'})
+ self.assertEqual({'is_commit_required': True,
+ 'is_reboot_required':
+ constants.RebootRequired.false},
+ result)
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_iDRACCardService, 'SetAttributes',
+ expected_selectors, expected_properties,
+ wait_for_idrac=True)
+
+ def test_set_idrac_settings_with_too_long_string(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ expected_message = ("Attribute 'Password' cannot be set to "
+ "value '123456789012345678901'. It must be "
+ "between 0 and 20 characters in length.")
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.iDracCardEnumerations[
+ uris.DCIM_iDRACCardEnumeration]['ok']},
+ {'text': test_utils.iDracCardEnumerations[
+ uris.DCIM_iDRACCardString]['ok']},
+ {'text': test_utils.iDracCardEnumerations[
+ uris.DCIM_iDRACCardInteger]['ok']}])
+ self.assertRaisesRegexp(
+ exceptions.DRACOperationFailed, re.escape(expected_message),
+ self.drac_client.set_idrac_settings,
+ {'Users.16#Password': '123456789012345678901'})
+
+
+class ClientiDRACCardChangesTestCase(base.BaseTest):
+
+ def setUp(self):
+ super(ClientiDRACCardChangesTestCase, self).setUp()
+ self.drac_client = dracclient.client.DRACClient(
+ **test_utils.FAKE_ENDPOINT)
+
+ @mock.patch.object(job.JobManagement, 'create_config_job', spec_set=True,
+ autospec=True)
+ def test_commit_pending_idrac_changes(self, mock_create_config_job):
+ self.drac_client.commit_pending_idrac_changes()
+
+ mock_create_config_job.assert_called_once_with(
+ mock.ANY,
+ resource_uri=uris.DCIM_iDRACCardService,
+ cim_creation_class_name='DCIM_iDRACCardService',
+ cim_name='DCIM:iDRACCardService',
+ target=dracclient.client.DRACClient.IDRAC_FQDD,
+ reboot=False, start_time='TIME_NOW')
+
+ @mock.patch.object(job.JobManagement, 'create_config_job', spec_set=True,
+ autospec=True)
+ def test_commit_pending_idrac_changes_with_reboot(
+ self, mock_create_config_job):
+
+ self.drac_client.commit_pending_idrac_changes(
+ reboot=True)
+
+ mock_create_config_job.assert_called_once_with(
+ mock.ANY,
+ resource_uri=uris.DCIM_iDRACCardService,
+ cim_creation_class_name='DCIM_iDRACCardService',
+ cim_name='DCIM:iDRACCardService',
+ target=dracclient.client.DRACClient.IDRAC_FQDD,
+ reboot=True, start_time='TIME_NOW')
+
+ @mock.patch.object(job.JobManagement, 'create_config_job', spec_set=True,
+ autospec=True)
+ def test_commit_pending_idrac_changes_with_time(
+ self, mock_create_config_job):
+ timestamp = '20140924120101'
+ self.drac_client.commit_pending_idrac_changes(
+ start_time=timestamp)
+
+ mock_create_config_job.assert_called_once_with(
+ mock.ANY,
+ resource_uri=uris.DCIM_iDRACCardService,
+ cim_creation_class_name='DCIM_iDRACCardService',
+ cim_name='DCIM:iDRACCardService',
+ target=dracclient.client.DRACClient.IDRAC_FQDD,
+ reboot=False, start_time=timestamp)
+
+ @mock.patch.object(job.JobManagement, 'create_config_job', spec_set=True,
+ autospec=True)
+ def test_commit_pending_idrac_changes_with_reboot_and_time(
+ self, mock_create_config_job):
+
+ timestamp = '20140924120101'
+ self.drac_client.commit_pending_idrac_changes(
+ reboot=True,
+ start_time=timestamp)
+
+ mock_create_config_job.assert_called_once_with(
+ mock.ANY,
+ resource_uri=uris.DCIM_iDRACCardService,
+ cim_creation_class_name='DCIM_iDRACCardService',
+ cim_name='DCIM:iDRACCardService',
+ target=dracclient.client.DRACClient.IDRAC_FQDD,
+ reboot=True, start_time=timestamp)
+
+ @mock.patch.object(job.JobManagement, 'delete_pending_config',
+ spec_set=True, autospec=True)
+ def test_abandon_pending_idrac_changes(self, mock_delete_pending_config):
+ self.drac_client.abandon_pending_idrac_changes()
+
+ mock_delete_pending_config.assert_called_once_with(
+ mock.ANY,
+ resource_uri=uris.DCIM_iDRACCardService,
+ cim_creation_class_name='DCIM_iDRACCardService',
+ cim_name='DCIM:iDRACCardService',
+ target=dracclient.client.DRACClient.IDRAC_FQDD)
+
+
+class ClientiDRACCardResetTestCase(base.BaseTest):
+
+ def setUp(self):
+ super(ClientiDRACCardResetTestCase, self).setUp()
+ self.drac_client = dracclient.client.DRACClient(
+ **test_utils.FAKE_ENDPOINT)
+
+ @mock.patch('dracclient.client.subprocess.call')
+ def test_ping_host(self, mock_os_system):
+ mock_os_system.return_value = 0
+ response = self.drac_client._ping_host('127.0.0.1')
+ self.assertEqual(mock_os_system.call_count, 1)
+ self.assertEqual(True, response)
+
+ @mock.patch('dracclient.client.subprocess.call')
+ def test_ping_host_not_pingable(self, mock_os_system):
+ mock_os_system.return_value = 1
+ response = self.drac_client._ping_host('127.0.0.1')
+ self.assertEqual(mock_os_system.call_count, 1)
+ self.assertEqual(False, response)
+
+ @mock.patch('dracclient.client.subprocess.call')
+ def test_ping_host_name_not_known(self, mock_os_system):
+ mock_os_system.return_value = 2
+ response = self.drac_client._ping_host('127.0.0.1')
+ self.assertEqual(mock_os_system.call_count, 1)
+ self.assertEqual(False, response)
+
+ @mock.patch('time.sleep')
+ @mock.patch('dracclient.client.DRACClient._ping_host')
+ def test_wait_for_host_alive(self, mock_ping_host, mock_sleep):
+ total_calls = 5
+ ping_count = 3
+ mock_ping_host.return_value = True
+ mock_sleep.return_value = None
+ response = self.drac_client._wait_for_host_state(
+ 'hostname',
+ alive=True,
+ ping_count=ping_count,
+ retries=total_calls)
+ self.assertEqual(True, response)
+ self.assertEqual(mock_sleep.call_count, ping_count)
+ self.assertEqual(mock_ping_host.call_count, ping_count)
+
+ @mock.patch('time.sleep')
+ @mock.patch('dracclient.client.DRACClient._ping_host')
+ def test_wait_for_host_alive_fail(self, mock_ping_host, mock_sleep):
+ total_calls = 5
+ ping_count = 3
+ mock_ping_host.return_value = False
+ mock_sleep.return_value = None
+ response = self.drac_client._wait_for_host_state(
+ 'hostname',
+ alive=True,
+ ping_count=ping_count,
+ retries=total_calls)
+ self.assertEqual(False, response)
+ self.assertEqual(mock_sleep.call_count, total_calls)
+ self.assertEqual(mock_ping_host.call_count, total_calls)
+
+ @mock.patch('time.sleep')
+ @mock.patch('dracclient.client.DRACClient._ping_host')
+ def test_wait_for_host_dead(self, mock_ping_host, mock_sleep):
+ total_calls = 5
+ ping_count = 3
+ mock_ping_host.return_value = False
+ mock_sleep.return_value = None
+ response = self.drac_client._wait_for_host_state(
+ 'hostname',
+ alive=False,
+ ping_count=ping_count,
+ retries=total_calls)
+ self.assertEqual(True, response)
+ self.assertEqual(mock_sleep.call_count, ping_count)
+ self.assertEqual(mock_ping_host.call_count, ping_count)
+
+ @mock.patch('time.sleep')
+ @mock.patch('dracclient.client.DRACClient._ping_host')
+ def test_wait_for_host_dead_fail(self, mock_ping_host, mock_sleep):
+ total_calls = 5
+ ping_count = 3
+ mock_ping_host.return_value = True
+ mock_sleep.return_value = None
+ response = self.drac_client._wait_for_host_state(
+ 'hostname',
+ alive=False,
+ ping_count=ping_count,
+ retries=total_calls)
+ self.assertEqual(False, response)
+ self.assertEqual(mock_sleep.call_count, total_calls)
+ self.assertEqual(mock_ping_host.call_count, total_calls)
+
+ @mock.patch('time.sleep')
+ @mock.patch('dracclient.client.DRACClient._ping_host')
+ def test_wait_for_host_alive_with_intermittent(
+ self, mock_ping_host, mock_sleep):
+ total_calls = 6
+ ping_count = 3
+ mock_ping_host.side_effect = [True, True, False, True, True, True]
+ mock_sleep.return_value = None
+ response = self.drac_client._wait_for_host_state(
+ 'hostname',
+ alive=True,
+ ping_count=ping_count,
+ retries=total_calls)
+ self.assertEqual(True, response)
+ self.assertEqual(mock_sleep.call_count, total_calls)
+
+ @mock.patch('time.sleep')
+ @mock.patch('dracclient.client.DRACClient._ping_host')
+ def test_wait_for_host_dead_with_intermittent(
+ self, mock_ping_host, mock_sleep):
+ total_calls = 6
+ ping_count = 3
+ mock_ping_host.side_effect = [False, False, True, False, False, False]
+ mock_sleep.return_value = None
+ response = self.drac_client._wait_for_host_state(
+ 'hostname',
+ alive=False,
+ ping_count=ping_count,
+ retries=total_calls)
+ self.assertEqual(True, response)
+ self.assertEqual(mock_sleep.call_count, total_calls)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke', spec_set=True,
+ autospec=True)
+ def test_reset_idrac(self, mock_invoke):
+ expected_selectors = {
+ 'CreationClassName': "DCIM_iDRACCardService",
+ 'Name': "DCIM:iDRACCardService",
+ 'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'DCIM:ComputerSystem'}
+ expected_properties = {'Force': '0'}
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.iDracCardInvocations[uris.DCIM_iDRACCardService][
+ 'iDRACReset']['ok'])
+
+ result = self.drac_client.reset_idrac()
+
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_iDRACCardService, 'iDRACReset',
+ expected_selectors, expected_properties,
+ check_return_value=False)
+ self.assertTrue(result)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke', spec_set=True,
+ autospec=True)
+ def test_reset_idrac_force(self, mock_invoke):
+ expected_selectors = {
+ 'CreationClassName': "DCIM_iDRACCardService",
+ 'Name': "DCIM:iDRACCardService",
+ 'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'DCIM:ComputerSystem'}
+ expected_properties = {'Force': '1'}
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.iDracCardInvocations[uris.DCIM_iDRACCardService][
+ 'iDRACReset']['ok'])
+
+ result = self.drac_client.reset_idrac(force=True)
+
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_iDRACCardService, 'iDRACReset',
+ expected_selectors, expected_properties,
+ check_return_value=False)
+ self.assertTrue(result)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke', spec_set=True,
+ autospec=True)
+ def test_reset_idrac_bad_result(self, mock_invoke):
+ expected_selectors = {
+ 'CreationClassName': "DCIM_iDRACCardService",
+ 'Name': "DCIM:iDRACCardService",
+ 'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'DCIM:ComputerSystem'}
+ expected_properties = {'Force': '0'}
+ expected_message = ("Failed to reset iDRAC")
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.iDracCardInvocations[uris.DCIM_iDRACCardService][
+ 'iDRACReset']['error'])
+
+ self.assertRaisesRegexp(
+ exceptions.DRACOperationFailed, re.escape(expected_message),
+ self.drac_client.reset_idrac)
+
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_iDRACCardService, 'iDRACReset',
+ expected_selectors, expected_properties,
+ check_return_value=False)
+
+ @mock.patch('time.sleep')
+ @mock.patch('dracclient.client.WSManClient.wait_until_idrac_is_ready')
+ @mock.patch('dracclient.client.DRACClient._wait_for_host_state')
+ @mock.patch(
+ 'dracclient.client.idrac_card.iDRACCardConfiguration.reset_idrac')
+ def test_reset_idrac_wait(
+ self,
+ mock_reset_idrac,
+ mock_wait_for_host_state,
+ mock_wait_until_idrac_is_ready,
+ mock_sleep):
+ mock_reset_idrac.return_value = True
+ mock_wait_for_host_state.side_effect = [True, True]
+ mock_wait_until_idrac_is_ready.return_value = True
+ mock_sleep.return_value = None
+
+ self.drac_client.reset_idrac(wait=True)
+
+ mock_reset_idrac.assert_called_once()
+ self.assertEqual(mock_wait_for_host_state.call_count, 2)
+ mock_wait_until_idrac_is_ready.assert_called_once()
+
+ @mock.patch('time.sleep')
+ @mock.patch('dracclient.client.WSManClient.wait_until_idrac_is_ready')
+ @mock.patch('dracclient.client.DRACClient._wait_for_host_state')
+ @mock.patch(
+ 'dracclient.client.idrac_card.iDRACCardConfiguration.reset_idrac')
+ def test_reset_idrac_wait_failed_reset(
+ self,
+ mock_reset_idrac,
+ mock_wait_for_host_state,
+ mock_wait_until_idrac_is_ready,
+ mock_sleep):
+ mock_reset_idrac.return_value = False
+ mock_wait_for_host_state.side_effect = [True, True]
+ mock_wait_until_idrac_is_ready.return_value = False
+ mock_sleep.return_value = None
+ expected_message = ("Failed to reset iDRAC")
+
+ self.assertRaisesRegexp(
+ exceptions.DRACOperationFailed, re.escape(expected_message),
+ self.drac_client.reset_idrac, wait=True)
+
+ mock_reset_idrac.assert_called_once()
+ mock_wait_for_host_state.assert_not_called()
+ mock_wait_until_idrac_is_ready.assert_not_called()
+
+ @mock.patch('time.sleep')
+ @mock.patch('dracclient.client.WSManClient.wait_until_idrac_is_ready')
+ @mock.patch('dracclient.client.DRACClient._wait_for_host_state')
+ @mock.patch(
+ 'dracclient.client.idrac_card.iDRACCardConfiguration.reset_idrac')
+ def test_reset_idrac_fail_wait_not_pingable(
+ self,
+ mock_reset_idrac,
+ mock_wait_for_host_state,
+ mock_wait_until_idrac_is_ready,
+ mock_sleep):
+ mock_reset_idrac.return_value = True
+ mock_wait_for_host_state.side_effect = [False, True]
+ mock_wait_until_idrac_is_ready.return_value = True
+ mock_sleep.return_value = None
+ expected_message = (
+ "Timed out waiting for the 1.2.3.4 iDRAC to become not pingable")
+
+ self.assertRaisesRegexp(
+ exceptions.DRACOperationFailed, re.escape(expected_message),
+ self.drac_client.reset_idrac, wait=True)
+
+ mock_reset_idrac.assert_called_once()
+ mock_wait_for_host_state.assert_called_once()
+ mock_wait_until_idrac_is_ready.assert_not_called()
+
+ @mock.patch('time.sleep')
+ @mock.patch('dracclient.client.WSManClient.wait_until_idrac_is_ready')
+ @mock.patch('dracclient.client.DRACClient._wait_for_host_state')
+ @mock.patch(
+ 'dracclient.client.idrac_card.iDRACCardConfiguration.reset_idrac')
+ def test_reset_idrac_fail_wait_pingable(
+ self,
+ mock_reset_idrac,
+ mock_wait_for_host_state,
+ mock_wait_until_idrac_is_ready,
+ mock_sleep):
+ mock_reset_idrac.return_value = True
+ mock_wait_for_host_state.side_effect = [True, False]
+ mock_wait_until_idrac_is_ready.return_value = True
+ mock_sleep.return_value = None
+ expected_message = (
+ "Timed out waiting for the 1.2.3.4 iDRAC to become pingable")
+
+ self.assertRaisesRegexp(
+ exceptions.DRACOperationFailed, re.escape(expected_message),
+ self.drac_client.reset_idrac, wait=True)
+
+ mock_reset_idrac.assert_called_once()
+ self.assertEqual(mock_wait_for_host_state.call_count, 2)
+ mock_wait_until_idrac_is_ready.assert_not_called()
diff --git a/dracclient/tests/test_inventory.py b/dracclient/tests/test_inventory.py
index a167da6..378a114 100644
--- a/dracclient/tests/test_inventory.py
+++ b/dracclient/tests/test_inventory.py
@@ -11,6 +11,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+from unittest import mock
+
import requests_mock
import dracclient.client
@@ -22,6 +24,8 @@
@requests_mock.Mocker()
+@mock.patch.object(dracclient.client.WSManClient, 'wait_until_idrac_is_ready',
+ spec_set=True, autospec=True)
class ClientInventoryManagementTestCase(base.BaseTest):
def setUp(self):
@@ -29,7 +33,7 @@ def setUp(self):
self.drac_client = dracclient.client.DRACClient(
**test_utils.FAKE_ENDPOINT)
- def test_list_cpus(self, mock_requests):
+ def test_list_cpus(self, mock_requests, mock_wait_until_idrac_is_ready):
expected_cpu = [inventory.CPU(
id='CPU.Socket.1',
cores=6,
@@ -37,6 +41,7 @@ def test_list_cpus(self, mock_requests):
model='Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz',
status='ok',
ht_enabled=True,
+ cpu_count=12,
turbo_enabled=True,
vt_enabled=True,
arch64=True)]
@@ -49,7 +54,8 @@ def test_list_cpus(self, mock_requests):
expected_cpu,
self.drac_client.list_cpus())
- def test_list_cpus_with_missing_flags(self, mock_requests):
+ def test_list_cpus_with_missing_flags(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
expected_cpu = [inventory.CPU(
id='CPU.Socket.1',
cores=8,
@@ -57,6 +63,7 @@ def test_list_cpus_with_missing_flags(self, mock_requests):
model='Intel(R) Xeon(R) CPU E5-2440 v2 @ 1.90GHz',
status='ok',
ht_enabled=False,
+ cpu_count=8,
turbo_enabled=False,
vt_enabled=False,
arch64=False)]
@@ -70,7 +77,7 @@ def test_list_cpus_with_missing_flags(self, mock_requests):
expected_cpu,
self.drac_client.list_cpus())
- def test_list_memory(self, mock_requests):
+ def test_list_memory(self, mock_requests, mock_wait_until_idrac_is_ready):
expected_memory = [inventory.Memory(
id='DIMM.Socket.A1',
size_mb=16384,
@@ -87,7 +94,7 @@ def test_list_memory(self, mock_requests):
expected_memory,
self.drac_client.list_memory())
- def test_list_nics(self, mock_requests):
+ def test_list_nics(self, mock_requests, mock_wait_until_idrac_is_ready):
expected_nics = [
inventory.NIC(
id='NIC.Embedded.1-1-1',
@@ -125,3 +132,18 @@ def test_list_nics(self, mock_requests):
self.assertEqual(
expected_nics,
self.drac_client.list_nics())
+
+ def test_get_system(self, mock_requests, mock_wait_until_idrac_is_ready):
+ expected_system = inventory.System(
+ id='System.Embedded.1',
+ uuid='ebd4edd3-dfd7-4c7d-a2c8-562b3c23b811',
+ service_tag='A1B2C3D',
+ model='PowerEdge R630',
+ lcc_version='2.1.0')
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.LifecycleControllerEnumerations[
+ uris.DCIM_SystemView]['ok'])
+ self.assertEqual(
+ expected_system,
+ self.drac_client.get_system())
diff --git a/dracclient/tests/test_job.py b/dracclient/tests/test_job.py
index 751b0b9..38add78 100644
--- a/dracclient/tests/test_job.py
+++ b/dracclient/tests/test_job.py
@@ -11,8 +11,10 @@
# License for the specific language governing permissions and limitations
# under the License.
+import datetime
import lxml.etree
-import mock
+from unittest import mock
+
import requests_mock
import dracclient.client
@@ -32,7 +34,10 @@ def setUp(self):
**test_utils.FAKE_ENDPOINT)
@requests_mock.Mocker()
- def test_list_jobs(self, mock_requests):
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_list_jobs(self, mock_requests, mock_wait_until_idrac_is_ready):
mock_requests.post(
'https://1.2.3.4:443/wsman',
text=test_utils.JobEnumerations[uris.DCIM_LifecycleJob]['ok'])
@@ -47,6 +52,7 @@ def test_list_jobs_only_unfinished(self, mock_enumerate):
expected_filter_query = ('select * from DCIM_LifecycleJob '
'where Name != "CLEARALL" and '
'JobStatus != "Reboot Completed" and '
+ 'JobStatus != "Reboot Failed" and '
'JobStatus != "Completed" and '
'JobStatus != "Completed with Errors" and '
'JobStatus != "Failed"')
@@ -98,18 +104,173 @@ def test_get_job_not_found(self, mock_enumerate):
filter_query=expected_filter_query)
self.assertIsNone(job)
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_delete_jobs_all(self, mock_invoke):
+ expected_selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'idrac',
+ 'CreationClassName': 'DCIM_JobService',
+ 'Name': 'JobService'}
+ expected_properties = {'JobID': 'JID_CLEARALL'}
+
+ self.drac_client.delete_jobs()
+
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_JobService, 'DeleteJobQueue',
+ expected_selectors, expected_properties,
+ expected_return_value=utils.RET_SUCCESS)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_delete_jobs_force(self, mock_invoke):
+ expected_selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'idrac',
+ 'CreationClassName': 'DCIM_JobService',
+ 'Name': 'JobService'}
+ expected_properties = {'JobID': 'JID_CLEARALL_FORCE'}
+
+ self.drac_client.delete_jobs(['JID_CLEARALL_FORCE'])
+
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_JobService, 'DeleteJobQueue',
+ expected_selectors, expected_properties,
+ expected_return_value=utils.RET_SUCCESS)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_delete_jobs_one(self, mock_invoke):
+ expected_selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'idrac',
+ 'CreationClassName': 'DCIM_JobService',
+ 'Name': 'JobService'}
+ expected_properties = {'JobID': 'JID_442507917525'}
+
+ self.drac_client.delete_jobs(['JID_442507917525'])
+
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_JobService, 'DeleteJobQueue',
+ expected_selectors, expected_properties,
+ expected_return_value=utils.RET_SUCCESS)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_delete_jobs_multi(self, mock_invoke):
+ expected_selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'idrac',
+ 'CreationClassName': 'DCIM_JobService',
+ 'Name': 'JobService'}
+
+ self.drac_client.delete_jobs(['JID_442507917525',
+ 'JID_442507917526'])
+
+ calls_expected = [
+ mock.call(mock.ANY,
+ uris.DCIM_JobService,
+ 'DeleteJobQueue',
+ expected_selectors,
+ {'JobID': 'JID_442507917525'},
+ expected_return_value=utils.RET_SUCCESS),
+ mock.call(mock.ANY,
+ uris.DCIM_JobService,
+ 'DeleteJobQueue',
+ expected_selectors,
+ {'JobID': 'JID_442507917526'},
+ expected_return_value=utils.RET_SUCCESS)]
+ mock_invoke.assert_has_calls(calls_expected)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_delete_jobs_none(self, mock_invoke):
+ self.drac_client.delete_jobs(None)
+ self.assertFalse(mock_invoke.called)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_delete_jobs_empty_list(self, mock_invoke):
+ self.drac_client.delete_jobs([])
+ self.assertFalse(mock_invoke.called)
+
+ @requests_mock.Mocker()
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_delete_job_not_found(
+ self, mock_requests,
+ mock_wait_until_idrac_is_ready):
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.JobService[uris.DCIM_JobService][
+ 'DeleteJobQueue']['error'])
+ self.assertRaises(
+ exceptions.DRACOperationFailed,
+ self.drac_client.delete_jobs,
+ ['JID_1234'])
+
+ @requests_mock.Mocker()
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_delete_some_jobs_not_found(
+ self, mock_requests,
+ mock_wait_until_idrac_is_ready):
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ [{'text': test_utils.JobService[uris.DCIM_JobService][
+ 'DeleteJobQueue']['error']},
+ {'text': test_utils.JobService[uris.DCIM_JobService][
+ 'DeleteJobQueue']['ok']}])
+
+ self.assertRaises(
+ exceptions.DRACOperationFailed,
+ self.drac_client.delete_jobs,
+ ['JID_1234', 'JID_442507917525'])
+
+ self.assertEqual(mock_requests.call_count, 2)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_create_config_job_for_lifecycle(self, mock_invoke):
+ cim_creation_class_name = 'DCIM_LCService'
+ cim_name = 'DCIM:LCService'
+ target = ''
+
+ expected_selectors = {'CreationClassName': cim_creation_class_name,
+ 'Name': cim_name,
+ 'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'DCIM:ComputerSystem'}
+ expected_properties = {'Target': target,
+ 'ScheduledStartTime': 'TIME_NOW'}
+
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.JobInvocations[uris.DCIM_LCService][
+ 'CreateConfigJob']['ok'])
+
+ job_id = self.drac_client.create_config_job(
+ uris.DCIM_LCService, cim_creation_class_name, cim_name, target,
+ start_time='TIME_NOW',
+ wait_for_idrac=False, method_name='CreateConfigJob')
+
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_LCService, 'CreateConfigJob',
+ expected_selectors, expected_properties,
+ expected_return_value=utils.RET_CREATED,
+ wait_for_idrac=False)
+ self.assertEqual('JID_442507917525', job_id)
+
@mock.patch.object(dracclient.client.WSManClient, 'invoke',
spec_set=True, autospec=True)
def test_create_config_job(self, mock_invoke):
cim_creation_class_name = 'DCIM_BIOSService'
cim_name = 'DCIM:BIOSService'
target = 'BIOS.Setup.1-1'
+ wait_for_idrac = True
expected_selectors = {'CreationClassName': cim_creation_class_name,
'Name': cim_name,
'SystemCreationClassName': 'DCIM_ComputerSystem',
'SystemName': 'DCIM:ComputerSystem'}
expected_properties = {'Target': target,
'ScheduledStartTime': 'TIME_NOW'}
+
mock_invoke.return_value = lxml.etree.fromstring(
test_utils.JobInvocations[uris.DCIM_BIOSService][
'CreateTargetedConfigJob']['ok'])
@@ -120,11 +281,73 @@ def test_create_config_job(self, mock_invoke):
mock_invoke.assert_called_once_with(
mock.ANY, uris.DCIM_BIOSService, 'CreateTargetedConfigJob',
expected_selectors, expected_properties,
- expected_return_value=utils.RET_CREATED)
+ expected_return_value=utils.RET_CREATED,
+ wait_for_idrac=wait_for_idrac)
+ self.assertEqual('JID_442507917525', job_id)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_create_config_job_with_start_time(self, mock_invoke):
+ cim_creation_class_name = 'DCIM_BIOSService'
+ cim_name = 'DCIM:BIOSService'
+ target = 'BIOS.Setup.1-1'
+ start_time = "20140924120105"
+ wait_for_idrac = True
+ expected_selectors = {'CreationClassName': cim_creation_class_name,
+ 'Name': cim_name,
+ 'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'DCIM:ComputerSystem'}
+ expected_properties = {'Target': target,
+ 'ScheduledStartTime': start_time}
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.JobInvocations[uris.DCIM_BIOSService][
+ 'CreateTargetedConfigJob']['ok'])
+
+ job_id = self.drac_client.create_config_job(
+ uris.DCIM_BIOSService, cim_creation_class_name, cim_name, target,
+ start_time=start_time)
+
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_BIOSService, 'CreateTargetedConfigJob',
+ expected_selectors, expected_properties,
+ expected_return_value=utils.RET_CREATED,
+ wait_for_idrac=wait_for_idrac)
+ self.assertEqual('JID_442507917525', job_id)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_create_config_job_with_no_start_time(self, mock_invoke):
+ cim_creation_class_name = 'DCIM_BIOSService'
+ cim_name = 'DCIM:BIOSService'
+ target = 'BIOS.Setup.1-1'
+ start_time = None
+ wait_for_idrac = True
+ expected_selectors = {'CreationClassName': cim_creation_class_name,
+ 'Name': cim_name,
+ 'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'DCIM:ComputerSystem'}
+ expected_properties = {'Target': target}
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.JobInvocations[uris.DCIM_BIOSService][
+ 'CreateTargetedConfigJob']['ok'])
+
+ job_id = self.drac_client.create_config_job(
+ uris.DCIM_BIOSService, cim_creation_class_name, cim_name, target,
+ start_time=start_time)
+
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_BIOSService, 'CreateTargetedConfigJob',
+ expected_selectors, expected_properties,
+ expected_return_value=utils.RET_CREATED,
+ wait_for_idrac=wait_for_idrac)
self.assertEqual('JID_442507917525', job_id)
@requests_mock.Mocker()
- def test_create_config_job_failed(self, mock_requests):
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_create_config_job_failed(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
cim_creation_class_name = 'DCIM_BIOSService'
cim_name = 'DCIM:BIOSService'
target = 'BIOS.Setup.1-1'
@@ -137,12 +360,32 @@ def test_create_config_job_failed(self, mock_requests):
exceptions.DRACOperationFailed, self.drac_client.create_config_job,
uris.DCIM_BIOSService, cim_creation_class_name, cim_name, target)
+ @requests_mock.Mocker()
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_create_config_job_for_lifecycle_failed(
+ self, mock_requests,
+ mock_wait_until_idrac_is_ready):
+ cim_creation_class_name = 'DCIM_LCService'
+ cim_name = 'DCIM:LCService'
+ target = ''
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.JobInvocations[uris.DCIM_LCService][
+ 'CreateConfigJob']['error'])
+
+ self.assertRaises(
+ exceptions.DRACOperationFailed, self.drac_client.create_config_job,
+ uris.DCIM_LCService, cim_creation_class_name, cim_name, target)
+
@mock.patch.object(dracclient.client.WSManClient, 'invoke', spec_set=True,
autospec=True)
def test_create_config_job_with_reboot(self, mock_invoke):
cim_creation_class_name = 'DCIM_BIOSService'
cim_name = 'DCIM:BIOSService'
target = 'BIOS.Setup.1-1'
+ wait_for_idrac = True
expected_selectors = {'CreationClassName': cim_creation_class_name,
'Name': cim_name,
'SystemCreationClassName': 'DCIM_ComputerSystem',
@@ -156,14 +399,65 @@ def test_create_config_job_with_reboot(self, mock_invoke):
job_id = self.drac_client.create_config_job(
uris.DCIM_BIOSService, cim_creation_class_name, cim_name, target,
- reboot=True)
+ reboot=True, realtime=False)
mock_invoke.assert_called_once_with(
mock.ANY, uris.DCIM_BIOSService, 'CreateTargetedConfigJob',
expected_selectors, expected_properties,
- expected_return_value=utils.RET_CREATED)
+ expected_return_value=utils.RET_CREATED,
+ wait_for_idrac=wait_for_idrac)
+ self.assertEqual('JID_442507917525', job_id)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke', spec_set=True,
+ autospec=True)
+ def test_create_config_job_with_realtime(self, mock_invoke):
+ cim_creation_class_name = 'DCIM_BIOSService'
+ cim_name = 'DCIM:BIOSService'
+ target = 'BIOS.Setup.1-1'
+ wait_for_idrac = True
+ expected_selectors = {'CreationClassName': cim_creation_class_name,
+ 'Name': cim_name,
+ 'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'DCIM:ComputerSystem'}
+ expected_properties = {'Target': target,
+ 'ScheduledStartTime': 'TIME_NOW',
+ 'RealTime': '1'}
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.JobInvocations[uris.DCIM_BIOSService][
+ 'CreateTargetedConfigJob']['ok'])
+
+ job_id = self.drac_client.create_config_job(
+ uris.DCIM_BIOSService, cim_creation_class_name, cim_name, target,
+ reboot=False, realtime=True)
+
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_BIOSService, 'CreateTargetedConfigJob',
+ expected_selectors, expected_properties,
+ expected_return_value=utils.RET_CREATED,
+ wait_for_idrac=wait_for_idrac)
self.assertEqual('JID_442507917525', job_id)
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke', spec_set=True,
+ autospec=True)
+ def test_create_reboot_job(self, mock_invoke):
+ expected_selectors = {
+ 'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'idrac',
+ 'CreationClassName': 'DCIM_JobService',
+ 'Name': 'JobService'}
+ expected_properties = {'RebootJobType': '3'}
+ self.drac_client.create_reboot_job()
+
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_JobService, 'CreateRebootJob',
+ expected_selectors, expected_properties,
+ expected_return_value=utils.RET_CREATED)
+
+ def test_create_reboot_job_bad_type(self):
+ self.assertRaises(
+ exceptions.InvalidParameterValue,
+ self.drac_client.create_reboot_job, 'BAD REBOOT TYPE')
+
@mock.patch.object(dracclient.client.WSManClient, 'invoke', spec_set=True,
autospec=True)
def test_delete_pending_config(self, mock_invoke):
@@ -188,7 +482,11 @@ def test_delete_pending_config(self, mock_invoke):
expected_return_value=utils.RET_SUCCESS)
@requests_mock.Mocker()
- def test_delete_pending_config_failed(self, mock_requests):
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_delete_pending_config_failed(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
cim_creation_class_name = 'DCIM_BIOSService'
cim_name = 'DCIM:BIOSService'
target = 'BIOS.Setup.1-1'
@@ -201,3 +499,75 @@ def test_delete_pending_config_failed(self, mock_requests):
exceptions.DRACOperationFailed,
self.drac_client.delete_pending_config, uris.DCIM_BIOSService,
cim_creation_class_name, cim_name, target)
+
+
+class ClientJobScheduleTestCase(base.BaseTest):
+ def setUp(self):
+ super(ClientJobScheduleTestCase, self).setUp()
+ self.drac_client = dracclient.client.DRACClient(
+ **test_utils.FAKE_ENDPOINT)
+
+ def _test_schedule_job_execution(self,
+ mock_invoke,
+ job_ids,
+ start_time,
+ expected_properties):
+ expected_selectors = {
+ 'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'idrac',
+ 'CreationClassName': 'DCIM_JobService',
+ 'Name': 'JobService'}
+
+ if start_time is None:
+ self.drac_client.schedule_job_execution(job_ids)
+ else:
+ self.drac_client.schedule_job_execution(job_ids, start_time)
+
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_JobService, 'SetupJobQueue',
+ expected_selectors, expected_properties,
+ expected_return_value=utils.RET_SUCCESS)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke', spec_set=True,
+ autospec=True)
+ def test_schedule_job_execution_one_job(self, mock_invoke):
+ job_ids = ['JID_442507917525']
+ expected_properties = {'StartTimeInterval': 'TIME_NOW',
+ 'JobArray': job_ids}
+
+ self._test_schedule_job_execution(mock_invoke, job_ids, None,
+ expected_properties)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke', spec_set=True,
+ autospec=True)
+ def test_schedule_job_execution_multi_job(self, mock_invoke):
+ job_ids = ['JID_442507917525', 'JID_442507917526']
+ expected_properties = {'StartTimeInterval': 'TIME_NOW',
+ 'JobArray': job_ids}
+ self._test_schedule_job_execution(mock_invoke, job_ids, None,
+ expected_properties)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke', spec_set=True,
+ autospec=True)
+ def test_schedule_job_execution_one_job_with_time(self, mock_invoke):
+ job_ids = ['JID_442507917525']
+ timestamp = datetime.datetime.today().strftime('%Y%m%d%H%M%S')
+ expected_properties = {'StartTimeInterval': timestamp,
+ 'JobArray': job_ids}
+ self._test_schedule_job_execution(mock_invoke, job_ids, timestamp,
+ expected_properties)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke', spec_set=True,
+ autospec=True)
+ def test_schedule_job_execution_multi_job_with_time(self, mock_invoke):
+ job_ids = ['JID_442507917525', 'JID_442507917526']
+ timestamp = datetime.datetime.today().strftime('%Y%m%d%H%M%S')
+ expected_properties = {'StartTimeInterval': timestamp,
+ 'JobArray': job_ids}
+ self._test_schedule_job_execution(mock_invoke, job_ids, timestamp,
+ expected_properties)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke')
+ def test_schedule_job_execution_no_jobs(self, mock_invoke):
+ self.drac_client.schedule_job_execution(job_ids=[])
+ mock_invoke.assert_not_called()
diff --git a/dracclient/tests/test_lifecycle_controller.py b/dracclient/tests/test_lifecycle_controller.py
index e53802a..136c201 100644
--- a/dracclient/tests/test_lifecycle_controller.py
+++ b/dracclient/tests/test_lifecycle_controller.py
@@ -11,12 +11,21 @@
# License for the specific language governing permissions and limitations
# under the License.
+import lxml.etree
+import re
+from unittest import mock
+
import requests_mock
import dracclient.client
+from dracclient import constants
+from dracclient import exceptions
+import dracclient.resources.job
+from dracclient.resources import lifecycle_controller
from dracclient.resources import uris
from dracclient.tests import base
from dracclient.tests import utils as test_utils
+from dracclient import utils
class ClientLifecycleControllerManagementTestCase(base.BaseTest):
@@ -36,3 +45,256 @@ def test_get_lifecycle_controller_version(self, mock_requests):
version = self.drac_client.get_lifecycle_controller_version()
self.assertEqual((2, 1, 0), version)
+
+
+@requests_mock.Mocker()
+class ClientLCConfigurationTestCase(base.BaseTest):
+
+ def setUp(self):
+ super(ClientLCConfigurationTestCase, self).setUp()
+ self.drac_client = dracclient.client.DRACClient(
+ **test_utils.FAKE_ENDPOINT)
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_list_lifecycle_settings_by_instance_id(
+ self, mock_requests,
+ mock_wait_until_idrac_is_ready):
+ expected_enum_attr = lifecycle_controller.LCEnumerableAttribute(
+ name='Lifecycle Controller State',
+ instance_id='LifecycleController.Embedded.1#LCAttributes.1#LifecycleControllerState', # noqa
+ read_only=False,
+ current_value='Enabled',
+ pending_value=None,
+ possible_values=['Disabled', 'Enabled', 'Recovery'])
+ expected_string_attr = lifecycle_controller.LCStringAttribute(
+ name='SYSID',
+ instance_id='LifecycleController.Embedded.1#LCAttributes.1#SystemID', # noqa
+ read_only=True,
+ current_value='639',
+ pending_value=None,
+ min_length=0,
+ max_length=3)
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.LifecycleControllerEnumerations[
+ uris.DCIM_LCEnumeration]['ok']},
+ {'text': test_utils.LifecycleControllerEnumerations[
+ uris.DCIM_LCString]['ok']}])
+
+ lifecycle_settings = self.drac_client.list_lifecycle_settings(
+ by_name=False)
+
+ self.assertEqual(14, len(lifecycle_settings))
+ # enumerable attribute
+ self.assertIn(
+ 'LifecycleController.Embedded.1#LCAttributes.1#LifecycleControllerState', # noqa
+ lifecycle_settings)
+ self.assertEqual(expected_enum_attr, lifecycle_settings[
+ 'LifecycleController.Embedded.1#LCAttributes.1#LifecycleControllerState']) # noqa
+ # string attribute
+ self.assertIn(
+ 'LifecycleController.Embedded.1#LCAttributes.1#SystemID',
+ lifecycle_settings)
+ self.assertEqual(expected_string_attr,
+ lifecycle_settings['LifecycleController.Embedded.1#LCAttributes.1#SystemID']) # noqa
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_list_lifecycle_settings_by_name(
+ self, mock_requests,
+ mock_wait_until_idrac_is_ready):
+ expected_enum_attr = lifecycle_controller.LCEnumerableAttribute(
+ name='Lifecycle Controller State',
+ instance_id='LifecycleController.Embedded.1#LCAttributes.1#LifecycleControllerState', # noqa
+ read_only=False,
+ current_value='Enabled',
+ pending_value=None,
+ possible_values=['Disabled', 'Enabled', 'Recovery'])
+ expected_string_attr = lifecycle_controller.LCStringAttribute(
+ name='SYSID',
+ instance_id='LifecycleController.Embedded.1#LCAttributes.1#SystemID', # noqa
+ read_only=True,
+ current_value='639',
+ pending_value=None,
+ min_length=0,
+ max_length=3)
+
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.LifecycleControllerEnumerations[
+ uris.DCIM_LCEnumeration]['ok']},
+ {'text': test_utils.LifecycleControllerEnumerations[
+ uris.DCIM_LCString]['ok']}])
+
+ lifecycle_settings = self.drac_client.list_lifecycle_settings(
+ by_name=True)
+
+ self.assertEqual(14, len(lifecycle_settings))
+ # enumerable attribute
+ self.assertIn(
+ 'Lifecycle Controller State',
+ lifecycle_settings)
+ self.assertEqual(expected_enum_attr, lifecycle_settings[
+ 'Lifecycle Controller State'])
+ # string attribute
+ self.assertIn(
+ 'SYSID',
+ lifecycle_settings)
+ self.assertEqual(expected_string_attr,
+ lifecycle_settings['SYSID'])
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_is_lifecycle_in_recovery(self, mock_requests,
+ mock_invoke):
+ expected_selectors = {'CreationClassName': 'DCIM_LCService',
+ 'SystemName': 'DCIM:ComputerSystem',
+ 'Name': 'DCIM:LCService',
+ 'SystemCreationClassName': 'DCIM_ComputerSystem'}
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.LifecycleControllerInvocations[uris.DCIM_LCService][
+ 'GetRemoteServicesAPIStatus']['is_recovery'])
+ result = self.drac_client.is_lifecycle_in_recovery()
+
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_LCService, 'GetRemoteServicesAPIStatus',
+ expected_selectors, {},
+ expected_return_value=utils.RET_SUCCESS,
+ wait_for_idrac=False)
+
+ self.assertEqual(True, result)
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'invoke', spec_set=True,
+ autospec=True)
+ def test_set_lifecycle_settings(self, mock_requests,
+ mock_invoke):
+
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.LifecycleControllerEnumerations[
+ uris.DCIM_LCEnumeration]['ok']},
+ {'text': test_utils.LifecycleControllerEnumerations[
+ uris.DCIM_LCString]['ok']}])
+
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.LifecycleControllerInvocations[uris.DCIM_LCService][
+ 'SetAttributes']['ok'])
+
+ result = self.drac_client.set_lifecycle_settings(
+ {'Collect System Inventory on Restart': 'Disabled'})
+
+ self.assertEqual({'is_commit_required': True,
+ 'is_reboot_required': constants.RebootRequired.false
+ },
+ result)
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_set_lifecycle_settings_with_unknown_attr(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.LifecycleControllerEnumerations[
+ uris.DCIM_LCEnumeration]['ok']},
+ {'text': test_utils.LifecycleControllerEnumerations[
+ uris.DCIM_LCString]['ok']},
+ {'text': test_utils.LifecycleControllerInvocations[
+ uris.DCIM_LCService]['SetAttributes']['error']}])
+
+ self.assertRaises(exceptions.InvalidParameterValue,
+ self.drac_client.set_lifecycle_settings,
+ {'foo': 'bar'})
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_set_lifecycle_settings_with_unchanged_attr(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.LifecycleControllerEnumerations[
+ uris.DCIM_LCEnumeration]['ok']},
+ {'text': test_utils.LifecycleControllerEnumerations[
+ uris.DCIM_LCString]['ok']}])
+
+ result = self.drac_client.set_lifecycle_settings(
+ {'Lifecycle Controller State': 'Enabled'})
+
+ self.assertEqual({'is_commit_required': False,
+ 'is_reboot_required':
+ constants.RebootRequired.false},
+ result)
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_set_lifecycle_settings_with_readonly_attr(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ expected_message = ("Cannot set read-only Lifecycle attributes: "
+ "['Licensed'].")
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.LifecycleControllerEnumerations[
+ uris.DCIM_LCEnumeration]['ok']},
+ {'text': test_utils.LifecycleControllerEnumerations[
+ uris.DCIM_LCString]['ok']}])
+
+ self.assertRaisesRegexp(
+ exceptions.DRACOperationFailed, re.escape(expected_message),
+ self.drac_client.set_lifecycle_settings, {'Licensed': 'yes'})
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_set_lifecycle_settings_with_incorrect_enum_value(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ expected_message = ("Attribute 'Lifecycle Controller State' cannot "
+ "be set to value 'foo'. It must be in "
+ "['Disabled', 'Enabled', 'Recovery'].")
+
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.LifecycleControllerEnumerations[
+ uris.DCIM_LCEnumeration]['ok']},
+ {'text': test_utils.LifecycleControllerEnumerations[
+ uris.DCIM_LCString]['ok']}])
+ self.assertRaisesRegexp(
+ exceptions.DRACOperationFailed, re.escape(expected_message),
+ self.drac_client.set_lifecycle_settings,
+ {'Lifecycle Controller State': 'foo'})
+
+
+class ClientLCChangesTestCase(base.BaseTest):
+
+ def setUp(self):
+ super(ClientLCChangesTestCase, self).setUp()
+ self.drac_client = dracclient.client.DRACClient(
+ **test_utils.FAKE_ENDPOINT)
+
+ @mock.patch.object(dracclient.resources.job.JobManagement,
+ 'create_config_job', spec_set=True, autospec=True)
+ def test_commit_pending_lifecycle_changes(self, mock_create_config_job):
+
+ self.drac_client.commit_pending_lifecycle_changes()
+
+ mock_create_config_job.assert_called_once_with(
+ mock.ANY, resource_uri=uris.DCIM_LCService,
+ cim_creation_class_name='DCIM_LCService',
+ cim_name='DCIM:LCService', target='',
+ reboot=False, start_time='TIME_NOW',
+ wait_for_idrac=False,
+ method_name='CreateConfigJob')
+
+ @mock.patch.object(dracclient.resources.job.JobManagement,
+ 'create_config_job', spec_set=True, autospec=True)
+ def test_commit_pending_lifecycle_changes_with_time(
+ self, mock_create_config_job):
+ timestamp = '20140924140201'
+ self.drac_client.commit_pending_lifecycle_changes(
+ start_time=timestamp)
+
+ mock_create_config_job.assert_called_once_with(
+ mock.ANY, resource_uri=uris.DCIM_LCService,
+ cim_creation_class_name='DCIM_LCService',
+ cim_name='DCIM:LCService', target='',
+ reboot=False, start_time=timestamp,
+ wait_for_idrac=False,
+ method_name='CreateConfigJob')
diff --git a/dracclient/tests/test_nic.py b/dracclient/tests/test_nic.py
new file mode 100644
index 0000000..2a4ea79
--- /dev/null
+++ b/dracclient/tests/test_nic.py
@@ -0,0 +1,495 @@
+#
+# 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 datetime
+import lxml.etree
+import re
+from unittest import mock
+
+import requests_mock
+
+import dracclient.client
+from dracclient import constants
+from dracclient import exceptions
+from dracclient.resources.inventory import NIC
+import dracclient.resources.job
+from dracclient.resources import nic
+from dracclient.resources import uris
+from dracclient.tests import base
+from dracclient.tests import utils as test_utils
+
+
+@requests_mock.Mocker()
+@mock.patch.object(dracclient.client.WSManClient, 'wait_until_idrac_is_ready',
+ spec_set=True, autospec=True)
+class ClientNICTestCase(base.BaseTest):
+
+ def setUp(self):
+ super(ClientNICTestCase, self).setUp()
+ self.drac_client = dracclient.client.DRACClient(
+ **test_utils.FAKE_ENDPOINT)
+
+ def test_list_nics(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
+ expected_nics = [
+ NIC(id='NIC.Embedded.1-1-1',
+ mac='B0:83:FE:C6:6F:A1',
+ model='Broadcom Gigabit Ethernet BCM5720 - B0:83:FE:C6:6F:A1',
+ speed_mbps=1000,
+ duplex='full duplex',
+ media_type='Base T'),
+ NIC(id='NIC.Slot.2-1-1',
+ mac='A0:36:9F:52:7D:1E',
+ model='Intel(R) Gigabit 2P I350-t Adapter - A0:36:9F:52:7D:1E',
+ speed_mbps=1000,
+ duplex='full duplex',
+ media_type='Base T'),
+ NIC(id='NIC.Slot.2-2-1',
+ mac='A0:36:9F:52:7D:1F',
+ model='Intel(R) Gigabit 2P I350-t Adapter - A0:36:9F:52:7D:1F',
+ speed_mbps=1000,
+ duplex='full duplex',
+ media_type='Base T'),
+ NIC(id='NIC.Embedded.2-1-1',
+ mac='B0:83:FE:C6:6F:A2',
+ model='Broadcom Gigabit Ethernet BCM5720 - B0:83:FE:C6:6F:A2',
+ speed_mbps=1000,
+ duplex='full duplex',
+ media_type='Base T')
+ ]
+
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.InventoryEnumerations[uris.DCIM_NICView]['ok'])
+
+ self.assertEqual(expected_nics, self.drac_client.list_nics())
+
+ def test_list_nics_sorted(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
+ expected_nics = [
+ NIC(id='NIC.Embedded.1-1-1',
+ mac='B0:83:FE:C6:6F:A1',
+ model='Broadcom Gigabit Ethernet BCM5720 - B0:83:FE:C6:6F:A1',
+ speed_mbps=1000,
+ duplex='full duplex',
+ media_type='Base T'),
+ NIC(id='NIC.Embedded.2-1-1',
+ mac='B0:83:FE:C6:6F:A2',
+ model='Broadcom Gigabit Ethernet BCM5720 - B0:83:FE:C6:6F:A2',
+ speed_mbps=1000,
+ duplex='full duplex',
+ media_type='Base T'),
+ NIC(id='NIC.Slot.2-1-1',
+ mac='A0:36:9F:52:7D:1E',
+ model='Intel(R) Gigabit 2P I350-t Adapter - A0:36:9F:52:7D:1E',
+ speed_mbps=1000,
+ duplex='full duplex',
+ media_type='Base T'),
+ NIC(id='NIC.Slot.2-2-1',
+ mac='A0:36:9F:52:7D:1F',
+ model='Intel(R) Gigabit 2P I350-t Adapter - A0:36:9F:52:7D:1F',
+ speed_mbps=1000,
+ duplex='full duplex',
+ media_type='Base T')
+ ]
+
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.InventoryEnumerations[uris.DCIM_NICView]['ok'])
+
+ self.assertEqual(expected_nics, self.drac_client.list_nics(sort=True))
+
+ def test_list_nic_settings(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
+ expected_enum_attr = nic.NICEnumerationAttribute(
+ name='BootStrapType',
+ instance_id='NIC.Integrated.1-3-1:BootStrapType',
+ fqdd='NIC.Integrated.1-3-1',
+ read_only=False,
+ current_value='AutoDetect',
+ pending_value=None,
+ possible_values=['AutoDetect', 'BBS', 'Int18h', 'Int19h'])
+
+ expected_string_attr = nic.NICStringAttribute(
+ name='BusDeviceFunction',
+ instance_id='NIC.Integrated.1-3-1:BusDeviceFunction',
+ fqdd='NIC.Integrated.1-3-1',
+ read_only=True,
+ current_value='02:00:00',
+ pending_value=None,
+ min_length=0,
+ max_length=0,
+ pcre_regex=None)
+
+ expected_integer_attr = nic.NICIntegerAttribute(
+ name='BlnkLeds',
+ instance_id='NIC.Integrated.1-3-1:BlnkLeds',
+ fqdd='NIC.Integrated.1-3-1',
+ read_only=False,
+ current_value=0,
+ pending_value=None,
+ lower_bound=0,
+ upper_bound=15)
+
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICEnumeration]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICString]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICInteger]['ok']}])
+
+ nic_settings = self.drac_client.list_nic_settings(
+ nic_id='NIC.Integrated.1-3-1')
+
+ self.assertEqual(63, len(nic_settings))
+
+ self.assertIn('BootStrapType', nic_settings)
+ self.assertEqual(expected_enum_attr,
+ nic_settings['BootStrapType'])
+
+ self.assertIn('BusDeviceFunction', nic_settings)
+ self.assertEqual(expected_string_attr,
+ nic_settings['BusDeviceFunction'])
+
+ self.assertIn('BlnkLeds', nic_settings)
+ self.assertEqual(expected_integer_attr,
+ nic_settings['BlnkLeds'])
+
+ def test_list_nic_settings_with_colliding_attrs(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICEnumeration]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICString]['colliding']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICInteger]['ok']}])
+
+ self.assertRaises(
+ exceptions.DRACOperationFailed,
+ self.drac_client.list_nic_settings,
+ nic_id='NIC.Integrated.1-3-1')
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke', spec_set=True,
+ autospec=True)
+ def test_set_nic_settings(self, mock_requests, mock_invoke,
+ mock_wait_until_idrac_is_ready):
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICEnumeration]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICString]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICInteger]['ok']}])
+
+ expected_selectors = {'CreationClassName': 'DCIM_NICService',
+ 'Name': 'DCIM:NICService',
+ 'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'DCIM:ComputerSystem'}
+ expected_properties = {'Target': 'NIC.Integrated.1-3-1',
+ 'AttributeValue': ['PXE'],
+ 'AttributeName': ['LegacyBootProto']}
+
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.NICInvocations[uris.DCIM_NICService][
+ 'SetAttributes']['ok'])
+
+ result = self.drac_client.set_nic_settings(
+ nic_id='NIC.Integrated.1-3-1',
+ settings={'LegacyBootProto': 'PXE'})
+
+ self.assertEqual({'is_commit_required': True,
+ 'is_reboot_required': constants.RebootRequired.true},
+ result)
+
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_NICService, 'SetAttributes',
+ expected_selectors, expected_properties,
+ wait_for_idrac=True)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke', spec_set=True,
+ autospec=True)
+ def test_set_nic_settings_string(self, mock_requests, mock_invoke,
+ mock_wait_until_idrac_is_ready):
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICEnumeration]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICString]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICInteger]['ok']}])
+
+ expected_selectors = {'CreationClassName': 'DCIM_NICService',
+ 'Name': 'DCIM:NICService',
+ 'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'DCIM:ComputerSystem'}
+ expected_properties = {'Target': 'NIC.Integrated.1-3-1',
+ 'AttributeValue': ['D4:AE:52:A5:B1:01'],
+ 'AttributeName': ['VirtMacAddr']}
+
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.NICInvocations[uris.DCIM_NICService][
+ 'SetAttributes']['ok'])
+
+ result = self.drac_client.set_nic_settings(
+ nic_id='NIC.Integrated.1-3-1',
+ settings={'VirtMacAddr': 'D4:AE:52:A5:B1:01'})
+
+ self.assertEqual({'is_commit_required': True,
+ 'is_reboot_required': constants.RebootRequired.true},
+ result)
+
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_NICService, 'SetAttributes',
+ expected_selectors, expected_properties,
+ wait_for_idrac=True)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke', spec_set=True,
+ autospec=True)
+ def test_set_nic_settings_integer(self, mock_requests, mock_invoke,
+ mock_wait_until_idrac_is_ready):
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICEnumeration]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICString]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICInteger]['ok']}])
+
+ expected_selectors = {'CreationClassName': 'DCIM_NICService',
+ 'Name': 'DCIM:NICService',
+ 'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'DCIM:ComputerSystem'}
+ expected_properties = {'Target': 'NIC.Integrated.1-3-1',
+ 'AttributeValue': [1],
+ 'AttributeName': ['SecondTgtBootLun']}
+
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.NICInvocations[uris.DCIM_NICService][
+ 'SetAttributes']['ok'])
+
+ result = self.drac_client.set_nic_settings(
+ nic_id='NIC.Integrated.1-3-1',
+ settings={'SecondTgtBootLun': 1})
+
+ self.assertEqual({'is_commit_required': True,
+ 'is_reboot_required': constants.RebootRequired.true},
+ result)
+
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_NICService, 'SetAttributes',
+ expected_selectors, expected_properties,
+ wait_for_idrac=True)
+
+ def test_set_nic_settings_error(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICEnumeration]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICString]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICInteger]['ok']},
+ {'text': test_utils.NICInvocations[
+ uris.DCIM_NICService]['SetAttributes']['error']}])
+
+ self.assertRaises(exceptions.DRACOperationFailed,
+ self.drac_client.set_nic_settings,
+ 'NIC.InvalidTarget',
+ {'LegacyBootProto': 'PXE'})
+
+ def test_set_nic_settings_with_unknown_attr(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICEnumeration]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICString]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICInteger]['ok']}])
+
+ self.assertRaises(exceptions.InvalidParameterValue,
+ self.drac_client.set_nic_settings,
+ 'NIC.Integrated.1-3-1',
+ {'foo': 'bar'})
+
+ def test_set_nic_settings_with_unchanged_attr(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICEnumeration]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICString]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICInteger]['ok']}])
+
+ result = self.drac_client.set_nic_settings(
+ nic_id='NIC.Integrated.1-3-1',
+ settings={'LegacyBootProto': 'NONE'})
+
+ self.assertEqual({'is_commit_required': False,
+ 'is_reboot_required':
+ constants.RebootRequired.false},
+ result)
+
+ def test_set_nic_settings_with_readonly_attr(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ expected_message = (
+ "Cannot set read-only iDRAC Card attributes: ['LinkStatus'].")
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICEnumeration]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICString]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICInteger]['ok']}])
+
+ self.assertRaisesRegexp(
+ exceptions.DRACOperationFailed, re.escape(expected_message),
+ self.drac_client.set_nic_settings,
+ 'NIC.Integrated.1-3-1',
+ {'LinkStatus': 'Connected'})
+
+ def test_set_nic_settings_with_incorrect_enum(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ expected_message = (
+ "Attribute 'LegacyBootProto' cannot be set to value 'foo'. "
+ "It must be in ['PXE', 'iSCSI', 'NONE'].")
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICEnumeration]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICString]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICInteger]['ok']}])
+
+ self.assertRaisesRegexp(
+ exceptions.DRACOperationFailed, re.escape(expected_message),
+ self.drac_client.set_nic_settings,
+ 'NIC.Integrated.1-3-1',
+ {'LegacyBootProto': 'foo'})
+
+ def test_set_nic_settings_with_incorrect_regexp(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ expected_message = (
+ "Attribute 'VirtMacAddr' cannot be set to value 'foo.' "
+ "It must match regex '^([0-9a-fA-F]{2}:){5}([0-9a-fA-F]{2})$'.")
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICEnumeration]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICString]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICInteger]['ok']}])
+
+ self.assertRaisesRegexp(
+ exceptions.DRACOperationFailed, re.escape(expected_message),
+ self.drac_client.set_nic_settings,
+ 'NIC.Integrated.1-3-1',
+ {'VirtMacAddr': 'foo'})
+
+ def test_set_nic_settings_with_out_of_bounds_value(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ expected_message = (
+ "Attribute BannerMessageTimeout cannot be set to value 100. "
+ "It must be between 0 and 14.")
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICEnumeration]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICString]['ok']},
+ {'text': test_utils.NICEnumerations[
+ uris.DCIM_NICInteger]['ok']}])
+
+ self.assertRaisesRegexp(
+ exceptions.DRACOperationFailed, re.escape(expected_message),
+ self.drac_client.set_nic_settings,
+ 'NIC.Integrated.1-3-1',
+ {'BannerMessageTimeout': 100})
+
+
+class ClientNICSettingTestCase(base.BaseTest):
+
+ def setUp(self):
+ super(ClientNICSettingTestCase, self).setUp()
+ self.drac_client = dracclient.client.DRACClient(
+ **test_utils.FAKE_ENDPOINT)
+
+ @mock.patch.object(dracclient.resources.job.JobManagement,
+ 'create_config_job', spec_set=True, autospec=True)
+ def test_create_nic_config_job(self, mock_create_config_job):
+
+ nic_id = 'NIC.Embedded.1-1-1'
+ self.drac_client.create_nic_config_job(
+ nic_id=nic_id)
+
+ mock_create_config_job.assert_called_once_with(
+ mock.ANY, resource_uri=uris.DCIM_NICService,
+ cim_creation_class_name='DCIM_NICService',
+ cim_name='DCIM:NICService',
+ target=nic_id,
+ reboot=False,
+ start_time='TIME_NOW')
+
+ @mock.patch.object(dracclient.resources.job.JobManagement,
+ 'create_config_job', spec_set=True, autospec=True)
+ def test_create_nic_config_job_reboot(self, mock_create_config_job):
+
+ nic_id = 'NIC.Embedded.1-1-1'
+ self.drac_client.create_nic_config_job(
+ nic_id=nic_id,
+ reboot=True)
+
+ mock_create_config_job.assert_called_once_with(
+ mock.ANY, resource_uri=uris.DCIM_NICService,
+ cim_creation_class_name='DCIM_NICService',
+ cim_name='DCIM:NICService',
+ target=nic_id,
+ reboot=True,
+ start_time='TIME_NOW')
+
+ @mock.patch.object(dracclient.resources.job.JobManagement,
+ 'create_config_job', spec_set=True, autospec=True)
+ def test_create_nic_config_job_time(self, mock_create_config_job):
+
+ nic_id = 'NIC.Embedded.1-1-1'
+ timestamp = datetime.datetime.today().strftime('%Y%m%d%H%M%S')
+ self.drac_client.create_nic_config_job(
+ nic_id=nic_id,
+ start_time=timestamp)
+
+ mock_create_config_job.assert_called_once_with(
+ mock.ANY, resource_uri=uris.DCIM_NICService,
+ cim_creation_class_name='DCIM_NICService',
+ cim_name='DCIM:NICService',
+ target=nic_id,
+ reboot=False,
+ start_time=timestamp)
+
+ @mock.patch.object(dracclient.resources.job.JobManagement,
+ 'create_config_job', spec_set=True, autospec=True)
+ def test_create_nic_config_job_no_time(self, mock_create_config_job):
+
+ nic_id = 'NIC.Embedded.1-1-1'
+ self.drac_client.create_nic_config_job(
+ nic_id=nic_id,
+ start_time=None)
+
+ mock_create_config_job.assert_called_once_with(
+ mock.ANY, resource_uri=uris.DCIM_NICService,
+ cim_creation_class_name='DCIM_NICService',
+ cim_name='DCIM:NICService',
+ target=nic_id,
+ reboot=False,
+ start_time=None)
diff --git a/dracclient/tests/test_raid.py b/dracclient/tests/test_raid.py
index f802db8..0793ca5 100644
--- a/dracclient/tests/test_raid.py
+++ b/dracclient/tests/test_raid.py
@@ -11,12 +11,17 @@
# License for the specific language governing permissions and limitations
# under the License.
+
+import collections
import lxml.etree
-import mock
import random
+import re
+from unittest import mock
+
import requests_mock
import dracclient.client
+from dracclient import constants
from dracclient import exceptions
import dracclient.resources.job
from dracclient.resources import raid
@@ -33,16 +38,278 @@ def setUp(self):
super(ClientRAIDManagementTestCase, self).setUp()
self.drac_client = dracclient.client.DRACClient(
**test_utils.FAKE_ENDPOINT)
+ self.raid_controller_fqdd = "RAID.Integrated.1-1"
+ self.boss_controller_fqdd = "AHCI.Slot.3-1"
+ cntl_dict = {'RAID.Integrated.1-1':
+ ['Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1',
+ 'Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1'],
+ 'AHCI.Integrated.1-1':
+ ['Disk.Bay.0:Enclosure.Internal.0-1:AHCI.Integrated.1-1',
+ 'Disk.Bay.1:Enclosure.Internal.0-1:AHCI.Integrated.1-1']}
+ self.controllers_to_physical_disk_ids = cntl_dict
+ self.disk_1 = raid.PhysicalDisk(
+ id='Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1',
+ description='Disk 0 in Backplane 1 of Int RAID Controller 1',
+ controller='RAID.Integrated.1-1',
+ manufacturer='ATA',
+ model='ST91000640NS',
+ media_type='hdd',
+ interface_type='sata',
+ size_mb=953344,
+ free_size_mb=953344,
+ serial_number='9XG4SLGZ',
+ firmware_version='AA09',
+ status='ok',
+ raid_status='ready',
+ sas_address='500056B37789ABE3',
+ device_protocol=None,
+ bus=None)
- def test_list_raid_controllers(self, mock_requests):
+ self.disk_2 = raid.PhysicalDisk(
+ id='Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1',
+ description='Disk 1 in Backplane 1 of Int RAID Controller 1',
+ controller='RAID.Integrated.1-1',
+ manufacturer='ATA',
+ model='ST91000640NS',
+ media_type='hdd',
+ interface_type='sata',
+ size_mb=953344,
+ free_size_mb=953344,
+ serial_number='9XG4SLGZ',
+ firmware_version='AA09',
+ status='online',
+ raid_status='ready',
+ sas_address='500056B37789ABE3',
+ device_protocol=None,
+ bus=None)
+
+ self.disk_3 = raid.PhysicalDisk(
+ id='Disk.Bay.0:Enclosure.Internal.0-1:AHCI.Integrated.1-1',
+ description='Disk 1 in Backplane 1 of Int BOSS Controller 1',
+ controller='AHCI.Integrated.1-1',
+ manufacturer='ATA',
+ model='ST91000640NS',
+ media_type='hdd',
+ interface_type='sata',
+ size_mb=953344,
+ free_size_mb=953344,
+ serial_number='9XG4SLGZ',
+ firmware_version='AA09',
+ status='online',
+ raid_status='ready',
+ sas_address='500056B37789ABE3',
+ device_protocol=None,
+ bus=None)
+
+ self.disk_4 = raid.PhysicalDisk(
+ id='Disk.Bay.1:Enclosure.Internal.0-1:AHCI.Integrated.1-1',
+ description='Disk 1 in Backplane 1 of Int RAID Controller 1',
+ controller='AHCI.Integrated.1-1',
+ manufacturer='ATA',
+ model='ST91000640NS',
+ media_type='hdd',
+ interface_type='sata',
+ size_mb=953344,
+ free_size_mb=953344,
+ serial_number='9XG4SLGZ',
+ firmware_version='AA09',
+ status='online',
+ raid_status='ready',
+ sas_address='500056B37789ABE3',
+ device_protocol=None,
+ bus=None)
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_list_raid_settings(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
+ expected_enum_attr = raid.RAIDEnumerableAttribute(
+ name='RAIDCurrentControllerMode',
+ instance_id='RAID.Integrated.1-1:RAIDCurrentControllerMode', # noqa
+ current_value=['RAID'],
+ pending_value=None,
+ read_only=True,
+ fqdd='RAID.Integrated.1-1',
+ possible_values=['RAID', 'Enhanced HBA'])
+ expected_string_attr = raid.RAIDStringAttribute(
+ name='Name',
+ instance_id='Disk.Virtual.1:RAID.Integrated.1-1:Name', # noqa
+ current_value='Virtual Disk 1',
+ pending_value=None,
+ read_only=True,
+ fqdd='Disk.Virtual.1:RAID.Integrated.1-1',
+ min_length=0,
+ max_length=129)
+ expected_integer_attr = raid.RAIDIntegerAttribute(
+ name='RAIDmaxSupportedVD',
+ instance_id='RAID.Integrated.1-1:RAIDmaxSupportedVD', # noqa
+ current_value=240,
+ pending_value=None,
+ read_only=True,
+ fqdd='RAID.Integrated.1-1',
+ lower_bound=0,
+ upper_bound=0)
+ # expected_string_attr
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.RAIDEnumerations[
+ uris.DCIM_RAIDEnumeration]['ok']},
+ {'text': test_utils.RAIDEnumerations[
+ uris.DCIM_RAIDString]['ok']},
+ {'text': test_utils.RAIDEnumerations[
+ uris.DCIM_RAIDInteger]['ok']}
+ ])
+
+ raid_settings = self.drac_client.list_raid_settings()
+ self.assertEqual(219, len(raid_settings))
+ # enumerable attribute
+ self.assertIn(
+ 'RAID.Integrated.1-1:RAIDCurrentControllerMode', # noqa
+ raid_settings)
+ self.assertEqual(expected_enum_attr.fqdd, raid_settings[
+ 'RAID.Integrated.1-1:RAIDCurrentControllerMode'].fqdd) # noqa
+ # string attribute
+ self.assertIn(
+ 'Disk.Virtual.1:RAID.Integrated.1-1:Name', # noqa
+ raid_settings)
+ self.assertEqual(expected_string_attr.fqdd,
+ raid_settings['Disk.Virtual.1:RAID.Integrated.1-1:Name'].fqdd) # noqa
+ # integer attribute
+ self.assertIn(
+ 'RAID.Integrated.1-1:RAIDmaxSupportedVD', # noqa
+ raid_settings)
+ self.assertEqual(expected_integer_attr.fqdd, raid_settings[
+ 'RAID.Integrated.1-1:RAIDmaxSupportedVD'].fqdd) # noqa
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'invoke', spec_set=True,
+ autospec=True)
+ def test_set_raid_settings(self, mock_requests,
+ mock_invoke,
+ mock_wait_until_idrac_is_ready):
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.RAIDEnumerations[
+ uris.DCIM_RAIDEnumeration]['ok']},
+ {'text': test_utils.RAIDEnumerations[
+ uris.DCIM_RAIDString]['ok']},
+ {'text': test_utils.RAIDEnumerations[
+ uris.DCIM_RAIDInteger]['ok']}])
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.RAIDInvocations[uris.DCIM_RAIDService][
+ 'SetAttributes']['ok'])
+
+ result = self.drac_client.set_raid_settings(
+ self.raid_controller_fqdd,
+ {'RAID.Integrated.1-1:RAIDRequestedControllerMode': 'RAID'})
+
+ self.assertEqual({'is_commit_required': True,
+ 'is_reboot_required': constants.RebootRequired.true
+ },
+ result)
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_set_raid_settings_with_unknown_attr(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.RAIDEnumerations[
+ uris.DCIM_RAIDEnumeration]['ok']},
+ {'text': test_utils.RAIDEnumerations[
+ uris.DCIM_RAIDString]['ok']},
+ {'text': test_utils.RAIDEnumerations[
+ uris.DCIM_RAIDInteger]['ok']},
+ {'text': test_utils.RAIDInvocations[
+ uris.DCIM_RAIDService]['SetAttributes']['error']}])
+
+ self.assertRaises(exceptions.InvalidParameterValue,
+ self.drac_client.set_raid_settings,
+ self.raid_controller_fqdd, {'foo': 'bar'})
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_set_raid_settings_with_unchanged_attr(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.RAIDEnumerations[
+ uris.DCIM_RAIDEnumeration]['ok']},
+ {'text': test_utils.RAIDEnumerations[
+ uris.DCIM_RAIDString]['ok']},
+ {'text': test_utils.RAIDEnumerations[
+ uris.DCIM_RAIDInteger]['ok']}])
+ attrKey = 'Disk.Virtual.1:RAID.Integrated.1-1:RAIDdefaultWritePolicy'
+ result = self.drac_client.set_raid_settings(
+ self.raid_controller_fqdd,
+ {attrKey: 'WriteBack'})
+
+ self.assertEqual({'is_commit_required': False,
+ 'is_reboot_required':
+ constants.RebootRequired.false},
+ result)
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_set_raid_settings_with_readonly_attr(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ expected_message = (
+ "Cannot set read-only RAID attributes: "
+ "['RAID.Integrated.1-1:RAIDCurrentControllerMode']."
+ )
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.RAIDEnumerations[
+ uris.DCIM_RAIDEnumeration]['ok']},
+ {'text': test_utils.RAIDEnumerations[
+ uris.DCIM_RAIDString]['ok']},
+ {'text': test_utils.RAIDEnumerations[
+ uris.DCIM_RAIDInteger]['ok']}])
+
+ self.assertRaisesRegexp(
+ exceptions.DRACOperationFailed, re.escape(expected_message),
+ self.drac_client.set_raid_settings,
+ self.raid_controller_fqdd,
+ {'RAID.Integrated.1-1:RAIDCurrentControllerMode': 'Enhanced HBA'})
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_set_raid_settings_with_incorrect_enum_value(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ expected_message = ("Attribute 'RAIDRequestedControllerMode' cannot "
+ "be set to value 'foo'. It must be in "
+ "['RAID', 'Enhanced HBA', 'None'].")
+
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.RAIDEnumerations[
+ uris.DCIM_RAIDEnumeration]['ok']},
+ {'text': test_utils.RAIDEnumerations[
+ uris.DCIM_RAIDString]['ok']},
+ {'text': test_utils.RAIDEnumerations[
+ uris.DCIM_RAIDInteger]['ok']}])
+ self.assertRaisesRegexp(
+ exceptions.DRACOperationFailed, re.escape(expected_message),
+ self.drac_client.set_raid_settings,
+ self.raid_controller_fqdd,
+ {'RAID.Integrated.1-1:RAIDRequestedControllerMode': 'foo'})
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_list_raid_controllers(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
expected_raid_controller = raid.RAIDController(
id='RAID.Integrated.1-1',
description='Integrated RAID Controller 1',
manufacturer='DELL',
model='PERC H710 Mini',
primary_status='ok',
- firmware_version='21.3.0-0009')
-
+ firmware_version='21.3.0-0009',
+ bus='1',
+ supports_realtime=True)
mock_requests.post(
'https://1.2.3.4:443/wsman',
text=test_utils.RAIDEnumerations[uris.DCIM_ControllerView]['ok'])
@@ -50,7 +317,11 @@ def test_list_raid_controllers(self, mock_requests):
self.assertIn(expected_raid_controller,
self.drac_client.list_raid_controllers())
- def test_list_virtual_disks(self, mock_requests):
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_list_virtual_disks(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
expected_virtual_disk = raid.VirtualDisk(
id='Disk.Virtual.0:RAID.Integrated.1-1',
name='disk 0',
@@ -62,7 +333,11 @@ def test_list_virtual_disks(self, mock_requests):
raid_status='online',
span_depth=1,
span_length=2,
- pending_operations=None)
+ pending_operations=None,
+ physical_disks=[
+ 'Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1',
+ 'Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1'
+ ])
mock_requests.post(
'https://1.2.3.4:443/wsman',
@@ -71,7 +346,41 @@ def test_list_virtual_disks(self, mock_requests):
self.assertIn(expected_virtual_disk,
self.drac_client.list_virtual_disks())
- def test_list_physical_disks(self, mock_requests):
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_list_virtual_disks_with_raid_status_change(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ 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,
+ status='ok',
+ raid_status='online',
+ span_depth=1,
+ span_length=2,
+ pending_operations=None,
+ physical_disks=[
+ 'Disk.Bay.4:Enclosure.Internal.0-1:RAID.Integrated.1-1',
+ 'Disk.Bay.5:Enclosure.Internal.0-1:RAID.Integrated.1-1'
+ ])
+
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.RAIDEnumerations[
+ uris.DCIM_VirtualDiskView]['Raid_Status_ok'])
+
+ self.assertIn(expected_virtual_disk,
+ self.drac_client.list_virtual_disks())
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_list_physical_disks(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
expected_physical_disk = raid.PhysicalDisk(
id='Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1',
description=('Disk 1 in Backplane 1 of '
@@ -86,7 +395,10 @@ def test_list_physical_disks(self, mock_requests):
serial_number='S0M3EY2Z',
firmware_version='LS0A',
status='ok',
- raid_status='ready')
+ raid_status='ready',
+ sas_address='5000C5007764F409',
+ device_protocol=None,
+ bus=None)
mock_requests.post(
'https://1.2.3.4:443/wsman',
@@ -95,7 +407,11 @@ def test_list_physical_disks(self, mock_requests):
self.assertIn(expected_physical_disk,
self.drac_client.list_physical_disks())
- def test_list_physical_disks_direct(self, mock_requests):
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_list_physical_disks_direct(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
expected_physical_disk = raid.PhysicalDisk(
id='Disk.Direct.2:RAID.Integrated.1-1',
description=('Disk 2 on '
@@ -110,7 +426,40 @@ def test_list_physical_disks_direct(self, mock_requests):
serial_number='S0M3EY3Z',
firmware_version='LS0B',
status='ok',
- raid_status='ready')
+ raid_status='ready',
+ sas_address='5000C5007764F409',
+ device_protocol=None,
+ bus=None)
+
+ 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,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_list_physical_disks_nvme(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
+ expected_physical_disk = raid.PhysicalDisk(
+ id='Disk.Bay.20:Enclosure.Internal.0-1:PCIeExtender.Slot.1',
+ description='PCIe SSD in Slot 20 in Bay 1',
+ controller='PCIeExtender.Slot.1',
+ manufacturer='SAMSUNG',
+ model='Dell Express Flash PM1725a 800GB SFF',
+ media_type='ssd',
+ interface_type='pcie',
+ size_mb=763097,
+ free_size_mb=None,
+ serial_number='S39YNX0JB02343',
+ firmware_version='1.0.4',
+ status='unknown',
+ raid_status=None,
+ sas_address=None,
+ device_protocol='NVMe-MI1.0',
+ bus='3E')
mock_requests.post(
'https://1.2.3.4:443/wsman',
@@ -142,13 +491,18 @@ def test_convert_physical_disks_1(self, mock_requests, mock_invoke):
'SystemName': 'DCIM:ComputerSystem',
'Name': 'DCIM:RAIDService'}
expected_properties = {'PDArray': [device_fqdd]}
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.RAIDInvocations[uris.DCIM_RAIDService][
+ 'ConvertToRAID']['ok'])
result = self.drac_client.convert_physical_disks(
raid_controller='controller',
physical_disks=[device_fqdd],
raid_enable=True)
- self.assertEqual({'commit_required': False}, result)
+ self.assertEqual({'is_commit_required': True,
+ 'is_reboot_required': constants.RebootRequired.true},
+ result)
mock_invoke.assert_called_once_with(
mock.ANY, uris.DCIM_RAIDService, expected_invocation,
expected_selectors, expected_properties,
@@ -168,13 +522,18 @@ def test_convert_physical_disks_n(self, mock_requests, mock_invoke):
'SystemName': 'DCIM:ComputerSystem',
'Name': 'DCIM:RAIDService'}
expected_properties = {'PDArray': device_list}
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.RAIDInvocations[uris.DCIM_RAIDService][
+ 'ConvertToRAID']['ok'])
result = self.drac_client.convert_physical_disks(
raid_controller='controller',
physical_disks=device_list,
raid_enable=True)
- self.assertEqual({'commit_required': False}, result)
+ self.assertEqual({'is_commit_required': True,
+ 'is_reboot_required': constants.RebootRequired.true},
+ result)
mock_invoke.assert_called_once_with(
mock.ANY, uris.DCIM_RAIDService, expected_invocation,
expected_selectors, expected_properties,
@@ -192,13 +551,18 @@ def test_convert_physical_disks_nonraid_1(self, mock_requests,
'SystemName': 'DCIM:ComputerSystem',
'Name': 'DCIM:RAIDService'}
expected_properties = {'PDArray': [device_fqdd]}
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.RAIDInvocations[uris.DCIM_RAIDService][
+ 'ConvertToRAID']['ok'])
result = self.drac_client.convert_physical_disks(
raid_controller='controller',
physical_disks=[device_fqdd],
raid_enable=False)
- self.assertEqual({'commit_required': False}, result)
+ self.assertEqual({'is_commit_required': True,
+ 'is_reboot_required': constants.RebootRequired.true},
+ result)
mock_invoke.assert_called_once_with(
mock.ANY, uris.DCIM_RAIDService, expected_invocation,
expected_selectors, expected_properties,
@@ -219,49 +583,28 @@ def test_convert_physical_disks_nonraid_n(self, mock_requests,
'SystemName': 'DCIM:ComputerSystem',
'Name': 'DCIM:RAIDService'}
expected_properties = {'PDArray': device_list}
-
- result = self.drac_client.convert_physical_disks(
- raid_controller='controller',
- physical_disks=device_list,
- raid_enable=False)
-
- self.assertEqual({'commit_required': False}, result)
- mock_invoke.assert_called_once_with(
- mock.ANY, uris.DCIM_RAIDService, expected_invocation,
- expected_selectors, expected_properties,
- expected_return_value=utils.RET_SUCCESS)
-
- @mock.patch.object(dracclient.client.WSManClient, 'invoke',
- spec_set=True, autospec=True)
- def test_convert_physical_disks_ok(self, mock_requests, mock_invoke):
- '''Convert a number of disks to RAID mode and check the return value'''
- device_list = []
- for i in range(0, random.randint(2, 10)):
- device_list += self._random_fqdd()
-
- expected_invocation = 'ConvertToRAID'
- expected_selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
- 'CreationClassName': 'DCIM_RAIDService',
- 'SystemName': 'DCIM:ComputerSystem',
- 'Name': 'DCIM:RAIDService'}
- expected_properties = {'PDArray': device_list}
-
mock_invoke.return_value = lxml.etree.fromstring(
test_utils.RAIDInvocations[uris.DCIM_RAIDService][
- expected_invocation]['ok'])
+ 'ConvertToRAID']['ok'])
result = self.drac_client.convert_physical_disks(
raid_controller='controller',
physical_disks=device_list,
- raid_enable=True)
+ raid_enable=False)
- self.assertEqual({'commit_required': True}, result)
+ self.assertEqual({'is_commit_required': True,
+ 'is_reboot_required': constants.RebootRequired.true},
+ result)
mock_invoke.assert_called_once_with(
mock.ANY, uris.DCIM_RAIDService, expected_invocation,
expected_selectors, expected_properties,
expected_return_value=utils.RET_SUCCESS)
- def test_convert_physical_disks_fail(self, mock_requests):
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_convert_physical_disks_fail(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
mock_requests.post(
'https://1.2.3.4:443/wsman',
text=test_utils.RAIDInvocations[
@@ -294,7 +637,9 @@ def test_create_virtual_disk(self, mock_requests, mock_invoke):
raid_controller='controller', physical_disks=['disk1', 'disk2'],
raid_level='1', size_mb=42)
- self.assertEqual({'commit_required': True}, result)
+ self.assertEqual({'is_commit_required': True,
+ 'is_reboot_required': constants.RebootRequired.true},
+ result)
mock_invoke.assert_called_once_with(
mock.ANY, uris.DCIM_RAIDService, 'CreateVirtualDisk',
expected_selectors, expected_properties,
@@ -324,13 +669,19 @@ def test_create_virtual_disk_with_extra_params(self, mock_requests,
raid_level='1', size_mb=42, disk_name='name', span_length=2,
span_depth=3)
- self.assertEqual({'commit_required': True}, result)
+ self.assertEqual({'is_commit_required': True,
+ 'is_reboot_required': constants.RebootRequired.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.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_create_virtual_disk_fail(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
mock_requests.post(
'https://1.2.3.4:443/wsman',
text=test_utils.RAIDInvocations[
@@ -377,6 +728,24 @@ def test_create_virtual_disk_missing_size(self, mock_requests):
physical_disks=['disk1', 'disk2'], raid_level='1', size_mb=None,
disk_name='name', span_length=2, span_depth=3)
+ # This test is specifically for support of creating a RAID1 on a Dell BOSS
+ # card. It requires that size_mb is set to 0
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_create_virtual_disk_0_size(self, mock_requests, mock_invoke):
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.RAIDInvocations[uris.DCIM_RAIDService][
+ 'CreateVirtualDisk']['ok'])
+
+ self.drac_client.create_virtual_disk(
+ raid_controller='controller',
+ physical_disks=['disk1', 'disk2'],
+ raid_level='1',
+ size_mb=0,
+ disk_name='name',
+ span_length=1,
+ span_depth=2)
+
def test_create_virtual_disk_invalid_size(self, mock_requests):
self.assertRaises(
exceptions.InvalidParameterValue,
@@ -412,13 +781,19 @@ def test_delete_virtual_disk(self, mock_requests, mock_invoke):
result = self.drac_client.delete_virtual_disk('disk1')
- self.assertEqual({'commit_required': True}, result)
+ self.assertEqual({'is_commit_required': True,
+ 'is_reboot_required': constants.RebootRequired.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.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_delete_virtual_disk_fail(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
mock_requests.post(
'https://1.2.3.4:443/wsman',
text=test_utils.RAIDInvocations[
@@ -428,31 +803,211 @@ def test_delete_virtual_disk_fail(self, mock_requests):
exceptions.DRACOperationFailed,
self.drac_client.delete_virtual_disk, 'disk1')
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_reset_raid_config(self, mock_requests, mock_invoke):
+ expected_selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'CreationClassName': 'DCIM_RAIDService',
+ 'SystemName': 'DCIM:ComputerSystem',
+ 'Name': 'DCIM:RAIDService'}
+ expected_properties = {'Target': self.raid_controller_fqdd}
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.RAIDInvocations[uris.DCIM_RAIDService][
+ 'ResetConfig']['ok'])
+ result = self.drac_client.reset_raid_config(self.raid_controller_fqdd)
+ self.assertEqual({'is_commit_required': True,
+ 'is_reboot_required':
+ constants.RebootRequired.optional},
+ result)
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_RAIDService, 'ResetConfig',
+ expected_selectors, expected_properties,
+ expected_return_value=utils.RET_SUCCESS)
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_reset_raid_config_fail(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.RAIDInvocations[
+ uris.DCIM_RAIDService]['ResetConfig']['error'])
+
+ self.assertRaises(
+ exceptions.DRACOperationFailed,
+ self.drac_client.reset_raid_config, self.raid_controller_fqdd)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_clear_foreign_config(self, mock_requests, mock_invoke):
+ expected_selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'CreationClassName': 'DCIM_RAIDService',
+ 'SystemName': 'DCIM:ComputerSystem',
+ 'Name': 'DCIM:RAIDService'}
+ expected_properties = {'Target': self.raid_controller_fqdd}
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.RAIDInvocations[uris.DCIM_RAIDService][
+ 'ClearForeignConfig']['ok'])
+
+ result = self.drac_client.clear_foreign_config(
+ self.raid_controller_fqdd)
+ self.assertEqual({'is_commit_required': True,
+ 'is_reboot_required':
+ constants.RebootRequired.optional},
+ result)
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_RAIDService, 'ClearForeignConfig',
+ expected_selectors, expected_properties,
+ check_return_value=False)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_clear_foreign_config_with_no_foreign_drive(self,
+ mock_requests,
+ mock_invoke):
+ expected_selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'CreationClassName': 'DCIM_RAIDService',
+ 'SystemName': 'DCIM:ComputerSystem',
+ 'Name': 'DCIM:RAIDService'}
+ expected_properties = {'Target': self.raid_controller_fqdd}
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.RAIDInvocations[uris.DCIM_RAIDService][
+ 'ClearForeignConfig']['no_foreign_drive'])
+
+ result = self.drac_client.clear_foreign_config(
+ self.raid_controller_fqdd)
+ self.assertEqual({'is_commit_required': False,
+ 'is_reboot_required':
+ constants.RebootRequired.false},
+ result)
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_RAIDService, 'ClearForeignConfig',
+ expected_selectors, expected_properties,
+ check_return_value=False)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_clear_foreign_config_with_operation_not_supported(self,
+ mock_requests,
+ mock_invoke):
+ expected_selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'CreationClassName': 'DCIM_RAIDService',
+ 'SystemName': 'DCIM:ComputerSystem',
+ 'Name': 'DCIM:RAIDService'}
+ expected_properties = {'Target': self.boss_controller_fqdd}
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.RAIDInvocations[uris.DCIM_RAIDService][
+ 'ClearForeignConfig']['foreign_drive_operation_not_supported'])
+
+ result = self.drac_client.clear_foreign_config(
+ self.boss_controller_fqdd)
+ self.assertEqual({'is_commit_required': False,
+ 'is_reboot_required':
+ constants.RebootRequired.false},
+ result)
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_RAIDService, 'ClearForeignConfig',
+ expected_selectors, expected_properties,
+ check_return_value=False)
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_clear_foreign_config_with_invalid_controller_id(
+ self,
+ mock_requests,
+ mock_wait_until_idrac_is_ready):
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.RAIDInvocations[
+ uris.DCIM_RAIDService]['ClearForeignConfig']
+ ['invalid_controller_id'])
+
+ self.assertRaises(
+ exceptions.DRACOperationFailed,
+ self.drac_client.clear_foreign_config, 'bad')
+
@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')
+ self.drac_client.commit_pending_raid_changes('controller',
+ realtime=False)
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)
+ cim_name='DCIM:RAIDService', target='controller', reboot=False,
+ start_time='TIME_NOW', realtime=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)
+ self.drac_client.commit_pending_raid_changes('controller',
+ reboot=True,
+ realtime=False)
+
+ 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,
+ start_time='TIME_NOW', realtime=False)
+
+ @mock.patch.object(dracclient.resources.job.JobManagement,
+ 'create_config_job', spec_set=True, autospec=True)
+ def test_commit_pending_raid_changes_with_start_time(
+ self, mock_requests,
+ mock_create_config_job):
+ timestamp = '20140924140201'
+ self.drac_client.commit_pending_raid_changes('controller',
+ start_time=timestamp,
+ realtime=False)
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)
+ cim_name='DCIM:RAIDService', target='controller', reboot=False,
+ start_time=timestamp, realtime=False)
+
+ @mock.patch.object(dracclient.resources.job.JobManagement,
+ 'create_config_job', spec_set=True, autospec=True)
+ def test_commit_pending_raid_changes_with_reboot_and_start_time(
+ self, mock_requests,
+ mock_create_config_job):
+ timestamp = '20140924140201'
+ self.drac_client.commit_pending_raid_changes('controller',
+ reboot=True,
+ start_time=timestamp,
+ realtime=False)
+
+ 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,
+ start_time=timestamp, realtime=False)
+
+ @mock.patch.object(dracclient.resources.job.JobManagement,
+ 'create_config_job', spec_set=True, autospec=True)
+ def test_commit_pending_raid_changes_with_realtime(
+ self, mock_requests,
+ mock_create_config_job):
+ timestamp = '20140924140201'
+ self.drac_client.commit_pending_raid_changes('controller',
+ reboot=False,
+ start_time=timestamp,
+ realtime=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=False,
+ start_time=timestamp, realtime=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,
+ def test_abandon_pending_raid_changes(self, mock_requests,
mock_delete_pending_config):
self.drac_client.abandon_pending_raid_changes('controller')
@@ -460,3 +1015,552 @@ def test_abandon_pending_bios_changes(self, mock_requests,
mock.ANY, resource_uri=uris.DCIM_RAIDService,
cim_creation_class_name='DCIM_RAIDService',
cim_name='DCIM:RAIDService', target='controller')
+
+ @mock.patch.object(dracclient.resources.job.JobManagement,
+ 'delete_pending_config', spec_set=True, autospec=True)
+ def test_abandon_pending_raid_changes_realtime(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')
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ @mock.patch.object(dracclient.resources.raid.RAIDManagement,
+ 'convert_physical_disks',
+ return_value={}, spec_set=True,
+ autospec=True)
+ def test_raid_controller_jbod_capable(self, mock_requests,
+ mock_wait_until_idrac_is_ready,
+ mock_convert_physical_disks):
+
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.RAIDEnumerations[uris.DCIM_PhysicalDiskView]['ok'])
+
+ is_jbod = self.drac_client.is_jbod_capable(self.raid_controller_fqdd)
+
+ self.assertTrue(is_jbod, msg="is_jbod is true")
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ @mock.patch.object(dracclient.resources.raid.RAIDManagement,
+ 'convert_physical_disks',
+ return_value={}, spec_set=True,
+ autospec=True)
+ def test_raid_controller_jbod_non_raid(self, mock_requests,
+ mock_wait_until_idrac_is_ready,
+ mock_convert_physical_disks):
+
+ pdv = test_utils.RAIDEnumerations[uris.DCIM_PhysicalDiskView]['ok']
+ # change to non-RAID value
+ pdv = pdv.replace("1",
+ "8")
+
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=pdv)
+
+ is_jbod = self.drac_client.is_jbod_capable(self.raid_controller_fqdd)
+
+ self.assertTrue(is_jbod, msg="is_jbod is true")
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ @mock.patch.object(dracclient.resources.raid.RAIDManagement,
+ 'convert_physical_disks',
+ return_value={}, spec_set=True,
+ autospec=True)
+ def test_raid_controller_jbod_unknown(self, mock_requests,
+ mock_wait_until_idrac_is_ready,
+ mock_convert_physical_disks):
+
+ is_jbod = False
+ pdv = test_utils.RAIDEnumerations[uris.DCIM_PhysicalDiskView]['ok']
+ # change to non-RAID value
+ pdv = pdv.replace("1",
+ "0")
+
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=pdv)
+ self.assertRaises(exceptions.DRACRequestFailed,
+ self.drac_client.is_jbod_capable,
+ self.raid_controller_fqdd)
+ self.assertFalse(is_jbod, msg="is_jbod is false")
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ @mock.patch.object(dracclient.resources.raid.RAIDManagement,
+ 'convert_physical_disks',
+ spec_set=True,
+ autospec=True)
+ def test_raid_controller_jbod_not_supported(self,
+ mock_requests,
+ mock_convert_physical_disks,
+ mock_wait_idrac_is_ready):
+
+ msg = " operation is not supported on th"
+ exc = exceptions.DRACOperationFailed(drac_messages=msg)
+ mock_convert_physical_disks.side_effect = exc
+
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.RAIDEnumerations[uris.DCIM_PhysicalDiskView]['ok'])
+
+ is_jbod = self.drac_client.is_jbod_capable(self.raid_controller_fqdd)
+ self.assertFalse(is_jbod, msg="is_jbod is false")
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ @mock.patch.object(dracclient.resources.raid.RAIDManagement,
+ 'convert_physical_disks',
+ spec_set=True,
+ autospec=True)
+ def test_raid_controller_jbod_ex_no_match(self,
+ mock_requests,
+ mock_convert_physical_disks,
+ mock_wait_until_idrac_is_ready):
+
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.RAIDEnumerations[uris.DCIM_PhysicalDiskView]['ok'])
+ msg = "NON_MATCHING_MESSAGE"
+ exc = exceptions.DRACOperationFailed(drac_messages=msg)
+ mock_convert_physical_disks.side_effect = exc
+
+ self.assertRaises(
+ exceptions.DRACOperationFailed,
+ self.drac_client.is_jbod_capable, self.raid_controller_fqdd)
+
+ def test_is_raid_controller_raid(self, mock_requests):
+ self.assertTrue(self.drac_client
+ .is_raid_controller("RAID.Integrated.1-1"))
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_is_raid_controller_boss(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.RAIDEnumerations[uris.DCIM_ControllerView]['ok'])
+ self.assertTrue(self.drac_client
+ .is_raid_controller("AHCI.Integrated.1-1"))
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_is_raid_controller_fail(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.RAIDEnumerations[uris.DCIM_ControllerView]['ok'])
+ self.assertFalse(self.drac_client
+ .is_raid_controller("notRAID.Integrated.1-1"))
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_is_boss_controller(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.RAIDEnumerations[uris.DCIM_ControllerView]['ok'])
+ self.assertTrue(self.drac_client
+ .is_boss_controller("AHCI.Integrated.1-1"))
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_is_not_boss_controller(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.RAIDEnumerations[uris.DCIM_ControllerView]['ok'])
+ self.assertFalse(self.drac_client
+ .is_boss_controller("notAHCI.Integrated.1-1"),
+ None)
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_is_boss_controller_with_cntl_list(self, mock_requests,
+ mock_wait_until_idrac_is_ready):
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.RAIDEnumerations[uris.DCIM_ControllerView]['ok'])
+ controllers = self.drac_client.list_raid_controllers()
+ self.assertTrue(self.drac_client
+ .is_boss_controller("AHCI.Integrated.1-1",
+ controllers))
+
+ def test_check_disks_status_no_controllers(self, mock_requests):
+ physical_disks = [self.disk_1, self.disk_2, self.disk_3, self.disk_4]
+ raid_mgt = self.drac_client._raid_mgmt
+
+ cont_to_phys_disk_ids = collections.defaultdict(list)
+ mode = constants.RaidStatus.jbod
+
+ raid_mgt._check_disks_status(mode, physical_disks,
+ cont_to_phys_disk_ids)
+ jbod_len = len(cont_to_phys_disk_ids['RAID.Integrated.1-1'])
+ self.assertEqual(jbod_len, 0)
+
+ # Switch mode to RAID and try again
+ cont_to_phys_disk_ids = collections.defaultdict(list)
+ mode = constants.RaidStatus.raid
+ raid_mgt._check_disks_status(mode, physical_disks,
+ cont_to_phys_disk_ids)
+ raid_len = len(cont_to_phys_disk_ids['RAID.Integrated.1-1'])
+ self.assertEqual(raid_len, 0)
+
+ def test_check_disks_status_bad(self, mock_requests):
+ mode = constants.RaidStatus.raid
+ disk_2 = self.disk_2._replace(raid_status='FAKE_STATUS')
+ physical_disks = [self.disk_1, disk_2, self.disk_3, self.disk_4]
+ raid_mgt = self.drac_client._raid_mgmt
+
+ self.assertRaises(ValueError,
+ raid_mgt._check_disks_status,
+ mode,
+ physical_disks,
+ self.controllers_to_physical_disk_ids)
+ mode = constants.RaidStatus.jbod
+ self.assertRaises(ValueError,
+ raid_mgt._check_disks_status,
+ mode,
+ physical_disks,
+ self.controllers_to_physical_disk_ids)
+
+ def test_check_disks_status_fail(self, mock_requests):
+ mode = constants.RaidStatus.raid
+ disk_2_failed = self.disk_2._replace(raid_status='failed')
+ physical_disks = [self.disk_1, disk_2_failed, self.disk_3, self.disk_4]
+ raid_mgt = self.drac_client._raid_mgmt
+
+ self.assertRaises(ValueError,
+ raid_mgt._check_disks_status,
+ mode,
+ physical_disks,
+ self.controllers_to_physical_disk_ids)
+ mode = constants.RaidStatus.jbod
+ self.assertRaises(ValueError,
+ raid_mgt._check_disks_status,
+ mode,
+ physical_disks,
+ self.controllers_to_physical_disk_ids)
+
+ def test_check_disks_status_no_change(self, mock_requests):
+ raid_mgt = self.drac_client._raid_mgmt
+ mode = constants.RaidStatus.raid
+ physical_disks = [self.disk_1, self.disk_2,
+ self.disk_3, self.disk_4]
+
+ raid_cntl_to_phys_disk_ids = raid_mgt._check_disks_status(
+ mode, physical_disks, self.controllers_to_physical_disk_ids)
+ raid_len = len(raid_cntl_to_phys_disk_ids['RAID.Integrated.1-1'])
+ self.assertEqual(raid_len, 0)
+
+ mode = constants.RaidStatus.jbod
+ disk_1_non_raid = self.disk_1._replace(raid_status='non-RAID')
+ disk_2_non_raid = self.disk_2._replace(raid_status='non-RAID')
+ physical_disks = [disk_1_non_raid, disk_2_non_raid,
+ self.disk_3, self.disk_4]
+
+ jbod_cntl_to_phys_disk_ids = raid_mgt._check_disks_status(
+ mode, physical_disks, self.controllers_to_physical_disk_ids)
+ jbod_len = len(jbod_cntl_to_phys_disk_ids['RAID.Integrated.1-1'])
+ self.assertEqual(jbod_len, 0)
+
+ def test_check_disks_status_change_state(self, mock_requests):
+ raid_mgt = self.drac_client._raid_mgmt
+ mode = constants.RaidStatus.jbod
+ physical_disks = [self.disk_1, self.disk_2, self.disk_3, self.disk_4]
+
+ jbod_cntl_to_phys_disk_ids = raid_mgt._check_disks_status(
+ mode, physical_disks, self.controllers_to_physical_disk_ids)
+ jbod_len = len(jbod_cntl_to_phys_disk_ids['RAID.Integrated.1-1'])
+ self.assertEqual(jbod_len, 2)
+
+ mode = constants.RaidStatus.raid
+ disk_1_non_raid = self.disk_1._replace(raid_status='non-RAID')
+ disk_2_non_raid = self.disk_2._replace(raid_status='non-RAID')
+ physical_disks = [disk_1_non_raid, disk_2_non_raid,
+ self.disk_3, self.disk_4]
+ raid_cntl_to_phys_disk_ids = raid_mgt._check_disks_status(
+ mode, physical_disks, self.controllers_to_physical_disk_ids)
+ raid_len = len(raid_cntl_to_phys_disk_ids['RAID.Integrated.1-1'])
+ self.assertEqual(raid_len, 2)
+
+ def test_check_disks_status_bad_and_fail(self, mock_requests):
+ mode = constants.RaidStatus.raid
+ disk_1_bad = self.disk_1._replace(raid_status='FAKE_STATUS')
+ disk_2_failed = self.disk_2._replace(raid_status='failed')
+ physical_disks = [disk_1_bad, disk_2_failed, self.disk_3, self.disk_4]
+ raid_mgt = self.drac_client._raid_mgmt
+
+ self.assertRaises(ValueError,
+ raid_mgt._check_disks_status,
+ mode,
+ physical_disks,
+ self.controllers_to_physical_disk_ids)
+ mode = constants.RaidStatus.jbod
+ self.assertRaises(ValueError,
+ raid_mgt._check_disks_status,
+ mode,
+ physical_disks,
+ self.controllers_to_physical_disk_ids)
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ @mock.patch.object(dracclient.resources.raid.RAIDManagement,
+ 'convert_physical_disks', spec_set=True,
+ autospec=True)
+ def test_change_physical_disk_state_jbod(
+ self, mock_requests,
+ mock_convert_physical_disks,
+ wait_until_idrac_is_ready):
+ mode = constants.RaidStatus.jbod
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.RAIDEnumerations[uris.DCIM_PhysicalDiskView]['ok'])
+ cvt_phys_disks_return_value = {'is_commit_required': True,
+ 'is_reboot_required': constants.
+ RebootRequired.true}
+ mock_convert_physical_disks.return_value = cvt_phys_disks_return_value
+
+ expected_return_value = {'RAID.Integrated.1-1':
+ cvt_phys_disks_return_value,
+ 'AHCI.Integrated.1-1':
+ cvt_phys_disks_return_value}
+ results = self.drac_client.change_physical_disk_state(
+ mode, self.controllers_to_physical_disk_ids)
+ self.assertEqual(results['conversion_results'],
+ expected_return_value)
+
+ @mock.patch.object(dracclient.resources.raid.RAIDManagement,
+ 'list_physical_disks', spec_set=True,
+ autospec=True)
+ @mock.patch.object(dracclient.resources.raid.RAIDManagement,
+ 'convert_physical_disks', spec_set=True,
+ autospec=True)
+ def test_change_physical_disk_state_raid(
+ self, mock_requests,
+ mock_convert_physical_disks,
+ mock_list_physical_disks):
+ mode = constants.RaidStatus.raid
+ disk_1_non_raid = self.disk_1._replace(raid_status='non-RAID')
+ disk_2_non_raid = self.disk_2._replace(raid_status='non-RAID')
+ physical_disks = [disk_1_non_raid, disk_2_non_raid,
+ self.disk_3, self.disk_4]
+ mock_list_physical_disks.return_value = physical_disks
+ boss_return_value = {'is_commit_required': False,
+ 'is_reboot_required':
+ constants.RebootRequired.false}
+ raid_return_value = {'is_commit_required': True,
+ 'is_reboot_required':
+ constants.RebootRequired.true}
+ mock_convert_physical_disks.return_value = raid_return_value
+
+ results = self.drac_client.change_physical_disk_state(
+ mode, self.controllers_to_physical_disk_ids)
+ self.assertEqual(len(results['conversion_results']), 2)
+ self.assertEqual(results['conversion_results']['AHCI.Integrated.1-1'],
+ boss_return_value)
+ self.assertEqual(results['conversion_results']['RAID.Integrated.1-1'],
+ raid_return_value)
+
+ @mock.patch.object(dracclient.resources.raid.RAIDManagement,
+ 'list_physical_disks', spec_set=True,
+ autospec=True)
+ def test_change_physical_disk_state_none(
+ self, mock_requests,
+ mock_list_physical_disks):
+ mode = constants.RaidStatus.raid
+ physical_disks = [self.disk_1, self.disk_2, self.disk_3, self.disk_4]
+ mock_list_physical_disks.return_value = physical_disks
+ expected_return_value = {'is_commit_required': False,
+ 'is_reboot_required':
+ constants.RebootRequired.false}
+ results = self.drac_client.change_physical_disk_state(
+ mode, self.controllers_to_physical_disk_ids)
+ self.assertEqual(results['conversion_results']['RAID.Integrated.1-1'],
+ expected_return_value)
+ self.assertEqual(results['conversion_results']['AHCI.Integrated.1-1'],
+ expected_return_value)
+
+ @mock.patch.object(dracclient.resources.raid.RAIDManagement,
+ 'list_physical_disks', spec_set=True,
+ autospec=True)
+ @mock.patch.object(dracclient.resources.raid.RAIDManagement,
+ 'convert_physical_disks', spec_set=True,
+ autospec=True,
+ side_effect=exceptions.DRACOperationFailed(
+ drac_messages=constants.NOT_SUPPORTED_MSG))
+ def test_change_physical_disk_state_not_supported(
+ self, mock_requests,
+ mock_convert_physical_disks,
+ mock_list_physical_disks):
+ mode = constants.RaidStatus.raid
+ disk_1_non_raid = self.disk_1._replace(raid_status='non-RAID')
+ disk_2_non_raid = self.disk_2._replace(raid_status='non-RAID')
+ physical_disks = [disk_1_non_raid, disk_2_non_raid,
+ self.disk_3, self.disk_4]
+ mock_list_physical_disks.return_value = physical_disks
+ expected_return_value = {'is_commit_required': False,
+ 'is_reboot_required':
+ constants.RebootRequired.false}
+ results = self.drac_client.change_physical_disk_state(
+ mode, self.controllers_to_physical_disk_ids)
+ self.assertEqual(results['conversion_results']['RAID.Integrated.1-1'],
+ expected_return_value)
+ self.assertEqual(results['conversion_results']['AHCI.Integrated.1-1'],
+ expected_return_value)
+
+ @mock.patch.object(dracclient.resources.raid.RAIDManagement,
+ 'list_physical_disks', spec_set=True,
+ autospec=True)
+ @mock.patch.object(dracclient.resources.raid.RAIDManagement,
+ 'convert_physical_disks', spec_set=True,
+ autospec=True,
+ side_effect=exceptions.DRACOperationFailed(
+ drac_messages="OTHER_MESSAGE"))
+ def test_change_physical_disk_state_raise_drac_operation_other(
+ self, mock_requests,
+ mock_convert_physical_disks,
+ mock_list_physical_disks):
+ mode = constants.RaidStatus.raid
+ disk_1_non_raid = self.disk_1._replace(raid_status='non-RAID')
+ disk_2_non_raid = self.disk_2._replace(raid_status='non-RAID')
+ physical_disks = [disk_1_non_raid, disk_2_non_raid,
+ self.disk_3, self.disk_4]
+ mock_list_physical_disks.return_value = physical_disks
+ self.assertRaisesRegexp(
+ exceptions.DRACOperationFailed,
+ "OTHER_MESSAGE",
+ self.drac_client.change_physical_disk_state,
+ mode,
+ self.controllers_to_physical_disk_ids)
+
+ @mock.patch.object(dracclient.resources.raid.RAIDManagement,
+ 'list_physical_disks', spec_set=True,
+ autospec=True)
+ @mock.patch.object(dracclient.resources.raid.RAIDManagement,
+ 'convert_physical_disks', spec_set=True,
+ autospec=True, side_effect=Exception(
+ "SOMETHING_BAD_HAPPENED"))
+ def test_change_physical_disk_state_raise_other(
+ self, mock_requests,
+ mock_convert_physical_disks,
+ mock_list_physical_disks):
+ mode = constants.RaidStatus.raid
+ disk_1_non_raid = self.disk_1._replace(raid_status='non-RAID')
+ disk_2_non_raid = self.disk_2._replace(raid_status='non-RAID')
+ physical_disks = [disk_1_non_raid, disk_2_non_raid,
+ self.disk_3, self.disk_4]
+ mock_list_physical_disks.return_value = physical_disks
+ self.assertRaisesRegexp(
+ Exception,
+ "SOMETHING_BAD_HAPPENED",
+ self.drac_client.change_physical_disk_state,
+ mode,
+ self.controllers_to_physical_disk_ids)
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ @mock.patch.object(dracclient.resources.raid.RAIDManagement,
+ 'list_physical_disks', spec_set=True,
+ autospec=True)
+ @mock.patch.object(dracclient.resources.raid.RAIDManagement,
+ 'convert_physical_disks', spec_set=True,
+ autospec=True)
+ def test_change_physical_disk_state_with_no_dict(
+ self, mock_requests,
+ mock_convert_physical_disks,
+ mock_list_physical_disks,
+ mock_wait_until_idrac_is_ready):
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.RAIDEnumerations[uris.DCIM_ControllerView]['ok'])
+ mode = constants.RaidStatus.jbod
+ physical_disks = [self.disk_1, self.disk_2, self.disk_3, self.disk_4]
+ mock_list_physical_disks.return_value = physical_disks
+ cvt_phys_disks_return_value = {'is_commit_required': True,
+ 'is_reboot_required': constants.
+ RebootRequired.true}
+ mock_convert_physical_disks.return_value = cvt_phys_disks_return_value
+ expected_return_value = {'RAID.Integrated.1-1':
+ cvt_phys_disks_return_value,
+ 'AHCI.Integrated.1-1':
+ cvt_phys_disks_return_value}
+ results = self.drac_client.change_physical_disk_state(mode)
+ self.assertDictEqual(results['conversion_results'],
+ expected_return_value)
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ @mock.patch.object(dracclient.resources.raid.RAIDManagement,
+ 'list_physical_disks', spec_set=True,
+ autospec=True)
+ def test_change_physical_disk_state_with_no_raid_or_boss_card_match(
+ self, mock_requests,
+ mock_list_physical_disks,
+ mock_wait_until_idrac_is_ready):
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.RAIDEnumerations[uris.DCIM_ControllerView]['ok'])
+ mode = constants.RaidStatus.jbod
+ _disk_1 = self.disk_1._replace(controller='NOT_RAID.Integrated.1-1')
+ _disk_2 = self.disk_2._replace(controller='NOT_RAID.Integrated.1-1')
+ _disk_3 = self.disk_3._replace(controller='NOT_AHCI.Integrated.1-1')
+ _disk_4 = self.disk_4._replace(controller='NOT_AHCI.Integrated.1-1')
+ physical_disks = [_disk_1, _disk_2, _disk_3, _disk_4]
+ mock_list_physical_disks.return_value = physical_disks
+ results = self.drac_client.change_physical_disk_state(mode)
+ self.assertDictEqual(results['conversion_results'], {})
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_is_realtime_supported_with_realtime_controller(
+ self,
+ mock_requests,
+ mock_wait_until_idrac_is_ready):
+ expected_raid_controller = 'RAID.Integrated.1-1'
+
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.RAIDEnumerations[uris.DCIM_ControllerView]['ok'])
+
+ self.assertTrue(
+ self.drac_client.is_realtime_supported(
+ expected_raid_controller))
+
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_is_realtime_supported_with_non_realtime_controller(
+ self,
+ mock_requests,
+ mock_wait_until_idrac_is_ready):
+ expected_raid_controller = 'AHCI.Integrated.1-1'
+
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.RAIDEnumerations[uris.DCIM_ControllerView]['ok'])
+
+ self.assertFalse(
+ self.drac_client.is_realtime_supported(
+ expected_raid_controller))
diff --git a/dracclient/tests/test_system.py b/dracclient/tests/test_system.py
new file mode 100644
index 0000000..54c9d9b
--- /dev/null
+++ b/dracclient/tests/test_system.py
@@ -0,0 +1,92 @@
+#
+# 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.
+
+from unittest import mock
+
+import requests_mock
+
+import dracclient.client
+from dracclient.resources import system
+from dracclient.resources import uris
+from dracclient.tests import base
+from dracclient.tests import utils as test_utils
+
+
+class ClientSystemConfigurationTestCase(base.BaseTest):
+
+ def setUp(self):
+ super(ClientSystemConfigurationTestCase, self).setUp()
+ self.drac_client = dracclient.client.DRACClient(
+ **test_utils.FAKE_ENDPOINT)
+
+ @requests_mock.Mocker()
+ @mock.patch.object(dracclient.client.WSManClient,
+ 'wait_until_idrac_is_ready', spec_set=True,
+ autospec=True)
+ def test_list_system_settings(
+ self, mock_requests, mock_wait_until_idrac_is_ready):
+ expected_enum_attr = system.SystemEnumerableAttribute(
+ name='ChassisLEDState',
+ instance_id='System.Embedded.1#ChassisPwrState.1#ChassisLEDState', # noqa
+ read_only=False,
+ current_value='Off',
+ pending_value=None,
+ fqdd='System.Embedded.1',
+ group_id='ChassisPwrState.1',
+ possible_values=['Unknown', 'Blinking', 'Off'])
+ expected_string_attr = system.SystemStringAttribute(
+ name='UserDefinedString',
+ instance_id='System.Embedded.1#LCD.1#UserDefinedString',
+ read_only=False,
+ current_value=None,
+ pending_value=None,
+ fqdd='System.Embedded.1',
+ group_id='LCD.1',
+ min_length=0,
+ max_length=62)
+ expected_integer_attr = system.SystemIntegerAttribute(
+ name='PowerCapValue',
+ instance_id='System.Embedded.1#ServerPwr.1#PowerCapValue',
+ read_only=False,
+ current_value=555,
+ pending_value=None,
+ fqdd='System.Embedded.1',
+ group_id='ServerPwr.1',
+ lower_bound=302,
+ upper_bound=578)
+
+ mock_requests.post('https://1.2.3.4:443/wsman', [
+ {'text': test_utils.SystemEnumerations[
+ uris.DCIM_SystemEnumeration]['ok']},
+ {'text': test_utils.SystemEnumerations[
+ uris.DCIM_SystemString]['ok']},
+ {'text': test_utils.SystemEnumerations[
+ uris.DCIM_SystemInteger]['ok']}])
+
+ system_settings = self.drac_client.list_system_settings()
+
+ self.assertEqual(44, len(system_settings))
+ # enumerable attribute
+ self.assertIn('System.Embedded.1#ChassisPwrState.1#ChassisLEDState',
+ system_settings)
+ self.assertEqual(expected_enum_attr, system_settings[
+ 'System.Embedded.1#ChassisPwrState.1#ChassisLEDState']) # noqa
+ # string attribute
+ self.assertIn('System.Embedded.1#LCD.1#UserDefinedString',
+ system_settings)
+ self.assertEqual(expected_string_attr, system_settings[
+ 'System.Embedded.1#LCD.1#UserDefinedString'])
+ self.assertIn('System.Embedded.1#ServerPwr.1#PowerCapValue',
+ system_settings)
+ self.assertEqual(expected_integer_attr,
+ system_settings['System.Embedded.1#ServerPwr.1#PowerCapValue']) # noqa
diff --git a/dracclient/tests/test_utils.py b/dracclient/tests/test_utils.py
index e99db8b..171d551 100644
--- a/dracclient/tests/test_utils.py
+++ b/dracclient/tests/test_utils.py
@@ -27,6 +27,28 @@ class UtilsTestCase(base.BaseTest):
def setUp(self):
super(UtilsTestCase, self).setUp()
+ def test__is_attr_non_nil_True(self):
+ doc = etree.fromstring(
+ test_utils.RAIDEnumerations[
+ uris.DCIM_ControllerView]['ok'])
+ controllers = utils.find_xml(doc, 'DCIM_ControllerView',
+ uris.DCIM_ControllerView, find_all=True)
+ version = utils.find_xml(controllers[0], 'Bus',
+ uris.DCIM_ControllerView)
+
+ self.assertTrue(utils._is_attr_non_nil(version))
+
+ def test__is_attr_non_nil_False(self):
+ doc = etree.fromstring(
+ test_utils.RAIDEnumerations[
+ uris.DCIM_ControllerView]['ok'])
+ controllers = utils.find_xml(doc, 'DCIM_ControllerView',
+ uris.DCIM_ControllerView, find_all=True)
+ version = utils.find_xml(controllers[0], 'DriverVersion',
+ uris.DCIM_ControllerView)
+
+ self.assertFalse(utils._is_attr_non_nil(version))
+
def test_get_wsman_resource_attr(self):
doc = etree.fromstring(
test_utils.InventoryEnumerations[uris.DCIM_CPUView]['ok'])
@@ -79,3 +101,75 @@ def test_get_wsman_resource_attr_missing_text(self):
exceptions.DRACEmptyResponseField, re.escape(expected_message),
utils.get_wsman_resource_attr, cpus[0], uris.DCIM_CPUView,
'HyperThreadingEnabled', allow_missing=False)
+
+ def test_get_wsman_resource_attr_missing_text_allowed(self):
+ doc = etree.fromstring(
+ test_utils.RAIDEnumerations[
+ uris.DCIM_ControllerView]['ok'])
+ controllers = utils.find_xml(doc, 'DCIM_ControllerView',
+ uris.DCIM_ControllerView, find_all=True)
+
+ result = utils.get_wsman_resource_attr(
+ controllers[0], uris.DCIM_ControllerView, 'DriverVersion',
+ allow_missing=False, nullable=True)
+ self.assertIsNone(result)
+
+ def test_get_all_wsman_resource_attrs(self):
+ doc = etree.fromstring(
+ test_utils.RAIDEnumerations[uris.DCIM_VirtualDiskView]['ok'])
+ vdisks = utils.find_xml(doc, 'DCIM_VirtualDiskView',
+ uris.DCIM_VirtualDiskView, find_all=True)
+
+ vals = utils.get_all_wsman_resource_attrs(
+ vdisks[0], uris.DCIM_VirtualDiskView, 'PhysicalDiskIDs')
+
+ expected_pdisks = [
+ 'Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1',
+ 'Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1'
+ ]
+ self.assertListEqual(expected_pdisks, vals)
+
+ def test_get_all_wsman_resource_attrs_missing_attr_allowed(self):
+ doc = etree.fromstring(
+ test_utils.InventoryEnumerations[
+ uris.DCIM_CPUView]['missing_flags'])
+ cpus = utils.find_xml(doc, 'DCIM_CPUView', uris.DCIM_CPUView,
+ find_all=True)
+
+ vals = utils.get_all_wsman_resource_attrs(
+ cpus[0], uris.DCIM_CPUView, 'HyperThreadingEnabled')
+
+ self.assertListEqual([], vals)
+
+ def test_get_all_wsman_resource_attrs_missing_text(self):
+ expected_message = ("Attribute 'HyperThreadingEnabled' is not nullable"
+ ", but no value received")
+ doc = etree.fromstring(
+ test_utils.InventoryEnumerations[
+ uris.DCIM_CPUView]['empty_flag'])
+ cpus = utils.find_xml(doc, 'DCIM_CPUView', uris.DCIM_CPUView,
+ find_all=True)
+
+ self.assertRaisesRegexp(
+ exceptions.DRACEmptyResponseField, re.escape(expected_message),
+ utils.get_all_wsman_resource_attrs, cpus[0], uris.DCIM_CPUView,
+ 'HyperThreadingEnabled')
+
+ def test_get_all_wsman_resource_attrs_missing_text_allowed(self):
+ doc = etree.fromstring(
+ test_utils.RAIDEnumerations[
+ uris.DCIM_ControllerView]['ok'])
+ controllers = utils.find_xml(doc, 'DCIM_ControllerView',
+ uris.DCIM_ControllerView, find_all=True)
+
+ result = utils.get_all_wsman_resource_attrs(
+ controllers[0], uris.DCIM_ControllerView, 'DriverVersion',
+ nullable=True)
+ self.assertEqual(result, [])
+
+ def test_build_return_dict_fail(self):
+ self.assertRaises(exceptions.InvalidParameterValue,
+ utils.build_return_dict,
+ doc=None,
+ resource_uri=None,
+ is_reboot_required_value='foo')
diff --git a/dracclient/tests/test_wsman.py b/dracclient/tests/test_wsman.py
index 09f7701..c0d6ea5 100644
--- a/dracclient/tests/test_wsman.py
+++ b/dracclient/tests/test_wsman.py
@@ -12,12 +12,14 @@
# under the License.
import collections
+from unittest import mock
import uuid
import lxml.etree
import lxml.objectify
-import mock
+import requests.exceptions
import requests_mock
+import six
from dracclient import exceptions
from dracclient.tests import base
@@ -54,6 +56,14 @@ def test_enumerate_with_invalid_status_code(self, mock_requests):
self.assertRaises(exceptions.WSManInvalidResponse,
self.client.enumerate, 'resource')
+ @requests_mock.Mocker()
+ def test_enumerate_with_invalid_utf8(self, mock_requests):
+ mock_requests.post('https://1.2.3.4:443/wsman',
+ content=six.b('yay!\xC0'))
+
+ resp = self.client.enumerate('resource')
+ self.assertEqual('yay!', resp.text)
+
@requests_mock.Mocker()
def test_enumerate_with_auto_pull(self, mock_requests):
mock_requests.post(
@@ -68,7 +78,7 @@ def test_enumerate_with_auto_pull(self, mock_requests):
foo_resource_uri = 'http://FooResource'
bar_resource_uri = 'http://BarResource'
self.assertEqual(
- 3, len(resp_xml.findall('.//{%s}FooResource' % foo_resource_uri)))
+ 4, len(resp_xml.findall('.//{%s}FooResource' % foo_resource_uri)))
self.assertEqual(
1, len(resp_xml.findall('.//{%s}BazResource' % bar_resource_uri)))
self.assertEqual(
@@ -108,6 +118,74 @@ def test_invoke(self, mock_requests):
self.assertEqual('yay!', resp.text)
+ @requests_mock.Mocker()
+ def test_invoke_with_ssl_errors(self, mock_requests):
+ mock_requests.post('https://1.2.3.4:443/wsman',
+ exc=requests.exceptions.SSLError)
+
+ self.assertRaises(exceptions.WSManRequestFailure,
+ self.client.invoke, 'http://resource', 'method',
+ {'selector': 'foo'}, {'property': 'bar'})
+
+ @requests_mock.Mocker()
+ def test_invoke_with_ssl_error_success(self, mock_requests):
+ expected_resp = 'yay!'
+ mock_requests.post('https://1.2.3.4:443/wsman',
+ [{'exc': requests.exceptions.SSLError},
+ {'text': expected_resp}])
+
+ resp = self.client.invoke('http://resource', 'method',
+ {'selector': 'foo'}, {'property': 'bar'})
+
+ self.assertEqual('yay!', resp.text)
+
+ @requests_mock.Mocker()
+ def test_invoke_with_connection_errors(self, mock_requests):
+ mock_requests.post('https://1.2.3.4:443/wsman',
+ exc=requests.exceptions.ConnectionError)
+
+ self.assertRaises(exceptions.WSManRequestFailure,
+ self.client.invoke, 'http://resource', 'method',
+ {'selector': 'foo'}, {'property': 'bar'})
+
+ @requests_mock.Mocker()
+ def test_invoke_with_connection_error_success(self, mock_requests):
+ expected_resp = 'yay!'
+ mock_requests.post('https://1.2.3.4:443/wsman',
+ [{'exc': requests.exceptions.ConnectionError},
+ {'text': expected_resp}])
+
+ resp = self.client.invoke('http://resource', 'method',
+ {'selector': 'foo'}, {'property': 'bar'})
+
+ self.assertEqual('yay!', resp.text)
+
+ @requests_mock.Mocker()
+ def test_invoke_with_unknown_error(self, mock_requests):
+ mock_requests.post('https://1.2.3.4:443/wsman',
+ exc=requests.exceptions.HTTPError)
+ self.assertRaises(exceptions.WSManRequestFailure,
+ self.client.invoke, 'http://resource', 'method',
+ {'selector': 'foo'}, {'property': 'bar'})
+
+ @requests_mock.Mocker()
+ @mock.patch('time.sleep', autospec=True)
+ def test_client_retry_delay(self, mock_requests, mock_ts):
+ ssl_retry_delay = 5
+ fake_endpoint = test_utils.FAKE_ENDPOINT.copy()
+ fake_endpoint['ssl_retry_delay'] = ssl_retry_delay
+ client = dracclient.wsman.Client(**fake_endpoint)
+ expected_resp = 'yay!'
+ mock_requests.post('https://1.2.3.4:443/wsman',
+ [{'exc': requests.exceptions.SSLError},
+ {'text': expected_resp}])
+
+ resp = client.invoke('http://resource', 'method',
+ {'selector': 'foo'}, {'property': 'bar'})
+
+ self.assertEqual('yay!', resp.text)
+ mock_ts.assert_called_once_with(ssl_retry_delay)
+
class PayloadTestCase(base.BaseTest):
diff --git a/dracclient/tests/utils.py b/dracclient/tests/utils.py
index 1adcf8f..4e4ee11 100644
--- a/dracclient/tests/utils.py
+++ b/dracclient/tests/utils.py
@@ -29,11 +29,12 @@ def load_wsman_xml(name):
"""Helper function to load a WSMan XML response from a file."""
with open(os.path.join(os.path.dirname(__file__), 'wsman_mocks',
- '%s.xml' % name), 'r') as f:
+ '%s.xml' % name), 'r') as f:
xml_body = f.read()
return xml_body
+
WSManEnumerations = {
'context': [
load_wsman_xml('wsman-enum_context-1'),
@@ -132,6 +133,53 @@ def load_wsman_xml(name):
'error': load_wsman_xml(
'bios_service-invoke-delete_pending_configuration-error'),
},
+ },
+ uris.DCIM_LCService: {
+ 'CreateConfigJob': {
+ 'ok': load_wsman_xml(
+ 'lc_service-invoke-create_config_job-ok'),
+ 'error': load_wsman_xml(
+ 'lc_service-invoke-create_config_job-error'),
+ },
+ }
+}
+
+JobService = {
+ uris.DCIM_JobService: {
+ 'DeleteJobQueue': {
+ 'ok': load_wsman_xml(
+ 'job_service-delete-job-id-ok'),
+ 'error': load_wsman_xml(
+ 'job_service-delete-job-id-error'),
+ }
+ }
+}
+
+iDracCardEnumerations = {
+ uris.DCIM_iDRACCardEnumeration: {
+ 'ok': load_wsman_xml('idraccard_enumeration-enum-ok')
+ },
+ uris.DCIM_iDRACCardString: {
+ 'ok': load_wsman_xml('idraccard_string-enum-ok')
+ },
+ uris.DCIM_iDRACCardInteger: {
+ 'ok': load_wsman_xml('idraccard_integer-enum-ok')
+ },
+}
+
+iDracCardInvocations = {
+ uris.DCIM_iDRACCardService: {
+ 'SetAttributes': {
+ 'ok': load_wsman_xml(
+ 'idrac_service-invoke-set_attributes-ok')
+ },
+ 'iDRACReset': {
+ 'ok': load_wsman_xml(
+ 'idrac_service-reset-ok'),
+ 'error': load_wsman_xml(
+ 'idrac_service-reset-error')
+ }
+
}
}
@@ -139,6 +187,55 @@ def load_wsman_xml(name):
uris.DCIM_SystemView: {
'ok': load_wsman_xml('system_view-enum-ok')
},
+ uris.DCIM_LCEnumeration: {
+ 'ok': load_wsman_xml('lc_enumeration-enum-ok')
+ },
+ uris.DCIM_LCString: {
+ 'ok': load_wsman_xml('lc_string-enum-ok')
+ }
+}
+
+LifecycleControllerInvocations = {
+ uris.DCIM_LCService: {
+ 'GetRemoteServicesAPIStatus': {
+ 'is_ready': load_wsman_xml('lc_getremoteservicesapistatus_ready'),
+ 'is_not_ready': load_wsman_xml(
+ 'lc_getremoteservicesapistatus_not_ready'),
+ 'is_recovery': load_wsman_xml(
+ 'lc_getremoteservicesapistatus_recovery'),
+ },
+ 'SetAttributes': {
+ 'ok': load_wsman_xml(
+ 'lc_service-invoke-set_attributes-ok'),
+ 'error': load_wsman_xml(
+ 'lc_service-invoke-set_attributes-error'),
+ }
+ }
+}
+
+NICEnumerations = {
+ uris.DCIM_NICEnumeration: {
+ 'ok': load_wsman_xml('nic_enumeration-enum-ok'),
+ },
+ uris.DCIM_NICString: {
+ 'ok': load_wsman_xml('nic_string-enum-ok'),
+ # this duplicates the LinkStatus from nic_enumeration-enum-ok
+ 'colliding': load_wsman_xml('nic_string-enum-colliding'),
+ },
+ uris.DCIM_NICInteger: {
+ 'ok': load_wsman_xml('nic_integer-enum-ok')
+ },
+}
+
+NICInvocations = {
+ uris.DCIM_NICService: {
+ 'SetAttributes': {
+ 'ok': load_wsman_xml(
+ 'nic_service-invoke-set_attributes-ok'),
+ 'error': load_wsman_xml(
+ 'nic_service-invoke-set_attributes-error'),
+ }
+ },
}
RAIDEnumerations = {
@@ -149,7 +246,18 @@ def load_wsman_xml(name):
'ok': load_wsman_xml('physical_disk_view-enum-ok')
},
uris.DCIM_VirtualDiskView: {
+ 'Raid_Status_ok': load_wsman_xml(
+ 'virtual_disk_view-enum-with-raid-status-ok'),
'ok': load_wsman_xml('virtual_disk_view-enum-ok')
+ },
+ uris.DCIM_RAIDEnumeration: {
+ 'ok': load_wsman_xml('raid_enumeration-enum-ok')
+ },
+ uris.DCIM_RAIDString: {
+ 'ok': load_wsman_xml('raid_string-enum-ok')
+ },
+ uris.DCIM_RAIDInteger: {
+ 'ok': load_wsman_xml('raid_integer-enum-ok')
}
}
@@ -172,6 +280,40 @@ def load_wsman_xml(name):
'raid_service-invoke-convert_physical_disks-ok'),
'error': load_wsman_xml(
'raid_service-invoke-convert_physical_disks-error'),
+ },
+ 'ResetConfig': {
+ 'ok': load_wsman_xml(
+ 'raid_service-invoke-reset_raid_config-ok'),
+ 'error': load_wsman_xml(
+ 'raid_service-invoke-reset_raid_config-error'),
+ },
+ 'ClearForeignConfig': {
+ 'ok': load_wsman_xml(
+ 'raid_service-invoke-clear_foreign_config-ok'),
+ 'no_foreign_drive': load_wsman_xml(
+ 'raid_service-invoke-clear_foreign_config-no_foreign_drive'),
+ 'invalid_controller_id': load_wsman_xml(
+ 'raid_service-invoke-clear_foreign_config-invalid_controller'),
+ 'foreign_drive_operation_not_supported': load_wsman_xml(
+ 'raid_service-invoke-clear_foreign_config-not_supported'),
+ },
+ 'SetAttributes': {
+ 'ok': load_wsman_xml(
+ 'raid_service-invoke-set_attributes-ok'),
+ 'error': load_wsman_xml(
+ 'raid_service-invoke-set_attributes-error'),
}
}
}
+
+SystemEnumerations = {
+ uris.DCIM_SystemEnumeration: {
+ 'ok': load_wsman_xml('system_enumeration-enum-ok'),
+ },
+ uris.DCIM_SystemString: {
+ 'ok': load_wsman_xml('system_string-enum-ok'),
+ },
+ uris.DCIM_SystemInteger: {
+ 'ok': load_wsman_xml('system_integer-enum-ok'),
+ }
+}
diff --git a/dracclient/tests/wsman_mocks/bios_enumeration-enum-ok.xml b/dracclient/tests/wsman_mocks/bios_enumeration-enum-ok.xml
index 6804d46..f817041 100644
--- a/dracclient/tests/wsman_mocks/bios_enumeration-enum-ok.xml
+++ b/dracclient/tests/wsman_mocks/bios_enumeration-enum-ok.xml
@@ -202,13 +202,13 @@
Logical Processor Idling
DynamicCoreAllocation
Disabled
-
- 421
+ <Dep><AttrLev Op="OR"><ROIf Name="ProcPwrPerf">MaxPerf</ROIf></AttrLev></Dep>
+ 5817
BIOS.Setup.1-1
Processor Settings
ProcSettings
BIOS.Setup.1-1:DynamicCoreAllocation
- false
+ true
Enabled
Disabled
@@ -1492,4 +1492,4 @@
-
\ No newline at end of file
+
diff --git a/dracclient/tests/wsman_mocks/controller_view-enum-ok.xml b/dracclient/tests/wsman_mocks/controller_view-enum-ok.xml
index 74c6488..069a0d8 100644
--- a/dracclient/tests/wsman_mocks/controller_view-enum-ok.xml
+++ b/dracclient/tests/wsman_mocks/controller_view-enum-ok.xml
@@ -43,6 +43,7 @@
0
1
PERC H710 Mini
+ 1
1
5B083FE0D2D0F200
1
@@ -52,9 +53,49 @@
0
0
+
+ 2
+ 512
+ 1
+ 2.5.13.2009
+ 1
+ Unknown
+ DELL
+ 2
+ Unknown
+ AHCI.Integrated.1-1
+
+ 1
+ 0
+ AHCI.Integrated.1-1
+ 0
+ AHCI.Integrated.1-1
+
+ 20150226175957.000000+000
+ 20150226175950.000000+000
+ Generation 2
+ Generation 3
+ 5B
+ 1
+ 1F38
+ 1028
+ 1000
+ 0
+ 1
+ BOSS-S1
+ 0
+ 1
+ 5B083FE0D2D0F201
+ 1
+ 1
+ 1
+ 1
+ 0
+ 0
+
-
\ No newline at end of file
+
diff --git a/dracclient/tests/wsman_mocks/idrac_service-invoke-set_attributes-ok.xml b/dracclient/tests/wsman_mocks/idrac_service-invoke-set_attributes-ok.xml
new file mode 100644
index 0000000..3f52ea8
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/idrac_service-invoke-set_attributes-ok.xml
@@ -0,0 +1,19 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_iDRACCardService/SetAttributesResponse
+ uuid:305ed6f4-2269-43c5-8c28-00b85e81099d
+ uuid:683c34bc-53c4-13c4-8064-17c1f0d9bed4
+
+
+
+ The command was successful
+ RAC001
+ No
+ 0
+ Set PendingValue
+
+
+
diff --git a/dracclient/tests/wsman_mocks/idrac_service-reset-error.xml b/dracclient/tests/wsman_mocks/idrac_service-reset-error.xml
new file mode 100644
index 0000000..9cc45d4
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/idrac_service-reset-error.xml
@@ -0,0 +1,22 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_iDRACCardService/iDRACResetResponse
+
+ uuid:a65ce3df-3690-42dd-af45-5c1f2cd0793b
+
+ uuid:e8f2cbe0-6fd0-1fd0-8057-dc9c046694d0
+
+
+
+
+ Invalid parameter value for Force
+ Force
+ RAC004
+ 2
+
+
+
\ No newline at end of file
diff --git a/dracclient/tests/wsman_mocks/idrac_service-reset-ok.xml b/dracclient/tests/wsman_mocks/idrac_service-reset-ok.xml
new file mode 100644
index 0000000..4b1eda0
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/idrac_service-reset-ok.xml
@@ -0,0 +1,22 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_iDRACCardService/iDRACResetResponse
+
+ uuid:a4a1cd1a-7c10-4dfc-98d9-d0cc2cd7c80c
+
+ uuid:6f9ecf40-6fd1-1fd1-a60b-dc9c046694d0
+
+
+
+
+ iDRAC was successfully reset.
+ RAC064
+ 0
+
+
+
+
diff --git a/dracclient/tests/wsman_mocks/idraccard_enumeration-enum-ok.xml b/dracclient/tests/wsman_mocks/idraccard_enumeration-enum-ok.xml
new file mode 100644
index 0000000..35bc8b9
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/idraccard_enumeration-enum-ok.xml
@@ -0,0 +1,4393 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse
+ uuid:d3870438-c87e-40e7-ad98-ab5fd4fe6279
+ uuid:a841c777-40aa-10aa-821b-de7e4e771814
+
+
+
+
+
+ iDRAC Type
+ Type
+ 13G Monolithic
+ 12G/13G
+
+ 6
+ iDRAC.Embedded.2
+ RAC Information
+ Info.1
+ iDRAC.Embedded.2#Info.1#Type
+ true
+
+ 12G/13G
+ 12G Monolithic
+ 12G Modular
+ 13G Monolithic
+ 13G Modular
+ 12G DCS
+ 13G DCS
+
+
+ iDRAC Type
+ Type
+ 13G Monolithic
+ 12G/13G
+
+ 6
+ iDRAC.Embedded.1
+ RAC Information
+ Info.1
+ iDRAC.Embedded.1#Info.1#Type
+ true
+
+ 12G/13G
+ 12G Monolithic
+ 12G Modular
+ 13G Monolithic
+ 13G Modular
+ 12G DCS
+ 13G DCS
+
+
+ NIC Enable
+ Enable
+ Enabled
+ Enabled
+
+ 51
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ NIC Selection
+ Selection
+ Dedicated
+ Dedicated
+
+ 53
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#Selection
+ false
+
+ Dedicated
+ LOM1
+ LOM2
+ LOM3
+ LOM4
+
+
+ NIC Failover
+ Failover
+ None
+ None
+
+ 54
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#Failover
+ false
+
+ None
+
+
+ NIC Speed
+ Speed
+ 1000
+ 100
+
+ 56
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#Speed
+ false
+
+ 10
+ 100
+ 1000
+
+
+ NIC Auto Negotiation
+ Autoneg
+ Enabled
+ Enabled
+
+ 55
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#Autoneg
+ false
+
+ Disabled
+ Enabled
+
+
+ NIC Duplex
+ Duplex
+ Full
+ Full
+
+ 57
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#Duplex
+ false
+
+ Half
+ Full
+
+
+ DNS Register RAC
+ DNSRegister
+ Disabled
+ Disabled
+
+ 60
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#DNSRegister
+ false
+
+ Disabled
+ Enabled
+
+
+ DNS Domain Name from DHCP
+ DNSDomainFromDHCP
+ Disabled
+ Disabled
+
+ 180
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#DNSDomainFromDHCP
+ false
+
+ Disabled
+ Enabled
+
+
+ Enable VLAN
+ VLanEnable
+ Disabled
+ Disabled
+
+ 63
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#VLanEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ DNS Domain Name from DHCP
+ DNSDomainNameFromDHCP
+ Disabled
+ Disabled
+
+ 180
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#DNSDomainNameFromDHCP
+ false
+
+ Disabled
+ Enabled
+
+
+ Auto NIC Enable
+ AutoDetect
+ Disabled
+ Disabled
+
+ 66
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#AutoDetect
+ false
+
+ Disabled
+ Enabled
+
+
+ Auto Configuration enable
+ AutoConfig
+ Disabled
+ Disabled
+
+ 69
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#AutoConfig
+ false
+
+ Disabled
+ Enable Once
+ Enable Once After Reset
+
+
+ VLan port
+ VLanPort
+ Both
+ Both
+
+ 70
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#VLanPort
+ false
+
+ Both
+ Dedicated port only
+ LOM ports only
+
+
+ Active NIC Interface
+ ActiveNIC
+ Dedicated
+ Dedicated
+
+ 71
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#ActiveNIC
+ true
+
+ No LOM Active
+ LOM1
+ LOM2
+ LOM3
+ LOM4
+ Dedicated
+ Unknown
+
+
+ Active NIC Link Status
+ LinkStatus
+ LinkPresent
+ NoLink
+
+ 72
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#LinkStatus
+ true
+
+ NoLink
+ LinkPresent
+
+
+ Active NIC Link Speed
+ LinkSpeed
+ 1Gbps
+ 100Mbps
+
+ 73
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#LinkSpeed
+ true
+
+ 10Mbps
+ 100Mbps
+ 1Gbps
+ Unknown
+
+
+ Active NIC Link Mode
+ LinkMode
+ FullDuplex
+ FullDuplex
+
+ 74
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#LinkMode
+ true
+
+ HalfDuplex
+ FullDuplex
+ Unknown
+
+
+ Auto Dedicated NIC
+ AutoDedicatedNIC
+ Disabled
+ Disabled
+
+ 75
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#AutoDedicatedNIC
+ false
+
+ Disabled
+ Enabled
+
+
+ IPv4 Enable
+ Enable
+ Enabled
+ Enabled
+
+ 101
+ iDRAC.Embedded.1
+ IPv4 Information
+ IPv4.1
+ iDRAC.Embedded.1#IPv4.1#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ IPv4 DHCP Enable
+ DHCPEnable
+ Disabled
+ Disabled
+
+ 102
+ iDRAC.Embedded.1
+ IPv4 Information
+ IPv4.1
+ iDRAC.Embedded.1#IPv4.1#DHCPEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ DNS Servers From DHCP
+ DNSFromDHCP
+ Disabled
+ Disabled
+
+ 106
+ iDRAC.Embedded.1
+ IPv4 Information
+ IPv4.1
+ iDRAC.Embedded.1#IPv4.1#DNSFromDHCP
+ false
+
+ Disabled
+ Enabled
+
+
+ IPV6 Enable
+ Enable
+ Disabled
+ Disabled
+
+ 151
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ IPV6 Auto Config
+ AutoConfig
+ Enabled
+ Enabled
+
+ 152
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#AutoConfig
+ false
+
+ Disabled
+ Enabled
+
+
+ DNS Server From DHCP6
+ DNSFromDHCP6
+ Disabled
+ Disabled
+
+ 153
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#DNSFromDHCP6
+ false
+
+ Disabled
+ Enabled
+
+
+ Address State
+ AddressState
+ Disabled
+ Active
+
+ 175
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#AddressState
+ true
+
+ Active
+ Disabled
+ Pending
+ Failed
+ Deprecated
+ Invalid
+
+
+ DNS Domain Name from DHCP
+ DNSDomainFromDHCP
+ Disabled
+ Disabled
+
+ 183
+ iDRAC.Embedded.1
+ NIC Static Information
+ NICStatic.1
+ iDRAC.Embedded.1#NICStatic.1#DNSDomainFromDHCP
+ false
+
+ Disabled
+ Enabled
+
+
+ DNS Servers From DHCP
+ DNSFromDHCP
+ Disabled
+ Disabled
+
+ 190
+ iDRAC.Embedded.1
+ IPv4 Static Information
+ IPv4Static.1
+ iDRAC.Embedded.1#IPv4Static.1#DNSFromDHCP
+ false
+
+ Disabled
+ Enabled
+
+
+ DNS Server From DHCP6
+ DNSFromDHCP6
+ Disabled
+ Disabled
+
+ 196
+ iDRAC.Embedded.1
+ IPv6 Static Information
+ IPv6Static.1
+ iDRAC.Embedded.1#IPv6Static.1#DNSFromDHCP6
+ false
+
+ Disabled
+ Enabled
+
+
+ Enable or Disable IPMI over LAN
+ Enable
+ Disabled
+ Disabled
+
+ 201
+ iDRAC.Embedded.1
+ IPMI LAN Information
+ IPMILan.1
+ iDRAC.Embedded.1#IPMILan.1#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ Privilege Limit
+ PrivLimit
+ Administrator
+ Administrator
+
+ 202
+ iDRAC.Embedded.1
+ IPMI LAN Information
+ IPMILan.1
+ iDRAC.Embedded.1#IPMILan.1#PrivLimit
+ false
+
+ User
+ Operator
+ Administrator
+
+
+ Enable or Disable Alerts over LAN
+ AlertEnable
+ Disabled
+ Disabled
+
+ 205
+ iDRAC.Embedded.1
+ IPMI LAN Information
+ IPMILan.1
+ iDRAC.Embedded.1#IPMILan.1#AlertEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ User Admin IPMI LAN Privilege
+ IpmiLanPrivilege
+ No Access
+ No Access
+
+ 254
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.1
+ iDRAC.Embedded.1#Users.1#IpmiLanPrivilege
+ true
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin IPMI Serial Privilege
+ IpmiSerialPrivilege
+ No Access
+ No Access
+
+ 255
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.1
+ iDRAC.Embedded.1#Users.1#IpmiSerialPrivilege
+ true
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin Enable
+ Enable
+ Disabled
+ Disabled
+
+ 256
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.1
+ iDRAC.Embedded.1#Users.1#Enable
+ true
+
+ Disabled
+ Enabled
+
+
+ User Admin SOL Enable
+ SolEnable
+ Disabled
+ Disabled
+
+ 257
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.1
+ iDRAC.Embedded.1#Users.1#SolEnable
+ true
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Protocol Enable
+ ProtocolEnable
+ Disabled
+ Disabled
+
+ 258
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.1
+ iDRAC.Embedded.1#Users.1#ProtocolEnable
+ true
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Authentication Protocol
+ AuthenticationProtocol
+ SHA
+ SHA
+
+ 259
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.1
+ iDRAC.Embedded.1#Users.1#AuthenticationProtocol
+ true
+
+ None
+ MD5
+ SHA
+
+
+ SNMP V3 Privacy Protocol
+ PrivacyProtocol
+ AES
+ AES
+
+ 260
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.1
+ iDRAC.Embedded.1#Users.1#PrivacyProtocol
+ true
+
+ None
+ DES
+ AES
+
+
+ User Admin IPMI LAN Privilege
+ IpmiLanPrivilege
+ Administrator
+ Administrator
+
+ 264
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.2
+ iDRAC.Embedded.1#Users.2#IpmiLanPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin IPMI Serial Privilege
+ IpmiSerialPrivilege
+ Administrator
+ Administrator
+
+ 265
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.2
+ iDRAC.Embedded.1#Users.2#IpmiSerialPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin Enable
+ Enable
+ Enabled
+ Disabled
+
+ 266
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.2
+ iDRAC.Embedded.1#Users.2#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ User Admin SOL Enable
+ SolEnable
+ Enabled
+ Disabled
+
+ 267
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.2
+ iDRAC.Embedded.1#Users.2#SolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Protocol Enable
+ ProtocolEnable
+ Disabled
+ Disabled
+
+ 268
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.2
+ iDRAC.Embedded.1#Users.2#ProtocolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Authentication Protocol
+ AuthenticationProtocol
+ SHA
+ SHA
+
+ 269
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.2
+ iDRAC.Embedded.1#Users.2#AuthenticationProtocol
+ false
+
+ None
+ MD5
+ SHA
+
+
+ SNMP V3 Privacy Protocol
+ PrivacyProtocol
+ AES
+ AES
+
+ 270
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.2
+ iDRAC.Embedded.1#Users.2#PrivacyProtocol
+ false
+
+ None
+ DES
+ AES
+
+
+ User Admin IPMI LAN Privilege
+ IpmiLanPrivilege
+ Administrator
+ No Access
+
+ 274
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.3
+ iDRAC.Embedded.1#Users.3#IpmiLanPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin IPMI Serial Privilege
+ IpmiSerialPrivilege
+ No Access
+ No Access
+
+ 275
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.3
+ iDRAC.Embedded.1#Users.3#IpmiSerialPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin Enable
+ Enable
+ Enabled
+ Disabled
+
+ 276
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.3
+ iDRAC.Embedded.1#Users.3#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ User Admin SOL Enable
+ SolEnable
+ Disabled
+ Disabled
+
+ 277
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.3
+ iDRAC.Embedded.1#Users.3#SolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Protocol Enable
+ ProtocolEnable
+ Disabled
+ Disabled
+
+ 278
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.3
+ iDRAC.Embedded.1#Users.3#ProtocolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Authentication Protocol
+ AuthenticationProtocol
+ SHA
+ SHA
+
+ 279
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.3
+ iDRAC.Embedded.1#Users.3#AuthenticationProtocol
+ false
+
+ None
+ MD5
+ SHA
+
+
+ SNMP V3 Privacy Protocol
+ PrivacyProtocol
+ AES
+ AES
+
+ 280
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.3
+ iDRAC.Embedded.1#Users.3#PrivacyProtocol
+ false
+
+ None
+ DES
+ AES
+
+
+ User Admin IPMI LAN Privilege
+ IpmiLanPrivilege
+ No Access
+ No Access
+
+ 284
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.4
+ iDRAC.Embedded.1#Users.4#IpmiLanPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin IPMI Serial Privilege
+ IpmiSerialPrivilege
+ No Access
+ No Access
+
+ 285
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.4
+ iDRAC.Embedded.1#Users.4#IpmiSerialPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin Enable
+ Enable
+ Enabled
+ Disabled
+
+ 286
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.4
+ iDRAC.Embedded.1#Users.4#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ User Admin SOL Enable
+ SolEnable
+ Disabled
+ Disabled
+
+ 287
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.4
+ iDRAC.Embedded.1#Users.4#SolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Protocol Enable
+ ProtocolEnable
+ Disabled
+ Disabled
+
+ 288
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.4
+ iDRAC.Embedded.1#Users.4#ProtocolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Authentication Protocol
+ AuthenticationProtocol
+ SHA
+ SHA
+
+ 289
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.4
+ iDRAC.Embedded.1#Users.4#AuthenticationProtocol
+ false
+
+ None
+ MD5
+ SHA
+
+
+ SNMP V3 Privacy Protocol
+ PrivacyProtocol
+ AES
+ AES
+
+ 290
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.4
+ iDRAC.Embedded.1#Users.4#PrivacyProtocol
+ false
+
+ None
+ DES
+ AES
+
+
+ User Admin IPMI LAN Privilege
+ IpmiLanPrivilege
+ No Access
+ No Access
+
+ 294
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.5
+ iDRAC.Embedded.1#Users.5#IpmiLanPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin IPMI Serial Privilege
+ IpmiSerialPrivilege
+ No Access
+ No Access
+
+ 295
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.5
+ iDRAC.Embedded.1#Users.5#IpmiSerialPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin Enable
+ Enable
+ Disabled
+ Disabled
+
+ 296
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.5
+ iDRAC.Embedded.1#Users.5#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ User Admin SOL Enable
+ SolEnable
+ Disabled
+ Disabled
+
+ 297
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.5
+ iDRAC.Embedded.1#Users.5#SolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Protocol Enable
+ ProtocolEnable
+ Disabled
+ Disabled
+
+ 298
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.5
+ iDRAC.Embedded.1#Users.5#ProtocolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Authentication Protocol
+ AuthenticationProtocol
+ SHA
+ SHA
+
+ 299
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.5
+ iDRAC.Embedded.1#Users.5#AuthenticationProtocol
+ false
+
+ None
+ MD5
+ SHA
+
+
+ SNMP V3 Privacy Protocol
+ PrivacyProtocol
+ AES
+ AES
+
+ 300
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.5
+ iDRAC.Embedded.1#Users.5#PrivacyProtocol
+ false
+
+ None
+ DES
+ AES
+
+
+ User Admin IPMI LAN Privilege
+ IpmiLanPrivilege
+ No Access
+ No Access
+
+ 304
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.6
+ iDRAC.Embedded.1#Users.6#IpmiLanPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin IPMI Serial Privilege
+ IpmiSerialPrivilege
+ No Access
+ No Access
+
+ 305
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.6
+ iDRAC.Embedded.1#Users.6#IpmiSerialPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin Enable
+ Enable
+ Disabled
+ Disabled
+
+ 306
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.6
+ iDRAC.Embedded.1#Users.6#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ User Admin SOL Enable
+ SolEnable
+ Disabled
+ Disabled
+
+ 307
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.6
+ iDRAC.Embedded.1#Users.6#SolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Protocol Enable
+ ProtocolEnable
+ Disabled
+ Disabled
+
+ 308
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.6
+ iDRAC.Embedded.1#Users.6#ProtocolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Authentication Protocol
+ AuthenticationProtocol
+ SHA
+ SHA
+
+ 309
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.6
+ iDRAC.Embedded.1#Users.6#AuthenticationProtocol
+ false
+
+ None
+ MD5
+ SHA
+
+
+ SNMP V3 Privacy Protocol
+ PrivacyProtocol
+ AES
+ AES
+
+ 310
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.6
+ iDRAC.Embedded.1#Users.6#PrivacyProtocol
+ false
+
+ None
+ DES
+ AES
+
+
+ User Admin IPMI LAN Privilege
+ IpmiLanPrivilege
+ No Access
+ No Access
+
+ 314
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.7
+ iDRAC.Embedded.1#Users.7#IpmiLanPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin IPMI Serial Privilege
+ IpmiSerialPrivilege
+ No Access
+ No Access
+
+ 315
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.7
+ iDRAC.Embedded.1#Users.7#IpmiSerialPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin Enable
+ Enable
+ Disabled
+ Disabled
+
+ 316
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.7
+ iDRAC.Embedded.1#Users.7#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ User Admin SOL Enable
+ SolEnable
+ Disabled
+ Disabled
+
+ 317
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.7
+ iDRAC.Embedded.1#Users.7#SolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Protocol Enable
+ ProtocolEnable
+ Disabled
+ Disabled
+
+ 318
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.7
+ iDRAC.Embedded.1#Users.7#ProtocolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Authentication Protocol
+ AuthenticationProtocol
+ SHA
+ SHA
+
+ 319
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.7
+ iDRAC.Embedded.1#Users.7#AuthenticationProtocol
+ false
+
+ None
+ MD5
+ SHA
+
+
+ SNMP V3 Privacy Protocol
+ PrivacyProtocol
+ AES
+ AES
+
+ 320
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.7
+ iDRAC.Embedded.1#Users.7#PrivacyProtocol
+ false
+
+ None
+ DES
+ AES
+
+
+ User Admin IPMI LAN Privilege
+ IpmiLanPrivilege
+ No Access
+ No Access
+
+ 324
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.8
+ iDRAC.Embedded.1#Users.8#IpmiLanPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin IPMI Serial Privilege
+ IpmiSerialPrivilege
+ No Access
+ No Access
+
+ 325
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.8
+ iDRAC.Embedded.1#Users.8#IpmiSerialPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin Enable
+ Enable
+ Disabled
+ Disabled
+
+ 326
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.8
+ iDRAC.Embedded.1#Users.8#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ User Admin SOL Enable
+ SolEnable
+ Disabled
+ Disabled
+
+ 327
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.8
+ iDRAC.Embedded.1#Users.8#SolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Protocol Enable
+ ProtocolEnable
+ Disabled
+ Disabled
+
+ 328
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.8
+ iDRAC.Embedded.1#Users.8#ProtocolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Authentication Protocol
+ AuthenticationProtocol
+ SHA
+ SHA
+
+ 329
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.8
+ iDRAC.Embedded.1#Users.8#AuthenticationProtocol
+ false
+
+ None
+ MD5
+ SHA
+
+
+ SNMP V3 Privacy Protocol
+ PrivacyProtocol
+ AES
+ AES
+
+ 330
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.8
+ iDRAC.Embedded.1#Users.8#PrivacyProtocol
+ false
+
+ None
+ DES
+ AES
+
+
+ User Admin IPMI LAN Privilege
+ IpmiLanPrivilege
+ No Access
+ No Access
+
+ 334
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.9
+ iDRAC.Embedded.1#Users.9#IpmiLanPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin IPMI Serial Privilege
+ IpmiSerialPrivilege
+ No Access
+ No Access
+
+ 335
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.9
+ iDRAC.Embedded.1#Users.9#IpmiSerialPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin Enable
+ Enable
+ Disabled
+ Disabled
+
+ 336
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.9
+ iDRAC.Embedded.1#Users.9#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ User Admin SOL Enable
+ SolEnable
+ Disabled
+ Disabled
+
+ 337
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.9
+ iDRAC.Embedded.1#Users.9#SolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Protocol Enable
+ ProtocolEnable
+ Disabled
+ Disabled
+
+ 338
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.9
+ iDRAC.Embedded.1#Users.9#ProtocolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Authentication Protocol
+ AuthenticationProtocol
+ SHA
+ SHA
+
+ 339
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.9
+ iDRAC.Embedded.1#Users.9#AuthenticationProtocol
+ false
+
+ None
+ MD5
+ SHA
+
+
+ SNMP V3 Privacy Protocol
+ PrivacyProtocol
+ AES
+ AES
+
+ 340
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.9
+ iDRAC.Embedded.1#Users.9#PrivacyProtocol
+ false
+
+ None
+ DES
+ AES
+
+
+ User Admin IPMI LAN Privilege
+ IpmiLanPrivilege
+ No Access
+ No Access
+
+ 344
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.10
+ iDRAC.Embedded.1#Users.10#IpmiLanPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin IPMI Serial Privilege
+ IpmiSerialPrivilege
+ No Access
+ No Access
+
+ 345
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.10
+ iDRAC.Embedded.1#Users.10#IpmiSerialPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin Enable
+ Enable
+ Disabled
+ Disabled
+
+ 346
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.10
+ iDRAC.Embedded.1#Users.10#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ User Admin SOL Enable
+ SolEnable
+ Disabled
+ Disabled
+
+ 347
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.10
+ iDRAC.Embedded.1#Users.10#SolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Protocol Enable
+ ProtocolEnable
+ Disabled
+ Disabled
+
+ 348
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.10
+ iDRAC.Embedded.1#Users.10#ProtocolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Authentication Protocol
+ AuthenticationProtocol
+ SHA
+ SHA
+
+ 349
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.10
+ iDRAC.Embedded.1#Users.10#AuthenticationProtocol
+ false
+
+ None
+ MD5
+ SHA
+
+
+ SNMP V3 Privacy Protocol
+ PrivacyProtocol
+ AES
+ AES
+
+ 350
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.10
+ iDRAC.Embedded.1#Users.10#PrivacyProtocol
+ false
+
+ None
+ DES
+ AES
+
+
+ User Admin IPMI LAN Privilege
+ IpmiLanPrivilege
+ No Access
+ No Access
+
+ 354
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.11
+ iDRAC.Embedded.1#Users.11#IpmiLanPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin IPMI Serial Privilege
+ IpmiSerialPrivilege
+ No Access
+ No Access
+
+ 355
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.11
+ iDRAC.Embedded.1#Users.11#IpmiSerialPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin Enable
+ Enable
+ Disabled
+ Disabled
+
+ 356
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.11
+ iDRAC.Embedded.1#Users.11#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ User Admin SOL Enable
+ SolEnable
+ Disabled
+ Disabled
+
+ 357
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.11
+ iDRAC.Embedded.1#Users.11#SolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Protocol Enable
+ ProtocolEnable
+ Disabled
+ Disabled
+
+ 358
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.11
+ iDRAC.Embedded.1#Users.11#ProtocolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Authentication Protocol
+ AuthenticationProtocol
+ SHA
+ SHA
+
+ 359
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.11
+ iDRAC.Embedded.1#Users.11#AuthenticationProtocol
+ false
+
+ None
+ MD5
+ SHA
+
+
+ SNMP V3 Privacy Protocol
+ PrivacyProtocol
+ AES
+ AES
+
+ 360
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.11
+ iDRAC.Embedded.1#Users.11#PrivacyProtocol
+ false
+
+ None
+ DES
+ AES
+
+
+ User Admin IPMI LAN Privilege
+ IpmiLanPrivilege
+ No Access
+ No Access
+
+ 364
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.12
+ iDRAC.Embedded.1#Users.12#IpmiLanPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin IPMI Serial Privilege
+ IpmiSerialPrivilege
+ No Access
+ No Access
+
+ 365
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.12
+ iDRAC.Embedded.1#Users.12#IpmiSerialPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin Enable
+ Enable
+ Disabled
+ Disabled
+
+ 366
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.12
+ iDRAC.Embedded.1#Users.12#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ User Admin SOL Enable
+ SolEnable
+ Disabled
+ Disabled
+
+ 367
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.12
+ iDRAC.Embedded.1#Users.12#SolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Protocol Enable
+ ProtocolEnable
+ Disabled
+ Disabled
+
+ 368
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.12
+ iDRAC.Embedded.1#Users.12#ProtocolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Authentication Protocol
+ AuthenticationProtocol
+ SHA
+ SHA
+
+ 369
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.12
+ iDRAC.Embedded.1#Users.12#AuthenticationProtocol
+ false
+
+ None
+ MD5
+ SHA
+
+
+ SNMP V3 Privacy Protocol
+ PrivacyProtocol
+ AES
+ AES
+
+ 370
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.12
+ iDRAC.Embedded.1#Users.12#PrivacyProtocol
+ false
+
+ None
+ DES
+ AES
+
+
+ User Admin IPMI LAN Privilege
+ IpmiLanPrivilege
+ No Access
+ No Access
+
+ 374
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.13
+ iDRAC.Embedded.1#Users.13#IpmiLanPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin IPMI Serial Privilege
+ IpmiSerialPrivilege
+ No Access
+ No Access
+
+ 375
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.13
+ iDRAC.Embedded.1#Users.13#IpmiSerialPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin Enable
+ Enable
+ Disabled
+ Disabled
+
+ 376
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.13
+ iDRAC.Embedded.1#Users.13#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ User Admin SOL Enable
+ SolEnable
+ Disabled
+ Disabled
+
+ 377
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.13
+ iDRAC.Embedded.1#Users.13#SolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Protocol Enable
+ ProtocolEnable
+ Disabled
+ Disabled
+
+ 378
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.13
+ iDRAC.Embedded.1#Users.13#ProtocolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Authentication Protocol
+ AuthenticationProtocol
+ SHA
+ SHA
+
+ 379
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.13
+ iDRAC.Embedded.1#Users.13#AuthenticationProtocol
+ false
+
+ None
+ MD5
+ SHA
+
+
+ SNMP V3 Privacy Protocol
+ PrivacyProtocol
+ AES
+ AES
+
+ 380
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.13
+ iDRAC.Embedded.1#Users.13#PrivacyProtocol
+ false
+
+ None
+ DES
+ AES
+
+
+ User Admin IPMI LAN Privilege
+ IpmiLanPrivilege
+ No Access
+ No Access
+
+ 384
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.14
+ iDRAC.Embedded.1#Users.14#IpmiLanPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin IPMI Serial Privilege
+ IpmiSerialPrivilege
+ No Access
+ No Access
+
+ 385
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.14
+ iDRAC.Embedded.1#Users.14#IpmiSerialPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin Enable
+ Enable
+ Disabled
+ Disabled
+
+ 386
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.14
+ iDRAC.Embedded.1#Users.14#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ User Admin SOL Enable
+ SolEnable
+ Disabled
+ Disabled
+
+ 387
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.14
+ iDRAC.Embedded.1#Users.14#SolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Protocol Enable
+ ProtocolEnable
+ Disabled
+ Disabled
+
+ 388
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.14
+ iDRAC.Embedded.1#Users.14#ProtocolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Authentication Protocol
+ AuthenticationProtocol
+ SHA
+ SHA
+
+ 389
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.14
+ iDRAC.Embedded.1#Users.14#AuthenticationProtocol
+ false
+
+ None
+ MD5
+ SHA
+
+
+ SNMP V3 Privacy Protocol
+ PrivacyProtocol
+ AES
+ AES
+
+ 390
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.14
+ iDRAC.Embedded.1#Users.14#PrivacyProtocol
+ false
+
+ None
+ DES
+ AES
+
+
+ User Admin IPMI LAN Privilege
+ IpmiLanPrivilege
+ No Access
+ No Access
+
+ 394
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.15
+ iDRAC.Embedded.1#Users.15#IpmiLanPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin IPMI Serial Privilege
+ IpmiSerialPrivilege
+ No Access
+ No Access
+
+ 395
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.15
+ iDRAC.Embedded.1#Users.15#IpmiSerialPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin Enable
+ Enable
+ Disabled
+ Disabled
+
+ 396
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.15
+ iDRAC.Embedded.1#Users.15#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ User Admin SOL Enable
+ SolEnable
+ Disabled
+ Disabled
+
+ 397
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.15
+ iDRAC.Embedded.1#Users.15#SolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Protocol Enable
+ ProtocolEnable
+ Disabled
+ Disabled
+
+ 398
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.15
+ iDRAC.Embedded.1#Users.15#ProtocolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Authentication Protocol
+ AuthenticationProtocol
+ SHA
+ SHA
+
+ 399
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.15
+ iDRAC.Embedded.1#Users.15#AuthenticationProtocol
+ false
+
+ None
+ MD5
+ SHA
+
+
+ SNMP V3 Privacy Protocol
+ PrivacyProtocol
+ AES
+ AES
+
+ 400
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.15
+ iDRAC.Embedded.1#Users.15#PrivacyProtocol
+ false
+
+ None
+ DES
+ AES
+
+
+ User Admin IPMI LAN Privilege
+ IpmiLanPrivilege
+ No Access
+ No Access
+
+ 404
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.16
+ iDRAC.Embedded.1#Users.16#IpmiLanPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin IPMI Serial Privilege
+ IpmiSerialPrivilege
+ No Access
+ No Access
+
+ 405
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.16
+ iDRAC.Embedded.1#Users.16#IpmiSerialPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+ No Access
+
+
+ User Admin Enable
+ Enable
+ Disabled
+ Disabled
+
+ 406
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.16
+ iDRAC.Embedded.1#Users.16#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ User Admin SOL Enable
+ SolEnable
+ Disabled
+ Disabled
+
+ 407
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.16
+ iDRAC.Embedded.1#Users.16#SolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Protocol Enable
+ ProtocolEnable
+ Disabled
+ Disabled
+
+ 408
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.16
+ iDRAC.Embedded.1#Users.16#ProtocolEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP V3 Authentication Protocol
+ AuthenticationProtocol
+ SHA
+ SHA
+
+ 409
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.16
+ iDRAC.Embedded.1#Users.16#AuthenticationProtocol
+ false
+
+ None
+ MD5
+ SHA
+
+
+ SNMP V3 Privacy Protocol
+ PrivacyProtocol
+ AES
+ AES
+
+ 410
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.16
+ iDRAC.Embedded.1#Users.16#PrivacyProtocol
+ false
+
+ None
+ DES
+ AES
+
+
+ Enable or Disable TFTP for Firmware Update
+ FwUpdateTFTPEnable
+ Enabled
+ Enabled
+
+ 451
+ iDRAC.Embedded.1
+ Firmware Update
+ Update.1
+ iDRAC.Embedded.1#Update.1#FwUpdateTFTPEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ Enable Email Alerts
+ Enable
+ Disabled
+ Disabled
+
+ 471
+ iDRAC.Embedded.1
+ RAC Email Alert
+ EmailAlert.1
+ iDRAC.Embedded.1#EmailAlert.1#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ Enable Email Alerts
+ Enable
+ Disabled
+ Disabled
+
+ 491
+ iDRAC.Embedded.1
+ RAC Email Alert
+ EmailAlert.2
+ iDRAC.Embedded.1#EmailAlert.2#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ Enable Email Alerts
+ Enable
+ Disabled
+ Disabled
+
+ 511
+ iDRAC.Embedded.1
+ RAC Email Alert
+ EmailAlert.3
+ iDRAC.Embedded.1#EmailAlert.3#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ Enable Email Alerts
+ Enable
+ Disabled
+ Disabled
+
+ 521
+ iDRAC.Embedded.1
+ RAC Email Alert
+ EmailAlert.4
+ iDRAC.Embedded.1#EmailAlert.4#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ Enable SMTP Authentication
+ SMTPAuthentication
+ Disabled
+ Disabled
+
+ 543
+ iDRAC.Embedded.1
+ RAC Remote Hosts
+ RemoteHosts.1
+ iDRAC.Embedded.1#RemoteHosts.1#SMTPAuthentication
+ false
+
+ Disabled
+ Enabled
+
+
+ Enable
+ Enable
+ Disabled
+ Disabled
+
+ 551
+ iDRAC.Embedded.1
+ Telnet Configuration
+ Telnet.1
+ iDRAC.Embedded.1#Telnet.1#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ Enable
+ Enable
+ Enabled
+ Enabled
+
+ 561
+ iDRAC.Embedded.1
+ RAC SSH
+ SSH.1
+ iDRAC.Embedded.1#SSH.1#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ Enable
+ Enable
+ Enabled
+ Enabled
+
+ 571
+ iDRAC.Embedded.1
+ RAC Web Server
+ WebServer.1
+ iDRAC.Embedded.1#WebServer.1#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ Enable
+ LowerEncryptionBitLength
+ Enabled
+ Enabled
+
+ 575
+ iDRAC.Embedded.1
+ RAC Web Server
+ WebServer.1
+ iDRAC.Embedded.1#WebServer.1#LowerEncryptionBitLength
+ false
+
+ Disabled
+ Enabled
+
+
+ Https Redirection
+ HttpsRedirection
+ Enabled
+ Enabled
+
+ 576
+ iDRAC.Embedded.1
+ RAC Web Server
+ WebServer.1
+ iDRAC.Embedded.1#WebServer.1#HttpsRedirection
+ false
+
+ Disabled
+ Enabled
+
+
+ SSL Encryption Bit Length
+ SSLEncryptionBitLength
+ 128-Bit or higher
+ 128-Bit or higher
+
+ 577
+ iDRAC.Embedded.1
+ RAC Web Server
+ WebServer.1
+ iDRAC.Embedded.1#WebServer.1#SSLEncryptionBitLength
+ false
+
+ Auto-Negotiate
+ 128-Bit or higher
+ 168-Bit or higher
+ 256-Bit or higher
+
+
+ TLS Protocol Support
+ TLSProtocol
+ TLS 1.1 and Higher
+ TLS 1.1 and Higher
+
+ 579
+ iDRAC.Embedded.1
+ RAC Web Server
+ WebServer.1
+ iDRAC.Embedded.1#WebServer.1#TLSProtocol
+ false
+
+ TLS 1.0 and Higher
+ TLS 1.1 and Higher
+ TLS 1.2 Only
+
+
+ Enable
+ Enable
+ Enabled
+ Enabled
+
+ 581
+ iDRAC.Embedded.1
+ Virtual Console Configuration
+ VirtualConsole.1
+ iDRAC.Embedded.1#VirtualConsole.1#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ Encrypt Enable
+ EncryptEnable
+ AES
+ AES
+
+ 582
+ iDRAC.Embedded.1
+ Virtual Console Configuration
+ VirtualConsole.1
+ iDRAC.Embedded.1#VirtualConsole.1#EncryptEnable
+ false
+
+ None
+ AES
+
+
+ Local Video
+ LocalVideo
+ Enabled
+ Enabled
+
+ 583
+ iDRAC.Embedded.1
+ Virtual Console Configuration
+ VirtualConsole.1
+ iDRAC.Embedded.1#VirtualConsole.1#LocalVideo
+ false
+
+ Disabled
+ Enabled
+
+
+ Plugin Type
+ PluginType
+ Active X
+ Active X
+
+ 584
+ iDRAC.Embedded.1
+ Virtual Console Configuration
+ VirtualConsole.1
+ iDRAC.Embedded.1#VirtualConsole.1#PluginType
+ false
+
+ Active X
+ Java
+ HTML5
+
+
+ Default action upon session sharing request timeout
+ AccessPrivilege
+ Deny Access
+ Full Access
+
+ 588
+ iDRAC.Embedded.1
+ Virtual Console Configuration
+ VirtualConsole.1
+ iDRAC.Embedded.1#VirtualConsole.1#AccessPrivilege
+ false
+
+ Deny Access
+ Read Only Access
+ Full Access
+
+
+ Attach State
+ AttachState
+ Auto-Attach
+ Auto-Attach
+
+ 589
+ iDRAC.Embedded.1
+ Virtual Console Configuration
+ VirtualConsole.1
+ iDRAC.Embedded.1#VirtualConsole.1#AttachState
+ false
+
+ Detached
+ Attached
+ Auto-Attach
+
+
+ Remote Enable
+ Enable
+ Enabled
+ Enabled
+
+ 591
+ iDRAC.Embedded.1
+ Remote Racadm Configuration
+ Racadm.1
+ iDRAC.Embedded.1#Racadm.1#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ Serial Console Enable
+ Enable
+ Enabled
+ Enabled
+
+ 601
+ iDRAC.Embedded.1
+ Serial Configuration
+ Serial.1
+ iDRAC.Embedded.1#Serial.1#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ Serial Baud Rate
+ BaudRate
+ 57600
+ 57600
+
+ 602
+ iDRAC.Embedded.1
+ Serial Configuration
+ Serial.1
+ iDRAC.Embedded.1#Serial.1#BaudRate
+ false
+
+ 9600
+ 19200
+ 38400
+ 57600
+ 115200
+
+
+ Serial Console No Authentication
+ NoAuth
+ Disabled
+ Disabled
+
+ 604
+ iDRAC.Embedded.1
+ Serial Configuration
+ Serial.1
+ iDRAC.Embedded.1#Serial.1#NoAuth
+ false
+
+ Disabled
+ Enabled
+
+
+ Serial Communication Redirection Enable
+ Enable
+ Enabled
+ Enabled
+
+ 611
+ iDRAC.Embedded.1
+ RAC Serial Redirection
+ SerialRedirection.1
+ iDRAC.Embedded.1#SerialRedirection.1#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ IPMI Serial Connection Mode
+ ConnectionMode
+ Basic
+ Basic
+
+ 621
+ iDRAC.Embedded.1
+ RAC IPMI Serial
+ IPMISerial.1
+ iDRAC.Embedded.1#IPMISerial.1#ConnectionMode
+ false
+
+ Terminal
+ Basic
+
+
+ IPMI Serial Baud Rate
+ BaudRate
+ 57600
+ 57600
+
+ 622
+ iDRAC.Embedded.1
+ RAC IPMI Serial
+ IPMISerial.1
+ iDRAC.Embedded.1#IPMISerial.1#BaudRate
+ false
+
+ 9600
+ 19200
+ 57600
+ 115200
+
+
+ IPMI Serial Flow Control
+ FlowControl
+ RTS/CTS
+ RTS/CTS
+
+ 623
+ iDRAC.Embedded.1
+ RAC IPMI Serial
+ IPMISerial.1
+ iDRAC.Embedded.1#IPMISerial.1#FlowControl
+ false
+
+ None
+ RTS/CTS
+
+
+ IPMI Serial Channel Privilege Limit
+ ChanPrivLimit
+ Administrator
+ Administrator
+
+ 624
+ iDRAC.Embedded.1
+ RAC IPMI Serial
+ IPMISerial.1
+ iDRAC.Embedded.1#IPMISerial.1#ChanPrivLimit
+ false
+
+ User
+ Operator
+ Administrator
+
+
+ IPMI Serial Line Edit
+ LineEdit
+ Enabled
+ Enabled
+
+ 625
+ iDRAC.Embedded.1
+ RAC IPMI Serial
+ IPMISerial.1
+ iDRAC.Embedded.1#IPMISerial.1#LineEdit
+ false
+
+ Disabled
+ Enabled
+
+
+ IPMI Serial Delete Control
+ DeleteControl
+ Disabled
+ Disabled
+
+ 626
+ iDRAC.Embedded.1
+ RAC IPMI Serial
+ IPMISerial.1
+ iDRAC.Embedded.1#IPMISerial.1#DeleteControl
+ false
+
+ Disabled
+ Enabled
+
+
+ IPMI Serial Echo Control
+ EchoControl
+ Enabled
+ Enabled
+
+ 627
+ iDRAC.Embedded.1
+ RAC IPMI Serial
+ IPMISerial.1
+ iDRAC.Embedded.1#IPMISerial.1#EchoControl
+ false
+
+ Disabled
+ Enabled
+
+
+ IPMI Serial Handshake Control
+ HandshakeControl
+ Enabled
+ Enabled
+
+ 628
+ iDRAC.Embedded.1
+ RAC IPMI Serial
+ IPMISerial.1
+ iDRAC.Embedded.1#IPMISerial.1#HandshakeControl
+ false
+
+ Disabled
+ Enabled
+
+
+ IPMI Serial New Line Sequence
+ NewLineSeq
+ CR-LF
+ CR-LF
+
+ 629
+ iDRAC.Embedded.1
+ RAC IPMI Serial
+ IPMISerial.1
+ iDRAC.Embedded.1#IPMISerial.1#NewLineSeq
+ false
+
+ None
+ CR-LF
+ Null
+ CR
+ LF-CR
+ LF
+
+
+ IPMI Serial Input New Line Sequence
+ InputNewLineSeq
+ Enter
+ Null
+
+ 630
+ iDRAC.Embedded.1
+ RAC IPMI Serial
+ IPMISerial.1
+ iDRAC.Embedded.1#IPMISerial.1#InputNewLineSeq
+ false
+
+ Enter
+ Null
+
+
+ IPMI SOL Enable
+ Enable
+ Disabled
+ Enabled
+
+ 641
+ iDRAC.Embedded.1
+ IPMI SOL
+ IPMISOL.1
+ iDRAC.Embedded.1#IPMISOL.1#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ IPMI SOL Baud Rate
+ BaudRate
+ 115200
+ 115200
+
+ 642
+ iDRAC.Embedded.1
+ IPMI SOL
+ IPMISOL.1
+ iDRAC.Embedded.1#IPMISOL.1#BaudRate
+ false
+
+ 9600
+ 19200
+ 57600
+ 115200
+
+
+ IPMI SOL Min Privilege
+ MinPrivilege
+ Administrator
+ Administrator
+
+ 643
+ iDRAC.Embedded.1
+ IPMI SOL
+ IPMISOL.1
+ iDRAC.Embedded.1#IPMISOL.1#MinPrivilege
+ false
+
+ User
+ Operator
+ Administrator
+
+
+ SNMP Agent Enable
+ AgentEnable
+ Enabled
+ Enabled
+
+ 701
+ iDRAC.Embedded.1
+ SNMP Configuration
+ SNMP.1
+ iDRAC.Embedded.1#SNMP.1#AgentEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SNMP Trap Format
+ TrapFormat
+ SNMPv1
+ SNMPv1
+
+ 703
+ iDRAC.Embedded.1
+ SNMP Configuration
+ SNMP.1
+ iDRAC.Embedded.1#SNMP.1#TrapFormat
+ false
+
+ SNMPv1
+ SNMPv2
+ SNMPv3
+
+
+ SNMP Protocol
+ SNMPProtocol
+ All
+ All
+
+ 704
+ iDRAC.Embedded.1
+ SNMP Configuration
+ SNMP.1
+ iDRAC.Embedded.1#SNMP.1#SNMPProtocol
+ false
+
+ All
+ SNMPv3
+
+
+ RAC Virtual Media Attached
+ Attached
+ AutoAttach
+ AutoAttach
+
+ 711
+ iDRAC.Embedded.1
+ Virtual Media
+ VirtualMedia.1
+ iDRAC.Embedded.1#VirtualMedia.1#Attached
+ false
+
+ Detached
+ Attached
+ AutoAttach
+
+
+ Virtual Media Boot Once
+ BootOnce
+ Disabled
+ Disabled
+
+ 712
+ iDRAC.Embedded.1
+ Virtual Media
+ VirtualMedia.1
+ iDRAC.Embedded.1#VirtualMedia.1#BootOnce
+ false
+
+ Disabled
+ Enabled
+
+
+ Virtual Media Key Enable
+ KeyEnable
+ Disabled
+ Disabled
+
+ 713
+ iDRAC.Embedded.1
+ Virtual Media
+ VirtualMedia.1
+ iDRAC.Embedded.1#VirtualMedia.1#KeyEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ Virtual Media Floppy Emulation
+ FloppyEmulation
+ Disabled
+ Disabled
+
+ 714
+ iDRAC.Embedded.1
+ Virtual Media
+ VirtualMedia.1
+ iDRAC.Embedded.1#VirtualMedia.1#FloppyEmulation
+ false
+
+ Disabled
+ Enabled
+
+
+ Virtual Media Encrypt Enable
+ EncryptEnable
+ None
+ AES
+
+ 715
+ iDRAC.Embedded.1
+ Virtual Media
+ VirtualMedia.1
+ iDRAC.Embedded.1#VirtualMedia.1#EncryptEnable
+ false
+
+ None
+ AES
+
+
+ Enable
+ Enable
+ Enabled
+ Enabled
+
+ 716
+ iDRAC.Embedded.1
+ Virtual Media
+ VirtualMedia.1
+ iDRAC.Embedded.1#VirtualMedia.1#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ Tune IP Range Enable
+ RangeEnable
+ Disabled
+ Disabled
+
+ 721
+ iDRAC.Embedded.1
+ IP Blocking
+ IPBlocking.1
+ iDRAC.Embedded.1#IPBlocking.1#RangeEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ Tune IP Block Enable
+ BlockEnable
+ Enabled
+ Enabled
+
+ 724
+ iDRAC.Embedded.1
+ IP Blocking
+ IPBlocking.1
+ iDRAC.Embedded.1#IPBlocking.1#BlockEnable
+ true
+
+ Disabled
+ Enabled
+
+
+ Preboot Config
+ PrebootConfig
+ Disabled
+ Disabled
+
+ 741
+ iDRAC.Embedded.1
+ Local Security
+ LocalSecurity.1
+ iDRAC.Embedded.1#LocalSecurity.1#PrebootConfig
+ false
+
+ Disabled
+ Enabled
+
+
+ Local Config
+ LocalConfig
+ Disabled
+ Disabled
+
+ 742
+ iDRAC.Embedded.1
+ Local Security
+ LocalSecurity.1
+ iDRAC.Embedded.1#LocalSecurity.1#LocalConfig
+ false
+
+ Disabled
+ Enabled
+
+
+ CSR Key Size
+ CsrKeySize
+ 2048
+ 2048
+
+ 768
+ iDRAC.Embedded.1
+ RAC Certificate
+ Security.1
+ iDRAC.Embedded.1#Security.1#CsrKeySize
+ false
+
+ 1024
+ 2048
+ 4096
+
+
+ FIPS Mode
+ FIPSMode
+ Disabled
+ Disabled
+
+ 769
+ iDRAC.Embedded.1
+ RAC Certificate
+ Security.1
+ iDRAC.Embedded.1#Security.1#FIPSMode
+ false
+
+ Enabled
+ Disabled
+
+
+ Enable LDAP
+ Enable
+ Disabled
+ Disabled
+
+ 1081
+ iDRAC.Embedded.1
+ LDAP
+ LDAP.1
+ iDRAC.Embedded.1#LDAP.1#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ LDAP Group Attribute Is Domain Name
+ GroupAttributeIsDN
+ Enabled
+ Enabled
+
+ 1087
+ iDRAC.Embedded.1
+ LDAP
+ LDAP.1
+ iDRAC.Embedded.1#LDAP.1#GroupAttributeIsDN
+ false
+
+ Disabled
+ Enabled
+
+
+ Enable LDAP Certificate Validation
+ CertValidationEnable
+ Enabled
+ Enabled
+
+ 1091
+ iDRAC.Embedded.1
+ LDAP
+ LDAP.1
+ iDRAC.Embedded.1#LDAP.1#CertValidationEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ Active Directory Enable
+ Enable
+ Disabled
+ Disabled
+
+ 771
+ iDRAC.Embedded.1
+ Active Directory
+ ActiveDirectory.1
+ iDRAC.Embedded.1#ActiveDirectory.1#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ Active Directory Schema Type
+ Schema
+ Extended Schema
+ Extended Schema
+
+ 775
+ iDRAC.Embedded.1
+ Active Directory
+ ActiveDirectory.1
+ iDRAC.Embedded.1#ActiveDirectory.1#Schema
+ false
+
+ Extended Schema
+ Standard Schema
+
+
+ Certificate Validation Enable
+ CertValidationEnable
+ Disabled
+ Disabled
+
+ 782
+ iDRAC.Embedded.1
+ Active Directory
+ ActiveDirectory.1
+ iDRAC.Embedded.1#ActiveDirectory.1#CertValidationEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SSO Enable
+ SSOEnable
+ Disabled
+ Disabled
+
+ 1063
+ iDRAC.Embedded.1
+ Active Directory
+ ActiveDirectory.1
+ iDRAC.Embedded.1#ActiveDirectory.1#SSOEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ Global Catalog Server Lookup Enable
+ GCLookupEnable
+ Disabled
+ Disabled
+
+ 784
+ iDRAC.Embedded.1
+ Active Directory
+ ActiveDirectory.1
+ iDRAC.Embedded.1#ActiveDirectory.1#GCLookupEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ Domain Controller Lookup Enable
+ DCLookupEnable
+ Disabled
+ Disabled
+
+ 785
+ iDRAC.Embedded.1
+ Active Directory
+ ActiveDirectory.1
+ iDRAC.Embedded.1#ActiveDirectory.1#DCLookupEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ Domain Controller Lookup By User Domain
+ DCLookupByUserDomain
+ Enabled
+ Enabled
+
+ 788
+ iDRAC.Embedded.1
+ Active Directory
+ ActiveDirectory.1
+ iDRAC.Embedded.1#ActiveDirectory.1#DCLookupByUserDomain
+ false
+
+ Disabled
+ Enabled
+
+
+ Smart Card Logon Enable
+ SmartCardLogonEnable
+ Disabled
+ Disabled
+
+ 1061
+ iDRAC.Embedded.1
+ Smart Card Configuration
+ SmartCard.1
+ iDRAC.Embedded.1#SmartCard.1#SmartCardLogonEnable
+ false
+
+ Disabled
+ Enabled
+ Enabled With Racadm
+
+
+ Smart Card CRL Enable
+ SmartCardCRLEnable
+ Disabled
+ Disabled
+
+ 1062
+ iDRAC.Embedded.1
+ Smart Card Configuration
+ SmartCard.1
+ iDRAC.Embedded.1#SmartCard.1#SmartCardCRLEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ Sys Log Enable
+ SysLogEnable
+ Disabled
+ Disabled
+
+ 1071
+ iDRAC.Embedded.1
+ Sys Log
+ SysLog.1
+ iDRAC.Embedded.1#SysLog.1#SysLogEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ Power Log Enable
+ PowerLogEnable
+ Disabled
+ Disabled
+
+ 1076
+ iDRAC.Embedded.1
+ Sys Log
+ SysLog.1
+ iDRAC.Embedded.1#SysLog.1#PowerLogEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ State
+ State
+ Disabled
+ Disabled
+
+ 1152
+ iDRAC.Embedded.1
+ SNMP Trap IPv6
+ SNMPTrapIPv6.1
+ iDRAC.Embedded.1#SNMPTrapIPv6.1#State
+ false
+
+ Disabled
+ Enabled
+
+
+ State
+ State
+ Disabled
+ Disabled
+
+ 1162
+ iDRAC.Embedded.1
+ SNMP Trap IPv6
+ SNMPTrapIPv6.2
+ iDRAC.Embedded.1#SNMPTrapIPv6.2#State
+ false
+
+ Disabled
+ Enabled
+
+
+ State
+ State
+ Disabled
+ Disabled
+
+ 1172
+ iDRAC.Embedded.1
+ SNMP Trap IPv6
+ SNMPTrapIPv6.3
+ iDRAC.Embedded.1#SNMPTrapIPv6.3#State
+ false
+
+ Disabled
+ Enabled
+
+
+ State
+ State
+ Disabled
+ Disabled
+
+ 1182
+ iDRAC.Embedded.1
+ SNMP Trap IPv6
+ SNMPTrapIPv6.4
+ iDRAC.Embedded.1#SNMPTrapIPv6.4#State
+ false
+
+ Disabled
+ Enabled
+
+
+ State
+ State
+ Disabled
+ Disabled
+
+ 1192
+ iDRAC.Embedded.1
+ SNMP Trap IPv4
+ SNMPTrapIPv4.1
+ iDRAC.Embedded.1#SNMPTrapIPv4.1#State
+ false
+
+ Disabled
+ Enabled
+
+
+ State
+ State
+ Disabled
+ Disabled
+
+ 1202
+ iDRAC.Embedded.1
+ SNMP Trap IPv4
+ SNMPTrapIPv4.2
+ iDRAC.Embedded.1#SNMPTrapIPv4.2#State
+ false
+
+ Disabled
+ Enabled
+
+
+ State
+ State
+ Disabled
+ Disabled
+
+ 1212
+ iDRAC.Embedded.1
+ SNMP Trap IPv4
+ SNMPTrapIPv4.3
+ iDRAC.Embedded.1#SNMPTrapIPv4.3#State
+ false
+
+ Disabled
+ Enabled
+
+
+ State
+ State
+ Disabled
+ Disabled
+
+ 1222
+ iDRAC.Embedded.1
+ SNMP Trap IPv4
+ SNMPTrapIPv4.4
+ iDRAC.Embedded.1#SNMPTrapIPv4.4#State
+ false
+
+ Disabled
+ Enabled
+
+
+ Media Attach State
+ MediaAttachState
+ Detached
+ Detached
+
+ 1232
+ iDRAC.Embedded.1
+ Remote File Share
+ RFS.1
+ iDRAC.Embedded.1#RFS.1#MediaAttachState
+ true
+
+ Attached
+ Detached
+
+
+ iDRAC Remote File Share Write protected
+ WriteProtected
+ Read Only
+ Read Only
+
+ 1234
+ iDRAC.Embedded.1
+ Remote File Share
+ RFS.1
+ iDRAC.Embedded.1#RFS.1#WriteProtected
+ true
+
+ Read Only
+ Read Write
+
+
+ OS-BMC Pass Through Capability
+ PTCapability
+ Capable
+ Not Capable
+
+ 1240
+ iDRAC.Embedded.1
+ OS-BMC Passthru Configuration
+ OS-BMC.1
+ iDRAC.Embedded.1#OS-BMC.1#PTCapability
+ true
+
+ Not Capable
+ Capable
+ Unavailable
+
+
+ LC and Host Private Channel State
+ AdminState
+ Disabled
+ Disabled
+
+ 1241
+ iDRAC.Embedded.1
+ OS-BMC Passthru Configuration
+ OS-BMC.1
+ iDRAC.Embedded.1#OS-BMC.1#AdminState
+ false
+
+ Disabled
+ Enabled
+
+
+ OS-BMC PT Mode
+ PTMode
+ usb-p2p
+ usb-p2p
+
+ 1244
+ iDRAC.Embedded.1
+ OS-BMC Passthru Configuration
+ OS-BMC.1
+ iDRAC.Embedded.1#OS-BMC.1#PTMode
+ false
+
+ lom-p2p
+ usb-p2p
+
+
+ State
+ State
+ Disabled
+ Disabled
+
+ 1602
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.1
+ iDRAC.Embedded.1#SNMPAlert.1#State
+ false
+
+ Disabled
+ Enabled
+
+
+ State
+ State
+ Disabled
+ Disabled
+
+ 1604
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.2
+ iDRAC.Embedded.1#SNMPAlert.2#State
+ false
+
+ Disabled
+ Enabled
+
+
+ State
+ State
+ Disabled
+ Disabled
+
+ 1606
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.3
+ iDRAC.Embedded.1#SNMPAlert.3#State
+ false
+
+ Disabled
+ Enabled
+
+
+ State
+ State
+ Disabled
+ Disabled
+
+ 1608
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.4
+ iDRAC.Embedded.1#SNMPAlert.4#State
+ false
+
+ Disabled
+ Enabled
+
+
+ State
+ State
+ Disabled
+ Disabled
+
+ 1610
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.5
+ iDRAC.Embedded.1#SNMPAlert.5#State
+ false
+
+ Disabled
+ Enabled
+
+
+ State
+ State
+ Disabled
+ Disabled
+
+ 1612
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.6
+ iDRAC.Embedded.1#SNMPAlert.6#State
+ false
+
+ Disabled
+ Enabled
+
+
+ State
+ State
+ Disabled
+ Disabled
+
+ 1614
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.7
+ iDRAC.Embedded.1#SNMPAlert.7#State
+ false
+
+ Disabled
+ Enabled
+
+
+ State
+ State
+ Disabled
+ Disabled
+
+ 1616
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.8
+ iDRAC.Embedded.1#SNMPAlert.8#State
+ false
+
+ Disabled
+ Enabled
+
+
+ Default Credential Mitigation
+ DefaultCredentialMitigation
+ Enabled
+ Enabled
+
+ 1700
+ iDRAC.Embedded.1
+ Default Credential Mitigation Configuration
+ DefaultCredentialMitigationConfigGroup.1
+ iDRAC.Embedded.1#DefaultCredentialMitigationConfigGroup.1#DefaultCredentialMitigation
+ false
+
+ Disabled
+ Enabled
+
+
+ Auto OS Lock State
+ AutoOSLockState
+ Enabled
+ Enabled
+
+ 1500
+ iDRAC.Embedded.1
+ Automatic OS Lock Group
+ AutoOSLockGroup.1
+ iDRAC.Embedded.1#AutoOSLockGroup.1#AutoOSLockState
+ false
+
+ Disabled
+ Enabled
+
+
+ NTP Enable
+ NTPEnable
+ Disabled
+ Disabled
+
+ 2004
+ iDRAC.Embedded.1
+ NTP Configuration Group
+ NTPConfigGroup.1
+ iDRAC.Embedded.1#NTPConfigGroup.1#NTPEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ SEL OEM Event Filter Enable
+ SELOEMEventFilterEnable
+ Disabled
+ Disabled
+
+ 2130
+ iDRAC.Embedded.1
+ iDRAC Logging
+ Logging.1
+ iDRAC.Embedded.1#Logging.1#SELOEMEventFilterEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ IOIDOpt Enable
+ IOIDOptEnable
+ Disabled
+ Disabled
+
+ 2140
+ iDRAC.Embedded.1
+ IO Identity Optimization
+ IOIDOpt.1
+ iDRAC.Embedded.1#IOIDOpt.1#IOIDOptEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ Virtual Address Persistence Policy Non Auxiliary Powered
+ VirtualAddressPersistencePolicyNonAuxPwrd
+ WarmReset
+ WarmReset
+
+ 2141
+ iDRAC.Embedded.1
+ IO Identity Optimization
+ IOIDOpt.1
+ iDRAC.Embedded.1#IOIDOpt.1#VirtualAddressPersistencePolicyNonAuxPwrd
+ false
+
+ None
+ WarmReset
+ ColdReset
+ WarmReset, ColdReset
+ ACPowerLoss
+ WarmReset, ACPowerLoss
+ ColdReset, ACPowerLoss
+ WarmReset, ColdReset, ACPowerLoss
+
+
+ Virtual Address Persistence Policy Auxiliary Powered
+ VirtualAddressPersistencePolicyAuxPwrd
+ WarmReset, ColdReset
+ WarmReset, ColdReset
+
+ 2142
+ iDRAC.Embedded.1
+ IO Identity Optimization
+ IOIDOpt.1
+ iDRAC.Embedded.1#IOIDOpt.1#VirtualAddressPersistencePolicyAuxPwrd
+ false
+
+ None
+ WarmReset
+ ColdReset
+ WarmReset, ColdReset
+ ACPowerLoss
+ WarmReset, ACPowerLoss
+ ColdReset, ACPowerLoss
+ WarmReset, ColdReset, ACPowerLoss
+
+
+ Initiator Persistence Policy
+ InitiatorPersistencePolicy
+ WarmReset, ColdReset, ACPowerLoss
+ WarmReset, ColdReset, ACPowerLoss
+
+ 2143
+ iDRAC.Embedded.1
+ IO Identity Optimization
+ IOIDOpt.1
+ iDRAC.Embedded.1#IOIDOpt.1#InitiatorPersistencePolicy
+ false
+
+ None
+ WarmReset
+ ColdReset
+ WarmReset, ColdReset
+ ACPowerLoss
+ WarmReset, ACPowerLoss
+ ColdReset, ACPowerLoss
+ WarmReset, ColdReset, ACPowerLoss
+
+
+ Storage Target Persistence Policy
+ StorageTargetPersistencePolicy
+ WarmReset, ColdReset, ACPowerLoss
+ WarmReset, ColdReset, ACPowerLoss
+
+ 2144
+ iDRAC.Embedded.1
+ IO Identity Optimization
+ IOIDOpt.1
+ iDRAC.Embedded.1#IOIDOpt.1#StorageTargetPersistencePolicy
+ false
+
+ None
+ WarmReset
+ ColdReset
+ WarmReset, ColdReset
+ ACPowerLoss
+ WarmReset, ACPowerLoss
+ ColdReset, ACPowerLoss
+ WarmReset, ColdReset, ACPowerLoss
+
+
+ OMSA Presence on Host
+ OMSAPresence
+ NA
+ NA
+
+ 2150
+ iDRAC.Embedded.1
+ ServiceModule
+ ServiceModule.1
+ iDRAC.Embedded.1#ServiceModule.1#OMSAPresence
+ true
+
+ Not Present
+ Present
+ NA
+
+
+ Sharing of OS Information via ServiceModule
+ OSInfo
+ Enabled
+ Enabled
+
+ 2151
+ iDRAC.Embedded.1
+ ServiceModule
+ ServiceModule.1
+ iDRAC.Embedded.1#ServiceModule.1#OSInfo
+ false
+
+ Disabled
+ Enabled
+
+
+ Watchdog timer via ServiceModule
+ WatchdogState
+ Disabled
+ Disabled
+
+ 2152
+ iDRAC.Embedded.1
+ ServiceModule
+ ServiceModule.1
+ iDRAC.Embedded.1#ServiceModule.1#WatchdogState
+ false
+
+ Disabled
+ Enabled
+
+
+ Recovery action on watchdog alert
+ WatchdogRecoveryAction
+ None
+ None
+
+ 2154
+ iDRAC.Embedded.1
+ ServiceModule
+ ServiceModule.1
+ iDRAC.Embedded.1#ServiceModule.1#WatchdogRecoveryAction
+ false
+
+ None
+ Reboot
+ Poweroff
+ Powercycle
+
+
+ LCL replication in OS Log
+ LCLReplication
+ Disabled
+ Disabled
+
+ 2156
+ iDRAC.Embedded.1
+ ServiceModule
+ ServiceModule.1
+ iDRAC.Embedded.1#ServiceModule.1#LCLReplication
+ false
+
+ Disabled
+ Enabled
+
+
+ Populate WMI information via ServiceModule
+ WMIInfo
+ Disabled
+ Disabled
+
+ 2157
+ iDRAC.Embedded.1
+ ServiceModule
+ ServiceModule.1
+ iDRAC.Embedded.1#ServiceModule.1#WMIInfo
+ false
+
+ Disabled
+ Enabled
+
+
+ ServiceModule Enable
+ ServiceModuleEnable
+ Enabled
+ Enabled
+
+ 2159
+ iDRAC.Embedded.1
+ ServiceModule
+ ServiceModule.1
+ iDRAC.Embedded.1#ServiceModule.1#ServiceModuleEnable
+ false
+
+ Disabled
+ Enabled
+
+
+ ServiceModule service state on host
+ ServiceModuleState
+ Not Running
+ Not Running
+
+ 2160
+ iDRAC.Embedded.1
+ ServiceModule
+ ServiceModule.1
+ iDRAC.Embedded.1#ServiceModule.1#ServiceModuleState
+ true
+
+ Not Running
+ Running
+
+
+ iDRAC Hard Reset
+ iDRACHardReset
+ Enabled
+ Enabled
+
+ 2222
+ iDRAC.Embedded.1
+ ServiceModule
+ ServiceModule.1
+ iDRAC.Embedded.1#ServiceModule.1#iDRACHardReset
+ false
+
+ Disabled
+ Enabled
+
+
+ Enable
+ Enable
+ Disabled
+ Disabled
+
+ 2162
+ iDRAC.Embedded.1
+ RAC VNC Server
+ VNCServer.1
+ iDRAC.Embedded.1#VNCServer.1#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ LowerEncryptionBitLength
+ LowerEncryptionBitLength
+ Disabled
+ Disabled
+
+ 2165
+ iDRAC.Embedded.1
+ RAC VNC Server
+ VNCServer.1
+ iDRAC.Embedded.1#VNCServer.1#LowerEncryptionBitLength
+ false
+
+ Disabled
+ Enabled
+
+
+ SSL Encryption Bit Length
+ SSLEncryptionBitLength
+ Disabled
+ Disabled
+
+ 2167
+ iDRAC.Embedded.1
+ RAC VNC Server
+ VNCServer.1
+ iDRAC.Embedded.1#VNCServer.1#SSLEncryptionBitLength
+ false
+
+ Disabled
+ Auto Negotiate
+ 128-Bit or higher
+ 168-Bit or higher
+ 256-Bit or higher
+
+
+ Enable
+ Enable
+ Disabled
+ Disabled
+
+ 2174
+ iDRAC.Embedded.1
+ vFlash
+ vFlashSD.1
+ iDRAC.Embedded.1#vFlashSD.1#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ Boot Once
+ BootOnce
+ Enabled
+ Enabled
+
+ 2191
+ iDRAC.Embedded.1
+ Server Boot
+ ServerBoot.1
+ iDRAC.Embedded.1#ServerBoot.1#BootOnce
+ false
+
+ Enabled
+ Disabled
+
+
+ Management Port Mode
+ ManagementPortMode
+ Automatic
+ Automatic
+
+ 2200
+ iDRAC.Embedded.1
+ USB Management
+ USB.1
+ iDRAC.Embedded.1#USB.1#ManagementPortMode
+ false
+
+ Automatic
+ Standard OS Use
+ iDRAC Direct Only
+
+
+ Configuration XML
+ ConfigurationXML
+ Enabled while server has default credential settings only
+ Enabled while server has default credential settings only
+
+ 2201
+ iDRAC.Embedded.1
+ USB Management
+ USB.1
+ iDRAC.Embedded.1#USB.1#ConfigurationXML
+ false
+
+ Disabled
+ Enabled while server has default credential settings only
+ Enabled
+
+
+ Port Status
+ PortStatus
+ Enabled
+ Enabled
+
+ 2202
+ iDRAC.Embedded.1
+ USB Management
+ USB.1
+ iDRAC.Embedded.1#USB.1#PortStatus
+ true
+
+ Disabled
+ Enabled
+
+
+ Enable
+ Enable
+ Disabled
+ Disabled
+
+ 2221
+ iDRAC.Embedded.1
+ ASR Config
+ ASRConfig.1
+ iDRAC.Embedded.1#ASRConfig.1#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+ Custom UI
+ CustomUI
+ DefaultUI
+ DefaultUI
+
+ 2222
+ iDRAC.Embedded.1
+ DCS Custom
+ DCSCustom.1
+ iDRAC.Embedded.1#DCSCustom.1#CustomUI
+ false
+
+ DefaultUI
+ Custom UI Enabled
+
+
+ Ignore Certificate Errors
+ IgnoreCertificateErrors
+ Yes
+ Yes
+
+ 2242
+ iDRAC.Embedded.1
+ RedfishEventing
+ RedfishEventing.1
+ iDRAC.Embedded.1#RedfishEventing.1#IgnoreCertificateErrors
+ true
+
+ No
+ Yes
+
+
+ Enable
+ Enable
+ Enabled
+ Enabled
+
+ 2250
+ iDRAC.Embedded.1
+ Redfish
+ Redfish.1
+ iDRAC.Embedded.1#Redfish.1#Enable
+ false
+
+ Disabled
+ Enabled
+
+
+
+
+
+
+
diff --git a/dracclient/tests/wsman_mocks/idraccard_integer-enum-ok.xml b/dracclient/tests/wsman_mocks/idraccard_integer-enum-ok.xml
new file mode 100644
index 0000000..906b031
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/idraccard_integer-enum-ok.xml
@@ -0,0 +1,1397 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse
+ uuid:1b114e09-e635-4ad9-90dd-3045421499a7
+ uuid:a92483bc-40aa-10aa-8221-de7e4e771814
+
+
+
+
+
+ NIC MTU
+ MTU
+ 1500
+ 1500
+
+ 58
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#MTU
+ false
+ 576
+
+ 1500
+
+
+ VLAN Priority
+ VLanPriority
+ 0
+ 0
+
+ 64
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#VLanPriority
+ false
+ 0
+
+ 7
+
+
+ VLAN ID
+ VLanID
+ 1
+ 1
+
+ 65
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#VLanID
+ false
+ 1
+
+ 4096
+
+
+ Shared to Dedicated Failover Timeout
+ DedicatedNICScanTime
+ 5
+ 5
+
+ 67
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#DedicatedNICScanTime
+ false
+ 5
+
+ 255
+
+
+ Dedicated to Shared Failover Timeout
+ SharedNICScanTime
+ 30
+ 30
+
+ 68
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#SharedNICScanTime
+ false
+ 5
+
+ 255
+
+
+ IPV6 Link Local Prefix Length
+ PrefixLength
+ 64
+ 64
+
+ 157
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#PrefixLength
+ false
+ 1
+
+ 128
+
+
+ Total Number of Extended IP
+ IPV6NumOfExtAddress
+ 0
+ 0
+
+ 160
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#IPV6NumOfExtAddress
+ true
+ 0
+
+ 255
+
+
+ IPV6 Link Local Prefix Length
+ PrefixLength
+ 64
+ 64
+
+ 193
+ iDRAC.Embedded.1
+ IPv6 Static Information
+ IPv6Static.1
+ iDRAC.Embedded.1#IPv6Static.1#PrefixLength
+ false
+ 1
+
+ 128
+
+
+ User Admin Privilege
+ Privilege
+ 0
+ 0
+
+ 253
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.1
+ iDRAC.Embedded.1#Users.1#Privilege
+ true
+ 0
+
+ 511
+
+
+ User Admin Privilege
+ Privilege
+ 511
+ 511
+
+ 263
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.2
+ iDRAC.Embedded.1#Users.2#Privilege
+ false
+ 0
+
+ 511
+
+
+ User Admin Privilege
+ Privilege
+ 0
+ 0
+
+ 273
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.3
+ iDRAC.Embedded.1#Users.3#Privilege
+ false
+ 0
+
+ 511
+
+
+ User Admin Privilege
+ Privilege
+ 313
+ 0
+
+ 283
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.4
+ iDRAC.Embedded.1#Users.4#Privilege
+ false
+ 0
+
+ 511
+
+
+ User Admin Privilege
+ Privilege
+ 0
+ 0
+
+ 293
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.5
+ iDRAC.Embedded.1#Users.5#Privilege
+ false
+ 0
+
+ 511
+
+
+ User Admin Privilege
+ Privilege
+ 0
+ 0
+
+ 303
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.6
+ iDRAC.Embedded.1#Users.6#Privilege
+ false
+ 0
+
+ 511
+
+
+ User Admin Privilege
+ Privilege
+ 0
+ 0
+
+ 313
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.7
+ iDRAC.Embedded.1#Users.7#Privilege
+ false
+ 0
+
+ 511
+
+
+ User Admin Privilege
+ Privilege
+ 0
+ 0
+
+ 323
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.8
+ iDRAC.Embedded.1#Users.8#Privilege
+ false
+ 0
+
+ 511
+
+
+ User Admin Privilege
+ Privilege
+ 0
+ 0
+
+ 333
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.9
+ iDRAC.Embedded.1#Users.9#Privilege
+ false
+ 0
+
+ 511
+
+
+ User Admin Privilege
+ Privilege
+ 0
+ 0
+
+ 343
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.10
+ iDRAC.Embedded.1#Users.10#Privilege
+ false
+ 0
+
+ 511
+
+
+ User Admin Privilege
+ Privilege
+ 0
+ 0
+
+ 353
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.11
+ iDRAC.Embedded.1#Users.11#Privilege
+ false
+ 0
+
+ 511
+
+
+ User Admin Privilege
+ Privilege
+ 0
+ 0
+
+ 363
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.12
+ iDRAC.Embedded.1#Users.12#Privilege
+ false
+ 0
+
+ 511
+
+
+ User Admin Privilege
+ Privilege
+ 0
+ 0
+
+ 373
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.13
+ iDRAC.Embedded.1#Users.13#Privilege
+ false
+ 0
+
+ 511
+
+
+ User Admin Privilege
+ Privilege
+ 0
+ 0
+
+ 383
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.14
+ iDRAC.Embedded.1#Users.14#Privilege
+ false
+ 0
+
+ 511
+
+
+ User Admin Privilege
+ Privilege
+ 0
+ 0
+
+ 393
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.15
+ iDRAC.Embedded.1#Users.15#Privilege
+ false
+ 0
+
+ 511
+
+
+ User Admin Privilege
+ Privilege
+ 0
+ 0
+
+ 403
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.16
+ iDRAC.Embedded.1#Users.16#Privilege
+ false
+ 0
+
+ 511
+
+
+ SMTP Port
+ SMTPPort
+ 25
+ 25
+
+ 542
+ iDRAC.Embedded.1
+ RAC Remote Hosts
+ RemoteHosts.1
+ iDRAC.Embedded.1#RemoteHosts.1#SMTPPort
+ false
+ 1
+
+ 65535
+
+
+ Telnet Port
+ Port
+ 23
+ 23
+
+ 552
+ iDRAC.Embedded.1
+ Telnet Configuration
+ Telnet.1
+ iDRAC.Embedded.1#Telnet.1#Port
+ false
+ 1
+
+ 65535
+
+
+ Timeout
+ Timeout
+ 1800
+ 1800
+
+ 553
+ iDRAC.Embedded.1
+ Telnet Configuration
+ Telnet.1
+ iDRAC.Embedded.1#Telnet.1#Timeout
+ false
+ 60
+
+ 10800
+
+
+ SSH Port
+ Port
+ 22
+ 22
+
+ 562
+ iDRAC.Embedded.1
+ RAC SSH
+ SSH.1
+ iDRAC.Embedded.1#SSH.1#Port
+ false
+ 1
+
+ 65535
+
+
+ SSH Idle Timeout
+ Timeout
+ 1800
+ 1800
+
+ 563
+ iDRAC.Embedded.1
+ RAC SSH
+ SSH.1
+ iDRAC.Embedded.1#SSH.1#Timeout
+ false
+ 60
+
+ 10800
+
+
+ Http Port
+ HttpPort
+ 80
+ 80
+
+ 572
+ iDRAC.Embedded.1
+ RAC Web Server
+ WebServer.1
+ iDRAC.Embedded.1#WebServer.1#HttpPort
+ false
+ 1
+
+ 65535
+
+
+ Https Port
+ HttpsPort
+ 443
+ 443
+
+ 573
+ iDRAC.Embedded.1
+ RAC Web Server
+ WebServer.1
+ iDRAC.Embedded.1#WebServer.1#HttpsPort
+ false
+ 1
+
+ 65535
+
+
+ Timeout
+ Timeout
+ 1800
+ 1800
+
+ 574
+ iDRAC.Embedded.1
+ RAC Web Server
+ WebServer.1
+ iDRAC.Embedded.1#WebServer.1#Timeout
+ false
+ 60
+
+ 10800
+
+
+ Max Number Of Sessions
+ MaxNumberOfSessions
+ 8
+ 8
+
+ 578
+ iDRAC.Embedded.1
+ RAC Web Server
+ WebServer.1
+ iDRAC.Embedded.1#WebServer.1#MaxNumberOfSessions
+ true
+ 1
+
+ 8
+
+
+ Max Sessions
+ MaxSessions
+ 6
+ 6
+
+ 585
+ iDRAC.Embedded.1
+ Virtual Console Configuration
+ VirtualConsole.1
+ iDRAC.Embedded.1#VirtualConsole.1#MaxSessions
+ false
+ 1
+
+ 6
+
+
+ vKVM Port
+ Port
+ 5900
+ 5900
+
+ 586
+ iDRAC.Embedded.1
+ Virtual Console Configuration
+ VirtualConsole.1
+ iDRAC.Embedded.1#VirtualConsole.1#Port
+ false
+ 1
+
+ 65535
+
+
+ Timeout
+ Timeout
+ 1800
+ 1800
+
+ 587
+ iDRAC.Embedded.1
+ Virtual Console Configuration
+ VirtualConsole.1
+ iDRAC.Embedded.1#VirtualConsole.1#Timeout
+ false
+ 60
+
+ 10800
+
+
+ Remote Timeout
+ Timeout
+ 60
+ 60
+
+ 592
+ iDRAC.Embedded.1
+ Remote Racadm Configuration
+ Racadm.1
+ iDRAC.Embedded.1#Racadm.1#Timeout
+ false
+ 10
+
+ 1920
+
+
+ Serial Console Idle Timeout
+ IdleTimeout
+ 300
+ 300
+
+ 603
+ iDRAC.Embedded.1
+ Serial Configuration
+ Serial.1
+ iDRAC.Embedded.1#Serial.1#IdleTimeout
+ false
+ 60
+
+ 1920
+
+
+ Serial History Size
+ HistorySize
+ 8192
+ 8192
+
+ 605
+ iDRAC.Embedded.1
+ Serial Configuration
+ Serial.1
+ iDRAC.Embedded.1#Serial.1#HistorySize
+ false
+ 0
+
+ 8192
+
+
+ IPMI SOL Accumulate Interval
+ AccumulateInterval
+ 10
+ 10
+
+ 644
+ iDRAC.Embedded.1
+ IPMI SOL
+ IPMISOL.1
+ iDRAC.Embedded.1#IPMISOL.1#AccumulateInterval
+ false
+ 1
+
+ 255
+
+
+ IPMI SOL Send Threshold
+ SendThreshold
+ 255
+ 255
+
+ 645
+ iDRAC.Embedded.1
+ IPMI SOL
+ IPMISOL.1
+ iDRAC.Embedded.1#IPMISOL.1#SendThreshold
+ false
+ 1
+
+ 255
+
+
+ IPMI SOL Retry Count
+ RetryCount
+ 7
+ 255
+
+ 646
+ iDRAC.Embedded.1
+ IPMI SOL
+ IPMISOL.1
+ iDRAC.Embedded.1#IPMISOL.1#RetryCount
+ true
+ 1
+
+ 255
+
+
+ IPMI SOL Retry Interval
+ RetryInterval
+ 48
+ 255
+
+ 647
+ iDRAC.Embedded.1
+ IPMI SOL
+ IPMISOL.1
+ iDRAC.Embedded.1#IPMISOL.1#RetryInterval
+ true
+ 1
+
+ 255
+
+
+ Discovery Port
+ DiscoveryPort
+ 161
+ 161
+
+ 705
+ iDRAC.Embedded.1
+ SNMP Configuration
+ SNMP.1
+ iDRAC.Embedded.1#SNMP.1#DiscoveryPort
+ false
+ 1
+
+ 65535
+
+
+ Alert Port
+ AlertPort
+ 162
+ 162
+
+ 706
+ iDRAC.Embedded.1
+ SNMP Configuration
+ SNMP.1
+ iDRAC.Embedded.1#SNMP.1#AlertPort
+ false
+ 1
+
+ 65535
+
+
+ Tune IP Block Fail Count
+ FailCount
+ 3
+ 3
+
+ 731
+ iDRAC.Embedded.1
+ IP Blocking
+ IPBlocking.1
+ iDRAC.Embedded.1#IPBlocking.1#FailCount
+ true
+ 2
+
+ 16
+
+
+ Tune IP Block Fail Window
+ FailWindow
+ 60
+ 60
+
+ 732
+ iDRAC.Embedded.1
+ IP Blocking
+ IPBlocking.1
+ iDRAC.Embedded.1#IPBlocking.1#FailWindow
+ true
+ 10
+
+ 65535
+
+
+ Tune IP Block Penalty Time
+ PenaltyTime
+ 600
+ 600
+
+ 733
+ iDRAC.Embedded.1
+ IP Blocking
+ IPBlocking.1
+ iDRAC.Embedded.1#IPBlocking.1#PenaltyTime
+ true
+ 2
+
+ 65535
+
+
+ Tune Time Zone Offset
+ TimeZoneOffset
+ 0
+ 0
+
+ 751
+ iDRAC.Embedded.1
+ Time Zone Configuration Information
+ Time.1
+ iDRAC.Embedded.1#Time.1#TimeZoneOffset
+ false
+ -43200
+
+ 46800
+
+
+ Tune Day Light Offset
+ DaylightOffset
+ 0
+ 0
+
+ 752
+ iDRAC.Embedded.1
+ Time Zone Configuration Information
+ Time.1
+ iDRAC.Embedded.1#Time.1#DaylightOffset
+ false
+ 0
+
+ 60
+
+
+ LDAP Port
+ Port
+ 636
+ 636
+
+ 1083
+ iDRAC.Embedded.1
+ LDAP
+ LDAP.1
+ iDRAC.Embedded.1#LDAP.1#Port
+ false
+ 1
+
+ 65535
+
+
+ Active Directory Authentication Timeout
+ AuthTimeout
+ 120
+ 120
+
+ 774
+ iDRAC.Embedded.1
+ Active Directory
+ ActiveDirectory.1
+ iDRAC.Embedded.1#ActiveDirectory.1#AuthTimeout
+ false
+ 15
+
+ 300
+
+
+ AD Group Privilege
+ Privilege
+ 0
+ 0
+
+ 803
+ iDRAC.Embedded.1
+ AD Group Configuration
+ ADGroup.1
+ iDRAC.Embedded.1#ADGroup.1#Privilege
+ false
+ 0
+
+ 511
+
+
+ AD Group Privilege
+ Privilege
+ 0
+ 0
+
+ 813
+ iDRAC.Embedded.1
+ AD Group Configuration
+ ADGroup.2
+ iDRAC.Embedded.1#ADGroup.2#Privilege
+ false
+ 0
+
+ 511
+
+
+ AD Group Privilege
+ Privilege
+ 0
+ 0
+
+ 823
+ iDRAC.Embedded.1
+ AD Group Configuration
+ ADGroup.3
+ iDRAC.Embedded.1#ADGroup.3#Privilege
+ false
+ 0
+
+ 511
+
+
+ AD Group Privilege
+ Privilege
+ 0
+ 0
+
+ 833
+ iDRAC.Embedded.1
+ ADGroup Configuration
+ ADGroup.4
+ iDRAC.Embedded.1#ADGroup.4#Privilege
+ false
+ 0
+
+ 511
+
+
+ AD Group Privilege
+ Privilege
+ 0
+ 0
+
+ 843
+ iDRAC.Embedded.1
+ ADGroup Configuration
+ ADGroup.5
+ iDRAC.Embedded.1#ADGroup.5#Privilege
+ false
+ 0
+
+ 511
+
+
+ Sys Log Port
+ Port
+ 514
+ 514
+
+ 1072
+ iDRAC.Embedded.1
+ Sys Log
+ SysLog.1
+ iDRAC.Embedded.1#SysLog.1#Port
+ false
+ 1
+
+ 65535
+
+
+ Power Log Interval
+ PowerLogInterval
+ 5
+ 5
+
+ 1077
+ iDRAC.Embedded.1
+ Sys Log
+ SysLog.1
+ iDRAC.Embedded.1#SysLog.1#PowerLogInterval
+ false
+ 1
+
+ 1440
+
+
+ LDAP Group Privilege
+ Privilege
+ 0
+ 0
+
+ 1102
+ iDRAC.Embedded.1
+ LDAP Group
+ LDAPRoleGroup.1
+ iDRAC.Embedded.1#LDAPRoleGroup.1#Privilege
+ false
+ 0
+
+ 511
+
+
+ LDAP Group Privilege
+ Privilege
+ 0
+ 0
+
+ 1112
+ iDRAC.Embedded.1
+ LDAP Group
+ LDAPRoleGroup.2
+ iDRAC.Embedded.1#LDAPRoleGroup.2#Privilege
+ false
+ 0
+
+ 511
+
+
+ LDAP Group Privilege
+ Privilege
+ 0
+ 0
+
+ 1122
+ iDRAC.Embedded.1
+ LDAP Group
+ LDAPRoleGroup.3
+ iDRAC.Embedded.1#LDAPRoleGroup.3#Privilege
+ false
+ 0
+
+ 511
+
+
+ LDAP Group Privilege
+ Privilege
+ 0
+ 0
+
+ 1132
+ iDRAC.Embedded.1
+ LDAP Group
+ LDAPRoleGroup.4
+ iDRAC.Embedded.1#LDAPRoleGroup.4#Privilege
+ false
+ 0
+
+ 511
+
+
+ LDAP Group Privilege
+ Privilege
+ 0
+ 0
+
+ 1142
+ iDRAC.Embedded.1
+ LDAP Group
+ LDAPRoleGroup.5
+ iDRAC.Embedded.1#LDAPRoleGroup.5#Privilege
+ false
+ 0
+
+ 511
+
+
+ Destination Number
+ DestinationNum
+ 1
+ 1
+
+ 1151
+ iDRAC.Embedded.1
+ SNMP Trap IPv6
+ SNMPTrapIPv6.1
+ iDRAC.Embedded.1#SNMPTrapIPv6.1#DestinationNum
+ true
+ 1
+
+ 4
+
+
+ Destination Number
+ DestinationNum
+ 1
+ 1
+
+ 1161
+ iDRAC.Embedded.1
+ SNMP Trap IPv6
+ SNMPTrapIPv6.2
+ iDRAC.Embedded.1#SNMPTrapIPv6.2#DestinationNum
+ true
+ 1
+
+ 4
+
+
+ Destination Number
+ DestinationNum
+ 1
+ 1
+
+ 1171
+ iDRAC.Embedded.1
+ SNMP Trap IPv6
+ SNMPTrapIPv6.3
+ iDRAC.Embedded.1#SNMPTrapIPv6.3#DestinationNum
+ true
+ 1
+
+ 4
+
+
+ Destination Number
+ DestinationNum
+ 1
+ 1
+
+ 1181
+ iDRAC.Embedded.1
+ SNMP Trap IPv6
+ SNMPTrapIPv6.4
+ iDRAC.Embedded.1#SNMPTrapIPv6.4#DestinationNum
+ true
+ 1
+
+ 4
+
+
+ Destination Number
+ DestinationNum
+ 1
+ 1
+
+ 1191
+ iDRAC.Embedded.1
+ SNMP Trap IPv4
+ SNMPTrapIPv4.1
+ iDRAC.Embedded.1#SNMPTrapIPv4.1#DestinationNum
+ true
+ 1
+
+ 4
+
+
+ Destination Number
+ DestinationNum
+ 1
+ 1
+
+ 1201
+ iDRAC.Embedded.1
+ SNMP Trap IPv4
+ SNMPTrapIPv4.2
+ iDRAC.Embedded.1#SNMPTrapIPv4.2#DestinationNum
+ true
+ 1
+
+ 4
+
+
+ Destination Number
+ DestinationNum
+ 1
+ 1
+
+ 1211
+ iDRAC.Embedded.1
+ SNMP Trap IPv4
+ SNMPTrapIPv4.3
+ iDRAC.Embedded.1#SNMPTrapIPv4.3#DestinationNum
+ true
+ 1
+
+ 4
+
+
+ Destination Number
+ DestinationNum
+ 1
+ 1
+
+ 1221
+ iDRAC.Embedded.1
+ SNMP Trap IPv4
+ SNMPTrapIPv4.4
+ iDRAC.Embedded.1#SNMPTrapIPv4.4#DestinationNum
+ true
+ 1
+
+ 4
+
+
+ SNMP V3 UserID
+ SNMPv3UserID
+ 0
+ 0
+
+ 1604
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.1
+ iDRAC.Embedded.1#SNMPAlert.1#SNMPv3UserID
+ true
+ 0
+
+ 16
+
+
+ SNMP V3 UserID
+ SNMPv3UserID
+ 0
+ 0
+
+ 1604
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.2
+ iDRAC.Embedded.1#SNMPAlert.2#SNMPv3UserID
+ true
+ 0
+
+ 16
+
+
+ SNMP V3 UserID
+ SNMPv3UserID
+ 0
+ 0
+
+ 1604
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.3
+ iDRAC.Embedded.1#SNMPAlert.3#SNMPv3UserID
+ true
+ 0
+
+ 16
+
+
+ SNMP V3 UserID
+ SNMPv3UserID
+ 0
+ 0
+
+ 1610
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.4
+ iDRAC.Embedded.1#SNMPAlert.4#SNMPv3UserID
+ true
+ 0
+
+ 16
+
+
+ SNMP V3 UserID
+ SNMPv3UserID
+ 0
+ 0
+
+ 1612
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.5
+ iDRAC.Embedded.1#SNMPAlert.5#SNMPv3UserID
+ true
+ 0
+
+ 16
+
+
+ SNMP V3 UserID
+ SNMPv3UserID
+ 0
+ 0
+
+ 1614
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.6
+ iDRAC.Embedded.1#SNMPAlert.6#SNMPv3UserID
+ true
+ 0
+
+ 16
+
+
+ SNMP V3 UserID
+ SNMPv3UserID
+ 0
+ 0
+
+ 1616
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.7
+ iDRAC.Embedded.1#SNMPAlert.7#SNMPv3UserID
+ true
+ 0
+
+ 16
+
+
+ SNMP V3 UserID
+ SNMPv3UserID
+ 0
+ 0
+
+ 1618
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.8
+ iDRAC.Embedded.1#SNMPAlert.8#SNMPv3UserID
+ true
+ 0
+
+ 16
+
+
+ NTP Maximum Distance
+ NTPMaxDist
+ 16
+ 16
+
+ 2005
+ iDRAC.Embedded.1
+ NTP Configuration Group
+ NTPConfigGroup.1
+ iDRAC.Embedded.1#NTPConfigGroup.1#NTPMaxDist
+ false
+ 1
+
+ 128
+
+
+ System reset time on watchdog alert
+ WatchdogResetTime
+ 480
+ 480
+
+ 2153
+ iDRAC.Embedded.1
+ ServiceModule
+ ServiceModule.1
+ iDRAC.Embedded.1#ServiceModule.1#WatchdogResetTime
+ false
+ 60
+
+ 720
+
+
+ Port
+ Port
+ 5901
+ 5901
+
+ 2164
+ iDRAC.Embedded.1
+ RAC VNC Server
+ VNCServer.1
+ iDRAC.Embedded.1#VNCServer.1#Port
+ false
+ 1024
+
+ 65535
+
+
+ Timeout
+ Timeout
+ 300
+ 300
+
+ 2166
+ iDRAC.Embedded.1
+ RAC VNC Server
+ VNCServer.1
+ iDRAC.Embedded.1#VNCServer.1#Timeout
+ false
+ 60
+
+ 10800
+
+
+ Delivery Retry Attempts
+ DeliveryRetryAttempts
+ 3
+ 3
+
+ 2240
+ iDRAC.Embedded.1
+ RedfishEventing
+ RedfishEventing.1
+ iDRAC.Embedded.1#RedfishEventing.1#DeliveryRetryAttempts
+ false
+ 0
+
+ 5
+
+
+ Delivery Retry Interval In Seconds
+ DeliveryRetryIntervalInSeconds
+ 30
+ 30
+
+ 2241
+ iDRAC.Embedded.1
+ RedfishEventing
+ RedfishEventing.1
+ iDRAC.Embedded.1#RedfishEventing.1#DeliveryRetryIntervalInSeconds
+ false
+ 5
+
+ 60
+
+
+
+
+
+
+
diff --git a/dracclient/tests/wsman_mocks/idraccard_string-enum-ok.xml b/dracclient/tests/wsman_mocks/idraccard_string-enum-ok.xml
new file mode 100644
index 0000000..07d5adb
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/idraccard_string-enum-ok.xml
@@ -0,0 +1,4549 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse
+ uuid:437c3101-0e6a-41f5-ad49-8a09b3ee5589
+ uuid:a8ddc513-40aa-10aa-821d-de7e4e771814
+
+
+
+
+
+ iDRAC Product Information
+ Product
+ Integrated Dell Remote Access Controller
+
+
+ 1
+ iDRAC.Embedded.1
+ RAC Information
+ Info.1
+ iDRAC.Embedded.1#Info.1#Product
+ true
+ 63
+ 0
+
+
+
+ iDRAC Description Information
+ Description
+ This system component provides a complete set of remote management functions for Dell PowerEdge Servers
+
+
+ 2
+ iDRAC.Embedded.1
+ RAC Information
+ Info.1
+ iDRAC.Embedded.1#Info.1#Description
+ true
+ 255
+ 0
+
+
+
+ iDRAC Version Information
+ Version
+ 2.40.40.40
+
+
+ 3
+ iDRAC.Embedded.1
+ RAC Information
+ Info.1
+ iDRAC.Embedded.1#Info.1#Version
+ true
+ 63
+ 0
+
+
+
+ iDRAC Build Information
+ Build
+ 45
+
+
+ 4
+ iDRAC.Embedded.1
+ RAC Information
+ Info.1
+ iDRAC.Embedded.1#Info.1#Build
+ true
+ 16
+ 0
+
+
+
+ iDRAC Name
+ Name
+ idrac-9CDK182
+ iDRAC
+
+ 5
+ iDRAC.Embedded.1
+ RAC Information
+ Info.1
+ iDRAC.Embedded.1#Info.1#Name
+ true
+ 15
+ 0
+
+
+
+ Server Generation
+ ServerGen
+ 13G
+
+
+ 7
+ iDRAC.Embedded.1
+ RAC Information
+ Info.1
+ iDRAC.Embedded.1#Info.1#ServerGen
+ true
+ 10
+ 0
+
+
+
+ MAC Address
+ MACAddress
+ 14:18:77:4E:7E:DE
+
+
+ 52
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#MACAddress
+ true
+ 17
+ 0
+
+
+
+ DNS RAC Name
+ DNSRacName
+ idrac-9CDK182
+ idrac-SVCTAG
+
+ 59
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#DNSRacName
+ false
+ 63
+ 0
+
+
+
+ DNS Domain Name
+ DNSDomainName
+ ib.sfdc.net
+
+
+ 181
+ iDRAC.Embedded.1
+ NIC Information
+ NIC.1
+ iDRAC.Embedded.1#NIC.1#DNSDomainName
+ false
+ 254
+ 0
+
+
+
+ IPv4 Address
+ Address
+ 10.224.178.123
+ 192.168.0.120
+
+ 103
+ iDRAC.Embedded.1
+ IPv4 Information
+ IPv4.1
+ iDRAC.Embedded.1#IPv4.1#Address
+ false
+ 16
+ 0
+
+
+
+ Net Mask
+ Netmask
+ 255.255.255.0
+ 255.255.255.0
+
+ 104
+ iDRAC.Embedded.1
+ IPv4 Information
+ IPv4.1
+ iDRAC.Embedded.1#IPv4.1#Netmask
+ false
+ 16
+ 0
+
+
+
+ Gateway
+ Gateway
+ 10.224.178.1
+ 192.168.0.1
+
+ 105
+ iDRAC.Embedded.1
+ IPv4 Information
+ IPv4.1
+ iDRAC.Embedded.1#IPv4.1#Gateway
+ false
+ 16
+ 0
+
+
+
+ DNS Server 1
+ DNS1
+ 10.225.9.2
+ 0.0.0.0
+
+ 107
+ iDRAC.Embedded.1
+ IPv4 Information
+ IPv4.1
+ iDRAC.Embedded.1#IPv4.1#DNS1
+ false
+ 16
+ 0
+
+
+
+ DNS Server 2
+ DNS2
+ 10.225.9.18
+ 0.0.0.0
+
+ 108
+ iDRAC.Embedded.1
+ IPv4 Information
+ IPv4.1
+ iDRAC.Embedded.1#IPv4.1#DNS2
+ false
+ 16
+ 0
+
+
+
+ IPV6 Address 1
+ Address1
+ ::
+ ::
+
+ 154
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#Address1
+ false
+ 63
+ 0
+
+
+
+ IPV6 Gateway
+ Gateway
+ ::
+ ::
+
+ 155
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#Gateway
+ false
+ 63
+ 0
+
+
+
+ IPV6 Link Local Address
+ LinkLocalAddress
+ ::
+ ::
+
+ 156
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#LinkLocalAddress
+ true
+ 63
+ 0
+
+
+
+ IPV6 DNS Server1
+ DNS1
+ ::
+ ::
+
+ 158
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#DNS1
+ false
+ 63
+ 0
+
+
+
+ IPV6 DNS Server2
+ DNS2
+ ::
+ ::
+
+ 159
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#DNS2
+ false
+ 63
+ 0
+
+
+
+ IPV6 Address 2
+ Address2
+ ::
+ ::
+
+ 161
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#Address2
+ true
+ 63
+ 0
+
+
+
+ IPV6 Address 3
+ Address3
+ ::
+ ::
+
+ 162
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#Address3
+ true
+ 63
+ 0
+
+
+
+ IPV6 Address 4
+ Address4
+ ::
+ ::
+
+ 163
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#Address4
+ true
+ 63
+ 0
+
+
+
+ IPV6 Address 5
+ Address5
+ ::
+ ::
+
+ 164
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#Address5
+ true
+ 63
+ 0
+
+
+
+ IPV6 Address 6
+ Address6
+ ::
+ ::
+
+ 165
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#Address6
+ true
+ 63
+ 0
+
+
+
+ IPV6 Address 7
+ Address7
+ ::
+ ::
+
+ 166
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#Address7
+ true
+ 63
+ 0
+
+
+
+ IPV6 Address 8
+ Address8
+ ::
+ ::
+
+ 167
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#Address8
+ true
+ 63
+ 0
+
+
+
+ IPV6 Address 9
+ Address9
+ ::
+ ::
+
+ 168
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#Address9
+ true
+ 63
+ 0
+
+
+
+ IPV6 Address 10
+ Address10
+ ::
+ ::
+
+ 169
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#Address10
+ true
+ 63
+ 0
+
+
+
+ IPV6 Address 11
+ Address11
+ ::
+ ::
+
+ 170
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#Address11
+ true
+ 63
+ 0
+
+
+
+ IPV6 Address 12
+ Address12
+ ::
+ ::
+
+ 171
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#Address12
+ true
+ 63
+ 0
+
+
+
+ IPV6 Address 13
+ Address13
+ ::
+ ::
+
+ 172
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#Address13
+ true
+ 63
+ 0
+
+
+
+ IPV6 Address 14
+ Address14
+ ::
+ ::
+
+ 173
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#Address14
+ true
+ 63
+ 0
+
+
+
+ IPV6 Address 15
+ Address15
+ ::
+ ::
+
+ 174
+ iDRAC.Embedded.1
+ IPv6 Information
+ IPv6.1
+ iDRAC.Embedded.1#IPv6.1#Address15
+ true
+ 63
+ 0
+
+
+
+ DNS Domain Name
+ DNSDomainName
+ ib.sfdc.net
+
+
+ 182
+ iDRAC.Embedded.1
+ NIC Static Information
+ NICStatic.1
+ iDRAC.Embedded.1#NICStatic.1#DNSDomainName
+ false
+ 254
+ 0
+
+
+
+ IPv4 Address
+ Address
+ 10.224.178.123
+ 192.168.0.120
+
+ 185
+ iDRAC.Embedded.1
+ IPv4 Static Information
+ IPv4Static.1
+ iDRAC.Embedded.1#IPv4Static.1#Address
+ false
+ 16
+ 0
+
+
+
+ Net Mask
+ Netmask
+ 255.255.255.0
+ 255.255.255.0
+
+ 186
+ iDRAC.Embedded.1
+ IPv4 Static Information
+ IPv4Static.1
+ iDRAC.Embedded.1#IPv4Static.1#Netmask
+ false
+ 16
+ 0
+
+
+
+ Gateway
+ Gateway
+ 10.224.178.1
+ 192.168.0.1
+
+ 187
+ iDRAC.Embedded.1
+ IPv4 Static Information
+ IPv4Static.1
+ iDRAC.Embedded.1#IPv4Static.1#Gateway
+ false
+ 16
+ 0
+
+
+
+ DNS Server 1
+ DNS1
+ 10.225.9.2
+ 0.0.0.0
+
+ 188
+ iDRAC.Embedded.1
+ IPv4 Static Information
+ IPv4Static.1
+ iDRAC.Embedded.1#IPv4Static.1#DNS1
+ false
+ 16
+ 0
+
+
+
+ DNS Server 2
+ DNS2
+ 10.225.9.18
+ 0.0.0.0
+
+ 189
+ iDRAC.Embedded.1
+ IPv4 Static Information
+ IPv4Static.1
+ iDRAC.Embedded.1#IPv4Static.1#DNS2
+ false
+ 16
+ 0
+
+
+
+ IPV6 Address 1
+ Address1
+ ::
+ ::
+
+ 191
+ iDRAC.Embedded.1
+ IPv6 Static Information
+ IPv6Static.1
+ iDRAC.Embedded.1#IPv6Static.1#Address1
+ false
+ 63
+ 0
+
+
+
+ IPV6 Gateway
+ Gateway
+ ::
+ ::
+
+ 192
+ iDRAC.Embedded.1
+ IPv6 Static Information
+ IPv6Static.1
+ iDRAC.Embedded.1#IPv6Static.1#Gateway
+ false
+ 63
+ 0
+
+
+
+ IPV6 DNS Server1
+ DNS1
+ ::
+ ::
+
+ 194
+ iDRAC.Embedded.1
+ IPv6 Static Information
+ IPv6Static.1
+ iDRAC.Embedded.1#IPv6Static.1#DNS1
+ false
+ 63
+ 0
+
+
+
+ IPV6 DNS Server2
+ DNS2
+ ::
+ ::
+
+ 195
+ iDRAC.Embedded.1
+ IPv6 Static Information
+ IPv6Static.1
+ iDRAC.Embedded.1#IPv6Static.1#DNS2
+ false
+ 63
+ 0
+
+
+
+ Encryption Key
+ EncryptionKey
+ 0000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000
+
+ 203
+ iDRAC.Embedded.1
+ IPMI LAN Information
+ IPMILan.1
+ iDRAC.Embedded.1#IPMILan.1#EncryptionKey
+ false
+ 40
+ 0
+
+
+
+ Community Name
+ CommunityName
+ WYSkmGB8
+ public
+
+ 204
+ iDRAC.Embedded.1
+ IPMI LAN Information
+ IPMILan.1
+ iDRAC.Embedded.1#IPMILan.1#CommunityName
+ false
+ 18
+ 0
+
+
+
+ User Admin User Name
+ UserName
+
+
+
+ 251
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.1
+ iDRAC.Embedded.1#Users.1#UserName
+ true
+ 16
+ 0
+
+
+
+ SHA256 hash of the password
+ SHA256Password
+
+
+
+ 2624
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.1
+ iDRAC.Embedded.1#Users.1#SHA256Password
+ false
+ 64
+ 0
+
+
+
+ SHA1 Hash of the SNMPv3 Key
+ SHA1v3Key
+
+
+
+ 2625
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.1
+ iDRAC.Embedded.1#Users.1#SHA1v3Key
+ false
+ 40
+ 0
+
+
+
+ MD5 Hash of the SNMPv3 key
+ MD5v3Key
+
+
+
+ 2626
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.1
+ iDRAC.Embedded.1#Users.1#MD5v3Key
+ false
+ 32
+ 0
+
+
+
+ Salt String Appended To Password Prior To Hash
+ SHA256PasswordSalt
+
+
+
+ 2627
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.1
+ iDRAC.Embedded.1#Users.1#SHA256PasswordSalt
+ false
+ 32
+ 0
+
+
+
+ User Admin User Name
+ UserName
+ admin
+ root
+
+ 261
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.2
+ iDRAC.Embedded.1#Users.2#UserName
+ false
+ 16
+ 0
+
+
+
+ SHA256 hash of the password
+ SHA256Password
+ AC403CC78DC7F1C340A8913CAAA53460E6F91775AB16ADFAA9B5DDBE57D4798C
+
+
+ 2634
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.2
+ iDRAC.Embedded.1#Users.2#SHA256Password
+ false
+ 64
+ 0
+
+
+
+ SHA1 Hash of the SNMPv3 Key
+ SHA1v3Key
+ c22d74e14376ce5e964bd13d468c392de73db061
+
+
+ 2635
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.2
+ iDRAC.Embedded.1#Users.2#SHA1v3Key
+ false
+ 40
+ 0
+
+
+
+ MD5 Hash of the SNMPv3 key
+ MD5v3Key
+ 5e58df0460c546d875c50341476ada6c
+
+
+ 2636
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.2
+ iDRAC.Embedded.1#Users.2#MD5v3Key
+ false
+ 32
+ 0
+
+
+
+ Salt String Appended To Password Prior To Hash
+ SHA256PasswordSalt
+ DB8A8304C5EAAA238E3BE93F6B9CC7DB
+
+
+ 2637
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.2
+ iDRAC.Embedded.1#Users.2#SHA256PasswordSalt
+ false
+ 32
+ 0
+
+
+
+ User Admin User Name
+ UserName
+ mrmon
+
+
+ 271
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.3
+ iDRAC.Embedded.1#Users.3#UserName
+ false
+ 16
+ 0
+
+
+
+ SHA256 hash of the password
+ SHA256Password
+ ACD86A03B4789BBCA4D6B3EFC50825FC1BD36A65A5B662D5263C50B1032DC20D
+
+
+ 2644
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.3
+ iDRAC.Embedded.1#Users.3#SHA256Password
+ false
+ 64
+ 0
+
+
+
+ SHA1 Hash of the SNMPv3 Key
+ SHA1v3Key
+ e176e67d8e05f7f8c862729d71ecfa1529290e7a
+
+
+ 2645
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.3
+ iDRAC.Embedded.1#Users.3#SHA1v3Key
+ false
+ 40
+ 0
+
+
+
+ MD5 Hash of the SNMPv3 key
+ MD5v3Key
+ f636a0e73b7c7113d948b0c738be6f56
+
+
+ 2646
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.3
+ iDRAC.Embedded.1#Users.3#MD5v3Key
+ false
+ 32
+ 0
+
+
+
+ Salt String Appended To Password Prior To Hash
+ SHA256PasswordSalt
+ DC06E8E9C4F80AFB73FFFADE82AF9DFA
+
+
+ 2647
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.3
+ iDRAC.Embedded.1#Users.3#SHA256PasswordSalt
+ false
+ 32
+ 0
+
+
+
+ User Admin User Name
+ UserName
+ oscnoc
+
+
+ 281
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.4
+ iDRAC.Embedded.1#Users.4#UserName
+ false
+ 16
+ 0
+
+
+
+ SHA256 hash of the password
+ SHA256Password
+ AA62370E0F53FC0FAD156CB65ACE4E176BF7E05A937D3134ED9A85C9ED1BB72F
+
+
+ 2654
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.4
+ iDRAC.Embedded.1#Users.4#SHA256Password
+ false
+ 64
+ 0
+
+
+
+ SHA1 Hash of the SNMPv3 Key
+ SHA1v3Key
+ 779dfe35824475dc95f7b993c0a9f6cd21724119
+
+
+ 2655
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.4
+ iDRAC.Embedded.1#Users.4#SHA1v3Key
+ false
+ 40
+ 0
+
+
+
+ MD5 Hash of the SNMPv3 key
+ MD5v3Key
+ 015a288c1f21d6e7792391eeb7bc8106
+
+
+ 2656
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.4
+ iDRAC.Embedded.1#Users.4#MD5v3Key
+ false
+ 32
+ 0
+
+
+
+ Salt String Appended To Password Prior To Hash
+ SHA256PasswordSalt
+ 8B65F922B8917D3E9173A0D9BAC4E42D
+
+
+ 2657
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.4
+ iDRAC.Embedded.1#Users.4#SHA256PasswordSalt
+ false
+ 32
+ 0
+
+
+
+ User Admin User Name
+ UserName
+
+
+
+ 291
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.5
+ iDRAC.Embedded.1#Users.5#UserName
+ false
+ 16
+ 0
+
+
+
+ SHA256 hash of the password
+ SHA256Password
+
+
+
+ 2664
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.5
+ iDRAC.Embedded.1#Users.5#SHA256Password
+ false
+ 64
+ 0
+
+
+
+ SHA1 Hash of the SNMPv3 Key
+ SHA1v3Key
+
+
+
+ 2665
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.5
+ iDRAC.Embedded.1#Users.5#SHA1v3Key
+ false
+ 40
+ 0
+
+
+
+ MD5 Hash of the SNMPv3 key
+ MD5v3Key
+
+
+
+ 2666
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.5
+ iDRAC.Embedded.1#Users.5#MD5v3Key
+ false
+ 32
+ 0
+
+
+
+ Salt String Appended To Password Prior To Hash
+ SHA256PasswordSalt
+
+
+
+ 2667
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.5
+ iDRAC.Embedded.1#Users.5#SHA256PasswordSalt
+ false
+ 32
+ 0
+
+
+
+ User Admin User Name
+ UserName
+
+
+
+ 301
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.6
+ iDRAC.Embedded.1#Users.6#UserName
+ false
+ 16
+ 0
+
+
+
+ SHA256 hash of the password
+ SHA256Password
+
+
+
+ 2674
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.6
+ iDRAC.Embedded.1#Users.6#SHA256Password
+ false
+ 64
+ 0
+
+
+
+ SHA1 Hash of the SNMPv3 Key
+ SHA1v3Key
+
+
+
+ 2675
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.6
+ iDRAC.Embedded.1#Users.6#SHA1v3Key
+ false
+ 40
+ 0
+
+
+
+ MD5 Hash of the SNMPv3 key
+ MD5v3Key
+
+
+
+ 2676
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.6
+ iDRAC.Embedded.1#Users.6#MD5v3Key
+ false
+ 32
+ 0
+
+
+
+ Salt String Appended To Password Prior To Hash
+ SHA256PasswordSalt
+
+
+
+ 2677
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.6
+ iDRAC.Embedded.1#Users.6#SHA256PasswordSalt
+ false
+ 32
+ 0
+
+
+
+ User Admin User Name
+ UserName
+
+
+
+ 311
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.7
+ iDRAC.Embedded.1#Users.7#UserName
+ false
+ 16
+ 0
+
+
+
+ SHA256 hash of the password
+ SHA256Password
+
+
+
+ 2684
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.7
+ iDRAC.Embedded.1#Users.7#SHA256Password
+ false
+ 64
+ 0
+
+
+
+ SHA1 Hash of the SNMPv3 Key
+ SHA1v3Key
+
+
+
+ 2685
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.7
+ iDRAC.Embedded.1#Users.7#SHA1v3Key
+ false
+ 40
+ 0
+
+
+
+ MD5 Hash of the SNMPv3 key
+ MD5v3Key
+
+
+
+ 2686
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.7
+ iDRAC.Embedded.1#Users.7#MD5v3Key
+ false
+ 32
+ 0
+
+
+
+ Salt String Appended To Password Prior To Hash
+ SHA256PasswordSalt
+
+
+
+ 2687
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.7
+ iDRAC.Embedded.1#Users.7#SHA256PasswordSalt
+ false
+ 32
+ 0
+
+
+
+ User Admin User Name
+ UserName
+
+
+
+ 321
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.8
+ iDRAC.Embedded.1#Users.8#UserName
+ false
+ 16
+ 0
+
+
+
+ SHA256 hash of the password
+ SHA256Password
+
+
+
+ 2694
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.8
+ iDRAC.Embedded.1#Users.8#SHA256Password
+ false
+ 64
+ 0
+
+
+
+ SHA1 Hash of the SNMPv3 Key
+ SHA1v3Key
+
+
+
+ 2695
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.8
+ iDRAC.Embedded.1#Users.8#SHA1v3Key
+ false
+ 40
+ 0
+
+
+
+ MD5 Hash of the SNMPv3 key
+ MD5v3Key
+
+
+
+ 2696
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.8
+ iDRAC.Embedded.1#Users.8#MD5v3Key
+ false
+ 32
+ 0
+
+
+
+ Salt String Appended To Password Prior To Hash
+ SHA256PasswordSalt
+
+
+
+ 2697
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.8
+ iDRAC.Embedded.1#Users.8#SHA256PasswordSalt
+ false
+ 32
+ 0
+
+
+
+ User Admin User Name
+ UserName
+
+
+
+ 331
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.9
+ iDRAC.Embedded.1#Users.9#UserName
+ false
+ 16
+ 0
+
+
+
+ SHA256 hash of the password
+ SHA256Password
+
+
+
+ 2704
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.9
+ iDRAC.Embedded.1#Users.9#SHA256Password
+ false
+ 64
+ 0
+
+
+
+ SHA1 Hash of the SNMPv3 Key
+ SHA1v3Key
+
+
+
+ 2705
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.9
+ iDRAC.Embedded.1#Users.9#SHA1v3Key
+ false
+ 40
+ 0
+
+
+
+ MD5 Hash of the SNMPv3 key
+ MD5v3Key
+
+
+
+ 2706
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.9
+ iDRAC.Embedded.1#Users.9#MD5v3Key
+ false
+ 32
+ 0
+
+
+
+ Salt String Appended To Password Prior To Hash
+ SHA256PasswordSalt
+
+
+
+ 2707
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.9
+ iDRAC.Embedded.1#Users.9#SHA256PasswordSalt
+ false
+ 32
+ 0
+
+
+
+ User Admin User Name
+ UserName
+
+
+
+ 341
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.10
+ iDRAC.Embedded.1#Users.10#UserName
+ false
+ 16
+ 0
+
+
+
+ SHA256 hash of the password
+ SHA256Password
+
+
+
+ 2714
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.10
+ iDRAC.Embedded.1#Users.10#SHA256Password
+ false
+ 64
+ 0
+
+
+
+ SHA1 Hash of the SNMPv3 Key
+ SHA1v3Key
+
+
+
+ 2715
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.10
+ iDRAC.Embedded.1#Users.10#SHA1v3Key
+ false
+ 40
+ 0
+
+
+
+ MD5 Hash of the SNMPv3 key
+ MD5v3Key
+
+
+
+ 2716
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.10
+ iDRAC.Embedded.1#Users.10#MD5v3Key
+ false
+ 32
+ 0
+
+
+
+ Salt String Appended To Password Prior To Hash
+ SHA256PasswordSalt
+
+
+
+ 2717
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.10
+ iDRAC.Embedded.1#Users.10#SHA256PasswordSalt
+ false
+ 32
+ 0
+
+
+
+ User Admin User Name
+ UserName
+
+
+
+ 351
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.11
+ iDRAC.Embedded.1#Users.11#UserName
+ false
+ 16
+ 0
+
+
+
+ SHA256 hash of the password
+ SHA256Password
+
+
+
+ 2724
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.11
+ iDRAC.Embedded.1#Users.11#SHA256Password
+ false
+ 64
+ 0
+
+
+
+ SHA1 Hash of the SNMPv3 Key
+ SHA1v3Key
+
+
+
+ 2725
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.11
+ iDRAC.Embedded.1#Users.11#SHA1v3Key
+ false
+ 40
+ 0
+
+
+
+ MD5 Hash of the SNMPv3 key
+ MD5v3Key
+
+
+
+ 2726
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.11
+ iDRAC.Embedded.1#Users.11#MD5v3Key
+ false
+ 32
+ 0
+
+
+
+ Salt String Appended To Password Prior To Hash
+ SHA256PasswordSalt
+
+
+
+ 2727
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.11
+ iDRAC.Embedded.1#Users.11#SHA256PasswordSalt
+ false
+ 32
+ 0
+
+
+
+ User Admin User Name
+ UserName
+
+
+
+ 361
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.12
+ iDRAC.Embedded.1#Users.12#UserName
+ false
+ 16
+ 0
+
+
+
+ SHA256 hash of the password
+ SHA256Password
+
+
+
+ 2734
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.12
+ iDRAC.Embedded.1#Users.12#SHA256Password
+ false
+ 64
+ 0
+
+
+
+ SHA1 Hash of the SNMPv3 Key
+ SHA1v3Key
+
+
+
+ 2735
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.12
+ iDRAC.Embedded.1#Users.12#SHA1v3Key
+ false
+ 40
+ 0
+
+
+
+ MD5 Hash of the SNMPv3 key
+ MD5v3Key
+
+
+
+ 2736
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.12
+ iDRAC.Embedded.1#Users.12#MD5v3Key
+ false
+ 32
+ 0
+
+
+
+ Salt String Appended To Password Prior To Hash
+ SHA256PasswordSalt
+
+
+
+ 2737
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.12
+ iDRAC.Embedded.1#Users.12#SHA256PasswordSalt
+ false
+ 32
+ 0
+
+
+
+ User Admin User Name
+ UserName
+
+
+
+ 371
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.13
+ iDRAC.Embedded.1#Users.13#UserName
+ false
+ 16
+ 0
+
+
+
+ SHA256 hash of the password
+ SHA256Password
+
+
+
+ 2744
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.13
+ iDRAC.Embedded.1#Users.13#SHA256Password
+ false
+ 64
+ 0
+
+
+
+ SHA1 Hash of the SNMPv3 Key
+ SHA1v3Key
+
+
+
+ 2745
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.13
+ iDRAC.Embedded.1#Users.13#SHA1v3Key
+ false
+ 40
+ 0
+
+
+
+ MD5 Hash of the SNMPv3 key
+ MD5v3Key
+
+
+
+ 2746
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.13
+ iDRAC.Embedded.1#Users.13#MD5v3Key
+ false
+ 32
+ 0
+
+
+
+ Salt String Appended To Password Prior To Hash
+ SHA256PasswordSalt
+
+
+
+ 2747
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.13
+ iDRAC.Embedded.1#Users.13#SHA256PasswordSalt
+ false
+ 32
+ 0
+
+
+
+ User Admin User Name
+ UserName
+
+
+
+ 381
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.14
+ iDRAC.Embedded.1#Users.14#UserName
+ false
+ 16
+ 0
+
+
+
+ SHA256 hash of the password
+ SHA256Password
+
+
+
+ 2754
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.14
+ iDRAC.Embedded.1#Users.14#SHA256Password
+ false
+ 64
+ 0
+
+
+
+ SHA1 Hash of the SNMPv3 Key
+ SHA1v3Key
+
+
+
+ 2755
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.14
+ iDRAC.Embedded.1#Users.14#SHA1v3Key
+ false
+ 40
+ 0
+
+
+
+ MD5 Hash of the SNMPv3 key
+ MD5v3Key
+
+
+
+ 2756
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.14
+ iDRAC.Embedded.1#Users.14#MD5v3Key
+ false
+ 32
+ 0
+
+
+
+ Salt String Appended To Password Prior To Hash
+ SHA256PasswordSalt
+
+
+
+ 2757
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.14
+ iDRAC.Embedded.1#Users.14#SHA256PasswordSalt
+ false
+ 32
+ 0
+
+
+
+ User Admin User Name
+ UserName
+
+
+
+ 391
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.15
+ iDRAC.Embedded.1#Users.15#UserName
+ false
+ 16
+ 0
+
+
+
+ SHA256 hash of the password
+ SHA256Password
+
+
+
+ 2764
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.15
+ iDRAC.Embedded.1#Users.15#SHA256Password
+ false
+ 64
+ 0
+
+
+
+ SHA1 Hash of the SNMPv3 Key
+ SHA1v3Key
+
+
+
+ 2765
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.15
+ iDRAC.Embedded.1#Users.15#SHA1v3Key
+ false
+ 40
+ 0
+
+
+
+ MD5 Hash of the SNMPv3 key
+ MD5v3Key
+
+
+
+ 2766
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.15
+ iDRAC.Embedded.1#Users.15#MD5v3Key
+ false
+ 32
+ 0
+
+
+
+ Salt String Appended To Password Prior To Hash
+ SHA256PasswordSalt
+
+
+
+ 2767
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.15
+ iDRAC.Embedded.1#Users.15#SHA256PasswordSalt
+ false
+ 32
+ 0
+
+
+
+ User Admin User Name
+ UserName
+
+
+
+ 401
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.16
+ iDRAC.Embedded.1#Users.16#UserName
+ false
+ 16
+ 0
+
+
+
+ SHA256 hash of the password
+ SHA256Password
+
+
+
+ 2774
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.16
+ iDRAC.Embedded.1#Users.16#SHA256Password
+ false
+ 64
+ 0
+
+
+
+ SHA1 Hash of the SNMPv3 Key
+ SHA1v3Key
+
+
+
+ 2775
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.16
+ iDRAC.Embedded.1#Users.16#SHA1v3Key
+ false
+ 40
+ 0
+
+
+
+ MD5 Hash of the SNMPv3 key
+ MD5v3Key
+
+
+
+ 2776
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.16
+ iDRAC.Embedded.1#Users.16#MD5v3Key
+ false
+ 32
+ 0
+
+
+
+ Salt String Appended To Password Prior To Hash
+ SHA256PasswordSalt
+
+
+
+ 2777
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.16
+ iDRAC.Embedded.1#Users.16#SHA256PasswordSalt
+ false
+ 32
+ 0
+
+
+
+ Firmware Update IP Address
+ FwUpdateIPAddr
+ 0.0.0.0
+ 0.0.0.0
+
+ 452
+ iDRAC.Embedded.1
+ Firmware Update
+ Update.1
+ iDRAC.Embedded.1#Update.1#FwUpdateIPAddr
+ false
+ 255
+ 0
+
+
+
+ Firmware Update File Path
+ FwUpdatePath
+
+
+
+ 453
+ iDRAC.Embedded.1
+ Firmware Update
+ Update.1
+ iDRAC.Embedded.1#Update.1#FwUpdatePath
+ false
+ 255
+ 0
+
+
+
+ Email Alert Address
+ Address
+
+
+
+ 472
+ iDRAC.Embedded.1
+ RAC Email Alert
+ EmailAlert.1
+ iDRAC.Embedded.1#EmailAlert.1#Address
+ false
+ 64
+ 0
+
+
+
+ Email Alert Custom Message
+ CustomMsg
+
+
+
+ 473
+ iDRAC.Embedded.1
+ RAC Email Alert
+ EmailAlert.1
+ iDRAC.Embedded.1#EmailAlert.1#CustomMsg
+ false
+ 32
+ 0
+
+
+
+ Email Alert Address
+ Address
+
+
+
+ 492
+ iDRAC.Embedded.1
+ RAC Email Alert
+ EmailAlert.2
+ iDRAC.Embedded.1#EmailAlert.2#Address
+ false
+ 64
+ 0
+
+
+
+ Email Alert Custom Message
+ CustomMsg
+
+
+
+ 493
+ iDRAC.Embedded.1
+ RAC Email Alert
+ EmailAlert.2
+ iDRAC.Embedded.1#EmailAlert.2#CustomMsg
+ false
+ 32
+ 0
+
+
+
+ Email Alert Address
+ Address
+
+
+
+ 512
+ iDRAC.Embedded.1
+ RAC Email Alert
+ EmailAlert.3
+ iDRAC.Embedded.1#EmailAlert.3#Address
+ false
+ 64
+ 0
+
+
+
+ Email Alert Custom Message
+ CustomMsg
+
+
+
+ 513
+ iDRAC.Embedded.1
+ RAC Email Alert
+ EmailAlert.3
+ iDRAC.Embedded.1#EmailAlert.3#CustomMsg
+ false
+ 32
+ 0
+
+
+
+ Email Alert Address
+ Address
+
+
+
+ 522
+ iDRAC.Embedded.1
+ RAC Email Alert
+ EmailAlert.4
+ iDRAC.Embedded.1#EmailAlert.4#Address
+ false
+ 64
+ 0
+
+
+
+ Email Alert Custom Message
+ CustomMsg
+
+
+
+ 523
+ iDRAC.Embedded.1
+ RAC Email Alert
+ EmailAlert.4
+ iDRAC.Embedded.1#EmailAlert.4#CustomMsg
+ false
+ 32
+ 0
+
+
+
+ SMTP Server IP Address
+ SMTPServerIPAddress
+ 10.224.39.20
+ 0.0.0.0
+
+ 541
+ iDRAC.Embedded.1
+ RAC Remote Hosts
+ RemoteHosts.1
+ iDRAC.Embedded.1#RemoteHosts.1#SMTPServerIPAddress
+ false
+ 255
+ 0
+
+
+
+ SMTP User Name
+ SMTPUserName
+
+
+
+ 544
+ iDRAC.Embedded.1
+ RAC Remote Hosts
+ RemoteHosts.1
+ iDRAC.Embedded.1#RemoteHosts.1#SMTPUserName
+ false
+ 50
+ 0
+
+
+
+ Serial Console Command
+ Command
+
+
+
+ 606
+ iDRAC.Embedded.1
+ Serial Configuration
+ Serial.1
+ iDRAC.Embedded.1#Serial.1#Command
+ false
+ 128
+ 0
+
+
+
+ Serial Console Quit Key
+ QuitKey
+ ^\
+ ^\
+
+ 612
+ iDRAC.Embedded.1
+ RAC Serial Redirection
+ SerialRedirection.1
+ iDRAC.Embedded.1#SerialRedirection.1#QuitKey
+ false
+ 2
+ 0
+
+
+
+ SNMP Agent Community
+ AgentCommunity
+ WYSkmGB8
+ public
+
+ 702
+ iDRAC.Embedded.1
+ SNMP Configuration
+ SNMP.1
+ iDRAC.Embedded.1#SNMP.1#AgentCommunity
+ false
+ 31
+ 0
+
+
+
+ Tune IP Range Address
+ RangeAddr
+ 192.168.1.1
+ 192.168.1.1
+
+ 722
+ iDRAC.Embedded.1
+ IP Blocking
+ IPBlocking.1
+ iDRAC.Embedded.1#IPBlocking.1#RangeAddr
+ false
+ 16
+ 0
+
+
+
+ Tune IP Range Mask
+ RangeMask
+ 255.255.255.0
+ 255.255.255.0
+
+ 723
+ iDRAC.Embedded.1
+ IP Blocking
+ IPBlocking.1
+ iDRAC.Embedded.1#IPBlocking.1#RangeMask
+ false
+ 16
+ 0
+
+
+
+ Time Zone String
+ TimeZone
+ CST6CDT
+ US/Central
+
+ 753
+ iDRAC.Embedded.1
+ Time Zone Configuration Information
+ Time.1
+ iDRAC.Embedded.1#Time.1#TimeZone
+ false
+ 32
+ 0
+
+
+
+ CSR Common Name
+ CsrCommonName
+
+
+
+ 761
+ iDRAC.Embedded.1
+ RAC Certificate
+ Security.1
+ iDRAC.Embedded.1#Security.1#CsrCommonName
+ false
+ 254
+ 0
+
+
+
+ CSR Organization Name
+ CsrOrganizationName
+
+
+
+ 762
+ iDRAC.Embedded.1
+ RAC Certificate
+ Security.1
+ iDRAC.Embedded.1#Security.1#CsrOrganizationName
+ false
+ 254
+ 0
+
+
+
+ CSR Organization Unit
+ CsrOrganizationUnit
+
+
+
+ 763
+ iDRAC.Embedded.1
+ RAC Certificate
+ Security.1
+ iDRAC.Embedded.1#Security.1#CsrOrganizationUnit
+ false
+ 254
+ 0
+
+
+
+ CSR Locality Name
+ CsrLocalityName
+
+
+
+ 764
+ iDRAC.Embedded.1
+ RAC Certificate
+ Security.1
+ iDRAC.Embedded.1#Security.1#CsrLocalityName
+ false
+ 254
+ 0
+
+
+
+ CSR State Name
+ CsrStateName
+
+
+
+ 765
+ iDRAC.Embedded.1
+ RAC Certificate
+ Security.1
+ iDRAC.Embedded.1#Security.1#CsrStateName
+ false
+ 254
+ 0
+
+
+
+ CSR Country Code
+ CsrCountryCode
+ US
+ US
+
+ 766
+ iDRAC.Embedded.1
+ RAC Certificate
+ Security.1
+ iDRAC.Embedded.1#Security.1#CsrCountryCode
+ false
+ 2
+ 0
+
+
+
+ CSR Email Address
+ CsrEmailAddr
+
+
+
+ 767
+ iDRAC.Embedded.1
+ RAC Certificate
+ Security.1
+ iDRAC.Embedded.1#Security.1#CsrEmailAddr
+ false
+ 254
+ 0
+
+
+
+ LDAP Server
+ Server
+
+
+
+ 1082
+ iDRAC.Embedded.1
+ LDAP
+ LDAP.1
+ iDRAC.Embedded.1#LDAP.1#Server
+ false
+ 1024
+ 0
+
+
+
+ LDAP Base Domain Name
+ BaseDN
+
+
+
+ 1084
+ iDRAC.Embedded.1
+ LDAP
+ LDAP.1
+ iDRAC.Embedded.1#LDAP.1#BaseDN
+ false
+ 254
+ 0
+
+
+
+ LDAP User Attribute
+ UserAttribute
+
+
+
+ 1085
+ iDRAC.Embedded.1
+ LDAP
+ LDAP.1
+ iDRAC.Embedded.1#LDAP.1#UserAttribute
+ false
+ 254
+ 0
+
+
+
+ LDAP Group Attribute
+ GroupAttribute
+
+
+
+ 1086
+ iDRAC.Embedded.1
+ LDAP
+ LDAP.1
+ iDRAC.Embedded.1#LDAP.1#GroupAttribute
+ false
+ 254
+ 0
+
+
+
+ LDAP Bind User Distinguished Name
+ BindDN
+
+
+
+ 1088
+ iDRAC.Embedded.1
+ LDAP
+ LDAP.1
+ iDRAC.Embedded.1#LDAP.1#BindDN
+ false
+ 254
+ 0
+
+
+
+ LDAP Search Filter
+ SearchFilter
+
+
+
+ 1090
+ iDRAC.Embedded.1
+ LDAP
+ LDAP.1
+ iDRAC.Embedded.1#LDAP.1#SearchFilter
+ false
+ 1024
+ 0
+
+
+
+ Active Directory RAC Name
+ RacName
+
+
+
+ 772
+ iDRAC.Embedded.1
+ Active Directory
+ ActiveDirectory.1
+ iDRAC.Embedded.1#ActiveDirectory.1#RacName
+ false
+ 254
+ 0
+
+
+
+ Active Directory RAC Domain
+ RacDomain
+
+
+
+ 773
+ iDRAC.Embedded.1
+ Active Directory
+ ActiveDirectory.1
+ iDRAC.Embedded.1#ActiveDirectory.1#RacDomain
+ false
+ 254
+ 0
+
+
+
+ Domain Controller 1
+ DomainController1
+
+
+
+ 776
+ iDRAC.Embedded.1
+ Active Directory
+ ActiveDirectory.1
+ iDRAC.Embedded.1#ActiveDirectory.1#DomainController1
+ false
+ 254
+ 0
+
+
+
+ Domain Controller 2
+ DomainController2
+
+
+
+ 777
+ iDRAC.Embedded.1
+ Active Directory
+ ActiveDirectory.1
+ iDRAC.Embedded.1#ActiveDirectory.1#DomainController2
+ false
+ 254
+ 0
+
+
+
+ Domain Controller 3
+ DomainController3
+
+
+
+ 778
+ iDRAC.Embedded.1
+ Active Directory
+ ActiveDirectory.1
+ iDRAC.Embedded.1#ActiveDirectory.1#DomainController3
+ false
+ 254
+ 0
+
+
+
+ Global Catalog 1
+ GlobalCatalog1
+
+
+
+ 779
+ iDRAC.Embedded.1
+ Active Directory
+ ActiveDirectory.1
+ iDRAC.Embedded.1#ActiveDirectory.1#GlobalCatalog1
+ false
+ 254
+ 0
+
+
+
+ Global Catalog 2
+ GlobalCatalog2
+
+
+
+ 780
+ iDRAC.Embedded.1
+ Active Directory
+ ActiveDirectory.1
+ iDRAC.Embedded.1#ActiveDirectory.1#GlobalCatalog2
+ false
+ 254
+ 0
+
+
+
+ Global Catalog 3
+ GlobalCatalog3
+
+
+
+ 781
+ iDRAC.Embedded.1
+ Active Directory
+ ActiveDirectory.1
+ iDRAC.Embedded.1#ActiveDirectory.1#GlobalCatalog3
+ false
+ 254
+ 0
+
+
+
+ Active Directory Root Domain
+ GCRootDomain
+
+
+
+ 786
+ iDRAC.Embedded.1
+ Active Directory
+ ActiveDirectory.1
+ iDRAC.Embedded.1#ActiveDirectory.1#GCRootDomain
+ false
+ 254
+ 0
+
+
+
+ Active Directory Lookup Domain Name
+ DCLookupDomainName
+
+
+
+ 787
+ iDRAC.Embedded.1
+ Active Directory
+ ActiveDirectory.1
+ iDRAC.Embedded.1#ActiveDirectory.1#DCLookupDomainName
+ false
+ 254
+ 0
+
+
+
+ AD Role Group Name
+ Name
+
+
+
+ 801
+ iDRAC.Embedded.1
+ AD Group Configuration
+ ADGroup.1
+ iDRAC.Embedded.1#ADGroup.1#Name
+ false
+ 254
+ 0
+
+
+
+ AD Group Domain
+ Domain
+
+
+
+ 802
+ iDRAC.Embedded.1
+ AD Group Configuration
+ ADGroup.1
+ iDRAC.Embedded.1#ADGroup.1#Domain
+ false
+ 254
+ 0
+
+
+
+ AD Role Group Name
+ Name
+
+
+
+ 811
+ iDRAC.Embedded.1
+ AD Group Configuration
+ ADGroup.2
+ iDRAC.Embedded.1#ADGroup.2#Name
+ false
+ 254
+ 0
+
+
+
+ AD Group Domain
+ Domain
+
+
+
+ 812
+ iDRAC.Embedded.1
+ AD Group Configuration
+ ADGroup.2
+ iDRAC.Embedded.1#ADGroup.2#Domain
+ false
+ 254
+ 0
+
+
+
+ AD Role Group Name
+ Name
+
+
+
+ 821
+ iDRAC.Embedded.1
+ AD Group Configuration
+ ADGroup.3
+ iDRAC.Embedded.1#ADGroup.3#Name
+ false
+ 254
+ 0
+
+
+
+ AD Group Domain
+ Domain
+
+
+
+ 822
+ iDRAC.Embedded.1
+ AD Group Configuration
+ ADGroup.3
+ iDRAC.Embedded.1#ADGroup.3#Domain
+ false
+ 254
+ 0
+
+
+
+ AD Role Group Name
+ Name
+
+
+
+ 831
+ iDRAC.Embedded.1
+ ADGroup Configuration
+ ADGroup.4
+ iDRAC.Embedded.1#ADGroup.4#Name
+ false
+ 254
+ 0
+
+
+
+ AD Group Domain
+ Domain
+
+
+
+ 832
+ iDRAC.Embedded.1
+ ADGroup Configuration
+ ADGroup.4
+ iDRAC.Embedded.1#ADGroup.4#Domain
+ false
+ 254
+ 0
+
+
+
+ AD Role Group Name
+ Name
+
+
+
+ 841
+ iDRAC.Embedded.1
+ ADGroup Configuration
+ ADGroup.5
+ iDRAC.Embedded.1#ADGroup.5#Name
+ false
+ 254
+ 0
+
+
+
+ AD Group Domain
+ Domain
+
+
+
+ 842
+ iDRAC.Embedded.1
+ ADGroup Configuration
+ ADGroup.5
+ iDRAC.Embedded.1#ADGroup.5#Domain
+ false
+ 254
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 851
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.1
+ iDRAC.Embedded.1#UserDomain.1#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 856
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.2
+ iDRAC.Embedded.1#UserDomain.2#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 861
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.3
+ iDRAC.Embedded.1#UserDomain.3#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 866
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.4
+ iDRAC.Embedded.1#UserDomain.4#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 871
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.5
+ iDRAC.Embedded.1#UserDomain.5#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 876
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.6
+ iDRAC.Embedded.1#UserDomain.6#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 881
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.7
+ iDRAC.Embedded.1#UserDomain.7#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 886
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.8
+ iDRAC.Embedded.1#UserDomain.8#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 891
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.9
+ iDRAC.Embedded.1#UserDomain.9#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 896
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.10
+ iDRAC.Embedded.1#UserDomain.10#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 901
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.11
+ iDRAC.Embedded.1#UserDomain.11#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 906
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.12
+ iDRAC.Embedded.1#UserDomain.12#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 911
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.13
+ iDRAC.Embedded.1#UserDomain.13#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 916
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.14
+ iDRAC.Embedded.1#UserDomain.14#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 921
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.15
+ iDRAC.Embedded.1#UserDomain.15#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 926
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.16
+ iDRAC.Embedded.1#UserDomain.16#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 931
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.17
+ iDRAC.Embedded.1#UserDomain.17#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 936
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.18
+ iDRAC.Embedded.1#UserDomain.18#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 941
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.19
+ iDRAC.Embedded.1#UserDomain.19#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 946
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.20
+ iDRAC.Embedded.1#UserDomain.20#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 951
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.21
+ iDRAC.Embedded.1#UserDomain.21#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 956
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.22
+ iDRAC.Embedded.1#UserDomain.22#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 961
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.23
+ iDRAC.Embedded.1#UserDomain.23#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 966
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.24
+ iDRAC.Embedded.1#UserDomain.24#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 971
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.25
+ iDRAC.Embedded.1#UserDomain.25#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 976
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.26
+ iDRAC.Embedded.1#UserDomain.26#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 981
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.27
+ iDRAC.Embedded.1#UserDomain.27#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 986
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.28
+ iDRAC.Embedded.1#UserDomain.28#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 991
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.29
+ iDRAC.Embedded.1#UserDomain.29#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 996
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.30
+ iDRAC.Embedded.1#UserDomain.30#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 1001
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.31
+ iDRAC.Embedded.1#UserDomain.31#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 1006
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.32
+ iDRAC.Embedded.1#UserDomain.32#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 1011
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.33
+ iDRAC.Embedded.1#UserDomain.33#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 1016
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.34
+ iDRAC.Embedded.1#UserDomain.34#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 1021
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.35
+ iDRAC.Embedded.1#UserDomain.35#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 1026
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.36
+ iDRAC.Embedded.1#UserDomain.36#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 1031
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.37
+ iDRAC.Embedded.1#UserDomain.37#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 1036
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.38
+ iDRAC.Embedded.1#UserDomain.38#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 1041
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.39
+ iDRAC.Embedded.1#UserDomain.39#Name
+ false
+ 255
+ 0
+
+
+
+ User Domain Name
+ Name
+
+
+
+ 1046
+ iDRAC.Embedded.1
+ User Domain
+ UserDomain.40
+ iDRAC.Embedded.1#UserDomain.40#Name
+ false
+ 255
+ 0
+
+
+
+ Sys Log Server 1
+ Server1
+
+
+
+ 1073
+ iDRAC.Embedded.1
+ Sys Log
+ SysLog.1
+ iDRAC.Embedded.1#SysLog.1#Server1
+ false
+ 63
+ 0
+
+
+
+ Sys Log Server 2
+ Server2
+
+
+
+ 1074
+ iDRAC.Embedded.1
+ Sys Log
+ SysLog.1
+ iDRAC.Embedded.1#SysLog.1#Server2
+ false
+ 63
+ 0
+
+
+
+ Sys Log Server 3
+ Server3
+
+
+
+ 1075
+ iDRAC.Embedded.1
+ Sys Log
+ SysLog.1
+ iDRAC.Embedded.1#SysLog.1#Server3
+ false
+ 63
+ 0
+
+
+
+ LDAP Role Group Domain Name
+ DN
+
+
+
+ 1101
+ iDRAC.Embedded.1
+ LDAP Group
+ LDAPRoleGroup.1
+ iDRAC.Embedded.1#LDAPRoleGroup.1#DN
+ false
+ 1024
+ 0
+
+
+
+ LDAP Role Group Domain Name
+ DN
+
+
+
+ 1111
+ iDRAC.Embedded.1
+ LDAP Group
+ LDAPRoleGroup.2
+ iDRAC.Embedded.1#LDAPRoleGroup.2#DN
+ false
+ 1024
+ 0
+
+
+
+ LDAP Role Group Domain Name
+ DN
+
+
+
+ 1121
+ iDRAC.Embedded.1
+ LDAP Group
+ LDAPRoleGroup.3
+ iDRAC.Embedded.1#LDAPRoleGroup.3#DN
+ false
+ 1024
+ 0
+
+
+
+ LDAP Role Group Domain Name
+ DN
+
+
+
+ 1131
+ iDRAC.Embedded.1
+ LDAP Group
+ LDAPRoleGroup.4
+ iDRAC.Embedded.1#LDAPRoleGroup.4#DN
+ false
+ 1024
+ 0
+
+
+
+ LDAP Role Group Domain Name
+ DN
+
+
+
+ 1141
+ iDRAC.Embedded.1
+ LDAP Group
+ LDAPRoleGroup.5
+ iDRAC.Embedded.1#LDAPRoleGroup.5#DN
+ false
+ 1024
+ 0
+
+
+
+ Destination IPv6 Address
+ DestIPv6Addr
+ ::
+ ::
+
+ 1153
+ iDRAC.Embedded.1
+ SNMP Trap IPv6
+ SNMPTrapIPv6.1
+ iDRAC.Embedded.1#SNMPTrapIPv6.1#DestIPv6Addr
+ false
+ 39
+ 0
+
+
+
+ Destination IPv6 Address
+ DestIPv6Addr
+ ::
+ ::
+
+ 1163
+ iDRAC.Embedded.1
+ SNMP Trap IPv6
+ SNMPTrapIPv6.2
+ iDRAC.Embedded.1#SNMPTrapIPv6.2#DestIPv6Addr
+ false
+ 39
+ 0
+
+
+
+ Destination IPv6 Address
+ DestIPv6Addr
+ ::
+ ::
+
+ 1173
+ iDRAC.Embedded.1
+ SNMP Trap IPv6
+ SNMPTrapIPv6.3
+ iDRAC.Embedded.1#SNMPTrapIPv6.3#DestIPv6Addr
+ false
+ 39
+ 0
+
+
+
+ Destination IPv6 Address
+ DestIPv6Addr
+ ::
+ ::
+
+ 1183
+ iDRAC.Embedded.1
+ SNMP Trap IPv6
+ SNMPTrapIPv6.4
+ iDRAC.Embedded.1#SNMPTrapIPv6.4#DestIPv6Addr
+ false
+ 39
+ 0
+
+
+
+ Destination IPv4 Address
+ DestIPv4Addr
+ 0.0.0.0
+ 0.0.0.0
+
+ 1193
+ iDRAC.Embedded.1
+ SNMP Trap IPv4
+ SNMPTrapIPv4.1
+ iDRAC.Embedded.1#SNMPTrapIPv4.1#DestIPv4Addr
+ false
+ 15
+ 0
+
+
+
+ Destination IPv4 Address
+ DestIPv4Addr
+ 0.0.0.0
+ 0.0.0.0
+
+ 1203
+ iDRAC.Embedded.1
+ SNMP Trap IPv4
+ SNMPTrapIPv4.2
+ iDRAC.Embedded.1#SNMPTrapIPv4.2#DestIPv4Addr
+ false
+ 15
+ 0
+
+
+
+ Destination IPv4 Address
+ DestIPv4Addr
+ 0.0.0.0
+ 0.0.0.0
+
+ 1213
+ iDRAC.Embedded.1
+ SNMP Trap IPv4
+ SNMPTrapIPv4.3
+ iDRAC.Embedded.1#SNMPTrapIPv4.3#DestIPv4Addr
+ false
+ 15
+ 0
+
+
+
+ Destination IPv4 Address
+ DestIPv4Addr
+ 0.0.0.0
+ 0.0.0.0
+
+ 1223
+ iDRAC.Embedded.1
+ SNMP Trap IPv4
+ SNMPTrapIPv4.4
+ iDRAC.Embedded.1#SNMPTrapIPv4.4#DestIPv4Addr
+ false
+ 15
+ 0
+
+
+
+ iDRAC Remote File Share Image Path
+ Image
+
+
+
+ 1233
+ iDRAC.Embedded.1
+ Remote File Share
+ RFS.1
+ iDRAC.Embedded.1#RFS.1#Image
+ true
+ 255
+ 0
+
+
+
+ OS-BMC PT HOST IP Address
+ OsIpAddress
+ 0.0.0.0
+ 0.0.0.0
+
+ 1243
+ iDRAC.Embedded.1
+ OS-BMC Passthru Configuration
+ OS-BMC.1
+ iDRAC.Embedded.1#OS-BMC.1#OsIpAddress
+ false
+ 16
+ 0
+
+
+
+ USB NIC IP Address
+ UsbNicIpAddress
+ 169.254.0.1
+ 169.254.0.1
+
+ 1245
+ iDRAC.Embedded.1
+ OS-BMC Passthru Configuration
+ OS-BMC.1
+ iDRAC.Embedded.1#OS-BMC.1#UsbNicIpAddress
+ false
+ 16
+ 0
+
+
+
+ Alert Destination
+ Destination
+ 0.0.0.0
+ 0.0.0.0
+
+ 1601
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.1
+ iDRAC.Embedded.1#SNMPAlert.1#Destination
+ false
+ 255
+ 0
+
+
+
+ SNMP V3 Username
+ SNMPv3Username
+
+
+
+ 1603
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.1
+ iDRAC.Embedded.1#SNMPAlert.1#SNMPv3Username
+ false
+ 16
+ 0
+
+
+
+ Alert Destination
+ Destination
+ 0.0.0.0
+ 0.0.0.0
+
+ 1603
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.2
+ iDRAC.Embedded.1#SNMPAlert.2#Destination
+ false
+ 255
+ 0
+
+
+
+ SNMP V3 Username
+ SNMPv3Username
+
+
+
+ 1603
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.2
+ iDRAC.Embedded.1#SNMPAlert.2#SNMPv3Username
+ false
+ 16
+ 0
+
+
+
+ Alert Destination
+ Destination
+ 0.0.0.0
+ 0.0.0.0
+
+ 1605
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.3
+ iDRAC.Embedded.1#SNMPAlert.3#Destination
+ false
+ 255
+ 0
+
+
+
+ SNMP V3 Username
+ SNMPv3Username
+
+
+
+ 1603
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.3
+ iDRAC.Embedded.1#SNMPAlert.3#SNMPv3Username
+ false
+ 16
+ 0
+
+
+
+ Alert Destination
+ Destination
+ 0.0.0.0
+ 0.0.0.0
+
+ 1607
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.4
+ iDRAC.Embedded.1#SNMPAlert.4#Destination
+ false
+ 255
+ 0
+
+
+
+ SNMP V3 Username
+ SNMPv3Username
+
+
+
+ 1609
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.4
+ iDRAC.Embedded.1#SNMPAlert.4#SNMPv3Username
+ false
+ 16
+ 0
+
+
+
+ Alert Destination
+ Destination
+ ::
+ ::
+
+ 1609
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.5
+ iDRAC.Embedded.1#SNMPAlert.5#Destination
+ false
+ 255
+ 0
+
+
+
+ SNMP V3 Username
+ SNMPv3Username
+
+
+
+ 1611
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.5
+ iDRAC.Embedded.1#SNMPAlert.5#SNMPv3Username
+ false
+ 16
+ 0
+
+
+
+ Alert Destination
+ Destination
+ ::
+ ::
+
+ 1611
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.6
+ iDRAC.Embedded.1#SNMPAlert.6#Destination
+ false
+ 255
+ 0
+
+
+
+ SNMP V3 Username
+ SNMPv3Username
+
+
+
+ 1613
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.6
+ iDRAC.Embedded.1#SNMPAlert.6#SNMPv3Username
+ false
+ 16
+ 0
+
+
+
+ Alert Destination
+ Destination
+ ::
+ ::
+
+ 1613
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.7
+ iDRAC.Embedded.1#SNMPAlert.7#Destination
+ false
+ 255
+ 0
+
+
+
+ SNMP V3 Username
+ SNMPv3Username
+
+
+
+ 1615
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.7
+ iDRAC.Embedded.1#SNMPAlert.7#SNMPv3Username
+ false
+ 16
+ 0
+
+
+
+ Alert Destination
+ Destination
+ ::
+ ::
+
+ 1615
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.8
+ iDRAC.Embedded.1#SNMPAlert.8#Destination
+ false
+ 255
+ 0
+
+
+
+ SNMP V3 Username
+ SNMPv3Username
+
+
+
+ 1617
+ iDRAC.Embedded.1
+ SNMP Alert Destination
+ SNMPAlert.8
+ iDRAC.Embedded.1#SNMPAlert.8#SNMPv3Username
+ false
+ 16
+ 0
+
+
+
+ NTP Server 1
+ NTP1
+
+
+
+ 2001
+ iDRAC.Embedded.1
+ NTP Configuration Group
+ NTPConfigGroup.1
+ iDRAC.Embedded.1#NTPConfigGroup.1#NTP1
+ false
+ 254
+ 0
+
+
+
+ NTP server 2
+ NTP2
+
+
+
+ 2002
+ iDRAC.Embedded.1
+ NTP Configuration Group
+ NTPConfigGroup.1
+ iDRAC.Embedded.1#NTPConfigGroup.1#NTP2
+ false
+ 254
+ 0
+
+
+
+ NTP server 3
+ NTP3
+
+
+
+ 2003
+ iDRAC.Embedded.1
+ NTP Configuration Group
+ NTPConfigGroup.1
+ iDRAC.Embedded.1#NTPConfigGroup.1#NTP3
+ false
+ 254
+ 0
+
+
+
+ CSC CSR Common Name
+ CSCCsrCommonName
+
+
+
+ 2100
+ iDRAC.Embedded.1
+ iDRAC Custom Signing Certificate
+ SecurityCSC.1
+ iDRAC.Embedded.1#SecurityCSC.1#CSCCsrCommonName
+ false
+ 64
+ 0
+
+
+
+ CSC CSR Business Name
+ CSCCsrBusiness
+
+
+
+ 2101
+ iDRAC.Embedded.1
+ iDRAC Custom Signing Certificate
+ SecurityCSC.1
+ iDRAC.Embedded.1#SecurityCSC.1#CSCCsrBusiness
+ false
+ 64
+ 0
+
+
+
+ CSC CSR Department Name
+ CSCCsrDeptName
+
+
+
+ 2102
+ iDRAC.Embedded.1
+ iDRAC Custom Signing Certificate
+ SecurityCSC.1
+ iDRAC.Embedded.1#SecurityCSC.1#CSCCsrDeptName
+ false
+ 64
+ 0
+
+
+
+ CSC CSR City Name
+ CSCCsrCityName
+
+
+
+ 2103
+ iDRAC.Embedded.1
+ iDRAC Custom Signing Certificate
+ SecurityCSC.1
+ iDRAC.Embedded.1#SecurityCSC.1#CSCCsrCityName
+ false
+ 64
+ 0
+
+
+
+ CSC CSR State Name
+ CSCCsrStateName
+
+
+
+ 2104
+ iDRAC.Embedded.1
+ iDRAC Custom Signing Certificate
+ SecurityCSC.1
+ iDRAC.Embedded.1#SecurityCSC.1#CSCCsrStateName
+ false
+ 64
+ 0
+
+
+
+ CSC CSR Country Code
+ CSCCsrCountryCode
+
+
+
+ 2105
+ iDRAC.Embedded.1
+ iDRAC Custom Signing Certificate
+ SecurityCSC.1
+ iDRAC.Embedded.1#SecurityCSC.1#CSCCsrCountryCode
+ false
+ 2
+ 0
+
+
+
+ CSC CSR Email Address
+ CSCCsrEmailAddr
+
+
+
+ 2106
+ iDRAC.Embedded.1
+ iDRAC Custom Signing Certificate
+ SecurityCSC.1
+ iDRAC.Embedded.1#SecurityCSC.1#CSCCsrEmailAddr
+ false
+ 64
+ 0
+
+
+
+ IPv6 URL
+ URL
+
+
+
+ 2120
+ iDRAC.Embedded.1
+ iDRAC IPv6 URL
+ IPv6URL.1
+ iDRAC.Embedded.1#IPv6URL.1#URL
+ true
+ 80
+ 0
+
+
+
+ Version of installed ServiceModule
+ ServiceModuleVersion
+ NA
+ NA
+
+ 2158
+ iDRAC.Embedded.1
+ ServiceModule
+ ServiceModule.1
+ iDRAC.Embedded.1#ServiceModule.1#ServiceModuleVersion
+ true
+ 256
+ 0
+
+
+
+ First Boot Device
+ FirstBootDevice
+ Normal
+
+
+ 2190
+ iDRAC.Embedded.1
+ Server Boot
+ ServerBoot.1
+ iDRAC.Embedded.1#ServerBoot.1#FirstBootDevice
+ false
+ 65
+ 0
+
+
+
+ User Admin Password
+ Password
+ ******
+
+
+ 252
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.1
+ iDRAC.Embedded.1#Users.1#Password
+ true
+ 20
+ 0
+
+
+
+ User Admin Password
+ Password
+ ******
+
+
+ 262
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.2
+ iDRAC.Embedded.1#Users.2#Password
+ false
+ 20
+ 0
+
+
+
+ User Admin Password
+ Password
+ ******
+
+
+ 272
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.3
+ iDRAC.Embedded.1#Users.3#Password
+ false
+ 20
+ 0
+
+
+
+ User Admin Password
+ Password
+ ******
+
+
+ 282
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.4
+ iDRAC.Embedded.1#Users.4#Password
+ false
+ 20
+ 0
+
+
+
+ User Admin Password
+ Password
+ ******
+
+
+ 292
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.5
+ iDRAC.Embedded.1#Users.5#Password
+ false
+ 20
+ 0
+
+
+
+ User Admin Password
+ Password
+ ******
+
+
+ 302
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.6
+ iDRAC.Embedded.1#Users.6#Password
+ false
+ 20
+ 0
+
+
+
+ User Admin Password
+ Password
+ ******
+
+
+ 312
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.7
+ iDRAC.Embedded.1#Users.7#Password
+ false
+ 20
+ 0
+
+
+
+ User Admin Password
+ Password
+ ******
+
+
+ 322
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.8
+ iDRAC.Embedded.1#Users.8#Password
+ false
+ 20
+ 0
+
+
+
+ User Admin Password
+ Password
+ ******
+
+
+ 332
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.9
+ iDRAC.Embedded.1#Users.9#Password
+ false
+ 20
+ 0
+
+
+
+ User Admin Password
+ Password
+ ******
+
+
+ 342
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.10
+ iDRAC.Embedded.1#Users.10#Password
+ false
+ 20
+ 0
+
+
+
+ User Admin Password
+ Password
+ ******
+
+
+ 352
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.11
+ iDRAC.Embedded.1#Users.11#Password
+ false
+ 20
+ 0
+
+
+
+ User Admin Password
+ Password
+ ******
+
+
+ 362
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.12
+ iDRAC.Embedded.1#Users.12#Password
+ false
+ 20
+ 0
+
+
+
+ User Admin Password
+ Password
+ ******
+
+
+ 372
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.13
+ iDRAC.Embedded.1#Users.13#Password
+ false
+ 20
+ 0
+
+
+
+ User Admin Password
+ Password
+ ******
+
+
+ 382
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.14
+ iDRAC.Embedded.1#Users.14#Password
+ false
+ 20
+ 0
+
+
+
+ User Admin Password
+ Password
+ ******
+
+
+ 392
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.15
+ iDRAC.Embedded.1#Users.15#Password
+ false
+ 20
+ 0
+
+
+
+ User Admin Password
+ Password
+ ******
+
+
+ 402
+ iDRAC.Embedded.1
+ iDRAC Users
+ Users.16
+ iDRAC.Embedded.1#Users.16#Password
+ false
+ 20
+ 0
+
+
+
+ SMTP Password
+ SMTPPassword
+ ******
+
+
+ 545
+ iDRAC.Embedded.1
+ RAC Remote Hosts
+ RemoteHosts.1
+ iDRAC.Embedded.1#RemoteHosts.1#SMTPPassword
+ false
+ 50
+ 0
+
+
+
+ LDAP Bind Password
+ BindPassword
+ ******
+
+
+ 1089
+ iDRAC.Embedded.1
+ LDAP
+ LDAP.1
+ iDRAC.Embedded.1#LDAP.1#BindPassword
+ false
+ 254
+ 0
+
+
+
+ Password
+ Password
+ ******
+ NULL
+
+ 2163
+ iDRAC.Embedded.1
+ RAC VNC Server
+ VNCServer.1
+ iDRAC.Embedded.1#VNCServer.1#Password
+ false
+ 8
+ 0
+
+
+
+
+
+
+
+
diff --git a/dracclient/tests/wsman_mocks/job_service-delete-job-id-error.xml b/dracclient/tests/wsman_mocks/job_service-delete-job-id-error.xml
new file mode 100644
index 0000000..1723f51
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/job_service-delete-job-id-error.xml
@@ -0,0 +1,21 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_JobService/DeleteJobQueueResponse
+
+ uuid:bd334a80-bd6f-4fc9-88cc-9c9cb79d41e8
+
+ uuid:ce21f862-70ac-10ac-b40d-64b5b4da6618
+
+
+
+
+ Invalid Job ID
+ SUP011
+ 2
+
+
+
\ No newline at end of file
diff --git a/dracclient/tests/wsman_mocks/job_service-delete-job-id-ok.xml b/dracclient/tests/wsman_mocks/job_service-delete-job-id-ok.xml
new file mode 100644
index 0000000..319225a
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/job_service-delete-job-id-ok.xml
@@ -0,0 +1,21 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_JobService/DeleteJobQueueResponse
+
+ uuid:5f1b62ee-19d4-4679-b083-477086856c79
+
+ uuid:07b2e831-70ae-10ae-b56f-64b5b4da6618
+
+
+
+
+ The specified job was deleted
+ SUP020
+ 0
+
+
+
\ No newline at end of file
diff --git a/dracclient/tests/wsman_mocks/lc_enumeration-enum-ok.xml b/dracclient/tests/wsman_mocks/lc_enumeration-enum-ok.xml
new file mode 100644
index 0000000..3e1d30a
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/lc_enumeration-enum-ok.xml
@@ -0,0 +1,144 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse
+ uuid:68f2fe2e-1424-4833-9ac0-756f24db2542
+ uuid:3ae5f7b2-40a9-10a9-8061-de7e4e771814
+
+
+
+
+
+ Collect System Inventory on Restart
+ Enabled
+ Enabled
+ LC.emb.1
+ LifecycleController.Embedded.1#LCAttributes.1#CollectSystemInventoryOnRestart
+ false
+
+ Disabled
+ Enabled
+
+
+ Part Configuration Update
+ Apply always
+ Apply always
+ LC.emb.1
+ LifecycleController.Embedded.1#LCAttributes.1#PartConfigurationUpdate
+ false
+
+ Disabled
+ Apply always
+ Apply only if firmware match
+
+
+ Part Firmware Update
+ Match firmware of replaced part
+ Match firmware of replaced part
+ LC.emb.1
+ LifecycleController.Embedded.1#LCAttributes.1#PartFirmwareUpdate
+ false
+
+ Disable
+ Allow version upgrade only
+ Match firmware of replaced part
+
+
+ Lifecycle Controller State
+ Enabled
+ Enabled
+ LC.emb.1
+ LifecycleController.Embedded.1#LCAttributes.1#LifecycleControllerState
+ false
+
+ Disabled
+ Enabled
+ Recovery
+
+
+ Licensed
+ Yes
+ No
+ LC.emb.1
+ LifecycleController.Embedded.1#LCAttributes.1#Licensed
+ true
+
+ No
+ Yes
+
+
+ Auto Discovery
+ Off
+ Off
+ LC.emb.1
+ LifecycleController.Embedded.1#LCAttributes.1#AutoDiscovery
+ true
+
+ Off
+ On
+
+
+ Discovery Factory Defaults
+ Off
+ Off
+ LC.emb.1
+ LifecycleController.Embedded.1#LCAttributes.1#DiscoveryFactoryDefaults
+ true
+
+ Off
+ On
+
+
+ IPChangeNotifyPS
+ Off
+ Off
+ LC.emb.1
+ LifecycleController.Embedded.1#LCAttributes.1#IPChangeNotifyPS
+ false
+
+ Off
+ On
+
+
+ BIOS Reset To Defaults Requested
+ False
+ False
+ LC.emb.1
+ LifecycleController.Embedded.1#LCAttributes.1#BIOSRTDRequested
+ false
+
+ False
+ True
+
+
+ Automatic Update Feature
+ Enabled
+ Disabled
+ LC.emb.1
+ LifecycleController.Embedded.1#LCAttributes.1#AutoUpdate
+ false
+
+ Disabled
+ Enabled
+
+ Automatic Backup Feature
+ Disabled
+ Disabled
+ LC.emb.1
+ LifecycleController.Embedded.1#LCAttributes.1#AutoBackup
+ false
+
+ Disabled
+ Enabled
+
+
+
+
+
+
+
diff --git a/dracclient/tests/wsman_mocks/lc_getremoteservicesapistatus_not_ready.xml b/dracclient/tests/wsman_mocks/lc_getremoteservicesapistatus_not_ready.xml
new file mode 100644
index 0000000..accd14f
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/lc_getremoteservicesapistatus_not_ready.xml
@@ -0,0 +1,19 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_LCService/GetRemoteServicesAPIStatusResponse
+ uuid:3ef0c018-3169-4184-9d81-ee1a73059940
+ uuid:9d5ff7cc-4fc0-1fc0-8090-98d61742a844
+
+
+
+ 5
+ Lifecycle Controller Remote Services is not ready.
+ LC060
+ 0
+ 0
+ 2
+ 1
+
+
+
diff --git a/dracclient/tests/wsman_mocks/lc_getremoteservicesapistatus_ready.xml b/dracclient/tests/wsman_mocks/lc_getremoteservicesapistatus_ready.xml
new file mode 100644
index 0000000..c7dd1c9
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/lc_getremoteservicesapistatus_ready.xml
@@ -0,0 +1,19 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_LCService/GetRemoteServicesAPIStatusResponse
+ uuid:18745811-2782-4d30-a288-8f001a895215
+ uuid:9ec203ba-4fc0-1fc0-8094-98d61742a844
+
+
+
+ 0
+ Lifecycle Controller Remote Services is ready.
+ LC061
+ 0
+ 0
+ 2
+ 0
+
+
+
diff --git a/dracclient/tests/wsman_mocks/lc_getremoteservicesapistatus_recovery.xml b/dracclient/tests/wsman_mocks/lc_getremoteservicesapistatus_recovery.xml
new file mode 100644
index 0000000..97b3a3a
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/lc_getremoteservicesapistatus_recovery.xml
@@ -0,0 +1,19 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_LCService/GetRemoteServicesAPIStatusResponse
+ uuid:18745811-2782-4d30-a288-8f001a895215
+ uuid:9ec203ba-4fc0-1fc0-8094-98d61742a844
+
+
+
+ 4
+ Lifecycle Controller Remote Services is not ready.
+ LC060
+ 0
+ 0
+ 7
+ 1
+
+
+
diff --git a/dracclient/tests/wsman_mocks/lc_service-invoke-create_config_job-error.xml b/dracclient/tests/wsman_mocks/lc_service-invoke-create_config_job-error.xml
new file mode 100644
index 0000000..c375bb7
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/lc_service-invoke-create_config_job-error.xml
@@ -0,0 +1,17 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_LCService/CreateConfigJobResponse
+ uuid:80cf5e1b-b109-4ef5-87c8-5b03ce6ba117
+ uuid:e57fa514-2189-1189-8ec1-a36fc6fe83b0
+
+
+
+ Configuration job already created, cannot create another config job on specified target until existing job is completed or is cancelled
+ LC007
+ 2
+
+
+
diff --git a/dracclient/tests/wsman_mocks/lc_service-invoke-create_config_job-ok.xml b/dracclient/tests/wsman_mocks/lc_service-invoke-create_config_job-ok.xml
new file mode 100644
index 0000000..b7ec83c
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/lc_service-invoke-create_config_job-ok.xml
@@ -0,0 +1,28 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_LCService/CreateConfigJobResponse
+ uuid:fc2fdae5-6ac2-4338-9b2e-e69b813af829
+ uuid:d7d89957-2189-1189-8ec0-a36fc6fe83b0
+
+
+
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_LifecycleJob
+
+ JID_442507917525
+ root/dcim
+
+
+
+
+ 4096
+
+
+
diff --git a/dracclient/tests/wsman_mocks/lc_service-invoke-set_attributes-error.xml b/dracclient/tests/wsman_mocks/lc_service-invoke-set_attributes-error.xml
new file mode 100644
index 0000000..c2c0b75
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/lc_service-invoke-set_attributes-error.xml
@@ -0,0 +1,21 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_LCService/SetAttributesResponse
+
+ uuid:bf8adefe-6fc0-456d-b97c-fd8d4aca2d6c
+
+ uuid:84abf7b9-7176-1176-a11c-a53ffbd9bed4
+
+
+
+
+ Invalid AttributeName.
+ LC057
+ 2
+
+
+
diff --git a/dracclient/tests/wsman_mocks/lc_service-invoke-set_attributes-ok.xml b/dracclient/tests/wsman_mocks/lc_service-invoke-set_attributes-ok.xml
new file mode 100644
index 0000000..7c4ff98
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/lc_service-invoke-set_attributes-ok.xml
@@ -0,0 +1,24 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_LCService/SetAttributesResponse
+
+ uuid:bf8adefe-6fc0-456d-b97c-fd8d4aca2d6c
+
+ uuid:84abf7b9-7176-1176-a11c-a53ffbd9bed4
+
+
+
+
+ LC001
+ The command was successful
+ 0
+ No
+ Set PendingValue
+
+
+
+
diff --git a/dracclient/tests/wsman_mocks/lc_string-enum-ok.xml b/dracclient/tests/wsman_mocks/lc_string-enum-ok.xml
new file mode 100644
index 0000000..95662b3
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/lc_string-enum-ok.xml
@@ -0,0 +1,55 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse
+ uuid:d0ede1a5-1f68-4bf6-a4ed-b528e92419db
+ uuid:159ae3a2-40aa-10aa-8171-de7e4e771814
+
+
+
+
+
+ SYSID
+ 639
+ LC.emb.1
+ LifecycleController.Embedded.1#LCAttributes.1#SystemID
+ true
+ 3
+ 0
+
+ 3
+
+
+ VirtualAddressManagementApplication
+
+
+ LC.emb.1
+ LifecycleController.Embedded.1#LCAttributes.1#VirtualAddressManagementApplication
+ false
+ 32
+ 0
+
+ 2
+
+
+ Provisioning Server
+
+ LC.emb.1
+ LifecycleController.Embedded.1#LCAttributes.1#ProvisioningServer
+ false
+ 255
+ 0
+
+ 2
+
+
+
+
+
+
+
diff --git a/dracclient/tests/wsman_mocks/nic_enumeration-enum-ok.xml b/dracclient/tests/wsman_mocks/nic_enumeration-enum-ok.xml
new file mode 100644
index 0000000..a6ebf09
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/nic_enumeration-enum-ok.xml
@@ -0,0 +1,767 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+
+ http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse
+
+ uuid:608d7722-0302-4feb-8080-4652e0e0ab48
+
+ uuid:07820ac0-71f0-11f0-a4a1-a53ffbd9bed4
+
+
+
+
+
+
+ Link Status
+ LinkStatus
+ Connected
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:LinkStatus
+ true
+
+ Disconnected
+ Connected
+ Disconnected
+
+ Connected
+
+
+
+ TCP/IP Parameters via DHCP
+
+ TcpIpViaDHCP
+ Enabled
+ IPv6Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-3-1:TcpIpViaDHCP
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ IP Autoconfiguration
+
+ IpAutoConfig
+ Enabled
+ IPv4Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-3-1:IpAutoConfig
+ true
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ iSCSI Parameters via DHCP
+
+ IscsiViaDHCP
+ Enabled
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-3-1:IscsiViaDHCP
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ CHAP Authentication
+
+ ChapAuthEnable
+ Disabled
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-3-1:ChapAuthEnable
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ Boot to iSCSI Target
+
+ IscsiTgtBoot
+ Enabled
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-3-1:IscsiTgtBoot
+ false
+
+ Disabled
+ Enabled
+ OneTimeDisabled
+ Disabled
+
+ Enabled
+
+ One Time Disabled
+
+
+
+ Use TCP Timestamp
+
+ TcpTimestmp
+ Disabled
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-3-1:TcpTimestmp
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ Target as First HDD
+
+ FirstHddTarget
+ Disabled
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-3-1:FirstHddTarget
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ IP Version
+ IpVer
+ IPv4
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-3-1:IpVer
+ false
+
+ IPv4
+ IPv6
+ IPv4
+ IPv6
+
+
+ Connect
+ ConnectFirstTgt
+ Disabled
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-3-1:ConnectFirstTgt
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ Connect
+ ConnectSecondTgt
+ Disabled
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-3-1:ConnectSecondTgt
+
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ Legacy Boot Protocol
+
+ LegacyBootProto
+ PXE
+
+ NIC.Integrated.1-3-1
+ MBA Configuration Menu
+ NICConfig
+ NIC.Integrated.1-3-1:LegacyBootProto
+ false
+ NONE
+ PXE
+ iSCSI
+ NONE
+ PXE
+ iSCSI
+ NONE
+
+
+ Boot Strap Type
+ BootStrapType
+ AutoDetect
+
+ NIC.Integrated.1-3-1
+ MBA Configuration Menu
+ NICConfig
+ NIC.Integrated.1-3-1:BootStrapType
+ false
+
+ AutoDetect
+ BBS
+ Int18h
+ Int19h
+ Auto Detect
+
+ BBS
+ Int 18h
+
+ Int 19h
+
+
+
+ Hide Setup Prompt
+
+ HideSetupPrompt
+ Disabled
+
+ NIC.Integrated.1-3-1
+ MBA Configuration Menu
+ NICConfig
+ NIC.Integrated.1-3-1:HideSetupPrompt
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ Link Speed
+ LnkSpeed
+ AutoNeg
+
+ NIC.Integrated.1-3-1
+ MBA Configuration Menu
+ NICConfig
+ NIC.Integrated.1-3-1:LnkSpeed
+ false
+
+ AutoNeg
+ 10MbpsHalf
+ 10MbpsFull
+ 100MbpsHalf
+ 100MbpsFull
+ AutoNeg
+
+ 10Mbps Half
+
+ 10Mbps Full
+
+ 100Mbps Half
+
+ 100Mbps Full
+
+
+
+ Pre-boot Wake On LAN
+
+ WakeOnLan
+ Disabled
+
+ NIC.Integrated.1-3-1
+ MBA Configuration Menu
+ NICConfig
+ NIC.Integrated.1-3-1:WakeOnLan
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ VLAN Mode
+ VLanMode
+ Disabled
+
+ NIC.Integrated.1-3-1
+ MBA Configuration Menu
+ NICConfig
+ NIC.Integrated.1-3-1:VLanMode
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ Use Independent Target Portal
+
+ UseIndTgtPortal
+ Disabled
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ Secondary Device
+ SecondaryDevice
+ NIC.Integrated.1-3-1:UseIndTgtPortal
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ Use Independent Target Name
+
+ UseIndTgtName
+ Disabled
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ Secondary Device
+ SecondaryDevice
+ NIC.Integrated.1-3-1:UseIndTgtName
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ Link Status
+ LinkStatus
+ Disconnected
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:LinkStatus
+ true
+
+ Disconnected
+ Connected
+ Disconnected
+
+ Connected
+
+
+
+ TCP/IP Parameters via DHCP
+
+ TcpIpViaDHCP
+ Enabled
+ IPv6Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-4-1:TcpIpViaDHCP
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ IP Autoconfiguration
+
+ IpAutoConfig
+ Enabled
+ IPv4Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-4-1:IpAutoConfig
+ true
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ iSCSI Parameters via DHCP
+
+ IscsiViaDHCP
+ Enabled
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-4-1:IscsiViaDHCP
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ CHAP Authentication
+
+ ChapAuthEnable
+ Disabled
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-4-1:ChapAuthEnable
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ Boot to iSCSI Target
+
+ IscsiTgtBoot
+ Enabled
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-4-1:IscsiTgtBoot
+ false
+
+ Disabled
+ Enabled
+ OneTimeDisabled
+ Disabled
+
+ Enabled
+
+ One Time Disabled
+
+
+
+ Use TCP Timestamp
+
+ TcpTimestmp
+ Disabled
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-4-1:TcpTimestmp
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ Target as First HDD
+
+ FirstHddTarget
+ Disabled
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-4-1:FirstHddTarget
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ IP Version
+ IpVer
+ IPv4
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-4-1:IpVer
+ false
+
+ IPv4
+ IPv6
+ IPv4
+ IPv6
+
+
+ Connect
+ ConnectFirstTgt
+ Disabled
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-4-1:ConnectFirstTgt
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ Connect
+ ConnectSecondTgt
+ Disabled
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-4-1:ConnectSecondTgt
+
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ Legacy Boot Protocol
+
+ LegacyBootProto
+ NONE
+
+ NIC.Integrated.1-4-1
+ MBA Configuration Menu
+ NICConfig
+ NIC.Integrated.1-4-1:LegacyBootProto
+ false
+
+ PXE
+ iSCSI
+ NONE
+ PXE
+ iSCSI
+ NONE
+
+
+ Boot Strap Type
+ BootStrapType
+ AutoDetect
+
+ NIC.Integrated.1-4-1
+ MBA Configuration Menu
+ NICConfig
+ NIC.Integrated.1-4-1:BootStrapType
+ false
+
+ AutoDetect
+ BBS
+ Int18h
+ Int19h
+ Auto Detect
+
+ BBS
+ Int 18h
+
+ Int 19h
+
+
+
+ Hide Setup Prompt
+
+ HideSetupPrompt
+ Disabled
+
+ NIC.Integrated.1-4-1
+ MBA Configuration Menu
+ NICConfig
+ NIC.Integrated.1-4-1:HideSetupPrompt
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ Link Speed
+ LnkSpeed
+ AutoNeg
+
+ NIC.Integrated.1-4-1
+ MBA Configuration Menu
+ NICConfig
+ NIC.Integrated.1-4-1:LnkSpeed
+ false
+
+ AutoNeg
+ 10MbpsHalf
+ 10MbpsFull
+ 100MbpsHalf
+ 100MbpsFull
+ AutoNeg
+
+ 10Mbps Half
+
+ 10Mbps Full
+
+ 100Mbps Half
+
+ 100Mbps Full
+
+
+
+ Pre-boot Wake On LAN
+
+ WakeOnLan
+ Disabled
+
+ NIC.Integrated.1-4-1
+ MBA Configuration Menu
+ NICConfig
+ NIC.Integrated.1-4-1:WakeOnLan
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ VLAN Mode
+ VLanMode
+ Disabled
+
+ NIC.Integrated.1-4-1
+ MBA Configuration Menu
+ NICConfig
+ NIC.Integrated.1-4-1:VLanMode
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ Use Independent Target Portal
+
+ UseIndTgtPortal
+ Disabled
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ Secondary Device
+ SecondaryDevice
+ NIC.Integrated.1-4-1:UseIndTgtPortal
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+ Use Independent Target Name
+
+ UseIndTgtName
+ Disabled
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ Secondary Device
+ SecondaryDevice
+ NIC.Integrated.1-4-1:UseIndTgtName
+ false
+
+ Disabled
+ Enabled
+ Disabled
+
+ Enabled
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dracclient/tests/wsman_mocks/nic_integer-enum-ok.xml b/dracclient/tests/wsman_mocks/nic_integer-enum-ok.xml
new file mode 100644
index 0000000..b61485b
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/nic_integer-enum-ok.xml
@@ -0,0 +1,298 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+
+ http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse
+
+ uuid:b37882c2-0355-4b03-b3b8-1cb69bf00a74
+
+ uuid:8473faf6-71f0-11f0-a53f-a53ffbd9bed4
+
+
+
+
+
+
+ Blink LEDs
+ BlnkLeds
+ 0
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:BlnkLeds
+ false
+ 0
+
+ 15
+
+
+ Link Up Delay Time
+
+ LnkUpDelayTime
+ 0
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-3-1:LnkUpDelayTime
+ false
+ 0
+
+ 255
+
+
+ LUN Busy Retry Count
+
+ LunBusyRetryCnt
+ 0
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-3-1:LunBusyRetryCnt
+ false
+ 0
+
+ 60
+
+
+ TCP Port
+ FirstTgtTcpPort
+ 3260
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-3-1:FirstTgtTcpPort
+ false
+ 1
+
+ 65535
+
+
+ Boot LUN
+ FirstTgtBootLun
+ 0
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-3-1:FirstTgtBootLun
+ false
+ 0
+
+ 255
+
+
+ TCP Port
+ SecondTgtTcpPort
+ 3260
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-3-1:SecondTgtTcpPort
+
+ false
+ 1
+
+ 65535
+
+
+ Boot LUN
+ SecondTgtBootLun
+ 0
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-3-1:SecondTgtBootLun
+
+ false
+ 0
+
+ 255
+
+
+ Banner Message Timeout
+
+ BannerMessageTimeout
+ 5
+
+ NIC.Integrated.1-3-1
+ MBA Configuration Menu
+ NICConfig
+ NIC.Integrated.1-3-1:BannerMessageTimeout
+
+ false
+ 0
+
+ 14
+
+
+ VLAN ID (1..4094)
+
+ VLanId
+ 1
+ Disabled]]>
+ NIC.Integrated.1-3-1
+ MBA Configuration Menu
+ NICConfig
+ NIC.Integrated.1-3-1:VLanId
+ true
+ 1
+
+ 4094
+
+
+ Blink LEDs
+ BlnkLeds
+ 0
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:BlnkLeds
+ false
+ 0
+
+ 15
+
+
+ Link Up Delay Time
+
+ LnkUpDelayTime
+ 0
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-4-1:LnkUpDelayTime
+ false
+ 0
+
+ 255
+
+
+ LUN Busy Retry Count
+
+ LunBusyRetryCnt
+ 0
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-4-1:LunBusyRetryCnt
+ false
+ 0
+
+ 60
+
+
+ TCP Port
+ FirstTgtTcpPort
+ 3260
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-4-1:FirstTgtTcpPort
+ false
+ 1
+
+ 65535
+
+
+ Boot LUN
+ FirstTgtBootLun
+ 0
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-4-1:FirstTgtBootLun
+ false
+ 0
+
+ 255
+
+
+ TCP Port
+ SecondTgtTcpPort
+ 3260
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-4-1:SecondTgtTcpPort
+
+ false
+ 1
+
+ 65535
+
+
+ Boot LUN
+ SecondTgtBootLun
+ 0
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-4-1:SecondTgtBootLun
+
+ false
+ 0
+ 2
+
+ 255
+
+
+ Banner Message Timeout
+
+ BannerMessageTimeout
+ 5
+
+ NIC.Integrated.1-4-1
+ MBA Configuration Menu
+ NICConfig
+ NIC.Integrated.1-4-1:BannerMessageTimeout
+
+ false
+ 0
+
+ 14
+
+
+ VLAN ID (1..4094)
+
+ VLanId
+ 1
+ Disabled]]>
+ NIC.Integrated.1-4-1
+ MBA Configuration Menu
+ NICConfig
+ NIC.Integrated.1-4-1:VLanId
+ true
+ 1
+
+ 4094
+
+
+
+
+
\ No newline at end of file
diff --git a/dracclient/tests/wsman_mocks/nic_service-invoke-set_attributes-error.xml b/dracclient/tests/wsman_mocks/nic_service-invoke-set_attributes-error.xml
new file mode 100644
index 0000000..2d18ed8
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/nic_service-invoke-set_attributes-error.xml
@@ -0,0 +1,22 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_NICService/SetAttributesResponse
+
+ uuid:e24aa9e2-28f3-487d-8f69-ab4234a2c9ba
+
+ uuid:d3770d92-7202-1202-b927-a53ffbd9bed4
+
+
+
+
+ Invalid parameter value for Target
+ Target
+ NIC004
+ 2
+
+
+
diff --git a/dracclient/tests/wsman_mocks/nic_service-invoke-set_attributes-ok.xml b/dracclient/tests/wsman_mocks/nic_service-invoke-set_attributes-ok.xml
new file mode 100644
index 0000000..66ae03f
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/nic_service-invoke-set_attributes-ok.xml
@@ -0,0 +1,23 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_NICService/SetAttributesResponse
+
+ uuid:bf8adefe-6fc0-456d-b97c-fd8d4aca2d6c
+
+ uuid:84abf7b9-7176-1176-a11c-a53ffbd9bed4
+
+
+
+
+ The command was successful.
+ NIC001
+ Yes
+ 0
+ Set PendingValue
+
+
+
\ No newline at end of file
diff --git a/dracclient/tests/wsman_mocks/nic_string-enum-colliding.xml b/dracclient/tests/wsman_mocks/nic_string-enum-colliding.xml
new file mode 100644
index 0000000..0aa8268
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/nic_string-enum-colliding.xml
@@ -0,0 +1,1185 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+
+ http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse
+
+ uuid:48fa32d6-5bdb-4080-a9cb-040fdd600ece
+
+ uuid:66b00908-71f0-11f0-a516-a53ffbd9bed4
+
+
+
+
+
+
+ Link Status
+ LinkStatus
+ BCM5720 A0
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:ChipMdl
+ true
+ 0
+ 0
+
+
+
+
+ PCI Device ID
+ PCIDeviceID
+ 165F
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:PCIDeviceID
+ true
+ 0
+ 0
+
+
+
+
+ Bus:Dev:Func
+ BusDeviceFunction
+ 02:00:00
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:BusDeviceFunction
+
+ true
+ 0
+ 0
+
+
+
+
+ Permanent MAC Address
+
+ MacAddr
+ D4:AE:52:A5:B1:EA
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:MacAddr
+ true
+ 17
+ 17
+
+
+
+
+ Virtual MAC Address
+
+ VirtMacAddr
+ D4:AE:52:A5:B1:EA
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:VirtMacAddr
+ false
+ 17
+ 17
+
+ ^([0-9a-fA-F]{2}:){5}([0-9a-fA-F]{2})$
+
+
+
+ FCoE Offload Support
+
+ FCoEOffloadSupport
+ Unavailable
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:FCoEOffloadSupport
+
+ true
+ 12
+ 0
+
+
+
+
+ iSCSI Offload Support
+
+ iSCSIOffloadSupport
+ Unavailable
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:iSCSIOffloadSupport
+
+ true
+ 12
+ 0
+
+
+
+
+ IBS
+ iSCSIBootSupport
+ Available
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:iSCSIBootSupport
+
+ true
+ 12
+ 0
+
+
+
+
+ PBS
+ PXEBootSupport
+ Available
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:PXEBootSupport
+ true
+ 12
+ 0
+
+
+
+
+ FBS
+ FCoEBootSupport
+ Unavailable
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:FCoEBootSupport
+ true
+ 12
+ 0
+
+
+
+
+ NPS
+ NicPartitioningSupport
+ Unavailable
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:NicPartitioningSupport
+
+ true
+ 12
+ 0
+
+
+
+
+ TBMax
+ TXBandwidthControlMaximum
+ Unavailable
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:TXBandwidthControlMaximum
+
+ true
+ 12
+ 0
+
+
+
+
+ TBMin
+ TXBandwidthControlMinimum
+ Unavailable
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:TXBandwidthControlMinimum
+
+ true
+ 12
+ 0
+
+
+
+
+ DHCP Vendor ID
+ DhcpVendId
+ BRCM ISAN
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-3-1:DhcpVendId
+ false
+ 32
+ 0
+
+
+
+
+ IP Address
+ IscsiInitiatorIpAddr
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-3-1:IscsiInitiatorIpAddr
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ Subnet Mask
+ IscsiInitiatorSubnet
+ 0.0.0.0
+ UnavailableIPv6]]>
+ NIC.Integrated.1-3-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-3-1:IscsiInitiatorSubnet
+
+ false
+ 15
+ 7
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}$
+
+
+
+ Subnet Mask Prefix
+
+ IscsiInitiatorSubnetPrefix
+
+ UnavailableIPv4]]>
+ NIC.Integrated.1-3-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-3-1:IscsiInitiatorSubnetPrefix
+
+ true
+ 3
+ 1
+
+
+
+
+ Default Gateway
+ IscsiInitiatorGateway
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-3-1:IscsiInitiatorGateway
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ Primary DNS
+ IscsiInitiatorPrimDns
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-3-1:IscsiInitiatorPrimDns
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ Secondary DNS
+ IscsiInitiatorSecDns
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-3-1:IscsiInitiatorSecDns
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ iSCSI Name
+ IscsiInitiatorName
+ iqn.1995-05.com.broadcom.iscsiboot
+
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-3-1:IscsiInitiatorName
+
+ false
+ 128
+ 0
+
+ ^[-0-9a-zA-Z.:_]{0,128}$
+
+
+ CHAP ID
+ IscsiInitiatorChapId
+
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-3-1:IscsiInitiatorChapId
+
+ false
+ 128
+ 0
+
+ ^[x20-~]{0,128}$
+
+
+ CHAP Secret
+ IscsiInitiatorChapPwd
+
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-3-1:IscsiInitiatorChapPwd
+
+ false
+ 16
+ 0
+
+ ^[x20-~]{0,16}$
+
+
+ IP Address
+ FirstTgtIpAddress
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-3-1:FirstTgtIpAddress
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ iSCSI Name
+ FirstTgtIscsiName
+
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-3-1:FirstTgtIscsiName
+
+ false
+ 128
+ 0
+
+ ^[-0-9a-zA-Z.:_]{0,128}$
+
+
+ CHAP ID
+ FirstTgtChapId
+
+
+ NIC.Integrated.1-3-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-3-1:FirstTgtChapId
+ false
+ 128
+ 0
+
+ ^[x20-~]{0,128}$
+
+
+ CHAP Secret
+ FirstTgtChapPwd
+
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-3-1:FirstTgtChapPwd
+ false
+ 16
+ 0
+
+ ^[x20-~]{0,16}$
+
+
+ IP Address
+ SecondTgtIpAddress
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-3-1:SecondTgtIpAddress
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ iSCSI Name
+ SecondTgtIscsiName
+
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-3-1:SecondTgtIscsiName
+
+ false
+ 128
+ 0
+
+ ^[-0-9a-zA-Z.:_]{0,128}$
+
+
+ CHAP ID
+ SecondTgtChapId
+
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-3-1:SecondTgtChapId
+ false
+ 128
+ 0
+
+ ^[x20-~]{0,128}$
+
+
+ CHAP Secret
+ SecondTgtChapPwd
+
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-3-1:SecondTgtChapPwd
+
+ false
+ 16
+ 0
+
+ ^[x20-~]{0,16}$
+
+
+ Firmware Family Version
+
+ FamilyVersion
+ 7.4.8
+
+ NIC.Integrated.1-3-1
+ Firmware Image Menu
+ FrmwImgMenu
+ NIC.Integrated.1-3-1:FamilyVersion
+ true
+ 20
+ 0
+
+
+
+
+ Bootcode
+ ControllerBIOSVersion
+ 1.30
+
+ NIC.Integrated.1-3-1
+ Firmware Image Menu
+ FrmwImgMenu
+ NIC.Integrated.1-3-1:ControllerBIOSVersion
+
+ true
+ 9
+ 0
+
+
+
+
+ EFI
+ EFIVersion
+ 15.4.6
+
+ NIC.Integrated.1-3-1
+ Firmware Image Menu
+ FrmwImgMenu
+ NIC.Integrated.1-3-1:EFIVersion
+ true
+ 9
+ 0
+
+
+
+
+ Secondary Device
+ SecondaryDeviceMacAddr
+ 00:00:00:00:00:00
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ Secondary Device
+ SecondaryDevice
+ NIC.Integrated.1-3-1:SecondaryDeviceMacAddr
+
+ false
+ 17
+ 17
+
+ ^([0-9a-fA-F]{2}:){5}([0-9a-fA-F]{2})$
+
+
+
+ Chip Type
+ ChipMdl
+ BCM5720 A0
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:ChipMdl
+ true
+ 0
+ 0
+
+
+
+
+ PCI Device ID
+ PCIDeviceID
+ 165F
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:PCIDeviceID
+ true
+ 0
+ 0
+
+
+
+
+ Bus:Dev:Func
+ BusDeviceFunction
+ 02:00:01
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:BusDeviceFunction
+
+ true
+ 0
+ 0
+
+
+
+
+ Permanent MAC Address
+
+ MacAddr
+ D4:AE:52:A5:B1:EB
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:MacAddr
+ true
+ 17
+ 17
+
+
+
+
+ Virtual MAC Address
+
+ VirtMacAddr
+ D4:AE:52:A5:B1:EB
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:VirtMacAddr
+ false
+ 17
+ 17
+
+ ^([0-9a-fA-F]{2}:){5}([0-9a-fA-F]{2})$
+
+
+
+ FCoE Offload Support
+
+ FCoEOffloadSupport
+ Unavailable
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:FCoEOffloadSupport
+
+ true
+ 12
+ 0
+
+
+
+
+ iSCSI Offload Support
+
+ iSCSIOffloadSupport
+ Unavailable
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:iSCSIOffloadSupport
+
+ true
+ 12
+ 0
+
+
+
+
+ IBS
+ iSCSIBootSupport
+ Available
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:iSCSIBootSupport
+
+ true
+ 12
+ 0
+
+
+
+
+ PBS
+ PXEBootSupport
+ Available
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:PXEBootSupport
+ true
+ 12
+ 0
+
+
+
+
+ FBS
+ FCoEBootSupport
+ Unavailable
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:FCoEBootSupport
+ true
+ 12
+ 0
+
+
+
+
+ NPS
+ NicPartitioningSupport
+ Unavailable
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:NicPartitioningSupport
+
+ true
+ 12
+ 0
+
+
+
+
+ TBMax
+ TXBandwidthControlMaximum
+ Unavailable
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:TXBandwidthControlMaximum
+
+ true
+ 12
+ 0
+
+
+
+
+ TBMin
+ TXBandwidthControlMinimum
+ Unavailable
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:TXBandwidthControlMinimum
+
+ true
+ 12
+ 0
+
+
+
+
+ DHCP Vendor ID
+ DhcpVendId
+ BRCM ISAN
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-4-1:DhcpVendId
+ false
+ 32
+ 0
+
+
+
+
+ IP Address
+ IscsiInitiatorIpAddr
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-4-1:IscsiInitiatorIpAddr
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ Subnet Mask
+ IscsiInitiatorSubnet
+ 0.0.0.0
+ UnavailableIPv6]]>
+ NIC.Integrated.1-4-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-4-1:IscsiInitiatorSubnet
+
+ false
+ 15
+ 7
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}$
+
+
+
+ Subnet Mask Prefix
+
+ IscsiInitiatorSubnetPrefix
+
+ UnavailableIPv4]]>
+ NIC.Integrated.1-4-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-4-1:IscsiInitiatorSubnetPrefix
+
+ true
+ 3
+ 1
+
+
+
+
+ Default Gateway
+ IscsiInitiatorGateway
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-4-1:IscsiInitiatorGateway
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ Primary DNS
+ IscsiInitiatorPrimDns
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-4-1:IscsiInitiatorPrimDns
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ Secondary DNS
+ IscsiInitiatorSecDns
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-4-1:IscsiInitiatorSecDns
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ iSCSI Name
+ IscsiInitiatorName
+ iqn.1995-05.com.broadcom.iscsiboot
+
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-4-1:IscsiInitiatorName
+
+ false
+ 128
+ 0
+
+ ^[-0-9a-zA-Z.:_]{0,128}$
+
+
+ CHAP ID
+ IscsiInitiatorChapId
+
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-4-1:IscsiInitiatorChapId
+
+ false
+ 128
+ 0
+
+ ^[x20-~]{0,128}$
+
+
+ CHAP Secret
+ IscsiInitiatorChapPwd
+
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-4-1:IscsiInitiatorChapPwd
+
+ false
+ 16
+ 0
+
+ ^[x20-~]{0,16}$
+
+
+ IP Address
+ FirstTgtIpAddress
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-4-1:FirstTgtIpAddress
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ iSCSI Name
+ FirstTgtIscsiName
+
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-4-1:FirstTgtIscsiName
+
+ false
+ 128
+ 0
+
+ ^[-0-9a-zA-Z.:_]{0,128}$
+
+
+ CHAP ID
+ FirstTgtChapId
+
+
+ NIC.Integrated.1-4-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-4-1:FirstTgtChapId
+ false
+ 128
+ 0
+
+ ^[x20-~]{0,128}$
+
+
+ CHAP Secret
+ FirstTgtChapPwd
+
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-4-1:FirstTgtChapPwd
+ false
+ 16
+ 0
+
+ ^[x20-~]{0,16}$
+
+
+ IP Address
+ SecondTgtIpAddress
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-4-1:SecondTgtIpAddress
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ iSCSI Name
+ SecondTgtIscsiName
+
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-4-1:SecondTgtIscsiName
+
+ false
+ 128
+ 0
+
+ ^[-0-9a-zA-Z.:_]{0,128}$
+
+
+ CHAP ID
+ SecondTgtChapId
+
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-4-1:SecondTgtChapId
+ false
+ 128
+ 0
+
+ ^[x20-~]{0,128}$
+
+
+ CHAP Secret
+ SecondTgtChapPwd
+
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-4-1:SecondTgtChapPwd
+
+ false
+ 16
+ 0
+
+ ^[x20-~]{0,16}$
+
+
+ Firmware Family Version
+
+ FamilyVersion
+ 7.4.8
+
+ NIC.Integrated.1-4-1
+ Firmware Image Menu
+ FrmwImgMenu
+ NIC.Integrated.1-4-1:FamilyVersion
+ true
+ 20
+ 0
+
+
+
+
+ Bootcode
+ ControllerBIOSVersion
+ 1.30
+
+ NIC.Integrated.1-4-1
+ Firmware Image Menu
+ FrmwImgMenu
+ NIC.Integrated.1-4-1:ControllerBIOSVersion
+
+ true
+ 9
+ 0
+
+
+
+
+ EFI
+ EFIVersion
+ 15.4.6
+
+ NIC.Integrated.1-4-1
+ Firmware Image Menu
+ FrmwImgMenu
+ NIC.Integrated.1-4-1:EFIVersion
+ true
+ 9
+ 0
+
+
+
+
+ Secondary Device
+ SecondaryDeviceMacAddr
+ 00:00:00:00:00:00
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ Secondary Device
+ SecondaryDevice
+ NIC.Integrated.1-4-1:SecondaryDeviceMacAddr
+
+ false
+ 17
+ 17
+
+ ^([0-9a-fA-F]{2}:){5}([0-9a-fA-F]{2})$
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dracclient/tests/wsman_mocks/nic_string-enum-ok.xml b/dracclient/tests/wsman_mocks/nic_string-enum-ok.xml
new file mode 100644
index 0000000..1059b33
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/nic_string-enum-ok.xml
@@ -0,0 +1,1185 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+
+ http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse
+
+ uuid:48fa32d6-5bdb-4080-a9cb-040fdd600ece
+
+ uuid:66b00908-71f0-11f0-a516-a53ffbd9bed4
+
+
+
+
+
+
+ Chip Type
+ ChipMdl
+ BCM5720 A0
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:ChipMdl
+ true
+ 0
+ 0
+
+
+
+
+ PCI Device ID
+ PCIDeviceID
+ 165F
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:PCIDeviceID
+ true
+ 0
+ 0
+
+
+
+
+ Bus:Dev:Func
+ BusDeviceFunction
+ 02:00:00
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:BusDeviceFunction
+
+ true
+ 0
+ 0
+
+
+
+
+ Permanent MAC Address
+
+ MacAddr
+ D4:AE:52:A5:B1:EA
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:MacAddr
+ true
+ 17
+ 17
+
+
+
+
+ Virtual MAC Address
+
+ VirtMacAddr
+ D4:AE:52:A5:B1:EA
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:VirtMacAddr
+ false
+ 17
+ 17
+
+ ^([0-9a-fA-F]{2}:){5}([0-9a-fA-F]{2})$
+
+
+
+ FCoE Offload Support
+
+ FCoEOffloadSupport
+ Unavailable
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:FCoEOffloadSupport
+
+ true
+ 12
+ 0
+
+
+
+
+ iSCSI Offload Support
+
+ iSCSIOffloadSupport
+ Unavailable
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:iSCSIOffloadSupport
+
+ true
+ 12
+ 0
+
+
+
+
+ IBS
+ iSCSIBootSupport
+ Available
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:iSCSIBootSupport
+
+ true
+ 12
+ 0
+
+
+
+
+ PBS
+ PXEBootSupport
+ Available
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:PXEBootSupport
+ true
+ 12
+ 0
+
+
+
+
+ FBS
+ FCoEBootSupport
+ Unavailable
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:FCoEBootSupport
+ true
+ 12
+ 0
+
+
+
+
+ NPS
+ NicPartitioningSupport
+ Unavailable
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:NicPartitioningSupport
+
+ true
+ 12
+ 0
+
+
+
+
+ TBMax
+ TXBandwidthControlMaximum
+ Unavailable
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:TXBandwidthControlMaximum
+
+ true
+ 12
+ 0
+
+
+
+
+ TBMin
+ TXBandwidthControlMinimum
+ Unavailable
+
+ NIC.Integrated.1-3-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-3-1:TXBandwidthControlMinimum
+
+ true
+ 12
+ 0
+
+
+
+
+ DHCP Vendor ID
+ DhcpVendId
+ BRCM ISAN
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-3-1:DhcpVendId
+ false
+ 32
+ 0
+
+
+
+
+ IP Address
+ IscsiInitiatorIpAddr
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-3-1:IscsiInitiatorIpAddr
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ Subnet Mask
+ IscsiInitiatorSubnet
+ 0.0.0.0
+ UnavailableIPv6]]>
+ NIC.Integrated.1-3-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-3-1:IscsiInitiatorSubnet
+
+ false
+ 15
+ 7
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}$
+
+
+
+ Subnet Mask Prefix
+
+ IscsiInitiatorSubnetPrefix
+
+ UnavailableIPv4]]>
+ NIC.Integrated.1-3-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-3-1:IscsiInitiatorSubnetPrefix
+
+ true
+ 3
+ 1
+
+
+
+
+ Default Gateway
+ IscsiInitiatorGateway
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-3-1:IscsiInitiatorGateway
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ Primary DNS
+ IscsiInitiatorPrimDns
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-3-1:IscsiInitiatorPrimDns
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ Secondary DNS
+ IscsiInitiatorSecDns
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-3-1:IscsiInitiatorSecDns
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ iSCSI Name
+ IscsiInitiatorName
+ iqn.1995-05.com.broadcom.iscsiboot
+
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-3-1:IscsiInitiatorName
+
+ false
+ 128
+ 0
+
+ ^[-0-9a-zA-Z.:_]{0,128}$
+
+
+ CHAP ID
+ IscsiInitiatorChapId
+
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-3-1:IscsiInitiatorChapId
+
+ false
+ 128
+ 0
+
+ ^[x20-~]{0,128}$
+
+
+ CHAP Secret
+ IscsiInitiatorChapPwd
+
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-3-1:IscsiInitiatorChapPwd
+
+ false
+ 16
+ 0
+
+ ^[x20-~]{0,16}$
+
+
+ IP Address
+ FirstTgtIpAddress
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-3-1:FirstTgtIpAddress
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ iSCSI Name
+ FirstTgtIscsiName
+
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-3-1:FirstTgtIscsiName
+
+ false
+ 128
+ 0
+
+ ^[-0-9a-zA-Z.:_]{0,128}$
+
+
+ CHAP ID
+ FirstTgtChapId
+
+
+ NIC.Integrated.1-3-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-3-1:FirstTgtChapId
+ false
+ 128
+ 0
+
+ ^[x20-~]{0,128}$
+
+
+ CHAP Secret
+ FirstTgtChapPwd
+
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-3-1:FirstTgtChapPwd
+ false
+ 16
+ 0
+
+ ^[x20-~]{0,16}$
+
+
+ IP Address
+ SecondTgtIpAddress
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-3-1:SecondTgtIpAddress
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ iSCSI Name
+ SecondTgtIscsiName
+
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-3-1:SecondTgtIscsiName
+
+ false
+ 128
+ 0
+
+ ^[-0-9a-zA-Z.:_]{0,128}$
+
+
+ CHAP ID
+ SecondTgtChapId
+
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-3-1:SecondTgtChapId
+ false
+ 128
+ 0
+
+ ^[x20-~]{0,128}$
+
+
+ CHAP Secret
+ SecondTgtChapPwd
+
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-3-1:SecondTgtChapPwd
+
+ false
+ 16
+ 0
+
+ ^[x20-~]{0,16}$
+
+
+ Firmware Family Version
+
+ FamilyVersion
+ 7.4.8
+
+ NIC.Integrated.1-3-1
+ Firmware Image Menu
+ FrmwImgMenu
+ NIC.Integrated.1-3-1:FamilyVersion
+ true
+ 20
+ 0
+
+
+
+
+ Bootcode
+ ControllerBIOSVersion
+ 1.30
+
+ NIC.Integrated.1-3-1
+ Firmware Image Menu
+ FrmwImgMenu
+ NIC.Integrated.1-3-1:ControllerBIOSVersion
+
+ true
+ 9
+ 0
+
+
+
+
+ EFI
+ EFIVersion
+ 15.4.6
+
+ NIC.Integrated.1-3-1
+ Firmware Image Menu
+ FrmwImgMenu
+ NIC.Integrated.1-3-1:EFIVersion
+ true
+ 9
+ 0
+
+
+
+
+ Secondary Device
+ SecondaryDeviceMacAddr
+ 00:00:00:00:00:00
+ Unavailable]]>
+ NIC.Integrated.1-3-1
+ Secondary Device
+ SecondaryDevice
+ NIC.Integrated.1-3-1:SecondaryDeviceMacAddr
+
+ false
+ 17
+ 17
+
+ ^([0-9a-fA-F]{2}:){5}([0-9a-fA-F]{2})$
+
+
+
+ Chip Type
+ ChipMdl
+ BCM5720 A0
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:ChipMdl
+ true
+ 0
+ 0
+
+
+
+
+ PCI Device ID
+ PCIDeviceID
+ 165F
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:PCIDeviceID
+ true
+ 0
+ 0
+
+
+
+
+ Bus:Dev:Func
+ BusDeviceFunction
+ 02:00:01
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:BusDeviceFunction
+
+ true
+ 0
+ 0
+
+
+
+
+ Permanent MAC Address
+
+ MacAddr
+ D4:AE:52:A5:B1:EB
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:MacAddr
+ true
+ 17
+ 17
+
+
+
+
+ Virtual MAC Address
+
+ VirtMacAddr
+ D4:AE:52:A5:B1:EB
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:VirtMacAddr
+ false
+ 17
+ 17
+
+ ^([0-9a-fA-F]{2}:){5}([0-9a-fA-F]{2})$
+
+
+
+ FCoE Offload Support
+
+ FCoEOffloadSupport
+ Unavailable
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:FCoEOffloadSupport
+
+ true
+ 12
+ 0
+
+
+
+
+ iSCSI Offload Support
+
+ iSCSIOffloadSupport
+ Unavailable
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:iSCSIOffloadSupport
+
+ true
+ 12
+ 0
+
+
+
+
+ IBS
+ iSCSIBootSupport
+ Available
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:iSCSIBootSupport
+
+ true
+ 12
+ 0
+
+
+
+
+ PBS
+ PXEBootSupport
+ Available
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:PXEBootSupport
+ true
+ 12
+ 0
+
+
+
+
+ FBS
+ FCoEBootSupport
+ Unavailable
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:FCoEBootSupport
+ true
+ 12
+ 0
+
+
+
+
+ NPS
+ NicPartitioningSupport
+ Unavailable
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:NicPartitioningSupport
+
+ true
+ 12
+ 0
+
+
+
+
+ TBMax
+ TXBandwidthControlMaximum
+ Unavailable
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:TXBandwidthControlMaximum
+
+ true
+ 12
+ 0
+
+
+
+
+ TBMin
+ TXBandwidthControlMinimum
+ Unavailable
+
+ NIC.Integrated.1-4-1
+ Main Configuration Page
+ VndrConfigPage
+ NIC.Integrated.1-4-1:TXBandwidthControlMinimum
+
+ true
+ 12
+ 0
+
+
+
+
+ DHCP Vendor ID
+ DhcpVendId
+ BRCM ISAN
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI General Parameters
+ IscsiGenParams
+ NIC.Integrated.1-4-1:DhcpVendId
+ false
+ 32
+ 0
+
+
+
+
+ IP Address
+ IscsiInitiatorIpAddr
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-4-1:IscsiInitiatorIpAddr
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ Subnet Mask
+ IscsiInitiatorSubnet
+ 0.0.0.0
+ UnavailableIPv6]]>
+ NIC.Integrated.1-4-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-4-1:IscsiInitiatorSubnet
+
+ false
+ 15
+ 7
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}$
+
+
+
+ Subnet Mask Prefix
+
+ IscsiInitiatorSubnetPrefix
+
+ UnavailableIPv4]]>
+ NIC.Integrated.1-4-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-4-1:IscsiInitiatorSubnetPrefix
+
+ true
+ 3
+ 1
+
+
+
+
+ Default Gateway
+ IscsiInitiatorGateway
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-4-1:IscsiInitiatorGateway
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ Primary DNS
+ IscsiInitiatorPrimDns
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-4-1:IscsiInitiatorPrimDns
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ Secondary DNS
+ IscsiInitiatorSecDns
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-4-1:IscsiInitiatorSecDns
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ iSCSI Name
+ IscsiInitiatorName
+ iqn.1995-05.com.broadcom.iscsiboot
+
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-4-1:IscsiInitiatorName
+
+ false
+ 128
+ 0
+
+ ^[-0-9a-zA-Z.:_]{0,128}$
+
+
+ CHAP ID
+ IscsiInitiatorChapId
+
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-4-1:IscsiInitiatorChapId
+
+ false
+ 128
+ 0
+
+ ^[x20-~]{0,128}$
+
+
+ CHAP Secret
+ IscsiInitiatorChapPwd
+
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Initiator Parameters
+
+ IscsiInitiatorParams
+ NIC.Integrated.1-4-1:IscsiInitiatorChapPwd
+
+ false
+ 16
+ 0
+
+ ^[x20-~]{0,16}$
+
+
+ IP Address
+ FirstTgtIpAddress
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-4-1:FirstTgtIpAddress
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ iSCSI Name
+ FirstTgtIscsiName
+
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-4-1:FirstTgtIscsiName
+
+ false
+ 128
+ 0
+
+ ^[-0-9a-zA-Z.:_]{0,128}$
+
+
+ CHAP ID
+ FirstTgtChapId
+
+
+ NIC.Integrated.1-4-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-4-1:FirstTgtChapId
+ false
+ 128
+ 0
+
+ ^[x20-~]{0,128}$
+
+
+ CHAP Secret
+ FirstTgtChapPwd
+
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI First Target Parameters
+
+ IscsiFirstTgtParams
+ NIC.Integrated.1-4-1:FirstTgtChapPwd
+ false
+ 16
+ 0
+
+ ^[x20-~]{0,16}$
+
+
+ IP Address
+ SecondTgtIpAddress
+ 0.0.0.0
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-4-1:SecondTgtIpAddress
+
+ false
+ 39
+ 2
+
+ ^([0-9]{1,3}.){3}[0-9]{1,3}|[0-9a-fA-F:]{2,39}$
+
+
+
+ iSCSI Name
+ SecondTgtIscsiName
+
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-4-1:SecondTgtIscsiName
+
+ false
+ 128
+ 0
+
+ ^[-0-9a-zA-Z.:_]{0,128}$
+
+
+ CHAP ID
+ SecondTgtChapId
+
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-4-1:SecondTgtChapId
+ false
+ 128
+ 0
+
+ ^[x20-~]{0,128}$
+
+
+ CHAP Secret
+ SecondTgtChapPwd
+
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ iSCSI Second Target Parameters
+
+ IscsiSecondTgtParams
+ NIC.Integrated.1-4-1:SecondTgtChapPwd
+
+ false
+ 16
+ 0
+
+ ^[x20-~]{0,16}$
+
+
+ Firmware Family Version
+
+ FamilyVersion
+ 7.4.8
+
+ NIC.Integrated.1-4-1
+ Firmware Image Menu
+ FrmwImgMenu
+ NIC.Integrated.1-4-1:FamilyVersion
+ true
+ 20
+ 0
+
+
+
+
+ Bootcode
+ ControllerBIOSVersion
+ 1.30
+
+ NIC.Integrated.1-4-1
+ Firmware Image Menu
+ FrmwImgMenu
+ NIC.Integrated.1-4-1:ControllerBIOSVersion
+
+ true
+ 9
+ 0
+
+
+
+
+ EFI
+ EFIVersion
+ 15.4.6
+
+ NIC.Integrated.1-4-1
+ Firmware Image Menu
+ FrmwImgMenu
+ NIC.Integrated.1-4-1:EFIVersion
+ true
+ 9
+ 0
+
+
+
+
+ Secondary Device
+ SecondaryDeviceMacAddr
+ 00:00:00:00:00:00
+ Unavailable]]>
+ NIC.Integrated.1-4-1
+ Secondary Device
+ SecondaryDevice
+ NIC.Integrated.1-4-1:SecondaryDeviceMacAddr
+
+ false
+ 17
+ 17
+
+ ^([0-9a-fA-F]{2}:){5}([0-9a-fA-F]{2})$
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dracclient/tests/wsman_mocks/physical_disk_view-enum-ok.xml b/dracclient/tests/wsman_mocks/physical_disk_view-enum-ok.xml
index bf3633b..791fa59 100644
--- a/dracclient/tests/wsman_mocks/physical_disk_view-enum-ok.xml
+++ b/dracclient/tests/wsman_mocks/physical_disk_view-enum-ok.xml
@@ -2,7 +2,9 @@
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">
+ xmlns:n1="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_PhysicalDiskView"
+ xmlns:n2="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_PCIeSSDView"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse
@@ -123,6 +125,108 @@
0
0
+
+ 512
+ 5
+ 0
+ Disk 1 on Integrated BOSS Controller 1
+ 2
+ Disk.Bay.0:Enclosure.Internal.0-1:AHCI.Integrated.1-1
+ 599550590976
+ 0
+ Disk.Bay.0:Enclosure.Internal.0-1:AHCI.Integrated.1-1
+ 20150226180025.000000+000
+ 20150226180025.000000+000
+ ATA
+ 2
+ 33
+ 2014
+ 3
+ 1
+ ST600MM0007
+ None
+ 0
+ CN07YX587262248G01PZA02
+ 0
+ 1
+ 1
+ 255
+ LS0B
+ 1
+ 5000C5007764F409
+ 0
+ S0M3EY3Z
+ 599550590976
+ 1
+ None
+ 0
+ 0
+
+
+ 512
+ 5
+ 0
+ Disk 2 on Integrated BOSS Controller 1
+ 2
+ Disk.Bay.1:Enclosure.Internal.0-1:AHCI.Integrated.1-1
+ 599550590976
+ 0
+ Disk.Bay.1:Enclosure.Internal.0-1:AHCI.Integrated.1-1
+ 20150226180025.000000+000
+ 20150226180025.000000+000
+ ATA
+ 2
+ 33
+ 2014
+ 3
+ 1
+ ST600MM0007
+ None
+ 0
+ CN07YX587262248G01PZA02
+ 0
+ 1
+ 1
+ 255
+ LS0B
+ 1
+ 5000C5007764F409
+ 0
+ S0M3EY3Z
+ 599550590976
+ 2
+ None
+ 0
+ 0
+
+
+ 7
+ 3E
+ PCIe SSD in Slot 20 in Bay 1
+ NVMe-MI1.0
+ 2
+ Disk.Bay.20:Enclosure.Internal.0-1:PCIeExtender.Slot.1
+ NO
+
+
+ Disk.Bay.20:Enclosure.Internal.0-1:PCIeExtender.Slot.1
+ SAMSUNG
+ 8 GT/s
+ 1
+ Dell Express Flash PM1725a 800GB SFF
+ 8 GT/s
+ x4
+ x4
+ 0
+ a822
+ 0
+
+ 100
+ 1.0.4
+ S39YNX0JB02343
+ 800166076416
+ 1
+
diff --git a/dracclient/tests/wsman_mocks/raid_enumeration-enum-ok.xml b/dracclient/tests/wsman_mocks/raid_enumeration-enum-ok.xml
new file mode 100644
index 0000000..f031e64
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/raid_enumeration-enum-ok.xml
@@ -0,0 +1,2347 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse
+ uuid:41a4f623-7f99-43b9-b240-4a773aa39860
+ uuid:3b204fe0-9caa-1caa-a2f1-614a498fd94c
+
+
+
+
+
+ RAIDSupportedRAIDLevels
+ 2(RAID-0)
+ 4(RAID-1)
+ 64(RAID-5)
+ 128(RAID-6)
+ 2048(RAID-10)
+ 8192(RAID-50)
+ 16384(RAID-60)
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDSupportedRAIDLevels
+ true
+
+ 2(RAID-0)
+ 4(RAID-1)
+ 64(RAID-5)
+ 128(RAID-6)
+ 2048(RAID-10)
+ 8192(RAID-50)
+ 16384(RAID-60)
+
+
+ RAIDSupportedDiskProt
+ SAS
+ SATA
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDSupportedDiskProt
+ true
+
+ SAS
+ SATA
+
+
+ RAIDSupportedInitTypes
+ Fast
+ Full
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDSupportedInitTypes
+ true
+
+ Fast
+ Full
+
+
+ RAIDloadBalancedMode
+ Automatic
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDloadBalancedMode
+ false
+
+ Automatic
+ Disabled
+
+
+ RAIDccMode
+ Normal
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDccMode
+ false
+
+ Normal
+ Stop on Error
+
+
+ RAIDprMode
+ Automatic
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDprMode
+ false
+
+ Disabled
+ Automatic
+ Manual
+
+
+ RAIDPatrolReadUnconfiguredArea
+ Enabled
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDPatrolReadUnconfiguredArea
+ false
+
+ Disabled
+ Enabled
+
+
+ RAIDcopybackMode
+ On
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDcopybackMode
+ false
+
+ On
+ On with SMART
+ Off
+
+
+ RAIDEnhancedAutoImportForeignConfig
+ Disabled
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDEnhancedAutoImportForeignConfig
+ false
+
+ Disabled
+ Enabled
+
+
+ RAIDControllerBootMode
+ Headless Mode Continue On Error
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDControllerBootMode
+ false
+
+ User Mode
+ Continue Boot On Error
+ Headless Mode Continue On Error
+ Headless Safe Mode
+
+
+ RAIDCurrentControllerMode
+ RAID
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDCurrentControllerMode
+ true
+
+ RAID
+ Enhanced HBA
+
+
+ RAIDRequestedControllerMode
+ None
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDRequestedControllerMode
+ false
+
+ RAID
+ Enhanced HBA
+ None
+
+
+ RAIDMode
+ None
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDMode
+ true
+
+ None
+ Linux
+ Windows
+ Mixed
+
+
+ RAIDpersistentHotspare
+ Disabled
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDpersistentHotspare
+ false
+
+ Disabled
+ Enabled
+
+
+ RAIDMaxCapableSpeed
+ 12_GBS
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDMaxCapableSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+ RAIDSupportedInitTypes
+ None
+ AHCI.Embedded.1-1
+ AHCI.Embedded.1-1:RAIDSupportedInitTypes
+ true
+
+ None
+
+
+ RAIDMode
+ None
+ AHCI.Embedded.1-1
+ AHCI.Embedded.1-1:RAIDMode
+ true
+
+ None
+ Linux
+ Windows
+ Mixed
+
+
+ RAIDSupportedInitTypes
+ None
+ AHCI.Embedded.2-1
+ AHCI.Embedded.2-1:RAIDSupportedInitTypes
+ true
+
+ None
+
+
+ RAIDMode
+ None
+ AHCI.Embedded.2-1
+ AHCI.Embedded.2-1:RAIDMode
+ true
+
+ None
+ Linux
+ Windows
+ Mixed
+
+
+ RAIDdefaultWritePolicy
+ WriteBack
+ Disk.Virtual.0:RAID.Integrated.1-1
+ Disk.Virtual.0:RAID.Integrated.1-1:RAIDdefaultWritePolicy
+ false
+
+ WriteThrough
+ WriteBack
+ WriteBackForce
+
+
+ RAIDdefaultReadPolicy
+ ReadAhead
+ Disk.Virtual.0:RAID.Integrated.1-1
+ Disk.Virtual.0:RAID.Integrated.1-1:RAIDdefaultReadPolicy
+ false
+
+ NoReadAhead
+ ReadAhead
+ AdaptiveReadAhead
+
+
+ DiskCachePolicy
+ Disabled
+ Disk.Virtual.0:RAID.Integrated.1-1
+ Disk.Virtual.0:RAID.Integrated.1-1:DiskCachePolicy
+ false
+
+ Default
+ Enabled
+ Disabled
+
+
+ T10PIStatus
+ Disabled
+ Disk.Virtual.0:RAID.Integrated.1-1
+ Disk.Virtual.0:RAID.Integrated.1-1:T10PIStatus
+ true
+
+ Disabled
+ Enabled
+
+
+ RAIDStripeSize
+ 512(256 KB)
+ Disk.Virtual.0:RAID.Integrated.1-1
+ Disk.Virtual.0:RAID.Integrated.1-1:RAIDStripeSize
+ true
+
+ 0
+ 1(512 Bytes)
+ 2(1 KB)
+ 4(2 KB)
+ 8(4 KB)
+ 16(8 KB)
+ 32(16 KB)
+ 64(32 KB)
+ 128(64 KB)
+ 256(128 KB)
+ 512(256 KB)
+ 1024(512 KB)
+ 2048(1024 KB)
+ 4096(2048 KB)
+ 8192(4096 KB)
+ 16384(8192 KB)
+ 32768(16384 KB)
+
+
+ RAIDdefaultWritePolicy
+ WriteBack
+ Disk.Virtual.1:RAID.Integrated.1-1
+ Disk.Virtual.1:RAID.Integrated.1-1:RAIDdefaultWritePolicy
+ false
+
+ WriteThrough
+ WriteBack
+ WriteBackForce
+
+
+ RAIDdefaultReadPolicy
+ ReadAhead
+ Disk.Virtual.1:RAID.Integrated.1-1
+ Disk.Virtual.1:RAID.Integrated.1-1:RAIDdefaultReadPolicy
+ false
+
+ NoReadAhead
+ ReadAhead
+ AdaptiveReadAhead
+
+
+ DiskCachePolicy
+ Disabled
+ Disk.Virtual.1:RAID.Integrated.1-1
+ Disk.Virtual.1:RAID.Integrated.1-1:DiskCachePolicy
+ false
+
+ Default
+ Enabled
+ Disabled
+
+
+ T10PIStatus
+ Disabled
+ Disk.Virtual.1:RAID.Integrated.1-1
+ Disk.Virtual.1:RAID.Integrated.1-1:T10PIStatus
+ true
+
+ Disabled
+ Enabled
+
+
+ RAIDStripeSize
+ 512(256 KB)
+ Disk.Virtual.1:RAID.Integrated.1-1
+ Disk.Virtual.1:RAID.Integrated.1-1:RAIDStripeSize
+ true
+
+ 0
+ 1(512 Bytes)
+ 2(1 KB)
+ 4(2 KB)
+ 8(4 KB)
+ 16(8 KB)
+ 32(16 KB)
+ 64(32 KB)
+ 128(64 KB)
+ 256(128 KB)
+ 512(256 KB)
+ 1024(512 KB)
+ 2048(1024 KB)
+ 4096(2048 KB)
+ 8192(4096 KB)
+ 16384(8192 KB)
+ 32768(16384 KB)
+
+
+ RAIDdefaultWritePolicy
+ WriteBack
+ Disk.Virtual.2:RAID.Integrated.1-1
+ Disk.Virtual.2:RAID.Integrated.1-1:RAIDdefaultWritePolicy
+ false
+
+ WriteThrough
+ WriteBack
+ WriteBackForce
+
+
+ RAIDdefaultReadPolicy
+ ReadAhead
+ Disk.Virtual.2:RAID.Integrated.1-1
+ Disk.Virtual.2:RAID.Integrated.1-1:RAIDdefaultReadPolicy
+ false
+
+ NoReadAhead
+ ReadAhead
+ AdaptiveReadAhead
+
+
+ DiskCachePolicy
+ Disabled
+ Disk.Virtual.2:RAID.Integrated.1-1
+ Disk.Virtual.2:RAID.Integrated.1-1:DiskCachePolicy
+ false
+
+ Default
+ Enabled
+ Disabled
+
+
+ T10PIStatus
+ Disabled
+ Disk.Virtual.2:RAID.Integrated.1-1
+ Disk.Virtual.2:RAID.Integrated.1-1:T10PIStatus
+ true
+
+ Disabled
+ Enabled
+
+
+ RAIDStripeSize
+ 512(256 KB)
+ Disk.Virtual.2:RAID.Integrated.1-1
+ Disk.Virtual.2:RAID.Integrated.1-1:RAIDStripeSize
+ true
+
+ 0
+ 1(512 Bytes)
+ 2(1 KB)
+ 4(2 KB)
+ 8(4 KB)
+ 16(8 KB)
+ 32(16 KB)
+ 64(32 KB)
+ 128(64 KB)
+ 256(128 KB)
+ 512(256 KB)
+ 1024(512 KB)
+ 2048(1024 KB)
+ 4096(2048 KB)
+ 8192(4096 KB)
+ 16384(8192 KB)
+ 32768(16384 KB)
+
+
+ RAIDdefaultWritePolicy
+ WriteBack
+ Disk.Virtual.3:RAID.Integrated.1-1
+ Disk.Virtual.3:RAID.Integrated.1-1:RAIDdefaultWritePolicy
+ false
+
+ WriteThrough
+ WriteBack
+ WriteBackForce
+
+
+ RAIDdefaultReadPolicy
+ ReadAhead
+ Disk.Virtual.3:RAID.Integrated.1-1
+ Disk.Virtual.3:RAID.Integrated.1-1:RAIDdefaultReadPolicy
+ false
+
+ NoReadAhead
+ ReadAhead
+ AdaptiveReadAhead
+
+
+ DiskCachePolicy
+ Disabled
+ Disk.Virtual.3:RAID.Integrated.1-1
+ Disk.Virtual.3:RAID.Integrated.1-1:DiskCachePolicy
+ false
+
+ Default
+ Enabled
+ Disabled
+
+
+ T10PIStatus
+ Disabled
+ Disk.Virtual.3:RAID.Integrated.1-1
+ Disk.Virtual.3:RAID.Integrated.1-1:T10PIStatus
+ true
+
+ Disabled
+ Enabled
+
+
+ RAIDStripeSize
+ 512(256 KB)
+ Disk.Virtual.3:RAID.Integrated.1-1
+ Disk.Virtual.3:RAID.Integrated.1-1:RAIDStripeSize
+ true
+
+ 0
+ 1(512 Bytes)
+ 2(1 KB)
+ 4(2 KB)
+ 8(4 KB)
+ 16(8 KB)
+ 32(16 KB)
+ 64(32 KB)
+ 128(64 KB)
+ 256(128 KB)
+ 512(256 KB)
+ 1024(512 KB)
+ 2048(1024 KB)
+ 4096(2048 KB)
+ 8192(4096 KB)
+ 16384(8192 KB)
+ 32768(16384 KB)
+
+
+ RAIDdefaultWritePolicy
+ WriteBack
+ Disk.Virtual.4:RAID.Integrated.1-1
+ Disk.Virtual.4:RAID.Integrated.1-1:RAIDdefaultWritePolicy
+ false
+
+ WriteThrough
+ WriteBack
+ WriteBackForce
+
+
+ RAIDdefaultReadPolicy
+ ReadAhead
+ Disk.Virtual.4:RAID.Integrated.1-1
+ Disk.Virtual.4:RAID.Integrated.1-1:RAIDdefaultReadPolicy
+ false
+
+ NoReadAhead
+ ReadAhead
+ AdaptiveReadAhead
+
+
+ DiskCachePolicy
+ Disabled
+ Disk.Virtual.4:RAID.Integrated.1-1
+ Disk.Virtual.4:RAID.Integrated.1-1:DiskCachePolicy
+ false
+
+ Default
+ Enabled
+ Disabled
+
+
+ T10PIStatus
+ Disabled
+ Disk.Virtual.4:RAID.Integrated.1-1
+ Disk.Virtual.4:RAID.Integrated.1-1:T10PIStatus
+ true
+
+ Disabled
+ Enabled
+
+
+ RAIDStripeSize
+ 512(256 KB)
+ Disk.Virtual.4:RAID.Integrated.1-1
+ Disk.Virtual.4:RAID.Integrated.1-1:RAIDStripeSize
+ true
+
+ 0
+ 1(512 Bytes)
+ 2(1 KB)
+ 4(2 KB)
+ 8(4 KB)
+ 16(8 KB)
+ 32(16 KB)
+ 64(32 KB)
+ 128(64 KB)
+ 256(128 KB)
+ 512(256 KB)
+ 1024(512 KB)
+ 2048(1024 KB)
+ 4096(2048 KB)
+ 8192(4096 KB)
+ 16384(8192 KB)
+ 32768(16384 KB)
+
+
+ RAIDdefaultWritePolicy
+ WriteBack
+ Disk.Virtual.5:RAID.Integrated.1-1
+ Disk.Virtual.5:RAID.Integrated.1-1:RAIDdefaultWritePolicy
+ false
+
+ WriteThrough
+ WriteBack
+ WriteBackForce
+
+
+ RAIDdefaultReadPolicy
+ ReadAhead
+ Disk.Virtual.5:RAID.Integrated.1-1
+ Disk.Virtual.5:RAID.Integrated.1-1:RAIDdefaultReadPolicy
+ false
+
+ NoReadAhead
+ ReadAhead
+ AdaptiveReadAhead
+
+
+ DiskCachePolicy
+ Disabled
+ Disk.Virtual.5:RAID.Integrated.1-1
+ Disk.Virtual.5:RAID.Integrated.1-1:DiskCachePolicy
+ false
+
+ Default
+ Enabled
+ Disabled
+
+
+ T10PIStatus
+ Disabled
+ Disk.Virtual.5:RAID.Integrated.1-1
+ Disk.Virtual.5:RAID.Integrated.1-1:T10PIStatus
+ true
+
+ Disabled
+ Enabled
+
+
+ RAIDStripeSize
+ 512(256 KB)
+ Disk.Virtual.5:RAID.Integrated.1-1
+ Disk.Virtual.5:RAID.Integrated.1-1:RAIDStripeSize
+ true
+
+ 0
+ 1(512 Bytes)
+ 2(1 KB)
+ 4(2 KB)
+ 8(4 KB)
+ 16(8 KB)
+ 32(16 KB)
+ 64(32 KB)
+ 128(64 KB)
+ 256(128 KB)
+ 512(256 KB)
+ 1024(512 KB)
+ 2048(1024 KB)
+ 4096(2048 KB)
+ 8192(4096 KB)
+ 16384(8192 KB)
+ 32768(16384 KB)
+
+
+ RAIDdefaultWritePolicy
+ WriteBack
+ Disk.Virtual.6:RAID.Integrated.1-1
+ Disk.Virtual.6:RAID.Integrated.1-1:RAIDdefaultWritePolicy
+ false
+
+ WriteThrough
+ WriteBack
+ WriteBackForce
+
+
+ RAIDdefaultReadPolicy
+ ReadAhead
+ Disk.Virtual.6:RAID.Integrated.1-1
+ Disk.Virtual.6:RAID.Integrated.1-1:RAIDdefaultReadPolicy
+ false
+
+ NoReadAhead
+ ReadAhead
+ AdaptiveReadAhead
+
+
+ DiskCachePolicy
+ Disabled
+ Disk.Virtual.6:RAID.Integrated.1-1
+ Disk.Virtual.6:RAID.Integrated.1-1:DiskCachePolicy
+ false
+
+ Default
+ Enabled
+ Disabled
+
+
+ T10PIStatus
+ Disabled
+ Disk.Virtual.6:RAID.Integrated.1-1
+ Disk.Virtual.6:RAID.Integrated.1-1:T10PIStatus
+ true
+
+ Disabled
+ Enabled
+
+
+ RAIDStripeSize
+ 512(256 KB)
+ Disk.Virtual.6:RAID.Integrated.1-1
+ Disk.Virtual.6:RAID.Integrated.1-1:RAIDStripeSize
+ true
+
+ 0
+ 1(512 Bytes)
+ 2(1 KB)
+ 4(2 KB)
+ 8(4 KB)
+ 16(8 KB)
+ 32(16 KB)
+ 64(32 KB)
+ 128(64 KB)
+ 256(128 KB)
+ 512(256 KB)
+ 1024(512 KB)
+ 2048(1024 KB)
+ 4096(2048 KB)
+ 8192(4096 KB)
+ 16384(8192 KB)
+ 32768(16384 KB)
+
+
+ RAIDdefaultWritePolicy
+ WriteBack
+ Disk.Virtual.7:RAID.Integrated.1-1
+ Disk.Virtual.7:RAID.Integrated.1-1:RAIDdefaultWritePolicy
+ false
+
+ WriteThrough
+ WriteBack
+ WriteBackForce
+
+
+ RAIDdefaultReadPolicy
+ ReadAhead
+ Disk.Virtual.7:RAID.Integrated.1-1
+ Disk.Virtual.7:RAID.Integrated.1-1:RAIDdefaultReadPolicy
+ false
+
+ NoReadAhead
+ ReadAhead
+ AdaptiveReadAhead
+
+
+ DiskCachePolicy
+ Disabled
+ Disk.Virtual.7:RAID.Integrated.1-1
+ Disk.Virtual.7:RAID.Integrated.1-1:DiskCachePolicy
+ false
+
+ Default
+ Enabled
+ Disabled
+
+
+ T10PIStatus
+ Disabled
+ Disk.Virtual.7:RAID.Integrated.1-1
+ Disk.Virtual.7:RAID.Integrated.1-1:T10PIStatus
+ true
+
+ Disabled
+ Enabled
+
+
+ RAIDStripeSize
+ 512(256 KB)
+ Disk.Virtual.7:RAID.Integrated.1-1
+ Disk.Virtual.7:RAID.Integrated.1-1:RAIDStripeSize
+ true
+
+ 0
+ 1(512 Bytes)
+ 2(1 KB)
+ 4(2 KB)
+ 8(4 KB)
+ 16(8 KB)
+ 32(16 KB)
+ 64(32 KB)
+ 128(64 KB)
+ 256(128 KB)
+ 512(256 KB)
+ 1024(512 KB)
+ 2048(1024 KB)
+ 4096(2048 KB)
+ 8192(4096 KB)
+ 16384(8192 KB)
+ 32768(16384 KB)
+
+
+ RAIDdefaultWritePolicy
+ WriteBack
+ Disk.Virtual.8:RAID.Integrated.1-1
+ Disk.Virtual.8:RAID.Integrated.1-1:RAIDdefaultWritePolicy
+ false
+
+ WriteThrough
+ WriteBack
+ WriteBackForce
+
+
+ RAIDdefaultReadPolicy
+ ReadAhead
+ Disk.Virtual.8:RAID.Integrated.1-1
+ Disk.Virtual.8:RAID.Integrated.1-1:RAIDdefaultReadPolicy
+ false
+
+ NoReadAhead
+ ReadAhead
+ AdaptiveReadAhead
+
+
+ DiskCachePolicy
+ Disabled
+ Disk.Virtual.8:RAID.Integrated.1-1
+ Disk.Virtual.8:RAID.Integrated.1-1:DiskCachePolicy
+ false
+
+ Default
+ Enabled
+ Disabled
+
+
+ T10PIStatus
+ Disabled
+ Disk.Virtual.8:RAID.Integrated.1-1
+ Disk.Virtual.8:RAID.Integrated.1-1:T10PIStatus
+ true
+
+ Disabled
+ Enabled
+
+
+ RAIDStripeSize
+ 512(256 KB)
+ Disk.Virtual.8:RAID.Integrated.1-1
+ Disk.Virtual.8:RAID.Integrated.1-1:RAIDStripeSize
+ true
+
+ 0
+ 1(512 Bytes)
+ 2(1 KB)
+ 4(2 KB)
+ 8(4 KB)
+ 16(8 KB)
+ 32(16 KB)
+ 64(32 KB)
+ 128(64 KB)
+ 256(128 KB)
+ 512(256 KB)
+ 1024(512 KB)
+ 2048(1024 KB)
+ 4096(2048 KB)
+ 8192(4096 KB)
+ 16384(8192 KB)
+ 32768(16384 KB)
+
+
+ RAIDdefaultWritePolicy
+ WriteBack
+ Disk.Virtual.9:RAID.Integrated.1-1
+ Disk.Virtual.9:RAID.Integrated.1-1:RAIDdefaultWritePolicy
+ false
+
+ WriteThrough
+ WriteBack
+ WriteBackForce
+
+
+ RAIDdefaultReadPolicy
+ ReadAhead
+ Disk.Virtual.9:RAID.Integrated.1-1
+ Disk.Virtual.9:RAID.Integrated.1-1:RAIDdefaultReadPolicy
+ false
+
+ NoReadAhead
+ ReadAhead
+ AdaptiveReadAhead
+
+
+ DiskCachePolicy
+ Disabled
+ Disk.Virtual.9:RAID.Integrated.1-1
+ Disk.Virtual.9:RAID.Integrated.1-1:DiskCachePolicy
+ false
+
+ Default
+ Enabled
+ Disabled
+
+
+ T10PIStatus
+ Disabled
+ Disk.Virtual.9:RAID.Integrated.1-1
+ Disk.Virtual.9:RAID.Integrated.1-1:T10PIStatus
+ true
+
+ Disabled
+ Enabled
+
+
+ RAIDStripeSize
+ 512(256 KB)
+ Disk.Virtual.9:RAID.Integrated.1-1
+ Disk.Virtual.9:RAID.Integrated.1-1:RAIDStripeSize
+ true
+
+ 0
+ 1(512 Bytes)
+ 2(1 KB)
+ 4(2 KB)
+ 8(4 KB)
+ 16(8 KB)
+ 32(16 KB)
+ 64(32 KB)
+ 128(64 KB)
+ 256(128 KB)
+ 512(256 KB)
+ 1024(512 KB)
+ 2048(1024 KB)
+ 4096(2048 KB)
+ 8192(4096 KB)
+ 16384(8192 KB)
+ 32768(16384 KB)
+
+
+ RAIDdefaultWritePolicy
+ WriteBack
+ Disk.Virtual.10:RAID.Integrated.1-1
+ Disk.Virtual.10:RAID.Integrated.1-1:RAIDdefaultWritePolicy
+ false
+
+ WriteThrough
+ WriteBack
+ WriteBackForce
+
+
+ RAIDdefaultReadPolicy
+ ReadAhead
+ Disk.Virtual.10:RAID.Integrated.1-1
+ Disk.Virtual.10:RAID.Integrated.1-1:RAIDdefaultReadPolicy
+ false
+
+ NoReadAhead
+ ReadAhead
+ AdaptiveReadAhead
+
+
+ DiskCachePolicy
+ Disabled
+ Disk.Virtual.10:RAID.Integrated.1-1
+ Disk.Virtual.10:RAID.Integrated.1-1:DiskCachePolicy
+ false
+
+ Default
+ Enabled
+ Disabled
+
+
+ T10PIStatus
+ Disabled
+ Disk.Virtual.10:RAID.Integrated.1-1
+ Disk.Virtual.10:RAID.Integrated.1-1:T10PIStatus
+ true
+
+ Disabled
+ Enabled
+
+
+ RAIDStripeSize
+ 512(256 KB)
+ Disk.Virtual.10:RAID.Integrated.1-1
+ Disk.Virtual.10:RAID.Integrated.1-1:RAIDStripeSize
+ true
+
+ 0
+ 1(512 Bytes)
+ 2(1 KB)
+ 4(2 KB)
+ 8(4 KB)
+ 16(8 KB)
+ 32(16 KB)
+ 64(32 KB)
+ 128(64 KB)
+ 256(128 KB)
+ 512(256 KB)
+ 1024(512 KB)
+ 2048(1024 KB)
+ 4096(2048 KB)
+ 8192(4096 KB)
+ 16384(8192 KB)
+ 32768(16384 KB)
+
+
+ RAIDdefaultWritePolicy
+ WriteBack
+ Disk.Virtual.11:RAID.Integrated.1-1
+ Disk.Virtual.11:RAID.Integrated.1-1:RAIDdefaultWritePolicy
+ false
+
+ WriteThrough
+ WriteBack
+ WriteBackForce
+
+
+ RAIDdefaultReadPolicy
+ ReadAhead
+ Disk.Virtual.11:RAID.Integrated.1-1
+ Disk.Virtual.11:RAID.Integrated.1-1:RAIDdefaultReadPolicy
+ false
+
+ NoReadAhead
+ ReadAhead
+ AdaptiveReadAhead
+
+
+ DiskCachePolicy
+ Disabled
+ Disk.Virtual.11:RAID.Integrated.1-1
+ Disk.Virtual.11:RAID.Integrated.1-1:DiskCachePolicy
+ false
+
+ Default
+ Enabled
+ Disabled
+
+
+ T10PIStatus
+ Disabled
+ Disk.Virtual.11:RAID.Integrated.1-1
+ Disk.Virtual.11:RAID.Integrated.1-1:T10PIStatus
+ true
+
+ Disabled
+ Enabled
+
+
+ RAIDStripeSize
+ 512(256 KB)
+ Disk.Virtual.11:RAID.Integrated.1-1
+ Disk.Virtual.11:RAID.Integrated.1-1:RAIDStripeSize
+ true
+
+ 0
+ 1(512 Bytes)
+ 2(1 KB)
+ 4(2 KB)
+ 8(4 KB)
+ 16(8 KB)
+ 32(16 KB)
+ 64(32 KB)
+ 128(64 KB)
+ 256(128 KB)
+ 512(256 KB)
+ 1024(512 KB)
+ 2048(1024 KB)
+ 4096(2048 KB)
+ 8192(4096 KB)
+ 16384(8192 KB)
+ 32768(16384 KB)
+
+
+ RAIDdefaultWritePolicy
+ WriteBack
+ Disk.Virtual.12:RAID.Integrated.1-1
+ Disk.Virtual.12:RAID.Integrated.1-1:RAIDdefaultWritePolicy
+ false
+
+ WriteThrough
+ WriteBack
+ WriteBackForce
+
+
+ RAIDdefaultReadPolicy
+ ReadAhead
+ Disk.Virtual.12:RAID.Integrated.1-1
+ Disk.Virtual.12:RAID.Integrated.1-1:RAIDdefaultReadPolicy
+ false
+
+ NoReadAhead
+ ReadAhead
+ AdaptiveReadAhead
+
+
+ DiskCachePolicy
+ Disabled
+ Disk.Virtual.12:RAID.Integrated.1-1
+ Disk.Virtual.12:RAID.Integrated.1-1:DiskCachePolicy
+ false
+
+ Default
+ Enabled
+ Disabled
+
+
+ T10PIStatus
+ Disabled
+ Disk.Virtual.12:RAID.Integrated.1-1
+ Disk.Virtual.12:RAID.Integrated.1-1:T10PIStatus
+ true
+
+ Disabled
+ Enabled
+
+
+ RAIDStripeSize
+ 512(256 KB)
+ Disk.Virtual.12:RAID.Integrated.1-1
+ Disk.Virtual.12:RAID.Integrated.1-1:RAIDStripeSize
+ true
+
+ 0
+ 1(512 Bytes)
+ 2(1 KB)
+ 4(2 KB)
+ 8(4 KB)
+ 16(8 KB)
+ 32(16 KB)
+ 64(32 KB)
+ 128(64 KB)
+ 256(128 KB)
+ 512(256 KB)
+ 1024(512 KB)
+ 2048(1024 KB)
+ 4096(2048 KB)
+ 8192(4096 KB)
+ 16384(8192 KB)
+ 32768(16384 KB)
+
+
+ RAIDdefaultWritePolicy
+ WriteBack
+ Disk.Virtual.13:RAID.Integrated.1-1
+ Disk.Virtual.13:RAID.Integrated.1-1:RAIDdefaultWritePolicy
+ false
+
+ WriteThrough
+ WriteBack
+ WriteBackForce
+
+
+ RAIDdefaultReadPolicy
+ ReadAhead
+ Disk.Virtual.13:RAID.Integrated.1-1
+ Disk.Virtual.13:RAID.Integrated.1-1:RAIDdefaultReadPolicy
+ false
+
+ NoReadAhead
+ ReadAhead
+ AdaptiveReadAhead
+
+
+ DiskCachePolicy
+ Enabled
+ Disk.Virtual.13:RAID.Integrated.1-1
+ Disk.Virtual.13:RAID.Integrated.1-1:DiskCachePolicy
+ false
+
+ Default
+ Enabled
+ Disabled
+
+
+ T10PIStatus
+ Disabled
+ Disk.Virtual.13:RAID.Integrated.1-1
+ Disk.Virtual.13:RAID.Integrated.1-1:T10PIStatus
+ true
+
+ Disabled
+ Enabled
+
+
+ RAIDStripeSize
+ 512(256 KB)
+ Disk.Virtual.13:RAID.Integrated.1-1
+ Disk.Virtual.13:RAID.Integrated.1-1:RAIDStripeSize
+ true
+
+ 0
+ 1(512 Bytes)
+ 2(1 KB)
+ 4(2 KB)
+ 8(4 KB)
+ 16(8 KB)
+ 32(16 KB)
+ 64(32 KB)
+ 128(64 KB)
+ 256(128 KB)
+ 512(256 KB)
+ 1024(512 KB)
+ 2048(1024 KB)
+ 4096(2048 KB)
+ 8192(4096 KB)
+ 16384(8192 KB)
+ 32768(16384 KB)
+
+
+ RAIDdefaultWritePolicy
+ WriteBack
+ Disk.Virtual.14:RAID.Integrated.1-1
+ Disk.Virtual.14:RAID.Integrated.1-1:RAIDdefaultWritePolicy
+ false
+
+ WriteThrough
+ WriteBack
+ WriteBackForce
+
+
+ RAIDdefaultReadPolicy
+ ReadAhead
+ Disk.Virtual.14:RAID.Integrated.1-1
+ Disk.Virtual.14:RAID.Integrated.1-1:RAIDdefaultReadPolicy
+ false
+
+ NoReadAhead
+ ReadAhead
+ AdaptiveReadAhead
+
+
+ DiskCachePolicy
+ Enabled
+ Disk.Virtual.14:RAID.Integrated.1-1
+ Disk.Virtual.14:RAID.Integrated.1-1:DiskCachePolicy
+ false
+
+ Default
+ Enabled
+ Disabled
+
+
+ T10PIStatus
+ Disabled
+ Disk.Virtual.14:RAID.Integrated.1-1
+ Disk.Virtual.14:RAID.Integrated.1-1:T10PIStatus
+ true
+
+ Disabled
+ Enabled
+
+
+ RAIDStripeSize
+ 512(256 KB)
+ Disk.Virtual.14:RAID.Integrated.1-1
+ Disk.Virtual.14:RAID.Integrated.1-1:RAIDStripeSize
+ true
+
+ 0
+ 1(512 Bytes)
+ 2(1 KB)
+ 4(2 KB)
+ 8(4 KB)
+ 16(8 KB)
+ 32(16 KB)
+ 64(32 KB)
+ 128(64 KB)
+ 256(128 KB)
+ 512(256 KB)
+ 1024(512 KB)
+ 2048(1024 KB)
+ 4096(2048 KB)
+ 8192(4096 KB)
+ 16384(8192 KB)
+ 32768(16384 KB)
+
+
+ RAIDdefaultWritePolicy
+ WriteBack
+ Disk.Virtual.15:RAID.Integrated.1-1
+ Disk.Virtual.15:RAID.Integrated.1-1:RAIDdefaultWritePolicy
+ false
+
+ WriteThrough
+ WriteBack
+ WriteBackForce
+
+
+ RAIDdefaultReadPolicy
+ ReadAhead
+ Disk.Virtual.15:RAID.Integrated.1-1
+ Disk.Virtual.15:RAID.Integrated.1-1:RAIDdefaultReadPolicy
+ false
+
+ NoReadAhead
+ ReadAhead
+ AdaptiveReadAhead
+
+
+ DiskCachePolicy
+ Enabled
+ Disk.Virtual.15:RAID.Integrated.1-1
+ Disk.Virtual.15:RAID.Integrated.1-1:DiskCachePolicy
+ false
+
+ Default
+ Enabled
+ Disabled
+
+
+ T10PIStatus
+ Disabled
+ Disk.Virtual.15:RAID.Integrated.1-1
+ Disk.Virtual.15:RAID.Integrated.1-1:T10PIStatus
+ true
+
+ Disabled
+ Enabled
+
+
+ RAIDStripeSize
+ 512(256 KB)
+ Disk.Virtual.15:RAID.Integrated.1-1
+ Disk.Virtual.15:RAID.Integrated.1-1:RAIDStripeSize
+ true
+
+ 0
+ 1(512 Bytes)
+ 2(1 KB)
+ 4(2 KB)
+ 8(4 KB)
+ 16(8 KB)
+ 32(16 KB)
+ 64(32 KB)
+ 128(64 KB)
+ 256(128 KB)
+ 512(256 KB)
+ 1024(512 KB)
+ 2048(1024 KB)
+ 4096(2048 KB)
+ 8192(4096 KB)
+ 16384(8192 KB)
+ 32768(16384 KB)
+
+
+ RAIDdefaultWritePolicy
+ WriteBack
+ Disk.Virtual.16:RAID.Integrated.1-1
+ Disk.Virtual.16:RAID.Integrated.1-1:RAIDdefaultWritePolicy
+ false
+
+ WriteThrough
+ WriteBack
+ WriteBackForce
+
+
+ RAIDdefaultReadPolicy
+ ReadAhead
+ Disk.Virtual.16:RAID.Integrated.1-1
+ Disk.Virtual.16:RAID.Integrated.1-1:RAIDdefaultReadPolicy
+ false
+
+ NoReadAhead
+ ReadAhead
+ AdaptiveReadAhead
+
+
+ DiskCachePolicy
+ Enabled
+ Disk.Virtual.16:RAID.Integrated.1-1
+ Disk.Virtual.16:RAID.Integrated.1-1:DiskCachePolicy
+ false
+
+ Default
+ Enabled
+ Disabled
+
+
+ T10PIStatus
+ Disabled
+ Disk.Virtual.16:RAID.Integrated.1-1
+ Disk.Virtual.16:RAID.Integrated.1-1:T10PIStatus
+ true
+
+ Disabled
+ Enabled
+
+
+ RAIDStripeSize
+ 512(256 KB)
+ Disk.Virtual.16:RAID.Integrated.1-1
+ Disk.Virtual.16:RAID.Integrated.1-1:RAIDStripeSize
+ true
+
+ 0
+ 1(512 Bytes)
+ 2(1 KB)
+ 4(2 KB)
+ 8(4 KB)
+ 16(8 KB)
+ 32(16 KB)
+ 64(32 KB)
+ 128(64 KB)
+ 256(128 KB)
+ 512(256 KB)
+ 1024(512 KB)
+ 2048(1024 KB)
+ 4096(2048 KB)
+ 8192(4096 KB)
+ 16384(8192 KB)
+ 32768(16384 KB)
+
+
+ RAIDdefaultWritePolicy
+ WriteBack
+ Disk.Virtual.17:RAID.Integrated.1-1
+ Disk.Virtual.17:RAID.Integrated.1-1:RAIDdefaultWritePolicy
+ false
+
+ WriteThrough
+ WriteBack
+ WriteBackForce
+
+
+ RAIDdefaultReadPolicy
+ ReadAhead
+ Disk.Virtual.17:RAID.Integrated.1-1
+ Disk.Virtual.17:RAID.Integrated.1-1:RAIDdefaultReadPolicy
+ false
+
+ NoReadAhead
+ ReadAhead
+ AdaptiveReadAhead
+
+
+ DiskCachePolicy
+ Disabled
+ Disk.Virtual.17:RAID.Integrated.1-1
+ Disk.Virtual.17:RAID.Integrated.1-1:DiskCachePolicy
+ false
+
+ Default
+ Enabled
+ Disabled
+
+
+ T10PIStatus
+ Disabled
+ Disk.Virtual.17:RAID.Integrated.1-1
+ Disk.Virtual.17:RAID.Integrated.1-1:T10PIStatus
+ true
+
+ Disabled
+ Enabled
+
+
+ RAIDStripeSize
+ 512(256 KB)
+ Disk.Virtual.17:RAID.Integrated.1-1
+ Disk.Virtual.17:RAID.Integrated.1-1:RAIDStripeSize
+ true
+
+ 0
+ 1(512 Bytes)
+ 2(1 KB)
+ 4(2 KB)
+ 8(4 KB)
+ 16(8 KB)
+ 32(16 KB)
+ 64(32 KB)
+ 128(64 KB)
+ 256(128 KB)
+ 512(256 KB)
+ 1024(512 KB)
+ 2048(1024 KB)
+ 4096(2048 KB)
+ 8192(4096 KB)
+ 16384(8192 KB)
+ 32768(16384 KB)
+
+
+ RAIDdefaultWritePolicy
+ WriteBack
+ Disk.Virtual.18:RAID.Integrated.1-1
+ Disk.Virtual.18:RAID.Integrated.1-1:RAIDdefaultWritePolicy
+ false
+
+ WriteThrough
+ WriteBack
+ WriteBackForce
+
+
+ RAIDdefaultReadPolicy
+ ReadAhead
+ Disk.Virtual.18:RAID.Integrated.1-1
+ Disk.Virtual.18:RAID.Integrated.1-1:RAIDdefaultReadPolicy
+ false
+
+ NoReadAhead
+ ReadAhead
+ AdaptiveReadAhead
+
+
+ DiskCachePolicy
+ Disabled
+ Disk.Virtual.18:RAID.Integrated.1-1
+ Disk.Virtual.18:RAID.Integrated.1-1:DiskCachePolicy
+ false
+
+ Default
+ Enabled
+ Disabled
+
+
+ T10PIStatus
+ Disabled
+ Disk.Virtual.18:RAID.Integrated.1-1
+ Disk.Virtual.18:RAID.Integrated.1-1:T10PIStatus
+ true
+
+ Disabled
+ Enabled
+
+
+ RAIDStripeSize
+ 512(256 KB)
+ Disk.Virtual.18:RAID.Integrated.1-1
+ Disk.Virtual.18:RAID.Integrated.1-1:RAIDStripeSize
+ true
+
+ 0
+ 1(512 Bytes)
+ 2(1 KB)
+ 4(2 KB)
+ 8(4 KB)
+ 16(8 KB)
+ 32(16 KB)
+ 64(32 KB)
+ 128(64 KB)
+ 256(128 KB)
+ 512(256 KB)
+ 1024(512 KB)
+ 2048(1024 KB)
+ 4096(2048 KB)
+ 8192(4096 KB)
+ 16384(8192 KB)
+ 32768(16384 KB)
+
+
+ RAIDMultipath
+ Off
+ Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDMultipath
+ true
+
+ Off
+ On
+
+
+ BackplaneType
+ Not Shared
+ Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Enclosure.Internal.0-1:RAID.Integrated.1-1:BackplaneType
+ true
+
+ Not Shared
+ Shared
+
+
+ RAIDPDState
+ Online
+ Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDPDState
+ true
+
+ Unknown
+ Ready
+ Online
+ Foreign
+ Blocked
+ Failed
+ Non-RAID
+ Missing
+ Offline
+
+
+ RAIDHotSpareStatus
+ No
+ Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDHotSpareStatus
+ true
+
+ No
+ Dedicated
+ Global
+
+
+ RAIDNegotiatedSpeed
+ 12_GBS
+ Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNegotiatedSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+ RAIDPDState
+ Online
+ Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDPDState
+ true
+
+ Unknown
+ Ready
+ Online
+ Foreign
+ Blocked
+ Failed
+ Non-RAID
+ Missing
+ Offline
+
+
+ RAIDHotSpareStatus
+ No
+ Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDHotSpareStatus
+ true
+
+ No
+ Dedicated
+ Global
+
+
+ RAIDNegotiatedSpeed
+ 12_GBS
+ Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNegotiatedSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+ RAIDPDState
+ Online
+ Disk.Bay.2:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.2:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDPDState
+ true
+
+ Unknown
+ Ready
+ Online
+ Foreign
+ Blocked
+ Failed
+ Non-RAID
+ Missing
+ Offline
+
+
+ RAIDHotSpareStatus
+ No
+ Disk.Bay.2:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.2:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDHotSpareStatus
+ true
+
+ No
+ Dedicated
+ Global
+
+
+ RAIDNegotiatedSpeed
+ 12_GBS
+ Disk.Bay.2:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.2:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNegotiatedSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+ RAIDPDState
+ Online
+ Disk.Bay.3:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.3:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDPDState
+ true
+
+ Unknown
+ Ready
+ Online
+ Foreign
+ Blocked
+ Failed
+ Non-RAID
+ Missing
+ Offline
+
+
+ RAIDHotSpareStatus
+ No
+ Disk.Bay.3:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.3:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDHotSpareStatus
+ true
+
+ No
+ Dedicated
+ Global
+
+
+ RAIDNegotiatedSpeed
+ 12_GBS
+ Disk.Bay.3:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.3:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNegotiatedSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+ RAIDPDState
+ Online
+ Disk.Bay.4:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.4:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDPDState
+ true
+
+ Unknown
+ Ready
+ Online
+ Foreign
+ Blocked
+ Failed
+ Non-RAID
+ Missing
+ Offline
+
+
+ RAIDHotSpareStatus
+ No
+ Disk.Bay.4:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.4:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDHotSpareStatus
+
+ true
+
+ No
+ Dedicated
+ Global
+
+
+ RAIDNegotiatedSpeed
+ 12_GBS
+ Disk.Bay.4:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.4:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNegotiatedSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+ RAIDPDState
+ Online
+ Disk.Bay.5:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.5:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDPDState
+ true
+
+ Unknown
+ Ready
+ Online
+ Foreign
+ Blocked
+ Failed
+ Non-RAID
+ Missing
+ Offline
+
+
+ RAIDHotSpareStatus
+ No
+ Disk.Bay.5:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.5:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDHotSpareStatus
+ true
+
+ No
+ Dedicated
+ Global
+
+
+ RAIDNegotiatedSpeed
+ 12_GBS
+ Disk.Bay.5:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.5:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNegotiatedSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+ RAIDPDState
+ Online
+ Disk.Bay.6:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.6:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDPDState
+ true
+
+ Unknown
+ Ready
+ Online
+ Foreign
+ Blocked
+ Failed
+ Non-RAID
+ Missing
+ Offline
+
+
+ RAIDHotSpareStatus
+ No
+ Disk.Bay.6:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.6:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDHotSpareStatus
+ true
+
+ No
+ Dedicated
+ Global
+
+
+ RAIDNegotiatedSpeed
+ 12_GBS
+ Disk.Bay.6:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.6:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNegotiatedSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+ RAIDPDState
+ Online
+ Disk.Bay.7:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.7:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDPDState
+ true
+
+ Unknown
+ Ready
+ Online
+ Foreign
+ Blocked
+ Failed
+ Non-RAID
+ Missing
+ Offline
+
+
+ RAIDHotSpareStatus
+ No
+ Disk.Bay.7:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.7:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDHotSpareStatus
+ true
+
+ No
+ Dedicated
+ Global
+
+
+ RAIDNegotiatedSpeed
+ 12_GBS
+ Disk.Bay.7:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.7:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNegotiatedSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+ RAIDPDState
+ Online
+ Disk.Bay.8:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.8:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDPDState
+ true
+
+ Unknown
+ Ready
+ Online
+ Foreign
+ Blocked
+ Failed
+ Non-RAID
+ Missing
+ Offline
+
+
+ RAIDHotSpareStatus
+ No
+ Disk.Bay.8:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.8:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDHotSpareStatus
+ true
+
+ No
+ Dedicated
+ Global
+
+
+ RAIDNegotiatedSpeed
+ 12_GBS
+ Disk.Bay.8:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.8:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNegotiatedSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+ RAIDPDState
+ Online
+ Disk.Bay.9:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.9:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDPDState
+ true
+
+ Unknown
+ Ready
+ Online
+ Foreign
+ Blocked
+ Failed
+ Non-RAID
+ Missing
+ Offline
+
+
+ RAIDHotSpareStatus
+ No
+ Disk.Bay.9:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.9:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDHotSpareStatus
+ true
+
+ No
+ Dedicated
+ Global
+
+
+ RAIDNegotiatedSpeed
+ 12_GBS
+ Disk.Bay.9:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.9:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNegotiatedSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+ RAIDPDState
+ Online
+ Disk.Bay.10:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.10:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDPDState
+ true
+
+ Unknown
+ Ready
+ Online
+ Foreign
+ Blocked
+ Failed
+ Non-RAID
+ Missing
+ Offline
+
+
+ RAIDHotSpareStatus
+ No
+ Disk.Bay.10:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.10:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDHotSpareStatus
+ true
+
+ No
+ Dedicated
+ Global
+
+
+ RAIDNegotiatedSpeed
+ 12_GBS
+ Disk.Bay.10:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.10:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNegotiatedSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+ RAIDPDState
+ Online
+ Disk.Bay.11:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.11:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDPDState
+ true
+
+ Unknown
+ Ready
+ Online
+ Foreign
+ Blocked
+ Failed
+ Non-RAID
+ Missing
+ Offline
+
+
+ RAIDHotSpareStatus
+ No
+ Disk.Bay.11:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.11:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDHotSpareStatus
+ true
+
+ No
+ Dedicated
+ Global
+
+
+ RAIDNegotiatedSpeed
+ 12_GBS
+ Disk.Bay.11:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.11:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNegotiatedSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+ RAIDPDState
+ Online
+ Disk.Bay.12:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.12:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDPDState
+ true
+
+ Unknown
+ Ready
+ Online
+ Foreign
+ Blocked
+ Failed
+ Non-RAID
+ Missing
+ Offline
+
+
+ RAIDHotSpareStatus
+ No
+ Disk.Bay.12:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.12:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDHotSpareStatus
+ true
+
+ No
+ Dedicated
+ Global
+
+
+ RAIDNegotiatedSpeed
+ 6_GBS
+ Disk.Bay.12:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.12:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNegotiatedSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+ RAIDPDState
+ Online
+ Disk.Bay.13:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.13:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDPDState
+ true
+
+ Unknown
+ Ready
+ Online
+ Foreign
+ Blocked
+ Failed
+ Non-RAID
+ Missing
+ Offline
+
+
+ RAIDHotSpareStatus
+ No
+ Disk.Bay.13:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.13:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDHotSpareStatus
+ true
+
+ No
+ Dedicated
+ Global
+
+
+ RAIDNegotiatedSpeed
+ 6_GBS
+ Disk.Bay.13:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.13:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNegotiatedSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+ RAIDPDState
+ Online
+ Disk.Bay.14:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.14:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDPDState
+ true
+
+ Unknown
+ Ready
+ Online
+ Foreign
+ Blocked
+ Failed
+ Non-RAID
+ Missing
+ Offline
+
+
+ RAIDHotSpareStatus
+ No
+ Disk.Bay.14:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.14:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDHotSpareStatus
+ true
+
+ No
+ Dedicated
+ Global
+
+
+ RAIDNegotiatedSpeed
+ 6_GBS
+ Disk.Bay.14:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.14:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNegotiatedSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+ RAIDPDState
+ Online
+ Disk.Bay.15:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.15:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDPDState
+ true
+
+ Unknown
+ Ready
+ Online
+ Foreign
+ Blocked
+ Failed
+ Non-RAID
+ Missing
+ Offline
+
+
+ RAIDHotSpareStatus
+ No
+ Disk.Bay.15:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.15:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDHotSpareStatus
+ true
+
+ No
+ Dedicated
+ Global
+
+
+ RAIDNegotiatedSpeed
+ 6_GBS
+ Disk.Bay.15:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.15:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNegotiatedSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+ RAIDPDState
+ Online
+ Disk.Bay.16:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.16:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDPDState
+ true
+
+ Unknown
+ Ready
+ Online
+ Foreign
+ Blocked
+ Failed
+ Non-RAID
+ Missing
+ Offline
+
+
+ RAIDHotSpareStatus
+ No
+ Disk.Bay.16:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.16:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDHotSpareStatus
+ true
+
+ No
+ Dedicated
+ Global
+
+
+ RAIDNegotiatedSpeed
+ 12_GBS
+ Disk.Bay.16:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.16:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNegotiatedSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+ RAIDPDState
+ Online
+ Disk.Bay.17:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.17:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDPDState
+ true
+
+ Unknown
+ Ready
+ Online
+ Foreign
+ Blocked
+ Failed
+ Non-RAID
+ Missing
+ Offline
+
+
+ RAIDHotSpareStatus
+ No
+ Disk.Bay.17:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.17:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDHotSpareStatus
+ true
+
+ No
+ Dedicated
+ Global
+
+
+ RAIDNegotiatedSpeed
+ 12_GBS
+ Disk.Bay.17:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.17:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNegotiatedSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+ RAIDPDState
+ Online
+ Disk.Bay.18:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.18:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDPDState
+ true
+
+ Unknown
+ Ready
+ Online
+ Foreign
+ Blocked
+ Failed
+ Non-RAID
+ Missing
+ Offline
+
+
+ RAIDHotSpareStatus
+ No
+ Disk.Bay.18:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.18:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDHotSpareStatus
+ true
+
+ No
+ Dedicated
+ Global
+
+
+ RAIDNegotiatedSpeed
+ 12_GBS
+ Disk.Bay.18:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.18:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNegotiatedSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+ RAIDPDState
+ Online
+ Disk.Bay.19:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.19:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDPDState
+ true
+
+ Unknown
+ Ready
+ Online
+ Foreign
+ Blocked
+ Failed
+ Non-RAID
+ Missing
+ Offline
+
+
+ RAIDHotSpareStatus
+ No
+ Disk.Bay.19:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.19:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDHotSpareStatus
+ true
+
+ No
+ Dedicated
+ Global
+
+
+ RAIDNegotiatedSpeed
+ 12_GBS
+ Disk.Bay.19:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.19:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNegotiatedSpeed
+ true
+
+ 1_5_GBS
+ 3_GBS
+ 6_GBS
+ 12_GBS
+
+
+
+
+
+
diff --git a/dracclient/tests/wsman_mocks/raid_integer-enum-ok.xml b/dracclient/tests/wsman_mocks/raid_integer-enum-ok.xml
new file mode 100644
index 0000000..27c610c
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/raid_integer-enum-ok.xml
@@ -0,0 +1,416 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse
+ uuid:40206465-1566-46e3-bf05-9952ba57ec3c
+ uuid:6af777f7-9ef1-1ef1-b067-84d3878fd94c
+
+
+
+
+
+ RAIDmaxSupportedVD
+ 240
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDmaxSupportedVD
+ true
+ 0
+
+ 0
+
+
+ RAIDmaxPDsInSpan
+ 32
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDmaxPDsInSpan
+ true
+ 0
+
+ 0
+
+
+ RAIDmaxSpansInVD
+ 8
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDmaxSpansInVD
+ true
+ 0
+
+ 0
+
+
+ RAIDrebuildRate
+ 30
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDrebuildRate
+ false
+ 0
+
+ 100
+
+
+ RAIDccRate
+ 30
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDccRate
+ false
+ 0
+
+ 100
+
+
+ RAIDreconstructRate
+ 30
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDreconstructRate
+ false
+ 0
+
+ 100
+
+
+ RAIDbgiRate
+ 30
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDbgiRate
+ false
+ 0
+
+ 100
+
+
+ RAIDprRate
+ 30
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDprRate
+ true
+ 0
+
+ 100
+
+
+ RAIDspinDownIdleTime
+ 30
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDspinDownIdleTime
+ true
+ 0
+
+ 65535
+
+
+ RAIDprIterations
+ 0
+ RAID.Integrated.1-1
+ RAID.Integrated.1-1:RAIDprIterations
+ true
+ 1
+
+ 4294967295
+
+
+ RAIDmaxSupportedVD
+ 0
+ AHCI.Embedded.2-1
+ AHCI.Embedded.2-1:RAIDmaxSupportedVD
+ true
+ 0
+
+ 0
+
+
+ RAIDmaxPDsInSpan
+ 0
+ AHCI.Embedded.2-1
+ AHCI.Embedded.2-1:RAIDmaxPDsInSpan
+ true
+ 0
+
+ 0
+
+
+ RAIDmaxSpansInVD
+ 0
+ AHCI.Embedded.2-1
+ AHCI.Embedded.2-1:RAIDmaxSpansInVD
+ true
+ 0
+
+ 0
+
+
+ RAIDrebuildRate
+ 255
+ AHCI.Embedded.2-1
+ AHCI.Embedded.2-1:RAIDrebuildRate
+ true
+ 0
+
+ 100
+
+
+ RAIDccRate
+ 255
+ AHCI.Embedded.2-1
+ AHCI.Embedded.2-1:RAIDccRate
+ true
+ 0
+
+ 100
+
+
+ RAIDreconstructRate
+ 255
+ AHCI.Embedded.2-1
+ AHCI.Embedded.2-1:RAIDreconstructRate
+ true
+ 0
+
+ 100
+
+
+ RAIDbgiRate
+ 255
+ AHCI.Embedded.2-1
+ AHCI.Embedded.2-1:RAIDbgiRate
+ true
+ 0
+
+ 100
+
+
+ RAIDprRate
+ 255
+ AHCI.Embedded.2-1
+ AHCI.Embedded.2-1:RAIDprRate
+ true
+ 0
+
+ 100
+
+
+ RAIDspinDownIdleTime
+ 0
+ AHCI.Embedded.2-1
+ AHCI.Embedded.2-1:RAIDspinDownIdleTime
+ true
+ 0
+
+ 65535
+
+
+ RAIDprIterations
+ 0
+ AHCI.Embedded.2-1
+ AHCI.Embedded.2-1:RAIDprIterations
+ true
+ 1
+
+ 4294967295
+
+
+ RAIDmaxSupportedVD
+ 0
+ AHCI.Embedded.1-1
+ AHCI.Embedded.1-1:RAIDmaxSupportedVD
+ true
+ 0
+
+ 0
+
+
+ RAIDmaxPDsInSpan
+ 0
+ AHCI.Embedded.1-1
+ AHCI.Embedded.1-1:RAIDmaxPDsInSpan
+ true
+ 0
+
+ 0
+
+
+ RAIDmaxSpansInVD
+ 0
+ AHCI.Embedded.1-1
+ AHCI.Embedded.1-1:RAIDmaxSpansInVD
+ true
+ 0
+
+ 0
+
+
+ RAIDrebuildRate
+ 255
+ AHCI.Embedded.1-1
+ AHCI.Embedded.1-1:RAIDrebuildRate
+ true
+ 0
+
+ 100
+
+
+ RAIDccRate
+ 255
+ AHCI.Embedded.1-1
+ AHCI.Embedded.1-1:RAIDccRate
+ true
+ 0
+
+ 100
+
+
+ RAIDreconstructRate
+ 255
+ AHCI.Embedded.1-1
+ AHCI.Embedded.1-1:RAIDreconstructRate
+ true
+ 0
+
+ 100
+
+
+ RAIDbgiRate
+ 255
+ AHCI.Embedded.1-1
+ AHCI.Embedded.1-1:RAIDbgiRate
+ true
+ 0
+
+ 100
+
+
+ RAIDprRate
+ 255
+ AHCI.Embedded.1-1
+ AHCI.Embedded.1-1:RAIDprRate
+ true
+ 0
+
+ 100
+
+
+ RAIDspinDownIdleTime
+ 0
+ AHCI.Embedded.1-1
+ AHCI.Embedded.1-1:RAIDspinDownIdleTime
+ true
+ 0
+
+ 65535
+
+
+ RAIDprIterations
+ 0
+ AHCI.Embedded.1-1
+ AHCI.Embedded.1-1:RAIDprIterations
+ true
+ 1
+
+ 4294967295
+
+
+ RAIDNominalMediumRotationRate
+ 10000
+ Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNominalMediumRotationRate
+ true
+ 2
+
+ 4294967295
+
+
+ RAIDNominalMediumRotationRate
+ 10000
+ Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNominalMediumRotationRate
+ true
+ 2
+
+ 4294967295
+
+
+ RAIDNominalMediumRotationRate
+ 10000
+ Disk.Bay.2:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.2:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNominalMediumRotationRate
+ true
+ 2
+
+ 4294967295
+
+
+ RAIDNominalMediumRotationRate
+ 10000
+ Disk.Bay.3:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.3:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNominalMediumRotationRate
+ true
+ 2
+
+ 4294967295
+
+
+ RAIDNominalMediumRotationRate
+ 10000
+ Disk.Bay.4:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.4:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNominalMediumRotationRate
+ true
+ 2
+
+ 4294967295
+
+
+ RAIDNominalMediumRotationRate
+ 10000
+ Disk.Bay.5:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.5:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNominalMediumRotationRate
+ true
+ 2
+
+ 4294967295
+
+
+ RAIDNominalMediumRotationRate
+ 10000
+ Disk.Bay.6:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.6:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNominalMediumRotationRate
+ true
+ 2
+
+ 4294967295
+
+
+ RAIDNominalMediumRotationRate
+ 10000
+ Disk.Bay.7:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.7:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNominalMediumRotationRate
+ true
+ 2
+
+ 4294967295
+
+
+ RAIDNominalMediumRotationRate
+ 10000
+ Disk.Bay.8:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.8:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNominalMediumRotationRate
+ true
+ 2
+
+ 4294967295
+
+
+ RAIDNominalMediumRotationRate
+ 10000
+ Disk.Bay.9:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.9:Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDNominalMediumRotationRate
+ true
+ 2
+
+ 4294967295
+
+
+
+
+
+
+
diff --git a/dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-invalid_controller.xml b/dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-invalid_controller.xml
new file mode 100644
index 0000000..d60acb2
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-invalid_controller.xml
@@ -0,0 +1,17 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_RAIDService/ClearForeignConfigResponse
+ uuid:f9487fcf-103a-103a-8002-fd0aa2bdb228
+ uuid:000852e6-1040-1040-8997-a36fc6fe83b0
+
+
+
+ Controller not found
+ STOR030
+ 2
+
+
+
diff --git a/dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-no_foreign_drive.xml b/dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-no_foreign_drive.xml
new file mode 100644
index 0000000..6ab74d7
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-no_foreign_drive.xml
@@ -0,0 +1,17 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_RAIDService/ClearForeignConfigResponse
+ uuid:f9487fcf-103a-103a-8002-fd0aa2bdb228
+ uuid:000852e6-1040-1040-8997-a36fc6fe83b0
+
+
+
+ No foreign drives detected
+ STOR018
+ 2
+
+
+
diff --git a/dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-not_supported.xml b/dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-not_supported.xml
new file mode 100644
index 0000000..898e739
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-not_supported.xml
@@ -0,0 +1,18 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_RAIDService/ClearForeignConfigResponse
+ uuid:473f8ede-9a1a-441a-aaf6-699c1476aa97
+ uuid:55d91de0-90a1-10a1-8147-8c0c498fd94c
+
+
+
+ The operation cannot be completed either because the operation is not supported on the target device,
+ or the RAIDType of "MD Software RAID" does not allow the operation.
+ STOR058
+ 2
+
+
+
diff --git a/dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-ok.xml b/dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-ok.xml
new file mode 100644
index 0000000..dc303c5
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-ok.xml
@@ -0,0 +1,16 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_RAIDService/ClearForeignConfigResponse
+ uuid:fefa06de-103a-103a-8002-fd0aa2bdb228
+ uuid:05bc00f4-1040-1040-899d-a36fc6fe83b0
+
+
+
+ OPTIONAL
+ 0
+
+
+
diff --git a/dracclient/tests/wsman_mocks/raid_service-invoke-delete_virtual_disk-error.xml b/dracclient/tests/wsman_mocks/raid_service-invoke-delete_virtual_disk-error.xml
index c964a6b..37d5da2 100644
--- a/dracclient/tests/wsman_mocks/raid_service-invoke-delete_virtual_disk-error.xml
+++ b/dracclient/tests/wsman_mocks/raid_service-invoke-delete_virtual_disk-error.xml
@@ -14,4 +14,4 @@
2
-
\ No newline at end of file
+
diff --git a/dracclient/tests/wsman_mocks/raid_service-invoke-delete_virtual_disk-ok.xml b/dracclient/tests/wsman_mocks/raid_service-invoke-delete_virtual_disk-ok.xml
index 0b3eff2..b1035c3 100644
--- a/dracclient/tests/wsman_mocks/raid_service-invoke-delete_virtual_disk-ok.xml
+++ b/dracclient/tests/wsman_mocks/raid_service-invoke-delete_virtual_disk-ok.xml
@@ -13,4 +13,4 @@
0
-
\ No newline at end of file
+
diff --git a/dracclient/tests/wsman_mocks/raid_service-invoke-reset_raid_config-error.xml b/dracclient/tests/wsman_mocks/raid_service-invoke-reset_raid_config-error.xml
new file mode 100644
index 0000000..cad10be
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/raid_service-invoke-reset_raid_config-error.xml
@@ -0,0 +1,17 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_RAIDService/ResetConfigResponse
+ uuid:f9487fcf-103a-103a-8002-fd0aa2bdb228
+ uuid:000852e6-1040-1040-8997-a36fc6fe83b0
+
+
+
+ Virtual Disk not found
+ STOR028
+ 2
+
+
+
diff --git a/dracclient/tests/wsman_mocks/raid_service-invoke-reset_raid_config-ok.xml b/dracclient/tests/wsman_mocks/raid_service-invoke-reset_raid_config-ok.xml
new file mode 100644
index 0000000..867f54a
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/raid_service-invoke-reset_raid_config-ok.xml
@@ -0,0 +1,16 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_RAIDService/ResetConfigResponse
+ uuid:fefa06de-103a-103a-8002-fd0aa2bdb228
+ uuid:05bc00f4-1040-1040-899d-a36fc6fe83b0
+
+
+
+ OPTIONAL
+ 0
+
+
+
diff --git a/dracclient/tests/wsman_mocks/raid_service-invoke-set_attributes-error.xml b/dracclient/tests/wsman_mocks/raid_service-invoke-set_attributes-error.xml
new file mode 100644
index 0000000..e79807b
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/raid_service-invoke-set_attributes-error.xml
@@ -0,0 +1,21 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_RAIDService/SetAttributesResponse
+
+ uuid:bf8adefe-6fc0-456d-b97c-fd8d4aca2d6c
+
+ uuid:84abf7b9-7176-1176-a11c-a53ffbd9bed4
+
+
+
+
+ Invalid parameter value
+ STOR004
+ 2
+
+
+
diff --git a/dracclient/tests/wsman_mocks/raid_service-invoke-set_attributes-ok.xml b/dracclient/tests/wsman_mocks/raid_service-invoke-set_attributes-ok.xml
new file mode 100644
index 0000000..50d5fd4
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/raid_service-invoke-set_attributes-ok.xml
@@ -0,0 +1,24 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_RAIDService/SetAttributesResponse
+
+ uuid:bf8adefe-6fc0-456d-b97c-fd8d4aca2d6c
+
+ uuid:84abf7b9-7176-1176-a11c-a53ffbd9bed4
+
+
+
+
+ STOR001
+ The command was successful for all attributes
+ 0
+ Yes
+ Set PendingValue
+
+
+
+
diff --git a/dracclient/tests/wsman_mocks/raid_string-enum-ok.xml b/dracclient/tests/wsman_mocks/raid_string-enum-ok.xml
new file mode 100644
index 0000000..866961f
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/raid_string-enum-ok.xml
@@ -0,0 +1,49 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse
+ uuid:6f1e7eae-511a-4268-9913-c1ce1bb414be
+ uuid:6da65cf0-9cbb-1cbb-9773-deda878fd94c
+
+
+
+
+
+ Name
+ Virtual Disk 0
+ Disk.Virtual.0:RAID.Integrated.1-1
+ Disk.Virtual.0:RAID.Integrated.1-1:Name
+ true
+ 129
+ 0
+
+
+
+ Name
+ Virtual Disk 1
+ Disk.Virtual.1:RAID.Integrated.1-1
+ Disk.Virtual.1:RAID.Integrated.1-1:Name
+ true
+ 129
+ 0
+
+
+
+ RAIDEffectiveSASAddress
+ 500056B3239C1AFD
+ Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Enclosure.Internal.0-1:RAID.Integrated.1-1:RAIDEffectiveSASAddress
+ true
+ 16
+ 16
+
+
+
+
+
+
diff --git a/dracclient/tests/wsman_mocks/system_enumeration-enum-ok.xml b/dracclient/tests/wsman_mocks/system_enumeration-enum-ok.xml
new file mode 100644
index 0000000..a790951
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/system_enumeration-enum-ok.xml
@@ -0,0 +1,294 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse
+ uuid:f150770f-b5b7-4b08-9572-b5225e7c668b
+ uuid:7c41ce96-41ee-11ee-a839-de7e4e771814
+
+
+
+
+
+ Power Cap Setting
+ PowerCapSetting
+ Disabled
+ Disabled
+
+ 1401
+ System.Embedded.1
+ Server Power
+ ServerPwr.1
+ System.Embedded.1#ServerPwr.1#PowerCapSetting
+ false
+
+ Enabled
+ Disabled
+
+
+ Power Supply Redundancy Policy
+ PSRedPolicy
+ Input Power Redundant
+ Not Redundant
+
+ 1405
+ System.Embedded.1
+ Server Power
+ ServerPwr.1
+ System.Embedded.1#ServerPwr.1#PSRedPolicy
+ false
+
+ Not Redundant
+ Input Power Redundant
+
+
+ Power Supply PFC Enable
+ PSPFCEnabled
+ Disabled
+ Disabled
+
+ 1406
+ System.Embedded.1
+ Server Power
+ ServerPwr.1
+ System.Embedded.1#ServerPwr.1#PSPFCEnabled
+ false
+
+ Enabled
+ Disabled
+
+
+ Power Supply Rapid On Enable
+ PSRapidOn
+ Disabled
+ Enabled
+
+ 1408
+ System.Embedded.1
+ Server Power
+ ServerPwr.1
+ System.Embedded.1#ServerPwr.1#PSRapidOn
+ false
+
+ Enabled
+ Disabled
+
+
+ Rapid on Primary PSU
+ RapidOnPrimaryPSU
+ PSU1
+ PSU1
+
+ 1411
+ System.Embedded.1
+ Server Power
+ ServerPwr.1
+ System.Embedded.1#ServerPwr.1#RapidOnPrimaryPSU
+ false
+
+ PSU1
+ PSU2
+
+
+ LCD Configuration
+ Configuration
+ Service Tag
+ Service Tag
+
+ 1432
+ System.Embedded.1
+ LCD
+ LCD.1
+ System.Embedded.1#LCD.1#Configuration
+ false
+
+ User Defined
+ Model Name
+ None
+ iDRAC IPv4 Address
+ iDRAC MAC Address
+ OS System Name
+ Service Tag
+ IPv6 Address
+ Ambient Temperature
+ System Watts
+ Asset Tag
+
+
+ vConsole Indication
+ vConsoleIndication
+ Disabled
+ Disabled
+
+ 1434
+ System.Embedded.1
+ LCD
+ LCD.1
+ System.Embedded.1#LCD.1#vConsoleIndication
+ false
+
+ Enabled
+ Disabled
+
+
+ System Watt Qualifier
+ QualifierWatt
+ Watts
+ Watts
+
+ 1435
+ System.Embedded.1
+ LCD
+ LCD.1
+ System.Embedded.1#LCD.1#QualifierWatt
+ false
+
+ Watts
+ BTU/hr
+
+
+ Ambient Temperature Qualifier
+ QualifierTemp
+ F
+ C
+
+ 1436
+ System.Embedded.1
+ LCD
+ LCD.1
+ System.Embedded.1#LCD.1#QualifierTemp
+ false
+
+ C
+ F
+
+
+ Fresh Air Compliant Configuration
+ FreshAirCompliantConfiguration
+ Yes
+ Yes
+
+ 1441
+ System.Embedded.1
+ Thermal Configuration
+ ThermalConfig.1
+ System.Embedded.1#ThermalConfig.1#FreshAirCompliantConfiguration
+ true
+
+ Not Applicable
+ Yes
+ No
+
+
+ Thermal Profile
+ ThermalProfile
+ Maximum Performance
+ Default Thermal Profile Settings
+
+ 1470
+ System.Embedded.1
+ Thermal Settings
+ ThermalSettings.1
+ System.Embedded.1#ThermalSettings.1#ThermalProfile
+ false
+
+ Default Thermal Profile Settings
+ Maximum Performance
+ Minimum Power
+
+
+ Fan Speed Offset
+ FanSpeedOffset
+ Off
+ Off
+
+ 1472
+ System.Embedded.1
+ Thermal Settings
+ ThermalSettings.1
+ System.Embedded.1#ThermalSettings.1#FanSpeedOffset
+ false
+
+ Off
+ Low Fan Speed
+ High Fan Speed
+ Medium Fan Speed
+ Max Fan Speed
+
+
+ Fan Speed Response for Third-Party PCI Cards
+ ThirdPartyPCIFanResponse
+ Enabled
+ Enabled
+
+ 1480
+ System.Embedded.1
+ Thermal Settings
+ ThermalSettings.1
+ System.Embedded.1#ThermalSettings.1#ThirdPartyPCIFanResponse
+ false
+
+ Disabled
+ Enabled
+
+
+ Quick Sync Presence
+ Presence
+ Not Supported
+ Not Supported
+
+ 2300
+ System.Embedded.1
+ Quick Sync
+ QuickSync.1
+ System.Embedded.1#QuickSync.1#Presence
+ true
+
+ Not Supported
+ Absent
+ Present
+
+
+ Backplane Bus Mode
+ BackplaneBusMode
+ I2C
+ Unknown
+
+ 2330
+ System.Embedded.1
+ Backplane
+ Backplane.1
+ System.Embedded.1#Backplane.1#BackplaneBusMode
+ true
+
+ Unknown
+ I2C
+ SGPIO
+
+
+ LED State
+ ChassisLEDState
+ Off
+ Unknown
+
+ 2372
+ System.Embedded.1
+ Powerstate
+ ChassisPwrState.1
+ System.Embedded.1#ChassisPwrState.1#ChassisLEDState
+ false
+
+ Unknown
+ Blinking
+ Off
+
+
+
+
+
+
+
diff --git a/dracclient/tests/wsman_mocks/system_integer-enum-ok.xml b/dracclient/tests/wsman_mocks/system_integer-enum-ok.xml
new file mode 100644
index 0000000..5d6efaa
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/system_integer-enum-ok.xml
@@ -0,0 +1,277 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse
+ uuid:9ce6b8f8-cd0e-4994-8db6-758ef8da9d8c
+ uuid:7c9354bc-41ee-11ee-a83d-de7e4e771814
+
+
+
+
+
+ Power Cap Value
+ PowerCapValue
+ 555
+ 32767
+
+ 1402
+ System.Embedded.1
+ Server Power
+ ServerPwr.1
+ System.Embedded.1#ServerPwr.1#PowerCapValue
+ false
+ 302
+
+ 578
+
+
+ Power Cap Max Threshold
+ PowerCapMaxThres
+ 578
+ 0
+
+ 1403
+ System.Embedded.1
+ Server Power
+ ServerPwr.1
+ System.Embedded.1#ServerPwr.1#PowerCapMaxThres
+ true
+
+
+
+
+
+ Power Cap Min Threshold
+ PowerCapMinThres
+ 302
+ 0
+
+ 1404
+ System.Embedded.1
+ Server Power
+ ServerPwr.1
+ System.Embedded.1#ServerPwr.1#PowerCapMinThres
+ true
+
+
+
+
+
+ Active Power Cap Value
+ ActivePowerCapVal
+ 555
+ 32767
+
+ 1409
+ System.Embedded.1
+ Server Power
+ ServerPwr.1
+ System.Embedded.1#ServerPwr.1#ActivePowerCapVal
+ true
+ 302
+
+ 578
+
+
+ Rack Slot
+ RackSlot
+ 1
+ 1
+
+ 1424
+ System.Embedded.1
+ Server Topology
+ ServerTopology.1
+ System.Embedded.1#ServerTopology.1#RackSlot
+ false
+ 1
+
+ 255
+
+
+ Size of Managed System in U
+ SizeOfManagedSystemInU
+ 1
+ 0
+
+ 1425
+ System.Embedded.1
+ Server Topology
+ ServerTopology.1
+ System.Embedded.1#ServerTopology.1#SizeOfManagedSystemInU
+ true
+
+
+
+
+
+ Event Generation Interval
+ EventGenerationInterval
+ 30
+ 30
+
+ 1440
+ System.Embedded.1
+ Thermal Configuration
+ ThermalConfig.1
+ System.Embedded.1#ThermalConfig.1#EventGenerationInterval
+ false
+ 0
+
+ 365
+
+
+ Critical Event Generation Interval
+ CriticalEventGenerationInterval
+ 30
+ 30
+
+ 1440
+ System.Embedded.1
+ Thermal Configuration
+ ThermalConfig.1
+ System.Embedded.1#ThermalConfig.1#CriticalEventGenerationInterval
+ false
+ 0
+
+ 365
+
+
+ Server Powered On Time Duration
+ ServerPoweredOnTime
+ 123456
+ 0
+
+ 1453
+ System.Embedded.1
+ Server Operating System
+ ServerOS.1
+ System.Embedded.1#ServerOS.1#ServerPoweredOnTime
+ true
+
+
+
+
+
+ Minimum Fan Speed
+ MinimumFanSpeed
+ 255
+ 0
+
+ 1473
+ System.Embedded.1
+ Thermal Settings
+ ThermalSettings.1
+ System.Embedded.1#ThermalSettings.1#MinimumFanSpeed
+ false
+ 0
+
+ 65535
+
+
+ MFS Minimum Limit
+ MFSMinimumLimit
+ 9
+ 0
+
+ 1474
+ System.Embedded.1
+ Thermal Settings
+ ThermalSettings.1
+ System.Embedded.1#ThermalSettings.1#MFSMinimumLimit
+ true
+
+
+
+
+
+ MFS Maximum Limit
+ MFSMaximumLimit
+ 100
+ 0
+
+ 1475
+ System.Embedded.1
+ Thermal Settings
+ ThermalSettings.1
+ System.Embedded.1#ThermalSettings.1#MFSMaximumLimit
+ true
+
+
+
+
+
+ Fan Speed Low Offset Value
+ FanSpeedLowOffsetVal
+ 35
+ 0
+
+ 1476
+ System.Embedded.1
+ Thermal Settings
+ ThermalSettings.1
+ System.Embedded.1#ThermalSettings.1#FanSpeedLowOffsetVal
+ true
+
+
+
+
+
+ Fan Speed Medium Offset Value
+ FanSpeedMediumOffsetVal
+ 50
+ 0
+
+ 1477
+ System.Embedded.1
+ Thermal Settings
+ ThermalSettings.1
+ System.Embedded.1#ThermalSettings.1#FanSpeedMediumOffsetVal
+ true
+
+
+
+
+
+ Fan Speed High Offset Value
+ FanSpeedHighOffsetVal
+ 55
+ 0
+
+ 1478
+ System.Embedded.1
+ Thermal Settings
+ ThermalSettings.1
+ System.Embedded.1#ThermalSettings.1#FanSpeedHighOffsetVal
+ true
+
+
+
+
+
+ Fan Speed Maximum Offset Value
+ FanSpeedMaxOffsetVal
+ 100
+ 0
+
+ 1479
+ System.Embedded.1
+ Thermal Settings
+ ThermalSettings.1
+ System.Embedded.1#ThermalSettings.1#FanSpeedMaxOffsetVal
+ true
+
+
+
+
+
+
+
+
+
+
diff --git a/dracclient/tests/wsman_mocks/system_string-enum-ok.xml b/dracclient/tests/wsman_mocks/system_string-enum-ok.xml
new file mode 100644
index 0000000..8086367
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/system_string-enum-ok.xml
@@ -0,0 +1,213 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse
+ uuid:2c1819b5-9c87-44ee-bde1-88e43cd73edd
+ uuid:7c734ea8-41ee-11ee-a83b-de7e4e771814
+
+
+
+
+
+ Active Power Cap Policy Name
+ ActivePolicyName
+ iDRAC
+
+
+ 1410
+ System.Embedded.1
+ Server Power
+ ServerPwr.1
+ System.Embedded.1#ServerPwr.1#ActivePolicyName
+ true
+ 128
+ 0
+
+
+
+ Data Center Name
+ DataCenterName
+
+
+
+ 1421
+ System.Embedded.1
+ Server Topology
+ ServerTopology.1
+ System.Embedded.1#ServerTopology.1#DataCenterName
+ false
+ 128
+ 0
+
+
+
+ Aisle Name
+ AisleName
+
+
+
+ 1422
+ System.Embedded.1
+ Server Topology
+ ServerTopology.1
+ System.Embedded.1#ServerTopology.1#AisleName
+ false
+ 128
+ 0
+
+
+
+ Rack Name
+ RackName
+
+
+
+ 1423
+ System.Embedded.1
+ Server Topology
+ ServerTopology.1
+ System.Embedded.1#ServerTopology.1#RackName
+ false
+ 128
+ 0
+
+
+
+ Room Name
+ RoomName
+
+
+
+ 1428
+ System.Embedded.1
+ Server Topology
+ ServerTopology.1
+ System.Embedded.1#ServerTopology.1#RoomName
+ false
+ 128
+ 0
+
+
+
+ Current LCD Display String
+ CurrentDisplay
+ ST: 1234567
+
+
+ 1431
+ System.Embedded.1
+ LCD
+ LCD.1
+ System.Embedded.1#LCD.1#CurrentDisplay
+ true
+ 62
+ 0
+
+
+
+ User Defined String for LCD
+ UserDefinedString
+
+
+
+ 1433
+ System.Embedded.1
+ LCD
+ LCD.1
+ System.Embedded.1#LCD.1#UserDefinedString
+ false
+ 62
+ 0
+
+
+
+ Host Name
+ HostName
+ test-host1-1-dc.ops.domain.net
+
+
+ 1450
+ System.Embedded.1
+ Server Operating System
+ ServerOS.1
+ System.Embedded.1#ServerOS.1#HostName
+ false
+ 62
+ 0
+
+
+
+ Operating System Name
+ OSName
+ CentOS
+
+
+ 1451
+ System.Embedded.1
+ Server Operating System
+ ServerOS.1
+ System.Embedded.1#ServerOS.1#OSName
+ false
+ 62
+ 0
+
+
+
+ Operating System Version
+ OSVersion
+ release 6.8 (Final) Kernel 2.6.32-642.3.1.el6.x86_64 (x86_64)
+
+
+ 1452
+ System.Embedded.1
+ Server Operating System
+ ServerOS.1
+ System.Embedded.1#ServerOS.1#OSVersion
+ true
+ 62
+ 0
+
+
+
+ OEM Operating System Version
+ OEMOSVersion
+ release 6.8 (Final) Kernel 2.6.32-642.3.1.el6.x86_64 (x86_64)
+
+
+ 1454
+ System.Embedded.1
+ Server Operating System
+ ServerOS.1
+ System.Embedded.1#ServerOS.1#OEMOSVersion
+ true
+ 62
+ 0
+
+
+
+ OS App Collection Time
+ OSAppCollectionTime
+ N/A
+
+
+ 2310
+ System.Embedded.1
+ Server Information
+ Diagnostics.1
+ System.Embedded.1#Diagnostics.1#OSAppCollectionTime
+ true
+ 64
+ 0
+
+
+
+
+
+
+
+
diff --git a/dracclient/tests/wsman_mocks/system_view-enum-ok.xml b/dracclient/tests/wsman_mocks/system_view-enum-ok.xml
index ad2d5a5..c10054b 100644
--- a/dracclient/tests/wsman_mocks/system_view-enum-ok.xml
+++ b/dracclient/tests/wsman_mocks/system_view-enum-ok.xml
@@ -15,9 +15,12 @@
System.Embedded.1
2.1.0
+ PowerEdge R630
+ A1B2C3D
+ ebd4edd3-dfd7-4c7d-a2c8-562b3c23b811
-
\ No newline at end of file
+
diff --git a/dracclient/tests/wsman_mocks/virtual_disk_view-enum-ok.xml b/dracclient/tests/wsman_mocks/virtual_disk_view-enum-ok.xml
index 1777050..ee507f2 100644
--- a/dracclient/tests/wsman_mocks/virtual_disk_view-enum-ok.xml
+++ b/dracclient/tests/wsman_mocks/virtual_disk_view-enum-ok.xml
@@ -30,7 +30,8 @@
Background Intialization
8
0
-
+ Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1
1
2
4
@@ -51,4 +52,4 @@
-
\ No newline at end of file
+
diff --git a/dracclient/tests/wsman_mocks/virtual_disk_view-enum-with-raid-status-ok.xml b/dracclient/tests/wsman_mocks/virtual_disk_view-enum-with-raid-status-ok.xml
new file mode 100644
index 0000000..c8e3151
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/virtual_disk_view-enum-with-raid-status-ok.xml
@@ -0,0 +1,55 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse
+ uuid:b182f1ee-103a-103a-8002-fd0aa2bdb228
+ uuid:b80f21ed-103f-103f-8992-a36fc6fe83b0
+
+
+
+
+
+ 512
+ 6
+ 0
+ Virtual Disk 0 on Integrated RAID Controller 1
+ 1024
+ Disk.Virtual.0:RAID.Integrated.1-1
+ Disk.Virtual.0:RAID.Integrated.1-1
+ 20150301200527.000000+000
+ 20150301200527.000000+000
+ 0
+ 1
+ disk 0
+ 0
+ Background Intialization
+ 8
+ 0
+ Disk.Bay.4:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ Disk.Bay.5:Enclosure.Internal.0-1:RAID.Integrated.1-1
+ 1
+ 2
+ 4
+ 16
+ 1
+ 1
+ 599550590976
+ 1
+ 2
+ 0
+ 128
+ 0
+ 0
+ 2
+
+
+
+
+
+
+
diff --git a/dracclient/tests/wsman_mocks/wsman-enum_context-1.xml b/dracclient/tests/wsman_mocks/wsman-enum_context-1.xml
index e9b265b..002cb69 100644
--- a/dracclient/tests/wsman_mocks/wsman-enum_context-1.xml
+++ b/dracclient/tests/wsman_mocks/wsman-enum_context-1.xml
@@ -1,6 +1,8 @@
+ xmlns:wsen="http://schemas.xmlsoap.org/ws/2004/09/enumeration"
+ xmlns:wsman="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"
+ xmlns:n1="http://FooResource">
http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse
@@ -10,6 +12,11 @@
enum-context-uuid
+
+
+ 1
+
+
diff --git a/dracclient/tests/wsman_mocks/wsman-enum_context-2.xml b/dracclient/tests/wsman_mocks/wsman-enum_context-2.xml
index cab5e11..a2ae36c 100644
--- a/dracclient/tests/wsman_mocks/wsman-enum_context-2.xml
+++ b/dracclient/tests/wsman_mocks/wsman-enum_context-2.xml
@@ -14,7 +14,7 @@
enum-context-uuid
- 1
+ 2
diff --git a/dracclient/tests/wsman_mocks/wsman-enum_context-3.xml b/dracclient/tests/wsman_mocks/wsman-enum_context-3.xml
index 38190c7..1516a9a 100644
--- a/dracclient/tests/wsman_mocks/wsman-enum_context-3.xml
+++ b/dracclient/tests/wsman_mocks/wsman-enum_context-3.xml
@@ -13,10 +13,10 @@
enum-context-uuid
- 2
+ 3
- 3
+ 4
diff --git a/dracclient/tests/wsman_mocks/wsman-enum_context-4.xml b/dracclient/tests/wsman_mocks/wsman-enum_context-4.xml
index 15e0490..81ddbf5 100644
--- a/dracclient/tests/wsman_mocks/wsman-enum_context-4.xml
+++ b/dracclient/tests/wsman_mocks/wsman-enum_context-4.xml
@@ -12,7 +12,7 @@
- 4
+ 5
diff --git a/dracclient/utils.py b/dracclient/utils.py
index 935cdb4..387f5b2 100644
--- a/dracclient/utils.py
+++ b/dracclient/utils.py
@@ -15,7 +15,13 @@
Common functionalities shared between different DRAC modules.
"""
+from dracclient import constants
+import logging
+
from dracclient import exceptions
+from dracclient import wsman
+
+LOG = logging.getLogger(__name__)
NS_XMLSchema_Instance = 'http://www.w3.org/2001/XMLSchema-instance'
@@ -24,6 +30,12 @@
RET_ERROR = '2'
RET_CREATED = '4096'
+REBOOT_REQUIRED = {
+ 'yes': constants.RebootRequired.true,
+ 'no': constants.RebootRequired.false,
+ 'optional': constants.RebootRequired.optional
+}
+
def find_xml(doc, item, namespace, find_all=False):
"""Find the first or all elements in an ElementTree object.
@@ -46,6 +58,15 @@ def find_xml(doc, item, namespace, find_all=False):
return doc.find(query)
+def _is_attr_non_nil(elem):
+ """Return whether an element is non-nil.
+
+ :param elem: the element object.
+ :returns: whether the element is nil.
+ """
+ return elem.attrib.get('{%s}nil' % NS_XMLSchema_Instance) != 'true'
+
+
def get_wsman_resource_attr(doc, resource_uri, attr_name, nullable=False,
allow_missing=False):
"""Find an attribute of a resource in an ElementTree object.
@@ -78,11 +99,94 @@ def get_wsman_resource_attr(doc, resource_uri, attr_name, nullable=False,
raise exceptions.DRACEmptyResponseField(attr=attr_name)
return item.text.strip()
else:
- nil_attr = item.attrib.get('{%s}nil' % NS_XMLSchema_Instance)
- if nil_attr != 'true':
+ if _is_attr_non_nil(item):
return item.text.strip()
+def get_all_wsman_resource_attrs(doc, resource_uri, attr_name, nullable=False):
+ """Find all instances of an attribute of a resource in an ElementTree.
+
+ :param doc: the element tree object.
+ :param resource_uri: the resource URI of the namespace.
+ :param attr_name: the name of the attribute.
+ :param nullable: enables checking if any of the elements contain an
+ XMLSchema-instance namespaced nil attribute that has a
+ value of True. In this case, these elements will not be
+ returned.
+ :raises: DRACEmptyResponseField if any of the attributes in the XML doc
+ have no text and nullable is False.
+ :returns: a list containing the value of each of the instances of the
+ attribute.
+ """
+ items = find_xml(doc, attr_name, resource_uri, find_all=True)
+
+ if not nullable:
+ for item in items:
+ if item.text is None:
+ raise exceptions.DRACEmptyResponseField(attr=attr_name)
+ return [item.text.strip() for item in items]
+ else:
+
+ return [item.text.strip() for item in items if _is_attr_non_nil(item)]
+
+
+def build_return_dict(doc, resource_uri,
+ is_commit_required_value=None,
+ is_reboot_required_value=None):
+ """Builds a dictionary to be returned
+
+ Build a dictionary to be returned from WSMAN operations that are not
+ read-only.
+
+ :param doc: the element tree object.
+ :param resource_uri: the resource URI of the namespace.
+ :param is_commit_required_value: The value to be returned for
+ is_commit_required, or None if the value should be determined
+ from the doc.
+ :param is_reboot_required_value: The value to be returned for
+ is_reboot_required, or None if the value should be determined
+ from the doc.
+ :returns: a dictionary containing:
+ - is_commit_required: indicates if a commit is required.
+ - is_reboot_required: indicates if a reboot is required.
+ """
+
+ if is_reboot_required_value is not None and \
+ is_reboot_required_value not in constants.RebootRequired.all():
+ msg = ("is_reboot_required_value must be a member of the "
+ "RebootRequired enumeration or None. The passed value was "
+ "%(is_reboot_required_value)s" % {
+ 'is_reboot_required_value': is_reboot_required_value})
+ raise exceptions.InvalidParameterValue(reason=msg)
+
+ result = {}
+ if is_commit_required_value is None:
+ is_commit_required_value = is_commit_required(doc, resource_uri)
+
+ result['is_commit_required'] = is_commit_required_value
+
+ if is_reboot_required_value is None:
+ is_reboot_required_value = reboot_required(doc, resource_uri)
+
+ result['is_reboot_required'] = is_reboot_required_value
+
+ return result
+
+
+def is_commit_required(doc, resource_uri):
+ """Check the response document if commit is required.
+
+ If SetResult contains "pending" in the response then a commit is required.
+
+ :param doc: the element tree object.
+ :param resource_uri: the resource URI of the namespace.
+ :returns: a boolean value indicating commit is required or not.
+ """
+
+ commit_required = find_xml(doc, 'SetResult', resource_uri)
+ return "pendingvalue" in commit_required.text.lower()
+
+
def is_reboot_required(doc, resource_uri):
"""Check the response document if reboot is requested.
@@ -99,6 +203,22 @@ def is_reboot_required(doc, resource_uri):
return reboot_required.text.lower() == 'yes'
+def reboot_required(doc, resource_uri):
+ """Check the response document if reboot is requested.
+
+ RebootRequired attribute in the response indicates whether node needs to
+ be rebooted, so that the pending changes can be committed.
+
+ :param doc: the element tree object.
+ :param resource_uri: the resource URI of the namespace.
+ :returns: True if reboot is required, False if it is not, and the string
+ "optional" if reboot is optional.
+ """
+
+ reboot_required_value = find_xml(doc, 'RebootRequired', resource_uri)
+ return REBOOT_REQUIRED[reboot_required_value.text.lower()]
+
+
def validate_integer_value(value, attr_name, error_msgs):
"""Validate integer value"""
@@ -110,3 +230,209 @@ def validate_integer_value(value, attr_name, error_msgs):
int(value)
except ValueError:
error_msgs.append("'%s' is not an integer value" % attr_name)
+
+
+def list_settings(client, namespaces, by_name=True, fqdd_filter=None,
+ name_formatter=None, wait_for_idrac=True):
+ """List the configuration settings
+
+ :param client: an instance of WSManClient.
+ :param namespaces: a list of URI/class pairs to retrieve.
+ :param by_name: controls whether returned dictionary uses
+ attribute name or instance_id as key.
+ :param fqdd_filter: An FQDD used to filter the instances. Note that
+ this is only used when by_name is True.
+ :param name_formatter: a method used to format the keys in the
+ returned dictionary. By default,
+ attribute.name will be used.
+ :param wait_for_idrac: indicates whether or not to wait for the
+ iDRAC to be ready to accept commands before
+ issuing the command.
+ :returns: a dictionary with the settings using name or instance_id as
+ the key.
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on error reported back by the DRAC
+ interface
+ """
+
+ result = {}
+ for (namespace, attr_cls) in namespaces:
+ attribs = _get_config(client, namespace, attr_cls, by_name,
+ fqdd_filter, name_formatter, wait_for_idrac)
+ if not set(result).isdisjoint(set(attribs)):
+ raise exceptions.DRACOperationFailed(
+ drac_messages=('Colliding attributes %r' % (
+ set(result) & set(attribs))))
+ result.update(attribs)
+ return result
+
+
+def _get_config(client, resource, attr_cls, by_name, fqdd_filter,
+ name_formatter, wait_for_idrac):
+ result = {}
+
+ doc = client.enumerate(resource, wait_for_idrac=wait_for_idrac)
+ items = doc.find('.//{%s}Items' % wsman.NS_WSMAN)
+
+ for item in items:
+ attribute = attr_cls.parse(item)
+ if by_name:
+ # Filter out all instances without a matching FQDD
+ if fqdd_filter is None or fqdd_filter == attribute.fqdd:
+ if name_formatter is None:
+ name = attribute.name
+ else:
+ name = name_formatter(attribute)
+
+ result[name] = attribute
+ else:
+ result[attribute.instance_id] = attribute
+
+ return result
+
+
+def set_settings(settings_type,
+ client,
+ namespaces,
+ new_settings,
+ resource_uri,
+ cim_creation_class_name,
+ cim_name,
+ target,
+ name_formatter=None,
+ wait_for_idrac=True,
+ by_name=True):
+ """Generically handles setting various types of settings on the iDRAC
+
+ This method pulls the current list of settings from the iDRAC then compares
+ that list against the passed new settings to determine if there are any
+ errors. If no errors exist then the settings are sent to the iDRAC using
+ the passed resource, target, etc.
+
+ :param settings_type: a string indicating the settings type
+ :param client: an instance of WSManClient
+ :param namespaces: a list of URI/class pairs to retrieve.
+ :param new_settings: a dictionary containing the proposed values, with
+ each key being the name of attribute and the
+ value being the proposed value.
+ :param resource_uri: URI of resource to invoke
+ :param cim_creation_class_name: creation class name of the CIM object
+ :param cim_name: name of the CIM object
+ :param target: target device
+ :param name_formatter: a method used to format the keys in the
+ returned dictionary. By default,
+ attribute.name will be used.
+ :param wait_for_idrac: indicates whether or not to wait for the
+ iDRAC to be ready to accept commands before issuing
+ the command
+ :param by_name: Controls whether returned dictionary uses RAID
+ attribute name or instance_id as key.
+ :returns: a dictionary containing:
+ - The is_commit_required key with a boolean value indicating
+ whether a config job must be created for the values to be
+ applied.
+ - The is_reboot_required key with a RebootRequired enumerated
+ value indicating whether the server must be rebooted for the
+ values to be applied. Possible values are true and false.
+ :raises: WSManRequestFailure on request failures
+ :raises: WSManInvalidResponse when receiving invalid response
+ :raises: DRACOperationFailed on new settings with invalid values or
+ attempting to set read-only settings or when an error is reported
+ back by the iDRAC interface
+ :raises: DRACUnexpectedReturnValue on return value mismatch
+ :raises: InvalidParameterValue on invalid new setting
+ """
+ current_settings = list_settings(client, namespaces, by_name=by_name,
+ name_formatter=name_formatter,
+ wait_for_idrac=wait_for_idrac)
+
+ unknown_keys = set(new_settings) - set(current_settings)
+ if unknown_keys:
+ msg = ('Unknown %(settings_type)s attributes found: %(unknown_keys)r' %
+ {'settings_type': settings_type, 'unknown_keys': unknown_keys})
+ raise exceptions.InvalidParameterValue(reason=msg)
+
+ read_only_keys = []
+ unchanged_attribs = []
+ invalid_attribs_msgs = []
+ attrib_names = []
+ candidates = set(new_settings)
+
+ for attr in candidates:
+ # There are RAID settings that can have multiple values,
+ # however these are all read-only attributes.
+ # Filter out all read-only attributes first so that we exclude
+ # these settings from further consideration
+ current_setting_value = current_settings[attr].current_value
+ if type(current_setting_value) is list:
+ current_setting_value = current_setting_value[0]
+
+ unchanged_attribute = str(new_settings[attr]) == str(
+ current_setting_value)
+
+ # check if read-only attribute is unchanged
+ if current_settings[attr].read_only and not unchanged_attribute:
+ read_only_keys.append(attr)
+
+ if unchanged_attribute:
+ unchanged_attribs.append(attr)
+ else:
+ validation_msg = current_settings[attr].validate(
+ new_settings[attr])
+ if not validation_msg:
+ attrib_names.append(attr)
+ else:
+ invalid_attribs_msgs.append(validation_msg)
+
+ if unchanged_attribs:
+ LOG.debug('Ignoring unchanged %(settings_type)s attributes: '
+ '%(unchanged_attribs)r' %
+ {'settings_type': settings_type,
+ 'unchanged_attribs': unchanged_attribs})
+
+ if invalid_attribs_msgs or read_only_keys:
+ if read_only_keys:
+ read_only_msg = ['Cannot set read-only %(settings_type)s '
+ 'attributes: %(read_only_keys)r.' %
+ {'settings_type': settings_type,
+ 'read_only_keys': read_only_keys}]
+ else:
+ read_only_msg = []
+
+ drac_messages = '\n'.join(invalid_attribs_msgs + read_only_msg)
+ raise exceptions.DRACOperationFailed(
+ drac_messages=drac_messages)
+
+ if not attrib_names:
+ return build_return_dict(
+ None,
+ resource_uri,
+ is_commit_required_value=False,
+ is_reboot_required_value=constants.RebootRequired.false)
+
+ selectors = {'CreationClassName': cim_creation_class_name,
+ 'Name': cim_name,
+ 'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'SystemName': 'DCIM:ComputerSystem'}
+
+ properties = {'Target': target,
+ 'AttributeValue': [new_settings[attr] for attr
+ in attrib_names]}
+ # To set RAID settings, above we fetched list raid settings using
+ # instance_id to retrieve attribute values. When we pass instance_id in
+ # setattribute method for setting any new RAID settings, wsman raises
+ # an error. So another approach to set those settings is to list raid
+ # settings using instance_id and for settings new settings, pass the
+ # attribute names in list to SetAttributes method along with the target.
+ # That's the reason, we need to handle RAID specific settings like below
+ if settings_type == 'RAID':
+ properties['AttributeName'] = [current_settings[attr].name for
+ attr in attrib_names]
+ else:
+ properties['AttributeName'] = attrib_names
+ doc = client.invoke(resource_uri, 'SetAttributes',
+ selectors, properties,
+ wait_for_idrac=wait_for_idrac)
+
+ return build_return_dict(doc, resource_uri)
diff --git a/dracclient/wsman.py b/dracclient/wsman.py
index 737df72..55cf548 100644
--- a/dracclient/wsman.py
+++ b/dracclient/wsman.py
@@ -12,12 +12,15 @@
# under the License.
import logging
+import re
+import six
+import time
import uuid
from lxml import etree as ElementTree
-import requests
import requests.exceptions
+from dracclient import constants
from dracclient import exceptions
LOG = logging.getLogger(__name__)
@@ -41,13 +44,31 @@ class Client(object):
"""Simple client for talking over WSMan protocol."""
def __init__(self, host, username, password, port=443, path='/wsman',
- protocol='https'):
+ protocol='https',
+ ssl_retries=constants.DEFAULT_WSMAN_SSL_ERROR_RETRIES,
+ ssl_retry_delay=(
+ constants.DEFAULT_WSMAN_SSL_ERROR_RETRY_DELAY_SEC)):
+ """Creates client object
+
+ :param host: hostname or IP of the DRAC interface
+ :param username: username for accessing the DRAC interface
+ :param password: password for accessing the DRAC interface
+ :param port: port for accessing the DRAC interface
+ :param path: path for accessing the DRAC interface
+ :param protocol: protocol for accessing the DRAC interface
+ :param ssl_retries: number of resends to attempt on SSL failures
+ :param ssl_retry_delay: number of seconds to wait between
+ retries on SSL failures
+ """
+
self.host = host
self.username = username
self.password = password
self.port = port
self.path = path
self.protocol = protocol
+ self.ssl_retries = ssl_retries
+ self.ssl_retry_delay = ssl_retry_delay
self.endpoint = ('%(protocol)s://%(host)s:%(port)s%(path)s' % {
'protocol': self.protocol,
'host': self.host,
@@ -58,16 +79,52 @@ def _do_request(self, payload):
payload = payload.build()
LOG.debug('Sending request to %(endpoint)s: %(payload)s',
{'endpoint': self.endpoint, 'payload': payload})
- try:
- resp = requests.post(
- self.endpoint,
- auth=requests.auth.HTTPBasicAuth(self.username, self.password),
- data=payload,
- # TODO(ifarkas): enable cert verification
- verify=False)
- except requests.exceptions.RequestException:
- LOG.exception('Request failed')
- raise exceptions.WSManRequestFailure()
+
+ num_tries = 1
+ while num_tries <= self.ssl_retries:
+ try:
+ resp = requests.post(
+ self.endpoint,
+ auth=requests.auth.HTTPBasicAuth(self.username,
+ self.password),
+ data=payload,
+ # TODO(ifarkas): enable cert verification
+ verify=False)
+ break
+ except (requests.exceptions.ConnectionError,
+ requests.exceptions.SSLError) as ex:
+
+ error_msg = "A {error_type} error occurred while " \
+ " communicating with {host}, attempt {num_tries} of " \
+ "{retries}".format(
+ error_type=type(ex).__name__,
+ host=self.host,
+ num_tries=num_tries,
+ retries=self.ssl_retries)
+
+ if num_tries == self.ssl_retries:
+ LOG.error(error_msg)
+ raise exceptions.WSManRequestFailure(
+ "A {error_type} error occurred while communicating "
+ "with {host}: {error}".format(
+ error_type=type(ex).__name__,
+ host=self.host,
+ error=ex))
+ else:
+ LOG.warning(error_msg)
+
+ num_tries += 1
+ if self.ssl_retry_delay > 0 and num_tries <= self.ssl_retries:
+ time.sleep(self.ssl_retry_delay)
+
+ except requests.exceptions.RequestException as ex:
+ error_msg = "A {error_type} error occurred while " \
+ "communicating with {host}: {error}".format(
+ error_type=type(ex).__name__,
+ host=self.host,
+ error=ex)
+ LOG.error(error_msg)
+ raise exceptions.WSManRequestFailure(error_msg)
LOG.debug('Received response from %(endpoint)s: %(payload)s',
{'endpoint': self.endpoint, 'payload': resp.content})
@@ -102,24 +159,36 @@ def enumerate(self, resource_uri, optimization=True, max_elems=100,
filter_query, filter_dialect)
resp = self._do_request(payload)
- resp_xml = ElementTree.fromstring(resp.content)
+ try:
+ resp_xml = ElementTree.fromstring(resp.content)
+ except ElementTree.XMLSyntaxError:
+ LOG.warning('Received invalid content from iDRAC. Filtering out '
+ 'unprintable characters: ' + repr(resp.content))
+
+ # Filter out everything except for printable ASCII characters and
+ # tab
+ resp_xml = ElementTree.fromstring(re.sub(six.b('[^\x20-\x7e\t]'),
+ six.b(''),
+ resp.content))
if auto_pull:
- find_items_query = './/{%s}Items' % NS_WSMAN_ENUM
+ # The first response returns ""
+ find_items_wsman_query = './/{%s}Items' % NS_WSMAN
+
+ # Successive pulls return ""
+ find_items_enum_query = './/{%s}Items' % NS_WSMAN_ENUM
+
full_resp_xml = resp_xml
+ items_xml = full_resp_xml.find(find_items_wsman_query)
context = self._enum_context(full_resp_xml)
while context is not None:
resp_xml = self.pull(resource_uri, context, max_elems)
context = self._enum_context(resp_xml)
- items_xml = full_resp_xml.find(find_items_query)
- if items_xml is not None:
- # merge enumeration items
- for item in resp_xml.find(find_items_query):
- items_xml.append(item)
- else:
- full_resp_xml = resp_xml
+ # Merge in next batch of enumeration items
+ for item in resp_xml.find(find_items_enum_query):
+ items_xml.append(item)
# remove enumeration context because items are already merged
enum_context_elem = full_resp_xml.find('.//{%s}EnumerationContext'
diff --git a/setup.cfg b/setup.cfg
index 1b0414d..94d0507 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -3,7 +3,7 @@ name = python-dracclient
summary = Library for managing machines with Dell iDRAC cards
description-file = README.rst
maintainer = DracClient Team
-maintainer_email = openstack-dev@lists.openstack.org
+author-email = openstack-discuss@lists.openstack.org
home-page = https://launchpad.net/python-dracclient
license = Apache-2
classifier =
@@ -12,11 +12,10 @@ classifier =
License :: OSI Approved :: Apache Software License
Operating System :: POSIX
Programming Language :: Python
- Programming Language :: Python :: 2
- Programming Language :: Python :: 2.7
Programming Language :: Python :: 3
- Programming Language :: Python :: 3.4
- Programming Language :: Python :: 3.5
+ Programming Language :: Python :: 3.6
+ Programming Language :: Python :: 3.7
+ Programming Language :: Python :: 3.8
[files]
packages =
diff --git a/test-requirements.txt b/test-requirements.txt
index 89121f4..d87015c 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -4,8 +4,5 @@
coverage>=3.6
doc8
-hacking>=0.11.0,<0.12
-mock>=2.0
+hacking>=1.1.0,<1.2.0 # Apache-2.0
requests-mock>=1.0
-sphinx>=1.2.1,!=1.3b1,<1.3
-oslosphinx>=2.5.0,!=3.4.0
diff --git a/tox.ini b/tox.ini
index 135f431..552504e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,12 +1,15 @@
[tox]
-envlist = py35,py34,pep8,py27
+minversion = 3.1.0
+envlist = py38,py36,pep8
+ignore_basepython_conflict=true
[testenv]
usedevelop = True
-install_command = pip install -U -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages}
+install_command = pip install -U -c{env:UPPER_CONSTRAINTS_FILE:https://opendev.org/openstack/requirements/raw/branch/master/upper-constraints.txt} {opts} {packages}
deps =
-r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
+basepython = python3
setenv = PYTHONDONTWRITEBYTECODE=1
commands =
coverage run --branch --source dracclient --omit "dracclient/tests*" -m unittest discover dracclient.tests
@@ -16,13 +19,17 @@ commands =
commands = {posargs}
[testenv:pep8]
-basepython = python2.7
commands =
flake8 dracclient
doc8 README.rst CONTRIBUTING.rst doc/source
[testenv:docs]
-commands = python setup.py build_sphinx
+deps =
+ -c{env:UPPER_CONSTRAINTS_FILE:https://opendev.org/openstack/requirements/raw/branch/master/upper-constraints.txt}
+ -r{toxinidir}/requirements.txt
+ -r{toxinidir}/doc/requirements.txt
+commands =
+ sphinx-build -b html doc/source doc/build/html
[flake8]
max-complexity=15
diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml
new file mode 100644
index 0000000..cab1fe4
--- /dev/null
+++ b/zuul.d/project.yaml
@@ -0,0 +1,3 @@
+- project:
+ templates:
+ - openstack-python3-victoria-jobs