Add power management
Change-Id: Iab9d9f7e4e25e3d3fdec9b28fe49a7226e68c9ff
This commit is contained in:
parent
ef3d9a292e
commit
9153b850b2
116
dracclient/client.py
Normal file
116
dracclient/client.py
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Wrapper for pywsman.Client
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from dracclient import exceptions
|
||||||
|
from dracclient.resources import bios
|
||||||
|
from dracclient import utils
|
||||||
|
from dracclient import wsman
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class DRACClient(object):
|
||||||
|
"""Client for managing DRAC nodes"""
|
||||||
|
|
||||||
|
def __init__(self, host, username, password, port=443, path='/wsman',
|
||||||
|
protocol='https'):
|
||||||
|
"""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
|
||||||
|
"""
|
||||||
|
self.client = WSManClient(host, username, password, port, path,
|
||||||
|
protocol)
|
||||||
|
self._power_mgmt = bios.PowerManagement(self.client)
|
||||||
|
|
||||||
|
def get_power_state(self):
|
||||||
|
"""Returns the current power state of the node
|
||||||
|
|
||||||
|
:returns: power state of the node, one of 'POWER_ON', 'POWER_OFF' or
|
||||||
|
'REBOOT'
|
||||||
|
:raises: WSManRequestFailure on request failures
|
||||||
|
:raises: WSManInvalidResponse when receiving invalid response
|
||||||
|
:raises: DRACOperationFailed on error reported back by the DRAC
|
||||||
|
interface
|
||||||
|
"""
|
||||||
|
return self._power_mgmt.get_power_state()
|
||||||
|
|
||||||
|
def set_power_state(self, target_state):
|
||||||
|
"""Turns the server power on/off or do a reboot
|
||||||
|
|
||||||
|
:param target_state: target power state. Valid options are: 'POWER_ON',
|
||||||
|
'POWER_OFF' and 'REBOOT'.
|
||||||
|
: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 target power state
|
||||||
|
"""
|
||||||
|
self._power_mgmt.set_power_state(target_state)
|
||||||
|
|
||||||
|
|
||||||
|
class WSManClient(wsman.Client):
|
||||||
|
"""Wrapper for wsman.Client with return value checking"""
|
||||||
|
|
||||||
|
def invoke(self, resource_uri, method, selectors=None, properties=None,
|
||||||
|
expected_return_value=None):
|
||||||
|
"""Invokes a remote WS-Man method
|
||||||
|
|
||||||
|
:param resource_uri: URI of the resource
|
||||||
|
:param method: name of the method to invoke
|
||||||
|
:param selectors: dictionary of selectors
|
||||||
|
:param properties: dictionary of properties
|
||||||
|
:param expected_return_value: expected return value reported back by
|
||||||
|
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.
|
||||||
|
:returns: an lxml.etree.Element object of the response received
|
||||||
|
: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
|
||||||
|
"""
|
||||||
|
if selectors is None:
|
||||||
|
selectors = {}
|
||||||
|
|
||||||
|
if properties is None:
|
||||||
|
properties = {}
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
return resp
|
17
dracclient/constants.py
Normal file
17
dracclient/constants.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
# power states
|
||||||
|
POWER_ON = 'POWER_ON'
|
||||||
|
POWER_OFF = 'POWER_OFF'
|
||||||
|
REBOOT = 'REBOOT'
|
@ -21,8 +21,26 @@ class BaseClientException(Exception):
|
|||||||
super(BaseClientException, self).__init__(message)
|
super(BaseClientException, self).__init__(message)
|
||||||
|
|
||||||
|
|
||||||
|
class DRACRequestFailed(BaseClientException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DRACOperationFailed(DRACRequestFailed):
|
||||||
|
msg_fmt = ('DRAC operation failed. Messages: %(drac_messages)s')
|
||||||
|
|
||||||
|
|
||||||
|
class DRACUnexpectedReturnValue(DRACRequestFailed):
|
||||||
|
msg_fmt = ('DRAC operation yielded return value %(actual_return_value)s '
|
||||||
|
'that is neither error nor the expected '
|
||||||
|
'%(expected_return_value)s')
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidParameterValue(BaseClientException):
|
||||||
|
msg_fmt = '%(reason)s'
|
||||||
|
|
||||||
|
|
||||||
class WSManRequestFailure(BaseClientException):
|
class WSManRequestFailure(BaseClientException):
|
||||||
msg_fmt = ('WSMan request failed.')
|
msg_fmt = ('WSMan request failed')
|
||||||
|
|
||||||
|
|
||||||
class WSManInvalidResponse(BaseClientException):
|
class WSManInvalidResponse(BaseClientException):
|
||||||
|
0
dracclient/resources/__init__.py
Normal file
0
dracclient/resources/__init__.py
Normal file
84
dracclient/resources/bios.py
Normal file
84
dracclient/resources/bios.py
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
#
|
||||||
|
# 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 import constants
|
||||||
|
from dracclient import exceptions
|
||||||
|
from dracclient.resources import uris
|
||||||
|
from dracclient import utils
|
||||||
|
|
||||||
|
POWER_STATES = {
|
||||||
|
'2': constants.POWER_ON,
|
||||||
|
'3': constants.POWER_OFF,
|
||||||
|
'11': constants.REBOOT,
|
||||||
|
}
|
||||||
|
|
||||||
|
REVERSE_POWER_STATES = dict((v, k) for (k, v) in POWER_STATES.items())
|
||||||
|
|
||||||
|
|
||||||
|
class PowerManagement(object):
|
||||||
|
|
||||||
|
def __init__(self, client):
|
||||||
|
"""Creates PowerManagement object
|
||||||
|
|
||||||
|
:param client: an instance of WSManClient
|
||||||
|
"""
|
||||||
|
self.client = client
|
||||||
|
|
||||||
|
def get_power_state(self):
|
||||||
|
"""Returns the current power state of the node
|
||||||
|
|
||||||
|
:returns: power state of the node, one of 'POWER_ON', 'POWER_OFF' or
|
||||||
|
'REBOOT'
|
||||||
|
:raises: WSManRequestFailure on request failures
|
||||||
|
:raises: WSManInvalidResponse when receiving invalid response
|
||||||
|
:raises: DRACOperationFailed on error reported back by the DRAC
|
||||||
|
interface
|
||||||
|
"""
|
||||||
|
|
||||||
|
filter_query = ('select EnabledState from '
|
||||||
|
'DCIM_ComputerSystem where Name="srv:system"')
|
||||||
|
doc = self.client.enumerate(uris.DCIM_ComputerSystem,
|
||||||
|
filter_query=filter_query)
|
||||||
|
enabled_state = utils.find_xml(doc, 'EnabledState',
|
||||||
|
uris.DCIM_ComputerSystem)
|
||||||
|
|
||||||
|
return POWER_STATES[enabled_state.text]
|
||||||
|
|
||||||
|
def set_power_state(self, target_state):
|
||||||
|
"""Turns the server power on/off or do a reboot
|
||||||
|
|
||||||
|
:param target_state: target power state. Valid options are: 'POWER_ON',
|
||||||
|
'POWER_OFF' and 'REBOOT'.
|
||||||
|
: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 target power state
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
drac_requested_state = REVERSE_POWER_STATES[target_state]
|
||||||
|
except KeyError:
|
||||||
|
msg = ("'%(target_state)s' is not supported. "
|
||||||
|
"Supported power states: %(supported_power_states)r") % {
|
||||||
|
'target_state': target_state,
|
||||||
|
'supported_power_states': list(REVERSE_POWER_STATES)}
|
||||||
|
raise exceptions.InvalidParameterValue(reason=msg)
|
||||||
|
|
||||||
|
selectors = {'CreationClassName': 'DCIM_ComputerSystem',
|
||||||
|
'Name': 'srv:system'}
|
||||||
|
properties = {'RequestedState': drac_requested_state}
|
||||||
|
|
||||||
|
self.client.invoke(uris.DCIM_ComputerSystem, 'RequestStateChange',
|
||||||
|
selectors, properties)
|
44
dracclient/resources/uris.py
Normal file
44
dracclient/resources/uris.py
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Schema definitions and resource URIs for the classes implemented by the DRAC
|
||||||
|
WS-Man API.
|
||||||
|
"""
|
||||||
|
|
||||||
|
DCIM_BIOSEnumeration = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
|
||||||
|
'DCIM_BIOSEnumeration')
|
||||||
|
|
||||||
|
DCIM_BIOSInteger = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
|
||||||
|
'DCIM_BIOSInteger')
|
||||||
|
|
||||||
|
DCIM_BIOSService = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
|
||||||
|
'DCIM_BIOSService')
|
||||||
|
|
||||||
|
DCIM_BIOSString = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
|
||||||
|
'DCIM_BIOSString')
|
||||||
|
|
||||||
|
DCIM_BootConfigSetting = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
|
||||||
|
'DCIM_BootConfigSetting')
|
||||||
|
|
||||||
|
DCIM_BootSourceSetting = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
|
||||||
|
'DCIM_BootSourceSetting')
|
||||||
|
|
||||||
|
DCIM_ComputerSystem = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2'
|
||||||
|
'/DCIM_ComputerSystem')
|
||||||
|
|
||||||
|
DCIM_LifecycleJob = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
|
||||||
|
'DCIM_LifecycleJob')
|
||||||
|
|
||||||
|
DCIM_SystemView = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
|
||||||
|
'DCIM_SystemView')
|
123
dracclient/tests/test_client.py
Normal file
123
dracclient/tests/test_client.py
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
#
|
||||||
|
# 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 requests_mock
|
||||||
|
|
||||||
|
import dracclient.client
|
||||||
|
from dracclient import exceptions
|
||||||
|
from dracclient.resources import uris
|
||||||
|
from dracclient.tests import base
|
||||||
|
from dracclient.tests import utils as test_utils
|
||||||
|
|
||||||
|
|
||||||
|
@requests_mock.Mocker()
|
||||||
|
class ClientPowerManagementTestCase(base.BaseTest):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(ClientPowerManagementTestCase, self).setUp()
|
||||||
|
self.drac_client = dracclient.client.DRACClient(
|
||||||
|
**test_utils.FAKE_ENDPOINT)
|
||||||
|
|
||||||
|
def test_get_power_state(self, mock_requests):
|
||||||
|
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):
|
||||||
|
mock_requests.post(
|
||||||
|
'https://1.2.3.4:443/wsman',
|
||||||
|
text=test_utils.BIOSInvocations[
|
||||||
|
uris.DCIM_ComputerSystem]['RequestStateChange']['ok'])
|
||||||
|
|
||||||
|
self.assertIsNone(self.drac_client.set_power_state('POWER_ON'))
|
||||||
|
|
||||||
|
def test_set_power_state_fail(self, mock_requests):
|
||||||
|
mock_requests.post(
|
||||||
|
'https://1.2.3.4:443/wsman',
|
||||||
|
text=test_utils.BIOSInvocations[
|
||||||
|
uris.DCIM_ComputerSystem]['RequestStateChange']['error'])
|
||||||
|
|
||||||
|
self.assertRaises(exceptions.DRACOperationFailed,
|
||||||
|
self.drac_client.set_power_state, 'POWER_ON')
|
||||||
|
|
||||||
|
def test_set_power_state_invalid_target_state(self, mock_requests):
|
||||||
|
self.assertRaises(exceptions.InvalidParameterValue,
|
||||||
|
self.drac_client.set_power_state, 'foo')
|
||||||
|
|
||||||
|
|
||||||
|
@requests_mock.Mocker()
|
||||||
|
class WSManClientTestCase(base.BaseTest):
|
||||||
|
|
||||||
|
def test_enumerate(self, mock_requests):
|
||||||
|
mock_requests.post('https://1.2.3.4:443/wsman',
|
||||||
|
text='<result>yay!</result>')
|
||||||
|
|
||||||
|
client = dracclient.client.WSManClient(**test_utils.FAKE_ENDPOINT)
|
||||||
|
resp = client.enumerate('http://resource')
|
||||||
|
self.assertEqual('yay!', resp.text)
|
||||||
|
|
||||||
|
def test_invoke(self, mock_requests):
|
||||||
|
xml = """
|
||||||
|
<response xmlns:n1="http://resource">
|
||||||
|
<n1:ReturnValue>42</n1:ReturnValue>
|
||||||
|
<result>yay!</result>
|
||||||
|
</response>
|
||||||
|
""" # 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')
|
||||||
|
self.assertEqual('yay!', resp.find('result').text)
|
||||||
|
|
||||||
|
def test_invoke_with_expected_return_value(self, mock_requests):
|
||||||
|
xml = """
|
||||||
|
<response xmlns:n1="http://resource">
|
||||||
|
<n1:ReturnValue>42</n1:ReturnValue>
|
||||||
|
<result>yay!</result>
|
||||||
|
</response>
|
||||||
|
""" # 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',
|
||||||
|
expected_return_value='42')
|
||||||
|
self.assertEqual('yay!', resp.find('result').text)
|
||||||
|
|
||||||
|
def test_invoke_with_error_return_value(self, mock_requests):
|
||||||
|
xml = """
|
||||||
|
<response xmlns:n1="http://resource">
|
||||||
|
<n1:ReturnValue>2</n1:ReturnValue>
|
||||||
|
<result>yay!</result>
|
||||||
|
</response>
|
||||||
|
""" # noqa
|
||||||
|
mock_requests.post('https://1.2.3.4:443/wsman', text=xml)
|
||||||
|
|
||||||
|
client = dracclient.client.WSManClient(**test_utils.FAKE_ENDPOINT)
|
||||||
|
self.assertRaises(exceptions.DRACOperationFailed, client.invoke,
|
||||||
|
'http://resource', 'Foo')
|
||||||
|
|
||||||
|
def test_invoke_with_unexpected_return_value(self, mock_requests):
|
||||||
|
xml = """
|
||||||
|
<response xmlns:n1="http://resource">
|
||||||
|
<n1:ReturnValue>42</n1:ReturnValue>
|
||||||
|
<result>yay!</result>
|
||||||
|
</response>
|
||||||
|
""" # noqa
|
||||||
|
mock_requests.post('https://1.2.3.4:443/wsman', text=xml)
|
||||||
|
|
||||||
|
client = dracclient.client.WSManClient(**test_utils.FAKE_ENDPOINT)
|
||||||
|
self.assertRaises(exceptions.DRACUnexpectedReturnValue, client.invoke,
|
||||||
|
'http://resource', 'Foo',
|
||||||
|
expected_return_value='4242')
|
@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
from dracclient.resources import uris
|
||||||
|
|
||||||
FAKE_ENDPOINT = {
|
FAKE_ENDPOINT = {
|
||||||
'host': '1.2.3.4',
|
'host': '1.2.3.4',
|
||||||
'port': '443',
|
'port': '443',
|
||||||
@ -40,3 +42,20 @@ WSManEnumerations = {
|
|||||||
load_wsman_xml('wsman-enum_context-4'),
|
load_wsman_xml('wsman-enum_context-4'),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIOSEnumerations = {
|
||||||
|
uris.DCIM_ComputerSystem: {
|
||||||
|
'ok': load_wsman_xml('computer_system-enum-ok')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
BIOSInvocations = {
|
||||||
|
uris.DCIM_ComputerSystem: {
|
||||||
|
'RequestStateChange': {
|
||||||
|
'ok': load_wsman_xml(
|
||||||
|
'computer_system-invoke-request_state_change-ok'),
|
||||||
|
'error': load_wsman_xml(
|
||||||
|
'computer_system-invoke-request_state_change-error'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
23
dracclient/tests/wsman_mocks/computer_system-enum-ok.xml
Normal file
23
dracclient/tests/wsman_mocks/computer_system-enum-ok.xml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
|
||||||
|
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
|
||||||
|
xmlns:wsen="http://schemas.xmlsoap.org/ws/2004/09/enumeration"
|
||||||
|
xmlns:n1="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_ComputerSystem">
|
||||||
|
<s:Header>
|
||||||
|
<wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
|
||||||
|
<wsa:Action>http://schemas.xmlsoap.org/ws/2004/09/enumeration/PullResponse</wsa:Action>
|
||||||
|
<wsa:RelatesTo>uuid:2b1f3c28-1ca3-1ca3-8003-fd0aa2bdb228</wsa:RelatesTo>
|
||||||
|
<wsa:MessageID>uuid:5ba7c817-1ca7-1ca7-8a31-a36fc6fe83b0</wsa:MessageID>
|
||||||
|
</s:Header>
|
||||||
|
<s:Body>
|
||||||
|
<wsen:PullResponse>
|
||||||
|
<wsen:Items>
|
||||||
|
<n1:DCIM_ComputerSystem>
|
||||||
|
<n1:CreationClassName>DCIM_ComputerSystem</n1:CreationClassName>
|
||||||
|
<n1:EnabledState>2</n1:EnabledState>
|
||||||
|
<n1:Name>srv:system</n1:Name>
|
||||||
|
</n1:DCIM_ComputerSystem>
|
||||||
|
</wsen:Items>
|
||||||
|
<wsen:EndOfSequence/>
|
||||||
|
</wsen:PullResponse>
|
||||||
|
</s:Body>
|
||||||
|
</s:Envelope>
|
@ -0,0 +1,18 @@
|
|||||||
|
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
|
||||||
|
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
|
||||||
|
xmlns:n1="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_ComputerSystem">
|
||||||
|
<s:Header>
|
||||||
|
<wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
|
||||||
|
<wsa:Action>http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_ComputerSystem/RequestStateChangeResponse</wsa:Action>
|
||||||
|
<wsa:RelatesTo>uuid:0e1e69c7-1ca6-1ca6-8002-fd0aa2bdb228</wsa:RelatesTo>
|
||||||
|
<wsa:MessageID>uuid:3f2d0db0-1caa-1caa-8003-fcc71555dbe0</wsa:MessageID>
|
||||||
|
</s:Header>
|
||||||
|
<s:Body>
|
||||||
|
<n1:RequestStateChange_OUTPUT>
|
||||||
|
<n1:Message>The command failed to set RequestedState</n1:Message>
|
||||||
|
<n1:MessageArguments>RequestedState</n1:MessageArguments>
|
||||||
|
<n1:MessageID>SYS021</n1:MessageID>
|
||||||
|
<n1:ReturnValue>2</n1:ReturnValue>
|
||||||
|
</n1:RequestStateChange_OUTPUT>
|
||||||
|
</s:Body>
|
||||||
|
</s:Envelope>
|
@ -0,0 +1,15 @@
|
|||||||
|
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
|
||||||
|
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
|
||||||
|
xmlns:n1="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_ComputerSystem">
|
||||||
|
<s:Header>
|
||||||
|
<wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
|
||||||
|
<wsa:Action>http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_ComputerSystem/RequestStateChangeResponse</wsa:Action>
|
||||||
|
<wsa:RelatesTo>uuid:11302b44-1ca6-1ca6-8002-fd0aa2bdb228</wsa:RelatesTo>
|
||||||
|
<wsa:MessageID>uuid:4244f4ca-1caa-1caa-8004-fcc71555dbe0</wsa:MessageID>
|
||||||
|
</s:Header>
|
||||||
|
<s:Body>
|
||||||
|
<n1:RequestStateChange_OUTPUT>
|
||||||
|
<n1:ReturnValue>0</n1:ReturnValue>
|
||||||
|
</n1:RequestStateChange_OUTPUT>
|
||||||
|
</s:Body>
|
||||||
|
</s:Envelope>
|
42
dracclient/utils.py
Normal file
42
dracclient/utils.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Common functionalities shared between different DRAC modules.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# ReturnValue constants
|
||||||
|
RET_SUCCESS = '0'
|
||||||
|
RET_ERROR = '2'
|
||||||
|
RET_CREATED = '4096'
|
||||||
|
|
||||||
|
|
||||||
|
def find_xml(doc, item, namespace, find_all=False):
|
||||||
|
"""Find the first or all elements in an ElementTree object.
|
||||||
|
|
||||||
|
:param doc: the element tree object.
|
||||||
|
:param item: the element name.
|
||||||
|
:param namespace: the namespace of the element.
|
||||||
|
:param find_all: Boolean value, if True find all elements, if False
|
||||||
|
find only the first one. Defaults to False.
|
||||||
|
:returns: if find_all is False the element object will be returned
|
||||||
|
if found, None if not found. If find_all is True a list of
|
||||||
|
element objects will be returned or an empty list if no
|
||||||
|
elements were found.
|
||||||
|
|
||||||
|
"""
|
||||||
|
query = ('.//{%(namespace)s}%(item)s' % {'namespace': namespace,
|
||||||
|
'item': item})
|
||||||
|
if find_all:
|
||||||
|
return doc.findall(query)
|
||||||
|
return doc.find(query)
|
Loading…
Reference in New Issue
Block a user