Merge "Implement VNFC support"
This commit is contained in:
commit
4349df4ece
57
doc/source/devref/vnf_component_usage_guide.rst
Normal file
57
doc/source/devref/vnf_component_usage_guide.rst
Normal file
@ -0,0 +1,57 @@
|
||||
========================
|
||||
VNF Component in Tacker
|
||||
========================
|
||||
|
||||
This section will cover how to deploy `vnf component` in Tacker with the
|
||||
examples of how to write VNF descriptors.
|
||||
|
||||
|
||||
Sample TOSCA with vnfc
|
||||
=======================
|
||||
|
||||
The following example shows vnfc resource using TOSCA template.
|
||||
The target (VDU1) of the 'firewall_vnfc' in this example need to be
|
||||
described firstly like other TOSCA templates in Tacker.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
topology_template:
|
||||
node_templates:
|
||||
firewall_vnfc:
|
||||
type: tosca.nodes.nfv.VNFC.Tacker
|
||||
requirements:
|
||||
- host: VDU1
|
||||
interfaces:
|
||||
Standard:
|
||||
create: install_vnfc.sh
|
||||
|
||||
Every vnfc node must be of type 'tosca.nodes.nfv.VNFC.Tacker'. It takes
|
||||
two parameters:
|
||||
|
||||
1) requirements: This node will accept list of hosts on which VNFC has to be
|
||||
installed.
|
||||
2) interfaces: This node will accept the absolute path of shell script to be run
|
||||
on the VDUs. This shell script should reside in the machine where tacker
|
||||
server is running.
|
||||
|
||||
|
||||
How to setup environment
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
To make use of VNFC in Tacker, we have to upload the image to the glance in
|
||||
which heat-config and heat-config agents are installed. The installation steps
|
||||
can be referred `here <https://github.com/openstack/heat-templates/blob/master/
|
||||
hot/software-config/elements/README.rst>`_.
|
||||
|
||||
Currently VNFC feature works by using `heat software config <http://docs.openstack.org/
|
||||
developer/heat/template_guide/openstack.html#OS::Heat::SoftwareConfig>`_ which
|
||||
makes use of heat API.
|
||||
|
||||
So the glance images which has heat-config agents installed are only to be
|
||||
passed to VDU.
|
||||
|
||||
Known Limitations
|
||||
~~~~~~~~~~~~~~~~~
|
||||
1) Only one VNFC is supported for one VDU. Multiple VNFC per VDU will
|
||||
be introduced in future.
|
||||
2) The shell script for vnfc has to be placed in the machine where tacker
|
||||
server is running.
|
@ -61,6 +61,7 @@ Feature Documentation
|
||||
devref/vnffgd_template_description.rst
|
||||
devref/vnffg_usage_guide.rst
|
||||
devref/nsd_usage_guide.rst
|
||||
devref/vnf_component_usage_guide.rst
|
||||
|
||||
API Documentation
|
||||
=================
|
||||
|
@ -0,0 +1,8 @@
|
||||
---
|
||||
features:
|
||||
- Add support to pass shell script to install VNF
|
||||
components in the tosca template
|
||||
other:
|
||||
- Only one VNFC is supported for one VDU. Multiple VNFC per VDU will
|
||||
be introduced in future.
|
||||
- The shell script for vnfc has to be placed in the machine where tacker server is running
|
40
samples/tosca-templates/vnfd/test_tosca_vnfc.yaml
Normal file
40
samples/tosca-templates/vnfd/test_tosca_vnfc.yaml
Normal file
@ -0,0 +1,40 @@
|
||||
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
|
||||
metadata:
|
||||
template_name: sample-tosca-vnfd-for-vnfc
|
||||
|
||||
topology_template:
|
||||
node_templates:
|
||||
firewall_vnfc:
|
||||
type: tosca.nodes.nfv.VNFC.Tacker
|
||||
requirements:
|
||||
- host: VDU1
|
||||
interfaces:
|
||||
Standard:
|
||||
create: install_vnfc.sh
|
||||
|
||||
VDU1:
|
||||
type: tosca.nodes.nfv.VDU.Tacker
|
||||
properties:
|
||||
image: fedora-software-config
|
||||
flavor: m1.small
|
||||
mgmt_driver: noop
|
||||
key_name: stack_key
|
||||
config: |
|
||||
param0: key1
|
||||
param1: key2
|
||||
|
||||
CP1:
|
||||
type: tosca.nodes.nfv.CP.Tacker
|
||||
properties:
|
||||
management: true
|
||||
anti_spoofing_protection: false
|
||||
requirements:
|
||||
- virtualLink:
|
||||
node: VL1
|
||||
- virtualBinding:
|
||||
node: VDU1
|
||||
VL1:
|
||||
type: tosca.nodes.nfv.VL
|
||||
properties:
|
||||
network_name: net1
|
||||
vendor: Tacker
|
@ -0,0 +1,63 @@
|
||||
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
|
||||
metadata:
|
||||
template_name: sample-tosca-vnfd-for-vnfc
|
||||
|
||||
topology_template:
|
||||
node_templates:
|
||||
firewall_vnfc:
|
||||
type: tosca.nodes.nfv.VNFC.Tacker
|
||||
requirements:
|
||||
- host: VDU1
|
||||
- host: VDU2
|
||||
interfaces:
|
||||
Standard:
|
||||
create: /home/bharatht/install_vnfc.sh
|
||||
|
||||
VDU1:
|
||||
type: tosca.nodes.nfv.VDU.Tacker
|
||||
properties:
|
||||
image: fedora-software-config
|
||||
flavor: m1.small
|
||||
mgmt_driver: noop
|
||||
key_name: stack_key
|
||||
config: |
|
||||
param0: key1
|
||||
param1: key2
|
||||
|
||||
CP1:
|
||||
type: tosca.nodes.nfv.CP.Tacker
|
||||
properties:
|
||||
management: true
|
||||
anti_spoofing_protection: false
|
||||
requirements:
|
||||
- virtualLink:
|
||||
node: VL1
|
||||
- virtualBinding:
|
||||
node: VDU1
|
||||
VDU2:
|
||||
type: tosca.nodes.nfv.VDU.Tacker
|
||||
properties:
|
||||
image: fedora-software-config
|
||||
flavor: m1.small
|
||||
mgmt_driver: noop
|
||||
key_name: stack_key
|
||||
config: |
|
||||
param0: key1
|
||||
param1: key2
|
||||
|
||||
CP2:
|
||||
type: tosca.nodes.nfv.CP.Tacker
|
||||
properties:
|
||||
management: true
|
||||
anti_spoofing_protection: false
|
||||
requirements:
|
||||
- virtualLink:
|
||||
node: VL1
|
||||
- virtualBinding:
|
||||
node: VDU2
|
||||
|
||||
VL1:
|
||||
type: tosca.nodes.nfv.VL
|
||||
properties:
|
||||
network_name: private
|
||||
vendor: Tacker
|
@ -13,6 +13,7 @@
|
||||
POLICY_ALARMING = 'tosca.policies.tacker.Alarming'
|
||||
DEFAULT_ALARM_ACTIONS = ['respawn', 'log', 'log_and_kill', 'notify']
|
||||
VNF_CIRROS_CREATE_TIMEOUT = 300
|
||||
VNFC_CREATE_TIMEOUT = 600
|
||||
VNF_CIRROS_DELETE_TIMEOUT = 300
|
||||
VNF_CIRROS_DEAD_TIMEOUT = 250
|
||||
ACTIVE_SLEEP_TIME = 3
|
||||
|
2
tacker/tests/etc/samples/install_vnfc.sh
Normal file
2
tacker/tests/etc/samples/install_vnfc.sh
Normal file
@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
echo "Successfully installed VNFC" > /tacker
|
42
tacker/tests/etc/samples/sample_tosca_vnfc.yaml
Normal file
42
tacker/tests/etc/samples/sample_tosca_vnfc.yaml
Normal file
@ -0,0 +1,42 @@
|
||||
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
|
||||
metadata:
|
||||
template_name: sample-tosca-vnfd-for-vnfc
|
||||
|
||||
topology_template:
|
||||
node_templates:
|
||||
firewall_vnfc:
|
||||
type: tosca.nodes.nfv.VNFC.Tacker
|
||||
requirements:
|
||||
- host: VDU1
|
||||
interfaces:
|
||||
Standard:
|
||||
create: install_vnfc.sh
|
||||
|
||||
VDU1:
|
||||
type: tosca.nodes.nfv.VDU.Tacker
|
||||
properties:
|
||||
flavor: m1.small
|
||||
mgmt_driver: noop
|
||||
config: |
|
||||
param0: key1
|
||||
param1: key2
|
||||
artifacts:
|
||||
fedora:
|
||||
type: tosca.artifacts.Deployment.Image.VM
|
||||
file: https://github.com/bharaththiruveedula/dotfiles/raw/master/fedora-sw.qcow2
|
||||
CP1:
|
||||
type: tosca.nodes.nfv.CP.Tacker
|
||||
properties:
|
||||
management: true
|
||||
anti_spoofing_protection: false
|
||||
requirements:
|
||||
- virtualLink:
|
||||
node: VL1
|
||||
- virtualBinding:
|
||||
node: VDU1
|
||||
|
||||
VL1:
|
||||
type: tosca.nodes.nfv.VL
|
||||
properties:
|
||||
network_name: private
|
||||
vendor: Tacker
|
110
tacker/tests/functional/vnfm/test_tosca_vnfc.py
Normal file
110
tacker/tests/functional/vnfm/test_tosca_vnfc.py
Normal file
@ -0,0 +1,110 @@
|
||||
# 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
|
||||
from oslo_config import cfg
|
||||
from toscaparser import tosca_template
|
||||
import yaml
|
||||
|
||||
from tacker.common import utils
|
||||
from tacker.plugins.common import constants as evt_constants
|
||||
from tacker.tests import constants
|
||||
from tacker.tests.functional import base
|
||||
from tacker.tests.utils import read_file
|
||||
from tacker.vnfm.tosca import utils as toscautils
|
||||
|
||||
CONF = cfg.CONF
|
||||
SOFTWARE_DEPLOYMENT = 'OS::Heat::SoftwareDeployment'
|
||||
|
||||
|
||||
class VnfTestToscaVNFC(base.BaseTackerTest):
|
||||
def test_create_delete_tosca_vnfc(self):
|
||||
input_yaml = read_file('sample_tosca_vnfc.yaml')
|
||||
tosca_dict = yaml.safe_load(input_yaml)
|
||||
path = os.path.abspath(os.path.join(
|
||||
os.path.dirname(__file__), "../../etc/samples"))
|
||||
vnfd_name = 'sample-tosca-vnfc'
|
||||
tosca_dict['topology_template']['node_templates'
|
||||
]['firewall_vnfc'
|
||||
]['interfaces'
|
||||
]['Standard']['create'] = path \
|
||||
+ '/install_vnfc.sh'
|
||||
tosca_arg = {'vnfd': {'name': vnfd_name,
|
||||
'attributes': {'vnfd': tosca_dict}}}
|
||||
|
||||
# Create vnfd with tosca template
|
||||
vnfd_instance = self.client.create_vnfd(body=tosca_arg)
|
||||
self.assertIsNotNone(vnfd_instance)
|
||||
|
||||
# Create vnf with vnfd_id
|
||||
vnfd_id = vnfd_instance['vnfd']['id']
|
||||
vnf_arg = {'vnf': {'vnfd_id': vnfd_id, 'name':
|
||||
"test_tosca_vnfc"}}
|
||||
vnf_instance = self.client.create_vnf(body=vnf_arg)
|
||||
|
||||
vnf_id = vnf_instance['vnf']['id']
|
||||
self.wait_until_vnf_active(vnf_id,
|
||||
constants.VNFC_CREATE_TIMEOUT,
|
||||
constants.ACTIVE_SLEEP_TIME)
|
||||
self.assertEqual('ACTIVE',
|
||||
self.client.show_vnf(vnf_id)['vnf']['status'])
|
||||
self.validate_vnf_instance(vnfd_instance, vnf_instance)
|
||||
|
||||
self.verify_vnf_crud_events(
|
||||
vnf_id, evt_constants.RES_EVT_CREATE, evt_constants.PENDING_CREATE,
|
||||
cnt=2)
|
||||
self.verify_vnf_crud_events(
|
||||
vnf_id, evt_constants.RES_EVT_CREATE, evt_constants.ACTIVE)
|
||||
|
||||
# Validate mgmt_url with input yaml file
|
||||
mgmt_url = self.client.show_vnf(vnf_id)['vnf']['mgmt_url']
|
||||
self.assertIsNotNone(mgmt_url)
|
||||
mgmt_dict = yaml.load(str(mgmt_url))
|
||||
|
||||
input_dict = yaml.load(input_yaml)
|
||||
toscautils.updateimports(input_dict)
|
||||
|
||||
tosca = tosca_template.ToscaTemplate(parsed_params={}, a_file=False,
|
||||
yaml_dict_tpl=input_dict)
|
||||
|
||||
vdus = toscautils.findvdus(tosca)
|
||||
|
||||
self.assertEqual(len(vdus), len(mgmt_dict.keys()))
|
||||
for vdu in vdus:
|
||||
self.assertIsNotNone(mgmt_dict[vdu.name])
|
||||
self.assertEqual(True, utils.is_valid_ipv4(mgmt_dict[vdu.name]))
|
||||
|
||||
# Check the status of SoftwareDeployment
|
||||
heat_stack_id = self.client.show_vnf(vnf_id)['vnf']['instance_id']
|
||||
resource_types = self.h_client.resources
|
||||
resources = resource_types.list(stack_id=heat_stack_id)
|
||||
for resource in resources:
|
||||
resource = resource.to_dict()
|
||||
if resource['resource_type'] == \
|
||||
SOFTWARE_DEPLOYMENT:
|
||||
self.assertEqual('CREATE_COMPLETE',
|
||||
resource['resource_status'])
|
||||
break
|
||||
|
||||
# Delete vnf_instance with vnf_id
|
||||
try:
|
||||
self.client.delete_vnf(vnf_id)
|
||||
except Exception:
|
||||
assert False, "vnf Delete of test_vnf_with_multiple_vdus failed"
|
||||
|
||||
self.wait_until_vnf_delete(vnf_id,
|
||||
constants.VNF_CIRROS_DELETE_TIMEOUT)
|
||||
self.verify_vnf_crud_events(vnf_id, evt_constants.RES_EVT_DELETE,
|
||||
evt_constants.PENDING_DELETE, cnt=2)
|
||||
|
||||
# Delete vnfd_instance
|
||||
self.addCleanup(self.client.delete_vnfd, vnfd_id)
|
@ -0,0 +1,36 @@
|
||||
heat_template_version: 2013-05-23
|
||||
parameters: {}
|
||||
resources:
|
||||
VDU1:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
config_drive: false
|
||||
flavor: m1.small
|
||||
image: Fedora
|
||||
networks:
|
||||
- port:
|
||||
get_resource: CP1
|
||||
user_data_format: SOFTWARE_CONFIG
|
||||
CP1:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network: existing_network_1
|
||||
port_security_enabled: false
|
||||
firewall_vnfc_create_config:
|
||||
type: OS::Heat::SoftwareConfig
|
||||
properties:
|
||||
config: 'echo "Test case for Tacker";'
|
||||
group: script
|
||||
firewall_vnfc_create_deploy:
|
||||
type: OS::Heat::SoftwareDeployment
|
||||
properties:
|
||||
config: {get_resource: firewall_vnfc_create_config}
|
||||
server: {get_resource: VDU1}
|
||||
depends_on:
|
||||
- VDU1
|
||||
|
||||
outputs:
|
||||
mgmt_ip-VDU1:
|
||||
value:
|
||||
get_attr: [CP1, fixed_ips, 0, ip_address]
|
||||
|
@ -0,0 +1,39 @@
|
||||
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
|
||||
metadata:
|
||||
template_name: sample-tosca-vnfd-for-vnfc
|
||||
|
||||
topology_template:
|
||||
node_templates:
|
||||
firewall_vnfc:
|
||||
type: tosca.nodes.nfv.VNFC.Tacker
|
||||
requirements:
|
||||
- host: VDU1
|
||||
interfaces:
|
||||
Standard:
|
||||
create: install_vnfc.sh
|
||||
|
||||
VDU1:
|
||||
type: tosca.nodes.nfv.VDU.Tacker
|
||||
properties:
|
||||
image: Fedora
|
||||
flavor: m1.small
|
||||
mgmt_driver: noop
|
||||
config: |
|
||||
param0: key1
|
||||
param1: key2
|
||||
|
||||
CP1:
|
||||
type: tosca.nodes.nfv.CP.Tacker
|
||||
properties:
|
||||
management: true
|
||||
anti_spoofing_protection: false
|
||||
requirements:
|
||||
- virtualLink:
|
||||
node: VL1
|
||||
- virtualBinding:
|
||||
node: VDU1
|
||||
VL1:
|
||||
type: tosca.nodes.nfv.VL
|
||||
properties:
|
||||
network_name: net1
|
||||
vendor: Tacker
|
@ -39,7 +39,7 @@ OPTS = [
|
||||
help=_("Number of attempts to retry for stack"
|
||||
" creation/deletion")),
|
||||
cfg.IntOpt('stack_retry_wait',
|
||||
default=5,
|
||||
default=10,
|
||||
help=_("Wait time (in seconds) between consecutive stack"
|
||||
" create/delete retries")),
|
||||
]
|
||||
|
@ -257,3 +257,9 @@ node_types:
|
||||
required: true
|
||||
entry_schema:
|
||||
type: tosca.nfv.datatypes.pathType
|
||||
tosca.nodes.nfv.VNFC.Tacker:
|
||||
derived_from: tosca.nodes.SoftwareComponent
|
||||
requirements:
|
||||
- host:
|
||||
node: tosca.nodes.nfv.VDU.Tacker
|
||||
relationship: tosca.relationships.HostedOn
|
||||
|
@ -35,6 +35,7 @@ TACKERVDU = 'tosca.nodes.nfv.VDU.Tacker'
|
||||
TOSCA_BINDS_TO = 'tosca.relationships.network.BindsTo'
|
||||
VDU = 'tosca.nodes.nfv.VDU'
|
||||
IMAGE = 'tosca.artifacts.Deployment.Image.VM'
|
||||
HEAT_SOFTWARE_CONFIG = 'OS::Heat::SoftwareConfig'
|
||||
OS_RESOURCES = {
|
||||
'flavor': 'get_flavor_dict',
|
||||
'image': 'get_image_dict'
|
||||
@ -254,6 +255,13 @@ def post_process_heat_template(heat_tpl, mgmt_ports, metadata,
|
||||
metadata_dict
|
||||
|
||||
add_resources_tpl(heat_dict, res_tpl)
|
||||
for res in heat_dict["resources"].values():
|
||||
if not res['type'] == HEAT_SOFTWARE_CONFIG:
|
||||
continue
|
||||
config = res["properties"]["config"]
|
||||
if 'get_file' in config:
|
||||
res["properties"]["config"] = open(config["get_file"]).read()
|
||||
|
||||
if unsupported_res_prop:
|
||||
convert_unsupported_res_prop(heat_dict, unsupported_res_prop)
|
||||
return yaml.dump(heat_dict)
|
||||
|
Loading…
Reference in New Issue
Block a user