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 handler
import (
2019-01-09 15:05:32 +08:00
"encoding/json"
2019-10-29 18:36:15 +08:00
"errors"
2017-11-07 11:40:44 +08:00
"fmt"
"os"
2019-01-25 23:34:12 +08:00
"strconv"
2017-11-07 11:40:44 +08:00
"strings"
"time"
2017-12-13 17:38:45 +08:00
"github.com/coreos/etcd/clientv3"
2020-02-24 12:53:03 +08:00
"github.com/jinzhu/gorm"
"github.com/pquerna/ffjson/ffjson"
2020-09-18 15:54:21 +08:00
"github.com/sirupsen/logrus"
2020-02-24 12:53:03 +08:00
"github.com/twinj/uuid"
2021-05-19 09:19:52 +08:00
pkgerr "github.com/pkg/errors"
2020-02-24 12:53:03 +08:00
2020-09-24 21:09:00 +08:00
"github.com/goodrain/rainbond/api/client/prometheus"
2018-04-24 16:44:59 +08:00
"github.com/goodrain/rainbond/api/util"
2020-10-22 15:35:26 +08:00
"github.com/goodrain/rainbond/api/util/bcode"
2019-09-03 15:09:30 +08:00
"github.com/goodrain/rainbond/builder/parser"
2019-01-09 15:05:32 +08:00
"github.com/goodrain/rainbond/cmd/api/option"
"github.com/goodrain/rainbond/db"
"github.com/goodrain/rainbond/event"
2018-11-19 18:56:28 +08:00
"github.com/goodrain/rainbond/worker/client"
2018-04-24 16:44:59 +08:00
"github.com/goodrain/rainbond/worker/discover/model"
2019-08-26 00:27:24 +08:00
"github.com/goodrain/rainbond/worker/server"
2019-01-09 15:05:32 +08:00
"github.com/goodrain/rainbond/worker/server/pb"
2020-02-24 12:53:03 +08:00
api_model "github.com/goodrain/rainbond/api/model"
2019-12-04 10:02:07 +08:00
dberrors "github.com/goodrain/rainbond/db/errors"
2019-01-09 15:05:32 +08:00
core_model "github.com/goodrain/rainbond/db/model"
2018-04-24 16:44:59 +08:00
dbmodel "github.com/goodrain/rainbond/db/model"
2019-10-29 18:36:15 +08:00
eventutil "github.com/goodrain/rainbond/eventlog/util"
2018-12-04 13:43:15 +08:00
gclient "github.com/goodrain/rainbond/mq/client"
2018-04-24 16:44:59 +08:00
core_util "github.com/goodrain/rainbond/util"
2020-02-24 12:53:03 +08:00
typesv1 "github.com/goodrain/rainbond/worker/appm/types/v1"
2017-11-07 11:40:44 +08:00
)
2019-10-29 18:36:15 +08:00
// ErrServiceNotClosed -
var ErrServiceNotClosed = errors . New ( "Service has not been closed" )
2017-11-07 11:40:44 +08:00
//ServiceAction service act
type ServiceAction struct {
2020-09-24 21:09:00 +08:00
MQClient gclient . MQClient
EtcdCli * clientv3 . Client
statusCli * client . AppRuntimeSyncClient
prometheusCli prometheus . Interface
conf option . Config
2017-11-07 11:40:44 +08:00
}
2019-02-26 16:39:27 +08:00
type dCfg struct {
Type string ` json:"type" `
Servers [ ] string ` json:"servers" `
Key string ` json:"key" `
Username string ` json:"username" `
Password string ` json:"password" `
}
2017-11-07 11:40:44 +08:00
//CreateManager create Manger
2018-12-08 12:58:40 +08:00
func CreateManager ( conf option . Config , mqClient gclient . MQClient ,
2020-09-24 21:09:00 +08:00
etcdCli * clientv3 . Client , statusCli * client . AppRuntimeSyncClient , prometheusCli prometheus . Interface ) * ServiceAction {
2017-11-07 11:40:44 +08:00
return & ServiceAction {
2020-09-24 21:09:00 +08:00
MQClient : mqClient ,
EtcdCli : etcdCli ,
statusCli : statusCli ,
conf : conf ,
prometheusCli : prometheusCli ,
2017-12-15 16:49:24 +08:00
}
}
2017-12-18 14:11:43 +08:00
2017-11-07 11:40:44 +08:00
//ServiceBuild service build
func ( s * ServiceAction ) ServiceBuild ( tenantID , serviceID string , r * api_model . BuildServiceStruct ) error {
eventID := r . Body . EventID
logger := event . GetManager ( ) . GetLogger ( eventID )
defer event . CloseManager ( )
service , err := db . GetManager ( ) . TenantServiceDao ( ) . GetServiceByID ( serviceID )
2018-10-09 19:00:17 +08:00
db . GetManager ( ) . TenantServiceDao ( ) . UpdateModel ( service )
2017-11-07 11:40:44 +08:00
if err != nil {
return err
}
if r . Body . Kind == "" {
r . Body . Kind = "source"
}
switch r . Body . Kind {
2018-02-02 15:10:49 +08:00
case "build_from_image" :
if err := s . buildFromImage ( r , service ) ; err != nil {
2018-12-08 12:58:40 +08:00
logger . Error ( "The image build application task failed to send: " + err . Error ( ) , map [ string ] string { "step" : "callback" , "status" : "failure" } )
2018-03-02 10:41:01 +08:00
return err
2018-02-02 15:10:49 +08:00
}
2018-12-08 12:58:40 +08:00
logger . Info ( "The mirror build application task successed to send " , map [ string ] string { "step" : "image-service" , "status" : "starting" } )
2018-02-02 15:10:49 +08:00
return nil
case "build_from_source_code" :
if err := s . buildFromSourceCode ( r , service ) ; err != nil {
2018-12-08 12:58:40 +08:00
logger . Error ( "The source code build application task failed to send " + err . Error ( ) , map [ string ] string { "step" : "callback" , "status" : "failure" } )
2018-02-02 15:10:49 +08:00
return err
}
2018-12-08 12:58:40 +08:00
logger . Info ( "The source code build application task successed to send " , map [ string ] string { "step" : "source-service" , "status" : "starting" } )
2018-02-02 15:10:49 +08:00
return nil
2018-03-05 17:40:56 +08:00
case "build_from_market_image" :
if err := s . buildFromImage ( r , service ) ; err != nil {
2018-12-08 12:58:40 +08:00
logger . Error ( "The cloud image build application task failed to send " + err . Error ( ) , map [ string ] string { "step" : "callback" , "status" : "failure" } )
2018-03-05 17:40:56 +08:00
return err
}
2018-12-08 12:58:40 +08:00
logger . Info ( "The cloud image build application task successed to send " , map [ string ] string { "step" : "image-service" , "status" : "starting" } )
2018-03-05 17:40:56 +08:00
return nil
case "build_from_market_slug" :
2018-03-06 17:36:41 +08:00
if err := s . buildFromMarketSlug ( r , service ) ; err != nil {
2018-12-08 12:58:40 +08:00
logger . Error ( "The cloud slug build application task failed to send " + err . Error ( ) , map [ string ] string { "step" : "callback" , "status" : "failure" } )
2018-03-06 17:36:41 +08:00
return err
}
2018-12-08 12:58:40 +08:00
logger . Info ( "The cloud slug build application task successed to send " , map [ string ] string { "step" : "image-service" , "status" : "starting" } )
2018-03-05 17:40:56 +08:00
return nil
2017-11-07 11:40:44 +08:00
default :
return fmt . Errorf ( "unexpect kind" )
}
}
2018-03-05 17:40:56 +08:00
func ( s * ServiceAction ) buildFromMarketSlug ( r * api_model . BuildServiceStruct , service * dbmodel . TenantServices ) error {
body := make ( map [ string ] interface { } )
if r . Body . Operator == "" {
body [ "operator" ] = "define"
} else {
body [ "operator" ] = r . Body . Operator
}
body [ "deploy_version" ] = r . Body . DeployVersion
body [ "event_id" ] = r . Body . EventID
2018-12-04 15:21:33 +08:00
body [ "action" ] = r . Body . Action
2018-03-05 17:40:56 +08:00
body [ "tenant_name" ] = r . Body . TenantName
2018-03-06 18:01:00 +08:00
body [ "tenant_id" ] = service . TenantID
body [ "service_id" ] = service . ServiceID
2018-03-05 17:40:56 +08:00
body [ "service_alias" ] = r . Body . ServiceAlias
body [ "slug_info" ] = r . Body . SlugInfo
2018-12-04 16:38:00 +08:00
2018-12-04 18:08:51 +08:00
topic := gclient . BuilderTopic
2018-12-04 16:38:00 +08:00
if s . isWindowsService ( service . ServiceID ) {
2018-12-04 18:08:51 +08:00
topic = gclient . WindowsBuilderTopic
2018-12-04 16:38:00 +08:00
}
2018-12-04 13:43:15 +08:00
return s . MQClient . SendBuilderTopic ( gclient . TaskStruct {
2018-12-04 16:38:00 +08:00
Topic : topic ,
2018-12-04 13:43:15 +08:00
TaskType : "build_from_market_slug" ,
TaskBody : body ,
} )
2018-03-05 17:40:56 +08:00
}
2018-12-04 16:38:00 +08:00
2018-02-02 15:10:49 +08:00
func ( s * ServiceAction ) buildFromImage ( r * api_model . BuildServiceStruct , service * dbmodel . TenantServices ) error {
dependIds , err := db . GetManager ( ) . TenantServiceRelationDao ( ) . GetTenantServiceRelations ( service . ServiceID )
if err != nil {
return err
}
body := make ( map [ string ] interface { } )
if r . Body . Operator == "" {
body [ "operator" ] = "define"
} else {
body [ "operator" ] = r . Body . Operator
}
2018-03-02 10:41:01 +08:00
body [ "image" ] = r . Body . ImageURL
2018-11-27 10:42:10 +08:00
body [ "service_id" ] = service . ServiceID
2018-02-02 15:10:49 +08:00
body [ "deploy_version" ] = r . Body . DeployVersion
body [ "namespace" ] = service . Namespace
body [ "operator" ] = r . Body . Operator
body [ "event_id" ] = r . Body . EventID
body [ "tenant_name" ] = r . Body . TenantName
body [ "service_alias" ] = r . Body . ServiceAlias
2018-12-04 15:21:33 +08:00
body [ "action" ] = r . Body . Action
2018-02-02 15:10:49 +08:00
body [ "dep_sids" ] = dependIds
body [ "code_from" ] = "image_manual"
2018-03-05 17:40:56 +08:00
if r . Body . User != "" && r . Body . Password != "" {
body [ "user" ] = r . Body . User
body [ "password" ] = r . Body . Password
}
2018-12-04 18:08:51 +08:00
topic := gclient . BuilderTopic
2018-12-04 16:38:00 +08:00
if s . isWindowsService ( service . ServiceID ) {
2018-12-04 18:08:51 +08:00
topic = gclient . WindowsBuilderTopic
2018-11-30 17:38:08 +08:00
}
2018-12-04 13:43:15 +08:00
return s . MQClient . SendBuilderTopic ( gclient . TaskStruct {
Topic : topic ,
TaskType : "build_from_image" ,
TaskBody : body ,
} )
2018-02-02 15:10:49 +08:00
}
func ( s * ServiceAction ) buildFromSourceCode ( r * api_model . BuildServiceStruct , service * dbmodel . TenantServices ) error {
logrus . Debugf ( "build_from_source_code" )
2018-03-02 10:41:01 +08:00
if r . Body . RepoURL == "" || r . Body . Branch == "" || r . Body . DeployVersion == "" || r . Body . EventID == "" {
2018-02-02 15:10:49 +08:00
return fmt . Errorf ( "args error" )
2018-03-02 10:41:01 +08:00
}
2018-02-02 15:10:49 +08:00
body := make ( map [ string ] interface { } )
if r . Body . Operator == "" {
body [ "operator" ] = "define"
2018-03-02 10:41:01 +08:00
} else {
2018-02-02 15:10:49 +08:00
body [ "operator" ] = r . Body . Operator
}
body [ "tenant_id" ] = service . TenantID
body [ "service_id" ] = service . ServiceID
body [ "repo_url" ] = r . Body . RepoURL
body [ "action" ] = r . Body . Action
body [ "lang" ] = r . Body . Lang
body [ "runtime" ] = r . Body . Runtime
body [ "deploy_version" ] = r . Body . DeployVersion
body [ "event_id" ] = r . Body . EventID
body [ "envs" ] = r . Body . ENVS
body [ "tenant_name" ] = r . Body . TenantName
body [ "branch" ] = r . Body . Branch
2018-10-18 12:38:38 +08:00
body [ "server_type" ] = r . Body . ServerType
2018-02-02 15:10:49 +08:00
body [ "service_alias" ] = r . Body . ServiceAlias
if r . Body . User != "" && r . Body . Password != "" {
body [ "user" ] = r . Body . User
body [ "password" ] = r . Body . Password
}
body [ "expire" ] = 180
2018-12-04 18:08:51 +08:00
topic := gclient . BuilderTopic
2018-12-04 16:38:00 +08:00
if s . isWindowsService ( service . ServiceID ) {
2018-12-04 18:08:51 +08:00
topic = gclient . WindowsBuilderTopic
2018-12-04 16:38:00 +08:00
}
2018-12-04 13:43:15 +08:00
return s . MQClient . SendBuilderTopic ( gclient . TaskStruct {
2018-12-04 16:38:00 +08:00
Topic : topic ,
2018-12-04 13:43:15 +08:00
TaskType : "build_from_source_code" ,
TaskBody : body ,
} )
2018-11-30 17:38:08 +08:00
}
2018-12-04 16:38:00 +08:00
func ( s * ServiceAction ) isWindowsService ( serviceID string ) bool {
label , err := db . GetManager ( ) . TenantServiceLabelDao ( ) . GetLabelByNodeSelectorKey ( serviceID , "windows" )
if label == nil || err != nil {
return false
}
return true
}
2017-11-07 11:40:44 +08:00
//AddLabel add labels
2018-12-04 15:20:59 +08:00
func ( s * ServiceAction ) AddLabel ( l * api_model . LabelsStruct , serviceID string ) error {
tx := db . GetManager ( ) . Begin ( )
2019-06-20 13:59:19 +08:00
defer func ( ) {
if r := recover ( ) ; r != nil {
logrus . Errorf ( "Unexpected panic occurred, rollback transaction: %v" , r )
tx . Rollback ( )
}
} ( )
2020-02-18 22:41:18 +08:00
//V5.2: do not support service type label
2018-12-04 15:20:59 +08:00
for _ , label := range l . Labels {
2020-02-18 22:41:18 +08:00
labelModel := dbmodel . TenantServiceLable {
ServiceID : serviceID ,
LabelKey : label . LabelKey ,
LabelValue : label . LabelValue ,
2018-12-04 15:54:47 +08:00
}
if err := db . GetManager ( ) . TenantServiceLabelDaoTransactions ( tx ) . AddModel ( & labelModel ) ; err != nil {
tx . Rollback ( )
return err
2017-11-07 11:40:44 +08:00
}
}
2018-12-04 15:20:59 +08:00
if err := tx . Commit ( ) . Error ; err != nil {
tx . Rollback ( )
return err
}
2017-11-07 11:40:44 +08:00
return nil
}
2018-12-04 14:09:15 +08:00
//UpdateLabel updates labels
2018-12-04 15:20:59 +08:00
func ( s * ServiceAction ) UpdateLabel ( l * api_model . LabelsStruct , serviceID string ) error {
2018-12-04 14:09:15 +08:00
tx := db . GetManager ( ) . Begin ( )
2019-06-20 13:59:19 +08:00
defer func ( ) {
if r := recover ( ) ; r != nil {
logrus . Errorf ( "Unexpected panic occurred, rollback transaction: %v" , r )
tx . Rollback ( )
}
} ( )
2018-12-04 15:20:59 +08:00
for _ , label := range l . Labels {
// delete old labels
2018-12-04 17:55:45 +08:00
err := db . GetManager ( ) . TenantServiceLabelDaoTransactions ( tx ) .
DelTenantServiceLabelsByServiceIDKey ( serviceID , label . LabelKey )
2018-12-04 15:20:59 +08:00
if err != nil {
logrus . Errorf ( "error deleting old labels: %v" , err )
2018-12-04 14:09:15 +08:00
tx . Rollback ( )
return err
}
2020-02-18 22:41:18 +08:00
// V5.2 do not support service type label
2018-12-04 15:20:59 +08:00
// add new labels
2020-02-18 22:41:18 +08:00
labelModel := dbmodel . TenantServiceLable {
ServiceID : serviceID ,
LabelKey : label . LabelKey ,
LabelValue : label . LabelValue ,
2018-12-04 15:54:47 +08:00
}
if err := db . GetManager ( ) . TenantServiceLabelDaoTransactions ( tx ) . AddModel ( & labelModel ) ; err != nil {
logrus . Errorf ( "error adding new labels: %v" , err )
tx . Rollback ( )
return err
2018-12-04 15:20:59 +08:00
}
2018-12-04 14:09:15 +08:00
}
if err := tx . Commit ( ) . Error ; err != nil {
tx . Rollback ( )
return err
}
return nil
}
//DeleteLabel deletes label
2018-12-04 15:20:59 +08:00
func ( s * ServiceAction ) DeleteLabel ( l * api_model . LabelsStruct , serviceID string ) error {
tx := db . GetManager ( ) . Begin ( )
2019-06-20 13:59:19 +08:00
defer func ( ) {
if r := recover ( ) ; r != nil {
logrus . Errorf ( "Unexpected panic occurred, rollback transaction: %v" , r )
tx . Rollback ( )
}
} ( )
2018-12-04 15:20:59 +08:00
for _ , label := range l . Labels {
2018-12-04 17:55:45 +08:00
err := db . GetManager ( ) . TenantServiceLabelDaoTransactions ( tx ) .
DelTenantServiceLabelsByServiceIDKeyValue ( serviceID , label . LabelKey , label . LabelValue )
2018-12-04 15:20:59 +08:00
if err != nil {
logrus . Errorf ( "error deleting label: %v" , err )
tx . Rollback ( )
return err
}
2017-11-07 11:40:44 +08:00
}
2018-12-04 15:20:59 +08:00
if err := tx . Commit ( ) . Error ; err != nil {
tx . Rollback ( )
return err
}
return nil
2017-11-07 11:40:44 +08:00
}
//StartStopService start service
func ( s * ServiceAction ) StartStopService ( sss * api_model . StartStopStruct ) error {
services , err := db . GetManager ( ) . TenantServiceDao ( ) . GetServiceByID ( sss . ServiceID )
if err != nil {
logrus . Errorf ( "get service by id error, %v" , err )
return err
}
TaskBody := model . StopTaskBody {
TenantID : sss . TenantID ,
ServiceID : sss . ServiceID ,
DeployVersion : services . DeployVersion ,
EventID : sss . EventID ,
}
2018-12-04 18:08:51 +08:00
err = s . MQClient . SendBuilderTopic ( gclient . TaskStruct {
2017-11-07 11:40:44 +08:00
TaskType : sss . TaskType ,
TaskBody : TaskBody ,
2018-12-04 18:08:51 +08:00
Topic : gclient . WorkerTopic ,
} )
2017-11-07 11:40:44 +08:00
if err != nil {
logrus . Errorf ( "equque mq error, %v" , err )
return err
}
2018-01-02 12:04:36 +08:00
logrus . Debugf ( "equeue mq startstop task success" )
2017-11-07 11:40:44 +08:00
return nil
}
//ServiceVertical vertical service
func ( s * ServiceAction ) ServiceVertical ( vs * model . VerticalScalingTaskBody ) error {
2018-11-19 18:56:28 +08:00
service , err := db . GetManager ( ) . TenantServiceDao ( ) . GetServiceByID ( vs . ServiceID )
if err != nil {
logrus . Errorf ( "get service by id %s error, %s" , service . ServiceID , err )
return err
}
2020-04-27 17:54:45 +08:00
oldMemory := service . ContainerMemory
oldCPU := service . ContainerCPU
var rollback = func ( ) {
service . ContainerMemory = oldMemory
service . ContainerCPU = oldCPU
_ = db . GetManager ( ) . TenantServiceDao ( ) . UpdateModel ( service )
}
2018-11-19 18:56:28 +08:00
if service . ContainerMemory == vs . ContainerMemory && service . ContainerCPU == vs . ContainerCPU {
return nil
}
service . ContainerMemory = vs . ContainerMemory
service . ContainerCPU = vs . ContainerCPU
err = db . GetManager ( ) . TenantServiceDao ( ) . UpdateModel ( service )
if err != nil {
logrus . Errorf ( "update service memory and cpu failure. %v" , err )
return fmt . Errorf ( "Vertical service faliure:%s" , err . Error ( ) )
}
2018-12-04 18:08:51 +08:00
err = s . MQClient . SendBuilderTopic ( gclient . TaskStruct {
2017-11-07 11:40:44 +08:00
TaskType : "vertical_scaling" ,
TaskBody : vs ,
2018-12-04 18:08:51 +08:00
Topic : gclient . WorkerTopic ,
} )
2017-11-07 11:40:44 +08:00
if err != nil {
2020-04-27 17:54:45 +08:00
// roll back service
rollback ( )
2017-11-07 11:40:44 +08:00
logrus . Errorf ( "equque mq error, %v" , err )
return err
}
logrus . Debugf ( "equeue mq vertical task success" )
return nil
}
//ServiceHorizontal Service Horizontal
func ( s * ServiceAction ) ServiceHorizontal ( hs * model . HorizontalScalingTaskBody ) error {
2018-11-19 18:56:28 +08:00
service , err := db . GetManager ( ) . TenantServiceDao ( ) . GetServiceByID ( hs . ServiceID )
if err != nil {
logrus . Errorf ( "get service by id %s error, %s" , service . ServiceID , err )
return err
}
2020-04-24 14:50:51 +08:00
// for rollback database
oldReplicas := service . Replicas
2018-11-19 18:56:28 +08:00
if int32 ( service . Replicas ) == hs . Replicas {
return nil
}
2021-05-19 09:19:52 +08:00
pods , err := s . statusCli . GetServicePods ( service . ServiceID )
if err != nil {
return pkgerr . Wrap ( err , "GetPodByService Error" )
}
if int32 ( len ( pods . NewPods ) ) == hs . Replicas {
return nil
}
2018-11-19 18:56:28 +08:00
service . Replicas = int ( hs . Replicas )
err = db . GetManager ( ) . TenantServiceDao ( ) . UpdateModel ( service )
if err != nil {
logrus . Errorf ( "updtae service replicas failure. %v" , err )
return fmt . Errorf ( "horizontal service faliure:%s" , err . Error ( ) )
}
2020-04-24 14:50:51 +08:00
2020-04-27 17:54:45 +08:00
var rollback = func ( ) {
service . Replicas = oldReplicas
_ = db . GetManager ( ) . TenantServiceDao ( ) . UpdateModel ( service )
2020-04-24 14:50:51 +08:00
}
2020-04-27 17:54:45 +08:00
err = s . MQClient . SendBuilderTopic ( gclient . TaskStruct {
TaskType : "horizontal_scaling" ,
TaskBody : hs ,
Topic : gclient . WorkerTopic ,
} )
if err != nil {
// roll back service
rollback ( )
logrus . Errorf ( "equque mq error, %v" , err )
2017-11-07 11:40:44 +08:00
return err
}
2020-04-24 14:50:51 +08:00
2020-04-27 17:54:45 +08:00
// if send task success, return nil
logrus . Debugf ( "enqueue mq horizontal task success" )
return nil
2017-11-07 11:40:44 +08:00
}
//ServiceUpgrade service upgrade
func ( s * ServiceAction ) ServiceUpgrade ( ru * model . RollingUpgradeTaskBody ) error {
services , err := db . GetManager ( ) . TenantServiceDao ( ) . GetServiceByID ( ru . ServiceID )
if err != nil {
2018-11-29 12:27:27 +08:00
logrus . Errorf ( "get service by id %s error %s" , ru . ServiceID , err . Error ( ) )
2017-11-07 11:40:44 +08:00
return err
}
2018-11-29 12:27:27 +08:00
version , err := db . GetManager ( ) . VersionInfoDao ( ) . GetVersionByDeployVersion ( ru . NewDeployVersion , ru . ServiceID )
if err != nil {
logrus . Errorf ( "get service version by id %s version %s error, %s" , ru . ServiceID , ru . NewDeployVersion , err . Error ( ) )
return err
}
2020-04-27 17:54:45 +08:00
oldDeployVersion := services . DeployVersion
var rollback = func ( ) {
services . DeployVersion = oldDeployVersion
_ = db . GetManager ( ) . TenantServiceDao ( ) . UpdateModel ( services )
}
2018-11-29 12:27:27 +08:00
if version . FinalStatus != "success" {
2019-03-01 22:06:34 +08:00
logrus . Warnf ( "deploy version %s is not build success,can not change deploy version in this upgrade event" , ru . NewDeployVersion )
} else {
services . DeployVersion = ru . NewDeployVersion
err = db . GetManager ( ) . TenantServiceDao ( ) . UpdateModel ( services )
if err != nil {
logrus . Errorf ( "update service deploy version error. %v" , err )
return fmt . Errorf ( "horizontal service faliure:%s" , err . Error ( ) )
}
2018-11-19 18:56:28 +08:00
}
2018-12-04 15:09:00 +08:00
err = s . MQClient . SendBuilderTopic ( gclient . TaskStruct {
2017-11-07 11:40:44 +08:00
TaskBody : ru ,
2018-12-04 15:09:00 +08:00
TaskType : "rolling_upgrade" ,
2018-12-04 18:08:51 +08:00
Topic : gclient . WorkerTopic ,
2018-12-04 15:09:00 +08:00
} )
2018-01-31 14:24:09 +08:00
if err != nil {
2020-04-27 17:54:45 +08:00
// roll back service deploy version
rollback ( )
2018-12-04 15:09:00 +08:00
logrus . Errorf ( "equque upgrade message error, %v" , err )
2017-11-07 11:40:44 +08:00
return err
}
return nil
}
//ServiceCreate create service
func ( s * ServiceAction ) ServiceCreate ( sc * api_model . ServiceStruct ) error {
jsonSC , err := ffjson . Marshal ( sc )
if err != nil {
logrus . Errorf ( "trans service struct to json failed. %v" , err )
return err
}
var ts dbmodel . TenantServices
if err := ffjson . Unmarshal ( jsonSC , & ts ) ; err != nil {
logrus . Errorf ( "trans json to tenant service error, %v" , err )
return err
}
2018-11-27 14:50:30 +08:00
if ts . ServiceName == "" {
ts . ServiceName = ts . ServiceAlias
}
2017-11-07 11:40:44 +08:00
ts . UpdateTime = time . Now ( )
ports := sc . PortsInfo
envs := sc . EnvsInfo
volumns := sc . VolumesInfo
2018-03-13 16:55:53 +08:00
dependVolumes := sc . DepVolumesInfo
2017-11-07 11:40:44 +08:00
dependIds := sc . DependIDs
2020-09-17 18:28:37 +08:00
ts . AppID = sc . AppID
2017-12-18 14:11:43 +08:00
ts . DeployVersion = ""
2018-04-09 11:58:16 +08:00
tx := db . GetManager ( ) . Begin ( )
2019-06-20 13:59:19 +08:00
defer func ( ) {
if r := recover ( ) ; r != nil {
logrus . Errorf ( "Unexpected panic occurred, rollback transaction: %v" , r )
tx . Rollback ( )
}
} ( )
2018-04-09 11:58:16 +08:00
//create app
2017-11-07 11:40:44 +08:00
if err := db . GetManager ( ) . TenantServiceDaoTransactions ( tx ) . AddModel ( & ts ) ; err != nil {
logrus . Errorf ( "add service error, %v" , err )
tx . Rollback ( )
return err
}
2018-04-09 11:58:16 +08:00
//set app envs
2017-11-07 11:40:44 +08:00
if len ( envs ) > 0 {
for _ , env := range envs {
env . ServiceID = ts . ServiceID
env . TenantID = ts . TenantID
if err := db . GetManager ( ) . TenantServiceEnvVarDaoTransactions ( tx ) . AddModel ( & env ) ; err != nil {
2019-11-14 17:05:05 +08:00
logrus . Errorf ( "add env[name=%s] error, %v" , env . AttrName , err )
2019-12-04 10:02:07 +08:00
if err != dberrors . ErrRecordAlreadyExist {
2019-11-14 17:05:05 +08:00
tx . Rollback ( )
return err
}
logrus . Warningf ( "recover env[name=%s]" , env . AttrName )
// if env already exists, update it
if err = db . GetManager ( ) . TenantServiceEnvVarDaoTransactions ( tx ) . UpdateModel ( & env ) ; err != nil {
tx . Rollback ( )
return err
}
2017-11-07 11:40:44 +08:00
}
}
}
2018-04-09 11:58:16 +08:00
//set app port
2017-11-07 11:40:44 +08:00
if len ( ports ) > 0 {
for _ , port := range ports {
port . ServiceID = ts . ServiceID
port . TenantID = ts . TenantID
if err := db . GetManager ( ) . TenantServicesPortDaoTransactions ( tx ) . AddModel ( & port ) ; err != nil {
logrus . Errorf ( "add port %v error, %v" , port . ContainerPort , err )
tx . Rollback ( )
return err
}
}
}
2018-04-09 11:58:16 +08:00
//set app volumns
2017-11-07 11:40:44 +08:00
if len ( volumns ) > 0 {
localPath := os . Getenv ( "LOCAL_DATA_PATH" )
sharePath := os . Getenv ( "SHARE_DATA_PATH" )
if localPath == "" {
localPath = "/grlocaldata"
}
if sharePath == "" {
sharePath = "/grdata"
}
for _ , volumn := range volumns {
2019-01-17 15:10:28 +08:00
v := dbmodel . TenantServiceVolume {
2021-02-06 17:53:02 +08:00
ServiceID : ts . ServiceID ,
Category : volumn . Category ,
VolumeType : volumn . VolumeType ,
VolumeName : volumn . VolumeName ,
HostPath : volumn . HostPath ,
VolumePath : volumn . VolumePath ,
IsReadOnly : volumn . IsReadOnly ,
VolumeCapacity : volumn . VolumeCapacity ,
// AccessMode 读写模式( Important! A volume can only be mounted using one access mode at a time, even if it supports many. For example, a GCEPersistentDisk can be mounted as ReadWriteOnce by a single node or ReadOnlyMany by many nodes, but not at the same time. #https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes)
AccessMode : volumn . AccessMode ,
// SharePolicy 共享模式
SharePolicy : volumn . SharePolicy ,
// BackupPolicy 备份策略
BackupPolicy : volumn . BackupPolicy ,
// ReclaimPolicy 回收策略
ReclaimPolicy : volumn . ReclaimPolicy ,
// AllowExpansion 是否支持扩展
AllowExpansion : volumn . AllowExpansion ,
// VolumeProviderName 使用的存储驱动别名
VolumeProviderName : volumn . VolumeProviderName ,
2019-01-17 15:10:28 +08:00
}
v . ServiceID = ts . ServiceID
2017-11-07 11:40:44 +08:00
if volumn . VolumeType == "" {
2019-01-17 15:10:28 +08:00
v . VolumeType = dbmodel . ShareFileVolumeType . String ( )
2017-11-07 11:40:44 +08:00
}
if volumn . HostPath == "" {
//step 1 设置主机目录
switch volumn . VolumeType {
2018-08-16 18:21:06 +08:00
//共享文件存储
2017-11-07 11:40:44 +08:00
case dbmodel . ShareFileVolumeType . String ( ) :
2019-01-17 15:10:28 +08:00
v . HostPath = fmt . Sprintf ( "%s/tenant/%s/service/%s%s" , sharePath , sc . TenantID , ts . ServiceID , volumn . VolumePath )
2018-10-11 11:25:19 +08:00
//本地文件存储
2017-11-07 11:40:44 +08:00
case dbmodel . LocalVolumeType . String ( ) :
2020-03-10 02:02:03 +08:00
if ! dbmodel . ServiceType ( sc . ExtendMethod ) . IsState ( ) {
2018-02-01 15:06:59 +08:00
tx . Rollback ( )
2020-03-10 19:23:14 +08:00
return util . CreateAPIHandleError ( 400 , fmt . Errorf ( "local volume type only support state component" ) )
2017-11-07 11:40:44 +08:00
}
2019-01-17 15:10:28 +08:00
v . HostPath = fmt . Sprintf ( "%s/tenant/%s/service/%s%s" , localPath , sc . TenantID , ts . ServiceID , volumn . VolumePath )
2020-03-10 02:02:03 +08:00
case dbmodel . ConfigFileVolumeType . String ( ) , dbmodel . MemoryFSVolumeType . String ( ) :
logrus . Debug ( "simple volume type : " , volumn . VolumeType )
default :
if ! dbmodel . ServiceType ( sc . ExtendMethod ) . IsState ( ) {
tx . Rollback ( )
2020-03-10 19:23:14 +08:00
return util . CreateAPIHandleError ( 400 , fmt . Errorf ( "custom volume type only support state component" ) )
2020-03-10 02:02:03 +08:00
}
2017-11-07 11:40:44 +08:00
}
}
if volumn . VolumeName == "" {
2019-01-17 15:10:28 +08:00
v . VolumeName = uuid . NewV4 ( ) . String ( )
2017-11-07 11:40:44 +08:00
}
2019-01-17 15:10:28 +08:00
if err := db . GetManager ( ) . TenantServiceVolumeDaoTransactions ( tx ) . AddModel ( & v ) ; err != nil {
2017-11-07 11:40:44 +08:00
logrus . Errorf ( "add volumn %v error, %v" , volumn . HostPath , err )
tx . Rollback ( )
return err
}
2019-01-17 15:10:28 +08:00
if volumn . FileContent != "" {
cf := & dbmodel . TenantServiceConfigFile {
2019-03-14 17:52:09 +08:00
ServiceID : sc . ServiceID ,
2019-01-17 15:10:28 +08:00
VolumeName : volumn . VolumeName ,
FileContent : volumn . FileContent ,
}
if err := db . GetManager ( ) . TenantServiceConfigFileDaoTransactions ( tx ) . AddModel ( cf ) ; err != nil {
tx . Rollback ( )
return util . CreateAPIHandleErrorFromDBError ( "error creating config file" , err )
}
}
2017-11-07 11:40:44 +08:00
}
}
2018-04-09 11:58:16 +08:00
//set app dependVolumes
2018-03-13 16:55:53 +08:00
if len ( dependVolumes ) > 0 {
for _ , depVolume := range dependVolumes {
depVolume . ServiceID = ts . ServiceID
depVolume . TenantID = ts . TenantID
volume , err := db . GetManager ( ) . TenantServiceVolumeDao ( ) . GetVolumeByServiceIDAndName ( depVolume . DependServiceID , depVolume . VolumeName )
if err != nil {
tx . Rollback ( )
return fmt . Errorf ( "find volume %s error %s" , depVolume . VolumeName , err . Error ( ) )
}
2019-10-10 15:39:27 +08:00
depVolume . VolumeType = volume . VolumeType
2018-03-13 16:55:53 +08:00
depVolume . HostPath = volume . HostPath
if err := db . GetManager ( ) . TenantServiceMountRelationDaoTransactions ( tx ) . AddModel ( & depVolume ) ; err != nil {
tx . Rollback ( )
return fmt . Errorf ( "add dep volume %s error %s" , depVolume . VolumeName , err . Error ( ) )
}
}
}
2018-04-09 11:58:16 +08:00
//set app depends
2017-11-07 11:40:44 +08:00
if len ( dependIds ) > 0 {
for _ , id := range dependIds {
if err := db . GetManager ( ) . TenantServiceRelationDaoTransactions ( tx ) . AddModel ( & id ) ; err != nil {
logrus . Errorf ( "add depend_id %v error, %v" , id . DependServiceID , err )
tx . Rollback ( )
return err
}
}
}
2018-04-09 11:58:16 +08:00
//set app label
2020-02-18 17:23:51 +08:00
if sc . OSType == "windows" {
if err := db . GetManager ( ) . TenantServiceLabelDaoTransactions ( tx ) . AddModel ( & dbmodel . TenantServiceLable {
ServiceID : ts . ServiceID ,
LabelKey : core_model . LabelKeyNodeSelector ,
LabelValue : sc . OSType ,
} ) ; err != nil {
logrus . Errorf ( "add label %s=%s %v error, %v" , core_model . LabelKeyNodeSelector , sc . OSType , ts . ServiceID , err )
tx . Rollback ( )
return err
}
2017-11-07 11:40:44 +08:00
}
2019-02-25 01:07:37 +08:00
// sc.Endpoints can't be nil
// sc.Endpoints.Discovery or sc.Endpoints.Static can't be nil
2019-03-06 15:27:28 +08:00
if sc . Kind == dbmodel . ServiceKindThirdParty . String ( ) { // TODO: validate request data
2019-06-20 18:01:05 +08:00
if sc . Endpoints == nil {
2020-06-29 21:12:04 +08:00
tx . Rollback ( )
2019-06-20 18:01:05 +08:00
return fmt . Errorf ( "endpoints can not be empty for third-party service" )
}
2019-02-26 16:39:27 +08:00
if config := strings . Replace ( sc . Endpoints . Discovery , " " , "" , - 1 ) ; config != "" {
var cfg dCfg
err := json . Unmarshal ( [ ] byte ( config ) , & cfg )
if err != nil {
2019-02-25 10:57:01 +08:00
tx . Rollback ( )
return err
2019-02-25 01:07:37 +08:00
}
2019-02-28 11:50:54 +08:00
c := & dbmodel . ThirdPartySvcDiscoveryCfg {
2019-02-26 16:39:27 +08:00
ServiceID : sc . ServiceID ,
Type : cfg . Type ,
Servers : strings . Join ( cfg . Servers , "," ) ,
Key : cfg . Key ,
Username : cfg . Username ,
Password : cfg . Password ,
}
2019-02-28 11:50:54 +08:00
if err := db . GetManager ( ) . ThirdPartySvcDiscoveryCfgDaoTransactions ( tx ) .
2019-02-26 16:39:27 +08:00
AddModel ( c ) ; err != nil {
2019-02-25 01:07:37 +08:00
logrus . Errorf ( "error saving discover center configuration: %v" , err )
tx . Rollback ( )
return err
}
2019-02-26 16:39:27 +08:00
} else if static := strings . Replace ( sc . Endpoints . Static , " " , "" , - 1 ) ; static != "" {
2019-02-25 10:57:01 +08:00
var obj [ ] string
2019-02-26 16:39:27 +08:00
err := json . Unmarshal ( [ ] byte ( static ) , & obj )
2019-02-25 10:57:01 +08:00
if err != nil {
tx . Rollback ( )
return err
}
2019-02-27 00:26:55 +08:00
trueValue := true
2019-02-25 10:57:01 +08:00
for _ , o := range obj {
2019-02-25 01:07:37 +08:00
ep := & dbmodel . Endpoint {
ServiceID : sc . ServiceID ,
UUID : core_util . NewUUID ( ) ,
2019-02-27 00:26:55 +08:00
IsOnline : & trueValue ,
2019-02-25 01:07:37 +08:00
}
2019-09-19 21:08:01 +08:00
address := o
port := 0
prefix := ""
if strings . HasPrefix ( address , "https://" ) {
address = strings . Split ( address , "https://" ) [ 1 ]
prefix = "https://"
}
if strings . HasPrefix ( address , "http://" ) {
address = strings . Split ( address , "http://" ) [ 1 ]
prefix = "http://"
}
if strings . Contains ( address , ":" ) {
addressL := strings . Split ( address , ":" )
address = addressL [ 0 ]
port , _ = strconv . Atoi ( addressL [ 1 ] )
2019-02-25 01:07:37 +08:00
}
2019-09-19 21:08:01 +08:00
ep . IP = prefix + address
ep . Port = port
2019-09-17 18:19:34 +08:00
logrus . Debugf ( "add new endpoint: %v" , ep )
2019-02-25 01:07:37 +08:00
if err := db . GetManager ( ) . EndpointsDaoTransactions ( tx ) . AddModel ( ep ) ; err != nil {
tx . Rollback ( )
2019-02-25 10:57:01 +08:00
logrus . Errorf ( "error saving o endpoint: %v" , err )
2019-02-25 01:07:37 +08:00
return err
}
}
}
}
// TODO: create default probe for third-party service.
2018-02-01 15:06:59 +08:00
if err := tx . Commit ( ) . Error ; err != nil {
tx . Rollback ( )
return err
}
2018-04-09 11:58:16 +08:00
logrus . Debugf ( "create a new app %s success" , ts . ServiceAlias )
2017-11-07 11:40:44 +08:00
return nil
}
//ServiceUpdate update service
func ( s * ServiceAction ) ServiceUpdate ( sc map [ string ] interface { } ) error {
ts , err := db . GetManager ( ) . TenantServiceDao ( ) . GetServiceByID ( sc [ "service_id" ] . ( string ) )
if err != nil {
return err
}
2018-11-22 14:33:29 +08:00
version , err := db . GetManager ( ) . VersionInfoDao ( ) . GetVersionByDeployVersion ( ts . DeployVersion , ts . ServiceID )
2020-09-29 18:46:22 +08:00
if memory , ok := sc [ "container_memory" ] . ( int ) ; ok && memory != 0 {
ts . ContainerMemory = memory
2017-11-07 11:40:44 +08:00
}
2020-09-29 18:46:22 +08:00
if name , ok := sc [ "service_name" ] . ( string ) ; ok && name != "" {
ts . ServiceName = name
2018-11-27 14:50:30 +08:00
}
2020-11-24 10:35:41 +08:00
if appID , ok := sc [ "app_id" ] . ( string ) ; ok && appID != "" {
ts . AppID = appID
}
2020-02-20 16:15:40 +08:00
if sc [ "extend_method" ] != nil {
extendMethod := sc [ "extend_method" ] . ( string )
2020-03-05 18:39:38 +08:00
ts . ExtendMethod = extendMethod
// if component replicas is more than 1, so can't change service type to singleton
if ts . Replicas > 1 && ts . IsSingleton ( ) {
2020-02-20 16:15:40 +08:00
err := fmt . Errorf ( "service[%s] replicas > 1, can't change service typ to stateless_singleton" , ts . ServiceAlias )
return err
}
volumes , err := db . GetManager ( ) . TenantServiceVolumeDao ( ) . GetTenantServiceVolumesByServiceID ( ts . ServiceID )
if err != nil {
return err
}
for _ , vo := range volumes {
2020-02-20 17:51:48 +08:00
if vo . VolumeType == dbmodel . ShareFileVolumeType . String ( ) || vo . VolumeType == dbmodel . MemoryFSVolumeType . String ( ) {
continue
}
2020-03-05 18:39:38 +08:00
if vo . VolumeType == dbmodel . LocalVolumeType . String ( ) && ! ts . IsState ( ) {
2020-02-20 16:15:40 +08:00
err := fmt . Errorf ( "service[%s] has local volume type, can't change type to stateless" , ts . ServiceAlias )
return err
}
2020-03-05 18:39:38 +08:00
// if component use volume, what it accessMode is rwo, can't change volume type to stateless
if vo . AccessMode == "RWO" && ! ts . IsState ( ) {
2020-02-20 16:15:40 +08:00
err := fmt . Errorf ( "service[%s] volume[%s] access_mode is RWO, can't change type to stateless" , ts . ServiceAlias , vo . VolumeName )
return err
}
}
2020-02-20 17:51:48 +08:00
ts . ExtendMethod = extendMethod
2020-02-20 16:15:40 +08:00
ts . ServiceType = extendMethod
}
2018-11-22 14:33:29 +08:00
//update service
2017-11-07 11:40:44 +08:00
if err := db . GetManager ( ) . TenantServiceDao ( ) . UpdateModel ( ts ) ; err != nil {
logrus . Errorf ( "update service error, %v" , err )
return err
}
2018-11-22 14:33:29 +08:00
//update service version
2020-02-20 23:27:48 +08:00
if version != nil {
if err := db . GetManager ( ) . VersionInfoDao ( ) . UpdateModel ( version ) ; err != nil {
logrus . Errorf ( "update version error, %v" , err )
return err
}
2018-11-22 14:33:29 +08:00
}
2017-11-07 11:40:44 +08:00
return nil
}
//LanguageSet language set
func ( s * ServiceAction ) LanguageSet ( langS * api_model . LanguageSet ) error {
logrus . Debugf ( "service id is %s, language is %s" , langS . ServiceID , langS . Language )
services , err := db . GetManager ( ) . TenantServiceDao ( ) . GetServiceByID ( langS . ServiceID )
if err != nil {
logrus . Errorf ( "get service by id error, %v, %v" , services , err )
return err
}
if langS . Language == "java" {
services . ContainerMemory = 512
if err := db . GetManager ( ) . TenantServiceDao ( ) . UpdateModel ( services ) ; err != nil {
logrus . Errorf ( "update tenant service error %v" , err )
return err
}
}
return nil
}
//GetService get service(s)
func ( s * ServiceAction ) GetService ( tenantID string ) ( [ ] * dbmodel . TenantServices , error ) {
services , err := db . GetManager ( ) . TenantServiceDao ( ) . GetServicesAllInfoByTenantID ( tenantID )
if err != nil {
logrus . Errorf ( "get service by id error, %v, %v" , services , err )
return nil , err
}
2018-07-16 15:30:53 +08:00
var serviceIDs [ ] string
for _ , s := range services {
serviceIDs = append ( serviceIDs , s . ServiceID )
}
status := s . statusCli . GetStatuss ( strings . Join ( serviceIDs , "," ) )
for _ , s := range services {
if status , ok := status [ s . ServiceID ] ; ok {
s . CurStatus = status
}
}
2017-11-07 11:40:44 +08:00
return services , nil
}
2020-09-18 17:02:28 +08:00
//GetServicesByAppID get service(s) by appID
2020-09-19 22:06:53 +08:00
func ( s * ServiceAction ) GetServicesByAppID ( appID string , page , pageSize int ) ( * api_model . ListServiceResponse , error ) {
var resp api_model . ListServiceResponse
2020-09-18 17:02:28 +08:00
services , total , err := db . GetManager ( ) . TenantServiceDao ( ) . GetServicesInfoByAppID ( appID , page , pageSize )
if err != nil {
logrus . Errorf ( "get service by application id error, %v, %v" , services , err )
2020-09-19 22:06:53 +08:00
return nil , err
2020-09-18 17:02:28 +08:00
}
var serviceIDs [ ] string
for _ , s := range services {
serviceIDs = append ( serviceIDs , s . ServiceID )
}
status := s . statusCli . GetStatuss ( strings . Join ( serviceIDs , "," ) )
for _ , s := range services {
if status , ok := status [ s . ServiceID ] ; ok {
s . CurStatus = status
}
}
2020-09-19 22:06:53 +08:00
if services != nil {
resp . Services = services
} else {
resp . Services = make ( [ ] * dbmodel . TenantServices , 0 )
}
resp . Page = page
resp . Total = total
resp . PageSize = pageSize
return & resp , nil
2020-09-18 17:02:28 +08:00
}
2017-12-15 16:49:24 +08:00
//GetPagedTenantRes get pagedTenantServiceRes(s)
2018-05-24 09:41:47 +08:00
func ( s * ServiceAction ) GetPagedTenantRes ( offset , len int ) ( [ ] * api_model . TenantResource , int , error ) {
2018-05-23 18:58:31 +08:00
allstatus := s . statusCli . GetAllStatus ( )
var serviceIDs [ ] string
for k , v := range allstatus {
if ! s . statusCli . IsClosedStatus ( v ) {
serviceIDs = append ( serviceIDs , k )
}
}
2018-05-24 09:41:47 +08:00
services , count , err := db . GetManager ( ) . TenantServiceDao ( ) . GetPagedTenantService ( offset , len , serviceIDs )
2017-12-15 16:49:24 +08:00
if err != nil {
logrus . Errorf ( "get service by id error, %v, %v" , services , err )
2018-05-24 09:41:47 +08:00
return nil , count , err
2017-12-15 16:49:24 +08:00
}
var result [ ] * api_model . TenantResource
2017-12-18 14:11:43 +08:00
for _ , v := range services {
2017-12-15 16:49:24 +08:00
var res api_model . TenantResource
2018-05-23 19:55:49 +08:00
res . UUID , _ = v [ "tenant" ] . ( string )
res . Name , _ = v [ "tenant_name" ] . ( string )
res . EID , _ = v [ "eid" ] . ( string )
res . AllocatedCPU , _ = v [ "capcpu" ] . ( int )
res . AllocatedMEM , _ = v [ "capmem" ] . ( int )
res . UsedCPU , _ = v [ "usecpu" ] . ( int )
res . UsedMEM , _ = v [ "usemem" ] . ( int )
2017-12-18 14:11:43 +08:00
result = append ( result , & res )
2017-12-15 16:49:24 +08:00
}
2018-05-24 09:41:47 +08:00
return result , count , nil
2017-12-15 16:49:24 +08:00
}
2017-12-25 11:14:02 +08:00
//GetTenantRes get pagedTenantServiceRes(s)
2017-12-15 16:49:24 +08:00
func ( s * ServiceAction ) GetTenantRes ( uuid string ) ( * api_model . TenantResource , error ) {
2019-01-28 16:00:51 +08:00
tenant , err := db . GetManager ( ) . TenantDao ( ) . GetTenantByUUID ( uuid )
if err != nil {
logrus . Errorf ( "get tenant %s info failure %v" , uuid , err . Error ( ) )
return nil , err
}
2018-04-27 16:35:20 +08:00
services , err := db . GetManager ( ) . TenantServiceDao ( ) . GetServicesByTenantID ( uuid )
2017-12-15 16:49:24 +08:00
if err != nil {
2019-01-28 16:00:51 +08:00
logrus . Errorf ( "get service by id error, %v, %v" , services , err . Error ( ) )
2017-12-15 16:49:24 +08:00
return nil , err
}
2018-04-27 16:35:20 +08:00
var serviceIDs string
var AllocatedCPU , AllocatedMEM int
for _ , ser := range services {
if serviceIDs == "" {
serviceIDs += ser . ServiceID
} else {
serviceIDs += "," + ser . ServiceID
}
2019-01-28 16:25:02 +08:00
AllocatedCPU += ser . ContainerCPU * ser . Replicas
AllocatedMEM += ser . ContainerMemory * ser . Replicas
2018-04-27 16:35:20 +08:00
}
2020-07-22 18:52:24 +08:00
tenantResUesd , err := s . statusCli . GetTenantResource ( uuid )
if err != nil {
logrus . Errorf ( "get tenant %s resource failure %s" , uuid , err . Error ( ) )
}
2020-09-28 16:43:27 +08:00
disks := GetServicesDiskDeprecated ( strings . Split ( serviceIDs , "," ) , s . prometheusCli )
2018-07-16 15:30:53 +08:00
var value float64
for _ , v := range disks {
value += v
}
2017-12-15 16:49:24 +08:00
var res api_model . TenantResource
2017-12-18 14:11:43 +08:00
res . UUID = uuid
2019-01-28 16:00:51 +08:00
res . Name = tenant . Name
res . EID = tenant . EID
2018-04-27 16:35:20 +08:00
res . AllocatedCPU = AllocatedCPU
res . AllocatedMEM = AllocatedMEM
2020-07-22 18:52:24 +08:00
if tenantResUesd != nil {
res . UsedCPU = int ( tenantResUesd . CpuRequest )
res . UsedMEM = int ( tenantResUesd . MemoryRequest )
}
2018-07-16 15:30:53 +08:00
res . UsedDisk = value
2017-12-15 16:49:24 +08:00
return & res , nil
}
2020-09-28 16:43:27 +08:00
//GetServicesDiskDeprecated get service disk
//
// Deprecated
func GetServicesDiskDeprecated ( ids [ ] string , prometheusCli prometheus . Interface ) map [ string ] float64 {
2019-01-25 23:34:12 +08:00
result := make ( map [ string ] float64 )
//query disk used in prometheus
query := fmt . Sprintf ( ` max(app_resource_appfs { service_id=~"%s"}) by(service_id) ` , strings . Join ( ids , "|" ) )
2020-09-24 21:09:00 +08:00
metric := prometheusCli . GetMetric ( query , time . Now ( ) )
for _ , re := range metric . MetricData . MetricValues {
var serviceID = re . Metadata [ "service_id" ]
if re . Sample != nil {
result [ serviceID ] = re . Sample . Value ( )
2019-01-25 23:34:12 +08:00
}
}
return result
}
2017-11-07 11:40:44 +08:00
//CodeCheck code check
func ( s * ServiceAction ) CodeCheck ( c * api_model . CheckCodeStruct ) error {
2018-12-04 18:08:51 +08:00
err := s . MQClient . SendBuilderTopic ( gclient . TaskStruct {
2017-11-07 11:40:44 +08:00
TaskType : "code_check" ,
2018-12-04 18:08:51 +08:00
TaskBody : c . Body ,
2018-12-06 12:17:27 +08:00
Topic : gclient . BuilderTopic ,
2018-12-04 18:08:51 +08:00
} )
2017-11-07 11:40:44 +08:00
if err != nil {
logrus . Errorf ( "equque mq error, %v" , err )
return err
}
return nil
}
//ServiceDepend service depend
func ( s * ServiceAction ) ServiceDepend ( action string , ds * api_model . DependService ) error {
switch action {
case "add" :
tsr := & dbmodel . TenantServiceRelation {
TenantID : ds . TenantID ,
ServiceID : ds . ServiceID ,
DependServiceID : ds . DepServiceID ,
DependServiceType : ds . DepServiceType ,
DependOrder : 1 ,
}
if err := db . GetManager ( ) . TenantServiceRelationDao ( ) . AddModel ( tsr ) ; err != nil {
logrus . Errorf ( "add depend error, %v" , err )
return err
}
case "delete" :
logrus . Debugf ( "serviceid is %v, depid is %v" , ds . ServiceID , ds . DepServiceID )
if err := db . GetManager ( ) . TenantServiceRelationDao ( ) . DeleteRelationByDepID ( ds . ServiceID , ds . DepServiceID ) ; err != nil {
logrus . Errorf ( "delete depend error, %v" , err )
return err
}
}
return nil
}
//EnvAttr env attr
func ( s * ServiceAction ) EnvAttr ( action string , at * dbmodel . TenantServiceEnvVar ) error {
switch action {
case "add" :
if err := db . GetManager ( ) . TenantServiceEnvVarDao ( ) . AddModel ( at ) ; err != nil {
logrus . Errorf ( "add env %v error, %v" , at . AttrName , err )
return err
}
case "delete" :
if err := db . GetManager ( ) . TenantServiceEnvVarDao ( ) . DeleteModel ( at . ServiceID , at . AttrName ) ; err != nil {
logrus . Errorf ( "delete env %v error, %v" , at . AttrName , err )
return err
}
2018-03-26 17:58:46 +08:00
case "update" :
2018-03-31 12:53:50 +08:00
if err := db . GetManager ( ) . TenantServiceEnvVarDao ( ) . UpdateModel ( at ) ; err != nil {
logrus . Errorf ( "update env %v error,%v" , at . AttrName , err )
2018-03-26 17:58:46 +08:00
return err
2018-03-31 12:53:50 +08:00
}
2017-11-07 11:40:44 +08:00
}
return nil
}
2020-10-22 15:35:26 +08:00
// CreatePorts -
func ( s * ServiceAction ) CreatePorts ( tenantID , serviceID string , vps * api_model . ServicePorts ) error {
tx := db . GetManager ( ) . Begin ( )
defer func ( ) {
if r := recover ( ) ; r != nil {
logrus . Errorf ( "Unexpected panic occurred, rollback transaction: %v" , r )
tx . Rollback ( )
}
} ( )
for _ , vp := range vps . Port {
// make sure K8sServiceName is unique
if vp . K8sServiceName != "" {
port , err := db . GetManager ( ) . TenantServicesPortDao ( ) . GetByTenantAndName ( tenantID , vp . K8sServiceName )
if err != nil && err != gorm . ErrRecordNotFound {
tx . Rollback ( )
return err
}
if port != nil {
tx . Rollback ( )
return bcode . ErrK8sServiceNameExists
}
}
var vpD dbmodel . TenantServicesPort
vpD . ServiceID = serviceID
vpD . TenantID = tenantID
vpD . IsInnerService = & vp . IsInnerService
vpD . IsOuterService = & vp . IsOuterService
vpD . ContainerPort = vp . ContainerPort
vpD . MappingPort = vp . MappingPort
vpD . Protocol = vp . Protocol
vpD . PortAlias = vp . PortAlias
vpD . K8sServiceName = vp . K8sServiceName
if err := db . GetManager ( ) . TenantServicesPortDaoTransactions ( tx ) . AddModel ( & vpD ) ; err != nil {
tx . Rollback ( )
return err
}
}
if err := tx . Commit ( ) . Error ; err != nil {
tx . Rollback ( )
return err
}
return nil
}
2017-11-07 11:40:44 +08:00
//PortVar port var
2017-11-30 18:55:11 +08:00
func ( s * ServiceAction ) PortVar ( action , tenantID , serviceID string , vps * api_model . ServicePorts , oldPort int ) error {
crt , err := db . GetManager ( ) . TenantServicePluginRelationDao ( ) . CheckSomeModelPluginByServiceID (
serviceID ,
2019-06-14 15:19:53 +08:00
dbmodel . InBoundNetPlugin ,
2017-11-30 18:55:11 +08:00
)
if err != nil {
return err
}
2017-11-07 11:40:44 +08:00
switch action {
case "delete" :
2017-11-30 18:55:11 +08:00
tx := db . GetManager ( ) . Begin ( )
2019-08-11 17:21:34 +08:00
defer func ( ) {
if r := recover ( ) ; r != nil {
logrus . Errorf ( "Unexpected panic occurred, rollback transaction: %v" , r )
tx . Rollback ( )
}
} ( )
2017-11-07 11:40:44 +08:00
for _ , vp := range vps . Port {
2017-11-30 18:55:11 +08:00
if err := db . GetManager ( ) . TenantServicesPortDaoTransactions ( tx ) . DeleteModel ( serviceID , vp . ContainerPort ) ; err != nil {
2017-11-07 11:40:44 +08:00
logrus . Errorf ( "delete port var error, %v" , err )
2017-11-30 18:55:11 +08:00
tx . Rollback ( )
2017-11-07 11:40:44 +08:00
return err
}
}
2017-11-30 18:55:11 +08:00
if err := tx . Commit ( ) . Error ; err != nil {
tx . Rollback ( )
logrus . Debugf ( "commit delete port error, %v" , err )
return err
}
2017-11-07 11:40:44 +08:00
case "update" :
2017-11-30 18:55:11 +08:00
tx := db . GetManager ( ) . Begin ( )
2019-08-11 17:21:34 +08:00
defer func ( ) {
if r := recover ( ) ; r != nil {
logrus . Errorf ( "Unexpected panic occurred, rollback transaction: %v" , r )
tx . Rollback ( )
}
} ( )
2017-11-07 11:40:44 +08:00
for _ , vp := range vps . Port {
2017-11-30 18:55:11 +08:00
//port更新单个请求
2017-12-01 18:54:53 +08:00
if oldPort == 0 {
oldPort = vp . ContainerPort
}
2017-11-30 18:55:11 +08:00
vpD , err := db . GetManager ( ) . TenantServicesPortDao ( ) . GetPort ( serviceID , oldPort )
2017-11-07 11:40:44 +08:00
if err != nil {
2018-02-01 15:06:59 +08:00
tx . Rollback ( )
2017-11-07 11:40:44 +08:00
return err
}
2020-10-22 15:35:26 +08:00
// make sure K8sServiceName is unique
if vp . K8sServiceName != "" {
port , err := db . GetManager ( ) . TenantServicesPortDao ( ) . GetByTenantAndName ( tenantID , vp . K8sServiceName )
if err != nil && err != gorm . ErrRecordNotFound {
tx . Rollback ( )
return err
}
if port != nil && vpD . K8sServiceName != vp . K8sServiceName {
tx . Rollback ( )
return bcode . ErrK8sServiceNameExists
}
}
2017-11-07 11:40:44 +08:00
vpD . ServiceID = serviceID
vpD . TenantID = tenantID
2019-05-18 17:59:35 +08:00
vpD . IsInnerService = & vp . IsInnerService
vpD . IsOuterService = & vp . IsOuterService
2017-11-07 11:40:44 +08:00
vpD . ContainerPort = vp . ContainerPort
vpD . MappingPort = vp . MappingPort
vpD . Protocol = vp . Protocol
vpD . PortAlias = vp . PortAlias
2020-10-22 15:35:26 +08:00
vpD . K8sServiceName = vp . K8sServiceName
2017-11-30 18:55:11 +08:00
if err := db . GetManager ( ) . TenantServicesPortDaoTransactions ( tx ) . UpdateModel ( vpD ) ; err != nil {
2017-11-07 11:40:44 +08:00
logrus . Errorf ( "update port var error, %v" , err )
2017-11-30 18:55:11 +08:00
tx . Rollback ( )
2017-11-07 11:40:44 +08:00
return err
}
2017-11-30 18:55:11 +08:00
if crt {
pluginPort , err := db . GetManager ( ) . TenantServicesStreamPluginPortDao ( ) . GetPluginMappingPortByServiceIDAndContainerPort (
serviceID ,
2019-06-14 15:19:53 +08:00
dbmodel . InBoundNetPlugin ,
2017-11-30 18:55:11 +08:00
oldPort ,
)
2017-12-28 13:44:31 +08:00
goon := true
2017-11-30 18:55:11 +08:00
if err != nil {
2017-12-28 13:44:31 +08:00
if strings . Contains ( err . Error ( ) , "record not found" ) {
goon = false
} else {
logrus . Errorf ( "get plugin mapping port error:(%s)" , err )
tx . Rollback ( )
return err
}
2017-11-30 18:55:11 +08:00
}
2017-12-28 13:44:31 +08:00
if goon {
pluginPort . ContainerPort = vp . ContainerPort
if err := db . GetManager ( ) . TenantServicesStreamPluginPortDaoTransactions ( tx ) . UpdateModel ( pluginPort ) ; err != nil {
logrus . Errorf ( "update plugin mapping port error:(%s)" , err )
tx . Rollback ( )
return err
}
2017-11-30 18:55:11 +08:00
}
}
}
if err := tx . Commit ( ) . Error ; err != nil {
tx . Rollback ( )
logrus . Debugf ( "commit update port error, %v" , err )
return err
2017-11-07 11:40:44 +08:00
}
}
return nil
}
//PortOuter 端口对外服务操作
2018-12-07 19:40:28 +08:00
func ( s * ServiceAction ) PortOuter ( tenantName , serviceID string , containerPort int ,
servicePort * api_model . ServicePortInnerOrOuter ) ( * dbmodel . TenantServiceLBMappingPort , string , error ) {
p , err := db . GetManager ( ) . TenantServicesPortDao ( ) . GetPort ( serviceID , containerPort )
2017-11-07 11:40:44 +08:00
if err != nil {
return nil , "" , fmt . Errorf ( "find service port error:%s" , err . Error ( ) )
}
2018-11-22 14:33:29 +08:00
_ , err = db . GetManager ( ) . TenantServiceDao ( ) . GetServiceByID ( serviceID )
2017-11-07 11:40:44 +08:00
if err != nil {
return nil , "" , fmt . Errorf ( "find service error:%s" , err . Error ( ) )
}
2017-11-30 15:03:10 +08:00
hasUpStream , err := db . GetManager ( ) . TenantServicePluginRelationDao ( ) . CheckSomeModelPluginByServiceID (
serviceID ,
2019-06-14 15:19:53 +08:00
dbmodel . InBoundNetPlugin ,
2017-11-30 15:03:10 +08:00
)
if err != nil {
return nil , "" , fmt . Errorf ( "get plugin relations error: %s" , err . Error ( ) )
}
2017-11-07 11:40:44 +08:00
//if stream 创建vs端口
vsPort := & dbmodel . TenantServiceLBMappingPort { }
2018-12-07 19:40:28 +08:00
switch servicePort . Body . Operation {
2017-11-07 11:40:44 +08:00
case "close" :
2019-05-18 17:59:35 +08:00
if * p . IsOuterService { //如果端口已经开了对外
falsev := false
p . IsOuterService = & falsev
2017-11-07 11:40:44 +08:00
tx := db . GetManager ( ) . Begin ( )
2019-08-11 17:21:34 +08:00
defer func ( ) {
if r := recover ( ) ; r != nil {
logrus . Errorf ( "Unexpected panic occurred, rollback transaction: %v" , r )
tx . Rollback ( )
}
} ( )
2017-11-07 11:40:44 +08:00
if err = db . GetManager ( ) . TenantServicesPortDaoTransactions ( tx ) . UpdateModel ( p ) ; err != nil {
2018-02-01 15:30:30 +08:00
tx . Rollback ( )
2017-11-07 11:40:44 +08:00
return nil , "" , err
}
2018-11-22 14:33:29 +08:00
2017-11-30 15:03:10 +08:00
if hasUpStream {
pluginPort , err := db . GetManager ( ) . TenantServicesStreamPluginPortDao ( ) . GetPluginMappingPortByServiceIDAndContainerPort (
serviceID ,
2019-06-14 15:19:53 +08:00
dbmodel . InBoundNetPlugin ,
2018-12-07 19:40:28 +08:00
containerPort ,
2017-11-30 15:03:10 +08:00
)
if err != nil {
if err . Error ( ) == gorm . ErrRecordNotFound . Error ( ) {
2018-12-07 19:40:28 +08:00
logrus . Debugf ( "outer, plugin port (%d) is not exist, do not need delete" , containerPort )
2017-11-30 15:03:10 +08:00
goto OUTERCLOSEPASS
}
2018-02-01 15:30:30 +08:00
tx . Rollback ( )
2017-11-30 15:03:10 +08:00
return nil , "" , fmt . Errorf ( "outer, get plugin mapping port error:(%s)" , err )
}
2019-05-18 17:59:35 +08:00
if * p . IsInnerService {
2017-11-30 15:35:14 +08:00
//发现内网未关闭则不删除该映射
2018-12-07 19:40:28 +08:00
logrus . Debugf ( "outer, close outer, but plugin inner port (%d) is exist, do not need delete" , containerPort )
2017-11-30 15:35:14 +08:00
goto OUTERCLOSEPASS
}
2017-11-30 15:03:10 +08:00
if err := db . GetManager ( ) . TenantServicesStreamPluginPortDaoTransactions ( tx ) . DeletePluginMappingPortByContainerPort (
serviceID ,
2019-06-14 15:19:53 +08:00
dbmodel . InBoundNetPlugin ,
2018-12-07 19:40:28 +08:00
containerPort ,
2017-11-30 15:03:10 +08:00
) ; err != nil {
2018-02-01 15:30:30 +08:00
tx . Rollback ( )
2018-12-07 19:40:28 +08:00
return nil , "" , fmt . Errorf ( "outer, delete plugin mapping port %d error:(%s)" , containerPort , err )
2017-11-30 15:03:10 +08:00
}
2018-12-07 19:40:28 +08:00
logrus . Debugf ( fmt . Sprintf ( "outer, delete plugin port %d->%d" , containerPort , pluginPort . PluginPort ) )
2017-11-30 15:03:10 +08:00
OUTERCLOSEPASS :
}
2017-11-07 11:40:44 +08:00
if err := tx . Commit ( ) . Error ; err != nil {
tx . Rollback ( )
return nil , "" , err
}
} else {
return nil , "" , nil
}
case "open" :
2019-05-18 17:59:35 +08:00
truev := true
p . IsOuterService = & truev
2017-11-07 11:40:44 +08:00
tx := db . GetManager ( ) . Begin ( )
2019-08-11 17:21:34 +08:00
defer func ( ) {
if r := recover ( ) ; r != nil {
logrus . Errorf ( "Unexpected panic occurred, rollback transaction: %v" , r )
tx . Rollback ( )
}
} ( )
2017-11-07 11:40:44 +08:00
if err = db . GetManager ( ) . TenantServicesPortDaoTransactions ( tx ) . UpdateModel ( p ) ; err != nil {
2018-02-01 15:30:30 +08:00
tx . Rollback ( )
2017-11-07 11:40:44 +08:00
return nil , "" , err
}
2017-11-30 15:03:10 +08:00
if hasUpStream {
pluginPort , err := db . GetManager ( ) . TenantServicesStreamPluginPortDao ( ) . GetPluginMappingPortByServiceIDAndContainerPort (
serviceID ,
2019-06-14 15:19:53 +08:00
dbmodel . InBoundNetPlugin ,
2018-12-07 19:40:28 +08:00
containerPort ,
2017-11-30 15:03:10 +08:00
)
var pPort int
if err != nil {
if err . Error ( ) == gorm . ErrRecordNotFound . Error ( ) {
ppPort , err := db . GetManager ( ) . TenantServicesStreamPluginPortDaoTransactions ( tx ) . SetPluginMappingPort (
p . TenantID ,
serviceID ,
2019-06-14 15:19:53 +08:00
dbmodel . InBoundNetPlugin ,
2018-12-07 19:40:28 +08:00
containerPort ,
2017-11-30 15:03:10 +08:00
)
if err != nil {
2018-02-01 15:30:30 +08:00
tx . Rollback ( )
2017-11-30 15:03:10 +08:00
logrus . Errorf ( "outer, set plugin mapping port error:(%s)" , err )
return nil , "" , fmt . Errorf ( "outer, set plugin mapping port error:(%s)" , err )
}
pPort = ppPort
goto OUTEROPENPASS
}
2018-02-01 15:30:30 +08:00
tx . Rollback ( )
2017-11-30 15:03:10 +08:00
return nil , "" , fmt . Errorf ( "outer, in setting plugin mapping port, get plugin mapping port error:(%s)" , err )
}
logrus . Debugf ( "outer, plugin mapping port is already exist, %d->%d" , pluginPort . ContainerPort , pluginPort . PluginPort )
OUTEROPENPASS :
2018-12-07 19:40:28 +08:00
logrus . Debugf ( "outer, set plugin mapping port %d->%d" , containerPort , pPort )
2017-11-30 15:03:10 +08:00
}
2017-11-07 11:40:44 +08:00
if err := tx . Commit ( ) . Error ; err != nil {
tx . Rollback ( )
return nil , "" , err
}
}
return vsPort , p . Protocol , nil
}
//PortInner 端口对内服务操作
2018-11-22 14:33:29 +08:00
//TODO: send task to worker
2017-11-07 11:40:44 +08:00
func ( s * ServiceAction ) PortInner ( tenantName , serviceID , operation string , port int ) error {
p , err := db . GetManager ( ) . TenantServicesPortDao ( ) . GetPort ( serviceID , port )
if err != nil {
return err
}
2018-11-22 14:33:29 +08:00
_ , err = db . GetManager ( ) . TenantServiceDao ( ) . GetServiceByID ( serviceID )
2017-11-07 11:40:44 +08:00
if err != nil {
return fmt . Errorf ( "get service error:%s" , err . Error ( ) )
}
2017-11-30 15:03:10 +08:00
hasUpStream , err := db . GetManager ( ) . TenantServicePluginRelationDao ( ) . CheckSomeModelPluginByServiceID (
serviceID ,
2019-06-14 15:19:53 +08:00
dbmodel . InBoundNetPlugin ,
2017-11-30 15:03:10 +08:00
)
if err != nil {
return fmt . Errorf ( "get plugin relations error: %s" , err . Error ( ) )
}
2017-11-07 11:40:44 +08:00
tx := db . GetManager ( ) . Begin ( )
2019-06-20 13:59:19 +08:00
defer func ( ) {
if r := recover ( ) ; r != nil {
logrus . Errorf ( "Unexpected panic occurred, rollback transaction: %v" , r )
tx . Rollback ( )
}
} ( )
2017-11-07 11:40:44 +08:00
switch operation {
case "close" :
2019-05-18 17:59:35 +08:00
if * p . IsInnerService { //如果端口已经开了对内
falsev := false
p . IsInnerService = & falsev
2017-11-07 11:40:44 +08:00
if err = db . GetManager ( ) . TenantServicesPortDaoTransactions ( tx ) . UpdateModel ( p ) ; err != nil {
2018-02-01 15:30:30 +08:00
tx . Rollback ( )
2017-11-07 11:40:44 +08:00
return fmt . Errorf ( "update service port error: %s" , err . Error ( ) )
}
2017-11-30 15:03:10 +08:00
if hasUpStream {
pluginPort , err := db . GetManager ( ) . TenantServicesStreamPluginPortDao ( ) . GetPluginMappingPortByServiceIDAndContainerPort (
serviceID ,
2019-06-14 15:19:53 +08:00
dbmodel . InBoundNetPlugin ,
2017-11-30 15:03:10 +08:00
port ,
)
if err != nil {
if err . Error ( ) == gorm . ErrRecordNotFound . Error ( ) {
2017-11-30 15:35:14 +08:00
logrus . Debugf ( "inner, plugin port (%d) is not exist, do not need delete" , port )
2017-11-30 15:03:10 +08:00
goto INNERCLOSEPASS
}
2018-02-01 15:30:30 +08:00
tx . Rollback ( )
2017-11-30 15:03:10 +08:00
return fmt . Errorf ( "inner, get plugin mapping port error:(%s)" , err )
}
2019-05-18 17:59:35 +08:00
if * p . IsOuterService {
2017-11-30 15:35:14 +08:00
logrus . Debugf ( "inner, close inner, but plugin outerport (%d) is exist, do not need delete" , port )
goto INNERCLOSEPASS
}
2017-11-30 15:03:10 +08:00
if err := db . GetManager ( ) . TenantServicesStreamPluginPortDaoTransactions ( tx ) . DeletePluginMappingPortByContainerPort (
serviceID ,
2019-06-14 15:19:53 +08:00
dbmodel . InBoundNetPlugin ,
2017-11-30 15:03:10 +08:00
port ,
) ; err != nil {
2018-02-01 15:30:30 +08:00
tx . Rollback ( )
2017-11-30 15:03:10 +08:00
return fmt . Errorf ( "inner, delete plugin mapping port %d error:(%s)" , port , err )
}
logrus . Debugf ( fmt . Sprintf ( "inner, delete plugin port %d->%d" , port , pluginPort . PluginPort ) )
INNERCLOSEPASS :
}
2017-11-07 11:40:44 +08:00
} else {
2018-02-01 15:30:30 +08:00
tx . Rollback ( )
2017-11-07 11:40:44 +08:00
return fmt . Errorf ( "already close" )
}
case "open" :
2019-05-18 17:59:35 +08:00
if * p . IsInnerService {
2018-02-01 15:30:30 +08:00
tx . Rollback ( )
2017-11-07 11:40:44 +08:00
return fmt . Errorf ( "already open" )
}
2019-05-18 17:59:35 +08:00
truv := true
p . IsInnerService = & truv
2017-11-07 11:40:44 +08:00
if err = db . GetManager ( ) . TenantServicesPortDaoTransactions ( tx ) . UpdateModel ( p ) ; err != nil {
2018-02-01 15:30:30 +08:00
tx . Rollback ( )
2017-11-07 11:40:44 +08:00
return err
}
2017-11-30 15:03:10 +08:00
if hasUpStream {
pluginPort , err := db . GetManager ( ) . TenantServicesStreamPluginPortDao ( ) . GetPluginMappingPortByServiceIDAndContainerPort (
serviceID ,
2019-06-14 15:19:53 +08:00
dbmodel . InBoundNetPlugin ,
2017-11-30 15:03:10 +08:00
port ,
)
var pPort int
if err != nil {
if err . Error ( ) == gorm . ErrRecordNotFound . Error ( ) {
ppPort , err := db . GetManager ( ) . TenantServicesStreamPluginPortDaoTransactions ( tx ) . SetPluginMappingPort (
p . TenantID ,
serviceID ,
2019-06-14 15:19:53 +08:00
dbmodel . InBoundNetPlugin ,
2017-11-30 15:03:10 +08:00
port ,
)
if err != nil {
2018-02-01 15:30:30 +08:00
tx . Rollback ( )
2017-11-30 15:03:10 +08:00
logrus . Errorf ( "inner, set plugin mapping port error:(%s)" , err )
return fmt . Errorf ( "inner, set plugin mapping port error:(%s)" , err )
}
pPort = ppPort
goto INNEROPENPASS
}
2018-02-01 15:30:30 +08:00
tx . Rollback ( )
2017-11-30 15:03:10 +08:00
return fmt . Errorf ( "inner, in setting plugin mapping port, get plugin mapping port error:(%s)" , err )
}
logrus . Debugf ( "inner, plugin mapping port is already exist, %d->%d" , pluginPort . ContainerPort , pluginPort . PluginPort )
INNEROPENPASS :
logrus . Debugf ( "inner, set plugin mapping port %d->%d" , port , pPort )
}
2017-11-07 11:40:44 +08:00
}
if err := tx . Commit ( ) . Error ; err != nil {
tx . Rollback ( )
return err
}
return nil
}
//VolumnVar var volumn
2019-01-07 16:10:40 +08:00
func ( s * ServiceAction ) VolumnVar ( tsv * dbmodel . TenantServiceVolume , tenantID , fileContent , action string ) * util . APIHandleError {
2017-11-07 11:40:44 +08:00
localPath := os . Getenv ( "LOCAL_DATA_PATH" )
sharePath := os . Getenv ( "SHARE_DATA_PATH" )
if localPath == "" {
localPath = "/grlocaldata"
}
if sharePath == "" {
sharePath = "/grdata"
}
2019-01-06 22:13:19 +08:00
2017-11-07 11:40:44 +08:00
switch action {
case "add" :
if tsv . HostPath == "" {
//step 1 设置主机目录
switch tsv . VolumeType {
//共享文件存储
case dbmodel . ShareFileVolumeType . String ( ) :
tsv . HostPath = fmt . Sprintf ( "%s/tenant/%s/service/%s%s" , sharePath , tenantID , tsv . ServiceID , tsv . VolumePath )
2019-08-11 17:21:34 +08:00
//本地文件存储
2017-11-07 11:40:44 +08:00
case dbmodel . LocalVolumeType . String ( ) :
2020-12-04 19:45:42 +08:00
serviceInfo , err := db . GetManager ( ) . TenantServiceDao ( ) . GetServiceTypeByID ( tsv . ServiceID )
2017-11-07 11:40:44 +08:00
if err != nil {
return util . CreateAPIHandleErrorFromDBError ( "service type" , err )
}
2020-03-05 18:39:38 +08:00
// local volume just only support state component
2020-02-20 17:51:48 +08:00
if serviceInfo == nil || ! serviceInfo . IsState ( ) {
2020-03-05 18:39:38 +08:00
return util . CreateAPIHandleError ( 400 , fmt . Errorf ( "应用类型为'无状态'.不支持本地存储" ) )
2017-11-07 11:40:44 +08:00
}
tsv . HostPath = fmt . Sprintf ( "%s/tenant/%s/service/%s%s" , localPath , tenantID , tsv . ServiceID , tsv . VolumePath )
}
}
2019-11-26 15:11:13 +08:00
util . SetVolumeDefaultValue ( tsv )
2019-01-06 22:13:19 +08:00
// begin transaction
tx := db . GetManager ( ) . Begin ( )
2019-08-11 17:21:34 +08:00
defer func ( ) {
if r := recover ( ) ; r != nil {
logrus . Errorf ( "Unexpected panic occurred, rollback transaction: %v" , r )
tx . Rollback ( )
}
} ( )
2019-01-06 22:13:19 +08:00
if err := db . GetManager ( ) . TenantServiceVolumeDaoTransactions ( tx ) . AddModel ( tsv ) ; err != nil {
tx . Rollback ( )
2017-11-07 11:40:44 +08:00
return util . CreateAPIHandleErrorFromDBError ( "add volume" , err )
}
2019-01-07 16:10:40 +08:00
if fileContent != "" {
cf := & dbmodel . TenantServiceConfigFile {
2019-03-06 14:06:42 +08:00
ServiceID : tsv . ServiceID ,
2019-01-07 18:26:18 +08:00
VolumeName : tsv . VolumeName ,
2019-01-07 16:10:40 +08:00
FileContent : fileContent ,
}
if err := db . GetManager ( ) . TenantServiceConfigFileDaoTransactions ( tx ) . AddModel ( cf ) ; err != nil {
tx . Rollback ( )
return util . CreateAPIHandleErrorFromDBError ( "error creating config file" , err )
}
2019-01-06 22:13:19 +08:00
}
// end transaction
if err := tx . Commit ( ) . Error ; err != nil {
tx . Rollback ( )
return util . CreateAPIHandleErrorFromDBError ( "error ending transaction" , err )
}
2017-11-07 11:40:44 +08:00
case "delete" :
2019-01-06 22:13:19 +08:00
// begin transaction
tx := db . GetManager ( ) . Begin ( )
2019-08-11 17:21:34 +08:00
defer func ( ) {
if r := recover ( ) ; r != nil {
logrus . Errorf ( "Unexpected panic occurred, rollback transaction: %v" , r )
tx . Rollback ( )
}
} ( )
2017-11-07 11:40:44 +08:00
if tsv . VolumeName != "" {
2019-11-01 19:09:45 +08:00
volume , err := db . GetManager ( ) . TenantServiceVolumeDaoTransactions ( tx ) . GetVolumeByServiceIDAndName ( tsv . ServiceID , tsv . VolumeName )
if err != nil {
tx . Rollback ( )
return util . CreateAPIHandleErrorFromDBError ( "find volume" , err )
}
if err := db . GetManager ( ) . TenantServiceVolumeDaoTransactions ( tx ) . DeleteModel ( tsv . ServiceID , tsv . VolumeName ) ; err != nil && err . Error ( ) != gorm . ErrRecordNotFound . Error ( ) {
2019-01-06 22:13:19 +08:00
tx . Rollback ( )
2017-11-07 11:40:44 +08:00
return util . CreateAPIHandleErrorFromDBError ( "delete volume" , err )
}
2019-11-01 19:09:45 +08:00
err = s . MQClient . SendBuilderTopic ( gclient . TaskStruct {
Topic : gclient . WorkerTopic ,
TaskType : "volume_gc" ,
TaskBody : map [ string ] interface { } {
"tenant_id" : tenantID ,
"service_id" : volume . ServiceID ,
"volume_id" : volume . ID ,
"volume_path" : volume . VolumePath ,
} ,
} )
if err != nil {
logrus . Errorf ( "send 'volume_gc' task: %v" , err )
tx . Rollback ( )
return util . CreateAPIHandleErrorFromDBError ( "send 'volume_gc' task" , err )
}
2017-11-07 11:40:44 +08:00
} else {
2019-01-26 01:26:11 +08:00
if err := db . GetManager ( ) . TenantServiceVolumeDaoTransactions ( tx ) . DeleteByServiceIDAndVolumePath ( tsv . ServiceID , tsv . VolumePath ) ; err != nil && err . Error ( ) != gorm . ErrRecordNotFound . Error ( ) {
2019-01-06 22:13:19 +08:00
tx . Rollback ( )
2017-11-07 11:40:44 +08:00
return util . CreateAPIHandleErrorFromDBError ( "delete volume" , err )
}
}
2019-03-06 14:06:42 +08:00
if err := db . GetManager ( ) . TenantServiceConfigFileDaoTransactions ( tx ) . DelByVolumeID ( tsv . ServiceID , tsv . VolumeName ) ; err != nil {
2019-01-06 22:13:19 +08:00
tx . Rollback ( )
return util . CreateAPIHandleErrorFromDBError ( "error deleting config files" , err )
}
// end transaction
if err := tx . Commit ( ) . Error ; err != nil {
tx . Rollback ( )
return util . CreateAPIHandleErrorFromDBError ( "error ending transaction" , err )
}
2017-11-07 11:40:44 +08:00
}
return nil
}
2019-03-06 14:06:42 +08:00
// UpdVolume updates service volume.
func ( s * ServiceAction ) UpdVolume ( sid string , req * api_model . UpdVolumeReq ) error {
tx := db . GetManager ( ) . Begin ( )
2019-06-20 13:59:19 +08:00
defer func ( ) {
if r := recover ( ) ; r != nil {
logrus . Errorf ( "Unexpected panic occurred, rollback transaction: %v" , r )
tx . Rollback ( )
}
} ( )
2019-12-13 11:31:08 +08:00
v , err := db . GetManager ( ) . TenantServiceVolumeDaoTransactions ( tx ) . GetVolumeByServiceIDAndName ( sid , req . VolumeName )
if err != nil {
tx . Rollback ( )
return err
}
v . VolumePath = req . VolumePath
if err := db . GetManager ( ) . TenantServiceVolumeDaoTransactions ( tx ) . UpdateModel ( v ) ; err != nil {
tx . Rollback ( )
return err
}
if req . VolumeType == "config-file" {
configfile , err := db . GetManager ( ) . TenantServiceConfigFileDaoTransactions ( tx ) . GetByVolumeName ( sid , req . VolumeName )
2019-08-11 17:21:34 +08:00
if err != nil {
tx . Rollback ( )
return err
}
2019-12-13 11:31:08 +08:00
configfile . FileContent = req . FileContent
if err := db . GetManager ( ) . TenantServiceConfigFileDaoTransactions ( tx ) . UpdateModel ( configfile ) ; err != nil {
2019-08-11 17:21:34 +08:00
tx . Rollback ( )
return err
}
2019-03-06 14:06:42 +08:00
}
tx . Commit ( )
return nil
}
2017-11-07 11:40:44 +08:00
//GetVolumes 获取应用全部存储
2019-12-16 13:54:50 +08:00
func ( s * ServiceAction ) GetVolumes ( serviceID string ) ( [ ] * api_model . VolumeWithStatusStruct , * util . APIHandleError ) {
volumeWithStatusList := make ( [ ] * api_model . VolumeWithStatusStruct , 0 )
vs , err := db . GetManager ( ) . TenantServiceVolumeDao ( ) . GetTenantServiceVolumesByServiceID ( serviceID )
2017-11-07 11:40:44 +08:00
if err != nil && err . Error ( ) != gorm . ErrRecordNotFound . Error ( ) {
return nil , util . CreateAPIHandleErrorFromDBError ( "get volumes" , err )
}
2019-12-16 13:54:50 +08:00
volumeStatusList , err := s . statusCli . GetAppVolumeStatus ( serviceID )
if err != nil {
logrus . Warnf ( "get volume status error: %s" , err . Error ( ) )
}
2019-12-18 10:49:37 +08:00
volumeStatus := make ( map [ string ] pb . ServiceVolumeStatus )
2019-12-16 13:54:50 +08:00
if volumeStatusList != nil && volumeStatusList . GetStatus ( ) != nil {
2019-12-18 10:49:37 +08:00
volumeStatus = volumeStatusList . GetStatus ( )
}
for _ , volume := range vs {
vws := & api_model . VolumeWithStatusStruct {
ServiceID : volume . ServiceID ,
Category : volume . Category ,
VolumeType : volume . VolumeType ,
VolumeName : volume . VolumeName ,
HostPath : volume . HostPath ,
VolumePath : volume . VolumePath ,
IsReadOnly : volume . IsReadOnly ,
VolumeCapacity : volume . VolumeCapacity ,
AccessMode : volume . AccessMode ,
SharePolicy : volume . SharePolicy ,
BackupPolicy : volume . BackupPolicy ,
ReclaimPolicy : volume . ReclaimPolicy ,
AllowExpansion : volume . AllowExpansion ,
VolumeProviderName : volume . VolumeProviderName ,
}
volumeID := strconv . FormatInt ( int64 ( volume . ID ) , 10 )
if phrase , ok := volumeStatus [ volumeID ] ; ok {
vws . Status = phrase . String ( )
} else {
vws . Status = pb . ServiceVolumeStatus_NOT_READY . String ( )
2019-12-16 13:54:50 +08:00
}
2019-12-18 10:49:37 +08:00
volumeWithStatusList = append ( volumeWithStatusList , vws )
2019-12-16 13:54:50 +08:00
}
return volumeWithStatusList , nil
2017-11-07 11:40:44 +08:00
}
//VolumeDependency VolumeDependency
func ( s * ServiceAction ) VolumeDependency ( tsr * dbmodel . TenantServiceMountRelation , action string ) * util . APIHandleError {
switch action {
case "add" :
if tsr . VolumeName != "" {
vm , err := db . GetManager ( ) . TenantServiceVolumeDao ( ) . GetVolumeByServiceIDAndName ( tsr . DependServiceID , tsr . VolumeName )
if err != nil {
return util . CreateAPIHandleErrorFromDBError ( "get volume" , err )
}
tsr . HostPath = vm . HostPath
if err := db . GetManager ( ) . TenantServiceMountRelationDao ( ) . AddModel ( tsr ) ; err != nil {
return util . CreateAPIHandleErrorFromDBError ( "add volume mount relation" , err )
}
} else {
if tsr . HostPath == "" {
return util . CreateAPIHandleError ( 400 , fmt . Errorf ( "host path can not be empty when create volume dependency in api v2" ) )
}
if err := db . GetManager ( ) . TenantServiceMountRelationDao ( ) . AddModel ( tsr ) ; err != nil {
return util . CreateAPIHandleErrorFromDBError ( "add volume mount relation" , err )
}
}
case "delete" :
if tsr . VolumeName != "" {
if err := db . GetManager ( ) . TenantServiceMountRelationDao ( ) . DElTenantServiceMountRelationByServiceAndName ( tsr . ServiceID , tsr . VolumeName ) ; err != nil {
return util . CreateAPIHandleErrorFromDBError ( "delete mount relation" , err )
}
} else {
if err := db . GetManager ( ) . TenantServiceMountRelationDao ( ) . DElTenantServiceMountRelationByDepService ( tsr . ServiceID , tsr . DependServiceID ) ; err != nil {
return util . CreateAPIHandleErrorFromDBError ( "delete mount relation" , err )
}
}
}
return nil
}
//GetDepVolumes 获取依赖存储
func ( s * ServiceAction ) GetDepVolumes ( serviceID string ) ( [ ] * dbmodel . TenantServiceMountRelation , * util . APIHandleError ) {
dbManager := db . GetManager ( )
mounts , err := dbManager . TenantServiceMountRelationDao ( ) . GetTenantServiceMountRelationsByService ( serviceID )
if err != nil {
return nil , util . CreateAPIHandleErrorFromDBError ( "get dep volume" , err )
}
return mounts , nil
}
//ServiceProbe ServiceProbe
2018-11-22 14:33:29 +08:00
func ( s * ServiceAction ) ServiceProbe ( tsp * dbmodel . TenantServiceProbe , action string ) error {
2017-11-07 11:40:44 +08:00
switch action {
case "add" :
if err := db . GetManager ( ) . ServiceProbeDao ( ) . AddModel ( tsp ) ; err != nil {
return err
}
case "update" :
2018-03-31 12:53:50 +08:00
if err := db . GetManager ( ) . ServiceProbeDao ( ) . UpdateModel ( tsp ) ; err != nil {
2017-11-07 11:40:44 +08:00
return err
}
case "delete" :
if err := db . GetManager ( ) . ServiceProbeDao ( ) . DeleteModel ( tsp . ServiceID , tsp . ProbeID ) ; err != nil {
return err
}
}
return nil
}
//RollBack RollBack
func ( s * ServiceAction ) RollBack ( rs * api_model . RollbackStruct ) error {
2019-03-05 12:05:55 +08:00
service , err := db . GetManager ( ) . TenantServiceDao ( ) . GetServiceByID ( rs . ServiceID )
2017-11-07 11:40:44 +08:00
if err != nil {
return err
}
2019-03-05 12:05:55 +08:00
oldDeployVersion := service . DeployVersion
2017-11-07 11:40:44 +08:00
if service . DeployVersion == rs . DeployVersion {
return fmt . Errorf ( "current version is %v, don't need rollback" , rs . DeployVersion )
}
service . DeployVersion = rs . DeployVersion
2019-03-05 12:05:55 +08:00
if err := db . GetManager ( ) . TenantServiceDao ( ) . UpdateModel ( service ) ; err != nil {
2017-11-07 11:40:44 +08:00
return err
}
//发送重启消息到MQ
startStopStruct := & api_model . StartStopStruct {
TenantID : rs . TenantID ,
ServiceID : rs . ServiceID ,
EventID : rs . EventID ,
2018-11-28 19:32:39 +08:00
TaskType : "rolling_upgrade" ,
2017-11-07 11:40:44 +08:00
}
if err := GetServiceManager ( ) . StartStopService ( startStopStruct ) ; err != nil {
2019-03-05 12:05:55 +08:00
// rollback
service . DeployVersion = oldDeployVersion
if err := db . GetManager ( ) . TenantServiceDao ( ) . UpdateModel ( service ) ; err != nil {
logrus . Warningf ( "error deploy version rollback: %v" , err )
}
2017-11-07 11:40:44 +08:00
return err
}
return nil
}
//GetStatus GetStatus
func ( s * ServiceAction ) GetStatus ( serviceID string ) ( * api_model . StatusList , error ) {
services , errS := db . GetManager ( ) . TenantServiceDao ( ) . GetServiceByID ( serviceID )
if errS != nil {
return nil , errS
}
sl := & api_model . StatusList {
TenantID : services . TenantID ,
ServiceID : serviceID ,
ServiceAlias : services . ServiceAlias ,
DeployVersion : services . DeployVersion ,
Replicas : services . Replicas ,
ContainerMem : services . ContainerMemory ,
ContainerCPU : services . ContainerCPU ,
CurStatus : services . CurStatus ,
StatusCN : TransStatus ( services . CurStatus ) ,
}
2018-04-03 18:21:46 +08:00
status := s . statusCli . GetStatus ( serviceID )
if status != "" {
sl . CurStatus = status
sl . StatusCN = TransStatus ( status )
2017-11-07 11:40:44 +08:00
}
2019-08-23 09:22:23 +08:00
di , err := s . statusCli . GetServiceDeployInfo ( serviceID )
if err != nil {
logrus . Warningf ( "service id: %s; failed to get deploy info: %v" , serviceID , err )
} else {
sl . StartTime = di . GetStartTime ( )
}
2017-11-07 11:40:44 +08:00
return sl , nil
}
//GetServicesStatus 获取一组应用状态,若 serviceIDs为空,获取租户所有应用状态
2020-02-25 20:03:21 +08:00
func ( s * ServiceAction ) GetServicesStatus ( tenantID string , serviceIDs [ ] string ) [ ] map [ string ] interface { } {
2017-11-07 11:40:44 +08:00
if serviceIDs == nil || len ( serviceIDs ) == 0 {
2018-04-03 18:21:46 +08:00
services , _ := db . GetManager ( ) . TenantServiceDao ( ) . GetServicesByTenantID ( tenantID )
for _ , s := range services {
serviceIDs = append ( serviceIDs , s . ServiceID )
}
2017-11-07 11:40:44 +08:00
}
2020-02-25 20:03:21 +08:00
if len ( serviceIDs ) == 0 {
return [ ] map [ string ] interface { } { }
2017-11-07 11:40:44 +08:00
}
2020-02-25 20:03:21 +08:00
statusList := s . statusCli . GetStatuss ( strings . Join ( serviceIDs , "," ) )
var info = make ( [ ] map [ string ] interface { } , 0 )
if statusList != nil {
for k , v := range statusList {
serviceInfo := map [ string ] interface { } { "service_id" : k , "status" : v , "status_cn" : TransStatus ( v ) , "used_mem" : 0 }
info = append ( info , serviceInfo )
}
}
return info
2017-11-07 11:40:44 +08:00
}
2020-02-27 16:40:01 +08:00
// GetEnterpriseRunningServices get running services
2020-03-30 18:23:33 +08:00
func ( s * ServiceAction ) GetEnterpriseRunningServices ( enterpriseID string ) ( [ ] string , * util . APIHandleError ) {
2020-02-21 22:43:28 +08:00
var tenantIDs [ ] string
tenants , err := db . GetManager ( ) . EnterpriseDao ( ) . GetEnterpriseTenants ( enterpriseID )
if err != nil {
logrus . Errorf ( "list tenant failed: %s" , err . Error ( ) )
2020-03-30 18:23:33 +08:00
return nil , util . CreateAPIHandleErrorFromDBError ( fmt . Sprintf ( "enterprise[%s] get tenant failed" , enterpriseID ) , err )
}
if len ( tenants ) == 0 {
return nil , util . CreateAPIHandleErrorf ( 400 , "enterprise[%s] has not tenants" , enterpriseID )
2020-02-21 22:43:28 +08:00
}
for _ , tenant := range tenants {
tenantIDs = append ( tenantIDs , tenant . UUID )
}
services , err := db . GetManager ( ) . TenantServiceDao ( ) . GetServicesByTenantIDs ( tenantIDs )
2020-02-21 20:59:59 +08:00
if err != nil {
2020-03-30 19:13:24 +08:00
logrus . Errorf ( "list tenants service failed: %s" , err . Error ( ) )
return nil , util . CreateAPIHandleErrorf ( 500 , "get enterprise[%s] service failed: %s" , enterpriseID , err . Error ( ) )
2020-02-21 20:59:59 +08:00
}
var serviceIDs [ ] string
for _ , svc := range services {
serviceIDs = append ( serviceIDs , svc . ServiceID )
}
statusList := s . statusCli . GetStatuss ( strings . Join ( serviceIDs , "," ) )
retServices := make ( [ ] string , 0 , 10 )
for service , status := range statusList {
if status == typesv1 . RUNNING {
retServices = append ( retServices , service )
}
}
2020-03-30 18:23:33 +08:00
return retServices , nil
2020-02-21 20:59:59 +08:00
}
2017-11-07 11:40:44 +08:00
//CreateTenant create tenant
func ( s * ServiceAction ) CreateTenant ( t * dbmodel . Tenants ) error {
if ten , _ := db . GetManager ( ) . TenantDao ( ) . GetTenantIDByName ( t . Name ) ; ten != nil {
return fmt . Errorf ( "tenant name %s is exist" , t . Name )
}
tx := db . GetManager ( ) . Begin ( )
2019-06-20 13:59:19 +08:00
defer func ( ) {
if r := recover ( ) ; r != nil {
logrus . Errorf ( "Unexpected panic occurred, rollback transaction: %v" , r )
tx . Rollback ( )
}
} ( )
2017-11-07 11:40:44 +08:00
if err := db . GetManager ( ) . TenantDaoTransactions ( tx ) . AddModel ( t ) ; err != nil {
2018-02-01 15:06:59 +08:00
if ! strings . HasSuffix ( err . Error ( ) , "is exist" ) {
2018-02-01 15:30:30 +08:00
tx . Rollback ( )
2018-02-01 15:06:59 +08:00
return err
2017-11-07 11:40:44 +08:00
}
}
2018-02-01 15:06:59 +08:00
if err := tx . Commit ( ) . Error ; err != nil {
tx . Rollback ( )
return err
}
return nil
2017-11-07 11:40:44 +08:00
}
//CreateTenandIDAndName create tenant_id and tenant_name
func ( s * ServiceAction ) CreateTenandIDAndName ( eid string ) ( string , string , error ) {
id := fmt . Sprintf ( "%s" , uuid . NewV4 ( ) )
uid := strings . Replace ( id , "-" , "" , - 1 )
name := strings . Split ( id , "-" ) [ 0 ]
logrus . Debugf ( "uuid is %v, name is %v" , uid , name )
return uid , name , nil
}
2019-08-20 17:26:14 +08:00
//K8sPodInfos -
type K8sPodInfos struct {
NewPods [ ] * K8sPodInfo ` json:"new_pods" `
OldPods [ ] * K8sPodInfo ` json:"old_pods" `
}
2018-11-22 14:33:29 +08:00
//K8sPodInfo for api
2018-08-16 18:21:06 +08:00
type K8sPodInfo struct {
2019-08-26 00:27:24 +08:00
PodName string ` json:"pod_name" `
PodIP string ` json:"pod_ip" `
PodStatus string ` json:"pod_status" `
2019-08-30 20:06:32 +08:00
ServiceID string ` json:"service_id" `
2019-08-26 00:27:24 +08:00
Container map [ string ] map [ string ] string ` json:"container" `
2018-08-16 18:21:06 +08:00
}
2017-11-07 11:40:44 +08:00
//GetPods get pods
2019-08-20 17:26:14 +08:00
func ( s * ServiceAction ) GetPods ( serviceID string ) ( * K8sPodInfos , error ) {
2018-11-22 14:33:29 +08:00
pods , err := s . statusCli . GetServicePods ( serviceID )
2019-08-26 00:27:24 +08:00
if err != nil && ! strings . Contains ( err . Error ( ) , server . ErrAppServiceNotFound . Error ( ) ) &&
! strings . Contains ( err . Error ( ) , server . ErrPodNotFound . Error ( ) ) {
2018-08-17 11:02:57 +08:00
logrus . Error ( "GetPodByService Error:" , err )
2017-11-07 11:40:44 +08:00
return nil , err
}
2019-08-26 00:27:24 +08:00
if pods == nil {
return nil , nil
}
2019-08-20 17:26:14 +08:00
convpod := func ( pods [ ] * pb . ServiceAppPod ) [ ] * K8sPodInfo {
var podsInfoList [ ] * K8sPodInfo
var podNames [ ] string
for _ , v := range pods {
var podInfo K8sPodInfo
podInfo . PodName = v . PodName
podInfo . PodIP = v . PodIp
podInfo . PodStatus = v . PodStatus
2019-08-30 20:06:32 +08:00
podInfo . ServiceID = serviceID
2019-08-20 17:26:14 +08:00
containerInfos := make ( map [ string ] map [ string ] string , 10 )
for _ , container := range v . Containers {
containerInfos [ container . ContainerName ] = map [ string ] string {
"memory_limit" : fmt . Sprintf ( "%d" , container . MemoryLimit ) ,
"memory_usage" : "0" ,
}
2018-08-17 13:51:17 +08:00
}
2019-08-20 17:26:14 +08:00
podInfo . Container = containerInfos
podNames = append ( podNames , v . PodName )
podsInfoList = append ( podsInfoList , & podInfo )
}
containerMemInfo , _ := s . GetPodContainerMemory ( podNames )
for _ , c := range podsInfoList {
for k := range c . Container {
if info , exist := containerMemInfo [ c . PodName ] [ k ] ; exist {
c . Container [ k ] [ "memory_usage" ] = info
}
2018-08-17 12:40:14 +08:00
}
2018-08-16 18:21:06 +08:00
}
2019-08-20 17:26:14 +08:00
return podsInfoList
2018-08-16 18:21:06 +08:00
}
2019-08-20 17:26:14 +08:00
newpods := convpod ( pods . NewPods )
oldpods := convpod ( pods . OldPods )
return & K8sPodInfos {
NewPods : newpods ,
OldPods : oldpods ,
} , nil
2018-08-16 18:21:06 +08:00
}
2020-07-29 19:08:01 +08:00
//GetMultiServicePods get pods
func ( s * ServiceAction ) GetMultiServicePods ( serviceIDs [ ] string ) ( * K8sPodInfos , error ) {
mpods , err := s . statusCli . GetMultiServicePods ( serviceIDs )
if err != nil && ! strings . Contains ( err . Error ( ) , server . ErrAppServiceNotFound . Error ( ) ) &&
! strings . Contains ( err . Error ( ) , server . ErrPodNotFound . Error ( ) ) {
logrus . Error ( "GetPodByService Error:" , err )
return nil , err
}
if mpods == nil {
return nil , nil
}
convpod := func ( serviceID string , pods [ ] * pb . ServiceAppPod ) [ ] * K8sPodInfo {
var podsInfoList [ ] * K8sPodInfo
var podNames [ ] string
for _ , v := range pods {
var podInfo K8sPodInfo
podInfo . PodName = v . PodName
podInfo . PodIP = v . PodIp
podInfo . PodStatus = v . PodStatus
podInfo . ServiceID = serviceID
podNames = append ( podNames , v . PodName )
podsInfoList = append ( podsInfoList , & podInfo )
}
return podsInfoList
}
var re K8sPodInfos
for serviceID , pods := range mpods . ServicePods {
2020-08-04 23:10:49 +08:00
if pods != nil {
re . NewPods = append ( re . NewPods , convpod ( serviceID , pods . NewPods ) ... )
re . OldPods = append ( re . OldPods , convpod ( serviceID , pods . OldPods ) ... )
}
2020-07-29 19:08:01 +08:00
}
return & re , nil
}
2018-11-22 14:33:29 +08:00
//GetPodContainerMemory Use Prometheus to query memory resources
func ( s * ServiceAction ) GetPodContainerMemory ( podNames [ ] string ) ( map [ string ] map [ string ] string , error ) {
memoryUsageMap := make ( map [ string ] map [ string ] string , 10 )
queryName := strings . Join ( podNames , "|" )
2020-02-13 20:51:19 +08:00
query := fmt . Sprintf ( ` container_memory_rss { pod=~"%s"} ` , queryName )
2020-09-24 21:09:00 +08:00
metric := s . prometheusCli . GetMetric ( query , time . Now ( ) )
for _ , re := range metric . MetricData . MetricValues {
var containerName = re . Metadata [ "container" ]
var podName = re . Metadata [ "pod" ]
var valuesBytes string
if re . Sample != nil {
2020-09-30 11:03:14 +08:00
valuesBytes = fmt . Sprintf ( "%d" , int ( re . Sample . Value ( ) ) )
2020-09-24 21:09:00 +08:00
}
if _ , ok := memoryUsageMap [ podName ] ; ok {
memoryUsageMap [ podName ] [ containerName ] = valuesBytes
} else {
memoryUsageMap [ podName ] = map [ string ] string {
containerName : valuesBytes ,
2018-08-16 18:21:06 +08:00
}
}
}
return memoryUsageMap , nil
2017-11-07 11:40:44 +08:00
}
//TransServieToDelete trans service info to delete table
2019-10-30 10:23:28 +08:00
func ( s * ServiceAction ) TransServieToDelete ( tenantID , serviceID string ) error {
2020-02-24 12:38:18 +08:00
_ , err := db . GetManager ( ) . TenantServiceDao ( ) . GetServiceByID ( serviceID )
if err != nil && gorm . ErrRecordNotFound == err {
logrus . Infof ( "service[%s] of tenant[%s] do not exist, ignore it" , serviceID , tenantID )
return nil
}
2019-10-29 18:36:15 +08:00
if err := s . isServiceClosed ( serviceID ) ; err != nil {
return err
}
2019-10-30 10:23:28 +08:00
body , err := s . gcTaskBody ( tenantID , serviceID )
if err != nil {
return fmt . Errorf ( "GC task body: %v" , err )
}
2019-10-29 18:36:15 +08:00
if err := s . delServiceMetadata ( serviceID ) ; err != nil {
return fmt . Errorf ( "delete service-related metadata: %v" , err )
}
// let rbd-chaos remove related persistent data
2019-10-30 10:23:28 +08:00
logrus . Info ( "let rbd-chaos remove related persistent data" )
2019-11-01 14:37:07 +08:00
topic := gclient . WorkerTopic
2019-10-30 10:23:28 +08:00
if err := s . MQClient . SendBuilderTopic ( gclient . TaskStruct {
Topic : topic ,
2019-11-01 14:37:07 +08:00
TaskType : "service_gc" ,
2019-10-30 10:23:28 +08:00
TaskBody : body ,
} ) ; err != nil {
logrus . Warningf ( "send gc task: %v" , err )
}
2019-10-29 18:36:15 +08:00
return nil
}
// isServiceClosed checks if the service has been closed according to the serviceID.
func ( s * ServiceAction ) isServiceClosed ( serviceID string ) error {
2018-03-02 20:14:52 +08:00
service , err := db . GetManager ( ) . TenantServiceDao ( ) . GetServiceByID ( serviceID )
if err != nil {
return err
}
2018-04-19 11:34:48 +08:00
status := s . statusCli . GetStatus ( serviceID )
2019-03-14 17:52:09 +08:00
if service . Kind != dbmodel . ServiceKindThirdParty . String ( ) {
if ! s . statusCli . IsClosedStatus ( status ) {
2019-10-29 18:36:15 +08:00
return ErrServiceNotClosed
2019-03-14 17:52:09 +08:00
}
2017-11-07 11:40:44 +08:00
}
2019-10-29 18:36:15 +08:00
return nil
}
// delServiceMetadata deletes service-related metadata in the database.
func ( s * ServiceAction ) delServiceMetadata ( serviceID string ) error {
service , err := db . GetManager ( ) . TenantServiceDao ( ) . GetServiceByID ( serviceID )
if err != nil {
return err
}
2020-06-29 21:12:04 +08:00
logrus . Infof ( "delete service %s %s" , serviceID , service . ServiceAlias )
2017-11-07 11:40:44 +08:00
tx := db . GetManager ( ) . Begin ( )
2019-06-20 13:59:19 +08:00
defer func ( ) {
if r := recover ( ) ; r != nil {
logrus . Errorf ( "Unexpected panic occurred, rollback transaction: %v" , r )
tx . Rollback ( )
}
} ( )
2017-11-07 11:40:44 +08:00
delService := service . ChangeDelete ( )
2017-12-18 14:11:43 +08:00
delService . ID = 0
2017-11-07 11:40:44 +08:00
if err := db . GetManager ( ) . TenantServiceDeleteDaoTransactions ( tx ) . AddModel ( delService ) ; err != nil {
tx . Rollback ( )
return err
}
2019-02-15 17:20:08 +08:00
var deleteServicePropertyFunc = [ ] func ( serviceID string ) error {
2019-10-29 18:36:15 +08:00
db . GetManager ( ) . CodeCheckResultDaoTransactions ( tx ) . DeleteByServiceID ,
2019-02-15 17:20:08 +08:00
db . GetManager ( ) . TenantServiceEnvVarDaoTransactions ( tx ) . DELServiceEnvsByServiceID ,
2019-10-29 18:36:15 +08:00
db . GetManager ( ) . TenantPluginVersionConfigDaoTransactions ( tx ) . DeletePluginConfigByServiceID ,
db . GetManager ( ) . TenantServicePluginRelationDaoTransactions ( tx ) . DeleteALLRelationByServiceID ,
db . GetManager ( ) . TenantServicesStreamPluginPortDaoTransactions ( tx ) . DeleteAllPluginMappingPortByServiceID ,
db . GetManager ( ) . TenantServiceDaoTransactions ( tx ) . DeleteServiceByServiceID ,
2019-02-15 17:20:08 +08:00
db . GetManager ( ) . TenantServicesPortDaoTransactions ( tx ) . DELPortsByServiceID ,
db . GetManager ( ) . TenantServiceRelationDaoTransactions ( tx ) . DELRelationsByServiceID ,
2019-10-29 18:36:15 +08:00
db . GetManager ( ) . TenantServiceMountRelationDaoTransactions ( tx ) . DELTenantServiceMountRelationByServiceID ,
2019-02-15 17:20:08 +08:00
db . GetManager ( ) . TenantServiceVolumeDaoTransactions ( tx ) . DeleteTenantServiceVolumesByServiceID ,
2019-03-16 21:34:07 +08:00
db . GetManager ( ) . TenantServiceConfigFileDaoTransactions ( tx ) . DelByServiceID ,
db . GetManager ( ) . EndpointsDaoTransactions ( tx ) . DeleteByServiceID ,
2019-10-29 18:36:15 +08:00
db . GetManager ( ) . ThirdPartySvcDiscoveryCfgDaoTransactions ( tx ) . DeleteByServiceID ,
db . GetManager ( ) . TenantServiceLabelDaoTransactions ( tx ) . DeleteLabelByServiceID ,
2019-11-01 14:37:07 +08:00
db . GetManager ( ) . VersionInfoDaoTransactions ( tx ) . DeleteVersionByServiceID ,
2019-10-29 18:36:15 +08:00
db . GetManager ( ) . TenantPluginVersionENVDaoTransactions ( tx ) . DeleteEnvByServiceID ,
db . GetManager ( ) . ServiceProbeDaoTransactions ( tx ) . DELServiceProbesByServiceID ,
2019-11-01 14:37:07 +08:00
db . GetManager ( ) . ServiceEventDaoTransactions ( tx ) . DelEventByServiceID ,
2020-09-19 17:17:28 +08:00
db . GetManager ( ) . TenantServiceMonitorDaoTransactions ( tx ) . DeleteServiceMonitorByServiceID ,
2020-11-13 09:14:44 +08:00
db . GetManager ( ) . AppConfigGroupServiceDaoTransactions ( tx ) . DeleteEffectiveServiceByServiceID ,
2019-03-16 21:34:07 +08:00
}
if err := GetGatewayHandler ( ) . DeleteTCPRuleByServiceIDWithTransaction ( serviceID , tx ) ; err != nil {
tx . Rollback ( )
return err
}
if err := GetGatewayHandler ( ) . DeleteHTTPRuleByServiceIDWithTransaction ( serviceID , tx ) ; err != nil {
tx . Rollback ( )
return err
2019-02-15 17:20:08 +08:00
}
for _ , del := range deleteServicePropertyFunc {
if err := del ( serviceID ) ; err != nil {
2019-10-29 18:36:15 +08:00
if err != gorm . ErrRecordNotFound {
2019-02-15 17:20:08 +08:00
tx . Rollback ( )
return err
}
2018-12-28 12:33:37 +08:00
}
}
2017-11-07 11:40:44 +08:00
if err := tx . Commit ( ) . Error ; err != nil {
tx . Rollback ( )
return err
}
return nil
}
2019-10-29 18:36:15 +08:00
// delLogFile deletes persistent data related to the service based on serviceID.
2019-10-30 10:23:28 +08:00
func ( s * ServiceAction ) delLogFile ( serviceID string , eventIDs [ ] string ) {
2019-10-29 18:36:15 +08:00
// log generated during service running
dockerLogPath := eventutil . DockerLogFilePath ( s . conf . LogPath , serviceID )
if err := os . RemoveAll ( dockerLogPath ) ; err != nil {
logrus . Warningf ( "remove docker log files: %v" , err )
}
// log generated by the service event
eventLogPath := eventutil . EventLogFilePath ( s . conf . LogPath )
for _ , eventID := range eventIDs {
eventLogFileName := eventutil . EventLogFileName ( eventLogPath , eventID )
if err := os . RemoveAll ( eventLogFileName ) ; err != nil {
logrus . Warningf ( "file: %s; remove event log file: %v" , eventLogFileName , err )
}
}
2019-10-30 10:23:28 +08:00
}
func ( s * ServiceAction ) gcTaskBody ( tenantID , serviceID string ) ( map [ string ] interface { } , error ) {
events , err := db . GetManager ( ) . ServiceEventDao ( ) . ListByTargetID ( serviceID )
if err != nil {
logrus . Errorf ( "list events based on serviceID: %v" , err )
}
var eventIDs [ ] string
for _ , event := range events {
eventIDs = append ( eventIDs , event . EventID )
}
return map [ string ] interface { } {
"tenant_id" : tenantID ,
"service_id" : serviceID ,
"event_ids" : eventIDs ,
} , nil
2019-10-29 18:36:15 +08:00
}
2018-12-07 13:53:43 +08:00
//GetServiceDeployInfo get service deploy info
2018-12-07 15:15:52 +08:00
func ( s * ServiceAction ) GetServiceDeployInfo ( tenantID , serviceID string ) ( * pb . DeployInfo , * util . APIHandleError ) {
info , err := s . statusCli . GetServiceDeployInfo ( serviceID )
if err != nil {
return nil , util . CreateAPIHandleError ( 500 , err )
}
return info , nil
2018-12-07 13:53:43 +08:00
}
2019-02-13 16:30:17 +08:00
// ListVersionInfo lists version info
func ( s * ServiceAction ) ListVersionInfo ( serviceID string ) ( * api_model . BuildListRespVO , error ) {
versionInfos , err := db . GetManager ( ) . VersionInfoDao ( ) . GetAllVersionByServiceID ( serviceID )
if err != nil && err != gorm . ErrRecordNotFound {
logrus . Errorf ( "error getting all version by service id: %v" , err )
return nil , fmt . Errorf ( "error getting all version by service id: %v" , err )
}
svc , err := db . GetManager ( ) . TenantServiceDao ( ) . GetServiceByID ( serviceID )
if err != nil {
logrus . Errorf ( "error getting service by uuid: %v" , err )
return nil , fmt . Errorf ( "error getting service by uuid: %v" , err )
}
2019-08-22 14:20:08 +08:00
b , err := json . Marshal ( versionInfos )
if err != nil {
return nil , fmt . Errorf ( "error marshaling version infos: %v" , err )
}
var bversions [ ] * api_model . BuildVersion
if err := json . Unmarshal ( b , & bversions ) ; err != nil {
return nil , fmt . Errorf ( "error unmarshaling version infos: %v" , err )
}
for idx := range bversions {
bv := bversions [ idx ]
if bv . Kind == "build_from_image" || bv . Kind == "build_from_market_image" {
2019-09-03 15:09:30 +08:00
image := parser . ParseImageName ( bv . RepoURL )
bv . ImageDomain = image . GetDomain ( )
bv . ImageRepo = image . GetRepostory ( )
bv . ImageTag = image . GetTag ( )
2019-08-22 14:20:08 +08:00
}
}
2019-02-13 16:30:17 +08:00
result := & api_model . BuildListRespVO {
DeployVersion : svc . DeployVersion ,
2019-08-22 14:20:08 +08:00
List : bversions ,
2019-02-13 16:30:17 +08:00
}
return result , nil
}
2019-11-13 11:05:25 +08:00
// AddAutoscalerRule -
func ( s * ServiceAction ) AddAutoscalerRule ( req * api_model . AutoscalerRuleReq ) error {
tx := db . GetManager ( ) . Begin ( )
defer db . GetManager ( ) . EnsureEndTransactionFunc ( )
r := & dbmodel . TenantServiceAutoscalerRules {
RuleID : req . RuleID ,
ServiceID : req . ServiceID ,
Enable : req . Enable ,
XPAType : req . XPAType ,
MinReplicas : req . MinReplicas ,
MaxReplicas : req . MaxReplicas ,
}
if err := db . GetManager ( ) . TenantServceAutoscalerRulesDaoTransactions ( tx ) . AddModel ( r ) ; err != nil {
tx . Rollback ( )
return err
}
for _ , metric := range req . Metrics {
m := & dbmodel . TenantServiceAutoscalerRuleMetrics {
RuleID : req . RuleID ,
MetricsType : metric . MetricsType ,
MetricsName : metric . MetricsName ,
MetricTargetType : metric . MetricTargetType ,
MetricTargetValue : metric . MetricTargetValue ,
}
if err := db . GetManager ( ) . TenantServceAutoscalerRuleMetricsDaoTransactions ( tx ) . AddModel ( m ) ; err != nil {
tx . Rollback ( )
return err
}
}
2019-11-13 18:48:51 +08:00
taskbody := map [ string ] interface { } {
"service_id" : r . ServiceID ,
"rule_id" : r . RuleID ,
}
if err := s . MQClient . SendBuilderTopic ( gclient . TaskStruct {
TaskType : "refreshhpa" ,
TaskBody : taskbody ,
Topic : gclient . WorkerTopic ,
} ) ; err != nil {
logrus . Errorf ( "send 'refreshhpa' task: %v" , err )
return err
}
logrus . Infof ( "rule id: %s; successfully send 'refreshhpa' task." , r . RuleID )
2019-11-13 11:05:25 +08:00
return tx . Commit ( ) . Error
}
// UpdAutoscalerRule -
func ( s * ServiceAction ) UpdAutoscalerRule ( req * api_model . AutoscalerRuleReq ) error {
rule , err := db . GetManager ( ) . TenantServceAutoscalerRulesDao ( ) . GetByRuleID ( req . RuleID )
if err != nil {
return err
}
rule . Enable = req . Enable
rule . XPAType = req . XPAType
rule . MinReplicas = req . MinReplicas
rule . MaxReplicas = req . MaxReplicas
tx := db . GetManager ( ) . Begin ( )
defer db . GetManager ( ) . EnsureEndTransactionFunc ( )
if err := db . GetManager ( ) . TenantServceAutoscalerRulesDaoTransactions ( tx ) . UpdateModel ( rule ) ; err != nil {
tx . Rollback ( )
return err
}
2019-11-28 17:21:05 +08:00
// delete metrics
if err := db . GetManager ( ) . TenantServceAutoscalerRuleMetricsDaoTransactions ( tx ) . DeleteByRuleID ( req . RuleID ) ; err != nil {
tx . Rollback ( )
return err
}
2019-11-13 11:05:25 +08:00
for _ , metric := range req . Metrics {
m := & dbmodel . TenantServiceAutoscalerRuleMetrics {
RuleID : req . RuleID ,
MetricsType : metric . MetricsType ,
MetricsName : metric . MetricsName ,
MetricTargetType : metric . MetricTargetType ,
MetricTargetValue : metric . MetricTargetValue ,
}
2019-11-28 17:21:05 +08:00
if err := db . GetManager ( ) . TenantServceAutoscalerRuleMetricsDaoTransactions ( tx ) . AddModel ( m ) ; err != nil {
2019-11-13 11:05:25 +08:00
tx . Rollback ( )
return err
}
}
2019-11-13 18:48:51 +08:00
taskbody := map [ string ] interface { } {
"service_id" : rule . ServiceID ,
"rule_id" : rule . RuleID ,
}
if err := s . MQClient . SendBuilderTopic ( gclient . TaskStruct {
TaskType : "refreshhpa" ,
TaskBody : taskbody ,
Topic : gclient . WorkerTopic ,
} ) ; err != nil {
logrus . Errorf ( "send 'refreshhpa' task: %v" , err )
return err
}
logrus . Infof ( "rule id: %s; successfully send 'refreshhpa' task." , rule . RuleID )
2019-11-13 11:05:25 +08:00
return tx . Commit ( ) . Error
}
2019-11-14 15:30:40 +08:00
// ListScalingRecords -
func ( s * ServiceAction ) ListScalingRecords ( serviceID string , page , pageSize int ) ( [ ] * dbmodel . TenantServiceScalingRecords , int , error ) {
records , err := db . GetManager ( ) . TenantServiceScalingRecordsDao ( ) . ListByServiceID ( serviceID , ( page - 1 ) * pageSize , pageSize )
if err != nil {
return nil , 0 , err
}
count , err := db . GetManager ( ) . TenantServiceScalingRecordsDao ( ) . CountByServiceID ( serviceID )
if err != nil {
return nil , 0 , err
}
return records , count , nil
2019-11-13 11:05:25 +08:00
}
2017-11-07 11:40:44 +08:00
//TransStatus trans service status
func TransStatus ( eStatus string ) string {
switch eStatus {
case "starting" :
2018-03-07 10:18:26 +08:00
return "启动中"
2017-11-07 11:40:44 +08:00
case "abnormal" :
return "运行异常"
case "upgrade" :
return "升级中"
case "closed" :
return "已关闭"
case "stopping" :
return "关闭中"
case "checking" :
return "检测中"
case "unusual" :
return "运行异常"
case "running" :
return "运行中"
case "failure" :
return "未知"
case "undeploy" :
return "未部署"
case "deployed" :
return "已部署"
}
return ""
}
//CheckLabel check label
func CheckLabel ( serviceID string ) bool {
//true for v2, false for v1
serviceLabel , err := db . GetManager ( ) . TenantServiceLabelDao ( ) . GetTenantServiceLabel ( serviceID )
if err != nil {
return false
}
if serviceLabel != nil && len ( serviceLabel ) > 0 {
return true
}
return false
}
//CheckMapKey CheckMapKey
func CheckMapKey ( rebody map [ string ] interface { } , key string , defaultValue interface { } ) map [ string ] interface { } {
if _ , ok := rebody [ key ] ; ok {
return rebody
}
rebody [ key ] = defaultValue
return rebody
}