Merge "Make tight the way an instance is considered as UP"
[sdnvpn.git] / sdnvpn / lib / quagga.py
1 """Utilities for setting up quagga peering"""
2
3 import logging
4 import re
5 import time
6
7 import functest.utils.functest_utils as ft_utils
8 import sdnvpn.lib.config as config
9 from sdnvpn.lib.utils import run_odl_cmd, exec_cmd
10
11 logger = logging.getLogger('sdnvpn-quagga')
12
13 COMMON_CONFIG = config.CommonConfig()
14
15
16 def odl_add_neighbor(neighbor_ip, controller_ip, controller):
17     # Explicitly pass controller_ip because controller.ip
18     # Might not be accessible from the Quagga instance
19     command = 'configure-bgp -op add-neighbor --as-num 200'
20     command += ' --ip %s --use-source-ip %s' % (neighbor_ip, controller_ip)
21     success = run_odl_cmd(controller, command)
22     # The run_cmd api is really whimsical
23     logger.info("Maybe stdout of %s: %s", command, success)
24     return success
25
26
27 def bootstrap_quagga(fip_addr, controller_ip):
28     script = gen_quagga_setup_script(
29         controller_ip,
30         fip_addr)
31     cmd = "sshpass -popnfv ssh opnfv@%s << EOF %s EOF" % (fip_addr, script)
32     rc = ft_utils.execute_command(cmd)
33     return rc == 0
34
35
36 def gen_quagga_setup_script(controller_ip,
37                             fake_floating_ip,
38                             ext_net_mask):
39     with open(COMMON_CONFIG.quagga_setup_script_path) as f:
40         template = f.read()
41     script = template % (controller_ip,
42                          fake_floating_ip,
43                          ext_net_mask)
44     return script
45
46
47 def check_for_peering(controller):
48     cmd = 'show-bgp --cmd \\"ip bgp neighbors\\"'
49     tries = 20
50     neighbors = None
51     bgp_state_regex = re.compile("(BGP state =.*)")
52     opens_regex = re.compile("Opens:(.*)")
53     while tries > 0:
54         if neighbors and 'Established' in neighbors:
55             break
56         neighbors = run_odl_cmd(controller, cmd)
57         logger.info("Output of %s: %s", cmd, neighbors)
58         if neighbors:
59             opens = opens_regex.search(neighbors)
60             if opens:
61                 logger.info("Opens sent/received: %s", opens.group(1))
62             state = bgp_state_regex.search(neighbors)
63             if state:
64                 logger.info("Peering state: %s", state.group(1))
65         tries -= 1
66         time.sleep(1)
67
68     if not neighbors or 'Established' not in neighbors:
69         logger.error("Quagga failed to peer with OpenDaylight")
70         logger.error("OpenDaylight status: %s", neighbors)
71         return False
72
73     logger.info("Quagga peered with OpenDaylight")
74     return True
75
76
77 def check_for_route_exchange(ip):
78     """Check that Quagga has learned the route to an IP"""
79     logger.debug("Checking that '%s' is in the Zebra routing table", ip)
80     routes, success = exec_cmd("vtysh -c 'show ip route'", verbose=True)
81     if not success:
82         return False
83     logger.debug("Zebra routing table: %s", routes)
84     return ip in routes