Add vnflcm subscriptions APIs

This patch supports CLI of vnflcm subscriptions APIs.

They are as follows.
* vnflcm subsc create
* vnflcm subsc delete
* vnflcm subsc list
* vnflcm subsc show

The output message of "vnflcm delete" was also modified
to match "vnflcm subsc delete".

Implements: blueprint support-nfv-solv3-subscriptions
Implements: blueprint support-etsi-nfv-specs
Change-Id: I9a839a3d131afc80fec0c2bbaa30443798117e0d
This commit is contained in:
Ai Hamano 2022-07-19 15:21:43 +09:00
parent 5c643d007e
commit 21f60be225
8 changed files with 770 additions and 4 deletions

@ -103,6 +103,10 @@ openstack.tackerclient.v1 =
vnflcm_op_retry = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:RetryVnfLcmOp
vnflcm_op_list = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:ListVnfLcmOp
vnflcm_op_show = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:ShowVnfLcmOp
vnflcm_subsc_create = tackerclient.osc.v1.vnflcm.vnflcm_subsc:CreateLccnSubscription
vnflcm_subsc_delete = tackerclient.osc.v1.vnflcm.vnflcm_subsc:DeleteLccnSubscription
vnflcm_subsc_list = tackerclient.osc.v1.vnflcm.vnflcm_subsc:ListLccnSubscription
vnflcm_subsc_show = tackerclient.osc.v1.vnflcm.vnflcm_subsc:ShowLccnSubscription
vnflcm_versions = tackerclient.osc.common.vnflcm.vnflcm_versions:VnfLcmVersions
openstack.tackerclient.v2 =
vnflcm_create = tackerclient.osc.v1.vnflcm.vnflcm:CreateVnfLcm
@ -121,4 +125,8 @@ openstack.tackerclient.v2 =
vnflcm_op_retry = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:RetryVnfLcmOp
vnflcm_op_list = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:ListVnfLcmOp
vnflcm_op_show = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:ShowVnfLcmOp
vnflcm_subsc_create = tackerclient.osc.v1.vnflcm.vnflcm_subsc:CreateLccnSubscription
vnflcm_subsc_delete = tackerclient.osc.v1.vnflcm.vnflcm_subsc:DeleteLccnSubscription
vnflcm_subsc_list = tackerclient.osc.v1.vnflcm.vnflcm_subsc:ListLccnSubscription
vnflcm_subsc_show = tackerclient.osc.v1.vnflcm.vnflcm_subsc:ShowLccnSubscription
vnflcm_versions = tackerclient.osc.common.vnflcm.vnflcm_versions:VnfLcmVersions

@ -0,0 +1,114 @@
{
"filter": {
"vnfInstanceSubscriptionFilter": {
"vnfdIds": [
"dummy-vnfdId-1",
"dummy-vnfdId-2"
],
"vnfProductsFromProviders": [
{
"vnfProvider": "dummy-vnfProvider-1",
"vnfProducts": [
{
"vnfProductName": "dummy-vnfProductName-1-1",
"versions": [
{
"vnfSoftwareVersion": "1.0",
"vnfdVersions": ["1.0", "2.0"]
},
{
"vnfSoftwareVersion": "1.1",
"vnfdVersions": ["1.1", "2.1"]
}
]
},
{
"vnfProductName": "dummy-vnfProductName-1-2",
"versions": [
{
"vnfSoftwareVersion": "1.0",
"vnfdVersions": ["1.0", "2.0"]
},
{
"vnfSoftwareVersion": "1.1",
"vnfdVersions": ["1.1", "2.1"]
}
]
}
]
},
{
"vnfProvider": "dummy-vnfProvider-2",
"vnfProducts": [
{
"vnfProductName": "dummy-vnfProductName-2-1",
"versions": [
{
"vnfSoftwareVersion": "1.0",
"vnfdVersions": ["1.0", "2.0"]
},
{
"vnfSoftwareVersion": "1.1",
"vnfdVersions": ["1.1", "2.1"]
}
]
},
{
"vnfProductName": "dummy-vnfProductName-2-2",
"versions": [
{
"vnfSoftwareVersion": "1.0",
"vnfdVersions": ["1.0", "2.0"]
},
{
"vnfSoftwareVersion": "1.1",
"vnfdVersions": ["1.1", "2.1"]
}
]
}
]
}
],
"vnfInstanceIds": [
"dummy-vnfInstanceId-1",
"dummy-vnfInstanceId-2"
],
"vnfInstanceNames": [
"dummy-vnfInstanceName-1",
"dummy-vnfInstanceName-2"
]
},
"notificationTypes": [
"VnfLcmOperationOccurrenceNotification",
"VnfIdentifierCreationNotification",
"VnfIdentifierDeletionNotification"
],
"operationTypes": [
"INSTANTIATE",
"SCALE",
"TERMINATE",
"HEAL",
"MODIFY_INFO",
"CHANGE_EXT_CONN"
],
"operationStates": [
"COMPLETED",
"FAILED",
"FAILED_TEMP",
"PROCESSING",
"ROLLING_BACK",
"ROLLED_BACK",
"STARTING"
]
},
"callbackUri": "http://localhost:9990/notification/callback/test",
"authentication": {
"authType": [
"BASIC"
],
"paramsBasic": {
"password": "test_pass",
"userName": "test_user"
}
}
}

