[PTP dual NIC config] Manage parameter life-cycle

Instead of having ptp-parameters being created/destroyed by specific
commands, they should be managed in the context of their owner's life-
cycle, i.e., being created when PTP instance or interface first set it
and removed when the last reference from owner is removed.

Bonus changes:
1. PTP interface commands use object name (complementary work for
https://review.opendev.org/c/starlingx/config/+/822545)
2. Assigning/removing PTP instance to/from host is moved to _patch_sys
(actually _patch locked with LOCK_NAME_SYS - minor pending issue from
https://review.opendev.org/c/starlingx/config/+/822200/comment/5d526f18_8125ead3/)
3. Removed mentions to database IDs in user messages, since he/she
cannot see that field in show/list commands

Test Plan:

PASS: Updated test cases with parameters created/destroyed in the
      context of other object operations;
PASS: Fresh install without -add & -delete commands for PTP parameters,
      new parameters created and removed in the context of PTP instance
      and/or PTP interface life-cycle operations.

Regression:

PASS: Unit test cases related to PTP configuration.

Story: 2009248
Task: 44287
Signed-off-by: Douglas Henrique Koerich <douglashenrique.koerich@windriver.com>
Change-Id: I2820a5340d95a9487f422bee0cad37b0adb50fd3
This commit is contained in:
Douglas Henrique Koerich 2022-01-13 15:10:45 -03:00
parent a37c216b8f
commit 948fd84492
17 changed files with 418 additions and 384 deletions

View File

@ -77,66 +77,47 @@ def do_ptp_instance_delete(cc, args):
print('Deleted PTP instance: %s' % uuid)
def _ptp_instance_parameter_op(cc, op, ptp_instance_uuid, data):
def _ptp_instance_parameter_op(cc, op, instance, parameters):
if len(parameters) == 0:
raise exc.CommandError('Missing PTP parameter')
ptp_instance = ptp_instance_utils._find_ptp_instance(cc, instance)
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)
for parameter in parameters:
patch.append({'op': op,
'path': '/ptp_parameters/-',
'value': parameter})
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")
@utils.arg('paramuuid',
metavar='<parameter UUID>',
@utils.arg('parameters',
metavar='<name=value>',
nargs='+',
action='append',
default=[],
help="UUID of PTP parameter")
help="PTP parameter to add")
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)
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)
_ptp_instance_parameter_op(cc, op='add', instance=args.nameoruuid,
parameters=args.parameters[0])
@utils.arg('nameoruuid',
metavar='<name or UUID>',
help="Name or UUID of PTP instance")
@utils.arg('paramuuid',
metavar='<parameter UUID>',
@utils.arg('parameters',
metavar='<name=value>',
nargs='+',
action='append',
default=[],
help="UUID of PTP parameter")
help="PTP parameter to remove")
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)
_ptp_instance_parameter_op(cc, op='remove', instance=args.nameoruuid,
parameters=args.parameters[0])
@utils.arg('hostnameorid',
@ -149,14 +130,14 @@ def do_host_ptp_instance_list(cc, args):
_print_ptp_instance_list(ptp_instances)
def _host_ptp_instance_op(cc, op, uuid, instance):
def _host_ptp_instance_op(cc, op, host, instance):
ihost = ihost_utils._find_ihost(cc, host)
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)
patch = [{'op': op, 'path': '/ptp_instances/-', 'value': ptp_instance.id}]
cc.ihost.update(ihost.uuid, patch)
ptp_instances = cc.ptp_instance.list_by_host(uuid)
ptp_instances = cc.ptp_instance.list_by_host(ihost.uuid)
_print_ptp_instance_list(ptp_instances)
@ -165,11 +146,10 @@ def _host_ptp_instance_op(cc, op, uuid, instance):
help="Name or ID of host")
@utils.arg('nameoruuid',
metavar='<name or UUID>',
help="Name or UUID of PTP instance")
help="Name or UUID of PTP instance to assign")
def do_host_ptp_instance_assign(cc, args):
"""Associate PTP instance(s) to host."""
ihost = ihost_utils._find_ihost(cc, args.hostnameorid)
_host_ptp_instance_op(cc, op='add', uuid=ihost.uuid,
_host_ptp_instance_op(cc, op='add', host=args.hostnameorid,
instance=args.nameoruuid)
@ -178,9 +158,8 @@ def do_host_ptp_instance_assign(cc, args):
help="Name or ID of host")
@utils.arg('nameoruuid',
metavar='<name or UUID>',
help="Name or UUID of PTP instance")
help="Name or UUID of PTP instance to remove")
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,
_host_ptp_instance_op(cc, op='remove', host=args.hostnameorid,
instance=args.nameoruuid)

View File

@ -11,7 +11,7 @@ from cgtsclient.common import utils
from cgtsclient import exc
from cgtsclient.v1 import options
CREATION_ATTRIBUTES = ['ptp_instance_uuid']
CREATION_ATTRIBUTES = ['name', 'ptp_instance_uuid']
class PtpInterface(base.Resource):
@ -64,8 +64,14 @@ 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)
raise exc.CommandError('PTP interface not found: %s' % key)
else:
return interface
else:
ptp_interfaces = cc.ptp_interface.list()
for interface in ptp_interfaces:
if interface.name == key:
return interface
else:
raise exc.CommandError('PTP interface not found: %s' % key)

