orchestrator.py 4.13 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
#!/usr/bin/env python3

# Copyright (C) 2018 Simon Redman <sredman@cs.utah.edu>
#
# 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.

# For future reference, here is the OSPFv6 RFC: https://tools.ietf.org/html/rfc2740.html

import add_routable_ipv6_addrs
import frr_configurator
22
import json
23
import ssh_helper
24
import sysctl_configurator
25 26 27 28 29
import topomap_parser

import argparse
import getpass
from netdiff import NetJsonParser
30
import re
31 32 33 34 35 36 37

if __name__ == "__main__":
    parser = argparse.ArgumentParser("Setup an Emulab experiment for Segment Routing")
    parser.add_argument("--topomap-file", action='store', default='/var/emulab/boot/topomap', type=str,
                        help="Path to the emulab topomap file to parse")
    parser.add_argument("--netgraph-file", action='store', type=str, required=False,
                        help="Path to the NetJSON file to parse. Skips parsing the netgrap from the topomap-file")
38 39
    parser.add_argument("--netgraph-write", action='store', type=str, required=False,
                        help="(Optional) Path to write the final NetJSON file")
40 41
    parser.add_argument("--username", action='store', type=str, default=getpass.getuser(),
                        help="Username to use on all hosts. Defaults to current user's username")
42
    parser.add_argument("--stop", action='store_true',
43
                        help="Stop all services (after writing config files)")
44 45 46 47
    parser.add_argument("--ovs-regex", action='store', type=str, default='.*ovs.*',
                        help="Regex to distinguish OVS nodes by label (Default \".*ovs.*\")")
    parser.add_argument("--host-regex", action='store', type=str, default='.*host.*',
                        help="Regex to distinguish host nodes by label (Default \".*host.*\")")
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65

    args = parser.parse_args()

    if not args.netgraph_file:
        netgraph = NetJsonParser(data=topomap_parser.parse_topomap_to_netjson(args.topomap_file))
    else:
        netgraph = NetJsonParser(file=args.netgraph_file)

    ssh_helper.network_graph_login(netgraph.graph, args.username)

    # Skip adding ipv6 addresses to the management interfaces
    management_ips = [node["management-ip"] for node in netgraph.graph._node.values()]

    ULA_map = add_routable_ipv6_addrs.construct_ULAs(netgraph.graph, ignore_addrs=management_ips)

    add_routable_ipv6_addrs.add_ULAs_to_hosts(netgraph.graph, ULA_map)
    add_routable_ipv6_addrs.add_interfaces_to_netgraph(netgraph.graph, ULA_map)

66
    # Prepare a list of nodes which run OVS and should thus be ignore for router-related activites
67 68 69
    ovs_nodes = []
    for node in netgraph.graph.nodes:
        node_name = netgraph.graph._node[node]['label']
70
        if re.match(args.ovs_regex, node_name):
71
            ovs_nodes.append(node)
72

73
    # Prepare a list of nodes which are "customer host nodes" and should thus be ignored for core network-related activities
74 75 76 77 78 79 80 81
    host_nodes = []
    for node in netgraph.graph.nodes:
        node_name = netgraph.graph._node[node]['label']
        if re.match(args.host_regex, node_name):
            host_nodes.append(node)

    frr_configurator.configure_nodes(netgraph.graph, ignore_nodes=ovs_nodes + host_nodes)
    frr_configurator.start_frr_on_network(netgraph.graph, ignore_nodes=ovs_nodes + host_nodes)
82

83 84 85
    # Customer hosts would normally be DHCP clients, etc., but for now just give them a route
    add_routable_ipv6_addrs.add_default_routes(netgraph.graph, ULA_map, host_nodes)

86
    sysctl_configurator.configure_nodes(netgraph.graph,ignore_nodes=ovs_nodes)
87

88
    ssh_helper.network_graph_logout(netgraph.graph)
89 90

    if args.netgraph_write:
91 92
        with open(args.netgraph_write, 'w') as outfile:
            json.dump(netgraph.json(dict=True), outfile)