Skip to content

Conversation

@fernando-villalba
Copy link
Collaborator

A document detailing defaults, controller logic and where to apply it.

* Utilize **`ValidatingAdmissionPolicy` (CEL)** for *stateless, context-aware* validation that needs access to `oldObject.status` or `request.userInfo`.
* Provide clear, actionable error messages at admission time.
* Support multiple certificate management strategies (cert-manager and self-contained).
* Keep webhook logic in the `data-handler` module.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the distinction of the data-handler and why here instead of resource-handler?


* **Pros:** Automatic certificate generation, renewal, and CA bundle injection. Industry standard.
* **Cons:** Adds a runtime dependency on `cert-manager`.
* **Implementation:** Ship `Certificate` and `Issuer` manifests in `config/webhook/cert-manager`.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how would we prevent the webhook from registering before the certs are ready? For example, the api server tries to call the webhook (MultiCluster CREATE/DELETE) before certs are generated

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@teaglebuilt

We sidestep the issue by enforcing a strict order of operations in main.go.

Here is how:

  1. First, we check if tls.crt and tls.key already exist in the cert directory (e.g., mounted by cert-manager). If they do, we skip internal generation entirely and just use those files.
  2. If no certs are found, we initialize our internal generator and run rotator.Bootstrap(ctx). This is a blocking call. The operator won't proceed past this line until the certs are generated, written to disk, and the MutatingWebhookConfiguration is patched with the new CA bundle.
  3. The webhook server (port 9443) is managed by mgr. Since we haven't called mgr.Start() yet, the binary isn't even listening on that port. If the API server tried to call us during this phase, it would just get a connection refused, not a TLS error.
  4. On top of that, we use a readyz check. Kubernetes won't send traffic to the Pod's Service until the manager is fully up and running, which only happens after that bootstrap phase succeeds.

I hope that answers your question! The code is already implemented in main if you want to go take a look.

…idation

This commit updates the `admission-controller-and-defaults.md` design document
to include the specific logic required for the v1alpha1 System Catalog
implementation.

**Changes:**
* **Level 2 (CEL):** Added explicit `XValidation` rules to enforce the v1alpha1
  topology constraints (Single-Database `postgres` only) and the Mandatory
  Default TableGroup rule (`size() == 1`).
* **Level 4 (Mutation):** Detailed the "System Catalog Injection" logic within
  the Mutating Webhook. This ensures that empty `spec.databases` or
  `tableGroups` lists are automatically hydrated with the mandatory `postgres`
  and `default` resources before hitting the API server.
* **Test Plan:** Updated integration tests to verify that `MultigresCluster`
  creation correctly injects these system resources when they are omitted from
  the spec.
Establishes a 4-tier admission control architecture (OpenAPI, Embedded CEL,
ValidatingAdmissionPolicy, Webhook) to handle validation and defaulting.

Key design points:
- Solves "Invisible Defaults" via a Shared Resolver pattern used by both
  the Webhook (persistence) and Controller (in-memory fallback).
- Defines stateful validation rules for Template referential integrity.
- Adds backward compatibility strategy for K8s < 1.30: The Webhook will
  redundantly implement critical ValidatingAdmissionPolicy logic (e.g.,
  Read-Only Child resources) to support older clusters.
- Updates drawbacks to reflect the maintenance cost of this temporary
  logic duplication.
@fernando-villalba
Copy link
Collaborator Author

Merging this as it explains in great detail the reasoning behind our webhook and admission controllers design.

@fernando-villalba fernando-villalba merged commit b5d80be into main Jan 15, 2026
@fernando-villalba fernando-villalba deleted the admission-controller-doc branch January 15, 2026 21:06
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.

3 participants