Revision 18aab5b7 examples/miniedit.py

View differences:

examples/miniedit.py
13 13
OpenFlow icon from https://www.opennetworking.org/
14 14
"""
15 15

  
16
# For now, tolerate long lines and long module
17
# pylint: disable=line-too-long,too-many-lines
18

  
16 19
MINIEDIT_VERSION = '2.2.0.1'
17 20

  
18 21
from optparse import OptionParser
......
83 86

  
84 87

  
85 88
class InbandController( RemoteController ):
86

  
89
    "RemoteController that ignores checkListening"
87 90
    def checkListening( self ):
88 91
        "Overridden to do nothing."
89 92
        return
90 93

  
91 94
class CustomUserSwitch(UserSwitch):
95
    "Customized UserSwitch"
92 96
    def __init__( self, name, dpopts='--no-slicing', **kwargs ):
93 97
        UserSwitch.__init__( self, name, **kwargs )
94 98
        self.switchIP = None
95 99

  
96 100
    def getSwitchIP(self):
101
        "Return management IP address"
97 102
        return self.switchIP
98 103

  
99 104
    def setSwitchIP(self, ip):
105
        "Set management IP address"
100 106
        self.switchIP = ip
101 107

  
102 108
    def start( self, controllers ):
109
        "Start and set management IP address"
103 110
        # Call superclass constructor
104 111
        UserSwitch.start( self, controllers )
105 112
        # Set Switch IP address
106
        if (self.switchIP is not None):
113
        if self.switchIP is not None:
107 114
            if not self.inNamespace:
108 115
                self.cmd( 'ifconfig', self, self.switchIP )
109 116
            else:
110 117
                self.cmd( 'ifconfig lo', self.switchIP )
111 118

  
112 119
class LegacyRouter( Node ):
113

  
120
    "Simple IP router"
114 121
    def __init__( self, name, inNamespace=True, **params ):
115 122
        Node.__init__( self, name, inNamespace, **params )
116 123

  
......
122 129
        return r
123 130

  
124 131
class LegacySwitch(OVSSwitch):
125

  
132
    "OVS switch in standalone/bridge mode"
126 133
    def __init__( self, name, **params ):
127 134
        OVSSwitch.__init__( self, name, failMode='standalone', **params )
128 135
        self.switchIP = None
129 136

  
130 137
class customOvs(OVSSwitch):
138
    "Customized OVS switch"
131 139

  
132 140
    def __init__( self, name, failMode='secure', datapath='kernel', **params ):
133 141
        OVSSwitch.__init__( self, name, failMode=failMode, datapath=datapath, **params )
134 142
        self.switchIP = None
135 143

  
136 144
    def getSwitchIP(self):
145
        "Return management IP address"
137 146
        return self.switchIP
138 147

  
139 148
    def setSwitchIP(self, ip):
149
        "Set management IP address"
140 150
        self.switchIP = ip
141 151

  
142 152
    def start( self, controllers ):
153
        "Start and set management IP address"
143 154
        # Call superclass constructor
144 155
        OVSSwitch.start( self, controllers )
145 156
        # Set Switch IP address
146
        if (self.switchIP is not None):
157
        if self.switchIP is not None:
147 158
            self.cmd( 'ifconfig', self, self.switchIP )
148 159

  
149 160
class PrefsDialog(tkSimpleDialog.Dialog):
161
    "Preferences dialog"
162

  
163
    def __init__(self, parent, title, prefDefaults):
164

  
165
        self.prefValues = prefDefaults
166

  
167
        tkSimpleDialog.Dialog.__init__(self, parent, title)
168

  
169
    def body(self, master):
170
        "Create dialog body"
171
        self.rootFrame = master
172
        self.leftfieldFrame = Frame(self.rootFrame, padx=5, pady=5)
173
        self.leftfieldFrame.grid(row=0, column=0, sticky='nswe', columnspan=2)
174
        self.rightfieldFrame = Frame(self.rootFrame, padx=5, pady=5)
175
        self.rightfieldFrame.grid(row=0, column=2, sticky='nswe', columnspan=2)
176

  
177
        # Field for Base IP
178
        Label(self.leftfieldFrame, text="IP Base:").grid(row=0, sticky=E)
179
        self.ipEntry = Entry(self.leftfieldFrame)
180
        self.ipEntry.grid(row=0, column=1)
181
        ipBase =  self.prefValues['ipBase']
182
        self.ipEntry.insert(0, ipBase)
183

  
184
        # Selection of terminal type
185
        Label(self.leftfieldFrame, text="Default Terminal:").grid(row=1, sticky=E)
186
        self.terminalVar = StringVar(self.leftfieldFrame)
187
        self.terminalOption = OptionMenu(self.leftfieldFrame, self.terminalVar, "xterm", "gterm")
188
        self.terminalOption.grid(row=1, column=1, sticky=W)
189
        terminalType = self.prefValues['terminalType']
190
        self.terminalVar.set(terminalType)
191

  
192
        # Field for CLI
193
        Label(self.leftfieldFrame, text="Start CLI:").grid(row=2, sticky=E)
194
        self.cliStart = IntVar()
195
        self.cliButton = Checkbutton(self.leftfieldFrame, variable=self.cliStart)
196
        self.cliButton.grid(row=2, column=1, sticky=W)
197
        if self.prefValues['startCLI'] == '0':
198
            self.cliButton.deselect()
199
        else:
200
            self.cliButton.select()
201

  
202
        # Selection of switch type
203
        Label(self.leftfieldFrame, text="Default Switch:").grid(row=3, sticky=E)
204
        self.switchType = StringVar(self.leftfieldFrame)
205
        self.switchTypeMenu = OptionMenu(self.leftfieldFrame, self.switchType, "Open vSwitch Kernel Mode", "Indigo Virtual Switch", "Userspace Switch", "Userspace Switch inNamespace")
206
        self.switchTypeMenu.grid(row=3, column=1, sticky=W)
207
        switchTypePref = self.prefValues['switchType']
208
        if switchTypePref == 'ivs':
209
            self.switchType.set("Indigo Virtual Switch")
210
        elif switchTypePref == 'userns':
211
            self.switchType.set("Userspace Switch inNamespace")
212
        elif switchTypePref == 'user':
213
            self.switchType.set("Userspace Switch")
214
        else:
215
            self.switchType.set("Open vSwitch Kernel Mode")
216

  
217

  
218
        # Fields for OVS OpenFlow version
219
        ovsFrame= LabelFrame(self.leftfieldFrame, text='Open vSwitch', padx=5, pady=5)
220
        ovsFrame.grid(row=4, column=0, columnspan=2, sticky=EW)
221
        Label(ovsFrame, text="OpenFlow 1.0:").grid(row=0, sticky=E)
222
        Label(ovsFrame, text="OpenFlow 1.1:").grid(row=1, sticky=E)
223
        Label(ovsFrame, text="OpenFlow 1.2:").grid(row=2, sticky=E)
224
        Label(ovsFrame, text="OpenFlow 1.3:").grid(row=3, sticky=E)
225

  
226
        self.ovsOf10 = IntVar()
227
        self.covsOf10 = Checkbutton(ovsFrame, variable=self.ovsOf10)
228
        self.covsOf10.grid(row=0, column=1, sticky=W)
229
        if self.prefValues['openFlowVersions']['ovsOf10'] == '0':
230
            self.covsOf10.deselect()
231
        else:
232
            self.covsOf10.select()
150 233

  
151
        def __init__(self, parent, title, prefDefaults):
152

  
153
            self.prefValues = prefDefaults
154

  
155
            tkSimpleDialog.Dialog.__init__(self, parent, title)
156

  
157
        def body(self, master):
158
            self.rootFrame = master
159
            self.leftfieldFrame = Frame(self.rootFrame, padx=5, pady=5)
160
            self.leftfieldFrame.grid(row=0, column=0, sticky='nswe', columnspan=2)
161
            self.rightfieldFrame = Frame(self.rootFrame, padx=5, pady=5)
162
            self.rightfieldFrame.grid(row=0, column=2, sticky='nswe', columnspan=2)
163

  
164

  
165
            # Field for Base IP
166
            Label(self.leftfieldFrame, text="IP Base:").grid(row=0, sticky=E)
167
            self.ipEntry = Entry(self.leftfieldFrame)
168
            self.ipEntry.grid(row=0, column=1)
169
            ipBase =  self.prefValues['ipBase']
170
            self.ipEntry.insert(0, ipBase)
171

  
172
            # Selection of terminal type
173
            Label(self.leftfieldFrame, text="Default Terminal:").grid(row=1, sticky=E)
174
            self.terminalVar = StringVar(self.leftfieldFrame)
175
            self.terminalOption = OptionMenu(self.leftfieldFrame, self.terminalVar, "xterm", "gterm")
176
            self.terminalOption.grid(row=1, column=1, sticky=W)
177
            terminalType = self.prefValues['terminalType']
178
            self.terminalVar.set(terminalType)
179

  
180
            # Field for CLI
181
            Label(self.leftfieldFrame, text="Start CLI:").grid(row=2, sticky=E)
182
            self.cliStart = IntVar()
183
            self.cliButton = Checkbutton(self.leftfieldFrame, variable=self.cliStart)
184
            self.cliButton.grid(row=2, column=1, sticky=W)
185
            if self.prefValues['startCLI'] == '0':
186
                self.cliButton.deselect()
187
            else:
188
                self.cliButton.select()
189

  
190
            # Selection of switch type
191
            Label(self.leftfieldFrame, text="Default Switch:").grid(row=3, sticky=E)
192
            self.switchType = StringVar(self.leftfieldFrame)
193
            self.switchTypeMenu = OptionMenu(self.leftfieldFrame, self.switchType, "Open vSwitch Kernel Mode", "Indigo Virtual Switch", "Userspace Switch", "Userspace Switch inNamespace")
194
            self.switchTypeMenu.grid(row=3, column=1, sticky=W)
195
            switchTypePref = self.prefValues['switchType']
196
            if switchTypePref == 'ivs':
197
                self.switchType.set("Indigo Virtual Switch")
198
            elif switchTypePref == 'userns':
199
                self.switchType.set("Userspace Switch inNamespace")
200
            elif switchTypePref == 'user':
201
                self.switchType.set("Userspace Switch")
202
            else:
203
                self.switchType.set("Open vSwitch Kernel Mode")
204

  
234
        self.ovsOf11 = IntVar()
235
        self.covsOf11 = Checkbutton(ovsFrame, variable=self.ovsOf11)
236
        self.covsOf11.grid(row=1, column=1, sticky=W)
237
        if self.prefValues['openFlowVersions']['ovsOf11'] == '0':
238
            self.covsOf11.deselect()
239
        else:
240
            self.covsOf11.select()
205 241

  
206
            # Fields for OVS OpenFlow version
207
            ovsFrame= LabelFrame(self.leftfieldFrame, text='Open vSwitch', padx=5, pady=5)
208
            ovsFrame.grid(row=4, column=0, columnspan=2, sticky=EW)
209
            Label(ovsFrame, text="OpenFlow 1.0:").grid(row=0, sticky=E)
210
            Label(ovsFrame, text="OpenFlow 1.1:").grid(row=1, sticky=E)
211
            Label(ovsFrame, text="OpenFlow 1.2:").grid(row=2, sticky=E)
212
            Label(ovsFrame, text="OpenFlow 1.3:").grid(row=3, sticky=E)
242
        self.ovsOf12 = IntVar()
243
        self.covsOf12 = Checkbutton(ovsFrame, variable=self.ovsOf12)
244
        self.covsOf12.grid(row=2, column=1, sticky=W)
245
        if self.prefValues['openFlowVersions']['ovsOf12'] == '0':
246
            self.covsOf12.deselect()
247
        else:
248
            self.covsOf12.select()
213 249

  
214
            self.ovsOf10 = IntVar()
215
            self.covsOf10 = Checkbutton(ovsFrame, variable=self.ovsOf10)
216
            self.covsOf10.grid(row=0, column=1, sticky=W)
217
            if self.prefValues['openFlowVersions']['ovsOf10'] == '0':
218
                self.covsOf10.deselect()
219
            else:
220
                self.covsOf10.select()
250
        self.ovsOf13 = IntVar()
251
        self.covsOf13 = Checkbutton(ovsFrame, variable=self.ovsOf13)
252
        self.covsOf13.grid(row=3, column=1, sticky=W)
253
        if self.prefValues['openFlowVersions']['ovsOf13'] == '0':
254
            self.covsOf13.deselect()
255
        else:
256
            self.covsOf13.select()
257

  
258
        # Field for DPCTL listen port
259
        Label(self.leftfieldFrame, text="dpctl port:").grid(row=5, sticky=E)
260
        self.dpctlEntry = Entry(self.leftfieldFrame)
261
        self.dpctlEntry.grid(row=5, column=1)
262
        if 'dpctl' in self.prefValues:
263
            self.dpctlEntry.insert(0, self.prefValues['dpctl'])
264

  
265
        # sFlow
266
        sflowValues = self.prefValues['sflow']
267
        self.sflowFrame= LabelFrame(self.rightfieldFrame, text='sFlow Profile for Open vSwitch', padx=5, pady=5)
268
        self.sflowFrame.grid(row=0, column=0, columnspan=2, sticky=EW)
269

  
270
        Label(self.sflowFrame, text="Target:").grid(row=0, sticky=E)
271
        self.sflowTarget = Entry(self.sflowFrame)
272
        self.sflowTarget.grid(row=0, column=1)
273
        self.sflowTarget.insert(0, sflowValues['sflowTarget'])
274

  
275
        Label(self.sflowFrame, text="Sampling:").grid(row=1, sticky=E)
276
        self.sflowSampling = Entry(self.sflowFrame)
277
        self.sflowSampling.grid(row=1, column=1)
278
        self.sflowSampling.insert(0, sflowValues['sflowSampling'])
279

  
280
        Label(self.sflowFrame, text="Header:").grid(row=2, sticky=E)
281
        self.sflowHeader = Entry(self.sflowFrame)
282
        self.sflowHeader.grid(row=2, column=1)
283
        self.sflowHeader.insert(0, sflowValues['sflowHeader'])
284

  
285
        Label(self.sflowFrame, text="Polling:").grid(row=3, sticky=E)
286
        self.sflowPolling = Entry(self.sflowFrame)
287
        self.sflowPolling.grid(row=3, column=1)
288
        self.sflowPolling.insert(0, sflowValues['sflowPolling'])
289

  
290
        # NetFlow
291
        nflowValues = self.prefValues['netflow']
292
        self.nFrame= LabelFrame(self.rightfieldFrame, text='NetFlow Profile for Open vSwitch', padx=5, pady=5)
293
        self.nFrame.grid(row=1, column=0, columnspan=2, sticky=EW)
294

  
295
        Label(self.nFrame, text="Target:").grid(row=0, sticky=E)
296
        self.nflowTarget = Entry(self.nFrame)
297
        self.nflowTarget.grid(row=0, column=1)
298
        self.nflowTarget.insert(0, nflowValues['nflowTarget'])
299

  
300
        Label(self.nFrame, text="Active Timeout:").grid(row=1, sticky=E)
301
        self.nflowTimeout = Entry(self.nFrame)
302
        self.nflowTimeout.grid(row=1, column=1)
303
        self.nflowTimeout.insert(0, nflowValues['nflowTimeout'])
304

  
305
        Label(self.nFrame, text="Add ID to Interface:").grid(row=2, sticky=E)
306
        self.nflowAddId = IntVar()
307
        self.nflowAddIdButton = Checkbutton(self.nFrame, variable=self.nflowAddId)
308
        self.nflowAddIdButton.grid(row=2, column=1, sticky=W)
309
        if nflowValues['nflowAddId'] == '0':
310
            self.nflowAddIdButton.deselect()
311
        else:
312
            self.nflowAddIdButton.select()
313

  
314
        # initial focus
315
        return self.ipEntry
316

  
317
    def apply(self):
318
        ipBase = self.ipEntry.get()
319
        terminalType = self.terminalVar.get()
320
        startCLI = str(self.cliStart.get())
321
        sw = self.switchType.get()
322
        dpctl = self.dpctlEntry.get()
323

  
324
        ovsOf10 = str(self.ovsOf10.get())
325
        ovsOf11 = str(self.ovsOf11.get())
326
        ovsOf12 = str(self.ovsOf12.get())
327
        ovsOf13 = str(self.ovsOf13.get())
328

  
329
        sflowValues = {'sflowTarget':self.sflowTarget.get(),
330
                       'sflowSampling':self.sflowSampling.get(),
331
                       'sflowHeader':self.sflowHeader.get(),
332
                       'sflowPolling':self.sflowPolling.get()}
333
        nflowvalues = {'nflowTarget':self.nflowTarget.get(),
334
                       'nflowTimeout':self.nflowTimeout.get(),
335
                       'nflowAddId':str(self.nflowAddId.get())}
336
        self.result = {'ipBase':ipBase,
337
                       'terminalType':terminalType,
338
                       'dpctl':dpctl,
339
                       'sflow':sflowValues,
340
                       'netflow':nflowvalues,
341
                       'startCLI':startCLI}
342
        if sw == 'Indigo Virtual Switch':
343
            self.result['switchType'] = 'ivs'
344
            if StrictVersion(MININET_VERSION) < StrictVersion('2.1'):
345
                self.ovsOk = False
346
                showerror(title="Error",
347
                          message='MiniNet version 2.1+ required. You have '+VERSION+'.')
348
        elif sw == 'Userspace Switch':
349
            self.result['switchType'] = 'user'
350
        elif sw == 'Userspace Switch inNamespace':
351
            self.result['switchType'] = 'userns'
352
        else:
353
            self.result['switchType'] = 'ovs'
221 354

  
222
            self.ovsOf11 = IntVar()
223
            self.covsOf11 = Checkbutton(ovsFrame, variable=self.ovsOf11)
224
            self.covsOf11.grid(row=1, column=1, sticky=W)
225
            if self.prefValues['openFlowVersions']['ovsOf11'] == '0':
226
                self.covsOf11.deselect()
227
            else:
228
                self.covsOf11.select()
355
        self.ovsOk = True
356
        if ovsOf11 == "1":
357
            ovsVer = self.getOvsVersion()
358
            if StrictVersion(ovsVer) < StrictVersion('2.0'):
359
                self.ovsOk = False
360
                showerror(title="Error",
361
                          message='Open vSwitch version 2.0+ required. You have '+ovsVer+'.')
362
        if ovsOf12 == "1" or ovsOf13 == "1":
363
            ovsVer = self.getOvsVersion()
364
            if StrictVersion(ovsVer) < StrictVersion('1.10'):
365
                self.ovsOk = False
366
                showerror(title="Error",
367
                          message='Open vSwitch version 1.10+ required. You have '+ovsVer+'.')
229 368

  
230
            self.ovsOf12 = IntVar()
231
            self.covsOf12 = Checkbutton(ovsFrame, variable=self.ovsOf12)
232
            self.covsOf12.grid(row=2, column=1, sticky=W)
233
            if self.prefValues['openFlowVersions']['ovsOf12'] == '0':
234
                self.covsOf12.deselect()
235
            else:
236
                self.covsOf12.select()
369
        if self.ovsOk:
370
            self.result['openFlowVersions']={'ovsOf10':ovsOf10,
371
                                             'ovsOf11':ovsOf11,
372
                                             'ovsOf12':ovsOf12,
373
                                             'ovsOf13':ovsOf13}
374
        else:
375
            self.result = None
237 376

  
238
            self.ovsOf13 = IntVar()
239
            self.covsOf13 = Checkbutton(ovsFrame, variable=self.ovsOf13)
240
            self.covsOf13.grid(row=3, column=1, sticky=W)
241
            if self.prefValues['openFlowVersions']['ovsOf13'] == '0':
242
                self.covsOf13.deselect()
243
            else:
244
                self.covsOf13.select()
245

  
246
            # Field for DPCTL listen port
247
            Label(self.leftfieldFrame, text="dpctl port:").grid(row=5, sticky=E)
248
            self.dpctlEntry = Entry(self.leftfieldFrame)
249
            self.dpctlEntry.grid(row=5, column=1)
250
            if 'dpctl' in self.prefValues:
251
                self.dpctlEntry.insert(0, self.prefValues['dpctl'])
252

  
253
            # sFlow
254
            sflowValues = self.prefValues['sflow']
255
            self.sflowFrame= LabelFrame(self.rightfieldFrame, text='sFlow Profile for Open vSwitch', padx=5, pady=5)
256
            self.sflowFrame.grid(row=0, column=0, columnspan=2, sticky=EW)
257

  
258
            Label(self.sflowFrame, text="Target:").grid(row=0, sticky=E)
259
            self.sflowTarget = Entry(self.sflowFrame)
260
            self.sflowTarget.grid(row=0, column=1)
261
            self.sflowTarget.insert(0, sflowValues['sflowTarget'])
262

  
263
            Label(self.sflowFrame, text="Sampling:").grid(row=1, sticky=E)
264
            self.sflowSampling = Entry(self.sflowFrame)
265
            self.sflowSampling.grid(row=1, column=1)
266
            self.sflowSampling.insert(0, sflowValues['sflowSampling'])
267

  
268
            Label(self.sflowFrame, text="Header:").grid(row=2, sticky=E)
269
            self.sflowHeader = Entry(self.sflowFrame)
270
            self.sflowHeader.grid(row=2, column=1)
271
            self.sflowHeader.insert(0, sflowValues['sflowHeader'])
272

  
273
            Label(self.sflowFrame, text="Polling:").grid(row=3, sticky=E)
274
            self.sflowPolling = Entry(self.sflowFrame)
275
            self.sflowPolling.grid(row=3, column=1)
276
            self.sflowPolling.insert(0, sflowValues['sflowPolling'])
277

  
278
            # NetFlow
279
            nflowValues = self.prefValues['netflow']
280
            self.nFrame= LabelFrame(self.rightfieldFrame, text='NetFlow Profile for Open vSwitch', padx=5, pady=5)
281
            self.nFrame.grid(row=1, column=0, columnspan=2, sticky=EW)
282

  
283
            Label(self.nFrame, text="Target:").grid(row=0, sticky=E)
284
            self.nflowTarget = Entry(self.nFrame)
285
            self.nflowTarget.grid(row=0, column=1)
286
            self.nflowTarget.insert(0, nflowValues['nflowTarget'])
287

  
288
            Label(self.nFrame, text="Active Timeout:").grid(row=1, sticky=E)
289
            self.nflowTimeout = Entry(self.nFrame)
290
            self.nflowTimeout.grid(row=1, column=1)
291
            self.nflowTimeout.insert(0, nflowValues['nflowTimeout'])
292

  
293
            Label(self.nFrame, text="Add ID to Interface:").grid(row=2, sticky=E)
294
            self.nflowAddId = IntVar()
295
            self.nflowAddIdButton = Checkbutton(self.nFrame, variable=self.nflowAddId)
296
            self.nflowAddIdButton.grid(row=2, column=1, sticky=W)
297
            if nflowValues['nflowAddId'] == '0':
298
                self.nflowAddIdButton.deselect()
299
            else:
300
                self.nflowAddIdButton.select()
301

  
302
            # initial focus
303
            return self.ipEntry
304

  
305
        def apply(self):
306
            ipBase = self.ipEntry.get()
307
            terminalType = self.terminalVar.get()
308
            startCLI = str(self.cliStart.get())
309
            sw = self.switchType.get()
310
            dpctl = self.dpctlEntry.get()
311

  
312
            ovsOf10 = str(self.ovsOf10.get())
313
            ovsOf11 = str(self.ovsOf11.get())
314
            ovsOf12 = str(self.ovsOf12.get())
315
            ovsOf13 = str(self.ovsOf13.get())
316

  
317
            sflowValues = {'sflowTarget':self.sflowTarget.get(),
318
                           'sflowSampling':self.sflowSampling.get(),
319
                           'sflowHeader':self.sflowHeader.get(),
320
                           'sflowPolling':self.sflowPolling.get()}
321
            nflowvalues = {'nflowTarget':self.nflowTarget.get(),
322
                           'nflowTimeout':self.nflowTimeout.get(),
323
                           'nflowAddId':str(self.nflowAddId.get())}
324
            self.result = {'ipBase':ipBase,
325
                           'terminalType':terminalType,
326
                           'dpctl':dpctl,
327
                           'sflow':sflowValues,
328
                           'netflow':nflowvalues,
329
                           'startCLI':startCLI}
330
            if sw == 'Indigo Virtual Switch':
331
                self.result['switchType'] = 'ivs'
332
                if StrictVersion(MININET_VERSION) < StrictVersion('2.1'):
333
                    self.ovsOk = False
334
                    showerror(title="Error",
335
                              message='MiniNet version 2.1+ required. You have '+VERSION+'.')
336
            elif sw == 'Userspace Switch':
337
                self.result['switchType'] = 'user'
338
            elif sw == 'Userspace Switch inNamespace':
339
                self.result['switchType'] = 'userns'
340
            else:
341
                self.result['switchType'] = 'ovs'
342

  
343
            self.ovsOk = True
344
            if ovsOf11 == "1":
345
                ovsVer = self.getOvsVersion()
346
                if StrictVersion(ovsVer) < StrictVersion('2.0'):
347
                    self.ovsOk = False
348
                    showerror(title="Error",
349
                              message='Open vSwitch version 2.0+ required. You have '+ovsVer+'.')
350
            if ovsOf12 == "1" or ovsOf13 == "1":
351
                ovsVer = self.getOvsVersion()
352
                if StrictVersion(ovsVer) < StrictVersion('1.10'):
353
                    self.ovsOk = False
354
                    showerror(title="Error",
355
                              message='Open vSwitch version 1.10+ required. You have '+ovsVer+'.')
356

  
357
            if self.ovsOk:
358
                self.result['openFlowVersions']={'ovsOf10':ovsOf10,
359
                                                 'ovsOf11':ovsOf11,
360
                                                 'ovsOf12':ovsOf12,
361
                                                 'ovsOf13':ovsOf13}
362
            else:
363
                self.result = None
364

  
365
        def getOvsVersion(self):
366
            outp = quietRun("ovs-vsctl show")
367
            r = r'ovs_version: "(.*)"'
368
            m = re.search(r, outp)
369
            if m is None:
370
                print 'Version check failed'
371
                return None
372
            else:
373
                print 'Open vSwitch version is '+m.group(1)
374
                return m.group(1)
377
    def getOvsVersion(self):
378
        "Return OVS version"
379
        outp = quietRun("ovs-vsctl show")
380
        r = r'ovs_version: "(.*)"'
381
        m = re.search(r, outp)
382
        if m is None:
383
            print 'Version check failed'
384
            return None
385
        else:
386
            print 'Open vSwitch version is '+m.group(1)
387
            return m.group(1)
375 388

  
376 389

  
377 390
class CustomDialog(object):
378 391

  
379
        # TODO: Fix button placement and Title and window focus lock
380
        def __init__(self, master, title):
381
            self.top=Toplevel(master)
392
    # TODO: Fix button placement and Title and window focus lock
393
    def __init__(self, master, title):
394
        self.top=Toplevel(master)
382 395

  
383
            self.bodyFrame = Frame(self.top)
384
            self.bodyFrame.grid(row=0, column=0, sticky='nswe')
385
            self.body(self.bodyFrame)
396
        self.bodyFrame = Frame(self.top)
397
        self.bodyFrame.grid(row=0, column=0, sticky='nswe')
398
        self.body(self.bodyFrame)
386 399

  
387
            #return self.b # initial focus
388
            buttonFrame = Frame(self.top, relief='ridge', bd=3, bg='lightgrey')
389
            buttonFrame.grid(row=1 , column=0, sticky='nswe')
400
        #return self.b # initial focus
401
        buttonFrame = Frame(self.top, relief='ridge', bd=3, bg='lightgrey')
402
        buttonFrame.grid(row=1 , column=0, sticky='nswe')
390 403

  
391
            okButton = Button(buttonFrame, width=8, text='OK', relief='groove',
392
                       bd=4, command=self.okAction)
393
            okButton.grid(row=0, column=0, sticky=E)
404
        okButton = Button(buttonFrame, width=8, text='OK', relief='groove',
405
                   bd=4, command=self.okAction)
406
        okButton.grid(row=0, column=0, sticky=E)
394 407

  
395
            canlceButton = Button(buttonFrame, width=8, text='Cancel', relief='groove',
396
                        bd=4, command=self.cancelAction)
397
            canlceButton.grid(row=0, column=1, sticky=W)
408
        canlceButton = Button(buttonFrame, width=8, text='Cancel', relief='groove',
409
                    bd=4, command=self.cancelAction)
410
        canlceButton.grid(row=0, column=1, sticky=W)
398 411

  
399
        def body(self, master):
400
            self.rootFrame = master
412
    def body(self, master):
413
        self.rootFrame = master
401 414

  
402
        def apply(self):
403
            self.top.destroy()
415
    def apply(self):
416
        self.top.destroy()
404 417

  
405
        def cancelAction(self):
406
            self.top.destroy()
418
    def cancelAction(self):
419
        self.top.destroy()
407 420

  
408
        def okAction(self):
409
            self.apply()
410
            self.top.destroy()
421
    def okAction(self):
422
        self.apply()
423
        self.top.destroy()
411 424

  
412 425
class HostDialog(CustomDialog):
413 426

  
414
        def __init__(self, master, title, prefDefaults):
415

  
416
            self.prefValues = prefDefaults
417
            self.result = None
427
    def __init__(self, master, title, prefDefaults):
428

  
429
        self.prefValues = prefDefaults
430
        self.result = None
431

  
432
        CustomDialog.__init__(self, master, title)
433

  
434
    def body(self, master):
435
        self.rootFrame = master
436
        n = Notebook(self.rootFrame)
437
        self.propFrame = Frame(n)
438
        self.vlanFrame = Frame(n)
439
        self.interfaceFrame = Frame(n)
440
        self.mountFrame = Frame(n)
441
        n.add(self.propFrame, text='Properties')
442
        n.add(self.vlanFrame, text='VLAN Interfaces')
443
        n.add(self.interfaceFrame, text='External Interfaces')
444
        n.add(self.mountFrame, text='Private Directories')
445
        n.pack()
446

  
447
        ### TAB 1
448
        # Field for Hostname
449
        Label(self.propFrame, text="Hostname:").grid(row=0, sticky=E)
450
        self.hostnameEntry = Entry(self.propFrame)
451
        self.hostnameEntry.grid(row=0, column=1)
452
        if 'hostname' in self.prefValues:
453
            self.hostnameEntry.insert(0, self.prefValues['hostname'])
418 454

  
419
            CustomDialog.__init__(self, master, title)
420

  
421
        def body(self, master):
422
            self.rootFrame = master
423
            n = Notebook(self.rootFrame)
424
            self.propFrame = Frame(n)
425
            self.vlanFrame = Frame(n)
426
            self.interfaceFrame = Frame(n)
427
            self.mountFrame = Frame(n)
428
            n.add(self.propFrame, text='Properties')
429
            n.add(self.vlanFrame, text='VLAN Interfaces')
430
            n.add(self.interfaceFrame, text='External Interfaces')
431
            n.add(self.mountFrame, text='Private Directories')
432
            n.pack()
433

  
434
            ### TAB 1
435
            # Field for Hostname
436
            Label(self.propFrame, text="Hostname:").grid(row=0, sticky=E)
437
            self.hostnameEntry = Entry(self.propFrame)
438
            self.hostnameEntry.grid(row=0, column=1)
439
            if 'hostname' in self.prefValues:
440
                self.hostnameEntry.insert(0, self.prefValues['hostname'])
441

  
442
            # Field for Switch IP
443
            Label(self.propFrame, text="IP Address:").grid(row=1, sticky=E)
444
            self.ipEntry = Entry(self.propFrame)
445
            self.ipEntry.grid(row=1, column=1)
446
            if 'ip' in self.prefValues:
447
                self.ipEntry.insert(0, self.prefValues['ip'])
448

  
449
            # Field for default route
450
            Label(self.propFrame, text="Default Route:").grid(row=2, sticky=E)
451
            self.routeEntry = Entry(self.propFrame)
452
            self.routeEntry.grid(row=2, column=1)
453
            if 'defaultRoute' in self.prefValues:
454
                self.routeEntry.insert(0, self.prefValues['defaultRoute'])
455

  
456
            # Field for CPU
457
            Label(self.propFrame, text="Amount CPU:").grid(row=3, sticky=E)
458
            self.cpuEntry = Entry(self.propFrame)
459
            self.cpuEntry.grid(row=3, column=1)
460
            if 'cpu' in self.prefValues:
461
                self.cpuEntry.insert(0, str(self.prefValues['cpu']))
462
            # Selection of Scheduler
463
            if 'sched' in self.prefValues:
464
                sched =  self.prefValues['sched']
455
        # Field for Switch IP
456
        Label(self.propFrame, text="IP Address:").grid(row=1, sticky=E)
457
        self.ipEntry = Entry(self.propFrame)
458
        self.ipEntry.grid(row=1, column=1)
459
        if 'ip' in self.prefValues:
460
            self.ipEntry.insert(0, self.prefValues['ip'])
461

  
462
        # Field for default route
463
        Label(self.propFrame, text="Default Route:").grid(row=2, sticky=E)
464
        self.routeEntry = Entry(self.propFrame)
465
        self.routeEntry.grid(row=2, column=1)
466
        if 'defaultRoute' in self.prefValues:
467
            self.routeEntry.insert(0, self.prefValues['defaultRoute'])
468

  
469
        # Field for CPU
470
        Label(self.propFrame, text="Amount CPU:").grid(row=3, sticky=E)
471
        self.cpuEntry = Entry(self.propFrame)
472
        self.cpuEntry.grid(row=3, column=1)
473
        if 'cpu' in self.prefValues:
474
            self.cpuEntry.insert(0, str(self.prefValues['cpu']))
475
        # Selection of Scheduler
476
        if 'sched' in self.prefValues:
477
            sched =  self.prefValues['sched']
478
        else:
479
            sched = 'host'
480
        self.schedVar = StringVar(self.propFrame)
481
        self.schedOption = OptionMenu(self.propFrame, self.schedVar, "host", "cfs", "rt")
482
        self.schedOption.grid(row=3, column=2, sticky=W)
483
        self.schedVar.set(sched)
484

  
485
        # Selection of Cores
486
        Label(self.propFrame, text="Cores:").grid(row=4, sticky=E)
487
        self.coreEntry = Entry(self.propFrame)
488
        self.coreEntry.grid(row=4, column=1)
489
        if 'cores' in self.prefValues:
490
            self.coreEntry.insert(1, self.prefValues['cores'])
491

  
492
        # Start command
493
        Label(self.propFrame, text="Start Command:").grid(row=5, sticky=E)
494
        self.startEntry = Entry(self.propFrame)
495
        self.startEntry.grid(row=5, column=1, sticky='nswe', columnspan=3)
496
        if 'startCommand' in self.prefValues:
497
            self.startEntry.insert(0, str(self.prefValues['startCommand']))
498
        # Stop command
499
        Label(self.propFrame, text="Stop Command:").grid(row=6, sticky=E)
500
        self.stopEntry = Entry(self.propFrame)
501
        self.stopEntry.grid(row=6, column=1, sticky='nswe', columnspan=3)
502
        if 'stopCommand' in self.prefValues:
503
            self.stopEntry.insert(0, str(self.prefValues['stopCommand']))
504

  
505
        ### TAB 2
506
        # External Interfaces
507
        self.externalInterfaces = 0
508
        Label(self.interfaceFrame, text="External Interface:").grid(row=0, column=0, sticky=E)
509
        self.b = Button( self.interfaceFrame, text='Add', command=self.addInterface)
510
        self.b.grid(row=0, column=1)
511

  
512
        self.interfaceFrame = VerticalScrolledTable(self.interfaceFrame, rows=0, columns=1, title='External Interfaces')
513
        self.interfaceFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
514
        self.tableFrame = self.interfaceFrame.interior
515
        self.tableFrame.addRow(value=['Interface Name'], readonly=True)
516

  
517
        # Add defined interfaces
518
        externalInterfaces = []
519
        if 'externalInterfaces' in self.prefValues:
520
            externalInterfaces = self.prefValues['externalInterfaces']
521

  
522
        for externalInterface in externalInterfaces:
523
            self.tableFrame.addRow(value=[externalInterface])
524

  
525
        ### TAB 3
526
        # VLAN Interfaces
527
        self.vlanInterfaces = 0
528
        Label(self.vlanFrame, text="VLAN Interface:").grid(row=0, column=0, sticky=E)
529
        self.vlanButton = Button( self.vlanFrame, text='Add', command=self.addVlanInterface)
530
        self.vlanButton.grid(row=0, column=1)
531

  
532
        self.vlanFrame = VerticalScrolledTable(self.vlanFrame, rows=0, columns=2, title='VLAN Interfaces')
533
        self.vlanFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
534
        self.vlanTableFrame = self.vlanFrame.interior
535
        self.vlanTableFrame.addRow(value=['IP Address','VLAN ID'], readonly=True)
536

  
537
        vlanInterfaces = []
538
        if 'vlanInterfaces' in self.prefValues:
539
            vlanInterfaces = self.prefValues['vlanInterfaces']
540
        for vlanInterface in vlanInterfaces:
541
            self.vlanTableFrame.addRow(value=vlanInterface)
542

  
543
        ### TAB 4
544
        # Private Directories
545
        self.privateDirectories = 0
546
        Label(self.mountFrame, text="Private Directory:").grid(row=0, column=0, sticky=E)
547
        self.mountButton = Button( self.mountFrame, text='Add', command=self.addDirectory)
548
        self.mountButton.grid(row=0, column=1)
549

  
550
        self.mountFrame = VerticalScrolledTable(self.mountFrame, rows=0, columns=2, title='Directories')
551
        self.mountFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
552
        self.mountTableFrame = self.mountFrame.interior
553
        self.mountTableFrame.addRow(value=['Mount','Persistent Directory'], readonly=True)
554

  
555
        directoryList = []
556
        if 'privateDirectory' in self.prefValues:
557
            directoryList = self.prefValues['privateDirectory']
558
        for privateDir in directoryList:
559
            if isinstance( privateDir, tuple ):
560
                self.mountTableFrame.addRow(value=privateDir)
465 561
            else:
466
                sched = 'host'
467
            self.schedVar = StringVar(self.propFrame)
468
            self.schedOption = OptionMenu(self.propFrame, self.schedVar, "host", "cfs", "rt")
469
            self.schedOption.grid(row=3, column=2, sticky=W)
470
            self.schedVar.set(sched)
471

  
472
            # Selection of Cores
473
            Label(self.propFrame, text="Cores:").grid(row=4, sticky=E)
474
            self.coreEntry = Entry(self.propFrame)
475
            self.coreEntry.grid(row=4, column=1)
476
            if 'cores' in self.prefValues:
477
                self.coreEntry.insert(1, self.prefValues['cores'])
478

  
479
            # Start command
480
            Label(self.propFrame, text="Start Command:").grid(row=5, sticky=E)
481
            self.startEntry = Entry(self.propFrame)
482
            self.startEntry.grid(row=5, column=1, sticky='nswe', columnspan=3)
483
            if 'startCommand' in self.prefValues:
484
                self.startEntry.insert(0, str(self.prefValues['startCommand']))
485
            # Stop command
486
            Label(self.propFrame, text="Stop Command:").grid(row=6, sticky=E)
487
            self.stopEntry = Entry(self.propFrame)
488
            self.stopEntry.grid(row=6, column=1, sticky='nswe', columnspan=3)
489
            if 'stopCommand' in self.prefValues:
490
                self.stopEntry.insert(0, str(self.prefValues['stopCommand']))
491

  
492
            ### TAB 2
493
            # External Interfaces
494
            self.externalInterfaces = 0
495
            Label(self.interfaceFrame, text="External Interface:").grid(row=0, column=0, sticky=E)
496
            self.b = Button( self.interfaceFrame, text='Add', command=self.addInterface)
497
            self.b.grid(row=0, column=1)
498

  
499
            self.interfaceFrame = VerticalScrolledTable(self.interfaceFrame, rows=0, columns=1, title='External Interfaces')
500
            self.interfaceFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
501
            self.tableFrame = self.interfaceFrame.interior
502
            self.tableFrame.addRow(value=['Interface Name'], readonly=True)
503

  
504
            # Add defined interfaces
505
            externalInterfaces = []
506
            if 'externalInterfaces' in self.prefValues:
507
                externalInterfaces = self.prefValues['externalInterfaces']
508

  
509
            for externalInterface in externalInterfaces:
510
                self.tableFrame.addRow(value=[externalInterface])
511

  
512
            ### TAB 3
513
            # VLAN Interfaces
514
            self.vlanInterfaces = 0
515
            Label(self.vlanFrame, text="VLAN Interface:").grid(row=0, column=0, sticky=E)
516
            self.vlanButton = Button( self.vlanFrame, text='Add', command=self.addVlanInterface)
517
            self.vlanButton.grid(row=0, column=1)
518

  
519
            self.vlanFrame = VerticalScrolledTable(self.vlanFrame, rows=0, columns=2, title='VLAN Interfaces')
520
            self.vlanFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
521
            self.vlanTableFrame = self.vlanFrame.interior
522
            self.vlanTableFrame.addRow(value=['IP Address','VLAN ID'], readonly=True)
523

  
524
            vlanInterfaces = []
525
            if 'vlanInterfaces' in self.prefValues:
526
                vlanInterfaces = self.prefValues['vlanInterfaces']
527
            for vlanInterface in vlanInterfaces:
528
                self.vlanTableFrame.addRow(value=vlanInterface)
529

  
530
            ### TAB 4
531
            # Private Directories
532
            self.privateDirectories = 0
533
            Label(self.mountFrame, text="Private Directory:").grid(row=0, column=0, sticky=E)
534
            self.mountButton = Button( self.mountFrame, text='Add', command=self.addDirectory)
535
            self.mountButton.grid(row=0, column=1)
536

  
537
            self.mountFrame = VerticalScrolledTable(self.mountFrame, rows=0, columns=2, title='Directories')
538
            self.mountFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
539
            self.mountTableFrame = self.mountFrame.interior
540
            self.mountTableFrame.addRow(value=['Mount','Persistent Directory'], readonly=True)
541

  
542
            directoryList = []
543
            if 'privateDirectory' in self.prefValues:
544
                directoryList = self.prefValues['privateDirectory']
545
            for privateDir in directoryList:
546
                if isinstance( privateDir, tuple ):
547
                    self.mountTableFrame.addRow(value=privateDir)
562
                self.mountTableFrame.addRow(value=[privateDir,''])
563

  
564

  
565
    def addDirectory( self ):
566
        self.mountTableFrame.addRow()
567

  
568
    def addVlanInterface( self ):
569
        self.vlanTableFrame.addRow()
570

  
571
    def addInterface( self ):
572
        self.tableFrame.addRow()
573

  
574
    def apply(self):
575
        externalInterfaces = []
576
        for row in range(self.tableFrame.rows):
577
            if (len(self.tableFrame.get(row, 0)) > 0 and
578
                row > 0):
579
                externalInterfaces.append(self.tableFrame.get(row, 0))
580
        vlanInterfaces = []
581
        for row in range(self.vlanTableFrame.rows):
582
            if (len(self.vlanTableFrame.get(row, 0)) > 0 and
583
                len(self.vlanTableFrame.get(row, 1)) > 0 and
584
                row > 0):
585
                vlanInterfaces.append([self.vlanTableFrame.get(row, 0), self.vlanTableFrame.get(row, 1)])
586
        privateDirectories = []
587
        for row in range(self.mountTableFrame.rows):
588
            if len(self.mountTableFrame.get(row, 0)) > 0 and row > 0:
589
                if len(self.mountTableFrame.get(row, 1)) > 0:
590
                    privateDirectories.append((self.mountTableFrame.get(row, 0), self.mountTableFrame.get(row, 1)))
548 591
                else:
549
                    self.mountTableFrame.addRow(value=[privateDir,''])
550

  
551

  
552
        def addDirectory( self ):
553
            self.mountTableFrame.addRow()
554

  
555
        def addVlanInterface( self ):
556
            self.vlanTableFrame.addRow()
557

  
558
        def addInterface( self ):
559
            self.tableFrame.addRow()
560

  
561
        def apply(self):
562
            externalInterfaces = []
563
            for row in range(self.tableFrame.rows):
564
                if (len(self.tableFrame.get(row, 0)) > 0 and
565
                    row > 0):
566
                    externalInterfaces.append(self.tableFrame.get(row, 0))
567
            vlanInterfaces = []
568
            for row in range(self.vlanTableFrame.rows):
569
                if (len(self.vlanTableFrame.get(row, 0)) > 0 and
570
                    len(self.vlanTableFrame.get(row, 1)) > 0 and
571
                    row > 0):
572
                    vlanInterfaces.append([self.vlanTableFrame.get(row, 0), self.vlanTableFrame.get(row, 1)])
573
            privateDirectories = []
574
            for row in range(self.mountTableFrame.rows):
575
                if (len(self.mountTableFrame.get(row, 0)) > 0 and row > 0):
576
                    if(len(self.mountTableFrame.get(row, 1)) > 0):
577
                        privateDirectories.append((self.mountTableFrame.get(row, 0), self.mountTableFrame.get(row, 1)))
578
                    else:
579
                        privateDirectories.append(self.mountTableFrame.get(row, 0))
580

  
581
            results = {'cpu': self.cpuEntry.get(),
582
                       'cores':self.coreEntry.get(),
583
                       'sched':self.schedVar.get(),
584
                       'hostname':self.hostnameEntry.get(),
585
                       'ip':self.ipEntry.get(),
586
                       'defaultRoute':self.routeEntry.get(),
587
                       'startCommand':self.startEntry.get(),
588
                       'stopCommand':self.stopEntry.get(),
589
                       'privateDirectory':privateDirectories,
590
                       'externalInterfaces':externalInterfaces,
591
                       'vlanInterfaces':vlanInterfaces}
592
            self.result = results
592
                    privateDirectories.append(self.mountTableFrame.get(row, 0))
593

  
594
        results = {'cpu': self.cpuEntry.get(),
595
                   'cores':self.coreEntry.get(),
596
                   'sched':self.schedVar.get(),
597
                   'hostname':self.hostnameEntry.get(),
598
                   'ip':self.ipEntry.get(),
599
                   'defaultRoute':self.routeEntry.get(),
600
                   'startCommand':self.startEntry.get(),
601
                   'stopCommand':self.stopEntry.get(),
602
                   'privateDirectory':privateDirectories,
603
                   'externalInterfaces':externalInterfaces,
604
                   'vlanInterfaces':vlanInterfaces}
605
        self.result = results
593 606

  
594 607
class SwitchDialog(CustomDialog):
595 608

  
596
        def __init__(self, master, title, prefDefaults):
597

  
598
            self.prefValues = prefDefaults
599
            self.result = None
600
            CustomDialog.__init__(self, master, title)
601

  
602
        def body(self, master):
603
            self.rootFrame = master
604
            self.leftfieldFrame = Frame(self.rootFrame)
605
            self.rightfieldFrame = Frame(self.rootFrame)
606
            self.leftfieldFrame.grid(row=0, column=0, sticky='nswe')
607
            self.rightfieldFrame.grid(row=0, column=1, sticky='nswe')
608

  
609
            rowCount = 0
610
            externalInterfaces = []
611
            if 'externalInterfaces' in self.prefValues:
612
                externalInterfaces = self.prefValues['externalInterfaces']
613

  
614
            # Field for Hostname
615
            Label(self.leftfieldFrame, text="Hostname:").grid(row=rowCount, sticky=E)
616
            self.hostnameEntry = Entry(self.leftfieldFrame)
617
            self.hostnameEntry.grid(row=rowCount, column=1)
618
            self.hostnameEntry.insert(0, self.prefValues['hostname'])
619
            rowCount+=1
620

  
621
            # Field for DPID
622
            Label(self.leftfieldFrame, text="DPID:").grid(row=rowCount, sticky=E)
623
            self.dpidEntry = Entry(self.leftfieldFrame)
624
            self.dpidEntry.grid(row=rowCount, column=1)
625
            if 'dpid' in self.prefValues:
626
                self.dpidEntry.insert(0, self.prefValues['dpid'])
627
            rowCount+=1
628

  
629
            # Field for Netflow
630
            Label(self.leftfieldFrame, text="Enable NetFlow:").grid(row=rowCount, sticky=E)
631
            self.nflow = IntVar()
632
            self.nflowButton = Checkbutton(self.leftfieldFrame, variable=self.nflow)
633
            self.nflowButton.grid(row=rowCount, column=1, sticky=W)
634
            if 'netflow' in self.prefValues:
635
                if self.prefValues['netflow'] == '0':
636
                    self.nflowButton.deselect()
637
                else:
638
                    self.nflowButton.select()
639
            else:
609
    def __init__(self, master, title, prefDefaults):
610

  
611
        self.prefValues = prefDefaults
612
        self.result = None
613
        CustomDialog.__init__(self, master, title)
614

  
615
    def body(self, master):
616
        self.rootFrame = master
617
        self.leftfieldFrame = Frame(self.rootFrame)
618
        self.rightfieldFrame = Frame(self.rootFrame)
619
        self.leftfieldFrame.grid(row=0, column=0, sticky='nswe')
620
        self.rightfieldFrame.grid(row=0, column=1, sticky='nswe')
621

  
622
        rowCount = 0
623
        externalInterfaces = []
624
        if 'externalInterfaces' in self.prefValues:
625
            externalInterfaces = self.prefValues['externalInterfaces']
626

  
627
        # Field for Hostname
628
        Label(self.leftfieldFrame, text="Hostname:").grid(row=rowCount, sticky=E)
629
        self.hostnameEntry = Entry(self.leftfieldFrame)
630
        self.hostnameEntry.grid(row=rowCount, column=1)
631
        self.hostnameEntry.insert(0, self.prefValues['hostname'])
632
        rowCount+=1
633

  
634
        # Field for DPID
635
        Label(self.leftfieldFrame, text="DPID:").grid(row=rowCount, sticky=E)
636
        self.dpidEntry = Entry(self.leftfieldFrame)
637
        self.dpidEntry.grid(row=rowCount, column=1)
638
        if 'dpid' in self.prefValues:
639
            self.dpidEntry.insert(0, self.prefValues['dpid'])
640
        rowCount+=1
641

  
642
        # Field for Netflow
643
        Label(self.leftfieldFrame, text="Enable NetFlow:").grid(row=rowCount, sticky=E)
644
        self.nflow = IntVar()
645
        self.nflowButton = Checkbutton(self.leftfieldFrame, variable=self.nflow)
646
        self.nflowButton.grid(row=rowCount, column=1, sticky=W)
647
        if 'netflow' in self.prefValues:
648
            if self.prefValues['netflow'] == '0':
640 649
                self.nflowButton.deselect()
641
            rowCount+=1
642

  
643
            # Field for sflow
644
            Label(self.leftfieldFrame, text="Enable sFlow:").grid(row=rowCount, sticky=E)
645
            self.sflow = IntVar()
646
            self.sflowButton = Checkbutton(self.leftfieldFrame, variable=self.sflow)
647
            self.sflowButton.grid(row=rowCount, column=1, sticky=W)
648
            if 'sflow' in self.prefValues:
649
                if self.prefValues['sflow'] == '0':
650
                    self.sflowButton.deselect()
651
                else:
652
                    self.sflowButton.select()
653 650
            else:
651
                self.nflowButton.select()
652
        else:
653
            self.nflowButton.deselect()
654
        rowCount+=1
655

  
656
        # Field for sflow
657
        Label(self.leftfieldFrame, text="Enable sFlow:").grid(row=rowCount, sticky=E)
658
        self.sflow = IntVar()
659
        self.sflowButton = Checkbutton(self.leftfieldFrame, variable=self.sflow)
660
        self.sflowButton.grid(row=rowCount, column=1, sticky=W)
661
        if 'sflow' in self.prefValues:
662
            if self.prefValues['sflow'] == '0':
654 663
                self.sflowButton.deselect()
655
            rowCount+=1
656

  
657
            # Selection of switch type
658
            Label(self.leftfieldFrame, text="Switch Type:").grid(row=rowCount, sticky=E)
659
            self.switchType = StringVar(self.leftfieldFrame)
660
            self.switchTypeMenu = OptionMenu(self.leftfieldFrame, self.switchType, "Default", "Open vSwitch Kernel Mode", "Indigo Virtual Switch", "Userspace Switch", "Userspace Switch inNamespace")
661
            self.switchTypeMenu.grid(row=rowCount, column=1, sticky=W)
662
            if 'switchType' in self.prefValues:
663
                switchTypePref = self.prefValues['switchType']
664
                if switchTypePref == 'ivs':
665
                    self.switchType.set("Indigo Virtual Switch")
666
                elif switchTypePref == 'userns':
667
                    self.switchType.set("Userspace Switch inNamespace")
668
                elif switchTypePref == 'user':
669
                    self.switchType.set("Userspace Switch")
670
                elif switchTypePref == 'ovs':
671
                    self.switchType.set("Open vSwitch Kernel Mode")
672
                else:
673
                    self.switchType.set("Default")
664
            else:
665
                self.sflowButton.select()
666
        else:
667
            self.sflowButton.deselect()
668
        rowCount+=1
669

  
670
        # Selection of switch type
671
        Label(self.leftfieldFrame, text="Switch Type:").grid(row=rowCount, sticky=E)
672
        self.switchType = StringVar(self.leftfieldFrame)
673
        self.switchTypeMenu = OptionMenu(self.leftfieldFrame, self.switchType, "Default", "Open vSwitch Kernel Mode", "Indigo Virtual Switch", "Userspace Switch", "Userspace Switch inNamespace")
674
        self.switchTypeMenu.grid(row=rowCount, column=1, sticky=W)
675
        if 'switchType' in self.prefValues:
676
            switchTypePref = self.prefValues['switchType']
677
            if switchTypePref == 'ivs':
678
                self.switchType.set("Indigo Virtual Switch")
679
            elif switchTypePref == 'userns':
680
                self.switchType.set("Userspace Switch inNamespace")
681
            elif switchTypePref == 'user':
682
                self.switchType.set("Userspace Switch")
683
            elif switchTypePref == 'ovs':
684
                self.switchType.set("Open vSwitch Kernel Mode")
674 685
            else:
675 686
                self.switchType.set("Default")
676
            rowCount+=1
677

  
678
            # Field for Switch IP
679
            Label(self.leftfieldFrame, text="IP Address:").grid(row=rowCount, sticky=E)
680
            self.ipEntry = Entry(self.leftfieldFrame)
681
            self.ipEntry.grid(row=rowCount, column=1)
682
            if 'switchIP' in self.prefValues:
683
                self.ipEntry.insert(0, self.prefValues['switchIP'])
684
            rowCount+=1
685

  
686
            # Field for DPCTL port
687
            Label(self.leftfieldFrame, text="DPCTL port:").grid(row=rowCount, sticky=E)
688
            self.dpctlEntry = Entry(self.leftfieldFrame)
689
            self.dpctlEntry.grid(row=rowCount, column=1)
690
            if 'dpctl' in self.prefValues:
691
                self.dpctlEntry.insert(0, self.prefValues['dpctl'])
692
            rowCount+=1
693

  
694
            # External Interfaces
695
            Label(self.rightfieldFrame, text="External Interface:").grid(row=0, sticky=E)
696
            self.b = Button( self.rightfieldFrame, text='Add', command=self.addInterface)
697
            self.b.grid(row=0, column=1)
698

  
699
            self.interfaceFrame = VerticalScrolledTable(self.rightfieldFrame, rows=0, columns=1, title='External Interfaces')
700
            self.interfaceFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
701
            self.tableFrame = self.interfaceFrame.interior
702

  
703
            # Add defined interfaces
704
            for externalInterface in externalInterfaces:
705
                self.tableFrame.addRow(value=[externalInterface])
706

  
707
            self.commandFrame = Frame(self.rootFrame)
708
            self.commandFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
709
            self.commandFrame.columnconfigure(1, weight=1)
710
            # Start command
711
            Label(self.commandFrame, text="Start Command:").grid(row=0, column=0, sticky=W)
712
            self.startEntry = Entry(self.commandFrame)
713
            self.startEntry.grid(row=0, column=1,  sticky='nsew')
714
            if 'startCommand' in self.prefValues:
715
                self.startEntry.insert(0, str(self.prefValues['startCommand']))
716
            # Stop command
717
            Label(self.commandFrame, text="Stop Command:").grid(row=1, column=0, sticky=W)
718
            self.stopEntry = Entry(self.commandFrame)
719
            self.stopEntry.grid(row=1, column=1, sticky='nsew')
720
            if 'stopCommand' in self.prefValues:
721
                self.stopEntry.insert(0, str(self.prefValues['stopCommand']))
722

  
723
        def addInterface( self ):
724
            self.tableFrame.addRow()
725

  
726
        def defaultDpid( self ,name):
727
            "Derive dpid from switch name, s1 -> 1"
728
            try:
729
                dpid = int( re.findall( r'\d+', name )[ 0 ] )
730
                dpid = hex( dpid )[ 2: ]
731
                return dpid
732
            except IndexError:
733
                return None
734
                #raise Exception( 'Unable to derive default datapath ID - '
735
                #                 'please either specify a dpid or use a '
736
                #                 'canonical switch name such as s23.' )
737

  
738
        def apply(self):
739
            externalInterfaces = []
740
            for row in range(self.tableFrame.rows):
741
                #print 'Interface is ' + self.tableFrame.get(row, 0)
742
                if (len(self.tableFrame.get(row, 0)) > 0):
743
                    externalInterfaces.append(self.tableFrame.get(row, 0))
744

  
745
            dpid = self.dpidEntry.get()
746
            if (self.defaultDpid(self.hostnameEntry.get()) is None
747
               and len(dpid) == 0):
687
        else:
688
            self.switchType.set("Default")
689
        rowCount+=1
690

  
691
        # Field for Switch IP
692
        Label(self.leftfieldFrame, text="IP Address:").grid(row=rowCount, sticky=E)
693
        self.ipEntry = Entry(self.leftfieldFrame)
694
        self.ipEntry.grid(row=rowCount, column=1)
695
        if 'switchIP' in self.prefValues:
696
            self.ipEntry.insert(0, self.prefValues['switchIP'])
697
        rowCount+=1
698

  
699
        # Field for DPCTL port
700
        Label(self.leftfieldFrame, text="DPCTL port:").grid(row=rowCount, sticky=E)
701
        self.dpctlEntry = Entry(self.leftfieldFrame)
702
        self.dpctlEntry.grid(row=rowCount, column=1)
703
        if 'dpctl' in self.prefValues:
704
            self.dpctlEntry.insert(0, self.prefValues['dpctl'])
705
        rowCount+=1
706

  
707
        # External Interfaces
708
        Label(self.rightfieldFrame, text="External Interface:").grid(row=0, sticky=E)
709
        self.b = Button( self.rightfieldFrame, text='Add', command=self.addInterface)
710
        self.b.grid(row=0, column=1)
711

  
712
        self.interfaceFrame = VerticalScrolledTable(self.rightfieldFrame, rows=0, columns=1, title='External Interfaces')
713
        self.interfaceFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
714
        self.tableFrame = self.interfaceFrame.interior
715

  
716
        # Add defined interfaces
717
        for externalInterface in externalInterfaces:
718
            self.tableFrame.addRow(value=[externalInterface])
719

  
720
        self.commandFrame = Frame(self.rootFrame)
721
        self.commandFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
722
        self.commandFrame.columnconfigure(1, weight=1)
723
        # Start command
724
        Label(self.commandFrame, text="Start Command:").grid(row=0, column=0, sticky=W)
725
        self.startEntry = Entry(self.commandFrame)
726
        self.startEntry.grid(row=0, column=1,  sticky='nsew')
727
        if 'startCommand' in self.prefValues:
728
            self.startEntry.insert(0, str(self.prefValues['startCommand']))
729
        # Stop command
730
        Label(self.commandFrame, text="Stop Command:").grid(row=1, column=0, sticky=W)
731
        self.stopEntry = Entry(self.commandFrame)
732
        self.stopEntry.grid(row=1, column=1, sticky='nsew')
733
        if 'stopCommand' in self.prefValues:
734
            self.stopEntry.insert(0, str(self.prefValues['stopCommand']))
735

  
736
    def addInterface( self ):
737
        self.tableFrame.addRow()
738

  
739
    def defaultDpid( self ,name):
740
        "Derive dpid from switch name, s1 -> 1"
741
        try:
742
            dpid = int( re.findall( r'\d+', name )[ 0 ] )
743
            dpid = hex( dpid )[ 2: ]
744
            return dpid
745
        except IndexError:
746
            return None
747
            #raise Exception( 'Unable to derive default datapath ID - '
748
            #                 'please either specify a dpid or use a '
749
            #                 'canonical switch name such as s23.' )
750

  
751
    def apply(self):
752
        externalInterfaces = []
753
        for row in range(self.tableFrame.rows):
754
            #print 'Interface is ' + self.tableFrame.get(row, 0)
755
            if len(self.tableFrame.get(row, 0)) > 0:
756
                externalInterfaces.append(self.tableFrame.get(row, 0))
757

  
758
        dpid = self.dpidEntry.get()
759
        if (self.defaultDpid(self.hostnameEntry.get()) is None
760
           and len(dpid) == 0):
761
            showerror(title="Error",
762
                          message= 'Unable to derive default datapath ID - '
763
                             'please either specify a DPID or use a '
764
                             'canonical switch name such as s23.' )
765

  
766

  
767
        results = {'externalInterfaces':externalInterfaces,
768
                   'hostname':self.hostnameEntry.get(),
769
                   'dpid':dpid,
770
                   'startCommand':self.startEntry.get(),
771
                   'stopCommand':self.stopEntry.get(),
772
                   'sflow':str(self.sflow.get()),
773
                   'netflow':str(self.nflow.get()),
774
                   'dpctl':self.dpctlEntry.get(),
775
                   'switchIP':self.ipEntry.get()}
776
        sw = self.switchType.get()
777
        if sw == 'Indigo Virtual Switch':
778
            results['switchType'] = 'ivs'
779
            if StrictVersion(MININET_VERSION) < StrictVersion('2.1'):
780
                self.ovsOk = False
748 781
                showerror(title="Error",
749
                              message= 'Unable to derive default datapath ID - '
750
                                 'please either specify a DPID or use a '
751
                                 'canonical switch name such as s23.' )
752

  
753

  
754
            results = {'externalInterfaces':externalInterfaces,
755
                       'hostname':self.hostnameEntry.get(),
756
                       'dpid':dpid,
757
                       'startCommand':self.startEntry.get(),
758
                       'stopCommand':self.stopEntry.get(),
759
                       'sflow':str(self.sflow.get()),
760
                       'netflow':str(self.nflow.get()),
761
                       'dpctl':self.dpctlEntry.get(),
762
                       'switchIP':self.ipEntry.get()}
763
            sw = self.switchType.get()
764
            if sw == 'Indigo Virtual Switch':
765
                results['switchType'] = 'ivs'
766
                if StrictVersion(MININET_VERSION) < StrictVersion('2.1'):
767
                    self.ovsOk = False
768
                    showerror(title="Error",
769
                              message='MiniNet version 2.1+ required. You have '+VERSION+'.')
770
            elif sw == 'Userspace Switch inNamespace':
771
                results['switchType'] = 'userns'
772
            elif sw == 'Userspace Switch':
773
                results['switchType'] = 'user'
774
            elif sw == 'Open vSwitch Kernel Mode':
775
                results['switchType'] = 'ovs'
776
            else:
777
                results['switchType'] = 'default'
778
            self.result = results
782
                          message='MiniNet version 2.1+ required. You have '+VERSION+'.')
783
        elif sw == 'Userspace Switch inNamespace':
784
            results['switchType'] = 'userns'
785
        elif sw == 'Userspace Switch':
786
            results['switchType'] = 'user'
787
        elif sw == 'Open vSwitch Kernel Mode':
788
            results['switchType'] = 'ovs'
789
        else:
790
            results['switchType'] = 'default'
791
        self.result = results
779 792

  
780 793

  
781 794
class VerticalScrolledTable(LabelFrame):
......
809 822
        # track changes to the canvas and frame width and sync them,
810 823
        # also updating the scrollbar
811 824
        def _configure_interior(event):
812
            # update the scrollbars to match the size of the inner frame
825
        # update the scrollbars to match the size of the inner frame
813 826
            size = (interior.winfo_reqwidth(), interior.winfo_reqheight())
814 827
            canvas.config(scrollregion="0 0 %s %s" % size)
815 828
            if interior.winfo_reqwidth() != canvas.winfo_width():
816
                # update the canvas's width to fit the inner frame
829
            # update the canvas's width to fit the inner frame
817 830
                canvas.config(width=interior.winfo_reqwidth())
818 831
        interior.bind('<Configure>', _configure_interior)
819 832

  
......
856 869
            label.grid(row=self.rows, column=column, sticky="wens", padx=1, pady=1)
857 870
            if value is not None:
858 871
                label.insert(0, value[column])
859
            if (readonly == True):
872
            if readonly == True:
860 873
                label.configure(state='readonly')
861 874
            current_row.append(label)
862 875
        self._widgets.append(current_row)
......
865 878

  
866 879
class LinkDialog(tkSimpleDialog.Dialog):
867 880

  
868
        def __init__(self, parent, title, linkDefaults):
869

  
870
            self.linkValues = linkDefaults
871

  
872
            tkSimpleDialog.Dialog.__init__(self, parent, title)
873

  
874
        def body(self, master):
875

  
876
            self.var = StringVar(master)
877
            Label(master, text="Bandwidth:").grid(row=0, sticky=E)
878
            self.e1 = Entry(master)
879
            self.e1.grid(row=0, column=1)
880
            Label(master, text="Mbit").grid(row=0, column=2, sticky=W)
881
            if 'bw' in self.linkValues:
882
                self.e1.insert(0,str(self.linkValues['bw']))
883

  
884
            Label(master, text="Delay:").grid(row=1, sticky=E)
885
            self.e2 = Entry(master)
886
            self.e2.grid(row=1, column=1)
887
            if 'delay' in self.linkValues:
888
                self.e2.insert(0, self.linkValues['delay'])
889

  
890
            Label(master, text="Loss:").grid(row=2, sticky=E)
891
            self.e3 = Entry(master)
892
            self.e3.grid(row=2, column=1)
893
            Label(master, text="%").grid(row=2, column=2, sticky=W)
894
            if 'loss' in self.linkValues:
895
                self.e3.insert(0, str(self.linkValues['loss']))
896

  
897
            Label(master, text="Max Queue size:").grid(row=3, sticky=E)
898
            self.e4 = Entry(master)
899
            self.e4.grid(row=3, column=1)
900
            if 'max_queue_size' in self.linkValues:
901
                self.e4.insert(0, str(self.linkValues['max_queue_size']))
902

  
903
            Label(master, text="Jitter:").grid(row=4, sticky=E)
904
            self.e5 = Entry(master)
905
            self.e5.grid(row=4, column=1)
906
            if 'jitter' in self.linkValues:
907
                self.e5.insert(0, self.linkValues['jitter'])
908

  
909
            Label(master, text="Speedup:").grid(row=5, sticky=E)
910
            self.e6 = Entry(master)
911
            self.e6.grid(row=5, column=1)
912
            if 'speedup' in self.linkValues:
913
                self.e6.insert(0, str(self.linkValues['speedup']))
914

  
915
            return self.e1 # initial focus
916

  
917
        def apply(self):
918
            self.result = {}
919
            if (len(self.e1.get()) > 0):
920
                self.result['bw'] = int(self.e1.get())
921
            if (len(self.e2.get()) > 0):
922
                self.result['delay'] = self.e2.get()
923
            if (len(self.e3.get()) > 0):
924
                self.result['loss'] = int(self.e3.get())
925
            if (len(self.e4.get()) > 0):
926
                self.result['max_queue_size'] = int(self.e4.get())
927
            if (len(self.e5.get()) > 0):
928
                self.result['jitter'] = self.e5.get()
929
            if (len(self.e6.get()) > 0):
930
                self.result['speedup'] = int(self.e6.get())
881
    def __init__(self, parent, title, linkDefaults):
882

  
883
        self.linkValues = linkDefaults
884

  
885
        tkSimpleDialog.Dialog.__init__(self, parent, title)
886

  
887
    def body(self, master):
888

  
889
        self.var = StringVar(master)
890
        Label(master, text="Bandwidth:").grid(row=0, sticky=E)
891
        self.e1 = Entry(master)
892
        self.e1.grid(row=0, column=1)
893
        Label(master, text="Mbit").grid(row=0, column=2, sticky=W)
894
        if 'bw' in self.linkValues:
895
            self.e1.insert(0,str(self.linkValues['bw']))
896

  
897
        Label(master, text="Delay:").grid(row=1, sticky=E)
898
        self.e2 = Entry(master)
899
        self.e2.grid(row=1, column=1)
900
        if 'delay' in self.linkValues:
901
            self.e2.insert(0, self.linkValues['delay'])
902

  
903
        Label(master, text="Loss:").grid(row=2, sticky=E)
904
        self.e3 = Entry(master)
905
        self.e3.grid(row=2, column=1)
906
        Label(master, text="%").grid(row=2, column=2, sticky=W)
907
        if 'loss' in self.linkValues:
908
            self.e3.insert(0, str(self.linkValues['loss']))
909

  
910
        Label(master, text="Max Queue size:").grid(row=3, sticky=E)
911
        self.e4 = Entry(master)
912
        self.e4.grid(row=3, column=1)
913
        if 'max_queue_size' in self.linkValues:
914
            self.e4.insert(0, str(self.linkValues['max_queue_size']))
915

  
916
        Label(master, text="Jitter:").grid(row=4, sticky=E)
917
        self.e5 = Entry(master)
918
        self.e5.grid(row=4, column=1)
919
        if 'jitter' in self.linkValues:
920
            self.e5.insert(0, self.linkValues['jitter'])
921

  
922
        Label(master, text="Speedup:").grid(row=5, sticky=E)
923
        self.e6 = Entry(master)
924
        self.e6.grid(row=5, column=1)
925
        if 'speedup' in self.linkValues:
926
            self.e6.insert(0, str(self.linkValues['speedup']))
927

  
928
        return self.e1 # initial focus
929

  
930
    def apply(self):
931
        self.result = {}
932
        if len(self.e1.get()) > 0:
933
            self.result['bw'] = int(self.e1.get())
934
        if len(self.e2.get()) > 0:
935
            self.result['delay'] = self.e2.get()
936
        if len(self.e3.get()) > 0:
937
            self.result['loss'] = int(self.e3.get())
938
        if len(self.e4.get()) > 0:
939
            self.result['max_queue_size'] = int(self.e4.get())
940
        if len(self.e5.get()) > 0:
941
            self.result['jitter'] = self.e5.get()
942
        if len(self.e6.get()) > 0:
943
            self.result['speedup'] = int(self.e6.get())
931 944

  
932 945
class ControllerDialog(tkSimpleDialog.Dialog):
933 946

  
934
        def __init__(self, parent, title, ctrlrDefaults=None):
935

  
936
            if ctrlrDefaults:
937
                self.ctrlrValues = ctrlrDefaults
938

  
939
            tkSimpleDialog.Dialog.__init__(self, parent, title)
940

  
941
        def body(self, master):
942

  
943
            self.var = StringVar(master)
944
            self.protcolvar = StringVar(master)
945

  
946
            rowCount=0
947
            # Field for Hostname
948
            Label(master, text="Name:").grid(row=rowCount, sticky=E)
949
            self.hostnameEntry = Entry(master)
950
            self.hostnameEntry.grid(row=rowCount, column=1)
951
            self.hostnameEntry.insert(0, self.ctrlrValues['hostname'])
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff