diff --git a/api/api/api_interface.go b/api/api/api_interface.go
index c3bbbd8e1..7880b11eb 100644
--- a/api/api/api_interface.go
+++ b/api/api/api_interface.go
@@ -142,7 +142,12 @@ type Gatewayer interface {
RuleConfig(w http.ResponseWriter, r *http.Request)
}
-// ThirdPartyServicer is a interface for defining methods for third-party service.
+// ThirdPartyServicer is an interface for defining methods for third-party service.
type ThirdPartyServicer interface {
Endpoints(w http.ResponseWriter, r *http.Request)
}
+
+// Labeler is an interface for defining methods to get information of labels.
+type Labeler interface {
+ Labels(w http.ResponseWriter, r *http.Request)
+}
diff --git a/api/api_routers/version2/v2Routers.go b/api/api_routers/version2/v2Routers.go
index 10e96cf34..86b9c45e1 100644
--- a/api/api_routers/version2/v2Routers.go
+++ b/api/api_routers/version2/v2Routers.go
@@ -226,6 +226,7 @@ func (v2 *V2) clusterRouter() chi.Router {
func (v2 *V2) resourcesRouter() chi.Router {
r := chi.NewRouter()
+ r.Get("/labels", controller.GetManager().Labels)
r.Post("/tenants", controller.GetManager().TenantResources)
r.Post("/services", controller.GetManager().ServiceResources)
r.Get("/tenants/sum", controller.GetManager().SumTenants)
diff --git a/api/controller/app.go b/api/controller/app.go
index dbf5563d8..8ac4713b6 100644
--- a/api/controller/app.go
+++ b/api/controller/app.go
@@ -1,6 +1,7 @@
package controller
import (
+ "encoding/json"
"fmt"
"net/http"
diff --git a/api/controller/labels.go b/api/controller/labels.go
new file mode 100644
index 000000000..2b1515c14
--- /dev/null
+++ b/api/controller/labels.go
@@ -0,0 +1,42 @@
+// 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 .
+
+package controller
+
+import (
+ "github.com/goodrain/rainbond/cmd/api/option"
+ httputil "github.com/goodrain/rainbond/util/http"
+ "net/http"
+)
+
+// LabelController implements Labeler.
+type LabelController struct {
+ optconfig *option.Config
+}
+
+// Labels - get -> list labels
+func (l *LabelController) Labels(w http.ResponseWriter, r *http.Request) {
+ switch r.Method {
+ case "GET":
+ l.listLabels(w, r)
+ }
+}
+
+func (l *LabelController) listLabels(w http.ResponseWriter, r *http.Request) {
+ httputil.ReturnSuccess(r, w, l.optconfig.EnableFeature)
+}
diff --git a/api/controller/manager.go b/api/controller/manager.go
index 21933b42f..45475c5ca 100644
--- a/api/controller/manager.go
+++ b/api/controller/manager.go
@@ -48,6 +48,7 @@ type V2Manager interface {
api.AppInterface
api.Gatewayer
api.ThirdPartyServicer
+ api.Labeler
}
var defaultV2Manager V2Manager
@@ -79,5 +80,7 @@ func NewManager(conf option.Config, statusCli *client.AppRuntimeSyncClient) (*V2
v2r.GatewayStruct.MQClient = mqClient
v2r.GatewayStruct.cfg = &conf
+
+ v2r.LabelController.optconfig = &conf
return &v2r, nil
}
diff --git a/api/controller/resources.go b/api/controller/resources.go
index 1511bd951..cb09fcff9 100644
--- a/api/controller/resources.go
+++ b/api/controller/resources.go
@@ -41,7 +41,7 @@ import (
"github.com/jinzhu/gorm"
"github.com/pquerna/ffjson/ffjson"
"github.com/renstorm/fuzzysearch/fuzzy"
- "github.com/thedevsaddam/govalidator"
+ validator "github.com/thedevsaddam/govalidator"
)
//V2Routes v2Routes
@@ -52,6 +52,7 @@ type V2Routes struct {
AppStruct
GatewayStruct
ThirdPartyServiceController
+ LabelController
}
//Show test
@@ -600,14 +601,12 @@ func (t *TenantStruct) CreateService(w http.ResponseWriter, r *http.Request) {
// schema:
// "$ref": "#/responses/commandResponse"
// description: 统一返回格式
- logrus.Debugf("trans create service service")
var ss api_model.ServiceStruct
body, err := ioutil.ReadAll(r.Body)
if err != nil {
httputil.ReturnError(r, w, 500, err.Error())
return
}
-
err = ffjson.Unmarshal(body, &ss)
if err != nil {
httputil.ReturnError(r, w, 500, err.Error())
@@ -1615,7 +1614,7 @@ func (t *TenantStruct) AddProbe(w http.ResponseWriter, r *http.Request) {
tspD.FailureThreshold = tsp.FailureThreshold
tspD.HTTPHeader = tsp.HTTPHeader
tspD.InitialDelaySecond = tsp.InitialDelaySecond
- tspD.IsUsed = tsp.IsUsed
+ tspD.IsUsed = &tsp.IsUsed
tspD.Mode = tsp.Mode
tspD.Path = tsp.Path
tspD.PeriodSecond = tsp.PeriodSecond
@@ -1665,7 +1664,7 @@ func (t *TenantStruct) UpdateProbe(w http.ResponseWriter, r *http.Request) {
tspD.FailureThreshold = tsp.FailureThreshold
tspD.HTTPHeader = tsp.HTTPHeader
tspD.InitialDelaySecond = tsp.InitialDelaySecond
- tspD.IsUsed = tsp.IsUsed
+ tspD.IsUsed = &tsp.IsUsed
tspD.Mode = tsp.Mode
tspD.Path = tsp.Path
tspD.PeriodSecond = tsp.PeriodSecond
diff --git a/api/handler/gateway_action.go b/api/handler/gateway_action.go
index 28aa13913..84307302d 100644
--- a/api/handler/gateway_action.go
+++ b/api/handler/gateway_action.go
@@ -54,7 +54,12 @@ func (g *GatewayAction) AddHTTPRule(req *apimodel.AddHTTPRuleStruct) (string, er
ServiceID: req.ServiceID,
ContainerPort: req.ContainerPort,
Domain: req.Domain,
- Path: req.Path,
+ Path: func() string {
+ if !strings.HasPrefix(req.Path, "/") {
+ return "/" + req.Path
+ }
+ return req.Path
+ }(),
Header: req.Header,
Cookie: req.Cookie,
Weight: req.Weight,
@@ -164,7 +169,12 @@ func (g *GatewayAction) UpdateHTTPRule(req *apimodel.UpdateHTTPRuleStruct) (stri
if req.Domain != "" {
rule.Domain = req.Domain
}
- rule.Path = req.Path
+ rule.Path = func() string {
+ if !strings.HasPrefix(req.Path, "/") {
+ return "/" + req.Path
+ }
+ return req.Path
+ }()
rule.Header = req.Header
rule.Cookie = req.Cookie
rule.Weight = req.Weight
@@ -611,6 +621,12 @@ func (g *GatewayAction) RuleConfig(req *apimodel.RuleConfigReq) error {
})
setheaders := make(map[string]string)
for _, item := range req.Body.SetHeaders {
+ if strings.TrimSpace(item.Key) == ""{
+ continue
+ }
+ if strings.TrimSpace(item.Value) == "" {
+ item.Value = "empty"
+ }
// filter same key
setheaders["set-header-"+item.Key] = item.Value
}
diff --git a/api/handler/third_party_service_handler.go b/api/handler/third_party_service_handler.go
index f97e1d868..1c00f9fa0 100644
--- a/api/handler/third_party_service_handler.go
+++ b/api/handler/third_party_service_handler.go
@@ -100,9 +100,9 @@ func (t *ThirdPartyServiceHanlder) ListEndpoints(sid string) ([]*model.EndpointR
for _, item := range endpoints {
m[item.UUID] = &model.EndpointResp{
EpID: item.UUID,
- IP: func(ip string, port int) string {
- if port != 0 {
- return fmt.Sprintf("%s:%d", ip, port)
+ IP: func(ip string, p int) string {
+ if p != 0 {
+ return fmt.Sprintf("%s:%d", ip, p)
}
return ip
}(item.IP, item.Port),
@@ -126,13 +126,8 @@ func (t *ThirdPartyServiceHanlder) ListEndpoints(sid string) ([]*model.EndpointR
continue
}
m[item.Uuid] = &model.EndpointResp{
- EpID: item.Uuid,
- IP: func(ip string, port int32) string {
- if port != 0 {
- return fmt.Sprintf("%s:%d", ip, port)
- }
- return ip
- }(item.Ip, item.Port),
+ EpID: item.Uuid,
+ IP: item.Ip,
Status: item.Status,
IsOnline: true,
IsStatic: false,
diff --git a/api/region/service.go b/api/region/service.go
index 40a4ef4a1..aa21316a9 100644
--- a/api/region/service.go
+++ b/api/region/service.go
@@ -21,7 +21,6 @@ package region
import (
"bytes"
"fmt"
-
"github.com/goodrain/rainbond/api/model"
"github.com/goodrain/rainbond/api/util"
dbmodel "github.com/goodrain/rainbond/db/model"
diff --git a/api/region/types.go b/api/region/types.go
index 089a066ed..f32e766a7 100644
--- a/api/region/types.go
+++ b/api/region/types.go
@@ -25,8 +25,9 @@ type ServiceDeployInfo struct {
Deployment string `protobuf:"bytes,3,opt,name=deployment,proto3" json:"deployment,omitempty"`
Pods map[string]string `protobuf:"bytes,4,rep,name=pods,proto3" json:"pods,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Services map[string]string `protobuf:"bytes,5,rep,name=services,proto3" json:"services,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
- Secrets map[string]string `protobuf:"bytes,6,rep,name=secrets,proto3" json:"secrets,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
- Ingresses map[string]string `protobuf:"bytes,7,rep,name=ingresses,proto3" json:"ingresses,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
- Replicatset map[string]string `protobuf:"bytes,8,rep,name=replicatset,proto3" json:"replicatset,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
- Status string `protobuf:"bytes,9,opt,name=status,proto3" json:"status,omitempty"`
+ Endpoints map[string]string `protobuf:"bytes,6,rep,name=endpoints,proto3" json:"endpoints,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ Secrets map[string]string `protobuf:"bytes,7,rep,name=secrets,proto3" json:"secrets,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ Ingresses map[string]string `protobuf:"bytes,8,rep,name=ingresses,proto3" json:"ingresses,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ Replicatset map[string]string `protobuf:"bytes,9,rep,name=replicatset,proto3" json:"replicatset,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ Status string `protobuf:"bytes,10,opt,name=status,proto3" json:"status,omitempty"`
}
diff --git a/builder/exector/exector.go b/builder/exector/exector.go
index 3303259b2..ad2f8c7e7 100644
--- a/builder/exector/exector.go
+++ b/builder/exector/exector.go
@@ -136,11 +136,11 @@ func (e *exectorManager) AddTask(task *pb.TaskMessage) error {
}
func (e *exectorManager) exec(task *pb.TaskMessage) error {
- creater, ok := workerCreaterList[task.TaskType]
+ creator, ok := workerCreaterList[task.TaskType]
if !ok {
return fmt.Errorf("`%s` tasktype can't support", task.TaskType)
}
- worker, err := creater(task.TaskBody, e)
+ worker, err := creator(task.TaskBody, e)
if err != nil {
logrus.Errorf("create worker for builder error.%s", err)
return err
diff --git a/builder/exector/export_app.go b/builder/exector/export_app.go
index cf10e70a7..5188af708 100644
--- a/builder/exector/export_app.go
+++ b/builder/exector/export_app.go
@@ -19,16 +19,14 @@
package exector
import (
- "time"
-
"fmt"
"io/ioutil"
"os"
"os/exec"
+ "regexp"
"strconv"
"strings"
-
- "regexp"
+ "time"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/client"
@@ -39,7 +37,7 @@ import (
"github.com/goodrain/rainbond/util"
"github.com/pkg/errors"
"github.com/tidwall/gjson"
- "gopkg.in/yaml.v2"
+ yaml "gopkg.in/yaml.v2"
)
var re = regexp.MustCompile(`\s`)
@@ -270,7 +268,7 @@ func (i *ExportApp) exportImage(serviceDir string, app gjson.Result) error {
}
//change save app image name
imageName := sources.ImageNameWithNamespaceHandle(image)
- saveImageName := fmt.Sprintf("%s/%s:%s", "goodrain.me", imageName.Name, imageName.Tag)
+ saveImageName := fmt.Sprintf("%s/%s:%s", builder.REGISTRYDOMAIN, imageName.Name, imageName.Tag)
if err := sources.ImageTag(i.DockerClient, image, saveImageName, i.Logger, 2); err != nil {
return err
}
@@ -351,7 +349,7 @@ func (i *ExportApp) savePlugins() error {
}
//change save app image name
imageName := sources.ImageNameWithNamespaceHandle(image)
- saveImageName := fmt.Sprintf("%s/%s:%s", "goodrain.me", imageName.Name, imageName.Tag)
+ saveImageName := fmt.Sprintf("%s/%s:%s", builder.REGISTRYDOMAIN, imageName.Name, imageName.Tag)
if err := sources.ImageTag(i.DockerClient, image, saveImageName, i.Logger, 2); err != nil {
return err
}
@@ -498,6 +496,7 @@ type Service struct {
Volumes []string `yaml:"volumes,omitempty"`
Command string `yaml:"command,omitempty"`
Environment map[string]string `yaml:"environment,omitempty"`
+ DependsOn []string `yaml:"depends_on,omitempty"`
Loggin struct {
Driver string `yaml:"driver,omitempty"`
Options struct {
@@ -525,6 +524,7 @@ func (i *ExportApp) buildDockerComposeYaml() error {
for _, app := range apps {
image := app.Get("image").String()
+ shareImage := app.Get("share_image").String()
appName := app.Get("service_cname").String()
appName = unicode2zh(appName)
volumes := make([]string, 0, 3)
@@ -542,8 +542,10 @@ func (i *ExportApp) buildDockerComposeYaml() error {
volumes = append(volumes, fmt.Sprintf("%s:%s", volumeName, volumePath))
}
+ lang := app.Get("language").String()
// 如果该组件是源码方式部署,则挂载slug文件到runner容器内
- if checkIsRunner(image) {
+ if lang != "dockerfile" && checkIsRunner(image) {
+ shareImage = image
shareSlugPath := app.Get("share_slug_path").String()
tarFileName := buildToLinuxFileName(shareSlugPath)
volume := fmt.Sprintf("__GROUP_DIR__/%s/%s:/tmp/slug/slug.tgz", appName, tarFileName)
@@ -552,8 +554,10 @@ func (i *ExportApp) buildDockerComposeYaml() error {
}
// 处理环境变量
- for k, v := range app.Get("service_env_map_list").Map() {
- envs[k] = v.String()
+ for _, item := range app.Get("service_env_map_list").Array() {
+ key := item.Get("attr_name").String()
+ value := item.Get("attr_value").String()
+ envs[key] = value
}
for _, item := range app.Get("service_connect_info_map_list").Array() {
@@ -562,6 +566,7 @@ func (i *ExportApp) buildDockerComposeYaml() error {
envs[key] = value
}
+ var depServices []string
// 如果该app依赖了另了个app-b,则把app-b中所有公开环境变量注入到该app
for _, item := range app.Get("dep_service_map_list").Array() {
serviceKey := item.Get("dep_service_key").String()
@@ -569,10 +574,14 @@ func (i *ExportApp) buildDockerComposeYaml() error {
for k, v := range depEnvs {
envs[k] = v
}
+
+ if svc := i.getDependedService(serviceKey, &apps); svc != "" {
+ depServices = append(depServices, svc)
+ }
}
service := &Service{
- Image: image,
+ Image: shareImage,
ContainerName: appName,
Restart: "always",
NetworkMode: "host",
@@ -583,6 +592,9 @@ func (i *ExportApp) buildDockerComposeYaml() error {
service.Loggin.Driver = "json-file"
service.Loggin.Options.MaxSize = "5m"
service.Loggin.Options.MaxFile = "2"
+ if depServices != nil && len(depServices) > 0 {
+ service.DependsOn = depServices
+ }
y.Services[appName] = service
}
@@ -607,7 +619,7 @@ func (i *ExportApp) buildDockerComposeYaml() error {
func (i *ExportApp) getPublicEnvByKey(serviceKey string, apps *[]gjson.Result) map[string]string {
envs := make(map[string]string, 5)
for _, app := range *apps {
- appKey := app.Get("service_key").String()
+ appKey := app.Get("service_share_uuid").String()
if appKey == serviceKey {
for _, item := range app.Get("service_connect_info_map_list").Array() {
key := item.Get("attr_name").String()
@@ -621,6 +633,15 @@ func (i *ExportApp) getPublicEnvByKey(serviceKey string, apps *[]gjson.Result) m
return envs
}
+func (i *ExportApp) getDependedService(key string, apps *[]gjson.Result) string {
+ for _, app := range *apps {
+ if key == app.Get("service_share_uuid").String() {
+ return app.Get("service_cname").String()
+ }
+ }
+ return ""
+}
+
func (i *ExportApp) buildStartScript() error {
if err := exec.Command("cp", "/src/export-app/run.sh", i.SourceDir).Run(); err != nil {
err = errors.New("Failed to generate start script to: " + i.SourceDir)
diff --git a/builder/exector/export_app_test.go b/builder/exector/export_app_test.go
new file mode 100644
index 000000000..658aa5fae
--- /dev/null
+++ b/builder/exector/export_app_test.go
@@ -0,0 +1,35 @@
+// 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 .
+
+package exector
+
+import (
+ "github.com/goodrain/rainbond/event"
+ "testing"
+)
+
+func TestExportApp_parseApps(t *testing.T) {
+ e := &ExportApp{
+ SourceDir: "./",
+ Logger: event.GetTestLogger(),
+ }
+ err := e.buildDockerComposeYaml()
+ if err != nil {
+ t.Error(err)
+ }
+}
diff --git a/builder/exector/import_app.go b/builder/exector/import_app.go
index d6989de88..01730f3b9 100644
--- a/builder/exector/import_app.go
+++ b/builder/exector/import_app.go
@@ -32,6 +32,7 @@ import (
simplejson "github.com/bitly/go-simplejson"
"github.com/docker/docker/client"
"github.com/goodrain/rainbond/api/model"
+ "github.com/goodrain/rainbond/builder"
"github.com/goodrain/rainbond/builder/sources"
"github.com/goodrain/rainbond/db"
"github.com/goodrain/rainbond/event"
@@ -388,7 +389,7 @@ func (i *ImportApp) importPlugins() error {
// 上传之前先要根据新的仓库地址修改镜像名
image := i.oldPluginPath[plugin.Get("service_key").String()]
imageName := sources.ImageNameWithNamespaceHandle(image)
- saveImageName := fmt.Sprintf("%s/%s:%s", "goodrain.me", imageName.Name, imageName.Tag)
+ saveImageName := fmt.Sprintf("%s/%s:%s", builder.REGISTRYDOMAIN, imageName.Name, imageName.Tag)
newImageName := plugin.Get("share_image").String()
if err := sources.ImageTag(i.DockerClient, saveImageName, newImageName, i.Logger, 2); err != nil {
return fmt.Errorf("change plugin image tag(%s => %s) error %s", saveImageName, newImageName, err.Error())
@@ -440,7 +441,7 @@ func (i *ImportApp) loadApps() error {
pass := app.Get("service_image.hub_password").String()
// 上传之前先要根据新的仓库地址修改镜像名
image := app.Get("share_image").String()
- if err := sources.ImageTag(i.DockerClient, fmt.Sprintf("%s/%s:%s", "goodrain.me", oldImageName.Name, oldImageName.Tag), image, i.Logger, 15); err != nil {
+ if err := sources.ImageTag(i.DockerClient, fmt.Sprintf("%s/%s:%s", builder.REGISTRYDOMAIN, oldImageName.Name, oldImageName.Tag), image, i.Logger, 15); err != nil {
return fmt.Errorf("change image tag(%s => %s) error %s", fmt.Sprintf("%s/%s:%s", i.ServiceImage.HubUrl, oldImageName.Name, oldImageName.Tag), image, err.Error())
}
// 开始上传
diff --git a/builder/exector/metadata.json b/builder/exector/metadata.json
new file mode 100644
index 000000000..2cbae7b49
--- /dev/null
+++ b/builder/exector/metadata.json
@@ -0,0 +1 @@
+{"describe": "NextCloud-\u4e2a\u4eba\u79c1\u6709\u7f51\u76d8\u7684\u6700\u4f73\u9009\u62e9,\u652f\u6301\u6587\u6863\u591a\u4eba\u534f\u540c\u5728\u7ebf\u7f16\u8f91\u3002", "group_version": "v16.0.0", "image_base64_string": null, "template_version": "v2", "apps": [{"deploy_version": "20190318181959", "service_name": "", "image": "hub.goodrain.com/goodrain/gr6faafe_goodrain-apps_redis:20180620210426_v3.2.11", "service_volume_map_list": [{"file_content": "", "category": "app_publish", "volume_path": "/data", "volume_type": "share-file", "volume_name": "GR6FAAFE_1"}], "extend_method": "state", "service_key": "b2a88a74806f48d480b0e15c2c1b237d", "category": "app_publish", "service_region": "rainbond", "share_type": "image", "extend_method_map": {"min_node": 1, "step_memory": 128, "is_restart": 0, "step_node": 1, "max_memory": 65536, "max_node": 1, "min_memory": 256}, "version": "81701", "service_source": "market", "memory": 256, "service_type": "application", "service_env_map_list": [{"attr_name": "TZ", "name": "\u65f6\u533a", "is_change": true, "attr_value": "Asia/Shanghai"}, {"attr_name": "TCP_KEEPALIVE", "name": "\u662f\u5426\u5f00\u542f\u957f\u94fe\u63a5\uff0c0\u4e3a\u5173\u95ed", "is_change": true, "attr_value": "300"}, {"attr_name": "DATABASES", "name": "\u53ef\u7528\u6570\u636e\u5e93\u6570\u91cf", "is_change": true, "attr_value": "16"}, {"attr_name": "LOGLEVEL", "name": "\u65e5\u5fd7\u8bb0\u5f55\u7b49\u7ea7\uff1adebug\u3001verbose\u3001notice\u3001warning", "is_change": true, "attr_value": "notice"}, {"attr_name": "SLOWLOG_LOG_SLOWER_THAN", "name": "\u6162\u65e5\u5fd7\u8bbe\u5b9a\u65f6\u95f4\uff0c\u5355\u4f4d\u5fae\u79d2\uff0c0\u4e3a\u6bcf\u6761\u90fd\u8bb0\u5f55", "is_change": true, "attr_value": "10000"}, {"attr_name": "SLOWLOG_MAX_LEN", "name": "\u6162\u65e5\u5fd7\u957f\u5ea6", "is_change": true, "attr_value": "128"}, {"attr_name": "MAXCLIENTS", "name": "\u5ba2\u6237\u7aef\u6700\u5927\u8fde\u63a5\u6570", "is_change": true, "attr_value": "10000"}, {"attr_name": "TIMEOUT", "name": "\u5ba2\u6237\u7aef\u8fde\u63a5\u65f6\u7684\u8d85\u65f6\u65f6\u95f4", "is_change": true, "attr_value": "100"}, {"attr_name": "DBFILENAME", "name": "\u672c\u5730\u6301\u4e45\u5316\u6570\u636e\u5e93\u6587\u4ef6\u540d", "is_change": true, "attr_value": "dump.rdb"}], "service_related_plugin_config": [], "service_alias": "gr04ea71", "service_cname": "Redis-3.2.11", "port_map_list": [{"port_alias": "REDIS", "protocol": "tcp", "tenant_id": "157b2015f1c74b219f38849f7857d382", "container_port": 6379, "is_outer_service": false, "is_inner_service": true}], "share_image": "hub.goodrain.com/goodrain/gr6faafe_goodrain-apps_redis:20190318181959_v16.0.0", "dep_service_map_list": [], "probes": [{"http_header": "", "initial_delay_second": 2, "is_used": true, "cmd": "", "probe_id": "9a0760d48b62459bb18f82271b985c30", "period_second": 3, "port": 6379, "mode": "readiness", "failure_threshold": 3, "path": "", "scheme": "tcp", "success_threshold": 1, "ID": 777, "timeout_second": 30, "service_id": "55fafdfac23b47ecb607d860b604ea71"}], "language": "", "need_share": true, "tenant_id": "157b2015f1c74b219f38849f7857d382", "cmd": "", "creater": 3150, "service_share_uuid": "b2a88a74806f48d480b0e15c2c1b237d+55fafdfac23b47ecb607d860b604ea71", "service_image": {"hub_user": "goodrain-admin", "is_trust": true, "namespace": "goodrain", "hub_url": "hub.goodrain.com", "hub_password": "goodrain123465"}, "service_connect_info_map_list": [{"name": "\u8fde\u63a5\u5bc6\u7801", "attr_name": "REDIS_PASS", "attr_value": "**None**", "is_change": true, "container_port": 0}], "service_id": "55fafdfac23b47ecb607d860b604ea71"}, {"deploy_version": "20190317214343", "service_name": "", "image": "hub.goodrain.com/goodrain/mysql:20181019160510_20181019160510_5.7.23", "service_volume_map_list": [{"file_content": "", "category": "app_publish", "volume_path": "/var/lib/mysql", "volume_type": "share-file", "volume_name": "GREAF238_1"}, {"file_content": "", "category": "app_publish", "volume_path": "/var/log/mysql", "volume_type": "share-file", "volume_name": "GREAF238_2"}], "extend_method": "state", "service_key": "ea30f85acb714fc080251b0417cf6544", "category": "app_publish", "service_region": "rainbond", "share_type": "image", "extend_method_map": {"min_node": 1, "step_memory": 128, "is_restart": 0, "step_node": 1, "max_memory": 65536, "max_node": 1, "min_memory": 512}, "version": "percona-5.7", "service_source": "market", "memory": 512, "service_type": "application", "service_env_map_list": [{"attr_name": "PERCONA_MAJOR", "name": "PERCONA_MAJOR", "is_change": true, "attr_value": "5.7"}, {"attr_name": "PERCONA_VERSION", "name": "PERCONA_VERSION", "is_change": true, "attr_value": "5.7.23-23-1.stretch"}, {"attr_name": "MYSQL_VERSION", "name": "MYSQL_VERSION", "is_change": true, "attr_value": "5.7.23"}, {"attr_name": "TZ", "name": "TZ", "is_change": true, "attr_value": "Asia/Shanghai"}, {"attr_name": "GOSU_VERSION", "name": "GOSU_VERSION", "is_change": true, "attr_value": "1.10"}, {"attr_name": "MYSQLC_MYSQLD_MAX_CONNECTIONS", "name": "\u914d\u7f6e-\u6700\u5927\u8fde\u63a5\u6570", "is_change": true, "attr_value": "3000"}, {"attr_name": "MYSQLC_MYSQLD_THREAD_CACHE_SIZE", "name": "\u914d\u7f6e-threadcache\u6c60\u4e2d\u53ef\u4ee5\u7f13\u5b58\u8fde\u63a5\u7ebf\u7a0b\u7684\u6700\u5927\u6570\u91cf", "is_change": true, "attr_value": "64"}, {"attr_name": "MYSQLC_MYSQLD_PORT", "name": "\u914d\u7f6e-\u76d1\u542c\u7aef\u53e3", "is_change": true, "attr_value": "3306"}, {"attr_name": "MYSQL_ROOT_PASSWORD", "name": "root\u5bc6\u7801", "is_change": true, "attr_value": "asdaCJASDVMKCLSAKDVMC"}], "service_related_plugin_config": [{"attr": [{"protocol": "mysql", "dest_service_alias": "", "container_port": 3306, "create_time": "2019-03-17 21:43:43", "attrs": "{\"OPEN\": \"YES\"}", "dest_service_id": "", "build_version": "20190227212402", "service_id": "e01167679d2f45b1a4d4f241b2b10f0c", "injection": "auto", "plugin_id": "79b17da80bf1447fa4c019e41f1aa66c", "ID": 2289, "service_meta_type": "upstream_port"}], "create_time": "2019-03-17 21:43:43", "plugin_status": true, "build_version": "20190227212402", "service_id": "e01167679d2f45b1a4d4f241b2b10f0c", "plugin_id": "79b17da80bf1447fa4c019e41f1aa66c", "plugin_key": "perf_analyze_plugin", "ID": 189, "service_meta_type": ""}], "service_alias": "grb10f0c", "service_cname": "MySQL5.7", "port_map_list": [{"port_alias": "MYSQL", "protocol": "mysql", "tenant_id": "157b2015f1c74b219f38849f7857d382", "container_port": 3306, "is_outer_service": false, "is_inner_service": true}], "share_image": "hub.goodrain.com/goodrain/mysql:20190317214343_v16.0.0", "dep_service_map_list": [], "probes": [{"http_header": "", "initial_delay_second": 2, "is_used": true, "cmd": "", "probe_id": "d3d70ac49d6a4ba2af181428b3af8a1b", "period_second": 3, "port": 3306, "mode": "readiness", "failure_threshold": 3, "path": "", "scheme": "tcp", "success_threshold": 1, "ID": 716, "timeout_second": 30, "service_id": "e01167679d2f45b1a4d4f241b2b10f0c"}], "language": "", "need_share": true, "tenant_id": "157b2015f1c74b219f38849f7857d382", "cmd": "", "creater": 3150, "service_share_uuid": "ea30f85acb714fc080251b0417cf6544+e01167679d2f45b1a4d4f241b2b10f0c", "service_image": {"hub_user": "goodrain-admin", "is_trust": true, "namespace": "goodrain", "hub_url": "hub.goodrain.com", "hub_password": "goodrain123465"}, "service_connect_info_map_list": [{"name": "\u6570\u636e\u5e93\u540d", "attr_name": "MYSQL_DATABASE", "attr_value": "default", "is_change": true, "container_port": 0}, {"name": "admin", "attr_name": "MYSQL_USER", "attr_value": "admin", "is_change": true, "container_port": 0}, {"name": "\u5bc6\u7801", "attr_name": "MYSQL_PASSWORD", "attr_value": "**None**", "is_change": true, "container_port": 0}], "service_id": "e01167679d2f45b1a4d4f241b2b10f0c"}, {"deploy_version": "20190320172220", "service_name": "", "image": "goodrain.me/runner:latest", "service_volume_map_list": [{"file_content": "", "category": "application", "volume_path": "/var/www/html", "volume_type": "share-file", "volume_name": "GRD35B4F_1"}], "extend_method": "stateless", "service_key": "5d9b134116854ea39c570fdf44a53e23", "category": "application", "service_region": "rainbond", "share_type": "image", "extend_method_map": {"min_node": 1, "step_memory": 128, "is_restart": 0, "step_node": 1, "max_memory": 65536, "max_node": 20, "min_memory": 1024}, "version": "latest", "service_source": "source_code", "memory": 1024, "service_type": "application", "service_env_map_list": [{"attr_name": "NEXTCLOUD_VERSION", "name": "NEXTCLOUD_VERSION", "is_change": true, "attr_value": "15.0.5"}], "service_related_plugin_config": [], "service_alias": "grd35b4f", "service_cname": "nextcloud-server", "port_map_list": [{"port_alias": "GRD35B4F80", "protocol": "http", "tenant_id": "157b2015f1c74b219f38849f7857d382", "container_port": 80, "is_outer_service": true, "is_inner_service": false}], "share_image": "hub.goodrain.com/goodrain/grd35b4f_goodrain_nextcloud-server:20190320172220_v16.0.0", "dep_service_map_list": [{"dep_service_key": "b2a88a74806f48d480b0e15c2c1b237d+55fafdfac23b47ecb607d860b604ea71"}, {"dep_service_key": "ea30f85acb714fc080251b0417cf6544+e01167679d2f45b1a4d4f241b2b10f0c"}], "probes": [{"http_header": "", "initial_delay_second": 2, "is_used": true, "cmd": "", "probe_id": "c02e145336bf4ad59da96f27078dc30e", "period_second": 3, "port": 80, "mode": "readiness", "failure_threshold": 3, "path": "", "scheme": "tcp", "success_threshold": 1, "ID": 911, "timeout_second": 20, "service_id": "6ee0d5bc96ff928d117f1c00c0d35b4f"}], "language": "dockerfile", "need_share": true, "tenant_id": "157b2015f1c74b219f38849f7857d382", "cmd": "", "creater": 3150, "service_share_uuid": "5d9b134116854ea39c570fdf44a53e23+6ee0d5bc96ff928d117f1c00c0d35b4f", "service_image": {"hub_user": "goodrain-admin", "is_trust": true, "namespace": "goodrain", "hub_url": "hub.goodrain.com", "hub_password": "goodrain123465"}, "service_connect_info_map_list": [], "service_id": "6ee0d5bc96ff928d117f1c00c0d35b4f"}, {"deploy_version": "20190319101324", "service_name": "", "image": "barnett/collabora:190114", "service_volume_map_list": [], "extend_method": "stateless", "service_key": "802967c1bd5d41e99a52b4c6f5ccec91", "category": "app_publish", "service_region": "rainbond", "share_type": "image", "extend_method_map": {"min_node": 1, "step_memory": 128, "is_restart": 0, "step_node": 1, "max_memory": 65536, "max_node": 20, "min_memory": 2048}, "version": "190114", "service_source": "docker_image", "memory": 2048, "service_type": "application", "service_env_map_list": [{"attr_name": "domain", "name": "", "is_change": true, "attr_value": "80\\.grd35b4f\\.52bli69h\\.0196bd\\.grapps\\.cn"}], "service_related_plugin_config": [], "service_alias": "gra660c5", "service_cname": "collabora-online", "port_map_list": [{"port_alias": "GRA660C59980", "protocol": "tcp", "tenant_id": "157b2015f1c74b219f38849f7857d382", "container_port": 9980, "is_outer_service": true, "is_inner_service": false}], "share_image": "hub.goodrain.com/goodrain/collabora:20190319101324_v16.0.0", "dep_service_map_list": [], "probes": [], "language": "", "need_share": true, "tenant_id": "157b2015f1c74b219f38849f7857d382", "cmd": "", "creater": 3150, "service_share_uuid": "802967c1bd5d41e99a52b4c6f5ccec91+3a542db90d9c607cba4c1caecca660c5", "service_image": {"hub_user": "goodrain-admin", "is_trust": true, "namespace": "goodrain", "hub_url": "hub.goodrain.com", "hub_password": "goodrain123465"}, "service_connect_info_map_list": [], "service_id": "3a542db90d9c607cba4c1caecca660c5"}], "group_name": "Nextcloud", "plugins": [{"category": "analyst-plugin:perf", "origin": "local_market", "config_groups": [{"config_name": "\u7aef\u53e3\u662f\u5426\u5f00\u542f\u5206\u6790", "ID": 18, "options": [{"attr_info": "\u662f\u5426\u5f00\u542f\u5f53\u524d\u7aef\u53e3\u5206\u6790\uff0c\u7528\u6237\u81ea\u52a9\u9009\u62e9\u670d\u52a1\u7aef\u53e3", "protocol": "http,mysql", "attr_default_value": "YES", "attr_name": "OPEN", "attr_alt_value": "YES,NO", "ID": 108, "is_change": true, "build_version": "20190227212402", "plugin_id": "79b17da80bf1447fa4c019e41f1aa66c", "attr_type": "radio", "service_meta_type": "upstream_port"}], "build_version": "20190227212402", "plugin_id": "79b17da80bf1447fa4c019e41f1aa66c", "injection": "auto", "service_meta_type": "upstream_port"}], "desc": "\u5b9e\u65f6\u5206\u6790\u5e94\u7528\u7684\u541e\u5410\u7387\u3001\u54cd\u5e94\u65f6\u95f4\u3001\u5728\u7ebf\u4eba\u6570\u7b49\u6307\u6807", "tenant_id": "157b2015f1c74b219f38849f7857d382", "region": "rainbond", "plugin_alias": "\u670d\u52a1\u5b9e\u65f6\u6027\u80fd\u5206\u6790", "plugin_name": "gr79b17d", "ID": 18, "create_user": 3150, "create_time": "2019-02-27 21:24:02", "origin_share_id": "perf_analyze_plugin", "plugin_image": {"hub_user": "goodrain-admin", "is_trust": true, "namespace": "goodrain", "hub_url": "hub.goodrain.com", "hub_password": "goodrain123465"}, "build_version": "20190227212402", "share_image": "hub.goodrain.com/goodrain/plugin_tcm_79b17da80bf1447fa4c019e41f1aa66c:latest_20192272124333977015_20190227212402", "plugin_id": "79b17da80bf1447fa4c019e41f1aa66c", "plugin_key": "perf_analyze_plugin", "build_source": "image", "image": "goodrain.me/tcm", "code_repo": ""}], "group_key": "5acfa319e8084a16abc1806cfd79cad6", "suffix": ""}
\ No newline at end of file
diff --git a/builder/exector/plugin_dockerfile.go b/builder/exector/plugin_dockerfile.go
index 78dff668c..b10aa81f3 100644
--- a/builder/exector/plugin_dockerfile.go
+++ b/builder/exector/plugin_dockerfile.go
@@ -107,7 +107,7 @@ func (e *exectorManager) runD(t *model.BuildPluginTaskBody, logger event.Logger)
logger.Info("代码检测为dockerfile,开始编译", map[string]string{"step": "build-exector"})
mm := strings.Split(t.GitURL, "/")
n1 := strings.Split(mm[len(mm)-1], ".")[0]
- buildImageName := fmt.Sprintf("goodrain.me/plugin_%s_%s:%s", n1, t.PluginID, t.DeployVersion)
+ buildImageName := fmt.Sprintf(builder.REGISTRYDOMAIN+"/plugin_%s_%s:%s", n1, t.PluginID, t.DeployVersion)
buildOptions := types.ImageBuildOptions{
Tags: []string{buildImageName},
Remove: true,
diff --git a/builder/repostory.go b/builder/repostory.go
index 5f405156e..4078a874e 100644
--- a/builder/repostory.go
+++ b/builder/repostory.go
@@ -48,7 +48,7 @@ var REGISTRYUSER = ""
var REGISTRYPASS = ""
//RUNNERIMAGENAME runner image name
-var RUNNERIMAGENAME = "goodrain.me/runner"
+var RUNNERIMAGENAME = REGISTRYDOMAIN + "/runner"
//BUILDERIMAGENAME builder image name
-var BUILDERIMAGENAME = "goodrain.me/builder"
+var BUILDERIMAGENAME = REGISTRYDOMAIN + "/builder"
diff --git a/db/model/tenant.go b/db/model/tenant.go
index 5f684f1b8..6708e2dc4 100644
--- a/db/model/tenant.go
+++ b/db/model/tenant.go
@@ -409,7 +409,7 @@ type TenantServiceProbe struct {
//检测超时时间
TimeoutSecond int `gorm:"column:timeout_second;size:3;default:30" json:"timeout_second" validate:"timeout_second"`
//是否启用
- IsUsed int `gorm:"column:is_used;size:1;default:1" json:"is_used" validate:"is_used"`
+ IsUsed *int `gorm:"column:is_used;size:1;default:1" json:"is_used" validate:"is_used"`
//标志为失败的检测次数
FailureThreshold int `gorm:"column:failure_threshold;size:2;default:3" json:"failure_threshold" validate:"failure_threshold"`
//标志为成功的检测次数
diff --git a/db/mysql/dao/gateway.go b/db/mysql/dao/gateway.go
index 2f940f83a..a778997e9 100644
--- a/db/mysql/dao/gateway.go
+++ b/db/mysql/dao/gateway.go
@@ -168,10 +168,7 @@ func (h *HTTPRuleDaoImpl) UpdateModel(mo model.Interface) error {
if !ok {
return fmt.Errorf("Failed to convert %s to *model.HTTPRule", reflect.TypeOf(mo).String())
}
-
- return h.DB.Table(hr.TableName()).
- Where("uuid = ?", hr.UUID).
- Update(hr).Error
+ return h.DB.Save(hr).Error
}
// GetHTTPRuleByID gets a HTTPRule based on uuid
diff --git a/db/mysql/dao/k8s.go b/db/mysql/dao/k8s.go
index f7d87dc6f..c4c42e74e 100644
--- a/db/mysql/dao/k8s.go
+++ b/db/mysql/dao/k8s.go
@@ -50,7 +50,8 @@ func (t *ServiceProbeDaoImpl) UpdateModel(mo model.Interface) error {
probe := mo.(*model.TenantServiceProbe)
if probe.ID == 0 {
var oldProbe model.TenantServiceProbe
- if err := t.DB.Where("service_id = ? and mode = ? and probe_id=?", probe.ServiceID, probe.Mode, probe.ProbeID).Find(&oldProbe).Error; err != nil {
+ if err := t.DB.Where("service_id = ? and probe_id=?", probe.ServiceID,
+ probe.ProbeID).Find(&oldProbe).Error; err != nil {
return err
}
if oldProbe.ID == 0 {
diff --git a/gateway/annotations/proxy/proxy.go b/gateway/annotations/proxy/proxy.go
index fe49a254e..27500147d 100644
--- a/gateway/annotations/proxy/proxy.go
+++ b/gateway/annotations/proxy/proxy.go
@@ -116,7 +116,15 @@ func (l1 *Config) Equal(l2 *Config) bool {
if l1.ProxyBuffering != l2.ProxyBuffering {
return false
}
- // TODO: ProxySetHeaders
+
+ if len(l1.SetHeaders) != len(l2.SetHeaders) {
+ return false
+ }
+ for k, v := range l1.SetHeaders {
+ if l2.SetHeaders[k] != v {
+ return false
+ }
+ }
return true
}
@@ -219,6 +227,9 @@ func (a proxy) Parse(ing *extensions.Ingress) (interface{}, error) {
fmt.Sprintf("%s/%s", ing.GetNamespace(), ing.GetName()), err)
}
for k, v := range setHeaders {
+ if v == "empty" {
+ v = ""
+ }
config.SetHeaders[k] = v
}
diff --git a/gateway/annotations/proxy/proxy_test.go b/gateway/annotations/proxy/proxy_test.go
index 3552ce829..23bdf2a83 100644
--- a/gateway/annotations/proxy/proxy_test.go
+++ b/gateway/annotations/proxy/proxy_test.go
@@ -92,7 +92,7 @@ func TestProxy(t *testing.T) {
data[parser.GetAnnotationWithPrefix("proxy-read-timeout")] = "3"
data[parser.GetAnnotationWithPrefix("proxy-buffers-number")] = "8"
data[parser.GetAnnotationWithPrefix("proxy-buffer-size")] = "1k"
- data[parser.GetAnnotationWithPrefix("proxy-body-size")] = "2k"
+ data[parser.GetAnnotationWithPrefix("proxy-body-size")] = "2"
data[parser.GetAnnotationWithPrefix("proxy-next-upstream")] = "off"
data[parser.GetAnnotationWithPrefix("proxy-next-upstream-tries")] = "3"
data[parser.GetAnnotationWithPrefix("proxy-request-buffering")] = "off"
@@ -122,8 +122,8 @@ func TestProxy(t *testing.T) {
if p.BufferSize != "1k" {
t.Errorf("expected 1k as buffer-size but returned %v", p.BufferSize)
}
- if p.BodySize != "2k" {
- t.Errorf("expected 2k as body-size but returned %v", p.BodySize)
+ if p.BodySize != 2 {
+ t.Errorf("expected 2 as body-size but returned %v", p.BodySize)
}
if p.NextUpstream != "off" {
t.Errorf("expected off as next-upstream but returned %v", p.NextUpstream)
@@ -168,7 +168,7 @@ func TestProxyWithNoAnnotation(t *testing.T) {
if p.BufferSize != "10k" {
t.Errorf("expected 10k as buffer-size but returned %v", p.BufferSize)
}
- if p.BodySize != "3k" {
+ if p.BodySize != 3 {
t.Errorf("expected 3k as body-size but returned %v", p.BodySize)
}
if p.NextUpstream != "error" {
diff --git a/gateway/store/store.go b/gateway/store/store.go
index 713ed3529..74c30ae62 100644
--- a/gateway/store/store.go
+++ b/gateway/store/store.go
@@ -29,9 +29,6 @@ import (
"strings"
"sync"
- "github.com/goodrain/rainbond/db/model"
- "k8s.io/apimachinery/pkg/labels"
-
"github.com/Sirupsen/logrus"
"github.com/eapache/channels"
"github.com/goodrain/rainbond/cmd/gateway/option"
@@ -40,7 +37,7 @@ import (
"github.com/goodrain/rainbond/gateway/controller/config"
"github.com/goodrain/rainbond/gateway/defaults"
"github.com/goodrain/rainbond/gateway/util"
- v1 "github.com/goodrain/rainbond/gateway/v1"
+ "github.com/goodrain/rainbond/gateway/v1"
corev1 "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -377,97 +374,74 @@ func (s *k8sStore) extractAnnotations(ing *extensions.Ingress) {
func (s *k8sStore) ListPool() ([]*v1.Pool, []*v1.Pool) {
var httpPools []*v1.Pool
var tcpPools []*v1.Pool
+ l7Pools := make(map[string]*v1.Pool)
+ l4Pools := make(map[string]*v1.Pool)
+ for _, item := range s.listers.Endpoint.List() {
+ ep := item.(*corev1.Endpoints)
- f := func(backendMap map[string][]backend, poolMap map[string]struct{}) map[string]*v1.Pool {
- pools := make(map[string]*v1.Pool)
- for k, v := range backendMap {
- service, err := s.listers.Service.ByKey(k)
- if err != nil {
- logrus.Warningf("Key: %s;error getting service: %v", k, err)
- continue
- }
- originPort := service.GetLabels()["origin_port"]
- var pluginPort int32
- if originPort != "" {
- port, err := strconv.Atoi(originPort)
- if err != nil {
- logrus.Warningf("Origin port: %s; error converting to type int: %v", err)
- pluginPort = 0
- } else {
- pluginPort = int32(port)
+ if ep.Subsets != nil || len(ep.Subsets) != 0 {
+ epn := ep.ObjectMeta.Name
+ // l7
+ backends := l7PoolBackendMap[ep.ObjectMeta.Name]
+ for _, backend := range backends {
+ pool := l7Pools[backend.name]
+ if pool == nil {
+ pool = &v1.Pool{
+ Nodes: []*v1.Node{},
+ }
+ pool.Name = backend.name
+ pool.UpstreamHashBy = backend.hashBy
+ l7Pools[backend.name] = pool
}
- }
-
- // list related endpoints
- labelname, ok := service.GetLabels()["name"]
- if !ok {
- logrus.Warningf("Key: %s;label 'name' not found", k)
- continue
- }
- selector, err := labels.Parse(fmt.Sprintf("name=%s", labelname))
- if err != nil {
- logrus.Warningf("Label: %s; error parsing labels: %s",
- fmt.Sprintf("name=%s", labelname), err.Error())
- continue
- }
- endpoints, err := s.sharedInformer.Core().V1().Endpoints().Lister().Endpoints(service.GetNamespace()).List(selector)
- if err != nil {
- logrus.Warningf("Label: %s; error listing endpoints: %v",
- fmt.Sprintf("name=%s", labelname), err)
- continue
- }
-
- for _, ep := range endpoints {
- if ep.Subsets == nil || len(ep.Subsets) == 0 {
- continue
- }
- if ep.GetLabels()["service_kind"] != model.ServiceKindThirdParty.String() {
- if ep.Subsets[0].Ports[0].Port != service.Spec.Ports[0].TargetPort.IntVal {
- continue
+ for _, ss := range ep.Subsets {
+ var addresses []corev1.EndpointAddress
+ if ss.Addresses != nil && len(ss.Addresses) > 0 {
+ addresses = append(addresses, ss.Addresses...)
+ } else {
+ addresses = append(addresses, ss.NotReadyAddresses...)
+ }
+ for _, address := range addresses {
+ if _, ok := l7PoolMap[epn]; ok { // l7
+ pool.Nodes = append(pool.Nodes, &v1.Node{
+ Host: address.IP,
+ Port: ss.Ports[0].Port,
+ Weight: backend.weight,
+ })
+ }
}
}
-
- for _, backend := range v {
- pool := pools[backend.name]
- if pool == nil {
- pool = &v1.Pool{
- Nodes: []*v1.Node{},
- }
- pool.Name = backend.name
- pool.UpstreamHashBy = backend.hashBy
- pools[backend.name] = pool
+ }
+ // l4
+ backends = l4PoolBackendMap[ep.ObjectMeta.Name]
+ for _, backend := range backends {
+ pool := l4Pools[backend.name]
+ if pool == nil {
+ pool = &v1.Pool{
+ Nodes: []*v1.Node{},
}
- for _, ss := range ep.Subsets {
- var addresses []corev1.EndpointAddress
- if ss.Addresses != nil && len(ss.Addresses) > 0 {
- addresses = append(addresses, ss.Addresses...)
- } else {
- addresses = append(addresses, ss.NotReadyAddresses...)
- }
- for _, address := range addresses {
- if _, ok := poolMap[k]; ok { // l7
- pool.Nodes = append(pool.Nodes, &v1.Node{
- Host: address.IP,
- Port: func(pluginPort, addressPort int32) int32 {
- if pluginPort != 0 {
- return pluginPort
- }
- return addressPort
- }(pluginPort, ss.Ports[0].Port),
- Weight: backend.weight,
- })
- }
+ pool.Name = backend.name
+ l4Pools[backend.name] = pool
+ }
+ for _, ss := range ep.Subsets {
+ var addresses []corev1.EndpointAddress
+ if ss.Addresses != nil && len(ss.Addresses) > 0 {
+ addresses = append(addresses, ss.Addresses...)
+ } else {
+ addresses = append(addresses, ss.NotReadyAddresses...)
+ }
+ for _, address := range addresses {
+ if _, ok := l4PoolMap[epn]; ok { // l7
+ pool.Nodes = append(pool.Nodes, &v1.Node{
+ Host: address.IP,
+ Port: ss.Ports[0].Port,
+ Weight: backend.weight,
+ })
}
}
}
}
}
- return pools
}
-
- l7Pools := f(l7PoolBackendMap, l7PoolMap)
- l4Pools := f(l4PoolBackendMap, l4PoolMap)
-
// change map to slice TODO: use map directly
for _, pool := range l7Pools {
httpPools = append(httpPools, pool)
@@ -491,20 +465,20 @@ func (s *k8sStore) ListVirtualService() (l7vs []*v1.VirtualService, l4vs []*v1.V
if !s.ingressIsValid(ing) {
continue
}
+
ingKey := k8s.MetaNamespaceKey(ing)
anns, err := s.GetIngressAnnotations(ingKey)
if err != nil {
logrus.Errorf("Error getting Ingress annotations %q: %v", ingKey, err)
}
if anns.L4.L4Enable && anns.L4.L4Port != 0 {
- svcKey := fmt.Sprintf("%v/%v", ing.Namespace, ing.Spec.Backend.ServiceName)
-
// region l4
host := strings.Replace(anns.L4.L4Host, " ", "", -1)
if host == "" {
host = s.conf.IP
}
host = s.conf.IP
+ svcKey := fmt.Sprintf("%v/%v", ing.Namespace, ing.Spec.Backend.ServiceName)
protocol := s.GetServiceProtocol(svcKey, ing.Spec.Backend.ServicePort.IntVal)
listening := fmt.Sprintf("%s:%v", host, anns.L4.L4Port)
if string(protocol) == string(v1.ProtocolUDP) {
@@ -521,11 +495,12 @@ func (s *k8sStore) ListVirtualService() (l7vs []*v1.VirtualService, l4vs []*v1.V
vs.Namespace = anns.Namespace
vs.ServiceID = anns.Labels["service_id"]
}
- l4PoolMap[svcKey] = struct{}{}
+
+ l4PoolMap[ing.Spec.Backend.ServiceName] = struct{}{}
l4vsMap[listening] = vs
l4vs = append(l4vs, vs)
backend := backend{name: backendName, weight: anns.Weight.Weight}
- l4PoolBackendMap[svcKey] = append(l4PoolBackendMap[svcKey], backend)
+ l4PoolBackendMap[ing.Spec.Backend.ServiceName] = append(l4PoolBackendMap[ing.Spec.Backend.ServiceName], backend)
// endregion
} else {
// region l7
@@ -577,14 +552,15 @@ func (s *k8sStore) ListVirtualService() (l7vs []*v1.VirtualService, l4vs []*v1.V
vs.SSLCert = hostSSLMap[DefVirSrvName]
}
}
+
l7vsMap[virSrvName] = vs
l7vs = append(l7vs, vs)
}
+
for _, path := range rule.IngressRuleValue.HTTP.Paths {
- svckey := fmt.Sprintf("%s/%s", ing.Namespace, path.Backend.ServiceName)
locKey := fmt.Sprintf("%s_%s", virSrvName, path.Path)
location := srvLocMap[locKey]
- l7PoolMap[svckey] = struct{}{}
+ l7PoolMap[path.Backend.ServiceName] = struct{}{}
// if location do not exists, then creates a new one
if location == nil {
location = &v1.Location{
@@ -593,10 +569,9 @@ func (s *k8sStore) ListVirtualService() (l7vs []*v1.VirtualService, l4vs []*v1.V
}
srvLocMap[locKey] = location
vs.Locations = append(vs.Locations, location)
+ // the first ingress proxy takes effect
+ location.Proxy = anns.Proxy
}
-
- location.Proxy = anns.Proxy
-
// If their ServiceName is the same, then the new one will overwrite the old one.
nameCondition := &v1.Condition{}
var backendName string
@@ -619,7 +594,7 @@ func (s *k8sStore) ListVirtualService() (l7vs []*v1.VirtualService, l4vs []*v1.V
if anns.UpstreamHashBy != "" {
backend.hashBy = anns.UpstreamHashBy
}
- l7PoolBackendMap[svckey] = append(l7PoolBackendMap[svckey], backend)
+ l7PoolBackendMap[path.Backend.ServiceName] = append(l7PoolBackendMap[path.Backend.ServiceName], backend)
}
}
// endregion
@@ -630,57 +605,47 @@ func (s *k8sStore) ListVirtualService() (l7vs []*v1.VirtualService, l4vs []*v1.V
// ingressIsValid checks if the specified ingress is valid
func (s *k8sStore) ingressIsValid(ing *extensions.Ingress) bool {
- var svcKey string
+
+ var endpointKey string
if ing.Spec.Backend != nil { // stream
- svcKey = fmt.Sprintf("%s/%s", ing.Namespace, ing.Spec.Backend.ServiceName)
+ endpointKey = fmt.Sprintf("%s/%s", ing.Namespace, ing.Spec.Backend.ServiceName)
} else { // http
Loop:
for _, rule := range ing.Spec.Rules {
for _, path := range rule.IngressRuleValue.HTTP.Paths {
- svcKey = fmt.Sprintf("%s/%s", ing.Namespace, path.Backend.ServiceName)
- if svcKey != "" {
+ endpointKey = fmt.Sprintf("%s/%s", ing.Namespace, path.Backend.ServiceName)
+ if endpointKey != "" {
break Loop
}
}
}
}
- service, err := s.listers.Service.ByKey(svcKey)
+ item, exists, err := s.listers.Endpoint.GetByKey(endpointKey)
if err != nil {
- logrus.Warningf("Key: %s; error getting key: %v", err)
+ logrus.Errorf("Can not get endpoint by key(%s): %v", endpointKey, err)
return false
}
- labelname := fmt.Sprintf("name=%s", service.GetLabels()["name"])
- selector, err := labels.Parse(labelname)
- if err != nil {
- logrus.Warningf("Label: %s;error parsing labels: %v", labelname, err)
+ if !exists {
+ logrus.Warningf("Endpoint \"%s\" does not exist.", endpointKey)
return false
}
- eps, err := s.sharedInformer.Core().V1().Endpoints().Lister().Endpoints(service.GetNamespace()).List(selector)
- if err != nil {
- logrus.Warningf("selector: %s; error listing endpoints: %v",
- fmt.Sprintf("name=%s", labelname), err)
+ endpoint, ok := item.(*corev1.Endpoints)
+ if !ok {
+ logrus.Errorf("Cant not convert %v to %v", reflect.TypeOf(item), reflect.TypeOf(endpoint))
return false
}
- if eps == nil || len(eps) == 0 {
- logrus.Warningf("Selector: %s; empty endpoints", fmt.Sprintf("name=%s", labelname))
+ if endpoint.Subsets == nil || len(endpoint.Subsets) == 0 {
+ logrus.Warningf("Endpoints(%s) is empty, ignore it", endpointKey)
+ return false
}
-
- result := false
- for _, ep := range eps {
- if ep.Subsets != nil && len(ep.Subsets) > 0 {
- e := ep.Subsets[0]
- if ep.GetLabels()["service_kind"] != model.ServiceKindThirdParty.String() &&
- e.Ports[0].Port != service.Spec.Ports[0].Port {
- continue
- }
- if !((e.Addresses == nil || len(e.Addresses) == 0) && (e.NotReadyAddresses == nil || len(e.NotReadyAddresses) == 0)) {
- result = true
- break
- }
+ for _, ep := range endpoint.Subsets {
+ if (ep.Addresses == nil || len(ep.Addresses) == 0) && (ep.NotReadyAddresses == nil || len(ep.NotReadyAddresses) == 0) {
+ logrus.Warningf("Endpoints(%s) is empty, ignore it", endpointKey)
+ return false
}
}
- return result
+ return true
}
// GetIngress returns the Ingress matching key.
@@ -701,20 +666,6 @@ func (s *k8sStore) ListIngresses() []*extensions.Ingress {
return ingresses
}
-// GetServiceNameLabelByKey returns name in the labels of corev1.Service
-// matching key(name/namespace).
-func (s *k8sStore) GetServiceNameLabelByKey(key string) (string, error) {
- svc, err := s.listers.Service.ByKey(key)
- if err != nil {
- return "", err
- }
- name, ok := svc.Labels["name"]
- if !ok {
- return "", fmt.Errorf("label \"name\" not found")
- }
- return name, nil
-}
-
// GetServiceProtocol returns the Service matching key and port.
func (s *k8sStore) GetServiceProtocol(key string, port int32) corev1.Protocol {
svcs, err := s.listers.Service.ByKey(key)
diff --git a/gateway/v1/location.go b/gateway/v1/location.go
index 95880122a..38b901a93 100644
--- a/gateway/v1/location.go
+++ b/gateway/v1/location.go
@@ -75,6 +75,10 @@ func (l *Location) Equals(c *Location) bool {
}
}
+ if !l.Proxy.Equal(&c.Proxy) {
+ return false
+ }
+
return true
}
diff --git a/gateway/v1/node.go b/gateway/v1/node.go
index a298b6375..778c8186e 100644
--- a/gateway/v1/node.go
+++ b/gateway/v1/node.go
@@ -46,6 +46,9 @@ func (n *Node) Equals(c *Node) bool { //
if n.Host != c.Host {
return false
}
+ if n.Port != c.Port {
+ return false
+ }
if n.Protocol != c.Protocol {
return false
}
@@ -61,5 +64,11 @@ func (n *Node) Equals(c *Node) bool { //
if n.Weight != c.Weight {
return false
}
+ if n.MaxFails != c.MaxFails {
+ return false
+ }
+ if n.FailTimeout != c.FailTimeout {
+ return false
+ }
return true
}
diff --git a/gateway/v1/node_test.go b/gateway/v1/node_test.go
index 84a920f04..ef277a09f 100644
--- a/gateway/v1/node_test.go
+++ b/gateway/v1/node_test.go
@@ -18,42 +18,21 @@
package v1
-import "testing"
+import (
+ "testing"
+)
func TestNode_Equals(t *testing.T) {
- n := &Node{
- Meta: Meta{
- Index: 888,
- Name: "foo-node",
- Namespace: "ns",
- PluginName: "Nginx",
- },
- Host: "www.goodrain.com",
- Port: 80,
- Protocol: "Http",
- State: "ok",
- PoolName: "foo-poolName",
- Ready: true,
- Weight: 5,
- }
- c := &Node{
- Meta: Meta{
- Index: 888,
- Name: "foo-node",
- Namespace: "ns",
- PluginName: "Nginx",
- },
- Host: "www.goodrain.com",
- Port: 80,
- Protocol: "Http",
- State: "ok",
- PoolName: "foo-poolName",
- Ready: true,
- Weight: 5,
- }
+ n := newFakeNode()
+ c := newFakeNode()
if !n.Equals(c) {
t.Errorf("n should equal c")
}
+ f := newFakeNode()
+ f.MaxFails = 5
+ if n.Equals(f) {
+ t.Errorf("n should not equal c")
+ }
}
func newFakeNode() *Node {
@@ -71,5 +50,7 @@ func newFakeNode() *Node {
PoolName: "foo-poolName",
Ready: true,
Weight: 5,
+ MaxFails: 3,
+ FailTimeout: "5",
}
}
diff --git a/gateway/v1/ssl_cert.go b/gateway/v1/ssl_cert.go
index 68a5c9a20..f3fa23f3e 100644
--- a/gateway/v1/ssl_cert.go
+++ b/gateway/v1/ssl_cert.go
@@ -47,7 +47,7 @@ func (s *SSLCert) Equals(c *SSLCert) bool {
if !s.Meta.Equals(c.Meta) {
return false
}
- if s.CertificatePem != c.CertificatePem {
+ if (s.Certificate == nil) != (c.Certificate == nil) {
return false
}
if s.Certificate != nil && c.Certificate != nil {
@@ -55,9 +55,6 @@ func (s *SSLCert) Equals(c *SSLCert) bool {
return false
}
}
- if !(s.Certificate == nil && c.Certificate == nil) {
- return false
- }
if s.CertificateStr != c.CertificateStr {
return false
}
diff --git a/gateway/v1/ssl_cert_test.go b/gateway/v1/ssl_cert_test.go
index 5f200f9e9..177400a78 100644
--- a/gateway/v1/ssl_cert_test.go
+++ b/gateway/v1/ssl_cert_test.go
@@ -30,14 +30,24 @@ func TestSSLCert_Equals(t *testing.T) {
if !s.Equals(c) {
t.Errorf("s should equal c.")
}
+ s.Certificate = nil
+ if s.Equals(c) {
+ t.Errorf("s should not equal c.")
+ }
+ c.Certificate = nil
+ if !s.Equals(c) {
+ t.Errorf("s should equal c.")
+ }
}
func newFakeSSLCert() *SSLCert {
meta := newFakeMeta()
+ certificate := &x509.Certificate{}
+ certificate.Raw = []byte("foobar")
return &SSLCert{
Meta: &meta,
CertificateStr: "dummy certificate str",
- Certificate: &x509.Certificate{},
+ Certificate: certificate,
PrivateKey: "dummy private key",
CertificatePem: "/expert/servers/nginx/certificate/dummy-secret.pem",
CN: []string{
diff --git a/gateway/v1/virtual_service.go b/gateway/v1/virtual_service.go
index 5475eeea5..dd5de61b0 100644
--- a/gateway/v1/virtual_service.go
+++ b/gateway/v1/virtual_service.go
@@ -174,6 +174,17 @@ func (v *VirtualService) Equals(c *VirtualService) bool {
if !v.SSLCert.Equals(c.SSLCert) {
return false
}
+ if v.ForceSSLRedirect != c.ForceSSLRedirect {
+ return false
+ }
+ if len(v.ExtensionConfig) != len(c.ExtensionConfig) {
+ return false
+ }
+ for key, ve := range v.ExtensionConfig {
+ if c.ExtensionConfig[key] != ve {
+ return false
+ }
+ }
return true
}
diff --git a/grctl/cmd/service.go b/grctl/cmd/service.go
index 9124586fe..258d6878c 100644
--- a/grctl/cmd/service.go
+++ b/grctl/cmd/service.go
@@ -392,6 +392,36 @@ func showServiceDeployInfo(c *cli.Context) error {
}
fmt.Println("------------Service------------")
fmt.Println(serviceTable.Render())
+ //show endpoints
+ if deployInfo.Endpoints != nil && len(deployInfo.Endpoints) > 0 {
+ epTable := termtables.CreateTable()
+ epTable.AddHeaders("Name", "IP", "Port", "Protocol")
+ for epname := range deployInfo.Endpoints {
+ if clients.K8SClient != nil {
+ ep, _ := clients.K8SClient.CoreV1().Endpoints(tenantID).Get(epname, metav1.GetOptions{})
+ if ep != nil {
+ for i := range ep.Subsets {
+ ss := &ep.Subsets[i]
+ for j := range ss.Ports {
+ port := &ss.Ports[j]
+ for k := range ss.Addresses {
+ address := &ss.Addresses[k]
+ epTable.AddRow(ep.Name, address.IP, port.Port, port.Protocol)
+ }
+ for k := range ss.NotReadyAddresses {
+ address := &ss.NotReadyAddresses[k]
+ epTable.AddRow(ep.Name, address.IP, port.Port, port.Protocol)
+ }
+ }
+ }
+ }
+ } else {
+ epTable.AddRow(epname, "-", "-", "-")
+ }
+ }
+ fmt.Println("------------endpoints------------")
+ fmt.Println(epTable.Render())
+ }
//show ingress
ingressTable := termtables.CreateTable()
ingressTable.AddHeaders("Name", "Host")
diff --git a/release.sh b/release.sh
index c769c2800..fc7443c83 100755
--- a/release.sh
+++ b/release.sh
@@ -7,7 +7,12 @@ BASE_NAME=rainbond
GO_VERSION=1.11
GATEWAY_GO_VERSION=1.11-alpine3.8
-VERSION=master
+VERSION=5.1.1
+if [ -z "$TRAVIS_TAG" ]; then
+ VERSION=$TRAVIS_BRANCH-dev
+else
+ VERSION=$TRAVIS_TAG
+fi
buildTime=$(date +%F-%H)
git_commit=$(git log -n 1 --pretty --format=%h)
diff --git a/util/prober/manager.go b/util/prober/manager.go
index 6542e4d66..43bffcedd 100644
--- a/util/prober/manager.go
+++ b/util/prober/manager.go
@@ -20,7 +20,6 @@ package prober
import (
"context"
- "encoding/json"
"errors"
"sync"
"time"
@@ -39,12 +38,13 @@ type Prober interface {
CloseWatch(serviceName string, id string) error
Start()
AddServices(in []*v1.Service)
- CheckAndAddService(in *v1.Service) bool
+ CheckIfExist(in *v1.Service) bool
SetServices([]*v1.Service)
GetServices() []*v1.Service
GetServiceHealth() map[string]*v1.HealthStatus
SetAndUpdateServices([]*v1.Service) error
AddAndUpdateServices([]*v1.Service) error
+ UpdateServiceProbe(service *v1.Service)
UpdateServicesProbe(services []*v1.Service)
Stop() error
DisableWatcher(serviceName, watcherID string)
@@ -276,22 +276,30 @@ func (p *probeManager) AddServices(in []*v1.Service) {
}
// CheckAndAddService checks if the input service exists, if it does not exist, add it.
-func (p *probeManager) CheckAndAddService(in *v1.Service) bool {
+func (p *probeManager) CheckIfExist(in *v1.Service) bool {
exist := false
for _, svc := range p.services {
if svc.Name == in.Name {
- logrus.Debugf("svc name: %s; in name: %s;", svc.Name, in.Name)
exist = true
}
}
- if !exist {
- b, _ := json.Marshal(in)
- logrus.Debugf("add service: %s", string(b))
- p.services = append(p.services, in)
- }
return exist
}
+func (p *probeManager) isNeedUpdate(new *v1.Service) bool {
+ var old *v1.Service
+ for _, svc := range p.services {
+ if svc.Name == new.Name {
+ old = svc
+ }
+ }
+ if old == nil {
+ // not found old one
+ return true
+ }
+ return !new.Equal(old)
+}
+
func (p *probeManager) GetServiceHealth() map[string]*v1.HealthStatus {
return p.status
}
@@ -361,21 +369,46 @@ func (p *probeManager) updateAllServicesProbe() {
}
}
+// UpdateServiceProbe updates and runs one service probe.
+func (p *probeManager) UpdateServiceProbe(service *v1.Service) {
+ if service.ServiceHealth == nil || service.Disable || !p.isNeedUpdate(service) {
+ return
+ }
+ logrus.Debugf("Probe: %s; update probe.", service.Name)
+ // stop old probe
+ old := p.serviceProbe[service.Name]
+ if old != nil {
+ old.Stop()
+ }
+ // create new probe
+ serviceProbe := probe.CreateProbe(p.ctx, p.statusChan, service)
+ if serviceProbe != nil {
+ p.serviceProbe[service.Name] = serviceProbe
+ serviceProbe.Check()
+ }
+}
+
// UpdateServicesProbe updates and runs services probe.
func (p *probeManager) UpdateServicesProbe(services []*v1.Service) {
- logrus.Debugf("update services probe...")
+ if services == nil || len(services) == 0 {
+ logrus.Debug("Empty services")
+ return
+ }
+ oldSvcs := p.ListServicesBySid(services[0].Sid)
for _, v := range services {
- if v.ServiceHealth == nil {
- continue
- }
- if v.Disable {
+ delete(oldSvcs, v.Name)
+ if v.ServiceHealth == nil || v.Disable || !p.isNeedUpdate(v) {
continue
}
+ logrus.Debugf("Probe: %s; update probe.", v.Name)
// stop old probe
old := p.serviceProbe[v.Name]
if old != nil {
old.Stop()
}
+ if !p.CheckIfExist(v) {
+ p.services = append(p.services, v)
+ }
// create new probe
serviceProbe := probe.CreateProbe(p.ctx, p.statusChan, v)
if serviceProbe != nil {
@@ -383,6 +416,20 @@ func (p *probeManager) UpdateServicesProbe(services []*v1.Service) {
serviceProbe.Check()
}
}
+ for _, svc := range oldSvcs {
+ p.StopProbes([]string{svc.Name})
+ }
+}
+
+// ListServicesBySid lists services corresponding to sid.
+func (p *probeManager) ListServicesBySid(sid string) map[string]*v1.Service {
+ res := make(map[string]*v1.Service)
+ for _, svc := range p.services {
+ if svc.Sid == sid {
+ res[svc.Name] = svc
+ }
+ }
+ return res
}
// GetProbe returns a probe associated with name.
@@ -397,6 +444,7 @@ func (p *probeManager) StopProbes(names []string) {
logrus.Debugf("Name: %s; Probe not found.", name)
continue
}
+ logrus.Debugf("Name: %s; Probe stopped", name)
probe.Stop()
delete(p.serviceProbe, name)
for idx, svc := range p.services {
diff --git a/util/prober/probes/probe.go b/util/prober/probes/probe.go
index 9b15666d2..a14d48b0d 100644
--- a/util/prober/probes/probe.go
+++ b/util/prober/probes/probe.go
@@ -20,7 +20,6 @@ package probe
import (
"context"
- "github.com/Sirupsen/logrus"
"github.com/goodrain/rainbond/util/prober/types/v1"
)
@@ -34,7 +33,6 @@ type Probe interface {
func CreateProbe(ctx context.Context, statusChan chan *v1.HealthStatus, v *v1.Service) Probe {
ctx, cancel := context.WithCancel(ctx)
if v.ServiceHealth.Model == "tcp" {
- logrus.Debug("creat tcp probe...")
t := &TCPProbe{
Name: v.ServiceHealth.Name,
Address: v.ServiceHealth.Address,
@@ -47,7 +45,6 @@ func CreateProbe(ctx context.Context, statusChan chan *v1.HealthStatus, v *v1.Se
return t
}
if v.ServiceHealth.Model == "http" {
- logrus.Debug("creat http probe...")
t := &HTTPProbe{
Name: v.ServiceHealth.Name,
Address: v.ServiceHealth.Address,
diff --git a/util/prober/probes/tcp.go b/util/prober/probes/tcp.go
index 60149e7ae..4e330f659 100644
--- a/util/prober/probes/tcp.go
+++ b/util/prober/probes/tcp.go
@@ -32,7 +32,7 @@ func (h *TCPProbe) Stop() {
// TCPCheck -
func (h *TCPProbe) TCPCheck() {
- logrus.Debug("tcp check...")
+ logrus.Debugf("TCP check; Name: %s; Address: %s", h.Name, h.Address)
timer := time.NewTimer(time.Second * time.Duration(h.TimeInterval))
defer timer.Stop()
for {
diff --git a/util/prober/types/v1/types.go b/util/prober/types/v1/types.go
index 3269da38f..0e70cc398 100644
--- a/util/prober/types/v1/types.go
+++ b/util/prober/types/v1/types.go
@@ -25,27 +25,78 @@ const (
StatHealthy string = "healthy"
// StatUnhealthy -
StatUnhealthy string = "unhealthy"
- // StaTDeath -
+ // StatDeath -
StatDeath string = "death"
)
-//Service Service
+// Service Service
type Service struct {
+ Sid string `json:"service_id"`
Name string `json:"name"`
ServiceHealth *Health `json:"health"`
Disable bool `json:"disable"`
}
+// Equal check if the left service(l) is equal to the right service(r)
+func (l *Service) Equal(r *Service) bool {
+ if l == r {
+ return true
+ }
+ if l.Sid != r.Sid {
+ return false
+ }
+ if l.Name != r.Name {
+ return false
+ }
+ if l.Disable != r.Disable {
+ return false
+ }
+ if !l.ServiceHealth.Equal(r.ServiceHealth) {
+ return false
+ }
+ return true
+}
+
//Health ServiceHealth
type Health struct {
Name string `json:"name"`
Model string `json:"model"`
+ IP string `json:"ip"`
Port int `json:"port"`
Address string `json:"address"`
TimeInterval int `json:"time_interval"`
MaxErrorsNum int `json:"max_errors_num"`
}
+// Equal check if the left health(l) is equal to the right health(r)
+func (l *Health) Equal(r *Health) bool {
+ if l == r {
+ return true
+ }
+ if l.Name != r.Name {
+ return false
+ }
+ if l.Model != r.Model {
+ return false
+ }
+ if l.IP != r.IP {
+ return false
+ }
+ if l.Port != r.Port {
+ return false
+ }
+ if l.Address != r.Address {
+ return false
+ }
+ if l.TimeInterval != r.TimeInterval {
+ return false
+ }
+ if l.MaxErrorsNum != r.MaxErrorsNum {
+ return false
+ }
+ return true
+}
+
//HealthStatus health status
type HealthStatus struct {
Name string `json:"name"`
diff --git a/worker/appm/controller/restart.go b/worker/appm/controller/restart.go
index 2b74efeb9..df0bf8e16 100644
--- a/worker/appm/controller/restart.go
+++ b/worker/appm/controller/restart.go
@@ -55,8 +55,10 @@ func (s *restartController) Begin() {
s.manager.callback(s.controllerID, nil)
}
func (s *restartController) restartOne(app v1.AppService) error {
- stopController := stopController{
+ //Restart the control set timeout interval is 5m
+ stopController := &stopController{
manager: s.manager,
+ waiting: time.Minute * 5,
}
if err := stopController.stopOne(app); err != nil {
app.Logger.Error("(Restart)Stop app failure %s,you could waiting stoped and manual start it", GetCallbackLoggerOption())
diff --git a/worker/appm/controller/stop.go b/worker/appm/controller/stop.go
index 2b7535eee..c522fb8d7 100644
--- a/worker/appm/controller/stop.go
+++ b/worker/appm/controller/stop.go
@@ -35,6 +35,7 @@ type stopController struct {
controllerID string
appService []v1.AppService
manager *Manager
+ waiting time.Duration
}
func (s *stopController) Begin() {
@@ -143,6 +144,9 @@ func (s *stopController) WaitingReady(app v1.AppService) error {
if storeAppService != nil && storeAppService.Replicas > 0 {
timeout = time.Duration(storeAppService.Replicas) * timeout
}
+ if s.waiting != 0 {
+ timeout = s.waiting
+ }
if err := WaitStop(s.manager.store, storeAppService, timeout, app.Logger, s.stopChan); err != nil {
return err
}
diff --git a/worker/appm/controller/upgrade.go b/worker/appm/controller/upgrade.go
index d9d731324..554ffb561 100644
--- a/worker/appm/controller/upgrade.go
+++ b/worker/appm/controller/upgrade.go
@@ -20,15 +20,16 @@ package controller
import (
"fmt"
+ "github.com/goodrain/rainbond/worker/appm/f"
"sync"
"time"
"github.com/Sirupsen/logrus"
- v1 "github.com/goodrain/rainbond/worker/appm/types/v1"
+ "github.com/goodrain/rainbond/worker/appm/types/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- types "k8s.io/apimachinery/pkg/types"
+ "k8s.io/apimachinery/pkg/types"
)
type upgradeController struct {
@@ -140,7 +141,6 @@ func (s *upgradeController) upgradeService(newapp v1.AppService) {
}
func (s *upgradeController) upgradeOne(app v1.AppService) error {
-
//first: check and create namespace
_, err := s.manager.client.CoreV1().Namespaces().Get(app.TenantID, metav1.GetOptions{})
if err != nil {
@@ -167,27 +167,16 @@ func (s *upgradeController) upgradeOne(app v1.AppService) error {
}
}
- if ingresses := app.GetIngress(); ingresses != nil {
- for _, ingress := range ingresses {
- _, err := s.manager.client.Extensions().Ingresses(ingress.Namespace).Update(ingress)
- if err != nil {
- app.Logger.Error(fmt.Sprintf("upgrade ingress %s failure %s", app.ServiceAlias, err.Error()), getLoggerOption("failure"))
- logrus.Errorf("upgrade ingress %s failure %s", app.ServiceAlias, err.Error())
- }
- }
- }
- //upgrade k8s service
+ oldApp := s.manager.store.GetAppService(app.ServiceID)
s.upgradeService(app)
- //upgrade k8s secrets
- if secrets := app.GetSecrets(); secrets != nil {
- for _, secret := range secrets {
- _, err := s.manager.client.CoreV1().Secrets(secret.Namespace).Update(secret)
- if err != nil {
- app.Logger.Error(fmt.Sprintf("upgrade secret %s failure %s", app.ServiceAlias, err.Error()), getLoggerOption("failure"))
- logrus.Errorf("upgrade secret %s failure %s", app.ServiceAlias, err.Error())
- }
- }
+ handleErr := func(msg string, err error) error {
+ // ignore ingress and secret error
+ logrus.Warning(msg)
+ return nil
}
+ _ = f.UpgradeSecrets(s.manager.client, &app, oldApp.GetSecrets(), app.GetSecrets(), handleErr)
+ _ = f.UpgradeIngress(s.manager.client, &app, oldApp.GetIngress(), app.GetIngress(), handleErr)
+
return s.WaitingReady(app)
}
diff --git a/worker/appm/conversion/plugin.go b/worker/appm/conversion/plugin.go
index c34a37c31..d516c3f89 100644
--- a/worker/appm/conversion/plugin.go
+++ b/worker/appm/conversion/plugin.go
@@ -24,6 +24,8 @@ import (
"os"
"strings"
+ "github.com/goodrain/rainbond/builder"
+
"github.com/Sirupsen/logrus"
api_model "github.com/goodrain/rainbond/api/model"
@@ -149,7 +151,7 @@ func createUDPDefaultPluginContainer(serviceID string, envs []v1.EnvVar) v1.Cont
}},
Env: envs,
TerminationMessagePath: "",
- Image: "goodrain.me/adapter",
+ Image: builder.REGISTRYDOMAIN + "/adapter",
Resources: createAdapterResources(128, 500),
}
}
@@ -239,7 +241,7 @@ func applyDefaultMeshPluginConfig(as *typesv1.AppService, dbmanager db.Manager)
if err != nil {
return "", err
}
- pluginID := "tcpmesh" + util.NewUUID()
+ pluginID := "tcpmesh" + as.ServiceID
cm := &v1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("config-%s-%s", as.ServiceID, pluginID),
diff --git a/worker/appm/f/function.go b/worker/appm/f/function.go
index b4a6717f6..f84eb7787 100644
--- a/worker/appm/f/function.go
+++ b/worker/appm/f/function.go
@@ -20,9 +20,8 @@ package f
import (
"fmt"
-
"github.com/Sirupsen/logrus"
- v1 "github.com/goodrain/rainbond/worker/appm/types/v1"
+ "github.com/goodrain/rainbond/worker/appm/types/v1"
corev1 "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
@@ -54,7 +53,7 @@ func ApplyOne(clientset *kubernetes.Clientset, app *v1.AppService) error {
}
// update endpoints
for _, ep := range app.GetEndpoints() {
- ensureEndpoints(ep, clientset)
+ EnsureEndpoints(ep, clientset)
}
// update ingress
for _, ing := range app.GetIngress() {
@@ -76,16 +75,6 @@ func ApplyOne(clientset *kubernetes.Clientset, app *v1.AppService) error {
logrus.Warningf("error deleting secret(%v): %v", secret, err)
}
}
- // delete delEndpoints
- for _, ep := range app.GetDelEndpoints() {
- err := clientset.CoreV1().Endpoints(ep.Namespace).Delete(ep.Name, &metav1.DeleteOptions{})
- if err != nil {
- // don't return error, hope it is ok next time
- logrus.Warningf("error deleting endpoints(%v): %v", ep, err)
- continue
- }
- logrus.Debugf("successfully deleted endpoints(%v)", ep)
- }
// delete delServices
for _, svc := range app.GetDelServices() {
err := clientset.CoreV1().Services(svc.Namespace).Delete(svc.Name, &metav1.DeleteOptions{})
@@ -151,9 +140,9 @@ func ensureSecret(secret *corev1.Secret, clientSet kubernetes.Interface) {
}
}
-func ensureEndpoints(ep *corev1.Endpoints, clientSet kubernetes.Interface) {
+// EnsureEndpoints creates or updates endpoints.
+func EnsureEndpoints(ep *corev1.Endpoints, clientSet kubernetes.Interface) {
_, err := clientSet.CoreV1().Endpoints(ep.Namespace).Update(ep)
-
if err != nil {
if k8sErrors.IsNotFound(err) {
_, err := clientSet.CoreV1().Endpoints(ep.Namespace).Create(ep)
@@ -166,15 +155,166 @@ func ensureEndpoints(ep *corev1.Endpoints, clientSet kubernetes.Interface) {
}
}
-// If the port has three different values, one of them cannot be 0
-func checkRbdEndpoints(rbdEndpoints []*v1.RbdEndpoints) bool {
- if len(rbdEndpoints) < 2 {
- return true
+// UpgradeIngress is used to update *extensions.Ingress.
+func UpgradeIngress(clientset *kubernetes.Clientset,
+ as *v1.AppService,
+ old, new []*extensions.Ingress,
+ handleErr func(msg string, err error) error) error {
+ var oldMap = make(map[string]*extensions.Ingress, len(old))
+ for i, item := range old {
+ oldMap[item.Name] = old[i]
}
- for _, item := range rbdEndpoints {
- if item.Port == 0 {
- return false
+ for _, n := range new {
+ if o, ok := oldMap[n.Name]; ok {
+ n.UID = o.UID
+ n.ResourceVersion = o.ResourceVersion
+ ing, err := clientset.ExtensionsV1beta1().Ingresses(n.Namespace).Update(n)
+ if err != nil {
+ if err := handleErr(fmt.Sprintf("error updating ingress: %+v: err: %v",
+ ing, err), err); err != nil {
+ return err
+ }
+ continue
+ }
+ as.SetIngress(ing)
+ delete(oldMap, o.Name)
+ logrus.Debugf("ServiceID: %s; successfully update ingress: %s", as.ServiceID, ing.Name)
+ } else {
+ logrus.Debugf("ingress: %+v", n)
+ ing, err := clientset.ExtensionsV1beta1().Ingresses(n.Namespace).Create(n)
+ if err != nil {
+ if err := handleErr(fmt.Sprintf("error creating ingress: %+v: err: %v",
+ ing, err), err); err != nil {
+ return err
+ }
+ continue
+ }
+ as.SetIngress(ing)
+ logrus.Debugf("ServiceID: %s; successfully create ingress: %s", as.ServiceID, ing.Name)
}
}
- return true
+ for _, ing := range oldMap {
+ if ing != nil {
+ if err := clientset.ExtensionsV1beta1().Ingresses(ing.Namespace).Delete(ing.Name,
+ &metav1.DeleteOptions{}); err != nil {
+ if err := handleErr(fmt.Sprintf("error deleting ingress: %+v: err: %v",
+ ing, err), err); err != nil {
+ return err
+ }
+ continue
+ }
+ logrus.Debugf("ServiceID: %s; successfully delete ingress: %s", as.ServiceID, ing.Name)
+ }
+ }
+ return nil
+}
+
+// UpgradeSecrets is used to update *corev1.Secret.
+func UpgradeSecrets(clientset *kubernetes.Clientset,
+ as *v1.AppService, old, new []*corev1.Secret,
+ handleErr func(msg string, err error) error) error {
+ var oldMap = make(map[string]*corev1.Secret, len(old))
+ for i, item := range old {
+ oldMap[item.Name] = old[i]
+ }
+ for _, n := range new {
+ if o, ok := oldMap[n.Name]; ok {
+ n.UID = o.UID
+ n.ResourceVersion = o.ResourceVersion
+ sec, err := clientset.CoreV1().Secrets(n.Namespace).Update(n)
+ if err != nil {
+ if err := handleErr(fmt.Sprintf("error updating secret: %+v: err: %v",
+ sec, err), err); err != nil {
+ return err
+ }
+ continue
+ }
+ as.SetSecret(sec)
+ delete(oldMap, o.Name)
+ logrus.Debugf("ServiceID: %s; successfully update secret: %s", as.ServiceID, sec.Name)
+ } else {
+ sec, err := clientset.CoreV1().Secrets(n.Namespace).Create(n)
+ if err != nil {
+ if err := handleErr(fmt.Sprintf("error creating secret: %+v: err: %v",
+ sec, err), err); err != nil {
+ return err
+ }
+ continue
+ }
+ as.SetSecret(sec)
+ logrus.Debugf("ServiceID: %s; successfully create secret: %s", as.ServiceID, sec.Name)
+ }
+ }
+ for _, sec := range oldMap {
+ if sec != nil {
+ if err := clientset.CoreV1().Secrets(sec.Namespace).Delete(sec.Name, &metav1.DeleteOptions{}); err != nil {
+ if err := handleErr(fmt.Sprintf("error deleting secret: %+v: err: %v",
+ sec, err), err); err != nil {
+ return err
+ }
+ continue
+ }
+ logrus.Debugf("ServiceID: %s; successfully delete secret: %s", as.ServiceID, sec.Name)
+ }
+ }
+ return nil
+}
+
+// UpgradeEndpoints is used to update *corev1.Endpoints.
+func UpgradeEndpoints(clientset *kubernetes.Clientset,
+ as *v1.AppService, old, new []*corev1.Endpoints,
+ handleErr func(msg string, err error) error) error {
+ var oldMap = make(map[string]*corev1.Endpoints, len(old))
+ for i, item := range old {
+ oldMap[item.Name] = old[i]
+ }
+ for _, n := range new {
+ if o, ok := oldMap[n.Name]; ok {
+ ep, err := clientset.CoreV1().Endpoints(n.Namespace).Update(n)
+ if err != nil {
+ if e := handleErr(fmt.Sprintf("error updating endpoints: %+v: err: %v",
+ ep, err), err); e != nil {
+ return e
+ }
+ continue
+ }
+ as.AddEndpoints(ep)
+ delete(oldMap, o.Name)
+ logrus.Debugf("ServiceID: %s; successfully update endpoints: %s", as.ServiceID, ep.Name)
+ } else {
+ _, err := clientset.CoreV1().Endpoints(n.Namespace).Create(n)
+ if err != nil {
+ if err := handleErr(fmt.Sprintf("error creating endpoints: %+v: err: %v",
+ n, err), err); err != nil {
+ return err
+ }
+ continue
+ }
+ as.AddEndpoints(n)
+ logrus.Debugf("ServiceID: %s; successfully create endpoints: %s", as.ServiceID, n.Name)
+ }
+ }
+ for _, sec := range oldMap {
+ if sec != nil {
+ if err := clientset.CoreV1().Endpoints(sec.Namespace).Delete(sec.Name, &metav1.DeleteOptions{}); err != nil {
+ if err := handleErr(fmt.Sprintf("error deleting endpoints: %+v: err: %v",
+ sec, err), err); err != nil {
+ return err
+ }
+ continue
+ }
+ logrus.Debugf("ServiceID: %s; successfully delete endpoints: %s", as.ServiceID, sec.Name)
+ }
+ }
+ return nil
+}
+
+// UpdateEndpoints uses clientset to update the given Endpoints.
+func UpdateEndpoints(ep *corev1.Endpoints, clientSet *kubernetes.Clientset) {
+ _, err := clientSet.CoreV1().Endpoints(ep.Namespace).Update(ep)
+ if err != nil {
+ logrus.Warningf("error updating endpoints: %+v; err: %v", ep, err)
+ return
+ }
+ logrus.Debugf("Key: %s/%s; Successfully update endpoints", ep.GetNamespace(), ep.GetName())
}
diff --git a/worker/appm/prober/prober.go b/worker/appm/prober/prober.go
index 96c65159d..a52d48423 100644
--- a/worker/appm/prober/prober.go
+++ b/worker/appm/prober/prober.go
@@ -21,15 +21,13 @@ package prober
import (
"context"
"fmt"
- "strconv"
- "strings"
"github.com/Sirupsen/logrus"
"github.com/eapache/channels"
"github.com/goodrain/rainbond/db"
"github.com/goodrain/rainbond/db/model"
uitlprober "github.com/goodrain/rainbond/util/prober"
- "github.com/goodrain/rainbond/util/prober/types/v1"
+ v1 "github.com/goodrain/rainbond/util/prober/types/v1"
"github.com/goodrain/rainbond/worker/appm/store"
"github.com/goodrain/rainbond/worker/appm/thirdparty/discovery"
appmv1 "github.com/goodrain/rainbond/worker/appm/types/v1"
@@ -41,8 +39,8 @@ import (
type Prober interface {
Start()
Stop()
- AddProbe(ep *corev1.Endpoints)
- StopProbe(ep *corev1.Endpoints)
+ UpdateProbes(info []*store.ProbeInfo)
+ StopProbe(uuids []string)
}
// NewProber creates a new third-party service prober.
@@ -100,19 +98,14 @@ func (t *tpProbe) Start() {
evt := event.(store.Event)
switch evt.Type {
case store.CreateEvent:
- logrus.Debug("create probe")
- ep := evt.Obj.(*corev1.Endpoints)
- t.AddProbe(ep)
+ infos := evt.Obj.([]*store.ProbeInfo)
+ t.UpdateProbes(infos)
case store.UpdateEvent:
- logrus.Debug("update probe")
- old := evt.Old.(*corev1.Endpoints)
- ep := evt.Obj.(*corev1.Endpoints)
- t.StopProbe(old)
- t.AddProbe(ep)
+ infos := evt.Obj.([]*store.ProbeInfo)
+ t.UpdateProbes(infos)
case store.DeleteEvent:
- logrus.Debug("delete probe")
- ep := evt.Obj.(*corev1.Endpoints)
- t.StopProbe(ep)
+ uuids := evt.Obj.([]string)
+ t.StopProbe(uuids)
}
case <-t.ctx.Done():
return
@@ -126,83 +119,83 @@ func (t *tpProbe) Stop() {
t.cancel()
}
-func (t *tpProbe) AddProbe(ep *corev1.Endpoints) {
- service, probeInfo, sid := t.createServices(ep)
- if service == nil {
- logrus.Debugf("Empty service, stop creating probe")
- return
- }
- ip := ep.GetLabels()["ip"]
- port, _ := strconv.Atoi(ep.GetLabels()["port"])
- // watch
- logrus.Debug("enable watcher...")
- if t.utilprober.CheckAndAddService(service) {
- logrus.Debugf("Service: %+v; Exists", service)
- return
- }
- go func(service *v1.Service) {
- watcher := t.utilprober.WatchServiceHealthy(service.Name)
- t.utilprober.EnableWatcher(watcher.GetServiceName(), watcher.GetID())
- defer watcher.Close()
- defer t.utilprober.DisableWatcher(watcher.GetServiceName(), watcher.GetID())
- for {
- select {
- case event := <-watcher.Watch():
- if event == nil {
- return
- }
- switch event.Status {
- case v1.StatHealthy:
- obj := &appmv1.RbdEndpoint{
- UUID: service.Name,
- IP: ip,
- Port: port,
- Sid: sid,
+func (t *tpProbe) UpdateProbes(infos []*store.ProbeInfo) {
+ var services []*v1.Service
+ for _, info := range infos {
+ service, probeInfo := t.createServices(info)
+ if service == nil {
+ logrus.Debugf("Empty service, stop creating probe")
+ continue
+ }
+ services = append(services, service)
+ // watch
+ if t.utilprober.CheckIfExist(service) {
+ continue
+ }
+ go func(service *v1.Service, info *store.ProbeInfo) {
+ watcher := t.utilprober.WatchServiceHealthy(service.Name)
+ t.utilprober.EnableWatcher(watcher.GetServiceName(), watcher.GetID())
+ defer watcher.Close()
+ defer t.utilprober.DisableWatcher(watcher.GetServiceName(), watcher.GetID())
+ for {
+ select {
+ case event := <-watcher.Watch():
+ if event == nil {
+ return
}
- t.updateCh.In() <- discovery.Event{
- Type: discovery.HealthEvent,
- Obj: obj,
- }
- case v1.StatDeath, v1.StatUnhealthy:
- if event.ErrorNumber > service.ServiceHealth.MaxErrorsNum {
- if probeInfo.Mode == model.OfflineFailureAction.String() {
- obj := &appmv1.RbdEndpoint{
- UUID: service.Name,
- IP: ip,
- Port: port,
- Sid: sid,
- }
- t.updateCh.In() <- discovery.Event{
- Type: discovery.DeleteEvent,
- Obj: obj,
- }
- } else {
- obj := &appmv1.RbdEndpoint{
- UUID: service.Name,
- IP: ip,
- Port: port,
- Sid: sid,
- }
- t.updateCh.In() <- discovery.Event{
- Type: discovery.UnhealthyEvent,
- Obj: obj,
+ switch event.Status {
+ case v1.StatHealthy:
+ obj := &appmv1.RbdEndpoint{
+ UUID: info.UUID,
+ IP: info.IP,
+ Port: int(info.Port),
+ Sid: info.Sid,
+ }
+ t.updateCh.In() <- discovery.Event{
+ Type: discovery.HealthEvent,
+ Obj: obj,
+ }
+ case v1.StatDeath, v1.StatUnhealthy:
+ if event.ErrorNumber > service.ServiceHealth.MaxErrorsNum {
+ if probeInfo.Mode == model.OfflineFailureAction.String() {
+ obj := &appmv1.RbdEndpoint{
+ UUID: info.UUID,
+ IP: info.IP,
+ Port: int(info.Port),
+ Sid: info.Sid,
+ }
+ t.updateCh.In() <- discovery.Event{
+ Type: discovery.DeleteEvent,
+ Obj: obj,
+ }
+ } else {
+ obj := &appmv1.RbdEndpoint{
+ UUID: info.UUID,
+ IP: info.IP,
+ Port: int(info.Port),
+ Sid: info.Sid,
+ }
+ t.updateCh.In() <- discovery.Event{
+ Type: discovery.UnhealthyEvent,
+ Obj: obj,
+ }
}
}
}
+ case <-t.ctx.Done():
+ // TODO: should stop for one service, not all services.
+ return
}
- case <-t.ctx.Done():
- return
}
- }
- }(service)
- // start
- t.utilprober.UpdateServicesProbe([]*v1.Service{service})
+ }(service, info)
+ }
+ t.utilprober.UpdateServicesProbe(services)
}
-func (t *tpProbe) StopProbe(ep *corev1.Endpoints) {
- name := t.createServiceNames(ep)
- logrus.Debugf("Name: %s; Stop probe.", name)
- t.utilprober.StopProbes([]string{name})
+func (t *tpProbe) StopProbe(uuids []string) {
+ for _, name := range uuids {
+ t.utilprober.StopProbes([]string{name})
+ }
}
// GetProbeInfo returns probe info associated with sid.
@@ -210,12 +203,11 @@ func (t *tpProbe) StopProbe(ep *corev1.Endpoints) {
// If there is no probe in the database, return a default probe
func (t *tpProbe) GetProbeInfo(sid string) (*model.TenantServiceProbe, error) {
probes, err := t.dbm.ServiceProbeDao().GetServiceProbes(sid)
- if err != nil || probes == nil || len(probes) == 0 || probes[0].IsUsed == 0 {
+ if err != nil || probes == nil || len(probes) == 0 || *(probes[0].IsUsed) == 0 {
if err != nil {
logrus.Warningf("ServiceID: %s; error getting probes: %v", sid, err)
}
// no defined probe, use default one
- logrus.Debugf("no defined probe, use default one")
return &model.TenantServiceProbe{
Scheme: "tcp",
PeriodSecond: 5,
@@ -226,31 +218,23 @@ func (t *tpProbe) GetProbeInfo(sid string) (*model.TenantServiceProbe, error) {
return probes[0], nil
}
-func (t *tpProbe) createServices(ep *corev1.Endpoints) (*v1.Service, *model.TenantServiceProbe, string) {
- sid := ep.GetLabels()["service_id"]
- ip := ep.GetLabels()["ip"]
- port := ep.GetLabels()["port"]
- if strings.TrimSpace(sid) == "" {
- logrus.Warningf("Endpoints key: %s; ServiceID not found, stop creating probe",
- fmt.Sprintf("%s/%s", ep.Namespace, ep.Name))
- return nil, nil, ""
- }
- probeInfo, err := t.GetProbeInfo(sid)
+func (t *tpProbe) createServices(probeInfo *store.ProbeInfo) (*v1.Service, *model.TenantServiceProbe) {
+ tsp, err := t.GetProbeInfo(probeInfo.Sid)
if err != nil {
logrus.Warningf("ServiceID: %s; Unexpected error occurred, ignore the creation of "+
- "probes: %s", sid, err.Error())
- return nil, nil, ""
+ "probes: %s", probeInfo.Sid, err.Error())
+ return nil, nil
}
- if probeInfo.Mode == "liveness" {
- probeInfo.Mode = model.IgnoreFailureAction.String()
+ if tsp.Mode == "liveness" {
+ tsp.Mode = model.IgnoreFailureAction.String()
}
- service := createService(probeInfo)
- service.Name = ep.GetLabels()["uuid"]
- portint, _ := strconv.Atoi(port)
- service.ServiceHealth.Port = portint
- service.ServiceHealth.Name = service.Name // TODO: no need?
- service.ServiceHealth.Address = fmt.Sprintf("%s:%s", ip, port)
- return service, probeInfo, sid
+ service := createService(tsp)
+ service.Sid = probeInfo.Sid
+ service.Name = probeInfo.UUID
+ service.ServiceHealth.Port = int(probeInfo.Port)
+ service.ServiceHealth.Name = service.Name
+ service.ServiceHealth.Address = fmt.Sprintf("%s:%d", probeInfo.IP, probeInfo.Port)
+ return service, tsp
}
func (t *tpProbe) createServiceNames(ep *corev1.Endpoints) string {
diff --git a/worker/appm/store/store.go b/worker/appm/store/store.go
index 5972e72b6..f3819dc2b 100644
--- a/worker/appm/store/store.go
+++ b/worker/appm/store/store.go
@@ -20,6 +20,7 @@ package store
import (
"context"
+ "encoding/json"
"fmt"
"sync"
"time"
@@ -78,7 +79,14 @@ const (
type Event struct {
Type EventType
Obj interface{}
- Old interface{}
+}
+
+// ProbeInfo holds the context of a probe.
+type ProbeInfo struct {
+ Sid string `json:"sid"`
+ UUID string `json:"uuid"`
+ IP string `json:"ip"`
+ Port int32 `json:"port"`
}
//appRuntimeStore app runtime store
@@ -154,21 +162,22 @@ func NewStore(clientset *kubernetes.Clientset,
epEventHandler := cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
ep := obj.(*corev1.Endpoints)
- logrus.Debugf("received add endpoints: %+v", ep)
serviceID := ep.Labels["service_id"]
version := ep.Labels["version"]
createrID := ep.Labels["creater_id"]
if serviceID != "" && createrID != "" {
appservice, err := store.getAppService(serviceID, version, createrID, true)
if err == conversion.ErrServiceNotFound {
- store.conf.KubeClient.CoreV1().Endpoints(ep.Namespace).Delete(ep.Name, &metav1.DeleteOptions{})
+ logrus.Debugf("ServiceID: %s; Action: AddFunc; service not found", serviceID)
}
if appservice != nil {
appservice.AddEndpoints(ep)
- if isThirdParty(ep) {
+ if isThirdParty(ep) && ep.Subsets != nil && len(ep.Subsets) > 0 {
+ logrus.Debugf("received add endpoints: %+v", ep)
+ probeInfos := listProbeInfos(ep, serviceID)
probeCh.In() <- Event{
Type: CreateEvent,
- Obj: obj,
+ Obj: probeInfos,
}
}
return
@@ -177,7 +186,6 @@ func NewStore(clientset *kubernetes.Clientset,
},
DeleteFunc: func(obj interface{}) {
ep := obj.(*corev1.Endpoints)
- logrus.Debugf("received delete endpoints: %+v", ep)
serviceID := ep.Labels["service_id"]
version := ep.Labels["version"]
createrID := ep.Labels["creater_id"]
@@ -186,12 +194,18 @@ func NewStore(clientset *kubernetes.Clientset,
if appservice != nil {
appservice.DelEndpoints(ep)
if appservice.IsClosed() {
+ logrus.Debugf("ServiceID: %s; Action: DeleteFunc;service is closed", serviceID)
store.DeleteAppService(appservice)
}
if isThirdParty(ep) {
+ logrus.Debugf("received delete endpoints: %+v", ep)
+ var uuids []string
+ for _, item := range ep.Subsets {
+ uuids = append(uuids, item.Ports[0].Name)
+ }
probeCh.In() <- Event{
Type: DeleteEvent,
- Obj: obj,
+ Obj: uuids,
}
}
}
@@ -206,20 +220,18 @@ func NewStore(clientset *kubernetes.Clientset,
if serviceID != "" && createrID != "" {
appservice, err := store.getAppService(serviceID, version, createrID, true)
if err == conversion.ErrServiceNotFound {
- logrus.Debug("ServiceID: error service not found")
- store.conf.KubeClient.CoreV1().Endpoints(cep.Namespace).Delete(cep.Name, &metav1.DeleteOptions{})
+ logrus.Debugf("ServiceID: %s; Action: UpdateFunc; service not found", serviceID)
}
if appservice != nil {
appservice.AddEndpoints(cep)
if isThirdParty(cep) {
+ curInfos := listProbeInfos(cep, serviceID)
probeCh.In() <- Event{
Type: UpdateEvent,
- Obj: cur,
- Old: old,
+ Obj: curInfos,
}
}
}
- //}
}
},
}
@@ -236,6 +248,67 @@ func NewStore(clientset *kubernetes.Clientset,
return store
}
+func listProbeInfos(ep *corev1.Endpoints, sid string) []*ProbeInfo {
+ var probeInfos []*ProbeInfo
+ for _, subset := range ep.Subsets {
+ uuid := subset.Ports[0].Name
+ port := subset.Ports[0].Port
+ for _, address := range subset.NotReadyAddresses {
+ info := &ProbeInfo{
+ Sid: sid,
+ UUID: uuid,
+ IP: address.IP,
+ Port: port,
+ }
+ probeInfos = append(probeInfos, info)
+ }
+ for _, address := range subset.Addresses {
+ info := &ProbeInfo{
+ Sid: sid,
+ UUID: uuid,
+ IP: address.IP,
+ Port: port,
+ }
+ probeInfos = append(probeInfos, info)
+ }
+ }
+ return probeInfos
+}
+
+func upgradeProbe(ch chan<- interface{}, old, cur []*ProbeInfo) {
+ ob, _ := json.Marshal(old)
+ cb, _ := json.Marshal(cur)
+ logrus.Debugf("Old probe infos: %s", string(ob))
+ logrus.Debugf("Current probe infos: %s", string(cb))
+ oldMap := make(map[string]*ProbeInfo, len(old))
+ for i := 0; i < len(old); i++ {
+ oldMap[old[i].UUID] = old[i]
+ }
+ for _, c := range cur {
+ if info := oldMap[c.UUID]; info != nil {
+ delete(oldMap, c.UUID)
+ logrus.Debugf("UUID: %s; update probe", c.UUID)
+ ch <- Event{
+ Type: UpdateEvent,
+ Obj: c,
+ }
+ } else {
+ logrus.Debugf("UUID: %s; create probe", c.UUID)
+ ch <- Event{
+ Type: CreateEvent,
+ Obj: []*ProbeInfo{c},
+ }
+ }
+ }
+ for _, info := range oldMap {
+ logrus.Debugf("UUID: %s; delete probe", info.UUID)
+ ch <- Event{
+ Type: DeleteEvent,
+ Obj: info,
+ }
+ }
+}
+
func (a *appRuntimeStore) init() error {
//init leader namespace
leaderNamespace := a.conf.LeaderElectionNamespace
diff --git a/worker/appm/thirdparty/discovery/discovery.go b/worker/appm/thirdparty/discovery/discovery.go
index 2c9a93604..f9988450b 100644
--- a/worker/appm/thirdparty/discovery/discovery.go
+++ b/worker/appm/thirdparty/discovery/discovery.go
@@ -35,9 +35,11 @@ const (
// UpdateEvent event associated with an object update in a service discovery center
UpdateEvent EventType = "UPDATE"
// DeleteEvent event associated when an object is removed from a service discovery center
- DeleteEvent EventType = "DELETE"
+ DeleteEvent EventType = "DELETE"
+ // UnhealthyEvent -
UnhealthyEvent EventType = "UNHEALTHY"
- HealthEvent EventType = "HEALTH"
+ // HealthEvent -
+ HealthEvent EventType = "HEALTH"
)
// Event holds the context of an event.
diff --git a/worker/appm/thirdparty/thirdparty.go b/worker/appm/thirdparty/thirdparty.go
index 4bf1a646d..5c632d543 100644
--- a/worker/appm/thirdparty/thirdparty.go
+++ b/worker/appm/thirdparty/thirdparty.go
@@ -21,19 +21,18 @@ package thirdparty
import (
"encoding/json"
"fmt"
- "github.com/goodrain/rainbond/worker/util"
- "strconv"
+ "sync"
"github.com/Sirupsen/logrus"
"github.com/eapache/channels"
"github.com/goodrain/rainbond/db"
"github.com/goodrain/rainbond/db/model"
+ "github.com/goodrain/rainbond/worker/appm/f"
"github.com/goodrain/rainbond/worker/appm/store"
"github.com/goodrain/rainbond/worker/appm/thirdparty/discovery"
"github.com/goodrain/rainbond/worker/appm/types/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
- k8sErrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)
@@ -63,7 +62,7 @@ func NewThirdPartier(clientset *kubernetes.Clientset,
}
type thirdparty struct {
- clientset kubernetes.Interface
+ clientset *kubernetes.Clientset
store store.Storer
// a collection of stop channel for every service.
@@ -87,13 +86,14 @@ func (t *thirdparty) Start() {
}
logrus.Debugf("Received event: %+v", evt)
if evt.Type == v1.StartEvent { // no need to distinguish between event types
+ needWatch := false
stopCh := t.svcStopCh[evt.Sid]
- if stopCh != nil {
+ if stopCh == nil {
logrus.Debugf("ServiceID: %s; already started.", evt.Sid)
- continue
+ needWatch = true
+ t.svcStopCh[evt.Sid] = make(chan struct{})
}
- t.svcStopCh[evt.Sid] = make(chan struct{})
- go t.runStart(evt.Sid)
+ go t.runStart(evt.Sid, needWatch)
}
if evt.Type == v1.StopEvent {
stopCh := t.svcStopCh[evt.Sid]
@@ -114,7 +114,7 @@ func (t *thirdparty) Start() {
go t.runUpdate(devent)
case <-t.stopCh:
for _, stopCh := range t.svcStopCh {
- close(stopCh)
+ close(stopCh) // TODO: close of closed channel
}
break
}
@@ -122,38 +122,33 @@ func (t *thirdparty) Start() {
}()
}
-func (t *thirdparty) runStart(sid string) {
- logrus.Debugf("ServiceID: %s; run start...", sid)
+func (t *thirdparty) runStart(sid string, needWatch bool) {
as := t.store.GetAppService(sid)
- // TODO: when an error occurs, consider retrying.
- rbdeps, d := t.ListRbdEndpoints(sid)
- b, _ := json.Marshal(rbdeps)
- logrus.Debugf("ServiceID: %s; rbd endpoints: %+v", sid, string(b))
- // TODO: empty rbdeps
- if rbdeps == nil || len(rbdeps) == 0 {
- logrus.Warningf("ServiceID: %s;Empty rbd endpoints, stop starting third-party service.", sid)
+ var err error
+ for i := 3; i > 0; i-- { // retry 3 times
+ rbdeps, ir := t.ListRbdEndpoints(sid)
+ if rbdeps == nil || len(rbdeps) == 0 {
+ logrus.Warningf("ServiceID: %s;Empty rbd endpoints, stop starting third-party service.", sid)
+ continue
+ }
+
+ var eps []*corev1.Endpoints
+ eps, err = t.k8sEndpoints(as, rbdeps)
+ if err != nil {
+ logrus.Warningf("ServiceID: %s; error creating k8s endpoints: %s", sid, err.Error())
+ continue
+ }
+ for _, ep := range eps {
+ f.EnsureEndpoints(ep, t.clientset)
+ }
+
+ if needWatch && ir != nil {
+ ir.Watch()
+ }
+ logrus.Infof("ServiceID: %s; successfully running start task", sid)
return
}
-
- eps, err := t.createK8sEndpoints(as, rbdeps)
- if err != nil {
- logrus.Errorf("ServiceID: %s; error creating k8s endpoints: %s", sid, err.Error())
- return
- }
- // find out old endpoints, and delete it.
- old := as.GetEndpoints()
- // TODO: can do better
- del := findDeletedEndpoints(old, eps)
- for _, ep := range del {
- deleteEndpoints(ep, t.clientset)
- }
- for _, ep := range eps {
- ensureEndpoints(ep, t.clientset)
- }
-
- if d != nil {
- d.Watch()
- }
+ logrus.Errorf("ServiceID: %s; error running start task: %v", sid, err)
}
// ListRbdEndpoints lists all rbd endpoints, include static and dynamic.
@@ -181,28 +176,20 @@ func (t *thirdparty) ListRbdEndpoints(sid string) ([]*v1.RbdEndpoint, Interacter
return res, d
}
-func findDeletedEndpoints(old, new []*corev1.Endpoints) []*corev1.Endpoints {
- if old == nil {
- logrus.Debugf("empty old endpoints.")
- return nil
- }
- var res []*corev1.Endpoints
- for _, o := range old {
- del := true
- for _, n := range new {
- if o.Name == n.Name {
- del = false
- break
+func deleteSubset(as *v1.AppService, rbdep *v1.RbdEndpoint) {
+ eps := as.GetEndpoints()
+ for _, ep := range eps {
+ for idx, item := range ep.Subsets {
+ if item.Ports[0].Name == rbdep.UUID {
+ logrus.Debugf("UUID: %s; subset deleted", rbdep.UUID)
+ ep.Subsets[idx] = ep.Subsets[len(ep.Subsets)-1]
+ ep.Subsets = ep.Subsets[:len(ep.Subsets)-1]
}
}
- if del {
- res = append(res, o)
- }
}
- return res
}
-func (t *thirdparty) createK8sEndpoints(as *v1.AppService, epinfo []*v1.RbdEndpoint) ([]*corev1.Endpoints, error) {
+func (t *thirdparty) k8sEndpoints(as *v1.AppService, epinfo []*v1.RbdEndpoint) ([]*corev1.Endpoints, error) {
ports, err := db.GetManager().TenantServicesPortDao().GetPortsByServiceID(as.ServiceID)
if err != nil {
return nil, err
@@ -213,258 +200,201 @@ func (t *thirdparty) createK8sEndpoints(as *v1.AppService, epinfo []*v1.RbdEndpo
}
p := ports[0]
- logrus.Debugf("create outer third-party service")
- f := func() []*corev1.Endpoints {
- var eps []*corev1.Endpoints
- for _, epi := range epinfo {
- port, realport := func(targetPort int, realPort int) (int32, bool) { // final port
- if realPort == 0 {
- return int32(targetPort), false
- }
- return int32(realPort), true
- }(p.ContainerPort, epi.Port)
- ep := corev1.Endpoints{}
- ep.Namespace = as.TenantID
- if p.IsInnerService {
- ep.Name = util.CreateEndpointsName(as.TenantName, as.ServiceAlias, epi.UUID)
- ep.Name = epi.UUID
- ep.Labels = as.GetCommonLabels(map[string]string{
- "name": as.ServiceAlias + "Service",
- "service-kind": model.ServiceKindThirdParty.String(),
- })
- }
- if p.IsOuterService {
- ep.Name = util.CreateEndpointsName(as.TenantName, as.ServiceAlias, epi.UUID) + "out"
- ep.Labels = as.GetCommonLabels(map[string]string{
- "name": as.ServiceAlias + "ServiceOUT",
- "service-kind": model.ServiceKindThirdParty.String(),
- })
- }
- ep.Labels["uuid"] = epi.UUID
- ep.Labels["ip"] = epi.IP
- ep.Labels["port"] = strconv.Itoa(int(port))
- ep.Labels["real-port"] = strconv.FormatBool(realport)
- subset := corev1.EndpointSubset{
- Ports: []corev1.EndpointPort{
- {
- Port: port,
- },
- },
- Addresses: []corev1.EndpointAddress{
- {
- IP: epi.IP,
- },
- },
- }
- ep.Subsets = append(ep.Subsets, subset)
- eps = append(eps, &ep)
- }
- return eps
- }
-
var res []*corev1.Endpoints
if p.IsInnerService {
- res = append(res, f()...)
+ ep := &corev1.Endpoints{}
+ ep.Namespace = as.TenantID
+ // inner or outer
+ if p.IsInnerService {
+ ep.Name = fmt.Sprintf("service-%d-%d", p.ID, p.ContainerPort)
+ ep.Labels = as.GetCommonLabels(map[string]string{
+ "name": as.ServiceAlias + "Service",
+ "service-kind": model.ServiceKindThirdParty.String(),
+ })
+ }
+ res = append(res, ep)
}
if p.IsOuterService {
- res = append(res, f()...)
+ ep := &corev1.Endpoints{}
+ ep.Namespace = as.TenantID
+ // inner or outer
+ if p.IsOuterService {
+ ep.Name = fmt.Sprintf("service-%d-%dout", p.ID, p.ContainerPort)
+ ep.Labels = as.GetCommonLabels(map[string]string{
+ "name": as.ServiceAlias + "ServiceOUT",
+ "service-kind": model.ServiceKindThirdParty.String(),
+ })
+ }
+ res = append(res, ep)
+ }
+
+ var subsets []corev1.EndpointSubset
+ for _, epi := range epinfo {
+ subset := corev1.EndpointSubset{
+ Ports: []corev1.EndpointPort{
+ {
+ Name: epi.UUID,
+ Port: func(targetPort int, realPort int) int32 {
+ if realPort == 0 {
+ return int32(targetPort)
+ }
+ return int32(realPort)
+ }(p.ContainerPort, epi.Port),
+ Protocol: corev1.ProtocolTCP,
+ },
+ },
+ Addresses: []corev1.EndpointAddress{
+ {
+ IP: epi.IP,
+ },
+ },
+ }
+ subsets = append(subsets, subset)
+ }
+ for _, item := range res {
+ item.Subsets = subsets
}
return res, nil
}
-func deleteEndpoints(ep *corev1.Endpoints, clientset kubernetes.Interface) {
- err := clientset.CoreV1().Endpoints(ep.Namespace).Delete(ep.Name, &metav1.DeleteOptions{})
+func updateSubset(as *v1.AppService, rbdep *v1.RbdEndpoint) error {
+ ports, err := db.GetManager().TenantServicesPortDao().GetPortsByServiceID(as.ServiceID)
if err != nil {
- logrus.Debugf("Ignore; error deleting endpoints%+v: %v", ep, err)
+ return err
}
-}
-
-func ensureEndpoints(ep *corev1.Endpoints, clientSet kubernetes.Interface) {
- logrus.Debugf("ensure endpoints: %+v", ep)
- _, err := clientSet.CoreV1().Endpoints(ep.Namespace).Update(ep)
-
- if err != nil {
- if k8sErrors.IsNotFound(err) {
- _, err := clientSet.CoreV1().Endpoints(ep.Namespace).Create(ep)
- if err != nil {
- logrus.Warningf("error creating endpoints %+v: %v", ep, err)
+ // third-party service can only have one port
+ if ports == nil || len(ports) == 0 {
+ return fmt.Errorf("Port not found")
+ }
+ p := ports[0]
+ subset := corev1.EndpointSubset{
+ Ports: []corev1.EndpointPort{
+ {
+ Name: rbdep.UUID,
+ Port: func(targetPort int, realPort int) int32 {
+ if realPort == 0 {
+ return int32(targetPort)
+ }
+ return int32(realPort)
+ }(p.ContainerPort, rbdep.Port),
+ Protocol: corev1.ProtocolTCP,
+ },
+ },
+ Addresses: []corev1.EndpointAddress{
+ {
+ IP: rbdep.IP,
+ },
+ },
+ }
+ for _, ep := range as.GetEndpoints() {
+ exist := false
+ for idx, item := range ep.Subsets {
+ if item.Ports[0].Name == subset.Ports[0].Name {
+ ep.Subsets[idx] = item
+ exist = true
+ break
}
- return
}
- logrus.Warningf("error updating endpoints %+v: %v", ep, err)
- }
-}
-
-func ensureConfigMap(cm *corev1.ConfigMap, clientSet kubernetes.Interface) {
- _, err := clientSet.CoreV1().ConfigMaps(cm.Namespace).Update(cm)
-
- if err != nil {
- if k8sErrors.IsNotFound(err) {
- _, err := clientSet.CoreV1().ConfigMaps(cm.Namespace).Create(cm)
- if err != nil {
- logrus.Warningf("error creating ConfigMaps %+v: %v", cm, err)
- }
- return
+ if !exist {
+ ep.Subsets = append(ep.Subsets, subset)
}
- logrus.Warningf("error updating ConfigMaps %+v: %v", cm, err)
}
+ return nil
}
func (t *thirdparty) runUpdate(event discovery.Event) {
- ep := event.Obj.(*v1.RbdEndpoint)
- as := t.store.GetAppService(ep.Sid)
- switch event.Type {
- case discovery.CreateEvent:
- b, _ := json.Marshal(ep)
- logrus.Debugf("Run update; Event received: Type: %v; Body: %s", event.Type, string(b))
- endpoints, err := t.createK8sEndpoints(as, []*v1.RbdEndpoint{ep})
- if err != nil {
- logrus.Warningf("ServiceID: %s; error creating k8s endpoints struct: %s",
- ep.Sid, err.Error())
- return
- }
- for _, ep := range endpoints {
- ensureEndpoints(ep, t.clientset)
- }
- case discovery.UpdateEvent:
- b, _ := json.Marshal(ep)
- logrus.Debugf("Run update; Event received: Type: %v; Body: %s", event.Type, string(b))
- // TODO: Compare old and new endpoints
- // TODO: delete old endpoints
- if !ep.IsOnline {
- eps := ListOldEndpoints(as, ep)
- for _, item := range eps {
- deleteEndpoints(item, t.clientset)
+ fc := func(as *v1.AppService, rbdep *v1.RbdEndpoint, ready bool, msg string, condition func(subset corev1.EndpointSubset) bool) {
+ var wait sync.WaitGroup
+ go func() {
+ wait.Add(1)
+ defer wait.Done()
+ for _, ep := range as.GetEndpoints() {
+ for idx, subset := range ep.Subsets {
+ if subset.Ports[0].Name == rbdep.UUID && condition(subset) {
+ logrus.Debugf("Executed; health: %v; msg: %s", ready, msg)
+ ep.Subsets[idx] = createSubset(rbdep, ready)
+ f.UpdateEndpoints(ep, t.clientset)
+ }
+ }
}
- return
- }
- endpoints, err := t.createK8sEndpoints(as, []*v1.RbdEndpoint{ep})
+ }()
+ wait.Wait()
+ }
+
+ rbdep := event.Obj.(*v1.RbdEndpoint)
+ as := t.store.GetAppService(rbdep.Sid)
+ b, _ := json.Marshal(rbdep)
+ msg := fmt.Sprintf("Run update; Event received: Type: %v; Body: %s", event.Type, string(b))
+ switch event.Type {
+ case discovery.CreateEvent, discovery.UpdateEvent:
+ logrus.Debug(msg)
+ err := updateSubset(as, rbdep)
if err != nil {
- logrus.Warningf("ServiceID: %s; error creating k8s endpoints struct: %s",
- ep.Sid, err.Error())
+ logrus.Warningf("ServiceID: %s; error adding subset: %s",
+ rbdep.Sid, err.Error())
return
}
- for _, ep := range endpoints {
- ensureEndpoints(ep, t.clientset)
- }
+ _ = f.UpgradeEndpoints(t.clientset, as, as.GetEndpoints(), as.GetEndpoints(),
+ func(msg string, err error) error {
+ logrus.Warning(msg)
+ return nil
+ })
case discovery.DeleteEvent:
- b, _ := json.Marshal(ep)
- logrus.Debugf("Run update; Event received: Type: %v; Body: %s", event.Type, string(b))
- eps := ListOldEndpoints(as, ep)
- for _, item := range eps {
- deleteEndpoints(item, t.clientset)
- }
+ logrus.Debug(msg)
+ deleteSubset(as, rbdep)
+ eps := as.GetEndpoints()
+ _ = f.UpgradeEndpoints(t.clientset, as, as.GetEndpoints(), eps,
+ func(msg string, err error) error {
+ logrus.Warning(msg)
+ return nil
+ })
case discovery.HealthEvent:
- subset := createSubset(ep, false)
- eps := ListOldEndpoints(as, ep)
- for _, ep := range eps {
- if !isHealth(ep) {
- ep.Subsets = []corev1.EndpointSubset{
- subset,
- }
- ensureEndpoints(ep, t.clientset)
- }
+ isUnhealthy := func(subset corev1.EndpointSubset) bool {
+ return !isHealthy(subset)
}
+ fc(as, rbdep, true, msg, isUnhealthy)
case discovery.UnhealthyEvent:
- subset := createSubset(ep, true)
- eps := ListOldEndpoints(as, ep)
- for _, ep := range eps {
- if isHealth(ep) {
- ep.Subsets = []corev1.EndpointSubset{
- subset,
- }
- ensureEndpoints(ep, t.clientset)
- }
- }
+ fc(as, rbdep, false, msg, isHealthy)
}
}
func (t *thirdparty) runDelete(sid string) {
as := t.store.GetAppService(sid) // TODO: need to delete?
-
- if services := as.GetServices(); services != nil {
- for _, service := range services {
- err := t.clientset.CoreV1().Services(as.TenantID).Delete(service.Name, &metav1.DeleteOptions{})
- if err != nil && !errors.IsNotFound(err) {
- logrus.Warningf("error deleting service: %v", err)
- }
- }
- }
- if secrets := as.GetSecrets(); secrets != nil {
- for _, secret := range secrets {
- if secret != nil {
- err := t.clientset.CoreV1().Secrets(as.TenantID).Delete(secret.Name, &metav1.DeleteOptions{})
- if err != nil && !errors.IsNotFound(err) {
- logrus.Warningf("error deleting secrets: %v", err)
- }
- t.store.OnDelete(secret)
- }
- }
- }
- if ingresses := as.GetIngress(); ingresses != nil {
- for _, ingress := range ingresses {
- err := t.clientset.ExtensionsV1beta1().Ingresses(as.TenantID).Delete(ingress.Name, &metav1.DeleteOptions{})
- if err != nil && !errors.IsNotFound(err) {
- logrus.Warningf("error deleting ingress: %v", err)
- }
- t.store.OnDelete(ingress)
- }
- }
- if configs := as.GetConfigMaps(); configs != nil {
- for _, config := range configs {
- err := t.clientset.CoreV1().ConfigMaps(as.TenantID).Delete(config.Name, &metav1.DeleteOptions{})
- if err != nil && !errors.IsNotFound(err) {
- logrus.Warningf("error deleting config map: %v", err)
- }
- t.store.OnDelete(config)
- }
- }
if eps := as.GetEndpoints(); eps != nil {
for _, ep := range eps {
logrus.Debugf("Endpoints delete: %+v", ep)
err := t.clientset.CoreV1().Endpoints(as.TenantID).Delete(ep.Name, &metav1.DeleteOptions{})
if err != nil && !errors.IsNotFound(err) {
- logrus.Warningf("error deleting endpoin empty old app servicets: %v", err)
+ logrus.Warningf("error deleting endpoint empty old app endpoints: %v", err)
}
t.store.OnDelete(ep)
}
}
}
-func ListOldEndpoints(as *v1.AppService, ep *v1.RbdEndpoint) []*corev1.Endpoints {
- var res []*corev1.Endpoints
- for _, item := range as.GetEndpoints() {
- if item.GetLabels()["uuid"] == ep.UUID {
- res = append(res, item)
- }
- }
- return res
-}
-
-func createSubset(ep *v1.RbdEndpoint, notReady bool) corev1.EndpointSubset {
+func createSubset(ep *v1.RbdEndpoint, ready bool) corev1.EndpointSubset {
address := corev1.EndpointAddress{
IP: ep.IP,
}
port := corev1.EndpointPort{
- Port: int32(ep.Port),
+ Name: ep.UUID,
+ Port: int32(ep.Port),
+ Protocol: corev1.ProtocolTCP,
}
subset := corev1.EndpointSubset{}
- if notReady {
- subset.NotReadyAddresses = append(subset.Addresses, address)
- } else {
+ if ready {
subset.Addresses = append(subset.Addresses, address)
+ } else {
+ subset.NotReadyAddresses = append(subset.NotReadyAddresses, address)
}
subset.Ports = append(subset.Ports, port)
return subset
}
-func isHealth(ep *corev1.Endpoints) bool {
- if ep.Subsets == nil || len(ep.Subsets) == 0 {
- return false
- }
- if ep.Subsets[0].Addresses != nil && len(ep.Subsets[0].Addresses) > 0 {
+func isHealthy(subset corev1.EndpointSubset) bool {
+ if subset.Addresses != nil && len(subset.Addresses) > 0 {
return true
}
return false
diff --git a/worker/appm/types/v1/v1.go b/worker/appm/types/v1/v1.go
index a41df16b3..c0d23d0a7 100644
--- a/worker/appm/types/v1/v1.go
+++ b/worker/appm/types/v1/v1.go
@@ -23,6 +23,8 @@ import (
"os"
"strconv"
+ "github.com/goodrain/rainbond/builder"
+
"github.com/Sirupsen/logrus"
"github.com/goodrain/rainbond/db/model"
"github.com/goodrain/rainbond/event"
@@ -104,7 +106,6 @@ type AppService struct {
services []*corev1.Service
delServices []*corev1.Service
endpoints []*corev1.Endpoints
- delEndpoints []*corev1.Endpoints
configMaps []*corev1.ConfigMap
ingresses []*extensions.Ingress
delIngs []*extensions.Ingress // ingresses which need to be deleted
@@ -317,11 +318,6 @@ func (a *AppService) GetEndpointsByName(name string) *corev1.Endpoints {
return nil
}
-// GetDelEndpoints returns endpoints that need to be deleted in AppService
-func (a *AppService) GetDelEndpoints() []*corev1.Endpoints {
- return a.delEndpoints
-}
-
//DelEndpoints deletes *corev1.Endpoints
func (a *AppService) DelEndpoints(ep *corev1.Endpoints) {
for i, c := range a.endpoints {
@@ -576,7 +572,7 @@ func GetTCPMeshImageName() string {
if d := os.Getenv("TCPMESH_DEFAULT_IMAGE_NAME"); d != "" {
return d
}
- return "goodrain.me/mesh_plugin"
+ return builder.REGISTRYDOMAIN + "/mesh_plugin"
}
//GetProbeMeshImageName get probe init mesh image name
@@ -584,5 +580,5 @@ func GetProbeMeshImageName() string {
if d := os.Getenv("PROBE_MESH_IMAGE_NAME"); d != "" {
return d
}
- return "goodrain.me/rbd-init-probe"
+ return builder.REGISTRYDOMAIN + "/rbd-init-probe"
}
diff --git a/worker/master/volumes/provider/lib/controller/controller.go b/worker/master/volumes/provider/lib/controller/controller.go
index 9584ede05..50dadea5b 100644
--- a/worker/master/volumes/provider/lib/controller/controller.go
+++ b/worker/master/volumes/provider/lib/controller/controller.go
@@ -615,7 +615,8 @@ func (ctrl *ProvisionController) processNextClaimWorkItem() bool {
if err := ctrl.syncClaimHandler(key); err != nil {
if ctrl.claimQueue.NumRequeues(obj) < ctrl.failedProvisionThreshold {
- logrus.Warningf("Retrying syncing claim %q because failures %v < threshold %v", key, ctrl.claimQueue.NumRequeues(obj), ctrl.failedProvisionThreshold)
+ logrus.Warningf("Retrying syncing claim %q because failures %v < threshold %v",
+ key, ctrl.claimQueue.NumRequeues(obj), ctrl.failedProvisionThreshold)
ctrl.claimQueue.AddRateLimited(obj)
} else {
logrus.Errorf("Giving up syncing claim %q because failures %v >= threshold %v", key, ctrl.claimQueue.NumRequeues(obj), ctrl.failedProvisionThreshold)
diff --git a/worker/server/pb/app_runtime_server.pb.go b/worker/server/pb/app_runtime_server.pb.go
index bd6f875c4..788d45ad9 100644
--- a/worker/server/pb/app_runtime_server.pb.go
+++ b/worker/server/pb/app_runtime_server.pb.go
@@ -427,10 +427,11 @@ type DeployInfo struct {
Deployment string `protobuf:"bytes,3,opt,name=deployment,proto3" json:"deployment,omitempty"`
Pods map[string]string `protobuf:"bytes,4,rep,name=pods,proto3" json:"pods,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Services map[string]string `protobuf:"bytes,5,rep,name=services,proto3" json:"services,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
- Secrets map[string]string `protobuf:"bytes,6,rep,name=secrets,proto3" json:"secrets,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
- Ingresses map[string]string `protobuf:"bytes,7,rep,name=ingresses,proto3" json:"ingresses,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
- Replicatset map[string]string `protobuf:"bytes,8,rep,name=replicatset,proto3" json:"replicatset,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
- Status string `protobuf:"bytes,9,opt,name=status,proto3" json:"status,omitempty"`
+ Endpoints map[string]string `protobuf:"bytes,6,rep,name=endpoints,proto3" json:"endpoints,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ Secrets map[string]string `protobuf:"bytes,7,rep,name=secrets,proto3" json:"secrets,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ Ingresses map[string]string `protobuf:"bytes,8,rep,name=ingresses,proto3" json:"ingresses,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ Replicatset map[string]string `protobuf:"bytes,9,rep,name=replicatset,proto3" json:"replicatset,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ Status string `protobuf:"bytes,10,opt,name=status,proto3" json:"status,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -496,6 +497,13 @@ func (m *DeployInfo) GetServices() map[string]string {
return nil
}
+func (m *DeployInfo) GetEndpoints() map[string]string {
+ if m != nil {
+ return m.Endpoints
+ }
+ return nil
+}
+
func (m *DeployInfo) GetSecrets() map[string]string {
if m != nil {
return m.Secrets
@@ -916,6 +924,7 @@ func init() {
proto.RegisterMapType((map[string]*Container)(nil), "pb.ServiceAppPod.ContainersEntry")
proto.RegisterType((*Container)(nil), "pb.Container")
proto.RegisterType((*DeployInfo)(nil), "pb.DeployInfo")
+ proto.RegisterMapType((map[string]string)(nil), "pb.DeployInfo.EndpointsEntry")
proto.RegisterMapType((map[string]string)(nil), "pb.DeployInfo.IngressesEntry")
proto.RegisterMapType((map[string]string)(nil), "pb.DeployInfo.PodsEntry")
proto.RegisterMapType((map[string]string)(nil), "pb.DeployInfo.ReplicatsetEntry")
@@ -932,72 +941,73 @@ func init() {
func init() { proto.RegisterFile("app_runtime_server.proto", fileDescriptor_f94cf1a886c479d6) }
var fileDescriptor_f94cf1a886c479d6 = []byte{
- // 1026 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x56, 0xdb, 0x6e, 0xdb, 0x46,
- 0x10, 0xd5, 0xdd, 0xd2, 0xc8, 0x92, 0xe3, 0x49, 0x9d, 0xd0, 0x4a, 0xdc, 0x24, 0x2c, 0x52, 0xf8,
- 0x21, 0x50, 0x0b, 0x17, 0x46, 0x1d, 0x27, 0x68, 0x21, 0xc4, 0x86, 0x2b, 0xc0, 0x4d, 0x0d, 0xda,
- 0x79, 0x16, 0x68, 0x72, 0xe3, 0x6e, 0x2d, 0x2e, 0xb7, 0xdc, 0xa5, 0x01, 0x3e, 0xb6, 0xbf, 0x90,
- 0x1f, 0xea, 0x17, 0xf4, 0xad, 0xff, 0x53, 0xec, 0x85, 0x14, 0x75, 0x09, 0x5c, 0xb7, 0x05, 0xf2,
- 0xb6, 0x3c, 0x3b, 0x67, 0x66, 0xe7, 0x0c, 0x67, 0x76, 0xc1, 0xf1, 0x39, 0x9f, 0x24, 0x29, 0x93,
- 0x34, 0x22, 0x13, 0x41, 0x92, 0x1b, 0x92, 0x0c, 0x79, 0x12, 0xcb, 0x18, 0x6b, 0xfc, 0xd2, 0x5d,
- 0x83, 0xe6, 0x71, 0xc4, 0x65, 0xe6, 0x7e, 0x05, 0xfd, 0x73, 0x92, 0xdc, 0xd0, 0x80, 0x78, 0xe4,
- 0xd7, 0x94, 0x08, 0x89, 0x3b, 0x00, 0xc2, 0x20, 0x13, 0x1a, 0x3a, 0xd5, 0xa7, 0xd5, 0xdd, 0x8e,
- 0xd7, 0xb1, 0xc8, 0x38, 0x74, 0xf7, 0x60, 0xc3, 0x12, 0x44, 0xce, 0x78, 0x02, 0xdd, 0x19, 0x43,
- 0x58, 0x0a, 0x14, 0x14, 0xe1, 0xbe, 0x80, 0xde, 0x05, 0x61, 0x3e, 0x93, 0x39, 0xe3, 0x11, 0x74,
- 0xa4, 0x06, 0x66, 0x21, 0xda, 0x06, 0x18, 0x87, 0xee, 0x6f, 0x55, 0xe8, 0x9d, 0x4b, 0x5f, 0xa6,
- 0xe2, 0x47, 0x22, 0x84, 0x7f, 0x45, 0x70, 0x1f, 0x5a, 0x42, 0x03, 0x4e, 0xf5, 0x69, 0x7d, 0xb7,
- 0xbb, 0xb7, 0x33, 0xe4, 0x97, 0xc3, 0x39, 0x13, 0xfb, 0x75, 0xcc, 0x64, 0x92, 0x79, 0xd6, 0x78,
- 0xf0, 0x12, 0xba, 0x25, 0x18, 0xef, 0x41, 0xfd, 0x9a, 0x64, 0x36, 0x9c, 0x5a, 0xe2, 0x67, 0xd0,
- 0xbc, 0xf1, 0xa7, 0x29, 0x71, 0x6a, 0x1a, 0x33, 0x1f, 0x87, 0xb5, 0x83, 0xaa, 0x9b, 0x41, 0xf7,
- 0x88, 0x8a, 0xeb, 0xfc, 0x00, 0x5f, 0x43, 0x33, 0xa4, 0xe2, 0x3a, 0x8f, 0x3f, 0x50, 0xf1, 0x4b,
- 0xfb, 0x7a, 0x6d, 0x83, 0x1b, 0xc3, 0xc1, 0x01, 0xc0, 0x0c, 0xbc, 0x2d, 0x74, 0xb5, 0x1c, 0xfa,
- 0x10, 0x36, 0xad, 0xc0, 0x23, 0xce, 0xcf, 0xe2, 0xf0, 0x94, 0x0a, 0x89, 0xcf, 0xa1, 0xc1, 0xe3,
- 0x30, 0x8f, 0xbf, 0xa9, 0xf3, 0x2f, 0x1b, 0x79, 0x7a, 0xdb, 0xfd, 0xb3, 0x06, 0xbd, 0x39, 0xfc,
- 0x96, 0x6a, 0xaa, 0x42, 0x84, 0x84, 0x4f, 0xe3, 0x4c, 0xed, 0x1a, 0x15, 0xda, 0x06, 0x18, 0x87,
- 0xaa, 0xae, 0x76, 0x53, 0x66, 0x9c, 0x38, 0x75, 0x53, 0x57, 0x03, 0x5d, 0x64, 0x9c, 0xe0, 0x36,
- 0xb4, 0x79, 0x1c, 0x4e, 0x98, 0x1f, 0x11, 0xa7, 0xa1, 0x77, 0xd7, 0x78, 0x1c, 0xbe, 0xf5, 0x23,
- 0x82, 0x5b, 0xd0, 0x52, 0x5b, 0x94, 0x3b, 0x4d, 0xa3, 0x2d, 0x8f, 0xc3, 0x31, 0x57, 0xc7, 0x51,
- 0xb0, 0xad, 0x66, 0xcb, 0x1c, 0x87, 0xc7, 0xa1, 0xa9, 0x13, 0x8e, 0x00, 0x82, 0x98, 0x49, 0x9f,
- 0x32, 0x92, 0x08, 0x67, 0x4d, 0x27, 0xfb, 0x6c, 0x29, 0xd9, 0xe1, 0x9b, 0xc2, 0xc6, 0x68, 0x5e,
- 0x22, 0x0d, 0x4e, 0x61, 0x63, 0x61, 0x7b, 0x85, 0xfa, 0x5f, 0x94, 0xd5, 0xef, 0xee, 0xf5, 0x54,
- 0x88, 0x82, 0x55, 0x2e, 0xc6, 0x3b, 0xe8, 0x14, 0x38, 0x3e, 0x87, 0x7e, 0x11, 0xc8, 0x24, 0x6d,
- 0x5c, 0xf6, 0x0a, 0x54, 0xa7, 0xfe, 0x0c, 0xd6, 0x23, 0x12, 0xc5, 0x49, 0x36, 0x99, 0xd2, 0x88,
- 0x4a, 0x1d, 0xa3, 0xee, 0x75, 0x0d, 0x76, 0xaa, 0x20, 0xf7, 0xaf, 0x26, 0xc0, 0x91, 0x91, 0x99,
- 0xbd, 0x8f, 0xf1, 0x31, 0x74, 0x94, 0x3b, 0xc1, 0xfd, 0x20, 0xf7, 0x39, 0x03, 0xd0, 0x85, 0x75,
- 0xa5, 0x17, 0x79, 0x9f, 0x4e, 0x89, 0x20, 0xd2, 0x96, 0x69, 0x0e, 0xc3, 0xcf, 0xc1, 0xd6, 0x25,
- 0x22, 0x4c, 0xce, 0x57, 0x4a, 0x21, 0xf8, 0xc2, 0xfe, 0x3f, 0x0d, 0x2d, 0xa9, 0xa3, 0xff, 0xdf,
- 0x22, 0xfe, 0xf0, 0x2c, 0x0e, 0xad, 0x92, 0xda, 0x0a, 0x0f, 0xa0, 0x6d, 0x7f, 0x11, 0xe1, 0x34,
- 0x35, 0xe3, 0xf1, 0x02, 0x23, 0x1f, 0x01, 0x86, 0x55, 0x58, 0xe3, 0x3e, 0xac, 0x09, 0x12, 0x24,
- 0x44, 0xaa, 0xe2, 0x2a, 0xe2, 0xa3, 0x25, 0xa2, 0xde, 0x35, 0xbc, 0xdc, 0x16, 0x5f, 0x41, 0x87,
- 0xb2, 0xab, 0x84, 0x08, 0x41, 0xf2, 0xb2, 0xef, 0x2c, 0x10, 0xc7, 0xf9, 0xbe, 0xa1, 0xce, 0xec,
- 0x71, 0x04, 0xdd, 0x84, 0xf0, 0x29, 0x0d, 0x7c, 0xa9, 0xe4, 0x69, 0x6b, 0xfa, 0x93, 0x05, 0xba,
- 0x37, 0xb3, 0x30, 0x0e, 0xca, 0x1c, 0x7c, 0x50, 0x0c, 0x98, 0x8e, 0x96, 0x2e, 0x9f, 0x20, 0xdf,
- 0x42, 0xa7, 0xd0, 0xe6, 0x2e, 0xf3, 0x63, 0xf0, 0xaa, 0xe8, 0xc3, 0x7f, 0x41, 0x3e, 0x84, 0xf5,
- 0xb2, 0x4c, 0x77, 0xe2, 0xbe, 0x86, 0xfe, 0xbc, 0x52, 0x77, 0x62, 0x7f, 0x07, 0xf7, 0x16, 0x85,
- 0xba, 0xd3, 0xd8, 0xfc, 0xa3, 0x0a, 0xfd, 0x7c, 0xd2, 0x8b, 0x38, 0x4d, 0x02, 0xa2, 0x86, 0x48,
- 0xc0, 0xd3, 0x49, 0x62, 0x26, 0xbf, 0x76, 0x53, 0xf7, 0x20, 0xe0, 0x69, 0xe9, 0x2e, 0x50, 0x06,
- 0xe5, 0x5e, 0x69, 0x07, 0x3c, 0xd5, 0x8d, 0xa2, 0x5a, 0xce, 0xf6, 0x52, 0xee, 0xa0, 0xae, 0x2d,
- 0x7a, 0x06, 0xcd, 0x7d, 0x2c, 0xb6, 0x5c, 0x63, 0xa9, 0xe5, 0xf0, 0x4b, 0xd8, 0x48, 0x52, 0xc6,
- 0x28, 0xbb, 0x9a, 0xa8, 0x9b, 0x91, 0xa5, 0x91, 0x9e, 0x4c, 0x75, 0xaf, 0x67, 0xe1, 0x11, 0xe7,
- 0x6f, 0xd3, 0xc8, 0xfd, 0xbd, 0x0a, 0xdb, 0xa3, 0x30, 0xbc, 0xf8, 0x99, 0x26, 0xe1, 0x99, 0x9f,
- 0xc8, 0xec, 0x98, 0x85, 0x3c, 0xa6, 0x4c, 0xaa, 0xeb, 0x0e, 0x11, 0x1a, 0x69, 0x5a, 0x0c, 0x52,
- 0xbd, 0x56, 0x02, 0x89, 0x62, 0x7a, 0xaa, 0x25, 0xf6, 0xa1, 0x46, 0xb9, 0xed, 0xc2, 0x1a, 0xe5,
- 0x8a, 0xc5, 0xe3, 0xc4, 0x1c, 0xab, 0xe9, 0xe9, 0xb5, 0x4a, 0x9b, 0x8a, 0x49, 0xcc, 0xa6, 0x94,
- 0x11, 0x7d, 0x92, 0xb6, 0xd7, 0xa6, 0xe2, 0x27, 0xfd, 0xad, 0x0f, 0xf1, 0x8e, 0x7f, 0xe2, 0x43,
- 0x8c, 0x60, 0xfb, 0x88, 0x4c, 0xff, 0xcb, 0x19, 0xdc, 0x0f, 0x55, 0xc0, 0x65, 0x07, 0xff, 0x63,
- 0x02, 0xb3, 0xc6, 0x6d, 0x96, 0x1b, 0x77, 0x3e, 0xb1, 0xd6, 0x42, 0x62, 0xdf, 0xc3, 0xfd, 0x15,
- 0x59, 0xe1, 0x2e, 0xd4, 0xe3, 0xcb, 0x5f, 0xec, 0x15, 0xfb, 0x40, 0xcd, 0x8f, 0x65, 0x2b, 0x4f,
- 0x99, 0xec, 0x7d, 0x68, 0x40, 0x7f, 0xc4, 0xb9, 0x67, 0x5e, 0x57, 0xe7, 0x19, 0x0b, 0xf0, 0x00,
- 0xd6, 0x4f, 0x88, 0x1c, 0x71, 0x6e, 0x6f, 0xb2, 0xfb, 0xa5, 0x5b, 0x2b, 0x7f, 0x28, 0x0d, 0x36,
- 0x97, 0xde, 0x2d, 0x6e, 0x05, 0x5f, 0x02, 0x18, 0xa6, 0x9a, 0x34, 0x88, 0x25, 0x5e, 0x4e, 0xdb,
- 0x5a, 0xba, 0x01, 0xd5, 0x9b, 0xc0, 0xad, 0xe0, 0x3e, 0xf4, 0x4e, 0x88, 0x2c, 0x5d, 0x24, 0xab,
- 0xd8, 0xfd, 0xf9, 0x49, 0xe8, 0x56, 0xf0, 0x35, 0x6c, 0x9e, 0x10, 0xb9, 0xd0, 0xa7, 0xfa, 0x6c,
- 0x73, 0xaf, 0xb4, 0x01, 0x96, 0x21, 0x63, 0xe6, 0x56, 0xf0, 0x07, 0x78, 0xa8, 0xc2, 0xaf, 0x52,
- 0x70, 0x55, 0xf8, 0x87, 0xab, 0x85, 0x14, 0x6e, 0x05, 0xdf, 0xc0, 0xd6, 0xca, 0x4e, 0x43, 0x3d,
- 0xfb, 0x3f, 0xda, 0x84, 0x83, 0x8e, 0xda, 0x36, 0xcf, 0x57, 0xed, 0x64, 0x65, 0xa7, 0x18, 0x27,
- 0x1f, 0x6d, 0xa2, 0x25, 0x27, 0x2b, 0x7f, 0x75, 0xb4, 0xb7, 0xd0, 0xf4, 0x1f, 0x38, 0xb9, 0x6c,
- 0xe9, 0xe7, 0xf5, 0x37, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0xc9, 0x52, 0x20, 0xc0, 0x7a, 0x0b,
- 0x00, 0x00,
+ // 1044 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x56, 0xef, 0x6e, 0xdb, 0x36,
+ 0x10, 0xf7, 0xff, 0xd8, 0xe7, 0xd8, 0x69, 0xd8, 0xa5, 0x55, 0xdc, 0x76, 0x6d, 0x35, 0x74, 0xc8,
+ 0x87, 0xc2, 0x1b, 0x32, 0x04, 0x4b, 0xd3, 0x62, 0x83, 0xd1, 0x04, 0x99, 0x81, 0xac, 0x0b, 0x94,
+ 0xf4, 0xb3, 0xa1, 0x48, 0x6c, 0xc6, 0xc5, 0x22, 0x59, 0x91, 0x0a, 0xa0, 0x8f, 0xdb, 0x2b, 0xf4,
+ 0x85, 0xf6, 0x04, 0xc3, 0x1e, 0x69, 0xe0, 0x1f, 0xc9, 0x92, 0xad, 0xa2, 0xf3, 0x36, 0x60, 0xdf,
+ 0xa8, 0xdf, 0xdd, 0xef, 0x8e, 0x77, 0xa7, 0xbb, 0x23, 0x38, 0x3e, 0xe7, 0xb3, 0x38, 0xa1, 0x92,
+ 0x44, 0x78, 0x26, 0x70, 0x7c, 0x8b, 0xe3, 0x31, 0x8f, 0x99, 0x64, 0xa8, 0xc1, 0xaf, 0xdc, 0x0d,
+ 0x68, 0x9f, 0x44, 0x5c, 0xa6, 0xee, 0x57, 0x30, 0xbc, 0xc0, 0xf1, 0x2d, 0x09, 0xb0, 0x87, 0xdf,
+ 0x27, 0x58, 0x48, 0xf4, 0x08, 0x40, 0x18, 0x64, 0x46, 0x42, 0xa7, 0xfe, 0xa4, 0xbe, 0xd7, 0xf3,
+ 0x7a, 0x16, 0x99, 0x86, 0xee, 0x3e, 0x6c, 0x59, 0x82, 0xc8, 0x18, 0x8f, 0xa1, 0xbf, 0x60, 0x08,
+ 0x4b, 0x81, 0x9c, 0x22, 0xdc, 0xe7, 0x30, 0xb8, 0xc4, 0xd4, 0xa7, 0x32, 0x63, 0x3c, 0x80, 0x9e,
+ 0xd4, 0xc0, 0xc2, 0x45, 0xd7, 0x00, 0xd3, 0xd0, 0xfd, 0xb5, 0x0e, 0x83, 0x0b, 0xe9, 0xcb, 0x44,
+ 0xfc, 0x88, 0x85, 0xf0, 0xaf, 0x31, 0x3a, 0x80, 0x8e, 0xd0, 0x80, 0x53, 0x7f, 0xd2, 0xdc, 0xeb,
+ 0xef, 0x3f, 0x1a, 0xf3, 0xab, 0x71, 0x49, 0xc5, 0x7e, 0x9d, 0x50, 0x19, 0xa7, 0x9e, 0x55, 0x1e,
+ 0xbd, 0x80, 0x7e, 0x01, 0x46, 0x77, 0xa0, 0x79, 0x83, 0x53, 0xeb, 0x4e, 0x1d, 0xd1, 0x67, 0xd0,
+ 0xbe, 0xf5, 0xe7, 0x09, 0x76, 0x1a, 0x1a, 0x33, 0x1f, 0x47, 0x8d, 0xc3, 0xba, 0x9b, 0x42, 0xff,
+ 0x98, 0x88, 0x9b, 0xec, 0x02, 0x5f, 0x43, 0x3b, 0x24, 0xe2, 0x26, 0xf3, 0x3f, 0x52, 0xfe, 0x0b,
+ 0x72, 0x7d, 0xb6, 0xce, 0x8d, 0xe2, 0xe8, 0x10, 0x60, 0x01, 0x7e, 0xca, 0x75, 0xbd, 0xe8, 0xfa,
+ 0x08, 0xb6, 0x6d, 0x82, 0x27, 0x9c, 0x9f, 0xb3, 0xf0, 0x8c, 0x08, 0x89, 0x9e, 0x41, 0x8b, 0xb3,
+ 0x30, 0xf3, 0xbf, 0xad, 0xe3, 0x2f, 0x2a, 0x79, 0x5a, 0xec, 0xfe, 0xd1, 0x80, 0x41, 0x09, 0xff,
+ 0x44, 0x35, 0x55, 0x21, 0x42, 0xcc, 0xe7, 0x2c, 0x55, 0x52, 0x93, 0x85, 0xae, 0x01, 0xa6, 0xa1,
+ 0xaa, 0xab, 0x15, 0xca, 0x94, 0x63, 0xa7, 0x69, 0xea, 0x6a, 0xa0, 0xcb, 0x94, 0x63, 0xb4, 0x0b,
+ 0x5d, 0xce, 0xc2, 0x19, 0xf5, 0x23, 0xec, 0xb4, 0xb4, 0x74, 0x83, 0xb3, 0xf0, 0x8d, 0x1f, 0x61,
+ 0xb4, 0x03, 0x1d, 0x25, 0x22, 0xdc, 0x69, 0x9b, 0xdc, 0x72, 0x16, 0x4e, 0xb9, 0xba, 0x8e, 0x82,
+ 0x6d, 0x35, 0x3b, 0xe6, 0x3a, 0x9c, 0x85, 0xa6, 0x4e, 0x68, 0x02, 0x10, 0x30, 0x2a, 0x7d, 0x42,
+ 0x71, 0x2c, 0x9c, 0x0d, 0x1d, 0xec, 0xd3, 0x95, 0x60, 0xc7, 0xaf, 0x73, 0x1d, 0x93, 0xf3, 0x02,
+ 0x69, 0x74, 0x06, 0x5b, 0x4b, 0xe2, 0x8a, 0xec, 0x7f, 0x51, 0xcc, 0x7e, 0x7f, 0x7f, 0xa0, 0x5c,
+ 0xe4, 0xac, 0x62, 0x31, 0xde, 0x42, 0x2f, 0xc7, 0xd1, 0x33, 0x18, 0xe6, 0x8e, 0x4c, 0xd0, 0xc6,
+ 0xe4, 0x20, 0x47, 0x75, 0xe8, 0x4f, 0x61, 0x33, 0xc2, 0x11, 0x8b, 0xd3, 0xd9, 0x9c, 0x44, 0x44,
+ 0x6a, 0x1f, 0x4d, 0xaf, 0x6f, 0xb0, 0x33, 0x05, 0xb9, 0x7f, 0x76, 0x00, 0x8e, 0x4d, 0x9a, 0xe9,
+ 0x3b, 0x86, 0x1e, 0x42, 0x4f, 0x99, 0x13, 0xdc, 0x0f, 0x32, 0x9b, 0x0b, 0x00, 0xb9, 0xb0, 0xa9,
+ 0xf2, 0x85, 0xdf, 0x25, 0x73, 0x2c, 0xb0, 0xb4, 0x65, 0x2a, 0x61, 0xe8, 0x73, 0xb0, 0x75, 0x89,
+ 0x30, 0x95, 0xe5, 0x4a, 0x29, 0x04, 0x3d, 0xb7, 0xff, 0x4f, 0x4b, 0xa7, 0xd4, 0xd1, 0xff, 0x6f,
+ 0xee, 0x7f, 0x7c, 0xce, 0x42, 0x9b, 0x49, 0xad, 0x85, 0x0e, 0xa1, 0x6b, 0x7f, 0x11, 0xe1, 0xb4,
+ 0x35, 0xe3, 0xe1, 0x12, 0x23, 0x1b, 0x01, 0x86, 0x95, 0x6b, 0xa3, 0x97, 0xd0, 0xc3, 0x34, 0xe4,
+ 0x8c, 0x50, 0xa9, 0xca, 0x9b, 0x37, 0x6b, 0x81, 0x7a, 0x92, 0xc9, 0x0d, 0x77, 0xa1, 0x8f, 0x0e,
+ 0x60, 0x43, 0xe0, 0x20, 0xc6, 0x32, 0x2b, 0xfd, 0x83, 0x15, 0xaf, 0x5a, 0x6a, 0x88, 0x99, 0xae,
+ 0xf2, 0x49, 0xe8, 0x75, 0x8c, 0x85, 0xc0, 0xc2, 0xe9, 0x56, 0xfa, 0x9c, 0x66, 0x72, 0xeb, 0x33,
+ 0xd7, 0x47, 0x13, 0xe8, 0xc7, 0x98, 0xcf, 0x49, 0xe0, 0x4b, 0x95, 0xdb, 0x9e, 0xa6, 0x3f, 0x5e,
+ 0xa2, 0x7b, 0x0b, 0x0d, 0x63, 0xa0, 0xc8, 0x41, 0xf7, 0xf2, 0xe9, 0x04, 0x3a, 0xef, 0xd9, 0xf8,
+ 0xf9, 0x16, 0x7a, 0x79, 0x62, 0xd7, 0x19, 0x3e, 0xa3, 0x97, 0x79, 0x13, 0xff, 0x03, 0xf2, 0x2b,
+ 0x18, 0x96, 0x33, 0xbc, 0x16, 0xfb, 0x08, 0x36, 0x8b, 0x49, 0x5e, 0xd7, 0x73, 0x39, 0xcf, 0x6b,
+ 0xb1, 0xbf, 0x83, 0x3b, 0xcb, 0x69, 0x5e, 0x6b, 0x62, 0xff, 0x5e, 0x87, 0x61, 0xb6, 0x64, 0x04,
+ 0x4b, 0xe2, 0x00, 0xab, 0xf9, 0x15, 0xf0, 0x64, 0x16, 0x9b, 0xa5, 0xa3, 0xcd, 0x34, 0x3d, 0x08,
+ 0x78, 0x52, 0x58, 0x43, 0x4a, 0xa1, 0xd8, 0xa6, 0xdd, 0x80, 0x27, 0xba, 0x47, 0x55, 0xb7, 0xdb,
+ 0x36, 0xce, 0x0c, 0x34, 0xb5, 0xc6, 0xc0, 0xa0, 0x99, 0x8d, 0xe5, 0x6e, 0x6f, 0xad, 0x74, 0x3b,
+ 0xfa, 0x12, 0xb6, 0xe2, 0x84, 0x52, 0x42, 0xaf, 0x67, 0x6a, 0x29, 0xd3, 0x24, 0xd2, 0x43, 0xb1,
+ 0xe9, 0x0d, 0x2c, 0x3c, 0xe1, 0xfc, 0x4d, 0x12, 0xb9, 0xbf, 0xd5, 0x61, 0x77, 0x12, 0x86, 0x97,
+ 0x3f, 0x93, 0x38, 0x3c, 0xf7, 0x63, 0x99, 0xe6, 0x85, 0xf4, 0xf0, 0x7b, 0x84, 0xa0, 0x95, 0x24,
+ 0xf9, 0x0c, 0xd7, 0x67, 0x95, 0x20, 0x91, 0x0f, 0x6e, 0x75, 0x44, 0x43, 0x68, 0x10, 0x6e, 0x07,
+ 0x40, 0x83, 0x70, 0xc5, 0xe2, 0x2c, 0x36, 0xd7, 0x6a, 0x7b, 0xfa, 0xac, 0xc2, 0x26, 0x62, 0xc6,
+ 0xe8, 0x9c, 0x50, 0xac, 0x6f, 0xd2, 0xf5, 0xba, 0x44, 0xfc, 0xa4, 0xbf, 0xf5, 0x25, 0xde, 0xf2,
+ 0xff, 0xf9, 0x12, 0x13, 0xd8, 0x3d, 0xc6, 0xf3, 0x7f, 0x73, 0x07, 0xf7, 0x43, 0x1d, 0xd0, 0xaa,
+ 0x81, 0xff, 0x30, 0x80, 0x45, 0xdb, 0xb7, 0x8b, 0x6d, 0x5f, 0x0e, 0xac, 0xb3, 0x14, 0xd8, 0xf7,
+ 0x70, 0xb7, 0x22, 0x2a, 0xb4, 0x07, 0x4d, 0x76, 0xf5, 0x8b, 0xdd, 0xee, 0xf7, 0xd4, 0xf4, 0x59,
+ 0xd5, 0xf2, 0x94, 0xca, 0xfe, 0x87, 0x16, 0x0c, 0x27, 0x9c, 0x7b, 0xe6, 0x61, 0x77, 0x91, 0xd2,
+ 0x00, 0x1d, 0xc2, 0xe6, 0x29, 0x96, 0x13, 0xce, 0xed, 0x12, 0xbd, 0x5b, 0x58, 0x98, 0xd9, 0x1b,
+ 0x6d, 0xb4, 0xbd, 0xf2, 0x64, 0x72, 0x6b, 0xe8, 0x05, 0x80, 0x61, 0xaa, 0x39, 0x85, 0x50, 0x81,
+ 0x97, 0xd1, 0x76, 0x56, 0x96, 0xaf, 0x7a, 0x8e, 0xb8, 0x35, 0x74, 0x00, 0x83, 0x53, 0x2c, 0x0b,
+ 0x3b, 0xac, 0x8a, 0x3d, 0x2c, 0xcf, 0x51, 0xb7, 0x86, 0x5e, 0xc1, 0xf6, 0x29, 0x96, 0x4b, 0x7d,
+ 0xaa, 0xef, 0x56, 0x7a, 0x20, 0x8e, 0x50, 0x11, 0x32, 0x6a, 0x6e, 0x0d, 0xfd, 0x00, 0xf7, 0x95,
+ 0xfb, 0xaa, 0x0c, 0x56, 0xb9, 0xbf, 0x5f, 0x9d, 0x48, 0xe1, 0xd6, 0xd0, 0x6b, 0xd8, 0xa9, 0xec,
+ 0x34, 0xa4, 0x37, 0xc7, 0x47, 0x9b, 0x70, 0xd4, 0x53, 0x62, 0xf3, 0x72, 0xd6, 0x46, 0x2a, 0x3b,
+ 0xc5, 0x18, 0xf9, 0x68, 0x13, 0xad, 0x18, 0xa9, 0xfc, 0xd5, 0x91, 0xdd, 0x61, 0xf3, 0xbf, 0x61,
+ 0xe4, 0xaa, 0xa3, 0x5f, 0xf6, 0xdf, 0xfc, 0x15, 0x00, 0x00, 0xff, 0xff, 0xa2, 0xcd, 0xa8, 0xa8,
+ 0xf5, 0x0b, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
diff --git a/worker/server/pb/app_runtime_server.proto b/worker/server/pb/app_runtime_server.proto
index 676cef706..744351420 100644
--- a/worker/server/pb/app_runtime_server.proto
+++ b/worker/server/pb/app_runtime_server.proto
@@ -56,10 +56,11 @@ message DeployInfo {
string deployment = 3;
map pods = 4;
map services = 5;
- map secrets = 6;
- map ingresses = 7;
- map replicatset = 8;
- string status = 9;
+ map endpoints = 6;
+ map secrets = 7;
+ map ingresses = 8;
+ map replicatset = 9;
+ string status = 10;
}
message TenantResource {
diff --git a/worker/server/server.go b/worker/server/server.go
index 30b118f15..d3a1502bf 100644
--- a/worker/server/server.go
+++ b/worker/server/server.go
@@ -21,9 +21,9 @@ package server
import (
"context"
"fmt"
+ "github.com/goodrain/rainbond/db/model"
corev1 "k8s.io/api/core/v1"
"net"
- "strconv"
"strings"
"time"
@@ -180,6 +180,14 @@ func (r *RuntimeServer) GetDeployInfo(ctx context.Context, re *pb.ServiceRequest
}
deployinfo.Services = service
}
+ if endpoints := appService.GetEndpoints(); endpoints != nil &&
+ appService.AppServiceBase.ServiceKind == model.ServiceKindThirdParty {
+ eps := make(map[string]string, len(endpoints))
+ for _, s := range endpoints {
+ eps[s.Name] = s.Name
+ }
+ deployinfo.Endpoints = eps
+ }
if secrets := appService.GetSecrets(); secrets != nil {
secretsinfo := make(map[string]string, len(secrets))
for _, s := range secrets {
@@ -242,36 +250,49 @@ func (r *RuntimeServer) ListThirdPartyEndpoints(ctx context.Context, re *pb.Serv
return new(pb.ThirdPartyEndpoints), nil
}
var pbeps []*pb.ThirdPartyEndpoint
+ // The same IP may correspond to two endpoints, which are internal and external endpoints.
+ // So it is need to filter the same IP.
exists := make(map[string]bool)
for _, ep := range as.GetEndpoints() {
- if exists[ep.GetLabels()["uuid"]] {
+ if ep.Subsets == nil || len(ep.Subsets) == 0 {
+ logrus.Debugf("Key: %s; empty subsets", fmt.Sprintf("%s/%s", ep.Namespace, ep.Name))
continue
}
- exists[ep.GetLabels()["uuid"]] = true
- pbep := &pb.ThirdPartyEndpoint{
- Uuid: ep.GetLabels()["uuid"],
- Sid: ep.GetLabels()["service_id"],
- Ip: ep.GetLabels()["ip"],
- Port: func(item *corev1.Endpoints) int32 {
- realport, _ := strconv.ParseBool(item.GetLabels()["realport"])
- if realport {
- portstr := item.GetLabels()["port"]
- port, _ := strconv.Atoi(portstr)
- return int32(port)
+ for idx, subset := range ep.Subsets {
+ if exists[subset.Ports[0].Name] {
+ continue
+ }
+ ip := func(subset corev1.EndpointSubset) string {
+ if subset.Addresses != nil && len(subset.Addresses) > 0 {
+ return subset.Addresses[0].IP
}
- return 0
- }(ep),
- Status: func(item *corev1.Endpoints) string {
- if item.Subsets == nil || len(item.Subsets) == 0 {
+ if subset.NotReadyAddresses != nil && len(subset.NotReadyAddresses) > 0 {
+ return subset.NotReadyAddresses[0].IP
+ }
+ return ""
+ }(subset)
+ if strings.TrimSpace(ip) == "" {
+ logrus.Debugf("Key: %s; Index: %d; IP not found", fmt.Sprintf("%s/%s", ep.Namespace, ep.Name), idx)
+ continue
+ }
+ exists[subset.Ports[0].Name] = true
+ pbep := &pb.ThirdPartyEndpoint{
+ Uuid: subset.Ports[0].Name,
+ Sid: ep.GetLabels()["service_id"],
+ Ip: ip,
+ Port: subset.Ports[0].Port,
+ Status: func(item *corev1.Endpoints) string {
+ if subset.Addresses != nil && len(subset.Addresses) > 0 {
+ return "healthy"
+ }
+ if subset.NotReadyAddresses != nil && len(subset.NotReadyAddresses) > 0 {
+ return "unhealthy"
+ }
return "unknown"
- }
- if item.Subsets[0].Addresses == nil || len(item.Subsets[0].Addresses) == 0 {
- return "unhealthy"
- }
- return "healthy"
- }(ep),
+ }(ep),
+ }
+ pbeps = append(pbeps, pbep)
}
- pbeps = append(pbeps, pbep)
}
return &pb.ThirdPartyEndpoints{
Obj: pbeps,
@@ -310,9 +331,16 @@ func (r *RuntimeServer) UpdThirdPartyEndpoint(ctx context.Context, re *pb.UpdThi
Port: int(re.Port),
IsOnline: re.IsOnline,
}
- r.updateCh.In() <- discovery.Event{
- Type: discovery.UpdateEvent,
- Obj: rbdep,
+ if re.IsOnline == false {
+ r.updateCh.In() <- discovery.Event{
+ Type: discovery.DeleteEvent,
+ Obj: rbdep,
+ }
+ } else {
+ r.updateCh.In() <- discovery.Event{
+ Type: discovery.UpdateEvent,
+ Obj: rbdep,
+ }
}
return new(pb.Empty), nil
}