[PTP dual NIC config] Changes from new data model

Because of redesign of PTP data model done in:
https://review.opendev.org/c/starlingx/config/+/819391 and extended by
https://review.opendev.org/c/starlingx/config/+/820519 and
https://review.opendev.org/c/starlingx/config/+/820961
the API and related code had to be changed in order to support the
new relationships among tables, the updated workflow of configuration
and so on.
Some unnecessary code was removed for bridge tables that don't need it.

Test Plan:

PASS: New and updated test cases for the PTP configuration workflow.
PASS: Fresh install with commands being executed to populate tables.

Regression:

PASS: All unchanged test cases related to PTP.

Story: 2009248
Task: 44208
Signed-off-by: Douglas Henrique Koerich <douglashenrique.koerich@windriver.com>
Change-Id: Ib1fa0a044bfc1a4573084f32d8993f4d4cc2539c
This commit is contained in:
Douglas Henrique Koerich 2021-12-10 10:10:21 -03:00
parent 01a275ae60
commit 157b4ce08f
38 changed files with 1391 additions and 1937 deletions

View File

@ -70,11 +70,8 @@ from cgtsclient.v1 import pci_device
from cgtsclient.v1 import port
from cgtsclient.v1 import ptp
from cgtsclient.v1 import ptp_instance
from cgtsclient.v1 import ptp_instance_map
from cgtsclient.v1 import ptp_interface
from cgtsclient.v1 import ptp_interface_map
from cgtsclient.v1 import ptp_parameter
from cgtsclient.v1 import ptp_paramownership
from cgtsclient.v1 import registry_image
from cgtsclient.v1 import remotelogging
from cgtsclient.v1 import restore
@ -125,12 +122,8 @@ class Client(http.HTTPClient):
self.intp = intp.intpManager(self)
self.ptp = ptp.ptpManager(self)
self.ptp_instance = ptp_instance.PtpInstanceManager(self)
self.ptp_instance_map = ptp_instance_map.PtpInstanceMapManager(self)
self.ptp_interface = ptp_interface.PtpInterfaceManager(self)
self.ptp_interface_map = ptp_interface_map.PtpInterfaceMapManager(self)
self.ptp_parameter = ptp_parameter.PtpParameterManager(self)
self.ptp_paramownership = \
ptp_paramownership.PtpParameterOwnershipManager(self)
self.iextoam = iextoam.iextoamManager(self)
self.controller_fs = controller_fs.ControllerFsManager(self)
self.storage_backend = storage_backend.StorageBackendManager(self)

View File

@ -50,13 +50,8 @@ 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 update(self, ptp_instance_id, patch):
return self._update(self._path(ptp_instance_id), patch)
def delete(self, ptp_instance_id):
return self._delete(self._path(ptp_instance_id))
@ -72,7 +67,7 @@ def _find_ptp_instance(cc, key):
return instance
else:
ptp_instances = cc.ptp_instance.list()
for instance in ptp_instances[:]:
for instance in ptp_instances:
if instance.name == key:
return instance
else:

View File

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

View File

@ -13,14 +13,21 @@ from cgtsclient.v1 import ptp_instance as ptp_instance_utils
def _print_ptp_instance_show(ptp_instance_obj):
fields = ['uuid',
'name',
'service',
fields = ['uuid', 'name', 'service', 'hostnames', 'parameters',
'created_at']
data = [(f, getattr(ptp_instance_obj, f, '')) for f in fields]
utils.print_tuple_list(data)
@utils.arg('nameoruuid',
metavar='<name or UUID>',
help="Name or UUID of PTP instance")
def do_ptp_instance_show(cc, args):
"""Show PTP instance attributes."""
ptp_instance = ptp_instance_utils._find_ptp_instance(cc, args.nameoruuid)
_print_ptp_instance_show(ptp_instance)
def _print_ptp_instance_list(ptp_instance_list):
field_labels = ['uuid', 'name', 'service']
fields = ['uuid', 'name', 'service']
@ -33,25 +40,6 @@ def do_ptp_instance_list(cc, args):
_print_ptp_instance_list(ptp_instances)
@utils.arg('hostnameorid',
metavar='<hostname or id>',
help="Name or ID of host")
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)
_print_ptp_instance_list(ptp_instances)
@utils.arg('nameoruuid',
metavar='<name or UUID>',
help="Name or UUID of PTP instance")
def do_ptp_instance_show(cc, args):
"""Show PTP instance attributes."""
ptp_instance = ptp_instance_utils._find_ptp_instance(cc, args.nameoruuid)
_print_ptp_instance_show(ptp_instance)
@utils.arg('name',
metavar='<name>',
help="Name of PTP instance [REQUIRED]")
@ -89,24 +77,87 @@ def do_ptp_instance_delete(cc, args):
print('Deleted PTP instance: %s' % uuid)
@utils.arg('hostnameorid',
metavar='<hostname or id>',
help="Name or ID of host [REQUIRED]")
def _ptp_instance_parameter_op(cc, op, ptp_instance_uuid, data):
patch = []
for (_k, v) in data.items():
for uuids in v:
for uuid in uuids:
if not utils.is_uuid_like(uuid):
raise exc.CommandError("Invalid UUID '%s'" % uuid)
patch.append({'op': op,
'path': '/ptp_parameters/-',
'value': uuid})
ptp_instance = cc.ptp_instance.update(ptp_instance_uuid, patch)
_print_ptp_instance_show(ptp_instance)
@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)
help="Name or UUID of PTP instance")
@utils.arg('paramuuid',
metavar='<parameter UUID>',
nargs='+',
action='append',
default=[],
help="UUID of PTP parameter")
def do_ptp_instance_parameter_add(cc, args):
"""Add parameter(s) to a PTP instance."""
if len(args.paramuuid) == 0:
raise exc.CommandError('Missing PTP parameter UUID')
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))
field_list = ['paramuuid']
data = dict((k, v) for (k, v) in vars(args).items()
if k in field_list and not (v is None))
_ptp_instance_parameter_op(cc, op='add',
ptp_instance_uuid=ptp_instance.uuid, data=data)
@utils.arg('nameoruuid',
metavar='<name or UUID>',
help="Name or UUID of PTP instance")
@utils.arg('paramuuid',
metavar='<parameter UUID>',
nargs='+',
action='append',
default=[],
help="UUID of PTP parameter")
def do_ptp_instance_parameter_delete(cc, args):
"""Delete parameter(s) from a PTP instance."""
if len(args.paramuuid) == 0:
raise exc.CommandError('Missing PTP parameter UUID')
ptp_instance = ptp_instance_utils._find_ptp_instance(cc, args.nameoruuid)
field_list = ['paramuuid']
data = dict((k, v) for (k, v) in vars(args).items()
if k in field_list and not (v is None))
_ptp_instance_parameter_op(cc, op='remove',
ptp_instance_uuid=ptp_instance.uuid, data=data)
@utils.arg('hostnameorid',
metavar='<hostname or id>',
help="Name or ID of host")
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)
_print_ptp_instance_list(ptp_instances)
def _host_ptp_instance_op(cc, op, uuid, instance):
ptp_instance = ptp_instance_utils._find_ptp_instance(cc,
instance)
ptp_instance_id = ptp_instance.id
patch = [{'op': op, 'path': '/ptp_instances/-', 'value': ptp_instance_id}]
cc.ihost.update(uuid, patch)
ptp_instances = cc.ptp_instance.list_by_host(uuid)
_print_ptp_instance_list(ptp_instances)
@utils.arg('hostnameorid',
@ -115,15 +166,21 @@ def do_host_ptp_instance_add(cc, args):
@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."""
def do_host_ptp_instance_assign(cc, args):
"""Associate PTP instance(s) 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.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))
_host_ptp_instance_op(cc, op='add', uuid=ihost.uuid,
instance=args.nameoruuid)
@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_remove(cc, args):
"""Disassociate PTP instance(s) from host."""
ihost = ihost_utils._find_ihost(cc, args.hostnameorid)
_host_ptp_instance_op(cc, op='remove', uuid=ihost.uuid,
instance=args.nameoruuid)

View File

@ -7,10 +7,11 @@
########################################################################
from cgtsclient.common import base
from cgtsclient.common import utils
from cgtsclient import exc
from cgtsclient.v1 import options
CREATION_ATTRIBUTES = ['interface_uuid', 'ptp_instance_uuid']
CREATION_ATTRIBUTES = ['ptp_instance_uuid']
class PtpInterface(base.Resource):
@ -33,8 +34,8 @@ class PtpInterfaceManager(base.Manager):
path = 'v1/ihosts/%s/ptp_interfaces' % host_id
return self._list(path, "ptp_interfaces")
def list_by_interface(self, host_id, interface_id):
path = 'v1/ihosts/%s/ptp_interfaces?interface_uuid=%s' % (host_id, interface_id)
def list_by_interface(self, interface_id):
path = 'v1/iinterfaces/%s/ptp_interfaces' % interface_id
return self._list(path, "ptp_interfaces")
def get(self, ptp_interface_id):
@ -52,5 +53,19 @@ class PtpInterfaceManager(base.Manager):
raise exc.InvalidAttribute('Invalid attribute: %s' % key)
return self._create(self._path(), body)
def update(self, ptp_interface_id, patch):
return self._update(self._path(ptp_interface_id), patch)
def delete(self, ptp_interface_id):
return self._delete(self._path(ptp_interface_id))
def _find_ptp_interface(cc, key):
if key.isdigit() or utils.is_uuid_like(key):
try:
interface = cc.ptp_interface.get(key)
return interface
except exc.HTTPNotFound:
pass
raise exc.CommandError('PTP interface not found: %s' % key)

View File

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

View File

