Validate rendered cloud-init templates against official schema#63
Validate rendered cloud-init templates against official schema#63
Conversation
e7410fe to
bc121e8
Compare
Add jsonschema dev dependency and two new tests that render the Jinja2 cloud-init template (with and without Tailscale) then validate the output against canonical/cloud-init's JSON schema. Tests skip gracefully when the network is unavailable. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
bc121e8 to
7a37172
Compare
| CLOUD_CONFIG_SCHEMA_URL = ( | ||
| "https://raw.githubusercontent.com/canonical/cloud-init/main/" | ||
| "cloudinit/config/schemas/schema-cloud-config-v1.json" | ||
| ) |
There was a problem hiding this comment.
Do we always want to check against main? Some older distros may not support the latest cloud-init schema. Adding a newer keys would pass this test, but break dropkit for older distros.
If we look at all the distro slugs supported by the digital ocean API and pick the ones we want to support, we could pin the check against the lowest common version among the supported distros.
If we pin the version, we could also commit the schema directly to the repo, eliminating the need to fetch the scema each time.
But also, that may be overkill for what we are doing here 😄
There was a problem hiding this comment.
IMO - we should have this dependency in the repo directly, and have a github action workflow to update it periodically.
I prefer to be able to run tests locally, and that would avoid to have to redownload the file and each tests run :)
| """Verify the rendered template without Tailscale also passes schema validation.""" | ||
| rendered = _render_template(tailscale_enabled=False) | ||
| doc = yaml.safe_load(rendered) | ||
| validator = Draft4Validator(cloud_config_schema) |
There was a problem hiding this comment.
Is the schema on main guaranteed to stay on Draft 4?
Summary
jsonschemaas a dev dependencyTest plan
uv run pytest tests/test_cloudinit.py -v— all 6 tests passuv run pytest -v— full suite (291 tests) passes with coverage above thresholdprek run— all pre-commit hooks pass🤖 Generated with Claude Code