Merge "Add ability to schedule jobs"
This commit is contained in:
commit
e68dacb1d6
|
@ -244,11 +244,17 @@ class DRACClient(object):
|
||||||
def commit_pending_idrac_changes(
|
def commit_pending_idrac_changes(
|
||||||
self,
|
self,
|
||||||
idrac_fqdd=IDRAC_FQDD,
|
idrac_fqdd=IDRAC_FQDD,
|
||||||
reboot=False):
|
reboot=False,
|
||||||
"""Creates a config job for applying all pending changes to an iDRAC
|
start_time='TIME_NOW'):
|
||||||
|
"""Create a config job for applying all pending iDRAC changes.
|
||||||
|
|
||||||
:param idrac_fqdd: the FQDD of the iDRAC.
|
:param idrac_fqdd: the FQDD of the iDRAC.
|
||||||
:param reboot: indication of whether to also create a reboot job
|
: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
|
:returns: id of the created configuration job
|
||||||
:raises: WSManRequestFailure on request failures
|
:raises: WSManRequestFailure on request failures
|
||||||
:raises: WSManInvalidResponse when receiving invalid response
|
:raises: WSManInvalidResponse when receiving invalid response
|
||||||
|
@ -261,7 +267,8 @@ class DRACClient(object):
|
||||||
cim_creation_class_name='DCIM_iDRACCardService',
|
cim_creation_class_name='DCIM_iDRACCardService',
|
||||||
cim_name='DCIM:iDRACCardService',
|
cim_name='DCIM:iDRACCardService',
|
||||||
target=idrac_fqdd,
|
target=idrac_fqdd,
|
||||||
reboot=reboot)
|
reboot=reboot,
|
||||||
|
start_time=start_time)
|
||||||
|
|
||||||
def abandon_pending_idrac_changes(self, idrac_fqdd=IDRAC_FQDD):
|
def abandon_pending_idrac_changes(self, idrac_fqdd=IDRAC_FQDD):
|
||||||
"""Abandon all pending changes to an iDRAC
|
"""Abandon all pending changes to an iDRAC
|
||||||
|
@ -332,12 +339,16 @@ class DRACClient(object):
|
||||||
"""
|
"""
|
||||||
return self._job_mgmt.get_job(job_id)
|
return self._job_mgmt.get_job(job_id)
|
||||||
|
|
||||||
def create_config_job(self, resource_uri, cim_creation_class_name,
|
def create_config_job(self,
|
||||||
cim_name, target,
|
resource_uri,
|
||||||
|
cim_creation_class_name,
|
||||||
|
cim_name,
|
||||||
|
target,
|
||||||
cim_system_creation_class_name='DCIM_ComputerSystem',
|
cim_system_creation_class_name='DCIM_ComputerSystem',
|
||||||
cim_system_name='DCIM:ComputerSystem',
|
cim_system_name='DCIM:ComputerSystem',
|
||||||
reboot=False):
|
reboot=False,
|
||||||
"""Creates a config job
|
start_time='TIME_NOW'):
|
||||||
|
"""Creates a configuration job.
|
||||||
|
|
||||||
In CIM (Common Information Model), weak association is used to name an
|
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.
|
instance of one class in the context of an instance of another class.
|
||||||
|
@ -353,18 +364,62 @@ class DRACClient(object):
|
||||||
:param cim_system_creation_class_name: creation class name of the
|
:param cim_system_creation_class_name: creation class name of the
|
||||||
scoping system
|
scoping system
|
||||||
:param cim_system_name: name of the scoping system
|
:param cim_system_name: name of the scoping system
|
||||||
:param reboot: indicates whether a RebootJob should also be
|
:param reboot: indicates whether or not a RebootJob should also be
|
||||||
created or not
|
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
|
||||||
:returns: id of the created job
|
:returns: id of the created job
|
||||||
:raises: WSManRequestFailure on request failures
|
:raises: WSManRequestFailure on request failures
|
||||||
:raises: WSManInvalidResponse when receiving invalid response
|
: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
|
interface
|
||||||
:raises: DRACUnexpectedReturnValue on return value mismatch
|
:raises: DRACUnexpectedReturnValue on return value mismatch
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return self._job_mgmt.create_config_job(
|
return self._job_mgmt.create_config_job(
|
||||||
resource_uri, cim_creation_class_name, cim_name, target,
|
resource_uri=resource_uri,
|
||||||
cim_system_creation_class_name, cim_system_name, reboot)
|
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)
|
||||||
|
|
||||||
|
def create_reboot_job(self,
|
||||||
|
reboot_type='graceful_reboot_with_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(
|
def delete_pending_config(
|
||||||
self, resource_uri, cim_creation_class_name, cim_name, target,
|
self, resource_uri, cim_creation_class_name, cim_name, target,
|
||||||
|
@ -398,23 +453,34 @@ class DRACClient(object):
|
||||||
resource_uri, cim_creation_class_name, cim_name, target,
|
resource_uri, cim_creation_class_name, cim_name, target,
|
||||||
cim_system_creation_class_name, cim_system_name)
|
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
|
"""Applies all pending changes on the BIOS by creating a config job
|
||||||
|
|
||||||
:param reboot: indicates whether a RebootJob should also be
|
:param reboot: indicates whether a RebootJob should also be
|
||||||
created or not
|
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
|
:returns: id of the created job
|
||||||
:raises: WSManRequestFailure on request failures
|
:raises: WSManRequestFailure on request failures
|
||||||
:raises: WSManInvalidResponse when receiving invalid response
|
:raises: WSManInvalidResponse when receiving invalid response
|
||||||
:raises: DRACOperationFailed on error reported back by the DRAC
|
: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
|
:raises: DRACUnexpectedReturnValue on return value mismatch
|
||||||
"""
|
"""
|
||||||
return self._job_mgmt.create_config_job(
|
return self._job_mgmt.create_config_job(
|
||||||
resource_uri=uris.DCIM_BIOSService,
|
resource_uri=uris.DCIM_BIOSService,
|
||||||
cim_creation_class_name='DCIM_BIOSService',
|
cim_creation_class_name='DCIM_BIOSService',
|
||||||
cim_name='DCIM:BIOSService', target=self.BIOS_DEVICE_FQDD,
|
cim_name='DCIM:BIOSService',
|
||||||
reboot=reboot)
|
target=self.BIOS_DEVICE_FQDD,
|
||||||
|
reboot=reboot,
|
||||||
|
start_time=start_time)
|
||||||
|
|
||||||
def abandon_pending_bios_changes(self):
|
def abandon_pending_bios_changes(self):
|
||||||
"""Deletes all pending changes on the BIOS
|
"""Deletes all pending changes on the BIOS
|
||||||
|
@ -569,7 +635,8 @@ class DRACClient(object):
|
||||||
"""
|
"""
|
||||||
return self._raid_mgmt.delete_virtual_disk(virtual_disk)
|
return self._raid_mgmt.delete_virtual_disk(virtual_disk)
|
||||||
|
|
||||||
def commit_pending_raid_changes(self, raid_controller, reboot=False):
|
def commit_pending_raid_changes(self, raid_controller, reboot=False,
|
||||||
|
start_time='TIME_NOW'):
|
||||||
"""Applies all pending changes on a RAID controller
|
"""Applies all pending changes on a RAID controller
|
||||||
|
|
||||||
...by creating a config job.
|
...by creating a config job.
|
||||||
|
@ -577,6 +644,11 @@ class DRACClient(object):
|
||||||
:param raid_controller: id of the RAID controller
|
:param raid_controller: id of the RAID controller
|
||||||
:param reboot: indicates whether a RebootJob should also be
|
:param reboot: indicates whether a RebootJob should also be
|
||||||
created or not
|
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
|
:returns: id of the created job
|
||||||
:raises: WSManRequestFailure on request failures
|
:raises: WSManRequestFailure on request failures
|
||||||
:raises: WSManInvalidResponse when receiving invalid response
|
:raises: WSManInvalidResponse when receiving invalid response
|
||||||
|
@ -587,7 +659,10 @@ class DRACClient(object):
|
||||||
return self._job_mgmt.create_config_job(
|
return self._job_mgmt.create_config_job(
|
||||||
resource_uri=uris.DCIM_RAIDService,
|
resource_uri=uris.DCIM_RAIDService,
|
||||||
cim_creation_class_name='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)
|
||||||
|
|
||||||
def abandon_pending_raid_changes(self, raid_controller):
|
def abandon_pending_raid_changes(self, raid_controller):
|
||||||
"""Deletes all pending changes on a RAID controller
|
"""Deletes all pending changes on a RAID controller
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
import collections
|
import collections
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
import dracclient.exceptions as exceptions
|
||||||
from dracclient.resources import uris
|
from dracclient.resources import uris
|
||||||
from dracclient import utils
|
from dracclient import utils
|
||||||
from dracclient import wsman
|
from dracclient import wsman
|
||||||
|
@ -25,6 +26,12 @@ JobTuple = collections.namedtuple(
|
||||||
['id', 'name', 'start_time', 'until_time', 'message', 'status',
|
['id', 'name', 'start_time', 'until_time', 'message', 'status',
|
||||||
'percent_complete'])
|
'percent_complete'])
|
||||||
|
|
||||||
|
REBOOT_TYPES = {
|
||||||
|
'power_cycle': '1',
|
||||||
|
'graceful_reboot_without_forced_shutdown': '2',
|
||||||
|
'graceful_reboot_with_forced_shutdown': '3',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Job(JobTuple):
|
class Job(JobTuple):
|
||||||
|
|
||||||
|
@ -108,7 +115,8 @@ class JobManagement(object):
|
||||||
cim_name, target,
|
cim_name, target,
|
||||||
cim_system_creation_class_name='DCIM_ComputerSystem',
|
cim_system_creation_class_name='DCIM_ComputerSystem',
|
||||||
cim_system_name='DCIM:ComputerSystem',
|
cim_system_name='DCIM:ComputerSystem',
|
||||||
reboot=False):
|
reboot=False,
|
||||||
|
start_time='TIME_NOW'):
|
||||||
"""Creates a config job
|
"""Creates a config job
|
||||||
|
|
||||||
In CIM (Common Information Model), weak association is used to name an
|
In CIM (Common Information Model), weak association is used to name an
|
||||||
|
@ -127,6 +135,12 @@ class JobManagement(object):
|
||||||
:param cim_system_name: 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
|
:param reboot: indicates whether a RebootJob should also be created or
|
||||||
not
|
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.
|
||||||
:returns: id of the created job
|
:returns: id of the created job
|
||||||
:raises: WSManRequestFailure on request failures
|
:raises: WSManRequestFailure on request failures
|
||||||
:raises: WSManInvalidResponse when receiving invalid response
|
:raises: WSManInvalidResponse when receiving invalid response
|
||||||
|
@ -140,21 +154,98 @@ class JobManagement(object):
|
||||||
'CreationClassName': cim_creation_class_name,
|
'CreationClassName': cim_creation_class_name,
|
||||||
'Name': cim_name}
|
'Name': cim_name}
|
||||||
|
|
||||||
properties = {'Target': target,
|
properties = {'Target': target}
|
||||||
'ScheduledStartTime': 'TIME_NOW'}
|
|
||||||
|
|
||||||
if reboot:
|
if reboot:
|
||||||
properties['RebootJobType'] = '3'
|
properties['RebootJobType'] = '3'
|
||||||
|
|
||||||
|
if start_time is not None:
|
||||||
|
properties['ScheduledStartTime'] = start_time
|
||||||
|
|
||||||
doc = self.client.invoke(resource_uri, 'CreateTargetedConfigJob',
|
doc = self.client.invoke(resource_uri, 'CreateTargetedConfigJob',
|
||||||
selectors, properties,
|
selectors, properties,
|
||||||
expected_return_value=utils.RET_CREATED)
|
expected_return_value=utils.RET_CREATED)
|
||||||
|
|
||||||
query = ('.//{%(namespace)s}%(item)s[@%(attribute_name)s='
|
return self._get_job_id(doc)
|
||||||
'"%(attribute_value)s"]' %
|
|
||||||
{'namespace': wsman.NS_WSMAN, 'item': 'Selector',
|
def create_reboot_job(self,
|
||||||
'attribute_name': 'Name',
|
reboot_type='graceful_reboot_with_forced_shutdown'):
|
||||||
'attribute_value': 'InstanceID'})
|
"""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)
|
||||||
|
|
||||||
|
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
|
job_id = doc.find(query).text
|
||||||
return job_id
|
return job_id
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,9 @@ DCIM_iDRACCardService = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
|
||||||
DCIM_iDRACCardString = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
|
DCIM_iDRACCardString = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
|
||||||
'DCIM_iDRACCardString')
|
'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 = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
|
||||||
'DCIM_LCEnumeration')
|
'DCIM_LCEnumeration')
|
||||||
|
|
||||||
|
|
|
@ -484,7 +484,8 @@ class ClientBIOSChangesTestCase(base.BaseTest):
|
||||||
mock_create_config_job.assert_called_once_with(
|
mock_create_config_job.assert_called_once_with(
|
||||||
mock.ANY, resource_uri=uris.DCIM_BIOSService,
|
mock.ANY, resource_uri=uris.DCIM_BIOSService,
|
||||||
cim_creation_class_name='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,
|
@mock.patch.object(dracclient.resources.job.JobManagement,
|
||||||
'create_config_job', spec_set=True, autospec=True)
|
'create_config_job', spec_set=True, autospec=True)
|
||||||
|
@ -495,7 +496,38 @@ class ClientBIOSChangesTestCase(base.BaseTest):
|
||||||
mock_create_config_job.assert_called_once_with(
|
mock_create_config_job.assert_called_once_with(
|
||||||
mock.ANY, resource_uri=uris.DCIM_BIOSService,
|
mock.ANY, resource_uri=uris.DCIM_BIOSService,
|
||||||
cim_creation_class_name='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,
|
@mock.patch.object(dracclient.resources.job.JobManagement,
|
||||||
'delete_pending_config', spec_set=True, autospec=True)
|
'delete_pending_config', spec_set=True, autospec=True)
|
||||||
|
|
|
@ -283,7 +283,7 @@ class ClientiDRACCardChangesTestCase(base.BaseTest):
|
||||||
cim_creation_class_name='DCIM_iDRACCardService',
|
cim_creation_class_name='DCIM_iDRACCardService',
|
||||||
cim_name='DCIM:iDRACCardService',
|
cim_name='DCIM:iDRACCardService',
|
||||||
target=dracclient.client.DRACClient.IDRAC_FQDD,
|
target=dracclient.client.DRACClient.IDRAC_FQDD,
|
||||||
reboot=False)
|
reboot=False, start_time='TIME_NOW')
|
||||||
|
|
||||||
@mock.patch.object(job.JobManagement, 'create_config_job', spec_set=True,
|
@mock.patch.object(job.JobManagement, 'create_config_job', spec_set=True,
|
||||||
autospec=True)
|
autospec=True)
|
||||||
|
@ -299,7 +299,41 @@ class ClientiDRACCardChangesTestCase(base.BaseTest):
|
||||||
cim_creation_class_name='DCIM_iDRACCardService',
|
cim_creation_class_name='DCIM_iDRACCardService',
|
||||||
cim_name='DCIM:iDRACCardService',
|
cim_name='DCIM:iDRACCardService',
|
||||||
target=dracclient.client.DRACClient.IDRAC_FQDD,
|
target=dracclient.client.DRACClient.IDRAC_FQDD,
|
||||||
reboot=True)
|
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',
|
@mock.patch.object(job.JobManagement, 'delete_pending_config',
|
||||||
spec_set=True, autospec=True)
|
spec_set=True, autospec=True)
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import datetime
|
||||||
import lxml.etree
|
import lxml.etree
|
||||||
import mock
|
import mock
|
||||||
import requests_mock
|
import requests_mock
|
||||||
|
@ -127,6 +128,59 @@ class ClientJobManagementTestCase(base.BaseTest):
|
||||||
expected_return_value=utils.RET_CREATED)
|
expected_return_value=utils.RET_CREATED)
|
||||||
self.assertEqual('JID_442507917525', job_id)
|
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"
|
||||||
|
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)
|
||||||
|
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
|
||||||
|
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)
|
||||||
|
self.assertEqual('JID_442507917525', job_id)
|
||||||
|
|
||||||
@requests_mock.Mocker()
|
@requests_mock.Mocker()
|
||||||
@mock.patch.object(dracclient.client.WSManClient,
|
@mock.patch.object(dracclient.client.WSManClient,
|
||||||
'wait_until_idrac_is_ready', spec_set=True,
|
'wait_until_idrac_is_ready', spec_set=True,
|
||||||
|
@ -172,6 +226,27 @@ class ClientJobManagementTestCase(base.BaseTest):
|
||||||
expected_return_value=utils.RET_CREATED)
|
expected_return_value=utils.RET_CREATED)
|
||||||
self.assertEqual('JID_442507917525', job_id)
|
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,
|
@mock.patch.object(dracclient.client.WSManClient, 'invoke', spec_set=True,
|
||||||
autospec=True)
|
autospec=True)
|
||||||
def test_delete_pending_config(self, mock_invoke):
|
def test_delete_pending_config(self, mock_invoke):
|
||||||
|
@ -213,3 +288,75 @@ class ClientJobManagementTestCase(base.BaseTest):
|
||||||
exceptions.DRACOperationFailed,
|
exceptions.DRACOperationFailed,
|
||||||
self.drac_client.delete_pending_config, uris.DCIM_BIOSService,
|
self.drac_client.delete_pending_config, uris.DCIM_BIOSService,
|
||||||
cim_creation_class_name, cim_name, target)
|
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()
|
||||||
|
|
|
@ -525,7 +525,8 @@ class ClientRAIDManagementTestCase(base.BaseTest):
|
||||||
mock_create_config_job.assert_called_once_with(
|
mock_create_config_job.assert_called_once_with(
|
||||||
mock.ANY, resource_uri=uris.DCIM_RAIDService,
|
mock.ANY, resource_uri=uris.DCIM_RAIDService,
|
||||||
cim_creation_class_name='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')
|
||||||
|
|
||||||
@mock.patch.object(dracclient.resources.job.JobManagement,
|
@mock.patch.object(dracclient.resources.job.JobManagement,
|
||||||
'create_config_job', spec_set=True, autospec=True)
|
'create_config_job', spec_set=True, autospec=True)
|
||||||
|
@ -536,7 +537,39 @@ class ClientRAIDManagementTestCase(base.BaseTest):
|
||||||
mock_create_config_job.assert_called_once_with(
|
mock_create_config_job.assert_called_once_with(
|
||||||
mock.ANY, resource_uri=uris.DCIM_RAIDService,
|
mock.ANY, resource_uri=uris.DCIM_RAIDService,
|
||||||
cim_creation_class_name='DCIM_RAIDService',
|
cim_creation_class_name='DCIM_RAIDService',
|
||||||
cim_name='DCIM:RAIDService', target='controller', reboot=True)
|
cim_name='DCIM:RAIDService', target='controller', 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_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)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
@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)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
@mock.patch.object(dracclient.resources.job.JobManagement,
|
@mock.patch.object(dracclient.resources.job.JobManagement,
|
||||||
'delete_pending_config', spec_set=True, autospec=True)
|
'delete_pending_config', spec_set=True, autospec=True)
|
||||||
|
|
Loading…
Reference in New Issue