Support parameter input for vnffg template

Change-Id: Ied3dfaa3f9b2a4bc3be43cd349d6d47f760cdd3b
Depends-On: I93819ff19ae91ca5e24778e220d3d09b63532ddf
Implements: blueprint vnffgd-param-support
This commit is contained in:
venkatamahesh 2016-11-30 15:27:15 +05:30
parent d311cfb77a
commit c4eacd0d44
11 changed files with 226 additions and 25 deletions

View File

@ -51,22 +51,28 @@ deploy a sample VNFFGD template such as the one `here <https://github.com/
openstack/tacker/tree/master/samples/tosca-templates/vnffgd/
tosca-vnffgd-sample.yaml>`_.
*Note: A current constraint of the Forwarding Path policy match criteria is
to include the network_src_port_id, such as:*
.. note::
::
A current constraint of the Forwarding Path policy match criteria is
to include the network_src_port_id, such as:
.. code-block:: yaml
policy:
type: ACL
criteria:
- network_src_port_id: 640dfd77-c92b-45a3-b8fc-22712de480e1
policy:
type: ACL
criteria:
- network_src_port_id: 640dfd77-c92b-45a3-b8fc-22712de480e1
This is required due to a limitation of Neutron networking-sfc and only
applies to an OpenStack VIM.
Tacker provides the following CLI to create a VNFFGD:
**tacker vnffgd-create --vnffgd-file <vnffgd file> <vnffgd name>**
.. code-block:: console
tacker vnffgd-create --vnffgd-file <vnffgd file> <vnffgd name>
Creating the VNFFG
~~~~~~~~~~~~~~~~~~
@ -82,14 +88,23 @@ http://docs.openstack.org/developer/tacker/install/getting_started.html
Tacker provides the following CLI to create VNFFG:
**tacker vnffg-create --vnffgd-id <vnffg-id>**
**--vnffgd-name <vnffgd name>**
**--vnf-mapping <vnf mapping>**
**--symmetrical <boolean>**
.. code-block:: console
tacker vnffg-create --vnffgd-name <vnffgd name> \
--vnf-mapping <vnf mapping> --symmetrical <boolean>
If you use a parameterized vnffg template:
.. code-block:: console
tacker vnffg-create --vnffgd-name <vnffgd name> \
--param-file <param file> --vnf-mapping <vnf mapping> \
--symmetrical <boolean>
Here,
* vnffgd-id/name - VNFFGD to use to instantiate this VNFFG
* vnffgd-name - VNFFGD to use to instantiate this VNFFG
* param-file - Parameter file in Yaml.
* vnf-mapping - Allows a list of logical VNFD to VNF instance mapping
* symmetrical - True/False
@ -101,9 +116,11 @@ each VNF in the Forwarding Path. For example, imagine a Forwarding Path
map each VNFD defined in the VNFFGD Forwarding Path to the desired VNF
instance:
**tacker vnffg-create --vnffgd-name myvnffgd**
**--vnf-mapping VNF1:'91e32c20-6d1f-47a4-9ba7-08f5e5effe07',**
**VNF2:'7168062e-9fa1-4203-8cb7-f5c99ff3ee1b'**
.. code-block:: console
tacker vnffg-create --vnffgd-name myvnffgd \
--vnf-mapping VNF1:'91e32c20-6d1f-47a4-9ba7-08f5e5effe07', \
VNF2:'7168062e-9fa1-4203-8cb7-f5c99ff3ee1b'
Alternatively, if no vnf-mapping is provided then Tacker VNFFG will attempt
to search for VNF instances derived from the given VNFDs in the VNFFGD. If
@ -115,8 +132,10 @@ flow through the path. This creates an extra classifier to ensure return
traffic flows through the chain in a reverse path, otherwise this traffic
routed normally and does not enter the VNFFG.
*Note: Enabling symmetrical is not currently supported by the OpenStack VIM
driver*
.. note::
Enabling symmetrical is not currently supported by the OpenStack VIM
driver
Viewing a VNFFG
~~~~~~~~~~~~~~~
@ -128,12 +147,14 @@ a Classifier. The main command to view a VNFFG is 'tacker vnffg-show,
however there are several commands available in order to view the
sub-components for a rendered VNFFG:
- **tacker nfp-list**
- **tacker nfp-show <nfp id>**
- **tacker chain-list**
- **tacker chain-show <chain id>**
- **tacker classifier-list**
- **tacker classifier-show <classifier id>**
.. code-block:: console
tacker nfp-list
tacker nfp-show <nfp id>
tacker chain-list
tacker chain-show <chain id>
tacker classifier-list
tacker classifier-show <classifier id>
Known Issues and Limitations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -0,0 +1,8 @@
---
features:
- Added parameter support for deploying VNF Forwarding Graph
Descriptor templates. With this addition the user can deploy
a VNFFG using an Onboarded parameterized template with
different parameter values using parameter yaml
file at each time without onboarding new template.