View File

@ -15,28 +15,25 @@ from cgtsclient.v1 import ptp_interface as ptp_interface_utils
def _print_ptp_interface_show(ptp_interface_obj):
fields = ['uuid', 'interface_names', 'ptp_instance_name', 'parameters',
'created_at']
fields = ['uuid', 'name', 'interface_names', 'ptp_instance_name',
'parameters', 'created_at']
data = [(f, getattr(ptp_interface_obj, f, '')) for f in fields]
utils.print_tuple_list(data)
@utils.arg('ptp_interface_uuid',
metavar='<ptp_interface_uuid>',
help="UUID of a PTP interface")
@utils.arg('nameoruuid',
metavar='<name or UUID>',
help="Name or UUID of a PTP interface")
def do_ptp_interface_show(cc, args):
"""Show PTP interface attributes."""
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)
ptp_interface = ptp_interface_utils._find_ptp_interface(
cc, args.nameoruuid)
_print_ptp_interface_show(ptp_interface)
def _print_ptp_interface_list(ptp_interface_list):
field_labels = ['uuid', 'ptp_instance_name', 'parameters']
fields = ['uuid', 'ptp_instance_name', 'parameters']
field_labels = ['uuid', 'name', 'ptp_instance_name', 'parameters']
fields = ['uuid', 'name', 'ptp_instance_name', 'parameters']
utils.print_list(ptp_interface_list, fields, field_labels)
@ -46,20 +43,24 @@ def do_ptp_interface_list(cc, args):
_print_ptp_interface_list(ptp_interfaces)
@utils.arg('name',
metavar='<name>',
help="Name of PTP interface [REQUIRED]")
@utils.arg('ptpinstancenameorid',
metavar='<name or UUID>',
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 = ['ptp_instance_uuid']
ptp_instance = \
ptp_instance_utils._find_ptp_instance(cc, args.ptpinstancenameorid)
field_list = ['name']
# 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
# Check the PTP instance exists
ptp_instance = ptp_instance_utils._find_ptp_instance(
cc, args.ptpinstancenameorid)
data.update({'ptp_instance_uuid': ptp_instance.uuid})
ptp_interface = cc.ptp_interface.create(**data)
uuid = getattr(ptp_interface, 'uuid', '')
@ -71,73 +72,59 @@ def do_ptp_interface_add(cc, args):
_print_ptp_interface_show(ptp_interface)
@utils.arg('ptp_interface_uuid',
metavar='<ptp_interface_uuid>',
help="UUID of a PTP instance")
@utils.arg('nameoruuid',
metavar='<name or UUID>',
help="Name or UUID of PTP interface")
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)
ptp_interface = ptp_interface_utils._find_ptp_interface(
cc, args.nameoruuid)
uuid = ptp_interface.uuid
cc.ptp_interface.delete(uuid)
print('Deleted PTP interface: %s' % uuid)
def _ptp_interface_parameter_op(cc, op, ptp_interface_uuid, data):
def _ptp_interface_parameter_op(cc, op, interface, parameters):
if len(parameters) == 0:
raise exc.CommandError('Missing PTP parameter')
ptp_interface = ptp_interface_utils._find_ptp_interface(cc, interface)
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)
for parameter in parameters:
patch.append({'op': op,
'path': '/ptp_parameters/-',
'value': parameter})
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>',
@utils.arg('nameoruuid',
metavar='<name or UUID>',
help="Name or UUID of PTP interface")
@utils.arg('parameters',
metavar='<name=value>',
nargs='+',
action='append',
default=[],
help="UUID of PTP parameter")
help="PTP parameter to add")
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)
_ptp_interface_parameter_op(cc, op='add', interface=args.nameoruuid,
parameters=args.parameters[0])
@utils.arg('ptp_interface_uuid',
metavar='<UUID>',
help="UUID of PTP interface")
@utils.arg('paramuuid',
metavar='<parameter UUID>',
@utils.arg('nameoruuid',
metavar='<name or UUID>',
help="Name or UUID of PTP interface")
@utils.arg('parameters',
metavar='<name=value>',
nargs='+',
action='append',
default=[],
help="UUID of PTP parameter")
help="PTP parameter to remove")
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)
_ptp_interface_parameter_op(cc, op='remove', interface=args.nameoruuid,
parameters=args.parameters[0])
@utils.arg('hostnameorid',
@ -166,16 +153,18 @@ def do_host_if_ptp_list(cc, args):
utils.print_list(ptp_interfaces, fields, field_labels)
def _interface_ptp_op(cc, op, uuid, ptp_interface):
def _interface_ptp_op(cc, op, host, interface, ptp_interface):
ihost = ihost_utils._find_ihost(cc, host)
iinterface = iinterface_utils._find_interface(cc, ihost, 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)
cc.iinterface.update(iinterface.uuid, patch)
ptp_interfaces = cc.ptp_interface.list_by_interface(uuid)
ptp_interfaces = cc.ptp_interface.list_by_interface(iinterface.uuid)
_print_ptp_interface_list(ptp_interfaces)
@ -183,31 +172,29 @@ def _interface_ptp_op(cc, op, uuid, ptp_interface):
metavar='<hostname or id>',
help="The host associated with the PTP interface")
@utils.arg('ifnameorid',
metavar='<interface name or uuid>',
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")
@utils.arg('ptp_interface_nameoruuid',
metavar='<PTP interface name or UUID>',
help="Name or UUID of PTP interface to assign")
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)
_interface_ptp_op(cc, op='add', host=args.hostnameorid,
interface=args.ifnameorid,
ptp_interface=args.ptp_interface_nameoruuid)
@utils.arg('hostnameorid',
metavar='<hostname or id>',
help="The host associated with the PTP interface")
@utils.arg('ifnameorid',
metavar='<interface name or uuid>',
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")
@utils.arg('ptp_interface_nameoruuid',
metavar='<PTP interface name or UUID>',
help="Name or UUID of PTP interface to remove")
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)
_interface_ptp_op(cc, op='remove', host=args.hostnameorid,
interface=args.ifnameorid,
ptp_interface=args.ptp_interface_nameoruuid)

