Add support SFC encapsulation from networking-sfc
This feature allows choosing SFC encapsulation between MPLS and NSH (default MPLS). It also apply SFC proxy to make use of correlation. Change-Id: Ia5eda02df415c9e3f6f035068176d60a14ffb68f
This commit is contained in:
parent
4b9bcfeeef
commit
0e7fffbc77
56
contrib/tacker-config/vnffg-clean.sh
Executable file
56
contrib/tacker-config/vnffg-clean.sh
Executable file
@ -0,0 +1,56 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
echo "Deleting VNF forwarding graph VNFFG1"
|
||||||
|
for vnffg in VNFFG1; do
|
||||||
|
vnffg_id=$(openstack vnf graph list | grep $vnffg | awk '{print $2}')
|
||||||
|
if [ -n "$vnffg_id" ]; then
|
||||||
|
openstack vnf graph delete $vnffg_id
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
echo "Deleting VNFs"
|
||||||
|
for vnf_name in VNF1 VNF2; do
|
||||||
|
vnf_id=$(openstack vnf list | grep $vnf_name | awk '{print $2}')
|
||||||
|
if [ -n "$vnf_id" ]; then
|
||||||
|
openstack vnf delete $vnf_id
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Deleting VNF descriptors"
|
||||||
|
for vnfd_name in VNFD1 VNFD2; do
|
||||||
|
vnfd_id=$(openstack vnf descriptor list | grep $vnfd_name | awk '{print $2}')
|
||||||
|
if [ -n "$vnfd_id" ]; then
|
||||||
|
openstack vnf descriptor delete $vnfd_id
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Deleting http_client and http_server"
|
||||||
|
for server_name in http_client http_server; do
|
||||||
|
server_id=$(openstack server list | grep $server_name | awk '{print $2}')
|
||||||
|
if [ -n "$server_id" ]; then
|
||||||
|
openstack server delete $server_id
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
echo "Deleting VIM0"
|
||||||
|
vim_id=$(openstack vim list | grep VIM0 | awk '{print $2}')
|
||||||
|
if [ -n "$vim_id" ]; then
|
||||||
|
openstack vim delete $vim_id
|
||||||
|
fi
|
||||||
|
|
64
contrib/tacker-config/vnffg-config.sh
Executable file
64
contrib/tacker-config/vnffg-config.sh
Executable file
@ -0,0 +1,64 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
network_name='net0'
|
||||||
|
network_id=$(openstack network list | grep $network_name | awk '{print $2}')
|
||||||
|
if [ -z "$network_id" ]; then
|
||||||
|
echo "Creating network net0"
|
||||||
|
openstack network create $network_name --provider-network-type=vxlan --provider-segment 1005
|
||||||
|
openstack subnet create --network $network_name --subnet-range 10.0.10.0/24 subnet-test
|
||||||
|
network_id=$(openstack network list | grep $network_name | awk '{print $2}')
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Creating HTTP client"
|
||||||
|
openstack server create --flavor m1.tiny --image cirros-0.4.0-x86_64-disk --nic net-id=$network_id http_client
|
||||||
|
echo "Creating HTTP server"
|
||||||
|
openstack server create --flavor m1.tiny --image cirros-0.4.0-x86_64-disk --nic net-id=$network_id http_server
|
||||||
|
|
||||||
|
sleep 15
|
||||||
|
|
||||||
|
ip_src=$(openstack server list | grep http_client | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
|
||||||
|
network_source_port_id=$(openstack port list | grep $ip_src | awk '{print $2}')
|
||||||
|
ip_dst=$(openstack server list | grep http_server | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
|
||||||
|
network_dest_port_id=$(openstack port list | grep $ip_dst | awk '{print $2}')
|
||||||
|
|
||||||
|
echo "Creating/ Updating ns_param.yaml file"
|
||||||
|
cat > ../../samples/tosca-templates/vnffgd/vnffg-param-file.yaml << EOL
|
||||||
|
net_src_port_id: ${network_source_port_id}
|
||||||
|
ip_dst_pre: ${ip_dst}/24
|
||||||
|
net_dst_port_id: ${network_dest_port_id}
|
||||||
|
dst_port_range: 80-80
|
||||||
|
EOL
|
||||||
|
|
||||||
|
vim_default=$(openstack vim list | grep openstack | awk '{print $10}')
|
||||||
|
if [ "$vim_default" != "True" ]; then
|
||||||
|
echo "Creating default VIM"
|
||||||
|
cat > ./vim_config.yaml << EOL
|
||||||
|
auth_url: $OS_AUTH_URL
|
||||||
|
username: $OS_USERNAME
|
||||||
|
password: $OS_PASSWORD
|
||||||
|
project_name: $OS_PROJECT_NAME
|
||||||
|
project_domain_name: $OS_PROJECT_DOMAIN_ID
|
||||||
|
user_domain_name: $OS_USER_DOMAIN_ID
|
||||||
|
EOL
|
||||||
|
openstack vim register --config-file vim_config.yaml --is-default VIM0
|
||||||
|
rm ./vim_config.yaml
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Create VNF1 and VNF2"
|
||||||
|
openstack vnf descriptor create --vnfd-file ../../samples/tosca-templates/vnffgd/tosca-vnffg-vnfd1.yaml VNFD1
|
||||||
|
openstack vnf create --vnfd-name VNFD1 --vim-name VIM0 VNF1
|
||||||
|
openstack vnf descriptor create --vnfd-file ../../samples/tosca-templates/vnffgd/tosca-vnffg-vnfd2.yaml VNFD2
|
||||||
|
openstack vnf create --vnfd-name VNFD2 --vim-name VIM0 VNF2
|
||||||
|
|
@ -121,6 +121,7 @@ without "symmetrical", you can ommit "network_dst_port_id" and "ip_dst_prefix".
|
|||||||
properties:
|
properties:
|
||||||
id: 51
|
id: 51
|
||||||
symmetrical: true
|
symmetrical: true
|
||||||
|
correlation: nsh
|
||||||
policy:
|
policy:
|
||||||
type: ACL
|
type: ACL
|
||||||
criteria:
|
criteria:
|
||||||
@ -134,14 +135,24 @@ without "symmetrical", you can ommit "network_dst_port_id" and "ip_dst_prefix".
|
|||||||
path:
|
path:
|
||||||
- forwarder: VNFD1
|
- forwarder: VNFD1
|
||||||
capability: CP12
|
capability: CP12
|
||||||
|
sfc_encap: True
|
||||||
- forwarder: VNFD2
|
- forwarder: VNFD2
|
||||||
capability: CP22
|
capability: CP22
|
||||||
|
sfc_encap: False
|
||||||
|
|
||||||
In above template, users can set **symmetrical** in properties of a forwarding
|
In above template, users can set **symmetrical** in properties of a forwarding
|
||||||
path create symmetrical VNFFG. If this property is not set, **symmetrical**
|
path create symmetrical VNFFG. If this property is not set, **symmetrical**
|
||||||
will be specified by **--symmetrical** in create VNFFG command (default value
|
will be specified by **--symmetrical** in create VNFFG command (default value
|
||||||
is False).
|
is False).
|
||||||
|
|
||||||
|
In other hand, by setting **correlation** in properties let users can choose
|
||||||
|
SFC encapsulation between MPLS or NSH (default: MPLS). If sfc_encap is True,
|
||||||
|
port pair's correlation is set to same value with **correlation** to make use
|
||||||
|
of **correlation** that SFC Encapsulation provides, otherwise port pair's
|
||||||
|
correlation is set to None to install SFC proxy `SFC_PROXY`_. Detailed
|
||||||
|
information about SFC encapsulation can be found in Networking-SFC project
|
||||||
|
`SFC_ENCAPSULATION`_
|
||||||
|
|
||||||
You can use the sample VNFFGD template for symmetrical feature (in port chain)
|
You can use the sample VNFFGD template for symmetrical feature (in port chain)
|
||||||
such as this `link <https://github.com/openstack/tacker/tree/master/samples/
|
such as this `link <https://github.com/openstack/tacker/tree/master/samples/
|
||||||
tosca-templates/vnffgd/tosca-vnffgd-symmetrical-sample.yaml>`_.
|
tosca-templates/vnffgd/tosca-vnffgd-symmetrical-sample.yaml>`_.
|
||||||
@ -298,6 +309,20 @@ Using the below command query the list of existing VNFFG templates.
|
|||||||
| 95d9-0199253db72e | myvnffg | ACTIVE | bd7829bf-85de-4f3b-960a-8482028bfb34|
|
| 95d9-0199253db72e | myvnffg | ACTIVE | bd7829bf-85de-4f3b-960a-8482028bfb34|
|
||||||
+--------------------+---------+--------+-------------+--------+--------------+
|
+--------------------+---------+--------+-------------+--------+--------------+
|
||||||
|
|
||||||
|
To verify result, user can get information of port chain in networking-sfc:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ openstack sfc port chain list --fit-width
|
||||||
|
|
||||||
|
+-----------------------+-------------------+-----------------------+-----------------------+-----------------------+----------+
|
||||||
|
| ID | Name | Port Pair Groups | Flow Classifiers | Chain Parameters | Chain ID |
|
||||||
|
+-----------------------+-------------------+-----------------------+-----------------------+-----------------------+----------+
|
||||||
|
| 60d1a3ee-8455-415e- | VNFFG1-port-chain | [u'87d7d4c2-d2d1-4a99 | [u'02fa422c-9f40-4092 | {u'symmetric': False, | 51 |
|
||||||
|
| 8ff1-e0b6b9f9f277 | | -81fb-f3d5f51dd919', | -a8b0-c04355116e5e'] | u'correlation': | |
|
||||||
|
| | | u'81213b4c-0e5e-445d- | | u'nsh'} | |
|
||||||
|
| | | add6-dea2bf55078f'] | | | |
|
||||||
|
+-----------------------+-------------------+-----------------------+-----------------------+-----------------------+----------+
|
||||||
|
|
||||||
After the user located the VNFFG the subsequent action is to update it.
|
After the user located the VNFFG the subsequent action is to update it.
|
||||||
Based on the appropriate choice, update VNFFG template.
|
Based on the appropriate choice, update VNFFG template.
|
||||||
@ -394,6 +419,7 @@ By using the below VNFFGD template we can update the exisitng VNFFG.
|
|||||||
properties:
|
properties:
|
||||||
id: 52
|
id: 52
|
||||||
symmetrical: false
|
symmetrical: false
|
||||||
|
correlation: nsh
|
||||||
policy:
|
policy:
|
||||||
type: ACL
|
type: ACL
|
||||||
criteria:
|
criteria:
|
||||||
@ -406,8 +432,10 @@ By using the below VNFFGD template we can update the exisitng VNFFG.
|
|||||||
path:
|
path:
|
||||||
- forwarder: VNFD1
|
- forwarder: VNFD1
|
||||||
capability: CP1
|
capability: CP1
|
||||||
|
sfc_encap: True
|
||||||
- forwarder: VNFD2
|
- forwarder: VNFD2
|
||||||
capability: CP2
|
capability: CP2
|
||||||
|
sfc_encap: False
|
||||||
|
|
||||||
groups:
|
groups:
|
||||||
VNFFG1:
|
VNFFG1:
|
||||||
@ -458,3 +486,5 @@ Known Issues and Limitations
|
|||||||
|
|
||||||
.. _VNF1: https://github.com/openstack/tacker/blob/master/samples/tosca-templates/vnffgd/tosca-vnffg-vnfd1.yaml
|
.. _VNF1: https://github.com/openstack/tacker/blob/master/samples/tosca-templates/vnffgd/tosca-vnffg-vnfd1.yaml
|
||||||
.. _VNF2: https://github.com/openstack/tacker/blob/master/samples/tosca-templates/vnffgd/tosca-vnffg-vnfd2.yaml
|
.. _VNF2: https://github.com/openstack/tacker/blob/master/samples/tosca-templates/vnffgd/tosca-vnffg-vnfd2.yaml
|
||||||
|
.. _SFC_PROXY: https://tools.ietf.org/html/rfc8300
|
||||||
|
.. _SFC_ENCAPSULATION: https://docs.openstack.org/networking-sfc/latest/contributor/ietf_sfc_encapsulation.html
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Add support SFC encapsulation from networking-sfc. This feature allows
|
||||||
|
choosing SFC encapsulation between MPLS and NSH (default MPLS). It also
|
||||||
|
apply SFC proxy to make use of correlation.
|
@ -25,6 +25,7 @@ topology_template:
|
|||||||
user_data_format: RAW
|
user_data_format: RAW
|
||||||
user_data: |
|
user_data: |
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||||
cat << EOF >> /etc/network/interfaces
|
cat << EOF >> /etc/network/interfaces
|
||||||
auto eth1
|
auto eth1
|
||||||
iface eth1 inet dhcp
|
iface eth1 inet dhcp
|
||||||
|
@ -25,6 +25,7 @@ topology_template:
|
|||||||
user_data_format: RAW
|
user_data_format: RAW
|
||||||
user_data: |
|
user_data: |
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||||
cat << EOF >> /etc/network/interfaces
|
cat << EOF >> /etc/network/interfaces
|
||||||
auto eth1
|
auto eth1
|
||||||
iface eth1 inet dhcp
|
iface eth1 inet dhcp
|
||||||
|
61
samples/tosca-templates/vnffgd/tosca-vnffgd-correlation.yaml
Normal file
61
samples/tosca-templates/vnffgd/tosca-vnffgd-correlation.yaml
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
|
||||||
|
|
||||||
|
description: Sample VNFFG template
|
||||||
|
|
||||||
|
topology_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.
|
||||||
|
|
||||||
|
net_dst_port_id:
|
||||||
|
type: string
|
||||||
|
description: Port UUID of dest VM.
|
||||||
|
|
||||||
|
node_templates:
|
||||||
|
|
||||||
|
Forwarding_path1:
|
||||||
|
type: tosca.nodes.nfv.FP.TackerV2
|
||||||
|
description: creates path (CP12->CP22)
|
||||||
|
properties:
|
||||||
|
id: 51
|
||||||
|
correlation: mpls
|
||||||
|
policy:
|
||||||
|
type: ACL
|
||||||
|
criteria:
|
||||||
|
- name: block_tcp
|
||||||
|
classifier:
|
||||||
|
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 }
|
||||||
|
network_dst_port_id: { get_input: net_dst_port_id }
|
||||||
|
path:
|
||||||
|
- forwarder: VNFD1
|
||||||
|
capability: CP12
|
||||||
|
sfc_encap: True
|
||||||
|
- forwarder: VNFD2
|
||||||
|
capability: CP22
|
||||||
|
sfc_encap: True
|
||||||
|
|
||||||
|
groups:
|
||||||
|
VNFFG1:
|
||||||
|
type: tosca.groups.nfv.VNFFG
|
||||||
|
description: HTTP to Corporate Net
|
||||||
|
properties:
|
||||||
|
vendor: tacker
|
||||||
|
version: 1.0
|
||||||
|
number_of_endpoints: 2
|
||||||
|
dependent_virtual_link: [VL12,VL22]
|
||||||
|
connection_point: [CP12,CP22]
|
||||||
|
constituent_vnfs: [VNFD1,VNFD2]
|
||||||
|
members: [Forwarding_path1]
|
@ -502,8 +502,10 @@ class VnffgPluginDbMixin(vnffg.VNFFGPluginBase, db_base.CommonDbMixin):
|
|||||||
'capability'], vnf_id=vnf_mapping[element['forwarder']])
|
'capability'], vnf_id=vnf_mapping[element['forwarder']])
|
||||||
# Check if this is a new VNF entry in the chain
|
# Check if this is a new VNF entry in the chain
|
||||||
if element['forwarder'] != prev_forwarder:
|
if element['forwarder'] != prev_forwarder:
|
||||||
chain_list.append({'name': vnf_info['name'],
|
chain_list.append(
|
||||||
CP: [vnf_cp]})
|
{'name': vnf_info['name'],
|
||||||
|
CP: [vnf_cp],
|
||||||
|
'sfc_encap': element.get('sfc_encap', True)})
|
||||||
prev_forwarder = element['forwarder']
|
prev_forwarder = element['forwarder']
|
||||||
# Must be an egress CP
|
# Must be an egress CP
|
||||||
else:
|
else:
|
||||||
@ -512,7 +514,6 @@ class VnffgPluginDbMixin(vnffg.VNFFGPluginBase, db_base.CommonDbMixin):
|
|||||||
'forwarder'])
|
'forwarder'])
|
||||||
else:
|
else:
|
||||||
chain_list[-1][CP].append(vnf_cp)
|
chain_list[-1][CP].append(vnf_cp)
|
||||||
|
|
||||||
return chain_list
|
return chain_list
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -1339,6 +1340,14 @@ class VnffgPluginDbMixin(vnffg.VNFFGPluginBase, db_base.CommonDbMixin):
|
|||||||
self.delete_vnffgd(context, vnffgd_id)
|
self.delete_vnffgd(context, vnffgd_id)
|
||||||
|
|
||||||
def _get_symmetrical_template(self, context, vnffg):
|
def _get_symmetrical_template(self, context, vnffg):
|
||||||
|
fp_prop = self._get_fp_properties(context, vnffg)
|
||||||
|
return fp_prop.get('symmetrical', False)
|
||||||
|
|
||||||
|
def _get_correlation_template(self, context, vnffg):
|
||||||
|
fp_prop = self._get_fp_properties(context, vnffg)
|
||||||
|
return fp_prop.get('correlation', 'mpls')
|
||||||
|
|
||||||
|
def _get_fp_properties(self, context, vnffg):
|
||||||
vnffgd_topo = None
|
vnffgd_topo = None
|
||||||
if vnffg.get('vnffgd_template'):
|
if vnffg.get('vnffgd_template'):
|
||||||
vnffgd_topo = vnffg['vnffgd_template']['topology_template']
|
vnffgd_topo = vnffg['vnffgd_template']['topology_template']
|
||||||
@ -1349,7 +1358,7 @@ class VnffgPluginDbMixin(vnffg.VNFFGPluginBase, db_base.CommonDbMixin):
|
|||||||
vnffg_name = list(vnffgd_topo['groups'].keys())[0]
|
vnffg_name = list(vnffgd_topo['groups'].keys())[0]
|
||||||
nfp_name = vnffgd_topo['groups'][vnffg_name]['members'][0]
|
nfp_name = vnffgd_topo['groups'][vnffg_name]['members'][0]
|
||||||
fp_prop = vnffgd_topo['node_templates'][nfp_name]['properties']
|
fp_prop = vnffgd_topo['node_templates'][nfp_name]['properties']
|
||||||
return fp_prop.get('symmetrical', None)
|
return fp_prop
|
||||||
|
|
||||||
def _make_template_dict(self, template, fields=None):
|
def _make_template_dict(self, template, fields=None):
|
||||||
res = {}
|
res = {}
|
||||||
|
@ -84,6 +84,7 @@ FC_MAP = {'name': 'name',
|
|||||||
'network_dst_port_id': 'logical_destination_port'}
|
'network_dst_port_id': 'logical_destination_port'}
|
||||||
|
|
||||||
CONNECTION_POINT = 'connection_points'
|
CONNECTION_POINT = 'connection_points'
|
||||||
|
SFC_ENCAP = 'sfc_encap'
|
||||||
|
|
||||||
|
|
||||||
def config_opts():
|
def config_opts():
|
||||||
@ -386,7 +387,7 @@ class OpenStack_Driver(abstract_vim_driver.VimAbstractDriver,
|
|||||||
raise ValueError('empty match field for input flow classifier')
|
raise ValueError('empty match field for input flow classifier')
|
||||||
|
|
||||||
def create_chain(self, name, path_id, fc_ids, vnfs, symmetrical=False,
|
def create_chain(self, name, path_id, fc_ids, vnfs, symmetrical=False,
|
||||||
auth_attr=None):
|
correlation='mpls', auth_attr=None):
|
||||||
if not auth_attr:
|
if not auth_attr:
|
||||||
LOG.warning("auth information required for n-sfc driver")
|
LOG.warning("auth information required for n-sfc driver")
|
||||||
return None
|
return None
|
||||||
@ -424,6 +425,12 @@ class OpenStack_Driver(abstract_vim_driver.VimAbstractDriver,
|
|||||||
ingress = cp_list[0]
|
ingress = cp_list[0]
|
||||||
egress = cp_list[1]
|
egress = cp_list[1]
|
||||||
|
|
||||||
|
# If sfc_encap is True, pp_corr is set to correlation to
|
||||||
|
# make use of correlation, otherwise pp_corr is set to None
|
||||||
|
# to install SFC proxy
|
||||||
|
sfc_encap = vnf.get(SFC_ENCAP, True)
|
||||||
|
pp_corr = correlation if sfc_encap else None
|
||||||
|
|
||||||
# valid_port_in_use function is used to find out the
|
# valid_port_in_use function is used to find out the
|
||||||
# port_pair_group_id of the existing port pair group
|
# port_pair_group_id of the existing port pair group
|
||||||
# which was created by ingress and egress of current VNF
|
# which was created by ingress and egress of current VNF
|
||||||
@ -436,6 +443,8 @@ class OpenStack_Driver(abstract_vim_driver.VimAbstractDriver,
|
|||||||
port_pair['description'] = 'port pair for ' + vnf['name']
|
port_pair['description'] = 'port pair for ' + vnf['name']
|
||||||
port_pair['ingress'] = ingress
|
port_pair['ingress'] = ingress
|
||||||
port_pair['egress'] = egress
|
port_pair['egress'] = egress
|
||||||
|
port_pair['service_function_parameters'] = {
|
||||||
|
'correlation': pp_corr}
|
||||||
port_pair_id = neutronclient_.port_pair_create(port_pair)
|
port_pair_id = neutronclient_.port_pair_create(port_pair)
|
||||||
if not port_pair_id:
|
if not port_pair_id:
|
||||||
LOG.warning("Chain creation failed due to port pair"
|
LOG.warning("Chain creation failed due to port pair"
|
||||||
@ -488,9 +497,9 @@ class OpenStack_Driver(abstract_vim_driver.VimAbstractDriver,
|
|||||||
port_chain['description'] = 'port-chain for Tacker VNFFG'
|
port_chain['description'] = 'port-chain for Tacker VNFFG'
|
||||||
port_chain['port_pair_groups'] = port_pair_group_list
|
port_chain['port_pair_groups'] = port_pair_group_list
|
||||||
port_chain['flow_classifiers'] = fc_ids
|
port_chain['flow_classifiers'] = fc_ids
|
||||||
if symmetrical:
|
port_chain['chain_parameters'] = {}
|
||||||
port_chain['chain_parameters'] = {}
|
port_chain['chain_parameters']['symmetric'] = symmetrical
|
||||||
port_chain['chain_parameters']['symmetric'] = True
|
port_chain['chain_parameters']['correlation'] = correlation
|
||||||
return neutronclient_.port_chain_create(port_chain)
|
return neutronclient_.port_chain_create(port_chain)
|
||||||
|
|
||||||
def update_chain(self, chain_id, fc_ids, vnfs,
|
def update_chain(self, chain_id, fc_ids, vnfs,
|
||||||
|
@ -345,11 +345,13 @@ class NfvoPlugin(nfvo_db_plugin.NfvoPluginDb, vnffg_db.VnffgPluginDbMixin,
|
|||||||
name_match_list.append(classifier_dict)
|
name_match_list.append(classifier_dict)
|
||||||
# grab the first VNF to check it's VIM type
|
# grab the first VNF to check it's VIM type
|
||||||
# we have already checked that all VNFs are in the same VIM
|
# we have already checked that all VNFs are in the same VIM
|
||||||
vim_obj = self._get_vim_from_vnf(context,
|
vim_obj = self._get_vim_from_vnf(
|
||||||
list(vnffg_dict[
|
context, list(vnffg_dict['vnf_mapping'].values())[0])
|
||||||
'vnf_mapping'].values())[0])
|
|
||||||
# TODO(trozet): figure out what auth info we actually need to pass
|
# TODO(trozet): figure out what auth info we actually need to pass
|
||||||
# to the driver. Is it a session, or is full vim obj good enough?
|
# to the driver. Is it a session, or is full vim obj good enough?
|
||||||
|
|
||||||
|
correlation = super(NfvoPlugin, self)._get_correlation_template(
|
||||||
|
context, vnffg_info)
|
||||||
driver_type = vim_obj['type']
|
driver_type = vim_obj['type']
|
||||||
try:
|
try:
|
||||||
fc_ids = []
|
fc_ids = []
|
||||||
@ -366,6 +368,7 @@ class NfvoPlugin(nfvo_db_plugin.NfvoPluginDb, vnffg_db.VnffgPluginDbMixin,
|
|||||||
vnfs=sfc['chain'],
|
vnfs=sfc['chain'],
|
||||||
fc_ids=fc_ids,
|
fc_ids=fc_ids,
|
||||||
symmetrical=sfc['symmetrical'],
|
symmetrical=sfc['symmetrical'],
|
||||||
|
correlation=correlation,
|
||||||
auth_attr=vim_obj['auth_cred'])
|
auth_attr=vim_obj['auth_cred'])
|
||||||
except Exception:
|
except Exception:
|
||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
|
@ -651,14 +651,15 @@ class TestNfvoPlugin(db_base.SqlTestCase):
|
|||||||
self.assertIn('id', result)
|
self.assertIn('id', result)
|
||||||
self.assertIn('status', result)
|
self.assertIn('status', result)
|
||||||
self.assertEqual('PENDING_CREATE', result['status'])
|
self.assertEqual('PENDING_CREATE', result['status'])
|
||||||
self._driver_manager.invoke.assert_called_with(mock.ANY, mock.ANY,
|
self._driver_manager.invoke.assert_called_with(
|
||||||
name=mock.ANY,
|
mock.ANY, mock.ANY,
|
||||||
path_id=mock.ANY,
|
name=mock.ANY,
|
||||||
vnfs=mock.ANY,
|
path_id=mock.ANY,
|
||||||
fc_ids=mock.ANY,
|
vnfs=mock.ANY,
|
||||||
auth_attr=mock.ANY,
|
fc_ids=mock.ANY,
|
||||||
symmetrical=mock.ANY
|
auth_attr=mock.ANY,
|
||||||
)
|
symmetrical=mock.ANY,
|
||||||
|
correlation=mock.ANY)
|
||||||
|
|
||||||
def test_create_vnffg_abstract_types(self):
|
def test_create_vnffg_abstract_types(self):
|
||||||
with patch.object(TackerManager, 'get_service_plugins') as \
|
with patch.object(TackerManager, 'get_service_plugins') as \
|
||||||
@ -673,14 +674,15 @@ class TestNfvoPlugin(db_base.SqlTestCase):
|
|||||||
self.assertIn('id', result)
|
self.assertIn('id', result)
|
||||||
self.assertIn('status', result)
|
self.assertIn('status', result)
|
||||||
self.assertEqual('PENDING_CREATE', result['status'])
|
self.assertEqual('PENDING_CREATE', result['status'])
|
||||||
self._driver_manager.invoke.assert_called_with(mock.ANY, mock.ANY,
|
self._driver_manager.invoke.assert_called_with(
|
||||||
name=mock.ANY,
|
mock.ANY, mock.ANY,
|
||||||
path_id=mock.ANY,
|
name=mock.ANY,
|
||||||
vnfs=mock.ANY,
|
path_id=mock.ANY,
|
||||||
fc_ids=mock.ANY,
|
vnfs=mock.ANY,
|
||||||
auth_attr=mock.ANY,
|
fc_ids=mock.ANY,
|
||||||
symmetrical=mock.ANY
|
auth_attr=mock.ANY,
|
||||||
)
|
symmetrical=mock.ANY,
|
||||||
|
correlation=mock.ANY)
|
||||||
|
|
||||||
@mock.patch('tacker.nfvo.nfvo_plugin.NfvoPlugin.create_vnffgd')
|
@mock.patch('tacker.nfvo.nfvo_plugin.NfvoPlugin.create_vnffgd')
|
||||||
def test_create_vnffg_abstract_types_inline(self, mock_create_vnffgd):
|
def test_create_vnffg_abstract_types_inline(self, mock_create_vnffgd):
|
||||||
@ -700,14 +702,15 @@ class TestNfvoPlugin(db_base.SqlTestCase):
|
|||||||
self.assertEqual('PENDING_CREATE', result['status'])
|
self.assertEqual('PENDING_CREATE', result['status'])
|
||||||
self.assertEqual('dummy_vnffg_inline', result['name'])
|
self.assertEqual('dummy_vnffg_inline', result['name'])
|
||||||
mock_create_vnffgd.assert_called_once_with(mock.ANY, mock.ANY)
|
mock_create_vnffgd.assert_called_once_with(mock.ANY, mock.ANY)
|
||||||
self._driver_manager.invoke.assert_called_with(mock.ANY, mock.ANY,
|
self._driver_manager.invoke.assert_called_with(
|
||||||
name=mock.ANY,
|
mock.ANY, mock.ANY,
|
||||||
path_id=mock.ANY,
|
name=mock.ANY,
|
||||||
vnfs=mock.ANY,
|
path_id=mock.ANY,
|
||||||
fc_ids=mock.ANY,
|
vnfs=mock.ANY,
|
||||||
auth_attr=mock.ANY,
|
fc_ids=mock.ANY,
|
||||||
symmetrical=mock.ANY
|
auth_attr=mock.ANY,
|
||||||
)
|
symmetrical=mock.ANY,
|
||||||
|
correlation=mock.ANY)
|
||||||
|
|
||||||
def test_create_vnffg_param_values(self):
|
def test_create_vnffg_param_values(self):
|
||||||
with patch.object(TackerManager, 'get_service_plugins') as \
|
with patch.object(TackerManager, 'get_service_plugins') as \
|
||||||
@ -722,14 +725,15 @@ class TestNfvoPlugin(db_base.SqlTestCase):
|
|||||||
self.assertIn('id', result)
|
self.assertIn('id', result)
|
||||||
self.assertIn('status', result)
|
self.assertIn('status', result)
|
||||||
self.assertEqual('PENDING_CREATE', result['status'])
|
self.assertEqual('PENDING_CREATE', result['status'])
|
||||||
self._driver_manager.invoke.assert_called_with(mock.ANY, mock.ANY,
|
self._driver_manager.invoke.assert_called_with(
|
||||||
name=mock.ANY,
|
mock.ANY, mock.ANY,
|
||||||
path_id=mock.ANY,
|
name=mock.ANY,
|
||||||
vnfs=mock.ANY,
|
path_id=mock.ANY,
|
||||||
fc_ids=mock.ANY,
|
vnfs=mock.ANY,
|
||||||
auth_attr=mock.ANY,
|
fc_ids=mock.ANY,
|
||||||
symmetrical=mock.ANY
|
auth_attr=mock.ANY,
|
||||||
)
|
symmetrical=mock.ANY,
|
||||||
|
correlation=mock.ANY)
|
||||||
|
|
||||||
def test_create_vnffg_no_classifier(self):
|
def test_create_vnffg_no_classifier(self):
|
||||||
with patch.object(TackerManager, 'get_service_plugins') as \
|
with patch.object(TackerManager, 'get_service_plugins') as \
|
||||||
@ -744,14 +748,15 @@ class TestNfvoPlugin(db_base.SqlTestCase):
|
|||||||
self.assertIn('id', result)
|
self.assertIn('id', result)
|
||||||
self.assertIn('status', result)
|
self.assertIn('status', result)
|
||||||
self.assertEqual('PENDING_CREATE', result['status'])
|
self.assertEqual('PENDING_CREATE', result['status'])
|
||||||
self._driver_manager.invoke.assert_called_with(mock.ANY, mock.ANY,
|
self._driver_manager.invoke.assert_called_with(
|
||||||
name=mock.ANY,
|
mock.ANY, mock.ANY,
|
||||||
path_id=mock.ANY,
|
name=mock.ANY,
|
||||||
vnfs=mock.ANY,
|
path_id=mock.ANY,
|
||||||
fc_ids=mock.ANY,
|
vnfs=mock.ANY,
|
||||||
auth_attr=mock.ANY,
|
fc_ids=mock.ANY,
|
||||||
symmetrical=mock.ANY
|
auth_attr=mock.ANY,
|
||||||
)
|
symmetrical=mock.ANY,
|
||||||
|
correlation=mock.ANY)
|
||||||
|
|
||||||
def test_create_vnffg_param_value_format_error(self):
|
def test_create_vnffg_param_value_format_error(self):
|
||||||
with patch.object(TackerManager, 'get_service_plugins') as \
|
with patch.object(TackerManager, 'get_service_plugins') as \
|
||||||
@ -786,14 +791,16 @@ class TestNfvoPlugin(db_base.SqlTestCase):
|
|||||||
self.assertIn('id', result)
|
self.assertIn('id', result)
|
||||||
self.assertIn('status', result)
|
self.assertIn('status', result)
|
||||||
self.assertEqual('PENDING_CREATE', result['status'])
|
self.assertEqual('PENDING_CREATE', result['status'])
|
||||||
self._driver_manager.invoke.assert_called_with(mock.ANY, mock.ANY,
|
self._driver_manager.invoke.assert_called_with(
|
||||||
name=mock.ANY,
|
mock.ANY, mock.ANY,
|
||||||
path_id=mock.ANY,
|
name=mock.ANY,
|
||||||
vnfs=mock.ANY,
|
path_id=mock.ANY,
|
||||||
fc_ids=mock.ANY,
|
vnfs=mock.ANY,
|
||||||
auth_attr=mock.ANY,
|
fc_ids=mock.ANY,
|
||||||
symmetrical=mock.ANY
|
auth_attr=mock.ANY,
|
||||||
)
|
symmetrical=mock.ANY,
|
||||||
|
correlation=mock.ANY
|
||||||
|
)
|
||||||
|
|
||||||
def test_create_vnffg_duplicate_criteria(self):
|
def test_create_vnffg_duplicate_criteria(self):
|
||||||
with patch.object(TackerManager, 'get_service_plugins') as \
|
with patch.object(TackerManager, 'get_service_plugins') as \
|
||||||
|
@ -7,6 +7,10 @@ data_types:
|
|||||||
capability:
|
capability:
|
||||||
type: string
|
type: string
|
||||||
required: true
|
required: true
|
||||||
|
sfc_encap:
|
||||||
|
type: boolean
|
||||||
|
required: false
|
||||||
|
default: true
|
||||||
|
|
||||||
tosca.nfv.datatypes.aclType:
|
tosca.nfv.datatypes.aclType:
|
||||||
properties:
|
properties:
|
||||||
@ -308,6 +312,13 @@ node_types:
|
|||||||
symmetrical:
|
symmetrical:
|
||||||
type: boolean
|
type: boolean
|
||||||
required: false
|
required: false
|
||||||
|
default: false
|
||||||
|
correlation:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
constraints:
|
||||||
|
- valid_values: [ mpls, nsh ]
|
||||||
|
default: mpls
|
||||||
policy:
|
policy:
|
||||||
type: tosca.nfv.datatypes.policyTypeV2
|
type: tosca.nfv.datatypes.policyTypeV2
|
||||||
required: false
|
required: false
|
||||||
@ -327,6 +338,13 @@ node_types:
|
|||||||
symmetrical:
|
symmetrical:
|
||||||
type: boolean
|
type: boolean
|
||||||
required: false
|
required: false
|
||||||
|
default: false
|
||||||
|
correlation:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
constraints:
|
||||||
|
- valid_values: [ mpls, nsh ]
|
||||||
|
default: mpls
|
||||||
policy:
|
policy:
|
||||||
type: tosca.nfv.datatypes.policyType
|
type: tosca.nfv.datatypes.policyType
|
||||||
required: true
|
required: true
|
||||||
|
Loading…
Reference in New Issue
Block a user