View File

@ -0,0 +1,52 @@
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
description: Sample VNFFG parameterized template
topology_template:
description: Sample VNFFG parameterized template
inputs:
net_src_port_id:
type: string
description: Port UUID of source VM.
dst_port_range:
type: string
description: Destination port range
ip_dst_pre:
type: string
description: Cidr format of destination ip.
node_templates:
Forwarding_path1:
type: tosca.nodes.nfv.FP.Tacker
description: creates path (CP12->CP22)
properties:
id: 51
policy:
type: ACL
criteria:
- network_src_port_id: { get_input: net_src_port_id }
- destination_port_range: { get_input: dst_port_range }
- ip_proto: 6
- ip_dst_prefix: { get_input: ip_dst_pre }
path:
- forwarder: VNFD1
capability: CP12
- forwarder: VNFD2
capability: CP22
groups:
VNFFG1:
type: tosca.groups.nfv.VNFFG
description: HTTP to Corporate Net
properties:
vendor: tacker
version: 1.0
number_of_endpoints: 5
dependent_virtual_link: [VL12,VL22]
connection_point: [CP12,CP22]
constituent_vnfs: [VNFD1,VNFD2]
members: [Forwarding_path1]

View File

@ -0,0 +1,6 @@
{
net_src_port_id: 640dfd77-c92b-45a3-b8fc-22712de480e1
dst_port_range: 80-1024
ip_dst_pre:
- 192.168.1.2/24
}

View File

@ -269,3 +269,7 @@ class VnfPolicyTypeInvalid(BadRequest):
class DuplicateResourceName(TackerException):
message = _("%(resource)s with name %(name)s already exists")
class InvalidParam(TackerException):
message = _("Param values must be a dict type")

View File

@ -91,6 +91,8 @@ class Vnffg(model_base.BASE, models_v1.HasTenant, models_v1.HasId):
# Mapping of VNFD to VNF instance names
vnf_mapping = sa.Column(types.Json)
attributes = sa.Column(types.Json)
class VnffgNfp(model_base.BASE, models_v1.HasTenant, models_v1.HasId):
"""Network Forwarding Path Data Model"""
@ -310,6 +312,7 @@ class VnffgPluginDbMixin(vnffg.VNFFGPluginBase, db_base.CommonDbMixin):
description=template_db.description,
vnf_mapping=vnf_mapping,
vnffgd_id=template_id,
attributes=template_db.get('template'),
status=constants.PENDING_CREATE)
context.session.add(vnffg_db)
@ -677,7 +680,7 @@ class VnffgPluginDbMixin(vnffg.VNFFGPluginBase, db_base.CommonDbMixin):
'forwarding_paths': vnffg_db.forwarding_paths[0]['id']
}
key_list = ('id', 'tenant_id', 'name', 'description',
'vnf_mapping', 'status', 'vnffgd_id')
'vnf_mapping', 'status', 'vnffgd_id', 'attributes')
res.update((key, vnffg_db[key]) for key in key_list)
return self._fields(res, fields)

View File

