package lifecycle import ( "context" "fmt" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" v1etcd "edge-infra.dev/pkg/sds/etcd/operator/apis/etcdmember/v1" "edge-infra.dev/pkg/sds/lib/etcd/client" ) // destroy removes all traces of an EtcdMember. This includes // removing the member from the etcd cluster and then deleting the EtcdMember // object. Deleting the EtcdMember object will also delete the associated // secret for the EtcdMember due to the cascading delete behaviour. func (r *Reconciler) destroy(ctx context.Context, handlers *Handlers) error { // delete the EtcdMember object from the API server incase the EtcdMember // came in unhealthy but the deletion process had not been started yet if err := handlers.member.DeleteRemote(ctx); err != nil { return fmt.Errorf("failed to delete EtcdMember: %w", err) } // remove the member from the etcd cluster if err := r.removeFromCluster(ctx, handlers); err != nil { return fmt.Errorf("failed to remove member from etcd cluster: %w", err) } // remove the finalizer so that the deletion completes err := handlers.member.WithReconcileRemote(ctx, func(e *v1etcd.EtcdMember) { controllerutil.RemoveFinalizer(e, v1etcd.Finalizer) }) if err != nil { return fmt.Errorf("failed to remove EtcdMember finalizer: %w", err) } r.Metrics.Custom.RecordEtcdMemberDelete(handlers.member.EtcdMember) return nil } // removeEtcdMember removes the current EtcdMember from the etcd cluster func (r *Reconciler) removeFromCluster(ctx context.Context, handlers *Handlers) error { resp, err := r.EtcdRetryClient.SafeMemberList(ctx) if err != nil { return err } // find the etcd member that matches the EtcdMember we are deleting // and remove it from the etcd cluster for _, m := range resp.Members { if m.Name == handlers.member.Name || m.PeerURLs[0] == handlers.member.PeerURL() { if _, err := r.EtcdRetryClient.SafeMemberRemove(ctx, m.ID); client.IgnoreMemberNotFound(err) != nil { return err } } } return nil }