@ -347,7 +347,7 @@ class TerminateVnfLcm(command.Command):
result = client.delete_vnf_instance(parsed_args.vnf_instance)
if not result:
print(_("VNF Instance '%(id)s' deleted successfully") %
print(_("VNF Instance '%(id)s' is deleted successfully") %
{'id': parsed_args.vnf_instance})
def _wait_until_vnf_is_terminated(self, client, vnf_instance_id,
@ -420,7 +420,7 @@ class DeleteVnfLcm(command.Command):
print(_('All specified vnf instances are deleted '
'successfully'))
else:
print(_("Vnf instance '%s' deleted "
print(_("Vnf instance '%s' is deleted "
"successfully") % vnf_instances[0])

@ -0,0 +1,206 @@
# Copyright (C) 2022 Nippon Telegraph and Telephone Corporation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import json
import logging
import os
from osc_lib.command import command
from osc_lib import utils
from tackerclient.common import exceptions
from tackerclient.i18n import _
from tackerclient.osc import sdk_utils
from tackerclient.osc import utils as tacker_osc_utils
LOG = logging.getLogger(__name__)
_LCCN_SUBSCRIPTION_ID = 'subscription_id'
_MIXED_CASE_FIELDS = ['filter', 'callbackUri']
_FORMATTERS = {
'filter': tacker_osc_utils.FormatComplexDataColumn,
'_links': tacker_osc_utils.FormatComplexDataColumn
}
def _get_columns(lccn_subsc_obj):
column_map = {
'id': 'ID',
'filter': 'Filter',
'callbackUri': 'Callback URI',
'_links': 'Links'
}
return sdk_utils.get_osc_show_columns_for_sdk_resource(lccn_subsc_obj,
column_map)
def jsonfile2body(file_path):
if file_path is not None and os.access(file_path, os.R_OK) is False:
msg = _("File %s does not exist or user does not have read "
"privileges to it")
reason = msg % file_path
raise exceptions.InvalidInput(reason=reason)
try:
with open(file_path) as f:
body = json.load(f)
except (IOError, ValueError) as ex:
msg = _("Failed to load parameter file. Error: %s")
reason = msg % ex
raise exceptions.InvalidInput(reason=reason)
if not body:
reason = _('The parameter file is empty')
raise exceptions.InvalidInput(reason=reason)
return body
class CreateLccnSubscription(command.ShowOne):
_description = _("Create a new Lccn Subscription")
def get_parser(self, prog_name):
parser = super(CreateLccnSubscription, self).get_parser(prog_name)
parser.add_argument(
'create_request_file',
metavar="<param-file>",
help=_('Specify create request parameters in a json file.'))
return parser
def take_action(self, parsed_args):
client = self.app.client_manager.tackerclient
subsc = client.create_lccn_subscription(
jsonfile2body(parsed_args.create_request_file))
display_columns, columns = _get_columns(subsc)
data = utils.get_item_properties(sdk_utils.DictModel(subsc),
columns, formatters=_FORMATTERS,
mixed_case_fields=_MIXED_CASE_FIELDS)
return (display_columns, data)
class DeleteLccnSubscription(command.Command):
_description = _("Delete Lccn Subscription(s)")
def get_parser(self, prog_name):
parser = super(DeleteLccnSubscription, self).get_parser(prog_name)
parser.add_argument(
_LCCN_SUBSCRIPTION_ID,
metavar="<subscription-id>",
nargs="+",
help=_("Lccn Subscription ID(s) to delete"))
return parser
def take_action(self, parsed_args):
error_count = 0
client = self.app.client_manager.tackerclient
lccn_subscriptions = parsed_args.subscription_id
for lccn_subscription in lccn_subscriptions:
try:
client.delete_lccn_subscription(lccn_subscription)
except Exception as e:
error_count += 1
LOG.error(_("Failed to delete Lccn Subscription with "
"ID '%(subsc)s': %(e)s"),
{'subsc': lccn_subscription, 'e': e})
total = len(lccn_subscriptions)
if (error_count > 0):
msg = (_("Failed to delete %(error_count)s of %(total)s "
"Lccn Subscriptions.") % {'error_count': error_count,
'total': total})
raise exceptions.CommandError(message=msg)
else:
if total > 1:
print(_('All specified Lccn Subscriptions are deleted '
'successfully'))
else:
print(_("Lccn Subscription '%s' is deleted "
"successfully") % lccn_subscriptions[0])
class ListLccnSubscription(command.Lister):
_description = _("List Lccn Subscriptions")
def get_parser(self, program_name):
parser = super(ListLccnSubscription, self).get_parser(program_name)
parser.add_argument(
"--filter",
metavar="<filter>",
help=_("Attribute-based-filtering parameters"),
)
return parser
def get_attributes(self, exclude=None):
fields = [
{
"key": "id",
"value": "ID"
},
{
"key": "callbackUri",
"value": "Callback URI"
}
]
attributes = []
for field in fields:
attributes.extend([(field['key'], field['value'],
tacker_osc_utils.LIST_BOTH)])
return tuple(attributes)
def take_action(self, parsed_args):
params = {}
if parsed_args.filter:
params['filter'] = parsed_args.filter
client = self.app.client_manager.tackerclient
subscriptions = client.list_lccn_subscriptions(**params)
headers, columns = tacker_osc_utils.get_column_definitions(
self.get_attributes(), long_listing=True)
dictionary_properties = (utils.get_dict_properties(
s, columns, mixed_case_fields=_MIXED_CASE_FIELDS)
for s in subscriptions
)
return (headers, dictionary_properties)
class ShowLccnSubscription(command.ShowOne):
_description = _("Display Lccn Subscription details")
def get_parser(self, program_name):
parser = super(ShowLccnSubscription, self).get_parser(program_name)
parser.add_argument(
_LCCN_SUBSCRIPTION_ID,
metavar="<subscription-id>",
help=_('Lccn Subscription ID to display'))
return parser
def take_action(self, parsed_args):
client = self.app.client_manager.tackerclient
obj = client.show_lccn_subscription(parsed_args.subscription_id)
display_columns, columns = _get_columns(obj)
data = utils.get_item_properties(
sdk_utils.DictModel(obj),
columns, formatters=_FORMATTERS,
mixed_case_fields=_MIXED_CASE_FIELDS)
return (display_columns, data)

@ -420,7 +420,7 @@ class TestTerminateVnfLcm(TestVnfLcm):
self.assertIn(expected_message, actual_message)
if delete_vnf:
expected_message = ("VNF Instance '%s' deleted successfully"
expected_message = ("VNF Instance '%s' is deleted successfully"
% vnf_instance['id'])
self.assertIn(expected_message, actual_message)
@ -536,7 +536,7 @@ class TestDeleteVnfLcm(TestVnfLcm):
sys.stdout = buffer = StringIO()
result = self.delete_vnf_instance.take_action(parsed_args)
self.assertIsNone(result)
self.assertEqual(("Vnf instance '%s' deleted successfully")
self.assertEqual(("Vnf instance '%s' is deleted successfully")
% self.vnf_instances[0]['id'],
buffer.getvalue().strip())

@ -0,0 +1,209 @@
# Copyright (C) 2022 Nippon Telegraph and Telephone Corporation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import os
import sys
from io import StringIO
from tackerclient.common import exceptions
from tackerclient.osc import utils as tacker_osc_utils
from tackerclient.osc.v1.vnflcm import vnflcm_subsc
from tackerclient.tests.unit.osc import base
from tackerclient.tests.unit.osc.v1 import test_vnflcm
from tackerclient.tests.unit.osc.v1 import vnflcm_subsc_fakes
def _get_columns_vnflcm_subsc(action=None):
columns = ['ID', 'Filter', 'Callback URI', 'Links']
if action == 'list':
columns = [ele for ele in columns if ele not in
['Filter', 'Links']]
return columns
class TestCreateLccnSubscription(test_vnflcm.TestVnfLcm):
def setUp(self):
super(TestCreateLccnSubscription, self).setUp()
self.create_subscription = vnflcm_subsc.CreateLccnSubscription(
self.app, self.app_args, cmd_name='vnflcm subsc create')
def test_create_no_args(self):
self.assertRaises(base.ParserException, self.check_parser,
self.create_subscription, [], [])
def test_take_action(self):
subscription = vnflcm_subsc_fakes.lccn_subsc_response()
sample_param_file = ("./tackerclient/osc/v1/vnflcm/samples/"
"create_lccn_subscription_param_sample.json")
arglist = [sample_param_file]
verifylist = [('create_request_file', sample_param_file)]
# command param
parsed_args = self.check_parser(self.create_subscription,
arglist, verifylist)
self.requests_mock.register_uri(
'POST', os.path.join(self.url, 'vnflcm/v1/subscriptions'),
json=subscription, headers=self.header)
actual_columns, data = (self.create_subscription.take_action(
parsed_args))
headers, attributes = vnflcm_subsc._get_columns(subscription)
self.assertCountEqual(_get_columns_vnflcm_subsc(),
actual_columns)
self.assertListItemsEqual(vnflcm_subsc_fakes.get_subscription_data(
subscription, columns=attributes), data)
class TestListLccnSubscription(test_vnflcm.TestVnfLcm):
subscriptions = vnflcm_subsc_fakes.create_subscriptions(count=3)
def setUp(self):
super(TestListLccnSubscription, self).setUp()
self.list_subscription = vnflcm_subsc.ListLccnSubscription(
self.app, self.app_args, cmd_name='vnflcm subsc list')
def test_take_action(self):
parsed_args = self.check_parser(self.list_subscription, [], [])
self.requests_mock.register_uri(
'GET', os.path.join(self.url, 'vnflcm/v1/subscriptions'),
json=self.subscriptions, headers=self.header)
actual_columns, data = self.list_subscription.take_action(parsed_args)
headers, columns = tacker_osc_utils.get_column_definitions(
self.list_subscription.get_attributes(), long_listing=True)
expected_data = []
for subscription_obj in self.subscriptions:
expected_data.append(vnflcm_subsc_fakes.get_subscription_data(
subscription_obj, columns=columns, list_action=True))
self.assertCountEqual(_get_columns_vnflcm_subsc(action='list'),
actual_columns)
self.assertCountEqual(expected_data, list(data))
class TestShowLccnSubscription(test_vnflcm.TestVnfLcm):
def setUp(self):
super(TestShowLccnSubscription, self).setUp()
self.show_subscription = vnflcm_subsc.ShowLccnSubscription(
self.app, self.app_args, cmd_name='vnflcm subsc show')
def test_take_action(self):
subscription = vnflcm_subsc_fakes.lccn_subsc_response()
arglist = [subscription['id']]
verifylist = [('subscription_id', subscription['id'])]
# command param
parsed_args = self.check_parser(self.show_subscription, arglist,
verifylist)
self.requests_mock.register_uri(
'GET', os.path.join(self.url, 'vnflcm/v1/subscriptions',
subscription['id']),
json=subscription, headers=self.header)
columns, data = (self.show_subscription.take_action(parsed_args))
self.assertCountEqual(_get_columns_vnflcm_subsc(),
columns)
headers, attributes = vnflcm_subsc._get_columns(subscription)
self.assertListItemsEqual(
vnflcm_subsc_fakes.get_subscription_data(subscription,
columns=attributes),
data)
class TestDeleteLccnSubscription(test_vnflcm.TestVnfLcm):
subscriptions = vnflcm_subsc_fakes.create_subscriptions(count=3)
def setUp(self):
super(TestDeleteLccnSubscription, self).setUp()
self.delete_subscription = vnflcm_subsc.DeleteLccnSubscription(
self.app, self.app_args, cmd_name='vnflcm subsc delete')
def _mock_request_url_for_delete(self, subsc_index):
url = os.path.join(self.url, 'vnflcm/v1/subscriptions',
self.subscriptions[subsc_index]['id'])
json = self.subscriptions[subsc_index]
self.requests_mock.register_uri('GET', url, json=json,
headers=self.header)
self.requests_mock.register_uri('DELETE', url,
headers=self.header, json={})
def test_delete_one_subscription(self):
arglist = [self.subscriptions[0]['id']]
verifylist = [('subscription_id',
[self.subscriptions[0]['id']])]
parsed_args = self.check_parser(self.delete_subscription,
arglist, verifylist)
self._mock_request_url_for_delete(0)
sys.stdout = buffer = StringIO()
result = self.delete_subscription.take_action(parsed_args)
self.assertIsNone(result)
self.assertEqual(("Lccn Subscription '%s' is deleted successfully")
% self.subscriptions[0]['id'],
buffer.getvalue().strip())
def test_delete_multiple_subscription(self):
arglist = []
for subscription in self.subscriptions:
arglist.append(subscription['id'])
verifylist = [('subscription_id', arglist)]
parsed_args = self.check_parser(self.delete_subscription,
arglist, verifylist)
for i in range(0, 3):
self._mock_request_url_for_delete(i)
sys.stdout = buffer = StringIO()
result = self.delete_subscription.take_action(parsed_args)
self.assertIsNone(result)
self.assertEqual('All specified Lccn Subscriptions are deleted '
'successfully', buffer.getvalue().strip())
def test_delete_multiple_subscription_exception(self):
arglist = [
self.subscriptions[0]['id'],
'xxxx-yyyy-zzzz',
self.subscriptions[1]['id'],
]
verifylist = [('subscription_id', arglist)]
parsed_args = self.check_parser(self.delete_subscription,
arglist, verifylist)
self._mock_request_url_for_delete(0)
url = os.path.join(self.url, 'vnflcm/v1/subscriptions',
'xxxx-yyyy-zzzz')
self.requests_mock.register_uri(
'GET', url, exc=exceptions.ConnectionFailed)
self._mock_request_url_for_delete(1)
exception = self.assertRaises(exceptions.CommandError,
self.delete_subscription.take_action,
parsed_args)
self.assertEqual('Failed to delete 1 of 3 Lccn Subscriptions.',
exception.message)

@ -0,0 +1,190 @@
# Copyright (C) 2022 Nippon Telegraph and Telephone Corporation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_utils.fixture import uuidsentinel
from oslo_utils import uuidutils
from tackerclient.osc import utils as tacker_osc_utils
def lccn_subsc_response(attrs=None):
"""Create a fake subscription.
:param Dictionary attrs:
A dictionary with all attributes
:return:
A subscription dict
"""
attrs = attrs or {}
id = uuidsentinel.lccn_subsc_id
# Set default attributes.
dummy_subscription = {
"id": id,
"filter": {
"vnfInstanceSubscriptionFilter": {
"vnfdIds": [
"dummy-vnfdId-1",
"dummy-vnfdId-2"
],
"vnfProductsFromProviders": [
{
"vnfProvider": "dummy-vnfProvider-1",
"vnfProducts": [
{
"vnfProductName": "dummy-vnfProductName-1-1",
"versions": [
{
"vnfSoftwareVersion": "1.0",
"vnfdVersions": ["1.0", "2.0"]
},
{
"vnfSoftwareVersion": "1.1",
"vnfdVersions": ["1.1", "2.1"]
}
]
},
{
"vnfProductName": "dummy-vnfProductName-1-2",
"versions": [
{
"vnfSoftwareVersion": "1.0",
"vnfdVersions": ["1.0", "2.0"]
},
{
"vnfSoftwareVersion": "1.1",
"vnfdVersions": ["1.1", "2.1"]
}
]
}
]
},
{
"vnfProvider": "dummy-vnfProvider-2",
"vnfProducts": [
{
"vnfProductName": "dummy-vnfProductName-2-1",
"versions": [
{
"vnfSoftwareVersion": "1.0",
"vnfdVersions": ["1.0", "2.0"]
},
{
"vnfSoftwareVersion": "1.1",
"vnfdVersions": ["1.1", "2.1"]
}
]
},
{
"vnfProductName": "dummy-vnfProductName-2-2",
"versions": [
{
"vnfSoftwareVersion": "1.0",
"vnfdVersions": ["1.0", "2.0"]
},
{
"vnfSoftwareVersion": "1.1",
"vnfdVersions": ["1.1", "2.1"]
}
]
}
]
}
],
"vnfInstanceIds": [
"dummy-vnfInstanceId-1",
"dummy-vnfInstanceId-2"
],
"vnfInstanceNames": [
"dummy-vnfInstanceName-1",
"dummy-vnfInstanceName-2"
]
},
"notificationTypes": [
"VnfLcmOperationOccurrenceNotification",
"VnfIdentifierCreationNotification",
"VnfIdentifierDeletionNotification"
],
"operationTypes": [
"INSTANTIATE",
"SCALE",
"TERMINATE",
"HEAL",
"MODIFY_INFO",
"CHANGE_EXT_CONN"
],
"operationStates": [
"COMPLETED",
"FAILED",
"FAILED_TEMP",
"PROCESSING",
"ROLLING_BACK",
"ROLLED_BACK",
"STARTING"
]
},
"callbackUri": "http://localhost:9990/notification/callback/test",
"_links": {
"self": {
"href": "http://127.0.0.1:9890/vnflcm/v2/subscriptions/" + id
}
}
}
# Overwrite default attributes.
dummy_subscription.update(attrs)
return dummy_subscription
def get_subscription_data(subscription, list_action=False, columns=None):
"""Get the subscription data.
:return:
A tuple object sorted based on the name of the columns.
"""
complex_attributes = ['filter', '_links']
for attribute in complex_attributes:
if subscription.get(attribute):
subscription.update(
{attribute: tacker_osc_utils.FormatComplexDataColumn(
subscription[attribute])})
if list_action:
for item in ['filter', '_links']:
subscription.pop(item)
# return the list of data as per column order
if columns:
return tuple([subscription[key] for key in columns])
return tuple([subscription[key] for key in sorted(
subscription.keys())])
def create_subscriptions(count=2):
"""Create multiple fake subscriptions.
:param count: The number of subscriptions to fake
:return:
A list of fake subscriptions dictionary
"""
uri = "http://localhost:9990/notification/callback/"
subscriptions = []
for i in range(0, count):
unique_id = uuidutils.generate_uuid()
subscriptions.append(lccn_subsc_response(
attrs={'id': unique_id,
'callbackUri': uri + str(i)}))
return subscriptions

@ -895,6 +895,10 @@ class VnfLCMClient(ClientBase):
'/vnflcm/{}/vnf_lcm_op_occs'.format(sol_api_version))
self.vnf_lcm_op_occs_path = (
'/vnflcm/{}/vnf_lcm_op_occs/%s'.format(sol_api_version))
self.lccn_subscriptions_path = (
'/vnflcm/{}/subscriptions'.format(sol_api_version))
self.lccn_subscription_path = (
'/vnflcm/{}/subscriptions/%s'.format(sol_api_version))
def build_action(self, action):
return action
@ -992,6 +996,28 @@ class VnfLCMClient(ClientBase):
return self.get(self.vnf_lcm_op_occs_path % occ_id,
headers=self.headers)
@APIParamsCall
def create_lccn_subscription(self, body):
return self.post(self.lccn_subscriptions_path, body=body,
headers=self.headers)
@APIParamsCall
def delete_lccn_subscription(self, subsc_id):
return self.delete(self.lccn_subscription_path % subsc_id,
headers=self.headers)
@APIParamsCall
def list_lccn_subscriptions(self, retrieve_all=True, **_params):
subscriptions = self.list(None, self.lccn_subscriptions_path,
retrieve_all, headers=self.headers,
**_params)
return subscriptions
@APIParamsCall
def show_lccn_subscription(self, subsc_id):
return self.get(self.lccn_subscription_path % subsc_id,
headers=self.headers)
@APIParamsCall
def show_vnf_lcm_versions(self, major_version):
if major_version is None:
@ -1324,5 +1350,18 @@ class Client(object):
def show_vnf_lcm_op_occs(self, occ_id):
return self.vnf_lcm_client.show_vnf_lcm_op_occs(occ_id)
def create_lccn_subscription(self, body):
return self.vnf_lcm_client.create_lccn_subscription(body)
def delete_lccn_subscription(self, subsc_id):
return self.vnf_lcm_client.delete_lccn_subscription(subsc_id)
def list_lccn_subscriptions(self, retrieve_all=True, **_params):
return self.vnf_lcm_client.list_lccn_subscriptions(
retrieve_all=retrieve_all, **_params)
def show_lccn_subscription(self, subsc_id):
return self.vnf_lcm_client.show_lccn_subscription(subsc_id)
def show_vnf_lcm_versions(self, major_version):
return self.vnf_lcm_client.show_vnf_lcm_versions(major_version)