Add CPU enumeration and InventoryManagement class

Change-Id: I1f65cc8b39b9e665ac2f7a48cdc4dc0193c81256
This commit is contained in:
Chris Coyle 2016-03-12 11:43:51 -05:00
parent e2dd764649
commit b61253ce92
6 changed files with 200 additions and 0 deletions

View File

@ -19,6 +19,7 @@ import logging
from dracclient import exceptions from dracclient import exceptions
from dracclient.resources import bios from dracclient.resources import bios
from dracclient.resources import inventory
from dracclient.resources import job from dracclient.resources import job
from dracclient.resources import lifecycle_controller from dracclient.resources import lifecycle_controller
from dracclient.resources import raid from dracclient.resources import raid
@ -52,6 +53,7 @@ class DRACClient(object):
self._boot_mgmt = bios.BootManagement(self.client) self._boot_mgmt = bios.BootManagement(self.client)
self._bios_cfg = bios.BIOSConfiguration(self.client) self._bios_cfg = bios.BIOSConfiguration(self.client)
self._raid_mgmt = raid.RAIDManagement(self.client) self._raid_mgmt = raid.RAIDManagement(self.client)
self._inventory_mgmt = inventory.InventoryManagement(self.client)
def get_power_state(self): def get_power_state(self):
"""Returns the current power state of the node """Returns the current power state of the node
@ -402,6 +404,17 @@ class DRACClient(object):
cim_creation_class_name='DCIM_RAIDService', cim_creation_class_name='DCIM_RAIDService',
cim_name='DCIM:RAIDService', target=raid_controller) cim_name='DCIM:RAIDService', target=raid_controller)
def list_cpus(self):
"""Returns the list of CPUs
:returns: a list of CPU objects
:raises: WSManRequestFailure on request failures
:raises: WSManInvalidResponse when receiving invalid response
:raises: DRACOperationFailed on error reported back by the DRAC
interface
"""
return self._inventory_mgmt.list_cpus()
class WSManClient(wsman.Client): class WSManClient(wsman.Client):
"""Wrapper for wsman.Client with return value checking""" """Wrapper for wsman.Client with return value checking"""

View File

@ -0,0 +1,73 @@
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import collections
from dracclient.resources import uris
from dracclient import utils
CPU = collections.namedtuple(
'CPU',
['id', 'cores', 'speed', 'ht_enabled', 'model', 'status', 'turbo_enabled',
'vt_enabled'])
PrimaryStatus = {
'0': 'Unknown',
'1': 'OK',
'2': 'Degraded',
'3': 'Error'
}
class InventoryManagement(object):
def __init__(self, client):
"""Creates InventoryManagement object
:param client: an instance of WSManClient
"""
self.client = client
def list_cpus(self):
"""Returns the list of CPUs
:returns: a list of CPU objects
:raises: WSManRequestFailure on request failures
:raises: WSManInvalidResponse when receiving invalid response
:raises: DRACOperationFailed on error reported back by the DRAC
"""
doc = self.client.enumerate(uris.DCIM_CPUView)
cpus = utils.find_xml(doc, 'DCIM_CPUView',
uris.DCIM_CPUView,
find_all=True)
return [self._parse_cpus(cpu) for cpu in cpus]
def _parse_cpus(self, cpu):
return CPU(
id=self._get_cpu_attr(cpu, 'FQDD'),
cores=int(self._get_cpu_attr(cpu, 'NumberOfProcessorCores')),
speed=int(self._get_cpu_attr(cpu, 'CurrentClockSpeed')),
ht_enabled=bool(self._get_cpu_attr(cpu, 'HyperThreadingEnabled')),
model=self._get_cpu_attr(cpu, 'Model'),
status=PrimaryStatus[self._get_cpu_attr(cpu, 'PrimaryStatus')],
turbo_enabled=bool(self._get_cpu_attr(cpu, 'TurboModeEnabled')),
vt_enabled=bool(self._get_cpu_attr(cpu,
'VirtualizationTechnologyEnabled'))
)
def _get_cpu_attr(self, cpu, attr_name):
return utils.get_wsman_resource_attr(
cpu, uris.DCIM_CPUView, attr_name)

