Add new Ethernet Interface in RSD 2.3 manager

Change-Id: I00e0733b916763c7a2b972f9f8073fd8e3581057
This commit is contained in:
Lin Yang 2019-02-05 12:52:09 -08:00
parent 85c26d828c
commit e2a17a6065
9 changed files with 357 additions and 21 deletions

View File

@ -98,11 +98,6 @@ class Manager(base.ResourceBase):
firmware_version = base.Field('FirmwareVersion') firmware_version = base.Field('FirmwareVersion')
"""The manager firmware version""" """The manager firmware version"""
ethernet_interfaces = base.Field(
'EthernetInterfaces',
adapter=rsd_lib_utils.get_resource_identity)
"""Link to ethernet interfaces of this manager"""
links = LinksField('Links') links = LinksField('Links')
"""These links to related components of this manager""" """These links to related components of this manager"""
@ -144,8 +139,8 @@ class Manager(base.ResourceBase):
@property @property
@utils.cache_it @utils.cache_it
def ethernet_interface(self): def ethernet_interfaces(self):
"""Property to provide reference to `EthernetInterface` instance """Property to provide reference to `EthernetInterfaceCollection`
It is calculated once when it is queried for the first time. On It is calculated once when it is queried for the first time. On
refresh, this property is reset. refresh, this property is reset.

View File

@ -0,0 +1,41 @@
# Copyright 2019 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 import utils
from rsd_lib.resources.v2_2.manager import manager
from rsd_lib.resources.v2_3.system import ethernet_interface
class Manager(manager.Manager):
@property
@utils.cache_it
def ethernet_interfaces(self):
"""Property to provide reference to `EthernetInterface` instance
It is calculated once when it is queried for the first time. On
refresh, this property is reset.
"""
return ethernet_interface.EthernetInterfaceCollection(
self._conn, self._get_ethernet_interface_path(),
redfish_version=self.redfish_version)
class ManagerCollection(manager.ManagerCollection):
@property
def _resource_type(self):
return Manager

View File

@ -0,0 +1,80 @@
{
"@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": null
},
"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",
"Actions": {
"#Manager.Reset": {
"target": "/redfish/v1/Managers/PSME/Actions/Manager.Reset",
"ResetType@Redfish.AllowableValues": []
},
"Oem": {}
}
}

View File

@ -0,0 +1,19 @@
{
"@odata.context": "/redfish/v1/$metadata#ManagerCollection.ManagerCollection",
"@odata.id": "/redfish/v1/Managers",
"@odata.type": "#ManagerCollection.ManagerCollection",
"Name": "Manager Collection",
"Description": "description-as-string",
"Members@odata.count": 3,
"Members": [
{
"@odata.id": "/redfish/v1/Managers/BMC1"
},
{
"@odata.id": "/redfish/v1/Managers/BMC2"
},
{
"@odata.id": "/redfish/v1/Managers/PSME"
}
]
}

View File

@ -0,0 +1,63 @@
{
"@odata.context":"/redfish/v1/$metadata#EthernetInterface.EthernetInterface",
"@odata.id":"/redfish/v1/Systems/System1/EthernetInterfaces/LAN1",
"@odata.type":"#EthernetInterface.v1_1_0.EthernetInterface",
"Id":"LAN1",
"Name":"Ethernet Interface",
"Description":"System NIC 1",
"Status":{
"State":"Enabled",
"Health":"OK",
"HealthRollup":null
},
"InterfaceEnabled":true,
"PermanentMACAddress":"AA:BB:CC:DD:EE:FF",
"MACAddress":"AA:BB:CC:DD:EE:FF",
"SpeedMbps":100,
"AutoNeg":true,
"FullDuplex":true,
"MTUSize":1500,
"HostName":"web483",
"FQDN":"web483.redfishspecification.org",
"IPv6DefaultGateway":"fe80::3ed9:2bff:fe34:600",
"MaxIPv6StaticAddresses":null,
"NameServers":[
"names.redfishspecification.org"
],
"IPv4Addresses":[
{
"Address":"192.168.0.10",
"SubnetMask":"255.255.252.0",
"AddressOrigin":"Static",
"Gateway":"192.168.0.1"
}
],
"IPv6Addresses":[
{
"Address":"fe80::1ec1:deff:fe6f:1e24",
"PrefixLength":64,
"AddressOrigin":"Static",
"AddressState":"Preferred"
}
],
"IPv6StaticAddresses":[
],
"VLAN":null,
"VLANs": {
"@odata.id": "/redfish/v1/Managers/1/EthernetInterfaces/1/VLANs"
},
"Oem":{
},
"Links":{
"Oem":{
"Intel_RackScale":{
"@odata.type":"#Intel.Oem.EthernetInterface",
"NeighborPort":{
"@odata.id":"/redfish/v1/EthernetSwitches/1/Ports/1"
}
}
}
}
}

