Skip to content

feat: add DiscoveryContextPolicy CRD for operator-configurable discovery context rules#602

Merged
scotwells merged 5 commits into
mainfrom
feat/discovery-context-policy
May 6, 2026
Merged

feat: add DiscoveryContextPolicy CRD for operator-configurable discovery context rules#602
scotwells merged 5 commits into
mainfrom
feat/discovery-context-policy

Conversation

@scotwells
Copy link
Copy Markdown
Contributor

Summary

  • Introduces DiscoveryContextPolicy, a new cluster-scoped CRD (discovery.miloapis.com/v1alpha1) that gives operators a Kubernetes-native way to control which parent contexts (Platform, Organization, Project, User) each API resource appears in during discovery
  • Slots in as the highest-precedence source in the contextual discovery registry: DiscoveryContextPolicy > CRD annotation > static registration
  • Supports per-resource rules and "*" wildcards for group and/or resource, with alphabetical-first-policy-name as tiebreaker for conflicts
  • Ships a default DiscoveryContextPolicy (core-kubernetes-resources) that maps core k8s groups ("", apps, batch, networking.k8s.io, rbac.authorization.k8s.io) to Project context

Motivation

The existing contextual discovery feature only sourced context rules from CRD annotations and static registrations at startup. This left two gaps:

  1. Resources from aggregated API servers (no CRDs in the apiextensions API)
  2. Native Kubernetes resources (built into the API server)

DiscoveryContextPolicy fills both gaps: any operator or aggregated-server author can deploy a policy object without changing Milo's source code.

Implementation notes

  • The registry watches DiscoveryContextPolicy objects via a dynamic informer using the loopback client config (bypasses RBAC; system-level access)
  • The policy informer uses PollUntilContextCancel to retry indefinitely until the DiscoveryContextPolicy CRD is available — necessary because the CRD is bootstrapped by Milo's own post-start hook and may not exist when the informer hook fires
  • HasSynced() now gates on both the CRD informer and the policy informer having completed their initial list, so the discovery filter continues to fall open during startup

Test plan

  • Unit tests: go test ./pkg/server/discovery/... (13 tests: policy precedence, wildcard matching, exact-beats-wildcard, multi-policy conflict, delete cleanup, HasSynced gating)
  • E2E tests: task test:end-to-end — extended test/discovery-context-filter/chainsaw-test.yaml with policy apply/verify/delete/revert steps
  • Verify generated CRD manifest includes enum validation on spec.rules[].contexts
  • Verify task generate:code is idempotent (no unexpected changes)

🤖 Generated with Claude Code

scotwells and others added 2 commits May 5, 2026 19:16
…context source

Introduces the DiscoveryContextPolicy cluster-scoped CRD (discovery.miloapis.com/v1alpha1)
as a third source for the discovery context registry, taking precedence over both CRD
annotations and static registrations. Supports exact GroupResource matching, wildcard
group/resource patterns, and multi-policy conflict resolution via alphabetical policy name
ordering. Includes a dynamic informer with retry backoff (CRD may not exist at startup),
scheme registration, RBAC, a protected-resource default policy for core Kubernetes resources,
and full unit + e2e test coverage.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add enum validation to Contexts field (Platform|Organization|Project|User)
- Replace bounded ExponentialBackoff (10 attempts) with PollUntilContextCancel
  so a slow CRD bootstrap never permanently disables the policy informer
- Add TestDeletePolicyRemovesWildcardEntries to cover policyWildcards cleanup
- Add TestExactMatchConflictBetweenPolicies to cover alphabetical-winner logic
- Regenerate CRD YAML to pick up enum constraints and remove stale RBAC rules
  (controller-manager does not need discovery RBAC; apiserver uses loopback)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@joggrbot
Copy link
Copy Markdown
Contributor

joggrbot Bot commented May 6, 2026

📝 Documentation Analysis

Joggr found 1 outdated docs in the pull request.

Autofix

Joggr failed to autofix the outdated docs, please try again later or contact support.

Outdated

file reason confidence
test/discovery-context-filter/README.md This test documentation is now significantly out-of-date because the codebase added DiscoveryContextPolicy CRDs, allowing dynamic policy-driven runtime overrides of API context visibility, but the test and its README still only describe static CRD annotation-based filtering and expectations. 62.2%

✅ Latest commit analyzed: 09c74e7 | Powered by Joggr

scotwells and others added 2 commits May 5, 2026 20:28
Remove activity from the base config/services component. The ActivityPolicy
CRDs live in the activity service, which is not deployed in the milo test
cluster (or any environment that hasn't installed that service). Environments
that do have the activity service can include config/services/activity/
directly in their overlay.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…entity

- Add Platform parent-context annotation to the namespaced Note type
- Register sessions and useridentities statically in the discovery
  registry under the User context, since they are built-in API server
  resources and cannot use the kubebuilder annotation approach

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@scotwells scotwells requested a review from kevwilliams May 6, 2026 22:43
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@scotwells scotwells marked this pull request as ready for review May 6, 2026 22:45
@scotwells scotwells merged commit e64efd0 into main May 6, 2026
8 of 9 checks passed
@scotwells scotwells deleted the feat/discovery-context-policy branch May 6, 2026 22:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants