Update node compose requirements in RSD 2.4
Change-Id: I69ba06f2f1d142acf43ad966aaa7719c0eb0db08
This commit is contained in:
parent
f0c456f916
commit
df2dca3897
@ -1,4 +1,4 @@
|
||||
# Copyright 2018 Intel, Inc.
|
||||
# Copyright 2019 Intel, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
@ -13,9 +13,16 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from jsonschema import validate
|
||||
import logging
|
||||
|
||||
from sushy.resources import base
|
||||
|
||||
from rsd_lib.resources.v2_3.node import node
|
||||
from rsd_lib.resources.v2_4.node import schemas as node_schemas
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AttachEndpointActionField(base.CompositeField):
|
||||
@ -55,3 +62,107 @@ class NodeCollection(node.NodeCollection):
|
||||
the object according to schema of the given version.
|
||||
"""
|
||||
super(NodeCollection, self).__init__(connector, path, redfish_version)
|
||||
|
||||
def _create_compose_request(self, name=None, description=None,
|
||||
processor_req=None, memory_req=None,
|
||||
remote_drive_req=None, local_drive_req=None,
|
||||
ethernet_interface_req=None,
|
||||
security_req=None, total_system_core_req=None,
|
||||
total_system_memory_req=None):
|
||||
|
||||
request = {}
|
||||
|
||||
if name is not None:
|
||||
request['Name'] = name
|
||||
if description is not None:
|
||||
request['Description'] = description
|
||||
|
||||
if processor_req is not None:
|
||||
validate(processor_req,
|
||||
node_schemas.processor_req_schema)
|
||||
request['Processors'] = processor_req
|
||||
|
||||
if memory_req is not None:
|
||||
validate(memory_req,
|
||||
node_schemas.memory_req_schema)
|
||||
request['Memory'] = memory_req
|
||||
|
||||
if remote_drive_req is not None:
|
||||
validate(remote_drive_req,
|
||||
node_schemas.remote_drive_req_schema)
|
||||
request['RemoteDrives'] = remote_drive_req
|
||||
|
||||
if local_drive_req is not None:
|
||||
validate(local_drive_req,
|
||||
node_schemas.local_drive_req_schema)
|
||||
request['LocalDrives'] = local_drive_req
|
||||
|
||||
if ethernet_interface_req is not None:
|
||||
validate(ethernet_interface_req,
|
||||
node_schemas.ethernet_interface_req_schema)
|
||||
request['EthernetInterfaces'] = ethernet_interface_req
|
||||
|
||||
if security_req is not None:
|
||||
validate(security_req,
|
||||
node_schemas.security_req_schema)
|
||||
request['Security'] = security_req
|
||||
|
||||
if total_system_core_req is not None:
|
||||
validate(total_system_core_req,
|
||||
node_schemas.total_system_core_req_schema)
|
||||
request['TotalSystemCoreCount'] = total_system_core_req
|
||||
|
||||
if total_system_memory_req is not None:
|
||||
validate(total_system_memory_req,
|
||||
node_schemas.total_system_memory_req_schema)
|
||||
request['TotalSystemMemoryMiB'] = total_system_memory_req
|
||||
|
||||
return request
|
||||
|
||||
def compose_node(self, name=None, description=None,
|
||||
processor_req=None, memory_req=None,
|
||||
remote_drive_req=None, local_drive_req=None,
|
||||
ethernet_interface_req=None, security_req=None,
|
||||
total_system_core_req=None, total_system_memory_req=None):
|
||||
"""Compose a node from RackScale hardware
|
||||
|
||||
:param name: Name of node
|
||||
:param description: Description of node
|
||||
:param processor_req: JSON for node processors
|
||||
:param memory_req: JSON for node memory modules
|
||||
:param remote_drive_req: JSON for node remote drives
|
||||
:param local_drive_req: JSON for node local drives
|
||||
:param ethernet_interface_req: JSON for node ethernet ports
|
||||
:param security_req: JSON for node security requirements
|
||||
:param total_system_core_req: Total processor cores available in
|
||||
composed node
|
||||
:param total_system_memory_req: Total memory available in composed node
|
||||
:returns: The location of the composed node
|
||||
|
||||
When the 'processor_req' is not none: it need a computer system
|
||||
contains processors whose each processor meet all conditions in the
|
||||
value.
|
||||
|
||||
When the 'total_system_core_req' is not none: it need a computer
|
||||
system contains processors whose cores sum up to number equal or
|
||||
greater than 'total_system_core_req'.
|
||||
|
||||
When both values are not none: it need meet all conditions.
|
||||
|
||||
'memory_req' and 'total_system_memory_req' is the same.
|
||||
"""
|
||||
target_uri = self._get_compose_action_element().target_uri
|
||||
properties = self._create_compose_request(
|
||||
name=name, description=description,
|
||||
processor_req=processor_req,
|
||||
memory_req=memory_req,
|
||||
remote_drive_req=remote_drive_req,
|
||||
local_drive_req=local_drive_req,
|
||||
ethernet_interface_req=ethernet_interface_req,
|
||||
security_req=security_req,
|
||||
total_system_core_req=total_system_core_req,
|
||||
total_system_memory_req=total_system_memory_req)
|
||||
resp = self._conn.post(target_uri, data=properties)
|
||||
LOG.info("Node created at %s", resp.headers['Location'])
|
||||
node_url = resp.headers['Location']
|
||||
return node_url[node_url.find(self._path):]
|
||||
|
248
rsd_lib/resources/v2_4/node/schemas.py
Normal file
248
rsd_lib/resources/v2_4/node/schemas.py
Normal file
@ -0,0 +1,248 @@
|
||||
# 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.
|
||||
|
||||
processor_req_schema = {
|
||||
'type': 'array',
|
||||
'items': [{
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'@odata.type': {'type': 'string'},
|
||||
'Model': {'type': 'string'},
|
||||
'TotalCores': {'type': 'number'},
|
||||
'AchievableSpeedMHz': {'type': 'number'},
|
||||
'InstructionSet': {
|
||||
'type': 'string',
|
||||
'enum': ['x86', 'x86-64', 'IA-64', 'ARM-A32',
|
||||
'ARM-A64', 'MIPS32', 'MIPS64', 'OEM']
|
||||
},
|
||||
'Oem': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'Intel_RackScale': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'Brand': {
|
||||
'type': 'string',
|
||||
'enum': ['E3', 'E5', 'E7', 'X3', 'X5', 'X7',
|
||||
'I3', 'I5', 'I7', 'Silver', 'Gold',
|
||||
'Platinum', 'Unknown']
|
||||
},
|
||||
'Capabilities': {
|
||||
'type': 'array',
|
||||
'items': [{'type': 'string'}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'Resource': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'@odata.id': {'type': 'string'}
|
||||
}
|
||||
},
|
||||
'Chassis': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'@odata.id': {'type': 'string'}
|
||||
}
|
||||
},
|
||||
'ProcessorType': {
|
||||
'type': 'string',
|
||||
'enum': ['CPU', 'FPGA', 'GPU', 'DSP', 'Accelerator', 'OEM']
|
||||
},
|
||||
'Connectivity': {
|
||||
'type': 'array',
|
||||
'items': [{
|
||||
'type': 'string',
|
||||
'enum': ['Local', 'Ethernet', 'RemotePCIe']
|
||||
}]
|
||||
}
|
||||
},
|
||||
'additionalProperties': False,
|
||||
}]
|
||||
}
|
||||
|
||||
memory_req_schema = {
|
||||
'type': 'array',
|
||||
'items': [{
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'@odata.type': {'type': 'string'},
|
||||
'CapacityMiB': {'type': 'number'},
|
||||
'MemoryType': {
|
||||
'type': 'string',
|
||||
'enum': ['DRAM', 'NVDIMM_N', 'NVDIMM_F', 'NVMDIMM_P',
|
||||
'IntelOptane']
|
||||
},
|
||||
'MemoryDeviceType': {
|
||||
'type': 'string',
|
||||
'enum': ['DDR', 'DDR2', 'DDR3', 'DDR4', 'DDR4_SDRAM',
|
||||
'DDR4E_SDRAM', 'LPDDR4_SDRAM', 'DDR3_SDRAM',
|
||||
'LPDDR3_SDRAM', 'DDR2_SDRAM', 'DDR2_SDRAM_FB_DIMM',
|
||||
'DDR2_SDRAM_FB_DIMM_PROBE', 'DDR_SGRAM',
|
||||
'DDR_SDRAM', 'ROM', 'SDRAM', 'EDO',
|
||||
'FastPageMode', 'PipelinedNibble']
|
||||
},
|
||||
'SpeedMHz': {'type': 'number'},
|
||||
'Manufacturer': {'type': 'string'},
|
||||
'DataWidthBits': {'type': 'number'},
|
||||
'Resource': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'@odata.id': {'type': 'string'}
|
||||
}
|
||||
},
|
||||
'Chassis': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'@odata.id': {'type': 'string'}
|
||||
}
|
||||
}
|
||||
},
|
||||
'additionalProperties': False,
|
||||
}]
|
||||
}
|
||||
|
||||
remote_drive_req_schema = {
|
||||
'type': 'array',
|
||||
'items': [{
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'@odata.type': {'type': 'string'},
|
||||
'CapacityGiB': {'type': 'number'},
|
||||
'Protocol': {
|
||||
'type': 'string',
|
||||
'enum': ['iSCSI', 'NVMeOverFabrics']
|
||||
},
|
||||
'Master': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'Type': {
|
||||
'type': 'string',
|
||||
'enum': ['Snapshot', 'Clone']
|
||||
},
|
||||
'Resource': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'@odata.id': {'type': 'string'}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'Resource': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'@odata.id': {'type': 'string'}
|
||||
}
|
||||
}
|
||||
},
|
||||
'additionalProperties': False,
|
||||
}]
|
||||
}
|
||||
|
||||
local_drive_req_schema = {
|
||||
'type': 'array',
|
||||
'items': [{
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'@odata.type': {'type': 'string'},
|
||||
'CapacityGiB': {'type': 'number'},
|
||||
'Type': {
|
||||
'type': 'string',
|
||||
'enum': ['HDD', 'SSD']
|
||||
},
|
||||
'MinRPM': {'type': 'number'},
|
||||
'SerialNumber': {'type': 'string'},
|
||||
'Interface': {
|
||||
'type': 'string',
|
||||
'enum': ['SAS', 'SATA', 'NVMe']
|
||||
},
|
||||
'Resource': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'@odata.id': {'type': 'string'}
|
||||
}
|
||||
},
|
||||
'Chassis': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'@odata.id': {'type': 'string'}
|
||||
}
|
||||
},
|
||||
'FabricSwitch': {'type': 'boolean'}
|
||||
},
|
||||
'additionalProperties': False,
|
||||
}]
|
||||
}
|
||||
|
||||
ethernet_interface_req_schema = {
|
||||
'type': 'array',
|
||||
'items': [{
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'@odata.type': {'type': 'string'},
|
||||
'SpeedMbps': {'type': 'number'},
|
||||
'PrimaryVLAN': {'type': 'number'},
|
||||
'VLANs': {
|
||||
'type': 'array',
|
||||
'additionalItems': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'VLANId': {'type': 'number'},
|
||||
'Tagged': {'type': 'boolean'}
|
||||
}
|
||||
}
|
||||
},
|
||||
'Resource': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'@odata.id': {'type': 'string'}
|
||||
}
|
||||
},
|
||||
'Chassis': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'@odata.id': {'type': 'string'}
|
||||
}
|
||||
}
|
||||
},
|
||||
'additionalProperties': False,
|
||||
}]
|
||||
}
|
||||
|
||||
security_req_schema = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'@odata.type': {'type': 'string'},
|
||||
'TpmPresent': {'type': 'boolean'},
|
||||
'TpmInterfaceType': {'type': 'string'},
|
||||
'TxtEnabled': {'type': 'boolean'},
|
||||
'ClearTPMOnDelete': {'type': 'boolean'},
|
||||
'PersistentMemoryOperationOnDelete': {
|
||||
'type': 'string',
|
||||
'enum': ['PreserveConfiguration', 'SecureErase', 'OverwritePCD']
|
||||
}
|
||||
},
|
||||
'additionalProperties': False,
|
||||
}
|
||||
|
||||
total_system_core_req_schema = {
|
||||
'type': 'number'
|
||||
}
|
||||
|
||||
total_system_memory_req_schema = {
|
||||
'type': 'number'
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2017 Intel, Inc.
|
||||
# Copyright 2019 Intel, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
@ -14,6 +14,7 @@
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
import jsonschema
|
||||
import mock
|
||||
import testtools
|
||||
|
||||
@ -212,6 +213,9 @@ class NodeCollectionTestCase(testtools.TestCase):
|
||||
'r') as f:
|
||||
self.conn.get.return_value = request_fakes.fake_request_get(
|
||||
json.loads(f.read()))
|
||||
self.conn.post.return_value = request_fakes.fake_request_post(
|
||||
None, headers={"Location": "https://localhost:8443/"
|
||||
"redfish/v1/Nodes/1"})
|
||||
|
||||
self.node_col = node.NodeCollection(
|
||||
self.conn, '/redfish/v1/Nodes', redfish_version='1.0.2')
|
||||
@ -238,3 +242,445 @@ class NodeCollectionTestCase(testtools.TestCase):
|
||||
redfish_version=self.node_col.redfish_version)
|
||||
self.assertIsInstance(members, list)
|
||||
self.assertEqual(1, len(members))
|
||||
|
||||
def test__get_compose_action_element(self):
|
||||
value = self.node_col._get_compose_action_element()
|
||||
self.assertEqual('/redfish/v1/Nodes/Actions/Allocate',
|
||||
value.target_uri)
|
||||
|
||||
def test_compose_node_no_reqs(self):
|
||||
result = self.node_col.compose_node()
|
||||
self.node_col._conn.post.assert_called_once_with(
|
||||
'/redfish/v1/Nodes/Actions/Allocate', data={})
|
||||
self.assertEqual(result, '/redfish/v1/Nodes/1')
|
||||
|
||||
def test_compose_node(self):
|
||||
reqs = {
|
||||
'Name': 'test',
|
||||
'Description': 'this is a test node',
|
||||
"Processors": [{
|
||||
"@odata.type":
|
||||
"AllocationComposedNodeRequest.v1_1_0.Processor",
|
||||
"Model": "Multi-Core Intel(R) Xeon(R) processor 7xxx Series",
|
||||
"TotalCores": 2,
|
||||
"AchievableSpeedMHz": 3700,
|
||||
"InstructionSet": "x86-64",
|
||||
"Oem": {
|
||||
"Intel_RackScale": {
|
||||
"@odata.type": "AllocationComposedNodeRequest.v1_1_0."
|
||||
"ProcessorExtensions",
|
||||
"Brand": "E5",
|
||||
"Capabilities": ["sse"]
|
||||
}
|
||||
},
|
||||
"Resource": {
|
||||
"@odata.id": "/redfish/v1/Systems/1/Processors/1"
|
||||
},
|
||||
"Chassis": {
|
||||
"@odata.id": "/redfish/v1/Chassis/1"
|
||||
},
|
||||
"ProcessorType": "CPU",
|
||||
"Connectivity": ["Local", "RemotePCIe"]
|
||||
}],
|
||||
"Memory": [{
|
||||
"@odata.type": "AllocationComposedNodeRequest.v1_1_0.Memory",
|
||||
"CapacityMiB": 16000,
|
||||
"MemoryType": "DRAM",
|
||||
"MemoryDeviceType": "DDR3",
|
||||
"SpeedMHz": 1600,
|
||||
"Manufacturer": "Intel",
|
||||
"DataWidthBits": 64,
|
||||
"Resource": {
|
||||
"@odata.id": "/redfish/v1/Systems/1/Memory/1"
|
||||
},
|
||||
"Chassis": {
|
||||
"@odata.id": "/redfish/v1/Chassis/1"
|
||||
}
|
||||
}],
|
||||
"RemoteDrives": [{
|
||||
"CapacityGiB": 80,
|
||||
"Protocol": "iSCSI",
|
||||
"Master": {
|
||||
"@odata.type":
|
||||
"AllocationComposedNodeRequest.v1_1_0.Master",
|
||||
"Type": "Snapshot",
|
||||
"Resource": {
|
||||
"@odata.id":
|
||||
"/redfish/v1/StorageServices/iscsi1/Volumes/1"
|
||||
}
|
||||
}
|
||||
}],
|
||||
"LocalDrives": [{
|
||||
"CapacityGiB": 100,
|
||||
"Type": "HDD",
|
||||
"MinRPM": 5400,
|
||||
"SerialNumber": "12345678",
|
||||
"Interface": "SATA",
|
||||
"Resource": {
|
||||
"@odata.id": "redfish/v1/Chassis/Blade1/Drives/Disk1"
|
||||
},
|
||||
"Chassis": {
|
||||
"@odata.id": "/redfish/v1/Chassis/Blade1"
|
||||
},
|
||||
"FabricSwitch": False
|
||||
}],
|
||||
"EthernetInterfaces": [{
|
||||
"SpeedMbps": 1000,
|
||||
"PrimaryVLAN": 100,
|
||||
"VLANs": [{
|
||||
"VLANId": 100,
|
||||
"Tagged": False
|
||||
}],
|
||||
"Resource": {
|
||||
"@odata.id": "/redfish/v1/Systems/1/EthernetInterfaces/1"
|
||||
},
|
||||
"Chassis": {
|
||||
"@odata.id": "/redfish/v1/Chassis/1"
|
||||
}
|
||||
}],
|
||||
'Security': {
|
||||
'TpmPresent': True,
|
||||
'TpmInterfaceType': 'TPM2_0',
|
||||
'TxtEnabled': True,
|
||||
'ClearTPMOnDelete': True,
|
||||
"PersistentMemoryOperationOnDelete": "OverwritePCD"
|
||||
},
|
||||
'TotalSystemCoreCount': 8,
|
||||
'TotalSystemMemoryMiB': 16000
|
||||
}
|
||||
result = self.node_col.compose_node(
|
||||
name='test', description='this is a test node',
|
||||
processor_req=[{
|
||||
"@odata.type":
|
||||
"AllocationComposedNodeRequest.v1_1_0.Processor",
|
||||
"Model": "Multi-Core Intel(R) Xeon(R) processor 7xxx Series",
|
||||
"TotalCores": 2,
|
||||
"AchievableSpeedMHz": 3700,
|
||||
"InstructionSet": "x86-64",
|
||||
"Oem": {
|
||||
"Intel_RackScale": {
|
||||
"@odata.type": "AllocationComposedNodeRequest.v1_1_0."
|
||||
"ProcessorExtensions",
|
||||
"Brand": "E5",
|
||||
"Capabilities": ["sse"]
|
||||
}
|
||||
},
|
||||
"Resource": {
|
||||
"@odata.id": "/redfish/v1/Systems/1/Processors/1"
|
||||
},
|
||||
"Chassis": {
|
||||
"@odata.id": "/redfish/v1/Chassis/1"
|
||||
},
|
||||
"ProcessorType": "CPU",
|
||||
"Connectivity": ["Local", "RemotePCIe"]
|
||||
}],
|
||||
memory_req=[{
|
||||
"@odata.type": "AllocationComposedNodeRequest.v1_1_0.Memory",
|
||||
"CapacityMiB": 16000,
|
||||
"MemoryType": "DRAM",
|
||||
"MemoryDeviceType": "DDR3",
|
||||
"SpeedMHz": 1600,
|
||||
"Manufacturer": "Intel",
|
||||
"DataWidthBits": 64,
|
||||
"Resource": {
|
||||
"@odata.id": "/redfish/v1/Systems/1/Memory/1"
|
||||
},
|
||||
"Chassis": {
|
||||
"@odata.id": "/redfish/v1/Chassis/1"
|
||||
}
|
||||
}],
|
||||
remote_drive_req=[{
|
||||
"CapacityGiB": 80,
|
||||
"Protocol": "iSCSI",
|
||||
"Master": {
|
||||
"@odata.type":
|
||||
"AllocationComposedNodeRequest.v1_1_0.Master",
|
||||
"Type": "Snapshot",
|
||||
"Resource": {
|
||||
"@odata.id": "/redfish/v1/StorageServices/iscsi1/"
|
||||
"Volumes/1"
|
||||
}
|
||||
}
|
||||
}],
|
||||
local_drive_req=[{
|
||||
"CapacityGiB": 100,
|
||||
"Type": "HDD",
|
||||
"MinRPM": 5400,
|
||||
"SerialNumber": "12345678",
|
||||
"Interface": "SATA",
|
||||
"Resource": {
|
||||
"@odata.id": "redfish/v1/Chassis/Blade1/Drives/Disk1"
|
||||
},
|
||||
"Chassis": {
|
||||
"@odata.id": "/redfish/v1/Chassis/Blade1"
|
||||
},
|
||||
"FabricSwitch": False
|
||||
}],
|
||||
ethernet_interface_req=[{
|
||||
"SpeedMbps": 1000,
|
||||
"PrimaryVLAN": 100,
|
||||
"VLANs": [{
|
||||
"VLANId": 100,
|
||||
"Tagged": False
|
||||
}],
|
||||
"Resource": {
|
||||
"@odata.id": "/redfish/v1/Systems/1/EthernetInterfaces/1"
|
||||
},
|
||||
"Chassis": {
|
||||
"@odata.id": "/redfish/v1/Chassis/1"
|
||||
}
|
||||
}],
|
||||
security_req={
|
||||
'TpmPresent': True,
|
||||
'TpmInterfaceType': 'TPM2_0',
|
||||
'TxtEnabled': True,
|
||||
'ClearTPMOnDelete': True,
|
||||
"PersistentMemoryOperationOnDelete": "OverwritePCD"
|
||||
},
|
||||
total_system_core_req=8,
|
||||
total_system_memory_req=16000)
|
||||
self.node_col._conn.post.assert_called_once_with(
|
||||
'/redfish/v1/Nodes/Actions/Allocate', data=reqs)
|
||||
self.assertEqual(result, '/redfish/v1/Nodes/1')
|
||||
|
||||
def test_compose_node_with_invalid_reqs(self):
|
||||
# Wrong processor type
|
||||
with self.assertRaisesRegex(
|
||||
jsonschema.exceptions.ValidationError,
|
||||
("'invalid' is not one of \['CPU', 'FPGA', 'GPU', 'DSP', "
|
||||
"'Accelerator', 'OEM'\]")):
|
||||
|
||||
self.node_col.compose_node(
|
||||
name='test', description='this is a test node',
|
||||
processor_req=[{
|
||||
'TotalCores': 4,
|
||||
'ProcessorType': 'invalid'}])
|
||||
|
||||
# Wrong processor Oem Brand
|
||||
with self.assertRaisesRegex(
|
||||
jsonschema.exceptions.ValidationError,
|
||||
("'invalid' is not one of \['E3', 'E5'")):
|
||||
|
||||
self.node_col.compose_node(
|
||||
name='test', description='this is a test node',
|
||||
processor_req=[{
|
||||
'TotalCores': 4,
|
||||
'Oem': {
|
||||
"Intel_RackScale": {
|
||||
'Brand': 'invalid',
|
||||
'Capabilities': ['sse']
|
||||
}
|
||||
}
|
||||
}])
|
||||
|
||||
# Wrong processor Oem Capabilities
|
||||
with self.assertRaisesRegex(
|
||||
jsonschema.exceptions.ValidationError,
|
||||
("'sse' is not of type 'array'")):
|
||||
|
||||
self.node_col.compose_node(
|
||||
name='test', description='this is a test node',
|
||||
processor_req=[{
|
||||
'TotalCores': 4,
|
||||
'Oem': {
|
||||
"Intel_RackScale": {
|
||||
'Brand': 'E3',
|
||||
'Capabilities': 'sse'
|
||||
}
|
||||
}
|
||||
}])
|
||||
|
||||
# Wrong processor Oem Capabilities
|
||||
with self.assertRaisesRegex(
|
||||
jsonschema.exceptions.ValidationError,
|
||||
("0 is not of type 'string'")):
|
||||
|
||||
self.node_col.compose_node(
|
||||
name='test', description='this is a test node',
|
||||
processor_req=[{
|
||||
'TotalCores': 4,
|
||||
'Oem': {
|
||||
"Intel_RackScale": {
|
||||
'Brand': 'E3',
|
||||
'Capabilities': [0]
|
||||
}
|
||||
}
|
||||
}])
|
||||
|
||||
# Wrong processor Connectivity
|
||||
with self.assertRaisesRegex(
|
||||
jsonschema.exceptions.ValidationError,
|
||||
("'invalid-value' is not one of \['Local', 'Ethernet', "
|
||||
"'RemotePCIe'\]")):
|
||||
|
||||
self.node_col.compose_node(
|
||||
name='test', description='this is a test node',
|
||||
processor_req=[{
|
||||
'TotalCores': 4,
|
||||
"Connectivity": ["invalid-value"]
|
||||
}])
|
||||
|
||||
# Wrong memory MemoryType
|
||||
with self.assertRaisesRegex(
|
||||
jsonschema.exceptions.ValidationError,
|
||||
("'invalid-value' is not one of \['DRAM', 'NVDIMM_N', 'NVDIMM_F', "
|
||||
"'NVMDIMM_P', 'IntelOptane'\]")):
|
||||
|
||||
self.node_col.compose_node(
|
||||
name='test', description='this is a test node',
|
||||
memory_req=[{
|
||||
"CapacityMiB": 16000,
|
||||
"MemoryType": "invalid-value",
|
||||
}])
|
||||
|
||||
# Wrong remote drive CapacityGiB
|
||||
with self.assertRaisesRegex(
|
||||
jsonschema.exceptions.ValidationError,
|
||||
("'invalid' is not of type 'number'")):
|
||||
|
||||
self.node_col.compose_node(
|
||||
name='test', description='this is a test node',
|
||||
remote_drive_req=[{
|
||||
'CapacityGiB': 'invalid',
|
||||
'Protocol': 'NVMeOverFabrics',
|
||||
'Master': {
|
||||
'Type': 'Snapshot',
|
||||
'Resource': {
|
||||
'@odata.id':
|
||||
'/redfish/v1/StorageServices/NVMeoE1/Volumes/'
|
||||
'102'
|
||||
}
|
||||
},
|
||||
'Resource': {
|
||||
'@odata.id':
|
||||
'/redfish/v1/StorageServices/NVMeoE1/Volumes/102'
|
||||
}
|
||||
}])
|
||||
|
||||
# Wrong remote drive Protocol
|
||||
with self.assertRaisesRegex(
|
||||
jsonschema.exceptions.ValidationError,
|
||||
("'invalid' is not one of \['iSCSI', 'NVMeOverFabrics'\]")):
|
||||
|
||||
self.node_col.compose_node(
|
||||
name='test', description='this is a test node',
|
||||
remote_drive_req=[{
|
||||
'CapacityGiB': 80,
|
||||
'Protocol': 'invalid',
|
||||
'Master': {
|
||||
'Type': 'Snapshot',
|
||||
'Resource': {
|
||||
'@odata.id':
|
||||
'/redfish/v1/StorageServices/NVMeoE1/Volumes/'
|
||||
'102'
|
||||
}
|
||||
},
|
||||
'Resource': {
|
||||
'@odata.id':
|
||||
'/redfish/v1/StorageServices/NVMeoE1/Volumes/102'
|
||||
}
|
||||
}])
|
||||
|
||||
# Wrong remote drive Master Type
|
||||
with self.assertRaisesRegex(
|
||||
jsonschema.exceptions.ValidationError,
|
||||
("'invalid' is not one of \['Snapshot', 'Clone'\]")):
|
||||
|
||||
self.node_col.compose_node(
|
||||
name='test', description='this is a test node',
|
||||
remote_drive_req=[{
|
||||
'CapacityGiB': 80,
|
||||
'Protocol': 'iSCSI',
|
||||
'Master': {
|
||||
'Type': 'invalid',
|
||||
'Resource': {
|
||||
'@odata.id':
|
||||
'/redfish/v1/StorageServices/NVMeoE1/Volumes/'
|
||||
'102'
|
||||
}
|
||||
},
|
||||
'Resource': {
|
||||
'@odata.id':
|
||||
'/redfish/v1/StorageServices/NVMeoE1/Volumes/102'
|
||||
}
|
||||
}])
|
||||
|
||||
# Wrong security parameter "TpmPresent"
|
||||
with self.assertRaisesRegex(
|
||||
jsonschema.exceptions.ValidationError,
|
||||
"'invalid' is not of type 'boolean'"):
|
||||
self.node_col.compose_node(
|
||||
name='test', description='this is a test node',
|
||||
security_req={
|
||||
'TpmPresent': 'invalid',
|
||||
'TpmInterfaceType': 'TPM2_0',
|
||||
'TxtEnabled': True,
|
||||
'ClearTPMOnDelete': True
|
||||
})
|
||||
|
||||
# Wrong security parameter "TpmInterfaceType"
|
||||
with self.assertRaisesRegex(
|
||||
jsonschema.exceptions.ValidationError,
|
||||
"True is not of type 'string'"):
|
||||
self.node_col.compose_node(
|
||||
name='test', description='this is a test node',
|
||||
security_req={
|
||||
'TpmPresent': False,
|
||||
'TpmInterfaceType': True,
|
||||
'TxtEnabled': True,
|
||||
'ClearTPMOnDelete': True
|
||||
})
|
||||
|
||||
# Wrong security parameter "TxtEnabled"
|
||||
with self.assertRaisesRegex(
|
||||
jsonschema.exceptions.ValidationError,
|
||||
"'invalid' is not of type 'boolean'"):
|
||||
self.node_col.compose_node(
|
||||
name='test', description='this is a test node',
|
||||
security_req={
|
||||
'TpmPresent': True,
|
||||
'TpmInterfaceType': 'TPM2_0',
|
||||
'TxtEnabled': 'invalid',
|
||||
'ClearTPMOnDelete': True
|
||||
})
|
||||
|
||||
# Wrong security parameter "ClearTPMOnDelete"
|
||||
with self.assertRaisesRegex(
|
||||
jsonschema.exceptions.ValidationError,
|
||||
"'invalid' is not of type 'boolean'"):
|
||||
self.node_col.compose_node(
|
||||
name='test', description='this is a test node',
|
||||
security_req={
|
||||
'TpmPresent': True,
|
||||
'TpmInterfaceType': 'TPM2_0',
|
||||
'TxtEnabled': True,
|
||||
'ClearTPMOnDelete': 'invalid'
|
||||
})
|
||||
|
||||
# Wrong security parameter "PersistentMemoryOperationOnDelete"
|
||||
with self.assertRaisesRegex(
|
||||
jsonschema.exceptions.ValidationError,
|
||||
("'invalid' is not one of \['PreserveConfiguration', "
|
||||
"'SecureErase', 'OverwritePCD'\]")):
|
||||
self.node_col.compose_node(
|
||||
name='test', description='this is a test node',
|
||||
security_req={
|
||||
'TpmPresent': True,
|
||||
'TpmInterfaceType': 'TPM2_0',
|
||||
'TxtEnabled': True,
|
||||
'PersistentMemoryOperationOnDelete': 'invalid'
|
||||
})
|
||||
|
||||
# Wrong additional security parameter
|
||||
with self.assertRaisesRegex(
|
||||
jsonschema.exceptions.ValidationError,
|
||||
("Additional properties are not allowed \('invalid-key' was "
|
||||
"unexpected\)")):
|
||||
self.node_col.compose_node(
|
||||
name='test', description='this is a test node',
|
||||
security_req={
|
||||
'TpmPresent': True,
|
||||
'TpmInterfaceType': 'TPM2_0',
|
||||
'TxtEnabled': False,
|
||||
'invalid-key': 'invalid-value'
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user