fix(region): support lb health check (#23009)

This commit is contained in:
屈轩
2025-08-01 18:38:41 +08:00
committed by GitHub
parent 33936c937c
commit 52d54cfc00
45 changed files with 1225 additions and 63 deletions
@@ -0,0 +1,30 @@
// 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 compute
import (
"yunion.io/x/onecloud/cmd/climc/shell"
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
options "yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
cmd := shell.NewResourceCmd(&modules.LoadbalancerHealthChecks).WithKeyword("lb-health-check")
cmd.List(&options.LoadbalancerHealthCheckListOptions{})
cmd.Show(&options.LoadbalancerHealthCheckIdOptions{})
cmd.Create(&options.LoadbalancerHealthCheckCreateOptions{})
cmd.Delete(&options.LoadbalancerHealthCheckIdOptions{})
cmd.Update(&options.LoadbalancerHealthCheckUpdateOptions{})
}
+1 -1
View File
@@ -96,7 +96,7 @@ require (
k8s.io/cri-api v0.22.17
k8s.io/klog/v2 v2.20.0
moul.io/http2curl/v2 v2.3.0
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250730103446-8b50657aec9f
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250801094033-0d3c2f9a0e80
yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0
yunion.io/x/jsonutils v1.0.1-0.20250507052344-1abcf4f443b1
yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91
+2 -2
View File
@@ -1408,8 +1408,8 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250730103446-8b50657aec9f h1:dSJnDY8bp5wDt3egbszpWtipjGTacjHDsI7p3xi3bg4=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250730103446-8b50657aec9f/go.mod h1:FXxAEbdNfWXX9gjME3K2nJhkydHY5EKEUZb+RLEzVwQ=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250801094033-0d3c2f9a0e80 h1:Y+jCUi+/5kxjjzPVyQ0TagxLEksMfEeFhVQa7hFznrI=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250801094033-0d3c2f9a0e80/go.mod h1:FXxAEbdNfWXX9gjME3K2nJhkydHY5EKEUZb+RLEzVwQ=
yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0 h1:msG4SiDSVU7CrXH06WuHlNEZXIooTcmNbfrIGHuIHBU=
yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
@@ -0,0 +1,61 @@
// 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 compute
import (
"yunion.io/x/onecloud/pkg/apis"
)
type LoadbalancerHealthCheckDetails struct {
apis.VirtualResourceDetails
ManagedResourceInfo
CloudregionResourceInfo
}
type LoadbalancerHealthCheckListInput struct {
apis.VirtualResourceListInput
apis.ExternalizedResourceBaseListInput
ManagedResourceListInput
RegionalFilterListInput
}
type SLoadbalancerHealthCheckCreateInput struct {
apis.VirtualResourceCreateInput
CloudregionResourceInput
CloudproviderResourceInput
HealthCheckType string
HealthCheckDomain string
HealthCheckURI string
HealthCheckHttpCode string
HealthCheckMethod string
HealthCheckPort int
HealthCheckRise int
HealthCheckFall int
HealthCheckTimeout int
HealthCheckInterval int
HealthCheckReq string
HealthCheckExp string
}
type SLoadbalancerHealthCheckUpdateInput struct {
apis.VirtualResourceBaseUpdateInput
}
+3 -1
View File
@@ -69,7 +69,9 @@ type LoadbalancerBackendGroupCreateInput struct {
//swagger: ignore
Loadbalancer string `json:"loadbalancer" yunion-deprecated-by:"loadbalancer_id"`
// 负载均衡ID
LoadbalancerId string `json:"loadbalancer_id"`
LoadbalancerId string `json:"loadbalancer_id"`
Scheduler string `json:"scheduler"`
LoadbalancerHealthCheckId string `json:"loadbalancer_health_check_id"`
Type string `json:"type"`
+3
View File
@@ -2348,6 +2348,9 @@ func syncPublicCloudProviderInfo(
if syncRange.IsNotSkipSyncResource(LoadbalancerCertificateManager) {
syncRegionLoadbalancerCertificates(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange)
}
if syncRange.IsNotSkipSyncResource(LoadbalancerHealthCheckManager) {
syncRegionLoadbalancerHealthChecks(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange)
}
if syncRange.IsNotSkipSyncResource(LoadbalancerManager) {
syncRegionLoadbalancers(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange)
}
+32
View File
@@ -60,6 +60,38 @@ func syncRegionLoadbalancerCertificates(
}
}
func syncRegionLoadbalancerHealthChecks(
ctx context.Context,
userCred mcclient.TokenCredential,
syncResults SSyncResultSet,
provider *SCloudprovider,
localRegion *SCloudregion,
remoteRegion cloudprovider.ICloudRegion,
syncRange *SSyncRange,
) {
healthChecks, err := func() ([]cloudprovider.ICloudLoadbalancerHealthCheck, error) {
defer syncResults.AddRequestCost(LoadbalancerHealthCheckManager)()
return remoteRegion.GetILoadBalancerHealthChecks()
}()
if err != nil {
msg := fmt.Sprintf("GetILoadBalancerHealthChecks for region %s failed %s", remoteRegion.GetName(), err)
log.Errorln(msg)
return
}
result := func() compare.SyncResult {
defer syncResults.AddSqlCost(LoadbalancerHealthCheckManager)()
return localRegion.SyncLoadbalancerHealthChecks(ctx, userCred, provider, healthChecks)
}()
syncResults.Add(LoadbalancerHealthCheckManager, result)
msg := result.Result()
log.Infof("SyncLoadbalancerHealthChecks for region %s result: %s", localRegion.Name, msg)
if result.IsError() {
return
}
}
func syncRegionLoadbalancerAcls(
ctx context.Context,
userCred mcclient.TokenCredential,
@@ -0,0 +1,433 @@
// 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"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/sqlchemy"
"yunion.io/x/onecloud/pkg/apis"
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/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
// +onecloud:swagger-gen-model-singular=loadbalancer_health_check
// +onecloud:swagger-gen-model-plural=loadbalancerhealthchecks
type SLoadbalancerHealthCheckManager struct {
SLoadbalancerLogSkipper
db.SVirtualResourceBaseManager
db.SExternalizedResourceBaseManager
SManagedResourceBaseManager
SCloudregionResourceBaseManager
}
var LoadbalancerHealthCheckManager *SLoadbalancerHealthCheckManager
func init() {
LoadbalancerHealthCheckManager = &SLoadbalancerHealthCheckManager{
SVirtualResourceBaseManager: db.NewVirtualResourceBaseManager(
SLoadbalancerHealthCheck{},
"loadbalancer_health_checks_tbl",
"loadbalancer_health_check",
"loadbalancer_health_checks",
),
}
LoadbalancerHealthCheckManager.SetVirtualObject(LoadbalancerHealthCheckManager)
}
type SLoadbalancerHealthCheck struct {
db.SVirtualResourceBase
db.SExternalizedResourceBase
SManagedResourceBase
SCloudregionResourceBase
SLoadbalancerHealthChecker
}
// 健康检查列表
func (man *SLoadbalancerHealthCheckManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.LoadbalancerHealthCheckListInput,
) (*sqlchemy.SQuery, error) {
q, err := man.SVirtualResourceBaseManager.ListItemFilter(ctx, q, userCred, query.VirtualResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SVirtualResourceBaseManager.ListItemFilter")
}
q, err = man.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
}
q, err = man.SManagedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemFilter")
}
q, err = man.SCloudregionResourceBaseManager.ListItemFilter(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemFilter")
}
return q, nil
}
func (man *SLoadbalancerHealthCheckManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.LoadbalancerHealthCheckListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = man.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
}
q, err = man.SCloudregionResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (man *SLoadbalancerHealthCheckManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = man.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = man.SCloudregionResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (man *SLoadbalancerHealthCheckManager) ValidateCreateData(
ctx context.Context,
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
query jsonutils.JSONObject,
input *api.SLoadbalancerHealthCheckCreateInput,
) (*api.SLoadbalancerHealthCheckCreateInput, error) {
var err error
input.VirtualResourceCreateInput, err = man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.VirtualResourceCreateInput)
if err != nil {
return nil, errors.Wrap(err, "SVirtualResourceBaseManager.ValidateCreateData")
}
input.Status = apis.STATUS_CREATING
regionObj, err := validators.ValidateModel(ctx, userCred, CloudregionManager, &input.CloudregionId)
if err != nil {
return nil, err
}
region := regionObj.(*SCloudregion)
if len(input.CloudproviderId) > 0 {
providerObj, err := validators.ValidateModel(ctx, userCred, CloudproviderManager, &input.CloudproviderId)
if err != nil {
return nil, err
}
input.ManagerId = input.CloudproviderId
provider := providerObj.(*SCloudprovider)
if provider.Provider != region.Provider {
return nil, httperrors.NewConflictError("conflict region %s and cloudprovider %s", region.Name, provider.Name)
}
}
return input, nil
}
func (hc *SLoadbalancerHealthCheck) ValidateUpdateData(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
input *api.SLoadbalancerHealthCheckUpdateInput,
) (*api.SLoadbalancerHealthCheckUpdateInput, error) {
var err error
input.VirtualResourceBaseUpdateInput, err = hc.SVirtualResourceBase.ValidateUpdateData(ctx, userCred, query, input.VirtualResourceBaseUpdateInput)
if err != nil {
return nil, errors.Wrap(err, "SVirtualResourceBase.ValidateUpdateData")
}
return nil, cloudprovider.ErrNotImplemented
}
func (hc *SLoadbalancerHealthCheck) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) {
hc.SVirtualResourceBase.PostUpdate(ctx, userCred, query, data)
keys, _ := jsonutils.Marshal(SLoadbalancerHealthChecker{}).(*jsonutils.JSONDict).GetMap()
needUpdate := false
for key := range keys {
if data.Contains(key) {
needUpdate = true
break
}
}
if needUpdate {
hc.StartLoadBalancerHealthCheckUpdateTask(ctx, userCred, "")
}
}
func (hc *SLoadbalancerHealthCheck) StartLoadBalancerHealthCheckUpdateTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
hc.SetStatus(ctx, userCred, api.LB_SYNC_CONF, "")
task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerHealthCheckUpdateTask", hc, userCred, nil, parentTaskId, "", nil)
if err != nil {
return err
}
return task.ScheduleRun(nil)
}
func (hc *SLoadbalancerHealthCheck) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
hc.SVirtualResourceBase.PostCreate(ctx, userCred, ownerId, query, data)
hc.SetStatus(ctx, userCred, api.LB_CREATING, "")
err := hc.StartLoadBalancerHealthCheckCreateTask(ctx, userCred, "")
if err != nil {
log.Errorf("Failed to create loadbalancer backend error: %v", err)
}
}
func (manager *SLoadbalancerHealthCheckManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.LoadbalancerHealthCheckDetails {
rows := make([]api.LoadbalancerHealthCheckDetails, len(objs))
stdRows := manager.SVirtualResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
managerRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
regionRows := manager.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.LoadbalancerHealthCheckDetails{
VirtualResourceDetails: stdRows[i],
ManagedResourceInfo: managerRows[i],
CloudregionResourceInfo: regionRows[i],
}
}
return rows
}
func (hc *SLoadbalancerHealthCheck) StartLoadBalancerHealthCheckCreateTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerHealthCheckCreateTask", hc, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
return task.ScheduleRun(nil)
}
func (hc *SLoadbalancerHealthCheck) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (hc *SLoadbalancerHealthCheck) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return hc.SVirtualResourceBase.Delete(ctx, userCred)
}
func (hc *SLoadbalancerHealthCheck) GetIRegion(ctx context.Context) (cloudprovider.ICloudRegion, error) {
region, err := hc.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
provider, err := hc.GetDriver(ctx)
if err != nil {
return nil, errors.Wrapf(err, "GetDriver")
}
return provider.GetIRegionById(region.ExternalId)
}
func (hc *SLoadbalancerHealthCheck) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
hc.SetStatus(ctx, userCred, api.LB_STATUS_DELETING, "")
return hc.StartLoadBalancerHealthCheckDeleteTask(ctx, userCred, jsonutils.NewDict(), "")
}
func (hc *SLoadbalancerHealthCheck) StartLoadBalancerHealthCheckDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerHealthCheckDeleteTask", hc, userCred, params, parentTaskId, "", nil)
if err != nil {
return err
}
return task.ScheduleRun(nil)
}
func (region *SCloudregion) GetLoadbalancerHealthChecks(managerId string) ([]SLoadbalancerHealthCheck, error) {
q := LoadbalancerHealthCheckManager.Query().Equals("manager_id", managerId).Equals("cloudregion_id", region.Id)
ret := []SLoadbalancerHealthCheck{}
err := db.FetchModelObjects(LoadbalancerHealthCheckManager, q, &ret)
if err != nil {
return nil, errors.Wrap(err, "FetchModelObjects")
}
return ret, nil
}
func (region *SCloudregion) SyncLoadbalancerHealthChecks(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, exts []cloudprovider.ICloudLoadbalancerHealthCheck) compare.SyncResult {
lockman.LockRawObject(ctx, LoadbalancerHealthCheckManager.Keyword(), region.Id)
defer lockman.ReleaseRawObject(ctx, LoadbalancerHealthCheckManager.Keyword(), region.Id)
result := compare.SyncResult{}
dbRes, err := region.GetLoadbalancerHealthChecks(provider.Id)
if err != nil {
result.Error(err)
return result
}
removed := []SLoadbalancerHealthCheck{}
commondb := []SLoadbalancerHealthCheck{}
commonext := []cloudprovider.ICloudLoadbalancerHealthCheck{}
added := []cloudprovider.ICloudLoadbalancerHealthCheck{}
err = compare.CompareSets(dbRes, exts, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(err)
return result
}
for i := 0; i < len(removed); i++ {
err = removed[i].syncRemove(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i++ {
err = commondb[i].SyncWithCloudLoadbalancerHealthCheck(ctx, userCred, commonext[i], provider)
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
for i := 0; i < len(added); i++ {
err := region.newFromCloudLoadbalancerHealthCheck(ctx, userCred, added[i], provider)
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
func (hc *SLoadbalancerHealthCheck) SyncWithCloudLoadbalancerHealthCheck(
ctx context.Context,
userCred mcclient.TokenCredential,
ext cloudprovider.ICloudLoadbalancerHealthCheck,
provider *SCloudprovider,
) error {
diff, err := db.UpdateWithLock(ctx, hc, func() error {
hc.HealthCheck = ext.GetHealthCheck()
hc.HealthCheckType = ext.GetHealthCheckType()
hc.HealthCheckDomain = ext.GetHealthCheckDomain()
hc.HealthCheckURI = ext.GetHealthCheckURI()
hc.HealthCheckHttpCode = ext.GetHealthCheckCode()
hc.HealthCheckMethod = ext.GetHealthCheckMethod()
hc.HealthCheckPort = ext.GetHealthCheckPort()
hc.HealthCheckRise = ext.GetHealthCheckRise()
hc.HealthCheckFall = ext.GetHealthCheckFail()
hc.HealthCheckTimeout = ext.GetHealthCheckTimeout()
hc.HealthCheckInterval = ext.GetHealthCheckInterval()
hc.HealthCheckReq = ext.GetHealthCheckReq()
hc.HealthCheckExp = ext.GetHealthCheckExp()
return nil
})
if err != nil {
return err
}
syncVirtualResourceMetadata(ctx, userCred, hc, ext, false)
SyncCloudProject(ctx, userCred, hc, provider.GetOwnerId(), ext, provider)
if len(diff) > 0 {
db.OpsLog.LogSyncUpdate(hc, diff, userCred)
}
return nil
}
func (region *SCloudregion) newFromCloudLoadbalancerHealthCheck(
ctx context.Context,
userCred mcclient.TokenCredential,
ext cloudprovider.ICloudLoadbalancerHealthCheck,
provider *SCloudprovider,
) error {
hc := &SLoadbalancerHealthCheck{}
hc.SetModelManager(LoadbalancerHealthCheckManager, hc)
hc.Name = ext.GetName()
hc.Status = ext.GetStatus()
hc.ManagerId = provider.Id
hc.CloudregionId = region.Id
hc.ExternalId = ext.GetGlobalId()
hc.HealthCheck = ext.GetHealthCheck()
hc.HealthCheckType = ext.GetHealthCheckType()
hc.HealthCheckDomain = ext.GetHealthCheckDomain()
hc.HealthCheckURI = ext.GetHealthCheckURI()
hc.HealthCheckHttpCode = ext.GetHealthCheckCode()
hc.HealthCheckMethod = ext.GetHealthCheckMethod()
hc.HealthCheckPort = ext.GetHealthCheckPort()
hc.HealthCheckRise = ext.GetHealthCheckRise()
hc.HealthCheckFall = ext.GetHealthCheckFail()
hc.HealthCheckTimeout = ext.GetHealthCheckTimeout()
hc.HealthCheckInterval = ext.GetHealthCheckInterval()
hc.HealthCheckReq = ext.GetHealthCheckReq()
hc.HealthCheckExp = ext.GetHealthCheckExp()
hc.DomainId = provider.DomainId
hc.ProjectId = provider.ProjectId
err := LoadbalancerHealthCheckManager.TableSpec().Insert(ctx, hc)
if err != nil {
return errors.Wrap(err, "Insert")
}
syncVirtualResourceMetadata(ctx, userCred, hc, ext, false)
SyncCloudProject(ctx, userCred, hc, provider.GetOwnerId(), ext, provider)
return nil
}
func (hc *SLoadbalancerHealthCheck) syncRemove(ctx context.Context, userCred mcclient.TokenCredential) error {
lockman.LockObject(ctx, hc)
defer lockman.ReleaseObject(ctx, hc)
return hc.RealDelete(ctx, userCred)
}
func (manager *SLoadbalancerHealthCheckManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SVirtualResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SVirtualResourceBaseManager.ListItemExportKeys")
}
return q, nil
}
@@ -68,6 +68,8 @@ type SLoadbalancerBackendGroup struct {
db.SExternalizedResourceBase
SLoadbalancerResourceBase `width:"36" charset:"ascii" nullable:"true" list:"user" create:"optional"`
LoadbalancerHealthCheckId string `width:"36" charset:"ascii" nullable:"true" list:"user" create:"optional"`
Scheduler string `width:"36" charset:"ascii" nullable:"true" list:"user" create:"optional"`
Type string `width:"36" charset:"ascii" nullable:"false" list:"user" default:"normal" create:"optional"`
}
@@ -220,6 +222,12 @@ func (man *SLoadbalancerBackendGroupManager) ValidateCreateData(ctx context.Cont
if err != nil {
return nil, err
}
if len(input.LoadbalancerHealthCheckId) > 0 {
_, err := validators.ValidateModel(ctx, userCred, LoadbalancerHealthCheckManager, &input.LoadbalancerHealthCheckId)
if err != nil {
return nil, err
}
}
region, err := lb.GetRegion()
if err != nil {
@@ -712,6 +720,15 @@ func (lbbg *SLoadbalancerBackendGroup) SyncWithCloudLoadbalancerBackendgroup(
diff, err := db.UpdateWithLock(ctx, lbbg, func() error {
lbbg.Type = ext.GetType()
lbbg.Status = ext.GetStatus()
lbbg.Scheduler = ext.GetScheduler()
if hcId := ext.GetHealthCheckId(); hcId != "" {
hc, err := db.FetchByExternalIdAndManagerId(LoadbalancerHealthCheckManager, hcId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
return q.Equals("manager_id", lb.ManagerId)
})
if err == nil {
lbbg.LoadbalancerHealthCheckId = hc.GetId()
}
}
return nil
})
if err != nil {
@@ -755,7 +772,16 @@ func (lb *SLoadbalancer) newFromCloudLoadbalancerBackendgroup(
lbbg.Type = ext.GetType()
lbbg.Status = ext.GetStatus()
lbbg.Scheduler = ext.GetScheduler()
lbbg.Name = ext.GetName()
if hcId := ext.GetHealthCheckId(); hcId != "" {
hc, err := db.FetchByExternalIdAndManagerId(LoadbalancerHealthCheckManager, hcId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
return q.Equals("manager_id", lb.ManagerId)
})
if err == nil {
lbbg.LoadbalancerHealthCheckId = hc.GetId()
}
}
err := LoadbalancerBackendGroupManager.TableSpec().Insert(ctx, lbbg)
if err != nil {
@@ -781,6 +807,14 @@ func (lb *SLoadbalancer) newFromCloudLoadbalancerBackendgroup(
return lbbg, nil
}
func (lbbg *SLoadbalancerBackendGroup) GetHealthCheck() (*SLoadbalancerHealthCheck, error) {
obj, err := db.FetchById(LoadbalancerHealthCheckManager, lbbg.LoadbalancerHealthCheckId)
if err != nil {
return nil, errors.Wrap(err, "FetchById")
}
return obj.(*SLoadbalancerHealthCheck), nil
}
func (manager *SLoadbalancerBackendGroupManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
@@ -84,7 +84,7 @@ type SLoadbalancerListenerRule struct {
RedirectPool *api.ListenerRuleRedirectPool `list:"user" update:"user" create:"optional"`
SLoadbalancerHealthCheck // 目前只有腾讯云HTTP、HTTPS类型的健康检查是和规则绑定的。
SLoadbalancerHealthChecker // 目前只有腾讯云HTTP、HTTPS类型的健康检查是和规则绑定的。
SLoadbalancerHTTPRateLimiter
SLoadbalancerHTTPRedirect
}
+62 -30
View File
@@ -66,29 +66,46 @@ func init() {
}
type SLoadbalancerHTTPRateLimiter struct {
HTTPRequestRate int `nullable:"true" list:"user" create:"optional" update:"user"` // 限定监听接收请示速率
HTTPRequestRatePerSrc int `nullable:"true" list:"user" create:"optional" update:"user"` // 源IP监听请求最大速率
// 限定监听接收请示速率
HTTPRequestRate int `nullable:"true" list:"user" create:"optional" update:"user"`
// 源IP监听请求最大速率
HTTPRequestRatePerSrc int `nullable:"true" list:"user" create:"optional" update:"user"`
}
type SLoadbalancerRateLimiter struct {
EgressMbps int `nullable:"true" list:"user" get:"user" create:"optional" update:"user" json:"egress_mbps"`
}
type SLoadbalancerHealthCheck struct {
HealthCheck string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional" update:"user"` // 健康检查开启状态 on|off
HealthCheckType string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional" update:"user"` // 健康检查协议 HTTP|TCP
type SLoadbalancerHealthChecker struct {
// 健康检查开启状态 on|off
HealthCheck string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional" update:"user"`
// 健康检查协议 HTTP|TCP
HealthCheckType string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional" update:"user"`
HealthCheckDomain string `charset:"ascii" nullable:"true" list:"user" create:"optional" update:"user"` // 健康检查域名 yunion.cn
HealthCheckURI string `charset:"ascii" nullable:"true" list:"user" create:"optional" update:"user"` // 健康检查路径 /
HealthCheckHttpCode string `charset:"ascii" nullable:"true" list:"user" create:"optional" update:"user"` // HTTP正常状态码 http_2xx,http_3xx
// 健康检查域名 yunion.cn
HealthCheckDomain string `charset:"ascii" nullable:"true" list:"user" create:"optional" update:"user"`
// 健康检查路径 /
HealthCheckURI string `charset:"ascii" nullable:"true" list:"user" create:"optional" update:"user"`
// HTTP正常状态码 http_2xx,http_3xx
HealthCheckHttpCode string `charset:"ascii" nullable:"true" list:"user" create:"optional" update:"user"`
// 健康检查方法 GET|POST|HEAD
HealthCheckMethod string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional" update:"user"`
// 健康检查端口 80
HealthCheckPort int `nullable:"true" list:"user" create:"optional" update:"user"`
HealthCheckRise int `nullable:"true" list:"user" create:"optional" update:"user"` // 健康检查健康阈值 3秒
HealthCheckFall int `nullable:"true" list:"user" create:"optional" update:"user"` // 健康检查不健康阈值 15秒
HealthCheckTimeout int `nullable:"true" list:"user" create:"optional" update:"user"` // 健康检查超时时间 10
HealthCheckInterval int `nullable:"true" list:"user" create:"optional" update:"user"` // 健康检查间隔时间 5秒
// 健康检查健康阈值 3秒
HealthCheckRise int `nullable:"true" list:"user" create:"optional" update:"user"`
// 健康检查不健康阈值 15
HealthCheckFall int `nullable:"true" list:"user" create:"optional" update:"user"`
// 健康检查超时时间 10秒
HealthCheckTimeout int `nullable:"true" list:"user" create:"optional" update:"user"`
// 健康检查间隔时间 5秒
HealthCheckInterval int `nullable:"true" list:"user" create:"optional" update:"user"`
HealthCheckReq string `list:"user" create:"optional" update:"user"` // UDP监听健康检查的请求串
HealthCheckExp string `list:"user" create:"optional" update:"user"` // UDP监听健康检查的响应串
// UDP监听健康检查的请求串
HealthCheckReq string `list:"user" create:"optional" update:"user"`
// UDP监听健康检查的响应串
HealthCheckExp string `list:"user" create:"optional" update:"user"`
}
type SLoadbalancerTCPListener struct{}
@@ -96,21 +113,32 @@ type SLoadbalancerUDPListener struct{}
// TODO sensible default for knobs
type SLoadbalancerHTTPListener struct {
StickySession string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional" update:"user"` // 会话保持开启状态 on|off
StickySessionType string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional" update:"user"` // Cookie处理方式 insert(植入cookie)|server(重写cookie)
StickySessionCookie string `width:"128" charset:"ascii" nullable:"true" list:"user" create:"optional" update:"user"` // Cookie名称
StickySessionCookieTimeout int `nullable:"true" list:"user" create:"optional" update:"user"` // 会话超时时间
// 会话保持开启状态 on|off
StickySession string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional" update:"user"`
// Cookie处理方式 insert(植入cookie)|server(重写cookie)
StickySessionType string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional" update:"user"`
// Cookie名称
StickySessionCookie string `width:"128" charset:"ascii" nullable:"true" list:"user" create:"optional" update:"user"`
// 会话超时时间
StickySessionCookieTimeout int `nullable:"true" list:"user" create:"optional" update:"user"`
XForwardedFor bool `nullable:"true" list:"user" create:"optional" update:"user"` // 获取客户端真实IP
Gzip bool `nullable:"true" list:"user" create:"optional" update:"user"` // Gzip数据压缩
// 获取客户端真实IP
XForwardedFor bool `nullable:"true" list:"user" create:"optional" update:"user"`
// Gzip数据压缩
Gzip bool `nullable:"true" list:"user" create:"optional" update:"user"`
}
type SLoadbalancerHTTPRedirect struct {
Redirect string `width:"16" nullable:"true" list:"user" create:"optional" update:"user" default:"off"` // 跳转类型
RedirectCode int `nullable:"true" list:"user" create:"optional" update:"user"` // 跳转HTTP code
RedirectScheme string `width:"16" nullable:"true" list:"user" create:"optional" update:"user"` // 跳转uri scheme
RedirectHost string `nullable:"true" list:"user" create:"optional" update:"user"` // 跳转时变更Host
RedirectPath string `nullable:"true" list:"user" create:"optional" update:"user"` // 跳转时变更Path
// 跳转类型
Redirect string `width:"16" nullable:"true" list:"user" create:"optional" update:"user" default:"off"`
// 跳转HTTP code
RedirectCode int `nullable:"true" list:"user" create:"optional" update:"user"`
// 跳转uri scheme
RedirectScheme string `width:"16" nullable:"true" list:"user" create:"optional" update:"user"`
// 跳转时变更Host
RedirectHost string `nullable:"true" list:"user" create:"optional" update:"user"`
// 跳转时变更Path
RedirectPath string `nullable:"true" list:"user" create:"optional" update:"user"`
}
// TODO
@@ -141,10 +169,14 @@ type SLoadbalancerListener struct {
SendProxy string `width:"16" charset:"ascii" nullable:"false" list:"user" create:"optional" update:"user" default:"off"`
ClientRequestTimeout int `nullable:"true" list:"user" create:"optional" update:"user"` // 连接请求超时时间
ClientIdleTimeout int `nullable:"true" list:"user" create:"optional" update:"user"` // 连接空闲超时时间
BackendConnectTimeout int `nullable:"true" list:"user" create:"optional" update:"user"` // 后端连接超时时间
BackendIdleTimeout int `nullable:"true" list:"user" create:"optional" update:"user"` // 后端连接空闲时间
// 连接请求超时时间
ClientRequestTimeout int `nullable:"true" list:"user" create:"optional" update:"user"`
// 连接空闲超时时间
ClientIdleTimeout int `nullable:"true" list:"user" create:"optional" update:"user"`
// 后端连接超时时间
BackendConnectTimeout int `nullable:"true" list:"user" create:"optional" update:"user"`
// 后端连接空闲时间
BackendIdleTimeout int `nullable:"true" list:"user" create:"optional" update:"user"`
AclStatus string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional" update:"user"`
AclType string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional" update:"user"`
@@ -157,7 +189,7 @@ type SLoadbalancerListener struct {
SLoadbalancerHTTPListener
SLoadbalancerHTTPSListener
SLoadbalancerHealthCheck
SLoadbalancerHealthChecker
SLoadbalancerHTTPRateLimiter
SLoadbalancerHTTPRedirect
}
@@ -472,8 +472,12 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateLoadbalancerBackend
group := &cloudprovider.SLoadbalancerBackendGroup{
Name: lbbg.Name,
GroupType: lbbg.Type,
Scheduler: lbbg.Scheduler,
Backends: []cloudprovider.SLoadbalancerBackend{},
}
if hc, err := lbbg.GetHealthCheck(); err == nil {
group.HealthCheckId = hc.ExternalId
}
backends, err := lbbg.GetBackends()
if err != nil {
return nil, errors.Wrapf(err, "GetBackends")
+1
View File
@@ -160,6 +160,7 @@ func InitHandlers(app *appsrv.Application) {
models.LoadbalancerAclManager,
models.LoadbalancerAgentManager,
models.LoadbalancerClusterManager,
models.LoadbalancerHealthCheckManager,
models.RouteTableManager,
models.RouteTableAssociationManager,
models.RouteTableRouteSetManager,
@@ -0,0 +1,88 @@
// 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 loadbalancer
import (
"context"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/apis"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type LoadbalancerHealthCheckCreateTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(LoadbalancerHealthCheckCreateTask{})
}
func (self *LoadbalancerHealthCheckCreateTask) taskFail(ctx context.Context, hc *models.SLoadbalancerHealthCheck, err error) {
hc.SetStatus(ctx, self.GetUserCred(), api.LB_CREATE_FAILED, err.Error())
db.OpsLog.LogEvent(hc, db.ACT_ALLOCATE_FAIL, err, self.UserCred)
logclient.AddActionLogWithStartable(self, hc, logclient.ACT_CREATE, err, self.UserCred, false)
notifyclient.NotifySystemErrorWithCtx(ctx, hc.Id, hc.Name, api.LB_CREATE_FAILED, err.Error())
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *LoadbalancerHealthCheckCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
hc := obj.(*models.SLoadbalancerHealthCheck)
iRegion, err := hc.GetIRegion(ctx)
if err != nil {
self.taskFail(ctx, hc, errors.Wrapf(err, "GetIRegion"))
return
}
opts := &cloudprovider.SLoadbalancerHealthCheck{
Name: hc.Name,
HealthCheckType: hc.HealthCheckType,
HealthCheckDomain: hc.HealthCheckDomain,
HealthCheckURI: hc.HealthCheckURI,
HealthCheckHttpCode: hc.HealthCheckHttpCode,
HealthCheckMethod: hc.HealthCheckMethod,
HealthCheckPort: hc.HealthCheckPort,
HealthCheckTimeout: hc.HealthCheckTimeout,
HealthCheckInterval: hc.HealthCheckInterval,
HealthCheckRise: hc.HealthCheckRise,
HealthCheckReq: hc.HealthCheckReq,
HealthCheckExp: hc.HealthCheckExp,
}
iHc, err := iRegion.CreateILoadBalancerHealthCheck(opts)
if err != nil {
self.taskFail(ctx, hc, errors.Wrapf(err, "CreateILoadBalancerHealthCheck"))
return
}
_, err = db.Update(hc, func() error {
hc.ExternalId = iHc.GetGlobalId()
hc.Status = apis.STATUS_AVAILABLE
return nil
})
if err != nil {
self.taskFail(ctx, hc, errors.Wrapf(err, "Update"))
}
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,80 @@
// 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 loadbalancer
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type LoadbalancerHealthCheckDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(LoadbalancerHealthCheckDeleteTask{})
}
func (self *LoadbalancerHealthCheckDeleteTask) taskFail(ctx context.Context, hc *models.SLoadbalancerHealthCheck, err error) {
hc.SetStatus(ctx, self.GetUserCred(), api.LB_STATUS_DELETE_FAILED, err.Error())
db.OpsLog.LogEvent(hc, db.ACT_DELOCATE_FAIL, err.Error(), self.UserCred)
logclient.AddActionLogWithStartable(self, hc, logclient.ACT_DELOCATE, err.Error(), self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *LoadbalancerHealthCheckDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
hc := obj.(*models.SLoadbalancerHealthCheck)
if len(hc.ExternalId) == 0 {
self.taskComplete(ctx, hc)
return
}
iRegion, err := hc.GetIRegion(ctx)
if err != nil {
self.taskFail(ctx, hc, errors.Wrapf(err, "GetIRegion"))
return
}
hcs, err := iRegion.GetILoadBalancerHealthChecks()
if err != nil {
self.taskFail(ctx, hc, errors.Wrapf(err, "GetLoadbalancerHealthChecks"))
return
}
for i := range hcs {
if hcs[i].GetGlobalId() == hc.ExternalId {
err = hcs[i].Delete()
if err != nil {
self.taskFail(ctx, hc, errors.Wrapf(err, "Delete"))
return
}
self.taskComplete(ctx, hc)
return
}
}
self.taskComplete(ctx, hc)
}
func (self *LoadbalancerHealthCheckDeleteTask) taskComplete(ctx context.Context, hc *models.SLoadbalancerHealthCheck) {
hc.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,93 @@
// 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 loadbalancer
import (
"context"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/apis"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type LoadbalancerHealthCheckUpdateTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(LoadbalancerHealthCheckUpdateTask{})
}
func (self *LoadbalancerHealthCheckUpdateTask) taskFail(ctx context.Context, hc *models.SLoadbalancerHealthCheck, err error) {
hc.SetStatus(ctx, self.GetUserCred(), api.LB_SYNC_CONF_FAILED, err.Error())
db.OpsLog.LogEvent(hc, db.ACT_SYNC_CONF, err.Error(), self.UserCred)
logclient.AddActionLogWithStartable(self, hc, logclient.ACT_SYNC_CONF, err.Error(), self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *LoadbalancerHealthCheckUpdateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
hc := obj.(*models.SLoadbalancerHealthCheck)
iRegion, err := hc.GetIRegion(ctx)
if err != nil {
self.taskFail(ctx, hc, errors.Wrapf(err, "GetIRegion"))
return
}
hcs, err := iRegion.GetILoadBalancerHealthChecks()
if err != nil {
self.taskFail(ctx, hc, errors.Wrapf(err, "GetLoadbalancerHealthChecks"))
return
}
for i := range hcs {
if hcs[i].GetGlobalId() == hc.ExternalId {
opts := &cloudprovider.SLoadbalancerHealthCheck{
Name: hc.Name,
HealthCheckType: hc.HealthCheckType,
HealthCheckDomain: hc.HealthCheckDomain,
HealthCheckURI: hc.HealthCheckURI,
HealthCheckHttpCode: hc.HealthCheckHttpCode,
HealthCheckMethod: hc.HealthCheckMethod,
HealthCheckPort: hc.HealthCheckPort,
HealthCheckTimeout: hc.HealthCheckTimeout,
HealthCheckInterval: hc.HealthCheckInterval,
HealthCheckRise: hc.HealthCheckRise,
HealthCheckReq: hc.HealthCheckReq,
HealthCheckExp: hc.HealthCheckExp,
}
err := hcs[i].Update(ctx, opts)
if err != nil {
self.taskFail(ctx, hc, errors.Wrapf(err, "Update"))
return
}
self.taskComplete(ctx, hc)
return
}
}
self.taskFail(ctx, hc, errors.Wrapf(errors.ErrNotFound, "LoadbalancerHealthCheck %s not found", hc.ExternalId))
}
func (self *LoadbalancerHealthCheckUpdateTask) taskComplete(ctx context.Context, hc *models.SLoadbalancerHealthCheck) {
hc.SetStatus(ctx, self.GetUserCred(), apis.STATUS_AVAILABLE, "")
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,47 @@
// 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 compute
import (
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
"yunion.io/x/onecloud/pkg/mcclient/modules"
)
type LoadbalancerHealthCheckManager struct {
modulebase.ResourceManager
}
var (
LoadbalancerHealthChecks LoadbalancerHealthCheckManager
)
func init() {
LoadbalancerHealthChecks = LoadbalancerHealthCheckManager{
modules.NewComputeManager(
"loadbalancer_health_check",
"loadbalancer_health_checks",
[]string{
"id",
"name",
"status",
"cloudregion",
"manager",
"project",
},
[]string{"tenant"},
),
}
modules.RegisterCompute(&LoadbalancerHealthChecks)
}
@@ -0,0 +1,50 @@
// 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 compute
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
type LoadbalancerHealthCheckListOptions struct {
options.BaseListOptions
Cloudregion string
}
func (opts *LoadbalancerHealthCheckListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
type LoadbalancerHealthCheckIdOptions struct {
options.BaseIdOptions
}
type LoadbalancerHealthCheckCreateOptions struct {
options.SharableProjectizedResourceBaseCreateInput
NAME string
Manager string
Region string
}
func (opts *LoadbalancerHealthCheckCreateOptions) Params() (jsonutils.JSONObject, error) {
return options.StructToParams(opts)
}
type LoadbalancerHealthCheckUpdateOptions struct {
LoadbalancerHealthCheckIdOptions
}
+1 -1
View File
@@ -1852,7 +1852,7 @@ sigs.k8s.io/structured-merge-diff/v4/value
# sigs.k8s.io/yaml v1.2.0
## explicit; go 1.12
sigs.k8s.io/yaml
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250730103446-8b50657aec9f
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250801094033-0d3c2f9a0e80
## explicit; go 1.21
yunion.io/x/cloudmux/pkg/apis
yunion.io/x/cloudmux/pkg/apis/billing
+9 -4
View File
@@ -15,10 +15,11 @@
package cloudprovider
type SLoadbalancerBackendGroup struct {
Name string
GroupType string
Status string
Backends []SLoadbalancerBackend
Name string
GroupType string
Status string
Backends []SLoadbalancerBackend
HealthCheckId string
// huawei
Scheduler string
@@ -30,6 +31,8 @@ type SLoadbalancerBackendGroup struct {
}
type SLoadbalancerHealthCheck struct {
Name string
HealthCheckType string
HealthCheckReq string
HealthCheckExp string
@@ -40,6 +43,8 @@ type SLoadbalancerHealthCheck struct {
HealthCheckHttpCode string
HealthCheckURI string
HealthCheckInterval int
HealthCheckMethod string
HealthCheckPort int
HealthCheckRise int
HealthCheckFail int
+16 -2
View File
@@ -116,6 +116,8 @@ type ICloudRegion interface {
GetILoadBalancers() ([]ICloudLoadbalancer, error)
GetILoadBalancerAcls() ([]ICloudLoadbalancerAcl, error)
GetILoadBalancerHealthChecks() ([]ICloudLoadbalancerHealthCheck, error)
GetILoadBalancerCertificates() ([]ICloudLoadbalancerCertificate, error)
GetILoadBalancerById(loadbalancerId string) (ICloudLoadbalancer, error)
@@ -125,6 +127,7 @@ type ICloudRegion interface {
CreateILoadBalancer(loadbalancer *SLoadbalancerCreateOptions) (ICloudLoadbalancer, error)
CreateILoadBalancerAcl(acl *SLoadbalancerAccessControlList) (ICloudLoadbalancerAcl, error)
CreateILoadBalancerCertificate(cert *SLoadbalancerCertificate) (ICloudLoadbalancerCertificate, error)
CreateILoadBalancerHealthCheck(healthCheck *SLoadbalancerHealthCheck) (ICloudLoadbalancerHealthCheck, error)
GetISkus() ([]ICloudSku, error)
CreateISku(opts *SServerSkuCreateOption) (ICloudSku, error)
@@ -749,7 +752,7 @@ type ICloudLoadbalancerRedirect interface {
GetRedirectPath() string
}
type ICloudloadbalancerHealthCheck interface {
type ICloudloadbalancerHealthCheckInfo interface {
GetHealthCheck() string
GetHealthCheckType() string
GetHealthCheckTimeout() int
@@ -763,9 +766,19 @@ type ICloudloadbalancerHealthCheck interface {
// HTTP && HTTPS
GetHealthCheckDomain() string
GetHealthCheckURI() string
GetHealthCheckMethod() string
GetHealthCheckPort() int
GetHealthCheckCode() string
}
type ICloudLoadbalancerHealthCheck interface {
IVirtualResource
ICloudloadbalancerHealthCheckInfo
Delete() error
Update(ctx context.Context, opts *SLoadbalancerHealthCheck) error
}
type ICloudLoadbalancerListener interface {
ICloudResource
@@ -801,7 +814,7 @@ type ICloudLoadbalancerListener interface {
// http redirect
ICloudLoadbalancerRedirect
ICloudloadbalancerHealthCheck
ICloudloadbalancerHealthCheckInfo
Start() error
Stop() error
@@ -838,6 +851,7 @@ type ICloudLoadbalancerBackendGroup interface {
IsDefault() bool
GetType() string
GetScheduler() string
GetHealthCheckId() string
GetILoadbalancerBackends() ([]ICloudLoadbalancerBackend, error)
GetILoadbalancerBackendById(backendId string) (ICloudLoadbalancerBackend, error)
AddBackendServer(opts *SLoadbalancerBackend) (ICloudLoadbalancerBackend, error)
+8
View File
@@ -239,6 +239,14 @@ func (listener *SAlbListener) GetHealthCheckDomain() string {
return ""
}
func (listener *SAlbListener) GetHealthCheckMethod() string {
return ""
}
func (listener *SAlbListener) GetHealthCheckPort() int {
return 0
}
func (listener *SAlbListener) GetHealthCheckURI() string {
return ""
}
+1 -1
View File
@@ -25,7 +25,7 @@ import (
)
type SAlbServerGroup struct {
multicloud.SResourceBase
multicloud.SLoadbalancerBackendGroupBase
AliyunTags
alb *SAlb
@@ -172,6 +172,14 @@ func (listerner *SLoadbalancerHTTPListener) GetHealthCheckDomain() string {
return listerner.HealthCheckDomain
}
func (listerner *SLoadbalancerHTTPListener) GetHealthCheckMethod() string {
return ""
}
func (listerner *SLoadbalancerHTTPListener) GetHealthCheckPort() int {
return listerner.HealthCheckConnectPort
}
func (listerner *SLoadbalancerHTTPListener) GetHealthCheckURI() string {
return listerner.HealthCheckURI
}
@@ -167,6 +167,14 @@ func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckDomain() string {
return listerner.HealthCheckDomain
}
func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckMethod() string {
return ""
}
func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckPort() int {
return listerner.HealthCheckConnectPort
}
func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckURI() string {
return listerner.HealthCheckURI
}
@@ -147,6 +147,14 @@ func (listerner *SLoadbalancerTCPListener) GetHealthCheckDomain() string {
return ""
}
func (listerner *SLoadbalancerTCPListener) GetHealthCheckMethod() string {
return ""
}
func (listerner *SLoadbalancerTCPListener) GetHealthCheckPort() int {
return listerner.HealthCheckConnectPort
}
func (listerner *SLoadbalancerTCPListener) GetHealthCheckURI() string {
return ""
}
@@ -152,6 +152,14 @@ func (listerner *SLoadbalancerUDPListener) GetHealthCheckDomain() string {
return ""
}
func (listerner *SLoadbalancerUDPListener) GetHealthCheckMethod() string {
return ""
}
func (listerner *SLoadbalancerUDPListener) GetHealthCheckPort() int {
return listerner.HealthCheckConnectPort
}
func (listerner *SLoadbalancerUDPListener) GetHealthCheckURI() string {
return ""
}
+8
View File
@@ -152,6 +152,14 @@ func (listener *SNlbListener) GetHealthCheckDomain() string {
return ""
}
func (listener *SNlbListener) GetHealthCheckMethod() string {
return ""
}
func (listener *SNlbListener) GetHealthCheckPort() int {
return 0
}
func (listener *SNlbListener) GetHealthCheckURI() string {
return ""
}
@@ -173,6 +173,14 @@ func (listerner *SLoadbalancerHTTPListener) GetHealthCheckDomain() string {
return listerner.HealthCheckDomain
}
func (listerner *SLoadbalancerHTTPListener) GetHealthCheckMethod() string {
return ""
}
func (listerner *SLoadbalancerHTTPListener) GetHealthCheckPort() int {
return listerner.HealthCheckConnectPort
}
func (listerner *SLoadbalancerHTTPListener) GetHealthCheckURI() string {
return listerner.HealthCheckURI
}
@@ -168,6 +168,14 @@ func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckDomain() string {
return listerner.HealthCheckDomain
}
func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckMethod() string {
return ""
}
func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckPort() int {
return listerner.HealthCheckConnectPort
}
func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckURI() string {
return listerner.HealthCheckURI
}
@@ -148,6 +148,14 @@ func (listerner *SLoadbalancerTCPListener) GetHealthCheckDomain() string {
return ""
}
func (listerner *SLoadbalancerTCPListener) GetHealthCheckMethod() string {
return ""
}
func (listerner *SLoadbalancerTCPListener) GetHealthCheckPort() int {
return listerner.HealthCheckConnectPort
}
func (listerner *SLoadbalancerTCPListener) GetHealthCheckURI() string {
return ""
}
@@ -153,6 +153,14 @@ func (listerner *SLoadbalancerUDPListener) GetHealthCheckDomain() string {
return ""
}
func (listerner *SLoadbalancerUDPListener) GetHealthCheckMethod() string {
return ""
}
func (listerner *SLoadbalancerUDPListener) GetHealthCheckPort() int {
return listerner.HealthCheckConnectPort
}
func (listerner *SLoadbalancerUDPListener) GetHealthCheckURI() string {
return ""
}
@@ -299,6 +299,14 @@ func (self *SElbListener) GetHealthCheckDomain() string {
return health.HealthCheckDomain
}
func (self *SElbListener) GetHealthCheckMethod() string {
return ""
}
func (self *SElbListener) GetHealthCheckPort() int {
return 0
}
func (self *SElbListener) GetHealthCheckURI() string {
group, err := self.getBackendGroup()
if err != nil {
@@ -211,6 +211,14 @@ func (self *SLoadBalancerHTTPListener) GetHealthCheckDomain() string {
return ""
}
func (self *SLoadBalancerHTTPListener) GetHealthCheckMethod() string {
return ""
}
func (self *SLoadBalancerHTTPListener) GetHealthCheckPort() int {
return 0
}
func (self *SLoadBalancerHTTPListener) GetHealthCheckURI() string {
return ""
}
@@ -224,6 +224,14 @@ func (self *SLoadBalancerListener) GetHealthCheckDomain() string {
return ""
}
func (self *SLoadBalancerListener) GetHealthCheckMethod() string {
return ""
}
func (self *SLoadBalancerListener) GetHealthCheckPort() int {
return 0
}
func (self *SLoadBalancerListener) GetHealthCheckURI() string {
return ""
}
@@ -322,6 +322,14 @@ func (self *SGlobalLoadbalancerListener) GetHealthCheckDomain() string {
}
}
func (self *SGlobalLoadbalancerListener) GetHealthCheckMethod() string {
return ""
}
func (self *SGlobalLoadbalancerListener) GetHealthCheckPort() int {
return 0
}
func (self *SGlobalLoadbalancerListener) GetHealthCheckURI() string {
hcs := self.GetHealthChecks()
if hcs == nil {
+14 -5
View File
@@ -241,11 +241,12 @@ func (self *SLoadbalancerListener) GetStickySession() string {
/*
https://cloud.google.com/load-balancing/docs/backend-service#sessionAffinity
区域级外部 HTTP(S) 负载均衡器:
(NONE)
客户端 IP (CLIENT_IP)
生成的 Cookie (GENERATED_COOKIE)
标头字段 (HEADER_FIELD)
HTTP Cookie (HTTP_COOKIE)
(NONE)
客户端 IP (CLIENT_IP)
生成的 Cookie (GENERATED_COOKIE)
标头字段 (HEADER_FIELD)
HTTP Cookie (HTTP_COOKIE)
*/
func (self *SLoadbalancerListener) GetStickySessionType() string {
switch self.backendService.SessionAffinity {
@@ -440,6 +441,14 @@ func (self *SLoadbalancerListener) GetHealthCheckDomain() string {
}
}
func (self *SLoadbalancerListener) GetHealthCheckMethod() string {
return ""
}
func (self *SLoadbalancerListener) GetHealthCheckPort() int {
return 0
}
func (self *SLoadbalancerListener) GetHealthCheckURI() string {
hcs := self.GetHealthChecks()
if hcs == nil {
@@ -357,6 +357,14 @@ func (self *SElbListener) GetHealthCheckDomain() string {
return ""
}
func (self *SElbListener) GetHealthCheckMethod() string {
return ""
}
func (self *SElbListener) GetHealthCheckPort() int {
return 0
}
func (self *SElbListener) GetHealthCheckURI() string {
lbbg, err := self.GetBackendGroup()
if err != nil {
@@ -360,6 +360,14 @@ func (self *SElbListener) GetHealthCheckDomain() string {
return ""
}
func (self *SElbListener) GetHealthCheckMethod() string {
return ""
}
func (self *SElbListener) GetHealthCheckPort() int {
return 0
}
func (self *SElbListener) GetHealthCheckURI() string {
lbbg, err := self.GetBackendGroup()
if err != nil {
+4
View File
@@ -27,3 +27,7 @@ type SLoadbalancerBackendGroupBase struct {
func (self *SLoadbalancerBackendGroupBase) Update(ctx context.Context, opts *cloudprovider.SLoadbalancerBackendGroup) error {
return cloudprovider.ErrNotImplemented
}
func (self *SLoadbalancerBackendGroupBase) GetHealthCheckId() string {
return ""
}
+3 -1
View File
@@ -14,7 +14,9 @@
package multicloud
import "yunion.io/x/cloudmux/pkg/cloudprovider"
import (
"yunion.io/x/cloudmux/pkg/cloudprovider"
)
type SNoLbRegion struct{}
@@ -393,6 +393,14 @@ func (listener *SLoadbalancerListener) GetHealthCheckDomain() string {
return pool.healthmonitor.DomainName
}
func (listener *SLoadbalancerListener) GetHealthCheckMethod() string {
return ""
}
func (listener *SLoadbalancerListener) GetHealthCheckPort() int {
return 0
}
func (listener *SLoadbalancerListener) GetHealthCheckURI() string {
pool, err := listener.fetchFeaturePool()
if err != nil {
-14
View File
@@ -12,20 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// 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 openstack
import (
@@ -299,6 +299,14 @@ func (self *SLBListener) GetHealthCheckDomain() string {
return self.HealthCheck.HTTPCheckDomain
}
func (self *SLBListener) GetHealthCheckMethod() string {
return ""
}
func (self *SLBListener) GetHealthCheckPort() int {
return 0
}
func (self *SLBListener) GetHealthCheckURI() string {
return self.HealthCheck.HTTPCheckPath
}
+8
View File
@@ -396,3 +396,11 @@ func (self *SRegion) GetIMiscResources() ([]cloudprovider.ICloudMiscResource, er
func (self *SRegion) GetISSLCertificates() ([]cloudprovider.ICloudSSLCertificate, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetISSLCertificate")
}
func (self *SRegion) GetILoadBalancerHealthChecks() ([]cloudprovider.ICloudLoadbalancerHealthCheck, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetILoadBalancerHealthChecks")
}
func (self *SRegion) CreateILoadBalancerHealthCheck(healthCheck *cloudprovider.SLoadbalancerHealthCheck) (cloudprovider.ICloudLoadbalancerHealthCheck, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "CreateILoadBalancerHealthCheck")
}