Skip to content

add: link to roadmap - #18

Merged
Andrei Kvapil (kvaps) merged 1 commit into
mainfrom
basic-readme
Mar 13, 2024
Merged

Andrei Kvapil (kvaps) merged 1 commit into
mainfrom
basic-readme

Conversation

@kvaps

@kvaps Andrei Kvapil (kvaps) commented Mar 13, 2024 •

Copy link
Copy Markdown
Member

fixes: #10

Signed-off-by: Andrei Kvapil [email protected]

Signed-off-by: Andrei Kvapil <[email protected]>
@kvaps
Andrei Kvapil (kvaps) enabled auto-merge (squash) March 13, 2024 10:35
@kvaps
Andrei Kvapil (kvaps) merged commit b6adcc3 into main Mar 13, 2024
Comment thread README.md
Versioning adheres to the [Semantic Versioning](http://semver.org/) principles.
A full list of the available releases is available in the GitHub repository's [Release](https://github.com/aenix-io/etcd-operator/releases) section.

- [Roadmap](https://github.com/orgs/aenix-io/projects/1)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this link correct?
I can see roadmap by this link
etcd-operator (view)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah, just fixed a views under the link, thank you

Terry Tang (saymololy) pushed a commit to saymololy/etcd-operator that referenced this pull request Nov 2, 2026
…ozystack#18)

* api: CEL XValidation rules on EtcdClusterSpec (cozystack#15)

Apiserver-side enforcement (k8s 1.28+) for the four validation rules
the previous PR's docs flagged as "user must avoid this":

  - StorageMedium immutable. Flipping the medium on an existing cluster
    would orphan the previous PVC (or tmpfs) and the rolling-migrate
    path is not implemented. Default the field to "" so oldSelf is
    always present on Update — CEL transition rules skip when oldSelf
    is absent, which would otherwise let absent → Memory slip past
    immutability.

  - Storage > 0 when StorageMedium=Memory. Zero or unset Storage with
    Memory medium produces an unbounded tmpfs; reject at admission.

  - Replicas=0 with Memory rejected. The previously documented wedge
    (dormant flip deletes the Pod, tmpfs evaporates, resume path
    recreates the member as if data were preserved → empty data dir,
    etcd refuses to start). Apiserver now blocks the combination.

  - Storage cannot shrink. PVCs cannot shrink and tmpfs SizeLimit
    reduction does not free already-allocated memory.

Implementation entirely in +kubebuilder:validation:XValidation markers.
No webhook, no Service, no cert-manager dependency — CEL is compiled
into the CRD's x-kubernetes-validations and evaluated by the apiserver
directly. `quantity()` library required (k8s 1.28+, already the
project's documented floor).

go.mod gains github.com/blang/semver/v4 as an indirect transitive of
controller-runtime's envtest package, which the next commit needs.

Signed-off-by: Timofei Larkin <[email protected]>

* api: envtest harness + CEL rule tests

CEL XValidation runs apiserver-side, so the only way to test these
contracts is to spin up a real apiserver via controller-runtime's
envtest, install the project's CRDs, and observe accept/reject
behaviour on Create and Update.

TestMain skips the package entirely when KUBEBUILDER_ASSETS is unset
so dev-IDE runs (`go test ./...`) don't fail; the Makefile's `make
test` target sets it via `setup-envtest use`. Existing make test
integration continues to work; this PR adds the first envtest user.

Tests:
  - StorageMedium immutable: create PVC-backed, attempt to flip to
    Memory on Update, expect rejection.
  - Storage > 0 for Memory: create with Memory + storage=0, expect
    rejection at Create time.
  - Replicas=0 + Memory: rejected on Create and on transition 3 → 0.
  - Storage shrink: 1Gi → 512Mi rejected; 1Gi → 2Gi accepted (negative
    guard that the shrink rule isn't a no-grow rule).
  - Happy path: PVC default, Memory with non-zero storage, and PVC
    with replicas=0 (the wedge rule must only fire for Memory) all
    Create successfully — guards against rule inversion or over-
    broad CEL expressions.
Signed-off-by: Timofei Larkin <[email protected]>

* docs: walk back wedge caveats; document CEL validation

The memory-storage PR's docs introduced "this combination wedges, the
admission webhook in cozystack#15 will fix it, until then don't do this"
caveats across concepts, operations, installation, and the API
godoc. With the CEL rules now landed on the CRD itself, the apiserver
rejects those combinations at admission. Update the docs to reflect:

- concepts.md: replace "Known limitation: replicas=0 wedges" with an
  "Apiserver-enforced validation" table listing the four rules, when
  each fires, and why.
- operations.md: replace "Do not set replicas=0 on memory clusters"
  with the actual rejection-error transcript from the apiserver.
- installation.md: drop the "cozystack#15 wedge to avoid" parenthetical.
- README.md: add an "Apiserver-enforced validation" bullet under
  "What's supported"; drop the "Not safe to combine with replicas=0
  yet" qualifier since it's no longer possible.

The k8s 1.28+ floor for the quantity() CEL library is consistent with
the project's existing minimum (1.28+ already documented in
installation.md prerequisites).

Signed-off-by: Timofei Larkin <[email protected]>

* api: coerce storage to string before quantity() (CEL int-or-string)

CEL's quantity() function accepts only string input. spec.storage in
the CRD schema is x-kubernetes-int-or-string, so a kubectl-style YAML
like `storage: 0` arrives at the apiserver as a JSON integer rather
than a quantity string. Without explicit string() coercion CEL trips
"no such overload: quantity(int)" and the user sees that runtime error
instead of the rule's message field. Both rules that call quantity()
now wrap the field in string() first.

The typed Go API always emits Quantity values as strings, which is why
the original envtest cases passed — they couldn't reach the integer
path. The smoke test on dev4 surfaced this immediately on
`kubectl apply` of a raw YAML.

Add TestCEL_StorageMustBeNonZero_IntegerInput using
unstructured.Unstructured to send int64(0) directly; pins the
contract that the rule's human-readable message must surface for
either input form.

Signed-off-by: Timofei Larkin <[email protected]>

* Address review of feat/cel-validation

Two stale comments still claimed the admission gate was future work
("admission webhook in cozystack#15 will reject ...", "Until admission gates
the replicas=0+memory combination (issue cozystack#15) ..."). Both predate the
CEL rule landing in the same PR. Rewrite to describe the defensive
runtime branch correctly: the CEL rule blocks the combination on
Create/Update, but an operator upgrade onto a pre-existing dormant
memory cluster (which slipped in before the rule was installed) still
reaches the Paused-message branch — defence in depth, not future work.

Non-blocking observation: the `quantity()` CEL library was alpha in
1.28 (behind CRDValidationRatcheting) and stable in 1.29. The strict
floor for the CRD to install cleanly is 1.29, not 1.28; the previous
PR's "1.28+ tested" carry-over was technically right for alpha but
risks support requests from 1.28 users with the gate off. Tighten
README, docs/concepts.md, and docs/installation.md to "1.29+".

Signed-off-by: Timofei Larkin <[email protected]>

* Address review of CEL validation PR

Two of the three blockers raised were real:

1. docs/concepts.md and docs/installation.md attributed the quantity()
   gating to CRDValidationRatcheting. Wrong gate: that's KEP-4008
   (allow lingering schema violations on Update, GA in 1.33), and is
   unrelated to CEL. The actual gating story is:

     - CEL CRD validation (CustomResourceValidationExpressions): beta
       1.25, GA 1.29.
     - quantity() CEL extension: added in 1.28.

   Safe floor for both pieces GA is 1.29; that's also the floor the
   docs already settled on for unrelated reasons. Rewrite the paragraph
   in concepts.md and the installation.md prerequisite row to describe
   reality and drop the CRDValidationRatcheting red herring entirely —
   it would actively mislead a cluster admin toggling the wrong gate.

2. The Go doc comment on EtcdClusterSpec (which controller-gen carries
   through to the generated CRD YAML's `description` field) still said
   "k8s 1.28+ apiserver-enforced". Operators reading
   `kubectl explain etcdcluster.spec` would see 1.28+ while the docs
   say 1.29+. Bump the godoc to match; regenerate the CRD YAML so the
   apiserver-served schema agrees.

The reviewer also raised a fourth "blocker" about documenting the
difference between Gi (binary) and G (decimal) quantity units in case
a user is surprised that storage: 1Gi → 1G is rejected as a shrink.
Not addressed: that's standard Kubernetes resource.Quantity semantics
(every PVC, memory limit, CPU request, ... behaves identically), and
documenting it in this operator's docs sets the precedent that every
operator should re-document k8s primitives. The CEL rule's error
"spec.storage cannot be shrunk" is correct and terse; users surprised
by 1Gi vs 1G need k8s docs, not ours.

Signed-off-by: Timofei Larkin <[email protected]>

---------

Signed-off-by: Timofei Larkin <[email protected]>
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.

Fill basic project information

4 participants