diff options
author | jose.lausuch <jose.lausuch@ericsson.com> | 2016-11-18 10:58:16 +0100 |
---|---|---|
committer | jose.lausuch <jose.lausuch@ericsson.com> | 2016-11-22 15:20:48 +0100 |
commit | f8f0f71fcde7511605695d152f5e777c19a50547 (patch) | |
tree | 5bd78a0634701bfe968879a6a0f990e3cf7c2c55 | |
parent | 3ae02c7d5f4c934e20ab0057172c29a68ff9aa1f (diff) |
Switch SFC call to sfc repository
The SFC testcase code has been moved from Functest to SFC repo.
1) Add SFC repo in the Docker image
2) Change call in exec_tests
3) Remove code from Functest
Change-Id: Ie6705d047b04646942d89215e992f46f8c4e58db
Signed-off-by: jose.lausuch <jose.lausuch@ericsson.com>
-rw-r--r-- | docker/Dockerfile | 1 | ||||
-rw-r--r-- | functest/ci/exec_test.sh | 5 | ||||
-rw-r--r-- | functest/opnfv_tests/features/sfc/SSHUtils.py | 120 | ||||
-rwxr-xr-x | functest/opnfv_tests/features/sfc/compute_presetup_CI.bash | 27 | ||||
-rwxr-xr-x | functest/opnfv_tests/features/sfc/correct_classifier.bash | 37 | ||||
-rwxr-xr-x | functest/opnfv_tests/features/sfc/delete.sh | 15 | ||||
-rw-r--r-- | functest/opnfv_tests/features/sfc/ovs_utils.py | 137 | ||||
-rwxr-xr-x | functest/opnfv_tests/features/sfc/prepare_odl_sfc.bash | 38 | ||||
-rwxr-xr-x | functest/opnfv_tests/features/sfc/prepare_odl_sfc.py | 97 | ||||
-rwxr-xr-x | functest/opnfv_tests/features/sfc/server_presetup_CI.bash | 13 | ||||
-rwxr-xr-x | functest/opnfv_tests/features/sfc/sfc.py | 593 | ||||
-rwxr-xr-x | functest/opnfv_tests/features/sfc/sfc_change_classi.bash | 7 | ||||
-rwxr-xr-x | functest/opnfv_tests/features/sfc/sfc_tacker.bash | 31 | ||||
-rwxr-xr-x | functest/opnfv_tests/features/sfc/tacker_client_install.sh | 43 | ||||
-rw-r--r-- | functest/opnfv_tests/features/sfc/test-vnfd1.yaml | 31 | ||||
-rw-r--r-- | functest/opnfv_tests/features/sfc/test-vnfd2.yaml | 31 |
16 files changed, 2 insertions, 1224 deletions
diff --git a/docker/Dockerfile b/docker/Dockerfile index 5afb4aac..54d14bf1 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -87,6 +87,7 @@ RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/parser ${repo RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/doctor ${repos_dir}/doctor RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/ovno ${repos_dir}/ovno RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/promise ${repos_dir}/promise +RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/sfc ${repos_dir}/sfc RUN git clone --depth 1 https://gerrit.opnfv.org/gerrit/securityscanning ${repos_dir}/securityscanning RUN git clone --depth 1 https://gerrit.opnfv.org/gerrit/releng ${repos_dir}/releng diff --git a/functest/ci/exec_test.sh b/functest/ci/exec_test.sh index 234a4d24..b15f5351 100644 --- a/functest/ci/exec_test.sh +++ b/functest/ci/exec_test.sh @@ -160,13 +160,10 @@ function run_test(){ python ${FUNCTEST_TEST_DIR}/features/domino.py $report ;; "odl-sfc") - pip install --upgrade python-keystoneclient==1.7.4 - ODL_SFC_DIR=${FUNCTEST_TEST_DIR}/features/sfc - # pass FUNCTEST_REPO_DIR inside prepare_odl_sfc.bash + ODL_SFC_DIR=${repos_dir}/sfc/tests/functest/odl-sfc FUNCTEST_REPO_DIR=${FUNCTEST_REPO_DIR} python ${ODL_SFC_DIR}/prepare_odl_sfc.py || exit $? source ${ODL_SFC_DIR}/tackerc python ${ODL_SFC_DIR}/sfc.py $report - pip install --upgrade python-keystoneclient==3.5.0 ;; "parser") python ${FUNCTEST_TEST_DIR}/vnf/vRNC/parser.py $report diff --git a/functest/opnfv_tests/features/sfc/SSHUtils.py b/functest/opnfv_tests/features/sfc/SSHUtils.py deleted file mode 100644 index 9c8c2c72..00000000 --- a/functest/opnfv_tests/features/sfc/SSHUtils.py +++ /dev/null @@ -1,120 +0,0 @@ -############################################################################## -# Copyright (c) 2015 Ericsson AB and others. -# Authors: George Paraskevopoulos (geopar@intracom-telecom.com) -# Jose Lausuch (jose.lausuch@ericsson.com) -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - - -import paramiko -import functest.utils.functest_logger as rl -import os - -logger = rl.Logger('SSHUtils').getLogger() - - -def get_ssh_client(hostname, username, password=None, proxy=None): - client = None - try: - if proxy is None: - client = paramiko.SSHClient() - else: - client = ProxyHopClient() - client.configure_jump_host(proxy['ip'], - proxy['username'], - proxy['password']) - - if client is None: - raise Exception('Could not connect to client') - - client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - client.connect(hostname, - username=username, - password=password) - return client - except Exception, e: - logger.error(e) - return None - - -def get_file(ssh_conn, src, dest): - try: - sftp = ssh_conn.open_sftp() - sftp.get(src, dest) - return True - except Exception, e: - logger.error("Error [get_file(ssh_conn, '%s', '%s']: %s" % - (src, dest, e)) - return None - - -def put_file(ssh_conn, src, dest): - try: - sftp = ssh_conn.open_sftp() - sftp.put(src, dest) - return True - except Exception, e: - logger.error("Error [put_file(ssh_conn, '%s', '%s']: %s" % - (src, dest, e)) - return None - - -class ProxyHopClient(paramiko.SSHClient): - ''' - Connect to a remote server using a proxy hop - ''' - def __init__(self, *args, **kwargs): - self.logger = rl.Logger("ProxyHopClient").getLogger() - self.proxy_ssh = None - self.proxy_transport = None - self.proxy_channel = None - self.proxy_ip = None - self.proxy_ssh_key = None - self.local_ssh_key = os.path.join(os.getcwd(), 'id_rsa') - super(ProxyHopClient, self).__init__(*args, **kwargs) - - def configure_jump_host(self, jh_ip, jh_user, jh_pass, - jh_ssh_key='/root/.ssh/id_rsa'): - self.proxy_ip = jh_ip - self.proxy_ssh_key = jh_ssh_key - self.proxy_ssh = paramiko.SSHClient() - self.proxy_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - self.proxy_ssh.connect(jh_ip, - username=jh_user, - password=jh_pass) - self.proxy_transport = self.proxy_ssh.get_transport() - - def connect(self, hostname, port=22, username='root', password=None, - pkey=None, key_filename=None, timeout=None, allow_agent=True, - look_for_keys=True, compress=False, sock=None, gss_auth=False, - gss_kex=False, gss_deleg_creds=True, gss_host=None, - banner_timeout=None): - try: - if self.proxy_ssh is None: - raise Exception('You must configure the jump ' - 'host before calling connect') - - get_file_res = get_file(self.proxy_ssh, - self.proxy_ssh_key, - self.local_ssh_key) - if get_file_res is None: - raise Exception('Could\'t fetch SSH key from jump host') - proxy_key = (paramiko.RSAKey - .from_private_key_file(self.local_ssh_key)) - - self.proxy_channel = self.proxy_transport.open_channel( - "direct-tcpip", - (hostname, 22), - (self.proxy_ip, 22)) - - self.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - super(ProxyHopClient, self).connect(hostname, - username=username, - pkey=proxy_key, - sock=self.proxy_channel) - os.remove(self.local_ssh_key) - except Exception, e: - self.logger.error(e) diff --git a/functest/opnfv_tests/features/sfc/compute_presetup_CI.bash b/functest/opnfv_tests/features/sfc/compute_presetup_CI.bash deleted file mode 100755 index 36148aa1..00000000 --- a/functest/opnfv_tests/features/sfc/compute_presetup_CI.bash +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -# This script must be use with vxlan-gpe + nsh. Once we have eth + nsh support -# in ODL, we will not need it anymore - -set -e -ssh_options='-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' -BASEDIR=`dirname $0` -INSTALLER_IP=${INSTALLER_IP:-10.20.0.2} - -pushd $BASEDIR -#ip=`sshpass -p r00tme ssh $ssh_options root@${INSTALLER_IP} 'fuel node'|grep compute|\ -#awk '{print $10}' | head -1` - -ip=$1 -echo $ip -#sshpass -p r00tme scp $ssh_options correct_classifier.bash ${INSTALLER_IP}:/root -#sshpass -p r00tme ssh $ssh_options root@${INSTALLER_IP} 'scp correct_classifier.bash '"$ip"':/root' - -sshpass -p r00tme ssh $ssh_options root@${INSTALLER_IP} 'ssh root@'"$ip"' ifconfig br-int up' -output=$(sshpass -p r00tme ssh $ssh_options root@${INSTALLER_IP} 'ssh root@'"$ip"' ip route | \ -cut -d" " -f1 | grep 11.0.0.0' ; exit 0) - -if [ -z "$output" ]; then -sshpass -p r00tme ssh $ssh_options root@${INSTALLER_IP} 'ssh root@'"$ip"' ip route add 11.0.0.0/24 \ -dev br-int' -fi diff --git a/functest/opnfv_tests/features/sfc/correct_classifier.bash b/functest/opnfv_tests/features/sfc/correct_classifier.bash deleted file mode 100755 index fb08af5c..00000000 --- a/functest/opnfv_tests/features/sfc/correct_classifier.bash +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash - -#This scripts correct the current ODL bug which does not detect -#when SFF and classifier are in the same swtich - -nsp=`ovs-ofctl -O Openflow13 dump-flows br-int table=11 | \ -grep "NXM_NX_NSP" | head -1 | cut -d',' -f13 | cut -d':' -f2 \ -| cut -d'-' -f1` - -ip=`ovs-ofctl -O Openflow13 dump-flows br-int table=11 | \ -grep NXM_NX_NSH_C1 | head -1 | cut -d':' -f5 | cut -d'-' -f1` - -output_port=`ovs-ofctl -O Openflow13 show br-int | \ -grep vxgpe | cut -d'(' -f1` - -output_port2=`echo $output_port` - -echo "This is the nsp =$(($nsp))" -echo "This is the ip=$ip" -echo "This is the vxlan-gpe port=$output_port2" - -ovs-ofctl -O Openflow13 del-flows br-int "table=11,tcp,reg0=0x1,tp_dst=80" -ovs-ofctl -O Openflow13 del-flows br-int "table=11,tcp,reg0=0x1,tp_dst=22" - -ovs-ofctl -O Openflow13 add-flow br-int "table=11,tcp,reg0=0x1,tp_dst=80 \ -actions=move:NXM_NX_TUN_ID[0..31]->NXM_NX_NSH_C2[],push_nsh,\ -load:0x1->NXM_NX_NSH_MDTYPE[],load:0x3->NXM_NX_NSH_NP[],\ -load:$ip->NXM_NX_NSH_C1[],load:$nsp->NXM_NX_NSP[0..23],\ -load:0xff->NXM_NX_NSI[],load:$ip->NXM_NX_TUN_IPV4_DST[],\ -load:$nsp->NXM_NX_TUN_ID[0..31],resubmit($output_port,0)" - -ovs-ofctl -O Openflow13 add-flow br-int "table=11,tcp,reg0=0x1,tp_dst=22\ - actions=move:NXM_NX_TUN_ID[0..31]->NXM_NX_NSH_C2[],push_nsh,\ -load:0x1->NXM_NX_NSH_MDTYPE[],load:0x3->NXM_NX_NSH_NP[],\ -load:$ip->NXM_NX_NSH_C1[],load:$nsp->NXM_NX_NSP[0..23],\ -load:0xff->NXM_NX_NSI[],load:$ip->NXM_NX_TUN_IPV4_DST[],\ -load:$nsp->NXM_NX_TUN_ID[0..31],resubmit($output_port,0)" diff --git a/functest/opnfv_tests/features/sfc/delete.sh b/functest/opnfv_tests/features/sfc/delete.sh deleted file mode 100755 index c04ae637..00000000 --- a/functest/opnfv_tests/features/sfc/delete.sh +++ /dev/null @@ -1,15 +0,0 @@ -tacker sfc-classifier-delete red_http -tacker sfc-classifier-delete blue_ssh -tacker sfc-classifier-delete red_ssh -tacker sfc-classifier-delete blue_http -tacker sfc-delete red -tacker sfc-delete blue -tacker vnf-delete testVNF1 -tacker vnf-delete testVNF2 -tacker vnfd-delete test-vnfd1 -tacker vnfd-delete test-vnfd2 -openstack stack delete sfc --y -openstack stack delete sfc_test1 --y -openstack stack delete sfc_test2 --y -nova delete client -nova delete server diff --git a/functest/opnfv_tests/features/sfc/ovs_utils.py b/functest/opnfv_tests/features/sfc/ovs_utils.py deleted file mode 100644 index af1f232c..00000000 --- a/functest/opnfv_tests/features/sfc/ovs_utils.py +++ /dev/null @@ -1,137 +0,0 @@ -############################################################################## -# Copyright (c) 2015 Ericsson AB and others. -# Author: George Paraskevopoulos (geopar@intracom-telecom.com) -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - -import functest.utils.functest_logger as rl -import os -import time -import shutil -import re - -logger = rl.Logger('ovs_utils').getLogger() - - -class OVSLogger(object): - def __init__(self, basedir, ft_resdir): - self.ovs_dir = basedir - self.ft_resdir = ft_resdir - self.__mkdir_p(self.ovs_dir) - - def __mkdir_p(self, dirpath): - if not os.path.exists(dirpath): - os.makedirs(dirpath) - - def __ssh_host(self, ssh_conn, host_prefix='10.20.0'): - try: - _, stdout, _ = ssh_conn.exec_command('hostname -I') - hosts = stdout.readline().strip().split(' ') - found_host = [h for h in hosts if h.startswith(host_prefix)][0] - return found_host - except Exception, e: - logger.error(e) - - def __dump_to_file(self, operation, host, text, timestamp=None): - ts = (timestamp if timestamp is not None - else time.strftime("%Y%m%d-%H%M%S")) - dumpdir = os.path.join(self.ovs_dir, ts) - self.__mkdir_p(dumpdir) - fname = '{0}_{1}'.format(operation, host) - with open(os.path.join(dumpdir, fname), 'w') as f: - f.write(text) - - def __remote_cmd(self, ssh_conn, cmd): - try: - _, stdout, stderr = ssh_conn.exec_command(cmd) - errors = stderr.readlines() - if len(errors) > 0: - host = self.__ssh_host(ssh_conn) - logger.error(''.join(errors)) - raise Exception('Could not execute {0} in {1}' - .format(cmd, host)) - output = ''.join(stdout.readlines()) - return output - except Exception, e: - logger.error('[__remote_command(ssh_client, {0})]: {1}' - .format(cmd, e)) - return None - - def create_artifact_archive(self): - shutil.make_archive(self.ovs_dir, - 'zip', - root_dir=os.path.dirname(self.ovs_dir), - base_dir=self.ovs_dir) - shutil.copy2('{0}.zip'.format(self.ovs_dir), self.ft_resdir) - - def ofctl_dump_flows(self, ssh_conn, br='br-int', - choose_table=None, timestamp=None): - try: - cmd = 'ovs-ofctl -OOpenFlow13 dump-flows {0}'.format(br) - if choose_table is not None: - cmd = '{0} table={1}'.format(cmd, choose_table) - output = self.__remote_cmd(ssh_conn, cmd) - operation = 'ofctl_dump_flows' - host = self.__ssh_host(ssh_conn) - self.__dump_to_file(operation, host, output, timestamp=timestamp) - return output - except Exception, e: - logger.error('[ofctl_dump_flows(ssh_client, {0}, {1})]: {2}' - .format(br, choose_table, e)) - return None - - def vsctl_show(self, ssh_conn, timestamp=None): - try: - cmd = 'ovs-vsctl show' - output = self.__remote_cmd(ssh_conn, cmd) - operation = 'vsctl_show' - host = self.__ssh_host(ssh_conn) - self.__dump_to_file(operation, host, output, timestamp=timestamp) - return output - except Exception, e: - logger.error('[vsctl_show(ssh_client)]: {0}'.format(e)) - return None - - def dump_ovs_logs(self, controller_clients, compute_clients, - related_error=None, timestamp=None): - if timestamp is None: - timestamp = time.strftime("%Y%m%d-%H%M%S") - - for controller_client in controller_clients: - self.ofctl_dump_flows(controller_client, - timestamp=timestamp) - self.vsctl_show(controller_client, - timestamp=timestamp) - - for compute_client in compute_clients: - self.ofctl_dump_flows(compute_client, - timestamp=timestamp) - self.vsctl_show(compute_client, - timestamp=timestamp) - - if related_error is not None: - dumpdir = os.path.join(self.ovs_dir, timestamp) - with open(os.path.join(dumpdir, 'error'), 'w') as f: - f.write(related_error) - - def ofctl_time_counter(self, ssh_conn): - try: - # We get the flows from table 11 - table = 11 - br = "br-int" - output = self.ofctl_dump_flows(ssh_conn, br, table) - pattern = "NXM_NX_NSP" - rsps = [] - lines = output.split(",") - for line in lines: - is_there = re.findall(pattern, line) - if is_there: - value = line.split(":")[1].split("-")[0] - rsps.append(value) - return rsps - except Exception, e: - logger.error('Error when countering %s' % e) - return None diff --git a/functest/opnfv_tests/features/sfc/prepare_odl_sfc.bash b/functest/opnfv_tests/features/sfc/prepare_odl_sfc.bash deleted file mode 100755 index c4d8f4f8..00000000 --- a/functest/opnfv_tests/features/sfc/prepare_odl_sfc.bash +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -# -# Author: George Paraskevopoulos (geopar@intracom-telecom.com) -# Manuel Buil (manuel.buil@ericsson.com) -# Prepares the controller and the compute nodes for the odl-sfc testcase -# -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -# - -ODL_SFC_LOG=/home/opnfv/functest/results/odl-sfc.log -ODL_SFC_DIR=${FUNCTEST_REPO_DIR}/opnfv_tests/features/sfc - -# Split the output to the log file and redirect STDOUT and STDERR to /dev/null -bash ${ODL_SFC_DIR}/server_presetup_CI.bash |& \ - tee -a ${ODL_SFC_LOG} 1>/dev/null 2>&1 - -# Get return value from PIPESTATUS array (bash specific feature) -ret_val=${PIPESTATUS[0]} -if [ $ret_val != 0 ]; then - echo "The tacker server deployment failed" - exit $ret_val -fi -echo "The tacker server was deployed successfully" - -bash ${ODL_SFC_DIR}/compute_presetup_CI.bash |& \ - tee -a ${ODL_SFC_LOG} 1>/dev/null 2>&1 - -ret_val=${PIPESTATUS[0]} -if [ $ret_val != 0 ]; then - exit $ret_val -fi - -exit 0 diff --git a/functest/opnfv_tests/features/sfc/prepare_odl_sfc.py b/functest/opnfv_tests/features/sfc/prepare_odl_sfc.py deleted file mode 100755 index 8ba287e9..00000000 --- a/functest/opnfv_tests/features/sfc/prepare_odl_sfc.py +++ /dev/null @@ -1,97 +0,0 @@ -# -# Author: George Paraskevopoulos (geopar@intracom-telecom.com) -# Manuel Buil (manuel.buil@ericsson.com) -# Prepares the controller and the compute nodes for the odl-sfc testcase -# -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -# - -import os -import sys -import subprocess -import paramiko -import functest.utils.functest_logger as ft_logger - -logger = ft_logger.Logger("ODL_SFC").getLogger() - -try: - FUNCTEST_REPO_DIR = os.environ['FUNCTEST_REPO_DIR'] -except: - logger.debug("FUNCTEST_REPO_DIR does not exist!!!!!") - -FUNCTEST_REPO_DIR = "/home/opnfv/repos/functest" - -try: - INSTALLER_IP = os.environ['INSTALLER_IP'] - -except: - logger.debug("INSTALLER_IP does not exist. We create 10.20.0.2") - INSTALLER_IP = "10.20.0.2" - -os.environ['ODL_SFC_LOG'] = "/home/opnfv/functest/results/odl-sfc.log" -os.environ['ODL_SFC_DIR'] = os.path.join(FUNCTEST_REPO_DIR, - "functest/opnfv_tests/features/sfc") - -command = os.environ['ODL_SFC_DIR'] + ("/server_presetup_CI.bash | " - "tee -a ${ODL_SFC_LOG} " - "1>/dev/null 2>&1") - -output = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) - -# This code is for debugging purposes -# for line in iter(output.stdout.readline, ''): -# i = line.rstrip() -# print(i) - -# Make sure the process is finished before checking the returncode -if not output.poll(): - output.wait() - -# Get return value -if output.returncode: - print("The presetup of the server did not work") - sys.exit(output.returncode) - -logger.info("The presetup of the server worked ") - -ssh_options = "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" -ssh = paramiko.SSHClient() -ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - -try: - ssh.connect(INSTALLER_IP, username="root", - password="r00tme", timeout=2) - command = "fuel node | grep compute | awk '{print $10}'" - logger.info("Executing ssh to collect the compute IPs") - (stdin, stdout, stderr) = ssh.exec_command(command) -except: - logger.debug("Something went wrong in the ssh to collect the computes IP") - -output = stdout.readlines() -for ip in output: - command = os.environ['ODL_SFC_DIR'] + ("/compute_presetup_CI.bash " - "" + ip.rstrip() + "| tee -a " - "${ODL_SFC_LOG} 1>/dev/null 2>&1") - - output = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) - -# This code is for debugging purposes -# for line in iter(output.stdout.readline, ''): -# print(line) -# sys.stdout.flush() - - output.stdout.close() - - if not (output.poll()): - output.wait() - - # Get return value - if output.returncode: - print("The compute config did not work on compute %s" % ip) - sys.exit(output.returncode) - -sys.exit(0) diff --git a/functest/opnfv_tests/features/sfc/server_presetup_CI.bash b/functest/opnfv_tests/features/sfc/server_presetup_CI.bash deleted file mode 100755 index 240353f5..00000000 --- a/functest/opnfv_tests/features/sfc/server_presetup_CI.bash +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -set -e -ssh_options='-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' -BASEDIR=`dirname $0` -INSTALLER_IP=${INSTALLER_IP:-10.20.0.2} - -pushd $BASEDIR -ip=$(sshpass -p r00tme ssh $ssh_options root@${INSTALLER_IP} 'fuel node'|grep controller|awk '{print $10}' | head -1) -echo $ip - -sshpass -p r00tme scp $ssh_options delete.sh ${INSTALLER_IP}:/root -sshpass -p r00tme ssh $ssh_options root@${INSTALLER_IP} 'scp '"$ip"':/root/tackerc .' -sshpass -p r00tme scp $ssh_options ${INSTALLER_IP}:/root/tackerc $BASEDIR diff --git a/functest/opnfv_tests/features/sfc/sfc.py b/functest/opnfv_tests/features/sfc/sfc.py deleted file mode 100755 index 1956eb37..00000000 --- a/functest/opnfv_tests/features/sfc/sfc.py +++ /dev/null @@ -1,593 +0,0 @@ -import argparse -import os -import subprocess -import sys -import time -import functest.utils.functest_logger as ft_logger -import functest.utils.functest_utils as ft_utils -import functest.utils.openstack_utils as os_utils -import re -import json -import SSHUtils as ssh_utils -import ovs_utils -import thread - -parser = argparse.ArgumentParser() - -parser.add_argument("-r", "--report", - help="Create json result file", - action="store_true") - -args = parser.parse_args() - -""" logging configuration """ -logger = ft_logger.Logger("ODL_SFC").getLogger() - -FUNCTEST_RESULTS_DIR = '/home/opnfv/functest/results/odl-sfc' -FUNCTEST_REPO = ft_utils.FUNCTEST_REPO -REPO_PATH = os.path.join(os.environ['repos_dir'], 'functest/') -CLIENT = "client" -SERVER = "server" -FLAVOR = "custom" -IMAGE_NAME = "sf_nsh_colorado" -IMAGE_FILENAME = "sf_nsh_colorado.qcow2" -IMAGE_FORMAT = "qcow2" -IMAGE_DIR = "/home/opnfv/functest/data" -IMAGE_PATH = os.path.join(IMAGE_DIR, IMAGE_FILENAME) -IMAGE_URL = "http://artifacts.opnfv.org/sfc/demo/" + IMAGE_FILENAME - -# NEUTRON Private Network parameters -NET_NAME = "example-net" -SUBNET_NAME = "example-subnet" -SUBNET_CIDR = "11.0.0.0/24" -ROUTER_NAME = "example-router" -SECGROUP_NAME = "example-sg" -SECGROUP_DESCR = "Example Security group" -SFC_TEST_DIR = os.path.join(REPO_PATH, "functest/opnfv_tests/features/sfc/") -TACKER_SCRIPT = SFC_TEST_DIR + "sfc_tacker.bash" -TACKER_CHANGECLASSI = SFC_TEST_DIR + "sfc_change_classi.bash" -ssh_options = '-q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' -json_results = {"tests": 4, "failures": 0} - -PROXY = { - 'ip': '10.20.0.2', - 'username': 'root', - 'password': 'r00tme' -} - -# run given command locally and return commands output if success - - -def run_cmd(cmd, wdir=None, ignore_stderr=False, ignore_no_output=True): - pipe = subprocess.Popen(cmd, shell=True, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, cwd=wdir) - - (output, errors) = pipe.communicate() - if output: - output = output.strip() - if pipe.returncode < 0: - logger.error(errors) - return False - if errors: - logger.error(errors) - if ignore_stderr: - return True - else: - return False - - if ignore_no_output: - if not output: - return True - - return output - -# run given command on OpenStack controller - - -def run_cmd_on_cntlr(cmd): - ip_cntlrs = get_openstack_node_ips("controller") - if not ip_cntlrs: - return None - - ssh_cmd = "ssh %s %s %s" % (ssh_options, ip_cntlrs[0], cmd) - return run_cmd_on_fm(ssh_cmd) - -# run given command on OpenStack Compute node - - -def run_cmd_on_compute(cmd): - ip_computes = get_openstack_node_ips("compute") - if not ip_computes: - return None - - ssh_cmd = "ssh %s %s %s" % (ssh_options, ip_computes[0], cmd) - return run_cmd_on_fm(ssh_cmd) - -# run given command on Fuel Master - - -def run_cmd_on_fm(cmd, username="root", passwd="r00tme"): - ip = os.environ.get("INSTALLER_IP") - ssh_cmd = "sshpass -p %s ssh %s %s@%s %s" % ( - passwd, ssh_options, username, ip, cmd) - return run_cmd(ssh_cmd) - -# run given command on Remote Machine, Can be VM - - -def run_cmd_remote(ip, cmd, username="root", passwd="opnfv"): - ssh_opt_append = "%s -o ConnectTimeout=50 " % ssh_options - ssh_cmd = "sshpass -p %s ssh %s %s@%s %s" % ( - passwd, ssh_opt_append, username, ip, cmd) - return run_cmd(ssh_cmd) - -# Get OpenStack Nodes IP Address - - -def get_openstack_node_ips(role): - fuel_env = os.environ.get("FUEL_ENV") - if fuel_env is not None: - cmd = "fuel2 node list -f json -e %s" % fuel_env - else: - cmd = "fuel2 node list -f json" - - nodes = run_cmd_on_fm(cmd) - ips = [] - nodes = json.loads(nodes) - for node in nodes: - if role in node["roles"]: - ips.append(node["ip"]) - - return ips - -# Configures IPTABLES on OpenStack Controller - - -def configure_iptables(): - iptable_cmds = ["iptables -P INPUT ACCEPT", - "iptables -t nat -P INPUT ACCEPT", - "iptables -A INPUT -m state \ - --state NEW,ESTABLISHED,RELATED -j ACCEPT"] - - for cmd in iptable_cmds: - logger.info("Configuring %s on contoller" % cmd) - run_cmd_on_cntlr(cmd) - - return - - -def download_image(): - if not os.path.isfile(IMAGE_PATH): - logger.info("Downloading image") - ft_utils.download_url(IMAGE_URL, IMAGE_DIR) - - logger.info("Using old image") - return - - -def setup_glance(glance_client): - image_id = os_utils.create_glance_image(glance_client, - IMAGE_NAME, - IMAGE_PATH, - disk=IMAGE_FORMAT, - container="bare", - public=True) - - return image_id - - -def setup_neutron(neutron_client): - n_dict = os_utils.create_network_full(neutron_client, - NET_NAME, - SUBNET_NAME, - ROUTER_NAME, - SUBNET_CIDR) - if not n_dict: - logger.error("failed to create neutron network") - sys.exit(-1) - - network_id = n_dict["net_id"] - return network_id - - -def setup_ingress_egress_secgroup(neutron_client, protocol, - min_port=None, max_port=None): - secgroups = os_utils.get_security_groups(neutron_client) - for sg in secgroups: - os_utils.create_secgroup_rule(neutron_client, sg['id'], - 'ingress', protocol, - port_range_min=min_port, - port_range_max=max_port) - os_utils.create_secgroup_rule(neutron_client, sg['id'], - 'egress', protocol, - port_range_min=min_port, - port_range_max=max_port) - return - - -def setup_security_groups(neutron_client): - sg_id = os_utils.create_security_group_full(neutron_client, - SECGROUP_NAME, SECGROUP_DESCR) - setup_ingress_egress_secgroup(neutron_client, "icmp") - setup_ingress_egress_secgroup(neutron_client, "udp", 67, 68) - setup_ingress_egress_secgroup(neutron_client, "tcp", 22, 22) - setup_ingress_egress_secgroup(neutron_client, "tcp", 80, 80) - return sg_id - - -def boot_instance(nova_client, name, flavor, image_id, network_id, sg_id): - logger.info("Creating instance '%s'..." % name) - logger.debug( - "Configuration:\n name=%s \n flavor=%s \n image=%s \n " - "network=%s \n" % (name, flavor, image_id, network_id)) - - instance = os_utils.create_instance_and_wait_for_active(flavor, - image_id, - network_id, - name) - - if instance is None: - logger.error("Error while booting instance.") - sys.exit(-1) - - instance_ip = instance.networks.get(NET_NAME)[0] - logger.debug("Instance '%s' got private ip '%s'." % - (name, instance_ip)) - - logger.info("Adding '%s' to security group %s" % (name, SECGROUP_NAME)) - os_utils.add_secgroup_to_instance(nova_client, instance.id, sg_id) - - return instance_ip - - -def ping(remote, pkt_cnt=1, iface=None, retries=100, timeout=None): - ping_cmd = 'ping' - - if timeout: - ping_cmd = ping_cmd + ' -w %s' % timeout - - grep_cmd = "grep -e 'packet loss' -e rtt" - - if iface is not None: - ping_cmd = ping_cmd + ' -I %s' % iface - - ping_cmd = ping_cmd + ' -i 0 -c %d %s' % (pkt_cnt, remote) - cmd = ping_cmd + '|' + grep_cmd - - while retries > 0: - output = run_cmd(cmd) - if not output: - return False - - match = re.search('(\d*)% packet loss', output) - if not match: - return False - - packet_loss = int(match.group(1)) - if packet_loss == 0: - return True - - retries = retries - 1 - - return False - - -def get_floating_ips(nova_client, neutron_client): - ips = [] - instances = nova_client.servers.list(search_opts={'all_tenants': 1}) - for instance in instances: - floatip_dic = os_utils.create_floating_ip(neutron_client) - floatip = floatip_dic['fip_addr'] - instance.add_floating_ip(floatip) - logger.info("Instance name and ip %s:%s " % (instance.name, floatip)) - logger.info("Waiting for instance %s:%s to come up" % - (instance.name, floatip)) - if not ping(floatip): - logger.info("Instance %s:%s didn't come up" % - (instance.name, floatip)) - sys.exit(1) - - if instance.name == "server": - logger.info("Server:%s is reachable" % floatip) - server_ip = floatip - elif instance.name == "client": - logger.info("Client:%s is reachable" % floatip) - client_ip = floatip - else: - logger.info("SF:%s is reachable" % floatip) - ips.append(floatip) - - return server_ip, client_ip, ips[1], ips[0] - -# Start http server on a give machine, Can be VM - - -def start_http_server(ip): - cmd = "\'python -m SimpleHTTPServer 80" - cmd = cmd + " > /dev/null 2>&1 &\'" - return run_cmd_remote(ip, cmd) - -# Set firewall using vxlan_tool.py on a give machine, Can be VM - - -def vxlan_firewall(sf, iface="eth0", port="22", block=True): - cmd = "python vxlan_tool.py" - cmd = cmd + " -i " + iface + " -d forward -v off" - if block: - cmd = "python vxlan_tool.py -i eth0 -d forward -v off -b " + port - - cmd = "sh -c 'cd /root;nohup " + cmd + " > /dev/null 2>&1 &'" - run_cmd_remote(sf, cmd) - -# Run netcat on a give machine, Can be VM - - -def netcat(s_ip, c_ip, port="80", timeout=5): - cmd = "nc -zv " - cmd = cmd + " -w %s %s %s" % (timeout, s_ip, port) - cmd = cmd + " 2>&1" - output = run_cmd_remote(c_ip, cmd) - logger.info("%s" % output) - return output - - -def is_ssh_blocked(srv_prv_ip, client_ip): - res = netcat(srv_prv_ip, client_ip, port="22") - match = re.search("nc:.*timed out:.*", res, re.M) - if match: - return True - - return False - - -def is_http_blocked(srv_prv_ip, client_ip): - res = netcat(srv_prv_ip, client_ip, port="80") - match = re.search(".* 80 port.* succeeded!", res, re.M) - if match: - return False - - return True - - -def capture_err_logs(ovs_logger, controller_clients, - compute_clients, error): - timestamp = time.strftime("%Y%m%d-%H%M%S") - ovs_logger.dump_ovs_logs(controller_clients, - compute_clients, - related_error=error, - timestamp=timestamp) - return - - -def update_json_results(name, result): - json_results.update({name: result}) - if result is not "Passed": - json_results["failures"] += 1 - - return - - -def get_ssh_clients(role): - clients = [] - for ip in get_openstack_node_ips(role): - s_client = ssh_utils.get_ssh_client(ip, - 'root', - proxy=PROXY) - clients.append(s_client) - - return clients - -# Check SSH connectivity to VNFs - - -def check_ssh(ips, retries=100): - check = [False, False] - logger.info("Checking SSH connectivity to the SFs with ips %s" % str(ips)) - while retries and not all(check): - for index, ip in enumerate(ips): - check[index] = run_cmd_remote(ip, "exit") - - if all(check): - logger.info("SSH connectivity to the SFs established") - return True - - time.sleep(3) - retries -= 1 - - return False - -# Measure the time it takes to update the classification rules - - -def capture_time_log(ovs_logger, compute_clients): - i = 0 - first_RSP = "" - start_time = time.time() - while True: - rsps = ovs_logger.ofctl_time_counter(compute_clients[0]) - if not i: - if len(rsps) > 0: - first_RSP = rsps[0] - i = i + 1 - else: - first_RSP = 0 - i = i + 1 - if (len(rsps) > 1): - if(first_RSP != rsps[0]): - if (rsps[0] == rsps[1]): - stop_time = time.time() - logger.info("classification rules updated") - difference = stop_time - start_time - logger.info("It took %s seconds" % difference) - break - time.sleep(1) - return - - -def main(): - installer_type = os.environ.get("INSTALLER_TYPE") - if installer_type != "fuel": - logger.error( - '\033[91mCurrently supported only Fuel Installer type\033[0m') - sys.exit(1) - - installer_ip = os.environ.get("INSTALLER_IP") - if not installer_ip: - logger.error( - '\033[91minstaller ip is not set\033[0m') - logger.error( - '\033[91mexport INSTALLER_IP=<ip>\033[0m') - sys.exit(1) - - env_list = run_cmd_on_fm("fuel2 env list -f json") - fuel_env = os.environ.get("FUEL_ENV") - if len(eval(env_list)) > 1 and fuel_env is None: - out = run_cmd_on_fm("fuel env") - logger.error( - '\033[91mMore than one fuel env found\033[0m\n %s' % out) - logger.error( - '\033[91mexport FUEL_ENV=<env-id> to set ENV\033[0m') - sys.exit(1) - - start_time = time.time() - status = "PASS" - configure_iptables() - download_image() - _, custom_flv_id = os_utils.get_or_create_flavor( - FLAVOR, 1500, 10, 1, public=True) - if not custom_flv_id: - logger.error("Failed to create custom flavor") - sys.exit(1) - - glance_client = os_utils.get_glance_client() - neutron_client = os_utils.get_neutron_client() - nova_client = os_utils.get_nova_client() - - controller_clients = get_ssh_clients("controller") - compute_clients = get_ssh_clients("compute") - - ovs_logger = ovs_utils.OVSLogger( - os.path.join(os.getcwd(), 'ovs-logs'), - FUNCTEST_RESULTS_DIR) - - image_id = setup_glance(glance_client) - network_id = setup_neutron(neutron_client) - sg_id = setup_security_groups(neutron_client) - - boot_instance( - nova_client, CLIENT, FLAVOR, image_id, network_id, sg_id) - srv_prv_ip = boot_instance( - nova_client, SERVER, FLAVOR, image_id, network_id, sg_id) - - subprocess.call(TACKER_SCRIPT, shell=True) - - # Start measuring the time it takes to implement the classification rules - try: - thread.start_new_thread(capture_time_log, - (ovs_logger, compute_clients,)) - except Exception, e: - logger.error("Unable to start the thread that counts time %s" % e) - - server_ip, client_ip, sf1, sf2 = get_floating_ips( - nova_client, neutron_client) - - if not check_ssh([sf1, sf2]): - logger.error("Cannot establish SSH connection to the SFs") - sys.exit(1) - - logger.info("Starting HTTP server on %s" % server_ip) - if not start_http_server(server_ip): - logger.error( - '\033[91mFailed to start HTTP server on %s\033[0m' % server_ip) - sys.exit(1) - - logger.info("Starting HTTP firewall on %s" % sf2) - vxlan_firewall(sf2, port="80") - logger.info("Starting SSH firewall on %s" % sf1) - vxlan_firewall(sf1, port="22") - - logger.info("Wait for ODL to update the classification rules in OVS") - time.sleep(120) - - logger.info("Test SSH") - if is_ssh_blocked(srv_prv_ip, client_ip): - logger.info('\033[92mTEST 1 [PASSED] ==> SSH BLOCKED\033[0m') - update_json_results("Test 1: SSH Blocked", "Passed") - else: - error = ('\033[91mTEST 1 [FAILED] ==> SSH NOT BLOCKED\033[0m') - logger.error(error) - capture_err_logs( - ovs_logger, controller_clients, compute_clients, error) - update_json_results("Test 1: SSH Blocked", "Failed") - - logger.info("Test HTTP") - if not is_http_blocked(srv_prv_ip, client_ip): - logger.info('\033[92mTEST 2 [PASSED] ==> HTTP WORKS\033[0m') - update_json_results("Test 2: HTTP works", "Passed") - else: - error = ('\033[91mTEST 2 [FAILED] ==> HTTP BLOCKED\033[0m') - logger.error(error) - capture_err_logs( - ovs_logger, controller_clients, compute_clients, error) - update_json_results("Test 2: HTTP works", "Failed") - - logger.info("Changing the classification") - subprocess.call(TACKER_CHANGECLASSI, shell=True) - - # Start measuring the time it takes to implement the classification rules - try: - thread.start_new_thread(capture_time_log, - (ovs_logger, compute_clients,)) - except Exception, e: - logger.error("Unable to start the thread that counts time %s" % e) - - logger.info("Wait for ODL to update the classification rules in OVS") - time.sleep(100) - - logger.info("Test HTTP") - if is_http_blocked(srv_prv_ip, client_ip): - logger.info('\033[92mTEST 3 [PASSED] ==> HTTP Blocked\033[0m') - update_json_results("Test 3: HTTP Blocked", "Passed") - else: - error = ('\033[91mTEST 3 [FAILED] ==> HTTP WORKS\033[0m') - logger.error(error) - capture_err_logs(controller_clients, compute_clients, error) - update_json_results("Test 3: HTTP Blocked", "Failed") - - logger.info("Test SSH") - if not is_ssh_blocked(srv_prv_ip, client_ip): - logger.info('\033[92mTEST 4 [PASSED] ==> SSH Works\033[0m') - update_json_results("Test 4: SSH Works", "Passed") - else: - error = ('\033[91mTEST 4 [FAILED] ==> SSH BLOCKED\033[0m') - logger.error(error) - capture_err_logs(controller_clients, compute_clients, error) - update_json_results("Test 4: SSH Works", "Failed") - - if json_results["failures"]: - status = "FAIL" - logger.error('\033[91mSFC TESTS: %s :( FOUND %s FAIL \033[0m' % ( - status, json_results["failures"])) - - ovs_logger.create_artifact_archive() - - if args.report: - stop_time = time.time() - logger.debug("Promise Results json: " + str(json_results)) - ft_utils.push_results_to_db("sfc", - "functest-odl-sfc", - start_time, - stop_time, - status, - json_results) - - if status == "PASS": - logger.info('\033[92mSFC ALL TESTS: %s :)\033[0m' % status) - sys.exit(0) - - sys.exit(1) - -if __name__ == '__main__': - main() diff --git a/functest/opnfv_tests/features/sfc/sfc_change_classi.bash b/functest/opnfv_tests/features/sfc/sfc_change_classi.bash deleted file mode 100755 index 70375ab3..00000000 --- a/functest/opnfv_tests/features/sfc/sfc_change_classi.bash +++ /dev/null @@ -1,7 +0,0 @@ -tacker sfc-classifier-delete red_http -tacker sfc-classifier-delete red_ssh - -tacker sfc-classifier-create --name blue_http --chain blue --match source_port=0,dest_port=80,protocol=6 -tacker sfc-classifier-create --name blue_ssh --chain blue --match source_port=0,dest_port=22,protocol=6 - -tacker sfc-classifier-list diff --git a/functest/opnfv_tests/features/sfc/sfc_tacker.bash b/functest/opnfv_tests/features/sfc/sfc_tacker.bash deleted file mode 100755 index 690d5f52..00000000 --- a/functest/opnfv_tests/features/sfc/sfc_tacker.bash +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash -BASEDIR=`dirname $0` - -#import VNF descriptor -tacker vnfd-create --vnfd-file ${BASEDIR}/test-vnfd1.yaml -tacker vnfd-create --vnfd-file ${BASEDIR}/test-vnfd2.yaml - -#create instances of the imported VNF -tacker vnf-create --name testVNF1 --vnfd-name test-vnfd1 -tacker vnf-create --name testVNF2 --vnfd-name test-vnfd2 - -key=true -while $key;do - sleep 3 - active=`tacker vnf-list | grep -E 'PENDING|ERROR'` - echo -e "checking if SFs are up: $active" - if [ -z "$active" ]; then - key=false - fi -done - -#create service chain -tacker sfc-create --name red --chain testVNF1 -tacker sfc-create --name blue --chain testVNF2 - -#create classifier -tacker sfc-classifier-create --name red_http --chain red --match source_port=0,dest_port=80,protocol=6 -tacker sfc-classifier-create --name red_ssh --chain red --match source_port=0,dest_port=22,protocol=6 - -tacker sfc-list -tacker sfc-classifier-list diff --git a/functest/opnfv_tests/features/sfc/tacker_client_install.sh b/functest/opnfv_tests/features/sfc/tacker_client_install.sh deleted file mode 100755 index adb9a44b..00000000 --- a/functest/opnfv_tests/features/sfc/tacker_client_install.sh +++ /dev/null @@ -1,43 +0,0 @@ -MYDIR=$(dirname $(readlink -f "$0")) -CLIENT=$(echo python-python-tackerclient_*_all.deb) -CLIREPO="tacker-client" - -# Function checks whether a python egg is available, if not, installs -function chkPPkg() { - PKG="$1" - IPPACK=$(python - <<'____EOF' -import pip -from os.path import join -for package in pip.get_installed_distributions(): - print(package.location) - print(join(package.location, *package._get_metadata("top_level.txt"))) -____EOF -) - echo "$IPPACK" | grep -q "$PKG" - if [ $? -ne 0 ];then - pip install "$PKG" - fi -} - -function envSetup() { - apt-get install -y python-all debhelper fakeroot - #pip install --upgrade python-keystoneclient==1.7.4 - chkPPkg stdeb -} - -# Function installs python-tackerclient from github -function deployTackerClient() { - cd $MYDIR - git clone -b 'SFC_refactor' https://github.com/trozet/python-tackerclient.git $CLIREPO - cd $CLIREPO - python setup.py --command-packages=stdeb.command bdist_deb - cd "deb_dist" - CLIENT=$(echo python-python-tackerclient_*_all.deb) - cp $CLIENT $MYDIR - dpkg -i "${MYDIR}/${CLIENT}" - apt-get -f -y install - dpkg -i "${MYDIR}/${CLIENT}" -} - -envSetup -deployTackerClient diff --git a/functest/opnfv_tests/features/sfc/test-vnfd1.yaml b/functest/opnfv_tests/features/sfc/test-vnfd1.yaml deleted file mode 100644 index 5c672e38..00000000 --- a/functest/opnfv_tests/features/sfc/test-vnfd1.yaml +++ /dev/null @@ -1,31 +0,0 @@ -template_name: test-vnfd1 -description: firewall1-example - -service_properties: - Id: firewall1-vnfd - vendor: tacker - version: 1 - type: - - firewall1 -vdus: - vdu1: - id: vdu1 - vm_image: sf_nsh_colorado - instance_type: custom - service_type: firewall1 - - network_interfaces: - management: - network: example-net - management: true - - placement_policy: - availability_zone: nova - - auto-scaling: noop - monitoring_policy: noop - failure_policy: respawn - - config: - param0: key0 - param1: key1 diff --git a/functest/opnfv_tests/features/sfc/test-vnfd2.yaml b/functest/opnfv_tests/features/sfc/test-vnfd2.yaml deleted file mode 100644 index 8a570ab9..00000000 --- a/functest/opnfv_tests/features/sfc/test-vnfd2.yaml +++ /dev/null @@ -1,31 +0,0 @@ -template_name: test-vnfd2 -description: firewall2-example - -service_properties: - Id: firewall2-vnfd - vendor: tacker - version: 1 - type: - - firewall2 -vdus: - vdu1: - id: vdu1 - vm_image: sf_nsh_colorado - instance_type: custom - service_type: firewall2 - - network_interfaces: - management: - network: example-net - management: true - - placement_policy: - availability_zone: nova - - auto-scaling: noop - monitoring_policy: noop - failure_policy: respawn - - config: - param0: key0 - param1: key1 |