[REV] add cmd for cluster and change some api client

This commit is contained in:
barnettZQG 2018-07-17 16:18:19 +08:00
parent 3d45ea9cca
commit 881fb3ea7a
22 changed files with 556 additions and 757 deletions

View File

@ -138,6 +138,10 @@ func Proxy(next http.Handler) http.Handler {
handler.GetNodeProxy().Proxy(w, r)
return
}
if strings.HasPrefix(r.RequestURI, "/v2/cluster") {
handler.GetNodeProxy().Proxy(w, r)
return
}
if strings.HasPrefix(r.RequestURI, "/v2/builder") {
handler.GetBuilderProxy().Proxy(w, r)
return

View File

@ -19,27 +19,32 @@
package region
import (
"reflect"
dbmodel "github.com/goodrain/rainbond/db/model"
"github.com/goodrain/rainbond/api/util"
"github.com/goodrain/rainbond/node/api/model"
utilhttp "github.com/goodrain/rainbond/util/http"
)
var modelRegistry = make(map[string]reflect.Type)
func init() {
registerType("tenants", &[]*dbmodel.Tenants{})
registerType("tenant", &dbmodel.Tenants{})
//ClusterInterface cluster api
type ClusterInterface interface {
GetClusterInfo() (*model.ClusterResource, *util.APIHandleError)
}
func registerType(name string, elem interface{}) {
t := reflect.TypeOf(elem).Elem()
modelRegistry[name] = t
func (r *regionImpl) Cluster() ClusterInterface {
return &cluster{prefix: "/v2/cluster", regionImpl: *r}
}
func newStruct(name string) (interface{}, bool) {
elem, ok := modelRegistry[name]
if !ok {
return nil, false
type cluster struct {
regionImpl
prefix string
}
func (c *cluster) GetClusterInfo() (*model.ClusterResource, *util.APIHandleError) {
var cr model.ClusterResource
var decode utilhttp.ResponseBody
decode.Bean = &cr
code, err := c.DoRequest(c.prefix, "GET", nil, &decode)
if err != nil {
return nil, handleErrAndCode(err, code)
}
return reflect.New(elem).Elem().Interface(), true
return &cr, nil
}

View File

@ -22,69 +22,183 @@ import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"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"
"github.com/goodrain/rainbond/api/util"
utilhttp "github.com/goodrain/rainbond/util/http"
)
var nodeclient *RNodeClient
//NewNode new node client
func NewNode(nodeAPI string) {
if nodeclient == nil {
nodeclient = &RNodeClient{
NodeAPI: nodeAPI,
}
}
func (r *regionImpl) Tasks() TaskInterface {
return &task{regionImpl: *r, prefix: "/v2/tasks"}
}
func GetNode() *RNodeClient {
return nodeclient
func (r *regionImpl) Nodes() NodeInterface {
return &node{regionImpl: *r, prefix: "/v2/nodes"}
}
type RNodeClient struct {
NodeAPI string
}
func (r *RNodeClient) Tasks() TaskInterface {
return &task{client: r, prefix: "/tasks"}
}
func (r *RNodeClient) Nodes() NodeInterface {
return &node{client: r, prefix: "/nodes"}
}
func (r *RNodeClient) Configs() ConfigsInterface {
return &configs{client: r, prefix: "/configs"}
func (r *regionImpl) Configs() ConfigsInterface {
return &configs{regionImpl: *r, prefix: "/v2/configs"}
}
type task struct {
client *RNodeClient
regionImpl
prefix string
}
type node struct {
client *RNodeClient
regionImpl
prefix string
}
func (n *node) Get(node string) (*client.HostNode, *util.APIHandleError) {
var res utilhttp.ResponseBody
var gc client.HostNode
res.Bean = &gc
code, err := n.DoRequest(n.prefix+"/"+node, "GET", nil, &res)
if err != nil {
return nil, util.CreateAPIHandleError(code, err)
}
if code != 200 {
return nil, util.CreateAPIHandleError(code, fmt.Errorf("Get database center configs code %d", code))
}
return &gc, nil
}
func (n *node) GetNodeByRule(rule string) ([]*client.HostNode, *util.APIHandleError) {
var res utilhttp.ResponseBody
var gc []*client.HostNode
res.List = &gc
code, err := n.DoRequest(n.prefix+"/rule/"+rule, "GET", nil, &res)
if err != nil {
return nil, util.CreateAPIHandleError(code, err)
}
if code != 200 {
return nil, util.CreateAPIHandleError(code, fmt.Errorf("Get database center configs code %d", code))
}
return gc, nil
}
func (n *node) List() ([]*client.HostNode, *util.APIHandleError) {
var res utilhttp.ResponseBody
var gc []*client.HostNode
res.List = &gc
code, err := n.DoRequest(n.prefix, "GET", nil, &res)
if err != nil {
return nil, util.CreateAPIHandleError(code, err)
}
if code != 200 {
return nil, util.CreateAPIHandleError(code, fmt.Errorf("Get database center configs code %d", code))
}
return gc, nil
}
func (n *node) Add(node *client.APIHostNode) *util.APIHandleError {
body, err := json.Marshal(node)
if err != nil {
return util.CreateAPIHandleError(400, err)
}
code, err := n.DoRequest(n.prefix, "POST", bytes.NewBuffer(body), nil)
if err != nil {
return util.CreateAPIHandleError(code, err)
}
return nil
}
func (n *node) Label(nid string, label map[string]string) *util.APIHandleError {
body, err := json.Marshal(label)
if err != nil {
return util.CreateAPIHandleError(400, err)
}
code, err := n.DoRequest(n.prefix+"/"+nid+"/labels", "PUT", bytes.NewBuffer(body), nil)
if err != nil {
return util.CreateAPIHandleError(code, err)
}
return nil
}
func (n *node) Delete(nid string) *util.APIHandleError {
code, err := n.DoRequest(n.prefix+"/"+nid, "DELETE", nil, nil)
if err != nil {
return util.CreateAPIHandleError(code, err)
}
return nil
}
func (n *node) Up(nid string) *util.APIHandleError {
code, err := n.DoRequest(n.prefix+"/"+nid+"/up", "POST", nil, nil)
if err != nil {
return util.CreateAPIHandleError(code, err)
}
return nil
}
func (n *node) Down(nid string) *util.APIHandleError {
code, err := n.DoRequest(n.prefix+"/"+nid+"/down", "POST", nil, nil)
if err != nil {
return util.CreateAPIHandleError(code, err)
}
return nil
}
func (n *node) UnSchedulable(nid string) *util.APIHandleError {
code, err := n.DoRequest(n.prefix+"/"+nid+"/unschedulable", "PUT", nil, nil)
if err != nil {
return util.CreateAPIHandleError(code, err)
}
return nil
}
func (n *node) ReSchedulable(nid string) *util.APIHandleError {
code, err := n.DoRequest(n.prefix+"/"+nid+"/reschedulable", "PUT", nil, nil)
if err != nil {
return util.CreateAPIHandleError(code, err)
}
return nil
}
type configs struct {
regionImpl
prefix string
}
func (c *configs) Get() (*model.GlobalConfig, *util.APIHandleError) {
var res utilhttp.ResponseBody
var gc = model.GlobalConfig{
Configs: make(map[string]*model.ConfigUnit),
}
res.Bean = &gc
code, err := c.DoRequest(c.prefix+"/datacenter", "GET", nil, &res)
if err != nil {
return nil, util.CreateAPIHandleError(code, err)
}
if code != 200 {
return nil, util.CreateAPIHandleError(code, fmt.Errorf("Get database center configs code %d", code))
}
return &gc, nil
}
func (c *configs) Put(gc *model.GlobalConfig) *util.APIHandleError {
rebody, err := ffjson.Marshal(gc)
if err != nil {
return util.CreateAPIHandleError(400, err)
}
code, err := c.DoRequest(c.prefix+"/datacenter", "PUT", bytes.NewBuffer(rebody), nil)
if err != nil {
return util.CreateAPIHandleError(code, err)
}
if code != 200 {
return util.CreateAPIHandleError(code, fmt.Errorf("Put database center configs code %d", code))
}
return nil
}
//TaskInterface task api
type TaskInterface interface {
Get(name string) (*model.Task, *util.APIHandleError)
Status(name string) (*TaskStatus, error)
HandleTaskStatus(task string) (*map[string]*model.TaskStatus, *util.APIHandleError)
GetTaskStatus(task string) (map[string]*model.TaskStatus, *util.APIHandleError)
Add(task *model.Task) *util.APIHandleError
AddGroup(group *model.TaskGroup) *util.APIHandleError
Exec(name string, nodes []string) *util.APIHandleError
List() ([]*model.Task, *util.APIHandleError)
Refresh() *util.APIHandleError
}
//NodeInterface node api
type NodeInterface interface {
Rule(rule string) ([]*client.HostNode, *util.APIHandleError)
GetNodeByRule(rule string) ([]*client.HostNode, *util.APIHandleError)
Get(node string) (*client.HostNode, *util.APIHandleError)
List() ([]*client.HostNode, *util.APIHandleError)
Add(node *client.APIHostNode) *util.APIHandleError
@ -101,190 +215,34 @@ type ConfigsInterface interface {
Get() (*model.GlobalConfig, *util.APIHandleError)
Put(*model.GlobalConfig) *util.APIHandleError
}
type configs struct {
client *RNodeClient
prefix string
}
func (c *configs) Get() (*model.GlobalConfig, *util.APIHandleError) {
body, code, err := c.client.Request(c.prefix+"/datacenter", "GET", nil)
if err != nil {
return nil, util.CreateAPIHandleError(code, err)
}
if code != 200 {
return nil, util.CreateAPIHandleError(code, fmt.Errorf("Get database center configs code %d", code))
}
var res utilhttp.ResponseBody
var gc = model.GlobalConfig{
Configs: make(map[string]*model.ConfigUnit),
}
res.Bean = &gc
if err := ffjson.Unmarshal(body, &res); err != nil {
return nil, util.CreateAPIHandleError(code, err)
}
if gc, ok := res.Bean.(*model.GlobalConfig); ok {
return gc, nil
}
return nil, nil
}
func (c *configs) Put(gc *model.GlobalConfig) *util.APIHandleError {
rebody, err := ffjson.Marshal(gc)
if err != nil {
return util.CreateAPIHandleError(400, err)
}
_, code, err := c.client.Request(c.prefix+"/datacenter", "PUT", rebody)
if err != nil {
return util.CreateAPIHandleError(code, err)
}
if code != 200 {
return util.CreateAPIHandleError(code, fmt.Errorf("Put database center configs code %d", code))
}
return nil
}
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)
}
if code != 200 {
return nil, util.CreateAPIHandleError(code, fmt.Errorf("Get database center configs code %d", code))
}
var res utilhttp.ResponseBody
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.(*client.HostNode); ok {
return gc, nil
}
return nil, nil
}
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)
}
if code != 200 {
return nil, util.CreateAPIHandleError(code, fmt.Errorf("Get database center configs code %d", code))
}
var res utilhttp.ResponseBody
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.(*[]*client.HostNode); ok {
return *gc, nil
}
return nil, nil
}
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)
}
if code != 200 {
return nil, util.CreateAPIHandleError(code, fmt.Errorf("Get database center configs code %d", code))
}
var res utilhttp.ResponseBody
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.(*[]*client.HostNode); ok {
return *gc, nil
}
return nil, nil
}
// put/post 类
func (n *node) Add(node *client.APIHostNode) *util.APIHandleError {
body, err := json.Marshal(node)
if err != nil {
return util.CreateAPIHandleError(400, err)
}
resp, code, err := n.client.Request(n.prefix, "POST", body)
return n.client.handleErrAndCodeWithMsg(resp, err, code)
}
func (n *node) Label(nid string, label map[string]string) *util.APIHandleError {
body, err := json.Marshal(label)
if err != nil {
return util.CreateAPIHandleError(400, err)
}
resp, code, err := n.client.Request(n.prefix+"/"+nid+"/labels", "PUT", body)
return n.client.handleErrAndCodeWithMsg(resp, err, code)
}
func (n *node) Delete(nid string) *util.APIHandleError {
resp, code, err := n.client.Request(n.prefix+"/"+nid, "DELETE", nil)
return n.client.handleErrAndCodeWithMsg(resp, err, code)
}
func (n *node) Up(nid string) *util.APIHandleError {
resp, code, err := n.client.Request(n.prefix+"/"+nid+"/up", "POST", nil)
return n.client.handleErrAndCodeWithMsg(resp, err, code)
}
func (n *node) Down(nid string) *util.APIHandleError {
resp, code, err := n.client.Request(n.prefix+"/"+nid+"/down", "POST", nil)
return n.client.handleErrAndCodeWithMsg(resp, err, code)
}
func (n *node) UnSchedulable(nid string) *util.APIHandleError {
resp, code, err := n.client.Request(n.prefix+"/"+nid+"/unschedulable", "PUT", nil)
return n.client.handleErrAndCodeWithMsg(resp, err, code)
}
func (n *node) ReSchedulable(nid string) *util.APIHandleError {
resp, code, err := n.client.Request(n.prefix+"/"+nid+"/reschedulable", "PUT", nil)
return n.client.handleErrAndCodeWithMsg(resp, err, code)
}
func (t *task) Get(id string) (*model.Task, *util.APIHandleError) {
url := t.prefix + "/" + id
body, code, err := nodeclient.Request(url, "GET", nil)
var res utilhttp.ResponseBody
var gc model.Task
res.Bean = &gc
code, err := t.DoRequest(t.prefix+"/"+id, "GET", nil, &res)
if err != nil {
return nil, util.CreateAPIHandleError(code, err)
}
if code != 200 {
return nil, util.CreateAPIHandleError(code, fmt.Errorf("get task with code %d", code))
}
var res utilhttp.ResponseBody
var gc model.Task
res.Bean = &gc
if err := ffjson.Unmarshal(body, &res); err != nil {
return nil, util.CreateAPIHandleError(code, err)
}
if gc, ok := res.Bean.(*model.Task); ok {
return gc, nil
}
return nil, nil
return &gc, nil
}
//List list all task
func (t *task) List() ([]*model.Task, *util.APIHandleError) {
url := t.prefix
body, code, err := nodeclient.Request(url, "GET", nil)
var res utilhttp.ResponseBody
var gc []*model.Task
res.List = &gc
code, err := t.DoRequest(t.prefix, "GET", nil, &res)
if err != nil {
return nil, util.CreateAPIHandleError(code, err)
}
if code != 200 {
return nil, util.CreateAPIHandleError(code, fmt.Errorf("get task with code %d", code))
}
var res utilhttp.ResponseBody
var gc []*model.Task
res.List = &gc
if err := ffjson.Unmarshal(body, &res); err != nil {
return nil, util.CreateAPIHandleError(code, err)
}
if gc, ok := res.List.(*[]*model.Task); ok {
return *gc, nil
}
return nil, nil
return gc, nil
}
//Exec 执行任务
@ -298,130 +256,42 @@ func (t *task) Exec(taskID string, nodes []string) *util.APIHandleError {
return util.CreateAPIHandleError(400, err)
}
url := t.prefix + "/" + taskID + "/exec"
resp, code, err := nodeclient.Request(url, "POST", body)
return t.client.handleErrAndCodeWithMsg(resp, err, code)
code, err := t.DoRequest(url, "POST", bytes.NewBuffer(body), nil)
if err != nil {
return util.CreateAPIHandleError(code, err)
}
return nil
}
func (t *task) Add(task *model.Task) *util.APIHandleError {
body, _ := json.Marshal(task)
url := t.prefix
resp, code, err := nodeclient.Request(url, "POST", body)
return t.client.handleErrAndCodeWithMsg(resp, err, code)
code, err := t.DoRequest(url, "POST", bytes.NewBuffer(body), nil)
if err != nil {
return util.CreateAPIHandleError(code, err)
}
return nil
}
func (t *task) AddGroup(group *model.TaskGroup) *util.APIHandleError {
body, _ := json.Marshal(group)
url := "/taskgroups"
resp, code, err := nodeclient.Request(url, "POST", body)
return t.client.handleErrAndCodeWithMsg(resp, err, code)
url := "/v2/taskgroups"
code, err := t.DoRequest(url, "POST", bytes.NewBuffer(body), nil)
if err != nil {
return util.CreateAPIHandleError(code, err)
}
return nil
}
//Refresh 刷新静态配置
func (t *task) Refresh() *util.APIHandleError {
url := t.prefix + "/taskreload"
resp, code, err := nodeclient.Request(url, "PUT", nil)
return t.client.handleErrAndCodeWithMsg(resp, err, code)
}
type TaskStatus struct {
Status map[string]model.TaskStatus `json:"status,omitempty"`
}
func (t *task) Status(name string) (*TaskStatus, error) {
taskId := name
return HandleTaskStatus(taskId)
}
func (t *task) HandleTaskStatus(task string) (*map[string]*model.TaskStatus, *util.APIHandleError) {
body, code, err := nodeclient.Request("/tasks/"+task+"/status", "GET", nil)
func (t *task) GetTaskStatus(task string) (map[string]*model.TaskStatus, *util.APIHandleError) {
var res utilhttp.ResponseBody
var gc = make(map[string]*model.TaskStatus)
res.Bean = &gc
code, err := t.DoRequest("/tasks/"+task+"/status", "GET", nil, &res)
if err != nil {
return nil, util.CreateAPIHandleError(code, err)
}
if code != 200 {
return nil, util.CreateAPIHandleError(code, fmt.Errorf("get task with code %d", code))
}
var res utilhttp.ResponseBody
var gc map[string]*model.TaskStatus
res.Bean = &gc
if err := ffjson.Unmarshal(body, &res); err != nil {
return nil, util.CreateAPIHandleError(code, err)
}
if gc, ok := res.Bean.(*map[string]*model.TaskStatus); ok {
return gc, nil
}
return nil, nil
}
func HandleTaskStatus(task string) (*TaskStatus, error) {
resp, code, err := nodeclient.Request("/tasks/"+task+"/status", "GET", nil)
if err != nil {
logrus.Errorf("error execute status Request,details %s", err.Error())
return nil, err
}
if code == 200 {
j, _ := simplejson.NewJson(resp)
bean := j.Get("bean")
beanB, _ := json.Marshal(bean)
var status TaskStatus
statusMap := make(map[string]model.TaskStatus)
json, _ := simplejson.NewJson(beanB)
second := json.Interface()
if second == nil {
return nil, errors.New("get status failed")
}
m := second.(map[string]interface{})
for k, _ := range m {
var taskStatus model.TaskStatus
taskStatus.CompleStatus = m[k].(map[string]interface{})["comple_status"].(string)
taskStatus.Status = m[k].(map[string]interface{})["status"].(string)
taskStatus.JobID = k
statusMap[k] = taskStatus
}
status.Status = statusMap
return &status, nil
}
return nil, errors.New(fmt.Sprintf("response status is %s", code))
}
//Request Request
func (r *RNodeClient) Request(url, method string, body []byte) ([]byte, int, error) {
//logrus.Infof("requesting url: %s by method :%s,and body is %s",r.NodeAPI+url,method,string(body))
request, err := http.NewRequest(method, "http://127.0.0.1:6100/v2"+url, bytes.NewBuffer(body))
if err != nil {
return nil, 500, err
}
request.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(request)
if err != nil {
return nil, 500, err
}
data, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, 500, err
}
defer res.Body.Close()
//logrus.Infof("response is %s,response code is %d",string(data),res.StatusCode)
return data, res.StatusCode, nil
}
func (r *RNodeClient) handleErrAndCode(err error, code int) *util.APIHandleError {
if err != nil {
return util.CreateAPIHandleError(code, err)
}
if code != 200 {
return util.CreateAPIHandleError(code, fmt.Errorf("error with code %d", code))
}
return nil
}
func (r *RNodeClient) handleErrAndCodeWithMsg(resp []byte, err error, code int) *util.APIHandleError {
if err != nil {
return util.CreateAPIHandleError(code, err)
}
if code != 200 {
return util.CreateAPIHandleError(code, fmt.Errorf("error with code %d , %s", code, string(resp)))
}
return nil
return gc, nil
}

