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 (
|
|
|
|
"context"
|
2019-01-09 15:05:32 +08:00
|
|
|
"encoding/json"
|
2017-11-07 11:40:44 +08:00
|
|
|
"fmt"
|
2019-01-25 23:34:12 +08:00
|
|
|
"github.com/goodrain/rainbond/api/proxy"
|
2019-01-09 15:05:32 +08:00
|
|
|
"net/http"
|
2017-11-07 11:40:44 +08:00
|
|
|
"os"
|
2019-01-25 23:34:12 +08:00
|
|
|
"strconv"
|
2017-11-07 11:40:44 +08:00
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
2019-01-09 15:05:32 +08:00
|
|
|
"github.com/Sirupsen/logrus"
|
2017-12-13 17:38:45 +08:00
|
|
|
"github.com/coreos/etcd/clientv3"
|
2018-04-24 16:44:59 +08:00
|
|
|
api_model "github.com/goodrain/rainbond/api/model"
|
|
|
|
"github.com/goodrain/rainbond/api/util"
|
2019-01-09 15:05:32 +08:00
|
|
|
"github.com/goodrain/rainbond/cmd/api/option"
|
|
|
|
"github.com/goodrain/rainbond/db"
|
|
|
|
core_model "github.com/goodrain/rainbond/db/model"
|
2018-04-24 16:44:59 +08:00
|
|
|
dbmodel "github.com/goodrain/rainbond/db/model"
|
2019-01-09 15:05:32 +08:00
|
|
|
"github.com/goodrain/rainbond/event"
|
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"
|
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-01-09 15:05:32 +08:00
|
|
|
"github.com/goodrain/rainbond/worker/server/pb"
|
|
|
|
"github.com/jinzhu/gorm"
|
|
|
|
"github.com/pquerna/ffjson/ffjson"
|
|
|
|
"github.com/twinj/uuid"
|
2017-11-07 11:40:44 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
//ServiceAction service act
|
|
|
|
type ServiceAction struct {
|
2018-12-04 13:43:15 +08:00
|
|
|
MQClient gclient.MQClient
|
2018-11-22 14:33:29 +08:00
|
|
|
EtcdCli *clientv3.Client
|
|
|
|
statusCli *client.AppRuntimeSyncClient
|
2018-12-08 12:58:40 +08:00
|
|
|
conf option.Config
|
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,
|
2018-04-03 18:21:46 +08:00
|
|
|
etcdCli *clientv3.Client, statusCli *client.AppRuntimeSyncClient) *ServiceAction {
|
2017-11-07 11:40:44 +08:00
|
|
|
return &ServiceAction{
|
2018-11-22 14:33:29 +08:00
|
|
|
MQClient: mqClient,
|
|
|
|
EtcdCli: etcdCli,
|
|
|
|
statusCli: statusCli,
|
2018-12-08 12:58:40 +08:00
|
|
|
conf: conf,
|
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()
|
|
|
|
for _, label := range l.Labels {
|
2018-12-04 15:54:47 +08:00
|
|
|
var labelModel dbmodel.TenantServiceLable
|
|
|
|
switch label.LabelKey {
|
2018-12-04 15:59:58 +08:00
|
|
|
case core_model.LabelKeyServiceType:
|
2018-12-04 15:54:47 +08:00
|
|
|
labelModel.ServiceID = serviceID
|
|
|
|
labelModel.LabelKey = core_model.LabelKeyServiceType
|
|
|
|
labelModel.LabelValue = chekeServiceLabel(label.LabelValue)
|
|
|
|
default:
|
|
|
|
labelModel.ServiceID = serviceID
|
|
|
|
labelModel.LabelKey = label.LabelKey
|
|
|
|
labelModel.LabelValue = label.LabelValue
|
|
|
|
}
|
|
|
|
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()
|
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
|
|
|
|
}
|
2018-12-04 15:20:59 +08:00
|
|
|
// add new labels
|
2018-12-04 15:54:47 +08:00
|
|
|
var labelModel dbmodel.TenantServiceLable
|
|
|
|
switch label.LabelKey {
|
2018-12-04 15:59:58 +08:00
|
|
|
case core_model.LabelKeyServiceType:
|
2018-12-04 15:54:47 +08:00
|
|
|
labelModel.ServiceID = serviceID
|
|
|
|
labelModel.LabelKey = core_model.LabelKeyServiceType
|
|
|
|
labelModel.LabelValue = chekeServiceLabel(label.LabelValue)
|
|
|
|
default:
|
|
|
|
labelModel.ServiceID = serviceID
|
|
|
|
labelModel.LabelKey = label.LabelKey
|
|
|
|
labelModel.LabelValue = label.LabelValue
|
|
|
|
}
|
|
|
|
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()
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
//UpdateServiceLabel UpdateLabel
|
|
|
|
func (s *ServiceAction) UpdateServiceLabel(serviceID, value string) error {
|
|
|
|
sls, err := db.GetManager().TenantServiceLabelDao().GetTenantServiceLabel(serviceID)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if len(sls) > 0 {
|
|
|
|
for _, sl := range sls {
|
|
|
|
sl.ServiceID = serviceID
|
|
|
|
sl.LabelKey = core_model.LabelKeyServiceType
|
|
|
|
value = chekeServiceLabel(value)
|
|
|
|
sl.LabelValue = value
|
|
|
|
return db.GetManager().TenantServiceLabelDao().UpdateModel(sl)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return fmt.Errorf("Get tenant service label error")
|
|
|
|
}
|
|
|
|
|
|
|
|
//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
|
|
|
|
}
|
|
|
|
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 {
|
|
|
|
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
|
|
|
|
}
|
|
|
|
if int32(service.Replicas) == hs.Replicas {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
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())
|
|
|
|
}
|
2018-12-04 18:08:51 +08:00
|
|
|
err = s.MQClient.SendBuilderTopic(gclient.TaskStruct{
|
2017-11-07 11:40:44 +08:00
|
|
|
TaskType: "horizontal_scaling",
|
|
|
|
TaskBody: hs,
|
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
|
|
|
|
}
|
|
|
|
logrus.Debugf("equeue mq horizontal task success")
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
//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
|
|
|
|
}
|
|
|
|
if version.FinalStatus != "success" {
|
|
|
|
return fmt.Errorf("deploy version is not build success,do not upgrade")
|
2018-11-19 18:56:28 +08:00
|
|
|
}
|
|
|
|
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-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 {
|
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
|
2017-12-18 14:11:43 +08:00
|
|
|
ts.DeployVersion = ""
|
2018-04-09 11:58:16 +08:00
|
|
|
tx := db.GetManager().Begin()
|
|
|
|
//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 {
|
|
|
|
logrus.Errorf("add env %v error, %v", env.AttrName, err)
|
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
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{
|
2019-01-26 01:26:11 +08:00
|
|
|
ServiceID: ts.ServiceID,
|
|
|
|
Category: volumn.Category,
|
2019-01-17 15:10:28 +08:00
|
|
|
VolumeType: volumn.VolumeType,
|
|
|
|
VolumeName: volumn.VolumeName,
|
2019-01-26 01:26:11 +08:00
|
|
|
HostPath: volumn.HostPath,
|
2019-01-17 15:10:28 +08:00
|
|
|
VolumePath: volumn.VolumePath,
|
|
|
|
IsReadOnly: volumn.IsReadOnly,
|
|
|
|
}
|
|
|
|
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():
|
2018-10-11 12:30:32 +08:00
|
|
|
if sc.ExtendMethod != "state" {
|
2018-02-01 15:06:59 +08:00
|
|
|
tx.Rollback()
|
2017-11-07 11:40:44 +08:00
|
|
|
return util.CreateAPIHandleError(400, fmt.Errorf("应用类型不为有状态应用.不支持本地存储"))
|
|
|
|
}
|
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)
|
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{
|
|
|
|
UUID: uuid.NewV4().String(),
|
|
|
|
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())
|
|
|
|
}
|
|
|
|
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
|
2017-11-07 11:40:44 +08:00
|
|
|
if err := db.GetManager().TenantServiceLabelDaoTransactions(tx).AddModel(&dbmodel.TenantServiceLable{
|
|
|
|
ServiceID: ts.ServiceID,
|
|
|
|
LabelKey: core_model.LabelKeyServiceType,
|
|
|
|
LabelValue: sc.ServiceLabel,
|
|
|
|
}); err != nil {
|
|
|
|
logrus.Errorf("add label %v error, %v", ts.ServiceID, err)
|
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
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)
|
2017-11-07 11:40:44 +08:00
|
|
|
if sc["container_memory"] != nil {
|
|
|
|
ts.ContainerMemory = sc["container_memory"].(int)
|
|
|
|
}
|
|
|
|
if sc["container_cmd"] != nil {
|
2018-11-22 14:33:29 +08:00
|
|
|
version.Cmd = sc["container_cmd"].(string)
|
2017-11-07 11:40:44 +08:00
|
|
|
}
|
2018-11-27 14:50:30 +08:00
|
|
|
if sc["service_name"] != nil {
|
|
|
|
ts.ServiceName = sc["service_name"].(string)
|
|
|
|
}
|
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
|
|
|
|
if err := db.GetManager().VersionInfoDao().UpdateModel(version); err != nil {
|
|
|
|
logrus.Errorf("update version error, %v", err)
|
|
|
|
return err
|
|
|
|
}
|
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
|
|
|
|
}
|
|
|
|
|
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) {
|
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 {
|
|
|
|
logrus.Errorf("get service by id error, %v, %v", services, err)
|
|
|
|
return nil, err
|
|
|
|
}
|
2018-04-27 16:35:20 +08:00
|
|
|
var serviceIDs string
|
|
|
|
var AllocatedCPU, AllocatedMEM int
|
|
|
|
var serMap = make(map[string]*dbmodel.TenantServices, len(services))
|
|
|
|
for _, ser := range services {
|
|
|
|
if serviceIDs == "" {
|
|
|
|
serviceIDs += ser.ServiceID
|
|
|
|
} else {
|
|
|
|
serviceIDs += "," + ser.ServiceID
|
|
|
|
}
|
|
|
|
AllocatedCPU += ser.ContainerCPU
|
|
|
|
AllocatedMEM += ser.ContainerMemory
|
|
|
|
serMap[ser.ServiceID] = ser
|
|
|
|
}
|
|
|
|
status := s.statusCli.GetStatuss(serviceIDs)
|
|
|
|
var UsedCPU, UsedMEM int
|
|
|
|
for k, v := range status {
|
|
|
|
if !s.statusCli.IsClosedStatus(v) {
|
|
|
|
UsedCPU += serMap[k].ContainerCPU
|
|
|
|
UsedMEM += serMap[k].ContainerMemory
|
|
|
|
}
|
|
|
|
}
|
2019-01-25 23:34:12 +08:00
|
|
|
disks := GetServicesDisk(strings.Split(serviceIDs, ","), GetPrometheusProxy())
|
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
|
|
|
|
res.Name = ""
|
|
|
|
res.EID = ""
|
2018-04-27 16:35:20 +08:00
|
|
|
res.AllocatedCPU = AllocatedCPU
|
|
|
|
res.AllocatedMEM = AllocatedMEM
|
|
|
|
res.UsedCPU = UsedCPU
|
|
|
|
res.UsedMEM = UsedMEM
|
2018-07-16 15:30:53 +08:00
|
|
|
res.UsedDisk = value
|
2017-12-15 16:49:24 +08:00
|
|
|
return &res, nil
|
|
|
|
}
|
|
|
|
|
2019-01-25 23:34:12 +08:00
|
|
|
func GetServicesDisk(ids []string, p proxy.Proxy) map[string]float64 {
|
|
|
|
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, "|"))
|
|
|
|
query = strings.Replace(query, " ", "%20", -1)
|
2019-01-26 01:26:11 +08:00
|
|
|
req, err := http.NewRequest("GET", fmt.Sprintf("http://127.0.0.1:9999/api/v1/query?query=%s", query), nil)
|
2019-01-25 23:34:12 +08:00
|
|
|
if err != nil {
|
|
|
|
logrus.Error("create request prometheus api error ", err.Error())
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
presult, err := p.Do(req)
|
|
|
|
if err != nil {
|
|
|
|
logrus.Error("do pproxy request prometheus api error ", err.Error())
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
if presult.Body != nil {
|
|
|
|
defer presult.Body.Close()
|
|
|
|
if presult.StatusCode != 200 {
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
var qres QueryResult
|
|
|
|
err = json.NewDecoder(presult.Body).Decode(&qres)
|
|
|
|
if err == nil {
|
|
|
|
for _, re := range qres.Data.Result {
|
|
|
|
var serviceID string
|
|
|
|
if tid, ok := re["metric"].(map[string]interface{}); ok {
|
|
|
|
serviceID = tid["service_id"].(string)
|
|
|
|
}
|
|
|
|
if re, ok := (re["value"]).([]interface{}); ok && len(re) == 2 {
|
|
|
|
i, err := strconv.ParseFloat(re[1].(string), 10)
|
|
|
|
if err != nil {
|
|
|
|
logrus.Warningf("error convert interface(%v) to float64", re[1].(string))
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
result[serviceID] = i
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
//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,
|
|
|
|
dbmodel.UpNetPlugin,
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-11-07 11:40:44 +08:00
|
|
|
switch action {
|
|
|
|
case "add":
|
|
|
|
for _, vp := range vps.Port {
|
|
|
|
var vpD dbmodel.TenantServicesPort
|
|
|
|
vpD.ServiceID = serviceID
|
|
|
|
vpD.TenantID = tenantID
|
|
|
|
//默认不打开
|
|
|
|
vpD.IsInnerService = false
|
|
|
|
vpD.IsOuterService = false
|
|
|
|
vpD.ContainerPort = vp.ContainerPort
|
|
|
|
vpD.MappingPort = vp.MappingPort
|
|
|
|
vpD.Protocol = vp.Protocol
|
|
|
|
vpD.PortAlias = vp.PortAlias
|
|
|
|
if err := db.GetManager().TenantServicesPortDao().AddModel(&vpD); err != nil {
|
|
|
|
logrus.Errorf("add port var error, %v", err)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case "delete":
|
2017-11-30 18:55:11 +08:00
|
|
|
tx := db.GetManager().Begin()
|
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()
|
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
|
|
|
|
}
|
|
|
|
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
|
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,
|
|
|
|
dbmodel.UpNetPlugin,
|
|
|
|
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,
|
|
|
|
dbmodel.UpNetPlugin,
|
|
|
|
)
|
|
|
|
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":
|
|
|
|
if p.IsOuterService { //如果端口已经开了对外
|
|
|
|
p.IsOuterService = false
|
|
|
|
tx := db.GetManager().Begin()
|
|
|
|
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,
|
|
|
|
dbmodel.UpNetPlugin,
|
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)
|
|
|
|
}
|
2017-11-30 15:35:14 +08:00
|
|
|
if p.IsInnerService {
|
|
|
|
//发现内网未关闭则不删除该映射
|
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,
|
|
|
|
dbmodel.UpNetPlugin,
|
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":
|
|
|
|
if p.IsOuterService {
|
2018-12-07 19:40:28 +08:00
|
|
|
if p.Protocol != "http" && p.Protocol != "https" && servicePort.Body.IfCreateExPort {
|
2017-11-07 11:40:44 +08:00
|
|
|
vsPort, err = s.createVSPort(serviceID, p.ContainerPort)
|
|
|
|
if vsPort == nil {
|
|
|
|
return nil, "", fmt.Errorf("port already open but can not get lb mapping port,%s", err.Error())
|
|
|
|
}
|
|
|
|
return vsPort, p.Protocol, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
p.IsOuterService = true
|
|
|
|
tx := db.GetManager().Begin()
|
|
|
|
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-12-07 19:40:28 +08:00
|
|
|
if p.Protocol != "http" && p.Protocol != "https" && servicePort.Body.IfCreateExPort {
|
2017-11-07 11:40:44 +08:00
|
|
|
vsPort, err = s.createVSPort(serviceID, p.ContainerPort)
|
|
|
|
if vsPort == nil {
|
2018-02-01 15:30:30 +08:00
|
|
|
tx.Rollback()
|
2017-11-07 11:40:44 +08:00
|
|
|
return nil, "", fmt.Errorf("create or get vs map port for service error,%s", err.Error())
|
|
|
|
}
|
|
|
|
}
|
2017-11-30 15:03:10 +08:00
|
|
|
if hasUpStream {
|
|
|
|
pluginPort, err := db.GetManager().TenantServicesStreamPluginPortDao().GetPluginMappingPortByServiceIDAndContainerPort(
|
|
|
|
serviceID,
|
|
|
|
dbmodel.UpNetPlugin,
|
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,
|
|
|
|
dbmodel.UpNetPlugin,
|
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
|
|
|
|
}
|
|
|
|
func (s *ServiceAction) createVSPort(serviceID string, containerPort int) (*dbmodel.TenantServiceLBMappingPort, error) {
|
|
|
|
vsPort, err := db.GetManager().TenantServiceLBMappingPortDao().CreateTenantServiceLBMappingPort(serviceID, containerPort)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("create vs map port for service error,%s", err.Error())
|
|
|
|
}
|
|
|
|
return vsPort, 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,
|
|
|
|
dbmodel.UpNetPlugin,
|
|
|
|
)
|
|
|
|
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()
|
|
|
|
switch operation {
|
|
|
|
case "close":
|
|
|
|
if p.IsInnerService { //如果端口已经开了对内
|
|
|
|
p.IsInnerService = false
|
|
|
|
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,
|
|
|
|
dbmodel.UpNetPlugin,
|
|
|
|
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)
|
|
|
|
}
|
2017-11-30 15:35:14 +08:00
|
|
|
if p.IsOuterService {
|
|
|
|
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,
|
|
|
|
dbmodel.UpNetPlugin,
|
|
|
|
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":
|
|
|
|
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")
|
|
|
|
}
|
|
|
|
p.IsInnerService = true
|
|
|
|
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,
|
|
|
|
dbmodel.UpNetPlugin,
|
|
|
|
port,
|
|
|
|
)
|
|
|
|
var pPort int
|
|
|
|
if err != nil {
|
|
|
|
if err.Error() == gorm.ErrRecordNotFound.Error() {
|
|
|
|
ppPort, err := db.GetManager().TenantServicesStreamPluginPortDaoTransactions(tx).SetPluginMappingPort(
|
|
|
|
p.TenantID,
|
|
|
|
serviceID,
|
|
|
|
dbmodel.UpNetPlugin,
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2018-06-07 13:02:24 +08:00
|
|
|
//ChangeLBPort change lb mapping port
|
|
|
|
//only support change to existing port in this tenants
|
|
|
|
func (s *ServiceAction) ChangeLBPort(tenantID, serviceID string, containerPort, changelbPort int) (*dbmodel.TenantServiceLBMappingPort, *util.APIHandleError) {
|
|
|
|
oldmapport, err := db.GetManager().TenantServiceLBMappingPortDao().GetLBPortByTenantAndPort(tenantID, changelbPort)
|
|
|
|
if err != nil {
|
|
|
|
logrus.Errorf("change lb port check error, %s", err.Error())
|
|
|
|
return nil, util.CreateAPIHandleErrorFromDBError("change lb port", err)
|
|
|
|
}
|
|
|
|
mapport, err := db.GetManager().TenantServiceLBMappingPortDao().GetTenantServiceLBMappingPort(serviceID, containerPort)
|
|
|
|
if err != nil {
|
|
|
|
logrus.Errorf("change lb port get error, %s", err.Error())
|
|
|
|
return nil, util.CreateAPIHandleErrorFromDBError("change lb port", err)
|
|
|
|
}
|
|
|
|
port := oldmapport.Port
|
|
|
|
oldmapport.Port = mapport.Port
|
|
|
|
mapport.Port = port
|
|
|
|
tx := db.GetManager().Begin()
|
|
|
|
if err := db.GetManager().TenantServiceLBMappingPortDaoTransactions(tx).DELServiceLBMappingPortByServiceIDAndPort(oldmapport.ServiceID, port); err != nil {
|
|
|
|
tx.Rollback()
|
|
|
|
return nil, util.CreateAPIHandleErrorFromDBError("change lb port", err)
|
|
|
|
}
|
|
|
|
if err := db.GetManager().TenantServiceLBMappingPortDaoTransactions(tx).UpdateModel(mapport); err != nil {
|
|
|
|
tx.Rollback()
|
|
|
|
return nil, util.CreateAPIHandleErrorFromDBError("change lb port", err)
|
|
|
|
}
|
|
|
|
if err := db.GetManager().TenantServiceLBMappingPortDaoTransactions(tx).AddModel(oldmapport); err != nil {
|
|
|
|
tx.Rollback()
|
|
|
|
return nil, util.CreateAPIHandleErrorFromDBError("change lb port", err)
|
|
|
|
}
|
|
|
|
if err := tx.Commit().Error; err != nil {
|
|
|
|
tx.Rollback()
|
|
|
|
return nil, util.CreateAPIHandleErrorFromDBError("change lb port", err)
|
|
|
|
}
|
|
|
|
return mapport, nil
|
|
|
|
}
|
|
|
|
|
2017-11-07 11:40:44 +08:00
|
|
|
//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)
|
2018-08-16 18:21:06 +08:00
|
|
|
//本地文件存储
|
2017-11-07 11:40:44 +08:00
|
|
|
case dbmodel.LocalVolumeType.String():
|
|
|
|
serviceType, err := db.GetManager().TenantServiceLabelDao().GetTenantServiceTypeLabel(tsv.ServiceID)
|
|
|
|
if err != nil {
|
|
|
|
return util.CreateAPIHandleErrorFromDBError("service type", err)
|
|
|
|
}
|
2017-11-13 21:54:11 +08:00
|
|
|
if serviceType == nil || serviceType.LabelValue != core_util.StatefulServiceType {
|
2017-11-07 11:40:44 +08:00
|
|
|
return util.CreateAPIHandleError(400, fmt.Errorf("应用类型不为有状态应用.不支持本地存储"))
|
|
|
|
}
|
|
|
|
tsv.HostPath = fmt.Sprintf("%s/tenant/%s/service/%s%s", localPath, tenantID, tsv.ServiceID, tsv.VolumePath)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if tsv.VolumeName == "" {
|
|
|
|
tsv.VolumeName = uuid.NewV4().String()
|
|
|
|
}
|
2019-01-06 22:13:19 +08:00
|
|
|
// begin transaction
|
|
|
|
tx := db.GetManager().Begin()
|
|
|
|
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{
|
|
|
|
UUID: uuid.NewV4().String(),
|
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()
|
2017-11-07 11:40:44 +08:00
|
|
|
if tsv.VolumeName != "" {
|
2019-01-06 22:13:19 +08:00
|
|
|
err := db.GetManager().TenantServiceVolumeDaoTransactions(tx).DeleteModel(tsv.ServiceID, tsv.VolumeName)
|
2018-06-01 10:51:05 +08:00
|
|
|
if 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)
|
|
|
|
}
|
|
|
|
} 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-01-07 18:26:18 +08:00
|
|
|
if err := db.GetManager().TenantServiceConfigFileDaoTransactions(tx).DelByVolumeID(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
|
|
|
|
}
|
|
|
|
|
|
|
|
//GetVolumes 获取应用全部存储
|
|
|
|
func (s *ServiceAction) GetVolumes(serviceID string) ([]*dbmodel.TenantServiceVolume, *util.APIHandleError) {
|
|
|
|
dbManager := db.GetManager()
|
|
|
|
vs, err := dbManager.TenantServiceVolumeDao().GetTenantServiceVolumesByServiceID(serviceID)
|
|
|
|
if err != nil && err.Error() != gorm.ErrRecordNotFound.Error() {
|
|
|
|
return nil, util.CreateAPIHandleErrorFromDBError("get volumes", err)
|
|
|
|
}
|
|
|
|
return vs, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
//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 {
|
|
|
|
tx := db.GetManager().Begin()
|
|
|
|
service, err := db.GetManager().TenantServiceDaoTransactions(tx).GetServiceByID(rs.ServiceID)
|
|
|
|
if err != nil {
|
2018-02-01 15:06:59 +08:00
|
|
|
tx.Rollback()
|
2017-11-07 11:40:44 +08:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
if service.DeployVersion == rs.DeployVersion {
|
2018-02-01 15:06:59 +08:00
|
|
|
tx.Rollback()
|
2017-11-07 11:40:44 +08:00
|
|
|
return fmt.Errorf("current version is %v, don't need rollback", rs.DeployVersion)
|
|
|
|
}
|
|
|
|
service.DeployVersion = rs.DeployVersion
|
|
|
|
if err := db.GetManager().TenantServiceDaoTransactions(tx).UpdateModel(service); err != nil {
|
2018-02-01 15:06:59 +08:00
|
|
|
tx.Rollback()
|
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 {
|
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := tx.Commit().Error; err != nil {
|
|
|
|
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
|
|
|
}
|
|
|
|
return sl, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
//GetServicesStatus 获取一组应用状态,若 serviceIDs为空,获取租户所有应用状态
|
2018-04-03 18:21:46 +08:00
|
|
|
func (s *ServiceAction) GetServicesStatus(tenantID string, serviceIDs []string) map[string]string {
|
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
|
|
|
}
|
2018-04-03 18:21:46 +08:00
|
|
|
if len(serviceIDs) > 0 {
|
|
|
|
status := s.statusCli.GetStatuss(strings.Join(serviceIDs, ","))
|
|
|
|
return status
|
2017-11-07 11:40:44 +08:00
|
|
|
}
|
2018-04-03 18:21:46 +08:00
|
|
|
return nil
|
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()
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2018-11-22 14:33:29 +08:00
|
|
|
//K8sPodInfo for api
|
2018-08-16 18:21:06 +08:00
|
|
|
type K8sPodInfo struct {
|
2018-11-22 14:33:29 +08:00
|
|
|
ServiceID string `json:"service_id"`
|
|
|
|
DeployID string `json:"deploy_id"`
|
|
|
|
DeployType string `json:"deploy_type"`
|
|
|
|
PodName string `json:"pod_name"`
|
|
|
|
PodIP string `json:"pod_ip"`
|
|
|
|
PodStatus string `json:"pod_status"`
|
|
|
|
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
|
2018-11-22 14:33:29 +08:00
|
|
|
func (s *ServiceAction) GetPods(serviceID string) ([]*K8sPodInfo, error) {
|
|
|
|
var podsInfoList []*K8sPodInfo
|
|
|
|
pods, err := s.statusCli.GetServicePods(serviceID)
|
2017-11-07 11:40:44 +08:00
|
|
|
if err != nil {
|
2018-08-17 11:02:57 +08:00
|
|
|
logrus.Error("GetPodByService Error:", err)
|
2017-11-07 11:40:44 +08:00
|
|
|
return nil, err
|
|
|
|
}
|
2018-11-22 14:33:29 +08:00
|
|
|
var podNames []string
|
|
|
|
for _, v := range pods.Pods {
|
2018-08-17 12:01:54 +08:00
|
|
|
var podInfo K8sPodInfo
|
2018-11-22 14:33:29 +08:00
|
|
|
containerInfos := make(map[string]map[string]string, 10)
|
|
|
|
podInfo.ServiceID = v.ServiceId
|
|
|
|
podInfo.DeployID = v.DeployId
|
|
|
|
podInfo.DeployType = v.DeployType
|
2018-08-16 18:21:06 +08:00
|
|
|
podInfo.PodName = v.PodName
|
2018-11-22 14:33:29 +08:00
|
|
|
podInfo.PodIP = v.PodIp
|
|
|
|
podInfo.PodStatus = v.PodStatus
|
|
|
|
for _, container := range v.Containers {
|
|
|
|
containerInfos[container.ContainerName] = map[string]string{
|
2019-01-09 14:55:26 +08:00
|
|
|
"memory_limit": fmt.Sprintf("%d", container.MemoryLimit),
|
2018-11-22 14:33:29 +08:00
|
|
|
"memory_usage": "0",
|
2018-08-17 13:51:17 +08:00
|
|
|
}
|
2018-08-16 18:21:06 +08:00
|
|
|
}
|
2018-11-22 14:33:29 +08:00
|
|
|
podInfo.Container = containerInfos
|
2018-11-22 16:22:44 +08:00
|
|
|
podNames = append(podNames, v.PodName)
|
2018-11-22 14:33:29 +08:00
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
return podsInfoList, 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)
|
2018-08-16 18:21:06 +08:00
|
|
|
proxy := GetPrometheusProxy()
|
2018-11-22 14:33:29 +08:00
|
|
|
queryName := strings.Join(podNames, "|")
|
|
|
|
query := fmt.Sprintf(`container_memory_usage_bytes{pod_name=~"%s"}`, queryName)
|
2018-08-16 18:21:06 +08:00
|
|
|
proQuery := strings.Replace(query, " ", "%20", -1)
|
|
|
|
req, err := http.NewRequest("GET", fmt.Sprintf("http://127.0.0.1:9999/api/v1/query?query=%s", proQuery), nil)
|
|
|
|
if err != nil {
|
|
|
|
logrus.Error("create request prometheus api error ", err.Error())
|
|
|
|
return memoryUsageMap, nil
|
|
|
|
}
|
|
|
|
presult, err := proxy.Do(req)
|
|
|
|
if err != nil {
|
|
|
|
logrus.Error("do proxy request prometheus api error ", err.Error())
|
|
|
|
return memoryUsageMap, nil
|
|
|
|
}
|
|
|
|
if presult.Body != nil {
|
|
|
|
defer presult.Body.Close()
|
|
|
|
if presult.StatusCode != 200 {
|
2018-08-17 12:40:14 +08:00
|
|
|
logrus.Error("StatusCode:", presult.StatusCode, err)
|
2018-08-16 18:21:06 +08:00
|
|
|
return memoryUsageMap, nil
|
|
|
|
}
|
|
|
|
var qres QueryResult
|
|
|
|
err = json.NewDecoder(presult.Body).Decode(&qres)
|
|
|
|
if err == nil {
|
|
|
|
for _, re := range qres.Data.Result {
|
2018-11-22 14:33:29 +08:00
|
|
|
var containerName, podName string
|
2018-08-17 11:31:59 +08:00
|
|
|
var valuesBytes string
|
2018-08-16 18:21:06 +08:00
|
|
|
if cname, ok := re["metric"].(map[string]interface{}); ok {
|
2018-11-22 16:22:44 +08:00
|
|
|
if containerName, ok = cname["container_name"].(string); !ok {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if podName, ok = cname["pod_name"].(string); !ok {
|
|
|
|
continue
|
|
|
|
}
|
2018-08-17 12:40:14 +08:00
|
|
|
} else {
|
2018-08-17 11:31:59 +08:00
|
|
|
logrus.Info("metric decode error")
|
2018-08-16 18:21:06 +08:00
|
|
|
}
|
|
|
|
if val, ok := (re["value"]).([]interface{}); ok && len(val) == 2 {
|
2018-08-17 11:31:59 +08:00
|
|
|
valuesBytes = val[1].(string)
|
2018-08-17 12:40:14 +08:00
|
|
|
} else {
|
2018-08-17 11:31:59 +08:00
|
|
|
logrus.Info("value decode error")
|
2018-08-16 18:21:06 +08:00
|
|
|
}
|
2018-11-22 14:33:29 +08:00
|
|
|
if _, ok := memoryUsageMap[podName]; ok {
|
|
|
|
memoryUsageMap[podName][containerName] = valuesBytes
|
|
|
|
} else {
|
|
|
|
memoryUsageMap[podName] = map[string]string{
|
2018-11-22 16:22:44 +08:00
|
|
|
containerName: valuesBytes,
|
2018-11-22 14:33:29 +08:00
|
|
|
}
|
|
|
|
}
|
2018-08-16 18:21:06 +08:00
|
|
|
}
|
2018-11-22 16:22:44 +08:00
|
|
|
return memoryUsageMap, nil
|
2018-08-16 18:21:06 +08:00
|
|
|
}
|
2018-08-17 12:40:14 +08:00
|
|
|
} else {
|
2018-08-17 11:31:59 +08:00
|
|
|
logrus.Error("Body Is empty")
|
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
|
2017-12-28 14:27:00 +08:00
|
|
|
func (s *ServiceAction) TransServieToDelete(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)
|
2018-04-19 13:00:26 +08:00
|
|
|
if !s.statusCli.IsClosedStatus(status) {
|
2017-11-07 11:40:44 +08:00
|
|
|
return fmt.Errorf("unclosed")
|
|
|
|
}
|
|
|
|
tx := db.GetManager().Begin()
|
|
|
|
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
|
|
|
|
}
|
|
|
|
if err := db.GetManager().TenantServiceDaoTransactions(tx).DeleteServiceByServiceID(serviceID); err != nil {
|
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
//删除domain
|
|
|
|
//删除pause
|
|
|
|
//删除tenant_system_pause
|
|
|
|
//删除tenant_service_relation
|
|
|
|
if err := db.GetManager().TenantServiceMountRelationDaoTransactions(tx).DELTenantServiceMountRelationByServiceID(serviceID); err != nil {
|
2017-11-17 12:08:09 +08:00
|
|
|
if err.Error() != gorm.ErrRecordNotFound.Error() {
|
2017-11-07 11:40:44 +08:00
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//删除tenant_service_evn_var
|
|
|
|
if err := db.GetManager().TenantServiceEnvVarDaoTransactions(tx).DELServiceEnvsByServiceID(serviceID); err != nil {
|
2017-11-17 12:08:09 +08:00
|
|
|
if err.Error() != gorm.ErrRecordNotFound.Error() {
|
2017-11-07 11:40:44 +08:00
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//删除tenant_services_port
|
|
|
|
if err := db.GetManager().TenantServicesPortDaoTransactions(tx).DELPortsByServiceID(serviceID); err != nil {
|
2017-11-17 12:08:09 +08:00
|
|
|
if err.Error() != gorm.ErrRecordNotFound.Error() {
|
2017-11-07 11:40:44 +08:00
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//删除tenant_service_mnt_relation
|
|
|
|
if err := db.GetManager().TenantServiceRelationDaoTransactions(tx).DELRelationsByServiceID(serviceID); err != nil {
|
2017-11-17 12:08:09 +08:00
|
|
|
if err.Error() != gorm.ErrRecordNotFound.Error() {
|
2017-11-07 11:40:44 +08:00
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//删除tenant_lb_mapping_port
|
|
|
|
if err := db.GetManager().TenantServiceLBMappingPortDaoTransactions(tx).DELServiceLBMappingPortByServiceID(serviceID); err != nil {
|
2017-11-17 12:08:09 +08:00
|
|
|
if err.Error() != gorm.ErrRecordNotFound.Error() {
|
2017-11-07 11:40:44 +08:00
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//删除tenant_service_volume
|
|
|
|
if err := db.GetManager().TenantServiceVolumeDaoTransactions(tx).DeleteTenantServiceVolumesByServiceID(serviceID); err != nil {
|
2017-11-17 12:08:09 +08:00
|
|
|
if err.Error() != gorm.ErrRecordNotFound.Error() {
|
2017-11-07 11:40:44 +08:00
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//删除service_probe
|
|
|
|
if err := db.GetManager().ServiceProbeDaoTransactions(tx).DELServiceProbesByServiceID(serviceID); err != nil {
|
2017-11-17 12:08:09 +08:00
|
|
|
if err.Error() != gorm.ErrRecordNotFound.Error() {
|
2017-11-07 11:40:44 +08:00
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2017-12-28 13:44:31 +08:00
|
|
|
//TODO: 如果有关联过插件,需要删除该插件相关配置及资源
|
|
|
|
if err := db.GetManager().TenantServicePluginRelationDaoTransactions(tx).DeleteALLRelationByServiceID(serviceID); err != nil {
|
|
|
|
if err.Error() != gorm.ErrRecordNotFound.Error() {
|
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if err := db.GetManager().TenantServicesStreamPluginPortDaoTransactions(tx).DeleteAllPluginMappingPortByServiceID(serviceID); err != nil {
|
|
|
|
if err.Error() != gorm.ErrRecordNotFound.Error() {
|
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if err := db.GetManager().TenantPluginVersionENVDaoTransactions(tx).DeleteEnvByServiceID(serviceID); err != nil {
|
|
|
|
if err.Error() != gorm.ErrRecordNotFound.Error() {
|
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2018-02-26 17:34:27 +08:00
|
|
|
if err := db.GetManager().TenantServiceLabelDaoTransactions(tx).DeleteLabelByServiceID(serviceID); err != nil {
|
|
|
|
if err.Error() != gorm.ErrRecordNotFound.Error() {
|
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2018-12-28 12:33:37 +08:00
|
|
|
// delete gateway related resources
|
|
|
|
httpRules, err := db.GetManager().HttpRuleDaoTransactions(tx).ListByServiceID(serviceID)
|
|
|
|
if err != nil {
|
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
for _, r := range httpRules {
|
|
|
|
if err := db.GetManager().HttpRuleDaoTransactions(tx).DeleteHttpRuleByID(r.UUID); err != nil {
|
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tcpRules, err := db.GetManager().TcpRuleDaoTransactions(tx).ListByServiceID(serviceID)
|
|
|
|
if err != nil {
|
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
for _, r := range tcpRules {
|
|
|
|
if err := db.GetManager().TcpRuleDaoTransactions(tx).DeleteTcpRule(r); err != nil {
|
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2018-03-07 10:18:26 +08:00
|
|
|
//删除plugin etcd资源
|
2017-12-28 14:45:33 +08:00
|
|
|
prefixK := fmt.Sprintf("/resources/define/%s/%s", service.TenantID, service.ServiceAlias)
|
2018-03-07 10:18:26 +08:00
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
defer cancel()
|
|
|
|
_, err = s.EtcdCli.Delete(ctx, prefixK, clientv3.WithPrefix())
|
2017-12-28 13:44:31 +08:00
|
|
|
if err != nil {
|
|
|
|
logrus.Errorf("delete prefix %s from etcd error, %v", prefixK, err)
|
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
2017-11-07 11:40:44 +08:00
|
|
|
if err := tx.Commit().Error; err != nil {
|
|
|
|
tx.Rollback()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
func chekeServiceLabel(v string) string {
|
|
|
|
if strings.Contains(v, "有状态") {
|
|
|
|
return core_util.StatefulServiceType
|
|
|
|
}
|
|
|
|
if strings.Contains(v, "无状态") {
|
|
|
|
return core_util.StatelessServiceType
|
|
|
|
}
|
|
|
|
return v
|
|
|
|
}
|