Merge "[PTP dual NIC config] Review of PTP data model"

This commit is contained in:
Zuul 2021-12-05 13:35:03 +00:00 committed by Gerrit Code Review
commit 1bfd8f4ed3
33 changed files with 1537 additions and 1092 deletions

View File

@ -72,6 +72,7 @@ from cgtsclient.v1 import ptp
from cgtsclient.v1 import ptp_instance
from cgtsclient.v1 import ptp_interface
from cgtsclient.v1 import ptp_parameter
from cgtsclient.v1 import ptp_paramownership
from cgtsclient.v1 import registry_image
from cgtsclient.v1 import remotelogging
from cgtsclient.v1 import restore
@ -124,6 +125,8 @@ class Client(http.HTTPClient):
self.ptp_instance = ptp_instance.PtpInstanceManager(self)
self.ptp_interface = ptp_interface.PtpInterfaceManager(self)
self.ptp_parameter = ptp_parameter.PtpParameterManager(self)
self.ptp_paramownership = \
ptp_paramownership.PtpParameterOwnershipManager(self)
self.iextoam = iextoam.iextoamManager(self)
self.controller_fs = controller_fs.ControllerFsManager(self)
self.storage_backend = storage_backend.StorageBackendManager(self)

View File

@ -12,7 +12,7 @@ from cgtsclient import exc
from cgtsclient.v1 import options
CREATION_ATTRIBUTES = ['name', 'service', 'host_uuid']
CREATION_ATTRIBUTES = ['name', 'service']
class PtpInstance(base.Resource):
@ -50,6 +50,14 @@ class PtpInstanceManager(base.Manager):
raise exc.InvalidAttribute('%s' % key)
return self._create(self._path(), data)
def apply(self, ihost_uuid, ptp_instance_id):
return self._update('/v1/ihosts/%s?action=apply' % ihost_uuid,
ptp_instance_id)
def remove(self, ihost_uuid, ptp_instance_id):
return self._update('/v1/ihosts/%s?action=remove' % ihost_uuid,
ptp_instance_id)
def delete(self, ptp_instance_id):
return self._delete(self._path(ptp_instance_id))

View File

