Route exchange test with testcase3 75/36575/11
authortomsou <soth@intracom-telecom.com>
Tue, 27 Jun 2017 11:48:31 +0000 (11:48 +0000)
committerPeriyasamy Palanisamy <periyasamy.palanisamy@ericsson.com>
Tue, 26 Jun 2018 13:38:17 +0000 (15:38 +0200)
This review brings up quagga VM installed with 6WIND quagga,
configures with external ip prefix and making sure that it gets
exchanged with ODL peer.

Change-Id: I9ba677e74f24258f7cc59db70b013fbdbbec917a
Signed-off-by: Periyasamy Palanisamy <periyasamy.palanisamy@ericsson.com>
sdnvpn/artifacts/quagga_setup.sh
sdnvpn/lib/quagga.py
sdnvpn/lib/utils.py
sdnvpn/test/functest/config.yaml
sdnvpn/test/functest/testcase_3.py

index a8fe9f6..fbd229f 100644 (file)
@@ -1,22 +1,25 @@
 #! /bin/bash
 
 set -xe
-
 # change the password because this script is run on a passwordless cloud-image
 echo 'ubuntu:opnfv' | chpasswd
 
 # Wait for a floating IP
 # as a workaround to NAT breakage
-sleep 20
+sleep 100
 
 # Variables to be filled in with python
-NEIGHBOR_IP=%s
-OWN_IP=%s
+NEIGHBOR_IP=$1
+OWN_IP=$2
 # directly access the instance from the external net without NAT
-EXT_NET_MASK=%s
+EXT_NET_MASK=$3
+IP_PREFIX=$4
+RD=$5
+IRT=$6
+ERT=$7
 
 if [[ $(getent hosts | awk '{print $2}') != *"$(cat /etc/hostname | awk '{print $1}')"* ]]
-then 
+then
 echo "127.0.1.1 $(cat /etc/hostname | awk '{print $1}')" | tee -a /etc/hosts
 fi
 
@@ -37,60 +40,53 @@ fi
 ip link set $quagga_int up
 ip addr add $OWN_IP/$EXT_NET_MASK dev $quagga_int
 
-ZEBRA_CONFIG_LOCATION="/etc/quagga/zebra.conf"
-DAEMONS_FILE_LOCATION="/etc/quagga/daemons"
-BGPD_CONFIG_LOCATION="/etc/quagga/bgpd.conf"
-BGPD_LOG_FILE="/var/log/bgpd.log"
-
-# Quagga is already installed to run as well in setups without inet
-# dns fix
-# echo "nameserver 8.8.8.8" > /etc/resolvconf/resolv.conf.d/head
-# resolvconf -u
-# DEBIAN_FRONTEND=noninteractive apt-get update
-# DEBIAN_FRONTEND=noninteractive apt-get install quagga -y
-
-touch $BGPD_LOG_FILE
-chown quagga:quagga $BGPD_LOG_FILE
-
-chown quagga:quagga $DAEMONS_FILE_LOCATION
-cat <<CATEOF > $DAEMONS_FILE_LOCATION
-zebra=yes
-bgpd=yes
-ospfd=no
-ospf6d=no
-ripd=no
-ripngd=no
-isisd=no
-babeld=no
-CATEOF
-
-touch $ZEBRA_CONFIG_LOCATION
-chown quagga:quagga $ZEBRA_CONFIG_LOCATION
+# Download quagga/zrpc rpms
+cd /root
+wget http://artifacts.opnfv.org/sdnvpn/quagga4/quagga-ubuntu-updated.tar.gz
+tar -xvf quagga-ubuntu-updated.tar.gz
+cd /root/quagga
+dpkg -i c-capnproto_1.0.2.75f7901.Ubuntu16.04_amd64.deb
+dpkg -i zmq_4.1.3.56b71af.Ubuntu16.04_amd64.deb
+dpkg -i quagga_1.1.0.cd8ab40.Ubuntu16.04_amd64.deb
+dpkg -i thrift_1.0.0.b2a4d4a.Ubuntu16.04_amd64.deb
+dpkg -i zrpc_0.2.0efd19f.thriftv4.Ubuntu16.04_amd64.deb
 
