Merge "Add new command to show fabric details"

This commit is contained in:
Jenkins 2017-09-21 17:36:41 +00:00 committed by Gerrit Code Review
commit 442b05b73c
7 changed files with 198 additions and 2 deletions

View File

@ -28,6 +28,8 @@ def extract_attr(redfish_obj):
return redfish_obj
if isinstance(redfish_obj, list):
return [extract_attr(i) for i in redfish_obj]
if isinstance(redfish_obj, tuple):
return tuple(extract_attr(i) for i in redfish_obj)
if isinstance(redfish_obj, dict):
return {i: extract_attr(redfish_obj[i]) for i in redfish_obj}

View File

@ -13,6 +13,8 @@
# under the License.
#
import json
from rsdclient.common import command
@ -24,3 +26,22 @@ class ListFabric(command.Command):
rsd_client = self.app.client_manager.rsd
fabric_list = rsd_client.fabric.list()
print(fabric_list)
class ShowFabric(command.Command):
_description = "Display fabric details"
def get_parser(self, prog_name):
parser = super(ShowFabric, self).get_parser(prog_name)
parser.add_argument(
'fabric',
metavar='<fabric>',
help='ID of the fabric.')
return parser
def take_action(self, parsed_args):
self.log.debug("take_action(%s)", parsed_args)
rsd_client = self.app.client_manager.rsd
fabric_detail = rsd_client.fabric.show(parsed_args.fabric)
print("{0}".format(json.dumps(fabric_detail, indent=2)))

View File

@ -190,3 +190,98 @@ class FakeStorageSerice(object):
self.physical_drives.get_members.return_value = [FakePhysicalDrive()]
self.logical_drives = mock.Mock()
self.logical_drives.get_members.return_value = [FakeLogicalDrive()]
FAKE_FABRIC_PYTHON_DICT = {
'description': 'PCIe Fabric',
'fabric_type': 'PCIe',
'identity': 'PCIe',
'max_zones': 5,
'name': 'PCIe Fabric',
'zones': [{
'description': 'PCIe Zone 1',
'identity': '1',
'links': {
'endpoint_identities': (
'/redfish/v1/Fabrics/PCIe/Endpoints/HostRootComplex1',
'/redfish/v1/Fabrics/PCIe/Endpoints/NVMeDrivePF2'
)
},
'name': 'PCIe Zone 1'
}],
'endpoints': [{
'connected_entities': [{
'entity_link': '/redfish/v1/Chassis/PCIeSwitch1/Drives/Disk.Bay.0',
'entity_role': 'Target',
'entity_type': 'Drive',
'identifiers': [{
'name': '00000000-0000-0000-0000-000000000000',
'name_format': 'UUID'
}]
}],
'description': 'The PCIe Physical function of an 850GB NVMe drive',
'host_reservation_memory': 1000,
'identifiers': [{
'name': '00000000-0000-0000-0000-000000000000',
'name_format': 'UUID'
}],
'identity': 'NVMeDrivePF1',
'name': 'NVMe Drive',
'protocol': 'PCIe',
'redfish_version': '1.0.2',
'redundancy': []
}]
}
class FakeEndpoint(object):
def __init__(self):
self.connected_entities = [{
'entity_link': '/redfish/v1/Chassis/PCIeSwitch1/Drives/Disk.Bay.0',
'entity_role': 'Target',
'entity_type': 'Drive',
'identifiers': [{
'name': '00000000-0000-0000-0000-000000000000',
'name_format': 'UUID'
}]
}]
self.description = 'The PCIe Physical function of an 850GB NVMe drive'
self.host_reservation_memory = 1000
self.identifiers = [{
'name': '00000000-0000-0000-0000-000000000000',
'name_format': 'UUID'
}]
self.identity = 'NVMeDrivePF1'
self.name = 'NVMe Drive'
self.protocol = 'PCIe'
self.redfish_version = '1.0.2'
self.redundancy = []
class FakeZone(object):
def __init__(self):
self.description = 'PCIe Zone 1'
self.identity = '1'
self.name = 'PCIe Zone 1'
self.links = {
'endpoint_identities': (
'/redfish/v1/Fabrics/PCIe/Endpoints/HostRootComplex1',
'/redfish/v1/Fabrics/PCIe/Endpoints/NVMeDrivePF2'
)
}
class FakeFabric(object):
def __init__(self):
self.description = 'PCIe Fabric'
self.fabric_type = 'PCIe'
self.identity = 'PCIe'
self.max_zones = 5
self.name = 'PCIe Fabric'
self.endpoints = mock.Mock()
self.endpoints.get_members.return_value = [FakeEndpoint()]
self.zones = mock.Mock()
self.zones.get_members.return_value = [FakeZone()]

