mirror of
https://github.com/GNS3/gns3-server.git
synced 2025-01-18 10:46:24 +00:00
Merge remote-tracking branch 'origin/3.0' into gh-pages
This commit is contained in:
commit
0697b467a2
11
.github/workflows/publish_api_documentation.yml
vendored
11
.github/workflows/publish_api_documentation.yml
vendored
@ -15,10 +15,15 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: "3.0"
|
||||
ref: "gh-pages"
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.6
|
||||
- name: Merge changes from 3.0 branch
|
||||
run: |
|
||||
git config user.name github-actions
|
||||
git config user.email github-actions@github.com
|
||||
git merge origin/3.0 -X theirs
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
@ -32,11 +37,7 @@ jobs:
|
||||
python3 publish_api_documentation.py
|
||||
- name: Publish the API documentation
|
||||
run: |
|
||||
git config user.name github-actions
|
||||
git config user.email github-actions@github.com
|
||||
git add docs
|
||||
git status
|
||||
git commit -m "Publish API documentation"
|
||||
git checkout gh-pages
|
||||
git merge 3.0 -X theirs
|
||||
git push
|
||||
|
@ -49,7 +49,7 @@ log = logging.getLogger(__name__)
|
||||
|
||||
app = FastAPI(title="GNS3 controller API",
|
||||
description="This page describes the public controller API for GNS3",
|
||||
version="v2")
|
||||
version="v3")
|
||||
|
||||
origins = [
|
||||
"http://127.0.0.1",
|
||||
@ -71,8 +71,8 @@ app.add_middleware(
|
||||
)
|
||||
|
||||
app.include_router(index.router, tags=["Index"])
|
||||
app.include_router(controller.router, prefix="/v2")
|
||||
app.mount("/v2/compute", compute_api)
|
||||
app.include_router(controller.router, prefix="/v3")
|
||||
app.mount("/v3/compute", compute_api)
|
||||
|
||||
|
||||
@app.exception_handler(ControllerError)
|
||||
|
@ -44,11 +44,11 @@ from ..error import NodeError, ImageMissingError
|
||||
from ..nios.nio_udp import NIOUDP
|
||||
from ..nios.nio_tap import NIOTAP
|
||||
from ..base_node import BaseNode
|
||||
from ...schemas.qemu import QEMU_OBJECT_SCHEMA, QEMU_PLATFORMS
|
||||
from ...utils.asyncio import monitor_process
|
||||
from ...utils.images import md5sum
|
||||
from ...utils import macaddress_to_int, int_to_macaddress
|
||||
|
||||
from gns3server.schemas.qemu_nodes import Qemu, QemuPlatform
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
@ -216,7 +216,10 @@ class QemuVM(BaseNode):
|
||||
self._platform = "i386"
|
||||
else:
|
||||
self._platform = re.sub(r'^qemu-system-(.*)$', r'\1', qemu_bin, re.IGNORECASE)
|
||||
if self._platform.split(".")[0] not in QEMU_PLATFORMS:
|
||||
|
||||
try:
|
||||
QemuPlatform(self._platform.split(".")[0])
|
||||
except ValueError:
|
||||
raise QemuError("Platform {} is unknown".format(self._platform))
|
||||
log.info('QEMU VM "{name}" [{id}] has set the QEMU path to {qemu_path}'.format(name=self._name,
|
||||
id=self._id,
|
||||
@ -2288,7 +2291,7 @@ class QemuVM(BaseNode):
|
||||
"node_directory": self.working_path
|
||||
}
|
||||
# Qemu has a long list of options. The JSON schema is the single source of information
|
||||
for field in QEMU_OBJECT_SCHEMA["required"]:
|
||||
for field in Qemu.schema()["properties"]:
|
||||
if field not in answer:
|
||||
try:
|
||||
answer[field] = getattr(self, field)
|
||||
|
@ -497,7 +497,7 @@ class Compute:
|
||||
host = "[{}]".format(host)
|
||||
elif host == "0.0.0.0":
|
||||
host = "127.0.0.1"
|
||||
return "{}://{}:{}/v2/compute{}".format(self._protocol, host, self._port, path)
|
||||
return "{}://{}:{}/v3/compute{}".format(self._protocol, host, self._port, path)
|
||||
|
||||
def get_url(self, path):
|
||||
""" Returns URL for specific path at Compute"""
|
||||
|
@ -310,7 +310,7 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
||||
remaining_try = 300
|
||||
while remaining_try > 0:
|
||||
try:
|
||||
async with HTTPClient.get(f"http://127.0.0.1:{api_port}/v2/compute/network/interfaces") as resp:
|
||||
async with HTTPClient.get(f"http://127.0.0.1:{api_port}/v3/compute/network/interfaces") as resp:
|
||||
if resp.status < 300:
|
||||
try:
|
||||
json_data = await resp.json()
|
||||
|
@ -345,11 +345,12 @@ class Link:
|
||||
node_id = self.capture_node["node"].id
|
||||
adapter_number = self.capture_node["adapter_number"]
|
||||
port_number = self.capture_node["port_number"]
|
||||
url = "/projects/{project_id}/{node_type}/nodes/{node_id}/adapters/{adapter_number}/ports/{port_number}/pcap".format(project_id=self.project.id,
|
||||
node_type=node_type,
|
||||
node_id=node_id,
|
||||
adapter_number=adapter_number,
|
||||
port_number=port_number)
|
||||
url = "/projects/{project_id}/{node_type}/nodes/{node_id}/adapters/{adapter_number}/" \
|
||||
"ports/{port_number}/capture/stream".format(project_id=self.project.id,
|
||||
node_type=node_type,
|
||||
node_id=node_id,
|
||||
adapter_number=adapter_number,
|
||||
port_number=port_number)
|
||||
|
||||
return compute._getUrl(url)
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (C) 2016 GNS3 Technologies Inc.
|
||||
# Copyright (C) 2020 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
|
||||
@ -17,57 +17,14 @@
|
||||
|
||||
import copy
|
||||
import uuid
|
||||
import json
|
||||
import jsonschema
|
||||
|
||||
from gns3server.schemas.cloud_template import CLOUD_TEMPLATE_OBJECT_SCHEMA
|
||||
from gns3server.schemas.ethernet_switch_template import ETHERNET_SWITCH_TEMPLATE_OBJECT_SCHEMA
|
||||
from gns3server.schemas.ethernet_hub_template import ETHERNET_HUB_TEMPLATE_OBJECT_SCHEMA
|
||||
from gns3server.schemas.docker_template import DOCKER_TEMPLATE_OBJECT_SCHEMA
|
||||
from gns3server.schemas.vpcs_template import VPCS_TEMPLATE_OBJECT_SCHEMA
|
||||
from gns3server.schemas.traceng_template import TRACENG_TEMPLATE_OBJECT_SCHEMA
|
||||
from gns3server.schemas.virtualbox_template import VIRTUALBOX_TEMPLATE_OBJECT_SCHEMA
|
||||
from gns3server.schemas.vmware_template import VMWARE_TEMPLATE_OBJECT_SCHEMA
|
||||
from gns3server.schemas.iou_template import IOU_TEMPLATE_OBJECT_SCHEMA
|
||||
from gns3server.schemas.qemu_template import QEMU_TEMPLATE_OBJECT_SCHEMA
|
||||
|
||||
from gns3server.schemas.dynamips_template import (
|
||||
DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
||||
C7200_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
||||
C3745_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
||||
C3725_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
||||
C3600_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
||||
C2691_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
||||
C2600_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
||||
C1700_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA
|
||||
)
|
||||
from pydantic import ValidationError
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from gns3server import schemas
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Add default values for missing entries in a request, largely taken from jsonschema documentation example
|
||||
# https://python-jsonschema.readthedocs.io/en/latest/faq/#why-doesn-t-my-schema-s-default-property-set-the-default-on-my-instance
|
||||
def extend_with_default(validator_class):
|
||||
|
||||
validate_properties = validator_class.VALIDATORS["properties"]
|
||||
def set_defaults(validator, properties, instance, schema):
|
||||
if jsonschema.Draft4Validator(schema).is_valid(instance):
|
||||
# only add default for the matching sub-schema (e.g. when using 'oneOf')
|
||||
for property, subschema in properties.items():
|
||||
if "default" in subschema:
|
||||
instance.setdefault(property, subschema["default"])
|
||||
|
||||
for error in validate_properties(validator, properties, instance, schema,):
|
||||
yield error
|
||||
|
||||
return jsonschema.validators.extend(
|
||||
validator_class, {"properties" : set_defaults},
|
||||
)
|
||||
|
||||
|
||||
ValidatorWithDefaults = extend_with_default(jsonschema.Draft4Validator)
|
||||
|
||||
ID_TO_CATEGORY = {
|
||||
3: "firewall",
|
||||
2: "guest",
|
||||
@ -76,27 +33,26 @@ ID_TO_CATEGORY = {
|
||||
}
|
||||
|
||||
TEMPLATE_TYPE_TO_SHEMA = {
|
||||
"cloud": CLOUD_TEMPLATE_OBJECT_SCHEMA,
|
||||
"ethernet_hub": ETHERNET_HUB_TEMPLATE_OBJECT_SCHEMA,
|
||||
"ethernet_switch": ETHERNET_SWITCH_TEMPLATE_OBJECT_SCHEMA,
|
||||
"docker": DOCKER_TEMPLATE_OBJECT_SCHEMA,
|
||||
"dynamips": DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
||||
"vpcs": VPCS_TEMPLATE_OBJECT_SCHEMA,
|
||||
"traceng": TRACENG_TEMPLATE_OBJECT_SCHEMA,
|
||||
"virtualbox": VIRTUALBOX_TEMPLATE_OBJECT_SCHEMA,
|
||||
"vmware": VMWARE_TEMPLATE_OBJECT_SCHEMA,
|
||||
"iou": IOU_TEMPLATE_OBJECT_SCHEMA,
|
||||
"qemu": QEMU_TEMPLATE_OBJECT_SCHEMA
|
||||
"cloud": schemas.CloudTemplate,
|
||||
"ethernet_hub": schemas.EthernetHubTemplate,
|
||||
"ethernet_switch": schemas.EthernetSwitchTemplate,
|
||||
"docker": schemas.DockerTemplate,
|
||||
"dynamips": schemas.DynamipsTemplate,
|
||||
"vpcs": schemas.VPCSTemplate,
|
||||
"virtualbox": schemas.VirtualBoxTemplate,
|
||||
"vmware": schemas.VMwareTemplate,
|
||||
"iou": schemas.IOUTemplate,
|
||||
"qemu": schemas.QemuTemplate
|
||||
}
|
||||
|
||||
DYNAMIPS_PLATFORM_TO_SHEMA = {
|
||||
"c7200": C7200_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
||||
"c3745": C3745_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
||||
"c3725": C3725_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
||||
"c3600": C3600_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
||||
"c2691": C2691_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
||||
"c2600": C2600_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
||||
"c1700": C1700_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA
|
||||
"c7200": schemas.C7200DynamipsTemplate,
|
||||
"c3745": schemas.C3745DynamipsTemplate,
|
||||
"c3725": schemas.C3725DynamipsTemplate,
|
||||
"c3600": schemas.C3600DynamipsTemplate,
|
||||
"c2691": schemas.C2691DynamipsTemplate,
|
||||
"c2600": schemas.C2600DynamipsTemplate,
|
||||
"c1700": schemas.C1700DynamipsTemplate
|
||||
}
|
||||
|
||||
|
||||
@ -141,11 +97,18 @@ class Template:
|
||||
self._builtin = builtin
|
||||
|
||||
if builtin is False:
|
||||
self.validate_and_apply_defaults(TEMPLATE_TYPE_TO_SHEMA[self.template_type])
|
||||
|
||||
if self.template_type == "dynamips":
|
||||
# special case for Dynamips to cover all platform types that contain specific settings
|
||||
self.validate_and_apply_defaults(DYNAMIPS_PLATFORM_TO_SHEMA[self._settings["platform"]])
|
||||
try:
|
||||
template_schema = TEMPLATE_TYPE_TO_SHEMA[self.template_type]
|
||||
template_settings_with_defaults = template_schema .parse_obj(self.__json__())
|
||||
self._settings = jsonable_encoder(template_settings_with_defaults.dict())
|
||||
if self.template_type == "dynamips":
|
||||
# special case for Dynamips to cover all platform types that contain specific settings
|
||||
dynamips_template_schema = DYNAMIPS_PLATFORM_TO_SHEMA[self._settings["platform"]]
|
||||
dynamips_template_settings_with_defaults = dynamips_template_schema.parse_obj(self.__json__())
|
||||
self._settings = jsonable_encoder(dynamips_template_settings_with_defaults.dict())
|
||||
except ValidationError as e:
|
||||
print(e) #TODO: handle errors
|
||||
raise
|
||||
|
||||
log.debug('Template "{name}" [{id}] loaded'.format(name=self.name, id=self._id))
|
||||
|
||||
@ -179,7 +142,6 @@ class Template:
|
||||
|
||||
def update(self, **kwargs):
|
||||
|
||||
|
||||
from gns3server.controller import Controller
|
||||
controller = Controller.instance()
|
||||
Controller.instance().check_can_write_config()
|
||||
@ -187,17 +149,6 @@ class Template:
|
||||
controller.notification.controller_emit("template.updated", self.__json__())
|
||||
controller.save()
|
||||
|
||||
def validate_and_apply_defaults(self, schema):
|
||||
|
||||
validator = ValidatorWithDefaults(schema)
|
||||
try:
|
||||
validator.validate(self.__json__())
|
||||
except jsonschema.ValidationError as e:
|
||||
message = "JSON schema error {}".format(e.message)
|
||||
log.error(message)
|
||||
log.debug("Input schema: {}".format(json.dumps(schema)))
|
||||
raise
|
||||
|
||||
def __json__(self):
|
||||
"""
|
||||
Template settings.
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import copy
|
||||
import uuid
|
||||
import jsonschema
|
||||
import pydantic
|
||||
|
||||
from .controller_error import ControllerError, ControllerNotFoundError
|
||||
from .template import Template
|
||||
@ -53,8 +53,8 @@ class TemplateManager:
|
||||
try:
|
||||
template = Template(template_settings.get("template_id"), template_settings)
|
||||
self._templates[template.id] = template
|
||||
except jsonschema.ValidationError as e:
|
||||
message = "Cannot load template with JSON data '{}': {}".format(template_settings, e.message)
|
||||
except pydantic.ValidationError as e:
|
||||
message = "Cannot load template with JSON data '{}': {}".format(template_settings, e)
|
||||
log.warning(message)
|
||||
continue
|
||||
|
||||
@ -90,8 +90,8 @@ class TemplateManager:
|
||||
template_id = settings.setdefault("template_id", str(uuid.uuid4()))
|
||||
try:
|
||||
template = Template(template_id, settings)
|
||||
except jsonschema.ValidationError as e:
|
||||
message = "JSON schema error adding template with JSON data '{}': {}".format(settings, e.message)
|
||||
except pydantic.ValidationError as e:
|
||||
message = "JSON schema error adding template with JSON data '{}': {}".format(settings, e)
|
||||
raise ControllerError(message)
|
||||
|
||||
from . import Controller
|
||||
|
@ -18,21 +18,22 @@
|
||||
import os
|
||||
import html
|
||||
import json
|
||||
import copy
|
||||
import uuid
|
||||
import glob
|
||||
import shutil
|
||||
import zipfile
|
||||
import jsonschema
|
||||
import pydantic
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from ..version import __version__
|
||||
from ..schemas.topology import TOPOLOGY_SCHEMA
|
||||
from ..schemas import dynamips_vm
|
||||
from ..utils.qt import qt_font_to_style
|
||||
from ..compute.dynamips import PLATFORMS_DEFAULT_RAM
|
||||
from .controller_error import ControllerError
|
||||
|
||||
from gns3server.schemas.topology import Topology
|
||||
from gns3server.schemas.dynamips_nodes import DynamipsCreate
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -40,29 +41,21 @@ log = logging.getLogger(__name__)
|
||||
GNS3_FILE_FORMAT_REVISION = 9
|
||||
|
||||
|
||||
class DynamipsNodeValidation(DynamipsCreate):
|
||||
name: Optional[str] = None
|
||||
|
||||
|
||||
def _check_topology_schema(topo):
|
||||
try:
|
||||
jsonschema.validate(topo, TOPOLOGY_SCHEMA)
|
||||
Topology.parse_obj(topo)
|
||||
|
||||
# Check the nodes property against compute schemas
|
||||
for node in topo["topology"].get("nodes", []):
|
||||
schema = None
|
||||
if node["node_type"] == "dynamips":
|
||||
schema = copy.deepcopy(dynamips_vm.VM_CREATE_SCHEMA)
|
||||
DynamipsNodeValidation.parse_obj(node.get("properties", {}))
|
||||
|
||||
if schema:
|
||||
# Properties send to compute but in an other place in topology
|
||||
delete_properties = ["name", "node_id"]
|
||||
for prop in delete_properties:
|
||||
del schema["properties"][prop]
|
||||
schema["required"] = [p for p in schema["required"] if p not in delete_properties]
|
||||
|
||||
jsonschema.validate(node.get("properties", {}), schema)
|
||||
|
||||
except jsonschema.ValidationError as e:
|
||||
error = "Invalid data in topology file: {} in schema: {}".format(
|
||||
e.message,
|
||||
json.dumps(e.schema))
|
||||
except pydantic.ValidationError as e:
|
||||
error = "Invalid data in topology file: {}".format(e)
|
||||
log.critical(error)
|
||||
raise ControllerError(error)
|
||||
|
||||
|
@ -51,7 +51,7 @@ from . import vpcs_nodes
|
||||
|
||||
compute_api = FastAPI(title="GNS3 compute API",
|
||||
description="This page describes the private compute API for GNS3. PLEASE DO NOT USE DIRECTLY!",
|
||||
version="v2")
|
||||
version="v3")
|
||||
|
||||
|
||||
@compute_api.exception_handler(ComputeError)
|
||||
|
@ -26,7 +26,7 @@ from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.responses import StreamingResponse
|
||||
from uuid import UUID
|
||||
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
from gns3server.compute.dynamips import Dynamips
|
||||
from gns3server.compute.dynamips.nodes.atm_switch import ATMSwitch
|
||||
|
||||
@ -186,7 +186,7 @@ async def delete_nio(adapter_number: int, port_number: int, node: ATMSwitch = De
|
||||
await nio.delete()
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/start_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start",
|
||||
responses=responses)
|
||||
async def start_capture(adapter_number: int,
|
||||
port_number: int,
|
||||
@ -202,7 +202,7 @@ async def start_capture(adapter_number: int,
|
||||
return {"pcap_file_path": pcap_file_path}
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/stop_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop_capture",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses=responses)
|
||||
async def stop_capture(adapter_number: int, port_number: int, node: ATMSwitch = Depends(dep_node)):
|
||||
@ -214,7 +214,7 @@ async def stop_capture(adapter_number: int, port_number: int, node: ATMSwitch =
|
||||
await node.stop_capture(port_number)
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/pcap",
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream",
|
||||
responses=responses)
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: ATMSwitch = Depends(dep_node)):
|
||||
"""
|
||||
|
@ -27,7 +27,7 @@ from fastapi import APIRouter
|
||||
from gns3server.version import __version__
|
||||
from gns3server.compute import MODULES
|
||||
from gns3server.utils.path import get_default_project_directory
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
@ -27,7 +27,7 @@ from fastapi.responses import StreamingResponse
|
||||
from typing import Union
|
||||
from uuid import UUID
|
||||
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
from gns3server.compute.builtin import Builtin
|
||||
from gns3server.compute.builtin.nodes.cloud import Cloud
|
||||
|
||||
@ -197,7 +197,7 @@ async def delete_nio(adapter_number: int, port_number: int, node: Cloud = Depend
|
||||
await node.remove_nio(port_number)
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/start_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start",
|
||||
responses=responses)
|
||||
async def start_capture(adapter_number: int,
|
||||
port_number: int,
|
||||
@ -213,7 +213,7 @@ async def start_capture(adapter_number: int,
|
||||
return {"pcap_file_path": pcap_file_path}
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/stop_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses=responses)
|
||||
async def stop_capture(adapter_number: int, port_number: int, node: Cloud = Depends(dep_node)):
|
||||
|
@ -33,7 +33,7 @@ from gns3server.utils.interfaces import interfaces
|
||||
from gns3server.compute.qemu import Qemu
|
||||
from gns3server.compute.virtualbox import VirtualBox
|
||||
from gns3server.compute.vmware import VMware
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
|
||||
from fastapi import APIRouter, HTTPException, Body, status
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
|
@ -26,7 +26,7 @@ from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.responses import StreamingResponse
|
||||
from uuid import UUID
|
||||
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
from gns3server.compute.docker import Docker
|
||||
from gns3server.compute.docker.docker_vm import DockerVM
|
||||
|
||||
@ -262,7 +262,7 @@ async def delete_nio(adapter_number: int, port_number: int, node: DockerVM = Dep
|
||||
await node.adapter_remove_nio_binding(adapter_number)
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/start_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start",
|
||||
responses=responses)
|
||||
async def start_capture(adapter_number: int,
|
||||
port_number: int,
|
||||
@ -278,7 +278,7 @@ async def start_capture(adapter_number: int,
|
||||
return {"pcap_file_path": str(pcap_file_path)}
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/stop_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses=responses)
|
||||
async def stop_capture(adapter_number: int, port_number: int, node: DockerVM = Depends(dep_node)):
|
||||
@ -290,7 +290,7 @@ async def stop_capture(adapter_number: int, port_number: int, node: DockerVM = D
|
||||
await node.stop_capture(adapter_number)
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/pcap",
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream",
|
||||
responses=responses)
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: DockerVM = Depends(dep_node)):
|
||||
"""
|
||||
|
@ -31,7 +31,7 @@ from uuid import UUID
|
||||
from gns3server.compute.dynamips import Dynamips
|
||||
from gns3server.compute.dynamips.nodes.router import Router
|
||||
from gns3server.compute.dynamips.dynamips_error import DynamipsError
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@ -219,7 +219,7 @@ async def delete_nio(adapter_number: int, port_number: int, node: Router = Depen
|
||||
await nio.delete()
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/start_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start",
|
||||
responses=responses)
|
||||
async def start_capture(adapter_number: int,
|
||||
port_number: int,
|
||||
@ -242,7 +242,7 @@ async def start_capture(adapter_number: int,
|
||||
return {"pcap_file_path": pcap_file_path}
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/stop_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses=responses)
|
||||
async def stop_capture(adapter_number: int, port_number: int, node: Router = Depends(dep_node)):
|
||||
@ -253,7 +253,7 @@ async def stop_capture(adapter_number: int, port_number: int, node: Router = Dep
|
||||
await node.stop_capture(adapter_number, port_number)
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/pcap",
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream",
|
||||
responses=responses)
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: Router = Depends(dep_node)):
|
||||
"""
|
||||
|
@ -28,7 +28,7 @@ from uuid import UUID
|
||||
|
||||
from gns3server.compute.dynamips import Dynamips
|
||||
from gns3server.compute.dynamips.nodes.ethernet_hub import EthernetHub
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@ -187,7 +187,7 @@ async def delete_nio(adapter_number: int, port_number: int, node: EthernetHub =
|
||||
await nio.delete()
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/start_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start",
|
||||
responses=responses)
|
||||
async def start_capture(adapter_number: int,
|
||||
port_number: int,
|
||||
@ -203,7 +203,7 @@ async def start_capture(adapter_number: int,
|
||||
return {"pcap_file_path": pcap_file_path}
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/stop_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses=responses)
|
||||
async def stop_capture(adapter_number: int, port_number: int, node: EthernetHub = Depends(dep_node)):
|
||||
@ -215,7 +215,7 @@ async def stop_capture(adapter_number: int, port_number: int, node: EthernetHub
|
||||
await node.stop_capture(port_number)
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/pcap",
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream",
|
||||
responses=responses)
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: EthernetHub = Depends(dep_node)):
|
||||
"""
|
||||
|
@ -28,7 +28,7 @@ from uuid import UUID
|
||||
|
||||
from gns3server.compute.dynamips import Dynamips
|
||||
from gns3server.compute.dynamips.nodes.ethernet_switch import EthernetSwitch
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@ -186,7 +186,7 @@ async def delete_nio(adapter_number: int, port_number: int, node: EthernetSwitch
|
||||
await nio.delete()
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/start_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start",
|
||||
responses=responses)
|
||||
async def start_capture(adapter_number: int,
|
||||
port_number: int,
|
||||
@ -202,7 +202,7 @@ async def start_capture(adapter_number: int,
|
||||
return {"pcap_file_path": pcap_file_path}
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/stop_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses=responses)
|
||||
async def stop_capture(adapter_number: int,port_number: int, node: EthernetSwitch = Depends(dep_node)):
|
||||
@ -214,7 +214,7 @@ async def stop_capture(adapter_number: int,port_number: int, node: EthernetSwitc
|
||||
await node.stop_capture(port_number)
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/pcap",
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream",
|
||||
responses=responses)
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: EthernetSwitch = Depends(dep_node)):
|
||||
"""
|
||||
|
@ -26,7 +26,7 @@ from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.responses import StreamingResponse
|
||||
from uuid import UUID
|
||||
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
from gns3server.compute.dynamips import Dynamips
|
||||
from gns3server.compute.dynamips.nodes.frame_relay_switch import FrameRelaySwitch
|
||||
|
||||
@ -188,7 +188,7 @@ async def delete_nio(adapter_number: int, port_number: int, node: FrameRelaySwit
|
||||
await nio.delete()
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/start_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start",
|
||||
responses=responses)
|
||||
async def start_capture(adapter_number: int,
|
||||
port_number: int,
|
||||
@ -204,7 +204,7 @@ async def start_capture(adapter_number: int,
|
||||
return {"pcap_file_path": pcap_file_path}
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/stop_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses=responses)
|
||||
async def stop_capture(adapter_number: int, port_number: int, node: FrameRelaySwitch = Depends(dep_node)):
|
||||
@ -216,7 +216,7 @@ async def stop_capture(adapter_number: int, port_number: int, node: FrameRelaySw
|
||||
await node.stop_capture(port_number)
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/pcap",
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream",
|
||||
responses=responses)
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: FrameRelaySwitch = Depends(dep_node)):
|
||||
"""
|
||||
|
@ -27,7 +27,7 @@ from fastapi.responses import StreamingResponse
|
||||
from typing import Union
|
||||
from uuid import UUID
|
||||
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
from gns3server.compute.iou import IOU
|
||||
from gns3server.compute.iou.iou_vm import IOUVM
|
||||
|
||||
@ -237,7 +237,7 @@ async def delete_nio(adapter_number: int, port_number: int, node: IOUVM = Depend
|
||||
await node.adapter_remove_nio_binding(adapter_number, port_number)
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/start_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start",
|
||||
responses=responses)
|
||||
async def start_capture(adapter_number: int,
|
||||
port_number: int,
|
||||
@ -252,7 +252,7 @@ async def start_capture(adapter_number: int,
|
||||
return {"pcap_file_path": str(pcap_file_path)}
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/stop_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses=responses)
|
||||
async def stop_capture(adapter_number: int, port_number: int, node: IOUVM = Depends(dep_node)):
|
||||
@ -263,7 +263,7 @@ async def stop_capture(adapter_number: int, port_number: int, node: IOUVM = Depe
|
||||
await node.stop_capture(adapter_number, port_number)
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/pcap",
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream",
|
||||
responses=responses)
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: IOUVM = Depends(dep_node)):
|
||||
"""
|
||||
|
@ -27,7 +27,7 @@ from fastapi.responses import StreamingResponse
|
||||
from typing import Union
|
||||
from uuid import UUID
|
||||
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
from gns3server.compute.builtin import Builtin
|
||||
from gns3server.compute.builtin.nodes.nat import Nat
|
||||
|
||||
@ -192,7 +192,7 @@ async def delete_nio(adapter_number: int, port_number: int, node: Nat = Depends(
|
||||
await node.remove_nio(port_number)
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/start_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start",
|
||||
responses=responses)
|
||||
async def start_capture(adapter_number: int,
|
||||
port_number: int,
|
||||
@ -208,7 +208,7 @@ async def start_capture(adapter_number: int,
|
||||
return {"pcap_file_path": pcap_file_path}
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/stop_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses=responses)
|
||||
async def stop_capture(adapter_number: int, port_number: int, node: Nat = Depends(dep_node)):
|
||||
@ -220,7 +220,7 @@ async def stop_capture(adapter_number: int, port_number: int, node: Nat = Depend
|
||||
await node.stop_capture(port_number)
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/pcap",
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream",
|
||||
responses=responses)
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: Nat = Depends(dep_node)):
|
||||
"""
|
||||
|
@ -32,7 +32,7 @@ from uuid import UUID
|
||||
|
||||
from gns3server.compute.project_manager import ProjectManager
|
||||
from gns3server.compute.project import Project
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
|
||||
|
||||
router = APIRouter()
|
||||
|
@ -27,7 +27,7 @@ from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.responses import StreamingResponse
|
||||
from uuid import UUID
|
||||
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
from gns3server.compute.project_manager import ProjectManager
|
||||
from gns3server.compute.qemu import Qemu
|
||||
from gns3server.compute.qemu.qemu_vm import QemuVM
|
||||
@ -252,7 +252,7 @@ async def delete_nio(adapter_number: int, port_number: int, node: QemuVM = Depen
|
||||
await node.adapter_remove_nio_binding(adapter_number)
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/start_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start",
|
||||
responses=responses)
|
||||
async def start_capture(adapter_number: int,
|
||||
port_number: int,
|
||||
@ -268,7 +268,7 @@ async def start_capture(adapter_number: int,
|
||||
return {"pcap_file_path": str(pcap_file_path)}
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/stop_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses=responses)
|
||||
async def stop_capture(adapter_number: int, port_number: int, node: QemuVM = Depends(dep_node)):
|
||||
@ -280,7 +280,7 @@ async def stop_capture(adapter_number: int, port_number: int, node: QemuVM = Dep
|
||||
await node.stop_capture(adapter_number)
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/pcap",
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream",
|
||||
responses=responses)
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: QemuVM = Depends(dep_node)):
|
||||
"""
|
||||
|
@ -26,7 +26,7 @@ from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.responses import StreamingResponse
|
||||
from uuid import UUID
|
||||
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
from gns3server.compute.virtualbox import VirtualBox
|
||||
from gns3server.compute.virtualbox.virtualbox_error import VirtualBoxError
|
||||
from gns3server.compute.project_manager import ProjectManager
|
||||
@ -260,7 +260,7 @@ async def delete_nio(adapter_number: int, port_number: int, node: VirtualBoxVM =
|
||||
await node.adapter_remove_nio_binding(adapter_number)
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/start_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start",
|
||||
responses=responses)
|
||||
async def start_capture(adapter_number: int,
|
||||
port_number: int,
|
||||
@ -276,7 +276,7 @@ async def start_capture(adapter_number: int,
|
||||
return {"pcap_file_path": str(pcap_file_path)}
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/stop_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses=responses)
|
||||
async def stop_capture(adapter_number: int, port_number: int, node: VirtualBoxVM = Depends(dep_node)):
|
||||
@ -288,7 +288,7 @@ async def stop_capture(adapter_number: int, port_number: int, node: VirtualBoxVM
|
||||
await node.stop_capture(adapter_number)
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/pcap",
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream",
|
||||
responses=responses)
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: VirtualBoxVM = Depends(dep_node)):
|
||||
"""
|
||||
|
@ -26,7 +26,7 @@ from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.responses import StreamingResponse
|
||||
from uuid import UUID
|
||||
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
from gns3server.compute.vmware import VMware
|
||||
from gns3server.compute.project_manager import ProjectManager
|
||||
from gns3server.compute.vmware.vmware_vm import VMwareVM
|
||||
@ -225,7 +225,7 @@ async def delete_nio(adapter_number: int, port_number: int, node: VMwareVM = Dep
|
||||
await node.adapter_remove_nio_binding(adapter_number)
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/start_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start",
|
||||
responses=responses)
|
||||
async def start_capture(adapter_number: int,
|
||||
port_number: int,
|
||||
@ -241,7 +241,7 @@ async def start_capture(adapter_number: int,
|
||||
return {"pcap_file_path": pcap_file_path}
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/stop_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses=responses)
|
||||
async def stop_capture(adapter_number: int, port_number: int, node: VMwareVM = Depends(dep_node)):
|
||||
@ -253,7 +253,7 @@ async def stop_capture(adapter_number: int, port_number: int, node: VMwareVM = D
|
||||
await node.stop_capture(adapter_number)
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/pcap",
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream",
|
||||
responses=responses)
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: VMwareVM = Depends(dep_node)):
|
||||
"""
|
||||
|
@ -26,7 +26,7 @@ from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.responses import StreamingResponse
|
||||
from uuid import UUID
|
||||
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
from gns3server.compute.vpcs import VPCS
|
||||
from gns3server.compute.vpcs.vpcs_vm import VPCSVM
|
||||
|
||||
@ -208,7 +208,7 @@ async def delete_nio(adapter_number: int, port_number: int, node: VPCSVM = Depen
|
||||
await node.port_remove_nio_binding(port_number)
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/start_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start",
|
||||
responses=responses)
|
||||
async def start_capture(adapter_number: int,
|
||||
port_number: int,
|
||||
@ -224,7 +224,7 @@ async def start_capture(adapter_number: int,
|
||||
return {"pcap_file_path": pcap_file_path}
|
||||
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/stop_capture",
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses=responses)
|
||||
async def stop_capture(adapter_number: int, port_number: int, node: VPCSVM = Depends(dep_node)):
|
||||
@ -244,7 +244,7 @@ async def reset_console(node: VPCSVM = Depends(dep_node)):
|
||||
await node.reset_console()
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/pcap",
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream",
|
||||
responses=responses)
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: VPCSVM = Depends(dep_node)):
|
||||
"""
|
||||
|
@ -25,22 +25,21 @@ from typing import List, Union
|
||||
from uuid import UUID
|
||||
|
||||
from gns3server.controller import Controller
|
||||
from gns3server.endpoints.schemas.common import ErrorMessage
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
responses = {
|
||||
404: {"model": ErrorMessage, "description": "Compute not found"}
|
||||
404: {"model": schemas.ErrorMessage, "description": "Compute not found"}
|
||||
}
|
||||
|
||||
|
||||
@router.post("",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Compute,
|
||||
responses={404: {"model": ErrorMessage, "description": "Could not connect to compute"},
|
||||
409: {"model": ErrorMessage, "description": "Could not create compute"},
|
||||
401: {"model": ErrorMessage, "description": "Invalid authentication for compute"}})
|
||||
responses={404: {"model": schemas.ErrorMessage, "description": "Could not connect to compute"},
|
||||
409: {"model": schemas.ErrorMessage, "description": "Could not create compute"},
|
||||
401: {"model": schemas.ErrorMessage, "description": "Invalid authentication for compute"}})
|
||||
async def create_compute(compute_data: schemas.ComputeCreate):
|
||||
"""
|
||||
Create a new compute on the controller.
|
||||
|
@ -26,8 +26,7 @@ from gns3server.config import Config
|
||||
from gns3server.controller import Controller
|
||||
from gns3server.version import __version__
|
||||
from gns3server.controller.controller_error import ControllerError, ControllerForbiddenError
|
||||
from gns3server.endpoints.schemas.common import ErrorMessage
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
|
||||
|
||||
import logging
|
||||
@ -38,7 +37,7 @@ router = APIRouter()
|
||||
|
||||
@router.post("/shutdown",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses={403: {"model": ErrorMessage, "description": "Server shutdown not allowed"}})
|
||||
responses={403: {"model": schemas.ErrorMessage, "description": "Server shutdown not allowed"}})
|
||||
async def shutdown():
|
||||
"""
|
||||
Shutdown the local server
|
||||
@ -85,7 +84,7 @@ def version():
|
||||
@router.post("/version",
|
||||
response_model=schemas.Version,
|
||||
response_model_exclude_defaults=True,
|
||||
responses={409: {"model": ErrorMessage, "description": "Invalid version"}})
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Invalid version"}})
|
||||
def check_version(version: schemas.Version):
|
||||
"""
|
||||
Check if version is the same as the server.
|
||||
|
@ -25,18 +25,17 @@ from typing import List
|
||||
from uuid import UUID
|
||||
|
||||
from gns3server.controller import Controller
|
||||
from gns3server.endpoints.schemas.common import ErrorMessage
|
||||
from gns3server.endpoints.schemas.drawings import Drawing
|
||||
from gns3server import schemas
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
responses = {
|
||||
404: {"model": ErrorMessage, "description": "Project or drawing not found"}
|
||||
404: {"model": schemas.ErrorMessage, "description": "Project or drawing not found"}
|
||||
}
|
||||
|
||||
|
||||
@router.get("",
|
||||
response_model=List[Drawing],
|
||||
response_model=List[schemas.Drawing],
|
||||
response_model_exclude_unset=True)
|
||||
async def get_drawings(project_id: UUID):
|
||||
"""
|
||||
@ -49,9 +48,9 @@ async def get_drawings(project_id: UUID):
|
||||
|
||||
@router.post("",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=Drawing,
|
||||
response_model=schemas.Drawing,
|
||||
responses=responses)
|
||||
async def create_drawing(project_id: UUID, drawing_data: Drawing):
|
||||
async def create_drawing(project_id: UUID, drawing_data: schemas.Drawing):
|
||||
"""
|
||||
Create a new drawing.
|
||||
"""
|
||||
@ -62,7 +61,7 @@ async def create_drawing(project_id: UUID, drawing_data: Drawing):
|
||||
|
||||
|
||||
@router.get("/{drawing_id}",
|
||||
response_model=Drawing,
|
||||
response_model=schemas.Drawing,
|
||||
response_model_exclude_unset=True,
|
||||
responses=responses)
|
||||
async def get_drawing(project_id: UUID, drawing_id: UUID):
|
||||
@ -76,10 +75,10 @@ async def get_drawing(project_id: UUID, drawing_id: UUID):
|
||||
|
||||
|
||||
@router.put("/{drawing_id}",
|
||||
response_model=Drawing,
|
||||
response_model=schemas.Drawing,
|
||||
response_model_exclude_unset=True,
|
||||
responses=responses)
|
||||
async def update_drawing(project_id: UUID, drawing_id: UUID, drawing_data: Drawing):
|
||||
async def update_drawing(project_id: UUID, drawing_id: UUID, drawing_data: schemas.Drawing):
|
||||
"""
|
||||
Update a drawing.
|
||||
"""
|
||||
|
@ -23,7 +23,7 @@ from fastapi import APIRouter
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
|
||||
from gns3server.controller import Controller
|
||||
from gns3server.endpoints.schemas.gns3vm import GNS3VM
|
||||
from gns3server import schemas
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@ -48,7 +48,7 @@ async def get_vms(engine: str):
|
||||
return vms
|
||||
|
||||
|
||||
@router.get("", response_model=GNS3VM)
|
||||
@router.get("", response_model=schemas.GNS3VM)
|
||||
async def get_gns3vm_settings():
|
||||
"""
|
||||
Return the GNS3 VM settings.
|
||||
@ -57,8 +57,8 @@ async def get_gns3vm_settings():
|
||||
return Controller.instance().gns3vm.__json__()
|
||||
|
||||
|
||||
@router.put("", response_model=GNS3VM, response_model_exclude_unset=True)
|
||||
async def update_gns3vm_settings(gns3vm_data: GNS3VM):
|
||||
@router.put("", response_model=schemas.GNS3VM, response_model_exclude_unset=True)
|
||||
async def update_gns3vm_settings(gns3vm_data: schemas.GNS3VM):
|
||||
"""
|
||||
Update the GNS3 VM settings.
|
||||
"""
|
||||
|
@ -32,8 +32,7 @@ from gns3server.controller import Controller
|
||||
from gns3server.controller.controller_error import ControllerError
|
||||
from gns3server.controller.link import Link
|
||||
from gns3server.utils.http_client import HTTPClient
|
||||
from gns3server.endpoints.schemas.common import ErrorMessage
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
@ -41,7 +40,7 @@ log = logging.getLogger(__name__)
|
||||
router = APIRouter()
|
||||
|
||||
responses = {
|
||||
404: {"model": ErrorMessage, "description": "Could not find project or link"}
|
||||
404: {"model": schemas.ErrorMessage, "description": "Could not find project or link"}
|
||||
}
|
||||
|
||||
|
||||
@ -70,8 +69,8 @@ async def get_links(project_id: UUID):
|
||||
@router.post("",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Link,
|
||||
responses={404: {"model": ErrorMessage, "description": "Could not find project"},
|
||||
409: {"model": ErrorMessage, "description": "Could not create link"}})
|
||||
responses={404: {"model": schemas.ErrorMessage, "description": "Could not find project"},
|
||||
409: {"model": schemas.ErrorMessage, "description": "Could not create link"}})
|
||||
async def create_link(project_id: UUID, link_data: schemas.Link):
|
||||
"""
|
||||
Create a new link.
|
||||
@ -137,31 +136,6 @@ async def update_link(link_data: schemas.Link, link: Link = Depends(dep_link)):
|
||||
return link.__json__()
|
||||
|
||||
|
||||
@router.post("/{link_id}/start_capture",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Link,
|
||||
responses=responses)
|
||||
async def start_capture(capture_data: dict, link: Link = Depends(dep_link)):
|
||||
"""
|
||||
Start packet capture on the link.
|
||||
"""
|
||||
|
||||
await link.start_capture(data_link_type=capture_data.get("data_link_type", "DLT_EN10MB"),
|
||||
capture_file_name=capture_data.get("capture_file_name"))
|
||||
return link.__json__()
|
||||
|
||||
|
||||
@router.post("/{link_id}/stop_capture",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses=responses)
|
||||
async def stop_capture(link: Link = Depends(dep_link)):
|
||||
"""
|
||||
Stop packet capture on the link.
|
||||
"""
|
||||
|
||||
await link.stop_capture()
|
||||
|
||||
|
||||
@router.delete("/{link_id}",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses=responses)
|
||||
@ -186,9 +160,34 @@ async def reset_link(link: Link = Depends(dep_link)):
|
||||
return link.__json__()
|
||||
|
||||
|
||||
@router.get("/{link_id}/pcap",
|
||||
@router.post("/{link_id}/capture/start",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Link,
|
||||
responses=responses)
|
||||
async def start_capture(capture_data: dict, link: Link = Depends(dep_link)):
|
||||
"""
|
||||
Start packet capture on the link.
|
||||
"""
|
||||
|
||||
await link.start_capture(data_link_type=capture_data.get("data_link_type", "DLT_EN10MB"),
|
||||
capture_file_name=capture_data.get("capture_file_name"))
|
||||
return link.__json__()
|
||||
|
||||
|
||||
@router.post("/{link_id}/capture/stop",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses=responses)
|
||||
async def stop_capture(link: Link = Depends(dep_link)):
|
||||
"""
|
||||
Stop packet capture on the link.
|
||||
"""
|
||||
|
||||
await link.stop_capture()
|
||||
|
||||
|
||||
@router.get("/{link_id}/capture/stream",
|
||||
responses=responses)
|
||||
async def pcap(request: Request, link: Link = Depends(dep_link)):
|
||||
async def stream_pcap(request: Request, link: Link = Depends(dep_link)):
|
||||
"""
|
||||
Stream the PCAP capture file from compute.
|
||||
"""
|
||||
|
@ -34,8 +34,7 @@ from gns3server.controller.project import Project
|
||||
from gns3server.utils import force_unix_path
|
||||
from gns3server.utils.http_client import HTTPClient
|
||||
from gns3server.controller.controller_error import ControllerForbiddenError
|
||||
from gns3server.endpoints.schemas.common import ErrorMessage
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
@ -80,7 +79,7 @@ class NodeConcurrency(APIRoute):
|
||||
router = APIRouter(route_class=NodeConcurrency)
|
||||
|
||||
responses = {
|
||||
404: {"model": ErrorMessage, "description": "Could not find project or node"}
|
||||
404: {"model": schemas.ErrorMessage, "description": "Could not find project or node"}
|
||||
}
|
||||
|
||||
|
||||
@ -105,8 +104,8 @@ async def dep_node(node_id: UUID, project: Project = Depends(dep_project)):
|
||||
@router.post("",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Node,
|
||||
responses={404: {"model": ErrorMessage, "description": "Could not find project"},
|
||||
409: {"model": ErrorMessage, "description": "Could not create node"}})
|
||||
responses={404: {"model": schemas.ErrorMessage, "description": "Could not find project"},
|
||||
409: {"model": schemas.ErrorMessage, "description": "Could not create node"}})
|
||||
async def create_node(node_data: schemas.Node, project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Create a new node.
|
||||
@ -212,7 +211,7 @@ async def update_node(node_data: schemas.NodeUpdate, node: Node = Depends(dep_no
|
||||
@router.delete("/{node_id}",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses={**responses,
|
||||
409: {"model": ErrorMessage, "description": "Cannot delete node"}})
|
||||
409: {"model": schemas.ErrorMessage, "description": "Cannot delete node"}})
|
||||
async def delete_node(node_id: UUID, project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Delete a node from a project.
|
||||
@ -381,7 +380,7 @@ async def ws_console(websocket: WebSocket, node: Node = Depends(dep_node)):
|
||||
compute = node.compute
|
||||
await websocket.accept()
|
||||
log.info(f"New client {websocket.client.host}:{websocket.client.port} has connected to controller console WebSocket")
|
||||
ws_console_compute_url = f"ws://{compute.host}:{compute.port}/v2/compute/projects/" \
|
||||
ws_console_compute_url = f"ws://{compute.host}:{compute.port}/v3/compute/projects/" \
|
||||
f"{node.project.id}/{node.node_type}/nodes/{node.id}/console/ws"
|
||||
|
||||
async def ws_receive(ws_console_compute):
|
||||
|
@ -37,8 +37,7 @@ from typing import List, Optional
|
||||
from uuid import UUID
|
||||
from pathlib import Path
|
||||
|
||||
from gns3server.endpoints.schemas.common import ErrorMessage
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
from gns3server.controller import Controller
|
||||
from gns3server.controller.project import Project
|
||||
from gns3server.controller.controller_error import ControllerError, ControllerForbiddenError
|
||||
@ -51,7 +50,7 @@ from gns3server.config import Config
|
||||
router = APIRouter()
|
||||
|
||||
responses = {
|
||||
404: {"model": ErrorMessage, "description": "Could not find project"}
|
||||
404: {"model": schemas.ErrorMessage, "description": "Could not find project"}
|
||||
}
|
||||
|
||||
|
||||
@ -83,7 +82,7 @@ def get_projects():
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Project,
|
||||
response_model_exclude_unset=True,
|
||||
responses={409: {"model": ErrorMessage, "description": "Could not create project"}})
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Could not create project"}})
|
||||
async def create_project(project_data: schemas.ProjectCreate):
|
||||
"""
|
||||
Create a new project.
|
||||
@ -145,7 +144,7 @@ def get_project_stats(project: Project = Depends(dep_project)):
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses={
|
||||
**responses,
|
||||
409: {"model": ErrorMessage, "description": "Could not close project"}
|
||||
409: {"model": schemas.ErrorMessage, "description": "Could not close project"}
|
||||
})
|
||||
async def close_project(project: Project = Depends(dep_project)):
|
||||
"""
|
||||
@ -160,7 +159,7 @@ async def close_project(project: Project = Depends(dep_project)):
|
||||
response_model=schemas.Project,
|
||||
responses={
|
||||
**responses,
|
||||
409: {"model": ErrorMessage, "description": "Could not open project"}
|
||||
409: {"model": schemas.ErrorMessage, "description": "Could not open project"}
|
||||
})
|
||||
async def open_project(project: Project = Depends(dep_project)):
|
||||
"""
|
||||
@ -176,7 +175,7 @@ async def open_project(project: Project = Depends(dep_project)):
|
||||
response_model=schemas.Project,
|
||||
responses={
|
||||
**responses,
|
||||
409: {"model": ErrorMessage, "description": "Could not load project"}
|
||||
409: {"model": schemas.ErrorMessage, "description": "Could not load project"}
|
||||
})
|
||||
async def load_project(path: str = Body(..., embed=True)):
|
||||
"""
|
||||
@ -346,7 +345,7 @@ async def import_project(project_id: UUID, request: Request, path: Optional[Path
|
||||
response_model=schemas.Project,
|
||||
responses={
|
||||
**responses,
|
||||
409: {"model": ErrorMessage, "description": "Could not duplicate project"}
|
||||
409: {"model": schemas.ErrorMessage, "description": "Could not duplicate project"}
|
||||
})
|
||||
async def duplicate(project_data: schemas.ProjectDuplicate, project: Project = Depends(dep_project)):
|
||||
"""
|
||||
|
@ -27,14 +27,13 @@ from typing import List
|
||||
from uuid import UUID
|
||||
|
||||
from gns3server.controller.project import Project
|
||||
from gns3server.endpoints.schemas.common import ErrorMessage
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
from gns3server.controller import Controller
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
responses = {
|
||||
404: {"model": ErrorMessage, "description": "Could not find project or snapshot"}
|
||||
404: {"model": schemas.ErrorMessage, "description": "Could not find project or snapshot"}
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,7 +25,7 @@ from fastapi import APIRouter, Request, status
|
||||
from fastapi.responses import FileResponse
|
||||
|
||||
from gns3server.controller import Controller
|
||||
from gns3server.endpoints.schemas.common import ErrorMessage
|
||||
from gns3server import schemas
|
||||
from gns3server.controller.controller_error import ControllerError, ControllerNotFoundError
|
||||
|
||||
import logging
|
||||
@ -43,7 +43,7 @@ def get_symbols():
|
||||
|
||||
|
||||
@router.get("/{symbol_id:path}/raw",
|
||||
responses={404: {"model": ErrorMessage, "description": "Could not find symbol"}})
|
||||
responses={404: {"model": schemas.ErrorMessage, "description": "Could not find symbol"}})
|
||||
async def get_symbol(symbol_id: str):
|
||||
"""
|
||||
Download a symbol file.
|
||||
|
@ -27,25 +27,20 @@ log = logging.getLogger(__name__)
|
||||
|
||||
from fastapi import APIRouter, Request, Response, HTTPException, status
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from typing import Union, List
|
||||
from typing import List
|
||||
from uuid import UUID
|
||||
|
||||
from gns3server.endpoints.schemas.common import ErrorMessage
|
||||
from gns3server.endpoints import schemas
|
||||
from gns3server import schemas
|
||||
from gns3server.controller import Controller
|
||||
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
responses = {
|
||||
404: {"model": ErrorMessage, "description": "Could not find template"}
|
||||
404: {"model": schemas.ErrorMessage, "description": "Could not find template"}
|
||||
}
|
||||
|
||||
|
||||
#template_create_models = Union[schemas.VPCSTemplateCreate, schemas.CloudTemplateCreate, schemas.IOUTemplateCreate]
|
||||
#template_update_models = Union[schemas.VPCSTemplateUpdate, schemas.CloudTemplateUpdate, schemas.IOUTemplateUpdate]
|
||||
#template_response_models = Union[schemas.VPCSTemplate, schemas.CloudTemplate, schemas.IOUTemplate]
|
||||
|
||||
|
||||
@router.post("/templates",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Template)
|
||||
@ -138,7 +133,7 @@ async def duplicate_template(template_id: UUID):
|
||||
@router.post("/projects/{project_id}/templates/{template_id}",
|
||||
response_model=schemas.Node,
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
responses={404: {"model": ErrorMessage, "description": "Could not find project or template"}})
|
||||
responses={404: {"model": schemas.ErrorMessage, "description": "Could not find project or template"}})
|
||||
async def create_node_from_template(project_id: UUID, template_id: UUID, template_usage: schemas.TemplateUsage):
|
||||
"""
|
||||
Create a new node from a template.
|
||||
|
@ -1,45 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2020 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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 .version import Version
|
||||
from .iou_license import IOULicense
|
||||
from .links import Link
|
||||
from .common import ErrorMessage
|
||||
from .computes import ComputeCreate, ComputeUpdate, Compute, AutoIdlePC
|
||||
from .nodes import NodeUpdate, NodeDuplicate, NodeCapture, Node
|
||||
from .projects import ProjectCreate, ProjectUpdate, ProjectDuplicate, Project, ProjectFile
|
||||
from .snapshots import SnapshotCreate, Snapshot
|
||||
from .templates import TemplateCreate, TemplateUpdate, TemplateUsage, Template
|
||||
from .capabilities import Capabilities
|
||||
from .nios import UDPNIO, TAPNIO, EthernetNIO
|
||||
from .atm_switch_nodes import ATMSwitchCreate, ATMSwitchUpdate, ATMSwitch
|
||||
from .cloud_nodes import CloudCreate, CloudUpdate, Cloud
|
||||
from .docker_nodes import DockerCreate, DockerUpdate, Docker
|
||||
from .dynamips_nodes import DynamipsCreate, DynamipsUpdate, Dynamips
|
||||
from .ethernet_hub_nodes import EthernetHubCreate, EthernetHubUpdate, EthernetHub
|
||||
from .ethernet_switch_nodes import EthernetSwitchCreate, EthernetSwitchUpdate, EthernetSwitch
|
||||
from .frame_relay_switch_nodes import FrameRelaySwitchCreate, FrameRelaySwitchUpdate, FrameRelaySwitch
|
||||
from .iou_nodes import IOUCreate, IOUUpdate, IOUStart, IOU
|
||||
from .nat_nodes import NATCreate, NATUpdate, NAT
|
||||
from .qemu_nodes import QemuCreate, QemuUpdate, Qemu, QemuDiskResize, QemuImageCreate, QemuImageUpdate
|
||||
from .virtualbox_nodes import VirtualBoxCreate, VirtualBoxUpdate, VirtualBox
|
||||
from .vmware_nodes import VMwareCreate, VMwareUpdate, VMware
|
||||
from .vpcs_nodes import VPCSCreate, VPCSUpdate, VPCS
|
||||
from .vpcs_templates import VPCSTemplateCreate, VPCSTemplateUpdate, VPCSTemplate
|
||||
from .cloud_templates import CloudTemplateCreate, CloudTemplateUpdate, CloudTemplate
|
||||
from .iou_templates import IOUTemplateCreate, IOUTemplateUpdate, IOUTemplate
|
@ -1,35 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2020 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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 pydantic import BaseModel, Field
|
||||
from typing import List
|
||||
|
||||
from .nodes import NodeType
|
||||
|
||||
|
||||
class Capabilities(BaseModel):
|
||||
"""
|
||||
Capabilities properties.
|
||||
"""
|
||||
|
||||
version: str = Field(..., description="Compute version number")
|
||||
node_types: List[NodeType] = Field(..., description="Node types supported by the compute")
|
||||
platform: str = Field(..., description="Platform where the compute is running")
|
||||
cpus: int = Field(..., description="Number of CPUs on this compute")
|
||||
memory: int = Field(..., description="Amount of memory on this compute")
|
||||
disk_size: int = Field(..., description="Disk size on this compute")
|
@ -1,25 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2015 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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 pydantic import BaseModel, Field
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class Version(BaseModel):
|
||||
|
||||
version: str = Field(..., description="Version number")
|
||||
local: Optional[bool] = Field(None, description="Whether this is a local server or not")
|
@ -0,0 +1,64 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2020 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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 .iou_license import IOULicense
|
||||
from .links import Link
|
||||
from .common import ErrorMessage
|
||||
from .version import Version
|
||||
from .computes import ComputeCreate, ComputeUpdate, AutoIdlePC, Compute
|
||||
from .templates import TemplateCreate, TemplateUpdate, TemplateUsage, Template
|
||||
from .drawings import Drawing
|
||||
from .gns3vm import GNS3VM
|
||||
from .nodes import NodeUpdate, NodeDuplicate, NodeCapture, Node
|
||||
from .projects import ProjectCreate, ProjectUpdate, ProjectDuplicate, Project, ProjectFile
|
||||
from .snapshots import SnapshotCreate, Snapshot
|
||||
from .capabilities import Capabilities
|
||||
from .nios import UDPNIO, TAPNIO, EthernetNIO
|
||||
from .atm_switch_nodes import ATMSwitchCreate, ATMSwitchUpdate, ATMSwitch
|
||||
from .cloud_nodes import CloudCreate, CloudUpdate, Cloud
|
||||
from .docker_nodes import DockerCreate, DockerUpdate, Docker
|
||||
from .dynamips_nodes import DynamipsCreate, DynamipsUpdate, Dynamips
|
||||
from .ethernet_hub_nodes import EthernetHubCreate, EthernetHubUpdate, EthernetHub
|
||||
from .ethernet_switch_nodes import EthernetSwitchCreate, EthernetSwitchUpdate, EthernetSwitch
|
||||
from .frame_relay_switch_nodes import FrameRelaySwitchCreate, FrameRelaySwitchUpdate, FrameRelaySwitch
|
||||
from .qemu_nodes import QemuCreate, QemuUpdate, QemuImageCreate, QemuImageUpdate, QemuDiskResize, Qemu
|
||||
from .iou_nodes import IOUCreate, IOUUpdate, IOUStart, IOU
|
||||
from .nat_nodes import NATCreate, NATUpdate, NAT
|
||||
from .vpcs_nodes import VPCSCreate, VPCSUpdate, VPCS
|
||||
from .vmware_nodes import VMwareCreate, VMwareUpdate, VMware
|
||||
from .virtualbox_nodes import VirtualBoxCreate, VirtualBoxUpdate, VirtualBox
|
||||
|
||||
from .vpcs_templates import VPCSTemplate
|
||||
from .cloud_templates import CloudTemplate
|
||||
from .iou_templates import IOUTemplate
|
||||
from .docker_templates import DockerTemplate
|
||||
from .ethernet_hub_templates import EthernetHubTemplate
|
||||
from .ethernet_switch_templates import EthernetSwitchTemplate
|
||||
from .virtualbox_templates import VirtualBoxTemplate
|
||||
from .vmware_templates import VMwareTemplate
|
||||
from .qemu_templates import QemuTemplate
|
||||
from .dynamips_templates import (
|
||||
DynamipsTemplate,
|
||||
C1700DynamipsTemplate,
|
||||
C2600DynamipsTemplate,
|
||||
C2691DynamipsTemplate,
|
||||
C3600DynamipsTemplate,
|
||||
C3725DynamipsTemplate,
|
||||
C3745DynamipsTemplate,
|
||||
C7200DynamipsTemplate
|
||||
)
|
@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2015 GNS3 Technologies Inc.
|
||||
# Copyright (C) 2020 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,40 +15,21 @@
|
||||
# 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 .node import NODE_TYPE_SCHEMA
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import List
|
||||
|
||||
from .nodes import NodeType
|
||||
|
||||
|
||||
CAPABILITIES_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Get what a server support",
|
||||
"type": "object",
|
||||
"required": ["version", "node_types"],
|
||||
"properties": {
|
||||
"version": {
|
||||
"description": "Version number",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"node_types": {
|
||||
"type": "array",
|
||||
"items": NODE_TYPE_SCHEMA,
|
||||
"description": "Node type supported by the compute"
|
||||
},
|
||||
"platform": {
|
||||
"type": "string",
|
||||
"description": "Platform where the compute is running"
|
||||
},
|
||||
"cpus": {
|
||||
"description": "Number of CPUs on this compute. Read only",
|
||||
"type": ["integer", "null"],
|
||||
},
|
||||
"memory": {
|
||||
"description": "Amount of memory on this compute. Read only",
|
||||
"type": ["integer", "null"],
|
||||
},
|
||||
"disk_size": {
|
||||
"description": "Disk size on this compute. Read only",
|
||||
"type": ["integer", "null"],
|
||||
},
|
||||
},
|
||||
"additionalProperties": False
|
||||
}
|
||||
class Capabilities(BaseModel):
|
||||
"""
|
||||
Capabilities properties.
|
||||
"""
|
||||
|
||||
version: str = Field(..., description="Compute version number")
|
||||
node_types: List[NodeType] = Field(..., description="Node types supported by the compute")
|
||||
platform: str = Field(..., description="Platform where the compute is running")
|
||||
cpus: int = Field(..., description="Number of CPUs on this compute")
|
||||
memory: int = Field(..., description="Amount of memory on this compute")
|
||||
disk_size: int = Field(..., description="Disk size on this compute")
|
||||
|
@ -1,66 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import copy
|
||||
from .template import BASE_TEMPLATE_PROPERTIES
|
||||
from .port import PORT_OBJECT_SCHEMA
|
||||
|
||||
|
||||
CLOUD_TEMPLATE_PROPERTIES = {
|
||||
"ports_mapping": {
|
||||
"type": "array",
|
||||
"items": [PORT_OBJECT_SCHEMA],
|
||||
"default": []
|
||||
},
|
||||
"remote_console_host": {
|
||||
"description": "Remote console host or IP",
|
||||
"type": ["string"],
|
||||
"minLength": 1,
|
||||
"default": "127.0.0.1"
|
||||
},
|
||||
"remote_console_port": {
|
||||
"description": "Console TCP port",
|
||||
"minimum": 1,
|
||||
"maximum": 65535,
|
||||
"type": "integer",
|
||||
"default": 23
|
||||
},
|
||||
"remote_console_type": {
|
||||
"description": "Console type",
|
||||
"enum": ["telnet", "vnc", "spice", "http", "https", "none"],
|
||||
"default": "none"
|
||||
},
|
||||
"remote_console_http_path": {
|
||||
"description": "Path of the remote web interface",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"default": "/"
|
||||
},
|
||||
}
|
||||
|
||||
CLOUD_TEMPLATE_PROPERTIES.update(copy.deepcopy(BASE_TEMPLATE_PROPERTIES))
|
||||
CLOUD_TEMPLATE_PROPERTIES["category"]["default"] = "guest"
|
||||
CLOUD_TEMPLATE_PROPERTIES["default_name_format"]["default"] = "Cloud{0}"
|
||||
CLOUD_TEMPLATE_PROPERTIES["symbol"]["default"] = ":/symbols/cloud.svg"
|
||||
|
||||
CLOUD_TEMPLATE_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "A cloud template object",
|
||||
"type": "object",
|
||||
"properties": CLOUD_TEMPLATE_PROPERTIES,
|
||||
"additionalProperties": False
|
||||
}
|
@ -17,29 +17,13 @@
|
||||
|
||||
|
||||
from .templates import Category, TemplateBase
|
||||
from .cloud_nodes import EthernetPort, TAPPort, UDPPort
|
||||
from .cloud_nodes import EthernetPort, TAPPort, UDPPort, CloudConsoleType
|
||||
|
||||
from pydantic import Field
|
||||
from typing import Optional, Union, List
|
||||
from enum import Enum
|
||||
|
||||
from .nodes import NodeType
|
||||
|
||||
|
||||
class RemoteConsoleType(str, Enum):
|
||||
"""
|
||||
Supported remote console types for cloud nodes.
|
||||
"""
|
||||
|
||||
none = "none"
|
||||
telnet = "telnet"
|
||||
vnc = "vnc"
|
||||
spice = "spice"
|
||||
http = "http"
|
||||
https = "https"
|
||||
|
||||
|
||||
class CloudTemplateBase(TemplateBase):
|
||||
class CloudTemplate(TemplateBase):
|
||||
|
||||
category: Optional[Category] = "guest"
|
||||
default_name_format: Optional[str] = "Cloud{0}"
|
||||
@ -47,28 +31,5 @@ class CloudTemplateBase(TemplateBase):
|
||||
ports_mapping: List[Union[EthernetPort, TAPPort, UDPPort]] = []
|
||||
remote_console_host: Optional[str] = Field("127.0.0.1", description="Remote console host or IP")
|
||||
remote_console_port: Optional[int] = Field(23, gt=0, le=65535, description="Remote console TCP port")
|
||||
remote_console_type: Optional[RemoteConsoleType] = Field("none", description="Remote console type")
|
||||
remote_console_path: Optional[str] = Field("/", description="Path of the remote web interface")
|
||||
|
||||
|
||||
class CloudTemplateCreate(CloudTemplateBase):
|
||||
|
||||
name: str
|
||||
template_type: NodeType
|
||||
compute_id: str
|
||||
|
||||
|
||||
class CloudTemplateUpdate(CloudTemplateBase):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class CloudTemplate(CloudTemplateBase):
|
||||
|
||||
template_id: str
|
||||
name: str
|
||||
category: Category
|
||||
symbol: str
|
||||
builtin: bool
|
||||
template_type: NodeType
|
||||
compute_id: Union[str, None]
|
||||
remote_console_type: Optional[CloudConsoleType] = Field("none", description="Remote console type")
|
||||
remote_console_http_path: Optional[str] = Field("/", description="Path of the remote web interface")
|
@ -1,188 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2015 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import copy
|
||||
from .capabilities import CAPABILITIES_SCHEMA
|
||||
|
||||
COMPUTE_CREATE_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Request validation to register a GNS3 compute instance",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"compute_id": {
|
||||
"description": "Server identifier",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "Server name",
|
||||
"type": "string"
|
||||
},
|
||||
"protocol": {
|
||||
"description": "Server protocol",
|
||||
"enum": ["http", "https"]
|
||||
},
|
||||
"host": {
|
||||
"description": "Server host",
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"description": "Server port",
|
||||
"type": "integer"
|
||||
},
|
||||
"user": {
|
||||
"description": "User for authentication",
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"password": {
|
||||
"description": "Password for authentication",
|
||||
"type": ["string", "null"]
|
||||
}
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"required": ["protocol", "host", "port"]
|
||||
}
|
||||
|
||||
COMPUTE_UPDATE_SCHEMA = copy.deepcopy(COMPUTE_CREATE_SCHEMA)
|
||||
del COMPUTE_UPDATE_SCHEMA["required"]
|
||||
|
||||
COMPUTE_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Request validation to a GNS3 compute object instance",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"compute_id": {
|
||||
"description": "Server identifier",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "Server name",
|
||||
"type": "string"
|
||||
},
|
||||
"protocol": {
|
||||
"description": "Server protocol",
|
||||
"enum": ["http", "https"]
|
||||
},
|
||||
"host": {
|
||||
"description": "Server host",
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"description": "Server port",
|
||||
"type": "integer"
|
||||
},
|
||||
"user": {
|
||||
"description": "User for authentication",
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"connected": {
|
||||
"description": "Whether the controller is connected to the compute or not",
|
||||
"type": "boolean"
|
||||
},
|
||||
"cpu_usage_percent": {
|
||||
"description": "CPU usage of the compute. Read only",
|
||||
"type": ["number", "null"],
|
||||
"maximum": 100,
|
||||
"minimum": 0
|
||||
},
|
||||
"memory_usage_percent": {
|
||||
"description": "RAM usage of the compute. Read only",
|
||||
"type": ["number", "null"],
|
||||
"maximum": 100,
|
||||
"minimum": 0
|
||||
},
|
||||
"disk_usage_percent": {
|
||||
"description": "Disk usage of the compute. Read only",
|
||||
"type": ["number", "null"],
|
||||
"maximum": 100,
|
||||
"minimum": 0
|
||||
},
|
||||
"last_error": {
|
||||
"description": "Last error on the compute",
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"capabilities": CAPABILITIES_SCHEMA
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"required": ["compute_id", "protocol", "host", "port", "name"]
|
||||
}
|
||||
|
||||
COMPUTE_ENDPOINT_OUTPUT_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Output schema for obtaining endpoint on compute",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"endpoint": {
|
||||
"description": "URL to endpoint on specific compute and to particular action",
|
||||
"type": "string"
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
COMPUTE_PORTS_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Output schema for open ports on a compute",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"console_port_range": {
|
||||
"description": "Console port range",
|
||||
"type": "array",
|
||||
"uniqueItems": True,
|
||||
"minItems": 2,
|
||||
"maxItems": 2,
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 65535
|
||||
}
|
||||
},
|
||||
"console_ports": {
|
||||
"description": "Console ports used by the compute",
|
||||
"type": "array",
|
||||
"uniqueItems": True,
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 65535
|
||||
}
|
||||
},
|
||||
"udp_port_range": {
|
||||
"description": "UDP port range",
|
||||
"type": "array",
|
||||
"uniqueItems": True,
|
||||
"minItems": 2,
|
||||
"maxItems": 2,
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 65535
|
||||
}
|
||||
},
|
||||
"udp_ports": {
|
||||
"description": "UDP ports used by the compute",
|
||||
"type": "array",
|
||||
"uniqueItems": True,
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 65535
|
||||
}
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
@ -103,12 +103,12 @@ class Compute(ComputeBase):
|
||||
|
||||
compute_id: Union[str, UUID]
|
||||
name: str
|
||||
connected: bool = Field(..., description="Whether the controller is connected to the compute or not")
|
||||
cpu_usage_percent: float = Field(..., description="CPU usage of the compute", ge=0, le=100)
|
||||
memory_usage_percent: float = Field(..., description="Memory usage of the compute", ge=0, le=100)
|
||||
disk_usage_percent: float = Field(..., description="Disk usage of the compute", ge=0, le=100)
|
||||
connected: Optional[bool] = Field(None, description="Whether the controller is connected to the compute or not")
|
||||
cpu_usage_percent: Optional[float] = Field(None, description="CPU usage of the compute", ge=0, le=100)
|
||||
memory_usage_percent: Optional[float] = Field(None, description="Memory usage of the compute", ge=0, le=100)
|
||||
disk_usage_percent: Optional[float] = Field(None, description="Disk usage of the compute", ge=0, le=100)
|
||||
last_error: Optional[str] = Field(None, description="Last error found on the compute")
|
||||
capabilities: Capabilities
|
||||
capabilities: Optional[Capabilities] = None
|
||||
|
||||
|
||||
class AutoIdlePC(BaseModel):
|
@ -1,49 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
CUSTOM_ADAPTERS_ARRAY_SCHEMA = {
|
||||
"type": "array",
|
||||
"default": [],
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Custom properties",
|
||||
"properties": {
|
||||
"adapter_number": {
|
||||
"type": "integer",
|
||||
"description": "Adapter number"
|
||||
},
|
||||
"port_name": {
|
||||
"type": "string",
|
||||
"description": "Custom port name",
|
||||
"minLength": 1,
|
||||
},
|
||||
"adapter_type": {
|
||||
"type": "string",
|
||||
"description": "Custom adapter type",
|
||||
"minLength": 1,
|
||||
},
|
||||
"mac_address": {
|
||||
"description": "Custom MAC address",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"pattern": "^([0-9a-fA-F]{2}[:]){5}([0-9a-fA-F]{2})$"
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"required": ["adapter_number"]
|
||||
},
|
||||
}
|
@ -1,115 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import copy
|
||||
from .template import BASE_TEMPLATE_PROPERTIES
|
||||
from .custom_adapters import CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||
|
||||
|
||||
DOCKER_TEMPLATE_PROPERTIES = {
|
||||
"image": {
|
||||
"description": "Docker image name",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"adapters": {
|
||||
"description": "Number of adapters",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 99,
|
||||
"default": 1
|
||||
},
|
||||
"start_command": {
|
||||
"description": "Docker CMD entry",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"environment": {
|
||||
"description": "Docker environment variables",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"console_type": {
|
||||
"description": "Console type",
|
||||
"enum": ["telnet", "vnc", "http", "https", "none"],
|
||||
"default": "telnet"
|
||||
},
|
||||
"aux_type": {
|
||||
"description": "Auxiliary console type",
|
||||
"enum": ["telnet", "none"],
|
||||
"default": "none"
|
||||
},
|
||||
"console_auto_start": {
|
||||
"description": "Automatically start the console when the node has started",
|
||||
"type": "boolean",
|
||||
"default": False,
|
||||
},
|
||||
"console_http_port": {
|
||||
"description": "Internal port in the container for the HTTP server",
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 65535,
|
||||
"default": 80
|
||||
},
|
||||
"console_http_path": {
|
||||
"description": "Path of the web interface",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"default": "/"
|
||||
},
|
||||
"console_resolution": {
|
||||
"description": "Console resolution for VNC",
|
||||
"type": "string",
|
||||
"pattern": "^[0-9]+x[0-9]+$",
|
||||
"default": "1024x768"
|
||||
},
|
||||
"extra_hosts": {
|
||||
"description": "Docker extra hosts (added to /etc/hosts)",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"extra_volumes": {
|
||||
"description": "Additional directories to make persistent",
|
||||
"type": "array",
|
||||
"default": []
|
||||
},
|
||||
"memory": {
|
||||
"description": "Maximum amount of memory the container can use in MB",
|
||||
"type": "integer",
|
||||
"default": 0
|
||||
},
|
||||
"cpus": {
|
||||
"description": "Maximum amount of CPU resources the container can use",
|
||||
"type": "number",
|
||||
"default": 0
|
||||
},
|
||||
"custom_adapters": CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||
}
|
||||
|
||||
DOCKER_TEMPLATE_PROPERTIES.update(copy.deepcopy(BASE_TEMPLATE_PROPERTIES))
|
||||
DOCKER_TEMPLATE_PROPERTIES["category"]["default"] = "guest"
|
||||
DOCKER_TEMPLATE_PROPERTIES["default_name_format"]["default"] = "{name}-{0}"
|
||||
DOCKER_TEMPLATE_PROPERTIES["symbol"]["default"] = ":/symbols/docker_guest.svg"
|
||||
|
||||
DOCKER_TEMPLATE_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "A Docker template object",
|
||||
"type": "object",
|
||||
"properties": DOCKER_TEMPLATE_PROPERTIES,
|
||||
"required": ["image"],
|
||||
"additionalProperties": False
|
||||
}
|
46
gns3server/schemas/docker_templates.py
Normal file
46
gns3server/schemas/docker_templates.py
Normal file
@ -0,0 +1,46 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2020 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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 .templates import Category, TemplateBase
|
||||
from .nodes import CustomAdapter
|
||||
from .docker_nodes import ConsoleType, AuxType
|
||||
|
||||
from pydantic import Field
|
||||
from typing import Optional, List
|
||||
|
||||
|
||||
class DockerTemplate(TemplateBase):
|
||||
|
||||
category: Optional[Category] = "guest"
|
||||
default_name_format: Optional[str] = "{name}-{0}"
|
||||
symbol: Optional[str] = ":/symbols/docker_guest.svg"
|
||||
image: str = Field(..., description="Docker image name")
|
||||
adapters: Optional[int] = Field(1, ge=0, le=100, description="Number of adapters")
|
||||
start_command: Optional[str] = Field("", description="Docker CMD entry")
|
||||
environment: Optional[str] = Field("", description="Docker environment variables")
|
||||
console_type: Optional[ConsoleType] = Field("telnet", description="Console type")
|
||||
aux_type: Optional[AuxType] = Field("none", description="Auxiliary console type")
|
||||
console_auto_start: Optional[bool] = Field(False, description="Automatically start the console when the node has started")
|
||||
console_http_port: Optional[int] = Field(80, gt=0, le=65535, description="Internal port in the container for the HTTP server")
|
||||
console_http_path: Optional[str] = Field("/", description="Path of the web interface",)
|
||||
console_resolution: Optional[str] = Field("1024x768", regex="^[0-9]+x[0-9]+$", description="Console resolution for VNC")
|
||||
extra_hosts: Optional[str] = Field("", description="Docker extra hosts (added to /etc/hosts)")
|
||||
extra_volumes: Optional[List] = Field([], description="Additional directories to make persistent")
|
||||
memory: Optional[int] = Field(0, description="Maximum amount of memory the container can use in MB")
|
||||
cpus: Optional[int] = Field(0, description="Maximum amount of CPU resources the container can use")
|
||||
custom_adapters: Optional[List[CustomAdapter]] = Field([], description="Custom adapters")
|
@ -1,66 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (C) 2015 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
DRAWING_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "An drawing object",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"drawing_id": {
|
||||
"description": "Drawing UUID",
|
||||
"type": "string",
|
||||
"minLength": 36,
|
||||
"maxLength": 36,
|
||||
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
|
||||
},
|
||||
"project_id": {
|
||||
"description": "Project UUID",
|
||||
"type": "string",
|
||||
"minLength": 36,
|
||||
"maxLength": 36,
|
||||
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
|
||||
},
|
||||
"x": {
|
||||
"description": "X property",
|
||||
"type": "integer"
|
||||
},
|
||||
"y": {
|
||||
"description": "Y property",
|
||||
"type": "integer"
|
||||
},
|
||||
"z": {
|
||||
"description": "Z property",
|
||||
"type": "integer"
|
||||
},
|
||||
"locked": {
|
||||
"description": "Whether the element locked or not",
|
||||
"type": "boolean"
|
||||
},
|
||||
"rotation": {
|
||||
"description": "Rotation of the element",
|
||||
"type": "integer",
|
||||
"minimum": -359,
|
||||
"maximum": 360
|
||||
},
|
||||
"svg": {
|
||||
"description": "SVG content of the drawing",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": False
|
||||
}
|
@ -25,6 +25,20 @@ from uuid import UUID
|
||||
from .nodes import NodeStatus
|
||||
|
||||
|
||||
class DynamipsPlatform(str, Enum):
|
||||
"""
|
||||
Supported Dynamips Platforms.
|
||||
"""
|
||||
|
||||
c7200 = "c7200"
|
||||
c3725 = "c3725"
|
||||
c3745 = "c3745"
|
||||
c3600 = "c3600"
|
||||
c2691 = "c2691"
|
||||
c2600 = "c2600"
|
||||
c1700 = "c1700"
|
||||
|
||||
|
||||
class DynamipsAdapters(str, Enum):
|
||||
"""
|
||||
Supported Dynamips Network Modules.
|
||||
@ -56,6 +70,7 @@ class DynamipsAdapters(str, Enum):
|
||||
gt96100_fe = "GT96100-FE"
|
||||
leopard_2fe = "Leopard-2FE"
|
||||
|
||||
|
||||
class DynamipsWics(str, Enum):
|
||||
"""
|
||||
Supported Dynamips WICs.
|
||||
@ -108,7 +123,7 @@ class DynamipsBase(BaseModel):
|
||||
node_id: Optional[UUID] = None
|
||||
name: Optional[str] = None
|
||||
dynamips_id: Optional[int] = Field(None, description="Dynamips internal ID")
|
||||
platform: Optional[str] = Field(None, description="Cisco router platform", regex="^c[0-9]{4}$")
|
||||
platform: Optional[DynamipsPlatform] = Field(None, description="Cisco router platform")
|
||||
ram: Optional[int] = Field(None, description="Amount of RAM in MB")
|
||||
nvram: Optional[int] = Field(None, description="Amount of NVRAM in KB")
|
||||
image: Optional[Path] = Field(None, description="Path to the IOS image")
|
||||
@ -133,16 +148,16 @@ class DynamipsBase(BaseModel):
|
||||
aux_type: Optional[DynamipsConsoleType] = Field(None, description="Auxiliary console type")
|
||||
mac_addr: Optional[str] = Field(None, description="Base MAC address", regex="^([0-9a-fA-F]{4}\\.){2}[0-9a-fA-F]{4}$")
|
||||
system_id: Optional[str] = Field(None, description="System ID")
|
||||
slot0: Optional[str] = Field(None, description="Network module slot 0")
|
||||
slot1: Optional[str] = Field(None, description="Network module slot 1")
|
||||
slot2: Optional[str] = Field(None, description="Network module slot 2")
|
||||
slot3: Optional[str] = Field(None, description="Network module slot 3")
|
||||
slot4: Optional[str] = Field(None, description="Network module slot 4")
|
||||
slot5: Optional[str] = Field(None, description="Network module slot 5")
|
||||
slot6: Optional[str] = Field(None, description="Network module slot 6")
|
||||
wic0: Optional[str] = Field(None, description="Network module WIC slot 0")
|
||||
wic1: Optional[str] = Field(None, description="Network module WIC slot 1")
|
||||
wic2: Optional[str] = Field(None, description="Network module WIC slot 2")
|
||||
slot0: Optional[DynamipsAdapters] = Field(None, description="Network module slot 0")
|
||||
slot1: Optional[DynamipsAdapters] = Field(None, description="Network module slot 1")
|
||||
slot2: Optional[DynamipsAdapters] = Field(None, description="Network module slot 2")
|
||||
slot3: Optional[DynamipsAdapters] = Field(None, description="Network module slot 3")
|
||||
slot4: Optional[DynamipsAdapters] = Field(None, description="Network module slot 4")
|
||||
slot5: Optional[DynamipsAdapters] = Field(None, description="Network module slot 5")
|
||||
slot6: Optional[DynamipsAdapters] = Field(None, description="Network module slot 6")
|
||||
wic0: Optional[DynamipsWics] = Field(None, description="Network module WIC slot 0")
|
||||
wic1: Optional[DynamipsWics] = Field(None, description="Network module WIC slot 1")
|
||||
wic2: Optional[DynamipsWics] = Field(None, description="Network module WIC slot 2")
|
||||
npe: Optional[DynamipsNPE] = Field(None, description="NPE model")
|
||||
midplane: Optional[DynamipsMidplane] = Field(None, description="Midplane model")
|
||||
sensors: Optional[List] = Field(None, description="Temperature sensors")
|
@ -1,404 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import copy
|
||||
from .template import BASE_TEMPLATE_PROPERTIES
|
||||
from .dynamips_vm import DYNAMIPS_ADAPTERS, DYNAMIPS_WICS
|
||||
|
||||
|
||||
DYNAMIPS_TEMPLATE_PROPERTIES = {
|
||||
"platform": {
|
||||
"description": "Platform type",
|
||||
"enum": ["c7200", "c3745", "c3725", "c3600", "c2691", "c2600", "c1700"]
|
||||
},
|
||||
"image": {
|
||||
"description": "Path to the IOS image",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"mmap": {
|
||||
"description": "MMAP feature",
|
||||
"type": "boolean",
|
||||
"default": True
|
||||
},
|
||||
"exec_area": {
|
||||
"description": "Exec area value",
|
||||
"type": "integer",
|
||||
"default": 64
|
||||
},
|
||||
"mac_addr": {
|
||||
"description": "Base MAC address",
|
||||
"type": "string",
|
||||
"anyOf": [
|
||||
{"pattern": "^([0-9a-fA-F]{4}\\.){2}[0-9a-fA-F]{4}$"},
|
||||
{"pattern": "^$"}
|
||||
],
|
||||
"default": ""
|
||||
},
|
||||
"system_id": {
|
||||
"description": "System ID",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"default": "FTX0945W0MY"
|
||||
},
|
||||
"startup_config": {
|
||||
"description": "IOS startup configuration file",
|
||||
"type": "string",
|
||||
"default": "ios_base_startup-config.txt"
|
||||
},
|
||||
"private_config": {
|
||||
"description": "IOS private configuration file",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"idlepc": {
|
||||
"description": "Idle-PC value",
|
||||
"type": "string",
|
||||
"pattern": "^(0x[0-9a-fA-F]+)?$",
|
||||
"default": ""
|
||||
},
|
||||
"idlemax": {
|
||||
"description": "Idlemax value",
|
||||
"type": "integer",
|
||||
"default": 500
|
||||
},
|
||||
"idlesleep": {
|
||||
"description": "Idlesleep value",
|
||||
"type": "integer",
|
||||
"default": 30
|
||||
},
|
||||
"disk0": {
|
||||
"description": "Disk0 size in MB",
|
||||
"type": "integer",
|
||||
"default": 0
|
||||
},
|
||||
"disk1": {
|
||||
"description": "Disk1 size in MB",
|
||||
"type": "integer",
|
||||
"default": 0
|
||||
},
|
||||
"auto_delete_disks": {
|
||||
"description": "Automatically delete nvram and disk files",
|
||||
"type": "boolean",
|
||||
"default": False
|
||||
},
|
||||
"wic0": DYNAMIPS_WICS,
|
||||
"wic1": DYNAMIPS_WICS,
|
||||
"wic2": DYNAMIPS_WICS,
|
||||
"slot0": DYNAMIPS_ADAPTERS,
|
||||
"slot1": DYNAMIPS_ADAPTERS,
|
||||
"slot2": DYNAMIPS_ADAPTERS,
|
||||
"slot3": DYNAMIPS_ADAPTERS,
|
||||
"slot4": DYNAMIPS_ADAPTERS,
|
||||
"slot5": DYNAMIPS_ADAPTERS,
|
||||
"slot6": DYNAMIPS_ADAPTERS,
|
||||
"console_type": {
|
||||
"description": "Console type",
|
||||
"enum": ["telnet", "none"],
|
||||
"default": "telnet"
|
||||
},
|
||||
"console_auto_start": {
|
||||
"description": "Automatically start the console when the node has started",
|
||||
"type": "boolean",
|
||||
"default": False
|
||||
},
|
||||
"aux_type": {
|
||||
"description": "Auxiliary console type",
|
||||
"enum": ["telnet", "none"],
|
||||
"default": "none"
|
||||
}
|
||||
}
|
||||
|
||||
DYNAMIPS_TEMPLATE_PROPERTIES.update(copy.deepcopy(BASE_TEMPLATE_PROPERTIES))
|
||||
DYNAMIPS_TEMPLATE_PROPERTIES["category"]["default"] = "router"
|
||||
DYNAMIPS_TEMPLATE_PROPERTIES["default_name_format"]["default"] = "R{0}"
|
||||
DYNAMIPS_TEMPLATE_PROPERTIES["symbol"]["default"] = ":/symbols/router.svg"
|
||||
|
||||
DYNAMIPS_TEMPLATE_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "A Dynamips template object",
|
||||
"type": "object",
|
||||
"properties": DYNAMIPS_TEMPLATE_PROPERTIES,
|
||||
"required": ["platform", "image"],
|
||||
}
|
||||
|
||||
C7200_DYNAMIPS_TEMPLATE_PROPERTIES = {
|
||||
"ram": {
|
||||
"description": "Amount of RAM in MB",
|
||||
"type": "integer",
|
||||
"default": 512
|
||||
},
|
||||
"nvram": {
|
||||
"description": "Amount of NVRAM in KB",
|
||||
"type": "integer",
|
||||
"default": 512
|
||||
},
|
||||
"npe": {
|
||||
"description": "NPE model",
|
||||
"enum": ["npe-100", "npe-150", "npe-175", "npe-200", "npe-225", "npe-300", "npe-400", "npe-g2"],
|
||||
"default": "npe-400"
|
||||
},
|
||||
"midplane": {
|
||||
"description": "Midplane model",
|
||||
"enum": ["std", "vxr"],
|
||||
"default": "vxr"
|
||||
},
|
||||
"sparsemem": {
|
||||
"description": "Sparse memory feature",
|
||||
"type": "boolean",
|
||||
"default": True
|
||||
}
|
||||
}
|
||||
|
||||
C7200_DYNAMIPS_TEMPLATE_PROPERTIES.update(DYNAMIPS_TEMPLATE_PROPERTIES)
|
||||
|
||||
C7200_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "A c7200 Dynamips template object",
|
||||
"type": "object",
|
||||
"properties": C7200_DYNAMIPS_TEMPLATE_PROPERTIES,
|
||||
"additionalProperties": False
|
||||
}
|
||||
|
||||
C3745_DYNAMIPS_TEMPLATE_PROPERTIES = {
|
||||
"ram": {
|
||||
"description": "Amount of RAM in MB",
|
||||
"type": "integer",
|
||||
"default": 256
|
||||
},
|
||||
"nvram": {
|
||||
"description": "Amount of NVRAM in KB",
|
||||
"type": "integer",
|
||||
"default": 256
|
||||
},
|
||||
"iomem": {
|
||||
"description": "I/O memory percentage",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 100,
|
||||
"default": 5
|
||||
},
|
||||
"sparsemem": {
|
||||
"description": "Sparse memory feature",
|
||||
"type": "boolean",
|
||||
"default": True
|
||||
}
|
||||
}
|
||||
|
||||
C3745_DYNAMIPS_TEMPLATE_PROPERTIES.update(DYNAMIPS_TEMPLATE_PROPERTIES)
|
||||
|
||||
C3745_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "A c3745 Dynamips template object",
|
||||
"type": "object",
|
||||
"properties": C3745_DYNAMIPS_TEMPLATE_PROPERTIES,
|
||||
"additionalProperties": False
|
||||
}
|
||||
|
||||
C3725_DYNAMIPS_TEMPLATE_PROPERTIES = {
|
||||
"ram": {
|
||||
"description": "Amount of RAM in MB",
|
||||
"type": "integer",
|
||||
"default": 128
|
||||
},
|
||||
"nvram": {
|
||||
"description": "Amount of NVRAM in KB",
|
||||
"type": "integer",
|
||||
"default": 256
|
||||
},
|
||||
"iomem": {
|
||||
"description": "I/O memory percentage",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 100,
|
||||
"default": 5
|
||||
},
|
||||
"sparsemem": {
|
||||
"description": "Sparse memory feature",
|
||||
"type": "boolean",
|
||||
"default": True
|
||||
}
|
||||
}
|
||||
|
||||
C3725_DYNAMIPS_TEMPLATE_PROPERTIES.update(DYNAMIPS_TEMPLATE_PROPERTIES)
|
||||
|
||||
C3725_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "A c3725 Dynamips template object",
|
||||
"type": "object",
|
||||
"properties": C3725_DYNAMIPS_TEMPLATE_PROPERTIES,
|
||||
"additionalProperties": False
|
||||
}
|
||||
|
||||
C3600_DYNAMIPS_TEMPLATE_PROPERTIES = {
|
||||
"chassis": {
|
||||
"description": "Chassis type",
|
||||
"enum": ["3620", "3640", "3660"],
|
||||
"default": "3660"
|
||||
},
|
||||
"ram": {
|
||||
"description": "Amount of RAM in MB",
|
||||
"type": "integer",
|
||||
"default": 192
|
||||
},
|
||||
"nvram": {
|
||||
"description": "Amount of NVRAM in KB",
|
||||
"type": "integer",
|
||||
"default": 128
|
||||
},
|
||||
|
||||
"iomem": {
|
||||
"description": "I/O memory percentage",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 100,
|
||||
"default": 5
|
||||
},
|
||||
"sparsemem": {
|
||||
"description": "Sparse memory feature",
|
||||
"type": "boolean",
|
||||
"default": True
|
||||
}
|
||||
}
|
||||
|
||||
C3600_DYNAMIPS_TEMPLATE_PROPERTIES.update(DYNAMIPS_TEMPLATE_PROPERTIES)
|
||||
|
||||
C3600_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "A c3600 Dynamips template object",
|
||||
"type": "object",
|
||||
"properties": C3600_DYNAMIPS_TEMPLATE_PROPERTIES,
|
||||
"required": ["chassis"],
|
||||
"additionalProperties": False
|
||||
}
|
||||
|
||||
C2691_DYNAMIPS_TEMPLATE_PROPERTIES = {
|
||||
"ram": {
|
||||
"description": "Amount of RAM in MB",
|
||||
"type": "integer",
|
||||
"default": 192
|
||||
},
|
||||
"nvram": {
|
||||
"description": "Amount of NVRAM in KB",
|
||||
"type": "integer",
|
||||
"default": 256
|
||||
},
|
||||
"iomem": {
|
||||
"description": "I/O memory percentage",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 100,
|
||||
"default": 5
|
||||
},
|
||||
"sparsemem": {
|
||||
"description": "Sparse memory feature",
|
||||
"type": "boolean",
|
||||
"default": True
|
||||
}
|
||||
}
|
||||
|
||||
C2691_DYNAMIPS_TEMPLATE_PROPERTIES.update(DYNAMIPS_TEMPLATE_PROPERTIES)
|
||||
|
||||
C2691_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "A c2691 Dynamips template object",
|
||||
"type": "object",
|
||||
"properties": C2691_DYNAMIPS_TEMPLATE_PROPERTIES,
|
||||
"additionalProperties": False
|
||||
}
|
||||
|
||||
C2600_DYNAMIPS_TEMPLATE_PROPERTIES = {
|
||||
"chassis": {
|
||||
"description": "Chassis type",
|
||||
"enum": ["2610", "2620", "2610XM", "2620XM", "2650XM", "2621", "2611XM", "2621XM", "2651XM"],
|
||||
"default": "2651XM"
|
||||
},
|
||||
"ram": {
|
||||
"description": "Amount of RAM in MB",
|
||||
"type": "integer",
|
||||
"default": 160
|
||||
},
|
||||
"nvram": {
|
||||
"description": "Amount of NVRAM in KB",
|
||||
"type": "integer",
|
||||
"default": 128
|
||||
},
|
||||
"iomem": {
|
||||
"description": "I/O memory percentage",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 100,
|
||||
"default": 15
|
||||
},
|
||||
"sparsemem": {
|
||||
"description": "Sparse memory feature",
|
||||
"type": "boolean",
|
||||
"default": True
|
||||
}
|
||||
}
|
||||
|
||||
C2600_DYNAMIPS_TEMPLATE_PROPERTIES.update(DYNAMIPS_TEMPLATE_PROPERTIES)
|
||||
|
||||
C2600_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "A c2600 Dynamips template object",
|
||||
"type": "object",
|
||||
"properties": C2600_DYNAMIPS_TEMPLATE_PROPERTIES,
|
||||
"required": ["chassis"],
|
||||
"additionalProperties": False
|
||||
}
|
||||
|
||||
C1700_DYNAMIPS_TEMPLATE_PROPERTIES = {
|
||||
"chassis": {
|
||||
"description": "Chassis type",
|
||||
"enum": ["1720", "1721", "1750", "1751", "1760"],
|
||||
"default": "1760"
|
||||
},
|
||||
"ram": {
|
||||
"description": "Amount of RAM in MB",
|
||||
"type": "integer",
|
||||
"default": 160
|
||||
},
|
||||
"nvram": {
|
||||
"description": "Amount of NVRAM in KB",
|
||||
"type": "integer",
|
||||
"default": 128
|
||||
},
|
||||
"iomem": {
|
||||
"description": "I/O memory percentage",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 100,
|
||||
"default": 15
|
||||
},
|
||||
"sparsemem": {
|
||||
"description": "Sparse memory feature",
|
||||
"type": "boolean",
|
||||
"default": False
|
||||
}
|
||||
}
|
||||
|
||||
C1700_DYNAMIPS_TEMPLATE_PROPERTIES.update(DYNAMIPS_TEMPLATE_PROPERTIES)
|
||||
|
||||
C1700_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "A c1700 Dynamips template object",
|
||||
"type": "object",
|
||||
"properties": C1700_DYNAMIPS_TEMPLATE_PROPERTIES,
|
||||
"required": ["chassis"],
|
||||
"additionalProperties": False
|
||||
}
|
154
gns3server/schemas/dynamips_templates.py
Normal file
154
gns3server/schemas/dynamips_templates.py
Normal file
@ -0,0 +1,154 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2020 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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 .templates import Category, TemplateBase
|
||||
from .dynamips_nodes import (
|
||||
DynamipsConsoleType,
|
||||
DynamipsPlatform,
|
||||
DynamipsAdapters,
|
||||
DynamipsWics,
|
||||
DynamipsNPE,
|
||||
DynamipsMidplane
|
||||
)
|
||||
|
||||
from pydantic import Field
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class DynamipsTemplate(TemplateBase):
|
||||
|
||||
category: Optional[Category] = "router"
|
||||
default_name_format: Optional[str] = "R{0}"
|
||||
symbol: Optional[str] = ":/symbols/router.svg"
|
||||
platform: DynamipsPlatform = Field(..., description="Cisco router platform")
|
||||
image: Path = Field(..., description="Path to the IOS image")
|
||||
exec_area: Optional[int] = Field(64, description="Exec area value")
|
||||
mmap: Optional[bool] = Field(True, description="MMAP feature")
|
||||
mac_addr: Optional[str] = Field("", description="Base MAC address", regex="^([0-9a-fA-F]{4}\\.){2}[0-9a-fA-F]{4}$|^$")
|
||||
system_id: Optional[str] = Field("FTX0945W0MY", description="System ID")
|
||||
startup_config: Optional[str] = Field("ios_base_startup-config.txt", description="IOS startup configuration file")
|
||||
private_config: Optional[str] = Field("", description="IOS private configuration file")
|
||||
idlepc: Optional[str] = Field("", description="Idle-PC value", regex="^(0x[0-9a-fA-F]+)?$|^$")
|
||||
idlemax: Optional[int] = Field(500, description="Idlemax value")
|
||||
idlesleep: Optional[int] = Field(30, description="Idlesleep value")
|
||||
disk0: Optional[int] = Field(0, description="Disk0 size in MB")
|
||||
disk1: Optional[int] = Field(0, description="Disk1 size in MB")
|
||||
auto_delete_disks: Optional[bool] = Field(False, description="Automatically delete nvram and disk files")
|
||||
console_type: Optional[DynamipsConsoleType] = Field("telnet", description="Console type")
|
||||
console_auto_start: Optional[bool] = Field(False, description="Automatically start the console when the node has started")
|
||||
aux_type: Optional[DynamipsConsoleType] = Field("none", description="Auxiliary console type")
|
||||
slot0: Optional[DynamipsAdapters] = Field(None, description="Network module slot 0")
|
||||
slot1: Optional[DynamipsAdapters] = Field(None, description="Network module slot 1")
|
||||
slot2: Optional[DynamipsAdapters] = Field(None, description="Network module slot 2")
|
||||
slot3: Optional[DynamipsAdapters] = Field(None, description="Network module slot 3")
|
||||
slot4: Optional[DynamipsAdapters] = Field(None, description="Network module slot 4")
|
||||
slot5: Optional[DynamipsAdapters] = Field(None, description="Network module slot 5")
|
||||
slot6: Optional[DynamipsAdapters] = Field(None, description="Network module slot 6")
|
||||
wic0: Optional[DynamipsWics] = Field(None, description="Network module WIC slot 0")
|
||||
wic1: Optional[DynamipsWics] = Field(None, description="Network module WIC slot 1")
|
||||
wic2: Optional[DynamipsWics] = Field(None, description="Network module WIC slot 2")
|
||||
|
||||
|
||||
class C7200DynamipsTemplate(DynamipsTemplate):
|
||||
|
||||
ram: Optional[int] = Field(512, description="Amount of RAM in MB")
|
||||
nvram: Optional[int] = Field(512, description="Amount of NVRAM in KB")
|
||||
npe: Optional[DynamipsNPE] = Field("npe-400", description="NPE model")
|
||||
midplane: Optional[DynamipsMidplane] = Field("vxr", description="Midplane model")
|
||||
sparsemem: Optional[bool] = Field(True, description="Sparse memory feature")
|
||||
|
||||
|
||||
class C3725DynamipsTemplate(DynamipsTemplate):
|
||||
|
||||
ram: Optional[int] = Field(128, description="Amount of RAM in MB")
|
||||
nvram: Optional[int] = Field(256, description="Amount of NVRAM in KB")
|
||||
iomem: Optional[int] = Field(5, ge=0, le=100, description="I/O memory percentage")
|
||||
sparsemem: Optional[bool] = Field(True, description="Sparse memory feature")
|
||||
|
||||
|
||||
class C3745DynamipsTemplate(DynamipsTemplate):
|
||||
|
||||
ram: Optional[int] = Field(256, description="Amount of RAM in MB")
|
||||
nvram: Optional[int] = Field(256, description="Amount of NVRAM in KB")
|
||||
iomem: Optional[int] = Field(5, ge=0, le=100, description="I/O memory percentage")
|
||||
sparsemem: Optional[bool] = Field(True, description="Sparse memory feature")
|
||||
|
||||
|
||||
class C3600ChassisType(str, Enum):
|
||||
|
||||
chassis_3620 = "3620"
|
||||
chassis_3640 = "3640"
|
||||
chassis_3660 = "3660"
|
||||
|
||||
|
||||
class C3600DynamipsTemplate(DynamipsTemplate):
|
||||
|
||||
chassis: Optional[C3600ChassisType] = Field("c3660", description="Chassis type")
|
||||
ram: Optional[int] = Field(192, description="Amount of RAM in MB")
|
||||
nvram: Optional[int] = Field(128, description="Amount of NVRAM in KB")
|
||||
iomem: Optional[int] = Field(5, ge=0, le=100, description="I/O memory percentage")
|
||||
sparsemem: Optional[bool] = Field(True, description="Sparse memory feature")
|
||||
|
||||
|
||||
class C2691DynamipsTemplate(DynamipsTemplate):
|
||||
|
||||
ram: Optional[int] = Field(192, description="Amount of RAM in MB")
|
||||
nvram: Optional[int] = Field(256, description="Amount of NVRAM in KB")
|
||||
iomem: Optional[int] = Field(5, ge=0, le=100, description="I/O memory percentage")
|
||||
sparsemem: Optional[bool] = Field(True, description="Sparse memory feature")
|
||||
|
||||
|
||||
class C2600ChassisType(str, Enum):
|
||||
|
||||
chassis_2610 = "2610"
|
||||
chassis_2620 = "2620"
|
||||
chassis_2610xm = "2610XM"
|
||||
chassis_2620xm = "2620XM"
|
||||
chassis_2650xm = "2650XM"
|
||||
chassis_2621 = "2621"
|
||||
chassis_2611xm = "2611XM"
|
||||
chassis_2621xm = "2621XM"
|
||||
chassis_2651xm = "2651XM"
|
||||
|
||||
|
||||
class C2600DynamipsTemplate(DynamipsTemplate):
|
||||
|
||||
chassis: Optional[C2600ChassisType] = Field("2651XM", description="Chassis type")
|
||||
ram: Optional[int] = Field(160, description="Amount of RAM in MB")
|
||||
nvram: Optional[int] = Field(128, description="Amount of NVRAM in KB")
|
||||
iomem: Optional[int] = Field(15, ge=0, le=100, description="I/O memory percentage")
|
||||
sparsemem: Optional[bool] = Field(True, description="Sparse memory feature")
|
||||
|
||||
|
||||
class C1700ChassisType(str, Enum):
|
||||
|
||||
chassis_1720 = "1720"
|
||||
chassis_1721 = "1721"
|
||||
chassis_1750 = "1750"
|
||||
chassis_1751 = "1751"
|
||||
chassis_1760 = "1760"
|
||||
|
||||
|
||||
class C1700DynamipsTemplate(DynamipsTemplate):
|
||||
|
||||
chassis: Optional[C1700ChassisType] = Field("1760", description="Chassis type")
|
||||
ram: Optional[int] = Field(160, description="Amount of RAM in MB")
|
||||
nvram: Optional[int] = Field(128, description="Amount of NVRAM in KB")
|
||||
iomem: Optional[int] = Field(15, ge=0, le=100, description="I/O memory percentage")
|
||||
sparsemem: Optional[bool] = Field(False, description="Sparse memory feature")
|
@ -1,774 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2014 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
DYNAMIPS_ADAPTERS = {
|
||||
"description": "Dynamips Network Module",
|
||||
"enum": ["C7200-IO-2FE",
|
||||
"C7200-IO-FE",
|
||||
"C7200-IO-GE-E",
|
||||
"NM-16ESW",
|
||||
"NM-1E",
|
||||
"NM-1FE-TX",
|
||||
"NM-4E",
|
||||
"NM-4T",
|
||||
"PA-2FE-TX",
|
||||
"PA-4E",
|
||||
"PA-4T+",
|
||||
"PA-8E",
|
||||
"PA-8T",
|
||||
"PA-A1",
|
||||
"PA-FE-TX",
|
||||
"PA-GE",
|
||||
"PA-POS-OC3",
|
||||
"C2600-MB-2FE",
|
||||
"C2600-MB-1E",
|
||||
"C1700-MB-1FE",
|
||||
"C2600-MB-2E",
|
||||
"C2600-MB-1FE",
|
||||
"C1700-MB-WIC1",
|
||||
"GT96100-FE",
|
||||
"Leopard-2FE",
|
||||
""]
|
||||
}
|
||||
|
||||
DYNAMIPS_WICS = {
|
||||
"description": "Dynamips WIC",
|
||||
"enum": ["WIC-1ENET",
|
||||
"WIC-1T",
|
||||
"WIC-2T",
|
||||
""]
|
||||
}
|
||||
|
||||
#TODO: improve schema for Dynamips (match platform specific options, e.g. NPE allowd only for c7200)
|
||||
VM_CREATE_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Request validation to create a new Dynamips VM instance",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"node_id": {
|
||||
"description": "Node UUID",
|
||||
"oneOf": [
|
||||
{"type": "string",
|
||||
"minLength": 36,
|
||||
"maxLength": 36,
|
||||
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"},
|
||||
{"type": "integer"} # for legacy projects
|
||||
]
|
||||
},
|
||||
"dynamips_id": {
|
||||
"description": "Dynamips ID",
|
||||
"type": ["integer", "null"]
|
||||
},
|
||||
"name": {
|
||||
"description": "Dynamips VM instance name",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"usage": {
|
||||
"description": "How to use the Dynamips VM",
|
||||
"type": "string",
|
||||
},
|
||||
"platform": {
|
||||
"description": "Cisco router platform",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"pattern": "^c[0-9]{4}$"
|
||||
},
|
||||
"chassis": {
|
||||
"description": "Cisco router chassis model",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"pattern": "^[0-9]{4}(XM)?$"
|
||||
},
|
||||
"image": {
|
||||
"description": "Path to the IOS image",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"image_md5sum": {
|
||||
"description": "Checksum of the IOS image",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1,
|
||||
},
|
||||
"startup_config_content": {
|
||||
"description": "Content of IOS startup configuration file",
|
||||
"type": "string",
|
||||
},
|
||||
"private_config_content": {
|
||||
"description": "Content of IOS private configuration file",
|
||||
"type": "string",
|
||||
},
|
||||
"ram": {
|
||||
"description": "Amount of RAM in MB",
|
||||
"type": "integer"
|
||||
},
|
||||
"nvram": {
|
||||
"description": "Amount of NVRAM in KB",
|
||||
"type": "integer"
|
||||
},
|
||||
"mmap": {
|
||||
"description": "MMAP feature",
|
||||
"type": "boolean"
|
||||
},
|
||||
"sparsemem": {
|
||||
"description": "Sparse memory feature",
|
||||
"type": "boolean"
|
||||
},
|
||||
"clock_divisor": {
|
||||
"description": "Clock divisor",
|
||||
"type": "integer"
|
||||
},
|
||||
"idlepc": {
|
||||
"description": "Idle-PC value",
|
||||
"type": "string",
|
||||
"pattern": "^(0x[0-9a-fA-F]+)?$"
|
||||
},
|
||||
"idlemax": {
|
||||
"description": "Idlemax value",
|
||||
"type": "integer",
|
||||
},
|
||||
"idlesleep": {
|
||||
"description": "Idlesleep value",
|
||||
"type": "integer",
|
||||
},
|
||||
"exec_area": {
|
||||
"description": "Exec area value",
|
||||
"type": "integer",
|
||||
},
|
||||
"disk0": {
|
||||
"description": "Disk0 size in MB",
|
||||
"type": "integer"
|
||||
},
|
||||
"disk1": {
|
||||
"description": "Disk1 size in MB",
|
||||
"type": "integer"
|
||||
},
|
||||
"auto_delete_disks": {
|
||||
"description": "Automatically delete nvram and disk files",
|
||||
"type": "boolean"
|
||||
},
|
||||
"console": {
|
||||
"description": "Console TCP port",
|
||||
"type": ["integer", "null"],
|
||||
"minimum": 1,
|
||||
"maximum": 65535
|
||||
},
|
||||
"console_type": {
|
||||
"description": "Console type",
|
||||
"enum": ["telnet", "none"]
|
||||
},
|
||||
"aux": {
|
||||
"description": "Auxiliary console TCP port",
|
||||
"type": ["null", "integer"],
|
||||
"minimum": 1,
|
||||
"maximum": 65535
|
||||
},
|
||||
"aux_type": {
|
||||
"description": "Auxiliary console type",
|
||||
"enum": ["telnet", "none"]
|
||||
},
|
||||
"mac_addr": {
|
||||
"description": "Base MAC address",
|
||||
"type": ["null", "string"],
|
||||
"minLength": 1,
|
||||
"pattern": "^([0-9a-fA-F]{4}\\.){2}[0-9a-fA-F]{4}$"
|
||||
},
|
||||
"system_id": {
|
||||
"description": "System ID",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"slot0": {
|
||||
"description": "Network module slot 0",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"slot1": {
|
||||
"description": "Network module slot 1",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"slot2": {
|
||||
"description": "Network module slot 2",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"slot3": {
|
||||
"description": "Network module slot 3",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"slot4": {
|
||||
"description": "Network module slot 4",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"slot5": {
|
||||
"description": "Network module slot 5",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"slot6": {
|
||||
"description": "Network module slot 6",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"wic0": {
|
||||
"description": "Network module WIC slot 0",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"wic1": {
|
||||
"description": "Network module WIC slot 0",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"wic2": {
|
||||
"description": "Network module WIC slot 0",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
# C7200 properties
|
||||
"npe": {
|
||||
"description": "NPE model",
|
||||
"enum": ["npe-100",
|
||||
"npe-150",
|
||||
"npe-175",
|
||||
"npe-200",
|
||||
"npe-225",
|
||||
"npe-300",
|
||||
"npe-400",
|
||||
"npe-g2"]
|
||||
},
|
||||
"midplane": {
|
||||
"description": "Midplane model",
|
||||
"enum": ["std", "vxr"]
|
||||
},
|
||||
"sensors": {
|
||||
"description": "Temperature sensors",
|
||||
"type": "array"
|
||||
},
|
||||
"power_supplies": {
|
||||
"description": "Power supplies status",
|
||||
"type": "array"
|
||||
},
|
||||
# I/O memory property for all platforms but C7200
|
||||
"iomem": {
|
||||
"description": "I/O memory percentage",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 100
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"required": ["name", "platform", "image", "ram"]
|
||||
}
|
||||
|
||||
VM_UPDATE_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Request validation to update a Dynamips VM instance",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "Dynamips VM instance name",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"usage": {
|
||||
"description": "How to use the Dynamips VM",
|
||||
"type": "string",
|
||||
},
|
||||
"platform": {
|
||||
"description": "Cisco router platform",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"pattern": "^c[0-9]{4}$"
|
||||
},
|
||||
"chassis": {
|
||||
"description": "Cisco router chassis model",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"pattern": "^[0-9]{4}(XM)?$"
|
||||
},
|
||||
"image": {
|
||||
"description": "Path to the IOS image",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"image_md5sum": {
|
||||
"description": "Checksum of the IOS image",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1,
|
||||
},
|
||||
"dynamips_id": {
|
||||
"description": "Dynamips ID",
|
||||
"type": "integer"
|
||||
},
|
||||
"ram": {
|
||||
"description": "Amount of RAM in MB",
|
||||
"type": "integer"
|
||||
},
|
||||
"nvram": {
|
||||
"description": "Amount of NVRAM in KB",
|
||||
"type": "integer"
|
||||
},
|
||||
"mmap": {
|
||||
"description": "MMAP feature",
|
||||
"type": "boolean"
|
||||
},
|
||||
"sparsemem": {
|
||||
"description": "Sparse memory feature",
|
||||
"type": "boolean"
|
||||
},
|
||||
"clock_divisor": {
|
||||
"description": "Clock divisor",
|
||||
"type": "integer"
|
||||
},
|
||||
"idlepc": {
|
||||
"description": "Idle-PC value",
|
||||
"type": "string",
|
||||
"pattern": "^(0x[0-9a-fA-F]+)?$"
|
||||
},
|
||||
"idlemax": {
|
||||
"description": "Idlemax value",
|
||||
"type": "integer",
|
||||
},
|
||||
"idlesleep": {
|
||||
"description": "Idlesleep value",
|
||||
"type": "integer",
|
||||
},
|
||||
"exec_area": {
|
||||
"description": "Exec area value",
|
||||
"type": "integer",
|
||||
},
|
||||
"disk0": {
|
||||
"description": "Disk0 size in MB",
|
||||
"type": "integer"
|
||||
},
|
||||
"disk1": {
|
||||
"description": "Disk1 size in MB",
|
||||
"type": "integer"
|
||||
},
|
||||
"auto_delete_disks": {
|
||||
"description": "Automatically delete nvram and disk files",
|
||||
"type": "boolean"
|
||||
},
|
||||
"console": {
|
||||
"description": "Console TCP port",
|
||||
"type": ["integer", "null"],
|
||||
"minimum": 1,
|
||||
"maximum": 65535
|
||||
},
|
||||
"console_type": {
|
||||
"description": "Console type",
|
||||
"enum": ["telnet", "none"]
|
||||
},
|
||||
"aux": {
|
||||
"description": "Auxiliary console TCP port",
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 65535
|
||||
},
|
||||
"aux_type": {
|
||||
"description": "Auxiliary console type",
|
||||
"enum": ["telnet", "none"]
|
||||
},
|
||||
"mac_addr": {
|
||||
"description": "Base MAC address",
|
||||
"type": ["null", "string"],
|
||||
"minLength": 1,
|
||||
"pattern": "^([0-9a-fA-F]{4}\\.){2}[0-9a-fA-F]{4}$"
|
||||
},
|
||||
"system_id": {
|
||||
"description": "System ID",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"slot0": {
|
||||
"description": "Network module slot 0",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"slot1": {
|
||||
"description": "Network module slot 1",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"slot2": {
|
||||
"description": "Network module slot 2",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"slot3": {
|
||||
"description": "Network module slot 3",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"slot4": {
|
||||
"description": "Network module slot 4",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"slot5": {
|
||||
"description": "Network module slot 5",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"slot6": {
|
||||
"description": "Network module slot 6",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"wic0": {
|
||||
"description": "Network module WIC slot 0",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"wic1": {
|
||||
"description": "Network module WIC slot 0",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"wic2": {
|
||||
"description": "Network module WIC slot 0",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
# C7200 properties
|
||||
"npe": {
|
||||
"description": "NPE model",
|
||||
"enum": ["npe-100",
|
||||
"npe-150",
|
||||
"npe-175",
|
||||
"npe-200",
|
||||
"npe-225",
|
||||
"npe-300",
|
||||
"npe-400",
|
||||
"npe-g2"]
|
||||
},
|
||||
"midplane": {
|
||||
"description": "Midplane model",
|
||||
"enum": ["std", "vxr"]
|
||||
},
|
||||
"sensors": {
|
||||
"description": "Temperature sensors",
|
||||
"type": "array"
|
||||
},
|
||||
"power_supplies": {
|
||||
"description": "Power supplies status",
|
||||
"type": "array"
|
||||
},
|
||||
# I/O memory property for all platforms but C7200
|
||||
"iomem": {
|
||||
"description": "I/O memory percentage",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 100
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
|
||||
VM_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Dynamips VM instance",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"dynamips_id": {
|
||||
"description": "ID to use with Dynamips",
|
||||
"type": "integer"
|
||||
},
|
||||
"node_id": {
|
||||
"description": "Node UUID",
|
||||
"type": "string",
|
||||
"minLength": 36,
|
||||
"maxLength": 36,
|
||||
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
|
||||
},
|
||||
"node_directory": {
|
||||
"description": "Path to the vm working directory",
|
||||
"type": "string"
|
||||
},
|
||||
"project_id": {
|
||||
"description": "Project UUID",
|
||||
"type": "string",
|
||||
"minLength": 36,
|
||||
"maxLength": 36,
|
||||
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
|
||||
},
|
||||
"name": {
|
||||
"description": "Dynamips VM instance name",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"usage": {
|
||||
"description": "How to use the Dynamips VM",
|
||||
"type": "string",
|
||||
},
|
||||
"status": {
|
||||
"description": "VM status",
|
||||
"enum": ["started", "stopped", "suspended"]
|
||||
},
|
||||
"platform": {
|
||||
"description": "Cisco router platform",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"pattern": "^c[0-9]{4}$"
|
||||
},
|
||||
"chassis": {
|
||||
"description": "Cisco router chassis model",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"pattern": "^[0-9]{4}(XM)?$"
|
||||
},
|
||||
"image": {
|
||||
"description": "Path to the IOS image",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"image_md5sum": {
|
||||
"description": "Checksum of the IOS image",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1,
|
||||
},
|
||||
"ram": {
|
||||
"description": "Amount of RAM in MB",
|
||||
"type": "integer"
|
||||
},
|
||||
"nvram": {
|
||||
"description": "Amount of NVRAM in KB",
|
||||
"type": "integer"
|
||||
},
|
||||
"mmap": {
|
||||
"description": "MMAP feature",
|
||||
"type": "boolean"
|
||||
},
|
||||
"sparsemem": {
|
||||
"description": "Sparse memory feature",
|
||||
"type": "boolean"
|
||||
},
|
||||
"clock_divisor": {
|
||||
"description": "Clock divisor",
|
||||
"type": "integer"
|
||||
},
|
||||
"idlepc": {
|
||||
"description": "Idle-PC value",
|
||||
"type": "string",
|
||||
"pattern": "^(0x[0-9a-fA-F]+)?$"
|
||||
},
|
||||
"idlemax": {
|
||||
"description": "Idlemax value",
|
||||
"type": "integer",
|
||||
},
|
||||
"idlesleep": {
|
||||
"description": "Idlesleep value",
|
||||
"type": "integer",
|
||||
},
|
||||
"exec_area": {
|
||||
"description": "Exec area value",
|
||||
"type": "integer",
|
||||
},
|
||||
"disk0": {
|
||||
"description": "Disk0 size in MB",
|
||||
"type": "integer"
|
||||
},
|
||||
"disk1": {
|
||||
"description": "Disk1 size in MB",
|
||||
"type": "integer"
|
||||
},
|
||||
"auto_delete_disks": {
|
||||
"description": "Automatically delete nvram and disk files",
|
||||
"type": "boolean"
|
||||
},
|
||||
"console": {
|
||||
"description": "Console TCP port",
|
||||
"type": ["integer", "null"],
|
||||
"minimum": 1,
|
||||
"maximum": 65535
|
||||
},
|
||||
"console_type": {
|
||||
"description": "Console type",
|
||||
"enum": ["telnet", "none"]
|
||||
},
|
||||
"aux": {
|
||||
"description": "Auxiliary console TCP port",
|
||||
"type": ["integer", "null"],
|
||||
"minimum": 1,
|
||||
"maximum": 65535
|
||||
},
|
||||
"aux_type": {
|
||||
"description": "Auxiliary console type",
|
||||
"enum": ["telnet", "none"]
|
||||
},
|
||||
"mac_addr": {
|
||||
"description": "Base MAC address",
|
||||
"type": ["null", "string"]
|
||||
#"minLength": 1,
|
||||
#"pattern": "^([0-9a-fA-F]{4}\\.){2}[0-9a-fA-F]{4}$"
|
||||
},
|
||||
"system_id": {
|
||||
"description": "System ID",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"slot0": {
|
||||
"description": "Network module slot 0",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"slot1": {
|
||||
"description": "Network module slot 1",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"slot2": {
|
||||
"description": "Network module slot 2",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"slot3": {
|
||||
"description": "Network module slot 3",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"slot4": {
|
||||
"description": "Network module slot 4",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"slot5": {
|
||||
"description": "Network module slot 5",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"slot6": {
|
||||
"description": "Network module slot 6",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"wic0": {
|
||||
"description": "Network module WIC slot 0",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"wic1": {
|
||||
"description": "Network module WIC slot 0",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"wic2": {
|
||||
"description": "Network module WIC slot 0",
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
# C7200 properties
|
||||
"npe": {
|
||||
"description": "NPE model",
|
||||
"enum": ["npe-100",
|
||||
"npe-150",
|
||||
"npe-175",
|
||||
"npe-200",
|
||||
"npe-225",
|
||||
"npe-300",
|
||||
"npe-400",
|
||||
"npe-g2"]
|
||||
},
|
||||
"midplane": {
|
||||
"description": "Midplane model",
|
||||
"enum": ["std", "vxr"]
|
||||
},
|
||||
"sensors": {
|
||||
"description": "Temperature sensors",
|
||||
"type": "array"
|
||||
},
|
||||
"power_supplies": {
|
||||
"description": "Power supplies status",
|
||||
"type": "array"
|
||||
},
|
||||
# I/O memory property for all platforms but C7200
|
||||
"iomem": {
|
||||
"description": "I/O memory percentage",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 100
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"required": ["name", "node_id", "project_id", "dynamips_id", "console", "console_type"]
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import copy
|
||||
from .template import BASE_TEMPLATE_PROPERTIES
|
||||
|
||||
|
||||
ETHERNET_HUB_TEMPLATE_PROPERTIES = {
|
||||
"ports_mapping": {
|
||||
"type": "array",
|
||||
"default": [{"port_number": 0,
|
||||
"name": "Ethernet0"
|
||||
},
|
||||
{"port_number": 1,
|
||||
"name": "Ethernet1"
|
||||
},
|
||||
{"port_number": 2,
|
||||
"name": "Ethernet2"
|
||||
},
|
||||
{"port_number": 3,
|
||||
"name": "Ethernet3"
|
||||
},
|
||||
{"port_number": 4,
|
||||
"name": "Ethernet4"
|
||||
},
|
||||
{"port_number": 5,
|
||||
"name": "Ethernet5"
|
||||
},
|
||||
{"port_number": 6,
|
||||
"name": "Ethernet6"
|
||||
},
|
||||
{"port_number": 7,
|
||||
"name": "Ethernet7"
|
||||
}
|
||||
],
|
||||
"items": [
|
||||
{"type": "object",
|
||||
"oneOf": [{"description": "Ethernet port",
|
||||
"properties": {"name": {"description": "Port name",
|
||||
"type": "string",
|
||||
"minLength": 1},
|
||||
"port_number": {
|
||||
"description": "Port number",
|
||||
"type": "integer",
|
||||
"minimum": 0}
|
||||
},
|
||||
"required": ["name", "port_number"],
|
||||
"additionalProperties": False}
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
ETHERNET_HUB_TEMPLATE_PROPERTIES.update(copy.deepcopy(BASE_TEMPLATE_PROPERTIES))
|
||||
ETHERNET_HUB_TEMPLATE_PROPERTIES["category"]["default"] = "switch"
|
||||
ETHERNET_HUB_TEMPLATE_PROPERTIES["default_name_format"]["default"] = "Hub{0}"
|
||||
ETHERNET_HUB_TEMPLATE_PROPERTIES["symbol"]["default"] = ":/symbols/hub.svg"
|
||||
|
||||
ETHERNET_HUB_TEMPLATE_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "An Ethernet hub template object",
|
||||
"type": "object",
|
||||
"properties": ETHERNET_HUB_TEMPLATE_PROPERTIES,
|
||||
"additionalProperties": False
|
||||
}
|
43
gns3server/schemas/ethernet_hub_templates.py
Normal file
43
gns3server/schemas/ethernet_hub_templates.py
Normal file
@ -0,0 +1,43 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2020 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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 .templates import Category, TemplateBase
|
||||
from .ethernet_hub_nodes import EthernetHubPort
|
||||
|
||||
from pydantic import Field
|
||||
from typing import Optional, List
|
||||
|
||||
|
||||
DEFAULT_PORTS = [
|
||||
dict(port_number=0, name="Ethernet0"),
|
||||
dict(port_number=1, name="Ethernet1"),
|
||||
dict(port_number=2, name="Ethernet2"),
|
||||
dict(port_number=3, name="Ethernet3"),
|
||||
dict(port_number=4, name="Ethernet4"),
|
||||
dict(port_number=5, name="Ethernet5"),
|
||||
dict(port_number=6, name="Ethernet6"),
|
||||
dict(port_number=7, name="Ethernet7")
|
||||
]
|
||||
|
||||
|
||||
class EthernetHubTemplate(TemplateBase):
|
||||
|
||||
category: Optional[Category] = "switch"
|
||||
default_name_format: Optional[str] = "Hub{0}"
|
||||
symbol: Optional[str] = ":/symbols/hub.svg"
|
||||
ports_mapping: Optional[List[EthernetHubPort]] = Field(DEFAULT_PORTS, description="Ports")
|
@ -1,127 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import copy
|
||||
from .template import BASE_TEMPLATE_PROPERTIES
|
||||
|
||||
|
||||
ETHERNET_SWITCH_TEMPLATE_PROPERTIES = {
|
||||
"ports_mapping": {
|
||||
"type": "array",
|
||||
"default": [{"ethertype": "",
|
||||
"name": "Ethernet0",
|
||||
"vlan": 1,
|
||||
"type": "access",
|
||||
"port_number": 0
|
||||
},
|
||||
{"ethertype": "",
|
||||
"name": "Ethernet1",
|
||||
"vlan": 1,
|
||||
"type": "access",
|
||||
"port_number": 1
|
||||
},
|
||||
{"ethertype": "",
|
||||
"name": "Ethernet2",
|
||||
"vlan": 1,
|
||||
"type": "access",
|
||||
"port_number": 2
|
||||
},
|
||||
{"ethertype": "",
|
||||
"name": "Ethernet3",
|
||||
"vlan": 1,
|
||||
"type": "access",
|
||||
"port_number": 3
|
||||
},
|
||||
{"ethertype": "",
|
||||
"name": "Ethernet4",
|
||||
"vlan": 1,
|
||||
"type": "access",
|
||||
"port_number": 4
|
||||
},
|
||||
{"ethertype": "",
|
||||
"name": "Ethernet5",
|
||||
"vlan": 1,
|
||||
"type": "access",
|
||||
"port_number": 5
|
||||
},
|
||||
{"ethertype": "",
|
||||
"name": "Ethernet6",
|
||||
"vlan": 1,
|
||||
"type": "access",
|
||||
"port_number": 6
|
||||
},
|
||||
{"ethertype": "",
|
||||
"name": "Ethernet7",
|
||||
"vlan": 1,
|
||||
"type": "access",
|
||||
"port_number": 7
|
||||
}
|
||||
],
|
||||
"items": [
|
||||
{"type": "object",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Ethernet port",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "Port name",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"port_number": {
|
||||
"description": "Port number",
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"type": {
|
||||
"description": "Port type",
|
||||
"enum": ["access", "dot1q", "qinq"],
|
||||
},
|
||||
"vlan": {"description": "VLAN number",
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
"ethertype": {
|
||||
"description": "QinQ Ethertype",
|
||||
"enum": ["", "0x8100", "0x88A8", "0x9100", "0x9200"],
|
||||
},
|
||||
},
|
||||
"required": ["name", "port_number", "type"],
|
||||
"additionalProperties": False
|
||||
},
|
||||
]},
|
||||
]
|
||||
},
|
||||
"console_type": {
|
||||
"description": "Console type",
|
||||
"enum": ["telnet", "none"],
|
||||
"default": "none"
|
||||
},
|
||||
}
|
||||
|
||||
ETHERNET_SWITCH_TEMPLATE_PROPERTIES.update(copy.deepcopy(BASE_TEMPLATE_PROPERTIES))
|
||||
ETHERNET_SWITCH_TEMPLATE_PROPERTIES["category"]["default"] = "switch"
|
||||
ETHERNET_SWITCH_TEMPLATE_PROPERTIES["default_name_format"]["default"] = "Switch{0}"
|
||||
ETHERNET_SWITCH_TEMPLATE_PROPERTIES["symbol"]["default"] = ":/symbols/ethernet_switch.svg"
|
||||
|
||||
ETHERNET_SWITCH_TEMPLATE_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "An Ethernet switch template object",
|
||||
"type": "object",
|
||||
"properties": ETHERNET_SWITCH_TEMPLATE_PROPERTIES,
|
||||
"additionalProperties": False
|
||||
}
|
53
gns3server/schemas/ethernet_switch_templates.py
Normal file
53
gns3server/schemas/ethernet_switch_templates.py
Normal file
@ -0,0 +1,53 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2020 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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 .templates import Category, TemplateBase
|
||||
from .ethernet_switch_nodes import EthernetSwitchPort
|
||||
|
||||
from pydantic import Field
|
||||
from typing import Optional, List
|
||||
from enum import Enum
|
||||
|
||||
DEFAULT_PORTS = [
|
||||
dict(port_number=0, name="Ethernet0", vlan=1, type="access", ethertype=""),
|
||||
dict(port_number=1, name="Ethernet1", vlan=1, type="access", ethertype=""),
|
||||
dict(port_number=2, name="Ethernet2", vlan=1, type="access", ethertype=""),
|
||||
dict(port_number=3, name="Ethernet3", vlan=1, type="access", ethertype=""),
|
||||
dict(port_number=4, name="Ethernet4", vlan=1, type="access", ethertype=""),
|
||||
dict(port_number=5, name="Ethernet5", vlan=1, type="access", ethertype=""),
|
||||
dict(port_number=6, name="Ethernet6", vlan=1, type="access", ethertype=""),
|
||||
dict(port_number=7, name="Ethernet7", vlan=1, type="access", ethertype="")
|
||||
]
|
||||
|
||||
|
||||
class ConsoleType(str, Enum):
|
||||
"""
|
||||
Supported console types for Ethernet switch nodes.
|
||||
"""
|
||||
|
||||
none = "none"
|
||||
telnet = "telnet"
|
||||
|
||||
|
||||
class EthernetSwitchTemplate(TemplateBase):
|
||||
|
||||
category: Optional[Category] = "switch"
|
||||
default_name_format: Optional[str] = "Switch{0}"
|
||||
symbol: Optional[str] = ":/symbols/ethernet_switch.svg"
|
||||
ports_mapping: Optional[List[EthernetSwitchPort]] = Field(DEFAULT_PORTS, description="Ports")
|
||||
console_type: Optional[ConsoleType] = Field("none", description="Console type")
|
@ -1,23 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (C) 2017 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
FILTER_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Packet filter. This allow to simulate latency and errors",
|
||||
"type": "object"
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import copy
|
||||
from .template import BASE_TEMPLATE_PROPERTIES
|
||||
|
||||
|
||||
IOU_TEMPLATE_PROPERTIES = {
|
||||
"path": {
|
||||
"description": "Path of IOU executable",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"ethernet_adapters": {
|
||||
"description": "Number of ethernet adapters",
|
||||
"type": "integer",
|
||||
"default": 2
|
||||
},
|
||||
"serial_adapters": {
|
||||
"description": "Number of serial adapters",
|
||||
"type": "integer",
|
||||
"default": 2
|
||||
},
|
||||
"ram": {
|
||||
"description": "RAM in MB",
|
||||
"type": "integer",
|
||||
"default": 256
|
||||
},
|
||||
"nvram": {
|
||||
"description": "NVRAM in KB",
|
||||
"type": "integer",
|
||||
"default": 128
|
||||
},
|
||||
"use_default_iou_values": {
|
||||
"description": "Use default IOU values",
|
||||
"type": "boolean",
|
||||
"default": True
|
||||
},
|
||||
"startup_config": {
|
||||
"description": "Startup-config of IOU",
|
||||
"type": "string",
|
||||
"default": "iou_l3_base_startup-config.txt"
|
||||
},
|
||||
"private_config": {
|
||||
"description": "Private-config of IOU",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"l1_keepalives": {
|
||||
"description": "Always keep up Ethernet interface (does not always work)",
|
||||
"type": "boolean",
|
||||
"default": False
|
||||
},
|
||||
"console_type": {
|
||||
"description": "Console type",
|
||||
"enum": ["telnet", "none"],
|
||||
"default": "telnet"
|
||||
},
|
||||
"console_auto_start": {
|
||||
"description": "Automatically start the console when the node has started",
|
||||
"type": "boolean",
|
||||
"default": False
|
||||
},
|
||||
}
|
||||
|
||||
IOU_TEMPLATE_PROPERTIES.update(copy.deepcopy(BASE_TEMPLATE_PROPERTIES))
|
||||
IOU_TEMPLATE_PROPERTIES["category"]["default"] = "router"
|
||||
IOU_TEMPLATE_PROPERTIES["default_name_format"]["default"] = "IOU{0}"
|
||||
IOU_TEMPLATE_PROPERTIES["symbol"]["default"] = ":/symbols/multilayer_switch.svg"
|
||||
|
||||
IOU_TEMPLATE_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "A IOU template object",
|
||||
"type": "object",
|
||||
"properties": IOU_TEMPLATE_PROPERTIES,
|
||||
"required": ["path"],
|
||||
"additionalProperties": False
|
||||
}
|
@ -17,30 +17,18 @@
|
||||
|
||||
|
||||
from .templates import Category, TemplateBase
|
||||
from .iou_nodes import ConsoleType
|
||||
|
||||
from pydantic import Field
|
||||
from pathlib import Path
|
||||
from typing import Optional, Union
|
||||
from enum import Enum
|
||||
|
||||
from .nodes import NodeType
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class ConsoleType(str, Enum):
|
||||
"""
|
||||
Supported console types for IOU nodes
|
||||
"""
|
||||
|
||||
none = "none"
|
||||
telnet = "telnet"
|
||||
|
||||
|
||||
class IOUTemplateBase(TemplateBase):
|
||||
class IOUTemplate(TemplateBase):
|
||||
|
||||
category: Optional[Category] = "router"
|
||||
default_name_format: Optional[str] = "IOU{0}"
|
||||
symbol: Optional[str] = ":/symbols/multilayer_switch.svg"
|
||||
|
||||
path: Path = Field(..., description="Path of IOU executable")
|
||||
ethernet_adapters: Optional[int] = Field(2, description="Number of ethernet adapters")
|
||||
serial_adapters: Optional[int] = Field(2, description="Number of serial adapters")
|
||||
@ -53,25 +41,3 @@ class IOUTemplateBase(TemplateBase):
|
||||
console_type: Optional[ConsoleType] = Field("telnet", description="Console type")
|
||||
console_auto_start: Optional[bool] = Field(False, description="Automatically start the console when the node has started")
|
||||
|
||||
|
||||
class IOUTemplateCreate(IOUTemplateBase):
|
||||
|
||||
name: str
|
||||
template_type: NodeType
|
||||
compute_id: str
|
||||
|
||||
|
||||
class IOUTemplateUpdate(IOUTemplateBase):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class IOUTemplate(IOUTemplateBase):
|
||||
|
||||
template_id: str
|
||||
name: str
|
||||
category: Category
|
||||
symbol: str
|
||||
builtin: bool
|
||||
template_type: NodeType
|
||||
compute_id: Union[str, None]
|
@ -1,45 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
LABEL_OBJECT_SCHEMA = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": {"type": "string"},
|
||||
"style": {
|
||||
"description": "SVG style attribute. Apply default style if null",
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"x": {
|
||||
"description": "Relative X position of the label. Center it if null",
|
||||
"type": ["integer", "null"]
|
||||
},
|
||||
"y": {
|
||||
"description": "Relative Y position of the label",
|
||||
"type": "integer"
|
||||
},
|
||||
"rotation": {
|
||||
"description": "Rotation of the label",
|
||||
"type": "integer",
|
||||
"minimum": -359,
|
||||
"maximum": 360
|
||||
},
|
||||
},
|
||||
"required": [
|
||||
"text"
|
||||
],
|
||||
"additionalProperties": False
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (C) 2015 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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 .label import LABEL_OBJECT_SCHEMA
|
||||
from .filter import FILTER_OBJECT_SCHEMA
|
||||
|
||||
LINK_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "A link object",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"link_id": {
|
||||
"description": "Link UUID",
|
||||
"type": "string",
|
||||
"minLength": 36,
|
||||
"maxLength": 36,
|
||||
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
|
||||
},
|
||||
"project_id": {
|
||||
"description": "Project UUID",
|
||||
"type": "string",
|
||||
"minLength": 36,
|
||||
"maxLength": 36,
|
||||
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
|
||||
},
|
||||
"nodes": {
|
||||
"description": "List of the VMS",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"node_id": {
|
||||
"description": "Node UUID",
|
||||
"type": "string",
|
||||
"minLength": 36,
|
||||
"maxLength": 36,
|
||||
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
|
||||
},
|
||||
"adapter_number": {
|
||||
"description": "Adapter number",
|
||||
"type": "integer"
|
||||
},
|
||||
"port_number": {
|
||||
"description": "Port number",
|
||||
"type": "integer"
|
||||
},
|
||||
"label": LABEL_OBJECT_SCHEMA
|
||||
},
|
||||
"required": ["node_id", "adapter_number", "port_number"],
|
||||
"additionalProperties": False
|
||||
}
|
||||
},
|
||||
"suspend": {
|
||||
"type": "boolean",
|
||||
"description": "Suspend the link"
|
||||
},
|
||||
"filters": FILTER_OBJECT_SCHEMA,
|
||||
"capturing": {
|
||||
"description": "Read only property. True if a capture running on the link",
|
||||
"type": "boolean"
|
||||
},
|
||||
"capture_file_name": {
|
||||
"description": "Read only property. The name of the capture file if a capture is running",
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"capture_file_path": {
|
||||
"description": "Read only property. The full path of the capture file if a capture is running",
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"capture_compute_id": {
|
||||
"description": "Read only property. The compute identifier where a capture is running",
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"link_type": {
|
||||
"description": "Type of link",
|
||||
"enum": ["ethernet", "serial"]
|
||||
}
|
||||
},
|
||||
"additionalProperties": False
|
||||
}
|
||||
|
||||
|
||||
LINK_CAPTURE_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Request validation to start a packet capture on a link",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data_link_type": {
|
||||
"description": "PCAP data link type (http://www.tcpdump.org/linktypes.html)",
|
||||
"enum": ["DLT_ATM_RFC1483", "DLT_EN10MB", "DLT_FRELAY", "DLT_C_HDLC", "DLT_PPP_SERIAL"]
|
||||
},
|
||||
"capture_file_name": {
|
||||
"description": "Read only property. The name of the capture file if capture is running",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": False
|
||||
}
|
@ -1,192 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2015 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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 .filter import FILTER_OBJECT_SCHEMA
|
||||
|
||||
|
||||
NIO_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Request validation to add a NIO for a VM instance",
|
||||
"type": "object",
|
||||
"definitions": {
|
||||
"UDP": {
|
||||
"description": "UDP Network Input/Output",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": ["nio_udp"]
|
||||
},
|
||||
"lport": {
|
||||
"description": "Local port",
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 65535
|
||||
},
|
||||
"rhost": {
|
||||
"description": "Remote host",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"rport": {
|
||||
"description": "Remote port",
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 65535
|
||||
},
|
||||
"suspend": {
|
||||
"type": "boolean",
|
||||
"description": "Suspend the link"
|
||||
},
|
||||
"filters": FILTER_OBJECT_SCHEMA
|
||||
},
|
||||
"required": ["type", "lport", "rhost", "rport"],
|
||||
"additionalProperties": False
|
||||
},
|
||||
"Ethernet": {
|
||||
"description": "Generic Ethernet Network Input/Output",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": ["nio_generic_ethernet", "nio_ethernet"]
|
||||
},
|
||||
"ethernet_device": {
|
||||
"description": "Ethernet device name e.g. eth0",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
},
|
||||
"required": ["type", "ethernet_device"],
|
||||
"additionalProperties": False
|
||||
},
|
||||
"LinuxEthernet": {
|
||||
"description": "Linux Ethernet Network Input/Output",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": ["nio_linux_ethernet"]
|
||||
},
|
||||
"ethernet_device": {
|
||||
"description": "Ethernet device name e.g. eth0",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
},
|
||||
"required": ["type", "ethernet_device"],
|
||||
"additionalProperties": False
|
||||
},
|
||||
"NAT": {
|
||||
"description": "NAT Network Input/Output",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": ["nio_nat"]
|
||||
},
|
||||
},
|
||||
"required": ["type"],
|
||||
"additionalProperties": False
|
||||
},
|
||||
"TAP": {
|
||||
"description": "TAP Network Input/Output",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": ["nio_tap"]
|
||||
},
|
||||
"tap_device": {
|
||||
"description": "TAP device name e.g. tap0",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
},
|
||||
"required": ["type", "tap_device"],
|
||||
"additionalProperties": False
|
||||
},
|
||||
"UNIX": {
|
||||
"description": "UNIX Network Input/Output",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": ["nio_unix"]
|
||||
},
|
||||
"local_file": {
|
||||
"description": "path to the UNIX socket file (local)",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"remote_file": {
|
||||
"description": "path to the UNIX socket file (remote)",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
},
|
||||
"required": ["type", "local_file", "remote_file"],
|
||||
"additionalProperties": False
|
||||
},
|
||||
"VDE": {
|
||||
"description": "VDE Network Input/Output",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": ["nio_vde"]
|
||||
},
|
||||
"control_file": {
|
||||
"description": "path to the VDE control file",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"local_file": {
|
||||
"description": "path to the VDE control file",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
},
|
||||
"required": ["type", "control_file", "local_file"],
|
||||
"additionalProperties": False
|
||||
},
|
||||
"VMNET": {
|
||||
"description": "VMNET Network Input/Output",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": ["nio_vmnet"]
|
||||
},
|
||||
"vmnet": {
|
||||
"description": "VMnet interface name e.g. vmnet12",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
},
|
||||
"required": ["type", "vmnet"],
|
||||
"additionalProperties": False
|
||||
},
|
||||
"NULL": {
|
||||
"description": "NULL Network Input/Output",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": ["nio_null"]
|
||||
},
|
||||
},
|
||||
"required": ["type"],
|
||||
"additionalProperties": False
|
||||
},
|
||||
},
|
||||
"oneOf": [
|
||||
{"$ref": "#/definitions/UDP"},
|
||||
{"$ref": "#/definitions/Ethernet"},
|
||||
{"$ref": "#/definitions/LinuxEthernet"},
|
||||
{"$ref": "#/definitions/NAT"},
|
||||
{"$ref": "#/definitions/TAP"},
|
||||
{"$ref": "#/definitions/UNIX"},
|
||||
{"$ref": "#/definitions/VDE"},
|
||||
{"$ref": "#/definitions/VMNET"},
|
||||
{"$ref": "#/definitions/NULL"},
|
||||
],
|
||||
"additionalProperties": True,
|
||||
"required": ["type"]
|
||||
}
|
@ -1,301 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (C) 2015 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import copy
|
||||
from .label import LABEL_OBJECT_SCHEMA
|
||||
from .custom_adapters import CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||
|
||||
NODE_TYPE_SCHEMA = {
|
||||
"description": "Type of node",
|
||||
"enum": [
|
||||
"cloud",
|
||||
"nat",
|
||||
"ethernet_hub",
|
||||
"ethernet_switch",
|
||||
"frame_relay_switch",
|
||||
"atm_switch",
|
||||
"docker",
|
||||
"dynamips",
|
||||
"vpcs",
|
||||
"traceng",
|
||||
"virtualbox",
|
||||
"vmware",
|
||||
"iou",
|
||||
"qemu"
|
||||
]
|
||||
}
|
||||
|
||||
NODE_LIST_IMAGES_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "List of binary images",
|
||||
"type": "array",
|
||||
"items": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"filename": {
|
||||
"description": "Image filename",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"path": {
|
||||
"description": "Image path",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"md5sum": {
|
||||
"description": "md5sum of the image if available",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1
|
||||
},
|
||||
"filesize": {
|
||||
"description": "size of the image if available",
|
||||
"type": ["integer", "null"],
|
||||
"minimum": 0
|
||||
}
|
||||
},
|
||||
"required": ["filename", "path"],
|
||||
"additionalProperties": False
|
||||
}
|
||||
],
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
|
||||
NODE_CAPTURE_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Request validation to start a packet capture on a port",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"capture_file_name": {
|
||||
"description": "Capture file name",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"data_link_type": {
|
||||
"description": "PCAP data link type (http://www.tcpdump.org/linktypes.html)",
|
||||
"enum": ["DLT_ATM_RFC1483", "DLT_EN10MB", "DLT_FRELAY", "DLT_C_HDLC", "DLT_PPP_SERIAL"]
|
||||
}
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"required": ["capture_file_name"]
|
||||
}
|
||||
|
||||
|
||||
NODE_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "A node object",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"compute_id": {
|
||||
"description": "Compute identifier",
|
||||
"type": "string"
|
||||
},
|
||||
"project_id": {
|
||||
"description": "Project UUID",
|
||||
"type": "string",
|
||||
"minLength": 36,
|
||||
"maxLength": 36,
|
||||
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
|
||||
},
|
||||
"node_id": {
|
||||
"description": "Node UUID",
|
||||
"type": "string",
|
||||
"minLength": 36,
|
||||
"maxLength": 36,
|
||||
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
|
||||
},
|
||||
"template_id": {
|
||||
"description": "Template UUID from which the node has been created. Read only",
|
||||
"type": ["null", "string"],
|
||||
"minLength": 36,
|
||||
"maxLength": 36,
|
||||
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
|
||||
},
|
||||
"node_type": NODE_TYPE_SCHEMA,
|
||||
"node_directory": {
|
||||
"description": "Working directory of the node. Read only",
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"command_line": {
|
||||
"description": "Command line use to start the node",
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"name": {
|
||||
"description": "Node name",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"console": {
|
||||
"description": "Console TCP port",
|
||||
"minimum": 1,
|
||||
"maximum": 65535,
|
||||
"type": ["integer", "null"]
|
||||
},
|
||||
"console_host": {
|
||||
"description": "Console host. Warning if the host is 0.0.0.0 or :: (listen on all interfaces) you need to use the same address you use to connect to the controller.",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"console_type": {
|
||||
"description": "Console type",
|
||||
"enum": ["vnc", "telnet", "http", "https", "spice", "spice+agent", "none", None]
|
||||
},
|
||||
"console_auto_start": {
|
||||
"description": "Automatically start the console when the node has started",
|
||||
"type": "boolean"
|
||||
},
|
||||
"aux": {
|
||||
"description": "Auxiliary console TCP port",
|
||||
"minimum": 1,
|
||||
"maximum": 65535,
|
||||
"type": ["integer", "null"]
|
||||
},
|
||||
"aux_type": {
|
||||
"description": "Auxiliary console type",
|
||||
"enum": ["vnc", "telnet", "http", "https", "spice", "spice+agent", "none", None]
|
||||
},
|
||||
"properties": {
|
||||
"description": "Properties specific to an emulator",
|
||||
"type": "object"
|
||||
},
|
||||
"status": {
|
||||
"description": "Status of the node",
|
||||
"enum": ["stopped", "started", "suspended"]
|
||||
},
|
||||
"label": LABEL_OBJECT_SCHEMA,
|
||||
"symbol": {
|
||||
"description": "Symbol of the node",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1
|
||||
},
|
||||
"width": {
|
||||
"description": "Width of the node (Read only)",
|
||||
"type": "integer"
|
||||
},
|
||||
"height": {
|
||||
"description": "Height of the node (Read only)",
|
||||
"type": "integer"
|
||||
},
|
||||
"x": {
|
||||
"description": "X position of the node",
|
||||
"type": "integer"
|
||||
},
|
||||
"y": {
|
||||
"description": "Y position of the node",
|
||||
"type": "integer"
|
||||
},
|
||||
"z": {
|
||||
"description": "Z position of the node",
|
||||
"type": "integer"
|
||||
},
|
||||
"locked": {
|
||||
"description": "Whether the element locked or not",
|
||||
"type": "boolean"
|
||||
},
|
||||
"port_name_format": {
|
||||
"description": "Formating for port name {0} will be replace by port number",
|
||||
"type": "string"
|
||||
},
|
||||
"port_segment_size": {
|
||||
"description": "Size of the port segment",
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"first_port_name": {
|
||||
"description": "Name of the first port",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"custom_adapters": CUSTOM_ADAPTERS_ARRAY_SCHEMA,
|
||||
"ports": {
|
||||
"description": "List of node ports READ only",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "A node port",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Port name",
|
||||
},
|
||||
"short_name": {
|
||||
"type": "string",
|
||||
"description": "Short version of port name",
|
||||
},
|
||||
"adapter_number": {
|
||||
"type": "integer",
|
||||
"description": "Adapter slot"
|
||||
},
|
||||
"adapter_type": {
|
||||
"description": "Adapter type",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1,
|
||||
},
|
||||
"port_number": {
|
||||
"type": "integer",
|
||||
"description": "Port slot"
|
||||
},
|
||||
"link_type": {
|
||||
"description": "Type of link",
|
||||
"enum": ["ethernet", "serial"]
|
||||
},
|
||||
"data_link_types": {
|
||||
"type": "object",
|
||||
"description": "Available PCAP types for capture",
|
||||
"properties": {}
|
||||
},
|
||||
"mac_address": {
|
||||
"description": "MAC address (if available)",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1,
|
||||
"pattern": "^([0-9a-fA-F]{2}[:]){5}([0-9a-fA-F]{2})$"
|
||||
},
|
||||
},
|
||||
"additionalProperties": False
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"required": ["name", "node_type", "compute_id"]
|
||||
}
|
||||
|
||||
NODE_CREATE_SCHEMA = NODE_OBJECT_SCHEMA
|
||||
NODE_UPDATE_SCHEMA = copy.deepcopy(NODE_OBJECT_SCHEMA)
|
||||
del NODE_UPDATE_SCHEMA["required"]
|
||||
|
||||
|
||||
NODE_DUPLICATE_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Duplicate a node",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"x": {
|
||||
"description": "X position of the node",
|
||||
"type": "integer"
|
||||
},
|
||||
"y": {
|
||||
"description": "Y position of the node",
|
||||
"type": "integer"
|
||||
},
|
||||
"z": {
|
||||
"description": "Z position of the node",
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"required": ["x", "y"]
|
||||
}
|
@ -1,115 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
PORT_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "A port use in the cloud",
|
||||
"type": "object",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Ethernet interface port",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "Port name",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"port_number": {
|
||||
"description": "Port number",
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"type": {
|
||||
"description": "Port type",
|
||||
"enum": ["ethernet"]
|
||||
},
|
||||
"interface": {
|
||||
"description": "Ethernet interface name e.g. eth0",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
},
|
||||
"required": ["name", "port_number", "type", "interface"],
|
||||
"additionalProperties": False
|
||||
},
|
||||
{
|
||||
"description": "TAP interface port",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "Port name",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"port_number": {
|
||||
"description": "Port number",
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"type": {
|
||||
"description": "Port type",
|
||||
"enum": ["tap"]
|
||||
},
|
||||
"interface": {
|
||||
"description": "TAP interface name e.g. tap0",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
},
|
||||
"required": ["name", "port_number", "type", "interface"],
|
||||
"additionalProperties": False
|
||||
},
|
||||
{
|
||||
"description": "UDP tunnel port",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "Port name",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"port_number": {
|
||||
"description": "Port number",
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"type": {
|
||||
"description": "Port type",
|
||||
"enum": ["udp"]
|
||||
},
|
||||
"lport": {
|
||||
"description": "Local UDP tunnel port",
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 65535
|
||||
},
|
||||
"rhost": {
|
||||
"description": "Remote UDP tunnel host",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"rport": {
|
||||
"description": "Remote UDP tunnel port",
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 65535
|
||||
}
|
||||
},
|
||||
"required": ["name", "port_number", "type", "lport", "rhost", "rport"],
|
||||
"additionalProperties": False
|
||||
}
|
||||
]
|
||||
}
|
@ -1,329 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2015 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import copy
|
||||
|
||||
SUPPLIER_OBJECT_SCHEMA = {
|
||||
"type": ["object", "null"],
|
||||
"description": "Supplier of the project",
|
||||
"properties": {
|
||||
"logo": {
|
||||
"type": "string",
|
||||
"description": "Path to the project supplier logo"
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "URL to the project supplier site"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VARIABLES_OBJECT_SCHEMA = {
|
||||
"type": ["array", "null"],
|
||||
"description": "Variables required to run the project",
|
||||
"items": {
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Variable name",
|
||||
"minLength": 1
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "Variable value"
|
||||
}
|
||||
},
|
||||
"required": ["name"]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PROJECT_CREATE_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Request validation to create a new Project instance",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "Project name",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1
|
||||
},
|
||||
"path": {
|
||||
"description": "Project directory",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1
|
||||
},
|
||||
"auto_close": {
|
||||
"description": "Project auto close",
|
||||
"type": "boolean"
|
||||
},
|
||||
"project_id": {
|
||||
"description": "Project UUID",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 36,
|
||||
"maxLength": 36,
|
||||
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
|
||||
},
|
||||
"scene_height": {
|
||||
"type": "integer",
|
||||
"description": "Height of the drawing area"
|
||||
},
|
||||
"scene_width": {
|
||||
"type": "integer",
|
||||
"description": "Width of the drawing area"
|
||||
},
|
||||
"zoom": {
|
||||
"type": "integer",
|
||||
"description": "Zoom of the drawing area"
|
||||
},
|
||||
"show_layers": {
|
||||
"type": "boolean",
|
||||
"description": "Show layers on the drawing area"
|
||||
},
|
||||
"snap_to_grid": {
|
||||
"type": "boolean",
|
||||
"description": "Snap to grid on the drawing area"
|
||||
},
|
||||
"show_grid": {
|
||||
"type": "boolean",
|
||||
"description": "Show the grid on the drawing area"
|
||||
},
|
||||
"grid_size": {
|
||||
"type": "integer",
|
||||
"description": "Grid size for the drawing area for nodes"
|
||||
},
|
||||
"drawing_grid_size": {
|
||||
"type": "integer",
|
||||
"description": "Grid size for the drawing area for drawings"
|
||||
},
|
||||
"show_interface_labels": {
|
||||
"type": "boolean",
|
||||
"description": "Show interface labels on the drawing area"
|
||||
},
|
||||
"supplier": SUPPLIER_OBJECT_SCHEMA,
|
||||
"variables": VARIABLES_OBJECT_SCHEMA
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"required": ["name"]
|
||||
}
|
||||
|
||||
# Create a project duplicate schema based on create schema and add "reset_mac_addresses" properties
|
||||
PROJECT_DUPLICATE_SCHEMA = copy.deepcopy(PROJECT_CREATE_SCHEMA)
|
||||
PROJECT_DUPLICATE_SCHEMA["description"] = "Request validation to duplicate a Project instance"
|
||||
PROJECT_DUPLICATE_SCHEMA["properties"].update({"reset_mac_addresses": {"type": "boolean",
|
||||
"description": "Reset MAC addresses for this project"
|
||||
}})
|
||||
|
||||
PROJECT_UPDATE_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Request validation to update a Project instance",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "Project name",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1
|
||||
},
|
||||
"path": {
|
||||
"description": "Path of the project on the server (work only with --local)",
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"auto_close": {
|
||||
"description": "Project auto close when client cut off the notifications feed",
|
||||
"type": "boolean"
|
||||
},
|
||||
"auto_open": {
|
||||
"description": "Project open when GNS3 start",
|
||||
"type": "boolean"
|
||||
},
|
||||
"auto_start": {
|
||||
"description": "Project start when opened",
|
||||
"type": "boolean"
|
||||
},
|
||||
"scene_height": {
|
||||
"type": "integer",
|
||||
"description": "Height of the drawing area"
|
||||
},
|
||||
"scene_width": {
|
||||
"type": "integer",
|
||||
"description": "Width of the drawing area"
|
||||
},
|
||||
"zoom": {
|
||||
"type": "integer",
|
||||
"description": "Zoom of the drawing area"
|
||||
},
|
||||
"show_layers": {
|
||||
"type": "boolean",
|
||||
"description": "Show layers on the drawing area"
|
||||
},
|
||||
"snap_to_grid": {
|
||||
"type": "boolean",
|
||||
"description": "Snap to grid on the drawing area"
|
||||
},
|
||||
"show_grid": {
|
||||
"type": "boolean",
|
||||
"description": "Show the grid on the drawing area"
|
||||
},
|
||||
"grid_size": {
|
||||
"type": "integer",
|
||||
"description": "Grid size for the drawing area for nodes"
|
||||
},
|
||||
"drawing_grid_size": {
|
||||
"type": "integer",
|
||||
"description": "Grid size for the drawing area for drawings"
|
||||
},
|
||||
"show_interface_labels": {
|
||||
"type": "boolean",
|
||||
"description": "Show interface labels on the drawing area"
|
||||
},
|
||||
"supplier": SUPPLIER_OBJECT_SCHEMA,
|
||||
"variables": VARIABLES_OBJECT_SCHEMA
|
||||
},
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
PROJECT_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Project instance",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "Project name",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1
|
||||
},
|
||||
"project_id": {
|
||||
"description": "Project UUID",
|
||||
"type": "string",
|
||||
"minLength": 36,
|
||||
"maxLength": 36,
|
||||
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
|
||||
},
|
||||
"path": {
|
||||
"description": "Project directory",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1
|
||||
},
|
||||
"filename": {
|
||||
"description": "Project filename",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1
|
||||
},
|
||||
"status": {
|
||||
"description": "Project status Read only",
|
||||
"enum": ["opened", "closed"]
|
||||
},
|
||||
"auto_close": {
|
||||
"description": "Project auto close when client cut off the notifications feed",
|
||||
"type": "boolean"
|
||||
},
|
||||
"auto_open": {
|
||||
"description": "Project open when GNS3 start",
|
||||
"type": "boolean"
|
||||
},
|
||||
"auto_start": {
|
||||
"description": "Project start when opened",
|
||||
"type": "boolean"
|
||||
},
|
||||
"scene_height": {
|
||||
"type": "integer",
|
||||
"description": "Height of the drawing area"
|
||||
},
|
||||
"scene_width": {
|
||||
"type": "integer",
|
||||
"description": "Width of the drawing area"
|
||||
},
|
||||
"zoom": {
|
||||
"type": "integer",
|
||||
"description": "Zoom of the drawing area"
|
||||
},
|
||||
"show_layers": {
|
||||
"type": "boolean",
|
||||
"description": "Show layers on the drawing area"
|
||||
},
|
||||
"snap_to_grid": {
|
||||
"type": "boolean",
|
||||
"description": "Snap to grid on the drawing area"
|
||||
},
|
||||
"show_grid": {
|
||||
"type": "boolean",
|
||||
"description": "Show the grid on the drawing area"
|
||||
},
|
||||
"grid_size": {
|
||||
"type": "integer",
|
||||
"description": "Grid size for the drawing area for nodes"
|
||||
},
|
||||
"drawing_grid_size": {
|
||||
"type": "integer",
|
||||
"description": "Grid size for the drawing area for drawings"
|
||||
},
|
||||
"show_interface_labels": {
|
||||
"type": "boolean",
|
||||
"description": "Show interface labels on the drawing area"
|
||||
},
|
||||
"supplier": SUPPLIER_OBJECT_SCHEMA,
|
||||
"variables": VARIABLES_OBJECT_SCHEMA
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"required": ["project_id"]
|
||||
}
|
||||
|
||||
PROJECT_LOAD_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Load a project",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {
|
||||
"description": ".gns3 path",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"required": ["path"]
|
||||
}
|
||||
|
||||
PROJECT_LIST_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "List of projects",
|
||||
"type": "array",
|
||||
"items": PROJECT_OBJECT_SCHEMA
|
||||
}
|
||||
|
||||
PROJECT_FILE_LIST_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "List files in the project",
|
||||
"type": "array",
|
||||
"items": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {
|
||||
"description": "File path",
|
||||
"type": ["string"]
|
||||
},
|
||||
"md5sum": {
|
||||
"description": "MD5 hash of the file",
|
||||
"type": ["string"]
|
||||
},
|
||||
|
||||
},
|
||||
}
|
||||
],
|
||||
"additionalProperties": False,
|
||||
}
|
@ -35,7 +35,7 @@ class ProjectStatus(str, Enum):
|
||||
class Supplier(BaseModel):
|
||||
|
||||
logo: str = Field(..., description="Path to the project supplier logo")
|
||||
url: HttpUrl = Field(..., description="URL to the project supplier site")
|
||||
url: Optional[HttpUrl] = Field(None, description="URL to the project supplier site")
|
||||
|
||||
|
||||
class Variable(BaseModel):
|
@ -1,886 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2014 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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 .custom_adapters import CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||
|
||||
QEMU_PLATFORMS = ["aarch64", "alpha", "arm", "cris", "i386", "lm32", "m68k", "microblaze", "microblazeel", "mips", "mips64", "mips64el", "mipsel", "moxie", "or32", "ppc", "ppc64", "ppcemb", "s390x", "sh4", "sh4eb", "sparc", "sparc64", "tricore", "unicore32", "x86_64", "xtensa", "xtensaeb", ""]
|
||||
|
||||
|
||||
QEMU_CREATE_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Request validation to create a new QEMU VM instance",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"node_id": {
|
||||
"description": "Node UUID",
|
||||
"oneOf": [
|
||||
{"type": "string",
|
||||
"minLength": 36,
|
||||
"maxLength": 36,
|
||||
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"},
|
||||
{"type": "integer"} # for legacy projects
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"description": "QEMU VM instance name",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"usage": {
|
||||
"description": "How to use the Qemu VM",
|
||||
"type": "string",
|
||||
},
|
||||
"linked_clone": {
|
||||
"description": "Whether the VM is a linked clone or not",
|
||||
"type": "boolean"
|
||||
},
|
||||
"qemu_path": {
|
||||
"description": "Path to QEMU",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1,
|
||||
},
|
||||
"platform": {
|
||||
"description": "Platform to emulate",
|
||||
"enum": QEMU_PLATFORMS + ["null"]
|
||||
},
|
||||
"console": {
|
||||
"description": "Console TCP port",
|
||||
"minimum": 1,
|
||||
"maximum": 65535,
|
||||
"type": ["integer", "null"]
|
||||
},
|
||||
"console_type": {
|
||||
"description": "Console type",
|
||||
"enum": ["telnet", "vnc", "spice", "spice+agent", "none"]
|
||||
},
|
||||
"aux": {
|
||||
"description": "Auxiliary TCP port",
|
||||
"minimum": 1,
|
||||
"maximum": 65535,
|
||||
"type": ["integer", "null"]
|
||||
},
|
||||
"aux_type": {
|
||||
"description": "Auxiliary console type",
|
||||
"enum": ["telnet", "vnc", "spice", "spice+agent", "none"]
|
||||
},
|
||||
"hda_disk_image": {
|
||||
"description": "QEMU hda disk image path",
|
||||
"type": "string",
|
||||
},
|
||||
"hda_disk_interface": {
|
||||
"description": "QEMU hda interface",
|
||||
"type": "string",
|
||||
},
|
||||
"hda_disk_image_md5sum": {
|
||||
"description": "QEMU hda disk image checksum",
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"hdb_disk_image": {
|
||||
"description": "QEMU hdb disk image path",
|
||||
"type": "string",
|
||||
},
|
||||
"hdb_disk_interface": {
|
||||
"description": "QEMU hdb interface",
|
||||
"type": "string",
|
||||
},
|
||||
"hdb_disk_image_md5sum": {
|
||||
"description": "QEMU hdb disk image checksum",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"hdc_disk_image": {
|
||||
"description": "QEMU hdc disk image path",
|
||||
"type": "string",
|
||||
},
|
||||
"hdc_disk_interface": {
|
||||
"description": "QEMU hdc interface",
|
||||
"type": "string",
|
||||
},
|
||||
"hdc_disk_image_md5sum": {
|
||||
"description": "QEMU hdc disk image checksum",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"hdd_disk_image": {
|
||||
"description": "QEMU hdd disk image path",
|
||||
"type": "string",
|
||||
},
|
||||
"hdd_disk_interface": {
|
||||
"description": "QEMU hdd interface",
|
||||
"type": "string",
|
||||
},
|
||||
"hdd_disk_image_md5sum": {
|
||||
"description": "QEMU hdd disk image checksum",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"cdrom_image": {
|
||||
"description": "QEMU cdrom image path",
|
||||
"type": "string",
|
||||
},
|
||||
"cdrom_image_md5sum": {
|
||||
"description": "QEMU cdrom image checksum",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"bios_image": {
|
||||
"description": "QEMU bios image path",
|
||||
"type": "string",
|
||||
},
|
||||
"bios_image_md5sum": {
|
||||
"description": "QEMU bios image checksum",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"boot_priority": {
|
||||
"description": "QEMU boot priority",
|
||||
"enum": ["c", "d", "n", "cn", "cd", "dn", "dc", "nc", "nd"]
|
||||
},
|
||||
"ram": {
|
||||
"description": "Amount of RAM in MB",
|
||||
"type": ["integer", "null"]
|
||||
},
|
||||
"cpus": {
|
||||
"description": "Number of vCPUs",
|
||||
"type": ["integer", "null"],
|
||||
"minimum": 1,
|
||||
"maximum": 255,
|
||||
},
|
||||
"maxcpus": {
|
||||
"description": "Maximum number of hotpluggable vCPUs",
|
||||
"type": ["integer", "null"],
|
||||
"minimum": 1,
|
||||
"maximum": 255,
|
||||
},
|
||||
"adapters": {
|
||||
"description": "Number of adapters",
|
||||
"type": ["integer", "null"],
|
||||
"minimum": 0,
|
||||
"maximum": 275,
|
||||
},
|
||||
"adapter_type": {
|
||||
"description": "QEMU adapter type",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1,
|
||||
},
|
||||
"mac_address": {
|
||||
"description": "QEMU MAC address",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1,
|
||||
"pattern": "^([0-9a-fA-F]{2}[:]){5}([0-9a-fA-F]{2})$"
|
||||
},
|
||||
"initrd": {
|
||||
"description": "QEMU initrd path",
|
||||
"type": "string",
|
||||
},
|
||||
"initrd_md5sum": {
|
||||
"description": "QEMU initrd path",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"kernel_image": {
|
||||
"description": "QEMU kernel image path",
|
||||
"type": "string",
|
||||
},
|
||||
"kernel_image_md5sum": {
|
||||
"description": "QEMU kernel image checksum",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"kernel_command_line": {
|
||||
"description": "QEMU kernel command line",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"legacy_networking": {
|
||||
"description": "Use QEMU legagy networking commands (-net syntax)",
|
||||
"type": ["boolean", "null"],
|
||||
},
|
||||
"replicate_network_connection_state": {
|
||||
"description": "Replicate the network connection state for links in Qemu",
|
||||
"type": ["boolean", "null"],
|
||||
},
|
||||
"create_config_disk": {
|
||||
"description": "Automatically create a config disk on HDD disk interface (secondary slave)",
|
||||
"type": ["boolean", "null"],
|
||||
},
|
||||
"on_close": {
|
||||
"description": "Action to execute on the VM is closed",
|
||||
"enum": ["power_off", "shutdown_signal", "save_vm_state"],
|
||||
},
|
||||
"cpu_throttling": {
|
||||
"description": "Percentage of CPU allowed for QEMU",
|
||||
"minimum": 0,
|
||||
"maximum": 800,
|
||||
"type": ["integer", "null"],
|
||||
},
|
||||
"process_priority": {
|
||||
"description": "Process priority for QEMU",
|
||||
"enum": ["realtime",
|
||||
"very high",
|
||||
"high",
|
||||
"normal",
|
||||
"low",
|
||||
"very low",
|
||||
"null"]
|
||||
},
|
||||
"options": {
|
||||
"description": "Additional QEMU options",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"custom_adapters": CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"required": ["name"],
|
||||
}
|
||||
|
||||
QEMU_UPDATE_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Request validation to update a QEMU VM instance",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "QEMU VM instance name",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1,
|
||||
},
|
||||
"usage": {
|
||||
"description": "How to use the QEMU VM",
|
||||
"type": "string",
|
||||
},
|
||||
"qemu_path": {
|
||||
"description": "Path to QEMU",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1,
|
||||
},
|
||||
"platform": {
|
||||
"description": "Platform to emulate",
|
||||
"enum": QEMU_PLATFORMS + ["null"]
|
||||
},
|
||||
"console": {
|
||||
"description": "Console TCP port",
|
||||
"minimum": 1,
|
||||
"maximum": 65535,
|
||||
"type": ["integer", "null"]
|
||||
},
|
||||
"console_type": {
|
||||
"description": "Console type",
|
||||
"enum": ["telnet", "vnc", "spice", "spice+agent", "none"]
|
||||
},
|
||||
"aux": {
|
||||
"description": "Auxiliary TCP port",
|
||||
"minimum": 1,
|
||||
"maximum": 65535,
|
||||
"type": ["integer", "null"]
|
||||
},
|
||||
"aux_type": {
|
||||
"description": "Auxiliary console type",
|
||||
"enum": ["telnet", "vnc", "spice", "spice+agent", "none"]
|
||||
},
|
||||
"linked_clone": {
|
||||
"description": "Whether the VM is a linked clone or not",
|
||||
"type": "boolean"
|
||||
},
|
||||
"hda_disk_image": {
|
||||
"description": "QEMU hda disk image path",
|
||||
"type": "string",
|
||||
},
|
||||
"hda_disk_interface": {
|
||||
"description": "QEMU hda interface",
|
||||
"type": "string",
|
||||
},
|
||||
"hda_disk_image_md5sum": {
|
||||
"description": "QEMU hda disk image checksum",
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"hdb_disk_image": {
|
||||
"description": "QEMU hdb disk image path",
|
||||
"type": "string",
|
||||
},
|
||||
"hdb_disk_interface": {
|
||||
"description": "QEMU hdb interface",
|
||||
"type": "string",
|
||||
},
|
||||
"hdb_disk_image_md5sum": {
|
||||
"description": "QEMU hdb disk image checksum",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"hdc_disk_image": {
|
||||
"description": "QEMU hdc disk image path",
|
||||
"type": "string",
|
||||
},
|
||||
"hdc_disk_interface": {
|
||||
"description": "QEMU hdc interface",
|
||||
"type": "string",
|
||||
},
|
||||
"hdc_disk_image_md5sum": {
|
||||
"description": "QEMU hdc disk image checksum",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"hdd_disk_image": {
|
||||
"description": "QEMU hdd disk image path",
|
||||
"type": "string",
|
||||
},
|
||||
"hdd_disk_interface": {
|
||||
"description": "QEMU hdd interface",
|
||||
"type": "string",
|
||||
},
|
||||
"hdd_disk_image_md5sum": {
|
||||
"description": "QEMU hdd disk image checksum",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"bios_image": {
|
||||
"description": "QEMU bios image path",
|
||||
"type": "string",
|
||||
},
|
||||
"bios_image_md5sum": {
|
||||
"description": "QEMU bios image checksum",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"cdrom_image": {
|
||||
"description": "QEMU cdrom image path",
|
||||
"type": "string",
|
||||
},
|
||||
"cdrom_image_md5sum": {
|
||||
"description": "QEMU cdrom image checksum",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"boot_priority": {
|
||||
"description": "QEMU boot priority",
|
||||
"enum": ["c", "d", "n", "cn", "cd", "dn", "dc", "nc", "nd"]
|
||||
},
|
||||
"ram": {
|
||||
"description": "Amount of RAM in MB",
|
||||
"type": ["integer", "null"]
|
||||
},
|
||||
"cpus": {
|
||||
"description": "Number of vCPUs",
|
||||
"type": ["integer", "null"],
|
||||
"minimum": 1,
|
||||
"maximum": 255,
|
||||
},
|
||||
"maxcpus": {
|
||||
"description": "Maximum number of hotpluggable vCPUs",
|
||||
"type": ["integer", "null"],
|
||||
"minimum": 1,
|
||||
"maximum": 255,
|
||||
},
|
||||
"adapters": {
|
||||
"description": "Number of adapters",
|
||||
"type": ["integer", "null"],
|
||||
"minimum": 0,
|
||||
"maximum": 275,
|
||||
},
|
||||
"adapter_type": {
|
||||
"description": "QEMU adapter type",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1,
|
||||
},
|
||||
"mac_address": {
|
||||
"description": "QEMU MAC address",
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1,
|
||||
"pattern": "^([0-9a-fA-F]{2}[:]){5}([0-9a-fA-F]{2})$"
|
||||
},
|
||||
"initrd": {
|
||||
"description": "QEMU initrd path",
|
||||
"type": "string",
|
||||
},
|
||||
"initrd_md5sum": {
|
||||
"description": "QEMU initrd path",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"kernel_image": {
|
||||
"description": "QEMU kernel image path",
|
||||
"type": "string",
|
||||
},
|
||||
"kernel_image_md5sum": {
|
||||
"description": "QEMU kernel image checksum",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"kernel_command_line": {
|
||||
"description": "QEMU kernel command line",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"legacy_networking": {
|
||||
"description": "Use QEMU legagy networking commands (-net syntax)",
|
||||
"type": ["boolean", "null"],
|
||||
},
|
||||
"replicate_network_connection_state": {
|
||||
"description": "Replicate the network connection state for links in Qemu",
|
||||
"type": ["boolean", "null"],
|
||||
},
|
||||
"create_config_disk": {
|
||||
"description": "Automatically create a config disk on HDD disk interface (secondary slave)",
|
||||
"type": ["boolean", "null"],
|
||||
},
|
||||
"on_close": {
|
||||
"description": "Action to execute on the VM is closed",
|
||||
"enum": ["power_off", "shutdown_signal", "save_vm_state"],
|
||||
},
|
||||
"cpu_throttling": {
|
||||
"description": "Percentage of CPU allowed for QEMU",
|
||||
"minimum": 0,
|
||||
"maximum": 800,
|
||||
"type": ["integer", "null"],
|
||||
},
|
||||
"process_priority": {
|
||||
"description": "Process priority for QEMU",
|
||||
"enum": ["realtime",
|
||||
"very high",
|
||||
"high",
|
||||
"normal",
|
||||
"low",
|
||||
"very low",
|
||||
"null"]
|
||||
},
|
||||
"options": {
|
||||
"description": "Additional QEMU options",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"custom_adapters": CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||
},
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
QEMU_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Request validation for a QEMU VM instance",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"node_id": {
|
||||
"description": "Node UUID",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"project_id": {
|
||||
"description": "Project UUID",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"name": {
|
||||
"description": "QEMU VM instance name",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"status": {
|
||||
"description": "VM status",
|
||||
"enum": ["started", "stopped", "suspended"]
|
||||
},
|
||||
"usage": {
|
||||
"description": "How to use the QEMU VM",
|
||||
"type": "string",
|
||||
},
|
||||
"qemu_path": {
|
||||
"description": "Path to QEMU",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"platform": {
|
||||
"description": "Platform to emulate",
|
||||
"enum": QEMU_PLATFORMS
|
||||
},
|
||||
"hda_disk_image": {
|
||||
"description": "QEMU hda disk image path",
|
||||
"type": "string",
|
||||
},
|
||||
"hda_disk_interface": {
|
||||
"description": "QEMU hda interface",
|
||||
"type": "string",
|
||||
},
|
||||
"hda_disk_image_md5sum": {
|
||||
"description": "QEMU hda disk image checksum",
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"hdb_disk_image": {
|
||||
"description": "QEMU hdb disk image path",
|
||||
"type": "string",
|
||||
},
|
||||
"hdb_disk_interface": {
|
||||
"description": "QEMU hdb interface",
|
||||
"type": "string",
|
||||
},
|
||||
"hdb_disk_image_md5sum": {
|
||||
"description": "QEMU hdb disk image checksum",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"hdc_disk_image": {
|
||||
"description": "QEMU hdc disk image path",
|
||||
"type": "string",
|
||||
},
|
||||
"hdc_disk_interface": {
|
||||
"description": "QEMU hdc interface",
|
||||
"type": "string",
|
||||
},
|
||||
"hdc_disk_image_md5sum": {
|
||||
"description": "QEMU hdc disk image checksum",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"hdd_disk_image": {
|
||||
"description": "QEMU hdd disk image path",
|
||||
"type": "string",
|
||||
},
|
||||
"hdd_disk_interface": {
|
||||
"description": "QEMU hdd interface",
|
||||
"type": "string",
|
||||
},
|
||||
"hdd_disk_image_md5sum": {
|
||||
"description": "QEMU hdd disk image checksum",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"bios_image": {
|
||||
"description": "QEMU bios image path",
|
||||
"type": "string",
|
||||
},
|
||||
"bios_image_md5sum": {
|
||||
"description": "QEMU bios image checksum",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"cdrom_image": {
|
||||
"description": "QEMU cdrom image path",
|
||||
"type": "string",
|
||||
},
|
||||
"cdrom_image_md5sum": {
|
||||
"description": "QEMU cdrom image checksum",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"boot_priority": {
|
||||
"description": "QEMU boot priority",
|
||||
"enum": ["c", "d", "n", "cn", "cd", "dn", "dc", "nc", "nd"]
|
||||
},
|
||||
"node_directory": {
|
||||
"description": "Path to the VM working directory",
|
||||
"type": "string"
|
||||
},
|
||||
"ram": {
|
||||
"description": "Amount of RAM in MB",
|
||||
"type": "integer"
|
||||
},
|
||||
"cpus": {
|
||||
"description": "Number of vCPUs",
|
||||
"type": ["integer", "null"],
|
||||
"minimum": 1,
|
||||
"maximum": 255,
|
||||
},
|
||||
"maxcpus": {
|
||||
"description": "Maximum number of hotpluggable vCPUs",
|
||||
"type": ["integer", "null"],
|
||||
"minimum": 1,
|
||||
"maximum": 255,
|
||||
},
|
||||
"adapters": {
|
||||
"description": "Number of adapters",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 275,
|
||||
},
|
||||
"adapter_type": {
|
||||
"description": "QEMU adapter type",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"mac_address": {
|
||||
"description": "QEMU MAC address",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"pattern": "^([0-9a-fA-F]{2}[:]){5}([0-9a-fA-F]{2})$"
|
||||
},
|
||||
"console": {
|
||||
"description": "Console TCP port",
|
||||
"minimum": 1,
|
||||
"maximum": 65535,
|
||||
"type": ["integer", "null"]
|
||||
},
|
||||
"console_type": {
|
||||
"description": "Console type",
|
||||
"enum": ["telnet", "vnc", "spice","spice+agent", "none"]
|
||||
},
|
||||
"aux": {
|
||||
"description": "Auxiliary TCP port",
|
||||
"minimum": 1,
|
||||
"maximum": 65535,
|
||||
"type": ["integer", "null"]
|
||||
},
|
||||
"aux_type": {
|
||||
"description": "Auxiliary console type",
|
||||
"enum": ["telnet", "vnc", "spice", "spice+agent", "none"]
|
||||
},
|
||||
"initrd": {
|
||||
"description": "QEMU initrd path",
|
||||
"type": "string",
|
||||
},
|
||||
"initrd_md5sum": {
|
||||
"description": "QEMU initrd path",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"kernel_image": {
|
||||
"description": "QEMU kernel image path",
|
||||
"type": "string",
|
||||
},
|
||||
"kernel_image_md5sum": {
|
||||
"description": "QEMU kernel image checksum",
|
||||
"type": ["string", "null"],
|
||||
},
|
||||
"kernel_command_line": {
|
||||
"description": "QEMU kernel command line",
|
||||
"type": "string",
|
||||
},
|
||||
"legacy_networking": {
|
||||
"description": "Use QEMU legagy networking commands (-net syntax)",
|
||||
"type": "boolean",
|
||||
},
|
||||
"replicate_network_connection_state": {
|
||||
"description": "Replicate the network connection state for links in Qemu",
|
||||
"type": "boolean",
|
||||
},
|
||||
"create_config_disk": {
|
||||
"description": "Automatically create a config disk on HDD disk interface (secondary slave)",
|
||||
"type": ["boolean", "null"],
|
||||
},
|
||||
"on_close": {
|
||||
"description": "Action to execute on the VM is closed",
|
||||
"enum": ["power_off", "shutdown_signal", "save_vm_state"],
|
||||
},
|
||||
"save_vm_state": {
|
||||
"description": "Save VM state support",
|
||||
"type": ["boolean", "null"],
|
||||
},
|
||||
"cpu_throttling": {
|
||||
"description": "Percentage of CPU allowed for QEMU",
|
||||
"minimum": 0,
|
||||
"maximum": 800,
|
||||
"type": "integer",
|
||||
},
|
||||
"process_priority": {
|
||||
"description": "Process priority for QEMU",
|
||||
"enum": ["realtime",
|
||||
"very high",
|
||||
"high",
|
||||
"normal",
|
||||
"low",
|
||||
"very low"]
|
||||
},
|
||||
"options": {
|
||||
"description": "Additional QEMU options",
|
||||
"type": "string",
|
||||
},
|
||||
"command_line": {
|
||||
"description": "Last command line used by GNS3 to start QEMU",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"required": ["node_id",
|
||||
"project_id",
|
||||
"name",
|
||||
"usage",
|
||||
"qemu_path",
|
||||
"platform",
|
||||
"console_type",
|
||||
"aux_type",
|
||||
"hda_disk_image",
|
||||
"hdb_disk_image",
|
||||
"hdc_disk_image",
|
||||
"hdd_disk_image",
|
||||
"hda_disk_image_md5sum",
|
||||
"hdb_disk_image_md5sum",
|
||||
"hdc_disk_image_md5sum",
|
||||
"hdd_disk_image_md5sum",
|
||||
"hda_disk_interface",
|
||||
"hdb_disk_interface",
|
||||
"hdc_disk_interface",
|
||||
"hdd_disk_interface",
|
||||
"cdrom_image",
|
||||
"cdrom_image_md5sum",
|
||||
"bios_image",
|
||||
"bios_image_md5sum",
|
||||
"boot_priority",
|
||||
"ram",
|
||||
"cpus",
|
||||
"maxcpus",
|
||||
"adapters",
|
||||
"adapter_type",
|
||||
"mac_address",
|
||||
"console",
|
||||
"aux",
|
||||
"initrd",
|
||||
"kernel_image",
|
||||
"initrd_md5sum",
|
||||
"kernel_image_md5sum",
|
||||
"kernel_command_line",
|
||||
"legacy_networking",
|
||||
"replicate_network_connection_state",
|
||||
"create_config_disk",
|
||||
"on_close",
|
||||
"cpu_throttling",
|
||||
"process_priority",
|
||||
"options",
|
||||
"node_directory",
|
||||
"command_line",
|
||||
"status"]
|
||||
}
|
||||
|
||||
QEMU_RESIZE_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Resize a disk in a QEMU VM",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"drive_name": {
|
||||
"description": "Absolute or relative path of the image",
|
||||
"enum": ["hda", "hdb", "hdc", "hdd"]
|
||||
},
|
||||
"extend": {
|
||||
"description": "Number of Megabytes to extend the image",
|
||||
"type": "integer"
|
||||
},
|
||||
# TODO: support shrink? (could be dangerous)
|
||||
},
|
||||
"required": ["drive_name", "extend"],
|
||||
"additionalProperties": False
|
||||
}
|
||||
|
||||
QEMU_BINARY_FILTER_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Request validation for a list of QEMU capabilities",
|
||||
"properties": {
|
||||
"archs": {
|
||||
"description": "Architectures to filter binaries with",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"enum": QEMU_PLATFORMS
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
QEMU_BINARY_LIST_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Request validation for a list of QEMU binaries",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/QemuPath"
|
||||
},
|
||||
"definitions": {
|
||||
"QemuPath": {
|
||||
"description": "Qemu path object",
|
||||
"properties": {
|
||||
"path": {
|
||||
"description": "Qemu path",
|
||||
"type": "string",
|
||||
},
|
||||
"version": {
|
||||
"description": "Qemu version",
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
QEMU_CAPABILITY_LIST_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Request validation for a list of QEMU capabilities",
|
||||
"properties": {
|
||||
"kvm": {
|
||||
"description": "Architectures that KVM is enabled for",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"enum": QEMU_PLATFORMS
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
QEMU_IMAGE_CREATE_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Create a new QEMU image. Options can be specific to a format. Read qemu-img manual for more information",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"qemu_img": {
|
||||
"description": "Path to the qemu-img binary",
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"description": "Absolute or relative path of the image",
|
||||
"type": "string"
|
||||
},
|
||||
"format": {
|
||||
"description": "Image format type",
|
||||
"enum": ["qcow2", "qcow", "vpc", "vdi", "vmdk", "raw"]
|
||||
},
|
||||
"size": {
|
||||
"description": "Image size in Megabytes",
|
||||
"type": "integer"
|
||||
},
|
||||
"preallocation": {
|
||||
"enum": ["off", "metadata", "falloc", "full"]
|
||||
},
|
||||
"cluster_size": {
|
||||
"type": "integer"
|
||||
},
|
||||
"refcount_bits": {
|
||||
"type": "integer"
|
||||
},
|
||||
"lazy_refcounts": {
|
||||
"enum": ["on", "off"]
|
||||
},
|
||||
"subformat": {
|
||||
"enum": [
|
||||
"dynamic",
|
||||
"fixed",
|
||||
"streamOptimized",
|
||||
"twoGbMaxExtentSparse",
|
||||
"twoGbMaxExtentFlat",
|
||||
"monolithicSparse",
|
||||
"monolithicFlat",
|
||||
]
|
||||
},
|
||||
"static": {
|
||||
"enum": ["on", "off"]
|
||||
},
|
||||
"zeroed_grain": {
|
||||
"enum": ["on", "off"]
|
||||
},
|
||||
"adapter_type": {
|
||||
"enum": [
|
||||
"ide",
|
||||
"lsilogic",
|
||||
"buslogic",
|
||||
"legacyESX"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["qemu_img", "path", "format", "size"],
|
||||
"additionalProperties": False
|
||||
}
|
||||
|
||||
QEMU_IMAGE_UPDATE_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Update an existing QEMU image",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"qemu_img": {
|
||||
"description": "Path to the qemu-img binary",
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"description": "Absolute or relative path of the image",
|
||||
"type": "string"
|
||||
},
|
||||
"extend": {
|
||||
"description": "Number of Megabytes to extend the image",
|
||||
"type": "integer"
|
||||
},
|
||||
},
|
||||
"required": ["qemu_img", "path"],
|
||||
"additionalProperties": False
|
||||
}
|
@ -104,6 +104,54 @@ class QemuProcessPriority(str, Enum):
|
||||
very_low = "very low"
|
||||
|
||||
|
||||
class QemuAdapterType(str, Enum):
|
||||
"""
|
||||
Supported Qemu VM adapter types.
|
||||
"""
|
||||
|
||||
e1000 = "e1000"
|
||||
e1000_82544gc = "e1000-82544gc"
|
||||
e1000_82545em = "e1000-82545em"
|
||||
e1000e = "e1000e"
|
||||
i82550 = "i82550"
|
||||
i82551 = "i82551"
|
||||
i82557a = "i82557a"
|
||||
i82557b = "i82557b"
|
||||
i82557c = "i82557c"
|
||||
i82558a = "i82558a"
|
||||
i82558b = "i82558b"
|
||||
i82559a = "i82559a"
|
||||
i82559b = "i82559b"
|
||||
i82559c = "i82559c"
|
||||
i82559er = "i82559er"
|
||||
i82562 = "i82562"
|
||||
i82801 = "i82801"
|
||||
ne2k_pci = "ne2k_pci"
|
||||
pcnet = "pcnet"
|
||||
rocker = "rocker"
|
||||
rtl8139 = "rtl8139"
|
||||
virtio = "virtio"
|
||||
virtio_net_pci = "virtio-net-pci"
|
||||
vmxnet3 = "vmxnet3"
|
||||
|
||||
|
||||
class QemuDiskInterfaceType(str, Enum):
|
||||
"""
|
||||
Supported Qemu VM disk interface types.
|
||||
"""
|
||||
|
||||
ide = "ide"
|
||||
sate = "sata"
|
||||
nvme = "nvme"
|
||||
scsi = "scsi"
|
||||
sd = "sd"
|
||||
mtd = "mtd"
|
||||
floppy = "floppy"
|
||||
pflash = "pflash"
|
||||
virtio = "virtio"
|
||||
none = "none"
|
||||
|
||||
|
||||
class QemuBase(BaseModel):
|
||||
"""
|
||||
Common Qemu node properties.
|
||||
@ -121,16 +169,16 @@ class QemuBase(BaseModel):
|
||||
aux_type: Optional[QemuConsoleType] = Field(None, description="Auxiliary console type")
|
||||
hda_disk_image: Optional[Path] = Field(None, description="QEMU hda disk image path")
|
||||
hda_disk_image_md5sum: Optional[str] = Field(None, description="QEMU hda disk image checksum")
|
||||
hda_disk_image_interface: Optional[str] = Field(None, description="QEMU hda interface")
|
||||
hda_disk_interface: Optional[QemuDiskInterfaceType] = Field(None, description="QEMU hda interface")
|
||||
hdb_disk_image: Optional[Path] = Field(None, description="QEMU hdb disk image path")
|
||||
hdb_disk_image_md5sum: Optional[str] = Field(None, description="QEMU hdb disk image checksum")
|
||||
hdb_disk_image_interface: Optional[str] = Field(None, description="QEMU hdb interface")
|
||||
hdb_disk_interface: Optional[QemuDiskInterfaceType] = Field(None, description="QEMU hdb interface")
|
||||
hdc_disk_image: Optional[Path] = Field(None, description="QEMU hdc disk image path")
|
||||
hdc_disk_image_md5sum: Optional[str] = Field(None, description="QEMU hdc disk image checksum")
|
||||
hdc_disk_image_interface: Optional[str] = Field(None, description="QEMU hdc interface")
|
||||
hdc_disk_interface: Optional[QemuDiskInterfaceType] = Field(None, description="QEMU hdc interface")
|
||||
hdd_disk_image: Optional[Path] = Field(None, description="QEMU hdd disk image path")
|
||||
hdd_disk_image_md5sum: Optional[str] = Field(None, description="QEMU hdd disk image checksum")
|
||||
hdd_disk_image_interface: Optional[str] = Field(None, description="QEMU hdd interface")
|
||||
hdd_disk_interface: Optional[QemuDiskInterfaceType] = Field(None, description="QEMU hdd interface")
|
||||
cdrom_image: Optional[Path] = Field(None, description="QEMU cdrom image path")
|
||||
cdrom_image_md5sum: Optional[str] = Field(None, description="QEMU cdrom image checksum")
|
||||
bios_image: Optional[Path] = Field(None, description="QEMU bios image path")
|
||||
@ -140,12 +188,12 @@ class QemuBase(BaseModel):
|
||||
kernel_image: Optional[Path] = Field(None, description="QEMU kernel image path")
|
||||
kernel_image_md5sum: Optional[str] = Field(None, description="QEMU kernel image checksum")
|
||||
kernel_command_line: Optional[str] = Field(None, description="QEMU kernel command line")
|
||||
boot_priotiry: Optional[QemuBootPriority] = Field(None, description="QEMU boot priority")
|
||||
boot_priority: Optional[QemuBootPriority] = Field(None, description="QEMU boot priority")
|
||||
ram: Optional[int] = Field(None, description="Amount of RAM in MB")
|
||||
cpus: Optional[int] = Field(None, ge=1, le=255, description="Number of vCPUs")
|
||||
maxcpus: Optional[int] = Field(None, ge=1, le=255, description="Maximum number of hotpluggable vCPUs")
|
||||
adapters: Optional[int] = Field(None, ge=0, le=275, description="Number of adapters")
|
||||
adapter_type: Optional[str] = Field(None, description="QEMU adapter type")
|
||||
adapter_type: Optional[QemuAdapterType] = Field(None, description="QEMU adapter type")
|
||||
mac_address: Optional[str] = Field(None, description="QEMU MAC address", regex="^([0-9a-fA-F]{2}[:]){5}([0-9a-fA-F]{2})$")
|
||||
legacy_networking: Optional[bool] = Field(None, description="Use QEMU legagy networking commands (-net syntax)")
|
||||
replicate_network_connection_state: Optional[bool] = Field(None, description="Replicate the network connection state for links in Qemu")
|
@ -1,234 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import copy
|
||||
from .template import BASE_TEMPLATE_PROPERTIES
|
||||
from .custom_adapters import CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||
from .qemu import QEMU_PLATFORMS
|
||||
|
||||
|
||||
QEMU_TEMPLATE_PROPERTIES = {
|
||||
"qemu_path": {
|
||||
"description": "Path to QEMU",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"platform": {
|
||||
"description": "Platform to emulate",
|
||||
"enum": QEMU_PLATFORMS,
|
||||
"default": "i386"
|
||||
},
|
||||
"linked_clone": {
|
||||
"description": "Whether the VM is a linked clone or not",
|
||||
"type": "boolean",
|
||||
"default": True
|
||||
},
|
||||
"ram": {
|
||||
"description": "Amount of RAM in MB",
|
||||
"type": "integer",
|
||||
"default": 256
|
||||
},
|
||||
"cpus": {
|
||||
"description": "Number of vCPUs",
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 255,
|
||||
"default": 1
|
||||
},
|
||||
"maxcpus": {
|
||||
"description": "Maximum number of hotpluggable vCPUs",
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 255,
|
||||
"default": 1
|
||||
},
|
||||
"adapters": {
|
||||
"description": "Number of adapters",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 275,
|
||||
"default": 1
|
||||
},
|
||||
"adapter_type": {
|
||||
"description": "QEMU adapter type",
|
||||
"type": "string",
|
||||
"enum": ["e1000", "e1000-82544gc", "e1000-82545em", "e1000e", "i82550", "i82551", "i82557a", "i82557b", "i82557c", "i82558a",
|
||||
"i82558b", "i82559a", "i82559b", "i82559c", "i82559er", "i82562", "i82801", "ne2k_pci", "pcnet", "rocker", "rtl8139",
|
||||
"virtio", "virtio-net-pci", "vmxnet3"],
|
||||
"default": "e1000"
|
||||
},
|
||||
"mac_address": {
|
||||
"description": "QEMU MAC address",
|
||||
"type": ["string", "null"],
|
||||
"anyOf": [
|
||||
{"pattern": "^([0-9a-fA-F]{2}[:]){5}([0-9a-fA-F]{2})$"},
|
||||
{"pattern": "^$"}
|
||||
],
|
||||
"default": "",
|
||||
},
|
||||
"first_port_name": {
|
||||
"description": "Optional name of the first networking port example: eth0",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"port_name_format": {
|
||||
"description": "Optional formatting of the networking port example: eth{0}",
|
||||
"type": "string",
|
||||
"default": "Ethernet{0}"
|
||||
},
|
||||
"port_segment_size": {
|
||||
"description": "Optional port segment size. A port segment is a block of port. For example Ethernet0/0 Ethernet0/1 is the module 0 with a port segment size of 2",
|
||||
"type": "integer",
|
||||
"default": 0
|
||||
},
|
||||
"console_type": {
|
||||
"description": "Console type",
|
||||
"enum": ["telnet", "vnc", "spice", "spice+agent", "none"],
|
||||
"default": "telnet"
|
||||
},
|
||||
"console_auto_start": {
|
||||
"description": "Automatically start the console when the node has started",
|
||||
"type": "boolean",
|
||||
"default": False
|
||||
},
|
||||
"aux_type": {
|
||||
"description": "Auxiliary console type",
|
||||
"enum": ["telnet", "vnc", "spice", "spice+agent", "none"],
|
||||
"default": "none"
|
||||
},
|
||||
"boot_priority": {
|
||||
"description": "QEMU boot priority",
|
||||
"enum": ["c", "d", "n", "cn", "cd", "dn", "dc", "nc", "nd"],
|
||||
"default": "c"
|
||||
},
|
||||
"hda_disk_image": {
|
||||
"description": "QEMU hda disk image path",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"hda_disk_interface": {
|
||||
"description": "QEMU hda interface",
|
||||
"enum": ["ide", "sata", "nvme", "scsi", "sd", "mtd", "floppy", "pflash", "virtio", "none"],
|
||||
"default": "none"
|
||||
},
|
||||
"hdb_disk_image": {
|
||||
"description": "QEMU hdb disk image path",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"hdb_disk_interface": {
|
||||
"description": "QEMU hdb interface",
|
||||
"enum": ["ide", "sata", "nvme", "scsi", "sd", "mtd", "floppy", "pflash", "virtio", "none"],
|
||||
"default": "none"
|
||||
},
|
||||
"hdc_disk_image": {
|
||||
"description": "QEMU hdc disk image path",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"hdc_disk_interface": {
|
||||
"description": "QEMU hdc interface",
|
||||
"enum": ["ide", "sata", "nvme", "scsi", "sd", "mtd", "floppy", "pflash", "virtio", "none"],
|
||||
"default": "none"
|
||||
},
|
||||
"hdd_disk_image": {
|
||||
"description": "QEMU hdd disk image path",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"hdd_disk_interface": {
|
||||
"description": "QEMU hdd interface",
|
||||
"enum": ["ide", "sata", "nvme", "scsi", "sd", "mtd", "floppy", "pflash", "virtio", "none"],
|
||||
"default": "none"
|
||||
},
|
||||
"cdrom_image": {
|
||||
"description": "QEMU cdrom image path",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"initrd": {
|
||||
"description": "QEMU initrd path",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"kernel_image": {
|
||||
"description": "QEMU kernel image path",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"bios_image": {
|
||||
"description": "QEMU bios image path",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"kernel_command_line": {
|
||||
"description": "QEMU kernel command line",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"legacy_networking": {
|
||||
"description": "Use QEMU legagy networking commands (-net syntax)",
|
||||
"type": "boolean",
|
||||
"default": False
|
||||
},
|
||||
"replicate_network_connection_state": {
|
||||
"description": "Replicate the network connection state for links in Qemu",
|
||||
"type": "boolean",
|
||||
"default": True
|
||||
},
|
||||
"create_config_disk": {
|
||||
"description": "Automatically create a config disk on HDD disk interface (secondary slave)",
|
||||
"type": "boolean",
|
||||
"default": False
|
||||
},
|
||||
"on_close": {
|
||||
"description": "Action to execute on the VM is closed",
|
||||
"enum": ["power_off", "shutdown_signal", "save_vm_state"],
|
||||
"default": "power_off"
|
||||
},
|
||||
"cpu_throttling": {
|
||||
"description": "Percentage of CPU allowed for QEMU",
|
||||
"minimum": 0,
|
||||
"maximum": 800,
|
||||
"type": "integer",
|
||||
"default": 0
|
||||
},
|
||||
"process_priority": {
|
||||
"description": "Process priority for QEMU",
|
||||
"enum": ["realtime", "very high", "high", "normal", "low", "very low"],
|
||||
"default": "normal"
|
||||
},
|
||||
"options": {
|
||||
"description": "Additional QEMU options",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"custom_adapters": CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||
}
|
||||
|
||||
QEMU_TEMPLATE_PROPERTIES.update(copy.deepcopy(BASE_TEMPLATE_PROPERTIES))
|
||||
QEMU_TEMPLATE_PROPERTIES["category"]["default"] = "guest"
|
||||
QEMU_TEMPLATE_PROPERTIES["default_name_format"]["default"] = "{name}-{0}"
|
||||
QEMU_TEMPLATE_PROPERTIES["symbol"]["default"] = ":/symbols/qemu_guest.svg"
|
||||
|
||||
QEMU_TEMPLATE_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "A Qemu template object",
|
||||
"type": "object",
|
||||
"properties": QEMU_TEMPLATE_PROPERTIES,
|
||||
"additionalProperties": False
|
||||
}
|
77
gns3server/schemas/qemu_templates.py
Normal file
77
gns3server/schemas/qemu_templates.py
Normal file
@ -0,0 +1,77 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2020 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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 .templates import Category, TemplateBase
|
||||
from .qemu_nodes import (
|
||||
QemuConsoleType,
|
||||
QemuPlatform,
|
||||
QemuAdapterType,
|
||||
QemuOnCloseAction,
|
||||
QemuBootPriority,
|
||||
QemuDiskInterfaceType,
|
||||
QemuProcessPriority,
|
||||
CustomAdapter
|
||||
)
|
||||
|
||||
from pathlib import Path
|
||||
from pydantic import Field
|
||||
from typing import Optional, List
|
||||
|
||||
|
||||
class QemuTemplate(TemplateBase):
|
||||
|
||||
category: Optional[Category] = "guest"
|
||||
default_name_format: Optional[str] = "{name}-{0}"
|
||||
symbol: Optional[str] = ":/symbols/qemu_guest.svg"
|
||||
qemu_path: Optional[Path] = Field("", description="Qemu executable path")
|
||||
platform: Optional[QemuPlatform] = Field("i386", description="Platform to emulate")
|
||||
linked_clone: Optional[bool] = Field(True, description="Whether the VM is a linked clone or not")
|
||||
ram: Optional[int] = Field(256, description="Amount of RAM in MB")
|
||||
cpus: Optional[int] = Field(1, ge=1, le=255, description="Number of vCPUs")
|
||||
maxcpus: Optional[int] = Field(1, ge=1, le=255, description="Maximum number of hotpluggable vCPUs")
|
||||
adapters: Optional[int] = Field(1, ge=0, le=275, description="Number of adapters")
|
||||
adapter_type: Optional[QemuAdapterType] = Field("e1000", description="QEMU adapter type")
|
||||
mac_address: Optional[str] = Field("", description="QEMU MAC address", regex="^([0-9a-fA-F]{2}[:]){5}([0-9a-fA-F]{2})$|^$")
|
||||
first_port_name: Optional[str] = Field("", description="Optional name of the first networking port example: eth0")
|
||||
port_name_format: Optional[str] = Field("Ethernet{0}", description="Optional formatting of the networking port example: eth{0}")
|
||||
port_segment_size: Optional[int] = Field(0, description="Optional port segment size. A port segment is a block of port. For example Ethernet0/0 Ethernet0/1 is the module 0 with a port segment size of 2")
|
||||
console_type: Optional[QemuConsoleType] = Field("telnet", description="Console type")
|
||||
console_auto_start: Optional[bool] = Field(False, description="Automatically start the console when the node has started")
|
||||
aux_type: Optional[QemuConsoleType] = Field("none", description="Auxiliary console type")
|
||||
boot_priority: Optional[QemuBootPriority] = Field("c", description="QEMU boot priority")
|
||||
hda_disk_image: Optional[Path] = Field("", description="QEMU hda disk image path")
|
||||
hda_disk_interface: Optional[QemuDiskInterfaceType] = Field("none", description="QEMU hda interface")
|
||||
hdb_disk_image: Optional[Path] = Field("", description="QEMU hdb disk image path")
|
||||
hdb_disk_interface: Optional[QemuDiskInterfaceType] = Field("none", description="QEMU hdb interface")
|
||||
hdc_disk_image: Optional[Path] = Field("", description="QEMU hdc disk image path")
|
||||
hdc_disk_interface: Optional[QemuDiskInterfaceType] = Field("none", description="QEMU hdc interface")
|
||||
hdd_disk_image: Optional[Path] = Field("", description="QEMU hdd disk image path")
|
||||
hdd_disk_interface: Optional[QemuDiskInterfaceType] = Field("none", description="QEMU hdd interface")
|
||||
cdrom_image: Optional[Path] = Field("", description="QEMU cdrom image path")
|
||||
initrd: Optional[Path] = Field("", description="QEMU initrd path")
|
||||
kernel_image: Optional[Path] = Field("", description="QEMU kernel image path")
|
||||
bios_image: Optional[Path] = Field("", description="QEMU bios image path")
|
||||
kernel_command_line: Optional[str] = Field("", description="QEMU kernel command line")
|
||||
legacy_networking: Optional[bool] = Field(False, description="Use QEMU legagy networking commands (-net syntax)")
|
||||
replicate_network_connection_state: Optional[bool] = Field(True, description="Replicate the network connection state for links in Qemu")
|
||||
create_config_disk: Optional[bool] = Field(False, description="Automatically create a config disk on HDD disk interface (secondary slave)")
|
||||
on_close: Optional[QemuOnCloseAction] = Field("power_off", description="Action to execute on the VM is closed")
|
||||
cpu_throttling: Optional[int] = Field(0, ge=0, le=800, description="Percentage of CPU allowed for QEMU")
|
||||
process_priority: Optional[QemuProcessPriority] = Field("normal", description="Process priority for QEMU")
|
||||
options: Optional[str] = Field("", description="Additional QEMU options")
|
||||
custom_adapters: Optional[List[CustomAdapter]] = Field([], description="Custom adapters")
|
@ -1,82 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2015 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
SERVER_STATISTICS_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"type": "object",
|
||||
"required": ["memory_total",
|
||||
"memory_free",
|
||||
"memory_used",
|
||||
"swap_total",
|
||||
"swap_free",
|
||||
"swap_used",
|
||||
"cpu_usage_percent",
|
||||
"memory_usage_percent",
|
||||
"swap_usage_percent",
|
||||
"disk_usage_percent",
|
||||
"load_average_percent"],
|
||||
"additionalProperties": False,
|
||||
"properties": {
|
||||
"memory_total": {
|
||||
"description": "Total physical memory (exclusive swap) in bytes",
|
||||
"type": "integer",
|
||||
},
|
||||
"memory_free": {
|
||||
"description": "Free memory in bytes",
|
||||
"type": "integer",
|
||||
},
|
||||
"memory_used": {
|
||||
"description": "Memory used in bytes",
|
||||
"type": "integer",
|
||||
},
|
||||
"swap_total": {
|
||||
"description": "Total swap memory in bytes",
|
||||
"type": "integer",
|
||||
},
|
||||
"swap_free": {
|
||||
"description": "Free swap memory in bytes",
|
||||
"type": "integer",
|
||||
},
|
||||
"swap_used": {
|
||||
"description": "Swap memory used in bytes",
|
||||
"type": "integer",
|
||||
},
|
||||
"cpu_usage_percent": {
|
||||
"description": "CPU usage in percent",
|
||||
"type": "integer",
|
||||
},
|
||||
"memory_usage_percent": {
|
||||
"description": "Memory usage in percent",
|
||||
"type": "integer",
|
||||
},
|
||||
"swap_usage_percent": {
|
||||
"description": "Swap usage in percent",
|
||||
"type": "integer",
|
||||
},
|
||||
"disk_usage_percent": {
|
||||
"description": "Disk usage in percent",
|
||||
"type": "integer",
|
||||
},
|
||||
"load_average_percent": {
|
||||
"description": "Average system load over the last 1, 5 and 15 minutes",
|
||||
"type": "array",
|
||||
"items": [{"type": "integer"}],
|
||||
"minItems": 3,
|
||||
"maxItems": 3
|
||||
},
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2015 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
SNAPSHOT_CREATE_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Request validation to create a new snapshot",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "Snapshot name",
|
||||
"minLength": 1
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"required": ["name"]
|
||||
}
|
||||
|
||||
SNAPSHOT_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Request validation to update a Project instance",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"snapshot_id": {
|
||||
"description": "Snapshot UUID",
|
||||
"type": "string",
|
||||
"minLength": 36,
|
||||
"maxLength": 36,
|
||||
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
|
||||
},
|
||||
"project_id": {
|
||||
"description": "Project UUID",
|
||||
"type": "string",
|
||||
"minLength": 36,
|
||||
"maxLength": 36,
|
||||
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
|
||||
},
|
||||
"name": {
|
||||
"description": "Project name",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"created_at": {
|
||||
"description": "Date of the snapshot (UTC timestamp)",
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"required": ["snapshot_id", "name", "created_at", "project_id"]
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2015 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import copy
|
||||
|
||||
BASE_TEMPLATE_PROPERTIES = {
|
||||
"template_id": {
|
||||
"description": "Template UUID",
|
||||
"type": "string",
|
||||
"minLength": 36,
|
||||
"maxLength": 36,
|
||||
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
|
||||
},
|
||||
"template_type": {
|
||||
"description": "Type of node",
|
||||
"enum": ["cloud", "ethernet_hub", "ethernet_switch", "docker", "dynamips", "vpcs", "traceng",
|
||||
"virtualbox", "vmware", "iou", "qemu"]
|
||||
},
|
||||
"name": {
|
||||
"description": "Template name",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"usage": {
|
||||
"description": "How to use this template",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"compute_id": {
|
||||
"description": "Compute identifier",
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"default_name_format": {
|
||||
"description": "Default name format",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"symbol": {
|
||||
"description": "Symbol of the template",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"category": {
|
||||
"description": "Template category",
|
||||
"anyOf": [
|
||||
{"type": "integer"}, # old category support
|
||||
{"enum": ["router", "switch", "guest", "firewall"]}
|
||||
]
|
||||
},
|
||||
"builtin": {
|
||||
"description": "Template is builtin",
|
||||
"type": "boolean"
|
||||
},
|
||||
}
|
||||
|
||||
TEMPLATE_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "A template object",
|
||||
"type": "object",
|
||||
"properties": BASE_TEMPLATE_PROPERTIES,
|
||||
"required": ["name", "template_type", "template_id", "category", "compute_id", "default_name_format", "symbol", "builtin"]
|
||||
}
|
||||
|
||||
TEMPLATE_CREATE_SCHEMA = copy.deepcopy(TEMPLATE_OBJECT_SCHEMA)
|
||||
|
||||
# create schema
|
||||
# these properties are not required to create a template
|
||||
TEMPLATE_CREATE_SCHEMA["required"].remove("template_id")
|
||||
TEMPLATE_CREATE_SCHEMA["required"].remove("category")
|
||||
TEMPLATE_CREATE_SCHEMA["required"].remove("default_name_format")
|
||||
TEMPLATE_CREATE_SCHEMA["required"].remove("symbol")
|
||||
TEMPLATE_CREATE_SCHEMA["required"].remove("builtin")
|
||||
|
||||
# update schema
|
||||
TEMPLATE_UPDATE_SCHEMA = copy.deepcopy(TEMPLATE_OBJECT_SCHEMA)
|
||||
del TEMPLATE_UPDATE_SCHEMA["required"]
|
||||
|
||||
TEMPLATE_USAGE_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Request validation to use a Template instance",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"x": {
|
||||
"description": "X position",
|
||||
"type": "integer"
|
||||
},
|
||||
"y": {
|
||||
"description": "Y position",
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"description": "Use this name to create a new node",
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"compute_id": {
|
||||
"description": "If the template don't have a default compute use this compute",
|
||||
"type": ["null", "string"]
|
||||
}
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"required": ["x", "y"]
|
||||
}
|
@ -45,8 +45,8 @@ class TemplateBase(BaseModel):
|
||||
symbol: Optional[str] = None
|
||||
builtin: Optional[bool] = None
|
||||
template_type: Optional[NodeType] = None
|
||||
usage: Optional[str] = None
|
||||
compute_id: Optional[str] = None
|
||||
usage: Optional[str] = ""
|
||||
|
||||
class Config:
|
||||
extra = "allow"
|
@ -19,136 +19,66 @@
|
||||
# This file contains the validation for checking a .gns3 file
|
||||
#
|
||||
|
||||
from gns3server.schemas.compute import COMPUTE_OBJECT_SCHEMA
|
||||
from gns3server.schemas.drawing import DRAWING_OBJECT_SCHEMA
|
||||
from gns3server.schemas.link import LINK_OBJECT_SCHEMA
|
||||
from gns3server.schemas.node import NODE_OBJECT_SCHEMA
|
||||
from gns3server.schemas.project import VARIABLES_OBJECT_SCHEMA
|
||||
from gns3server.schemas.project import SUPPLIER_OBJECT_SCHEMA
|
||||
from .computes import Compute
|
||||
from .drawings import Drawing
|
||||
from .links import Link
|
||||
from .nodes import Node
|
||||
|
||||
from .projects import (
|
||||
Supplier,
|
||||
Variable
|
||||
)
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional, List
|
||||
from enum import Enum
|
||||
from uuid import UUID
|
||||
|
||||
|
||||
TOPOLOGY_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "The topology",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"project_id": {
|
||||
"description": "Project UUID",
|
||||
"type": "string",
|
||||
"minLength": 36,
|
||||
"maxLength": 36,
|
||||
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
|
||||
},
|
||||
"type": {
|
||||
"description": "Type of file. It's always topology",
|
||||
"enum": ["topology"]
|
||||
},
|
||||
"auto_start": {
|
||||
"description": "Start the topology when opened",
|
||||
"type": "boolean"
|
||||
},
|
||||
"auto_close": {
|
||||
"description": "Close the topology when no client is connected",
|
||||
"type": "boolean"
|
||||
},
|
||||
"auto_open": {
|
||||
"description": "Open the topology with GNS3",
|
||||
"type": "boolean"
|
||||
},
|
||||
"revision": {
|
||||
"description": "Version of the .gns3 specification.",
|
||||
"type": "integer"
|
||||
},
|
||||
"version": {
|
||||
"description": "Version of the GNS3 software which have update the file for the last time",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the project"
|
||||
},
|
||||
"scene_height": {
|
||||
"type": "integer",
|
||||
"description": "Height of the drawing area"
|
||||
},
|
||||
"scene_width": {
|
||||
"type": "integer",
|
||||
"description": "Width of the drawing area"
|
||||
},
|
||||
"zoom": {
|
||||
"type": "integer",
|
||||
"description": "Zoom of the drawing area"
|
||||
},
|
||||
"show_layers": {
|
||||
"type": "boolean",
|
||||
"description": "Show layers on the drawing area"
|
||||
},
|
||||
"snap_to_grid": {
|
||||
"type": "boolean",
|
||||
"description": "Snap to grid on the drawing area"
|
||||
},
|
||||
"show_grid": {
|
||||
"type": "boolean",
|
||||
"description": "Show the grid on the drawing area"
|
||||
},
|
||||
"grid_size": {
|
||||
"type": "integer",
|
||||
"description": "Grid size for the drawing area for nodes"
|
||||
},
|
||||
"drawing_grid_size": {
|
||||
"type": "integer",
|
||||
"description": "Grid size for the drawing area for drawings"
|
||||
},
|
||||
"show_interface_labels": {
|
||||
"type": "boolean",
|
||||
"description": "Show interface labels on the drawing area"
|
||||
},
|
||||
"supplier": SUPPLIER_OBJECT_SCHEMA,
|
||||
"variables": VARIABLES_OBJECT_SCHEMA,
|
||||
"topology": {
|
||||
"description": "The topology content",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"computes": {
|
||||
"description": "Computes servers",
|
||||
"type": "array",
|
||||
"items": COMPUTE_OBJECT_SCHEMA
|
||||
},
|
||||
"drawings": {
|
||||
"description": "Drawings elements",
|
||||
"type": "array",
|
||||
"items": DRAWING_OBJECT_SCHEMA
|
||||
},
|
||||
"links": {
|
||||
"description": "Link elements",
|
||||
"type": "array",
|
||||
"items": LINK_OBJECT_SCHEMA
|
||||
},
|
||||
"nodes": {
|
||||
"description": "Nodes elements",
|
||||
"type": "array",
|
||||
"items": NODE_OBJECT_SCHEMA
|
||||
}
|
||||
},
|
||||
"required": ["nodes", "links", "drawings", "computes"],
|
||||
"additionalProperties": False
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"project_id", "type", "revision", "version", "name", "topology"
|
||||
],
|
||||
"additionalProperties": False
|
||||
}
|
||||
class TopologyType(str, Enum):
|
||||
|
||||
topology = "topology"
|
||||
|
||||
|
||||
class TopologyContent(BaseModel):
|
||||
|
||||
computes: List[Compute] = Field(..., description="List of computes")
|
||||
drawings: List[Drawing] = Field(..., description="List of drawings")
|
||||
links: List[Link] = Field(..., description="List of links")
|
||||
nodes: List[Node] = Field(..., description="List of nodes")
|
||||
|
||||
|
||||
class Topology(BaseModel):
|
||||
|
||||
project_id: UUID = Field(..., description="Project UUID")
|
||||
type: TopologyType = Field(..., description="Type of file. It's always topology")
|
||||
revision: int = Field(..., description="Version of the .gns3 specification")
|
||||
version: str = Field(..., description="Version of the GNS3 software which have update the file for the last time")
|
||||
name: str = Field(..., description="Name of the project")
|
||||
topology: TopologyContent = Field(..., description="Topology content")
|
||||
auto_start: Optional[bool] = Field(None, description="Start the topology when opened")
|
||||
auto_close: Optional[bool] = Field(None, description="Close the topology when no client is connected")
|
||||
scene_height: Optional[int] = Field(None, description="Height of the drawing area")
|
||||
scene_width: Optional[int] = Field(None, description="Width of the drawing area")
|
||||
zoom: Optional[int] = Field(None, description="Zoom of the drawing area")
|
||||
show_layers: Optional[bool] = Field(None, description="Show layers on the drawing area")
|
||||
snap_to_grid: Optional[bool] = Field(None, description="Snap to grid on the drawing area")
|
||||
show_grid: Optional[bool] = Field(None, description="Show the grid on the drawing area")
|
||||
grid_size: Optional[int] = Field(None, description="Grid size for the drawing area for nodes")
|
||||
drawing_grid_size: Optional[int] = Field(None, description="Grid size for the drawing area for drawings")
|
||||
show_interface_labels: Optional[bool] = Field(None, description="Show interface labels on the drawing area")
|
||||
supplier: Optional[Supplier] = Field(None, description="Supplier of the project")
|
||||
variables: Optional[List[Variable]] = Field(None, description="Variables required to run the project")
|
||||
|
||||
|
||||
def main():
|
||||
import jsonschema
|
||||
|
||||
import json
|
||||
import sys
|
||||
|
||||
with open(sys.argv[1]) as f:
|
||||
data = json.load(f)
|
||||
jsonschema.validate(data, TOPOLOGY_SCHEMA)
|
||||
Topology.parse_obj(data)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -1,51 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import copy
|
||||
from .template import BASE_TEMPLATE_PROPERTIES
|
||||
|
||||
|
||||
TRACENG_TEMPLATE_PROPERTIES = {
|
||||
"ip_address": {
|
||||
"description": "Source IP address for tracing",
|
||||
"type": ["string"],
|
||||
"minLength": 1
|
||||
},
|
||||
"default_destination": {
|
||||
"description": "Default destination IP address or hostname for tracing",
|
||||
"type": ["string"],
|
||||
"minLength": 1
|
||||
},
|
||||
"console_type": {
|
||||
"description": "Console type",
|
||||
"enum": ["none"],
|
||||
"default": "none"
|
||||
},
|
||||
}
|
||||
|
||||
TRACENG_TEMPLATE_PROPERTIES.update(copy.deepcopy(BASE_TEMPLATE_PROPERTIES))
|
||||
TRACENG_TEMPLATE_PROPERTIES["category"]["default"] = "guest"
|
||||
TRACENG_TEMPLATE_PROPERTIES["default_name_format"]["default"] = "TraceNG{0}"
|
||||
TRACENG_TEMPLATE_PROPERTIES["symbol"]["default"] = ":/symbols/traceng.svg"
|
||||
|
||||
TRACENG_TEMPLATE_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "A TraceNG template object",
|
||||
"type": "object",
|
||||
"properties": TRACENG_TEMPLATE_PROPERTIES,
|
||||
"additionalProperties": False
|
||||
}
|
@ -15,19 +15,11 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
VERSION_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"type": "object",
|
||||
'required': ['version'],
|
||||
"additionalProperties": False,
|
||||
"properties": {
|
||||
"version": {
|
||||
"description": "Version number",
|
||||
"type": "string",
|
||||
},
|
||||
"local": {
|
||||
"description": "Whether this is a local server or not",
|
||||
"type": "boolean",
|
||||
}
|
||||
}
|
||||
}
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class Version(BaseModel):
|
||||
|
||||
version: str = Field(..., description="Version number")
|
||||
local: Optional[bool] = Field(None, description="Whether this is a local server or not")
|
||||
|
@ -42,6 +42,16 @@ class VirtualBoxOnCloseAction(str, Enum):
|
||||
save_vm_state = "save_vm_state"
|
||||
|
||||
|
||||
class VirtualBoxAdapterType(str, Enum):
|
||||
|
||||
pcnet_pci_ii = "PCnet-PCI II (Am79C970A)",
|
||||
pcnet_fast_iii = "PCNet-FAST III (Am79C973)",
|
||||
intel_pro_1000_mt_desktop = "Intel PRO/1000 MT Desktop (82540EM)",
|
||||
intel_pro_1000_t_server = "Intel PRO/1000 T Server (82543GC)",
|
||||
intel_pro_1000_mt_server = "Intel PRO/1000 MT Server (82545EM)",
|
||||
paravirtualized_network = "Paravirtualized Network (virtio-net)"
|
||||
|
||||
|
||||
class VirtualBoxBase(BaseModel):
|
||||
"""
|
||||
Common VirtualBox node properties.
|
||||
@ -54,14 +64,14 @@ class VirtualBoxBase(BaseModel):
|
||||
usage: Optional[str] = Field(None, description="How to use the node")
|
||||
# 36 adapters is the maximum given by the ICH9 chipset in VirtualBox
|
||||
adapters: Optional[int] = Field(None, ge=0, le=36, description="Number of adapters")
|
||||
adapter_type: Optional[str] = Field(None, description="VirtualBox adapter type")
|
||||
adapter_type: Optional[VirtualBoxAdapterType] = Field(None, description="VirtualBox adapter type")
|
||||
use_any_adapter: Optional[bool] = Field(None, description="Allow GNS3 to use any VirtualBox adapter")
|
||||
console: Optional[int] = Field(None, gt=0, le=65535, description="Console TCP port")
|
||||
console_type: Optional[VirtualBoxConsoleType] = Field(None, description="Console type")
|
||||
ram: Optional[int] = Field(None, ge=0, le=65535, description="Amount of RAM in MB")
|
||||
headless: Optional[bool] = Field(None, description="Headless mode")
|
||||
on_close: Optional[VirtualBoxOnCloseAction] = Field(None, description="Action to execute on the VM is closed")
|
||||
custom_adapters: Optional[List[CustomAdapter]] = Field(None, description="Custom adpaters")
|
||||
custom_adapters: Optional[List[CustomAdapter]] = Field(None, description="Custom adapters")
|
||||
|
||||
|
||||
class VirtualBoxCreate(VirtualBoxBase):
|
@ -1,113 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import copy
|
||||
from .template import BASE_TEMPLATE_PROPERTIES
|
||||
from .custom_adapters import CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||
|
||||
|
||||
VIRTUALBOX_TEMPLATE_PROPERTIES = {
|
||||
"vmname": {
|
||||
"description": "VirtualBox VM name (in VirtualBox itself)",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"ram": {
|
||||
"description": "Amount of RAM",
|
||||
"minimum": 0,
|
||||
"maximum": 65535,
|
||||
"type": "integer",
|
||||
"default": 256
|
||||
},
|
||||
"linked_clone": {
|
||||
"description": "Whether the VM is a linked clone or not",
|
||||
"type": "boolean",
|
||||
"default": False
|
||||
},
|
||||
"adapters": {
|
||||
"description": "Number of adapters",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 36, # maximum given by the ICH9 chipset in VirtualBox
|
||||
"default": 1
|
||||
},
|
||||
"use_any_adapter": {
|
||||
"description": "Allow GNS3 to use any VirtualBox adapter",
|
||||
"type": "boolean",
|
||||
"default": False
|
||||
},
|
||||
"adapter_type": {
|
||||
"description": "VirtualBox adapter type",
|
||||
"enum": ["PCnet-PCI II (Am79C970A)",
|
||||
"PCNet-FAST III (Am79C973)",
|
||||
"Intel PRO/1000 MT Desktop (82540EM)",
|
||||
"Intel PRO/1000 T Server (82543GC)",
|
||||
"Intel PRO/1000 MT Server (82545EM)",
|
||||
"Paravirtualized Network (virtio-net)"],
|
||||
"default": "Intel PRO/1000 MT Desktop (82540EM)"
|
||||
},
|
||||
"first_port_name": {
|
||||
"description": "Optional name of the first networking port example: eth0",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"port_name_format": {
|
||||
"description": "Optional formatting of the networking port example: eth{0}",
|
||||
"type": "string",
|
||||
"default": "Ethernet{0}"
|
||||
},
|
||||
"port_segment_size": {
|
||||
"description": "Optional port segment size. A port segment is a block of port. For example Ethernet0/0 Ethernet0/1 is the module 0 with a port segment size of 2",
|
||||
"type": "integer",
|
||||
"default": 0
|
||||
},
|
||||
"headless": {
|
||||
"description": "Headless mode",
|
||||
"type": "boolean",
|
||||
"default": False
|
||||
},
|
||||
"on_close": {
|
||||
"description": "Action to execute on the VM is closed",
|
||||
"enum": ["power_off", "shutdown_signal", "save_vm_state"],
|
||||
"default": "power_off"
|
||||
},
|
||||
"console_type": {
|
||||
"description": "Console type",
|
||||
"enum": ["telnet", "none"],
|
||||
"default": "none"
|
||||
},
|
||||
"console_auto_start": {
|
||||
"description": "Automatically start the console when the node has started",
|
||||
"type": "boolean",
|
||||
"default": False
|
||||
},
|
||||
"custom_adapters": CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||
}
|
||||
|
||||
VIRTUALBOX_TEMPLATE_PROPERTIES.update(copy.deepcopy(BASE_TEMPLATE_PROPERTIES))
|
||||
VIRTUALBOX_TEMPLATE_PROPERTIES["category"]["default"] = "guest"
|
||||
VIRTUALBOX_TEMPLATE_PROPERTIES["default_name_format"]["default"] = "{name}-{0}"
|
||||
VIRTUALBOX_TEMPLATE_PROPERTIES["symbol"]["default"] = ":/symbols/vbox_guest.svg"
|
||||
|
||||
VIRTUALBOX_TEMPLATE_OBJECT_SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "A VirtualBox template object",
|
||||
"type": "object",
|
||||
"properties": VIRTUALBOX_TEMPLATE_PROPERTIES,
|
||||
"required": ["vmname"],
|
||||
"additionalProperties": False
|
||||
}
|
48
gns3server/schemas/virtualbox_templates.py
Normal file
48
gns3server/schemas/virtualbox_templates.py
Normal file
@ -0,0 +1,48 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2020 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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 .templates import Category, TemplateBase
|
||||
from .virtualbox_nodes import (
|
||||
VirtualBoxConsoleType,
|
||||
VirtualBoxAdapterType,
|
||||
VirtualBoxOnCloseAction,
|
||||
CustomAdapter
|
||||
)
|
||||
|
||||
from pydantic import Field
|
||||
from typing import Optional, List
|
||||
|
||||
|
||||
class VirtualBoxTemplate(TemplateBase):
|
||||
|
||||
category: Optional[Category] = "guest"
|
||||
default_name_format: Optional[str] = "{name}-{0}"
|
||||
symbol: Optional[str] = ":/symbols/vbox_guest.svg"
|
||||
vmname: str = Field(..., description="VirtualBox VM name (in VirtualBox itself)")
|
||||
ram: Optional[int] = Field(256, gt=0, description="Amount of RAM in MB")
|
||||
linked_clone: Optional[bool] = Field(False, description="Whether the VM is a linked clone or not")
|
||||
adapters: Optional[int] = Field(1, ge=0, le=36, description="Number of adapters") # 36 is the maximum given by the ICH9 chipset in VirtualBox
|
||||
use_any_adapter: Optional[bool] = Field(False, description="Allow GNS3 to use any VirtualBox adapter")
|
||||
adapter_type: Optional[VirtualBoxAdapterType] = Field("Intel PRO/1000 MT Desktop (82540EM)", description="VirtualBox adapter type")
|
||||
first_port_name: Optional[str] = Field("", description="Optional name of the first networking port example: eth0")
|
||||
port_name_format: Optional[str] = Field("Ethernet{0}", description="Optional formatting of the networking port example: eth{0}")
|
||||
port_segment_size: Optional[int] = Field(0, description="Optional port segment size. A port segment is a block of port. For example Ethernet0/0 Ethernet0/1 is the module 0 with a port segment size of 2")
|
||||
headless: Optional[bool] = Field(False, description="Headless mode")
|
||||
on_close: Optional[VirtualBoxOnCloseAction] = Field("power_off", description="Action to execute on the VM is closed")
|
||||
console_type: Optional[VirtualBoxConsoleType] = Field("none", description="Console type")
|
||||
console_auto_start: Optional[bool] = Field(False, description="Automatically start the console when the node has started")
|
||||
custom_adapters: Optional[List[CustomAdapter]] = Field([], description="Custom adapters")
|
@ -43,6 +43,21 @@ class VMwareOnCloseAction(str, Enum):
|
||||
save_vm_state = "save_vm_state"
|
||||
|
||||
|
||||
class VMwareAdapterType(str, Enum):
|
||||
"""
|
||||
Supported VMware VM adapter types.
|
||||
"""
|
||||
|
||||
default = "default"
|
||||
e1000 = "e1000"
|
||||
e1000e = "e1000e"
|
||||
flexible = "flexible"
|
||||
vlance = "vlance"
|
||||
vmxnet = "vmxnet"
|
||||
vmxnet2 = "vmxnet2"
|
||||
vmxnet3 = "vmxnet3"
|
||||
|
||||
|
||||
class VMwareBase(BaseModel):
|
||||
"""
|
||||
Common VMware node properties.
|
||||
@ -59,7 +74,7 @@ class VMwareBase(BaseModel):
|
||||
on_close: Optional[VMwareOnCloseAction] = Field(None, description="Action to execute on the VM is closed")
|
||||
# 10 adapters is the maximum supported by VMware VMs.
|
||||
adapters: Optional[int] = Field(None, ge=0, le=10, description="Number of adapters")
|
||||
adapter_type: Optional[str] = Field(None, description="VMware adapter type")
|
||||
adapter_type: Optional[VMwareAdapterType] = Field(None, description="VMware adapter type")
|
||||
use_any_adapter: Optional[bool] = Field(None, description="Allow GNS3 to use any VMware adapter")
|
||||
custom_adapters: Optional[List[CustomAdapter]] = Field(None, description="Custom adpaters")
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user