Merge "Add FabricCollection
and Fabric
classes"
This commit is contained in:
commit
f10322a67c
@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Adds support for the Fabric resource to the library.
|
||||
|
@ -21,6 +21,7 @@ from sushy.resources.constants import * # noqa
|
||||
from sushy.resources.system.constants import * # noqa
|
||||
from sushy.resources.manager.constants import * # noqa
|
||||
from sushy.resources.chassis.constants import * # noqa
|
||||
from sushy.resources.fabric.constants import * # noqa
|
||||
|
||||
__all__ = ('Sushy',)
|
||||
__version__ = pbr.version.VersionInfo(
|
||||
|
@ -21,6 +21,7 @@ from sushy import exceptions
|
||||
from sushy.resources import base
|
||||
from sushy.resources.chassis import chassis
|
||||
from sushy.resources.compositionservice import compositionservice
|
||||
from sushy.resources.fabric import fabric
|
||||
from sushy.resources.manager import manager
|
||||
from sushy.resources.registry import message_registry
|
||||
from sushy.resources.registry import message_registry_file
|
||||
@ -83,6 +84,9 @@ class Sushy(base.ResourceBase):
|
||||
_chassis_path = base.Field(['Chassis', '@odata.id'])
|
||||
"""ChassisCollection path"""
|
||||
|
||||
_fabrics_path = base.Field(['Fabrics', '@odata.id'])
|
||||
"""FabricCollection path"""
|
||||
|
||||
_session_service_path = base.Field(['SessionService', '@odata.id'])
|
||||
"""SessionService path"""
|
||||
|
||||
@ -192,6 +196,29 @@ class Sushy(base.ResourceBase):
|
||||
return chassis.Chassis(self._conn, identity,
|
||||
redfish_version=self.redfish_version)
|
||||
|
||||
def get_fabric_collection(self):
|
||||
"""Get the FabricCollection object
|
||||
|
||||
:raises: MissingAttributeError, if the collection attribute is
|
||||
not found
|
||||
:returns: a FabricCollection object
|
||||
"""
|
||||
if not self._fabrics_path:
|
||||
raise exceptions.MissingAttributeError(
|
||||
attribute='Fabrics/@odata.id', resource=self._path)
|
||||
|
||||
return fabric.FabricCollection(self._conn, self._fabrics_path,
|
||||
redfish_version=self.redfish_version)
|
||||
|
||||
def get_fabric(self, identity):
|
||||
"""Given the identity return a Fabric object
|
||||
|
||||
:param identity: The identity of the Fabric resource
|
||||
:returns: The Fabric object
|
||||
"""
|
||||
return fabric.Fabric(self._conn, identity,
|
||||
redfish_version=self.redfish_version)
|
||||
|
||||
def get_manager_collection(self):
|
||||
"""Get the ManagerCollection object
|
||||
|
||||
|
0
sushy/resources/fabric/__init__.py
Normal file
0
sushy/resources/fabric/__init__.py
Normal file
42
sushy/resources/fabric/constants.py
Normal file
42
sushy/resources/fabric/constants.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.
|
||||
|
||||
# Values come from the Redfish Fabric json-schema 1.0.4:
|
||||
# http://redfish.dmtf.org/schemas/v1/Fabric.v1_0_4.json#/definitions/Fabric
|
||||
|
||||
# Fabric Types constants
|
||||
|
||||
FABRIC_TYPE_AHCI = 'Advanced Host Controller Interface'
|
||||
FABRIC_TYPE_FC = 'Fibre Channel'
|
||||
FABRIC_TYPE_FCP = 'Fibre Channel Protocol for SCSI'
|
||||
FABRIC_TYPE_FCoE = 'Fibre Channel over Ethernet'
|
||||
FABRIC_TYPE_FICON = 'FIbre CONnection (FICON)'
|
||||
FABRIC_TYPE_FTP = 'File Transfer Protocol'
|
||||
FABRIC_TYPE_HTTP = 'Hypertext Transport Protocol'
|
||||
FABRIC_TYPE_HTTPS = 'Secure Hypertext Transport Protocol'
|
||||
FABRIC_TYPE_I2C = 'Inter-Integrated Circuit Bus'
|
||||
FABRIC_TYPE_NFSv3 = 'Network File System version 3'
|
||||
FABRIC_TYPE_NFSv4 = 'Network File System version 4'
|
||||
FABRIC_TYPE_NVMe = 'Non-Volatile Memory Express'
|
||||
FABRIC_TYPE_NVMeOverFabrics = 'NVMe over Fabrics'
|
||||
FABRIC_TYPE_OEM = 'OEM specific'
|
||||
FABRIC_TYPE_PCIe = 'PCI Express'
|
||||
FABRIC_TYPE_RoCE = 'RDMA over Converged Ethernet Protocol'
|
||||
FABRIC_TYPE_RoCEv2 = 'RDMA over Converged Ethernet Protocol Version 2'
|
||||
FABRIC_TYPE_SAS = 'Serial Attached SCSI'
|
||||
FABRIC_TYPE_SATA = 'Serial AT Attachment'
|
||||
FABRIC_TYPE_SFTP = 'Secure File Transfer Protocol'
|
||||
FABRIC_TYPE_SMB = 'Server Message Block (aka CIFS Common Internet File System)'
|
||||
FABRIC_TYPE_UHCI = 'Universal Host Controller Interface'
|
||||
FABRIC_TYPE_USB = 'Universal Serial Bus'
|
||||
FABRIC_TYPE_iSCSI = 'Internet SCSI'
|
||||
FABRIC_TYPE_iWARP = 'Internet Wide Area Remote Direct Memory Access Protocol'
|
77
sushy/resources/fabric/fabric.py
Normal file
77
sushy/resources/fabric/fabric.py
Normal file
@ -0,0 +1,77 @@
|
||||
# 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.
|
||||
|
||||
# This is referred from Redfish standard schema.
|
||||
# http://redfish.dmtf.org/schemas/v1/Fabric.v1_0_4.json
|
||||
|
||||
from sushy.resources import base
|
||||
from sushy.resources import common
|
||||
from sushy.resources.fabric import mappings as fab_maps
|
||||
|
||||
import logging
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Fabric(base.ResourceBase):
|
||||
"""Fabric resource
|
||||
|
||||
The Fabric represents a simple fabric consisting of one or more
|
||||
switches, zero or more endpoints, and zero or more zones.
|
||||
"""
|
||||
|
||||
identity = base.Field('Id', required=True)
|
||||
"""Identifier for the fabric"""
|
||||
|
||||
name = base.Field('Name', required=True)
|
||||
"""The fabric name"""
|
||||
|
||||
description = base.Field('Description')
|
||||
"""The fabric description"""
|
||||
|
||||
max_zones = base.Field('MaxZones')
|
||||
"""The maximum number of zones the switch can currently configure"""
|
||||
|
||||
status = common.StatusField('Status')
|
||||
"""The fabric status"""
|
||||
|
||||
fabric_type = base.MappedField('FabricType',
|
||||
fab_maps.FABRIC_TYPE_VALUE_MAP)
|
||||
"""The protocol being sent over this fabric"""
|
||||
|
||||
def __init__(self, connector, identity, redfish_version=None):
|
||||
"""A class representing a Fabric
|
||||
|
||||
:param connector: A Connector instance
|
||||
:param identity: The identity of the Fabric resource
|
||||
:param redfish_version: The version of RedFish. Used to construct
|
||||
the object according to schema of the given version.
|
||||
"""
|
||||
super(Fabric, self).__init__(connector, identity, redfish_version)
|
||||
|
||||
|
||||
class FabricCollection(base.ResourceCollectionBase):
|
||||
|
||||
@property
|
||||
def _resource_type(self):
|
||||
return Fabric
|
||||
|
||||
def __init__(self, connector, path, redfish_version=None):
|
||||
"""A class representing a FabricCollection
|
||||
|
||||
:param connector: A Connector instance
|
||||
:param path: The canonical path to the Fabric collection resource
|
||||
:param redfish_version: The version of RedFish. Used to construct
|
||||
the object according to schema of the given version.
|
||||
"""
|
||||
super(FabricCollection, self).__init__(connector, path,
|
||||
redfish_version)
|
47
sushy/resources/fabric/mappings.py
Normal file
47
sushy/resources/fabric/mappings.py
Normal file
@ -0,0 +1,47 @@
|
||||
# Copyright 2017 Red Hat, 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.fabric import constants as fab_cons
|
||||
from sushy import utils
|
||||
|
||||
FABRIC_TYPE_VALUE_MAP = {
|
||||
'AHCI': fab_cons.FABRIC_TYPE_AHCI,
|
||||
'FC': fab_cons.FABRIC_TYPE_FC,
|
||||
'FCP': fab_cons.FABRIC_TYPE_FCP,
|
||||
'FCoE': fab_cons.FABRIC_TYPE_FCoE,
|
||||
'FICON': fab_cons.FABRIC_TYPE_FICON,
|
||||
'FTP': fab_cons.FABRIC_TYPE_FTP,
|
||||
'HTTP': fab_cons.FABRIC_TYPE_HTTP,
|
||||
'HTTPS': fab_cons.FABRIC_TYPE_HTTPS,
|
||||
'I2C': fab_cons.FABRIC_TYPE_I2C,
|
||||
'NFSv3': fab_cons.FABRIC_TYPE_NFSv3,
|
||||
'NFSv4': fab_cons.FABRIC_TYPE_NFSv4,
|
||||
'NVMe': fab_cons.FABRIC_TYPE_NVMe,
|
||||
'NVMeOverFabrics': fab_cons.FABRIC_TYPE_NVMeOverFabrics,
|
||||
'OEM': fab_cons.FABRIC_TYPE_OEM,
|
||||
'PCIe': fab_cons.FABRIC_TYPE_PCIe,
|
||||
'RoCE': fab_cons.FABRIC_TYPE_RoCE,
|
||||
'RoCEv2': fab_cons.FABRIC_TYPE_RoCEv2,
|
||||
'SAS': fab_cons.FABRIC_TYPE_SAS,
|
||||
'SATA': fab_cons.FABRIC_TYPE_SATA,
|
||||
'SFTP': fab_cons.FABRIC_TYPE_SFTP,
|
||||
'SMB': fab_cons.FABRIC_TYPE_SMB,
|
||||
'UHCI': fab_cons.FABRIC_TYPE_UHCI,
|
||||
'USB': fab_cons.FABRIC_TYPE_USB,
|
||||
'iSCSI': fab_cons.FABRIC_TYPE_iSCSI,
|
||||
'iWARP': fab_cons.FABRIC_TYPE_iWARP,
|
||||
}
|
||||
|
||||
FABRIC_TYPE_VALUE_MAP_REV = utils.revert_dictionary(FABRIC_TYPE_VALUE_MAP)
|
29
sushy/tests/unit/json_samples/fabric.json
Normal file
29
sushy/tests/unit/json_samples/fabric.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"@odata.type": "#Fabric.v1_0_3.Fabric",
|
||||
"Id": "SAS",
|
||||
"Name": "SAS Fabric",
|
||||
"FabricType": "SAS",
|
||||
"Description": "A SAS Fabric with redundant switches.",
|
||||
"Status": {
|
||||
"State": "Enabled",
|
||||
"Health": "OK"
|
||||
},
|
||||
"Zones": {
|
||||
"@odata.id": "/redfish/v1/Fabrics/SAS/Zones"
|
||||
},
|
||||
"Endpoints": {
|
||||
"@odata.id": "/redfish/v1/Fabrics/SAS/Endpoints"
|
||||
},
|
||||
"Switches": {
|
||||
"@odata.id": "/redfish/v1/Fabrics/SAS/Switches"
|
||||
},
|
||||
"Links": {
|
||||
"Oem": {}
|
||||
},
|
||||
"Actions": {
|
||||
"Oem": {}
|
||||
},
|
||||
"Oem": {},
|
||||
"@odata.context": "/redfish/v1/$metadata#Fabric.Fabric",
|
||||
"@odata.id": "/redfish/v1/Fabrics/SAS"
|
||||
}
|
16
sushy/tests/unit/json_samples/fabric_collection.json
Normal file
16
sushy/tests/unit/json_samples/fabric_collection.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"@odata.type": "#FabricCollection.FabricCollection",
|
||||
"Name": "Fabric Collection",
|
||||
"Members@odata.count": 2,
|
||||
"Members": [
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Fabrics/SAS1"
|
||||
},
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Fabrics/SAS2"
|
||||
}
|
||||
],
|
||||
"@odata.context": "/redfish/v1/$metadata#FabricCollection.FabricCollection",
|
||||
"@odata.id": "/redfish/v1/Fabrics",
|
||||
"@Redfish.Copyright": "Copyright 2014-2017 Distributed Management Task Force, Inc. (DMTF). For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright."
|
||||
}
|
@ -21,6 +21,9 @@
|
||||
"Managers": {
|
||||
"@odata.id": "/redfish/v1/Managers"
|
||||
},
|
||||
"Fabrics": {
|
||||
"@odata.id": "/redfish/v1/Fabrics"
|
||||
},
|
||||
"Tasks": {
|
||||
"@odata.id": "/redfish/v1/TaskService"
|
||||
},
|
||||
|
0
sushy/tests/unit/resources/fabric/__init__.py
Normal file
0
sushy/tests/unit/resources/fabric/__init__.py
Normal file
79
sushy/tests/unit/resources/fabric/test_fabric.py
Normal file
79
sushy/tests/unit/resources/fabric/test_fabric.py
Normal file
@ -0,0 +1,79 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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
|
||||
|
||||
import sushy
|
||||
from sushy.resources.fabric import fabric
|
||||
from sushy.tests.unit import base
|
||||
|
||||
|
||||
class FabricTestCase(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(FabricTestCase, self).setUp()
|
||||
self.conn = mock.Mock()
|
||||
with open('sushy/tests/unit/json_samples/fabric.json') as f:
|
||||
self.conn.get.return_value.json.return_value = json.load(f)
|
||||
|
||||
self.fabric = fabric.Fabric(self.conn, '/redfish/v1/Fabrics/SAS',
|
||||
redfish_version='1.0.3')
|
||||
|
||||
def test__parse_attributes(self):
|
||||
# | WHEN |
|
||||
self.fabric._parse_attributes()
|
||||
# | THEN |
|
||||
self.assertEqual('1.0.3', self.fabric.redfish_version)
|
||||
self.assertEqual('SAS', self.fabric.identity)
|
||||
self.assertEqual('SAS Fabric', self.fabric.name)
|
||||
self.assertEqual('A SAS Fabric with redundant switches.',
|
||||
self.fabric.description)
|
||||
self.assertEqual(sushy.FABRIC_TYPE_SAS,
|
||||
self.fabric.fabric_type)
|
||||
self.assertEqual(sushy.STATE_ENABLED, self.fabric.status.state)
|
||||
self.assertEqual(sushy.HEALTH_OK, self.fabric.status.health)
|
||||
|
||||
|
||||
class FabricCollectionTestCase(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(FabricCollectionTestCase, self).setUp()
|
||||
self.conn = mock.Mock()
|
||||
with open('sushy/tests/unit/json_samples/'
|
||||
'fabric_collection.json') as f:
|
||||
self.conn.get.return_value.json.return_value = json.load(f)
|
||||
self.fabric = fabric.FabricCollection(
|
||||
self.conn, '/redfish/v1/Fabrics', redfish_version='1.0.3')
|
||||
|
||||
@mock.patch.object(fabric, 'Fabric', autospec=True)
|
||||
def test_get_member(self, fabric_mock):
|
||||
self.fabric.get_member('/redfish/v1/Fabrics/SAS1')
|
||||
fabric_mock.assert_called_once_with(
|
||||
self.fabric._conn, '/redfish/v1/Fabrics/SAS1',
|
||||
redfish_version=self.fabric.redfish_version)
|
||||
|
||||
@mock.patch.object(fabric, 'Fabric', autospec=True)
|
||||
def test_get_members(self, fabric_mock):
|
||||
members = self.fabric.get_members()
|
||||
calls = [
|
||||
mock.call(self.fabric._conn, '/redfish/v1/Fabrics/SAS1',
|
||||
redfish_version=self.fabric.redfish_version),
|
||||
mock.call(self.fabric._conn, '/redfish/v1/Fabrics/SAS2',
|
||||
redfish_version=self.fabric.redfish_version)
|
||||
]
|
||||
fabric_mock.assert_has_calls(calls)
|
||||
self.assertIsInstance(members, list)
|
||||
self.assertEqual(2, len(members))
|
@ -22,6 +22,7 @@ from sushy import exceptions
|
||||
from sushy import main
|
||||
from sushy.resources.chassis import chassis
|
||||
from sushy.resources.compositionservice import compositionservice
|
||||
from sushy.resources.fabric import fabric
|
||||
from sushy.resources.manager import manager
|
||||
from sushy.resources.registry import message_registry_file
|
||||
from sushy.resources.sessionservice import session
|
||||
@ -67,6 +68,7 @@ class MainTestCase(base.TestCase):
|
||||
self.assertEqual('/redfish/v1/Systems', self.root._systems_path)
|
||||
self.assertEqual('/redfish/v1/Managers', self.root._managers_path)
|
||||
self.assertEqual('/redfish/v1/Chassis', self.root._chassis_path)
|
||||
self.assertEqual('/redfish/v1/Fabrics', self.root._fabrics_path)
|
||||
self.assertEqual('/redfish/v1/SessionService',
|
||||
self.root._session_service_path)
|
||||
self.assertEqual('/redfish/v1/CompositionService',
|
||||
@ -118,6 +120,20 @@ class MainTestCase(base.TestCase):
|
||||
self.root._conn, '/redfish/v1/Chassis',
|
||||
redfish_version=self.root.redfish_version)
|
||||
|
||||
@mock.patch.object(fabric, 'Fabric', autospec=True)
|
||||
def test_get_fabric(self, mock_fabric):
|
||||
self.root.get_fabric('fake-fabric-id')
|
||||
mock_fabric.assert_called_once_with(
|
||||
self.root._conn, 'fake-fabric-id',
|
||||
redfish_version=self.root.redfish_version)
|
||||
|
||||
@mock.patch.object(fabric, 'FabricCollection', autospec=True)
|
||||
def test_get_fabric_collection(self, fabric_collection_mock):
|
||||
self.root.get_fabric_collection()
|
||||
fabric_collection_mock.assert_called_once_with(
|
||||
self.root._conn, '/redfish/v1/Fabrics',
|
||||
redfish_version=self.root.redfish_version)
|
||||
|
||||
@mock.patch.object(manager, 'ManagerCollection', autospec=True)
|
||||
def test_get_manager_collection(self, ManagerCollection_mock):
|
||||
self.root.get_manager_collection()
|
||||
@ -205,6 +221,11 @@ class BareMinimumMainTestCase(base.TestCase):
|
||||
exceptions.MissingAttributeError,
|
||||
'Chassis/@odata.id', self.root.get_chassis_collection)
|
||||
|
||||
def test_get_fabric_collection_when_fabrics_attr_absent(self):
|
||||
self.assertRaisesRegex(
|
||||
exceptions.MissingAttributeError,
|
||||
'Fabrics/@odata.id', self.root.get_fabric_collection)
|
||||
|
||||
def test_get_session_service_when_sessionservice_attr_absent(self):
|
||||
self.assertRaisesRegex(
|
||||
exceptions.MissingAttributeError,
|
||||
|
Loading…
Reference in New Issue
Block a user