Add another protocol "NVMeOverFabrics" of remote drive
It support another protocol "NVMeOverFabrics" of remote storage drive beside "iSCSI" when attach it to composed node in RSD 2.3. Change-Id: I7089e98469352d30d7ab459741e465b354d2040f
This commit is contained in:
parent
11b975dd44
commit
e2ff3b548e
35
rsd_lib/resources/v2_3/__init__.py
Normal file
35
rsd_lib/resources/v2_3/__init__.py
Normal file
@ -0,0 +1,35 @@
|
||||
# Copyright 2018 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 rsd_lib.resources import v2_2
|
||||
|
||||
from rsd_lib.resources.v2_3.node import node
|
||||
|
||||
|
||||
class RSDLibV2_3(v2_2.RSDLibV2_2):
|
||||
|
||||
# Override these two variables inherited from v2.2. The corresponding
|
||||
# services don't exist in RSD v2.3
|
||||
_storage_service_path = None
|
||||
_telemetry_service_path = None
|
||||
|
||||
def get_node(self, identity):
|
||||
"""Given the identity return a Node object
|
||||
|
||||
:param identity: The identity of the Node resource
|
||||
:returns: The Node object
|
||||
"""
|
||||
return node.Node(self._conn, identity,
|
||||
redfish_version=self.redfish_version)
|
0
rsd_lib/resources/v2_3/node/__init__.py
Normal file
0
rsd_lib/resources/v2_3/node/__init__.py
Normal file
45
rsd_lib/resources/v2_3/node/node.py
Normal file
45
rsd_lib/resources/v2_3/node/node.py
Normal file
@ -0,0 +1,45 @@
|
||||
# Copyright 2018 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 exceptions
|
||||
|
||||
from rsd_lib.resources.v2_1.node import node as v2_1_node
|
||||
|
||||
|
||||
class Node(v2_1_node.Node):
|
||||
|
||||
def attach_endpoint(self, endpoint, protocol=None):
|
||||
"""Attach endpoint from available pool to composed node
|
||||
|
||||
:param endpoint: Link to endpoint to attach.
|
||||
:param protocol: Protocol of the remote drive.
|
||||
:raises: InvalidParameterValueError
|
||||
"""
|
||||
attach_action = self._get_attach_endpoint_action_element()
|
||||
valid_endpoints = attach_action.allowed_values
|
||||
target_uri = attach_action.target_uri
|
||||
|
||||
if endpoint and endpoint not in valid_endpoints:
|
||||
raise exceptions.InvalidParameterValueError(
|
||||
parameter='endpoint', value=endpoint,
|
||||
valid_values=valid_endpoints)
|
||||
|
||||
data = {}
|
||||
if endpoint is not None:
|
||||
data['Resource'] = {'@odata.id': endpoint}
|
||||
if protocol is not None:
|
||||
data['Protocol'] = protocol
|
||||
|
||||
self._conn.post(target_uri, data=data)
|
117
rsd_lib/tests/unit/json_samples/v2_3/node.json
Normal file
117
rsd_lib/tests/unit/json_samples/v2_3/node.json
Normal file
@ -0,0 +1,117 @@
|
||||
{
|
||||
"@odata.context": "/redfish/v1/$metadata#Nodes/Members/$entity",
|
||||
"@odata.id": "/redfish/v1/Nodes/Node1",
|
||||
"@odata.type": "#ComposedNode.1.1.0.ComposedNode",
|
||||
"Id": "Node1",
|
||||
"Name": "Composed Node",
|
||||
"Description": "Node #1",
|
||||
"UUID": "fa39d108-7d70-400a-9db2-6940375c31c2",
|
||||
"PowerState": "On",
|
||||
"Status": {
|
||||
"State": "Enabled",
|
||||
"Health": "OK",
|
||||
"HealthRollup": "OK"
|
||||
},
|
||||
"Processors": {
|
||||
"Count": 2,
|
||||
"Model": "Multi-Core Intel(R) Xeon(R) processor 7xxx Series",
|
||||
"Status": {
|
||||
"State": "Enabled",
|
||||
"Health": "OK",
|
||||
"HealthRollup" : "OK"
|
||||
}
|
||||
},
|
||||
"Memory": {
|
||||
"TotalSystemMemoryGiB": 32,
|
||||
"Status": {
|
||||
"State": "Enabled",
|
||||
"Health": "OK",
|
||||
"HealthRollup" : "OK"
|
||||
}
|
||||
},
|
||||
"ComposedNodeState": "Allocated",
|
||||
"Boot": {
|
||||
"BootSourceOverrideEnabled": "Disabled",
|
||||
"BootSourceOverrideTarget": "None",
|
||||
"BootSourceOverrideTarget@Redfish.AllowableValues": [
|
||||
"None",
|
||||
"Pxe",
|
||||
"Hdd",
|
||||
"RemoteDrive"
|
||||
],
|
||||
"BootSourceOverrideMode": "Legacy",
|
||||
"BootSourceOverrideMode@Redfish.AllowableValues": ["Legacy",
|
||||
"UEFI"]
|
||||
},
|
||||
"Oem": {},
|
||||
"Links": {
|
||||
"ComputerSystem": {
|
||||
"@odata.id": "/redfish/v1/Systems/System1"
|
||||
},
|
||||
"Processors": [
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Systems/System1/Processors/CPU1"
|
||||
}
|
||||
],
|
||||
"Memory": [
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Systems/System1/Memory/Dimm1"
|
||||
}
|
||||
],
|
||||
"EthernetInterfaces": [
|
||||
{
|
||||
"@odata.id":
|
||||
"/redfish/v1/Systems/System1/EthernetInterfaces/LAN1"
|
||||
}
|
||||
],
|
||||
"LocalDrives": [
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Chassis/Blade1/Drives/1"
|
||||
}
|
||||
],
|
||||
"RemoteDrives": [
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Services/RSS1/Targets/target1"
|
||||
}
|
||||
],
|
||||
"ManagedBy": [
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Managers/PODM"
|
||||
}
|
||||
],
|
||||
"Oem": {}
|
||||
},
|
||||
"Actions": {
|
||||
"#ComposedNode.Reset": {
|
||||
"target": "/redfish/v1/Nodes/Node1/Actions/ComposedNode.Reset",
|
||||
"ResetType@Redfish.AllowableValues": [
|
||||
"On",
|
||||
"ForceOff",
|
||||
"GracefulRestart",
|
||||
"ForceRestart",
|
||||
"Nmi",
|
||||
"ForceOn",
|
||||
"PushPowerButton",
|
||||
"GracefulShutdown"
|
||||
]
|
||||
},
|
||||
"#ComposedNode.Assemble": {
|
||||
"target": "/redfish/v1/Nodes/Node1/Actions/ComposedNode.Assemble"
|
||||
},
|
||||
"#ComposedNode.AttachEndpoint": {
|
||||
"target":
|
||||
"/redfish/v1/Nodes/Node1/Actions/ComposedNode.AttachEndpoint",
|
||||
"Resource@Redfish.AllowableValues": [
|
||||
{"@odata.id":"/redfish/v1/Chassis/PCIeSwitchChassis/Drives/Disk.Bay.1"},
|
||||
{"@odata.id":"/redfish/v1/StorageServices/NVMeoE1/Volumes/1"}
|
||||
]
|
||||
},
|
||||
"#ComposedNode.DetachEndpoint": {
|
||||
"target":
|
||||
"/redfish/v1/Nodes/Node1/Actions/ComposedNode.DetachEndpoint",
|
||||
"Resource@Redfish.AllowableValues": [
|
||||
{"@odata.id":"/redfish/v1/Chassis/PCIeSwitchChassis/Drives/Disk.Bay.3"}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
41
rsd_lib/tests/unit/json_samples/v2_3/root.json
Normal file
41
rsd_lib/tests/unit/json_samples/v2_3/root.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"@odata.context": "/redfish/v1/$metadata#ServiceRoot.ServiceRoot",
|
||||
"@odata.id": "/redfish/v1/",
|
||||
"@odata.type": "#ServiceRoot.v1_1_1.ServiceRoot",
|
||||
"Id": "RootService",
|
||||
"Name": "Root Service",
|
||||
"Description": "description-as-string",
|
||||
"RedfishVersion": "1.1.0",
|
||||
"UUID": "92384634-2938-2342-8820-489239905423",
|
||||
"Systems": {
|
||||
"@odata.id": "/redfish/v1/Systems"
|
||||
},
|
||||
"Chassis": {
|
||||
"@odata.id": "/redfish/v1/Chassis"
|
||||
},
|
||||
"Managers": {
|
||||
"@odata.id": "/redfish/v1/Managers"
|
||||
},
|
||||
"EventService": {
|
||||
"@odata.id": "/redfish/v1/EventService"
|
||||
},
|
||||
"Fabrics": {
|
||||
"@odata.id": "/redfish/v1/Fabrics"
|
||||
},
|
||||
"StorageServices": {
|
||||
"@odata.id": "/redfish/v1/StorageSerices"
|
||||
},
|
||||
"Oem": {
|
||||
"Intel_RackScale": {
|
||||
"@odata.type": "#Intel.Oem.ServiceRoot",
|
||||
"ApiVersion": "2.3.0",
|
||||
"Nodes": {
|
||||
"@odata.id": "/redfish/v1/Nodes"
|
||||
},
|
||||
"EthernetSwitches": {
|
||||
"@odata.id": "/redfish/v1/EthernetSwitches"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Links": {}
|
||||
}
|
0
rsd_lib/tests/unit/resources/v2_3/__init__.py
Normal file
0
rsd_lib/tests/unit/resources/v2_3/__init__.py
Normal file
0
rsd_lib/tests/unit/resources/v2_3/node/__init__.py
Normal file
0
rsd_lib/tests/unit/resources/v2_3/node/__init__.py
Normal file
58
rsd_lib/tests/unit/resources/v2_3/node/test_node.py
Normal file
58
rsd_lib/tests/unit/resources/v2_3/node/test_node.py
Normal file
@ -0,0 +1,58 @@
|
||||
# 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.
|
||||
|
||||
import json
|
||||
import mock
|
||||
import testtools
|
||||
|
||||
from sushy import exceptions
|
||||
|
||||
from rsd_lib.resources.v2_3.node import node
|
||||
|
||||
|
||||
class NodeTestCase(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(NodeTestCase, self).setUp()
|
||||
self.conn = mock.Mock()
|
||||
with open('rsd_lib/tests/unit/json_samples/v2_3/node.json', 'r') as f:
|
||||
self.conn.get.return_value.json.return_value = json.loads(f.read())
|
||||
|
||||
self.node_inst = node.Node(
|
||||
self.conn, '/redfish/v1/Nodes/Node1',
|
||||
redfish_version='1.0.2')
|
||||
|
||||
def test_attach_endpoint(self):
|
||||
self.node_inst.attach_endpoint(
|
||||
endpoint='/redfish/v1/StorageServices/NVMeoE1/Volumes/1',
|
||||
protocol='NVMeOverFabrics')
|
||||
self.node_inst._conn.post.assert_called_once_with(
|
||||
'/redfish/v1/Nodes/Node1/Actions/ComposedNode.AttachEndpoint',
|
||||
data={'Resource': {'@odata.id': '/redfish/v1/'
|
||||
'StorageServices/NVMeoE1/Volumes/1'},
|
||||
'Protocol': 'NVMeOverFabrics'})
|
||||
|
||||
def test_attach_endpoint_invalid_parameter(self):
|
||||
self.assertRaises(exceptions.InvalidParameterValueError,
|
||||
self.node_inst.attach_endpoint,
|
||||
endpoint='invalid')
|
||||
|
||||
def test_attach_endpoint_only_with_resource_uri(self):
|
||||
self.node_inst.attach_endpoint(
|
||||
endpoint='/redfish/v1/StorageServices/NVMeoE1/Volumes/1')
|
||||
self.node_inst._conn.post.assert_called_once_with(
|
||||
'/redfish/v1/Nodes/Node1/Actions/ComposedNode.AttachEndpoint',
|
||||
data={'Resource': {'@odata.id': '/redfish/v1/'
|
||||
'StorageServices/NVMeoE1/Volumes/1'}})
|
125
rsd_lib/tests/unit/resources/v2_3/test_rsdlib_v2_3.py
Normal file
125
rsd_lib/tests/unit/resources/v2_3/test_rsdlib_v2_3.py
Normal file
@ -0,0 +1,125 @@
|
||||
# Copyright 2018 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.
|
||||
|
||||
import json
|
||||
import mock
|
||||
import testtools
|
||||
|
||||
from rsd_lib.resources.v2_1.chassis import chassis as v2_1_chassis
|
||||
from rsd_lib.resources.v2_1.fabric import fabric as v2_1_fabric
|
||||
from rsd_lib.resources.v2_1.node import node as v2_1_node
|
||||
from rsd_lib.resources.v2_2.system import system as v2_2_system
|
||||
from rsd_lib.resources import v2_3
|
||||
from rsd_lib.resources.v2_3.node import node as v2_3_node
|
||||
|
||||
|
||||
class RSDLibV2_3TestCase(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(RSDLibV2_3TestCase, self).setUp()
|
||||
self.conn = mock.Mock()
|
||||
with open('rsd_lib/tests/unit/json_samples/v2_3/root.json', 'r') as f:
|
||||
self.conn.get.return_value.json.return_value = json.loads(f.read())
|
||||
self.rsd = v2_3.RSDLibV2_3(self.conn)
|
||||
|
||||
def test__parse_attributes(self):
|
||||
self.rsd._parse_attributes()
|
||||
self.assertEqual("2.3.0", self.rsd._rsd_api_version)
|
||||
self.assertEqual("1.1.0", self.rsd._redfish_version)
|
||||
self.assertEqual("/redfish/v1/Systems", self.rsd._systems_path)
|
||||
self.assertEqual("/redfish/v1/Nodes", self.rsd._nodes_path)
|
||||
self.assertEqual("/redfish/v1/Chassis", self.rsd._chassis_path)
|
||||
self.assertEqual("/redfish/v1/Fabrics", self.rsd._fabrics_path)
|
||||
self.assertEqual(None, self.rsd._storage_service_path)
|
||||
self.assertEqual(None, self.rsd._telemetry_service_path)
|
||||
|
||||
@mock.patch.object(v2_2_system, 'SystemCollection', autospec=True)
|
||||
def test_get_system_collection(self, mock_system_collection):
|
||||
self.rsd.get_system_collection()
|
||||
mock_system_collection.assert_called_once_with(
|
||||
self.rsd._conn, '/redfish/v1/Systems',
|
||||
redfish_version=self.rsd.redfish_version)
|
||||
|
||||
@mock.patch.object(v2_2_system, 'System', autospec=True)
|
||||
def test_get_system(self, mock_system):
|
||||
self.rsd.get_system('fake-system-id')
|
||||
mock_system.assert_called_once_with(
|
||||
self.rsd._conn, 'fake-system-id',
|
||||
redfish_version=self.rsd.redfish_version)
|
||||
|
||||
@mock.patch.object(v2_1_node, 'NodeCollection', autospec=True)
|
||||
def test_get_node_collection(self, mock_node_collection):
|
||||
self.rsd.get_node_collection()
|
||||
mock_node_collection.assert_called_once_with(
|
||||
self.rsd._conn, '/redfish/v1/Nodes',
|
||||
redfish_version=self.rsd.redfish_version)
|
||||
|
||||
@mock.patch.object(v2_3_node, 'Node', autospec=True)
|
||||
def test_get_node(self, mock_node):
|
||||
self.rsd.get_node('fake-node-id')
|
||||
mock_node.assert_called_once_with(
|
||||
self.rsd._conn, 'fake-node-id',
|
||||
redfish_version=self.rsd.redfish_version)
|
||||
|
||||
@mock.patch.object(v2_1_fabric, 'FabricCollection', autospec=True)
|
||||
def test_get_fabric_collection(self, mock_fabric_collection):
|
||||
self.rsd.get_fabric_collection()
|
||||
mock_fabric_collection.assert_called_once_with(
|
||||
self.rsd._conn, '/redfish/v1/Fabrics',
|
||||
redfish_version=self.rsd.redfish_version)
|
||||
|
||||
@mock.patch.object(v2_1_fabric, 'Fabric', autospec=True)
|
||||
def test_get_fabric(self, mock_fabric):
|
||||
self.rsd.get_fabric('fake-fabric-id')
|
||||
mock_fabric.assert_called_once_with(
|
||||
self.rsd._conn, 'fake-fabric-id',
|
||||
redfish_version=self.rsd.redfish_version)
|
||||
|
||||
@mock.patch.object(v2_1_chassis, 'ChassisCollection', autospec=True)
|
||||
def test_get_chassis_collection(self, mock_chassis_collection):
|
||||
self.rsd.get_chassis_collection()
|
||||
mock_chassis_collection.assert_called_once_with(
|
||||
self.rsd._conn, '/redfish/v1/Chassis',
|
||||
redfish_version=self.rsd.redfish_version)
|
||||
|
||||
@mock.patch.object(v2_1_chassis, 'Chassis', autospec=True)
|
||||
def test_get_chassis(self, mock_chassis):
|
||||
self.rsd.get_chassis('fake-chassis-id')
|
||||
mock_chassis.assert_called_once_with(
|
||||
self.rsd._conn, 'fake-chassis-id',
|
||||
redfish_version=self.rsd.redfish_version)
|
||||
|
||||
# @mock.patch.object(v2_1_storage_service, 'StorageServiceCollection',
|
||||
# autospec=True)
|
||||
# def test_get_storage_service_collection(self,
|
||||
# mock_storage_service_collection):
|
||||
# self.rsd.get_storage_service_collection()
|
||||
# mock_storage_service_collection.assert_called_once_with(
|
||||
# self.rsd._conn, '/redfish/v1/Services',
|
||||
# redfish_version=self.rsd.redfish_version)
|
||||
|
||||
# @mock.patch.object(v2_1_storage_service, 'StorageService', autospec=True)
|
||||
# def test_get_storage_service(self, mock_storage_service):
|
||||
# self.rsd.get_storage_service('fake-storage-service-id')
|
||||
# mock_storage_service.assert_called_once_with(
|
||||
# self.rsd._conn, 'fake-storage-service-id',
|
||||
# redfish_version=self.rsd.redfish_version)
|
||||
|
||||
# @mock.patch.object(v2_2_telemetry, 'Telemetry', autospec=True)
|
||||
# def test_get_telemetry_service(self, mock_telemetry_service):
|
||||
# self.rsd.get_telemetry_service()
|
||||
# mock_telemetry_service.assert_called_once_with(
|
||||
# self.rsd._conn, '/redfish/v1/TelemetryService',
|
||||
# redfish_version=self.rsd.redfish_version)
|
Loading…
x
Reference in New Issue
Block a user