Lin Yang 609075345c Reformat all files with black auto formatter
Change-Id: I037b6b4a8d08862893060c5fe85865e9e11ac486
2019-09-11 16:36:53 -07:00

235 lines
7.4 KiB
Python

# 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 jsonschema
import logging
from sushy.resources import base
from sushy import utils
from rsd_lib import base as rsd_lib_base
from rsd_lib import common as rsd_lib_common
from rsd_lib.resources.v2_3.fabric import endpoint_schemas
from rsd_lib import utils as rsd_lib_utils
LOG = logging.getLogger(__name__)
class IdentifiersField(base.ListField):
name_format = base.Field("DurableNameFormat")
name = base.Field("DurableName")
class ConnectedEntitiesField(base.ListField):
entity_type = base.Field("EntityType")
entity_role = base.Field("EntityRole")
entity_link = base.Field(
"EntityLink", adapter=rsd_lib_utils.get_resource_identity
)
class LinksField(base.CompositeField):
ports = base.Field("Ports", adapter=utils.get_members_identities)
endpoints = base.Field("Endpoints", adapter=utils.get_members_identities)
zones = base.Field(
["Oem", "Intel_RackScale", "Zones"],
adapter=utils.get_members_identities,
)
interface = base.Field(
["Oem", "Intel_RackScale", "Interface"],
adapter=rsd_lib_utils.get_resource_identity,
)
class IPTransportDetailsField(base.ListField):
transport_protocol = base.Field("TransportProtocol")
ipv4_address = base.Field(["IPv4Address", "Address"])
ipv6_address = base.Field(["IPv6Address", "Address"])
port = base.Field("Port", adapter=rsd_lib_utils.num_or_none)
class AuthenticationField(base.CompositeField):
username = base.Field("Username")
password = base.Field("Password")
class OemField(base.CompositeField):
authentication = AuthenticationField(["Intel_RackScale", "Authentication"])
class Endpoint(rsd_lib_base.ResourceBase):
connected_entities = ConnectedEntitiesField("ConnectedEntities")
"""Entities connected to endpoint"""
description = base.Field("Description")
"""The endpoint description"""
protocol = base.Field("EndpointProtocol")
"""Protocol for endpoint (i.e. PCIe)"""
identifiers = IdentifiersField("Identifiers")
"""Identifiers for endpoint"""
identity = base.Field("Id", required=True)
"""The endpoint identity string"""
name = base.Field("Name")
"""The endpoint name"""
status = rsd_lib_common.StatusField("Status")
"""The endpoint status"""
links = LinksField("Links")
"""These links to related components of this endpoint"""
ip_transport_details = IPTransportDetailsField("IPTransportDetails")
"""IP transport details info of this endpoint"""
oem = OemField("Oem")
"""The OEM additional info of this endpoint"""
def update_authentication(self, username=None, password=None):
"""Update endpoint authentication
:param username: an endpoint username used to authenticate it on the
other side of a communication channel
:param password: an endpoint password
:raises: BadRequestError if at least one param isn't specified
"""
if username is None and password is None:
raise ValueError(
'At least "username" or "password" parameter has '
"to be specified"
)
data = {
"Oem": {
"Intel_RackScale": {
"@odata.type": "#Intel.Oem.Endpoint",
"Authentication": {},
}
}
}
if username is not None:
data["Oem"]["Intel_RackScale"]["Authentication"][
"Username"
] = username
if password is not None:
data["Oem"]["Intel_RackScale"]["Authentication"][
"Password"
] = password
self._conn.patch(self.path, data=data)
class EndpointCollection(rsd_lib_base.ResourceCollectionBase):
@property
def _resource_type(self):
return Endpoint
def _create_endpoint_request(
self,
identifiers,
connected_entities,
protocol=None,
ip_transport_details=None,
interface=None,
authentication=None,
):
request = {}
jsonschema.validate(
identifiers, endpoint_schemas.identifiers_req_schema
)
request["Identifiers"] = identifiers
jsonschema.validate(
connected_entities, endpoint_schemas.connected_entities_req_schema
)
request["ConnectedEntities"] = connected_entities
if protocol is not None:
jsonschema.validate(protocol, endpoint_schemas.protocol_req_schema)
request["EndpointProtocol"] = protocol
if ip_transport_details is not None:
jsonschema.validate(
ip_transport_details,
endpoint_schemas.ip_transport_details_req_schema,
)
request["IPTransportDetails"] = ip_transport_details
if interface is not None:
jsonschema.validate(
interface, endpoint_schemas.interface_req_schema
)
request["Links"] = {
"Oem": {
"Intel_RackScale": {
"Interfaces": [{"@odata.id": interface}]
}
}
}
if authentication is not None:
jsonschema.validate(
authentication, endpoint_schemas.authentication_req_schema
)
request["Oem"] = {
"Intel_RackScale": {"Authentication": authentication}
}
return request
def create_endpoint(
self,
identifiers,
connected_entities,
protocol=None,
ip_transport_details=None,
interface=None,
authentication=None,
):
"""Create a new endpoint
:param identifiers: provides iQN or NQN of created entity
:param connected_entities: provides information about entities
connected to the endpoint
:param protocol: the protocol used by the endpoint
:param ip_transport_details: the transport used for accessing the
endpoint
:param interface: the interface that should be used for the endpoint
connectivity
:param authentication: authentication data for target-initiator
authentication. Currently supported only for the
iSCSI protocol.
:returns: The uri of the new endpoint
"""
properties = self._create_endpoint_request(
identifiers,
connected_entities,
protocol,
ip_transport_details,
interface,
authentication,
)
resp = self._conn.post(self._path, data=properties)
LOG.info("Endpoint created at %s", resp.headers["Location"])
endpoint_url = resp.headers["Location"]
return endpoint_url[endpoint_url.find(self._path):]