diff --git a/gns3server/controller/__init__.py b/gns3server/controller/__init__.py index c59f32a4..0b3cd929 100644 --- a/gns3server/controller/__init__.py +++ b/gns3server/controller/__init__.py @@ -85,8 +85,7 @@ class Controller: log.critical("Cannot load %s: %s", self._config_file, str(e)) return for c in data["computes"]: - compute_id = c.pop("compute_id") - yield from self.add_compute(compute_id, **c) + yield from self.add_compute(**c) def is_enabled(self): """ @@ -96,26 +95,28 @@ class Controller: return Config.instance().get_section_config("Server").getboolean("controller") @asyncio.coroutine - def add_compute(self, compute_id, **kwargs): + def add_compute(self, **kwargs): """ Add a server to the dictionary of compute servers controlled by this controller :param compute_id: Compute server identifier :param kwargs: See the documentation of Compute """ + compute_id = kwargs.pop("compute_id", None) if compute_id not in self._computes: # We disallow to create from the outside the if compute_id == 'local': return None - compute_server = Compute(compute_id=compute_id, controller=self, **kwargs) - self._computes[compute_id] = compute_server + compute = Compute(compute_id=compute_id, controller=self, **kwargs) + self._computes[compute.id] = compute self.save() - self.notification.emit("compute.created", compute_server.__json__()) + self.notification.emit("compute.created", compute.__json__()) + return compute else: self.notification.emit("compute.updated", self._computes[compute_id].__json__()) - return self._computes[compute_id] + return self._computes[compute_id] @asyncio.coroutine def delete_compute(self, compute_id): @@ -125,6 +126,7 @@ class Controller: """ compute = self.get_compute(compute_id) del self._computes[compute_id] + self.save() self.notification.emit("compute.deleted", compute.__json__()) @property diff --git a/gns3server/controller/compute.py b/gns3server/controller/compute.py index 9f6e83c3..6d0b1b75 100644 --- a/gns3server/controller/compute.py +++ b/gns3server/controller/compute.py @@ -18,6 +18,7 @@ import aiohttp import asyncio import json +import uuid from ..utils import parse_version from ..controller.controller_error import ControllerError @@ -38,10 +39,15 @@ class Compute: A GNS3 compute. """ - def __init__(self, compute_id, controller=None, protocol="http", host="localhost", port=8000, user=None, password=None, name=None): + def __init__(self, compute_id, controller=None, protocol="http", host="localhost", port=3080, user=None, password=None, name=None): assert controller is not None log.info("Create compute %s", compute_id) - self._id = compute_id + + if compute_id is None: + self._id = str(uuid.uuid4()) + else: + self._id = compute_id + self.protocol = protocol self.host = host self.port = port diff --git a/tests/controller/test_compute.py b/tests/controller/test_compute.py index ad521e0d..0c340c25 100644 --- a/tests/controller/test_compute.py +++ b/tests/controller/test_compute.py @@ -47,9 +47,10 @@ def test_name(): assert c.name == "Local" c = Compute("world", protocol="https", host="example.com", port=84, controller=MagicMock(), name="hello") assert c.name == "hello" - c = Compute("world", protocol="https", host="example.com", port=84, controller=MagicMock(),user="azertyuiopqsdfghjklkm") + c = Compute("world", protocol="https", host="example.com", port=84, controller=MagicMock(), user="azertyuiopqsdfghjklkm") assert c.name == "https://azertyuiopq...@example.com:84" + def test_compute_local(compute): """ If the compute is local but the compute id is local diff --git a/tests/controller/test_controller.py b/tests/controller/test_controller.py index 43fcda86..032d51b6 100644 --- a/tests/controller/test_controller.py +++ b/tests/controller/test_controller.py @@ -77,27 +77,30 @@ def test_isEnabled(controller): def test_addCompute(controller, controller_config_path, async_run): controller._notification = MagicMock() - c = async_run(controller.add_compute("test1")) + c = async_run(controller.add_compute(compute_id="test1")) controller._notification.emit.assert_called_with("compute.created", c.__json__()) assert len(controller.computes) == 1 - async_run(controller.add_compute("test1")) + async_run(controller.add_compute(compute_id="test1")) controller._notification.emit.assert_called_with("compute.updated", c.__json__()) assert len(controller.computes) == 1 - async_run(controller.add_compute("test2")) + async_run(controller.add_compute(compute_id="test2")) assert len(controller.computes) == 2 def test_deleteCompute(controller, controller_config_path, async_run): - c = async_run(controller.add_compute("test1")) + c = async_run(controller.add_compute(compute_id="test1")) assert len(controller.computes) == 1 controller._notification = MagicMock() async_run(controller.delete_compute("test1")) assert len(controller.computes) == 0 controller._notification.emit.assert_called_with("compute.deleted", c.__json__()) + with open(controller_config_path) as f: + data = json.load(f) + assert len(data["computes"]) == 0 def test_addComputeConfigFile(controller, controller_config_path, async_run): - async_run(controller.add_compute("test1")) + async_run(controller.add_compute(compute_id="test1")) assert len(controller.computes) == 1 with open(controller_config_path) as f: data = json.load(f) @@ -105,7 +108,7 @@ def test_addComputeConfigFile(controller, controller_config_path, async_run): { 'compute_id': 'test1', 'host': 'localhost', - 'port': 8000, + 'port': 3080, 'protocol': 'http', 'user': None, 'password': None @@ -114,7 +117,7 @@ def test_addComputeConfigFile(controller, controller_config_path, async_run): def test_getCompute(controller, async_run): - compute = async_run(controller.add_compute("test1")) + compute = async_run(controller.add_compute(compute_id="test1")) assert controller.get_compute("test1") == compute with pytest.raises(aiohttp.web.HTTPNotFound): diff --git a/tests/handlers/api/controller/test_compute.py b/tests/handlers/api/controller/test_compute.py index 91a71d50..0f9305ae 100644 --- a/tests/handlers/api/controller/test_compute.py +++ b/tests/handlers/api/controller/test_compute.py @@ -16,7 +16,27 @@ # along with this program. If not, see . -def test_compute_create(http_controller, controller): +def test_compute_create_without_id(http_controller, controller): + + params = { + "protocol": "http", + "host": "example.com", + "port": 84, + "user": "julien", + "password": "secure" + } + response = http_controller.post("/computes", params, example=True) + assert response.status == 201 + assert response.route == "/computes" + assert response.json["user"] == "julien" + assert response.json["compute_id"] is not None + assert "password" not in response.json + + assert len(controller.computes) == 1 + assert controller.computes[response.json["compute_id"]].host == "example.com" + + +def test_compute_create_with_id(http_controller, controller): params = { "compute_id": "my_compute_id", @@ -36,6 +56,7 @@ def test_compute_create(http_controller, controller): assert controller.computes["my_compute_id"].host == "example.com" + def test_compute_get(http_controller, controller): params = {