1
0
mirror of https://github.com/GNS3/gns3-server synced 2024-11-28 03:08:14 +00:00

Project global variables

This commit is contained in:
ziajka 2018-05-04 14:34:44 +02:00
parent 80958e8a6d
commit e267f8a8b8
9 changed files with 167 additions and 8 deletions

1
.gitignore vendored
View File

@ -39,6 +39,7 @@ nosetests.xml
.project
.pydevproject
.settings
.vscode
# Pycharm
.idea

View File

@ -325,6 +325,10 @@ class DockerVM(BaseNode):
# Give the information to the container the list of volume path mounted
params["Env"].append("GNS3_VOLUMES={}".format(":".join(self._volumes)))
if self.project.variables:
for var in self.project.variables:
params["Env"].append("{}={}".format(var["name"], var.get('value', '')))
if self._environment:
for e in self._environment.strip().split("\n"):
e = e.strip()

View File

@ -46,7 +46,7 @@ class Project:
:param path: path of the project. (None use the standard directory)
"""
def __init__(self, name=None, project_id=None, path=None):
def __init__(self, name=None, project_id=None, path=None, variables=None):
self._name = name
if project_id:
@ -61,6 +61,7 @@ class Project:
self._nodes = set()
self._used_tcp_ports = set()
self._used_udp_ports = set()
self._variables = variables
if path is None:
location = get_default_project_directory()
@ -83,7 +84,8 @@ class Project:
return {
"name": self._name,
"project_id": self._id
"project_id": self._id,
"variables": self._variables
}
def _config(self):
@ -131,6 +133,14 @@ class Project:
return self._nodes
@property
def variables(self):
return self._variables
@variables.setter
def variables(self, variables):
self._variables = variables
def record_tcp_port(self, port):
"""
Associate a reserved TCP port number with this project.

View File

@ -68,7 +68,7 @@ class Project:
def __init__(self, name=None, project_id=None, path=None, controller=None, status="opened",
filename=None, auto_start=False, auto_open=False, auto_close=True,
scene_height=1000, scene_width=2000, zoom=100, show_layers=False, snap_to_grid=False, show_grid=False,
grid_size=0, show_interface_labels=False):
grid_size=0, show_interface_labels=False, variables=None, supplier=None):
self._controller = controller
assert name is not None
@ -85,6 +85,9 @@ class Project:
self._show_grid = show_grid
self._grid_size = grid_size
self._show_interface_labels = show_interface_labels
self._variables = variables
self._supplier = supplier
self._loading = False
# Disallow overwrite of existing project
@ -266,6 +269,36 @@ class Project:
"""
self._show_interface_labels = show_interface_labels
@property
def variables(self):
"""
Variables applied to the project
:return: list
"""
return self._variables
@variables.setter
def variables(self, variables):
"""
Setter for variables applied to the project
"""
self._variables = variables
@property
def supplier(self):
"""
Supplier of the project
:return: dict
"""
return self._supplier
@supplier.setter
def supplier(self, supplier):
"""
Setter for supplier of the project
"""
self._supplier = supplier
@property
def auto_start(self):
"""
@ -1012,7 +1045,9 @@ class Project:
"snap_to_grid": self._snap_to_grid,
"show_grid": self._show_grid,
"grid_size": self._grid_size,
"show_interface_labels": self._show_interface_labels
"show_interface_labels": self._show_interface_labels,
"supplier": self._supplier,
"variables": self._variables
}
def __repr__(self):

View File

@ -15,6 +15,40 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
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"
},
"value": {
"type": "string",
"description": "Variable value"
}
},
"required": ["name"]
}
}
PROJECT_CREATE_SCHEMA = {
"$schema": "http://json-schema.org/draft-04/schema#",
@ -73,7 +107,9 @@ PROJECT_CREATE_SCHEMA = {
"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"]
@ -136,7 +172,9 @@ PROJECT_UPDATE_SCHEMA = {
"show_interface_labels": {
"type": "boolean",
"description": "Show interface labels on the drawing area"
}
},
"supplier": SUPPLIER_OBJECT_SCHEMA,
"variables": VARIABLES_OBJECT_SCHEMA
},
"additionalProperties": False,
}
@ -215,7 +253,9 @@ PROJECT_OBJECT_SCHEMA = {
"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"]

View File

@ -251,6 +251,28 @@ def test_create_with_empty_extra_hosts(loop, project, manager):
assert len([ e for e in called_kwargs["data"]["Env"] if "GNS3_EXTRA_HOSTS" in e]) == 0
def test_create_with_project_variables(loop, project_with_variables, manager):
response = {
"Id": "e90e34656806",
"Warnings": []
}
project.variables = [
{"name": "VAR1"},
{"name": "VAR2", "value": "VAL1"}
]
with asyncio_patch("gns3server.compute.docker.Docker.list_images", return_value=[{"image": "ubuntu"}]):
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
vm = DockerVM("test", str(uuid.uuid4()), project, manager, "ubuntu")
loop.run_until_complete(asyncio.async(vm.create()))
called_kwargs = mock.call_args[1]
assert "VAR1=" in called_kwargs["data"]["Env"]
assert "VAR2=VAL1" in called_kwargs["data"]["Env"]
assert vm._extra_hosts == extra_hosts
project.variables = None
def test_create_start_cmd(loop, project, manager):
response = {

View File

@ -92,9 +92,29 @@ def test_changing_path_not_allowed(tmpdir):
p.path = str(tmpdir)
def test_variables(tmpdir):
variables = [{"name": "VAR1", "value": "VAL1"}]
p = Project(project_id=str(uuid4()), variables=variables)
assert p.variables == variables
def test_json(tmpdir):
p = Project(project_id=str(uuid4()))
assert p.__json__() == {"name": p.name, "project_id": p.id}
assert p.__json__() == {
"name": p.name,
"project_id": p.id,
"variables": None
}
def test_json_with_variables(tmpdir):
variables = [{"name": "VAR1", "value": "VAL1"}]
p = Project(project_id=str(uuid4()), variables=variables)
assert p.__json__() == {
"name": p.name,
"project_id": p.id,
"variables": variables
}
def test_node_working_directory(tmpdir, node):

View File

@ -77,6 +77,8 @@ def test_json(tmpdir):
"show_layers": False,
"snap_to_grid": False,
"grid_size": 0,
"supplier": None,
"variables": []
}

View File

@ -67,6 +67,31 @@ def test_create_project_with_uuid(http_controller):
assert response.json["name"] == "test"
def test_create_project_with_variables(http_controller):
variables = [
{"name": "TEST1"},
{"name": "TEST2", "value": "value1"}
]
query = {"name": "test", "project_id": "30010203-0405-0607-0809-0a0b0c0d0e0f", "variables": variables}
response = http_controller.post("/projects", query)
assert response.status == 201
assert response.json["variables"] == [
{"name": "TEST1"},
{"name": "TEST2", "value": "value1"}
]
def test_create_project_with_supplier(http_controller):
supplier = {
'logo': 'logo.png',
'url': 'http://example.com'
}
query = {"name": "test", "project_id": "30010203-0405-0607-0809-0a0b0c0d0e0f", "supplier": supplier}
response = http_controller.post("/projects", query)
assert response.status == 201
assert response.json["supplier"] == supplier
def test_update_project(http_controller):
query = {"name": "test", "project_id": "10010203-0405-0607-0809-0a0b0c0d0e0f"}
response = http_controller.post("/projects", query)