-cat <<CATEOF > $BGPD_CONFIG_LOCATION
-! -*- bgp -*-
-
-hostname bgpd
-password sdncbgpc
+nohup /opt/quagga/sbin/bgpd &
 
+cat > /tmp/quagga-config << EOF1
+config terminal
 router bgp 200
- bgp router-id ${OWN_IP}
- neighbor ${NEIGHBOR_IP} remote-as 100
- no neighbor ${NEIGHBOR_IP} activate
+ bgp router-id $OWN_IP
+ no bgp log-neighbor-changes
+ bgp graceful-restart stalepath-time 90
+ bgp graceful-restart restart-time 900
+ bgp graceful-restart
+ bgp graceful-restart preserve-fw-state
+ bgp bestpath as-path multipath-relax
+ neighbor $NEIGHBOR_IP remote-as 100
+ no neighbor $NEIGHBOR_IP activate
+ vrf $RD
+  rd $RD
+  rt import $IRT
+  rt export $ERT
+ exit
+!
+address-family vpnv4
+neighbor $NEIGHBOR_IP activate
+neighbor $NEIGHBOR_IP attribute-unchanged next-hop
+exit
 !
- address-family vpnv4 unicast
- neighbor ${NEIGHBOR_IP} activate
- exit-address-family
+route-map map permit 1
+ set ip next-hop $OWN_IP
+exit
 !
-line vty
- exec-timeout 0 0
+router bgp 200
+address-family vpnv4
+network $IP_PREFIX rd $RD tag 100 route-map map
+exit
 !
-debug bgp events
-debug bgp  updates
-log file ${BGPD_LOG_FILE}
-end
-CATEOF
-chown quagga:quagga $BGPD_CONFIG_LOCATION
-service quagga restart
-pgrep bgpd
-pgrep zebra
+EOF1
+
+sleep 20
+
+(sleep 1;echo "sdncbgpc";sleep 1;cat /tmp/quagga-config;sleep 1; echo "exit") |nc -q1 localhost 2605
index e072f1c..0ea206e 100644 (file)
@@ -44,12 +44,14 @@ def bootstrap_quagga(fip_addr, controller_ip):
 
 def gen_quagga_setup_script(controller_ip,
                             fake_floating_ip,
-                            ext_net_mask):
+                            ext_net_mask,
+                            ip_prefix, rd, irt, ert):
     with open(COMMON_CONFIG.quagga_setup_script_path) as f:
         template = f.read()
     script = template % (controller_ip,
                          fake_floating_ip,
-                         ext_net_mask)
+                         ext_net_mask,
+                         ip_prefix, rd, irt, ert)
     return script
 
 
index 33ff594..e43750c 100644 (file)
@@ -7,6 +7,7 @@
 #
 # http://www.apache.org/licenses/LICENSE-2.0
 #
+import json
 import logging
 import os
 import time
@@ -14,6 +15,7 @@ import requests
 import re
 import subprocess
 from concurrent.futures import ThreadPoolExecutor
+from requests.auth import HTTPBasicAuth
 
 from opnfv.deployment.factory import Factory as DeploymentFactory
 
@@ -942,3 +944,41 @@ def get_odl_bgp_entity_owner(controllers):
                 if re.search(odl_bgp_owner, line):
                     return controller
         return None
