blob: 973385ad9a37da64bdd63cab671be1a97d759af3 [file] [log] [blame]
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001#!/usr/bin/python
2
3"""
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07004Copyright 2015 Open Networking Foundation (ONF)
5
6Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
7the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
8or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
9
10 TestON is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 2 of the License, or
13 (at your option) any later version.
14
15 TestON is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with TestON. If not, see <http://www.gnu.org/licenses/>.
22"""
23
24"""
kelvin-onlabd9e23de2015-08-06 10:34:44 -070025Custom topology for Mininet
26Author: kelvin@onlab.us
27"""
28from mininet.topo import Topo
29from mininet.net import Mininet
30from mininet.node import Host, RemoteController
31from mininet.node import Node
32from mininet.node import CPULimitedHost
33from mininet.link import TCLink
34from mininet.cli import CLI
35from mininet.log import setLogLevel
36from mininet.util import dumpNodeConnections
37from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
38import sys
39coreSwitches = {}
40spineSwitches = {}
41leafSwitches = {}
42endSwitches = {}
43allSwitches = {}
44# Counters for nodes
45totalSwitches = 0
46totalEndSwitches = 0
47totalHosts = 0
48endSwitchCount = 0 # total count of end switch in each row in gui
49class spineTopo( Topo ):
50
51 def __init__( self, **opts ):
52 "Create a topology."
53 Topo.__init__( self, **opts )
54
55 def build( self, s, l, c, e, h, **opts ):
56 """
57 s = number of spine switches
58 l = number of leaf switches
59 c = number of core
60 e = number of end switch
61 h = number of end host
62 """
63 global totalSwitches
64 global coreSwitches
65 global spineSwitches
66 global leafSwitches
67 global endSwitches
68 global totalEndSwitches
69 global totalHosts
70 global allSwitches
71 global endSwitchCount
72 endSwitchCount = e
73
74 print "Creating topology with", s,"spine", l,"leaf", c,"core",\
75 e,"end switches and",h,"host for each end switches"
76
77 self.addCore( c )
78 self.addSpine( s )
79 self.addLeaf( l )
80 self.linkLayer( coreSwitches, spineSwitches )
81 self.linkLayer( spineSwitches, leafSwitches )
82 self.linkEndSwitch( e, leafSwitches )
83 self.linkHosts( h )
84
85 allSwitches = coreSwitches
86 allSwitches.update( spineSwitches )
87 allSwitches.update( leafSwitches )
88 allSwitches.update( endSwitches )
89 deviceData = self.createSwitchDict()
90 self.genCfgJson( deviceData )
91
92
93 def addCore( self, numSwitch ):
94 global totalSwitches
95 global coreSwitches
96 for i in range( numSwitch ):
97 coreSwitches[ 'core' + str( i + 1 ) ] = self.addSwitch(
98 's' + str( totalSwitches + 1 ) )
99 totalSwitches += 1
100
101 def addSpine( self, numSwitch ):
102 global totalSwitches
103 global spineSwitches
104 for i in range( numSwitch ):
105 spineSwitches[ 'spine' + str( i + 1 ) ] = self.addSwitch(
106 's' + str( totalSwitches + 1 ) )
107 totalSwitches += 1
108
109 def addLeaf( self, numSwitch ):
110 global totalSwitches
111 global leafSwitches
112 for i in range( numSwitch ):
113 leafSwitches[ 'leaf' + str( i + 1 ) ] = self.addSwitch(
114 's' + str( totalSwitches + 1 ) )
115 totalSwitches += 1
116
117 def addEnd( self ):
118 global totalSwitches
119 global totalEndSwitches
120 global endSwitches
121
122 endSwitches[ 'end' + str( totalEndSwitches + 1 ) ] = self.addSwitch(
123 's' + str( totalSwitches + 1 ) )
124 totalSwitches += 1
125 totalEndSwitches += 1
126
127 return endSwitches[ 'end' + str( totalEndSwitches ) ]
128
129 def addEndHosts( self ):
130 global totalHosts
131
132 totalHosts += 1
133 host = self.addHost( 'h' + str( totalHosts ) )
134
135 return host
136
137
138 def linkHosts( self, numHosts ):
139 global endSwitches
140 switches = sorted( endSwitches.values() )
141
142 for sw in switches:
143 for i in xrange( numHosts ):
144 self.addLink( sw, self.addEndHosts() )
145
146
147 def linkLayer( self, topLayer, botLayer ):
148 """
149 Description:
150 The top layer is the upper layer in the spine topology eg. top layer
151 can be the spine and the bottom layer is the leaf, another is the
152 core layer is the top layer and the spine is the bottom layer and
153 so on.
154 Required:
155 topLayer - Upper layer in the spine topology to be linked in the
156 layer below
157 botLater - Layer that is below the upper layer to be linked at
158 """
159
160 topSwitches = sorted( topLayer.keys() )
161 botSwitches = sorted( botLayer.keys() )
162
163 for topSw in topSwitches:
164 for botSw in botSwitches:
165 self.addLink( topLayer.get( topSw ), botLayer.get( botSw ) )
166
167
168 def linkEndSwitch( self, numSwitch, leafLayer ):
169 global totalSwitches
170 global totalEndSwitches
171
172 leaf = sorted( leafLayer.values() )
173
174 for i in xrange( len( leafSwitches ) ):
175 if len( leafSwitches ) == 1:
176 for j in xrange( numSwitch ):
177 self.addLink( leaf[ 0 ], self.addEnd() )
178 break
179 if len( leafSwitches ) == 2:
180 for j in xrange( numSwitch ):
181 endSw = self.addEnd()
182 self.addLink( leaf[ i ], endSw )
183 self.addLink( leaf[ i + 1 ], endSw )
184 break
185 if i == ( len( leafSwitches ) - 1 ) and len( leafSwitches )%2:
186 for j in xrange( numSwitch ):
187 self.addLink( leaf[ i ], self.addEnd() )
188 break
189 if i == 0:
190 for j in xrange( numSwitch ):
191 endSw = self.addEnd()
192 self.addLink( leaf[ i ], endSw )
193 self.addLink( leaf[ i + 1 ], endSw )
194 continue
195 if i == 1:
196 continue
197 if i%2 == 0:
198 for j in xrange( numSwitch ):
199 endSw = self.addEnd()
200 self.addLink( leaf[ i ], endSw )
201 self.addLink( leaf[ i + 1 ], endSw )
202
203 def genCfgJson( self, deviceData ):
204 import json
205 configJson = {}
206 configJson[ "devices" ] = deviceData
207 with open( 'spine.json', 'w+' ) as outfile:
208 json.dump( configJson, outfile )
209 #cfgFile = open( "spine.json" , 'w+' )
210 #cfgFile.write( configJson )
211 #cfgFile.close()
212
213
214
215 def createSwitchDict( self ):
216 global allSwitches
217 global endSwitchCount
218
219 latitude = 0
220 longitude = 0
221 coreLong = -70
222 spineLong = -80
223 leafLong = -90
224 endLat = 30
225 rowCount = 0 # count of end switches or rows
226 colOffSet = 0 # off set for end switches; longitude
227
228 #for i in xrange( len( allSwitches ) ):
229 deviceList = []
230 deviceDict = {}
231 for sw in allSwitches:
232 tempSw = allSwitches.get( sw )
233 uri = str( "{0:0>16}".format( str( hex( int( tempSw[ 1: ] ) )\
234 ).split( "x" )[ 1 ] ) )
235 mac = str( "{0:0>12}".format( str( hex( int( tempSw[ 1: ] ) )\
236 ).split( "x" )[ 1 ] ) )
237
238 if "core" in sw:
239 latitude = 45
240 longitude = coreLong
241 coreLong += 2.5
242 elif "spine" in sw:
243 latitude = 40
244 longitude = spineLong
245 spineLong += 1.5
246 elif "leaf" in sw:
247 latitude = 35
248 longitude = leafLong
249 leafLong += 1.5
250 elif "end" in sw:
251 # Reset position and move to the right once every
252 # number of end switches
253 if rowCount == endSwitchCount:
254 colOffSet += 2.5
255 rowCount = 0
256 endLat = 30
257 longitude = -80 + colOffSet
258 latitude = endLat
259 endLat -= 1
260 rowCount += 1
261
262 tempItem = { "alias": allSwitches.get( sw ) ,
263 "uri": "of:" + uri,
264 "mac": mac,
265 "annotations": { "name": sw,
266 "latitude": latitude,
267 "longitude": longitude },
268 "type": "SWITCH" }
269 deviceList.append( tempItem )
270
271 return deviceList
272 #def createHostsJson( hostDict ):
273
274topos = { 'spine': ( lambda s=2, l=3, c=1, e=5, h=1: spineTopo( s=s,
275 l=l,
276 c=c,
277 e=e,
278 h=h) ) }
279
280# HERE THE CODE DEFINITION OF THE TOPOLOGY ENDS
281
282def setupNetwork():
283 "Create network"
284 topo = spineTopo()
285 #if controller_ip == '':
286 #controller_ip = '10.0.2.2';
287 # controller_ip = '127.0.0.1';
288 network = Mininet( topo=topo,
289 autoSetMacs=True,
290 controller=None )
291 network.start()
292 CLI( network )
293 network.stop()
294
295if __name__ == '__main__':
296 setLogLevel( 'info' )
297 #setLogLevel('debug')
298 setupNetwork()