@ -11,11 +11,12 @@ from cgtsclient import exc
from cgtsclient.v1 import ihost as ihost_utils
from cgtsclient.v1 import iinterface as iinterface_utils
from cgtsclient.v1 import ptp_instance as ptp_instance_utils
from cgtsclient.v1 import ptp_interface as ptp_interface_utils
def _print_ptp_interface_show(ptp_interface_obj):
fields = ['uuid', 'ifname', 'ptp_instance_name',
'hostname', 'created_at']
fields = ['uuid', 'interface_names', 'ptp_instance_name', 'parameters',
'created_at']
data = [(f, getattr(ptp_interface_obj, f, '')) for f in fields]
utils.print_tuple_list(data)
@ -25,40 +26,49 @@ def _print_ptp_interface_show(ptp_interface_obj):
help="UUID of a PTP interface")
def do_ptp_interface_show(cc, args):
"""Show PTP interface attributes."""
ptp_interface = cc.ptp_interface.get(args.ptp_interface_uuid)
host_id = str(getattr(ptp_interface, 'forihostid', ''))
ihost = ihost_utils._find_ihost(cc, host_id)
setattr(ptp_interface, 'hostname', ihost.hostname)
try:
ptp_interface = cc.ptp_interface.get(args.ptp_interface_uuid)
except exc.HTTPNotFound:
raise exc.CommandError('PTP interface not found: %s'
% args.ptp_interface_uuid)
_print_ptp_interface_show(ptp_interface)
@utils.arg('hostnameorid',
metavar='<hostname or id>',
help="Hostname or ID of a host")
@utils.arg('ifnameorid',
metavar='<interface name or uuid>',
nargs='?',
help="Interface name [OPTIONAL]")
def do_ptp_interface_list(cc, args):
"""List PTP interfaces on the specified host,
or a subset of PTP interfaces associated
with a given underlying interface.
"""
ihost = ihost_utils._find_ihost(cc, args.hostnameorid)
if args.ifnameorid:
validate_interface = iinterface_utils._find_interface(cc, ihost, args.ifnameorid)
ptp_interfaces = cc.ptp_interface.list_by_interface(ihost.uuid, validate_interface.uuid)
else:
ptp_interfaces = cc.ptp_interface.list_by_host(ihost.uuid)
def _print_ptp_interface_list(ptp_interface_list):
field_labels = ['uuid', 'ptp_instance_name', 'parameters']
fields = ['uuid', 'ptp_instance_name', 'parameters']
utils.print_list(ptp_interface_list, fields, field_labels)
# Add a hostname column using the forihostid field
for i in ptp_interfaces[:]:
host_id = str(getattr(i, 'forihostid', ''))
ihost = ihost_utils._find_ihost(cc, host_id)
setattr(i, 'hostname', ihost.hostname)
field_labels = ['uuid', 'hostname', 'ifname', 'ptp_instance_name']
fields = ['uuid', 'hostname', 'ifname', 'ptp_instance_name']
utils.print_list(ptp_interfaces, fields, field_labels)
def do_ptp_interface_list(cc, args):
"""List all PTP interfaces."""
ptp_interfaces = cc.ptp_interface.list()
_print_ptp_interface_list(ptp_interfaces)
@utils.arg('ptpinstancenameorid',
metavar='<name or UUID>',
help="Name or UUID of a PTP instance [REQUIRED]")
def do_ptp_interface_add(cc, args):
"""Add a PTP interface."""
field_list = ['ptp_instance_uuid']
ptp_instance = \
ptp_instance_utils._find_ptp_instance(cc, args.ptpinstancenameorid)
# 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))
data["ptp_instance_uuid"] = ptp_instance.uuid
ptp_interface = cc.ptp_interface.create(**data)
uuid = getattr(ptp_interface, 'uuid', '')
try:
ptp_interface = cc.ptp_interface.get(uuid)
except exc.HTTPNotFound:
raise exc.CommandError('PTP interface just created not found: %s'
% uuid)
_print_ptp_interface_show(ptp_interface)
@utils.arg('ptp_interface_uuid',
@ -67,44 +77,137 @@ def do_ptp_interface_list(cc, args):
def do_ptp_interface_delete(cc, args):
"""Delete a PTP interface"""
cc.ptp_interface.delete(args.ptp_interface_uuid)
print('Deleted PTP interface: %s' % (args.ptp_interface_uuid))
print('Deleted PTP interface: %s' % args.ptp_interface_uuid)
def _ptp_interface_parameter_op(cc, op, ptp_interface_uuid, data):
patch = []
for (_k, v) in data.items():
for uuids in v:
for uuid in uuids:
if not utils.is_uuid_like(uuid):
raise exc.CommandError("Invalid UUID '%s'" % uuid)
patch.append({'op': op,
'path': '/ptp_parameters/-',
'value': uuid})
ptp_interface = cc.ptp_interface.update(ptp_interface_uuid, patch)
_print_ptp_interface_show(ptp_interface)
@utils.arg('ptp_interface_uuid',
metavar='<UUID>',
help="UUID of PTP interface")
@utils.arg('paramuuid',
metavar='<parameter UUID>',
nargs='+',
action='append',
default=[],
help="UUID of PTP parameter")
def do_ptp_interface_parameter_add(cc, args):
"""Add parameter(s) to a PTP interface."""
if len(args.paramuuid) == 0:
raise exc.CommandError('Missing PTP parameter UUID')
field_list = ['paramuuid']
data = dict((k, v) for (k, v) in vars(args).items()
if k in field_list and not (v is None))
_ptp_interface_parameter_op(cc, op='add',
ptp_interface_uuid=args.ptp_interface_uuid,
data=data)
@utils.arg('ptp_interface_uuid',
metavar='<UUID>',
help="UUID of PTP interface")
@utils.arg('paramuuid',
metavar='<parameter UUID>',
nargs='+',
action='append',
default=[],
help="UUID of PTP parameter")
def do_ptp_interface_parameter_delete(cc, args):
"""Delete parameter(s) from a PTP interface."""
if len(args.paramuuid) == 0:
raise exc.CommandError('Missing PTP parameter UUID')
field_list = ['paramuuid']
data = dict((k, v) for (k, v) in vars(args).items()
if k in field_list and not (v is None))
_ptp_interface_parameter_op(cc, op='remove',
ptp_interface_uuid=args.ptp_interface_uuid,
data=data)
@utils.arg('hostnameorid',
metavar='<hostname or id>',
help="The hostname or id associated with the interface and ptp instance [REQUIRED]")
help="Hostname or ID of a host")
@utils.arg('ifnameorid',
metavar='<interface name or UUID>',
nargs='?',
help="Interface name or UUID [OPTIONAL]")
def do_host_if_ptp_list(cc, args):
"""List all PTP interfaces on the specified host,
or a subset of PTP interfaces associated
with a given underlying interface.
"""
ihost = ihost_utils._find_ihost(cc, args.hostnameorid)
if args.ifnameorid:
iinterface = iinterface_utils._find_interface(cc, ihost,
args.ifnameorid)
ptp_interfaces = cc.ptp_interface.list_by_interface(
iinterface.uuid)
_print_ptp_interface_list(ptp_interfaces)
else:
ptp_interfaces = cc.ptp_interface.list_by_host(ihost.uuid)
field_labels = ['uuid', 'ptp_instance_name', 'interface_names']
fields = ['uuid', 'ptp_instance_name', 'interface_names']
utils.print_list(ptp_interfaces, fields, field_labels)
def _interface_ptp_op(cc, op, uuid, ptp_interface):
ptp_interface_obj = ptp_interface_utils._find_ptp_interface(cc,
ptp_interface)
ptp_interface_id = ptp_interface_obj.id
patch = [{'op': op,
'path': '/ptp_interfaces/-',
'value': ptp_interface_id}]
cc.iinterface.update(uuid, patch)
ptp_interfaces = cc.ptp_interface.list_by_interface(uuid)
_print_ptp_interface_list(ptp_interfaces)
@utils.arg('hostnameorid',
metavar='<hostname or id>',
help="The host associated with the PTP interface")
@utils.arg('ifnameorid',
metavar='<interface name or uuid>',
help="Name or UUID of an interface [REQUIRED]")
@utils.arg('ptpinstancenameorid',
metavar='<ptp instance name or uuid>',
help="Name or UUID of a PTP instance [REQUIRED]")
def do_ptp_interface_add(cc, args):
"""Add a PTP interface."""
field_list = ['interface_uuid', 'ptp_instance_uuid']
help="Name or UUID of an interface at host")
@utils.arg('ptp_interface_uuid',
metavar='<PTP interface UUID>',
help="UUID of PTP interface")
def do_host_if_ptp_assign(cc, args):
"""Associate PTP to an interface at host."""
ihost = ihost_utils._find_ihost(cc, args.hostnameorid)
iinterface = iinterface_utils._find_interface(cc, ihost, args.ifnameorid)
_interface_ptp_op(cc, op='add', uuid=iinterface.uuid,
ptp_interface=args.ptp_interface_uuid)
validate_ihost = ihost_utils._find_ihost(cc, args.hostnameorid)
validate_ptp_instance = ptp_instance_utils._find_ptp_instance(cc, args.ptpinstancenameorid)
validate_interface = iinterface_utils._find_interface(cc, validate_ihost, args.ifnameorid)
if validate_ihost.uuid != validate_ptp_instance.host_uuid:
raise exc.CommandError('PTP instance %s is not on host %s.'
% (validate_ptp_instance.uuid, validate_ihost.hostname))
# 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))
data["interface_uuid"] = validate_interface.uuid
data["ptp_instance_uuid"] = validate_ptp_instance.uuid
ptp_interface = cc.ptp_interface.create(**data)
uuid = getattr(ptp_interface, 'uuid', '')
try:
ptp_interface = cc.ptp_interface.get(uuid)
except exc.HTTPNotFound:
raise exc.CommandError('Created PTP interface UUID not found: %s'
% uuid)
setattr(ptp_interface, 'hostname', validate_ihost.hostname)
_print_ptp_interface_show(ptp_interface)
@utils.arg('hostnameorid',
metavar='<hostname or id>',
help="The host associated with the PTP interface")
@utils.arg('ifnameorid',
metavar='<interface name or uuid>',
help="Name or UUID of an interface at host")
@utils.arg('ptp_interface_uuid',
metavar='<PTP interface UUID>',
help="UUID of PTP interface")
def do_host_if_ptp_remove(cc, args):
"""Disassociate PTP to an interface at host."""
ihost = ihost_utils._find_ihost(cc, args.hostnameorid)
iinterface = iinterface_utils._find_interface(cc, ihost, args.ifnameorid)
_interface_ptp_op(cc, op='remove', uuid=iinterface.uuid,
ptp_interface=args.ptp_interface_uuid)

View File

@ -34,8 +34,8 @@ class PtpParameterManager(base.Manager):
path = '/v1/ptp_instances/%s/ptp_parameters' % ptp_instance_uuid
return self._list(path, "ptp_parameters")
def list_by_interface(self, interface_uuid):
path = '/v1/iinterfaces/%s/ptp_parameters' % interface_uuid
def list_by_ptp_interface(self, ptp_interface_uuid):
path = '/v1/ptp_interfaces/%s/ptp_parameters' % ptp_interface_uuid
return self._list(path, "ptp_parameters")
def get(self, ptp_parameter_id):

View File

@ -17,40 +17,6 @@ def _print_ptp_parameter_show(ptp_parameter_obj):
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)
def do_ptp_parameter_list(cc, args):
"""List all PTP parameters."""
ptp_parameters = cc.ptp_parameter.list()
_print_ptp_parameter_list(ptp_parameters)
@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',
metavar='<uuid>',
help="UUID of PTP parameter")
@ -60,6 +26,39 @@ def do_ptp_parameter_show(cc, args):
_print_ptp_parameter_show(ptp_parameter)
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('--instance',
metavar='<instance>',
default=None,
help="UUID of PTP instance")
@utils.arg('--interface',
metavar='<interface>',
default=None,
help="UUID of PTP interface")
def do_ptp_parameter_list(cc, args):
"""List all PTP parameters, the ones of a specified PTP instance or
the ones of a specified PTP interface.
"""
if args.instance:
if args.interface:
raise exc.CommandError('Only a single optional argument allowed')
else:
ptp_parameters = cc.ptp_parameter.list_by_ptp_instance(
args.instance)
elif args.interface:
ptp_parameters = cc.ptp_parameter.list_by_ptp_interface(
args.interface)
else:
ptp_parameters = cc.ptp_parameter.list()
_print_ptp_parameter_list(ptp_parameters)
@utils.arg('name',
metavar='<name>',
help="Name of PTP parameter [REQUIRED]")

View File

@ -1,44 +0,0 @@
########################################################################
#
# 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

