package controller
import (
"context"
"fmt"
"io/ioutil"
"net/http"
"os"
"strconv"
"github.com/go-chi/chi"
"github.com/goodrain/rainbond/api/handler"
api_model "github.com/goodrain/rainbond/api/model"
ctxutil "github.com/goodrain/rainbond/api/util/ctx"
"github.com/goodrain/rainbond/db"
dbmodel "github.com/goodrain/rainbond/db/model"
"github.com/goodrain/rainbond/event"
validator "github.com/goodrain/rainbond/util/govalidator"
httputil "github.com/goodrain/rainbond/util/http"
"github.com/goodrain/rainbond/worker/discover/model"
"github.com/jinzhu/gorm"
"github.com/pquerna/ffjson/ffjson"
"github.com/sirupsen/logrus"
)
func (t *TenantStruct) StartService(w http.ResponseWriter, r *http.Request) {
tenantID := r.Context().Value(ctxutil.ContextKey("tenant_id")).(string)
serviceID := r.Context().Value(ctxutil.ContextKey("service_id")).(string)
tenant := r.Context().Value(ctxutil.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(ctxutil.ContextKey("service")).(*dbmodel.TenantServices)
sEvent := r.Context().Value(ctxutil.ContextKey("event")).(*dbmodel.ServiceEvent)
if service.Kind != "third_party" {
var noMemory, noCPU, needStorage int
if service.ContainerCPU == 0 {
noCPU = service.Replicas
}
if service.ContainerMemory == 0 {
noMemory = service.Replicas
}
storages, err := db.GetManager().TenantServiceVolumeDao().GetTenantServiceVolumesByServiceID(serviceID)
if err != nil {
httputil.ReturnResNotEnough(r, w, sEvent.EventID, err.Error())
return
}
if storages != nil && len(storages) > 0 {
for _, storage := range storages {
needStorage += int(storage.VolumeCapacity)
}
}
if err := handler.CheckTenantResource(r.Context(), tenant, service.Replicas*service.ContainerMemory, service.Replicas*service.ContainerCPU, needStorage, noMemory, noCPU); err != nil {
httputil.ReturnResNotEnough(r, w, sEvent.EventID, err.Error())
return
}
}
startStopStruct := &api_model.StartStopStruct{
TenantID: tenantID,
ServiceID: serviceID,
EventID: sEvent.EventID,
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)
}
func (t *TenantStruct) StopService(w http.ResponseWriter, r *http.Request) {
tenantID := r.Context().Value(ctxutil.ContextKey("tenant_id")).(string)
serviceID := r.Context().Value(ctxutil.ContextKey("service_id")).(string)
sEvent := r.Context().Value(ctxutil.ContextKey("event")).(*dbmodel.ServiceEvent)
defer event.CloseManager()
startStopStruct := &api_model.StartStopStruct{
TenantID: tenantID,
ServiceID: serviceID,
EventID: sEvent.EventID,
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)
}
func (t *TenantStruct) RestartService(w http.ResponseWriter, r *http.Request) {
tenantID := r.Context().Value(ctxutil.ContextKey("tenant_id")).(string)
serviceID := r.Context().Value(ctxutil.ContextKey("service_id")).(string)
sEvent := r.Context().Value(ctxutil.ContextKey("event")).(*dbmodel.ServiceEvent)
defer event.CloseManager()
startStopStruct := &api_model.StartStopStruct{
TenantID: tenantID,
ServiceID: serviceID,
EventID: sEvent.EventID,
TaskType: "restart",
}
curStatus := t.StatusCli.GetStatus(serviceID)
if curStatus == "closed" {
startStopStruct.TaskType = "start"
}
tenant := r.Context().Value(ctxutil.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(ctxutil.ContextKey("service")).(*dbmodel.TenantServices)
var noMemory, noCPU, needStorage int
if service.ContainerCPU == 0 {
noCPU = service.Replicas
}
if service.ContainerMemory == 0 {
noMemory = service.Replicas
}
storages, err := db.GetManager().TenantServiceVolumeDao().GetTenantServiceVolumesByServiceID(serviceID)
if err != nil {
httputil.ReturnResNotEnough(r, w, sEvent.EventID, err.Error())
return
}
if storages != nil && len(storages) > 0 {
for _, storage := range storages {
needStorage += int(storage.VolumeCapacity)
}
}
if err := handler.CheckTenantResource(r.Context(), tenant, service.Replicas*service.ContainerMemory, needStorage, service.Replicas*service.ContainerCPU, noMemory, noCPU); err != nil {
httputil.ReturnResNotEnough(r, w, sEvent.EventID, err.Error())
return
}
if err := handler.GetServiceManager().StartStopService(startStopStruct); err != nil {
httputil.ReturnError(r, w, 500, "get service info error.")
return
}
httputil.ReturnSuccess(r, w, sEvent)
}
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(ctxutil.ContextKey("tenant_id")).(string)
serviceID := r.Context().Value(ctxutil.ContextKey("service_id")).(string)
sEvent := r.Context().Value(ctxutil.ContextKey("event")).(*dbmodel.ServiceEvent)
var cpuSet, gpuSet, memorySet *int
if cpu, ok := data["container_cpu"].(float64); ok {
cpuInt := int(cpu)
cpuSet = &cpuInt
}
if memory, ok := data["container_memory"].(float64); ok {
memoryInt := int(memory)
memorySet = &memoryInt
}
if gpu, ok := data["container_gpu"].(float64); ok {
gpuInt := int(gpu)
gpuSet = &gpuInt
}
tenant := r.Context().Value(ctxutil.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(ctxutil.ContextKey("service")).(*dbmodel.TenantServices)
if memorySet != nil && cpuSet != nil {
var noMemory, noCPU int
if *cpuSet == 0 {
noCPU = service.Replicas
}
if *memorySet == 0 {
noMemory = service.Replicas
}
if err := handler.CheckTenantResource(r.Context(), tenant, service.Replicas*(*memorySet), service.Replicas*(*cpuSet), 0, noMemory, noCPU); err != nil {
httputil.ReturnResNotEnough(r, w, sEvent.EventID, err.Error())
return
}
}
verticalTask := &model.VerticalScalingTaskBody{
TenantID: tenantID,
ServiceID: serviceID,
EventID: sEvent.EventID,
ContainerCPU: cpuSet,
ContainerMemory: memorySet,
ContainerGPU: gpuSet,
}
if err := handler.GetServiceManager().ServiceVertical(r.Context(), verticalTask); err != nil {
httputil.ReturnError(r, w, 500, fmt.Sprintf("service vertical error. %v", err))
return
}
httputil.ReturnSuccess(r, w, sEvent)
}
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(ctxutil.ContextKey("tenant_id")).(string)
serviceID := r.Context().Value(ctxutil.ContextKey("service_id")).(string)
sEvent := r.Context().Value(ctxutil.ContextKey("event")).(*dbmodel.ServiceEvent)
replicas := int32(data["node_num"].(float64))
tenant := r.Context().Value(ctxutil.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(ctxutil.ContextKey("service")).(*dbmodel.TenantServices)
var noMemory, noCPU int
if service.ContainerCPU == 0 {
noCPU = int(replicas)
}
if service.ContainerMemory == 0 {
noMemory = int(replicas)
}
if int(replicas) > service.Replicas {
if err := handler.CheckTenantResource(r.Context(), tenant, service.ContainerMemory*(int(replicas-int32(service.Replicas))), service.ContainerCPU*(int(replicas-int32(service.Replicas))), 0, noMemory, noCPU); err != nil {
httputil.ReturnResNotEnough(r, w, sEvent.EventID, err.Error())
return
}
}
horizontalTask := &model.HorizontalScalingTaskBody{
TenantID: tenantID,
ServiceID: serviceID,
EventID: sEvent.EventID,
Username: sEvent.UserName,
Replicas: replicas,
}
if err := handler.GetServiceManager().ServiceHorizontal(horizontalTask); err != nil {
httputil.ReturnBcodeError(r, w, err)
return
}
httputil.ReturnSuccess(r, w, sEvent)
}
func (t *TenantStruct) BuildService(w http.ResponseWriter, r *http.Request) {
var build api_model.ComponentBuildReq
ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &build, nil)
if !ok {
return
}
serviceID := r.Context().Value(ctxutil.ContextKey("service_id")).(string)
tenantName := r.Context().Value(ctxutil.ContextKey("tenant_name")).(string)
build.TenantName = tenantName
build.EventID = r.Context().Value(ctxutil.ContextKey("event_id")).(string)
if build.ServiceID != serviceID {
httputil.ReturnError(r, w, 400, "build service id is failure")
return
}
tenant := r.Context().Value(ctxutil.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(ctxutil.ContextKey("service")).(*dbmodel.TenantServices)
var noMemory, noCPU, needStorage int
if service.ContainerCPU == 0 {
noCPU = service.Replicas
}
if service.ContainerMemory == 0 {
noMemory = service.Replicas
}
storages, err := db.GetManager().TenantServiceVolumeDao().GetTenantServiceVolumesByServiceID(serviceID)
if err != nil {
httputil.ReturnResNotEnough(r, w, build.EventID, err.Error())
return
}
if storages != nil && len(storages) > 0 {
for _, storage := range storages {
needStorage += int(storage.VolumeCapacity)
}
}
if err := handler.CheckTenantResource(r.Context(), tenant, service.Replicas*service.ContainerMemory, service.Replicas*service.ContainerCPU, needStorage, noMemory, noCPU); err != nil {
httputil.ReturnResNotEnough(r, w, build.EventID, err.Error())
return
}
res, err := handler.GetOperationHandler().Build(&build)
if err != nil {
httputil.ReturnBcodeError(r, w, err)
return
}
httputil.ReturnSuccess(r, w, res)
}
func (t *TenantStruct) PauseService(w http.ResponseWriter, r *http.Request) {
serviceID := r.Context().Value(ctxutil.ContextKey("service_id")).(string)
sEvent := r.Context().Value(ctxutil.ContextKey("event")).(*dbmodel.ServiceEvent)
if err := handler.GetServiceManager().PauseUNPauseService(serviceID, "pause"); err != nil {
httputil.ReturnError(r, w, 500, "get service info error.")
return
}
err := db.GetManager().ServiceEventDao().SetEventStatus(r.Context(), dbmodel.EventStatusSuccess)
if err != nil {
httputil.ReturnError(r, w, 500, fmt.Sprintf("pause update event failure: %v", err))
return
}
httputil.ReturnSuccess(r, w, sEvent)
}
func (t *TenantStruct) UNPauseService(w http.ResponseWriter, r *http.Request) {
serviceID := r.Context().Value(ctxutil.ContextKey("service_id")).(string)
sEvent := r.Context().Value(ctxutil.ContextKey("event")).(*dbmodel.ServiceEvent)
if err := handler.GetServiceManager().PauseUNPauseService(serviceID, "unpause"); err != nil {
httputil.ReturnError(r, w, 500, "get service info error.")
return
}
err := db.GetManager().ServiceEventDao().SetEventStatus(r.Context(), dbmodel.EventStatusSuccess)
if err != nil {
httputil.ReturnError(r, w, 500, fmt.Sprintf("unpause update event failure: %v", err))
return
}
httputil.ReturnSuccess(r, w, sEvent)
}
func (t *TenantStruct) BuildList(w http.ResponseWriter, r *http.Request) {
serviceID := r.Context().Value(ctxutil.ContextKey("service_id")).(string)
resp, err := handler.GetServiceManager().ListVersionInfo(serviceID)
if err != nil {
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)
}
func (t *TenantStruct) FileManageService(w http.ResponseWriter, r *http.Request) {
tarPath := r.FormValue("path")
podName := r.FormValue("pod_name")
namespace := r.FormValue("namespace")
serviceID := r.Context().Value(ctxutil.ContextKey("service_id")).(string)
fileInfos, err := handler.GetServiceManager().FileManageInfo(serviceID, podName, tarPath, namespace)
if err != nil {
logrus.Errorf(fmt.Sprintf("%v get file manage %v failure: %v", serviceID, tarPath, err))
httputil.ReturnError(r, w, 500, fmt.Sprintf("%v get file manage %v failure: %v", serviceID, tarPath, err))
return
}
httputil.ReturnSuccess(r, w, fileInfos)
}
func (t *TenantStruct) BuildVersionIsExist(w http.ResponseWriter, r *http.Request) {
statusMap := make(map[string]bool)
serviceID := r.Context().Value(ctxutil.ContextKey("service_id")).(string)
buildVersion := chi.URLParam(r, "build_version")
_, err := db.GetManager().VersionInfoDao().GetVersionByDeployVersion(buildVersion, 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 {
statusMap["status"] = false
} else {
statusMap["status"] = true
}
httputil.ReturnSuccess(r, w, statusMap)
}
func (t *TenantStruct) DeleteBuildVersion(w http.ResponseWriter, r *http.Request) {
serviceID := r.Context().Value(ctxutil.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" {
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)
}
func (t *TenantStruct) UpdateBuildVersion(w http.ResponseWriter, r *http.Request) {
var build api_model.UpdateBuildVersionReq
ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &build, nil)
if !ok {
return
}
serviceID := r.Context().Value(ctxutil.ContextKey("service_id")).(string)
buildVersion := chi.URLParam(r, "build_version")
versionInfo, err := db.GetManager().VersionInfoDao().GetVersionByDeployVersion(buildVersion, serviceID)
if err != nil {
httputil.ReturnError(r, w, 500, fmt.Sprintf("update build version info error, %v", err))
return
}
versionInfo.PlanVersion = build.PlanVersion
err = db.GetManager().VersionInfoDao().UpdateModel(versionInfo)
if err != nil {
httputil.ReturnError(r, w, 500, fmt.Sprintf("update build version info error, %v", err))
return
}
httputil.ReturnSuccess(r, w, nil)
}
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)
case "PUT":
t.UpdateBuildVersion(w, r)
}
}
func (t *TenantStruct) GetDeployVersion(w http.ResponseWriter, r *http.Request) {
service := r.Context().Value(ctxutil.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, "build version do not exist")
return
}
httputil.ReturnSuccess(r, w, version)
}
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{})
if !ok {
httputil.ReturnError(r, w, 400, "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)
if err != nil {
httputil.ReturnError(r, w, 500, 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)
}
func (t *TenantStruct) DeployService(w http.ResponseWriter, r *http.Request) {
logrus.Debugf("trans deploy service")
w.Write([]byte("deploy service"))
}
func (t *TenantStruct) UpgradeService(w http.ResponseWriter, r *http.Request) {
var upgradeRequest api_model.ComponentUpgradeReq
ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &upgradeRequest, nil)
if !ok {
logrus.Errorf("start operation validate request body failure")
return
}
upgradeRequest.EventID = r.Context().Value(ctxutil.ContextKey("event_id")).(string)
serviceID := r.Context().Value(ctxutil.ContextKey("service_id")).(string)
if upgradeRequest.ServiceID != serviceID {
httputil.ReturnError(r, w, 400, "upgrade service id failure")
return
}
tenant := r.Context().Value(ctxutil.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(ctxutil.ContextKey("service")).(*dbmodel.TenantServices)
if service.Kind != "third_party" {
var noMemory, noCPU, needStorage int
if service.ContainerCPU == 0 {
noCPU = service.Replicas
}
if service.ContainerMemory == 0 {
noMemory = service.Replicas
}
storages, err := db.GetManager().TenantServiceVolumeDao().GetTenantServiceVolumesByServiceID(serviceID)
if err != nil {
httputil.ReturnResNotEnough(r, w, upgradeRequest.EventID, err.Error())
return
}
if storages != nil && len(storages) > 0 {
for _, storage := range storages {
needStorage += int(storage.VolumeCapacity)
}
}
if err := handler.CheckTenantResource(r.Context(), tenant, service.Replicas*service.ContainerMemory, service.Replicas*service.ContainerCPU, needStorage, noMemory, noCPU); err != nil {
httputil.ReturnResNotEnough(r, w, upgradeRequest.EventID, err.Error())
return
}
}
res, err := handler.GetOperationHandler().Upgrade(&upgradeRequest)
if err != nil {
httputil.ReturnBcodeError(r, w, err)
return
}
httputil.ReturnSuccess(r, w, res)
}
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(ctxutil.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)
}
func (t *TenantStruct) RollBack(w http.ResponseWriter, r *http.Request) {
var rollbackRequest api_model.RollbackInfoRequestStruct
ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &rollbackRequest, nil)
if !ok {
logrus.Errorf("start operation validate request body failure")
return
}
serviceID := r.Context().Value(ctxutil.ContextKey("service_id")).(string)
if rollbackRequest.ServiceID != serviceID {
httputil.ReturnError(r, w, 400, "rollback service id failure")
return
}
rollbackRequest.EventID = r.Context().Value(ctxutil.ContextKey("event_id")).(string)
tenant := r.Context().Value(ctxutil.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(ctxutil.ContextKey("service")).(*dbmodel.TenantServices)
var noMemory, noCPU int
if service.ContainerCPU == 0 {
noCPU = service.Replicas
}
if service.ContainerMemory == 0 {
noMemory = service.Replicas
}
if err := handler.CheckTenantResource(r.Context(), tenant, service.Replicas*service.ContainerMemory, service.Replicas*service.ContainerCPU, 0, noMemory, noCPU); err != nil {
httputil.ReturnResNotEnough(r, w, rollbackRequest.EventID, err.Error())
return
}
re := handler.GetOperationHandler().RollBack(rollbackRequest)
httputil.ReturnSuccess(r, w, re)
}
type TenantResourceQuota struct {
LimitMemory int `json:"limit_memory"`
LimitCPU int `json:"limit_cpu"`
LimitStorage int `json:"limit_storage"`
}
func (t *TenantStruct) LimitTenantResource(w http.ResponseWriter, r *http.Request) {
var trq TenantResourceQuota
body, err := ioutil.ReadAll(r.Body)
if err != nil {
httputil.ReturnError(r, w, 500, err.Error())
return
}
err = ffjson.Unmarshal(body, &trq)
if err != nil {
httputil.ReturnError(r, w, 500, err.Error())
return
}
tenantID := r.Context().Value(ctxutil.ContextKey("tenant_id")).(string)
tenant, err := db.GetManager().TenantDao().GetTenantByUUID(tenantID)
if err != nil {
httputil.ReturnError(r, w, 400, err.Error())
return
}
tenant.LimitMemory = trq.LimitMemory
tenant.LimitCPU = trq.LimitCPU
tenant.LimitStorage = trq.LimitStorage
err = handler.GetTenantManager().TenantResourceQuota(context.Background(), tenant.Namespace, trq.LimitCPU, trq.LimitMemory, trq.LimitStorage)
if err != nil {
httputil.ReturnError(r, w, 400, err.Error())
return
}
if err := db.GetManager().TenantDao().UpdateModel(tenant); err != nil {
httputil.ReturnError(r, w, 500, err.Error())
}
httputil.ReturnSuccess(r, w, "success!")
}
type SourcesInfo struct {
TenantID string `json:"tenant_id"`
AvailableMemory int `json:"available_memory"`
Status bool `json:"status"`
MemTotal int `json:"mem_total"`
MemUsed int `json:"mem_used"`
CPUTotal int `json:"cpu_total"`
CPUUsed int `json:"cpu_used"`
}
func (t *TenantStruct) TenantResourcesStatus(w http.ResponseWriter, r *http.Request) {
tenantID := r.Context().Value(ctxutil.ContextKey("tenant_id")).(string)
tenant, err := db.GetManager().TenantDao().GetTenantByUUID(tenantID)
if err != nil {
httputil.ReturnError(r, w, 400, err.Error())
return
}
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{
TenantID: tenantID,
AvailableMemory: 0,
Status: true,
MemTotal: tenant.LimitMemory,
MemUsed: statsInfo.MEM,
CPUTotal: 0,
CPUUsed: statsInfo.CPU,
}
httputil.ReturnSuccess(r, w, sourcesInfo)
return
}
if statsInfo.MEM >= tenant.LimitMemory {
sourcesInfo := SourcesInfo{
TenantID: tenantID,
AvailableMemory: tenant.LimitMemory - statsInfo.MEM,
Status: false,
MemTotal: tenant.LimitMemory,
MemUsed: statsInfo.MEM,
CPUTotal: tenant.LimitMemory / 4,
CPUUsed: statsInfo.CPU,
}
httputil.ReturnSuccess(r, w, sourcesInfo)
} else {
sourcesInfo := SourcesInfo{
TenantID: tenantID,
AvailableMemory: tenant.LimitMemory - statsInfo.MEM,
Status: true,
MemTotal: tenant.LimitMemory,
MemUsed: statsInfo.MEM,
CPUTotal: tenant.LimitMemory / 4,
CPUUsed: statsInfo.CPU,
}
httputil.ReturnSuccess(r, w, sourcesInfo)
}
}
func GetServiceDeployInfo(w http.ResponseWriter, r *http.Request) {
tenantID := r.Context().Value(ctxutil.ContextKey("tenant_id")).(string)
serviceID := r.Context().Value(ctxutil.ContextKey("service_id")).(string)
info, err := handler.GetServiceManager().GetServiceDeployInfo(tenantID, serviceID)
if err != nil {
err.Handle(r, w)
return
}
httputil.ReturnSuccess(r, w, info)
}
func (t *TenantStruct) Log(w http.ResponseWriter, r *http.Request) {
component := r.Context().Value(ctxutil.ContextKey("service")).(*dbmodel.TenantServices)
podName := r.URL.Query().Get("podName")
containerName := r.URL.Query().Get("containerName")
follow, _ := strconv.ParseBool(r.URL.Query().Get("follow"))
err := handler.GetServiceManager().Log(w, r, component, podName, containerName, follow)
if err != nil {
httputil.ReturnBcodeError(r, w, err)
return
}
}