Collection of GNS3 GUI Tools
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
3.7KB

  1. #!/usr/local/bin/python3
  2. """
  3. paste.py - send list of commands one by one to the node
  4. """
  5. import os
  6. import sys
  7. import telnetlib
  8. import gns3api
  9. def get_console(argv):
  10. """ parse command line and retrieve console host and port """
  11. # get arguments
  12. if len(argv) < 4:
  13. sys.exit("usage:\npaste version parameter-file project-id [sel-item ...]")
  14. try:
  15. with open(argv[2], "r") as file:
  16. cntl_url, cntl_user, cntl_passwd, *_ = file.read(512).splitlines()
  17. if argv[2].endswith(".tmp"):
  18. os.remove(argv[2])
  19. except (OSError, ValueError) as err:
  20. sys.exit("Can't get controller connection params: {}".format(err))
  21. project_id = argv[3]
  22. sel_nodes = [node[6:] for node in argv[4:] if node.startswith("nodes/")]
  23. if not sel_nodes:
  24. sys.exit("No node selected")
  25. elif len(sel_nodes) != 1:
  26. sys.exit("Select only one node")
  27. node_id = sel_nodes[0]
  28. # connect to GNS3 controller
  29. try:
  30. api = gns3api.GNS3Api(cntl_url, cntl_user, cntl_passwd)
  31. except gns3api.GNS3ApiException as err:
  32. sys.exit("Can't connect to GNS3 controller: {}".format(err))
  33. try:
  34. node = api.request('GET', ('/v2/projects', project_id, 'nodes', node_id))
  35. node_name = node['name']
  36. if node['status'] != 'started':
  37. sys.exit("Node '{}' is {}".format(node_name, node['status']))
  38. console_port = node['console']
  39. if not console_port:
  40. sys.exit("Node '{}' doesn't use the console".format(node_name))
  41. console_host = node['console_host']
  42. if console_host in ('0.0.0.0', '::'):
  43. compute = api.request('GET', ('/v2/computes', node['compute_id']))
  44. console_host = compute['host']
  45. except gns3api.GNS3ApiException as err:
  46. sys.exit("Can't get node information: {}".format(err))
  47. return (node_name, console_host, console_port)
  48. def send_commands(node_name, console_host, console_port):
  49. """ read commands from stdin and send them to the node """
  50. stdin_bin = sys.stdin.buffer
  51. stdout_bin = sys.stdout.buffer
  52. prompt = b'[>#] ?$'
  53. status = "???"
  54. try:
  55. # open telnet connection
  56. status = "connect"
  57. telnet = telnetlib.Telnet(console_host, console_port, 10)
  58. # read old junk
  59. while telnet.read_until(b'xyzzy', timeout=0.3):
  60. pass
  61. # send a <CR>
  62. status = "first contact"
  63. telnet.write(b'\r') # first <return>
  64. try:
  65. telnet.expect([prompt], 5)
  66. except OSError:
  67. pass
  68. telnet.write(b'\r') # second <return>
  69. (_, _, data) = telnet.expect([prompt], 5)
  70. data = data.splitlines()[-1]
  71. # get commands
  72. status = "getting commands"
  73. print("Paste commands, end with EOF...")
  74. commands = stdin_bin.readlines()
  75. print('')
  76. # send commands
  77. status = "sending commands"
  78. stdout_bin.write(data)
  79. stdout_bin.flush()
  80. for line in commands:
  81. line = line.rstrip(b'\r\n')
  82. while True:
  83. data = telnet.read_until(b'xyzzy', timeout=0.2)
  84. if not data:
  85. break
  86. stdout_bin.write(data)
  87. stdout_bin.flush()
  88. telnet.write(line + b'\r')
  89. (_, _, data) = telnet.expect([prompt], 5)
  90. stdout_bin.write(data)
  91. stdout_bin.flush()
  92. # close connection
  93. status = "close"
  94. telnet.close()
  95. print('')
  96. except OSError as err:
  97. sys.exit("\n{}: I/O error during {} - {}\n".format(node_name, status, err))
  98. except KeyboardInterrupt:
  99. telnet.close()
  100. sys.exit("\n{}: Aborted\n".format(node_name))
  101. if __name__ == "__main__":
  102. send_commands(*get_console(sys.argv))