+
+
+def add_quagga_external_gre_end_point(controllers, remote_tep_ip):
+    json_body = {'input':
+                 {'destination-ip': remote_tep_ip,
+                  'tunnel-type': "odl-interface:tunnel-type-mpls-over-gre"}
+                 }
+    url = ('http://{ip}:8081/restconf/operations/'
+           'itm-rpc:add-external-tunnel-endpoint'.format(ip=controllers[0].ip))
+    headers = {'Content-type': 'application/yang.data+json',
+               'Accept': 'application/yang.data+json'}
+    try:
+        requests.post(url, data=json.dumps(json_body),
+                      headers=headers,
+                      auth=HTTPBasicAuth('admin', 'admin'))
+    except Exception as e:
+        logger.error("Failed to create external tunnel endpoint on"
+                     " ODL for external tep ip %s with error %s"
+                     % (remote_tep_ip, e))
+    return None
+
+
+def is_fib_entry_present_on_odl(controllers, ip_prefix, vrf_id):
+    url = ('http://admin:admin@{ip}:8081/restconf/config/odl-fib:fibEntries/'
+           'vrfTables/{vrf}/'.format(ip=controllers[0].ip, vrf=vrf_id))
+    logger.error("url is %s" % url)
+    try:
+        vrf_table = requests.get(url).json()
+        is_ipprefix_exists = False
+        for vrf_entry in vrf_table['vrfTables'][0]['vrfEntry']:
+            if vrf_entry['destPrefix'] == ip_prefix:
+                is_ipprefix_exists = True
+                break
+        return is_ipprefix_exists
+    except Exception as e:
+        logger.error('Failed to find ip prefix %s with error %s'
+                     % (ip_prefix, e))
+    return False
index 360d88f..e910c77 100644 (file)
@@ -86,8 +86,13 @@ testcases:
     quagga_instance_ip: 10.10.11.5
     instance_1_name: sdnvpn-3-1
     instance_1_ip: 10.10.10.5
-    import_targets: '31:31'
-    export_targets: '32:32'
+    route_targets: '88:88'
+    import_targets: '88:88'
+    export_targets: '88:88'
+    route_distinguishers: '18:18'
+    external_network_name: External Network in Quagga VM
+    external_network_ip_prefix: 30.1.1.1/32
+    external_network_ip: 30.1.1.1
 
   sdnvpn.test.functest.testcase_4:
     enabled: true
index 7f70043..a527236 100644 (file)
@@ -186,7 +186,14 @@ def main():
         test_utils.open_http_port(neutron_client, sg_id)
 
         test_utils.open_bgp_port(neutron_client, sg_id)
