import logging
import requests
-__author__ = 'Marcus Williams'
+__author__ = "Marcus Williams"
__copyright__ = "Copyright (c) 2015, Intel Corp Inc., Cisco Systems Inc. and others"
__credits__ = ["Jan Medved, Lori Jakab"]
__license__ = "New-style BSD"
__version__ = "0.0.1"
-class OvsdbConfigBlaster (object):
- PUT_HEADERS = {'Content-Type': 'application/json',
- 'Authorization': 'Basic YWRtaW46YWRtaW4=',
- 'Accept': 'application/json'}
- GET_HEADERS = {'Accept': 'application/json',
- 'Authorization': 'Basic YWRtaW46YWRtaW4='}
- DELETE_HEADERS = {'Accept': 'application/json',
- 'Authorization': 'Basic YWRtaW46YWRtaW4='}
+class OvsdbConfigBlaster(object):
+ PUT_HEADERS = {
+ "Content-Type": "application/json",
+ "Authorization": "Basic YWRtaW46YWRtaW4=",
+ "Accept": "application/json",
+ }
+ GET_HEADERS = {
+ "Accept": "application/json",
+ "Authorization": "Basic YWRtaW46YWRtaW4=",
+ }
+ DELETE_HEADERS = {
+ "Accept": "application/json",
+ "Authorization": "Basic YWRtaW46YWRtaW4=",
+ }
TIMEOUT = 10
- def __init__(self,
- controller_ip,
- controller_port,
- vswitch_ip,
- vswitch_ovsdb_port,
- vswitch_remote_ip,
- vswitch_remote_ovsdb_port,
- vswitch_port_type,
- vswitch_lst_del_br,
- delete_ports,
- num_instances):
+ def __init__(
+ self,
+ controller_ip,
+ controller_port,
+ vswitch_ip,
+ vswitch_ovsdb_port,
+ vswitch_remote_ip,
+ vswitch_remote_ovsdb_port,
+ vswitch_port_type,
+ vswitch_lst_del_br,
+ delete_ports,
+ num_instances,
+ ):
"""
Args:
:param controller_ip: The ODL host ip used to send RPCs
self.controller_port = controller_port
self.vswitch_dict = dict()
self.add_vswitch_to_dict(
- vswitch_ip,
- vswitch_remote_ip,
- vswitch_ovsdb_port, 'ovs-1')
+ vswitch_ip, vswitch_remote_ip, vswitch_ovsdb_port, "ovs-1"
+ )
if vswitch_remote_ip:
self.add_vswitch_to_dict(
- vswitch_remote_ip,
- vswitch_ip,
- vswitch_remote_ovsdb_port, 'ovs-2')
+ vswitch_remote_ip, vswitch_ip, vswitch_remote_ovsdb_port, "ovs-2"
+ )
self.vswitch_port_type = vswitch_port_type
self.vswitch_lst_del_br = vswitch_lst_del_br
self.num_instances = num_instances
self.delete_ports = delete_ports
- self.connect_vswitch(self.vswitch_dict['ovs-1'])
- if self.vswitch_dict.get('ovs-2'):
- self.connect_vswitch(self.vswitch_dict['ovs-2'])
+ self.connect_vswitch(self.vswitch_dict["ovs-1"])
+ if self.vswitch_dict.get("ovs-2"):
+ self.connect_vswitch(self.vswitch_dict["ovs-2"])
@staticmethod
def return_ovsdb_url(vswitch_ip, vswitch_ovsdb_port, url_type="config"):
"""
url_prefix = None
if url_type == "config":
- url_prefix = 'restconf/config/'
+ url_prefix = "restconf/config/"
elif url_type == "oper":
- url_prefix = 'restconf/operational/'
- ovsdb_url = url_prefix \
- + 'network-topology:' \
- 'network-topology/topology/' \
- 'ovsdb:1/node/ovsdb:%2F%2F' \
- + vswitch_ip\
- + ':' \
- + vswitch_ovsdb_port
+ url_prefix = "restconf/operational/"
+ ovsdb_url = (
+ url_prefix + "network-topology:"
+ "network-topology/topology/"
+ "ovsdb:1/node/ovsdb:%2F%2F" + vswitch_ip + ":" + vswitch_ovsdb_port
+ )
return ovsdb_url
- def add_vswitch_to_dict(self, vswitch_ip, vswitch_remote_ip, vswitch_ovsdb_port, vswitch_name):
+ def add_vswitch_to_dict(
+ self, vswitch_ip, vswitch_remote_ip, vswitch_ovsdb_port, vswitch_name
+ ):
""" Add details of an Open vSwitch instance to self.vswitch_dict
Args:
:param vswitch_ip: The ip of Open vSwitch to use
:param vswitch_ovsdb_port: The ovsdb port of Open vSwitch to use
:param vswitch_name: The name to label the added Open vSwitch instance
"""
- urlprefix = 'http://' \
- + self.controller_ip + \
- ':' \
- + self.controller_port + \
- '/'
- self.vswitch_dict.update({
- vswitch_name: {
- 'name': vswitch_name,
- 'ip': vswitch_ip,
- 'remote-ip': vswitch_remote_ip,
- 'ovsdb-port': vswitch_ovsdb_port,
- 'node-id': 'ovsdb://%s:%s'
- % (vswitch_ip,
- vswitch_ovsdb_port),
- 'post-url': urlprefix
- + OvsdbConfigBlaster.return_ovsdb_url(
- vswitch_ip,
- vswitch_ovsdb_port),
- 'get-config-url': urlprefix
- + OvsdbConfigBlaster.return_ovsdb_url(
- vswitch_ip,
- vswitch_ovsdb_port),
- 'get-oper-url': urlprefix
- + OvsdbConfigBlaster.return_ovsdb_url(
- vswitch_ip,
- vswitch_ovsdb_port)}})
+ urlprefix = "http://" + self.controller_ip + ":" + self.controller_port + "/"
+ self.vswitch_dict.update(
+ {
+ vswitch_name: {
+ "name": vswitch_name,
+ "ip": vswitch_ip,
+ "remote-ip": vswitch_remote_ip,
+ "ovsdb-port": vswitch_ovsdb_port,
+ "node-id": "ovsdb://%s:%s" % (vswitch_ip, vswitch_ovsdb_port),
+ "post-url": urlprefix
+ + OvsdbConfigBlaster.return_ovsdb_url(
+ vswitch_ip, vswitch_ovsdb_port
+ ),
+ "get-config-url": urlprefix
+ + OvsdbConfigBlaster.return_ovsdb_url(
+ vswitch_ip, vswitch_ovsdb_port
+ ),
+ "get-oper-url": urlprefix
+ + OvsdbConfigBlaster.return_ovsdb_url(
+ vswitch_ip, vswitch_ovsdb_port
+ ),
+ }
+ }
+ )
def connect_vswitch(self, vswitch_dict):
""" Connect ODL to an Open vSwitch instance using restconf
an instance of Open vSwitch
"""
connect_ovs_body = {
- u'network-topology:node': [
+ u"network-topology:node": [
{
- u'node-id': unicode(vswitch_dict['node-id']),
- u'connection-info': {
- u'ovsdb:remote-port': unicode(vswitch_dict['ovsdb-port']),
- u'ovsdb:remote-ip': unicode(vswitch_dict['ip'])
- }
+ u"node-id": unicode(vswitch_dict["node-id"]),
+ u"connection-info": {
+ u"ovsdb:remote-port": unicode(vswitch_dict["ovsdb-port"]),
+ u"ovsdb:remote-ip": unicode(vswitch_dict["ip"]),
+ },
}
]
}
- self.send_rest(self.session,
- vswitch_dict['post-url'],
- connect_ovs_body)
+ self.send_rest(self.session, vswitch_dict["post-url"], connect_ovs_body)
- def add_bridge(self, num_instances, vswitch_name='ovs-1'):
+ def add_bridge(self, num_instances, vswitch_name="ovs-1"):
"""Add num_instances of bridge to ODL config
Args:
:param num_instances: Number of bridges to create
"""
for i in range(num_instances):
- bridge_name = unicode('br-' + str(i) + '-test')
+ bridge_name = unicode("br-" + str(i) + "-test")
add_bridge_body = {
u"network-topology:node": [
{
u"node-id": u"%s/bridge/%s"
- % (unicode(self.vswitch_dict[vswitch_name]
- .get('node-id')),
- unicode(bridge_name)),
+ % (
+ unicode(self.vswitch_dict[vswitch_name].get("node-id")),
+ unicode(bridge_name),
+ ),
u"ovsdb:bridge-name": unicode(bridge_name),
u"ovsdb:datapath-id": u"00:00:b2:bf:48:25:f2:4b",
u"ovsdb:protocol-entry": [
- {
- u"protocol":
- u"ovsdb:ovsdb-bridge-protocol-openflow-13"
- }],
+ {u"protocol": u"ovsdb:ovsdb-bridge-protocol-openflow-13"}
+ ],
u"ovsdb:controller-entry": [
{
- u"target": u"tcp:%s:%s" % (self.controller_ip, self.controller_port)
- }],
+ u"target": u"tcp:%s:%s"
+ % (self.controller_ip, self.controller_port)
+ }
+ ],
u"ovsdb:managed-by": u"/network-topology:network-topology/"
- u"network-topology:topology"
- u"[network-topology:topology-id"
- u"='ovsdb:1']/network-topology:node"
- u"[network-topology:node-id="
- u"'%s']"
- % unicode(self.vswitch_dict[vswitch_name]
- .get('node-id'))
+ u"network-topology:topology"
+ u"[network-topology:topology-id"
+ u"='ovsdb:1']/network-topology:node"
+ u"[network-topology:node-id="
+ u"'%s']"
+ % unicode(self.vswitch_dict[vswitch_name].get("node-id")),
}
]
}
- self.send_rest(self.session,
- self.vswitch_dict[vswitch_name]
- .get('post-url')
- + '%2Fbridge%2F'
- + bridge_name,
- add_bridge_body)
+ self.send_rest(
+ self.session,
+ self.vswitch_dict[vswitch_name].get("post-url")
+ + "%2Fbridge%2F"
+ + bridge_name,
+ add_bridge_body,
+ )
self.session.close()
def add_port(self, port_type="ovsdb:interface-type-vxlan"):
:param port_type: The type of port to create
default: 'ovsdb:interface-type-vxlan'
"""
- bridge_name = 'br-0-test'
- self.add_bridge(1, 'ovs-1')
-# self.add_bridge(1, 'ovs-2')
+ bridge_name = "br-0-test"
+ self.add_bridge(1, "ovs-1")
+ # self.add_bridge(1, 'ovs-2')
for instance in range(self.num_instances):
for vswitch in self.vswitch_dict.itervalues():
if port_type == "ovsdb:interface-type-vxlan":
port_prefix = "tp-"
- ovsdb_rest_url = vswitch.get('post-url') \
- + '%2Fbridge%2F'\
- + bridge_name\
- + '/termination-point/'
- body_name = 'tp-body'
+ ovsdb_rest_url = (
+ vswitch.get("post-url")
+ + "%2Fbridge%2F"
+ + bridge_name
+ + "/termination-point/"
+ )
+ body_name = "tp-body"
else:
port_prefix = "port-"
- ovsdb_rest_url = vswitch.get('post-url') \
- + '%2Fbridge%2F' \
- + bridge_name\
- + '/port/'
- body_name = 'port-body'
- port_name = port_prefix + str(instance) + '-test-' + vswitch.get('ip')
- body = {'tp-body': {
- u"network-topology:termination-point": [
- {
- u"ovsdb:options": [
- {
- u"ovsdb:option": u"remote_ip",
- u"ovsdb:value": unicode(vswitch.get('remote-ip'))
- }
- ],
- u"ovsdb:name": unicode(port_name),
- u"ovsdb:interface-type": unicode(port_type),
- u"tp-id": unicode(port_name),
- u"vlan-tag": unicode(instance + 1),
- u"trunks": [
- {
- u"trunk": u"5"
- }
- ],
- u"vlan-mode": u"access"
- }
- ]
- },
+ ovsdb_rest_url = (
+ vswitch.get("post-url")
+ + "%2Fbridge%2F"
+ + bridge_name
+ + "/port/"
+ )
+ body_name = "port-body"
+ port_name = port_prefix + str(instance) + "-test-" + vswitch.get("ip")
+ body = {
+ "tp-body": {
+ u"network-topology:termination-point": [
+ {
+ u"ovsdb:options": [
+ {
+ u"ovsdb:option": u"remote_ip",
+ u"ovsdb:value": unicode(
+ vswitch.get("remote-ip")
+ ),
+ }
+ ],
+ u"ovsdb:name": unicode(port_name),
+ u"ovsdb:interface-type": unicode(port_type),
+ u"tp-id": unicode(port_name),
+ u"vlan-tag": unicode(instance + 1),
+ u"trunks": [{u"trunk": u"5"}],
+ u"vlan-mode": u"access",
+ }
+ ]
+ },
# TODO add port-body
- 'port-body': {}}
- self.send_rest(self.session,
- ovsdb_rest_url + port_name,
- body.get(body_name))
+ "port-body": {},
+ }
+ self.send_rest(
+ self.session, ovsdb_rest_url + port_name, body.get(body_name)
+ )
self.session.close()
"""
for vswitch_names in vswitch_lst_del_br:
for br_num in range(num_bridges):
- bridge_name = unicode('br-' + str(br_num) + '-test')
- self.send_rest_del(self.session,
- self.vswitch_dict[vswitch_names]
- .get('post-url')
- + '%2Fbridge%2F'
- + bridge_name)
+ bridge_name = unicode("br-" + str(br_num) + "-test")
+ self.send_rest_del(
+ self.session,
+ self.vswitch_dict[vswitch_names].get("post-url")
+ + "%2Fbridge%2F"
+ + bridge_name,
+ )
self.session.close()
def delete_port(self, num_ports):
:param num_ports: Number of ports to delete
"""
for port in range(num_ports):
- bridge_name = 'br-0-test'
+ bridge_name = "br-0-test"
for vswitch in self.vswitch_dict.itervalues():
port_prefix = "tp-"
- ovsdb_rest_url = vswitch.get('post-url') \
- + '%2Fbridge%2F' \
- + bridge_name \
- + '/termination-point/'
- port_name = port_prefix + str(port) + '-test-' + vswitch.get('ip')
- self.send_rest_del(self.session,
- ovsdb_rest_url + port_name)
+ ovsdb_rest_url = (
+ vswitch.get("post-url")
+ + "%2Fbridge%2F"
+ + bridge_name
+ + "/termination-point/"
+ )
+ port_name = port_prefix + str(port) + "-test-" + vswitch.get("ip")
+ self.send_rest_del(self.session, ovsdb_rest_url + port_name)
self.session.close()
def send_rest_del(self, session, rest_url):
:param session: The HTTP session handle
:return int: status_code - HTTP status code
"""
- ret = session.delete(rest_url,
- headers=self.DELETE_HEADERS,
- stream=False,
- timeout=self.TIMEOUT)
+ ret = session.delete(
+ rest_url, headers=self.DELETE_HEADERS, stream=False, timeout=self.TIMEOUT
+ )
if ret.status_code is not 200:
- raise ValueError(ret.text,
- ret.status_code,
- rest_url)
+ raise ValueError(ret.text, ret.status_code, rest_url)
return ret.status_code
def send_rest(self, session, rest_url, json_body):
Returns:
:return int: status_code - HTTP status code
"""
- ret = session.put(rest_url,
- json=json_body,
- headers=self.PUT_HEADERS,
- stream=False,
- timeout=self.TIMEOUT)
+ ret = session.put(
+ rest_url,
+ json=json_body,
+ headers=self.PUT_HEADERS,
+ stream=False,
+ timeout=self.TIMEOUT,
+ )
if ret.status_code is not 200:
- raise ValueError(ret.text,
- ret.status_code,
- rest_url,
- json_body)
+ raise ValueError(ret.text, ret.status_code, rest_url, json_body)
return ret.status_code
if __name__ == "__main__":
- parser = argparse.ArgumentParser(description='Add:delete bridge/port/term-points to OpenDaylight')
+ parser = argparse.ArgumentParser(
+ description="Add:delete bridge/port/term-points to OpenDaylight"
+ )
- parser.add_argument('--mode', default='None',
- help='Operating mode, can be "bridge", "port" or "term" \
- (default is "bridge")')
- parser.add_argument('--controller', default='127.0.0.1',
- help='IP of running ODL controller \
- (default is 127.0.0.1)')
- parser.add_argument('--controllerport', default='8181',
- help='Port of ODL RESTCONF \
- (default is 8181)')
- parser.add_argument('--vswitch', default='127.0.0.1',
- help='IP of Open vSwitch \
- (default is 127.0.0.1)')
- parser.add_argument('--vswitchport', default='6640',
- help='Port of Open vSwitch OVSDB server \
- (default is 6640)')
- parser.add_argument('--vswitchremote', default=None,
- help='IP of remote Open vSwitch \
- (default is none)')
- parser.add_argument('--vswitchremoteport', default=None,
- help='Port of remote Open vSwitch OVSDB server \
- (default is none)')
- parser.add_argument('--vswitchporttype', default=None,
- help='Port of remote Open vSwitch OVSDB server \
- (default is none)')
- parser.add_argument('--deletebridges', nargs='*', type=str, default=None,
- help='A list of switches on which to delete bridges, '
- 'uses instances for number of bridges. \
+ parser.add_argument(
+ "--mode",
+ default="None",
+ help='Operating mode, can be "bridge", "port" or "term" \
+ (default is "bridge")',
+ )
+ parser.add_argument(
+ "--controller",
+ default="127.0.0.1",
+ help="IP of running ODL controller \
+ (default is 127.0.0.1)",
+ )
+ parser.add_argument(
+ "--controllerport",
+ default="8181",
+ help="Port of ODL RESTCONF \
+ (default is 8181)",
+ )
+ parser.add_argument(
+ "--vswitch",
+ default="127.0.0.1",
+ help="IP of Open vSwitch \
+ (default is 127.0.0.1)",
+ )
+ parser.add_argument(
+ "--vswitchport",
+ default="6640",
+ help="Port of Open vSwitch OVSDB server \
+ (default is 6640)",
+ )
+ parser.add_argument(
+ "--vswitchremote",
+ default=None,
+ help="IP of remote Open vSwitch \
+ (default is none)",
+ )
+ parser.add_argument(
+ "--vswitchremoteport",
+ default=None,
+ help="Port of remote Open vSwitch OVSDB server \
+ (default is none)",
+ )
+ parser.add_argument(
+ "--vswitchporttype",
+ default=None,
+ help="Port of remote Open vSwitch OVSDB server \
+ (default is none)",
+ )
+ parser.add_argument(
+ "--deletebridges",
+ nargs="*",
+ type=str,
+ default=None,
+ help="A list of switches on which to delete bridges, "
+ 'uses instances for number of bridges. \
Example: "ovs-1 ovs2" \
- (default is none)')
- parser.add_argument('--deleteports', type=int, default=1,
- help='delete ports of remote open vswitch ovsdb server (default 1)')
- parser.add_argument('--instances', type=int, default=1,
- help='Number of instances to add/get (default 1)')
+ (default is none)',
+ )
+ parser.add_argument(
+ "--deleteports",
+ type=int,
+ default=1,
+ help="delete ports of remote open vswitch ovsdb server (default 1)",
+ )
+ parser.add_argument(
+ "--instances",
+ type=int,
+ default=1,
+ help="Number of instances to add/get (default 1)",
+ )
args = parser.parse_args()
- ovsdb_config_blaster = OvsdbConfigBlaster(args.controller,
- args.controllerport,
- args.vswitch,
- args.vswitchport,
- args.vswitchremote,
- args.vswitchremoteport,
- args.vswitchporttype,
- args.deletebridges,
- args.deleteports,
- args.instances)
+ ovsdb_config_blaster = OvsdbConfigBlaster(
+ args.controller,
+ args.controllerport,
+ args.vswitch,
+ args.vswitchport,
+ args.vswitchremote,
+ args.vswitchremoteport,
+ args.vswitchporttype,
+ args.deletebridges,
+ args.deleteports,
+ args.instances,
+ )
if args.mode == "bridge":
if args.deletebridges is not None:
- ovsdb_config_blaster.delete_bridge(ovsdb_config_blaster.
- vswitch_lst_del_br,
- ovsdb_config_blaster.
- num_instances)
+ ovsdb_config_blaster.delete_bridge(
+ ovsdb_config_blaster.vswitch_lst_del_br,
+ ovsdb_config_blaster.num_instances,
+ )
else:
ovsdb_config_blaster.add_bridge(ovsdb_config_blaster.num_instances)
elif args.mode == "term":
else:
ovsdb_config_blaster.add_port()
else:
- print("please use: python ovsdbconfigblaster.py --help "
- "\nUnsupported mode: ", args.mode)
+ print(
+ "please use: python ovsdbconfigblaster.py --help " "\nUnsupported mode: ",
+ args.mode,
+ )