From 29e6411f11766c3048aec82e0d2b95be4ac3b689 Mon Sep 17 00:00:00 2001 From: schillinge Date: Thu, 14 Mar 2019 22:44:03 +0100 Subject: [PATCH] Added example for performing a performance analysis of VNFFGs The example uses jinja2 for templating the VNFFG NSD in order to test increasingly long forwarding chains. Change-Id: If3ccad70a67b8b03a2ab43356f17a442a8abc770 Signed-off-by: schillinge --- examples/autogenerated/vnffg-nsd/.gitkeep | 0 examples/images/trafficdebug/Dockerfile | 22 ++++ examples/performance_measurements/vnffg.py | 120 +++++++++++++++++++++ examples/services/vnffg/vnffg.yaml | 95 ++++++++++++++++ examples/templates/vnffg-nsd.yaml | 90 ++++++++++++++++ examples/vnfs/vnffg/vnffg.yaml | 40 +++++++ setup.py | 3 +- 7 files changed, 369 insertions(+), 1 deletion(-) create mode 100644 examples/autogenerated/vnffg-nsd/.gitkeep create mode 100644 examples/images/trafficdebug/Dockerfile create mode 100644 examples/performance_measurements/vnffg.py create mode 100644 examples/services/vnffg/vnffg.yaml create mode 100644 examples/templates/vnffg-nsd.yaml create mode 100644 examples/vnfs/vnffg/vnffg.yaml diff --git a/examples/autogenerated/vnffg-nsd/.gitkeep b/examples/autogenerated/vnffg-nsd/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/images/trafficdebug/Dockerfile b/examples/images/trafficdebug/Dockerfile new file mode 100644 index 0000000..93fb40c --- /dev/null +++ b/examples/images/trafficdebug/Dockerfile @@ -0,0 +1,22 @@ +# Copyright (c) 2019 Erik Schilling +# 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 fedora:29 + +# required for examples: +RUN dnf install -y net-tools iproute iputils iperf3 + +# for debugging: +RUN dnf install -y iftop tcpdump nmap procps-ng diff --git a/examples/performance_measurements/vnffg.py b/examples/performance_measurements/vnffg.py new file mode 100644 index 0000000..3959b3a --- /dev/null +++ b/examples/performance_measurements/vnffg.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python2 +# Copyright (c) 2019 Erik Schilling +# 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 csv +import json +import os + +import time +from jinja2 import Environment, FileSystemLoader + +from emuvim.api.osm.pre_configured_osm import PreConfiguredOSM +from emuvim.api.util.docker_utils import build_dockerfile_dir + + +# sys.path.append('/vim-emu/pycharm-debug.egg') +# import pydevd +# pydevd.settrace('10.0.2.2', port=21001, stdoutToServer=True, stderrToServer=True, suspend=False) + +prefix = os.path.dirname(os.path.abspath(__file__)) + +build_dockerfile_dir('../images/trafficdebug/', 'trafficdebug') + +env = Environment( + loader=FileSystemLoader(os.path.join(prefix, '../templates/')) +) +template = env.get_template('vnffg-nsd.yaml') + +IPERF_TIME = 30 + + +def run_iperf(node, target_ip, target_port): + vnffg_iperf_out = node.cmd('iperf3 -J -t %d -c %s -p %d' % (IPERF_TIME, target_ip, target_port)) + print(vnffg_iperf_out) + vnffg_iperf = json.loads(vnffg_iperf_out) + vnffg_rtt = vnffg_iperf['end']['streams'][0]['sender']['mean_rtt'] + vnffg_bits_per_second = vnffg_iperf['end']['sum_received']['bits_per_second'] + return vnffg_rtt, vnffg_bits_per_second + + +def main(): + with open('vnffg-%d.csv' % time.time(), 'w') as csvfile: + fieldnames = ['n', 'deploy', 'vnffg_iperf_rtt', 'vnffg_iperf_bps', + 'normal_iperf_rtt', 'normal_iperf_bps', 'delete'] + writer = csv.DictWriter(csvfile, fieldnames=fieldnames) + + writer.writeheader() + + # vim-emu increases the subnet ip part by 1 for each run + subnet = 0 + + for n in range(1, 15 + 1): + # render NSD template for current iteration + with open(os.path.join(prefix, '../autogenerated/vnffg-nsd/vnffg-nsd.yml'), 'w') as f: + f.write(template.render(n=n, subnet=subnet)) + + with PreConfiguredOSM(osm_version='master') as osm: + osm.onboard_vnfd('../vnfs/vnffg') + nsd_id = osm.onboard_nsd('../autogenerated/vnffg-nsd') + ns_create = time.time() + osm.ns_create('vnffg-%d' % n, nsd_id) + + osm.ns_wait_until_all_in_status('running') + + ns_deploy_done = time.time() + + # ensure that port chains are created, they are not reported by the API. + time.sleep(60) + + first_name = 'dc1_vnffg-%d-1--1' % n + last_name = 'dc1_vnffg-%d-%d--1' % (n, n + 1) + first_node = osm.api.compute.find_server_by_name_or_id(first_name).emulator_compute + last_node = osm.api.compute.find_server_by_name_or_id(last_name).emulator_compute + + last_node.cmd('iperf3 -s -p 80 > /dev/null &') + last_node.cmd('iperf3 -s -p 81 > /dev/null &') + + # give iperf3 servers time to start up + time.sleep(1) + + target_ip = '10.0.%d.%d' % (subnet, n + 2) + vnffg_rtt, vnffg_bits_per_second = run_iperf(first_node, target_ip, 80) + normal_rtt, normal_bits_per_second = run_iperf(first_node, target_ip, 81) + + ns_delete = time.time() + for ns in osm.ns_list(): + osm.ns_delete(ns['id']) + + osm.ns_wait_until_all_in_status('terminated') + + ns_delete_done = time.time() + measurement = { + 'n': n, + 'deploy': ns_deploy_done - ns_create, + 'vnffg_iperf_rtt': vnffg_rtt, + 'vnffg_iperf_bps': vnffg_bits_per_second, + 'normal_iperf_rtt': normal_rtt, + 'normal_iperf_bps': normal_bits_per_second, + 'delete': ns_delete_done - ns_delete + } + writer.writerow(measurement) + csvfile.flush() + + subnet += 1 + + +if __name__ == '__main__': + main() diff --git a/examples/services/vnffg/vnffg.yaml b/examples/services/vnffg/vnffg.yaml new file mode 100644 index 0000000..e7d5464 --- /dev/null +++ b/examples/services/vnffg/vnffg.yaml @@ -0,0 +1,95 @@ +# Copyright (c) 2019 Erik Schilling +# 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. + +nsd:nsd-catalog: + nsd: + - id: vnffg-example + short-name: vnffg-example + name: vnffg-example + constituent-vnfd: + - member-vnf-index: 1 + vnfd-id-ref: vnfd-traffic-view + - member-vnf-index: 2 + vnfd-id-ref: vnfd-traffic-view + - member-vnf-index: 3 + vnfd-id-ref: vnfd-traffic-view + ip-profiles: + - description: Inter VNF Link + ip-profile-params: + gateway-address: 10.0.0.210 + ip-version: ipv4 + subnet-address: 10.0.0.0/24 + dns-server: + - address: 8.8.8.8 + - address: 8.8.8.9 + dhcp-params: + count: 200 + start-address: 10.0.0.1 + name: ipprofileA + vld: + - id: vld1 + name: vld1-name + short-name: vld1-sname + type: ELAN + ip-profile-ref: ipprofileA + vnfd-connection-point-ref: + - member-vnf-index-ref: 1 + vnfd-id-ref: vnfd-traffic-view + vnfd-connection-point-ref: eth0 + ip-address: 10.0.0.10 + - member-vnf-index-ref: 2 + vnfd-id-ref: vnfd-traffic-view + vnfd-connection-point-ref: eth0 + ip-address: 10.0.0.11 + - member-vnf-index-ref: 3 + vnfd-id-ref: vnfd-traffic-view + vnfd-connection-point-ref: eth0 + ip-address: 10.0.0.12 + vnffgd: + - id: vnffg1 + name: vnffg1-name + short-name: vnffg1-sname + description: vnffg1-description + vendor: vnffg1-vendor + version: '1.0' + rsp: + - id: rsp1 + name: rsp1-name + vnfd-connection-point-ref: + - member-vnf-index-ref: 2 + order: 0 + vnfd-id-ref: vnfd-traffic-view + vnfd-ingress-connection-point-ref: eth0 + vnfd-egress-connection-point-ref: eth0 + - member-vnf-index-ref: 3 + order: 1 + vnfd-id-ref: vnfd-traffic-view + vnfd-ingress-connection-point-ref: eth0 + vnfd-egress-connection-point-ref: eth0 + classifier: + - id: class1 + name: class1-name + rsp-id-ref: rsp1 + member-vnf-index-ref: 1 + vnfd-id-ref: vnfd-traffic-view + vnfd-connection-point-ref: eth0 + match-attributes: + - id: match1 + ip-proto: 6 # TCP + source-ip-address: 10.0.0.2 + destination-ip-address: 10.0.0.4 + source-port: 0 + destination-port: 80 + diff --git a/examples/templates/vnffg-nsd.yaml b/examples/templates/vnffg-nsd.yaml new file mode 100644 index 0000000..a3e992c --- /dev/null +++ b/examples/templates/vnffg-nsd.yaml @@ -0,0 +1,90 @@ +# Copyright (c) 2019 Erik Schilling +# 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. + +nsd:nsd-catalog: + nsd: + - id: vnffg-example + short-name: vnffg-example + name: vnffg-example + constituent-vnfd: + - member-vnf-index: 1 + vnfd-id-ref: vnfd-traffic-view + {% for i in range(2, n + 2) %} + - member-vnf-index: {{ i }} + vnfd-id-ref: vnfd-traffic-view + {% endfor %} + ip-profiles: + - description: Inter VNF Link + ip-profile-params: + gateway-address: 10.0.{{ subnet }}.210 + ip-version: ipv4 + subnet-address: 10.0.{{ subnet }}.0/24 + dns-server: + - address: 8.8.8.8 + - address: 8.8.8.9 + dhcp-params: + count: 200 + start-address: 10.0.{{ subnet }}.1 + name: ipprofileA + vld: + - id: vld1 + name: vld1-name + short-name: vld1-sname + type: ELAN + ip-profile-ref: ipprofileA + vnfd-connection-point-ref: + - member-vnf-index-ref: 1 + vnfd-id-ref: vnfd-traffic-view + vnfd-connection-point-ref: eth0 + ip-address: 10.0.{{ subnet }}.2 + {% for i in range(2, n + 2) %} + - member-vnf-index-ref: {{ i }} + vnfd-id-ref: vnfd-traffic-view + vnfd-connection-point-ref: eth0 + ip-address: 10.0.{{ subnet }}.{{ i + 1 }} + {% endfor %} + vnffgd: + - id: vnffg1 + name: vnffg1-name + short-name: vnffg1-sname + description: vnffg1-description + vendor: vnffg1-vendor + version: '1.0' + rsp: + - id: rsp1 + name: rsp1-name + vnfd-connection-point-ref: + {% for i in range(n) %} + - member-vnf-index-ref: {{ i + 2 }} + order: {{ i }} + vnfd-id-ref: vnfd-traffic-view + vnfd-ingress-connection-point-ref: eth0 + vnfd-egress-connection-point-ref: eth0 + {% endfor %} + classifier: + - id: class1 + name: class1-name + rsp-id-ref: rsp1 + member-vnf-index-ref: 1 + vnfd-id-ref: vnfd-traffic-view + vnfd-connection-point-ref: eth0 + match-attributes: + - id: match1 + ip-proto: 6 # TCP + source-ip-address: 10.0.{{ subnet }}.2 + destination-ip-address: 10.0.{{ subnet }}.{{ n + 2 }} + source-port: 0 + destination-port: 80 + diff --git a/examples/vnfs/vnffg/vnffg.yaml b/examples/vnfs/vnffg/vnffg.yaml new file mode 100644 index 0000000..7955118 --- /dev/null +++ b/examples/vnfs/vnffg/vnffg.yaml @@ -0,0 +1,40 @@ +# Copyright (c) 2019 Erik Schilling +# 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. + +vnfd:vnfd-catalog: + vnfd: + - id: vnfd-traffic-view + short-name: vnfd-traffic-view + name: vnfd-traffic-view + vdu: + - id: vnfd-traffic-view-vdu + vm-flavor: + vcpu-count: 1 + memory-mb: 256 + storage-gb: 6 + image: 'trafficdebug' + interface: + - name: eth0 + type: EXTERNAL + position: 0 + external-connection-point-ref: eth0 + virtual-interface: + type: OM-MGMT + bandwidth: '0' + mgmt-interface: + vdu-id: vnfd-traffic-view-vdu + connection-point: + - name: eth0 + type: VPORT diff --git a/setup.py b/setup.py index 7fb1add..5bab406 100755 --- a/setup.py +++ b/setup.py @@ -59,7 +59,8 @@ setup(name='emuvim', 'gevent', 'flake8', # fixes: https://github.com/pytest-dev/pytest/issues/4770 - 'more-itertools<=5.0.0' + 'more-itertools<=5.0.0', + 'jinja2' ], zip_safe=False, entry_points={ -- 2.17.1