Add manager resources for RSD v2.1

Change-Id: I29533dca4cbc67ae720bb6d95519a0e797f117c9
This commit is contained in:
ya.wang 2018-04-08 09:49:47 +08:00
parent 3be4548f07
commit e9dfd51bcf
7 changed files with 404 additions and 0 deletions

View File

@ -17,6 +17,7 @@ from sushy.resources import base
from rsd_lib.resources.v2_1.chassis import chassis
from rsd_lib.resources.v2_1.fabric import fabric
from rsd_lib.resources.v2_1.manager import manager
from rsd_lib.resources.v2_1.node import node
from rsd_lib.resources.v2_1.storage_service import storage_service
from rsd_lib.resources.v2_1.system import system
@ -40,6 +41,9 @@ class RSDLibV2_1(base.ResourceBase):
_fabrics_path = base.Field(['Fabrics', '@odata.id'], required=True)
"""FabricCollection path"""
_managers_path = base.Field(['Managers', '@odata.id'], required=True)
"""ManagerCollection path"""
_redfish_version = base.Field(['RedfishVersion'], required=True)
"""Redfish version"""
@ -158,3 +162,24 @@ class RSDLibV2_1(base.ResourceBase):
return fabric.Fabric(self._conn,
identity,
redfish_version=self.redfish_version)
def get_manager_collection(self):
"""Get the ManagerCollection object
:raises: MissingAttributeError, if the collection attribute is
not found
:returns: a ManagerCollection object
"""
return manager.ManagerCollection(self._conn,
self._managers_path,
redfish_version=self.redfish_version)
def get_manager(self, identity):
"""Given the identity return a Manager object
:param identity: The identity of the Manager resource
:returns: The Manager object
"""
return manager.Manager(self._conn,
identity,
redfish_version=self.redfish_version)

View File

@ -0,0 +1,140 @@
# Copyright 2018 99cloud, 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
from sushy import utils
from rsd_lib import utils as rsd_lib_utils
class StatusField(base.CompositeField):
state = base.Field('State')
health = base.Field('Health')
health_rollup = base.Field('HealthRollup')
class GraphicalConsoleField(base.CompositeField):
service_enabled = base.Field('ServiceEnabled')
max_concurrent_sessions = base.Field('MaxConcurrentSessions', adapter=int)
connect_types_supported = base.Field('ConnectTypesSupported', adapter=list)
class SerialConsoleField(base.CompositeField):
service_enabled = base.Field('ServiceEnabled')
max_concurrent_sessions = base.Field('MaxConcurrentSessions', adapter=int)
connect_types_supported = base.Field('ConnectTypesSupported', adapter=list)
class CommandShellField(base.CompositeField):
service_enabled = base.Field('ServiceEnabled')
max_concurrent_sessions = base.Field('MaxConcurrentSessions', adapter=int)
connect_types_supported = base.Field('ConnectTypesSupported', adapter=list)
class LinksField(base.CompositeField):
manager_for_servers = base.Field('ManagerForServers', default=(),
adapter=utils.get_members_identities)
"""Link to managed servers of this manager"""
manager_for_chassis = base.Field('ManagerForChassis', default=(),
adapter=utils.get_members_identities)
"""Link to managed chassis of this manager"""
oem = base.Field('Oem')
"""The oem options values of links (dict)"""
class Manager(base.ResourceBase):
identity = base.Field('Id', required=True)
"""The manager identity string"""
name = base.Field('Name')
"""The manager name"""
manager_type = base.Field('ManagerType')
"""The manager type"""
description = base.Field('Description')
"""The manager description"""
service_entry_point_uuid = base.Field('ServiceEntryPointUUID')
"""The manager service entry point uuid"""
uuid = base.Field('UUID')
"""The manager uuid"""
model = base.Field('Model')
"""The manager model"""
status = StatusField("Status")
"""The manager status"""
graphical_console = GraphicalConsoleField('GraphicalConsole')
"""The manager graphical console"""
serial_console = SerialConsoleField('SerialConsole')
"""The manager serial console"""
command_shell = CommandShellField('CommandShell')
"""The manager shell console"""
firmware_version = base.Field('FirmwareVersion')
"""The manager firmware version"""
network_protocol = base.Field('NewworkProtocol',
adapter=rsd_lib_utils.get_resource_identity)
"""Link to network protocol of this manager"""
ethernet_interfaces = base.Field(
'EthernetInterfaces',
adapter=rsd_lib_utils.get_resource_identity)
"""Link to ethernet interfaces of this manager"""
links = LinksField('Links')
"""These links to related components of this manager"""
oem = base.Field('Oem')
"""The manager oem options values (dict)"""
power_state = base.Field('PowerState')
"""The manager power state"""
def __init__(self, connector, identity, redfish_version=None):
"""A class representing a manager
: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(Manager, self).__init__(connector, identity, redfish_version)
class ManagerCollection(base.ResourceCollectionBase):
@property
def _resource_type(self):
return Manager
def __init__(self, connector, path, redfish_version=None):
"""A class representing a Manager 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(ManagerCollection, self).__init__(connector,
path,
redfish_version)

