Add `Endpoint
sub-resource to
Fabric
`
Add representation of the Endpoint sub-resource to Fabric resource in sushy. A fabric endpoint represents the properties of an entity that sends or receives protocol defined messages over a transport. Story: #2003853 Task: #26648 Change-Id: I76c99da2aac8e0629bb468e22abd104cb29bc4ab
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Exposes the ``endpoint`` sub-resource from the ``fabric`` resource.
|
||||
``endpoint`` represents the properties of an entity that sends or receives
|
||||
protocol defined messages over a transport.
|
@@ -13,30 +13,87 @@
|
||||
# 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
|
||||
# Protocol type 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'
|
||||
PROTOCOL_TYPE_AHCI = 'Advanced Host Controller Interface'
|
||||
PROTOCOL_TYPE_FC = 'Fibre Channel'
|
||||
PROTOCOL_TYPE_FCP = 'Fibre Channel Protocol for SCSI'
|
||||
PROTOCOL_TYPE_FCoE = 'Fibre Channel over Ethernet'
|
||||
PROTOCOL_TYPE_FICON = 'FIbre CONnection (FICON)'
|
||||
PROTOCOL_TYPE_FTP = 'File Transfer Protocol'
|
||||
PROTOCOL_TYPE_HTTP = 'Hypertext Transport Protocol'
|
||||
PROTOCOL_TYPE_HTTPS = 'Secure Hypertext Transport Protocol'
|
||||
PROTOCOL_TYPE_I2C = 'Inter-Integrated Circuit Bus'
|
||||
PROTOCOL_TYPE_NFSv3 = 'Network File System version 3'
|
||||
PROTOCOL_TYPE_NFSv4 = 'Network File System version 4'
|
||||
PROTOCOL_TYPE_NVMe = 'Non-Volatile Memory Express'
|
||||
PROTOCOL_TYPE_NVMeOverFabrics = 'NVMe over Fabrics'
|
||||
PROTOCOL_TYPE_OEM = 'OEM specific'
|
||||
PROTOCOL_TYPE_PCIe = 'PCI Express'
|
||||
PROTOCOL_TYPE_RoCE = 'RDMA over Converged Ethernet Protocol'
|
||||
PROTOCOL_TYPE_RoCEv2 = 'RDMA over Converged Ethernet Protocol Version 2'
|
||||
PROTOCOL_TYPE_SAS = 'Serial Attached SCSI'
|
||||
PROTOCOL_TYPE_SATA = 'Serial AT Attachment'
|
||||
PROTOCOL_TYPE_SFTP = 'Secure File Transfer Protocol'
|
||||
PROTOCOL_TYPE_SMB = 'Server Message Block (CIFS Common Internet File System)'
|
||||
PROTOCOL_TYPE_UHCI = 'Universal Host Controller Interface'
|
||||
PROTOCOL_TYPE_USB = 'Universal Serial Bus'
|
||||
PROTOCOL_TYPE_iSCSI = 'Internet SCSI'
|
||||
PROTOCOL_TYPE_iWARP = 'Internet Wide Area Remote Direct Memory Access Protocol'
|
||||
|
||||
# Address origin IPv4 constants
|
||||
|
||||
ADDRESS_ORIGIN_IPv4_BOOTP = 'Address is provided by a BOOTP service'
|
||||
ADDRESS_ORIGIN_IPv4_DHCP = 'Address is provided by a DHCPv4 service'
|
||||
ADDRESS_ORIGIN_IPv4_IPv4LINKLOCAL = 'Address valid only for this segment'
|
||||
ADDRESS_ORIGIN_IPv4_STATIC = 'A static address as configured by the user'
|
||||
|
||||
# Address origin IPv6 constants
|
||||
|
||||
ADDRESS_ORIGIN_IPv6_DHCPv6 = 'Address is provided by a DHCPv6 service'
|
||||
ADDRESS_ORIGIN_IPv6_LINKLOCAL = 'Address valid only for this network segment'
|
||||
ADDRESS_ORIGIN_IPv6_SLAAC = 'Stateless Address Auto Configuration service'
|
||||
ADDRESS_ORIGIN_IPv6_STATIC = 'A static address as configured by the user'
|
||||
|
||||
# Address state constants
|
||||
|
||||
ADDRESS_STATE_DEPRECATED = 'Deprecated'
|
||||
"""This address is currently within it's valid lifetime, but is now outside of
|
||||
it's preferred lifetime as defined in RFC 4862."""
|
||||
ADDRESS_STATE_FAILED = 'Failed'
|
||||
"""This address has failed Duplicate Address Detection testing as defined in
|
||||
RFC 4862 section 5.4 and is not currently in use."""
|
||||
ADDRESS_STATE_PREFERRED = 'Preferred'
|
||||
"""This address is currently within both it's valid and preferred lifetimes as
|
||||
defined in RFC 4862."""
|
||||
ADDRESS_STATE_TENTATIVE = 'Tentative'
|
||||
"""This address is currently undergoing Duplicate Address Detection testing as
|
||||
defined in RFC 4862 section 5.4."""
|
||||
|
||||
# Durable name format constants
|
||||
|
||||
DURABLE_NAME_FORMAT_EUI = 'IEEE-defined 64-bit Extended Unique Identifier'
|
||||
DURABLE_NAME_FORMAT_FC_WWN = 'Fibre Channel World Wide Name'
|
||||
DURABLE_NAME_FORMAT_NAA = 'Name Address Authority Format'
|
||||
DURABLE_NAME_FORMAT_NQN = 'NVMe Qualified Name'
|
||||
DURABLE_NAME_FORMAT_NSID = 'NVM Namespace Identifier'
|
||||
DURABLE_NAME_FORMAT_UUID = 'Universally Unique Identifier'
|
||||
DURABLE_NAME_FORMAT_iQN = 'iSCSI Qualified Name'
|
||||
|
||||
# Entity role constants
|
||||
|
||||
ENTITY_ROLE_BOTH = 'The entity is acting as both an initiator and a target'
|
||||
ENTITY_ROLE_INITIATOR = 'The entity is acting as an initiator'
|
||||
ENTITY_ROLE_TARGET = 'The entity is acting as a target'
|
||||
|
||||
# Entity type constants
|
||||
|
||||
ENTITY_TYPE_PCI_BRIDGE = 'PCI(e) Bridge'
|
||||
ENTITY_TYPE_DISPLAY_CONTROLLER = 'Display Controller'
|
||||
ENTITY_TYPE_DRIVE = 'Disk Drive'
|
||||
ENTITY_TYPE_NETWORK_CONTROLLER = 'Network Controller'
|
||||
ENTITY_TYPE_PROCESSOR = 'Processor Device'
|
||||
ENTITY_TYPE_ROOT_COMPLEX = 'Root Complex'
|
||||
ENTITY_TYPE_STORAGE_EXPANDER = 'Storage Expander'
|
||||
ENTITY_TYPE_STORAGE_INITIATOR = 'Storage Initiator'
|
||||
ENTITY_TYPE_VOLUME = 'Volume'
|
||||
|
178
sushy/resources/fabric/endpoint.py
Normal file
178
sushy/resources/fabric/endpoint.py
Normal file
@@ -0,0 +1,178 @@
|
||||
# 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.
|
||||
# https://redfish.dmtf.org/schemas/Endpoint.v1_3_0.json
|
||||
|
||||
import logging
|
||||
|
||||
from sushy.resources import base
|
||||
from sushy.resources import common
|
||||
from sushy.resources.fabric import mappings as fab_maps
|
||||
from sushy import utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class IPv4AddressField(base.CompositeField):
|
||||
|
||||
address = base.Field('Address')
|
||||
"""This is the IPv4 Address."""
|
||||
|
||||
gateway = base.Field('Gateway')
|
||||
"""This is the IPv4 gateway for this address."""
|
||||
|
||||
subnet_mask = base.Field('SubnetMask')
|
||||
"""This is the IPv4 Subnet mask."""
|
||||
|
||||
address_origin = base.MappedField('AddressOrigin',
|
||||
fab_maps.ADDRESS_ORIGIN_IPv4_VALUE_MAP)
|
||||
"""This indicates how the address was determined."""
|
||||
|
||||
|
||||
class IPv6AddressField(base.CompositeField):
|
||||
|
||||
address = base.Field('Address')
|
||||
"""This is the IPv6 Address."""
|
||||
|
||||
prefix_length = base.Field('PrefixLength', adapter=utils.int_or_none)
|
||||
"""This is the IPv6 Address Prefix Length."""
|
||||
|
||||
address_origin = base.MappedField('AddressOrigin',
|
||||
fab_maps.ADDRESS_ORIGIN_IPv6_VALUE_MAP)
|
||||
"""This indicates how the address was determined."""
|
||||
|
||||
address_state = base.MappedField('AddressState',
|
||||
fab_maps.ADDRESS_STATE_VALUE_MAP)
|
||||
"""The current state of this address as defined in RFC 4862."""
|
||||
|
||||
|
||||
class IPTransportDetailsListField(base.ListField):
|
||||
"""IP transport details
|
||||
|
||||
This array contains details for each IP transport supported by this
|
||||
endpoint. The array structure can be used to model multiple IP addresses
|
||||
for this endpoint.
|
||||
"""
|
||||
|
||||
port = base.Field('Port', adapter=utils.int_or_none)
|
||||
"""The UDP or TCP port number used by the Endpoint."""
|
||||
|
||||
transport_protocol = base.MappedField('TransportProtocol',
|
||||
fab_maps.PROTOCOL_TYPE_VALUE_MAP)
|
||||
"""The protocol used by the connection entity."""
|
||||
|
||||
ipv4_address = IPv4AddressField('IPv4Address')
|
||||
"""The IPv4 address object."""
|
||||
|
||||
ipv6_address = IPv6AddressField('IPv6Address')
|
||||
"""The IPv6 address object."""
|
||||
|
||||
|
||||
class PciIdField(base.CompositeField):
|
||||
|
||||
device_id = base.Field('DeviceId')
|
||||
"""The Device ID of this PCIe function."""
|
||||
|
||||
subsystem_id = base.Field('SubsystemId')
|
||||
"""The Subsystem ID of this PCIefunction."""
|
||||
|
||||
subsystem_vendor_id = base.Field('SubsystemVendorId')
|
||||
"""The Subsystem Vendor ID of thisPCIe function."""
|
||||
|
||||
vendor_id = base.Field('VendorId')
|
||||
"""The Vendor ID of this PCIe function."""
|
||||
|
||||
|
||||
class IdentifierListField(base.ListField):
|
||||
|
||||
durable_name = base.Field('DurableName')
|
||||
"""This indicates the world wide, persistent name of the entity."""
|
||||
|
||||
durable_name_format = base.MappedField('DurableNameFormat',
|
||||
fab_maps.DUR_NAME_FORMAT_VALUE_MAP)
|
||||
"""This represents the format of the DurableName property."""
|
||||
|
||||
|
||||
class ConnectedEntitiesListField(base.ListField):
|
||||
"""All the entities connected to this endpoint."""
|
||||
|
||||
pci_class_code = base.Field('PciClassCode')
|
||||
"""The Class Code, Subclass code, and Programming Interface code of
|
||||
this PCIe function."""
|
||||
|
||||
pci_function_number = base.Field('PciFunctionNumber',
|
||||
adapter=utils.int_or_none)
|
||||
"""The PCI ID of the connected entity."""
|
||||
|
||||
entity_pci_id = PciIdField('EntityPciId')
|
||||
"""The PCI ID of the connected entity."""
|
||||
|
||||
identifiers = IdentifierListField('Identifiers')
|
||||
"""Identifiers for the remote entity."""
|
||||
|
||||
entity_role = base.MappedField('EntityRole',
|
||||
fab_maps.ENTITY_ROLE_VALUE_MAP)
|
||||
"""The role of the connected entity."""
|
||||
|
||||
entity_type = base.MappedField('EntityType',
|
||||
fab_maps.ENTITY_TYPE_VALUE_MAP)
|
||||
"""The type of the connected entity."""
|
||||
|
||||
|
||||
class Endpoint(base.ResourceBase):
|
||||
"""This class represents a fabric endpoint.
|
||||
|
||||
It represents the properties of an entity that sends or receives protocol
|
||||
defined messages over a transport.
|
||||
"""
|
||||
|
||||
identity = base.Field('Id', required=True)
|
||||
"""Identifier for the endpoint"""
|
||||
|
||||
name = base.Field('Name', required=True)
|
||||
"""The endpoint name"""
|
||||
|
||||
description = base.Field('Description')
|
||||
"""The endpoint description"""
|
||||
|
||||
status = common.StatusField('Status')
|
||||
"""The endpoint status"""
|
||||
|
||||
host_reservation_memory_bytes = base.Field('HostReservationMemoryBytes',
|
||||
adapter=utils.int_or_none)
|
||||
"""The amount of memory in Bytes that the Host should allocate to connect
|
||||
to this endpoint.
|
||||
"""
|
||||
|
||||
endpoint_protocol = base.MappedField('EndpointProtocol',
|
||||
fab_maps.PROTOCOL_TYPE_VALUE_MAP)
|
||||
"""The protocol supported by this endpoint."""
|
||||
|
||||
pci_id = PciIdField('PciId')
|
||||
"""The PCI ID of the endpoint."""
|
||||
|
||||
IP_transport_details = IPTransportDetailsListField('IPTransportDetails')
|
||||
"""This array contains details for each IP transport supported by this
|
||||
endpoint. The array structure can be used to model multiple IP addresses
|
||||
for this endpoint."""
|
||||
|
||||
connected_entities = ConnectedEntitiesListField('ConnectedEntities')
|
||||
"""All entities connected to this endpoint."""
|
||||
|
||||
|
||||
class EndpointCollection(base.ResourceCollectionBase):
|
||||
"""Represents a collection of endpoints associated with the fabric."""
|
||||
|
||||
@property
|
||||
def _resource_type(self):
|
||||
return Endpoint
|
@@ -15,7 +15,9 @@
|
||||
|
||||
from sushy.resources import base
|
||||
from sushy.resources import common
|
||||
from sushy.resources.fabric import endpoint as fab_endpoint
|
||||
from sushy.resources.fabric import mappings as fab_maps
|
||||
from sushy import utils
|
||||
|
||||
import logging
|
||||
|
||||
@@ -38,14 +40,14 @@ class Fabric(base.ResourceBase):
|
||||
description = base.Field('Description')
|
||||
"""The fabric description"""
|
||||
|
||||
max_zones = base.Field('MaxZones')
|
||||
max_zones = base.Field('MaxZones', adapter=utils.int_or_none)
|
||||
"""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)
|
||||
fab_maps.PROTOCOL_TYPE_VALUE_MAP)
|
||||
"""The protocol being sent over this fabric"""
|
||||
|
||||
def __init__(self, connector, identity, redfish_version=None):
|
||||
@@ -58,6 +60,13 @@ class Fabric(base.ResourceBase):
|
||||
"""
|
||||
super(Fabric, self).__init__(connector, identity, redfish_version)
|
||||
|
||||
@property
|
||||
@utils.cache_it
|
||||
def endpoints(self):
|
||||
return fab_endpoint.EndpointCollection(
|
||||
self._conn, utils.get_sub_resource_path_by(self, 'Endpoints'),
|
||||
redfish_version=self.redfish_version)
|
||||
|
||||
|
||||
class FabricCollection(base.ResourceCollectionBase):
|
||||
|
||||
|
@@ -16,32 +16,89 @@
|
||||
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,
|
||||
PROTOCOL_TYPE_VALUE_MAP = {
|
||||
'AHCI': fab_cons.PROTOCOL_TYPE_AHCI,
|
||||
'FC': fab_cons.PROTOCOL_TYPE_FC,
|
||||
'FCP': fab_cons.PROTOCOL_TYPE_FCP,
|
||||
'FCoE': fab_cons.PROTOCOL_TYPE_FCoE,
|
||||
'FICON': fab_cons.PROTOCOL_TYPE_FICON,
|
||||
'FTP': fab_cons.PROTOCOL_TYPE_FTP,
|
||||
'HTTP': fab_cons.PROTOCOL_TYPE_HTTP,
|
||||
'HTTPS': fab_cons.PROTOCOL_TYPE_HTTPS,
|
||||
'I2C': fab_cons.PROTOCOL_TYPE_I2C,
|
||||
'NFSv3': fab_cons.PROTOCOL_TYPE_NFSv3,
|
||||
'NFSv4': fab_cons.PROTOCOL_TYPE_NFSv4,
|
||||
'NVMe': fab_cons.PROTOCOL_TYPE_NVMe,
|
||||
'NVMeOverFabrics': fab_cons.PROTOCOL_TYPE_NVMeOverFabrics,
|
||||
'OEM': fab_cons.PROTOCOL_TYPE_OEM,
|
||||
'PCIe': fab_cons.PROTOCOL_TYPE_PCIe,
|
||||
'RoCE': fab_cons.PROTOCOL_TYPE_RoCE,
|
||||
'RoCEv2': fab_cons.PROTOCOL_TYPE_RoCEv2,
|
||||
'SAS': fab_cons.PROTOCOL_TYPE_SAS,
|
||||
'SATA': fab_cons.PROTOCOL_TYPE_SATA,
|
||||
'SFTP': fab_cons.PROTOCOL_TYPE_SFTP,
|
||||
'SMB': fab_cons.PROTOCOL_TYPE_SMB,
|
||||
'UHCI': fab_cons.PROTOCOL_TYPE_UHCI,
|
||||
'USB': fab_cons.PROTOCOL_TYPE_USB,
|
||||
'iSCSI': fab_cons.PROTOCOL_TYPE_iSCSI,
|
||||
'iWARP': fab_cons.PROTOCOL_TYPE_iWARP,
|
||||
}
|
||||
|
||||
FABRIC_TYPE_VALUE_MAP_REV = utils.revert_dictionary(FABRIC_TYPE_VALUE_MAP)
|
||||
|
||||
ADDRESS_ORIGIN_IPv4_VALUE_MAP = {
|
||||
'BOOTP': fab_cons.ADDRESS_ORIGIN_IPv4_BOOTP,
|
||||
'DHCP': fab_cons.ADDRESS_ORIGIN_IPv4_DHCP,
|
||||
'IPv4LinkLocal': fab_cons.ADDRESS_ORIGIN_IPv4_IPv4LINKLOCAL,
|
||||
'Static': fab_cons.ADDRESS_ORIGIN_IPv4_STATIC,
|
||||
}
|
||||
|
||||
|
||||
ADDRESS_ORIGIN_IPv6_VALUE_MAP = {
|
||||
'DHCPv6': fab_cons.ADDRESS_ORIGIN_IPv6_DHCPv6,
|
||||
'LinkLocal': fab_cons.ADDRESS_ORIGIN_IPv6_LINKLOCAL,
|
||||
'SLAAC': fab_cons.ADDRESS_ORIGIN_IPv6_SLAAC,
|
||||
'Static': fab_cons.ADDRESS_ORIGIN_IPv6_STATIC,
|
||||
}
|
||||
|
||||
|
||||
ADDRESS_STATE_VALUE_MAP = {
|
||||
'Deprecated': fab_cons.ADDRESS_STATE_DEPRECATED,
|
||||
'Failed': fab_cons.ADDRESS_STATE_FAILED,
|
||||
'Preferred': fab_cons.ADDRESS_STATE_PREFERRED,
|
||||
'Tentative': fab_cons.ADDRESS_STATE_TENTATIVE,
|
||||
}
|
||||
|
||||
|
||||
DUR_NAME_FORMAT_VALUE_MAP = {
|
||||
'EUI': fab_cons.DURABLE_NAME_FORMAT_EUI,
|
||||
'FC_WWN': fab_cons.DURABLE_NAME_FORMAT_FC_WWN,
|
||||
'NAA': fab_cons.DURABLE_NAME_FORMAT_NAA,
|
||||
'NQN': fab_cons.DURABLE_NAME_FORMAT_NQN,
|
||||
'NSID': fab_cons.DURABLE_NAME_FORMAT_NSID,
|
||||
'UUID': fab_cons.DURABLE_NAME_FORMAT_UUID,
|
||||
'iQN': fab_cons.DURABLE_NAME_FORMAT_iQN,
|
||||
}
|
||||
|
||||
|
||||
ENTITY_ROLE_VALUE_MAP = {
|
||||
'Both': fab_cons.ENTITY_ROLE_BOTH,
|
||||
'Initiator': fab_cons.ENTITY_ROLE_INITIATOR,
|
||||
'Target': fab_cons.ENTITY_ROLE_TARGET,
|
||||
}
|
||||
|
||||
ENTITY_ROLE_VALUE_MAP_REV = utils.revert_dictionary(ENTITY_ROLE_VALUE_MAP)
|
||||
|
||||
|
||||
ENTITY_TYPE_VALUE_MAP = {
|
||||
'Bridge': fab_cons.ENTITY_TYPE_PCI_BRIDGE,
|
||||
'DisplayController': fab_cons.ENTITY_TYPE_DISPLAY_CONTROLLER,
|
||||
'Drive': fab_cons.ENTITY_TYPE_DRIVE,
|
||||
'NetworkController': fab_cons.ENTITY_TYPE_NETWORK_CONTROLLER,
|
||||
'Processor': fab_cons.ENTITY_TYPE_PROCESSOR,
|
||||
'RootComplex': fab_cons.ENTITY_TYPE_ROOT_COMPLEX,
|
||||
'StorageExpander': fab_cons.ENTITY_TYPE_STORAGE_EXPANDER,
|
||||
'StorageInitiator': fab_cons.ENTITY_TYPE_STORAGE_INITIATOR,
|
||||
'Volume': fab_cons.ENTITY_TYPE_VOLUME,
|
||||
}
|
||||
|
||||
ENTITY_TYPE_VALUE_MAP_REV = utils.revert_dictionary(ENTITY_TYPE_VALUE_MAP)
|
||||
|
40
sushy/tests/unit/json_samples/endpoint.json
Normal file
40
sushy/tests/unit/json_samples/endpoint.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"@odata.type":"#Endpoint.v1_1_0.Endpoint",
|
||||
"Id":"Drive1",
|
||||
"Name":"SAS Drive",
|
||||
"Description":"The SAS Drive in Enclosure 2 Bay 0",
|
||||
"EndpointProtocol":"SAS",
|
||||
"ConnectedEntities":[
|
||||
{
|
||||
"EntityType":"Drive",
|
||||
"EntityRole":"Target",
|
||||
"Identifiers":[
|
||||
{
|
||||
"DurableNameFormat":"NAA",
|
||||
"DurableName":"32ADF365C6C1B7C3"
|
||||
}
|
||||
],
|
||||
"Oem":{}
|
||||
}
|
||||
],
|
||||
"Links":
|
||||
{
|
||||
"MutuallyExclusiveEndpoints":[
|
||||
{
|
||||
"@odata.id":"/redfish/v1/Fabrics/SAS/Endpoints/Enclosure2"
|
||||
}
|
||||
],
|
||||
"Ports":[
|
||||
{
|
||||
"@odata.id":"/redfish/v1/Fabrics/SAS/Switches/Switch1/Ports/8"
|
||||
},
|
||||
{
|
||||
"@odata.id":"/redfish/v1/Fabrics/SAS/Switches/Switch2/Ports/8"
|
||||
}
|
||||
],
|
||||
"Oem":{}
|
||||
},
|
||||
"Oem":{},
|
||||
"@odata.context":"/redfish/v1/$metadata#Endpoint.Endpoint",
|
||||
"@odata.id":"/redfish/v1/Fabrics/SAS/Endpoints/Drive1"
|
||||
}
|
13
sushy/tests/unit/json_samples/endpoint_collection.json
Normal file
13
sushy/tests/unit/json_samples/endpoint_collection.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"@odata.type": "#EndpointCollection.EndpointCollection",
|
||||
"Name": "Endpoint Collection",
|
||||
"Members@odata.count": 1,
|
||||
"Members": [
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Fabrics/SAS/Endpoints/Drive1"
|
||||
}
|
||||
],
|
||||
"Oem": {},
|
||||
"@odata.context": "/redfish/v1/$metadata#EndpointCollection.EndpointCollection",
|
||||
"@odata.id": "/redfish/v1/Fabrics/SAS/Endpoints"
|
||||
}
|
48
sushy/tests/unit/resources/fabric/test_endpoint.py
Normal file
48
sushy/tests/unit/resources/fabric/test_endpoint.py
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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 endpoint
|
||||
from sushy.tests.unit import base
|
||||
|
||||
|
||||
class EndpointTestCase(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(EndpointTestCase, self).setUp()
|
||||
self.conn = mock.Mock()
|
||||
with open('sushy/tests/unit/json_samples/'
|
||||
'endpoint.json') as f:
|
||||
self.conn.get.return_value.json.return_value = json.load(f)
|
||||
self.fab_endpoint = endpoint.Endpoint(
|
||||
self.conn, '/redfish/v1/Fabrics/SAS/Endpoints/Drive1',
|
||||
redfish_version='1.0.2')
|
||||
|
||||
def test__parse_atrtributes(self):
|
||||
self.fab_endpoint._parse_attributes()
|
||||
self.assertEqual('Drive1', self.fab_endpoint.identity)
|
||||
self.assertEqual('SAS Drive', self.fab_endpoint.name)
|
||||
self.assertEqual(sushy.PROTOCOL_TYPE_SAS,
|
||||
self.fab_endpoint.endpoint_protocol)
|
||||
self.assertEqual(sushy.ENTITY_TYPE_DRIVE,
|
||||
self.fab_endpoint.connected_entities[0].entity_type)
|
||||
self.assertEqual(sushy.ENTITY_ROLE_TARGET,
|
||||
self.fab_endpoint.connected_entities[0].entity_role)
|
||||
con_entity = self.fab_endpoint.connected_entities[0]
|
||||
self.assertEqual(sushy.DURABLE_NAME_FORMAT_NAA,
|
||||
con_entity.identifiers[0].durable_name_format)
|
||||
self.assertEqual('32ADF365C6C1B7C3',
|
||||
con_entity.identifiers[0].durable_name)
|
@@ -17,6 +17,7 @@ import json
|
||||
import mock
|
||||
|
||||
import sushy
|
||||
from sushy.resources.fabric import endpoint
|
||||
from sushy.resources.fabric import fabric
|
||||
from sushy.tests.unit import base
|
||||
|
||||
@@ -41,11 +42,68 @@ class FabricTestCase(base.TestCase):
|
||||
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.assertEqual(sushy.PROTOCOL_TYPE_SAS,
|
||||
self.fabric.fabric_type)
|
||||
self.assertEqual(sushy.STATE_ENABLED, self.fabric.status.state)
|
||||
self.assertEqual(sushy.HEALTH_OK, self.fabric.status.health)
|
||||
|
||||
def test_endpoints(self):
|
||||
# | GIVEN |
|
||||
with open('sushy/tests/unit/json_samples/'
|
||||
'endpoint_collection.json') as f:
|
||||
endpoint_collection_return_value = json.load(f)
|
||||
|
||||
with open('sushy/tests/unit/json_samples/'
|
||||
'endpoint.json') as f:
|
||||
endpoint_return_value = json.load(f)
|
||||
|
||||
self.conn.get.return_value.json.side_effect = [
|
||||
endpoint_collection_return_value, endpoint_return_value]
|
||||
|
||||
# | WHEN |
|
||||
actual_endpoints = self.fabric.endpoints
|
||||
|
||||
# | THEN |
|
||||
self.assertIsInstance(actual_endpoints,
|
||||
endpoint.EndpointCollection)
|
||||
self.assertEqual(actual_endpoints.name, 'Endpoint Collection')
|
||||
|
||||
member = actual_endpoints.get_member(
|
||||
'/redfish/v1/Fabrics/SAS/Endpoints/Drive1')
|
||||
|
||||
self.assertEqual(member.name, "SAS Drive")
|
||||
self.assertEqual(member.endpoint_protocol, sushy.PROTOCOL_TYPE_SAS)
|
||||
|
||||
def test_endpoints_on_refresh(self):
|
||||
# | GIVEN |
|
||||
with open('sushy/tests/unit/json_samples/'
|
||||
'endpoint_collection.json') as f:
|
||||
self.conn.get.return_value.json.return_value = json.load(f)
|
||||
|
||||
# | WHEN & THEN |
|
||||
endpts = self.fabric.endpoints
|
||||
self.assertIsInstance(endpts, endpoint.EndpointCollection)
|
||||
|
||||
# On refreshing the fabric instance...
|
||||
with open('sushy/tests/unit/json_samples/fabric.json', 'r') as f:
|
||||
self.conn.get.return_value.json.return_value = json.loads(f.read())
|
||||
|
||||
self.fabric.invalidate()
|
||||
self.fabric.refresh(force=False)
|
||||
|
||||
# | WHEN & THEN |
|
||||
self.assertTrue(endpts._is_stale)
|
||||
|
||||
# | GIVEN |
|
||||
with open('sushy/tests/unit/json_samples/'
|
||||
'endpoint_collection.json') as f:
|
||||
self.conn.get.return_value.json.return_value = json.load(f)
|
||||
|
||||
# | WHEN & THEN |
|
||||
self.assertIsInstance(self.fabric.endpoints,
|
||||
endpoint.EndpointCollection)
|
||||
self.assertFalse(endpts._is_stale)
|
||||
|
||||
|
||||
class FabricCollectionTestCase(base.TestCase):
|
||||
|
||||
|
Reference in New Issue
Block a user