Creating a topology using python - python

I want to build a mininet topology using python API. My topology is supposed to have 2 controllers, 3 switches and each switch will have several hosts connected to it (number of connected hosts is 2, 4, 1 respectively). Here is the code:
#!/usr/bin/python
import time
from mininet.net import Mininet
from mininet.node import Controller, OVSKernelSwitch, RemoteController
from mininet.cli import CLI
from mininet.log import setLogLevel, info
def net():
net = Mininet(controller=RemoteController, switch=OVSKernelSwitch)
c1 = net.addController('c1', controller=RemoteController, ip="127.0.0.1", port=6653)
c2 = net.addController('c2', controller=RemoteController, ip="127.0.0.1", port=7753)
s_n = 3 #number of switches
c_n = 2 #number of controllers
hosts = []
amount = [2, 4, 1] # number of hosts that each switch has
info( "*** Creating switches\n" )
switches = [ net.addSwitch( 's%s' % s ) for s in range( 1, s_n ) ]
index1 = 0
L_in = 0
index2 = 0
info( "*** Creating hosts\n" )
for s in switches:
L_in = (L_in + 1)
if L_in <= len(amount):
index1 = (index2 + 1)
index2 = (index1 + amount[L_in]) - 1
hosts = [ net.addHost( 'h%s' % n ) for n in ( index1, index2 ) ]
for h in hosts:
net.addLink( s, h )
else:
break
# Wire up switches
last = None
for switch in switches:
if last:
net.addLink( last, switch )
last = switch
net.build()
c1.start()
c2.start()
for sw in switches[:c_n]:
sw.start( [c1] )
for sw in switches[c_n:]:
sw.start( [c2] )
net.start()
CLI( net )
net.stop()
if __name__ == '__main__':
setLogLevel( 'info' )
net()
But when I run the code, it is not working correctly. For example, I expect 3 switches, but 2 switches are created. I expect 7 hosts, but 4 hosts are created. The connection between hosts and switches is not correct, too. Here is the output:
*** Creating switches
*** Creating hosts
*** Configuring hosts
h1 h4 h5 h5
*** Starting controller
c1 c2
*** Starting 2 switches
s1 s2 ...
*** Starting CLI:
mininet> net
h1 h1-eth0:s1-eth1
h4 h4-eth0:s1-eth2
h5 h5-eth0:s2-eth2
h5 h5-eth0:s2-eth2
s1 lo: s1-eth1:h1-eth0 s1-eth2:h4-eth0 s1-eth3:s2-eth3
s2 lo: s2-eth1:h5-eth0 s2-eth2:h5-eth0 s2-eth3:s1-eth3
c1
c2

A number of problems here.
range(1, n) produces numbers from 1 no n-1, not to n.
You define function net that will shadow the previous (imported?) definition of module net. Call it make_net or something.
Explicit loop indices like L_in is almost always a bad idea, same as non-descriptive names as index2.
Something like this should give you the idea:
n_switches = 3
hosts_per_switch = [2, 4, 1]
switches = [addSwitch("s%d" % n + 1) for n in range(n_switches)]
for (switch, number_of_hosts) in zip(switches, hosts_per_switch): # Pair them.
hosts = [addHost("h%d" % n + 1) for n in range(number_of_hosts)]
for host in hosts:
addLink(switch, host)

Related

Python - issue with removing fields from the output

