Exemple #1
0
def install_flow(node_id, table_id):
    """ 
    This will install a flow.

    You should pass via POST few args.

    TODO: Better documentation.
    """
    credentials = (odl_user, odl_pass)
    odl = ODLInstance(odl_server, credentials)
    try:
        node = odl.get_node_by_id(node_id)
        table = node.get_table_by_id(table_id)
    except (NodeNotFound, TableNotFound) as e:
        flask.abort(404)

    form = flask.request.form
    table.install_flow(priority = form.get('priority'),
                       name = form.get('name'),
                       eth_type = form.get('eth_type'),
                       eth_source = form.get('eth_source'),
                       eth_destination = form.get('eth_destination'),
                       ipv4_source = form.get('ipv4_source'),
                       ipv4_destination = form.get('ipv4_destination'),
                       connector_id = form.get('output'),
                       template_dir = template_dir)
    return flask.redirect("/")
Exemple #2
0
def path_stats(node_id, table_id, clean_flow_id, diff):
    credentials = (odl_user, odl_pass)
    odl = ODLInstance(odl_server, credentials)
    try:
        node = odl.get_node_by_id(node_id)
        table = node.get_table_by_id(table_id)
        flow = table.get_flow_by_clean_id(clean_flow_id)
    except (NodeNotFound, TableNotFound, FlowNotFound) as e:
        return flask.abort(404)

    nodes = odl.get_nodes()
    data = [];
    eth_type = flow.get_ethernet_type()
    eth_src = flow.get_ethernet_source()
    eth_dest = flow.get_ethernet_destination()
    ipv4_src = flow.get_ipv4_source()
    ipv4_dest = flow.get_ipv4_destination()
    if eth_type == 0x0800 and (eth_src != '*' or
                               eth_dest != '*' or
                               ipv4_src != '*' or
                               ipv4_dest != '*'):
        path = explore_path(nodes, flow, eth_type, eth_src, eth_dest, ipv4_src, ipv4_dest)
        for n in path:
            ndata = {
                'id': n['id'],
                'main': get_rrd_stats(n['id'], n['main']['table_id'], n['main']['clean_flow_id'], diff)
            }
            if n.has_key('oposite'):
                ndata['oposite'] = get_rrd_stats(n['id'], n['oposite']['table_id'], n['oposite']['clean_flow_id'], diff)
            data.append(ndata)
    else:
        data.append({'id': node.id, 'main': get_rrd_stats(node.id, table.id, flow.clean_id, diff)})
    return flask.jsonify(data)
Exemple #3
0
def delete_flow(node_id, table_id, flow_id):
    credentials = (odl_user, odl_pass)
    odl = ODLInstance(odl_server, credentials)

    data = json.loads(flask.request.get_data().decode('utf-8'))
    delete_all = data['delete_all']

    try:
        # Get the node object
        node = odl.get_node_by_id(node_id)
        # Get the table object
        table = node.get_table_by_id(table_id)
        # Get the flow
        flow = table.get_all_flows()[flow_id]
    except (NodeNotFound, TableNotFound, FlowNotFound) as e:
        flask.abort(404)

    if delete_all:
        nodes = odl.get_nodes()
        for node in nodes.values():
            node.delete_config_flows_by_name(flow.name)
    else:
        flow.delete()

    return flask.redirect("/")
Exemple #4
0
def flow_stats(node_id, table_id, clean_flow_id):
    """ 
    This endpoint returns statistics to plot.
    You should pass a node id, table id and a clean flow id. (removing #, $, -
    and * symbols from id).
    """
    # Main flow
    main = get_rrd_stats(node_id, table_id, clean_flow_id)

    credentials = (odl_user, odl_pass)
    odl = ODLInstance(odl_server, credentials)
    try:
        node = odl.get_node_by_id(node_id)
        table = node.get_table_by_id(table_id)
        flow = table.get_flow_by_clean_id(clean_flow_id)
    except (NodeNotFound, TableNotFound, FlowNotFound) as e:
        return flask.abort(404)

    # Try to get the oposite flow (just in case of where booth are added with
    # same name.
    flows = table.get_config_flows_by_name(flow.name)
    for oposite in flows:
        if oposite.clean_id != clean_flow_id:
            break
    if flows:
        oposite = get_rrd_stats(node_id, table_id, oposite.clean_id)
    else:
        oposite = []

    return flask.jsonify({'main': main,
                          'oposite': oposite})
Exemple #5
0
def delete_flow(node_id, table_id, flow_id):
    credentials = (odl_user, odl_pass)
    odl = ODLInstance(odl_server, credentials)

    data = json.loads(flask.request.get_data().decode('utf-8'))
    delete_all = data['delete_all']

    try:
        # Get the node object
        node = odl.get_node_by_id(node_id)
        # Get the table object
        table = node.get_table_by_id(table_id)
        # Get the flow
        flow = table.get_all_flows()[flow_id]
    except (NodeNotFound, TableNotFound, FlowNotFound) as e:
        flask.abort(404)

    if delete_all:
        nodes = odl.get_nodes()
        for node in nodes.values():
            node.delete_config_flows_by_name(flow.name)
    else:
        flow.delete()

    return flask.redirect("/")
