Embed the appliances in the server. (#927)

This add a /appliances call
This commit is contained in:
Julien Duponchelle authored and GitHub committed 2017-04-12 14:35:49 +02:00
1 parent 4f1b738ef5
commit 9dc6f0f486
11 files changed
+432 -27

No files matched your search

+65 -4
View File
@@ -57,13 +57,12 @@ class Controller:
# Store settings shared by the different GUI will be replace by dedicated API later
self._settings = None
self._local_server = None
self._appliances = {}
self._appliance_templates = {}
self._config_file = os.path.join(Config.instance().config_dir, "gns3_controller.conf")
log.info("Load controller configuration file {}".format(self._config_file))
self._appliance_templates = {}
self.load_appliances()
def load_appliances(self):
self._appliance_templates = {}
for file in os.listdir(get_resource('appliances')):
@@ -72,6 +71,59 @@ class Controller:
if appliance.status != 'broken':
self._appliance_templates[appliance.id] = appliance
self._appliances = {}
for vm in self._settings.get("Qemu", {}).get("vms", []):
vm["node_type"] = "qemu"
appliance = Appliance(None, vm)
self._appliances[appliance.id] = appliance
for vm in self._settings.get("IOU", {}).get("devices", []):
vm["node_type"] = "iou"
appliance = Appliance(None, vm)
self._appliances[appliance.id] = appliance
for vm in self._settings.get("Docker", {}).get("containers", []):
vm["node_type"] = "docker"
appliance = Appliance(None, vm)
self._appliances[appliance.id] = appliance
for vm in self._settings.get("Builtin", {}).get("cloud_nodes", []):
vm["node_type"] = "cloud"
appliance = Appliance(None, vm)
self._appliances[appliance.id] = appliance
for vm in self._settings.get("Builtin", {}).get("ethernet_switches", []):
vm["node_type"] = "ethernet_switch"
appliance = Appliance(None, vm)
self._appliances[appliance.id] = appliance
for vm in self._settings.get("Builtin", {}).get("ethernet_hubs", []):
vm["node_type"] = "ethernet_hub"
appliance = Appliance(None, vm)
self._appliances[appliance.id] = appliance
for vm in self._settings.get("Dynamips", {}).get("routers", []):
vm["node_type"] = "dynamips"
appliance = Appliance(None, vm)
self._appliances[appliance.id] = appliance
for vm in self._settings.get("VMware", {}).get("vms", []):
vm["node_type"] = "vmware"
appliance = Appliance(None, vm)
self._appliances[appliance.id] = appliance
for vm in self._settings.get("VirtualBox", {}).get("vms", []):
vm["node_type"] = "virtualbox"
appliance = Appliance(None, vm)
self._appliances[appliance.id] = appliance
for vm in self._settings.get("VPCS", {}).get("nodes", []):
vm["node_type"] = "vpcs"
appliance = Appliance(None, vm)
self._appliances[appliance.id] = appliance
# Add builtins
builtins = []
builtins.append(Appliance(None, {"node_type": "cloud", "name": "Cloud", "category": 2, "symbol": ":/symbols/cloud.svg"}, builtin=True))
builtins.append(Appliance(None, {"node_type": "nat", "name": "NAT", "category": 2, "symbol": ":/symbols/cloud.svg"}, builtin=True))
builtins.append(Appliance(None, {"node_type": "vpcs", "name": "VPCS", "category": 2, "symbol": ":/symbols/vpcs_guest.svg"}, builtin=True))
builtins.append(Appliance(None, {"node_type": "ethernet_switch", "name": "Ethernet switch", "category": 1, "symbol": ":/symbols/ethernet_switch.svg"}, builtin=True))
builtins.append(Appliance(None, {"node_type": "ethernet_hub", "name": "Ethernet hub", "category": 1, "symbol": ":/symbols/hub.svg"}, builtin=True))
builtins.append(Appliance(None, {"node_type": "frame_relay_switch", "name": "Frame Relay switch", "category": 1, "symbol": ":/symbols/frame_relay_switch.svg"}, builtin=True))
builtins.append(Appliance(None, {"node_type": "atm_switch", "name": "ATM switch", "category": 1, "symbol": ":/symbols/atm_switch.svg"}, builtin=True))
for b in builtins:
self._appliances[b.id] = b
@asyncio.coroutine
def start(self):
log.info("Start controller")
@@ -190,6 +242,7 @@ class Controller:
if "gns3vm" in data:
self.gns3vm.settings = data["gns3vm"]
self.load_appliances()
return data["computes"]
@asyncio.coroutine
@@ -309,6 +362,7 @@ class Controller:
self._settings = val
self._settings["modification_uuid"] = str(uuid.uuid4()) # We add a modification id to the settings it's help the gui to detect changes
self.save()
self.load_appliances()
self.notification.emit("settings.updated", val)
@asyncio.coroutine
@@ -515,6 +569,13 @@ class Controller:
"""
return self._appliance_templates
@property
def appliances(self):
"""
:returns: The dictionary of appliances managed by GNS3
"""
return self._appliances
def projects_directory(self):
server_config = Config.instance().get_section_config("Server")
return os.path.expanduser(server_config.get("projects_path", "~/GNS3/projects"))
+37 -2
View File
@@ -18,21 +18,56 @@
import uuid
# Convert old GUI category to text category
ID_TO_CATEGORY = {
3: "firewall",
2: "guest",
1: "switch",
0: "router"
}
class Appliance:
def __init__(self, appliance_id, data):
def __init__(self, appliance_id, data, builtin=False):
if appliance_id is None:
self._id = str(uuid.uuid4())
else:
self._id = appliance_id
self._data = data
self._builtin = builtin
@property
def id(self):
return self._id
@property
def data(self):
return self._data
@property
def name(self):
return self._data["name"]
@property
def compute_id(self):
return self._data.get("server")
@property
def builtin(self):
return self._builtin
def __json__(self):
"""
Appliance data (a hash)
"""
return self._data
return {
"appliance_id": self._id,
"node_type": self._data["node_type"],
"name": self._data["name"],
"default_name_format": self._data.get("default_name_format", "{name}-{0}"),
"category": ID_TO_CATEGORY[self._data["category"]],
"symbol": self._data["symbol"],
"compute_id": self.compute_id,
"builtin": self._builtin
}
+24
View File
@@ -19,6 +19,7 @@ import re
import os
import json
import uuid
import copy
import shutil
import asyncio
import aiohttp
@@ -317,6 +318,29 @@ class Project:
return self.update_allocated_node_name(new_name)
return new_name
@open_required
@asyncio.coroutine
def add_node_from_appliance(self, appliance_id, x=0, y=0, compute_id=None):
"""
Create a node from an appliance
"""
try:
template = copy.copy(self.controller.appliances[appliance_id].data)
except KeyError:
msg = "Appliance {} doesn't exist".format(appliance_id)
log.error(msg)
raise aiohttp.web.HTTPNotFound(text=msg)
template["x"] = x
template["y"] = y
node_type = template.pop("node_type")
compute = self.controller.get_compute(template.pop("server", compute_id))
name = template.pop("name")
default_name_format = template.pop("default_name_format", "{name}-{0}")
name = default_name_format.replace("{name}", name)
node_id = str(uuid.uuid4())
node = yield from self.add_node(compute, name, node_id, node_type=node_type, **template)
return node
@open_required
@asyncio.coroutine
def add_node(self, compute, name, node_id, dump=True, node_type=None, **kwargs):