OSC support to create vnf using vnflcm API
Added a new command ``openstack vnflcm create`` to create a new vnf. Blueprint: support-etsi-nfv-specs Change-Id: Ia90955df6ac141661c3d58e4de4e098c4cb51aab
This commit is contained in:
parent
e712c255d0
commit
66efce28d4
@ -34,7 +34,7 @@ oslo.context==2.19.2
|
||||
oslo.i18n==3.15.3
|
||||
oslo.log==3.36.0
|
||||
oslo.serialization==2.18.0
|
||||
oslo.utils==3.33.0
|
||||
oslo.utils==3.40.0
|
||||
pbr==2.0.0
|
||||
pep8==1.5.7
|
||||
positional==1.2.1
|
||||
|
@ -14,5 +14,5 @@ Babel!=2.4.0,>=2.3.4 # BSD
|
||||
oslo.i18n>=3.15.3 # Apache-2.0
|
||||
osc-lib>=1.8.0 # Apache-2.0
|
||||
oslo.log>=3.36.0 # Apache-2.0
|
||||
oslo.utils>=3.33.0 # Apache-2.0
|
||||
oslo.utils>=3.40.0 # Apache-2.0
|
||||
oslo.serialization!=2.19.1,>=2.18.0 # Apache-2.0
|
||||
|
@ -83,7 +83,7 @@ openstack.tackerclient.v1 =
|
||||
vnf_package_show = tackerclient.osc.v1.vnfpkgm.vnf_package:ShowVnfPackage
|
||||
vnf_package_upload = tackerclient.osc.v1.vnfpkgm.vnf_package:UploadVnfPackage
|
||||
vnf_package_delete = tackerclient.osc.v1.vnfpkgm.vnf_package:DeleteVnfPackage
|
||||
|
||||
vnflcm_create = tackerclient.osc.v1.vnflcm.vnflcm:CreateVnfLcm
|
||||
|
||||
[build_releasenotes]
|
||||
all_files = 1
|
||||
|
0
tackerclient/osc/v1/vnflcm/__init__.py
Normal file
0
tackerclient/osc/v1/vnflcm/__init__.py
Normal file
82
tackerclient/osc/v1/vnflcm/vnflcm.py
Normal file
82
tackerclient/osc/v1/vnflcm/vnflcm.py
Normal file
@ -0,0 +1,82 @@
|
||||
# Copyright (C) 2020 NTT DATA
|
||||
# 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 osc_lib.command import command
|
||||
from osc_lib import utils
|
||||
|
||||
from tackerclient.i18n import _
|
||||
from tackerclient.osc import sdk_utils
|
||||
|
||||
_mixed_case_fields = ('vnfInstanceName', 'vnfInstanceDescription', 'vnfdId',
|
||||
'vnfProvider', 'vnfProductName', 'vnfSoftwareVersion',
|
||||
'vnfdVersion', 'instantiationState')
|
||||
|
||||
|
||||
def _get_columns(item):
|
||||
column_map = {
|
||||
'id': 'ID',
|
||||
'vnfInstanceName': 'VNF Instance Name',
|
||||
'vnfInstanceDescription': 'VNF Instance Description',
|
||||
'vnfdId': 'VNFD ID',
|
||||
'vnfProvider': 'VNF Provider',
|
||||
'vnfProductName': 'VNF Product Name',
|
||||
'vnfSoftwareVersion': 'VNF Software Version',
|
||||
'vnfdVersion': 'VNFD Version',
|
||||
'instantiationState': 'Instantiation State',
|
||||
'links': 'Links',
|
||||
}
|
||||
return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map)
|
||||
|
||||
|
||||
class CreateVnfLcm(command.ShowOne):
|
||||
_description = _("Create a new VNF Instance")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateVnfLcm, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'vnfd_id',
|
||||
metavar="<vnfd-id>",
|
||||
help=_('Identifier that identifies the VNFD which defines the '
|
||||
'VNF instance to be created.'))
|
||||
parser.add_argument(
|
||||
'--name',
|
||||
metavar="<vnf-instance-name>",
|
||||
help=_('Name of the VNF instance to be created.'))
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
metavar="<vnf-instance-description>",
|
||||
help=_('Description of the VNF instance to be created.'))
|
||||
return parser
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
body = {}
|
||||
body['vnfdId'] = parsed_args.vnfd_id
|
||||
|
||||
if parsed_args.description:
|
||||
body['vnfInstanceDescription'] = parsed_args.description
|
||||
|
||||
if parsed_args.name:
|
||||
body['vnfInstanceName'] = parsed_args.name
|
||||
|
||||
return body
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
vnf = client.create_vnf_instance(self.args2body(parsed_args))
|
||||
display_columns, columns = _get_columns(vnf)
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(vnf),
|
||||
columns, mixed_case_fields=_mixed_case_fields)
|
||||
return (display_columns, data)
|
84
tackerclient/tests/unit/osc/v1/test_vnflcm.py
Normal file
84
tackerclient/tests/unit/osc/v1/test_vnflcm.py
Normal file
@ -0,0 +1,84 @@
|
||||
# Copyright (C) 2020 NTT DATA
|
||||
# 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 ddt
|
||||
import mock
|
||||
import os
|
||||
|
||||
from oslo_utils.fixture import uuidsentinel
|
||||
|
||||
from tackerclient.osc.v1.vnflcm import vnflcm
|
||||
from tackerclient.tests.unit.osc import base
|
||||
from tackerclient.tests.unit.osc.v1.fixture_data import client
|
||||
from tackerclient.tests.unit.osc.v1 import vnflcm_fakes
|
||||
|
||||
|
||||
class TestVnfLcm(base.FixturedTestCase):
|
||||
client_fixture_class = client.ClientFixture
|
||||
|
||||
def setUp(self):
|
||||
super(TestVnfLcm, self).setUp()
|
||||
self.url = client.TACKER_URL
|
||||
self.header = {'content-type': 'application/json'}
|
||||
self.app = mock.Mock()
|
||||
self.app_args = mock.Mock()
|
||||
self.client_manager = self.cs
|
||||
self.app.client_manager.tackerclient = self.client_manager
|
||||
|
||||
|
||||
def _get_columns_vnflcm():
|
||||
columns = ['ID', 'Instantiation State', 'VNF Instance Description',
|
||||
'VNF Instance Name', 'VNF Product Name', 'VNF Provider',
|
||||
'VNF Software Version', 'VNFD ID', 'VNFD Version', 'Links']
|
||||
return columns
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestCreateVnfLcm(TestVnfLcm):
|
||||
|
||||
def setUp(self):
|
||||
super(TestCreateVnfLcm, self).setUp()
|
||||
self.create_vnf_lcm = vnflcm.CreateVnfLcm(
|
||||
self.app, self.app_args, cmd_name='vnflcm create')
|
||||
|
||||
def test_create_no_args(self):
|
||||
self.assertRaises(base.ParserException, self.check_parser,
|
||||
self.create_vnf_lcm, [], [])
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_take_action(self, optional_arguments):
|
||||
arglist = [uuidsentinel.vnf_package_vnfd_id]
|
||||
verifylist = [('vnfd_id', uuidsentinel.vnf_package_vnfd_id)]
|
||||
|
||||
if optional_arguments:
|
||||
arglist.extend(['--name', 'test',
|
||||
'--description', 'test'])
|
||||
verifylist.extend([('name', 'test'),
|
||||
('description', 'test')])
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(self.create_vnf_lcm, arglist,
|
||||
verifylist)
|
||||
|
||||
json = vnflcm_fakes.vnf_instance_response()
|
||||
self.requests_mock.register_uri(
|
||||
'POST', os.path.join(self.url, 'vnflcm/v1/vnf_instances'),
|
||||
json=json, headers=self.header)
|
||||
|
||||
columns, data = (self.create_vnf_lcm.take_action(parsed_args))
|
||||
self.assertItemsEqual(_get_columns_vnflcm(),
|
||||
columns)
|
||||
self.assertItemsEqual(vnflcm_fakes.get_vnflcm_data(json),
|
||||
data)
|
53
tackerclient/tests/unit/osc/v1/vnflcm_fakes.py
Normal file
53
tackerclient/tests/unit/osc/v1/vnflcm_fakes.py
Normal file
@ -0,0 +1,53 @@
|
||||
# Copyright (C) 2020 NTT DATA
|
||||
# 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
|
||||
|
||||
|
||||
def vnf_instance_response(attrs=None):
|
||||
"""Create a fake vnf instance.
|
||||
|
||||
:param Dictionary attrs:
|
||||
A dictionary with all attributes
|
||||
:return:
|
||||
A vnf instance dict
|
||||
"""
|
||||
attrs = attrs or {}
|
||||
|
||||
# Set default attributes.
|
||||
dummy_vnf_instance = {
|
||||
"id": uuidsentinel.vnf_instance_id,
|
||||
"vnfInstanceName": "Fake-VNF-Instance",
|
||||
"vnfInstanceDescription": "Fake VNF",
|
||||
"vnfdId": uuidsentinel.vnf_package_vnfd_id,
|
||||
"vnfProvider": "NTT NS lab",
|
||||
"vnfProductName": "Sample VNF",
|
||||
"vnfSoftwareVersion": "1.0",
|
||||
"vnfdVersion": "1.0",
|
||||
"instantiationState": "NOT_INSTANTIATED",
|
||||
"links": "vnflcm/v1/vnf_instances/" + uuidsentinel.vnf_instance_id +
|
||||
"/instantiate"
|
||||
}
|
||||
return dummy_vnf_instance
|
||||
|
||||
|
||||
def get_vnflcm_data(vnf_instance):
|
||||
"""Get the vnf instance data.
|
||||
|
||||
:return:
|
||||
A tuple object sorted based on the name of the columns.
|
||||
"""
|
||||
# return the list of data as per column order
|
||||
return tuple([vnf_instance[key] for key in sorted(vnf_instance.keys())])
|
@ -774,6 +774,23 @@ class VnfPackageClient(ClientBase):
|
||||
body=file_data)
|
||||
|
||||
|
||||
class VnfLCMClient(ClientBase):
|
||||
"""Client for vnflcm APIs.
|
||||
|
||||
Purpose of this class is to create required request url for vnflcm
|
||||
APIs.
|
||||
"""
|
||||
|
||||
vnf_instances_path = '/vnflcm/v1/vnf_instances'
|
||||
|
||||
def build_action(self, action):
|
||||
return action
|
||||
|
||||
@APIParamsCall
|
||||
def create_vnf_instance(self, body):
|
||||
return self.post(self.vnf_instances_path, body=body)
|
||||
|
||||
|
||||
class Client(object):
|
||||
"""Unified interface to interact with multiple applications of tacker service.
|
||||
|
||||
@ -794,6 +811,7 @@ class Client(object):
|
||||
"""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.vnf_lcm_client = VnfLCMClient(**kwargs)
|
||||
self.vnf_package_client = VnfPackageClient(**kwargs)
|
||||
self.legacy_client = LegacyClient(**kwargs)
|
||||
|
||||
@ -1018,3 +1036,8 @@ class Client(object):
|
||||
|
||||
def delete_vnf_package(self, vnf_package):
|
||||
return self.vnf_package_client.delete_vnf_package(vnf_package)
|
||||
|
||||
# VnfLCMClient methods.
|
||||
|
||||
def create_vnf_instance(self, body):
|
||||
return self.vnf_lcm_client.create_vnf_instance(body)
|
||||
|
Loading…
x
Reference in New Issue
Block a user