Repository navigation
fix(k8s): cross-check provided contract hosts against rendered Services (E150) (#1035) - #1038
RonaldHensbergen wants to merge 3 commits into
Conversation
…es (E150) (#1035) The E150 provide-side cross-check from #1028 only ran in the compose renderer; the Kubernetes renderer had just the consume-side E084 check, so a provided contract advertising a host no rendered k8s Service matched did not fail closed on the helm target. render_helm now runs _check_provided_contract_services next to _check_binding_services: every provided http-service, sql-database, cache-service, and object-storage contract's advertised network host (the host field, the endpoint's hostname part, or a serviceName resolved to the serving workload's Service name, honoring workload-level serviceName overrides) is checked against the Services the render produces for that module, and a mismatch fails closed with E150. External hosts (dots, ports) are skipped and modules rendering no Service are left to their own diagnostics, mirroring the compose check. README's E150 row, docs/modules.md, and the CHANGELOG cover both render targets. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
RonaldHensbergen
left a comment
There was a problem hiding this comment.
Self-review (contributor == reviewer), all angles checked:
- Functioneel / fail-closed:
_check_provided_contract_servicesruns inrender_helmright after_check_binding_services, before the error gate, so an E150 mismatch returns{}files — the chart is not written. The "renders green but breaks at runtime" scenario (provide host no k8s Service answers) is now a render-time error. Verified against the real profile (still renders clean, golden hashes unchanged) and against broken plans (superset hostnowhere, dagster serviceNameno-such-workload, workload serviceName override cases) — all fail closed with E150 at the expected paths. - serviceName semantics: a provide
serviceNamenames a workload and is resolved through_compose_service_nameto the workload's rendered Service name, honoring workload-levelserviceNameoverrides (host must then be the Service name, not the workload name) — consistent with what E084 consume-side bindings and_release_scope_binding_hostsexpect. - E/W-codes: E150 is reused deliberately — codes are shared across render targets already (E071–E080 in both renderers); no new code allocated, so no collision with main or open PRs (fresh fetch checked; E150 is the highest code in use).
- Tests: 7 new tests in tests/test_k8s_renderer.py (fail host, pass host, serviceName hit/miss, sql-database + object-storage endpoints, external hosts skipped, no-rendered-services skip, serviceName override). tests/test_k8s_renderer.py: 33 passed; with test_contract_host_resolution.py and test_main.py: 205 passed; full suite 1973 tests with only the pre-existing, unrelated test_security.py rule-set-version failure (working-tree-only changes, not on this branch).
- Docs/conventies: README E150 row now covers both targets, docs/modules.md describes the helm cross-check, CHANGELOG [Unreleased] has a Fixed entry; ruff and markdownlint clean on touched files.
Geen openstaande punten meer; PR is naar mijn oordeel merge-klaar.
…renderers SonarCloud's quality gate on PR #1038 failed with 10.9% duplication on new code (required <= 3%): _check_provided_contract_services in cli/k8s_renderer.py duplicated the candidate extraction and diagnostic construction of the compose renderer's _validate_provided_contract_hosts. The shared logic now lives once in cli/renderer.py: - _provided_contract_host_candidates: per-kind (field, host) pairs a provided contract spec advertises; - _validate_provided_contract_hosts_against: the E150 loop, parameterized by the target wording (service_kind/fix_hint) and an optional resolve_service_name hook for the helm target's workload-level serviceName overrides. _validate_provided_contract_hosts (compose) and _check_provided_contract_services (helm) are now thin wrappers that only supply their rendered-service names. Behavior is unchanged: all 1973 tests pass, ruff clean. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
|
|
CI fix pushed (fadbabb): the SonarCloud quality gate failed on the first push with 10.9% duplication on new code (limit 3%) -- The E150 core is now shared once in Result: |



Closes #1035.
The E150 provide-side cross-check from #1028 only ran in the compose renderer (cli/renderer.py); the Kubernetes renderer had just the consume-side E084 check, so a provided contract advertising a host that no rendered k8s Service matched did not fail closed on the helm target.
Changes
Verification