[REV] update grctl code,add show tenant resource command

This commit is contained in:
barnettZQG 2018-07-16 15:30:53 +08:00
parent 9a5bd730d8
commit f130f9c9c4
11 changed files with 175 additions and 63 deletions

View File

@ -727,6 +727,16 @@ func (s *ServiceAction) GetService(tenantID string) ([]*dbmodel.TenantServices,
logrus.Errorf("get service by id error, %v, %v", services, err)
return nil, err
}
var serviceIDs []string
for _, s := range services {
serviceIDs = append(serviceIDs, s.ServiceID)
}
status := s.statusCli.GetStatuss(strings.Join(serviceIDs, ","))
for _, s := range services {
if status, ok := status[s.ServiceID]; ok {
s.CurStatus = status
}
}
return services, nil
}
@ -787,6 +797,11 @@ func (s *ServiceAction) GetTenantRes(uuid string) (*api_model.TenantResource, er
UsedMEM += serMap[k].ContainerMemory
}
}
disks := s.statusCli.GetAppsDisk(serviceIDs)
var value float64
for _, v := range disks {
value += v
}
var res api_model.TenantResource
res.UUID = uuid
res.Name = ""
@ -795,6 +810,7 @@ func (s *ServiceAction) GetTenantRes(uuid string) (*api_model.TenantResource, er
res.AllocatedMEM = AllocatedMEM
res.UsedCPU = UsedCPU
res.UsedMEM = UsedMEM
res.UsedDisk = value
return &res, nil
}

View File

