mirror of
https://github.com/GNS3/gns3-server.git
synced 2025-01-31 00:24:12 +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
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
ref: "3.0"
|
ref: "gh-pages"
|
||||||
- uses: actions/setup-python@v2
|
- uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: 3.6
|
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
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
@ -32,11 +37,7 @@ jobs:
|
|||||||
python3 publish_api_documentation.py
|
python3 publish_api_documentation.py
|
||||||
- name: Publish the API documentation
|
- name: Publish the API documentation
|
||||||
run: |
|
run: |
|
||||||
git config user.name github-actions
|
|
||||||
git config user.email github-actions@github.com
|
|
||||||
git add docs
|
git add docs
|
||||||
git status
|
git status
|
||||||
git commit -m "Publish API documentation"
|
git commit -m "Publish API documentation"
|
||||||
git checkout gh-pages
|
|
||||||
git merge 3.0 -X theirs
|
|
||||||
git push
|
git push
|
||||||
|
@ -49,7 +49,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
app = FastAPI(title="GNS3 controller API",
|
app = FastAPI(title="GNS3 controller API",
|
||||||
description="This page describes the public controller API for GNS3",
|
description="This page describes the public controller API for GNS3",
|
||||||
version="v2")
|
version="v3")
|
||||||
|
|
||||||
origins = [
|
origins = [
|
||||||
"http://127.0.0.1",
|
"http://127.0.0.1",
|
||||||
@ -71,8 +71,8 @@ app.add_middleware(
|
|||||||
)
|
)
|
||||||
|
|
||||||
app.include_router(index.router, tags=["Index"])
|
app.include_router(index.router, tags=["Index"])
|
||||||
app.include_router(controller.router, prefix="/v2")
|
app.include_router(controller.router, prefix="/v3")
|
||||||
app.mount("/v2/compute", compute_api)
|
app.mount("/v3/compute", compute_api)
|
||||||
|
|
||||||
|
|
||||||
@app.exception_handler(ControllerError)
|
@app.exception_handler(ControllerError)
|
||||||
|
@ -44,11 +44,11 @@ from ..error import NodeError, ImageMissingError
|
|||||||
from ..nios.nio_udp import NIOUDP
|
from ..nios.nio_udp import NIOUDP
|
||||||
from ..nios.nio_tap import NIOTAP
|
from ..nios.nio_tap import NIOTAP
|
||||||
from ..base_node import BaseNode
|
from ..base_node import BaseNode
|
||||||
from ...schemas.qemu import QEMU_OBJECT_SCHEMA, QEMU_PLATFORMS
|
|
||||||
from ...utils.asyncio import monitor_process
|
from ...utils.asyncio import monitor_process
|
||||||
from ...utils.images import md5sum
|
from ...utils.images import md5sum
|
||||||
from ...utils import macaddress_to_int, int_to_macaddress
|
from ...utils import macaddress_to_int, int_to_macaddress
|
||||||
|
|
||||||
|
from gns3server.schemas.qemu_nodes import Qemu, QemuPlatform
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -216,7 +216,10 @@ class QemuVM(BaseNode):
|
|||||||
self._platform = "i386"
|
self._platform = "i386"
|
||||||
else:
|
else:
|
||||||
self._platform = re.sub(r'^qemu-system-(.*)$', r'\1', qemu_bin, re.IGNORECASE)
|
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))
|
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,
|
log.info('QEMU VM "{name}" [{id}] has set the QEMU path to {qemu_path}'.format(name=self._name,
|
||||||
id=self._id,
|
id=self._id,
|
||||||
@ -2288,7 +2291,7 @@ class QemuVM(BaseNode):
|
|||||||
"node_directory": self.working_path
|
"node_directory": self.working_path
|
||||||
}
|
}
|
||||||
# Qemu has a long list of options. The JSON schema is the single source of information
|
# 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:
|
if field not in answer:
|
||||||
try:
|
try:
|
||||||
answer[field] = getattr(self, field)
|
answer[field] = getattr(self, field)
|
||||||
|
@ -497,7 +497,7 @@ class Compute:
|
|||||||
host = "[{}]".format(host)
|
host = "[{}]".format(host)
|
||||||
elif host == "0.0.0.0":
|
elif host == "0.0.0.0":
|
||||||
host = "127.0.0.1"
|
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):
|
def get_url(self, path):
|
||||||
""" Returns URL for specific path at Compute"""
|
""" Returns URL for specific path at Compute"""
|
||||||
|
@ -310,7 +310,7 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
|||||||
remaining_try = 300
|
remaining_try = 300
|
||||||
while remaining_try > 0:
|
while remaining_try > 0:
|
||||||
try:
|
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:
|
if resp.status < 300:
|
||||||
try:
|
try:
|
||||||
json_data = await resp.json()
|
json_data = await resp.json()
|
||||||
|
@ -345,11 +345,12 @@ class Link:
|
|||||||
node_id = self.capture_node["node"].id
|
node_id = self.capture_node["node"].id
|
||||||
adapter_number = self.capture_node["adapter_number"]
|
adapter_number = self.capture_node["adapter_number"]
|
||||||
port_number = self.capture_node["port_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,
|
url = "/projects/{project_id}/{node_type}/nodes/{node_id}/adapters/{adapter_number}/" \
|
||||||
node_type=node_type,
|
"ports/{port_number}/capture/stream".format(project_id=self.project.id,
|
||||||
node_id=node_id,
|
node_type=node_type,
|
||||||
adapter_number=adapter_number,
|
node_id=node_id,
|
||||||
port_number=port_number)
|
adapter_number=adapter_number,
|
||||||
|
port_number=port_number)
|
||||||
|
|
||||||
return compute._getUrl(url)
|
return compute._getUrl(url)
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python
|
#!/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
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
@ -17,57 +17,14 @@
|
|||||||
|
|
||||||
import copy
|
import copy
|
||||||
import uuid
|
import uuid
|
||||||
import json
|
|
||||||
import jsonschema
|
|
||||||
|
|
||||||
from gns3server.schemas.cloud_template import CLOUD_TEMPLATE_OBJECT_SCHEMA
|
from pydantic import ValidationError
|
||||||
from gns3server.schemas.ethernet_switch_template import ETHERNET_SWITCH_TEMPLATE_OBJECT_SCHEMA
|
from fastapi.encoders import jsonable_encoder
|
||||||
from gns3server.schemas.ethernet_hub_template import ETHERNET_HUB_TEMPLATE_OBJECT_SCHEMA
|
from gns3server import schemas
|
||||||
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
|
|
||||||
)
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
log = logging.getLogger(__name__)
|
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 = {
|
ID_TO_CATEGORY = {
|
||||||
3: "firewall",
|
3: "firewall",
|
||||||
2: "guest",
|
2: "guest",
|
||||||
@ -76,27 +33,26 @@ ID_TO_CATEGORY = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEMPLATE_TYPE_TO_SHEMA = {
|
TEMPLATE_TYPE_TO_SHEMA = {
|
||||||
"cloud": CLOUD_TEMPLATE_OBJECT_SCHEMA,
|
"cloud": schemas.CloudTemplate,
|
||||||
"ethernet_hub": ETHERNET_HUB_TEMPLATE_OBJECT_SCHEMA,
|
"ethernet_hub": schemas.EthernetHubTemplate,
|
||||||
"ethernet_switch": ETHERNET_SWITCH_TEMPLATE_OBJECT_SCHEMA,
|
"ethernet_switch": schemas.EthernetSwitchTemplate,
|
||||||
"docker": DOCKER_TEMPLATE_OBJECT_SCHEMA,
|
"docker": schemas.DockerTemplate,
|
||||||
"dynamips": DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
"dynamips": schemas.DynamipsTemplate,
|
||||||
"vpcs": VPCS_TEMPLATE_OBJECT_SCHEMA,
|
"vpcs": schemas.VPCSTemplate,
|
||||||
"traceng": TRACENG_TEMPLATE_OBJECT_SCHEMA,
|
"virtualbox": schemas.VirtualBoxTemplate,
|
||||||
"virtualbox": VIRTUALBOX_TEMPLATE_OBJECT_SCHEMA,
|
"vmware": schemas.VMwareTemplate,
|
||||||
"vmware": VMWARE_TEMPLATE_OBJECT_SCHEMA,
|
"iou": schemas.IOUTemplate,
|
||||||
"iou": IOU_TEMPLATE_OBJECT_SCHEMA,
|
"qemu": schemas.QemuTemplate
|
||||||
"qemu": QEMU_TEMPLATE_OBJECT_SCHEMA
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DYNAMIPS_PLATFORM_TO_SHEMA = {
|
DYNAMIPS_PLATFORM_TO_SHEMA = {
|
||||||
"c7200": C7200_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
"c7200": schemas.C7200DynamipsTemplate,
|
||||||
"c3745": C3745_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
"c3745": schemas.C3745DynamipsTemplate,
|
||||||
"c3725": C3725_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
"c3725": schemas.C3725DynamipsTemplate,
|
||||||
"c3600": C3600_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
"c3600": schemas.C3600DynamipsTemplate,
|
||||||
"c2691": C2691_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
"c2691": schemas.C2691DynamipsTemplate,
|
||||||
"c2600": C2600_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA,
|
"c2600": schemas.C2600DynamipsTemplate,
|
||||||
"c1700": C1700_DYNAMIPS_TEMPLATE_OBJECT_SCHEMA
|
"c1700": schemas.C1700DynamipsTemplate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -141,11 +97,18 @@ class Template:
|
|||||||
self._builtin = builtin
|
self._builtin = builtin
|
||||||
|
|
||||||
if builtin is False:
|
if builtin is False:
|
||||||
self.validate_and_apply_defaults(TEMPLATE_TYPE_TO_SHEMA[self.template_type])
|
try:
|
||||||
|
template_schema = TEMPLATE_TYPE_TO_SHEMA[self.template_type]
|
||||||
if self.template_type == "dynamips":
|
template_settings_with_defaults = template_schema .parse_obj(self.__json__())
|
||||||
# special case for Dynamips to cover all platform types that contain specific settings
|
self._settings = jsonable_encoder(template_settings_with_defaults.dict())
|
||||||
self.validate_and_apply_defaults(DYNAMIPS_PLATFORM_TO_SHEMA[self._settings["platform"]])
|
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))
|
log.debug('Template "{name}" [{id}] loaded'.format(name=self.name, id=self._id))
|
||||||
|
|
||||||
@ -179,7 +142,6 @@ class Template:
|
|||||||
|
|
||||||
def update(self, **kwargs):
|
def update(self, **kwargs):
|
||||||
|
|
||||||
|
|
||||||
from gns3server.controller import Controller
|
from gns3server.controller import Controller
|
||||||
controller = Controller.instance()
|
controller = Controller.instance()
|
||||||
Controller.instance().check_can_write_config()
|
Controller.instance().check_can_write_config()
|
||||||
@ -187,17 +149,6 @@ class Template:
|
|||||||
controller.notification.controller_emit("template.updated", self.__json__())
|
controller.notification.controller_emit("template.updated", self.__json__())
|
||||||
controller.save()
|
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):
|
def __json__(self):
|
||||||
"""
|
"""
|
||||||
Template settings.
|
Template settings.
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
import copy
|
import copy
|
||||||
import uuid
|
import uuid
|
||||||
import jsonschema
|
import pydantic
|
||||||
|
|
||||||
from .controller_error import ControllerError, ControllerNotFoundError
|
from .controller_error import ControllerError, ControllerNotFoundError
|
||||||
from .template import Template
|
from .template import Template
|
||||||
@ -53,8 +53,8 @@ class TemplateManager:
|
|||||||
try:
|
try:
|
||||||
template = Template(template_settings.get("template_id"), template_settings)
|
template = Template(template_settings.get("template_id"), template_settings)
|
||||||
self._templates[template.id] = template
|
self._templates[template.id] = template
|
||||||
except jsonschema.ValidationError as e:
|
except pydantic.ValidationError as e:
|
||||||
message = "Cannot load template with JSON data '{}': {}".format(template_settings, e.message)
|
message = "Cannot load template with JSON data '{}': {}".format(template_settings, e)
|
||||||
log.warning(message)
|
log.warning(message)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -90,8 +90,8 @@ class TemplateManager:
|
|||||||
template_id = settings.setdefault("template_id", str(uuid.uuid4()))
|
template_id = settings.setdefault("template_id", str(uuid.uuid4()))
|
||||||
try:
|
try:
|
||||||
template = Template(template_id, settings)
|
template = Template(template_id, settings)
|
||||||
except jsonschema.ValidationError as e:
|
except pydantic.ValidationError as e:
|
||||||
message = "JSON schema error adding template with JSON data '{}': {}".format(settings, e.message)
|
message = "JSON schema error adding template with JSON data '{}': {}".format(settings, e)
|
||||||
raise ControllerError(message)
|
raise ControllerError(message)
|
||||||
|
|
||||||
from . import Controller
|
from . import Controller
|
||||||
|
@ -18,21 +18,22 @@
|
|||||||
import os
|
import os
|
||||||
import html
|
import html
|
||||||
import json
|
import json
|
||||||
import copy
|
|
||||||
import uuid
|
import uuid
|
||||||
import glob
|
import glob
|
||||||
import shutil
|
import shutil
|
||||||
import zipfile
|
import zipfile
|
||||||
import jsonschema
|
import pydantic
|
||||||
|
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from ..version import __version__
|
from ..version import __version__
|
||||||
from ..schemas.topology import TOPOLOGY_SCHEMA
|
|
||||||
from ..schemas import dynamips_vm
|
|
||||||
from ..utils.qt import qt_font_to_style
|
from ..utils.qt import qt_font_to_style
|
||||||
from ..compute.dynamips import PLATFORMS_DEFAULT_RAM
|
from ..compute.dynamips import PLATFORMS_DEFAULT_RAM
|
||||||
from .controller_error import ControllerError
|
from .controller_error import ControllerError
|
||||||
|
|
||||||
|
from gns3server.schemas.topology import Topology
|
||||||
|
from gns3server.schemas.dynamips_nodes import DynamipsCreate
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -40,29 +41,21 @@ log = logging.getLogger(__name__)
|
|||||||
GNS3_FILE_FORMAT_REVISION = 9
|
GNS3_FILE_FORMAT_REVISION = 9
|
||||||
|
|
||||||
|
|
||||||
|
class DynamipsNodeValidation(DynamipsCreate):
|
||||||
|
name: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
def _check_topology_schema(topo):
|
def _check_topology_schema(topo):
|
||||||
try:
|
try:
|
||||||
jsonschema.validate(topo, TOPOLOGY_SCHEMA)
|
Topology.parse_obj(topo)
|
||||||
|
|
||||||
# Check the nodes property against compute schemas
|
# Check the nodes property against compute schemas
|
||||||
for node in topo["topology"].get("nodes", []):
|
for node in topo["topology"].get("nodes", []):
|
||||||
schema = None
|
|
||||||
if node["node_type"] == "dynamips":
|
if node["node_type"] == "dynamips":
|
||||||
schema = copy.deepcopy(dynamips_vm.VM_CREATE_SCHEMA)
|
DynamipsNodeValidation.parse_obj(node.get("properties", {}))
|
||||||
|
|
||||||
if schema:
|
except pydantic.ValidationError as e:
|
||||||
# Properties send to compute but in an other place in topology
|
error = "Invalid data in topology file: {}".format(e)
|
||||||
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))
|
|
||||||
log.critical(error)
|
log.critical(error)
|
||||||
raise ControllerError(error)
|
raise ControllerError(error)
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ from . import vpcs_nodes
|
|||||||
|
|
||||||
compute_api = FastAPI(title="GNS3 compute API",
|
compute_api = FastAPI(title="GNS3 compute API",
|
||||||
description="This page describes the private compute API for GNS3. PLEASE DO NOT USE DIRECTLY!",
|
description="This page describes the private compute API for GNS3. PLEASE DO NOT USE DIRECTLY!",
|
||||||
version="v2")
|
version="v3")
|
||||||
|
|
||||||
|
|
||||||
@compute_api.exception_handler(ComputeError)
|
@compute_api.exception_handler(ComputeError)
|
||||||
|
@ -26,7 +26,7 @@ from fastapi.encoders import jsonable_encoder
|
|||||||
from fastapi.responses import StreamingResponse
|
from fastapi.responses import StreamingResponse
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from gns3server.endpoints import schemas
|
from gns3server import schemas
|
||||||
from gns3server.compute.dynamips import Dynamips
|
from gns3server.compute.dynamips import Dynamips
|
||||||
from gns3server.compute.dynamips.nodes.atm_switch import ATMSwitch
|
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()
|
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)
|
responses=responses)
|
||||||
async def start_capture(adapter_number: int,
|
async def start_capture(adapter_number: int,
|
||||||
port_number: int,
|
port_number: int,
|
||||||
@ -202,7 +202,7 @@ async def start_capture(adapter_number: int,
|
|||||||
return {"pcap_file_path": pcap_file_path}
|
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,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
responses=responses)
|
responses=responses)
|
||||||
async def stop_capture(adapter_number: int, port_number: int, node: ATMSwitch = Depends(dep_node)):
|
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)
|
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)
|
responses=responses)
|
||||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: ATMSwitch = Depends(dep_node)):
|
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.version import __version__
|
||||||
from gns3server.compute import MODULES
|
from gns3server.compute import MODULES
|
||||||
from gns3server.utils.path import get_default_project_directory
|
from gns3server.utils.path import get_default_project_directory
|
||||||
from gns3server.endpoints import schemas
|
from gns3server import schemas
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ from fastapi.responses import StreamingResponse
|
|||||||
from typing import Union
|
from typing import Union
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from gns3server.endpoints import schemas
|
from gns3server import schemas
|
||||||
from gns3server.compute.builtin import Builtin
|
from gns3server.compute.builtin import Builtin
|
||||||
from gns3server.compute.builtin.nodes.cloud import Cloud
|
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)
|
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)
|
responses=responses)
|
||||||
async def start_capture(adapter_number: int,
|
async def start_capture(adapter_number: int,
|
||||||
port_number: int,
|
port_number: int,
|
||||||
@ -213,7 +213,7 @@ async def start_capture(adapter_number: int,
|
|||||||
return {"pcap_file_path": pcap_file_path}
|
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,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
responses=responses)
|
responses=responses)
|
||||||
async def stop_capture(adapter_number: int, port_number: int, node: Cloud = Depends(dep_node)):
|
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.qemu import Qemu
|
||||||
from gns3server.compute.virtualbox import VirtualBox
|
from gns3server.compute.virtualbox import VirtualBox
|
||||||
from gns3server.compute.vmware import VMware
|
from gns3server.compute.vmware import VMware
|
||||||
from gns3server.endpoints import schemas
|
from gns3server import schemas
|
||||||
|
|
||||||
from fastapi import APIRouter, HTTPException, Body, status
|
from fastapi import APIRouter, HTTPException, Body, status
|
||||||
from fastapi.encoders import jsonable_encoder
|
from fastapi.encoders import jsonable_encoder
|
||||||
|
@ -26,7 +26,7 @@ from fastapi.encoders import jsonable_encoder
|
|||||||
from fastapi.responses import StreamingResponse
|
from fastapi.responses import StreamingResponse
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from gns3server.endpoints import schemas
|
from gns3server import schemas
|
||||||
from gns3server.compute.docker import Docker
|
from gns3server.compute.docker import Docker
|
||||||
from gns3server.compute.docker.docker_vm import DockerVM
|
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)
|
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)
|
responses=responses)
|
||||||
async def start_capture(adapter_number: int,
|
async def start_capture(adapter_number: int,
|
||||||
port_number: int,
|
port_number: int,
|
||||||
@ -278,7 +278,7 @@ async def start_capture(adapter_number: int,
|
|||||||
return {"pcap_file_path": str(pcap_file_path)}
|
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,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
responses=responses)
|
responses=responses)
|
||||||
async def stop_capture(adapter_number: int, port_number: int, node: DockerVM = Depends(dep_node)):
|
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)
|
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)
|
responses=responses)
|
||||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: DockerVM = Depends(dep_node)):
|
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 import Dynamips
|
||||||
from gns3server.compute.dynamips.nodes.router import Router
|
from gns3server.compute.dynamips.nodes.router import Router
|
||||||
from gns3server.compute.dynamips.dynamips_error import DynamipsError
|
from gns3server.compute.dynamips.dynamips_error import DynamipsError
|
||||||
from gns3server.endpoints import schemas
|
from gns3server import schemas
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
@ -219,7 +219,7 @@ async def delete_nio(adapter_number: int, port_number: int, node: Router = Depen
|
|||||||
await nio.delete()
|
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)
|
responses=responses)
|
||||||
async def start_capture(adapter_number: int,
|
async def start_capture(adapter_number: int,
|
||||||
port_number: int,
|
port_number: int,
|
||||||
@ -242,7 +242,7 @@ async def start_capture(adapter_number: int,
|
|||||||
return {"pcap_file_path": pcap_file_path}
|
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,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
responses=responses)
|
responses=responses)
|
||||||
async def stop_capture(adapter_number: int, port_number: int, node: Router = Depends(dep_node)):
|
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)
|
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)
|
responses=responses)
|
||||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: Router = Depends(dep_node)):
|
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 import Dynamips
|
||||||
from gns3server.compute.dynamips.nodes.ethernet_hub import EthernetHub
|
from gns3server.compute.dynamips.nodes.ethernet_hub import EthernetHub
|
||||||
from gns3server.endpoints import schemas
|
from gns3server import schemas
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ async def delete_nio(adapter_number: int, port_number: int, node: EthernetHub =
|
|||||||
await nio.delete()
|
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)
|
responses=responses)
|
||||||
async def start_capture(adapter_number: int,
|
async def start_capture(adapter_number: int,
|
||||||
port_number: int,
|
port_number: int,
|
||||||
@ -203,7 +203,7 @@ async def start_capture(adapter_number: int,
|
|||||||
return {"pcap_file_path": pcap_file_path}
|
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,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
responses=responses)
|
responses=responses)
|
||||||
async def stop_capture(adapter_number: int, port_number: int, node: EthernetHub = Depends(dep_node)):
|
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)
|
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)
|
responses=responses)
|
||||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: EthernetHub = Depends(dep_node)):
|
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 import Dynamips
|
||||||
from gns3server.compute.dynamips.nodes.ethernet_switch import EthernetSwitch
|
from gns3server.compute.dynamips.nodes.ethernet_switch import EthernetSwitch
|
||||||
from gns3server.endpoints import schemas
|
from gns3server import schemas
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ async def delete_nio(adapter_number: int, port_number: int, node: EthernetSwitch
|
|||||||
await nio.delete()
|
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)
|
responses=responses)
|
||||||
async def start_capture(adapter_number: int,
|
async def start_capture(adapter_number: int,
|
||||||
port_number: int,
|
port_number: int,
|
||||||
@ -202,7 +202,7 @@ async def start_capture(adapter_number: int,
|
|||||||
return {"pcap_file_path": pcap_file_path}
|
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,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
responses=responses)
|
responses=responses)
|
||||||
async def stop_capture(adapter_number: int,port_number: int, node: EthernetSwitch = Depends(dep_node)):
|
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)
|
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)
|
responses=responses)
|
||||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: EthernetSwitch = Depends(dep_node)):
|
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 fastapi.responses import StreamingResponse
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from gns3server.endpoints import schemas
|
from gns3server import schemas
|
||||||
from gns3server.compute.dynamips import Dynamips
|
from gns3server.compute.dynamips import Dynamips
|
||||||
from gns3server.compute.dynamips.nodes.frame_relay_switch import FrameRelaySwitch
|
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()
|
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)
|
responses=responses)
|
||||||
async def start_capture(adapter_number: int,
|
async def start_capture(adapter_number: int,
|
||||||
port_number: int,
|
port_number: int,
|
||||||
@ -204,7 +204,7 @@ async def start_capture(adapter_number: int,
|
|||||||
return {"pcap_file_path": pcap_file_path}
|
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,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
responses=responses)
|
responses=responses)
|
||||||
async def stop_capture(adapter_number: int, port_number: int, node: FrameRelaySwitch = Depends(dep_node)):
|
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)
|
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)
|
responses=responses)
|
||||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: FrameRelaySwitch = Depends(dep_node)):
|
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 typing import Union
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from gns3server.endpoints import schemas
|
from gns3server import schemas
|
||||||
from gns3server.compute.iou import IOU
|
from gns3server.compute.iou import IOU
|
||||||
from gns3server.compute.iou.iou_vm import IOUVM
|
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)
|
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)
|
responses=responses)
|
||||||
async def start_capture(adapter_number: int,
|
async def start_capture(adapter_number: int,
|
||||||
port_number: int,
|
port_number: int,
|
||||||
@ -252,7 +252,7 @@ async def start_capture(adapter_number: int,
|
|||||||
return {"pcap_file_path": str(pcap_file_path)}
|
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,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
responses=responses)
|
responses=responses)
|
||||||
async def stop_capture(adapter_number: int, port_number: int, node: IOUVM = Depends(dep_node)):
|
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)
|
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)
|
responses=responses)
|
||||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: IOUVM = Depends(dep_node)):
|
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 typing import Union
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from gns3server.endpoints import schemas
|
from gns3server import schemas
|
||||||
from gns3server.compute.builtin import Builtin
|
from gns3server.compute.builtin import Builtin
|
||||||
from gns3server.compute.builtin.nodes.nat import Nat
|
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)
|
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)
|
responses=responses)
|
||||||
async def start_capture(adapter_number: int,
|
async def start_capture(adapter_number: int,
|
||||||
port_number: int,
|
port_number: int,
|
||||||
@ -208,7 +208,7 @@ async def start_capture(adapter_number: int,
|
|||||||
return {"pcap_file_path": pcap_file_path}
|
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,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
responses=responses)
|
responses=responses)
|
||||||
async def stop_capture(adapter_number: int, port_number: int, node: Nat = Depends(dep_node)):
|
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)
|
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)
|
responses=responses)
|
||||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: Nat = Depends(dep_node)):
|
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_manager import ProjectManager
|
||||||
from gns3server.compute.project import Project
|
from gns3server.compute.project import Project
|
||||||
from gns3server.endpoints import schemas
|
from gns3server import schemas
|
||||||
|
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
@ -27,7 +27,7 @@ from fastapi.encoders import jsonable_encoder
|
|||||||
from fastapi.responses import StreamingResponse
|
from fastapi.responses import StreamingResponse
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from gns3server.endpoints import schemas
|
from gns3server import schemas
|
||||||
from gns3server.compute.project_manager import ProjectManager
|
from gns3server.compute.project_manager import ProjectManager
|
||||||
from gns3server.compute.qemu import Qemu
|
from gns3server.compute.qemu import Qemu
|
||||||
from gns3server.compute.qemu.qemu_vm import QemuVM
|
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)
|
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)
|
responses=responses)
|
||||||
async def start_capture(adapter_number: int,
|
async def start_capture(adapter_number: int,
|
||||||
port_number: int,
|
port_number: int,
|
||||||
@ -268,7 +268,7 @@ async def start_capture(adapter_number: int,
|
|||||||
return {"pcap_file_path": str(pcap_file_path)}
|
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,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
responses=responses)
|
responses=responses)
|
||||||
async def stop_capture(adapter_number: int, port_number: int, node: QemuVM = Depends(dep_node)):
|
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)
|
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)
|
responses=responses)
|
||||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: QemuVM = Depends(dep_node)):
|
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 fastapi.responses import StreamingResponse
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from gns3server.endpoints import schemas
|
from gns3server import schemas
|
||||||
from gns3server.compute.virtualbox import VirtualBox
|
from gns3server.compute.virtualbox import VirtualBox
|
||||||
from gns3server.compute.virtualbox.virtualbox_error import VirtualBoxError
|
from gns3server.compute.virtualbox.virtualbox_error import VirtualBoxError
|
||||||
from gns3server.compute.project_manager import ProjectManager
|
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)
|
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)
|
responses=responses)
|
||||||
async def start_capture(adapter_number: int,
|
async def start_capture(adapter_number: int,
|
||||||
port_number: int,
|
port_number: int,
|
||||||
@ -276,7 +276,7 @@ async def start_capture(adapter_number: int,
|
|||||||
return {"pcap_file_path": str(pcap_file_path)}
|
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,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
responses=responses)
|
responses=responses)
|
||||||
async def stop_capture(adapter_number: int, port_number: int, node: VirtualBoxVM = Depends(dep_node)):
|
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)
|
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)
|
responses=responses)
|
||||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: VirtualBoxVM = Depends(dep_node)):
|
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 fastapi.responses import StreamingResponse
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from gns3server.endpoints import schemas
|
from gns3server import schemas
|
||||||
from gns3server.compute.vmware import VMware
|
from gns3server.compute.vmware import VMware
|
||||||
from gns3server.compute.project_manager import ProjectManager
|
from gns3server.compute.project_manager import ProjectManager
|
||||||
from gns3server.compute.vmware.vmware_vm import VMwareVM
|
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)
|
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)
|
responses=responses)
|
||||||
async def start_capture(adapter_number: int,
|
async def start_capture(adapter_number: int,
|
||||||
port_number: int,
|
port_number: int,
|
||||||
@ -241,7 +241,7 @@ async def start_capture(adapter_number: int,
|
|||||||
return {"pcap_file_path": pcap_file_path}
|
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,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
responses=responses)
|
responses=responses)
|
||||||
async def stop_capture(adapter_number: int, port_number: int, node: VMwareVM = Depends(dep_node)):
|
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)
|
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)
|
responses=responses)
|
||||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: VMwareVM = Depends(dep_node)):
|
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 fastapi.responses import StreamingResponse
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from gns3server.endpoints import schemas
|
from gns3server import schemas
|
||||||
from gns3server.compute.vpcs import VPCS
|
from gns3server.compute.vpcs import VPCS
|
||||||
from gns3server.compute.vpcs.vpcs_vm import VPCSVM
|
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)
|
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)
|
responses=responses)
|
||||||
async def start_capture(adapter_number: int,
|
async def start_capture(adapter_number: int,
|
||||||
port_number: int,
|
port_number: int,
|
||||||
@ -224,7 +224,7 @@ async def start_capture(adapter_number: int,
|
|||||||
return {"pcap_file_path": pcap_file_path}
|
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,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
responses=responses)
|
responses=responses)
|
||||||
async def stop_capture(adapter_number: int, port_number: int, node: VPCSVM = Depends(dep_node)):
|
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()
|
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)
|
responses=responses)
|
||||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: VPCSVM = Depends(dep_node)):
|
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 uuid import UUID
|
||||||
|
|
||||||
from gns3server.controller import Controller
|
from gns3server.controller import Controller
|
||||||
from gns3server.endpoints.schemas.common import ErrorMessage
|
from gns3server import schemas
|
||||||
from gns3server.endpoints import schemas
|
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
responses = {
|
responses = {
|
||||||
404: {"model": ErrorMessage, "description": "Compute not found"}
|
404: {"model": schemas.ErrorMessage, "description": "Compute not found"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@router.post("",
|
@router.post("",
|
||||||
status_code=status.HTTP_201_CREATED,
|
status_code=status.HTTP_201_CREATED,
|
||||||
response_model=schemas.Compute,
|
response_model=schemas.Compute,
|
||||||
responses={404: {"model": ErrorMessage, "description": "Could not connect to compute"},
|
responses={404: {"model": schemas.ErrorMessage, "description": "Could not connect to compute"},
|
||||||
409: {"model": ErrorMessage, "description": "Could not create compute"},
|
409: {"model": schemas.ErrorMessage, "description": "Could not create compute"},
|
||||||
401: {"model": ErrorMessage, "description": "Invalid authentication for compute"}})
|
401: {"model": schemas.ErrorMessage, "description": "Invalid authentication for compute"}})
|
||||||
async def create_compute(compute_data: schemas.ComputeCreate):
|
async def create_compute(compute_data: schemas.ComputeCreate):
|
||||||
"""
|
"""
|
||||||
Create a new compute on the controller.
|
Create a new compute on the controller.
|
||||||
|
@ -26,8 +26,7 @@ from gns3server.config import Config
|
|||||||
from gns3server.controller import Controller
|
from gns3server.controller import Controller
|
||||||
from gns3server.version import __version__
|
from gns3server.version import __version__
|
||||||
from gns3server.controller.controller_error import ControllerError, ControllerForbiddenError
|
from gns3server.controller.controller_error import ControllerError, ControllerForbiddenError
|
||||||
from gns3server.endpoints.schemas.common import ErrorMessage
|
from gns3server import schemas
|
||||||
from gns3server.endpoints import schemas
|
|
||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
@ -38,7 +37,7 @@ router = APIRouter()
|
|||||||
|
|
||||||
@router.post("/shutdown",
|
@router.post("/shutdown",
|
||||||
status_code=status.HTTP_204_NO_CONTENT,
|
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():
|
async def shutdown():
|
||||||
"""
|
"""
|
||||||
Shutdown the local server
|
Shutdown the local server
|
||||||
@ -85,7 +84,7 @@ def version():
|
|||||||
@router.post("/version",
|
@router.post("/version",
|
||||||
response_model=schemas.Version,
|
response_model=schemas.Version,
|
||||||
response_model_exclude_defaults=True,
|
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):
|
def check_version(version: schemas.Version):
|
||||||
"""
|
"""
|
||||||
Check if version is the same as the server.
|
Check if version is the same as the server.
|
||||||
|
@ -25,18 +25,17 @@ from typing import List
|
|||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from gns3server.controller import Controller
|
from gns3server.controller import Controller
|
||||||
from gns3server.endpoints.schemas.common import ErrorMessage
|
from gns3server import schemas
|
||||||
from gns3server.endpoints.schemas.drawings import Drawing
|
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
responses = {
|
responses = {
|
||||||
404: {"model": ErrorMessage, "description": "Project or drawing not found"}
|
404: {"model": schemas.ErrorMessage, "description": "Project or drawing not found"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@router.get("",
|
@router.get("",
|
||||||
response_model=List[Drawing],
|
response_model=List[schemas.Drawing],
|
||||||
response_model_exclude_unset=True)
|
response_model_exclude_unset=True)
|
||||||
async def get_drawings(project_id: UUID):
|
async def get_drawings(project_id: UUID):
|
||||||
"""
|
"""
|
||||||
@ -49,9 +48,9 @@ async def get_drawings(project_id: UUID):
|
|||||||
|
|
||||||
@router.post("",
|
@router.post("",
|
||||||
status_code=status.HTTP_201_CREATED,
|
status_code=status.HTTP_201_CREATED,
|
||||||
response_model=Drawing,
|
response_model=schemas.Drawing,
|
||||||
responses=responses)
|
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.
|
Create a new drawing.
|
||||||
"""
|
"""
|
||||||
@ -62,7 +61,7 @@ async def create_drawing(project_id: UUID, drawing_data: Drawing):
|
|||||||
|
|
||||||
|
|
||||||
@router.get("/{drawing_id}",
|
@router.get("/{drawing_id}",
|
||||||
response_model=Drawing,
|
response_model=schemas.Drawing,
|
||||||
response_model_exclude_unset=True,
|
response_model_exclude_unset=True,
|
||||||
responses=responses)
|
responses=responses)
|
||||||
async def get_drawing(project_id: UUID, drawing_id: UUID):
|
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}",
|
@router.put("/{drawing_id}",
|
||||||
response_model=Drawing,
|
response_model=schemas.Drawing,
|
||||||
response_model_exclude_unset=True,
|
response_model_exclude_unset=True,
|
||||||
responses=responses)
|
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.
|
Update a drawing.
|
||||||
"""
|
"""
|
||||||
|
@ -23,7 +23,7 @@ from fastapi import APIRouter
|
|||||||
from fastapi.encoders import jsonable_encoder
|
from fastapi.encoders import jsonable_encoder
|
||||||
|
|
||||||
from gns3server.controller import Controller
|
from gns3server.controller import Controller
|
||||||
from gns3server.endpoints.schemas.gns3vm import GNS3VM
|
from gns3server import schemas
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ async def get_vms(engine: str):
|
|||||||
return vms
|
return vms
|
||||||
|
|
||||||
|
|
||||||
@router.get("", response_model=GNS3VM)
|
@router.get("", response_model=schemas.GNS3VM)
|
||||||
async def get_gns3vm_settings():
|
async def get_gns3vm_settings():
|
||||||
"""
|
"""
|
||||||
Return the GNS3 VM settings.
|
Return the GNS3 VM settings.
|
||||||
@ -57,8 +57,8 @@ async def get_gns3vm_settings():
|
|||||||
return Controller.instance().gns3vm.__json__()
|
return Controller.instance().gns3vm.__json__()
|
||||||
|
|
||||||
|
|
||||||
@router.put("", response_model=GNS3VM, response_model_exclude_unset=True)
|
@router.put("", response_model=schemas.GNS3VM, response_model_exclude_unset=True)
|
||||||
async def update_gns3vm_settings(gns3vm_data: GNS3VM):
|
async def update_gns3vm_settings(gns3vm_data: schemas.GNS3VM):
|
||||||
"""
|
"""
|
||||||
Update the GNS3 VM settings.
|
Update the GNS3 VM settings.
|
||||||
"""
|
"""
|
||||||
|
@ -32,8 +32,7 @@ from gns3server.controller import Controller
|
|||||||
from gns3server.controller.controller_error import ControllerError
|
from gns3server.controller.controller_error import ControllerError
|
||||||
from gns3server.controller.link import Link
|
from gns3server.controller.link import Link
|
||||||
from gns3server.utils.http_client import HTTPClient
|
from gns3server.utils.http_client import HTTPClient
|
||||||
from gns3server.endpoints.schemas.common import ErrorMessage
|
from gns3server import schemas
|
||||||
from gns3server.endpoints import schemas
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -41,7 +40,7 @@ log = logging.getLogger(__name__)
|
|||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
responses = {
|
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("",
|
@router.post("",
|
||||||
status_code=status.HTTP_201_CREATED,
|
status_code=status.HTTP_201_CREATED,
|
||||||
response_model=schemas.Link,
|
response_model=schemas.Link,
|
||||||
responses={404: {"model": ErrorMessage, "description": "Could not find project"},
|
responses={404: {"model": schemas.ErrorMessage, "description": "Could not find project"},
|
||||||
409: {"model": ErrorMessage, "description": "Could not create link"}})
|
409: {"model": schemas.ErrorMessage, "description": "Could not create link"}})
|
||||||
async def create_link(project_id: UUID, link_data: schemas.Link):
|
async def create_link(project_id: UUID, link_data: schemas.Link):
|
||||||
"""
|
"""
|
||||||
Create a new 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__()
|
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}",
|
@router.delete("/{link_id}",
|
||||||
status_code=status.HTTP_204_NO_CONTENT,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
responses=responses)
|
responses=responses)
|
||||||
@ -186,9 +160,34 @@ async def reset_link(link: Link = Depends(dep_link)):
|
|||||||
return link.__json__()
|
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)
|
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.
|
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 import force_unix_path
|
||||||
from gns3server.utils.http_client import HTTPClient
|
from gns3server.utils.http_client import HTTPClient
|
||||||
from gns3server.controller.controller_error import ControllerForbiddenError
|
from gns3server.controller.controller_error import ControllerForbiddenError
|
||||||
from gns3server.endpoints.schemas.common import ErrorMessage
|
from gns3server import schemas
|
||||||
from gns3server.endpoints import schemas
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -80,7 +79,7 @@ class NodeConcurrency(APIRoute):
|
|||||||
router = APIRouter(route_class=NodeConcurrency)
|
router = APIRouter(route_class=NodeConcurrency)
|
||||||
|
|
||||||
responses = {
|
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("",
|
@router.post("",
|
||||||
status_code=status.HTTP_201_CREATED,
|
status_code=status.HTTP_201_CREATED,
|
||||||
response_model=schemas.Node,
|
response_model=schemas.Node,
|
||||||
responses={404: {"model": ErrorMessage, "description": "Could not find project"},
|
responses={404: {"model": schemas.ErrorMessage, "description": "Could not find project"},
|
||||||
409: {"model": ErrorMessage, "description": "Could not create node"}})
|
409: {"model": schemas.ErrorMessage, "description": "Could not create node"}})
|
||||||
async def create_node(node_data: schemas.Node, project: Project = Depends(dep_project)):
|
async def create_node(node_data: schemas.Node, project: Project = Depends(dep_project)):
|
||||||
"""
|
"""
|
||||||
Create a new node.
|
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}",
|
@router.delete("/{node_id}",
|
||||||
status_code=status.HTTP_204_NO_CONTENT,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
responses={**responses,
|
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)):
|
async def delete_node(node_id: UUID, project: Project = Depends(dep_project)):
|
||||||
"""
|
"""
|
||||||
Delete a node from a 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
|
compute = node.compute
|
||||||
await websocket.accept()
|
await websocket.accept()
|
||||||
log.info(f"New client {websocket.client.host}:{websocket.client.port} has connected to controller console WebSocket")
|
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"
|
f"{node.project.id}/{node.node_type}/nodes/{node.id}/console/ws"
|
||||||
|
|
||||||
async def ws_receive(ws_console_compute):
|
async def ws_receive(ws_console_compute):
|
||||||
|
@ -37,8 +37,7 @@ from typing import List, Optional
|
|||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from gns3server.endpoints.schemas.common import ErrorMessage
|
from gns3server import schemas
|
||||||
from gns3server.endpoints import schemas
|
|
||||||
from gns3server.controller import Controller
|
from gns3server.controller import Controller
|
||||||
from gns3server.controller.project import Project
|
from gns3server.controller.project import Project
|
||||||
from gns3server.controller.controller_error import ControllerError, ControllerForbiddenError
|
from gns3server.controller.controller_error import ControllerError, ControllerForbiddenError
|
||||||
@ -51,7 +50,7 @@ from gns3server.config import Config
|
|||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
responses = {
|
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,
|
status_code=status.HTTP_201_CREATED,
|
||||||
response_model=schemas.Project,
|
response_model=schemas.Project,
|
||||||
response_model_exclude_unset=True,
|
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):
|
async def create_project(project_data: schemas.ProjectCreate):
|
||||||
"""
|
"""
|
||||||
Create a new project.
|
Create a new project.
|
||||||
@ -145,7 +144,7 @@ def get_project_stats(project: Project = Depends(dep_project)):
|
|||||||
status_code=status.HTTP_204_NO_CONTENT,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
responses={
|
responses={
|
||||||
**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)):
|
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,
|
response_model=schemas.Project,
|
||||||
responses={
|
responses={
|
||||||
**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)):
|
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,
|
response_model=schemas.Project,
|
||||||
responses={
|
responses={
|
||||||
**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)):
|
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,
|
response_model=schemas.Project,
|
||||||
responses={
|
responses={
|
||||||
**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)):
|
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 uuid import UUID
|
||||||
|
|
||||||
from gns3server.controller.project import Project
|
from gns3server.controller.project import Project
|
||||||
from gns3server.endpoints.schemas.common import ErrorMessage
|
from gns3server import schemas
|
||||||
from gns3server.endpoints import schemas
|
|
||||||
from gns3server.controller import Controller
|
from gns3server.controller import Controller
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
responses = {
|
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 fastapi.responses import FileResponse
|
||||||
|
|
||||||
from gns3server.controller import Controller
|
from gns3server.controller import Controller
|
||||||
from gns3server.endpoints.schemas.common import ErrorMessage
|
from gns3server import schemas
|
||||||
from gns3server.controller.controller_error import ControllerError, ControllerNotFoundError
|
from gns3server.controller.controller_error import ControllerError, ControllerNotFoundError
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
@ -43,7 +43,7 @@ def get_symbols():
|
|||||||
|
|
||||||
|
|
||||||
@router.get("/{symbol_id:path}/raw",
|
@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):
|
async def get_symbol(symbol_id: str):
|
||||||
"""
|
"""
|
||||||
Download a symbol file.
|
Download a symbol file.
|
||||||
|
@ -27,25 +27,20 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
from fastapi import APIRouter, Request, Response, HTTPException, status
|
from fastapi import APIRouter, Request, Response, HTTPException, status
|
||||||
from fastapi.encoders import jsonable_encoder
|
from fastapi.encoders import jsonable_encoder
|
||||||
from typing import Union, List
|
from typing import List
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from gns3server.endpoints.schemas.common import ErrorMessage
|
from gns3server import schemas
|
||||||
from gns3server.endpoints import schemas
|
|
||||||
from gns3server.controller import Controller
|
from gns3server.controller import Controller
|
||||||
|
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
responses = {
|
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",
|
@router.post("/templates",
|
||||||
status_code=status.HTTP_201_CREATED,
|
status_code=status.HTTP_201_CREATED,
|
||||||
response_model=schemas.Template)
|
response_model=schemas.Template)
|
||||||
@ -138,7 +133,7 @@ async def duplicate_template(template_id: UUID):
|
|||||||
@router.post("/projects/{project_id}/templates/{template_id}",
|
@router.post("/projects/{project_id}/templates/{template_id}",
|
||||||
response_model=schemas.Node,
|
response_model=schemas.Node,
|
||||||
status_code=status.HTTP_201_CREATED,
|
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):
|
async def create_node_from_template(project_id: UUID, template_id: UUID, template_usage: schemas.TemplateUsage):
|
||||||
"""
|
"""
|
||||||
Create a new node from a template.
|
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 -*-
|
# -*- 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
|
# 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
|
# 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
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# 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 = {
|
class Capabilities(BaseModel):
|
||||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
"""
|
||||||
"description": "Get what a server support",
|
Capabilities properties.
|
||||||
"type": "object",
|
"""
|
||||||
"required": ["version", "node_types"],
|
|
||||||
"properties": {
|
version: str = Field(..., description="Compute version number")
|
||||||
"version": {
|
node_types: List[NodeType] = Field(..., description="Node types supported by the compute")
|
||||||
"description": "Version number",
|
platform: str = Field(..., description="Platform where the compute is running")
|
||||||
"type": ["string", "null"],
|
cpus: int = Field(..., description="Number of CPUs on this compute")
|
||||||
},
|
memory: int = Field(..., description="Amount of memory on this compute")
|
||||||
"node_types": {
|
disk_size: int = Field(..., description="Disk size on this compute")
|
||||||
"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
|
|
||||||
}
|
|
||||||
|
@ -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 .templates import Category, TemplateBase
|
||||||
from .cloud_nodes import EthernetPort, TAPPort, UDPPort
|
from .cloud_nodes import EthernetPort, TAPPort, UDPPort, CloudConsoleType
|
||||||
|
|
||||||
from pydantic import Field
|
from pydantic import Field
|
||||||
from typing import Optional, Union, List
|
from typing import Optional, Union, List
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
from .nodes import NodeType
|
|
||||||
|
|
||||||
|
|
||||||
class RemoteConsoleType(str, Enum):
|
class CloudTemplate(TemplateBase):
|
||||||
"""
|
|
||||||
Supported remote console types for cloud nodes.
|
|
||||||
"""
|
|
||||||
|
|
||||||
none = "none"
|
|
||||||
telnet = "telnet"
|
|
||||||
vnc = "vnc"
|
|
||||||
spice = "spice"
|
|
||||||
http = "http"
|
|
||||||
https = "https"
|
|
||||||
|
|
||||||
|
|
||||||
class CloudTemplateBase(TemplateBase):
|
|
||||||
|
|
||||||
category: Optional[Category] = "guest"
|
category: Optional[Category] = "guest"
|
||||||
default_name_format: Optional[str] = "Cloud{0}"
|
default_name_format: Optional[str] = "Cloud{0}"
|
||||||
@ -47,28 +31,5 @@ class CloudTemplateBase(TemplateBase):
|
|||||||
ports_mapping: List[Union[EthernetPort, TAPPort, UDPPort]] = []
|
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_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_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_type: Optional[CloudConsoleType] = Field("none", description="Remote console type")
|
||||||
remote_console_path: Optional[str] = Field("/", description="Path of the remote web interface")
|
remote_console_http_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]
|
|
@ -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]
|
compute_id: Union[str, UUID]
|
||||||
name: str
|
name: str
|
||||||
connected: bool = Field(..., description="Whether the controller is connected to the compute or not")
|
connected: Optional[bool] = Field(None, 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)
|
cpu_usage_percent: Optional[float] = Field(None, 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)
|
memory_usage_percent: Optional[float] = Field(None, 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)
|
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")
|
last_error: Optional[str] = Field(None, description="Last error found on the compute")
|
||||||
capabilities: Capabilities
|
capabilities: Optional[Capabilities] = None
|
||||||
|
|
||||||
|
|
||||||
class AutoIdlePC(BaseModel):
|
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
|
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):
|
class DynamipsAdapters(str, Enum):
|
||||||
"""
|
"""
|
||||||
Supported Dynamips Network Modules.
|
Supported Dynamips Network Modules.
|
||||||
@ -56,6 +70,7 @@ class DynamipsAdapters(str, Enum):
|
|||||||
gt96100_fe = "GT96100-FE"
|
gt96100_fe = "GT96100-FE"
|
||||||
leopard_2fe = "Leopard-2FE"
|
leopard_2fe = "Leopard-2FE"
|
||||||
|
|
||||||
|
|
||||||
class DynamipsWics(str, Enum):
|
class DynamipsWics(str, Enum):
|
||||||
"""
|
"""
|
||||||
Supported Dynamips WICs.
|
Supported Dynamips WICs.
|
||||||
@ -108,7 +123,7 @@ class DynamipsBase(BaseModel):
|
|||||||
node_id: Optional[UUID] = None
|
node_id: Optional[UUID] = None
|
||||||
name: Optional[str] = None
|
name: Optional[str] = None
|
||||||
dynamips_id: Optional[int] = Field(None, description="Dynamips internal ID")
|
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")
|
ram: Optional[int] = Field(None, description="Amount of RAM in MB")
|
||||||
nvram: Optional[int] = Field(None, description="Amount of NVRAM in KB")
|
nvram: Optional[int] = Field(None, description="Amount of NVRAM in KB")
|
||||||
image: Optional[Path] = Field(None, description="Path to the IOS image")
|
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")
|
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}$")
|
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")
|
system_id: Optional[str] = Field(None, description="System ID")
|
||||||
slot0: Optional[str] = Field(None, description="Network module slot 0")
|
slot0: Optional[DynamipsAdapters] = Field(None, description="Network module slot 0")
|
||||||
slot1: Optional[str] = Field(None, description="Network module slot 1")
|
slot1: Optional[DynamipsAdapters] = Field(None, description="Network module slot 1")
|
||||||
slot2: Optional[str] = Field(None, description="Network module slot 2")
|
slot2: Optional[DynamipsAdapters] = Field(None, description="Network module slot 2")
|
||||||
slot3: Optional[str] = Field(None, description="Network module slot 3")
|
slot3: Optional[DynamipsAdapters] = Field(None, description="Network module slot 3")
|
||||||
slot4: Optional[str] = Field(None, description="Network module slot 4")
|
slot4: Optional[DynamipsAdapters] = Field(None, description="Network module slot 4")
|
||||||
slot5: Optional[str] = Field(None, description="Network module slot 5")
|
slot5: Optional[DynamipsAdapters] = Field(None, description="Network module slot 5")
|
||||||
slot6: Optional[str] = Field(None, description="Network module slot 6")
|
slot6: Optional[DynamipsAdapters] = Field(None, description="Network module slot 6")
|
||||||
wic0: Optional[str] = Field(None, description="Network module WIC slot 0")
|
wic0: Optional[DynamipsWics] = Field(None, description="Network module WIC slot 0")
|
||||||
wic1: Optional[str] = Field(None, description="Network module WIC slot 1")
|
wic1: Optional[DynamipsWics] = Field(None, description="Network module WIC slot 1")
|
||||||
wic2: Optional[str] = Field(None, description="Network module WIC slot 2")
|
wic2: Optional[DynamipsWics] = Field(None, description="Network module WIC slot 2")
|
||||||
npe: Optional[DynamipsNPE] = Field(None, description="NPE model")
|
npe: Optional[DynamipsNPE] = Field(None, description="NPE model")
|
||||||
midplane: Optional[DynamipsMidplane] = Field(None, description="Midplane model")
|
midplane: Optional[DynamipsMidplane] = Field(None, description="Midplane model")
|
||||||
sensors: Optional[List] = Field(None, description="Temperature sensors")
|
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 .templates import Category, TemplateBase
|
||||||
|
from .iou_nodes import ConsoleType
|
||||||
|
|
||||||
from pydantic import Field
|
from pydantic import Field
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional, Union
|
from typing import Optional
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
from .nodes import NodeType
|
|
||||||
|
|
||||||
|
|
||||||
class ConsoleType(str, Enum):
|
class IOUTemplate(TemplateBase):
|
||||||
"""
|
|
||||||
Supported console types for IOU nodes
|
|
||||||
"""
|
|
||||||
|
|
||||||
none = "none"
|
|
||||||
telnet = "telnet"
|
|
||||||
|
|
||||||
|
|
||||||
class IOUTemplateBase(TemplateBase):
|
|
||||||
|
|
||||||
category: Optional[Category] = "router"
|
category: Optional[Category] = "router"
|
||||||
default_name_format: Optional[str] = "IOU{0}"
|
default_name_format: Optional[str] = "IOU{0}"
|
||||||
symbol: Optional[str] = ":/symbols/multilayer_switch.svg"
|
symbol: Optional[str] = ":/symbols/multilayer_switch.svg"
|
||||||
|
|
||||||
path: Path = Field(..., description="Path of IOU executable")
|
path: Path = Field(..., description="Path of IOU executable")
|
||||||
ethernet_adapters: Optional[int] = Field(2, description="Number of ethernet adapters")
|
ethernet_adapters: Optional[int] = Field(2, description="Number of ethernet adapters")
|
||||||
serial_adapters: Optional[int] = Field(2, description="Number of serial 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_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")
|
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):
|
class Supplier(BaseModel):
|
||||||
|
|
||||||
logo: str = Field(..., description="Path to the project supplier logo")
|
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):
|
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"
|
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):
|
class QemuBase(BaseModel):
|
||||||
"""
|
"""
|
||||||
Common Qemu node properties.
|
Common Qemu node properties.
|
||||||
@ -121,16 +169,16 @@ class QemuBase(BaseModel):
|
|||||||
aux_type: Optional[QemuConsoleType] = Field(None, description="Auxiliary console type")
|
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: 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_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: 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_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: 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_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: 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_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: Optional[Path] = Field(None, description="QEMU cdrom image path")
|
||||||
cdrom_image_md5sum: Optional[str] = Field(None, description="QEMU cdrom image checksum")
|
cdrom_image_md5sum: Optional[str] = Field(None, description="QEMU cdrom image checksum")
|
||||||
bios_image: Optional[Path] = Field(None, description="QEMU bios image path")
|
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: Optional[Path] = Field(None, description="QEMU kernel image path")
|
||||||
kernel_image_md5sum: Optional[str] = Field(None, description="QEMU kernel image checksum")
|
kernel_image_md5sum: Optional[str] = Field(None, description="QEMU kernel image checksum")
|
||||||
kernel_command_line: Optional[str] = Field(None, description="QEMU kernel command line")
|
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")
|
ram: Optional[int] = Field(None, description="Amount of RAM in MB")
|
||||||
cpus: Optional[int] = Field(None, ge=1, le=255, description="Number of vCPUs")
|
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")
|
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")
|
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})$")
|
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)")
|
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")
|
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
|
symbol: Optional[str] = None
|
||||||
builtin: Optional[bool] = None
|
builtin: Optional[bool] = None
|
||||||
template_type: Optional[NodeType] = None
|
template_type: Optional[NodeType] = None
|
||||||
usage: Optional[str] = None
|
|
||||||
compute_id: Optional[str] = None
|
compute_id: Optional[str] = None
|
||||||
|
usage: Optional[str] = ""
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
extra = "allow"
|
extra = "allow"
|
@ -19,136 +19,66 @@
|
|||||||
# This file contains the validation for checking a .gns3 file
|
# This file contains the validation for checking a .gns3 file
|
||||||
#
|
#
|
||||||
|
|
||||||
from gns3server.schemas.compute import COMPUTE_OBJECT_SCHEMA
|
from .computes import Compute
|
||||||
from gns3server.schemas.drawing import DRAWING_OBJECT_SCHEMA
|
from .drawings import Drawing
|
||||||
from gns3server.schemas.link import LINK_OBJECT_SCHEMA
|
from .links import Link
|
||||||
from gns3server.schemas.node import NODE_OBJECT_SCHEMA
|
from .nodes import Node
|
||||||
from gns3server.schemas.project import VARIABLES_OBJECT_SCHEMA
|
|
||||||
from gns3server.schemas.project import SUPPLIER_OBJECT_SCHEMA
|
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 = {
|
class TopologyType(str, Enum):
|
||||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
|
||||||
"description": "The topology",
|
topology = "topology"
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"project_id": {
|
class TopologyContent(BaseModel):
|
||||||
"description": "Project UUID",
|
|
||||||
"type": "string",
|
computes: List[Compute] = Field(..., description="List of computes")
|
||||||
"minLength": 36,
|
drawings: List[Drawing] = Field(..., description="List of drawings")
|
||||||
"maxLength": 36,
|
links: List[Link] = Field(..., description="List of links")
|
||||||
"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: List[Node] = Field(..., description="List of nodes")
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"description": "Type of file. It's always topology",
|
class Topology(BaseModel):
|
||||||
"enum": ["topology"]
|
|
||||||
},
|
project_id: UUID = Field(..., description="Project UUID")
|
||||||
"auto_start": {
|
type: TopologyType = Field(..., description="Type of file. It's always topology")
|
||||||
"description": "Start the topology when opened",
|
revision: int = Field(..., description="Version of the .gns3 specification")
|
||||||
"type": "boolean"
|
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")
|
||||||
"auto_close": {
|
topology: TopologyContent = Field(..., description="Topology content")
|
||||||
"description": "Close the topology when no client is connected",
|
auto_start: Optional[bool] = Field(None, description="Start the topology when opened")
|
||||||
"type": "boolean"
|
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")
|
||||||
"auto_open": {
|
scene_width: Optional[int] = Field(None, description="Width of the drawing area")
|
||||||
"description": "Open the topology with GNS3",
|
zoom: Optional[int] = Field(None, description="Zoom of the drawing area")
|
||||||
"type": "boolean"
|
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")
|
||||||
"revision": {
|
show_grid: Optional[bool] = Field(None, description="Show the grid on the drawing area")
|
||||||
"description": "Version of the .gns3 specification.",
|
grid_size: Optional[int] = Field(None, description="Grid size for the drawing area for nodes")
|
||||||
"type": "integer"
|
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")
|
||||||
"version": {
|
supplier: Optional[Supplier] = Field(None, description="Supplier of the project")
|
||||||
"description": "Version of the GNS3 software which have update the file for the last time",
|
variables: Optional[List[Variable]] = Field(None, description="Variables required to run the project")
|
||||||
"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
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
import jsonschema
|
|
||||||
import json
|
import json
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
with open(sys.argv[1]) as f:
|
with open(sys.argv[1]) as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
jsonschema.validate(data, TOPOLOGY_SCHEMA)
|
Topology.parse_obj(data)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
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
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
VERSION_SCHEMA = {
|
from pydantic import BaseModel, Field
|
||||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
from typing import Optional
|
||||||
"type": "object",
|
|
||||||
'required': ['version'],
|
|
||||||
"additionalProperties": False,
|
class Version(BaseModel):
|
||||||
"properties": {
|
|
||||||
"version": {
|
version: str = Field(..., description="Version number")
|
||||||
"description": "Version number",
|
local: Optional[bool] = Field(None, description="Whether this is a local server or not")
|
||||||
"type": "string",
|
|
||||||
},
|
|
||||||
"local": {
|
|
||||||
"description": "Whether this is a local server or not",
|
|
||||||
"type": "boolean",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -42,6 +42,16 @@ class VirtualBoxOnCloseAction(str, Enum):
|
|||||||
save_vm_state = "save_vm_state"
|
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):
|
class VirtualBoxBase(BaseModel):
|
||||||
"""
|
"""
|
||||||
Common VirtualBox node properties.
|
Common VirtualBox node properties.
|
||||||
@ -54,14 +64,14 @@ class VirtualBoxBase(BaseModel):
|
|||||||
usage: Optional[str] = Field(None, description="How to use the node")
|
usage: Optional[str] = Field(None, description="How to use the node")
|
||||||
# 36 adapters is the maximum given by the ICH9 chipset in VirtualBox
|
# 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")
|
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")
|
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: Optional[int] = Field(None, gt=0, le=65535, description="Console TCP port")
|
||||||
console_type: Optional[VirtualBoxConsoleType] = Field(None, description="Console type")
|
console_type: Optional[VirtualBoxConsoleType] = Field(None, description="Console type")
|
||||||
ram: Optional[int] = Field(None, ge=0, le=65535, description="Amount of RAM in MB")
|
ram: Optional[int] = Field(None, ge=0, le=65535, description="Amount of RAM in MB")
|
||||||
headless: Optional[bool] = Field(None, description="Headless mode")
|
headless: Optional[bool] = Field(None, description="Headless mode")
|
||||||
on_close: Optional[VirtualBoxOnCloseAction] = Field(None, description="Action to execute on the VM is closed")
|
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):
|
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"
|
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):
|
class VMwareBase(BaseModel):
|
||||||
"""
|
"""
|
||||||
Common VMware node properties.
|
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")
|
on_close: Optional[VMwareOnCloseAction] = Field(None, description="Action to execute on the VM is closed")
|
||||||
# 10 adapters is the maximum supported by VMware VMs.
|
# 10 adapters is the maximum supported by VMware VMs.
|
||||||
adapters: Optional[int] = Field(None, ge=0, le=10, description="Number of adapters")
|
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")
|
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")
|
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…
x
Reference in New Issue
Block a user