diff --git a/gns3server/compute/docker/__init__.py b/gns3server/compute/docker/__init__.py
index 57b2c1e1..2c499b98 100644
--- a/gns3server/compute/docker/__init__.py
+++ b/gns3server/compute/docker/__init__.py
@@ -22,7 +22,6 @@ Docker server module.
import asyncio
import logging
import aiohttp
-import urllib
import json
from gns3server.utils import parse_version
diff --git a/gns3server/compute/virtualbox/__init__.py b/gns3server/compute/virtualbox/__init__.py
index 92136b32..5b006d1b 100644
--- a/gns3server/compute/virtualbox/__init__.py
+++ b/gns3server/compute/virtualbox/__init__.py
@@ -155,7 +155,7 @@ class VirtualBox(BaseManager):
continue
@asyncio.coroutine
- def list_images(self):
+ def list_vms(self):
"""
Gets VirtualBox VM list.
"""
diff --git a/gns3server/controller/__init__.py b/gns3server/controller/__init__.py
index 531db407..9dafcc0f 100644
--- a/gns3server/controller/__init__.py
+++ b/gns3server/controller/__init__.py
@@ -31,7 +31,7 @@ log = logging.getLogger(__name__)
class Controller:
- """The controller manage multiple gns3 computes"""
+ """The controller manage multiple gns3 compute servers"""
def __init__(self):
self._computes = {}
@@ -97,7 +97,7 @@ class Controller:
# We disallow to create from the outside the
if compute_id == 'local':
- return self._createLocalCompute()
+ return self._create_local_compute()
if compute_id not in self._computes:
compute = Compute(compute_id=compute_id, controller=self, **kwargs)
@@ -105,7 +105,7 @@ class Controller:
self.save()
return self._computes[compute_id]
- def _createLocalCompute(self):
+ def _create_local_compute(self):
"""
Create the local compute node. It's the controller itself
"""
@@ -139,7 +139,7 @@ class Controller:
raise aiohttp.web.HTTPNotFound(text="Compute ID {} doesn't exist".format(compute_id))
@asyncio.coroutine
- def addProject(self, project_id=None, **kwargs):
+ def add_project(self, project_id=None, **kwargs):
"""
Create a project or return an existing project
diff --git a/gns3server/handlers/api/compute/config_handler.py b/gns3server/handlers/api/compute/config_handler.py
index aa3b1a99..8da644cb 100644
--- a/gns3server/handlers/api/compute/config_handler.py
+++ b/gns3server/handlers/api/compute/config_handler.py
@@ -17,16 +17,15 @@
from aiohttp.web import HTTPForbidden
-from ....web.route import Route
-from ....config import Config
+from gns3server.web.route import Route
+from gns3server.config import Config
class ConfigHandler:
- @classmethod
@Route.post(
r"/config/reload",
- description="Check if version is the same as the server",
+ description="Reload the server configuration file",
status_codes={
201: "Config reload",
403: "Config reload refused"
@@ -35,6 +34,6 @@ class ConfigHandler:
config = Config.instance()
if config.get_section_config("Server").getboolean("local", False) is False:
- raise HTTPForbidden(text="You can only reload the configuration for a local server")
+ raise HTTPForbidden(text="The configuration can only be reloaded on a local server")
config.reload()
response.set_status(201)
diff --git a/gns3server/handlers/api/compute/docker_handler.py b/gns3server/handlers/api/compute/docker_handler.py
index ae43b9fb..740c8a6b 100644
--- a/gns3server/handlers/api/compute/docker_handler.py
+++ b/gns3server/handlers/api/compute/docker_handler.py
@@ -18,40 +18,26 @@
import os
from aiohttp.web import HTTPConflict
-from ....web.route import Route
-from ....compute.docker import Docker
+from gns3server.web.route import Route
+from gns3server.compute.docker import Docker
+from gns3server.schemas.node import NODE_CAPTURE_SCHEMA
+from gns3server.schemas.nio import NIO_SCHEMA
-from ....schemas.docker import (
+from gns3server.schemas.docker import (
DOCKER_CREATE_SCHEMA,
DOCKER_OBJECT_SCHEMA,
DOCKER_UPDATE_SCHEMA,
DOCKER_LIST_IMAGES_SCHEMA
)
-from ....schemas.node import NODE_CAPTURE_SCHEMA
-from ....schemas.nio import NIO_SCHEMA
class DockerHandler:
- """API entry points for Docker."""
+ """API entry points for Docker containers."""
- @classmethod
- @Route.get(
- r"/docker/images",
- status_codes={
- 200: "Success",
- },
- output=DOCKER_LIST_IMAGES_SCHEMA,
- description="Get all available Docker images")
- def show(request, response):
- docker_manager = Docker.instance()
- images = yield from docker_manager.list_images()
- response.json(images)
-
- @classmethod
@Route.post(
r"/projects/{project_id}/docker/nodes",
parameters={
- "project_id": "UUID for the project"
+ "project_id": "Project UUID"
},
status_codes={
201: "Instance created",
@@ -63,33 +49,32 @@ class DockerHandler:
output=DOCKER_OBJECT_SCHEMA)
def create(request, response):
docker_manager = Docker.instance()
- vm = yield from docker_manager.create_node(request.json.pop("name"),
- request.match_info["project_id"],
- request.json.get("node_id"),
- image=request.json.pop("image"),
- start_command=request.json.get("start_command"),
- environment=request.json.get("environment"),
- adapters=request.json.get("adapters"),
- console=request.json.get("console"),
- console_type=request.json.get("console_type"),
- console_resolution=request.json.get("console_resolution", "1024x768"),
- console_http_port=request.json.get("console_http_port", 80),
- console_http_path=request.json.get("console_http_path", "/"),
- aux=request.json.get("aux"))
+ container = yield from docker_manager.create_node(request.json.pop("name"),
+ request.match_info["project_id"],
+ request.json.get("node_id"),
+ image=request.json.pop("image"),
+ start_command=request.json.get("start_command"),
+ environment=request.json.get("environment"),
+ adapters=request.json.get("adapters"),
+ console=request.json.get("console"),
+ console_type=request.json.get("console_type"),
+ console_resolution=request.json.get("console_resolution", "1024x768"),
+ console_http_port=request.json.get("console_http_port", 80),
+ console_http_path=request.json.get("console_http_path", "/"),
+ aux=request.json.get("aux"))
for name, value in request.json.items():
- if name != "_node_id":
- if hasattr(vm, name) and getattr(vm, name) != value:
- setattr(vm, name, value)
+ if name != "node_id":
+ if hasattr(container, name) and getattr(container, name) != value:
+ setattr(container, name, value)
response.set_status(201)
- response.json(vm)
+ response.json(container)
- @classmethod
@Route.post(
r"/projects/{project_id}/docker/nodes/{node_id}/start",
parameters={
- "project_id": "UUID of the project",
- "node_id": "ID of the container"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance started",
@@ -101,16 +86,15 @@ class DockerHandler:
output=DOCKER_OBJECT_SCHEMA)
def start(request, response):
docker_manager = Docker.instance()
- vm = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
- yield from vm.start()
+ container = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
+ yield from container.start()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/docker/nodes/{node_id}/stop",
parameters={
- "project_id": "UUID of the project",
- "node_id": "ID of the container"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance stopped",
@@ -122,16 +106,15 @@ class DockerHandler:
output=DOCKER_OBJECT_SCHEMA)
def stop(request, response):
docker_manager = Docker.instance()
- vm = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
- yield from vm.stop()
+ container = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
+ yield from container.stop()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/docker/nodes/{node_id}/reload",
parameters={
- "project_id": "UUID of the project",
- "node_id": "ID of the container"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance restarted",
@@ -143,16 +126,15 @@ class DockerHandler:
output=DOCKER_OBJECT_SCHEMA)
def reload(request, response):
docker_manager = Docker.instance()
- vm = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
- yield from vm.restart()
+ container = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
+ yield from container.restart()
response.set_status(204)
- @classmethod
@Route.delete(
r"/projects/{project_id}/docker/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "ID for the container",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
},
status_codes={
204: "Instance deleted",
@@ -162,16 +144,15 @@ class DockerHandler:
description="Delete a Docker container")
def delete(request, response):
docker_manager = Docker.instance()
- vm = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
- yield from vm.delete()
+ container = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
+ yield from container.delete()
response.set_status(204)
- @classmethod
@Route.post(
- r"/projects/{project_id}/docker/nodes/{node_id}/suspend",
+ r"/projects/{project_id}/docker/nodes/{node_id}/pause",
parameters={
- "project_id": "UUID of the project",
- "node_id": "ID of the container"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance paused",
@@ -181,17 +162,37 @@ class DockerHandler:
description="Pause a Docker container",
input=DOCKER_CREATE_SCHEMA,
output=DOCKER_OBJECT_SCHEMA)
- def suspend(request, response):
+ def pause(request, response):
docker_manager = Docker.instance()
- vm = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
- yield from vm.pause()
+ container = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
+ yield from container.pause()
+ response.set_status(204)
+
+ @Route.post(
+ r"/projects/{project_id}/docker/nodes/{node_id}/unpause",
+ parameters={
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
+ },
+ status_codes={
+ 204: "Instance unpaused",
+ 400: "Invalid request",
+ 404: "Instance doesn't exist"
+ },
+ description="Unpause a Docker container",
+ input=DOCKER_CREATE_SCHEMA,
+ output=DOCKER_OBJECT_SCHEMA)
+ def unpause(request, response):
+ docker_manager = Docker.instance()
+ container = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
+ yield from container.unpause()
response.set_status(204)
@Route.post(
r"/projects/{project_id}/docker/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio",
parameters={
- "project_id": "UUID for the project",
- "node_id": "ID of the container",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Adapter where the nio should be added",
"port_number": "Port on the adapter"
},
@@ -205,21 +206,20 @@ class DockerHandler:
output=NIO_SCHEMA)
def create_nio(request, response):
docker_manager = Docker.instance()
- vm = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
+ container = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
nio_type = request.json["type"]
- if nio_type not in ("nio_udp"):
+ if nio_type != "nio_udp":
raise HTTPConflict(text="NIO of type {} is not supported".format(nio_type))
nio = docker_manager.create_nio(int(request.match_info["adapter_number"]), request.json)
- yield from vm.adapter_add_nio_binding(int(request.match_info["adapter_number"]), nio)
+ yield from container.adapter_add_nio_binding(int(request.match_info["adapter_number"]), nio)
response.set_status(201)
response.json(nio)
- @classmethod
@Route.delete(
r"/projects/{project_id}/docker/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio",
parameters={
- "project_id": "UUID for the project",
- "node_id": "ID of the container",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Adapter where the nio should be added",
"port_number": "Port on the adapter"
},
@@ -231,16 +231,15 @@ class DockerHandler:
description="Remove a NIO from a Docker container")
def delete_nio(request, response):
docker_manager = Docker.instance()
- vm = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
- yield from vm.adapter_remove_nio_binding(int(request.match_info["adapter_number"]))
+ container = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
+ yield from container.adapter_remove_nio_binding(int(request.match_info["adapter_number"]))
response.set_status(204)
- @classmethod
@Route.put(
r"/projects/{project_id}/docker/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
200: "Instance updated",
@@ -254,25 +253,25 @@ class DockerHandler:
def update(request, response):
docker_manager = Docker.instance()
- vm = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
- vm.name = request.json.get("name", vm.name)
- vm.console = request.json.get("console", vm.console)
- vm.aux = request.json.get("aux", vm.aux)
- vm.console_type = request.json.get("console_type", vm.console_type)
- vm.console_resolution = request.json.get("console_resolution", vm.console_resolution)
- vm.console_http_port = request.json.get("console_http_port", vm.console_http_port)
- vm.console_http_path = request.json.get("console_http_path", vm.console_http_path)
- vm.start_command = request.json.get("start_command", vm.start_command)
- vm.environment = request.json.get("environment", vm.environment)
- vm.adapters = request.json.get("adapters", vm.adapters)
- yield from vm.update()
- response.json(vm)
+ container = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
+ container.name = request.json.get("name", container.name)
+ container.console = request.json.get("console", container.console)
+ container.aux = request.json.get("aux", container.aux)
+ container.console_type = request.json.get("console_type", container.console_type)
+ container.console_resolution = request.json.get("console_resolution", container.console_resolution)
+ container.console_http_port = request.json.get("console_http_port", container.console_http_port)
+ container.console_http_path = request.json.get("console_http_path", container.console_http_path)
+ container.start_command = request.json.get("start_command", container.start_command)
+ container.environment = request.json.get("environment", container.environment)
+ container.adapters = request.json.get("adapters", container.adapters)
+ yield from container.update()
+ response.json(container)
@Route.post(
r"/projects/{project_id}/docker/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/start_capture",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Adapter to start a packet capture",
"port_number": "Port on the adapter"
},
@@ -282,25 +281,25 @@ class DockerHandler:
404: "Instance doesn't exist",
409: "Node not started"
},
- description="Start a packet capture on a Docker VM instance",
+ description="Start a packet capture on a Docker container instance",
input=NODE_CAPTURE_SCHEMA)
def start_capture(request, response):
docker_manager = Docker.instance()
- vm = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
+ container = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
adapter_number = int(request.match_info["adapter_number"])
- pcap_file_path = os.path.join(vm.project.capture_working_directory(), request.json["capture_file_name"])
+ pcap_file_path = os.path.join(container.project.capture_working_directory(), request.json["capture_file_name"])
- if not vm.is_running():
- raise HTTPConflict(text="Cannot capture traffic on a non started VM")
- yield from vm.start_capture(adapter_number, pcap_file_path)
+ if not container.is_running():
+ raise HTTPConflict(text="Cannot capture traffic on a non started Docker container")
+ yield from container.start_capture(adapter_number, pcap_file_path)
response.json({"pcap_file_path": str(pcap_file_path)})
@Route.post(
r"/projects/{project_id}/docker/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/stop_capture",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Adapter to stop a packet capture",
"port_number": "Port on the adapter (always 0)"
},
@@ -308,17 +307,29 @@ class DockerHandler:
204: "Capture stopped",
400: "Invalid request",
404: "Instance doesn't exist",
- 409: "VM not started"
+ 409: "Container not started"
},
- description="Stop a packet capture on a IOU VM instance")
+ description="Stop a packet capture on a Docker container instance")
def stop_capture(request, response):
docker_manager = Docker.instance()
- vm = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
+ container = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
- if not vm.is_running():
- raise HTTPConflict(text="Cannot capture traffic on a non started VM")
+ if not container.is_running():
+ raise HTTPConflict(text="Cannot capture traffic on a non started Docker container")
adapter_number = int(request.match_info["adapter_number"])
- yield from vm.stop_capture(adapter_number)
+ yield from container.stop_capture(adapter_number)
response.set_status(204)
+
+ @Route.get(
+ r"/docker/images",
+ status_codes={
+ 200: "Success",
+ },
+ output=DOCKER_LIST_IMAGES_SCHEMA,
+ description="Get all available Docker images")
+ def show(request, response):
+ docker_manager = Docker.instance()
+ images = yield from docker_manager.list_images()
+ response.json(images)
diff --git a/gns3server/handlers/api/compute/dynamips_device_handler.py b/gns3server/handlers/api/compute/dynamips_device_handler.py
index 1cd738eb..4ff4b791 100644
--- a/gns3server/handlers/api/compute/dynamips_device_handler.py
+++ b/gns3server/handlers/api/compute/dynamips_device_handler.py
@@ -17,13 +17,17 @@
import os
import asyncio
-from ....web.route import Route
-from ....schemas.dynamips_device import DEVICE_CREATE_SCHEMA
-from ....schemas.dynamips_device import DEVICE_UPDATE_SCHEMA
-from ....schemas.dynamips_device import DEVICE_OBJECT_SCHEMA
-from ....schemas.dynamips_device import DEVICE_NIO_SCHEMA
-from ....schemas.node import NODE_CAPTURE_SCHEMA
-from ....compute.dynamips import Dynamips
+
+from gns3server.web.route import Route
+from gns3server.schemas.node import NODE_CAPTURE_SCHEMA
+from gns3server.compute.dynamips import Dynamips
+
+from gns3server.schemas.dynamips_device import (
+ DEVICE_CREATE_SCHEMA,
+ DEVICE_UPDATE_SCHEMA,
+ DEVICE_OBJECT_SCHEMA,
+ DEVICE_NIO_SCHEMA
+)
class DynamipsDeviceHandler:
@@ -32,11 +36,10 @@ class DynamipsDeviceHandler:
API entry points for Dynamips devices.
"""
- @classmethod
@Route.post(
r"/projects/{project_id}/dynamips/devices",
parameters={
- "project_id": "UUID for the project"
+ "project_id": "Project UUID"
},
status_codes={
201: "Instance created",
@@ -57,12 +60,11 @@ class DynamipsDeviceHandler:
response.set_status(201)
response.json(device)
- @classmethod
@Route.get(
r"/projects/{project_id}/dynamips/devices/{device_id}",
parameters={
- "project_id": "UUID for the project",
- "device_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "device_id": "Device UUID"
},
status_codes={
200: "Success",
@@ -77,12 +79,11 @@ class DynamipsDeviceHandler:
device = dynamips_manager.get_device(request.match_info["device_id"], project_id=request.match_info["project_id"])
response.json(device)
- @classmethod
@Route.put(
r"/projects/{project_id}/dynamips/devices/{device_id}",
parameters={
- "project_id": "UUID for the project",
- "device_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "device_id": "Device UUID"
},
status_codes={
200: "Instance updated",
@@ -107,12 +108,11 @@ class DynamipsDeviceHandler:
response.json(device)
- @classmethod
@Route.delete(
r"/projects/{project_id}/dynamips/devices/{device_id}",
parameters={
- "project_id": "UUID for the project",
- "device_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "device_id": "Device UUID"
},
status_codes={
204: "Instance deleted",
@@ -129,8 +129,8 @@ class DynamipsDeviceHandler:
@Route.post(
r"/projects/{project_id}/dynamips/devices/{device_id}/ports/{port_number:\d+}/nio",
parameters={
- "project_id": "UUID for the project",
- "device_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "device_id": "Device UUID",
"port_number": "Port on the device"
},
status_codes={
@@ -162,12 +162,11 @@ class DynamipsDeviceHandler:
response.set_status(201)
response.json(nio)
- @classmethod
@Route.delete(
r"/projects/{project_id}/dynamips/devices/{device_id}/ports/{port_number:\d+}/nio",
parameters={
- "project_id": "UUID for the project",
- "device_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "device_id": "Device UUID",
"port_number": "Port on the device"
},
status_codes={
@@ -188,8 +187,8 @@ class DynamipsDeviceHandler:
@Route.post(
r"/projects/{project_id}/dynamips/devices/{device_id}/ports/{port_number:\d+}/start_capture",
parameters={
- "project_id": "UUID for the project",
- "device_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "device_id": "Device UUID",
"port_number": "Port on the device"
},
status_codes={
@@ -211,8 +210,8 @@ class DynamipsDeviceHandler:
@Route.post(
r"/projects/{project_id}/dynamips/devices/{device_id}/ports/{port_number:\d+}/stop_capture",
parameters={
- "project_id": "UUID for the project",
- "device_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "device_id": "Device UUID",
"port_number": "Port on the device"
},
status_codes={
diff --git a/gns3server/handlers/api/compute/dynamips_vm_handler.py b/gns3server/handlers/api/compute/dynamips_vm_handler.py
index 6748ccb8..05ec3e5f 100644
--- a/gns3server/handlers/api/compute/dynamips_vm_handler.py
+++ b/gns3server/handlers/api/compute/dynamips_vm_handler.py
@@ -19,17 +19,23 @@ import os
import sys
import base64
-from ....web.route import Route
-from ....schemas.nio import NIO_SCHEMA
-from ....schemas.dynamips_vm import VM_CREATE_SCHEMA
-from ....schemas.dynamips_vm import VM_UPDATE_SCHEMA
-from ....schemas.dynamips_vm import VM_OBJECT_SCHEMA
-from ....schemas.dynamips_vm import VM_CONFIGS_SCHEMA
-from ....schemas.node import NODE_CAPTURE_SCHEMA
-from ....schemas.node import NODE_LIST_IMAGES_SCHEMA
-from ....compute.dynamips import Dynamips
-from ....compute.dynamips.dynamips_error import DynamipsError
-from ....compute.project_manager import ProjectManager
+from gns3server.web.route import Route
+from gns3server.schemas.nio import NIO_SCHEMA
+from gns3server.compute.dynamips import Dynamips
+from gns3server.compute.dynamips.dynamips_error import DynamipsError
+from gns3server.compute.project_manager import ProjectManager
+
+from gns3server.schemas.node import (
+ NODE_CAPTURE_SCHEMA,
+ NODE_LIST_IMAGES_SCHEMA,
+)
+
+from gns3server.schemas.dynamips_vm import (
+ VM_CREATE_SCHEMA,
+ VM_UPDATE_SCHEMA,
+ VM_OBJECT_SCHEMA,
+ VM_CONFIGS_SCHEMA
+)
DEFAULT_CHASSIS = {
"c1700": "1720",
@@ -44,11 +50,10 @@ class DynamipsVMHandler:
API entry points for Dynamips VMs.
"""
- @classmethod
@Route.post(
r"/projects/{project_id}/dynamips/nodes",
parameters={
- "project_id": "UUID for the project"
+ "project_id": "Project UUID"
},
status_codes={
201: "Instance created",
@@ -66,24 +71,23 @@ class DynamipsVMHandler:
if platform in DEFAULT_CHASSIS:
default_chassis = DEFAULT_CHASSIS[platform]
vm = yield from dynamips_manager.create_node(request.json.pop("name"),
- request.match_info["project_id"],
- request.json.get("node_id"),
- request.json.get("dynamips_id"),
- platform,
- console=request.json.get("console"),
- aux=request.json.get("aux"),
- chassis=request.json.pop("chassis", default_chassis))
+ request.match_info["project_id"],
+ request.json.get("node_id"),
+ request.json.get("dynamips_id"),
+ platform,
+ console=request.json.get("console"),
+ aux=request.json.get("aux"),
+ chassis=request.json.pop("chassis", default_chassis))
yield from dynamips_manager.update_vm_settings(vm, request.json)
response.set_status(201)
response.json(vm)
- @classmethod
@Route.get(
r"/projects/{project_id}/dynamips/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
200: "Success",
@@ -98,12 +102,11 @@ class DynamipsVMHandler:
vm = dynamips_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
response.json(vm)
- @classmethod
@Route.put(
r"/projects/{project_id}/dynamips/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
200: "Instance updated",
@@ -121,12 +124,11 @@ class DynamipsVMHandler:
yield from dynamips_manager.update_vm_settings(vm, request.json)
response.json(vm)
- @classmethod
@Route.delete(
r"/projects/{project_id}/dynamips/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance deleted",
@@ -138,16 +140,14 @@ class DynamipsVMHandler:
# check the project_id exists
ProjectManager.instance().get_project(request.match_info["project_id"])
-
yield from Dynamips.instance().delete_node(request.match_info["node_id"])
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/dynamips/nodes/{node_id}/start",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance started",
@@ -166,12 +166,11 @@ class DynamipsVMHandler:
yield from vm.start()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/dynamips/nodes/{node_id}/stop",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance stopped",
@@ -186,12 +185,11 @@ class DynamipsVMHandler:
yield from vm.stop()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/dynamips/nodes/{node_id}/suspend",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance suspended",
@@ -206,12 +204,11 @@ class DynamipsVMHandler:
yield from vm.suspend()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/dynamips/nodes/{node_id}/resume",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance resumed",
@@ -226,12 +223,11 @@ class DynamipsVMHandler:
yield from vm.resume()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/dynamips/nodes/{node_id}/reload",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance reloaded",
@@ -249,8 +245,8 @@ class DynamipsVMHandler:
@Route.post(
r"/projects/{project_id}/dynamips/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Adapter where the nio should be added",
"port_number": "Port on the adapter"
},
@@ -273,12 +269,11 @@ class DynamipsVMHandler:
response.set_status(201)
response.json(nio)
- @classmethod
@Route.delete(
r"/projects/{project_id}/dynamips/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Adapter from where the nio should be removed",
"port_number": "Port on the adapter"
},
@@ -301,8 +296,8 @@ class DynamipsVMHandler:
@Route.post(
r"/projects/{project_id}/dynamips/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/start_capture",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Adapter to start a packet capture",
"port_number": "Port on the adapter"
},
@@ -334,8 +329,8 @@ class DynamipsVMHandler:
@Route.post(
r"/projects/{project_id}/dynamips/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/stop_capture",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Adapter to stop a packet capture",
"port_number": "Port on the adapter (always 0)"
},
@@ -356,6 +351,10 @@ class DynamipsVMHandler:
@Route.get(
r"/projects/{project_id}/dynamips/nodes/{node_id}/configs",
+ parameters={
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
+ },
status_codes={
200: "Configs retrieved",
400: "Invalid request",
@@ -375,7 +374,7 @@ class DynamipsVMHandler:
startup_config_content = base64.b64decode(startup_config_base64).decode("utf-8", errors='replace')
result["startup_config_content"] = startup_config_content
else:
- # nvram doesn't contain anything if the router has not been started at least once
+ # The NVRAM doesn't contain anything if the router has not been started at least once
# in this case just use the startup-config file
if vm.startup_config:
startup_config_path = os.path.join(module_workdir, vm.startup_config)
@@ -392,7 +391,7 @@ class DynamipsVMHandler:
private_config_content = base64.b64decode(private_config_base64).decode("utf-8", errors='replace')
result["private_config_content"] = private_config_content
else:
- # nvram doesn't contain anything if the router has not been started at least once
+ # The NVRAM doesn't contain anything if the router has not been started at least once
# in this case just use the private-config file
if vm.private_config:
private_config_path = os.path.join(module_workdir, vm.private_config)
@@ -410,6 +409,10 @@ class DynamipsVMHandler:
@Route.post(
r"/projects/{project_id}/dynamips/nodes/{node_id}/configs/save",
+ parameters={
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
+ },
status_codes={
200: "Configs saved",
400: "Invalid request",
@@ -425,6 +428,10 @@ class DynamipsVMHandler:
@Route.get(
r"/projects/{project_id}/dynamips/nodes/{node_id}/idlepc_proposals",
+ parameters={
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
+ },
status_codes={
200: "Idle-PCs retrieved",
400: "Invalid request",
@@ -442,6 +449,10 @@ class DynamipsVMHandler:
@Route.get(
r"/projects/{project_id}/dynamips/nodes/{node_id}/auto_idlepc",
+ parameters={
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
+ },
status_codes={
200: "Best Idle-pc value found",
400: "Invalid request",
@@ -457,28 +468,31 @@ class DynamipsVMHandler:
response.json({"idlepc": idlepc})
@Route.get(
- r"/dynamips/nodes",
+ r"/dynamips/images",
status_codes={
- 200: "List of Dynamips VM retrieved",
+ 200: "List of Dynamips IOS images",
},
- description="Retrieve the list of Dynamips VMS",
+ description="Retrieve the list of Dynamips IOS images",
output=NODE_LIST_IMAGES_SCHEMA)
- def list_vms(request, response):
+ def list_images(request, response):
dynamips_manager = Dynamips.instance()
- vms = yield from dynamips_manager.list_images()
+ images = yield from dynamips_manager.list_images()
response.set_status(200)
- response.json(vms)
+ response.json(images)
@Route.post(
- r"/dynamips/nodes/{path}",
+ r"/dynamips/images/{filename:.+}",
+ parameters={
+ "filename": "Image filename"
+ },
status_codes={
- 204: "Image uploaded",
+ 204: "Upload a Dynamips IOS image",
},
raw=True,
- description="Upload Dynamips image")
+ description="Upload a Dynamips IOS image")
def upload_image(request, response):
dynamips_manager = Dynamips.instance()
- yield from dynamips_manager.write_image(request.match_info["path"], request.content)
+ yield from dynamips_manager.write_image(request.match_info["filename"], request.content)
response.set_status(204)
diff --git a/gns3server/handlers/api/compute/iou_handler.py b/gns3server/handlers/api/compute/iou_handler.py
index 0362f9bd..82018201 100644
--- a/gns3server/handlers/api/compute/iou_handler.py
+++ b/gns3server/handlers/api/compute/iou_handler.py
@@ -18,16 +18,22 @@
import os
from aiohttp.web import HTTPConflict
-from ....web.route import Route
-from ....schemas.nio import NIO_SCHEMA
-from ....schemas.iou import IOU_CREATE_SCHEMA
-from ....schemas.iou import IOU_START_SCHEMA
-from ....schemas.iou import IOU_UPDATE_SCHEMA
-from ....schemas.iou import IOU_OBJECT_SCHEMA
-from ....schemas.iou import IOU_CONFIGS_SCHEMA
-from ....schemas.node import NODE_LIST_IMAGES_SCHEMA
-from ....schemas.node import NODE_CAPTURE_SCHEMA
-from ....compute.iou import IOU
+from gns3server.web.route import Route
+from gns3server.schemas.nio import NIO_SCHEMA
+from gns3server.compute.iou import IOU
+
+from gns3server.schemas.node import (
+ NODE_CAPTURE_SCHEMA,
+ NODE_LIST_IMAGES_SCHEMA,
+)
+
+from gns3server.schemas.iou import (
+ IOU_CREATE_SCHEMA,
+ IOU_START_SCHEMA,
+ IOU_UPDATE_SCHEMA,
+ IOU_OBJECT_SCHEMA,
+ IOU_CONFIGS_SCHEMA,
+)
class IOUHandler:
@@ -36,11 +42,10 @@ class IOUHandler:
API entry points for IOU.
"""
- @classmethod
@Route.post(
r"/projects/{project_id}/iou/nodes",
parameters={
- "project_id": "UUID for the project"
+ "project_id": "Project UUID"
},
status_codes={
201: "Instance created",
@@ -72,19 +77,18 @@ class IOUHandler:
response.set_status(201)
response.json(vm)
- @classmethod
@Route.get(
r"/projects/{project_id}/iou/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
200: "Success",
400: "Invalid request",
404: "Instance doesn't exist"
},
- description="Get a IOU instance",
+ description="Get an IOU instance",
output=IOU_OBJECT_SCHEMA)
def show(request, response):
@@ -92,12 +96,11 @@ class IOUHandler:
vm = iou_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
response.json(vm)
- @classmethod
@Route.put(
r"/projects/{project_id}/iou/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
200: "Instance updated",
@@ -105,7 +108,7 @@ class IOUHandler:
404: "Instance doesn't exist",
409: "Conflict"
},
- description="Update a IOU instance",
+ description="Update an IOU instance",
input=IOU_UPDATE_SCHEMA,
output=IOU_OBJECT_SCHEMA)
def update(request, response):
@@ -122,30 +125,28 @@ class IOUHandler:
vm.private_config = request.json.get("private_config_content")
response.json(vm)
- @classmethod
@Route.delete(
r"/projects/{project_id}/iou/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance deleted",
400: "Invalid request",
404: "Instance doesn't exist"
},
- description="Delete a IOU instance")
+ description="Delete an IOU instance")
def delete(request, response):
yield from IOU.instance().delete_node(request.match_info["node_id"])
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/iou/nodes/{node_id}/start",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
200: "Instance started",
@@ -154,7 +155,7 @@ class IOUHandler:
},
input=IOU_START_SCHEMA,
output=IOU_OBJECT_SCHEMA,
- description="Start a IOU instance")
+ description="Start an IOU instance")
def start(request, response):
iou_manager = IOU.instance()
@@ -167,19 +168,18 @@ class IOUHandler:
yield from vm.start()
response.json(vm)
- @classmethod
@Route.post(
r"/projects/{project_id}/iou/nodes/{node_id}/stop",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance stopped",
400: "Invalid request",
404: "Instance doesn't exist"
},
- description="Stop a IOU instance")
+ description="Stop an IOU instance")
def stop(request, response):
iou_manager = IOU.instance()
@@ -187,19 +187,18 @@ class IOUHandler:
yield from vm.stop()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/iou/nodes/{node_id}/reload",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
},
status_codes={
204: "Instance reloaded",
400: "Invalid request",
404: "Instance doesn't exist"
},
- description="Reload a IOU instance")
+ description="Reload an IOU instance")
def reload(request, response):
iou_manager = IOU.instance()
@@ -210,8 +209,8 @@ class IOUHandler:
@Route.post(
r"/projects/{project_id}/iou/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Network adapter where the nio is located",
"port_number": "Port where the nio should be added"
},
@@ -235,12 +234,11 @@ class IOUHandler:
response.set_status(201)
response.json(nio)
- @classmethod
@Route.delete(
r"/projects/{project_id}/iou/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Network adapter where the nio is located",
"port_number": "Port from where the nio should be removed"
},
@@ -260,8 +258,8 @@ class IOUHandler:
@Route.post(
r"/projects/{project_id}/iou/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/start_capture",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Adapter to start a packet capture",
"port_number": "Port on the adapter"
},
@@ -271,7 +269,7 @@ class IOUHandler:
404: "Instance doesn't exist",
409: "VM not started"
},
- description="Start a packet capture on a IOU VM instance",
+ description="Start a packet capture on an IOU VM instance",
input=NODE_CAPTURE_SCHEMA)
def start_capture(request, response):
@@ -288,8 +286,8 @@ class IOUHandler:
@Route.post(
r"/projects/{project_id}/iou/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/stop_capture",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Adapter to stop a packet capture",
"port_number": "Port on the adapter (always 0)"
},
@@ -299,7 +297,7 @@ class IOUHandler:
404: "Instance doesn't exist",
409: "VM not started"
},
- description="Stop a packet capture on a IOU VM instance")
+ description="Stop a packet capture on an IOU VM instance")
def stop_capture(request, response):
iou_manager = IOU.instance()
@@ -315,6 +313,10 @@ class IOUHandler:
@Route.get(
r"/projects/{project_id}/iou/nodes/{node_id}/configs",
+ parameters={
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
+ },
status_codes={
200: "Configs retrieved",
400: "Invalid request",
@@ -352,6 +354,10 @@ class IOUHandler:
@Route.post(
r"/projects/{project_id}/iou/nodes/{node_id}/configs/save",
+ parameters={
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
+ },
status_codes={
200: "Configs saved",
400: "Invalid request",
@@ -366,28 +372,31 @@ class IOUHandler:
response.set_status(200)
@Route.get(
- r"/iou/nodes",
+ r"/iou/images",
status_codes={
- 200: "List of IOU VM retrieved",
+ 200: "List of IOU images",
},
- description="Retrieve the list of IOU VMS",
+ description="Retrieve the list of IOU images",
output=NODE_LIST_IMAGES_SCHEMA)
- def list_iou_nodes(request, response):
+ def list_iou_images(request, response):
iou_manager = IOU.instance()
- iou_nodes = yield from iou_manager.list_images()
+ images = yield from iou_manager.list_images()
response.set_status(200)
- response.json(iou_nodes)
+ response.json(images)
@Route.post(
- r"/iou/nodes/{path}",
+ r"/iou/images/{filename:.+}",
+ parameters={
+ "filename": "Image filename"
+ },
status_codes={
204: "Image uploaded",
},
raw=True,
- description="Upload IOU image.")
+ description="Upload an IOU image")
def upload_image(request, response):
iou_manager = IOU.instance()
- yield from iou_manager.write_image(request.match_info["path"], request.content)
+ yield from iou_manager.write_image(request.match_info["filename"], request.content)
response.set_status(204)
diff --git a/gns3server/handlers/api/compute/network_handler.py b/gns3server/handlers/api/compute/network_handler.py
index e2da87ad..375c600c 100644
--- a/gns3server/handlers/api/compute/network_handler.py
+++ b/gns3server/handlers/api/compute/network_handler.py
@@ -15,19 +15,18 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-from ....web.route import Route
-from ....compute.port_manager import PortManager
-from ....compute.project_manager import ProjectManager
-from ....utils.interfaces import interfaces
+from gns3server.web.route import Route
+from gns3server.compute.port_manager import PortManager
+from gns3server.compute.project_manager import ProjectManager
+from gns3server.utils.interfaces import interfaces
class NetworkHandler:
- @classmethod
@Route.post(
r"/projects/{project_id}/ports/udp",
parameters={
- "project_id": "The UUID of the project",
+ "project_id": "Project UUID",
},
status_codes={
201: "UDP port allocated",
@@ -43,7 +42,6 @@ class NetworkHandler:
response.set_status(201)
response.json({"udp_port": udp_port})
- @classmethod
@Route.get(
r"/interfaces",
description="List all the network interfaces available on the server")
diff --git a/gns3server/handlers/api/compute/notification_handler.py b/gns3server/handlers/api/compute/notification_handler.py
index e0903f29..19fa64d9 100644
--- a/gns3server/handlers/api/compute/notification_handler.py
+++ b/gns3server/handlers/api/compute/notification_handler.py
@@ -17,17 +17,16 @@
import asyncio
-from ....web.route import Route
-from ....compute.notification_manager import NotificationManager
from aiohttp.web import WebSocketResponse
+from gns3server.web.route import Route
+from gns3server.compute.notification_manager import NotificationManager
class NotificationHandler:
- @classmethod
@Route.get(
r"/notifications/ws",
- description="Send notifications about what happend using websockets")
+ description="Send notifications using Websockets")
def notifications(request, response):
notifications = NotificationManager.instance()
ws = WebSocketResponse()
@@ -36,8 +35,8 @@ class NotificationHandler:
with notifications.queue() as queue:
while True:
try:
- notif = yield from queue.get_json(5)
- except asyncio.futures.CancelledError as e:
+ notification = yield from queue.get_json(5)
+ except asyncio.futures.CancelledError:
break
- ws.send_str(notif)
+ ws.send_str(notification)
return ws
diff --git a/gns3server/handlers/api/compute/project_handler.py b/gns3server/handlers/api/compute/project_handler.py
index 9315c0e5..2690c161 100644
--- a/gns3server/handlers/api/compute/project_handler.py
+++ b/gns3server/handlers/api/compute/project_handler.py
@@ -22,10 +22,17 @@ import os
import psutil
import tempfile
-from ....web.route import Route
-from ....schemas.project import PROJECT_OBJECT_SCHEMA, PROJECT_CREATE_SCHEMA, PROJECT_UPDATE_SCHEMA, PROJECT_FILE_LIST_SCHEMA, PROJECT_LIST_SCHEMA
-from ....compute.project_manager import ProjectManager
-from ....compute import MODULES
+from gns3server.web.route import Route
+from gns3server.compute.project_manager import ProjectManager
+from gns3server.compute import MODULES
+
+from gns3server.schemas.project import (
+ PROJECT_OBJECT_SCHEMA,
+ PROJECT_CREATE_SCHEMA,
+ PROJECT_UPDATE_SCHEMA,
+ PROJECT_FILE_LIST_SCHEMA,
+ PROJECT_LIST_SCHEMA
+)
import logging
log = logging.getLogger()
@@ -33,13 +40,12 @@ log = logging.getLogger()
class ProjectHandler:
- # How many clients has subcribe to notifications
+ # How many clients have subscribed to notifications
_notifications_listening = {}
- @classmethod
@Route.get(
r"/projects",
- description="List projects opened on the server",
+ description="List all projects opened on the server",
status_codes={
200: "Project list",
},
@@ -51,13 +57,12 @@ class ProjectHandler:
response.set_status(200)
response.json(list(pm.projects))
- @classmethod
@Route.post(
r"/projects",
description="Create a new project on the server",
status_codes={
201: "Project created",
- 403: "You are not allowed to modify this property",
+ 403: "Forbidden to create a project",
409: "Project already created"
},
output=PROJECT_OBJECT_SCHEMA,
@@ -74,12 +79,11 @@ class ProjectHandler:
response.set_status(201)
response.json(p)
- @classmethod
@Route.get(
r"/projects/{project_id}",
description="Get project information",
parameters={
- "project_id": "The UUID of the project",
+ "project_id": "Project UUID",
},
status_codes={
200: "Success",
@@ -92,16 +96,15 @@ class ProjectHandler:
project = pm.get_project(request.match_info["project_id"])
response.json(project)
- @classmethod
@Route.put(
r"/projects/{project_id}",
description="Update a project",
parameters={
- "project_id": "The UUID of the project",
+ "project_id": "Project UUID",
},
status_codes={
- 200: "The project has been updated",
- 403: "You are not allowed to modify this property",
+ 200: "Project updated",
+ 403: "Forbidden to update this project",
404: "The project doesn't exist"
},
output=PROJECT_OBJECT_SCHEMA,
@@ -118,16 +121,15 @@ class ProjectHandler:
for module in MODULES:
yield from module.instance().project_moved(project)
yield from project.clean_old_path(old_path)
- # Very important we need to remove temporary flag after moving the project
+ # Very important: we need to remove temporary flag after moving the project
project.temporary = request.json.get("temporary", project.temporary)
response.json(project)
- @classmethod
@Route.post(
r"/projects/{project_id}/commit",
description="Write changes on disk",
parameters={
- "project_id": "The UUID of the project",
+ "project_id": "Project UUID",
},
status_codes={
204: "Changes have been written on disk",
@@ -140,15 +142,14 @@ class ProjectHandler:
yield from project.commit()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/close",
description="Close a project",
parameters={
- "project_id": "The UUID of the project",
+ "project_id": "Project UUID",
},
status_codes={
- 204: "The project has been closed",
+ 204: "Project closed",
404: "The project doesn't exist"
})
def close(request, response):
@@ -160,15 +161,14 @@ class ProjectHandler:
pm.remove_project(project.id)
del ProjectHandler._notifications_listening[project.id]
else:
- log.warning("Skip project closing, another client is listening for project informations")
+ log.warning("Skip project closing, another client is listening for project notifications")
response.set_status(204)
- @classmethod
@Route.delete(
r"/projects/{project_id}",
description="Delete a project from disk",
parameters={
- "project_id": "The UUID of the project",
+ "project_id": "Project UUID",
},
status_codes={
204: "Changes have been written on disk",
@@ -182,12 +182,11 @@ class ProjectHandler:
pm.remove_project(project.id)
response.set_status(204)
- @classmethod
@Route.get(
r"/projects/{project_id}/notifications",
- description="Receive notifications about the projects",
+ description="Receive notifications about the project",
parameters={
- "project_id": "The UUID of the project",
+ "project_id": "Project UUID",
},
status_codes={
200: "End of stream",
@@ -201,7 +200,7 @@ class ProjectHandler:
response.content_type = "application/json"
response.set_status(200)
response.enable_chunked_encoding()
- # Very important: do not send a content lenght otherwise QT close the connection but curl can consume the Feed
+ # Very important: do not send a content length otherwise QT closes the connection (curl can consume the feed)
response.content_length = None
response.start(request)
@@ -226,30 +225,27 @@ class ProjectHandler:
if project.id in ProjectHandler._notifications_listening:
ProjectHandler._notifications_listening[project.id] -= 1
- @classmethod
def _getPingMessage(cls):
"""
- The ping message is regulary send to the client to
- keep the connection open. We send with it some informations
- about server load.
+ Ping messages are regularly sent to the client to
+ keep the connection open. We send with it some information about server load.
:returns: hash
"""
stats = {}
- # Non blocking call in order to get cpu usage. First call will return 0
+ # Non blocking call in order to get cpu usage. First call will return 0.
stats["cpu_usage_percent"] = psutil.cpu_percent(interval=None)
stats["memory_usage_percent"] = psutil.virtual_memory().percent
return {"action": "ping", "event": stats}
- @classmethod
@Route.get(
r"/projects/{project_id}/files",
description="List files of a project",
parameters={
- "project_id": "The UUID of the project",
+ "project_id": "Project UUID",
},
status_codes={
- 200: "Return list of files",
+ 200: "Return a list of files",
404: "The project doesn't exist"
},
output=PROJECT_FILE_LIST_SCHEMA)
@@ -261,15 +257,14 @@ class ProjectHandler:
response.json(files)
response.set_status(200)
- @classmethod
@Route.get(
r"/projects/{project_id}/files/{path:.+}",
- description="Get a file of a project",
+ description="Get a file from a project",
parameters={
- "project_id": "The UUID of the project",
+ "project_id": "Project UUID",
},
status_codes={
- 200: "Return the file",
+ 200: "File returned",
403: "Permission denied",
404: "The file doesn't exist"
})
@@ -280,7 +275,7 @@ class ProjectHandler:
path = request.match_info["path"]
path = os.path.normpath(path)
- # Raise error if user try to escape
+ # Raise an error if user try to escape
if path[0] == ".":
raise aiohttp.web.HTTPForbidden
path = os.path.join(project.path, path)
@@ -288,7 +283,7 @@ class ProjectHandler:
response.content_type = "application/octet-stream"
response.set_status(200)
response.enable_chunked_encoding()
- # Very important: do not send a content length otherwise QT close the connection but curl can consume the Feed
+ # Very important: do not send a content length otherwise QT closes the connection (curl can consume the feed)
response.content_length = None
try:
@@ -305,15 +300,14 @@ class ProjectHandler:
except PermissionError:
raise aiohttp.web.HTTPForbidden()
- @classmethod
@Route.get(
r"/projects/{project_id}/stream/{path:.+}",
description="Stream a file from a project",
parameters={
- "project_id": "The UUID of the project",
+ "project_id": "Project UUID",
},
status_codes={
- 200: "Return the file",
+ 200: "File returned",
403: "Permission denied",
404: "The file doesn't exist"
})
@@ -324,7 +318,7 @@ class ProjectHandler:
path = request.match_info["path"]
path = os.path.normpath(path)
- # Raise error if user try to escape
+ # Raise an error if user try to escape
if path[0] == ".":
raise aiohttp.web.HTTPForbidden
path = os.path.join(project.path, path)
@@ -332,7 +326,7 @@ class ProjectHandler:
response.content_type = "application/octet-stream"
response.set_status(200)
response.enable_chunked_encoding()
- # Very important: do not send a content length otherwise QT close the connection but curl can consume the Feed
+ # Very important: do not send a content length otherwise QT closes the connection (curl can consume the feed)
response.content_length = None
try:
@@ -349,16 +343,15 @@ class ProjectHandler:
except PermissionError:
raise aiohttp.web.HTTPForbidden()
- @classmethod
@Route.post(
r"/projects/{project_id}/files/{path:.+}",
- description="Get a file of a project",
+ description="Write a file to a project",
parameters={
- "project_id": "The UUID of the project",
+ "project_id": "Project UUID",
},
raw=True,
status_codes={
- 200: "Return the file",
+ 200: "File returned",
403: "Permission denied",
404: "The path doesn't exist"
})
@@ -389,16 +382,15 @@ class ProjectHandler:
except PermissionError:
raise aiohttp.web.HTTPForbidden()
- @classmethod
@Route.get(
r"/projects/{project_id}/export",
description="Export a project as a portable archive",
parameters={
- "project_id": "The UUID of the project",
+ "project_id": "Project UUID",
},
raw=True,
status_codes={
- 200: "Return the file",
+ 200: "File returned",
404: "The project doesn't exist"
})
def export_project(request, response):
@@ -408,7 +400,7 @@ class ProjectHandler:
response.content_type = 'application/gns3project'
response.headers['CONTENT-DISPOSITION'] = 'attachment; filename="{}.gns3project"'.format(project.name)
response.enable_chunked_encoding()
- # Very important: do not send a content length otherwise QT close the connection but curl can consume the Feed
+ # Very important: do not send a content length otherwise QT closes the connection (curl can consume the feed)
response.content_length = None
response.start(request)
@@ -418,18 +410,17 @@ class ProjectHandler:
yield from response.write_eof()
- @classmethod
@Route.post(
r"/projects/{project_id}/import",
description="Import a project from a portable archive",
parameters={
- "project_id": "The UUID of the project",
+ "project_id": "Project UUID",
},
raw=True,
output=PROJECT_OBJECT_SCHEMA,
status_codes={
200: "Project imported",
- 403: "You are not allowed to modify this property"
+ 403: "Forbidden to import project"
})
def import_project(request, response):
@@ -437,11 +428,9 @@ class ProjectHandler:
project_id = request.match_info["project_id"]
project = pm.create_project(project_id=project_id)
- # We write the content to a temporary location
- # and after extract all. It could be more optimal to stream
- # this but it's not implemented in Python.
- #
- # Spooled mean the file is temporary keep in ram until max_size
+ # We write the content to a temporary location and after we extract it all.
+ # It could be more optimal to stream this but it is not implemented in Python.
+ # Spooled means the file is temporary kept in memory until max_size is reached
try:
with tempfile.SpooledTemporaryFile(max_size=10000) as temp:
while True:
diff --git a/gns3server/handlers/api/compute/qemu_handler.py b/gns3server/handlers/api/compute/qemu_handler.py
index 23e42dca..fa7f2c13 100644
--- a/gns3server/handlers/api/compute/qemu_handler.py
+++ b/gns3server/handlers/api/compute/qemu_handler.py
@@ -19,19 +19,23 @@ import sys
import os.path
from aiohttp.web import HTTPConflict
-from ....web.route import Route
-from ....compute.project_manager import ProjectManager
-from ....schemas.nio import NIO_SCHEMA
-from ....schemas.qemu import QEMU_CREATE_SCHEMA
-from ....schemas.qemu import QEMU_UPDATE_SCHEMA
-from ....schemas.qemu import QEMU_OBJECT_SCHEMA
-from ....schemas.qemu import QEMU_BINARY_FILTER_SCHEMA
-from ....schemas.qemu import QEMU_BINARY_LIST_SCHEMA
-from ....schemas.qemu import QEMU_CAPABILITY_LIST_SCHEMA
-from ....schemas.qemu import QEMU_IMAGE_CREATE_SCHEMA
-from ....schemas.node import NODE_LIST_IMAGES_SCHEMA
-from ....compute.qemu import Qemu
-from ....config import Config
+
+from gns3server.web.route import Route
+from gns3server.compute.project_manager import ProjectManager
+from gns3server.schemas.nio import NIO_SCHEMA
+from gns3server.schemas.node import NODE_LIST_IMAGES_SCHEMA
+from gns3server.compute.qemu import Qemu
+from gns3server.config import Config
+
+from gns3server.schemas.qemu import (
+ QEMU_CREATE_SCHEMA,
+ QEMU_UPDATE_SCHEMA,
+ QEMU_OBJECT_SCHEMA,
+ QEMU_BINARY_LIST_SCHEMA,
+ QEMU_BINARY_FILTER_SCHEMA,
+ QEMU_CAPABILITY_LIST_SCHEMA,
+ QEMU_IMAGE_CREATE_SCHEMA
+)
class QEMUHandler:
@@ -40,11 +44,10 @@ class QEMUHandler:
API entry points for QEMU.
"""
- @classmethod
@Route.post(
r"/projects/{project_id}/qemu/nodes",
parameters={
- "project_id": "UUID for the project"
+ "project_id": "Project UUID"
},
status_codes={
201: "Instance created",
@@ -73,12 +76,11 @@ class QEMUHandler:
response.set_status(201)
response.json(vm)
- @classmethod
@Route.get(
r"/projects/{project_id}/qemu/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
200: "Success",
@@ -93,12 +95,11 @@ class QEMUHandler:
vm = qemu_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
response.json(vm)
- @classmethod
@Route.put(
r"/projects/{project_id}/qemu/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
200: "Instance updated",
@@ -120,12 +121,11 @@ class QEMUHandler:
response.json(vm)
- @classmethod
@Route.delete(
r"/projects/{project_id}/qemu/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance deleted",
@@ -138,12 +138,11 @@ class QEMUHandler:
yield from Qemu.instance().delete_node(request.match_info["node_id"])
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/qemu/nodes/{node_id}/start",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
200: "Instance started",
@@ -156,20 +155,18 @@ class QEMUHandler:
qemu_manager = Qemu.instance()
vm = qemu_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
- if sys.platform.startswith("linux") and qemu_manager.config.get_section_config("Qemu").getboolean("enable_kvm", True) \
- and "-no-kvm" not in vm.options:
+ if sys.platform.startswith("linux") and qemu_manager.config.get_section_config("Qemu").getboolean("enable_kvm", True) and "-no-kvm" not in vm.options:
pm = ProjectManager.instance()
if pm.check_hardware_virtualization(vm) is False:
raise HTTPConflict(text="Cannot start VM with KVM enabled because hardware virtualization (VT-x/AMD-V) is already used by another software like VMware or VirtualBox")
yield from vm.start()
response.json(vm)
- @classmethod
@Route.post(
r"/projects/{project_id}/qemu/nodes/{node_id}/stop",
parameters={
- "project_id": "UUID for the project",
- "vm_node": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance stopped",
@@ -184,12 +181,11 @@ class QEMUHandler:
yield from vm.stop()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/qemu/nodes/{node_id}/reload",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
},
status_codes={
204: "Instance reloaded",
@@ -204,12 +200,11 @@ class QEMUHandler:
yield from vm.reload()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/qemu/nodes/{node_id}/suspend",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
},
status_codes={
204: "Instance suspended",
@@ -224,12 +219,11 @@ class QEMUHandler:
yield from vm.suspend()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/qemu/nodes/{node_id}/resume",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
},
status_codes={
204: "Instance resumed",
@@ -247,8 +241,8 @@ class QEMUHandler:
@Route.post(
r"/projects/{project_id}/qemu/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Network adapter where the nio is located",
"port_number": "Port on the adapter (always 0)"
},
@@ -272,12 +266,11 @@ class QEMUHandler:
response.set_status(201)
response.json(nio)
- @classmethod
@Route.delete(
r"/projects/{project_id}/qemu/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Network adapter where the nio is located",
"port_number": "Port on the adapter (always 0)"
},
@@ -294,7 +287,6 @@ class QEMUHandler:
yield from vm.adapter_remove_nio_binding(int(request.match_info["adapter_number"]))
response.set_status(204)
- @classmethod
@Route.get(
r"/qemu/binaries",
status_codes={
@@ -310,7 +302,6 @@ class QEMUHandler:
binaries = yield from Qemu.binary_list(request.json.get("archs", None))
response.json(binaries)
- @classmethod
@Route.get(
r"/qemu/img-binaries",
status_codes={
@@ -340,7 +331,6 @@ class QEMUHandler:
capabilities["kvm"] = kvms
response.json(capabilities)
- @classmethod
@Route.post(
r"/qemu/img",
status_codes={
@@ -363,28 +353,31 @@ class QEMUHandler:
response.set_status(201)
@Route.get(
- r"/qemu/nodes",
+ r"/qemu/images",
status_codes={
- 200: "List of Qemu images retrieved",
+ 200: "List of Qemu images",
},
description="Retrieve the list of Qemu images",
output=NODE_LIST_IMAGES_SCHEMA)
- def list_vm_nodes(request, response):
+ def list_qemu_images(request, response):
qemu_manager = Qemu.instance()
- vm_nodes = yield from qemu_manager.list_images()
+ images = yield from qemu_manager.list_images()
response.set_status(200)
- response.json(vm_nodes)
+ response.json(images)
@Route.post(
- r"/qemu/nodes/{path:.+}",
+ r"/qemu/images/{filename:.+}",
+ parameters={
+ "filename": "Image filename"
+ },
status_codes={
204: "Image uploaded",
},
raw=True,
- description="Upload Qemu image.")
+ description="Upload Qemu image")
def upload_image(request, response):
qemu_manager = Qemu.instance()
- yield from qemu_manager.write_image(request.match_info["path"], request.content)
+ yield from qemu_manager.write_image(request.match_info["filename"], request.content)
response.set_status(204)
diff --git a/gns3server/handlers/api/compute/version_handler.py b/gns3server/handlers/api/compute/version_handler.py
index dad6d31b..b45f4aa9 100644
--- a/gns3server/handlers/api/compute/version_handler.py
+++ b/gns3server/handlers/api/compute/version_handler.py
@@ -15,16 +15,15 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-from ....web.route import Route
-from ....config import Config
-from ....schemas.version import VERSION_SCHEMA
-from ....version import __version__
+from gns3server.web.route import Route
+from gns3server.config import Config
+from gns3server.schemas.version import VERSION_SCHEMA
+from gns3server.version import __version__
from aiohttp.web import HTTPConflict
class VersionHandler:
- @classmethod
@Route.get(
r"/version",
description="Retrieve the server version number",
@@ -35,7 +34,6 @@ class VersionHandler:
local_server = config.get_section_config("Server").getboolean("local", False)
response.json({"version": __version__, "local": local_server})
- @classmethod
@Route.post(
r"/version",
description="Check if version is the same as the server",
diff --git a/gns3server/handlers/api/compute/virtualbox_handler.py b/gns3server/handlers/api/compute/virtualbox_handler.py
index d23a24cd..c0f28d4f 100644
--- a/gns3server/handlers/api/compute/virtualbox_handler.py
+++ b/gns3server/handlers/api/compute/virtualbox_handler.py
@@ -18,15 +18,17 @@
import os
from aiohttp.web import HTTPConflict
-from ....web.route import Route
-from ....schemas.nio import NIO_SCHEMA
-from ....schemas.virtualbox import VBOX_CREATE_SCHEMA
-from ....schemas.virtualbox import VBOX_UPDATE_SCHEMA
-from ....schemas.virtualbox import VBOX_OBJECT_SCHEMA
-from ....schemas.node import NODE_CAPTURE_SCHEMA
-from ....compute.virtualbox import VirtualBox
-from ....compute.project_manager import ProjectManager
+from gns3server.web.route import Route
+from gns3server.schemas.nio import NIO_SCHEMA
+from gns3server.schemas.node import NODE_CAPTURE_SCHEMA
+from gns3server.compute.virtualbox import VirtualBox
+from gns3server.compute.project_manager import ProjectManager
+from gns3server.schemas.virtualbox import (
+ VBOX_CREATE_SCHEMA,
+ VBOX_UPDATE_SCHEMA,
+ VBOX_OBJECT_SCHEMA
+)
class VirtualBoxHandler:
@@ -34,24 +36,10 @@ class VirtualBoxHandler:
API entry points for VirtualBox.
"""
- @classmethod
- @Route.get(
- r"/virtualbox/vms",
- status_codes={
- 200: "Success",
- },
- description="Get all available VirtualBox VMs")
- def index(request, response):
-
- vbox_manager = VirtualBox.instance()
- vms = yield from vbox_manager.list_images()
- response.json(vms)
-
- @classmethod
@Route.post(
r"/projects/{project_id}/virtualbox/nodes",
parameters={
- "project_id": "UUID for the project"
+ "project_id": "Project UUID"
},
status_codes={
201: "Instance created",
@@ -88,12 +76,11 @@ class VirtualBoxHandler:
response.set_status(201)
response.json(vm)
- @classmethod
@Route.get(
r"/projects/{project_id}/virtualbox/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
200: "Success",
@@ -108,12 +95,11 @@ class VirtualBoxHandler:
vm = vbox_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
response.json(vm)
- @classmethod
@Route.put(
r"/projects/{project_id}/virtualbox/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
200: "Instance updated",
@@ -153,12 +139,11 @@ class VirtualBoxHandler:
response.json(vm)
- @classmethod
@Route.delete(
r"/projects/{project_id}/virtualbox/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance deleted",
@@ -170,16 +155,14 @@ class VirtualBoxHandler:
# check the project_id exists
ProjectManager.instance().get_project(request.match_info["project_id"])
-
yield from VirtualBox.instance().delete_node(request.match_info["node_id"])
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/virtualbox/nodes/{node_id}/start",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance started",
@@ -198,12 +181,11 @@ class VirtualBoxHandler:
yield from vm.start()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/virtualbox/nodes/{node_id}/stop",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance stopped",
@@ -218,12 +200,11 @@ class VirtualBoxHandler:
yield from vm.stop()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/virtualbox/nodes/{node_id}/suspend",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance suspended",
@@ -238,12 +219,11 @@ class VirtualBoxHandler:
yield from vm.suspend()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/virtualbox/nodes/{node_id}/resume",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance resumed",
@@ -258,12 +238,11 @@ class VirtualBoxHandler:
yield from vm.resume()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/virtualbox/nodes/{node_id}/reload",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance reloaded",
@@ -281,8 +260,8 @@ class VirtualBoxHandler:
@Route.post(
r"/projects/{project_id}/virtualbox/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Adapter where the nio should be added",
"port_number": "Port on the adapter (always 0)"
},
@@ -306,12 +285,11 @@ class VirtualBoxHandler:
response.set_status(201)
response.json(nio)
- @classmethod
@Route.delete(
r"/projects/{project_id}/virtualbox/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Adapter from where the nio should be removed",
"port_number": "Port on the adapter (always 0)"
},
@@ -331,8 +309,8 @@ class VirtualBoxHandler:
@Route.post(
r"/projects/{project_id}/virtualbox/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/start_capture",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Adapter to start a packet capture",
"port_number": "Port on the adapter (always 0)"
},
@@ -355,8 +333,8 @@ class VirtualBoxHandler:
@Route.post(
r"/projects/{project_id}/virtualbox/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/stop_capture",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Adapter to stop a packet capture",
"port_number": "Port on the adapter (always 0)"
},
@@ -372,3 +350,14 @@ class VirtualBoxHandler:
vm = vbox_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
vm.stop_capture(int(request.match_info["adapter_number"]))
response.set_status(204)
+
+ @Route.get(
+ r"/virtualbox/vms",
+ status_codes={
+ 200: "Success",
+ },
+ description="Get all available VirtualBox VMs")
+ def get_vms(request, response):
+ vbox_manager = VirtualBox.instance()
+ vms = yield from vbox_manager.list_vms()
+ response.json(vms)
diff --git a/gns3server/handlers/api/compute/vmware_handler.py b/gns3server/handlers/api/compute/vmware_handler.py
index 1dfe2408..da268c12 100644
--- a/gns3server/handlers/api/compute/vmware_handler.py
+++ b/gns3server/handlers/api/compute/vmware_handler.py
@@ -18,14 +18,17 @@
import os
from aiohttp.web import HTTPConflict
-from ....web.route import Route
-from ....schemas.vmware import VMWARE_CREATE_SCHEMA
-from ....schemas.vmware import VMWARE_UPDATE_SCHEMA
-from ....schemas.vmware import VMWARE_OBJECT_SCHEMA
-from ....schemas.node import NODE_CAPTURE_SCHEMA
-from ....schemas.nio import NIO_SCHEMA
-from ....compute.vmware import VMware
-from ....compute.project_manager import ProjectManager
+from gns3server.web.route import Route
+from gns3server.schemas.node import NODE_CAPTURE_SCHEMA
+from gns3server.schemas.nio import NIO_SCHEMA
+from gns3server.compute.vmware import VMware
+from gns3server.compute.project_manager import ProjectManager
+
+from gns3server.schemas.vmware import (
+ VMWARE_CREATE_SCHEMA,
+ VMWARE_UPDATE_SCHEMA,
+ VMWARE_OBJECT_SCHEMA
+)
class VMwareHandler:
@@ -34,24 +37,10 @@ class VMwareHandler:
API entry points for VMware.
"""
- @classmethod
- @Route.get(
- r"/vmware/vms",
- status_codes={
- 200: "Success",
- },
- description="Get all VMware VMs available")
- def index(request, response):
-
- vmware_manager = VMware.instance()
- vms = yield from vmware_manager.list_vms()
- response.json(vms)
-
- @classmethod
@Route.post(
r"/projects/{project_id}/vmware/nodes",
parameters={
- "project_id": "UUID for the project"
+ "project_id": "Project UUID"
},
status_codes={
201: "Instance created",
@@ -79,12 +68,11 @@ class VMwareHandler:
response.set_status(201)
response.json(vm)
- @classmethod
@Route.get(
r"/projects/{project_id}/vmware/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
200: "Success",
@@ -99,12 +87,11 @@ class VMwareHandler:
vm = vmware_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
response.json(vm)
- @classmethod
@Route.put(
r"/projects/{project_id}/vmware/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
200: "Instance updated",
@@ -126,12 +113,11 @@ class VMwareHandler:
response.json(vm)
- @classmethod
@Route.delete(
r"/projects/{project_id}/vmware/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance deleted",
@@ -146,12 +132,11 @@ class VMwareHandler:
yield from VMware.instance().delete_node(request.match_info["node_id"])
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/vmware/nodes/{node_id}/start",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance started",
@@ -170,12 +155,11 @@ class VMwareHandler:
yield from vm.start()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/vmware/nodes/{node_id}/stop",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance stopped",
@@ -190,12 +174,11 @@ class VMwareHandler:
yield from vm.stop()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/vmware/nodes/{node_id}/suspend",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance suspended",
@@ -210,12 +193,11 @@ class VMwareHandler:
yield from vm.suspend()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/vmware/nodes/{node_id}/resume",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance resumed",
@@ -230,12 +212,11 @@ class VMwareHandler:
yield from vm.resume()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/vmware/nodes/{node_id}/reload",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance reloaded",
@@ -253,8 +234,8 @@ class VMwareHandler:
@Route.post(
r"/projects/{project_id}/vmware/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Adapter where the nio should be added",
"port_number": "Port on the adapter (always 0)"
},
@@ -278,12 +259,11 @@ class VMwareHandler:
response.set_status(201)
response.json(nio)
- @classmethod
@Route.delete(
r"/projects/{project_id}/vmware/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Adapter from where the nio should be removed",
"port_number": "Port on the adapter (always 0)"
},
@@ -303,8 +283,8 @@ class VMwareHandler:
@Route.post(
r"/projects/{project_id}/vmware/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/start_capture",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Adapter to start a packet capture",
"port_number": "Port on the adapter (always 0)"
},
@@ -327,8 +307,8 @@ class VMwareHandler:
@Route.post(
r"/projects/{project_id}/vmware/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/stop_capture",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Adapter to stop a packet capture",
"port_number": "Port on the adapter (always 0)"
},
@@ -346,12 +326,11 @@ class VMwareHandler:
yield from vm.stop_capture(adapter_number)
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/vmware/nodes/{node_id}/interfaces/vmnet",
parameters={
- "project_id": "The UUID of the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
},
status_codes={
201: "VMnet interface allocated",
@@ -366,3 +345,14 @@ class VMwareHandler:
vm.vmnets.append(vmnet)
response.set_status(201)
response.json({"vmnet": vmnet})
+
+ @Route.get(
+ r"/vmware/vms",
+ status_codes={
+ 200: "Success",
+ },
+ description="Get all VMware VMs available")
+ def get_vms(request, response):
+ vmware_manager = VMware.instance()
+ vms = yield from vmware_manager.list_vms()
+ response.json(vms)
diff --git a/gns3server/handlers/api/compute/vpcs_handler.py b/gns3server/handlers/api/compute/vpcs_handler.py
index 9e540076..288e3d77 100644
--- a/gns3server/handlers/api/compute/vpcs_handler.py
+++ b/gns3server/handlers/api/compute/vpcs_handler.py
@@ -16,12 +16,15 @@
# along with this program. If not, see .
from aiohttp.web import HTTPConflict
-from ....web.route import Route
-from ....schemas.nio import NIO_SCHEMA
-from ....schemas.vpcs import VPCS_CREATE_SCHEMA
-from ....schemas.vpcs import VPCS_UPDATE_SCHEMA
-from ....schemas.vpcs import VPCS_OBJECT_SCHEMA
-from ....compute.vpcs import VPCS
+from gns3server.web.route import Route
+from gns3server.schemas.nio import NIO_SCHEMA
+from gns3server.compute.vpcs import VPCS
+
+from gns3server.schemas.vpcs import (
+ VPCS_CREATE_SCHEMA,
+ VPCS_UPDATE_SCHEMA,
+ VPCS_OBJECT_SCHEMA
+)
class VPCSHandler:
@@ -30,11 +33,10 @@ class VPCSHandler:
API entry points for VPCS.
"""
- @classmethod
@Route.post(
r"/projects/{project_id}/vpcs/nodes",
parameters={
- "project_id": "UUID for the project"
+ "project_id": "Project UUID"
},
status_codes={
201: "Instance created",
@@ -47,20 +49,19 @@ class VPCSHandler:
def create(request, response):
vpcs = VPCS.instance()
- node = yield from vpcs.create_node(request.json["name"],
- request.match_info["project_id"],
- request.json.get("node_id"),
- console=request.json.get("console"),
- startup_script=request.json.get("startup_script"))
+ vm = yield from vpcs.create_node(request.json["name"],
+ request.match_info["project_id"],
+ request.json.get("node_id"),
+ console=request.json.get("console"),
+ startup_script=request.json.get("startup_script"))
response.set_status(201)
- response.json(node)
+ response.json(vm)
- @classmethod
@Route.get(
r"/projects/{project_id}/vpcs/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
200: "Success",
@@ -75,12 +76,11 @@ class VPCSHandler:
vm = vpcs_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
response.json(vm)
- @classmethod
@Route.put(
r"/projects/{project_id}/vpcs/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
200: "Instance updated",
@@ -100,12 +100,11 @@ class VPCSHandler:
vm.startup_script = request.json.get("startup_script", vm.startup_script)
response.json(vm)
- @classmethod
@Route.delete(
r"/projects/{project_id}/vpcs/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance deleted",
@@ -118,12 +117,11 @@ class VPCSHandler:
yield from VPCS.instance().delete_node(request.match_info["node_id"])
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/vpcs/nodes/{node_id}/start",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance started",
@@ -139,12 +137,11 @@ class VPCSHandler:
yield from vm.start()
response.json(vm)
- @classmethod
@Route.post(
r"/projects/{project_id}/vpcs/nodes/{node_id}/stop",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
204: "Instance stopped",
@@ -159,12 +156,11 @@ class VPCSHandler:
yield from vm.stop()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/vpcs/nodes/{node_id}/reload",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
},
status_codes={
204: "Instance reloaded",
@@ -182,8 +178,8 @@ class VPCSHandler:
@Route.post(
r"/projects/{project_id}/vpcs/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Network adapter where the nio is located",
"port_number": "Port where the nio should be added"
},
@@ -207,12 +203,11 @@ class VPCSHandler:
response.set_status(201)
response.json(nio)
- @classmethod
@Route.delete(
r"/projects/{project_id}/vpcs/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the instance",
+ "project_id": "Project UUID",
+ "node_id": "Node UUID",
"adapter_number": "Network adapter where the nio is located",
"port_number": "Port from where the nio should be removed"
},
diff --git a/gns3server/handlers/api/controller/compute_handler.py b/gns3server/handlers/api/controller/compute_handler.py
index 0037ea3c..57dc373e 100644
--- a/gns3server/handlers/api/controller/compute_handler.py
+++ b/gns3server/handlers/api/controller/compute_handler.py
@@ -18,27 +18,24 @@
import asyncio
from aiohttp.web import HTTPForbidden
-from ....web.route import Route
-from ....config import Config
-from ....compute.project_manager import ProjectManager
-from ....schemas.compute import COMPUTE_CREATE_SCHEMA, COMPUTE_OBJECT_SCHEMA
-from ....controller import Controller
-from ....controller.compute import Compute
-
+from gns3server.web.route import Route
+from gns3server.config import Config
+from gns3server.compute.project_manager import ProjectManager
+from gns3server.schemas.compute import COMPUTE_CREATE_SCHEMA, COMPUTE_OBJECT_SCHEMA
+from gns3server.controller import Controller
import logging
log = logging.getLogger(__name__)
class ComputeHandler:
- """API entry points for compute management."""
+ """API entry points for compute server management."""
- @classmethod
@Route.post(
r"/computes",
- description="Register a compute",
+ description="Register a compute server",
status_codes={
- 201: "Compute added"
+ 201: "Compute server added"
},
input=COMPUTE_CREATE_SCHEMA,
output=COMPUTE_OBJECT_SCHEMA)
@@ -48,31 +45,29 @@ class ComputeHandler:
response.set_status(201)
response.json(compute)
- @classmethod
@Route.get(
r"/computes",
- description="List compute nodes",
+ description="List of compute server",
status_codes={
- 200: "Compute list"
+ 200: "Compute servers list returned"
})
def list(request, response):
controller = Controller.instance()
response.json([c for c in controller.computes.values()])
- @classmethod
@Route.post(
r"/computes/shutdown",
- description="Shutdown the local compute",
+ description="Shutdown a local compute server",
status_codes={
- 201: "Compute is shutting down",
- 403: "Compute shutdown refused"
+ 201: "Compute server is shutting down",
+ 403: "Compute server shutdown refused"
})
def shutdown(request, response):
config = Config.instance()
if config.get_section_config("Server").getboolean("local", False) is False:
- raise HTTPForbidden(text="You can only stop a local server")
+ raise HTTPForbidden(text="Only a local server can be shutdown")
# close all the projects first
pm = ProjectManager.instance()
@@ -97,12 +92,12 @@ class ComputeHandler:
asyncio.async(server.shutdown_server())
response.set_status(201)
- @classmethod
+
@Route.get(
r"/computes/{compute_id:.+}",
- description="Get a compute node informations",
+ description="Get a compute server information",
status_codes={
- 200: "Compute list"
+ 200: "Compute server information returned"
},
output=COMPUTE_OBJECT_SCHEMA)
def get(request, response):
diff --git a/gns3server/handlers/api/controller/link_handler.py b/gns3server/handlers/api/controller/link_handler.py
index b38a356e..3491da1e 100644
--- a/gns3server/handlers/api/controller/link_handler.py
+++ b/gns3server/handlers/api/controller/link_handler.py
@@ -17,9 +17,13 @@
import aiohttp
-from ....web.route import Route
-from ....schemas.link import LINK_OBJECT_SCHEMA, LINK_CAPTURE_SCHEMA
-from ....controller import Controller
+from gns3server.web.route import Route
+from gns3server.controller import Controller
+
+from gns3server.schemas.link import (
+ LINK_OBJECT_SCHEMA,
+ LINK_CAPTURE_SCHEMA
+)
class LinkHandler:
@@ -27,11 +31,10 @@ class LinkHandler:
API entry point for Link
"""
- @classmethod
@Route.post(
r"/projects/{project_id}/links",
parameters={
- "project_id": "UUID for the project"
+ "project_id": "Project UUID"
},
status_codes={
201: "Link created",
@@ -51,12 +54,11 @@ class LinkHandler:
response.set_status(201)
response.json(link)
- @classmethod
@Route.post(
r"/projects/{project_id}/links/{link_id}/start_capture",
parameters={
- "project_id": "UUID for the project",
- "link_id": "UUID of the link"
+ "project_id": "Project UUID",
+ "link_id": "Link UUID"
},
status_codes={
201: "Capture started",
@@ -64,7 +66,7 @@ class LinkHandler:
},
input=LINK_CAPTURE_SCHEMA,
output=LINK_OBJECT_SCHEMA,
- description="Start capture on a link instance. By default we consider it as an ethernet link")
+ description="Start capture on a link instance. By default we consider it as an Ethernet link")
def start_capture(request, response):
controller = Controller.instance()
@@ -74,12 +76,11 @@ class LinkHandler:
response.set_status(201)
response.json(link)
- @classmethod
@Route.post(
r"/projects/{project_id}/links/{link_id}/stop_capture",
parameters={
- "project_id": "UUID for the project",
- "link_id": "UUID of the link"
+ "project_id": "Project UUID",
+ "link_id": "Link UUID"
},
status_codes={
201: "Capture stopped",
@@ -95,12 +96,11 @@ class LinkHandler:
response.set_status(201)
response.json(link)
- @classmethod
@Route.delete(
r"/projects/{project_id}/links/{link_id}",
parameters={
- "project_id": "UUID for the project",
- "link_id": "UUID of the link"
+ "project_id": "Project UUID",
+ "link_id": "Link UUID"
},
status_codes={
204: "Link deleted",
@@ -116,16 +116,15 @@ class LinkHandler:
response.set_status(204)
response.json(link)
- @classmethod
@Route.get(
r"/projects/{project_id}/links/{link_id}/pcap",
parameters={
- "project_id": "UUID for the project",
- "link_id": "UUID of the link"
+ "project_id": "Project UUID",
+ "link_id": "Link UUID"
},
- description="Get the pcap from the capture",
+ description="Steam the pcap capture file",
status_codes={
- 200: "Return the file",
+ 200: "File returned",
403: "Permission denied",
404: "The file doesn't exist"
})
@@ -145,7 +144,7 @@ class LinkHandler:
response.content_type = "application/vnd.tcpdump.pcap"
response.set_status(200)
response.enable_chunked_encoding()
- # Very important: do not send a content length otherwise QT close the connection but curl can consume the Feed
+ # Very important: do not send a content length otherwise QT closes the connection (curl can consume the feed)
response.content_length = None
response.start(request)
diff --git a/gns3server/handlers/api/controller/node_handler.py b/gns3server/handlers/api/controller/node_handler.py
index 7bd6b579..da438204 100644
--- a/gns3server/handlers/api/controller/node_handler.py
+++ b/gns3server/handlers/api/controller/node_handler.py
@@ -15,9 +15,13 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-from ....web.route import Route
-from ....schemas.node import NODE_OBJECT_SCHEMA, NODE_UPDATE_SCHEMA
-from ....controller import Controller
+from gns3server.web.route import Route
+from gns3server.controller import Controller
+
+from gns3server.schemas.node import (
+ NODE_OBJECT_SCHEMA,
+ NODE_UPDATE_SCHEMA
+)
class NodeHandler:
@@ -25,11 +29,10 @@ class NodeHandler:
API entry point for node
"""
- @classmethod
@Route.post(
r"/projects/{project_id}/nodes",
parameters={
- "project_id": "UUID for the project"
+ "project_id": "Project UUID"
},
status_codes={
201: "Instance created",
@@ -47,28 +50,27 @@ class NodeHandler:
response.set_status(201)
response.json(node)
- @classmethod
@Route.get(
r"/projects/{project_id}/nodes",
parameters={
- "project_id": "UUID for the project"
+ "project_id": "Project UUID"
},
status_codes={
- 200: "List of nodes",
+ 200: "List of nodes returned",
},
description="List nodes of a project")
def list_nodes(request, response):
controller = Controller.instance()
project = controller.get_project(request.match_info["project_id"])
- response.json([ v for v in project.nodes.values() ])
+ response.json([v for v in project.nodes.values()])
- @classmethod
@Route.put(
r"/projects/{project_id}/nodes/{node_id}",
status_codes={
- 201: "Instance created",
- 400: "Invalid request"
+ 200: "Instance updated",
+ 400: "Invalid request",
+ 404: "Instance doesn't exist"
},
description="Update a node instance",
input=NODE_UPDATE_SCHEMA,
@@ -77,25 +79,25 @@ class NodeHandler:
project = Controller.instance().get_project(request.match_info["project_id"])
node = project.get_node(request.match_info["node_id"])
- # Ignore this, because we use it only in create
+ # Ignore these because we only use them when creating a node
request.json.pop("node_id", None)
request.json.pop("node_type", None)
request.json.pop("compute_id", None)
yield from node.update(**request.json)
- response.set_status(201)
+ response.set_status(200)
response.json(node)
- @classmethod
@Route.post(
r"/projects/{project_id}/nodes/{node_id}/start",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the node"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
- 201: "Instance created",
- 400: "Invalid request"
+ 204: "Instance started",
+ 400: "Invalid request",
+ 404: "Instance doesn't exist"
},
description="Start a node instance",
output=NODE_OBJECT_SCHEMA)
@@ -104,61 +106,58 @@ class NodeHandler:
project = Controller.instance().get_project(request.match_info["project_id"])
node = project.get_node(request.match_info["node_id"])
yield from node.start()
- response.set_status(201)
- response.json(node)
+ response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/nodes/{node_id}/stop",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the node"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
- 201: "Instance created",
- 400: "Invalid request"
+ 204: "Instance stopped",
+ 400: "Invalid request",
+ 404: "Instance doesn't exist"
},
- description="Start a node instance",
+ description="Stop a node instance",
output=NODE_OBJECT_SCHEMA)
def stop(request, response):
project = Controller.instance().get_project(request.match_info["project_id"])
node = project.get_node(request.match_info["node_id"])
yield from node.stop()
- response.set_status(201)
- response.json(node)
+ response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/nodes/{node_id}/suspend",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the node"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
- 201: "Instance created",
- 400: "Invalid request"
+ 204: "Instance suspended",
+ 400: "Invalid request",
+ 404: "Instance doesn't exist"
},
- description="Start a node instance",
+ description="Suspend a node instance",
output=NODE_OBJECT_SCHEMA)
def suspend(request, response):
project = Controller.instance().get_project(request.match_info["project_id"])
node = project.get_node(request.match_info["node_id"])
yield from node.suspend()
- response.set_status(201)
- response.json(node)
+ response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/nodes/{node_id}/reload",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the node"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
- 201: "Instance created",
- 400: "Invalid request"
+ 204: "Instance reloaded",
+ 400: "Invalid request",
+ 404: "Instance doesn't exist"
},
description="Reload a node instance",
output=NODE_OBJECT_SCHEMA)
@@ -167,23 +166,22 @@ class NodeHandler:
project = Controller.instance().get_project(request.match_info["project_id"])
node = project.get_node(request.match_info["node_id"])
yield from node.reload()
- response.set_status(201)
- response.json(node)
+ response.set_status(204)
- @classmethod
@Route.delete(
r"/projects/{project_id}/nodes/{node_id}",
parameters={
- "project_id": "UUID for the project",
- "node_id": "UUID for the node"
+ "project_id": "Project UUID",
+ "node_id": "Node UUID"
},
status_codes={
- 201: "Instance deleted",
- 400: "Invalid request"
+ 204: "Instance deleted",
+ 400: "Invalid request",
+ 404: "Instance doesn't exist"
},
description="Delete a node instance")
def delete(request, response):
project = Controller.instance().get_project(request.match_info["project_id"])
node = project.get_node(request.match_info["node_id"])
yield from node.destroy()
- response.set_status(201)
+ response.set_status(204)
diff --git a/gns3server/handlers/api/controller/project_handler.py b/gns3server/handlers/api/controller/project_handler.py
index 35db544b..9f1e6b95 100644
--- a/gns3server/handlers/api/controller/project_handler.py
+++ b/gns3server/handlers/api/controller/project_handler.py
@@ -19,10 +19,13 @@ import aiohttp
import asyncio
-from ....web.route import Route
-from ....schemas.project import PROJECT_OBJECT_SCHEMA, PROJECT_CREATE_SCHEMA
-from ....controller import Controller
+from gns3server.web.route import Route
+from gns3server.controller import Controller
+from gns3server.schemas.project import (
+ PROJECT_OBJECT_SCHEMA,
+ PROJECT_CREATE_SCHEMA
+)
import logging
log = logging.getLogger()
@@ -30,7 +33,6 @@ log = logging.getLogger()
class ProjectHandler:
- @classmethod
@Route.post(
r"/projects",
description="Create a new project on the server",
@@ -43,15 +45,13 @@ class ProjectHandler:
def create_project(request, response):
controller = Controller.instance()
- project = yield from controller.addProject(
- name=request.json.get("name"),
- path=request.json.get("path"),
- project_id=request.json.get("project_id"),
- temporary=request.json.get("temporary", False))
+ project = yield from controller.add_project(name=request.json.get("name"),
+ path=request.json.get("path"),
+ project_id=request.json.get("project_id"),
+ temporary=request.json.get("temporary", False))
response.set_status(201)
response.json(project)
- @classmethod
@Route.get(
r"/projects",
description="List projects",
@@ -60,17 +60,16 @@ class ProjectHandler:
})
def list_projects(request, response):
controller = Controller.instance()
- response.json([ p for p in controller.projects.values() ])
+ response.json([p for p in controller.projects.values()])
- @classmethod
@Route.get(
r"/projects/{project_id}",
- description="Get the project",
+ description="Get a project",
parameters={
- "project_id": "The UUID of the project",
+ "project_id": "Project UUID",
},
status_codes={
- 200: "The project exist",
+ 200: "Project information returned",
404: "The project doesn't exist"
})
def get(request, response):
@@ -78,12 +77,11 @@ class ProjectHandler:
project = controller.get_project(request.match_info["project_id"])
response.json(project)
- @classmethod
@Route.post(
r"/projects/{project_id}/commit",
description="Write changes on disk",
parameters={
- "project_id": "The UUID of the project",
+ "project_id": "Project UUID",
},
status_codes={
204: "Changes have been written on disk",
@@ -96,12 +94,11 @@ class ProjectHandler:
yield from project.commit()
response.set_status(204)
- @classmethod
@Route.post(
r"/projects/{project_id}/close",
description="Close a project",
parameters={
- "project_id": "The UUID of the project",
+ "project_id": "Project UUID",
},
status_codes={
204: "The project has been closed",
@@ -115,12 +112,11 @@ class ProjectHandler:
controller.remove_project(project)
response.set_status(204)
- @classmethod
@Route.delete(
r"/projects/{project_id}",
description="Delete a project from disk",
parameters={
- "project_id": "The UUID of the project",
+ "project_id": "Project UUID",
},
status_codes={
204: "Changes have been written on disk",
@@ -134,12 +130,11 @@ class ProjectHandler:
controller.remove_project(project)
response.set_status(204)
- @classmethod
@Route.get(
r"/projects/{project_id}/notifications",
- description="Receive notifications about the projects",
+ description="Receive notifications about projects",
parameters={
- "project_id": "The UUID of the project",
+ "project_id": "Project UUID",
},
status_codes={
200: "End of stream",
@@ -153,7 +148,7 @@ class ProjectHandler:
response.content_type = "application/json"
response.set_status(200)
response.enable_chunked_encoding()
- # Very important: do not send a content lenght otherwise QT close the connection but curl can consume the Feed
+ # Very important: do not send a content length otherwise QT closes the connection (curl can consume the feed)
response.content_length = None
response.start(request)
@@ -165,12 +160,11 @@ class ProjectHandler:
except asyncio.futures.CancelledError as e:
break
- @classmethod
@Route.get(
r"/projects/{project_id}/notifications/ws",
- description="Receive notifications about the projects via Websocket",
+ description="Receive notifications about projects from a Websocket",
parameters={
- "project_id": "The UUID of the project",
+ "project_id": "Project UUID",
},
status_codes={
200: "End of stream",
@@ -187,8 +181,8 @@ class ProjectHandler:
with project.queue() as queue:
while True:
try:
- notif = yield from queue.get_json(5)
+ notification = yield from queue.get_json(5)
except asyncio.futures.CancelledError as e:
break
- ws.send_str(notif)
+ ws.send_str(notification)
return ws
diff --git a/gns3server/handlers/api/controller/version_handler.py b/gns3server/handlers/api/controller/version_handler.py
index dad6d31b..b45f4aa9 100644
--- a/gns3server/handlers/api/controller/version_handler.py
+++ b/gns3server/handlers/api/controller/version_handler.py
@@ -15,16 +15,15 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-from ....web.route import Route
-from ....config import Config
-from ....schemas.version import VERSION_SCHEMA
-from ....version import __version__
+from gns3server.web.route import Route
+from gns3server.config import Config
+from gns3server.schemas.version import VERSION_SCHEMA
+from gns3server.version import __version__
from aiohttp.web import HTTPConflict
class VersionHandler:
- @classmethod
@Route.get(
r"/version",
description="Retrieve the server version number",
@@ -35,7 +34,6 @@ class VersionHandler:
local_server = config.get_section_config("Server").getboolean("local", False)
response.json({"version": __version__, "local": local_server})
- @classmethod
@Route.post(
r"/version",
description="Check if version is the same as the server",
diff --git a/gns3server/handlers/index_handler.py b/gns3server/handlers/index_handler.py
index 2aa42cea..14302e18 100644
--- a/gns3server/handlers/index_handler.py
+++ b/gns3server/handlers/index_handler.py
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2015 GNS3 Technologies Inc.
+# Copyright (C) 2016 GNS3 Technologies Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -15,58 +15,51 @@
# along with this program. If not, see .
-from ..web.route import Route
-from ..controller import Controller
-from ..compute.port_manager import PortManager
-from ..compute.project_manager import ProjectManager
-from ..version import __version__
+from gns3server.web.route import Route
+from gns3server.controller import Controller
+from gns3server.compute.port_manager import PortManager
+from gns3server.compute.project_manager import ProjectManager
+from gns3server.version import __version__
class IndexHandler:
- @classmethod
@Route.get(
r"/",
- description="Home page for GNS3Server"
+ description="Home page of the GNS3 server"
)
def index(request, response):
response.template("index.html")
- @classmethod
@Route.get(
r"/compute",
- description="Ressources used by GNS3 Compute"
+ description="Resources used by the GNS3 compute servers"
)
def compute(request, response):
response.template("compute.html",
port_manager=PortManager.instance(),
- project_manager=ProjectManager.instance()
- )
+ project_manager=ProjectManager.instance())
- @classmethod
@Route.get(
r"/controller",
- description="Ressources used by GNS3 Controller"
+ description="Resources used by the GNS3 controller server"
)
def controller(request, response):
response.template("controller.html",
- controller=Controller.instance()
- )
+ controller=Controller.instance())
- @classmethod
@Route.get(
r"/projects/{project_id}",
- description="Ressources used by GNS3 Controller"
+ description="List of the GNS3 projects"
)
def project(request, response):
controller = Controller.instance()
response.template("project.html",
project=controller.get_project(request.match_info["project_id"]))
- @classmethod
@Route.get(
r"/v1/version",
- description="Old API"
+ description="Old 1.0 API"
)
def get_v1(request, response):
response.json({"version": __version__})
diff --git a/gns3server/handlers/upload_handler.py b/gns3server/handlers/upload_handler.py
index a0526950..be9ee137 100644
--- a/gns3server/handlers/upload_handler.py
+++ b/gns3server/handlers/upload_handler.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2015 GNS3 Technologies Inc.
+# Copyright (C) 2016 GNS3 Technologies Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -22,17 +22,16 @@ import io
import tarfile
import asyncio
-from ..config import Config
-from ..web.route import Route
-from ..utils.images import remove_checksum, md5sum
+from gns3server.config import Config
+from gns3server.web.route import Route
+from gns3server.utils.images import remove_checksum, md5sum
class UploadHandler:
- @classmethod
@Route.get(
r"/upload",
- description="Manage upload of GNS3 images",
+ description="List binary images",
api_version=None
)
def index(request, response):
@@ -50,10 +49,9 @@ class UploadHandler:
uploaded_files.append(iourc_path)
response.template("upload.html", files=uploaded_files)
- @classmethod
@Route.post(
r"/upload",
- description="Manage upload of GNS3 images",
+ description="Upload binary images",
api_version=None
)
def upload(request, response):
@@ -95,16 +93,14 @@ class UploadHandler:
return
response.redirect("/upload")
- @classmethod
@Route.get(
r"/backup/images.tar",
- description="Backup GNS3 images",
+ description="Backup binary images",
api_version=None
)
def backup_images(request, response):
yield from UploadHandler._backup_directory(request, response, UploadHandler.image_directory())
- @classmethod
@Route.get(
r"/backup/projects.tar",
description="Backup GNS3 projects",
diff --git a/gns3server/schemas/node.py b/gns3server/schemas/node.py
index dd2c597c..e0fbf627 100644
--- a/gns3server/schemas/node.py
+++ b/gns3server/schemas/node.py
@@ -18,7 +18,7 @@
NODE_LIST_IMAGES_SCHEMA = {
"$schema": "http://json-schema.org/draft-04/schema#",
- "description": "List of disk images",
+ "description": "List of binary images",
"type": "array",
"items": [
{
diff --git a/tests/compute/virtualbox/test_virtualbox_manager.py b/tests/compute/virtualbox/test_virtualbox_manager.py
index fffe2c78..c3ca7a4f 100644
--- a/tests/compute/virtualbox/test_virtualbox_manager.py
+++ b/tests/compute/virtualbox/test_virtualbox_manager.py
@@ -71,7 +71,7 @@ def test_vboxmanage_path(manager, tmpdir):
assert manager.find_vboxmanage() == path
-def test_list_images(manager, loop):
+def test_list_vms(manager, loop):
vm_list = ['"Windows 8.1" {27b4d095-ff5f-4ac4-bb9d-5f2c7861c1f1}',
'"Carriage',
'Return" {27b4d095-ff5f-4ac4-bb9d-5f2c7861c1f1}',
@@ -92,7 +92,7 @@ def test_list_images(manager, loop):
with asyncio_patch("gns3server.compute.virtualbox.VirtualBox.execute") as mock:
mock.side_effect = execute_mock
- vms = loop.run_until_complete(asyncio.async(manager.list_images()))
+ vms = loop.run_until_complete(asyncio.async(manager.list_vms()))
assert vms == [
{"vmname": "Windows 8.1", "ram": 512},
{"vmname": "Linux Microcore 4.7.1", "ram": 256}
diff --git a/tests/controller/test_controller.py b/tests/controller/test_controller.py
index d3f5c5d3..5afecb38 100644
--- a/tests/controller/test_controller.py
+++ b/tests/controller/test_controller.py
@@ -121,18 +121,18 @@ def test_addProject(controller, async_run):
uuid1 = str(uuid.uuid4())
uuid2 = str(uuid.uuid4())
- async_run(controller.addProject(project_id=uuid1))
+ async_run(controller.add_project(project_id=uuid1))
assert len(controller.projects) == 1
- async_run(controller.addProject(project_id=uuid1))
+ async_run(controller.add_project(project_id=uuid1))
assert len(controller.projects) == 1
- async_run(controller.addProject(project_id=uuid2))
+ async_run(controller.add_project(project_id=uuid2))
assert len(controller.projects) == 2
def test_remove_project(controller, async_run):
uuid1 = str(uuid.uuid4())
- project1 = async_run(controller.addProject(project_id=uuid1))
+ project1 = async_run(controller.add_project(project_id=uuid1))
assert len(controller.projects) == 1
controller.remove_project(project1)
@@ -146,13 +146,13 @@ def test_addProject_with_compute(controller, async_run):
compute.post = MagicMock()
controller._computes = {"test1": compute}
- project1 = async_run(controller.addProject(project_id=uuid1))
+ project1 = async_run(controller.add_project(project_id=uuid1))
def test_getProject(controller, async_run):
uuid1 = str(uuid.uuid4())
- project = async_run(controller.addProject(project_id=uuid1))
+ project = async_run(controller.add_project(project_id=uuid1))
assert controller.get_project(uuid1) == project
with pytest.raises(aiohttp.web.HTTPNotFound):
assert controller.get_project("dsdssd")
diff --git a/tests/handlers/api/compute/test_docker.py b/tests/handlers/api/compute/test_docker.py
index 61173e5f..a981dac9 100644
--- a/tests/handlers/api/compute/test_docker.py
+++ b/tests/handlers/api/compute/test_docker.py
@@ -96,9 +96,16 @@ def test_docker_delete(http_compute, vm):
assert response.status == 204
-def test_docker_reload(http_compute, vm):
+def test_docker_pause(http_compute, vm):
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.pause", return_value=True) as mock:
- response = http_compute.post("/projects/{project_id}/docker/nodes/{node_id}/suspend".format(project_id=vm["project_id"], node_id=vm["node_id"]))
+ response = http_compute.post("/projects/{project_id}/docker/nodes/{node_id}/pause".format(project_id=vm["project_id"], node_id=vm["node_id"]))
+ assert mock.called
+ assert response.status == 204
+
+
+def test_docker_unpause(http_compute, vm):
+ with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.unpause", return_value=True) as mock:
+ response = http_compute.post("/projects/{project_id}/docker/nodes/{node_id}/unpause".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
diff --git a/tests/handlers/api/compute/test_dynamips.py b/tests/handlers/api/compute/test_dynamips.py
index f494d1a1..30654c37 100644
--- a/tests/handlers/api/compute/test_dynamips.py
+++ b/tests/handlers/api/compute/test_dynamips.py
@@ -151,17 +151,17 @@ def fake_file(tmpdir):
return path
-def test_vms(http_compute, tmpdir, fake_dynamips, fake_file):
+def test_images(http_compute, tmpdir, fake_dynamips, fake_file):
with patch("gns3server.compute.Dynamips.get_images_directory", return_value=str(tmpdir), example=True):
- response = http_compute.get("/dynamips/nodes")
+ response = http_compute.get("/dynamips/images")
assert response.status == 200
assert response.json == [{"filename": "7200.bin", "path": "7200.bin"}]
-def test_upload_vm(http_compute, tmpdir):
+def test_upload_image(http_compute, tmpdir):
with patch("gns3server.compute.Dynamips.get_images_directory", return_value=str(tmpdir),):
- response = http_compute.post("/dynamips/nodes/test2", body="TEST", raw=True)
+ response = http_compute.post("/dynamips/images/test2", body="TEST", raw=True)
assert response.status == 204
with open(str(tmpdir / "test2")) as f:
@@ -172,11 +172,11 @@ def test_upload_vm(http_compute, tmpdir):
assert checksum == "033bd94b1168d7e4f0d644c3c95e35bf"
-def test_upload_vm_permission_denied(http_compute, tmpdir):
+def test_upload_image_permission_denied(http_compute, tmpdir):
with open(str(tmpdir / "test2.tmp"), "w+") as f:
f.write("")
os.chmod(str(tmpdir / "test2.tmp"), 0)
with patch("gns3server.compute.Dynamips.get_images_directory", return_value=str(tmpdir),):
- response = http_compute.post("/dynamips/nodes/test2", body="TEST", raw=True)
+ response = http_compute.post("/dynamips/images/test2", body="TEST", raw=True)
assert response.status == 409
diff --git a/tests/handlers/api/compute/test_iou.py b/tests/handlers/api/compute/test_iou.py
index d92e32c8..12b6f361 100644
--- a/tests/handlers/api/compute/test_iou.py
+++ b/tests/handlers/api/compute/test_iou.py
@@ -328,17 +328,17 @@ def test_get_configs_with_startup_config_file(http_compute, project, vm):
assert response.json["startup_config_content"] == "TEST"
-def test_vms(http_compute, tmpdir, fake_iou_bin):
+def test_images(http_compute, tmpdir, fake_iou_bin):
with patch("gns3server.compute.IOU.get_images_directory", return_value=str(tmpdir)):
- response = http_compute.get("/iou/nodes", example=True)
+ response = http_compute.get("/iou/images", example=True)
assert response.status == 200
assert response.json == [{"filename": "iou.bin", "path": "iou.bin"}]
-def test_upload_vm(http_compute, tmpdir):
+def test_image_vm(http_compute, tmpdir):
with patch("gns3server.compute.IOU.get_images_directory", return_value=str(tmpdir),):
- response = http_compute.post("/iou/nodes/test2", body="TEST", raw=True)
+ response = http_compute.post("/iou/images/test2", body="TEST", raw=True)
assert response.status == 204
with open(str(tmpdir / "test2")) as f:
diff --git a/tests/handlers/api/compute/test_qemu.py b/tests/handlers/api/compute/test_qemu.py
index 3046efcc..9459a2b9 100644
--- a/tests/handlers/api/compute/test_qemu.py
+++ b/tests/handlers/api/compute/test_qemu.py
@@ -224,16 +224,16 @@ def test_qemu_list_binaries_filter(http_compute, vm):
assert response.json == ret
-def test_vms(http_compute, tmpdir, fake_qemu_vm):
+def test_images(http_compute, tmpdir, fake_qemu_vm):
- response = http_compute.get("/qemu/nodes")
+ response = http_compute.get("/qemu/images")
assert response.status == 200
assert response.json == [{"filename": "linux载.img", "path": "linux载.img"}]
-def test_upload_vm(http_compute, tmpdir):
+def test_upload_image(http_compute, tmpdir):
with patch("gns3server.compute.Qemu.get_images_directory", return_value=str(tmpdir),):
- response = http_compute.post("/qemu/nodes/test2", body="TEST", raw=True)
+ response = http_compute.post("/qemu/images/test2", body="TEST", raw=True)
assert response.status == 204
with open(str(tmpdir / "test2")) as f:
@@ -244,9 +244,9 @@ def test_upload_vm(http_compute, tmpdir):
assert checksum == "033bd94b1168d7e4f0d644c3c95e35bf"
-def test_upload_vm_ova(http_compute, tmpdir):
+def test_upload_image_ova(http_compute, tmpdir):
with patch("gns3server.compute.Qemu.get_images_directory", return_value=str(tmpdir),):
- response = http_compute.post("/qemu/nodes/test2.ova/test2.vmdk", body="TEST", raw=True)
+ response = http_compute.post("/qemu/images/test2.ova/test2.vmdk", body="TEST", raw=True)
assert response.status == 204
with open(str(tmpdir / "test2.ova" / "test2.vmdk")) as f:
@@ -257,19 +257,19 @@ def test_upload_vm_ova(http_compute, tmpdir):
assert checksum == "033bd94b1168d7e4f0d644c3c95e35bf"
-def test_upload_vm_forbiden_location(http_compute, tmpdir):
+def test_upload_image_forbiden_location(http_compute, tmpdir):
with patch("gns3server.compute.Qemu.get_images_directory", return_value=str(tmpdir),):
- response = http_compute.post("/qemu/nodes/../../test2", body="TEST", raw=True)
+ response = http_compute.post("/qemu/images/../../test2", body="TEST", raw=True)
assert response.status == 403
-def test_upload_vm_permission_denied(http_compute, tmpdir):
+def test_upload_image_permission_denied(http_compute, tmpdir):
with open(str(tmpdir / "test2.tmp"), "w+") as f:
f.write("")
os.chmod(str(tmpdir / "test2.tmp"), 0)
with patch("gns3server.compute.Qemu.get_images_directory", return_value=str(tmpdir),):
- response = http_compute.post("/qemu/nodes/test2", body="TEST", raw=True)
+ response = http_compute.post("/qemu/images/test2", body="TEST", raw=True)
assert response.status == 409
diff --git a/tests/handlers/api/controller/test_link.py b/tests/handlers/api/controller/test_link.py
index f77c3e1e..8e362d10 100644
--- a/tests/handlers/api/controller/test_link.py
+++ b/tests/handlers/api/controller/test_link.py
@@ -45,7 +45,7 @@ def compute(http_controller, async_run):
@pytest.fixture
def project(http_controller, async_run):
- return async_run(Controller.instance().addProject())
+ return async_run(Controller.instance().add_project())
def test_create_link(http_controller, tmpdir, project, compute, async_run):
diff --git a/tests/handlers/api/controller/test_node.py b/tests/handlers/api/controller/test_node.py
index 4d7229dd..12f941af 100644
--- a/tests/handlers/api/controller/test_node.py
+++ b/tests/handlers/api/controller/test_node.py
@@ -44,7 +44,7 @@ def compute(http_controller, async_run):
@pytest.fixture
def project(http_controller, async_run):
- return async_run(Controller.instance().addProject())
+ return async_run(Controller.instance().add_project())
@pytest.fixture
@@ -103,7 +103,7 @@ def test_update_node(http_controller, tmpdir, project, compute, node):
"startup_script": "echo test"
}
}, example=True)
- assert response.status == 201
+ assert response.status == 200
assert response.json["name"] == "test"
assert "name" not in response.json["properties"]
@@ -113,17 +113,14 @@ def test_start_node(http_controller, tmpdir, project, compute, node):
compute.post = AsyncioMagicMock()
response = http_controller.post("/projects/{}/nodes/{}/start".format(project.id, node.id), example=True)
- assert response.status == 201
- assert response.json["name"] == node.name
-
+ assert response.status == 204
def test_stop_node(http_controller, tmpdir, project, compute, node):
response = MagicMock()
compute.post = AsyncioMagicMock()
response = http_controller.post("/projects/{}/nodes/{}/stop".format(project.id, node.id), example=True)
- assert response.status == 201
- assert response.json["name"] == node.name
+ assert response.status == 204
def test_suspend_node(http_controller, tmpdir, project, compute, node):
@@ -131,8 +128,7 @@ def test_suspend_node(http_controller, tmpdir, project, compute, node):
compute.post = AsyncioMagicMock()
response = http_controller.post("/projects/{}/nodes/{}/suspend".format(project.id, node.id), example=True)
- assert response.status == 201
- assert response.json["name"] == node.name
+ assert response.status == 204
def test_reload_node(http_controller, tmpdir, project, compute, node):
@@ -140,8 +136,7 @@ def test_reload_node(http_controller, tmpdir, project, compute, node):
compute.post = AsyncioMagicMock()
response = http_controller.post("/projects/{}/nodes/{}/reload".format(project.id, node.id), example=True)
- assert response.status == 201
- assert response.json["name"] == node.name
+ assert response.status == 204
def test_delete_node(http_controller, tmpdir, project, compute, node):
@@ -149,4 +144,4 @@ def test_delete_node(http_controller, tmpdir, project, compute, node):
compute.post = AsyncioMagicMock()
response = http_controller.delete("/projects/{}/nodes/{}".format(project.id, node.id), example=True)
- assert response.status == 201
+ assert response.status == 204
diff --git a/tests/handlers/test_index.py b/tests/handlers/test_index.py
index eaa7f22a..385940f0 100644
--- a/tests/handlers/test_index.py
+++ b/tests/handlers/test_index.py
@@ -33,7 +33,7 @@ def test_index(http_root):
def test_controller(http_root, async_run):
- project = async_run(Controller.instance().addProject(name="test"))
+ project = async_run(Controller.instance().add_project(name="test"))
response = http_root.get('/controller')
assert "test" in response.html
assert response.status == 200
@@ -45,7 +45,7 @@ def test_compute(http_root):
def test_project(http_root, async_run):
- project = async_run(Controller.instance().addProject(name="test"))
+ project = async_run(Controller.instance().add_project(name="test"))
response = http_root.get('/projects/{}'.format(project.id))
assert response.status == 200