@ -30,14 +30,14 @@ type PagedTenantResList struct {
//TenantResource path参数
//swagger:parameters getVolumes getDepVolumes
type TenantResource struct {
AllocatedCPU int `json:"alloc_cpu"`
AllocatedMEM int `json:"alloc_memory"`
UsedCPU int `json:"used_cpu"`
UsedMEM int `json:"used_memory"`
Name string `json:"name"`
UUID string `json:"uuid"`
EID string `json:"eid"`
AllocatedCPU int `json:"alloc_cpu"`
AllocatedMEM int `json:"alloc_memory"`
UsedCPU int `json:"used_cpu"`
UsedMEM int `json:"used_memory"`
UsedDisk float64 `json:"used_disk"`
Name string `json:"name"`
UUID string `json:"uuid"`
EID string `json:"eid"`
}
func (list TenantResList) Len() int {
@ -58,4 +58,4 @@ func (list TenantResList) Swap(i, j int) {
temp := list[i]
list[i] = list[j]
list[j] = temp
}
}

View File

@ -28,6 +28,7 @@ import (
"github.com/Sirupsen/logrus"
"github.com/bitly/go-simplejson"
"github.com/goodrain/rainbond/node/api/model"
"github.com/goodrain/rainbond/node/nodem/client"
"github.com/pquerna/ffjson/ffjson"
//"github.com/goodrain/rainbond/grctl/cmd"
"errors"
@ -83,10 +84,10 @@ type TaskInterface interface {
Refresh() *util.APIHandleError
}
type NodeInterface interface {
Rule(rule string) ([]*model.HostNode, *util.APIHandleError)
Get(node string) (*model.HostNode, *util.APIHandleError)
List() ([]*model.HostNode, *util.APIHandleError)
Add(node *model.APIHostNode) *util.APIHandleError
Rule(rule string) ([]*client.HostNode, *util.APIHandleError)
Get(node string) (*client.HostNode, *util.APIHandleError)
List() ([]*client.HostNode, *util.APIHandleError)
Add(node *client.APIHostNode) *util.APIHandleError
Up(nid string) *util.APIHandleError
Down(nid string) *util.APIHandleError
UnSchedulable(nid string) *util.APIHandleError
@ -142,7 +143,7 @@ func (c *configs) Put(gc *model.GlobalConfig) *util.APIHandleError {
return nil
}
func (n *node) Get(node string) (*model.HostNode, *util.APIHandleError) {
func (n *node) Get(node string) (*client.HostNode, *util.APIHandleError) {
body, code, err := n.client.Request(n.prefix+"/"+node, "GET", nil)
if err != nil {
return nil, util.CreateAPIHandleError(code, err)
@ -151,17 +152,17 @@ func (n *node) Get(node string) (*model.HostNode, *util.APIHandleError) {
return nil, util.CreateAPIHandleError(code, fmt.Errorf("Get database center configs code %d", code))
}
var res utilhttp.ResponseBody
var gc model.HostNode
var gc client.HostNode
res.Bean = &gc
if err := ffjson.Unmarshal(body, &res); err != nil {
return nil, util.CreateAPIHandleError(code, err)
}
if gc, ok := res.Bean.(*model.HostNode); ok {
if gc, ok := res.Bean.(*client.HostNode); ok {
return gc, nil
}
return nil, nil
}
func (n *node) Rule(rule string) ([]*model.HostNode, *util.APIHandleError) {
func (n *node) Rule(rule string) ([]*client.HostNode, *util.APIHandleError) {
body, code, err := n.client.Request(n.prefix+"/rule/"+rule, "GET", nil)
if err != nil {
return nil, util.CreateAPIHandleError(code, err)
@ -170,17 +171,17 @@ func (n *node) Rule(rule string) ([]*model.HostNode, *util.APIHandleError) {
return nil, util.CreateAPIHandleError(code, fmt.Errorf("Get database center configs code %d", code))
}
var res utilhttp.ResponseBody
var gc []*model.HostNode
var gc []*client.HostNode
res.List = &gc
if err := ffjson.Unmarshal(body, &res); err != nil {
return nil, util.CreateAPIHandleError(code, err)
}
if gc, ok := res.List.(*[]*model.HostNode); ok {
if gc, ok := res.List.(*[]*client.HostNode); ok {
return *gc, nil
}
return nil, nil
}
func (n *node) List() ([]*model.HostNode, *util.APIHandleError) {
func (n *node) List() ([]*client.HostNode, *util.APIHandleError) {
body, code, err := n.client.Request(n.prefix, "GET", nil)
if err != nil {
return nil, util.CreateAPIHandleError(code, err)
@ -189,12 +190,12 @@ func (n *node) List() ([]*model.HostNode, *util.APIHandleError) {
return nil, util.CreateAPIHandleError(code, fmt.Errorf("Get database center configs code %d", code))
}
var res utilhttp.ResponseBody
var gc []*model.HostNode
var gc []*client.HostNode
res.List = &gc
if err := ffjson.Unmarshal(body, &res); err != nil {
return nil, util.CreateAPIHandleError(code, err)
}
if gc, ok := res.List.(*[]*model.HostNode); ok {
if gc, ok := res.List.(*[]*client.HostNode); ok {
return *gc, nil
}
return nil, nil
@ -202,7 +203,7 @@ func (n *node) List() ([]*model.HostNode, *util.APIHandleError) {
// put/post 类
func (n *node) Add(node *model.APIHostNode) *util.APIHandleError {
func (n *node) Add(node *client.APIHostNode) *util.APIHandleError {
body, err := json.Marshal(node)
if err != nil {
return util.CreateAPIHandleError(400, err)

View File

@ -25,8 +25,8 @@ import (
"fmt"
"io/ioutil"
"net/http"
"path"
"github.com/Sirupsen/logrus"
"github.com/bitly/go-simplejson"
"github.com/goodrain/rainbond/api/model"
api_model "github.com/goodrain/rainbond/api/model"
@ -188,7 +188,6 @@ func (s *services) Start(name, eventID string) *util.APIHandleError {
}
func request(url, method string, body []byte) ([]byte, int, error) {
logrus.Infof("req url is %s", region.regionAPI+url)
request, err := http.NewRequest(method, region.regionAPI+url, bytes.NewBuffer(body))
if err != nil {
return nil, 500, err
@ -274,3 +273,41 @@ func handleErrAndCode(err error, code int) *util.APIHandleError {
}
return nil
}
//Resources about resources
func (r *Region) Resources() ResourcesInterface {
return &resources{prefix: "/resources"}
}
//ResourcesInterface ResourcesInterface
type ResourcesInterface interface {
Tenants(tenantName string) ResourcesTenantInterface
}
type resources struct {
prefix string
}
func (r *resources) Tenants(tenantName string) ResourcesTenantInterface {
return &resourcesTenant{prefix: path.Join(r.prefix, "tenants", tenantName)}
}
//ResourcesTenantInterface ResourcesTenantInterface
type ResourcesTenantInterface interface {
Get() (*model.TenantResource, *util.APIHandleError)
}
type resourcesTenant struct {
prefix string
}
func (r *resourcesTenant) Get() (*model.TenantResource, *util.APIHandleError) {
res, code, err := request(r.prefix+"/res", "GET", nil)
if err != nil {
return nil, handleErrAndCode(err, code)
}
var rt model.TenantResource
if err := json.Unmarshal(res, &rt); err != nil {
return nil, util.CreateAPIHandleError(code, err)
}
return &rt, nil
}

View File

@ -21,6 +21,7 @@ package cache
import (
"fmt"
"os"
"strings"
"sync"
"time"
@ -28,8 +29,8 @@ import (
"github.com/goodrain/rainbond/db"
"github.com/goodrain/rainbond/db/model"
"golang.org/x/net/context"
"github.com/goodrain/rainbond/util"
"golang.org/x/net/context"
)
//DiskCache 磁盘异步统计
@ -38,16 +39,16 @@ type DiskCache struct {
Key string
Value float64
}
dbmanager db.Manager
ctx context.Context
lock sync.Mutex
dbmanager db.Manager
ctx context.Context
lock sync.Mutex
}
//CreatDiskCache 创建
func CreatDiskCache(ctx context.Context) *DiskCache {
return &DiskCache{
dbmanager: db.GetManager(),
ctx: ctx,
dbmanager: db.GetManager(),
ctx: ctx,
}
}
@ -140,3 +141,25 @@ func (d *DiskCache) Get() map[string]float64 {
}
return newcache
}
//GetTenantDisk GetTenantDisk
func (d *DiskCache) GetTenantDisk(tenantID string) float64 {
var value float64
for _, v := range d.cache {
if strings.HasSuffix(v.Key, "_"+tenantID) {
value += v.Value
}
}
return value
}
//GetServiceDisk GetServiceDisk
func (d *DiskCache) GetServiceDisk(serviceID string) float64 {
var value float64
for _, v := range d.cache {
if strings.HasPrefix(v.Key, serviceID+"_") {
value += v.Value
}
}
return value
}

View File

@ -161,8 +161,8 @@ func (a *AppRuntimeSyncClient) GetStatus(serviceID string) string {
return status.Status[serviceID]
}
//GetAllStatus get all status
func (a *AppRuntimeSyncClient) GetAppDisk() map[string]float64 {
//GetAllAppDisk get all service disk
func (a *AppRuntimeSyncClient) GetAllAppDisk() map[string]float64 {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
status, err := a.AppRuntimeSyncClient.GetAppDisk(ctx, &pb.StatusRequest{
@ -174,6 +174,19 @@ func (a *AppRuntimeSyncClient) GetAppDisk() map[string]float64 {
return status.Disks
}
//GetAppsDisk get define service disk
func (a *AppRuntimeSyncClient) GetAppsDisk(serviceIDs string) map[string]float64 {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
status, err := a.AppRuntimeSyncClient.GetAppDisk(ctx, &pb.StatusRequest{
ServiceIds: serviceIDs,
})
if err != nil {
return nil
}
return status.Disks
}
//GetStatuss get multiple app status
func (a *AppRuntimeSyncClient) GetStatuss(serviceIDs string) map[string]string {
ctx, cancel := context.WithCancel(context.Background())

View File

@ -23,6 +23,7 @@ import (
"time"
"github.com/Sirupsen/logrus"
"github.com/goodrain/rainbond/appruntimesync/cache"
"github.com/goodrain/rainbond/appruntimesync/clean"
"github.com/goodrain/rainbond/appruntimesync/pb"
"github.com/goodrain/rainbond/appruntimesync/pod"
@ -32,7 +33,6 @@ import (
"golang.org/x/net/context"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"github.com/goodrain/rainbond/appruntimesync/cache"
)
//AppRuntimeSyncServer AppRuntimeSyncServer
@ -107,10 +107,20 @@ func (a *AppRuntimeSyncServer) GetAppStatus(ctx context.Context, sr *pb.StatusRe
return &re, nil
}
//GetDiskStatus get app disk information
//GetAppDisk get app disk information
func (a *AppRuntimeSyncServer) GetAppDisk(ctx context.Context, sr *pb.StatusRequest) (*pb.DiskMessage, error) {
var re pb.DiskMessage
re.Disks = a.cache.Get()
if sr.ServiceIds == "" {
re.Disks = a.cache.Get()
return &re, nil
}
services := strings.Split(sr.ServiceIds, ",")
var rev = make(map[string]float64)
for _, s := range services {
value := a.cache.GetServiceDisk(s)
rev[s] = value
}
re.Disks = rev
return &re, nil
}

View File

@ -33,7 +33,7 @@ import (
"github.com/apcera/termtables"
"github.com/goodrain/rainbond/api/util"
"github.com/goodrain/rainbond/grctl/clients"
"github.com/goodrain/rainbond/node/api/model"
"github.com/goodrain/rainbond/node/nodem/client"
"github.com/urfave/cli"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
@ -77,7 +77,7 @@ func NewCmdShow() cli.Command {
return c
}
func getExternalIP(path string, node []*model.HostNode) []string {
func getExternalIP(path string, node []*client.HostNode) []string {
var result []string
if fileExist(path) {
externalIP, err := ioutil.ReadFile(path)
@ -103,7 +103,7 @@ func fileExist(path string) bool {
}
return false
}
func handleStatus(serviceTable *termtables.Table, ready bool, v *model.HostNode) {
func handleStatus(serviceTable *termtables.Table, ready bool, v *client.HostNode) {
if v.Role.HasRule("compute") && !v.Role.HasRule("manage") {
serviceTable.AddRow(v.ID, v.InternalIP, v.HostName, v.Role.String(), v.Mode, v.Status, v.Alived, !v.Unschedulable, ready)
} else if v.Role.HasRule("manage") && !v.Role.HasRule("compute") {
@ -159,7 +159,7 @@ func NewCmdNode() cli.Command {
handleErr(err)
serviceTable := termtables.CreateTable()
serviceTable.AddHeaders("Uid", "IP", "HostName", "NodeRole", "NodeMode", "Status", "Alived", "Schedulable", "Ready")
var rest []*model.HostNode
var rest []*client.HostNode
for _, v := range list {
if v.Role.HasRule("manage") {
handleStatus(serviceTable, isNodeReady(v), v)
@ -344,7 +344,7 @@ func NewCmdNode() cli.Command {
},
},
Action: func(c *cli.Context) error {
var node model.APIHostNode
var node client.APIHostNode
if c.IsSet("Role") {
node.Role = append(node.Role, c.String("Role"))
node.InternalIP = c.String("InternalIP")
@ -356,7 +356,7 @@ func NewCmdNode() cli.Command {
handleErr(err)
fmt.Println("开始初始化节点")
var hostNode *model.HostNode
var hostNode *client.HostNode
timer := time.NewTimer(15 * time.Second)
gotNode := false
for !gotNode {
@ -391,9 +391,9 @@ func NewCmdNode() cli.Command {
break
}
}
for _, val := range hostNode.Conditions {
for _, val := range hostNode.NodeStatus.Conditions {
fmt.Println("正在判断节点状态,请稍等")
if hostNode.Alived || (val.Type == model.NodeInit && val.Status == model.ConditionTrue) {
if hostNode.Alived || (val.Type == client.NodeInit && val.Status == client.ConditionTrue) {
fmt.Printf("节点 %s 初始化成功", hostNode.ID)
fmt.Println()
header = append(header, string(val.Type))
@ -402,7 +402,7 @@ func NewCmdNode() cli.Command {
tableC.AddRow(content)
fmt.Println(tableC.Render())
return nil
} else if val.Type == model.NodeInit && val.Status == model.ConditionFalse {
} else if val.Type == client.NodeInit && val.Status == client.ConditionFalse {
fmt.Printf("节点 %s 初始化失败:%s", hostNode.ID, val.Reason)
return nil
} else {
@ -479,7 +479,7 @@ func getNodeWithResource(c *cli.Context) error {
fmt.Println(table.Render())
return nil
}
func isNodeReady(node *model.HostNode) bool {
func isNodeReady(node *client.HostNode) bool {
if node.NodeStatus == nil {
return false
}

View File

@ -33,8 +33,8 @@ import (
"github.com/Sirupsen/logrus"
"github.com/apcera/termtables"
"github.com/goodrain/rainbond/cmd/grctl/option"
"github.com/goodrain/rainbond/api/util"
"github.com/goodrain/rainbond/cmd/grctl/option"
"github.com/goodrain/rainbond/grctl/clients"
"github.com/gorilla/websocket"
"github.com/gosuri/uitable"
@ -216,7 +216,11 @@ func stopTenantService(c *cli.Context) error {
//POST /v2/tenants/{tenant_name}/services/{service_alias}/stop
tenantID := c.Args().First()
eventID := c.Args().Get(1)
if tenantID == "" {
fmt.Println("Please provide tenant name")
os.Exit(1)
}
eventID := "system"
services, err := clients.RegionClient.Tenants().Get(tenantID).Services().List()
handleErr(err)
for _, service := range services {
@ -228,7 +232,6 @@ func stopTenantService(c *cli.Context) error {
}
GetEventLogf(eventID, server)
}
//err = region.StopService(service["service_id"].(string), service["deploy_version"].(string))
if err != nil {
logrus.Error("停止应用失败:" + err.Error())
return err

View File

@ -20,10 +20,11 @@ package cmd
import (
"fmt"
"os"
"github.com/Sirupsen/logrus"
"github.com/apcera/termtables"
"github.com/goodrain/rainbond/grctl/clients"
"github.com/gosuri/uitable"
"github.com/urfave/cli"
)
@ -75,7 +76,10 @@ func NewCmdTenant() cli.Command {
// grctrl tenant TENANT_NAME
func getTenantInfo(c *cli.Context) error {
tenantID := c.Args().First()
if tenantID == "" {
fmt.Println("Please provide tenant name")
os.Exit(1)
}
services, err := clients.RegionClient.Tenants().Get(tenantID).Services().List()
handleErr(err)
if services != nil {
@ -87,21 +91,25 @@ func getTenantInfo(c *cli.Context) error {
fmt.Println(table.Render())
return nil
}
logrus.Error("get nothing")
return nil
}
func findTenantResourceUsage(c *cli.Context) error {
tenantID := c.Args().First()
services, err := clients.RegionClient.Tenants().Get(tenantID).Services().List()
handleErr(err)
var cpuUsage float32
var cpuUnit float32 = 1000
var memoryUsage int64
for _, service := range services {
cpuUsage += float32(service.ContainerCPU)
memoryUsage += int64(service.ContainerMemory)
tenantName := c.Args().First()
if tenantName == "" {
fmt.Println("Please provide tenant name")
os.Exit(1)
}
fmt.Printf("租户 %s 占用CPU : %v 核; 占用Memory : %d M", tenantID, cpuUsage/cpuUnit, memoryUsage)
fmt.Println()
resources, err := clients.RegionClient.Resources().Tenants(tenantName).Get()
handleErr(err)
table := uitable.New()
table.Wrap = true // wrap columns
table.AddRow("租户名:", resources.Name)
table.AddRow("企业ID", resources.EID)
table.AddRow("总分配CPU资源", float64(resources.AllocatedCPU)/1000, "Core")
table.AddRow("总分配内存资源:", resources.AllocatedMEM, "Mb")
table.AddRow("正使用CPU资源", float64(resources.UsedCPU)/1000, "Core")
table.AddRow("正使用内存资源:", resources.UsedMEM, "Mb")
table.AddRow("正使用磁盘资源:", resources.UsedDisk/1024/1024, "Mb")
fmt.Println(table)
return nil
}

View File

@ -195,6 +195,7 @@ func (n *Cluster) handleNodeStatus(v *client.HostNode) {
return
}
}
v.Status = "error"
} else {
v.Status = "down"
}