You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cronsun/web/node.go

135 lines
3.0 KiB

8 years ago
package web
import (
"encoding/json"
"fmt"
"net/http"
"path"
"sort"
"strings"
"github.com/coreos/etcd/clientv3"
"github.com/gorilla/mux"
"sunteng/commons/log"
"sunteng/cronsun/conf"
"sunteng/cronsun/models"
)
type Node struct{}
var ngKeyDeepLen = len(conf.Config.Group)
func (n *Node) GetGroups(w http.ResponseWriter, r *http.Request) {
resp, err := models.DefalutClient.Get(conf.Config.Group, clientv3.WithPrefix(), clientv3.WithKeysOnly())
if err != nil {
outJSONError(w, http.StatusInternalServerError, err.Error())
return
}
var groupMap = make(map[string]bool, 8)
for i := range resp.Kvs {
ss := strings.Split(string(resp.Kvs[i].Key), "/")
groupMap[ss[ngKeyDeepLen]] = true
}
var groupList = make([]string, 0, len(groupMap))
for k := range groupMap {
groupList = append(groupList, k)
}
sort.Strings(groupList)
outJSON(w, groupList)
}
func (n *Node) GetGroupByGroupName(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
resp, err := models.DefalutClient.Get(path.Join(conf.Config.Group, vars["name"]), clientv3.WithPrefix(), clientv3.WithSort(clientv3.SortByKey, clientv3.SortAscend))
if err != nil {
outJSONError(w, http.StatusInternalServerError, err.Error())
return
}
var nodeList = make([]*models.Node, 0, resp.Count)
for i := range resp.Kvs {
node := &models.Node{}
err = json.Unmarshal(resp.Kvs[i].Value, &node)
if err != nil {
outJSONError(w, http.StatusInternalServerError, err.Error())
return
}
nodeList = append(nodeList)
}
outJSON(w, nodeList)
}
func (n *Node) JoinGroup(w http.ResponseWriter, r *http.Request) {
ng := []struct {
Nodes []string
Group string
}{}
de := json.NewDecoder(r.Body)
err := de.Decode(&ng)
if err != nil {
outJSONError(w, http.StatusBadRequest, err.Error())
return
}
gresp, err := models.DefalutClient.Get(conf.Config.Proc, clientv3.WithPrefix(), clientv3.WithKeysOnly())
if err != nil {
log.Errorf("get nodes list failed: %s", err.Error())
outJSONError(w, http.StatusInternalServerError, err.Error())
return
}
var nodes map[string]bool
for i := range gresp.Kvs {
ip := strings.TrimLeft(string(gresp.Kvs[i].Key), conf.Config.Proc)
nodes[ip] = true
}
var errMsg string
var status int
NGLOOP:
for i := range ng {
g := strings.TrimSpace(ng[i].Group)
if len(g) == 0 {
errMsg = "group name is emtpy."
status = http.StatusBadRequest
break
}
for _, n := range ng[i].Nodes {
n = strings.TrimSpace(n)
if len(n) == 0 {
errMsg = fmt.Sprintf("[%s] node ip is emtpy.", g)
status = http.StatusBadRequest
break NGLOOP
}
if _, ok := nodes[n]; !ok {
errMsg = fmt.Sprintf("node[%s] not found.", n)
status = http.StatusBadRequest
break NGLOOP
}
_, err = models.DefalutClient.Put(path.Join(conf.Config.Group, g, n), "")
if err != nil {
errMsg = "join failed: " + err.Error()
status = http.StatusInternalServerError
break NGLOOP
}
}
}
if len(errMsg) > 0 {
outJSONError(w, status, errMsg)
return
}
outJSON(w, nil)
}
func (n *Node) LeaveGroup(w http.ResponseWriter, r *http.Request) {}