I have an issue with my code. I need the script to remove fields which fill all three conditions:
the CreatedBy is koala,
Book is PI or SI or II or OT or FG,
and the Category **is ** Cert or CertPlus or Cap or Downside.
Currently my code removes all koala and all books and only takes the last argument. So for example my current output leaves fields only if the category is different. I would like it to show fields ONLY if all 3 arguments are met and not if koala or book = PI or SI or II or OT or FG and to show everything else which is in range.
If field is created by koala and category is Cert I wish to see this field but now it is removed.
Or if none of the arguments are met I also want to see those fields ( e.g. createdby is Extra, Book is NG and Category is Multiple. Now those are also removed from the output.
Example dataset:
In the link below - I wish to remove only those marked red:
current_path = os.path.dirname(os.path.realpath(sys.argv[0]))
a_path, q_path = 0, 0
def assign_path(current_path, a_path = 0, q_path = 0):
files = os.listdir(current_path)
for i in files:
if re.search('(?i)activity',i):
a_path = '\\'.join([current_path,i])
elif re.search('(?i)query',i):
q_path = '\\'.join([current_path,i])
return a_path, q_path
a_path, q_path = assign_path(current_path)
if a_path == 0 or q_path == 0:
files = os.listdir(current_path)
directories = []
for i in files:
if os.path.isdir(i): directories.append(i)
for i in directories:
if re.search('(?i)input',i):
a_path, q_path = assign_path('\\'.join([current_path,i]), a_path, q_path)
L = list(range(len(qr)))
L1 = list(range(len(qr2)))
L2 = list(range(len(ac)))
-------------------------------------------------------
qr = pd.read_excel(q_path)
qr2 = pd.read_excel(q_path)
qr_rec = qr2.iloc[[0,1]]
d = qr2.iloc[0].to_dict()
for i in list(d.keys()): d[i] = np.nan
for i in range(len(qr2)):
if qr2.iloc[i]['LinkageLinkType'] != 'B2B_COUNTER_TRADE'\
and qr2.iloc[i]['CreatedBy'] == 'koala_'\
and qr2.iloc[i]['Book'] in {'PI','SI','II','OT','FG'}\
and qr2.iloc[i]['Category'] not in {'Cert','CertPlus','Cap','Downside'}:
while i in L: L.remove(i)
if qr2.iloc[i]['PrimaryRiskId'] not in list(aID):
qr_rec = qr_rec.append(qr2.iloc[i],ignore_index=True)
I have added the beggining of the code which allows me to use the Excel file. I have two files, one of them being a_path ( please disregard this one). The issue I have is on the q_path.
Check this out:
pd.read_csv('stackoverflow.csv')
category book createdby
0 Multiple NG panda
1 Cert DG koala
2 Cap PI monkey
3 CertPlus ZZ panda
4 Cap ll joey
5 Cert OT koala
6 Cap FG koala
7 Cert PI koala
8 Block SI koala
9 Cap II koala
df.query("~(category in ['Cert', 'Cap'] and book in ['OT', 'FG', 'PI', 'II'] and createdby=='koala')")
category book createdby
0 Multiple NG panda
1 Cert DG koala
2 Cap PI monkey
3 CertPlus ZZ panda
4 Cap ll joey
8 Block SI koala
pd.DataFrame.query can be used to filter data, the ~ at the beginning is a not operator.
BR
E

List comprehension in python error?

I want to get the result of nmcli (linux) in a 3D list in python.
The sample output of nmcli device show is
GENERAL.DEVICE: wlan0
GENERAL.TYPE: wifi
GENERAL.HWADDR: :::::
GENERAL.MTU: 1500
GENERAL.STATE: 100 (connected)
GENERAL.CONNECTION:
GENERAL.CON-PATH: /org/freedesktop/NetworkManager/ActiveConnection/2
IP4.ADDRESS[1]: 192.168.1.106/16
IP4.GATEWAY: 192.168.1.1
IP4.ROUTE[1]: dst = 0.0.0.0/0, nh = 192.168.1.1, mt = 600
IP4.ROUTE[2]: dst = 192.168.0.0/16, nh = 0.0.0.0, mt = 600
IP4.DNS[1]: 192.168.1.1
IP6.ADDRESS[1]: :::::::/
IP6.ADDRESS[2]: :::::/
IP6.GATEWAY: :::::
IP6.ROUTE[1]: dst = :::::/, nh = ::, mt = 600
IP6.ROUTE[2]: dst = ::/0, nh = fe80::30ae:bfff:fe20:64d, mt = 600
IP6.ROUTE[3]: dst = ::/, nh = ::, mt = 256, table=255
IP6.ROUTE[4]: dst = ::/, nh = ::, mt = 256
IP6.ROUTE[5]: dst = ::/, nh = ::, mt = 600
IP6.DNS[1]: :::::
IP6.DNS[2]: :::::::
GENERAL.DEVICE: eth0
GENERAL.TYPE: ethernet
GENERAL.HWADDR: :::::
GENERAL.MTU: 1500
GENERAL.STATE: 20 (unavailable)
GENERAL.CONNECTION: --
GENERAL.CON-PATH: --
WIRED-PROPERTIES.CARRIER: off
GENERAL.DEVICE: lo
GENERAL.TYPE: loopback
GENERAL.HWADDR: 00:00:00:00:00:00
GENERAL.MTU: 65536
GENERAL.STATE: 10 (unmanaged)
GENERAL.CONNECTION: --
GENERAL.CON-PATH: --
IP4.ADDRESS[1]: 127.0.0.1/8
IP4.GATEWAY: --
IP6.ADDRESS[1]: ::1/128
IP6.GATEWAY: --
As you can see there are three interfaces : wlan0 , eth0 and lo.
I want a list of columns in a list of rows in a list of interfaces (3D).
I used subprocess to get the result
r1 = subprocess.run(['nmcli', 'device', 'show'], stdout=subprocess.PIPE)
r2 = [y.split() for y in [z.split('\n') for z in r1.split('\n\n')]]
But I get the following error
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <listcom>
AttributeError: 'list' object has no attribute 'split'
Any suggestions?
PS: I ran that on python 3.6.3 shell
The result of [z.split('\n') for z in r1.split('\n\n')] is a list of lists, so when you iterate over it you are trying to split a list instead of a string. The error is in y.split().
I think what you want is:
r2 = [[y.split() for y in z.split('\n')] for z in r1.split('\n\n')]

Mininet-wifi custom topology

At first I want wanted to create a complex topology (more switches connected to each other) but even this simple one is not working. I am not able to get a working connection eg. 'h1 ping h2'
Here is the topology:
He is the script that should create the equivalent topology:
!/usr/bin/python
"""
Setting the position of Nodes (only for Stations and Access Points) and providing mobility.
"""
from mininet.net import Mininet
from mininet.node import Controller, RemoteController, OVSKernelAP
from mininet.link import TCLink
from mininet.cli import CLI
from mininet.log import setLogLevel
def topology():
"Create a network."
net = Mininet( controller=Controller, link=TCLink, accessPoint=OVSKernelAP )
print "*** Creating nodes"
h1 = net.addHost( 'h1', mac='00:00:00:00:00:01', ip='10.0.0.1/8' )
h2 = net.addHost( 'h2', mac='00:00:00:00:00:11', ip='10.0.1.1/8' )
sta1 = net.addStation( 'sta1', mac='00:00:00:00:00:02', ip='10.0.0.2/8', position='50,50,0' )
sta2 = net.addStation( 'sta2', mac='00:00:00:00:00:03', ip='10.0.0.3/8', position='40,50,0')
sta3 = net.addStation( 'sta3', mac='00:00:00:00:00:04', ip='10.0.0.4/8', position='20,50,0' )
ap1 = net.addAccessPoint( 'ap1', ssid= 'new-ssid', mode= 'g', channel= '5', position='25,50,0', range='35' )
ap2 = net.addAccessPoint( 'ap2', ssid= 'new-ssid', mode= 'g', channel= '5', position='75,50,0', range='35' )
c1 = net.addController( 'c1' )
s1 = net.addSwitch('s1')
#net.runAlternativeModule('../module/mac80211_hwsim.ko')
print "*** Configuring wifi nodes"
net.configureWifiNodes()
print "*** Associating and Creating links"
net.addLink(ap1, s1)
net.addLink(ap2, s1)
net.addLink(s1, c1)
#net.addLink(ap1, ap2)
net.addLink(s1, h1)
net.addLink(s1, h2)
net.addLink(ap1, sta1)
net.addLink(ap1, sta2)
net.addLink(ap1, sta3)
print "*** Starting network"
net.build()
c1.start()
ap1.start( [c1] )
ap2.start( [c1] )
"""uncomment to plot graph"""
net.plotGraph(max_x=100, max_y=100)
net.startMobility(startTime=0)
net.mobility(sta1, 'start', time=1, position='0.0,50.0,0.0')
net.mobility(sta1, 'stop', time=30, position='100.0,50.0,0.0')
net.stopMobility(stopTime=31)
print "*** Running CLI"
CLI( net )
print "*** Stopping network"
net.stop()
if __name__ == '__main__':
setLogLevel( 'info' )
topology()
As already said, I am not able to even ping h1 and h2 :(
I even tried to use RemoteController but got the same result.
Any idea what might be wrong?
Please consider the changes below:
from mininet.node import Controller, RemoteController, OVSKernelAP, OVSSwitch
net = Mininet( controller=Controller, link=TCLink, accessPoint=OVSKernelAP, switch=OVSSwitch )
c1 = net.addController( 'c1', controller=Controller )
s3 = net.addSwitch('s3')
Remove:
net.addLink(s1, c1)
Add:
s3.start( [c1] )
Please note that if you set both ap and switch with the same ID (e.g. s1, ap1), they will have the same DPID by default. So, I had to rename s1 to s3. On the other hand you may define the DPID as a parameter when you add the node whether you want.

Converting multi-line script output to dictionary using regex

I got the following script output:
***************************************************
[g4u2680c]: searching for domains
---------------------------------------------------
host = g4u2680c.houston.example.com
ipaddr = [16.208.16.72]
VLAN = [352]
Gateway= [16.208.16.1]
Subnet = [255.255.248.0]
Subnet = [255.255.248.0]
Cluster= [g4u2679c g4u2680c g9u1484c g9u1485c]
host = g4u2680c.houston.example.com
ipaddr = [16.208.16.72]
VLAN = [352]
Gateway= [16.208.16.1]
Subnet = [255.255.248.0]
Subnet = [255.255.248.0]
Cluster= [g4u2679c g4u2680c g9u1484c g9u1485c]
* script completed Mon Jun 15 06:13:14 UTC 2015 **
* sleeping 30 to avoid DOS on dns via a loop **
I need to extract the 2 host list into a dictionary, with out the brackets.
Here is my code:
#!/bin/env python
import re
text="""***************************************************
[g4u2680c]: searching for domains
---------------------------------------------------
host = g4u2680c.houston.example.com
ipaddr = [16.208.16.72]
VLAN = [352]
Gateway= [16.208.16.1]
Subnet = [255.255.248.0]
Subnet = [255.255.248.0]
Cluster= [g4u2679c g4u2680c g9u1484c g9u1485c]
host = g4u2680c.houston.example.com
ipaddr = [16.208.16.72]
VLAN = [352]
Gateway= [16.208.16.1]
Subnet = [255.255.248.0]
Subnet = [255.255.248.0]
Cluster= [g4u2679c g4u2680c g9u1484c g9u1485c]
* script completed Mon Jun 15 06:13:14 UTC 2015 **
* sleeping 30 to avoid DOS on dns via a loop **
***************************************************
"""
seq = re.compile(r"host.+?\n\n",re.DOTALL)
a=seq.findall(text)
matches = re.findall(r'\w.+=.+', a[0])
matches = [m.split('=', 1) for m in matches]
matches = [ [m[0].strip().lower(), m[1].strip().lower()] for m in matches]
#should have function with regular expression to remove bracket here
d = dict(matches)
print d
What I got so far for the first host:
{'subnet': '[255.255.248.0]', 'vlan': '[352]', 'ipaddr': '[16.208.16.72]', 'cluster': '[g4u2679c g4u2680c g9u1484c g9u1485c]', 'host': 'g4u2680c.houston.example.com', 'gateway': '[16.208.16.1]'}
I need help to find the regex to remove the bracket as the value in the dictionary contain data with and without bracket.
Or if there is a better and simpler way to transform the original script output into dictionary.
You can use: (\w+)\s*=\s*\[?([^\n\]]+)\]?
demo
import re
p = re.compile(ur'(\w+)\s*=\s*\[?([^\n\]]+)\]?', re.MULTILINE)
test_str = u"host = g4u2680c.houston.example.com\n ipaddr = [16.208.16.72]\n VLAN = [352]\n Gateway= [16.208.16.1]\n Subnet = [255.255.248.0]\n Subnet = [255.255.248.0]\n Cluster= [g4u2679c g4u2680c g9u1484c g9u1485c]\n\nhost = g4u2680c.houston.example.com\n ipaddr = [16.208.16.72]\n VLAN = [352]\n Gateway= [16.208.16.1]\n Subnet = [255.255.248.0]\n Subnet = [255.255.248.0]\n Cluster= [g4u2679c g4u2680c g9u1484c g9u1485c]\n"
re.findall(p, test_str)
You can simply use re.findall and dict :
>>> dict([(i,j.strip('[]')) for i,j in re.findall(r'(\w+)\s*=\s*(.+)',text)])
{'Subnet': '255.255.248.0', 'VLAN': '352', 'ipaddr': '16.208.16.72', 'Cluster': 'g4u2679c g4u2680c g9u1484c g9u1485c', 'host': 'g4u2680c.houston.example.com', 'Gateway': '16.208.16.1'}
And about the brackets you can remove them by str.strip method.
You can try out this.
matches = [m.replace('[','').replace(']','').split('=', 1) for m in matches]

Two issue about python OpenOPC library

Issues description and environments
The OpenOPC library is friendly and easy to use, the api is simple too, but I have found two issues during the development of a tool to record real time OPC items data.
The development environment is: Window 8.1, Python 2.7.6, wxpython 2.8 unicode
The testing environment is: Window XP SP3, Python 2.7.6, wxpython 2.8 unicode, Rockwell's soft logix as OPC Server
The deploy environment is: Window XP SP3, connected with Rockwell's real PLC, installed RSLogix 5000 and RSLinx Classic Gateway
Questions
the opc.list function doesn't list all the item of specify node both in testing and workstaion environment. The question is how to list the 't' from the opc server?
An int array 'dint100' and a dint 't' is added with RS logix 5000 at the scope of soft_1
With the default OPC client test tool from Rockwell it could list the new added 't'
With OpenOPC library, I couldn't find out how to list the item 't', but I could read it's value by opc.read('[soft_1]t') with it's tag.
If the 't' could be listed, it could be added into the IO tree of my tool.
The opc.servers function will encounter an OPCError on the deploy environment, but the client could connect the 'RSLinx OPC Server' directly with the server name. Does opc.servers function dependent on some special dll or service?
Any suggestions will be appreciated! Thanks in advance!
Consider that the browsing problems ("opc.list") may not be on your side. RSLinx is notorious for its broken OPC browsing. Try some test/simulation server from a different vendor, to test this hypothesis.
I realize that I'm really late to this game. I found what was causing this issue. OpenOPC.py assumes that there cannot be both a "Leaf" and a "Branch" on the same level. Replace the function ilist with this:
def ilist(self, paths='*', recursive=False, flat=False, include_type=False):
"""Iterable version of list()"""
try:
self._update_tx_time()
pythoncom.CoInitialize()
try:
browser = self._opc.CreateBrowser()
# For OPC servers that don't support browsing
except:
return
paths, single, valid = type_check(paths)
if not valid:
raise TypeError("list(): 'paths' parameter must be a string or a list of strings")
if len(paths) == 0: paths = ['*']
nodes = {}
for path in paths:
if flat:
browser.MoveToRoot()
browser.Filter = ''
browser.ShowLeafs(True)
pattern = re.compile('^%s$' % wild2regex(path) , re.IGNORECASE)
matches = filter(pattern.search, browser)
if include_type: matches = [(x, node_type) for x in matches]
for node in matches: yield node
continue
queue = []
queue.append(path)
while len(queue) > 0:
tag = queue.pop(0)
browser.MoveToRoot()
browser.Filter = ''
pattern = None
path_str = '/'
path_list = tag.replace('.','/').split('/')
path_list = [p for p in path_list if len(p) > 0]
found_filter = False
path_postfix = '/'
for i, p in enumerate(path_list):
if found_filter:
path_postfix += p + '/'
elif p.find('*') >= 0:
pattern = re.compile('^%s$' % wild2regex(p) , re.IGNORECASE)
found_filter = True
elif len(p) != 0:
pattern = re.compile('^.*$')
browser.ShowBranches()
# Branch node, so move down
if len(browser) > 0:
try:
browser.MoveDown(p)
path_str += p + '/'
except:
if i < len(path_list)-1: return
pattern = re.compile('^%s$' % wild2regex(p) , re.IGNORECASE)
# Leaf node, so append all remaining path parts together
# to form a single search expression
else:
###################################### JG Edit - Flip the next two rows comment/uncommented
p = '.'.join(path_list[i:])
# p = string.join(path_list[i:], '.')
pattern = re.compile('^%s$' % wild2regex(p) , re.IGNORECASE)
break
###################################### JG Edit - Comment this to return to original
browser.ShowBranches()
node_types = ['Branch','Leaf']
if len(browser) == 0:
lowest_level = True
node_types.pop(0)
else:
lowest_level = False
for node_type in node_types:
if node_type=='Leaf':
browser.ShowLeafs(False)
matches = filter(pattern.search, browser)
if not lowest_level and recursive:
queue += [path_str + x + path_postfix for x in matches]
else:
###################################### JG Edit - Flip the next two rows comment/uncommented
if lowest_level or node_type=='Leaf': matches = [exceptional(browser.GetItemID,x)(x) for x in matches]
# if lowest_level: matches = [exceptional(browser.GetItemID,x)(x) for x in matches]
if include_type: matches = [(x, node_type) for x in matches]
for node in matches:
if not node in nodes: yield node
nodes[node] = True
###################################### Uncomment this to return to original
# browser.ShowBranches()
# if len(browser) == 0:
# browser.ShowLeafs(False)
# lowest_level = True
# node_type = 'Leaf'
# else:
# lowest_level = False
# node_type = 'Branch'
# matches = filter(pattern.search, browser)
# if not lowest_level and recursive:
# queue += [path_str + x + path_postfix for x in matches]
# else:
# if lowest_level: matches = [exceptional(browser.GetItemID,x)(x) for x in matches]
# if include_type: matches = [(x, node_type) for x in matches]
# for node in matches:
# if not node in nodes: yield node
# nodes[node] = True
except pythoncom.com_error as err:
error_msg = 'list: %s' % self._get_error_str(err)
raise OPCError(error_msg)

Categories

Resources