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 aiohttp
import jsonschema
import copy
from ..config import Config
from .project import Project
@ -181,6 +182,20 @@ class Controller:
self.save()
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):
#self._appliances = {}

View File

@ -115,7 +115,7 @@ class ApplianceHandler:
@Route.delete(
r"/appliances/{appliance_id}",
parameters={
"appliance_id": "Node UUID"
"appliance_id": "appliance UUID"
},
status_codes={
204: "Appliance deleted",
@ -140,6 +140,25 @@ class ApplianceHandler:
controller = Controller.instance()
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(
r"/projects/{project_id}/appliances/{appliance_id}",
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
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):
params = {"name": "Cisco c7200 appliance",