mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-03 05:51:15 +02:00
Handlers: cleanup and fixes.
This commit is contained in:
1 parent
885d93be02
commit
f81d35cc29
33 files changed
+723
-766
No files matched your search
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -15,9 +15,13 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
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)
|
||||
@@ -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
|
||||
@@ -15,16 +15,15 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
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",
|
||||
|
||||
Reference in new issue
Block a user