View File

@ -8,6 +8,8 @@
from cgtsclient.common import utils
from cgtsclient import exc
from cgtsclient.v1 import ptp_instance as ptp_instance_utils
from cgtsclient.v1 import ptp_interface as ptp_interface_utils
from cgtsclient.v1 import ptp_parameter as ptp_parameter_utils
@ -35,11 +37,11 @@ def _print_ptp_parameter_list(ptp_parameter_list):
@utils.arg('--instance',
metavar='<instance>',
default=None,
help="UUID of PTP instance")
help="Name or UUID of PTP instance")
@utils.arg('--interface',
metavar='<interface>',
default=None,
help="UUID of PTP interface")
help="Name or 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.
@ -48,42 +50,21 @@ def do_ptp_parameter_list(cc, args):
if args.interface:
raise exc.CommandError('Only a single optional argument allowed')
else:
ptp_parameters = cc.ptp_parameter.list_by_ptp_instance(
args.instance)
ptp_instance = ptp_instance_utils._find_ptp_instance(cc,
args.instance)
uuid = ptp_instance.uuid
ptp_parameters = cc.ptp_parameter.list_by_ptp_instance(uuid)
elif args.interface:
ptp_parameters = cc.ptp_parameter.list_by_ptp_interface(
args.interface)
ptp_interface = ptp_interface_utils._find_ptp_interface(cc,
args.interface)
uuid = ptp_interface.uuid
ptp_parameters = cc.ptp_parameter.list_by_ptp_interface(uuid)
else:
ptp_parameters = cc.ptp_parameter.list()
_print_ptp_parameter_list(ptp_parameters)
@utils.arg('name',
metavar='<name>',
help="Name of PTP parameter [REQUIRED]")
@utils.arg('value',
metavar='<value>',
help="Value of PTP parameter [REQUIRED]")
def do_ptp_parameter_add(cc, args):
"""Add a PTP parameter."""
field_list = ['name', 'value']
# 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_parameter = cc.ptp_parameter.create(**data)
uuid = getattr(ptp_parameter, 'uuid', '')
try:
ptp_parameter = cc.ptp_parameter.get(uuid)
except exc.HTTPNotFound:
raise exc.CommandError('PTP parameter just created not found: %s' %
uuid)
_print_ptp_parameter_show(ptp_parameter)
@utils.arg('uuid',
metavar='<uuid>',
help="UUID of PTP parameter")
@ -104,12 +85,3 @@ def do_ptp_parameter_modify(cc, args):
ptp_parameter = cc.ptp_parameter.update(args.uuid, patch)
_print_ptp_parameter_show(ptp_parameter)
@utils.arg('uuid',
metavar='<uuid>',
help="UUID of PTP parameter")
def do_ptp_parameter_delete(cc, args):
"""Delete a PTP parameter."""
cc.ptp_parameter.delete(args.uuid)
print('Deleted PTP parameter: %s' % args.uuid)

View File

@ -1825,15 +1825,14 @@ class HostController(rest.RestController):
path = p['path']
if path in optimize_list:
optimizable += 1
elif path == '/ptp_instances/-':
elif path == constants.PTP_INSTANCE_ARRAY_PATH:
has_ptp_instances = True
if has_ptp_instances:
return self._patch_ptp(uuid, patch)
elif len(patch) == optimizable:
if 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') or
has_ptp_instances):
return self._patch_sys(uuid, patch)
else:
return self._patch_gen(uuid, patch)
@ -1846,27 +1845,6 @@ 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
@ -1926,13 +1904,31 @@ class HostController(rest.RestController):
def _patch(self, uuid, patch):
log_start = cutils.timestamped("ihost_patch_start")
patch_obj = jsonpatch.JsonPatch(patch)
ihost_obj = objects.host.get_by_uuid(pecan.request.context, uuid)
ihost_dict = ihost_obj.as_dict()
self._block_add_host_semantic_checks(ihost_dict)
for p in patch:
if p['path'] == constants.PTP_INSTANCE_ARRAY_PATH:
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"))
values = {'host_id': ihost_obj.id,
'ptp_instance_id': ptp_instance_id}
if p.get('op') == constants.PTP_PATCH_OPERATION_ADD:
pecan.request.dbapi.ptp_instance_assign(values)
else:
pecan.request.dbapi.ptp_instance_remove(values)
# Remove from patch to apply the paths related to assigned PTP
# instances, since they don't actually patch the host object
patch.remove(p)
patch_obj = jsonpatch.JsonPatch(patch)
# Add transient fields that are not stored in the database
ihost_dict['bm_password'] = None