@ -16,18 +16,21 @@ def _print_ptp_instance_show(ptp_instance_obj):
fields = ['uuid',
'name',
'service',
'hostname',
'created_at']
data = [(f, getattr(ptp_instance_obj, f, '')) for f in fields]
utils.print_tuple_list(data)
def _print_ptp_instance_list(ptp_instance_list):
field_labels = ['uuid', 'name', 'service']
fields = ['uuid', 'name', 'service']
utils.print_list(ptp_instance_list, fields, field_labels)
def do_ptp_instance_list(cc, args):
"""List all PTP instances, in any host."""
"""List all PTP instances."""
ptp_instances = cc.ptp_instance.list()
field_labels = ['uuid', 'name', 'service', 'hostname']
fields = ['uuid', 'name', 'service', 'hostname']
utils.print_list(ptp_instances, fields, field_labels)
_print_ptp_instance_list(ptp_instances)
@utils.arg('hostnameorid',
@ -37,10 +40,7 @@ def do_host_ptp_instance_list(cc, args):
"""List PTP instances on host."""
ihost = ihost_utils._find_ihost(cc, args.hostnameorid)
ptp_instances = cc.ptp_instance.list_by_host(ihost.uuid)
field_labels = ['name', 'service', 'uuid']
fields = ['name', 'service', 'uuid']
utils.print_list(ptp_instances, fields, field_labels)
_print_ptp_instance_list(ptp_instances)
@utils.arg('nameoruuid',
@ -59,9 +59,6 @@ def do_ptp_instance_show(cc, args):
metavar='<service type>',
choices=['ptp4l', 'phc2sys', 'ts2phc'],
help="Service type [REQUIRED]")
@utils.arg('hostnameorid',
metavar='<hostname or id>',
help="Name or ID of host [REQUIRED]")
def do_ptp_instance_add(cc, args):
"""Add a PTP instance."""
@ -71,9 +68,6 @@ def do_ptp_instance_add(cc, args):
data = dict((k, v) for (k, v) in vars(args).items()
if k in field_list and not (v is None))
ihost = ihost_utils._find_ihost(cc, args.hostnameorid)
data.update({'host_uuid': ihost.uuid})
ptp_instance = cc.ptp_instance.create(**data)
uuid = getattr(ptp_instance, 'uuid', '')
try:
@ -93,3 +87,43 @@ def do_ptp_instance_delete(cc, args):
uuid = ptp_instance.uuid
cc.ptp_instance.delete(uuid)
print('Deleted PTP instance: %s' % uuid)
@utils.arg('hostnameorid',
metavar='<hostname or id>',
help="Name or ID of host [REQUIRED]")
@utils.arg('nameoruuid',
metavar='<name or UUID>',
help="Name or UUID of PTP instance [REQUIRED]")
def do_host_ptp_instance_add(cc, args):
"""Associate PTP instance to host."""
ihost = ihost_utils._find_ihost(cc, args.hostnameorid)
ptp_instance = ptp_instance_utils._find_ptp_instance(cc, args.nameoruuid)
try:
cc.ptp_instance.apply(ihost.uuid, ptp_instance.id)
except exc.HTTPNotFound:
raise exc.CommandError(
"Failed to apply PTP instance '%s' to host '%s'"
% (ihost.hostname, ptp_instance.name))
print("Applying PTP instance '%s' to host '%s'"
% (ihost.hostname, ptp_instance.name))
@utils.arg('hostnameorid',
metavar='<hostname or id>',
help="Name or ID of host")
@utils.arg('nameoruuid',
metavar='<name or UUID>',
help="Name or UUID of PTP instance")
def do_host_ptp_instance_delete(cc, args):
"""Disassociate PTP instance on host."""
ihost = ihost_utils._find_ihost(cc, args.hostnameorid)
ptp_instance = ptp_instance_utils._find_ptp_instance(cc, args.nameoruuid)
try:
cc.ptp_instance.remove(ihost.uuid, ptp_instance.id)
except exc.HTTPNotFound:
raise exc.CommandError(
"Failed to remove PTP instance '%s' from host '%s'"
% (ihost.hostname, ptp_instance.name))
print("Removing PTP instance '%s' from host '%s'"
% (ihost.hostname, ptp_instance.name))

View File

@ -11,7 +11,7 @@ from cgtsclient import exc
from cgtsclient.v1 import options
CREATION_ATTRIBUTES = ['name', 'value', 'type', 'foreign_uuid']
CREATION_ATTRIBUTES = ['name', 'value']
class PtpParameter(base.Resource):

View File

@ -11,71 +11,44 @@ from cgtsclient import exc
from cgtsclient.v1 import ptp_parameter as ptp_parameter_utils
def _owner_formatter(values):
result = []
result.append(str(values['name'] +
" of type " + values['type'] +
" at " + values['hostname']))
return result
def _print_ptp_parameter_show(ptp_parameter_obj):
fields = ['uuid', 'name', 'value', 'type',
'owner', 'foreign_uuid', 'created_at', 'updated_at']
labels = ['uuid', 'name', 'value', 'type',
'owned_by', 'owner_id', 'created_at', 'updated_at']
fields = ['uuid', 'name', 'value', 'created_at', 'updated_at']
data = [(f, getattr(ptp_parameter_obj, f, '')) for f in fields]
utils.print_tuple_list(data, labels,
formatters={'owner': _owner_formatter})
utils.print_tuple_list(data)
def _print_ptp_parameter_list(ptp_parameter_list):
fields = ['uuid', 'name', 'value']
labels = ['uuid', 'name', 'value']
utils.print_list(ptp_parameter_list, fields, labels)
@utils.arg('-t', '--type',
metavar='<owner type>',
choices=['ptp-instance', 'ptp-interface'],
help='List PTP parameters for a specific owner type')
@utils.arg('-u', '--foreign_uuid',
metavar='<owner uuid>',
help='List PTP parameters associated to specified owner')
def do_ptp_parameter_list(cc, args):
"""List all PTP parameters, in any host."""
missing = ((args.type is None) and (args.foreign_uuid is not None)) or \
((args.type is not None) and (args.foreign_uuid is None))
if missing:
raise exc.CommandError("Both 'type' and 'foreign_uuid' "
"must be provided")
ptp_parameters = None
if args.type == 'ptp-instance':
ptp_parameters = cc.ptp_parameter.list_by_ptp_instance(
args.foreign_uuid)
elif args.type == 'ptp-interface':
ptp_parameters = cc.ptp_parameter.list_by_interface(
args.foreign_uuid)
if ptp_parameters:
fields = ['uuid', 'name', 'value']
labels = ['uuid', 'name', 'value']
else:
ptp_parameters = cc.ptp_parameter.list()
for ptp_parameter in ptp_parameters:
owner_dict = getattr(ptp_parameter, 'owner', '')
setattr(ptp_parameter, 'owner_name', owner_dict['name'])
setattr(ptp_parameter, 'owner_host', owner_dict['hostname'])
"""List all PTP parameters."""
ptp_parameters = cc.ptp_parameter.list()
_print_ptp_parameter_list(ptp_parameters)
fields = ['uuid',
'name',
'value',
'type',
'owner_name',
'owner_host',
'foreign_uuid']
labels = ['uuid',
'name',
'value',
'owner_type',
'owner_name',
'owner_host',
'owner_uuid']
utils.print_list(ptp_parameters, fields, labels)
@utils.arg('ptp_instance_uuid',
metavar='<PTP instance uuid>',
help="UUID of PTP instance")
def do_ptp_parameter_list_instances(cc, args):
"""List all PTP parameters that are associated to a specific PTP instance.
"""
ptp_parameters = cc.ptp_parameter.list_by_ptp_instance(
args.ptp_instance_uuid)
_print_ptp_parameter_list(ptp_parameters)
@utils.arg('ptp_interface_uuid',
metavar='<PTP interface uuid>',
help="UUID of PTP interface")
def do_ptp_parameter_list_interfaces(cc, args):
"""List all PTP parameters that are associated to a specific PTP interface.
"""
ptp_parameters = cc.ptp_parameter.list_by_interface(
args.ptp_interface_uuid)
_print_ptp_parameter_list(ptp_parameters)
@utils.arg('uuid',
@ -93,18 +66,10 @@ def do_ptp_parameter_show(cc, args):
@utils.arg('value',
metavar='<value>',
help="Value of PTP parameter [REQUIRED]")
@utils.arg('type',
metavar='<owner type>',
choices=['ptp-instance', 'ptp-interface'],
help="Type of parameter owner ('ptp-instance' or 'ptp-interface') "
"[REQUIRED]")
@utils.arg('foreign_uuid',
metavar='<owner uuid>',
help="UUID of parameter owner [REQUIRED]")
def do_ptp_parameter_add(cc, args):
"""Add a PTP parameter."""
field_list = ['name', 'value', 'type', 'foreign_uuid']
field_list = ['name', 'value']
# Prune input fields down to required/expected values
data = dict((k, v) for (k, v) in vars(args).items()

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 = ['parameter_uuid', 'owner_uuid']
class PtpParameterOwnership(base.Resource):
def __repr__(self):
return "<PtpParameterOwnership %s>" % self._info
class PtpParameterOwnershipManager(base.Manager):
resource_class = PtpParameterOwnership
def _path(self, ptp_paramownership_id=None):
return '/v1/ptp_parameter_ownerships/%s' % ptp_paramownership_id \
if ptp_paramownership_id else '/v1/ptp_parameter_ownerships'
def get(self, ptp_paramownership_id):
try:
return self._list(self._path(ptp_paramownership_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_paramownership_id):
return self._delete(self._path(ptp_paramownership_id))

View File

@ -0,0 +1,49 @@
########################################################################
#
# Copyright (c) 2021 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
########################################################################
from cgtsclient.common import utils
from cgtsclient import exc
@utils.arg('parameter_uuid',
metavar='<parameter uuid>',
help="UUID of PTP parameter [REQUIRED]")
@utils.arg('owner_uuid',
metavar='<owner uuid>',
help="UUID of PTP instance or PTP interface [REQUIRED]")
def do_ptp_parameter_set_owner(cc, args):
"""Set ownership of a PTP parameter."""
field_list = ['parameter_uuid', 'owner_uuid']
# Prune input fields down to required/expected values
data = dict((k, v) for (k, v) in vars(args).items()
if k in field_list and not (v is None))
ptp_paramownership = cc.ptp_paramownership.create(**data)
uuid = getattr(ptp_paramownership, 'uuid', '')
try:
ptp_paramownership = cc.ptp_paramownership.get(uuid)
except exc.HTTPNotFound:
raise exc.CommandError('PTP ownership just set not found: %s' % uuid)
fields = ['uuid', 'parameter_uuid', 'owner_uuid', 'created_at']
labels = ('uuid', 'parameter', 'owner', 'created_at')
data = [(f, getattr(ptp_paramownership, f, '')) for f in fields]
utils.print_tuple_list(data, labels)
@utils.arg('parameter_uuid',
metavar='<parameter uuid>',
help="UUID of PTP parameter")
@utils.arg('owner_uuid',
metavar='<owner uuid>',
help="UUID of PTP instance or PTP interface")
def do_ptp_parameter_unset_owner(cc, args):
"""Remove ownership of a PTP parameter."""
cc.ptp_paramownership.delete(args.parameter_uuid, args.owner_uuid)
print('Removed association to PTP parameter %s', args.parameter_uuid)

View File

@ -57,6 +57,7 @@ from cgtsclient.v1 import port_shell
from cgtsclient.v1 import ptp_instance_shell
from cgtsclient.v1 import ptp_interface_shell
from cgtsclient.v1 import ptp_parameter_shell
from cgtsclient.v1 import ptp_paramownership_shell
from cgtsclient.v1 import ptp_shell
from cgtsclient.v1 import registry_image_shell
from cgtsclient.v1 import remotelogging_shell
@ -81,6 +82,7 @@ COMMAND_MODULES = [
ptp_instance_shell,
ptp_interface_shell,
ptp_parameter_shell,
ptp_paramownership_shell,
iextoam_shell,
controller_fs_shell,
storage_backend_shell,

View File

@ -68,6 +68,7 @@ from sysinv.api.controllers.v1 import ptp
from sysinv.api.controllers.v1 import ptp_instance
from sysinv.api.controllers.v1 import ptp_interface
from sysinv.api.controllers.v1 import ptp_parameter
from sysinv.api.controllers.v1 import ptp_paramownership
from sysinv.api.controllers.v1 import pv
from sysinv.api.controllers.v1 import registry_image
from sysinv.api.controllers.v1 import remotelogging
@ -158,6 +159,9 @@ class V1(base.APIBase):
ptp_parameters = [link.Link]
"Links to the ptp_parameters resource"
ptp_parameter_ownerships = [link.Link]
"Links to the ptp_parameter_ownerships resource"
iextoam = [link.Link]
"Links to the iextoam resource"
@ -480,6 +484,14 @@ class V1(base.APIBase):
'ptp_parameters', '',
bookmark=True)]
v1.ptp_parameter_ownerships = \
[link.Link.make_link('self', pecan.request.host_url,
'ptp_parameter_ownerships', ''),
link.Link.make_link('bookmark',
pecan.request.host_url,
'ptp_parameter_ownerships', '',
bookmark=True)]
v1.iextoam = [link.Link.make_link('self', pecan.request.host_url,
'iextoam', ''),
link.Link.make_link('bookmark',
@ -925,6 +937,8 @@ class Controller(rest.RestController):
ptp_instances = ptp_instance.PtpInstanceController()
ptp_interfaces = ptp_interface.PtpInterfaceController()
ptp_parameters = ptp_parameter.PtpParameterController()
ptp_parameter_ownerships = \
ptp_paramownership.PtpParameterOwnershipController()
iextoam = network_oam.OAMNetworkController()
controller_fs = controller_fs.ControllerFsController()
storage_backend = storage_backend.StorageBackendController()

View File

@ -43,20 +43,21 @@ class PtpInstance(base.APIBase):
created_at = wtypes.datetime.datetime
"Timestamp of creation of this PTP instance"
id = int
"Unique ID for this PTP instance"
# Inherited from PtpParameterOwner
uuid = types.uuid
"Unique UUID for this PTP instance"
host_id = int
"ID of host the PTP instance is associated to"
type = wtypes.Enum(str,
constants.PTP_PARAMETER_OWNER_INSTANCE,
constants.PTP_PARAMETER_OWNER_INTERFACE)
"Type of parameter owner (PTP_PARAMETER_OWNER_INSTANCE)"
host_uuid = types.uuid
"UUID of the host the PTP instance is associated to"
capabilities = {wtypes.text: utils.ValidTypes(wtypes.text,
six.integer_types)}
"Capabilities (metadata) of this PTP instance"
hostname = wtypes.text
"Name of the host the PTP instance is associated to"
# Fields of PtpInstance
name = wtypes.text
"Name given to the PTP instance"
@ -67,10 +68,6 @@ class PtpInstance(base.APIBase):
constants.PTP_INSTANCE_TYPE_TS2PHC)
"Type of service of the PTP instance"
capabilities = {wtypes.text: utils.ValidTypes(wtypes.text,
six.integer_types)}
"Capabilities (metadata) of this PTP instance"
def __init__(self, **kwargs):
self.fields = list(objects.ptp_instance.fields.keys())
for k in self.fields:
@ -83,16 +80,12 @@ class PtpInstance(base.APIBase):
ptp_instance = PtpInstance(**rpc_ptp_instance.as_dict())
if not expand:
ptp_instance.unset_fields_except(['uuid',
'host_uuid',
'hostname',
'type',
'capabilities',
'name',
'service',
'capabilities',
'created_at'])
# do not expose the id attribute
ptp_instance.host_id = wtypes.Unset
LOG.debug("PtpInstance.convert_with_links: converted %s" %
ptp_instance.as_dict())
return ptp_instance
@ -130,12 +123,13 @@ class PtpInstanceController(rest.RestController):
def __init__(self, from_ihosts=False):
self._from_ihosts = from_ihosts
def _get_ptp_instance_collection(
self, host_uuid=None, marker=None, limit=None, sort_key=None,
sort_dir=None, expand=False, resource_url=None):
LOG.debug("PtpInstanceController._get_ptp_instance_collection: "
"from_ihosts %s host_uuid %s" % (self._from_ihosts,
host_uuid))
@wsme_pecan.wsexpose(PtpInstanceCollection, types.uuid, types.uuid,
int, wtypes.text, wtypes.text)
def get_all(self, host_uuid=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'):
"""Retrieve a list of PTP instances."""
LOG.debug("PtpInstanceController.get_all: from_ihosts %s host_uuid %s"
% (self._from_ihosts, host_uuid))
if self._from_ihosts and not host_uuid:
raise exception.InvalidParameterValue(_(
"Host id not specified."))
@ -143,52 +137,39 @@ class PtpInstanceController(rest.RestController):
limit = utils.validate_limit(limit)
sort_dir = utils.validate_sort_dir(sort_dir)
LOG.debug("PtpInstanceController._get_ptp_instance_collection: "
"marker %s, limit %s, sort_dir %s" % (marker, limit,
sort_dir))
marker_obj = None
if marker:
marker_obj = objects.ptp_instance.get_by_uuid(
pecan.request.context, marker)
if self._from_ihosts or host_uuid:
ptp_instances = pecan.request.dbapi.ptp_instances_get_by_ihost(
host_uuid, limit,
marker_obj,
sort_key=sort_key,
sort_dir=sort_dir)
else:
ptp_instances = pecan.request.dbapi.ptp_instances_get_list(
limit, marker_obj,
sort_key=sort_key,
sort_dir=sort_dir)
ptp_instances = \
pecan.request.dbapi.ptp_instances_get_list(
host_uuid, limit, marker_obj, sort_key, sort_dir)
return PtpInstanceCollection.convert_with_links(
ptp_instances, limit, url=resource_url, expand=expand,
sort_key=sort_key, sort_dir=sort_dir)
ptp_instances, limit, sort_key=sort_key, sort_dir=sort_dir)
@wsme_pecan.wsexpose(PtpInstanceCollection, types.uuid, types.uuid,
int, wtypes.text, wtypes.text)
def get_all(self, uuid=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'):
"""Retrieve a list of PTP instances."""
LOG.debug("PtpInstanceController.get_all: uuid=%s" % uuid)
return self._get_ptp_instance_collection(uuid, marker, limit,
sort_key=sort_key,
sort_dir=sort_dir)
@wsme_pecan.wsexpose(PtpInstance, types.uuid)
def get_one(self, ptp_instance_uuid):
@wsme_pecan.wsexpose(PtpInstance, types.uuid, types.uuid)
def get_one(self, ptp_instance_uuid=None, host_uuid=None):
"""Retrieve a single PTP instance."""
LOG.debug("PtpInstanceController.get_one: uuid=%s" % ptp_instance_uuid)
LOG.debug("PtpInstanceController.get_one: uuid=%s, host=%s"
% (ptp_instance_uuid, host_uuid))
if self._from_ihosts and not host_uuid:
raise exception.InvalidParameterValue(_(
"Host id not specified."))
try:
ptp_instance = objects.ptp_instance.get_by_uuid(
pecan.request.context,
ptp_instance_uuid)
if host_uuid:
uuid = host_uuid
ptp_instance = \
pecan.request.dbapi.ptp_instances_get_one(host=host_uuid)
else:
uuid = ptp_instance_uuid
ptp_instance = objects.ptp_instance.get_by_uuid(
pecan.request.context,
ptp_instance_uuid)
except exception.InvalidParameterValue:
raise wsme.exc.ClientSideError(
_("No PTP instance found for %s" % ptp_instance_uuid))
_("No PTP instance found for %s" % uuid))
return PtpInstance.convert_with_links(ptp_instance)
@ -198,23 +179,6 @@ class PtpInstanceController(rest.RestController):
"""Create a new PTP instance."""
ptp_instance_dict = ptp_instance.as_dict()
LOG.debug("PtpInstanceController.post: %s" % ptp_instance_dict)
# Get rid of hostname (if any) to create the PTP instance
try:
ptp_instance_dict.pop('hostname')
except KeyError:
LOG.debug("PtpInstanceController.post: no hostname in %s" %
ptp_instance_dict)
# Replace host UUID by host ID
host_uuid = ptp_instance_dict.pop('host_uuid')
try:
ihost_obj = pecan.request.dbapi.ihost_get(host_uuid)
except exception.HostNotFound:
msg = _("Host with uuid '%s' does not exist. " % host_uuid)
raise wsme.exc.ClientSideError(msg)
ptp_instance_dict['host_id'] = ihost_obj['id']
return PtpInstance.convert_with_links(
pecan.request.dbapi.ptp_instance_create(ptp_instance_dict))
@ -228,23 +192,21 @@ class PtpInstanceController(rest.RestController):
# Only allow delete if there are no associated interfaces and
# parameters
parameters = pecan.request.dbapi.ptp_parameters_get_by_owner(
parameters = pecan.request.dbapi.ptp_parameters_get_by_owner_uuid(
ptp_instance_uuid)
if parameters:
names = [str(p['name']) for p in parameters]
raise wsme.exc.ClientSideError(
"PTP instance %s is still associated with PTP parameter(s): %s"
% (ptp_instance_uuid, names))
"PTP instance %s is still associated with PTP parameter(s)"
% ptp_instance_uuid)
ptp_instance_obj = objects.ptp_instance.get_by_uuid(
pecan.request.context, ptp_instance_uuid)
interfaces = pecan.request.dbapi.ptp_interfaces_get_by_instance(
ptp_instance_obj.id)
if interfaces:
names = [str(i['ifname']) for i in interfaces]
raise wsme.exc.ClientSideError(
"PTP instance %s is still associated with PTP interface(s): %s"
% (ptp_instance_uuid, names))
"PTP instance %s is still associated with PTP interface(s)"
% ptp_instance_uuid)
LOG.debug("PtpInstanceController.delete: all clear for %s" %
ptp_instance_uuid)

View File

@ -19,6 +19,7 @@ from sysinv.api.controllers.v1 import collection
from sysinv.api.controllers.v1 import link
from sysinv.api.controllers.v1 import types
from sysinv.api.controllers.v1 import utils
from sysinv.common import constants
from sysinv.common import exception
from sysinv import objects
@ -40,11 +41,21 @@ class PtpInterface(base.APIBase):
interface.
"""
# Inherited from PtpParameterOwner
uuid = types.uuid
"Unique UUID for this PTP interface"
interface_uuid = types.uuid
"ID for the interface associated with the PTP interface"
type = wtypes.Enum(str,
constants.PTP_PARAMETER_OWNER_INSTANCE,
constants.PTP_PARAMETER_OWNER_INTERFACE)
"Type of parameter owner (PTP_PARAMETER_OWNER_INTERFACE)"
capabilities = {wtypes.text: utils.ValidTypes(wtypes.text,
six.integer_types)}
"Capabilities (metadata) of this PTP interface"
# Fields of PtpInterface
ptp_instance_id = int
"ID for the PTP instance this interface is associated with"
@ -55,19 +66,9 @@ class PtpInterface(base.APIBase):
ptp_instance_uuid = types.uuid
"The UUID of the host this PTP interface belongs to"
ifname = wtypes.text
"The name of the underlying interface"
forihostid = int
"The foreign key host id"
ptp_instance_name = wtypes.text
"The name of the associated PTP instance"
capabilities = {wtypes.text: utils.ValidTypes(wtypes.text,
six.integer_types)}
"Capabilities (metadata) of this PTP interface"
created_at = wtypes.datetime.datetime
def __init__(self, **kwargs):
@ -83,13 +84,12 @@ class PtpInterface(base.APIBase):
ptp_interface = PtpInterface(**rpc_ptp_interface.as_dict())
if not expand:
ptp_interface.unset_fields_except(['uuid',
'ptp_instance_id',
'forihostid',
'ptp_instance_name',
'ifname',
'interface_uuid',
'capabilities',
'created_at'])
'type',
'capabilities',
'ptp_instance_id',
'ptp_instance_uuid',
'ptp_instance_name',
'created_at'])
return ptp_interface
@ -105,10 +105,10 @@ class PtpInterfaceCollection(collection.Collection):
@classmethod
def convert_with_links(cls, rpc_ptp_interfaces, limit, url=None,
expand=False, **kwargs):
expand=False, **kwargs):
collection = PtpInterfaceCollection()
collection.ptp_interfaces = [PtpInterface.convert_with_links(p, expand)
for p in rpc_ptp_interfaces]
for p in rpc_ptp_interfaces]
collection.next = collection.get_next(limit, url=url, **kwargs)
return collection
@ -123,56 +123,42 @@ class PtpInterfaceController(rest.RestController):
def __init__(self, from_ihosts=False):
self._from_ihosts = from_ihosts
def _get_ptp_interfaces_collection(self, host_uuid=None, marker=None,
limit=None, sort_key=None,
sort_dir=None, expand=False,
resource_url=None, interface_uuid=None):
@wsme_pecan.wsexpose(PtpInterfaceCollection, types.uuid, int, wtypes.text,
wtypes.text)
def get_all(self, marker=None, limit=None, sort_key='id', sort_dir='asc'):
"""Retrieve a list of PTP interfaces."""
limit = utils.validate_limit(limit)
sort_dir = utils.validate_sort_dir(sort_dir)
marker_obj = None
""" TODO
marker_obj = None
if marker:
marker_obj = objects.ptp_interface.get_by_uuid(pecan.request.context,
marker)
marker_obj = objects.ptp_interface.get_by_uuid(
pecan.request.context, marker)
if self._from_ihosts or host_uuid is not None:
if interface_uuid is not None:
ptp_interfaces = pecan.request.dbapi.ptp_interfaces_get_by_interface(
interface_uuid, limit,
marker_obj,
sort_key,
sort_dir)
ptp_interfaces = \
pecan.request.dbapi.ptp_interfaces_get_by_interface(
interface_uuid, limit, marker_obj, sort_key, sort_dir)
else:
ptp_interfaces = pecan.request.dbapi.ptp_interfaces_get_by_host(
host_uuid, limit,
marker_obj,
sort_key,
sort_dir)
ptp_interfaces = \
pecan.request.dbapi.ptp_interfaces_get_by_host(
host_uuid, limit, marker_obj, sort_key, sort_dir)
else:
ptp_interfaces = pecan.request.dbapi.ptp_interfaces_get_list()
"""
ptp_interfaces = pecan.request.dbapi.ptp_interfaces_get_list()
return PtpInterfaceCollection.convert_with_links(ptp_interfaces,
limit,
url=resource_url,
expand=expand,
sort_key=sort_key,
sort_dir=sort_dir)
@wsme_pecan.wsexpose(PtpInterfaceCollection, types.uuid, types.uuid, int,
wtypes.text, wtypes.text, types.uuid)
def get_all(self, host_uuid, marker=None, limit=None,
sort_key='id', sort_dir='asc', interface_uuid=None):
"""Retrieve a list of PTP interfaces."""
return self._get_ptp_interfaces_collection(host_uuid, marker, limit,
sort_key=sort_key,
sort_dir=sort_dir,
expand=False,
interface_uuid=interface_uuid)
limit,
sort_key=sort_key,
sort_dir=sort_dir)
@wsme_pecan.wsexpose(PtpInterface, types.uuid)
def get_one(self, ptp_interface_uuid):
"""Retrieve information about the given PTP interface"""
rpc_ptp_interface = objects.ptp_interface.get_by_uuid(pecan.request.context,
ptp_interface_uuid)
rpc_ptp_interface = objects.ptp_interface.get_by_uuid(
pecan.request.context, ptp_interface_uuid)
return PtpInterface.convert_with_links(rpc_ptp_interface)
@wsme_pecan.wsexpose(PtpInterface, body=PtpInterface)
@ -187,18 +173,16 @@ class PtpInterfaceController(rest.RestController):
instance_uuid = ptp_interface_dict.pop('ptp_instance_uuid', None)
instance = objects.ptp_instance.get_by_uuid(pecan.request.context,
instance_uuid)
interface_uuid = ptp_interface_dict.pop('interface_uuid', None)
interface = pecan.request.dbapi.iinterface_get(interface_uuid)
ptp_interface_dict['interface_id'] = interface['id']
ptp_interface_dict['ptp_instance_id'] = instance['id']
check = pecan.request.dbapi.ptp_interfaces_get_by_instance_and_interface(
ptp_interface_dict["ptp_instance_id"],
ptp_interface_dict["interface_id"])
""" TODO
check = \
pecan.request.dbapi.ptp_interfaces_get_by_instance_and_interface(
ptp_interface_dict["ptp_instance_id"],
ptp_interface_dict["interface_id"])
if len(check) != 0:
raise exception.PtpInterfaceAlreadyExists()
"""
result = pecan.request.dbapi.ptp_interface_create(ptp_interface_dict)
return PtpInterface.convert_with_links(result)
@ -213,7 +197,7 @@ class PtpInterfaceController(rest.RestController):
raise
# Only allow delete if there are no associated parameters
parameters = pecan.request.dbapi.ptp_parameters_get_by_owner(
parameters = pecan.request.dbapi.ptp_parameters_get_by_owner_uuid(
ptp_interface_uuid)
if parameters:
names = [str(p['name']) for p in parameters]

View File

@ -17,7 +17,6 @@ from sysinv.api.controllers.v1 import base
from sysinv.api.controllers.v1 import collection
from sysinv.api.controllers.v1 import types
from sysinv.api.controllers.v1 import utils
from sysinv.common import constants
from sysinv.common import exception
from sysinv.common import utils as cutils
from sysinv import objects
@ -57,16 +56,8 @@ class PtpParameter(base.APIBase):
value = wtypes.text
"Value of PTP parameter"
type = wtypes.Enum(str,
constants.PTP_PARAMETER_OWNER_INSTANCE,
constants.PTP_PARAMETER_OWNER_INTERFACE)
"Type of owner of this PTP parameter"
foreign_uuid = types.uuid
"UUID of the owner of this PTP parameter"
owner = types.MultiType([dict])
"Owner information: name, type, hostname"
owners = types.MultiType([list])
"Owners information: name, type, etc."
def __init__(self, **kwargs):
self.fields = list(objects.ptp_parameter.fields.keys())
@ -82,9 +73,7 @@ class PtpParameter(base.APIBase):
ptp_parameter.unset_fields_except(['uuid',
'name',
'value',
'type',
'foreign_uuid',
'owner',
'owners',
'created_at',
'updated_at'])
@ -121,11 +110,12 @@ class PtpParameterController(rest.RestController):
def __init__(self, parent=None):
self._parent = parent
def _get_ptp_parameter_collection(
self, parent_uuid=None, type=None, marker=None, limit=None,
sort_key=None, sort_dir=None, expand=False, resource_url=None):
LOG.debug("PtpParameterController._get_ptp_parameter_collection: "
"parent %s uuid %s type %s" %
@wsme_pecan.wsexpose(PtpParameterCollection, types.uuid, wtypes.text,
types.uuid, int, wtypes.text, wtypes.text)
def get_all(self, parent_uuid=None, type=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'):
"""Retrieve a list of PTP parameters."""
LOG.debug("PtpParameterController.get_all: parent %s uuid %s type %s" %
(self._parent, parent_uuid, type))
if self._parent and not parent_uuid:
raise exception.InvalidParameterValue(_(
@ -134,42 +124,27 @@ class PtpParameterController(rest.RestController):
limit = utils.validate_limit(limit)
sort_dir = utils.validate_sort_dir(sort_dir)
LOG.debug("PtpParameterController._get_ptp_parameter_collection: "
"marker %s, limit %s, sort_dir %s" % (marker, limit,
sort_dir))
marker_obj = None
if marker:
marker_obj = objects.ptp_parameter.get_by_uuid(
pecan.request.context, marker)
if parent_uuid:
ptp_parameters = pecan.request.dbapi.ptp_parameters_get_by_owner(
parent_uuid, limit, marker_obj, sort_key=sort_key,
sort_dir=sort_dir)
ptp_parameters = \
pecan.request.dbapi.ptp_parameters_get_by_owner_uuid(
parent_uuid, limit, marker_obj, sort_key=sort_key,
sort_dir=sort_dir)
elif type is not None:
ptp_parameters = pecan.request.dbapi.ptp_parameters_get_by_type(
type, limit, marker_obj, sort_key=sort_key, sort_dir=sort_dir)
ptp_parameters = \
pecan.request.dbapi.ptp_parameters_get_by_owner_type(
type, limit, marker_obj, sort_key=sort_key,
sort_dir=sort_dir)
else:
ptp_parameters = pecan.request.dbapi.ptp_parameters_get_list(
limit, marker_obj, sort_key=sort_key, sort_dir=sort_dir)
return PtpParameterCollection.convert_with_links(
ptp_parameters, limit, url=resource_url, expand=expand,
sort_key=sort_key, sort_dir=sort_dir)
@wsme_pecan.wsexpose(PtpParameterCollection, types.uuid, types.uuid,
int, wtypes.text, wtypes.text)
def get_all(self, uuid=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'):
"""Retrieve a list of PTP parameters."""
type = None
LOG.debug("PtpParameterController.get_all: uuid=%s, type=%s" %
(uuid, type))
return self._get_ptp_parameter_collection(uuid, type,
marker, limit,
sort_key=sort_key,
sort_dir=sort_dir)
ptp_parameters, limit, sort_key=sort_key, sort_dir=sort_dir)
@wsme_pecan.wsexpose(PtpParameter, types.uuid)
def get_one(self, ptp_parameter_uuid):
@ -186,24 +161,6 @@ class PtpParameterController(rest.RestController):
return PtpParameter.convert_with_links(ptp_parameter)
def _check_foreign_exists(self, type, uuid):
LOG.debug("PtpParameterController._check_foreign_exists: "
"type %s uuid %s" % (type, uuid))
try:
if type == constants.PTP_PARAMETER_OWNER_INSTANCE:
try:
pecan.request.dbapi.ptp_instance_get(uuid)
except exception.PtpInstanceNotFound:
raise exception.NotFound
elif type == constants.PTP_PARAMETER_OWNER_INTERFACE:
try:
pecan.request.dbapi.ptp_interface_get(uuid)
except exception.PtpInterfaceNotFound:
raise exception.NotFound
except exception.NotFound:
raise wsme.exc.ClientSideError(
_("No foreign object found with id %s" % uuid))
@cutils.synchronized(LOCK_NAME)
@wsme_pecan.wsexpose(PtpParameter, body=PtpParameter)
def post(self, ptp_parameter):
@ -211,12 +168,9 @@ class PtpParameterController(rest.RestController):
ptp_parameter_dict = ptp_parameter.as_dict()
LOG.debug("PtpParameterController.post: %s" % ptp_parameter_dict)
self._check_foreign_exists(ptp_parameter_dict['type'],
ptp_parameter_dict['foreign_uuid'])
# Get rid of owner details to create the PTP parameter
try:
ptp_parameter_dict.pop('owner')
ptp_parameter_dict.pop('owners')
except KeyError:
LOG.debug("PtpParameterController.post: no owner data in %s" %
ptp_parameter_dict)
@ -259,4 +213,14 @@ class PtpParameterController(rest.RestController):
if self._parent:
raise exception.OperationNotPermitted
# Only allow delete if there are no associated PTP instances and
# interfaces
owners = pecan.request.dbapi.ptp_paramownerships_get_by_parameter(
ptp_parameter_uuid)
if owners:
uuids = [str(o['owner_uuid']) for o in owners]
raise wsme.exc.ClientSideError(
"PTP parameter %s is still associated with %s"
% (ptp_parameter_uuid, uuids))
pecan.request.dbapi.ptp_parameter_destroy(ptp_parameter_uuid)

View File

@ -0,0 +1,158 @@
#
# 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 PtpParameterOwnershipPatchType(types.JsonPatchType):
@staticmethod
def mandatory_attrs():
return []
class PtpParameterOwnership(base.APIBase):
"""API representation of a PTP parameter ownership.
This class enforces type checking and value constraints, and converts
between the internal object model and the API representation of
a PTP parameter ownership.
"""
created_at = wtypes.datetime.datetime
"Timestamp of creation of this PTP parameter ownership"
id = int
"Unique ID for this PTP parameter ownership"
uuid = types.uuid
"Unique UUID for this PTP parameter ownership"
parameter_uuid = types.uuid
"UUID of the PTP parameter (name/value)"
owner_uuid = types.uuid
"UUID of the entity associated to PTP parameter (instance or interface)"
def __init__(self, **kwargs):
self.fields = list(objects.ptp_paramownership.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_paramownership, expand=True):
ptp_parameter_ownership = PtpParameterOwnership(
**rpc_ptp_paramownership.as_dict())
if not expand:
ptp_parameter_ownership.unset_fields_except(
['uuid', 'parameter_uuid', 'owner_uuid', 'created_at'])
LOG.debug("PtpParameterOwnership.convert_with_links: converted %s" %
ptp_parameter_ownership.as_dict())
return ptp_parameter_ownership
class PtpParameterOwnershipCollection(collection.Collection):
"""API representation of a collection of PTP owners."""
ptp_parameter_ownerships = [PtpParameterOwnership]
"A list containing PTP ownership objects"
def __init__(self, **kwargs):
self._type = 'ptp_parameter_ownerships'
@classmethod
def convert_with_links(cls, rpc_ptp_paramownerships, limit, url=None,
expand=False, **kwargs):
collection = PtpParameterOwnershipCollection()
collection.ptp_paramownerships = \
[PtpParameterOwnership.convert_with_links(p, expand)
for p in rpc_ptp_paramownerships]
collection.next = collection.get_next(limit, url=url, **kwargs)
return collection
LOCK_NAME = 'PtpParameterOwnershipController'
class PtpParameterOwnershipController(rest.RestController):
"""REST controller for PTP parameter ownership."""
@wsme_pecan.wsexpose(PtpParameterOwnership, types.uuid)
def get_one(self, ptp_paramownership_uuid):
"""Retrieve a single PTP parameter."""
LOG.debug("PtpParameterOwnershipController.get_one: uuid=%s" %
ptp_paramownership_uuid)
try:
ptp_paramownership = objects.ptp_paramownership.get_by_uuid(
pecan.request.context,
ptp_paramownership_uuid)
except exception.InvalidParameterValue:
raise wsme.exc.ClientSideError(
_("No PTP parameter ownership found for %s"
% ptp_paramownership_uuid))
return PtpParameterOwnership.convert_with_links(ptp_paramownership)
def _check_parameter_exists(self, uuid):
LOG.debug("PtpParameterOwnershipController._check_parameter_exists: "
"uuid %s" % uuid)
try:
pecan.request.dbapi.ptp_parameter_get(uuid)
except exception.PtpParameterNotFound:
raise wsme.exc.ClientSideError(
_("No PTP parameter object found with id %s" % uuid))
def _check_owner_exists(self, uuid):
LOG.debug("PtpParameterOwnershipController._check_owner_exists: "
"uuid %s" % uuid)
try:
pecan.request.dbapi.ptp_paramowner_get(uuid)
except exception.NotFound:
raise wsme.exc.ClientSideError(
_("No PTP parameter owner found with id %s" % uuid))
@cutils.synchronized(LOCK_NAME)
@wsme_pecan.wsexpose(PtpParameterOwnership, body=PtpParameterOwnership)
def post(self, ptp_paramownership):
"""Create a new PTP parameter ownership."""
ptp_paramownership_dict = ptp_paramownership.as_dict()
LOG.debug("PtpParameterOwnershipController.post: %s"
% ptp_paramownership_dict)
self._check_parameter_exists(ptp_paramownership_dict['parameter_uuid'])
self._check_owner_exists(ptp_paramownership_dict['owner_uuid'])
result = pecan.request.dbapi.ptp_parameter_set_owner(
ptp_paramownership_dict)
return PtpParameterOwnership.convert_with_links(result)
@cutils.synchronized(LOCK_NAME)
@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"
% ptp_paramownership_uuid)
ptp_paramownership = objects.ptp_paramownership.get_by_uuid(
pecan.request.context, ptp_paramownership_uuid)
pecan.request.dbapi.ptp_parameter_unset_owner(
ptp_paramownership.as_dict())

View File

@ -461,7 +461,12 @@ class PtpInterfaceAlreadyExists(Conflict):
class PtpParameterAlreadyExists(Conflict):
message = _("A PTP parameter with UUID %(uuid)s already exists.")
message = _("A PTP parameter with name '%(name)s' and value "
"'%(value)s' already exists.")
class PtpParameterOwnershipAlreadyExists(Conflict):
message = _("UUID %(param)s is already a PTP parameter of UUID %(owner)s.")
class PMAlreadyExists(Conflict):
@ -604,6 +609,14 @@ class PtpParameterNotFound(NotFound):
message = _("No PTP parameter with id %(uuid)s found.")
class PtpParameterOwnerNotFound(NotFound):
message = _("No PTP parameter owner with id %(uuid)s found.")
class PtpParameterOwnershipNotFound(NotFound):
message = _("No PTP parameter ownership with id %(uuid)s found.")
class DiskNotFound(NotFound):
message = _("No disk with id %(disk_id)s")

View File

@ -1914,7 +1914,6 @@ class Connection(object):
{
'name': 'default',
'service': 'ptp4l',
'host': 'controller-0',
'capabilities': { ... }
}
:returns: A PTP service instance.
@ -1929,19 +1928,21 @@ class Connection(object):
"""
@abc.abstractmethod
def ptp_instance_get_one(self, name=None, service=None):
def ptp_instance_get_one(self, name=None, host=None, service=None):
"""Returns exactly one PTP service instance.
:param name: name of PTP instance given by user.
:param host: id or uuid of host.
:param service: service of PTP instance.
:returns: A PTP service instance.
"""
@abc.abstractmethod
def ptp_instances_get_list(self, limit=None, marker=None, sort_key=None,
sort_dir=None):
def ptp_instances_get_list(self, host=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 limit: Maximum number of PTP instances to return.
:param marker: The last item of the previous page; we return the next
result set.
@ -1951,38 +1952,6 @@ class Connection(object):
:returns: A list of PTP instances.
"""
@abc.abstractmethod
def ptp_instances_get_by_ihost(self, ihost_id, limit=None, marker=None,
sort_key=None, sort_dir=None):
"""Returns a list of the PTP instances for a given ihost.
:param ihost_id: The id or uuid of an ihost.
:param limit: Maximum number of PTP instances 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 PTP instances.
"""
@abc.abstractmethod
def ptp_instance_update(self, ptp_instance_id, values):
"""Updates properties of a PTP instance.
:param ptp_instance_id: The id or uuid of a PTP instance.
:param values: May be a partial list, eg. when setting the
properties for capabilities. For example:
{
'capabilities':
{
'my-field-1': val1,
'my-field-2': val2
}
}
:returns: A PTP service instance.
"""
@abc.abstractmethod
def ptp_instance_destroy(self, ptp_instance_id):
"""Destroys a PTP service instance.
@ -2041,39 +2010,6 @@ class Connection(object):
:returns: A list of PTP interface associations.
"""
@abc.abstractmethod
def ptp_interfaces_get_by_host(self, host_uuid, limit=None,
marker=None, sort_key=None,
sort_dir=None):
"""Returns a list of the PTP associations for a given host.
:param host_uuid: The id or uuid of a host.
:param limit: Maximum number of PTP associations 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 PTP associations (instances) for the host
"""
@abc.abstractmethod
def ptp_interfaces_get_by_interface(self, interface_id, limit=None,
marker=None, sort_key=None,
sort_dir=None):
"""Returns a list of the PTP associations for a given interface.
:param interface_id: The id or uuid of an interface.
:param limit: Maximum number of PTP associations 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 PTP associations (instances) for the interface.
"""
@abc.abstractmethod
def ptp_interfaces_get_by_instance(self, ptp_instance_id, limit=None,
marker=None, sort_key=None,
@ -2110,21 +2046,6 @@ class Connection(object):
interface.
"""
def ptp_interface_update(self, ptp_interface_id, values):
"""Updates capabilities of a PTP interface.
:param ptp_interface_id: The id or uuid of a PTP interface.
:param values: May be a partial list. For example:
{
'capabilities':
{
'my-field-1': val1,
'my-field-2': val2
}
}
:returns: A PTP interface association.
"""
@abc.abstractmethod
def ptp_interface_destroy(self, ptp_interface_id):
"""Destroys a PTP interface association.
@ -2134,15 +2055,14 @@ class Connection(object):
@abc.abstractmethod
def ptp_parameter_create(self, values):
"""Creates a new PTP parameter.
"""Creates a new PTP parameter to be applied later either to some
instance(s) or PTP interface(s).
:param values: A dict containing several items used to identify
and track the PTP parameter.
{
'name': 'domain',
'value': '24',
'type': 'ptp-instance',
'foreign_uuid': 'c2abca03-2f33-413e-b60d-85133a4a37b6'
'value': '24'
}
:returns: A PTP parameter.
"""
@ -2178,8 +2098,8 @@ class Connection(object):
"""
@abc.abstractmethod
def ptp_parameters_get_by_type(self, type, limit=None, marker=None,
sort_key=None, sort_dir=None):
def ptp_parameters_get_by_owner_type(self, type, limit=None, marker=None,
sort_key=None, sort_dir=None):
"""Returns a list of all PTP parameters for a given owner type.
:param type: Type of the parameter owner (either 'ptp-instance' or
@ -2194,8 +2114,8 @@ class Connection(object):
"""
@abc.abstractmethod
def ptp_parameters_get_by_owner(self, uuid, limit=None, marker=None,
sort_key=None, sort_dir=None):
def ptp_parameters_get_by_owner_uuid(self, uuid, limit=None, marker=None,
sort_key=None, sort_dir=None):
"""Returns a list of the PTP parameters for a given owner identified by
its UUID.
@ -2221,6 +2141,50 @@ class Connection(object):
:returns: A PTP parameter.
"""
@abc.abstractmethod
def ptp_parameter_set_owner(self, values):
"""Set the PTP parameter to either a PTP instance or PTP interface
by associating their UUIDs to each other.
:param values: A dict containing the IDs used to associate
the PTP parameter to the owner entity.
{
'parameter_uuid': '86089c13-c687-4025-991b-45525d031b67',
'owner_uuid': 'ccc95d7c-abea-47ef-955b-026d68fd2b02'
}
:returns: A PTP parameter association.
"""
@abc.abstractmethod
def ptp_parameter_unset_owner(self, values):
"""Remove the association between a PTP parameter and either a PTP
instance or interface.
:param values: A dict containing the IDs used to associate
the PTP parameter to the owner entity.
{
'parameter_uuid': '86089c13-c687-4025-991b-45525d031b67',
'owner_uuid': 'ccc95d7c-abea-47ef-955b-026d68fd2b02'
}
"""
@abc.abstractmethod
def ptp_parameter_get_owners_list(self, ptp_parameter_id, limit=None,
marker=None, sort_key=None,
sort_dir=None):
"""Returns a list of all PTP instances and/or PTP interfaces that refer
to the PTP parameter.
:param ptp_parameter_id: The id or uuid of a PTP parameter.
:param limit: Maximum number of owners 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 owners for the given PTP parameter.
"""
@abc.abstractmethod
def ptp_parameter_destroy(self, ptp_parameter_id):
"""Destroys a PTP parameter.
@ -2228,6 +2192,55 @@ class Connection(object):
:param ptp_parameter_id: The id or uuid of a PTP parameter.
"""
@abc.abstractmethod
def ptp_paramowner_get(self, ptp_paramowner_id):
"""Returns a PTP parameter owner (can be either a PTP instance or a
PTP interface).
:param ptp_paramowner_id: The id or uuid of a PTP owner.
:returns: A PTP parameter owner.
"""
@abc.abstractmethod
def ptp_paramownership_get(self, ptp_paramownership_id):
"""Returns a PTP parameter ownership.
:param ptp_paramownership_id: The id or uuid of a PTP parameter
ownership.
:returns: A PTP parameter ownership.
"""
@abc.abstractmethod
def ptp_paramownerships_get_by_parameter(self, uuid, limit=None,
marker=None, sort_key=None,
sort_dir=None):
"""Returns a list of PTP ownerships for a given parameter.
:param uuid: UUID of the PTP parameter owner.
:param limit: Maximum number of PTP ownerships 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 PTP parameter ownerships.
"""
@abc.abstractmethod
def ptp_paramownerships_get_by_owner(self, uuid, limit=None, marker=None,
sort_key=None, sort_dir=None):
"""Returns a list of PTP ownerships for a given owner.
:param uuid: UUID of the PTP parameter owner (instance or interface).
:param limit: Maximum number of PTP ownerships 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 PTP parameter ownerships.
"""
@abc.abstractmethod
def iextoam_get_one(self):
"""Return exactly one iextoam.

View File

@ -1178,43 +1178,6 @@ def add_deviceimage_filter(query, value):
return add_identity_filter(query, value, use_name=True)
def add_ptp_instance_filter_by_host(query, hostid):
"""Adds a ptp-instance-specific ihost filter to a query.
Filters results by host id if supplied value is an integer,
otherwise attempts to filter results by host uuid.
:param query: Initial query to add filter to.
:param hostid: host id or uuid to filter results by.
:return: Modified query.
"""
if utils.is_int_like(hostid):
return query.filter_by(host_id=hostid)
elif utils.is_uuid_like(hostid):
query = query.join(models.ihost)
return query.filter(models.ihost.uuid == hostid)
LOG.debug("ptp_instance_filter_by_host: "
"No match for supplied filter id (%s)" % str(hostid))
def add_ptp_parameter_filter_by_owner(query, type, uuid):
if type == constants.PTP_PARAMETER_OWNER_INSTANCE:
query = query.join(models.PtpInstances,
models.PtpInstances.uuid == uuid)
elif type == constants.PTP_PARAMETER_OWNER_INTERFACE:
query = (query.join(models.PtpInterfaces,
models.PtpInterfaces.uuid == uuid)
.join(models.Interfaces, models.Interfaces.id ==
models.PtpInterfaces.interface_id))
else:
LOG.error("ptp_parameter_filter_by_owner: "
"Invalid owner type (%s)" % type)
raise exception.Invalid()
return query
class Connection(api.Connection):
"""SqlAlchemy connection."""
@ -3791,10 +3754,23 @@ class Connection(api.Connection):
return self._ptp_instance_get(ptp_instance_id)
@objects.objectify(objects.ptp_instance)
def ptp_instance_get_one(self, name=None, service=None):
def ptp_instance_get_one(self, name=None, host=None, service=None):
query = model_query(models.PtpInstances)
if name is not None:
query = query.filter_by(name=name)
elif 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 None
query = add_identity_filter(query, ptp_instance_id)
elif service is not None:
query = query.filter_by(service=service)
try:
@ -3803,33 +3779,29 @@ class Connection(api.Connection):
raise exception.NotFound()
@objects.objectify(objects.ptp_instance)
def ptp_instances_get_list(self, limit=None, marker=None,
def ptp_instances_get_list(self, host=None, limit=None, marker=None,
sort_key=None, sort_dir=None):
query = model_query(models.PtpInstances)
return _paginate_query(models.PtpInstances, limit, marker,
sort_key, sort_dir, query)
@objects.objectify(objects.ptp_instance)
def ptp_instances_get_by_ihost(self, ihost_id, limit=None, marker=None,
sort_key=None, sort_dir=None):
query = model_query(models.PtpInstances)
query = add_ptp_instance_filter_by_host(query, ihost_id)
return _paginate_query(models.PtpInstances, limit, marker,
sort_key, sort_dir, query)
@objects.objectify(objects.ptp_instance)
def ptp_instance_update(self, ptp_instance_id, values):
with _session_for_write() as session:
query = model_query(models.PtpInstances, session=session)
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)
count = query.update(values, synchronize_session='fetch')
if count != 1:
raise exception.PtpInstanceNotFound(uuid=ptp_instance_id)
return query.one()
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:
query = model_query(models.PtpInstances, session=session)
# PTP instance will be deleted by cascade
query = model_query(models.PtpParameterOwners, session=session)
query = add_identity_filter(query, ptp_instance_id)
try:
query.one()
@ -3874,56 +3846,37 @@ class Connection(api.Connection):
return self._ptp_interface_get(ptp_interface_id)
@objects.objectify(objects.ptp_interface)
def ptp_interface_get_one(self):
def ptp_interface_get_one(self, interface_uuid=None):
query = model_query(models.PtpInterfaces)
if interface_uuid is not None:
interface = self.iinterface_get(interface_uuid)
ptp_interface_id = interface['ptp_interface_id']
if not ptp_interface_id:
return None
query = add_identity_filter(query, ptp_interface_id)
try:
return query.one()
except NoResultFound:
raise exception.NotFound()
@objects.objectify(objects.ptp_interface)
def ptp_interfaces_get_list(self, limit=None, marker=None, sort_key=None,
def ptp_interfaces_get_list(self, host_uuid=None, interface_uuid=None,
limit=None, marker=None, sort_key=None,
sort_dir=None):
query = model_query(models.PtpInterfaces)
return _paginate_query(models.PtpInterfaces, limit, marker,
sort_key, sort_dir, query)
@objects.objectify(objects.ptp_interface)
def ptp_interfaces_get_by_host(self, host_uuid, limit=None,
marker=None, sort_key=None,
sort_dir=None):
ihost_obj = self.ihost_get(host_uuid)
query = model_query(models.PtpInterfaces)
query = (query.join(models.Interfaces).
join(models.ihost,
models.ihost.id == models.Interfaces.forihostid))
query, field = add_filter_by_many_identities(query, models.ihost, [ihost_obj.uuid])
return _paginate_query(models.PtpInterfaces, limit, marker, sort_key, sort_dir, query)
@objects.objectify(objects.ptp_interface)
def ptp_interfaces_get_by_interface(self, interface_id, limit=None,
marker=None, sort_key=None,
sort_dir=None):
# NOTE: iinterface_get() to raise an exception if the interface is
# not found or multiple results found
iface_obj = self.iinterface_get(interface_id)
query = model_query(models.PtpInterfaces)
query = query.filter_by(interface_id=iface_obj.id)
return _paginate_query(models.PtpInterfaces, limit, marker,
sort_key, sort_dir, query)
@objects.objectify(objects.ptp_interface)
def ptp_interfaces_get_by_instance_and_interface(self, ptp_instance_id,
interface_id,
limit=None,
marker=None,
sort_key=None,
sort_dir=None):
ptp_instance_obj = self.ptp_instance_get(ptp_instance_id)
ptp_interface_obj = self.iinterface_get(interface_id)
query = model_query(models.PtpInterfaces)
query = query.filter_by(interface_id=ptp_interface_obj.id)
query = query.filter_by(ptp_instance_id=ptp_instance_obj.id)
if host_uuid is not None:
query = query.join(models.Interfaces).join(
models.ihost,
models.ihost.id == models.Interfaces.forihostid).filter(
models.ihost.uuid == host_uuid,
models.Interfaces.ptp_interface_id ==
models.PtpInterfaces.id)
elif interface_uuid is not None:
interface = self.iinterface_get(interface_uuid)
ptp_interface_id = interface['ptp_interface_id']
if not ptp_interface_id:
return []
query = add_identity_filter(query, ptp_interface_id)
return _paginate_query(models.PtpInterfaces, limit, marker,
sort_key, sort_dir, query)
@ -3940,18 +3893,27 @@ class Connection(api.Connection):
sort_key, sort_dir, query)
@objects.objectify(objects.ptp_interface)
def ptp_interface_update(self, ptp_interface_id, values):
with _session_for_write() as session:
query = model_query(models.PtpInterfaces, session=session)
query = add_identity_filter(query, ptp_interface_id)
count = query.update(values, synchronize_session='fetch')
if count != 1:
raise exception.PtpInterfaceNotFound(uuid=ptp_interface_id)
return query.one()
def ptp_interfaces_get_by_instance_and_interface(self, ptp_instance_id,
interface_id,
limit=None,
marker=None,
sort_key=None,
sort_dir=None):
query = model_query(models.PtpInterfaces)
interface = self.iinterface_get(interface_id)
ptp_interface_id = interface['ptp_interface_id']
if not ptp_interface_id:
return []
query = add_identity_filter(query, ptp_interface_id)
ptp_instance_obj = self.ptp_instance_get(ptp_instance_id)
query = query.filter_by(ptp_instance_id=ptp_instance_obj.id)
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:
query = model_query(models.PtpInterfaces, session=session)
# PTP instance will be deleted by cascade
query = model_query(models.PtpParameterOwners, session=session)
query = add_identity_filter(query, ptp_interface_id)
try:
query.one()
@ -3978,7 +3940,8 @@ class Connection(api.Connection):
session.add(ptp_parameter)
session.flush()
except db_exc.DBDuplicateEntry:
raise exception.PtpParameterAlreadyExists(uuid=values['uuid'])
raise exception.PtpParameterAlreadyExists(
name=values['name'], value=values['value'])
return self._ptp_parameter_get(values['uuid'])
@objects.objectify(objects.ptp_parameter)
@ -4003,34 +3966,22 @@ class Connection(api.Connection):
sort_key, sort_dir, query)
@objects.objectify(objects.ptp_parameter)
def ptp_parameters_get_by_type(self, type, limit=None, marker=None,
sort_key=None, sort_dir=None):
def ptp_parameters_get_by_owner_type(self, type, limit=None, marker=None,
sort_key=None, sort_dir=None):
query = model_query(models.PtpParameters)
query = query.filter_by(type=type)
return _paginate_query(models.PtpParameters, limit, marker,
sort_key, sort_dir, query)
def _ptp_parameter_get_type(self, uuid):
type = None
query = model_query(models.PtpParameters)
query = query.filter_by(foreign_uuid=uuid)
ptp_parameter_object = query.first()
if ptp_parameter_object:
type = ptp_parameter_object.type
return type
query = query.join(models.PtpParameters.ptp_parameter_owners).filter(
models.PtpParameterOwners.type == type)
return _paginate_query(models.PtpParameters, limit, marker, sort_key,
sort_dir, query)
@objects.objectify(objects.ptp_parameter)
def ptp_parameters_get_by_owner(self, uuid, limit=None, marker=None,
sort_key=None, sort_dir=None):
type = self._ptp_parameter_get_type(uuid)
if not type:
return []
def ptp_parameters_get_by_owner_uuid(self, uuid, limit=None, marker=None,
sort_key=None, sort_dir=None):
query = model_query(models.PtpParameters)
query = query.filter_by(foreign_uuid=uuid)
query = add_ptp_parameter_filter_by_owner(query, type, uuid)
return _paginate_query(models.PtpParameters, limit, marker,
sort_key, sort_dir, query)
query = query.join(models.PtpParameters.ptp_parameter_owners).filter(
models.PtpParameterOwners.uuid == uuid)
return _paginate_query(models.PtpParameters, limit, marker, sort_key,
sort_dir, query)
@objects.objectify(objects.ptp_parameter)
def ptp_parameter_update(self, ptp_parameter_id, values):
@ -4042,6 +3993,49 @@ class Connection(api.Connection):
raise exception.PtpParameterNotFound(uuid=ptp_parameter_id)
return query.one()
@objects.objectify(objects.ptp_paramownership)
def ptp_parameter_set_owner(self, values):
if not values.get('uuid'):
values['uuid'] = uuidutils.generate_uuid()
param_ownership = models.PtpParameterOwnerships(**values)
with _session_for_write() as session:
try:
session.add(param_ownership)
session.flush()
except db_exc.DBDuplicateEntry:
raise exception.PtpParameterOwnershipAlreadyExists(
param=values['parameter_uuid'], owner=values['owner_uuid'])
query = model_query(models.PtpParameterOwnerships)
query = add_identity_filter(query, values['uuid'])
try:
return query.one()
except NoResultFound:
raise exception.PtpParameterOwnershipNotFound(
uuid=values['uuid'])
def ptp_parameter_unset_owner(self, values):
with _session_for_write() as session:
query = model_query(models.PtpParameterOwnerships, session=session)
query = query.filter_by(parameter_uuid=values['parameter_uuid'],
owner_uuid=values['owner_uuid'])
try:
query.one()
except NoResultFound:
return
query.delete()
@objects.objectify(objects.ptp_parameter)
def ptp_parameter_get_owners_list(self, ptp_parameter_id, limit=None,
marker=None, sort_key=None,
sort_dir=None):
query = model_query(models.PtpParameters)
query = add_identity_filter(query, ptp_parameter_id)
query = query.join(models.PtpParameters.ptp_parameter_owners)
return _paginate_query(models.PtpParameters, limit, marker, sort_key,
sort_dir, query)
def ptp_parameter_destroy(self, ptp_parameter_id):
with _session_for_write() as session:
query = model_query(models.PtpParameters, session=session)
@ -4052,6 +4046,42 @@ class Connection(api.Connection):
raise exception.PtpParameterNotFound(uuid=ptp_parameter_id)
query.delete()
@objects.objectify(objects.ptp_paramowner)
def ptp_paramowner_get(self, ptp_paramowner_id):
query = model_query(models.PtpParameterOwners)
query = add_identity_filter(query, ptp_paramowner_id)
try:
return query.one()
except NoResultFound:
raise exception.PtpParameterOwnerNotFound(uuid=ptp_paramowner_id)
@objects.objectify(objects.ptp_paramownership)
def ptp_paramownership_get(self, ptp_paramownership_id):
query = model_query(models.PtpParameterOwnerships)
query = add_identity_filter(query, ptp_paramownership_id)
try:
return query.one()
except NoResultFound:
raise exception.PtpParameterOwnershipNotFound(
uuid=ptp_paramownership_id)
@objects.objectify(objects.ptp_paramownership)
def ptp_paramownerships_get_by_parameter(self, uuid, limit=None,
marker=None, sort_key=None,
sort_dir=None):
query = model_query(models.PtpParameterOwnerships)
query = query.filter_by(parameter_uuid=uuid)
return _paginate_query(models.PtpParameterOwnerships, limit, marker,
sort_key, sort_dir, query)
@objects.objectify(objects.ptp_paramownership)
def ptp_paramownerships_get_by_owner(self, uuid, limit=None, marker=None,
sort_key=None, sort_dir=None):
query = model_query(models.PtpParameterOwnerships)
query = query.filter_by(owner_uuid=uuid)
return _paginate_query(models.PtpParameterOwnerships, limit, marker,
sort_key, sort_dir, query)
# NOTE: method is deprecated and provided for API compatibility.
# object class will convert Network entity to an iextoam object
@objects.objectify(objects.oam_network)

View File

@ -22,7 +22,7 @@ CHARSET = 'utf8'
def _populate_ptp_tables(meta, ptp_instances, ptp_interfaces,
ptp_parameters, i_host, interfaces):
ptp_parameters, ptp_parameter_ownerships):
"""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,51 +46,6 @@ def upgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
i_host = Table('i_host', meta, autoload=True)
ptp_instances = Table(
'ptp_instances',
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('name', String(255), unique=True),
Column('service', String(255)),
Column('host_id', Integer,
ForeignKey('i_host.id', ondelete="CASCADE")),
Column('capabilities', Text),
mysql_engine=ENGINE,
mysql_charset=CHARSET,
)
ptp_instances.create()
interfaces = Table('interfaces', meta, autoload=True)
ptp_interfaces = Table(
'ptp_interfaces',
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")),
Column('ptp_instance_id', Integer,
ForeignKey('ptp_instances.id', ondelete="CASCADE")),
Column('capabilities', Text),
mysql_engine=ENGINE,
mysql_charset=CHARSET,
)
ptp_interfaces.create()
ptp_parameters = Table(
'ptp_parameters',
meta,
@ -101,31 +56,125 @@ def upgrade(migrate_engine):
Column('id', Integer, primary_key=True, nullable=False),
Column('uuid', String(UUID_LENGTH), unique=True),
Column('name', String(255), nullable=False),
Column('name', String(255), unique=True, nullable=False),
Column('value', String(255)),
Column('type', String(255)),
Column('foreign_uuid', String(UUID_LENGTH), nullable=False),
UniqueConstraint('name', 'foreign_uuid', name='u_paramnameforeign'),
UniqueConstraint('name', 'value', name='u_paramnamevalue'),
mysql_engine=ENGINE,
mysql_charset=CHARSET,
)
ptp_parameters.create()
ptp_parameter_owners = Table(
'ptp_parameter_owners',
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('type', String(255), nullable=False),
Column('capabilities', Text),
mysql_engine=ENGINE,
mysql_charset=CHARSET,
)
ptp_parameter_owners.create()
ptp_instances = Table(
'ptp_instances',
meta,
Column('created_at', DateTime),
Column('updated_at', DateTime),
Column('deleted_at', DateTime),
Column('id', Integer,
ForeignKey('ptp_parameter_owners.id', ondelete="CASCADE"),
primary_key=True, nullable=False),
Column('name', String(255), unique=True, nullable=False),
Column('service', String(255)),
mysql_engine=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')))
ptp_interfaces = Table(
'ptp_interfaces',
meta,
Column('created_at', DateTime),
Column('updated_at', DateTime),
Column('deleted_at', DateTime),
Column('id', Integer,
ForeignKey('ptp_parameter_owners.id', ondelete="CASCADE"),
primary_key=True, nullable=False),
Column('ptp_instance_id', Integer,
ForeignKey('ptp_instances.id', ondelete="CASCADE"),
nullable=False),
mysql_engine=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')))
ptp_parameter_ownerships = Table(
'ptp_parameter_ownerships',
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('parameter_uuid', String(UUID_LENGTH),
ForeignKey('ptp_parameters.uuid', ondelete='CASCADE'),
nullable=False),
Column('owner_uuid', String(UUID_LENGTH), nullable=False),
UniqueConstraint('parameter_uuid', 'owner_uuid', name='u_paramowner'),
mysql_engine=ENGINE,
mysql_charset=CHARSET,
)
ptp_parameter_ownerships.create()
_populate_ptp_tables(meta, ptp_instances, ptp_interfaces, ptp_parameters,
i_host, interfaces)
ptp_parameter_ownerships)
def downgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
ptp_parameters = Table('ptp_parameters', meta, autoload=True)
ptp_parameters.drop()
ptp_parameter_ownerships = Table('ptp_parameter_ownerships',
meta,
autoload=True)
ptp_parameter_ownerships.drop()
ptp_interfaces = Table('ptp_interfaces', meta, autoload=True)
ptp_interfaces.drop()
ptp_instances = Table('ptp_instances', meta, autoload=True)
ptp_instances.drop()
ptp_parameter_owners = Table('ptp_parameter_owners', meta, autoload=True)
ptp_parameter_owners.drop()
ptp_parameters = Table('ptp_parameters', meta, autoload=True)
ptp_parameters.drop()

View File

@ -245,6 +245,9 @@ 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)
@ -262,7 +265,7 @@ class inode(Base):
forihostid = Column(Integer, ForeignKey('i_host.id', ondelete='CASCADE'))
host = relationship("ihost", backref="nodes", lazy="joined", cascade="all")
host = relationship("ihost", backref="nodes", lazy="joined", join_depth=1)
UniqueConstraint('numa_node', 'forihostid', name='u_hostnuma')
@ -356,7 +359,10 @@ class Interfaces(Base):
farend = Column(JSONEncodedDict)
sriov_numvfs = Column(Integer)
sriov_vf_driver = Column(String(255))
ptp_role = Column(String(255), default='none')
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",
@ -369,7 +375,7 @@ class Interfaces(Base):
join_depth=1)
host = relationship("ihost", backref="interfaces",
lazy="joined", cascade="all")
lazy="joined", join_depth=1)
addresses = relationship("Addresses",
backref=backref("interface", lazy="joined"),
@ -481,10 +487,10 @@ class Ports(Base):
capabilities = Column(JSONEncodedDict)
# JSON{'speed':1000,'MTU':9600, 'duplex':'', 'autonegotiation':'false'}
node = relationship("inode", backref="ports", lazy="joined", cascade="all")
host = relationship("ihost", backref="ports", lazy="joined", cascade="all")
node = relationship("inode", backref="ports", lazy="joined", join_depth=1)
host = relationship("ihost", backref="ports", lazy="joined", join_depth=1)
interface = relationship("Interfaces", backref="port",
lazy="joined", cascade="all")
lazy="joined", join_depth=1)
UniqueConstraint('pciaddr', 'dev_id', 'host_id', name='u_pciaddrdevihost')
@ -784,45 +790,6 @@ class PTP(Base):
system = relationship("isystem", lazy="joined", join_depth=1)
class PtpInstances(Base):
__tablename__ = "ptp_instances"
id = Column(Integer, primary_key=True, nullable=False)
uuid = Column(String(UUID_LENGTH), unique=True)
name = Column(String(255), unique=True)
service = Column(String(255))
host_id = Column(Integer, ForeignKey('i_host.id', ondelete='CASCADE'),
nullable=True)
# capabilities not used yet: JSON{'':"", '':''}
capabilities = Column(JSONEncodedDict)
host = relationship("ihost", backref="ptp_instance", lazy="joined",
cascade="all")
class PtpInterfaces(Base):
__tablename__ = "ptp_interfaces"
id = Column(Integer, primary_key=True, nullable=False)
uuid = Column(String(UUID_LENGTH), unique=True)
interface_id = Column(Integer,
ForeignKey('interfaces.id', ondelete='CASCADE'))
ptp_instance_id = Column(Integer,
ForeignKey('ptp_instances.id',
ondelete='CASCADE'))
# capabilities not used yet: JSON{'':"", '':''}
capabilities = Column(JSONEncodedDict)
interface = relationship("Interfaces", backref="ptp_interface",
lazy="joined", cascade="all")
ptp_instance = relationship("PtpInstances", backref="ptp_interface",
lazy="joined", cascade="all")
class PtpParameters(Base):
__tablename__ = "ptp_parameters"
@ -832,23 +799,106 @@ class PtpParameters(Base):
name = Column(String(255), nullable=False)
value = Column(String(255))
type = Column(String(255))
foreign_uuid = Column(String(UUID_LENGTH), nullable=False)
ptp_parameter_owners = relationship(
"PtpParameterOwners",
secondary="ptp_parameter_ownerships",
primaryjoin="PtpParameters.uuid == "
"foreign(PtpParameterOwnerships.parameter_uuid)",
secondaryjoin="PtpParameterOwners.uuid == "
"foreign(PtpParameterOwnerships.owner_uuid)",
back_populates="ptp_parameters", lazy="joined", join_depth=1)
ptp_instance = relationship(
"PtpInstances",
primaryjoin="PtpParameters.foreign_uuid == foreign(PtpInstances.uuid)",
lazy="subquery",
cascade="all")
UniqueConstraint('name', 'value', name='u_paramnamevalue')
ptp_interface = relationship(
"PtpInterfaces",
primaryjoin="PtpParameters.foreign_uuid == "
"foreign(PtpInterfaces.uuid)",
lazy="subquery",
cascade="all")
UniqueConstraint('name', 'foreign_uuid', name='u_paramnameforeign')
class PtpParameterOwners(Base):
__tablename__ = "ptp_parameter_owners"
id = Column(Integer, primary_key=True, nullable=False)
uuid = Column(String(UUID_LENGTH), unique=True)
type = Column(String(255), nullable=False)
# capabilities not used yet: JSON{'':"", '':''}
capabilities = Column(JSONEncodedDict)
ptp_parameters = relationship(
"PtpParameters",
secondary="ptp_parameter_ownerships",
primaryjoin="PtpParameterOwners.uuid == "
"foreign(PtpParameterOwnerships.owner_uuid)",
secondaryjoin="PtpParameters.uuid == "
"foreign(PtpParameterOwnerships.parameter_uuid)",
back_populates="ptp_parameter_owners", lazy="joined", join_depth=1)
__mapper_args__ = {
'polymorphic_identity': 'ptp_parameter_owner',
'polymorphic_on': type,
'with_polymorphic': '*'
}
class PtpInstances(PtpParameterOwners):
__tablename__ = "ptp_instances"
id = Column(Integer, ForeignKey('ptp_parameter_owners.id'),
primary_key=True,
nullable=False)
name = Column(String(255), unique=True, nullable=False)
service = Column(String(255))
__mapper_args__ = {
'polymorphic_identity': constants.PTP_PARAMETER_OWNER_INSTANCE
}
class PtpInterfaces(PtpParameterOwners):
__tablename__ = "ptp_interfaces"
id = Column(Integer, ForeignKey('ptp_parameter_owners.id'),
primary_key=True,
nullable=False)
ptp_instance_id = Column(Integer,
ForeignKey('ptp_instances.id',
ondelete='CASCADE'),
nullable=False)
ptp_instance = relationship("PtpInstances", lazy="joined", join_depth=1,
foreign_keys=[
PtpInstances.id,
PtpInstances.name,
PtpInstances.uuid])
__mapper_args__ = {
'polymorphic_identity': constants.PTP_PARAMETER_OWNER_INTERFACE
}
class PtpParameterOwnerships(Base):
"""
This is a bridge table used to model the many-to-many relationship between
PTP parameters and their owners: PTP instances and PTP interfaces.
"""
__tablename__ = "ptp_parameter_ownerships"
id = Column(Integer, primary_key=True, nullable=False)
uuid = Column(String(UUID_LENGTH), unique=True)
parameter_uuid = Column(String(UUID_LENGTH),
ForeignKey('ptp_parameters.uuid',
ondelete='CASCADE'),
nullable=False)
owner_uuid = Column(String(UUID_LENGTH), 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)
UniqueConstraint('parameter_uuid', 'owner_uuid', name='u_paramowner')
class StorageTier(Base):

View File

@ -73,6 +73,8 @@ from sysinv.objects import ptp
from sysinv.objects import ptp_instance
from sysinv.objects import ptp_interface
from sysinv.objects import ptp_parameter
from sysinv.objects import ptp_paramowner
from sysinv.objects import ptp_paramownership
from sysinv.objects import pv
from sysinv.objects import remote_logging
from sysinv.objects import route
@ -160,6 +162,8 @@ ptp = ptp.PTP
ptp_instance = ptp_instance.PtpInstance
ptp_interface = ptp_interface.PtpInterface
ptp_parameter = ptp_parameter.PtpParameter
ptp_paramowner = ptp_paramowner.PtpParameterOwner
ptp_paramownership = ptp_paramownership.PtpParameterOwnership
oam_network = network_oam.OAMNetwork
storage_backend = storage_backend.StorageBackend
storage_ceph = storage_ceph.StorageCeph
@ -242,6 +246,8 @@ __all__ = ("system",
"ptp_instance",
"ptp_interface",
"ptp_parameter",
"ptp_paramowner",
"ptp_paramownership",
"oam_network",
"storage_backend",
"storage_ceph",

View File

@ -23,6 +23,11 @@ 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()
@ -32,6 +37,7 @@ 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,
@ -76,6 +82,7 @@ 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,
@ -97,6 +104,7 @@ class Host(base.SysinvObject):
'isystem_uuid': 'system:uuid',
'software_load': _get_software_load,
'target_load': _get_target_load,
'ptp_config': _get_ptp_configuration
}
@base.remotable_classmethod

View File

@ -108,6 +108,11 @@ 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
@ -120,6 +125,7 @@ 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,
@ -148,6 +154,7 @@ 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,
}
@ -159,7 +166,8 @@ class Interface(base.SysinvObject):
'ipv6_pool': get_ipv6_address_pool,
'ihost_uuid': get_host_uuid,
'networktypelist': get_networktypes,
'datanetworks': get_datanetworks}
'datanetworks': get_datanetworks,
'ptp_config': _get_ptp_configuration}
_optional_fields = ['aemode', 'txhashpolicy', 'schedpolicy',
'vlan_id', 'vlan_type', 'primary_reselect']

View File

@ -9,36 +9,20 @@
from sysinv.db import api as db_api
from sysinv.objects import base
from sysinv.objects import utils
from sysinv.objects import ptp_paramowner
class PtpInstance(base.SysinvObject):
class PtpInstance(ptp_paramowner.PtpParameterOwner):
dbapi = db_api.get_instance()
fields = {
'id': int,
'uuid': utils.str_or_none,
fields = dict({
'name': utils.str_or_none,
'service': utils.str_or_none,
'service': utils.str_or_none
}, **ptp_paramowner.PtpParameterOwner.fields)
'host_id': utils.int_or_none,
'host_uuid': utils.str_or_none,
'hostname': utils.str_or_none,
'capabilities': utils.dict_or_none
}
_foreign_fields = {
'host_uuid': 'host:uuid',
'hostname': 'host:hostname'
}
_foreign_fields = {}
@base.remotable_classmethod
def get_by_uuid(cls, context, uuid):
return cls.dbapi.ptp_instance_get(uuid)
def save_changes(self, context, updates):
self.dbapi.ptp_instance_update(self.uuid, # pylint: disable=no-member
updates)

View File

@ -9,37 +9,22 @@
from sysinv.db import api as db_api
from sysinv.objects import base
from sysinv.objects import utils
from sysinv.objects import ptp_paramowner
class PtpInterface(base.SysinvObject):
class PtpInterface(ptp_paramowner.PtpParameterOwner):
dbapi = db_api.get_instance()
fields = {
'id': int,
'uuid': utils.str_or_none,
'interface_uuid': utils.str_or_none,
'interface_id': utils.int_or_none,
'ptp_instance_uuid': utils.str_or_none,
fields = dict({
'ptp_instance_id': utils.int_or_none,
'ptp_instance_name': utils.str_or_none,
'ifname': utils.str_or_none,
'forihostid': utils.int_or_none,
'capabilities': utils.dict_or_none
}
'ptp_instance_uuid': utils.str_or_none,
'ptp_instance_name': utils.str_or_none
}, **ptp_paramowner.PtpParameterOwner.fields)
_foreign_fields = {
'interface_uuid': 'interface:uuid',
'interface_id': 'interface:id',
'ptp_instance_uuid': 'ptp_instance:uuid',
'ptp_instance_name': 'ptp_instance:name',
'ifname': 'interface:ifname',
'forihostid': 'interface:forihostid',
'ptp_instance_host': 'ptp_instance:host_id'
'ptp_instance_name': 'ptp_instance:name'
}
@base.remotable_classmethod

View File

@ -12,30 +12,21 @@ from sysinv.objects import base
from sysinv.objects import utils
def get_owner(field, db_object):
owner = {}
"""Retrieves the owner details based on type and uuid."""
if db_object['type'] == constants.PTP_PARAMETER_OWNER_INSTANCE:
ptp_instances = getattr(db_object, 'ptp_instance')
if ptp_instances:
owner['name'] = ptp_instances[0].name
owner['type'] = ptp_instances[0].service
host = getattr(ptp_instances[0], 'host')
if host:
owner['hostname'] = host.hostname
def get_owners(field, db_object):
ptp_parameter_owners = db_object['ptp_parameter_owners']
if not ptp_parameter_owners:
return []
elif db_object['type'] == constants.PTP_PARAMETER_OWNER_INTERFACE:
ptp_interfaces = getattr(db_object, 'ptp_interface')
if ptp_interfaces:
interface = getattr(ptp_interfaces[0], 'interface')
if interface:
owner['name'] = interface.ifname
owner['type'] = interface.iftype
host = getattr(interface, 'host')
if host:
owner['hostname'] = host.hostname
owners = []
for owner in ptp_parameter_owners:
details = {}
details['uuid'] = owner.uuid
if owner.type == constants.PTP_PARAMETER_OWNER_INSTANCE:
details['owner'] = owner.name
details['type'] = owner.service
owners.append(details)
return owner
return owners
class PtpParameter(base.SysinvObject):
@ -49,14 +40,11 @@ class PtpParameter(base.SysinvObject):
'name': utils.str_or_none,
'value': utils.str_or_none,
'type': utils.str_or_none,
'foreign_uuid': utils.str_or_none,
'owner': dict
'owners': list
}
_foreign_fields = {
'owner': get_owner
'owners': get_owners
}
@base.remotable_classmethod

View File

@ -0,0 +1,29 @@
########################################################################
#
# 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 PtpParameterOwner(base.SysinvObject):
dbapi = db_api.get_instance()
fields = {
'id': int,
'uuid': utils.str_or_none,
'type': utils.str_or_none,
'capabilities': utils.dict_or_none
}
_foreign_fields = {}
@base.remotable_classmethod
def get_by_uuid(cls, context, uuid):
return cls.dbapi.ptp_paramowner_get(uuid)

View File

@ -0,0 +1,30 @@
########################################################################
#
# 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 PtpParameterOwnership(base.SysinvObject):
dbapi = db_api.get_instance()
fields = {
'id': int,
'uuid': utils.str_or_none,
'parameter_uuid': utils.str_or_none,
'owner_uuid': utils.str_or_none,
}
_foreign_fields = {}
@base.remotable_classmethod
def get_by_uuid(cls, context, uuid):
return cls.dbapi.ptp_paramownership_get(uuid)

View File

@ -195,7 +195,7 @@ class NetworkingPuppet(base.BasePuppet):
return {'platform::ptpinstance::enabled': ptp_enabled}
# Get the database entries for instances, interfaces and parameters
ptp_instances = self.dbapi.ptp_instances_get_by_ihost(host.uuid)
ptp_instances = self.dbapi.ptp_instances_get_list(host=host.uuid)
ptp_interfaces = self.dbapi.ptp_interfaces_get_by_host(host.uuid)
ptp_parameters_instance = self.dbapi.ptp_parameters_get_by_type(
constants.PTP_PARAMETER_OWNER_INSTANCE)

View File

@ -38,37 +38,22 @@ class BasePtpInstanceTestCase(base.FunctionalTest, dbbase.BaseHostTestCase):
return '%s/%s%s' % (self.HOST_PREFIX, host_uuid, self.API_PREFIX)
def get_post_object(self, name='test_instance',
service=constants.PTP_INSTANCE_TYPE_PTP4L,
host_id=None, host_uuid=None, hostname=None):
service=constants.PTP_INSTANCE_TYPE_PTP4L):
ptp_instance_db = dbutils.get_test_ptp_instance(name=name,
service=service,
host_id=host_id)
ptp_instance_db['host_uuid'] = host_uuid
ptp_instance_db['hostname'] = hostname
service=service)
return ptp_instance_db
class TestCreatePtpInstance(BasePtpInstanceTestCase):
name = constants.PTP_INSTANCE_DEFAULT_PTP4L
service = constants.PTP_INSTANCE_TYPE_PTP4L
host_id = None
host_uuid = None
hostname = None
def setUp(self):
super(TestCreatePtpInstance, self).setUp()
self.host_id = self.controller.id
self.host_uuid = self.controller.uuid
self.hostname = self.controller.hostname
dbutils.create_test_ptp_instance(name=self.name, service=self.service,
host_id=self.host_id)
dbutils.create_test_ptp_instance(name=self.name, service=self.service)
def _create_ptp_instance_success(self, name, service, host_id, host_uuid,
hostname):
ptp_instance_db = self.get_post_object(name=name, service=service,
host_id=host_id,
host_uuid=host_uuid,
hostname=hostname)
def _create_ptp_instance_success(self, name, service):
ptp_instance_db = self.get_post_object(name=name, service=service)
response = self.post_json(self.API_PREFIX, ptp_instance_db,
headers=self.API_HEADERS)
self.assertEqual('application/json', response.content_type)
@ -76,12 +61,9 @@ class TestCreatePtpInstance(BasePtpInstanceTestCase):
self.assertEqual(response.json[self.COMMON_FIELD],
ptp_instance_db[self.COMMON_FIELD])
def _create_ptp_instance_failed(self, name, service, host_id, host_uuid,
hostname, status_code, error_message):
ptp_instance_db = self.get_post_object(name=name, service=service,
host_id=host_id,
host_uuid=host_uuid,
hostname=hostname)
def _create_ptp_instance_failed(self, name, service,
status_code, error_message):
ptp_instance_db = self.get_post_object(name=name, service=service)
response = self.post_json(self.API_PREFIX, ptp_instance_db,
headers=self.API_HEADERS, expect_errors=True)
self.assertEqual('application/json', response.content_type)
@ -90,18 +72,12 @@ class TestCreatePtpInstance(BasePtpInstanceTestCase):
def test_create_ptp_instance_ok(self):
self._create_ptp_instance_success('test-instance',
constants.PTP_INSTANCE_TYPE_PTP4L,
host_id=self.controller.id,
host_uuid=self.controller.uuid,
hostname=self.controller.hostname)
constants.PTP_INSTANCE_TYPE_PTP4L)
def test_create_ptp_instance_invalid_service(self):
self._create_ptp_instance_failed(
'test-invalid',
'invalid',
host_id=self.controller.id,
host_uuid=self.controller.uuid,
hostname=self.controller.hostname,
status_code=http_client.BAD_REQUEST,
error_message='Invalid input for field/attribute service')
@ -111,23 +87,26 @@ class TestCreatePtpInstance(BasePtpInstanceTestCase):
self._create_ptp_instance_failed(
name=self.name,
service=self.service,
host_id=self.host_id,
host_uuid=self.host_uuid,
hostname=self.controller.hostname,
status_code=http_client.CONFLICT,
error_message=error_message)
def test_create_ptp_instance_invalid_host(self):
bad_uuid = 'f4c56ddf-aef3-46ed-b9aa-126a1faafd40'
error_message = '%s could not be found' % bad_uuid
self._create_ptp_instance_failed(
'test-invalid',
constants.PTP_INSTANCE_TYPE_PHC2SYS,
host_id=99,
host_uuid=bad_uuid,
hostname='badhost',
status_code=http_client.NOT_FOUND,
error_message=error_message)
class TestSetPtpInstance(BasePtpInstanceTestCase):
def setUp(self):
super(TestSetPtpInstance, self).setUp()
def test_set_ptp_instance_to_hosts(self):
# TODO
pass
class TestUnsetPtpInstance(BasePtpInstanceTestCase):
def setUp(self):
super(TestUnsetPtpInstance, self).setUp()
def test_unset_ptp_instance_from_hosts(self):
# TODO
pass
class TestGetPtpInstance(BasePtpInstanceTestCase):
@ -137,8 +116,7 @@ class TestGetPtpInstance(BasePtpInstanceTestCase):
def test_get_ptp_instance_found(self):
ptp_instance = dbutils.create_test_ptp_instance(
name=constants.PTP_INSTANCE_DEFAULT_PTP4L,
service=constants.PTP_INSTANCE_TYPE_PTP4L,
host_id=self.controller.id)
service=constants.PTP_INSTANCE_TYPE_PTP4L)
uuid = ptp_instance['uuid']
response = self.get_json(self.get_single_url(uuid))
self.assertIn(self.COMMON_FIELD, response)
@ -159,17 +137,15 @@ class TestListPtpInstance(BasePtpInstanceTestCase):
super(TestListPtpInstance, self).setUp()
self._create_test_ptp_instances()
def _create_test_ptp_instances(self, name_prefix='test', host_id=None):
def _create_test_ptp_instances(self, name_prefix='test'):
services = [constants.PTP_INSTANCE_TYPE_PTP4L,
constants.PTP_INSTANCE_TYPE_PHC2SYS,
constants.PTP_INSTANCE_TYPE_TS2PHC]
instances = []
if not host_id:
host_id = self.controller.id
for service in services:
name = '%s-%s' % (name_prefix, service)
instance = dbutils.create_test_ptp_instance(
name=name, service=service, host_id=host_id)
name=name, service=service)
instances.append(instance)
return instances
@ -183,11 +159,8 @@ class TestListPtpInstance(BasePtpInstanceTestCase):
self.assertEqual([], response[self.RESULT_KEY])
def test_list_ptp_instance_host(self):
self._create_test_ptp_instances(name_prefix='fake',
host_id=self.worker.id)
response = self.get_json(self.get_host_scoped_url(self.worker.uuid))
for result in response[self.RESULT_KEY]:
self.assertEqual(self.worker.uuid, result['host_uuid'])
# TODO
pass
class TestDeletePtpInstance(BasePtpInstanceTestCase):
@ -203,8 +176,7 @@ class TestDeletePtpInstance(BasePtpInstanceTestCase):
super(TestDeletePtpInstance, self).setUp()
self.ptp_instance = dbutils.create_test_ptp_instance(
name=constants.PTP_INSTANCE_DEFAULT_PTP4L,
service=constants.PTP_INSTANCE_TYPE_PTP4L,
host_id=self.controller.id)
service=constants.PTP_INSTANCE_TYPE_PTP4L)
self.uuid = self.ptp_instance['uuid']
def test_delete_ptp_instance_ok(self):
@ -220,12 +192,16 @@ class TestDeletePtpInstance(BasePtpInstanceTestCase):
self.assertEqual(response.status_code, http_client.NOT_FOUND)
self.assertIn(error_message, response.json['error_message'])
def test_delete_ptp_instance_with_host_failed(self):
# TODO
pass
def test_delete_ptp_instance_with_parameters_failed(self):
ptp_parameter = dbutils.create_test_ptp_parameter(
name='fake-param', value='fake-value',
type=constants.PTP_PARAMETER_OWNER_INSTANCE,
foreign_uuid=self.uuid)
self.assertEqual(self.uuid, ptp_parameter['foreign_uuid'])
name='fake-param', value='fake-value')
ptp_ownership = dbutils.create_test_ptp_ownership(
parameter_uuid=ptp_parameter['uuid'], owner_uuid=self.uuid)
self.assertEqual(self.uuid, ptp_ownership['owner_uuid'])
response = self.delete(self.get_single_url(self.uuid),
headers=self.API_HEADERS, expect_errors=True)

View File

@ -6,7 +6,6 @@
#
########################################################################
from oslo_utils import uuidutils
from six.moves import http_client
from sysinv.common import constants
from sysinv.tests.api import base
@ -25,21 +24,22 @@ class BasePtpInterfaceTestCase(base.FunctionalTest, dbbase.BaseHostTestCase):
RESULT_KEY = 'ptp_interfaces'
# Field that is known to exist for inputs and outputs
COMMON_FIELD = 'interface_uuid'
COMMON_FIELD = 'ptp_instance_uuid'
# Can perform API operations on thie object at a sublevel of host
HOST_PREFIX = '/ihosts'
# Attributes that should be populated by an API query
expected_api_fields = ['uuid', 'interface_id', 'ptp_instance_id']
# Attributes that should NOT be populated by an API query
hidden_api_fields = ['host_id']
def setUp(self):
super(BasePtpInterfaceTestCase, self).setUp()
self.controller = self._create_test_host(constants.CONTROLLER)
self.worker = self._create_test_host(constants.WORKER)
self.interface = dbutils.create_test_interface(
ifname='ptp0',
ifclass=constants.INTERFACE_CLASS_PLATFORM,
forihostid=self.controller.id,
ihost_uuid=self.controller.uuid)
self.instance = dbutils.create_test_ptp_instance(
name='testInstance',
service=constants.PTP_INSTANCE_TYPE_PTP4L)
def get_single_url(self, ptp_interface_uuid):
return '%s/%s' % (self.API_PREFIX, ptp_interface_uuid)
@ -53,51 +53,32 @@ class BasePtpInterfaceTestCase(base.FunctionalTest, dbbase.BaseHostTestCase):
self.API_PREFIX,
interface_uuid)
def get_post_object(self, interface_uuid=None, ptp_instance_uuid=None):
ptp_interface_db = {
'interface_uuid': interface_uuid,
'ptp_instance_uuid': ptp_instance_uuid
}
def get_post_object(self, ptp_instance_uuid):
ptp_interface_db = dbutils.get_test_ptp_interface(
ptp_instance_uuid=ptp_instance_uuid)
return ptp_interface_db
def assert_fields(self, api_object):
assert(uuidutils.is_uuid_like(api_object['uuid']))
for field in self.expected_api_fields:
self.assertIn(field, api_object)
for field in self.hidden_api_fields:
self.assertNotIn(field, api_object)
class TestCreatePtpInterface(BasePtpInterfaceTestCase):
def setUp(self):
super(TestCreatePtpInterface, self).setUp()
self.test_interface = dbutils.create_test_interface(
ifname='ptp0',
ifclass=constants.INTERFACE_CLASS_PLATFORM,
forihostid=self.controller.id,
ihost_uuid=self.controller.uuid)
self.test_instance = dbutils.create_test_ptp_instance(
name='testInstance',
service=constants.PTP_INSTANCE_TYPE_PTP4L,
host_id=self.controller.id)
def _create_ptp_interface_success(self, interface_uuid, ptp_instance_uuid):
ptp_interface_db = self.get_post_object(interface_uuid,
ptp_instance_uuid)
def _create_ptp_interface_success(self, ptp_instance_uuid):
ptp_interface_db = self.get_post_object(ptp_instance_uuid)
response = self.post_json(self.API_PREFIX, ptp_interface_db,
headers=self.API_HEADERS)
self.assertEqual('application/json', response.content_type)
self.assertEqual(response.status_code, http_client.OK)
"""
TODO: Check ptp_instance_uuid empty in the response
self.assertEqual(response.json[self.COMMON_FIELD],
ptp_interface_db[self.COMMON_FIELD])
"""
def _create_ptp_interface_failed(self, interface_uuid, ptp_instance_uuid,
def _create_ptp_interface_failed(self, ptp_instance_uuid,
status_code, error_message):
ptp_interface_db = self.get_post_object(interface_uuid,
ptp_instance_uuid)
ptp_interface_db = self.get_post_object(ptp_instance_uuid)
response = self.post_json(self.API_PREFIX, ptp_interface_db,
headers=self.API_HEADERS,
expect_errors=True)
@ -106,54 +87,40 @@ class TestCreatePtpInterface(BasePtpInterfaceTestCase):
self.assertIn(error_message, response.json['error_message'])
def test_create_ptp_interface_ok(self):
self._create_ptp_interface_success(self.test_interface.uuid,
self.test_instance.uuid)
def test_create_ptp_interface_invalid_interface(self):
self._create_ptp_interface_failed(
'32dbb999-6c10-448d-aeca-964c50af6384',
self.test_instance.uuid,
status_code=http_client.BAD_REQUEST,
error_message='No entry found for interface 32dbb999-6c10-448d-aeca-964c50af6384')
self._create_ptp_interface_success(self.instance.uuid)
def test_create_ptp_interface_invalid_instance(self):
self._create_ptp_interface_failed(
self.test_interface.uuid,
'32dbb999-6c10-448d-aeca-964c50af6384',
status_code=http_client.NOT_FOUND,
error_message='No PTP instance with id 32dbb999-6c10-448d-aeca-964c50af6384 found.')
def test_create_ptp_interface_duplicate(self):
self._create_ptp_interface_success(self.test_interface.uuid,
self.test_instance.uuid)
self._create_ptp_interface_failed(
interface_uuid=self.test_interface.uuid,
ptp_instance_uuid=self.test_instance.uuid,
status_code=http_client.INTERNAL_SERVER_ERROR,
error_message='')
class TestSetPtpInterface(BasePtpInterfaceTestCase):
def setUp(self):
super(TestSetPtpInterface, self).setUp()
def test_set_ptp_interface_to_interfaces(self):
# TODO
pass
class TestUnsetPtpInterface(BasePtpInterfaceTestCase):
def setUp(self):
super(TestUnsetPtpInterface, self).setUp()
def test_unset_ptp_interface_from_interfaces(self):
# TODO
pass
class TestGetPtpInterface(BasePtpInterfaceTestCase):
def setUp(self):
super(TestGetPtpInterface, self).setUp()
self.test_interface = dbutils.create_test_interface(
ifname='ptp0',
ifclass=constants.INTERFACE_CLASS_PLATFORM,
forihostid=self.controller.id,
ihost_uuid=self.controller.uuid)
self.test_instance = dbutils.create_test_ptp_instance(
name='testInstance',
service=constants.PTP_INSTANCE_TYPE_PTP4L,
host_id=self.controller.id)
self.test_ptp_interface = dbutils.create_test_ptp_interface(
interface_id=self.test_interface.id,
ptp_instance_id=self.test_instance.id)
ptp_instance_id=self.instance.id)
def test_get_ptp_interface_found(self):
response = self.get_json(
self.get_single_url(self.test_ptp_interface.uuid))
self.assertIn(self.COMMON_FIELD, response)
@ -161,7 +128,6 @@ class TestGetPtpInterface(BasePtpInterfaceTestCase):
def test_get_ptp_interface_not_found(self):
fake_uuid = 'f4c56ddf-aef3-46ed-b9aa-126a1faafd40'
error_message = 'No PTP interface with id %s found' % fake_uuid
response = self.get_json(self.get_single_url(fake_uuid),
expect_errors=True)
self.assertEqual('application/json', response.content_type)
@ -172,60 +138,28 @@ class TestGetPtpInterface(BasePtpInterfaceTestCase):
class TestListPtpInterface(BasePtpInterfaceTestCase):
def setUp(self):
super(TestListPtpInterface, self).setUp()
self.test_interface = dbutils.create_test_interface(
ifname='ptp0',
ifclass=constants.INTERFACE_CLASS_PLATFORM,
forihostid=self.worker.id,
ihost_uuid=self.worker.uuid)
self.dummy_interface = dbutils.create_test_interface(
ifname='ptp1',
ifclass=constants.INTERFACE_CLASS_PLATFORM,
forihostid=self.worker.id,
ihost_uuid=self.worker.uuid)
self.test_instance_ptp4l = dbutils.create_test_ptp_instance(
name='ptp4lInstance',
service=constants.PTP_INSTANCE_TYPE_PTP4L,
host_id=self.worker.id)
service=constants.PTP_INSTANCE_TYPE_PTP4L)
self.test_instance_phc2sys = dbutils.create_test_ptp_instance(
name='phc2sysInstance',
service='phc2sys',
host_id=self.worker.id)
service='phc2sys')
self.ptp4l_ptp_interface = dbutils.create_test_ptp_interface(
interface_id=self.test_interface.id,
ptp_instance_id=self.test_instance_ptp4l.id)
self.phc2sys_ptp_interface = dbutils.create_test_ptp_interface(
interface_id=self.test_interface.id,
ptp_instance_id=self.test_instance_phc2sys.id)
self.dummy_ptp_interface = dbutils.create_test_ptp_interface(
interface_id=self.dummy_interface.id,
ptp_instance_id=self.test_instance_ptp4l.id)
def test_list_ptp_interface_host(self):
response = self.get_json(self.get_host_scoped_url(self.worker.uuid))
for result in response[self.RESULT_KEY]:
self.assertEqual(self.worker.id, result['forihostid'])
if result['uuid'] == self.ptp4l_ptp_interface.uuid \
or result['uuid'] == self.dummy_interface.uuid:
self.assertEqual(self.test_instance_ptp4l.id,
result['ptp_instance_id'])
elif result['uuid'] == self.phc2sys_ptp_interface.uuid:
self.assertEqual(self.test_instance_phc2sys.id,
result['ptp_instance_id'])
# TODO
pass
def test_list_ptp_interface_interface(self):
response = self.get_json(self.get_host_scoped_url_interface(
self.worker.uuid, self.test_interface.uuid))
for result in response[self.RESULT_KEY]:
self.assertIn(self.COMMON_FIELD, result)
self.assertNotIn(self.dummy_interface.uuid, result)
# TODO
pass
def test_list_ptp_interface_empty(self):
response = self.get_json(self.get_host_scoped_url(self.controller.uuid))
self.assertEqual([], response[self.RESULT_KEY])
# TODO
pass
class TestDeletePtpInterface(BasePtpInterfaceTestCase):
@ -237,28 +171,14 @@ class TestDeletePtpInterface(BasePtpInterfaceTestCase):
def setUp(self):
super(TestDeletePtpInterface, self).setUp()
self.test_interface = dbutils.create_test_interface(
ifname='ptp0',
ifclass=constants.INTERFACE_CLASS_PLATFORM,
forihostid=self.worker.id,
ihost_uuid=self.worker.uuid)
self.test_instance_ptp4l = dbutils.create_test_ptp_instance(
name='ptp4lInstance',
service=constants.PTP_INSTANCE_TYPE_PTP4L,
host_id=self.worker.id)
self.test_ptp_interface = dbutils.create_test_ptp_interface(
interface_id=self.test_interface.id,
ptp_instance_id=self.test_instance_ptp4l.id)
ptp_instance_id=self.instance.id)
def test_delete_ptp_interface(self):
response = self.delete(
self.get_single_url(self.test_ptp_interface.uuid),
headers=self.API_HEADERS)
self.assertEqual(response.status_code, http_client.NO_CONTENT)
error_message = \
'No PTP interface with id %s found' % self.test_ptp_interface.uuid
response = self.get_json(
@ -268,14 +188,18 @@ class TestDeletePtpInterface(BasePtpInterfaceTestCase):
self.assertEqual(response.status_code, http_client.NOT_FOUND)
self.assertIn(error_message, response.json['error_message'])
def test_delete_ptp_interface_with_interface_failed(self):
# TODO
pass
def test_delete_ptp_interface_with_parameters_failed(self):
ptp_parameter = dbutils.create_test_ptp_parameter(
name='fake-param', value='fake-value',
type=constants.PTP_PARAMETER_OWNER_INTERFACE,
foreign_uuid=self.test_ptp_interface.uuid)
name='fake-param', value='fake-value')
ptp_ownership = dbutils.create_test_ptp_ownership(
parameter_uuid=ptp_parameter['uuid'],
owner_uuid=self.test_ptp_interface.uuid)
self.assertEqual(self.test_ptp_interface.uuid,
ptp_parameter['foreign_uuid'])
ptp_ownership['owner_uuid'])
response = self.delete(
self.get_single_url(self.test_ptp_interface.uuid),
headers=self.API_HEADERS, expect_errors=True)

View File

@ -15,13 +15,22 @@ class BasePtpParameterTestCase(base.FunctionalTest, dbbase.BaseHostTestCase):
API_HEADERS = {'User-Agent': 'sysinv-test'}
# Prefix for the URL
API_PREFIX = '/ptp_parameters'
PARAMETER_PREFIX = '/ptp_parameters'
# Python table key for the list of results
RESULT_KEY = 'ptp_parameters'
PARAMETER_KEY = 'ptp_parameters'
# Field that is known to exist for inputs and outputs
COMMON_FIELD = 'name'
PARAMETER_FIELD = 'name'
# Prefix for the URL
OWNERSHIP_PREFIX = '/ptp_parameter_ownerships'
# Python table key for the list of results
OWNERSHIP_KEY = 'ptp_parameter_ownerships'
# Field that is known to exist for inputs and outputs
OWNERSHIP_FIELD = 'owner_uuid'
# Can perform API operations on this object at a sublevel of PTP instances
PTP_INSTANCE_PREFIX = '/ptp_instances'
@ -32,64 +41,60 @@ class BasePtpParameterTestCase(base.FunctionalTest, dbbase.BaseHostTestCase):
def setUp(self):
super(BasePtpParameterTestCase, self).setUp()
self.controller = self._create_test_host(constants.CONTROLLER)
self.ptp_instances = self._create_test_ptp_instance(self.controller)
self.platform_interfaces = \
self._create_test_host_platform_interface(self.controller)
self.ptp_instances = self._create_test_ptp_instance()
self.ptp_interfaces = self._create_test_ptp_interface(
self.ptp_instances, self.platform_interfaces)
self.ptp_instances)
def get_single_url(self, ptp_parameter_uuid):
return '%s/%s' % (self.API_PREFIX, ptp_parameter_uuid)
def get_parameter_url(self, ptp_parameter_uuid):
return '%s/%s' % (self.PARAMETER_PREFIX, ptp_parameter_uuid)
def get_ownership_url(self, ptp_paramownership_uuid):
return '%s/%s' % (self.OWNERSHIP_PREFIX, ptp_paramownership_uuid)
def get_instance_scoped_url(self, ptp_instance_uuid):
return '%s/%s%s' % (self.PTP_INSTANCE_PREFIX, ptp_instance_uuid,
self.API_PREFIX)
self.PARAMETER_PREFIX)
def get_interface_scoped_url(self, interface_uuid):
return '%s/%s%s' % (self.INTERFACE_PREFIX, interface_uuid,
self.API_PREFIX)
self.PARAMETER_PREFIX)
def get_post_object(self, name='test_parameter', value='test_value',
type=None, foreign_uuid=None):
def get_post_parameter(self, name='test_parameter', value='test_value'):
return dbutils.get_test_ptp_parameter(name=name,
value=value,
type=type,
foreign_uuid=foreign_uuid)
value=value)
def get_post_ownership(self, parameter_uuid=None, owner_uuid=None):
return dbutils.get_test_ptp_ownership(parameter_uuid=parameter_uuid,
owner_uuid=owner_uuid)
class TestCreatePtpParameter(BasePtpParameterTestCase):
name = 'test-param'
value = 'test-value'
type = constants.PTP_PARAMETER_OWNER_INSTANCE
foreign_uuid = None
def setUp(self):
super(TestCreatePtpParameter, self).setUp()
self.foreign_uuid = self.ptp_instances[0].uuid
dbutils.create_test_ptp_parameter(name=self.name,
value=self.value,
type=self.type,
foreign_uuid=self.foreign_uuid)
ptp_parameter_db = dbutils.create_test_ptp_parameter(name=self.name,
value=self.value)
uuid = ptp_parameter_db['uuid']
response = self.get_json(self.get_parameter_url(uuid))
self.assertIn(self.PARAMETER_FIELD, response)
def _create_ptp_parameter_success(self, name, value, type, foreign_uuid):
ptp_parameter_db = self.get_post_object(name=name,
value=value,
type=type,
foreign_uuid=foreign_uuid)
response = self.post_json(self.API_PREFIX, ptp_parameter_db,
def _create_ptp_parameter_success(self, name, value):
ptp_parameter_db = self.get_post_parameter(name=name,
value=value)
response = self.post_json(self.PARAMETER_PREFIX, ptp_parameter_db,
headers=self.API_HEADERS)
self.assertEqual('application/json', response.content_type)
self.assertEqual(response.status_code, http_client.OK)
self.assertEqual(response.json[self.COMMON_FIELD],
ptp_parameter_db[self.COMMON_FIELD])
self.assertEqual(response.json[self.PARAMETER_FIELD],
ptp_parameter_db[self.PARAMETER_FIELD])
def _create_ptp_parameter_failed(self, name, value, type, foreign_uuid,
status_code, error_message):
ptp_parameter_db = self.get_post_object(name=name,
value=value,
type=type,
foreign_uuid=foreign_uuid)
response = self.post_json(self.API_PREFIX, ptp_parameter_db,
def _create_ptp_parameter_failed(self, name, value, status_code,
error_message):
ptp_parameter_db = self.get_post_parameter(name=name,
value=value)
response = self.post_json(self.PARAMETER_PREFIX, ptp_parameter_db,
headers=self.API_HEADERS, expect_errors=True)
self.assertEqual('application/json', response.content_type)
self.assertEqual(response.status_code, status_code)
@ -97,62 +102,217 @@ class TestCreatePtpParameter(BasePtpParameterTestCase):
def test_create_ptp_parameter_instance_ok(self):
self._create_ptp_parameter_success(
name='instance-param', value='instance-value',
type=constants.PTP_PARAMETER_OWNER_INSTANCE,
foreign_uuid=self.ptp_instances[0].uuid)
name='instance-param', value='instance-value')
def test_create_ptp_parameter_interface_ok(self):
self._create_ptp_parameter_success(
name='interface-param', value='interface-value',
type=constants.PTP_PARAMETER_OWNER_INTERFACE,
foreign_uuid=self.ptp_interfaces[0].uuid)
def test_create_ptp_parameter_invalid_type(self):
self._create_ptp_parameter_failed(
name='fake-param', value='fake-value',
type='invalid',
foreign_uuid=self.ptp_instances[0].uuid,
status_code=http_client.BAD_REQUEST,
error_message='Invalid input for field/attribute type')
def test_create_ptp_parameter_invalid_uuid(self):
bad_uuid = 'f4c56ddf-aef3-46ed-b9aa-126a1faafd40'
error_message = 'No foreign object found with id %s' % bad_uuid
self._create_ptp_parameter_failed(
name='fake-param', value='fake-value',
type=constants.PTP_PARAMETER_OWNER_INSTANCE,
foreign_uuid=bad_uuid,
status_code=http_client.BAD_REQUEST,
error_message=error_message)
name='interface-param', value='interface-value')
def test_create_ptp_parameter_duplicate(self):
self._create_ptp_parameter_failed(
name=self.name,
value='another-value',
type=constants.PTP_PARAMETER_OWNER_INSTANCE,
foreign_uuid=self.foreign_uuid,
value=self.value,
status_code=http_client.CONFLICT,
error_message='already exists')
class TestSetPtpParameter(BasePtpParameterTestCase):
name = 'test-param'
value = 'test-value'
parameter_uuid = None
owner_uuid = None
def setUp(self):
super(TestSetPtpParameter, self).setUp()
self.owner_uuid = self.ptp_instances[0].uuid
ptp_parameter_db = dbutils.create_test_ptp_parameter(name=self.name,
value=self.value)
self.parameter_uuid = ptp_parameter_db['uuid']
response = self.get_json(self.get_parameter_url(self.parameter_uuid))
self.assertIn(self.PARAMETER_FIELD, response)
ptp_ownership_db = dbutils.create_test_ptp_ownership(
parameter_uuid=self.parameter_uuid,
owner_uuid=self.owner_uuid)
ownership_uuid = ptp_ownership_db['uuid']
response = self.get_json(self.get_ownership_url(ownership_uuid))
self.assertIn(self.OWNERSHIP_FIELD, response)
def _set_ptp_parameter(self, name, value):
ptp_parameter_db = dbutils.create_test_ptp_parameter(name=name,
value=value)
return ptp_parameter_db['uuid']
def _set_ptp_ownership_success(self, name, value, owner_uuid):
parameter_uuid = self._set_ptp_parameter(name, value)
ptp_ownership_db = self.get_post_ownership(
parameter_uuid=parameter_uuid,
owner_uuid=owner_uuid)
response = self.post_json(self.OWNERSHIP_PREFIX, ptp_ownership_db,
headers=self.API_HEADERS)
self.assertEqual('application/json', response.content_type)
self.assertEqual(response.status_code, http_client.OK)
self.assertEqual(response.json[self.OWNERSHIP_FIELD],
ptp_ownership_db[self.OWNERSHIP_FIELD])
def _set_ptp_ownership_failed(self, name, value, owner_uuid,
status_code, error_message):
parameter_uuid = self._set_ptp_parameter(name, value)
ptp_ownership_db = self.get_post_ownership(
parameter_uuid=parameter_uuid,
owner_uuid=owner_uuid)
response = self.post_json(self.OWNERSHIP_PREFIX, ptp_ownership_db,
headers=self.API_HEADERS, expect_errors=True)
self.assertEqual('application/json', response.content_type)
self.assertEqual(response.status_code, status_code)
self.assertIn(error_message, response.json['error_message'])
def test_set_ptp_parameter_instance_ok(self):
self._set_ptp_ownership_success(
name='instance-param', value='instance-value',
owner_uuid=self.ptp_instances[0].uuid)
def test_set_ptp_parameter_interface_ok(self):
self._set_ptp_ownership_success(
name='interface-param', value='interface-value',
owner_uuid=self.ptp_interfaces[0].uuid)
def test_set_ptp_parameter_duplicate(self):
ptp_ownership_db = self.get_post_ownership(
parameter_uuid=self.parameter_uuid,
owner_uuid=self.owner_uuid)
response = self.post_json(self.OWNERSHIP_PREFIX, ptp_ownership_db,
headers=self.API_HEADERS, expect_errors=True)
self.assertEqual('application/json', response.content_type)
self.assertEqual(response.status_code, http_client.CONFLICT)
self.assertIn('already a PTP parameter',
response.json['error_message'])
def test_set_ptp_parameter_invalid_param(self):
bad_uuid = 'f4c56ddf-aef3-46ed-b9aa-126a1faafd40'
error_message = 'No PTP parameter object found with id %s' % bad_uuid
ptp_ownership_db = self.get_post_ownership(
parameter_uuid=bad_uuid,
owner_uuid=self.owner_uuid)
response = self.post_json(self.OWNERSHIP_PREFIX, ptp_ownership_db,
headers=self.API_HEADERS, expect_errors=True)
self.assertEqual('application/json', response.content_type)
self.assertEqual(response.status_code, http_client.BAD_REQUEST)
self.assertIn(error_message, response.json['error_message'])
def test_set_ptp_parameter_invalid_owner_uuid(self):
bad_uuid = 'f4c56ddf-aef3-46ed-b9aa-126a1faafd40'
error_message = 'No PTP parameter owner found with id %s' % bad_uuid
self._set_ptp_ownership_failed(
name='fake-param', value='fake-value',
owner_uuid=bad_uuid,
status_code=http_client.BAD_REQUEST,
error_message=error_message)
class TestUnsetPtpParameter(BasePtpParameterTestCase):
def setUp(self):
super(TestUnsetPtpParameter, self).setUp()
def test_unset_ptp_parameter_instance(self):
owner_uuid = self.ptp_instances[0].uuid
ptp_parameter = dbutils.create_test_ptp_parameter(
name='instance-param', value='instance-value')
ptp_ownership = dbutils.create_test_ptp_ownership(
parameter_uuid=ptp_parameter['uuid'],
owner_uuid=owner_uuid)
uuid = ptp_ownership['uuid']
response = self.delete(self.get_ownership_url(uuid),
headers=self.API_HEADERS)
self.assertEqual(response.status_code, http_client.NO_CONTENT)
# Double check the ownership was removed
error_message = 'No PTP parameter ownership with id %s found' % uuid
response = self.get_json(self.get_ownership_url(uuid),
expect_errors=True)
self.assertEqual('application/json', response.content_type)
self.assertEqual(response.status_code, http_client.NOT_FOUND)
self.assertIn(error_message, response.json['error_message'])
response = self.get_json(self.get_instance_scoped_url(owner_uuid))
self.assertEqual([], response[self.PARAMETER_KEY])
def test_unset_ptp_parameter_interface(self):
owner_uuid = self.ptp_interfaces[0].uuid
ptp_parameter = dbutils.create_test_ptp_parameter(
name='interface-param', value='interface-value')
ptp_ownership = dbutils.create_test_ptp_ownership(
parameter_uuid=ptp_parameter['uuid'],
owner_uuid=owner_uuid)
uuid = ptp_ownership['uuid']
response = self.delete(self.get_ownership_url(uuid),
headers=self.API_HEADERS)
self.assertEqual(response.status_code, http_client.NO_CONTENT)
# Double check the ownership was removed
error_message = 'No PTP parameter ownership with id %s found' % uuid
response = self.get_json(self.get_ownership_url(uuid),
expect_errors=True)
self.assertEqual('application/json', response.content_type)
self.assertEqual(response.status_code, http_client.NOT_FOUND)
self.assertIn(error_message, response.json['error_message'])
response = self.get_json(self.get_interface_scoped_url(owner_uuid))
self.assertEqual([], response[self.PARAMETER_KEY])
class TestGetPtpParameter(BasePtpParameterTestCase):
name = 'test-param'
value = 'test-value'
type = constants.PTP_PARAMETER_OWNER_INSTANCE
parameter_uuid = None
owner_uuid = None
def setUp(self):
super(TestGetPtpParameter, self).setUp()
self.owner_uuid = self.ptp_instances[0].uuid
ptp_parameter_db = dbutils.create_test_ptp_parameter(name=self.name,
value=self.value)
self.parameter_uuid = ptp_parameter_db['uuid']
response = self.get_json(self.get_parameter_url(self.parameter_uuid))
self.assertIn(self.PARAMETER_FIELD, response)
def test_get_ptp_parameter_found(self):
ptp_parameter = dbutils.create_test_ptp_parameter(
name='fake-param', value='fake-value',
type=constants.PTP_PARAMETER_OWNER_INSTANCE,
foreign_uuid=self.ptp_instances[0].uuid)
name='fake-param', value='fake-value')
uuid = ptp_parameter['uuid']
response = self.get_json(self.get_single_url(uuid))
self.assertIn(self.COMMON_FIELD, response)
response = self.get_json(self.get_parameter_url(uuid))
self.assertIn(self.PARAMETER_FIELD, response)
def test_get_ptp_parameter_not_found(self):
fake_uuid = 'f4c56ddf-aef3-46ed-b9aa-126a1faafd40'
error_message = 'No PTP parameter with id %s found' % fake_uuid
response = self.get_json(self.get_single_url(fake_uuid),
response = self.get_json(self.get_parameter_url(fake_uuid),
expect_errors=True)
self.assertEqual('application/json', response.content_type)
self.assertEqual(response.status_code, http_client.NOT_FOUND)
self.assertIn(error_message, response.json['error_message'])
def test_get_ptp_parameter_owner_found(self):
ptp_ownership = dbutils.create_test_ptp_ownership(
parameter_uuid=self.parameter_uuid,
owner_uuid=self.owner_uuid)
uuid = ptp_ownership['uuid']
response = self.get_json(self.get_ownership_url(uuid))
self.assertIn(self.OWNERSHIP_FIELD, response)
def test_get_ptp_parameter_owner_not_found(self):
fake_uuid = 'f4c56ddf-aef3-46ed-b9aa-126a1faafd40'
error_message = \
'No PTP parameter ownership with id %s found' % fake_uuid
response = self.get_json(self.get_ownership_url(fake_uuid),
expect_errors=True)
self.assertEqual('application/json', response.content_type)
self.assertEqual(response.status_code, http_client.NOT_FOUND)
@ -163,84 +323,62 @@ class TestListPtpParameter(BasePtpParameterTestCase):
def setUp(self):
super(TestListPtpParameter, self).setUp()
self._create_test_ptp_parameters(
type=constants.PTP_PARAMETER_OWNER_INSTANCE,
prefix='ptp')
prefix='ptp',
type=constants.PTP_PARAMETER_OWNER_INSTANCE)
self._create_test_ptp_parameters(
type=constants.PTP_PARAMETER_OWNER_INTERFACE,
prefix='iface')
prefix='iface',
type=constants.PTP_PARAMETER_OWNER_INTERFACE)
def _create_test_ptp_parameters(self, type, prefix='test',
foreign_uuid=None):
def _create_test_ptp_parameters(self, prefix='test',
owner_uuid=None, type=None):
parameters = []
ownerships = []
if not foreign_uuid:
if not owner_uuid:
if type == constants.PTP_PARAMETER_OWNER_INSTANCE:
foreign_uuid = self.ptp_instances[0].uuid
owner_uuid = self.ptp_instances[0].uuid
elif type == constants.PTP_PARAMETER_OWNER_INTERFACE:
foreign_uuid = self.ptp_interfaces[0].uuid
owner_uuid = self.ptp_interfaces[0].uuid
else:
return parameters
return parameters, ownerships
for i in range(2):
name = '%s-name%s' % (prefix, i)
value = '%s-value%s' % (prefix, i)
parameter = dbutils.create_test_ptp_parameter(
name=name, value=value, type=type, foreign_uuid=foreign_uuid)
parameter = dbutils.create_test_ptp_parameter(name=name,
value=value)
parameters.append(parameter)
return parameters
ownership = dbutils.create_test_ptp_ownership(
parameter_uuid=parameter['uuid'],
owner_uuid=owner_uuid)
ownerships.append(ownership)
return parameters, ownerships
def test_list_ptp_parameter_all(self):
response = self.get_json(self.API_PREFIX)
for result in response[self.RESULT_KEY]:
self.assertIn(self.COMMON_FIELD, result)
response = self.get_json(self.PARAMETER_PREFIX)
for result in response[self.PARAMETER_KEY]:
self.assertIn(self.PARAMETER_FIELD, result)
def test_list_ptp_parameter_empty(self):
fake_uuid = 'f4c56ddf-aef3-46ed-b9aa-126a1faafd40'
response = self.get_json(self.get_instance_scoped_url(fake_uuid))
self.assertEqual([], response[self.RESULT_KEY])
def test_list_ptp_parameter_by_type(self):
self._create_test_ptp_parameters(
constants.PTP_PARAMETER_OWNER_INSTANCE,
foreign_uuid=self.ptp_instances[1].uuid)
"""
TODO: needs investigation of the reason to get this:
webtest.app.AppError: Bad response: 400 Bad Request (not 200 OK or 3xx
redirect for http://
localhost/v1/ptp_parameters?q.field=type&q.value=ptp-instance&q.op=eq)
'{"error_message": "{\\"debuginfo\\": null, \\"faultcode\\":
\\"Client\\", \\"faultstring\\": \\"Unknown argument: \\\\\\"q.field,
q.value, q.op\\\\\\"\\"}"}'
query = [{
'field': 'type',
'value': constants.PTP_PARAMETER_OWNER_INSTANCE,
'op': 'eq'
}]
response = self.get_json(self.API_PREFIX, q=query)
for result in response[self.RESULT_KEY]:
self.assertEqual(constants.PTP_PARAMETER_OWNER_INSTANCE,
result['type'])
"""
self.assertEqual([], response[self.PARAMETER_KEY])
def test_list_ptp_parameter_by_instance(self):
self._create_test_ptp_parameters(
constants.PTP_PARAMETER_OWNER_INSTANCE,
foreign_uuid=self.ptp_instances[1].uuid)
response = self.get_json(self.get_instance_scoped_url(
self.ptp_instances[1].uuid))
for result in response[self.RESULT_KEY]:
self.assertEqual(self.ptp_instances[1].uuid,
result['foreign_uuid'])
uuid = self.ptp_instances[1].uuid
self._create_test_ptp_parameters(owner_uuid=uuid)
response = self.get_json(self.get_instance_scoped_url(uuid))
for result in response[self.PARAMETER_KEY]:
self.assertIn(uuid, str(result['owners']))
def test_list_ptp_parameter_by_interface(self):
self._create_test_ptp_parameters(
constants.PTP_PARAMETER_OWNER_INTERFACE,
foreign_uuid=self.ptp_interfaces[1].uuid)
response = self.get_json(self.get_interface_scoped_url(
self.ptp_interfaces[1].uuid))
for result in response[self.RESULT_KEY]:
self.assertEqual(self.ptp_interfaces[1].uuid,
result['foreign_uuid'])
uuid = self.ptp_interfaces[1].uuid
self._create_test_ptp_parameters(owner_uuid=uuid)
response = self.get_json(self.get_interface_scoped_url(uuid))
for result in response[self.PARAMETER_KEY]:
self.assertIn(uuid, str(result['owners']))
class TestUpdatePtpParameter(BasePtpParameterTestCase):
@ -249,12 +387,10 @@ class TestUpdatePtpParameter(BasePtpParameterTestCase):
def test_update_ptp_parameter(self):
ptp_parameter = dbutils.create_test_ptp_parameter(
name='fake-param', value='fake-value',
type=constants.PTP_PARAMETER_OWNER_INSTANCE,
foreign_uuid=self.ptp_instances[0].uuid)
name='fake-param', value='fake-value')
uuid = ptp_parameter['uuid']
response = self.patch_json(self.get_single_url(uuid),
response = self.patch_json(self.get_parameter_url(uuid),
[{'path': '/value',
'value': 'changed-value',
'op': 'replace'}],
@ -263,7 +399,7 @@ class TestUpdatePtpParameter(BasePtpParameterTestCase):
self.assertEqual(response.status_code, http_client.OK)
# Check the parameter was indeed updated
response = self.get_json(self.get_single_url(uuid))
response = self.get_json(self.get_parameter_url(uuid))
self.assertEqual(response['value'], 'changed-value')
@ -277,21 +413,32 @@ class TestDeletePtpParameter(BasePtpParameterTestCase):
def setUp(self):
super(TestDeletePtpParameter, self).setUp()
def test_delete_ptp_parameter(self):
def test_delete_ptp_parameter_ok(self):
ptp_parameter = dbutils.create_test_ptp_parameter(
name='fake-param', value='fake-value',
type=constants.PTP_PARAMETER_OWNER_INSTANCE,
foreign_uuid=self.ptp_instances[0].uuid)
name='fake-param', value='fake-value')
uuid = ptp_parameter['uuid']
response = self.delete(self.get_single_url(uuid),
response = self.delete(self.get_parameter_url(uuid),
headers=self.API_HEADERS)
self.assertEqual(response.status_code, http_client.NO_CONTENT)
# Check the instance was indeed removed
# Check the parameter was indeed removed
error_message = 'No PTP parameter with id %s found' % uuid
response = self.get_json(self.get_single_url(uuid),
response = self.get_json(self.get_parameter_url(uuid),
expect_errors=True)
self.assertEqual('application/json', response.content_type)
self.assertEqual(response.status_code, http_client.NOT_FOUND)
self.assertIn(error_message, response.json['error_message'])
def test_delete_ptp_parameter_with_owner_failed(self):
ptp_parameter = dbutils.create_test_ptp_parameter(
name='fake-param', value='fake-value')
uuid = ptp_parameter['uuid']
owner_uuid = self.ptp_instances[0].uuid
dbutils.create_test_ptp_ownership(parameter_uuid=uuid,
owner_uuid=owner_uuid)
response = self.delete(self.get_parameter_url(uuid),
headers=self.API_HEADERS, expect_errors=True)
self.assertEqual('application/json', response.content_type)
self.assertEqual(response.status_code, http_client.BAD_REQUEST)
self.assertIn('still associated with ', response.json['error_message'])

View File

@ -447,7 +447,7 @@ class BaseHostTestCase(BaseSystemTestCase):
index = index + 1
return ifaces
def _create_test_ptp_instance(self, host):
def _create_test_ptp_instance(self):
services = [constants.PTP_INSTANCE_TYPE_PTP4L,
constants.PTP_INSTANCE_TYPE_PHC2SYS]
names = [constants.PTP_INSTANCE_DEFAULT_PTP4L,
@ -455,18 +455,16 @@ class BaseHostTestCase(BaseSystemTestCase):
ptp_instances = []
for svc, nm in zip(services, names):
instance = dbutils.create_test_ptp_instance(
name=nm, service=svc, host_id=host['id'])
name=nm, service=svc)
ptp_instances.append(instance)
return ptp_instances
def _create_test_ptp_interface(self,
ptp_instances,
platform_interfaces):
ptp_instances):
ptp_interfaces = []
for ptp_instance in ptp_instances:
ptp_interface = dbutils.create_test_ptp_interface(
ptp_instance_id=ptp_instance['id'],
interface_id=platform_interfaces[0]['id'])
ptp_instance_id=ptp_instance['id'])
ptp_interfaces.append(ptp_interface)
return ptp_interfaces

View File

@ -1988,18 +1988,46 @@ class TestMigrations(BaseMigrationTestCase, WalkVersionsMixin):
getattr(sqlalchemy.types, coltype)))
def _check_120(self, engine, data):
ptp_instances = db_utils.get_table(engine, 'ptp_instances')
ptp_instance_columns = {
ptp_parameters = db_utils.get_table(engine, 'ptp_parameters')
ptp_parameters_columns = {
'created_at': 'DateTime',
'updated_at': 'DateTime',
'deleted_at': 'DateTime',
'id': 'Integer',
'uuid': 'String',
'name': 'String',
'service': 'String',
'host_id': 'Integer',
'value': 'String'
}
for column, column_type in ptp_parameters_columns.items():
self.assertTrue(
isinstance(ptp_parameters.c[column].type,
getattr(sqlalchemy.types, column_type)))
ptp_parameter_owners = db_utils.get_table(engine,
'ptp_parameter_owners')
ptp_parameter_owner_columns = {
'created_at': 'DateTime',
'updated_at': 'DateTime',
'deleted_at': 'DateTime',
'id': 'Integer',
'uuid': 'String',
'type': 'String',
'capabilities': 'Text'
}
for column, column_type in ptp_parameter_owner_columns.items():
self.assertTrue(
isinstance(ptp_parameter_owners.c[column].type,
getattr(sqlalchemy.types, column_type)))
ptp_instances = db_utils.get_table(engine, 'ptp_instances')
ptp_instance_columns = {
'created_at': 'DateTime',
'updated_at': 'DateTime',
'deleted_at': 'DateTime',
'id': 'Integer',
'name': 'String',
'service': 'String'
}
for column, column_type in ptp_instance_columns.items():
self.assertTrue(
isinstance(ptp_instances.c[column].type,
@ -2011,29 +2039,25 @@ class TestMigrations(BaseMigrationTestCase, WalkVersionsMixin):
'updated_at': 'DateTime',
'deleted_at': 'DateTime',
'id': 'Integer',
'uuid': 'String',
'interface_id': 'Integer',
'ptp_instance_id': 'Integer',
'capabilities': 'Text'
'ptp_instance_id': 'Integer'
}
for column, column_type in ptp_interface_columns.items():
self.assertTrue(
isinstance(ptp_interfaces.c[column].type,
getattr(sqlalchemy.types, column_type)))
ptp_parameters = db_utils.get_table(engine, 'ptp_parameters')
ptp_parameters_columns = {
ptp_parameter_ownerships = db_utils.get_table(
engine, 'ptp_parameter_ownerships')
ptp_parameter_ownership_columns = {
'created_at': 'DateTime',
'updated_at': 'DateTime',
'deleted_at': 'DateTime',
'id': 'Integer',
'uuid': 'String',
'name': 'String',
'value': 'String',
'type': 'String',
'foreign_uuid': 'String',
'parameter_uuid': 'String',
'owner_uuid': 'String'
}
for column, column_type in ptp_parameters_columns.items():
for column, column_type in ptp_parameter_ownership_columns.items():
self.assertTrue(
isinstance(ptp_parameters.c[column].type,
isinstance(ptp_parameter_ownerships.c[column].type,
getattr(sqlalchemy.types, column_type)))

View File

@ -539,22 +539,16 @@ def create_test_ptp(**kw):
# Utility functions to create a PTP instance for testing
def get_test_ptp_instance(**kw):
instance = {
'id': kw.get('id'),
'uuid': kw.get('uuid'),
'name': kw.get('name', None),
'service': kw.get('service', constants.PTP_INSTANCE_TYPE_PTP4L),
'host_id': kw.get('host_id', None)
# TODO: check why this is needed for this specific child class/table
'type': kw.get('type', constants.PTP_PARAMETER_OWNER_INSTANCE),
'name': kw.get('name'),
'service': kw.get('service', constants.PTP_INSTANCE_TYPE_PTP4L)
}
return instance
def create_test_ptp_instance(**kw):
instance = get_test_ptp_instance(**kw)
# Let DB generate ID if isn't specified
if 'id' not in kw:
del instance['id']
if 'uuid' in kw:
del instance['uuid']
dbapi = db_api.get_instance()
return dbapi.ptp_instance_create(instance)
@ -562,17 +556,14 @@ def create_test_ptp_instance(**kw):
# Create test ptp_interface object
def get_test_ptp_interface(**kw):
ptp_interface = {
'uuid': kw.get('uuid'),
'interface_id': kw.get('interface_id'),
'ptp_instance_id': kw.get('ptp_instance_id')
'ptp_instance_id': kw.get('ptp_instance_id'),
'ptp_instance_uuid': kw.get('ptp_instance_uuid', None)
}
return ptp_interface
def create_test_ptp_interface(**kw):
ptp_interface = get_test_ptp_interface(**kw)
if 'uuid' in kw:
del ptp_interface['uuid']
dbapi = db_api.get_instance()
return dbapi.ptp_interface_create(ptp_interface)
@ -580,27 +571,32 @@ def create_test_ptp_interface(**kw):
# Utility functions to create a PTP parameter for testing
def get_test_ptp_parameter(**kw):
parameter = {
'id': kw.get('id'),
'uuid': kw.get('uuid'),
'name': kw.get('name', None),
'value': kw.get('value', None),
'type': kw.get('type', None),
'foreign_uuid': kw.get('foreign_uuid', None)
'name': kw.get('name'),
'value': kw.get('value', None)
}
return parameter
def create_test_ptp_parameter(**kw):
parameter = get_test_ptp_parameter(**kw)
# Let DB generate ID if isn't specified
if 'id' not in kw:
del parameter['id']
if 'uuid' in kw:
del parameter['uuid']
dbapi = db_api.get_instance()
return dbapi.ptp_parameter_create(parameter)
def get_test_ptp_ownership(**kw):
ownership = {
'parameter_uuid': kw.get('parameter_uuid', None),
'owner_uuid': kw.get('owner_uuid', None)
}
return ownership
def create_test_ptp_ownership(**kw):
ownership = get_test_ptp_ownership(**kw)
dbapi = db_api.get_instance()
return dbapi.ptp_parameter_set_owner(ownership)
# Create test dns object
def get_test_dns(**kw):
dns = {