mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-21 14:19:49 +08:00
Merge pull request #5145 from tb365/bugfix/tb-elb-bugfix-0114
qcloud elb sync
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
+615
-330
File diff suppressed because it is too large
Load Diff
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user