This repository has been archived by the owner on Aug 21, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
301 additions
and
2 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
from __future__ import annotations | ||
|
||
from jsonschema import Draft202012Validator | ||
from jsonschema import SchemaError | ||
from jsonschema import ValidationError | ||
|
||
|
||
SCHEMA = { | ||
"$schema": "https://json-schema.org/draft/2020-12/schema#", | ||
"definitions": { | ||
"defaults": { | ||
"type": "object", | ||
"properties": { | ||
"name": {"type": "string", "description": "Human readable image name"}, | ||
"version": { | ||
"type": "string", | ||
"description": "RHEL image version following MAJOR.MINOR.PATCH", | ||
}, | ||
"imageId": { | ||
"type": "string", | ||
"description": "Image ID used for running the image", | ||
}, | ||
"date": { | ||
"type": "string", | ||
"description": "Date of image release in international date format", | ||
}, | ||
"virt": {"type": "string", "description": "Hypervisor Type"}, | ||
}, | ||
}, | ||
"aws": { | ||
"type": "object", | ||
"description": "AWS RHEL Image Data", | ||
"$ref": "#/definitions/defaults", | ||
"properties": { | ||
"selflink": { | ||
"description": "URL for direct access from cloud console", | ||
"format": "uri", | ||
"pattern": r"^https://console\.aws\.amazon\.com/ec2/home\?region=[a-z0-9-]*#launchAmi=ami-[a-z0-9]*", # noqa: E501 | ||
}, | ||
"region": { | ||
"type": "string", | ||
"description": "Region of image availability", | ||
}, | ||
}, | ||
"required": [ | ||
"name", | ||
"version", | ||
"imageId", | ||
"date", | ||
"virt", | ||
"selflink", | ||
"region", | ||
], | ||
}, | ||
"azure": { | ||
"type": "object", | ||
"description": "Azure RHEL Image Data", | ||
"$ref": "#/definitions/defaults", | ||
"required": ["name", "version", "imageId", "date", "virt"], | ||
}, | ||
"google": { | ||
"type": "object", | ||
"description": "Google RHEL Image Data", | ||
"$ref": "#/definitions/defaults", | ||
"properties": { | ||
"selflink": { | ||
"description": "URL for direct access from cloud console", | ||
"format": "uri", | ||
"pattern": r"^https://console.cloud.google.com/compute/imagesDetail/projects/rhel-cloud/global/images/[a-z0-9-]*", # noqa: E501 | ||
} | ||
}, | ||
"required": ["name", "version", "imageId", "date", "virt", "selflink"], | ||
}, | ||
}, | ||
"additionalProperties": False, | ||
"required": ["images"], | ||
"description": "Prepared Image Date for cloud image locator", | ||
"$ref": "#/definitions/defaults", | ||
"properties": { | ||
"images": { | ||
"type": "object", | ||
"additionalProperties": False, | ||
"description": "Prepared Image Data", | ||
"minProperties": 1, | ||
"properties": { | ||
"aws": {"type": "array", "items": {"$ref": "#/definitions/aws"}}, | ||
"azure": {"type": "array", "items": {"$ref": "#/definitions/azure"}}, | ||
"google": {"type": "array", "items": {"$ref": "#/definitions/google"}}, | ||
}, | ||
} | ||
}, | ||
} | ||
|
||
|
||
def validate_json(data: str) -> None: | ||
try: | ||
validator = Draft202012Validator(SCHEMA) | ||
errors = sorted(validator.iter_errors(data), key=lambda e: e.path) | ||
|
||
if errors: | ||
error_message = "Error validating image data: " | ||
for error in errors: | ||
error_message += f"[{error.schema_path}]: {error.message}; " | ||
raise ValidationError(message=error_message) | ||
|
||
except (ValidationError, SchemaError) as e: | ||
raise ValidationError(e.message) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
"""Test image updates from remote cloud APIs.""" | ||
from __future__ import annotations | ||
|
||
import pytest | ||
|
||
from jsonschema import ValidationError | ||
|
||
from rhelocator.update_images import schema | ||
|
||
|
||
def test_valid_image_data_validation(): | ||
"""Test image data validation with valid input.""" | ||
image_data = { | ||
"images": { | ||
"aws": [ | ||
{ | ||
"name": "some name", | ||
"version": "some version", | ||
"imageId": "some id", | ||
"date": "some date", | ||
"virt": "some virt", | ||
"selflink": "https://console.aws.amazon.com/ec2/home?region=eu-north-1#launchAmi=ami-0e02b69290bcd7b69", # noqa: E501 | ||
"region": "some region", | ||
} | ||
], | ||
"azure": [ | ||
{ | ||
"name": "some name", | ||
"version": "some version", | ||
"imageId": "some id", | ||
"date": "some date", | ||
"virt": "some virt", | ||
} | ||
], | ||
"google": [ | ||
{ | ||
"name": "some name", | ||
"version": "some version", | ||
"imageId": "some id", | ||
"date": "some date", | ||
"virt": "some virt", | ||
"selflink": "https://console.cloud.google.com/compute/imagesDetail/projects/rhel-cloud/global/images/rhel-7-v20220719", # noqa: E501 | ||
} | ||
], | ||
} | ||
} | ||
|
||
try: | ||
schema.validate_json(image_data) | ||
except ValidationError as exc: | ||
raise AssertionError(f"Validating proper image data raised an exception! {exc}") | ||
|
||
|
||
def test_incomplete_image_data_validation(): | ||
"""Test image data validation with incomplete input.""" | ||
image_data = { | ||
"images": { | ||
"aws": [ | ||
{ | ||
"name": "some name", | ||
"version": "some version", | ||
"imageId": "some id", | ||
"virt": "some virt", | ||
"selflink": "https://console.aws.amazon.com/ec2/home?region=eu-north-1#launchAmi=ami-0e02b69290bcd7b69", # noqa: E501 | ||
"region": "some region", | ||
} | ||
] | ||
} | ||
} | ||
|
||
with pytest.raises(ValidationError, match=r".*'date' is a required property.*"): | ||
schema.validate_json(image_data) | ||
|
||
|
||
def test_invalid_image_data_validation(): | ||
"""Test image data validation with invalid input type.""" | ||
image_data = { | ||
"images": { | ||
"aws": [ | ||
{ | ||
"name": "some name", | ||
"version": False, | ||
"imageId": "some id", | ||
"virt": "some virt", | ||
"date": "some date", | ||
"selflink": "https://console.aws.amazon.com/ec2/home?region=eu-north-1#launchAmi=ami-0e02b69290bcd7b69", # noqa: E501 | ||
"region": "some region", | ||
} | ||
] | ||
} | ||
} | ||
|
||
with pytest.raises(ValidationError, match=r".*False is not of type 'string'*"): | ||
schema.validate_json(image_data) | ||
|
||
|
||
def test_invalid_extra_image_data_validation(): | ||
"""Test image data validation with invalid extrea input data.""" | ||
image_data = { | ||
"images": { | ||
"oracle": [ | ||
{ | ||
"name": "some name", | ||
"version": "some version", | ||
"imageId": "some id", | ||
"virt": "some virt", | ||
"date": "some date", | ||
"selflink": "https://console.aws.amazon.com/ec2/home?region=eu-north-1#launchAmi=ami-0e02b69290bcd7b69", # noqa: E501 | ||
"region": "some region", | ||
} | ||
] | ||
} | ||
} | ||
|
||
with pytest.raises( | ||
ValidationError, match=r".*Additional properties are not allowed*" | ||
): | ||
schema.validate_json(image_data) | ||
|
||
|
||
def test_malicious_url(): | ||
"""Test image data validation with malicious url injection.""" | ||
image_data = { | ||
"images": { | ||
"aws": [ | ||
{ | ||
"name": "some name", | ||
"version": "some version", | ||
"imageId": "some id", | ||
"virt": "some virt", | ||
"date": "some date", | ||
"selflink": "http://some-evil-url.com/?https://console.aws.amazon.com/ec2/home?region=eu-north-1#launchAmi=ami-0e02b69290bcd7b69", # noqa: E501 | ||
"region": "some region", | ||
} | ||
] | ||
} | ||
} | ||
|
||
with pytest.raises(ValidationError, match=r".*does not match*"): | ||
schema.validate_json(image_data) |