View File

@ -40,6 +40,9 @@ DCIM_ComputerSystem = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2'
DCIM_ControllerView = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/' DCIM_ControllerView = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
'DCIM_ControllerView') 'DCIM_ControllerView')
DCIM_CPUView = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
'DCIM_CPUView')
DCIM_LifecycleJob = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/' DCIM_LifecycleJob = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/'
'DCIM_LifecycleJob') 'DCIM_LifecycleJob')

View File

@ -20,6 +20,7 @@ import requests_mock
import dracclient.client import dracclient.client
from dracclient import exceptions from dracclient import exceptions
from dracclient.resources import bios from dracclient.resources import bios
from dracclient.resources import inventory
import dracclient.resources.job import dracclient.resources.job
from dracclient.resources import lifecycle_controller from dracclient.resources import lifecycle_controller
from dracclient.resources import raid from dracclient.resources import raid
@ -952,3 +953,32 @@ class WSManClientTestCase(base.BaseTest):
self.assertRaises(exceptions.DRACUnexpectedReturnValue, client.invoke, self.assertRaises(exceptions.DRACUnexpectedReturnValue, client.invoke,
'http://resource', 'Foo', 'http://resource', 'Foo',
expected_return_value='4242') expected_return_value='4242')
@requests_mock.Mocker()
class ClientCPUTestCase(base.BaseTest):
def setUp(self):
super(ClientCPUTestCase, self).setUp()
self.drac_client = dracclient.client.DRACClient(
**test_utils.FAKE_ENDPOINT)
def test_list_cpus(self, mock_requests):
expected_cpu = [inventory.CPU(
id='CPU.Socket.1',
cores=6,
speed=2400,
ht_enabled=True,
model='Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz',
status='OK',
turbo_enabled=True,
vt_enabled=True
)]
mock_requests.post(
'https://1.2.3.4:443/wsman',
text=test_utils.CPUEnumerations[uris.DCIM_CPUView]['ok'])
self.assertEqual(
expected_cpu,
self.drac_client.list_cpus())

View File

