[PTP dual NIC config] 2nd review of PTP data model

In the original review of PTP data model:
https://review.opendev.org/c/starlingx/config/+/819391 the relationships
between ihost:PtpInstances and Interface:PtpInterfaces need to be many-
to-many like between PtpParameters:PtpParameterOwners, in order to allow
the same host run different PTP instances (services) as well for
interfaces.

Test Plan:

PASS: Fresh install shows all new tables and relationships while system
is responsive for other usual tasks (smoke test)

Regression:

PASS: All the previous test cases for PTP tables keep running with
success. New test cases are planned to support the new relationships.

Story: 2009248
Task: 44146
Signed-off-by: Douglas Henrique Koerich <douglashenrique.koerich@windriver.com>
Change-Id: Id03881cf354e77862a770fc9b71b6bb0ab14aa19
This commit is contained in:
Douglas Henrique Koerich 2021-12-07 14:57:54 -03:00
parent a291b5a4cc
commit 37aec5c439
22 changed files with 1083 additions and 69 deletions

View File

@ -70,7 +70,9 @@ from cgtsclient.v1 import pci_device
from cgtsclient.v1 import port
from cgtsclient.v1 import ptp
from cgtsclient.v1 import ptp_instance
from cgtsclient.v1 import ptp_instance_map
from cgtsclient.v1 import ptp_interface
from cgtsclient.v1 import ptp_interface_map
from cgtsclient.v1 import ptp_parameter
from cgtsclient.v1 import ptp_paramownership
from cgtsclient.v1 import registry_image
@ -123,7 +125,9 @@ class Client(http.HTTPClient):
self.intp = intp.intpManager(self)
self.ptp = ptp.ptpManager(self)
self.ptp_instance = ptp_instance.PtpInstanceManager(self)
self.ptp_instance_map = ptp_instance_map.PtpInstanceMapManager(self)
self.ptp_interface = ptp_interface.PtpInterfaceManager(self)
self.ptp_interface_map = ptp_interface_map.PtpInterfaceMapManager(self)
self.ptp_parameter = ptp_parameter.PtpParameterManager(self)
self.ptp_paramownership = \
ptp_paramownership.PtpParameterOwnershipManager(self)

View File

@ -0,0 +1,44 @@
########################################################################
#
# Copyright (c) 2021 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
########################################################################
from cgtsclient.common import base
from cgtsclient import exc
CREATION_ATTRIBUTES = ['host_id', 'ptp_instance_id']
class PtpInstanceMap(base.Resource):
def __repr__(self):
return "<PtpInstanceMap %s>" % self._info
class PtpInstanceMapManager(base.Manager):
resource_class = PtpInstanceMap
def _path(self, ptp_instance_map_id=None):
return '/v1/ptp_instance_maps/%s' % ptp_instance_map_id \
if ptp_instance_map_id else '/v1/ptp_instance_maps'
def get(self, ptp_instance_map_id):
try:
return self._list(self._path(ptp_instance_map_id))[0]
except IndexError:
return None
def create(self, **kwargs):
data = {}
for (key, value) in kwargs.items():
if key in CREATION_ATTRIBUTES:
data[key] = value
else:
raise exc.InvalidAttribute('%s' % key)
return self._create(self._path(), data)
def delete(self, ptp_instance_map_id):
return self._delete(self._path(ptp_instance_map_id))

View File

@ -0,0 +1,44 @@
########################################################################
#
# Copyright (c) 2021 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
########################################################################
from cgtsclient.common import base
from cgtsclient import exc
CREATION_ATTRIBUTES = ['interface_id', 'ptp_interface_id']
class PtpInterfaceMap(base.Resource):
def __repr__(self):
return "<PtpInterfaceMap %s>" % self._info
class PtpInterfaceMapManager(base.Manager):
resource_class = PtpInterfaceMap
def _path(self, ptp_interface_map_id=None):
return '/v1/ptp_interface_maps/%s' % ptp_interface_map_id \
if ptp_interface_map_id else '/v1/ptp_interface_maps'
def get(self, ptp_interface_map_id):
try:
return self._list(self._path(ptp_interface_map_id))[0]
except IndexError:
return None
def create(self, **kwargs):
data = {}
for (key, value) in kwargs.items():
if key in CREATION_ATTRIBUTES:
data[key] = value
else:
raise exc.InvalidAttribute('%s' % key)
return self._create(self._path(), data)
def delete(self, ptp_interface_map_id):
return self._delete(self._path(ptp_interface_map_id))

View File

