Merge "OSC support to instantiate and show vnf"
This commit is contained in:
@@ -84,6 +84,8 @@ openstack.tackerclient.v1 =
|
|||||||
vnf_package_upload = tackerclient.osc.v1.vnfpkgm.vnf_package:UploadVnfPackage
|
vnf_package_upload = tackerclient.osc.v1.vnfpkgm.vnf_package:UploadVnfPackage
|
||||||
vnf_package_delete = tackerclient.osc.v1.vnfpkgm.vnf_package:DeleteVnfPackage
|
vnf_package_delete = tackerclient.osc.v1.vnfpkgm.vnf_package:DeleteVnfPackage
|
||||||
vnflcm_create = tackerclient.osc.v1.vnflcm.vnflcm:CreateVnfLcm
|
vnflcm_create = tackerclient.osc.v1.vnflcm.vnflcm:CreateVnfLcm
|
||||||
|
vnflcm_show = tackerclient.osc.v1.vnflcm.vnflcm:ShowVnfLcm
|
||||||
|
vnflcm_instantiate = tackerclient.osc.v1.vnflcm.vnflcm:InstantiateVnfLcm
|
||||||
|
|
||||||
[build_releasenotes]
|
[build_releasenotes]
|
||||||
all_files = 1
|
all_files = 1
|
||||||
|
@@ -0,0 +1,79 @@
|
|||||||
|
{
|
||||||
|
"flavourId":"simple",
|
||||||
|
"instantiationLevelId":"instantiation_level_1",
|
||||||
|
"extVirtualLinks":[
|
||||||
|
{
|
||||||
|
"id":"ext-vl-uuid-VL1",
|
||||||
|
"vimConnectionId":"vim-uuid",
|
||||||
|
"resourceProviderId":"resource-provider-id",
|
||||||
|
"resourceId":"neutron-network-uuid_VL1",
|
||||||
|
"extCps":[
|
||||||
|
{
|
||||||
|
"cpdId":"CP1",
|
||||||
|
"cpConfig":[
|
||||||
|
{
|
||||||
|
"cpInstanceId":"cp-instance-id",
|
||||||
|
"linkPortId":"link-port-uuid_CP1",
|
||||||
|
"cpProtocolData":[
|
||||||
|
{
|
||||||
|
"layerProtocol":"IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet":{
|
||||||
|
"macAddress":"00:25:96:FF:FE:12:34:56",
|
||||||
|
"ipAddresses":[
|
||||||
|
{
|
||||||
|
"addressRange":{
|
||||||
|
"minAddress":"192.168.11.01",
|
||||||
|
"maxAddress":"192.168.21.201"
|
||||||
|
},
|
||||||
|
"subnetId":"neutron-subnet-uuid_CP1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"extLinkPorts":[
|
||||||
|
{
|
||||||
|
"id":"link-port-uuid_CP1",
|
||||||
|
"resourceHandle":{
|
||||||
|
"vimConnectionId":"vim-uuid",
|
||||||
|
"resourceProviderId":"resource-provider-id",
|
||||||
|
"resourceId":"neutron-port-uuid_CP1",
|
||||||
|
"vimLevelResourceType":"LINKPORT"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"extManagedVirtualLinks":[
|
||||||
|
{
|
||||||
|
"id":"extMngVLnk-uuid_VL3",
|
||||||
|
"vnfVirtualLinkDescId":"VL3",
|
||||||
|
"vimConnectionId":"vim-uuid",
|
||||||
|
"resourceProviderId":"resource-provider-id",
|
||||||
|
"resourceId":"neutron-network-uuid_VL3"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"vimConnectionInfo":[
|
||||||
|
{
|
||||||
|
"id":"vim-uuid",
|
||||||
|
"vimId":"dummy-vimid",
|
||||||
|
"vimType":"ETSINFV.OPENSTACK_KEYSTONE.v_2",
|
||||||
|
"interfaceInfo":{
|
||||||
|
"key1":"value1",
|
||||||
|
"key2":"value2"
|
||||||
|
},
|
||||||
|
"accessInfo":{
|
||||||
|
"key1":"value1",
|
||||||
|
"key2":"value2"
|
||||||
|
},
|
||||||
|
"extra":{
|
||||||
|
"key1":"value1",
|
||||||
|
"key2":"value2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@@ -13,18 +13,29 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
|
from osc_lib.cli import format_columns
|
||||||
from osc_lib.command import command
|
from osc_lib.command import command
|
||||||
from osc_lib import utils
|
from osc_lib import utils
|
||||||
|
|
||||||
|
from tackerclient.common import exceptions
|
||||||
from tackerclient.i18n import _
|
from tackerclient.i18n import _
|
||||||
from tackerclient.osc import sdk_utils
|
from tackerclient.osc import sdk_utils
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
_mixed_case_fields = ('vnfInstanceName', 'vnfInstanceDescription', 'vnfdId',
|
_mixed_case_fields = ('vnfInstanceName', 'vnfInstanceDescription', 'vnfdId',
|
||||||
'vnfProvider', 'vnfProductName', 'vnfSoftwareVersion',
|
'vnfProvider', 'vnfProductName', 'vnfSoftwareVersion',
|
||||||
'vnfdVersion', 'instantiationState')
|
'vnfdVersion', 'instantiationState',
|
||||||
|
'vimConnectionInfo', 'instantiatedVnfInfo')
|
||||||
|
|
||||||
|
_VNF_INSTANCE = 'vnf_instance'
|
||||||
|
|
||||||
|
|
||||||
def _get_columns(item):
|
def _get_columns(vnflcm_obj, action=None):
|
||||||
column_map = {
|
column_map = {
|
||||||
'id': 'ID',
|
'id': 'ID',
|
||||||
'vnfInstanceName': 'VNF Instance Name',
|
'vnfInstanceName': 'VNF Instance Name',
|
||||||
@@ -35,9 +46,19 @@ def _get_columns(item):
|
|||||||
'vnfSoftwareVersion': 'VNF Software Version',
|
'vnfSoftwareVersion': 'VNF Software Version',
|
||||||
'vnfdVersion': 'VNFD Version',
|
'vnfdVersion': 'VNFD Version',
|
||||||
'instantiationState': 'Instantiation State',
|
'instantiationState': 'Instantiation State',
|
||||||
'links': 'Links',
|
'_links': 'Links',
|
||||||
}
|
}
|
||||||
return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map)
|
if action == 'show':
|
||||||
|
if vnflcm_obj['instantiationState'] == 'INSTANTIATED':
|
||||||
|
column_map.update(
|
||||||
|
{'instantiatedVnfInfo': 'Instantiated Vnf Info'}
|
||||||
|
)
|
||||||
|
column_map.update(
|
||||||
|
{'vimConnectionInfo': 'VIM Connection Info',
|
||||||
|
'_links': 'Links'}
|
||||||
|
)
|
||||||
|
return sdk_utils.get_osc_show_columns_for_sdk_resource(vnflcm_obj,
|
||||||
|
column_map)
|
||||||
|
|
||||||
|
|
||||||
class CreateVnfLcm(command.ShowOne):
|
class CreateVnfLcm(command.ShowOne):
|
||||||
@@ -58,10 +79,19 @@ class CreateVnfLcm(command.ShowOne):
|
|||||||
'--description',
|
'--description',
|
||||||
metavar="<vnf-instance-description>",
|
metavar="<vnf-instance-description>",
|
||||||
help=_('Description of the VNF instance to be created.'))
|
help=_('Description of the VNF instance to be created.'))
|
||||||
|
parser.add_argument(
|
||||||
|
'--I',
|
||||||
|
metavar="<param-file>",
|
||||||
|
help=_("Instantiate VNF subsequently after it's creation. "
|
||||||
|
"Specify instantiate request parameters in a json file."))
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def args2body(self, parsed_args):
|
def args2body(self, parsed_args, file_path=None):
|
||||||
body = {}
|
body = {}
|
||||||
|
|
||||||
|
if file_path:
|
||||||
|
return instantiate_vnf_args2body(file_path)
|
||||||
|
|
||||||
body['vnfdId'] = parsed_args.vnfd_id
|
body['vnfdId'] = parsed_args.vnfd_id
|
||||||
|
|
||||||
if parsed_args.description:
|
if parsed_args.description:
|
||||||
@@ -75,8 +105,84 @@ class CreateVnfLcm(command.ShowOne):
|
|||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
client = self.app.client_manager.tackerclient
|
client = self.app.client_manager.tackerclient
|
||||||
vnf = client.create_vnf_instance(self.args2body(parsed_args))
|
vnf = client.create_vnf_instance(self.args2body(parsed_args))
|
||||||
|
if parsed_args.I:
|
||||||
|
# Instantiate VNF instance.
|
||||||
|
result = client.instantiate_vnf_instance(
|
||||||
|
vnf['id'],
|
||||||
|
self.args2body(parsed_args, file_path=parsed_args.I))
|
||||||
|
if not result:
|
||||||
|
print((_('VNF Instance %(id)s is created and instantiation'
|
||||||
|
' request has been accepted.') % {'id': vnf['id']}))
|
||||||
display_columns, columns = _get_columns(vnf)
|
display_columns, columns = _get_columns(vnf)
|
||||||
data = utils.get_item_properties(
|
data = utils.get_item_properties(
|
||||||
sdk_utils.DictModel(vnf),
|
sdk_utils.DictModel(vnf),
|
||||||
columns, mixed_case_fields=_mixed_case_fields)
|
columns, mixed_case_fields=_mixed_case_fields)
|
||||||
return (display_columns, data)
|
return (display_columns, data)
|
||||||
|
|
||||||
|
|
||||||
|
class ShowVnfLcm(command.ShowOne):
|
||||||
|
_description = _("Display VNF instance details")
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(ShowVnfLcm, self).get_parser(prog_name)
|
||||||
|
parser.add_argument(
|
||||||
|
_VNF_INSTANCE,
|
||||||
|
metavar="<vnf-instance>",
|
||||||
|
help=_("VNF instance ID to display"))
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
client = self.app.client_manager.tackerclient
|
||||||
|
obj = client.show_vnf_instance(parsed_args.vnf_instance)
|
||||||
|
display_columns, columns = _get_columns(obj, action='show')
|
||||||
|
data = utils.get_item_properties(
|
||||||
|
sdk_utils.DictModel(obj),
|
||||||
|
columns, mixed_case_fields=_mixed_case_fields,
|
||||||
|
formatters={'instantiatedVnfInfo': format_columns.DictColumn})
|
||||||
|
return (display_columns, data)
|
||||||
|
|
||||||
|
|
||||||
|
def instantiate_vnf_args2body(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")
|
||||||
|
raise exceptions.InvalidInput(msg % file_path)
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(file_path) as f:
|
||||||
|
body = json.load(f)
|
||||||
|
except (IOError, ValueError) as ex:
|
||||||
|
msg = _("Failed to load parameter file. Error: %s")
|
||||||
|
raise exceptions.InvalidInput(msg % ex)
|
||||||
|
|
||||||
|
if not body:
|
||||||
|
raise exceptions.InvalidInput(_('The parameter file is empty'))
|
||||||
|
|
||||||
|
return body
|
||||||
|
|
||||||
|
|
||||||
|
class InstantiateVnfLcm(command.Command):
|
||||||
|
_description = _("Instantiate a VNF Instance")
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(InstantiateVnfLcm, self).get_parser(prog_name)
|
||||||
|
parser.add_argument(
|
||||||
|
_VNF_INSTANCE,
|
||||||
|
metavar="<vnf-instance>",
|
||||||
|
help=_("VNF instance ID to instantiate"))
|
||||||
|
parser.add_argument(
|
||||||
|
'instantiation_request_file',
|
||||||
|
metavar="<param-file>",
|
||||||
|
help=_('Specify instantiate request parameters in a json file.'))
|
||||||
|
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
client = self.app.client_manager.tackerclient
|
||||||
|
result = client.instantiate_vnf_instance(
|
||||||
|
parsed_args.vnf_instance, instantiate_vnf_args2body(
|
||||||
|
parsed_args.instantiation_request_file))
|
||||||
|
if not result:
|
||||||
|
print((_('Instantiate request for VNF Instance %(id)s has been'
|
||||||
|
' accepted.') % {'id': parsed_args.vnf_instance}))
|
||||||
|
@@ -14,15 +14,19 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import ddt
|
import ddt
|
||||||
|
from io import StringIO
|
||||||
import mock
|
import mock
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
from oslo_utils.fixture import uuidsentinel
|
from oslo_utils.fixture import uuidsentinel
|
||||||
|
|
||||||
|
from tackerclient.common import exceptions
|
||||||
from tackerclient.osc.v1.vnflcm import vnflcm
|
from tackerclient.osc.v1.vnflcm import vnflcm
|
||||||
from tackerclient.tests.unit.osc import base
|
from tackerclient.tests.unit.osc import base
|
||||||
from tackerclient.tests.unit.osc.v1.fixture_data import client
|
from tackerclient.tests.unit.osc.v1.fixture_data import client
|
||||||
from tackerclient.tests.unit.osc.v1 import vnflcm_fakes
|
from tackerclient.tests.unit.osc.v1 import vnflcm_fakes
|
||||||
|
from tackerclient.v1_0 import client as proxy_client
|
||||||
|
|
||||||
|
|
||||||
class TestVnfLcm(base.FixturedTestCase):
|
class TestVnfLcm(base.FixturedTestCase):
|
||||||
@@ -38,10 +42,12 @@ class TestVnfLcm(base.FixturedTestCase):
|
|||||||
self.app.client_manager.tackerclient = self.client_manager
|
self.app.client_manager.tackerclient = self.client_manager
|
||||||
|
|
||||||
|
|
||||||
def _get_columns_vnflcm():
|
def _get_columns_vnflcm(action='create'):
|
||||||
columns = ['ID', 'Instantiation State', 'VNF Instance Description',
|
columns = ['ID', 'Instantiation State', 'VNF Instance Description',
|
||||||
'VNF Instance Name', 'VNF Product Name', 'VNF Provider',
|
'VNF Instance Name', 'VNF Product Name', 'VNF Provider',
|
||||||
'VNF Software Version', 'VNFD ID', 'VNFD Version', 'Links']
|
'VNF Software Version', 'VNFD ID', 'VNFD Version', 'Links']
|
||||||
|
if action == 'show':
|
||||||
|
columns.extend(['Instantiated Vnf Info', 'VIM Connection Info'])
|
||||||
return columns
|
return columns
|
||||||
|
|
||||||
|
|
||||||
@@ -57,8 +63,10 @@ class TestCreateVnfLcm(TestVnfLcm):
|
|||||||
self.assertRaises(base.ParserException, self.check_parser,
|
self.assertRaises(base.ParserException, self.check_parser,
|
||||||
self.create_vnf_lcm, [], [])
|
self.create_vnf_lcm, [], [])
|
||||||
|
|
||||||
@ddt.data(True, False)
|
@ddt.data({"optional_arguments": True, "instantiate": True},
|
||||||
def test_take_action(self, optional_arguments):
|
{"optional_arguments": False, "instantiate": False})
|
||||||
|
@ddt.unpack
|
||||||
|
def test_take_action(self, optional_arguments, instantiate):
|
||||||
arglist = [uuidsentinel.vnf_package_vnfd_id]
|
arglist = [uuidsentinel.vnf_package_vnfd_id]
|
||||||
verifylist = [('vnfd_id', uuidsentinel.vnf_package_vnfd_id)]
|
verifylist = [('vnfd_id', uuidsentinel.vnf_package_vnfd_id)]
|
||||||
|
|
||||||
@@ -69,6 +77,13 @@ class TestCreateVnfLcm(TestVnfLcm):
|
|||||||
('description', 'test')])
|
('description', 'test')])
|
||||||
|
|
||||||
# command param
|
# command param
|
||||||
|
if instantiate:
|
||||||
|
param_file = ("./tackerclient/osc/v1/vnflcm/samples/"
|
||||||
|
"instantiate_vnf_instance_param_sample.json")
|
||||||
|
|
||||||
|
arglist.extend(['--I', param_file])
|
||||||
|
verifylist.append(('I', param_file))
|
||||||
|
|
||||||
parsed_args = self.check_parser(self.create_vnf_lcm, arglist,
|
parsed_args = self.check_parser(self.create_vnf_lcm, arglist,
|
||||||
verifylist)
|
verifylist)
|
||||||
|
|
||||||
@@ -77,8 +92,148 @@ class TestCreateVnfLcm(TestVnfLcm):
|
|||||||
'POST', os.path.join(self.url, 'vnflcm/v1/vnf_instances'),
|
'POST', os.path.join(self.url, 'vnflcm/v1/vnf_instances'),
|
||||||
json=json, headers=self.header)
|
json=json, headers=self.header)
|
||||||
|
|
||||||
|
if instantiate:
|
||||||
|
self.requests_mock.register_uri(
|
||||||
|
'POST', os.path.join(self.url, 'vnflcm/v1/vnf_instances',
|
||||||
|
json['id'], 'instantiate'),
|
||||||
|
json={}, headers=self.header)
|
||||||
|
|
||||||
|
sys.stdout = buffer = StringIO()
|
||||||
columns, data = (self.create_vnf_lcm.take_action(parsed_args))
|
columns, data = (self.create_vnf_lcm.take_action(parsed_args))
|
||||||
|
|
||||||
|
expected_message = (
|
||||||
|
'VNF Instance ' + json['id'] + ' is created and instantiation '
|
||||||
|
'request has been accepted.')
|
||||||
|
if instantiate:
|
||||||
|
self.assertEqual(expected_message, buffer.getvalue().strip())
|
||||||
|
|
||||||
self.assertItemsEqual(_get_columns_vnflcm(),
|
self.assertItemsEqual(_get_columns_vnflcm(),
|
||||||
columns)
|
columns)
|
||||||
self.assertItemsEqual(vnflcm_fakes.get_vnflcm_data(json),
|
self.assertItemsEqual(vnflcm_fakes.get_vnflcm_data(json),
|
||||||
data)
|
data)
|
||||||
|
|
||||||
|
|
||||||
|
class TestShowVnfLcm(TestVnfLcm):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestShowVnfLcm, self).setUp()
|
||||||
|
self.show_vnf_lcm = vnflcm.ShowVnfLcm(
|
||||||
|
self.app, self.app_args, cmd_name='vnflcm show')
|
||||||
|
|
||||||
|
def test_take_action(self):
|
||||||
|
vnf_instance = vnflcm_fakes.vnf_instance_response(
|
||||||
|
instantiation_state='INSTANTIATED')
|
||||||
|
|
||||||
|
arglist = [vnf_instance['id']]
|
||||||
|
verifylist = [('vnf_instance', vnf_instance['id'])]
|
||||||
|
|
||||||
|
# command param
|
||||||
|
parsed_args = self.check_parser(self.show_vnf_lcm, arglist,
|
||||||
|
verifylist)
|
||||||
|
|
||||||
|
self.requests_mock.register_uri(
|
||||||
|
'GET', os.path.join(self.url, 'vnflcm/v1/vnf_instances',
|
||||||
|
vnf_instance['id']),
|
||||||
|
json=vnf_instance, headers=self.header)
|
||||||
|
|
||||||
|
columns, data = (self.show_vnf_lcm.take_action(parsed_args))
|
||||||
|
self.assertItemsEqual(_get_columns_vnflcm(action='show'),
|
||||||
|
columns)
|
||||||
|
|
||||||
|
|
||||||
|
class TestInstantiateVnfLcm(TestVnfLcm):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestInstantiateVnfLcm, self).setUp()
|
||||||
|
self.instantiate_vnf_lcm = vnflcm.InstantiateVnfLcm(
|
||||||
|
self.app, self.app_args, cmd_name='vnflcm instantiate')
|
||||||
|
|
||||||
|
def test_take_action(self):
|
||||||
|
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||||
|
sample_param_file = ("./tackerclient/osc/v1/vnflcm/samples/"
|
||||||
|
"instantiate_vnf_instance_param_sample.json")
|
||||||
|
|
||||||
|
arglist = [vnf_instance['id'], sample_param_file]
|
||||||
|
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||||
|
('instantiation_request_file', sample_param_file)]
|
||||||
|
|
||||||
|
# command param
|
||||||
|
parsed_args = self.check_parser(self.instantiate_vnf_lcm, arglist,
|
||||||
|
verifylist)
|
||||||
|
|
||||||
|
url = os.path.join(self.url, 'vnflcm/v1/vnf_instances',
|
||||||
|
vnf_instance['id'], 'instantiate')
|
||||||
|
self.requests_mock.register_uri(
|
||||||
|
'POST', url, headers=self.header, json={})
|
||||||
|
|
||||||
|
sys.stdout = buffer = StringIO()
|
||||||
|
with mock.patch.object(proxy_client.ClientBase,
|
||||||
|
'_handle_fault_response') as m:
|
||||||
|
self.instantiate_vnf_lcm.take_action(parsed_args)
|
||||||
|
# check no fault response is received
|
||||||
|
self.assertNotCalled(m)
|
||||||
|
self.assertEqual(
|
||||||
|
'Instantiate request for VNF Instance ' + vnf_instance['id'] +
|
||||||
|
' has been accepted.', buffer.getvalue().strip())
|
||||||
|
|
||||||
|
def test_take_action_vnf_instance_not_found(self):
|
||||||
|
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||||
|
sample_param_file = ("./tackerclient/osc/v1/vnflcm/samples/"
|
||||||
|
"instantiate_vnf_instance_param_sample.json")
|
||||||
|
arglist = [vnf_instance['id'], sample_param_file]
|
||||||
|
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||||
|
('instantiation_request_file', sample_param_file)]
|
||||||
|
|
||||||
|
# command param
|
||||||
|
parsed_args = self.check_parser(self.instantiate_vnf_lcm, arglist,
|
||||||
|
verifylist)
|
||||||
|
|
||||||
|
url = os.path.join(self.url, 'vnflcm/v1/vnf_instances',
|
||||||
|
vnf_instance['id'], 'instantiate')
|
||||||
|
self.requests_mock.register_uri(
|
||||||
|
'POST', url, headers=self.header, status_code=404, json={})
|
||||||
|
|
||||||
|
self.assertRaises(exceptions.TackerClientException,
|
||||||
|
self.instantiate_vnf_lcm.take_action,
|
||||||
|
parsed_args)
|
||||||
|
|
||||||
|
def test_take_action_param_file_not_exists(self):
|
||||||
|
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||||
|
sample_param_file = "./not_exists.json"
|
||||||
|
arglist = [vnf_instance['id'], sample_param_file]
|
||||||
|
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||||
|
('instantiation_request_file', sample_param_file)]
|
||||||
|
|
||||||
|
# command param
|
||||||
|
parsed_args = self.check_parser(self.instantiate_vnf_lcm, arglist,
|
||||||
|
verifylist)
|
||||||
|
|
||||||
|
ex = self.assertRaises(exceptions.InvalidInput,
|
||||||
|
self.instantiate_vnf_lcm.take_action,
|
||||||
|
parsed_args)
|
||||||
|
|
||||||
|
expected_msg = ("File %s does not exist or user does not have read "
|
||||||
|
"privileges to it")
|
||||||
|
self.assertEqual(expected_msg % sample_param_file, ex.message)
|
||||||
|
|
||||||
|
@mock.patch("os.open")
|
||||||
|
@mock.patch("os.access")
|
||||||
|
def test_take_action_invalid_format_param_file(self, mock_open,
|
||||||
|
mock_access):
|
||||||
|
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||||
|
sample_param_file = "./invalid_param_file.json"
|
||||||
|
arglist = [vnf_instance['id'], sample_param_file]
|
||||||
|
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||||
|
('instantiation_request_file', sample_param_file)]
|
||||||
|
|
||||||
|
mock_open.return_value = "invalid_json_data"
|
||||||
|
# command param
|
||||||
|
parsed_args = self.check_parser(self.instantiate_vnf_lcm, arglist,
|
||||||
|
verifylist)
|
||||||
|
|
||||||
|
ex = self.assertRaises(exceptions.InvalidInput,
|
||||||
|
self.instantiate_vnf_lcm.take_action,
|
||||||
|
parsed_args)
|
||||||
|
|
||||||
|
expected_msg = "Failed to load parameter file."
|
||||||
|
self.assertIn(expected_msg, ex.message)
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
from oslo_utils.fixture import uuidsentinel
|
from oslo_utils.fixture import uuidsentinel
|
||||||
|
|
||||||
|
|
||||||
def vnf_instance_response(attrs=None):
|
def vnf_instance_response(attrs=None, instantiation_state='NOT_INSTANTIATED'):
|
||||||
"""Create a fake vnf instance.
|
"""Create a fake vnf instance.
|
||||||
|
|
||||||
:param Dictionary attrs:
|
:param Dictionary attrs:
|
||||||
@@ -36,10 +36,74 @@ def vnf_instance_response(attrs=None):
|
|||||||
"vnfProductName": "Sample VNF",
|
"vnfProductName": "Sample VNF",
|
||||||
"vnfSoftwareVersion": "1.0",
|
"vnfSoftwareVersion": "1.0",
|
||||||
"vnfdVersion": "1.0",
|
"vnfdVersion": "1.0",
|
||||||
"instantiationState": "NOT_INSTANTIATED",
|
"_links": "vnflcm/v1/vnf_instances/" + uuidsentinel.vnf_instance_id +
|
||||||
"links": "vnflcm/v1/vnf_instances/" + uuidsentinel.vnf_instance_id +
|
"/instantiate",
|
||||||
"/instantiate"
|
"instantiationState": instantiation_state}
|
||||||
|
if instantiation_state == 'INSTANTIATED':
|
||||||
|
dummy_vnf_instance.update({
|
||||||
|
"vimConnectionInfo": [{
|
||||||
|
'id': uuidsentinel.uuid,
|
||||||
|
'vimId': uuidsentinel.vimId,
|
||||||
|
'vimType': 'openstack',
|
||||||
|
'interfaceInfo': {'k': 'v'},
|
||||||
|
'accessInfo': {'k': 'v'},
|
||||||
|
'extra': {'k': 'v'}
|
||||||
|
}],
|
||||||
|
"instantiatedVnfInfo": {
|
||||||
|
"flavourId": uuidsentinel.flavourId,
|
||||||
|
"vnfState": "STARTED",
|
||||||
|
"extCpInfo": [{
|
||||||
|
'id': uuidsentinel.extCpInfo_uuid,
|
||||||
|
'cpdId': uuidsentinel.cpdId_uuid,
|
||||||
|
'cpProtocolInfo': [{
|
||||||
|
'layerProtocol': 'IP_OVER_ETHERNET',
|
||||||
|
'ipOverEthernet': '{}'
|
||||||
|
}],
|
||||||
|
'extLinkPortId': uuidsentinel.extLinkPortId_uuid,
|
||||||
|
'metadata': {'k': 'v'},
|
||||||
|
'associatedVnfcCpId': uuidsentinel.associatedVnfcCpId_uuid
|
||||||
|
}],
|
||||||
|
"extVirtualLinkInfo": [{
|
||||||
|
'id': uuidsentinel.extVirtualLinkInfo_uuid,
|
||||||
|
'resourceHandle': {},
|
||||||
|
'extLinkPorts': []
|
||||||
|
}],
|
||||||
|
"extManagedVirtualLinkInfo": [{
|
||||||
|
"id": uuidsentinel.extManagedVirtualLinkInfo_uuid,
|
||||||
|
'vnfVirtualLinkDescId': {},
|
||||||
|
'networkResource': {},
|
||||||
|
'vnfLinkPorts': []
|
||||||
|
}],
|
||||||
|
"vnfcResourceInfo": [{
|
||||||
|
'id': uuidsentinel.vnfcResourceInfo_uuid,
|
||||||
|
'vduId': uuidsentinel.vduId_uuid,
|
||||||
|
'computeResource': {},
|
||||||
|
'storageResourceIds': [],
|
||||||
|
'reservationId': uuidsentinel.reservationId,
|
||||||
|
}],
|
||||||
|
"vnfVirtualLinkResourceInfo": [{
|
||||||
|
'id': uuidsentinel.vnfVirtualLinkResourceInfo,
|
||||||
|
'vnfVirtualLinkDescId': 'VL4',
|
||||||
|
'networkResource': {},
|
||||||
|
'reservationId': uuidsentinel.reservationId,
|
||||||
|
'vnfLinkPorts': [],
|
||||||
|
'metadata': {'k': 'v'}
|
||||||
|
}],
|
||||||
|
"virtualStorageResourceInfo": [{
|
||||||
|
'id': uuidsentinel.virtualStorageResourceInfo,
|
||||||
|
'virtualStorageDescId': uuidsentinel.virtualStorageDescId,
|
||||||
|
'storageResource': {},
|
||||||
|
'reservationId': uuidsentinel.reservationId,
|
||||||
|
'metadata': {'k': 'v'}
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"_links": {
|
||||||
|
'self': 'self_link',
|
||||||
|
'indicators': None,
|
||||||
|
'instantiate': 'instantiate_link'
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
return dummy_vnf_instance
|
return dummy_vnf_instance
|
||||||
|
|
||||||
|
|
||||||
|
@@ -782,6 +782,7 @@ class VnfLCMClient(ClientBase):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
vnf_instances_path = '/vnflcm/v1/vnf_instances'
|
vnf_instances_path = '/vnflcm/v1/vnf_instances'
|
||||||
|
vnf_instance_path = '/vnflcm/v1/vnf_instances/%s'
|
||||||
|
|
||||||
def build_action(self, action):
|
def build_action(self, action):
|
||||||
return action
|
return action
|
||||||
@@ -790,6 +791,15 @@ class VnfLCMClient(ClientBase):
|
|||||||
def create_vnf_instance(self, body):
|
def create_vnf_instance(self, body):
|
||||||
return self.post(self.vnf_instances_path, body=body)
|
return self.post(self.vnf_instances_path, body=body)
|
||||||
|
|
||||||
|
@APIParamsCall
|
||||||
|
def show_vnf_instance(self, vnf_id, **_params):
|
||||||
|
return self.get(self.vnf_instance_path % vnf_id, params=_params)
|
||||||
|
|
||||||
|
@APIParamsCall
|
||||||
|
def instantiate_vnf_instance(self, vnf_id, body):
|
||||||
|
return self.post((self.vnf_instance_path + "/instantiate") % vnf_id,
|
||||||
|
body=body)
|
||||||
|
|
||||||
|
|
||||||
class Client(object):
|
class Client(object):
|
||||||
"""Unified interface to interact with multiple applications of tacker service.
|
"""Unified interface to interact with multiple applications of tacker service.
|
||||||
@@ -1041,3 +1051,10 @@ class Client(object):
|
|||||||
|
|
||||||
def create_vnf_instance(self, body):
|
def create_vnf_instance(self, body):
|
||||||
return self.vnf_lcm_client.create_vnf_instance(body)
|
return self.vnf_lcm_client.create_vnf_instance(body)
|
||||||
|
|
||||||
|
def show_vnf_instance(self, vnf_instance, **_params):
|
||||||
|
return self.vnf_lcm_client.show_vnf_instance(vnf_instance,
|
||||||
|
**_params)
|
||||||
|
|
||||||
|
def instantiate_vnf_instance(self, vnf_id, body):
|
||||||
|
return self.vnf_lcm_client.instantiate_vnf_instance(vnf_id, body)
|
||||||
|
Reference in New Issue
Block a user