View File

@ -0,0 +1,12 @@
{
"@odata.context":"/redfish/v1/$metadata#Managers/Members/1/EthernetInterfaces/$entity",
"@odata.id":"/redfish/v1/Managers/1/EthernetInterfaces",
"@odata.type":"#EthernetNetworkInterface.v1_0_0.EthernetNetworkInterfaceCollection",
"Name":"Ethernet Network Interface Collection",
"Members@odata.count":1,
"Members":[
{
"@odata.id":"/redfish/v1/Managers/1/EthernetInterfaces/1"
}
]
}

View File

@ -144,9 +144,9 @@ class TestManager(base.TestCase):
'manager_ethernet_interface.json', 'r') as f: 'manager_ethernet_interface.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read()) self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN | # | WHEN |
actual_ethernet_interface = self.manager_inst.ethernet_interface actual_ethernet_interfaces = self.manager_inst.ethernet_interfaces
# | THEN | # | THEN |
self.assertIsInstance(actual_ethernet_interface, self.assertIsInstance(actual_ethernet_interfaces,
ethernet_interface.EthernetInterfaceCollection) ethernet_interface.EthernetInterfaceCollection)
self.conn.get.return_value.json.assert_called_once_with() self.conn.get.return_value.json.assert_called_once_with()
@ -154,17 +154,17 @@ class TestManager(base.TestCase):
self.conn.get.return_value.json.reset_mock() self.conn.get.return_value.json.reset_mock()
# | WHEN & THEN | # | WHEN & THEN |
# tests for same object on invoking subsequently # tests for same object on invoking subsequently
self.assertIs(actual_ethernet_interface, self.assertIs(actual_ethernet_interfaces,
self.manager_inst.ethernet_interface) self.manager_inst.ethernet_interfaces)
self.conn.get.return_value.json.assert_not_called() self.conn.get.return_value.json.assert_not_called()
def test_ethernet_interface_on_refresh(self): def test_ethernet_interface_on_refresh(self):
# | GIVEN | # | GIVEN |
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open('rsd_lib/tests/unit/json_samples/v2_1/'
'manager_ethernet_interface.json', 'r') as f: 'manager_ethernet_interface_collection.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read()) self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN | # | WHEN & THEN |
self.assertIsInstance(self.manager_inst.ethernet_interface, self.assertIsInstance(self.manager_inst.ethernet_interfaces,
ethernet_interface.EthernetInterfaceCollection) ethernet_interface.EthernetInterfaceCollection)
# On refreshing the manager instance... # On refreshing the manager instance...
@ -177,10 +177,10 @@ class TestManager(base.TestCase):
# | GIVEN | # | GIVEN |
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open('rsd_lib/tests/unit/json_samples/v2_1/'
'manager_ethernet_interface.json', 'r') as f: 'manager_ethernet_interface_collection.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read()) self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN | # | WHEN & THEN |
self.assertIsInstance(self.manager_inst.ethernet_interface, self.assertIsInstance(self.manager_inst.ethernet_interfaces,
ethernet_interface.EthernetInterfaceCollection) ethernet_interface.EthernetInterfaceCollection)

View File

