Local environment for testing IPAM against a real Milo control plane#49
Draft
scotwells wants to merge 1 commit into
Draft
Local environment for testing IPAM against a real Milo control plane#49scotwells wants to merge 1 commit into
scotwells wants to merge 1 commit into
Conversation
Adds a reusable local integration environment that runs the IPAM apiserver wired to a real, in-cluster Milo control plane, so the full IPAM<->Milo path can be exercised end-to-end: delegated authn/authz, quota enforcement, and the entitlement -> grant -> claim chain. This is the path the standalone e2e (--enable-quota=false, no Milo) cannot cover. Artifacts: - config/overlays/milo-integration/ — additive IPAM overlay (quota ON, all three delegation kubeconfig flags pointed at the in-cluster milo-apiserver via a Secret, NetworkPolicy egress to milo-system:6443). Dev/test-infra overlays are untouched. - config/overlays/milo-integration/quota/ — quota.miloapis.com primitives applied to Milo (ResourceRegistration + ClaimCreationPolicy + GrantCreationPolicy) that register the IPAM quotable type and auto-create the per-project grant/bucket/claim. Reproduces what the services.miloapis.com catalog API would do — this Milo build ships only the raw quota primitives. - config/overlays/milo-integration/rbac-tenant-user.yaml — Milo RBAC for the impersonated tenant user (IPAM delegates authz to Milo). - Taskfile milo-integration:up (+ deploy-milo / deploy-ipam / provision-quota). - docs/milo-integration.md — how to run it, the full-claim walkthrough, what it covers vs the standalone e2e, and known issues. Verified end-to-end: an impersonated project-scoped IPClaim binds synchronously (status.allocatedCIDR set) AND quota is enforced — a ResourceClaim is GRANTED (reason QuotaAvailable) and the project AllowanceBucket decrements (alloc 1/100). No Go changes; internal/allocation/ stays zero-dep and the forbidden-import rules are intact. No CI workflow changes (follow-up). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Adds a reusable local environment that runs IPAM wired to a real,
in-cluster Milo control plane, so we can exercise the full IPAM↔Milo path
locally — delegated authn/authz, quota enforcement, and entitlement → grant →
claim — which the standalone e2e (
--enable-quota=false, no Milo) cannotcover.
It proves, on a single kind cluster, that a project-scoped
IPClaim:status.allocatedCIDRset, andResourceClaimis granted (notbypassed) and the project's
AllowanceBucketdecrements.What you get
config/overlays/milo-integration/— additive IPAM overlay:--enable-quota=true,all three delegation kubeconfig flags pointed at the in-cluster
milo-apiserverService (via a
milo-kubeconfigSecret), NetworkPolicy egress tomilo-system:6443.dev/test-infraoverlays are untouched.config/overlays/milo-integration/quota/—quota.miloapis.comprimitivesapplied to Milo:
ResourceRegistration+ClaimCreationPolicy+GrantCreationPolicythat register the IPAM quotable type and auto-create theper-project grant / bucket / claim.
rbac-tenant-user.yaml— Milo RBAC for the impersonated tenant user (IPAMdelegates authz to Milo).
task milo-integration:up(+deploy-milo/deploy-ipam/provision-quota).docs/milo-integration.md— how to run it, the full-claim walkthrough, acoverage table vs the standalone e2e, and known issues.
End-to-end result (verified locally)
Key findings
milo-controller-manager. The full quota grantpipeline (
resource-registration,resource-grant,resource-claim,allowance-bucket, claim/grant-creation policies) runs inside the singlecontroller-manager via its multicluster manager — there is no separate
services-controller-manageras in staging, sotask dev:deploybrings upthe whole pipeline.
quota.miloapis.comprimitives, not thehigher-level
services.miloapis.comcatalog API. The existingconfig/components/service-catalog/(Service / ServiceConfiguration) cannotbe applied here; the overlay reproduces its effect with ResourceRegistration +
policies directly.
readyzpasses with quota ON — the quota + APF (FlowSchema /PriorityLevelConfiguration) informers sync from Milo, the staging readyz
dependency.
Known issues surfaced (IPAM-side, documented, not fixed here)
ClaimCreationPolicyname templates must userequestInfo.name, nottrigger.metadata.name— the IPClaim object handed to the quota plugin lacksa usable
metadatakey for CEL (related[SHOULD NOT HAPPEN] ... no type matching IPClaimSpecmanagedFields logs).origin/mainincludes aquota-object-convertor fix (Fix quota enforcement for IPAM claims #47) that may address this; the overlay uses the
robust
requestInfo.nameregardless.fatal error: concurrent map writeson the claim path (theunsynchronised-map failure mode noted around the
MaxConns=10cap inserve.go); the pod restarts and the retried claim succeeds.Scope / safety
internal/allocation/stays zero-dep; forbidden-import rules intact..github/workflows/*changes — CI wiring is a follow-up.reuse against any shared Milo.
🤖 Generated with Claude Code