View File

@ -443,7 +443,7 @@ class InterfaceController(rest.RestController):
elif '/ports' == p['path']:
ports = p['value']
patches_to_remove.append(p)
elif '/ptp_interfaces/-' == p['path']:
elif constants.PTP_INTERFACE_ARRAY_PATH == p['path']:
has_ptp_interfaces = True
ptp_interface_id = p['value']
try:
@ -455,7 +455,7 @@ class InterfaceController(rest.RestController):
% ptp_interface_id))
values = {'interface_id': rpc_interface.id,
'ptp_interface_id': ptp_interface_id}
if p['op'] == 'add':
if p.get('op') == constants.PTP_PATCH_OPERATION_ADD:
pecan.request.dbapi.ptp_interface_assign(values)
else:
pecan.request.dbapi.ptp_interface_remove(values)

View File

@ -219,24 +219,51 @@ class PtpInstanceController(rest.RestController):
# (but not having both operations in same patch)
patch_list = list(jsonpatch.JsonPatch(patch))
for p in patch_list:
param_uuid = p['value']
param_adding = p.get('op') == constants.PTP_PATCH_OPERATION_ADD
param_keypair = p['value']
if param_keypair.find('=') < 0:
raise wsme.exc.ClientSideError(
_("Bad PTP parameter keypair: %s" % param_keypair))
(param_name, param_value) = param_keypair.split('=', 1)
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))
ptp_parameter = \
pecan.request.dbapi.ptp_parameter_get_by_namevalue(
param_name, param_value)
if p['op'] == 'add':
except exception.NotFound:
if not param_adding:
raise wsme.exc.ClientSideError(
_("No PTP parameter object found for %s"
% param_keypair))
# If PTP parameter doesn't exist yet, create it
param_dict = dict(name=param_name, value=param_value)
LOG.debug("PtpInstanceController.patch: creating parameter %s"
% param_keypair)
ptp_parameter = pecan.request.dbapi.ptp_parameter_create(
param_dict)
param_uuid = ptp_parameter.uuid
if param_adding:
pecan.request.dbapi.ptp_instance_parameter_add(uuid,
param_uuid)
LOG.debug("PtpInstanceController.patch: added %s to %s" %
(param_uuid, uuid))
(param_keypair, uuid))
else:
pecan.request.dbapi.ptp_instance_parameter_remove(uuid,
param_uuid)
LOG.debug("PtpInstanceController.patch: removed %s from %s" %
(param_uuid, uuid))
(param_keypair, uuid))
# If PTP parameter isn't owned by anyone else, remove it
param_owners = pecan.request.dbapi.ptp_parameter_get_owners(
param_uuid)
if len(param_owners) == 0:
LOG.debug(
"PtpInstanceController.patch: destroying unreferenced "
"parameter %s" % param_keypair)
pecan.request.dbapi.ptp_parameter_destroy(param_uuid)
return PtpInstance.convert_with_links(
objects.ptp_instance.get_by_uuid(pecan.request.context, uuid))

View File

