Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: aenix-io/etcd-operator
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.3.0
Choose a base ref
...
head repository: aenix-io/etcd-operator
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref

Commits on Jul 3, 2024

  1. fix RBAC in Helm-chart (#247)

    Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
    kvaps authored Jul 3, 2024
    Copy the full SHA
    7367339 View commit details
  2. fix: sort etcd args to make them deterministic (#249)

    Fix non-deterministic order of etcd args.
    fixes #248
    sircthulhu authored Jul 3, 2024
    Copy the full SHA
    ec7f117 View commit details

Commits on Jul 12, 2024

  1. Set extraArgs in the end of args processing (#250)

    Set extraArgs in the end of args processing to let them overwrite
    default values
    makhov authored Jul 12, 2024
    Copy the full SHA
    d3f1892 View commit details

Commits on Jul 22, 2024

  1. Remove custom code for managing conditions. (#253)

    Since k8s offers built-in libraries for adding, updating and modifying
    conditions, there is not that much to gain from maintaining our own
    libraries, which we need to test and update ourselves.
    lllamnyp authored Jul 22, 2024
    Copy the full SHA
    197ac6e View commit details
  2. Add resizing operation

    Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
    kvaps committed Jul 22, 2024
    Copy the full SHA
    19374dc View commit details
  3. add e2e test for PVC and resize

    Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
    kvaps committed Jul 22, 2024
    Copy the full SHA
    2734299 View commit details
  4. update webhook to reject decreasing storage size

    Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
    kvaps committed Jul 22, 2024
    Copy the full SHA
    6121321 View commit details

Commits on Jul 23, 2024

  1. Add resizing operation (#254)

    kvaps authored Jul 23, 2024
    Copy the full SHA
    32e90c8 View commit details
  2. Prepare release v0.4 (#255)

    kvaps authored Jul 23, 2024
    Copy the full SHA
    dc76460 View commit details

Commits on Jul 30, 2024

  1. Copy the full SHA
    3a140f0 View commit details
  2. Copy the full SHA
    0c4e50d View commit details

Commits on Aug 9, 2024

  1. Add watch verb for storageclasses rbac (#258)

    Fixes these errors: `E0804 17:31:18.410670 1 reflector.go:150]
    pkg/mod/k8s.io/client-go@v0.30.2/tools/cache/reflector.go:232: Failed to
    watch *v1.StorageClass: unknown (get storageclasses.storage.k8s.io)`
    sholdee authored Aug 9, 2024
    Copy the full SHA
    bb350c3 View commit details

Commits on Aug 15, 2024

  1. Add a helper set library to facilitate implementation of the new heal…

    …th check procedure (#252)
    
    This is the first PR in a series of [stacked
    PRs](https://www.stacking.dev/), aimed ultimately at implementing the
    features described in #181 and #207. The next PR in the stack can be
    found at #259.
    lllamnyp authored Aug 15, 2024
    Copy the full SHA
    28b0def View commit details

Commits on Aug 19, 2024

  1. Add @lllamnyp to codeowners of some sections (#262)

    Co-authored-by: Andrei Kvapil <kvapss@gmail.com>
    lllamnyp and kvaps authored Aug 19, 2024
    Copy the full SHA
    51131a1 View commit details

Commits on Sep 10, 2024

  1. Separate ConfigMap templating and creation

    This commit factors out the building of a corev1.ConfigMap struct into a separate function, while leaving the logic of determining key parameters, such as the initial cluster, state, etc, as well as sending the request to the k8s API server in the already existing CreateOrUpdate function. This will be useful in the future, when this logic will be moved out of the factory library and into the reconciliation loop.
    lllamnyp committed Sep 10, 2024
    Copy the full SHA
    cb2a88f View commit details
  2. Copy the full SHA
    e00e6cb View commit details

Commits on Oct 15, 2024

  1. wait for client cert to become ready before getting etcd client (#269)

    The test of etcd cluster with TLS and auth config fails frequently,
    because the client certificate does not get created, before the etcd
    cluster is up and running. This PR adds a step to wait for the client
    cert to become ready, before executing the rest of the tests.
    
    <!-- This is an auto-generated comment: release notes by coderabbit.ai
    -->
    
    ## Summary by CodeRabbit
    
    - **New Features**
    - Reduced RSA private key sizes for various certificates to enhance
    security.
    - Added a new end-to-end test case to ensure readiness of TLS client
    certificates before proceeding with cluster operations.
    
    - **Bug Fixes**
    - Improved test reliability by ensuring TLS certificates are ready
    before stateful set readiness checks.
    
    <!-- end of auto-generated comment: release notes by coderabbit.ai -->
    lllamnyp authored Oct 15, 2024
    Copy the full SHA
    f0ec0a9 View commit details
  2. Add utility functions

    lllamnyp committed Oct 15, 2024
    Copy the full SHA
    5e22c32 View commit details
  3. Copy the full SHA
    a8076da View commit details

Commits on Dec 17, 2024

  1. update CODEOWNERS (#275)

    <!-- This is an auto-generated comment: release notes by coderabbit.ai
    -->
    
    ## Summary by CodeRabbit
    
    - **Chores**
    - Updated ownership assignments for various directories and file types
    to include new code owners.
    
    <!-- end of auto-generated comment: release notes by coderabbit.ai -->
    
    Signed-off-by: Artem Bortnikov <artem.bortnikov@telekom.com>
    aobort authored Dec 17, 2024
    Copy the full SHA
    ca39d30 View commit details
  2. Add watch verb for storageclasses (#266)

    this PR fixes the errors:
    
    ```
    E0924 11:31:59.069472       1 reflector.go:150] pkg/mod/k8s.io/client-go@v0.30.2/tools/cache/reflector.go:232: Failed to watch *v1.StorageClass: unknown (get storageclasses.storage.k8s.io)
    E0924 11:32:57.379956       1 reflector.go:150] pkg/mod/k8s.io/client-go@v0.30.2/tools/cache/reflector.go:232: Failed to watch *v1.StorageClass: unknown (get storageclasses.storage.k8s.io)
    E0924 11:33:50.776342       1 reflector.go:150] pkg/mod/k8s.io/client-go@v0.30.2/tools/cache/reflector.go:232: Failed to watch *v1.StorageClass: unknown (get storageclasses.storage.k8s.io)
    E0924 11:34:21.872401       1 reflector.go:150] pkg/mod/k8s.io/client-go@v0.30.2/tools/cache/reflector.go:232: Failed to watch *v1.StorageClass: unknown (get storageclasses.storage.k8s.io)
    ```
    
    <!-- This is an auto-generated comment: release notes by coderabbit.ai
    -->
    
    ## Summary by CodeRabbit
    
    - **New Features**
    - Enhanced role permissions to include the ability to monitor changes to
    resources in real-time by adding the `watch` verb.
    - **Bug Fixes**
    - Improved resource management capabilities for the
    `EtcdClusterReconciler` by updating permissions to allow watching of
    storage classes.
    
    <!-- end of auto-generated comment: release notes by coderabbit.ai -->
    kvaps authored Dec 17, 2024
    Copy the full SHA
    40373b6 View commit details
  3. Create a design-document for the controller (#181)

    # Motivation
    
    I started some "R'n'D" (scare quotes intended) for implementing scale
    up, scale down, self-healing and so on and quickly realized, that the
    coding of the member add/member remove and similar steps is the more
    trivial part of the undertaking. The difficult part is coming up with a
    working algorithm that can correctly deduce the cluster's state and
    execute the necessary actions at the right time.
    
    To better reason about the controller's algorithm now, and to better
    develop it going forward, I feel it is important to have good
    documentation of the current design and the intended next steps, so I
    started with trying to document the current state of the code.
    
    # Results
    
    This document contains a mermaid flowchart that outlines the
    reconciliation loop. It is better viewed in [rendered
    form](https://github.com/aenix-io/etcd-operator/blob/docs/design/docs/DESIGN.md).
    
    Going forward, I envision this document to have at least three purposes:
    * Let the developers spot flaws and prompt them to open issues.
    * Act as a more detailed form of documentation for advanced users.
    * Be a blueprint for implementing anything non-trivial.
    
    <!-- This is an auto-generated comment: release notes by coderabbit.ai
    -->
    ## Summary by CodeRabbit
    
    - **Documentation**
    - Updated the design document for the `EtcdCluster` custom resources
    with a detailed flowchart illustrating the reconciliation process and
    lifecycle management within a Kubernetes environment.
    <!-- end of auto-generated comment: release notes by coderabbit.ai -->
    
    ---------
    
    Co-authored-by: Hidden Marten <hiddenmarten@gmail.com>
    Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
    3 people authored Dec 17, 2024
    Copy the full SHA
    bfcf533 View commit details

Commits on Jan 31, 2025

  1. Add OIDC auth support in kubectl-etcd plugin (#272)

    Subj. Without such import, there is auth error:
    
    ```
    Error setting up etcd client: error creating Kubernetes client: no Auth Provider found for name "oidc"
    ```
    
    <!-- This is an auto-generated comment: release notes by coderabbit.ai
    -->
    
    ## Summary by CodeRabbit
    
    - **New Features**
    - Introduced commands for managing etcd pods, including status checks,
    defragmentation, compaction, alarm management, and member management.
      
    - **Bug Fixes**
    - Standardized error handling for improved user feedback during command
    execution.
    
    <!-- end of auto-generated comment: release notes by coderabbit.ai -->
    evgkrsk authored Jan 31, 2025
    Copy the full SHA
    d059eb3 View commit details
Showing with 833 additions and 401 deletions.
  1. +11 −10 CODEOWNERS
  2. +1 −1 Makefile
  3. +18 −0 api/v1alpha1/etcdcluster_webhook.go
  4. +40 −0 api/v1alpha1/etcdcluster_webhook_test.go
  5. +33 −0 charts/etcd-operator/templates/rbac/clusterrole-manager-role.yml
  6. +1 −0 cmd/kubectl-etcd/main.go
  7. +18 −1 config/rbac/role.yaml
  8. +81 −0 docs/DESIGN.md
  9. +4 −0 docs/sts-flow.svg
  10. +2 −3 examples/manifests/etcdcluster-persistent.yaml
  11. +6 −6 examples/manifests/etcdcluster-with-external-certificates.yaml
  12. +1 −0 go.mod
  13. +119 −18 internal/controller/etcdcluster_controller.go
  14. +0 −110 internal/controller/factory/condition.go
  15. +0 −129 internal/controller/factory/condition_test.go
  16. +36 −28 internal/controller/factory/{configMap.go → configmap.go}
  17. +17 −8 internal/controller/factory/configmap_test.go
  18. +85 −1 internal/controller/factory/pvc.go
  19. +161 −0 internal/controller/factory/pvc_test.go
  20. +56 −38 internal/controller/factory/statefulset.go
  21. +22 −1 internal/controller/factory/statefulset_test.go
  22. +10 −3 internal/controller/observables.go
  23. +29 −0 pkg/set/set.go
  24. +4 −4 site/content/en/docs/{v0.3 → v0.4}/_index.md
  25. 0 site/content/en/docs/{v0.3 → v0.4}/contribution-guidelines/_index.md
  26. 0 site/content/en/docs/{v0.3 → v0.4}/examples/_index.md
  27. 0 site/content/en/docs/{v0.3 → v0.4}/getting-started/_index.md
  28. 0 site/content/en/docs/{v0.3 → v0.4}/overview/_index.md
  29. 0 site/content/en/docs/{v0.3 → v0.4}/reference/_index.md
  30. +2 −2 site/content/en/docs/{v0.3 → v0.4}/reference/api.md
  31. +3 −3 site/hugo.yaml
  32. +73 −35 test/e2e/e2e_test.go
21 changes: 11 additions & 10 deletions CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
/.github @hiddenmarten @AlexGluck @aobort
/api @sircthulhu @Kirill-Garbar
/charts @hiddenmarten @AlexGluck @aobort
/cmd @sircthulhu @Kirill-Garbar
/config @sircthulhu @Kirill-Garbar
/hack @sircthulhu @Kirill-Garbar
/internal @sircthulhu @Kirill-Garbar @sergeyshevch
/test @sircthulhu @Kirill-Garbar @hiddenmarten @AlexGluck @aobort
/site @sergeyshevch @Kirill-Garbar
/*.md @kvaps @Kirill-Garbar
/.github @kvaps @lllamnyp @Kirill-Garbar @aobort
/api @kvaps @lllamnyp @Kirill-Garbar @aobort
/charts @kvaps @lllamnyp @Kirill-Garbar @aobort
/cmd @kvaps @lllamnyp @Kirill-Garbar @aobort
/config @kvaps @lllamnyp @Kirill-Garbar @aobort
/hack @kvaps @lllamnyp @Kirill-Garbar @aobort
/internal @kvaps @lllamnyp @Kirill-Garbar @aobort
/pkg @kvaps @lllamnyp @Kirill-Garbar @aobort
/test @kvaps @lllamnyp @Kirill-Garbar @aobort
/site @kvaps @lllamnyp @Kirill-Garbar @aobort
/*.md @kvaps @lllamnyp @Kirill-Garbar @aobort
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -56,7 +56,7 @@ generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."

.PHONY: generate-docs
generate-docs: crd-ref-docs ## Generate CRD reference documentation.
generate-docs: yq crd-ref-docs ## Generate CRD reference documentation.
@$(eval VERSION := $(shell $(YQ) '.params.version' site/hugo.yaml))
$(CRD_REF_DOCS) --config=.crd-docs.yaml --renderer=markdown --templates-dir="site/reference-templates" --output-path="site/content/en/docs/$(VERSION)/reference/api.md"

18 changes: 18 additions & 0 deletions api/v1alpha1/etcdcluster_webhook.go
Original file line number Diff line number Diff line change
@@ -107,11 +107,26 @@ func (r *EtcdCluster) ValidateUpdate(old runtime.Object) (admission.Warnings, er
etcdclusterlog.Info("validate update", "name", r.Name)
var warnings admission.Warnings
oldCluster := old.(*EtcdCluster)

// Check if replicas are being resized
if *oldCluster.Spec.Replicas != *r.Spec.Replicas {
warnings = append(warnings, "cluster resize is not currently supported")
}

var allErrors field.ErrorList

// Check if storage size is being decreased
oldStorage := oldCluster.Spec.Storage.VolumeClaimTemplate.Spec.Resources.Requests[corev1.ResourceStorage]
newStorage := r.Spec.Storage.VolumeClaimTemplate.Spec.Resources.Requests[corev1.ResourceStorage]
if newStorage.Cmp(oldStorage) < 0 {
allErrors = append(allErrors, field.Invalid(
field.NewPath("spec", "storage", "volumeClaimTemplate", "resources", "requests", "storage"),
newStorage.String(),
"decreasing storage size is not allowed"),
)
}

// Check if storage type is changing
if oldCluster.Spec.Storage.EmptyDir == nil && r.Spec.Storage.EmptyDir != nil ||
oldCluster.Spec.Storage.EmptyDir != nil && r.Spec.Storage.EmptyDir == nil {
allErrors = append(allErrors, field.Invalid(
@@ -121,6 +136,7 @@ func (r *EtcdCluster) ValidateUpdate(old runtime.Object) (admission.Warnings, er
)
}

// Validate PodDisruptionBudget
pdbWarnings, pdbErr := r.validatePdb()
if pdbErr != nil {
allErrors = append(allErrors, pdbErr...)
@@ -129,11 +145,13 @@ func (r *EtcdCluster) ValidateUpdate(old runtime.Object) (admission.Warnings, er
warnings = append(warnings, pdbWarnings...)
}

// Validate Security
securityErr := r.validateSecurity()
if securityErr != nil {
allErrors = append(allErrors, securityErr...)
}

// Validate Options
if errOptions := validateOptions(r); errOptions != nil {
allErrors = append(allErrors, field.Invalid(
field.NewPath("spec", "options"),
40 changes: 40 additions & 0 deletions api/v1alpha1/etcdcluster_webhook_test.go
Original file line number Diff line number Diff line change
@@ -111,6 +111,46 @@ var _ = Describe("EtcdCluster Webhook", func() {
}
})

It("Should reject decreasing storage size", func() {
etcdCluster := &EtcdCluster{
Spec: EtcdClusterSpec{
Replicas: ptr.To(int32(1)),
Storage: StorageSpec{
VolumeClaimTemplate: EmbeddedPersistentVolumeClaim{
Spec: corev1.PersistentVolumeClaimSpec{
Resources: corev1.VolumeResourceRequirements{
Requests: map[corev1.ResourceName]resource.Quantity{
corev1.ResourceStorage: resource.MustParse("5Gi"),
},
},
},
},
},
},
}
oldCluster := &EtcdCluster{
Spec: EtcdClusterSpec{
Replicas: ptr.To(int32(1)),
Storage: StorageSpec{
VolumeClaimTemplate: EmbeddedPersistentVolumeClaim{
Spec: corev1.PersistentVolumeClaimSpec{
Resources: corev1.VolumeResourceRequirements{
Requests: map[corev1.ResourceName]resource.Quantity{
corev1.ResourceStorage: resource.MustParse("10Gi"),
},
},
},
},
},
},
}
_, err := etcdCluster.ValidateUpdate(oldCluster)
if Expect(err).To(HaveOccurred()) {
statusErr := err.(*errors.StatusError)
Expect(statusErr.ErrStatus.Message).To(ContainSubstring("decreasing storage size is not allowed"))
}
})

It("Should allow changing emptydir size", func() {
etcdCluster := &EtcdCluster{
Spec: EtcdClusterSpec{
33 changes: 33 additions & 0 deletions charts/etcd-operator/templates/rbac/clusterrole-manager-role.yml
Original file line number Diff line number Diff line change
@@ -17,6 +17,22 @@ rules:
- patch
- update
- watch
- apiGroups:
- ""
resources:
- endpoints
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- secrets
verbs:
- list
- get
- watch
- apiGroups:
- ""
resources:
@@ -41,6 +57,23 @@ rules:
- patch
- update
- watch
- apiGroups:
- ""
resources:
- persistentvolumeclaims
verbs:
- get
- list
- patch
- watch
- apiGroups:
- "storage.k8s.io"
resources:
- storageclasses
verbs:
- get
- list
- watch
- apiGroups:
- etcd.aenix.io
resources:
1 change: 1 addition & 0 deletions cmd/kubectl-etcd/main.go
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
_ "k8s.io/client-go/plugin/pkg/client/auth" // Import all auth providers
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/tools/portforward"
"k8s.io/client-go/transport/spdy"
19 changes: 18 additions & 1 deletion config/rbac/role.yaml
Original file line number Diff line number Diff line change
@@ -24,13 +24,22 @@ rules:
- get
- list
- watch
- apiGroups:
- ""
resources:
- persistentvolumeclaims
verbs:
- get
- list
- patch
- watch
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- view
- watch
- apiGroups:
- ""
@@ -94,3 +103,11 @@ rules:
- patch
- update
- watch
- apiGroups:
- storage.k8s.io
resources:
- storageclasses
verbs:
- get
- list
- watch
81 changes: 81 additions & 0 deletions docs/DESIGN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Design

This document describes the interaction between `EtcdCluster` custom resources and other Kubernetes
primitives and gives an overview of the underlying implementation.

## Reconciliation flowchart

```mermaid
flowchart TD
Start(Start) --> A[Ensure service.]
A --> AA{Are there any\nendpoints?}
AA --> |Yes| AAA[Connect to the cluster\nand fetch all statuses.]
AAA --> |Got some response| AAAA{All reachable\nmembers have the\nsame cluster ID?}
AAAA --> |Yes| AAAAA{Is cluster\nin quorum?}
AAAAA --> |Yes| AAAAAA{Are all members \nmanaged by the operator?}
AAAAAA --> |Yes| AAAAAAA["`
Promote any learners.
Ensure configmap with initial cluster matching existing members and cluster state=existing.
Ensure StatefulSet with replicas = max member ordinal + 1
`"]
AAAAAAA --> |OK| AAAAAAAA{Are all\nmembers healthy?}
AAAAAAAA --> |Yes| AAAAAAAAA{Are all STS pods present\nin the member list?}
AAAAAAAAA --> |Yes| AAAAAAAAAA{Is the\nEtcdCluster\nsize equal to the\nStatefulSet\nsize?}
AAAAAAAAAA -->|Yes| AAAAAAAAAAA[Set cluster\nstatus to ready.]
AAAAAAAAAAA --> HappyStop([Stop])
AAAAAAAAAA --> |No, desired\nsize larger| AAAAAAAAAAB[Ensure ConfigMap with\ninitial cluster state existing\nand initial cluster URLs\nequal to current cluster\nplus one member, do\n'member add' API call and\nincrement StatefulSet size.]
AAAAAAAAAAB --> ScaleUpStop([Stop])
AAAAAAAAAA --> |No, desired\nsize smaller| AAAAAAAAAAC[Member remove API\ncall, then decrement\nStatefulSet size\nthen delete PVC.]
AAAAAAAAAAC --> ScaleDownStop([Stop])
AAAAAAAAAA --> |Etcd replicas=0\nSTS replicas=1| AAAAAAAAAAD[Decrement\nSTS to zero]
AAAAAAAAAAD --> ScaleToZeroStop([Stop])
AAAAAAAA --> |No| AAAAAAAAB1[On timeout evict member.]
AAAAAAAAB1 --> AAAAAAAAB2[Delete PVC, ensure ConfigMap with\nmembers + this one and delete pod.]
AAAAAAAAA --> |No| AAAAAAAAB2
AAAAAAA -->|Error| AAAAAAAB([Requeue])
AAAAAA --> |No| AAAAAAB([Not implemented,\nstop.])
AAAAA --> |No| AAAAAB([Quorum Loss Detected:
1. Check for temporary issues:
- Network partitions
- Pod scheduling problems
2. If temporary, wait for recovery
3. If permanent:
- Alert operators
- Document disaster recovery steps
- Consider backup restoration])
AAAA --> |No| AAAAB[Cluster is in\nsplit-brain. Set\nerror status.]
AAAAB --> AAAABStop([Stop])
AAA --> |No members\nreached| AAAB{Is the STS\npresent?}
AAAB --> |Yes| AAABA{"`Does it have the correct pod spec?`"}
AAABA --> |Yes| AAABAA(["`The statefulset cannot be ready, as the ready and liveness probes must be failing. Hope it becomes ready or wait for user intervention.`"])
AAABA --> |No| AAABAB["`Patch the podspec`"]
AAAB --> |No| AAABB(["`Looks like it was deleted with cascade=orphan. Create it again and see what happens`"])
AA --> |No| AAB{Is the STS\npresent?}
AAB --> |Yes| AABA{Does it have the\ncorrect pod spec?}
AABA --> |Yes| AABAA{Is it\nready?}
AABAA --> |Yes| AABAAA{Then it must have\nspec.replicas==0\n Is EtcdCluster\n.spec.replicas==0?}
AABAAA --> |Yes| AABAAAA([Cluster successfully\nscaled to zero, stop.])
AABAAA --> |No| AABAAAB["`
Ensure ConfigMap with initial cluster = new,
initial cluster peers with single member name-0,
increment STS size.
`"]
AABAA --> |No| AABAAB([Stop and wait, either\nit will turn ready soon\nand the next reconcile\nwill move things along,\nor user intervention is\nneeded])
AABA --> |No| AABAB[Patch the podspec]
AAB --> |No| AABB[Create configmap, initial state new\ninitial cluster according to spec.\nreplicas, create statefulset.]
```
Loading