-        net_id, subnet_1_id, router_1_id = test_utils.create_network(
+
+        image_id = os_utils.create_glance_image(
+            glance_client, TESTCASE_CONFIG.image_name,
+            COMMON_CONFIG.image_path, disk=COMMON_CONFIG.image_format,
+            container="bare", public='public')
+        image_ids.append(image_id)
+
+        net_1_id, subnet_1_id, router_1_id = test_utils.create_network(
             neutron_client,
             TESTCASE_CONFIG.net_1_name,
             TESTCASE_CONFIG.subnet_1_name,
@@ -203,7 +210,7 @@ def main():
 
         interfaces.append(tuple((router_1_id, subnet_1_id)))
         interfaces.append(tuple((router_quagga_id, subnet_quagga_id)))
-        network_ids.extend([net_id, quagga_net_id])
+        network_ids.extend([net_1_id, quagga_net_id])
         router_ids.extend([router_1_id, router_quagga_id])
         subnet_ids.extend([subnet_1_id, subnet_quagga_id])
 
@@ -250,7 +257,11 @@ def main():
         quagga_bootstrap_script = quagga.gen_quagga_setup_script(
             controller_ext_ip,
             fake_fip['fip_addr'],
-            ext_net_mask)
+            ext_net_mask,
+            TESTCASE_CONFIG.external_network_ip_prefix,
+            TESTCASE_CONFIG.route_distinguishers,
+            TESTCASE_CONFIG.import_targets,
+            TESTCASE_CONFIG.export_targets)
 
         quagga_vm = test_utils.create_instance(
             nova_client,
@@ -306,6 +317,83 @@ def main():
         else:
             results.add_failure("Peering with quagga")
 
+        test_utils.add_quagga_external_gre_end_point(controllers,
+                                                     fake_fip['fip_addr'])
+        test_utils.wait_before_subtest()
+
+        msg = ("Create VPN to define a VRF")
+        results.record_action(msg)
+        vpn_name = vpn_name = "sdnvpn-3"
+        kwargs = {
+            "import_targets": TESTCASE_CONFIG.import_targets,
+            "export_targets": TESTCASE_CONFIG.export_targets,
+            "route_targets": TESTCASE_CONFIG.route_targets,
+            "route_distinguishers": TESTCASE_CONFIG.route_distinguishers,
+            "name": vpn_name
+        }
+        bgpvpn = test_utils.create_bgpvpn(neutron_client, **kwargs)
+        bgpvpn_id = bgpvpn['bgpvpn']['id']
+        logger.debug("VPN1 created details: %s" % bgpvpn)
+        bgpvpn_ids.append(bgpvpn_id)
+
+        msg = ("Associate network '%s' to the VPN." %
+               TESTCASE_CONFIG.net_1_name)
+        results.record_action(msg)
+        results.add_to_summary(0, "-")
+
+        # create a vm and connect it with network1,
+        # which is going to be bgpvpn associated
+        userdata_common = test_utils.generate_ping_userdata(
+            [TESTCASE_CONFIG.external_network_ip])
+
+        compute_node = nova_client.hypervisors.list()[0]
+        av_zone_1 = "nova:" + compute_node.hypervisor_hostname
+        vm_bgpvpn = test_utils.create_instance(
+            nova_client,
+            TESTCASE_CONFIG.instance_1_name,
+            image_id,
+            net_1_id,
+            sg_id,
+            fixed_ip=TESTCASE_CONFIG.instance_1_ip,
+            secgroup_name=TESTCASE_CONFIG.secgroup_name,
+            compute_node=av_zone_1,
+            userdata=userdata_common)
+        instance_ids.append(vm_bgpvpn)
+
+        # wait for VM to get IP
+        instance_up = test_utils.wait_for_instances_up(vm_bgpvpn)
+        if not instance_up:
+            logger.error("One or more instances are down")
+
+        test_utils.create_network_association(
+            neutron_client, bgpvpn_id, net_1_id)
+
+        test_utils.wait_before_subtest()
+
+        msg = ("External IP prefix %s is exchanged with ODL"
+               % TESTCASE_CONFIG.external_network_ip_prefix)
+        fib_added = test_utils.is_fib_entry_present_on_odl(
+            controllers,
+            TESTCASE_CONFIG.external_network_ip_prefix,
+            TESTCASE_CONFIG.route_distinguishers)
+        if fib_added:
+            results.add_success(msg)
+        else:
+            results.add_failure(msg)
+
+        # TODO: uncomment the following once OVS is installed with > 2.8.3 and
+        # underlay connectivity is established between vxlan overlay and
+        # external network.
+        # results.get_ping_status_target_ip(
+        #    vm_bgpvpn,
+        #    TESTCASE_CONFIG.external_network_name,
+        #    TESTCASE_CONFIG.external_network_ip,
+        #    expected="PASS",
+        #    timeout=300)
+
+        results.add_to_summary(0, "=")
+        logger.info("\n%s" % results.summary)
+
     except Exception as e:
         logger.error("exception occurred while executing testcase_3: %s", e)
         raise
@@ -315,6 +403,14 @@ def main():
         test_utils.cleanup_neutron(neutron_client, floatingip_ids,
                                    bgpvpn_ids, interfaces, subnet_ids,
                                    router_ids, network_ids)
+        bgp_nbr_disconnect_cmd = ("bgp-nbr -i %s -a 200 del"
+                                  % fake_fip['fip_addr'])
+        bgp_server_stop_cmd = ("bgp-rtr -r %s -a 100 del"
+                               % controller_ext_ip)
+        odl_zrpc_disconnect_cmd = "bgp-connect -p 7644 -h 127.0.0.1 del"
+        test_utils.run_odl_cmd(controller, bgp_nbr_disconnect_cmd)
+        test_utils.run_odl_cmd(controller, bgp_server_stop_cmd)
+        test_utils.run_odl_cmd(controller, odl_zrpc_disconnect_cmd)
 
     return results.compile_summary()