@ -66,7 +66,9 @@ from sysinv.api.controllers.v1 import pci_device
from sysinv.api.controllers.v1 import port
from sysinv.api.controllers.v1 import ptp
from sysinv.api.controllers.v1 import ptp_instance
from sysinv.api.controllers.v1 import ptp_instance_map
from sysinv.api.controllers.v1 import ptp_interface
from sysinv.api.controllers.v1 import ptp_interface_map
from sysinv.api.controllers.v1 import ptp_parameter
from sysinv.api.controllers.v1 import ptp_paramownership
from sysinv.api.controllers.v1 import pv
@ -153,9 +155,15 @@ class V1(base.APIBase):
ptp_instances = [link.Link]
"Links to the ptp_instances resource"
ptp_instance_maps = [link.Link]
"Links to the ptp_instance_maps resource"
ptp_interfaces = [link.Link]
"Links to the ptp_interfaces resource"
ptp_interface_maps = [link.Link]
"Links to the ptp_interface_maps resource"
ptp_parameters = [link.Link]
"Links to the ptp_parameters resource"
@ -469,6 +477,14 @@ class V1(base.APIBase):
'ptp_instances', '',
bookmark=True)]
v1.ptp_instance_maps = [link.Link.make_link('self',
pecan.request.host_url,
'ptp_instance_maps', ''),
link.Link.make_link('bookmark',
pecan.request.host_url,
'ptp_instance_maps', '',
bookmark=True)]
v1.ptp_interfaces = [link.Link.make_link('self', pecan.request.host_url,
'ptp_interfaces', ''),
link.Link.make_link('bookmark',
@ -477,6 +493,14 @@ class V1(base.APIBase):
bookmark=True)
]
v1.ptp_interface_maps = [link.Link.make_link('self',
pecan.request.host_url,
'ptp_instance_maps', ''),
link.Link.make_link('bookmark',
pecan.request.host_url,
'ptp_instance_maps', '',
bookmark=True)]
v1.ptp_parameters = [link.Link.make_link('self', pecan.request.host_url,
'ptp_parameters', ''),
link.Link.make_link('bookmark',
@ -935,7 +959,9 @@ class Controller(rest.RestController):
intp = ntp.NTPController()
ptp = ptp.PTPController()
ptp_instances = ptp_instance.PtpInstanceController()
ptp_instance_maps = ptp_instance_map.PtpInstanceMapController()
ptp_interfaces = ptp_interface.PtpInterfaceController()
ptp_interface_maps = ptp_interface_map.PtpInterfaceMapController()
ptp_parameters = ptp_parameter.PtpParameterController()
ptp_parameter_ownerships = \
ptp_paramownership.PtpParameterOwnershipController()

View File

@ -0,0 +1,167 @@
#
# Copyright (c) 2021 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
import pecan
from pecan import rest
import wsme
from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
from oslo_log import log
from sysinv._i18n import _
from sysinv.api.controllers.v1 import base
from sysinv.api.controllers.v1 import collection
from sysinv.api.controllers.v1 import types
from sysinv.common import exception
from sysinv.common import utils as cutils
from sysinv import objects
LOG = log.getLogger(__name__)
class PtpInstanceMapPatchType(types.JsonPatchType):
@staticmethod
def mandatory_attrs():
return []
class PtpInstanceMap(base.APIBase):
"""API representation of a PTP instance map to host.
This class enforces type checking and value constraints, and converts
between the internal object model and the API representation of
a PTP instance association to host.
"""
created_at = wtypes.datetime.datetime
"Timestamp of creation of this PTP instance mapping"
id = int
"Unique ID for this PTP instance mapping"
uuid = types.uuid
"Unique UUID for this PTP instance mapping"
host_id = int
"ID of the associated host"
hostname = wtypes.text
"Name of the associated host"
ptp_instance_id = int
"ID of the associated PTP instance"
name = wtypes.text
"Name of the associated PTP instance"
service = wtypes.text
"Service type of the associated PTP instance"
def __init__(self, **kwargs):
self.fields = list(objects.ptp_instance_map.fields.keys())
for k in self.fields:
if not hasattr(self, k):
continue
setattr(self, k, kwargs.get(k))
@classmethod
def convert_with_links(cls, rpc_ptp_instance_map, expand=True):
ptp_instance_map = PtpInstanceMap(**rpc_ptp_instance_map.as_dict())
if not expand:
ptp_instance_map.unset_fields_except(
['uuid', 'host_id', 'hostname', 'ptp_instance_id',
'name', 'service', 'created_at'])
LOG.debug("PtpInstanceMap.convert_with_links: converted %s" %
ptp_instance_map.as_dict())
return ptp_instance_map
class PtpInstanceMapCollection(collection.Collection):
"""API representation of a collection of PTP instance maps."""
ptp_instance_maps = [PtpInstanceMap]
"A list containing PTP instance mapping objects"
def __init__(self, **kwargs):
self._type = 'ptp_instance_maps'
@classmethod
def convert_with_links(cls, rpc_ptp_instance_maps, limit, url=None,
expand=False, **kwargs):
collection = PtpInstanceMapCollection()
collection.ptp_instance_maps = \
[PtpInstanceMap.convert_with_links(p, expand)
for p in rpc_ptp_instance_maps]
collection.next = collection.get_next(limit, url=url, **kwargs)
return collection
LOCK_NAME = 'PtpInstanceMapController'
class PtpInstanceMapController(rest.RestController):
"""REST controller for PTP instance map."""
@wsme_pecan.wsexpose(PtpInstanceMap, types.uuid)
def get_one(self, ptp_instance_map_uuid):
"""Retrieve a single PTP instance."""
LOG.debug("PtpInstanceMapController.get_one: uuid=%s" %
ptp_instance_map_uuid)
try:
ptp_instance_map = objects.ptp_instance_map.get_by_uuid(
pecan.request.context,
ptp_instance_map_uuid)
except exception.InvalidParameterValue:
raise wsme.exc.ClientSideError(
_("No PTP instance mapping found for %s"
% ptp_instance_map_uuid))
return PtpInstanceMap.convert_with_links(ptp_instance_map)
def _check_instance_exists(self, id):
LOG.debug("PtpInstanceMapController._check_instance_exists: "
"id %d" % id)
try:
pecan.request.dbapi.ptp_instance_get(id)
except exception.PtpInstanceNotFound:
raise wsme.exc.ClientSideError(
_("No PTP parameter object found with id %d" % id))
def _check_host_exists(self, id):
LOG.debug("PtpInstanceMapController._check_host_exists: "
"id %d" % id)
try:
pecan.request.dbapi.ihost_get(id)
except exception.ServerNotFound:
raise wsme.exc.ClientSideError(
_("No host found with id %d" % id))
@cutils.synchronized(LOCK_NAME)
@wsme_pecan.wsexpose(PtpInstanceMap, body=PtpInstanceMap)
def post(self, ptp_instance_map):
"""Create a new PTP instance mapping."""
ptp_instance_map_dict = ptp_instance_map.as_dict()
LOG.debug("PtpInstanceMapController.post: %s"
% ptp_instance_map_dict)
self._check_instance_exists(ptp_instance_map_dict['ptp_instance_id'])
self._check_host_exists(ptp_instance_map_dict['host_id'])
result = pecan.request.dbapi.ptp_instance_set_host(
ptp_instance_map_dict)
return PtpInstanceMap.convert_with_links(result)
@cutils.synchronized(LOCK_NAME)
@wsme_pecan.wsexpose(None, types.uuid, status_code=204)
def delete(self, ptp_instance_map_uuid):
"""Delete a PTP instance mapping."""
LOG.debug("PtpInstanceMapController.delete: %s"
% ptp_instance_map_uuid)
ptp_instance_map = objects.ptp_instance_map.get_by_uuid(
pecan.request.context, ptp_instance_map_uuid)
pecan.request.dbapi.ptp_parameter_unset_host(
ptp_instance_map.as_dict())

View File

@ -0,0 +1,174 @@
#
# Copyright (c) 2021 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
import pecan
from pecan import rest
import wsme
from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
from oslo_log import log
from sysinv._i18n import _
from sysinv.api.controllers.v1 import base
from sysinv.api.controllers.v1 import collection
from sysinv.api.controllers.v1 import types
from sysinv.common import exception
from sysinv.common import utils as cutils
from sysinv import objects
LOG = log.getLogger(__name__)
class PtpInterfaceMapPatchType(types.JsonPatchType):
@staticmethod
def mandatory_attrs():
return []
class PtpInterfaceMap(base.APIBase):
"""API representation of a PTP interface map to interface.
This class enforces type checking and value constraints, and converts
between the internal object model and the API representation of
a PTP interface association to interface.
"""
created_at = wtypes.datetime.datetime
"Timestamp of creation of this PTP interface mapping"
id = int
"Unique ID for this PTP interface mapping"
uuid = types.uuid
"Unique UUID for this PTP interface mapping"
interface_id = int
"ID of the associated interface"
ifname = wtypes.text
"Name of the associated interface"
iftype = wtypes.text
"Type of the associated interface"
hostname = wtypes.text
"Name of the host for the associated interface"
ptp_interface_id = int
"ID of the associated PTP interface"
name = wtypes.text
"Name of the PTP instance for the associated PTP interface"
service = wtypes.text
"Service type of the PTP instance for the associated PTP interface"
def __init__(self, **kwargs):
self.fields = list(objects.ptp_interface_map.fields.keys())
for k in self.fields:
if not hasattr(self, k):
continue
setattr(self, k, kwargs.get(k))
@classmethod
def convert_with_links(cls, rpc_ptp_interface_map, expand=True):
ptp_interface_map = PtpInterfaceMap(**rpc_ptp_interface_map.as_dict())
if not expand:
ptp_interface_map.unset_fields_except(
['uuid', 'interface_id', 'ifname', 'iftype', 'hostname',
'ptp_interface_id', 'name', 'service', 'created_at'])
LOG.debug("PtpInterfaceMap.convert_with_links: converted %s" %
ptp_interface_map.as_dict())
return ptp_interface_map
class PtpInterfaceMapCollection(collection.Collection):
"""API representation of a collection of PTP interface maps."""
ptp_interface_maps = [PtpInterfaceMap]
"A list containing PTP interface map objects"
def __init__(self, **kwargs):
self._type = 'ptp_interface_maps'
@classmethod
def convert_with_links(cls, rpc_ptp_interface_maps, limit, url=None,
expand=False, **kwargs):
collection = PtpInterfaceMapCollection()
collection.ptp_interface_maps = \
[PtpInterfaceMap.convert_with_links(p, expand)
for p in rpc_ptp_interface_maps]
collection.next = collection.get_next(limit, url=url, **kwargs)
return collection
LOCK_NAME = 'PtpInterfaceMapController'
class PtpInterfaceMapController(rest.RestController):
"""REST controller for PTP interface map."""
@wsme_pecan.wsexpose(PtpInterfaceMap, types.uuid)
def get_one(self, ptp_interface_map_uuid):
"""Retrieve a single PTP interface."""
LOG.debug("PtpInterfaceMapController.get_one: uuid=%s" %
ptp_interface_map_uuid)
try:
ptp_interface_map = objects.ptp_interface_map.get_by_uuid(
pecan.request.context,
ptp_interface_map_uuid)
except exception.InvalidParameterValue:
raise wsme.exc.ClientSideError(
_("No PTP interface mapping found for %s"
% ptp_interface_map_uuid))
return PtpInterfaceMap.convert_with_links(ptp_interface_map)
def _check_interface_exists(self, id):
LOG.debug("PtpInterfaceMapController._check_interface_exists: "
"id %d" % id)
try:
pecan.request.dbapi.iinterface_get(id)
except exception.InvalidParameterValue:
raise wsme.exc.ClientSideError(
_("No interface found with id %d" % id))
def _check_ptp_interface_exists(self, id):
LOG.debug("PtpInterfaceMapController._check_ptp_interface_exists: "
"id %d" % id)
try:
pecan.request.dbapi.ptp_interface_get(id)
except exception.PtpInterfaceNotFound:
raise wsme.exc.ClientSideError(
_("No PTP interface found with id %d" % id))
@cutils.synchronized(LOCK_NAME)
@wsme_pecan.wsexpose(PtpInterfaceMap, body=PtpInterfaceMap)
def post(self, ptp_interface_map):
"""Create a new PTP interface mapping."""
ptp_interface_map_dict = ptp_interface_map.as_dict()
LOG.debug("PtpInterfaceMapController.post: %s"
% ptp_interface_map_dict)
self._check_interface_exists(ptp_interface_map_dict['interface_id'])
self._check_ptp_interface_exists(
ptp_interface_map_dict['ptp_interface_id'])
result = pecan.request.dbapi.ptp_interface_set_interface(
ptp_interface_map_dict)
return PtpInterfaceMap.convert_with_links(result)
@cutils.synchronized(LOCK_NAME)
@wsme_pecan.wsexpose(None, types.uuid, status_code=204)
def delete(self, ptp_interface_map_uuid):
"""Delete a PTP interface mapping."""
LOG.debug("PtpInterfaceMapController.delete: %s"
% ptp_interface_map_uuid)
ptp_interface_map = objects.ptp_interface_map.get_by_uuid(
pecan.request.context, ptp_interface_map_uuid)
pecan.request.dbapi.ptp_parameter_unset_interface(
ptp_interface_map.as_dict())

View File

@ -46,7 +46,13 @@ class PtpParameterOwnership(base.APIBase):
"Unique UUID for this PTP parameter ownership"
parameter_uuid = types.uuid
"UUID of the PTP parameter (name/value)"
"UUID of the PTP parameter"
parameter_name = wtypes.text
"Name of the PTP parameter"
parameter_value = wtypes.text
"Value of the PTP parameter"
owner_uuid = types.uuid
"UUID of the entity associated to PTP parameter (instance or interface)"
@ -64,7 +70,8 @@ class PtpParameterOwnership(base.APIBase):
**rpc_ptp_paramownership.as_dict())
if not expand:
ptp_parameter_ownership.unset_fields_except(
['uuid', 'parameter_uuid', 'owner_uuid', 'created_at'])
['uuid', 'parameter_uuid', 'parameter_name', 'parameter_value',
'owner_uuid', 'created_at'])
LOG.debug("PtpParameterOwnership.convert_with_links: converted %s" %
ptp_parameter_ownership.as_dict())
@ -139,6 +146,14 @@ class PtpParameterOwnershipController(rest.RestController):
LOG.debug("PtpParameterOwnershipController.post: %s"
% ptp_paramownership_dict)
# Get rid of parameter details to set the ownership
try:
ptp_paramownership_dict.pop('parameter_name')
ptp_paramownership_dict.pop('parameter_value')
except KeyError:
LOG.debug("PtpParameterController.post: no parameter data in %s" %
ptp_paramownership_dict)
self._check_parameter_exists(ptp_paramownership_dict['parameter_uuid'])
self._check_owner_exists(ptp_paramownership_dict['owner_uuid'])
@ -150,7 +165,7 @@ class PtpParameterOwnershipController(rest.RestController):
@wsme_pecan.wsexpose(None, types.uuid, status_code=204)
def delete(self, ptp_paramownership_uuid):
"""Delete a PTP parameter ownership."""
LOG.debug("PtpParameterController.delete: %s"
LOG.debug("PtpParameterOwnershipController.delete: %s"
% ptp_paramownership_uuid)
ptp_paramownership = objects.ptp_paramownership.get_by_uuid(
pecan.request.context, ptp_paramownership_uuid)

View File

@ -469,6 +469,16 @@ class PtpParameterOwnershipAlreadyExists(Conflict):
message = _("UUID %(param)s is already a PTP parameter of UUID %(owner)s.")
class PtpInstanceMapAlreadyExists(Conflict):
message = _("PTP instance %(ptp_instance)s is already associated to host "
"%(host)s.")
class PtpInterfaceMapAlreadyExists(Conflict):
message = _("PTP interface %(ptp_interface)s is already associated to "
"interface %(interface)s.")
class PMAlreadyExists(Conflict):
message = _("A PM with UUID %(uuid)s already exists.")
@ -617,6 +627,14 @@ class PtpParameterOwnershipNotFound(NotFound):
message = _("No PTP parameter ownership with id %(uuid)s found.")
class PtpInstanceMapNotFound(NotFound):
message = _("No PTP instance mapping with id %(uuid)s found.")
class PtpInterfaceMapNotFound(NotFound):
message = _("No PTP interface mapping with id %(uuid)s found.")
class DiskNotFound(NotFound):
message = _("No disk with id %(disk_id)s")

View File

@ -1938,11 +1938,11 @@ class Connection(object):
"""
@abc.abstractmethod
def ptp_instances_get_list(self, host=None, limit=None, marker=None,
def ptp_instances_get_list(self, host_uuid=None, limit=None, marker=None,
sort_key=None, sort_dir=None):
"""Returns a list of PTP service instances.
:param host: id or uuid of host.
:param host_uuid: id or uuid of host.
:param limit: Maximum number of PTP instances to return.
:param marker: The last item of the previous page; we return the next
result set.
@ -1952,6 +1952,46 @@ class Connection(object):
:returns: A list of PTP instances.
"""
@abc.abstractmethod
def ptp_instance_set_host(self, values):
"""Set the PTP instance to some host.
:param values: A dict containing the IDs used to associate
the PTP instance to the host.
{
'host_id': 1,
'ptp_instance_id': 3
}
:returns: A PTP instance mapping.
"""
@abc.abstractmethod
def ptp_instance_unset_host(self, values):
"""Remove the association between a PTP instance and a host.
:param values: A dict containing the IDs used to associate
the PTP instance to the host.
{
'host_id': 1,
'ptp_instance_id': 3
}
"""
@abc.abstractmethod
def ptp_instance_get_hosts(self, ptp_instance_id, limit=None, marker=None,
sort_key=None, sort_dir=None):
"""Returns a list of all hosts associated to the PTP instance.
:param ptp_instance_id: The id or uuid of a PTP instance.
:param limit: Maximum number of hosts to return.
:param marker: The last item of the previous page; we return the next
result set.
:param sort_key: Attribute by which results should be sorted
:param sort_dir: direction in which results should be sorted
(asc, desc)
:returns: A list of hosts for the given PTP instance.
"""
@abc.abstractmethod
def ptp_instance_destroy(self, ptp_instance_id):
"""Destroys a PTP service instance.
@ -1966,6 +2006,14 @@ class Connection(object):
:param name: The name given for a PTP instance.
"""
@abc.abstractmethod
def ptp_instance_map_get(self, ptp_instance_map_id):
"""Returns a PTP instance mapping.
:param ptp_instance_map_id: The id or uuid of a PTP instance map.
:returns: A PTP instance map.
"""
@abc.abstractmethod
def ptp_interface_create(self, values):
"""Creates a new PTP association between an interface
@ -2046,6 +2094,46 @@ class Connection(object):
interface.
"""
@abc.abstractmethod
def ptp_interface_set_interface(self, values):
"""Set the PTP interface to some interface.
:param values: A dict containing the IDs used to associate
the PTP interface to the interface.
{
'interface_id': 1,
'ptp_interface_id': 3
}
:returns: A PTP interface mapping.
"""
@abc.abstractmethod
def ptp_interface_unset_interface(self, values):
"""Remove the association between a PTP interface and a interface.
:param values: A dict containing the IDs used to associate
the PTP interface to the interface.
{
'interface_id': 1,
'ptp_interface_id': 3
}
"""
@abc.abstractmethod
def ptp_interface_get_interfaces(self, ptp_interface_id, limit=None,
marker=None, sort_key=None, sort_dir=None):
"""Returns a list of all interfaces associated to the PTP interface.
:param ptp_interface_id: The id or uuid of a PTP interface.
:param limit: Maximum number of interfaces to return.
:param marker: The last item of the previous page; we return the next
result set.
:param sort_key: Attribute by which results should be sorted
:param sort_dir: direction in which results should be sorted
(asc, desc)
:returns: A list of interfaces for the given PTP interface.
"""
@abc.abstractmethod
def ptp_interface_destroy(self, ptp_interface_id):
"""Destroys a PTP interface association.
@ -2053,6 +2141,14 @@ class Connection(object):
:param ptp_interface_id: The id or uuid of a PTP interface association.
"""
@abc.abstractmethod
def ptp_interface_map_get(self, ptp_interface_map_id):
"""Returns a PTP interface mapping.
:param ptp_interface_map_id: The id or uuid of a PTP interface map.
:returns: A PTP interface map.
"""
@abc.abstractmethod
def ptp_parameter_create(self, values):
"""Creates a new PTP parameter to be applied later either to some

View File

@ -3779,25 +3779,58 @@ class Connection(api.Connection):
raise exception.NotFound()
@objects.objectify(objects.ptp_instance)
def ptp_instances_get_list(self, host=None, limit=None, marker=None,
def ptp_instances_get_list(self, host_uuid=None, limit=None, marker=None,
sort_key=None, sort_dir=None):
query = model_query(models.PtpInstances)
if host is not None:
if utils.is_int_like(host):
ihost = self.ihost_get(int(host))
elif utils.is_uuid_like(host):
ihost = self.ihost_get(host.strip())
elif isinstance(host, models.ihost):
ihost = host
else:
raise exception.NodeNotFound(node=host)
ptp_instance_id = ihost['ptp_instance_id']
if not ptp_instance_id:
return []
query = add_identity_filter(query, ptp_instance_id)
if host_uuid is not None:
host = self.ihost_get(host_uuid)
query = query.join(models.PtpInstanceMaps,
models.PtpInstanceMaps.host_id == host.id)
return _paginate_query(models.PtpInstances, limit, marker,
sort_key, sort_dir, query)
@objects.objectify(objects.ptp_instance_map)
def ptp_instance_set_host(self, values):
if not values.get('uuid'):
values['uuid'] = uuidutils.generate_uuid()
ptp_instance_map = models.PtpInstanceMaps(**values)
with _session_for_write() as session:
try:
session.add(ptp_instance_map)
session.flush()
except db_exc.DBDuplicateEntry:
raise exception.PtpInstanceMapAlreadyExists(
ptp_instance=values['ptp_instance_id'],
host=values['host_id'])
query = model_query(models.PtpInstanceMaps)
query = add_identity_filter(query, values['uuid'])
try:
return query.one()
except NoResultFound:
raise exception.PtpInstanceMapNotFound(uuid=values['uuid'])
def ptp_instance_unset_host(self, values):
with _session_for_write() as session:
query = model_query(models.PtpInstanceMaps, session=session)
query = query.filter_by(ptp_instance_id=values['ptp_instance_id'],
host_id=values['host_id'])
try:
query.one()
except NoResultFound:
return
query.delete()
@objects.objectify(objects.ptp_instance)
def ptp_instance_get_hosts(self, ptp_instance_id, limit=None, marker=None,
sort_key=None, sort_dir=None):
query = model_query(models.PtpInstances)
query = add_identity_filter(query, ptp_instance_id)
query = query.join(models.PtpInstances.hosts)
return _paginate_query(models.PtpInstances, limit, marker, sort_key,
sort_dir, query)
def ptp_instance_destroy(self, ptp_instance_id):
with _session_for_write() as session:
# PTP instance will be deleted by cascade
@ -3819,6 +3852,15 @@ class Connection(api.Connection):
raise exception.NotFound()
query.delete()
@objects.objectify(objects.ptp_instance_map)
def ptp_instance_map_get(self, ptp_instance_map_id):
query = model_query(models.PtpInstanceMaps)
query = add_identity_filter(query, ptp_instance_map_id)
try:
return query.one()
except NoResultFound:
raise exception.PtpInstanceMapNotFound(uuid=ptp_instance_map_id)
def _ptp_interface_get(self, ptp_interface_id):
query = model_query(models.PtpInterfaces)
query = add_identity_filter(query, ptp_interface_id)
@ -3910,6 +3952,50 @@ class Connection(api.Connection):
return _paginate_query(models.PtpInterfaces, limit, marker,
sort_key, sort_dir, query)
@objects.objectify(objects.ptp_interface_map)
def ptp_interface_set_interface(self, values):
if not values.get('uuid'):
values['uuid'] = uuidutils.generate_uuid()
ptp_interface_map = models.PtpInterfaceMaps(**values)
with _session_for_write() as session:
try:
session.add(ptp_interface_map)
session.flush()
except db_exc.DBDuplicateEntry:
raise exception.PtpInterfaceMapAlreadyExists(
ptp_interface=values['ptp_interface_id'],
interface=values['interface_id'])
query = model_query(models.PtpInterfaceMaps)
query = add_identity_filter(query, values['uuid'])
try:
return query.one()
except NoResultFound:
raise exception.PtpInterfaceMapNotFound(uuid=values['uuid'])
def ptp_interface_unset_interface(self, values):
with _session_for_write() as session:
query = model_query(models.PtpInterfaceMaps, session=session)
query = query.filter_by(
ptp_interface_id=values['ptp_interface_id'],
interface_id=values['interface_id'])
try:
query.one()
except NoResultFound:
return
query.delete()
@objects.objectify(objects.ptp_interface)
def ptp_interface_get_interfaces(self, ptp_interface_id, limit=None,
marker=None, sort_key=None,
sort_dir=None):
query = model_query(models.PtpInterfaces)
query = add_identity_filter(query, ptp_interface_id)
query = query.join(models.PtpInterfaces.interfaces)
return _paginate_query(models.PtpInterfaces, limit, marker, sort_key,
sort_dir, query)
def ptp_interface_destroy(self, ptp_interface_id):
with _session_for_write() as session:
# PTP instance will be deleted by cascade
@ -3921,6 +4007,15 @@ class Connection(api.Connection):
raise exception.PtpInterfaceNotFound(uuid=ptp_interface_id)
query.delete()
@objects.objectify(objects.ptp_interface_map)
def ptp_interface_map_get(self, ptp_interface_map_id):
query = model_query(models.PtpInterfaceMaps)
query = add_identity_filter(query, ptp_interface_map_id)
try:
return query.one()
except NoResultFound:
raise exception.PtpInterfaceMapNotFound(uuid=ptp_interface_map_id)
def _ptp_parameter_get(self, ptp_parameter_id):
query = model_query(models.PtpParameters)
query = add_identity_filter(query, ptp_parameter_id)

View File

@ -21,8 +21,7 @@ ENGINE = 'InnoDB'
CHARSET = 'utf8'
def _populate_ptp_tables(meta, ptp_instances, ptp_interfaces,
ptp_parameters, ptp_parameter_ownerships):
def _populate_ptp_tables(meta, tables):
"""This function moves PTP configuration from other tables:
- If advanced (specialized) ptp4l configuration is found in
'service_parameter' table, it inserts a 'ptp4l' entry in
@ -46,6 +45,8 @@ def upgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
tables = {}
ptp_parameters = Table(
'ptp_parameters',
meta,
@ -65,6 +66,7 @@ def upgrade(migrate_engine):
mysql_charset=CHARSET,
)
ptp_parameters.create()
tables.update({'ptp_parameters': ptp_parameters})
ptp_parameter_owners = Table(
'ptp_parameter_owners',
@ -84,6 +86,7 @@ def upgrade(migrate_engine):
mysql_charset=CHARSET,
)
ptp_parameter_owners.create()
tables.update({'ptp_parameter_owners': ptp_parameter_owners})
ptp_instances = Table(
'ptp_instances',
@ -103,10 +106,7 @@ def upgrade(migrate_engine):
mysql_charset=CHARSET,
)
ptp_instances.create()
host = Table('i_host', meta, autoload=True)
host.create_column(
Column('ptp_instance_id', Integer, ForeignKey('ptp_instances.id')))
tables.update({'ptp_instances': ptp_instances})
ptp_interfaces = Table(
'ptp_interfaces',
@ -127,10 +127,7 @@ def upgrade(migrate_engine):
mysql_charset=CHARSET,
)
ptp_interfaces.create()
interface = Table('interfaces', meta, autoload=True)
interface.create_column(
Column('ptp_interface_id', Integer, ForeignKey('ptp_interfaces.id')))
tables.update({'ptp_interfaces': ptp_interfaces})
ptp_parameter_ownerships = Table(
'ptp_parameter_ownerships',
@ -145,7 +142,9 @@ def upgrade(migrate_engine):
Column('parameter_uuid', String(UUID_LENGTH),
ForeignKey('ptp_parameters.uuid', ondelete='CASCADE'),
nullable=False),
Column('owner_uuid', String(UUID_LENGTH), nullable=False),
Column('owner_uuid', String(UUID_LENGTH),
ForeignKey('ptp_parameter_owners.uuid', ondelete='CASCADE'),
nullable=False),
UniqueConstraint('parameter_uuid', 'owner_uuid', name='u_paramowner'),
@ -153,15 +152,78 @@ def upgrade(migrate_engine):
mysql_charset=CHARSET,
)
ptp_parameter_ownerships.create()
tables.update({'ptp_parameter_ownerships': ptp_parameter_ownerships})
_populate_ptp_tables(meta, ptp_instances, ptp_interfaces, ptp_parameters,
ptp_parameter_ownerships)
i_host = Table('i_host', meta, autoload=True)
tables.update({'i_host': i_host})
ptp_instance_maps = Table(
'ptp_instance_maps',
meta,
Column('created_at', DateTime),
Column('updated_at', DateTime),
Column('deleted_at', DateTime),
Column('id', Integer, primary_key=True, nullable=False),
Column('uuid', String(UUID_LENGTH), unique=True),
Column('host_id', Integer,
ForeignKey('i_host.id', ondelete='CASCADE'),
nullable=False),
Column('ptp_instance_id', Integer,
ForeignKey('ptp_instances.id', ondelete='CASCADE'),
nullable=False),
UniqueConstraint('host_id', 'ptp_instance_id', name='u_hostinstance'),
mysql_engine=ENGINE,
mysql_charset=CHARSET,
)
ptp_instance_maps.create()
tables.update({'ptp_instance_maps': ptp_instance_maps})
interfaces = Table('interfaces', meta, autoload=True)
tables.update({'interfaces': interfaces})
ptp_interface_maps = Table(
'ptp_interface_maps',
meta,
Column('created_at', DateTime),
Column('updated_at', DateTime),
Column('deleted_at', DateTime),
Column('id', Integer, primary_key=True, nullable=False),
Column('uuid', String(UUID_LENGTH), unique=True),
Column('interface_id', Integer,
ForeignKey('interfaces.id', ondelete='CASCADE'),
nullable=False),
Column('ptp_interface_id', Integer,
ForeignKey('ptp_interfaces.id', ondelete='CASCADE'),
nullable=False),
UniqueConstraint('interface_id', 'ptp_interface_id',
name='u_ifaceptpiface'),
mysql_engine=ENGINE,
mysql_charset=CHARSET,
)
ptp_interface_maps.create()
tables.update({'ptp_interface_maps': ptp_interface_maps})
_populate_ptp_tables(meta, tables)
def downgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
ptp_interface_maps = Table('ptp_interface_maps', meta, autoload=True)
ptp_interface_maps.drop()
ptp_instance_maps = Table('ptp_instance_maps', meta, autoload=True)
ptp_instance_maps.drop()
ptp_parameter_ownerships = Table('ptp_parameter_ownerships',
meta,
autoload=True)

View File

@ -245,14 +245,19 @@ class ihost(Base):
peer_id = Column(Integer,
ForeignKey('peers.id'))
ptp_instance_id = Column(Integer, ForeignKey('ptp_instances.id'))
ptp = relationship("PtpInstances", lazy="joined", join_depth=1)
system = relationship("isystem")
host_upgrade = relationship("HostUpgrade", uselist=False)
kube_host_upgrade = relationship("KubeHostUpgrade", uselist=False)
ptp_instances = relationship(
"PtpInstances",
secondary="ptp_instance_maps",
primaryjoin="ihost.id == foreign(PtpInstanceMaps.host_id)",
secondaryjoin="PtpInstances.id == "
"foreign(PtpInstanceMaps.ptp_instance_id)",
back_populates="hosts", lazy="joined", join_depth=1)
class inode(Base):
__tablename__ = 'i_node'
@ -361,9 +366,6 @@ class Interfaces(Base):
sriov_vf_driver = Column(String(255))
ptp_role = Column(String(255), default='none') # TODO: deprecate it
ptp_interface_id = Column(Integer, ForeignKey('ptp_interfaces.id'))
ptp = relationship("PtpInterfaces", lazy="joined", join_depth=1)
used_by = relationship(
"Interfaces",
secondary=interfaces_to_interfaces,
@ -389,6 +391,14 @@ class Interfaces(Base):
backref=backref("interface", lazy="joined"),
cascade="all")
ptp_interfaces = relationship(
"PtpInterfaces",
secondary="ptp_interface_maps",
primaryjoin="Interfaces.id == foreign(PtpInterfaceMaps.interface_id)",
secondaryjoin="PtpInterfaces.id == "
"foreign(PtpInterfaceMaps.ptp_interface_id)",
back_populates="interfaces", lazy="joined", join_depth=1)
UniqueConstraint('ifname', 'forihostid', name='u_interfacenameihost')
__mapper_args__ = {
@ -846,6 +856,14 @@ class PtpInstances(PtpParameterOwners):
name = Column(String(255), unique=True, nullable=False)
service = Column(String(255))
hosts = relationship(
"ihost",
secondary="ptp_instance_maps",
primaryjoin="PtpInstances.id == "
"foreign(PtpInstanceMaps.ptp_instance_id)",
secondaryjoin="ihost.id == foreign(PtpInstanceMaps.host_id)",
back_populates="ptp_instances", lazy="joined", join_depth=1)
__mapper_args__ = {
'polymorphic_identity': constants.PTP_PARAMETER_OWNER_INSTANCE
}
@ -868,6 +886,15 @@ class PtpInterfaces(PtpParameterOwners):
PtpInstances.name,
PtpInstances.uuid])
interfaces = relationship(
"Interfaces",
secondary="ptp_interface_maps",
primaryjoin="PtpInterfaces.id == "
"foreign(PtpInterfaceMaps.ptp_interface_id)",
secondaryjoin="Interfaces.id == "
"foreign(PtpInterfaceMaps.interface_id)",
back_populates="ptp_interfaces", lazy="joined", join_depth=1)
__mapper_args__ = {
'polymorphic_identity': constants.PTP_PARAMETER_OWNER_INTERFACE
}
@ -887,20 +914,64 @@ class PtpParameterOwnerships(Base):
ForeignKey('ptp_parameters.uuid',
ondelete='CASCADE'),
nullable=False)
owner_uuid = Column(String(UUID_LENGTH), nullable=False)
owner_uuid = Column(String(UUID_LENGTH),
ForeignKey('ptp_parameter_owners.uuid',
ondelete='CASCADE'),
nullable=False)
parameter = relationship("PtpParameters", lazy="joined", join_depth=1)
owner = relationship(
"PtpParameterOwners",
primaryjoin="PtpParameterOwnerships.owner_uuid == "
"foreign(PtpParameterOwners.uuid)",
lazy="joined",
join_depth=1)
owner = relationship("PtpParameterOwners", lazy="joined", join_depth=1)
UniqueConstraint('parameter_uuid', 'owner_uuid', name='u_paramowner')
class PtpInstanceMaps(Base):
"""
This is a bridge table used to model the many-to-many relationship between
PTP instances (the services) and the hosts they run.
"""
__tablename__ = "ptp_instance_maps"
id = Column(Integer, primary_key=True, nullable=False)
uuid = Column(String(UUID_LENGTH), unique=True)
host_id = Column(Integer,
ForeignKey('i_host.id', ondelete='CASCADE'),
nullable=False)
ptp_instance_id = Column(
Integer, ForeignKey('ptp_instances.id', ondelete='CASCADE'),
nullable=False)
host = relationship("ihost", lazy="joined", join_depth=1)
instance = relationship("PtpInstances", lazy="joined", join_depth=1)
UniqueConstraint('host_id', 'ptp_instance_id', name='u_hostinstance')
class PtpInterfaceMaps(Base):
"""
This is a bridge table used to model the many-to-many relationship between
PTP interfaces (PTP services and parameters) and the interfaces they run.
"""
__tablename__ = "ptp_interface_maps"
id = Column(Integer, primary_key=True, nullable=False)
uuid = Column(String(UUID_LENGTH), unique=True)
interface_id = Column(Integer,
ForeignKey('interfaces.id', ondelete='CASCADE'),
nullable=False)
ptp_interface_id = Column(
Integer, ForeignKey('ptp_interfaces.id', ondelete='CASCADE'),
nullable=False)
interface = relationship("Interfaces", lazy="joined", join_depth=1)
ptp_interface = relationship("PtpInterfaces", lazy="joined", join_depth=1)
UniqueConstraint('interface_id', 'ptp_interface_id',
name='u_ifaceptpiface')
class StorageTier(Base):
__tablename__ = 'storage_tiers'

View File

@ -71,7 +71,9 @@ from sysinv.objects import peer
from sysinv.objects import port
from sysinv.objects import ptp
from sysinv.objects import ptp_instance
from sysinv.objects import ptp_instance_map
from sysinv.objects import ptp_interface
from sysinv.objects import ptp_interface_map
from sysinv.objects import ptp_parameter
from sysinv.objects import ptp_paramowner
from sysinv.objects import ptp_paramownership
@ -160,7 +162,9 @@ dns = dns.DNS
ntp = ntp.NTP
ptp = ptp.PTP
ptp_instance = ptp_instance.PtpInstance
ptp_instance_map = ptp_instance_map.PtpInstanceMap
ptp_interface = ptp_interface.PtpInterface
ptp_interface_map = ptp_interface_map.PtpInterfaceMap
ptp_parameter = ptp_parameter.PtpParameter
ptp_paramowner = ptp_paramowner.PtpParameterOwner
ptp_paramownership = ptp_paramownership.PtpParameterOwnership
@ -244,7 +248,9 @@ __all__ = ("system",
"ntp",
"ptp",
"ptp_instance",
"ptp_instance_map",
"ptp_interface",
"ptp_interface_map",
"ptp_parameter",
"ptp_paramowner",
"ptp_paramownership",

View File

@ -23,11 +23,6 @@ def _get_target_load(field, db_object):
return db_object.host_upgrade.load_target.software_version
def _get_ptp_configuration(field, db_object):
# TODO
return {}
class Host(base.SysinvObject):
dbapi = db_api.get_instance()
@ -37,7 +32,6 @@ class Host(base.SysinvObject):
'forisystemid': utils.int_or_none,
'isystem_uuid': utils.str_or_none,
'peer_id': utils.int_or_none,
'ptp_instance_id': utils.int_or_none,
'recordtype': utils.str_or_none,
# 'created_at': utils.datetime_str_or_none,
@ -82,7 +76,6 @@ class Host(base.SysinvObject):
'config_target': utils.str_or_none,
'capabilities': utils.dict_or_none,
'clock_synchronization': utils.str_or_none,
'ptp_config': utils.dict_or_none,
'boot_device': utils.str_or_none,
'rootfs_device': utils.str_or_none,
@ -103,8 +96,7 @@ class Host(base.SysinvObject):
_foreign_fields = {
'isystem_uuid': 'system:uuid',
'software_load': _get_software_load,
'target_load': _get_target_load,
'ptp_config': _get_ptp_configuration
'target_load': _get_target_load
}
@base.remotable_classmethod

View File

@ -108,11 +108,6 @@ def get_datanetworks(field, db_object):
return result
def _get_ptp_configuration(field, db_object):
# TODO
return {}
class Interface(base.SysinvObject):
# VERSION 1.0: Initial version
# VERSION 1.1: Added VLAN and uses/used_by interface support
@ -125,7 +120,6 @@ class Interface(base.SysinvObject):
'uuid': utils.str_or_none,
'forihostid': utils.int_or_none,
'ihost_uuid': utils.str_or_none,
'ptp_interface_id': utils.int_or_none,
'ifname': utils.str_or_none,
'iftype': utils.str_or_none,
@ -154,7 +148,6 @@ class Interface(base.SysinvObject):
'sriov_numvfs': utils.int_or_none,
'sriov_vf_driver': utils.str_or_none,
'ptp_role': utils.str_or_none,
'ptp_config': utils.dict_or_none,
'max_tx_rate': utils.int_or_none,
}
@ -166,8 +159,7 @@ class Interface(base.SysinvObject):
'ipv6_pool': get_ipv6_address_pool,
'ihost_uuid': get_host_uuid,
'networktypelist': get_networktypes,
'datanetworks': get_datanetworks,
'ptp_config': _get_ptp_configuration}
'datanetworks': get_datanetworks}
_optional_fields = ['aemode', 'txhashpolicy', 'schedpolicy',
'vlan_id', 'vlan_type', 'primary_reselect']

View File

@ -12,16 +12,30 @@ from sysinv.objects import utils
from sysinv.objects import ptp_paramowner
def get_hosts(field, db_object):
hosts = db_object['hosts']
if not hosts:
return []
hostnames = []
for h in hosts:
hostnames.append(h.hostname)
return hostnames
class PtpInstance(ptp_paramowner.PtpParameterOwner):
dbapi = db_api.get_instance()
fields = dict({
'name': utils.str_or_none,
'service': utils.str_or_none
'service': utils.str_or_none,
'hosts': utils.list_of_strings_or_none
}, **ptp_paramowner.PtpParameterOwner.fields)
_foreign_fields = {}
_foreign_fields = {
'hosts': get_hosts
}
@base.remotable_classmethod
def get_by_uuid(cls, context, uuid):

View File

@ -0,0 +1,40 @@
########################################################################
#
# Copyright (c) 2021 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
########################################################################
from sysinv.db import api as db_api
from sysinv.objects import base
from sysinv.objects import utils
class PtpInstanceMap(base.SysinvObject):
dbapi = db_api.get_instance()
fields = {
'id': int,
'uuid': utils.str_or_none,
'host_id': int,
'hostname': utils.str_or_none,
'ptp_instance_id': int,
'name': utils.str_or_none,
'service': utils.str_or_none
}
_foreign_fields = {
'host_id': 'host:id',
'hostname': 'host:hostname',
'ptp_instance_id': 'ptp_instance:id',
'name': 'ptp_instance:name',
'service': 'ptp_instance:service'
}
@base.remotable_classmethod
def get_by_uuid(cls, context, uuid):
return cls.dbapi.ptp_instance_map_get(uuid)

View File

@ -12,6 +12,24 @@ from sysinv.objects import utils
from sysinv.objects import ptp_paramowner
def get_interfaces(field, db_object):
interfaces = db_object['interfaces']
if not interfaces:
return []
interfaces = []
for i in interfaces:
details = {}
details['name'] = i.ifname
details['type'] = i.iftype
host = getattr(i, 'host')
if host:
details['host'] = host.hostname
interfaces.append(details)
return interfaces
class PtpInterface(ptp_paramowner.PtpParameterOwner):
dbapi = db_api.get_instance()
@ -19,12 +37,14 @@ class PtpInterface(ptp_paramowner.PtpParameterOwner):
fields = dict({
'ptp_instance_id': utils.int_or_none,
'ptp_instance_uuid': utils.str_or_none,
'ptp_instance_name': utils.str_or_none
'ptp_instance_name': utils.str_or_none,
'interfaces': list
}, **ptp_paramowner.PtpParameterOwner.fields)
_foreign_fields = {
'ptp_instance_uuid': 'ptp_instance:uuid',
'ptp_instance_name': 'ptp_instance:name'
'ptp_instance_name': 'ptp_instance:name',
'interfaces': get_interfaces
}
@base.remotable_classmethod

View File

@ -0,0 +1,68 @@
########################################################################
#
# Copyright (c) 2021 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
########################################################################
from sysinv.db import api as db_api
from sysinv.objects import base
from sysinv.objects import utils
def get_hostname(field, db_object):
host = getattr(db_object['interface'], 'host')
if not host:
return None
return host.hostname
def get_instance_name(field, db_object):
instance = getattr(db_object['ptp_interface'], 'ptp_instance')
if not instance:
return None
return instance.name
def get_instance_service(field, db_object):
instance = getattr(db_object['ptp_interface'], 'ptp_instance')
if not instance:
return None
return instance.service
class PtpInterfaceMap(base.SysinvObject):
dbapi = db_api.get_instance()
fields = {
'id': int,
'uuid': utils.str_or_none,
'interface_id': int,
'ifname': utils.str_or_none,
'iftype': utils.str_or_none,
'hostname': utils.str_or_none,
'ptp_interface_id': int,
'name': utils.str_or_none,
'service': utils.str_or_none
}
_foreign_fields = {
'interface_id': 'interface:id',
'ifname': 'interface:ifname',
'iftype': 'interface:iftype',
'hostname': get_hostname,
'ptp_interface_id': 'ptp_interface:id',
'name': get_instance_name,
'service': get_instance_service
}
@base.remotable_classmethod
def get_by_uuid(cls, context, uuid):
return cls.dbapi.ptp_interface_map_get(uuid)

View File

@ -20,10 +20,18 @@ class PtpParameterOwnership(base.SysinvObject):
'uuid': utils.str_or_none,
'parameter_uuid': utils.str_or_none,
'parameter_name': utils.str_or_none,
'parameter_value': utils.str_or_none,
'owner_uuid': utils.str_or_none,
}
_foreign_fields = {}
_foreign_fields = {
'parameter_uuid': 'parameter:uuid',
'parameter_name': 'parameter:name',
'parameter_value': 'parameter:value',
'owner_uuid': 'owner:uuid'
}
@base.remotable_classmethod
def get_by_uuid(cls, context, uuid):

View File

@ -2061,3 +2061,33 @@ class TestMigrations(BaseMigrationTestCase, WalkVersionsMixin):
self.assertTrue(
isinstance(ptp_parameter_ownerships.c[column].type,
getattr(sqlalchemy.types, column_type)))
ptp_instance_maps = db_utils.get_table(engine, 'ptp_instance_maps')
ptp_instance_map_columns = {
'created_at': 'DateTime',
'updated_at': 'DateTime',
'deleted_at': 'DateTime',
'id': 'Integer',
'uuid': 'String',
'host_id': 'Integer',
'ptp_instance_id': 'Integer'
}
for column, column_type in ptp_instance_map_columns.items():
self.assertTrue(
isinstance(ptp_instance_maps.c[column].type,
getattr(sqlalchemy.types, column_type)))
ptp_interface_maps = db_utils.get_table(engine, 'ptp_interface_maps')
ptp_interface_map_columns = {
'created_at': 'DateTime',
'updated_at': 'DateTime',
'deleted_at': 'DateTime',
'id': 'Integer',
'uuid': 'String',
'interface_id': 'Integer',
'ptp_interface_id': 'Integer'
}
for column, column_type in ptp_interface_map_columns.items():
self.assertTrue(
isinstance(ptp_interface_maps.c[column].type,
getattr(sqlalchemy.types, column_type)))

View File

@ -597,6 +597,34 @@ def create_test_ptp_ownership(**kw):
return dbapi.ptp_parameter_set_owner(ownership)
def get_test_ptp_instance_map(**kw):
map = {
'host_id': kw.get('host_id', None),
'ptp_instance_id': kw.get('ptp_instance_id', None)
}
return map
def create_test_ptp_instance_map(**kw):
map = get_test_ptp_instance_map(**kw)
dbapi = db_api.get_instance()
return dbapi.ptp_instance_set_host(map)
def get_test_ptp_interface_map(**kw):
map = {
'interface_id': kw.get('interface_id', None),
'ptp_interface_id': kw.get('ptp_interface_id', None)
}
return map
def create_test_ptp_interface_map(**kw):
map = get_test_ptp_interface_map(**kw)
dbapi = db_api.get_instance()
return dbapi.ptp_interface_set_interface(map)
# Create test dns object
def get_test_dns(**kw):
dns = {