View File

@ -47,7 +47,10 @@ var AllTenant string
type Region interface {
Tenants(name string) TenantInterface
Resources() ResourcesInterface
//Nodes() NodeInterface
Tasks() TaskInterface
Nodes() NodeInterface
Cluster() ClusterInterface
Configs() ConfigsInterface
Version() string
DoRequest(path, method string, body io.Reader, decode *utilhttp.ResponseBody) (int, error)
}
@ -242,8 +245,10 @@ func (r *regionImpl) DoRequest(path, method string, body io.Reader, decode *util
if res.Body != nil {
defer res.Body.Close()
}
if err := json.NewDecoder(res.Body).Decode(decode); err != nil {
return res.StatusCode, err
if decode != nil {
if err := json.NewDecoder(res.Body).Decode(decode); err != nil {
return res.StatusCode, err
}
}
return res.StatusCode, err
}

View File

@ -56,3 +56,23 @@ func TestDoRequest(t *testing.T) {
}
t.Logf("%+v", tenants)
}
func TestListNodes(t *testing.T) {
region := NewRegion("http://kubeapi.goodrain.me:8888", "", "")
services, err := region.Nodes().List()
if err != nil {
t.Fatal(err)
}
for _, s := range services {
t.Logf("%+v", s)
}
}
func TestGetNodes(t *testing.T) {
region := NewRegion("http://kubeapi.goodrain.me:8888", "", "")
node, err := region.Nodes().Get("a134eab8-3d42-40f5-84a5-fcf2b7a44b31")
if err != nil {
t.Fatal(err)
}
t.Logf("%+v", node)
}

