github.com/alibaba/sealer@v0.8.6-0.20220430115802-37a2bdaa8173/pkg/checker/node_checker.go (about) 1 // Copyright © 2021 Alibaba Group Holding Ltd. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package checker 16 17 import ( 18 "fmt" 19 "text/template" 20 21 corev1 "k8s.io/api/core/v1" 22 23 "github.com/alibaba/sealer/common" 24 "github.com/alibaba/sealer/logger" 25 "github.com/alibaba/sealer/pkg/client/k8s" 26 v2 "github.com/alibaba/sealer/types/api/v2" 27 ) 28 29 const ( 30 ReadyNodeStatus = "Ready" 31 NotReadyNodeStatus = "NotReady" 32 ) 33 34 type NodeChecker struct { 35 client *k8s.Client 36 } 37 38 type NodeClusterStatus struct { 39 ReadyCount uint32 40 NotReadyCount uint32 41 NodeCount uint32 42 NotReadyNodeList []string 43 } 44 45 func (n *NodeChecker) Check(cluster *v2.Cluster, phase string) error { 46 if phase != PhasePost { 47 return nil 48 } 49 // checker if all the node is ready 50 c, err := k8s.Newk8sClient() 51 if err != nil { 52 return err 53 } 54 n.client = c 55 nodes, err := n.client.ListNodes() 56 if err != nil { 57 return err 58 } 59 var notReadyNodeList []string 60 var readyCount uint32 = 0 61 var nodeCount uint32 62 var notReadyCount uint32 = 0 63 for _, node := range nodes.Items { 64 nodeIP, nodePhase := getNodeStatus(node) 65 if nodePhase != ReadyNodeStatus { 66 notReadyCount++ 67 notReadyNodeList = append(notReadyNodeList, nodeIP) 68 } else { 69 readyCount++ 70 } 71 } 72 nodeCount = notReadyCount + readyCount 73 nodeClusterStatus := NodeClusterStatus{ 74 ReadyCount: readyCount, 75 NotReadyCount: notReadyCount, 76 NodeCount: nodeCount, 77 NotReadyNodeList: notReadyNodeList, 78 } 79 err = n.Output(nodeClusterStatus) 80 if err != nil { 81 return err 82 } 83 if notReadyCount != 0 { 84 return fmt.Errorf("check node %v not ready", notReadyNodeList) 85 } 86 return nil 87 } 88 89 func (n *NodeChecker) Output(nodeCLusterStatus NodeClusterStatus) error { 90 //t1, err := template.ParseFiles("templates/node_checker.tpl") 91 t := template.New("node_checker") 92 t, err := t.Parse( 93 `Cluster Node Status 94 ReadyNode: {{ .ReadyCount }}/{{ .NodeCount }} 95 {{ if (gt .NotReadyCount 0 ) -}} 96 Not Ready Node List: 97 {{- range .NotReadyNodeList }} 98 NodeIP: {{ . }} 99 {{- end }} 100 {{ end }} 101 `) 102 if err != nil { 103 panic(err) 104 } 105 t = template.Must(t, err) 106 err = t.Execute(common.StdOut, nodeCLusterStatus) 107 if err != nil { 108 logger.Error("node checkers template can not excute %s", err) 109 return err 110 } 111 return nil 112 } 113 114 func getNodeStatus(node corev1.Node) (IP string, Phase string) { 115 if len(node.Status.Addresses) < 1 { 116 return "", "" 117 } 118 for _, address := range node.Status.Addresses { 119 if address.Type == "InternalIP" { 120 IP = address.Address 121 } 122 } 123 if IP == "" { 124 IP = node.Status.Addresses[0].Address 125 } 126 Phase = NotReadyNodeStatus 127 for _, condition := range node.Status.Conditions { 128 if condition.Type == ReadyNodeStatus { 129 if condition.Status == "True" { 130 Phase = ReadyNodeStatus 131 } else { 132 Phase = NotReadyNodeStatus 133 } 134 } 135 } 136 return IP, Phase 137 } 138 139 func NewNodeChecker() Interface { 140 return &NodeChecker{} 141 }