From cfadfb8a0467e36e44c880853b60f1b23f157698 Mon Sep 17 00:00:00 2001 From: Yousong Zhou Date: Sat, 10 Aug 2019 09:17:17 +0000 Subject: [PATCH] =?UTF-8?q?lbcluster:=20=E6=B7=BB=E5=8A=A0wire=E4=BA=B2?= =?UTF-8?q?=E5=92=8C=E6=80=A7=E8=B4=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/climc/shell/loadbalancerclusters.go | 12 ++++++ pkg/compute/models/loadbalancerclusters.go | 43 +++++++++++++++++-- pkg/compute/regiondrivers/kvm.go | 30 +++++++++++-- .../modules/mod_loadbalancerclusters.go | 1 + pkg/mcclient/options/loadbalancerclusters.go | 7 +++ 5 files changed, 87 insertions(+), 6 deletions(-) diff --git a/cmd/climc/shell/loadbalancerclusters.go b/cmd/climc/shell/loadbalancerclusters.go index 54c8720983..92ad782440 100644 --- a/cmd/climc/shell/loadbalancerclusters.go +++ b/cmd/climc/shell/loadbalancerclusters.go @@ -33,6 +33,18 @@ func init() { printObject(lbcluster) return nil }) + R(&options.LoadbalancerClusterUpdateOptions{}, "lbcluster-update", "Update lbcluster", func(s *mcclient.ClientSession, opts *options.LoadbalancerClusterUpdateOptions) error { + params, err := options.StructToParams(opts) + if err != nil { + return err + } + lbcluster, err := modules.LoadbalancerClusters.Update(s, opts.ID, params) + if err != nil { + return err + } + printObject(lbcluster) + return nil + }) R(&options.LoadbalancerClusterGetOptions{}, "lbcluster-show", "Show lbcluster", func(s *mcclient.ClientSession, opts *options.LoadbalancerClusterGetOptions) error { lbcluster, err := modules.LoadbalancerClusters.Get(s, opts.ID, nil) if err != nil { diff --git a/pkg/compute/models/loadbalancerclusters.go b/pkg/compute/models/loadbalancerclusters.go index 9162de070b..1fba2a765d 100644 --- a/pkg/compute/models/loadbalancerclusters.go +++ b/pkg/compute/models/loadbalancerclusters.go @@ -50,19 +50,56 @@ func init() { type SLoadbalancerCluster struct { db.SStandaloneResourceBase SZoneResourceBase + WireId string `width:"36" charset:"ascii" nullable:"true" list:"admin" create:"optional" update:"admin"` } func (man *SLoadbalancerClusterManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { zoneV := validators.NewModelIdOrNameValidator("zone", "zone", ownerId) - if err := zoneV.Validate(data); err != nil { - return nil, err + wireV := validators.NewModelIdOrNameValidator("wire", "wire", ownerId) + vs := []validators.IValidator{ + zoneV, + wireV.Optional(true), } - if zone := zoneV.Model.(*SZone); zone.ExternalId != "" { + for _, v := range vs { + if err := v.Validate(data); err != nil { + return nil, err + } + } + zone := zoneV.Model.(*SZone) + if zone.ExternalId != "" { return nil, httperrors.NewInputParameterError("allow only internal zone, got %s(%s)", zone.Name, zone.Id) } + if wireV.Model != nil { + wire := wireV.Model.(*SWire) + if wire.ZoneId != zone.Id { + return nil, httperrors.NewInputParameterError("wire zone must match zone parameter, got %s, want %s(%s)", + wire.ZoneId, zone.Name, zone.Id) + } + } return man.SStandaloneResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, data) } +func (lbc *SLoadbalancerCluster) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + wireV := validators.NewModelIdOrNameValidator("wire", "wire", lbc.GetOwnerId()) + wireV.Optional(true) + if err := wireV.Validate(data); err != nil { + return nil, err + } + if wireV.Model != nil { + wire := wireV.Model.(*SWire) + if wire.ZoneId != lbc.ZoneId { + return nil, httperrors.NewInputParameterError("zone of wire must be %s, got %s", lbc.ZoneId, wire.ZoneId) + } + var from string + if lbc.WireId != "" { + from = "from " + lbc.WireId + " " + } + log.Infof("changing wire attribute of lbcluster %s(%s) %sto %s(%s)", + lbc.Name, lbc.Id, from, wire.Name, wire.Id) + } + return lbc.SStandaloneResourceBase.ValidateUpdateData(ctx, userCred, query, data) +} + func (lbc *SLoadbalancerCluster) ValidateDeleteCondition(ctx context.Context) error { men := []db.IModelManager{ LoadbalancerManager, diff --git a/pkg/compute/regiondrivers/kvm.go b/pkg/compute/regiondrivers/kvm.go index 5ed5d51804..c3a38719aa 100644 --- a/pkg/compute/regiondrivers/kvm.go +++ b/pkg/compute/regiondrivers/kvm.go @@ -87,16 +87,40 @@ func (self *SKVMRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context if len(clusters) == 0 { return nil, httperrors.NewInputParameterError("zone %s(%s) has no lbcluster", zone.Name, zone.Id) } - if len(clusters) > 1 { - log.Warningf("found %d lbclusters, randomly select 1", len(clusters)) + var ( + wireMatched []*models.SLoadbalancerCluster + wireNeutral []*models.SLoadbalancerCluster + ) + for i := range clusters { + c := &clusters[i] + if c.WireId != "" { + if c.WireId == network.WireId { + wireMatched = append(wireMatched, c) + } + } else { + wireNeutral = append(wireNeutral, c) + } } - data.Set("cluster_id", jsonutils.NewString(clusters[0].Id)) + var choices []*models.SLoadbalancerCluster + if len(wireMatched) > 0 { + choices = wireMatched + } else if len(wireNeutral) > 0 { + choices = wireNeutral + } else { + return nil, httperrors.NewInputParameterError("no viable lbcluster") + } + i := rand.Intn(len(choices)) + data.Set("cluster_id", jsonutils.NewString(choices[i].Id)) } else { cluster := clusterV.Model.(*models.SLoadbalancerCluster) if cluster.ZoneId != zone.Id { return nil, httperrors.NewInputParameterError("cluster zone %s does not match network zone %s ", cluster.ZoneId, zone.Id) } + if cluster.WireId != "" && cluster.WireId != network.WireId { + return nil, httperrors.NewInputParameterError("cluster wire affiliation does not match network's: %s != %s", + cluster.WireId, network.WireId) + } } data.Set("cloudregion_id", jsonutils.NewString(region.GetId())) diff --git a/pkg/mcclient/modules/mod_loadbalancerclusters.go b/pkg/mcclient/modules/mod_loadbalancerclusters.go index 32796e246d..7c24d74722 100644 --- a/pkg/mcclient/modules/mod_loadbalancerclusters.go +++ b/pkg/mcclient/modules/mod_loadbalancerclusters.go @@ -31,6 +31,7 @@ func init() { "id", "name", "zone_id", + "wire_id", }, []string{}, ), diff --git a/pkg/mcclient/options/loadbalancerclusters.go b/pkg/mcclient/options/loadbalancerclusters.go index bdacc6644d..1ba30b5033 100644 --- a/pkg/mcclient/options/loadbalancerclusters.go +++ b/pkg/mcclient/options/loadbalancerclusters.go @@ -18,6 +18,13 @@ type LoadbalancerClusterCreateOptions struct { NAME string Zone string + Wire string +} + +type LoadbalancerClusterUpdateOptions struct { + ID string `json:"-"` + + Wire string } type LoadbalancerClusterListOptions struct {