@ -207,9 +207,11 @@ class PtpInterfaceController(rest.RestController):
ptp_interface_dict = ptp_interface.as_dict()
LOG.debug("PtpInterfaceController.post: %s" % ptp_interface_dict)
"""
TODO: enforce "name" as required field here
"""
# Check 'name' is set (wasn't set in object model for no-patchability
# constraints)
if ptp_interface_dict.get('name') is None:
raise wsme.exc.ClientSideError(
_("No name assigned to PTP interface"))
ptp_instance_uuid = ptp_interface_dict.pop('ptp_instance_uuid', None)
ptp_instance = objects.ptp_instance.get_by_uuid(pecan.request.context,
@ -243,20 +245,51 @@ class PtpInterfaceController(rest.RestController):
# (but not having both operations in same patch)
patch_list = list(jsonpatch.JsonPatch(patch))
for p in patch_list:
param_uuid = p['value']
param_adding = p.get('op') == constants.PTP_PATCH_OPERATION_ADD
param_keypair = p['value']
if param_keypair.find('=') < 0:
raise wsme.exc.ClientSideError(
_("Bad PTP parameter keypair: %s" % param_keypair))
(param_name, param_value) = param_keypair.split('=', 1)
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))
ptp_parameter = \
pecan.request.dbapi.ptp_parameter_get_by_namevalue(
param_name, param_value)
if p['op'] == 'add':
except exception.NotFound:
if not param_adding:
raise wsme.exc.ClientSideError(
_("No PTP parameter object found for %s"
% param_keypair))
# If PTP parameter doesn't exist yet, create it
param_dict = dict(name=param_name, value=param_value)
LOG.debug("PtpInterfaceController.patch: creating parameter %s"
% param_keypair)
ptp_parameter = pecan.request.dbapi.ptp_parameter_create(
param_dict)
param_uuid = ptp_parameter.uuid
if param_adding:
pecan.request.dbapi.ptp_interface_parameter_add(uuid,
param_uuid)
LOG.debug("PtpInterfaceController.patch: added %s to %s" %
(param_keypair, uuid))
else:
pecan.request.dbapi.ptp_interface_parameter_remove(uuid,
param_uuid)
LOG.debug("PtpInterfaceController.patch: removed %s from %s" %
(param_keypair, uuid))
# If PTP parameter isn't owned by anyone else, remove it
param_owners = pecan.request.dbapi.ptp_parameter_get_owners(
param_uuid)
if len(param_owners) == 0:
LOG.debug(
"PtpInterfaceController.patch: destroying unreferenced "
"parameter %s" % param_keypair)
pecan.request.dbapi.ptp_parameter_destroy(param_uuid)
return PtpInterface.convert_with_links(
objects.ptp_interface.get_by_uuid(pecan.request.context, uuid))

View File

@ -1872,6 +1872,13 @@ PTP_INSTANCE_DEFAULT_PHC2SYS = 'default-phc2sys'
PTP_PARAMETER_OWNER_INSTANCE = 'ptp-instance'
PTP_PARAMETER_OWNER_INTERFACE = 'ptp-interface'
# Patching PTP entities
PTP_INSTANCE_ARRAY_PATH = '/ptp_instances/-'
PTP_INTERFACE_ARRAY_PATH = '/ptp_interfaces/-'
PTP_PARAMETER_ARRAY_PATH = '/ptp_parameters/-'
PTP_PATCH_OPERATION_ADD = 'add'
PTP_PATCH_OPERATION_DELETE = 'remove'
# Backup & Restore
FIX_INSTALL_UUID_INTERVAL_SECS = 30

View File

