func()

in controllers/scale.go [89:127]


func (r *EtcdadmClusterReconciler) removeEtcdMemberAndDeleteMachine(ctx context.Context, etcdClient EtcdClient, peerURL string, machineToDelete *clusterv1.Machine) error {
	log := r.Log
	// Etcdadm has a "reset" command to remove an etcd member. But we can't run that command on the CAPI machine object after it's provisioned.
	// so the following logic is based on how etcdadm performs "reset" https://github.com/kubernetes-sigs/etcdadm/blob/master/cmd/reset.go#L65
	etcdCtx, cancel := context.WithTimeout(ctx, constants.DefaultEtcdRequestTimeout)
	mresp, err := etcdClient.MemberList(etcdCtx)
	cancel()
	if err != nil {
		return fmt.Errorf("error listing members: %v", err)
	}
	localMember, ok := memberForPeerURLs(mresp, []string{peerURL})
	if ok {
		if len(mresp.Members) > 1 {
			log.Info("Removing", "member", localMember.Name)
			etcdCtx, cancel = context.WithTimeout(ctx, constants.DefaultEtcdRequestTimeout)
			_, err = etcdClient.MemberRemove(etcdCtx, localMember.ID)
			cancel()
			if err != nil {
				return fmt.Errorf("failed to remove etcd member %s with error %v", localMember.Name, err)
			}
			if machineToDelete != nil {
				if err := r.Client.Delete(ctx, machineToDelete); err != nil && !apierrors.IsNotFound(err) && !apierrors.IsGone(err) {
					return fmt.Errorf("failed to delete etcd machine %s with error %v", machineToDelete.Name, err)
				}
			}
		} else {
			log.Info("Not removing last member in the cluster", "member", localMember.Name)
		}
	} else {
		log.Info("Member was removed")
		if machineToDelete != nil {
			// this could happen if the etcd member was removed through etcdctl calls, ensure that the machine gets deleted too
			if err := r.Client.Delete(ctx, machineToDelete); err != nil && !apierrors.IsNotFound(err) && !apierrors.IsGone(err) {
				return fmt.Errorf("failed to delete etcd machine %s with error %v", machineToDelete.Name, err)
			}
		}
	}
	return nil
}