Rainbond/api/region/region.go

314 lines
9.2 KiB
Go
Raw Normal View History

2018-03-14 14:12:26 +08:00
// Copyright (C) 2014-2018 Goodrain Co., Ltd.
2017-11-10 11:53:05 +08:00
// RAINBOND, Application Management Platform
2018-03-14 14:33:31 +08:00
2017-11-10 11:53:05 +08:00
// 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.
2018-03-14 14:33:31 +08:00
2017-11-10 11:53:05 +08:00
// 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.
2018-03-14 14:33:31 +08:00
2017-11-10 11:53:05 +08:00
// 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 region
import (
2017-11-22 15:09:28 +08:00
"bytes"
"encoding/json"
"errors"
2017-12-25 19:49:32 +08:00
"fmt"
"io/ioutil"
2017-11-22 15:09:28 +08:00
"net/http"
"path"
2017-11-22 15:09:28 +08:00
2017-11-13 10:26:03 +08:00
"github.com/bitly/go-simplejson"
"github.com/goodrain/rainbond/api/model"
api_model "github.com/goodrain/rainbond/api/model"
"github.com/goodrain/rainbond/api/util"
dbmodel "github.com/goodrain/rainbond/db/model"
utilhttp "github.com/goodrain/rainbond/util/http"
"github.com/pquerna/ffjson/ffjson"
)
var regionAPI, token string
var region *Region
type Region struct {
regionAPI string
2017-11-22 15:09:28 +08:00
token string
authType string
}
2017-11-22 15:09:28 +08:00
func (r *Region) Tenants() TenantInterface {
2017-12-25 19:49:32 +08:00
return &tenant{prefix: "/tenants"}
}
type tenant struct {
tenantID string
2017-12-25 19:49:32 +08:00
prefix string
}
type services struct {
tenant *tenant
prefix string
2017-11-22 15:09:28 +08:00
model model.ServiceStruct
}
2017-11-22 15:09:28 +08:00
//TenantInterface TenantInterface
type TenantInterface interface {
2017-12-25 19:49:32 +08:00
Get(name string) *tenant
Services() ServiceInterface
2017-11-22 15:09:28 +08:00
DefineSources(ss *api_model.SourceSpec) DefineSourcesInterface
2017-12-08 17:14:12 +08:00
DefineCloudAuth(gt *api_model.GetUserToken) DefineCloudAuthInterface
}
2017-11-22 15:09:28 +08:00
func (t *tenant) Get(name string) *tenant {
2017-12-25 19:49:32 +08:00
t.tenantID = name
return t
}
func (t *tenant) Delete(name string) error {
return nil
}
func (t *tenant) Services() ServiceInterface {
return &services{
2017-12-25 19:49:32 +08:00
prefix: "services",
2017-11-22 15:09:28 +08:00
tenant: t,
}
}
2017-12-08 17:14:12 +08:00
//ServiceInterface ServiceInterface
type ServiceInterface interface {
2017-12-25 19:49:32 +08:00
Get(name string) (map[string]string, *util.APIHandleError)
Pods(serviceAlisa string) ([]*dbmodel.K8sPod, *util.APIHandleError)
List() ([]*model.ServiceStruct, *util.APIHandleError)
Stop(serviceAlisa, eventID string) *util.APIHandleError
Start(serviceAlisa, eventID string) *util.APIHandleError
EventLog(serviceAlisa, eventID, level string) ([]*model.MessageData, *util.APIHandleError)
}
func (s *services) Pods(serviceAlisa string) ([]*dbmodel.K8sPod, *util.APIHandleError) {
body, code, err := request("/v2"+s.tenant.prefix+"/"+s.tenant.tenantID+"/"+s.prefix+"/"+serviceAlisa+"/pods", "GET", nil)
if err != nil {
2017-12-25 19:49:32 +08:00
return nil, util.CreateAPIHandleError(code, err)
}
if code != 200 {
2017-12-25 19:49:32 +08:00
return nil, util.CreateAPIHandleError(code, fmt.Errorf("Get database center configs code %d", code))
}
var res utilhttp.ResponseBody
var gc []*dbmodel.K8sPod
res.List = &gc
if err := ffjson.Unmarshal(body, &res); err != nil {
2017-12-25 19:49:32 +08:00
return nil, util.CreateAPIHandleError(code, err)
}
if gc, ok := res.List.(*[]*dbmodel.K8sPod); ok {
return *gc, nil
}
return nil, nil
}
2017-12-25 19:49:32 +08:00
func (s *services) Get(name string) (map[string]string, *util.APIHandleError) {
body, code, err := request("/v2"+s.tenant.prefix+"/"+s.tenant.tenantID+"/"+s.prefix+"/"+name, "GET", nil)
2017-11-10 17:18:57 +08:00
if err != nil {
2017-12-25 19:49:32 +08:00
return nil, util.CreateAPIHandleError(code, err)
2017-11-10 17:18:57 +08:00
}
if code != 200 {
2017-12-25 19:49:32 +08:00
return nil, util.CreateAPIHandleError(code, fmt.Errorf("Get err with code %d", code))
}
j, err := simplejson.NewJson(body)
if err != nil {
2017-12-25 19:49:32 +08:00
return nil, util.CreateAPIHandleError(code, err)
}
2017-11-22 15:09:28 +08:00
m := make(map[string]string)
bean := j.Get("bean")
sa, err := bean.Get("serviceAlias").String()
si, err := bean.Get("serviceId").String()
ti, err := bean.Get("tenantId").String()
tn, err := bean.Get("tenantName").String()
m["serviceAlias"] = sa
m["serviceId"] = si
m["tenantId"] = ti
m["tenantName"] = tn
2017-12-25 19:49:32 +08:00
return m, nil
2017-11-10 17:18:57 +08:00
}
func (s *services) EventLog(serviceAlisa, eventID, level string) ([]*model.MessageData, *util.APIHandleError) {
2017-11-22 15:09:28 +08:00
data := []byte(`{"event_id":"` + eventID + `","level":"` + level + `"}`)
body, code, err := request("/v2"+s.tenant.prefix+"/"+s.tenant.tenantID+"/"+s.prefix+"/event-log", "POST", data)
2017-11-22 15:09:28 +08:00
if err != nil {
2017-12-25 19:49:32 +08:00
return nil, util.CreateAPIHandleError(code, err)
2017-11-10 17:18:57 +08:00
}
if code != 200 {
2017-12-25 19:49:32 +08:00
return nil, util.CreateAPIHandleError(code, fmt.Errorf("Get database center configs code %d", code))
}
var res utilhttp.ResponseBody
var gc []*model.MessageData
res.List = &gc
if err := ffjson.Unmarshal(body, &res); err != nil {
2017-12-25 19:49:32 +08:00
return nil, util.CreateAPIHandleError(code, err)
}
if gc, ok := res.List.(*[]*model.MessageData); ok {
return *gc, nil
}
return nil, nil
}
2017-12-25 19:49:32 +08:00
func (s *services) List() ([]*model.ServiceStruct, *util.APIHandleError) {
body, code, err := request("/v2"+s.tenant.prefix+"/"+s.tenant.tenantID+"/"+s.prefix, "GET", nil)
2017-11-22 15:09:28 +08:00
if err != nil {
2017-12-25 19:49:32 +08:00
return nil, util.CreateAPIHandleError(code, err)
}
if code != 200 {
2017-12-25 19:49:32 +08:00
return nil, util.CreateAPIHandleError(code, fmt.Errorf("Get with code %d", code))
}
var res utilhttp.ResponseBody
var gc []*model.ServiceStruct
res.List = &gc
if err := ffjson.Unmarshal(body, &res); err != nil {
2017-12-25 19:49:32 +08:00
return nil, util.CreateAPIHandleError(code, err)
}
if gc, ok := res.List.(*[]*model.ServiceStruct); ok {
return *gc, nil
}
return nil, nil
}
func (s *services) Stop(name, eventID string) *util.APIHandleError {
data := []byte(`{"event_id":"` + eventID + `"}`)
_, code, err := request("/v2"+s.tenant.prefix+"/"+s.tenant.tenantID+"/"+s.prefix+"/"+name+"/stop", "POST", data)
2017-12-25 19:49:32 +08:00
return handleErrAndCode(err, code)
2017-11-09 18:19:17 +08:00
}
func (s *services) Start(name, eventID string) *util.APIHandleError {
2017-11-09 18:19:17 +08:00
data := []byte(`{"event_id":"` + eventID + `"}`)
_, code, err := request("/v2"+s.tenant.prefix+"/"+s.tenant.tenantID+"/"+s.prefix+"/"+name+"/start", "POST", data)
2017-12-25 19:49:32 +08:00
return handleErrAndCode(err, code)
}
func request(url, method string, body []byte) ([]byte, int, error) {
2017-11-13 10:26:03 +08:00
request, err := http.NewRequest(method, region.regionAPI+url, bytes.NewBuffer(body))
if err != nil {
2017-11-22 15:09:28 +08:00
return nil, 500, err
}
request.Header.Set("Content-Type", "application/json")
2017-11-13 10:26:03 +08:00
if region.token != "" {
request.Header.Set("Authorization", "Token "+region.token)
}
res, err := http.DefaultClient.Do(request)
if err != nil {
2017-11-22 15:09:28 +08:00
return nil, 500, err
}
data, err := ioutil.ReadAll(res.Body)
defer res.Body.Close()
2017-11-22 15:09:28 +08:00
return data, res.StatusCode, err
}
2017-11-22 15:09:28 +08:00
func NewRegion(regionAPI, token, authType string) *Region {
if region == nil {
region = &Region{
regionAPI: regionAPI,
token: token,
authType: authType,
}
}
return region
}
func GetRegion() *Region {
return region
}
func LoadConfig(regionAPI, token string) (map[string]map[string]interface{}, error) {
if regionAPI != "" {
//return nil, errors.New("region api url can not be empty")
//return nil, errors.New("region api url can not be empty")
//todo
request, err := http.NewRequest("GET", regionAPI+"/v1/config", nil)
if err != nil {
return nil, err
}
request.Header.Set("Content-Type", "application/json")
if token != "" {
request.Header.Set("Authorization", "Token "+token)
}
res, err := http.DefaultClient.Do(request)
if err != nil {
return nil, err
}
defer res.Body.Close()
data, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
config := make(map[string]map[string]interface{})
if err := json.Unmarshal([]byte(data), &config); err != nil {
return nil, err
}
//{"k8s":{"url":"http://10.0.55.72:8181/api/v1","apitype":"kubernetes api"},
// "db":{"ENGINE":"django.db.backends.mysql",
// "AUTOCOMMIT":true,"ATOMIC_REQUESTS":false,"NAME":"region","CONN_MAX_AGE":0,
//"TIME_ZONE":"Asia/Shanghai","OPTIONS":{},
// "HOST":"10.0.55.72","USER":"writer1",
// "TEST":{"COLLATION":null,"CHARSET":null,"NAME":null,"MIRROR":null},
// "PASSWORD":"CeRYK8UzWD","PORT":"3306"}}
return config, nil
}
return nil, errors.New("wrong region api ")
}
//SetInfo 设置
func SetInfo(region, t string) {
regionAPI = region
token = t
}
2017-12-25 19:49:32 +08:00
func handleErrAndCode(err error, code int) *util.APIHandleError {
if err != nil {
2017-12-25 19:49:32 +08:00
return util.CreateAPIHandleError(code, err)
}
if code != 200 {
2017-12-25 19:49:32 +08:00
return util.CreateAPIHandleError(code, fmt.Errorf("error with code %d", code))
}
return nil
2017-12-25 19:49:32 +08:00
}
//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
}