Exemple #6
0
def all_stats():
    """
    Get all statistics information for each node
    """
    credentials = (odl_user, odl_pass)
    odl = ODLInstance(odl_server, credentials)
    nodes = odl.get_nodes()
    all_stats = {}
    for node in nodes.values():
        ports = node.get_connectors()
        for port in ports.values():
            connector = port.id
            stat = get_port_rrd_stats(node.id, port.id, 120)
            rates = map(lambda x: x['bytes'], stat)
            rate = sum(rates) / len(rates) if rates else 0
            all_stats[connector] = rate
        # tables = node.get_tables()
        # for table in tables.values():
        #     for flow in table.get_all_flows().values():
        #         for action in flow.get_actions():
        #             if action['type'] == 'output-action':
        #                 connector = node.id + ":" + action['value']
        #                 stat = get_rrd_stats(node.id, table.id, flow.clean_id, 120)
        #                 rates = map(lambda x: x['bytes'], stat)
        #                 rate = sum(rates) / len(rates) if rates else 0
        #                 all_stats[connector] = all_stats.get(connector, 0) + rate
    return flask.jsonify(all_stats)
Exemple #7
0
def install_flows_for_l3path(path_id):
    """ 
    This will install a l3 full path flows (based on IP Address addresses) in all
    switches in a path.

    You should use first '/api/routes/l3' to see the uid of path. This is a
    necessary argument for this endpoint.
    """
    client_ip = "%s" % flask.request.environ['REMOTE_ADDR']
    try:
        path = session_l3paths[client_ip][path_id]
    except KeyError:
        flask.abort(404)

    ports = get_ports_on_path(path)

    source_host = path[0]
    target_host = path[-1]

    # Install a flow in each switch on the path with correct output
    # port.
    for source_port, target_port in ports:
        source_switch = "%s:%s" % (source_port.split(":")[0], source_port.split(":")[1])
        target_switch = "%s:%s" % (target_port.split(":")[0], target_port.split(":")[1])
        # Just in case check
        if (source_switch != target_switch):
            print "Error 500: Switches are different on path"
            flask.abort(500)

        # Match: source_port, source_host, target_host, eth_type = 0x806 ?
        # Target Action: target_port
        # Lookup for switch in database
        try:
            credentials = (odl_user, odl_pass)
            odl = ODLInstance(odl_server, credentials)
            node = odl.get_node_by_id(target_switch)
            table = node.get_table_by_id(0) # Assuming installing on table 0
        except (NodeNotFound, TableNotFound) as e:
            print "Error: 404 - Switch or table not found in database"
            flask.abort(404)

        print "Inserting flow for %s..." % node.id

        # Install the flow one way
        table.l3output(flow_name = "L3AR%s" % path_id.split("-")[0],
                       connector_id = target_port,
                       source = "%s/32" % source_host,
                       destination = "%s/32" % target_host,
                       template_dir = template_dir)

        # Install the flow another way
        table.l3output(flow_name = "L3AR%s" % path_id.split("-")[0],
                       connector_id = source_port,
                       source = "%s/32" % target_host,
                       destination = "%s/32" % source_host,
                       template_dir = template_dir)

    # Update Json file
    return flask.redirect("/")
Exemple #8
0
def get_topology():
    """
    This endpoint returns a big topology with nodes and links.
    """
    credentials = (odl_user, odl_pass)
    odl = ODLInstance(odl_server, credentials)
    data = odl.to_dict()
    return flask.jsonify(data)
Exemple #9
0
def delete_low_priority_flows(node_id, table_id):
    credentials = (odl_user, odl_pass)
    odl = ODLInstance(odl_server, credentials)

    try:
        node = odl.get_node_by_id(node_id)
        table = node.get_table_by_id(table_id)
        table.delete_low_priority_flows()
        return flask.redirect("/")
    except (NodeNotFloud, TableNotFound) as e:
        flask.abort(404)
Exemple #10
0
 def __init__(self, url, user, pw):
     self.prompt = col.PROMPT + "odl-cli> " + col.ENDC
     self.config = {}
     self.cwc = self.config
     self.cwd_list = []
     self.odl = ODLInstance(url, (user, pw))
     self.util = Util()
     self.node = None
     self.table = None
     self.pp = pprint.PrettyPrinter(indent=1,
                                    width=80,
                                    depth=None,
                                    stream=None)
     cmd.Cmd.__init__(self)
Exemple #11
0
def flow_stats_all(name, diff):
    credentials = (odl_user, odl_pass)
    odl = ODLInstance(odl_server, credentials)
    nodes = odl.get_nodes()
    stats = {}
    for node in nodes.values():
        tables = node.get_tables()
        node_stats = {}
        for table in tables.values():
            flows = table.get_config_flows_by_name(name)
            for flow in flows:
                node_stats[flow.clean_id] = get_rrd_stats(node.id, table.id, flow.clean_id, diff)
        if node_stats:
            stats[node.id] = node_stats
    return flask.jsonify(stats)
Exemple #12
0
def l2routes():
    """ 
    This returns a list of all paths available between two MAC address. Also an
    random ID is generated for this session for each path. So you can use this ID
    when creating a complete PATH l2 flow.

    You should pass as data to the POST request the source and destination MAC
    addresses.

    Ex:

        {'source': '00:00:00:00:00:01', 'destination': '00:00:00:00:00:02'}

    """
    data = json.loads(flask.request.get_data().decode('utf-8'))
    source = data['source']
    destination = data['destination']

    credentials = (odl_user, odl_pass)
    odl = ODLInstance(odl_server, credentials)
    graph = odl.topology.get_networkx_graph()

    client_ip = "%s" % flask.request.environ['REMOTE_ADDR']
    session_l2paths[client_ip] = {}

    paths = []
    for path in nx.all_simple_paths(graph, source, destination):
        uid = "%s" % uuid.uuid1()
        paths.append({'uid': uid, 'path': path})
        session_l2paths[client_ip][uid] = path

    return flask.jsonify({'paths': paths})
