mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-03 05:51:15 +02:00
Validate appliance files with Pydantic
This commit is contained in:
1 parent
04934691df
commit
13ff7df9fa
6 files changed
+491
-22
No files matched your search
@@ -16,7 +16,6 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import copy
|
||||
import uuid
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@@ -27,12 +26,9 @@ class Appliance:
|
||||
def __init__(self, path, data, builtin=True):
|
||||
|
||||
self._data = data.copy()
|
||||
self._id = data.get("appliance_id", uuid.uuid5(uuid.NAMESPACE_X500, path))
|
||||
self._id = self._data.get("appliance_id")
|
||||
self._path = path
|
||||
self._builtin = builtin
|
||||
if "appliance_id" in self._data:
|
||||
del self._data["appliance_id"]
|
||||
|
||||
if self.status != "broken":
|
||||
log.debug(f'Appliance "{self.name}" [{self._id}] loaded')
|
||||
|
||||
@@ -84,6 +80,7 @@ class Appliance:
|
||||
"""
|
||||
Appliance data (a hash)
|
||||
"""
|
||||
|
||||
data = copy.deepcopy(self._data)
|
||||
data["builtin"] = self._builtin
|
||||
return data
|
||||
@@ -214,6 +214,10 @@ class ApplianceManager:
|
||||
|
||||
appliances_info = self._find_appliances_from_image_checksum(image_checksum)
|
||||
for appliance, image_version in appliances_info:
|
||||
try:
|
||||
schemas.Appliance.parse_obj(appliance.asdict())
|
||||
except ValidationError as e:
|
||||
log.warning(message=f"Could not validate appliance '{appliance.id}': {e}")
|
||||
if appliance.versions:
|
||||
for version in appliance.versions:
|
||||
if version.get("name") == image_version:
|
||||
@@ -241,6 +245,11 @@ class ApplianceManager:
|
||||
if not appliance:
|
||||
raise ControllerNotFoundError(message=f"Could not find appliance '{appliance_id}'")
|
||||
|
||||
try:
|
||||
schemas.Appliance.parse_obj(appliance.asdict())
|
||||
except ValidationError as e:
|
||||
raise ControllerError(message=f"Could not validate appliance '{appliance_id}': {e}")
|
||||
|
||||
if version:
|
||||
if not appliance.versions:
|
||||
raise ControllerBadRequestError(message=f"Appliance '{appliance_id}' do not have versions")
|
||||
@@ -289,16 +298,18 @@ class ApplianceManager:
|
||||
path = os.path.join(directory, file)
|
||||
try:
|
||||
with open(path, encoding="utf-8") as f:
|
||||
appliance = Appliance(path, json.load(f), builtin=builtin)
|
||||
json_data = appliance.asdict() # Check if loaded without error
|
||||
json_data = json.load(f)
|
||||
schemas.Appliance.parse_obj(json_data)
|
||||
appliance = Appliance(path, json_data, builtin=builtin)
|
||||
appliance_data = appliance.asdict() # Check if loaded without error
|
||||
if appliance.status != "broken":
|
||||
self._appliances[appliance.id] = appliance
|
||||
if not appliance.symbol or appliance.symbol.startswith(":/symbols/"):
|
||||
# apply a default symbol if the appliance has none or a default symbol
|
||||
default_symbol = self._get_default_symbol(json_data, symbol_theme)
|
||||
default_symbol = self._get_default_symbol(appliance_data, symbol_theme)
|
||||
if default_symbol:
|
||||
appliance.symbol = default_symbol
|
||||
except (ValueError, OSError, KeyError) as e:
|
||||
except (ValueError, OSError, KeyError, ValidationError) as e:
|
||||
log.warning(f"Cannot load appliance file '{path}': {e}")
|
||||
continue
|
||||
|
||||
|
||||
Reference in new issue
Block a user