diff --git a/cmd/climc/shell/compute/loadbalancers.go b/cmd/climc/shell/compute/loadbalancers.go index 130d2dba0b..4dd89d6f47 100644 --- a/cmd/climc/shell/compute/loadbalancers.go +++ b/cmd/climc/shell/compute/loadbalancers.go @@ -15,98 +15,24 @@ package compute import ( + "yunion.io/x/onecloud/cmd/climc/shell" "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/mcclient/modules" "yunion.io/x/onecloud/pkg/mcclient/options" ) func init() { - R(&options.LoadbalancerCreateOptions{}, "lb-create", "Create lb", func(s *mcclient.ClientSession, opts *options.LoadbalancerCreateOptions) error { - params, err := opts.Params() - if err != nil { - return err - } - lb, err := modules.Loadbalancers.Create(s, params) - if err != nil { - return err - } - printObject(lb) - return nil - }) - R(&options.LoadbalancerGetOptions{}, "lb-show", "Show lb", func(s *mcclient.ClientSession, opts *options.LoadbalancerGetOptions) error { - lb, err := modules.Loadbalancers.Get(s, opts.ID, nil) - if err != nil { - return err - } - printObject(lb) - return nil - }) - R(&options.LoadbalancerListOptions{}, "lb-list", "List lbs", func(s *mcclient.ClientSession, opts *options.LoadbalancerListOptions) error { - params, err := options.ListStructToParams(opts) - if err != nil { - return err - } - result, err := modules.Loadbalancers.List(s, params) - if err != nil { - return err - } - printList(result, modules.Loadbalancers.GetColumns(s)) - return nil - }) - R(&options.LoadbalancerUpdateOptions{}, "lb-update", "Update lb", func(s *mcclient.ClientSession, opts *options.LoadbalancerUpdateOptions) error { - params, err := options.StructToParams(opts) - lb, err := modules.Loadbalancers.Update(s, opts.ID, params) - if err != nil { - return err - } - printObject(lb) - return nil - }) - 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 - } - 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 { - return err - } - lb, err := modules.Loadbalancers.PerformAction(s, opts.ID, "status", params) - if err != nil { - return err - } - 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 - }) - - R(&options.LoadbalancerGetOptions{}, "lb-change-owner-candidate-domains", "Get change owner candidate domain list", func(s *mcclient.ClientSession, args *options.LoadbalancerGetOptions) error { - result, err := modules.Loadbalancers.GetSpecific(s, args.ID, "change-owner-candidate-domains", nil) - if err != nil { - return err - } - printObject(result) - return nil - }) + cmd := shell.NewResourceCmd(&modules.Loadbalancers).WithKeyword("lb") + cmd.Create(&options.LoadbalancerCreateOptions{}) + cmd.Show(&options.LoadbalancerIdOptions{}) + cmd.List(&options.LoadbalancerListOptions{}) + cmd.Update(&options.LoadbalancerUpdateOptions{}) + cmd.Delete(&options.LoadbalancerIdOptions{}) + cmd.Perform("purge", &options.LoadbalancerIdOptions{}) + cmd.Perform("status", &options.LoadbalancerActionStatusOptions{}) + cmd.Perform("syncstatus", &options.LoadbalancerIdOptions{}) + cmd.Perform("remote-update", &options.LoadbalancerRemoteUpdateOptions{}) + cmd.Get("change-owner-candidate-domains", &options.LoadbalancerIdOptions{}) R(&options.ResourceMetadataOptions{}, "lb-add-tag", "Set tag of a lb", func(s *mcclient.ClientSession, opts *options.ResourceMetadataOptions) error { params, err := opts.Params() @@ -134,17 +60,4 @@ func init() { return nil }) - R(&options.LoadbalancerRemoteUpdateOptions{}, "lb-remote-update", "Change lb status", func(s *mcclient.ClientSession, opts *options.ServerRemoteUpdateOptions) error { - params, err := options.StructToParams(opts) - if err != nil { - return err - } - lb, err := modules.Loadbalancers.PerformAction(s, opts.ID, "remote-update", params) - if err != nil { - return err - } - printObject(lb) - return nil - }) - } diff --git a/pkg/apis/compute/loadbalancer.go b/pkg/apis/compute/loadbalancer.go index 3c8dc73ebb..b5dfb1f419 100644 --- a/pkg/apis/compute/loadbalancer.go +++ b/pkg/apis/compute/loadbalancer.go @@ -74,6 +74,7 @@ type LoadbalancerListenerRuleListInput struct { type LoadbalancerListInput struct { apis.VirtualResourceListInput apis.ExternalizedResourceBaseListInput + apis.DeletePreventableResourceBaseListInput VpcFilterListInput ZonalFilterListBase diff --git a/pkg/compute/models/loadbalancers.go b/pkg/compute/models/loadbalancers.go index da9b473ec4..91ec3a2939 100644 --- a/pkg/compute/models/loadbalancers.go +++ b/pkg/compute/models/loadbalancers.go @@ -46,6 +46,7 @@ type SLoadbalancerManager struct { db.SVirtualResourceBaseManager db.SExternalizedResourceBaseManager + SDeletePreventableResourceBaseManager SVpcResourceBaseManager SZoneResourceBaseManager @@ -86,6 +87,7 @@ type SLoadbalancer struct { db.SExternalizedResourceBase SManagedResourceBase SCloudregionResourceBase + SDeletePreventableResourceBase // LB might optionally be in a VPC, vpc_id, manager_id, cloudregion_id SVpcResourceBase `width:"36" charset:"ascii" nullable:"true" list:"user" create:"optional"` @@ -152,6 +154,10 @@ func (man *SLoadbalancerManager) ListItemFilter( if err != nil { return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemFilter") } + q, err = man.SDeletePreventableResourceBaseManager.ListItemFilter(ctx, q, userCred, query.DeletePreventableResourceBaseListInput) + if err != nil { + return nil, errors.Wrap(err, "SDeletePreventableResourceBaseManager.ListItemFilter") + } vpcQuery := api.VpcFilterListInput{ VpcFilterListInputBase: query.VpcFilterListInputBase, } @@ -717,6 +723,10 @@ func (lb *SLoadbalancer) ValidateDeleteCondition(ctx context.Context) error { } } + if lb.DisableDelete.IsTrue() { + return httperrors.NewInvalidStatusError("loadbalancer is locked, cannot delete") + } + return lb.SModelBase.ValidateDeleteCondition(ctx) } diff --git a/pkg/compute/models/purge.go b/pkg/compute/models/purge.go index 8a25d1c72d..1c4bb46fef 100644 --- a/pkg/compute/models/purge.go +++ b/pkg/compute/models/purge.go @@ -303,6 +303,8 @@ func (lb *SLoadbalancer) purge(ctx context.Context, userCred mcclient.TokenCrede lockman.LockObject(ctx, lb) defer lockman.ReleaseObject(ctx, lb) + lb.DeletePreventionOff(lb, userCred) + _, err := db.UpdateWithLock(ctx, lb, func() error { //避免 purge backendgroups 时循环依赖 lb.BackendGroupId = "" diff --git a/pkg/mcclient/options/loadbalancers.go b/pkg/mcclient/options/loadbalancers.go index 5329dbf548..9892397d16 100644 --- a/pkg/mcclient/options/loadbalancers.go +++ b/pkg/mcclient/options/loadbalancers.go @@ -39,7 +39,7 @@ type LoadbalancerCreateOptions struct { Tags []string `help:"Tags info,prefix with 'user:', eg: user:project=default" json:"-"` } -func (opts *LoadbalancerCreateOptions) Params() (*jsonutils.JSONDict, error) { +func (opts *LoadbalancerCreateOptions) Params() (jsonutils.JSONObject, error) { params, err := StructToParams(opts) if err != nil { return nil, err @@ -62,18 +62,39 @@ func (opts *LoadbalancerCreateOptions) Params() (*jsonutils.JSONDict, error) { return params, nil } -type LoadbalancerGetOptions struct { +type LoadbalancerIdOptions struct { ID string `json:"-"` } +func (opts *LoadbalancerIdOptions) GetId() string { + return opts.ID +} + +func (opts *LoadbalancerIdOptions) Params() (jsonutils.JSONObject, error) { + return nil, nil +} + type LoadbalancerUpdateOptions struct { - ID string `json:"-"` + LoadbalancerIdOptions Name string + Delete string `help:"Lock server to prevent from deleting" choices:"enable|disable" json:"-"` Cluster string `json:"cluster_id"` BackendGroup string } +func (opts LoadbalancerUpdateOptions) Params() (jsonutils.JSONObject, error) { + params := jsonutils.Marshal(opts).(*jsonutils.JSONDict) + if len(opts.Delete) > 0 { + if opts.Delete == "disable" { + params.Set("disable_delete", jsonutils.JSONTrue) + } else { + params.Set("disable_delete", jsonutils.JSONFalse) + } + } + return params, nil +} + type LoadbalancerDeleteOptions struct { ID string `json:"-"` } @@ -94,20 +115,31 @@ type LoadbalancerListOptions struct { Cluster string `json:"cluster_id"` } +func (opts *LoadbalancerListOptions) Params() (jsonutils.JSONObject, error) { + return ListStructToParams(opts) +} + type LoadbalancerActionStatusOptions struct { - ID string `json:"-"` + LoadbalancerIdOptions Status string `choices:"enabled|disabled"` } +func (opts *LoadbalancerActionStatusOptions) Params() (jsonutils.JSONObject, error) { + if len(opts.Status) == 0 { + return nil, fmt.Errorf("empty status") + } + return jsonutils.Marshal(map[string]string{"status": opts.Status}), nil +} + type LoadbalancerActionSyncStatusOptions struct { ID string `json:"-"` } -type LoadbalancerIdOptions struct { - ID string `json:"-"` -} - type LoadbalancerRemoteUpdateOptions struct { - ID string `json:"-"` + LoadbalancerIdOptions computeapi.LoadbalancerRemoteUpdateInput } + +func (opts *LoadbalancerRemoteUpdateOptions) Params() (jsonutils.JSONObject, error) { + return jsonutils.Marshal(opts), nil +}