Exemple #13
0
def flow_stats_all(name, diff):
    credentials = (odl_user, odl_pass)
    odl = ODLInstance(odl_server, credentials)
    nodes = odl.get_nodes()
    stats = {}
    for node in nodes.values():
        tables = node.get_tables()
        node_stats = {}
        for table in tables.values():
            flows = table.get_config_flows_by_name(name)
            for flow in flows:
                node_stats[flow.clean_id] = get_rrd_stats(
                    node.id, table.id, flow.clean_id, diff)
        if node_stats:
            stats[node.id] = node_stats
    return flask.jsonify(stats)
Exemple #14
0
def spce_set_tc():
    data = json.loads(flask.request.get_data().decode('utf-8'))
    source = data['source']
    destination = data['destination']
    bandwidth = data['bandwidth']
    bs = data['bs']
    operation = data['operation']

    credentials = (odl_user, odl_pass)
    odl = ODLInstance(odl_server, credentials)
    spce = ALTOSpce(odl)

    try:
        if operation == 'create':
            return flask.jsonify(
                spce.set_tc(src=source, dst=destination, bd=bandwidth, bs=bs))
        else:
            return flask.jsonify(
                spce.update_tc(src=source,
                               dst=destination,
                               bd=bandwidth,
                               bs=bs))
    except ODLErrorOnPOST as e:
        print "Error: 500 - Rate limiting setup failed"
        flask.abort(500)
Exemple #15
0
def e2e_stats(path_id, diff):
    if cache_l2paths.has_key(path_id):
        path = cache_l2paths[path_id]
        flow_name = "L2AR%s" % path_id.split("-")[0]
        source_host = ":".join(path[0].split(":")[1::])
        target_host = ":".join(path[-1].split(":")[1::])
        match = {'eth_type': 0x0800, 'eth_src': source_host, 'eth_dest': target_host, 'ipv4_src': '*', 'ipv4_dest': '*'}
    elif cache_l3paths.has_key(path_id):
        path = cache_l3paths[path_id]
        flow_name = "L3AR%s" % path_id.split("-")[0]
        source_host = path[0] + '/32'
        target_host = path[-1] + '/32'
        match = {'eth_type': 0x0800, 'eth_src': '*', 'eth_dest': '*', 'ipv4_src': source_host, 'ipv4_dest': target_host}
    else:
        flask.abort(404)
    ports = get_ports_on_path(path)
    source_switch = "%s:%s" % (ports[0][1].split(":")[0], ports[0][1].split(":")[1])
    target_switch = "%s:%s" % (ports[-1][0].split(":")[0], ports[-1][0].split(":")[1])
    try:
        credentials = (odl_user, odl_pass)
        odl = ODLInstance(odl_server, credentials)
        main_node = odl.get_node_by_id(source_switch)
        oposite_node = odl.get_node_by_id(target_switch)
        # Assuming installing on table 0
        main_table = main_node.get_table_by_id(0)
        oposite_table = oposite_node.get_table_by_id(0)
    except (NodeNotFound, TableNotFound) as e:
        print "Error: 404 - Switch or table not found in database"
        flask.abort(404)

    main = {}
    for flow in main_table.get_config_flows_by_name(flow_name):
        if check_match_flow(flow, **match):
            main = get_rrd_stats(main_node.id, main_table.id, flow.clean_id, diff)
            break
    oposite = {}
    for flow in oposite_table.get_config_flows_by_name(flow_name):
        if check_reverse_match_flow(flow, **match):
            oposite = get_rrd_stats(oposite_node.id, oposite_table.id, flow.clean_id, diff)
            break
    return flask.jsonify({'main': main,
                          'oposite': oposite,
                          'source': source_host,
                          'target': target_host})
Exemple #16
0
def path_stats(node_id, table_id, clean_flow_id, diff):
    credentials = (odl_user, odl_pass)
    odl = ODLInstance(odl_server, credentials)
    try:
        node = odl.get_node_by_id(node_id)
        table = node.get_table_by_id(table_id)
        flow = table.get_flow_by_clean_id(clean_flow_id)
    except (NodeNotFound, TableNotFound, FlowNotFound) as e:
        return flask.abort(404)

    nodes = odl.get_nodes()
    data = []
    eth_type = flow.get_ethernet_type()
    eth_src = flow.get_ethernet_source()
    eth_dest = flow.get_ethernet_destination()
    ipv4_src = flow.get_ipv4_source()
    ipv4_dest = flow.get_ipv4_destination()
    if eth_type == 0x0800 and (eth_src != '*' or eth_dest != '*'
                               or ipv4_src != '*' or ipv4_dest != '*'):
        path = explore_path(nodes, flow, eth_type, eth_src, eth_dest, ipv4_src,
                            ipv4_dest)
        for n in path:
            ndata = {
                'id':
                n['id'],
                'main':
                get_rrd_stats(n['id'], n['main']['table_id'],
                              n['main']['clean_flow_id'], diff)
            }
            if n.has_key('oposite'):
                ndata['oposite'] = get_rrd_stats(n['id'],
                                                 n['oposite']['table_id'],
                                                 n['oposite']['clean_flow_id'],
                                                 diff)
            data.append(ndata)
    else:
        data.append({
            'id':
            node.id,
            'main':
            get_rrd_stats(node.id, table.id, flow.clean_id, diff)
        })
    return flask.jsonify(data)