@ -1,49 +0,0 @@
########################################################################
#
# 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,7 +57,6 @@ 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
@ -82,7 +81,6 @@ COMMAND_MODULES = [
ptp_instance_shell,
ptp_interface_shell,
ptp_parameter_shell,
ptp_paramownership_shell,
iextoam_shell,
controller_fs_shell,
storage_backend_shell,

View File

@ -66,11 +66,8 @@ from sysinv.api.controllers.v1 import pci_device
from sysinv.api.controllers.v1 import port
from sysinv.api.controllers.v1 import ptp
from sysinv.api.controllers.v1 import ptp_instance
from sysinv.api.controllers.v1 import ptp_instance_map
from sysinv.api.controllers.v1 import ptp_interface
from sysinv.api.controllers.v1 import ptp_interface_map
from sysinv.api.controllers.v1 import ptp_parameter
from sysinv.api.controllers.v1 import ptp_paramownership
from sysinv.api.controllers.v1 import pv
from sysinv.api.controllers.v1 import registry_image
from sysinv.api.controllers.v1 import remotelogging
@ -155,21 +152,12 @@ class V1(base.APIBase):
ptp_instances = [link.Link]
"Links to the ptp_instances resource"
ptp_instance_maps = [link.Link]
"Links to the ptp_instance_maps resource"
ptp_interfaces = [link.Link]
"Links to the ptp_interfaces resource"
ptp_interface_maps = [link.Link]
"Links to the ptp_interface_maps resource"
ptp_parameters = [link.Link]
"Links to the ptp_parameters resource"
ptp_parameter_ownerships = [link.Link]
"Links to the ptp_parameter_ownerships resource"
iextoam = [link.Link]
"Links to the iextoam resource"
@ -477,14 +465,6 @@ class V1(base.APIBase):
'ptp_instances', '',
bookmark=True)]
v1.ptp_instance_maps = [link.Link.make_link('self',
pecan.request.host_url,
'ptp_instance_maps', ''),
link.Link.make_link('bookmark',
pecan.request.host_url,
'ptp_instance_maps', '',
bookmark=True)]
v1.ptp_interfaces = [link.Link.make_link('self', pecan.request.host_url,
'ptp_interfaces', ''),
link.Link.make_link('bookmark',
@ -493,14 +473,6 @@ class V1(base.APIBase):
bookmark=True)
]
v1.ptp_interface_maps = [link.Link.make_link('self',
pecan.request.host_url,
'ptp_instance_maps', ''),
link.Link.make_link('bookmark',
pecan.request.host_url,
'ptp_instance_maps', '',
bookmark=True)]
v1.ptp_parameters = [link.Link.make_link('self', pecan.request.host_url,
'ptp_parameters', ''),
link.Link.make_link('bookmark',
@ -508,14 +480,6 @@ 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',
@ -959,12 +923,8 @@ class Controller(rest.RestController):
intp = ntp.NTPController()
ptp = ptp.PTPController()
ptp_instances = ptp_instance.PtpInstanceController()
ptp_instance_maps = ptp_instance_map.PtpInstanceMapController()
ptp_interfaces = ptp_interface.PtpInterfaceController()
ptp_interface_maps = ptp_interface_map.PtpInterfaceMapController()
ptp_parameters = ptp_parameter.PtpParameterController()
ptp_parameter_ownerships = \
ptp_paramownership.PtpParameterOwnershipController()
iextoam = network_oam.OAMNetworkController()
controller_fs = controller_fs.ControllerFsController()
storage_backend = storage_backend.StorageBackendController()

View File

@ -1129,10 +1129,10 @@ class HostController(rest.RestController):
"Expose interface_datanetworks as a sub-element of ihosts"
ptp_instances = ptp_instance.PtpInstanceController(from_ihosts=True)
"Expose PTP instance as a sub-element of ihosts"
"Expose PTP instances as a sub-element of ihosts"
ptp_interfaces = ptp_interface.PtpInterfaceController(from_ihosts=True)
"Expose PTP interface as a sub-element of ihosts"
ptp_interfaces = ptp_interface.PtpInterfaceController(parent="ihosts")
"Expose PTP interfaces as a sub-element of ihosts"
_custom_actions = {
'detail': ['GET'],
@ -1818,17 +1818,22 @@ class HostController(rest.RestController):
"""
utils.validate_patch(patch)
has_ptp_instances = False
optimizable = 0
optimize_list = ['/uptime', '/location', '/serialid', '/task']
for p in patch:
path = p['path']
if path in optimize_list:
optimizable += 1
elif path == '/ptp_instances/-':
has_ptp_instances = True
if len(patch) == optimizable:
if has_ptp_instances:
return self._patch_ptp(uuid, patch)
elif len(patch) == optimizable:
return self._patch(uuid, patch)
elif (pecan.request.user_agent.startswith('mtce') or
pecan.request.user_agent.startswith('vim')):
pecan.request.user_agent.startswith('vim')):
return self._patch_sys(uuid, patch)
else:
return self._patch_gen(uuid, patch)
@ -1841,6 +1846,27 @@ class HostController(rest.RestController):
def _patch_gen(self, uuid, patch):
return self._patch(uuid, patch)
@cutils.synchronized(LOCK_NAME)
def _patch_ptp(self, uuid, patch):
ihost_obj = objects.host.get_by_uuid(pecan.request.context, uuid)
for p in patch:
ptp_instance_id = p['value']
try:
# Check PTP instance exists
pecan.request.dbapi.ptp_instance_get(ptp_instance_id)
except exception.PtpInstanceNotFound:
raise wsme.exc.ClientSideError(
_("No PTP instance object with id %s"
% ptp_instance_id))
values = {'host_id': ihost_obj.id,
'ptp_instance_id': ptp_instance_id}
if p['op'] == 'add':
pecan.request.dbapi.ptp_instance_assign(values)
else:
pecan.request.dbapi.ptp_instance_remove(values)
return Host.convert_with_links(ihost_obj)
@staticmethod
def _validate_capability_is_not_set(old, new):
is_set, __ = new

View File

@ -46,7 +46,7 @@ from sysinv.api.controllers.v1 import types
from sysinv.api.controllers.v1 import utils
from sysinv.api.controllers.v1 import interface_network
from sysinv.api.controllers.v1 import interface_datanetwork
from sysinv.api.controllers.v1 import ptp_parameter
from sysinv.api.controllers.v1 import ptp_interface
from sysinv.common import constants
from sysinv.common import exception
from sysinv.common import utils as cutils
@ -303,8 +303,8 @@ class InterfaceController(rest.RestController):
routes = route.RouteController(parent="iinterfaces")
"Expose routes as a sub-element of interface"
ptp_parameters = ptp_parameter.PtpParameterController(parent="iinterface")
"Expose PTP parameters as a sub-element of interface"
ptp_interfaces = ptp_interface.PtpInterfaceController(parent="iinterface")
"Expose PTP interfaces as a sub-element of interface"
interface_networks = interface_network.InterfaceNetworkController(
parent="iinterfaces")
@ -426,8 +426,12 @@ class InterfaceController(rest.RestController):
LOG.debug("patch_data: %s" % patch)
rpc_interface = objects.interface.get_by_uuid(pecan.request.context,
interface_uuid)
uses = None
ports = None
has_ptp_interfaces = False
patches_to_remove = []
for p in patch:
if '/ifclass' == p['path']:
@ -439,6 +443,25 @@ class InterfaceController(rest.RestController):
elif '/ports' == p['path']:
ports = p['value']
patches_to_remove.append(p)
elif '/ptp_interfaces/-' == p['path']:
has_ptp_interfaces = True
ptp_interface_id = p['value']
try:
# Check PTP interface exists
pecan.request.dbapi.ptp_interface_get(ptp_interface_id)
except exception.PtpInterfaceNotFound:
raise wsme.exc.ClientSideError(
_("No PTP interface object with id %s"
% ptp_interface_id))
values = {'interface_id': rpc_interface.id,
'ptp_interface_id': ptp_interface_id}
if p['op'] == 'add':
pecan.request.dbapi.ptp_interface_assign(values)
else:
pecan.request.dbapi.ptp_interface_remove(values)
if has_ptp_interfaces:
return Interface.convert_with_links(rpc_interface)
if uses:
patch.append(dict(path='/uses', value=uses, op='replace'))
@ -447,9 +470,6 @@ class InterfaceController(rest.RestController):
LOG.debug("patch_ports: %s" % ports)
rpc_interface = objects.interface.get_by_uuid(pecan.request.context,
interface_uuid)
# create a temp interface for semantics checks
temp_interface = copy.deepcopy(rpc_interface)

View File

@ -4,6 +4,7 @@
# SPDX-License-Identifier: Apache-2.0
#
import jsonpatch
import pecan
from pecan import rest
import six
@ -43,8 +44,14 @@ class PtpInstance(base.APIBase):
created_at = wtypes.datetime.datetime
"Timestamp of creation of this PTP instance"
updated_at = wtypes.datetime.datetime
"Timestamp of update of this PTP instance"
# Inherited from PtpParameterOwner
id = int
"ID (primary key) of this PTP instance"
uuid = types.uuid
"Unique UUID for this PTP instance"
@ -68,6 +75,12 @@ class PtpInstance(base.APIBase):
constants.PTP_INSTANCE_TYPE_TS2PHC)
"Type of service of the PTP instance"
hostnames = types.MultiType([list])
"Name(s) of host(s) associated to this PTP instance"
parameters = types.MultiType([list])
"List of parameters referred by this PTP instance"
def __init__(self, **kwargs):
self.fields = list(objects.ptp_instance.fields.keys())
for k in self.fields:
@ -79,12 +92,16 @@ class PtpInstance(base.APIBase):
def convert_with_links(cls, rpc_ptp_instance, expand=True):
ptp_instance = PtpInstance(**rpc_ptp_instance.as_dict())
if not expand:
ptp_instance.unset_fields_except(['uuid',
ptp_instance.unset_fields_except(['id',
'uuid',
'type',
'capabilities',
'name',
'service',
'created_at'])
'hostnames',
'parameters',
'created_at',
'updated_at'])
LOG.debug("PtpInstance.convert_with_links: converted %s" %
ptp_instance.as_dict())
@ -126,7 +143,7 @@ class PtpInstanceController(rest.RestController):
@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'):
sort_key='name', 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))
@ -149,28 +166,12 @@ class PtpInstanceController(rest.RestController):
return PtpInstanceCollection.convert_with_links(
ptp_instances, limit, sort_key=sort_key, sort_dir=sort_dir)
@wsme_pecan.wsexpose(PtpInstance, types.uuid, types.uuid)
def get_one(self, ptp_instance_uuid=None, host_uuid=None):
@wsme_pecan.wsexpose(PtpInstance, types.uuid)
def get_one(self, ptp_instance_uuid):
"""Retrieve a single PTP instance."""
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:
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" % uuid))
LOG.debug("PtpInstanceController.get_one: uuid=%s" % ptp_instance_uuid)
ptp_instance = objects.ptp_instance.get_by_uuid(
pecan.request.context, ptp_instance_uuid)
return PtpInstance.convert_with_links(ptp_instance)
@cutils.synchronized(LOCK_NAME)
@ -179,9 +180,67 @@ 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 foreign data to create the PTP instance
try:
ptp_instance_dict.pop('hostnames')
except KeyError:
LOG.debug("PtpInstanceController.post: no host data in %s" %
ptp_instance_dict)
try:
ptp_instance_dict.pop('parameters')
except KeyError:
LOG.debug("PtpInstanceController.post: no parameter data in %s" %
ptp_instance_dict)
return PtpInstance.convert_with_links(
pecan.request.dbapi.ptp_instance_create(ptp_instance_dict))
@cutils.synchronized(LOCK_NAME)
@wsme.validate(types.uuid, [PtpInstancePatchType])
@wsme_pecan.wsexpose(PtpInstance, types.uuid,
body=[PtpInstancePatchType])
def patch(self, uuid, patch):
"""Update the association between PTP instance and PTP parameters."""
if self._from_ihosts:
raise exception.OperationNotPermitted
LOG.debug("PtpInstanceController.patch: params %s" % patch)
utils.validate_patch(patch)
try:
# Check PTP instance exists
objects.ptp_instance.get_by_uuid(pecan.request.context, uuid)
except exception.InvalidParameterValue:
raise wsme.exc.ClientSideError(
_("No PTP instance found for %s" % uuid))
# Currently patch is used to add/remove PTP parameters
# (but not having both operations in same patch)
patch_list = list(jsonpatch.JsonPatch(patch))
for p in patch_list:
param_uuid = p['value']
try:
# Check PTP parameter exists
pecan.request.dbapi.ptp_parameter_get(param_uuid)
except exception.PtpParameterNotFound:
raise wsme.exc.ClientSideError(
_("No PTP parameter object found for %s" % param_uuid))
if p['op'] == 'add':
pecan.request.dbapi.ptp_instance_parameter_add(uuid,
param_uuid)
LOG.debug("PtpInstanceController.patch: added %s to %s" %
(param_uuid, uuid))
else:
pecan.request.dbapi.ptp_instance_parameter_remove(uuid,
param_uuid)
LOG.debug("PtpInstanceController.patch: removed %s from %s" %
(param_uuid, uuid))
return PtpInstance.convert_with_links(
objects.ptp_instance.get_by_uuid(pecan.request.context, uuid))
@cutils.synchronized(LOCK_NAME)
@wsme_pecan.wsexpose(None, types.uuid, status_code=204)
def delete(self, ptp_instance_uuid):
@ -190,24 +249,35 @@ class PtpInstanceController(rest.RestController):
if self._from_ihosts:
raise exception.OperationNotPermitted
# Only allow delete if there are no associated interfaces and
try:
ptp_instance_obj = objects.ptp_instance.get_by_uuid(
pecan.request.context, ptp_instance_uuid)
except exception.PtpInstanceNotFound:
raise
# Only allow delete if there are no associated hosts, interfaces and
# parameters
parameters = pecan.request.dbapi.ptp_parameters_get_by_owner_uuid(
ptp_instance_uuid)
parameters = pecan.request.dbapi.ptp_parameters_get_list(
ptp_instance=ptp_instance_uuid)
if parameters:
raise wsme.exc.ClientSideError(
"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:
ptp_interfaces = pecan.request.dbapi.ptp_interfaces_get_list(
ptp_instance=ptp_instance_obj.id)
if ptp_interfaces:
raise wsme.exc.ClientSideError(
"PTP instance %s is still associated with PTP interface(s)"
% ptp_instance_uuid)
hosts = pecan.request.dbapi.ptp_instance_get_assignees(
ptp_instance_obj.id)
if hosts:
raise wsme.exc.ClientSideError(
"PTP instance %s is still associated with host(s)"
% ptp_instance_uuid)
LOG.debug("PtpInstanceController.delete: all clear for %s" %
ptp_instance_uuid)
pecan.request.dbapi.ptp_instance_destroy(ptp_instance_uuid)

View File

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

View File

@ -6,6 +6,7 @@
#
########################################################################
import jsonpatch
import pecan
from pecan import rest
import six
@ -14,13 +15,15 @@ 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 link
from sysinv.api.controllers.v1 import ptp_parameter
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
LOG = log.getLogger(__name__)
@ -41,8 +44,17 @@ class PtpInterface(base.APIBase):
interface.
"""
created_at = wtypes.datetime.datetime
"Timestamp of creation of this PTP interface"
updated_at = wtypes.datetime.datetime
"Timestamp of update of this PTP interface"
# Inherited from PtpParameterOwner
id = int
"ID (primary key) of this PTP interface"
uuid = types.uuid
"Unique UUID for this PTP interface"
@ -63,16 +75,20 @@ class PtpInterface(base.APIBase):
ptp_instance_id = int
"ID for the PTP instance this interface is associated with"
links = [link.Link]
"A list containing a self link and associated ptp interface links"
ptp_instance_uuid = types.uuid
"The UUID of the host this PTP interface belongs to"
ptp_instance_name = wtypes.text
"The name of the associated PTP instance"
created_at = wtypes.datetime.datetime
hostnames = types.MultiType([list])
"Name(s) of host(s) associated to this PTP interface"
interface_names = types.MultiType([list])
"Interface(s) associated to this PTP interface"
parameters = types.MultiType([list])
"List of parameters referred by this PTP interface"
def __init__(self, **kwargs):
self.fields = list(objects.ptp_interface.fields.keys())
@ -83,18 +99,24 @@ class PtpInterface(base.APIBase):
@classmethod
def convert_with_links(cls, rpc_ptp_interface, expand=True):
ptp_interface = PtpInterface(**rpc_ptp_interface.as_dict())
if not expand:
ptp_interface.unset_fields_except(['uuid',
ptp_interface.unset_fields_except(['id',
'uuid',
'type',
'capabilities',
'name',
'ptp_instance_id',
'ptp_instance_uuid',
'ptp_instance_name',
'created_at'])
'hostnames',
'interface_names',
'parameters',
'created_at',
'updated_at'])
LOG.debug("PtpInterface.convert_with_links: converted %s" %
ptp_interface.as_dict())
return ptp_interface
@ -124,95 +146,150 @@ LOCK_NAME = 'PtpInterfaceController'
class PtpInterfaceController(rest.RestController):
"""REST controller for ptp interfaces."""
def __init__(self, from_ihosts=False):
self._from_ihosts = from_ihosts
ptp_parameters = ptp_parameter.PtpParameterController(
parent="ptp_interface")
"Expose PTP parameters as a sub-element of PTP interfaces"
@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'):
def __init__(self, parent=None):
self._parent = parent
@wsme_pecan.wsexpose(PtpInterfaceCollection, types.uuid, types.uuid, int,
wtypes.text, wtypes.text)
def get_all(self, parent_uuid=None, marker=None, limit=None, sort_key='id',
sort_dir='asc'):
"""Retrieve a list of PTP interfaces."""
LOG.debug("PtpInterfaceController.get_all: parent %s uuid %s type %s" %
(self._parent, parent_uuid, type))
if self._parent and not parent_uuid:
raise exception.InvalidParameterValue(_(
"Parent id not specified."))
limit = utils.validate_limit(limit)
sort_dir = utils.validate_sort_dir(sort_dir)
""" TODO
marker_obj = None
if 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)
else:
ptp_interfaces = \
pecan.request.dbapi.ptp_interfaces_get_by_host(
host_uuid, limit, marker_obj, sort_key, sort_dir)
if self._parent == 'iinterface':
ptp_interfaces = \
pecan.request.dbapi.ptp_interfaces_get_list(
interface=parent_uuid, limit=limit, marker=marker_obj,
sort_key=sort_key, sort_dir=sort_dir)
elif self._parent == 'ihosts':
ptp_interfaces = \
pecan.request.dbapi.ptp_interfaces_get_list(
host=parent_uuid, limit=limit, marker=marker_obj,
sort_key=sort_key, sort_dir=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,
sort_key=sort_key,
sort_dir=sort_dir)
ptp_interfaces = \
pecan.request.dbapi.ptp_interfaces_get_list(
limit=limit, marker=marker_obj, sort_key=sort_key,
sort_dir=sort_dir)
return PtpInterfaceCollection.convert_with_links(
ptp_interfaces, 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(
LOG.debug("PtpInterfaceController.get_one: uuid=%s"
% ptp_interface_uuid)
ptp_interface = objects.ptp_interface.get_by_uuid(
pecan.request.context, ptp_interface_uuid)
return PtpInterface.convert_with_links(rpc_ptp_interface)
return PtpInterface.convert_with_links(ptp_interface)
@cutils.synchronized(LOCK_NAME)
@wsme_pecan.wsexpose(PtpInterface, body=PtpInterface)
def post(self, ptp_interface):
"""Create a new PTP interface"""
return self._create_ptp_interface(ptp_interface)
def _create_ptp_interface(self, ptp_interface):
# Create a new PTP interface
ptp_interface_dict = ptp_interface.as_dict()
LOG.debug("PtpInterfaceController.post: %s" % ptp_interface_dict)
"""
TODO: enforce "name" as required field here
"""
instance_uuid = ptp_interface_dict.pop('ptp_instance_uuid', None)
instance = objects.ptp_instance.get_by_uuid(pecan.request.context,
instance_uuid)
ptp_interface_dict['ptp_instance_id'] = instance['id']
ptp_instance_uuid = ptp_interface_dict.pop('ptp_instance_uuid', None)
ptp_instance = objects.ptp_instance.get_by_uuid(pecan.request.context,
ptp_instance_uuid)
ptp_interface_dict['ptp_instance_id'] = ptp_instance['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()
"""
return PtpInterface.convert_with_links(
pecan.request.dbapi.ptp_interface_create(ptp_interface_dict))
result = pecan.request.dbapi.ptp_interface_create(ptp_interface_dict)
return PtpInterface.convert_with_links(result)
@cutils.synchronized(LOCK_NAME)
@wsme.validate(types.uuid, [PtpInterfacePatchType])
@wsme_pecan.wsexpose(PtpInterface, types.uuid,
body=[PtpInterfacePatchType])
def patch(self, uuid, patch):
"""Update the association between PTP interface and PTP parameters."""
if self._parent:
raise exception.OperationNotPermitted
LOG.debug("PtpInterfaceController.patch: uuid %s params %s" %
(uuid, patch))
utils.validate_patch(patch)
try:
# Check PTP interface exists
objects.ptp_interface.get_by_uuid(pecan.request.context, uuid)
except exception.InvalidParameterValue:
raise wsme.exc.ClientSideError(
_("No PTP interface found for %s" % uuid))
# Currently patch is used to add/remove PTP parameters
# (but not having both operations in same patch)
patch_list = list(jsonpatch.JsonPatch(patch))
for p in patch_list:
param_uuid = p['value']
try:
# Check PTP parameter exists
pecan.request.dbapi.ptp_parameter_get(param_uuid)
except exception.PtpParameterNotFound:
raise wsme.exc.ClientSideError(
_("No PTP parameter object found for %s" % param_uuid))
if p['op'] == 'add':
pecan.request.dbapi.ptp_interface_parameter_add(uuid,
param_uuid)
else:
pecan.request.dbapi.ptp_interface_parameter_remove(uuid,
param_uuid)
return PtpInterface.convert_with_links(
objects.ptp_interface.get_by_uuid(pecan.request.context, uuid))
@wsme_pecan.wsexpose(None, types.uuid, status_code=204)
def delete(self, ptp_interface_uuid):
"""Delete a PTP interface."""
LOG.debug("PtpInterfaceController.delete: %s" % ptp_interface_uuid)
if self._parent:
raise exception.OperationNotPermitted
try:
ptp_interface = objects.ptp_interface.get_by_uuid(
ptp_interface_obj = objects.ptp_interface.get_by_uuid(
pecan.request.context, ptp_interface_uuid)
except exception.PtpInterfaceNotFound:
raise
# Only allow delete if there are no associated parameters
parameters = pecan.request.dbapi.ptp_parameters_get_by_owner_uuid(
ptp_interface_uuid)
# Only allow delete if there are no associated hosts/interfaces and
# parameters
parameters = pecan.request.dbapi.ptp_parameters_get_list(
ptp_interface=ptp_interface_uuid)
if parameters:
names = [str(p['name']) for p in parameters]
raise wsme.exc.ClientSideError(
"PTP interface %s has PTP parameter(s): %s"
% (ptp_interface_uuid, names))
"PTP interface %s is still associated with PTP parameter(s)"
% ptp_interface_uuid)
interfaces = pecan.request.dbapi.ptp_interface_get_assignees(
ptp_interface_obj.id)
if interfaces:
raise wsme.exc.ClientSideError(
"PTP interface %s is still associated with host interface(s)"
% ptp_interface_uuid)
LOG.debug("PtpInterfaceController.delete: all clear for %s" %
ptp_interface_uuid)
pecan.request.dbapi.ptp_interface_destroy(ptp_interface.uuid)
pecan.request.dbapi.ptp_interface_destroy(ptp_interface_uuid)

View File

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

View File

@ -57,7 +57,7 @@ class PtpParameter(base.APIBase):
"Value of PTP parameter"
owners = types.MultiType([list])
"Owners information: name, type, etc."
"List of owners (UUIDs)"
def __init__(self, **kwargs):
self.fields = list(objects.ptp_parameter.fields.keys())
@ -113,7 +113,7 @@ class PtpParameterController(rest.RestController):
@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'):
sort_key='name', 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))
@ -130,18 +130,27 @@ class PtpParameterController(rest.RestController):
pecan.request.context, marker)
if parent_uuid:
ptp_parameters = \
pecan.request.dbapi.ptp_parameters_get_by_owner_uuid(
parent_uuid, limit, marker_obj, sort_key=sort_key,
sort_dir=sort_dir)
if self._parent == 'ptp_instance':
ptp_parameters = \
pecan.request.dbapi.ptp_parameters_get_list(
ptp_instance=parent_uuid, limit=limit,
marker=marker_obj, sort_key=sort_key,
sort_dir=sort_dir)
elif self._parent == 'ptp_interface':
ptp_parameters = \
pecan.request.dbapi.ptp_parameters_get_list(
ptp_interface=parent_uuid, limit=limit,
marker=marker_obj, sort_key=sort_key,
sort_dir=sort_dir)
elif type is not None:
ptp_parameters = \
pecan.request.dbapi.ptp_parameters_get_by_owner_type(
pecan.request.dbapi.ptp_parameters_get_list_by_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)
limit=limit, marker=marker_obj, sort_key=sort_key,
sort_dir=sort_dir)
return PtpParameterCollection.convert_with_links(
ptp_parameters, limit, sort_key=sort_key, sort_dir=sort_dir)
@ -153,8 +162,7 @@ class PtpParameterController(rest.RestController):
ptp_parameter_uuid)
try:
ptp_parameter = objects.ptp_parameter.get_by_uuid(
pecan.request.context,
ptp_parameter_uuid)
pecan.request.context, ptp_parameter_uuid)
except exception.InvalidParameterValue:
raise wsme.exc.ClientSideError(
_("No PTP parameter found for %s" % ptp_parameter_uuid))
@ -168,11 +176,11 @@ class PtpParameterController(rest.RestController):
ptp_parameter_dict = ptp_parameter.as_dict()
LOG.debug("PtpParameterController.post: %s" % ptp_parameter_dict)
# Get rid of owner details to create the PTP parameter
# Get rid of owner list to create the PTP parameter
try:
ptp_parameter_dict.pop('owners')
except KeyError:
LOG.debug("PtpParameterController.post: no owner data in %s" %
LOG.debug("PtpParameterController.post: no owner list in %s" %
ptp_parameter_dict)
result = pecan.request.dbapi.ptp_parameter_create(ptp_parameter_dict)
@ -187,6 +195,7 @@ class PtpParameterController(rest.RestController):
if self._parent:
raise exception.OperationNotPermitted
utils.validate_patch(patch)
ptp_parameter = objects.ptp_parameter.get_by_uuid(
pecan.request.context, uuid)
@ -215,12 +224,10 @@ class PtpParameterController(rest.RestController):
# Only allow delete if there are no associated PTP instances and
# interfaces
owners = pecan.request.dbapi.ptp_paramownerships_get_by_parameter(
owners = pecan.request.dbapi.ptp_parameter_get_owners(
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))
raise wsme.exc.ClientSideError("PTP parameter %s still in use"
% ptp_parameter_uuid)
pecan.request.dbapi.ptp_parameter_destroy(ptp_parameter_uuid)

View File

@ -1,173 +0,0 @@
#
# 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"
parameter_name = wtypes.text
"Name of the PTP parameter"
parameter_value = wtypes.text
"Value of the PTP parameter"
owner_uuid = types.uuid
"UUID of the entity associated to PTP parameter (instance or interface)"
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', 'parameter_name', 'parameter_value',
'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)
# Get rid of parameter details to set the ownership
try:
ptp_paramownership_dict.pop('parameter_name')
ptp_paramownership_dict.pop('parameter_value')
except KeyError:
LOG.debug("PtpParameterController.post: no parameter data in %s" %
ptp_paramownership_dict)
self._check_parameter_exists(ptp_paramownership_dict['parameter_uuid'])
self._check_owner_exists(ptp_paramownership_dict['owner_uuid'])
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("PtpParameterOwnershipController.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

@ -1928,21 +1928,11 @@ class Connection(object):
"""
@abc.abstractmethod
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, host_uuid=None, limit=None, marker=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_uuid: id or uuid of host.
: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.
@ -1953,7 +1943,7 @@ class Connection(object):
"""
@abc.abstractmethod
def ptp_instance_set_host(self, values):
def ptp_instance_assign(self, values):
"""Set the PTP instance to some host.
:param values: A dict containing the IDs used to associate
@ -1966,7 +1956,7 @@ class Connection(object):
"""
@abc.abstractmethod
def ptp_instance_unset_host(self, values):
def ptp_instance_remove(self, values):
"""Remove the association between a PTP instance and a host.
:param values: A dict containing the IDs used to associate
@ -1978,8 +1968,8 @@ class Connection(object):
"""
@abc.abstractmethod
def ptp_instance_get_hosts(self, ptp_instance_id, limit=None, marker=None,
sort_key=None, sort_dir=None):
def ptp_instance_get_assignees(self, ptp_instance_id, limit=None,
marker=None, sort_key=None, sort_dir=None):
"""Returns a list of all hosts associated to the PTP instance.
:param ptp_instance_id: The id or uuid of a PTP instance.
@ -1992,6 +1982,22 @@ class Connection(object):
:returns: A list of hosts for the given PTP instance.
"""
@abc.abstractmethod
def ptp_instance_parameter_add(self, ptp_instance, ptp_parameter):
"""Add reference/association to PTP parameter.
:param ptp_instance: The UUID of a PTP instance.
:param ptp_parameter: The UUID of PTP parameter to be added.
"""
@abc.abstractmethod
def ptp_instance_parameter_remove(self, ptp_instance, ptp_parameter):
"""Remove reference/association to PTP parameter.
:param ptp_instance: The UUID of a PTP instance.
:param ptp_parameter: The UUID of PTP parameter to be removed.
"""
@abc.abstractmethod
def ptp_instance_destroy(self, ptp_instance_id):
"""Destroys a PTP service instance.
@ -2038,17 +2044,14 @@ class Connection(object):
"""
@abc.abstractmethod
def ptp_interface_get_one(self):
"""Returns exactly one PTP interface association.
:returns: A PTP interface association.
"""
@abc.abstractmethod
def ptp_interfaces_get_list(self, limit=None, marker=None, sort_key=None,
sort_dir=None):
def ptp_interfaces_get_list(self, host=None, interface=None,
ptp_instance=None, limit=None, marker=None,
sort_key=None, sort_dir=None):
"""Returns a list of PTP interface associations.
:param host: id or uuid of host.
:param interface: id or uuid of interface.
:param ptp_instance: id or uuid of PTP instance.
:param limit: Maximum number of PTP interfaces to return.
:param marker: The last item of the previous page; we return the next
result set.
@ -2059,43 +2062,7 @@ class Connection(object):
"""
@abc.abstractmethod
def ptp_interfaces_get_by_instance(self, ptp_instance_id, limit=None,
marker=None, sort_key=None,
sort_dir=None):
"""Returns a list of the PTP associations for a given PTP instance.
:param ptp_instance_id: The id or uuid of a PTP instance.
: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 (interfaces) for the PTP instance.
"""
@abc.abstractmethod
def ptp_interfaces_get_by_instance_and_interface(self, ptp_instance_id,
interface_id,
limit=None,
marker=None,
sort_key=None,
sort_dir=None):
"""Returns a list of one PTP interface for a given instance and interface.
:param ptp_instance_id: The id of a PTP instance.
:param interface_id: The UUID of the underlying interface.
: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 interfaces with the given instance and
interface.
"""
@abc.abstractmethod
def ptp_interface_set_interface(self, values):
def ptp_interface_assign(self, values):
"""Set the PTP interface to some interface.
:param values: A dict containing the IDs used to associate
@ -2108,7 +2075,7 @@ class Connection(object):
"""
@abc.abstractmethod
def ptp_interface_unset_interface(self, values):
def ptp_interface_remove(self, values):
"""Remove the association between a PTP interface and a interface.
:param values: A dict containing the IDs used to associate
@ -2120,8 +2087,8 @@ class Connection(object):
"""
@abc.abstractmethod
def ptp_interface_get_interfaces(self, ptp_interface_id, limit=None,
marker=None, sort_key=None, sort_dir=None):
def ptp_interface_get_assignees(self, ptp_interface_id, limit=None,
marker=None, sort_key=None, sort_dir=None):
"""Returns a list of all interfaces associated to the PTP interface.
:param ptp_interface_id: The id or uuid of a PTP interface.
@ -2134,6 +2101,22 @@ class Connection(object):
:returns: A list of interfaces for the given PTP interface.
"""
@abc.abstractmethod
def ptp_interface_parameter_add(self, ptp_interface, ptp_parameter):
"""Add reference/association to PTP parameter.
:param ptp_interface: The UUID of a PTP interface.
:param ptp_parameter: The UUID of PTP parameter to be added.
"""
@abc.abstractmethod
def ptp_interface_parameter_remove(self, ptp_interface, ptp_parameter):
"""Remove reference/association to PTP parameter.
:param ptp_interface: The UUID of a PTP interface.
:param ptp_parameter: The UUID of PTP parameter to be removed.
"""
@abc.abstractmethod
def ptp_interface_destroy(self, ptp_interface_id):
"""Destroys a PTP interface association.
@ -2172,18 +2155,13 @@ class Connection(object):
"""
@abc.abstractmethod
def ptp_parameter_get_one(self, name=None):
"""Returns exactly one PTP parameter.
:param name: name of PTP parameter.
:returns: A PTP parameter.
"""
@abc.abstractmethod
def ptp_parameters_get_list(self, limit=None, marker=None, sort_key=None,
def ptp_parameters_get_list(self, ptp_instance=None, ptp_interface=None,
limit=None, marker=None, sort_key=None,
sort_dir=None):
"""Returns a list of PTP parameters.
:param ptp_instance: UUID of PTP instance that uses the parameter.
:param ptp_interface: UUID of PTP interface that uses the parameter.
:param limit: Maximum number of PTP parameters to return.
:param marker: The last item of the previous page; we return the next
result set.
@ -2194,9 +2172,25 @@ class Connection(object):
"""
@abc.abstractmethod
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.
def ptp_parameter_get_owners(self, ptp_parameter_uuid, limit=None,
marker=None, sort_key=None, sort_dir=None):
"""Returns a list of all PTP instances and PTP interfaces that use
(point to) the PTP parameter.
:param ptp_parameter_id: The uuid of a PTP parameter.
:param limit: Maximum number of hosts to return.
:param marker: The last item of the previous page; we return the next
result set.
:param sort_key: Attribute by which results should be sorted
:param sort_dir: direction in which results should be sorted
(asc, desc)
:returns: A list of owners for the given PTP parameter.
"""
@abc.abstractmethod
def ptp_parameters_get_list_by_type(self, type, limit=None, marker=None,
sort_key=None, sort_dir=None):
"""Returns a list of all PTP parameters of a given owner type.
:param type: Type of the parameter owner (either 'ptp-instance' or
'ptp-interface')
@ -2209,22 +2203,6 @@ class Connection(object):
:returns: A list of PTP parameters for a specific owner type.
"""
@abc.abstractmethod
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.
:param uuid: UUID of the parameter owner.
:param limit: Maximum number of PTP parameters 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 parameters of the specified owner.
"""
@abc.abstractmethod
def ptp_parameter_update(self, ptp_parameter_id, values):
"""Updates properties of a PTP parameter.
@ -2237,50 +2215,6 @@ 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.
@ -2293,7 +2227,7 @@ class Connection(object):
"""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.
:param ptp_paramowner_id: The id or uuid of a PTP parameter owner.
:returns: A PTP parameter owner.
"""
@ -2306,37 +2240,6 @@ class Connection(object):
: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

@ -3740,6 +3740,8 @@ class Connection(api.Connection):
def ptp_instance_create(self, values):
if not values.get('uuid'):
values['uuid'] = uuidutils.generate_uuid()
if not values.get('type'):
values['type'] = constants.PTP_PARAMETER_OWNER_INSTANCE
ptp_instance = models.PtpInstances(**values)
with _session_for_write() as session:
try:
@ -3754,43 +3756,24 @@ 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, 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:
return query.one()
except NoResultFound:
raise exception.NotFound()
@objects.objectify(objects.ptp_instance)
def ptp_instances_get_list(self, host_uuid=None, 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)
if host_uuid is not None:
host = self.ihost_get(host_uuid)
query = query.join(models.PtpInstanceMaps,
models.PtpInstanceMaps.host_id == host.id)
if host is not None:
host_obj = self.ihost_get(host)
query = query.join(models.PtpInstanceMaps).filter(
models.PtpInstanceMaps.host_id == host_obj.id)
return _paginate_query(models.PtpInstances, limit, marker,
sort_key, sort_dir, query)
def ptp_instance_parameter_add(self, ptp_instance, ptp_parameter):
return self._ptp_parameter_add(ptp_instance, ptp_parameter)
def ptp_instance_parameter_remove(self, ptp_instance, ptp_parameter):
self._ptp_parameter_remove(ptp_instance, ptp_parameter)
@objects.objectify(objects.ptp_instance_map)
def ptp_instance_set_host(self, values):
def ptp_instance_assign(self, values):
if not values.get('uuid'):
values['uuid'] = uuidutils.generate_uuid()
ptp_instance_map = models.PtpInstanceMaps(**values)
@ -3811,7 +3794,7 @@ class Connection(api.Connection):
except NoResultFound:
raise exception.PtpInstanceMapNotFound(uuid=values['uuid'])
def ptp_instance_unset_host(self, values):
def ptp_instance_remove(self, values):
with _session_for_write() as session:
query = model_query(models.PtpInstanceMaps, session=session)
query = query.filter_by(ptp_instance_id=values['ptp_instance_id'],
@ -3822,14 +3805,14 @@ class Connection(api.Connection):
return
query.delete()
@objects.objectify(objects.ptp_instance)
def ptp_instance_get_hosts(self, ptp_instance_id, limit=None, marker=None,
sort_key=None, sort_dir=None):
query = model_query(models.PtpInstances)
query = add_identity_filter(query, ptp_instance_id)
query = query.join(models.PtpInstances.hosts)
return _paginate_query(models.PtpInstances, limit, marker, sort_key,
sort_dir, query)
@objects.objectify(objects.host)
def ptp_instance_get_assignees(self, ptp_instance_id, limit=None,
marker=None, sort_key=None, sort_dir=None):
query = model_query(models.ihost)
query = query.join(models.PtpInstanceMaps).filter(
models.PtpInstanceMaps.ptp_instance_id == ptp_instance_id)
return _paginate_query(models.ihost, limit, marker, sort_key, sort_dir,
query)
def ptp_instance_destroy(self, ptp_instance_id):
with _session_for_write() as session:
@ -3873,6 +3856,8 @@ class Connection(api.Connection):
def ptp_interface_create(self, values):
if not values.get('uuid'):
values['uuid'] = uuidutils.generate_uuid()
if not values.get('type'):
values['type'] = constants.PTP_PARAMETER_OWNER_INTERFACE
ptp_interface = models.PtpInterfaces()
ptp_interface.update(values)
with _session_for_write() as session:
@ -3888,72 +3873,37 @@ class Connection(api.Connection):
return self._ptp_interface_get(ptp_interface_id)
@objects.objectify(objects.ptp_interface)
def ptp_interface_get_one(self, interface_uuid=None):
def ptp_interfaces_get_list(self, host=None, interface=None,
ptp_instance=None, limit=None, marker=None,
sort_key=None, sort_dir=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, host_uuid=None, interface_uuid=None,
limit=None, marker=None, sort_key=None,
sort_dir=None):
query = model_query(models.PtpInterfaces)
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)
if ptp_instance is not None:
ptp_instance_obj = self.ptp_instance_get(ptp_instance)
query = query.filter_by(ptp_instance_id=ptp_instance_obj.id)
if interface is not None:
interface_obj = self.iinterface_get(interface)
query = query.join(models.PtpInterfaceMaps).filter(
models.PtpInterfaceMaps.interface_id == interface_obj.id)
elif interface is not None:
interface_obj = self.iinterface_get(interface)
query = query.join(models.PtpInterfaceMaps).filter(
models.PtpInterfaceMaps.interface_id == interface_obj.id)
elif host is not None:
host_obj = self.ihost_get(host)
query = query.join(models.PtpInterfaceMaps).join(
models.Interfaces).filter(
models.Interfaces.forihostid == host_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(self, ptp_instance_id, limit=None,
marker=None, sort_key=None,
sort_dir=None):
# NOTE: ptp_instance_get() to raise an exception if the instance is
# not found
ptp_instance_obj = self.ptp_instance_get(ptp_instance_id)
query = model_query(models.PtpInterfaces)
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_parameter_add(self, ptp_interface, ptp_parameter):
return self._ptp_parameter_add(ptp_interface, ptp_parameter)
@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):
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_parameter_remove(self, ptp_interface, ptp_parameter):
self._ptp_parameter_remove(ptp_interface, ptp_parameter)
@objects.objectify(objects.ptp_interface_map)
def ptp_interface_set_interface(self, values):
def ptp_interface_assign(self, values):
if not values.get('uuid'):
values['uuid'] = uuidutils.generate_uuid()
ptp_interface_map = models.PtpInterfaceMaps(**values)
@ -3974,7 +3924,7 @@ class Connection(api.Connection):
except NoResultFound:
raise exception.PtpInterfaceMapNotFound(uuid=values['uuid'])
def ptp_interface_unset_interface(self, values):
def ptp_interface_remove(self, values):
with _session_for_write() as session:
query = model_query(models.PtpInterfaceMaps, session=session)
query = query.filter_by(
@ -3986,14 +3936,13 @@ class Connection(api.Connection):
return
query.delete()
@objects.objectify(objects.ptp_interface)
def ptp_interface_get_interfaces(self, ptp_interface_id, limit=None,
marker=None, sort_key=None,
sort_dir=None):
query = model_query(models.PtpInterfaces)
query = add_identity_filter(query, ptp_interface_id)
query = query.join(models.PtpInterfaces.interfaces)
return _paginate_query(models.PtpInterfaces, limit, marker, sort_key,
@objects.objectify(objects.interface)
def ptp_interface_get_assignees(self, ptp_interface_id, limit=None,
marker=None, sort_key=None, sort_dir=None):
query = model_query(models.Interfaces)
query = query.join(models.PtpInterfaceMaps).filter(
models.PtpInterfaceMaps.ptp_interface_id == ptp_interface_id)
return _paginate_query(models.Interfaces, limit, marker, sort_key,
sort_dir, query)
def ptp_interface_destroy(self, ptp_interface_id):
@ -4043,39 +3992,43 @@ class Connection(api.Connection):
return self._ptp_parameter_get(ptp_parameter_id)
@objects.objectify(objects.ptp_parameter)
def ptp_parameter_get_one(self, name=None):
query = model_query(models.PtpParameters)
if name is not None:
query = query.filter_by(name=name)
try:
return query.one()
except NoResultFound:
raise exception.NotFound()
@objects.objectify(objects.ptp_parameter)
def ptp_parameters_get_list(self, limit=None, marker=None, sort_key=None,
def ptp_parameters_get_list(self, ptp_instance=None, ptp_interface=None,
limit=None, marker=None, sort_key=None,
sort_dir=None):
query = model_query(models.PtpParameters)
uuid = None
type = None
if ptp_instance:
uuid = ptp_instance
type = constants.PTP_PARAMETER_OWNER_INSTANCE
elif ptp_interface:
uuid = ptp_interface
type = constants.PTP_PARAMETER_OWNER_INTERFACE
if uuid and type:
query = query.join(
models.PtpParameters.ptp_parameter_owners).filter(
models.PtpParameterOwners.uuid == uuid,
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_type(self, type, limit=None, marker=None,
sort_key=None, sort_dir=None):
def ptp_parameters_get_list_by_type(self, type, limit=None, marker=None,
sort_key=None, sort_dir=None):
query = model_query(models.PtpParameters)
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_uuid(self, uuid, limit=None, marker=None,
sort_key=None, sort_dir=None):
query = model_query(models.PtpParameters)
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_paramowner)
def ptp_parameter_get_owners(self, ptp_parameter_uuid, limit=None,
marker=None, sort_key=None, sort_dir=None):
query = model_query(models.PtpParameterOwners)
query = query.join(models.PtpParameterOwnerships).filter(
models.PtpParameterOwnerships.parameter_uuid == ptp_parameter_uuid)
return _paginate_query(models.PtpParameterOwners, limit, marker,
sort_key, sort_dir, query)
@objects.objectify(objects.ptp_parameter)
def ptp_parameter_update(self, ptp_parameter_id, values):
@ -4087,49 +4040,6 @@ 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)
@ -4149,8 +4059,7 @@ class Connection(api.Connection):
except NoResultFound:
raise exception.PtpParameterOwnerNotFound(uuid=ptp_paramowner_id)
@objects.objectify(objects.ptp_paramownership)
def ptp_paramownership_get(self, ptp_paramownership_id):
def _ptp_paramownership_get(self, ptp_paramownership_id):
query = model_query(models.PtpParameterOwnerships)
query = add_identity_filter(query, ptp_paramownership_id)
try:
@ -4160,21 +4069,33 @@ class Connection(api.Connection):
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)
def ptp_paramownership_get(self, ptp_paramownership_id):
return self._ptp_paramownership_get(ptp_paramownership_id)
@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)
def _ptp_parameter_add(self, ptp_parameter_owner, ptp_parameter):
with _session_for_write() as session:
values = dict()
values['uuid'] = uuidutils.generate_uuid()
values['owner_uuid'] = ptp_parameter_owner
values['parameter_uuid'] = ptp_parameter
param_ownership = models.PtpParameterOwnerships(**values)
try:
session.add(param_ownership)
session.flush()
except db_exc.DBDuplicateEntry:
raise exception.PtpParameterOwnershipAlreadyExists(
param=ptp_parameter, owner=ptp_parameter_owner)
return self._ptp_paramownership_get(values['uuid'])
def _ptp_parameter_remove(self, ptp_parameter_owner, ptp_parameter):
with _session_for_write() as session:
query = model_query(models.PtpParameterOwnerships,
session=session)
query = query.filter_by(parameter_uuid=ptp_parameter,
owner_uuid=ptp_parameter_owner)
query.one()
query.delete()
# NOTE: method is deprecated and provided for API compatibility.
# object class will convert Network entity to an iextoam object

View File

@ -245,7 +245,7 @@ class ihost(Base):
peer_id = Column(Integer,
ForeignKey('peers.id'))
system = relationship("isystem")
system = relationship("isystem", lazy="joined", join_depth=1)
host_upgrade = relationship("HostUpgrade", uselist=False)
kube_host_upgrade = relationship("KubeHostUpgrade", uselist=False)
@ -880,10 +880,8 @@ class PtpInterfaces(PtpParameterOwners):
nullable=False)
ptp_instance = relationship("PtpInstances", lazy="joined", join_depth=1,
foreign_keys=[
PtpInstances.id,
PtpInstances.name,
PtpInstances.uuid])
primaryjoin="PtpInterfaces.ptp_instance_id == "
"PtpInstances.id")
interfaces = relationship(
"Interfaces",

View File

@ -23,6 +23,15 @@ def _get_target_load(field, db_object):
return db_object.host_upgrade.load_target.software_version
def _get_ptp_instance_names(field, db_object):
instances = db_object['ptp_instances']
names = []
if instances is not None:
for i in instances:
names.append(str(i.name))
return names
class Host(base.SysinvObject):
dbapi = db_api.get_instance()

View File

@ -12,14 +12,12 @@ from sysinv.objects import utils
from sysinv.objects import ptp_paramowner
def get_hosts(field, db_object):
def get_hostnames(field, db_object):
hosts = db_object['hosts']
if not hosts:
return []
hostnames = []
for h in hosts:
hostnames.append(h.hostname)
if hosts is not None:
for h in hosts:
hostnames.append(h.hostname)
return hostnames
@ -28,13 +26,16 @@ class PtpInstance(ptp_paramowner.PtpParameterOwner):
dbapi = db_api.get_instance()
fields = dict({
'id': int,
'name': utils.str_or_none,
'service': utils.str_or_none,
'hosts': utils.list_of_strings_or_none
'hostnames': utils.list_of_strings_or_none,
'parameters': utils.list_of_strings_or_none
}, **ptp_paramowner.PtpParameterOwner.fields)
_foreign_fields = {
'hosts': get_hosts
'hostnames': get_hostnames,
'parameters': ptp_paramowner.get_parameters
}
@base.remotable_classmethod

View File

@ -8,7 +8,6 @@
from sysinv.db import api as db_api
from sysinv.objects import base
from sysinv.objects import utils
class PtpInstanceMap(base.SysinvObject):
@ -16,23 +15,13 @@ class PtpInstanceMap(base.SysinvObject):
dbapi = db_api.get_instance()
fields = {
'id': int,
'uuid': utils.str_or_none,
'host_id': int,
'hostname': utils.str_or_none,
'ptp_instance_id': int,
'name': utils.str_or_none,
'service': utils.str_or_none
}
_foreign_fields = {
'host_id': 'host:id',
'hostname': 'host:hostname',
'ptp_instance_id': 'ptp_instance:id',
'name': 'ptp_instance:name',
'service': 'ptp_instance:service'
'ptp_instance_id': 'instance:id',
}
@base.remotable_classmethod

View File

@ -14,20 +14,23 @@ from sysinv.objects import ptp_paramowner
def get_interfaces(field, db_object):
interfaces = db_object['interfaces']
if not interfaces:
return []
interface_list = []
if interfaces is not None:
for i in interfaces:
host = getattr(i, 'host')
interface = '%s/%s' % (host.hostname, i.ifname)
interface_list.append(interface)
return interface_list
interfaces = []
for i in interfaces:
details = {}
details['name'] = i.ifname
details['type'] = i.iftype
host = getattr(i, 'host')
if host:
details['host'] = host.hostname
interfaces.append(details)
return interfaces
def get_hostnames(field, db_object):
interfaces = db_object['interfaces']
hostnames = []
if interfaces is not None:
for i in interfaces:
host = getattr(i, 'host')
hostnames.append(host.hostname)
return hostnames
class PtpInterface(ptp_paramowner.PtpParameterOwner):
@ -35,17 +38,23 @@ class PtpInterface(ptp_paramowner.PtpParameterOwner):
dbapi = db_api.get_instance()
fields = dict({
'id': int,
'name': utils.str_or_none,
'ptp_instance_id': utils.int_or_none,
'ptp_instance_id': int,
'ptp_instance_uuid': utils.str_or_none,
'ptp_instance_name': utils.str_or_none,
'interfaces': list
'interface_names': utils.list_of_strings_or_none,
'hostnames': utils.list_of_strings_or_none,
'parameters': utils.list_of_strings_or_none
}, **ptp_paramowner.PtpParameterOwner.fields)
_foreign_fields = {
'ptp_instance_id': 'ptp_instance:id',
'ptp_instance_uuid': 'ptp_instance:uuid',
'ptp_instance_name': 'ptp_instance:name',
'interfaces': get_interfaces
'interface_names': get_interfaces,
'hostnames': get_hostnames,
'parameters': ptp_paramowner.get_parameters
}
@base.remotable_classmethod

View File

@ -8,31 +8,6 @@
from sysinv.db import api as db_api
from sysinv.objects import base
from sysinv.objects import utils
def get_hostname(field, db_object):
host = getattr(db_object['interface'], 'host')
if not host:
return None
return host.hostname
def get_instance_name(field, db_object):
instance = getattr(db_object['ptp_interface'], 'ptp_instance')
if not instance:
return None
return instance.name
def get_instance_service(field, db_object):
instance = getattr(db_object['ptp_interface'], 'ptp_instance')
if not instance:
return None
return instance.service
class PtpInterfaceMap(base.SysinvObject):
@ -40,27 +15,13 @@ class PtpInterfaceMap(base.SysinvObject):
dbapi = db_api.get_instance()
fields = {
'id': int,
'uuid': utils.str_or_none,
'interface_id': int,
'ifname': utils.str_or_none,
'iftype': utils.str_or_none,
'hostname': utils.str_or_none,
'ptp_interface_id': int,
'name': utils.str_or_none,
'service': utils.str_or_none
}
_foreign_fields = {
'interface_id': 'interface:id',
'ifname': 'interface:ifname',
'iftype': 'interface:iftype',
'hostname': get_hostname,
'ptp_interface_id': 'ptp_interface:id',
'name': get_instance_name,
'service': get_instance_service
}
@base.remotable_classmethod

View File

@ -6,27 +6,18 @@
#
########################################################################
from sysinv.common import constants
from sysinv.db import api as db_api
from sysinv.objects import base
from sysinv.objects import utils
def get_owners(field, db_object):
ptp_parameter_owners = db_object['ptp_parameter_owners']
if not ptp_parameter_owners:
return []
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 owners
owners = db_object['ptp_parameter_owners']
uuids = []
if owners is not None:
for o in owners:
uuids.append(o.uuid)
return uuids
class PtpParameter(base.SysinvObject):
@ -36,11 +27,9 @@ class PtpParameter(base.SysinvObject):
fields = {
'id': int,
'uuid': utils.str_or_none,
'name': utils.str_or_none,
'value': utils.str_or_none,
'owners': list
'owners': utils.list_of_strings_or_none
}
_foreign_fields = {

View File

@ -11,6 +11,16 @@ from sysinv.objects import base
from sysinv.objects import utils
def get_parameters(field, db_object):
ptp_parameters = db_object['ptp_parameters']
parameters = []
if ptp_parameters is not None:
for p in ptp_parameters:
parameter = '%s=%s' % (p.name, p.value)
parameters.append(parameter)
return parameters
class PtpParameterOwner(base.SysinvObject):
dbapi = db_api.get_instance()
@ -19,7 +29,7 @@ class PtpParameterOwner(base.SysinvObject):
'id': int,
'uuid': utils.str_or_none,
'type': utils.str_or_none,
'capabilities': utils.dict_or_none
'capabilities': utils.dict_or_none,
}
_foreign_fields = {}

View File

@ -16,20 +16,12 @@ class PtpParameterOwnership(base.SysinvObject):
dbapi = db_api.get_instance()
fields = {
'id': int,
'uuid': utils.str_or_none,
'parameter_uuid': utils.str_or_none,
'parameter_name': utils.str_or_none,
'parameter_value': utils.str_or_none,
'owner_uuid': utils.str_or_none,
}
_foreign_fields = {
'parameter_uuid': 'parameter:uuid',
'parameter_name': 'parameter:name',
'parameter_value': 'parameter:value',
'owner_uuid': 'owner:uuid'
}

View File

@ -236,7 +236,7 @@ class NetworkingPuppet(base.BasePuppet):
for global_param in ptp_parameters_instance:
# Add the supplied instance parameters to global_parameters
if global_param['foreign_uuid'] == instance['uuid']:
if instance['uuid'] in global_param['owners']:
instance['global_parameters'][global_param['name']] = global_param['value']
if 'cmdline_opts' in instance['global_parameters']:
instance['cmdline_opts'] = instance['global_parameters'].pop('cmdline_opts')
@ -280,7 +280,7 @@ class NetworkingPuppet(base.BasePuppet):
iface['parameters'].update(default_interface_parameters)
# Add supplied params to the interface
for param in ptp_parameters_interface:
if param['foreign_uuid'] == iface['uuid']:
if iface['uuid'] in param['owners']:
iface['parameters'][param['name']] = param['value']
return ptp_instances
@ -289,20 +289,20 @@ class NetworkingPuppet(base.BasePuppet):
if host.clock_synchronization == constants.PTP:
ptp_enabled = True
# Returning here because ptp instance functionality is not enabled at this time
# Subsequent code is inactive until this return statement is removed and ptp instance
# functionality is turned on
return {'platform::ptpinstance::enabled': ptp_enabled}
else:
ptp_enabled = False
return {'platform::ptpinstance::enabled': ptp_enabled}
# Returning here because ptp instance functionality is not enabled at this time
# Subsequent code is inactive until this return statement is removed and ptp instance
# functionality is turned on
return {'platform::ptpinstance::enabled': ptp_enabled}
# Get the database entries for instances, interfaces and parameters
ptp_instances = self.dbapi.ptp_instances_get_by_ihost(ihost_id=host.id)
ptp_interfaces = self.dbapi.ptp_interfaces_get_by_host(host.uuid)
ptp_parameters_instance = self.dbapi.ptp_parameters_get_by_type(
ptp_instances = self.dbapi.ptp_instances_get_list(host=host.id)
ptp_interfaces = self.dbapi.ptp_interfaces_get_list(host=host.uuid)
ptp_parameters_instance = self.dbapi.ptp_parameters_get_list_by_type(
constants.PTP_PARAMETER_OWNER_INSTANCE)
ptp_parameters_interface = self.dbapi.ptp_parameters_get_by_type(
ptp_parameters_interface = self.dbapi.ptp_parameters_get_list_by_type(
constants.PTP_PARAMETER_OWNER_INTERFACE)
for index, instance in enumerate(ptp_instances):

View File

@ -37,11 +37,12 @@ class BasePtpInstanceTestCase(base.FunctionalTest, dbbase.BaseHostTestCase):
def get_host_scoped_url(self, host_uuid):
return '%s/%s%s' % (self.HOST_PREFIX, host_uuid, self.API_PREFIX)
def get_host_url(self, host_uuid):
return '%s/%s' % (self.HOST_PREFIX, host_uuid)
def get_post_object(self, name='test_instance',
service=constants.PTP_INSTANCE_TYPE_PTP4L):
ptp_instance_db = dbutils.get_test_ptp_instance(name=name,
service=service)
return ptp_instance_db
return dbutils.get_test_ptp_instance(name=name, service=service)
class TestCreatePtpInstance(BasePtpInstanceTestCase):
@ -91,22 +92,128 @@ class TestCreatePtpInstance(BasePtpInstanceTestCase):
error_message=error_message)
class TestSetPtpInstance(BasePtpInstanceTestCase):
class TestUpdatePtpInstance(BasePtpInstanceTestCase):
uuid = None
def setUp(self):
super(TestSetPtpInstance, self).setUp()
super(TestUpdatePtpInstance, self).setUp()
ptp_instance = dbutils.create_test_ptp_instance(
name=constants.PTP_INSTANCE_DEFAULT_PTP4L,
service=constants.PTP_INSTANCE_TYPE_PTP4L)
self.uuid = ptp_instance['uuid']
def test_set_ptp_instance_to_hosts(self):
# TODO
pass
def test_update_ptp_instance_add_parameter_ok(self):
ptp_parameter_1 = dbutils.create_test_ptp_parameter(
name='param1', value='value1')
ptp_parameter_2 = dbutils.create_test_ptp_parameter(
name='param2', value='value2')
response = self.patch_json(self.get_single_url(self.uuid),
[{'path': '/ptp_parameters/-',
'value': ptp_parameter_1['uuid'],
'op': 'add'},
{'path': '/ptp_parameters/-',
'value': ptp_parameter_2['uuid'],
'op': 'add'}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
def test_update_ptp_instance_add_parameter_failed_no_instance(self):
ptp_parameter = dbutils.create_test_ptp_parameter(name='name',
value='value')
fake_uuid = 'f4c56ddf-aef3-46ed-b9aa-126a1faafd40'
error_message = 'No PTP instance with id %s found.' % fake_uuid
response = self.patch_json(self.get_single_url(fake_uuid),
[{'path': '/ptp_parameters/-',
'value': ptp_parameter['uuid'],
'op': 'add'}],
headers=self.API_HEADERS,
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_update_ptp_instance_add_parameter_failed_no_param(self):
fake_uuid = 'f4c56ddf-aef3-46ed-b9aa-126a1faafd40'
error_message = 'No PTP parameter object found for %s' % fake_uuid
response = self.patch_json(self.get_single_url(self.uuid),
[{'path': '/ptp_parameters/-',
'value': fake_uuid,
'op': 'add'}],
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_update_ptp_instance_delete_parameter_ok(self):
ptp_parameter = dbutils.create_test_ptp_parameter(
name='param1', value='value1')
response = self.patch_json(self.get_single_url(self.uuid),
[{'path': '/ptp_parameters/-',
'value': ptp_parameter['uuid'],
'op': 'add'}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
response = self.patch_json(self.get_single_url(self.uuid),
[{'path': '/ptp_parameters/-',
'value': ptp_parameter['uuid'],
'op': 'remove'}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
class TestUnsetPtpInstance(BasePtpInstanceTestCase):
class TestHostPtpInstance(BasePtpInstanceTestCase):
def setUp(self):
super(TestUnsetPtpInstance, self).setUp()
super(TestHostPtpInstance, self).setUp()
def test_unset_ptp_instance_from_hosts(self):
# TODO
pass
def _assign_host_ptp_instance_success(self):
ptp_instance = dbutils.create_test_ptp_instance(
name=constants.PTP_INSTANCE_DEFAULT_PTP4L,
service=constants.PTP_INSTANCE_TYPE_PTP4L)
ptp_instance_id = ptp_instance['id']
response = self.patch_json(
self.get_host_url(self.controller.uuid),
[{'path': '/ptp_instances/-',
'value': ptp_instance_id,
'op': 'add'}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
return ptp_instance_id
def test_host_ptp_instance_assign_ok(self):
self._assign_host_ptp_instance_success()
def test_host_ptp_instance_assign_failed(self):
fake_id = 101
error_message = 'No PTP instance object with id %s' % fake_id
response = self.patch_json(
self.get_host_url(self.controller.uuid),
[{'path': '/ptp_instances/-',
'value': fake_id,
'op': 'add'}],
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_host_ptp_instance_remove_ok(self):
ptp_instance_id = self._assign_host_ptp_instance_success()
response = self.patch_json(
self.get_host_url(self.controller.uuid),
[{'path': '/ptp_instances/-',
'value': ptp_instance_id,
'op': 'remove'}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
class TestGetPtpInstance(BasePtpInstanceTestCase):
@ -117,8 +224,7 @@ class TestGetPtpInstance(BasePtpInstanceTestCase):
ptp_instance = dbutils.create_test_ptp_instance(
name=constants.PTP_INSTANCE_DEFAULT_PTP4L,
service=constants.PTP_INSTANCE_TYPE_PTP4L)
uuid = ptp_instance['uuid']
response = self.get_json(self.get_single_url(uuid))
response = self.get_json(self.get_single_url(ptp_instance['uuid']))
self.assertIn(self.COMMON_FIELD, response)
def test_get_ptp_instance_not_found(self):
@ -141,13 +247,18 @@ class TestListPtpInstance(BasePtpInstanceTestCase):
services = [constants.PTP_INSTANCE_TYPE_PTP4L,
constants.PTP_INSTANCE_TYPE_PHC2SYS,
constants.PTP_INSTANCE_TYPE_TS2PHC]
instances = []
for service in services:
name = '%s-%s' % (name_prefix, service)
instance = dbutils.create_test_ptp_instance(
name=name, service=service)
instances.append(instance)
return instances
instance = dbutils.create_test_ptp_instance(name=name,
service=service)
response = self.patch_json(
self.get_host_url(self.controller.uuid),
[{'path': '/ptp_instances/-',
'value': instance['id'],
'op': 'add'}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
def test_list_ptp_instance_all(self):
response = self.get_json(self.API_PREFIX)
@ -159,8 +270,10 @@ class TestListPtpInstance(BasePtpInstanceTestCase):
self.assertEqual([], response[self.RESULT_KEY])
def test_list_ptp_instance_host(self):
# TODO
pass
response = self.get_json(
self.get_host_scoped_url(self.controller.uuid))
for result in response[self.RESULT_KEY]:
self.assertIn(self.controller.hostname, result['hostnames'])
class TestDeletePtpInstance(BasePtpInstanceTestCase):
@ -193,15 +306,32 @@ class TestDeletePtpInstance(BasePtpInstanceTestCase):
self.assertIn(error_message, response.json['error_message'])
def test_delete_ptp_instance_with_host_failed(self):
# TODO
pass
response = self.patch_json(
self.get_host_url(self.controller.uuid),
[{'path': '/ptp_instances/-',
'value': self.ptp_instance['id'],
'op': 'add'}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
response = self.delete(self.get_single_url(self.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 host',
response.json['error_message'])
def test_delete_ptp_instance_with_parameters_failed(self):
ptp_parameter = dbutils.create_test_ptp_parameter(
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.patch_json(self.get_single_url(self.uuid),
[{'path': '/ptp_parameters/-',
'value': ptp_parameter['uuid'],
'op': 'add'}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
response = self.delete(self.get_single_url(self.uuid),
headers=self.API_HEADERS, expect_errors=True)
@ -211,12 +341,9 @@ class TestDeletePtpInstance(BasePtpInstanceTestCase):
response.json['error_message'])
def test_delete_ptp_instance_with_interfaces_failed(self):
interface = dbutils.create_test_interface(
ifname='fake0', ifclass=constants.INTERFACE_CLASS_PLATFORM,
forihostid=self.controller.id, ihost_uuid=self.controller.uuid)
ptp_interface = dbutils.create_test_ptp_interface(
interface_id=interface['id'],
ptp_instance_id=self.ptp_instance['id'])
ptp_instance_id=self.ptp_instance['id'],
ptp_instance_uuid=self.ptp_instance['uuid'])
self.assertEqual(self.ptp_instance['id'],
ptp_interface['ptp_instance_id'])

View File

@ -26,9 +26,12 @@ class BasePtpInterfaceTestCase(base.FunctionalTest, dbbase.BaseHostTestCase):
# Field that is known to exist for inputs and outputs
COMMON_FIELD = 'ptp_instance_uuid'
# Can perform API operations on thie object at a sublevel of host
# Can perform API operations on this object at a sublevel of host
HOST_PREFIX = '/ihosts'
# Can perform API operations on this object at a sublevel of interfaces
INTERFACE_PREFIX = '/iinterfaces'
def setUp(self):
super(BasePtpInterfaceTestCase, self).setUp()
self.controller = self._create_test_host(constants.CONTROLLER)
@ -47,16 +50,18 @@ class BasePtpInterfaceTestCase(base.FunctionalTest, dbbase.BaseHostTestCase):
def get_host_scoped_url(self, host_uuid):
return '%s/%s%s' % (self.HOST_PREFIX, host_uuid, self.API_PREFIX)
def get_host_scoped_url_interface(self, host_uuid, interface_uuid):
return '%s/%s%s?interface_uuid=%s' % (self.HOST_PREFIX,
host_uuid,
self.API_PREFIX,
interface_uuid)
def get_interface_scoped_url(self, interface_uuid):
return '%s/%s%s' % (self.INTERFACE_PREFIX, interface_uuid,
self.API_PREFIX)
def get_post_object(self, ptp_instance_uuid, name=None):
ptp_interface_db = dbutils.get_test_ptp_interface(
ptp_instance_uuid=ptp_instance_uuid, name=name)
return ptp_interface_db
def get_interface_url(self, interface_uuid):
return '%s/%s' % (self.INTERFACE_PREFIX, interface_uuid)
def get_post_object(self, ptp_instance_id, ptp_instance_uuid, name=None):
return dbutils.get_test_ptp_interface(
ptp_instance_id=ptp_instance_id,
ptp_instance_uuid=ptp_instance_uuid,
name=name)
class TestCreatePtpInterface(BasePtpInterfaceTestCase):
@ -64,21 +69,23 @@ class TestCreatePtpInterface(BasePtpInterfaceTestCase):
def setUp(self):
super(TestCreatePtpInterface, self).setUp()
def _create_ptp_interface_success(self, name, ptp_instance_uuid):
ptp_interface_db = self.get_post_object(ptp_instance_uuid, name)
def _create_ptp_interface_success(self, name, ptp_instance_id, ptp_instance_uuid):
ptp_interface_db = self.get_post_object(ptp_instance_id,
ptp_instance_uuid,
name)
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, name, ptp_instance_uuid,
def _create_ptp_interface_failed(self, name,
ptp_instance_id, ptp_instance_uuid,
status_code, error_message):
ptp_interface_db = self.get_post_object(ptp_instance_uuid, name)
ptp_interface_db = self.get_post_object(ptp_instance_id,
ptp_instance_uuid,
name)
response = self.post_json(self.API_PREFIX, ptp_interface_db,
headers=self.API_HEADERS,
expect_errors=True)
@ -87,48 +94,160 @@ class TestCreatePtpInterface(BasePtpInterfaceTestCase):
self.assertIn(error_message, response.json['error_message'])
def test_create_ptp_interface_ok(self):
self._create_ptp_interface_success('test', self.instance.uuid)
self._create_ptp_interface_success('test',
self.instance.id,
self.instance.uuid)
def test_create_ptp_interface_invalid_instance(self):
self._create_ptp_interface_failed(
'test',
'32dbb999-6c10-448d-aeca-964c50af6384',
status_code=http_client.NOT_FOUND,
error_message='No PTP instance with id 32dbb999-6c10-448d-aeca-964c50af6384 found.')
fake_id = 0
fake_uuid = '32dbb999-6c10-448d-aeca-964c50af6384'
error_message = 'No PTP instance with id %s found' % fake_uuid
self._create_ptp_interface_failed('test',
fake_id,
fake_uuid,
status_code=http_client.NOT_FOUND,
error_message=error_message)
class TestSetPtpInterface(BasePtpInterfaceTestCase):
class TestUpdatePtpInterface(BasePtpInterfaceTestCase):
uuid = None
def setUp(self):
super(TestSetPtpInterface, self).setUp()
super(TestUpdatePtpInterface, self).setUp()
ptp_interface = dbutils.create_test_ptp_interface(
ptp_instance_id=self.instance.id,
ptp_instance_uuid=self.instance.uuid)
self.uuid = ptp_interface['uuid']
def test_set_ptp_interface_to_interfaces(self):
# TODO
pass
def test_update_ptp_interface_add_parameter_ok(self):
ptp_parameter_1 = dbutils.create_test_ptp_parameter(
name='param1', value='value1')
ptp_parameter_2 = dbutils.create_test_ptp_parameter(
name='param2', value='value2')
response = self.patch_json(self.get_single_url(self.uuid),
[{'path': '/ptp_parameters/-',
'value': ptp_parameter_1['uuid'],
'op': 'add'},
{'path': '/ptp_parameters/-',
'value': ptp_parameter_2['uuid'],
'op': 'add'}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
def test_update_ptp_interface_add_parameter_failed_no_interface(self):
ptp_parameter = dbutils.create_test_ptp_parameter(name='name',
value='value')
fake_uuid = 'f4c56ddf-aef3-46ed-b9aa-126a1faafd40'
error_message = 'No PTP interface with id %s found.' % fake_uuid
response = self.patch_json(self.get_single_url(fake_uuid),
[{'path': '/ptp_parameters/-',
'value': ptp_parameter['uuid'],
'op': 'add'}],
headers=self.API_HEADERS,
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_update_ptp_interface_add_parameter_failed_no_param(self):
fake_uuid = 'f4c56ddf-aef3-46ed-b9aa-126a1faafd40'
error_message = 'No PTP parameter object found for %s' % fake_uuid
response = self.patch_json(self.get_single_url(self.uuid),
[{'path': '/ptp_parameters/-',
'value': fake_uuid,
'op': 'add'}],
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_update_ptp_interface_delete_parameter_ok(self):
ptp_parameter = dbutils.create_test_ptp_parameter(
name='param1', value='value1')
response = self.patch_json(self.get_single_url(self.uuid),
[{'path': '/ptp_parameters/-',
'value': ptp_parameter['uuid'],
'op': 'add'}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
response = self.patch_json(self.get_single_url(self.uuid),
[{'path': '/ptp_parameters/-',
'value': ptp_parameter['uuid'],
'op': 'remove'}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
class TestUnsetPtpInterface(BasePtpInterfaceTestCase):
class TestInterfacePtpInterface(BasePtpInterfaceTestCase):
def setUp(self):
super(TestUnsetPtpInterface, self).setUp()
super(TestInterfacePtpInterface, self).setUp()
def test_unset_ptp_interface_from_interfaces(self):
# TODO
pass
def _assign_interface_ptp_interface_success(self):
ptp_interface = dbutils.create_test_ptp_interface(
ptp_instance_id=self.instance.id,
ptp_instance_uuid=self.instance.uuid)
ptp_interface_id = ptp_interface['id']
response = self.patch_json(
self.get_interface_url(self.interface.uuid),
[{'path': '/ptp_interfaces/-',
'value': ptp_interface_id,
'op': 'add'}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
return ptp_interface_id
def test_interface_ptp_interface_assign_ok(self):
self._assign_interface_ptp_interface_success()
def test_interface_ptp_interface_assign_failed(self):
fake_id = 101
error_message = 'No PTP interface object with id %s' % fake_id
response = self.patch_json(
self.get_interface_url(self.interface.uuid),
[{'path': '/ptp_interfaces/-',
'value': fake_id,
'op': 'add'}],
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_interface_ptp_interface_remove_ok(self):
ptp_interface_id = self._assign_interface_ptp_interface_success()
response = self.patch_json(
self.get_interface_url(self.interface.uuid),
[{'path': '/ptp_interfaces/-',
'value': ptp_interface_id,
'op': 'remove'}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
class TestGetPtpInterface(BasePtpInterfaceTestCase):
def setUp(self):
super(TestGetPtpInterface, self).setUp()
self.test_ptp_interface = dbutils.create_test_ptp_interface(
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))
ptp_interface = dbutils.create_test_ptp_interface(
ptp_instance_id=self.instance.id,
ptp_instance_uuid=self.instance.uuid)
response = self.get_json(self.get_single_url(ptp_interface['uuid']))
self.assertIn(self.COMMON_FIELD, response)
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)
@ -139,28 +258,45 @@ class TestGetPtpInterface(BasePtpInterfaceTestCase):
class TestListPtpInterface(BasePtpInterfaceTestCase):
def setUp(self):
super(TestListPtpInterface, self).setUp()
self.test_instance_ptp4l = dbutils.create_test_ptp_instance(
name='ptp4lInstance',
service=constants.PTP_INSTANCE_TYPE_PTP4L)
self.test_instance_phc2sys = dbutils.create_test_ptp_instance(
name='phc2sysInstance',
service='phc2sys')
self.ptp4l_ptp_interface = dbutils.create_test_ptp_interface(
ptp_instance_id=self.test_instance_ptp4l.id)
self.phc2sys_ptp_interface = dbutils.create_test_ptp_interface(
ptp_instance_id=self.test_instance_phc2sys.id)
self.worker = self._create_test_host(constants.WORKER)
self._create_test_ptp_interfaces()
def test_list_ptp_interface_host(self):
# TODO
pass
def _create_test_ptp_interfaces(self):
for i in range(5):
ptp_interface = dbutils.create_test_ptp_interface(
ptp_instance_id=self.instance.id,
ptp_instance_uuid=self.instance.uuid)
response = self.patch_json(
self.get_interface_url(self.interface.uuid),
[{'path': '/ptp_interfaces/-',
'value': ptp_interface['id'],
'op': 'add'}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
def test_list_ptp_interface_interface(self):
# TODO
pass
def test_list_ptp_interface_all(self):
response = self.get_json(self.API_PREFIX)
for result in response[self.RESULT_KEY]:
self.assertIn(self.COMMON_FIELD, result)
def test_list_ptp_interface_empty(self):
# TODO
pass
response = self.get_json(self.get_host_scoped_url(self.worker.uuid))
self.assertEqual([], response[self.RESULT_KEY])
def test_list_ptp_interface_host(self):
response = self.get_json(
self.get_host_scoped_url(self.controller.uuid))
for result in response[self.RESULT_KEY]:
self.assertIn(self.controller.hostname, result['hostnames'])
def test_list_ptp_interface_interface(self):
response = self.get_json(
self.get_interface_scoped_url(self.interface.uuid))
interface_name = '%s/%s' % (self.controller.hostname,
self.interface.ifname)
for result in response[self.RESULT_KEY]:
self.assertIn(interface_name, result['interface_names'])
class TestDeletePtpInterface(BasePtpInterfaceTestCase):
@ -169,41 +305,61 @@ class TestDeletePtpInterface(BasePtpInterfaceTestCase):
python2 and python3 libraries may return different
content_type (None, or empty json) when NO_CONTENT returned.
"""
ptp_interface = None
uuid = None
def setUp(self):
super(TestDeletePtpInterface, self).setUp()
self.test_ptp_interface = dbutils.create_test_ptp_interface(
ptp_instance_id=self.instance.id)
self.ptp_interface = dbutils.create_test_ptp_interface(
ptp_instance_id=self.instance.id,
ptp_instance_uuid=self.instance.uuid)
self.uuid = self.ptp_interface['uuid']
def test_delete_ptp_interface(self):
response = self.delete(
self.get_single_url(self.test_ptp_interface.uuid),
headers=self.API_HEADERS)
def test_delete_ptp_interface_ok(self):
response = self.delete(self.get_single_url(self.uuid),
headers=self.API_HEADERS)
self.assertEqual(response.status_code, http_client.NO_CONTENT)
# Check the PTP interface was indeed removed
error_message = \
'No PTP interface with id %s found' % self.test_ptp_interface.uuid
response = self.get_json(
self.get_single_url(self.test_ptp_interface.uuid),
expect_errors=True)
'No PTP interface with id %s found' % self.uuid
response = self.get_json(self.get_single_url(self.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_interface_with_interface_failed(self):
# TODO
pass
response = self.patch_json(
self.get_interface_url(self.interface.uuid),
[{'path': '/ptp_interfaces/-',
'value': self.ptp_interface['id'],
'op': 'add'}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
response = self.delete(self.get_single_url(self.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 host interface',
response.json['error_message'])
def test_delete_ptp_interface_with_parameters_failed(self):
ptp_parameter = dbutils.create_test_ptp_parameter(
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_ownership['owner_uuid'])
response = self.delete(
self.get_single_url(self.test_ptp_interface.uuid),
headers=self.API_HEADERS, expect_errors=True)
response = self.patch_json(self.get_single_url(self.uuid),
[{'path': '/ptp_parameters/-',
'value': ptp_parameter['uuid'],
'op': 'add'}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
response = self.delete(self.get_single_url(self.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('has PTP parameter', response.json['error_message'])
self.assertIn('still associated with PTP parameter',
response.json['error_message'])

View File

@ -15,28 +15,19 @@ class BasePtpParameterTestCase(base.FunctionalTest, dbbase.BaseHostTestCase):
API_HEADERS = {'User-Agent': 'sysinv-test'}
# Prefix for the URL
PARAMETER_PREFIX = '/ptp_parameters'
API_PREFIX = '/ptp_parameters'
# Python table key for the list of results
PARAMETER_KEY = 'ptp_parameters'
RESULT_KEY = 'ptp_parameters'
# Field that is known to exist for inputs and outputs
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'
COMMON_FIELD = 'name'
# Can perform API operations on this object at a sublevel of PTP instances
PTP_INSTANCE_PREFIX = '/ptp_instances'
# Can perform API operations on this object at a sublevel of interfaces
INTERFACE_PREFIX = '/iinterfaces'
# Can perform API operations on this object at a sublevel of PTP interfaces
PTP_INTERFACE_PREFIX = '/ptp_interfaces'
def setUp(self):
super(BasePtpParameterTestCase, self).setUp()
@ -45,27 +36,25 @@ class BasePtpParameterTestCase(base.FunctionalTest, dbbase.BaseHostTestCase):
self.ptp_interfaces = self._create_test_ptp_interface(
self.ptp_instances)
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_single_url(self, ptp_parameter_uuid):
return '%s/%s' % (self.API_PREFIX, ptp_parameter_uuid)
def get_instance_scoped_url(self, ptp_instance_uuid):
return '%s/%s%s' % (self.PTP_INSTANCE_PREFIX, ptp_instance_uuid,
self.PARAMETER_PREFIX)
self.API_PREFIX)
def get_interface_scoped_url(self, interface_uuid):
return '%s/%s%s' % (self.INTERFACE_PREFIX, interface_uuid,
self.PARAMETER_PREFIX)
def get_interface_scoped_url(self, ptp_interface_uuid):
return '%s/%s%s' % (self.PTP_INTERFACE_PREFIX, ptp_interface_uuid,
self.API_PREFIX)
def get_post_parameter(self, name='test_parameter', value='test_value'):
return dbutils.get_test_ptp_parameter(name=name,
value=value)
def get_instance_url(self, ptp_instance_uuid):
return '%s/%s' % (self.PTP_INSTANCE_PREFIX, ptp_instance_uuid)
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)
def get_interface_url(self, ptp_interface_uuid):
return '%s/%s' % (self.PTP_INTERFACE_PREFIX, ptp_interface_uuid)
def get_post_object(self, name='test_parameter', value='test_value'):
return dbutils.get_test_ptp_parameter(name=name, value=value)
class TestCreatePtpParameter(BasePtpParameterTestCase):
@ -74,195 +63,35 @@ class TestCreatePtpParameter(BasePtpParameterTestCase):
def setUp(self):
super(TestCreatePtpParameter, self).setUp()
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)
dbutils.create_test_ptp_parameter(name=self.name, value=self.value)
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,
ptp_parameter_db = self.get_post_object(name=name, value=value)
response = self.post_json(self.API_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.PARAMETER_FIELD],
ptp_parameter_db[self.PARAMETER_FIELD])
self.assertEqual(response.json[self.COMMON_FIELD],
ptp_parameter_db[self.COMMON_FIELD])
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,
ptp_parameter_db = self.get_post_object(name=name, value=value)
response = self.post_json(self.API_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)
self.assertIn(error_message, response.json['error_message'])
def test_create_ptp_parameter_instance_ok(self):
def test_create_ptp_parameter_ok(self):
self._create_ptp_parameter_success(
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')
name='some-param', value='some-value')
def test_create_ptp_parameter_synonymous_ok(self):
self._create_ptp_parameter_success(
name=self.name, value='another-value')
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'
@ -272,44 +101,19 @@ class TestGetPtpParameter(BasePtpParameterTestCase):
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')
uuid = ptp_parameter['uuid']
response = self.get_json(self.get_parameter_url(uuid))
self.assertIn(self.PARAMETER_FIELD, response)
response = self.get_json(self.get_single_url(uuid))
self.assertIn(self.COMMON_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_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),
response = self.get_json(self.get_single_url(fake_uuid),
expect_errors=True)
self.assertEqual('application/json', response.content_type)
self.assertEqual(response.status_code, http_client.NOT_FOUND)
@ -319,63 +123,59 @@ class TestGetPtpParameter(BasePtpParameterTestCase):
class TestListPtpParameter(BasePtpParameterTestCase):
def setUp(self):
super(TestListPtpParameter, self).setUp()
self._create_test_ptp_parameters(
prefix='ptp',
type=constants.PTP_PARAMETER_OWNER_INSTANCE)
self._create_test_ptp_parameters(
prefix='iface',
type=constants.PTP_PARAMETER_OWNER_INTERFACE)
self._create_test_ptp_parameters()
def _create_test_ptp_parameters(self, prefix='test',
owner_uuid=None, type=None):
parameters = []
ownerships = []
def _create_test_ptp_parameters(self, prefix='test'):
param1 = dbutils.create_test_ptp_parameter(name='param1-name',
value='param1-value')
param2 = dbutils.create_test_ptp_parameter(name='param2-name',
value='param2-value')
response = self.patch_json(
self.get_instance_url(self.ptp_instances[0].uuid),
[{'path': '/ptp_parameters/-',
'value': param1['uuid'],
'op': 'add'},
{'path': '/ptp_parameters/-',
'value': param2['uuid'],
'op': 'add'}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
if not owner_uuid:
if type == constants.PTP_PARAMETER_OWNER_INSTANCE:
owner_uuid = self.ptp_instances[0].uuid
elif type == constants.PTP_PARAMETER_OWNER_INTERFACE:
owner_uuid = self.ptp_interfaces[0].uuid
else:
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)
parameters.append(parameter)
ownership = dbutils.create_test_ptp_ownership(
parameter_uuid=parameter['uuid'],
owner_uuid=owner_uuid)
ownerships.append(ownership)
return parameters, ownerships
param3 = dbutils.create_test_ptp_parameter(name='param3-name',
value='param3-value')
response = self.patch_json(
self.get_interface_url(self.ptp_interfaces[0].uuid),
[{'path': '/ptp_parameters/-',
'value': param3['uuid'],
'op': 'add'}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
def test_list_ptp_parameter_all(self):
response = self.get_json(self.PARAMETER_PREFIX)
for result in response[self.PARAMETER_KEY]:
self.assertIn(self.PARAMETER_FIELD, result)
response = self.get_json(self.API_PREFIX)
for result in response[self.RESULT_KEY]:
self.assertIn(self.COMMON_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.PARAMETER_KEY])
response = self.get_json(
self.get_instance_scoped_url(self.ptp_instances[1].uuid))
self.assertEqual([], response[self.RESULT_KEY])
def test_list_ptp_parameter_by_instance(self):
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']))
response = self.get_json(
self.get_instance_scoped_url(self.ptp_instances[0].uuid))
for result in response[self.RESULT_KEY]:
self.assertIn(self.ptp_instances[0].uuid, str(result['owners']))
self.assertNotIn(self.ptp_interfaces[0].uuid, str(result['owners']))
def test_list_ptp_parameter_by_interface(self):
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']))
response = self.get_json(
self.get_interface_scoped_url(self.ptp_interfaces[0].uuid))
for result in response[self.RESULT_KEY]:
self.assertIn(self.ptp_interfaces[0].uuid, str(result['owners']))
self.assertNotIn(self.ptp_instances[0].uuid, str(result['owners']))
class TestUpdatePtpParameter(BasePtpParameterTestCase):
@ -387,7 +187,7 @@ class TestUpdatePtpParameter(BasePtpParameterTestCase):
name='fake-param', value='fake-value')
uuid = ptp_parameter['uuid']
response = self.patch_json(self.get_parameter_url(uuid),
response = self.patch_json(self.get_single_url(uuid),
[{'path': '/value',
'value': 'changed-value',
'op': 'replace'}],
@ -396,7 +196,7 @@ class TestUpdatePtpParameter(BasePtpParameterTestCase):
self.assertEqual(response.status_code, http_client.OK)
# Check the parameter was indeed updated
response = self.get_json(self.get_parameter_url(uuid))
response = self.get_json(self.get_single_url(uuid))
self.assertEqual(response['value'], 'changed-value')
@ -406,36 +206,41 @@ class TestDeletePtpParameter(BasePtpParameterTestCase):
python2 and python3 libraries may return different
content_type (None, or empty json) when NO_CONTENT returned.
"""
ptp_parameter = None
uuid = None
def setUp(self):
super(TestDeletePtpParameter, self).setUp()
self.ptp_parameter = dbutils.create_test_ptp_parameter(
name='test-param', value='test-value')
self.uuid = self.ptp_parameter['uuid']
def test_delete_ptp_parameter_ok(self):
ptp_parameter = dbutils.create_test_ptp_parameter(
name='fake-param', value='fake-value')
uuid = ptp_parameter['uuid']
response = self.delete(self.get_parameter_url(uuid),
response = self.delete(self.get_single_url(self.uuid),
headers=self.API_HEADERS)
self.assertEqual(response.status_code, http_client.NO_CONTENT)
# Check the parameter was indeed removed
error_message = 'No PTP parameter with id %s found' % uuid
response = self.get_json(self.get_parameter_url(uuid),
error_message = 'No PTP parameter with id %s found' % self.uuid
response = self.get_json(self.get_single_url(self.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.patch_json(
self.get_interface_url(self.ptp_interfaces[0].uuid),
[{'path': '/ptp_parameters/-',
'value': self.uuid,
'op': 'add'}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
response = self.delete(self.get_parameter_url(uuid),
error_message = 'PTP parameter %s still in use' % self.uuid
response = self.delete(self.get_single_url(self.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'])
self.assertIn(error_message, response.json['error_message'])

View File

@ -464,7 +464,8 @@ class BaseHostTestCase(BaseSystemTestCase):
ptp_interfaces = []
for ptp_instance in ptp_instances:
ptp_interface = dbutils.create_test_ptp_interface(
ptp_instance_id=ptp_instance['id'])
ptp_instance_id=ptp_instance['id'],
ptp_instance_uuid=ptp_instance['uuid'])
ptp_interfaces.append(ptp_interface)
return ptp_interfaces

View File

@ -539,7 +539,6 @@ def create_test_ptp(**kw):
# Utility functions to create a PTP instance for testing
def get_test_ptp_instance(**kw):
instance = {
# 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)
@ -556,8 +555,9 @@ def create_test_ptp_instance(**kw):
# Create test ptp_interface object
def get_test_ptp_interface(**kw):
ptp_interface = {
'type': kw.get('type', constants.PTP_PARAMETER_OWNER_INTERFACE),
'ptp_instance_id': kw.get('ptp_instance_id'),
'ptp_instance_uuid': kw.get('ptp_instance_uuid', None),
'ptp_instance_uuid': kw.get('ptp_instance_uuid'),
'name': kw.get('name', None)
}
return ptp_interface
@ -584,48 +584,6 @@ def create_test_ptp_parameter(**kw):
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)
def get_test_ptp_instance_map(**kw):
map = {
'host_id': kw.get('host_id', None),
'ptp_instance_id': kw.get('ptp_instance_id', None)
}
return map
def create_test_ptp_instance_map(**kw):
map = get_test_ptp_instance_map(**kw)
dbapi = db_api.get_instance()
return dbapi.ptp_instance_set_host(map)
def get_test_ptp_interface_map(**kw):
map = {
'interface_id': kw.get('interface_id', None),
'ptp_interface_id': kw.get('ptp_interface_id', None)
}
return map
def create_test_ptp_interface_map(**kw):
map = get_test_ptp_interface_map(**kw)
dbapi = db_api.get_instance()
return dbapi.ptp_interface_set_interface(map)
# Create test dns object
def get_test_dns(**kw):
dns = {