// RAINBOND, Application Management Platform // Copyright (C) 2014-2017 Goodrain Co., Ltd. // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. For any non-GPL usage of Rainbond, // one or multiple Commercial Licenses authorized by Goodrain Co., Ltd. // must be obtained first. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . package cmd import ( "github.com/urfave/cli" "github.com/Sirupsen/logrus" "github.com/goodrain/rainbond/pkg/grctl/clients" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" "github.com/apcera/termtables" "fmt" "github.com/goodrain/rainbond/pkg/node/api/model" "strings" "strconv" "encoding/json" ) func NewCmdNode() cli.Command { c:=cli.Command{ Name: "node", Usage: "获取节点信息。grctl node", Action: func(c *cli.Context) error { Common(c) return getNode(c) }, } return c } func NewCmdAddNode() cli.Command { c:=cli.Command{ Name: "add_node", Usage: "添加节点。grctl add_node '{}'(jsoned host node)", Action: func(c *cli.Context) error { return addNode(c) }, } return c } func addNode(c *cli.Context) error{ jsoned:=c.Args().First() var node model.APIHostNode err:=json.Unmarshal([]byte(jsoned),&node) if err != nil { logrus.Errorf("error unmarshal input json host node") return err } clients.NodeClient.Nodes().Add(&node) return nil } func NewCmdRegionNode() cli.Command { c:=cli.Command{ Name: "region_node", Usage: "节点管理。grctl region_node", Subcommands:[]cli.Command{ { Name: "up", Usage: "up hostID", Action: func(c *cli.Context) error { id:=c.Args().First() clients.NodeClient.Nodes().Get(id).Up() return nil }, }, { Name: "down", Usage: "down hostID", Action: func(c *cli.Context) error { id:=c.Args().First() clients.NodeClient.Nodes().Get(id).Down() return nil }, }, { Name: "get", Usage: "get hostID", Action: func(c *cli.Context) error { id:=c.Args().First() n:=clients.NodeClient.Nodes().Get(id) b,_:=json.Marshal(n) fmt.Println(string(b)) return nil }, }, { Name: "list", Usage: "list", Action: func(c *cli.Context) error { list:=clients.NodeClient.Nodes().List() b,_:=json.Marshal(list) fmt.Println(string(b)) return nil }, }, { Name: "unscheduable", Usage: "unscheduable hostID", Action: func(c *cli.Context) error { id:=c.Args().First() clients.NodeClient.Nodes().Get(id).UnSchedulable() return nil }, }, { Name: "rescheduable", Usage: "rescheduable hostID", Action: func(c *cli.Context) error { id:=c.Args().First() clients.NodeClient.Nodes().Get(id).ReSchedulable() return nil }, }, }, } return c } func NewCmdNodeRes() cli.Command { c:=cli.Command{ Name: "noderes", Usage: "获取计算节点资源信息 grctl noderes", Action: func(c *cli.Context) error { Common(c) return getNodeWithResource(c) }, } return c } func getNodeWithResource(c *cli.Context) error { ns, err :=clients.K8SClient.Core().Nodes().List(metav1.ListOptions{}) if err != nil { logrus.Errorf("获取节点列表失败,details: %s",err.Error()) return err } table := termtables.CreateTable() table.AddHeaders("NodeName", "Version", "CapCPU(核)", "AllocatableCPU(核)","UsedCPU(核)", "CapMemory(M)","AllocatableMemory(M)","UsedMemory(M)") for _,v:=range ns.Items { podList, err := clients.K8SClient.Core().Pods(metav1.NamespaceAll).List(metav1.ListOptions{FieldSelector: fields.SelectorFromSet(fields.Set{"spec.nodeName": v.Name}).String()}) if err != nil { } var cpuPerNode=0 memPerNode:=0 for _,p:=range podList.Items{ status:=string(p.Status.Phase) if status!="Running" { continue } memPerPod:=0 memPerPod+=int(p.Spec.Containers[0].Resources.Requests.Memory().Value()) cpuOfPod:=p.Spec.Containers[0].Resources.Requests.Cpu().String() if strings.Contains(cpuOfPod,"m") { cpuOfPod=strings.Replace(cpuOfPod,"m","",-1) } cpuI,_:=strconv.Atoi(cpuOfPod) cpuPerNode+=cpuI memPerNode+=memPerPod } capCPU:=v.Status.Capacity.Cpu().Value() capMem:=v.Status.Capacity.Memory().Value() allocCPU:=v.Status.Allocatable.Cpu().Value() allocMem:=v.Status.Allocatable.Memory().Value() table.AddRow(v.Name,v.Status.NodeInfo.KubeletVersion,capCPU,allocCPU,float32(cpuPerNode)/1000,capMem/1024/1024,allocMem/1024/1024,memPerNode/1024/1024) } fmt.Println(table.Render()) return nil } func getNode(c *cli.Context) error { ns, err :=clients.K8SClient.Core().Nodes().List(metav1.ListOptions{}) if err != nil { logrus.Errorf("获取节点列表失败,details: %s",err.Error()) return err } table := termtables.CreateTable() table.AddHeaders("Name", "Status", "Namespace","Unschedulable", "KubeletVersion","Labels") for _,v:=range ns.Items{ cs:=v.Status.Conditions status:="unknown" for _,cv:=range cs{ status=string(cv.Status) if strings.Contains(status,"rue"){ status=string(cv.Type) break } } m:=v.Labels labels:="" for k:=range m { labels+=k labels+=" " } table.AddRow(v.Name, status,v.Namespace,v.Spec.Unschedulable, v.Status.NodeInfo.KubeletVersion,labels) } fmt.Println(table.Render()) return nil }