mirror of
https://github.com/GNS3/gns3-server
synced 2025-02-16 10:02:01 +00:00
PEP 8 clean thanks to auto pep8
This commit is contained in:
parent
7f185663d1
commit
f5ed9fbcf1
@ -103,7 +103,7 @@ def main():
|
|||||||
instance.change_password(passwd)
|
instance.change_password(passwd)
|
||||||
# wait for the password change to be processed. Continuing while
|
# wait for the password change to be processed. Continuing while
|
||||||
# a password change is processing will cause image creation to fail.
|
# a password change is processing will cause image creation to fail.
|
||||||
sleep(POLL_SEC*6)
|
sleep(POLL_SEC * 6)
|
||||||
|
|
||||||
env.host_string = str(instance.accessIPv4)
|
env.host_string = str(instance.accessIPv4)
|
||||||
env.user = "root"
|
env.user = "root"
|
||||||
|
@ -103,9 +103,9 @@ pygments_style = 'sphinx'
|
|||||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||||
# a list of builtin themes.
|
# a list of builtin themes.
|
||||||
html_theme = 'default'
|
html_theme = 'default'
|
||||||
#html_theme = 'nature'
|
# html_theme = 'nature'
|
||||||
|
|
||||||
#If uncommented it's turn off the default read the doc style
|
# If uncommented it's turn off the default read the doc style
|
||||||
html_style = "/default.css"
|
html_style = "/default.css"
|
||||||
|
|
||||||
# Theme options are theme-specific and customize the look and feel of a theme
|
# Theme options are theme-specific and customize the look and feel of a theme
|
||||||
|
@ -175,7 +175,6 @@ class BaseCloudCtrl(object):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.error("list_instances returned an error: {}".format(e))
|
log.error("list_instances returned an error: {}".format(e))
|
||||||
|
|
||||||
|
|
||||||
def create_key_pair(self, name):
|
def create_key_pair(self, name):
|
||||||
""" Create and return a new Key Pair. """
|
""" Create and return a new Key Pair. """
|
||||||
|
|
||||||
|
@ -1,45 +1,67 @@
|
|||||||
""" Exception classes for CloudCtrl classes. """
|
""" Exception classes for CloudCtrl classes. """
|
||||||
|
|
||||||
|
|
||||||
class ApiError(Exception):
|
class ApiError(Exception):
|
||||||
|
|
||||||
""" Raised when the server returns 500 Compute Error. """
|
""" Raised when the server returns 500 Compute Error. """
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BadRequest(Exception):
|
class BadRequest(Exception):
|
||||||
|
|
||||||
""" Raised when the server returns 400 Bad Request. """
|
""" Raised when the server returns 400 Bad Request. """
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ComputeFault(Exception):
|
class ComputeFault(Exception):
|
||||||
|
|
||||||
""" Raised when the server returns 400|500 Compute Fault. """
|
""" Raised when the server returns 400|500 Compute Fault. """
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Forbidden(Exception):
|
class Forbidden(Exception):
|
||||||
|
|
||||||
""" Raised when the server returns 403 Forbidden. """
|
""" Raised when the server returns 403 Forbidden. """
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ItemNotFound(Exception):
|
class ItemNotFound(Exception):
|
||||||
|
|
||||||
""" Raised when the server returns 404 Not Found. """
|
""" Raised when the server returns 404 Not Found. """
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class KeyPairExists(Exception):
|
class KeyPairExists(Exception):
|
||||||
|
|
||||||
""" Raised when the server returns 409 Conflict Key pair exists. """
|
""" Raised when the server returns 409 Conflict Key pair exists. """
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class MethodNotAllowed(Exception):
|
class MethodNotAllowed(Exception):
|
||||||
|
|
||||||
""" Raised when the server returns 405 Method Not Allowed. """
|
""" Raised when the server returns 405 Method Not Allowed. """
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class OverLimit(Exception):
|
class OverLimit(Exception):
|
||||||
|
|
||||||
""" Raised when the server returns 413 Over Limit. """
|
""" Raised when the server returns 413 Over Limit. """
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ServerCapacityUnavailable(Exception):
|
class ServerCapacityUnavailable(Exception):
|
||||||
|
|
||||||
""" Raised when the server returns 503 Server Capacity Uavailable. """
|
""" Raised when the server returns 503 Server Capacity Uavailable. """
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ServiceUnavailable(Exception):
|
class ServiceUnavailable(Exception):
|
||||||
|
|
||||||
""" Raised when the server returns 503 Service Unavailable. """
|
""" Raised when the server returns 503 Service Unavailable. """
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Unauthorized(Exception):
|
class Unauthorized(Exception):
|
||||||
|
|
||||||
""" Raised when the server returns 401 Unauthorized. """
|
""" Raised when the server returns 401 Unauthorized. """
|
||||||
pass
|
pass
|
||||||
|
@ -41,7 +41,7 @@ from os.path import expanduser
|
|||||||
|
|
||||||
SCRIPT_NAME = os.path.basename(__file__)
|
SCRIPT_NAME = os.path.basename(__file__)
|
||||||
|
|
||||||
#Is the full path when used as an import
|
# Is the full path when used as an import
|
||||||
SCRIPT_PATH = os.path.dirname(__file__)
|
SCRIPT_PATH = os.path.dirname(__file__)
|
||||||
|
|
||||||
if not SCRIPT_PATH:
|
if not SCRIPT_PATH:
|
||||||
@ -98,6 +98,8 @@ Options:
|
|||||||
""" % (SCRIPT_NAME)
|
""" % (SCRIPT_NAME)
|
||||||
|
|
||||||
# Parse cmd line options
|
# Parse cmd line options
|
||||||
|
|
||||||
|
|
||||||
def parse_cmd_line(argv):
|
def parse_cmd_line(argv):
|
||||||
"""
|
"""
|
||||||
Parse command line arguments
|
Parse command line arguments
|
||||||
@ -107,22 +109,22 @@ def parse_cmd_line(argv):
|
|||||||
|
|
||||||
short_args = "dvhk"
|
short_args = "dvhk"
|
||||||
long_args = ("debug",
|
long_args = ("debug",
|
||||||
"verbose",
|
"verbose",
|
||||||
"help",
|
"help",
|
||||||
"cloud_user_name=",
|
"cloud_user_name=",
|
||||||
"cloud_api_key=",
|
"cloud_api_key=",
|
||||||
"instance_id=",
|
"instance_id=",
|
||||||
"region=",
|
"region=",
|
||||||
"dead_time=",
|
"dead_time=",
|
||||||
"init-wait=",
|
"init-wait=",
|
||||||
"check-interval=",
|
"check-interval=",
|
||||||
"file=",
|
"file=",
|
||||||
"background",
|
"background",
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
opts, extra_opts = getopt.getopt(argv[1:], short_args, long_args)
|
opts, extra_opts = getopt.getopt(argv[1:], short_args, long_args)
|
||||||
except getopt.GetoptError as e:
|
except getopt.GetoptError as e:
|
||||||
print("Unrecognized command line option or missing required argument: %s" %(e))
|
print("Unrecognized command line option or missing required argument: %s" % (e))
|
||||||
print(usage)
|
print(usage)
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
@ -133,7 +135,7 @@ def parse_cmd_line(argv):
|
|||||||
cmd_line_option_list["cloud_api_key"] = None
|
cmd_line_option_list["cloud_api_key"] = None
|
||||||
cmd_line_option_list["instance_id"] = None
|
cmd_line_option_list["instance_id"] = None
|
||||||
cmd_line_option_list["region"] = None
|
cmd_line_option_list["region"] = None
|
||||||
cmd_line_option_list["dead_time"] = 60 * 60 #minutes
|
cmd_line_option_list["dead_time"] = 60 * 60 # minutes
|
||||||
cmd_line_option_list["check-interval"] = None
|
cmd_line_option_list["check-interval"] = None
|
||||||
cmd_line_option_list["init-wait"] = 5 * 60
|
cmd_line_option_list["init-wait"] = 5 * 60
|
||||||
cmd_line_option_list["file"] = None
|
cmd_line_option_list["file"] = None
|
||||||
@ -146,8 +148,7 @@ def parse_cmd_line(argv):
|
|||||||
elif sys.platform == "osx":
|
elif sys.platform == "osx":
|
||||||
cmd_line_option_list['syslog'] = "/var/run/syslog"
|
cmd_line_option_list['syslog'] = "/var/run/syslog"
|
||||||
else:
|
else:
|
||||||
cmd_line_option_list['syslog'] = ('localhost',514)
|
cmd_line_option_list['syslog'] = ('localhost', 514)
|
||||||
|
|
||||||
|
|
||||||
get_gns3secrets(cmd_line_option_list)
|
get_gns3secrets(cmd_line_option_list)
|
||||||
cmd_line_option_list["dead_time"] = int(cmd_line_option_list["dead_time"])
|
cmd_line_option_list["dead_time"] = int(cmd_line_option_list["dead_time"])
|
||||||
@ -181,7 +182,7 @@ def parse_cmd_line(argv):
|
|||||||
elif (opt in ("--background")):
|
elif (opt in ("--background")):
|
||||||
cmd_line_option_list["daemon"] = True
|
cmd_line_option_list["daemon"] = True
|
||||||
|
|
||||||
if cmd_line_option_list["shutdown"] == False:
|
if cmd_line_option_list["shutdown"] is False:
|
||||||
|
|
||||||
if cmd_line_option_list["check-interval"] is None:
|
if cmd_line_option_list["check-interval"] is None:
|
||||||
cmd_line_option_list["check-interval"] = cmd_line_option_list["dead_time"] + 120
|
cmd_line_option_list["check-interval"] = cmd_line_option_list["dead_time"] + 120
|
||||||
@ -211,9 +212,9 @@ def parse_cmd_line(argv):
|
|||||||
print(usage)
|
print(usage)
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
|
|
||||||
return cmd_line_option_list
|
return cmd_line_option_list
|
||||||
|
|
||||||
|
|
||||||
def get_gns3secrets(cmd_line_option_list):
|
def get_gns3secrets(cmd_line_option_list):
|
||||||
"""
|
"""
|
||||||
Load cloud credentials from .gns3secrets
|
Load cloud credentials from .gns3secrets
|
||||||
@ -248,10 +249,10 @@ def set_logging(cmd_options):
|
|||||||
log_level = logging.INFO
|
log_level = logging.INFO
|
||||||
log_level_console = logging.WARNING
|
log_level_console = logging.WARNING
|
||||||
|
|
||||||
if cmd_options['verbose'] == True:
|
if cmd_options['verbose']:
|
||||||
log_level_console = logging.INFO
|
log_level_console = logging.INFO
|
||||||
|
|
||||||
if cmd_options['debug'] == True:
|
if cmd_options['debug']:
|
||||||
log_level_console = logging.DEBUG
|
log_level_console = logging.DEBUG
|
||||||
log_level = logging.DEBUG
|
log_level = logging.DEBUG
|
||||||
|
|
||||||
@ -275,6 +276,7 @@ def set_logging(cmd_options):
|
|||||||
|
|
||||||
return log
|
return log
|
||||||
|
|
||||||
|
|
||||||
def send_shutdown(pid_file):
|
def send_shutdown(pid_file):
|
||||||
"""
|
"""
|
||||||
Sends the daemon process a kill signal
|
Sends the daemon process a kill signal
|
||||||
@ -291,8 +293,9 @@ def send_shutdown(pid_file):
|
|||||||
|
|
||||||
def _get_file_age(filename):
|
def _get_file_age(filename):
|
||||||
return datetime.datetime.fromtimestamp(
|
return datetime.datetime.fromtimestamp(
|
||||||
os.path.getmtime(filename)
|
os.path.getmtime(filename)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def monitor_loop(options):
|
def monitor_loop(options):
|
||||||
"""
|
"""
|
||||||
@ -307,7 +310,7 @@ def monitor_loop(options):
|
|||||||
|
|
||||||
terminate_attempts = 0
|
terminate_attempts = 0
|
||||||
|
|
||||||
while options['shutdown'] == False:
|
while options['shutdown'] is False:
|
||||||
log.debug("In monitor_loop for : %s" % (
|
log.debug("In monitor_loop for : %s" % (
|
||||||
datetime.datetime.now() - options['starttime'])
|
datetime.datetime.now() - options['starttime'])
|
||||||
)
|
)
|
||||||
@ -320,15 +323,15 @@ def monitor_loop(options):
|
|||||||
|
|
||||||
if delta.seconds > options["dead_time"]:
|
if delta.seconds > options["dead_time"]:
|
||||||
log.warning("Dead time exceeded, terminating instance ...")
|
log.warning("Dead time exceeded, terminating instance ...")
|
||||||
#Terminate involves many layers of HTTP / API calls, lots of
|
# Terminate involves many layers of HTTP / API calls, lots of
|
||||||
#different errors types could occur here.
|
# different errors types could occur here.
|
||||||
try:
|
try:
|
||||||
rksp = Rackspace(options)
|
rksp = Rackspace(options)
|
||||||
rksp.terminate()
|
rksp.terminate()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.critical("Exception during terminate: %s" % (e))
|
log.critical("Exception during terminate: %s" % (e))
|
||||||
|
|
||||||
terminate_attempts+=1
|
terminate_attempts += 1
|
||||||
log.warning("Termination sent, attempt: %s" % (terminate_attempts))
|
log.warning("Termination sent, attempt: %s" % (terminate_attempts))
|
||||||
time.sleep(600)
|
time.sleep(600)
|
||||||
else:
|
else:
|
||||||
@ -372,14 +375,13 @@ def main():
|
|||||||
for key, value in iter(sorted(options.items())):
|
for key, value in iter(sorted(options.items())):
|
||||||
log.debug("%s : %s" % (key, value))
|
log.debug("%s : %s" % (key, value))
|
||||||
|
|
||||||
|
|
||||||
log.debug("Checking file ....")
|
log.debug("Checking file ....")
|
||||||
if os.path.isfile(options["file"]) == False:
|
if os.path.isfile(options["file"]) is False:
|
||||||
log.critical("File does not exist!!!")
|
log.critical("File does not exist!!!")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
test_acess = _get_file_age(options["file"])
|
test_acess = _get_file_age(options["file"])
|
||||||
if type(test_acess) is not datetime.datetime:
|
if not isinstance(test_acess, datetime.datetime):
|
||||||
log.critical("Can't get file modification time!!!")
|
log.critical("Can't get file modification time!!!")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
@ -390,13 +392,11 @@ def main():
|
|||||||
|
|
||||||
|
|
||||||
class MyDaemon(daemon.daemon):
|
class MyDaemon(daemon.daemon):
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
monitor_loop(self.options)
|
monitor_loop(self.options)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
result = main()
|
result = main()
|
||||||
sys.exit(result)
|
sys.exit(result)
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,4 +21,4 @@
|
|||||||
# three numbers are the components of the version number. The fourth
|
# three numbers are the components of the version number. The fourth
|
||||||
# is zero for an official release, positive for a development branch,
|
# is zero for an official release, positive for a development branch,
|
||||||
# or negative for a release candidate or beta (after the base version
|
# or negative for a release candidate or beta (after the base version
|
||||||
# number has been incremented)
|
# number has been incremented)
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
"""Generic linux daemon base class for python 3.x."""
|
"""Generic linux daemon base class for python 3.x."""
|
||||||
|
|
||||||
import sys, os, time, atexit, signal
|
import sys
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import atexit
|
||||||
|
import signal
|
||||||
|
|
||||||
|
|
||||||
class daemon:
|
class daemon:
|
||||||
|
|
||||||
"""A generic daemon class.
|
"""A generic daemon class.
|
||||||
|
|
||||||
Usage: subclass the daemon class and override the run() method."""
|
Usage: subclass the daemon class and override the run() method."""
|
||||||
@ -54,7 +60,7 @@ class daemon:
|
|||||||
atexit.register(self.delpid)
|
atexit.register(self.delpid)
|
||||||
|
|
||||||
pid = str(os.getpid())
|
pid = str(os.getpid())
|
||||||
with open(self.pidfile,'w+') as f:
|
with open(self.pidfile, 'w+') as f:
|
||||||
f.write(pid + '\n')
|
f.write(pid + '\n')
|
||||||
|
|
||||||
def delpid(self):
|
def delpid(self):
|
||||||
@ -74,7 +80,7 @@ class daemon:
|
|||||||
|
|
||||||
# Check for a pidfile to see if the daemon already runs
|
# Check for a pidfile to see if the daemon already runs
|
||||||
try:
|
try:
|
||||||
with open(self.pidfile,'r') as pf:
|
with open(self.pidfile, 'r') as pf:
|
||||||
|
|
||||||
pid = int(pf.read().strip())
|
pid = int(pf.read().strip())
|
||||||
except IOError:
|
except IOError:
|
||||||
@ -101,20 +107,20 @@ class daemon:
|
|||||||
|
|
||||||
# Get the pid from the pidfile
|
# Get the pid from the pidfile
|
||||||
try:
|
try:
|
||||||
with open(self.pidfile,'r') as pf:
|
with open(self.pidfile, 'r') as pf:
|
||||||
pid = int(pf.read().strip())
|
pid = int(pf.read().strip())
|
||||||
except IOError:
|
except IOError:
|
||||||
pid = None
|
pid = None
|
||||||
|
|
||||||
if not pid:
|
if not pid:
|
||||||
message = "pidfile {0} does not exist. " + \
|
message = "pidfile {0} does not exist. " + \
|
||||||
"Daemon not running?\n"
|
"Daemon not running?\n"
|
||||||
sys.stderr.write(message.format(self.pidfile))
|
sys.stderr.write(message.format(self.pidfile))
|
||||||
return # not an error in a restart
|
return # not an error in a restart
|
||||||
|
|
||||||
# Try killing the daemon process
|
# Try killing the daemon process
|
||||||
try:
|
try:
|
||||||
while 1:
|
while True:
|
||||||
os.kill(pid, signal.SIGTERM)
|
os.kill(pid, signal.SIGTERM)
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
except OSError as err:
|
except OSError as err:
|
||||||
@ -123,7 +129,7 @@ class daemon:
|
|||||||
if os.path.exists(self.pidfile):
|
if os.path.exists(self.pidfile):
|
||||||
os.remove(self.pidfile)
|
os.remove(self.pidfile)
|
||||||
else:
|
else:
|
||||||
print (str(err.args))
|
print(str(err.args))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def restart(self):
|
def restart(self):
|
||||||
|
@ -23,7 +23,8 @@
|
|||||||
# or negative for a release candidate or beta (after the base version
|
# or negative for a release candidate or beta (after the base version
|
||||||
# number has been incremented)
|
# number has been incremented)
|
||||||
|
|
||||||
import os, sys
|
import os
|
||||||
|
import sys
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import socket
|
import socket
|
||||||
@ -34,7 +35,9 @@ from gns3dms.cloud.rackspace_ctrl import RackspaceCtrl
|
|||||||
LOG_NAME = "gns3dms.rksp"
|
LOG_NAME = "gns3dms.rksp"
|
||||||
log = logging.getLogger("%s" % (LOG_NAME))
|
log = logging.getLogger("%s" % (LOG_NAME))
|
||||||
|
|
||||||
|
|
||||||
class Rackspace(object):
|
class Rackspace(object):
|
||||||
|
|
||||||
def __init__(self, options):
|
def __init__(self, options):
|
||||||
self.username = options["cloud_user_name"]
|
self.username = options["cloud_user_name"]
|
||||||
self.apikey = options["cloud_api_key"]
|
self.apikey = options["cloud_api_key"]
|
||||||
@ -54,7 +57,7 @@ class Rackspace(object):
|
|||||||
|
|
||||||
for region in self.rksp.list_regions():
|
for region in self.rksp.list_regions():
|
||||||
log.debug("Rackspace regions: %s" % (region))
|
log.debug("Rackspace regions: %s" % (region))
|
||||||
|
|
||||||
log.debug("Checking region: %s" % (self.region))
|
log.debug("Checking region: %s" % (self.region))
|
||||||
self.rksp.set_region(self.region)
|
self.rksp.set_region(self.region)
|
||||||
for server in self.rksp.list_instances():
|
for server in self.rksp.list_instances():
|
||||||
|
@ -30,6 +30,7 @@ CLOUD_SERVER = 'CLOUD_SERVER'
|
|||||||
|
|
||||||
|
|
||||||
class Config(object):
|
class Config(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Configuration file management using configparser.
|
Configuration file management using configparser.
|
||||||
"""
|
"""
|
||||||
@ -117,7 +118,7 @@ class Config(object):
|
|||||||
:returns: configparser section
|
:returns: configparser section
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not section in self._config:
|
if section is not in self._config:
|
||||||
return self._config["DEFAULT"]
|
return self._config["DEFAULT"]
|
||||||
return self._config[section]
|
return self._config[section]
|
||||||
|
|
||||||
|
@ -27,32 +27,37 @@ import tornado.websocket
|
|||||||
import logging
|
import logging
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class GNS3BaseHandler(tornado.web.RequestHandler):
|
class GNS3BaseHandler(tornado.web.RequestHandler):
|
||||||
|
|
||||||
def get_current_user(self):
|
def get_current_user(self):
|
||||||
if 'required_user' not in self.settings:
|
if 'required_user' not in self.settings:
|
||||||
return "FakeUser"
|
return "FakeUser"
|
||||||
|
|
||||||
user = self.get_secure_cookie("user")
|
user = self.get_secure_cookie("user")
|
||||||
if not user:
|
if not user:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if self.settings['required_user'] == user.decode("utf-8"):
|
if self.settings['required_user'] == user.decode("utf-8"):
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
class GNS3WebSocketBaseHandler(tornado.websocket.WebSocketHandler):
|
class GNS3WebSocketBaseHandler(tornado.websocket.WebSocketHandler):
|
||||||
|
|
||||||
def get_current_user(self):
|
def get_current_user(self):
|
||||||
if 'required_user' not in self.settings:
|
if 'required_user' not in self.settings:
|
||||||
return "FakeUser"
|
return "FakeUser"
|
||||||
|
|
||||||
user = self.get_secure_cookie("user")
|
user = self.get_secure_cookie("user")
|
||||||
if not user:
|
if not user:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if self.settings['required_user'] == user.decode("utf-8"):
|
if self.settings['required_user'] == user.decode("utf-8"):
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
class LoginHandler(tornado.web.RequestHandler):
|
class LoginHandler(tornado.web.RequestHandler):
|
||||||
|
|
||||||
def get(self):
|
def get(self):
|
||||||
self.write('<html><body><form action="/login" method="post">'
|
self.write('<html><body><form action="/login" method="post">'
|
||||||
'Name: <input type="text" name="name">'
|
'Name: <input type="text" name="name">'
|
||||||
@ -61,10 +66,10 @@ class LoginHandler(tornado.web.RequestHandler):
|
|||||||
'</form></body></html>')
|
'</form></body></html>')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
redirect_to = self.get_argument("next")
|
redirect_to = self.get_argument("next")
|
||||||
self.set_secure_cookie("login_success_redirect_to", redirect_to)
|
self.set_secure_cookie("login_success_redirect_to", redirect_to)
|
||||||
except tornado.web.MissingArgumentError:
|
except tornado.web.MissingArgumentError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def post(self):
|
def post(self):
|
||||||
|
|
||||||
@ -72,21 +77,21 @@ class LoginHandler(tornado.web.RequestHandler):
|
|||||||
password = self.get_argument("password")
|
password = self.get_argument("password")
|
||||||
|
|
||||||
if self.settings['required_user'] == user and self.settings['required_pass'] == password:
|
if self.settings['required_user'] == user and self.settings['required_pass'] == password:
|
||||||
self.set_secure_cookie("user", user)
|
self.set_secure_cookie("user", user)
|
||||||
auth_status = "successful"
|
auth_status = "successful"
|
||||||
else:
|
else:
|
||||||
self.set_secure_cookie("user", "None")
|
self.set_secure_cookie("user", "None")
|
||||||
auth_status = "failure"
|
auth_status = "failure"
|
||||||
|
|
||||||
log.info("Authentication attempt {}: {}, {}".format(auth_status, user, password))
|
log.info("Authentication attempt {}: {}, {}".format(auth_status, user, password))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
redirect_to = self.get_secure_cookie("login_success_redirect_to")
|
redirect_to = self.get_secure_cookie("login_success_redirect_to")
|
||||||
except tornado.web.MissingArgumentError:
|
except tornado.web.MissingArgumentError:
|
||||||
redirect_to = "/"
|
redirect_to = "/"
|
||||||
|
|
||||||
if redirect_to is None:
|
if redirect_to is None:
|
||||||
self.write({'result': auth_status})
|
self.write({'result': auth_status})
|
||||||
else:
|
else:
|
||||||
log.info('Redirecting to {}'.format(redirect_to))
|
log.info('Redirecting to {}'.format(redirect_to))
|
||||||
self.redirect(redirect_to)
|
self.redirect(redirect_to)
|
||||||
|
@ -34,6 +34,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class FileUploadHandler(GNS3BaseHandler):
|
class FileUploadHandler(GNS3BaseHandler):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
File upload handler.
|
File upload handler.
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ from aiohttp.web import HTTPConflict
|
|||||||
|
|
||||||
|
|
||||||
class ProjectHandler:
|
class ProjectHandler:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@Route.post(
|
@Route.post(
|
||||||
r"/project",
|
r"/project",
|
||||||
|
@ -22,6 +22,7 @@ from ..modules.virtualbox import VirtualBox
|
|||||||
|
|
||||||
|
|
||||||
class VirtualBoxHandler:
|
class VirtualBoxHandler:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API entry points for VirtualBox.
|
API entry points for VirtualBox.
|
||||||
"""
|
"""
|
||||||
|
@ -23,6 +23,7 @@ from ..modules.vpcs import VPCS
|
|||||||
|
|
||||||
|
|
||||||
class VPCSHandler:
|
class VPCSHandler:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API entry points for VPCS.
|
API entry points for VPCS.
|
||||||
"""
|
"""
|
||||||
|
@ -27,6 +27,7 @@ from gns3server.version import __version__
|
|||||||
import logging
|
import logging
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def locale_check():
|
def locale_check():
|
||||||
"""
|
"""
|
||||||
Checks if this application runs with a correct locale (i.e. supports UTF-8 encoding) and attempt to fix
|
Checks if this application runs with a correct locale (i.e. supports UTF-8 encoding) and attempt to fix
|
||||||
@ -71,11 +72,10 @@ def main():
|
|||||||
Entry point for GNS3 server
|
Entry point for GNS3 server
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#TODO: migrate command line options to argparse (don't forget the quiet mode).
|
# TODO: migrate command line options to argparse (don't forget the quiet mode).
|
||||||
|
|
||||||
current_year = datetime.date.today().year
|
current_year = datetime.date.today().year
|
||||||
|
|
||||||
|
|
||||||
# TODO: Renable the test when we will have command line
|
# TODO: Renable the test when we will have command line
|
||||||
# user_log = logging.getLogger('user_facing')
|
# user_log = logging.getLogger('user_facing')
|
||||||
# if not options.quiet:
|
# if not options.quiet:
|
||||||
@ -95,7 +95,7 @@ def main():
|
|||||||
|
|
||||||
user_log.info("GNS3 server version {}".format(__version__))
|
user_log.info("GNS3 server version {}".format(__version__))
|
||||||
user_log.info("Copyright (c) 2007-{} GNS3 Technologies Inc.".format(current_year))
|
user_log.info("Copyright (c) 2007-{} GNS3 Technologies Inc.".format(current_year))
|
||||||
#TODO: end todo
|
# TODO: end todo
|
||||||
|
|
||||||
# we only support Python 3 version >= 3.3
|
# we only support Python 3 version >= 3.3
|
||||||
if sys.version_info < (3, 3):
|
if sys.version_info < (3, 3):
|
||||||
@ -115,7 +115,7 @@ def main():
|
|||||||
return
|
return
|
||||||
|
|
||||||
# TODO: Renable console_bind_to_any when we will have command line parsing
|
# TODO: Renable console_bind_to_any when we will have command line parsing
|
||||||
#server = Server(options.host, options.port, options.console_bind_to_any)
|
# server = Server(options.host, options.port, options.console_bind_to_any)
|
||||||
server = Server("127.0.0.1", 8000, False)
|
server = Server("127.0.0.1", 8000, False)
|
||||||
server.run()
|
server.run()
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
|
|
||||||
class Adapter(object):
|
class Adapter(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Base class for adapters.
|
Base class for adapters.
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class EthernetAdapter(Adapter):
|
class EthernetAdapter(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
VPCS Ethernet adapter.
|
VPCS Ethernet adapter.
|
||||||
"""
|
"""
|
||||||
|
@ -24,6 +24,7 @@ from .project_manager import ProjectManager
|
|||||||
|
|
||||||
|
|
||||||
class BaseManager:
|
class BaseManager:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Base class for all Manager.
|
Base class for all Manager.
|
||||||
Responsible of management of a VM pool
|
Responsible of management of a VM pool
|
||||||
|
@ -95,6 +95,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class Dynamips(IModule):
|
class Dynamips(IModule):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips module.
|
Dynamips module.
|
||||||
|
|
||||||
@ -140,7 +141,7 @@ class Dynamips(IModule):
|
|||||||
self._console_host = dynamips_config.get("console_host", kwargs["console_host"])
|
self._console_host = dynamips_config.get("console_host", kwargs["console_host"])
|
||||||
|
|
||||||
if not sys.platform.startswith("win32"):
|
if not sys.platform.startswith("win32"):
|
||||||
#FIXME: pickle issues Windows
|
# FIXME: pickle issues Windows
|
||||||
self._callback = self.add_periodic_callback(self._check_hypervisors, 5000)
|
self._callback = self.add_periodic_callback(self._check_hypervisors, 5000)
|
||||||
self._callback.start()
|
self._callback.start()
|
||||||
|
|
||||||
@ -323,7 +324,7 @@ class Dynamips(IModule):
|
|||||||
|
|
||||||
log.debug("received request {}".format(request))
|
log.debug("received request {}".format(request))
|
||||||
|
|
||||||
#TODO: JSON schema validation
|
# TODO: JSON schema validation
|
||||||
if not self._hypervisor_manager:
|
if not self._hypervisor_manager:
|
||||||
|
|
||||||
if "path" in request:
|
if "path" in request:
|
||||||
@ -407,7 +408,7 @@ class Dynamips(IModule):
|
|||||||
rhost = request["nio"]["rhost"]
|
rhost = request["nio"]["rhost"]
|
||||||
rport = request["nio"]["rport"]
|
rport = request["nio"]["rport"]
|
||||||
try:
|
try:
|
||||||
#TODO: handle IPv6
|
# TODO: handle IPv6
|
||||||
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
|
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
|
||||||
sock.connect((rhost, rport))
|
sock.connect((rhost, rport))
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
|
|
||||||
class Adapter(object):
|
class Adapter(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Base class for adapters.
|
Base class for adapters.
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class C1700_MB_1FE(Adapter):
|
class C1700_MB_1FE(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Integrated 1 port FastEthernet adapter for c1700 platform.
|
Integrated 1 port FastEthernet adapter for c1700 platform.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class C1700_MB_WIC1(Adapter):
|
class C1700_MB_WIC1(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Fake module to provide a placeholder for slot 1 interfaces when WICs
|
Fake module to provide a placeholder for slot 1 interfaces when WICs
|
||||||
are inserted into WIC slot 1.
|
are inserted into WIC slot 1.
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class C2600_MB_1E(Adapter):
|
class C2600_MB_1E(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Integrated 1 port Ethernet adapter for the c2600 platform.
|
Integrated 1 port Ethernet adapter for the c2600 platform.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class C2600_MB_1FE(Adapter):
|
class C2600_MB_1FE(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Integrated 1 port FastEthernet adapter for the c2600 platform.
|
Integrated 1 port FastEthernet adapter for the c2600 platform.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class C2600_MB_2E(Adapter):
|
class C2600_MB_2E(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Integrated 2 port Ethernet adapter for the c2600 platform.
|
Integrated 2 port Ethernet adapter for the c2600 platform.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class C2600_MB_2FE(Adapter):
|
class C2600_MB_2FE(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Integrated 2 port FastEthernet adapter for the c2600 platform.
|
Integrated 2 port FastEthernet adapter for the c2600 platform.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class C7200_IO_2FE(Adapter):
|
class C7200_IO_2FE(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
C7200-IO-2FE FastEthernet Input/Ouput controller.
|
C7200-IO-2FE FastEthernet Input/Ouput controller.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class C7200_IO_FE(Adapter):
|
class C7200_IO_FE(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
C7200-IO-FE FastEthernet Input/Ouput controller.
|
C7200-IO-FE FastEthernet Input/Ouput controller.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class C7200_IO_GE_E(Adapter):
|
class C7200_IO_GE_E(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
C7200-IO-GE-E GigabitEthernet Input/Ouput controller.
|
C7200-IO-GE-E GigabitEthernet Input/Ouput controller.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class Leopard_2FE(Adapter):
|
class Leopard_2FE(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Integrated 2 port FastEthernet adapter for c3660 router.
|
Integrated 2 port FastEthernet adapter for c3660 router.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class NM_16ESW(Adapter):
|
class NM_16ESW(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
NM-16ESW FastEthernet network module.
|
NM-16ESW FastEthernet network module.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class NM_1E(Adapter):
|
class NM_1E(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
NM-1E Ethernet network module.
|
NM-1E Ethernet network module.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class NM_1FE_TX(Adapter):
|
class NM_1FE_TX(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
NM-1FE-TX FastEthernet network module.
|
NM-1FE-TX FastEthernet network module.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class NM_4E(Adapter):
|
class NM_4E(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
NM-4E Ethernet network module.
|
NM-4E Ethernet network module.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class NM_4T(Adapter):
|
class NM_4T(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
NM-4T Serial network module.
|
NM-4T Serial network module.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class PA_2FE_TX(Adapter):
|
class PA_2FE_TX(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
PA-2FE-TX FastEthernet port adapter.
|
PA-2FE-TX FastEthernet port adapter.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class PA_4E(Adapter):
|
class PA_4E(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
PA-4E Ethernet port adapter.
|
PA-4E Ethernet port adapter.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class PA_4T(Adapter):
|
class PA_4T(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
PA-4T+ Serial port adapter.
|
PA-4T+ Serial port adapter.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class PA_8E(Adapter):
|
class PA_8E(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
PA-8E Ethernet port adapter.
|
PA-8E Ethernet port adapter.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class PA_8T(Adapter):
|
class PA_8T(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
PA-8T Serial port adapter.
|
PA-8T Serial port adapter.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class PA_A1(Adapter):
|
class PA_A1(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
PA-A1 ATM port adapter.
|
PA-A1 ATM port adapter.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class PA_FE_TX(Adapter):
|
class PA_FE_TX(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
PA-FE-TX FastEthernet port adapter.
|
PA-FE-TX FastEthernet port adapter.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class PA_GE(Adapter):
|
class PA_GE(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
PA-GE GigabitEthernet port adapter.
|
PA-GE GigabitEthernet port adapter.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class PA_POS_OC3(Adapter):
|
class PA_POS_OC3(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
PA-POS-OC3 port adapter.
|
PA-POS-OC3 port adapter.
|
||||||
"""
|
"""
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
|
|
||||||
class WIC_1ENET(object):
|
class WIC_1ENET(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
WIC-1ENET Ethernet
|
WIC-1ENET Ethernet
|
||||||
"""
|
"""
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
|
|
||||||
class WIC_1T(object):
|
class WIC_1T(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
WIC-1T Serial
|
WIC-1T Serial
|
||||||
"""
|
"""
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
|
|
||||||
class WIC_2T(object):
|
class WIC_2T(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
WIC-2T Serial
|
WIC-2T Serial
|
||||||
"""
|
"""
|
||||||
|
@ -466,7 +466,7 @@ class VM(object):
|
|||||||
adapter_name = value
|
adapter_name = value
|
||||||
adapter = ADAPTER_MATRIX[adapter_name]()
|
adapter = ADAPTER_MATRIX[adapter_name]()
|
||||||
try:
|
try:
|
||||||
if router.slots[slot_id] and type(router.slots[slot_id]) != type(adapter):
|
if router.slots[slot_id] and not isinstance(router.slots[slot_id], type(adapter)):
|
||||||
router.slot_remove_binding(slot_id)
|
router.slot_remove_binding(slot_id)
|
||||||
router.slot_add_binding(slot_id, adapter)
|
router.slot_add_binding(slot_id, adapter)
|
||||||
response[name] = value
|
response[name] = value
|
||||||
@ -487,14 +487,14 @@ class VM(object):
|
|||||||
wic_name = value
|
wic_name = value
|
||||||
wic = WIC_MATRIX[wic_name]()
|
wic = WIC_MATRIX[wic_name]()
|
||||||
try:
|
try:
|
||||||
if router.slots[0].wics[wic_slot_id] and type(router.slots[0].wics[wic_slot_id]) != type(wic):
|
if router.slots[0].wics[wic_slot_id] and not isinstance(router.slots[0].wics[wic_slot_id], type(wic)):
|
||||||
router.uninstall_wic(wic_slot_id)
|
router.uninstall_wic(wic_slot_id)
|
||||||
router.install_wic(wic_slot_id, wic)
|
router.install_wic(wic_slot_id, wic)
|
||||||
response[name] = value
|
response[name] = value
|
||||||
except DynamipsError as e:
|
except DynamipsError as e:
|
||||||
self.send_custom_error(str(e))
|
self.send_custom_error(str(e))
|
||||||
return
|
return
|
||||||
elif name.startswith("wic") and value == None:
|
elif name.startswith("wic") and value is None:
|
||||||
wic_slot_id = int(name[-1])
|
wic_slot_id = int(name[-1])
|
||||||
if router.slots[0].wics and router.slots[0].wics[wic_slot_id]:
|
if router.slots[0].wics and router.slots[0].wics[wic_slot_id]:
|
||||||
try:
|
try:
|
||||||
|
@ -30,6 +30,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class DynamipsHypervisor(object):
|
class DynamipsHypervisor(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Creates a new connection to a Dynamips server (also called hypervisor)
|
Creates a new connection to a Dynamips server (also called hypervisor)
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class Hypervisor(DynamipsHypervisor):
|
class Hypervisor(DynamipsHypervisor):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Hypervisor.
|
Hypervisor.
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class HypervisorManager(object):
|
class HypervisorManager(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Manages Dynamips hypervisors.
|
Manages Dynamips hypervisors.
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class NIO(object):
|
class NIO(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Base NIO class
|
Base NIO class
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class NIO_FIFO(NIO):
|
class NIO_FIFO(NIO):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips FIFO NIO.
|
Dynamips FIFO NIO.
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class NIO_GenericEthernet(NIO):
|
class NIO_GenericEthernet(NIO):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips generic Ethernet NIO.
|
Dynamips generic Ethernet NIO.
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class NIO_LinuxEthernet(NIO):
|
class NIO_LinuxEthernet(NIO):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips Linux Ethernet NIO.
|
Dynamips Linux Ethernet NIO.
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class NIO_Mcast(NIO):
|
class NIO_Mcast(NIO):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips Linux Ethernet NIO.
|
Dynamips Linux Ethernet NIO.
|
||||||
|
|
||||||
@ -103,5 +104,5 @@ class NIO_Mcast(NIO):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
self._hypervisor.send("nio set_mcast_ttl {name} {ttl}".format(name=self._name,
|
self._hypervisor.send("nio set_mcast_ttl {name} {ttl}".format(name=self._name,
|
||||||
ttl=ttl))
|
ttl=ttl))
|
||||||
self._ttl = ttl
|
self._ttl = ttl
|
||||||
|
@ -26,6 +26,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class NIO_Null(NIO):
|
class NIO_Null(NIO):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips NULL NIO.
|
Dynamips NULL NIO.
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class NIO_TAP(NIO):
|
class NIO_TAP(NIO):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips TAP NIO.
|
Dynamips TAP NIO.
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class NIO_UDP(NIO):
|
class NIO_UDP(NIO):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips UDP NIO.
|
Dynamips UDP NIO.
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class NIO_UDP_auto(NIO):
|
class NIO_UDP_auto(NIO):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips auto UDP NIO.
|
Dynamips auto UDP NIO.
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class NIO_UNIX(NIO):
|
class NIO_UNIX(NIO):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips UNIX NIO.
|
Dynamips UNIX NIO.
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class NIO_VDE(NIO):
|
class NIO_VDE(NIO):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips VDE NIO.
|
Dynamips VDE NIO.
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ from ..dynamips_error import DynamipsError
|
|||||||
|
|
||||||
|
|
||||||
class ATMBridge(object):
|
class ATMBridge(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips bridge switch.
|
Dynamips bridge switch.
|
||||||
|
|
||||||
@ -33,7 +34,7 @@ class ATMBridge(object):
|
|||||||
|
|
||||||
def __init__(self, hypervisor, name):
|
def __init__(self, hypervisor, name):
|
||||||
|
|
||||||
#FIXME: instance tracking
|
# FIXME: instance tracking
|
||||||
self._hypervisor = hypervisor
|
self._hypervisor = hypervisor
|
||||||
self._name = '"' + name + '"' # put name into quotes to protect spaces
|
self._name = '"' + name + '"' # put name into quotes to protect spaces
|
||||||
self._hypervisor.send("atm_bridge create {}".format(self._name))
|
self._hypervisor.send("atm_bridge create {}".format(self._name))
|
||||||
|
@ -28,6 +28,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class ATMSwitch(object):
|
class ATMSwitch(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips ATM switch.
|
Dynamips ATM switch.
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ http://github.com/GNS3/dynamips/blob/master/README.hypervisor#L538
|
|||||||
|
|
||||||
|
|
||||||
class Bridge(object):
|
class Bridge(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips bridge.
|
Dynamips bridge.
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class C1700(Router):
|
class C1700(Router):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips c1700 router.
|
Dynamips c1700 router.
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class C2600(Router):
|
class C2600(Router):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips c2600 router.
|
Dynamips c2600 router.
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class C2691(Router):
|
class C2691(Router):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips c2691 router.
|
Dynamips c2691 router.
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class C3600(Router):
|
class C3600(Router):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips c3600 router.
|
Dynamips c3600 router.
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class C3725(Router):
|
class C3725(Router):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips c3725 router.
|
Dynamips c3725 router.
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class C3745(Router):
|
class C3745(Router):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips c3745 router.
|
Dynamips c3745 router.
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class C7200(Router):
|
class C7200(Router):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips c7200 router (model is 7206).
|
Dynamips c7200 router (model is 7206).
|
||||||
|
|
||||||
@ -227,9 +228,9 @@ class C7200(Router):
|
|||||||
powered_on=power_supply))
|
powered_on=power_supply))
|
||||||
|
|
||||||
log.info("router {name} [id={id}]: power supply {power_supply_id} state updated to {powered_on}".format(name=self._name,
|
log.info("router {name} [id={id}]: power supply {power_supply_id} state updated to {powered_on}".format(name=self._name,
|
||||||
id=self._id,
|
id=self._id,
|
||||||
power_supply_id=power_supply_id,
|
power_supply_id=power_supply_id,
|
||||||
powered_on=power_supply))
|
powered_on=power_supply))
|
||||||
power_supply_id += 1
|
power_supply_id += 1
|
||||||
|
|
||||||
self._power_supplies = power_supplies
|
self._power_supplies = power_supplies
|
||||||
|
@ -28,6 +28,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class EthernetSwitch(object):
|
class EthernetSwitch(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips Ethernet switch.
|
Dynamips Ethernet switch.
|
||||||
|
|
||||||
@ -268,9 +269,9 @@ class EthernetSwitch(object):
|
|||||||
outer_vlan=outer_vlan))
|
outer_vlan=outer_vlan))
|
||||||
|
|
||||||
log.info("Ethernet switch {name} [id={id}]: port {port} set as a QinQ port with outer VLAN {vlan_id}".format(name=self._name,
|
log.info("Ethernet switch {name} [id={id}]: port {port} set as a QinQ port with outer VLAN {vlan_id}".format(name=self._name,
|
||||||
id=self._id,
|
id=self._id,
|
||||||
port=port,
|
port=port,
|
||||||
vlan_id=outer_vlan))
|
vlan_id=outer_vlan))
|
||||||
self._mapping[port] = ("qinq", outer_vlan)
|
self._mapping[port] = ("qinq", outer_vlan)
|
||||||
|
|
||||||
def get_mac_addr_table(self):
|
def get_mac_addr_table(self):
|
||||||
|
@ -28,6 +28,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class FrameRelaySwitch(object):
|
class FrameRelaySwitch(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips Frame Relay switch.
|
Dynamips Frame Relay switch.
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class Hub(Bridge):
|
class Hub(Bridge):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips hub (based on Bridge)
|
Dynamips hub (based on Bridge)
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class Router(object):
|
class Router(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dynamips router implementation.
|
Dynamips router implementation.
|
||||||
|
|
||||||
@ -575,7 +576,7 @@ class Router(object):
|
|||||||
try:
|
try:
|
||||||
reply = self._hypervisor.send("vm extract_config {}".format(self._name))[0].rsplit(' ', 2)[-2:]
|
reply = self._hypervisor.send("vm extract_config {}".format(self._name))[0].rsplit(' ', 2)[-2:]
|
||||||
except IOError:
|
except IOError:
|
||||||
#for some reason Dynamips gets frozen when it does not find the magic number in the NVRAM file.
|
# for some reason Dynamips gets frozen when it does not find the magic number in the NVRAM file.
|
||||||
return None, None
|
return None, None
|
||||||
startup_config = reply[0][1:-1] # get statup-config and remove single quotes
|
startup_config = reply[0][1:-1] # get statup-config and remove single quotes
|
||||||
private_config = reply[1][1:-1] # get private-config and remove single quotes
|
private_config = reply[1][1:-1] # get private-config and remove single quotes
|
||||||
|
@ -44,7 +44,7 @@ ETHSW_DELETE_SCHEMA = {
|
|||||||
"required": ["id"]
|
"required": ["id"]
|
||||||
}
|
}
|
||||||
|
|
||||||
#TODO: ports {'1': {'vlan': 1, 'type': 'qinq'}
|
# TODO: ports {'1': {'vlan': 1, 'type': 'qinq'}
|
||||||
ETHSW_UPDATE_SCHEMA = {
|
ETHSW_UPDATE_SCHEMA = {
|
||||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||||
"description": "Request validation to update an Ethernet switch instance",
|
"description": "Request validation to update an Ethernet switch instance",
|
||||||
@ -59,20 +59,20 @@ ETHSW_UPDATE_SCHEMA = {
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"minLength": 1,
|
"minLength": 1,
|
||||||
},
|
},
|
||||||
# "ports": {
|
# "ports": {
|
||||||
# "type": "object",
|
# "type": "object",
|
||||||
# "properties": {
|
# "properties": {
|
||||||
# "type": {
|
# "type": {
|
||||||
# "description": "Port type",
|
# "description": "Port type",
|
||||||
# "enum": ["access", "dot1q", "qinq"],
|
# "enum": ["access", "dot1q", "qinq"],
|
||||||
# },
|
# },
|
||||||
# "vlan": {
|
# "vlan": {
|
||||||
# "description": "VLAN number",
|
# "description": "VLAN number",
|
||||||
# "type": "integer",
|
# "type": "integer",
|
||||||
# "minimum": 1
|
# "minimum": 1
|
||||||
# },
|
# },
|
||||||
# },
|
# },
|
||||||
# },
|
# },
|
||||||
},
|
},
|
||||||
#"additionalProperties": False,
|
#"additionalProperties": False,
|
||||||
"required": ["id"]
|
"required": ["id"]
|
||||||
|
@ -147,7 +147,7 @@ VM_RELOAD_SCHEMA = {
|
|||||||
"required": ["id"]
|
"required": ["id"]
|
||||||
}
|
}
|
||||||
|
|
||||||
#TODO: improve platform specific properties (dependencies?)
|
# TODO: improve platform specific properties (dependencies?)
|
||||||
VM_UPDATE_SCHEMA = {
|
VM_UPDATE_SCHEMA = {
|
||||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||||
"description": "Request validation to update a VM instance",
|
"description": "Request validation to update a VM instance",
|
||||||
|
@ -56,6 +56,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class IOU(IModule):
|
class IOU(IModule):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
IOU module.
|
IOU module.
|
||||||
|
|
||||||
@ -635,7 +636,7 @@ class IOU(IModule):
|
|||||||
rhost = request["nio"]["rhost"]
|
rhost = request["nio"]["rhost"]
|
||||||
rport = request["nio"]["rport"]
|
rport = request["nio"]["rport"]
|
||||||
try:
|
try:
|
||||||
#TODO: handle IPv6
|
# TODO: handle IPv6
|
||||||
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
|
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
|
||||||
sock.connect((rhost, rport))
|
sock.connect((rhost, rport))
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
|
|
||||||
class Adapter(object):
|
class Adapter(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Base class for adapters.
|
Base class for adapters.
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class EthernetAdapter(Adapter):
|
class EthernetAdapter(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
IOU Ethernet adapter.
|
IOU Ethernet adapter.
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class SerialAdapter(Adapter):
|
class SerialAdapter(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
IOU Serial adapter.
|
IOU Serial adapter.
|
||||||
"""
|
"""
|
||||||
|
@ -43,6 +43,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class IOUDevice(object):
|
class IOUDevice(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
IOU device implementation.
|
IOU device implementation.
|
||||||
|
|
||||||
|
@ -56,22 +56,22 @@ EXIT_ABORT = 2
|
|||||||
# Mostly from:
|
# Mostly from:
|
||||||
# https://code.google.com/p/miniboa/source/browse/trunk/miniboa/telnet.py
|
# https://code.google.com/p/miniboa/source/browse/trunk/miniboa/telnet.py
|
||||||
#--[ Telnet Commands ]---------------------------------------------------------
|
#--[ Telnet Commands ]---------------------------------------------------------
|
||||||
SE = 240 # End of sub-negotiation parameters
|
SE = 240 # End of sub-negotiation parameters
|
||||||
NOP = 241 # No operation
|
NOP = 241 # No operation
|
||||||
DATMK = 242 # Data stream portion of a sync.
|
DATMK = 242 # Data stream portion of a sync.
|
||||||
BREAK = 243 # NVT Character BRK
|
BREAK = 243 # NVT Character BRK
|
||||||
IP = 244 # Interrupt Process
|
IP = 244 # Interrupt Process
|
||||||
AO = 245 # Abort Output
|
AO = 245 # Abort Output
|
||||||
AYT = 246 # Are you there
|
AYT = 246 # Are you there
|
||||||
EC = 247 # Erase Character
|
EC = 247 # Erase Character
|
||||||
EL = 248 # Erase Line
|
EL = 248 # Erase Line
|
||||||
GA = 249 # The Go Ahead Signal
|
GA = 249 # The Go Ahead Signal
|
||||||
SB = 250 # Sub-option to follow
|
SB = 250 # Sub-option to follow
|
||||||
WILL = 251 # Will; request or confirm option begin
|
WILL = 251 # Will; request or confirm option begin
|
||||||
WONT = 252 # Wont; deny option request
|
WONT = 252 # Wont; deny option request
|
||||||
DO = 253 # Do = Request or confirm remote option
|
DO = 253 # Do = Request or confirm remote option
|
||||||
DONT = 254 # Don't = Demand or confirm option halt
|
DONT = 254 # Don't = Demand or confirm option halt
|
||||||
IAC = 255 # Interpret as Command
|
IAC = 255 # Interpret as Command
|
||||||
SEND = 1 # Sub-process negotiation SEND command
|
SEND = 1 # Sub-process negotiation SEND command
|
||||||
IS = 0 # Sub-process negotiation IS command
|
IS = 0 # Sub-process negotiation IS command
|
||||||
#--[ Telnet Options ]----------------------------------------------------------
|
#--[ Telnet Options ]----------------------------------------------------------
|
||||||
@ -154,6 +154,7 @@ class FileLock:
|
|||||||
|
|
||||||
|
|
||||||
class Console:
|
class Console:
|
||||||
|
|
||||||
def fileno(self):
|
def fileno(self):
|
||||||
raise NotImplementedError("Only routers have fileno()")
|
raise NotImplementedError("Only routers have fileno()")
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ Base interface for NIOs.
|
|||||||
|
|
||||||
|
|
||||||
class NIO(object):
|
class NIO(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Network Input/Output.
|
Network Input/Output.
|
||||||
"""
|
"""
|
||||||
|
@ -23,6 +23,7 @@ from .nio import NIO
|
|||||||
|
|
||||||
|
|
||||||
class NIO_GenericEthernet(NIO):
|
class NIO_GenericEthernet(NIO):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Generic Ethernet NIO.
|
Generic Ethernet NIO.
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ from .nio import NIO
|
|||||||
|
|
||||||
|
|
||||||
class NIO_TAP(NIO):
|
class NIO_TAP(NIO):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
TAP NIO.
|
TAP NIO.
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ from .nio import NIO
|
|||||||
|
|
||||||
|
|
||||||
class NIO_UDP(NIO):
|
class NIO_UDP(NIO):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
UDP NIO.
|
UDP NIO.
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ Interface for TAP NIOs (UNIX based OSes only).
|
|||||||
|
|
||||||
|
|
||||||
class NIO_TAP(object):
|
class NIO_TAP(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
TAP NIO.
|
TAP NIO.
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ Interface for UDP NIOs.
|
|||||||
|
|
||||||
|
|
||||||
class NIO_UDP(object):
|
class NIO_UDP(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
UDP NIO.
|
UDP NIO.
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ import asyncio
|
|||||||
|
|
||||||
|
|
||||||
class PortManager:
|
class PortManager:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
:param host: IP address to bind for console connections
|
:param host: IP address to bind for console connections
|
||||||
"""
|
"""
|
||||||
|
@ -21,6 +21,7 @@ from uuid import uuid4
|
|||||||
|
|
||||||
|
|
||||||
class Project:
|
class Project:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
A project contains a list of VM.
|
A project contains a list of VM.
|
||||||
In theory VM are isolated project/project.
|
In theory VM are isolated project/project.
|
||||||
|
@ -20,6 +20,7 @@ from .project import Project
|
|||||||
|
|
||||||
|
|
||||||
class ProjectManager:
|
class ProjectManager:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This singleton keeps track of available projects.
|
This singleton keeps track of available projects.
|
||||||
"""
|
"""
|
||||||
|
@ -49,6 +49,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class Qemu(IModule):
|
class Qemu(IModule):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
QEMU module.
|
QEMU module.
|
||||||
|
|
||||||
@ -551,7 +552,7 @@ class Qemu(IModule):
|
|||||||
rhost = request["nio"]["rhost"]
|
rhost = request["nio"]["rhost"]
|
||||||
rport = request["nio"]["rport"]
|
rport = request["nio"]["rport"]
|
||||||
try:
|
try:
|
||||||
#TODO: handle IPv6
|
# TODO: handle IPv6
|
||||||
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
|
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
|
||||||
sock.connect((rhost, rport))
|
sock.connect((rhost, rport))
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
|
|
||||||
class Adapter(object):
|
class Adapter(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Base class for adapters.
|
Base class for adapters.
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ from .adapter import Adapter
|
|||||||
|
|
||||||
|
|
||||||
class EthernetAdapter(Adapter):
|
class EthernetAdapter(Adapter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
QEMU Ethernet adapter.
|
QEMU Ethernet adapter.
|
||||||
"""
|
"""
|
||||||
|
@ -21,6 +21,7 @@ Base interface for NIOs.
|
|||||||
|
|
||||||
|
|
||||||
class NIO(object):
|
class NIO(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Network Input/Output.
|
Network Input/Output.
|
||||||
"""
|
"""
|
||||||
|
@ -23,6 +23,7 @@ from .nio import NIO
|
|||||||
|
|
||||||
|
|
||||||
class NIO_UDP(NIO):
|
class NIO_UDP(NIO):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
UDP NIO.
|
UDP NIO.
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class QemuVM(object):
|
class QemuVM(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
QEMU VM implementation.
|
QEMU VM implementation.
|
||||||
|
|
||||||
@ -462,7 +463,6 @@ class QemuVM(object):
|
|||||||
disk_image=hdb_disk_image))
|
disk_image=hdb_disk_image))
|
||||||
self._hdb_disk_image = hdb_disk_image
|
self._hdb_disk_image = hdb_disk_image
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def adapters(self):
|
def adapters(self):
|
||||||
"""
|
"""
|
||||||
@ -586,7 +586,6 @@ class QemuVM(object):
|
|||||||
priority=process_priority))
|
priority=process_priority))
|
||||||
self._process_priority = process_priority
|
self._process_priority = process_priority
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ram(self):
|
def ram(self):
|
||||||
"""
|
"""
|
||||||
@ -999,18 +998,18 @@ class QemuVM(object):
|
|||||||
if self._legacy_networking:
|
if self._legacy_networking:
|
||||||
self._control_vm("host_net_remove {} gns3-{}".format(adapter_id, adapter_id))
|
self._control_vm("host_net_remove {} gns3-{}".format(adapter_id, adapter_id))
|
||||||
self._control_vm("host_net_add udp vlan={},name=gns3-{},sport={},dport={},daddr={}".format(adapter_id,
|
self._control_vm("host_net_add udp vlan={},name=gns3-{},sport={},dport={},daddr={}".format(adapter_id,
|
||||||
adapter_id,
|
adapter_id,
|
||||||
nio.lport,
|
nio.lport,
|
||||||
nio.rport,
|
nio.rport,
|
||||||
nio.rhost))
|
nio.rhost))
|
||||||
else:
|
else:
|
||||||
self._control_vm("host_net_remove {} gns3-{}".format(adapter_id, adapter_id))
|
self._control_vm("host_net_remove {} gns3-{}".format(adapter_id, adapter_id))
|
||||||
self._control_vm("host_net_add socket vlan={},name=gns3-{},udp={}:{},localaddr={}:{}".format(adapter_id,
|
self._control_vm("host_net_add socket vlan={},name=gns3-{},udp={}:{},localaddr={}:{}".format(adapter_id,
|
||||||
adapter_id,
|
adapter_id,
|
||||||
nio.rhost,
|
nio.rhost,
|
||||||
nio.rport,
|
nio.rport,
|
||||||
self._host,
|
self._host,
|
||||||
nio.lport))
|
nio.lport))
|
||||||
|
|
||||||
adapter.add_nio(0, nio)
|
adapter.add_nio(0, nio)
|
||||||
log.info("QEMU VM {name} [id={id}]: {nio} added to adapter {adapter_id}".format(name=self._name,
|
log.info("QEMU VM {name} [id={id}]: {nio} added to adapter {adapter_id}".format(name=self._name,
|
||||||
@ -1154,8 +1153,8 @@ class QemuVM(object):
|
|||||||
if not os.path.exists(hdb_disk):
|
if not os.path.exists(hdb_disk):
|
||||||
try:
|
try:
|
||||||
retcode = subprocess.call([qemu_img_path, "create", "-o",
|
retcode = subprocess.call([qemu_img_path, "create", "-o",
|
||||||
"backing_file={}".format(self._hdb_disk_image),
|
"backing_file={}".format(self._hdb_disk_image),
|
||||||
"-f", "qcow2", hdb_disk])
|
"-f", "qcow2", hdb_disk])
|
||||||
log.info("{} returned with {}".format(qemu_img_path, retcode))
|
log.info("{} returned with {}".format(qemu_img_path, retcode))
|
||||||
except (OSError, subprocess.SubprocessError) as e:
|
except (OSError, subprocess.SubprocessError) as e:
|
||||||
raise QemuError("Could not create disk image {}".format(e))
|
raise QemuError("Could not create disk image {}".format(e))
|
||||||
@ -1190,24 +1189,24 @@ class QemuVM(object):
|
|||||||
network_options = []
|
network_options = []
|
||||||
adapter_id = 0
|
adapter_id = 0
|
||||||
for adapter in self._ethernet_adapters:
|
for adapter in self._ethernet_adapters:
|
||||||
#TODO: let users specify a base mac address
|
# TODO: let users specify a base mac address
|
||||||
mac = "00:00:ab:%02x:%02x:%02d" % (random.randint(0x00, 0xff), random.randint(0x00, 0xff), adapter_id)
|
mac = "00:00:ab:%02x:%02x:%02d" % (random.randint(0x00, 0xff), random.randint(0x00, 0xff), adapter_id)
|
||||||
network_options.extend(["-net", "nic,vlan={},macaddr={},model={}".format(adapter_id, mac, self._adapter_type)])
|
network_options.extend(["-net", "nic,vlan={},macaddr={},model={}".format(adapter_id, mac, self._adapter_type)])
|
||||||
nio = adapter.get_nio(0)
|
nio = adapter.get_nio(0)
|
||||||
if nio and isinstance(nio, NIO_UDP):
|
if nio and isinstance(nio, NIO_UDP):
|
||||||
if self._legacy_networking:
|
if self._legacy_networking:
|
||||||
network_options.extend(["-net", "udp,vlan={},name=gns3-{},sport={},dport={},daddr={}".format(adapter_id,
|
network_options.extend(["-net", "udp,vlan={},name=gns3-{},sport={},dport={},daddr={}".format(adapter_id,
|
||||||
adapter_id,
|
adapter_id,
|
||||||
nio.lport,
|
nio.lport,
|
||||||
nio.rport,
|
nio.rport,
|
||||||
nio.rhost)])
|
nio.rhost)])
|
||||||
else:
|
else:
|
||||||
network_options.extend(["-net", "socket,vlan={},name=gns3-{},udp={}:{},localaddr={}:{}".format(adapter_id,
|
network_options.extend(["-net", "socket,vlan={},name=gns3-{},udp={}:{},localaddr={}:{}".format(adapter_id,
|
||||||
adapter_id,
|
adapter_id,
|
||||||
nio.rhost,
|
nio.rhost,
|
||||||
nio.rport,
|
nio.rport,
|
||||||
self._host,
|
self._host,
|
||||||
nio.lport)])
|
nio.lport)])
|
||||||
else:
|
else:
|
||||||
network_options.extend(["-net", "user,vlan={},name=gns3-{}".format(adapter_id, adapter_id)])
|
network_options.extend(["-net", "user,vlan={},name=gns3-{}".format(adapter_id, adapter_id)])
|
||||||
adapter_id += 1
|
adapter_id += 1
|
||||||
|
@ -31,6 +31,7 @@ if sys.platform.startswith("win"):
|
|||||||
|
|
||||||
|
|
||||||
class TelnetServer(threading.Thread):
|
class TelnetServer(threading.Thread):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Mini Telnet Server.
|
Mini Telnet Server.
|
||||||
|
|
||||||
@ -226,37 +227,38 @@ class TelnetServer(threading.Thread):
|
|||||||
# Mostly from https://code.google.com/p/miniboa/source/browse/trunk/miniboa/telnet.py
|
# Mostly from https://code.google.com/p/miniboa/source/browse/trunk/miniboa/telnet.py
|
||||||
|
|
||||||
# Telnet Commands
|
# Telnet Commands
|
||||||
SE = 240 # End of sub-negotiation parameters
|
SE = 240 # End of sub-negotiation parameters
|
||||||
NOP = 241 # No operation
|
NOP = 241 # No operation
|
||||||
DATMK = 242 # Data stream portion of a sync.
|
DATMK = 242 # Data stream portion of a sync.
|
||||||
BREAK = 243 # NVT Character BRK
|
BREAK = 243 # NVT Character BRK
|
||||||
IP = 244 # Interrupt Process
|
IP = 244 # Interrupt Process
|
||||||
AO = 245 # Abort Output
|
AO = 245 # Abort Output
|
||||||
AYT = 246 # Are you there
|
AYT = 246 # Are you there
|
||||||
EC = 247 # Erase Character
|
EC = 247 # Erase Character
|
||||||
EL = 248 # Erase Line
|
EL = 248 # Erase Line
|
||||||
GA = 249 # The Go Ahead Signal
|
GA = 249 # The Go Ahead Signal
|
||||||
SB = 250 # Sub-option to follow
|
SB = 250 # Sub-option to follow
|
||||||
WILL = 251 # Will; request or confirm option begin
|
WILL = 251 # Will; request or confirm option begin
|
||||||
WONT = 252 # Wont; deny option request
|
WONT = 252 # Wont; deny option request
|
||||||
DO = 253 # Do = Request or confirm remote option
|
DO = 253 # Do = Request or confirm remote option
|
||||||
DONT = 254 # Don't = Demand or confirm option halt
|
DONT = 254 # Don't = Demand or confirm option halt
|
||||||
IAC = 255 # Interpret as Command
|
IAC = 255 # Interpret as Command
|
||||||
SEND = 1 # Sub-process negotiation SEND command
|
SEND = 1 # Sub-process negotiation SEND command
|
||||||
IS = 0 # Sub-process negotiation IS command
|
IS = 0 # Sub-process negotiation IS command
|
||||||
|
|
||||||
# Telnet Options
|
# Telnet Options
|
||||||
BINARY = 0 # Transmit Binary
|
BINARY = 0 # Transmit Binary
|
||||||
ECHO = 1 # Echo characters back to sender
|
ECHO = 1 # Echo characters back to sender
|
||||||
RECON = 2 # Reconnection
|
RECON = 2 # Reconnection
|
||||||
SGA = 3 # Suppress Go-Ahead
|
SGA = 3 # Suppress Go-Ahead
|
||||||
TMARK = 6 # Timing Mark
|
TMARK = 6 # Timing Mark
|
||||||
TTYPE = 24 # Terminal Type
|
TTYPE = 24 # Terminal Type
|
||||||
NAWS = 31 # Negotiate About Window Size
|
NAWS = 31 # Negotiate About Window Size
|
||||||
LINEMO = 34 # Line Mode
|
LINEMO = 34 # Line Mode
|
||||||
|
|
||||||
|
|
||||||
class TelnetClient(object):
|
class TelnetClient(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Represents a Telnet client connection.
|
Represents a Telnet client connection.
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user