mirror of
https://github.com/GNS3/gns3-server.git
synced 2024-11-16 16:54:51 +02:00
parent
afcd27f348
commit
e892e5dfab
@ -23,6 +23,7 @@ A minimal version:
|
|||||||
|
|
||||||
The revision is the version of file format:
|
The revision is the version of file format:
|
||||||
|
|
||||||
|
* 8: GNS3 2.1
|
||||||
* 7: GNS3 2.0
|
* 7: GNS3 2.0
|
||||||
* 6: GNS3 2.0 < beta 3
|
* 6: GNS3 2.0 < beta 3
|
||||||
* 5: GNS3 2.0 < alpha 4
|
* 5: GNS3 2.0 < alpha 4
|
||||||
|
@ -515,25 +515,12 @@ class Dynamips(BaseManager):
|
|||||||
default_startup_config_path = os.path.join(module_workdir, vm.id, "configs", "i{}_startup-config.cfg".format(vm.dynamips_id))
|
default_startup_config_path = os.path.join(module_workdir, vm.id, "configs", "i{}_startup-config.cfg".format(vm.dynamips_id))
|
||||||
default_private_config_path = os.path.join(module_workdir, vm.id, "configs", "i{}_private-config.cfg".format(vm.dynamips_id))
|
default_private_config_path = os.path.join(module_workdir, vm.id, "configs", "i{}_private-config.cfg".format(vm.dynamips_id))
|
||||||
|
|
||||||
startup_config_path = settings.get("startup_config")
|
|
||||||
startup_config_content = settings.get("startup_config_content")
|
startup_config_content = settings.get("startup_config_content")
|
||||||
if startup_config_path:
|
if startup_config_content:
|
||||||
yield from vm.set_configs(startup_config_path)
|
self._create_config(vm, default_startup_config_path, startup_config_content)
|
||||||
elif startup_config_content:
|
|
||||||
startup_config_path = self._create_config(vm, default_startup_config_path, startup_config_content)
|
|
||||||
yield from vm.set_configs(startup_config_path)
|
|
||||||
elif os.path.isfile(default_startup_config_path) and os.path.getsize(default_startup_config_path) == 0:
|
|
||||||
# An empty startup-config may crash Dynamips
|
|
||||||
startup_config_path = self._create_config(vm, default_startup_config_path, "!\n")
|
|
||||||
yield from vm.set_configs(startup_config_path)
|
|
||||||
|
|
||||||
private_config_path = settings.get("private_config")
|
|
||||||
private_config_content = settings.get("private_config_content")
|
private_config_content = settings.get("private_config_content")
|
||||||
if private_config_path:
|
if private_config_content:
|
||||||
yield from vm.set_configs(vm.startup_config, private_config_path)
|
self._create_config(vm, default_private_config_path, private_config_content)
|
||||||
elif private_config_content:
|
|
||||||
private_config_path = self._create_config(vm, default_private_config_path, private_config_content)
|
|
||||||
yield from vm.set_configs(vm.startup_config, private_config_path)
|
|
||||||
|
|
||||||
def _create_config(self, vm, path, content=None):
|
def _create_config(self, vm, path, content=None):
|
||||||
"""
|
"""
|
||||||
@ -553,6 +540,11 @@ class Dynamips(BaseManager):
|
|||||||
except OSError as e:
|
except OSError as e:
|
||||||
raise DynamipsError("Could not create Dynamips configs directory: {}".format(e))
|
raise DynamipsError("Could not create Dynamips configs directory: {}".format(e))
|
||||||
|
|
||||||
|
if content is None or len(content) == 0:
|
||||||
|
content = "!\n"
|
||||||
|
if os.path.exists(path):
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(path, "wb") as f:
|
with open(path, "wb") as f:
|
||||||
if content:
|
if content:
|
||||||
|
@ -78,8 +78,6 @@ class Router(BaseNode):
|
|||||||
self._dynamips_id = dynamips_id
|
self._dynamips_id = dynamips_id
|
||||||
self._platform = platform
|
self._platform = platform
|
||||||
self._image = ""
|
self._image = ""
|
||||||
self._startup_config = ""
|
|
||||||
self._private_config = ""
|
|
||||||
self._ram = 128 # Megabytes
|
self._ram = 128 # Megabytes
|
||||||
self._nvram = 128 # Kilobytes
|
self._nvram = 128 # Kilobytes
|
||||||
self._mmap = True
|
self._mmap = True
|
||||||
@ -102,8 +100,6 @@ class Router(BaseNode):
|
|||||||
self._slots = []
|
self._slots = []
|
||||||
self._ghost_flag = ghost_flag
|
self._ghost_flag = ghost_flag
|
||||||
self._memory_watcher = None
|
self._memory_watcher = None
|
||||||
self._startup_config_content = ""
|
|
||||||
self._private_config_content = ""
|
|
||||||
|
|
||||||
if not ghost_flag:
|
if not ghost_flag:
|
||||||
if not dynamips_id:
|
if not dynamips_id:
|
||||||
@ -152,8 +148,6 @@ class Router(BaseNode):
|
|||||||
"platform": self._platform,
|
"platform": self._platform,
|
||||||
"image": self._image,
|
"image": self._image,
|
||||||
"image_md5sum": md5sum(self._image),
|
"image_md5sum": md5sum(self._image),
|
||||||
"startup_config": self._startup_config,
|
|
||||||
"private_config": self._private_config,
|
|
||||||
"ram": self._ram,
|
"ram": self._ram,
|
||||||
"nvram": self._nvram,
|
"nvram": self._nvram,
|
||||||
"mmap": self._mmap,
|
"mmap": self._mmap,
|
||||||
@ -171,9 +165,7 @@ class Router(BaseNode):
|
|||||||
"console_type": "telnet",
|
"console_type": "telnet",
|
||||||
"aux": self.aux,
|
"aux": self.aux,
|
||||||
"mac_addr": self._mac_addr,
|
"mac_addr": self._mac_addr,
|
||||||
"system_id": self._system_id,
|
"system_id": self._system_id}
|
||||||
"startup_config_content": self._startup_config_content,
|
|
||||||
"private_config_content": self._private_config_content}
|
|
||||||
|
|
||||||
# return the relative path if the IOS image is in the images_path directory
|
# return the relative path if the IOS image is in the images_path directory
|
||||||
router_info["image"] = self.manager.get_relative_image_path(self._image)
|
router_info["image"] = self.manager.get_relative_image_path(self._image)
|
||||||
@ -289,6 +281,16 @@ class Router(BaseNode):
|
|||||||
if not self._ghost_flag:
|
if not self._ghost_flag:
|
||||||
self.check_available_ram(self.ram)
|
self.check_available_ram(self.ram)
|
||||||
|
|
||||||
|
startup_config_path = os.path.join("configs", "i{}_startup-config.cfg".format(self._dynamips_id))
|
||||||
|
private_config_path = os.path.join("configs", "i{}_private-config.cfg".format(self._dynamips_id))
|
||||||
|
|
||||||
|
if not os.path.exists(private_config_path) or not os.path.getsize(private_config_path):
|
||||||
|
# an empty private-config can prevent a router to boot.
|
||||||
|
private_config_path = ''
|
||||||
|
yield from self._hypervisor.send('vm set_config "{name}" "{startup}" "{private}"'.format(
|
||||||
|
name=self._name,
|
||||||
|
startup=startup_config_path,
|
||||||
|
private=private_config_path))
|
||||||
yield from self._hypervisor.send('vm start "{name}"'.format(name=self._name))
|
yield from self._hypervisor.send('vm start "{name}"'.format(name=self._name))
|
||||||
self.status = "started"
|
self.status = "started"
|
||||||
log.info('router "{name}" [{id}] has been started'.format(name=self._name, id=self._id))
|
log.info('router "{name}" [{id}] has been started'.format(name=self._name, id=self._id))
|
||||||
@ -1458,26 +1460,6 @@ class Router(BaseNode):
|
|||||||
|
|
||||||
return self._slots
|
return self._slots
|
||||||
|
|
||||||
@property
|
|
||||||
def startup_config(self):
|
|
||||||
"""
|
|
||||||
Returns the startup-config for this router.
|
|
||||||
|
|
||||||
:returns: path to startup-config file
|
|
||||||
"""
|
|
||||||
|
|
||||||
return self._startup_config
|
|
||||||
|
|
||||||
@property
|
|
||||||
def private_config(self):
|
|
||||||
"""
|
|
||||||
Returns the private-config for this router.
|
|
||||||
|
|
||||||
:returns: path to private-config file
|
|
||||||
"""
|
|
||||||
|
|
||||||
return self._private_config
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def set_name(self, new_name):
|
def set_name(self, new_name):
|
||||||
"""
|
"""
|
||||||
@ -1486,89 +1468,34 @@ class Router(BaseNode):
|
|||||||
:param new_name: new name string
|
:param new_name: new name string
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self._startup_config:
|
# change the hostname in the startup-config
|
||||||
# change the hostname in the startup-config
|
startup_config_path = os.path.join(self._working_directory, "configs", "i{}_startup-config.cfg".format(self._dynamips_id))
|
||||||
startup_config_path = os.path.join(self._working_directory, "configs", "i{}_startup-config.cfg".format(self._dynamips_id))
|
if os.path.isfile(startup_config_path):
|
||||||
if os.path.isfile(startup_config_path):
|
try:
|
||||||
try:
|
with open(startup_config_path, "r+", encoding="utf-8", errors="replace") as f:
|
||||||
with open(startup_config_path, "r+", encoding="utf-8", errors="replace") as f:
|
old_config = f.read()
|
||||||
old_config = f.read()
|
new_config = old_config.replace(self.name, new_name)
|
||||||
new_config = old_config.replace(self.name, new_name)
|
f.seek(0)
|
||||||
f.seek(0)
|
f.write(new_config)
|
||||||
self._startup_config_content = new_config
|
except OSError as e:
|
||||||
f.write(new_config)
|
raise DynamipsError("Could not amend the configuration {}: {}".format(startup_config_path, e))
|
||||||
except OSError as e:
|
|
||||||
raise DynamipsError("Could not amend the configuration {}: {}".format(startup_config_path, e))
|
|
||||||
|
|
||||||
if self._private_config:
|
# change the hostname in the private-config
|
||||||
# change the hostname in the private-config
|
private_config_path = os.path.join(self._working_directory, "configs", "i{}_private-config.cfg".format(self._dynamips_id))
|
||||||
private_config_path = os.path.join(self._working_directory, "configs", "i{}_private-config.cfg".format(self._dynamips_id))
|
if os.path.isfile(private_config_path):
|
||||||
if os.path.isfile(private_config_path):
|
try:
|
||||||
try:
|
with open(private_config_path, "r+", encoding="utf-8", errors="replace") as f:
|
||||||
with open(private_config_path, "r+", encoding="utf-8", errors="replace") as f:
|
old_config = f.read()
|
||||||
old_config = f.read()
|
new_config = old_config.replace(self.name, new_name)
|
||||||
new_config = old_config.replace(self.name, new_name)
|
f.seek(0)
|
||||||
f.seek(0)
|
f.write(new_config)
|
||||||
self._private_config_content = new_config
|
except OSError as e:
|
||||||
f.write(new_config)
|
raise DynamipsError("Could not amend the configuration {}: {}".format(private_config_path, e))
|
||||||
except OSError as e:
|
|
||||||
raise DynamipsError("Could not amend the configuration {}: {}".format(private_config_path, e))
|
|
||||||
|
|
||||||
yield from self._hypervisor.send('vm rename "{name}" "{new_name}"'.format(name=self._name, new_name=new_name))
|
yield from self._hypervisor.send('vm rename "{name}" "{new_name}"'.format(name=self._name, new_name=new_name))
|
||||||
log.info('Router "{name}" [{id}]: renamed to "{new_name}"'.format(name=self._name, id=self._id, new_name=new_name))
|
log.info('Router "{name}" [{id}]: renamed to "{new_name}"'.format(name=self._name, id=self._id, new_name=new_name))
|
||||||
self._name = new_name
|
self._name = new_name
|
||||||
|
|
||||||
@asyncio.coroutine
|
|
||||||
def set_configs(self, startup_config, private_config=''):
|
|
||||||
"""
|
|
||||||
Sets the config files that are pushed to startup-config and
|
|
||||||
private-config in NVRAM when the instance is started.
|
|
||||||
|
|
||||||
:param startup_config: path to statup-config file
|
|
||||||
:param private_config: path to private-config file
|
|
||||||
(keep existing data when if an empty string)
|
|
||||||
"""
|
|
||||||
|
|
||||||
startup_config = startup_config.replace("\\", '/')
|
|
||||||
private_config = private_config.replace("\\", '/')
|
|
||||||
|
|
||||||
if self._startup_config != startup_config or self._private_config != private_config:
|
|
||||||
self._startup_config = startup_config
|
|
||||||
self._private_config = private_config
|
|
||||||
|
|
||||||
if private_config:
|
|
||||||
private_config_path = os.path.join(self._working_directory, private_config)
|
|
||||||
try:
|
|
||||||
if not os.path.getsize(private_config_path):
|
|
||||||
# an empty private-config can prevent a router to boot.
|
|
||||||
private_config = ''
|
|
||||||
self._private_config_content = ""
|
|
||||||
else:
|
|
||||||
with open(private_config_path) as f:
|
|
||||||
self._private_config_content = f.read()
|
|
||||||
except OSError as e:
|
|
||||||
raise DynamipsError("Cannot access the private-config {}: {}".format(private_config_path, e))
|
|
||||||
|
|
||||||
try:
|
|
||||||
startup_config_path = os.path.join(self._working_directory, startup_config)
|
|
||||||
with open(startup_config_path) as f:
|
|
||||||
self._startup_config_content = f.read()
|
|
||||||
except OSError as e:
|
|
||||||
raise DynamipsError("Cannot access the startup-config {}: {}".format(startup_config_path, e))
|
|
||||||
|
|
||||||
yield from self._hypervisor.send('vm set_config "{name}" "{startup}" "{private}"'.format(name=self._name,
|
|
||||||
startup=startup_config,
|
|
||||||
private=private_config))
|
|
||||||
|
|
||||||
log.info('Router "{name}" [{id}]: has a new startup-config set: "{startup}"'.format(name=self._name,
|
|
||||||
id=self._id,
|
|
||||||
startup=startup_config))
|
|
||||||
|
|
||||||
if private_config:
|
|
||||||
log.info('Router "{name}" [{id}]: has a new private-config set: "{private}"'.format(name=self._name,
|
|
||||||
id=self._id,
|
|
||||||
private=private_config))
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def extract_config(self):
|
def extract_config(self):
|
||||||
"""
|
"""
|
||||||
@ -1594,41 +1521,35 @@ class Router(BaseNode):
|
|||||||
Saves the startup-config and private-config to files.
|
Saves the startup-config and private-config to files.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.startup_config or self.private_config:
|
try:
|
||||||
|
config_path = os.path.join(self._working_directory, "configs")
|
||||||
|
os.makedirs(config_path, exist_ok=True)
|
||||||
|
except OSError as e:
|
||||||
|
raise DynamipsError("Could could not create configuration directory {}: {}".format(config_path, e))
|
||||||
|
|
||||||
|
startup_config_base64, private_config_base64 = yield from self.extract_config()
|
||||||
|
if startup_config_base64:
|
||||||
|
startup_config = os.path.join("configs", "i{}_startup-config.cfg".format(self._dynamips_id))
|
||||||
try:
|
try:
|
||||||
config_path = os.path.join(self._working_directory, "configs")
|
config = base64.b64decode(startup_config_base64).decode("utf-8", errors="replace")
|
||||||
os.makedirs(config_path, exist_ok=True)
|
config = "!\n" + config.replace("\r", "")
|
||||||
except OSError as e:
|
config_path = os.path.join(self._working_directory, startup_config)
|
||||||
raise DynamipsError("Could could not create configuration directory {}: {}".format(config_path, e))
|
with open(config_path, "wb") as f:
|
||||||
|
log.info("saving startup-config to {}".format(startup_config))
|
||||||
|
f.write(config.encode("utf-8"))
|
||||||
|
except (binascii.Error, OSError) as e:
|
||||||
|
raise DynamipsError("Could not save the startup configuration {}: {}".format(config_path, e))
|
||||||
|
|
||||||
startup_config_base64, private_config_base64 = yield from self.extract_config()
|
if private_config_base64 and base64.b64decode(private_config_base64) != b'\nkerberos password \nend\n':
|
||||||
if startup_config_base64:
|
private_config = os.path.join("configs", "i{}_private-config.cfg".format(self._dynamips_id))
|
||||||
if not self.startup_config:
|
try:
|
||||||
self._startup_config = os.path.join("configs", "i{}_startup-config.cfg".format(self._dynamips_id))
|
config = base64.b64decode(private_config_base64).decode("utf-8", errors="replace")
|
||||||
try:
|
config_path = os.path.join(self._working_directory, private_config)
|
||||||
config = base64.b64decode(startup_config_base64).decode("utf-8", errors="replace")
|
with open(config_path, "wb") as f:
|
||||||
config = "!\n" + config.replace("\r", "")
|
log.info("saving private-config to {}".format(private_config))
|
||||||
config_path = os.path.join(self._working_directory, self.startup_config)
|
f.write(config.encode("utf-8"))
|
||||||
with open(config_path, "wb") as f:
|
except (binascii.Error, OSError) as e:
|
||||||
log.info("saving startup-config to {}".format(self.startup_config))
|
raise DynamipsError("Could not save the private configuration {}: {}".format(config_path, e))
|
||||||
self._startup_config_content = config
|
|
||||||
f.write(config.encode("utf-8"))
|
|
||||||
except (binascii.Error, OSError) as e:
|
|
||||||
raise DynamipsError("Could not save the startup configuration {}: {}".format(config_path, e))
|
|
||||||
|
|
||||||
if private_config_base64 and base64.b64decode(private_config_base64) != b'\nkerberos password \nend\n':
|
|
||||||
if not self.private_config:
|
|
||||||
self._private_config = os.path.join("configs", "i{}_private-config.cfg".format(self._dynamips_id))
|
|
||||||
try:
|
|
||||||
config = base64.b64decode(private_config_base64).decode("utf-8", errors="replace")
|
|
||||||
config_path = os.path.join(self._working_directory, self.private_config)
|
|
||||||
with open(config_path, "wb") as f:
|
|
||||||
log.info("saving private-config to {}".format(self.private_config))
|
|
||||||
self._private_config_content = config
|
|
||||||
f.write(config.encode("utf-8"))
|
|
||||||
except (binascii.Error, OSError) as e:
|
|
||||||
raise DynamipsError("Could not save the private configuration {}: {}".format(config_path, e))
|
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
"""
|
"""
|
||||||
|
@ -26,8 +26,6 @@ import re
|
|||||||
import asyncio
|
import asyncio
|
||||||
import subprocess
|
import subprocess
|
||||||
import shutil
|
import shutil
|
||||||
import argparse
|
|
||||||
import threading
|
|
||||||
import configparser
|
import configparser
|
||||||
import struct
|
import struct
|
||||||
import hashlib
|
import hashlib
|
||||||
@ -207,10 +205,6 @@ class IOUVM(BaseNode):
|
|||||||
"ram": self._ram,
|
"ram": self._ram,
|
||||||
"nvram": self._nvram,
|
"nvram": self._nvram,
|
||||||
"l1_keepalives": self._l1_keepalives,
|
"l1_keepalives": self._l1_keepalives,
|
||||||
"startup_config": self.relative_startup_config_file,
|
|
||||||
"startup_config_content": self.startup_config_content,
|
|
||||||
"private_config_content": self.private_config_content,
|
|
||||||
"private_config": self.relative_private_config_file,
|
|
||||||
"use_default_iou_values": self._use_default_iou_values,
|
"use_default_iou_values": self._use_default_iou_values,
|
||||||
"command_line": self.command_line}
|
"command_line": self.command_line}
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ class VPCSVM(BaseNode):
|
|||||||
raise VPCSError("No path to a VPCS executable has been set")
|
raise VPCSError("No path to a VPCS executable has been set")
|
||||||
|
|
||||||
# This raise an error if ubridge is not available
|
# This raise an error if ubridge is not available
|
||||||
ubridge_path = self.ubridge_path
|
self.ubridge_path
|
||||||
|
|
||||||
if not os.path.isfile(path):
|
if not os.path.isfile(path):
|
||||||
raise VPCSError("VPCS program '{}' is not accessible".format(path))
|
raise VPCSError("VPCS program '{}' is not accessible".format(path))
|
||||||
@ -128,8 +128,6 @@ class VPCSVM(BaseNode):
|
|||||||
"console": self._console,
|
"console": self._console,
|
||||||
"console_type": "telnet",
|
"console_type": "telnet",
|
||||||
"project_id": self.project.id,
|
"project_id": self.project.id,
|
||||||
"startup_script": self.startup_script,
|
|
||||||
"startup_script_path": self.relative_startup_script,
|
|
||||||
"command_line": self.command_line}
|
"command_line": self.command_line}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
26
gns3server/configs/ios_base_startup-config.txt
Normal file
26
gns3server/configs/ios_base_startup-config.txt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
!
|
||||||
|
service timestamps debug datetime msec
|
||||||
|
service timestamps log datetime msec
|
||||||
|
no service password-encryption
|
||||||
|
!
|
||||||
|
hostname %h
|
||||||
|
!
|
||||||
|
ip cef
|
||||||
|
no ip domain-lookup
|
||||||
|
no ip icmp rate-limit unreachable
|
||||||
|
ip tcp synwait 5
|
||||||
|
no cdp log mismatch duplex
|
||||||
|
!
|
||||||
|
line con 0
|
||||||
|
exec-timeout 0 0
|
||||||
|
logging synchronous
|
||||||
|
privilege level 15
|
||||||
|
no login
|
||||||
|
line aux 0
|
||||||
|
exec-timeout 0 0
|
||||||
|
logging synchronous
|
||||||
|
privilege level 15
|
||||||
|
no login
|
||||||
|
!
|
||||||
|
!
|
||||||
|
end
|
181
gns3server/configs/ios_etherswitch_startup-config.txt
Normal file
181
gns3server/configs/ios_etherswitch_startup-config.txt
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
!
|
||||||
|
service timestamps debug datetime msec
|
||||||
|
service timestamps log datetime msec
|
||||||
|
no service password-encryption
|
||||||
|
no service dhcp
|
||||||
|
!
|
||||||
|
hostname %h
|
||||||
|
!
|
||||||
|
ip cef
|
||||||
|
no ip routing
|
||||||
|
no ip domain-lookup
|
||||||
|
no ip icmp rate-limit unreachable
|
||||||
|
ip tcp synwait 5
|
||||||
|
no cdp log mismatch duplex
|
||||||
|
vtp file nvram:vlan.dat
|
||||||
|
!
|
||||||
|
!
|
||||||
|
interface FastEthernet0/0
|
||||||
|
description *** Unused for Layer2 EtherSwitch ***
|
||||||
|
no ip address
|
||||||
|
shutdown
|
||||||
|
!
|
||||||
|
interface FastEthernet0/1
|
||||||
|
description *** Unused for Layer2 EtherSwitch ***
|
||||||
|
no ip address
|
||||||
|
shutdown
|
||||||
|
!
|
||||||
|
interface FastEthernet1/0
|
||||||
|
no shutdown
|
||||||
|
duplex full
|
||||||
|
speed 100
|
||||||
|
!
|
||||||
|
interface FastEthernet1/1
|
||||||
|
no shutdown
|
||||||
|
duplex full
|
||||||
|
speed 100
|
||||||
|
!
|
||||||
|
interface FastEthernet1/2
|
||||||
|
no shutdown
|
||||||
|
duplex full
|
||||||
|
speed 100
|
||||||
|
!
|
||||||
|
interface FastEthernet1/3
|
||||||
|
no shutdown
|
||||||
|
duplex full
|
||||||
|
speed 100
|
||||||
|
!
|
||||||
|
interface FastEthernet1/4
|
||||||
|
no shutdown
|
||||||
|
duplex full
|
||||||
|
speed 100
|
||||||
|
!
|
||||||
|
interface FastEthernet1/5
|
||||||
|
no shutdown
|
||||||
|
duplex full
|
||||||
|
speed 100
|
||||||
|
!
|
||||||
|
interface FastEthernet1/6
|
||||||
|
no shutdown
|
||||||
|
duplex full
|
||||||
|
speed 100
|
||||||
|
!
|
||||||
|
interface FastEthernet1/7
|
||||||
|
no shutdown
|
||||||
|
duplex full
|
||||||
|
speed 100
|
||||||
|
!
|
||||||
|
interface FastEthernet1/8
|
||||||
|
no shutdown
|
||||||
|
duplex full
|
||||||
|
speed 100
|
||||||
|
!
|
||||||
|
interface FastEthernet1/9
|
||||||
|
no shutdown
|
||||||
|
duplex full
|
||||||
|
speed 100
|
||||||
|
!
|
||||||
|
interface FastEthernet1/10
|
||||||
|
no shutdown
|
||||||
|
duplex full
|
||||||
|
speed 100
|
||||||
|
!
|
||||||
|
interface FastEthernet1/11
|
||||||
|
no shutdown
|
||||||
|
duplex full
|
||||||
|
speed 100
|
||||||
|
!
|
||||||
|
interface FastEthernet1/12
|
||||||
|
no shutdown
|
||||||
|
duplex full
|
||||||
|
speed 100
|
||||||
|
!
|
||||||
|
interface FastEthernet1/13
|
||||||
|
no shutdown
|
||||||
|
duplex full
|
||||||
|
speed 100
|
||||||
|
!
|
||||||
|
interface FastEthernet1/14
|
||||||
|
no shutdown
|
||||||
|
duplex full
|
||||||
|
speed 100
|
||||||
|
!
|
||||||
|
interface FastEthernet1/15
|
||||||
|
no shutdown
|
||||||
|
duplex full
|
||||||
|
speed 100
|
||||||
|
!
|
||||||
|
interface Vlan1
|
||||||
|
no ip address
|
||||||
|
shutdown
|
||||||
|
!
|
||||||
|
!
|
||||||
|
line con 0
|
||||||
|
exec-timeout 0 0
|
||||||
|
logging synchronous
|
||||||
|
privilege level 15
|
||||||
|
no login
|
||||||
|
line aux 0
|
||||||
|
exec-timeout 0 0
|
||||||
|
logging synchronous
|
||||||
|
privilege level 15
|
||||||
|
no login
|
||||||
|
!
|
||||||
|
!
|
||||||
|
banner exec $
|
||||||
|
|
||||||
|
***************************************************************
|
||||||
|
This is a normal Router with a SW module inside (NM-16ESW)
|
||||||
|
It has been preconfigured with hard coded speed and duplex
|
||||||
|
|
||||||
|
To create vlans use the command "vlan database" from exec mode
|
||||||
|
After creating all desired vlans use "exit" to apply the config
|
||||||
|
|
||||||
|
To view existing vlans use the command "show vlan-switch brief"
|
||||||
|
|
||||||
|
Warning: You are using an old IOS image for this router.
|
||||||
|
Please update the IOS to enable the "macro" command!
|
||||||
|
***************************************************************
|
||||||
|
|
||||||
|
$
|
||||||
|
!
|
||||||
|
!Warning: If the IOS is old and doesn't support macro, it will stop the configuration loading from this point!
|
||||||
|
!
|
||||||
|
macro name add_vlan
|
||||||
|
end
|
||||||
|
vlan database
|
||||||
|
vlan $v
|
||||||
|
exit
|
||||||
|
@
|
||||||
|
macro name del_vlan
|
||||||
|
end
|
||||||
|
vlan database
|
||||||
|
no vlan $v
|
||||||
|
exit
|
||||||
|
@
|
||||||
|
!
|
||||||
|
!
|
||||||
|
banner exec $
|
||||||
|
|
||||||
|
***************************************************************
|
||||||
|
This is a normal Router with a Switch module inside (NM-16ESW)
|
||||||
|
It has been pre-configured with hard-coded speed and duplex
|
||||||
|
|
||||||
|
To create vlans use the command "vlan database" in exec mode
|
||||||
|
After creating all desired vlans use "exit" to apply the config
|
||||||
|
|
||||||
|
To view existing vlans use the command "show vlan-switch brief"
|
||||||
|
|
||||||
|
Alias(exec) : vl - "show vlan-switch brief" command
|
||||||
|
Alias(configure): va X - macro to add vlan X
|
||||||
|
Alias(configure): vd X - macro to delete vlan X
|
||||||
|
***************************************************************
|
||||||
|
|
||||||
|
$
|
||||||
|
!
|
||||||
|
alias configure va macro global trace add_vlan $v
|
||||||
|
alias configure vd macro global trace del_vlan $v
|
||||||
|
alias exec vl show vlan-switch brief
|
||||||
|
!
|
||||||
|
!
|
||||||
|
end
|
132
gns3server/configs/iou_l2_base_startup-config.txt
Normal file
132
gns3server/configs/iou_l2_base_startup-config.txt
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
!
|
||||||
|
service timestamps debug datetime msec
|
||||||
|
service timestamps log datetime msec
|
||||||
|
no service password-encryption
|
||||||
|
!
|
||||||
|
hostname %h
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
logging discriminator EXCESS severity drops 6 msg-body drops EXCESSCOLL
|
||||||
|
logging buffered 50000
|
||||||
|
logging console discriminator EXCESS
|
||||||
|
!
|
||||||
|
no ip icmp rate-limit unreachable
|
||||||
|
!
|
||||||
|
ip cef
|
||||||
|
no ip domain-lookup
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
ip tcp synwait-time 5
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
interface Ethernet0/0
|
||||||
|
no ip address
|
||||||
|
no shutdown
|
||||||
|
duplex auto
|
||||||
|
!
|
||||||
|
interface Ethernet0/1
|
||||||
|
no ip address
|
||||||
|
no shutdown
|
||||||
|
duplex auto
|
||||||
|
!
|
||||||
|
interface Ethernet0/2
|
||||||
|
no ip address
|
||||||
|
no shutdown
|
||||||
|
duplex auto
|
||||||
|
!
|
||||||
|
interface Ethernet0/3
|
||||||
|
no ip address
|
||||||
|
no shutdown
|
||||||
|
duplex auto
|
||||||
|
!
|
||||||
|
interface Ethernet1/0
|
||||||
|
no ip address
|
||||||
|
no shutdown
|
||||||
|
duplex auto
|
||||||
|
!
|
||||||
|
interface Ethernet1/1
|
||||||
|
no ip address
|
||||||
|
no shutdown
|
||||||
|
duplex auto
|
||||||
|
!
|
||||||
|
interface Ethernet1/2
|
||||||
|
no ip address
|
||||||
|
no shutdown
|
||||||
|
duplex auto
|
||||||
|
!
|
||||||
|
interface Ethernet1/3
|
||||||
|
no ip address
|
||||||
|
no shutdown
|
||||||
|
duplex auto
|
||||||
|
!
|
||||||
|
interface Ethernet2/0
|
||||||
|
no ip address
|
||||||
|
no shutdown
|
||||||
|
duplex auto
|
||||||
|
!
|
||||||
|
interface Ethernet2/1
|
||||||
|
no ip address
|
||||||
|
no shutdown
|
||||||
|
duplex auto
|
||||||
|
!
|
||||||
|
interface Ethernet2/2
|
||||||
|
no ip address
|
||||||
|
no shutdown
|
||||||
|
duplex auto
|
||||||
|
!
|
||||||
|
interface Ethernet2/3
|
||||||
|
no ip address
|
||||||
|
no shutdown
|
||||||
|
duplex auto
|
||||||
|
!
|
||||||
|
interface Ethernet3/0
|
||||||
|
no ip address
|
||||||
|
no shutdown
|
||||||
|
duplex auto
|
||||||
|
!
|
||||||
|
interface Ethernet3/1
|
||||||
|
no ip address
|
||||||
|
no shutdown
|
||||||
|
duplex auto
|
||||||
|
!
|
||||||
|
interface Ethernet3/2
|
||||||
|
no ip address
|
||||||
|
no shutdown
|
||||||
|
duplex auto
|
||||||
|
!
|
||||||
|
interface Ethernet3/3
|
||||||
|
no ip address
|
||||||
|
no shutdown
|
||||||
|
duplex auto
|
||||||
|
!
|
||||||
|
interface Vlan1
|
||||||
|
no ip address
|
||||||
|
shutdown
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
line con 0
|
||||||
|
exec-timeout 0 0
|
||||||
|
privilege level 15
|
||||||
|
logging synchronous
|
||||||
|
line aux 0
|
||||||
|
exec-timeout 0 0
|
||||||
|
privilege level 15
|
||||||
|
logging synchronous
|
||||||
|
!
|
||||||
|
end
|
108
gns3server/configs/iou_l3_base_startup-config.txt
Normal file
108
gns3server/configs/iou_l3_base_startup-config.txt
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
!
|
||||||
|
service timestamps debug datetime msec
|
||||||
|
service timestamps log datetime msec
|
||||||
|
no service password-encryption
|
||||||
|
!
|
||||||
|
hostname %h
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
no ip icmp rate-limit unreachable
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
ip cef
|
||||||
|
no ip domain-lookup
|
||||||
|
!
|
||||||
|
!
|
||||||
|
ip tcp synwait-time 5
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!
|
||||||
|
interface Ethernet0/0
|
||||||
|
no ip address
|
||||||
|
shutdown
|
||||||
|
!
|
||||||
|
interface Ethernet0/1
|
||||||
|
no ip address
|
||||||
|
shutdown
|
||||||
|
!
|
||||||
|
interface Ethernet0/2
|
||||||
|
no ip address
|
||||||
|
shutdown
|
||||||
|
!
|
||||||
|
interface Ethernet0/3
|
||||||
|
no ip address
|
||||||
|
shutdown
|
||||||
|
!
|
||||||
|
interface Ethernet1/0
|
||||||
|
no ip address
|
||||||
|
shutdown
|
||||||
|
!
|
||||||
|
interface Ethernet1/1
|
||||||
|
no ip address
|
||||||
|
shutdown
|
||||||
|
!
|
||||||
|
interface Ethernet1/2
|
||||||
|
no ip address
|
||||||
|
shutdown
|
||||||
|
!
|
||||||
|
interface Ethernet1/3
|
||||||
|
no ip address
|
||||||
|
shutdown
|
||||||
|
!
|
||||||
|
interface Serial2/0
|
||||||
|
no ip address
|
||||||
|
shutdown
|
||||||
|
serial restart-delay 0
|
||||||
|
!
|
||||||
|
interface Serial2/1
|
||||||
|
no ip address
|
||||||
|
shutdown
|
||||||
|
serial restart-delay 0
|
||||||
|
!
|
||||||
|
interface Serial2/2
|
||||||
|
no ip address
|
||||||
|
shutdown
|
||||||
|
serial restart-delay 0
|
||||||
|
!
|
||||||
|
interface Serial2/3
|
||||||
|
no ip address
|
||||||
|
shutdown
|
||||||
|
serial restart-delay 0
|
||||||
|
!
|
||||||
|
interface Serial3/0
|
||||||
|
no ip address
|
||||||
|
shutdown
|
||||||
|
serial restart-delay 0
|
||||||
|
!
|
||||||
|
interface Serial3/1
|
||||||
|
no ip address
|
||||||
|
shutdown
|
||||||
|
serial restart-delay 0
|
||||||
|
!
|
||||||
|
interface Serial3/2
|
||||||
|
no ip address
|
||||||
|
shutdown
|
||||||
|
serial restart-delay 0
|
||||||
|
!
|
||||||
|
interface Serial3/3
|
||||||
|
no ip address
|
||||||
|
shutdown
|
||||||
|
serial restart-delay 0
|
||||||
|
!
|
||||||
|
!
|
||||||
|
no cdp log mismatch duplex
|
||||||
|
!
|
||||||
|
line con 0
|
||||||
|
exec-timeout 0 0
|
||||||
|
privilege level 15
|
||||||
|
logging synchronous
|
||||||
|
line aux 0
|
||||||
|
exec-timeout 0 0
|
||||||
|
privilege level 15
|
||||||
|
logging synchronous
|
||||||
|
!
|
||||||
|
end
|
1
gns3server/configs/vpcs_base_config.txt
Normal file
1
gns3server/configs/vpcs_base_config.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
set pcname %h
|
@ -16,9 +16,9 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
import json
|
import json
|
||||||
import socket
|
import socket
|
||||||
|
import shutil
|
||||||
import asyncio
|
import asyncio
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ from .symbols import Symbols
|
|||||||
from ..version import __version__
|
from ..version import __version__
|
||||||
from .topology import load_topology
|
from .topology import load_topology
|
||||||
from .gns3vm import GNS3VM
|
from .gns3vm import GNS3VM
|
||||||
|
from ..utils.get_resource import get_resource
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -54,6 +54,7 @@ class Controller:
|
|||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def start(self):
|
def start(self):
|
||||||
log.info("Start controller")
|
log.info("Start controller")
|
||||||
|
self.load_base_files()
|
||||||
yield from self.load()
|
yield from self.load()
|
||||||
server_config = Config.instance().get_section_config("Server")
|
server_config = Config.instance().get_section_config("Server")
|
||||||
host = server_config.get("host", "localhost")
|
host = server_config.get("host", "localhost")
|
||||||
@ -163,6 +164,20 @@ class Controller:
|
|||||||
except OSError as e:
|
except OSError as e:
|
||||||
log.error(str(e))
|
log.error(str(e))
|
||||||
|
|
||||||
|
def load_base_files(self):
|
||||||
|
"""
|
||||||
|
At startup we copy base file to the user location to allow
|
||||||
|
them to customize it
|
||||||
|
"""
|
||||||
|
dst_path = self.configs_path()
|
||||||
|
src_path = get_resource('configs')
|
||||||
|
try:
|
||||||
|
for file in os.listdir(src_path):
|
||||||
|
if not os.path.exists(os.path.join(dst_path, file)):
|
||||||
|
shutil.copy(os.path.join(src_path, file), os.path.join(dst_path, file))
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
def images_path(self):
|
def images_path(self):
|
||||||
"""
|
"""
|
||||||
Get the image storage directory
|
Get the image storage directory
|
||||||
@ -172,6 +187,15 @@ class Controller:
|
|||||||
os.makedirs(images_path, exist_ok=True)
|
os.makedirs(images_path, exist_ok=True)
|
||||||
return images_path
|
return images_path
|
||||||
|
|
||||||
|
def configs_path(self):
|
||||||
|
"""
|
||||||
|
Get the configs storage directory
|
||||||
|
"""
|
||||||
|
server_config = Config.instance().get_section_config("Server")
|
||||||
|
images_path = os.path.expanduser(server_config.get("configs_path", "~/GNS3/projects"))
|
||||||
|
os.makedirs(images_path, exist_ok=True)
|
||||||
|
return images_path
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def _import_gns3_gui_conf(self):
|
def _import_gns3_gui_conf(self):
|
||||||
"""
|
"""
|
||||||
|
@ -146,6 +146,15 @@ class Node:
|
|||||||
def properties(self, val):
|
def properties(self, val):
|
||||||
self._properties = val
|
self._properties = val
|
||||||
|
|
||||||
|
def _base_config_file_content(self, path):
|
||||||
|
if not os.path.isabs(path):
|
||||||
|
path = os.path.join(self.project.controller.configs_path(), path)
|
||||||
|
try:
|
||||||
|
with open(path) as f:
|
||||||
|
return f.read()
|
||||||
|
except (PermissionError, OSError):
|
||||||
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def project(self):
|
def project(self):
|
||||||
return self._project
|
return self._project
|
||||||
@ -366,8 +375,12 @@ class Node:
|
|||||||
self._console_type = value
|
self._console_type = value
|
||||||
elif key == "name":
|
elif key == "name":
|
||||||
self.name = value
|
self.name = value
|
||||||
elif key in ["node_id", "project_id", "console_host"]:
|
elif key in ["node_id", "project_id", "console_host",
|
||||||
pass
|
"startup_config_content",
|
||||||
|
"private_config_content",
|
||||||
|
"startup_script"]:
|
||||||
|
if key in self._properties:
|
||||||
|
del self._properties[key]
|
||||||
else:
|
else:
|
||||||
self._properties[key] = value
|
self._properties[key] = value
|
||||||
self._list_ports()
|
self._list_ports()
|
||||||
@ -384,6 +397,17 @@ class Node:
|
|||||||
data = copy.copy(properties)
|
data = copy.copy(properties)
|
||||||
else:
|
else:
|
||||||
data = copy.copy(self._properties)
|
data = copy.copy(self._properties)
|
||||||
|
# We replace the startup script name by the content of the file
|
||||||
|
mapping = {
|
||||||
|
"base_script_file": "startup_script",
|
||||||
|
"startup_config": "startup_config_content",
|
||||||
|
"private_config": "private_config_content",
|
||||||
|
}
|
||||||
|
for k, v in mapping.items():
|
||||||
|
if k in list(self._properties.keys()):
|
||||||
|
data[v] = self._base_config_file_content(self._properties[k])
|
||||||
|
del data[k]
|
||||||
|
del self._properties[k] # We send the file only one time
|
||||||
data["name"] = self._name
|
data["name"] = self._name
|
||||||
if self._console:
|
if self._console:
|
||||||
# console is optional for builtin nodes
|
# console is optional for builtin nodes
|
||||||
@ -585,17 +609,6 @@ class Node:
|
|||||||
return False
|
return False
|
||||||
return self.id == other.id and other.project.id == self.project.id
|
return self.id == other.id and other.project.id == self.project.id
|
||||||
|
|
||||||
def _filter_properties(self):
|
|
||||||
"""
|
|
||||||
Some properties are private and should not be exposed
|
|
||||||
"""
|
|
||||||
PRIVATE_PROPERTIES = ("iourc_content", )
|
|
||||||
prop = copy.copy(self._properties)
|
|
||||||
for k in list(prop.keys()):
|
|
||||||
if k in PRIVATE_PROPERTIES:
|
|
||||||
del prop[k]
|
|
||||||
return prop
|
|
||||||
|
|
||||||
def __json__(self, topology_dump=False):
|
def __json__(self, topology_dump=False):
|
||||||
"""
|
"""
|
||||||
:param topology_dump: Filter to keep only properties require for saving on disk
|
:param topology_dump: Filter to keep only properties require for saving on disk
|
||||||
@ -608,7 +621,7 @@ class Node:
|
|||||||
"name": self._name,
|
"name": self._name,
|
||||||
"console": self._console,
|
"console": self._console,
|
||||||
"console_type": self._console_type,
|
"console_type": self._console_type,
|
||||||
"properties": self._filter_properties(),
|
"properties": self._properties,
|
||||||
"label": self._label,
|
"label": self._label,
|
||||||
"x": self._x,
|
"x": self._x,
|
||||||
"y": self._y,
|
"y": self._y,
|
||||||
@ -631,7 +644,7 @@ class Node:
|
|||||||
"console_host": str(self._compute.console_host),
|
"console_host": str(self._compute.console_host),
|
||||||
"console_type": self._console_type,
|
"console_type": self._console_type,
|
||||||
"command_line": self._command_line,
|
"command_line": self._command_line,
|
||||||
"properties": self._filter_properties(),
|
"properties": self._properties,
|
||||||
"status": self._status,
|
"status": self._status,
|
||||||
"label": self._label,
|
"label": self._label,
|
||||||
"x": self._x,
|
"x": self._x,
|
||||||
|
@ -36,7 +36,7 @@ import logging
|
|||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
GNS3_FILE_FORMAT_REVISION = 7
|
GNS3_FILE_FORMAT_REVISION = 8
|
||||||
|
|
||||||
|
|
||||||
def _check_topology_schema(topo):
|
def _check_topology_schema(topo):
|
||||||
@ -138,6 +138,10 @@ def load_topology(path):
|
|||||||
if topo["revision"] < 7:
|
if topo["revision"] < 7:
|
||||||
topo = _convert_2_0_0_beta_2(topo, path)
|
topo = _convert_2_0_0_beta_2(topo, path)
|
||||||
|
|
||||||
|
# Version before GNS3 2.1
|
||||||
|
if topo["revision"] < 8:
|
||||||
|
topo = _convert_2_0_0(topo, path)
|
||||||
|
|
||||||
_check_topology_schema(topo)
|
_check_topology_schema(topo)
|
||||||
|
|
||||||
if changed:
|
if changed:
|
||||||
@ -146,6 +150,34 @@ def load_topology(path):
|
|||||||
return topo
|
return topo
|
||||||
|
|
||||||
|
|
||||||
|
def _convert_2_0_0(topo, topo_path):
|
||||||
|
"""
|
||||||
|
Convert topologies from GNS3 2.0.0 to 2.1
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
* Remove startup_script_path from VPCS and base config file for IOU and Dynamips
|
||||||
|
"""
|
||||||
|
topo["revision"] = 8
|
||||||
|
|
||||||
|
for node in topo.get("topology", {}).get("nodes", []):
|
||||||
|
if "properties" in node:
|
||||||
|
if node["node_type"] == "vpcs":
|
||||||
|
if "startup_script_path" in node["properties"]:
|
||||||
|
del node["properties"]["startup_script_path"]
|
||||||
|
if "startup_script" in node["properties"]:
|
||||||
|
del node["properties"]["startup_script"]
|
||||||
|
elif node["node_type"] == "dynamips" or node["node_type"] == "iou":
|
||||||
|
if "startup_config" in node["properties"]:
|
||||||
|
del node["properties"]["startup_config"]
|
||||||
|
if "private_config" in node["properties"]:
|
||||||
|
del node["properties"]["private_config"]
|
||||||
|
if "startup_config_content" in node["properties"]:
|
||||||
|
del node["properties"]["startup_config_content"]
|
||||||
|
if "private_config_content" in node["properties"]:
|
||||||
|
del node["properties"]["private_config_content"]
|
||||||
|
return topo
|
||||||
|
|
||||||
|
|
||||||
def _convert_2_0_0_beta_2(topo, topo_path):
|
def _convert_2_0_0_beta_2(topo, topo_path):
|
||||||
"""
|
"""
|
||||||
Convert topologies from GNS3 2.0.0 beta 2 to beta 3.
|
Convert topologies from GNS3 2.0.0 beta 2 to beta 3.
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import base64
|
|
||||||
|
|
||||||
from gns3server.web.route import Route
|
from gns3server.web.route import Route
|
||||||
from gns3server.schemas.nio import NIO_SCHEMA
|
from gns3server.schemas.nio import NIO_SCHEMA
|
||||||
@ -78,7 +77,6 @@ class DynamipsVMHandler:
|
|||||||
aux=request.json.get("aux"),
|
aux=request.json.get("aux"),
|
||||||
chassis=request.json.pop("chassis", default_chassis),
|
chassis=request.json.pop("chassis", default_chassis),
|
||||||
node_type="dynamips")
|
node_type="dynamips")
|
||||||
|
|
||||||
yield from dynamips_manager.update_vm_settings(vm, request.json)
|
yield from dynamips_manager.update_vm_settings(vm, request.json)
|
||||||
response.set_status(201)
|
response.set_status(201)
|
||||||
response.json(vm)
|
response.json(vm)
|
||||||
|
@ -344,10 +344,7 @@ class NodeHandler:
|
|||||||
raise aiohttp.web.HTTPForbidden
|
raise aiohttp.web.HTTPForbidden
|
||||||
|
|
||||||
node_type = node.node_type
|
node_type = node.node_type
|
||||||
if node_type == "dynamips":
|
path = "/project-files/{}/{}/{}".format(node_type, node.id, path)
|
||||||
path = "/project-files/{}/{}".format(node_type, path)
|
|
||||||
else:
|
|
||||||
path = "/project-files/{}/{}/{}".format(node_type, node.id, path)
|
|
||||||
|
|
||||||
res = yield from node.compute.http_query("GET", "/projects/{project_id}/files{path}".format(project_id=project.id, path=path), timeout=None, raw=True)
|
res = yield from node.compute.http_query("GET", "/projects/{project_id}/files{path}".format(project_id=project.id, path=path), timeout=None, raw=True)
|
||||||
response.set_status(200)
|
response.set_status(200)
|
||||||
@ -384,12 +381,9 @@ class NodeHandler:
|
|||||||
raise aiohttp.web.HTTPForbidden
|
raise aiohttp.web.HTTPForbidden
|
||||||
|
|
||||||
node_type = node.node_type
|
node_type = node.node_type
|
||||||
if node_type == "dynamips":
|
path = "/project-files/{}/{}/{}".format(node_type, node.id, path)
|
||||||
path = "/project-files/{}/{}".format(node_type, path)
|
|
||||||
else:
|
|
||||||
path = "/project-files/{}/{}/{}".format(node_type, node.id, path)
|
|
||||||
|
|
||||||
data = yield from request.content.read()
|
data = yield from request.content.read()
|
||||||
|
|
||||||
res = yield from node.compute.http_query("POST", "/projects/{project_id}/files{path}".format(project_id=project.id, path=path), data=data, timeout=None, raw=True)
|
yield from node.compute.http_query("POST", "/projects/{project_id}/files{path}".format(project_id=project.id, path=path), data=data, timeout=None, raw=True)
|
||||||
response.set_status(201)
|
response.set_status(201)
|
||||||
|
@ -62,18 +62,10 @@ VM_CREATE_SCHEMA = {
|
|||||||
"type": ["string", "null"],
|
"type": ["string", "null"],
|
||||||
"minLength": 1,
|
"minLength": 1,
|
||||||
},
|
},
|
||||||
"startup_config": {
|
|
||||||
"description": "Path to the IOS startup configuration file",
|
|
||||||
"type": "string",
|
|
||||||
},
|
|
||||||
"startup_config_content": {
|
"startup_config_content": {
|
||||||
"description": "Content of IOS startup configuration file",
|
"description": "Content of IOS startup configuration file",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
},
|
},
|
||||||
"private_config": {
|
|
||||||
"description": "Path to the IOS private configuration file",
|
|
||||||
"type": "string",
|
|
||||||
},
|
|
||||||
"private_config_content": {
|
"private_config_content": {
|
||||||
"description": "Content of IOS private configuration file",
|
"description": "Content of IOS private configuration file",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@ -296,22 +288,6 @@ VM_UPDATE_SCHEMA = {
|
|||||||
"description": "Dynamips ID",
|
"description": "Dynamips ID",
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"startup_config": {
|
|
||||||
"description": "Path to the IOS startup configuration file.",
|
|
||||||
"type": "string",
|
|
||||||
},
|
|
||||||
"private_config": {
|
|
||||||
"description": "Path to the IOS private configuration file.",
|
|
||||||
"type": "string",
|
|
||||||
},
|
|
||||||
"startup_config_content": {
|
|
||||||
"description": "Content of IOS startup configuration file",
|
|
||||||
"type": "string",
|
|
||||||
},
|
|
||||||
"private_config_content": {
|
|
||||||
"description": "Content of IOS private configuration file",
|
|
||||||
"type": "string",
|
|
||||||
},
|
|
||||||
"ram": {
|
"ram": {
|
||||||
"description": "Amount of RAM in MB",
|
"description": "Amount of RAM in MB",
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
@ -552,14 +528,6 @@ VM_OBJECT_SCHEMA = {
|
|||||||
"type": ["string", "null"],
|
"type": ["string", "null"],
|
||||||
"minLength": 1,
|
"minLength": 1,
|
||||||
},
|
},
|
||||||
"startup_config": {
|
|
||||||
"description": "Path to the IOS startup configuration file",
|
|
||||||
"type": "string",
|
|
||||||
},
|
|
||||||
"private_config": {
|
|
||||||
"description": "Path to the IOS private configuration file",
|
|
||||||
"type": "string",
|
|
||||||
},
|
|
||||||
"ram": {
|
"ram": {
|
||||||
"description": "Amount of RAM in MB",
|
"description": "Amount of RAM in MB",
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
@ -706,14 +674,6 @@ VM_OBJECT_SCHEMA = {
|
|||||||
{"type": "null"}
|
{"type": "null"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"startup_config_content": {
|
|
||||||
"description": "Content of IOS startup configuration file",
|
|
||||||
"type": "string",
|
|
||||||
},
|
|
||||||
"private_config_content": {
|
|
||||||
"description": "Content of IOS private configuration file",
|
|
||||||
"type": "string",
|
|
||||||
},
|
|
||||||
# C7200 properties
|
# C7200 properties
|
||||||
"npe": {
|
"npe": {
|
||||||
"description": "NPE model",
|
"description": "NPE model",
|
||||||
|
@ -78,14 +78,6 @@ IOU_CREATE_SCHEMA = {
|
|||||||
"description": "Use default IOU values",
|
"description": "Use default IOU values",
|
||||||
"type": ["boolean", "null"]
|
"type": ["boolean", "null"]
|
||||||
},
|
},
|
||||||
"startup_config": {
|
|
||||||
"description": "Path to the startup-config of IOU",
|
|
||||||
"type": ["string", "null"]
|
|
||||||
},
|
|
||||||
"private_config": {
|
|
||||||
"description": "Path to the private-config of IOU",
|
|
||||||
"type": ["string", "null"]
|
|
||||||
},
|
|
||||||
"startup_config_content": {
|
"startup_config_content": {
|
||||||
"description": "Startup-config of IOU",
|
"description": "Startup-config of IOU",
|
||||||
"type": ["string", "null"]
|
"type": ["string", "null"]
|
||||||
@ -94,10 +86,6 @@ IOU_CREATE_SCHEMA = {
|
|||||||
"description": "Private-config of IOU",
|
"description": "Private-config of IOU",
|
||||||
"type": ["string", "null"]
|
"type": ["string", "null"]
|
||||||
},
|
},
|
||||||
"iourc_content": {
|
|
||||||
"description": "Content of the iourc file. Ignored if Null",
|
|
||||||
"type": ["string", "null"]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"additionalProperties": False,
|
"additionalProperties": False,
|
||||||
"required": ["name", "path"]
|
"required": ["name", "path"]
|
||||||
@ -187,30 +175,10 @@ IOU_OBJECT_SCHEMA = {
|
|||||||
"description": "Always up ethernet interface",
|
"description": "Always up ethernet interface",
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"startup_config": {
|
|
||||||
"description": "Path of the startup-config content relative to project directory",
|
|
||||||
"type": ["string", "null"]
|
|
||||||
},
|
|
||||||
"private_config": {
|
|
||||||
"description": "Path of the private-config content relative to project directory",
|
|
||||||
"type": ["string", "null"]
|
|
||||||
},
|
|
||||||
"use_default_iou_values": {
|
"use_default_iou_values": {
|
||||||
"description": "Use default IOU values",
|
"description": "Use default IOU values",
|
||||||
"type": ["boolean", "null"]
|
"type": ["boolean", "null"]
|
||||||
},
|
},
|
||||||
"startup_config_content": {
|
|
||||||
"description": "Startup-config of IOU",
|
|
||||||
"type": ["string", "null"]
|
|
||||||
},
|
|
||||||
"private_config_content": {
|
|
||||||
"description": "Private-config of IOU",
|
|
||||||
"type": ["string", "null"]
|
|
||||||
},
|
|
||||||
"iourc_content": {
|
|
||||||
"description": "Content of the iourc file. Ignored if Null",
|
|
||||||
"type": ["string", "null"]
|
|
||||||
},
|
|
||||||
"command_line": {
|
"command_line": {
|
||||||
"description": "Last command line used by GNS3 to start QEMU",
|
"description": "Last command line used by GNS3 to start QEMU",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
@ -50,10 +50,6 @@ VPCS_CREATE_SCHEMA = {
|
|||||||
"description": "Content of the VPCS startup script",
|
"description": "Content of the VPCS startup script",
|
||||||
"type": ["string", "null"]
|
"type": ["string", "null"]
|
||||||
},
|
},
|
||||||
"startup_script_path": {
|
|
||||||
"description": "Path of the VPCS startup script relative to project directory (IGNORED)",
|
|
||||||
"type": ["string", "null"]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"additionalProperties": False,
|
"additionalProperties": False,
|
||||||
"required": ["name"]
|
"required": ["name"]
|
||||||
@ -79,14 +75,6 @@ VPCS_UPDATE_SCHEMA = {
|
|||||||
"description": "Console type",
|
"description": "Console type",
|
||||||
"enum": ["telnet"]
|
"enum": ["telnet"]
|
||||||
},
|
},
|
||||||
"startup_script": {
|
|
||||||
"description": "Content of the VPCS startup script",
|
|
||||||
"type": ["string", "null"]
|
|
||||||
},
|
|
||||||
"startup_script_path": {
|
|
||||||
"description": "Path of the VPCS startup script relative to project directory (IGNORED)",
|
|
||||||
"type": ["string", "null"]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"additionalProperties": False,
|
"additionalProperties": False,
|
||||||
}
|
}
|
||||||
@ -133,19 +121,11 @@ VPCS_OBJECT_SCHEMA = {
|
|||||||
"maxLength": 36,
|
"maxLength": 36,
|
||||||
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
|
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
|
||||||
},
|
},
|
||||||
"startup_script": {
|
|
||||||
"description": "Content of the VPCS startup script",
|
|
||||||
"type": ["string", "null"]
|
|
||||||
},
|
|
||||||
"startup_script_path": {
|
|
||||||
"description": "Path of the VPCS startup script relative to project directory",
|
|
||||||
"type": ["string", "null"]
|
|
||||||
},
|
|
||||||
"command_line": {
|
"command_line": {
|
||||||
"description": "Last command line used by GNS3 to start QEMU",
|
"description": "Last command line used by GNS3 to start QEMU",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": False,
|
"additionalProperties": False,
|
||||||
"required": ["name", "node_id", "status", "console", "console_type", "project_id", "startup_script_path", "command_line"]
|
"required": ["name", "node_id", "status", "console", "console_type", "project_id", "command_line"]
|
||||||
}
|
}
|
||||||
|
@ -465,3 +465,17 @@ def test_get_free_project_name(controller, async_run):
|
|||||||
async_run(controller.add_project(project_id=str(uuid.uuid4()), name="Test-1"))
|
async_run(controller.add_project(project_id=str(uuid.uuid4()), name="Test-1"))
|
||||||
assert controller.get_free_project_name("Test") == "Test-2"
|
assert controller.get_free_project_name("Test") == "Test-2"
|
||||||
assert controller.get_free_project_name("Hello") == "Hello"
|
assert controller.get_free_project_name("Hello") == "Hello"
|
||||||
|
|
||||||
|
|
||||||
|
def test_load_base_files(controller, config, tmpdir):
|
||||||
|
config.set_section_config("Server", {"configs_path": str(tmpdir)})
|
||||||
|
|
||||||
|
with open(str(tmpdir / 'iou_l2_base_startup-config.txt'), 'w+') as f:
|
||||||
|
f.write('test')
|
||||||
|
|
||||||
|
controller.load_base_files()
|
||||||
|
assert os.path.exists(str(tmpdir / 'iou_l3_base_startup-config.txt'))
|
||||||
|
|
||||||
|
# Check is the file has not been overwrite
|
||||||
|
with open(str(tmpdir / 'iou_l2_base_startup-config.txt')) as f:
|
||||||
|
assert f.read() == 'test'
|
||||||
|
@ -88,19 +88,6 @@ def test_eq(compute, project, node, controller):
|
|||||||
assert node != Node(Project(str(uuid.uuid4()), controller=controller), compute, "demo3", node_id=node.id, node_type="qemu")
|
assert node != Node(Project(str(uuid.uuid4()), controller=controller), compute, "demo3", node_id=node.id, node_type="qemu")
|
||||||
|
|
||||||
|
|
||||||
def test_properties_filter(project, compute):
|
|
||||||
"""
|
|
||||||
Some properties are private and should not be exposed
|
|
||||||
"""
|
|
||||||
node = Node(project, compute, "demo",
|
|
||||||
node_id=str(uuid.uuid4()),
|
|
||||||
node_type="vpcs",
|
|
||||||
console_type="vnc",
|
|
||||||
properties={"startup_script": "echo test", "iourc_content": "test"})
|
|
||||||
assert node._properties == {"startup_script": "echo test", "iourc_content": "test"}
|
|
||||||
assert node._filter_properties() == {"startup_script": "echo test"}
|
|
||||||
|
|
||||||
|
|
||||||
def test_json(node, compute):
|
def test_json(node, compute):
|
||||||
assert node.__json__() == {
|
assert node.__json__() == {
|
||||||
"compute_id": str(compute.id),
|
"compute_id": str(compute.id),
|
||||||
@ -207,6 +194,30 @@ def test_create_image_missing(node, compute, project, async_run):
|
|||||||
node._upload_missing_image.called is True
|
node._upload_missing_image.called is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_base_script(node, config, compute, tmpdir, async_run):
|
||||||
|
config.set_section_config("Server", {"configs_path": str(tmpdir)})
|
||||||
|
|
||||||
|
with open(str(tmpdir / 'test.txt'), 'w+') as f:
|
||||||
|
f.write('hostname test')
|
||||||
|
|
||||||
|
node._properties = {"base_script_file": "test.txt"}
|
||||||
|
node._console = 2048
|
||||||
|
|
||||||
|
response = MagicMock()
|
||||||
|
response.json = {"console": 2048}
|
||||||
|
compute.post = AsyncioMagicMock(return_value=response)
|
||||||
|
|
||||||
|
assert async_run(node.create()) is True
|
||||||
|
data = {
|
||||||
|
"console": 2048,
|
||||||
|
"console_type": "vnc",
|
||||||
|
"node_id": node.id,
|
||||||
|
"startup_script": "hostname test",
|
||||||
|
"name": "demo"
|
||||||
|
}
|
||||||
|
compute.post.assert_called_with("/projects/{}/vpcs/nodes".format(node.project.id), data=data, timeout=120)
|
||||||
|
|
||||||
|
|
||||||
def test_symbol(node, symbols_dir):
|
def test_symbol(node, symbols_dir):
|
||||||
"""
|
"""
|
||||||
Change symbol should change the node size
|
Change symbol should change the node size
|
||||||
|
@ -137,7 +137,7 @@ def test_add_node_local(async_run, controller):
|
|||||||
response.json = {"console": 2048}
|
response.json = {"console": 2048}
|
||||||
compute.post = AsyncioMagicMock(return_value=response)
|
compute.post = AsyncioMagicMock(return_value=response)
|
||||||
|
|
||||||
node = async_run(project.add_node(compute, "test", None, node_type="vpcs", properties={"startup_config": "test.cfg"}))
|
node = async_run(project.add_node(compute, "test", None, node_type="vpcs", properties={"startup_script": "test.cfg"}))
|
||||||
assert node.id in project._nodes
|
assert node.id in project._nodes
|
||||||
|
|
||||||
compute.post.assert_any_call('/projects', data={
|
compute.post.assert_any_call('/projects', data={
|
||||||
@ -147,7 +147,7 @@ def test_add_node_local(async_run, controller):
|
|||||||
})
|
})
|
||||||
compute.post.assert_any_call('/projects/{}/vpcs/nodes'.format(project.id),
|
compute.post.assert_any_call('/projects/{}/vpcs/nodes'.format(project.id),
|
||||||
data={'node_id': node.id,
|
data={'node_id': node.id,
|
||||||
'startup_config': 'test.cfg',
|
'startup_script': 'test.cfg',
|
||||||
'name': 'test'},
|
'name': 'test'},
|
||||||
timeout=120)
|
timeout=120)
|
||||||
assert compute in project._project_created_on_compute
|
assert compute in project._project_created_on_compute
|
||||||
@ -167,7 +167,7 @@ def test_add_node_non_local(async_run, controller):
|
|||||||
response.json = {"console": 2048}
|
response.json = {"console": 2048}
|
||||||
compute.post = AsyncioMagicMock(return_value=response)
|
compute.post = AsyncioMagicMock(return_value=response)
|
||||||
|
|
||||||
node = async_run(project.add_node(compute, "test", None, node_type="vpcs", properties={"startup_config": "test.cfg"}))
|
node = async_run(project.add_node(compute, "test", None, node_type="vpcs", properties={"startup_script": "test.cfg"}))
|
||||||
|
|
||||||
compute.post.assert_any_call('/projects', data={
|
compute.post.assert_any_call('/projects', data={
|
||||||
"name": project._name,
|
"name": project._name,
|
||||||
@ -175,7 +175,7 @@ def test_add_node_non_local(async_run, controller):
|
|||||||
})
|
})
|
||||||
compute.post.assert_any_call('/projects/{}/vpcs/nodes'.format(project.id),
|
compute.post.assert_any_call('/projects/{}/vpcs/nodes'.format(project.id),
|
||||||
data={'node_id': node.id,
|
data={'node_id': node.id,
|
||||||
'startup_config': 'test.cfg',
|
'startup_script': 'test.cfg',
|
||||||
'name': 'test'},
|
'name': 'test'},
|
||||||
timeout=120)
|
timeout=120)
|
||||||
assert compute in project._project_created_on_compute
|
assert compute in project._project_created_on_compute
|
||||||
|
@ -106,7 +106,6 @@ def demo_topology():
|
|||||||
"node_type": "vpcs",
|
"node_type": "vpcs",
|
||||||
"properties": {
|
"properties": {
|
||||||
"startup_script": "",
|
"startup_script": "",
|
||||||
"startup_script_path": "startup.vpc"
|
|
||||||
},
|
},
|
||||||
"symbol": ":/symbols/computer.svg",
|
"symbol": ":/symbols/computer.svg",
|
||||||
"width": 65,
|
"width": 65,
|
||||||
@ -131,7 +130,6 @@ def demo_topology():
|
|||||||
"node_type": "vpcs",
|
"node_type": "vpcs",
|
||||||
"properties": {
|
"properties": {
|
||||||
"startup_script": "",
|
"startup_script": "",
|
||||||
"startup_script_path": "startup.vpc"
|
|
||||||
},
|
},
|
||||||
"symbol": ":/symbols/computer.svg",
|
"symbol": ":/symbols/computer.svg",
|
||||||
"width": 65,
|
"width": 65,
|
||||||
|
@ -80,7 +80,6 @@ def test_iou_create_with_params(http_compute, project, base_params):
|
|||||||
params["l1_keepalives"] = True
|
params["l1_keepalives"] = True
|
||||||
params["startup_config_content"] = "hostname test"
|
params["startup_config_content"] = "hostname test"
|
||||||
params["use_default_iou_values"] = True
|
params["use_default_iou_values"] = True
|
||||||
params["iourc_content"] = "test"
|
|
||||||
|
|
||||||
response = http_compute.post("/projects/{project_id}/iou/nodes".format(project_id=project.id), params, example=True)
|
response = http_compute.post("/projects/{project_id}/iou/nodes".format(project_id=project.id), params, example=True)
|
||||||
assert response.status == 201
|
assert response.status == 201
|
||||||
@ -94,7 +93,6 @@ def test_iou_create_with_params(http_compute, project, base_params):
|
|||||||
assert response.json["l1_keepalives"] is True
|
assert response.json["l1_keepalives"] is True
|
||||||
assert response.json["use_default_iou_values"] is True
|
assert response.json["use_default_iou_values"] is True
|
||||||
|
|
||||||
assert "startup-config.cfg" in response.json["startup_config"]
|
|
||||||
with open(startup_config_file(project, response.json)) as f:
|
with open(startup_config_file(project, response.json)) as f:
|
||||||
assert f.read() == "hostname test"
|
assert f.read() == "hostname test"
|
||||||
|
|
||||||
@ -115,7 +113,6 @@ def test_iou_create_startup_config_already_exist(http_compute, project, base_par
|
|||||||
assert response.status == 201
|
assert response.status == 201
|
||||||
assert response.route == "/projects/{project_id}/iou/nodes"
|
assert response.route == "/projects/{project_id}/iou/nodes"
|
||||||
|
|
||||||
assert "startup-config.cfg" in response.json["startup_config"]
|
|
||||||
with open(startup_config_file(project, response.json)) as f:
|
with open(startup_config_file(project, response.json)) as f:
|
||||||
assert f.read() == "echo hello"
|
assert f.read() == "echo hello"
|
||||||
|
|
||||||
@ -183,9 +180,7 @@ def test_iou_update(http_compute, vm, tmpdir, free_console_port, project):
|
|||||||
"ethernet_adapters": 4,
|
"ethernet_adapters": 4,
|
||||||
"serial_adapters": 0,
|
"serial_adapters": 0,
|
||||||
"l1_keepalives": True,
|
"l1_keepalives": True,
|
||||||
"startup_config_content": "hostname test",
|
|
||||||
"use_default_iou_values": True,
|
"use_default_iou_values": True,
|
||||||
"iourc_content": "test"
|
|
||||||
}
|
}
|
||||||
response = http_compute.put("/projects/{project_id}/iou/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]), params, example=True)
|
response = http_compute.put("/projects/{project_id}/iou/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]), params, example=True)
|
||||||
assert response.status == 200
|
assert response.status == 200
|
||||||
@ -197,9 +192,6 @@ def test_iou_update(http_compute, vm, tmpdir, free_console_port, project):
|
|||||||
assert response.json["nvram"] == 2048
|
assert response.json["nvram"] == 2048
|
||||||
assert response.json["l1_keepalives"] is True
|
assert response.json["l1_keepalives"] is True
|
||||||
assert response.json["use_default_iou_values"] is True
|
assert response.json["use_default_iou_values"] is True
|
||||||
assert "startup-config.cfg" in response.json["startup_config"]
|
|
||||||
with open(startup_config_file(project, response.json)) as f:
|
|
||||||
assert f.read() == "hostname test"
|
|
||||||
|
|
||||||
|
|
||||||
def test_iou_nio_create_udp(http_compute, vm):
|
def test_iou_nio_create_udp(http_compute, vm):
|
||||||
|
@ -43,7 +43,6 @@ def test_vpcs_get(http_compute, project, vm):
|
|||||||
assert response.route == "/projects/{project_id}/vpcs/nodes/{node_id}"
|
assert response.route == "/projects/{project_id}/vpcs/nodes/{node_id}"
|
||||||
assert response.json["name"] == "PC TEST 1"
|
assert response.json["name"] == "PC TEST 1"
|
||||||
assert response.json["project_id"] == project.id
|
assert response.json["project_id"] == project.id
|
||||||
assert response.json["startup_script_path"] is None
|
|
||||||
assert response.json["status"] == "stopped"
|
assert response.json["status"] == "stopped"
|
||||||
|
|
||||||
|
|
||||||
@ -53,8 +52,6 @@ def test_vpcs_create_startup_script(http_compute, project):
|
|||||||
assert response.route == "/projects/{project_id}/vpcs/nodes"
|
assert response.route == "/projects/{project_id}/vpcs/nodes"
|
||||||
assert response.json["name"] == "PC TEST 1"
|
assert response.json["name"] == "PC TEST 1"
|
||||||
assert response.json["project_id"] == project.id
|
assert response.json["project_id"] == project.id
|
||||||
assert response.json["startup_script"] == os.linesep.join(["ip 192.168.1.2", "echo TEST"])
|
|
||||||
assert response.json["startup_script_path"] == "startup.vpc"
|
|
||||||
|
|
||||||
|
|
||||||
def test_vpcs_create_port(http_compute, project, free_console_port):
|
def test_vpcs_create_port(http_compute, project, free_console_port):
|
||||||
|
@ -63,7 +63,6 @@
|
|||||||
],
|
],
|
||||||
"slot0": "C7200-IO-FE",
|
"slot0": "C7200-IO-FE",
|
||||||
"sparsemem": true,
|
"sparsemem": true,
|
||||||
"startup_config": "configs/i1_startup-config.cfg",
|
|
||||||
"system_id": "FTX0945W0MY"
|
"system_id": "FTX0945W0MY"
|
||||||
},
|
},
|
||||||
"x": -112,
|
"x": -112,
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
"slot0": "Leopard-2FE",
|
"slot0": "Leopard-2FE",
|
||||||
"idlepc": "0x6057efc8",
|
"idlepc": "0x6057efc8",
|
||||||
"chassis": "3660",
|
"chassis": "3660",
|
||||||
"startup_config": "configs/i1_startup-config.cfg",
|
|
||||||
"image": "c3660-a3jk9s-mz.124-25c.bin",
|
"image": "c3660-a3jk9s-mz.124-25c.bin",
|
||||||
"mac_addr": "cc01.20b8.0000",
|
"mac_addr": "cc01.20b8.0000",
|
||||||
"aux": 2103,
|
"aux": 2103,
|
||||||
|
@ -53,7 +53,6 @@
|
|||||||
"ram": 256,
|
"ram": 256,
|
||||||
"slot0": "GT96100-FE",
|
"slot0": "GT96100-FE",
|
||||||
"sparsemem": true,
|
"sparsemem": true,
|
||||||
"startup_config": "configs/i1_startup-config.cfg",
|
|
||||||
"system_id": "FTX0945W0MY"
|
"system_id": "FTX0945W0MY"
|
||||||
},
|
},
|
||||||
"symbol": ":/symbols/router.svg",
|
"symbol": ":/symbols/router.svg",
|
||||||
@ -100,7 +99,6 @@
|
|||||||
"slot0": "Leopard-2FE",
|
"slot0": "Leopard-2FE",
|
||||||
"slot1": "NM-16ESW",
|
"slot1": "NM-16ESW",
|
||||||
"sparsemem": true,
|
"sparsemem": true,
|
||||||
"startup_config": "configs/i2_startup-config.cfg",
|
|
||||||
"system_id": "FTX0945W0MY"
|
"system_id": "FTX0945W0MY"
|
||||||
},
|
},
|
||||||
"symbol": ":/symbols/multilayer_switch.svg",
|
"symbol": ":/symbols/multilayer_switch.svg",
|
||||||
|
@ -76,7 +76,6 @@
|
|||||||
"port_segment_size": 0,
|
"port_segment_size": 0,
|
||||||
"first_port_name": null,
|
"first_port_name": null,
|
||||||
"properties": {
|
"properties": {
|
||||||
"startup_script_path": "startup.vpc"
|
|
||||||
},
|
},
|
||||||
"symbol": ":/symbols/vpcs_guest.svg",
|
"symbol": ":/symbols/vpcs_guest.svg",
|
||||||
"x": -29,
|
"x": -29,
|
||||||
|
@ -41,7 +41,6 @@
|
|||||||
"path": "i86bi-linux-l3-adventerprisek9-15.4.1T.bin",
|
"path": "i86bi-linux-l3-adventerprisek9-15.4.1T.bin",
|
||||||
"ram": 256,
|
"ram": 256,
|
||||||
"serial_adapters": 2,
|
"serial_adapters": 2,
|
||||||
"startup_config": "startup-config.cfg",
|
|
||||||
"use_default_iou_values": true
|
"use_default_iou_values": true
|
||||||
},
|
},
|
||||||
"symbol": ":/symbols/router.svg",
|
"symbol": ":/symbols/router.svg",
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
"port_segment_size": 0,
|
"port_segment_size": 0,
|
||||||
"first_port_name": null,
|
"first_port_name": null,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"startup_script_path" : "startup.vpc"
|
|
||||||
},
|
},
|
||||||
"label" : {
|
"label" : {
|
||||||
"y" : -25,
|
"y" : -25,
|
||||||
|
@ -50,7 +50,6 @@
|
|||||||
"port_segment_size": 0,
|
"port_segment_size": 0,
|
||||||
"first_port_name": null,
|
"first_port_name": null,
|
||||||
"properties": {
|
"properties": {
|
||||||
"startup_script_path": "startup.vpc"
|
|
||||||
},
|
},
|
||||||
"symbol": ":/symbols/vpcs_guest.svg",
|
"symbol": ":/symbols/vpcs_guest.svg",
|
||||||
"x": -87,
|
"x": -87,
|
||||||
@ -75,7 +74,6 @@
|
|||||||
"port_segment_size": 0,
|
"port_segment_size": 0,
|
||||||
"first_port_name": null,
|
"first_port_name": null,
|
||||||
"properties": {
|
"properties": {
|
||||||
"startup_script_path": "startup.vpc"
|
|
||||||
},
|
},
|
||||||
"symbol": ":/symbols/vpcs_guest.svg",
|
"symbol": ":/symbols/vpcs_guest.svg",
|
||||||
"x": 123,
|
"x": 123,
|
||||||
|
@ -61,8 +61,6 @@
|
|||||||
1,
|
1,
|
||||||
1
|
1
|
||||||
],
|
],
|
||||||
"private_config": "",
|
|
||||||
"private_config_content": "",
|
|
||||||
"ram": 512,
|
"ram": 512,
|
||||||
"sensors": [
|
"sensors": [
|
||||||
22,
|
22,
|
||||||
@ -78,8 +76,6 @@
|
|||||||
"slot5": null,
|
"slot5": null,
|
||||||
"slot6": null,
|
"slot6": null,
|
||||||
"sparsemem": true,
|
"sparsemem": true,
|
||||||
"startup_config": "configs/i1_startup-config.cfg",
|
|
||||||
"startup_config_content": "!\n!\nservice timestamps debug datetime msec\nservice timestamps log datetime msec\nno service password-encryption\n!\nhostname R1\n!\nip cef\nno ip domain-lookup\nno ip icmp rate-limit unreachable\nip tcp synwait 5\nno cdp log mismatch duplex\n!\nline con 0\n exec-timeout 0 0\n logging synchronous\n privilege level 15\n no login\nline aux 0\n exec-timeout 0 0\n logging synchronous\n privilege level 15\n no login\n!\n!\nend\n",
|
|
||||||
"system_id": "FTX0945W0MY"
|
"system_id": "FTX0945W0MY"
|
||||||
},
|
},
|
||||||
"symbol": ":/symbols/router.svg",
|
"symbol": ":/symbols/router.svg",
|
||||||
@ -129,8 +125,6 @@
|
|||||||
1,
|
1,
|
||||||
1
|
1
|
||||||
],
|
],
|
||||||
"private_config": "",
|
|
||||||
"private_config_content": "",
|
|
||||||
"ram": 512,
|
"ram": 512,
|
||||||
"sensors": [
|
"sensors": [
|
||||||
22,
|
22,
|
||||||
@ -146,8 +140,6 @@
|
|||||||
"slot5": null,
|
"slot5": null,
|
||||||
"slot6": null,
|
"slot6": null,
|
||||||
"sparsemem": true,
|
"sparsemem": true,
|
||||||
"startup_config": "configs/i2_startup-config.cfg",
|
|
||||||
"startup_config_content": "!\n!\nservice timestamps debug datetime msec\nservice timestamps log datetime msec\nno service password-encryption\n!\nhostname R2\n!\nip cef\nno ip domain-lookup\nno ip icmp rate-limit unreachable\nip tcp synwait 5\nno cdp log mismatch duplex\n!\nline con 0\n exec-timeout 0 0\n logging synchronous\n privilege level 15\n no login\nline aux 0\n exec-timeout 0 0\n logging synchronous\n privilege level 15\n no login\n!\n!\nend\n",
|
|
||||||
"system_id": "FTX0945W0MY"
|
"system_id": "FTX0945W0MY"
|
||||||
},
|
},
|
||||||
"symbol": ":/symbols/router.svg",
|
"symbol": ":/symbols/router.svg",
|
||||||
@ -160,4 +152,4 @@
|
|||||||
},
|
},
|
||||||
"type": "topology",
|
"type": "topology",
|
||||||
"version": "2.0.0dev7"
|
"version": "2.0.0dev7"
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user