Skip to content

Draft: do observables as interface #281

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: feat/new-status-check-pt4
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 24 additions & 14 deletions internal/controller/etcdcluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,13 @@

// Reconcile checks CR and current cluster state and performs actions to transform current state to desired.
func (r *EtcdClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
var state State
log.Debug(ctx, "reconciling object")
state := &observables{}
state.instance = &etcdaenixiov1alpha1.EtcdCluster{}
err := r.Get(ctx, req.NamespacedName, state.instance)

// TODO: marry abstract interface with actual object pointer
// state := &observables{}
// state.instance = &etcdaenixiov1alpha1.EtcdCluster{}
err := state.GetEtcdCluster()
if err != nil {
if errors.IsNotFound(err) {
log.Debug(ctx, "object not found")
Expand All @@ -86,9 +89,10 @@
// Error retrieving object, requeue
return reconcile.Result{}, err
}
// If object is being deleted, skipping reconciliation
if !state.instance.DeletionTimestamp.IsZero() {
return reconcile.Result{}, nil

// If object is being deleted, handle finalizers, dependent objects, etc
if state.PendingDeletion() {
return ctrl.Result{}, r.handleDeletion(ctx, state)
}

// create two services and the pdb
Expand All @@ -98,14 +102,14 @@
}

// fetch STS if exists
err = r.Get(ctx, req.NamespacedName, &state.statefulSet)

Check failure on line 105 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / nilaway-lint

state.statefulSet undefined (type State has no field or method statefulSet)

Check failure on line 105 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s latest version

state.statefulSet undefined (type State has no field or method statefulSet)

Check failure on line 105 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s previous version

state.statefulSet undefined (type State has no field or method statefulSet)

Check failure on line 105 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s penultimate version

state.statefulSet undefined (type State has no field or method statefulSet)

Check failure on line 105 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s latest version

state.statefulSet undefined (type State has no field or method statefulSet)

Check failure on line 105 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s penultimate version

state.statefulSet undefined (type State has no field or method statefulSet)

Check failure on line 105 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s previous version

state.statefulSet undefined (type State has no field or method statefulSet)

Check failure on line 105 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / pre-commit

state.statefulSet undefined (type State has no field or method statefulSet)
if client.IgnoreNotFound(err) != nil {
return ctrl.Result{}, fmt.Errorf("couldn't get statefulset: %w", err)
}
// state.stsExists = state.statefulSet.UID != ""

// fetch endpoints
clusterClient, singleClients, err := factory.NewEtcdClientSet(ctx, state.instance, r.Client)

Check failure on line 112 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / nilaway-lint

state.instance undefined (type State has no field or method instance)

Check failure on line 112 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s latest version

state.instance undefined (type State has no field or method instance)

Check failure on line 112 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s previous version

state.instance undefined (type State has no field or method instance)

Check failure on line 112 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s penultimate version

state.instance undefined (type State has no field or method instance)

Check failure on line 112 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s latest version

state.instance undefined (type State has no field or method instance)

Check failure on line 112 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s penultimate version

state.instance undefined (type State has no field or method instance)

Check failure on line 112 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s previous version

state.instance undefined (type State has no field or method instance)

Check failure on line 112 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / pre-commit

state.instance undefined (type State has no field or method instance)
if err != nil {
return ctrl.Result{}, err
}
Expand All @@ -114,23 +118,23 @@
// if clusterClient != nil {
// state.endpoints = clusterClient.Endpoints()
// }
state.clusterClient = clusterClient

Check failure on line 121 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / nilaway-lint

state.clusterClient undefined (type State has no field or method clusterClient)

Check failure on line 121 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s latest version

state.clusterClient undefined (type State has no field or method clusterClient)

Check failure on line 121 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s previous version

state.clusterClient undefined (type State has no field or method clusterClient)

Check failure on line 121 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s penultimate version

state.clusterClient undefined (type State has no field or method clusterClient)

Check failure on line 121 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s latest version

state.clusterClient undefined (type State has no field or method clusterClient)

Check failure on line 121 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s penultimate version

state.clusterClient undefined (type State has no field or method clusterClient)

Check failure on line 121 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s previous version

state.clusterClient undefined (type State has no field or method clusterClient)

Check failure on line 121 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / pre-commit

state.clusterClient undefined (type State has no field or method clusterClient)
state.singleClients = singleClients

Check failure on line 122 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / nilaway-lint

state.singleClients undefined (type State has no field or method singleClients)

Check failure on line 122 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s latest version

state.singleClients undefined (type State has no field or method singleClients)

Check failure on line 122 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s previous version

state.singleClients undefined (type State has no field or method singleClients)

Check failure on line 122 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s penultimate version

state.singleClients undefined (type State has no field or method singleClients)

Check failure on line 122 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s latest version

state.singleClients undefined (type State has no field or method singleClients)

Check failure on line 122 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s penultimate version

state.singleClients undefined (type State has no field or method singleClients)

Check failure on line 122 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s previous version

state.singleClients undefined (type State has no field or method singleClients)

Check failure on line 122 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / pre-commit

state.singleClients undefined (type State has no field or method singleClients)

// fetch PVCs
state.pvcs, err = factory.PVCs(ctx, state.instance, r.Client)

Check failure on line 125 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / nilaway-lint

state.pvcs undefined (type State has no field or method pvcs)

Check failure on line 125 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / nilaway-lint

state.instance undefined (type State has no field or method instance)

Check failure on line 125 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s latest version

state.instance undefined (type State has no field or method instance)

Check failure on line 125 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s latest version

state.pvcs undefined (type State has no field or method pvcs)

Check failure on line 125 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s previous version

state.instance undefined (type State has no field or method instance)

Check failure on line 125 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s previous version

state.pvcs undefined (type State has no field or method pvcs)

Check failure on line 125 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s penultimate version

state.instance undefined (type State has no field or method instance)

Check failure on line 125 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s penultimate version

state.pvcs undefined (type State has no field or method pvcs)

Check failure on line 125 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s latest version

state.instance undefined (type State has no field or method instance)

Check failure on line 125 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s latest version

state.pvcs undefined (type State has no field or method pvcs)

Check failure on line 125 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s penultimate version

state.instance undefined (type State has no field or method instance)

Check failure on line 125 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s penultimate version

state.pvcs undefined (type State has no field or method pvcs)

Check failure on line 125 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s previous version

state.instance undefined (type State has no field or method instance)

Check failure on line 125 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s previous version

state.pvcs undefined (type State has no field or method pvcs)

Check failure on line 125 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / pre-commit

state.instance undefined (type State has no field or method instance)

Check failure on line 125 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / pre-commit

state.pvcs undefined (type State has no field or method pvcs)
if err != nil {
return ctrl.Result{}, err
}

if !state.endpointsFound() {

Check failure on line 130 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / nilaway-lint

state.endpointsFound undefined (type State has no field or method endpointsFound)

Check failure on line 130 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s latest version

state.endpointsFound undefined (type State has no field or method endpointsFound)

Check failure on line 130 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s previous version

state.endpointsFound undefined (type State has no field or method endpointsFound)

Check failure on line 130 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s penultimate version

state.endpointsFound undefined (type State has no field or method endpointsFound)

Check failure on line 130 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s latest version

state.endpointsFound undefined (type State has no field or method endpointsFound)

Check failure on line 130 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s penultimate version

state.endpointsFound undefined (type State has no field or method endpointsFound)

Check failure on line 130 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s previous version

state.endpointsFound undefined (type State has no field or method endpointsFound)

Check failure on line 130 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / pre-commit

state.endpointsFound undefined (type State has no field or method endpointsFound)
if !state.statefulSetExists() {

Check failure on line 131 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / nilaway-lint

state.statefulSetExists undefined (type State has no field or method statefulSetExists)

Check failure on line 131 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s latest version

state.statefulSetExists undefined (type State has no field or method statefulSetExists)

Check failure on line 131 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s previous version

state.statefulSetExists undefined (type State has no field or method statefulSetExists)

Check failure on line 131 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s penultimate version

state.statefulSetExists undefined (type State has no field or method statefulSetExists)

Check failure on line 131 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s latest version

state.statefulSetExists undefined (type State has no field or method statefulSetExists)

Check failure on line 131 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s penultimate version

state.statefulSetExists undefined (type State has no field or method statefulSetExists)

Check failure on line 131 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s previous version

state.statefulSetExists undefined (type State has no field or method statefulSetExists)

Check failure on line 131 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / pre-commit

state.statefulSetExists undefined (type State has no field or method statefulSetExists)
return r.createClusterFromScratch(ctx, state) // TODO: needs implementing
}

// update sts pod template (and only pod template) if it doesn't match desired state
if !state.statefulSetPodSpecCorrect() { // TODO: needs implementing

Check failure on line 136 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / nilaway-lint

state.statefulSetPodSpecCorrect undefined (type State has no field or method statefulSetPodSpecCorrect)

Check failure on line 136 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s latest version

state.statefulSetPodSpecCorrect undefined (type State has no field or method statefulSetPodSpecCorrect)

Check failure on line 136 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s previous version

state.statefulSetPodSpecCorrect undefined (type State has no field or method statefulSetPodSpecCorrect)

Check failure on line 136 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s penultimate version

state.statefulSetPodSpecCorrect undefined (type State has no field or method statefulSetPodSpecCorrect)

Check failure on line 136 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s latest version

state.statefulSetPodSpecCorrect undefined (type State has no field or method statefulSetPodSpecCorrect)

Check failure on line 136 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s penultimate version

state.statefulSetPodSpecCorrect undefined (type State has no field or method statefulSetPodSpecCorrect)

Check failure on line 136 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s previous version

state.statefulSetPodSpecCorrect undefined (type State has no field or method statefulSetPodSpecCorrect)

Check failure on line 136 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / pre-commit

state.statefulSetPodSpecCorrect undefined (type State has no field or method statefulSetPodSpecCorrect)
desiredSts := factory.TemplateStatefulSet(state.instance) // TODO: needs implementing

Check failure on line 137 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / nilaway-lint

state.instance undefined (type State has no field or method instance)

Check failure on line 137 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s latest version

state.instance undefined (type State has no field or method instance)

Check failure on line 137 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s previous version

state.instance undefined (type State has no field or method instance)

Check failure on line 137 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test-e2e on k8s penultimate version

state.instance undefined (type State has no field or method instance)

Check failure on line 137 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s latest version

state.instance undefined (type State has no field or method instance)

Check failure on line 137 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s penultimate version

state.instance undefined (type State has no field or method instance)

Check failure on line 137 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / test on k8s previous version

state.instance undefined (type State has no field or method instance)

Check failure on line 137 in internal/controller/etcdcluster_controller.go

View workflow job for this annotation

GitHub Actions / pre-commit

state.instance undefined (type State has no field or method instance)
state.statefulSet.Spec.Template.Spec = desiredSts.Spec.Template.Spec
return ctrl.Result{}, r.patchOrCreateObject(ctx, &state.statefulSet)
}
Expand Down Expand Up @@ -232,7 +236,7 @@
}

// checkAndDeleteStatefulSetIfNecessary deletes the StatefulSet if the specified storage size has changed.
func (r *EtcdClusterReconciler) checkAndDeleteStatefulSetIfNecessary(ctx context.Context, state *observables) error {
func (r *EtcdClusterReconciler) checkAndDeleteStatefulSetIfNecessary(ctx context.Context, state State) error {
for _, volumeClaimTemplate := range state.statefulSet.Spec.VolumeClaimTemplates {
if volumeClaimTemplate.Name != "data" {
continue
Expand All @@ -254,7 +258,7 @@
}

// ensureConditionalClusterObjects creates or updates all objects owned by cluster CR
func (r *EtcdClusterReconciler) ensureConditionalClusterObjects(ctx context.Context, state *observables) error {
func (r *EtcdClusterReconciler) ensureConditionalClusterObjects(ctx context.Context, state State) error {

if err := factory.CreateOrUpdateClusterStateConfigMap(ctx, state.instance, r.Client); err != nil {
log.Error(ctx, err, "reconcile cluster state configmap failed")
Expand All @@ -277,7 +281,7 @@
}

// updateStatusOnErr wraps error and updates EtcdCluster status
func (r *EtcdClusterReconciler) updateStatusOnErr(ctx context.Context, state *observables, err error) (ctrl.Result, error) {
func (r *EtcdClusterReconciler) updateStatusOnErr(ctx context.Context, state State, err error) (ctrl.Result, error) {
// The function 'updateStatusOnErr' will always return non-nil error. Hence, the ctrl.Result will always be ignored.
// Therefore, the ctrl.Result returned by 'updateStatus' function can be discarded.
// REF: https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/reconcile@v0.17.3#Reconciler
Expand All @@ -289,7 +293,7 @@
}

// updateStatus updates EtcdCluster status and returns error and requeue in case status could not be updated due to conflict
func (r *EtcdClusterReconciler) updateStatus(ctx context.Context, state *observables) (ctrl.Result, error) {
func (r *EtcdClusterReconciler) updateStatus(ctx context.Context, state State) (ctrl.Result, error) {
err := r.Status().Update(ctx, state.instance)
if err == nil {
return ctrl.Result{}, nil
Expand All @@ -303,7 +307,7 @@
}

// isStatefulSetReady gets managed StatefulSet and checks its readiness.
func (r *EtcdClusterReconciler) isStatefulSetReady(ctx context.Context, state *observables) (bool, error) {
func (r *EtcdClusterReconciler) isStatefulSetReady(ctx context.Context, state State) (bool, error) {
sts := &appsv1.StatefulSet{}
err := r.Get(ctx, client.ObjectKeyFromObject(state.instance), sts)
if err == nil {
Expand All @@ -323,7 +327,7 @@
Complete(r)
}

func (r *EtcdClusterReconciler) configureAuth(ctx context.Context, state *observables) error {
func (r *EtcdClusterReconciler) configureAuth(ctx context.Context, state State) error {

var err error

Expand Down Expand Up @@ -603,7 +607,7 @@
// ensureUnconditionalObjects creates the two services and the PDB
// which can be created at the start of the reconciliation loop
// without any risk of disrupting the etcd cluster
func (r *EtcdClusterReconciler) ensureUnconditionalObjects(ctx context.Context, state *observables) error {
func (r *EtcdClusterReconciler) ensureUnconditionalObjects(ctx context.Context, state State) error {
const concurrentOperations = 3
c := make(chan error)
defer close(c)
Expand Down Expand Up @@ -669,7 +673,7 @@

// TODO!
// nolint:unparam,unused
func (r *EtcdClusterReconciler) createClusterFromScratch(ctx context.Context, state *observables) (ctrl.Result, error) {
func (r *EtcdClusterReconciler) createClusterFromScratch(ctx context.Context, state State) (ctrl.Result, error) {
cm := factory.TemplateClusterStateConfigMap(state.instance, "new", state.desiredReplicas())
err := ctrl.SetControllerReference(state.instance, cm, r.Scheme)
if err != nil {
Expand Down Expand Up @@ -728,3 +732,9 @@
func (r *EtcdClusterReconciler) promoteLearners(ctx context.Context) error {
return fmt.Errorf("not yet implemented")
}

// TODO!
// nolint:unused
func (r *EtcdClusterReconciler) handleDeletion(ctx context.Context, state State) error {
return fmt.Errorf("not yet implemented")
}
8 changes: 7 additions & 1 deletion internal/controller/etcdcluster_controller_new.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,13 @@ func (r *ClusterReconciler) etcdClusterConfig(ctx context.Context, cluster *etcd

// todo: implement this
func (r *ClusterReconciler) createClusterFromScratch(ctx context.Context, state *observables) error {
panic("not implemented")
if err := r.createOrUpdateClusterStateConfigMap(ctx, state); err != nil {
return err
}
if err := r.createOrUpdateStatefulSet(ctx, state); err != nil {
return err
}
return nil
}

// todo: implement this
Expand Down
7 changes: 7 additions & 0 deletions internal/controller/state.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package controller

type State interface {
ClusterExists() bool
PendingDeletion() bool
GetEtcdCluster() error
}
Loading