diff --git a/cluster/cluster.go b/cluster/cluster.go index 5a53713c..58d9cda1 100644 --- a/cluster/cluster.go +++ b/cluster/cluster.go @@ -11,6 +11,7 @@ import ( "github.com/rancher/rke/services" "github.com/rancher/types/apis/cluster.cattle.io/v1" "github.com/sirupsen/logrus" + "golang.org/x/crypto/ssh" yaml "gopkg.in/yaml.v2" "k8s.io/client-go/kubernetes" "k8s.io/client-go/util/cert" @@ -137,6 +138,7 @@ func ReconcileCluster(kubeCluster, currentCluster *Cluster) error { if err != nil { return fmt.Errorf("Failed to initialize new kubernetes client: %v", err) } + key, _ := checkEncryptedKey(kubeCluster.SSHKeyPath) logrus.Infof("[reconcile] Check Control plane hosts to be deleted") cpToDelete := hosts.GetToDeleteHosts(currentCluster.ControlPlaneHosts, kubeCluster.ControlPlaneHosts) @@ -144,6 +146,11 @@ func ReconcileCluster(kubeCluster, currentCluster *Cluster) error { if err := hosts.DeleteNode(&toDeleteHost, kubeClient); err != nil { return fmt.Errorf("Failed to delete controlplane node %s from cluster", toDeleteHost.AdvertisedHostname) } + // attempting to clean up the host + if err := reconcileHostCleaner(toDeleteHost, key, false); err != nil { + logrus.Warnf("[reconcile] Couldn't clean up controlplane node [%s]: %v", toDeleteHost.AdvertisedHostname, err) + continue + } } logrus.Infof("[reconcile] Check worker hosts to be deleted") @@ -152,6 +159,11 @@ func ReconcileCluster(kubeCluster, currentCluster *Cluster) error { if err := hosts.DeleteNode(&toDeleteHost, kubeClient); err != nil { return fmt.Errorf("Failed to delete worker node %s from cluster", toDeleteHost.AdvertisedHostname) } + // attempting to clean up the host + if err := reconcileHostCleaner(toDeleteHost, key, true); err != nil { + logrus.Warnf("[reconcile] Couldn't clean up worker node [%s]: %v", toDeleteHost.AdvertisedHostname, err) + continue + } } // Rolling update on change for nginx Proxy @@ -167,6 +179,23 @@ func ReconcileCluster(kubeCluster, currentCluster *Cluster) error { return nil } +func reconcileHostCleaner(toDeleteHost hosts.Host, key ssh.Signer, worker bool) error { + if err := toDeleteHost.TunnelUp(key); err != nil { + return fmt.Errorf("Not able to reach the host: %v", err) + } + if err := services.RemoveControlPlane([]hosts.Host{toDeleteHost}); err != nil { + return fmt.Errorf("Couldn't remove control plane: %v", err) + } + + if err := services.RemoveWorkerPlane(nil, []hosts.Host{toDeleteHost}); err != nil { + return fmt.Errorf("Couldn't remove worker plane: %v", err) + } + if err := toDeleteHost.CleanUp(); err != nil { + return fmt.Errorf("Not able to clean the host: %v", err) + } + return nil +} + func rebuildLocalAdminConfig(kubeCluster *Cluster) error { logrus.Infof("[reconcile] Rebuilding and update local kube config") currentKubeConfig := kubeCluster.Certificates[pki.KubeAdminCommonName] diff --git a/hosts/dialer.go b/hosts/dialer.go index 4bad4df0..614f8264 100644 --- a/hosts/dialer.go +++ b/hosts/dialer.go @@ -25,19 +25,19 @@ func (d *dialer) Dial(network, addr string) (net.Conn, error) { // Build SSH client configuration cfg, err := makeSSHConfig(d.host.User, d.signer) if err != nil { - logrus.Fatalf("Error configuring SSH: %v", err) + return nil, fmt.Errorf("Error configuring SSH: %v", err) } // Establish connection with SSH server conn, err := ssh.Dial("tcp", sshAddr, cfg) if err != nil { - logrus.Fatalf("Error establishing SSH connection: %v", err) + return nil, fmt.Errorf("Error establishing SSH connection: %v", err) } if len(d.host.DockerSocket) == 0 { d.host.DockerSocket = "/var/run/docker.sock" } remote, err := conn.Dial("unix", d.host.DockerSocket) if err != nil { - logrus.Fatalf("Error connecting to Docker socket on host [%s]: %v", d.host.AdvertisedHostname, err) + return nil, fmt.Errorf("Error connecting to Docker socket on host [%s]: %v", d.host.AdvertisedHostname, err) } return remote, err } diff --git a/hosts/hosts.go b/hosts/hosts.go index 64ec538a..f013b065 100644 --- a/hosts/hosts.go +++ b/hosts/hosts.go @@ -28,7 +28,7 @@ const ( ) func (h *Host) CleanUp() error { - logrus.Infof("[down] Cleaning up host [%s]", h.AdvertisedHostname) + logrus.Infof("[hosts] Cleaning up host [%s]", h.AdvertisedHostname) toCleanDirs := []string{ ToCleanEtcdDir, ToCleanSSLDir, @@ -36,7 +36,7 @@ func (h *Host) CleanUp() error { ToCleanCNIBin, ToCleanCalicoRun, } - logrus.Infof("[down] Running cleaner container on host [%s]", h.AdvertisedHostname) + logrus.Infof("[hosts] Running cleaner container on host [%s]", h.AdvertisedHostname) imageCfg, hostCfg := buildCleanerConfig(h, toCleanDirs) if err := docker.DoRunContainer(h.DClient, imageCfg, hostCfg, CleanerContainerName, h.AdvertisedHostname, CleanerContainerName); err != nil { return err @@ -46,11 +46,11 @@ func (h *Host) CleanUp() error { return err } - logrus.Infof("[down] Removing cleaner container on host [%s]", h.AdvertisedHostname) + logrus.Infof("[hosts] Removing cleaner container on host [%s]", h.AdvertisedHostname) if err := docker.RemoveContainer(h.DClient, h.AdvertisedHostname, CleanerContainerName); err != nil { return err } - logrus.Infof("[down] Successfully cleaned up host [%s]", h.AdvertisedHostname) + logrus.Infof("[hosts] Successfully cleaned up host [%s]", h.AdvertisedHostname) return nil }