mirror of
https://github.com/GNS3/gns3-server
synced 2025-01-01 11:40:56 +00:00
Chassis and private-config support
This commit is contained in:
parent
0e1d8e5071
commit
99cc7345b8
@ -20,6 +20,7 @@ Dynamips server module.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import base64
|
||||||
import tempfile
|
import tempfile
|
||||||
from gns3server.modules import IModule
|
from gns3server.modules import IModule
|
||||||
import gns3server.jsonrpc as jsonrpc
|
import gns3server.jsonrpc as jsonrpc
|
||||||
@ -362,6 +363,35 @@ class Dynamips(IModule):
|
|||||||
router.ghost_status = 2
|
router.ghost_status = 2
|
||||||
router.ghost_file = ghost_instance
|
router.ghost_file = ghost_instance
|
||||||
|
|
||||||
|
def save_base64config(self, config_base64, router, config_filename):
|
||||||
|
"""
|
||||||
|
Saves a base64 encoded config (decoded) to a file.
|
||||||
|
|
||||||
|
:param config_base64: base64 encoded config
|
||||||
|
:param router: router instance
|
||||||
|
:param config_filename: file name to save the config
|
||||||
|
|
||||||
|
:returns: relative path to the config file
|
||||||
|
"""
|
||||||
|
|
||||||
|
config = base64.decodestring(config_base64.encode("utf-8")).decode("utf-8")
|
||||||
|
config = "!\n" + config.replace("\r", "")
|
||||||
|
config = config.replace('%h', router.name)
|
||||||
|
config_dir = os.path.join(router.hypervisor.working_dir, "configs")
|
||||||
|
if not os.path.exists(config_dir):
|
||||||
|
try:
|
||||||
|
os.makedirs(config_dir)
|
||||||
|
except EnvironmentError as e:
|
||||||
|
raise DynamipsError("Could not create configs directory: {}".format(e))
|
||||||
|
config_path = os.path.join(config_dir, config_filename)
|
||||||
|
try:
|
||||||
|
with open(config_path, "w") as f:
|
||||||
|
log.info("saving startup-config to {}".format(config_path))
|
||||||
|
f.write(config)
|
||||||
|
except EnvironmentError as e:
|
||||||
|
raise DynamipsError("Could not save the configuration {}: {}".format(config_path, e))
|
||||||
|
return "configs" + os.sep + os.path.basename(config_path)
|
||||||
|
|
||||||
@IModule.route("dynamips.nio.get_interfaces")
|
@IModule.route("dynamips.nio.get_interfaces")
|
||||||
def nio_get_interfaces(self, request):
|
def nio_get_interfaces(self, request):
|
||||||
"""
|
"""
|
||||||
|
@ -101,6 +101,7 @@ class VM(object):
|
|||||||
- console (console port number)
|
- console (console port number)
|
||||||
- aux (auxiliary console port number)
|
- aux (auxiliary console port number)
|
||||||
- mac_addr (MAC address)
|
- mac_addr (MAC address)
|
||||||
|
- chassis (router chassis model)
|
||||||
|
|
||||||
Response parameters:
|
Response parameters:
|
||||||
- id (vm identifier)
|
- id (vm identifier)
|
||||||
@ -123,6 +124,9 @@ class VM(object):
|
|||||||
image = request["image"]
|
image = request["image"]
|
||||||
ram = request["ram"]
|
ram = request["ram"]
|
||||||
hypervisor = None
|
hypervisor = None
|
||||||
|
chassis = None
|
||||||
|
if "chassis" in request:
|
||||||
|
chassis = request["chassis"]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
@ -131,6 +135,9 @@ class VM(object):
|
|||||||
|
|
||||||
hypervisor = self._hypervisor_manager.allocate_hypervisor_for_router(image, ram)
|
hypervisor = self._hypervisor_manager.allocate_hypervisor_for_router(image, ram)
|
||||||
|
|
||||||
|
if chassis:
|
||||||
|
router = PLATFORMS[platform](hypervisor, name, chassis=chassis)
|
||||||
|
else:
|
||||||
router = PLATFORMS[platform](hypervisor, name)
|
router = PLATFORMS[platform](hypervisor, name)
|
||||||
router.ram = ram
|
router.ram = ram
|
||||||
router.image = image
|
router.image = image
|
||||||
@ -341,6 +348,7 @@ class VM(object):
|
|||||||
Optional request parameters:
|
Optional request parameters:
|
||||||
- any setting to update
|
- any setting to update
|
||||||
- startup_config_base64 (startup-config base64 encoded)
|
- startup_config_base64 (startup-config base64 encoded)
|
||||||
|
- private_config_base64 (private-config base64 encoded)
|
||||||
|
|
||||||
Response parameters:
|
Response parameters:
|
||||||
- same as original request
|
- same as original request
|
||||||
@ -360,25 +368,18 @@ class VM(object):
|
|||||||
try:
|
try:
|
||||||
# a new startup-config has been pushed
|
# a new startup-config has been pushed
|
||||||
if "startup_config_base64" in request:
|
if "startup_config_base64" in request:
|
||||||
config = base64.decodestring(request["startup_config_base64"].encode("utf-8")).decode("utf-8")
|
config_filename = "{}.cfg".format(router.name)
|
||||||
config = "!\n" + config.replace("\r", "")
|
request["startup_config"] = self.save_base64config(request["startup_config_base64"], router, config_filename)
|
||||||
config = config.replace('%h', router.name)
|
|
||||||
config_dir = os.path.join(router.hypervisor.working_dir, "configs")
|
|
||||||
if not os.path.exists(config_dir):
|
|
||||||
try:
|
|
||||||
os.makedirs(config_dir)
|
|
||||||
except EnvironmentError as e:
|
|
||||||
raise DynamipsError("Could not create configs directory: {}".format(e))
|
|
||||||
config_path = os.path.join(config_dir, "{}.cfg".format(router.name))
|
|
||||||
try:
|
|
||||||
with open(config_path, "w") as f:
|
|
||||||
log.info("saving startup-config to {}".format(config_path))
|
|
||||||
f.write(config)
|
|
||||||
except EnvironmentError as e:
|
|
||||||
raise DynamipsError("Could not save the configuration {}: {}".format(config_path, e))
|
|
||||||
request["startup_config"] = "configs" + os.sep + os.path.basename(config_path)
|
|
||||||
if "startup_config" in request:
|
if "startup_config" in request:
|
||||||
router.set_config(request["startup_config"])
|
router.set_config(request["startup_config"])
|
||||||
|
|
||||||
|
# a new private-config has been pushed
|
||||||
|
if "private_config_base64" in request:
|
||||||
|
config_filename = "{}-private.cfg".format(router.name)
|
||||||
|
request["private_config"] = self.save_base64config(request["private_config_base64"], router, config_filename)
|
||||||
|
if "private_config" in request:
|
||||||
|
router.set_config(router.startup_config, request["private_config"])
|
||||||
|
|
||||||
except DynamipsError as e:
|
except DynamipsError as e:
|
||||||
self.send_custom_error(str(e))
|
self.send_custom_error(str(e))
|
||||||
return
|
return
|
||||||
@ -455,9 +456,9 @@ class VM(object):
|
|||||||
router_id = request["id"]
|
router_id = request["id"]
|
||||||
router = self._routers[router_id]
|
router = self._routers[router_id]
|
||||||
try:
|
try:
|
||||||
if router.startup_config:
|
if router.startup_config or router.private_config:
|
||||||
#TODO: handle private-config
|
|
||||||
startup_config_base64, _ = router.extract_config()
|
startup_config_base64, private_config_base64 = router.extract_config()
|
||||||
if startup_config_base64:
|
if startup_config_base64:
|
||||||
try:
|
try:
|
||||||
config = base64.decodestring(startup_config_base64.encode("utf-8")).decode("utf-8")
|
config = base64.decodestring(startup_config_base64.encode("utf-8")).decode("utf-8")
|
||||||
@ -467,7 +468,19 @@ class VM(object):
|
|||||||
log.info("saving startup-config to {}".format(router.startup_config))
|
log.info("saving startup-config to {}".format(router.startup_config))
|
||||||
f.write(config)
|
f.write(config)
|
||||||
except EnvironmentError as e:
|
except EnvironmentError as e:
|
||||||
raise DynamipsError("Could not save the configuration {}: {}".format(config_path, e))
|
raise DynamipsError("Could not save the startup configuration {}: {}".format(config_path, e))
|
||||||
|
|
||||||
|
if private_config_base64:
|
||||||
|
try:
|
||||||
|
config = base64.decodestring(private_config_base64.encode("utf-8")).decode("utf-8")
|
||||||
|
config = "!\n" + config.replace("\r", "")
|
||||||
|
config_path = os.path.join(router.hypervisor.working_dir, router.private_config)
|
||||||
|
with open(config_path, "w") as f:
|
||||||
|
log.info("saving private-config to {}".format(router.private_config))
|
||||||
|
f.write(config)
|
||||||
|
except EnvironmentError as e:
|
||||||
|
raise DynamipsError("Could not save the private configuration {}: {}".format(config_path, e))
|
||||||
|
|
||||||
except DynamipsError as e:
|
except DynamipsError as e:
|
||||||
log.warn("could not save config to {}: {}".format(router.startup_config, e))
|
log.warn("could not save config to {}: {}".format(router.startup_config, e))
|
||||||
|
|
||||||
|
@ -86,7 +86,9 @@ class C7200(Router):
|
|||||||
"disk1": self._disk1,
|
"disk1": self._disk1,
|
||||||
"npe": self._npe,
|
"npe": self._npe,
|
||||||
"midplane": self._midplane,
|
"midplane": self._midplane,
|
||||||
"clock_divisor": self._clock_divisor}
|
"clock_divisor": self._clock_divisor,
|
||||||
|
"sensors": self._sensors,
|
||||||
|
"power_supplies": self._power_supplies}
|
||||||
|
|
||||||
# update the router defaults with the platform specific defaults
|
# update the router defaults with the platform specific defaults
|
||||||
router_defaults.update(platform_defaults)
|
router_defaults.update(platform_defaults)
|
||||||
@ -230,3 +232,17 @@ class C7200(Router):
|
|||||||
power_supply_id += 1
|
power_supply_id += 1
|
||||||
|
|
||||||
self._power_supplies = power_supplies
|
self._power_supplies = power_supplies
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
"""
|
||||||
|
Starts this router.
|
||||||
|
At least the IOS image must be set before starting it.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# trick: we must send sensors and power supplies info after starting the router
|
||||||
|
# otherwise they are not taken into account (Dynamips bug?)
|
||||||
|
Router.start(self)
|
||||||
|
if self._sensors != [22, 22, 22, 22]:
|
||||||
|
self.sensors = self._sensors
|
||||||
|
if self._power_supplies != [1, 1]:
|
||||||
|
self.power_supplies = self._power_supplies
|
||||||
|
@ -452,11 +452,15 @@ class Router(object):
|
|||||||
id=self._id,
|
id=self._id,
|
||||||
startup='"' + startup_config + '"'))
|
startup='"' + startup_config + '"'))
|
||||||
|
|
||||||
|
self._startup_config = startup_config
|
||||||
|
|
||||||
if private_config:
|
if private_config:
|
||||||
log.info("router {name} [id={id}]: has a private-config set: {private}".format(name=self._name,
|
log.info("router {name} [id={id}]: has a private-config set: {private}".format(name=self._name,
|
||||||
id=self._id,
|
id=self._id,
|
||||||
private='"' + private_config + '"'))
|
private='"' + private_config + '"'))
|
||||||
|
|
||||||
|
self._private_config = private_config
|
||||||
|
|
||||||
def extract_config(self):
|
def extract_config(self):
|
||||||
"""
|
"""
|
||||||
Gets the contents of the config files
|
Gets the contents of the config files
|
||||||
@ -1180,9 +1184,9 @@ class Router(object):
|
|||||||
|
|
||||||
# Generate an OIR event if the router is running and
|
# Generate an OIR event if the router is running and
|
||||||
# only for c7200, c3600 and c3745 (NM-4T only)
|
# only for c7200, c3600 and c3745 (NM-4T only)
|
||||||
if self.is_running() and self._platform == 'c7200' \
|
if self.is_running() and (self._platform == 'c7200' \
|
||||||
or (self._platform == 'c3600' and self.chassis == '3660') \
|
or (self._platform == 'c3600' and self.chassis == '3660') \
|
||||||
or (self._platform == 'c3745' and adapter == 'NM-4T'):
|
or (self._platform == 'c3745' and adapter == 'NM-4T')):
|
||||||
|
|
||||||
self._hypervisor.send("vm slot_oir_start {name} {slot_id} 0".format(name=self._name,
|
self._hypervisor.send("vm slot_oir_start {name} {slot_id} 0".format(name=self._name,
|
||||||
slot_id=slot_id))
|
slot_id=slot_id))
|
||||||
@ -1212,9 +1216,9 @@ class Router(object):
|
|||||||
|
|
||||||
# Generate an OIR event if the router is running and
|
# Generate an OIR event if the router is running and
|
||||||
# only for c7200, c3600 and c3745 (NM-4T only)
|
# only for c7200, c3600 and c3745 (NM-4T only)
|
||||||
if self.is_running() and self._platform == 'c7200' \
|
if self.is_running() and (self._platform == 'c7200' \
|
||||||
or (self._platform == 'c3600' and self.chassis == '3660') \
|
or (self._platform == 'c3600' and self.chassis == '3660') \
|
||||||
or (self._platform == 'c3745' and adapter == 'NM-4T'):
|
or (self._platform == 'c3745' and adapter == 'NM-4T')):
|
||||||
|
|
||||||
self._hypervisor.send("vm slot_oir_stop {name} {slot_id} 0".format(name=self._name,
|
self._hypervisor.send("vm slot_oir_stop {name} {slot_id} 0".format(name=self._name,
|
||||||
slot_id=slot_id))
|
slot_id=slot_id))
|
||||||
|
Loading…
Reference in New Issue
Block a user