Merge pull request #5145 from tb365/bugfix/tb-elb-bugfix-0114

qcloud elb sync
This commit is contained in:
yunion-ci-robot
2020-02-19 16:03:27 +08:00
committed by GitHub
18 changed files with 1553 additions and 391 deletions
+14
View File
@@ -70,4 +70,18 @@ type SLoadbalancerListenerRule struct {
BackendGroupType string
Condition string // for aws only
Scheduler string // for qcloud only
HealthCheck string // for qcloud only
HealthCheckType string // for qcloud only
HealthCheckTimeout int // for qcloud only
HealthCheckDomain string // for qcloud only
HealthCheckHttpCode string // for qcloud only
HealthCheckURI string // for qcloud only
HealthCheckInterval int // for qcloud only
HealthCheckRise int // for qcloud only
HealthCheckFail int // for qcloud only
StickySessionCookieTimeout int // for qcloud only
}
+45
View File
@@ -294,3 +294,48 @@ func syncAwsLoadbalancerBackends(ctx context.Context, userCred mcclient.TokenCre
return
}
}
/*qcloud elb sync*/
func SyncQcloudLoadbalancerBackendgroups(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localLoadbalancer *SLoadbalancer, remoteLoadbalancer cloudprovider.ICloudLoadbalancer, syncRange *SSyncRange) {
remoteBackendgroups, err := remoteLoadbalancer.GetILoadBalancerBackendGroups()
if err != nil {
msg := fmt.Sprintf("GetILoadBalancerBackendGroups for loadbalancer %s failed %s", localLoadbalancer.Name, err)
log.Errorln(msg)
return
}
localLbbgs, remoteLbbgs, result := QcloudCachedLbbgManager.SyncLoadbalancerBackendgroups(ctx, userCred, provider, localLoadbalancer, remoteBackendgroups, syncRange)
syncResults.Add(QcloudCachedLbbgManager, result)
msg := result.Result()
log.Infof("SyncLoadbalancerBackendgroups for loadbalancer %s result: %s", localLoadbalancer.Name, msg)
if result.IsError() {
return
}
for i := 0; i < len(localLbbgs); i++ {
func() {
lockman.LockObject(ctx, &localLbbgs[i])
defer lockman.ReleaseObject(ctx, &localLbbgs[i])
syncQcloudLoadbalancerBackends(ctx, userCred, syncResults, provider, &localLbbgs[i], remoteLbbgs[i], syncRange)
}()
}
}
func syncQcloudLoadbalancerBackends(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localLbbg *SQcloudCachedLbbg, remoteLbbg cloudprovider.ICloudLoadbalancerBackendGroup, syncRange *SSyncRange) {
remoteLbbs, err := remoteLbbg.GetILoadbalancerBackends()
if err != nil {
msg := fmt.Sprintf("GetILoadbalancerBackends for lbbg %s failed %s", localLbbg.Name, err)
log.Errorln(msg)
return
}
result := QcloudCachedLbManager.SyncLoadbalancerBackends(ctx, userCred, provider, localLbbg, remoteLbbs, syncRange)
syncResults.Add(LoadbalancerBackendManager, result)
msg := result.Result()
log.Infof("SyncLoadbalancerBackends for LoadbalancerBackendgroup %s result: %s", localLbbg.Name, msg)
if result.IsError() {
return
}
}
@@ -603,6 +603,17 @@ func (lbbg *SLoadbalancerBackendGroup) GetHuaweiCachedlbbg() ([]SHuaweiCachedLbb
return ret, nil
}
func (lbbg *SLoadbalancerBackendGroup) GetQcloudCachedlbbg() ([]SQcloudCachedLbbg, error) {
ret := []SQcloudCachedLbbg{}
q := QcloudCachedLbbgManager.Query().Equals("backend_group_id", lbbg.GetId())
err := db.FetchModelObjects(QcloudCachedLbbgManager, q, &ret)
if err != nil {
return nil, errors.Wrap(err, "loadbalancerBackendGroup.GetQcloudCachedlbbg")
}
return ret, nil
}
func (lbbg *SLoadbalancerBackendGroup) GetAwsBackendGroupParams(lblis *SLoadbalancerListener, lbr *SLoadbalancerListenerRule) (*cloudprovider.SLoadbalancerBackendGroup, error) {
ret, err := lbbg.GetBackendGroupParams()
if err != nil {
@@ -643,6 +654,21 @@ func (lbbg *SLoadbalancerBackendGroup) GetAwsBackendGroupParams(lblis *SLoadbala
return ret, nil
}
func (lbbg *SLoadbalancerBackendGroup) GetQcloudBackendGroupParams(lblis *SLoadbalancerListener, lbr *SLoadbalancerListenerRule) (*cloudprovider.SLoadbalancerBackendGroup, error) {
ret, err := lbbg.GetBackendGroupParams()
if err != nil {
return ret, err
}
if lbr != nil {
ret.ListenerID = lbr.GetExternalId()
} else {
ret.ListenerID = lblis.GetExternalId()
}
return ret, nil
}
func (lbbg *SLoadbalancerBackendGroup) GetBackendsParams() ([]cloudprovider.SLoadbalancerBackend, error) {
backends, err := lbbg.GetBackends()
if err != nil {
+33 -13
View File
@@ -624,18 +624,6 @@ func (lbr *SLoadbalancerListenerRule) constructFieldsFromCloudListenerRule(userC
lbr.Status = extRule.GetStatus()
lbr.Condition = extRule.GetCondition()
if groupId := extRule.GetBackendGroupId(); len(groupId) > 0 {
// 腾讯云兼容代码。主要目的是在关联listener rule时回写一个fake的backend group external id
if lbr.GetProviderName() == api.CLOUD_PROVIDER_QCLOUD && len(groupId) > 0 && len(lbr.BackendGroupId) > 0 {
ilbbg, err := LoadbalancerBackendGroupManager.FetchById(lbr.BackendGroupId)
lbbg := ilbbg.(*SLoadbalancerBackendGroup)
if err == nil && (len(lbbg.ExternalId) == 0 || lbbg.ExternalId != groupId) {
err = db.SetExternalId(lbbg, userCred, groupId)
if err != nil {
log.Errorf("Update loadbalancer BackendGroup(%s) external id failed: %s", lbbg.GetId(), err)
}
}
}
if lbr.GetProviderName() == api.CLOUD_PROVIDER_HUAWEI {
group, err := db.FetchByExternalId(HuaweiCachedLbbgManager, groupId)
if err != nil {
@@ -655,6 +643,16 @@ func (lbr *SLoadbalancerListenerRule) constructFieldsFromCloudListenerRule(userC
lbr.BackendGroupId = group.(*SAwsCachedLbbg).BackendGroupId
}
} else if lbr.GetProviderName() == api.CLOUD_PROVIDER_QCLOUD {
group, err := db.FetchByExternalId(QcloudCachedLbbgManager, groupId)
if err != nil {
if err == sql.ErrNoRows {
lbr.BackendGroupId = ""
}
log.Errorf("Fetch qcloud loadbalancer backendgroup by external id %s failed: %s", groupId, err)
}
lbr.BackendGroupId = group.(*SQcloudCachedLbbg).BackendGroupId
} else if backendgroup, err := db.FetchByExternalId(LoadbalancerBackendGroupManager, groupId); err == nil {
lbr.BackendGroupId = backendgroup.GetId()
}
@@ -686,7 +684,29 @@ func (lbr *SLoadbalancerListenerRule) updateCachedLoadbalancerBackendGroupAssoci
return nil
})
if err != nil {
return errors.Wrap(err, "LoadbalancerListener.updateCachedLoadbalancerBackendGroupAssociate")
return errors.Wrap(err, "LoadbalancerListener.updateCachedLoadbalancerBackendGroupAssociate.huawei")
}
}
}
case api.CLOUD_PROVIDER_QCLOUD:
_group, err := db.FetchByExternalId(QcloudCachedLbbgManager, exteralLbbgId)
if err != nil {
if err == sql.ErrNoRows {
lbr.BackendGroupId = ""
}
return fmt.Errorf("Fetch qcloud loadbalancer backendgroup by external id %s failed: %s", exteralLbbgId, err)
}
if _group != nil {
group := _group.(*SQcloudCachedLbbg)
if group.AssociatedId != lbr.Id {
_, err := db.UpdateWithLock(ctx, group, func() error {
group.AssociatedId = lbr.Id
group.AssociatedType = api.LB_ASSOCIATE_TYPE_RULE
return nil
})
if err != nil {
return errors.Wrap(err, "LoadbalancerListener.updateCachedLoadbalancerBackendGroupAssociate.qcloud")
}
}
}
+84 -16
View File
@@ -662,6 +662,29 @@ func (lblis *SLoadbalancerListener) GetAwsLoadbalancerListenerParams() (*cloudpr
return listener, nil
}
func (lblis *SLoadbalancerListener) GetQcloudLoadbalancerListenerParams() (*cloudprovider.SLoadbalancerListener, error) {
listener, err := lblis.GetLoadbalancerListenerParams()
if err != nil {
return nil, err
}
if backendgroup := lblis.GetLoadbalancerBackendGroup(); backendgroup != nil {
cachedLbbg, err := QcloudCachedLbbgManager.GetCachedBackendGroupByAssociateId(lblis.GetId())
if err != nil {
if err != sql.ErrNoRows {
return nil, errors.Wrap(err, "loadbalancerListener.GetCachedBackendGroupByAssociateId")
} else {
log.Debugf("loadbalancerListener.GetCachedBackendGroupByAssociateId %s not found", lblis.GetId())
}
} else {
listener.BackendGroupID = cachedLbbg.ExternalId
listener.BackendGroupType = backendgroup.Type
}
}
return listener, nil
}
func (lblis *SLoadbalancerListener) GetLoadbalancerCertificate() (*SCachedLoadbalancerCertificate, error) {
if len(lblis.CachedCertificateId) == 0 {
return nil, nil
@@ -877,27 +900,28 @@ func (lblis *SLoadbalancerListener) constructFieldsFromCloudListener(userCred mc
fallthrough
case api.LB_LISTENER_TYPE_HTTP:
if len(extListener.GetStickySessionType()) > 0 {
lblis.StickySession = extListener.GetStickySession()
lblis.StickySessionType = extListener.GetStickySessionType()
lblis.StickySessionCookie = extListener.GetStickySessionCookie()
lblis.StickySessionCookieTimeout = extListener.GetStickySessionCookieTimeout()
if lblis.GetProviderName() == api.CLOUD_PROVIDER_QCLOUD && utils.IsInStringArray(lblis.ListenerType, []string{api.LB_LISTENER_TYPE_HTTP, api.LB_LISTENER_TYPE_HTTPS}) {
// 腾讯云http&https监听, 没有会话保持,不需要同步
} else {
// deprecated ???
lblis.StickySession = extListener.GetStickySession()
lblis.StickySessionType = extListener.GetStickySessionType()
lblis.StickySessionCookie = extListener.GetStickySessionCookie()
lblis.StickySessionCookieTimeout = extListener.GetStickySessionCookieTimeout()
}
}
lblis.XForwardedFor = extListener.XForwardedForEnabled()
lblis.Gzip = extListener.GzipEnabled()
}
groupId := extListener.GetBackendGroupId()
// 腾讯云兼容代码。主要目的是在关联listen时回写一个fake的backend group external id
if lblis.GetProviderName() == api.CLOUD_PROVIDER_QCLOUD && len(groupId) > 0 && len(lblis.BackendGroupId) > 0 {
ilbbg, err := LoadbalancerBackendGroupManager.FetchById(lblis.BackendGroupId)
lbbg := ilbbg.(*SLoadbalancerBackendGroup)
if err == nil && (len(lbbg.ExternalId) == 0 || lbbg.ExternalId != groupId) {
err = db.SetExternalId(lbbg, userCred, groupId)
if err != nil {
log.Errorf("Update loadbalancer BackendGroup(%s) external id failed: %s", lbbg.GetId(), err)
}
}
if utils.IsInStringArray(extListener.GetStickySession(), []string{api.LB_BOOL_ON, api.LB_BOOL_OFF}) {
lblis.StickySession = extListener.GetStickySession()
lblis.StickySessionType = extListener.GetStickySessionType()
lblis.StickySessionCookie = extListener.GetStickySessionCookie()
lblis.StickySessionCookieTimeout = extListener.GetStickySessionCookieTimeout()
}
groupId := extListener.GetBackendGroupId()
switch lblis.GetProviderName() {
case api.CLOUD_PROVIDER_HUAWEI:
if len(groupId) > 0 {
@@ -931,6 +955,24 @@ func (lblis *SLoadbalancerListener) constructFieldsFromCloudListener(userCred mc
}
}
}
case api.CLOUD_PROVIDER_QCLOUD:
if len(groupId) > 0 {
lb := lblis.GetLoadbalancer()
if forward, _ := lb.LBInfo.Int("Forward"); forward == 1 {
// 应用型负载均衡
group, err := db.FetchByExternalId(QcloudCachedLbbgManager, groupId)
if err != nil {
log.Errorf("Fetch qcloud loadbalancer backendgroup by external id %s failed: %s", groupId, err)
} else {
lblis.BackendGroupId = group.(*SQcloudCachedLbbg).BackendGroupId
}
} else {
// 传统型负载均衡
if group, err := db.FetchByExternalId(LoadbalancerBackendGroupManager, groupId); err == nil {
lblis.BackendGroupId = group.GetId()
}
}
}
default:
if len(lblis.BackendGroupId) == 0 && len(groupId) == 0 {
lblis.BackendGroupId = lb.BackendGroupId
@@ -966,7 +1008,33 @@ func (lblis *SLoadbalancerListener) updateCachedLoadbalancerBackendGroupAssociat
return nil
})
if err != nil {
return errors.Wrap(err, "LoadbalancerListener.updateCachedLoadbalancerBackendGroupAssociate")
return errors.Wrap(err, "LoadbalancerListener.updateCachedLoadbalancerBackendGroupAssociate.huawei")
}
}
}
case api.CLOUD_PROVIDER_QCLOUD:
lb := lblis.GetLoadbalancer()
if forward, _ := lb.LBInfo.Int("Forward"); forward == 1 {
_group, err := db.FetchByExternalId(QcloudCachedLbbgManager, exteralLbbgId)
if err != nil {
if err == sql.ErrNoRows {
lblis.BackendGroupId = ""
} else {
return fmt.Errorf("Fetch qcloud loadbalancer backendgroup by external id %s failed: %s", exteralLbbgId, err)
}
}
if _group != nil {
group := _group.(*SQcloudCachedLbbg)
if group.AssociatedId != lblis.Id {
_, err := db.UpdateWithLock(ctx, group, func() error {
group.AssociatedId = lblis.Id
group.AssociatedType = api.LB_ASSOCIATE_TYPE_LISTENER
return nil
})
if err != nil {
return errors.Wrap(err, "LoadbalancerListener.updateCachedLoadbalancerBackendGroupAssociate.qcloud")
}
}
}
}
@@ -0,0 +1,288 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SQcloudCachedLbManager struct {
SLoadbalancerLogSkipper
db.SVirtualResourceBaseManager
}
var QcloudCachedLbManager *SQcloudCachedLbManager
func init() {
QcloudCachedLbManager = &SQcloudCachedLbManager{
SVirtualResourceBaseManager: db.NewVirtualResourceBaseManager(
SQcloudCachedLb{},
"qcloudcachedlbbs_tbl",
"qcloudcachedlbb",
"qcloudcachedlbbs",
),
}
QcloudCachedLbManager.SetVirtualObject(QcloudCachedLbManager)
}
type SQcloudCachedLb struct {
db.SVirtualResourceBase
db.SExternalizedResourceBase
SManagedResourceBase
SCloudregionResourceBase
BackendServerId string `width:"36" charset:"ascii" nullable:"true" list:"user" create:"optional"` // 后端服务器 实例ID
BackendId string `width:"36" charset:"ascii" nullable:"true" list:"user" create:"optional"` // 本地loadbalancebackend id
CachedBackendGroupId string `width:"36" charset:"ascii" nullable:"true" list:"user" create:"optional"`
}
func (lbb *SQcloudCachedLb) GetCustomizeColumns(context.Context, mcclient.TokenCredential, jsonutils.JSONObject) *jsonutils.JSONDict {
return nil
}
func (lbb *SQcloudCachedLb) GetCachedBackendGroup() (*SQcloudCachedLbbg, error) {
lbbg, err := db.FetchById(QcloudCachedLbbgManager, lbb.CachedBackendGroupId)
if err != nil {
return nil, err
}
return lbbg.(*SQcloudCachedLbbg), nil
}
func (lbb *SQcloudCachedLb) syncRemoveCloudLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential) error {
lockman.LockObject(ctx, lbb)
defer lockman.ReleaseObject(ctx, lbb)
err := lbb.ValidateDeleteCondition(ctx)
if err != nil { // cannot delete
err = lbb.SetStatus(userCred, api.LB_STATUS_UNKNOWN, "sync to delete")
} else {
lbb.SetModelManager(QcloudCachedLbManager, lbb)
err := db.DeleteModel(ctx, userCred, lbb)
if err != nil {
return err
}
}
return err
}
func (lbb *SQcloudCachedLb) constructFieldsFromCloudLoadbalancerBackend(extLoadbalancerBackend cloudprovider.ICloudLoadbalancerBackend) error {
lbb.Status = extLoadbalancerBackend.GetStatus()
instance, err := db.FetchByExternalId(GuestManager, extLoadbalancerBackend.GetBackendId())
if err != nil {
return err
}
guest := instance.(*SGuest)
lbb.BackendServerId = guest.Id
lbb.ExternalId = extLoadbalancerBackend.GetGlobalId()
return nil
}
func (lbb *SQcloudCachedLb) SyncWithCloudLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, extLoadbalancerBackend cloudprovider.ICloudLoadbalancerBackend, syncOwnerId mcclient.IIdentityProvider) error {
lbb.SetModelManager(QcloudCachedLbManager, lbb)
cacheLbbg, err := lbb.GetCachedBackendGroup()
if err != nil {
return errors.Wrap(err, "QcloudCachedLb.SyncWithCloudLoadbalancerBackend.GetCachedBackendGroup")
}
localLbbg, err := cacheLbbg.GetLocalBackendGroup(ctx, userCred)
if err != nil {
return errors.Wrap(err, "QcloudCachedLb.SyncWithCloudLoadbalancerBackend.GetLocalBackendGroup")
}
locallbb, err := newLocalBackendFromCloudLoadbalancerBackend(ctx, userCred, localLbbg, extLoadbalancerBackend, syncOwnerId)
if err != nil {
return errors.Wrap(err, "QcloudCachedLb.SyncWithCloudLoadbalancerBackend.newLocalBackendFromCloudLoadbalancerBackend")
}
diff, err := db.UpdateWithLock(ctx, lbb, func() error {
if locallbb != nil {
lbb.BackendId = locallbb.GetId()
}
return lbb.constructFieldsFromCloudLoadbalancerBackend(extLoadbalancerBackend)
})
if err != nil {
return err
}
db.OpsLog.LogSyncUpdate(lbb, diff, userCred)
SyncCloudProject(userCred, lbb, syncOwnerId, extLoadbalancerBackend, lbb.ManagerId)
return nil
}
func (man *SQcloudCachedLbManager) newFromCloudLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, loadbalancerBackendgroup *SQcloudCachedLbbg, extLoadbalancerBackend cloudprovider.ICloudLoadbalancerBackend, syncOwnerId mcclient.IIdentityProvider) (*SQcloudCachedLb, error) {
localBackendGroup, err := loadbalancerBackendgroup.GetLocalBackendGroup(ctx, userCred)
if err != nil {
return nil, err
} else if localBackendGroup == nil {
return nil, fmt.Errorf("newFromCloudLoadbalancerBackend localBackendGroup is nil")
}
locallbb, err := newLocalBackendFromCloudLoadbalancerBackend(ctx, userCred, localBackendGroup, extLoadbalancerBackend, syncOwnerId)
if err != nil {
return nil, err
}
lbb := &SQcloudCachedLb{}
lbb.SetModelManager(man, lbb)
lbb.CloudregionId = loadbalancerBackendgroup.CloudregionId
lbb.ManagerId = loadbalancerBackendgroup.ManagerId
lbb.CachedBackendGroupId = loadbalancerBackendgroup.Id
lbb.BackendId = locallbb.GetId()
lbb.ExternalId = extLoadbalancerBackend.GetGlobalId()
newName, err := db.GenerateName(man, syncOwnerId, extLoadbalancerBackend.GetName())
if err != nil {
return nil, err
}
lbb.Name = newName
if err := lbb.constructFieldsFromCloudLoadbalancerBackend(extLoadbalancerBackend); err != nil {
return nil, err
}
err = man.TableSpec().Insert(lbb)
if err != nil {
return nil, err
}
SyncCloudProject(userCred, lbb, syncOwnerId, extLoadbalancerBackend, loadbalancerBackendgroup.ManagerId)
db.OpsLog.LogEvent(lbb, db.ACT_CREATE, lbb.GetShortDesc(ctx), userCred)
return lbb, nil
}
func (man *SQcloudCachedLbManager) getLoadbalancerBackendsByLoadbalancerBackendgroup(loadbalancerBackendgroup *SQcloudCachedLbbg) ([]SQcloudCachedLb, error) {
loadbalancerBackends := []SQcloudCachedLb{}
q := man.Query().Equals("cached_backend_group_id", loadbalancerBackendgroup.Id)
if err := db.FetchModelObjects(man, q, &loadbalancerBackends); err != nil {
return nil, err
}
return loadbalancerBackends, nil
}
func (man *SQcloudCachedLbManager) SyncLoadbalancerBackends(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, loadbalancerBackendgroup *SQcloudCachedLbbg, lbbs []cloudprovider.ICloudLoadbalancerBackend, syncRange *SSyncRange) compare.SyncResult {
syncOwnerId := provider.GetOwnerId()
lockman.LockClass(ctx, man, db.GetLockClassKey(man, syncOwnerId))
defer lockman.ReleaseClass(ctx, man, db.GetLockClassKey(man, syncOwnerId))
syncResult := compare.SyncResult{}
dbLbbs, err := man.getLoadbalancerBackendsByLoadbalancerBackendgroup(loadbalancerBackendgroup)
if err != nil {
syncResult.Error(err)
return syncResult
}
removed := []SQcloudCachedLb{}
commondb := []SQcloudCachedLb{}
commonext := []cloudprovider.ICloudLoadbalancerBackend{}
added := []cloudprovider.ICloudLoadbalancerBackend{}
err = compare.CompareSets(dbLbbs, lbbs, &removed, &commondb, &commonext, &added)
if err != nil {
syncResult.Error(err)
return syncResult
}
for i := 0; i < len(removed); i++ {
err = removed[i].syncRemoveCloudLoadbalancerBackend(ctx, userCred)
if err != nil {
syncResult.DeleteError(err)
} else {
syncResult.Delete()
}
}
for i := 0; i < len(commondb); i++ {
err = commondb[i].SyncWithCloudLoadbalancerBackend(ctx, userCred, commonext[i], syncOwnerId)
if err != nil {
syncResult.UpdateError(err)
} else {
syncMetadata(ctx, userCred, &commondb[i], commonext[i])
syncResult.Update()
}
}
for i := 0; i < len(added); i++ {
local, err := man.newFromCloudLoadbalancerBackend(ctx, userCred, loadbalancerBackendgroup, added[i], syncOwnerId)
if err != nil {
syncResult.AddError(err)
} else {
syncMetadata(ctx, userCred, local, added[i])
syncResult.Add()
}
}
return syncResult
}
func (man *SQcloudCachedLbManager) GetBackendsByLocalBackendId(backendId string) ([]SQcloudCachedLb, error) {
loadbalancerBackends := []SQcloudCachedLb{}
q := man.Query().IsFalse("pending_deleted").Equals("backend_id", backendId)
if err := db.FetchModelObjects(man, q, &loadbalancerBackends); err != nil {
return nil, err
}
return loadbalancerBackends, nil
}
func (man *SQcloudCachedLbManager) CreateQcloudCachedLb(ctx context.Context, userCred mcclient.TokenCredential, lbb *SLoadbalancerBackend, cachedLbbg *SQcloudCachedLbbg, extLoadbalancerBackend cloudprovider.ICloudLoadbalancerBackend, syncOwnerId mcclient.IIdentityProvider) (*SQcloudCachedLb, error) {
cachedlbb := &SQcloudCachedLb{}
cachedlbb.SetModelManager(man, cachedlbb)
cachedlbb.CloudregionId = cachedLbbg.CloudregionId
cachedlbb.ManagerId = cachedLbbg.ManagerId
cachedlbb.CachedBackendGroupId = cachedLbbg.GetId()
cachedlbb.BackendId = lbb.GetId()
cachedlbb.ExternalId = extLoadbalancerBackend.GetGlobalId()
newName, err := db.GenerateName(man, syncOwnerId, extLoadbalancerBackend.GetName())
if err != nil {
return nil, err
}
cachedlbb.Name = newName
if err := cachedlbb.constructFieldsFromCloudLoadbalancerBackend(extLoadbalancerBackend); err != nil {
return nil, err
}
err = man.TableSpec().Insert(cachedlbb)
if err != nil {
return nil, err
}
SyncCloudProject(userCred, lbb, syncOwnerId, extLoadbalancerBackend, cachedLbbg.ManagerId)
db.OpsLog.LogEvent(cachedlbb, db.ACT_CREATE, lbb.GetShortDesc(ctx), userCred)
return cachedlbb, nil
}
@@ -0,0 +1,347 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"fmt"
"strconv"
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SQcloudCachedLbbgManager struct {
SLoadbalancerLogSkipper
db.SVirtualResourceBaseManager
}
var QcloudCachedLbbgManager *SQcloudCachedLbbgManager
func init() {
QcloudCachedLbbgManager = &SQcloudCachedLbbgManager{
SVirtualResourceBaseManager: db.NewVirtualResourceBaseManager(
SQcloudCachedLbbg{},
"qcloudcachedlbbgs_tbl",
"qcloudcachedlbbg",
"qcloudcachedlbbgs",
),
}
QcloudCachedLbbgManager.SetVirtualObject(QcloudCachedLbbgManager)
}
type SQcloudCachedLbbg struct {
db.SVirtualResourceBase
db.SExternalizedResourceBase
SManagedResourceBase
SCloudregionResourceBase
LoadbalancerId string `width:"36" charset:"ascii" nullable:"true" list:"user" create:"optional"`
BackendGroupId string `width:"36" charset:"ascii" nullable:"true" list:"user" create:"optional"`
AssociatedId string `width:"36" charset:"ascii" nullable:"true" list:"user" create:"optional"` // 关联ID
AssociatedType string `width:"36" charset:"ascii" nullable:"true" list:"user" create:"optional"` // 关联类型, listener || rule
}
func (lbb *SQcloudCachedLbbg) GetCustomizeColumns(context.Context, mcclient.TokenCredential, jsonutils.JSONObject) *jsonutils.JSONDict {
return nil
}
func (lbbg *SQcloudCachedLbbg) GetLocalBackendGroup(ctx context.Context, userCred mcclient.TokenCredential) (*SLoadbalancerBackendGroup, error) {
if len(lbbg.BackendGroupId) == 0 {
return nil, fmt.Errorf("GetLocalBackendGroup no related local backendgroup")
}
locallbbg, err := db.FetchById(LoadbalancerBackendGroupManager, lbbg.BackendGroupId)
if err != nil {
return nil, err
}
return locallbbg.(*SLoadbalancerBackendGroup), err
}
func (lbbg *SQcloudCachedLbbg) GetLoadbalancer() *SLoadbalancer {
lb, err := LoadbalancerManager.FetchById(lbbg.LoadbalancerId)
if err != nil {
log.Errorf("failed to find loadbalancer for backendgroup %s", lbbg.Name)
return nil
}
return lb.(*SLoadbalancer)
}
func (lbbg *SQcloudCachedLbbg) GetCachedBackends() ([]SQcloudCachedLb, error) {
ret := []SQcloudCachedLb{}
err := QcloudCachedLbManager.Query().Equals("cached_backend_group_id", lbbg.GetId()).IsFalse("pending_deleted").All(&ret)
if err != nil {
log.Errorf("failed to get cached backends for backendgroup %s", lbbg.Name)
return nil, err
}
return ret, nil
}
func (lbbg *SQcloudCachedLbbg) GetICloudLoadbalancerBackendGroup() (cloudprovider.ICloudLoadbalancerBackendGroup, error) {
if len(lbbg.ExternalId) == 0 {
return nil, fmt.Errorf("backendgroup %s has no external id", lbbg.GetId())
}
lb := lbbg.GetLoadbalancer()
if lb == nil {
return nil, fmt.Errorf("backendgroup %s releated loadbalancer not found", lbbg.GetId())
}
iregion, err := lb.GetIRegion()
if err != nil {
return nil, err
}
ilb, err := iregion.GetILoadBalancerById(lb.GetExternalId())
if err != nil {
return nil, err
}
ilbbg, err := ilb.GetILoadBalancerBackendGroupById(lbbg.ExternalId)
if err != nil {
return nil, err
}
return ilbbg, nil
}
func (lbbg *SQcloudCachedLbbg) syncRemoveCloudLoadbalancerBackendgroup(ctx context.Context, userCred mcclient.TokenCredential) error {
lockman.LockObject(ctx, lbbg)
defer lockman.ReleaseObject(ctx, lbbg)
err := lbbg.ValidateDeleteCondition(ctx)
if err != nil { // cannot delete
err = lbbg.SetStatus(userCred, api.LB_STATUS_UNKNOWN, "sync to delete")
} else {
lbbg.SetModelManager(QcloudCachedLbbgManager, lbbg)
_, err := db.Update(lbbg, func() error {
return lbbg.MarkDelete()
})
if err != nil {
return err
}
}
return err
}
func (lbbg *SQcloudCachedLbbg) isBackendsMatch(backends []SLoadbalancerBackend, ibackends []cloudprovider.ICloudLoadbalancerBackend) bool {
if len(ibackends) != len(backends) {
return false
}
locals := []string{}
remotes := []string{}
for i := range backends {
guest := backends[i].GetGuest()
seg := strings.Join([]string{guest.ExternalId, strconv.Itoa(backends[i].Weight), strconv.Itoa(backends[i].Port)}, "/")
locals = append(locals, seg)
}
for i := range ibackends {
ibackend := ibackends[i]
seg := strings.Join([]string{ibackend.GetBackendId(), strconv.Itoa(ibackend.GetWeight()), strconv.Itoa(ibackend.GetPort())}, "/")
remotes = append(remotes, seg)
}
for i := range remotes {
if !utils.IsInStringArray(remotes[i], locals) {
return false
}
}
return true
}
func (lbbg *SQcloudCachedLbbg) SyncWithCloudLoadbalancerBackendgroup(ctx context.Context, userCred mcclient.TokenCredential, lb *SLoadbalancer, extLoadbalancerBackendgroup cloudprovider.ICloudLoadbalancerBackendGroup, syncOwnerId mcclient.IIdentityProvider) error {
lbbg.SetModelManager(QcloudCachedLbbgManager, lbbg)
ibackends, err := extLoadbalancerBackendgroup.GetILoadbalancerBackends()
if err != nil {
return errors.Wrap(err, "QcloudCachedLbbg.SyncWithCloudLoadbalancerBackendgroup.GetILoadbalancerBackends")
}
localLbbg, err := lbbg.GetLocalBackendGroup(ctx, userCred)
if err != nil {
return errors.Wrap(err, "QcloudCachedLbbg.SyncWithCloudLoadbalancerBackendgroup.GetLocalBackendGroup")
}
backends, err := localLbbg.GetBackends()
if err != nil {
return errors.Wrap(err, "QcloudCachedLbbg.SyncWithCloudLoadbalancerBackendgroup.GetBackends")
}
var newLocalLbbg *SLoadbalancerBackendGroup
if !lbbg.isBackendsMatch(backends, ibackends) {
newLocalLbbg, err = newLocalBackendgroupFromCloudLoadbalancerBackendgroup(ctx, userCred, lb, extLoadbalancerBackendgroup, syncOwnerId)
if err != nil {
return errors.Wrap(err, "QcloudCachedLbbg.SyncWithCloudLoadbalancerBackendgroup.newLocalBackendgroupFromCloudLoadbalancerBackendgroup")
}
}
diff, err := db.UpdateWithLock(ctx, lbbg, func() error {
lbbg.Status = extLoadbalancerBackendgroup.GetStatus()
if newLocalLbbg != nil {
lbbg.BackendGroupId = newLocalLbbg.GetId()
}
return nil
})
if err != nil {
return err
}
db.OpsLog.LogSyncUpdate(lbbg, diff, userCred)
SyncCloudProject(userCred, lbbg, syncOwnerId, extLoadbalancerBackendgroup, lb.ManagerId)
return err
}
func (man *SQcloudCachedLbbgManager) GetCachedBackendGroupByAssociateId(associateId string) (*SQcloudCachedLbbg, error) {
ret := &SQcloudCachedLbbg{}
err := man.Query().IsFalse("pending_deleted").Equals("associated_id", associateId).First(ret)
if err != nil {
return nil, err
}
ret.SetModelManager(man, ret)
return ret, nil
}
func (man *SQcloudCachedLbbgManager) GetCachedBackendGroups(backendGroupId string) ([]SQcloudCachedLbbg, error) {
ret := []SQcloudCachedLbbg{}
err := man.Query().IsFalse("pending_deleted").Equals("backend_group_id", backendGroupId).All(&ret)
if err != nil {
return nil, err
}
return ret, nil
}
func (man *SQcloudCachedLbbgManager) getLoadbalancerBackendgroupsByLoadbalancer(lb *SLoadbalancer) ([]SQcloudCachedLbbg, error) {
lbbgs := []SQcloudCachedLbbg{}
q := man.Query().IsFalse("pending_deleted").Equals("loadbalancer_id", lb.Id)
if err := db.FetchModelObjects(man, q, &lbbgs); err != nil {
log.Errorf("failed to get lbbgs for lb: %s error: %v", lb.Name, err)
return nil, err
}
return lbbgs, nil
}
func (man *SQcloudCachedLbbgManager) SyncLoadbalancerBackendgroups(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, lb *SLoadbalancer, lbbgs []cloudprovider.ICloudLoadbalancerBackendGroup, syncRange *SSyncRange) ([]SQcloudCachedLbbg, []cloudprovider.ICloudLoadbalancerBackendGroup, compare.SyncResult) {
syncOwnerId := provider.GetOwnerId()
lockman.LockClass(ctx, man, db.GetLockClassKey(man, syncOwnerId))
defer lockman.ReleaseClass(ctx, man, db.GetLockClassKey(man, syncOwnerId))
localLbgs := []SQcloudCachedLbbg{}
remoteLbbgs := []cloudprovider.ICloudLoadbalancerBackendGroup{}
syncResult := compare.SyncResult{}
dbLbbgs, err := man.getLoadbalancerBackendgroupsByLoadbalancer(lb)
if err != nil {
syncResult.Error(err)
return nil, nil, syncResult
}
removed := []SQcloudCachedLbbg{}
commondb := []SQcloudCachedLbbg{}
commonext := []cloudprovider.ICloudLoadbalancerBackendGroup{}
added := []cloudprovider.ICloudLoadbalancerBackendGroup{}
err = compare.CompareSets(dbLbbgs, lbbgs, &removed, &commondb, &commonext, &added)
if err != nil {
syncResult.Error(err)
return nil, nil, syncResult
}
for i := 0; i < len(removed); i++ {
err = removed[i].syncRemoveCloudLoadbalancerBackendgroup(ctx, userCred)
if err != nil {
syncResult.DeleteError(err)
} else {
syncResult.Delete()
}
}
for i := 0; i < len(commondb); i++ {
err = commondb[i].SyncWithCloudLoadbalancerBackendgroup(ctx, userCred, lb, commonext[i], provider.GetOwnerId())
if err != nil {
syncResult.UpdateError(err)
} else {
syncMetadata(ctx, userCred, &commondb[i], commonext[i])
localLbgs = append(localLbgs, commondb[i])
remoteLbbgs = append(remoteLbbgs, commonext[i])
syncResult.Update()
}
}
for i := 0; i < len(added); i++ {
new, err := man.newFromCloudLoadbalancerBackendgroup(ctx, userCred, lb, added[i], syncOwnerId)
if err != nil {
syncResult.AddError(err)
} else {
syncMetadata(ctx, userCred, new, added[i])
localLbgs = append(localLbgs, *new)
remoteLbbgs = append(remoteLbbgs, added[i])
syncResult.Add()
}
}
return localLbgs, remoteLbbgs, syncResult
}
func (man *SQcloudCachedLbbgManager) newFromCloudLoadbalancerBackendgroup(ctx context.Context, userCred mcclient.TokenCredential, lb *SLoadbalancer, extLoadbalancerBackendgroup cloudprovider.ICloudLoadbalancerBackendGroup, syncOwnerId mcclient.IIdentityProvider) (*SQcloudCachedLbbg, error) {
LocalLbbg, err := newLocalBackendgroupFromCloudLoadbalancerBackendgroup(ctx, userCred, lb, extLoadbalancerBackendgroup, syncOwnerId)
if err != nil {
return nil, err
}
lbbg := &SQcloudCachedLbbg{}
lbbg.SetModelManager(man, lbbg)
lbbg.ManagerId = lb.ManagerId
lbbg.CloudregionId = lb.CloudregionId
lbbg.LoadbalancerId = lb.Id
lbbg.BackendGroupId = LocalLbbg.GetId()
lbbg.ExternalId = extLoadbalancerBackendgroup.GetGlobalId()
newName, err := db.GenerateName(man, syncOwnerId, LocalLbbg.GetName())
if err != nil {
return nil, err
}
lbbg.Name = newName
lbbg.Status = extLoadbalancerBackendgroup.GetStatus()
err = man.TableSpec().Insert(lbbg)
if err != nil {
return nil, err
}
SyncCloudProject(userCred, lbbg, syncOwnerId, extLoadbalancerBackendgroup, lb.ManagerId)
db.OpsLog.LogEvent(lbbg, db.ACT_CREATE, lbbg.GetShortDesc(ctx), userCred)
return lbbg, nil
}
+1 -1
View File
@@ -60,7 +60,7 @@ type IRegionDriver interface {
RequestCreateLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lbbg *SLoadbalancerBackendGroup, backends []cloudprovider.SLoadbalancerBackend, task taskman.ITask) error
RequestDeleteLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lbbg *SLoadbalancerBackendGroup, task taskman.ITask) error
ValidateDeleteLoadbalancerBackendGroupCondition(ctx context.Context, lbbb *SLoadbalancerBackendGroup) error
RequestSyncLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lblis *SLoadbalancerListener, lbbg *SLoadbalancerBackendGroup, task taskman.ITask) error
RequestSyncLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lblis *SLoadbalancerListener, task taskman.ITask) error
RequestPullRegionLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localRegion *SCloudregion, remoteRegion cloudprovider.ICloudRegion, syncRange *SSyncRange) error
RequestPullLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localLoadbalancer *SLoadbalancer, remoteLoadbalancer cloudprovider.ICloudLoadbalancer, syncRange *SSyncRange) error
GetBackendStatusForAdd() []string
+7 -1
View File
@@ -1327,7 +1327,13 @@ func (self *SAwsRegionDriver) RequestSyncLoadbalancerListener(ctx context.Contex
return nil
}
func (self *SAwsRegionDriver) RequestSyncLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, lbbg *models.SLoadbalancerBackendGroup, task taskman.ITask) error {
func (self *SAwsRegionDriver) RequestSyncLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error {
lbbg := lblis.GetLoadbalancerBackendGroup()
if lbbg == nil {
err := fmt.Errorf("failed to find lbbg for lblis %s", lblis.Name)
return errors.Wrap(err, "AwsRegionDriver.RequestSyncLoadbalancerBackendGroup.GetLoadbalancerBackendGroup")
}
lb := lblis.GetLoadbalancer()
if lb == nil {
return errors.Wrap(fmt.Errorf("listener %s related loadbalancer not found", lblis.GetId()), "AwsRegionDriver.RequestSyncLoadbalancerBackendGroup.GetLoadbalancer")
+7 -1
View File
@@ -862,8 +862,14 @@ func (self *SHuaWeiRegionDriver) removeCachedLbbg(ctx context.Context, userCred
return nil
}
func (self *SHuaWeiRegionDriver) RequestSyncLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, lbbg *models.SLoadbalancerBackendGroup, task taskman.ITask) error {
func (self *SHuaWeiRegionDriver) RequestSyncLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
lbbg := lblis.GetLoadbalancerBackendGroup()
if lbbg == nil {
err := fmt.Errorf("failed to find lbbg for lblis %s", lblis.Name)
return nil, errors.Wrap(err, "HuaWeiRegionDriver.RequestSyncLoadbalancerbackendGroup.GetLoadbalancerBackendGroup")
}
iRegion, err := lbbg.GetIRegion()
if err != nil {
return nil, err
+1 -1
View File
@@ -662,7 +662,7 @@ func (self *SKVMRegionDriver) RequestDeleteLoadbalancerAcl(ctx context.Context,
return nil
}
func (self *SKVMRegionDriver) RequestSyncLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, lbbg *models.SLoadbalancerBackendGroup, task taskman.ITask) error {
func (self *SKVMRegionDriver) RequestSyncLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error {
task.ScheduleRun(nil)
return nil
}
+1 -1
View File
@@ -548,7 +548,7 @@ func (self *SManagedVirtualizationRegionDriver) RequestDeleteLoadbalancerBackend
return nil
}
func (self *SManagedVirtualizationRegionDriver) RequestSyncLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, lbbg *models.SLoadbalancerBackendGroup, task taskman.ITask) error {
func (self *SManagedVirtualizationRegionDriver) RequestSyncLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error {
task.ScheduleRun(nil)
return nil
}
File diff suppressed because it is too large Load Diff
+2
View File
@@ -129,6 +129,8 @@ func InitHandlers(app *appsrv.Application) {
models.HuaweiCachedLbbgManager,
models.AwsCachedLbManager,
models.AwsCachedLbbgManager,
models.QcloudCachedLbManager,
models.QcloudCachedLbbgManager,
models.RouteTableManager,
models.SchedpolicyManager,
@@ -52,16 +52,10 @@ func (self *LoadbalancerListenerSyncTask) OnInit(ctx context.Context, obj db.ISt
return
}
lbbg := lblis.GetLoadbalancerBackendGroup()
if lbbg == nil {
self.taskFail(ctx, lblis, fmt.Sprintf("failed to find lbbg for lblis %s", lblis.Name))
return
}
self.SetStage("OnLoadbalancerBackendgroupSyncComplete", nil)
driver := region.GetDriver()
userCred := self.GetUserCred()
err := driver.RequestSyncLoadbalancerBackendGroup(ctx, userCred, lblis, lbbg, self)
err := driver.RequestSyncLoadbalancerBackendGroup(ctx, userCred, lblis, self)
if err != nil {
self.taskFail(ctx, lblis, err.Error())
}
+6 -1
View File
@@ -132,7 +132,7 @@ func (self *SLoadbalancer) GetILoadBalancerBackendGroupById(groupId string) (clo
func onecloudHealthCodeToQcloud(codes string) int {
qcode := 0
for i, code := range HTTP_CODES {
if strings.Contains(code, codes) {
if strings.Contains(codes, code) {
// 按位或然后再赋值qcode
qcode |= 1 << uint(i)
}
@@ -311,6 +311,11 @@ func (self *SLoadbalancer) GetILoadBalancerListeners() ([]cloudprovider.ICloudLo
}
func (self *SLoadbalancer) GetILoadBalancerBackendGroups() ([]cloudprovider.ICloudLoadbalancerBackendGroup, error) {
if self.Forward == LB_TYPE_CLASSIC {
bg := SLBBackendGroup{lb: self}
return []cloudprovider.ICloudLoadbalancerBackendGroup{&bg}, nil
}
listeners, err := self.GetLoadbalancerListeners("")
if err != nil {
return nil, err
@@ -29,7 +29,7 @@ import (
type SLBBackendGroup struct {
lb *SLoadbalancer // 必须不能为nil
listener *SLBListener // 必须不能为nil
listener *SLBListener // 能为nil
rule *SLBListenerRule // tcp、udp、tcp_ssl监听rule 为nil
}
@@ -57,6 +57,14 @@ func (self *SLBBackendGroup) GetStickySession() (*cloudprovider.SLoadbalancerSti
return nil, nil
}
func (self *SLBBackendGroup) GetListenerId() string {
if self.listener != nil {
return self.listener.GetId()
}
return ""
}
// 返回requestid
func (self *SLBBackendGroup) appLBBackendServer(action string, serverId string, weight int, port int) (string, error) {
if len(serverId) == 0 {
@@ -65,7 +73,7 @@ func (self *SLBBackendGroup) appLBBackendServer(action string, serverId string,
params := map[string]string{
"LoadBalancerId": self.lb.GetId(),
"ListenerId": self.listener.GetId(),
"ListenerId": self.GetListenerId(),
"Targets.0.InstanceId": serverId,
"Targets.0.Port": strconv.Itoa(port),
"Targets.0.Weight": strconv.Itoa(weight),
@@ -91,7 +99,7 @@ func (self *SLBBackendGroup) appLBSeventhBackendServer(action string, serverId s
params := map[string]string{
"loadBalancerId": self.lb.GetId(),
"listenerId": self.listener.GetId(),
"listenerId": self.GetListenerId(),
"backends.0.InstanceId": serverId,
"backends.0.Port": strconv.Itoa(port),
"backends.0.Weight": strconv.Itoa(weight),
@@ -117,7 +125,7 @@ func (self *SLBBackendGroup) updateBackendServerWeight(action string, serverId s
params := map[string]string{
"LoadBalancerId": self.lb.GetId(),
"ListenerId": self.listener.GetId(),
"ListenerId": self.GetListenerId(),
"Targets.0.InstanceId": serverId,
"Targets.0.Port": strconv.Itoa(port),
"Targets.0.Weight": strconv.Itoa(weight),
@@ -143,7 +151,7 @@ func (self *SLBBackendGroup) updateBackendServerPort(action string, serverId str
params := map[string]string{
"LoadBalancerId": self.lb.GetId(),
"ListenerId": self.listener.GetId(),
"ListenerId": self.GetListenerId(),
"Targets.0.InstanceId": serverId,
"Targets.0.Port": strconv.Itoa(oldPort),
"NewPort": strconv.Itoa(newPort),
@@ -221,8 +229,12 @@ func (self *SLBBackendGroup) AddBackendServer(serverId string, weight int, port
// https://cloud.tencent.com/document/product/214/30687
// https://cloud.tencent.com/document/product/214/31794
func (self *SLBBackendGroup) RemoveBackendServer(serverId string, weight int, port int) error {
_, err := self.lb.region.GetInstance(serverId)
if err == cloudprovider.ErrNotFound {
return nil
}
var requestId string
var err error
if self.lb.Forward == LB_TYPE_APPLICATION {
requestId, err = self.appLBBackendServer("DeregisterTargets", serverId, weight, port)
} else {
@@ -298,19 +310,23 @@ func (self *SLBBackendGroup) Sync(group *cloudprovider.SLoadbalancerBackendGroup
func backendGroupIdGen(lbid string, secondId string) string {
if len(secondId) > 0 {
return fmt.Sprintf("%s/%s", lbid, secondId)
return fmt.Sprintf("%s", secondId)
} else {
return lbid
}
}
func (self *SLBBackendGroup) GetId() string {
t := self.listener.GetListenerType()
t := ""
if self.listener != nil {
t = self.listener.GetListenerType()
}
if t == api.LB_LISTENER_TYPE_HTTP || t == api.LB_LISTENER_TYPE_HTTPS {
// http https 后端服务器只与规则绑定
return backendGroupIdGen(self.lb.GetId(), self.rule.GetId())
} else if self.lb.Forward == LB_TYPE_APPLICATION {
return backendGroupIdGen(self.lb.GetId(), self.listener.GetId())
return backendGroupIdGen(self.lb.GetId(), self.GetListenerId())
} else {
// 传统型lb 所有监听共用一个后端服务器组
return backendGroupIdGen(self.lb.GetId(), "")
@@ -383,13 +399,13 @@ func (self *SLBBackendGroup) GetBackends() ([]SLBBackend, error) {
var err error
if self.rule != nil {
// http、https监听
backends, err = self.lb.region.GetLBBackends(self.lb.Forward, self.lb.GetId(), self.listener.GetId(), self.rule.GetId())
backends, err = self.lb.region.GetLBBackends(self.lb.Forward, self.lb.GetId(), self.GetListenerId(), self.rule.GetId())
if err != nil {
return nil, err
}
} else {
// tcp,udp,tcp_ssl监听
backends, err = self.lb.region.GetLBBackends(self.lb.Forward, self.lb.GetId(), self.listener.GetId(), "")
backends, err = self.lb.region.GetLBBackends(self.lb.Forward, self.lb.GetId(), self.GetListenerId(), "")
if err != nil {
return nil, err
}
+48 -8
View File
@@ -88,12 +88,14 @@ func (self *SLBListener) GetBackendServerPort() int {
// https://cloud.tencent.com/document/product/214/30691
func (self *SLBListener) CreateILoadBalancerListenerRule(rule *cloudprovider.SLoadbalancerListenerRule) (cloudprovider.ICloudLoadbalancerListenerRule, error) {
hc := getListenerRuleHealthCheck(rule)
requestId, err := self.lb.region.CreateLoadbalancerListenerRule(self.lb.GetId(),
self.GetId(),
rule.Domain,
rule.Path,
&self.Scheduler,
&self.SessionExpireTime)
rule.Scheduler,
rule.StickySessionCookieTimeout,
hc)
if err != nil {
return nil, err
}
@@ -515,7 +517,7 @@ func (self *SRegion) GetLoadbalancerListeners(lbid string, t LB_TYPE, protocol s
}
// 返回requestID
func (self *SRegion) CreateLoadbalancerListenerRule(lbid string, listenerId string, domain string, url string, scheduler *string, sessionExpireTime *int) (string, error) {
func (self *SRegion) CreateLoadbalancerListenerRule(lbid string, listenerId string, domain string, url string, scheduler string, sessionExpireTime int, hc *healthCheck) (string, error) {
if len(lbid) == 0 {
return "", fmt.Errorf("loadbalancer id should not be empty")
}
@@ -527,12 +529,19 @@ func (self *SRegion) CreateLoadbalancerListenerRule(lbid string, listenerId stri
"Rules.0.Url": url,
}
if scheduler != nil && len(*scheduler) > 0 {
params["Rules.0.Scheduler"] = *scheduler
}
params["Rules.0.Scheduler"] = scheduler
params["Rules.0.SessionExpireTime"] = strconv.Itoa(sessionExpireTime)
if sessionExpireTime != nil {
params["Rules.0.SessionExpireTime"] = strconv.Itoa(*sessionExpireTime)
// health check
params["Rules.0.HealthCheck.HealthSwitch"] = strconv.Itoa(hc.HealthSwitch)
params["Rules.0.HealthCheck.IntervalTime"] = strconv.Itoa(hc.IntervalTime)
params["Rules.0.HealthCheck.HealthNum"] = strconv.Itoa(hc.HealthNum)
params["Rules.0.HealthCheck.UnHealthNum"] = strconv.Itoa(hc.UnHealthNum)
if hc.HTTPCode > 0 {
params["Rules.0.HealthCheck.HttpCode"] = strconv.Itoa(hc.HTTPCode)
params["Rules.0.HealthCheck.HttpCheckPath"] = hc.HTTPCheckPath
params["Rules.0.HealthCheck.HttpCheckDomain"] = hc.HTTPCheckDomain
params["Rules.0.HealthCheck.HttpCheckMethod"] = hc.HTTPCheckMethod
}
resp, err := self.clbRequest("CreateRule", params)
@@ -706,6 +715,37 @@ func getHealthCheck(listener *cloudprovider.SLoadbalancerListener) *healthCheck
return hc
}
func getListenerRuleHealthCheck(rule *cloudprovider.SLoadbalancerListenerRule) *healthCheck {
var hc *healthCheck
if rule.HealthCheck == api.LB_BOOL_ON {
hc = &healthCheck{
HealthSwitch: 1,
UnHealthNum: rule.HealthCheckFail,
IntervalTime: rule.HealthCheckInterval,
HealthNum: rule.HealthCheckRise,
TimeOut: rule.HealthCheckTimeout,
}
httpCode := onecloudHealthCodeToQcloud(rule.HealthCheckHttpCode)
if httpCode > 0 {
hc.HTTPCode = httpCode
hc.HTTPCheckMethod = "HEAD" // todo: add column HttpCheckMethod in model
hc.HTTPCheckDomain = rule.HealthCheckDomain
hc.HTTPCheckPath = rule.HealthCheckURI
}
} else {
hc = &healthCheck{
HealthSwitch: 0,
UnHealthNum: 3,
IntervalTime: 5,
HealthNum: 3,
TimeOut: 2,
}
}
return hc
}
func getCertificate(listener *cloudprovider.SLoadbalancerListener) *certificate {
var cert *certificate
if len(listener.CertificateID) > 0 {