summaryrefslogtreecommitdiffstats
path: root/scripts/automation/trex_control_plane
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/automation/trex_control_plane')
-rw-r--r--scripts/automation/trex_control_plane/client/trex_stateless_client.py58
-rw-r--r--scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py12
-rw-r--r--scripts/automation/trex_control_plane/client_utils/outer_packages.py4
-rw-r--r--scripts/automation/trex_control_plane/client_utils/packet_builder.py11
-rwxr-xr-xscripts/automation/trex_control_plane/examples/client_interactive_example.py1
-rw-r--r--scripts/automation/trex_control_plane/examples/interactive_stateless.py128
-rwxr-xr-xscripts/automation/trex_control_plane/server/extended_daemon_runner.py2
7 files changed, 207 insertions, 9 deletions
diff --git a/scripts/automation/trex_control_plane/client/trex_stateless_client.py b/scripts/automation/trex_control_plane/client/trex_stateless_client.py
new file mode 100644
index 00000000..670eda1d
--- /dev/null
+++ b/scripts/automation/trex_control_plane/client/trex_stateless_client.py
@@ -0,0 +1,58 @@
+#!/router/bin/python
+
+try:
+ # support import for Python 2
+ import outer_packages
+except ImportError:
+ # support import for Python 3
+ import client.outer_packages
+from client_utils.jsonrpc_client import JsonRpcClient
+
+
+
+class CTRexStatelessClient(object):
+ """docstring for CTRexStatelessClient"""
+ def __init__(self, server="localhost", port=5050, virtual=False):
+ super(CTRexStatelessClient, self).__init__()
+ self.tx_link = CTRexStatelessClient.CTxLink(server, port, virtual)
+
+
+ def transmit(self, method_name, params = {}):
+ return self.tx_link.transmit(method_name, params)
+
+
+
+ class CTxLink(object):
+ """describes the connectivity of the stateless client method"""
+ def __init__(self, server="localhost", port=5050, virtual=False):
+ super(CTRexStatelessClient.CTxLink, self).__init__()
+ self.virtual = virtual
+ self.server = server
+ self.port = port
+ self.rpc_link = JsonRpcClient(self.server, self.port)
+ if not self.virtual:
+ self.rpc_link.connect()
+
+ def transmit(self, method_name, params = {}):
+ if self.virtual:
+ print "Transmitting virtually over tcp://{server}:{port}".format(
+ server=self.server,
+ port=self.port)
+ id, msg = self.rpc_link.create_jsonrpc_v2(method_name, params)
+ print msg
+ return
+ else:
+ return self.rpc_link.invoke_rpc_method(method_name, params)
+
+
+
+
+
+class CTRexVM(object):
+ """docstring for CTRexVM"""
+ def __init__(self, arg):
+ super(CTRexVM, self).__init__()
+ self.arg = arg
+
+if __name__ == "__main__":
+ pass
diff --git a/scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py b/scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py
index 1631c494..89ac9127 100644
--- a/scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py
+++ b/scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py
@@ -34,16 +34,16 @@ class JsonRpcClient(object):
print "[verbose] " + msg
- def create_jsonrpc_v2 (self, method_name, params = {}, id = None):
+ def create_jsonrpc_v2 (self, method_name, params = {}):
msg = {}
msg["jsonrpc"] = "2.0"
msg["method"] = method_name
msg["params"] = params
- msg["id"] = id
+ msg["id"] = self.id_gen.next()
- return json.dumps(msg)
+ return id, json.dumps(msg)
def invoke_rpc_method (self, method_name, params = {}, block = False):
rc, msg = self._invoke_rpc_method(method_name, params, block)
@@ -56,8 +56,7 @@ class JsonRpcClient(object):
if not self.connected:
return False, "Not connected to server"
- id = self.id_gen.next()
- msg = self.create_jsonrpc_v2(method_name, params, id = id)
+ id, msg = self.create_jsonrpc_v2(method_name, params)
self.verbose_msg("Sending Request To Server:\n\n" + self.pretty_json(msg) + "\n")
@@ -180,7 +179,8 @@ class JsonRpcClient(object):
def __del__(self):
print "Shutting down RPC client\n"
- self.context.destroy(linger=0)
+ if hasattr(self, "context"):
+ self.context.destroy(linger=0)
if __name__ == "__main__":
pass
diff --git a/scripts/automation/trex_control_plane/client_utils/outer_packages.py b/scripts/automation/trex_control_plane/client_utils/outer_packages.py
index c489fd3d..3ba73ec1 100644
--- a/scripts/automation/trex_control_plane/client_utils/outer_packages.py
+++ b/scripts/automation/trex_control_plane/client_utils/outer_packages.py
@@ -8,7 +8,9 @@ CURRENT_PATH = os.path.dirname(os.path.realpath(__file__))
ROOT_PATH = os.path.abspath(os.path.join(CURRENT_PATH, os.pardir)) # path to trex_control_plane directory
PATH_TO_PYTHON_LIB = os.path.abspath(os.path.join(ROOT_PATH, os.pardir, os.pardir, 'external_libs'))
-CLIENT_UTILS_MODULES = ['zmq']
+CLIENT_UTILS_MODULES = ['zmq',
+ 'dpkt-1.8.6.2'
+ ]
def import_client_utils_modules():
diff --git a/scripts/automation/trex_control_plane/client_utils/packet_builder.py b/scripts/automation/trex_control_plane/client_utils/packet_builder.py
new file mode 100644
index 00000000..c33444a7
--- /dev/null
+++ b/scripts/automation/trex_control_plane/client_utils/packet_builder.py
@@ -0,0 +1,11 @@
+#!/router/bin/python
+
+
+import outer_packages
+import dpkt
+
+class CTRexPktBuilder(object):
+ """docstring for CTRexPktBuilder"""
+ def __init__(self, arg):
+ super(CTRexPktBuilder, self).__init__()
+ self.arg = arg \ No newline at end of file
diff --git a/scripts/automation/trex_control_plane/examples/client_interactive_example.py b/scripts/automation/trex_control_plane/examples/client_interactive_example.py
index 10735221..05028463 100755
--- a/scripts/automation/trex_control_plane/examples/client_interactive_example.py
+++ b/scripts/automation/trex_control_plane/examples/client_interactive_example.py
@@ -13,7 +13,6 @@ import time
import socket
import errno
-
class InteractiveTRexClient(cmd.Cmd):
intro = termstyle.green("\nInteractive shell to play with Cisco's T-Rex API.\nType help to view available pre-defined scenarios\n(c) All rights reserved.\n")
diff --git a/scripts/automation/trex_control_plane/examples/interactive_stateless.py b/scripts/automation/trex_control_plane/examples/interactive_stateless.py
new file mode 100644
index 00000000..016888d2
--- /dev/null
+++ b/scripts/automation/trex_control_plane/examples/interactive_stateless.py
@@ -0,0 +1,128 @@
+#!/router/bin/python
+
+import trex_root_path
+from client.trex_stateless_client import *
+from common.trex_exceptions import *
+import cmd
+from termstyle import termstyle
+# import termstyle
+import os
+from argparse import ArgumentParser
+import socket
+import errno
+import ast
+import json
+
+
+class InteractiveStatelessTRex(cmd.Cmd):
+
+ intro = termstyle.green("\nInteractive shell to play with Cisco's TRex stateless API.\
+ \nType help to view available pre-defined scenarios\n(c) All rights reserved.\n")
+ prompt = '> '
+
+ def __init__(self, trex_host, trex_port, virtual, verbose):
+ cmd.Cmd.__init__(self)
+
+ self.verbose = verbose
+ self.virtual = virtual
+ self.trex = CTRexStatelessClient(trex_host, trex_port, self.virtual)
+ self.DEFAULT_RUN_PARAMS = dict(m=1.5,
+ nc=True,
+ p=True,
+ d=100,
+ f='avl/sfr_delay_10_1g.yaml',
+ l=1000)
+ self.run_params = dict(self.DEFAULT_RUN_PARAMS)
+
+ def do_transmit(self, line):
+ """Transmits a request over using a given link to server.\
+ \nuse: transmit [method_name] [method_params]"""
+ if line == "":
+ print "\nUsage: [method name] [param dict as string]\n"
+ print "Example: rpc test_add {'x': 12, 'y': 17}\n"
+ return
+
+ args = line.split(' ', 1) # args will have max length of 2
+ method_name = args[0]
+ params = None
+ bad_parse = False
+
+ try:
+ params = ast.literal_eval(args[1])
+ if not isinstance(params, dict):
+ bad_parse = True
+ except ValueError as e1:
+ bad_parse = True
+ except SyntaxError as e2:
+ bad_parse = True
+
+ if bad_parse:
+ print "\nValue should be a valid dict: '{0}'".format(args[1])
+ print "\nUsage: [method name] [param dict as string]\n"
+ print "Example: rpc test_add {'x': 12, 'y': 17}\n"
+ return
+
+ response = self.trex.transmit(method_name, params)
+ if not self.virtual:
+ # expect response
+ rc, msg = response
+ if rc:
+ print "\nServer Response:\n\n" + json.dumps(msg) + "\n"
+ else:
+ print "\n*** " + msg + "\n"
+
+
+
+
+
+ def do_push_files(self, filepaths):
+ """Pushes a custom file to be stored locally on T-Rex server.\
+ \nPush multiple files by specifying their path separated by ' ' (space)."""
+ try:
+ filepaths = filepaths.split(' ')
+ print termstyle.green("*** Starting pushing files ({trex_files}) to T-Rex. ***".format(
+ trex_files=', '.join(filepaths))
+ )
+ ret_val = self.trex.push_files(filepaths)
+ if ret_val:
+ print termstyle.green("*** End of T-Rex push_files method (success) ***")
+ else:
+ print termstyle.magenta("*** End of T-Rex push_files method (failed) ***")
+
+ except IOError as inst:
+ print termstyle.magenta(inst)
+
+if __name__ == "__main__":
+ parser = ArgumentParser(description=termstyle.cyan('Run T-Rex client API demos and scenarios.'),
+ usage="client_interactive_example [options]")
+
+ parser.add_argument('-v', '--version', action='version', version='%(prog)s 1.0 \t (C) Cisco Systems Inc.\n')
+
+ parser.add_argument("-t", "--trex-host", required = True, dest="trex_host",
+ action="store", help="Specify the hostname or ip to connect with T-Rex server.",
+ metavar="HOST" )
+ parser.add_argument("-p", "--trex-port", type=int, default = 8090, metavar="PORT", dest="trex_port",
+ help="Select port on which the T-Rex server listens. Default port is 8090.", action="store")
+ # parser.add_argument("-m", "--maxhist", type=int, default = 100, metavar="SIZE", dest="hist_size",
+ # help="Specify maximum history size saved at client side. Default size is 100.", action="store")
+ parser.add_argument("--virtual", dest="virtual",
+ action="store_true",
+ help="Switch ON virtual option at TRex client. Default is: OFF.",
+ default=False)
+ parser.add_argument("--verbose", dest="verbose",
+ action="store_true",
+ help="Switch ON verbose option at TRex client. Default is: OFF.",
+ default=False)
+ args = parser.parse_args()
+
+ try:
+ InteractiveStatelessTRex(**vars(args)).cmdloop()
+
+ except KeyboardInterrupt:
+ print termstyle.cyan('Bye Bye!')
+ exit(-1)
+ except socket.error, e:
+ if e.errno == errno.ECONNREFUSED:
+ raise socket.error(errno.ECONNREFUSED,
+ "Connection from T-Rex server was terminated. \
+ Please make sure the server is up.")
diff --git a/scripts/automation/trex_control_plane/server/extended_daemon_runner.py b/scripts/automation/trex_control_plane/server/extended_daemon_runner.py
index 2ce1eb06..1813ed48 100755
--- a/scripts/automation/trex_control_plane/server/extended_daemon_runner.py
+++ b/scripts/automation/trex_control_plane/server/extended_daemon_runner.py
@@ -35,7 +35,7 @@ class ExtendedDaemonRunner(runner.DaemonRunner):
help_menu = """Specify action command to be applied on server.
(*) start : start the application in as a daemon process.
- (*) show : prompt a updated status of daemon process (running/ not running).
+ (*) show : prompt an updated status of daemon process (running/ not running).
(*) stop : exit the daemon process.
(*) restart : stop, then start again the application as daemon process
(*) start-live : start the application in live mode (no daemon process).