View File

@ -0,0 +1,75 @@
{
"@odata.context": "/redfish/v1/$metadata#Manager.Manager",
"@odata.id": "/redfish/v1/Managers/PSME",
"@odata.type": "#Manager.v1_2_0.Manager",
"Id": "1",
"Name": "Manager",
"ManagerType": "BMC",
"Description": "BMC",
"ServiceEntryPointUUID": "92384634-2938-2342-8820-489239905423",
"UUID": "00000000-0000-0000-0000-000000000000",
"Model": "Joo Janta 200",
"DateTime": "2015-03-13T04:14:33+06:00",
"DateTimeLocalOffset": "+06:00",
"Status": {
"State": "Enabled",
"Health": "OK",
"HealthRollup": "OK"
},
"GraphicalConsole": {
"ServiceEnabled": true,
"MaxConcurrentSessions": 2,
"ConnectTypesSupported": [
"KVMIP"
]
},
"SerialConsole": {
"ServiceEnabled": true,
"MaxConcurrentSessions": 1,
"ConnectTypesSupported": [
"Telnet",
"SSH",
"IPMI"
]
},
"CommandShell": {
"ServiceEnabled": true,
"MaxConcurrentSessions": 4,
"ConnectTypesSupported": [
"Telnet",
"SSH"
]
},
"FirmwareVersion": "1.00",
"NetworkProtocol": {
"@odata.id": "/redfish/v1/Managers/PSME/NetworkProtocol"
},
"EthernetInterfaces": {
"@odata.id": "/redfish/v1/Managers/PSME/EthernetInterfaces"
},
"Links": {
"@odata.type": "#Manager.v1_1_0.Links",
"ManagerForServers": [],
"ManagerForChassis": [
{
"@odata.id": "/redfish/v1/Chassis/FabricModule1"
}
],
"ManagerInChassis": {
"@odata.id": "/redfish/v1/Chassis/Drawer1"
},
"Oem": {
"Intel_RackScale": {
"@odata.type": "#Intel.Oem.ManagerLinks",
"ManagerForServices": [
{
"@odata.id": "/redfish/v1/Services/RSS1"
}
],
"ManagerForSwitches": []
}
}
},
"Oem": {},
"PowerState": "On"
}

View File

@ -0,0 +1,18 @@
{
"@odata.context": "/redfish/v1/$metadata#Managers",
"@odata.id": "/redfish/v1/Managers",
"@odata.type": "#ManagerCollection.1.0.0.ManagerCollection",
"Name": "Manager Collection",
"Members@odata.count": 3,
"Members": [
{
"@odata.id": "/redfish/v1/Managers/RMC"
},
{
"@odata.id": "/redfish/v1/Managers/MBPC1"
},
{
"@odata.id": "/redfish/v1/Managers/MBPC2"
}
]
}

View File