View File

@ -19,12 +19,14 @@
package option
import (
"encoding/json"
"io/ioutil"
"os"
"path"
"github.com/Sirupsen/logrus"
"github.com/goodrain/rainbond/builder/sources"
"github.com/urfave/cli"
yaml "gopkg.in/yaml.v2"
//"strings"
)
@ -32,30 +34,30 @@ var config Config
//Config Config
type Config struct {
RegionMysql RegionMysql `json:"RegionMysql"`
Kubernets Kubernets `json:"Kubernets"`
RegionAPI RegionAPI `json:"RegionAPI"`
DockerLogPath string `json:"DockerLogPath"`
RegionMysql RegionMysql `yaml:"region_db"`
Kubernets Kubernets `yaml:"kube"`
RegionAPI RegionAPI `yaml:"region_api"`
DockerLogPath string `yaml:"docker_log_path"`
}
//RegionMysql RegionMysql
type RegionMysql struct {
URL string `json:"URL"`
Pass string `json:"Pass"`
User string `json:"User"`
Database string `json:"Database"`
URL string `yaml:"url"`
Pass string `yaml:"pass"`
User string `yaml:"user"`
Database string `yaml:"database"`
}
//Kubernets Kubernets
type Kubernets struct {
Master string
Master string `yaml:"master"`
}
//RegionAPI RegionAPI
type RegionAPI struct {
URL string
Token string
Type string
URL string `yaml:"url"`
Token string `yaml:"token"`
Type string `yaml:"type"`
}
//LoadConfig 加载配置
@ -71,16 +73,21 @@ func LoadConfig(ctx *cli.Context) (Config, error) {
Database: os.Getenv("MYSQL_DB"),
},
}
_, err := os.Stat(ctx.GlobalString("config"))
configfile := ctx.GlobalString("config")
if configfile == "" {
home, _ := sources.Home()
configfile = path.Join(home, "grctl.yaml")
}
_, err := os.Stat(configfile)
if err != nil {
return config, err
}
data, err := ioutil.ReadFile(ctx.GlobalString("config"))
data, err := ioutil.ReadFile(configfile)
if err != nil {
logrus.Warning("Read config file error ,will get config from region.", err.Error())
return config, err
}
if err := json.Unmarshal(data, &config); err != nil {
if err := yaml.Unmarshal(data, &config); err != nil {
logrus.Warning("Read config file error ,will get config from region.", err.Error())
return config, err
}

View File

@ -22,9 +22,7 @@ import (
"os"
"sort"
"github.com/Sirupsen/logrus"
version "github.com/goodrain/rainbond/cmd"
"github.com/goodrain/rainbond/grctl/clients"
"github.com/goodrain/rainbond/grctl/cmd"
"github.com/urfave/cli"
)
@ -38,16 +36,12 @@ func Run() error {
App.Flags = []cli.Flag{
cli.StringFlag{
Name: "config, c",
Value: "/etc/goodrain/grctl.json",
Usage: "Load configuration from `FILE`",
Value: "",
Usage: "default <USER_HOME>/grctl.yaml",
},
}
sort.Sort(cli.FlagsByName(App.Flags))
sort.Sort(cli.CommandsByName(App.Commands))
App.Commands = cmd.GetCmds()
if err := clients.InitNodeClient("http://127.0.0.1:6100/v2"); err != nil {
logrus.Warnf("error config region")
}
return App.Run(os.Args)
}

View File

@ -24,8 +24,6 @@ import (
"path"
"time"
"github.com/goodrain/rainbond/node/utils"
"github.com/Sirupsen/logrus"
client "github.com/coreos/etcd/clientv3"
"github.com/fsnotify/fsnotify"
@ -112,7 +110,6 @@ type Conf struct {
// for node controller
DefaultConfigFile string
ServiceListFile string
}
//StatsdConfig StatsdConfig
@ -211,11 +208,12 @@ func cleanKeyPrefix(p string) string {
return p
}
//parse parse
func (c *Conf) parse() error {
err := utils.LoadExtendConf(*confFile, c)
if err != nil {
return err
}
// err := utils.LoadExtendConf(*confFile, c)
// if err != nil {
// return err
// }
if c.Etcd.DialTimeout > 0 {
c.Etcd.DialTimeout *= time.Second
@ -227,12 +225,12 @@ func (c *Conf) parse() error {
c.LockTTL = 300
}
c.NodePath = cleanKeyPrefix(c.NodePath)
c.Proc = cleanKeyPrefix(c.Proc)
c.JobPath = cleanKeyPrefix(c.JobPath)
c.Lock = cleanKeyPrefix(c.Lock)
c.Group = cleanKeyPrefix(c.Group)
c.Noticer = cleanKeyPrefix(c.Noticer)
// c.NodePath = cleanKeyPrefix(c.NodePath)
// c.Proc = cleanKeyPrefix(c.Proc)
// c.JobPath = cleanKeyPrefix(c.JobPath)
// c.Lock = cleanKeyPrefix(c.Lock)
// c.Group = cleanKeyPrefix(c.Group)
// c.Noticer = cleanKeyPrefix(c.Noticer)
//固定值
c.HostIDFile = "/opt/rainbond/etc/node/node_host_uuid.conf"
return nil

View File

@ -26,18 +26,8 @@ import (
//RegionClient region api
var RegionClient region.Region
//NodeClient node api
var NodeClient *region.RNodeClient
//InitRegionClient init region api client
func InitRegionClient(reg option.RegionAPI) error {
RegionClient = region.NewRegion(reg.URL, reg.Token, reg.Type)
return nil
}
//InitNodeClient init node api client
func InitNodeClient(nodeAPI string) error {
region.NewNode("http://127.0.0.1:6100/v2")
NodeClient = region.GetNode()
return nil
}

79
grctl/cmd/cluster.go Normal file
View File

@ -0,0 +1,79 @@
// 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 <http://www.gnu.org/licenses/>.
package cmd
import (
"fmt"
"github.com/apcera/termtables"
"github.com/goodrain/rainbond/grctl/clients"
"github.com/goodrain/rainbond/node/nodem/client"
"github.com/gosuri/uitable"
"github.com/urfave/cli"
)
//NewCmdCluster cmd for cluster
func NewCmdCluster() cli.Command {
c := cli.Command{
Name: "cluster",
Usage: "show curren cluster datacenter info",
Action: func(c *cli.Context) error {
Common(c)
return getClusterInfo(c)
},
}
return c
}
func getClusterInfo(c *cli.Context) error {
//show cluster resource detail
clusterInfo, err := clients.RegionClient.Cluster().GetClusterInfo()
handleErr(err)
table := uitable.New()
table.AddRow("", "Used/Total", "Use of")
table.AddRow("CPU", fmt.Sprintf("%f.2/%d", clusterInfo.ReqCPU, clusterInfo.CapCPU),
fmt.Sprintf("%d", int(clusterInfo.ReqCPU*100/float32(clusterInfo.CapCPU)))+"%")
table.AddRow("Memory", fmt.Sprintf("%d/%d", clusterInfo.ReqMem, clusterInfo.CapMem),
fmt.Sprintf("%d", int(float32(clusterInfo.ReqMem*100)/float32(clusterInfo.CapMem)))+"%")
table.AddRow("DistributedDisk", fmt.Sprintf("%d/%d", clusterInfo.ReqDisk, clusterInfo.CapDisk),
fmt.Sprintf("%d", int(float32(clusterInfo.ReqDisk*100)/float32(clusterInfo.CapDisk)))+"%")
fmt.Println(table)
//show node detail
list, err := clients.RegionClient.Nodes().List()
handleErr(err)
serviceTable := termtables.CreateTable()
serviceTable.AddHeaders("Uid", "IP", "HostName", "NodeRole", "NodeMode", "Status", "Alived", "Schedulable", "Ready")
var rest []*client.HostNode
for _, v := range list {
if v.Role.HasRule("manage") {
handleStatus(serviceTable, isNodeReady(v), v)
} else {
rest = append(rest, v)
}
}
if len(rest) > 0 {
serviceTable.AddSeparator()
}
for _, v := range rest {
handleStatus(serviceTable, isNodeReady(v), v)
}
fmt.Println(serviceTable.Render())
return nil
}

View File

@ -38,12 +38,12 @@ func GetCmds() []cli.Command {
cmds = append(cmds, NewCmdShow())
//task相关命令
cmds = append(cmds, NewCmdTasks())
//cmds = append(cmds, NewCmdTasks())
//数据中心配置相关命令
cmds = append(cmds, NewCmdConfigs())
//cmds = append(cmds, NewCmdComputeGroup())
cmds = append(cmds, NewCmdInstall())
//cmds = append(cmds, NewCmdInstall())
//cmds = append(cmds, NewCmdInstallStatus())
cmds = append(cmds, NewCmdDomain())
@ -73,8 +73,4 @@ func Common(c *cli.Context) {
if err := clients.InitRegionClient(config.RegionAPI); err != nil {
logrus.Warnf("error config region")
}
if err := clients.InitNodeClient("http://127.0.0.1:6100/v2"); err != nil {
logrus.Warnf("error config region")
}
}

View File

@ -38,7 +38,7 @@ func NewCmdConfigs() cli.Command {
Name: "get",
Usage: "get all datacenter configs",
Action: func(c *cli.Context) error {
configs, err := clients.NodeClient.Configs().Get()
configs, err := clients.RegionClient.Configs().Get()
if err != nil {
return err
}
@ -57,7 +57,7 @@ func NewCmdConfigs() cli.Command {
Action: func(c *cli.Context) error {
key := c.Args().Get(0)
value := c.Args().Get(1)
configs, err := clients.NodeClient.Configs().Get()
configs, err := clients.RegionClient.Configs().Get()
if err != nil {
return err
}
@ -77,7 +77,7 @@ func NewCmdConfigs() cli.Command {
gc.ValueType = "string"
gc.Value = value
}
err = clients.NodeClient.Configs().Put(configs)
err = clients.RegionClient.Configs().Put(configs)
if err != nil {
return err
}

View File

@ -17,19 +17,21 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package cmd
import (
"github.com/urfave/cli"
"fmt"
"bytes"
"fmt"
"os/exec"
"github.com/goodrain/rainbond/grctl/clients"
"github.com/Sirupsen/logrus"
"strings"
"github.com/Sirupsen/logrus"
"github.com/goodrain/rainbond/grctl/clients"
"github.com/goodrain/rainbond/node/api/model"
"github.com/urfave/cli"
)
func NewCmdDomain() cli.Command {
c:=cli.Command{
c := cli.Command{
Name: "domain",
Flags: []cli.Flag{
cli.StringFlag{
@ -43,17 +45,17 @@ func NewCmdDomain() cli.Command {
},
Usage: "",
Action: func(c *cli.Context) error {
ip:=c.String("ip")
if len(ip)==0 {
ip := c.String("ip")
if len(ip) == 0 {
fmt.Println("ip must not null")
return nil
}
domain:=c.String("domain")
cmd := exec.Command("bash", "/opt/rainbond/bin/.domain.sh",ip,domain)
outbuf:=bytes.NewBuffer(nil)
cmd.Stdout=outbuf
domain := c.String("domain")
cmd := exec.Command("bash", "/opt/rainbond/bin/.domain.sh", ip, domain)
outbuf := bytes.NewBuffer(nil)
cmd.Stdout = outbuf
cmd.Run()
out:=outbuf.String()
out := outbuf.String()
fmt.Println(out)
return nil
},
@ -61,7 +63,7 @@ func NewCmdDomain() cli.Command {
return c
}
func NewCmdCheckTask() cli.Command {
c:=cli.Command{
c := cli.Command{
Name: "checkTask",
Flags: []cli.Flag{
cli.StringFlag{
@ -71,90 +73,89 @@ func NewCmdCheckTask() cli.Command {
},
Usage: "",
Action: func(c *cli.Context) error {
uuid:=c.String("uuid")
if len(uuid)==0 {
uuid := c.String("uuid")
if len(uuid) == 0 {
fmt.Println("uuid must not null")
return nil
}
tasks,err:=clients.NodeClient.Tasks().List()
tasks, err := clients.RegionClient.Tasks().List()
if err != nil {
logrus.Errorf("error get task list,details %s",err.Error())
logrus.Errorf("error get task list,details %s", err.Error())
return err
}
var result []*ExecedTask
for _,v:=range tasks{
taskStatus,ok:=v.Status[uuid]
if ok{
status:=strings.ToLower(taskStatus.Status)
if status=="complete" ||status=="start"{
var taskentity =&ExecedTask{}
taskentity.ID=v.ID
taskentity.Status=taskStatus.Status
taskentity.Depends=[]string{}
dealDepend(taskentity,v)
dealNext(taskentity,tasks)
result=append(result, taskentity)
for _, v := range tasks {
taskStatus, ok := v.Status[uuid]
if ok {
status := strings.ToLower(taskStatus.Status)
if status == "complete" || status == "start" {
var taskentity = &ExecedTask{}
taskentity.ID = v.ID
taskentity.Status = taskStatus.Status
taskentity.Depends = []string{}
dealDepend(taskentity, v)
dealNext(taskentity, tasks)
result = append(result, taskentity)
continue
}
}else {
_,scheduled:=v.Scheduler.Status[uuid]
} else {
_, scheduled := v.Scheduler.Status[uuid]
if scheduled {
var taskentity =&ExecedTask{}
taskentity.ID=v.ID
taskentity.Depends=[]string{}
dealDepend(taskentity,v)
dealNext(taskentity,tasks)
allDepDone:=true
var taskentity = &ExecedTask{}
taskentity.ID = v.ID
taskentity.Depends = []string{}
dealDepend(taskentity, v)
dealNext(taskentity, tasks)
allDepDone := true
for _,dep:=range taskentity.Depends {
task,_:=clients.NodeClient.Tasks().Get(dep)
for _, dep := range taskentity.Depends {
task, _ := clients.RegionClient.Tasks().Get(dep)
_,depOK:=task.Status[uuid]
_, depOK := task.Status[uuid]
if !depOK {
allDepDone=false
allDepDone = false
break
}
}
if allDepDone {
taskentity.Status="start"
result=append(result, taskentity)
taskentity.Status = "start"
result = append(result, taskentity)
}
}
}
}
for _,v:=range result {
fmt.Printf("task %s is %s,depends is %v\n",v.ID,v.Status,v.Depends)
for _, v := range result {
fmt.Printf("task %s is %s,depends is %v\n", v.ID, v.Status, v.Depends)
}
return nil
},
}
return c
}
func dealDepend(result *ExecedTask,task *model.Task) {
func dealDepend(result *ExecedTask, task *model.Task) {
if task.Temp.Depends != nil {
for _,v:=range task.Temp.Depends{
result.Depends=append(result.Depends,v.DependTaskID)
for _, v := range task.Temp.Depends {
result.Depends = append(result.Depends, v.DependTaskID)
}
}
}
func dealNext(task *ExecedTask, tasks []*model.Task) {
for _,v:=range tasks {
for _, v := range tasks {
if v.Temp.Depends != nil {
for _,dep:=range v.Temp.Depends{
for _, dep := range v.Temp.Depends {
if dep.DependTaskID == task.ID {
task.Next=append(task.Next,v.ID)
task.Next = append(task.Next, v.ID)
}
}
}
}
}
type ExecedTask struct {
ID string
Status string
ID string
Status string
Depends []string
Next []string
Next []string
}

View File

@ -89,7 +89,7 @@ func NewCmdInstallStatus() cli.Command {
Action: func(c *cli.Context) error {
taskID := c.String("taskID")
if taskID == "" {
tasks, err := clients.NodeClient.Tasks().List()
tasks, err := clients.RegionClient.Tasks().List()
if err != nil {
logrus.Errorf("error get task list,details %s", err.Error())
return nil
@ -192,12 +192,12 @@ func initCluster(c *cli.Context) error {
var error *util.APIHandleError
for i := 0; i < 10; i++ {
time.Sleep(time.Second * 2)
gc, error = clients.NodeClient.Configs().Get()
gc, error = clients.RegionClient.Configs().Get()
if err == nil && gc != nil {
for _, nc := range newConfigs {
gc.Add(nc)
}
error = clients.NodeClient.Configs().Put(gc)
error = clients.RegionClient.Configs().Put(gc)
break
}
}
@ -217,7 +217,7 @@ func initCluster(c *cli.Context) error {
// logrus.Errorf("error exec task:%s,details %s", "check_manage_base_services", error.String())
// return error.Err
//}
error = clients.NodeClient.Tasks().Exec("check_manage_services", []string{hostID})
error = clients.RegionClient.Tasks().Exec("check_manage_services", []string{hostID})
if error != nil {
logrus.Errorf("error exec task:%s,details %s", "check_manage_services", error.String())
return error.Err

View File

@ -198,32 +198,32 @@ func Status(task string, nodes []string) {
lastState = "Start"
for checkFail < 3 {
time.Sleep(3 * time.Second)
taskE, err := clients.NodeClient.Tasks().Get(task)
taskE, err := clients.RegionClient.Tasks().Get(task)
if err != nil {
logrus.Warnf("error get task %s ,details %s,retry", task,err.String())
logrus.Warnf("error get task %s ,details %s,retry", task, err.String())
checkFail += 1
continue
}
//status,error:=clients.NodeClient.Tasks().Status(task)
status,err:=clients.NodeClient.Tasks().HandleTaskStatus(task)
if err != nil||status==nil {
logrus.Warnf("error get task %s status,details %s,retry",task,err.String())
checkFail+=1
status, err := clients.RegionClient.Tasks().GetTaskStatus(task)
if err != nil || status == nil {
logrus.Warnf("error get task %s status,details %s,retry", task, err.String())
checkFail += 1
continue
}
for k,v:=range *status{
for k, v := range status {
//不是当前任务需要检测的status
if !set[k] {
fmt.Print("..")
continue
}
if strings.Contains(v.Status, "error")||strings.Contains(v.CompleStatus,"Failure")||strings.Contains(v.CompleStatus,"Unknow") {
checkFail+=1
fmt.Errorf("error executing task %s",task)
for _,v:=range taskE.OutPut{
if set[v.NodeID]{
fmt.Printf("on %s :\n %s",v.NodeID,v.Body)
if strings.Contains(v.Status, "error") || strings.Contains(v.CompleStatus, "Failure") || strings.Contains(v.CompleStatus, "Unknow") {
checkFail += 1
fmt.Errorf("error executing task %s", task)
for _, v := range taskE.OutPut {
if set[v.NodeID] {
fmt.Printf("on %s :\n %s", v.NodeID, v.Body)
}
}
os.Exit(1)
@ -233,13 +233,13 @@ func Status(task string, nodes []string) {
} else {
fmt.Print("..")
}
lastState=v.Status
if v.Status=="complete"||v.CompleStatus=="Success"{
fmt.Printf("task %s is %s %s\n",task,v.Status,v.CompleStatus)
lastState=v.Status
taskFinished:=taskE
var nextTasks []string
for _,v:=range taskFinished.OutPut{
lastState = v.Status
if v.Status == "complete" || v.CompleStatus == "Success" {
fmt.Printf("task %s is %s %s\n", task, v.Status, v.CompleStatus)
lastState = v.Status
taskFinished := taskE
var nextTasks []string
for _, v := range taskFinished.OutPut {
if !set[v.NodeID] {
continue
}
@ -272,7 +272,7 @@ func Task(c *cli.Context, task string, status bool) error {
if len(nodes) == 0 {
return fmt.Errorf("nodes can not be empty")
}
err := clients.NodeClient.Tasks().Exec(task, nodes)
err := clients.RegionClient.Tasks().Exec(task, nodes)
if err != nil {
logrus.Errorf("error exec task:%s,details %s", task, err.Error())
return err

View File

@ -25,9 +25,7 @@ import (
"fmt"
"io/ioutil"
"os"
"strconv"
"strings"
"time"
"github.com/Sirupsen/logrus"
"github.com/apcera/termtables"
@ -35,8 +33,6 @@ import (
"github.com/goodrain/rainbond/grctl/clients"
"github.com/goodrain/rainbond/node/nodem/client"
"github.com/urfave/cli"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
)
func handleErr(err *util.APIHandleError) {
@ -50,7 +46,7 @@ func NewCmdShow() cli.Command {
Name: "show",
Usage: "显示region安装完成后访问地址",
Action: func(c *cli.Context) error {
manageHosts, err := clients.NodeClient.Nodes().Rule("manage")
manageHosts, err := clients.RegionClient.Nodes().GetNodeByRule("manage")
handleErr(err)
ips := getExternalIP("/etc/goodrain/envs/.exip", manageHosts)
fmt.Println("Manage your apps with webui")
@ -130,7 +126,7 @@ func NewCmdNode() cli.Command {
return nil
}
nodes, err := clients.NodeClient.Nodes().List()
nodes, err := clients.RegionClient.Nodes().List()
handleErr(err)
for _, v := range nodes {
if v.InternalIP == id {
@ -139,7 +135,7 @@ func NewCmdNode() cli.Command {
}
}
v, err := clients.NodeClient.Nodes().Get(id)
v, err := clients.RegionClient.Nodes().Get(id)
handleErr(err)
nodeByte, _ := json.Marshal(v)
var out bytes.Buffer
@ -155,7 +151,7 @@ func NewCmdNode() cli.Command {
Name: "list",
Usage: "list",
Action: func(c *cli.Context) error {
list, err := clients.NodeClient.Nodes().List()
list, err := clients.RegionClient.Nodes().List()
handleErr(err)
serviceTable := termtables.CreateTable()
serviceTable.AddHeaders("Uid", "IP", "HostName", "NodeRole", "NodeMode", "Status", "Alived", "Schedulable", "Ready")
@ -186,7 +182,7 @@ func NewCmdNode() cli.Command {
logrus.Errorf("need hostID")
return nil
}
err := clients.NodeClient.Nodes().Up(id)
err := clients.RegionClient.Nodes().Up(id)
handleErr(err)
return nil
},
@ -200,7 +196,7 @@ func NewCmdNode() cli.Command {
logrus.Errorf("need hostID")
return nil
}
err := clients.NodeClient.Nodes().Down(id)
err := clients.RegionClient.Nodes().Down(id)
handleErr(err)
return nil
},
@ -214,13 +210,13 @@ func NewCmdNode() cli.Command {
logrus.Errorf("need hostID")
return nil
}
node, err := clients.NodeClient.Nodes().Get(id)
node, err := clients.RegionClient.Nodes().Get(id)
handleErr(err)
if !node.Role.HasRule("compute") {
logrus.Errorf("管理节点不支持此功能")
return nil
}
err = clients.NodeClient.Nodes().UnSchedulable(id)
err = clients.RegionClient.Nodes().UnSchedulable(id)
handleErr(err)
return nil
},
@ -234,13 +230,13 @@ func NewCmdNode() cli.Command {
logrus.Errorf("need hostID")
return nil
}
node, err := clients.NodeClient.Nodes().Get(id)
node, err := clients.RegionClient.Nodes().Get(id)
handleErr(err)
if !node.Role.HasRule("compute") {
logrus.Errorf("管理节点不支持此功能")
return nil
}
err = clients.NodeClient.Nodes().ReSchedulable(id)
err = clients.RegionClient.Nodes().ReSchedulable(id)
handleErr(err)
return nil
},
@ -254,7 +250,7 @@ func NewCmdNode() cli.Command {
logrus.Errorf("need hostID")
return nil
}
err := clients.NodeClient.Nodes().Delete(id)
err := clients.RegionClient.Nodes().Delete(id)
handleErr(err)
return nil
},
@ -268,18 +264,12 @@ func NewCmdNode() cli.Command {
logrus.Errorf("need rule name")
return nil
}
hostnodes, err := clients.NodeClient.Nodes().Rule(rule)
hostnodes, err := clients.RegionClient.Nodes().GetNodeByRule(rule)
handleErr(err)
serviceTable := termtables.CreateTable()
serviceTable.AddHeaders("Uid", "IP", "HostName", "NodeRole", "NodeMode", "Alived", "Schedulable", "Ready")
serviceTable.AddHeaders("Uid", "IP", "HostName", "NodeRole", "NodeMode", "Status", "Alived", "Schedulable", "Ready")
for _, v := range hostnodes {
var ready bool = false
if v.NodeStatus != nil {
ready = true
}
handleStatus(serviceTable, ready, v)
handleStatus(serviceTable, isNodeReady(v), v)
}
return nil
},
@ -309,7 +299,7 @@ func NewCmdNode() cli.Command {
v := c.String("val")
label := make(map[string]string)
label[k] = v
err := clients.NodeClient.Nodes().Label(hostID, label)
err := clients.RegionClient.Nodes().Label(hostID, label)
handleErr(err)
return nil
},
@ -352,70 +342,69 @@ func NewCmdNode() cli.Command {
node.ExternalIP = c.String("ExternalIP")
node.RootPass = c.String("RootPass")
err := clients.NodeClient.Nodes().Add(&node)
err := clients.RegionClient.Nodes().Add(&node)
handleErr(err)
fmt.Println("开始初始化节点")
fmt.Println("success add node")
var hostNode *client.HostNode
timer := time.NewTimer(15 * time.Second)
gotNode := false
for !gotNode {
time.Sleep(3 * time.Second)
list, err := clients.NodeClient.Nodes().List()
handleErr(err)
for _, v := range list {
if node.InternalIP == v.InternalIP {
hostNode = v
timer.Stop()
gotNode = true
//todo 初始化其它节点失败判定
}
}
}
fmt.Println("添加节点成功,正在初始化")
tableC := termtables.CreateTable()
var header []string
var content []string
for {
time.Sleep(3 * time.Second)
list, err := clients.NodeClient.Nodes().List()
handleErr(err)
select {
case <-timer.C:
fmt.Println("添加节点超时请检查etcd")
return nil
default:
for _, v := range list {
if node.InternalIP == v.InternalIP {
hostNode = v
break
}
}
for _, val := range hostNode.NodeStatus.Conditions {
fmt.Println("正在判断节点状态,请稍等")
if hostNode.Alived || (val.Type == client.NodeInit && val.Status == client.ConditionTrue) {
fmt.Printf("节点 %s 初始化成功", hostNode.ID)
fmt.Println()
header = append(header, string(val.Type))
content = append(content, string(val.Status))
tableC.AddHeaders(header)
tableC.AddRow(content)
fmt.Println(tableC.Render())
return nil
} else if val.Type == client.NodeInit && val.Status == client.ConditionFalse {
fmt.Printf("节点 %s 初始化失败:%s", hostNode.ID, val.Reason)
return nil
} else {
fmt.Printf("..")
}
}
}
}
// var hostNode *client.HostNode
// timer := time.NewTimer(15 * time.Second)
// gotNode := false
// for !gotNode {
// time.Sleep(3 * time.Second)
// list, err := clients.RegionClient.Nodes().List()
// handleErr(err)
// for _, v := range list {
// if node.InternalIP == v.InternalIP {
// hostNode = v
// timer.Stop()
// gotNode = true
// //todo 初始化其它节点失败判定
// }
// }
// }
// fmt.Println("添加节点成功,正在初始化")
// tableC := termtables.CreateTable()
// var header []string
// var content []string
// for {
// time.Sleep(3 * time.Second)
// list, err := clients.RegionClient.Nodes().List()
// handleErr(err)
// select {
// case <-timer.C:
// fmt.Println("添加节点超时请检查etcd")
// return nil
// default:
// for _, v := range list {
// if node.InternalIP == v.InternalIP {
// hostNode = v
// break
// }
// }
// for _, val := range hostNode.NodeStatus.Conditions {
// fmt.Println("正在判断节点状态,请稍等")
// if hostNode.Alived || (val.Type == client.NodeInit && val.Status == client.ConditionTrue) {
// fmt.Printf("节点 %s 初始化成功", hostNode.ID)
// fmt.Println()
// header = append(header, string(val.Type))
// content = append(content, string(val.Status))
// tableC.AddHeaders(header)
// tableC.AddRow(content)
// fmt.Println(tableC.Render())
// return nil
// } else if val.Type == client.NodeInit && val.Status == client.ConditionFalse {
// fmt.Printf("节点 %s 初始化失败:%s", hostNode.ID, val.Reason)
// return nil
// } else {
// fmt.Printf("..")
// }
// }
// }
// }
fmt.Println("节点初始化结束")
// fmt.Println("节点初始化结束")
return nil
}
return errors.New("role must not null")
},
},
@ -424,61 +413,6 @@ func NewCmdNode() cli.Command {
return c
}
//NewCmdCluster cmd for cluster
func NewCmdCluster() cli.Command {
c := cli.Command{
Name: "cluster",
Usage: "获取集群信息 grctl cluster",
Action: func(c *cli.Context) error {
Common(c)
return getClusterInfo(c)
},
}
return c
}
func getClusterInfo(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 isNodeReady(node *client.HostNode) bool {
if node.NodeStatus == nil {
return false
@ -493,33 +427,3 @@ func isNodeReady(node *client.HostNode) bool {
return false
}
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
}

View File

@ -22,6 +22,7 @@ import (
"encoding/json"
"fmt"
"time"
"github.com/apcera/termtables"
"github.com/goodrain/rainbond/grctl/clients"
"github.com/goodrain/rainbond/node/api/model"
@ -35,16 +36,6 @@ func NewCmdTasks() cli.Command {
Name: "tasks",
Usage: "系统任务相关命令grctl tasks -h",
Subcommands: []cli.Command{
cli.Command{
Name: "static-refresh",
Usage: "Refresh static task config",
Action: func(c *cli.Context) error {
if err := clients.NodeClient.Tasks().Refresh(); err != nil {
return err
}
return nil
},
},
cli.Command{
Name: "list",
Usage: "List all task",
@ -55,7 +46,7 @@ func NewCmdTasks() cli.Command {
},
},
Action: func(c *cli.Context) error {
tasks, err := clients.NodeClient.Tasks().List()
tasks, err := clients.RegionClient.Tasks().List()
if err != nil {
return err
}
@ -126,7 +117,7 @@ func NewCmdTasks() cli.Command {
if taskID == "" {
fmt.Println("Please specified task id")
}
task, err := clients.NodeClient.Tasks().Get(taskID)
task, err := clients.RegionClient.Tasks().Get(taskID)
if err != nil {
return fmt.Errorf("get task error,%s", err.Error())
}
@ -158,7 +149,7 @@ func NewCmdTasks() cli.Command {
fmt.Println("Please specified nodeid use `-n`")
}
//fmt.Printf("node is %s task id is %s",nodeID,taskID)
err := clients.NodeClient.Tasks().Exec(taskID, []string{nodeID})
err := clients.RegionClient.Tasks().Exec(taskID, []string{nodeID})
handleErr(err)
return nil
},
@ -178,7 +169,7 @@ func getDependTask(task *model.Task, path string) {
for k, v := range depends {
tid := v.DependTaskID
taskD, err := clients.NodeClient.Tasks().Get(tid)
taskD, err := clients.RegionClient.Tasks().Get(tid)
handleErr(err)
//fmt.Print("task %s depend %s",task.ID,taskD.Task.ID)
if k == 0 {

View File

@ -333,8 +333,8 @@ func DiskUsage(path string) (disk DiskStatus) {
return
}
//RegionRes RegionRes
func RegionRes(w http.ResponseWriter, r *http.Request) {
//ClusterInfo ClusterInfo
func ClusterInfo(w http.ResponseWriter, r *http.Request) {
usedNodeList := make([]string, 0, 10)
nodes, err := kubecli.GetNodes()
if err != nil {
@ -365,99 +365,25 @@ func RegionRes(w http.ResponseWriter, r *http.Request) {
}
disk := DiskUsage("/grdata")
podMemRequestMB := memR / 1024 / 1024
result := new(model.ClusterResource)
result.CapCpu = int(capCPU)
result.CapMem = int(capMem) / 1024 / 1024
result.ReqCpu = float32(cpuR) / 1000
result.ReqMem = int(podMemRequestMB)
result.Node = len(nodes)
result.Tenant = 0
result.CapDisk = disk.All
result.ReqDisk = disk.Used
result := &model.ClusterResource{
CapCPU: int(capCPU),
CapMem: int(capMem) / 1024 / 1024,
ReqCPU: float32(cpuR) / 1000,
ReqMem: int(podMemRequestMB),
ComputeNode: len(nodes),
CapDisk: disk.All,
ReqDisk: disk.Used,
}
allnodes, _ := nodeService.GetAllNode()
result.AllNode = len(allnodes)
for _, n := range allnodes {
if n.Status != "running" {
result.NotReadyNode++
}
}
api.ReturnSuccess(r, w, result)
}
// func AddNode(w http.ResponseWriter, r *http.Request) {
// // swagger:operation PUT /v2/node/{node} v2 AddNode
// //
// // 重新上线计算节点
// //
// // add node
// //
// // ---
// // produces:
// // - application/json
// // parameters:
// // - name: name
// // in: path
// // description: nodeuid
// // required: true
// // type: string
// // format: string
// //
// // Responses:
// // '200':
// // description: '{"ok":true}'
// nodeUID := strings.TrimSpace(chi.URLParam(r, "node"))
// //k8snode,err:=core.GetNodeByName(nodeName) //maybe bug fixed
// node, err := k8s.GetSource(conf.Config.K8SNode + nodeUID)
// if err != nil {
// outRespDetails(w, http.StatusBadRequest, "error get node from etcd ", "etcd获取节点信息失败", nil, nil)
// return
// }
// if node.Status == "offline" && node.Role.HasRule("tree") {
// _, err := k8s.K8S.Core().Nodes().Get(node.HostName, metav1.GetOptions{})
// if err != nil {
// if apierrors.IsNotFound(err) {
// logrus.Info("create node to kubernetes")
// newk8sNode, err := k8s.CreateK8sNode(node)
// if err != nil {
// outRespDetails(w, 500, "create node failed "+err.Error(), "解析创建node失败", nil, nil)
// return
// }
// realK8SNode, err := k8s.K8S.Core().Nodes().Create(newk8sNode)
// logrus.Infof("重新上线后node uid为 %s ,下线之前node uid 为 %s ", string(realK8SNode.UID), nodeUID)
// if err != nil {
// if !apierrors.IsAlreadyExists(err) {
// node.Status = "running"
// }
// outRespDetails(w, 500, "create node failed "+err.Error(), "创建k8s节点失败", nil, nil)
// return
// }
// logrus.Debugf("reup node %s (old),creating core node ", nodeUID)
// hostNode, err := k8s.GetSource(conf.Config.K8SNode + string(nodeUID))
// if err != nil {
// outRespDetails(w, 500, "get node resource failed "+err.Error(), "etcd获取node资源失败", nil, nil)
// return
// }
// hostNode.ID = string(realK8SNode.UID)
// hostNode.Status = "running"
// //更改状态
// data, _ := json.Marshal(hostNode)
// logrus.Infof("adding node :%s online ,updated to %s ", string(realK8SNode.UID), string(data))
// err = k8s.AddSource(conf.Config.K8SNode+hostNode.ID, hostNode)
// if err != nil {
// outRespDetails(w, 500, "add new node failed "+err.Error(), "添加新node信息失败", nil, nil)
// return
// }
// err = k8s.DeleteSource(conf.Config.K8SNode + nodeUID)
// if err != nil {
// outRespDetails(w, 500, "delete old node failed "+err.Error(), "删除老node信息失败", nil, nil)
// return
// }
// logrus.Infof("adding node :%s online ,updated to %s ", string(realK8SNode.UID), string(data))
// }
// }
// }
// outRespSuccess(w, nil, nil)
// }
func outSuccess(w http.ResponseWriter) {
s := `{"ok":true}`
w.WriteHeader(200)

View File

@ -180,16 +180,18 @@ func DoRequest(baseAPI, query, queryType, method string, body []byte) ([]byte, i
return data, resp.StatusCode, nil
}
//Resource 资源
//ClusterResource 资源
type ClusterResource struct {
Node int `json:"node"`
Tenant int `json:"tenant"`
CapCpu int `json:"cap_cpu"`
CapMem int `json:"cap_mem"`
ReqCpu float32 `json:"req_cpu"`
ReqMem int `json:"req_mem"`
CapDisk uint64 `json:"cap_disk"`
ReqDisk uint64 `json:"req_disk"`
AllNode int `json:"all_node"`
NotReadyNode int `json:"notready_node"`
ComputeNode int `json:"compute_node"`
Tenant int `json:"tenant"`
CapCPU int `json:"cap_cpu"`
CapMem int `json:"cap_mem"`
ReqCPU float32 `json:"req_cpu"`
ReqMem int `json:"req_mem"`
CapDisk uint64 `json:"cap_disk"`
ReqDisk uint64 `json:"req_disk"`
}
type FirstConfig struct {

View File

@ -53,8 +53,11 @@ func Routers(mode string) *chi.Mux {
r.Get("/datacenter", controller.GetDatacenterConfig)
r.Put("/datacenter", controller.PutDatacenterConfig)
})
r.Route("/cluster", func(r chi.Router) {
r.Get("/", controller.ClusterInfo)
})
r.Route("/nodes", func(r chi.Router) {
r.Get("/fullres", controller.RegionRes)
r.Get("/fullres", controller.ClusterInfo)
r.Get("/resources", controller.Resources)
r.Get("/capres", controller.CapRes)
r.Get("/", controller.GetNodes)

View File

@ -95,9 +95,9 @@ func (n *NodeManager) Start(errchan chan error) error {
if err := n.init(); err != nil {
return err
}
if err := n.controller.Start(); err != nil {
return fmt.Errorf("start node controller error,%s", err.Error())
}
if err := n.controller.Start(); err != nil {
return fmt.Errorf("start node controller error,%s", err.Error())
}
// services, err := n.controller.GetAllService()
// if err != nil {
// return fmt.Errorf("get all services error,%s", err.Error())

View File

@ -20,6 +20,7 @@ package taskrun
import (
"context"
"fmt"
"sync"
"github.com/Sirupsen/logrus"
@ -48,7 +49,7 @@ type manager struct {
*cron.Cron
ctx context.Context
cancel context.CancelFunc
Conf option.Conf
Conf *option.Conf
jobs Jobs // 和结点相关的任务
onceJobs Jobs //记录执行的单任务
jobLock sync.Mutex
@ -76,6 +77,7 @@ func (n *manager) watchJobs(errChan chan error) error {
switch event.Type {
case watch.Added:
j := new(job.Job)
//fmt.Println(string(event.GetValue()))
err := j.Decode(event.GetValue())
if err != nil {
logrus.Errorf("decode job error :%s", err)
@ -84,6 +86,7 @@ func (n *manager) watchJobs(errChan chan error) error {
n.addJob(j)
case watch.Modified:
j := new(job.Job)
fmt.Println(string(event.GetValue()))
err := j.Decode(event.GetValue())
if err != nil {
logrus.Errorf("decode job error :%s", err)
@ -229,6 +232,7 @@ func Newmanager(cfg *option.Conf, etcdCli *clientv3.Client) (Manager, error) {
delIDs: make(map[string]bool, 8),
ttl: cfg.TTL,
etcdcli: etcdCli,
Conf: cfg,
}
return n, nil
}