Validate appliance files with Pydantic

This commit is contained in:
grossmj committed 2021-10-18 21:46:50 +10:30
1 parent 04934691df
commit 13ff7df9fa
6 files changed
+491 -22

No files matched your search

+2 -5
View File
@@ -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
+15 -4
View File
@@ -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