Rainbond/api/controller/service_action.go

734 lines
22 KiB
Go
Raw Normal View History

2018-03-14 14:12:26 +08:00
// Copyright (C) 2014-2018 Goodrain Co., Ltd.
2017-11-07 11:40:44 +08:00
// RAINBOND, Application Management Platform
2018-03-14 14:33:31 +08:00
2017-11-07 11:40:44 +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-07 11:40:44 +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-07 11:40:44 +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 controller
import (
"fmt"
"io/ioutil"
"net/http"
2018-08-03 15:17:10 +08:00
"os"
2019-06-29 20:02:41 +08:00
validator "github.com/thedevsaddam/govalidator"
"github.com/Sirupsen/logrus"
2018-08-03 15:17:10 +08:00
"github.com/go-chi/chi"
"github.com/goodrain/rainbond/api/handler"
"github.com/goodrain/rainbond/api/middleware"
api_model "github.com/goodrain/rainbond/api/model"
"github.com/goodrain/rainbond/db"
dbmodel "github.com/goodrain/rainbond/db/model"
"github.com/goodrain/rainbond/event"
httputil "github.com/goodrain/rainbond/util/http"
"github.com/goodrain/rainbond/worker/discover/model"
2018-06-21 14:30:23 +08:00
"github.com/jinzhu/gorm"
2018-10-23 18:11:27 +08:00
"github.com/pquerna/ffjson/ffjson"
2017-11-07 11:40:44 +08:00
)
//StartService StartService
// swagger:operation POST /v2/tenants/{tenant_name}/services/{service_alias}/start v2 startService
//
// 启动应用
//
2017-11-27 18:01:04 +08:00
// start service
//
// ---
// consumes:
// - application/json
// - application/x-protobuf
//
// produces:
// - application/json
// - application/xml
//
// responses:
// default:
// schema:
// "$ref": "#/responses/commandResponse"
// description: 统一返回格式
2017-11-07 11:40:44 +08:00
func (t *TenantStruct) StartService(w http.ResponseWriter, r *http.Request) {
tenantID := r.Context().Value(middleware.ContextKey("tenant_id")).(string)
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
tenant := r.Context().Value(middleware.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(middleware.ContextKey("service")).(*dbmodel.TenantServices)
if err := handler.CheckTenantResource(tenant, service.Replicas*service.ContainerMemory); err != nil {
httputil.ReturnResNotEnough(r, w, err.Error())
return
}
2019-08-22 16:07:26 +08:00
sEvent := r.Context().Value(middleware.ContextKey("event")).(*dbmodel.ServiceEvent)
2017-11-07 11:40:44 +08:00
startStopStruct := &api_model.StartStopStruct{
TenantID: tenantID,
ServiceID: serviceID,
2019-08-22 16:07:26 +08:00
EventID: sEvent.EventID,
2017-11-07 11:40:44 +08:00
TaskType: "start",
}
if err := handler.GetServiceManager().StartStopService(startStopStruct); err != nil {
httputil.ReturnError(r, w, 500, "get service info error.")
return
}
httputil.ReturnSuccess(r, w, sEvent)
2017-11-07 11:40:44 +08:00
return
}
//StopService StopService
// swagger:operation POST /v2/tenants/{tenant_name}/services/{service_alias}/stop v2 stopService
//
// 关闭应用
//
2017-11-27 18:01:04 +08:00
// stop service
//
// ---
// consumes:
// - application/json
// - application/x-protobuf
//
// produces:
// - application/json
// - application/xml
//
// responses:
// default:
// schema:
// "$ref": "#/responses/commandResponse"
// description: 统一返回格式
2017-11-07 11:40:44 +08:00
func (t *TenantStruct) StopService(w http.ResponseWriter, r *http.Request) {
tenantID := r.Context().Value(middleware.ContextKey("tenant_id")).(string)
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
2019-08-22 16:07:26 +08:00
sEvent := r.Context().Value(middleware.ContextKey("event")).(*dbmodel.ServiceEvent)
//save event
2017-11-07 11:40:44 +08:00
defer event.CloseManager()
startStopStruct := &api_model.StartStopStruct{
TenantID: tenantID,
ServiceID: serviceID,
2019-08-22 16:07:26 +08:00
EventID: sEvent.EventID,
2017-11-07 11:40:44 +08:00
TaskType: "stop",
}
if err := handler.GetServiceManager().StartStopService(startStopStruct); err != nil {
httputil.ReturnError(r, w, 500, "get service info error.")
return
}
httputil.ReturnSuccess(r, w, sEvent)
2017-11-07 11:40:44 +08:00
}
//RestartService RestartService
// swagger:operation POST /v2/tenants/{tenant_name}/services/{service_alias}/restart v2 restartService
//
// 重启应用
//
2017-11-27 18:01:04 +08:00
// restart service
//
// ---
// consumes:
// - application/json
// - application/x-protobuf
//
// produces:
// - application/json
// - application/xml
//
// responses:
// default:
// schema:
// "$ref": "#/responses/commandResponse"
// description: 统一返回格式
2017-11-07 11:40:44 +08:00
func (t *TenantStruct) RestartService(w http.ResponseWriter, r *http.Request) {
tenantID := r.Context().Value(middleware.ContextKey("tenant_id")).(string)
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
2019-08-22 16:07:26 +08:00
sEvent := r.Context().Value(middleware.ContextKey("event")).(*dbmodel.ServiceEvent)
2017-11-07 11:40:44 +08:00
defer event.CloseManager()
startStopStruct := &api_model.StartStopStruct{
TenantID: tenantID,
ServiceID: serviceID,
2019-08-22 16:07:26 +08:00
EventID: sEvent.EventID,
2017-11-07 11:40:44 +08:00
TaskType: "restart",
}
curStatus := t.StatusCli.GetStatus(serviceID)
if curStatus == "closed" {
startStopStruct.TaskType = "start"
}
tenant := r.Context().Value(middleware.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(middleware.ContextKey("service")).(*dbmodel.TenantServices)
if err := handler.CheckTenantResource(tenant, service.Replicas*service.ContainerMemory); err != nil {
httputil.ReturnResNotEnough(r, w, err.Error())
return
}
2017-11-07 11:40:44 +08:00
if err := handler.GetServiceManager().StartStopService(startStopStruct); err != nil {
httputil.ReturnError(r, w, 500, "get service info error.")
return
}
httputil.ReturnSuccess(r, w, sEvent)
2017-11-07 11:40:44 +08:00
return
}
//VerticalService VerticalService
// swagger:operation PUT /v2/tenants/{tenant_name}/services/{service_alias}/vertical v2 verticalService
//
// 应用垂直伸缩
//
2017-11-27 18:01:04 +08:00
// service vertical
//
// ---
// consumes:
// - application/json
// - application/x-protobuf
//
// produces:
// - application/json
// - application/xml
//
// responses:
// default:
// schema:
// "$ref": "#/responses/commandResponse"
// description: 统一返回格式
2017-11-07 11:40:44 +08:00
func (t *TenantStruct) VerticalService(w http.ResponseWriter, r *http.Request) {
rules := validator.MapData{
"container_cpu": []string{"required"},
"container_memory": []string{"required"},
}
data, ok := httputil.ValidatorRequestMapAndErrorResponse(r, w, rules, nil)
if !ok {
return
}
tenantID := r.Context().Value(middleware.ContextKey("tenant_id")).(string)
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
2019-08-22 16:07:26 +08:00
sEvent := r.Context().Value(middleware.ContextKey("event")).(*dbmodel.ServiceEvent)
2017-11-07 11:40:44 +08:00
cpu := int(data["container_cpu"].(float64))
mem := int(data["container_memory"].(float64))
tenant := r.Context().Value(middleware.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(middleware.ContextKey("service")).(*dbmodel.TenantServices)
if err := handler.CheckTenantResource(tenant, service.Replicas*mem); err != nil {
httputil.ReturnResNotEnough(r, w, err.Error())
return
}
2017-11-07 11:40:44 +08:00
verticalTask := &model.VerticalScalingTaskBody{
TenantID: tenantID,
ServiceID: serviceID,
2019-08-22 16:07:26 +08:00
EventID: sEvent.EventID,
2017-11-07 11:40:44 +08:00
ContainerCPU: cpu,
ContainerMemory: mem,
}
if err := handler.GetServiceManager().ServiceVertical(verticalTask); err != nil {
httputil.ReturnError(r, w, 500, fmt.Sprintf("service vertical error. %v", err))
return
}
httputil.ReturnSuccess(r, w, sEvent)
2017-11-07 11:40:44 +08:00
}
//HorizontalService HorizontalService
// swagger:operation PUT /v2/tenants/{tenant_name}/services/{service_alias}/horizontal v2 horizontalService
//
// 应用水平伸缩
//
2017-11-27 18:01:04 +08:00
// service horizontal
//
// ---
// consumes:
// - application/json
// - application/x-protobuf
//
// produces:
// - application/json
// - application/xml
//
// responses:
// default:
// schema:
// "$ref": "#/responses/commandResponse"
// description: 统一返回格式
2017-11-07 11:40:44 +08:00
func (t *TenantStruct) HorizontalService(w http.ResponseWriter, r *http.Request) {
rules := validator.MapData{
"node_num": []string{"required"},
}
data, ok := httputil.ValidatorRequestMapAndErrorResponse(r, w, rules, nil)
if !ok {
return
}
tenantID := r.Context().Value(middleware.ContextKey("tenant_id")).(string)
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
2019-08-22 16:07:26 +08:00
sEvent := r.Context().Value(middleware.ContextKey("event")).(*dbmodel.ServiceEvent)
2017-11-07 11:40:44 +08:00
replicas := int32(data["node_num"].(float64))
tenant := r.Context().Value(middleware.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(middleware.ContextKey("service")).(*dbmodel.TenantServices)
if err := handler.CheckTenantResource(tenant, service.ContainerMemory*int(replicas)); err != nil {
httputil.ReturnResNotEnough(r, w, err.Error())
return
}
2017-11-07 11:40:44 +08:00
horizontalTask := &model.HorizontalScalingTaskBody{
TenantID: tenantID,
ServiceID: serviceID,
2019-08-22 16:07:26 +08:00
EventID: sEvent.EventID,
2017-11-07 11:40:44 +08:00
Replicas: replicas,
}
2017-11-07 11:40:44 +08:00
if err := handler.GetServiceManager().ServiceHorizontal(horizontalTask); err != nil {
httputil.ReturnError(r, w, 500, fmt.Sprintf("service horizontal error. %v", err))
return
}
httputil.ReturnSuccess(r, w, sEvent)
2017-11-07 11:40:44 +08:00
}
//BuildService BuildService
// swagger:operation POST /v2/tenants/{tenant_name}/services/{service_alias}/build v2 serviceBuild
//
// 应用构建
//
2017-11-27 18:01:04 +08:00
// service build
//
// ---
// consumes:
// - application/json
// - application/x-protobuf
//
// produces:
// - application/json
// - application/xml
//
// responses:
// default:
// schema:
// "$ref": "#/responses/commandResponse"
// description: 统一返回格式
2017-11-07 11:40:44 +08:00
func (t *TenantStruct) BuildService(w http.ResponseWriter, r *http.Request) {
2019-06-29 21:16:07 +08:00
var build api_model.BuildInfoRequestStruct
ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &build, nil)
2017-11-07 11:40:44 +08:00
if !ok {
return
}
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
tenantName := r.Context().Value(middleware.ContextKey("tenant_name")).(string)
2019-06-29 21:16:07 +08:00
build.TenantName = tenantName
2019-08-22 16:07:26 +08:00
build.EventID = r.Context().Value(middleware.ContextKey("event_id")).(string)
2019-06-29 21:16:07 +08:00
if build.ServiceID != serviceID {
httputil.ReturnError(r, w, 400, "build service id is failure")
2019-08-22 16:07:26 +08:00
return
2017-11-07 11:40:44 +08:00
}
tenant := r.Context().Value(middleware.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(middleware.ContextKey("service")).(*dbmodel.TenantServices)
if err := handler.CheckTenantResource(tenant, service.Replicas*service.ContainerMemory); err != nil {
httputil.ReturnResNotEnough(r, w, err.Error())
return
}
2019-06-29 21:16:07 +08:00
re := handler.GetOperationHandler().Build(build)
2019-08-22 16:07:26 +08:00
if re.ErrMsg != "" {
httputil.ReturnError(r, w, 500, "build server error: "+re.ErrMsg)
return
}
2019-06-29 21:16:07 +08:00
httputil.ReturnSuccess(r, w, re)
2017-11-07 11:40:44 +08:00
}
//BuildList BuildList
func (t *TenantStruct) BuildList(w http.ResponseWriter, r *http.Request) {
2018-06-21 12:01:40 +08:00
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
resp, err := handler.GetServiceManager().ListVersionInfo(serviceID)
if err != nil {
2018-06-21 12:01:40 +08:00
logrus.Error("get version info error", err.Error())
httputil.ReturnError(r, w, 500, fmt.Sprintf("get version info erro, %v", err))
return
}
httputil.ReturnSuccess(r, w, resp)
2017-11-07 11:40:44 +08:00
}
2019-03-09 13:51:36 +08:00
//BuildVersionIsExist -
2018-06-21 14:30:23 +08:00
func (t *TenantStruct) BuildVersionIsExist(w http.ResponseWriter, r *http.Request) {
statusMap := make(map[string]bool)
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
buildVersion := chi.URLParam(r, "build_version")
_, err := db.GetManager().VersionInfoDao().GetVersionByDeployVersion(buildVersion, serviceID)
2018-08-03 15:17:10 +08:00
if err != nil && err != gorm.ErrRecordNotFound {
2018-06-21 14:35:47 +08:00
httputil.ReturnError(r, w, 500, fmt.Sprintf("get build version status erro, %v", err))
return
}
2018-08-03 15:17:10 +08:00
if err == gorm.ErrRecordNotFound {
2018-06-21 14:30:23 +08:00
statusMap["status"] = false
2018-08-03 15:17:10 +08:00
} else {
2018-06-21 14:30:23 +08:00
statusMap["status"] = true
}
httputil.ReturnSuccess(r, w, statusMap)
}
2019-03-09 13:51:36 +08:00
//DeleteBuildVersion -
2018-06-21 14:30:23 +08:00
func (t *TenantStruct) DeleteBuildVersion(w http.ResponseWriter, r *http.Request) {
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
buildVersion := chi.URLParam(r, "build_version")
val, err := db.GetManager().VersionInfoDao().GetVersionByDeployVersion(buildVersion, serviceID)
if err != nil && err != gorm.ErrRecordNotFound {
httputil.ReturnError(r, w, 500, fmt.Sprintf("delete build version erro, %v", err))
return
}
if err == gorm.ErrRecordNotFound {
} else {
if val.DeliveredType == "slug" && val.FinalStatus == "success" {
if err := os.Remove(val.DeliveredPath); err != nil {
httputil.ReturnError(r, w, 500, fmt.Sprintf("delete build version erro, %v", err))
return
}
if err := db.GetManager().VersionInfoDao().DeleteVersionInfo(val); err != nil {
httputil.ReturnError(r, w, 500, fmt.Sprintf("delete build version erro, %v", err))
return
}
}
if val.FinalStatus == "failure" {
2018-06-21 14:30:23 +08:00
if err := db.GetManager().VersionInfoDao().DeleteVersionInfo(val); err != nil {
httputil.ReturnError(r, w, 500, fmt.Sprintf("delete build version erro, %v", err))
return
}
}
if val.DeliveredType == "image" {
if err := db.GetManager().VersionInfoDao().DeleteVersionInfo(val); err != nil {
httputil.ReturnError(r, w, 500, fmt.Sprintf("delete build version erro, %v", err))
return
}
}
}
httputil.ReturnSuccess(r, w, nil)
}
2019-03-09 13:51:36 +08:00
//BuildVersionInfo -
2018-06-21 14:30:23 +08:00
func (t *TenantStruct) BuildVersionInfo(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "DELETE":
t.DeleteBuildVersion(w, r)
case "GET":
t.BuildVersionIsExist(w, r)
}
}
2018-08-03 15:17:10 +08:00
//GetDeployVersion GetDeployVersion by service
func (t *TenantStruct) GetDeployVersion(w http.ResponseWriter, r *http.Request) {
service := r.Context().Value(middleware.ContextKey("service")).(*dbmodel.TenantServices)
version, err := db.GetManager().VersionInfoDao().GetVersionByDeployVersion(service.DeployVersion, service.ServiceID)
if err != nil && err != gorm.ErrRecordNotFound {
httputil.ReturnError(r, w, 500, fmt.Sprintf("get build version status erro, %v", err))
return
}
if err == gorm.ErrRecordNotFound {
httputil.ReturnError(r, w, 404, fmt.Sprintf("build version do not exist"))
return
}
httputil.ReturnSuccess(r, w, version)
}
//GetManyDeployVersion GetDeployVersion by some service id
func (t *TenantStruct) GetManyDeployVersion(w http.ResponseWriter, r *http.Request) {
rules := validator.MapData{
"service_ids": []string{"required"},
}
data, ok := httputil.ValidatorRequestMapAndErrorResponse(r, w, rules, nil)
if !ok {
return
}
serviceIDs, ok := data["service_ids"].([]interface{})
2018-08-03 15:17:10 +08:00
if !ok {
httputil.ReturnError(r, w, 400, fmt.Sprintf("service ids must be a array"))
return
}
var list []string
for _, s := range serviceIDs {
list = append(list, s.(string))
}
services, err := db.GetManager().TenantServiceDao().GetServiceByIDs(list)
2018-08-03 15:17:10 +08:00
if err != nil {
httputil.ReturnError(r, w, 500, fmt.Sprintf(err.Error()))
return
}
var versionList []*dbmodel.VersionInfo
for _, service := range services {
version, err := db.GetManager().VersionInfoDao().GetVersionByDeployVersion(service.DeployVersion, service.ServiceID)
if err != nil && err != gorm.ErrRecordNotFound {
httputil.ReturnError(r, w, 500, fmt.Sprintf("get build version status erro, %v", err))
return
}
versionList = append(versionList, version)
}
httputil.ReturnSuccess(r, w, versionList)
}
2017-11-07 11:40:44 +08:00
//DeployService DeployService
func (t *TenantStruct) DeployService(w http.ResponseWriter, r *http.Request) {
logrus.Debugf("trans deploy service")
w.Write([]byte("deploy service"))
}
//UpgradeService UpgradeService
// swagger:operation POST /v2/tenants/{tenant_name}/services/{service_alias}/upgrade v2 upgradeService
//
// 升级应用
//
2017-11-27 18:01:04 +08:00
// upgrade service
//
// ---
// consumes:
// - application/json
// - application/x-protobuf
//
// produces:
// - application/json
// - application/xml
//
// responses:
// default:
// schema:
// "$ref": "#/responses/commandResponse"
// description: 统一返回格式
2017-11-07 11:40:44 +08:00
func (t *TenantStruct) UpgradeService(w http.ResponseWriter, r *http.Request) {
2019-06-29 20:02:41 +08:00
var upgradeRequest api_model.UpgradeInfoRequestStruct
ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &upgradeRequest, nil)
2017-11-07 11:40:44 +08:00
if !ok {
2019-06-29 20:02:41 +08:00
logrus.Errorf("start operation validate request body failure")
2017-11-07 11:40:44 +08:00
return
}
2019-08-22 16:07:26 +08:00
upgradeRequest.EventID = r.Context().Value(middleware.ContextKey("event_id")).(string)
2017-11-07 11:40:44 +08:00
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
2019-06-29 21:16:07 +08:00
if upgradeRequest.ServiceID != serviceID {
httputil.ReturnError(r, w, 400, "upgrade service id failure")
2018-02-26 11:35:50 +08:00
return
}
tenant := r.Context().Value(middleware.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(middleware.ContextKey("service")).(*dbmodel.TenantServices)
if err := handler.CheckTenantResource(tenant, service.Replicas*service.ContainerMemory); err != nil {
httputil.ReturnResNotEnough(r, w, err.Error())
return
}
2019-06-29 20:02:41 +08:00
re := handler.GetOperationHandler().Upgrade(upgradeRequest)
httputil.ReturnSuccess(r, w, re)
2017-11-07 11:40:44 +08:00
}
//CheckCode CheckCode
// swagger:operation POST /v2/tenants/{tenant_name}/code-check v2 checkCode
//
// 应用代码检测
//
2017-11-27 18:01:04 +08:00
// check code
//
// ---
// consumes:
// - application/json
// - application/x-protobuf
//
// produces:
// - application/json
// - application/xml
//
// responses:
// default:
// schema:
// "$ref": "#/responses/commandResponse"
// description: 统一返回格式
2017-11-07 11:40:44 +08:00
func (t *TenantStruct) CheckCode(w http.ResponseWriter, r *http.Request) {
var ccs api_model.CheckCodeStruct
ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &ccs.Body, nil)
if !ok {
return
}
if ccs.Body.TenantID == "" {
tenantID := r.Context().Value(middleware.ContextKey("tenant_id")).(string)
ccs.Body.TenantID = tenantID
}
ccs.Body.Action = "code_check"
if err := handler.GetServiceManager().CodeCheck(&ccs); err != nil {
httputil.ReturnError(r, w, 500, fmt.Sprintf("task code check error,%v", err))
return
}
httputil.ReturnSuccess(r, w, nil)
}
//RollBack RollBack
// swagger:operation Post /v2/tenants/{tenant_name}/services/{service_alias}/rollback v2 rollback
//
// 应用版本回滚
//
2017-11-27 18:01:04 +08:00
// service rollback
//
// ---
// consumes:
// - application/json
// - application/x-protobuf
//
// produces:
// - application/json
// - application/xml
//
// responses:
// default:
// schema:
// "$ref": "#/responses/commandResponse"
// description: 统一返回格式
2017-11-07 11:40:44 +08:00
func (t *TenantStruct) RollBack(w http.ResponseWriter, r *http.Request) {
2019-06-29 23:33:27 +08:00
var rollbackRequest api_model.RollbackInfoRequestStruct
ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &rollbackRequest, nil)
2017-11-07 11:40:44 +08:00
if !ok {
2019-06-29 23:33:27 +08:00
logrus.Errorf("start operation validate request body failure")
2017-11-07 11:40:44 +08:00
return
}
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
2019-06-29 23:33:27 +08:00
if rollbackRequest.ServiceID != serviceID {
httputil.ReturnError(r, w, 400, "rollback service id failure")
2017-11-07 11:40:44 +08:00
return
}
2019-08-22 16:07:26 +08:00
rollbackRequest.EventID = r.Context().Value(middleware.ContextKey("event_id")).(string)
tenant := r.Context().Value(middleware.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(middleware.ContextKey("service")).(*dbmodel.TenantServices)
if err := handler.CheckTenantResource(tenant, service.Replicas*service.ContainerMemory); err != nil {
httputil.ReturnResNotEnough(r, w, err.Error())
return
}
2019-06-29 23:33:27 +08:00
re := handler.GetOperationHandler().RollBack(rollbackRequest)
httputil.ReturnSuccess(r, w, re)
2017-11-07 11:40:44 +08:00
return
}
2018-10-23 18:11:27 +08:00
type limitMemory struct {
LimitMemory int `json:"limit_memory"`
}
2019-03-09 13:51:36 +08:00
//LimitTenantMemory -
2018-10-23 18:11:27 +08:00
func (t *TenantStruct) LimitTenantMemory(w http.ResponseWriter, r *http.Request) {
var lm limitMemory
body, err := ioutil.ReadAll(r.Body)
2019-08-22 16:07:26 +08:00
2018-10-23 18:11:27 +08:00
if err != nil {
httputil.ReturnError(r, w, 500, err.Error())
return
}
err = ffjson.Unmarshal(body, &lm)
if err != nil {
httputil.ReturnError(r, w, 500, err.Error())
return
}
tenantID := r.Context().Value(middleware.ContextKey("tenant_id")).(string)
tenant, err := db.GetManager().TenantDao().GetTenantByUUID(tenantID)
if err != nil {
httputil.ReturnError(r, w, 400, err.Error())
return
}
tenant.LimitMemory = lm.LimitMemory
if err := db.GetManager().TenantDao().UpdateModel(tenant); err != nil {
httputil.ReturnError(r, w, 500, err.Error())
}
httputil.ReturnSuccess(r, w, "success!")
}
2019-03-09 13:51:36 +08:00
//SourcesInfo -
2018-10-23 18:11:27 +08:00
type SourcesInfo struct {
2018-11-13 13:41:20 +08:00
TenantID string `json:"tenant_id"`
2018-10-23 18:11:27 +08:00
AvailableMemory int `json:"available_memory"`
Status bool `json:"status"`
MemTotal int `json:"mem_total"`
MemUsed int `json:"mem_used"`
2019-08-22 16:07:26 +08:00
CPUTotal int `json:"cpu_total"`
CPUUsed int `json:"cpu_used"`
2018-10-23 18:11:27 +08:00
}
2018-12-07 13:53:43 +08:00
//TenantResourcesStatus tenant resources status
2018-10-23 18:11:27 +08:00
func (t *TenantStruct) TenantResourcesStatus(w http.ResponseWriter, r *http.Request) {
tenantID := r.Context().Value(middleware.ContextKey("tenant_id")).(string)
tenant, err := db.GetManager().TenantDao().GetTenantByUUID(tenantID)
if err != nil {
httputil.ReturnError(r, w, 400, err.Error())
return
}
//11ms
services, err := handler.GetServiceManager().GetService(tenant.UUID)
if err != nil {
msg := httputil.ResponseBody{
Msg: fmt.Sprintf("get service error, %v", err),
}
httputil.Return(r, w, 500, msg)
return
}
statsInfo, _ := handler.GetTenantManager().StatsMemCPU(services)
if tenant.LimitMemory == 0 {
sourcesInfo := SourcesInfo{
2018-11-13 13:41:20 +08:00
TenantID: tenantID,
2018-10-23 18:11:27 +08:00
AvailableMemory: 0,
Status: true,
MemTotal: tenant.LimitMemory,
MemUsed: statsInfo.MEM,
2019-08-22 16:07:26 +08:00
CPUTotal: 0,
CPUUsed: statsInfo.CPU,
2018-10-23 18:11:27 +08:00
}
httputil.ReturnSuccess(r, w, sourcesInfo)
return
}
if statsInfo.MEM >= tenant.LimitMemory {
sourcesInfo := SourcesInfo{
2018-11-13 13:41:20 +08:00
TenantID: tenantID,
2018-10-23 18:11:27 +08:00
AvailableMemory: tenant.LimitMemory - statsInfo.MEM,
Status: false,
MemTotal: tenant.LimitMemory,
MemUsed: statsInfo.MEM,
2019-08-22 16:07:26 +08:00
CPUTotal: tenant.LimitMemory / 4,
CPUUsed: statsInfo.CPU,
2018-10-23 18:11:27 +08:00
}
httputil.ReturnSuccess(r, w, sourcesInfo)
} else {
sourcesInfo := SourcesInfo{
2018-11-13 13:41:20 +08:00
TenantID: tenantID,
2018-10-23 18:11:27 +08:00
AvailableMemory: tenant.LimitMemory - statsInfo.MEM,
Status: true,
MemTotal: tenant.LimitMemory,
MemUsed: statsInfo.MEM,
2019-08-22 16:07:26 +08:00
CPUTotal: tenant.LimitMemory / 4,
CPUUsed: statsInfo.CPU,
2018-10-23 18:11:27 +08:00
}
httputil.ReturnSuccess(r, w, sourcesInfo)
}
}
2018-12-07 13:53:43 +08:00
//GetServiceDeployInfo get service deploy info
func GetServiceDeployInfo(w http.ResponseWriter, r *http.Request) {
tenantID := r.Context().Value(middleware.ContextKey("tenant_id")).(string)
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
info, err := handler.GetServiceManager().GetServiceDeployInfo(tenantID, serviceID)
if err != nil {
err.Handle(r, w)
return
}
httputil.ReturnSuccess(r, w, info)
}