metal/inventory/inventory/inventory/api/controllers/v1/ethernet_port.py

311 lines
10 KiB
Python

# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 UnitedStack 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.
#
# Copyright (c) 2013-2018 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
import six
import pecan
from pecan import rest
import wsme
from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
from inventory.api.controllers.v1 import base
from inventory.api.controllers.v1 import collection
from inventory.api.controllers.v1 import link
from inventory.api.controllers.v1 import types
from inventory.api.controllers.v1 import utils
from inventory.common import exception
from inventory.common.i18n import _
from inventory import objects
from oslo_log import log
LOG = log.getLogger(__name__)
class EthernetPortPatchType(types.JsonPatchType):
@staticmethod
def mandatory_attrs():
return []
class EthernetPort(base.APIBase):
"""API representation of an Ethernet port
This class enforces type checking and value constraints, and converts
between the internal object model and the API representation of an
Ethernet port.
"""
uuid = types.uuid
"Unique UUID for this port"
type = wtypes.text
"Represent the type of port"
name = wtypes.text
"Represent the name of the port. Unique per host"
namedisplay = wtypes.text
"Represent the display name of the port. Unique per host"
pciaddr = wtypes.text
"Represent the pci address of the port"
dev_id = int
"The unique identifier of PCI device"
pclass = wtypes.text
"Represent the pci class of the port"
pvendor = wtypes.text
"Represent the pci vendor of the port"
pdevice = wtypes.text
"Represent the pci device of the port"
psvendor = wtypes.text
"Represent the pci svendor of the port"
psdevice = wtypes.text
"Represent the pci sdevice of the port"
numa_node = int
"Represent the numa node or zone sdevice of the port"
sriov_totalvfs = int
"The total number of available SR-IOV VFs"
sriov_numvfs = int
"The number of configured SR-IOV VFs"
sriov_vfs_pci_address = wtypes.text
"The PCI Addresses of the VFs"
driver = wtypes.text
"The kernel driver for this device"
mac = wsme.wsattr(types.macaddress, mandatory=False)
"Represent the MAC Address of the port"
mtu = int
"Represent the MTU size (bytes) of the port"
speed = int
"Represent the speed (MBytes/sec) of the port"
link_mode = int
"Represent the link mode of the port"
duplex = wtypes.text
"Represent the duplex mode of the port"
autoneg = wtypes.text
"Represent the auto-negotiation mode of the port"
bootp = wtypes.text
"Represent the bootp port of the host"
capabilities = {wtypes.text: utils.ValidTypes(wtypes.text,
six.integer_types)}
"Represent meta data of the port"
host_id = int
"Represent the host_id the port belongs to"
bootif = wtypes.text
"Represent whether the port is a boot port"
dpdksupport = bool
"Represent whether or not the port supports DPDK acceleration"
host_uuid = types.uuid
"Represent the UUID of the host the port belongs to"
node_uuid = types.uuid
"Represent the UUID of the node the port belongs to"
links = [link.Link]
"Represent a list containing a self link and associated port links"
def __init__(self, **kwargs):
self.fields = objects.EthernetPort.fields.keys()
for k in self.fields:
setattr(self, k, kwargs.get(k))
@classmethod
def convert_with_links(cls, rpc_port, expand=True):
port = EthernetPort(**rpc_port.as_dict())
if not expand:
port.unset_fields_except(['uuid', 'host_id', 'node_id',
'type', 'name',
'namedisplay', 'pciaddr', 'dev_id',
'pclass', 'pvendor', 'pdevice',
'psvendor', 'psdevice', 'numa_node',
'mac', 'sriov_totalvfs', 'sriov_numvfs',
'sriov_vfs_pci_address', 'driver',
'mtu', 'speed', 'link_mode',
'duplex', 'autoneg', 'bootp',
'capabilities',
'host_uuid',
'node_uuid', 'dpdksupport',
'created_at', 'updated_at'])
# never expose the id attribute
port.host_id = wtypes.Unset
port.node_id = wtypes.Unset
port.links = [link.Link.make_link('self', pecan.request.host_url,
'ethernet_ports', port.uuid),
link.Link.make_link('bookmark',
pecan.request.host_url,
'ethernet_ports', port.uuid,
bookmark=True)
]
return port
class EthernetPortCollection(collection.Collection):
"""API representation of a collection of EthernetPort objects."""
ethernet_ports = [EthernetPort]
"A list containing EthernetPort objects"
def __init__(self, **kwargs):
self._type = 'ethernet_ports'
@classmethod
def convert_with_links(cls, rpc_ports, limit, url=None,
expand=False, **kwargs):
collection = EthernetPortCollection()
collection.ethernet_ports = [EthernetPort.convert_with_links(p, expand)
for p in rpc_ports]
collection.next = collection.get_next(limit, url=url, **kwargs)
return collection
LOCK_NAME = 'EthernetPortController'
class EthernetPortController(rest.RestController):
"""REST controller for EthernetPorts."""
_custom_actions = {
'detail': ['GET'],
}
def __init__(self, from_hosts=False, from_node=False):
self._from_hosts = from_hosts
self._from_node = from_node
def _get_ports_collection(self, uuid, node_uuid,
marker, limit, sort_key, sort_dir,
expand=False, resource_url=None):
if self._from_hosts and not uuid:
raise exception.InvalidParameterValue(_(
"Host id not specified."))
if self._from_node and not uuid:
raise exception.InvalidParameterValue(_(
"node id not specified."))
limit = utils.validate_limit(limit)
sort_dir = utils.validate_sort_dir(sort_dir)
marker_obj = None
if marker:
marker_obj = objects.EthernetPort.get_by_uuid(
pecan.request.context,
marker)
if self._from_hosts:
ports = objects.EthernetPort.get_by_host(
pecan.request.context,
uuid, limit,
marker=marker_obj,
sort_key=sort_key,
sort_dir=sort_dir)
elif self._from_node:
ports = objects.EthernetPort.get_by_numa_node(
pecan.request.context,
uuid, limit,
marker=marker_obj,
sort_key=sort_key,
sort_dir=sort_dir)
else:
if uuid:
ports = objects.EthernetPort.get_by_host(
pecan.request.context,
uuid, limit,
marker=marker_obj,
sort_key=sort_key,
sort_dir=sort_dir)
else:
ports = objects.EthernetPort.list(
pecan.request.context,
limit, marker=marker_obj,
sort_key=sort_key,
sort_dir=sort_dir)
return EthernetPortCollection.convert_with_links(
ports, limit, url=resource_url,
expand=expand,
sort_key=sort_key,
sort_dir=sort_dir)
@wsme_pecan.wsexpose(EthernetPortCollection, types.uuid, types.uuid,
types.uuid, int, wtypes.text, wtypes.text)
def get_all(self, uuid=None, node_uuid=None,
marker=None, limit=None, sort_key='id', sort_dir='asc'):
"""Retrieve a list of ports."""
return self._get_ports_collection(uuid,
node_uuid,
marker, limit, sort_key, sort_dir)
@wsme_pecan.wsexpose(EthernetPortCollection, types.uuid, types.uuid, int,
wtypes.text, wtypes.text)
def detail(self, uuid=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'):
"""Retrieve a list of ports with detail."""
parent = pecan.request.path.split('/')[:-1][-1]
if parent != "ethernet_ports":
raise exception.HTTPNotFound
expand = True
resource_url = '/'.join(['ethernet_ports', 'detail'])
return self._get_ports_collection(uuid, marker, limit, sort_key,
sort_dir, expand, resource_url)
@wsme_pecan.wsexpose(EthernetPort, types.uuid)
def get_one(self, port_uuid):
"""Retrieve information about the given port."""
if self._from_hosts:
raise exception.OperationNotPermitted
rpc_port = objects.EthernetPort.get_by_uuid(
pecan.request.context, port_uuid)
return EthernetPort.convert_with_links(rpc_port)