ixnetwork 8.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/ixnetwork.rb +561 -0
  3. metadata +45 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: adde78c14d852066ec75676b526c404d570c4b3a
4
+ data.tar.gz: f3161d251261b82b6522c2a9c96670e8257af72b
5
+ SHA512:
6
+ metadata.gz: d19f8a25bd8e78cf4a3da6f0f65a2b0231e373c0f3ba3d48193d25a5cafc999f922a2ebe3a49e6d8f05ddc58ac5c6a0e7c9c93748fd8814054940bbcebcb498e
7
+ data.tar.gz: 7fe15ef418ad4e109f257305e53225c95b77e9e57f4070f2f9e38ab95f94b16fc363a84b512f4b525aa3598299d2536c20c93897167c002eed64526347f0a04f
data/lib/ixnetwork.rb ADDED
@@ -0,0 +1,561 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # IxNetwork API Bindings
4
+ #
5
+ # Copyright © 1997 - 2017 by IXIA
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"),
9
+ # to deal in the Software without restriction, including without limitation
10
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
+ # and/or sell copies of the Software, and to permit persons to whom the
12
+ # Software is furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in
15
+ # all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ # THE SOFTWARE.
24
+
25
+ require 'socket'
26
+ require 'etc'
27
+ require 'pathname'
28
+
29
+ class IxNetError < StandardError
30
+ #"""Default IxNet error"""
31
+ end
32
+
33
+ class IxNetwork
34
+ def initialize()
35
+ @_root = '::ixNet::OBJ-/'
36
+ @_null = '::ixNet::OBJ-null'
37
+ @_socket = nil
38
+ @_proxySocket = nil
39
+ @_connectTokens = ''
40
+ @_evalError = '1'
41
+ @_evalSuccess = '0'
42
+ @_evalResult = '0'
43
+ @_addContentSeparator = 0
44
+ @_firstItem = true
45
+ @_sendContent = Array.new
46
+ @_buffer = false
47
+ @_sendBuffer = Array.new
48
+ @_decoratedResult = Array.new
49
+ @_filename = nil
50
+ @_debug = false
51
+ @_async = false
52
+ @_timeout = nil
53
+ @_OK = '::ixNet::OK'
54
+ @_version = '8.40.1124.8'
55
+ end
56
+
57
+ def setDebug(debug)
58
+ @_debug = debug
59
+ return self
60
+ end
61
+
62
+ def getRoot()
63
+ return @_root
64
+ end
65
+
66
+ def getNull()
67
+ return @_null
68
+ end
69
+
70
+ def setAsync()
71
+ @_async = true;
72
+ return self
73
+ end
74
+
75
+ def setTimeout(timeout)
76
+ @_timeout = timeout
77
+ return self
78
+ end
79
+
80
+ def __initialConnect(address, port, options)
81
+ # make an initial socket connection
82
+ # this will keep trying as it could be connecting to the proxy
83
+ # which may not have an available application instance at that time
84
+ attempts = 0
85
+ while true
86
+ begin
87
+ sd = Socket.getaddrinfo(address,Socket::SOCK_STREAM,Socket::AF_INET)
88
+ @_socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
89
+ @_socket.connect(Socket.pack_sockaddr_in(port, sd[0][2]))
90
+ break
91
+ rescue SocketError => e
92
+ if @_proxySocket != nil and attempts < 120 then
93
+ time.sleep(2)
94
+ attempts += 1
95
+ else
96
+ self.__Close()
97
+ raise IxNetError,e.to_s + e.backtrace.to_s
98
+ end
99
+ end
100
+ end
101
+
102
+ # a socket connection has been made now read the type of connection
103
+ # setup to timeout if the remote endpoint is not valid
104
+ optval = [30, 0].pack("l_2")
105
+ @_socket.setsockopt Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, optval
106
+ read, write, error = select([@_socket], [], [], 30)
107
+ if read.length == 0 and write.length == 0 and error.length == 0 then
108
+ self.__Close()
109
+ raise IxNetError,'Connection handshake timed out after 30 seconds'
110
+ end
111
+ optval = [0, 0].pack("l_2")
112
+ @_socket.setsockopt Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, optval
113
+
114
+ # process the results from the endpoint
115
+ connectString = self.__Recv()
116
+ if connectString == 'proxy' then
117
+ @_socket.send(options,0)
118
+ @_connectTokens = self.__Recv().to_s
119
+ connectTokensArray = @_connectTokens.split()
120
+ connectTokens = Hash[connectTokensArray.values_at(* connectTokensArray.each_index.select {|i| i.even?}).zip \
121
+ connectTokensArray.values_at(* connectTokensArray.each_index.select {|i| i.odd?})]
122
+ @_proxySocket = @_socket
123
+ @_socket = nil
124
+ self.__initialConnect(address, connectTokens['-port'], '')
125
+ end
126
+ end
127
+
128
+ def connect(address, *args)
129
+ begin
130
+ if @_socket != nil then
131
+ self.__SendRecv('ixNet', 'help')
132
+ end
133
+ rescue
134
+ self.__Close()
135
+ end
136
+
137
+ begin
138
+ nameValuePairs = {}
139
+ name = nil
140
+ for arg in args
141
+ if arg.to_s.start_with?('-') then
142
+ if name.nil? then
143
+ name = arg.to_s
144
+ else
145
+ nameValuePairs[name] = ''
146
+ end
147
+ elsif !name.nil?
148
+ nameValuePairs[name] = arg.to_s
149
+ name = nil
150
+ end
151
+ end
152
+ if not nameValuePairs.include?('-port') then
153
+ nameValuePairs['-port'] = 8009
154
+ end
155
+
156
+ options = '-clientusername ' + Etc.getlogin
157
+ if nameValuePairs.include?('-serverusername') then
158
+ options += ' -serverusername ' + nameValuePairs['-serverusername']
159
+ end
160
+ if nameValuePairs.include?('-connectTimeout') then
161
+ options += ' -connectTimeout ' + nameValuePairs['-connectTimeout']
162
+ end
163
+ if nameValuePairs.include?('-closeServerOnDisconnect') then
164
+ options += ' -closeServerOnDisconnect ' + nameValuePairs[-closeServerOnDisconnect]
165
+ else
166
+ options += ' -closeServerOnDisconnect true'
167
+ end
168
+
169
+ if @_socket.nil? then
170
+ self.__initialConnect(address, nameValuePairs['-port'].to_i, options)
171
+ conRes = self.__SendRecv('ixNet', 'connect', address,'-clientType', 'ruby', *args)
172
+ self._CheckClientVersion()
173
+ return conRes
174
+ else
175
+ sockInfo = @_socket.getpeername()
176
+ return "Cannot connect to #{address}:#{nameValuePairs['-port']} as a connection is already established to #{sockInfo[0]}:#{sockInfo[1]}. Please execute disconnect before trying this command again."
177
+ end
178
+ rescue SocketError => e
179
+ self.__Close()
180
+ raise IxNetError,"Unable to connect to host:"+address.to_s+" port:"+nameValuePairs['-port'].to_s+". Error:"+e.to_s
181
+ end
182
+ end
183
+
184
+ def disconnect()
185
+ response = self.__SendRecv('ixNet', 'disconnect')
186
+ self.__Close()
187
+ return response
188
+ end
189
+
190
+ def help(*args)
191
+ return self.__SendRecv('ixNet', 'help', *args)
192
+ end
193
+
194
+ def setSessionParameter(*args)
195
+ if args.length % 2 == 0 then
196
+ return self.__SendRecv('ixNet', 'setSessionParameter', *args)
197
+ else
198
+ raise IxNetError,"setSessionParameter requires an even number of name/value pairs"
199
+ end
200
+ end
201
+
202
+ def getVersion()
203
+ if @_socket.nil? then
204
+ return @_version
205
+ else
206
+ return self.__SendRecv('ixNet', 'getVersion')
207
+ end
208
+ end
209
+
210
+ def getParent(objRef)
211
+ return self.__SendRecv('ixNet', 'getParent', objRef)
212
+ end
213
+
214
+ def exists(objRef)
215
+ return self.__SendRecv('ixNet', 'exists', self.__CheckObjRef(objRef))
216
+ end
217
+
218
+ def commit()
219
+ return self.__SendRecv('ixNet', 'commit')
220
+ end
221
+
222
+ def rollback()
223
+ return self.__SendRecv('ixNet', 'rollback')
224
+ end
225
+
226
+ def execute(*args)
227
+ return self.__SendRecv('ixNet', 'exec', *args)
228
+ end
229
+
230
+ def add(objRef, child, *args)
231
+ return self.__SendRecv('ixNet', 'add', self.__CheckObjRef(objRef), child, *args)
232
+ end
233
+
234
+ def remove(objRef)
235
+ return self.__SendRecv('ixNet', 'remove', objRef)
236
+ end
237
+
238
+ def setAttribute(objRef, name, value)
239
+ @_buffer = true
240
+ return self.__SendRecv('ixNet', 'setAttribute', self.__CheckObjRef(objRef), name, value)
241
+ end
242
+
243
+ def setMultiAttribute(objRef, *args)
244
+ @_buffer = true
245
+ return self.__SendRecv('ixNet', 'setMultiAttribute', self.__CheckObjRef(objRef), *args)
246
+ end
247
+
248
+ def getAttribute(objRef, name)
249
+ return self.__SendRecv('ixNet', 'getAttribute', self.__CheckObjRef(objRef), name)
250
+ end
251
+
252
+ def getList(objRef, child)
253
+ return self.__SendRecv('ixNet', 'getList', self.__CheckObjRef(objRef), child)
254
+ end
255
+
256
+ def getFilteredList(objRef, child, name, value)
257
+ return self.__SendRecv('ixNet', 'getFilteredList', self.__CheckObjRef(objRef), child, name, value)
258
+ end
259
+
260
+ def adjustIndexes(objRef, object)
261
+ return self.__SendRecv('ixNet', 'adjustIndexes', self.__CheckObjRef(objRef), object)
262
+ end
263
+
264
+ def remapIds(localIdList)
265
+ #if type(localIdList) is tuple then
266
+ # localIdList = list(localIdList)
267
+ #end
268
+ return self.__SendRecv('ixNet', 'remapIds', localIdList)
269
+ end
270
+
271
+ def getResult(resultId)
272
+ return self.__SendRecv('ixNet', 'getResult', resultId)
273
+ end
274
+
275
+ def wait(resultId)
276
+ return self.__SendRecv('ixNet', 'wait', resultId)
277
+ end
278
+
279
+ def isDone(resultId)
280
+ return self.__SendRecv('ixNet', 'isDone', resultId)
281
+ end
282
+
283
+ def isSuccess(resultId)
284
+ return self.__SendRecv('ixNet', 'isSuccess', resultId)
285
+ end
286
+
287
+ def writeTo(filename, *args)
288
+ if args.any? { |word| '-ixNetRelative'.include?(word)} then
289
+ return self.__SendRecv('ixNet', 'writeTo', filename,args.join("\02"))
290
+ else
291
+ return self.__CreateFileOnServer(filename)
292
+ end
293
+ end
294
+
295
+ def readFrom(filename, *args)
296
+ if args.any? { |word| '-ixNetRelative'.include?(word)} then
297
+ return self.__SendRecv('ixNet', 'readFrom', filename,args.join("\02"))
298
+ else
299
+ return self.__PutFileOnServer(filename)
300
+ end
301
+ end
302
+
303
+ def __CheckObjRef(objRef)
304
+ if (objRef.is_a? String) == false then
305
+ raise IxNetError,'The objRef parameter must be String instead of ' + objRef.class.to_s
306
+ else
307
+ return objRef
308
+ end
309
+ end
310
+
311
+ def __PutFileOnServer(filename)
312
+ truncatedFilename = Pathname.new(filename).basename
313
+ fid = File.open(filename, 'rb')
314
+ self.__Send("<001><005><007%s>%s<009%s>" % [filename.length, filename,File.size(filename)])
315
+ self.__SendBinary(fid.read())
316
+ fid.close()
317
+ remoteFilename = self.__Recv()
318
+
319
+ return self.__SendRecv('ixNet', 'readFrom', remoteFilename,'-ixNetRelative')
320
+ end
321
+
322
+ def __CreateFileOnServer(filename)
323
+ self.__Send("<001><006><007%s>%s<009>" % [filename.length, filename])
324
+ remoteFilename = self.__Recv()
325
+ return self.__SendRecv('ixNet', 'writeTo', remoteFilename,'-ixNetRelative', '-overwrite')
326
+ end
327
+
328
+ def __Close()
329
+ begin
330
+ if @_socket then
331
+ @_socket.close()
332
+ end
333
+ rescue
334
+ # clear exceptions
335
+ end
336
+ begin
337
+ if @_proxySocket then
338
+ @_proxySocket.close()
339
+ end
340
+ rescue
341
+ # clear exceptions
342
+ end
343
+ @_socket = nil
344
+ @_proxySocket = nil
345
+ end
346
+
347
+ def __Join(*args)
348
+ for arg in args
349
+ if arg.class == Array then
350
+ if @_addContentSeparator == 0 then
351
+ @_sendContent.push("\02")
352
+ end
353
+ if @_addContentSeparator > 0 then
354
+ @_sendContent.push('{')
355
+ end
356
+ @_addContentSeparator += 1
357
+ @_firstItem = true
358
+ if arg.length == 0 then
359
+ @_sendContent.push('{}')
360
+ else
361
+ for item in arg
362
+ self.__Join(item)
363
+ end
364
+ end
365
+ if @_addContentSeparator > 1 then
366
+ @_sendContent.push('}')
367
+ end
368
+ @_addContentSeparator -= 1
369
+ else
370
+ if @_addContentSeparator == 0 and @_sendContent.length > 0 then
371
+ @_sendContent.push("\02")
372
+ elsif @_addContentSeparator > 0
373
+ if @_firstItem == false then
374
+ @_sendContent.push(' ')
375
+ else
376
+ @_firstItem = false
377
+ end
378
+ end
379
+ if arg.nil? then
380
+ arg = ''
381
+ elsif !(arg.is_a? String)
382
+ arg = arg.to_s
383
+ end
384
+ if arg.length == 0 and @_sendContent.length > 0 then
385
+ @_sendContent.push('{}')
386
+ elsif arg.include?(' ') and @_addContentSeparator > 0
387
+ @_sendContent.push('{'+arg+'}')
388
+ else
389
+ @_sendContent.push(arg)
390
+ end
391
+ end
392
+ end
393
+ return
394
+ end
395
+
396
+ def __SendRecv(*args)
397
+ if @_socket.nil? then
398
+ raise IxNetError,'not connected'
399
+ end
400
+
401
+ @_addContentSeparator = 0
402
+ @_firstItem = true
403
+
404
+ argList = args
405
+
406
+ if @_async then
407
+ argList.insert(1, '-async')
408
+ end
409
+
410
+ if !@_timeout.nil? then
411
+ argList.insert(1, '-timeout')
412
+ argList.insert(2, @_timeout)
413
+ end
414
+
415
+ for item in argList
416
+ self.__Join(item)
417
+ end
418
+
419
+ @_sendContent.push("\03")
420
+ @_sendBuffer.push(@_sendContent.join(''));
421
+ if @_buffer == false then
422
+ buffer = @_sendBuffer.join('')
423
+ if @_debug then
424
+ puts "Sending: " + buffer
425
+ end
426
+ self.__Send("<001><002><009%s>%s" % [buffer.length,buffer])
427
+ @_sendBuffer = Array.new
428
+ end
429
+
430
+ @_async = false
431
+ @_timeout = nil
432
+ @_buffer = false
433
+ @_sendContent = Array.new
434
+
435
+ if @_sendBuffer.length > 0 then
436
+ return @_OK
437
+ else
438
+ return self.__Recv()
439
+ end
440
+ end
441
+
442
+ def __Send(content)
443
+ if @_socket.nil? then
444
+ raise IxNetError,'not connected'
445
+ else
446
+ begin
447
+ if content.is_a? String then
448
+ content = content
449
+ end
450
+ @_socket.send(content,0)
451
+ rescue SocketError => e
452
+ self.__Close()
453
+ raise IxNetError,"Error:"+e
454
+ end
455
+ end
456
+ end
457
+
458
+ def __SendBinary(content)
459
+ if @_socket.nil? then
460
+ raise IxNetError,"not connected"
461
+ else
462
+ begin
463
+ @_socket.send(content,0)
464
+ rescue SocketError => e
465
+ self.__Close()
466
+ raise IxNetError,"Error:"+e
467
+ end
468
+ end
469
+ end
470
+
471
+ def __Recv()
472
+ @_decoratedResult = Array.new
473
+ responseBuffer = ''
474
+ begin
475
+ while true
476
+ responseBuffer = ''
477
+ commandId = nil
478
+ contentLength = 0
479
+
480
+ while true
481
+ responseBuffer += @_socket.recv(1)
482
+ startIndex = responseBuffer.index('<')
483
+ stopIndex = responseBuffer.index('>')
484
+ if !startIndex.nil? and !stopIndex.nil? then
485
+ @si = startIndex + 1
486
+ @ei = startIndex + 3
487
+ commandId = responseBuffer[@si..@ei].to_i
488
+ if (startIndex + 4) < stopIndex then
489
+ @si = startIndex + 4
490
+ @ei = stopIndex
491
+ contentLength = responseBuffer[@si..@ei].to_i
492
+ end
493
+ break
494
+ end
495
+ end
496
+ if commandId == 1 then
497
+ @_evalResult = @_evalError
498
+ @_socket.recv(contentLength)
499
+ elsif commandId == 3
500
+ @_socket.recv(contentLength)
501
+ elsif commandId == 4
502
+ @_evalResult = @_socket.recv(contentLength)
503
+ elsif commandId == 7
504
+ @_filename = @_socket.recv(contentLength)
505
+ elsif commandId == 8
506
+ binaryFile = open(@_filename, 'w+b')
507
+ chunk = ''
508
+ bytesToRead = 32767
509
+ while contentLength > 0
510
+ if contentLength < bytesToRead then
511
+ bytesToRead = contentLength
512
+ end
513
+ chunk = @_socket.recv(bytesToRead)
514
+ binaryFile.write(chunk)
515
+ contentLength -= chunk.length
516
+ end
517
+ binaryFile.close()
518
+ elsif commandId == 9
519
+ @_decoratedResult = Array.new
520
+ chunk = ''
521
+ bytesToRead = 32767
522
+ while contentLength > 0
523
+ if contentLength < bytesToRead then
524
+ bytesToRead = contentLength
525
+ end
526
+ chunk = @_socket.recv(bytesToRead)
527
+ @_decoratedResult.push(chunk)
528
+ contentLength -= chunk.length
529
+ end
530
+ break
531
+ end
532
+ end
533
+
534
+ rescue SocketError => e
535
+ self.__Close()
536
+ raise IxNetError,"Recv failed. Error:"+e.to_s
537
+ end
538
+
539
+ if @_debug then
540
+ puts "Received: " + @_decoratedResult.join('')
541
+ end
542
+
543
+ if @_evalResult == @_evalError then
544
+ raise IxNetError,@_decoratedResult.join('')
545
+ end
546
+
547
+ if @_decoratedResult.length > 0 and @_decoratedResult[0].start_with?("\01") then
548
+ @_decoratedResult[0] = @_decoratedResult[0].sub("\01", '')
549
+ return eval(@_decoratedResult.join(""))
550
+ else
551
+ return @_decoratedResult.join("")
552
+ end
553
+ end
554
+
555
+ def _CheckClientVersion ()
556
+ if @_version != self.getVersion() then
557
+ puts "WARNING: IxNetwork Ruby library version " + @_version + " is not matching the IxNetwork client version " + self.getVersion()
558
+ end
559
+ end
560
+
561
+ end
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ixnetwork
3
+ version: !ruby/object:Gem::Version
4
+ version: 8.40.0
5
+ platform: ruby
6
+ authors:
7
+ - Mircea-Dan Gheorghe
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-12-22 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: "\tixnetwork is the Ruby library for the IxNetwork Low Level API that
14
+ allows you to configure and run IxNetwork tests.\n"
15
+ email: mircea-dan.gheorghe@keysight.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/ixnetwork.rb
21
+ homepage: https://github.com/ixiacom/ixnetwork-api-rb/
22
+ licenses:
23
+ - MIT
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.9.3
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 2.5.1
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: IxNetwork Low Level API
45
+ test_files: []