Exemple #17
0
 def __init__(self, url, user, pw):
     self.prompt = col.PROMPT + "odl-cli> " + col.ENDC
     self.config = {}
     self.cwc = self.config
     self.cwd_list = []
     self.odl = ODLInstance(url, (user, pw))
     self.util = Util()
     self.node = None
     self.table = None
     self.pp = pprint.PrettyPrinter(indent=1, width=80, depth=None, stream=None)
     cmd.Cmd.__init__(self)
Exemple #18
0
def l3routes():
    """
    This returns a list of all paths available between two IPv4 address. Also an
    random ID is generated for this session for each path. So you can use this ID
    when creating a complete PATH l3 flow.

    You should pass as data to the POST request the source and destination IPv4
    addresses.

    Ex:

        {'source': '192.168.1.1', 'destination': '192.168.1.2'}

    """
    data = json.loads(flask.request.get_data().decode('utf-8'))
    source = data['source']
    destination = data['destination']

    credentials = (odl_user, odl_pass)
    odl = ODLInstance(odl_server, credentials)
    graph = odl.topology.get_networkx_graph()

    source_id, dest_id = None, None

    # Theses are topology nodes
    # TODO: Topology nodes should be of same type of a normal node.
    #       EX: switch vs Host vs Port
    nodes = odl.topology.get_nodes()
    for node in nodes.values():
        node_id = node['node-id']
        if (node_id.split(":")[0] == "host"):
            ips = node['host-tracker-service:addresses']
            for ip in ips:
                if ip['ip'] == source:
                    source_id = "host:%s" % ip['mac']

                if ip['ip'] == destination:
                    dest_id = "host:%s" % ip['mac']

    if not source_id or not dest_id:
        return flask.jsonify({'paths': []})

    client_ip = "%s" % flask.request.environ['REMOTE_ADDR']
    session_l3paths[client_ip] = {}

    paths = []
    for path in nx.all_simple_paths(graph, source_id, dest_id):
        uid = "%s" % uuid.uuid1()
        path[0] = source
        path[-1] = destination
        paths.append({'uid': uid, 'path': path})
        session_l3paths[client_ip][uid] = path

    return flask.jsonify({'paths': paths})
Exemple #19
0
def all_stats():
    """
    Get all statistics information for each node
    """
    credentials = (odl_user, odl_pass)
    odl = ODLInstance(odl_server, credentials)
    nodes = odl.get_nodes()
    all_stats = {}
    for node in nodes.values():
        tables = node.get_tables()
        for table in tables.values():
            for flow in table.get_all_flows().values():
                for action in flow.get_actions():
                    if action['type'] == 'output-action':
                        connector = node.id + ":" + action['value']
                        stat = get_rrd_stats(node.id, table.id, flow.clean_id,
                                             120)
                        rates = map(lambda x: x['bytes'], stat)
                        rate = sum(rates) / len(rates) if rates else 0
                        all_stats[connector] = all_stats.get(connector,
                                                             0) + rate
    return flask.jsonify(all_stats)
Exemple #20
0
def spce_remove_tc():
    data = json.loads(flask.request.get_data().decode('utf-8'))
    path = data['path']

    credentials = (odl_user, odl_pass)
    odl = ODLInstance(odl_server, credentials)
    spce = ALTOSpce(odl)

    try:
        return flask.jsonify(spce.remove_tc(path))
    except ODLErrorOnPOST as e:
        print "Error: 500 - Rate limiting setup failed"
        flask.abort(500)
Exemple #21
0
def l2routes():
    """
    This returns a list of all paths available between two MAC address. Also an
    random ID is generated for this session for each path. So you can use this ID
    when creating a complete PATH l2 flow.

    You should pass as data to the POST request the source and destination MAC
    addresses.

    Ex:

        {'source': '00:00:00:00:00:01', 'destination': '00:00:00:00:00:02'}

    """
    data = json.loads(flask.request.get_data().decode('utf-8'))
    source = data['source']
    destination = data['destination']
    source_mac = data['source-mac']
    destination_mac = data['destination-mac']

    src_vlan = data['source-vlan'] if 'source-vlan' in data.keys() else ''
    dst_vlan = data['destination-vlan'] if 'destination-vlan' in data.keys(
    ) else ''

    if src_vlan != '' and dst_vlan != '':
        flask.abort(500, "Only one attachment point can have a vlan tag!")

    credentials = (odl_user, odl_pass)
    odl = ODLInstance(odl_server, credentials)
    graph = odl.topology.get_networkx_graph()

    client_ip = "%s" % flask.request.environ['REMOTE_ADDR']
    session_l2paths[client_ip] = {}

    paths = []
    for path in nx.all_simple_paths(graph, source, destination):
        uid = "%s" % uuid.uuid1()
        if source_mac:
            path = ['host:' + source_mac] + path
        if destination_mac:
            path.append('host:' + destination_mac)
        paths.append({'uid': uid, 'path': path})
        session_l2paths[client_ip][uid] = {
            'path': path,
            'src-vlan': src_vlan,
            'dst-vlan': dst_vlan
        }

    return flask.jsonify({'paths': paths})
Exemple #22
0
def delete_flow(node_id, table_id, flow_id):
    credentials = (odl_user, odl_pass)
    odl = ODLInstance(odl_server, credentials)

    delete_all = flask.request.form.get('delete_all')

    try:
        # Get the node object
        node = odl.get_node_by_id(node_id)
        # Get the table object
        table = node.get_table_by_id(table_id)
        # Get the flow
        flow = table.get_flow_by_id(flow_id)
    except (NodeNotFound, TableNotFound, FlowNotFound) as e:
        flask.abort(404)

    if delete_all:
        nodes = odl.get_nodes()
        for node in nodes.values():
            node.delete_config_flows_by_name(flow.name)
    else:
        flow.delete()

    return flask.redirect("/")
