diff --git a/pkg/apis/v1alpha/nodes/nodes_handler.go b/pkg/apis/v1alpha/nodes/nodes_handler.go index c3682c2ba..62ed76c90 100644 --- a/pkg/apis/v1alpha/nodes/nodes_handler.go +++ b/pkg/apis/v1alpha/nodes/nodes_handler.go @@ -19,6 +19,8 @@ package nodes import ( "github.com/emicklei/go-restful" + "net/http" + "kubesphere.io/kubesphere/pkg/constants" "kubesphere.io/kubesphere/pkg/filter/route" "kubesphere.io/kubesphere/pkg/models" @@ -32,6 +34,10 @@ func Register(ws *restful.WebService, subPath string) { ws.Route(ws.GET(subPath+"/{nodename}").To(handleSingleNode).Filter(route.RouteLogging)). Consumes(restful.MIME_JSON, restful.MIME_XML). Produces(restful.MIME_JSON) + + ws.Route(ws.POST(subPath+"/{nodename}/drainage").To(handleDrainNode).Filter(route.RouteLogging)). + Consumes(restful.MIME_JSON, restful.MIME_XML). + Produces(restful.MIME_JSON) } func handleNodes(request *restful.Request, response *restful.Response) { @@ -60,3 +66,21 @@ func handleSingleNode(request *restful.Request, response *restful.Response) { response.WriteAsJson(resultNode) } + +func handleDrainNode(request *restful.Request, response *restful.Response) { + + nodeName := request.PathParameter("nodename") + + result, err := models.DrainNode(nodeName) + + if err != nil { + + response.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()}) + + } else { + + response.WriteAsJson(result) + + } + +} diff --git a/pkg/models/nodes.go b/pkg/models/nodes.go index 7773eaad5..a24f7dd2f 100644 --- a/pkg/models/nodes.go +++ b/pkg/models/nodes.go @@ -23,10 +23,14 @@ import ( "strings" "github.com/golang/glog" - v1 "k8s.io/api/core/v1" + v1beta2 "k8s.io/api/apps/v1beta2" + "k8s.io/api/core/v1" + policy "k8s.io/api/policy/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "kubesphere.io/kubesphere/pkg/client" + kubeclient "kubesphere.io/kubesphere/pkg/client" + "kubesphere.io/kubesphere/pkg/constants" ksutil "kubesphere.io/kubesphere/pkg/util" ) @@ -213,3 +217,72 @@ func getNodeFileSystemStatus(node *v1.Node) (string, string, string) { } return "", "", "" } + +func DrainNode(nodename string) (msg constants.MessageResponse, err error) { + + k8sclient := kubeclient.NewK8sClient() + var options metav1.ListOptions + pods := make([]v1.Pod, 0) + options.FieldSelector = "spec.nodeName=" + nodename + podList, err := k8sclient.CoreV1().Pods("").List(options) + if err != nil { + + glog.Fatal(err) + return msg, err + + } + options.FieldSelector = "" + daemonsetList, err := k8sclient.AppsV1beta2().DaemonSets("").List(options) + + if err != nil { + + glog.Fatal(err) + return msg, err + + } + if len(podList.Items) > 0 { + + for _, pod := range podList.Items { + + if !containDaemonset(pod, *daemonsetList) { + + pods = append(pods, pod) + } + } + } + //create eviction + var eviction policy.Eviction + eviction.Kind = "Eviction" + eviction.APIVersion = "policy/v1beta1" + if len(pods) > 0 { + + for _, pod := range pods { + + eviction.Namespace = pod.Namespace + eviction.Name = pod.Name + err := k8sclient.CoreV1().Pods(pod.Namespace).Evict(&eviction) + if err != nil { + return msg, err + } + } + + } + msg.Message = fmt.Sprintf("success") + return msg, nil + +} + +func containDaemonset(pod v1.Pod, daemonsetList v1beta2.DaemonSetList) bool { + + flag := false + for _, daemonset := range daemonsetList.Items { + + if strings.Contains(pod.Name, daemonset.Name) { + + flag = true + } + + } + return flag + +}