1
0
mirror of https://github.com/GNS3/gns3-server synced 2024-12-24 15:58:08 +00:00

Support to duplicate an appliance.

This commit is contained in:
grossmj 2018-11-18 17:05:16 +07:00
parent 9b83b087cb
commit bd657c0167
3 changed files with 64 additions and 1 deletions

View File

@ -24,6 +24,7 @@ import shutil
import asyncio import asyncio
import aiohttp import aiohttp
import jsonschema import jsonschema
import copy
from ..config import Config from ..config import Config
from .project import Project from .project import Project
@ -181,6 +182,20 @@ class Controller:
self.save() self.save()
self.notification.controller_emit("appliance.deleted", appliance.__json__()) self.notification.controller_emit("appliance.deleted", appliance.__json__())
def duplicate_appliance(self, appliance_id):
"""
Duplicates an appliance.
:param appliance_id: appliance identifier
"""
appliance = self.get_appliance(appliance_id)
if appliance.builtin:
raise aiohttp.web.HTTPConflict(text="Appliance ID {} cannot be duplicated because it is a builtin".format(appliance_id))
appliance_settings = copy.deepcopy(appliance.settings)
del appliance_settings["appliance_id"]
return self.add_appliance(appliance_settings)
def load_appliances(self): def load_appliances(self):
#self._appliances = {} #self._appliances = {}

View File

@ -115,7 +115,7 @@ class ApplianceHandler:
@Route.delete( @Route.delete(
r"/appliances/{appliance_id}", r"/appliances/{appliance_id}",
parameters={ parameters={
"appliance_id": "Node UUID" "appliance_id": "appliance UUID"
}, },
status_codes={ status_codes={
204: "Appliance deleted", 204: "Appliance deleted",
@ -140,6 +140,25 @@ class ApplianceHandler:
controller = Controller.instance() controller = Controller.instance()
response.json([c for c in controller.appliances.values()]) response.json([c for c in controller.appliances.values()])
@Route.post(
r"/appliances/{appliance_id}/duplicate",
parameters={
"appliance_id": "Appliance UUID"
},
status_codes={
201: "Appliance duplicated",
400: "Invalid request",
404: "Appliance doesn't exist"
},
description="Duplicate an appliance",
output=APPLIANCE_OBJECT_SCHEMA)
async def duplicate(request, response):
controller = Controller.instance()
appliance = controller.duplicate_appliance(request.match_info["appliance_id"])
response.set_status(201)
response.json(appliance)
@Route.post( @Route.post(
r"/projects/{project_id}/appliances/{appliance_id}", r"/projects/{project_id}/appliances/{appliance_id}",
description="Create a node from an appliance", description="Create a node from an appliance",

View File

@ -210,6 +210,35 @@ def test_appliance_delete(http_controller, controller):
assert len(controller.appliances) == 0 assert len(controller.appliances) == 0
def test_appliance_duplicate(http_controller, controller):
appliance_id = str(uuid.uuid4())
params = {"appliance_id": appliance_id,
"base_script_file": "vpcs_base_config.txt",
"category": "guest",
"console_auto_start": False,
"console_type": "telnet",
"default_name_format": "PC{0}",
"name": "VPCS_TEST",
"compute_id": "local",
"symbol": ":/symbols/vpcs_guest.svg",
"appliance_type": "vpcs"}
response = http_controller.post("/appliances", params)
assert response.status == 201
response = http_controller.post("/appliances/{}/duplicate".format(appliance_id), example=True)
assert response.status == 201
assert response.json["appliance_id"] != appliance_id
params.pop("appliance_id")
for param, value in params.items():
assert response.json[param] == value
response = http_controller.get("/appliances")
assert len(response.json) == 2
assert len(controller.appliances) == 2
def test_c7200_dynamips_appliance_create(http_controller): def test_c7200_dynamips_appliance_create(http_controller):
params = {"name": "Cisco c7200 appliance", params = {"name": "Cisco c7200 appliance",