diff --git a/app/horus/core/horuser/action.go b/app/horus/core/horuser/action.go deleted file mode 100644 index 53a7ba89..00000000 --- a/app/horus/core/horuser/action.go +++ /dev/null @@ -1,166 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one or more -// contributor license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright ownership. -// The ASF licenses this file to You under the Apache License, Version 2.0 -// (the "License"); you may not use this file except in compliance with -// the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package horuser - -import ( - "fmt" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/klog/v2" -) - -func (h *Horuser) Cordon(nodeName, clusterName, moduleName string) (err error) { - kubeClient := h.kubeClientMap[clusterName] - if kubeClient == nil { - klog.Errorf("node Cordon kubeClient by clusterName empty.") - klog.Infof("nodeName:%v,clusterName:%v", nodeName, clusterName) - return err - } - - ctxFirst, cancelFirst := h.GetK8sContext() - defer cancelFirst() - node, err := kubeClient.CoreV1().Nodes().Get(ctxFirst, nodeName, v1.GetOptions{}) - if err != nil { - klog.Errorf("node Cordon get err nodeName:%v clusterName:%v", nodeName, clusterName) - return err - } - annotations := node.Annotations - if annotations == nil { - annotations = map[string]string{} - } - annotations["dubbo.apache.org/disable-by"] = "horus" - - node.Spec.Unschedulable = true - if node.Spec.Unschedulable { - klog.Infof("Node %v is already cordoned.", nodeName) - return nil - } - ctxSecond, cancelSecond := h.GetK8sContext() - defer cancelSecond() - node, err = kubeClient.CoreV1().Nodes().Update(ctxSecond, node, v1.UpdateOptions{}) - if err != nil { - klog.Errorf("node Cordon update err nodeName:%v clusterName:%v", nodeName, clusterName) - } else { - klog.Infof("node Cordon success nodeName:%v clusterName:%v", nodeName, clusterName) - } - return err -} - -func (h *Horuser) UnCordon(nodeName, clusterName string) (err error) { - kubeClient := h.kubeClientMap[clusterName] - if kubeClient == nil { - klog.Errorf("node UnCordon kubeClient by clusterName empty.") - klog.Infof("nodeName:%v,clusterName:%v", nodeName, clusterName) - return err - } - - ctxFirst, cancelFirst := h.GetK8sContext() - defer cancelFirst() - node, err := kubeClient.CoreV1().Nodes().Get(ctxFirst, nodeName, v1.GetOptions{}) - if err != nil { - klog.Errorf("node UnCordon get err nodeName:%v clusterName:%v", nodeName, clusterName) - return err - } - - node.Spec.Unschedulable = false - if !node.Spec.Unschedulable { - klog.Infof("Node %v is already uncordoned.", nodeName) - return nil - } - - ctxSecond, cancelSecond := h.GetK8sContext() - defer cancelSecond() - node, err = kubeClient.CoreV1().Nodes().Update(ctxSecond, node, v1.UpdateOptions{}) - if err != nil { - klog.Errorf("node UnCordon update err nodeName:%v clusterName:%v", nodeName, clusterName) - return err - } - klog.Infof("node UnCordon success nodeName:%v clusterName:%v", nodeName, clusterName) - return nil -} - -func (h *Horuser) Drain(nodeName, clusterName string) (err error) { - kubeClient := h.kubeClientMap[clusterName] - if kubeClient == nil { - klog.Errorf("node Drain kubeClient by clusterName empty.") - klog.Infof("nodeName:%v,clusterName:%v", nodeName, clusterName) - return err - } - - ctxFirst, cancelFirst := h.GetK8sContext() - defer cancelFirst() - listOpts := v1.ListOptions{FieldSelector: fmt.Sprintf("nodeName=%s", nodeName)} - var podNamespace string - pod, err := kubeClient.CoreV1().Pods(podNamespace).List(ctxFirst, listOpts) - if err != nil { - klog.Errorf("node Drain err:%v nodeName:%v clusterName:%v", err, nodeName, clusterName) - return err - } - if len(pod.Items) == 0 { - klog.Errorf("Cannot find pod on node.") - klog.Infof("nodeName:%v,clusterName:%v", nodeName, clusterName) - } - count := len(pod.Items) - for items, pods := range pod.Items { - ds := false - for _, owner := range pods.OwnerReferences { - if owner.Kind == "DaemonSet" { - ds = true - break - } - } - klog.Errorf("node Drain evict pod result items:%d count:%v nodeName:%v clusterName:%v podName:%v podNamespace:%v", items+1, count, nodeName, clusterName, pods.Name, pods.Namespace) - if ds { - continue - } - err := h.Evict(pods.Name, pods.Namespace, clusterName) - if err != nil { - klog.Errorf("node Drain evict pod err:%v items:%d count:%v nodeName:%v clusterName:%v podName:%v podNamespace:%v", err, items+1, count, nodeName, clusterName, pods.Name, pods.Namespace) - return err - } - } - return nil -} - -func (h *Horuser) Evict(podName, podNamespace, clusterName string) (err error) { - kubeClient := h.kubeClientMap[clusterName] - if kubeClient == nil { - klog.Errorf("pod Evict kubeClient by clusterName empty.") - klog.Infof("podName:%v podNamespace:%v clusterName:%v", podName, podNamespace, clusterName) - return err - } - - ctxFirst, cancelFirst := h.GetK8sContext() - defer cancelFirst() - _, err = kubeClient.CoreV1().Pods(podNamespace).Get(ctxFirst, podName, v1.GetOptions{}) - if err != nil { - klog.Errorf("pod Evict get err clusterName:%v podName:%v podNamespace:%v", clusterName, podName, podNamespace) - return err - } - ctxSecond, cancelSecond := h.GetK8sContext() - defer cancelSecond() - var gracePeriodSeconds int64 = -1 - propagationPolicy := v1.DeletePropagationBackground - err = kubeClient.CoreV1().Pods(podNamespace).Delete(ctxSecond, podName, v1.DeleteOptions{ - GracePeriodSeconds: &gracePeriodSeconds, - PropagationPolicy: &propagationPolicy, - }) - if err != nil { - klog.Errorf("pod Evict delete err clusterName:%v podName:%v podNamespace:%v", clusterName, podName, podNamespace) - return err - } - klog.Infof("pod Evict delete success clusterName:%v podName:%v podNamespace:%v", clusterName, podName, podNamespace) - return nil -} diff --git a/app/horus/core/horuser/node_cordon.go b/app/horus/core/horuser/node_cordon.go new file mode 100644 index 00000000..1f398c91 --- /dev/null +++ b/app/horus/core/horuser/node_cordon.go @@ -0,0 +1,58 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package horuser + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/klog/v2" +) + +func (h *Horuser) Cordon(nodeName, clusterName, moduleName string) (err error) { + kubeClient := h.kubeClientMap[clusterName] + if kubeClient == nil { + klog.Errorf("node Cordon kubeClient by clusterName empty.") + klog.Infof("nodeName:%v,clusterName:%v", nodeName, clusterName) + return err + } + + ctxFirst, cancelFirst := h.GetK8sContext() + defer cancelFirst() + node, err := kubeClient.CoreV1().Nodes().Get(ctxFirst, nodeName, v1.GetOptions{}) + if err != nil { + klog.Errorf("node Cordon get err nodeName:%v clusterName:%v", nodeName, clusterName) + return err + } + annotations := node.Annotations + if annotations == nil { + annotations = map[string]string{} + } + annotations["dubbo.apache.org/disable-by"] = "horus" + + node.Spec.Unschedulable = true + if node.Spec.Unschedulable { + klog.Infof("Node %v is already cordoned.", nodeName) + return nil + } + ctxSecond, cancelSecond := h.GetK8sContext() + defer cancelSecond() + node, err = kubeClient.CoreV1().Nodes().Update(ctxSecond, node, v1.UpdateOptions{}) + if err != nil { + klog.Errorf("node Cordon update err nodeName:%v clusterName:%v", nodeName, clusterName) + } else { + klog.Infof("node Cordon success nodeName:%v clusterName:%v", nodeName, clusterName) + } + return err +} diff --git a/app/horus/core/horuser/downtime.go b/app/horus/core/horuser/node_downtime.go similarity index 100% rename from app/horus/core/horuser/downtime.go rename to app/horus/core/horuser/node_downtime.go diff --git a/app/horus/core/horuser/node_drain.go b/app/horus/core/horuser/node_drain.go new file mode 100644 index 00000000..f7fe8726 --- /dev/null +++ b/app/horus/core/horuser/node_drain.go @@ -0,0 +1,65 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package horuser + +import ( + "fmt" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/klog/v2" +) + +func (h *Horuser) Drain(nodeName, clusterName string) (err error) { + kubeClient := h.kubeClientMap[clusterName] + if kubeClient == nil { + klog.Errorf("node Drain kubeClient by clusterName empty.") + klog.Infof("nodeName:%v,clusterName:%v", nodeName, clusterName) + return err + } + + ctxFirst, cancelFirst := h.GetK8sContext() + defer cancelFirst() + listOpts := v1.ListOptions{FieldSelector: fmt.Sprintf("nodeName=%s", nodeName)} + var podNamespace string + pod, err := kubeClient.CoreV1().Pods(podNamespace).List(ctxFirst, listOpts) + if err != nil { + klog.Errorf("node Drain err:%v nodeName:%v clusterName:%v", err, nodeName, clusterName) + return err + } + if len(pod.Items) == 0 { + klog.Errorf("Cannot find pod on node.") + klog.Infof("nodeName:%v,clusterName:%v", nodeName, clusterName) + } + count := len(pod.Items) + for items, pods := range pod.Items { + ds := false + for _, owner := range pods.OwnerReferences { + if owner.Kind == "DaemonSet" { + ds = true + break + } + } + klog.Errorf("node Drain evict pod result items:%d count:%v nodeName:%v clusterName:%v podName:%v podNamespace:%v", items+1, count, nodeName, clusterName, pods.Name, pods.Namespace) + if ds { + continue + } + err := h.Evict(pods.Name, pods.Namespace, clusterName) + if err != nil { + klog.Errorf("node Drain evict pod err:%v items:%d count:%v nodeName:%v clusterName:%v podName:%v podNamespace:%v", err, items+1, count, nodeName, clusterName, pods.Name, pods.Namespace) + return err + } + } + return nil +} diff --git a/app/horus/core/horuser/modular.go b/app/horus/core/horuser/node_modular.go similarity index 100% rename from app/horus/core/horuser/modular.go rename to app/horus/core/horuser/node_modular.go diff --git a/app/horus/core/horuser/recovery.go b/app/horus/core/horuser/node_recovery.go similarity index 100% rename from app/horus/core/horuser/recovery.go rename to app/horus/core/horuser/node_recovery.go diff --git a/app/horus/core/horuser/restart.go b/app/horus/core/horuser/node_restart.go similarity index 100% rename from app/horus/core/horuser/restart.go rename to app/horus/core/horuser/node_restart.go diff --git a/app/horus/core/horuser/node_uncordon.go b/app/horus/core/horuser/node_uncordon.go new file mode 100644 index 00000000..257eef6f --- /dev/null +++ b/app/horus/core/horuser/node_uncordon.go @@ -0,0 +1,54 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package horuser + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/klog/v2" +) + +func (h *Horuser) UnCordon(nodeName, clusterName string) (err error) { + kubeClient := h.kubeClientMap[clusterName] + if kubeClient == nil { + klog.Errorf("node UnCordon kubeClient by clusterName empty.") + klog.Infof("nodeName:%v,clusterName:%v", nodeName, clusterName) + return err + } + + ctxFirst, cancelFirst := h.GetK8sContext() + defer cancelFirst() + node, err := kubeClient.CoreV1().Nodes().Get(ctxFirst, nodeName, v1.GetOptions{}) + if err != nil { + klog.Errorf("node UnCordon get err nodeName:%v clusterName:%v", nodeName, clusterName) + return err + } + + node.Spec.Unschedulable = false + if !node.Spec.Unschedulable { + klog.Infof("Node %v is already uncordoned.", nodeName) + return nil + } + + ctxSecond, cancelSecond := h.GetK8sContext() + defer cancelSecond() + node, err = kubeClient.CoreV1().Nodes().Update(ctxSecond, node, v1.UpdateOptions{}) + if err != nil { + klog.Errorf("node UnCordon update err nodeName:%v clusterName:%v", nodeName, clusterName) + return err + } + klog.Infof("node UnCordon success nodeName:%v clusterName:%v", nodeName, clusterName) + return nil +} diff --git a/app/horus/core/horuser/pod_evict.go b/app/horus/core/horuser/pod_evict.go new file mode 100644 index 00000000..8c0abb23 --- /dev/null +++ b/app/horus/core/horuser/pod_evict.go @@ -0,0 +1,52 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package horuser + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/klog/v2" +) + +func (h *Horuser) Evict(podName, podNamespace, clusterName string) (err error) { + kubeClient := h.kubeClientMap[clusterName] + if kubeClient == nil { + klog.Errorf("pod Evict kubeClient by clusterName empty.") + klog.Infof("podName:%v podNamespace:%v clusterName:%v", podName, podNamespace, clusterName) + return err + } + + ctxFirst, cancelFirst := h.GetK8sContext() + defer cancelFirst() + _, err = kubeClient.CoreV1().Pods(podNamespace).Get(ctxFirst, podName, v1.GetOptions{}) + if err != nil { + klog.Errorf("pod Evict get err clusterName:%v podName:%v podNamespace:%v", clusterName, podName, podNamespace) + return err + } + ctxSecond, cancelSecond := h.GetK8sContext() + defer cancelSecond() + var gracePeriodSeconds int64 = -1 + propagationPolicy := v1.DeletePropagationBackground + err = kubeClient.CoreV1().Pods(podNamespace).Delete(ctxSecond, podName, v1.DeleteOptions{ + GracePeriodSeconds: &gracePeriodSeconds, + PropagationPolicy: &propagationPolicy, + }) + if err != nil { + klog.Errorf("pod Evict delete err clusterName:%v podName:%v podNamespace:%v", clusterName, podName, podNamespace) + return err + } + klog.Infof("pod Evict delete success clusterName:%v podName:%v podNamespace:%v", clusterName, podName, podNamespace) + return nil +} diff --git a/app/horus/core/horuser/pod_remove.go b/app/horus/core/horuser/pod_remove.go new file mode 100644 index 00000000..9d2ea881 --- /dev/null +++ b/app/horus/core/horuser/pod_remove.go @@ -0,0 +1,48 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package horuser + +import ( + "encoding/json" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/klog/v2" +) + +type SampleValue struct { + Operation string `json:"operation"` + Path string `json:"path"` +} + +func (h *Horuser) Finalizer(clusterName, podName, podNamespace string) error { + kubeClient := h.kubeClientMap[clusterName] + if kubeClient == nil { + klog.Errorf("Finalizer kubeClient by clusterName empty.") + klog.Infof("clusterName:%v podName:%v", clusterName, podName) + return nil + } + finalizer := SampleValue{ + Operation: "remove", + Path: "/metadata/finalizers", + } + var payload []interface{} + payload = append(payload, finalizer) + data, _ := json.Marshal(payload) + ctx, cancel := h.GetK8sContext() + defer cancel() + _, err := kubeClient.CoreV1().Pods(podNamespace).Patch(ctx, podName, types.JSONPatchType, data, v1.PatchOptions{}) + return err +} diff --git a/app/horus/core/horuser/prome.go b/app/horus/core/horuser/query.go similarity index 100% rename from app/horus/core/horuser/prome.go rename to app/horus/core/horuser/query.go