@ -49,9 +49,9 @@ class TestManager(base.TestCase):
'manager_ethernet_interface.json', 'r') as f: 'manager_ethernet_interface.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read()) self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN | # | WHEN |
actual_ethernet_interface = self.manager_inst.ethernet_interface actual_ethernet_interfaces = self.manager_inst.ethernet_interfaces
# | THEN | # | THEN |
self.assertIsInstance(actual_ethernet_interface, self.assertIsInstance(actual_ethernet_interfaces,
ethernet_interface.EthernetInterfaceCollection) ethernet_interface.EthernetInterfaceCollection)
self.conn.get.return_value.json.assert_called_once_with() self.conn.get.return_value.json.assert_called_once_with()
@ -59,8 +59,8 @@ class TestManager(base.TestCase):
self.conn.get.return_value.json.reset_mock() self.conn.get.return_value.json.reset_mock()
# | WHEN & THEN | # | WHEN & THEN |
# tests for same object on invoking subsequently # tests for same object on invoking subsequently
self.assertIs(actual_ethernet_interface, self.assertIs(actual_ethernet_interfaces,
self.manager_inst.ethernet_interface) self.manager_inst.ethernet_interfaces)
self.conn.get.return_value.json.assert_not_called() self.conn.get.return_value.json.assert_not_called()
def test_ethernet_interface_on_refresh(self): def test_ethernet_interface_on_refresh(self):
@ -69,7 +69,7 @@ class TestManager(base.TestCase):
'manager_ethernet_interface.json', 'r') as f: 'manager_ethernet_interface.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read()) self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN | # | WHEN & THEN |
self.assertIsInstance(self.manager_inst.ethernet_interface, self.assertIsInstance(self.manager_inst.ethernet_interfaces,
ethernet_interface.EthernetInterfaceCollection) ethernet_interface.EthernetInterfaceCollection)
# On refreshing the manager instance... # On refreshing the manager instance...
@ -85,7 +85,7 @@ class TestManager(base.TestCase):
'manager_ethernet_interface.json', 'r') as f: 'manager_ethernet_interface.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read()) self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN | # | WHEN & THEN |
self.assertIsInstance(self.manager_inst.ethernet_interface, self.assertIsInstance(self.manager_inst.ethernet_interfaces,
ethernet_interface.EthernetInterfaceCollection) ethernet_interface.EthernetInterfaceCollection)

View File

@ -0,0 +1,126 @@
# 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_3.manager import manager
from rsd_lib.resources.v2_3.system import ethernet_interface
class TestManager(base.TestCase):
def setUp(self):
super(TestManager, self).setUp()
self.conn = mock.Mock()
with open('rsd_lib/tests/unit/json_samples/v2_3/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__get_ethernet_interface_path(self):
expected = '/redfish/v1/Managers/PSME/EthernetInterfaces'
result = self.manager_inst._get_ethernet_interface_path()
self.assertEqual(expected, result)
def test_ethernet_interface(self):
# | GIVEN |
self.conn.get.return_value.json.reset_mock()
with open('rsd_lib/tests/unit/json_samples/v2_3/'
'manager_ethernet_interface_collection.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN |
actual_ethernet_interfaces = self.manager_inst.ethernet_interfaces
# | THEN |
self.assertIsInstance(actual_ethernet_interfaces,
ethernet_interface.EthernetInterfaceCollection)
self.conn.get.return_value.json.assert_called_once_with()
# reset mock
self.conn.get.return_value.json.reset_mock()
# | WHEN & THEN |
# tests for same object on invoking subsequently
self.assertIs(actual_ethernet_interfaces,
self.manager_inst.ethernet_interfaces)
self.conn.get.return_value.json.assert_not_called()
def test_ethernet_interface_on_refresh(self):
# | GIVEN |
with open('rsd_lib/tests/unit/json_samples/v2_3/'
'manager_ethernet_interface_collection.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN |
self.assertIsInstance(self.manager_inst.ethernet_interfaces,
ethernet_interface.EthernetInterfaceCollection)
# On refreshing the manager instance...
with open('rsd_lib/tests/unit/json_samples/v2_3/'
'manager.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
self.manager_inst.invalidate()
self.manager_inst.refresh(force=False)
# | GIVEN |
with open('rsd_lib/tests/unit/json_samples/v2_3/'
'manager_ethernet_interface_collection.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN |
self.assertIsInstance(self.manager_inst.ethernet_interfaces,
ethernet_interface.EthernetInterfaceCollection)
class TestManagerCollection(base.TestCase):
def setUp(self):
super(TestManagerCollection, self).setUp()
self.conn = mock.Mock()
with open('rsd_lib/tests/unit/json_samples/v2_3/'
'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.assertEqual(('/redfish/v1/Managers/BMC1',
'/redfish/v1/Managers/BMC2',
'/redfish/v1/Managers/PSME',),
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/BMC1')
mock_manager.assert_called_once_with(
self.manager_col._conn,
'/redfish/v1/Managers/BMC1',
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.assertIsInstance(members, list)
self.assertEqual(3, len(members))