Exemple #23
0
def spce_get_paths():
    credentials = (odl_user, odl_pass)
    odl = ODLInstance(odl_server, credentials)
    spce = ALTOSpce(odl)

    try:
        paths = spce.get_all_paths()
        alto_paths = []
        for path in paths:
            p = {'path': path['path'].split('|')}
            if 'tc' in path.keys() and path['tc'] >= 0:
                p['tc'] = path['tc']
            alto_paths.append(p)
        return flask.jsonify(paths=alto_paths)
    except ODLErrorOnPOST as e:
        print "Error: 500 - Get path failed"
        flask.abort(500)
Exemple #24
0
def spce_setup_path():
    data = json.loads(flask.request.get_data().decode('utf-8'))
    source = data['source']
    destination = data['destination']
    obj_metrics = data['obj_metrics']
    constraints = data['constraints']

    credentials = (odl_user, odl_pass)
    odl = ODLInstance(odl_server, credentials)
    spce = ALTOSpce(odl)

    try:
        return flask.jsonify(
            spce.path_setup(src=source,
                            dst=destination,
                            objective_metrics=obj_metrics,
                            constraint_metric=constraints))
    except ODLErrorOnPOST as e:
        print "Error: 500 - Setup path failed"
        flask.abort(500)
Exemple #25
0
class ODLCmd(cmd.Cmd):
    def __init__(self, url, user, pw):
        self.prompt = col.PROMPT + "odl-cli> " + col.ENDC
        self.config = {}
        self.cwc = self.config
        self.cwd_list = []
        self.odl = ODLInstance(url, (user, pw))
        self.util = Util()
        self.node = None
        self.table = None
        self.pp = pprint.PrettyPrinter(indent=1,
                                       width=80,
                                       depth=None,
                                       stream=None)
        cmd.Cmd.__init__(self)

    def emptyline(self):
        pass

    def do_cd(self, path):
        '''Change the current level of view of the config to be at <key>
        cd <key>'''
        if path == "" or path[0] == "/":
            new_wd_list = path[1:].split("/")
        else:
            new_wd_list = self.cwd_list + path.split("/")
        try:
            cwc, new_wd_list = self._conf_for_list(new_wd_list)
        except ConfigurationError as e:
            print col.FAIL + str(e) + col.ENDC
            return
        self.cwd_list = new_wd_list
        self.cwc = cwc

    def complete_cd(self, text, l, b, e):
        return [
            x[b - 3:] for x, y in self.cwc.iteritems() if x.startswith(l[3:])
        ]

    def do_ls(self, key):
        '''Show the top level of the current working config, or top level of config under [key]
        ls [key]'''
        conf = self.cwc
        if key:
            try:
                conf = conf[key]
            except KeyError:
                print "No such key %s" % key
                return

        try:
            for k, v in conf.iteritems():
                if isinstance(v, ODLNode):
                    try:
                        hostname = socket.gethostbyaddr(v.ip_address)[0]
                    except:
                        hostname = v.ip_address
                    print col.DIR + k + col.ENDC + ": (\"%s\", \"%s\", \"%s\")" % \
                    (hostname, v.description, v.manufacturer)
                elif isinstance(v, dict) or isinstance(v, list):
                    print col.DIR + k + col.ENDC
                else:
                    print "%s: %s" % (k, v)
        except:
            print "%s" % conf

    def complete_ls(self, text, l, b, e):
        return [
            x[b - 3:] for x, y in self.cwc.iteritems() if x.startswith(l[3:])
        ]

    def do_lsd(self, key):
        '''Show all config from current level down... or all config under [key]
        lsd [key]'''
        conf = self.cwc
        if key:
            try:
                conf = conf[key]
            except KeyError:
                print "No such key %s" % key
        self.pp.pprint(conf)

    def complete_lsd(self, text, l, b, e):
        return [
            x for x, y in self.cwc.iteritems()
            if isinstance(y, dict) and x.startswith(text)
        ]

    def do_pwd(self, key):
        '''Show current path in config separated by slashes
        pwd'''
        print "/" + "/".join(self.cwd_list)

    def do_get_nodes(self, args):
        '''Get all or a specific node from ODL
        get_nodes [node]'''
        try:
            nodes = self.odl.get_nodes()
            self.config = nodes
            self._set_cwc()
        except Exception as e:
            print "Error: %s" % e

    def do_get_topo(self, args):
        '''Get ODL topology'''
        try:
            t = ODLTopology(None, None, self.odl)
            topo = t.get_topology()
            self.config = topo
            self._set_cwc()
        except Exception as e:
            print "Error: %s" % e

    def do_del_flow(self, fid):
        try:
            if not self.cwd_list[-3] == "tables":
                raise
        except:
            print col.FAIL + "Not in a valid table leaf!" + col.ENDC
            return

        if not fid:
            print col.FAIL + "Must specify flow id or '*'" + col.ENDC
            return

        table = self.cwd_list[-2]
        if fid == "*":
            yn = self.util.query_yes_no("Delete ALL flows in table %s" %
                                        (table))
            if yn:
                flows = self.tables[int(table)].get_config_flows()
                for f in flows.values():
                    try:
                        f.delete()
                    except Exception as e:
                        print "Error deleting flow: %s" % e
            else:
                return
        else:
            yn = self.util.query_yes_no("Delete flow %s in table %s" %
                                        (fid, table))
            if yn:
                try:
                    flows = self.tables[int(table)].get_config_flows()
                    flows[fid].delete()
                except Exception as e:
                    print "Error deleting flow: %s" % e
            else:
                return

        self.do_update(None)
        self.do_get_nodes(None)

    def complete_del_flow(self, text, l, b, e):
        return [
            x[b - 9:] for x, y in self.cwc.iteritems() if x.startswith(l[9:])
        ]

    def do_add_flow(self, args):
        '''Add a flow, will prompt for user input'''
        if not self.node:
            print col.FAIL + "No ODL node selected!" + col.ENDC
            return

        file_path = self.util.get_string("Input file: ", None)
        if not file_path:
            print "You must include a json file containing the ODL flow(s)"
            return

        try:
            with open(file_path, 'r') as in_file:
                raw_json = in_file.read()

            flow_requests = json.loads(raw_json)
        except IOError, e:
            print "Could not open file %s" % file_path
            return
        except ValueError, e:
            print "Invalid json formatting in request"
            return