@ -457,7 +457,7 @@ class PtpInstanceAlreadyExists(Conflict):
class PtpInterfaceAlreadyExists(Conflict):
message = _("A PTP interface with UUID %(uuid)s already exists.")
message = _("A PTP interface with name '%(name)s' already exists.")
class PtpParameterAlreadyExists(Conflict):
@ -469,12 +469,11 @@ class PtpParameterOwnershipAlreadyExists(Conflict):
class PtpInstanceMapAlreadyExists(Conflict):
message = _("PTP instance %(ptp_instance)s is already associated to host "
"%(host)s.")
message = _("PTP instance is already associated to host %(host)s.")
class PtpInterfaceMapAlreadyExists(Conflict):
message = _("PTP interface %(ptp_interface)s is already associated to "
message = _("PTP interface is already associated to "
"interface %(interface)s.")

View File

@ -2124,6 +2124,13 @@ class Connection(object):
:param ptp_interface_id: The id or uuid of a PTP interface association.
"""
@abc.abstractmethod
def ptp_interface_destroy_by_name(self, name):
"""Destroys a PTP interface association based on name.
:param name: The name given for a PTP interface.
"""
@abc.abstractmethod
def ptp_interface_map_get(self, ptp_interface_map_id):
"""Returns a PTP interface mapping.
@ -2154,6 +2161,15 @@ class Connection(object):
:returns: A PTP parameter.
"""
@abc.abstractmethod
def ptp_parameter_get_by_namevalue(self, name, value):
"""Returns the PTP parameter entry that matches the pair name-value.
:param name: Name of a PTP parameter.
:param value: Value of a PTP parameter.
:returns: A PTP parameter.
"""
@abc.abstractmethod
def ptp_parameters_get_list(self, ptp_instance=None, ptp_interface=None,
limit=None, marker=None, sort_key=None,

View File

@ -3783,7 +3783,6 @@ class Connection(api.Connection):
session.flush()
except db_exc.DBDuplicateEntry:
raise exception.PtpInstanceMapAlreadyExists(
ptp_instance=values['ptp_instance_id'],
host=values['host_id'])
query = model_query(models.PtpInstanceMaps)
@ -3865,7 +3864,7 @@ class Connection(api.Connection):
session.add(ptp_interface)
session.flush()
except db_exc.DBDuplicateEntry:
raise exception.PtpInterfaceAlreadyExists(uuid=values['uuid'])
raise exception.PtpInterfaceAlreadyExists(name=values['name'])
return self._ptp_interface_get(values['uuid'])
@objects.objectify(objects.ptp_interface)
@ -3913,7 +3912,6 @@ class Connection(api.Connection):
session.flush()
except db_exc.DBDuplicateEntry:
raise exception.PtpInterfaceMapAlreadyExists(
ptp_interface=values['ptp_interface_id'],
interface=values['interface_id'])
query = model_query(models.PtpInterfaceMaps)
@ -3956,6 +3954,16 @@ class Connection(api.Connection):
raise exception.PtpInterfaceNotFound(uuid=ptp_interface_id)
query.delete()
def ptp_interface_destroy_by_name(self, name):
with _session_for_write() as session:
query = model_query(models.PtpInterfaces, session=session)
query = query.filter_by(name=name)
try:
query.one()
except NoResultFound:
raise exception.NotFound()
query.delete()
@objects.objectify(objects.ptp_interface_map)
def ptp_interface_map_get(self, ptp_interface_map_id):
query = model_query(models.PtpInterfaceMaps)
@ -3991,6 +3999,15 @@ class Connection(api.Connection):
def ptp_parameter_get(self, ptp_parameter_id):
return self._ptp_parameter_get(ptp_parameter_id)
@objects.objectify(objects.ptp_parameter)
def ptp_parameter_get_by_namevalue(self, name, value):
query = model_query(models.PtpParameters)
query = query.filter_by(name=name, value=value)
try:
return query.one()
except NoResultFound:
raise exception.NotFound
@objects.objectify(objects.ptp_parameter)
def ptp_parameters_get_list(self, ptp_instance=None, ptp_interface=None,
limit=None, marker=None, sort_key=None,

View File

@ -103,65 +103,48 @@ class TestUpdatePtpInstance(BasePtpInstanceTestCase):
self.uuid = ptp_instance['uuid']
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)
response = self.patch_json(
self.get_single_url(self.uuid),
[{'path': constants.PTP_PARAMETER_ARRAY_PATH,
'value': 'param1=value1',
'op': constants.PTP_PATCH_OPERATION_ADD},
{'path': constants.PTP_PARAMETER_ARRAY_PATH,
'value': 'param2=value2',
'op': constants.PTP_PATCH_OPERATION_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)
response = self.patch_json(
self.get_single_url(fake_uuid),
[{'path': constants.PTP_PARAMETER_ARRAY_PATH,
'value': 'param0=value0',
'op': constants.PTP_PATCH_OPERATION_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)
response = self.patch_json(
self.get_single_url(self.uuid),
[{'path': constants.PTP_PARAMETER_ARRAY_PATH,
'value': 'param0=value0',
'op': constants.PTP_PATCH_OPERATION_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)
response = self.patch_json(
self.get_single_url(self.uuid),
[{'path': constants.PTP_PARAMETER_ARRAY_PATH,
'value': 'param0=value0',
'op': constants.PTP_PATCH_OPERATION_DELETE}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
@ -177,9 +160,9 @@ class TestHostPtpInstance(BasePtpInstanceTestCase):
ptp_instance_id = ptp_instance['id']
response = self.patch_json(
self.get_host_url(self.controller.uuid),
[{'path': '/ptp_instances/-',
[{'path': constants.PTP_INSTANCE_ARRAY_PATH,
'value': ptp_instance_id,
'op': 'add'}],
'op': constants.PTP_PATCH_OPERATION_ADD}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
@ -191,26 +174,25 @@ class TestHostPtpInstance(BasePtpInstanceTestCase):
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/-',
[{'path': constants.PTP_INSTANCE_ARRAY_PATH,
'value': fake_id,
'op': 'add'}],
'op': constants.PTP_PATCH_OPERATION_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'])
self.assertIn('No PTP instance object', 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/-',
[{'path': constants.PTP_INSTANCE_ARRAY_PATH,
'value': ptp_instance_id,
'op': 'remove'}],
'op': constants.PTP_PATCH_OPERATION_DELETE}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
@ -253,9 +235,9 @@ class TestListPtpInstance(BasePtpInstanceTestCase):
service=service)
response = self.patch_json(
self.get_host_url(self.controller.uuid),
[{'path': '/ptp_instances/-',
[{'path': constants.PTP_INSTANCE_ARRAY_PATH,
'value': instance['id'],
'op': 'add'}],
'op': constants.PTP_PATCH_OPERATION_ADD}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
@ -308,9 +290,9 @@ class TestDeletePtpInstance(BasePtpInstanceTestCase):
def test_delete_ptp_instance_with_host_failed(self):
response = self.patch_json(
self.get_host_url(self.controller.uuid),
[{'path': '/ptp_instances/-',
[{'path': constants.PTP_INSTANCE_ARRAY_PATH,
'value': self.ptp_instance['id'],
'op': 'add'}],
'op': constants.PTP_PATCH_OPERATION_ADD}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
@ -323,13 +305,12 @@ class TestDeletePtpInstance(BasePtpInstanceTestCase):
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')
response = self.patch_json(self.get_single_url(self.uuid),
[{'path': '/ptp_parameters/-',
'value': ptp_parameter['uuid'],
'op': 'add'}],
headers=self.API_HEADERS)
response = self.patch_json(
self.get_single_url(self.uuid),
[{'path': constants.PTP_PARAMETER_ARRAY_PATH,
'value': 'param0=value0',
'op': constants.PTP_PATCH_OPERATION_ADD}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
@ -342,6 +323,7 @@ class TestDeletePtpInstance(BasePtpInstanceTestCase):
def test_delete_ptp_instance_with_interfaces_failed(self):
ptp_interface = dbutils.create_test_ptp_interface(
name='test',
ptp_instance_id=self.ptp_instance['id'],
ptp_instance_uuid=self.ptp_instance['uuid'])
self.assertEqual(self.ptp_instance['id'],

View File

@ -65,11 +65,18 @@ class BasePtpInterfaceTestCase(base.FunctionalTest, dbbase.BaseHostTestCase):
class TestCreatePtpInterface(BasePtpInterfaceTestCase):
name = 'test'
def setUp(self):
super(TestCreatePtpInterface, self).setUp()
dbutils.create_test_ptp_interface(name=self.name,
ptp_instance_id=self.instance.id,
ptp_instance_uuid=self.instance.uuid)
def _create_ptp_interface_success(self, name, ptp_instance_id, ptp_instance_uuid):
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)
@ -94,20 +101,38 @@ 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._create_ptp_interface_success('fake',
self.instance.id,
self.instance.uuid)
def test_create_ptp_interface_unnamed(self):
error_message = 'No name assigned to PTP interface'
self._create_ptp_interface_failed(None,
self.instance.id,
self.instance.uuid,
status_code=http_client.BAD_REQUEST,
error_message=error_message)
def test_create_ptp_interface_invalid_instance(self):
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',
self._create_ptp_interface_failed('fake',
fake_id,
fake_uuid,
status_code=http_client.NOT_FOUND,
error_message=error_message)
def test_create_ptp_interface_duplicate_name(self):
error_message = \
"PTP interface with name '%s' already exists" % self.name
self._create_ptp_interface_failed(
self.name,
self.instance.id,
self.instance.uuid,
status_code=http_client.CONFLICT,
error_message=error_message)
class TestUpdatePtpInterface(BasePtpInterfaceTestCase):
uuid = None
@ -115,70 +140,54 @@ class TestUpdatePtpInterface(BasePtpInterfaceTestCase):
def setUp(self):
super(TestUpdatePtpInterface, self).setUp()
ptp_interface = dbutils.create_test_ptp_interface(
name='test',
ptp_instance_id=self.instance.id,
ptp_instance_uuid=self.instance.uuid)
self.uuid = ptp_interface['uuid']
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)
response = self.patch_json(
self.get_single_url(self.uuid),
[{'path': constants.PTP_PARAMETER_ARRAY_PATH,
'value': 'param1=value1',
'op': constants.PTP_PATCH_OPERATION_ADD},
{'path': constants.PTP_PARAMETER_ARRAY_PATH,
'value': 'param2=value2',
'op': constants.PTP_PATCH_OPERATION_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)
response = self.patch_json(
self.get_single_url(fake_uuid),
[{'path': constants.PTP_PARAMETER_ARRAY_PATH,
'value': 'param0=value0',
'op': constants.PTP_PATCH_OPERATION_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)
response = self.patch_json(
self.get_single_url(self.uuid),
[{'path': constants.PTP_PARAMETER_ARRAY_PATH,
'value': 'param0=value0',
'op': constants.PTP_PATCH_OPERATION_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)
response = self.patch_json(
self.get_single_url(self.uuid),
[{'path': constants.PTP_PARAMETER_ARRAY_PATH,
'value': 'param0=value0',
'op': constants.PTP_PATCH_OPERATION_DELETE}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
@ -189,14 +198,15 @@ class TestInterfacePtpInterface(BasePtpInterfaceTestCase):
def _assign_interface_ptp_interface_success(self):
ptp_interface = dbutils.create_test_ptp_interface(
name='test',
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/-',
[{'path': constants.PTP_INTERFACE_ARRAY_PATH,
'value': ptp_interface_id,
'op': 'add'}],
'op': constants.PTP_PATCH_OPERATION_ADD}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
@ -211,9 +221,9 @@ class TestInterfacePtpInterface(BasePtpInterfaceTestCase):
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/-',
[{'path': constants.PTP_INTERFACE_ARRAY_PATH,
'value': fake_id,
'op': 'add'}],
'op': constants.PTP_PATCH_OPERATION_ADD}],
headers=self.API_HEADERS,
expect_errors=True)
self.assertEqual('application/json', response.content_type)
@ -225,9 +235,9 @@ class TestInterfacePtpInterface(BasePtpInterfaceTestCase):
response = self.patch_json(
self.get_interface_url(self.interface.uuid),
[{'path': '/ptp_interfaces/-',
[{'path': constants.PTP_INTERFACE_ARRAY_PATH,
'value': ptp_interface_id,
'op': 'remove'}],
'op': constants.PTP_PATCH_OPERATION_DELETE}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
@ -239,6 +249,7 @@ class TestGetPtpInterface(BasePtpInterfaceTestCase):
def test_get_ptp_interface_found(self):
ptp_interface = dbutils.create_test_ptp_interface(
name='test',
ptp_instance_id=self.instance.id,
ptp_instance_uuid=self.instance.uuid)
response = self.get_json(self.get_single_url(ptp_interface['uuid']))
@ -263,14 +274,16 @@ class TestListPtpInterface(BasePtpInterfaceTestCase):
def _create_test_ptp_interfaces(self):
for i in range(5):
name = 'test%s' % i
ptp_interface = dbutils.create_test_ptp_interface(
name=name,
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/-',
[{'path': constants.PTP_INTERFACE_ARRAY_PATH,
'value': ptp_interface['id'],
'op': 'add'}],
'op': constants.PTP_PATCH_OPERATION_ADD}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
@ -311,6 +324,7 @@ class TestDeletePtpInterface(BasePtpInterfaceTestCase):
def setUp(self):
super(TestDeletePtpInterface, self).setUp()
self.ptp_interface = dbutils.create_test_ptp_interface(
name='test',
ptp_instance_id=self.instance.id,
ptp_instance_uuid=self.instance.uuid)
self.uuid = self.ptp_interface['uuid']
@ -332,9 +346,9 @@ class TestDeletePtpInterface(BasePtpInterfaceTestCase):
def test_delete_ptp_interface_with_interface_failed(self):
response = self.patch_json(
self.get_interface_url(self.interface.uuid),
[{'path': '/ptp_interfaces/-',
[{'path': constants.PTP_INTERFACE_ARRAY_PATH,
'value': self.ptp_interface['id'],
'op': 'add'}],
'op': constants.PTP_PATCH_OPERATION_ADD}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
@ -347,13 +361,12 @@ class TestDeletePtpInterface(BasePtpInterfaceTestCase):
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')
response = self.patch_json(self.get_single_url(self.uuid),
[{'path': '/ptp_parameters/-',
'value': ptp_parameter['uuid'],
'op': 'add'}],
headers=self.API_HEADERS)
response = self.patch_json(
self.get_single_url(self.uuid),
[{'path': constants.PTP_PARAMETER_ARRAY_PATH,
'value': 'param0=value0',
'op': constants.PTP_PATCH_OPERATION_ADD}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)

View File

@ -126,29 +126,23 @@ class TestListPtpParameter(BasePtpParameterTestCase):
self._create_test_ptp_parameters()
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'}],
[{'path': constants.PTP_PARAMETER_ARRAY_PATH,
'value': 'param1=value1',
'op': constants.PTP_PATCH_OPERATION_ADD},
{'path': constants.PTP_PARAMETER_ARRAY_PATH,
'value': 'param2=value2',
'op': constants.PTP_PATCH_OPERATION_ADD}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
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'}],
[{'path': constants.PTP_PARAMETER_ARRAY_PATH,
'value': 'param3=value3',
'op': constants.PTP_PATCH_OPERATION_ADD}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)
@ -168,7 +162,8 @@ class TestListPtpParameter(BasePtpParameterTestCase):
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']))
self.assertNotIn(self.ptp_interfaces[0].uuid,
str(result['owners']))
def test_list_ptp_parameter_by_interface(self):
response = self.get_json(
@ -208,11 +203,13 @@ class TestDeletePtpParameter(BasePtpParameterTestCase):
"""
ptp_parameter = None
uuid = None
name = 'test-param'
value = 'test-value'
def setUp(self):
super(TestDeletePtpParameter, self).setUp()
self.ptp_parameter = dbutils.create_test_ptp_parameter(
name='test-param', value='test-value')
name=self.name, value=self.value)
self.uuid = self.ptp_parameter['uuid']
def test_delete_ptp_parameter_ok(self):
@ -229,11 +226,12 @@ class TestDeletePtpParameter(BasePtpParameterTestCase):
self.assertIn(error_message, response.json['error_message'])
def test_delete_ptp_parameter_with_owner_failed(self):
value = '%s=%s' % (self.name, self.value)
response = self.patch_json(
self.get_interface_url(self.ptp_interfaces[0].uuid),
[{'path': '/ptp_parameters/-',
'value': self.uuid,
'op': 'add'}],
[{'path': constants.PTP_PARAMETER_ARRAY_PATH,
'value': value,
'op': constants.PTP_PATCH_OPERATION_ADD}],
headers=self.API_HEADERS)
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.status_code, http_client.OK)

View File

@ -463,7 +463,9 @@ class BaseHostTestCase(BaseSystemTestCase):
ptp_instances):
ptp_interfaces = []
for ptp_instance in ptp_instances:
name = 'test%s' % ptp_instances.index(ptp_instance)
ptp_interface = dbutils.create_test_ptp_interface(
name=name,
ptp_instance_id=ptp_instance['id'],
ptp_instance_uuid=ptp_instance['uuid'])
ptp_interfaces.append(ptp_interface)

View File

@ -556,9 +556,9 @@ def create_test_ptp_instance(**kw):
def get_test_ptp_interface(**kw):
ptp_interface = {
'type': kw.get('type', constants.PTP_PARAMETER_OWNER_INTERFACE),
'name': kw.get('name'),
'ptp_instance_id': kw.get('ptp_instance_id'),
'ptp_instance_uuid': kw.get('ptp_instance_uuid'),
'name': kw.get('name', None)
'ptp_instance_uuid': kw.get('ptp_instance_uuid')
}
return ptp_interface