Merge "Add chassis resource"
This commit is contained in:
commit
6093a87aca
3
.gitignore
vendored
3
.gitignore
vendored
@ -37,6 +37,7 @@ nosetests.xml
|
|||||||
.mr.developer.cfg
|
.mr.developer.cfg
|
||||||
.project
|
.project
|
||||||
.pydevproject
|
.pydevproject
|
||||||
|
.idea/*
|
||||||
|
|
||||||
# Complexity
|
# Complexity
|
||||||
output/*.html
|
output/*.html
|
||||||
@ -55,4 +56,4 @@ ChangeLog
|
|||||||
.*sw?
|
.*sw?
|
||||||
|
|
||||||
# Files created by releasenotes build
|
# Files created by releasenotes build
|
||||||
releasenotes/build
|
releasenotes/build
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
import sushy
|
import sushy
|
||||||
from sushy.resources import base
|
from sushy.resources import base
|
||||||
|
|
||||||
|
from rsd_lib.resources import chassis
|
||||||
from rsd_lib.resources.node import node
|
from rsd_lib.resources.node import node
|
||||||
from rsd_lib.resources.storage_service import storage_service
|
from rsd_lib.resources.storage_service import storage_service
|
||||||
|
|
||||||
@ -25,6 +26,9 @@ class RSDLib(sushy.Sushy):
|
|||||||
_nodes_path = base.Field(['Nodes', '@odata.id'], required=True)
|
_nodes_path = base.Field(['Nodes', '@odata.id'], required=True)
|
||||||
"""NodeCollection path"""
|
"""NodeCollection path"""
|
||||||
|
|
||||||
|
_chassis_path = base.Field(['Chassis', '@odata.id'], required=True)
|
||||||
|
"""ChassisCollection path"""
|
||||||
|
|
||||||
_storage_service_path = base.Field(['Services',
|
_storage_service_path = base.Field(['Services',
|
||||||
'@odata.id'], required=True)
|
'@odata.id'], required=True)
|
||||||
"""StorageServiceCollection path"""
|
"""StorageServiceCollection path"""
|
||||||
@ -68,3 +72,24 @@ class RSDLib(sushy.Sushy):
|
|||||||
return storage_service.StorageService(
|
return storage_service.StorageService(
|
||||||
self._conn, identity,
|
self._conn, identity,
|
||||||
redfish_version=self.redfish_version)
|
redfish_version=self.redfish_version)
|
||||||
|
|
||||||
|
def get_chassis_collection(self):
|
||||||
|
"""Get the ChassisCollection object
|
||||||
|
|
||||||
|
:raises: MissingAttributeError, if the collection attribute is
|
||||||
|
not found
|
||||||
|
:returns: a ChassisCollection object
|
||||||
|
"""
|
||||||
|
return chassis.ChassisCollection(self._conn,
|
||||||
|
self._chassis_path,
|
||||||
|
redfish_version=self.redfish_version)
|
||||||
|
|
||||||
|
def get_chassis(self, identity):
|
||||||
|
"""Given the identity return a Chassis object
|
||||||
|
|
||||||
|
:param identity: The identity of the Chassis resource
|
||||||
|
:returns: The Chassis object
|
||||||
|
"""
|
||||||
|
return chassis.Chassis(self._conn,
|
||||||
|
identity,
|
||||||
|
redfish_version=self.redfish_version)
|
||||||
|
76
rsd_lib/resources/chassis.py
Normal file
76
rsd_lib/resources/chassis.py
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# Copyright 2017 Intel, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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 sushy.resources import base
|
||||||
|
|
||||||
|
|
||||||
|
class Chassis(base.ResourceBase):
|
||||||
|
identity = base.Field('Id', required=True)
|
||||||
|
"""The chassis identity string"""
|
||||||
|
|
||||||
|
asset_tag = base.Field('AssetTag')
|
||||||
|
"""The chassis asset tag"""
|
||||||
|
|
||||||
|
description = base.Field('Description')
|
||||||
|
"""The chassis description"""
|
||||||
|
|
||||||
|
manufacturer = base.Field('Manufacturer')
|
||||||
|
"""The chassis manufacturer"""
|
||||||
|
|
||||||
|
name = base.Field('Name')
|
||||||
|
"""The chassis name"""
|
||||||
|
|
||||||
|
part_number = base.Field('PartNumber')
|
||||||
|
"""The chassis part number"""
|
||||||
|
|
||||||
|
serial_number = base.Field('SerialNumber')
|
||||||
|
"""The chassis serial number"""
|
||||||
|
|
||||||
|
sku = base.Field('SKU')
|
||||||
|
"""The chassis stock-keeping unit"""
|
||||||
|
|
||||||
|
chassis_type = base.Field('ChassisType')
|
||||||
|
"""The chassis type"""
|
||||||
|
|
||||||
|
oem = base.Field('Oem')
|
||||||
|
"""The chassis oem options values (dict)"""
|
||||||
|
|
||||||
|
def __init__(self, connector, identity, redfish_version=None):
|
||||||
|
"""A class representing a Chassis
|
||||||
|
|
||||||
|
:param connector: A Connector instance
|
||||||
|
:param identity: The identity of the chassis resource
|
||||||
|
:param redfish_version: The version of RedFish. Used to construct
|
||||||
|
the object according to schema of the given version.
|
||||||
|
"""
|
||||||
|
super(Chassis, self).__init__(connector, identity, redfish_version)
|
||||||
|
|
||||||
|
|
||||||
|
class ChassisCollection(base.ResourceCollectionBase):
|
||||||
|
@property
|
||||||
|
def _resource_type(self):
|
||||||
|
return Chassis
|
||||||
|
|
||||||
|
def __init__(self, connector, path, redfish_version=None):
|
||||||
|
"""A class representing a Chassis Collection
|
||||||
|
|
||||||
|
:param connector: A Connector instance
|
||||||
|
:param path: The canonical path to the chassis collection resource
|
||||||
|
:param redfish_version: The version of RedFish. Used to construct
|
||||||
|
the object according to schema of the given version.
|
||||||
|
"""
|
||||||
|
super(ChassisCollection, self).__init__(connector,
|
||||||
|
path,
|
||||||
|
redfish_version)
|
73
rsd_lib/tests/unit/json_samples/chassis.json
Normal file
73
rsd_lib/tests/unit/json_samples/chassis.json
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
"@odata.context": "/redfish/v1/$metadata#Chassis/Members/$entity",
|
||||||
|
"@odata.id": "/redfish/v1/Chassis/Chassis1",
|
||||||
|
"@odata.type": "#Chassis.1.0.0.Chassis",
|
||||||
|
"AssetTag": "FlexChassis1",
|
||||||
|
"ChassisType": "Drawer",
|
||||||
|
"Description": "this is a chassis",
|
||||||
|
"Id": "Chassis1",
|
||||||
|
"IndicatorLED": "On",
|
||||||
|
"Links": {
|
||||||
|
"ComputerSystems": [
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Systems/system1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Systems/system2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Systems/system3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Systems/system4"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ContainedBy": {
|
||||||
|
"@odata.id": "/redfish/v1/Chassis/Rack1"
|
||||||
|
},
|
||||||
|
"Contains": [
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Chassis/Chassis1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ManagedBy": [
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Managers/manager1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ManagersIn": [
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Managers/manager1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Oem": { },
|
||||||
|
"Switches": [
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/EthernetSwitches/switch1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Manufacturer": "Intel Corporaion",
|
||||||
|
"Model": "Lenovo FLEX 8731",
|
||||||
|
"Name": "FLEX-1",
|
||||||
|
"Oem": {
|
||||||
|
"Intel:RackScale": {
|
||||||
|
"@odata.type": "#Intel.Oem.Chassis",
|
||||||
|
"Location": {
|
||||||
|
"Rack": "Rack1",
|
||||||
|
"UHeight": "10 U",
|
||||||
|
"ULocation": "25 U",
|
||||||
|
"UWidth": "1 U"
|
||||||
|
},
|
||||||
|
"UUID": "e1c2d764-5c72-36d6-9945-a78255edab51"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"PartNumber": "5c72-36d6",
|
||||||
|
"SKU": "e1c2d764-5c72",
|
||||||
|
"SerialNumber": "a78255edab51",
|
||||||
|
"Status": {
|
||||||
|
"Health": "OK",
|
||||||
|
"HealthRollup": "OK",
|
||||||
|
"State": "Enabled"
|
||||||
|
}
|
||||||
|
}
|
34
rsd_lib/tests/unit/json_samples/chassis_collection.json
Normal file
34
rsd_lib/tests/unit/json_samples/chassis_collection.json
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"@odata.context": "/redfish/v1/$metadata#Chassis",
|
||||||
|
"@odata.id": "/redfish/v1/Chassis",
|
||||||
|
"@odata.type": "#ChassisCollection.ChassisCollection",
|
||||||
|
"Members": [
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Chassis/Rack1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Chassis/Rack2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Chassis/Chassis1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Chassis/Chassis2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Chassis/Drawer1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Chassis/Drawer2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Chassis/NVMEChassis1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Chassis/NVMEChassis2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Members@odata.count": 8,
|
||||||
|
"Name": "Chassis Collection"
|
||||||
|
|
||||||
|
}
|
88
rsd_lib/tests/unit/resources/test_chassis.py
Normal file
88
rsd_lib/tests/unit/resources/test_chassis.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
# 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 json
|
||||||
|
|
||||||
|
import mock
|
||||||
|
|
||||||
|
from sushy.tests.unit import base
|
||||||
|
|
||||||
|
from rsd_lib.resources import chassis
|
||||||
|
|
||||||
|
|
||||||
|
class TestChassis(base.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestChassis, self).setUp()
|
||||||
|
self.conn = mock.Mock()
|
||||||
|
|
||||||
|
with open('rsd_lib/tests/unit/json_samples/chassis.json',
|
||||||
|
'r') as f:
|
||||||
|
self.conn.get.return_value.json.return_value = json.loads(f.read())
|
||||||
|
|
||||||
|
self.chassis_inst = chassis.Chassis(self.conn,
|
||||||
|
'/redfish/v1/Chassis/chassis1',
|
||||||
|
redfish_version='1.0.2')
|
||||||
|
|
||||||
|
def test_parse_attributes(self):
|
||||||
|
self.chassis_inst._parse_attributes()
|
||||||
|
self.assertEqual('1.0.2', self.chassis_inst.redfish_version)
|
||||||
|
self.assertEqual('FlexChassis1', self.chassis_inst.asset_tag)
|
||||||
|
self.assertEqual('Drawer', self.chassis_inst.chassis_type)
|
||||||
|
self.assertEqual('this is a chassis', self.chassis_inst.description)
|
||||||
|
self.assertEqual('Chassis1', self.chassis_inst.identity)
|
||||||
|
self.assertEqual('Intel Corporaion', self.chassis_inst.manufacturer)
|
||||||
|
self.assertEqual('FLEX-1', self.chassis_inst.name)
|
||||||
|
self.assertEqual('5c72-36d6', self.chassis_inst.part_number)
|
||||||
|
self.assertEqual('a78255edab51', self.chassis_inst.serial_number)
|
||||||
|
self.assertEqual('e1c2d764-5c72', self.chassis_inst.sku)
|
||||||
|
self.assertEqual('e1c2d764-5c72-36d6-9945-a78255edab51',
|
||||||
|
self.chassis_inst.oem['Intel:RackScale']['UUID'])
|
||||||
|
|
||||||
|
|
||||||
|
class TestChassisCollection(base.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestChassisCollection, self).setUp()
|
||||||
|
self.conn = mock.Mock()
|
||||||
|
|
||||||
|
with open('rsd_lib/tests/unit/json_samples/chassis_collection.json',
|
||||||
|
'r') as f:
|
||||||
|
self.conn.get.return_value.json.return_value = json.loads(f.read())
|
||||||
|
|
||||||
|
self.chassis_col = chassis.ChassisCollection(self.conn,
|
||||||
|
'/redfish/v1/Systems',
|
||||||
|
redfish_version='1.0.2')
|
||||||
|
|
||||||
|
def test__parse_attributes(self):
|
||||||
|
self.chassis_col._parse_attributes()
|
||||||
|
self.assertEqual('1.0.2', self.chassis_col.redfish_version)
|
||||||
|
self.assertEqual('Chassis Collection', self.chassis_col.name)
|
||||||
|
self.assertIn('/redfish/v1/Chassis/Chassis1',
|
||||||
|
self.chassis_col.members_identities)
|
||||||
|
|
||||||
|
@mock.patch.object(chassis, 'Chassis', autospec=True)
|
||||||
|
def test_get_member(self, mock_chassis):
|
||||||
|
self.chassis_col.get_member('/redfish/v1/Chassis/Chassis1')
|
||||||
|
|
||||||
|
mock_chassis.assert_called_once_with(
|
||||||
|
self.chassis_col._conn,
|
||||||
|
'/redfish/v1/Chassis/Chassis1',
|
||||||
|
redfish_version=self.chassis_col.redfish_version
|
||||||
|
)
|
||||||
|
|
||||||
|
@mock.patch.object(chassis, 'Chassis', autospec=True)
|
||||||
|
def test_get_members(self, mock_chassis):
|
||||||
|
members = self.chassis_col.get_members()
|
||||||
|
self.assertEqual(mock_chassis.call_count, 8)
|
||||||
|
self.assertIsInstance(members, list)
|
||||||
|
self.assertEqual(8, len(members))
|
Loading…
x
Reference in New Issue
Block a user