Exemple #26
0
def e2e_stats(path_id, diff):
    if cache_l2paths.has_key(path_id):
        path = cache_l2paths[path_id]
        flow_name = "L2AR%s" % path_id.split("-")[0]
        source_host = ":".join(path[0].split(":")[1::])
        target_host = ":".join(path[-1].split(":")[1::])
        match = {
            'eth_type': 0x0800,
            'eth_src': source_host,
            'eth_dest': target_host,
            'ipv4_src': '*',
            'ipv4_dest': '*'
        }
    elif cache_l3paths.has_key(path_id):
        path = cache_l3paths[path_id]
        flow_name = "L3AR%s" % path_id.split("-")[0]
        source_host = path[0] + '/32'
        target_host = path[-1] + '/32'
        match = {
            'eth_type': 0x0800,
            'eth_src': '*',
            'eth_dest': '*',
            'ipv4_src': source_host,
            'ipv4_dest': target_host
        }
    else:
        flask.abort(404)
    ports = get_ports_on_path(path)
    source_switch = "%s:%s" % (ports[0][1].split(":")[0],
                               ports[0][1].split(":")[1])
    target_switch = "%s:%s" % (ports[-1][0].split(":")[0],
                               ports[-1][0].split(":")[1])
    try:
        credentials = (odl_user, odl_pass)
        odl = ODLInstance(odl_server, credentials)
        main_node = odl.get_node_by_id(source_switch)
        oposite_node = odl.get_node_by_id(target_switch)
        # Assuming installing on table 0
        main_table = main_node.get_table_by_id(0)
        oposite_table = oposite_node.get_table_by_id(0)
    except (NodeNotFound, TableNotFound) as e:
        print "Error: 404 - Switch or table not found in database"
        flask.abort(404)

    main = {}
    for flow in main_table.get_config_flows_by_name(flow_name):
        if check_match_flow(flow, **match):
            main = get_rrd_stats(main_node.id, main_table.id, flow.clean_id,
                                 diff)
            break
    oposite = {}
    for flow in oposite_table.get_config_flows_by_name(flow_name):
        if check_reverse_match_flow(flow, **match):
            oposite = get_rrd_stats(oposite_node.id, oposite_table.id,
                                    flow.clean_id, diff)
            break
    return flask.jsonify({
        'main': main,
        'oposite': oposite,
        'source': source_host,
        'target': target_host
    })