@ -0,0 +1,128 @@
# 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.v2_1.manager import manager
class TestManager(base.TestCase):
def setUp(self):
super(TestManager, self).setUp()
self.conn = mock.Mock()
with open('rsd_lib/tests/unit/json_samples/v2_1/manager.json',
'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
self.manager_inst = manager.Manager(self.conn,
'/redfish/v1/Manager/PSME',
redfish_version='1.0.2')
def test_parse_attributes(self):
self.manager_inst._parse_attributes()
self.assertEqual('1.0.2', self.manager_inst.redfish_version)
self.assertEqual('1', self.manager_inst.identity)
self.assertEqual('Manager', self.manager_inst.name)
self.assertEqual('BMC', self.manager_inst.description)
self.assertEqual('92384634-2938-2342-8820-489239905423',
self.manager_inst.service_entry_point_uuid)
self.assertEqual('00000000-0000-0000-0000-000000000000',
self.manager_inst.uuid)
self.assertEqual('Joo Janta 200', self.manager_inst.model)
self.assertEqual('Enables', self.manager_inst.status.state)
self.assertEqual('OK', self.manager_inst.status.health)
self.assertEqual('OK', self.manager_inst.status.health_rollup)
self.assertEqual(True,
self.manager_inst.graphical_console.service_enabled)
self.assertEqual(
2,
self.manager_inst.graphical_console.max_concurrent_sessions)
self.assertEqual(
['KVMIP'],
self.manager_inst.graphical_console.connect_types_supported)
self.assertEqual(
True,
self.manager_inst.serial_console.service_enabled)
self.assertEqual(
1,
self.manager_inst.serial_console.max_concurrent_sessions)
self.assertEqual(
['Telnet', 'SSH', 'IPMI'],
self.manager_inst.serial_console.connect_types_supported)
self.assertEqual(
True,
self.manager_inst.command_shell.service_enabled)
self.assertEqual(
4,
self.manager_inst.command_shell.max_concurrent_sessions)
self.assertEqual(
['Telnet', 'SSH'],
self.manager_inst.command_shell.connect_types_supported)
self.assertEqual('1.00', self.manager_inst.firmware_version)
self.assertEqual(
('/redfish/v1/Managers/PSME/NetworkProtocol',),
self.manager_inst.network_protocol)
self.assertEqual(
('/redfish/v1/Managers/PSME/EthernetInterfaces',),
self.manager_inst.ethernet_interfaces)
self.assertEqual((), self.manager_inst.links.manager_for_servers)
self.assertEqual(
('/redfish/v1/Chassis/FabricModule1',),
self.manager_inst.links.manager_for_chassis)
self.assertEqual('On', self.manager_inst.power_state)
class TestManagerCollection(base.TestCase):
def setUp(self):
super(TestManagerCollection, self).setUp()
self.conn = mock.Mock()
with open('rsd_lib/tests/unit/json_samples/v2_1/'
'manager_collection.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
self.manager_col = manager.ManagerCollection(self.conn,
'redfish/v1/Managers',
redfish_version='1.0.2')
def test_parse_attributes(self):
self.manager_col._parse_attributes()
self.assertEqual('1.0.2', self.manager_col.redfish_version)
self.assertEqual('Manager Collection', self.manager_col.name)
self.assertIn(('/redfish/v1/Manaagers/RMC',
'/redfish/v1/Managers/MBPC1',
'/redfish/v1/Managers/MBPC2',),
self.manager_col.members_identities)
@mock.patch.object(manager, 'Manager', autospec=True)
def test_get_member(self, mock_manager):
self.manager_col.get_member('/redfish/v1/Managers/RMC')
mock_manager.assert_called_once_with(
self.manager_col._conn,
'/redfish/v1/Managers/RMC',
redfish_version=self.manager_col.redfish_version
)
@mock.patch.object(manager, 'Manager', autospec=True)
def test_get_members(self, mock_manager):
members = self.manager_col.get_members()
self.assertEqual(mock_manager.call_count, 3)
self.assertInstance(members, list)
self.assertEqual(3, len(members))

View File

@ -20,6 +20,7 @@ import testtools
from rsd_lib.resources import v2_1
from rsd_lib.resources.v2_1.chassis import chassis
from rsd_lib.resources.v2_1.fabric import fabric
from rsd_lib.resources.v2_1.manager import manager
from rsd_lib.resources.v2_1.node import node
from rsd_lib.resources.v2_1.storage_service import storage_service
from rsd_lib.resources.v2_1.system import system
@ -44,6 +45,7 @@ class RSDLibV2_1TestCase(testtools.TestCase):
self.assertEqual("/redfish/v1/Services",
self.rsd._storage_service_path)
self.assertEqual("/redfish/v1/Fabrics", self.rsd._fabrics_path)
self.assertEqual("/redfish/v1/Managers", self.rsd._managers_path)
@mock.patch.object(system, 'SystemCollection', autospec=True)
def test_get_system_collection(self, mock_system_collection):
@ -116,3 +118,19 @@ class RSDLibV2_1TestCase(testtools.TestCase):
mock_storage_service.assert_called_once_with(
self.rsd._conn, 'fake-storage-service-id',
redfish_version=self.rsd.redfish_version)
@mock.patch.object(manager, 'ManagerCollection', autospec=True)
def test_get_manager_collection(self,
mock_manager_collection):
self.rsd.get_manager_collection()
mock_manager_collection.assert_called_once_with(
self.rsd._conn, '/redfish/v1/Managers',
redfish_version=self.rsd.redfish_version)
@mock.patch.object(manager, 'Manager', autospec=True)
def test_get_manager(self, mock_manager_service):
self.rsd.get_manager('fake-manager-id')
mock_manager_service.assert_called_once_with(
self.rsd._conn, 'fake-manager-id',
redfish_version=self.rsd.redfish_version
)