View File

@ -0,0 +1,58 @@
# Copyright 2017 Intel, Inc.
#
# 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 mock
import testtools
from rsdclient.tests.common import fakes
from rsdclient.v1 import fabric
class FabricTest(testtools.TestCase):
def setUp(self):
super(FabricTest, self).setUp()
self.client = mock.Mock()
self.client._fabrics_path = '/redfish/v1/Fabrics'
self.mgr = fabric.FabricManager(self.client)
def test_list_fabric(self):
mock_fabric_collection = mock.Mock()
mock_fabric_collection.members_identities = \
('/redfish/v1/Fabrics/PCIe',)
self.mgr.client.get_fabric_collection.return_value = \
mock_fabric_collection
self.mgr.client.get_fabric.return_value = fakes.FakeFabric()
expected = (
'+----------+-------------+-------------+-------------+\n'
'| Identity | Name | Fabric_Type | Description |\n'
'+----------+-------------+-------------+-------------+\n'
'| PCIe | PCIe Fabric | PCIe | PCIe Fabric |\n'
'+----------+-------------+-------------+-------------+')
result = self.mgr.list()
self.mgr.client.get_fabric_collection.assert_called_once()
self.mgr.client.get_fabric.assert_called_once_with(
'/redfish/v1/Fabrics/PCIe')
self.assertEqual(str(result), expected)
def test_show_fabric(self):
self.client.get_fabric.return_value = fakes.FakeFabric()
result = self.mgr.show('PCIe')
expected = fakes.FAKE_FABRIC_PYTHON_DICT
self.mgr.client.get_fabric.assert_called_once_with(
'/redfish/v1/Fabrics/PCIe')
self.assertEqual(result, expected)

View File

@ -20,10 +20,10 @@ from rsdclient.tests.common import fakes
from rsdclient.v1 import storage_service
class NodeTest(testtools.TestCase):
class StorageServiceTest(testtools.TestCase):
def setUp(self):
super(NodeTest, self).setUp()
super(StorageServiceTest, self).setUp()
self.client = mock.Mock()
self.client._storage_service_path = '/redfish/v1/Services'
self.mgr = storage_service.StorageServiceManager(self.client)

View File

@ -13,6 +13,8 @@
# under the License.
#
import os
from rsdclient.common import base
from rsdclient.common import utils
@ -24,6 +26,9 @@ class FabricManager(base.Manager):
super(FabricManager, self).__init__(*args, **kwargs)
self.fabrics_path = self.client._fabrics_path
def _get_fabric_uri(self, fabric_id):
return os.path.join(self.fabrics_path, fabric_id)
def list(self):
fabric_collection = self.client.get_fabric_collection()
fabrics = [utils.extract_attr(self.client.get_fabric(fabric_uri))
@ -31,3 +36,17 @@ class FabricManager(base.Manager):
fabric_info_table = utils.print_dict(
fabrics, ["Identity", "Name", "Fabric_Type", "Description"])
return fabric_info_table
def show(self, fabric_id):
fabric = self.client.get_fabric(self._get_fabric_uri(fabric_id))
fabric_dict = utils.extract_attr(fabric)
# Append sub-items attributions
fabric_dict['endpoints'] = [
utils.extract_attr(item)
for item in fabric.endpoints.get_members()]
fabric_dict['zones'] = [
utils.extract_attr(item)
for item in fabric.zones.get_members()]
return fabric_dict

View File

@ -39,6 +39,7 @@ openstack.rsd.v1 =
rsd_storage_show = rsdclient.osc.v1.storage_service:ShowStorageServices
rsd_fabric_list = rsdclient.osc.v1.fabric:ListFabric
rsd_fabric_show = rsdclient.osc.v1.fabric:ShowFabric
[build_sphinx]
all-files = 1