Exemple #27
0
class ODLCmd(cmd.Cmd):
    def __init__(self, url, user, pw):
        self.prompt = col.PROMPT + "odl-cli> " + col.ENDC
        self.config = {}
        self.cwc = self.config
        self.cwd_list = []
        self.odl = ODLInstance(url, (user, pw))
        self.util = Util()
        self.node = None
        self.table = None
        self.pp = pprint.PrettyPrinter(indent=1, width=80, depth=None, stream=None)
        cmd.Cmd.__init__(self)

    def emptyline(self):
        pass
        
    def do_cd(self, path):
        '''Change the current level of view of the config to be at <key>
        cd <key>'''
        if path=="" or path[0]=="/":
            new_wd_list = path[1:].split("/")
        else:
            new_wd_list = self.cwd_list + path.split("/")
        try:
            cwc, new_wd_list = self._conf_for_list(new_wd_list)
        except ConfigurationError as e:
            print col.FAIL + str(e) + col.ENDC
            return
        self.cwd_list = new_wd_list
        self.cwc = cwc

    def complete_cd(self, text, l, b, e):
        return [ x[b-3:] for x,y in self.cwc.iteritems() if x.startswith(l[3:])]

    def do_ls(self, key):
        '''Show the top level of the current working config, or top level of config under [key]
        ls [key]'''
        conf = self.cwc
        if key:
            try:
                conf = conf[key]
            except KeyError:
                print "No such key %s" % key
                return

        try:
            for k,v in conf.iteritems():
                if isinstance(v, ODLNode):
                    try:
                        hostname = socket.gethostbyaddr(v.ip_address)[0]
                    except:
                        hostname = v.ip_address
                    print col.DIR + k + col.ENDC + ": (\"%s\", \"%s\", \"%s\")" % \
                    (hostname, v.description, v.manufacturer)
                elif isinstance(v, dict) or isinstance(v, list):
                    print col.DIR + k + col.ENDC
                else:
                    print "%s: %s" % (k, v)
        except:
            print "%s" % conf

    def complete_ls(self, text, l, b, e):
        return [ x[b-3:] for x,y in self.cwc.iteritems() if x.startswith(l[3:]) ]

    def do_lsd(self, key):
        '''Show all config from current level down... or all config under [key]
        lsd [key]'''
        conf = self.cwc
        if key:
            try:
                conf = conf[key]
            except KeyError:
                print "No such key %s" % key
        self.pp.pprint(conf)

    def complete_lsd(self, text, l, b, e):
        return [ x for x,y in self.cwc.iteritems()
                 if isinstance(y, dict) and x.startswith(text) ]

    def do_pwd(self, key):
        '''Show current path in config separated by slashes
        pwd'''
        print "/" + "/".join(self.cwd_list)

    def do_get_nodes(self, args):
        '''Get all or a specific node from ODL
        get_nodes [node]'''
        try:
            nodes = self.odl.get_nodes()
            self.config = nodes
            self._set_cwc()
        except Exception as e:
            print "Error: %s" % e

    def do_get_topo(self, args):
        '''Get ODL topology'''
        try:
            t = ODLTopology(None, None, self.odl)
            topo = t.get_topology()
            self.config = topo
            self._set_cwc()
        except Exception as e:
            print "Error: %s" % e

    def do_del_flow(self, fid):
        try:
            if not self.cwd_list[-3] == "tables":
                raise
        except:
            print col.FAIL + "Not in a valid table leaf!" + col.ENDC
            return

        if not fid:
            print col.FAIL + "Must specify flow id or '*'" + col.ENDC
            return

        table = self.cwd_list[-2]
        if fid == "*":
            yn = self.util.query_yes_no("Delete ALL flows in table %s" % (table))
            if yn:
                flows = self.tables[int(table)].get_config_flows()
                for f in flows.values():
                    try:
                        f.delete()
                    except Exception as e:
                        print "Error deleting flow: %s" % e
            else:
                return
        else:
            yn = self.util.query_yes_no("Delete flow %s in table %s" % (fid, table))
            if yn:
                try:
                    flows = self.tables[int(table)].get_config_flows()
                    flows[fid].delete()
                except Exception as e:
                    print "Error deleting flow: %s" % e
            else:
                return

        self.do_update(None)
        self.do_get_nodes(None)

    def complete_del_flow(self, text, l, b, e):
        return [ x[b-9:] for x,y in self.cwc.iteritems() if x.startswith(l[9:]) ]
            
    def do_add_flow(self, args):
        '''Add a flow, will prompt for user input'''
        if not self.node:
            print col.FAIL + "No ODL node selected!" + col.ENDC
            return

        file_path = self.util.get_string("Input file: ", None)
        if not file_path:
            print "You must include a json file containing the ODL flow(s)"
            return
        
        try:
            with open(file_path, 'r') as in_file:
                raw_json = in_file.read()
                
            flow_requests = json.loads(raw_json)
        except IOError, e:
            print "Could not open file %s" % file_path
            return
        except ValueError, e:
            print "Invalid json formatting in request"
            return
Exemple #28
0
def install_flows_for_l2path(path_id):
    """
    This will install a l2 full path flows (based on MAC addresses) in all
    switches in a path.

    You should use first '/api/routes/l2' to see the uid of path. This is a
    necessary argument for this endpoint.
    """
    client_ip = "%s" % flask.request.environ['REMOTE_ADDR']
    try:
        path = session_l2paths[client_ip][path_id]
        path, src_vlan, dst_vlan = path['path'], path['src-vlan'], path[
            'dst-vlan']
        src_vlan = src_vlan if src_vlan != '' else None
        dst_vlan = dst_vlan if dst_vlan != '' else None
    except KeyError:
        flask.abort(404)

    ports = get_ports_on_path(path)

    # [(u'openflow:562958149829575:2', u'openflow:562958149829575:21'),
    #  (u'openflow:440565346114459:257', u'openflow:440565346114459:217')]

    data = json.loads(flask.request.get_data().decode('utf-8'))
    source_host = data['source']
    target_host = data['destination']
    # source_host = ":".join(path[0].split(":")[1::])
    # target_host = ":".join(path[-1].split(":")[1::])

    # Install a flow in each switch on the path with correct output
    # port.
    if dst_vlan:
        source_host, target_host = target_host, source_host
        src_vlan, dst_vlan = dst_vlan, src_vlan
        ports.reverse()

    first = src_vlan
    for source_port, target_port in ports:
        source_switch = "%s:%s" % (source_port.split(":")[0],
                                   source_port.split(":")[1])
        target_switch = "%s:%s" % (target_port.split(":")[0],
                                   target_port.split(":")[1])
        # Just in case check
        if (source_switch != target_switch):
            print "Error 500: Switches are different on path"
            flask.abort(500)

        # Match: source_port, source_host, target_host, eth_type = 0x806 ?
        # Target Action: target_port
        # Lookup for switch in database
        try:
            credentials = (odl_user, odl_pass)
            odl = ODLInstance(odl_server, credentials)
            node = odl.get_node_by_id(target_switch)
            table = node.get_table_by_id(0)  # Assuming installing on table 0
        except (NodeNotFound, TableNotFound) as e:
            print "Error: 404 - Switch or table not found in database"
            flask.abort(404)

        print "Inserting flow for %s..." % node.id

        flow_name = "L2AR%s" % path_id.split('-')[0]
        if first:
            table.l2output(flow_name=flow_name,
                           in_port=source_port,
                           connector_id=target_port,
                           source=source_host,
                           destination=target_host,
                           template_dir=template_dir,
                           ingress_vlan=src_vlan)

            table.l2output(flow_name=flow_name,
                           in_port=target_port,
                           connector_id=source_port,
                           source=target_host,
                           destination=source_host,
                           template_dir=template_dir,
                           egress_vlan=src_vlan)

            first = False
            continue

        # Install the flow one way
        table.l2output(flow_name=flow_name,
                       in_port=source_port,
                       connector_id=target_port,
                       source=source_host,
                       destination=target_host,
                       template_dir=template_dir)

        # Install the flow another way
        table.l2output(flow_name=flow_name,
                       in_port=target_port,
                       connector_id=source_port,
                       source=target_host,
                       destination=source_host,
                       template_dir=template_dir)

    cache_l2paths[path_id] = path
    # Update Json file
    return flask.redirect("/")
