[ADD]Net Rules function

[DEL] delete v1 api/interface

[REV] optimize structs of api router;update swagger json
This commit is contained in:
崔斌 2017-11-16 19:13:14 +08:00
parent cbd1196f96
commit 9ed78faf46
14 changed files with 1031 additions and 156 deletions

View File

@ -933,6 +933,227 @@
}
}
},
"/v2/tenant/{tenant_name}/services/{service_alias}/net-rule/downstream": {
"post": {
"description": "set NetDownStreamRuleStruct",
"consumes": [
"application/json",
"application/x-protobuf"
],
"produces": [
"application/json",
"application/xml"
],
"tags": [
"v2"
],
"summary": "设置下游网络规则",
"operationId": "setNetDownStreamRuleStruct",
"parameters": [
{
"type": "string",
"x-go-name": "TenantName",
"name": "tenant_name",
"in": "path",
"required": true
},
{
"type": "string",
"x-go-name": "ServiceAlias",
"name": "service_alias",
"in": "path",
"required": true
},
{
"name": "Body",
"in": "body",
"schema": {
"type": "object",
"required": [
"dest_service",
"dest_service_alias",
"port",
"protocol",
"rules"
],
"properties": {
"dest_service": {
"description": "in: body",
"type": "string",
"x-go-name": "DestService"
},
"dest_service_alias": {
"description": "下游服务别名\nin: body",
"type": "string",
"x-go-name": "DestServiceAlias"
},
"port": {
"description": "端口\nin: body",
"type": "integer",
"format": "int64",
"x-go-name": "Port"
},
"protocol": {
"description": "协议\nin: body",
"type": "string",
"x-go-name": "Protocol"
},
"rules": {
"$ref": "#/definitions/NetDownStreamRules"
}
}
}
}
],
"responses": {
"default": {
"description": "统一返回格式",
"schema": {
"$ref": "#/responses/commandResponse"
}
}
}
}
},
"/v2/tenant/{tenant_name}/services/{service_alias}/net-rule/downstream/{dest_service_alias}/{port}": {
"get": {
"description": "set NetDownStreamRuleStruct",
"consumes": [
"application/json",
"application/x-protobuf"
],
"produces": [
"application/json",
"application/xml"
],
"tags": [
"v2"
],
"summary": "获取下游网络规则",
"operationId": "getNetDownStreamRuleStruct",
"parameters": [
{
"type": "string",
"x-go-name": "TenantName",
"name": "tenant_name",
"in": "path",
"required": true
},
{
"type": "string",
"x-go-name": "ServiceAlias",
"name": "service_alias",
"in": "path",
"required": true
},
{
"type": "string",
"x-go-name": "DestServiceAlias",
"name": "dest_service_alias",
"in": "path",
"required": true
},
{
"type": "integer",
"format": "int64",
"x-go-name": "Port",
"name": "port",
"in": "path",
"required": true
}
],
"responses": {
"default": {
"description": "统一返回格式",
"schema": {
"$ref": "#/responses/commandResponse"
}
}
}
},
"put": {
"description": "update NetDownStreamRuleStruct",
"consumes": [
"application/json",
"application/x-protobuf"
],
"produces": [
"application/json",
"application/xml"
],
"tags": [
"v2"
],
"summary": "更新下游网络规则",
"operationId": "updateNetDownStreamRuleStruct",
"parameters": [
{
"type": "string",
"x-go-name": "TenantName",
"name": "tenant_name",
"in": "path",
"required": true
},
{
"type": "string",
"x-go-name": "ServiceAlias",
"name": "service_alias",
"in": "path",
"required": true
},
{
"type": "string",
"x-go-name": "DestServiceAlias",
"name": "dest_service_alias",
"in": "path",
"required": true
},
{
"type": "integer",
"format": "int64",
"x-go-name": "Port",
"name": "port",
"in": "path",
"required": true
},
{
"name": "Body",
"in": "body",
"schema": {
"type": "object",
"required": [
"dest_service",
"protocol",
"rules"
],
"properties": {
"dest_service": {
"description": "in: body",
"type": "string",
"x-go-name": "DestService"
},
"protocol": {
"description": "协议\nin: body",
"type": "string",
"x-go-name": "Protocol"
},
"rules": {
"$ref": "#/definitions/NetDownStreamRules"
}
}
}
}
],
"responses": {
"default": {
"description": "统一返回格式",
"schema": {
"$ref": "#/responses/commandResponse"
}
}
}
}
},
"/v2/tenants": {
"post": {
"description": "add tenant",
@ -5526,6 +5747,38 @@
},
"x-go-package": "github.com/goodrain/rainbond/pkg/api/model"
},
"NetDownStreamRules": {
"description": "NetDownStreamRules NetDownStreamRules",
"type": "object",
"properties": {
"domain": {
"description": "域名转发\nin: body",
"type": "string",
"x-go-name": "Domain"
},
"header": {
"description": "请求头\nin: body",
"type": "string",
"x-go-name": "Header"
},
"limit": {
"description": "限流值\nin:body",
"type": "integer",
"format": "int64",
"x-go-name": "Limit"
},
"prefix": {
"description": "path规则\nin: body",
"type": "string",
"x-go-name": "Prefix"
},
"service_id": {
"type": "string",
"x-go-name": "ServiceID"
}
},
"x-go-package": "github.com/goodrain/rainbond/pkg/api/model"
},
"PluginDefaultENV": {
"description": "PluginDefaultENV 插件默认环境变量",
"type": "object",

View File

@ -1,25 +1,28 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2017 Goodrain Co., Ltd.
// 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.
// 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.
// 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 server
import (
"os"
"os/signal"
"syscall"
"github.com/goodrain/rainbond/cmd/api/option"
"github.com/goodrain/rainbond/pkg/api/controller"
"github.com/goodrain/rainbond/pkg/api/db"
@ -27,9 +30,6 @@ import (
"github.com/goodrain/rainbond/pkg/api/handler"
"github.com/goodrain/rainbond/pkg/api/server"
"github.com/goodrain/rainbond/pkg/event"
"os"
"os/signal"
"syscall"
"github.com/Sirupsen/logrus"
)
@ -76,14 +76,18 @@ func Run(s *option.APIServer) error {
if err := handler.CreateTenantManger(s.Config); err != nil {
logrus.Errorf("create tenant manager error, %v", err)
}
//创建NetRule manager
if err := handler.CreateNetRulesHandler(s.Config); err != nil {
logrus.Errorf("create net-rule manager error, %v", err)
}
//创建license manager
if err := handler.CreateLicenseManger(); err != nil {
logrus.Errorf("create tenant manager error, %v", err)
}
// if err := handler.CreateLicenseManger(); err != nil {
// logrus.Errorf("create tenant manager error, %v", err)
//}
//创建license验证 manager
if err := handler.CreateLicensesInfoManager(); err != nil {
logrus.Errorf("create license check manager error, %v", err)
}
// if err := handler.CreateLicensesInfoManager(); err != nil {
// logrus.Errorf("create license check manager error, %v", err)
// }
//创建v2Router manager
if err := controller.CreateV2RouterManager(s.Config); err != nil {
logrus.Errorf("create v2 route manager error, %v", err)

View File

@ -105,3 +105,11 @@ type PluginInterface interface {
UpdateVersionEnv(w http.ResponseWriter, r *http.Request)
GetPluginDefaultEnvs(w http.ResponseWriter, r *http.Request)
}
//RulesInterface RulesInterface
type RulesInterface interface {
SetDownStreamRule(w http.ResponseWriter, r *http.Request)
GetDownStreamRule(w http.ResponseWriter, r *http.Request)
DeleteDownStreamRule(w http.ResponseWriter, r *http.Request)
UpdateDownStreamRule(w http.ResponseWriter, r *http.Request)
}

View File

@ -45,3 +45,19 @@ func (v2 *V2) pluginRouter() chi.Router {
r.Delete("/build-version/{version_id}", controller.GetManager().DeletePluginBuildVersion)
return r
}
func (v2 *V2) serviceRelatePluginRouter() chi.Router {
r := chi.NewRouter()
//插件
//service relate plugin
// v2/tenant/tenant_name/services/service_alias/plugin/xxx
r.Post("/", controller.GetManager().PluginSet)
r.Put("/", controller.GetManager().PluginSet)
r.Get("/", controller.GetManager().PluginSet)
r.Delete("/{plugin_id}", controller.GetManager().DeletePluginRelation)
// plugin enable set env,包含普通设置和预设可修改部分
r.Post("/{plugin_id}/setenv", controller.GetManager().SetVersionEnv)
r.Put("/{plugin_id}/setenv/{env_name}", controller.GetManager().UpdateVersionEnv)
r.Get("/{plugin_id}/envs", controller.GetManager().GePluginEnvWhichCanBeSet)
return r
}

View File

@ -164,15 +164,10 @@ func (v2 *V2) serviceRouter() chi.Router {
r.Delete("/domains/{domain_name}", controller.GetManager().Entrance)
//插件
// add plugin
r.Post("/plugin", controller.GetManager().PluginSet)
r.Put("/plugin", controller.GetManager().PluginSet)
r.Get("/plugin", controller.GetManager().PluginSet)
r.Delete("/plugin/{plugin_id}", controller.GetManager().DeletePluginRelation)
// plugin enable set env,包含普通设置和预设可修改部分
r.Post("/plugin/{plugin_id}/setenv", controller.GetManager().SetVersionEnv)
r.Put("/plugin/{plugin_id}/setenv/{env_name}", controller.GetManager().UpdateVersionEnv)
r.Get("/plugin/{plugin_id}/envs", controller.GetManager().GePluginEnvWhichCanBeSet)
r.Mount("/plugin", v2.serviceRelatePluginRouter())
//rule
r.Mount("/net-rule", v2.rulesRouter())
return r
}

View File

@ -0,0 +1,52 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2017 Goodrain Co., Ltd.
// 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.
// 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.
// 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 version2
import (
"github.com/go-chi/chi"
"github.com/goodrain/rainbond/pkg/api/controller"
)
//PluginRouter plugin router
func (v2 *V2) rulesRouter() chi.Router {
r := chi.NewRouter()
// service rule
// url: v2/tenant/{tenant_name}/services/{service_alias}/net-rule/xxx
// -- --
//downstream
r.Mount("/downstream", v2.downstreamRouter())
//upstream
r.Mount("/upstream", v2.upstreamRouter())
return r
}
func (v2 *V2) downstreamRouter() chi.Router {
r := chi.NewRouter()
r.Post("/", controller.GetManager().SetDownStreamRule)
//r.Get("/")
r.Get("/{dest_service_alias}/{port}", controller.GetManager().GetDownStreamRule)
r.Put("/{dest_service_alias}/{port}", controller.GetManager().UpdateDownStreamRule)
//r.Delete("/{service_alias}/{port}")
return r
}
func (v2 *V2) upstreamRouter() chi.Router {
r := chi.NewRouter()
return r
}

View File

@ -42,6 +42,7 @@ type V2Manager interface {
apiFunc.ServiceInterface
apiFunc.LogInterface
apiFunc.PluginInterface
apiFunc.RulesInterface
}
var defaultV2Manager V2Manager

View File

@ -0,0 +1,158 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2017 Goodrain Co., Ltd.
// 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.
// 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.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package controller
import (
"net/http"
"github.com/goodrain/rainbond/pkg/api/handler"
"github.com/goodrain/rainbond/pkg/api/middleware"
api_model "github.com/goodrain/rainbond/pkg/api/model"
httputil "github.com/goodrain/rainbond/pkg/util/http"
)
//SetDownStreamRule 设置下游规则
// swagger:operation POST /v2/tenant/{tenant_name}/services/{service_alias}/net-rule/downstream v2 setNetDownStreamRuleStruct
//
// 设置下游网络规则
//
// set NetDownStreamRuleStruct
//
// ---
// consumes:
// - application/json
// - application/x-protobuf
//
// produces:
// - application/json
// - application/xml
//
// responses:
// default:
// schema:
// "$ref": "#/responses/commandResponse"
// description: 统一返回格式
func (t *TenantStruct) SetDownStreamRule(w http.ResponseWriter, r *http.Request) {
var rs api_model.SetNetDownStreamRuleStruct
ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &rs.Body, nil)
if !ok {
return
}
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
tenantName := r.Context().Value(middleware.ContextKey("tenant_name")).(string)
serviceAlias := r.Context().Value(middleware.ContextKey("service_alias")).(string)
tenantID := r.Context().Value(middleware.ContextKey("tenant_id")).(string)
rs.TenantName = tenantName
rs.ServiceAlias = serviceAlias
rs.Body.Rules.ServiceID = serviceID
if err := handler.GetRulesManager().CreateDownStreamNetRules(tenantID, &rs); err != nil {
err.Handle(r, w)
return
}
httputil.ReturnSuccess(r, w, nil)
}
//GetDownStreamRule 获取下游规则
// swagger:operation GET /v2/tenant/{tenant_name}/services/{service_alias}/net-rule/downstream/{dest_service_alias}/{port} v2 getNetDownStreamRuleStruct
//
// 获取下游网络规则
//
// set NetDownStreamRuleStruct
//
// ---
// consumes:
// - application/json
// - application/x-protobuf
//
// produces:
// - application/json
// - application/xml
//
// responses:
// default:
// schema:
// "$ref": "#/responses/commandResponse"
// description: 统一返回格式
func (t *TenantStruct) GetDownStreamRule(w http.ResponseWriter, r *http.Request) {
serviceAlias := r.Context().Value(middleware.ContextKey("service_alias")).(string)
destServiceAlias := r.Context().Value(middleware.ContextKey("dest_service_alias")).(string)
tenantID := r.Context().Value(middleware.ContextKey("tenant_id")).(string)
port := r.Context().Value(middleware.ContextKey("port")).(string)
nrs, err := handler.GetRulesManager().GetDownStreamNetRule(
tenantID,
serviceAlias,
destServiceAlias,
port)
if err != nil {
err.Handle(r, w)
return
}
httputil.ReturnSuccess(r, w, nrs)
}
//DeleteDownStreamRule 删除下游规则
func (t *TenantStruct) DeleteDownStreamRule(w http.ResponseWriter, r *http.Request) {}
//UpdateDownStreamRule 更新下游规则
// swagger:operation PUT /v2/tenant/{tenant_name}/services/{service_alias}/net-rule/downstream/{dest_service_alias}/{port} v2 updateNetDownStreamRuleStruct
//
// 更新下游网络规则
//
// update NetDownStreamRuleStruct
//
// ---
// consumes:
// - application/json
// - application/x-protobuf
//
// produces:
// - application/json
// - application/xml
//
// responses:
// default:
// schema:
// "$ref": "#/responses/commandResponse"
// description: 统一返回格式
func (t *TenantStruct) UpdateDownStreamRule(w http.ResponseWriter, r *http.Request) {
var urs api_model.UpdateNetDownStreamRuleStruct
ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &urs.Body, nil)
if !ok {
return
}
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
tenantName := r.Context().Value(middleware.ContextKey("tenant_name")).(string)
serviceAlias := r.Context().Value(middleware.ContextKey("service_alias")).(string)
tenantID := r.Context().Value(middleware.ContextKey("tenant_id")).(string)
destServiceAlias := r.Context().Value(middleware.ContextKey("dest_service_alias")).(string)
port := r.Context().Value(middleware.ContextKey("tenant_id")).(int)
urs.DestServiceAlias = destServiceAlias
urs.Port = port
urs.ServiceAlias = serviceAlias
urs.TenantName = tenantName
urs.Body.Rules.ServiceID = serviceID
if err := handler.GetRulesManager().UpdateDownStreamNetRule(tenantID, &urs); err != nil {
err.Handle(r, w)
return
}
httputil.ReturnSuccess(r, w, nil)
}

View File

@ -1,184 +1,182 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2017 Goodrain Co., Ltd.
// 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.
// 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.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package controller
import (
"fmt"
"net/http"
"github.com/goodrain/rainbond/pkg/api/middleware"
api_model "github.com/goodrain/rainbond/pkg/api/model"
"github.com/goodrain/rainbond/pkg/event"
"github.com/goodrain/rainbond/pkg/worker/discover/model"
"fmt"
"net/http"
validator "github.com/thedevsaddam/govalidator"
dbmodel "github.com/goodrain/rainbond/pkg/db/model"
"github.com/goodrain/rainbond/pkg/api/handler"
httputil "github.com/goodrain/rainbond/pkg/util/http"
tutil "github.com/goodrain/rainbond/pkg/util"
"github.com/Sirupsen/logrus"
"time"
"github.com/Sirupsen/logrus"
"github.com/goodrain/rainbond/pkg/api/handler"
"github.com/goodrain/rainbond/pkg/db"
dbmodel "github.com/goodrain/rainbond/pkg/db/model"
tutil "github.com/goodrain/rainbond/pkg/util"
httputil "github.com/goodrain/rainbond/pkg/util/http"
validator "github.com/thedevsaddam/govalidator"
)
const TIMELAYOUT = "2006-01-02T15:04:05"
//TIMELAYOUT TIMELAYOUT
const TIMELAYOUT = "2006-01-02T15:04:05"
func createEvent(serviceID,optType,tenantID,deployVersion string) (*dbmodel.ServiceEvent,int,error) {
eventID:=tutil.NewUUID()
logrus.Infof("creating event,id is %s",eventID)
event:=dbmodel.ServiceEvent{}
event.EventID=eventID
event.ServiceID=serviceID
event.OptType=optType
event.TenantID=tenantID
now:=time.Now()
func createEvent(serviceID, optType, tenantID, deployVersion string) (*dbmodel.ServiceEvent, int, error) {
eventID := tutil.NewUUID()
logrus.Infof("creating event,id is %s", eventID)
event := dbmodel.ServiceEvent{}
event.EventID = eventID
event.ServiceID = serviceID
event.OptType = optType
event.TenantID = tenantID
now := time.Now()
timeNow := now.Format(TIMELAYOUT)
event.StartTime=timeNow
event.UserName="system"
version:=deployVersion
oldDeployVersion:=""
if deployVersion=="" {
service,err:=db.GetManager().TenantServiceDao().GetServiceByID(serviceID)
event.StartTime = timeNow
event.UserName = "system"
version := deployVersion
oldDeployVersion := ""
if deployVersion == "" {
service, err := db.GetManager().TenantServiceDao().GetServiceByID(serviceID)
if err != nil {
return nil,3,nil
return nil, 3, nil
}
version=service.DeployVersion
version = service.DeployVersion
}
events,err:=db.GetManager().ServiceEventDao().GetEventByServiceID(serviceID)
events, err := db.GetManager().ServiceEventDao().GetEventByServiceID(serviceID)
if err != nil {
}
if len(events) != 0 {
latestEvent:=events[0]
oldDeployVersion=latestEvent.DeployVersion
latestEvent := events[0]
oldDeployVersion = latestEvent.DeployVersion
}
event.DeployVersion=version
event.OldDeployVersion=oldDeployVersion
event.DeployVersion = version
event.OldDeployVersion = oldDeployVersion
status,err:=checkCanAddEvent(serviceID)
status, err := checkCanAddEvent(serviceID)
if err != nil {
return nil,status,nil
return nil, status, nil
}
if status==0 {
if status == 0 {
db.GetManager().ServiceEventDao().AddModel(&event)
//todo add timmer auto timeout
go autoTimeOut(&event)
return &event,status,nil
}else {
return nil,status,nil
return &event, status, nil
}
return nil, status, nil
}
func autoTimeOut(event *dbmodel.ServiceEvent) {
var timer *time.Timer
//todo if 构建
if event.OptType=="build" {
timer=time.NewTimer(3*time.Minute)
}else {
timer=time.NewTimer(30*time.Second)
if event.OptType == "build" {
timer = time.NewTimer(3 * time.Minute)
} else {
timer = time.NewTimer(30 * time.Second)
}
for {
select {
case <-timer.C:
//时间到检查是否完成未完成设置为timeout
e,err:=db.GetManager().ServiceEventDao().GetEventByEventID(event.EventID)
e, err := db.GetManager().ServiceEventDao().GetEventByEventID(event.EventID)
if err != nil {
return
}
if e.FinalStatus == "" {
//未完成
e.FinalStatus = "timeout"
logrus.Warnf("event id:%s time out,",event.EventID)
err=db.GetManager().ServiceEventDao().UpdateModel(e)
return
}else {
logrus.Warnf("event id:%s time out,", event.EventID)
err = db.GetManager().ServiceEventDao().UpdateModel(e)
return
}
return
}
}
}
func checkCanAddEvent(s string) (int,error){
events,err:=db.GetManager().ServiceEventDao().GetEventByServiceID(s)
func checkCanAddEvent(s string) (int, error) {
events, err := db.GetManager().ServiceEventDao().GetEventByServiceID(s)
if err != nil {
return 3,err
return 3, err
}
if len(events) == 0 {
//service 首个event
return 0,nil
return 0, nil
}
latestEvent:=events[0]
if latestEvent.FinalStatus=="" {
latestEvent := events[0]
if latestEvent.FinalStatus == "" {
//未完成
timeOut,err:=checkEventTimeOut(latestEvent)
timeOut, err := checkEventTimeOut(latestEvent)
if err != nil {
return 3,err
return 3, err
}
if timeOut {
//未完成,超时
return 1,nil
}else{
//未完成,未超时
return 2,nil
return 1, nil
}
}else{
//已完成
return 0,nil
//未完成,未超时
return 2, nil
}
//已完成
return 0, nil
}
func checkEventTimeOut(event *dbmodel.ServiceEvent) (bool,error) {
func checkEventTimeOut(event *dbmodel.ServiceEvent) (bool, error) {
startTime := event.StartTime
start,err:=time.Parse(TIMELAYOUT,startTime)
if err!=nil {
return true,err
start, err := time.Parse(TIMELAYOUT, startTime)
if err != nil {
return true, err
}
if event.OptType == "deploy" || event.OptType == "create"{
if event.OptType == "deploy" || event.OptType == "create" {
end:=start.Add(3*time.Minute)
if (time.Now().After(end)){
end := start.Add(3 * time.Minute)
if time.Now().After(end) {
event.FinalStatus = "timeout"
err=db.GetManager().ServiceEventDao().UpdateModel(event)
return true,err
err = db.GetManager().ServiceEventDao().UpdateModel(event)
return true, err
}
}else {
end:=start.Add(30*time.Second)
if (time.Now().After(end)){
} else {
end := start.Add(30 * time.Second)
if time.Now().After(end) {
event.FinalStatus = "timeout"
err=db.GetManager().ServiceEventDao().UpdateModel(event)
return true,err
err = db.GetManager().ServiceEventDao().UpdateModel(event)
return true, err
}
}
return false,nil
return false, nil
}
func handleStatus(status int,err error,w http.ResponseWriter, r *http.Request){
if status!=0 {
func handleStatus(status int, err error, w http.ResponseWriter, r *http.Request) {
if status != 0 {
logrus.Error("应用启动任务发送失败 "+err.Error(), map[string]string{"step": "callback", "status": "failure"})
if status == 1 {
httputil.ReturnError(r, w, 400, "last time out .")
return
}
if status == 2{
if status == 2 {
httputil.ReturnError(r, w, 400, "last event unfinish.")
return
}
@ -186,6 +184,7 @@ func handleStatus(status int,err error,w http.ResponseWriter, r *http.Request){
return
}
}
//StartService StartService
func (t *TenantStruct) StartService(w http.ResponseWriter, r *http.Request) {
// swagger:operation POST /v2/tenants/{tenant_name}/services/{service_alias}/start v2 startService
@ -221,9 +220,8 @@ func (t *TenantStruct) StartService(w http.ResponseWriter, r *http.Request) {
tenantID := r.Context().Value(middleware.ContextKey("tenant_id")).(string)
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
sEvent,status,err:=createEvent(serviceID,"start",tenantID,"")
handleStatus(status,err,w,r)
sEvent, status, err := createEvent(serviceID, "start", tenantID, "")
handleStatus(status, err, w, r)
eventID := sEvent.EventID
@ -241,7 +239,7 @@ func (t *TenantStruct) StartService(w http.ResponseWriter, r *http.Request) {
return
}
logger.Info("应用启动任务发送成功 ", map[string]string{"step": "start-service", "status": "starting"})
httputil.ReturnSuccess(r,w,sEvent)
httputil.ReturnSuccess(r, w, sEvent)
return
}
@ -268,18 +266,10 @@ func (t *TenantStruct) StopService(w http.ResponseWriter, r *http.Request) {
// "$ref": "#/responses/commandResponse"
// description: 统一返回格式
logrus.Debugf("trans stop service")
//rules := validator.MapData{
// //"event_id": []string{"required"},
//}
//_, ok := httputil.ValidatorRequestMapAndErrorResponse(r, w, rules, nil)
//if !ok {
// return
//}
tenantID := r.Context().Value(middleware.ContextKey("tenant_id")).(string)
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
sEvent,status,err:=createEvent(serviceID,"stop",tenantID,"")
handleStatus(status,err,w,r)
sEvent, status, err := createEvent(serviceID, "stop", tenantID, "")
handleStatus(status, err, w, r)
//save event
eventID := sEvent.EventID
logger := event.GetManager().GetLogger(eventID)
@ -296,7 +286,7 @@ func (t *TenantStruct) StopService(w http.ResponseWriter, r *http.Request) {
return
}
logger.Info("应用停止任务发送成功 ", map[string]string{"step": "stop-service", "status": "starting"})
httputil.ReturnSuccess(r,w,sEvent)
httputil.ReturnSuccess(r, w, sEvent)
}
//RestartService RestartService
@ -332,8 +322,8 @@ func (t *TenantStruct) RestartService(w http.ResponseWriter, r *http.Request) {
//}
tenantID := r.Context().Value(middleware.ContextKey("tenant_id")).(string)
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
sEvent,status,err:=createEvent(serviceID,"restart",tenantID,"")
handleStatus(status,err,w,r)
sEvent, status, err := createEvent(serviceID, "restart", tenantID, "")
handleStatus(status, err, w, r)
//save event
eventID := sEvent.EventID
logger := event.GetManager().GetLogger(eventID)
@ -350,7 +340,7 @@ func (t *TenantStruct) RestartService(w http.ResponseWriter, r *http.Request) {
return
}
logger.Info("应用重启任务发送成功 ", map[string]string{"step": "restart-service", "status": "starting"})
httputil.ReturnSuccess(r,w,sEvent)
httputil.ReturnSuccess(r, w, sEvent)
return
}
@ -389,8 +379,8 @@ func (t *TenantStruct) VerticalService(w http.ResponseWriter, r *http.Request) {
}
tenantID := r.Context().Value(middleware.ContextKey("tenant_id")).(string)
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
sEvent,status,err:=createEvent(serviceID,"update",tenantID,"")
handleStatus(status,err,w,r)
sEvent, status, err := createEvent(serviceID, "update", tenantID, "")
handleStatus(status, err, w, r)
eventID := sEvent.EventID
logger := event.GetManager().GetLogger(eventID)
@ -410,7 +400,7 @@ func (t *TenantStruct) VerticalService(w http.ResponseWriter, r *http.Request) {
return
}
logger.Info("应用垂直升级任务发送成功 ", map[string]string{"step": "vertical-service", "status": "starting"})
httputil.ReturnSuccess(r,w,sEvent)
httputil.ReturnSuccess(r, w, sEvent)
}
//HorizontalService HorizontalService
@ -446,8 +436,8 @@ func (t *TenantStruct) HorizontalService(w http.ResponseWriter, r *http.Request)
}
tenantID := r.Context().Value(middleware.ContextKey("tenant_id")).(string)
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
sEvent,status,err:=createEvent(serviceID,"update",tenantID,"")
handleStatus(status,err,w,r)
sEvent, status, err := createEvent(serviceID, "update", tenantID, "")
handleStatus(status, err, w, r)
//save event
eventID := sEvent.EventID
logger := event.GetManager().GetLogger(eventID)
@ -465,7 +455,7 @@ func (t *TenantStruct) HorizontalService(w http.ResponseWriter, r *http.Request)
return
}
logger.Info("应用水平升级任务发送成功 ", map[string]string{"step": "horizontal-service", "status": "starting"})
httputil.ReturnSuccess(r,w,sEvent)
httputil.ReturnSuccess(r, w, sEvent)
}
//BuildService BuildService
@ -559,8 +549,8 @@ func (t *TenantStruct) UpgradeService(w http.ResponseWriter, r *http.Request) {
tenantID := r.Context().Value(middleware.ContextKey("tenant_id")).(string)
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
sEvent,status,err:=createEvent(serviceID,"update",tenantID,data["deploy_version"].(string))
handleStatus(status,err,w,r)
sEvent, status, err := createEvent(serviceID, "update", tenantID, data["deploy_version"].(string))
handleStatus(status, err, w, r)
eventID := sEvent.EventID
logger := event.GetManager().GetLogger(eventID)
@ -579,7 +569,7 @@ func (t *TenantStruct) UpgradeService(w http.ResponseWriter, r *http.Request) {
return
}
logger.Info("应用升级任务发送成功 ", map[string]string{"step": "upgrade-service", "status": "starting"})
httputil.ReturnSuccess(r,w,sEvent)
httputil.ReturnSuccess(r, w, sEvent)
}
//CheckCode CheckCode
@ -696,15 +686,15 @@ func (t *TenantStruct) RollBack(w http.ResponseWriter, r *http.Request) {
}
tenantID := r.Context().Value(middleware.ContextKey("tenant_id")).(string)
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
sEvent,status,err:=createEvent(serviceID,"rollback",tenantID,data["deploy_version"].(string))
handleStatus(status,err,w,r)
sEvent, status, err := createEvent(serviceID, "rollback", tenantID, data["deploy_version"].(string))
handleStatus(status, err, w, r)
eventID := sEvent.EventID
logger := event.GetManager().GetLogger(eventID)
defer event.CloseManager()
rs := &api_model.RollbackStruct{
TenantID: tenantID,
ServiceID: serviceID,
EventID: eventID,
TenantID: tenantID,
ServiceID: serviceID,
EventID: eventID,
//EventID: data["event_id"].(string),
//todo
DeployVersion: data["deploy_version"].(string),

136
pkg/api/handler/netRules.go Normal file
View File

@ -0,0 +1,136 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2017 Goodrain Co., Ltd.
// 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.
// 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.
// 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"
"fmt"
"time"
"github.com/pquerna/ffjson/ffjson"
"github.com/Sirupsen/logrus"
"github.com/coreos/etcd/clientv3"
"github.com/goodrain/rainbond/cmd/api/option"
api_model "github.com/goodrain/rainbond/pkg/api/model"
"github.com/goodrain/rainbond/pkg/api/util"
)
//NetRulesAction rules action struct
type NetRulesAction struct {
etcdCli *clientv3.Client
}
//CreateNetRulesManager get net rules manager
func CreateNetRulesManager(conf option.Config) (*NetRulesAction, error) {
cli, err := clientv3.New(clientv3.Config{
Endpoints: conf.EtcdEndpoint,
DialTimeout: 5 * time.Second,
})
if err != nil {
logrus.Errorf("create etcd client v3 error, %v", err)
return nil, err
}
defer cli.Close()
return &NetRulesAction{
etcdCli: cli,
}, nil
}
//CreateDownStreamNetRules CreateDownStreamNetRules
func (n *NetRulesAction) CreateDownStreamNetRules(
tenantID string,
rs *api_model.SetNetDownStreamRuleStruct) *util.APIHandleError {
k := fmt.Sprintf("/netRules/%s/%s/downstream/%s/%v",
tenantID, rs.ServiceAlias, rs.Body.DestServiceAlias, rs.Body.Port)
sb := &api_model.NetRulesDownStreamBody{
DestService: rs.Body.DestService,
DestServiceAlias: rs.Body.DestServiceAlias,
Port: rs.Body.Port,
Protocol: rs.Body.Protocol,
Rules: rs.Body.Rules,
}
v, err := ffjson.Marshal(sb)
if err != nil {
logrus.Errorf("mashal etcd value error, %v", err)
return util.CreateAPIHandleError(500, err)
}
_, err = n.etcdCli.Put(context.TODO(), k, string(v))
if err != nil {
logrus.Errorf("put k %s into etcd error, %v", k, err)
return util.CreateAPIHandleError(500, err)
}
//TODO: store mysql
return nil
}
//GetDownStreamNetRule GetDownStreamNetRule
func (n *NetRulesAction) GetDownStreamNetRule(
tenantID,
serviceAlias,
destServiceAlias,
port string) (*api_model.NetRulesDownStreamBody, *util.APIHandleError) {
k := fmt.Sprintf(
"/netRules/%s/%s/downstream/%s/%v",
tenantID,
serviceAlias,
destServiceAlias,
port)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
resp, err := n.etcdCli.Get(ctx, k)
cancel()
if err != nil {
logrus.Errorf("get etcd value error, %v", err)
return nil, util.CreateAPIHandleError(500, err)
}
if resp.Count != 0 {
v := resp.Kvs[0].Value
var sb api_model.NetRulesDownStreamBody
if err := ffjson.Unmarshal(v, &sb); err != nil {
logrus.Errorf("unmashal etcd v error, %v", err)
return nil, util.CreateAPIHandleError(500, err)
}
return &sb, nil
}
//TODO: query mysql
//TODO: create etcd record
return nil, nil
}
//UpdateDownStreamNetRule UpdateDownStreamNetRule
func (n *NetRulesAction) UpdateDownStreamNetRule(
tenantID string,
urs *api_model.UpdateNetDownStreamRuleStruct) *util.APIHandleError {
srs := &api_model.SetNetDownStreamRuleStruct{
TenantName: urs.TenantName,
ServiceAlias: urs.ServiceAlias,
}
srs.Body.DestService = urs.Body.DestService
srs.Body.DestServiceAlias = urs.DestServiceAlias
srs.Body.Port = urs.Port
srs.Body.Protocol = urs.Body.Protocol
srs.Body.Rules = urs.Body.Rules
//TODO: update mysql transaction
if err := n.CreateDownStreamNetRules(tenantID, srs); err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,60 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2017 Goodrain Co., Ltd.
// 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.
// 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.
// 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 (
"github.com/goodrain/rainbond/cmd/api/option"
api_model "github.com/goodrain/rainbond/pkg/api/model"
"github.com/goodrain/rainbond/pkg/api/util"
)
//NetRulesHandler net rules handler
type NetRulesHandler interface {
CreateDownStreamNetRules(
tenantID string,
rs *api_model.SetNetDownStreamRuleStruct) *util.APIHandleError
GetDownStreamNetRule(
tenantID,
serviceAlias,
destServiceAlias,
port string) (*api_model.NetRulesDownStreamBody, *util.APIHandleError)
UpdateDownStreamNetRule(
tenantID string,
urs *api_model.UpdateNetDownStreamRuleStruct) *util.APIHandleError
}
var defaultNetRulesHandler NetRulesHandler
//CreateNetRulesHandler create plugin handler
func CreateNetRulesHandler(conf option.Config) error {
var err error
if defaultNetRulesHandler != nil {
return nil
}
defaultNetRulesHandler, err = CreateNetRulesManager(conf)
if err != nil {
return err
}
return nil
}
//GetRulesManager get manager
func GetRulesManager() NetRulesHandler {
return defaultNetRulesHandler
}

View File

@ -0,0 +1,75 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2017 Goodrain Co., Ltd.
// 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.
// 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.
// 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"
"fmt"
"time"
"github.com/coreos/etcd/clientv3"
api_model "github.com/goodrain/rainbond/pkg/api/model"
"testing"
)
func TestStoreETCD(t *testing.T) {
cli, err := clientv3.New(clientv3.Config{
Endpoints: []string{"127.0.0.1:2379"},
DialTimeout: 5 * time.Second,
})
if err != nil {
t.Error(err)
}
nra := &NetRulesAction{
etcdCli: cli,
}
rules := &api_model.NetDownStreamRules{
Limit: 1024,
Header: "E1:V1,E2:V2",
Domain: "test.redis.com",
Prefix: "/redis",
}
srs := &api_model.SetNetDownStreamRuleStruct{
TenantName: "123",
ServiceAlias: "grtest12",
}
srs.Body.DestService = "redis"
srs.Body.DestServiceAlias = "grtest34"
srs.Body.Port = 6379
srs.Body.Protocol = "tcp"
srs.Body.Rules = rules
tenantID := "tenantid1b50sfadfadfafadfadfadf"
if err := nra.CreateDownStreamNetRules(tenantID, srs); err != nil {
t.Error(err)
}
k := fmt.Sprintf("/netRules/%s/%s/downstream/%s/%v",
tenantID, srs.ServiceAlias, srs.Body.DestServiceAlias, srs.Body.Port)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
v, err := cli.Get(ctx, k)
cancel()
if err != nil {
t.Error(err)
}
fmt.Printf("v is %v\n", string(v.Kvs[0].Value))
}

View File

@ -0,0 +1,130 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2017 Goodrain Co., Ltd.
// 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.
// 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.
// 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 model
//SetNetDownStreamRuleStruct SetNetDownStreamRuleStruct
//swagger:parameters setNetDownStreamRuleStruct
type SetNetDownStreamRuleStruct struct {
// in: path
// required: true
TenantName string `json:"tenant_name"`
// in: path
// required: true
ServiceAlias string `json:"service_alias"`
// in: body
Body struct {
//in: body
//required: true
DestService string `json:"dest_service" validate:"dest_service"`
//下游服务别名
//in: body
//required: true
DestServiceAlias string `json:"dest_service_alias" validate:"dest_service_alias"`
//端口
//in: body
//required: true
Port int `json:"port" validate:"port"`
//协议
//in: body
//required: true
Protocol string `json:"protocol" validate:"protocol|between:tcp,http"`
//规则体
//in: body
//required: true
Rules *NetDownStreamRules `json:"rules" validate:"rules"`
}
}
//NetRulesDownStreamBody NetRulesDownStreamBody
type NetRulesDownStreamBody struct {
DestService string `json:"dest_service"`
DestServiceAlias string `json:"dest_service_alias"`
Port int `json:"port"`
Protocol string `json:"protocol"`
Rules *NetDownStreamRules `json:"rules"`
}
//NetDownStreamRules NetDownStreamRules
type NetDownStreamRules struct {
//限流值
//in:body
//required: false
Limit int `json:"limit" validate:"limit|numeric_between:0,1024"`
//请求头
//in: body
//required: false
Header string `json:"header" validate:"header"`
//域名转发
//in: body
//required: false
Domain string `json:"domain" validate:"domain"`
//path规则
//in: body
//required: false
Prefix string `json:"prefix" validate:"prefix"`
ServiceID string `json:"service_id" validate:"service_id"`
}
//GetNetDownStreamRuleStruct GetNetDownStreamRuleStruct
//swagger:parameters getNetDownStreamRuleStruct
type GetNetDownStreamRuleStruct struct {
// in: path
// required: true
TenantName string `json:"tenant_name" validate:"tenant_name"`
// in: path
// required: true
ServiceAlias string `json:"service_alias" validate:"service_alias"`
// in: path
// required: true
DestServiceAlias string `json:"dest_service_alias" validate:"dest_service_alias"`
// in: path
// required: true
Port int `json:"port" validate:"port|numeric_between:1,65535"`
}
//UpdateNetDownStreamRuleStruct UpdateNetDownStreamRuleStruct
//swagger:parameters updateNetDownStreamRuleStruct
type UpdateNetDownStreamRuleStruct struct {
// in: path
// required: true
TenantName string `json:"tenant_name" validate:"tenant_name"`
// in: path
// required: true
ServiceAlias string `json:"service_alias" validate:"service_alias"`
// in: path
// required: true
DestServiceAlias string `json:"dest_service_alias" validate:"dest_service_alias"`
// in: path
// required: true
Port int `json:"port" validate:"port|numeric_between:1,65535"`
// in: body
Body struct {
//in: body
//required: true
DestService string `json:"dest_service" validate:"dest_service"`
//协议
//in: body
//required: true
Protocol string `json:"protocol" validate:"protocol|between:tcp,http"`
//规则体
//in: body
//required: true
Rules *NetDownStreamRules `json:"rules" validate:"rules"`
}
}

View File

@ -1,36 +1,34 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2017 Goodrain Co., Ltd.
// 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.
// 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.
// 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 server
import (
"github.com/goodrain/rainbond/cmd/api/option"
"github.com/goodrain/rainbond/pkg/api/singleton"
"context"
"net/http"
"os"
"time"
"github.com/goodrain/rainbond/cmd/api/option"
"github.com/goodrain/rainbond/pkg/api/apiRouters/doc"
"github.com/goodrain/rainbond/pkg/api/apiRouters/license"
"github.com/goodrain/rainbond/pkg/api/apiRouters/version1"
"github.com/goodrain/rainbond/pkg/api/apiRouters/version2"
"github.com/goodrain/rainbond/pkg/api/apiRouters/websocket"
@ -108,22 +106,21 @@ func (m *Manager) Stop() error {
//Run run
func (m *Manager) Run() {
v1FuncAPI, s, err := singleton.NewV1Singleton(m.conf)
if err != nil {
logrus.Errorf("V1 create manager error. %v", err)
}
v1R := &version1.V1Routes{
ServiceStruct: s,
APIFuncV1: v1FuncAPI,
}
// v1FuncAPI, s, err := singleton.NewV1Singleton(m.conf)
// if err != nil {
// logrus.Errorf("V1 create manager error. %v", err)
// }
// v1R := &version1.V1Routes{
// ServiceStruct: s,
// APIFuncV1: v1FuncAPI,
// }
v2R := &version2.V2{}
//swagger 路由
m.r.Mount("/v1", v1R.Routes())
//m.r.Mount("/v1", v1R.Routes())
m.r.Mount("/v2", v2R.Routes())
m.r.Mount("/", doc.Routes())
m.r.Mount("/license", license.Routes())
//m.r.Mount("/func/", rootFunc.Routes())
m.r.NotFound(v1R.UnFoundRequest)
//m.r.NotFound(v1R.UnFoundRequest)
//开启对浏览器的websocket服务和文件服务
go func() {
websocketRouter := chi.NewRouter()