mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 18:11:08 -05:00
- Implemented extensive test cases for the Parks API, covering endpoints for listing, retrieving, creating, updating, and deleting parks. - Added tests for filtering, searching, and ordering parks in the API. - Created tests for error handling in the API, including malformed JSON and unsupported methods. - Developed model tests for Park, ParkArea, Company, and ParkReview models, ensuring validation and constraints are enforced. - Introduced utility mixins for API and model testing to streamline assertions and enhance test readability. - Included integration tests to validate complete workflows involving park creation, retrieval, updating, and deletion.
210 lines
6.7 KiB
Python
Executable File
210 lines
6.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Validate autoinstall configuration against Ubuntu's schema.
|
|
This script provides basic validation to check if our autoinstall config
|
|
complies with the official schema structure.
|
|
"""
|
|
|
|
import json
|
|
import yaml
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def load_autoinstall_config(template_path: str) -> dict:
|
|
"""Load the autoinstall configuration from the template file."""
|
|
with open(template_path, 'r') as f:
|
|
content = f.read()
|
|
|
|
# Parse the cloud-config YAML
|
|
config = yaml.safe_load(content)
|
|
|
|
# Extract the autoinstall section
|
|
if 'autoinstall' in config:
|
|
return config['autoinstall']
|
|
else:
|
|
raise ValueError("No autoinstall section found in cloud-config")
|
|
|
|
|
|
def validate_required_fields(config: dict) -> list:
|
|
"""Validate required fields according to schema."""
|
|
errors = []
|
|
|
|
# Check version field (required)
|
|
if 'version' not in config:
|
|
errors.append("Missing required field: version")
|
|
elif not isinstance(config['version'], int) or config['version'] != 1:
|
|
errors.append("Invalid version: must be integer 1")
|
|
|
|
return errors
|
|
|
|
|
|
def validate_identity_section(config: dict) -> list:
|
|
"""Validate identity section."""
|
|
errors = []
|
|
|
|
if 'identity' in config:
|
|
identity = config['identity']
|
|
required_fields = ['username', 'hostname', 'password']
|
|
|
|
for field in required_fields:
|
|
if field not in identity:
|
|
errors.append(f"Identity section missing required field: {field}")
|
|
|
|
# Additional validation
|
|
if 'username' in identity and not isinstance(identity['username'], str):
|
|
errors.append("Identity username must be a string")
|
|
|
|
if 'hostname' in identity and not isinstance(identity['hostname'], str):
|
|
errors.append("Identity hostname must be a string")
|
|
|
|
return errors
|
|
|
|
|
|
def validate_network_section(config: dict) -> list:
|
|
"""Validate network section."""
|
|
errors = []
|
|
|
|
if 'network' in config:
|
|
network = config['network']
|
|
|
|
if 'version' not in network:
|
|
errors.append("Network section missing required field: version")
|
|
elif network['version'] != 2:
|
|
errors.append("Network version must be 2")
|
|
|
|
return errors
|
|
|
|
|
|
def validate_keyboard_section(config: dict) -> list:
|
|
"""Validate keyboard section."""
|
|
errors = []
|
|
|
|
if 'keyboard' in config:
|
|
keyboard = config['keyboard']
|
|
|
|
if 'layout' not in keyboard:
|
|
errors.append("Keyboard section missing required field: layout")
|
|
|
|
return errors
|
|
|
|
|
|
def validate_ssh_section(config: dict) -> list:
|
|
"""Validate SSH section."""
|
|
errors = []
|
|
|
|
if 'ssh' in config:
|
|
ssh = config['ssh']
|
|
|
|
if 'install-server' in ssh and not isinstance(ssh['install-server'], bool):
|
|
errors.append("SSH install-server must be boolean")
|
|
|
|
if 'authorized-keys' in ssh and not isinstance(ssh['authorized-keys'], list):
|
|
errors.append("SSH authorized-keys must be an array")
|
|
|
|
if 'allow-pw' in ssh and not isinstance(ssh['allow-pw'], bool):
|
|
errors.append("SSH allow-pw must be boolean")
|
|
|
|
return errors
|
|
|
|
|
|
def validate_packages_section(config: dict) -> list:
|
|
"""Validate packages section."""
|
|
errors = []
|
|
|
|
if 'packages' in config:
|
|
packages = config['packages']
|
|
|
|
if not isinstance(packages, list):
|
|
errors.append("Packages must be an array")
|
|
else:
|
|
for i, package in enumerate(packages):
|
|
if not isinstance(package, str):
|
|
errors.append(f"Package at index {i} must be a string")
|
|
|
|
return errors
|
|
|
|
|
|
def validate_commands_sections(config: dict) -> list:
|
|
"""Validate early-commands and late-commands sections."""
|
|
errors = []
|
|
|
|
for section_name in ['early-commands', 'late-commands']:
|
|
if section_name in config:
|
|
commands = config[section_name]
|
|
|
|
if not isinstance(commands, list):
|
|
errors.append(f"{section_name} must be an array")
|
|
else:
|
|
for i, command in enumerate(commands):
|
|
if not isinstance(command, (str, list)):
|
|
errors.append(f"{section_name} item at index {i} must be string or array")
|
|
elif isinstance(command, list):
|
|
for j, cmd_part in enumerate(command):
|
|
if not isinstance(cmd_part, str):
|
|
errors.append(f"{section_name}[{i}][{j}] must be a string")
|
|
|
|
return errors
|
|
|
|
|
|
def validate_shutdown_section(config: dict) -> list:
|
|
"""Validate shutdown section."""
|
|
errors = []
|
|
|
|
if 'shutdown' in config:
|
|
shutdown = config['shutdown']
|
|
valid_values = ['reboot', 'poweroff']
|
|
|
|
if shutdown not in valid_values:
|
|
errors.append(f"Shutdown must be one of: {valid_values}")
|
|
|
|
return errors
|
|
|
|
|
|
def main():
|
|
"""Main validation function."""
|
|
template_path = Path(__file__).parent / "cloud-init-template.yaml"
|
|
|
|
if not template_path.exists():
|
|
print(f"Error: Template file not found at {template_path}")
|
|
sys.exit(1)
|
|
|
|
try:
|
|
# Load the autoinstall configuration
|
|
print(f"Loading autoinstall config from {template_path}")
|
|
config = load_autoinstall_config(str(template_path))
|
|
|
|
# Run validation checks
|
|
all_errors = []
|
|
|
|
all_errors.extend(validate_required_fields(config))
|
|
all_errors.extend(validate_identity_section(config))
|
|
all_errors.extend(validate_network_section(config))
|
|
all_errors.extend(validate_keyboard_section(config))
|
|
all_errors.extend(validate_ssh_section(config))
|
|
all_errors.extend(validate_packages_section(config))
|
|
all_errors.extend(validate_commands_sections(config))
|
|
all_errors.extend(validate_shutdown_section(config))
|
|
|
|
# Report results
|
|
if all_errors:
|
|
print("\n❌ Validation failed with the following errors:")
|
|
for error in all_errors:
|
|
print(f" - {error}")
|
|
sys.exit(1)
|
|
else:
|
|
print("\n✅ Autoinstall configuration validation passed!")
|
|
print("Configuration appears to comply with Ubuntu autoinstall schema.")
|
|
|
|
# Print summary of detected sections
|
|
sections = list(config.keys())
|
|
print(f"\nDetected sections: {', '.join(sorted(sections))}")
|
|
|
|
except Exception as e:
|
|
print(f"Error during validation: {e}")
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|