mirror of
https://github.com/GNS3/gns3-server
synced 2024-12-29 02:08:10 +00:00
parent
6463007ef1
commit
f5e5cf5059
@ -15,12 +15,19 @@
|
||||
# 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 os
|
||||
import sys
|
||||
import json
|
||||
import asyncio
|
||||
import aiohttp
|
||||
|
||||
from ..config import Config
|
||||
from .project import Project
|
||||
from .compute import Compute
|
||||
from ..version import __version__
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Controller:
|
||||
@ -30,6 +37,48 @@ class Controller:
|
||||
self._computes = {}
|
||||
self._projects = {}
|
||||
|
||||
if sys.platform.startswith("win"):
|
||||
config_path = os.path.join(os.path.expandvars("%APPDATA%"), "GNS3")
|
||||
else:
|
||||
config_path = os.path.join(os.path.expanduser("~"), ".config", "GNS3")
|
||||
self._config_file = os.path.join(config_path, "gns3_controller.conf")
|
||||
|
||||
def save(self):
|
||||
"""
|
||||
Save the controller configuration on disk
|
||||
"""
|
||||
data = {
|
||||
"computes": [ {
|
||||
"host": c.host,
|
||||
"port": c.port,
|
||||
"protocol": c.protocol,
|
||||
"user": c.user,
|
||||
"password": c.password,
|
||||
"compute_id": c.id
|
||||
} for c in self._computes.values() ],
|
||||
"version": __version__
|
||||
}
|
||||
os.makedirs(os.path.dirname(self._config_file), exist_ok=True)
|
||||
with open(self._config_file, 'w+') as f:
|
||||
json.dump(data, f, indent=4)
|
||||
|
||||
@asyncio.coroutine
|
||||
def load(self):
|
||||
"""
|
||||
Reload the controller configuration from disk
|
||||
"""
|
||||
if not os.path.exists(self._config_file):
|
||||
return
|
||||
try:
|
||||
with open(self._config_file) as f:
|
||||
data = json.load(f)
|
||||
except OSError as e:
|
||||
log.critical("Can not load %s: %s", self._config_file, str(e))
|
||||
return
|
||||
for c in data["computes"]:
|
||||
compute_id = c.pop("compute_id")
|
||||
yield from self.addCompute(compute_id, **c)
|
||||
|
||||
def isEnabled(self):
|
||||
"""
|
||||
:returns: True if current instance is the controller
|
||||
@ -47,6 +96,7 @@ class Controller:
|
||||
if compute_id not in self._computes:
|
||||
compute = Compute(compute_id=compute_id, controller=self, **kwargs)
|
||||
self._computes[compute_id] = compute
|
||||
self.save()
|
||||
return self._computes[compute_id]
|
||||
|
||||
@property
|
||||
|
@ -87,6 +87,20 @@ class Compute:
|
||||
"""
|
||||
return self._host
|
||||
|
||||
@property
|
||||
def port(self):
|
||||
"""
|
||||
:returns: Compute port (integer)
|
||||
"""
|
||||
return self._port
|
||||
|
||||
@property
|
||||
def protocol(self):
|
||||
"""
|
||||
:returns: Compute protocol (string)
|
||||
"""
|
||||
return self._protocol
|
||||
|
||||
@property
|
||||
def user(self):
|
||||
return self._user
|
||||
|
@ -26,7 +26,6 @@ import datetime
|
||||
import sys
|
||||
import locale
|
||||
import argparse
|
||||
import asyncio
|
||||
|
||||
from gns3server.web.web_server import WebServer
|
||||
from gns3server.web.logger import init_logger
|
||||
@ -35,6 +34,7 @@ from gns3server.config import Config
|
||||
from gns3server.compute.project import Project
|
||||
from gns3server.crash_report import CrashReport
|
||||
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -34,6 +34,8 @@ from .request_handler import RequestHandler
|
||||
from ..config import Config
|
||||
from ..compute import MODULES
|
||||
from ..compute.port_manager import PortManager
|
||||
from ..controller import Controller
|
||||
|
||||
|
||||
# do not delete this import
|
||||
import gns3server.handlers
|
||||
@ -198,6 +200,9 @@ class WebServer:
|
||||
# Asyncio will raise error if coroutine is not called
|
||||
self._loop.set_debug(True)
|
||||
|
||||
if server_config.getboolean("controller"):
|
||||
asyncio.async(Controller.instance().load())
|
||||
|
||||
for key, val in os.environ.items():
|
||||
log.debug("ENV %s=%s", key, val)
|
||||
|
||||
|
@ -174,9 +174,16 @@ def ethernet_device():
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def controller():
|
||||
def controller_config_path(tmpdir):
|
||||
return str(tmpdir / "config" / "gns3_controller.conf")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def controller(tmpdir, controller_config_path):
|
||||
Controller._instance = None
|
||||
return Controller.instance()
|
||||
controller = Controller.instance()
|
||||
controller._config_file = controller_config_path
|
||||
return controller
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -15,8 +15,10 @@
|
||||
# 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 pytest
|
||||
import os
|
||||
import uuid
|
||||
import json
|
||||
import pytest
|
||||
import aiohttp
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
@ -25,6 +27,44 @@ from gns3server.controller import Controller
|
||||
from gns3server.controller.compute import Compute
|
||||
from gns3server.controller.project import Project
|
||||
from gns3server.config import Config
|
||||
from gns3server.version import __version__
|
||||
|
||||
|
||||
def test_save(controller, controller_config_path):
|
||||
controller.save()
|
||||
assert os.path.exists(controller_config_path)
|
||||
with open(controller_config_path) as f:
|
||||
data = json.load(f)
|
||||
assert data["computes"] == []
|
||||
assert data["version"] == __version__
|
||||
|
||||
|
||||
def test_load(controller, controller_config_path, async_run):
|
||||
controller.save()
|
||||
with open(controller_config_path) as f:
|
||||
data = json.load(f)
|
||||
data["computes"] = [
|
||||
{
|
||||
"host": "localhost",
|
||||
"port": 8000,
|
||||
"protocol": "http",
|
||||
"user": "admin",
|
||||
"password": "root",
|
||||
"compute_id": "test1"
|
||||
}
|
||||
]
|
||||
with open(controller_config_path, "w+") as f:
|
||||
json.dump(data, f)
|
||||
async_run(controller.load())
|
||||
assert len(controller.computes) == 1
|
||||
assert controller.computes["test1"].__json__() == {
|
||||
"compute_id": "test1",
|
||||
"connected": False,
|
||||
"host": "localhost",
|
||||
"port": 8000,
|
||||
"protocol": "http",
|
||||
"user": "admin"
|
||||
}
|
||||
|
||||
|
||||
def test_isEnabled(controller):
|
||||
@ -34,7 +74,7 @@ def test_isEnabled(controller):
|
||||
assert controller.isEnabled()
|
||||
|
||||
|
||||
def test_addCompute(controller, async_run):
|
||||
def test_addCompute(controller, controller_config_path, async_run):
|
||||
async_run(controller.addCompute("test1"))
|
||||
assert len(controller.computes) == 1
|
||||
async_run(controller.addCompute("test1"))
|
||||
@ -42,9 +82,24 @@ def test_addCompute(controller, async_run):
|
||||
async_run(controller.addCompute("test2"))
|
||||
assert len(controller.computes) == 2
|
||||
|
||||
def test_addComputeConfigFile(controller, controller_config_path, async_run):
|
||||
async_run(controller.addCompute("test1"))
|
||||
assert len(controller.computes) == 1
|
||||
with open(controller_config_path) as f:
|
||||
data = json.load(f)
|
||||
assert data["computes"] == [
|
||||
{
|
||||
'compute_id': 'test1',
|
||||
'host': 'localhost',
|
||||
'port': 8000,
|
||||
'protocol': 'http',
|
||||
'user': None,
|
||||
'password': None
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
def test_getCompute(controller, async_run):
|
||||
|
||||
compute = async_run(controller.addCompute("test1"))
|
||||
|
||||
assert controller.getCompute("test1") == compute
|
||||
|
Loading…
Reference in New Issue
Block a user