@ -97,6 +97,12 @@ BIOSInvocations = {
} }
} }
CPUEnumerations = {
uris.DCIM_CPUView: {
'ok': load_wsman_xml('cpu-enumeration-enum-ok')
}
}
JobEnumerations = { JobEnumerations = {
uris.DCIM_LifecycleJob: { uris.DCIM_LifecycleJob: {
'ok': load_wsman_xml('lifecycle_job-enum-ok'), 'ok': load_wsman_xml('lifecycle_job-enum-ok'),

View File

@ -0,0 +1,75 @@
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:wsen="http://schemas.xmlsoap.org/ws/2004/09/enumeration"
xmlns:wsman="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"
xmlns:n1="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_CPUView">
<s:Header>
<wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
<wsa:Action>http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse</wsa:Action>
<wsa:RelatesTo>uuid:dd7ea19a-8633-4fa4-a43a-66ae8220f689</wsa:RelatesTo>
<wsa:MessageID>uuid:247e710c-29de-19de-93c9-f148d4fe83b0</wsa:MessageID>
</s:Header>
<s:Body>
<wsen:EnumerateResponse>
<wsman:Items>
<n1:DCIM_CPUView>
<n1:CPUFamily>B3</n1:CPUFamily>
<n1:CPUStatus>1</n1:CPUStatus>
<n1:Cache1Associativity>7</n1:Cache1Associativity>
<n1:Cache1ErrorMethodology>4</n1:Cache1ErrorMethodology>
<n1:Cache1Level>0</n1:Cache1Level>
<n1:Cache1Location>0</n1:Cache1Location>
<n1:Cache1PrimaryStatus>1</n1:Cache1PrimaryStatus>
<n1:Cache1SRAMType>2</n1:Cache1SRAMType>
<n1:Cache1Size>384</n1:Cache1Size>
<n1:Cache1Type>5</n1:Cache1Type>
<n1:Cache1WritePolicy>1</n1:Cache1WritePolicy>
<n1:Cache2Associativity>7</n1:Cache2Associativity>
<n1:Cache2ErrorMethodology>5</n1:Cache2ErrorMethodology>
<n1:Cache2Level>1</n1:Cache2Level>
<n1:Cache2Location>0</n1:Cache2Location>
<n1:Cache2PrimaryStatus>1</n1:Cache2PrimaryStatus>
<n1:Cache2SRAMType>2</n1:Cache2SRAMType>
<n1:Cache2Size>1536</n1:Cache2Size>
<n1:Cache2Type>5</n1:Cache2Type>
<n1:Cache2WritePolicy>1</n1:Cache2WritePolicy>
<n1:Cache3Associativity>14</n1:Cache3Associativity>
<n1:Cache3ErrorMethodology>5</n1:Cache3ErrorMethodology>
<n1:Cache3Level>2</n1:Cache3Level>
<n1:Cache3Location>0</n1:Cache3Location>
<n1:Cache3PrimaryStatus>1</n1:Cache3PrimaryStatus>
<n1:Cache3SRAMType>2</n1:Cache3SRAMType>
<n1:Cache3Size>15360</n1:Cache3Size>
<n1:Cache3Type>5</n1:Cache3Type>
<n1:Cache3WritePolicy>1</n1:Cache3WritePolicy>
<n1:Characteristics>4</n1:Characteristics>
<n1:CurrentClockSpeed>2400</n1:CurrentClockSpeed>
<n1:DeviceDescription>CPU 1</n1:DeviceDescription>
<n1:ExecuteDisabledCapable>0</n1:ExecuteDisabledCapable>
<n1:ExecuteDisabledEnabled>0</n1:ExecuteDisabledEnabled>
<n1:ExternalBusClockSpeed>6400</n1:ExternalBusClockSpeed>
<n1:FQDD>CPU.Socket.1</n1:FQDD>
<n1:HyperThreadingCapable>1</n1:HyperThreadingCapable>
<n1:HyperThreadingEnabled>1</n1:HyperThreadingEnabled>
<n1:InstanceID>CPU.Socket.1</n1:InstanceID>
<n1:LastSystemInventoryTime>20160107171416.000000+000</n1:LastSystemInventoryTime>
<n1:LastUpdateTime>20151112172601.000000+000</n1:LastUpdateTime>
<n1:Manufacturer>Intel</n1:Manufacturer>
<n1:MaxClockSpeed>4000</n1:MaxClockSpeed>
<n1:Model>Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz</n1:Model>
<n1:NumberOfEnabledCores>6</n1:NumberOfEnabledCores>
<n1:NumberOfEnabledThreads>12</n1:NumberOfEnabledThreads>
<n1:NumberOfProcessorCores>6</n1:NumberOfProcessorCores>
<n1:PrimaryStatus>1</n1:PrimaryStatus>
<n1:TurboModeCapable>1</n1:TurboModeCapable>
<n1:TurboModeEnabled>1</n1:TurboModeEnabled>
<n1:VirtualizationTechnologyCapable>1</n1:VirtualizationTechnologyCapable>
<n1:VirtualizationTechnologyEnabled>1</n1:VirtualizationTechnologyEnabled>
<n1:Voltage>1.3</n1:Voltage>
</n1:DCIM_CPUView>
</wsman:Items>
<wsen:EnumerationContext/>
<wsman:EndOfSequence/>
</wsen:EnumerateResponse>
</s:Body>
</s:Envelope>