Exemple #29
0
    pw = args.get("<password>")
    if not pw:
        pw = "admin"

    ffile = args.get("<flow_file>")
        
    info =\
"""File  : %s
Server: %s
User  : %s
Passwd: %s\n""" % (ffile, url, user, "*****" if pw != "admin" else pw)
    print info
    
    try:
        f = open(ffile, 'r')
        fstr = f.read()
        flows = json.loads(fstr)
    except Exception, e:
        print "Error: %s" % e
        
    odl = ODLInstance(url, (user, pw))
    nodes = odl.get_nodes()
    for flow in flows:
        sw = flow['switch']
        tid = flow['flow']['table_id']
        tables = nodes[sw].get_tables()
        tables[tid].put_flow_from_data_json(json.dumps({"flow": flow['flow']}), flow['id'])
    f.close()
    
Exemple #30
0
    pw = args.get("<password>")
    if not pw:
        pw = "admin"

    ffile = args.get("<flow_file>")

    info =\
"""File  : %s
Server: %s
User  : %s
Passwd: %s\n""" % (ffile, url, user, "*****" if pw != "admin" else pw)
    print info

    try:
        f = open(ffile, 'r')
        fstr = f.read()
        flows = json.loads(fstr)
    except Exception, e:
        print "Error: %s" % e

    odl = ODLInstance(url, (user, pw))
    nodes = odl.get_nodes()
    for flow in flows:
        sw = flow['switch']
        tid = flow['flow']['table_id']
        tables = nodes[sw].get_tables()
        tables[tid].put_flow_from_data_json(json.dumps({"flow": flow['flow']}),
                                            flow['id'])
    f.close()
Exemple #31
0
def install_flows_for_l2path(path_id):
    """
    This will install a l2 full path flows (based on MAC addresses) in all
    switches in a path.

    You should use first '/api/routes/l2' to see the uid of path. This is a
    necessary argument for this endpoint.
    """
    client_ip = "%s" % flask.request.environ['REMOTE_ADDR']
    try:
        path = session_l2paths[client_ip][path_id]
        path, src_vlan, dst_vlan = path['path'], path['src-vlan'], path['dst-vlan']
        src_vlan = src_vlan if src_vlan != '' else None
        dst_vlan = dst_vlan if dst_vlan != '' else None
    except KeyError:
        flask.abort(404)

    ports = get_ports_on_path(path)

    # [(u'openflow:562958149829575:2', u'openflow:562958149829575:21'),
    #  (u'openflow:440565346114459:257', u'openflow:440565346114459:217')]

    data = json.loads(flask.request.get_data().decode('utf-8'))
    source_host = data['source']
    target_host = data['destination']
    # source_host = ":".join(path[0].split(":")[1::])
    # target_host = ":".join(path[-1].split(":")[1::])

    # Install a flow in each switch on the path with correct output
    # port.
    if dst_vlan:
        source_host, target_host = target_host, source_host
        src_vlan, dst_vlan = dst_vlan, src_vlan
        ports.reverse()

    first = src_vlan
    for source_port, target_port in ports:
        source_switch = "%s:%s" % (source_port.split(":")[0], source_port.split(":")[1])
        target_switch = "%s:%s" % (target_port.split(":")[0], target_port.split(":")[1])
        # Just in case check
        if (source_switch != target_switch):
            print "Error 500: Switches are different on path"
            flask.abort(500)

        # Match: source_port, source_host, target_host, eth_type = 0x806 ?
        # Target Action: target_port
        # Lookup for switch in database
        try:
            credentials = (odl_user, odl_pass)
            odl = ODLInstance(odl_server, credentials)
            node = odl.get_node_by_id(target_switch)
            table = node.get_table_by_id(0) # Assuming installing on table 0
        except (NodeNotFound, TableNotFound) as e:
            print "Error: 404 - Switch or table not found in database"
            flask.abort(404)

        print "Inserting flow for %s..." % node.id

        flow_name = "L2AR%s" % path_id.split('-')[0]
        if first:
            table.l2output(flow_name = flow_name,
                           in_port = source_port,
                           connector_id = target_port,
                           source = source_host,
                           destination = target_host,
                           template_dir = template_dir,
                           ingress_vlan = src_vlan)

            table.l2output(flow_name = flow_name,
                           in_port = target_port,
                           connector_id = source_port,
                           source = target_host,
                           destination = source_host,
                           template_dir = template_dir,
                           egress_vlan = src_vlan)

            first = False
            continue

        # Install the flow one way
        table.l2output(flow_name = flow_name,
                       in_port = source_port,
                       connector_id = target_port,
                       source = source_host,
                       destination = target_host,
                       template_dir = template_dir)

        # Install the flow another way
        table.l2output(flow_name = flow_name,
                       in_port = target_port,
                       connector_id = source_port,
                       source = target_host,
                       destination = source_host,
                       template_dir = template_dir)

    cache_l2paths[path_id] = path
    # Update Json file
    return flask.redirect("/")