mirror of
https://github.com/GNS3/gns3-server
synced 2024-11-24 09:18:08 +00:00
Fix Exporting portable projects with QEMU includes base images even when selecting no.
Fix https://github.com/GNS3/gns3-gui/issues/1409
This commit is contained in:
parent
7d90a73ed2
commit
d6f63d3b7d
@ -368,7 +368,8 @@ class ProjectHandler:
|
|||||||
response.content_length = None
|
response.content_length = None
|
||||||
response.start(request)
|
response.start(request)
|
||||||
|
|
||||||
for data in project.export(include_images=bool(request.GET.get("include_images", "0"))):
|
include_images = bool(int(request.json.get("include_images", "0")))
|
||||||
|
for data in project.export(include_images=include_images):
|
||||||
response.write(data)
|
response.write(data)
|
||||||
yield from response.drain()
|
yield from response.drain()
|
||||||
|
|
||||||
|
@ -17,11 +17,13 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
import jsonschema
|
import urllib
|
||||||
import asyncio
|
import asyncio
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import logging
|
import logging
|
||||||
import traceback
|
import traceback
|
||||||
|
import jsonschema
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -33,10 +35,11 @@ from ..config import Config
|
|||||||
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def parse_request(request, input_schema):
|
def parse_request(request, input_schema, raw):
|
||||||
"""Parse body of request and raise HTTP errors in case of problems"""
|
"""Parse body of request and raise HTTP errors in case of problems"""
|
||||||
|
|
||||||
content_length = request.content_length
|
content_length = request.content_length
|
||||||
if content_length is not None and content_length > 0:
|
if content_length is not None and content_length > 0 and not raw:
|
||||||
body = yield from request.read()
|
body = yield from request.read()
|
||||||
try:
|
try:
|
||||||
request.json = json.loads(body.decode('utf-8'))
|
request.json = json.loads(body.decode('utf-8'))
|
||||||
@ -45,13 +48,21 @@ def parse_request(request, input_schema):
|
|||||||
raise aiohttp.web.HTTPBadRequest(text="Invalid JSON {}".format(e))
|
raise aiohttp.web.HTTPBadRequest(text="Invalid JSON {}".format(e))
|
||||||
else:
|
else:
|
||||||
request.json = {}
|
request.json = {}
|
||||||
try:
|
|
||||||
jsonschema.validate(request.json, input_schema)
|
# Parse the query string
|
||||||
except jsonschema.ValidationError as e:
|
if len(request.query_string) > 0:
|
||||||
log.error("Invalid input query. JSON schema error: {}".format(e.message))
|
for (k, v) in urllib.parse.parse_qs(request.query_string).items():
|
||||||
raise aiohttp.web.HTTPBadRequest(text="Invalid JSON: {} in schema: {}".format(
|
request.json[k] = v[0]
|
||||||
e.message,
|
|
||||||
json.dumps(e.schema)))
|
if input_schema:
|
||||||
|
try:
|
||||||
|
jsonschema.validate(request.json, input_schema)
|
||||||
|
except jsonschema.ValidationError as e:
|
||||||
|
log.error("Invalid input query. JSON schema error: {}".format(e.message))
|
||||||
|
raise aiohttp.web.HTTPBadRequest(text="Invalid JSON: {} in schema: {}".format(
|
||||||
|
e.message,
|
||||||
|
json.dumps(e.schema)))
|
||||||
|
|
||||||
return request
|
return request
|
||||||
|
|
||||||
|
|
||||||
@ -161,12 +172,13 @@ class Route(object):
|
|||||||
if api_version is None or raw is True:
|
if api_version is None or raw is True:
|
||||||
response = Response(request=request, route=route, output_schema=output_schema)
|
response = Response(request=request, route=route, output_schema=output_schema)
|
||||||
|
|
||||||
|
request = yield from parse_request(request, None, raw)
|
||||||
yield from func(request, response)
|
yield from func(request, response)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
# API call
|
# API call
|
||||||
try:
|
try:
|
||||||
request = yield from parse_request(request, input_schema)
|
request = yield from parse_request(request, input_schema, raw)
|
||||||
record_file = server_config.get("record")
|
record_file = server_config.get("record")
|
||||||
if record_file:
|
if record_file:
|
||||||
try:
|
try:
|
||||||
|
@ -25,7 +25,7 @@ import asyncio
|
|||||||
import aiohttp
|
import aiohttp
|
||||||
import zipfile
|
import zipfile
|
||||||
|
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch, MagicMock
|
||||||
from tests.utils import asyncio_patch
|
from tests.utils import asyncio_patch
|
||||||
|
|
||||||
from gns3server.handlers.api.project_handler import ProjectHandler
|
from gns3server.handlers.api.project_handler import ProjectHandler
|
||||||
@ -306,6 +306,19 @@ def test_export(server, tmpdir, loop, project):
|
|||||||
assert content == b"hello"
|
assert content == b"hello"
|
||||||
|
|
||||||
|
|
||||||
|
def test_export_include_image(server, tmpdir, loop, project):
|
||||||
|
|
||||||
|
project.export = MagicMock()
|
||||||
|
response = server.get("/projects/{project_id}/export".format(project_id=project.id), raw=True)
|
||||||
|
project.export.assert_called_with(include_images=False)
|
||||||
|
|
||||||
|
response = server.get("/projects/{project_id}/export?include_images=0".format(project_id=project.id), raw=True)
|
||||||
|
project.export.assert_called_with(include_images=False)
|
||||||
|
|
||||||
|
response = server.get("/projects/{project_id}/export?include_images=1".format(project_id=project.id), raw=True)
|
||||||
|
project.export.assert_called_with(include_images=True)
|
||||||
|
|
||||||
|
|
||||||
def test_import(server, tmpdir, loop, project):
|
def test_import(server, tmpdir, loop, project):
|
||||||
|
|
||||||
with zipfile.ZipFile(str(tmpdir / "test.zip"), 'w') as myzip:
|
with zipfile.ZipFile(str(tmpdir / "test.zip"), 'w') as myzip:
|
||||||
|
Loading…
Reference in New Issue
Block a user