This patchset adds mistral workflow, tests, sample templates and user guide for NSD Change-Id: If53081bc76a5436287b307538a1255c65fc71cb2 Co-Authored-By: Bharath Thiruveedula<bharath_ves@hotmail.com> Partially-implements: blueprint nsd-supportchanges/37/414937/31
parent
d311cfb77a
commit
15c4d7ec5d
@ -0,0 +1,244 @@
|
||||
..
|
||||
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.
|
||||
|
||||
.. _ref-nsd:
|
||||
|
||||
==========================================================
|
||||
Orchestrating VNFs using Network Services Descriptor (NSD)
|
||||
==========================================================
|
||||
|
||||
To enable dynamic composition of network services, NFV introduces Network
|
||||
Service Descriptors (NSDs) that specify the network service to be created.
|
||||
This usage guide describes lifecycle of Network service descriptors and
|
||||
services.
|
||||
|
||||
NSD in Ocata can be used for creating multiple (related) VNFs in one shot
|
||||
using a single TOSCA template. This is a first (big) step into NSD, few
|
||||
follow-on enhancements like:
|
||||
1) Creating VLs / neutron networks using NSD (to support inter-VNF private VL)
|
||||
2) VNFFGD support in NSD.
|
||||
|
||||
Creating the NSD
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Once OpenStack along with Tacker has been successfully installed,
|
||||
deploy a sample VNFD templates using vnf1.yaml and vnf2.yaml as mentioned in
|
||||
reference section.
|
||||
|
||||
::
|
||||
tacker vnfd-create --vnfd-file vnfd1.yaml VNFD1
|
||||
|
||||
tacker vnfd-create --vnfd-file vnfd2.yaml VNFD2
|
||||
|
||||
The following code represents sample NSD which instantiates the above VNFs
|
||||
|
||||
::
|
||||
|
||||
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
|
||||
imports:
|
||||
- VNFD1
|
||||
- VNFD2
|
||||
topology_template:
|
||||
node_templates:
|
||||
VNF1:
|
||||
type: tosca.nodes.nfv.VNF1
|
||||
requirements:
|
||||
- virtualLink1: VL1
|
||||
- virtualLink2: VL2
|
||||
VNF2:
|
||||
type: tosca.nodes.nfv.VNF2
|
||||
VL1:
|
||||
type: tosca.nodes.nfv.VL
|
||||
properties:
|
||||
network_name: net0
|
||||
vendor: tacker
|
||||
VL2:
|
||||
type: tosca.nodes.nfv.VL
|
||||
properties:
|
||||
network_name: net_mgmt
|
||||
vendor: tacker
|
||||
|
||||
In above NSD template VL1 and VL2 are substituting the virtuallinks of VNF1.
|
||||
To onboard the above NSD:
|
||||
|
||||
**tacker nsd-create --nsd-file <nsd file> <nsd name>**
|
||||
|
||||
Creating the NS
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
To create a NS, you must have onboarded corresponding NSD and
|
||||
VNFDS(which NS is substituting)
|
||||
|
||||
Tacker provides the following CLI to create NS:
|
||||
|
||||
**tacker ns-create --nsd-id <nsd-id> <ns-name>**
|
||||
|
||||
Reference
|
||||
~~~~~~~~~
|
||||
|
||||
VNF1 sample template for nsd named vnfd1.yaml:
|
||||
|
||||
::
|
||||
|
||||
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
|
||||
description: Demo example
|
||||
node_types:
|
||||
tosca.nodes.nfv.VNF1:
|
||||
requirements:
|
||||
- virtualLink1:
|
||||
type: tosca.nodes.nfv.VL
|
||||
required: true
|
||||
- virtualLink2:
|
||||
type: tosca.nodes.nfv.VL
|
||||
required: true
|
||||
capabilities:
|
||||
forwader1:
|
||||
type: tosca.capabilities.nfv.Forwarder
|
||||
forwader2:
|
||||
type: tosca.capabilities.nfv.Forwarder
|
||||
|
||||
topology_template:
|
||||
substitution_mappings:
|
||||
node_type: tosca.nodes.nfv.VNF1
|
||||
requirements:
|
||||
virtualLink1: [CP11, virtualLink]
|
||||
virtualLink2: [CP14, virtualLink]
|
||||
capabilities:
|
||||
forwarder1: [CP11, forwarder]
|
||||
forwarder2: [CP14, forwarder]
|
||||
node_templates:
|
||||
VDU1:
|
||||
type: tosca.nodes.nfv.VDU.Tacker
|
||||
properties:
|
||||
image: cirros-0.3.4-x86_64-uec
|
||||
flavor: m1.tiny
|
||||
availability_zone: nova
|
||||
mgmt_driver: noop
|
||||
config: |
|
||||
param0: key1
|
||||
param1: key2
|
||||
CP11:
|
||||
type: tosca.nodes.nfv.CP.Tacker
|
||||
properties:
|
||||
management: true
|
||||
anti_spoofing_protection: false
|
||||
requirements:
|
||||
- virtualBinding:
|
||||
node: VDU1
|
||||
|
||||
VDU2:
|
||||
type: tosca.nodes.nfv.VDU.Tacker
|
||||
properties:
|
||||
image: cirros-0.3.4-x86_64-uec
|
||||
flavor: m1.medium
|
||||
availability_zone: nova
|
||||
mgmt_driver: noop
|
||||
config: |
|
||||
param0: key1
|
||||
param1: key2
|
||||
CP13:
|
||||
type: tosca.nodes.nfv.CP.Tacker
|
||||
properties:
|
||||
management: true
|
||||
anti_spoofing_protection: false
|
||||
requirements:
|
||||
- virtualLink:
|
||||
node: VL1
|
||||
- virtualBinding:
|
||||
node: VDU2
|
||||
CP14:
|
||||
type: tosca.nodes.nfv.CP.Tacker
|
||||
properties:
|
||||
management: true
|
||||
anti_spoofing_protection: false
|
||||
requirements:
|
||||
- virtualBinding:
|
||||
node: VDU2
|
||||
VL1:
|
||||
type: tosca.nodes.nfv.VL
|
||||
properties:
|
||||
network_name: net_mgmt
|
||||
vendor: Tacker
|
||||
VL2:
|
||||
type: tosca.nodes.nfv.VL
|
||||
properties:
|
||||
network_name: net0
|
||||
vendor: Tacker
|
||||
|
||||
VNF2 sample template for nsd named vnfd2.yaml:
|
||||
|
||||
::
|
||||
|
||||
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
|
||||
description: Demo example
|
||||
|
||||
node_types:
|
||||
tosca.nodes.nfv.VNF2:
|
||||
capabilities:
|
||||
forwarder1:
|
||||
type: tosca.capabilities.nfv.Forwarder
|
||||
topology_template:
|
||||
substitution_mappings:
|
||||
node_type: tosca.nodes.nfv.VNF2
|
||||
capabilities:
|
||||
forwarder1: [CP21, forwarder]
|
||||
node_templates:
|
||||
VDU1:
|
||||
type: tosca.nodes.nfv.VDU.Tacker
|
||||
properties:
|
||||
image: cirros-0.3.4-x86_64-uec
|
||||
flavor: m1.tiny
|
||||
availability_zone: nova
|
||||
mgmt_driver: noop
|
||||
config: |
|
||||
param0: key1
|
||||
param1: key2
|
||||
CP21:
|
||||
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: cirros-0.3.4-x86_64-uec
|
||||
flavor: m1.medium
|
||||
availability_zone: nova
|
||||
mgmt_driver: noop
|
||||
CP22:
|
||||
type: tosca.nodes.nfv.CP.Tacker
|
||||
properties:
|
||||
management: true
|
||||
anti_spoofing_protection: false
|
||||
requirements:
|
||||
- virtualLink:
|
||||
node: VL2
|
||||
- virtualBinding:
|
||||
node: VDU2
|
||||
VL1:
|
||||
type: tosca.nodes.nfv.VL
|
||||
properties:
|
||||
network_name: net_mgmt
|
||||
vendor: Tacker
|
||||
VL2:
|
||||
type: tosca.nodes.nfv.VL
|
||||
properties:
|
||||
network_name: net0
|
||||
vendor: Tacker
|
||||
|
||||
|
@ -0,0 +1,53 @@
|
||||
# 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 yaml
|
||||
|
||||
from oslo_log import log as logging
|
||||
|
||||
from tacker.nfvo.drivers.workflow import workflow_generator
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
FREQUENCY = 10
|
||||
SLEEP = 5
|
||||
|
||||
|
||||
class MistralClient(object):
|
||||
|
||||
def __init__(self, context, client, resource, action):
|
||||
self.context = context
|
||||
self.client = client
|
||||
self.wg = workflow_generator.WorkflowGenerator(resource, action)
|
||||
|
||||
def prepare_workflow(self, **kwargs):
|
||||
self.wg.task(**kwargs)
|
||||
|
||||
def create_workflow(self):
|
||||
definition_yaml = yaml.dump(self.wg.definition)
|
||||
wf = self.client.workflows.create(definition_yaml)
|
||||
wf_id = wf[0].id
|
||||
return wf_id
|
||||
|
||||
def delete_workflow(self, wf_id):
|
||||
self.client.workflows.delete(wf_id)
|
||||
|
||||
def execute_workflow(self, wf_id):
|
||||
wf_ex = self.client.executions.create(
|
||||
workflow_identifier=wf_id,
|
||||
workflow_input=self.wg.input_dict,
|
||||
wf_params={})
|
||||
return wf_ex
|
||||
|
||||
def get_execution_state(self, ex_id):
|
||||
return self.client.executions.get(ex_id).state
|
||||
|
||||
def delete_execution(self, ex_id):
|
||||
self.client.executions.delete(ex_id)
|
@ -0,0 +1,27 @@
|
||||
# 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.
|
||||
|
||||
|
||||
class Workflow(object):
|
||||
def __init__(self, wf_name, wf_type, version='2.0'):
|
||||
self._wf_name = wf_name
|
||||
self._wf_type = wf_type
|
||||
self._version = '2.0'
|
||||
|
||||
def get_name(self):
|
||||
return self.wf_name
|
||||
|
||||
def get_type(self):
|
||||
return self.wf_type
|
||||
|
||||
def get_version(self):
|
||||
self._version
|
@ -0,0 +1,190 @@
|
||||
# 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 ast
|
||||
import uuid
|
||||
|
||||
from six import iteritems
|
||||
|
||||
|
||||
OUTPUT = {
|
||||
'create_vnf': ['vnf_id', 'vim_id', 'mgmt_url', 'status']
|
||||
}
|
||||
|
||||
|
||||
class WorkflowGenerator(object):
|
||||
def __init__(self, resource, action):
|
||||
self.resource = resource
|
||||
self.action = action
|
||||
self.wf_name = self.action + '_' + self.resource
|
||||
self.wf_identifier = 'std.' + self.wf_name + str(uuid.uuid4())
|
||||
self.task = getattr(self, self.wf_name)
|
||||
self.input_dict = dict()
|
||||
self._build_basic_workflow()
|
||||
|
||||
def _build_basic_workflow(self):
|
||||
self.definition = {
|
||||
'version': '2.0',
|
||||
self.wf_identifier: {
|
||||
'type': 'direct',
|
||||
'input': [self.resource]
|
||||
}
|
||||
}
|
||||
|
||||
def _get_vim_id(self):
|
||||
pass
|
||||
|
||||
def _get_vnfd_id(self):
|
||||
pass
|
||||
|
||||
def _get_vnf_name(self):
|
||||
pass
|
||||
|
||||
def _get_attr(self):
|
||||
pass
|
||||
|
||||
def _get_description(self):
|
||||
pass
|
||||
|
||||
def _add_create_vnf_tasks(self, ns):
|
||||
vnfds = ns['vnfd_details']
|
||||
task_dict = dict()
|
||||
for vnfd_name, vnfd_info in iteritems(vnfds):
|
||||
nodes = vnfd_info['instances']
|
||||
for node in nodes:
|
||||
task = self.wf_name + '_' + node
|
||||
task_dict[task] = {
|
||||
'action': 'tacker.create_vnf body=<% $.vnf.{0} '
|
||||
'%>'.format(node),
|
||||
'input': {'body': '<% $.vnf.{0} %>'.format(node)},
|
||||
'publish': {
|
||||
'vnf_id_' + node: '<% task({0}).result.vnf.id '
|
||||
'%>'.format(task),
|
||||
'vim_id_' + node: '<% task({0}).result.vnf.vim_id'
|
||||
' %>'.format(task),
|
||||
'mgmt_url_' + node: '<% task({0}).result.vnf.mgmt_url'
|
||||
' %>'.format(task),
|
||||
'status_' + node: '<% task({0}).result.vnf.status'
|
||||
' %>'.format(task),
|
||||
},
|
||||
'on-success': ['wait_vnf_active_%s' % node]
|
||||
}
|
||||
return task_dict
|
||||
|
||||
def _add_wait_vnf_tasks(self, ns):
|
||||
vnfds = ns['vnfd_details']
|
||||
task_dict = dict()
|
||||
for vnfd_name, vnfd_info in iteritems(vnfds):
|
||||
nodes = vnfd_info['instances']
|
||||
for node in nodes:
|
||||
task = 'wait_vnf_active_%s' % node
|
||||
task_dict[task] = {
|
||||
'action': 'tacker.show_vnf vnf=<% $.vnf_id_{0} '
|
||||
'%>'.format(node),
|
||||
'retry': {
|
||||
'count': 10,
|
||||
'delay': 10,
|
||||
'break-on': '<% $.status_{0} = "ACTIVE" '
|
||||
'%>'.format(node),
|
||||
'break-on': '<% $.status_{0} = "ERROR"'
|
||||
' %>'.format(node),
|
||||
'continue-on': '<% $.status_{0} = "PENDING_CREATE" '
|
||||
'%>'.format(node),
|
||||
},
|
||||
'publish': {
|
||||
'mgmt_url_' + node: ' <% task({0}).result.vnf.'
|
||||
'mgmt_url %>'.format(task),
|
||||
'status_' + node: '<% task({0}).result.vnf.status'
|
||||
' %>'.format(task),
|
||||
},
|
||||
'on-success': [
|
||||
{'delete_vnf_' + node: '<% $.status_{0}='
|
||||
'"ERROR" %>'.format(node)}
|
||||
]
|
||||
}
|
||||
return task_dict
|
||||
|
||||
def _add_delete_vnf_tasks(self, ns):
|
||||
vnfds = ns['vnfd_details']
|
||||
task_dict = dict()
|
||||
for vnfd_name, vnfd_info in iteritems(vnfds):
|
||||
nodes = vnfd_info['instances']
|
||||
for node in nodes:
|
||||
task = 'delete_vnf_%s' % node
|
||||
task_dict[task] = {
|
||||
'action': 'tacker.delete_vnf vnf=<% $.vnf_id_{0}'
|
||||
'%>'.format(node),
|
||||
}
|
||||
return task_dict
|
||||
|
||||
def _build_output_dict(self, ns):
|
||||
vnfds = ns['vnfd_details']
|
||||
task_dict = dict()
|
||||
for vnfd_name, vnfd_info in iteritems(vnfds):
|
||||
nodes = vnfd_info['instances']
|
||||
for node in nodes:
|
||||
for op_name in OUTPUT[self.wf_name]:
|
||||
task_dict[op_name + '_' + node] = \
|
||||
'<% $.{0}_{1} %>'.format(op_name, node)
|
||||
return task_dict
|
||||
|
||||
def get_input_dict(self):
|
||||
return self.input_dict
|
||||
|
||||
def build_input(self, ns, params):
|
||||
vnfds = ns['vnfd_details']
|
||||
id = str(uuid.uuid4())
|
||||
self.input_dict = {'vnf': {}}
|
||||
for vnfd_name, vnfd_info in iteritems(vnfds):
|
||||
nodes = vnfd_info['instances']
|
||||
for node in nodes:
|
||||
self.input_dict['vnf'][node] = dict()
|
||||
self.input_dict['vnf'][node]['vnf'] = {
|
||||
'attributes': {},
|
||||
'vim_id': ns['ns'].get('vim_id', ''),
|
||||
'vnfd_id': vnfd_info['id'],
|
||||
'name': 'create_vnf_%s_%s' % (vnfd_info['id'],
|
||||
id)
|
||||
}
|
||||
if params.get(vnfd_name):
|
||||
self.input_dict['vnf'][node]['vnf']['attributes'] = {
|
||||
'param_values': params.get(vnfd_name)
|
||||
}
|
||||
|
||||
def create_vnf(self, **kwargs):
|
||||
ns = kwargs.get('ns')
|
||||
params = kwargs.get('params')
|
||||
# TODO(anyone): Keep this statements in a loop and
|
||||
# remove in all the methods.
|
||||
self.definition[self.wf_identifier]['tasks'] = dict()
|
||||
self.definition[self.wf_identifier]['tasks'].update(
|
||||
self._add_create_vnf_tasks(ns))
|
||||
self.definition[self.wf_identifier]['tasks'].update(
|
||||
self._add_wait_vnf_tasks(ns))
|
||||
self.definition[self.wf_identifier]['tasks'].update(
|
||||
self._add_delete_vnf_tasks(ns))
|
||||
self.definition[self.wf_identifier]['output'] = \
|
||||
self._build_output_dict(ns)
|
||||
self.build_input(ns, params)
|
||||
|
||||
def delete_vnf(self, ns):
|
||||
ns_dict = {'vnfd_details': {}}
|
||||
vnf_ids = ast.literal_eval(ns['vnf_ids'])
|
||||
self.definition[self.wf_identifier]['input'] = []
|
||||
for vnf in vnf_ids.keys():
|
||||
vnf_key = 'vnf_id_' + vnf
|
||||
self.definition[self.wf_identifier]['input'].append(vnf_key)
|
||||
self.input_dict[vnf_key] = vnf_ids[vnf]
|
||||
ns_dict['vnfd_details'][vnf] = {'instances': [vnf]}
|
||||
self.definition[self.wf_identifier]['tasks'] = dict()
|
||||
self.definition[self.wf_identifier]['tasks'].update(
|
||||
self._add_delete_vnf_tasks(ns_dict))
|
@ -0,0 +1,37 @@
|
||||
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
|
||||
imports:
|
||||
- test-ns-vnfd1
|
||||
- test-ns-vnfd2
|
||||
|
||||
topology_template:
|
||||
inputs:
|
||||
vl1_name:
|
||||
type: string
|
||||
description: name of VL1 virtuallink
|
||||
default: net_mgmt
|
||||
vl2_name:
|
||||
type: string
|
||||
description: name of VL2 virtuallink
|
||||
default: net0
|
||||
node_templates:
|
||||
VNF1:
|
||||
type: tosca.nodes.nfv.VNF1
|
||||
requirements:
|
||||
- virtualLink1: VL1
|
||||
- virtualLink2: VL2
|
||||
|
||||
VNF2:
|
||||
type: tosca.nodes.nfv.VNF2
|
||||
|
||||
VL1:
|
||||
type: tosca.nodes.nfv.VL
|
||||
properties:
|
||||
network_name: {get_input: vl1_name}
|
||||
vendor: tacker
|
||||
|
||||
VL2:
|
||||
type: tosca.nodes.nfv.VL
|
||||
properties:
|
||||
network_name: {get_input: vl2_name}
|
||||
vendor: tacker
|
||||
|
@ -0,0 +1,98 @@
|
||||
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
|
||||
|
||||
description: Demo example
|
||||
node_types:
|
||||
tosca.nodes.nfv.VNF1:
|
||||
requirements:
|
||||
- virtualLink1:
|
||||
type: tosca.nodes.nfv.VL
|
||||
required: true
|
||||
- virtualLink2:
|
||||
type: tosca.nodes.nfv.VL
|
||||
required: true
|
||||
capabilities:
|
||||
forwader1:
|
||||
type: tosca.capabilities.nfv.Forwarder
|
||||
forwader2:
|
||||
type: tosca.capabilities.nfv.Forwarder
|
||||
|
||||
topology_template:
|
||||
substitution_mappings:
|
||||
node_type: tosca.nodes.nfv.VNF1
|
||||
requirements:
|
||||
virtualLink1: [CP11, virtualLink]
|
||||
virtualLink2: [CP14, virtualLink]
|
||||
capabilities:
|
||||
forwarder1: [CP11, forwarder]
|
||||
forwarder2: [CP14, forwarder]
|
||||
|
||||
node_templates:
|
||||
VDU1:
|
||||
type: tosca.nodes.nfv.VDU.Tacker
|
||||
properties:
|
||||
image: cirros-0.3.4-x86_64-uec
|
||||
flavor: m1.tiny
|
||||
availability_zone: nova
|
||||
mgmt_driver: noop
|
||||
config: |
|
||||
param0: key1
|
||||
param1: key2
|
||||
|
||||
CP11:
|
||||
type: tosca.nodes.nfv.CP.Tacker
|
||||
properties:
|
||||
management: true
|
||||
anti_spoofing_protection: false
|
||||
requirements:
|
||||
- virtualBinding:
|
||||
node: VDU1
|
||||
|
||||
CP12:
|
||||
type: tosca.nodes.nfv.CP.Tacker
|
||||
properties:
|
||||
anti_spoofing_protection: false
|
||||
requirements:
|
||||
- virtualLink:
|
||||
node: VL2
|
||||
- virtualBinding:
|
||||
node: VDU1
|
||||
|
||||
VDU2:
|
||||
type: tosca.nodes.nfv.VDU.Tacker
|
||||
properties:
|
||||
image: cirros-0.3.4-x86_64-uec
|
||||
flavor: m1.medium
|
||||
availability_zone: nova
|
||||
mgmt_driver: noop
|
||||
config: |
|
||||
param0: key1
|
||||
param1: key2
|
||||
|
||||
CP13:
|
||||
type: tosca.nodes.nfv.CP.Tacker
|
||||
properties:
|
||||
management: true
|
||||
requirements:
|
||||
- virtualLink:
|
||||
node: VL1
|
||||
- virtualBinding:
|
||||
node: VDU2
|
||||
|
||||
CP14:
|
||||
type: tosca.nodes.nfv.CP.Tacker
|
||||
requirements:
|
||||
- virtualBinding:
|
||||
node: VDU2
|
||||
|
||||
VL1:
|
||||
type: tosca.nodes.nfv.VL
|
||||
properties:
|
||||
network_name: net_mgmt
|
||||
vendor: Tacker
|
||||
|
||||
VL2:
|
||||
type: tosca.nodes.nfv.VL
|
||||
properties:
|
||||
network_name: net0
|
||||
vendor: Tacker
|
||||
|
@ -0,0 +1,68 @@
|
||||
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
|
||||
|
||||
description: Demo example
|
||||
|
||||
node_types:
|
||||
tosca.nodes.nfv.VNF2:
|
||||
capabilities:
|
||||
forwarder1:
|
||||
type: tosca.capabilities.nfv.Forwarder
|
||||
topology_template:
|
||||
substitution_mappings:
|
||||
node_type: tosca.nodes.nfv.VNF2
|
||||
capabilities:
|
||||
forwarder1: [CP21, forwarder]
|
||||
node_templates:
|
||||
VDU1:
|
||||
type: tosca.nodes.nfv.VDU.Tacker
|
||||
properties:
|
||||
image: cirros-0.3.4-x86_64-uec
|
||||
flavor: m1.tiny
|
||||
availability_zone: nova
|
||||
mgmt_driver: noop
|
||||
config: |
|
||||
param0: key1
|
||||
param1: key2
|
||||
|
||||
CP21:
|
||||
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: cirros-0.3.4-x86_64-uec
|
||||
flavor: m1.medium
|
||||
availability_zone: nova
|
||||
mgmt_driver: noop
|
||||
config: |
|
||||
param0: key1
|
||||
param1: key2
|
||||
|
||||
CP22:
|
||||
type: tosca.nodes.nfv.CP.Tacker
|
||||
requirements:
|
||||
- virtualLink:
|
||||
|