@ -218,6 +218,13 @@ class NfvoPlugin(nfvo_db.NfvoPluginDb, vnffg_db.VnffgPluginDbMixin,
@log.log
def create_vnffg(self, context, vnffg):
vnffg_attributes = vnffg['vnffg']['attributes']
if vnffg_attributes.get('param_values'):
param = vnffg_attributes['param_values']
if isinstance(param, dict):
vnffg_attributes['param_values'] = yaml.safe_dump(param)
else:
raise exceptions.InvalidParam()
vnffg_dict = super(NfvoPlugin, self)._create_vnffg_pre(context, vnffg)
nfp = super(NfvoPlugin, self).get_nfp(context,
vnffg_dict['forwarding_paths'])

View File

@ -32,8 +32,11 @@ ipparams = _get_template('vnf_cirros_param_values_ipaddr.yaml')
userdata_params = _get_template('vnf_cirros_param_values_user_data.yaml')
config_data = _get_template('config_data.yaml')
update_config_data = _get_template('update_config_data.yaml')
vnffg_params = _get_template('vnffg_params.yaml')
vnffgd_template = yaml.load(_get_template('vnffgd_template.yaml'))
vnffgd_tosca_template = yaml.load(_get_template('tosca_vnffgd_template.yaml'))
vnffgd_tosca_param_template = yaml.load(_get_template(
'tosca_vnffgd_param_template.yaml'))
vnffgd_invalid_tosca_template = yaml.load(_get_template(
'tosca_invalid_vnffgd_template.yaml'))
vnfd_scale_tosca_template = _get_template('tosca_scale.yaml')
@ -164,15 +167,30 @@ def get_dummy_vnffg_obj():
'vnffgd_id': u'eb094833-995e-49f0-a047-dfb56aaf7c4e',
'tenant_id': u'ad7ebc56538745a08ef7c5e97f8bd437',
'name': 'dummy_vnffg',
u'attributes': {u'template': vnffgd_tosca_template},
'vnf_mapping': {},
'symmetrical': False}}
def get_dummy_vnffg_param_obj():
return {'vnffg': {'description': 'dummy_vnf_description',
'vnffgd_id': u'eb094833-995e-49f0-a047-dfb56aaf7c4e',
'tenant_id': u'ad7ebc56538745a08ef7c5e97f8bd437',
'name': 'dummy_vnffg',
u'attributes': {
u'template': vnffgd_tosca_param_template},
'vnf_mapping': {},
u'attributes': {u'param_values':
yaml.safe_load(vnffg_params)},
'symmetrical': False}}
def get_dummy_vnffg_obj_vnf_mapping():
return {'vnffg': {'description': 'dummy_vnf_description',
'vnffgd_id': u'eb094833-995e-49f0-a047-dfb56aaf7c4e',
'tenant_id': u'ad7ebc56538745a08ef7c5e97f8bd437',
'name': 'dummy_vnffg',
u'attributes': {u'template': vnffgd_tosca_template},
'vnf_mapping': {
'VNF1': '91e32c20-6d1f-47a4-9ba7-08f5e5effe07',
'VNF3': '7168062e-9fa1-4203-8cb7-f5c99ff3ee1b'

View File

@ -0,0 +1,46 @@
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
description: example template
topology_template:
description: Example VNFFG template
inputs:
net_name:
type: string
description: Name of the network
node_templates:
Forwarding_path1:
type: tosca.nodes.nfv.FP.Tacker
description: creates path (CP11->CP12->CP32)
properties:
id: 51
policy:
type: ACL
criteria:
- network_name: { get_input: net_name }
- destination_port_range: 80-1024
- ip_proto: 6
- ip_dst_prefix: 192.168.1.2/24
path:
- forwarder: VNF1
capability: CP11
- forwarder: VNF1
capability: CP12
- forwarder: VNF3
capability: CP32
groups:
VNFFG1:
type: tosca.groups.nfv.VNFFG
description: HTTP to Corporate Net
properties:
vendor: tacker
version: 1.0
number_of_endpoints: 5
dependent_virtual_link: [VL1,VL2,VL3]
connection_point: [CP11,CP12,CP32]
constituent_vnfs: [VNF1,VNF3]
members: [Forwarding_path1]

View File

@ -0,0 +1,3 @@
{
'net_name': tenant1_net
}

View File

@ -257,6 +257,18 @@ class TestNfvoPlugin(db_base.SqlTestCase):
session.flush()
return vnffg_template
def _insert_dummy_vnffg_param_template(self):
session = self.context.session
vnffg_template = vnffg_db.VnffgTemplate(
id='eb094833-995e-49f0-a047-dfb56aaf7c4e',
tenant_id='ad7ebc56538745a08ef7c5e97f8bd437',
name='fake_template',
description='fake_template_description',
template={u'vnffgd': utils.vnffgd_tosca_param_template})
session.add(vnffg_template)
session.flush()
return vnffg_template
def _insert_dummy_vnffg(self):
session = self.context.session
vnffg = vnffg_db.Vnffg(
@ -363,6 +375,27 @@ class TestNfvoPlugin(db_base.SqlTestCase):
symmetrical=mock.ANY
)
def test_create_vnffg_param_values(self):
with patch.object(TackerManager, 'get_service_plugins') as \
mock_plugins:
mock_plugins.return_value = {'VNFM': FakeVNFMPlugin()}
mock.patch('tacker.common.driver_manager.DriverManager',
side_effect=FakeDriverManager()).start()
self._insert_dummy_vnffg_param_template()
vnffg_obj = utils.get_dummy_vnffg_param_obj()
result = self.nfvo_plugin.create_vnffg(self.context, vnffg_obj)
self.assertIsNotNone(result)
self.assertIn('id', result)
self.assertIn('status', result)
self.assertEqual('PENDING_CREATE', result['status'])
self._driver_manager.invoke.assert_called_with(mock.ANY, mock.ANY,
name=mock.ANY,
vnfs=mock.ANY,
fc_id=mock.ANY,
auth_attr=mock.ANY,
symmetrical=mock.ANY
)
def test_create_vnffg_vnf_mapping(self):
with patch.object(TackerManager, 'get_service_plugins') as \
mock_plugins: