From 2df78f917fffa9dd69a680646aa597b497805e58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Thu, 3 Jan 2019 11:36:17 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=B7=BB=E5=8A=A0region=20driver?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/climc/shell/loadbalanceracls.go | 8 + cmd/climc/shell/loadbalancerbackendgroups.go | 10 +- cmd/climc/shell/loadbalancerbackends.go | 10 +- cmd/climc/shell/loadbalancerlistenerrules.go | 10 +- cmd/climc/shell/loadbalancers.go | 8 + pkg/cloudprovider/fakeregion.go | 24 ++ pkg/cloudprovider/loadbalancer.go | 16 + pkg/cloudprovider/loadbalanceracl.go | 11 + pkg/cloudprovider/loadbalancerbackend.go | 13 + pkg/cloudprovider/loadbalancerlistener.go | 15 + pkg/cloudprovider/resources.go | 24 ++ pkg/compute/models/cloudproviders.go | 11 + pkg/compute/models/cloudregions.go | 12 + pkg/compute/models/loadbalancer_const.go | 12 +- pkg/compute/models/loadbalanceracls.go | 84 +++- .../models/loadbalancerbackendgroups.go | 165 +++++++- pkg/compute/models/loadbalancerbackends.go | 78 +++- .../models/loadbalancercertificates.go | 89 +++- pkg/compute/models/loadbalancerlisteners.go | 62 ++- pkg/compute/models/loadbalancernetworks.go | 26 +- pkg/compute/models/loadbalancers.go | 169 ++++++-- pkg/compute/models/regiondrivers.go | 57 +++ pkg/compute/regiondrivers/aliyun.go | 60 +++ pkg/compute/regiondrivers/aws.go | 18 + pkg/compute/regiondrivers/azure.go | 18 + pkg/compute/regiondrivers/base.go | 62 +++ pkg/compute/regiondrivers/esxi.go | 18 + pkg/compute/regiondrivers/huawei.go | 18 + pkg/compute/regiondrivers/kvm.go | 147 +++++++ pkg/compute/regiondrivers/managedvirtual.go | 399 ++++++++++++++++++ pkg/compute/regiondrivers/openstack.go | 18 + pkg/compute/regiondrivers/qcloud.go | 18 + pkg/compute/regiondrivers/virtualization.go | 5 + pkg/compute/service/service.go | 1 + .../tasks/loadbalancer_backend_create_task.go | 47 +++ .../tasks/loadbalancer_backend_delete_task.go | 47 +++ .../loadbalancer_backendgroup_create_task.go | 50 +++ .../loadbalancer_backendgroup_delete_task.go | 47 +++ pkg/compute/tasks/loadbalancer_create_task.go | 47 +++ pkg/compute/tasks/loadbalancer_delete_task.go | 47 +++ .../loadbalancer_listener_create_task.go | 47 +++ .../loadbalancer_listener_delete_task.go | 47 +++ .../tasks/loadbalanceracl_create_task.go | 47 +++ .../tasks/loadbalanceracl_delete_task.go | 47 +++ .../loadbalancercertificate_create_task.go | 47 +++ .../loadbalancercertificate_delete_task.go | 47 +++ pkg/mcclient/models/loadbalancers.go | 6 +- pkg/mcclient/options/loadbalanceracls.go | 2 + .../options/loadbalancerbackendgroups.go | 4 +- pkg/mcclient/options/loadbalancers.go | 12 +- pkg/util/aliyun/loadbalancer.go | 61 ++- pkg/util/aliyun/loadbalanceracl.go | 26 ++ pkg/util/aliyun/loadbalancerbackendgroup.go | 105 +++++ .../aliyun/loadbalancerdefaultbackendgroup.go | 41 ++ .../loadbalancermasterslavebackendgroup.go | 85 ++++ .../aliyun/loadbalancerservercertificate.go | 28 ++ pkg/util/aliyun/region.go | 127 ++++++ pkg/util/aws/region.go | 24 ++ pkg/util/azure/region.go | 24 ++ pkg/util/huawei/region.go | 24 ++ pkg/util/openstack/region.go | 24 ++ pkg/util/qcloud/region.go | 24 ++ 62 files changed, 2791 insertions(+), 89 deletions(-) create mode 100644 pkg/cloudprovider/loadbalancer.go create mode 100644 pkg/cloudprovider/loadbalanceracl.go create mode 100644 pkg/cloudprovider/loadbalancerbackend.go create mode 100644 pkg/cloudprovider/loadbalancerlistener.go create mode 100644 pkg/compute/models/regiondrivers.go create mode 100644 pkg/compute/regiondrivers/aliyun.go create mode 100644 pkg/compute/regiondrivers/aws.go create mode 100644 pkg/compute/regiondrivers/azure.go create mode 100644 pkg/compute/regiondrivers/base.go create mode 100644 pkg/compute/regiondrivers/esxi.go create mode 100644 pkg/compute/regiondrivers/huawei.go create mode 100644 pkg/compute/regiondrivers/kvm.go create mode 100644 pkg/compute/regiondrivers/managedvirtual.go create mode 100644 pkg/compute/regiondrivers/openstack.go create mode 100644 pkg/compute/regiondrivers/qcloud.go create mode 100644 pkg/compute/regiondrivers/virtualization.go create mode 100644 pkg/compute/tasks/loadbalancer_backend_create_task.go create mode 100644 pkg/compute/tasks/loadbalancer_backend_delete_task.go create mode 100644 pkg/compute/tasks/loadbalancer_backendgroup_create_task.go create mode 100644 pkg/compute/tasks/loadbalancer_backendgroup_delete_task.go create mode 100644 pkg/compute/tasks/loadbalancer_create_task.go create mode 100644 pkg/compute/tasks/loadbalancer_delete_task.go create mode 100644 pkg/compute/tasks/loadbalancer_listener_create_task.go create mode 100644 pkg/compute/tasks/loadbalancer_listener_delete_task.go create mode 100644 pkg/compute/tasks/loadbalanceracl_create_task.go create mode 100644 pkg/compute/tasks/loadbalanceracl_delete_task.go create mode 100644 pkg/compute/tasks/loadbalancercertificate_create_task.go create mode 100644 pkg/compute/tasks/loadbalancercertificate_delete_task.go diff --git a/cmd/climc/shell/loadbalanceracls.go b/cmd/climc/shell/loadbalanceracls.go index 70f3baf9ed..c0e36d0704 100644 --- a/cmd/climc/shell/loadbalanceracls.go +++ b/cmd/climc/shell/loadbalanceracls.go @@ -93,6 +93,14 @@ func init() { printLbAcl(lbacl) return nil }) + R(&options.LoadbalancerAclDeleteOptions{}, "lbacl-purge", "Purge lbacl", func(s *mcclient.ClientSession, opts *options.LoadbalancerAclDeleteOptions) error { + lbacl, err := modules.LoadbalancerAcls.PerformAction(s, opts.ID, "purge", nil) + if err != nil { + return err + } + printLbAcl(lbacl) + return nil + }) R(&options.LoadbalancerAclDeleteOptions{}, "lbacl-delete", "Show lbacl", func(s *mcclient.ClientSession, opts *options.LoadbalancerAclDeleteOptions) error { lbacl, err := modules.LoadbalancerAcls.Delete(s, opts.ID, nil) if err != nil { diff --git a/cmd/climc/shell/loadbalancerbackendgroups.go b/cmd/climc/shell/loadbalancerbackendgroups.go index 068ac36bc4..b6dcf83247 100644 --- a/cmd/climc/shell/loadbalancerbackendgroups.go +++ b/cmd/climc/shell/loadbalancerbackendgroups.go @@ -51,7 +51,7 @@ func init() { printObject(lbbackendgroup) return nil }) - R(&options.LoadbalancerBackendGroupDeleteOptions{}, "lbbackendgroup-delete", "Show lbbackendgroup", func(s *mcclient.ClientSession, opts *options.LoadbalancerBackendGroupDeleteOptions) error { + R(&options.LoadbalancerBackendGroupDeleteOptions{}, "lbbackendgroup-delete", "Delete lbbackendgroup", func(s *mcclient.ClientSession, opts *options.LoadbalancerBackendGroupDeleteOptions) error { lbbackendgroup, err := modules.LoadbalancerBackendGroups.Delete(s, opts.ID, nil) if err != nil { return err @@ -59,4 +59,12 @@ func init() { printObject(lbbackendgroup) return nil }) + R(&options.LoadbalancerBackendGroupDeleteOptions{}, "lbbackendgroup-purge", "Purge lbbackendgroup", func(s *mcclient.ClientSession, opts *options.LoadbalancerBackendGroupDeleteOptions) error { + lbbackendgroup, err := modules.LoadbalancerBackendGroups.PerformAction(s, opts.ID, "purge", nil) + if err != nil { + return err + } + printObject(lbbackendgroup) + return nil + }) } diff --git a/cmd/climc/shell/loadbalancerbackends.go b/cmd/climc/shell/loadbalancerbackends.go index f8e1c4d03e..e7c991b6a0 100644 --- a/cmd/climc/shell/loadbalancerbackends.go +++ b/cmd/climc/shell/loadbalancerbackends.go @@ -48,7 +48,7 @@ func init() { printObject(lbbackend) return nil }) - R(&options.LoadbalancerBackendDeleteOptions{}, "lbbackend-delete", "Show lbbackend", func(s *mcclient.ClientSession, opts *options.LoadbalancerBackendDeleteOptions) error { + R(&options.LoadbalancerBackendDeleteOptions{}, "lbbackend-delete", "Delete lbbackend", func(s *mcclient.ClientSession, opts *options.LoadbalancerBackendDeleteOptions) error { lbbackend, err := modules.LoadbalancerBackends.Delete(s, opts.ID, nil) if err != nil { return err @@ -56,4 +56,12 @@ func init() { printObject(lbbackend) return nil }) + R(&options.LoadbalancerBackendDeleteOptions{}, "lbbackend-purge", "Purge lbbackend", func(s *mcclient.ClientSession, opts *options.LoadbalancerBackendDeleteOptions) error { + lbbackend, err := modules.LoadbalancerBackends.PerformAction(s, opts.ID, "purge", nil) + if err != nil { + return err + } + printObject(lbbackend) + return nil + }) } diff --git a/cmd/climc/shell/loadbalancerlistenerrules.go b/cmd/climc/shell/loadbalancerlistenerrules.go index 403dbd9acc..60d4660bc5 100644 --- a/cmd/climc/shell/loadbalancerlistenerrules.go +++ b/cmd/climc/shell/loadbalancerlistenerrules.go @@ -46,7 +46,7 @@ func init() { printObject(lblistenerrule) return nil }) - R(&options.LoadbalancerListenerRuleDeleteOptions{}, "lblistenerrule-delete", "Show lblistenerrule", func(s *mcclient.ClientSession, opts *options.LoadbalancerListenerRuleDeleteOptions) error { + R(&options.LoadbalancerListenerRuleDeleteOptions{}, "lblistenerrule-delete", "Delete lblistenerrule", func(s *mcclient.ClientSession, opts *options.LoadbalancerListenerRuleDeleteOptions) error { lblistenerrule, err := modules.LoadbalancerListenerRules.Delete(s, opts.ID, nil) if err != nil { return err @@ -54,6 +54,14 @@ func init() { printObject(lblistenerrule) return nil }) + R(&options.LoadbalancerListenerRuleDeleteOptions{}, "lblistenerrule-purge", "Purge lblistenerrule", func(s *mcclient.ClientSession, opts *options.LoadbalancerListenerRuleDeleteOptions) error { + lblistenerrule, err := modules.LoadbalancerListenerRules.PerformAction(s, opts.ID, "purge", nil) + if err != nil { + return err + } + printObject(lblistenerrule) + return nil + }) R(&options.LoadbalancerListenerRuleActionStatusOptions{}, "lblistenerrule-status", "Change lblistenerrule status", func(s *mcclient.ClientSession, opts *options.LoadbalancerListenerRuleActionStatusOptions) error { params, err := options.StructToParams(opts) if err != nil { diff --git a/cmd/climc/shell/loadbalancers.go b/cmd/climc/shell/loadbalancers.go index 5ee9d53f1d..8ed03003e4 100644 --- a/cmd/climc/shell/loadbalancers.go +++ b/cmd/climc/shell/loadbalancers.go @@ -56,6 +56,14 @@ func init() { printObject(lb) return nil }) + R(&options.LoadbalancerPurgeOptions{}, "lb-purge", "Purge lb", func(s *mcclient.ClientSession, opts *options.LoadbalancerPurgeOptions) error { + lb, err := modules.Loadbalancers.PerformAction(s, opts.ID, "purge", nil) + if err != nil { + return err + } + printObject(lb) + return nil + }) R(&options.LoadbalancerActionStatusOptions{}, "lb-status", "Change lb status", func(s *mcclient.ClientSession, opts *options.LoadbalancerActionStatusOptions) error { params, err := options.StructToParams(opts) if err != nil { diff --git a/pkg/cloudprovider/fakeregion.go b/pkg/cloudprovider/fakeregion.go index 4c849c8e30..6e82f803b5 100644 --- a/pkg/cloudprovider/fakeregion.go +++ b/pkg/cloudprovider/fakeregion.go @@ -84,6 +84,22 @@ func (region *SFakeOnPremiseRegion) GetILoadBalancers() ([]ICloudLoadbalancer, e return nil, ErrNotSupported } +func (region *SFakeOnPremiseRegion) GetILoadBalancerById(loadbalancerId string) (ICloudLoadbalancer, error) { + return nil, ErrNotSupported +} + +func (region *SFakeOnPremiseRegion) GetILoadBalancerAclById(aclId string) (ICloudLoadbalancerAcl, error) { + return nil, ErrNotSupported +} + +func (region *SFakeOnPremiseRegion) GetILoadBalancerCertificateById(certId string) (ICloudLoadbalancerCertificate, error) { + return nil, ErrNotSupported +} + +func (region *SFakeOnPremiseRegion) CreateILoadBalancerCertificate(name string, privateKey, certificate string) (ICloudLoadbalancerCertificate, error) { + return nil, ErrNotImplemented +} + func (region *SFakeOnPremiseRegion) GetILoadbalancerAcls() ([]ICloudLoadbalancerAcl, error) { return nil, ErrNotSupported } @@ -91,3 +107,11 @@ func (region *SFakeOnPremiseRegion) GetILoadbalancerAcls() ([]ICloudLoadbalancer func (region *SFakeOnPremiseRegion) GetILoadbalancerCertificates() ([]ICloudLoadbalancerCertificate, error) { return nil, ErrNotSupported } + +func (region *SFakeOnPremiseRegion) CreateILoadBalancer(loadbalancer *SLoadbalancer) (ICloudLoadbalancer, error) { + return nil, ErrNotSupported +} + +func (region *SFakeOnPremiseRegion) CreateILoadBalancerAcl(acl *SLoadbalancerAccessControlList) (ICloudLoadbalancerAcl, error) { + return nil, ErrNotSupported +} diff --git a/pkg/cloudprovider/loadbalancer.go b/pkg/cloudprovider/loadbalancer.go new file mode 100644 index 0000000000..21fe546711 --- /dev/null +++ b/pkg/cloudprovider/loadbalancer.go @@ -0,0 +1,16 @@ +package cloudprovider + +import "yunion.io/x/onecloud/pkg/util/billing" + +type SLoadbalancer struct { + Name string + ZoneID string + VpcID string + NetworkID string + Address string + AddressType string + LoadbalancerSpec string + ChargeType string + Bandwidth int + billingCycle *billing.SBillingCycle +} diff --git a/pkg/cloudprovider/loadbalanceracl.go b/pkg/cloudprovider/loadbalanceracl.go new file mode 100644 index 0000000000..b8d708ebb0 --- /dev/null +++ b/pkg/cloudprovider/loadbalanceracl.go @@ -0,0 +1,11 @@ +package cloudprovider + +type SLoadbalancerAccessControlListEntry struct { + CIDR string + Comment string +} + +type SLoadbalancerAccessControlList struct { + Name string + Entrys []SLoadbalancerAccessControlListEntry +} diff --git a/pkg/cloudprovider/loadbalancerbackend.go b/pkg/cloudprovider/loadbalancerbackend.go new file mode 100644 index 0000000000..16f5f6892b --- /dev/null +++ b/pkg/cloudprovider/loadbalancerbackend.go @@ -0,0 +1,13 @@ +package cloudprovider + +type SLoadbalancerBackend struct { + Index int + Weight int + Port int + ID string + Name string + ExternalID string + BackendType string + BackendRole string + Address string +} diff --git a/pkg/cloudprovider/loadbalancerlistener.go b/pkg/cloudprovider/loadbalancerlistener.go new file mode 100644 index 0000000000..8dfd655b7d --- /dev/null +++ b/pkg/cloudprovider/loadbalancerlistener.go @@ -0,0 +1,15 @@ +package cloudprovider + +type SLoadbalancerListener struct { + Name string + LoadbalancerID string + ListenerType string + ListenerPort int + BackendGroupID string + Scheduler string + AccessControlListStatus string + AccessControlListType string + AccessControlListID string + EnableHTTP2 bool + CertificateID string +} diff --git a/pkg/cloudprovider/resources.go b/pkg/cloudprovider/resources.go index 83f3596492..33824a5ae0 100644 --- a/pkg/cloudprovider/resources.go +++ b/pkg/cloudprovider/resources.go @@ -66,6 +66,14 @@ type ICloudRegion interface { GetILoadbalancerAcls() ([]ICloudLoadbalancerAcl, error) GetILoadbalancerCertificates() ([]ICloudLoadbalancerCertificate, error) + GetILoadBalancerById(loadbalancerId string) (ICloudLoadbalancer, error) + GetILoadBalancerAclById(aclId string) (ICloudLoadbalancerAcl, error) + GetILoadBalancerCertificateById(certId string) (ICloudLoadbalancerCertificate, error) + + CreateILoadBalancer(loadbalancer *SLoadbalancer) (ICloudLoadbalancer, error) + CreateILoadBalancerAcl(acl *SLoadbalancerAccessControlList) (ICloudLoadbalancerAcl, error) + CreateILoadBalancerCertificate(name string, privateKey, certificate string) (ICloudLoadbalancerCertificate, error) + GetProvider() string } @@ -400,9 +408,16 @@ type ICloudLoadbalancer interface { GetNetworkId() string GetVpcId() string GetZoneId() string + GetLoadbalancerSpec() string + GetChargeType() string + + Delete() error GetILoadbalancerListeners() ([]ICloudLoadbalancerListener, error) GetILoadbalancerBackendGroups() ([]ICloudLoadbalancerBackendGroup, error) + + CreateILoadBalancerBackendGroup(name string, groupType string, backends []SLoadbalancerBackend) (ICloudLoadbalancerBackendGroup, error) + GetILoadbalancerBackendGroupById(groupId string) (ICloudLoadbalancerBackendGroup, error) } type ICloudLoadbalancerListener interface { @@ -459,6 +474,11 @@ type ICloudLoadbalancerBackendGroup interface { IsDefault() bool GetType() string GetILoadbalancerBackends() ([]ICloudLoadbalancerBackend, error) + AddBackendServer(serverId string, weight int, port int) (ICloudLoadbalancerBackend, error) + RemoveBackendServer(serverId string) error + + Delete() error + Sync(name string) error } type ICloudLoadbalancerBackend interface { @@ -474,6 +494,9 @@ type ICloudLoadbalancerBackend interface { type ICloudLoadbalancerCertificate interface { ICloudResource + Sync(name, privateKey, publickKey string) error + Delete() error + GetCommonName() string GetSubjectAlternativeNames() string GetFingerprint() string // return value format: :,比如sha1:7454a14fdb8ae1ea8b2f72e458a24a76bd23ec19 @@ -495,4 +518,5 @@ type ICloudLoadbalancerAcl interface { // } // ] GetAclEntries() *jsonutils.JSONArray + Delete() error } diff --git a/pkg/compute/models/cloudproviders.go b/pkg/compute/models/cloudproviders.go index a0da013c15..ce1b948bda 100644 --- a/pkg/compute/models/cloudproviders.go +++ b/pkg/compute/models/cloudproviders.go @@ -45,6 +45,17 @@ const ( var ( CLOUD_PROVIDER_VALID_STATUS = []string{CLOUD_PROVIDER_CONNECTED, CLOUD_PROVIDER_START_SYNC, CLOUD_PROVIDER_SYNCING} + + CLOUD_PROVIDERS = []string{ + CLOUD_PROVIDER_KVM, + CLOUD_PROVIDER_VMWARE, + CLOUD_PROVIDER_ALIYUN, + CLOUD_PROVIDER_QCLOUD, + CLOUD_PROVIDER_AZURE, + CLOUD_PROVIDER_AWS, + CLOUD_PROVIDER_HUAWEI, + CLOUD_PROVIDER_OPENSTACK, + } ) type SCloudproviderManager struct { diff --git a/pkg/compute/models/cloudregions.go b/pkg/compute/models/cloudregions.go index 12136fea33..1113aed31a 100644 --- a/pkg/compute/models/cloudregions.go +++ b/pkg/compute/models/cloudregions.go @@ -10,6 +10,7 @@ import ( "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/pkg/util/compare" + "yunion.io/x/pkg/utils" "yunion.io/x/sqlchemy" "yunion.io/x/onecloud/pkg/cloudcommon/db" @@ -127,6 +128,17 @@ func (self *SCloudregion) GetVpcCount() int { } } +func (self *SCloudregion) GetDriver() IRegionDriver { + provider := self.Provider + if len(provider) == 0 { + provider = CLOUD_PROVIDER_KVM + } + if !utils.IsInStringArray(provider, CLOUD_PROVIDERS) { + log.Fatalf("Unsupported region provider %s", provider) + } + return GetRegionDriver(provider) +} + func (self *SCloudregion) getMoreDetails(extra *jsonutils.JSONDict) *jsonutils.JSONDict { extra.Add(jsonutils.NewInt(int64(self.GetVpcCount())), "vpc_count") extra.Add(jsonutils.NewInt(int64(self.GetZoneCount())), "zone_count") diff --git a/pkg/compute/models/loadbalancer_const.go b/pkg/compute/models/loadbalancer_const.go index 77b83b2106..1eb020b307 100644 --- a/pkg/compute/models/loadbalancer_const.go +++ b/pkg/compute/models/loadbalancer_const.go @@ -26,7 +26,17 @@ const ( LB_STATUS_ENABLED = "enabled" LB_STATUS_DISABLED = "disabled" - LB_STATUS_INIT = "init" + LB_STATUS_INIT = "init" + + LB_STATUS_CREATING = "creating" + LB_STATUS_CREATE_FAILED = "create_failed" + + LB_STATUS_SYNCING = "syncing" + LB_STATUS_SYNCING_FAILED = "syncing_failed" + + LB_STATUS_DELETING = "deleting" + LB_STATUS_DELETE_FAILED = "delete_failed" + LB_STATUS_UNKNOWN = "unknown" LB_STATUS_RUNNING = "running" LB_STATUS_STOPPED = "stopped" diff --git a/pkg/compute/models/loadbalanceracls.go b/pkg/compute/models/loadbalanceracls.go index b436cc8aa2..e42478b257 100644 --- a/pkg/compute/models/loadbalanceracls.go +++ b/pkg/compute/models/loadbalanceracls.go @@ -2,6 +2,7 @@ package models import ( "context" + "database/sql" "fmt" "net" "reflect" @@ -15,6 +16,7 @@ import ( "yunion.io/x/sqlchemy" "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/cloudcommon/validators" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/httperrors" @@ -103,7 +105,7 @@ type SLoadbalancerAcl struct { db.SSharableVirtualResourceBase SManagedResourceBase - CloudregionId string `width:"36" charset:"ascii" nullable:"false" list:"admin" default:"default" create:"optional"` + CloudregionId string `width:"36" charset:"ascii" nullable:"false" list:"admin" default:"default" create:"required"` AclEntries *SLoadbalancerAclEntries `list:"user" update:"user" create:"required"` } @@ -125,7 +127,23 @@ func (man *SLoadbalancerAclManager) ValidateCreateData(ctx context.Context, user if err != nil { return nil, err } - return man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data) + if _, err := man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data); err != nil { + return nil, err + } + regionID, err := data.GetString("cloudregion_id") + if err != nil { + return nil, httperrors.NewMissingParameterError("cloudregion_id") + } + _region, err := CloudregionManager.FetchByIdOrName(userCred, regionID) + if err != nil { + if err == sql.ErrNoRows { + return nil, httperrors.NewResourceNotFoundError("failed to find cloudregion %s", regionID) + } + return nil, httperrors.NewGeneralError(err) + } + data.Set("cloudregion_id", jsonutils.NewString(_region.GetId())) + region := _region.(*SCloudregion) + return region.GetDriver().ValidateCreateLoadbalancerAclData(ctx, userCred, data) } func (lbacl *SLoadbalancerAcl) AllowPerformStatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { @@ -140,6 +158,44 @@ func (lbacl *SLoadbalancerAcl) ValidateUpdateData(ctx context.Context, userCred return lbacl.SSharableVirtualResourceBase.ValidateUpdateData(ctx, userCred, query, data) } +func (lbacl *SLoadbalancerAcl) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) { + lbacl.SSharableVirtualResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data) + + lbacl.SetStatus(userCred, LB_STATUS_CREATING, "") + if err := lbacl.StartLoadBalancerAclCreateTask(ctx, userCred, ""); err != nil { + log.Errorf("Failed to create loadbalanceracl error: %v", err) + } +} + +func (lbacl *SLoadbalancerAcl) StartLoadBalancerAclCreateTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerAclCreateTask", lbacl, userCred, nil, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil +} + +func (lbacl *SLoadbalancerAcl) GetRegion() *SCloudregion { + region, err := CloudregionManager.FetchById(lbacl.CloudregionId) + if err != nil { + return nil + } + return region.(*SCloudregion) +} + +func (lbacl *SLoadbalancerAcl) GetIRegion() (cloudprovider.ICloudRegion, error) { + provider, err := lbacl.GetDriver() + if err != nil { + return nil, fmt.Errorf("No cloudprovide for lb %s: %s", lbacl.Name, err) + } + region := lbacl.GetRegion() + if region == nil { + return nil, fmt.Errorf("failed to find region for lb %s", lbacl.Name) + } + return provider.GetIRegionById(region.ExternalId) +} + func (lbacl *SLoadbalancerAcl) AllowPerformPatch(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) bool { return lbacl.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, lbacl, "patch") } @@ -214,8 +270,28 @@ func (lbacl *SLoadbalancerAcl) ValidateDeleteCondition(ctx context.Context) erro return nil } -func (lbacl *SLoadbalancerAcl) PreDelete(ctx context.Context, userCred mcclient.TokenCredential) { - lbacl.DoPendingDelete(ctx, userCred) +func (lbacl *SLoadbalancerAcl) AllowPerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { + return db.IsAdminAllowPerform(userCred, lbacl, "purge") +} + +func (lbacl *SLoadbalancerAcl) PerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { + parasm := jsonutils.NewDict() + parasm.Add(jsonutils.JSONTrue, "purge") + return nil, lbacl.StartLoadBalancerAclDeleteTask(ctx, userCred, parasm, "") +} + +func (lbacl *SLoadbalancerAcl) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error { + lbacl.SetStatus(userCred, LB_STATUS_DELETING, "") + return lbacl.StartLoadBalancerAclDeleteTask(ctx, userCred, jsonutils.NewDict(), "") +} + +func (lbacl *SLoadbalancerAcl) StartLoadBalancerAclDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerAclDeleteTask", lbacl, userCred, params, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil } func (lbacl *SLoadbalancerAcl) Delete(ctx context.Context, userCred mcclient.TokenCredential) error { diff --git a/pkg/compute/models/loadbalancerbackendgroups.go b/pkg/compute/models/loadbalancerbackendgroups.go index 92860a0585..41fd4cd6fa 100644 --- a/pkg/compute/models/loadbalancerbackendgroups.go +++ b/pkg/compute/models/loadbalancerbackendgroups.go @@ -2,7 +2,10 @@ package models import ( "context" + "database/sql" "fmt" + "strconv" + "strings" "yunion.io/x/jsonutils" "yunion.io/x/log" @@ -11,8 +14,10 @@ import ( "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/cloudprovider" + "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" ) @@ -70,14 +75,117 @@ func (man *SLoadbalancerBackendGroupManager) ValidateCreateData(ctx context.Cont if err != nil { return nil, err } - return man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data) + if _, err := man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data); err != nil { + return nil, err + } + lb := lbV.Model.(*SLoadbalancer) + backends := []cloudprovider.SLoadbalancerBackend{} + for idx := 0; data.Contains(fmt.Sprintf("backend.%d", idx)); idx++ { + _backend, _ := data.GetString(fmt.Sprintf("backend.%d", idx)) + backend := cloudprovider.SLoadbalancerBackend{BackendType: LB_BACKEND_GUEST, Index: idx, BackendRole: "default"} + for _, info := range strings.Split(_backend, ",") { + value := strings.Split(info, ":") + if len(value) != 2 { + return nil, httperrors.NewInputParameterError("Unknown backend info %s", info) + } + switch strings.ToLower(value[0]) { + case "id", "name": + backend.ID = value[1] + case "backend_type", "backendtype", "type": + backend.BackendType = value[1] + case "weight": + v, err := strconv.Atoi(value[1]) + if err != nil || v < 0 || v > 256 { + return nil, httperrors.NewInputParameterError("weight %s not support, only support range 0 ~ 100") + } + backend.Weight = v + case "port": + v, err := strconv.Atoi(value[1]) + if err != nil || v < 1 || v > 65535 { + return nil, httperrors.NewInputParameterError("port %s not support, only support range 1 ~ 65535") + } + backend.Port = v + } + } + if len(backend.ID) == 0 { + return nil, httperrors.NewMissingParameterError("Missing backend id or name params") + } + if backend.Port < 1 || backend.Port > 65535 { + return nil, httperrors.NewInputParameterError("port %s not support, only support range 1 ~ 65535") + } + switch backend.BackendType { + case LB_BACKEND_GUEST: + _guest, err := GuestManager.FetchByIdOrName(userCred, backend.ID) + if err != nil { + if err == sql.ErrNoRows { + return nil, httperrors.NewResourceNotFoundError("failed to find guest %s", backend.ID) + } + return nil, httperrors.NewGeneralError(err) + } + guest := _guest.(*SGuest) + host := guest.GetHost() + if host == nil { + return nil, fmt.Errorf("error getting host of guest %s", guest.Name) + } + if host.ZoneId != lb.ZoneId { + return nil, fmt.Errorf("zone of host %q (%s) != zone of loadbalancer %q (%s)", + host.Name, host.ZoneId, lb.Name, lb.ZoneId) + } + backend.ID = guest.Id + backend.Name = guest.Name + backend.ExternalID = guest.ExternalId + address, err := LoadbalancerBackendManager.getGuestAddress(guest) + if err != nil { + return nil, err + } + backend.Address = address + case LB_BACKEND_HOST: + if !db.IsAdminAllowCreate(userCred, man) { + return nil, httperrors.NewForbiddenError("only sysadmin can specify host as backend") + } + _host, err := HostManager.FetchByIdOrName(userCred, backend.ID) + if err != nil { + if err == sql.ErrNoRows { + return nil, httperrors.NewResourceNotFoundError("failed to find host %s", backend.ID) + } + return nil, httperrors.NewGeneralError(err) + } + host := _host.(*SHost) + backend.ID = host.Id + backend.Name = host.Name + backend.ExternalID = host.ExternalId + backend.Address = host.AccessIp + default: + return nil, httperrors.NewInputParameterError("unexpected backend type %s", backend.BackendType) + } + backends = append(backends, backend) + } + data.Set("backends", jsonutils.Marshal(backends)) + return lb.GetRegion().GetDriver().ValidateCreateLoadbalancerBackendGroupData(ctx, userCred, data, backends) } func (lbbg *SLoadbalancerBackendGroup) GetLoadbalancer() *SLoadbalancer { - lb, _ := LoadbalancerManager.FetchById(lbbg.LoadbalancerId) + lb, err := LoadbalancerManager.FetchById(lbbg.LoadbalancerId) + if err != nil { + return nil + } return lb.(*SLoadbalancer) } +func (llbg *SLoadbalancerBackendGroup) GetRegion() *SCloudregion { + if loadbalancer := llbg.GetLoadbalancer(); loadbalancer != nil { + return loadbalancer.GetRegion() + } + return nil +} + +func (lbbg *SLoadbalancerBackendGroup) GetIRegion() (cloudprovider.ICloudRegion, error) { + if loadbalancer := lbbg.GetLoadbalancer(); loadbalancer != nil { + return loadbalancer.GetIRegion() + } + return nil, fmt.Errorf("failed to find loadbalancer for backendgroup %s", lbbg.Name) +} + func (lbbg *SLoadbalancerBackendGroup) AllowPerformStatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { return false } @@ -123,12 +231,35 @@ func (lbbg *SLoadbalancerBackendGroup) GetExtraDetails(ctx context.Context, user return extra, nil } -func (lbbg *SLoadbalancerBackendGroup) PreDelete(ctx context.Context, userCred mcclient.TokenCredential) { - lbbg.DoPendingDelete(ctx, userCred) - lbbg.PreDeleteSubs(ctx, userCred) +func (lbbg *SLoadbalancerBackendGroup) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) { + lbbg.SVirtualResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data) + params := jsonutils.NewDict() + backends, _ := data.Get("backends") + if backends != nil { + params.Add(backends, "backends") + } + lbbg.SetStatus(userCred, LB_STATUS_CREATING, "") + if err := lbbg.StartLoadBalancerBackendGroupCreateTask(ctx, userCred, params, ""); err != nil { + log.Errorf("Failed to create loadbalancer backendgroup error: %v", err) + } } +func (lbbg *SLoadbalancerBackendGroup) StartLoadBalancerBackendGroupCreateTask(ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerLoadbalancerBackendGroupCreateTask", lbbg, userCred, params, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil +} + +// func (lbbg *SLoadbalancerBackendGroup) PreDelete(ctx context.Context, userCred mcclient.TokenCredential) { +// lbbg.DoPendingDelete(ctx, userCred) +// lbbg.PreDeleteSubs(ctx, userCred) +// } + func (lbbg *SLoadbalancerBackendGroup) PreDeleteSubs(ctx context.Context, userCred mcclient.TokenCredential) { + lbbg.DoCancelPendingDelete(ctx, userCred) subMan := LoadbalancerBackendManager ownerProjId := lbbg.GetOwnerProjectId() @@ -138,6 +269,30 @@ func (lbbg *SLoadbalancerBackendGroup) PreDeleteSubs(ctx context.Context, userCr subMan.PreDeleteSubs(ctx, userCred, q) } +func (lbbg *SLoadbalancerBackendGroup) AllowPerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { + return db.IsAdminAllowPerform(userCred, lbbg, "purge") +} + +func (lbbg *SLoadbalancerBackendGroup) PerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { + parasm := jsonutils.NewDict() + parasm.Add(jsonutils.JSONTrue, "purge") + return nil, lbbg.StartLoadBalancerBackendGroupDeleteTask(ctx, userCred, parasm, "") +} + +func (lbbg *SLoadbalancerBackendGroup) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error { + lbbg.SetStatus(userCred, LB_STATUS_DELETING, "") + return lbbg.StartLoadBalancerBackendGroupDeleteTask(ctx, userCred, jsonutils.NewDict(), "") +} + +func (lbbg *SLoadbalancerBackendGroup) StartLoadBalancerBackendGroupDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerBackendGroupDeleteTask", lbbg, userCred, params, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil +} + func (lbbg *SLoadbalancerBackendGroup) Delete(ctx context.Context, userCred mcclient.TokenCredential) error { return nil } diff --git a/pkg/compute/models/loadbalancerbackends.go b/pkg/compute/models/loadbalancerbackends.go index b7f33f709a..05945dadbf 100644 --- a/pkg/compute/models/loadbalancerbackends.go +++ b/pkg/compute/models/loadbalancerbackends.go @@ -5,10 +5,12 @@ import ( "fmt" "yunion.io/x/jsonutils" + "yunion.io/x/log" "yunion.io/x/pkg/util/compare" "yunion.io/x/sqlchemy" "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/cloudcommon/validators" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/mcclient" @@ -154,6 +156,36 @@ func (lbb *SLoadbalancerBackend) AllowPerformStatus(ctx context.Context, userCre return false } +func (lbb *SLoadbalancerBackend) GetLoadbalancerBackendGroup() *SLoadbalancerBackendGroup { + backendgroup, err := LoadbalancerBackendGroupManager.FetchById(lbb.BackendGroupId) + if err != nil { + return nil + } + return backendgroup.(*SLoadbalancerBackendGroup) +} + +func (lbb *SLoadbalancerBackend) GetGuest() *SGuest { + guest, err := GuestManager.FetchById(lbb.BackendId) + if err != nil { + return nil + } + return guest.(*SGuest) +} + +func (lbb *SLoadbalancerBackend) GetRegion() *SCloudregion { + if backendgroup := lbb.GetLoadbalancerBackendGroup(); backendgroup != nil { + return backendgroup.GetRegion() + } + return nil +} + +func (lbb *SLoadbalancerBackend) GetIRegion() (cloudprovider.ICloudRegion, error) { + if backendgroup := lbb.GetLoadbalancerBackendGroup(); backendgroup != nil { + return backendgroup.GetIRegion() + } + return nil, fmt.Errorf("failed to find backendgroup for backend %s", lbb.Name) +} + func (man *SLoadbalancerBackendManager) getGuestAddress(guest *SGuest) (string, error) { gns := guest.GetNetworks() if len(gns) == 0 { @@ -181,14 +213,55 @@ func (lbb *SLoadbalancerBackend) ValidateUpdateData(ctx context.Context, userCre return lbb.SVirtualResourceBase.ValidateUpdateData(ctx, userCred, query, data) } -func (lbb *SLoadbalancerBackend) PreDelete(ctx context.Context, userCred mcclient.TokenCredential) { - lbb.DoPendingDelete(ctx, userCred) +func (lbb *SLoadbalancerBackend) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) { + lbb.SVirtualResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data) + lbb.SetStatus(userCred, LB_STATUS_CREATING, "") + if err := lbb.StartLoadBalancerBackendCreateTask(ctx, userCred, ""); err != nil { + log.Errorf("Failed to create loadbalancer backend error: %v", err) + } } +func (lbb *SLoadbalancerBackend) StartLoadBalancerBackendCreateTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerLoadbalancerBackendCreateTask", lbb, userCred, nil, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil +} + +// func (lbb *SLoadbalancerBackend) PreDelete(ctx context.Context, userCred mcclient.TokenCredential) { +// lbb.DoPendingDelete(ctx, userCred) +// } + func (lbb *SLoadbalancerBackend) Delete(ctx context.Context, userCred mcclient.TokenCredential) error { return nil } +func (lbb *SLoadbalancerBackend) AllowPerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { + return db.IsAdminAllowPerform(userCred, lbb, "purge") +} + +func (lbb *SLoadbalancerBackend) PerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { + parasm := jsonutils.NewDict() + parasm.Add(jsonutils.JSONTrue, "purge") + return nil, lbb.StartLoadBalancerBackendDeleteTask(ctx, userCred, parasm, "") +} + +func (lbb *SLoadbalancerBackend) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error { + lbb.SetStatus(userCred, LB_STATUS_DELETING, "") + return lbb.StartLoadBalancerBackendDeleteTask(ctx, userCred, jsonutils.NewDict(), "") +} + +func (lbb *SLoadbalancerBackend) StartLoadBalancerBackendDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerBackendDeleteTask", lbb, userCred, params, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil +} + func (man *SLoadbalancerBackendManager) getLoadbalancerBackendsByLoadbalancerBackendgroup(loadbalancerBackendgroup *SLoadbalancerBackendGroup) ([]SLoadbalancerBackend, error) { loadbalancerBackends := []SLoadbalancerBackend{} q := man.Query().Equals("backend_group_id", loadbalancerBackendgroup.Id) @@ -271,6 +344,7 @@ func (lbb *SLoadbalancerBackend) constructFieldsFromCloudLoadbalancerBackend(ext return err } guest := instance.(*SGuest) + lbb.BackendId = guest.Id address, err := LoadbalancerBackendManager.getGuestAddress(guest) if err != nil { return err diff --git a/pkg/compute/models/loadbalancercertificates.go b/pkg/compute/models/loadbalancercertificates.go index 9df95b6188..8bf3e1f73f 100644 --- a/pkg/compute/models/loadbalancercertificates.go +++ b/pkg/compute/models/loadbalancercertificates.go @@ -4,6 +4,7 @@ import ( "context" "crypto/sha256" "crypto/x509" + "database/sql" "encoding/hex" "encoding/pem" "fmt" @@ -16,6 +17,7 @@ import ( "yunion.io/x/sqlchemy" "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/cloudcommon/validators" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/httperrors" @@ -125,7 +127,23 @@ func (man *SLoadbalancerCertificateManager) ValidateCreateData(ctx context.Conte if err != nil { return nil, err } - return man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data) + if _, err := man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data); err != nil { + return nil, err + } + regionID, err := data.GetString("cloudregion_id") + if err != nil { + return nil, httperrors.NewMissingParameterError("cloudregion_id") + } + _region, err := CloudregionManager.FetchByIdOrName(userCred, regionID) + if err != nil { + if err == sql.ErrNoRows { + return nil, httperrors.NewResourceNotFoundError("failed to find cloudregion %s", regionID) + } + return nil, httperrors.NewGeneralError(err) + } + data.Set("cloudregion_id", jsonutils.NewString(_region.GetId())) + region := _region.(*SCloudregion) + return region.GetDriver().ValidateCreateLoadbalancerCertificateData(ctx, userCred, data) } func (man *SLoadbalancerCertificateManager) InitializeData() error { @@ -180,7 +198,28 @@ func (lbcert *SLoadbalancerCertificate) ValidateUpdateData(ctx context.Context, if err != nil { return nil, err } - return lbcert.SVirtualResourceBase.ValidateUpdateData(ctx, userCred, query, data) + if _, err := lbcert.SVirtualResourceBase.ValidateUpdateData(ctx, userCred, query, data); err != nil { + return nil, err + } + return lbcert.GetRegion().GetDriver().ValidateUpdateLoadbalancerCertificateData(ctx, userCred, data) +} + +func (lbcert *SLoadbalancerCertificate) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) { + lbcert.SVirtualResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data) + + lbcert.SetStatus(userCred, LB_STATUS_CREATING, "") + if err := lbcert.StartLoadBalancerCertificateCreateTask(ctx, userCred, ""); err != nil { + log.Errorf("Failed to create loadbalancercertificate error: %v", err) + } +} + +func (lbcert *SLoadbalancerCertificate) StartLoadBalancerCertificateCreateTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerCertificateCreateTask", lbcert, userCred, nil, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil } func (lbcert *SLoadbalancerCertificate) ValidateDeleteCondition(ctx context.Context) error { @@ -203,11 +242,51 @@ func (lbcert *SLoadbalancerCertificate) ValidateDeleteCondition(ctx context.Cont return nil } -func (lbcert *SLoadbalancerCertificate) PreDelete(ctx context.Context, userCred mcclient.TokenCredential) { - lbcert.DoPendingDelete(ctx, userCred) +func (lbcert *SLoadbalancerCertificate) Delete(ctx context.Context, userCred mcclient.TokenCredential) error { + return nil } -func (lbcert *SLoadbalancerCertificate) Delete(ctx context.Context, userCred mcclient.TokenCredential) error { +func (lbcert *SLoadbalancerCertificate) GetRegion() *SCloudregion { + region, err := CloudregionManager.FetchById(lbcert.CloudregionId) + if err != nil { + return nil + } + return region.(*SCloudregion) +} + +func (lbcert *SLoadbalancerCertificate) GetIRegion() (cloudprovider.ICloudRegion, error) { + provider, err := lbcert.GetDriver() + if err != nil { + return nil, fmt.Errorf("No cloudprovide for lbcert %s: %s", lbcert.Name, err) + } + region := lbcert.GetRegion() + if region == nil { + return nil, fmt.Errorf("failed to find region for lbcert %s", lbcert.Name) + } + return provider.GetIRegionById(region.ExternalId) +} + +func (lbcert *SLoadbalancerCertificate) AllowPerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { + return db.IsAdminAllowPerform(userCred, lbcert, "purge") +} + +func (lbcert *SLoadbalancerCertificate) PerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { + parasm := jsonutils.NewDict() + parasm.Add(jsonutils.JSONTrue, "purge") + return nil, lbcert.StartLoadBalancerCertificateDeleteTask(ctx, userCred, parasm, "") +} + +func (lbcert *SLoadbalancerCertificate) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error { + lbcert.SetStatus(userCred, LB_STATUS_DELETING, "") + return lbcert.StartLoadBalancerCertificateDeleteTask(ctx, userCred, jsonutils.NewDict(), "") +} + +func (lbcert *SLoadbalancerCertificate) StartLoadBalancerCertificateDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerCertificateDeleteTask", lbcert, userCred, params, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) return nil } diff --git a/pkg/compute/models/loadbalancerlisteners.go b/pkg/compute/models/loadbalancerlisteners.go index 1700e09b76..6aba9992dc 100644 --- a/pkg/compute/models/loadbalancerlisteners.go +++ b/pkg/compute/models/loadbalancerlisteners.go @@ -12,6 +12,7 @@ import ( "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/cloudprovider" "yunion.io/x/onecloud/pkg/httperrors" @@ -394,12 +395,49 @@ func (lblis *SLoadbalancerListener) GetExtraDetails(ctx context.Context, userCre return extra, nil } -func (lblis *SLoadbalancerListener) PreDelete(ctx context.Context, userCred mcclient.TokenCredential) { - lblis.SetStatus(userCred, LB_STATUS_DISABLED, "preDelete") - lblis.DoPendingDelete(ctx, userCred) - lblis.PreDeleteSubs(ctx, userCred) +func (lblis *SLoadbalancerListener) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) { + lblis.SVirtualResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data) + + lblis.SetStatus(userCred, LB_STATUS_CREATING, "") + if err := lblis.StartLoadBalancerListenerCreateTask(ctx, userCred, ""); err != nil { + log.Errorf("Failed to create loadbalancer listener error: %v", err) + } } +func (lblis *SLoadbalancerListener) StartLoadBalancerListenerCreateTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerListenerCreateTask", lblis, userCred, nil, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil +} + +func (lblis *SLoadbalancerListener) AllowPerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { + return db.IsAdminAllowPerform(userCred, lblis, "purge") +} + +func (lblis *SLoadbalancerListener) PerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { + parasm := jsonutils.NewDict() + parasm.Add(jsonutils.JSONTrue, "purge") + return nil, lblis.StartLoadBalancerListenerDeleteTask(ctx, userCred, parasm, "") +} + +func (lblis *SLoadbalancerListener) StartLoadBalancerListenerDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerListenerDeleteTask", lblis, userCred, params, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil +} + +// func (lblis *SLoadbalancerListener) PreDelete(ctx context.Context, userCred mcclient.TokenCredential) { +// lblis.SetStatus(userCred, LB_STATUS_DISABLED, "preDelete") +// lblis.DoPendingDelete(ctx, userCred) +// lblis.PreDeleteSubs(ctx, userCred) +// } + func (lblis *SLoadbalancerListener) PreDeleteSubs(ctx context.Context, userCred mcclient.TokenCredential) { subMan := LoadbalancerListenerRuleManager ownerProjId := lblis.GetOwnerProjectId() @@ -408,12 +446,28 @@ func (lblis *SLoadbalancerListener) PreDeleteSubs(ctx context.Context, userCred defer lockman.ReleaseClass(ctx, subMan, ownerProjId) q := subMan.Query().Equals("listener_id", lblis.Id) subMan.PreDeleteSubs(ctx, userCred, q) + lblis.DoPendingDelete(ctx, userCred) } func (lblis *SLoadbalancerListener) Delete(ctx context.Context, userCred mcclient.TokenCredential) error { return nil } +func (lblis *SLoadbalancerListener) GetLoadbalancer() *SLoadbalancer { + loadbalancer, err := LoadbalancerManager.FetchById(lblis.LoadbalancerId) + if err != nil { + return nil + } + return loadbalancer.(*SLoadbalancer) +} + +func (lblis *SLoadbalancerListener) GetRegion() *SCloudregion { + if loadbalancer := lblis.GetLoadbalancer(); loadbalancer != nil { + return loadbalancer.GetRegion() + } + return nil +} + func (man *SLoadbalancerListenerManager) getLoadbalancerListenersByLoadbalancer(lb *SLoadbalancer) ([]SLoadbalancerListener, error) { listeners := []SLoadbalancerListener{} q := man.Query().Equals("loadbalancer_id", lb.Id) diff --git a/pkg/compute/models/loadbalancernetworks.go b/pkg/compute/models/loadbalancernetworks.go index 921c759f35..28244397ce 100644 --- a/pkg/compute/models/loadbalancernetworks.go +++ b/pkg/compute/models/loadbalancernetworks.go @@ -51,10 +51,10 @@ func (ln *SLoadbalancerNetwork) Network() *SNetwork { } type SLoadbalancerNetworkRequestData struct { - loadbalancer *SLoadbalancer - networkId string + Loadbalancer *SLoadbalancer + NetworkId string reserved bool // allocate from reserved - address string // the address user intends to use + Address string // the address user intends to use strategy IPAddlocationDirection // allocate bottom up, top down, randomly } @@ -68,13 +68,13 @@ func (m *SLoadbalancernetworkManager) NewLoadbalancerNetwork(ctx context.Context if networkMan == nil { return nil, fmt.Errorf("failed getting network manager") } - im, err := networkMan.FetchById(req.networkId) + im, err := networkMan.FetchById(req.NetworkId) if err != nil { return nil, err } network := im.(*SNetwork) ln := &SLoadbalancerNetwork{ - LoadbalancerId: req.loadbalancer.Id, + LoadbalancerId: req.Loadbalancer.Id, NetworkId: network.Id, } ln.SetModelManager(m) @@ -84,7 +84,7 @@ func (m *SLoadbalancernetworkManager) NewLoadbalancerNetwork(ctx context.Context usedMap := network.GetUsedAddresses() recentReclaimed := map[string]bool{} ipAddr, err := network.GetFreeIP(ctx, userCred, - usedMap, recentReclaimed, req.address, req.strategy, req.reserved) + usedMap, recentReclaimed, req.Address, req.strategy, req.reserved) if err != nil { return nil, err } @@ -125,32 +125,32 @@ func (m *SLoadbalancernetworkManager) DeleteLoadbalancerNetwork(ctx context.Cont } func (m *SLoadbalancernetworkManager) SyncLoadbalancerNetwork(ctx context.Context, userCred mcclient.TokenCredential, req *SLoadbalancerNetworkRequestData) error { - _network, err := NetworkManager.FetchById(req.networkId) + _network, err := NetworkManager.FetchById(req.NetworkId) if err != nil { return err } network := _network.(*SNetwork) - ip, err := netutils.NewIPV4Addr(req.address) + ip, err := netutils.NewIPV4Addr(req.Address) if err != nil { return err } if !network.isAddressInRange(ip) { - return fmt.Errorf("address %s is not in the range of network %s(%s)", req.address, network.Id, network.Name) + return fmt.Errorf("address %s is not in the range of network %s(%s)", req.Address, network.Id, network.Name) } - q := m.Query().Equals("loadbalancer_id", req.loadbalancer.Id).Equals("network_id", req.networkId) + q := m.Query().Equals("loadbalancer_id", req.Loadbalancer.Id).Equals("network_id", req.NetworkId) lns := []SLoadbalancerNetwork{} if err := db.FetchModelObjects(m, q, &lns); err != nil { return err } if len(lns) == 0 { - ln := &SLoadbalancerNetwork{LoadbalancerId: req.loadbalancer.Id, NetworkId: req.networkId, IpAddr: req.address} + ln := &SLoadbalancerNetwork{LoadbalancerId: req.Loadbalancer.Id, NetworkId: req.NetworkId, IpAddr: req.Address} return m.TableSpec().Insert(ln) } for i := 0; i < len(lns); i++ { if i == 0 { - if lns[i].IpAddr != req.address { + if lns[i].IpAddr != req.Address { _, err := lns[i].GetModelManager().TableSpec().Update(&lns[i], func() error { - lns[i].IpAddr = req.address + lns[i].IpAddr = req.Address return nil }) if err != nil { diff --git a/pkg/compute/models/loadbalancers.go b/pkg/compute/models/loadbalancers.go index 3aa4f3d190..214ca73e82 100644 --- a/pkg/compute/models/loadbalancers.go +++ b/pkg/compute/models/loadbalancers.go @@ -12,6 +12,7 @@ import ( "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/cloudprovider" "yunion.io/x/onecloud/pkg/httperrors" @@ -35,6 +36,11 @@ func init() { } } +const ( + LB_CHARGE_TYPE_BY_TRAFFIC = "traffic" + LB_CHARGE_TYPE_BY_BANDWIDTH = "bandwidth" +) + // TODO build errors on pkg/httperrors/errors.go // NewGetManagerError // NewMissingArgumentError @@ -49,15 +55,18 @@ type SLoadbalancer struct { db.SVirtualResourceBase SManagedResourceBase - Address string `width:"16" charset:"ascii" nullable:"false" list:"user" create:"optional"` - AddressType string `width:"16" charset:"ascii" nullable:"false" list:"user" create:"optional"` - NetworkType string `width:"16" charset:"ascii" nullable:"false" list:"user" create:"optional"` + Address string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional"` + AddressType string `width:"16" charset:"ascii" nullable:"false" default:"intranet" list:"user" create:"optional"` + NetworkType string `width:"16" charset:"ascii" nullable:"false" default:"vpc" list:"user" create:"optional"` NetworkId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required"` VpcId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` ZoneId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` CloudregionId string `width:"36" charset:"ascii" nullable:"false" list:"admin" default:"default" create:"optional"` - BackendGroupId string `width:"36" charset:"ascii" nullable:"false" list:"user" update:"user" update:"user"` + ChargeType string `list:"user" default:"traffic" create:"optional"` + LoadbalancerSpec string `list:"user" create:"optional"` + + BackendGroupId string `width:"36" charset:"ascii" nullable:"true" list:"user" update:"user" update:"user"` } func (man *SLoadbalancerManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) { @@ -117,6 +126,14 @@ func (man *SLoadbalancerManager) ValidateCreateData(ctx context.Context, userCre if wire == nil { return nil, fmt.Errorf("getting wire failed") } + vpc := wire.getVpc() + if vpc == nil { + return nil, fmt.Errorf("getting vpc failed") + } + data.Set("vpc_id", jsonutils.NewString(vpc.Id)) + if len(vpc.ManagerId) > 0 { + data.Set("manager_id", jsonutils.NewString(vpc.ManagerId)) + } zone := wire.GetZone() if zone == nil { return nil, fmt.Errorf("getting zone failed") @@ -130,8 +147,11 @@ func (man *SLoadbalancerManager) ValidateCreateData(ctx context.Context, userCre // TODO validate network is of classic type data.Set("network_type", jsonutils.NewString(LB_NETWORK_TYPE_CLASSIC)) data.Set("address_type", jsonutils.NewString(LB_ADDR_TYPE_INTRANET)) + if _, err := man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data); err != nil { + return nil, err + } + return region.GetDriver().ValidateCreateLoadbalancerData(ctx, userCred, data) } - return man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data) } func (lb *SLoadbalancer) AllowPerformStatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { @@ -143,26 +163,91 @@ func (lb *SLoadbalancer) PostCreate(ctx context.Context, userCred mcclient.Token // NOTE lb.Id will only be available after BeforeInsert happens // NOTE this means lb.UpdateVersion will be 0, then 1 after creation // NOTE need ways to notify error - LoadbalancerManager.TableSpec().Update(lb, func() error { - if lb.AddressType == LB_ADDR_TYPE_INTRANET { - // TODO support use reserved ip address - // TODO prefer ip address from server_type loadbalancer? - req := &SLoadbalancerNetworkRequestData{ - loadbalancer: lb, - networkId: lb.NetworkId, - address: lb.Address, - } - // NOTE the small window when agents can see the ephemeral address - ln, err := LoadbalancernetworkManager.NewLoadbalancerNetwork(ctx, userCred, req) - if err != nil { - log.Errorf("allocating loadbalancer network failed: %v, req: %#v", err, req) - lb.Address = "" - } else { - lb.Address = ln.IpAddr - } - } + + lb.SetStatus(userCred, LB_STATUS_CREATING, "") + if err := lb.StartLoadBalancerCreateTask(ctx, userCred, ""); err != nil { + log.Errorf("Failed to create loadbalancer error: %v", err) + } +} + +func (lb *SLoadbalancer) GetCloudprovider() *SCloudprovider { + cloudprovider, err := CloudproviderManager.FetchById(lb.ManagerId) + if err != nil { return nil - }) + } + return cloudprovider.(*SCloudprovider) +} + +func (lb *SLoadbalancer) GetRegion() *SCloudregion { + region, err := CloudregionManager.FetchById(lb.CloudregionId) + if err != nil { + return nil + } + return region.(*SCloudregion) +} + +func (lb *SLoadbalancer) GetZone() *SZone { + zone, err := ZoneManager.FetchById(lb.ZoneId) + if err != nil { + return nil + } + return zone.(*SZone) +} + +func (lb *SLoadbalancer) GetVpc() *SVpc { + vpc, err := VpcManager.FetchById(lb.VpcId) + if err != nil { + return nil + } + return vpc.(*SVpc) +} + +func (lb *SLoadbalancer) GetNetwork() *SNetwork { + network, err := NetworkManager.FetchById(lb.NetworkId) + if err != nil { + return nil + } + return network.(*SNetwork) +} + +func (lb *SLoadbalancer) GetIRegion() (cloudprovider.ICloudRegion, error) { + provider, err := lb.GetDriver() + if err != nil { + return nil, fmt.Errorf("No cloudprovide for lb %s: %s", lb.Name, err) + } + region := lb.GetRegion() + if region == nil { + return nil, fmt.Errorf("failed to find region for lb %s", lb.Name) + } + return provider.GetIRegionById(region.ExternalId) +} + +func (lb *SLoadbalancer) AllowPerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { + return db.IsAdminAllowPerform(userCred, lb, "purge") +} + +func (lb *SLoadbalancer) PerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { + parasm := jsonutils.NewDict() + parasm.Add(jsonutils.JSONTrue, "purge") + return nil, lb.StartLoadBalancerDeleteTask(ctx, userCred, parasm, "") +} + +func (lb *SLoadbalancer) StartLoadBalancerDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerDeleteTask", lb, userCred, params, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil +} + +func (lb *SLoadbalancer) StartLoadBalancerCreateTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerCreateTask", lb, userCred, nil, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil } func (lb *SLoadbalancer) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { @@ -200,23 +285,17 @@ func (lb *SLoadbalancer) GetExtraDetails(ctx context.Context, userCred mcclient. } func (lb *SLoadbalancer) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error { - if len(lb.Address) > 0 { - // TODO reserve support + lb.SetStatus(userCred, LB_STATUS_DELETING, "") + return lb.StartLoadBalancerDeleteTask(ctx, userCred, jsonutils.NewDict(), "") +} + +func (lb *SLoadbalancer) PendingDelete(ctx context.Context, userCred mcclient.TokenCredential) { + if len(lb.NetworkId) > 0 { req := &SLoadbalancerNetworkDeleteData{ loadbalancer: lb, } - err := LoadbalancernetworkManager.DeleteLoadbalancerNetwork(ctx, userCred, req) - if err != nil { - return err - } - lb.Address = "" + LoadbalancernetworkManager.DeleteLoadbalancerNetwork(ctx, userCred, req) } - // TODO How about mark pending delete and return - return nil -} - -func (lb *SLoadbalancer) PreDelete(ctx context.Context, userCred mcclient.TokenCredential) { - lb.SetStatus(userCred, LB_STATUS_DISABLED, "preDelete") lb.DoPendingDelete(ctx, userCred) lb.PreDeleteSubs(ctx, userCred) } @@ -326,6 +405,8 @@ func (man *SLoadbalancerManager) newFromCloudLoadbalancer(ctx context.Context, u lb.NetworkType = extLb.GetNetworkType() lb.Name = extLb.GetName() lb.Status = extLb.GetStatus() + lb.LoadbalancerSpec = extLb.GetLoadbalancerSpec() + lb.ChargeType = extLb.GetChargeType() lb.ExternalId = extLb.GetGlobalId() if networkId := extLb.GetNetworkId(); len(networkId) > 0 { if network, err := NetworkManager.FetchByExternalId(networkId); err == nil && network != nil { @@ -359,9 +440,9 @@ func (man *SLoadbalancerManager) newFromCloudLoadbalancer(ctx context.Context, u func (lb *SLoadbalancer) syncLoadbalancerNetwork(ctx context.Context, userCred mcclient.TokenCredential) { if len(lb.NetworkId) > 0 { lbNetReq := &SLoadbalancerNetworkRequestData{ - loadbalancer: lb, - networkId: lb.NetworkId, - address: lb.Address, + Loadbalancer: lb, + NetworkId: lb.NetworkId, + Address: lb.Address, } err := LoadbalancernetworkManager.SyncLoadbalancerNetwork(ctx, userCred, lbNetReq) if err != nil { @@ -375,11 +456,9 @@ func (lb *SLoadbalancer) SyncWithCloudLoadbalancer(ctx context.Context, userCred lb.Address = extLb.GetAddress() lb.Status = extLb.GetStatus() lb.Name = extLb.GetName() - if networkId := extLb.GetNetworkId(); len(networkId) > 0 { - if network, err := NetworkManager.FetchByExternalId(networkId); err == nil && network != nil { - lb.NetworkId = network.GetId() - } - } + lb.LoadbalancerSpec = extLb.GetLoadbalancerSpec() + lb.ChargeType = extLb.GetChargeType() + if projectSync && len(projectId) > 0 { lb.ProjectId = projectId } diff --git a/pkg/compute/models/regiondrivers.go b/pkg/compute/models/regiondrivers.go new file mode 100644 index 0000000000..899e0f48ed --- /dev/null +++ b/pkg/compute/models/regiondrivers.go @@ -0,0 +1,57 @@ +package models + +import ( + "context" + + "yunion.io/x/jsonutils" + "yunion.io/x/log" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/mcclient" +) + +type IRegionDriver interface { + GetProvider() string + + ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) + RequestCreateLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *SLoadbalancer, task taskman.ITask) error + RequestDeleteLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *SLoadbalancer, task taskman.ITask) error + + ValidateCreateLoadbalancerAclData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) + RequestCreateLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *SLoadbalancerAcl, task taskman.ITask) error + RequestDeleteLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *SLoadbalancerAcl, task taskman.ITask) error + + ValidateCreateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) + ValidateUpdateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) + RequestCreateLoadbalancerCertificate(ctx context.Context, userCred mcclient.TokenCredential, lbcert *SLoadbalancerCertificate, task taskman.ITask) error + RequestDeleteLoadbalancerCertificate(ctx context.Context, userCred mcclient.TokenCredential, lbcert *SLoadbalancerCertificate, task taskman.ITask) error + + ValidateCreateLoadbalancerBackendGroupData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backends []cloudprovider.SLoadbalancerBackend) (*jsonutils.JSONDict, error) + 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 + + RequestCreateLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, lbb *SLoadbalancerBackend, task taskman.ITask) error + RequestDeleteLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, lbb *SLoadbalancerBackend, task taskman.ITask) error + + RequestCreateLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *SLoadbalancerListener, task taskman.ITask) error + RequestDeleteLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *SLoadbalancerListener, task taskman.ITask) error +} + +var regionDrivers map[string]IRegionDriver + +func init() { + regionDrivers = make(map[string]IRegionDriver) +} + +func RegisterRegionDriver(driver IRegionDriver) { + regionDrivers[driver.GetProvider()] = driver +} + +func GetRegionDriver(provider string) IRegionDriver { + driver, ok := regionDrivers[provider] + if ok { + return driver + } + log.Fatalf("Unsupported provider %s", provider) + return nil +} diff --git a/pkg/compute/regiondrivers/aliyun.go b/pkg/compute/regiondrivers/aliyun.go new file mode 100644 index 0000000000..17a5f94f65 --- /dev/null +++ b/pkg/compute/regiondrivers/aliyun.go @@ -0,0 +1,60 @@ +package regiondrivers + +import ( + "context" + + "yunion.io/x/jsonutils" + "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/pkg/utils" +) + +type SAliyunRegionDriver struct { + SManagedVirtualizationRegionDriver +} + +func init() { + driver := SAliyunRegionDriver{} + models.RegisterRegionDriver(&driver) +} + +func (self *SAliyunRegionDriver) GetProvider() string { + return models.CLOUD_PROVIDER_ALIYUN +} + +func (self *SAliyunRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + loadbalancerSpec, _ := data.GetString("loadbalancer_spec") + if len(loadbalancerSpec) != 0 && !utils.IsInStringArray(loadbalancerSpec, []string{"slb.s1.small", "slb.s2.small", "slb.s2.mediu", "slb.s3.small", "slb.s3.mediu", "slb.s3.large"}) { + return nil, httperrors.NewInputParameterError("Unsupport loadbalancer_spec %s, support slb.s1.small、slb.s2.small、slb.s2.medium、slb.s3.small、slb.s3.medium、slb.s3.large", loadbalancerSpec) + } + return data, nil +} + +func (self *SAliyunRegionDriver) ValidateUpdateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + if data.Contains("certificate") || data.Contains("private_key") { + return nil, httperrors.NewUnsupportOperationError("Aliyun not allow to change certificate") + } + return data, nil +} + +func (self *SAliyunRegionDriver) ValidateCreateLoadbalancerBackendGroupData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backends []cloudprovider.SLoadbalancerBackend) (*jsonutils.JSONDict, error) { + groupType, _ := data.GetString("type") + switch groupType { + case "", models.LB_BACKENDGROUP_TYPE_NORMAL: + break + case models.LB_BACKENDGROUP_TYPE_MASTER_SLAVE: + if len(backends) != 2 { + return nil, httperrors.NewInputParameterError("master slave backendgorup must contain two backend") + } + default: + return nil, httperrors.NewInputParameterError("Unsupport backendgorup type %s", groupType) + } + for _, backend := range backends { + if len(backend.ExternalID) == 0 { + return nil, httperrors.NewInputParameterError("invalid guest %s", backend.Name) + } + } + return data, nil +} diff --git a/pkg/compute/regiondrivers/aws.go b/pkg/compute/regiondrivers/aws.go new file mode 100644 index 0000000000..c56817fb61 --- /dev/null +++ b/pkg/compute/regiondrivers/aws.go @@ -0,0 +1,18 @@ +package regiondrivers + +import ( + "yunion.io/x/onecloud/pkg/compute/models" +) + +type SAwsRegionDriver struct { + SManagedVirtualizationRegionDriver +} + +func init() { + driver := SAwsRegionDriver{} + models.RegisterRegionDriver(&driver) +} + +func (self *SAwsRegionDriver) GetProvider() string { + return models.CLOUD_PROVIDER_AWS +} diff --git a/pkg/compute/regiondrivers/azure.go b/pkg/compute/regiondrivers/azure.go new file mode 100644 index 0000000000..e19b1749bc --- /dev/null +++ b/pkg/compute/regiondrivers/azure.go @@ -0,0 +1,18 @@ +package regiondrivers + +import ( + "yunion.io/x/onecloud/pkg/compute/models" +) + +type SAzureRegionDriver struct { + SManagedVirtualizationRegionDriver +} + +func init() { + driver := SAzureRegionDriver{} + models.RegisterRegionDriver(&driver) +} + +func (self *SAzureRegionDriver) GetProvider() string { + return models.CLOUD_PROVIDER_AZURE +} diff --git a/pkg/compute/regiondrivers/base.go b/pkg/compute/regiondrivers/base.go new file mode 100644 index 0000000000..2f276f7846 --- /dev/null +++ b/pkg/compute/regiondrivers/base.go @@ -0,0 +1,62 @@ +package regiondrivers + +import ( + "context" + "fmt" + + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/mcclient" +) + +type SBaseRegionDriver struct { +} + +func (self *SBaseRegionDriver) RequestCreateLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestCreateLoadbalancer") +} + +func (self *SBaseRegionDriver) RequestDeleteLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestDeleteLoadbalancer") +} + +func (self *SBaseRegionDriver) RequestCreateLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *models.SLoadbalancerAcl, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestCreateLoadbalancerAcl") +} + +func (self *SBaseRegionDriver) RequestDeleteLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *models.SLoadbalancerAcl, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestDeleteLoadbalancerAcl") +} + +func (self *SBaseRegionDriver) RequestCreateLoadbalancerCertificate(ctx context.Context, userCred mcclient.TokenCredential, lbcert *models.SLoadbalancerCertificate, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestCreateLoadbalancerCertificate") +} + +func (self *SBaseRegionDriver) RequestDeleteLoadbalancerCertificate(ctx context.Context, userCred mcclient.TokenCredential, lbcert *models.SLoadbalancerCertificate, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestDeleteLoadbalancerCertificate") +} + +func (self *SBaseRegionDriver) RequestCreateLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lbbg *models.SLoadbalancerBackendGroup, backends []cloudprovider.SLoadbalancerBackend, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestCreateLoadbalancerBackendGroup") +} + +func (self *SBaseRegionDriver) RequestDeleteLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lbbg *models.SLoadbalancerBackendGroup, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestDeleteLoadbalancerBackendGroup") +} + +func (self *SBaseRegionDriver) RequestCreateLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, lbb *models.SLoadbalancerBackend, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestCreateLoadbalancerBackend") +} + +func (self *SBaseRegionDriver) RequestDeleteLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, lbb *models.SLoadbalancerBackend, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestDeleteLoadbalancerBackend") +} + +func (self *SBaseRegionDriver) RequestCreateLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestCreateLoadbalancerListener") +} + +func (self *SBaseRegionDriver) RequestDeleteLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestDeleteLoadbalancerListener") +} diff --git a/pkg/compute/regiondrivers/esxi.go b/pkg/compute/regiondrivers/esxi.go new file mode 100644 index 0000000000..010e91c919 --- /dev/null +++ b/pkg/compute/regiondrivers/esxi.go @@ -0,0 +1,18 @@ +package regiondrivers + +import ( + "yunion.io/x/onecloud/pkg/compute/models" +) + +type SEsxiRegionDriver struct { + SManagedVirtualizationRegionDriver +} + +func init() { + driver := SEsxiRegionDriver{} + models.RegisterRegionDriver(&driver) +} + +func (self *SEsxiRegionDriver) GetProvider() string { + return models.CLOUD_PROVIDER_VMWARE +} diff --git a/pkg/compute/regiondrivers/huawei.go b/pkg/compute/regiondrivers/huawei.go new file mode 100644 index 0000000000..f54c480666 --- /dev/null +++ b/pkg/compute/regiondrivers/huawei.go @@ -0,0 +1,18 @@ +package regiondrivers + +import ( + "yunion.io/x/onecloud/pkg/compute/models" +) + +type SHuaWeiRegionDriver struct { + SManagedVirtualizationRegionDriver +} + +func init() { + driver := SHuaWeiRegionDriver{} + models.RegisterRegionDriver(&driver) +} + +func (self *SHuaWeiRegionDriver) GetProvider() string { + return models.CLOUD_PROVIDER_HUAWEI +} diff --git a/pkg/compute/regiondrivers/kvm.go b/pkg/compute/regiondrivers/kvm.go new file mode 100644 index 0000000000..f3b0c1d8e1 --- /dev/null +++ b/pkg/compute/regiondrivers/kvm.go @@ -0,0 +1,147 @@ +package regiondrivers + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + "yunion.io/x/log" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/mcclient" +) + +type SKVMRegionDriver struct { + SBaseRegionDriver +} + +func init() { + driver := SKVMRegionDriver{} + models.RegisterRegionDriver(&driver) +} + +func (self *SKVMRegionDriver) GetProvider() string { + return models.CLOUD_PROVIDER_KVM +} + +func (self *SKVMRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + return data, nil +} + +func (self *SKVMRegionDriver) ValidateCreateLoadbalancerAclData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + return data, nil +} + +func (self *SKVMRegionDriver) ValidateCreateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + return data, nil +} + +func (self *SKVMRegionDriver) ValidateUpdateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + return data, nil +} + +func (self *SKVMRegionDriver) ValidateCreateLoadbalancerBackendGroupData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backends []cloudprovider.SLoadbalancerBackend) (*jsonutils.JSONDict, error) { + return data, nil +} + +func (self *SKVMRegionDriver) RequestCreateLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + _, err := models.LoadbalancerManager.TableSpec().Update(lb, func() error { + if lb.AddressType == models.LB_ADDR_TYPE_INTRANET { + // TODO support use reserved ip address + // TODO prefer ip address from server_type loadbalancer? + req := &models.SLoadbalancerNetworkRequestData{ + Loadbalancer: lb, + NetworkId: lb.NetworkId, + Address: lb.Address, + } + // NOTE the small window when agents can see the ephemeral address + ln, err := models.LoadbalancernetworkManager.NewLoadbalancerNetwork(ctx, userCred, req) + if err != nil { + log.Errorf("allocating loadbalancer network failed: %v, req: %#v", err, req) + lb.Address = "" + } else { + lb.Address = ln.IpAddr + } + } + return nil + }) + return nil, err + }) + return nil +} + +func (self *SKVMRegionDriver) RequestDeleteLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { + task.ScheduleRun(nil) + return nil +} + +func (self *SKVMRegionDriver) RequestCreateLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *models.SLoadbalancerAcl, task taskman.ITask) error { + task.ScheduleRun(nil) + return nil +} + +func (self *SKVMRegionDriver) RequestDeleteLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *models.SLoadbalancerAcl, task taskman.ITask) error { + task.ScheduleRun(nil) + return nil +} + +func (self *SKVMRegionDriver) RequestCreateLoadbalancerCertificate(ctx context.Context, userCred mcclient.TokenCredential, lbcert *models.SLoadbalancerCertificate, task taskman.ITask) error { + task.ScheduleRun(nil) + return nil +} + +func (self *SKVMRegionDriver) RequestDeleteLoadbalancerCertificate(ctx context.Context, userCred mcclient.TokenCredential, lbcert *models.SLoadbalancerCertificate, task taskman.ITask) error { + task.ScheduleRun(nil) + return nil +} + +func (self *SKVMRegionDriver) RequestCreateLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lbbg *models.SLoadbalancerBackendGroup, backends []cloudprovider.SLoadbalancerBackend, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + for _, backend := range backends { + loadbalancerBackend := models.SLoadbalancerBackend{ + BackendGroupId: lbbg.Id, + BackendId: backend.ID, + BackendType: backend.BackendType, + BackendRole: backend.BackendRole, + Weight: backend.Weight, + Address: backend.Address, + Port: backend.Port, + } + loadbalancerBackend.Status = models.LB_STATUS_ENABLED + loadbalancerBackend.ProjectId = userCred.GetProjectId() + loadbalancerBackend.Name = fmt.Sprintf("%s-%s-%s", lbbg.Name, backend.BackendType, backend.Name) + if err := models.LoadbalancerBackendManager.TableSpec().Insert(&loadbalancerBackend); err != nil { + return nil, err + } + } + return nil, nil + }) + return nil +} + +func (self *SKVMRegionDriver) RequestDeleteLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lbbg *models.SLoadbalancerBackendGroup, task taskman.ITask) error { + task.ScheduleRun(nil) + return nil +} + +func (self *SKVMRegionDriver) RequestCreateLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, lbb *models.SLoadbalancerBackend, task taskman.ITask) error { + task.ScheduleRun(nil) + return nil +} + +func (self *SKVMRegionDriver) RequestDeleteLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, lbb *models.SLoadbalancerBackend, task taskman.ITask) error { + task.ScheduleRun(nil) + return nil +} + +func (self *SKVMRegionDriver) RequestCreateLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { + task.ScheduleRun(nil) + return nil +} + +func (self *SKVMRegionDriver) RequestDeleteLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { + task.ScheduleRun(nil) + return nil +} diff --git a/pkg/compute/regiondrivers/managedvirtual.go b/pkg/compute/regiondrivers/managedvirtual.go new file mode 100644 index 0000000000..bf191edc65 --- /dev/null +++ b/pkg/compute/regiondrivers/managedvirtual.go @@ -0,0 +1,399 @@ +package regiondrivers + +import ( + "context" + "database/sql" + "fmt" + + "yunion.io/x/jsonutils" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/mcclient" +) + +type SManagedVirtualizationRegionDriver struct { + SVirtualizationRegionDriver +} + +func (self *SManagedVirtualizationRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + return data, nil +} + +func (self *SManagedVirtualizationRegionDriver) ValidateManagerId(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + managerID := jsonutils.GetAnyString(data, []string{"manager_id", "manager"}) + if len(managerID) == 0 { + return nil, httperrors.NewMissingParameterError("manager_id") + } + provider, err := models.CloudproviderManager.FetchByIdOrName(userCred, managerID) + if err != nil { + if err == sql.ErrNoRows { + return nil, httperrors.NewResourceNotFoundError("failed to find cloudprovider %s", managerID) + } + return nil, httperrors.NewGeneralError(err) + } + data.Set("manager_id", jsonutils.NewString(provider.GetId())) + return data, nil +} + +func (self *SManagedVirtualizationRegionDriver) ValidateCreateLoadbalancerAclData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + return self.ValidateManagerId(ctx, userCred, data) +} + +func (self *SManagedVirtualizationRegionDriver) ValidateCreateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + return data, nil +} + +func (self *SManagedVirtualizationRegionDriver) ValidateUpdateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + return data, nil +} + +func (self *SManagedVirtualizationRegionDriver) ValidateCreateLoadbalancerBackendGroupData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backends []cloudprovider.SLoadbalancerBackend) (*jsonutils.JSONDict, error) { + for _, backend := range backends { + if len(backend.ExternalID) == 0 { + return nil, httperrors.NewInputParameterError("invalid guest %s", backend.Name) + } + } + return data, nil +} + +func (self *SManagedVirtualizationRegionDriver) RequestCreateLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + params := &cloudprovider.SLoadbalancer{ + Name: lb.Name, + Address: lb.Address, + AddressType: lb.AddressType, + ChargeType: lb.ChargeType, + LoadbalancerSpec: lb.LoadbalancerSpec, + } + iRegion, err := lb.GetIRegion() + if err != nil { + return nil, err + } + if len(lb.ZoneId) > 0 { + zone := lb.GetZone() + if zone == nil { + return nil, fmt.Errorf("failed to find zone for lb %s", lb.Name) + } + iZone, err := iRegion.GetIZoneById(zone.ExternalId) + if err != nil { + return nil, err + } + params.ZoneID = iZone.GetId() + } + if len(lb.VpcId) > 0 { + vpc := lb.GetVpc() + if vpc == nil { + return nil, fmt.Errorf("failed to find vpc for lb %s", lb.Name) + } + iVpc, err := iRegion.GetIVpcById(vpc.ExternalId) + if err != nil { + return nil, err + } + params.VpcID = iVpc.GetId() + } + if len(lb.NetworkId) > 0 { + network := lb.GetNetwork() + if network == nil { + return nil, fmt.Errorf("failed to find network for lb %s", lb.Name) + } + iNetwork, err := network.GetINetwork() + if err != nil { + return nil, err + } + params.NetworkID = iNetwork.GetId() + } + iLoadbalancer, err := iRegion.CreateILoadBalancer(params) + if err != nil { + return nil, err + } + if err := lb.SetExternalId(iLoadbalancer.GetGlobalId()); err != nil { + return nil, err + } + if err := lb.SyncWithCloudLoadbalancer(ctx, userCred, iLoadbalancer, "", false); err != nil { + return nil, err + } + if lb.AddressType == models.LB_ADDR_TYPE_INTRANET { + req := &models.SLoadbalancerNetworkRequestData{ + Loadbalancer: lb, + NetworkId: lb.NetworkId, + Address: lb.Address, + } + if _, err := models.LoadbalancernetworkManager.NewLoadbalancerNetwork(ctx, userCred, req); err != nil { + return nil, err + } + } + + lbbgs, err := iLoadbalancer.GetILoadbalancerBackendGroups() + if err != nil { + return nil, err + } + if len(lbbgs) > 0 { + provider := lb.GetCloudprovider() + if provider == nil { + return nil, fmt.Errorf("failed to find cloudprovider for lb %s", lb.Name) + } + models.LoadbalancerBackendGroupManager.SyncLoadbalancerBackendgroups(ctx, userCred, provider, lb, lbbgs, &models.SSyncRange{}) + } + return nil, nil + }) + return nil +} + +func (self *SManagedVirtualizationRegionDriver) RequestDeleteLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + if jsonutils.QueryBoolean(task.GetParams(), "purge", false) { + return nil, nil + } + iRegion, err := lb.GetIRegion() + if err != nil { + return nil, err + } + iLoadbalancer, err := iRegion.GetILoadBalancerById(lb.ExternalId) + if err != nil { + if err == cloudprovider.ErrNotFound { + return nil, nil + } + return nil, err + } + return nil, iLoadbalancer.Delete() + }) + return nil +} + +func (self *SManagedVirtualizationRegionDriver) RequestCreateLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *models.SLoadbalancerAcl, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + iRegion, err := lbacl.GetIRegion() + if err != nil { + return nil, err + } + acl := &cloudprovider.SLoadbalancerAccessControlList{Name: lbacl.Name, Entrys: []cloudprovider.SLoadbalancerAccessControlListEntry{}} + if lbacl.AclEntries != nil { + for _, entry := range *lbacl.AclEntries { + acl.Entrys = append(acl.Entrys, cloudprovider.SLoadbalancerAccessControlListEntry{CIDR: entry.Cidr, Comment: entry.Comment}) + } + } + iLoadbalancerAcl, err := iRegion.CreateILoadBalancerAcl(acl) + if err != nil { + return nil, err + } + if err := lbacl.SetExternalId(iLoadbalancerAcl.GetGlobalId()); err != nil { + return nil, err + } + return nil, lbacl.SyncWithCloudLoadbalancerAcl(ctx, userCred, iLoadbalancerAcl, "", false) + }) + return nil +} + +func (self *SManagedVirtualizationRegionDriver) RequestDeleteLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *models.SLoadbalancerAcl, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + if jsonutils.QueryBoolean(task.GetParams(), "purge", false) { + return nil, nil + } + iRegion, err := lbacl.GetIRegion() + if err != nil { + return nil, err + } + iLoadbalancerAcl, err := iRegion.GetILoadBalancerAclById(lbacl.ExternalId) + if err != nil { + if err == cloudprovider.ErrNotFound { + return nil, nil + } + return nil, err + } + return nil, iLoadbalancerAcl.Delete() + }) + return nil +} + +func (self *SManagedVirtualizationRegionDriver) RequestCreateLoadbalancerCertificate(ctx context.Context, userCred mcclient.TokenCredential, lbcert *models.SLoadbalancerCertificate, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + iRegion, err := lbcert.GetIRegion() + if err != nil { + return nil, err + } + iLoadbalancerCert, err := iRegion.CreateILoadBalancerCertificate(lbcert.Name, lbcert.PrivateKey, lbcert.Certificate) + if err != nil { + return nil, err + } + if err := lbcert.SetExternalId(iLoadbalancerCert.GetGlobalId()); err != nil { + return nil, err + } + return nil, lbcert.SyncWithCloudLoadbalancerCertificate(ctx, userCred, iLoadbalancerCert, "", false) + }) + return nil +} + +func (self *SManagedVirtualizationRegionDriver) RequestDeleteLoadbalancerCertificate(ctx context.Context, userCred mcclient.TokenCredential, lbcert *models.SLoadbalancerCertificate, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + if jsonutils.QueryBoolean(task.GetParams(), "purge", false) { + return nil, nil + } + iRegion, err := lbcert.GetIRegion() + if err != nil { + return nil, err + } + iLoadbalancerCert, err := iRegion.GetILoadBalancerCertificateById(lbcert.ExternalId) + if err != nil { + if err == cloudprovider.ErrNotFound { + return nil, nil + } + return nil, err + } + return nil, iLoadbalancerCert.Delete() + }) + return nil +} + +func (self *SManagedVirtualizationRegionDriver) RequestCreateLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lbbg *models.SLoadbalancerBackendGroup, backends []cloudprovider.SLoadbalancerBackend, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + iRegion, err := lbbg.GetIRegion() + if err != nil { + return nil, err + } + loadbalancer := lbbg.GetLoadbalancer() + if loadbalancer == nil { + return nil, fmt.Errorf("failed to find loadbalancer for backendgroup %s", lbbg.Name) + } + iLoadbalancer, err := iRegion.GetILoadBalancerById(loadbalancer.ExternalId) + if err != nil { + return nil, err + } + iLoadbalancerBackendGroup, err := iLoadbalancer.CreateILoadBalancerBackendGroup(lbbg.Name, lbbg.Type, backends) + if err != nil { + return nil, err + } + if err := lbbg.SetExternalId(iLoadbalancerBackendGroup.GetGlobalId()); err != nil { + return nil, err + } + iBackends, err := iLoadbalancerBackendGroup.GetILoadbalancerBackends() + if err != nil { + return nil, err + } + if len(iBackends) > 0 { + provider := loadbalancer.GetCloudprovider() + if provider == nil { + return nil, fmt.Errorf("failed to find cloudprovider for lb %s", loadbalancer.Name) + } + models.LoadbalancerBackendManager.SyncLoadbalancerBackends(ctx, userCred, provider, lbbg, iBackends, &models.SSyncRange{}) + } + return nil, nil + }) + return nil +} + +func (self *SManagedVirtualizationRegionDriver) RequestDeleteLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lbbg *models.SLoadbalancerBackendGroup, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + if jsonutils.QueryBoolean(task.GetParams(), "purge", false) { + return nil, nil + } + iRegion, err := lbbg.GetIRegion() + if err != nil { + return nil, err + } + loadbalancer := lbbg.GetLoadbalancer() + if loadbalancer == nil { + return nil, fmt.Errorf("failed to find loadbalancer for backendgroup %s", lbbg.Name) + } + iLoadbalancer, err := iRegion.GetILoadBalancerById(loadbalancer.ExternalId) + if err != nil { + return nil, err + } + iLoadbalancerBackendGroup, err := iLoadbalancer.GetILoadbalancerBackendGroupById(lbbg.ExternalId) + if err != nil { + if err == cloudprovider.ErrNotFound { + return nil, nil + } + return nil, err + } + return nil, iLoadbalancerBackendGroup.Delete() + }) + return nil +} + +func (self *SManagedVirtualizationRegionDriver) RequestCreateLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, lbb *models.SLoadbalancerBackend, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + lbbg := lbb.GetLoadbalancerBackendGroup() + if lbbg == nil { + return nil, fmt.Errorf("failed to find lbbg for backend %s", lbb.Name) + } + lb := lbbg.GetLoadbalancer() + if lb == nil { + return nil, fmt.Errorf("failed to find lb for backendgroup %s", lbbg.Name) + } + iRegion, err := lb.GetIRegion() + if err != nil { + return nil, err + } + iLoadbalancer, err := iRegion.GetILoadBalancerById(lb.ExternalId) + if err != nil { + return nil, err + } + iLoadbalancerBackendGroup, err := iLoadbalancer.GetILoadbalancerBackendGroupById(lbbg.ExternalId) + if err != nil { + return nil, err + } + guest := lbb.GetGuest() + if guest == nil { + return nil, fmt.Errorf("failed to find guest for lbb %s", lbb.Name) + } + iLoadbalancerBackend, err := iLoadbalancerBackendGroup.AddBackendServer(guest.ExternalId, lbb.Weight, lbb.Port) + if err != nil { + return nil, err + } + return nil, lbb.SyncWithCloudLoadbalancerBackend(ctx, userCred, iLoadbalancerBackend, "", false) + }) + return nil +} + +func (self *SManagedVirtualizationRegionDriver) RequestDeleteLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, lbb *models.SLoadbalancerBackend, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + if jsonutils.QueryBoolean(task.GetParams(), "purge", false) { + return nil, nil + } + lbbg := lbb.GetLoadbalancerBackendGroup() + if lbbg == nil { + return nil, fmt.Errorf("failed to find lbbg for backend %s", lbb.Name) + } + lb := lbbg.GetLoadbalancer() + if lb == nil { + return nil, fmt.Errorf("failed to find lb for backendgroup %s", lbbg.Name) + } + iRegion, err := lb.GetIRegion() + if err != nil { + return nil, err + } + iLoadbalancer, err := iRegion.GetILoadBalancerById(lb.ExternalId) + if err != nil { + return nil, err + } + iLoadbalancerBackendGroup, err := iLoadbalancer.GetILoadbalancerBackendGroupById(lbbg.ExternalId) + if err != nil { + return nil, err + } + guest := lbb.GetGuest() + if guest == nil { + return nil, fmt.Errorf("failed to find guest for lbb %s", lbb.Name) + } + return nil, iLoadbalancerBackendGroup.RemoveBackendServer(guest.ExternalId) + }) + return nil +} + +func (self *SManagedVirtualizationRegionDriver) RequestCreateLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + return nil, nil + }) + return nil +} + +func (self *SManagedVirtualizationRegionDriver) RequestDeleteLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + if jsonutils.QueryBoolean(task.GetParams(), "purge", false) { + return nil, nil + } + return nil, nil + }) + return nil +} diff --git a/pkg/compute/regiondrivers/openstack.go b/pkg/compute/regiondrivers/openstack.go new file mode 100644 index 0000000000..0f6db5e04e --- /dev/null +++ b/pkg/compute/regiondrivers/openstack.go @@ -0,0 +1,18 @@ +package regiondrivers + +import ( + "yunion.io/x/onecloud/pkg/compute/models" +) + +type SOpenStackRegionDriver struct { + SManagedVirtualizationRegionDriver +} + +func init() { + driver := SOpenStackRegionDriver{} + models.RegisterRegionDriver(&driver) +} + +func (self *SOpenStackRegionDriver) GetProvider() string { + return models.CLOUD_PROVIDER_OPENSTACK +} diff --git a/pkg/compute/regiondrivers/qcloud.go b/pkg/compute/regiondrivers/qcloud.go new file mode 100644 index 0000000000..6aed19e9be --- /dev/null +++ b/pkg/compute/regiondrivers/qcloud.go @@ -0,0 +1,18 @@ +package regiondrivers + +import ( + "yunion.io/x/onecloud/pkg/compute/models" +) + +type SQcloudRegionDriver struct { + SManagedVirtualizationRegionDriver +} + +func init() { + driver := SQcloudRegionDriver{} + models.RegisterRegionDriver(&driver) +} + +func (self *SQcloudRegionDriver) GetProvider() string { + return models.CLOUD_PROVIDER_QCLOUD +} diff --git a/pkg/compute/regiondrivers/virtualization.go b/pkg/compute/regiondrivers/virtualization.go new file mode 100644 index 0000000000..75afea6d53 --- /dev/null +++ b/pkg/compute/regiondrivers/virtualization.go @@ -0,0 +1,5 @@ +package regiondrivers + +type SVirtualizationRegionDriver struct { + SBaseRegionDriver +} diff --git a/pkg/compute/service/service.go b/pkg/compute/service/service.go index 048f5ef7ed..97d7393017 100644 --- a/pkg/compute/service/service.go +++ b/pkg/compute/service/service.go @@ -10,6 +10,7 @@ import ( _ "yunion.io/x/onecloud/pkg/compute/guestdrivers" _ "yunion.io/x/onecloud/pkg/compute/hostdrivers" + _ "yunion.io/x/onecloud/pkg/compute/regiondrivers" _ "yunion.io/x/onecloud/pkg/compute/tasks" _ "yunion.io/x/onecloud/pkg/util/aliyun/provider" _ "yunion.io/x/onecloud/pkg/util/aws/provider" diff --git a/pkg/compute/tasks/loadbalancer_backend_create_task.go b/pkg/compute/tasks/loadbalancer_backend_create_task.go new file mode 100644 index 0000000000..ad664ff559 --- /dev/null +++ b/pkg/compute/tasks/loadbalancer_backend_create_task.go @@ -0,0 +1,47 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerBackendCreateTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerBackendCreateTask{}) +} + +func (self *LoadbalancerBackendCreateTask) taskFail(ctx context.Context, lbb *models.SLoadbalancerBackend, reason string) { + lbb.SetStatus(self.GetUserCred(), models.LB_STATUS_CREATE_FAILED, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerBackendCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lbb := obj.(*models.SLoadbalancerBackend) + region := lbb.GetRegion() + if region == nil { + self.taskFail(ctx, lbb, fmt.Sprintf("failed to find region for lbb %s", lbb.Name)) + return + } + self.SetStage("OnLoadbalancerBackendCreateComplete", nil) + if err := region.GetDriver().RequestCreateLoadbalancerBackend(ctx, self.GetUserCred(), lbb, self); err != nil { + self.taskFail(ctx, lbb, err.Error()) + } +} + +func (self *LoadbalancerBackendCreateTask) OnLoadbalancerBackendCreateComplete(ctx context.Context, lbb *models.SLoadbalancerBackend, data jsonutils.JSONObject) { + lbb.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerBackendCreateTask) OnLoadbalancerBackendCreateCompleteFailed(ctx context.Context, lbb *models.SLoadbalancerBackend, reason jsonutils.JSONObject) { + self.taskFail(ctx, lbb, reason.String()) +} diff --git a/pkg/compute/tasks/loadbalancer_backend_delete_task.go b/pkg/compute/tasks/loadbalancer_backend_delete_task.go new file mode 100644 index 0000000000..7aba65751a --- /dev/null +++ b/pkg/compute/tasks/loadbalancer_backend_delete_task.go @@ -0,0 +1,47 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerBackendDeleteTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerBackendDeleteTask{}) +} + +func (self *LoadbalancerBackendDeleteTask) taskFail(ctx context.Context, lbb *models.SLoadbalancerBackend, reason string) { + lbb.SetStatus(self.GetUserCred(), models.LB_STATUS_DELETE_FAILED, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerBackendDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lbb := obj.(*models.SLoadbalancerBackend) + region := lbb.GetRegion() + if region == nil { + self.taskFail(ctx, lbb, fmt.Sprintf("failed to find region for lbb %s", lbb.Name)) + return + } + self.SetStage("OnLoadbalancerBackendDeleteComplete", nil) + if err := region.GetDriver().RequestDeleteLoadbalancerBackend(ctx, self.GetUserCred(), lbb, self); err != nil { + self.taskFail(ctx, lbb, err.Error()) + } +} + +func (self *LoadbalancerBackendDeleteTask) OnLoadbalancerBackendDeleteComplete(ctx context.Context, lbb *models.SLoadbalancerBackend, data jsonutils.JSONObject) { + lbb.DoPendingDelete(ctx, self.GetUserCred()) + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerBackendDeleteTask) OnLoadbalancerBackendDeleteCompleteFailed(ctx context.Context, lbb *models.SLoadbalancerBackend, reason jsonutils.JSONObject) { + self.taskFail(ctx, lbb, reason.String()) +} diff --git a/pkg/compute/tasks/loadbalancer_backendgroup_create_task.go b/pkg/compute/tasks/loadbalancer_backendgroup_create_task.go new file mode 100644 index 0000000000..af6b814ba3 --- /dev/null +++ b/pkg/compute/tasks/loadbalancer_backendgroup_create_task.go @@ -0,0 +1,50 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerLoadbalancerBackendGroupCreateTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerLoadbalancerBackendGroupCreateTask{}) +} + +func (self *LoadbalancerLoadbalancerBackendGroupCreateTask) taskFail(ctx context.Context, lbacl *models.SLoadbalancerBackendGroup, reason string) { + lbacl.SetStatus(self.GetUserCred(), models.LB_STATUS_CREATE_FAILED, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerLoadbalancerBackendGroupCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lbbg := obj.(*models.SLoadbalancerBackendGroup) + region := lbbg.GetRegion() + if region == nil { + self.taskFail(ctx, lbbg, fmt.Sprintf("failed to find region for lb backendgroup %s", lbbg.Name)) + return + } + backends := []cloudprovider.SLoadbalancerBackend{} + self.GetParams().Unmarshal(&backends, "backends") + self.SetStage("OnLoadbalancerBackendGroupCreateComplete", nil) + if err := region.GetDriver().RequestCreateLoadbalancerBackendGroup(ctx, self.GetUserCred(), lbbg, backends, self); err != nil { + self.taskFail(ctx, lbbg, err.Error()) + } +} + +func (self *LoadbalancerLoadbalancerBackendGroupCreateTask) OnLoadbalancerBackendGroupCreateComplete(ctx context.Context, lbbg *models.SLoadbalancerBackendGroup, data jsonutils.JSONObject) { + lbbg.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerLoadbalancerBackendGroupCreateTask) OnLoadbalancerBackendGroupCreateCompleteFailed(ctx context.Context, lbbg *models.SLoadbalancerBackendGroup, reason jsonutils.JSONObject) { + self.taskFail(ctx, lbbg, reason.String()) +} diff --git a/pkg/compute/tasks/loadbalancer_backendgroup_delete_task.go b/pkg/compute/tasks/loadbalancer_backendgroup_delete_task.go new file mode 100644 index 0000000000..2d382a8139 --- /dev/null +++ b/pkg/compute/tasks/loadbalancer_backendgroup_delete_task.go @@ -0,0 +1,47 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerBackendGroupDeleteTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerBackendGroupDeleteTask{}) +} + +func (self *LoadbalancerBackendGroupDeleteTask) taskFail(ctx context.Context, lbbg *models.SLoadbalancerBackendGroup, reason string) { + lbbg.SetStatus(self.GetUserCred(), models.LB_STATUS_DELETE_FAILED, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerBackendGroupDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lbbg := obj.(*models.SLoadbalancerBackendGroup) + region := lbbg.GetRegion() + if region == nil { + self.taskFail(ctx, lbbg, fmt.Sprintf("failed to find region for lb %s", lbbg.Name)) + return + } + self.SetStage("OnLoadbalancerBackendGroupDeleteComplete", nil) + if err := region.GetDriver().RequestDeleteLoadbalancerBackendGroup(ctx, self.GetUserCred(), lbbg, self); err != nil { + self.taskFail(ctx, lbbg, err.Error()) + } +} + +func (self *LoadbalancerBackendGroupDeleteTask) OnLoadbalancerBackendGroupDeleteComplete(ctx context.Context, lbbg *models.SLoadbalancerBackendGroup, data jsonutils.JSONObject) { + lbbg.PreDeleteSubs(ctx, self.GetUserCred()) + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerBackendGroupDeleteTask) OnLoadbalancerBackendGroupDeleteCompleteFailed(ctx context.Context, lbbg *models.SLoadbalancerBackendGroup, reason jsonutils.JSONObject) { + self.taskFail(ctx, lbbg, reason.String()) +} diff --git a/pkg/compute/tasks/loadbalancer_create_task.go b/pkg/compute/tasks/loadbalancer_create_task.go new file mode 100644 index 0000000000..00b5861ff6 --- /dev/null +++ b/pkg/compute/tasks/loadbalancer_create_task.go @@ -0,0 +1,47 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerCreateTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerCreateTask{}) +} + +func (self *LoadbalancerCreateTask) taskFail(ctx context.Context, lb *models.SLoadbalancer, reason string) { + lb.SetStatus(self.GetUserCred(), models.LB_STATUS_CREATE_FAILED, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lb := obj.(*models.SLoadbalancer) + region := lb.GetRegion() + if region == nil { + self.taskFail(ctx, lb, fmt.Sprintf("failed to find region for lb %s", lb.Name)) + return + } + self.SetStage("OnLoadbalancerCreateComplete", nil) + if err := region.GetDriver().RequestCreateLoadbalancer(ctx, self.GetUserCred(), lb, self); err != nil { + self.taskFail(ctx, lb, err.Error()) + } +} + +func (self *LoadbalancerCreateTask) OnLoadbalancerCreateComplete(ctx context.Context, lb *models.SLoadbalancer, data jsonutils.JSONObject) { + lb.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerCreateTask) OnLoadbalancerCreateCompleteFailed(ctx context.Context, lb *models.SLoadbalancer, reason jsonutils.JSONObject) { + self.taskFail(ctx, lb, reason.String()) +} diff --git a/pkg/compute/tasks/loadbalancer_delete_task.go b/pkg/compute/tasks/loadbalancer_delete_task.go new file mode 100644 index 0000000000..cc7d0da17e --- /dev/null +++ b/pkg/compute/tasks/loadbalancer_delete_task.go @@ -0,0 +1,47 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerDeleteTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerDeleteTask{}) +} + +func (self *LoadbalancerDeleteTask) taskFail(ctx context.Context, lb *models.SLoadbalancer, reason string) { + lb.SetStatus(self.GetUserCred(), models.LB_STATUS_DELETE_FAILED, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lb := obj.(*models.SLoadbalancer) + region := lb.GetRegion() + if region == nil { + self.taskFail(ctx, lb, fmt.Sprintf("failed to find region for lb %s", lb.Name)) + return + } + self.SetStage("OnLoadbalancerDeleteComplete", nil) + if err := region.GetDriver().RequestDeleteLoadbalancer(ctx, self.GetUserCred(), lb, self); err != nil { + self.taskFail(ctx, lb, err.Error()) + } +} + +func (self *LoadbalancerDeleteTask) OnLoadbalancerDeleteComplete(ctx context.Context, lb *models.SLoadbalancer, data jsonutils.JSONObject) { + lb.PendingDelete(ctx, self.GetUserCred()) + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerDeleteTask) OnLoadbalancerDeleteCompleteFailed(ctx context.Context, lb *models.SLoadbalancer, reason jsonutils.JSONObject) { + self.taskFail(ctx, lb, reason.String()) +} diff --git a/pkg/compute/tasks/loadbalancer_listener_create_task.go b/pkg/compute/tasks/loadbalancer_listener_create_task.go new file mode 100644 index 0000000000..ef1b4827d6 --- /dev/null +++ b/pkg/compute/tasks/loadbalancer_listener_create_task.go @@ -0,0 +1,47 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerListenerCreateTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerListenerCreateTask{}) +} + +func (self *LoadbalancerListenerCreateTask) taskFail(ctx context.Context, lblis *models.SLoadbalancerListener, reason string) { + lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_CREATE_FAILED, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerListenerCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lblis := obj.(*models.SLoadbalancerListener) + region := lblis.GetRegion() + if region == nil { + self.taskFail(ctx, lblis, fmt.Sprintf("failed to find region for lblis %s", lblis.Name)) + return + } + self.SetStage("OnLoadbalancerListenerCreateComplete", nil) + if err := region.GetDriver().RequestCreateLoadbalancerListener(ctx, self.GetUserCred(), lblis, self); err != nil { + self.taskFail(ctx, lblis, err.Error()) + } +} + +func (self *LoadbalancerListenerCreateTask) OnLoadbalancerListenerCreateComplete(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { + lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerListenerCreateTask) OnLoadbalancerListenerCreateCompleteFailed(ctx context.Context, lblis *models.SLoadbalancerListener, reason jsonutils.JSONObject) { + self.taskFail(ctx, lblis, reason.String()) +} diff --git a/pkg/compute/tasks/loadbalancer_listener_delete_task.go b/pkg/compute/tasks/loadbalancer_listener_delete_task.go new file mode 100644 index 0000000000..50accb60fe --- /dev/null +++ b/pkg/compute/tasks/loadbalancer_listener_delete_task.go @@ -0,0 +1,47 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerListenerDeleteTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerListenerDeleteTask{}) +} + +func (self *LoadbalancerListenerDeleteTask) taskFail(ctx context.Context, lblis *models.SLoadbalancerListener, reason string) { + lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_DELETE_FAILED, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerListenerDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lblis := obj.(*models.SLoadbalancerListener) + region := lblis.GetRegion() + if region == nil { + self.taskFail(ctx, lblis, fmt.Sprintf("failed to find region for lblis %s", lblis.Name)) + return + } + self.SetStage("OnLoadbalancerListenerDeleteComplete", nil) + if err := region.GetDriver().RequestDeleteLoadbalancerListener(ctx, self.GetUserCred(), lblis, self); err != nil { + self.taskFail(ctx, lblis, err.Error()) + } +} + +func (self *LoadbalancerListenerDeleteTask) OnLoadbalancerListenerDeleteComplete(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { + lblis.PreDeleteSubs(ctx, self.GetUserCred()) + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerListenerDeleteTask) OnLoadbalancerListenerDeleteCompleteFailed(ctx context.Context, lblis *models.SLoadbalancerListener, reason jsonutils.JSONObject) { + self.taskFail(ctx, lblis, reason.String()) +} diff --git a/pkg/compute/tasks/loadbalanceracl_create_task.go b/pkg/compute/tasks/loadbalanceracl_create_task.go new file mode 100644 index 0000000000..4a5f576d5c --- /dev/null +++ b/pkg/compute/tasks/loadbalanceracl_create_task.go @@ -0,0 +1,47 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerAclCreateTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerAclCreateTask{}) +} + +func (self *LoadbalancerAclCreateTask) taskFail(ctx context.Context, lbacl *models.SLoadbalancerAcl, reason string) { + lbacl.SetStatus(self.GetUserCred(), models.LB_STATUS_CREATE_FAILED, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerAclCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lbacl := obj.(*models.SLoadbalancerAcl) + region := lbacl.GetRegion() + if region == nil { + self.taskFail(ctx, lbacl, fmt.Sprintf("failed to find region for lbacl %s", lbacl.Name)) + return + } + self.SetStage("OnLoadbalancerAclCreateComplete", nil) + if err := region.GetDriver().RequestCreateLoadbalancerAcl(ctx, self.GetUserCred(), lbacl, self); err != nil { + self.taskFail(ctx, lbacl, err.Error()) + } +} + +func (self *LoadbalancerAclCreateTask) OnLoadbalancerAclCreateComplete(ctx context.Context, lbacl *models.SLoadbalancerAcl, data jsonutils.JSONObject) { + lbacl.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerAclCreateTask) OnLoadbalancerAclCreateCompleteFailed(ctx context.Context, lbacl *models.SLoadbalancerAcl, reason jsonutils.JSONObject) { + self.taskFail(ctx, lbacl, reason.String()) +} diff --git a/pkg/compute/tasks/loadbalanceracl_delete_task.go b/pkg/compute/tasks/loadbalanceracl_delete_task.go new file mode 100644 index 0000000000..cf4ce12b3d --- /dev/null +++ b/pkg/compute/tasks/loadbalanceracl_delete_task.go @@ -0,0 +1,47 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerAclDeleteTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerAclDeleteTask{}) +} + +func (self *LoadbalancerAclDeleteTask) taskFail(ctx context.Context, lbacl *models.SLoadbalancerAcl, reason string) { + lbacl.SetStatus(self.GetUserCred(), models.LB_STATUS_DELETE_FAILED, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerAclDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lbacl := obj.(*models.SLoadbalancerAcl) + region := lbacl.GetRegion() + if region == nil { + self.taskFail(ctx, lbacl, fmt.Sprintf("failed to find region for lbacl %s", lbacl.Name)) + return + } + self.SetStage("OnLoadbalancerAclDeleteComplete", nil) + if err := region.GetDriver().RequestDeleteLoadbalancerAcl(ctx, self.GetUserCred(), lbacl, self); err != nil { + self.taskFail(ctx, lbacl, err.Error()) + } +} + +func (self *LoadbalancerAclDeleteTask) OnLoadbalancerAclDeleteComplete(ctx context.Context, lbacl *models.SLoadbalancerAcl, data jsonutils.JSONObject) { + lbacl.DoPendingDelete(ctx, self.GetUserCred()) + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerAclDeleteTask) OnLoadbalancerAclDeleteCompleteFailed(ctx context.Context, lbacl *models.SLoadbalancerAcl, reason jsonutils.JSONObject) { + self.taskFail(ctx, lbacl, reason.String()) +} diff --git a/pkg/compute/tasks/loadbalancercertificate_create_task.go b/pkg/compute/tasks/loadbalancercertificate_create_task.go new file mode 100644 index 0000000000..be43a9d197 --- /dev/null +++ b/pkg/compute/tasks/loadbalancercertificate_create_task.go @@ -0,0 +1,47 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerCertificateCreateTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerCertificateCreateTask{}) +} + +func (self *LoadbalancerCertificateCreateTask) taskFail(ctx context.Context, lbcert *models.SLoadbalancerCertificate, reason string) { + lbcert.SetStatus(self.GetUserCred(), models.LB_STATUS_CREATE_FAILED, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerCertificateCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lbcert := obj.(*models.SLoadbalancerCertificate) + region := lbcert.GetRegion() + if region == nil { + self.taskFail(ctx, lbcert, fmt.Sprintf("failed to find region for lbcert %s", lbcert.Name)) + return + } + self.SetStage("OnLoadbalancerCertificateCreateComplete", nil) + if err := region.GetDriver().RequestCreateLoadbalancerCertificate(ctx, self.GetUserCred(), lbcert, self); err != nil { + self.taskFail(ctx, lbcert, err.Error()) + } +} + +func (self *LoadbalancerCertificateCreateTask) OnLoadbalancerCertificateCreateComplete(ctx context.Context, lbcert *models.SLoadbalancerCertificate, data jsonutils.JSONObject) { + lbcert.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerCertificateCreateTask) OnLoadbalancerCertificateCreateCompleteFailed(ctx context.Context, lbcert *models.SLoadbalancerCertificate, reason jsonutils.JSONObject) { + self.taskFail(ctx, lbcert, reason.String()) +} diff --git a/pkg/compute/tasks/loadbalancercertificate_delete_task.go b/pkg/compute/tasks/loadbalancercertificate_delete_task.go new file mode 100644 index 0000000000..dc06cec852 --- /dev/null +++ b/pkg/compute/tasks/loadbalancercertificate_delete_task.go @@ -0,0 +1,47 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerCertificateDeleteTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerCertificateDeleteTask{}) +} + +func (self *LoadbalancerCertificateDeleteTask) taskFail(ctx context.Context, lbcert *models.SLoadbalancerCertificate, reason string) { + lbcert.SetStatus(self.GetUserCred(), models.LB_STATUS_DELETE_FAILED, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerCertificateDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lbcert := obj.(*models.SLoadbalancerCertificate) + region := lbcert.GetRegion() + if region == nil { + self.taskFail(ctx, lbcert, fmt.Sprintf("failed to find region for lbcert %s", lbcert.Name)) + return + } + self.SetStage("OnLoadbalancerCertificateDeleteComplete", nil) + if err := region.GetDriver().RequestDeleteLoadbalancerCertificate(ctx, self.GetUserCred(), lbcert, self); err != nil { + self.taskFail(ctx, lbcert, err.Error()) + } +} + +func (self *LoadbalancerCertificateDeleteTask) OnLoadbalancerCertificateDeleteComplete(ctx context.Context, lbcert *models.SLoadbalancerCertificate, data jsonutils.JSONObject) { + lbcert.DoPendingDelete(ctx, self.GetUserCred()) + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerCertificateDeleteTask) OnLoadbalancerCertificateDeleteCompleteFailed(ctx context.Context, lbcert *models.SLoadbalancerCertificate, reason jsonutils.JSONObject) { + self.taskFail(ctx, lbcert, reason.String()) +} diff --git a/pkg/mcclient/models/loadbalancers.go b/pkg/mcclient/models/loadbalancers.go index ca6a7961dd..e02a73c0e0 100644 --- a/pkg/mcclient/models/loadbalancers.go +++ b/pkg/mcclient/models/loadbalancers.go @@ -15,8 +15,10 @@ type Loadbalancer struct { VpcId string ZoneId string - BackendGroupId string - CloudregionId string + BackendGroupId string + CloudregionId string + ChargeType string + LoadbalancerSpec string } type LoadbalancerTCPListener struct{} diff --git a/pkg/mcclient/options/loadbalanceracls.go b/pkg/mcclient/options/loadbalanceracls.go index dc704c18fa..801c3aa7bf 100644 --- a/pkg/mcclient/options/loadbalanceracls.go +++ b/pkg/mcclient/options/loadbalanceracls.go @@ -58,6 +58,8 @@ func (entries AclEntries) String() string { type LoadbalancerAclCreateOptions struct { NAME string AclEntry []string `help:"acl entry with cidr and comment separated by #, e.g. 10.9.0.0/16#no comment" json:"-"` + Provider string `json:"manager_id"` + REGION string `json:"cloudregion_id"` } type LoadbalancerAclGetOptions struct { diff --git a/pkg/mcclient/options/loadbalancerbackendgroups.go b/pkg/mcclient/options/loadbalancerbackendgroups.go index 495acf870b..c3c95076e6 100644 --- a/pkg/mcclient/options/loadbalancerbackendgroups.go +++ b/pkg/mcclient/options/loadbalancerbackendgroups.go @@ -2,7 +2,9 @@ package options type LoadbalancerBackendGroupCreateOptions struct { NAME string - Loadbalancer string + LOADBALANCER string + Type string `choices:"default|normal|master_slave"` + Backend []string } type LoadbalancerBackendGroupGetOptions struct { diff --git a/pkg/mcclient/options/loadbalancers.go b/pkg/mcclient/options/loadbalancers.go index e6ea70ca87..9406520f1c 100644 --- a/pkg/mcclient/options/loadbalancers.go +++ b/pkg/mcclient/options/loadbalancers.go @@ -1,9 +1,11 @@ package options type LoadbalancerCreateOptions struct { - NAME string - Network string - Address string + NAME string + Network string + Address string + LoadbalancerSpec string `choices:"slb.s1.small|slb.s2.small|slb.s2.medium|slb.s3.small|slb.s3.medium|slb.s3.large"` + ChargeType string `choices:"traffic|bandwidth"` } type LoadbalancerGetOptions struct { @@ -21,6 +23,10 @@ type LoadbalancerDeleteOptions struct { ID string } +type LoadbalancerPurgeOptions struct { + ID string +} + type LoadbalancerListOptions struct { BaseListOptions Zone string diff --git a/pkg/util/aliyun/loadbalancer.go b/pkg/util/aliyun/loadbalancer.go index 42a274d68b..135f65d7ac 100644 --- a/pkg/util/aliyun/loadbalancer.go +++ b/pkg/util/aliyun/loadbalancer.go @@ -59,7 +59,7 @@ type SLoadbalancer struct { InternetChargeType string //公网实例的计费方式。取值:paybybandwidth:按带宽计费 paybytraffic:按流量计费(默认值) 说明 当 PayType参数的值为PrePay时,只支持按带宽计费。 PayType string //实例的计费类型,取值:PayOnDemand:按量付费 PrePay:预付费 ResourceGroupId string //企业资源组ID。 - + LoadBalancerSpec string //负载均衡实例的的性能规格 } func (lb *SLoadbalancer) GetName() string { @@ -152,6 +152,14 @@ func (region *SRegion) GetLoadbalancerDetail(loadbalancerId string) (*SLoadbalan return &lb, body.Unmarshal(&lb) } +func (lb *SLoadbalancer) Delete() error { + params := map[string]string{} + params["RegionId"] = lb.region.RegionId + params["LoadBalancerId"] = lb.LoadBalancerId + _, err := lb.region.lbRequest("DeleteLoadBalancer", params) + return err +} + func (lb *SLoadbalancer) GetILoadbalancerBackendGroups() ([]cloudprovider.ICloudLoadbalancerBackendGroup, error) { ibackendgroups := []cloudprovider.ICloudLoadbalancerBackendGroup{} { @@ -183,6 +191,57 @@ func (lb *SLoadbalancer) GetILoadbalancerBackendGroups() ([]cloudprovider.ICloud return ibackendgroups, nil } +func (lb *SLoadbalancer) CreateILoadBalancerBackendGroup(name string, groupType string, backends []cloudprovider.SLoadbalancerBackend) (cloudprovider.ICloudLoadbalancerBackendGroup, error) { + switch groupType { + case models.LB_BACKENDGROUP_TYPE_NORMAL: + group, err := lb.region.CreateLoadbalancerBackendGroup(name, lb.LoadBalancerId, backends) + if err != nil { + return nil, err + } + group.lb = lb + return group, nil + case models.LB_BACKENDGROUP_TYPE_MASTER_SLAVE: + group, err := lb.region.CreateLoadbalancerMasterSlaveBackendGroup(name, lb.LoadBalancerId, backends) + if err != nil { + return nil, err + } + group.lb = lb + return group, nil + default: + return nil, fmt.Errorf("Unsupport backendgroup type %s", groupType) + } +} + +func (lb *SLoadbalancer) GetLoadbalancerSpec() string { + if len(lb.LoadBalancerSpec) == 0 { + lb.Refresh() + } + return lb.LoadBalancerSpec +} + +func (lb *SLoadbalancer) GetChargeType() string { + switch lb.InternetChargeType { + case "paybybandwidth": + return "bandwidth" + case "paybytraffic": + return "traffic" + } + return "unknown" +} + +func (lb *SLoadbalancer) GetILoadbalancerBackendGroupById(groupId string) (cloudprovider.ICloudLoadbalancerBackendGroup, error) { + groups, err := lb.GetILoadbalancerBackendGroups() + if err != nil { + return nil, err + } + for i := 0; i < len(groups); i++ { + if groups[i].GetGlobalId() == groupId { + return groups[i], nil + } + } + return nil, cloudprovider.ErrNotFound +} + func (lb *SLoadbalancer) GetILoadbalancerListeners() ([]cloudprovider.ICloudLoadbalancerListener, error) { loadbalancer, err := lb.region.GetLoadbalancerDetail(lb.LoadBalancerId) if err != nil { diff --git a/pkg/util/aliyun/loadbalanceracl.go b/pkg/util/aliyun/loadbalanceracl.go index bcf255d808..545cf69313 100644 --- a/pkg/util/aliyun/loadbalanceracl.go +++ b/pkg/util/aliyun/loadbalanceracl.go @@ -68,6 +68,32 @@ func (acl *SLoadbalancerAcl) GetAclEntries() *jsonutils.JSONArray { return result } +func (region *SRegion) UpdateAclName(aclId, name string) error { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["AclId"] = aclId + params["AclName"] = name + _, err := region.lbRequest("SetAccessControlListAttribute", params) + return err +} + +func (region *SRegion) RemoveAccessControlListEntry(aclId string, data jsonutils.JSONObject) error { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["AclId"] = aclId + params["AclEntrys"] = data.String() + _, err := region.lbRequest("RemoveAccessControlListEntry", params) + return err +} + +func (acl *SLoadbalancerAcl) Delete() error { + params := map[string]string{} + params["RegionId"] = acl.region.RegionId + params["AclId"] = acl.AclId + _, err := acl.region.lbRequest("DeleteAccessControlList", params) + return err +} + func (region *SRegion) GetLoadbalancerAclDetail(aclId string) (*SLoadbalancerAcl, error) { params := map[string]string{} params["RegionId"] = region.RegionId diff --git a/pkg/util/aliyun/loadbalancerbackendgroup.go b/pkg/util/aliyun/loadbalancerbackendgroup.go index 513f0727c1..7f2fdb825c 100644 --- a/pkg/util/aliyun/loadbalancerbackendgroup.go +++ b/pkg/util/aliyun/loadbalancerbackendgroup.go @@ -1,6 +1,8 @@ package aliyun import ( + "fmt" + "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" @@ -108,3 +110,106 @@ func (backendgroup *SLoadbalancerBackendGroup) GetILoadbalancerBackends() ([]clo } return ibackends, nil } + +func (region *SRegion) CreateLoadbalancerBackendGroup(name, loadbalancerId string, backends []cloudprovider.SLoadbalancerBackend) (*SLoadbalancerBackendGroup, error) { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["VServerGroupName"] = name + params["LoadBalancerId"] = loadbalancerId + if len(backends) > 0 { + servers := jsonutils.NewArray() + for _, backend := range backends { + servers.Add( + jsonutils.Marshal( + map[string]string{ + "ServerId": backend.ExternalID, + "Port": fmt.Sprintf("%d", backend.Port), + "Weight": fmt.Sprintf("%d", backend.Weight), + }, + )) + } + params["BackendServers"] = servers.String() + } + body, err := region.lbRequest("CreateVServerGroup", params) + if err != nil { + return nil, err + } + groupId, err := body.GetString("VServerGroupId") + if err != nil { + return nil, err + } + return region.GetLoadbalancerBackendgroupById(groupId) +} + +func (region *SRegion) GetLoadbalancerBackendgroupById(groupId string) (*SLoadbalancerBackendGroup, error) { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["VServerGroupId"] = groupId + body, err := region.lbRequest("DescribeVServerGroupAttribute", params) + if err != nil { + return nil, err + } + group := &SLoadbalancerBackendGroup{} + return group, body.Unmarshal(group) +} + +func (region *SRegion) UpdateLoadBalancerBackendGroupName(name, groupId string) error { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["VServerGroupId"] = groupId + params["VServerGroupName"] = name + _, err := region.lbRequest("SetVServerGroupAttribute", params) + return err +} + +func (backendgroup *SLoadbalancerBackendGroup) Sync(name string) error { + if backendgroup.VServerGroupName != name { + return backendgroup.lb.region.UpdateLoadBalancerBackendGroupName(backendgroup.VServerGroupId, name) + } + return nil +} + +func (region *SRegion) DeleteLoadBalancerBackendGroup(groupId string) error { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["VServerGroupId"] = groupId + _, err := region.lbRequest("DeleteVServerGroup", params) + return err +} + +func (backendgroup *SLoadbalancerBackendGroup) Delete() error { + return backendgroup.lb.region.DeleteLoadBalancerBackendGroup(backendgroup.VServerGroupId) +} + +func (region *SRegion) AddBackendVServer(loadbalancerId, serverId string, weight, port int) error { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["LoadBalancerId"] = loadbalancerId + servers := jsonutils.NewArray() + servers.Add(jsonutils.Marshal(map[string]string{"ServerId": serverId, "Weight": fmt.Sprintf("%d", weight*100/256), "Port": fmt.Sprintf("%d", port)})) + params["BackendServers"] = servers.String() + _, err := region.lbRequest("AddVServerGroupBackendServers", params) + return err +} + +func (region *SRegion) RemoveBackendVServer(loadbalancerId, serverId string) error { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["LoadBalancerId"] = loadbalancerId + servers := jsonutils.NewArray() + servers.Add(jsonutils.NewString(serverId)) + params["BackendServers"] = servers.String() + _, err := region.lbRequest("RemoveVServerGroupBackendServers", params) + return err +} + +func (backendgroup *SLoadbalancerBackendGroup) AddBackendServer(serverId string, weight, port int) (cloudprovider.ICloudLoadbalancerBackend, error) { + if err := backendgroup.lb.region.AddBackendVServer(backendgroup.lb.LoadBalancerId, serverId, weight, port); err != nil { + return nil, err + } + return &SLoadbalancerBackend{lbbg: backendgroup, ServerId: serverId, Weight: weight, Port: port}, nil +} + +func (backendgroup *SLoadbalancerBackendGroup) RemoveBackendServer(serverId string) error { + return backendgroup.lb.region.RemoveBackendVServer(backendgroup.lb.LoadBalancerId, serverId) +} diff --git a/pkg/util/aliyun/loadbalancerdefaultbackendgroup.go b/pkg/util/aliyun/loadbalancerdefaultbackendgroup.go index 7261df2c2a..7e1df929cc 100644 --- a/pkg/util/aliyun/loadbalancerdefaultbackendgroup.go +++ b/pkg/util/aliyun/loadbalancerdefaultbackendgroup.go @@ -60,3 +60,44 @@ func (backendgroup *SLoadbalancerDefaultBackendGroup) GetILoadbalancerBackends() } return ibackends, nil } + +func (backendgroup *SLoadbalancerDefaultBackendGroup) Sync(name string) error { + return cloudprovider.ErrNotSupported +} + +func (backendgroup *SLoadbalancerDefaultBackendGroup) Delete() error { + return cloudprovider.ErrNotSupported +} + +func (region *SRegion) AddBackendServer(loadbalancerId, serverId string, weight, port int) error { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["LoadBalancerId"] = loadbalancerId + servers := jsonutils.NewArray() + servers.Add(jsonutils.Marshal(map[string]string{"ServerId": serverId, "Weight": fmt.Sprintf("%d", weight*100/256)})) + params["BackendServers"] = servers.String() + _, err := region.lbRequest("AddBackendServers", params) + return err +} + +func (backendgroup *SLoadbalancerDefaultBackendGroup) AddBackendServer(serverId string, weight, port int) (cloudprovider.ICloudLoadbalancerBackend, error) { + if err := backendgroup.lb.region.AddBackendServer(backendgroup.lb.LoadBalancerId, serverId, weight, port); err != nil { + return nil, err + } + return &SLoadbalancerDefaultBackend{lbbg: backendgroup, ServerId: serverId}, nil +} + +func (region *SRegion) RemoveBackendServer(loadbalancerId, serverId string) error { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["LoadBalancerId"] = loadbalancerId + servers := jsonutils.NewArray() + servers.Add(jsonutils.NewString(serverId)) + params["BackendServers"] = servers.String() + _, err := region.lbRequest("RemoveBackendServers", params) + return err +} + +func (backendgroup *SLoadbalancerDefaultBackendGroup) RemoveBackendServer(serverId string) error { + return backendgroup.lb.region.RemoveBackendServer(backendgroup.lb.LoadBalancerId, serverId) +} diff --git a/pkg/util/aliyun/loadbalancermasterslavebackendgroup.go b/pkg/util/aliyun/loadbalancermasterslavebackendgroup.go index f11908ca77..b3e73b0a41 100644 --- a/pkg/util/aliyun/loadbalancermasterslavebackendgroup.go +++ b/pkg/util/aliyun/loadbalancermasterslavebackendgroup.go @@ -1,6 +1,8 @@ package aliyun import ( + "fmt" + "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" @@ -85,3 +87,86 @@ func (backendgroup *SLoadbalancerMasterSlaveBackendGroup) GetILoadbalancerBacken } return ibackends, nil } + +func (region *SRegion) CreateLoadbalancerMasterSlaveBackendGroup(name, loadbalancerId string, backends []cloudprovider.SLoadbalancerBackend) (*SLoadbalancerMasterSlaveBackendGroup, error) { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["MasterSlaveServerGroupName"] = name + params["LoadBalancerId"] = loadbalancerId + if len(backends) != 2 { + return nil, fmt.Errorf("master slave backendgorup must contain two backend") + } + servers := jsonutils.NewArray() + for _, backend := range backends { + serverType := "Slave" + if backend.Index == 0 { + serverType = "Master" + } + servers.Add( + jsonutils.Marshal( + map[string]string{ + "ServerId": backend.ExternalID, + "Port": fmt.Sprintf("%d", backend.Port), + "Weight": fmt.Sprintf("%d", backend.Weight), + "ServerType": serverType, + }, + )) + } + body, err := region.lbRequest("CreateMasterSlaveVServerGroup", params) + if err != nil { + return nil, err + } + groupId, err := body.GetString("MasterSlaveServerGroupId") + if err != nil { + return nil, err + } + return region.GetLoadbalancerMasterSlaveBackendgroupById(groupId) +} + +func (region *SRegion) GetLoadbalancerMasterSlaveBackendgroupById(groupId string) (*SLoadbalancerMasterSlaveBackendGroup, error) { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["MasterSlaveServerGroupId"] = groupId + body, err := region.lbRequest("DescribeMasterSlaveVServerGroupAttribute", params) + if err != nil { + return nil, err + } + group := &SLoadbalancerMasterSlaveBackendGroup{} + return group, body.Unmarshal(group) +} + +func (region *SRegion) UpdateLoadbalancerMasterSlaveBackendgroupName(name, groupId string) error { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["MasterSlaveServerGroupId"] = groupId + params["MasterSlaveServerGroupName"] = name + _, err := region.lbRequest("SetMasterSlaveVServerGroupAttribute", params) + return err +} + +func (backendgroup *SLoadbalancerMasterSlaveBackendGroup) Sync(name string) error { + if backendgroup.MasterSlaveServerGroupName != name { + return backendgroup.lb.region.UpdateLoadbalancerMasterSlaveBackendgroupName(backendgroup.MasterSlaveServerGroupId, name) + } + return nil +} + +func (region *SRegion) DeleteLoadbalancerMasterSlaveBackendgroup(groupId string) error { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["MasterSlaveServerGroupId"] = groupId + _, err := region.lbRequest("DeleteMasterSlaveServerGroup", params) + return err +} + +func (backendgroup *SLoadbalancerMasterSlaveBackendGroup) Delete() error { + return backendgroup.lb.region.DeleteLoadbalancerMasterSlaveBackendgroup(backendgroup.MasterSlaveServerGroupId) +} + +func (backendgroup *SLoadbalancerMasterSlaveBackendGroup) AddBackendServer(serverId string, weight, port int) (cloudprovider.ICloudLoadbalancerBackend, error) { + return nil, cloudprovider.ErrNotSupported +} + +func (backendgroup *SLoadbalancerMasterSlaveBackendGroup) RemoveBackendServer(serverId string) error { + return cloudprovider.ErrNotSupported +} diff --git a/pkg/util/aliyun/loadbalancerservercertificate.go b/pkg/util/aliyun/loadbalancerservercertificate.go index 65818ea5c8..e7c2ec37f3 100644 --- a/pkg/util/aliyun/loadbalancerservercertificate.go +++ b/pkg/util/aliyun/loadbalancerservercertificate.go @@ -75,6 +75,34 @@ func (certificate *SLoadbalancerServerCertificate) Refresh() error { return nil } +func (region *SRegion) UpdateServerCertificateName(certId, name string) error { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["ServerCertificateId"] = certId + params["ServerCertificateName"] = name + _, err := region.lbRequest("SetServerCertificateName", params) + return err +} + +func (certificate *SLoadbalancerServerCertificate) Sync(name string, privateKey string, publicKey string) error { + if certificate.ServerCertificateName != name { + return certificate.region.UpdateServerCertificateName(certificate.ServerCertificateId, name) + } + return nil +} + +func (certificate *SLoadbalancerServerCertificate) Delete() error { + return certificate.region.DeleteServerCertificate(certificate.ServerCertificateId) +} + +func (region *SRegion) DeleteServerCertificate(certId string) error { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["ServerCertificateId"] = certId + _, err := region.lbRequest("DeleteServerCertificate", params) + return err +} + func (region *SRegion) GetLoadbalancerServerCertificates() ([]SLoadbalancerServerCertificate, error) { params := map[string]string{} params["RegionId"] = region.RegionId diff --git a/pkg/util/aliyun/region.go b/pkg/util/aliyun/region.go index ed8b309fe8..547013e077 100644 --- a/pkg/util/aliyun/region.go +++ b/pkg/util/aliyun/region.go @@ -3,12 +3,14 @@ package aliyun import ( "fmt" "strings" + "time" "github.com/aliyun/alibaba-cloud-sdk-go/sdk" "github.com/aliyun/aliyun-oss-go-sdk/oss" "yunion.io/x/jsonutils" "yunion.io/x/log" + "yunion.io/x/pkg/util/regutils" "yunion.io/x/pkg/util/secrules" "yunion.io/x/pkg/utils" @@ -678,6 +680,45 @@ func (region *SRegion) GetILoadBalancers() ([]cloudprovider.ICloudLoadbalancer, return ilbs, nil } +func (region *SRegion) GetILoadBalancerById(loadbalancerId string) (cloudprovider.ICloudLoadbalancer, error) { + return region.GetLoadbalancerDetail(loadbalancerId) +} + +func (region *SRegion) GetILoadBalancerCertificateById(certId string) (cloudprovider.ICloudLoadbalancerCertificate, error) { + certs, err := region.GetLoadbalancerServerCertificates() + if err != nil { + return nil, err + } + for i := 0; i < len(certs); i++ { + if certs[i].GetGlobalId() == certId { + certs[i].region = region + return &certs[i], nil + } + } + return nil, cloudprovider.ErrNotFound +} + +func (region *SRegion) CreateILoadBalancerCertificate(name string, privateKey, certificate string) (cloudprovider.ICloudLoadbalancerCertificate, error) { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["ServerCertificateName"] = name + params["PrivateKey"] = privateKey + params["ServerCertificate"] = certificate + body, err := region.lbRequest("UploadServerCertificate", params) + if err != nil { + return nil, err + } + certID, err := body.GetString("ServerCertificateId") + if err != nil { + return nil, err + } + return region.GetILoadBalancerCertificateById(certID) +} + +func (region *SRegion) GetILoadBalancerAclById(aclId string) (cloudprovider.ICloudLoadbalancerAcl, error) { + return region.GetLoadbalancerAclDetail(aclId) +} + func (region *SRegion) GetILoadbalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) { acls, err := region.GetLoadbalancerAcls() if err != nil { @@ -703,3 +744,89 @@ func (region *SRegion) GetILoadbalancerCertificates() ([]cloudprovider.ICloudLoa } return iCertificates, nil } + +func (region *SRegion) CreateILoadBalancer(loadbalancer *cloudprovider.SLoadbalancer) (cloudprovider.ICloudLoadbalancer, error) { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["LoadBalancerName"] = loadbalancer.Name + if len(loadbalancer.ZoneID) > 0 { + params["MasterZoneId"] = loadbalancer.ZoneID + } + + if len(loadbalancer.VpcID) > 0 { + params["VpcId"] = loadbalancer.VpcID + } + + if len(loadbalancer.NetworkID) > 0 { + params["VSwitchId"] = loadbalancer.NetworkID + } + + if len(loadbalancer.Address) > 0 { + params["Address"] = loadbalancer.Address + } + + if len(loadbalancer.AddressType) > 0 { + params["AddressType"] = loadbalancer.AddressType + } + + if len(loadbalancer.LoadbalancerSpec) > 0 { + params["LoadBalancerSpec"] = loadbalancer.LoadbalancerSpec + } + + if loadbalancer.Bandwidth > 0 { + params["Bandwidth"] = fmt.Sprintf("%d", loadbalancer.Bandwidth) + } + + body, err := region.lbRequest("CreateLoadBalancer", params) + if err != nil { + return nil, err + } + loadBalancerID, err := body.GetString("LoadBalancerId") + if err != nil { + return nil, err + } + iLoadbalancer, err := region.GetLoadbalancerDetail(loadBalancerID) + if err != nil { + return nil, err + } + return iLoadbalancer, cloudprovider.WaitStatus(iLoadbalancer, models.LB_STATUS_ENABLED, time.Second*5, time.Minute*5) +} + +func (region *SRegion) AddAccessControlListEntry(aclId string, entrys []cloudprovider.SLoadbalancerAccessControlListEntry) error { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["AclId"] = aclId + aclArray := jsonutils.NewArray() + for i := 0; i < len(entrys); i++ { + //阿里云AclEntrys参数必须是CIDR格式的。 + if regutils.MatchIPAddr(entrys[i].CIDR) { + entrys[i].CIDR += "/32" + } + aclArray.Add(jsonutils.Marshal(map[string]string{"entry": entrys[i].CIDR, "comment": entrys[i].Comment})) + } + if aclArray.Length() == 0 { + return nil + } + params["AclEntrys"] = aclArray.String() + _, err := region.lbRequest("AddAccessControlListEntry", params) + return err +} + +func (region *SRegion) CreateILoadBalancerAcl(acl *cloudprovider.SLoadbalancerAccessControlList) (cloudprovider.ICloudLoadbalancerAcl, error) { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["AclName"] = acl.Name + body, err := region.lbRequest("CreateAccessControlList", params) + if err != nil { + return nil, err + } + aclId, err := body.GetString("AclId") + if err != nil { + return nil, err + } + iAcl, err := region.GetLoadbalancerAclDetail(aclId) + if err != nil { + return nil, err + } + return iAcl, region.AddAccessControlListEntry(aclId, acl.Entrys) +} diff --git a/pkg/util/aws/region.go b/pkg/util/aws/region.go index 626192516d..7b02e87036 100644 --- a/pkg/util/aws/region.go +++ b/pkg/util/aws/region.go @@ -455,6 +455,22 @@ func (region *SRegion) GetILoadBalancers() ([]cloudprovider.ICloudLoadbalancer, return nil, cloudprovider.ErrNotImplemented } +func (region *SRegion) GetILoadBalancerById(loadbalancerId string) (cloudprovider.ICloudLoadbalancer, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) GetILoadBalancerAclById(aclId string) (cloudprovider.ICloudLoadbalancerAcl, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) GetILoadBalancerCertificateById(certId string) (cloudprovider.ICloudLoadbalancerCertificate, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) CreateILoadBalancerCertificate(name string, privateKey, certificate string) (cloudprovider.ICloudLoadbalancerCertificate, error) { + return nil, cloudprovider.ErrNotImplemented +} + func (region *SRegion) GetILoadbalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) { return nil, cloudprovider.ErrNotImplemented } @@ -462,3 +478,11 @@ func (region *SRegion) GetILoadbalancerAcls() ([]cloudprovider.ICloudLoadbalance func (region *SRegion) GetILoadbalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) { return nil, cloudprovider.ErrNotImplemented } + +func (region *SRegion) CreateILoadBalancer(loadbalancer *cloudprovider.SLoadbalancer) (cloudprovider.ICloudLoadbalancer, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) CreateILoadBalancerAcl(acl *cloudprovider.SLoadbalancerAccessControlList) (cloudprovider.ICloudLoadbalancerAcl, error) { + return nil, cloudprovider.ErrNotImplemented +} diff --git a/pkg/util/azure/region.go b/pkg/util/azure/region.go index 00ebbac4df..ebc4cc7744 100644 --- a/pkg/util/azure/region.go +++ b/pkg/util/azure/region.go @@ -507,6 +507,22 @@ func (region *SRegion) GetILoadBalancers() ([]cloudprovider.ICloudLoadbalancer, return nil, cloudprovider.ErrNotImplemented } +func (region *SRegion) GetILoadBalancerById(loadbalancerId string) (cloudprovider.ICloudLoadbalancer, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) GetILoadBalancerAclById(aclId string) (cloudprovider.ICloudLoadbalancerAcl, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) GetILoadBalancerCertificateById(certId string) (cloudprovider.ICloudLoadbalancerCertificate, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) CreateILoadBalancerCertificate(name string, privateKey, certificate string) (cloudprovider.ICloudLoadbalancerCertificate, error) { + return nil, cloudprovider.ErrNotImplemented +} + func (region *SRegion) GetILoadbalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) { return nil, cloudprovider.ErrNotImplemented } @@ -514,3 +530,11 @@ func (region *SRegion) GetILoadbalancerAcls() ([]cloudprovider.ICloudLoadbalance func (region *SRegion) GetILoadbalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) { return nil, cloudprovider.ErrNotImplemented } + +func (region *SRegion) CreateILoadBalancer(loadbalancer *cloudprovider.SLoadbalancer) (cloudprovider.ICloudLoadbalancer, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) CreateILoadBalancerAcl(acl *cloudprovider.SLoadbalancerAccessControlList) (cloudprovider.ICloudLoadbalancerAcl, error) { + return nil, cloudprovider.ErrNotImplemented +} diff --git a/pkg/util/huawei/region.go b/pkg/util/huawei/region.go index 0af2f4e72d..78ad3dd7b3 100644 --- a/pkg/util/huawei/region.go +++ b/pkg/util/huawei/region.go @@ -133,6 +133,22 @@ func (self *SRegion) GetILoadBalancers() ([]cloudprovider.ICloudLoadbalancer, er return nil, cloudprovider.ErrNotImplemented } +func (region *SRegion) GetILoadBalancerById(loadbalancerId string) (cloudprovider.ICloudLoadbalancer, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) GetILoadBalancerAclById(aclId string) (cloudprovider.ICloudLoadbalancerAcl, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) GetILoadBalancerCertificateById(certId string) (cloudprovider.ICloudLoadbalancerCertificate, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) CreateILoadBalancerCertificate(name string, privateKey, certificate string) (cloudprovider.ICloudLoadbalancerCertificate, error) { + return nil, cloudprovider.ErrNotImplemented +} + func (self *SRegion) GetILoadbalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) { return nil, cloudprovider.ErrNotImplemented } @@ -645,3 +661,11 @@ func (self *SRegion) addSecurityGroupRule(secGrpId, direction, portStart, portEn rule := SecurityGroupRule{} return DoCreate(self.ecsClient.SecurityGroupRules.Create, params, &rule) } + +func (region *SRegion) CreateILoadBalancer(loadbalancer *cloudprovider.SLoadbalancer) (cloudprovider.ICloudLoadbalancer, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) CreateILoadBalancerAcl(acl *cloudprovider.SLoadbalancerAccessControlList) (cloudprovider.ICloudLoadbalancerAcl, error) { + return nil, cloudprovider.ErrNotImplemented +} diff --git a/pkg/util/openstack/region.go b/pkg/util/openstack/region.go index 6b1825ae2c..ccad02a2c6 100644 --- a/pkg/util/openstack/region.go +++ b/pkg/util/openstack/region.go @@ -285,6 +285,22 @@ func (region *SRegion) GetILoadBalancers() ([]cloudprovider.ICloudLoadbalancer, return nil, cloudprovider.ErrNotImplemented } +func (region *SRegion) GetILoadBalancerById(loadbalancerId string) (cloudprovider.ICloudLoadbalancer, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) GetILoadBalancerAclById(aclId string) (cloudprovider.ICloudLoadbalancerAcl, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) GetILoadBalancerCertificateById(certId string) (cloudprovider.ICloudLoadbalancerCertificate, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) CreateILoadBalancerCertificate(name string, privateKey, certificate string) (cloudprovider.ICloudLoadbalancerCertificate, error) { + return nil, cloudprovider.ErrNotImplemented +} + func (region *SRegion) GetILoadbalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) { return nil, cloudprovider.ErrNotImplemented } @@ -292,3 +308,11 @@ func (region *SRegion) GetILoadbalancerAcls() ([]cloudprovider.ICloudLoadbalance func (region *SRegion) GetILoadbalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) { return nil, cloudprovider.ErrNotImplemented } + +func (region *SRegion) CreateILoadBalancer(loadbalancer *cloudprovider.SLoadbalancer) (cloudprovider.ICloudLoadbalancer, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) CreateILoadBalancerAcl(acl *cloudprovider.SLoadbalancerAccessControlList) (cloudprovider.ICloudLoadbalancerAcl, error) { + return nil, cloudprovider.ErrNotImplemented +} diff --git a/pkg/util/qcloud/region.go b/pkg/util/qcloud/region.go index 0c90e551f3..0bdc5bcc06 100644 --- a/pkg/util/qcloud/region.go +++ b/pkg/util/qcloud/region.go @@ -582,6 +582,22 @@ func (region *SRegion) GetILoadBalancers() ([]cloudprovider.ICloudLoadbalancer, return nil, cloudprovider.ErrNotImplemented } +func (region *SRegion) GetILoadBalancerById(loadbalancerId string) (cloudprovider.ICloudLoadbalancer, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) GetILoadBalancerAclById(aclId string) (cloudprovider.ICloudLoadbalancerAcl, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) GetILoadBalancerCertificateById(certId string) (cloudprovider.ICloudLoadbalancerCertificate, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) CreateILoadBalancerCertificate(name string, privateKey, certificate string) (cloudprovider.ICloudLoadbalancerCertificate, error) { + return nil, cloudprovider.ErrNotImplemented +} + func (region *SRegion) GetILoadbalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) { return nil, cloudprovider.ErrNotImplemented } @@ -589,3 +605,11 @@ func (region *SRegion) GetILoadbalancerAcls() ([]cloudprovider.ICloudLoadbalance func (region *SRegion) GetILoadbalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) { return nil, cloudprovider.ErrNotImplemented } + +func (region *SRegion) CreateILoadBalancer(loadbalancer *cloudprovider.SLoadbalancer) (cloudprovider.ICloudLoadbalancer, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) CreateILoadBalancerAcl(acl *cloudprovider.SLoadbalancerAccessControlList) (cloudprovider.ICloudLoadbalancerAcl, error) { + return nil, cloudprovider.ErrNotImplemented +} From dc81eb1d5ed29b9d631b5679ecf2b8d1fde0650f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Fri, 11 Jan 2019 15:00:06 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E7=BB=9F=E4=B8=80LoadBalancer=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E5=A4=A7=E5=B0=8F=E5=86=99=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/climc/shell/loadbalancerlisteners.go | 10 +- cmd/climc/shell/loadbalancers.go | 2 +- pkg/cloudprovider/fakeregion.go | 6 +- pkg/cloudprovider/loadbalancerbackendgroup.go | 7 + pkg/cloudprovider/loadbalancercertificate.go | 7 + pkg/cloudprovider/loadbalancerlistener.go | 33 ++ pkg/cloudprovider/resources.go | 45 +- pkg/compute/models/hosts.go | 6 +- pkg/compute/models/hoststorages.go | 2 +- pkg/compute/models/loadbalancer_const.go | 3 + pkg/compute/models/loadbalanceracls.go | 29 +- .../models/loadbalancerbackendgroups.go | 13 +- pkg/compute/models/loadbalancerbackends.go | 49 +-- .../models/loadbalancerlistenerrules.go | 72 +++- pkg/compute/models/loadbalancerlisteners.go | 148 ++++++- pkg/compute/models/loadbalancers.go | 135 +++++- pkg/compute/models/regiondrivers.go | 16 + pkg/compute/regiondrivers/aliyun.go | 80 ++++ pkg/compute/regiondrivers/base.go | 36 ++ pkg/compute/regiondrivers/kvm.go | 95 +++++ pkg/compute/regiondrivers/managedvirtual.go | 390 +++++++++++++++--- .../tasks/cloud_provider_sync_info_task.go | 17 +- ...ask.go => loadbalancer_acl_create_task.go} | 0 ...ask.go => loadbalancer_acl_delete_task.go} | 0 .../tasks/loadbalancer_acl_sync_task.go | 47 +++ ...> loadbalancer_certificate_create_task.go} | 0 ...> loadbalancer_certificate_delete_task.go} | 0 .../loadbalancer_listener_rule_create_task.go | 47 +++ .../loadbalancer_listener_rule_delete_task.go | 47 +++ .../tasks/loadbalancer_listener_start_task.go | 57 +++ .../tasks/loadbalancer_listener_stop_task.go | 57 +++ .../loadbalancer_listener_syncstatus_task.go | 46 +++ pkg/compute/tasks/loadbalancer_start_task.go | 57 +++ pkg/compute/tasks/loadbalancer_stop_task.go | 57 +++ .../tasks/loadbalancer_syncstatus_task.go | 46 +++ pkg/mcclient/options/loadbalanceracls.go | 2 +- .../options/loadbalancercertificates.go | 6 +- pkg/mcclient/options/loadbalancers.go | 3 + pkg/util/aliyun/aliyun.go | 7 +- pkg/util/aliyun/loadbalancer.go | 69 +++- pkg/util/aliyun/loadbalanceracl.go | 34 +- pkg/util/aliyun/loadbalancerbackendgroup.go | 16 +- .../aliyun/loadbalancerdefaultbackendgroup.go | 6 +- pkg/util/aliyun/loadbalancerhttplistener.go | 80 ++++ pkg/util/aliyun/loadbalancerhttpslistener.go | 90 ++++ pkg/util/aliyun/loadbalancerlistenerrule.go | 85 +++- .../loadbalancermasterslavebackendgroup.go | 2 +- pkg/util/aliyun/loadbalancertcplistener.go | 112 +++++ pkg/util/aliyun/loadbalancerudplistener.go | 34 ++ pkg/util/aliyun/region.go | 14 +- pkg/util/aliyun/shell/loadbalanceracl.go | 2 +- pkg/util/aws/region.go | 6 +- pkg/util/azure/region.go | 6 +- pkg/util/huawei/region.go | 6 +- pkg/util/openstack/region.go | 6 +- pkg/util/qcloud/region.go | 6 +- 56 files changed, 2047 insertions(+), 207 deletions(-) create mode 100644 pkg/cloudprovider/loadbalancerbackendgroup.go create mode 100644 pkg/cloudprovider/loadbalancercertificate.go rename pkg/compute/tasks/{loadbalanceracl_create_task.go => loadbalancer_acl_create_task.go} (100%) rename pkg/compute/tasks/{loadbalanceracl_delete_task.go => loadbalancer_acl_delete_task.go} (100%) create mode 100644 pkg/compute/tasks/loadbalancer_acl_sync_task.go rename pkg/compute/tasks/{loadbalancercertificate_create_task.go => loadbalancer_certificate_create_task.go} (100%) rename pkg/compute/tasks/{loadbalancercertificate_delete_task.go => loadbalancer_certificate_delete_task.go} (100%) create mode 100644 pkg/compute/tasks/loadbalancer_listener_rule_create_task.go create mode 100644 pkg/compute/tasks/loadbalancer_listener_rule_delete_task.go create mode 100644 pkg/compute/tasks/loadbalancer_listener_start_task.go create mode 100644 pkg/compute/tasks/loadbalancer_listener_stop_task.go create mode 100644 pkg/compute/tasks/loadbalancer_listener_syncstatus_task.go create mode 100644 pkg/compute/tasks/loadbalancer_start_task.go create mode 100644 pkg/compute/tasks/loadbalancer_stop_task.go create mode 100644 pkg/compute/tasks/loadbalancer_syncstatus_task.go diff --git a/cmd/climc/shell/loadbalancerlisteners.go b/cmd/climc/shell/loadbalancerlisteners.go index 2c60b61c05..d2dd225c7b 100644 --- a/cmd/climc/shell/loadbalancerlisteners.go +++ b/cmd/climc/shell/loadbalancerlisteners.go @@ -48,7 +48,7 @@ func init() { printObject(lblistener) return nil }) - R(&options.LoadbalancerListenerDeleteOptions{}, "lblistener-delete", "Show lblistener", func(s *mcclient.ClientSession, opts *options.LoadbalancerListenerDeleteOptions) error { + R(&options.LoadbalancerListenerDeleteOptions{}, "lblistener-delete", "Delete lblistener", func(s *mcclient.ClientSession, opts *options.LoadbalancerListenerDeleteOptions) error { lblistener, err := modules.LoadbalancerListeners.Delete(s, opts.ID, nil) if err != nil { return err @@ -56,6 +56,14 @@ func init() { printObject(lblistener) return nil }) + R(&options.LoadbalancerListenerDeleteOptions{}, "lblistener-purge", "Purge lblistener", func(s *mcclient.ClientSession, opts *options.LoadbalancerListenerDeleteOptions) error { + lblistener, err := modules.LoadbalancerListeners.PerformAction(s, opts.ID, "purge", nil) + if err != nil { + return err + } + printObject(lblistener) + return nil + }) R(&options.LoadbalancerListenerActionStatusOptions{}, "lblistener-status", "Change lblistener status", func(s *mcclient.ClientSession, opts *options.LoadbalancerListenerActionStatusOptions) error { params, err := options.StructToParams(opts) if err != nil { diff --git a/cmd/climc/shell/loadbalancers.go b/cmd/climc/shell/loadbalancers.go index 8ed03003e4..4aae865a12 100644 --- a/cmd/climc/shell/loadbalancers.go +++ b/cmd/climc/shell/loadbalancers.go @@ -48,7 +48,7 @@ func init() { printObject(lb) return nil }) - R(&options.LoadbalancerDeleteOptions{}, "lb-delete", "Show lb", func(s *mcclient.ClientSession, opts *options.LoadbalancerDeleteOptions) error { + R(&options.LoadbalancerDeleteOptions{}, "lb-delete", "Delete lb", func(s *mcclient.ClientSession, opts *options.LoadbalancerDeleteOptions) error { lb, err := modules.Loadbalancers.Delete(s, opts.ID, nil) if err != nil { return err diff --git a/pkg/cloudprovider/fakeregion.go b/pkg/cloudprovider/fakeregion.go index 6e82f803b5..fc85e3481e 100644 --- a/pkg/cloudprovider/fakeregion.go +++ b/pkg/cloudprovider/fakeregion.go @@ -96,15 +96,15 @@ func (region *SFakeOnPremiseRegion) GetILoadBalancerCertificateById(certId strin return nil, ErrNotSupported } -func (region *SFakeOnPremiseRegion) CreateILoadBalancerCertificate(name string, privateKey, certificate string) (ICloudLoadbalancerCertificate, error) { +func (region *SFakeOnPremiseRegion) CreateILoadBalancerCertificate(cert *SLoadbalancerCertificate) (ICloudLoadbalancerCertificate, error) { return nil, ErrNotImplemented } -func (region *SFakeOnPremiseRegion) GetILoadbalancerAcls() ([]ICloudLoadbalancerAcl, error) { +func (region *SFakeOnPremiseRegion) GetILoadBalancerAcls() ([]ICloudLoadbalancerAcl, error) { return nil, ErrNotSupported } -func (region *SFakeOnPremiseRegion) GetILoadbalancerCertificates() ([]ICloudLoadbalancerCertificate, error) { +func (region *SFakeOnPremiseRegion) GetILoadBalancerCertificates() ([]ICloudLoadbalancerCertificate, error) { return nil, ErrNotSupported } diff --git a/pkg/cloudprovider/loadbalancerbackendgroup.go b/pkg/cloudprovider/loadbalancerbackendgroup.go new file mode 100644 index 0000000000..6f1a988585 --- /dev/null +++ b/pkg/cloudprovider/loadbalancerbackendgroup.go @@ -0,0 +1,7 @@ +package cloudprovider + +type SLoadbalancerBackendGroup struct { + Name string + GroupType string + Backends []SLoadbalancerBackend +} diff --git a/pkg/cloudprovider/loadbalancercertificate.go b/pkg/cloudprovider/loadbalancercertificate.go new file mode 100644 index 0000000000..6139365ac3 --- /dev/null +++ b/pkg/cloudprovider/loadbalancercertificate.go @@ -0,0 +1,7 @@ +package cloudprovider + +type SLoadbalancerCertificate struct { + Name string + PrivateKey string + Certificate string +} diff --git a/pkg/cloudprovider/loadbalancerlistener.go b/pkg/cloudprovider/loadbalancerlistener.go index 8dfd655b7d..744dbbad93 100644 --- a/pkg/cloudprovider/loadbalancerlistener.go +++ b/pkg/cloudprovider/loadbalancerlistener.go @@ -5,6 +5,7 @@ type SLoadbalancerListener struct { LoadbalancerID string ListenerType string ListenerPort int + BackendGroupType string BackendGroupID string Scheduler string AccessControlListStatus string @@ -12,4 +13,36 @@ type SLoadbalancerListener struct { AccessControlListID string EnableHTTP2 bool CertificateID string + Bandwidth int + Description string + EstablishedTimeout int + + HealthCheck string + HealthCheckTimeout int + HealthCheckDomain string + HealthCheckHttpCode string + HealthCheckURI string + HealthCheckInterval int + + HealthCheckRise int + HealthCheckFail int + + StickySession string + StickySessionCookie string + StickySessionType string + StickySessionCookieTimeout int + + ForwardPort int + XForwardedFor bool + Gzip bool + + TLSCipherPolicy string +} + +type SLoadbalancerListenerRule struct { + Name string + Domain string + Path string + BackendGroupID string + BackendGroupType string } diff --git a/pkg/cloudprovider/resources.go b/pkg/cloudprovider/resources.go index 33824a5ae0..a14d446a2f 100644 --- a/pkg/cloudprovider/resources.go +++ b/pkg/cloudprovider/resources.go @@ -63,8 +63,8 @@ type ICloudRegion interface { GetIStoragecacheById(id string) (ICloudStoragecache, error) GetILoadBalancers() ([]ICloudLoadbalancer, error) - GetILoadbalancerAcls() ([]ICloudLoadbalancerAcl, error) - GetILoadbalancerCertificates() ([]ICloudLoadbalancerCertificate, error) + GetILoadBalancerAcls() ([]ICloudLoadbalancerAcl, error) + GetILoadBalancerCertificates() ([]ICloudLoadbalancerCertificate, error) GetILoadBalancerById(loadbalancerId string) (ICloudLoadbalancer, error) GetILoadBalancerAclById(aclId string) (ICloudLoadbalancerAcl, error) @@ -72,7 +72,7 @@ type ICloudRegion interface { CreateILoadBalancer(loadbalancer *SLoadbalancer) (ICloudLoadbalancer, error) CreateILoadBalancerAcl(acl *SLoadbalancerAccessControlList) (ICloudLoadbalancerAcl, error) - CreateILoadBalancerCertificate(name string, privateKey, certificate string) (ICloudLoadbalancerCertificate, error) + CreateILoadBalancerCertificate(cert *SLoadbalancerCertificate) (ICloudLoadbalancerCertificate, error) GetProvider() string } @@ -413,11 +413,17 @@ type ICloudLoadbalancer interface { Delete() error - GetILoadbalancerListeners() ([]ICloudLoadbalancerListener, error) - GetILoadbalancerBackendGroups() ([]ICloudLoadbalancerBackendGroup, error) + Start() error + Stop() error - CreateILoadBalancerBackendGroup(name string, groupType string, backends []SLoadbalancerBackend) (ICloudLoadbalancerBackendGroup, error) - GetILoadbalancerBackendGroupById(groupId string) (ICloudLoadbalancerBackendGroup, error) + GetILoadBalancerListeners() ([]ICloudLoadbalancerListener, error) + GetILoadBalancerBackendGroups() ([]ICloudLoadbalancerBackendGroup, error) + + CreateILoadBalancerBackendGroup(group *SLoadbalancerBackendGroup) (ICloudLoadbalancerBackendGroup, error) + GetILoadBalancerBackendGroupById(groupId string) (ICloudLoadbalancerBackendGroup, error) + + CreateILoadBalancerListener(listener *SLoadbalancerListener) (ICloudLoadbalancerListener, error) + GetILoadBalancerListenerById(listenerId string) (ICloudLoadbalancerListener, error) } type ICloudLoadbalancerListener interface { @@ -446,6 +452,8 @@ type ICloudLoadbalancerListener interface { GetHealthCheckDomain() string GetHealthCheckURI() string GetHealthCheckCode() string + CreateILoadBalancerListenerRule(rule *SLoadbalancerListenerRule) (ICloudLoadbalancerListenerRule, error) + GetILoadBalancerListenerRuleById(ruleId string) (ICloudLoadbalancerListenerRule, error) GetILoadbalancerListenerRules() ([]ICloudLoadbalancerListenerRule, error) GetStickySession() string GetStickySessionType() string @@ -458,6 +466,11 @@ type ICloudLoadbalancerListener interface { GetCertificateId() string GetTLSCipherPolicy() string HTTP2Enabled() bool + + Start() error + Stop() error + + Delete() error } type ICloudLoadbalancerListenerRule interface { @@ -466,6 +479,8 @@ type ICloudLoadbalancerListenerRule interface { GetDomain() string GetPath() string GetBackendGroupId() string + + Delete() error } type ICloudLoadbalancerBackendGroup interface { @@ -475,7 +490,7 @@ type ICloudLoadbalancerBackendGroup interface { GetType() string GetILoadbalancerBackends() ([]ICloudLoadbalancerBackend, error) AddBackendServer(serverId string, weight int, port int) (ICloudLoadbalancerBackend, error) - RemoveBackendServer(serverId string) error + RemoveBackendServer(serverId string, weight int, port int) error Delete() error Sync(name string) error @@ -506,17 +521,7 @@ type ICloudLoadbalancerCertificate interface { type ICloudLoadbalancerAcl interface { ICloudResource - // return array data like this: - // [ - // { - // "cidr":"10.10.12.0/24", - // "comment":"test data" - // }, - // { - // "cidr":"192.168.10.12", - // "comment":"test data2" - // } - // ] - GetAclEntries() *jsonutils.JSONArray + GetAclEntries() []SLoadbalancerAccessControlListEntry + Sync(acl *SLoadbalancerAccessControlList) error Delete() error } diff --git a/pkg/compute/models/hosts.go b/pkg/compute/models/hosts.go index cdf119fdf7..ff5fe2cf69 100644 --- a/pkg/compute/models/hosts.go +++ b/pkg/compute/models/hosts.go @@ -125,9 +125,9 @@ type SHost struct { Rack string `width:"16" charset:"ascii" nullable:"true" get:"admin" update:"admin" create:"admin_optional"` // Column(VARCHAR(16, charset='ascii'), nullable=True) Slots string `width:"16" charset:"ascii" nullable:"true" get:"admin" update:"admin" create:"admin_optional"` // Column(VARCHAR(16, charset='ascii'), nullable=True) - AccessMac string `width:"32" charset:"ascii" nullable:"false" index:"true" list:"admin" update:"admin" create:"admin_required"` // Column(VARCHAR(32, charset='ascii'), nullable=False, index=True) - AccessIp string `width:"16" charset:"ascii" nullable:"true" list:"admin" update:"admin" create:"admin_optional"` // Column(VARCHAR(16, charset='ascii'), nullable=True) - ManagerUri string `width:"256" charset:"ascii" nullable:"true" list:"admin" update:"admin" create:"admin_optional"` // Column(VARCHAR(256, charset='ascii'), nullable=True) + AccessMac string `width:"32" charset:"ascii" nullable:"true" index:"true" list:"admin" update:"admin" create:"admin_required"` // Column(VARCHAR(32, charset='ascii'), nullable=False, index=True) + AccessIp string `width:"16" charset:"ascii" nullable:"true" list:"admin" update:"admin" create:"admin_optional"` // Column(VARCHAR(16, charset='ascii'), nullable=True) + ManagerUri string `width:"256" charset:"ascii" nullable:"true" list:"admin" update:"admin" create:"admin_optional"` // Column(VARCHAR(256, charset='ascii'), nullable=True) SysInfo jsonutils.JSONObject `nullable:"true" search:"admin" get:"admin" update:"admin" create:"admin_optional"` // Column(JSONEncodedDict, nullable=True) SN string `width:"128" charset:"ascii" nullable:"true" list:"admin" update:"admin" create:"admin_optional"` // Column(VARCHAR(128, charset='ascii'), nullable=True) diff --git a/pkg/compute/models/hoststorages.go b/pkg/compute/models/hoststorages.go index a42ccd736a..863c0e3e2b 100644 --- a/pkg/compute/models/hoststorages.go +++ b/pkg/compute/models/hoststorages.go @@ -40,7 +40,7 @@ func init() { type SHoststorage struct { SHostJointsBase - MountPoint string `width:"256" charset:"ascii" nullable:"false" list:"admin" update:"admin" create:"required"` // Column(VARCHAR(256, charset='ascii'), nullable=False) + MountPoint string `width:"256" charset:"ascii" nullable:"true" list:"admin" update:"admin" create:"required"` // Column(VARCHAR(256, charset='ascii'), nullable=False) HostId string `width:"36" charset:"ascii" nullable:"false" list:"admin" create:"required"` // Column(VARCHAR(36, charset='ascii'), nullable=False) StorageId string `width:"36" charset:"ascii" nullable:"false" list:"admin" create:"required"` // Column(VARCHAR(36, charset='ascii'), nullable=False) diff --git a/pkg/compute/models/loadbalancer_const.go b/pkg/compute/models/loadbalancer_const.go index 1eb020b307..4fa0f50a41 100644 --- a/pkg/compute/models/loadbalancer_const.go +++ b/pkg/compute/models/loadbalancer_const.go @@ -40,10 +40,13 @@ const ( LB_STATUS_UNKNOWN = "unknown" LB_STATUS_RUNNING = "running" LB_STATUS_STOPPED = "stopped" + LB_STATUS_START_FAILED = "start_failed" + LB_STATUS_STOP_FAILED = "stop_failed" LB_STATUS_CONFIGURING = "configuring" // config changes pending LB_STATUS_STOPPING = "stopping" LB_STATUS_DELETE_PENDING = "delete_pending" LB_STATUS_ERROR = "error" // bad things happen + ) var LB_STATUS_SPEC = validators.NewChoices( diff --git a/pkg/compute/models/loadbalanceracls.go b/pkg/compute/models/loadbalanceracls.go index e42478b257..efffc6e753 100644 --- a/pkg/compute/models/loadbalanceracls.go +++ b/pkg/compute/models/loadbalanceracls.go @@ -158,6 +158,21 @@ func (lbacl *SLoadbalancerAcl) ValidateUpdateData(ctx context.Context, userCred return lbacl.SSharableVirtualResourceBase.ValidateUpdateData(ctx, userCred, query, data) } +func (lbacl *SLoadbalancerAcl) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) { + lbacl.SSharableVirtualResourceBase.PostUpdate(ctx, userCred, query, data) + lbacl.SetStatus(userCred, LB_STATUS_SYNCING, "") + lbacl.StartLoadBalancerAclSyncTask(ctx, userCred, "") +} + +func (lbacl *SLoadbalancerAcl) StartLoadBalancerAclSyncTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerAclSyncTask", lbacl, userCred, nil, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil +} + func (lbacl *SLoadbalancerAcl) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) { lbacl.SSharableVirtualResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data) @@ -379,10 +394,9 @@ func (man *SLoadbalancerAclManager) newFromCloudLoadbalancerAcl(ctx context.Cont acl.ProjectId = provider.ProjectId } - aclEntries := extAcl.GetAclEntries() acl.AclEntries = &SLoadbalancerAclEntries{} - if err := aclEntries.Unmarshal(acl.AclEntries); err != nil { - return nil, err + for _, entry := range extAcl.GetAclEntries() { + *acl.AclEntries = append(*acl.AclEntries, &SLoadbalancerAclEntry{Cidr: entry.CIDR, Comment: entry.Comment}) } return &acl, man.TableSpec().Insert(&acl) } @@ -390,13 +404,14 @@ func (man *SLoadbalancerAclManager) newFromCloudLoadbalancerAcl(ctx context.Cont func (acl *SLoadbalancerAcl) SyncWithCloudLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, extAcl cloudprovider.ICloudLoadbalancerAcl, projectId string, projectSync bool) error { _, err := acl.GetModelManager().TableSpec().Update(acl, func() error { acl.Name = extAcl.GetName() - aclEntries := extAcl.GetAclEntries() - + acl.AclEntries = &SLoadbalancerAclEntries{} + for _, entry := range extAcl.GetAclEntries() { + *acl.AclEntries = append(*acl.AclEntries, &SLoadbalancerAclEntry{Cidr: entry.CIDR, Comment: entry.Comment}) + } if projectSync && len(projectId) > 0 { acl.ProjectId = projectId } - acl.AclEntries = &SLoadbalancerAclEntries{} - return aclEntries.Unmarshal(acl.AclEntries) + return nil }) return err } diff --git a/pkg/compute/models/loadbalancerbackendgroups.go b/pkg/compute/models/loadbalancerbackendgroups.go index 41fd4cd6fa..e719202b11 100644 --- a/pkg/compute/models/loadbalancerbackendgroups.go +++ b/pkg/compute/models/loadbalancerbackendgroups.go @@ -134,7 +134,7 @@ func (man *SLoadbalancerBackendGroupManager) ValidateCreateData(ctx context.Cont backend.ID = guest.Id backend.Name = guest.Name backend.ExternalID = guest.ExternalId - address, err := LoadbalancerBackendManager.getGuestAddress(guest) + address, err := LoadbalancerBackendManager.GetGuestAddress(guest) if err != nil { return nil, err } @@ -209,7 +209,8 @@ func (lbbg *SLoadbalancerBackendGroup) ValidateDeleteCondition(ctx context.Conte lbbgId, n, man.KeywordPlural()) } } - return nil + + return lbbg.GetRegion().GetDriver().ValidateDeleteLoadbalancerBackendGroupCondition(ctx, lbbg) } func (lbbg *SLoadbalancerBackendGroup) GetCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict { @@ -253,13 +254,8 @@ func (lbbg *SLoadbalancerBackendGroup) StartLoadBalancerBackendGroupCreateTask(c return nil } -// func (lbbg *SLoadbalancerBackendGroup) PreDelete(ctx context.Context, userCred mcclient.TokenCredential) { -// lbbg.DoPendingDelete(ctx, userCred) -// lbbg.PreDeleteSubs(ctx, userCred) -// } - func (lbbg *SLoadbalancerBackendGroup) PreDeleteSubs(ctx context.Context, userCred mcclient.TokenCredential) { - lbbg.DoCancelPendingDelete(ctx, userCred) + lbbg.DoPendingDelete(ctx, userCred) subMan := LoadbalancerBackendManager ownerProjId := lbbg.GetOwnerProjectId() @@ -373,6 +369,7 @@ func (man *SLoadbalancerBackendGroupManager) SyncLoadbalancerBackendgroups(ctx c func (lbbg *SLoadbalancerBackendGroup) constructFieldsFromCloudBackendgroup(lb *SLoadbalancer, extLoadbalancerBackendgroup cloudprovider.ICloudLoadbalancerBackendGroup) { lbbg.Name = extLoadbalancerBackendgroup.GetName() lbbg.Type = extLoadbalancerBackendgroup.GetType() + lbbg.Status = extLoadbalancerBackendgroup.GetStatus() } func (lbbg *SLoadbalancerBackendGroup) SyncWithCloudLoadbalancerBackendgroup(ctx context.Context, userCred mcclient.TokenCredential, lb *SLoadbalancer, extLoadbalancerBackendgroup cloudprovider.ICloudLoadbalancerBackendGroup, projectId string, projectSync bool) error { diff --git a/pkg/compute/models/loadbalancerbackends.go b/pkg/compute/models/loadbalancerbackends.go index 05945dadbf..7742017abf 100644 --- a/pkg/compute/models/loadbalancerbackends.go +++ b/pkg/compute/models/loadbalancerbackends.go @@ -85,47 +85,24 @@ func (man *SLoadbalancerBackendManager) ValidateCreateData(ctx context.Context, } } backendGroup := backendGroupV.Model.(*SLoadbalancerBackendGroup) + lb := backendGroup.GetLoadbalancer() backendType := backendTypeV.Value var baseName string + var backendV *validators.ValidatorModelIdOrName switch backendType { case LB_BACKEND_GUEST: - backendV := validators.NewModelIdOrNameValidator("backend", "server", ownerProjId) + backendV = validators.NewModelIdOrNameValidator("backend", "server", ownerProjId) err := backendV.Validate(data) if err != nil { return nil, err } guest := backendV.Model.(*SGuest) - { - // guest zone must match that of loadbalancer's - host := guest.GetHost() - if host == nil { - return nil, fmt.Errorf("error getting host of guest %s", guest.GetId()) - } - lb := backendGroup.GetLoadbalancer() - if lb == nil { - return nil, fmt.Errorf("error loadbalancer of backend group %s", backendGroup.GetId()) - } - if host.ZoneId != lb.ZoneId { - return nil, fmt.Errorf("zone of host %q (%s) != zone of loadbalancer %q (%s)", - host.Name, host.ZoneId, lb.Name, lb.ZoneId) - } - } - { - // get guest intranet address - // - // NOTE add address hint (cidr) if needed - address, err := man.getGuestAddress(guest) - if err != nil { - return nil, err - } - data.Set("address", jsonutils.NewString(address)) - } baseName = guest.Name case LB_BACKEND_HOST: if !db.IsAdminAllowCreate(userCred, man) { return nil, fmt.Errorf("only sysadmin can specify host as backend") } - backendV := validators.NewModelIdOrNameValidator("backend", "host", userCred.GetProjectId()) + backendV = validators.NewModelIdOrNameValidator("backend", "host", userCred.GetProjectId()) err := backendV.Validate(data) if err != nil { return nil, err @@ -149,7 +126,10 @@ func (man *SLoadbalancerBackendManager) ValidateCreateData(ctx context.Context, // - Use name from input query name := fmt.Sprintf("%s-%s-%s", backendGroup.Name, backendType, baseName) data.Set("name", jsonutils.NewString(name)) - return man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data) + if _, err := man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data); err != nil { + return nil, err + } + return backendGroup.GetLoadbalancer().GetRegion().GetDriver().ValidateCreateLoadbalancerBackendData(ctx, userCred, data, backendType, lb, backendGroup, backendV.Model) } func (lbb *SLoadbalancerBackend) AllowPerformStatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { @@ -186,7 +166,7 @@ func (lbb *SLoadbalancerBackend) GetIRegion() (cloudprovider.ICloudRegion, error return nil, fmt.Errorf("failed to find backendgroup for backend %s", lbb.Name) } -func (man *SLoadbalancerBackendManager) getGuestAddress(guest *SGuest) (string, error) { +func (man *SLoadbalancerBackendManager) GetGuestAddress(guest *SGuest) (string, error) { gns := guest.GetNetworks() if len(gns) == 0 { return "", fmt.Errorf("guest %s has no network attached", guest.GetId()) @@ -222,7 +202,7 @@ func (lbb *SLoadbalancerBackend) PostCreate(ctx context.Context, userCred mcclie } func (lbb *SLoadbalancerBackend) StartLoadBalancerBackendCreateTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { - task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerLoadbalancerBackendCreateTask", lbb, userCred, nil, parentTaskId, "", nil) + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerBackendCreateTask", lbb, userCred, nil, parentTaskId, "", nil) if err != nil { return err } @@ -271,6 +251,13 @@ func (man *SLoadbalancerBackendManager) getLoadbalancerBackendsByLoadbalancerBac return loadbalancerBackends, nil } +func (lbb *SLoadbalancerBackend) ValidateDeleteCondition(ctx context.Context) error { + if err := lbb.SVirtualResourceBase.ValidateDeleteCondition(ctx); err != nil { + return err + } + return lbb.GetRegion().GetDriver().ValidateDeleteLoadbalancerBackendCondition(ctx, lbb) +} + func (man *SLoadbalancerBackendManager) SyncLoadbalancerBackends(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, loadbalancerBackendgroup *SLoadbalancerBackendGroup, lbbs []cloudprovider.ICloudLoadbalancerBackend, syncRange *SSyncRange) compare.SyncResult { syncResult := compare.SyncResult{} @@ -345,7 +332,7 @@ func (lbb *SLoadbalancerBackend) constructFieldsFromCloudLoadbalancerBackend(ext } guest := instance.(*SGuest) lbb.BackendId = guest.Id - address, err := LoadbalancerBackendManager.getGuestAddress(guest) + address, err := LoadbalancerBackendManager.GetGuestAddress(guest) if err != nil { return err } diff --git a/pkg/compute/models/loadbalancerlistenerrules.go b/pkg/compute/models/loadbalancerlistenerrules.go index 2a7685bf69..9fa90ac0af 100644 --- a/pkg/compute/models/loadbalancerlistenerrules.go +++ b/pkg/compute/models/loadbalancerlistenerrules.go @@ -10,6 +10,7 @@ import ( "yunion.io/x/sqlchemy" "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/cloudcommon/validators" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/httperrors" @@ -120,7 +121,52 @@ func (man *SLoadbalancerListenerRuleManager) ValidateCreateData(ctx context.Cont if err != nil { return nil, err } - return man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data) + if _, err := man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data); err != nil { + return nil, err + } + return listener.GetRegion().GetDriver().ValidateCreateLoadbalancerListenerRuleData(ctx, userCred, data, backendGroupV.Model) +} + +func (lbr *SLoadbalancerListenerRule) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) { + lbr.SVirtualResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data) + + lbr.SetStatus(userCred, LB_STATUS_CREATING, "") + if err := lbr.StartLoadBalancerListenerRuleCreateTask(ctx, userCred, ""); err != nil { + log.Errorf("Failed to create loadbalancer listener rule error: %v", err) + } +} + +func (lbr *SLoadbalancerListenerRule) StartLoadBalancerListenerRuleCreateTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerListenerRuleCreateTask", lbr, userCred, nil, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil +} + +func (lbr *SLoadbalancerListenerRule) AllowPerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { + return db.IsAdminAllowPerform(userCred, lbr, "purge") +} + +func (lbr *SLoadbalancerListenerRule) PerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { + parasm := jsonutils.NewDict() + parasm.Add(jsonutils.JSONTrue, "purge") + return nil, lbr.StartLoadBalancerListenerRuleDeleteTask(ctx, userCred, parasm, "") +} + +func (lbr *SLoadbalancerListenerRule) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error { + lbr.SetStatus(userCred, LB_STATUS_DELETING, "") + return lbr.StartLoadBalancerListenerRuleDeleteTask(ctx, userCred, jsonutils.NewDict(), "") +} + +func (lbr *SLoadbalancerListenerRule) StartLoadBalancerListenerRuleDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerListenerRuleDeleteTask", lbr, userCred, params, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil } func (lbr *SLoadbalancerListenerRule) AllowPerformStatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { @@ -176,9 +222,27 @@ func (lbr *SLoadbalancerListenerRule) GetExtraDetails(ctx context.Context, userC return extra, nil } -func (lbr *SLoadbalancerListenerRule) PreDelete(ctx context.Context, userCred mcclient.TokenCredential) { - lbr.SetStatus(userCred, LB_STATUS_DISABLED, "preDelete") - lbr.DoPendingDelete(ctx, userCred) +func (lbr *SLoadbalancerListenerRule) GetLoadbalancerListener() *SLoadbalancerListener { + listener, err := LoadbalancerListenerManager.FetchById(lbr.ListenerId) + if err != nil { + return nil + } + return listener.(*SLoadbalancerListener) +} + +func (lbr *SLoadbalancerListenerRule) GetRegion() *SCloudregion { + if listener := lbr.GetLoadbalancerListener(); listener != nil { + return listener.GetRegion() + } + return nil +} + +func (lbr *SLoadbalancerListenerRule) GetLoadbalancerBackendGroup() *SLoadbalancerBackendGroup { + group, err := LoadbalancerBackendGroupManager.FetchById(lbr.BackendGroupId) + if err != nil { + return nil + } + return group.(*SLoadbalancerBackendGroup) } func (lbr *SLoadbalancerListenerRule) Delete(ctx context.Context, userCred mcclient.TokenCredential) error { diff --git a/pkg/compute/models/loadbalancerlisteners.go b/pkg/compute/models/loadbalancerlisteners.go index 6aba9992dc..9f06589a04 100644 --- a/pkg/compute/models/loadbalancerlisteners.go +++ b/pkg/compute/models/loadbalancerlisteners.go @@ -69,7 +69,9 @@ type SLoadbalancerHTTPSListener struct { type SLoadbalancerListener struct { db.SVirtualResourceBase + SManagedResourceBase + CloudregionId string `width:"36" charset:"ascii" nullable:"false" list:"admin" default:"default" create:"optional"` LoadbalancerId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` ListenerType string `width:"16" charset:"ascii" nullable:"false" list:"user" create:"required"` ListenerPort int `nullable:"false" list:"user" create:"required"` @@ -202,6 +204,8 @@ func (man *SLoadbalancerListenerManager) ValidateCreateData(ctx context.Context, } } lb := lbV.Model.(*SLoadbalancer) + data.Set("manager_id", jsonutils.NewString(lb.ManagerId)) + data.Set("cloudregion_id", jsonutils.NewString(lb.CloudregionId)) listenerPort := listenerPortV.Value listenerType := listenerTypeV.Value { @@ -231,6 +235,10 @@ func (man *SLoadbalancerListenerManager) ValidateCreateData(ctx context.Context, return nil, err } } + cert := certV.Model.(*SLoadbalancerCertificate) + if cert.CloudregionId != lb.CloudregionId { + return nil, httperrors.NewInputParameterError("certificate %s(%s) and lb %s(%s) are not in the same region", cert.Name, cert.Id, lb.Name, lb.Id) + } } } { @@ -258,7 +266,10 @@ func (man *SLoadbalancerListenerManager) ValidateCreateData(ctx context.Context, if err := man.validateAcl(aclStatusV, aclTypeV, aclV, data); err != nil { return nil, err } - return man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data) + if _, err := man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data); err != nil { + return nil, err + } + return lb.GetRegion().GetDriver().ValidateCreateLoadbalancerListenerData(ctx, userCred, data, backendGroupV.Model) } func (man *SLoadbalancerListenerManager) checkTypeV(listenerType string) validators.IValidator { @@ -292,6 +303,51 @@ func (lblis *SLoadbalancerListener) AllowPerformStatus(ctx context.Context, user return lblis.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, lblis, "status") } +func (lblis *SLoadbalancerListener) PerformStatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { + if _, err := lblis.SVirtualResourceBase.PerformStatus(ctx, userCred, query, data); err != nil { + return nil, err + } + if lblis.Status == LB_STATUS_ENABLED { + return nil, lblis.StartLoadBalancerListenerStartTask(ctx, userCred, "") + } + return nil, lblis.StartLoadBalancerListenerStopTask(ctx, userCred, "") +} + +func (lblis *SLoadbalancerListener) StartLoadBalancerListenerStartTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerListenerStartTask", lblis, userCred, nil, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil +} + +func (lblis *SLoadbalancerListener) StartLoadBalancerListenerStopTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerListenerStopTask", lblis, userCred, nil, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil +} + +func (lblis *SLoadbalancerListener) AllowPerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { + return db.IsAdminAllowPerform(userCred, lblis, "syncstatus") +} + +func (lblis *SLoadbalancerListener) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { + return nil, lblis.StartLoadBalancerListenerSyncstatusTask(ctx, userCred, "") +} + +func (lblis *SLoadbalancerListener) StartLoadBalancerListenerSyncstatusTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerListenerSyncstatusTask", lblis, userCred, nil, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil +} + func (lblis *SLoadbalancerListener) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { ownerProjId := lblis.GetOwnerProjectId() backendGroupV := validators.NewModelIdOrNameValidator("backend_group", "loadbalancerbackendgroup", ownerProjId) @@ -432,11 +488,10 @@ func (lblis *SLoadbalancerListener) StartLoadBalancerListenerDeleteTask(ctx cont return nil } -// func (lblis *SLoadbalancerListener) PreDelete(ctx context.Context, userCred mcclient.TokenCredential) { -// lblis.SetStatus(userCred, LB_STATUS_DISABLED, "preDelete") -// lblis.DoPendingDelete(ctx, userCred) -// lblis.PreDeleteSubs(ctx, userCred) -// } +func (lblis *SLoadbalancerListener) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error { + lblis.SetStatus(userCred, LB_STATUS_DELETING, "") + return lblis.StartLoadBalancerListenerDeleteTask(ctx, userCred, jsonutils.NewDict(), "") +} func (lblis *SLoadbalancerListener) PreDeleteSubs(ctx context.Context, userCred mcclient.TokenCredential) { subMan := LoadbalancerListenerRuleManager @@ -453,6 +508,80 @@ func (lblis *SLoadbalancerListener) Delete(ctx context.Context, userCred mcclien return nil } +func (lblis *SLoadbalancerListener) GetLoadbalancerListenerCreateParams() (*cloudprovider.SLoadbalancerListener, error) { + listener := &cloudprovider.SLoadbalancerListener{ + Name: lblis.Name, + Description: lblis.Description, + ListenerType: lblis.ListenerType, + ListenerPort: lblis.ListenerPort, + Scheduler: lblis.Scheduler, + EnableHTTP2: lblis.EnableHttp2, + Bandwidth: 0, + EstablishedTimeout: lblis.BackendConnectTimeout, + + HealthCheck: lblis.HealthCheck, + HealthCheckTimeout: lblis.HealthCheckTimeout, + HealthCheckDomain: lblis.HealthCheckDomain, + HealthCheckHttpCode: lblis.HealthCheckHttpCode, + HealthCheckURI: lblis.HealthCheckURI, + HealthCheckInterval: lblis.HealthCheckInterval, + + HealthCheckRise: lblis.HealthCheckRise, + HealthCheckFail: lblis.HealthCheckFall, + + StickySession: lblis.StickySession, + StickySessionType: lblis.StickySessionType, + StickySessionCookie: lblis.StickySessionCookie, + StickySessionCookieTimeout: lblis.StickySessionCookieTimeout, + + //ForwardPort: lblis.ForwardPort, + XForwardedFor: lblis.XForwardedFor, + TLSCipherPolicy: lblis.TLSCipherPolicy, + Gzip: lblis.Gzip, + } + if acl := lblis.GetLoadbalancerAcl(); acl != nil { + listener.AccessControlListID = acl.ExternalId + listener.AccessControlListType = lblis.AclType + listener.AccessControlListStatus = lblis.AclStatus + } + if certificate := lblis.GetLoadbalancerCertificate(); certificate != nil && lblis.ListenerType == LB_LISTENER_TYPE_HTTPS { + listener.CertificateID = certificate.ExternalId + } + + if backendgroup := lblis.GetLoadbalancerBackendGroup(); backendgroup != nil { + listener.BackendGroupID = backendgroup.ExternalId + listener.BackendGroupType = backendgroup.Type + } + return listener, nil +} + +func (lblis *SLoadbalancerListener) GetLoadbalancerCertificate() *SLoadbalancerCertificate { + if len(lblis.CertificateId) == 0 { + return nil + } + certificate, err := LoadbalancerCertificateManager.FetchById(lblis.CertificateId) + if err != nil { + return nil + } + return certificate.(*SLoadbalancerCertificate) +} + +func (lblis *SLoadbalancerListener) GetLoadbalancerAcl() *SLoadbalancerAcl { + acl, err := LoadbalancerAclManager.FetchById(lblis.AclId) + if err != nil { + return nil + } + return acl.(*SLoadbalancerAcl) +} + +func (lblis *SLoadbalancerListener) GetLoadbalancerBackendGroup() *SLoadbalancerBackendGroup { + group, err := LoadbalancerBackendGroupManager.FetchById(lblis.BackendGroupId) + if err != nil { + return nil + } + return group.(*SLoadbalancerBackendGroup) +} + func (lblis *SLoadbalancerListener) GetLoadbalancer() *SLoadbalancer { loadbalancer, err := LoadbalancerManager.FetchById(lblis.LoadbalancerId) if err != nil { @@ -468,6 +597,13 @@ func (lblis *SLoadbalancerListener) GetRegion() *SCloudregion { return nil } +func (lblis *SLoadbalancerListener) GetIRegion() (cloudprovider.ICloudRegion, error) { + if loadbalancer := lblis.GetLoadbalancer(); loadbalancer != nil { + return loadbalancer.GetIRegion() + } + return nil, fmt.Errorf("failed to find loadbalancer for lblis %s", lblis.Name) +} + func (man *SLoadbalancerListenerManager) getLoadbalancerListenersByLoadbalancer(lb *SLoadbalancer) ([]SLoadbalancerListener, error) { listeners := []SLoadbalancerListener{} q := man.Query().Equals("loadbalancer_id", lb.Id) diff --git a/pkg/compute/models/loadbalancers.go b/pkg/compute/models/loadbalancers.go index 214ca73e82..60f47922ce 100644 --- a/pkg/compute/models/loadbalancers.go +++ b/pkg/compute/models/loadbalancers.go @@ -58,7 +58,7 @@ type SLoadbalancer struct { Address string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional"` AddressType string `width:"16" charset:"ascii" nullable:"false" default:"intranet" list:"user" create:"optional"` NetworkType string `width:"16" charset:"ascii" nullable:"false" default:"vpc" list:"user" create:"optional"` - NetworkId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required"` + NetworkId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` VpcId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` ZoneId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` CloudregionId string `width:"36" charset:"ascii" nullable:"false" list:"admin" default:"default" create:"optional"` @@ -88,13 +88,26 @@ func (man *SLoadbalancerManager) ListItemFilter(ctx context.Context, q *sqlchemy func (man *SLoadbalancerManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { networkV := validators.NewModelIdOrNameValidator("network", "network", ownerProjId) + addressType, _ := data.GetString("address_type") + zoneV := validators.NewModelIdOrNameValidator("zone", "zone", "") + managerIdV := validators.NewModelIdOrNameValidator("manager_id", "cloudprovider", "") + if addressType == LB_ADDR_TYPE_INTERNET { + networkV.Optional(true) + } else { + zoneV.Optional(true) + managerIdV.Optional(true) + } addressV := validators.NewIPv4AddrValidator("address") + addressTypeV := validators.NewStringChoicesValidator("address_type", LB_ADDR_TYPES) { keyV := map[string]validators.IValidator{ "status": validators.NewStringChoicesValidator("status", LB_STATUS_SPEC).Default(LB_STATUS_ENABLED), - "address": addressV.Optional(true), - "network": networkV, + "address": addressV.Optional(true), + "address_type": addressTypeV.Default(LB_ADDR_TYPE_INTRANET), + "network": networkV, + "zone": zoneV, + "manager_id": managerIdV, } for _, v := range keyV { if err := v.Validate(data); err != nil { @@ -102,7 +115,8 @@ func (man *SLoadbalancerManager) ValidateCreateData(ctx context.Context, userCre } } } - { + var region *SCloudregion + if addressTypeV.Value == LB_ADDR_TYPE_INTRANET { network := networkV.Model.(*SNetwork) if ipAddr := addressV.IP; ipAddr != nil { ipS := ipAddr.String() @@ -139,7 +153,7 @@ func (man *SLoadbalancerManager) ValidateCreateData(ctx context.Context, userCre return nil, fmt.Errorf("getting zone failed") } data.Set("zone_id", jsonutils.NewString(zone.GetId())) - region := zone.GetRegion() + region = zone.GetRegion() if region == nil { return nil, fmt.Errorf("getting region failed") } @@ -147,17 +161,76 @@ func (man *SLoadbalancerManager) ValidateCreateData(ctx context.Context, userCre // TODO validate network is of classic type data.Set("network_type", jsonutils.NewString(LB_NETWORK_TYPE_CLASSIC)) data.Set("address_type", jsonutils.NewString(LB_ADDR_TYPE_INTRANET)) - if _, err := man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data); err != nil { - return nil, err + } else { + zone := zoneV.Model.(*SZone) + data.Set("zone_id", jsonutils.NewString(zone.GetId())) + region = zone.GetRegion() + if region == nil { + return nil, fmt.Errorf("getting region failed") } - return region.GetDriver().ValidateCreateLoadbalancerData(ctx, userCred, data) + data.Set("vpc_id", jsonutils.NewString("")) + data.Set("address", jsonutils.NewString("")) + data.Set("network_id", jsonutils.NewString("")) + data.Set("manager_id", jsonutils.NewString(managerIdV.Model.GetId())) + data.Set("cloudregion_id", jsonutils.NewString(region.GetId())) + data.Set("network_type", jsonutils.NewString(LB_NETWORK_TYPE_VPC)) + data.Set("address_type", jsonutils.NewString(LB_ADDR_TYPE_INTERNET)) } + if _, err := man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data); err != nil { + return nil, err + } + return region.GetDriver().ValidateCreateLoadbalancerData(ctx, userCred, data) } func (lb *SLoadbalancer) AllowPerformStatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { return lb.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, lb, "status") } +func (lb *SLoadbalancer) PerformStatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { + if _, err := lb.SVirtualResourceBase.PerformStatus(ctx, userCred, query, data); err != nil { + return nil, err + } + if lb.Status == LB_STATUS_ENABLED { + return nil, lb.StartLoadBalancerStartTask(ctx, userCred, "") + } + return nil, lb.StartLoadBalancerStopTask(ctx, userCred, "") +} + +func (lb *SLoadbalancer) StartLoadBalancerStartTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerStartTask", lb, userCred, nil, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil +} + +func (lb *SLoadbalancer) StartLoadBalancerStopTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerStopTask", lb, userCred, nil, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil +} + +func (lb *SLoadbalancer) AllowPerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { + return db.IsAdminAllowPerform(userCred, lb, "syncstatus") +} + +func (lb *SLoadbalancer) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { + return nil, lb.StartLoadBalancerSyncstatusTask(ctx, userCred, "") +} + +func (lb *SLoadbalancer) StartLoadBalancerSyncstatusTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerSyncstatusTask", lb, userCred, nil, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil +} + func (lb *SLoadbalancer) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) { lb.SVirtualResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data) // NOTE lb.Id will only be available after BeforeInsert happens @@ -222,6 +295,52 @@ func (lb *SLoadbalancer) GetIRegion() (cloudprovider.ICloudRegion, error) { return provider.GetIRegionById(region.ExternalId) } +func (lb *SLoadbalancer) GetCreateLoadbalancerParams(iRegion cloudprovider.ICloudRegion) (*cloudprovider.SLoadbalancer, error) { + params := &cloudprovider.SLoadbalancer{ + Name: lb.Name, + Address: lb.Address, + AddressType: lb.AddressType, + ChargeType: lb.ChargeType, + LoadbalancerSpec: lb.LoadbalancerSpec, + } + iRegion, err := lb.GetIRegion() + if err != nil { + return nil, err + } + if len(lb.ZoneId) > 0 { + zone := lb.GetZone() + if zone == nil { + return nil, fmt.Errorf("failed to find zone for lb %s", lb.Name) + } + iZone, err := iRegion.GetIZoneById(zone.ExternalId) + if err != nil { + return nil, err + } + params.ZoneID = iZone.GetId() + } + if lb.AddressType == LB_ADDR_TYPE_INTRANET { + vpc := lb.GetVpc() + if vpc == nil { + return nil, fmt.Errorf("failed to find vpc for lb %s", lb.Name) + } + iVpc, err := iRegion.GetIVpcById(vpc.ExternalId) + if err != nil { + return nil, err + } + params.VpcID = iVpc.GetId() + network := lb.GetNetwork() + if network == nil { + return nil, fmt.Errorf("failed to find network for lb %s", lb.Name) + } + iNetwork, err := network.GetINetwork() + if err != nil { + return nil, err + } + params.NetworkID = iNetwork.GetId() + } + return params, nil +} + func (lb *SLoadbalancer) AllowPerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { return db.IsAdminAllowPerform(userCred, lb, "purge") } diff --git a/pkg/compute/models/regiondrivers.go b/pkg/compute/models/regiondrivers.go index 899e0f48ed..bdfd40b638 100644 --- a/pkg/compute/models/regiondrivers.go +++ b/pkg/compute/models/regiondrivers.go @@ -5,6 +5,7 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/log" + "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/mcclient" @@ -16,10 +17,14 @@ type IRegionDriver interface { ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) RequestCreateLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *SLoadbalancer, task taskman.ITask) error RequestDeleteLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *SLoadbalancer, task taskman.ITask) error + RequestStartLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *SLoadbalancer, task taskman.ITask) error + RequestStopLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *SLoadbalancer, task taskman.ITask) error + RequestSyncstatusLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *SLoadbalancer, task taskman.ITask) error ValidateCreateLoadbalancerAclData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) RequestCreateLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *SLoadbalancerAcl, task taskman.ITask) error RequestDeleteLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *SLoadbalancerAcl, task taskman.ITask) error + RequestSyncLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *SLoadbalancerAcl, task taskman.ITask) error ValidateCreateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) ValidateUpdateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) @@ -29,12 +34,23 @@ type IRegionDriver interface { ValidateCreateLoadbalancerBackendGroupData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backends []cloudprovider.SLoadbalancerBackend) (*jsonutils.JSONDict, error) 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 + ValidateCreateLoadbalancerBackendData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backendType string, lb *SLoadbalancer, backendGroup *SLoadbalancerBackendGroup, backend db.IModel) (*jsonutils.JSONDict, error) RequestCreateLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, lbb *SLoadbalancerBackend, task taskman.ITask) error RequestDeleteLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, lbb *SLoadbalancerBackend, task taskman.ITask) error + ValidateDeleteLoadbalancerBackendCondition(ctx context.Context, lbb *SLoadbalancerBackend) error + ValidateCreateLoadbalancerListenerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backendGroup db.IModel) (*jsonutils.JSONDict, error) RequestCreateLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *SLoadbalancerListener, task taskman.ITask) error RequestDeleteLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *SLoadbalancerListener, task taskman.ITask) error + RequestStartLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *SLoadbalancerListener, task taskman.ITask) error + RequestStopLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *SLoadbalancerListener, task taskman.ITask) error + RequestSyncstatusLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *SLoadbalancerListener, task taskman.ITask) error + + ValidateCreateLoadbalancerListenerRuleData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backendGroup db.IModel) (*jsonutils.JSONDict, error) + RequestCreateLoadbalancerListenerRule(ctx context.Context, userCred mcclient.TokenCredential, lbr *SLoadbalancerListenerRule, task taskman.ITask) error + RequestDeleteLoadbalancerListenerRule(ctx context.Context, userCred mcclient.TokenCredential, lbr *SLoadbalancerListenerRule, task taskman.ITask) error } var regionDrivers map[string]IRegionDriver diff --git a/pkg/compute/regiondrivers/aliyun.go b/pkg/compute/regiondrivers/aliyun.go index 17a5f94f65..284d35b919 100644 --- a/pkg/compute/regiondrivers/aliyun.go +++ b/pkg/compute/regiondrivers/aliyun.go @@ -2,8 +2,10 @@ package regiondrivers import ( "context" + "fmt" "yunion.io/x/jsonutils" + "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/onecloud/pkg/httperrors" @@ -39,6 +41,21 @@ func (self *SAliyunRegionDriver) ValidateUpdateLoadbalancerCertificateData(ctx c return data, nil } +func (self *SAliyunRegionDriver) ValidateDeleteLoadbalancerBackendCondition(ctx context.Context, lbb *models.SLoadbalancerBackend) error { + backendGroup := lbb.GetLoadbalancerBackendGroup() + if backendGroup.Type == models.LB_BACKENDGROUP_TYPE_MASTER_SLAVE { + return httperrors.NewUnsupportOperationError("backend %s belong master slave backendgroup, not allow delete") + } + return nil +} + +func (self *SAliyunRegionDriver) ValidateDeleteLoadbalancerBackendGroupCondition(ctx context.Context, lbbg *models.SLoadbalancerBackendGroup) error { + if lbbg.Type == models.LB_BACKENDGROUP_TYPE_DEFAULT { + return httperrors.NewUnsupportOperationError("not allow to delete default backend group") + } + return nil +} + func (self *SAliyunRegionDriver) ValidateCreateLoadbalancerBackendGroupData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backends []cloudprovider.SLoadbalancerBackend) (*jsonutils.JSONDict, error) { groupType, _ := data.GetString("type") switch groupType { @@ -55,6 +72,69 @@ func (self *SAliyunRegionDriver) ValidateCreateLoadbalancerBackendGroupData(ctx if len(backend.ExternalID) == 0 { return nil, httperrors.NewInputParameterError("invalid guest %s", backend.Name) } + if backend.Weight < 0 || backend.Weight > 100 { + return nil, httperrors.NewInputParameterError("Aliyun instance weight must be in the range of 0 ~ 100") + } + } + return data, nil +} + +func (self *SAliyunRegionDriver) ValidateCreateLoadbalancerBackendData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backendType string, lb *models.SLoadbalancer, backendGroup *models.SLoadbalancerBackendGroup, backend db.IModel) (*jsonutils.JSONDict, error) { + if backendType != models.LB_BACKEND_GUEST { + return nil, httperrors.NewUnsupportOperationError("internal error: unexpected backend type %s", backendType) + } + if !utils.IsInStringArray(backendGroup.Type, []string{models.LB_BACKENDGROUP_TYPE_DEFAULT, models.LB_BACKENDGROUP_TYPE_NORMAL}) { + return nil, httperrors.NewUnsupportOperationError("backendgroup %s not support this operation", backendGroup.Name) + } + guest := backend.(*models.SGuest) + host := guest.GetHost() + if host == nil { + return nil, fmt.Errorf("error getting host of guest %s", guest.GetId()) + } + if lb == nil { + return nil, fmt.Errorf("error loadbalancer of backend group %s", backendGroup.GetId()) + } + hostRegion := host.GetRegion() + lbRegion := lb.GetRegion() + if hostRegion.Id != lbRegion.Id { + return nil, httperrors.NewInputParameterError("region of host %q (%s) != region of loadbalancer %q (%s))", + host.Name, host.ZoneId, lb.Name, lb.ZoneId) + } + address, err := models.LoadbalancerBackendManager.GetGuestAddress(guest) + if err != nil { + return nil, err + } + data.Set("address", jsonutils.NewString(address)) + weight, _ := data.Int("weight") + if weight < 0 || weight > 100 { + return nil, httperrors.NewInputParameterError("Aliyun instance weight must be in the range of 0 ~ 100") + } + return data, nil +} + +func (self *SAliyunRegionDriver) ValidateCreateLoadbalancerListenerRuleData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backendGroup db.IModel) (*jsonutils.JSONDict, error) { + backendgroup, ok := backendGroup.(*models.SLoadbalancerBackendGroup) + if !ok { + return nil, httperrors.NewMissingParameterError("backend_group") + } + if backendgroup.Type != models.LB_BACKENDGROUP_TYPE_NORMAL { + return nil, httperrors.NewInputParameterError("backend group type must be normal") + } + return data, nil +} + +func (self *SAliyunRegionDriver) ValidateCreateLoadbalancerListenerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backendGroup db.IModel) (*jsonutils.JSONDict, error) { + backendgroup, ok := backendGroup.(*models.SLoadbalancerBackendGroup) + if !ok { + return nil, httperrors.NewMissingParameterError("backend_group") + } + if !utils.IsInStringArray(backendgroup.Type, []string{models.LB_BACKENDGROUP_TYPE_MASTER_SLAVE, models.LB_BACKENDGROUP_TYPE_NORMAL}) { + return nil, httperrors.NewUnsupportOperationError("backend group type %s not support this operation", backendgroup.Type) + } + lb := backendgroup.GetLoadbalancer() + tlsCipherPolicy, _ := data.GetString("tls_cipher_policy") + if len(tlsCipherPolicy) > 0 && len(lb.LoadbalancerSpec) == 0 { + data.Set("tls_cipher_policy", jsonutils.NewString("")) } return data, nil } diff --git a/pkg/compute/regiondrivers/base.go b/pkg/compute/regiondrivers/base.go index 2f276f7846..57e80379b5 100644 --- a/pkg/compute/regiondrivers/base.go +++ b/pkg/compute/regiondrivers/base.go @@ -17,6 +17,18 @@ func (self *SBaseRegionDriver) RequestCreateLoadbalancer(ctx context.Context, us return fmt.Errorf("Not Implement RequestCreateLoadbalancer") } +func (self *SBaseRegionDriver) RequestStartLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestStartLoadbalancer") +} + +func (self *SBaseRegionDriver) RequestStopLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestStopLoadbalancer") +} + +func (self *SBaseRegionDriver) RequestSyncstatusLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestSyncstatusLoadbalancer") +} + func (self *SBaseRegionDriver) RequestDeleteLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { return fmt.Errorf("Not Implement RequestDeleteLoadbalancer") } @@ -25,6 +37,10 @@ func (self *SBaseRegionDriver) RequestCreateLoadbalancerAcl(ctx context.Context, return fmt.Errorf("Not Implement RequestCreateLoadbalancerAcl") } +func (self *SBaseRegionDriver) RequestSyncLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *models.SLoadbalancerAcl, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestSyncLoadbalancerAcl") +} + func (self *SBaseRegionDriver) RequestDeleteLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *models.SLoadbalancerAcl, task taskman.ITask) error { return fmt.Errorf("Not Implement RequestDeleteLoadbalancerAcl") } @@ -60,3 +76,23 @@ func (self *SBaseRegionDriver) RequestCreateLoadbalancerListener(ctx context.Con func (self *SBaseRegionDriver) RequestDeleteLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { return fmt.Errorf("Not Implement RequestDeleteLoadbalancerListener") } + +func (self *SBaseRegionDriver) RequestStartLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestStartLoadbalancerListener") +} + +func (self *SBaseRegionDriver) RequestStopLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestStopLoadbalancerListener") +} + +func (self *SBaseRegionDriver) RequestSyncstatusLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestSyncstatusLoadbalancerListener") +} + +func (self *SBaseRegionDriver) RequestCreateLoadbalancerListenerRule(ctx context.Context, userCred mcclient.TokenCredential, lbr *models.SLoadbalancerListenerRule, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestCreateLoadbalancerListenerRule") +} + +func (self *SBaseRegionDriver) RequestDeleteLoadbalancerListenerRule(ctx context.Context, userCred mcclient.TokenCredential, lbr *models.SLoadbalancerListenerRule, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestDeleteLoadbalancerListenerRule") +} diff --git a/pkg/compute/regiondrivers/kvm.go b/pkg/compute/regiondrivers/kvm.go index f3b0c1d8e1..6a8385fbba 100644 --- a/pkg/compute/regiondrivers/kvm.go +++ b/pkg/compute/regiondrivers/kvm.go @@ -6,6 +6,7 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/log" + "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" @@ -45,6 +46,47 @@ func (self *SKVMRegionDriver) ValidateCreateLoadbalancerBackendGroupData(ctx con return data, nil } +func (self *SKVMRegionDriver) ValidateCreateLoadbalancerBackendData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backendType string, lb *models.SLoadbalancer, backendGroup *models.SLoadbalancerBackendGroup, backend db.IModel) (*jsonutils.JSONDict, error) { + switch backendType { + case models.LB_BACKEND_GUEST: + guest := backend.(*models.SGuest) + { + // guest zone must match that of loadbalancer's + host := guest.GetHost() + if host == nil { + return nil, fmt.Errorf("error getting host of guest %s", guest.GetId()) + } + + if lb == nil { + return nil, fmt.Errorf("error loadbalancer of backend group %s", backendGroup.GetId()) + } + if host.ZoneId != lb.ZoneId { + return nil, fmt.Errorf("zone of host %q (%s) != zone of loadbalancer %q (%s)", + host.Name, host.ZoneId, lb.Name, lb.ZoneId) + } + } + { + // get guest intranet address + // + // NOTE add address hint (cidr) if needed + address, err := models.LoadbalancerBackendManager.GetGuestAddress(guest) + if err != nil { + return nil, err + } + data.Set("address", jsonutils.NewString(address)) + } + } + return data, nil +} + +func (self *SKVMRegionDriver) ValidateCreateLoadbalancerListenerRuleData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backendGroup db.IModel) (*jsonutils.JSONDict, error) { + return data, nil +} + +func (self *SKVMRegionDriver) ValidateCreateLoadbalancerListenerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backendGroup db.IModel) (*jsonutils.JSONDict, error) { + return data, nil +} + func (self *SKVMRegionDriver) RequestCreateLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { _, err := models.LoadbalancerManager.TableSpec().Update(lb, func() error { @@ -72,6 +114,21 @@ func (self *SKVMRegionDriver) RequestCreateLoadbalancer(ctx context.Context, use return nil } +func (self *SKVMRegionDriver) RequestStartLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { + task.ScheduleRun(nil) + return nil +} + +func (self *SKVMRegionDriver) RequestStopLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { + task.ScheduleRun(nil) + return nil +} + +func (self *SKVMRegionDriver) RequestSyncstatusLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { + task.ScheduleRun(nil) + return nil +} + func (self *SKVMRegionDriver) RequestDeleteLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { task.ScheduleRun(nil) return nil @@ -82,6 +139,11 @@ func (self *SKVMRegionDriver) RequestCreateLoadbalancerAcl(ctx context.Context, return nil } +func (self *SKVMRegionDriver) RequestSyncLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *models.SLoadbalancerAcl, task taskman.ITask) error { + task.ScheduleRun(nil) + return nil +} + func (self *SKVMRegionDriver) RequestDeleteLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *models.SLoadbalancerAcl, task taskman.ITask) error { task.ScheduleRun(nil) return nil @@ -131,6 +193,14 @@ func (self *SKVMRegionDriver) RequestCreateLoadbalancerBackend(ctx context.Conte return nil } +func (self *SKVMRegionDriver) ValidateDeleteLoadbalancerBackendCondition(ctx context.Context, lbb *models.SLoadbalancerBackend) error { + return nil +} + +func (self *SKVMRegionDriver) ValidateDeleteLoadbalancerBackendGroupCondition(ctx context.Context, lbbg *models.SLoadbalancerBackendGroup) error { + return nil +} + func (self *SKVMRegionDriver) RequestDeleteLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, lbb *models.SLoadbalancerBackend, task taskman.ITask) error { task.ScheduleRun(nil) return nil @@ -145,3 +215,28 @@ func (self *SKVMRegionDriver) RequestDeleteLoadbalancerListener(ctx context.Cont task.ScheduleRun(nil) return nil } + +func (self *SKVMRegionDriver) RequestStartLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { + task.ScheduleRun(nil) + return nil +} + +func (self *SKVMRegionDriver) RequestStopLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { + task.ScheduleRun(nil) + return nil +} + +func (self *SKVMRegionDriver) RequestSyncstatusLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { + task.ScheduleRun(nil) + return nil +} + +func (self *SKVMRegionDriver) RequestCreateLoadbalancerListenerRule(ctx context.Context, userCred mcclient.TokenCredential, lbr *models.SLoadbalancerListenerRule, task taskman.ITask) error { + task.ScheduleRun(nil) + return nil +} + +func (self *SKVMRegionDriver) RequestDeleteLoadbalancerListenerRule(ctx context.Context, userCred mcclient.TokenCredential, lbr *models.SLoadbalancerListenerRule, task taskman.ITask) error { + task.ScheduleRun(nil) + return nil +} diff --git a/pkg/compute/regiondrivers/managedvirtual.go b/pkg/compute/regiondrivers/managedvirtual.go index bf191edc65..457a026feb 100644 --- a/pkg/compute/regiondrivers/managedvirtual.go +++ b/pkg/compute/regiondrivers/managedvirtual.go @@ -6,11 +6,14 @@ import ( "fmt" "yunion.io/x/jsonutils" + "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/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/pkg/utils" ) type SManagedVirtualizationRegionDriver struct { @@ -49,6 +52,32 @@ func (self *SManagedVirtualizationRegionDriver) ValidateUpdateLoadbalancerCertif return data, nil } +func (self *SManagedVirtualizationRegionDriver) ValidateCreateLoadbalancerBackendData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backendType string, lb *models.SLoadbalancer, backendGroup *models.SLoadbalancerBackendGroup, backend db.IModel) (*jsonutils.JSONDict, error) { + if backendType != models.LB_BACKEND_GUEST { + return nil, httperrors.NewUnsupportOperationError("internal error: unexpected backend type %s", backendType) + } + guest := backend.(*models.SGuest) + host := guest.GetHost() + if host == nil { + return nil, fmt.Errorf("error getting host of guest %s", guest.GetId()) + } + if lb == nil { + return nil, fmt.Errorf("error loadbalancer of backend group %s", backendGroup.GetId()) + } + hostRegion := host.GetRegion() + lbRegion := lb.GetRegion() + if hostRegion.Id != lbRegion.Id { + return nil, httperrors.NewInputParameterError("region of host %q (%s) != region of loadbalancer %q (%s))", + host.Name, host.ZoneId, lb.Name, lb.ZoneId) + } + address, err := models.LoadbalancerBackendManager.GetGuestAddress(guest) + if err != nil { + return nil, err + } + data.Set("address", jsonutils.NewString(address)) + return data, nil +} + func (self *SManagedVirtualizationRegionDriver) ValidateCreateLoadbalancerBackendGroupData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backends []cloudprovider.SLoadbalancerBackend) (*jsonutils.JSONDict, error) { for _, backend := range backends { if len(backend.ExternalID) == 0 { @@ -58,51 +87,31 @@ func (self *SManagedVirtualizationRegionDriver) ValidateCreateLoadbalancerBacken return data, nil } +func (self *SManagedVirtualizationRegionDriver) ValidateCreateLoadbalancerListenerRuleData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backendGroup db.IModel) (*jsonutils.JSONDict, error) { + return data, nil +} + +func (self *SManagedVirtualizationRegionDriver) ValidateCreateLoadbalancerListenerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backendGroup db.IModel) (*jsonutils.JSONDict, error) { + return data, nil +} + +func (self *SManagedVirtualizationRegionDriver) ValidateDeleteLoadbalancerBackendCondition(ctx context.Context, lbb *models.SLoadbalancerBackend) error { + return nil +} + +func (self *SManagedVirtualizationRegionDriver) ValidateDeleteLoadbalancerBackendGroupCondition(ctx context.Context, lbbg *models.SLoadbalancerBackendGroup) error { + return nil +} + func (self *SManagedVirtualizationRegionDriver) RequestCreateLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { - params := &cloudprovider.SLoadbalancer{ - Name: lb.Name, - Address: lb.Address, - AddressType: lb.AddressType, - ChargeType: lb.ChargeType, - LoadbalancerSpec: lb.LoadbalancerSpec, - } iRegion, err := lb.GetIRegion() if err != nil { return nil, err } - if len(lb.ZoneId) > 0 { - zone := lb.GetZone() - if zone == nil { - return nil, fmt.Errorf("failed to find zone for lb %s", lb.Name) - } - iZone, err := iRegion.GetIZoneById(zone.ExternalId) - if err != nil { - return nil, err - } - params.ZoneID = iZone.GetId() - } - if len(lb.VpcId) > 0 { - vpc := lb.GetVpc() - if vpc == nil { - return nil, fmt.Errorf("failed to find vpc for lb %s", lb.Name) - } - iVpc, err := iRegion.GetIVpcById(vpc.ExternalId) - if err != nil { - return nil, err - } - params.VpcID = iVpc.GetId() - } - if len(lb.NetworkId) > 0 { - network := lb.GetNetwork() - if network == nil { - return nil, fmt.Errorf("failed to find network for lb %s", lb.Name) - } - iNetwork, err := network.GetINetwork() - if err != nil { - return nil, err - } - params.NetworkID = iNetwork.GetId() + params, err := lb.GetCreateLoadbalancerParams(iRegion) + if err != nil { + return nil, err } iLoadbalancer, err := iRegion.CreateILoadBalancer(params) if err != nil { @@ -125,7 +134,7 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateLoadbalancer(ctx co } } - lbbgs, err := iLoadbalancer.GetILoadbalancerBackendGroups() + lbbgs, err := iLoadbalancer.GetILoadBalancerBackendGroups() if err != nil { return nil, err } @@ -141,6 +150,55 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateLoadbalancer(ctx co return nil } +func (self *SManagedVirtualizationRegionDriver) RequestStartLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + iRegion, err := lb.GetIRegion() + if err != nil { + return nil, err + } + iLoadbalancer, err := iRegion.GetILoadBalancerById(lb.ExternalId) + if err != nil { + return nil, err + } + return nil, iLoadbalancer.Start() + }) + return nil +} + +func (self *SManagedVirtualizationRegionDriver) RequestStopLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + iRegion, err := lb.GetIRegion() + if err != nil { + return nil, err + } + iLoadbalancer, err := iRegion.GetILoadBalancerById(lb.ExternalId) + if err != nil { + return nil, err + } + return nil, iLoadbalancer.Stop() + }) + return nil +} + +func (self *SManagedVirtualizationRegionDriver) RequestSyncstatusLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + iRegion, err := lb.GetIRegion() + if err != nil { + return nil, err + } + iLoadbalancer, err := iRegion.GetILoadBalancerById(lb.ExternalId) + if err != nil { + return nil, err + } + status := iLoadbalancer.GetStatus() + if utils.IsInStringArray(status, []string{models.LB_STATUS_ENABLED, models.LB_STATUS_DISABLED}) { + return nil, lb.SetStatus(userCred, status, "") + } + return nil, fmt.Errorf("Unknown loadbalancer status %s", status) + }) + return nil +} + func (self *SManagedVirtualizationRegionDriver) RequestDeleteLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { if jsonutils.QueryBoolean(task.GetParams(), "purge", false) { @@ -186,6 +244,30 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateLoadbalancerAcl(ctx return nil } +func (self *SManagedVirtualizationRegionDriver) RequestSyncLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *models.SLoadbalancerAcl, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + iRegion, err := lbacl.GetIRegion() + if err != nil { + return nil, err + } + acl := &cloudprovider.SLoadbalancerAccessControlList{Name: lbacl.Name, Entrys: []cloudprovider.SLoadbalancerAccessControlListEntry{}} + if lbacl.AclEntries != nil { + for _, entry := range *lbacl.AclEntries { + acl.Entrys = append(acl.Entrys, cloudprovider.SLoadbalancerAccessControlListEntry{CIDR: entry.Cidr, Comment: entry.Comment}) + } + } + lockman.LockRawObject(ctx, "acl", lbacl.Id) + defer lockman.ReleaseRawObject(ctx, "acl", lbacl.Id) + + iLoadbalancerAcl, err := iRegion.GetILoadBalancerAclById(lbacl.ExternalId) + if err != nil { + return nil, err + } + return nil, iLoadbalancerAcl.Sync(acl) + }) + return nil +} + func (self *SManagedVirtualizationRegionDriver) RequestDeleteLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *models.SLoadbalancerAcl, task taskman.ITask) error { taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { if jsonutils.QueryBoolean(task.GetParams(), "purge", false) { @@ -213,7 +295,12 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateLoadbalancerCertifi if err != nil { return nil, err } - iLoadbalancerCert, err := iRegion.CreateILoadBalancerCertificate(lbcert.Name, lbcert.PrivateKey, lbcert.Certificate) + certificate := &cloudprovider.SLoadbalancerCertificate{ + Name: lbcert.Name, + PrivateKey: lbcert.PrivateKey, + Certificate: lbcert.Certificate, + } + iLoadbalancerCert, err := iRegion.CreateILoadBalancerCertificate(certificate) if err != nil { return nil, err } @@ -260,7 +347,12 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateLoadbalancerBackend if err != nil { return nil, err } - iLoadbalancerBackendGroup, err := iLoadbalancer.CreateILoadBalancerBackendGroup(lbbg.Name, lbbg.Type, backends) + group := &cloudprovider.SLoadbalancerBackendGroup{ + Name: lbbg.Name, + GroupType: lbbg.Type, + Backends: backends, + } + iLoadbalancerBackendGroup, err := iLoadbalancer.CreateILoadBalancerBackendGroup(group) if err != nil { return nil, err } @@ -300,7 +392,7 @@ func (self *SManagedVirtualizationRegionDriver) RequestDeleteLoadbalancerBackend if err != nil { return nil, err } - iLoadbalancerBackendGroup, err := iLoadbalancer.GetILoadbalancerBackendGroupById(lbbg.ExternalId) + iLoadbalancerBackendGroup, err := iLoadbalancer.GetILoadBalancerBackendGroupById(lbbg.ExternalId) if err != nil { if err == cloudprovider.ErrNotFound { return nil, nil @@ -330,7 +422,7 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateLoadbalancerBackend if err != nil { return nil, err } - iLoadbalancerBackendGroup, err := iLoadbalancer.GetILoadbalancerBackendGroupById(lbbg.ExternalId) + iLoadbalancerBackendGroup, err := iLoadbalancer.GetILoadBalancerBackendGroupById(lbbg.ExternalId) if err != nil { return nil, err } @@ -342,6 +434,9 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateLoadbalancerBackend if err != nil { return nil, err } + if err := lbb.SetExternalId(iLoadbalancerBackend.GetGlobalId()); err != nil { + return nil, err + } return nil, lbb.SyncWithCloudLoadbalancerBackend(ctx, userCred, iLoadbalancerBackend, "", false) }) return nil @@ -368,7 +463,7 @@ func (self *SManagedVirtualizationRegionDriver) RequestDeleteLoadbalancerBackend if err != nil { return nil, err } - iLoadbalancerBackendGroup, err := iLoadbalancer.GetILoadbalancerBackendGroupById(lbbg.ExternalId) + iLoadbalancerBackendGroup, err := iLoadbalancer.GetILoadBalancerBackendGroupById(lbbg.ExternalId) if err != nil { return nil, err } @@ -376,14 +471,37 @@ func (self *SManagedVirtualizationRegionDriver) RequestDeleteLoadbalancerBackend if guest == nil { return nil, fmt.Errorf("failed to find guest for lbb %s", lbb.Name) } - return nil, iLoadbalancerBackendGroup.RemoveBackendServer(guest.ExternalId) + return nil, iLoadbalancerBackendGroup.RemoveBackendServer(guest.ExternalId, lbb.Weight, lbb.Port) }) return nil } func (self *SManagedVirtualizationRegionDriver) RequestCreateLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { - return nil, nil + params, err := lblis.GetLoadbalancerListenerCreateParams() + if err != nil { + return nil, err + } + loadbalancer := lblis.GetLoadbalancer() + if loadbalancer == nil { + return nil, fmt.Errorf("failed to find loadbalancer for lblis %s", lblis.Name) + } + iRegion, err := loadbalancer.GetIRegion() + if err != nil { + return nil, err + } + iLoadbalancer, err := iRegion.GetILoadBalancerById(loadbalancer.ExternalId) + if err != nil { + return nil, err + } + iListener, err := iLoadbalancer.CreateILoadBalancerListener(params) + if err != nil { + return nil, err + } + if err := lblis.SetExternalId(iListener.GetGlobalId()); err != nil { + return nil, err + } + return nil, lblis.SyncWithCloudLoadbalancerListener(ctx, userCred, loadbalancer, iListener, "", false) }) return nil } @@ -393,7 +511,183 @@ func (self *SManagedVirtualizationRegionDriver) RequestDeleteLoadbalancerListene if jsonutils.QueryBoolean(task.GetParams(), "purge", false) { return nil, nil } - return nil, nil + loadbalancer := lblis.GetLoadbalancer() + if loadbalancer == nil { + return nil, fmt.Errorf("failed to find loadbalancer for lblis %s", lblis.Name) + } + iRegion, err := loadbalancer.GetIRegion() + if err != nil { + return nil, err + } + iLoadbalancer, err := iRegion.GetILoadBalancerById(loadbalancer.ExternalId) + if err != nil { + return nil, err + } + iListener, err := iLoadbalancer.GetILoadBalancerListenerById(lblis.ExternalId) + if err != nil { + if err == cloudprovider.ErrNotFound { + return nil, nil + } + return nil, err + } + return nil, iListener.Delete() + }) + return nil +} + +func (self *SManagedVirtualizationRegionDriver) RequestStartLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + loadbalancer := lblis.GetLoadbalancer() + if loadbalancer == nil { + return nil, fmt.Errorf("failed to find loadbalancer for lblis %s", lblis.Name) + } + iRegion, err := loadbalancer.GetIRegion() + if err != nil { + return nil, err + } + iLoadbalancer, err := iRegion.GetILoadBalancerById(loadbalancer.ExternalId) + if err != nil { + return nil, err + } + iListener, err := iLoadbalancer.GetILoadBalancerListenerById(lblis.ExternalId) + if err != nil { + return nil, err + } + return nil, iListener.Start() + }) + return nil +} + +func (self *SManagedVirtualizationRegionDriver) RequestStopLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + loadbalancer := lblis.GetLoadbalancer() + if loadbalancer == nil { + return nil, fmt.Errorf("failed to find loadbalancer for lblis %s", lblis.Name) + } + iRegion, err := loadbalancer.GetIRegion() + if err != nil { + return nil, err + } + iLoadbalancer, err := iRegion.GetILoadBalancerById(loadbalancer.ExternalId) + if err != nil { + return nil, err + } + iListener, err := iLoadbalancer.GetILoadBalancerListenerById(lblis.ExternalId) + if err != nil { + return nil, err + } + return nil, iListener.Stop() + }) + return nil +} + +func (self *SManagedVirtualizationRegionDriver) RequestSyncstatusLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + loadbalancer := lblis.GetLoadbalancer() + if loadbalancer == nil { + return nil, fmt.Errorf("failed to find loadbalancer for lblis %s", lblis.Name) + } + iRegion, err := loadbalancer.GetIRegion() + if err != nil { + return nil, err + } + iLoadbalancer, err := iRegion.GetILoadBalancerById(loadbalancer.ExternalId) + if err != nil { + return nil, err + } + iListener, err := iLoadbalancer.GetILoadBalancerListenerById(lblis.ExternalId) + if err != nil { + return nil, err + } + status := iListener.GetStatus() + if utils.IsInStringArray(status, []string{models.LB_STATUS_ENABLED, models.LB_STATUS_DISABLED}) { + return nil, lblis.SetStatus(userCred, status, "") + } + return nil, fmt.Errorf("Unknown loadbalancer listener status %s", status) + }) + return nil +} + +func (self *SManagedVirtualizationRegionDriver) RequestCreateLoadbalancerListenerRule(ctx context.Context, userCred mcclient.TokenCredential, lbr *models.SLoadbalancerListenerRule, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + listener := lbr.GetLoadbalancerListener() + if listener == nil { + return nil, fmt.Errorf("failed to find listener for listnener rule %s", lbr.Name) + } + loadbalancer := listener.GetLoadbalancer() + if loadbalancer == nil { + return nil, fmt.Errorf("failed to find loadbalancer for listener %s", listener.Name) + } + iRegion, err := loadbalancer.GetIRegion() + if err != nil { + return nil, err + } + iLoadbalancer, err := iRegion.GetILoadBalancerById(loadbalancer.ExternalId) + if err != nil { + return nil, err + } + iListener, err := iLoadbalancer.GetILoadBalancerListenerById(listener.ExternalId) + if err != nil { + return nil, err + } + rule := &cloudprovider.SLoadbalancerListenerRule{ + Name: lbr.Name, + Domain: lbr.Domain, + Path: lbr.Path, + } + if len(lbr.BackendGroupId) > 0 { + group := lbr.GetLoadbalancerBackendGroup() + if group == nil { + return nil, fmt.Errorf("failed to find backend group for listener rule %s", lbr.Name) + } + rule.BackendGroupID = group.ExternalId + rule.BackendGroupType = group.Type + } + iListenerRule, err := iListener.CreateILoadBalancerListenerRule(rule) + if err != nil { + return nil, err + } + if err := lbr.SetExternalId(iListenerRule.GetGlobalId()); err != nil { + return nil, err + } + return nil, lbr.SyncWithCloudLoadbalancerListenerRule(ctx, userCred, iListenerRule, "", false) + }) + return nil +} + +func (self *SManagedVirtualizationRegionDriver) RequestDeleteLoadbalancerListenerRule(ctx context.Context, userCred mcclient.TokenCredential, lbr *models.SLoadbalancerListenerRule, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + if jsonutils.QueryBoolean(task.GetParams(), "purge", false) { + return nil, nil + } + listener := lbr.GetLoadbalancerListener() + if listener == nil { + return nil, fmt.Errorf("failed to find listener for listnener rule %s", lbr.Name) + } + loadbalancer := listener.GetLoadbalancer() + if loadbalancer == nil { + return nil, fmt.Errorf("failed to find loadbalancer for listener %s", listener.Name) + } + iRegion, err := loadbalancer.GetIRegion() + if err != nil { + return nil, err + } + iLoadbalancer, err := iRegion.GetILoadBalancerById(loadbalancer.ExternalId) + if err != nil { + return nil, err + } + iListener, err := iLoadbalancer.GetILoadBalancerListenerById(listener.ExternalId) + if err != nil { + return nil, err + } + iListenerRule, err := iListener.GetILoadBalancerListenerRuleById(lbr.ExternalId) + if err != nil { + if err == cloudprovider.ErrNotFound { + return nil, nil + } + return nil, err + } + return nil, iListenerRule.Delete() }) return nil } diff --git a/pkg/compute/tasks/cloud_provider_sync_info_task.go b/pkg/compute/tasks/cloud_provider_sync_info_task.go index 88f8ebe31f..23346f10f4 100644 --- a/pkg/compute/tasks/cloud_provider_sync_info_task.go +++ b/pkg/compute/tasks/cloud_provider_sync_info_task.go @@ -5,6 +5,7 @@ import ( "fmt" "strings" + "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/pkg/utils" @@ -198,9 +199,9 @@ func syncPublicCloudProviderInfo(ctx context.Context, provider *models.SCloudpro } func syncRegionLoadbalancerCertificates(ctx context.Context, provider *models.SCloudprovider, task *CloudProviderSyncInfoTask, localRegion *models.SCloudregion, remoteRegion cloudprovider.ICloudRegion, syncRange *models.SSyncRange) { - certificates, err := remoteRegion.GetILoadbalancerCertificates() + certificates, err := remoteRegion.GetILoadBalancerCertificates() if err != nil { - msg := fmt.Sprintf("GetILoadbalancerCertificates for region %s failed %s", remoteRegion.GetName(), err) + msg := fmt.Sprintf("GetILoadBalancerCertificates for region %s failed %s", remoteRegion.GetName(), err) log.Errorf(msg) logSyncFailed(provider, task, msg) return @@ -215,9 +216,9 @@ func syncRegionLoadbalancerCertificates(ctx context.Context, provider *models.SC } func syncRegionLoadbalancerAcls(ctx context.Context, provider *models.SCloudprovider, task *CloudProviderSyncInfoTask, localRegion *models.SCloudregion, remoteRegion cloudprovider.ICloudRegion, syncRange *models.SSyncRange) { - acls, err := remoteRegion.GetILoadbalancerAcls() + acls, err := remoteRegion.GetILoadBalancerAcls() if err != nil { - msg := fmt.Sprintf("GetILoadbalancerAcls for region %s failed %s", remoteRegion.GetName(), err) + msg := fmt.Sprintf("GetILoadBalancerAcls for region %s failed %s", remoteRegion.GetName(), err) log.Errorf(msg) logSyncFailed(provider, task, msg) return @@ -254,9 +255,9 @@ func syncRegionLoadbalancers(ctx context.Context, provider *models.SCloudprovide } func syncLoadbalancerListeners(ctx context.Context, provider *models.SCloudprovider, task *CloudProviderSyncInfoTask, localLoadbalancer *models.SLoadbalancer, remoteLoadbalancer cloudprovider.ICloudLoadbalancer, syncRange *models.SSyncRange) { - remoteListeners, err := remoteLoadbalancer.GetILoadbalancerListeners() + remoteListeners, err := remoteLoadbalancer.GetILoadBalancerListeners() if err != nil { - msg := fmt.Sprintf("GetILoadbalancerListeners for loadbalancer %s failed %s", localLoadbalancer.Name, err) + msg := fmt.Sprintf("GetILoadBalancerListeners for loadbalancer %s failed %s", localLoadbalancer.Name, err) log.Errorf(msg) logSyncFailed(provider, task, msg) return @@ -291,9 +292,9 @@ func syncLoadbalancerListenerRules(ctx context.Context, provider *models.SCloudp } func syncLoadbalancerBackendgroups(ctx context.Context, provider *models.SCloudprovider, task *CloudProviderSyncInfoTask, localLoadbalancer *models.SLoadbalancer, remoteLoadbalancer cloudprovider.ICloudLoadbalancer, syncRange *models.SSyncRange) { - remoteBackendgroups, err := remoteLoadbalancer.GetILoadbalancerBackendGroups() + remoteBackendgroups, err := remoteLoadbalancer.GetILoadBalancerBackendGroups() if err != nil { - msg := fmt.Sprintf("GetILoadbalancerBackendGroups for loadbalancer %s failed %s", localLoadbalancer.Name, err) + msg := fmt.Sprintf("GetILoadBalancerBackendGroups for loadbalancer %s failed %s", localLoadbalancer.Name, err) log.Errorf(msg) logSyncFailed(provider, task, msg) return diff --git a/pkg/compute/tasks/loadbalanceracl_create_task.go b/pkg/compute/tasks/loadbalancer_acl_create_task.go similarity index 100% rename from pkg/compute/tasks/loadbalanceracl_create_task.go rename to pkg/compute/tasks/loadbalancer_acl_create_task.go diff --git a/pkg/compute/tasks/loadbalanceracl_delete_task.go b/pkg/compute/tasks/loadbalancer_acl_delete_task.go similarity index 100% rename from pkg/compute/tasks/loadbalanceracl_delete_task.go rename to pkg/compute/tasks/loadbalancer_acl_delete_task.go diff --git a/pkg/compute/tasks/loadbalancer_acl_sync_task.go b/pkg/compute/tasks/loadbalancer_acl_sync_task.go new file mode 100644 index 0000000000..8c41672f41 --- /dev/null +++ b/pkg/compute/tasks/loadbalancer_acl_sync_task.go @@ -0,0 +1,47 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerAclSyncTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerAclSyncTask{}) +} + +func (self *LoadbalancerAclSyncTask) taskFail(ctx context.Context, lbacl *models.SLoadbalancerAcl, reason string) { + lbacl.SetStatus(self.GetUserCred(), models.LB_STATUS_SYNCING_FAILED, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerAclSyncTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lbacl := obj.(*models.SLoadbalancerAcl) + region := lbacl.GetRegion() + if region == nil { + self.taskFail(ctx, lbacl, fmt.Sprintf("failed to find region for lbacl %s", lbacl.Name)) + return + } + self.SetStage("OnLoadbalancerAclSyncComplete", nil) + if err := region.GetDriver().RequestSyncLoadbalancerAcl(ctx, self.GetUserCred(), lbacl, self); err != nil { + self.taskFail(ctx, lbacl, err.Error()) + } +} + +func (self *LoadbalancerAclSyncTask) OnLoadbalancerAclSyncComplete(ctx context.Context, lbacl *models.SLoadbalancerAcl, data jsonutils.JSONObject) { + lbacl.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerAclSyncTask) OnLoadbalancerAclSyncCompleteFailed(ctx context.Context, lbacl *models.SLoadbalancerAcl, reason jsonutils.JSONObject) { + self.taskFail(ctx, lbacl, reason.String()) +} diff --git a/pkg/compute/tasks/loadbalancercertificate_create_task.go b/pkg/compute/tasks/loadbalancer_certificate_create_task.go similarity index 100% rename from pkg/compute/tasks/loadbalancercertificate_create_task.go rename to pkg/compute/tasks/loadbalancer_certificate_create_task.go diff --git a/pkg/compute/tasks/loadbalancercertificate_delete_task.go b/pkg/compute/tasks/loadbalancer_certificate_delete_task.go similarity index 100% rename from pkg/compute/tasks/loadbalancercertificate_delete_task.go rename to pkg/compute/tasks/loadbalancer_certificate_delete_task.go diff --git a/pkg/compute/tasks/loadbalancer_listener_rule_create_task.go b/pkg/compute/tasks/loadbalancer_listener_rule_create_task.go new file mode 100644 index 0000000000..843ef57f0e --- /dev/null +++ b/pkg/compute/tasks/loadbalancer_listener_rule_create_task.go @@ -0,0 +1,47 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerListenerRuleCreateTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerListenerRuleCreateTask{}) +} + +func (self *LoadbalancerListenerRuleCreateTask) taskFail(ctx context.Context, lbr *models.SLoadbalancerListenerRule, reason string) { + lbr.SetStatus(self.GetUserCred(), models.LB_STATUS_CREATE_FAILED, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerListenerRuleCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lbr := obj.(*models.SLoadbalancerListenerRule) + region := lbr.GetRegion() + if region == nil { + self.taskFail(ctx, lbr, fmt.Sprintf("failed to find region for lbr %s", lbr.Name)) + return + } + self.SetStage("OnLoadbalancerListenerRuleCreateComplete", nil) + if err := region.GetDriver().RequestCreateLoadbalancerListenerRule(ctx, self.GetUserCred(), lbr, self); err != nil { + self.taskFail(ctx, lbr, err.Error()) + } +} + +func (self *LoadbalancerListenerRuleCreateTask) OnLoadbalancerListenerRuleCreateComplete(ctx context.Context, lbr *models.SLoadbalancerListenerRule, data jsonutils.JSONObject) { + lbr.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerListenerRuleCreateTask) OnLoadbalancerListenerRuleCreateCompleteFailed(ctx context.Context, lbr *models.SLoadbalancerListenerRule, reason jsonutils.JSONObject) { + self.taskFail(ctx, lbr, reason.String()) +} diff --git a/pkg/compute/tasks/loadbalancer_listener_rule_delete_task.go b/pkg/compute/tasks/loadbalancer_listener_rule_delete_task.go new file mode 100644 index 0000000000..771cf90ee9 --- /dev/null +++ b/pkg/compute/tasks/loadbalancer_listener_rule_delete_task.go @@ -0,0 +1,47 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerListenerRuleDeleteTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerListenerRuleDeleteTask{}) +} + +func (self *LoadbalancerListenerRuleDeleteTask) taskFail(ctx context.Context, lbr *models.SLoadbalancerListenerRule, reason string) { + lbr.SetStatus(self.GetUserCred(), models.LB_STATUS_DELETE_FAILED, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerListenerRuleDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lbr := obj.(*models.SLoadbalancerListenerRule) + region := lbr.GetRegion() + if region == nil { + self.taskFail(ctx, lbr, fmt.Sprintf("failed to find region for lbr %s", lbr.Name)) + return + } + self.SetStage("OnLoadbalancerListenerRuleDeleteComplete", nil) + if err := region.GetDriver().RequestDeleteLoadbalancerListenerRule(ctx, self.GetUserCred(), lbr, self); err != nil { + self.taskFail(ctx, lbr, err.Error()) + } +} + +func (self *LoadbalancerListenerRuleDeleteTask) OnLoadbalancerListenerRuleDeleteComplete(ctx context.Context, lbr *models.SLoadbalancerListenerRule, data jsonutils.JSONObject) { + lbr.DoPendingDelete(ctx, self.GetUserCred()) + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerListenerRuleDeleteTask) OnLoadbalancerListenerRuleDeleteCompleteFailed(ctx context.Context, lbr *models.SLoadbalancerListenerRule, reason jsonutils.JSONObject) { + self.taskFail(ctx, lbr, reason.String()) +} diff --git a/pkg/compute/tasks/loadbalancer_listener_start_task.go b/pkg/compute/tasks/loadbalancer_listener_start_task.go new file mode 100644 index 0000000000..d067f56544 --- /dev/null +++ b/pkg/compute/tasks/loadbalancer_listener_start_task.go @@ -0,0 +1,57 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerListenerStartTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerListenerStartTask{}) +} + +func (self *LoadbalancerListenerStartTask) taskFail(ctx context.Context, lblis *models.SLoadbalancerListener, reason string) { + lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_UNKNOWN, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerListenerStartTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lblis := obj.(*models.SLoadbalancerListener) + region := lblis.GetRegion() + if region == nil { + self.taskFail(ctx, lblis, fmt.Sprintf("failed to find region for lblis %s", lblis.Name)) + return + } + self.SetStage("OnLoadbalancerListenerStartComplete", nil) + if err := region.GetDriver().RequestStartLoadbalancerListener(ctx, self.GetUserCred(), lblis, self); err != nil { + self.taskFail(ctx, lblis, err.Error()) + } +} + +func (self *LoadbalancerListenerStartTask) OnLoadbalancerListenerStartComplete(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { + lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerListenerStartTask) OnLoadbalancerListenerStartCompleteFailed(ctx context.Context, lblis *models.SLoadbalancerListener, reason jsonutils.JSONObject) { + lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_START_FAILED, reason.String()) + self.SetStage("OnLoadbalancerListenerSyncStatusComplete", nil) + lblis.StartLoadBalancerListenerSyncstatusTask(ctx, self.GetUserCred(), self.GetTaskId()) +} + +func (self *LoadbalancerListenerStartTask) OnLoadbalancerListenerSyncStatusComplete(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerListenerStartTask) OnLoadbalancerListenerSyncStatusCompleteFailed(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { + self.taskFail(ctx, lblis, data.String()) +} diff --git a/pkg/compute/tasks/loadbalancer_listener_stop_task.go b/pkg/compute/tasks/loadbalancer_listener_stop_task.go new file mode 100644 index 0000000000..1593fcd63e --- /dev/null +++ b/pkg/compute/tasks/loadbalancer_listener_stop_task.go @@ -0,0 +1,57 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerListenerStopTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerListenerStopTask{}) +} + +func (self *LoadbalancerListenerStopTask) taskFail(ctx context.Context, lblis *models.SLoadbalancerListener, reason string) { + lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_UNKNOWN, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerListenerStopTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lblis := obj.(*models.SLoadbalancerListener) + region := lblis.GetRegion() + if region == nil { + self.taskFail(ctx, lblis, fmt.Sprintf("failed to find region for lblis %s", lblis.Name)) + return + } + self.SetStage("OnLoadbalancerListenerStopComplete", nil) + if err := region.GetDriver().RequestStopLoadbalancerListener(ctx, self.GetUserCred(), lblis, self); err != nil { + self.taskFail(ctx, lblis, err.Error()) + } +} + +func (self *LoadbalancerListenerStopTask) OnLoadbalancerListenerStopComplete(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { + lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_DISABLED, "") + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerListenerStopTask) OnLoadbalancerListenerStopCompleteFailed(ctx context.Context, lblis *models.SLoadbalancerListener, reason jsonutils.JSONObject) { + lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_START_FAILED, reason.String()) + self.SetStage("OnLoadbalancerListenerSyncStatusComplete", nil) + lblis.StartLoadBalancerListenerSyncstatusTask(ctx, self.GetUserCred(), self.GetTaskId()) +} + +func (self *LoadbalancerListenerStopTask) OnLoadbalancerListenerSyncStatusComplete(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerListenerStopTask) OnLoadbalancerListenerSyncStatusCompleteFailed(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { + self.taskFail(ctx, lblis, data.String()) +} diff --git a/pkg/compute/tasks/loadbalancer_listener_syncstatus_task.go b/pkg/compute/tasks/loadbalancer_listener_syncstatus_task.go new file mode 100644 index 0000000000..c9c3235ef2 --- /dev/null +++ b/pkg/compute/tasks/loadbalancer_listener_syncstatus_task.go @@ -0,0 +1,46 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerListenerSyncstatusTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerListenerSyncstatusTask{}) +} + +func (self *LoadbalancerListenerSyncstatusTask) taskFail(ctx context.Context, lblis *models.SLoadbalancerListener, reason string) { + lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_UNKNOWN, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerListenerSyncstatusTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lblis := obj.(*models.SLoadbalancerListener) + region := lblis.GetRegion() + if region == nil { + self.taskFail(ctx, lblis, fmt.Sprintf("failed to find region for lblis %s", lblis.Name)) + return + } + self.SetStage("OnLoadbalancerListenerSyncstatusComplete", nil) + if err := region.GetDriver().RequestSyncstatusLoadbalancerListener(ctx, self.GetUserCred(), lblis, self); err != nil { + self.taskFail(ctx, lblis, err.Error()) + } +} + +func (self *LoadbalancerListenerSyncstatusTask) OnLoadbalancerListenerSyncstatusComplete(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerListenerSyncstatusTask) OnLoadbalancerListenerSyncstatusCompleteFailed(ctx context.Context, lblis *models.SLoadbalancerListener, reason jsonutils.JSONObject) { + self.taskFail(ctx, lblis, reason.String()) +} diff --git a/pkg/compute/tasks/loadbalancer_start_task.go b/pkg/compute/tasks/loadbalancer_start_task.go new file mode 100644 index 0000000000..28512fbe35 --- /dev/null +++ b/pkg/compute/tasks/loadbalancer_start_task.go @@ -0,0 +1,57 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerStartTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerStartTask{}) +} + +func (self *LoadbalancerStartTask) taskFail(ctx context.Context, lb *models.SLoadbalancer, reason string) { + lb.SetStatus(self.GetUserCred(), models.LB_STATUS_UNKNOWN, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerStartTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lb := obj.(*models.SLoadbalancer) + region := lb.GetRegion() + if region == nil { + self.taskFail(ctx, lb, fmt.Sprintf("failed to find region for lb %s", lb.Name)) + return + } + self.SetStage("OnLoadbalancerStartComplete", nil) + if err := region.GetDriver().RequestStartLoadbalancer(ctx, self.GetUserCred(), lb, self); err != nil { + self.taskFail(ctx, lb, err.Error()) + } +} + +func (self *LoadbalancerStartTask) OnLoadbalancerStartComplete(ctx context.Context, lb *models.SLoadbalancer, data jsonutils.JSONObject) { + lb.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerStartTask) OnLoadbalancerStartCompleteFailed(ctx context.Context, lb *models.SLoadbalancer, reason jsonutils.JSONObject) { + lb.SetStatus(self.GetUserCred(), models.LB_STATUS_START_FAILED, reason.String()) + self.SetStage("OnLoadbalancerSyncStatusComplete", nil) + lb.StartLoadBalancerSyncstatusTask(ctx, self.GetUserCred(), self.GetTaskId()) +} + +func (self *LoadbalancerStartTask) OnLoadbalancerSyncStatusComplete(ctx context.Context, lb *models.SLoadbalancer, data jsonutils.JSONObject) { + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerStartTask) OnLoadbalancerSyncStatusCompleteFailed(ctx context.Context, lb *models.SLoadbalancer, data jsonutils.JSONObject) { + self.taskFail(ctx, lb, data.String()) +} diff --git a/pkg/compute/tasks/loadbalancer_stop_task.go b/pkg/compute/tasks/loadbalancer_stop_task.go new file mode 100644 index 0000000000..e7618cfdc9 --- /dev/null +++ b/pkg/compute/tasks/loadbalancer_stop_task.go @@ -0,0 +1,57 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerStopTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerStopTask{}) +} + +func (self *LoadbalancerStopTask) taskFail(ctx context.Context, lb *models.SLoadbalancer, reason string) { + lb.SetStatus(self.GetUserCred(), models.LB_STATUS_UNKNOWN, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerStopTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lb := obj.(*models.SLoadbalancer) + region := lb.GetRegion() + if region == nil { + self.taskFail(ctx, lb, fmt.Sprintf("failed to find region for lb %s", lb.Name)) + return + } + self.SetStage("OnLoadbalancerStopComplete", nil) + if err := region.GetDriver().RequestStopLoadbalancer(ctx, self.GetUserCred(), lb, self); err != nil { + self.taskFail(ctx, lb, err.Error()) + } +} + +func (self *LoadbalancerStopTask) OnLoadbalancerStopComplete(ctx context.Context, lb *models.SLoadbalancer, data jsonutils.JSONObject) { + lb.SetStatus(self.GetUserCred(), models.LB_STATUS_DISABLED, "") + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerStopTask) OnLoadbalancerStopCompleteFailed(ctx context.Context, lb *models.SLoadbalancer, reason jsonutils.JSONObject) { + lb.SetStatus(self.GetUserCred(), models.LB_STATUS_START_FAILED, reason.String()) + self.SetStage("OnLoadbalancerSyncStatusComplete", nil) + lb.StartLoadBalancerSyncstatusTask(ctx, self.GetUserCred(), self.GetTaskId()) +} + +func (self *LoadbalancerStopTask) OnLoadbalancerSyncStatusComplete(ctx context.Context, lb *models.SLoadbalancer, data jsonutils.JSONObject) { + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerStopTask) OnLoadbalancerSyncStatusCompleteFailed(ctx context.Context, lb *models.SLoadbalancer, data jsonutils.JSONObject) { + self.taskFail(ctx, lb, data.String()) +} diff --git a/pkg/compute/tasks/loadbalancer_syncstatus_task.go b/pkg/compute/tasks/loadbalancer_syncstatus_task.go new file mode 100644 index 0000000000..4fe30bc890 --- /dev/null +++ b/pkg/compute/tasks/loadbalancer_syncstatus_task.go @@ -0,0 +1,46 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type LoadbalancerSyncstatusTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerSyncstatusTask{}) +} + +func (self *LoadbalancerSyncstatusTask) taskFail(ctx context.Context, lb *models.SLoadbalancer, reason string) { + lb.SetStatus(self.GetUserCred(), models.LB_STATUS_UNKNOWN, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerSyncstatusTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lb := obj.(*models.SLoadbalancer) + region := lb.GetRegion() + if region == nil { + self.taskFail(ctx, lb, fmt.Sprintf("failed to find region for lb %s", lb.Name)) + return + } + self.SetStage("OnLoadbalancerSyncstatusComplete", nil) + if err := region.GetDriver().RequestSyncstatusLoadbalancer(ctx, self.GetUserCred(), lb, self); err != nil { + self.taskFail(ctx, lb, err.Error()) + } +} + +func (self *LoadbalancerSyncstatusTask) OnLoadbalancerSyncstatusComplete(ctx context.Context, lb *models.SLoadbalancer, data jsonutils.JSONObject) { + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerSyncstatusTask) OnLoadbalancerSyncstatusCompleteFailed(ctx context.Context, lb *models.SLoadbalancer, reason jsonutils.JSONObject) { + self.taskFail(ctx, lb, reason.String()) +} diff --git a/pkg/mcclient/options/loadbalanceracls.go b/pkg/mcclient/options/loadbalanceracls.go index 801c3aa7bf..27591e9829 100644 --- a/pkg/mcclient/options/loadbalanceracls.go +++ b/pkg/mcclient/options/loadbalanceracls.go @@ -59,7 +59,7 @@ type LoadbalancerAclCreateOptions struct { NAME string AclEntry []string `help:"acl entry with cidr and comment separated by #, e.g. 10.9.0.0/16#no comment" json:"-"` Provider string `json:"manager_id"` - REGION string `json:"cloudregion_id"` + Region string `required:"true" json:"cloudregion_id"` } type LoadbalancerAclGetOptions struct { diff --git a/pkg/mcclient/options/loadbalancercertificates.go b/pkg/mcclient/options/loadbalancercertificates.go index b93dabedaa..f544bd7d1b 100644 --- a/pkg/mcclient/options/loadbalancercertificates.go +++ b/pkg/mcclient/options/loadbalancercertificates.go @@ -36,8 +36,10 @@ func loadbalancerCertificateLoadFiles(cert, pkey string, allowEmpty bool) (*json type LoadbalancerCertificateCreateOptions struct { NAME string - Cert string `required:"true" json:"-" help:"path to certificate file"` - Pkey string `required:"true" json:"-" help:"path to private key file"` + Cert string `required:"true" json:"-" help:"path to certificate file"` + Pkey string `required:"true" json:"-" help:"path to private key file"` + Region string `required:"true" json:"cloudregion_id"` + ManagerId string } func (opts *LoadbalancerCertificateCreateOptions) Params() (*jsonutils.JSONDict, error) { diff --git a/pkg/mcclient/options/loadbalancers.go b/pkg/mcclient/options/loadbalancers.go index 9406520f1c..aa98cadfb2 100644 --- a/pkg/mcclient/options/loadbalancers.go +++ b/pkg/mcclient/options/loadbalancers.go @@ -4,8 +4,11 @@ type LoadbalancerCreateOptions struct { NAME string Network string Address string + AddressType string `choices:"intranet|internet"` LoadbalancerSpec string `choices:"slb.s1.small|slb.s2.small|slb.s2.medium|slb.s3.small|slb.s3.medium|slb.s3.large"` ChargeType string `choices:"traffic|bandwidth"` + Zone string + ManagerId string } type LoadbalancerGetOptions struct { diff --git a/pkg/util/aliyun/aliyun.go b/pkg/util/aliyun/aliyun.go index 6407a03530..7b29e9911e 100644 --- a/pkg/util/aliyun/aliyun.go +++ b/pkg/util/aliyun/aliyun.go @@ -55,7 +55,12 @@ func jsonRequest(client *sdk.Client, domain, apiVersion, apiName string, params resp, err := _jsonRequest(client, domain, apiVersion, apiName, params) retry := false if err != nil { - for _, code := range []string{"SignatureNonceUsed", "InvalidInstance.NotSupported"} { + for _, code := range []string{"404 Not Found"} { + if strings.Contains(err.Error(), code) { + return nil, cloudprovider.ErrNotFound + } + } + for _, code := range []string{"SignatureNonceUsed", "InvalidInstance.NotSupported", "try later"} { if strings.Contains(err.Error(), code) { retry = true break diff --git a/pkg/util/aliyun/loadbalancer.go b/pkg/util/aliyun/loadbalancer.go index 135f65d7ac..b1a0b974bd 100644 --- a/pkg/util/aliyun/loadbalancer.go +++ b/pkg/util/aliyun/loadbalancer.go @@ -60,6 +60,7 @@ type SLoadbalancer struct { PayType string //实例的计费类型,取值:PayOnDemand:按量付费 PrePay:预付费 ResourceGroupId string //企业资源组ID。 LoadBalancerSpec string //负载均衡实例的的性能规格 + Bandwidth int //按带宽计费的公网型实例的带宽峰值 } func (lb *SLoadbalancer) GetName() string { @@ -160,7 +161,7 @@ func (lb *SLoadbalancer) Delete() error { return err } -func (lb *SLoadbalancer) GetILoadbalancerBackendGroups() ([]cloudprovider.ICloudLoadbalancerBackendGroup, error) { +func (lb *SLoadbalancer) GetILoadBalancerBackendGroups() ([]cloudprovider.ICloudLoadbalancerBackendGroup, error) { ibackendgroups := []cloudprovider.ICloudLoadbalancerBackendGroup{} { backendgroups, err := lb.region.GetLoadbalancerBackendgroups(lb.LoadBalancerId) @@ -191,27 +192,41 @@ func (lb *SLoadbalancer) GetILoadbalancerBackendGroups() ([]cloudprovider.ICloud return ibackendgroups, nil } -func (lb *SLoadbalancer) CreateILoadBalancerBackendGroup(name string, groupType string, backends []cloudprovider.SLoadbalancerBackend) (cloudprovider.ICloudLoadbalancerBackendGroup, error) { - switch groupType { +func (lb *SLoadbalancer) CreateILoadBalancerBackendGroup(group *cloudprovider.SLoadbalancerBackendGroup) (cloudprovider.ICloudLoadbalancerBackendGroup, error) { + switch group.GroupType { case models.LB_BACKENDGROUP_TYPE_NORMAL: - group, err := lb.region.CreateLoadbalancerBackendGroup(name, lb.LoadBalancerId, backends) + group, err := lb.region.CreateLoadbalancerBackendGroup(group.Name, lb.LoadBalancerId, group.Backends) if err != nil { return nil, err } group.lb = lb return group, nil case models.LB_BACKENDGROUP_TYPE_MASTER_SLAVE: - group, err := lb.region.CreateLoadbalancerMasterSlaveBackendGroup(name, lb.LoadBalancerId, backends) + group, err := lb.region.CreateLoadbalancerMasterSlaveBackendGroup(group.Name, lb.LoadBalancerId, group.Backends) if err != nil { return nil, err } group.lb = lb return group, nil default: - return nil, fmt.Errorf("Unsupport backendgroup type %s", groupType) + return nil, fmt.Errorf("Unsupport backendgroup type %s", group.GroupType) } } +func (lb *SLoadbalancer) CreateILoadBalancerListener(listener *cloudprovider.SLoadbalancerListener) (cloudprovider.ICloudLoadbalancerListener, error) { + switch listener.ListenerType { + case models.LB_LISTENER_TYPE_TCP: + return lb.region.CreateLoadbalancerTCPListener(lb, listener) + case models.LB_LISTENER_TYPE_UDP: + return lb.region.CreateLoadbalancerUDPListener(lb, listener) + case models.LB_LISTENER_TYPE_HTTP: + return lb.region.CreateLoadbalancerHTTPListener(lb, listener) + case models.LB_LISTENER_TYPE_HTTPS: + return lb.region.CreateLoadbalancerHTTPSListener(lb, listener) + } + return nil, fmt.Errorf("unsupport listener type %s", listener.ListenerType) +} + func (lb *SLoadbalancer) GetLoadbalancerSpec() string { if len(lb.LoadBalancerSpec) == 0 { lb.Refresh() @@ -229,8 +244,8 @@ func (lb *SLoadbalancer) GetChargeType() string { return "unknown" } -func (lb *SLoadbalancer) GetILoadbalancerBackendGroupById(groupId string) (cloudprovider.ICloudLoadbalancerBackendGroup, error) { - groups, err := lb.GetILoadbalancerBackendGroups() +func (lb *SLoadbalancer) GetILoadBalancerBackendGroupById(groupId string) (cloudprovider.ICloudLoadbalancerBackendGroup, error) { + groups, err := lb.GetILoadBalancerBackendGroups() if err != nil { return nil, err } @@ -242,7 +257,43 @@ func (lb *SLoadbalancer) GetILoadbalancerBackendGroupById(groupId string) (cloud return nil, cloudprovider.ErrNotFound } -func (lb *SLoadbalancer) GetILoadbalancerListeners() ([]cloudprovider.ICloudLoadbalancerListener, error) { +func (region *SRegion) loadbalancerOperation(loadbalancerId, status string) error { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["LoadBalancerId"] = loadbalancerId + params["LoadBalancerStatus"] = status + _, err := region.lbRequest("SetLoadBalancerStatus", params) + return err +} + +func (lb *SLoadbalancer) Start() error { + if lb.LoadBalancerStatus != "active" { + return lb.region.loadbalancerOperation(lb.LoadBalancerId, "active") + } + return nil +} + +func (lb *SLoadbalancer) Stop() error { + if lb.LoadBalancerStatus != "inactive" { + return lb.region.loadbalancerOperation(lb.LoadBalancerId, "inactive") + } + return nil +} + +func (lb *SLoadbalancer) GetILoadBalancerListenerById(listenerId string) (cloudprovider.ICloudLoadbalancerListener, error) { + listener, err := lb.GetILoadBalancerListeners() + if err != nil { + return nil, err + } + for i := 0; i < len(listener); i++ { + if listener[i].GetGlobalId() == listenerId { + return listener[i], nil + } + } + return nil, cloudprovider.ErrNotFound +} + +func (lb *SLoadbalancer) GetILoadBalancerListeners() ([]cloudprovider.ICloudLoadbalancerListener, error) { loadbalancer, err := lb.region.GetLoadbalancerDetail(lb.LoadBalancerId) if err != nil { return nil, err diff --git a/pkg/util/aliyun/loadbalanceracl.go b/pkg/util/aliyun/loadbalanceracl.go index 545cf69313..226040a686 100644 --- a/pkg/util/aliyun/loadbalanceracl.go +++ b/pkg/util/aliyun/loadbalanceracl.go @@ -3,6 +3,7 @@ package aliyun import ( "yunion.io/x/jsonutils" "yunion.io/x/log" + "yunion.io/x/onecloud/pkg/cloudprovider" ) type AclEntrys struct { @@ -55,17 +56,17 @@ func (acl *SLoadbalancerAcl) Refresh() error { return jsonutils.Update(acl, loadbalancerAcl) } -func (acl *SLoadbalancerAcl) GetAclEntries() *jsonutils.JSONArray { - result := jsonutils.NewArray() +func (acl *SLoadbalancerAcl) GetAclEntries() []cloudprovider.SLoadbalancerAccessControlListEntry { detail, err := acl.region.GetLoadbalancerAclDetail(acl.AclId) if err != nil { log.Errorf("GetLoadbalancerAclDetail %s failed: %v", acl.AclId, err) - return result + return nil } + entrys := []cloudprovider.SLoadbalancerAccessControlListEntry{} for _, entry := range detail.AclEntrys.AclEntry { - result.Add(jsonutils.Marshal(map[string]string{"cidr": entry.AclEntryIP, "comment": entry.AclEntryComment})) + entrys = append(entrys, cloudprovider.SLoadbalancerAccessControlListEntry{CIDR: entry.AclEntryIP, Comment: entry.AclEntryComment}) } - return result + return entrys } func (region *SRegion) UpdateAclName(aclId, name string) error { @@ -106,7 +107,7 @@ func (region *SRegion) GetLoadbalancerAclDetail(aclId string) (*SLoadbalancerAcl return &detail, body.Unmarshal(&detail) } -func (region *SRegion) GetLoadbalancerAcls() ([]SLoadbalancerAcl, error) { +func (region *SRegion) GetLoadBalancerAcls() ([]SLoadbalancerAcl, error) { params := map[string]string{} params["RegionId"] = region.RegionId body, err := region.lbRequest("DescribeAccessControlLists", params) @@ -116,3 +117,24 @@ func (region *SRegion) GetLoadbalancerAcls() ([]SLoadbalancerAcl, error) { acls := []SLoadbalancerAcl{} return acls, body.Unmarshal(&acls, "Acls", "Acl") } + +func (acl *SLoadbalancerAcl) Sync(_acl *cloudprovider.SLoadbalancerAccessControlList) error { + if acl.AclName != _acl.Name { + if err := acl.region.UpdateAclName(acl.AclId, _acl.Name); err != nil { + return err + } + } + entrys := jsonutils.NewArray() + for _, entry := range acl.AclEntrys.AclEntry { + entrys.Add(jsonutils.Marshal(map[string]string{"entry": entry.AclEntryIP, "comment": entry.AclEntryComment})) + } + if entrys.Length() > 0 { + if err := acl.region.RemoveAccessControlListEntry(acl.AclId, entrys); err != nil && !isError(err, "Acl does not have any entry") { + return err + } + } + if len(_acl.Entrys) > 0 { + return acl.region.AddAccessControlListEntry(acl.AclId, _acl.Entrys) + } + return nil +} diff --git a/pkg/util/aliyun/loadbalancerbackendgroup.go b/pkg/util/aliyun/loadbalancerbackendgroup.go index 7f2fdb825c..ed928904bf 100644 --- a/pkg/util/aliyun/loadbalancerbackendgroup.go +++ b/pkg/util/aliyun/loadbalancerbackendgroup.go @@ -181,35 +181,37 @@ func (backendgroup *SLoadbalancerBackendGroup) Delete() error { return backendgroup.lb.region.DeleteLoadBalancerBackendGroup(backendgroup.VServerGroupId) } -func (region *SRegion) AddBackendVServer(loadbalancerId, serverId string, weight, port int) error { +func (region *SRegion) AddBackendVServer(loadbalancerId, backendGroupId, serverId string, weight, port int) error { params := map[string]string{} params["RegionId"] = region.RegionId params["LoadBalancerId"] = loadbalancerId + params["VServerGroupId"] = backendGroupId servers := jsonutils.NewArray() - servers.Add(jsonutils.Marshal(map[string]string{"ServerId": serverId, "Weight": fmt.Sprintf("%d", weight*100/256), "Port": fmt.Sprintf("%d", port)})) + servers.Add(jsonutils.Marshal(map[string]string{"ServerId": serverId, "Weight": fmt.Sprintf("%d", weight), "Port": fmt.Sprintf("%d", port)})) params["BackendServers"] = servers.String() _, err := region.lbRequest("AddVServerGroupBackendServers", params) return err } -func (region *SRegion) RemoveBackendVServer(loadbalancerId, serverId string) error { +func (region *SRegion) RemoveBackendVServer(loadbalancerId, backendgroupId, serverId string, port int) error { params := map[string]string{} params["RegionId"] = region.RegionId params["LoadBalancerId"] = loadbalancerId + params["VServerGroupId"] = backendgroupId servers := jsonutils.NewArray() - servers.Add(jsonutils.NewString(serverId)) + servers.Add(jsonutils.Marshal(map[string]string{"ServerId": serverId, "Port": fmt.Sprintf("%d", port)})) params["BackendServers"] = servers.String() _, err := region.lbRequest("RemoveVServerGroupBackendServers", params) return err } func (backendgroup *SLoadbalancerBackendGroup) AddBackendServer(serverId string, weight, port int) (cloudprovider.ICloudLoadbalancerBackend, error) { - if err := backendgroup.lb.region.AddBackendVServer(backendgroup.lb.LoadBalancerId, serverId, weight, port); err != nil { + if err := backendgroup.lb.region.AddBackendVServer(backendgroup.lb.LoadBalancerId, backendgroup.VServerGroupId, serverId, weight, port); err != nil { return nil, err } return &SLoadbalancerBackend{lbbg: backendgroup, ServerId: serverId, Weight: weight, Port: port}, nil } -func (backendgroup *SLoadbalancerBackendGroup) RemoveBackendServer(serverId string) error { - return backendgroup.lb.region.RemoveBackendVServer(backendgroup.lb.LoadBalancerId, serverId) +func (backendgroup *SLoadbalancerBackendGroup) RemoveBackendServer(serverId string, weight, port int) error { + return backendgroup.lb.region.RemoveBackendVServer(backendgroup.lb.LoadBalancerId, backendgroup.VServerGroupId, serverId, port) } diff --git a/pkg/util/aliyun/loadbalancerdefaultbackendgroup.go b/pkg/util/aliyun/loadbalancerdefaultbackendgroup.go index 7e1df929cc..793e529525 100644 --- a/pkg/util/aliyun/loadbalancerdefaultbackendgroup.go +++ b/pkg/util/aliyun/loadbalancerdefaultbackendgroup.go @@ -74,7 +74,7 @@ func (region *SRegion) AddBackendServer(loadbalancerId, serverId string, weight, params["RegionId"] = region.RegionId params["LoadBalancerId"] = loadbalancerId servers := jsonutils.NewArray() - servers.Add(jsonutils.Marshal(map[string]string{"ServerId": serverId, "Weight": fmt.Sprintf("%d", weight*100/256)})) + servers.Add(jsonutils.Marshal(map[string]string{"ServerId": serverId, "Weight": fmt.Sprintf("%d", weight)})) params["BackendServers"] = servers.String() _, err := region.lbRequest("AddBackendServers", params) return err @@ -84,7 +84,7 @@ func (backendgroup *SLoadbalancerDefaultBackendGroup) AddBackendServer(serverId if err := backendgroup.lb.region.AddBackendServer(backendgroup.lb.LoadBalancerId, serverId, weight, port); err != nil { return nil, err } - return &SLoadbalancerDefaultBackend{lbbg: backendgroup, ServerId: serverId}, nil + return &SLoadbalancerDefaultBackend{lbbg: backendgroup, ServerId: serverId, Weight: weight}, nil } func (region *SRegion) RemoveBackendServer(loadbalancerId, serverId string) error { @@ -98,6 +98,6 @@ func (region *SRegion) RemoveBackendServer(loadbalancerId, serverId string) erro return err } -func (backendgroup *SLoadbalancerDefaultBackendGroup) RemoveBackendServer(serverId string) error { +func (backendgroup *SLoadbalancerDefaultBackendGroup) RemoveBackendServer(serverId string, weight, port int) error { return backendgroup.lb.region.RemoveBackendServer(backendgroup.lb.LoadBalancerId, serverId) } diff --git a/pkg/util/aliyun/loadbalancerhttplistener.go b/pkg/util/aliyun/loadbalancerhttplistener.go index 2f47b464ad..5556fc9750 100644 --- a/pkg/util/aliyun/loadbalancerhttplistener.go +++ b/pkg/util/aliyun/loadbalancerhttplistener.go @@ -247,3 +247,83 @@ func (region *SRegion) GetLoadbalancerHTTPListener(loadbalancerId string, listen listener := SLoadbalancerHTTPListener{} return &listener, body.Unmarshal(&listener) } + +func (region *SRegion) DeleteLoadbalancerListener(loadbalancerId string, listenerPort int) error { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["LoadBalancerId"] = loadbalancerId + params["ListenerPort"] = fmt.Sprintf("%d", listenerPort) + _, err := region.lbRequest("DeleteLoadBalancerListener", params) + return err +} + +func (region *SRegion) CreateLoadbalancerHTTPListener(lb *SLoadbalancer, listener *cloudprovider.SLoadbalancerListener) (cloudprovider.ICloudLoadbalancerListener, error) { + params := region.constructBaseCreateListenerParams(lb, listener) + params = region.constructHTTPCreateListenerParams(params, listener) + _, err := region.lbRequest("CreateLoadBalancerHTTPListener", params) + if err != nil { + return nil, err + } + iListener, err := region.GetLoadbalancerHTTPListener(lb.LoadBalancerId, listener.ListenerPort) + if err != nil { + return nil, err + } + iListener.lb = lb + return iListener, nil +} + +func (listerner *SLoadbalancerHTTPListener) Delete() error { + return listerner.lb.region.DeleteLoadbalancerListener(listerner.lb.LoadBalancerId, listerner.ListenerPort) +} + +func (listerner *SLoadbalancerHTTPListener) CreateILoadBalancerListenerRule(rule *cloudprovider.SLoadbalancerListenerRule) (cloudprovider.ICloudLoadbalancerListenerRule, error) { + _rule := &SLoadbalancerListenerRule{ + Domain: rule.Domain, + Url: rule.Path, + RuleName: rule.Name, + } + if len(rule.BackendGroupID) > 0 { //&& rule.BackendGroupType == models.LB_BACKENDGROUP_TYPE_NORMAL { + _rule.VServerGroupId = rule.BackendGroupID + } + listenerRule, err := listerner.lb.region.CreateLoadbalancerListenerRule(listerner.ListenerPort, listerner.lb.LoadBalancerId, _rule) + if err != nil { + return nil, err + } + listenerRule.httpListener = listerner + return listenerRule, nil +} + +func (listerner *SLoadbalancerHTTPListener) GetILoadBalancerListenerRuleById(ruleId string) (cloudprovider.ICloudLoadbalancerListenerRule, error) { + rule, err := listerner.lb.region.GetLoadbalancerListenerRule(ruleId) + if err != nil { + return nil, err + } + rule.httpListener = listerner + return rule, nil +} + +func (region *SRegion) startListener(listenerPort int, loadbalancerId string) error { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["LoadBalancerId"] = loadbalancerId + params["ListenerPort"] = fmt.Sprintf("%d", listenerPort) + _, err := region.lbRequest("StartLoadBalancerListener", params) + return err +} + +func (region *SRegion) stopListener(listenerPort int, loadbalancerId string) error { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["LoadBalancerId"] = loadbalancerId + params["ListenerPort"] = fmt.Sprintf("%d", listenerPort) + _, err := region.lbRequest("StopLoadBalancerListener", params) + return err +} + +func (listerner *SLoadbalancerHTTPListener) Start() error { + return listerner.lb.region.startListener(listerner.ListenerPort, listerner.lb.LoadBalancerId) +} + +func (listerner *SLoadbalancerHTTPListener) Stop() error { + return listerner.lb.region.stopListener(listerner.ListenerPort, listerner.lb.LoadBalancerId) +} diff --git a/pkg/util/aliyun/loadbalancerhttpslistener.go b/pkg/util/aliyun/loadbalancerhttpslistener.go index a88a12ab15..f6da257729 100644 --- a/pkg/util/aliyun/loadbalancerhttpslistener.go +++ b/pkg/util/aliyun/loadbalancerhttpslistener.go @@ -4,6 +4,7 @@ import ( "fmt" "yunion.io/x/jsonutils" + "yunion.io/x/log" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" ) @@ -242,3 +243,92 @@ func (region *SRegion) GetLoadbalancerHTTPSListener(loadbalancerId string, liste listener := SLoadbalancerHTTPSListener{} return &listener, body.Unmarshal(&listener) } + +func (region *SRegion) constructHTTPCreateListenerParams(params map[string]string, listener *cloudprovider.SLoadbalancerListener) map[string]string { + log.Errorf("listener: %s", jsonutils.Marshal(listener).PrettyString()) + params["HealthCheck"] = listener.HealthCheck + if listener.HealthCheck == "on" { + if len(listener.HealthCheckURI) == 0 { + params["HealthCheckURI"] = "/" + } + //The HealthCheckTimeout parameter is required. + if listener.HealthCheckTimeout < 1 || listener.HealthCheckTimeout > 300 { + listener.HealthCheckTimeout = 5 + } + params["HealthCheckTimeout"] = fmt.Sprintf("%d", listener.HealthCheckTimeout) + } + params["StickySession"] = listener.StickySession + params["StickySessionType"] = listener.StickySessionType + params["Cookie"] = listener.StickySessionCookie + if listener.StickySessionCookieTimeout < 1 || listener.StickySessionCookieTimeout > 86400 { + listener.StickySessionCookieTimeout = 500 + } + params["CookieTimeout"] = fmt.Sprintf("%d", listener.StickySessionCookieTimeout) + params["ForwardPort"] = fmt.Sprintf("%d", listener.ForwardPort) + params["Gzip"] = "off" + if listener.Gzip { + params["Gzip"] = "on" + } + params["XForwardedFor"] = "off" + if listener.XForwardedFor { + params["XForwardedFor"] = "on" + } + return params +} + +func (region *SRegion) CreateLoadbalancerHTTPSListener(lb *SLoadbalancer, listener *cloudprovider.SLoadbalancerListener) (cloudprovider.ICloudLoadbalancerListener, error) { + params := region.constructBaseCreateListenerParams(lb, listener) + params = region.constructHTTPCreateListenerParams(params, listener) + params["ServerCertificateId"] = listener.CertificateID + if len(listener.TLSCipherPolicy) > 0 { + params["TLSCipherPolicy"] = listener.TLSCipherPolicy + } + _, err := region.lbRequest("CreateLoadBalancerHTTPSListener", params) + if err != nil { + return nil, err + } + iListener, err := region.GetLoadbalancerHTTPSListener(lb.LoadBalancerId, listener.ListenerPort) + if err != nil { + return nil, err + } + iListener.lb = lb + return iListener, nil +} + +func (listerner *SLoadbalancerHTTPSListener) Delete() error { + return listerner.lb.region.DeleteLoadbalancerListener(listerner.lb.LoadBalancerId, listerner.ListenerPort) +} + +func (listerner *SLoadbalancerHTTPSListener) CreateILoadBalancerListenerRule(rule *cloudprovider.SLoadbalancerListenerRule) (cloudprovider.ICloudLoadbalancerListenerRule, error) { + _rule := &SLoadbalancerListenerRule{ + Domain: rule.Domain, + Url: rule.Path, + RuleName: rule.Name, + } + if len(rule.BackendGroupID) > 0 { //&& rule.BackendGroupType == models.LB_BACKENDGROUP_TYPE_NORMAL { + _rule.VServerGroupId = rule.BackendGroupID + } + listenerRule, err := listerner.lb.region.CreateLoadbalancerListenerRule(listerner.ListenerPort, listerner.lb.LoadBalancerId, _rule) + if err != nil { + return nil, err + } + listenerRule.httpsListener = listerner + return listenerRule, nil +} + +func (listerner *SLoadbalancerHTTPSListener) GetILoadBalancerListenerRuleById(ruleId string) (cloudprovider.ICloudLoadbalancerListenerRule, error) { + rule, err := listerner.lb.region.GetLoadbalancerListenerRule(ruleId) + if err != nil { + return nil, err + } + rule.httpsListener = listerner + return rule, nil +} + +func (listerner *SLoadbalancerHTTPSListener) Start() error { + return listerner.lb.region.startListener(listerner.ListenerPort, listerner.lb.LoadBalancerId) +} + +func (listerner *SLoadbalancerHTTPSListener) Stop() error { + return listerner.lb.region.stopListener(listerner.ListenerPort, listerner.lb.LoadBalancerId) +} diff --git a/pkg/util/aliyun/loadbalancerlistenerrule.go b/pkg/util/aliyun/loadbalancerlistenerrule.go index 8a49013e10..ac69dbefdc 100644 --- a/pkg/util/aliyun/loadbalancerlistenerrule.go +++ b/pkg/util/aliyun/loadbalancerlistenerrule.go @@ -4,18 +4,19 @@ import ( "fmt" "yunion.io/x/jsonutils" + "yunion.io/x/onecloud/pkg/cloudprovider" ) type SLoadbalancerListenerRule struct { httpListener *SLoadbalancerHTTPListener httpsListener *SLoadbalancerHTTPSListener - Domain string + Domain string `json:"Domain"` ListenerSync string RuleId string - RuleName string - Url string - VServerGroupId string + RuleName string `json:"RuleName"` + Url string `json:"Url"` + VServerGroupId string `json:"VServerGroupId"` } func (lbr *SLoadbalancerListenerRule) GetName() string { @@ -42,10 +43,27 @@ func (lbr *SLoadbalancerListenerRule) IsEmulated() bool { return false } -func (lbr *SLoadbalancerListenerRule) Refresh() error { +func (lbr *SLoadbalancerListenerRule) getRegion() *SRegion { + if lbr.httpListener != nil { + return lbr.httpListener.lb.region + } else if lbr.httpsListener != nil { + return lbr.httpsListener.lb.region + } return nil } +func (lbr *SLoadbalancerListenerRule) Refresh() error { + region := lbr.getRegion() + if region == nil { + return fmt.Errorf("failed to find listener for rule %s", lbr.RuleName) + } + rule, err := region.GetLoadbalancerListenerRule(lbr.RuleId) + if err != nil { + return err + } + return jsonutils.Update(lbr, rule) +} + func (lbr *SLoadbalancerListenerRule) GetDomain() string { return lbr.Domain } @@ -70,3 +88,60 @@ func (region *SRegion) GetLoadbalancerListenerRules(loadbalancerId string, liste rules := []SLoadbalancerListenerRule{} return rules, body.Unmarshal(&rules, "Rules", "Rule") } + +func (lbr *SLoadbalancerListenerRule) Delete() error { + if lbr.httpListener != nil { + return lbr.httpListener.lb.region.DeleteLoadbalancerListenerRule(lbr.RuleId) + } + if lbr.httpsListener != nil { + return lbr.httpsListener.lb.region.DeleteLoadbalancerListenerRule(lbr.RuleId) + } + return fmt.Errorf("failed to find listener for listener rule %s", lbr.RuleName) +} + +func (region *SRegion) DeleteLoadbalancerListenerRule(ruleId string) error { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["RuleIds"] = fmt.Sprintf(`["%s"]`, ruleId) + _, err := region.lbRequest("DeleteRules", params) + return err +} + +func (region *SRegion) CreateLoadbalancerListenerRule(listenerPort int, loadbalancerId string, _rule *SLoadbalancerListenerRule) (*SLoadbalancerListenerRule, error) { + params := map[string]string{} + params["RegionId"] = region.RegionId + params["ListenerPort"] = fmt.Sprintf("%d", listenerPort) + params["LoadBalancerId"] = loadbalancerId + _rules := jsonutils.NewArray() + _rules.Add(jsonutils.Marshal(_rule)) + params["RuleList"] = _rules.String() + body, err := region.lbRequest("CreateRules", params) + if err != nil { + return nil, err + } + rules := []SLoadbalancerListenerRule{} + if err := body.Unmarshal(&rules, "Rules", "Rule"); err != nil { + return nil, err + } + for _, rule := range rules { + if rule.RuleName == _rule.RuleName { + return region.GetLoadbalancerListenerRule(rule.RuleId) + } + } + return nil, cloudprovider.ErrNotFound +} + +func (region *SRegion) GetLoadbalancerListenerRule(ruleId string) (*SLoadbalancerListenerRule, error) { + if len(ruleId) == 0 { + return nil, cloudprovider.ErrNotFound + } + params := map[string]string{} + params["RegionId"] = region.RegionId + params["RuleId"] = ruleId + body, err := region.lbRequest("DescribeRuleAttribute", params) + if err != nil { + return nil, err + } + rule := &SLoadbalancerListenerRule{RuleId: ruleId} + return rule, body.Unmarshal(rule) +} diff --git a/pkg/util/aliyun/loadbalancermasterslavebackendgroup.go b/pkg/util/aliyun/loadbalancermasterslavebackendgroup.go index b3e73b0a41..a179dd9b76 100644 --- a/pkg/util/aliyun/loadbalancermasterslavebackendgroup.go +++ b/pkg/util/aliyun/loadbalancermasterslavebackendgroup.go @@ -167,6 +167,6 @@ func (backendgroup *SLoadbalancerMasterSlaveBackendGroup) AddBackendServer(serve return nil, cloudprovider.ErrNotSupported } -func (backendgroup *SLoadbalancerMasterSlaveBackendGroup) RemoveBackendServer(serverId string) error { +func (backendgroup *SLoadbalancerMasterSlaveBackendGroup) RemoveBackendServer(serverId string, weight, port int) error { return cloudprovider.ErrNotSupported } diff --git a/pkg/util/aliyun/loadbalancertcplistener.go b/pkg/util/aliyun/loadbalancertcplistener.go index b82511e21a..7953e3fc8a 100644 --- a/pkg/util/aliyun/loadbalancertcplistener.go +++ b/pkg/util/aliyun/loadbalancertcplistener.go @@ -6,6 +6,7 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/pkg/utils" ) type SLoadbalancerTCPListener struct { @@ -205,3 +206,114 @@ func (region *SRegion) GetLoadbalancerTCPListener(loadbalancerId string, listene listener := SLoadbalancerTCPListener{} return &listener, body.Unmarshal(&listener) } + +func (region *SRegion) constructBaseCreateListenerParams(lb *SLoadbalancer, listener *cloudprovider.SLoadbalancerListener) map[string]string { + params := map[string]string{} + params["RegionId"] = region.RegionId + switch lb.InternetChargeType { + case "paybybandwidth": + params["Bandwidth"] = "-1" + case "paybytraffic": + if lb.Bandwidth > 5000 { + lb.Bandwidth = 5000 + } + params["Bandwidth"] = fmt.Sprintf("%d", lb.Bandwidth) + default: + params["Bandwidth"] = fmt.Sprintf("%d", listener.Bandwidth) + } + params["ListenerPort"] = fmt.Sprintf("%d", listener.ListenerPort) + params["LoadBalancerId"] = lb.LoadBalancerId + if len(listener.AccessControlListID) > 0 { + params["AclId"] = listener.AccessControlListID + } + if utils.IsInStringArray(listener.AccessControlListStatus, []string{"on", "off"}) { + params["AclStatus"] = listener.AccessControlListStatus + } + if utils.IsInStringArray(listener.AccessControlListType, []string{"white", "black"}) { + params["AclType"] = listener.AccessControlListType + } + if len(listener.BackendGroupID) > 0 { + switch listener.BackendGroupType { + case models.LB_BACKENDGROUP_TYPE_NORMAL: + params["VServerGroupId"] = listener.BackendGroupID + case models.LB_BACKENDGROUP_TYPE_MASTER_SLAVE: + params["MasterSlaveServerGroupId"] = listener.BackendGroupID + } + } else { + //TODO + params["BackendServerPort"] = "" + } + if len(listener.Description) > 0 { + params["Description"] = listener.Description + } + if listener.EstablishedTimeout >= 10 && listener.EstablishedTimeout <= 900 { + params["EstablishedTimeout"] = fmt.Sprintf("%d", listener.EstablishedTimeout) + } + + if utils.IsInStringArray(listener.ListenerType, []string{models.LB_LISTENER_TYPE_TCP, models.LB_LISTENER_TYPE_UDP}) { + if listener.HealthCheckTimeout >= 1 && listener.HealthCheckTimeout <= 300 { + params["HealthCheckConnectTimeout"] = fmt.Sprintf("%d", listener.HealthCheckTimeout) + } + } + + if len(listener.HealthCheckDomain) > 0 { + params["HealthCheckDomain"] = listener.HealthCheckDomain + } + + if len(listener.HealthCheckHttpCode) > 0 { + params["HealthCheckHttpCode"] = listener.HealthCheckHttpCode + } + + if len(listener.HealthCheckURI) > 0 { + params["HealthCheckURI"] = listener.HealthCheckURI + } + + if listener.HealthCheckRise >= 2 && listener.HealthCheckRise <= 10 { + params["HealthyThreshold"] = fmt.Sprintf("%d", listener.HealthCheckRise) + } + + if listener.HealthCheckFail >= 2 && listener.HealthCheckFail <= 10 { + params["UnhealthyThreshold"] = fmt.Sprintf("%d", listener.HealthCheckFail) + } + + if listener.HealthCheckInterval >= 1 && listener.HealthCheckInterval <= 50 { + params["healthCheckInterval"] = fmt.Sprintf("%d", listener.HealthCheckInterval) + } + + params["Scheduler"] = listener.Scheduler + return params +} + +func (region *SRegion) CreateLoadbalancerTCPListener(lb *SLoadbalancer, listener *cloudprovider.SLoadbalancerListener) (cloudprovider.ICloudLoadbalancerListener, error) { + params := region.constructBaseCreateListenerParams(lb, listener) + _, err := region.lbRequest("CreateLoadBalancerTCPListener", params) + if err != nil { + return nil, err + } + iListener, err := region.GetLoadbalancerTCPListener(lb.LoadBalancerId, listener.ListenerPort) + if err != nil { + return nil, err + } + iListener.lb = lb + return iListener, nil +} + +func (listerner *SLoadbalancerTCPListener) Delete() error { + return listerner.lb.region.DeleteLoadbalancerListener(listerner.lb.LoadBalancerId, listerner.ListenerPort) +} + +func (listerner *SLoadbalancerTCPListener) CreateILoadBalancerListenerRule(rule *cloudprovider.SLoadbalancerListenerRule) (cloudprovider.ICloudLoadbalancerListenerRule, error) { + return nil, cloudprovider.ErrNotSupported +} + +func (listerner *SLoadbalancerTCPListener) GetILoadBalancerListenerRuleById(ruleId string) (cloudprovider.ICloudLoadbalancerListenerRule, error) { + return nil, cloudprovider.ErrNotSupported +} + +func (listerner *SLoadbalancerTCPListener) Start() error { + return listerner.lb.region.startListener(listerner.ListenerPort, listerner.lb.LoadBalancerId) +} + +func (listerner *SLoadbalancerTCPListener) Stop() error { + return listerner.lb.region.stopListener(listerner.ListenerPort, listerner.lb.LoadBalancerId) +} diff --git a/pkg/util/aliyun/loadbalancerudplistener.go b/pkg/util/aliyun/loadbalancerudplistener.go index 10f98b1e34..e9624754ed 100644 --- a/pkg/util/aliyun/loadbalancerudplistener.go +++ b/pkg/util/aliyun/loadbalancerudplistener.go @@ -206,3 +206,37 @@ func (region *SRegion) GetLoadbalancerUDPListener(loadbalancerId string, listene listener := SLoadbalancerUDPListener{} return &listener, body.Unmarshal(&listener) } + +func (region *SRegion) CreateLoadbalancerUDPListener(lb *SLoadbalancer, listener *cloudprovider.SLoadbalancerListener) (cloudprovider.ICloudLoadbalancerListener, error) { + params := region.constructBaseCreateListenerParams(lb, listener) + _, err := region.lbRequest("CreateLoadBalancerUDPListener", params) + if err != nil { + return nil, err + } + iListener, err := region.GetLoadbalancerUDPListener(lb.LoadBalancerId, listener.ListenerPort) + if err != nil { + return nil, err + } + iListener.lb = lb + return iListener, nil +} + +func (listerner *SLoadbalancerUDPListener) Delete() error { + return listerner.lb.region.DeleteLoadbalancerListener(listerner.lb.LoadBalancerId, listerner.ListenerPort) +} + +func (listerner *SLoadbalancerUDPListener) CreateILoadBalancerListenerRule(rule *cloudprovider.SLoadbalancerListenerRule) (cloudprovider.ICloudLoadbalancerListenerRule, error) { + return nil, cloudprovider.ErrNotSupported +} + +func (listerner *SLoadbalancerUDPListener) GetILoadBalancerListenerRuleById(ruleId string) (cloudprovider.ICloudLoadbalancerListenerRule, error) { + return nil, cloudprovider.ErrNotSupported +} + +func (listerner *SLoadbalancerUDPListener) Start() error { + return listerner.lb.region.startListener(listerner.ListenerPort, listerner.lb.LoadBalancerId) +} + +func (listerner *SLoadbalancerUDPListener) Stop() error { + return listerner.lb.region.stopListener(listerner.ListenerPort, listerner.lb.LoadBalancerId) +} diff --git a/pkg/util/aliyun/region.go b/pkg/util/aliyun/region.go index 547013e077..a022e81a67 100644 --- a/pkg/util/aliyun/region.go +++ b/pkg/util/aliyun/region.go @@ -698,12 +698,12 @@ func (region *SRegion) GetILoadBalancerCertificateById(certId string) (cloudprov return nil, cloudprovider.ErrNotFound } -func (region *SRegion) CreateILoadBalancerCertificate(name string, privateKey, certificate string) (cloudprovider.ICloudLoadbalancerCertificate, error) { +func (region *SRegion) CreateILoadBalancerCertificate(cert *cloudprovider.SLoadbalancerCertificate) (cloudprovider.ICloudLoadbalancerCertificate, error) { params := map[string]string{} params["RegionId"] = region.RegionId - params["ServerCertificateName"] = name - params["PrivateKey"] = privateKey - params["ServerCertificate"] = certificate + params["ServerCertificateName"] = cert.Name + params["PrivateKey"] = cert.PrivateKey + params["ServerCertificate"] = cert.Certificate body, err := region.lbRequest("UploadServerCertificate", params) if err != nil { return nil, err @@ -719,8 +719,8 @@ func (region *SRegion) GetILoadBalancerAclById(aclId string) (cloudprovider.IClo return region.GetLoadbalancerAclDetail(aclId) } -func (region *SRegion) GetILoadbalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) { - acls, err := region.GetLoadbalancerAcls() +func (region *SRegion) GetILoadBalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) { + acls, err := region.GetLoadBalancerAcls() if err != nil { return nil, err } @@ -732,7 +732,7 @@ func (region *SRegion) GetILoadbalancerAcls() ([]cloudprovider.ICloudLoadbalance return iAcls, nil } -func (region *SRegion) GetILoadbalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) { +func (region *SRegion) GetILoadBalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) { certificates, err := region.GetLoadbalancerServerCertificates() if err != nil { return nil, err diff --git a/pkg/util/aliyun/shell/loadbalanceracl.go b/pkg/util/aliyun/shell/loadbalanceracl.go index 8ffa47e22b..298e2cd5ed 100644 --- a/pkg/util/aliyun/shell/loadbalanceracl.go +++ b/pkg/util/aliyun/shell/loadbalanceracl.go @@ -9,7 +9,7 @@ func init() { type LoadbalancerACLListOptions struct { } shellutils.R(&LoadbalancerACLListOptions{}, "lb-acl-list", "List loadbalanceAcls", func(cli *aliyun.SRegion, args *LoadbalancerACLListOptions) error { - acls, err := cli.GetLoadbalancerAcls() + acls, err := cli.GetLoadBalancerAcls() if err != nil { return err } diff --git a/pkg/util/aws/region.go b/pkg/util/aws/region.go index 7b02e87036..b3a41fc417 100644 --- a/pkg/util/aws/region.go +++ b/pkg/util/aws/region.go @@ -467,15 +467,15 @@ func (region *SRegion) GetILoadBalancerCertificateById(certId string) (cloudprov return nil, cloudprovider.ErrNotImplemented } -func (region *SRegion) CreateILoadBalancerCertificate(name string, privateKey, certificate string) (cloudprovider.ICloudLoadbalancerCertificate, error) { +func (region *SRegion) CreateILoadBalancerCertificate(cert *cloudprovider.SLoadbalancerCertificate) (cloudprovider.ICloudLoadbalancerCertificate, error) { return nil, cloudprovider.ErrNotImplemented } -func (region *SRegion) GetILoadbalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) { +func (region *SRegion) GetILoadBalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) { return nil, cloudprovider.ErrNotImplemented } -func (region *SRegion) GetILoadbalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) { +func (region *SRegion) GetILoadBalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) { return nil, cloudprovider.ErrNotImplemented } diff --git a/pkg/util/azure/region.go b/pkg/util/azure/region.go index ebc4cc7744..80eb0ddfaa 100644 --- a/pkg/util/azure/region.go +++ b/pkg/util/azure/region.go @@ -519,15 +519,15 @@ func (region *SRegion) GetILoadBalancerCertificateById(certId string) (cloudprov return nil, cloudprovider.ErrNotImplemented } -func (region *SRegion) CreateILoadBalancerCertificate(name string, privateKey, certificate string) (cloudprovider.ICloudLoadbalancerCertificate, error) { +func (region *SRegion) CreateILoadBalancerCertificate(cert *cloudprovider.SLoadbalancerCertificate) (cloudprovider.ICloudLoadbalancerCertificate, error) { return nil, cloudprovider.ErrNotImplemented } -func (region *SRegion) GetILoadbalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) { +func (region *SRegion) GetILoadBalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) { return nil, cloudprovider.ErrNotImplemented } -func (region *SRegion) GetILoadbalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) { +func (region *SRegion) GetILoadBalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) { return nil, cloudprovider.ErrNotImplemented } diff --git a/pkg/util/huawei/region.go b/pkg/util/huawei/region.go index 78ad3dd7b3..a09ee15cfd 100644 --- a/pkg/util/huawei/region.go +++ b/pkg/util/huawei/region.go @@ -145,15 +145,15 @@ func (region *SRegion) GetILoadBalancerCertificateById(certId string) (cloudprov return nil, cloudprovider.ErrNotImplemented } -func (region *SRegion) CreateILoadBalancerCertificate(name string, privateKey, certificate string) (cloudprovider.ICloudLoadbalancerCertificate, error) { +func (region *SRegion) CreateILoadBalancerCertificate(cert *cloudprovider.SLoadbalancerCertificate) (cloudprovider.ICloudLoadbalancerCertificate, error) { return nil, cloudprovider.ErrNotImplemented } -func (self *SRegion) GetILoadbalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) { +func (self *SRegion) GetILoadBalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) { return nil, cloudprovider.ErrNotImplemented } -func (self *SRegion) GetILoadbalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) { +func (self *SRegion) GetILoadBalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) { return nil, cloudprovider.ErrNotImplemented } diff --git a/pkg/util/openstack/region.go b/pkg/util/openstack/region.go index ccad02a2c6..adfedb0131 100644 --- a/pkg/util/openstack/region.go +++ b/pkg/util/openstack/region.go @@ -297,15 +297,15 @@ func (region *SRegion) GetILoadBalancerCertificateById(certId string) (cloudprov return nil, cloudprovider.ErrNotImplemented } -func (region *SRegion) CreateILoadBalancerCertificate(name string, privateKey, certificate string) (cloudprovider.ICloudLoadbalancerCertificate, error) { +func (region *SRegion) CreateILoadBalancerCertificate(cert *cloudprovider.SLoadbalancerCertificate) (cloudprovider.ICloudLoadbalancerCertificate, error) { return nil, cloudprovider.ErrNotImplemented } -func (region *SRegion) GetILoadbalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) { +func (region *SRegion) GetILoadBalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) { return nil, cloudprovider.ErrNotImplemented } -func (region *SRegion) GetILoadbalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) { +func (region *SRegion) GetILoadBalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) { return nil, cloudprovider.ErrNotImplemented } diff --git a/pkg/util/qcloud/region.go b/pkg/util/qcloud/region.go index 0bdc5bcc06..4d223a9129 100644 --- a/pkg/util/qcloud/region.go +++ b/pkg/util/qcloud/region.go @@ -594,15 +594,15 @@ func (region *SRegion) GetILoadBalancerCertificateById(certId string) (cloudprov return nil, cloudprovider.ErrNotImplemented } -func (region *SRegion) CreateILoadBalancerCertificate(name string, privateKey, certificate string) (cloudprovider.ICloudLoadbalancerCertificate, error) { +func (region *SRegion) CreateILoadBalancerCertificate(cert *cloudprovider.SLoadbalancerCertificate) (cloudprovider.ICloudLoadbalancerCertificate, error) { return nil, cloudprovider.ErrNotImplemented } -func (region *SRegion) GetILoadbalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) { +func (region *SRegion) GetILoadBalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) { return nil, cloudprovider.ErrNotImplemented } -func (region *SRegion) GetILoadbalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) { +func (region *SRegion) GetILoadBalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) { return nil, cloudprovider.ErrNotImplemented } From 53b03c1d59be5a5f6690700e92585bfb38a7c664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Tue, 15 Jan 2019 21:32:52 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=9B=91=E5=90=AC?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E9=85=8D=E7=BD=AE=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/climc/shell/loadbalancercertificates.go | 10 ++- cmd/climc/shell/loadbalancerlisteners.go | 8 +++ cmd/climc/shell/loadbalancers.go | 8 +++ pkg/cloudcommon/db/opslog.go | 1 + pkg/cloudprovider/loadbalancerbackend.go | 2 + pkg/cloudprovider/resources.go | 1 + pkg/compute/models/hosts.go | 6 +- pkg/compute/models/hoststorages.go | 2 +- pkg/compute/models/initdb.go | 4 ++ pkg/compute/models/loadbalancer_const.go | 12 ++-- pkg/compute/models/loadbalanceracls.go | 4 +- .../models/loadbalancerbackendgroups.go | 49 ++++++++++--- pkg/compute/models/loadbalancerbackends.go | 31 +++++++- .../models/loadbalancercertificates.go | 4 +- .../models/loadbalancerlistenerrules.go | 31 +++++++- pkg/compute/models/loadbalancerlisteners.go | 72 +++++++++++++++++-- pkg/compute/models/loadbalancers.go | 7 +- pkg/compute/models/regiondrivers.go | 4 +- pkg/compute/regiondrivers/aliyun.go | 45 ++++++++++-- pkg/compute/regiondrivers/base.go | 4 ++ pkg/compute/regiondrivers/kvm.go | 33 ++++++++- pkg/compute/regiondrivers/managedvirtual.go | 41 ++++++++++- .../tasks/loadbalancer_acl_create_task.go | 9 ++- .../tasks/loadbalancer_acl_delete_task.go | 7 ++ .../tasks/loadbalancer_acl_sync_task.go | 9 ++- .../tasks/loadbalancer_backend_create_task.go | 9 ++- .../loadbalancer_backendgroup_create_task.go | 9 ++- .../loadbalancer_backendgroup_delete_task.go | 7 ++ .../loadbalancer_certificate_create_task.go | 9 ++- .../loadbalancer_certificate_delete_task.go | 7 ++ pkg/compute/tasks/loadbalancer_create_task.go | 22 +++++- pkg/compute/tasks/loadbalancer_delete_task.go | 7 ++ .../loadbalancer_listener_create_task.go | 22 +++++- .../loadbalancer_listener_delete_task.go | 7 ++ .../loadbalancer_listener_rule_create_task.go | 9 ++- .../loadbalancer_listener_rule_delete_task.go | 7 ++ .../tasks/loadbalancer_listener_start_task.go | 21 +++--- .../tasks/loadbalancer_listener_stop_task.go | 21 +++--- .../tasks/loadbalancer_listener_sync_task.go | 63 ++++++++++++++++ .../loadbalancer_listener_syncstatus_task.go | 7 ++ pkg/compute/tasks/loadbalancer_start_task.go | 21 +++--- pkg/compute/tasks/loadbalancer_stop_task.go | 21 +++--- .../tasks/loadbalancer_syncstatus_task.go | 7 ++ pkg/mcclient/options/loadbalancerlisteners.go | 4 ++ pkg/mcclient/options/loadbalancers.go | 4 ++ pkg/util/aliyun/aliyun.go | 2 +- pkg/util/aliyun/loadbalancerhttplistener.go | 11 +++ pkg/util/aliyun/loadbalancerhttpslistener.go | 19 ++++- .../loadbalancermasterslavebackendgroup.go | 18 ++--- pkg/util/aliyun/loadbalancertcplistener.go | 18 +++-- pkg/util/aliyun/loadbalancerudplistener.go | 10 +++ pkg/util/logclient/logclient.go | 2 + 52 files changed, 643 insertions(+), 125 deletions(-) create mode 100644 pkg/compute/tasks/loadbalancer_listener_sync_task.go diff --git a/cmd/climc/shell/loadbalancercertificates.go b/cmd/climc/shell/loadbalancercertificates.go index 21882b5165..3aed443386 100644 --- a/cmd/climc/shell/loadbalancercertificates.go +++ b/cmd/climc/shell/loadbalancercertificates.go @@ -51,7 +51,7 @@ func init() { printObject(lbcert) return nil }) - R(&options.LoadbalancerCertificateDeleteOptions{}, "lbcert-delete", "Show lbcert", func(s *mcclient.ClientSession, opts *options.LoadbalancerCertificateDeleteOptions) error { + R(&options.LoadbalancerCertificateDeleteOptions{}, "lbcert-delete", "Delete lbcert", func(s *mcclient.ClientSession, opts *options.LoadbalancerCertificateDeleteOptions) error { lbcert, err := modules.LoadbalancerCertificates.Delete(s, opts.ID, nil) if err != nil { return err @@ -59,4 +59,12 @@ func init() { printObject(lbcert) return nil }) + R(&options.LoadbalancerCertificateDeleteOptions{}, "lbcert-purge", "Purge lbcert", func(s *mcclient.ClientSession, opts *options.LoadbalancerCertificateDeleteOptions) error { + lbcert, err := modules.LoadbalancerCertificates.PerformAction(s, opts.ID, "purge", nil) + if err != nil { + return err + } + printObject(lbcert) + return nil + }) } diff --git a/cmd/climc/shell/loadbalancerlisteners.go b/cmd/climc/shell/loadbalancerlisteners.go index d2dd225c7b..d88b28b4fc 100644 --- a/cmd/climc/shell/loadbalancerlisteners.go +++ b/cmd/climc/shell/loadbalancerlisteners.go @@ -76,4 +76,12 @@ func init() { printObject(lblistener) return nil }) + R(&options.LoadbalancerListenerActionSyncStatusOptions{}, "lblistener-syncstatus", "Sync lblistener status", func(s *mcclient.ClientSession, opts *options.LoadbalancerListenerActionSyncStatusOptions) error { + lblistener, err := modules.LoadbalancerListeners.PerformAction(s, opts.ID, "syncstatus", nil) + if err != nil { + return err + } + printObject(lblistener) + return nil + }) } diff --git a/cmd/climc/shell/loadbalancers.go b/cmd/climc/shell/loadbalancers.go index 4aae865a12..1024f9f6ce 100644 --- a/cmd/climc/shell/loadbalancers.go +++ b/cmd/climc/shell/loadbalancers.go @@ -76,4 +76,12 @@ func init() { printObject(lb) return nil }) + R(&options.LoadbalancerActionSyncStatusOptions{}, "lb-syncstatus", "Sync lb status", func(s *mcclient.ClientSession, opts *options.LoadbalancerActionSyncStatusOptions) error { + lb, err := modules.Loadbalancers.PerformAction(s, opts.ID, "syncstatus", nil) + if err != nil { + return err + } + printObject(lb) + return nil + }) } diff --git a/pkg/cloudcommon/db/opslog.go b/pkg/cloudcommon/db/opslog.go index 8711dc6f49..3b0fe4b8e4 100644 --- a/pkg/cloudcommon/db/opslog.go +++ b/pkg/cloudcommon/db/opslog.go @@ -107,6 +107,7 @@ const ( ACT_SYNCING_CONF = "syncing_conf" ACT_SYNC_CONF = "sync_conf" ACT_SYNC_CONF_FAIL = "sync_conf_fail" + ACT_SYNC_STATUS = "sync_status" ACT_CHANGE_OWNER = "change_owner" diff --git a/pkg/cloudprovider/loadbalancerbackend.go b/pkg/cloudprovider/loadbalancerbackend.go index 16f5f6892b..7f883d9cb4 100644 --- a/pkg/cloudprovider/loadbalancerbackend.go +++ b/pkg/cloudprovider/loadbalancerbackend.go @@ -10,4 +10,6 @@ type SLoadbalancerBackend struct { BackendType string BackendRole string Address string + ZoneId string + HostName string } diff --git a/pkg/cloudprovider/resources.go b/pkg/cloudprovider/resources.go index a14d446a2f..6eed2879fe 100644 --- a/pkg/cloudprovider/resources.go +++ b/pkg/cloudprovider/resources.go @@ -469,6 +469,7 @@ type ICloudLoadbalancerListener interface { Start() error Stop() error + Sync(listener *SLoadbalancerListener) error Delete() error } diff --git a/pkg/compute/models/hosts.go b/pkg/compute/models/hosts.go index ff5fe2cf69..cdf119fdf7 100644 --- a/pkg/compute/models/hosts.go +++ b/pkg/compute/models/hosts.go @@ -125,9 +125,9 @@ type SHost struct { Rack string `width:"16" charset:"ascii" nullable:"true" get:"admin" update:"admin" create:"admin_optional"` // Column(VARCHAR(16, charset='ascii'), nullable=True) Slots string `width:"16" charset:"ascii" nullable:"true" get:"admin" update:"admin" create:"admin_optional"` // Column(VARCHAR(16, charset='ascii'), nullable=True) - AccessMac string `width:"32" charset:"ascii" nullable:"true" index:"true" list:"admin" update:"admin" create:"admin_required"` // Column(VARCHAR(32, charset='ascii'), nullable=False, index=True) - AccessIp string `width:"16" charset:"ascii" nullable:"true" list:"admin" update:"admin" create:"admin_optional"` // Column(VARCHAR(16, charset='ascii'), nullable=True) - ManagerUri string `width:"256" charset:"ascii" nullable:"true" list:"admin" update:"admin" create:"admin_optional"` // Column(VARCHAR(256, charset='ascii'), nullable=True) + AccessMac string `width:"32" charset:"ascii" nullable:"false" index:"true" list:"admin" update:"admin" create:"admin_required"` // Column(VARCHAR(32, charset='ascii'), nullable=False, index=True) + AccessIp string `width:"16" charset:"ascii" nullable:"true" list:"admin" update:"admin" create:"admin_optional"` // Column(VARCHAR(16, charset='ascii'), nullable=True) + ManagerUri string `width:"256" charset:"ascii" nullable:"true" list:"admin" update:"admin" create:"admin_optional"` // Column(VARCHAR(256, charset='ascii'), nullable=True) SysInfo jsonutils.JSONObject `nullable:"true" search:"admin" get:"admin" update:"admin" create:"admin_optional"` // Column(JSONEncodedDict, nullable=True) SN string `width:"128" charset:"ascii" nullable:"true" list:"admin" update:"admin" create:"admin_optional"` // Column(VARCHAR(128, charset='ascii'), nullable=True) diff --git a/pkg/compute/models/hoststorages.go b/pkg/compute/models/hoststorages.go index 863c0e3e2b..a42ccd736a 100644 --- a/pkg/compute/models/hoststorages.go +++ b/pkg/compute/models/hoststorages.go @@ -40,7 +40,7 @@ func init() { type SHoststorage struct { SHostJointsBase - MountPoint string `width:"256" charset:"ascii" nullable:"true" list:"admin" update:"admin" create:"required"` // Column(VARCHAR(256, charset='ascii'), nullable=False) + MountPoint string `width:"256" charset:"ascii" nullable:"false" list:"admin" update:"admin" create:"required"` // Column(VARCHAR(256, charset='ascii'), nullable=False) HostId string `width:"36" charset:"ascii" nullable:"false" list:"admin" create:"required"` // Column(VARCHAR(36, charset='ascii'), nullable=False) StorageId string `width:"36" charset:"ascii" nullable:"false" list:"admin" create:"required"` // Column(VARCHAR(36, charset='ascii'), nullable=False) diff --git a/pkg/compute/models/initdb.go b/pkg/compute/models/initdb.go index af51d9f58c..693031881c 100644 --- a/pkg/compute/models/initdb.go +++ b/pkg/compute/models/initdb.go @@ -22,6 +22,10 @@ func InitDB() error { NetworkManager, LoadbalancerCertificateManager, LoadbalancerManager, + LoadbalancerListenerManager, + LoadbalancerListenerRuleManager, + LoadbalancerBackendGroupManager, + LoadbalancerBackendManager, } { err := manager.InitializeData() if err != nil { diff --git a/pkg/compute/models/loadbalancer_const.go b/pkg/compute/models/loadbalancer_const.go index 4fa0f50a41..5708efd8af 100644 --- a/pkg/compute/models/loadbalancer_const.go +++ b/pkg/compute/models/loadbalancer_const.go @@ -28,11 +28,14 @@ const ( LB_STATUS_INIT = "init" - LB_STATUS_CREATING = "creating" - LB_STATUS_CREATE_FAILED = "create_failed" + LB_CREATING = "creating" + LB_CREATE_FAILED = "create_failed" - LB_STATUS_SYNCING = "syncing" - LB_STATUS_SYNCING_FAILED = "syncing_failed" + LB_SYNC_CONF = "sync_conf" + LB_SYNC_CONF_FAILED = "sync_conf_failed" + + LB_SYNC_STATUS = "sync_status" + LB_SYNC_STATUS_FAILED = "sync_status_failed" LB_STATUS_DELETING = "deleting" LB_STATUS_DELETE_FAILED = "delete_failed" @@ -46,7 +49,6 @@ const ( LB_STATUS_STOPPING = "stopping" LB_STATUS_DELETE_PENDING = "delete_pending" LB_STATUS_ERROR = "error" // bad things happen - ) var LB_STATUS_SPEC = validators.NewChoices( diff --git a/pkg/compute/models/loadbalanceracls.go b/pkg/compute/models/loadbalanceracls.go index efffc6e753..f5fb851226 100644 --- a/pkg/compute/models/loadbalanceracls.go +++ b/pkg/compute/models/loadbalanceracls.go @@ -160,7 +160,7 @@ func (lbacl *SLoadbalancerAcl) ValidateUpdateData(ctx context.Context, userCred func (lbacl *SLoadbalancerAcl) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) { lbacl.SSharableVirtualResourceBase.PostUpdate(ctx, userCred, query, data) - lbacl.SetStatus(userCred, LB_STATUS_SYNCING, "") + lbacl.SetStatus(userCred, LB_SYNC_CONF, "") lbacl.StartLoadBalancerAclSyncTask(ctx, userCred, "") } @@ -176,7 +176,7 @@ func (lbacl *SLoadbalancerAcl) StartLoadBalancerAclSyncTask(ctx context.Context, func (lbacl *SLoadbalancerAcl) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) { lbacl.SSharableVirtualResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data) - lbacl.SetStatus(userCred, LB_STATUS_CREATING, "") + lbacl.SetStatus(userCred, LB_CREATING, "") if err := lbacl.StartLoadBalancerAclCreateTask(ctx, userCred, ""); err != nil { log.Errorf("Failed to create loadbalanceracl error: %v", err) } diff --git a/pkg/compute/models/loadbalancerbackendgroups.go b/pkg/compute/models/loadbalancerbackendgroups.go index e719202b11..a9006de62a 100644 --- a/pkg/compute/models/loadbalancerbackendgroups.go +++ b/pkg/compute/models/loadbalancerbackendgroups.go @@ -40,7 +40,9 @@ func init() { type SLoadbalancerBackendGroup struct { db.SVirtualResourceBase + SManagedResourceBase + CloudregionId string `width:"36" charset:"ascii" nullable:"false" list:"admin" default:"default" create:"optional"` Type string `width:"36" charset:"ascii" nullable:"false" list:"user" default:"normal" create:"optional"` LoadbalancerId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` } @@ -49,7 +51,7 @@ func (man *SLoadbalancerBackendGroupManager) PreDeleteSubs(ctx context.Context, subs := []SLoadbalancerBackendGroup{} db.FetchModelObjects(man, q, &subs) for _, sub := range subs { - sub.PreDelete(ctx, userCred) + sub.DoPendingDelete(ctx, userCred) } } @@ -79,6 +81,8 @@ func (man *SLoadbalancerBackendGroupManager) ValidateCreateData(ctx context.Cont return nil, err } lb := lbV.Model.(*SLoadbalancer) + data.Set("manager_id", jsonutils.NewString(lb.ManagerId)) + data.Set("cloudregion_id", jsonutils.NewString(lb.CloudregionId)) backends := []cloudprovider.SLoadbalancerBackend{} for idx := 0; data.Contains(fmt.Sprintf("backend.%d", idx)); idx++ { _backend, _ := data.GetString(fmt.Sprintf("backend.%d", idx)) @@ -127,13 +131,12 @@ func (man *SLoadbalancerBackendGroupManager) ValidateCreateData(ctx context.Cont if host == nil { return nil, fmt.Errorf("error getting host of guest %s", guest.Name) } - if host.ZoneId != lb.ZoneId { - return nil, fmt.Errorf("zone of host %q (%s) != zone of loadbalancer %q (%s)", - host.Name, host.ZoneId, lb.Name, lb.ZoneId) - } + backend.ZoneId = host.ZoneId + backend.HostName = host.Name backend.ID = guest.Id backend.Name = guest.Name backend.ExternalID = guest.ExternalId + address, err := LoadbalancerBackendManager.GetGuestAddress(guest) if err != nil { return nil, err @@ -161,7 +164,7 @@ func (man *SLoadbalancerBackendGroupManager) ValidateCreateData(ctx context.Cont backends = append(backends, backend) } data.Set("backends", jsonutils.Marshal(backends)) - return lb.GetRegion().GetDriver().ValidateCreateLoadbalancerBackendGroupData(ctx, userCred, data, backends) + return lb.GetRegion().GetDriver().ValidateCreateLoadbalancerBackendGroupData(ctx, userCred, data, lb, backends) } func (lbbg *SLoadbalancerBackendGroup) GetLoadbalancer() *SLoadbalancer { @@ -239,7 +242,7 @@ func (lbbg *SLoadbalancerBackendGroup) PostCreate(ctx context.Context, userCred if backends != nil { params.Add(backends, "backends") } - lbbg.SetStatus(userCred, LB_STATUS_CREATING, "") + lbbg.SetStatus(userCred, LB_CREATING, "") if err := lbbg.StartLoadBalancerBackendGroupCreateTask(ctx, userCred, params, ""); err != nil { log.Errorf("Failed to create loadbalancer backendgroup error: %v", err) } @@ -425,7 +428,7 @@ func (man *SLoadbalancerBackendGroupManager) newFromCloudLoadbalancerBackendgrou return lbbg, nil } -func (man *SLoadbalancerBackendGroupManager) InitializeData() error { +func (man *SLoadbalancerBackendGroupManager) initBackendGroupType() error { backendgroups := []SLoadbalancerBackendGroup{} q := man.Query() q = q.Filter(sqlchemy.IsNullOrEmpty(q.Field("type"))) @@ -444,3 +447,33 @@ func (man *SLoadbalancerBackendGroupManager) InitializeData() error { } return nil } + +func (man *SLoadbalancerBackendGroupManager) InitializeData() error { + if err := man.initBackendGroupType(); err != nil { + return err + } + return man.initBackendGroupRegion() +} + +func (manager *SLoadbalancerBackendGroupManager) initBackendGroupRegion() error { + groups := []SLoadbalancerBackendGroup{} + q := manager.Query() + q = q.Filter(sqlchemy.IsNotEmpty(q.Field("cloudregion_id"))) + if err := db.FetchModelObjects(manager, q, &groups); err != nil { + return err + } + for i := 0; i < len(groups); i++ { + group := &groups[i] + if lb := group.GetLoadbalancer(); lb != nil && len(lb.CloudregionId) > 0 { + _, err := group.GetModelManager().TableSpec().Update(group, func() error { + group.CloudregionId = lb.CloudregionId + group.ManagerId = lb.ManagerId + return nil + }) + if err != nil { + log.Errorf("failed to update loadbalancer backendgroup %s cloudregion_id", group.Name) + } + } + } + return nil +} diff --git a/pkg/compute/models/loadbalancerbackends.go b/pkg/compute/models/loadbalancerbackends.go index 7742017abf..2ea482c1d8 100644 --- a/pkg/compute/models/loadbalancerbackends.go +++ b/pkg/compute/models/loadbalancerbackends.go @@ -35,7 +35,9 @@ func init() { type SLoadbalancerBackend struct { db.SVirtualResourceBase + SManagedResourceBase + CloudregionId string `width:"36" charset:"ascii" nullable:"false" list:"admin" default:"default" create:"optional"` BackendGroupId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` BackendId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` BackendType string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` @@ -49,7 +51,7 @@ func (man *SLoadbalancerBackendManager) PreDeleteSubs(ctx context.Context, userC subs := []SLoadbalancerBackend{} db.FetchModelObjects(man, q, &subs) for _, sub := range subs { - sub.PreDelete(ctx, userCred) + sub.DoPendingDelete(ctx, userCred) } } @@ -86,6 +88,8 @@ func (man *SLoadbalancerBackendManager) ValidateCreateData(ctx context.Context, } backendGroup := backendGroupV.Model.(*SLoadbalancerBackendGroup) lb := backendGroup.GetLoadbalancer() + data.Set("manager_id", jsonutils.NewString(lb.ManagerId)) + data.Set("cloudregion_id", jsonutils.NewString(lb.CloudregionId)) backendType := backendTypeV.Value var baseName string var backendV *validators.ValidatorModelIdOrName @@ -195,7 +199,7 @@ func (lbb *SLoadbalancerBackend) ValidateUpdateData(ctx context.Context, userCre func (lbb *SLoadbalancerBackend) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) { lbb.SVirtualResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data) - lbb.SetStatus(userCred, LB_STATUS_CREATING, "") + lbb.SetStatus(userCred, LB_CREATING, "") if err := lbb.StartLoadBalancerBackendCreateTask(ctx, userCred, ""); err != nil { log.Errorf("Failed to create loadbalancer backend error: %v", err) } @@ -367,3 +371,26 @@ func (man *SLoadbalancerBackendManager) newFromCloudLoadbalancerBackend(ctx cont } return lbb, man.TableSpec().Insert(lbb) } + +func (manager *SLoadbalancerBackendManager) InitializeData() error { + backends := []SLoadbalancerBackend{} + q := manager.Query() + q = q.Filter(sqlchemy.IsNotEmpty(q.Field("cloudregion_id"))) + if err := db.FetchModelObjects(manager, q, &backends); err != nil { + return err + } + for i := 0; i < len(backends); i++ { + backend := &backends[i] + if group := backend.GetLoadbalancerBackendGroup(); group != nil && len(group.CloudregionId) > 0 { + _, err := backend.GetModelManager().TableSpec().Update(backend, func() error { + backend.CloudregionId = group.CloudregionId + backend.ManagerId = group.ManagerId + return nil + }) + if err != nil { + log.Errorf("failed to update loadbalancer backend %s cloudregion_id", group.Name) + } + } + } + return nil +} diff --git a/pkg/compute/models/loadbalancercertificates.go b/pkg/compute/models/loadbalancercertificates.go index 8bf3e1f73f..9a36d6cc66 100644 --- a/pkg/compute/models/loadbalancercertificates.go +++ b/pkg/compute/models/loadbalancercertificates.go @@ -69,7 +69,7 @@ func (man *SLoadbalancerCertificateManager) PreDeleteSubs(ctx context.Context, u subs := []SLoadbalancerCertificate{} db.FetchModelObjects(man, q, &subs) for _, sub := range subs { - sub.PreDelete(ctx, userCred) + sub.DoPendingDelete(ctx, userCred) } } @@ -207,7 +207,7 @@ func (lbcert *SLoadbalancerCertificate) ValidateUpdateData(ctx context.Context, func (lbcert *SLoadbalancerCertificate) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) { lbcert.SVirtualResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data) - lbcert.SetStatus(userCred, LB_STATUS_CREATING, "") + lbcert.SetStatus(userCred, LB_CREATING, "") if err := lbcert.StartLoadBalancerCertificateCreateTask(ctx, userCred, ""); err != nil { log.Errorf("Failed to create loadbalancercertificate error: %v", err) } diff --git a/pkg/compute/models/loadbalancerlistenerrules.go b/pkg/compute/models/loadbalancerlistenerrules.go index 9fa90ac0af..d5dc51491b 100644 --- a/pkg/compute/models/loadbalancerlistenerrules.go +++ b/pkg/compute/models/loadbalancerlistenerrules.go @@ -36,7 +36,9 @@ func init() { type SLoadbalancerListenerRule struct { db.SVirtualResourceBase + SManagedResourceBase + CloudregionId string `width:"36" charset:"ascii" nullable:"false" list:"admin" default:"default" create:"optional"` ListenerId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` BackendGroupId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional" update:"user"` @@ -64,7 +66,7 @@ func (man *SLoadbalancerListenerRuleManager) PreDeleteSubs(ctx context.Context, subs := []SLoadbalancerListenerRule{} db.FetchModelObjects(man, q, &subs) for _, sub := range subs { - sub.PreDelete(ctx, userCred) + sub.DoPendingDelete(ctx, userCred) } } @@ -107,6 +109,8 @@ func (man *SLoadbalancerListenerRuleManager) ValidateCreateData(ctx context.Cont } } listener := listenerV.Model.(*SLoadbalancerListener) + data.Set("cloudregion_id", jsonutils.NewString(listener.CloudregionId)) + data.Set("manager_id", jsonutils.NewString(listener.ManagerId)) listenerType := listener.ListenerType if listenerType != LB_LISTENER_TYPE_HTTP && listenerType != LB_LISTENER_TYPE_HTTPS { return nil, fmt.Errorf("listener type must be http/https, got %s", listenerType) @@ -130,7 +134,7 @@ func (man *SLoadbalancerListenerRuleManager) ValidateCreateData(ctx context.Cont func (lbr *SLoadbalancerListenerRule) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) { lbr.SVirtualResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data) - lbr.SetStatus(userCred, LB_STATUS_CREATING, "") + lbr.SetStatus(userCred, LB_CREATING, "") if err := lbr.StartLoadBalancerListenerRuleCreateTask(ctx, userCred, ""); err != nil { log.Errorf("Failed to create loadbalancer listener rule error: %v", err) } @@ -357,3 +361,26 @@ func (lbr *SLoadbalancerListenerRule) SyncWithCloudLoadbalancerListenerRule(ctx }) return err } + +func (manager *SLoadbalancerListenerRuleManager) InitializeData() error { + rules := []SLoadbalancerListenerRule{} + q := manager.Query() + q = q.Filter(sqlchemy.IsNotEmpty(q.Field("cloudregion_id"))) + if err := db.FetchModelObjects(manager, q, &rules); err != nil { + return err + } + for i := 0; i < len(rules); i++ { + rule := &rules[i] + if listener := rule.GetLoadbalancerListener(); listener != nil && len(listener.CloudregionId) > 0 { + _, err := listener.GetModelManager().TableSpec().Update(rule, func() error { + rule.CloudregionId = listener.CloudregionId + rule.ManagerId = listener.ManagerId + return nil + }) + if err != nil { + log.Errorf("failed to update loadbalancer listener rule %s cloudregion_id", rule.Name) + } + } + } + return nil +} diff --git a/pkg/compute/models/loadbalancerlisteners.go b/pkg/compute/models/loadbalancerlisteners.go index 9f06589a04..80988883f6 100644 --- a/pkg/compute/models/loadbalancerlisteners.go +++ b/pkg/compute/models/loadbalancerlisteners.go @@ -8,6 +8,7 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/pkg/util/compare" + "yunion.io/x/pkg/utils" "yunion.io/x/sqlchemy" "yunion.io/x/onecloud/pkg/cloudcommon/db" @@ -137,7 +138,7 @@ func (man *SLoadbalancerListenerManager) PreDeleteSubs(ctx context.Context, user subs := []SLoadbalancerListener{} db.FetchModelObjects(man, q, &subs) for _, sub := range subs { - sub.PreDelete(ctx, userCred) + sub.DoPendingDelete(ctx, userCred) } } @@ -336,11 +337,15 @@ func (lblis *SLoadbalancerListener) AllowPerformSyncstatus(ctx context.Context, } func (lblis *SLoadbalancerListener) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { - return nil, lblis.StartLoadBalancerListenerSyncstatusTask(ctx, userCred, "") + params := jsonutils.NewDict() + if utils.IsInStringArray(lblis.Status, []string{LB_STATUS_ENABLED, LB_STATUS_DISABLED}) { + params.Add(jsonutils.NewString(lblis.Status), "origin_status") + } + return nil, lblis.StartLoadBalancerListenerSyncstatusTask(ctx, userCred, params, "") } -func (lblis *SLoadbalancerListener) StartLoadBalancerListenerSyncstatusTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { - task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerListenerSyncstatusTask", lblis, userCred, nil, parentTaskId, "", nil) +func (lblis *SLoadbalancerListener) StartLoadBalancerListenerSyncstatusTask(ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerListenerSyncstatusTask", lblis, userCred, params, parentTaskId, "", nil) if err != nil { return err } @@ -417,7 +422,29 @@ func (lblis *SLoadbalancerListener) ValidateUpdateData(ctx context.Context, user backendGroup.Name, backendGroup.Id, backendGroup.LoadbalancerId, lblis.LoadbalancerId) } } - return lblis.SVirtualResourceBase.ValidateUpdateData(ctx, userCred, query, data) + if _, err := lblis.SVirtualResourceBase.ValidateUpdateData(ctx, userCred, query, data); err != nil { + return nil, err + } + return lblis.GetRegion().GetDriver().ValidateUpdateLoadbalancerListenerData(ctx, userCred, data, backendGroupV.Model) +} + +func (lblis *SLoadbalancerListener) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) { + lblis.SVirtualResourceBase.PostUpdate(ctx, userCred, query, data) + lblis.StartLoadBalancerListenerSyncTask(ctx, userCred, "") +} + +func (lblis *SLoadbalancerListener) StartLoadBalancerListenerSyncTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { + params := jsonutils.NewDict() + if utils.IsInStringArray(lblis.Status, []string{LB_STATUS_ENABLED, LB_STATUS_DISABLED}) { + params.Add(jsonutils.NewString(lblis.Status), "origin_status") + } + lblis.SetStatus(userCred, LB_SYNC_CONF, "") + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerListenerSyncTask", lblis, userCred, params, parentTaskId, "", nil) + if err != nil { + return err + } + task.ScheduleRun(nil) + return nil } func (lblis *SLoadbalancerListener) GetCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict { @@ -454,7 +481,7 @@ func (lblis *SLoadbalancerListener) GetExtraDetails(ctx context.Context, userCre func (lblis *SLoadbalancerListener) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) { lblis.SVirtualResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data) - lblis.SetStatus(userCred, LB_STATUS_CREATING, "") + lblis.SetStatus(userCred, LB_CREATING, "") if err := lblis.StartLoadBalancerListenerCreateTask(ctx, userCred, ""); err != nil { log.Errorf("Failed to create loadbalancer listener error: %v", err) } @@ -479,6 +506,14 @@ func (lblis *SLoadbalancerListener) PerformPurge(ctx context.Context, userCred m return nil, lblis.StartLoadBalancerListenerDeleteTask(ctx, userCred, parasm, "") } +func (lblis *SLoadbalancerListener) AllowPerformSync(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { + return db.IsAdminAllowPerform(userCred, lblis, "sync") +} + +func (lblis *SLoadbalancerListener) PerformSync(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { + return nil, lblis.StartLoadBalancerListenerSyncTask(ctx, userCred, "") +} + func (lblis *SLoadbalancerListener) StartLoadBalancerListenerDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error { task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerListenerDeleteTask", lblis, userCred, params, parentTaskId, "", nil) if err != nil { @@ -508,7 +543,7 @@ func (lblis *SLoadbalancerListener) Delete(ctx context.Context, userCred mcclien return nil } -func (lblis *SLoadbalancerListener) GetLoadbalancerListenerCreateParams() (*cloudprovider.SLoadbalancerListener, error) { +func (lblis *SLoadbalancerListener) GetLoadbalancerListenerParams() (*cloudprovider.SLoadbalancerListener, error) { listener := &cloudprovider.SLoadbalancerListener{ Name: lblis.Name, Description: lblis.Description, @@ -747,3 +782,26 @@ func (man *SLoadbalancerListenerManager) newFromCloudLoadbalancerListener(ctx co } return lblis, man.TableSpec().Insert(lblis) } + +func (manager *SLoadbalancerListenerManager) InitializeData() error { + listeners := []SLoadbalancerListener{} + q := manager.Query() + q = q.Filter(sqlchemy.IsNotEmpty(q.Field("cloudregion_id"))) + if err := db.FetchModelObjects(manager, q, &listeners); err != nil { + return err + } + for i := 0; i < len(listeners); i++ { + listener := &listeners[i] + if lb := listener.GetLoadbalancer(); lb != nil && len(lb.CloudregionId) > 0 { + _, err := listener.GetModelManager().TableSpec().Update(listener, func() error { + listener.CloudregionId = lb.CloudregionId + listener.ManagerId = lb.ManagerId + return nil + }) + if err != nil { + log.Errorf("failed to update loadbalancer listener %s cloudregion_id", listener.Name) + } + } + } + return nil +} diff --git a/pkg/compute/models/loadbalancers.go b/pkg/compute/models/loadbalancers.go index 60f47922ce..29571bff5c 100644 --- a/pkg/compute/models/loadbalancers.go +++ b/pkg/compute/models/loadbalancers.go @@ -223,7 +223,10 @@ func (lb *SLoadbalancer) PerformSyncstatus(ctx context.Context, userCred mcclien } func (lb *SLoadbalancer) StartLoadBalancerSyncstatusTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { - task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerSyncstatusTask", lb, userCred, nil, parentTaskId, "", nil) + params := jsonutils.NewDict() + params.Add(jsonutils.NewString(lb.Status), "origin_status") + lb.SetStatus(userCred, LB_SYNC_STATUS, "") + task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerSyncstatusTask", lb, userCred, params, parentTaskId, "", nil) if err != nil { return err } @@ -237,7 +240,7 @@ func (lb *SLoadbalancer) PostCreate(ctx context.Context, userCred mcclient.Token // NOTE this means lb.UpdateVersion will be 0, then 1 after creation // NOTE need ways to notify error - lb.SetStatus(userCred, LB_STATUS_CREATING, "") + lb.SetStatus(userCred, LB_CREATING, "") if err := lb.StartLoadBalancerCreateTask(ctx, userCred, ""); err != nil { log.Errorf("Failed to create loadbalancer error: %v", err) } diff --git a/pkg/compute/models/regiondrivers.go b/pkg/compute/models/regiondrivers.go index bdfd40b638..63d45408d4 100644 --- a/pkg/compute/models/regiondrivers.go +++ b/pkg/compute/models/regiondrivers.go @@ -31,7 +31,7 @@ type IRegionDriver interface { RequestCreateLoadbalancerCertificate(ctx context.Context, userCred mcclient.TokenCredential, lbcert *SLoadbalancerCertificate, task taskman.ITask) error RequestDeleteLoadbalancerCertificate(ctx context.Context, userCred mcclient.TokenCredential, lbcert *SLoadbalancerCertificate, task taskman.ITask) error - ValidateCreateLoadbalancerBackendGroupData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backends []cloudprovider.SLoadbalancerBackend) (*jsonutils.JSONDict, error) + ValidateCreateLoadbalancerBackendGroupData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, lb *SLoadbalancer, backends []cloudprovider.SLoadbalancerBackend) (*jsonutils.JSONDict, error) 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 @@ -42,11 +42,13 @@ type IRegionDriver interface { ValidateDeleteLoadbalancerBackendCondition(ctx context.Context, lbb *SLoadbalancerBackend) error ValidateCreateLoadbalancerListenerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backendGroup db.IModel) (*jsonutils.JSONDict, error) + ValidateUpdateLoadbalancerListenerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backendGroup db.IModel) (*jsonutils.JSONDict, error) RequestCreateLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *SLoadbalancerListener, task taskman.ITask) error RequestDeleteLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *SLoadbalancerListener, task taskman.ITask) error RequestStartLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *SLoadbalancerListener, task taskman.ITask) error RequestStopLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *SLoadbalancerListener, task taskman.ITask) error RequestSyncstatusLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *SLoadbalancerListener, task taskman.ITask) error + RequestSyncLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *SLoadbalancerListener, task taskman.ITask) error ValidateCreateLoadbalancerListenerRuleData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backendGroup db.IModel) (*jsonutils.JSONDict, error) RequestCreateLoadbalancerListenerRule(ctx context.Context, userCred mcclient.TokenCredential, lbr *SLoadbalancerListenerRule, task taskman.ITask) error diff --git a/pkg/compute/regiondrivers/aliyun.go b/pkg/compute/regiondrivers/aliyun.go index 284d35b919..6394aa70e4 100644 --- a/pkg/compute/regiondrivers/aliyun.go +++ b/pkg/compute/regiondrivers/aliyun.go @@ -6,6 +6,7 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/validators" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/onecloud/pkg/httperrors" @@ -44,7 +45,7 @@ func (self *SAliyunRegionDriver) ValidateUpdateLoadbalancerCertificateData(ctx c func (self *SAliyunRegionDriver) ValidateDeleteLoadbalancerBackendCondition(ctx context.Context, lbb *models.SLoadbalancerBackend) error { backendGroup := lbb.GetLoadbalancerBackendGroup() if backendGroup.Type == models.LB_BACKENDGROUP_TYPE_MASTER_SLAVE { - return httperrors.NewUnsupportOperationError("backend %s belong master slave backendgroup, not allow delete") + return httperrors.NewUnsupportOperationError("backend %s belong master slave backendgroup, not allow delete", lbb.Name) } return nil } @@ -56,7 +57,7 @@ func (self *SAliyunRegionDriver) ValidateDeleteLoadbalancerBackendGroupCondition return nil } -func (self *SAliyunRegionDriver) ValidateCreateLoadbalancerBackendGroupData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backends []cloudprovider.SLoadbalancerBackend) (*jsonutils.JSONDict, error) { +func (self *SAliyunRegionDriver) ValidateCreateLoadbalancerBackendGroupData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, lb *models.SLoadbalancer, backends []cloudprovider.SLoadbalancerBackend) (*jsonutils.JSONDict, error) { groupType, _ := data.GetString("type") switch groupType { case "", models.LB_BACKENDGROUP_TYPE_NORMAL: @@ -128,13 +129,45 @@ func (self *SAliyunRegionDriver) ValidateCreateLoadbalancerListenerData(ctx cont if !ok { return nil, httperrors.NewMissingParameterError("backend_group") } - if !utils.IsInStringArray(backendgroup.Type, []string{models.LB_BACKENDGROUP_TYPE_MASTER_SLAVE, models.LB_BACKENDGROUP_TYPE_NORMAL}) { - return nil, httperrors.NewUnsupportOperationError("backend group type %s not support this operation", backendgroup.Type) + listenerType, _ := data.GetString("listener_type") + if utils.IsInStringArray(listenerType, []string{models.LB_LISTENER_TYPE_UDP, models.LB_LISTENER_TYPE_TCP}) && !utils.IsInStringArray(backendgroup.Type, []string{models.LB_BACKENDGROUP_TYPE_MASTER_SLAVE, models.LB_BACKENDGROUP_TYPE_NORMAL}) { + return nil, httperrors.NewUnsupportOperationError("udp or tcp listener only support normal or master_slave backendgroup") + } + if utils.IsInStringArray(listenerType, []string{models.LB_LISTENER_TYPE_HTTP, models.LB_LISTENER_TYPE_HTTPS}) && backendgroup.Type != models.LB_BACKENDGROUP_TYPE_NORMAL { + return nil, httperrors.NewUnsupportOperationError("http or https listener only support normal or master_slave backendgroup") } lb := backendgroup.GetLoadbalancer() - tlsCipherPolicy, _ := data.GetString("tls_cipher_policy") - if len(tlsCipherPolicy) > 0 && len(lb.LoadbalancerSpec) == 0 { + if tlsCipherPolicy, _ := data.GetString("tls_cipher_policy"); len(tlsCipherPolicy) > 0 && len(lb.LoadbalancerSpec) == 0 { data.Set("tls_cipher_policy", jsonutils.NewString("")) } + if healthCheckDomain, _ := data.GetString("health_check_domain"); len(healthCheckDomain) > 80 { + return nil, httperrors.NewInputParameterError("health_check_domain must be in the range of 1 ~ 80") + } + + keyV := map[string]validators.IValidator{ + "bandwidth": validators.NewRangeValidator("bandwidth", 1, 5000), + + "client_request_timeout": validators.NewRangeValidator("client_request_timeout", 1, 180), + + "sticky_session_cookie_timeout": validators.NewRangeValidator("sticky_session_cookie_timeout", 1, 86400), + + "health_check_rise": validators.NewRangeValidator("health_check_rise", 2, 10), + "health_check_fall": validators.NewRangeValidator("health_check_fall", 2, 10), + "health_check_timeout": validators.NewRangeValidator("health_check_timeout", 1, 300), + "health_check_interval": validators.NewRangeValidator("health_check_interval", 1, 50), + } + if !utils.IsInStringArray(listenerType, []string{models.LB_LISTENER_TYPE_UDP, models.LB_LISTENER_TYPE_TCP}) { + keyV["client_idle_timeout"] = validators.NewRangeValidator("client_idle_timeout", 1, 60) + } + for _, v := range keyV { + v.Optional(true) + if err := v.Validate(data); err != nil { + return nil, err + } + } return data, nil } + +func (self *SAliyunRegionDriver) ValidateUpdateLoadbalancerListenerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backendGroup db.IModel) (*jsonutils.JSONDict, error) { + return self.ValidateCreateLoadbalancerListenerData(ctx, userCred, data, backendGroup) +} diff --git a/pkg/compute/regiondrivers/base.go b/pkg/compute/regiondrivers/base.go index 57e80379b5..31f299cf06 100644 --- a/pkg/compute/regiondrivers/base.go +++ b/pkg/compute/regiondrivers/base.go @@ -89,6 +89,10 @@ func (self *SBaseRegionDriver) RequestSyncstatusLoadbalancerListener(ctx context return fmt.Errorf("Not Implement RequestSyncstatusLoadbalancerListener") } +func (self *SBaseRegionDriver) RequestSyncLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { + return fmt.Errorf("Not Implement RequestSyncLoadbalancerListener") +} + func (self *SBaseRegionDriver) RequestCreateLoadbalancerListenerRule(ctx context.Context, userCred mcclient.TokenCredential, lbr *models.SLoadbalancerListenerRule, task taskman.ITask) error { return fmt.Errorf("Not Implement RequestCreateLoadbalancerListenerRule") } diff --git a/pkg/compute/regiondrivers/kvm.go b/pkg/compute/regiondrivers/kvm.go index 6a8385fbba..47882154e2 100644 --- a/pkg/compute/regiondrivers/kvm.go +++ b/pkg/compute/regiondrivers/kvm.go @@ -11,6 +11,7 @@ import ( "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/pkg/utils" ) type SKVMRegionDriver struct { @@ -42,7 +43,16 @@ func (self *SKVMRegionDriver) ValidateUpdateLoadbalancerCertificateData(ctx cont return data, nil } -func (self *SKVMRegionDriver) ValidateCreateLoadbalancerBackendGroupData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backends []cloudprovider.SLoadbalancerBackend) (*jsonutils.JSONDict, error) { +func (self *SKVMRegionDriver) ValidateCreateLoadbalancerBackendGroupData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, lb *models.SLoadbalancer, backends []cloudprovider.SLoadbalancerBackend) (*jsonutils.JSONDict, error) { + for _, backend := range backends { + switch backend.BackendType { + case models.LB_BACKEND_GUEST: + if backend.ZoneId != lb.ZoneId { + return nil, fmt.Errorf("zone of host %q (%s) != zone of loadbalancer %q (%s)", + backend.HostName, backend.ZoneId, lb.Name, lb.ZoneId) + } + } + } return data, nil } @@ -87,6 +97,10 @@ func (self *SKVMRegionDriver) ValidateCreateLoadbalancerListenerData(ctx context return data, nil } +func (self *SKVMRegionDriver) ValidateUpdateLoadbalancerListenerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backendGroup db.IModel) (*jsonutils.JSONDict, error) { + return data, nil +} + func (self *SKVMRegionDriver) RequestCreateLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { _, err := models.LoadbalancerManager.TableSpec().Update(lb, func() error { @@ -125,6 +139,12 @@ func (self *SKVMRegionDriver) RequestStopLoadbalancer(ctx context.Context, userC } func (self *SKVMRegionDriver) RequestSyncstatusLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error { + originStatus, _ := task.GetParams().GetString("origin_status") + if utils.IsInStringArray(originStatus, []string{models.LB_STATUS_ENABLED, models.LB_STATUS_DISABLED}) { + lb.SetStatus(userCred, originStatus, "") + } else { + lb.SetStatus(userCred, models.LB_STATUS_ENABLED, "") + } task.ScheduleRun(nil) return nil } @@ -227,6 +247,17 @@ func (self *SKVMRegionDriver) RequestStopLoadbalancerListener(ctx context.Contex } func (self *SKVMRegionDriver) RequestSyncstatusLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { + originStatus, _ := task.GetParams().GetString("origin_status") + if utils.IsInStringArray(originStatus, []string{models.LB_STATUS_ENABLED, models.LB_STATUS_DISABLED}) { + lblis.SetStatus(userCred, originStatus, "") + } else { + lblis.SetStatus(userCred, models.LB_STATUS_ENABLED, "") + } + task.ScheduleRun(nil) + return nil +} + +func (self *SKVMRegionDriver) RequestSyncLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { task.ScheduleRun(nil) return nil } diff --git a/pkg/compute/regiondrivers/managedvirtual.go b/pkg/compute/regiondrivers/managedvirtual.go index 457a026feb..d6a0f351af 100644 --- a/pkg/compute/regiondrivers/managedvirtual.go +++ b/pkg/compute/regiondrivers/managedvirtual.go @@ -78,7 +78,7 @@ func (self *SManagedVirtualizationRegionDriver) ValidateCreateLoadbalancerBacken return data, nil } -func (self *SManagedVirtualizationRegionDriver) ValidateCreateLoadbalancerBackendGroupData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backends []cloudprovider.SLoadbalancerBackend) (*jsonutils.JSONDict, error) { +func (self *SManagedVirtualizationRegionDriver) ValidateCreateLoadbalancerBackendGroupData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, lb *models.SLoadbalancer, backends []cloudprovider.SLoadbalancerBackend) (*jsonutils.JSONDict, error) { for _, backend := range backends { if len(backend.ExternalID) == 0 { return nil, httperrors.NewInputParameterError("invalid guest %s", backend.Name) @@ -95,6 +95,10 @@ func (self *SManagedVirtualizationRegionDriver) ValidateCreateLoadbalancerListen return data, nil } +func (self *SManagedVirtualizationRegionDriver) ValidateUpdateLoadbalancerListenerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backendGroup db.IModel) (*jsonutils.JSONDict, error) { + return data, nil +} + func (self *SManagedVirtualizationRegionDriver) ValidateDeleteLoadbalancerBackendCondition(ctx context.Context, lbb *models.SLoadbalancerBackend) error { return nil } @@ -478,7 +482,7 @@ func (self *SManagedVirtualizationRegionDriver) RequestDeleteLoadbalancerBackend func (self *SManagedVirtualizationRegionDriver) RequestCreateLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { - params, err := lblis.GetLoadbalancerListenerCreateParams() + params, err := lblis.GetLoadbalancerListenerParams() if err != nil { return nil, err } @@ -558,6 +562,39 @@ func (self *SManagedVirtualizationRegionDriver) RequestStartLoadbalancerListener return nil } +func (self *SManagedVirtualizationRegionDriver) RequestSyncLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + params, err := lblis.GetLoadbalancerListenerParams() + if err != nil { + return nil, err + } + loadbalancer := lblis.GetLoadbalancer() + if loadbalancer == nil { + return nil, fmt.Errorf("failed to find loadbalancer for lblis %s", lblis.Name) + } + iRegion, err := loadbalancer.GetIRegion() + if err != nil { + return nil, err + } + iLoadbalancer, err := iRegion.GetILoadBalancerById(loadbalancer.ExternalId) + if err != nil { + return nil, err + } + iListener, err := iLoadbalancer.GetILoadBalancerListenerById(lblis.ExternalId) + if err != nil { + return nil, err + } + if err := iListener.Sync(params); err != nil { + return nil, err + } + if err := iListener.Refresh(); err != nil { + return nil, err + } + return nil, lblis.SyncWithCloudLoadbalancerListener(ctx, userCred, loadbalancer, iListener, "", false) + }) + return nil +} + func (self *SManagedVirtualizationRegionDriver) RequestStopLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error { taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { loadbalancer := lblis.GetLoadbalancer() diff --git a/pkg/compute/tasks/loadbalancer_acl_create_task.go b/pkg/compute/tasks/loadbalancer_acl_create_task.go index 4a5f576d5c..53deb86a8b 100644 --- a/pkg/compute/tasks/loadbalancer_acl_create_task.go +++ b/pkg/compute/tasks/loadbalancer_acl_create_task.go @@ -8,7 +8,9 @@ import ( "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 LoadbalancerAclCreateTask struct { @@ -20,7 +22,10 @@ func init() { } func (self *LoadbalancerAclCreateTask) taskFail(ctx context.Context, lbacl *models.SLoadbalancerAcl, reason string) { - lbacl.SetStatus(self.GetUserCred(), models.LB_STATUS_CREATE_FAILED, reason) + lbacl.SetStatus(self.GetUserCred(), models.LB_CREATE_FAILED, reason) + db.OpsLog.LogEvent(lbacl, db.ACT_ALLOCATE_FAIL, reason, self.UserCred) + logclient.AddActionLog(lbacl, logclient.ACT_CREATE, reason, self.UserCred, false) + notifyclient.NotifySystemError(lbacl.Id, lbacl.Name, models.LB_CREATE_FAILED, reason) self.SetStageFailed(ctx, reason) } @@ -39,6 +44,8 @@ func (self *LoadbalancerAclCreateTask) OnInit(ctx context.Context, obj db.IStand func (self *LoadbalancerAclCreateTask) OnLoadbalancerAclCreateComplete(ctx context.Context, lbacl *models.SLoadbalancerAcl, data jsonutils.JSONObject) { lbacl.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") + db.OpsLog.LogEvent(lbacl, db.ACT_ALLOCATE, lbacl.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lbacl, logclient.ACT_CREATE, nil, self.UserCred, true) self.SetStageComplete(ctx, nil) } diff --git a/pkg/compute/tasks/loadbalancer_acl_delete_task.go b/pkg/compute/tasks/loadbalancer_acl_delete_task.go index cf4ce12b3d..ab95d23e0b 100644 --- a/pkg/compute/tasks/loadbalancer_acl_delete_task.go +++ b/pkg/compute/tasks/loadbalancer_acl_delete_task.go @@ -8,7 +8,9 @@ import ( "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 LoadbalancerAclDeleteTask struct { @@ -21,6 +23,9 @@ func init() { func (self *LoadbalancerAclDeleteTask) taskFail(ctx context.Context, lbacl *models.SLoadbalancerAcl, reason string) { lbacl.SetStatus(self.GetUserCred(), models.LB_STATUS_DELETE_FAILED, reason) + db.OpsLog.LogEvent(lbacl, db.ACT_DELOCATE_FAIL, reason, self.UserCred) + logclient.AddActionLog(lbacl, logclient.ACT_DELETE, reason, self.UserCred, false) + notifyclient.NotifySystemError(lbacl.Id, lbacl.Name, models.LB_STATUS_DELETE_FAILED, reason) self.SetStageFailed(ctx, reason) } @@ -38,6 +43,8 @@ func (self *LoadbalancerAclDeleteTask) OnInit(ctx context.Context, obj db.IStand } func (self *LoadbalancerAclDeleteTask) OnLoadbalancerAclDeleteComplete(ctx context.Context, lbacl *models.SLoadbalancerAcl, data jsonutils.JSONObject) { + db.OpsLog.LogEvent(lbacl, db.ACT_DELETE, lbacl.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lbacl, logclient.ACT_DELETE, nil, self.UserCred, true) lbacl.DoPendingDelete(ctx, self.GetUserCred()) self.SetStageComplete(ctx, nil) } diff --git a/pkg/compute/tasks/loadbalancer_acl_sync_task.go b/pkg/compute/tasks/loadbalancer_acl_sync_task.go index 8c41672f41..50277c984c 100644 --- a/pkg/compute/tasks/loadbalancer_acl_sync_task.go +++ b/pkg/compute/tasks/loadbalancer_acl_sync_task.go @@ -8,7 +8,9 @@ import ( "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 LoadbalancerAclSyncTask struct { @@ -20,7 +22,10 @@ func init() { } func (self *LoadbalancerAclSyncTask) taskFail(ctx context.Context, lbacl *models.SLoadbalancerAcl, reason string) { - lbacl.SetStatus(self.GetUserCred(), models.LB_STATUS_SYNCING_FAILED, reason) + lbacl.SetStatus(self.GetUserCred(), models.LB_SYNC_CONF_FAILED, reason) + db.OpsLog.LogEvent(lbacl, db.ACT_SYNC_CONF, reason, self.UserCred) + logclient.AddActionLog(lbacl, logclient.ACT_SYNC_CONF, reason, self.UserCred, false) + notifyclient.NotifySystemError(lbacl.Id, lbacl.Name, models.LB_SYNC_CONF_FAILED, reason) self.SetStageFailed(ctx, reason) } @@ -39,6 +44,8 @@ func (self *LoadbalancerAclSyncTask) OnInit(ctx context.Context, obj db.IStandal func (self *LoadbalancerAclSyncTask) OnLoadbalancerAclSyncComplete(ctx context.Context, lbacl *models.SLoadbalancerAcl, data jsonutils.JSONObject) { lbacl.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") + db.OpsLog.LogEvent(lbacl, db.ACT_SYNC_CONF, lbacl.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lbacl, logclient.ACT_SYNC_CONF, nil, self.UserCred, true) self.SetStageComplete(ctx, nil) } diff --git a/pkg/compute/tasks/loadbalancer_backend_create_task.go b/pkg/compute/tasks/loadbalancer_backend_create_task.go index ad664ff559..93325910ee 100644 --- a/pkg/compute/tasks/loadbalancer_backend_create_task.go +++ b/pkg/compute/tasks/loadbalancer_backend_create_task.go @@ -8,7 +8,9 @@ import ( "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 LoadbalancerBackendCreateTask struct { @@ -20,7 +22,10 @@ func init() { } func (self *LoadbalancerBackendCreateTask) taskFail(ctx context.Context, lbb *models.SLoadbalancerBackend, reason string) { - lbb.SetStatus(self.GetUserCred(), models.LB_STATUS_CREATE_FAILED, reason) + lbb.SetStatus(self.GetUserCred(), models.LB_CREATE_FAILED, reason) + db.OpsLog.LogEvent(lbb, db.ACT_ALLOCATE_FAIL, reason, self.UserCred) + logclient.AddActionLog(lbb, logclient.ACT_CREATE, reason, self.UserCred, false) + notifyclient.NotifySystemError(lbb.Id, lbb.Name, models.LB_CREATE_FAILED, reason) self.SetStageFailed(ctx, reason) } @@ -39,6 +44,8 @@ func (self *LoadbalancerBackendCreateTask) OnInit(ctx context.Context, obj db.IS func (self *LoadbalancerBackendCreateTask) OnLoadbalancerBackendCreateComplete(ctx context.Context, lbb *models.SLoadbalancerBackend, data jsonutils.JSONObject) { lbb.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") + db.OpsLog.LogEvent(lbb, db.ACT_ALLOCATE, lbb.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lbb, logclient.ACT_CREATE, nil, self.UserCred, true) self.SetStageComplete(ctx, nil) } diff --git a/pkg/compute/tasks/loadbalancer_backendgroup_create_task.go b/pkg/compute/tasks/loadbalancer_backendgroup_create_task.go index af6b814ba3..1c7965c581 100644 --- a/pkg/compute/tasks/loadbalancer_backendgroup_create_task.go +++ b/pkg/compute/tasks/loadbalancer_backendgroup_create_task.go @@ -8,8 +8,10 @@ import ( "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/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/util/logclient" ) type LoadbalancerLoadbalancerBackendGroupCreateTask struct { @@ -21,7 +23,10 @@ func init() { } func (self *LoadbalancerLoadbalancerBackendGroupCreateTask) taskFail(ctx context.Context, lbacl *models.SLoadbalancerBackendGroup, reason string) { - lbacl.SetStatus(self.GetUserCred(), models.LB_STATUS_CREATE_FAILED, reason) + lbacl.SetStatus(self.GetUserCred(), models.LB_CREATE_FAILED, reason) + db.OpsLog.LogEvent(lbacl, db.ACT_ALLOCATE_FAIL, reason, self.UserCred) + logclient.AddActionLog(lbacl, logclient.ACT_CREATE, reason, self.UserCred, false) + notifyclient.NotifySystemError(lbacl.Id, lbacl.Name, models.LB_CREATE_FAILED, reason) self.SetStageFailed(ctx, reason) } @@ -42,6 +47,8 @@ func (self *LoadbalancerLoadbalancerBackendGroupCreateTask) OnInit(ctx context.C func (self *LoadbalancerLoadbalancerBackendGroupCreateTask) OnLoadbalancerBackendGroupCreateComplete(ctx context.Context, lbbg *models.SLoadbalancerBackendGroup, data jsonutils.JSONObject) { lbbg.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") + db.OpsLog.LogEvent(lbbg, db.ACT_ALLOCATE, lbbg.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lbbg, logclient.ACT_CREATE, nil, self.UserCred, true) self.SetStageComplete(ctx, nil) } diff --git a/pkg/compute/tasks/loadbalancer_backendgroup_delete_task.go b/pkg/compute/tasks/loadbalancer_backendgroup_delete_task.go index 2d382a8139..7ecf01d9dd 100644 --- a/pkg/compute/tasks/loadbalancer_backendgroup_delete_task.go +++ b/pkg/compute/tasks/loadbalancer_backendgroup_delete_task.go @@ -8,7 +8,9 @@ import ( "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 LoadbalancerBackendGroupDeleteTask struct { @@ -21,6 +23,9 @@ func init() { func (self *LoadbalancerBackendGroupDeleteTask) taskFail(ctx context.Context, lbbg *models.SLoadbalancerBackendGroup, reason string) { lbbg.SetStatus(self.GetUserCred(), models.LB_STATUS_DELETE_FAILED, reason) + db.OpsLog.LogEvent(lbbg, db.ACT_DELOCATE_FAIL, reason, self.UserCred) + logclient.AddActionLog(lbbg, logclient.ACT_DELETE, reason, self.UserCred, false) + notifyclient.NotifySystemError(lbbg.Id, lbbg.Name, models.LB_STATUS_DELETE_FAILED, reason) self.SetStageFailed(ctx, reason) } @@ -38,6 +43,8 @@ func (self *LoadbalancerBackendGroupDeleteTask) OnInit(ctx context.Context, obj } func (self *LoadbalancerBackendGroupDeleteTask) OnLoadbalancerBackendGroupDeleteComplete(ctx context.Context, lbbg *models.SLoadbalancerBackendGroup, data jsonutils.JSONObject) { + db.OpsLog.LogEvent(lbbg, db.ACT_DELETE, lbbg.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lbbg, logclient.ACT_DELETE, nil, self.UserCred, true) lbbg.PreDeleteSubs(ctx, self.GetUserCred()) self.SetStageComplete(ctx, nil) } diff --git a/pkg/compute/tasks/loadbalancer_certificate_create_task.go b/pkg/compute/tasks/loadbalancer_certificate_create_task.go index be43a9d197..e696db3b46 100644 --- a/pkg/compute/tasks/loadbalancer_certificate_create_task.go +++ b/pkg/compute/tasks/loadbalancer_certificate_create_task.go @@ -8,7 +8,9 @@ import ( "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 LoadbalancerCertificateCreateTask struct { @@ -20,7 +22,10 @@ func init() { } func (self *LoadbalancerCertificateCreateTask) taskFail(ctx context.Context, lbcert *models.SLoadbalancerCertificate, reason string) { - lbcert.SetStatus(self.GetUserCred(), models.LB_STATUS_CREATE_FAILED, reason) + lbcert.SetStatus(self.GetUserCred(), models.LB_CREATE_FAILED, reason) + db.OpsLog.LogEvent(lbcert, db.ACT_ALLOCATE_FAIL, reason, self.UserCred) + logclient.AddActionLog(lbcert, logclient.ACT_CREATE, reason, self.UserCred, false) + notifyclient.NotifySystemError(lbcert.Id, lbcert.Name, models.LB_CREATE_FAILED, reason) self.SetStageFailed(ctx, reason) } @@ -39,6 +44,8 @@ func (self *LoadbalancerCertificateCreateTask) OnInit(ctx context.Context, obj d func (self *LoadbalancerCertificateCreateTask) OnLoadbalancerCertificateCreateComplete(ctx context.Context, lbcert *models.SLoadbalancerCertificate, data jsonutils.JSONObject) { lbcert.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") + db.OpsLog.LogEvent(lbcert, db.ACT_ALLOCATE, lbcert.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lbcert, logclient.ACT_CREATE, nil, self.UserCred, true) self.SetStageComplete(ctx, nil) } diff --git a/pkg/compute/tasks/loadbalancer_certificate_delete_task.go b/pkg/compute/tasks/loadbalancer_certificate_delete_task.go index dc06cec852..1480f483ec 100644 --- a/pkg/compute/tasks/loadbalancer_certificate_delete_task.go +++ b/pkg/compute/tasks/loadbalancer_certificate_delete_task.go @@ -8,7 +8,9 @@ import ( "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 LoadbalancerCertificateDeleteTask struct { @@ -21,6 +23,9 @@ func init() { func (self *LoadbalancerCertificateDeleteTask) taskFail(ctx context.Context, lbcert *models.SLoadbalancerCertificate, reason string) { lbcert.SetStatus(self.GetUserCred(), models.LB_STATUS_DELETE_FAILED, reason) + db.OpsLog.LogEvent(lbcert, db.ACT_DELOCATE_FAIL, reason, self.UserCred) + logclient.AddActionLog(lbcert, logclient.ACT_DELETE, reason, self.UserCred, false) + notifyclient.NotifySystemError(lbcert.Id, lbcert.Name, models.LB_STATUS_DELETE_FAILED, reason) self.SetStageFailed(ctx, reason) } @@ -38,6 +43,8 @@ func (self *LoadbalancerCertificateDeleteTask) OnInit(ctx context.Context, obj d } func (self *LoadbalancerCertificateDeleteTask) OnLoadbalancerCertificateDeleteComplete(ctx context.Context, lbcert *models.SLoadbalancerCertificate, data jsonutils.JSONObject) { + db.OpsLog.LogEvent(lbcert, db.ACT_DELETE, lbcert.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lbcert, logclient.ACT_DELETE, nil, self.UserCred, true) lbcert.DoPendingDelete(ctx, self.GetUserCred()) self.SetStageComplete(ctx, nil) } diff --git a/pkg/compute/tasks/loadbalancer_create_task.go b/pkg/compute/tasks/loadbalancer_create_task.go index 00b5861ff6..4e16013038 100644 --- a/pkg/compute/tasks/loadbalancer_create_task.go +++ b/pkg/compute/tasks/loadbalancer_create_task.go @@ -8,7 +8,9 @@ import ( "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 LoadbalancerCreateTask struct { @@ -20,7 +22,10 @@ func init() { } func (self *LoadbalancerCreateTask) taskFail(ctx context.Context, lb *models.SLoadbalancer, reason string) { - lb.SetStatus(self.GetUserCred(), models.LB_STATUS_CREATE_FAILED, reason) + lb.SetStatus(self.GetUserCred(), models.LB_CREATE_FAILED, reason) + db.OpsLog.LogEvent(lb, db.ACT_ALLOCATE_FAIL, reason, self.UserCred) + logclient.AddActionLog(lb, logclient.ACT_CREATE, reason, self.UserCred, false) + notifyclient.NotifySystemError(lb.Id, lb.Name, models.LB_CREATE_FAILED, reason) self.SetStageFailed(ctx, reason) } @@ -39,9 +44,22 @@ func (self *LoadbalancerCreateTask) OnInit(ctx context.Context, obj db.IStandalo func (self *LoadbalancerCreateTask) OnLoadbalancerCreateComplete(ctx context.Context, lb *models.SLoadbalancer, data jsonutils.JSONObject) { lb.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") - self.SetStageComplete(ctx, nil) + db.OpsLog.LogEvent(lb, db.ACT_ALLOCATE, lb.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lb, logclient.ACT_CREATE, nil, self.UserCred, true) + self.SetStage("OnLoadbalancerStartComplete", nil) + lb.StartLoadBalancerStartTask(ctx, self.GetUserCred(), self.GetTaskId()) } func (self *LoadbalancerCreateTask) OnLoadbalancerCreateCompleteFailed(ctx context.Context, lb *models.SLoadbalancer, reason jsonutils.JSONObject) { self.taskFail(ctx, lb, reason.String()) } + +func (self *LoadbalancerCreateTask) OnLoadbalancerStartComplete(ctx context.Context, lb *models.SLoadbalancer, data jsonutils.JSONObject) { + lb.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerCreateTask) OnLoadbalancerStartCompleteFailed(ctx context.Context, lb *models.SLoadbalancer, reason jsonutils.JSONObject) { + lb.SetStatus(self.GetUserCred(), models.LB_STATUS_DISABLED, reason.String()) + self.SetStageFailed(ctx, reason.String()) +} diff --git a/pkg/compute/tasks/loadbalancer_delete_task.go b/pkg/compute/tasks/loadbalancer_delete_task.go index cc7d0da17e..bb4fef41d4 100644 --- a/pkg/compute/tasks/loadbalancer_delete_task.go +++ b/pkg/compute/tasks/loadbalancer_delete_task.go @@ -8,7 +8,9 @@ import ( "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 LoadbalancerDeleteTask struct { @@ -21,6 +23,9 @@ func init() { func (self *LoadbalancerDeleteTask) taskFail(ctx context.Context, lb *models.SLoadbalancer, reason string) { lb.SetStatus(self.GetUserCred(), models.LB_STATUS_DELETE_FAILED, reason) + db.OpsLog.LogEvent(lb, db.ACT_DELOCATE_FAIL, reason, self.UserCred) + logclient.AddActionLog(lb, logclient.ACT_DELETE, reason, self.UserCred, false) + notifyclient.NotifySystemError(lb.Id, lb.Name, models.LB_STATUS_DELETE_FAILED, reason) self.SetStageFailed(ctx, reason) } @@ -38,6 +43,8 @@ func (self *LoadbalancerDeleteTask) OnInit(ctx context.Context, obj db.IStandalo } func (self *LoadbalancerDeleteTask) OnLoadbalancerDeleteComplete(ctx context.Context, lb *models.SLoadbalancer, data jsonutils.JSONObject) { + db.OpsLog.LogEvent(lb, db.ACT_DELETE, lb.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lb, logclient.ACT_DELETE, nil, self.UserCred, true) lb.PendingDelete(ctx, self.GetUserCred()) self.SetStageComplete(ctx, nil) } diff --git a/pkg/compute/tasks/loadbalancer_listener_create_task.go b/pkg/compute/tasks/loadbalancer_listener_create_task.go index ef1b4827d6..76b91f7363 100644 --- a/pkg/compute/tasks/loadbalancer_listener_create_task.go +++ b/pkg/compute/tasks/loadbalancer_listener_create_task.go @@ -8,7 +8,9 @@ import ( "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 LoadbalancerListenerCreateTask struct { @@ -20,7 +22,10 @@ func init() { } func (self *LoadbalancerListenerCreateTask) taskFail(ctx context.Context, lblis *models.SLoadbalancerListener, reason string) { - lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_CREATE_FAILED, reason) + lblis.SetStatus(self.GetUserCred(), models.LB_CREATE_FAILED, reason) + db.OpsLog.LogEvent(lblis, db.ACT_ALLOCATE_FAIL, reason, self.UserCred) + logclient.AddActionLog(lblis, logclient.ACT_CREATE, reason, self.UserCred, false) + notifyclient.NotifySystemError(lblis.Id, lblis.Name, models.LB_CREATE_FAILED, reason) self.SetStageFailed(ctx, reason) } @@ -39,9 +44,22 @@ func (self *LoadbalancerListenerCreateTask) OnInit(ctx context.Context, obj db.I func (self *LoadbalancerListenerCreateTask) OnLoadbalancerListenerCreateComplete(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") - self.SetStageComplete(ctx, nil) + db.OpsLog.LogEvent(lblis, db.ACT_ALLOCATE, lblis.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lblis, logclient.ACT_CREATE, nil, self.UserCred, true) + self.SetStage("OnLoadbalancerListenerStartComplete", nil) + lblis.StartLoadBalancerListenerStartTask(ctx, self.GetUserCred(), self.GetTaskId()) } func (self *LoadbalancerListenerCreateTask) OnLoadbalancerListenerCreateCompleteFailed(ctx context.Context, lblis *models.SLoadbalancerListener, reason jsonutils.JSONObject) { self.taskFail(ctx, lblis, reason.String()) } + +func (self *LoadbalancerListenerCreateTask) OnLoadbalancerListenerStartComplete(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { + lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerListenerCreateTask) OnLoadbalancerListenerStartCompleteFailed(ctx context.Context, lblis *models.SLoadbalancerListener, reason jsonutils.JSONObject) { + lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_DISABLED, reason.String()) + self.SetStageFailed(ctx, reason.String()) +} diff --git a/pkg/compute/tasks/loadbalancer_listener_delete_task.go b/pkg/compute/tasks/loadbalancer_listener_delete_task.go index 50accb60fe..23c5067eb9 100644 --- a/pkg/compute/tasks/loadbalancer_listener_delete_task.go +++ b/pkg/compute/tasks/loadbalancer_listener_delete_task.go @@ -8,7 +8,9 @@ import ( "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 LoadbalancerListenerDeleteTask struct { @@ -21,6 +23,9 @@ func init() { func (self *LoadbalancerListenerDeleteTask) taskFail(ctx context.Context, lblis *models.SLoadbalancerListener, reason string) { lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_DELETE_FAILED, reason) + db.OpsLog.LogEvent(lblis, db.ACT_DELOCATE_FAIL, reason, self.UserCred) + logclient.AddActionLog(lblis, logclient.ACT_DELETE, reason, self.UserCred, false) + notifyclient.NotifySystemError(lblis.Id, lblis.Name, models.LB_STATUS_DELETE_FAILED, reason) self.SetStageFailed(ctx, reason) } @@ -38,6 +43,8 @@ func (self *LoadbalancerListenerDeleteTask) OnInit(ctx context.Context, obj db.I } func (self *LoadbalancerListenerDeleteTask) OnLoadbalancerListenerDeleteComplete(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { + db.OpsLog.LogEvent(lblis, db.ACT_DELETE, lblis.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lblis, logclient.ACT_DELETE, nil, self.UserCred, true) lblis.PreDeleteSubs(ctx, self.GetUserCred()) self.SetStageComplete(ctx, nil) } diff --git a/pkg/compute/tasks/loadbalancer_listener_rule_create_task.go b/pkg/compute/tasks/loadbalancer_listener_rule_create_task.go index 843ef57f0e..d006ee4b1e 100644 --- a/pkg/compute/tasks/loadbalancer_listener_rule_create_task.go +++ b/pkg/compute/tasks/loadbalancer_listener_rule_create_task.go @@ -8,7 +8,9 @@ import ( "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 LoadbalancerListenerRuleCreateTask struct { @@ -20,7 +22,10 @@ func init() { } func (self *LoadbalancerListenerRuleCreateTask) taskFail(ctx context.Context, lbr *models.SLoadbalancerListenerRule, reason string) { - lbr.SetStatus(self.GetUserCred(), models.LB_STATUS_CREATE_FAILED, reason) + lbr.SetStatus(self.GetUserCred(), models.LB_CREATE_FAILED, reason) + db.OpsLog.LogEvent(lbr, db.ACT_ALLOCATE_FAIL, reason, self.UserCred) + logclient.AddActionLog(lbr, logclient.ACT_CREATE, reason, self.UserCred, false) + notifyclient.NotifySystemError(lbr.Id, lbr.Name, models.LB_CREATE_FAILED, reason) self.SetStageFailed(ctx, reason) } @@ -39,6 +44,8 @@ func (self *LoadbalancerListenerRuleCreateTask) OnInit(ctx context.Context, obj func (self *LoadbalancerListenerRuleCreateTask) OnLoadbalancerListenerRuleCreateComplete(ctx context.Context, lbr *models.SLoadbalancerListenerRule, data jsonutils.JSONObject) { lbr.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") + db.OpsLog.LogEvent(lbr, db.ACT_ALLOCATE, lbr.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lbr, logclient.ACT_CREATE, nil, self.UserCred, true) self.SetStageComplete(ctx, nil) } diff --git a/pkg/compute/tasks/loadbalancer_listener_rule_delete_task.go b/pkg/compute/tasks/loadbalancer_listener_rule_delete_task.go index 771cf90ee9..5774ae1a2d 100644 --- a/pkg/compute/tasks/loadbalancer_listener_rule_delete_task.go +++ b/pkg/compute/tasks/loadbalancer_listener_rule_delete_task.go @@ -8,7 +8,9 @@ import ( "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 LoadbalancerListenerRuleDeleteTask struct { @@ -21,6 +23,9 @@ func init() { func (self *LoadbalancerListenerRuleDeleteTask) taskFail(ctx context.Context, lbr *models.SLoadbalancerListenerRule, reason string) { lbr.SetStatus(self.GetUserCred(), models.LB_STATUS_DELETE_FAILED, reason) + db.OpsLog.LogEvent(lbr, db.ACT_DELOCATE_FAIL, reason, self.UserCred) + logclient.AddActionLog(lbr, logclient.ACT_DELETE, reason, self.UserCred, false) + notifyclient.NotifySystemError(lbr.Id, lbr.Name, models.LB_STATUS_DELETE_FAILED, reason) self.SetStageFailed(ctx, reason) } @@ -38,6 +43,8 @@ func (self *LoadbalancerListenerRuleDeleteTask) OnInit(ctx context.Context, obj } func (self *LoadbalancerListenerRuleDeleteTask) OnLoadbalancerListenerRuleDeleteComplete(ctx context.Context, lbr *models.SLoadbalancerListenerRule, data jsonutils.JSONObject) { + db.OpsLog.LogEvent(lbr, db.ACT_DELETE, lbr.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lbr, logclient.ACT_DELETE, nil, self.UserCred, true) lbr.DoPendingDelete(ctx, self.GetUserCred()) self.SetStageComplete(ctx, nil) } diff --git a/pkg/compute/tasks/loadbalancer_listener_start_task.go b/pkg/compute/tasks/loadbalancer_listener_start_task.go index d067f56544..8cc81b96e8 100644 --- a/pkg/compute/tasks/loadbalancer_listener_start_task.go +++ b/pkg/compute/tasks/loadbalancer_listener_start_task.go @@ -8,7 +8,9 @@ import ( "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 LoadbalancerListenerStartTask struct { @@ -20,7 +22,10 @@ func init() { } func (self *LoadbalancerListenerStartTask) taskFail(ctx context.Context, lblis *models.SLoadbalancerListener, reason string) { - lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_UNKNOWN, reason) + lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_DISABLED, reason) + db.OpsLog.LogEvent(lblis, db.ACT_ENABLE, reason, self.UserCred) + logclient.AddActionLog(lblis, logclient.ACT_ENABLE, reason, self.UserCred, false) + notifyclient.NotifySystemError(lblis.Id, lblis.Name, models.LB_STATUS_DISABLED, reason) self.SetStageFailed(ctx, reason) } @@ -39,19 +44,11 @@ func (self *LoadbalancerListenerStartTask) OnInit(ctx context.Context, obj db.IS func (self *LoadbalancerListenerStartTask) OnLoadbalancerListenerStartComplete(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") + db.OpsLog.LogEvent(lblis, db.ACT_ENABLE, lblis.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lblis, logclient.ACT_ENABLE, nil, self.UserCred, true) self.SetStageComplete(ctx, nil) } func (self *LoadbalancerListenerStartTask) OnLoadbalancerListenerStartCompleteFailed(ctx context.Context, lblis *models.SLoadbalancerListener, reason jsonutils.JSONObject) { - lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_START_FAILED, reason.String()) - self.SetStage("OnLoadbalancerListenerSyncStatusComplete", nil) - lblis.StartLoadBalancerListenerSyncstatusTask(ctx, self.GetUserCred(), self.GetTaskId()) -} - -func (self *LoadbalancerListenerStartTask) OnLoadbalancerListenerSyncStatusComplete(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { - self.SetStageComplete(ctx, nil) -} - -func (self *LoadbalancerListenerStartTask) OnLoadbalancerListenerSyncStatusCompleteFailed(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { - self.taskFail(ctx, lblis, data.String()) + self.taskFail(ctx, lblis, reason.String()) } diff --git a/pkg/compute/tasks/loadbalancer_listener_stop_task.go b/pkg/compute/tasks/loadbalancer_listener_stop_task.go index 1593fcd63e..323606f48d 100644 --- a/pkg/compute/tasks/loadbalancer_listener_stop_task.go +++ b/pkg/compute/tasks/loadbalancer_listener_stop_task.go @@ -8,7 +8,9 @@ import ( "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 LoadbalancerListenerStopTask struct { @@ -20,7 +22,10 @@ func init() { } func (self *LoadbalancerListenerStopTask) taskFail(ctx context.Context, lblis *models.SLoadbalancerListener, reason string) { - lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_UNKNOWN, reason) + lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, reason) + db.OpsLog.LogEvent(lblis, db.ACT_DISABLE, reason, self.UserCred) + logclient.AddActionLog(lblis, logclient.ACT_DISABLE, reason, self.UserCred, false) + notifyclient.NotifySystemError(lblis.Id, lblis.Name, models.LB_STATUS_ENABLED, reason) self.SetStageFailed(ctx, reason) } @@ -39,19 +44,11 @@ func (self *LoadbalancerListenerStopTask) OnInit(ctx context.Context, obj db.ISt func (self *LoadbalancerListenerStopTask) OnLoadbalancerListenerStopComplete(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_DISABLED, "") + db.OpsLog.LogEvent(lblis, db.ACT_DISABLE, lblis.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lblis, logclient.ACT_DISABLE, nil, self.UserCred, true) self.SetStageComplete(ctx, nil) } func (self *LoadbalancerListenerStopTask) OnLoadbalancerListenerStopCompleteFailed(ctx context.Context, lblis *models.SLoadbalancerListener, reason jsonutils.JSONObject) { - lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_START_FAILED, reason.String()) - self.SetStage("OnLoadbalancerListenerSyncStatusComplete", nil) - lblis.StartLoadBalancerListenerSyncstatusTask(ctx, self.GetUserCred(), self.GetTaskId()) -} - -func (self *LoadbalancerListenerStopTask) OnLoadbalancerListenerSyncStatusComplete(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { - self.SetStageComplete(ctx, nil) -} - -func (self *LoadbalancerListenerStopTask) OnLoadbalancerListenerSyncStatusCompleteFailed(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { - self.taskFail(ctx, lblis, data.String()) + self.taskFail(ctx, lblis, reason.String()) } diff --git a/pkg/compute/tasks/loadbalancer_listener_sync_task.go b/pkg/compute/tasks/loadbalancer_listener_sync_task.go new file mode 100644 index 0000000000..6b00691e5c --- /dev/null +++ b/pkg/compute/tasks/loadbalancer_listener_sync_task.go @@ -0,0 +1,63 @@ +package tasks + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + + "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 LoadbalancerListenerSyncTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(LoadbalancerListenerSyncTask{}) +} + +func (self *LoadbalancerListenerSyncTask) taskFail(ctx context.Context, lblis *models.SLoadbalancerListener, reason string) { + lblis.SetStatus(self.GetUserCred(), models.LB_SYNC_CONF_FAILED, reason) + db.OpsLog.LogEvent(lblis, db.ACT_SYNC_CONF, reason, self.UserCred) + logclient.AddActionLog(lblis, logclient.ACT_SYNC_CONF, reason, self.UserCred, false) + notifyclient.NotifySystemError(lblis.Id, lblis.Name, models.LB_SYNC_CONF_FAILED, reason) + self.SetStageFailed(ctx, reason) +} + +func (self *LoadbalancerListenerSyncTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + lblis := obj.(*models.SLoadbalancerListener) + region := lblis.GetRegion() + if region == nil { + self.taskFail(ctx, lblis, fmt.Sprintf("failed to find region for lblis %s", lblis.Name)) + return + } + self.SetStage("OnLoadbalancerListenerSyncComplete", nil) + if err := region.GetDriver().RequestSyncLoadbalancerListener(ctx, self.GetUserCred(), lblis, self); err != nil { + self.taskFail(ctx, lblis, err.Error()) + } +} + +func (self *LoadbalancerListenerSyncTask) OnLoadbalancerListenerSyncComplete(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { + db.OpsLog.LogEvent(lblis, db.ACT_SYNC_CONF, lblis.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lblis, logclient.ACT_SYNC_CONF, nil, self.UserCred, true) + self.SetStage("OnLoadbalancerListenerSyncStatusComplete", nil) + lblis.StartLoadBalancerListenerSyncstatusTask(ctx, self.GetUserCred(), self.GetParams(), self.GetTaskId()) +} + +func (self *LoadbalancerListenerSyncTask) OnLoadbalancerListenerSyncCompleteFailed(ctx context.Context, lblis *models.SLoadbalancerListener, reason jsonutils.JSONObject) { + self.taskFail(ctx, lblis, reason.String()) +} + +func (self *LoadbalancerListenerSyncTask) OnLoadbalancerListenerSyncStatusComplete(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { + self.SetStageComplete(ctx, nil) +} + +func (self *LoadbalancerListenerSyncTask) OnLoadbalancerListenerSyncStatusCompleteFailed(ctx context.Context, lblis *models.SLoadbalancerListener, reason jsonutils.JSONObject) { + lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_UNKNOWN, reason.String()) + self.SetStageFailed(ctx, reason.String()) +} diff --git a/pkg/compute/tasks/loadbalancer_listener_syncstatus_task.go b/pkg/compute/tasks/loadbalancer_listener_syncstatus_task.go index c9c3235ef2..fc3a64cefd 100644 --- a/pkg/compute/tasks/loadbalancer_listener_syncstatus_task.go +++ b/pkg/compute/tasks/loadbalancer_listener_syncstatus_task.go @@ -8,7 +8,9 @@ import ( "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 LoadbalancerListenerSyncstatusTask struct { @@ -21,6 +23,9 @@ func init() { func (self *LoadbalancerListenerSyncstatusTask) taskFail(ctx context.Context, lblis *models.SLoadbalancerListener, reason string) { lblis.SetStatus(self.GetUserCred(), models.LB_STATUS_UNKNOWN, reason) + db.OpsLog.LogEvent(lblis, db.ACT_SYNC_STATUS, reason, self.UserCred) + logclient.AddActionLog(lblis, logclient.ACT_SYNC_STATUS, reason, self.UserCred, false) + notifyclient.NotifySystemError(lblis.Id, lblis.Name, models.LB_SYNC_CONF_FAILED, reason) self.SetStageFailed(ctx, reason) } @@ -38,6 +43,8 @@ func (self *LoadbalancerListenerSyncstatusTask) OnInit(ctx context.Context, obj } func (self *LoadbalancerListenerSyncstatusTask) OnLoadbalancerListenerSyncstatusComplete(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject) { + db.OpsLog.LogEvent(lblis, db.ACT_SYNC_STATUS, lblis.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lblis, logclient.ACT_SYNC_STATUS, nil, self.UserCred, true) self.SetStageComplete(ctx, nil) } diff --git a/pkg/compute/tasks/loadbalancer_start_task.go b/pkg/compute/tasks/loadbalancer_start_task.go index 28512fbe35..b402cf8109 100644 --- a/pkg/compute/tasks/loadbalancer_start_task.go +++ b/pkg/compute/tasks/loadbalancer_start_task.go @@ -8,7 +8,9 @@ import ( "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 LoadbalancerStartTask struct { @@ -20,7 +22,10 @@ func init() { } func (self *LoadbalancerStartTask) taskFail(ctx context.Context, lb *models.SLoadbalancer, reason string) { - lb.SetStatus(self.GetUserCred(), models.LB_STATUS_UNKNOWN, reason) + lb.SetStatus(self.GetUserCred(), models.LB_STATUS_DISABLED, reason) + db.OpsLog.LogEvent(lb, db.ACT_ENABLE, reason, self.UserCred) + logclient.AddActionLog(lb, logclient.ACT_ENABLE, reason, self.UserCred, false) + notifyclient.NotifySystemError(lb.Id, lb.Name, models.LB_STATUS_DISABLED, reason) self.SetStageFailed(ctx, reason) } @@ -39,19 +44,11 @@ func (self *LoadbalancerStartTask) OnInit(ctx context.Context, obj db.IStandalon func (self *LoadbalancerStartTask) OnLoadbalancerStartComplete(ctx context.Context, lb *models.SLoadbalancer, data jsonutils.JSONObject) { lb.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, "") + db.OpsLog.LogEvent(lb, db.ACT_ENABLE, lb.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lb, logclient.ACT_ENABLE, nil, self.UserCred, true) self.SetStageComplete(ctx, nil) } func (self *LoadbalancerStartTask) OnLoadbalancerStartCompleteFailed(ctx context.Context, lb *models.SLoadbalancer, reason jsonutils.JSONObject) { - lb.SetStatus(self.GetUserCred(), models.LB_STATUS_START_FAILED, reason.String()) - self.SetStage("OnLoadbalancerSyncStatusComplete", nil) - lb.StartLoadBalancerSyncstatusTask(ctx, self.GetUserCred(), self.GetTaskId()) -} - -func (self *LoadbalancerStartTask) OnLoadbalancerSyncStatusComplete(ctx context.Context, lb *models.SLoadbalancer, data jsonutils.JSONObject) { - self.SetStageComplete(ctx, nil) -} - -func (self *LoadbalancerStartTask) OnLoadbalancerSyncStatusCompleteFailed(ctx context.Context, lb *models.SLoadbalancer, data jsonutils.JSONObject) { - self.taskFail(ctx, lb, data.String()) + self.taskFail(ctx, lb, reason.String()) } diff --git a/pkg/compute/tasks/loadbalancer_stop_task.go b/pkg/compute/tasks/loadbalancer_stop_task.go index e7618cfdc9..4457466f99 100644 --- a/pkg/compute/tasks/loadbalancer_stop_task.go +++ b/pkg/compute/tasks/loadbalancer_stop_task.go @@ -8,7 +8,9 @@ import ( "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 LoadbalancerStopTask struct { @@ -20,7 +22,10 @@ func init() { } func (self *LoadbalancerStopTask) taskFail(ctx context.Context, lb *models.SLoadbalancer, reason string) { - lb.SetStatus(self.GetUserCred(), models.LB_STATUS_UNKNOWN, reason) + lb.SetStatus(self.GetUserCred(), models.LB_STATUS_ENABLED, reason) + db.OpsLog.LogEvent(lb, db.ACT_DISABLE, reason, self.UserCred) + logclient.AddActionLog(lb, logclient.ACT_DISABLE, reason, self.UserCred, false) + notifyclient.NotifySystemError(lb.Id, lb.Name, models.LB_STATUS_ENABLED, reason) self.SetStageFailed(ctx, reason) } @@ -39,19 +44,11 @@ func (self *LoadbalancerStopTask) OnInit(ctx context.Context, obj db.IStandalone func (self *LoadbalancerStopTask) OnLoadbalancerStopComplete(ctx context.Context, lb *models.SLoadbalancer, data jsonutils.JSONObject) { lb.SetStatus(self.GetUserCred(), models.LB_STATUS_DISABLED, "") + db.OpsLog.LogEvent(lb, db.ACT_DISABLE, lb.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lb, logclient.ACT_DISABLE, nil, self.UserCred, true) self.SetStageComplete(ctx, nil) } func (self *LoadbalancerStopTask) OnLoadbalancerStopCompleteFailed(ctx context.Context, lb *models.SLoadbalancer, reason jsonutils.JSONObject) { - lb.SetStatus(self.GetUserCred(), models.LB_STATUS_START_FAILED, reason.String()) - self.SetStage("OnLoadbalancerSyncStatusComplete", nil) - lb.StartLoadBalancerSyncstatusTask(ctx, self.GetUserCred(), self.GetTaskId()) -} - -func (self *LoadbalancerStopTask) OnLoadbalancerSyncStatusComplete(ctx context.Context, lb *models.SLoadbalancer, data jsonutils.JSONObject) { - self.SetStageComplete(ctx, nil) -} - -func (self *LoadbalancerStopTask) OnLoadbalancerSyncStatusCompleteFailed(ctx context.Context, lb *models.SLoadbalancer, data jsonutils.JSONObject) { - self.taskFail(ctx, lb, data.String()) + self.taskFail(ctx, lb, reason.String()) } diff --git a/pkg/compute/tasks/loadbalancer_syncstatus_task.go b/pkg/compute/tasks/loadbalancer_syncstatus_task.go index 4fe30bc890..2083ddec3b 100644 --- a/pkg/compute/tasks/loadbalancer_syncstatus_task.go +++ b/pkg/compute/tasks/loadbalancer_syncstatus_task.go @@ -8,7 +8,9 @@ import ( "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 LoadbalancerSyncstatusTask struct { @@ -21,6 +23,9 @@ func init() { func (self *LoadbalancerSyncstatusTask) taskFail(ctx context.Context, lb *models.SLoadbalancer, reason string) { lb.SetStatus(self.GetUserCred(), models.LB_STATUS_UNKNOWN, reason) + db.OpsLog.LogEvent(lb, db.ACT_SYNC_STATUS, reason, self.UserCred) + logclient.AddActionLog(lb, logclient.ACT_SYNC_STATUS, reason, self.UserCred, false) + notifyclient.NotifySystemError(lb.Id, lb.Name, models.LB_SYNC_CONF_FAILED, reason) self.SetStageFailed(ctx, reason) } @@ -38,6 +43,8 @@ func (self *LoadbalancerSyncstatusTask) OnInit(ctx context.Context, obj db.IStan } func (self *LoadbalancerSyncstatusTask) OnLoadbalancerSyncstatusComplete(ctx context.Context, lb *models.SLoadbalancer, data jsonutils.JSONObject) { + db.OpsLog.LogEvent(lb, db.ACT_SYNC_STATUS, lb.GetShortDesc(ctx), self.UserCred) + logclient.AddActionLog(lb, logclient.ACT_SYNC_STATUS, nil, self.UserCred, true) self.SetStageComplete(ctx, nil) } diff --git a/pkg/mcclient/options/loadbalancerlisteners.go b/pkg/mcclient/options/loadbalancerlisteners.go index 7f2ddd087e..2f56e238aa 100644 --- a/pkg/mcclient/options/loadbalancerlisteners.go +++ b/pkg/mcclient/options/loadbalancerlisteners.go @@ -160,3 +160,7 @@ type LoadbalancerListenerActionStatusOptions struct { ID string Status string `choices:"enabled|disabled"` } + +type LoadbalancerListenerActionSyncStatusOptions struct { + ID string +} diff --git a/pkg/mcclient/options/loadbalancers.go b/pkg/mcclient/options/loadbalancers.go index aa98cadfb2..0e27c8cfb6 100644 --- a/pkg/mcclient/options/loadbalancers.go +++ b/pkg/mcclient/options/loadbalancers.go @@ -44,3 +44,7 @@ type LoadbalancerActionStatusOptions struct { ID string Status string `choices:"enabled|disabled"` } + +type LoadbalancerActionSyncStatusOptions struct { + ID string +} diff --git a/pkg/util/aliyun/aliyun.go b/pkg/util/aliyun/aliyun.go index 7b29e9911e..830422825c 100644 --- a/pkg/util/aliyun/aliyun.go +++ b/pkg/util/aliyun/aliyun.go @@ -60,7 +60,7 @@ func jsonRequest(client *sdk.Client, domain, apiVersion, apiName string, params return nil, cloudprovider.ErrNotFound } } - for _, code := range []string{"SignatureNonceUsed", "InvalidInstance.NotSupported", "try later"} { + for _, code := range []string{"SignatureNonceUsed", "InvalidInstance.NotSupported", "try later", "BackendServer.configuring"} { if strings.Contains(err.Error(), code) { retry = true break diff --git a/pkg/util/aliyun/loadbalancerhttplistener.go b/pkg/util/aliyun/loadbalancerhttplistener.go index 5556fc9750..589f67c48c 100644 --- a/pkg/util/aliyun/loadbalancerhttplistener.go +++ b/pkg/util/aliyun/loadbalancerhttplistener.go @@ -327,3 +327,14 @@ func (listerner *SLoadbalancerHTTPListener) Start() error { func (listerner *SLoadbalancerHTTPListener) Stop() error { return listerner.lb.region.stopListener(listerner.ListenerPort, listerner.lb.LoadBalancerId) } + +func (region *SRegion) SyncLoadbalancerHTTPListener(lb *SLoadbalancer, listener *cloudprovider.SLoadbalancerListener) error { + params := region.constructBaseCreateListenerParams(lb, listener) + params = region.constructHTTPCreateListenerParams(params, listener) + _, err := region.lbRequest("SetLoadBalancerHTTPListenerAttribute", params) + return err +} + +func (listerner *SLoadbalancerHTTPListener) Sync(lblis *cloudprovider.SLoadbalancerListener) error { + return listerner.lb.region.SyncLoadbalancerHTTPListener(listerner.lb, lblis) +} diff --git a/pkg/util/aliyun/loadbalancerhttpslistener.go b/pkg/util/aliyun/loadbalancerhttpslistener.go index f6da257729..be509d3e11 100644 --- a/pkg/util/aliyun/loadbalancerhttpslistener.go +++ b/pkg/util/aliyun/loadbalancerhttpslistener.go @@ -4,7 +4,6 @@ import ( "fmt" "yunion.io/x/jsonutils" - "yunion.io/x/log" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" ) @@ -245,7 +244,6 @@ func (region *SRegion) GetLoadbalancerHTTPSListener(loadbalancerId string, liste } func (region *SRegion) constructHTTPCreateListenerParams(params map[string]string, listener *cloudprovider.SLoadbalancerListener) map[string]string { - log.Errorf("listener: %s", jsonutils.Marshal(listener).PrettyString()) params["HealthCheck"] = listener.HealthCheck if listener.HealthCheck == "on" { if len(listener.HealthCheckURI) == 0 { @@ -264,7 +262,7 @@ func (region *SRegion) constructHTTPCreateListenerParams(params map[string]strin listener.StickySessionCookieTimeout = 500 } params["CookieTimeout"] = fmt.Sprintf("%d", listener.StickySessionCookieTimeout) - params["ForwardPort"] = fmt.Sprintf("%d", listener.ForwardPort) + //params["ForwardPort"] = fmt.Sprintf("%d", listener.ForwardPort) //暂不支持 params["Gzip"] = "off" if listener.Gzip { params["Gzip"] = "on" @@ -332,3 +330,18 @@ func (listerner *SLoadbalancerHTTPSListener) Start() error { func (listerner *SLoadbalancerHTTPSListener) Stop() error { return listerner.lb.region.stopListener(listerner.ListenerPort, listerner.lb.LoadBalancerId) } + +func (region *SRegion) SyncLoadbalancerHTTPSListener(lb *SLoadbalancer, listener *cloudprovider.SLoadbalancerListener) error { + params := region.constructBaseCreateListenerParams(lb, listener) + params = region.constructHTTPCreateListenerParams(params, listener) + params["ServerCertificateId"] = listener.CertificateID + if len(lb.LoadBalancerSpec) > 0 && len(listener.TLSCipherPolicy) > 0 { + params["TLSCipherPolicy"] = listener.TLSCipherPolicy + } + _, err := region.lbRequest("SetLoadBalancerHTTPSListenerAttribute", params) + return err +} + +func (listerner *SLoadbalancerHTTPSListener) Sync(lblis *cloudprovider.SLoadbalancerListener) error { + return listerner.lb.region.SyncLoadbalancerHTTPSListener(listerner.lb, lblis) +} diff --git a/pkg/util/aliyun/loadbalancermasterslavebackendgroup.go b/pkg/util/aliyun/loadbalancermasterslavebackendgroup.go index a179dd9b76..fe30a8e34a 100644 --- a/pkg/util/aliyun/loadbalancermasterslavebackendgroup.go +++ b/pkg/util/aliyun/loadbalancermasterslavebackendgroup.go @@ -112,7 +112,8 @@ func (region *SRegion) CreateLoadbalancerMasterSlaveBackendGroup(name, loadbalan }, )) } - body, err := region.lbRequest("CreateMasterSlaveVServerGroup", params) + params["MasterSlaveBackendServers"] = servers.String() + body, err := region.lbRequest("CreateMasterSlaveServerGroup", params) if err != nil { return nil, err } @@ -127,7 +128,8 @@ func (region *SRegion) GetLoadbalancerMasterSlaveBackendgroupById(groupId string params := map[string]string{} params["RegionId"] = region.RegionId params["MasterSlaveServerGroupId"] = groupId - body, err := region.lbRequest("DescribeMasterSlaveVServerGroupAttribute", params) + params["NeedInstanceDetail"] = "true" + body, err := region.lbRequest("DescribeMasterSlaveServerGroupAttribute", params) if err != nil { return nil, err } @@ -135,19 +137,7 @@ func (region *SRegion) GetLoadbalancerMasterSlaveBackendgroupById(groupId string return group, body.Unmarshal(group) } -func (region *SRegion) UpdateLoadbalancerMasterSlaveBackendgroupName(name, groupId string) error { - params := map[string]string{} - params["RegionId"] = region.RegionId - params["MasterSlaveServerGroupId"] = groupId - params["MasterSlaveServerGroupName"] = name - _, err := region.lbRequest("SetMasterSlaveVServerGroupAttribute", params) - return err -} - func (backendgroup *SLoadbalancerMasterSlaveBackendGroup) Sync(name string) error { - if backendgroup.MasterSlaveServerGroupName != name { - return backendgroup.lb.region.UpdateLoadbalancerMasterSlaveBackendgroupName(backendgroup.MasterSlaveServerGroupId, name) - } return nil } diff --git a/pkg/util/aliyun/loadbalancertcplistener.go b/pkg/util/aliyun/loadbalancertcplistener.go index 7953e3fc8a..b8948f9892 100644 --- a/pkg/util/aliyun/loadbalancertcplistener.go +++ b/pkg/util/aliyun/loadbalancertcplistener.go @@ -211,9 +211,9 @@ func (region *SRegion) constructBaseCreateListenerParams(lb *SLoadbalancer, list params := map[string]string{} params["RegionId"] = region.RegionId switch lb.InternetChargeType { - case "paybybandwidth": - params["Bandwidth"] = "-1" case "paybytraffic": + params["Bandwidth"] = "-1" + case "paybybandwidth": if lb.Bandwidth > 5000 { lb.Bandwidth = 5000 } @@ -243,8 +243,8 @@ func (region *SRegion) constructBaseCreateListenerParams(lb *SLoadbalancer, list //TODO params["BackendServerPort"] = "" } - if len(listener.Description) > 0 { - params["Description"] = listener.Description + if len(listener.Name) > 0 { + params["Description"] = listener.Name } if listener.EstablishedTimeout >= 10 && listener.EstablishedTimeout <= 900 { params["EstablishedTimeout"] = fmt.Sprintf("%d", listener.EstablishedTimeout) @@ -317,3 +317,13 @@ func (listerner *SLoadbalancerTCPListener) Start() error { func (listerner *SLoadbalancerTCPListener) Stop() error { return listerner.lb.region.stopListener(listerner.ListenerPort, listerner.lb.LoadBalancerId) } + +func (region *SRegion) SyncLoadbalancerTCPListener(lb *SLoadbalancer, listener *cloudprovider.SLoadbalancerListener) error { + params := region.constructBaseCreateListenerParams(lb, listener) + _, err := region.lbRequest("SetLoadBalancerTCPListenerAttribute", params) + return err +} + +func (listerner *SLoadbalancerTCPListener) Sync(lblis *cloudprovider.SLoadbalancerListener) error { + return listerner.lb.region.SyncLoadbalancerTCPListener(listerner.lb, lblis) +} diff --git a/pkg/util/aliyun/loadbalancerudplistener.go b/pkg/util/aliyun/loadbalancerudplistener.go index e9624754ed..e489af1b69 100644 --- a/pkg/util/aliyun/loadbalancerudplistener.go +++ b/pkg/util/aliyun/loadbalancerudplistener.go @@ -240,3 +240,13 @@ func (listerner *SLoadbalancerUDPListener) Start() error { func (listerner *SLoadbalancerUDPListener) Stop() error { return listerner.lb.region.stopListener(listerner.ListenerPort, listerner.lb.LoadBalancerId) } + +func (region *SRegion) SyncLoadbalancerUDPListener(lb *SLoadbalancer, listener *cloudprovider.SLoadbalancerListener) error { + params := region.constructBaseCreateListenerParams(lb, listener) + _, err := region.lbRequest("SetLoadBalancerUDPListenerAttribute", params) + return err +} + +func (listerner *SLoadbalancerUDPListener) Sync(lblis *cloudprovider.SLoadbalancerListener) error { + return listerner.lb.region.SyncLoadbalancerUDPListener(listerner.lb, lblis) +} diff --git a/pkg/util/logclient/logclient.go b/pkg/util/logclient/logclient.go index ed50ded525..c130b8b8e1 100644 --- a/pkg/util/logclient/logclient.go +++ b/pkg/util/logclient/logclient.go @@ -61,6 +61,8 @@ const ( ACT_VM_REVOKESECGROUP = "取消关联安全组" ACT_VM_SETSECGROUP = "设置安全组" ACT_RESET_DISK = "回滚磁盘" + ACT_SYNC_STATUS = "同步状态" + ACT_SYNC_CONF = "同步配置" ACT_IMAGE_SAVE = "上传镜像" From 409b376ebdd13086d2a5a7462ab076827dff0f25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Thu, 17 Jan 2019 12:25:19 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BF=AE=E6=AD=A3udp,tcp=E5=90=8E=E7=AB=AF?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=99=A8=E7=BB=84id=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/climc/shell/loadbalancerbackendgroups.go | 2 +- pkg/cloudprovider/loadbalancerlistener.go | 6 +- pkg/cloudprovider/resources.go | 1 + pkg/compute/models/loadbalancer_const.go | 22 +-- pkg/compute/models/loadbalanceracls.go | 19 +-- .../models/loadbalancerbackendgroups.go | 131 ++++++++---------- pkg/compute/models/loadbalancerbackends.go | 8 +- .../models/loadbalancercertificates.go | 19 +-- .../models/loadbalancerlistenerrules.go | 2 +- pkg/compute/models/loadbalancerlisteners.go | 22 +-- pkg/compute/models/loadbalancers.go | 11 +- pkg/compute/regiondrivers/aliyun.go | 61 +++++++- pkg/compute/regiondrivers/managedvirtual.go | 11 -- pkg/mcclient/models/loadbalancers.go | 11 +- pkg/mcclient/options/loadbalanceracls.go | 8 +- .../options/loadbalancerbackendgroups.go | 90 +++++++++++- .../options/loadbalancercertificates.go | 2 +- pkg/mcclient/options/loadbalancerlisteners.go | 9 +- pkg/util/aliyun/loadbalancerhttplistener.go | 4 + pkg/util/aliyun/loadbalancerhttpslistener.go | 4 + pkg/util/aliyun/loadbalancertcplistener.go | 21 +-- pkg/util/aliyun/loadbalancerudplistener.go | 4 + 22 files changed, 283 insertions(+), 185 deletions(-) diff --git a/cmd/climc/shell/loadbalancerbackendgroups.go b/cmd/climc/shell/loadbalancerbackendgroups.go index b6dcf83247..7212c9997b 100644 --- a/cmd/climc/shell/loadbalancerbackendgroups.go +++ b/cmd/climc/shell/loadbalancerbackendgroups.go @@ -8,7 +8,7 @@ import ( func init() { R(&options.LoadbalancerBackendGroupCreateOptions{}, "lbbackendgroup-create", "Create lbbackendgroup", func(s *mcclient.ClientSession, opts *options.LoadbalancerBackendGroupCreateOptions) error { - params, err := options.StructToParams(opts) + params, err := opts.Params() if err != nil { return err } diff --git a/pkg/cloudprovider/loadbalancerlistener.go b/pkg/cloudprovider/loadbalancerlistener.go index 744dbbad93..85d95c13ad 100644 --- a/pkg/cloudprovider/loadbalancerlistener.go +++ b/pkg/cloudprovider/loadbalancerlistener.go @@ -32,9 +32,9 @@ type SLoadbalancerListener struct { StickySessionType string StickySessionCookieTimeout int - ForwardPort int - XForwardedFor bool - Gzip bool + BackendServerPort int + XForwardedFor bool + Gzip bool TLSCipherPolicy string } diff --git a/pkg/cloudprovider/resources.go b/pkg/cloudprovider/resources.go index 6eed2879fe..a23f31a48b 100644 --- a/pkg/cloudprovider/resources.go +++ b/pkg/cloudprovider/resources.go @@ -447,6 +447,7 @@ type ICloudLoadbalancerListener interface { GetHealthCheckExp() string GetBackendGroupId() string + GetBackendServerPort() int // HTTP && HTTPS GetHealthCheckDomain() string diff --git a/pkg/compute/models/loadbalancer_const.go b/pkg/compute/models/loadbalancer_const.go index 5708efd8af..f6c7b597ba 100644 --- a/pkg/compute/models/loadbalancer_const.go +++ b/pkg/compute/models/loadbalancer_const.go @@ -40,15 +40,10 @@ const ( LB_STATUS_DELETING = "deleting" LB_STATUS_DELETE_FAILED = "delete_failed" - LB_STATUS_UNKNOWN = "unknown" - LB_STATUS_RUNNING = "running" - LB_STATUS_STOPPED = "stopped" - LB_STATUS_START_FAILED = "start_failed" - LB_STATUS_STOP_FAILED = "stop_failed" - LB_STATUS_CONFIGURING = "configuring" // config changes pending - LB_STATUS_STOPPING = "stopping" - LB_STATUS_DELETE_PENDING = "delete_pending" - LB_STATUS_ERROR = "error" // bad things happen + LB_STATUS_START_FAILED = "start_failed" + LB_STATUS_STOP_FAILED = "stop_failed" + + LB_STATUS_UNKNOWN = "unknown" ) var LB_STATUS_SPEC = validators.NewChoices( @@ -71,15 +66,6 @@ var LB_BACKENDGROUP_TYPE = validators.NewChoices( LB_BACKENDGROUP_TYPE_MASTER_SLAVE, ) -var LB_STATUS_RUNTIME = validators.NewChoices( - LB_STATUS_INIT, - LB_STATUS_CONFIGURING, - LB_STATUS_RUNNING, - LB_STATUS_STOPPING, - LB_STATUS_STOPPED, - LB_STATUS_ERROR, -) - // Load Balancer network type (vpc or classic) determines viable backend // servers (they should be from the same network type as the load balancer). // diff --git a/pkg/compute/models/loadbalanceracls.go b/pkg/compute/models/loadbalanceracls.go index f5fb851226..86c92ea048 100644 --- a/pkg/compute/models/loadbalanceracls.go +++ b/pkg/compute/models/loadbalanceracls.go @@ -2,7 +2,6 @@ package models import ( "context" - "database/sql" "fmt" "net" "reflect" @@ -130,19 +129,13 @@ func (man *SLoadbalancerAclManager) ValidateCreateData(ctx context.Context, user if _, err := man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data); err != nil { return nil, err } - regionID, err := data.GetString("cloudregion_id") - if err != nil { - return nil, httperrors.NewMissingParameterError("cloudregion_id") + + regionV := validators.NewModelIdOrNameValidator("cloudregion", "cloudregion", ownerProjId) + regionV.Default("default") + if err := regionV.Validate(data); err != nil { + return nil, err } - _region, err := CloudregionManager.FetchByIdOrName(userCred, regionID) - if err != nil { - if err == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError("failed to find cloudregion %s", regionID) - } - return nil, httperrors.NewGeneralError(err) - } - data.Set("cloudregion_id", jsonutils.NewString(_region.GetId())) - region := _region.(*SCloudregion) + region := regionV.Model.(*SCloudregion) return region.GetDriver().ValidateCreateLoadbalancerAclData(ctx, userCred, data) } diff --git a/pkg/compute/models/loadbalancerbackendgroups.go b/pkg/compute/models/loadbalancerbackendgroups.go index a9006de62a..a959dbfa87 100644 --- a/pkg/compute/models/loadbalancerbackendgroups.go +++ b/pkg/compute/models/loadbalancerbackendgroups.go @@ -4,8 +4,6 @@ import ( "context" "database/sql" "fmt" - "strconv" - "strings" "yunion.io/x/jsonutils" "yunion.io/x/log" @@ -84,84 +82,69 @@ func (man *SLoadbalancerBackendGroupManager) ValidateCreateData(ctx context.Cont data.Set("manager_id", jsonutils.NewString(lb.ManagerId)) data.Set("cloudregion_id", jsonutils.NewString(lb.CloudregionId)) backends := []cloudprovider.SLoadbalancerBackend{} - for idx := 0; data.Contains(fmt.Sprintf("backend.%d", idx)); idx++ { - _backend, _ := data.GetString(fmt.Sprintf("backend.%d", idx)) - backend := cloudprovider.SLoadbalancerBackend{BackendType: LB_BACKEND_GUEST, Index: idx, BackendRole: "default"} - for _, info := range strings.Split(_backend, ",") { - value := strings.Split(info, ":") - if len(value) != 2 { - return nil, httperrors.NewInputParameterError("Unknown backend info %s", info) - } - switch strings.ToLower(value[0]) { - case "id", "name": - backend.ID = value[1] - case "backend_type", "backendtype", "type": - backend.BackendType = value[1] - case "weight": - v, err := strconv.Atoi(value[1]) - if err != nil || v < 0 || v > 256 { - return nil, httperrors.NewInputParameterError("weight %s not support, only support range 0 ~ 100") - } - backend.Weight = v - case "port": - v, err := strconv.Atoi(value[1]) - if err != nil || v < 1 || v > 65535 { - return nil, httperrors.NewInputParameterError("port %s not support, only support range 1 ~ 65535") - } - backend.Port = v - } + if data.Contains("backends") { + if err := data.Unmarshal(&backends, "backends"); err != nil { + return nil, err } - if len(backend.ID) == 0 { - return nil, httperrors.NewMissingParameterError("Missing backend id or name params") - } - if backend.Port < 1 || backend.Port > 65535 { - return nil, httperrors.NewInputParameterError("port %s not support, only support range 1 ~ 65535") - } - switch backend.BackendType { - case LB_BACKEND_GUEST: - _guest, err := GuestManager.FetchByIdOrName(userCred, backend.ID) - if err != nil { - if err == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError("failed to find guest %s", backend.ID) - } - return nil, httperrors.NewGeneralError(err) + for i := 0; i < len(backends); i++ { + if len(backends[i].BackendType) == 0 { + backends[i].BackendType = LB_BACKEND_GUEST } - guest := _guest.(*SGuest) - host := guest.GetHost() - if host == nil { - return nil, fmt.Errorf("error getting host of guest %s", guest.Name) + if backends[i].Weight < 0 || backends[i].Weight > 256 { + return nil, httperrors.NewInputParameterError("weight %s not support, only support range 0 ~ 256") + } + if backends[i].Port < 1 || backends[i].Port > 65535 { + return nil, httperrors.NewInputParameterError("port %s not support, only support range 1 ~ 65535") + } + if len(backends[i].ID) == 0 { + return nil, httperrors.NewMissingParameterError("Missing backend id") } - backend.ZoneId = host.ZoneId - backend.HostName = host.Name - backend.ID = guest.Id - backend.Name = guest.Name - backend.ExternalID = guest.ExternalId - address, err := LoadbalancerBackendManager.GetGuestAddress(guest) - if err != nil { - return nil, err - } - backend.Address = address - case LB_BACKEND_HOST: - if !db.IsAdminAllowCreate(userCred, man) { - return nil, httperrors.NewForbiddenError("only sysadmin can specify host as backend") - } - _host, err := HostManager.FetchByIdOrName(userCred, backend.ID) - if err != nil { - if err == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError("failed to find host %s", backend.ID) + switch backends[i].BackendType { + case LB_BACKEND_GUEST: + _guest, err := GuestManager.FetchByIdOrName(userCred, backends[i].ID) + if err != nil { + if err == sql.ErrNoRows { + return nil, httperrors.NewResourceNotFoundError("failed to find guest %s", backends[i].ID) + } + return nil, httperrors.NewGeneralError(err) } - return nil, httperrors.NewGeneralError(err) + guest := _guest.(*SGuest) + host := guest.GetHost() + if host == nil { + return nil, fmt.Errorf("error getting host of guest %s", guest.Name) + } + backends[i].ZoneId = host.ZoneId + backends[i].HostName = host.Name + backends[i].ID = guest.Id + backends[i].Name = guest.Name + backends[i].ExternalID = guest.ExternalId + + address, err := LoadbalancerBackendManager.GetGuestAddress(guest) + if err != nil { + return nil, err + } + backends[i].Address = address + case LB_BACKEND_HOST: + if !db.IsAdminAllowCreate(userCred, man) { + return nil, httperrors.NewForbiddenError("only sysadmin can specify host as backend") + } + _host, err := HostManager.FetchByIdOrName(userCred, backends[i].ID) + if err != nil { + if err == sql.ErrNoRows { + return nil, httperrors.NewResourceNotFoundError("failed to find host %s", backends[i].ID) + } + return nil, httperrors.NewGeneralError(err) + } + host := _host.(*SHost) + backends[i].ID = host.Id + backends[i].Name = host.Name + backends[i].ExternalID = host.ExternalId + backends[i].Address = host.AccessIp + default: + return nil, httperrors.NewInputParameterError("unexpected backend type %s", backends[i].BackendType) } - host := _host.(*SHost) - backend.ID = host.Id - backend.Name = host.Name - backend.ExternalID = host.ExternalId - backend.Address = host.AccessIp - default: - return nil, httperrors.NewInputParameterError("unexpected backend type %s", backend.BackendType) } - backends = append(backends, backend) } data.Set("backends", jsonutils.Marshal(backends)) return lb.GetRegion().GetDriver().ValidateCreateLoadbalancerBackendGroupData(ctx, userCred, data, lb, backends) @@ -458,7 +441,7 @@ func (man *SLoadbalancerBackendGroupManager) InitializeData() error { func (manager *SLoadbalancerBackendGroupManager) initBackendGroupRegion() error { groups := []SLoadbalancerBackendGroup{} q := manager.Query() - q = q.Filter(sqlchemy.IsNotEmpty(q.Field("cloudregion_id"))) + q = q.Filter(sqlchemy.IsNullOrEmpty(q.Field("cloudregion_id"))) if err := db.FetchModelObjects(manager, q, &groups); err != nil { return err } diff --git a/pkg/compute/models/loadbalancerbackends.go b/pkg/compute/models/loadbalancerbackends.go index 2ea482c1d8..4de7adc471 100644 --- a/pkg/compute/models/loadbalancerbackends.go +++ b/pkg/compute/models/loadbalancerbackends.go @@ -167,7 +167,7 @@ func (lbb *SLoadbalancerBackend) GetIRegion() (cloudprovider.ICloudRegion, error if backendgroup := lbb.GetLoadbalancerBackendGroup(); backendgroup != nil { return backendgroup.GetIRegion() } - return nil, fmt.Errorf("failed to find backendgroup for backend %s", lbb.Name) + return nil, fmt.Errorf("failed to find region for backend %s", lbb.Name) } func (man *SLoadbalancerBackendManager) GetGuestAddress(guest *SGuest) (string, error) { @@ -214,10 +214,6 @@ func (lbb *SLoadbalancerBackend) StartLoadBalancerBackendCreateTask(ctx context. return nil } -// func (lbb *SLoadbalancerBackend) PreDelete(ctx context.Context, userCred mcclient.TokenCredential) { -// lbb.DoPendingDelete(ctx, userCred) -// } - func (lbb *SLoadbalancerBackend) Delete(ctx context.Context, userCred mcclient.TokenCredential) error { return nil } @@ -375,7 +371,7 @@ func (man *SLoadbalancerBackendManager) newFromCloudLoadbalancerBackend(ctx cont func (manager *SLoadbalancerBackendManager) InitializeData() error { backends := []SLoadbalancerBackend{} q := manager.Query() - q = q.Filter(sqlchemy.IsNotEmpty(q.Field("cloudregion_id"))) + q = q.Filter(sqlchemy.IsNullOrEmpty(q.Field("cloudregion_id"))) if err := db.FetchModelObjects(manager, q, &backends); err != nil { return err } diff --git a/pkg/compute/models/loadbalancercertificates.go b/pkg/compute/models/loadbalancercertificates.go index 9a36d6cc66..3c030e7fa9 100644 --- a/pkg/compute/models/loadbalancercertificates.go +++ b/pkg/compute/models/loadbalancercertificates.go @@ -4,7 +4,6 @@ import ( "context" "crypto/sha256" "crypto/x509" - "database/sql" "encoding/hex" "encoding/pem" "fmt" @@ -130,19 +129,13 @@ func (man *SLoadbalancerCertificateManager) ValidateCreateData(ctx context.Conte if _, err := man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data); err != nil { return nil, err } - regionID, err := data.GetString("cloudregion_id") - if err != nil { - return nil, httperrors.NewMissingParameterError("cloudregion_id") + + regionV := validators.NewModelIdOrNameValidator("cloudregion", "cloudregion", ownerProjId) + regionV.Default("default") + if err := regionV.Validate(data); err != nil { + return nil, err } - _region, err := CloudregionManager.FetchByIdOrName(userCred, regionID) - if err != nil { - if err == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError("failed to find cloudregion %s", regionID) - } - return nil, httperrors.NewGeneralError(err) - } - data.Set("cloudregion_id", jsonutils.NewString(_region.GetId())) - region := _region.(*SCloudregion) + region := regionV.Model.(*SCloudregion) return region.GetDriver().ValidateCreateLoadbalancerCertificateData(ctx, userCred, data) } diff --git a/pkg/compute/models/loadbalancerlistenerrules.go b/pkg/compute/models/loadbalancerlistenerrules.go index d5dc51491b..cee456567d 100644 --- a/pkg/compute/models/loadbalancerlistenerrules.go +++ b/pkg/compute/models/loadbalancerlistenerrules.go @@ -365,7 +365,7 @@ func (lbr *SLoadbalancerListenerRule) SyncWithCloudLoadbalancerListenerRule(ctx func (manager *SLoadbalancerListenerRuleManager) InitializeData() error { rules := []SLoadbalancerListenerRule{} q := manager.Query() - q = q.Filter(sqlchemy.IsNotEmpty(q.Field("cloudregion_id"))) + q = q.Filter(sqlchemy.IsNullOrEmpty(q.Field("cloudregion_id"))) if err := db.FetchModelObjects(manager, q, &rules); err != nil { return err } diff --git a/pkg/compute/models/loadbalancerlisteners.go b/pkg/compute/models/loadbalancerlisteners.go index 80988883f6..3e9a47e389 100644 --- a/pkg/compute/models/loadbalancerlisteners.go +++ b/pkg/compute/models/loadbalancerlisteners.go @@ -72,11 +72,12 @@ type SLoadbalancerListener struct { db.SVirtualResourceBase SManagedResourceBase - CloudregionId string `width:"36" charset:"ascii" nullable:"false" list:"admin" default:"default" create:"optional"` - LoadbalancerId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` - ListenerType string `width:"16" charset:"ascii" nullable:"false" list:"user" create:"required"` - ListenerPort int `nullable:"false" list:"user" create:"required"` - BackendGroupId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional" update:"user"` + CloudregionId string `width:"36" charset:"ascii" nullable:"false" list:"admin" default:"default" create:"optional"` + LoadbalancerId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` + ListenerType string `width:"16" charset:"ascii" nullable:"false" list:"user" create:"required"` + ListenerPort int `nullable:"false" list:"user" create:"required"` + BackendGroupId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional" update:"user"` + BackendServerPort int `nullable:"false" get:"user" list:"user" default:"0" create:"optional"` Scheduler string `width:"16" charset:"ascii" nullable:"false" list:"user" create:"required" update:"user"` @@ -569,10 +570,10 @@ func (lblis *SLoadbalancerListener) GetLoadbalancerListenerParams() (*cloudprovi StickySessionCookie: lblis.StickySessionCookie, StickySessionCookieTimeout: lblis.StickySessionCookieTimeout, - //ForwardPort: lblis.ForwardPort, - XForwardedFor: lblis.XForwardedFor, - TLSCipherPolicy: lblis.TLSCipherPolicy, - Gzip: lblis.Gzip, + BackendServerPort: lblis.BackendServerPort, + XForwardedFor: lblis.XForwardedFor, + TLSCipherPolicy: lblis.TLSCipherPolicy, + Gzip: lblis.Gzip, } if acl := lblis.GetLoadbalancerAcl(); acl != nil { listener.AccessControlListID = acl.ExternalId @@ -730,6 +731,7 @@ func (lblis *SLoadbalancerListener) constructFieldsFromCloudListener(lb *SLoadba lblis.HealthCheckType = extListener.GetHealthCheckType() lblis.HealthCheckTimeout = extListener.GetHealthCheckTimeout() lblis.HealthCheckInterval = extListener.GetHealthCheckInterval() + lblis.BackendServerPort = extListener.GetBackendServerPort() switch lblis.ListenerType { case LB_LISTENER_TYPE_HTTPS: @@ -786,7 +788,7 @@ func (man *SLoadbalancerListenerManager) newFromCloudLoadbalancerListener(ctx co func (manager *SLoadbalancerListenerManager) InitializeData() error { listeners := []SLoadbalancerListener{} q := manager.Query() - q = q.Filter(sqlchemy.IsNotEmpty(q.Field("cloudregion_id"))) + q = q.Filter(sqlchemy.IsNullOrEmpty(q.Field("cloudregion_id"))) if err := db.FetchModelObjects(manager, q, &listeners); err != nil { return err } diff --git a/pkg/compute/models/loadbalancers.go b/pkg/compute/models/loadbalancers.go index 29571bff5c..d8118b1b96 100644 --- a/pkg/compute/models/loadbalancers.go +++ b/pkg/compute/models/loadbalancers.go @@ -56,15 +56,15 @@ type SLoadbalancer struct { SManagedResourceBase Address string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional"` - AddressType string `width:"16" charset:"ascii" nullable:"false" default:"intranet" list:"user" create:"optional"` - NetworkType string `width:"16" charset:"ascii" nullable:"false" default:"vpc" list:"user" create:"optional"` + AddressType string `width:"16" charset:"ascii" nullable:"false" list:"user" create:"optional"` + NetworkType string `width:"16" charset:"ascii" nullable:"false" list:"user" create:"optional"` NetworkId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` VpcId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` ZoneId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` CloudregionId string `width:"36" charset:"ascii" nullable:"false" list:"admin" default:"default" create:"optional"` - ChargeType string `list:"user" default:"traffic" create:"optional"` - LoadbalancerSpec string `list:"user" create:"optional"` + ChargeType string `list:"user" get:"user" create:"optional"` + LoadbalancerSpec string `list:"user" get:"user" create:"optional"` BackendGroupId string `width:"36" charset:"ascii" nullable:"true" list:"user" update:"user" update:"user"` } @@ -163,15 +163,14 @@ func (man *SLoadbalancerManager) ValidateCreateData(ctx context.Context, userCre data.Set("address_type", jsonutils.NewString(LB_ADDR_TYPE_INTRANET)) } else { zone := zoneV.Model.(*SZone) - data.Set("zone_id", jsonutils.NewString(zone.GetId())) region = zone.GetRegion() if region == nil { return nil, fmt.Errorf("getting region failed") } + // 公网 lb 实例和vpc、network无关联 data.Set("vpc_id", jsonutils.NewString("")) data.Set("address", jsonutils.NewString("")) data.Set("network_id", jsonutils.NewString("")) - data.Set("manager_id", jsonutils.NewString(managerIdV.Model.GetId())) data.Set("cloudregion_id", jsonutils.NewString(region.GetId())) data.Set("network_type", jsonutils.NewString(LB_NETWORK_TYPE_VPC)) data.Set("address_type", jsonutils.NewString(LB_ADDR_TYPE_INTERNET)) diff --git a/pkg/compute/regiondrivers/aliyun.go b/pkg/compute/regiondrivers/aliyun.go index 6394aa70e4..78bb06539a 100644 --- a/pkg/compute/regiondrivers/aliyun.go +++ b/pkg/compute/regiondrivers/aliyun.go @@ -130,12 +130,10 @@ func (self *SAliyunRegionDriver) ValidateCreateLoadbalancerListenerData(ctx cont return nil, httperrors.NewMissingParameterError("backend_group") } listenerType, _ := data.GetString("listener_type") - if utils.IsInStringArray(listenerType, []string{models.LB_LISTENER_TYPE_UDP, models.LB_LISTENER_TYPE_TCP}) && !utils.IsInStringArray(backendgroup.Type, []string{models.LB_BACKENDGROUP_TYPE_MASTER_SLAVE, models.LB_BACKENDGROUP_TYPE_NORMAL}) { - return nil, httperrors.NewUnsupportOperationError("udp or tcp listener only support normal or master_slave backendgroup") - } - if utils.IsInStringArray(listenerType, []string{models.LB_LISTENER_TYPE_HTTP, models.LB_LISTENER_TYPE_HTTPS}) && backendgroup.Type != models.LB_BACKENDGROUP_TYPE_NORMAL { - return nil, httperrors.NewUnsupportOperationError("http or https listener only support normal or master_slave backendgroup") + if utils.IsInStringArray(listenerType, []string{models.LB_LISTENER_TYPE_HTTP, models.LB_LISTENER_TYPE_HTTPS}) && !utils.IsInStringArray(backendgroup.Type, []string{models.LB_BACKENDGROUP_TYPE_DEFAULT, models.LB_BACKENDGROUP_TYPE_MASTER_SLAVE}) { + return nil, httperrors.NewUnsupportOperationError("http or https listener only supportd default or master_slave backendgroup") } + lb := backendgroup.GetLoadbalancer() if tlsCipherPolicy, _ := data.GetString("tls_cipher_policy"); len(tlsCipherPolicy) > 0 && len(lb.LoadbalancerSpec) == 0 { data.Set("tls_cipher_policy", jsonutils.NewString("")) @@ -159,8 +157,12 @@ func (self *SAliyunRegionDriver) ValidateCreateLoadbalancerListenerData(ctx cont if !utils.IsInStringArray(listenerType, []string{models.LB_LISTENER_TYPE_UDP, models.LB_LISTENER_TYPE_TCP}) { keyV["client_idle_timeout"] = validators.NewRangeValidator("client_idle_timeout", 1, 60) } + + if backendgroup.Type == models.LB_BACKENDGROUP_TYPE_DEFAULT { + keyV["backend_server_port"] = validators.NewPortValidator("backend_server_port") + } + for _, v := range keyV { - v.Optional(true) if err := v.Validate(data); err != nil { return nil, err } @@ -169,5 +171,50 @@ func (self *SAliyunRegionDriver) ValidateCreateLoadbalancerListenerData(ctx cont } func (self *SAliyunRegionDriver) ValidateUpdateLoadbalancerListenerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, backendGroup db.IModel) (*jsonutils.JSONDict, error) { - return self.ValidateCreateLoadbalancerListenerData(ctx, userCred, data, backendGroup) + listenerType, _ := data.GetString("listener_type") + + keyV := map[string]validators.IValidator{ + "bandwidth": validators.NewRangeValidator("bandwidth", 1, 5000), + + "client_request_timeout": validators.NewRangeValidator("client_request_timeout", 1, 180), + + "sticky_session_cookie_timeout": validators.NewRangeValidator("sticky_session_cookie_timeout", 1, 86400), + + "health_check_rise": validators.NewRangeValidator("health_check_rise", 2, 10), + "health_check_fall": validators.NewRangeValidator("health_check_fall", 2, 10), + "health_check_timeout": validators.NewRangeValidator("health_check_timeout", 1, 300), + "health_check_interval": validators.NewRangeValidator("health_check_interval", 1, 50), + } + + if healthCheckDomain, _ := data.GetString("health_check_domain"); len(healthCheckDomain) > 80 { + return nil, httperrors.NewInputParameterError("health_check_domain must be in the range of 1 ~ 80") + } + + backendgroup, ok := backendGroup.(*models.SLoadbalancerBackendGroup) + if ok { + if utils.IsInStringArray(listenerType, []string{models.LB_LISTENER_TYPE_HTTP, models.LB_LISTENER_TYPE_HTTPS}) && !utils.IsInStringArray(backendgroup.Type, []string{models.LB_BACKENDGROUP_TYPE_DEFAULT, models.LB_BACKENDGROUP_TYPE_MASTER_SLAVE}) { + return nil, httperrors.NewUnsupportOperationError("http or https listener only supportd default or master_slave backendgroup") + } + + if backendgroup.Type == models.LB_BACKENDGROUP_TYPE_DEFAULT { + keyV["backend_server_port"] = validators.NewPortValidator("backend_server_port") + } + + lb := backendgroup.GetLoadbalancer() + if tlsCipherPolicy, _ := data.GetString("tls_cipher_policy"); len(tlsCipherPolicy) > 0 && len(lb.LoadbalancerSpec) == 0 { + data.Set("tls_cipher_policy", jsonutils.NewString("")) + } + } + + if !utils.IsInStringArray(listenerType, []string{models.LB_LISTENER_TYPE_UDP, models.LB_LISTENER_TYPE_TCP}) { + keyV["client_idle_timeout"] = validators.NewRangeValidator("client_idle_timeout", 1, 60) + } + + for _, v := range keyV { + v.Optional(true) + if err := v.Validate(data); err != nil { + return nil, err + } + } + return data, nil } diff --git a/pkg/compute/regiondrivers/managedvirtual.go b/pkg/compute/regiondrivers/managedvirtual.go index d6a0f351af..ab721fa324 100644 --- a/pkg/compute/regiondrivers/managedvirtual.go +++ b/pkg/compute/regiondrivers/managedvirtual.go @@ -127,17 +127,6 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateLoadbalancer(ctx co if err := lb.SyncWithCloudLoadbalancer(ctx, userCred, iLoadbalancer, "", false); err != nil { return nil, err } - if lb.AddressType == models.LB_ADDR_TYPE_INTRANET { - req := &models.SLoadbalancerNetworkRequestData{ - Loadbalancer: lb, - NetworkId: lb.NetworkId, - Address: lb.Address, - } - if _, err := models.LoadbalancernetworkManager.NewLoadbalancerNetwork(ctx, userCred, req); err != nil { - return nil, err - } - } - lbbgs, err := iLoadbalancer.GetILoadBalancerBackendGroups() if err != nil { return nil, err diff --git a/pkg/mcclient/models/loadbalancers.go b/pkg/mcclient/models/loadbalancers.go index e02a73c0e0..2c1b2cc6be 100644 --- a/pkg/mcclient/models/loadbalancers.go +++ b/pkg/mcclient/models/loadbalancers.go @@ -48,7 +48,9 @@ type LoadbalancerHTTPRateLimiter struct { type LoadbalancerListener struct { VirtualResource + ManagedResource + CloudregionId string LoadbalancerId string ListenerType string ListenerPort int @@ -60,7 +62,8 @@ type LoadbalancerListener struct { BackendConnectTimeout int BackendIdleTimeout int - BackendGroupId string + BackendGroupId string + BackendServerPort int AclStatus string AclType string @@ -91,7 +94,9 @@ type LoadbalancerListener struct { type LoadbalancerListenerRule struct { VirtualResource + ManagedResource + CloudregionId string ListenerId string BackendGroupId string @@ -103,14 +108,18 @@ type LoadbalancerListenerRule struct { type LoadbalancerBackendGroup struct { VirtualResource + ManagedResource Type string LoadbalancerId string + CloudregionId string } type LoadbalancerBackend struct { VirtualResource + ManagedResource + CloudregionId string BackendGroupId string BackendId string BackendType string diff --git a/pkg/mcclient/options/loadbalanceracls.go b/pkg/mcclient/options/loadbalanceracls.go index 27591e9829..3064116497 100644 --- a/pkg/mcclient/options/loadbalanceracls.go +++ b/pkg/mcclient/options/loadbalanceracls.go @@ -56,10 +56,10 @@ func (entries AclEntries) String() string { } type LoadbalancerAclCreateOptions struct { - NAME string - AclEntry []string `help:"acl entry with cidr and comment separated by #, e.g. 10.9.0.0/16#no comment" json:"-"` - Provider string `json:"manager_id"` - Region string `required:"true" json:"cloudregion_id"` + NAME string + AclEntry []string `help:"acl entry with cidr and comment separated by #, e.g. 10.9.0.0/16#no comment" json:"-"` + ManagerId string `json:"manager_id"` + Region string `json:"cloudregion"` } type LoadbalancerAclGetOptions struct { diff --git a/pkg/mcclient/options/loadbalancerbackendgroups.go b/pkg/mcclient/options/loadbalancerbackendgroups.go index c3c95076e6..9b6798af21 100644 --- a/pkg/mcclient/options/loadbalancerbackendgroups.go +++ b/pkg/mcclient/options/loadbalancerbackendgroups.go @@ -1,10 +1,96 @@ package options +import ( + "fmt" + "strconv" + "strings" + + "yunion.io/x/jsonutils" + "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/pkg/utils" +) + type LoadbalancerBackendGroupCreateOptions struct { NAME string LOADBALANCER string - Type string `choices:"default|normal|master_slave"` - Backend []string + Type string `choices:"default|normal|master_slave"` + Backend []string `help:"backends with separated by ',' e.g. weight:80,port:443,id:01e9d393-d2b8-4d2e-85fb-023b83889070,backend_type:guest" json:"-"` +} + +type Backends []*SBackend + +type SBackend struct { + Index int + Weight int + Port int + ID string + BackendType string +} + +func NewBackend(s string, index int) (*SBackend, error) { + backend := &SBackend{Index: index} + for _, part := range strings.Split(s, ",") { + value := strings.Split(part, ":") + if len(value) != 2 { + return nil, fmt.Errorf("invalid input params %s eg: weight:80,port:443,id:01e9d393-d2b8-4d2e-85fb-023b83889070,backend_type:guest", part) + } + switch value[0] { + case "weight": + weight, err := strconv.Atoi(value[1]) + if err != nil { + return nil, fmt.Errorf("invalid weight %s error: %v", value[1], err) + } + if weight < 0 || weight > 256 { + return nil, fmt.Errorf("invalid weight range, only support 0 ~ 256") + } + backend.Weight = weight + case "port": + port, err := strconv.Atoi(value[1]) + if err != nil { + return nil, fmt.Errorf("invalid port %s error: %v", value[1], err) + } + if port < 1 || port > 65535 { + return nil, fmt.Errorf("invalid port range, only support 1 ~ 65535") + } + backend.Port = port + case "backend_type": + if utils.IsInStringArray(value[1], []string{models.LB_BACKEND_GUEST, models.LB_BACKEND_HOST}) { + return nil, fmt.Errorf("invalid backend type %s only support %s %s", value[1], models.LB_BACKEND_GUEST, models.LB_BACKEND_HOST) + } + backend.BackendType = value[1] + case "id": + backend.ID = value[1] + default: + return nil, fmt.Errorf("invalid input type %s", value[0]) + } + } + return backend, nil +} + +func NewBackends(ss []string) (Backends, error) { + backends := Backends{} + for index, s := range ss { + backend, err := NewBackend(s, index) + if err != nil { + return nil, err + } + backends = append(backends, backend) + } + return backends, nil +} + +func (opts *LoadbalancerBackendGroupCreateOptions) Params() (*jsonutils.JSONDict, error) { + params, err := optionsStructToParams(opts) + if err != nil { + return nil, err + } + backends, err := NewBackends(opts.Backend) + if err != nil { + return nil, err + } + backendJSON := jsonutils.Marshal(backends) + params.Set("backends", backendJSON) + return params, nil } type LoadbalancerBackendGroupGetOptions struct { diff --git a/pkg/mcclient/options/loadbalancercertificates.go b/pkg/mcclient/options/loadbalancercertificates.go index f544bd7d1b..a88a441952 100644 --- a/pkg/mcclient/options/loadbalancercertificates.go +++ b/pkg/mcclient/options/loadbalancercertificates.go @@ -38,7 +38,7 @@ type LoadbalancerCertificateCreateOptions struct { Cert string `required:"true" json:"-" help:"path to certificate file"` Pkey string `required:"true" json:"-" help:"path to private key file"` - Region string `required:"true" json:"cloudregion_id"` + Region string `json:"cloudregion"` ManagerId string } diff --git a/pkg/mcclient/options/loadbalancerlisteners.go b/pkg/mcclient/options/loadbalancerlisteners.go index 2f56e238aa..567409e549 100644 --- a/pkg/mcclient/options/loadbalancerlisteners.go +++ b/pkg/mcclient/options/loadbalancerlisteners.go @@ -3,10 +3,11 @@ package options type LoadbalancerListenerCreateOptions struct { NAME string - Loadbalancer string `required:"true"` - ListenerType string `required:"true" choices:"tcp|udp|http|https"` - ListenerPort *int `required:"true"` - BackendGroup string + Loadbalancer string `required:"true"` + ListenerType string `required:"true" choices:"tcp|udp|http|https"` + ListenerPort *int `required:"true"` + BackendServerPort *int + BackendGroup string Scheduler string `required:"true" choices:"rr|wrr|wlc|sch|tch"` diff --git a/pkg/util/aliyun/loadbalancerhttplistener.go b/pkg/util/aliyun/loadbalancerhttplistener.go index 589f67c48c..56cefc8783 100644 --- a/pkg/util/aliyun/loadbalancerhttplistener.go +++ b/pkg/util/aliyun/loadbalancerhttplistener.go @@ -117,6 +117,10 @@ func (listerner *SLoadbalancerHTTPListener) GetBackendGroupId() string { return listerner.VServerGroupId } +func (listerner *SLoadbalancerHTTPListener) GetBackendServerPort() int { + return listerner.BackendServerPort +} + func (listerner *SLoadbalancerHTTPListener) GetScheduler() string { return listerner.Scheduler } diff --git a/pkg/util/aliyun/loadbalancerhttpslistener.go b/pkg/util/aliyun/loadbalancerhttpslistener.go index be509d3e11..aba7729869 100644 --- a/pkg/util/aliyun/loadbalancerhttpslistener.go +++ b/pkg/util/aliyun/loadbalancerhttpslistener.go @@ -112,6 +112,10 @@ func (listerner *SLoadbalancerHTTPSListener) GetBackendGroupId() string { return listerner.VServerGroupId } +func (listerner *SLoadbalancerHTTPSListener) GetBackendServerPort() int { + return listerner.BackendServerPort +} + func (listerner *SLoadbalancerHTTPSListener) GetScheduler() string { return listerner.Scheduler } diff --git a/pkg/util/aliyun/loadbalancertcplistener.go b/pkg/util/aliyun/loadbalancertcplistener.go index b8948f9892..3b8f2492b9 100644 --- a/pkg/util/aliyun/loadbalancertcplistener.go +++ b/pkg/util/aliyun/loadbalancertcplistener.go @@ -190,6 +190,10 @@ func (listerner *SLoadbalancerTCPListener) HTTP2Enabled() bool { return false } +func (listerner *SLoadbalancerTCPListener) GetBackendServerPort() int { + return listerner.BackendServerPort +} + func (listerner *SLoadbalancerTCPListener) GetILoadbalancerListenerRules() ([]cloudprovider.ICloudLoadbalancerListenerRule, error) { return []cloudprovider.ICloudLoadbalancerListenerRule{}, nil } @@ -232,16 +236,13 @@ func (region *SRegion) constructBaseCreateListenerParams(lb *SLoadbalancer, list if utils.IsInStringArray(listener.AccessControlListType, []string{"white", "black"}) { params["AclType"] = listener.AccessControlListType } - if len(listener.BackendGroupID) > 0 { - switch listener.BackendGroupType { - case models.LB_BACKENDGROUP_TYPE_NORMAL: - params["VServerGroupId"] = listener.BackendGroupID - case models.LB_BACKENDGROUP_TYPE_MASTER_SLAVE: - params["MasterSlaveServerGroupId"] = listener.BackendGroupID - } - } else { - //TODO - params["BackendServerPort"] = "" + switch listener.BackendGroupType { + case models.LB_BACKENDGROUP_TYPE_NORMAL: + params["VServerGroupId"] = listener.BackendGroupID + case models.LB_BACKENDGROUP_TYPE_MASTER_SLAVE: + params["MasterSlaveServerGroupId"] = listener.BackendGroupID + case models.LB_BACKENDGROUP_TYPE_DEFAULT: + params["BackendServerPort"] = fmt.Sprintf("%d", listener.BackendServerPort) } if len(listener.Name) > 0 { params["Description"] = listener.Name diff --git a/pkg/util/aliyun/loadbalancerudplistener.go b/pkg/util/aliyun/loadbalancerudplistener.go index e489af1b69..ef51e5a642 100644 --- a/pkg/util/aliyun/loadbalancerudplistener.go +++ b/pkg/util/aliyun/loadbalancerudplistener.go @@ -94,6 +94,10 @@ func (listerner *SLoadbalancerUDPListener) GetBackendGroupId() string { return listerner.MasterSlaveServerGroupId } +func (listerner *SLoadbalancerUDPListener) GetBackendServerPort() int { + return listerner.BackendServerPort +} + func (listerner *SLoadbalancerUDPListener) GetScheduler() string { return listerner.Scheduler }