mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-10-28 03:23:25 +08:00
feat(region): support merging mutli wires to a wire
This commit is contained in:
@@ -30,6 +30,6 @@ func init() {
|
||||
cmd.Perform("public", new(options.WirePublicOptions))
|
||||
cmd.Perform("private", new(options.WireOptions))
|
||||
cmd.Perform("change-owner-candidate-domains", new(options.WireOptions))
|
||||
cmd.Perform("merge", new(options.WireMergeOptions))
|
||||
cmd.PerformWithKeyword("merge", "merge-from", new(options.WireMergeOptions))
|
||||
cmd.Perform("merge-network", new(options.WireOptions))
|
||||
}
|
||||
|
||||
@@ -101,5 +101,14 @@ type WireMergeInput struct {
|
||||
MergeNetwork bool `json:"merge_network"`
|
||||
}
|
||||
|
||||
type WireMergeFromInput struct {
|
||||
// description: wire ids or names to be merged from
|
||||
// required: true
|
||||
Sources []string `json:"sources"`
|
||||
// description: if merge networks under wire
|
||||
// required: false
|
||||
MergeNetwork bool `json:"merge_network"`
|
||||
}
|
||||
|
||||
type WireMergeNetworkInput struct {
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
"yunion.io/x/pkg/tristate"
|
||||
"yunion.io/x/pkg/util/compare"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
"yunion.io/x/pkg/util/sets"
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
@@ -995,11 +996,87 @@ func (w *SWire) PerformMergeNetwork(ctx context.Context, userCred mcclient.Token
|
||||
return nil, w.StartMergeNetwork(ctx, userCred, "")
|
||||
}
|
||||
|
||||
func (w *SWire) AllowPerformMerge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
|
||||
return w.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, w, "merge")
|
||||
func (sm *SWireManager) FetchByIdsOrNames(idOrNames []string) ([]SWire, error) {
|
||||
if len(idOrNames) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
q := sm.Query("")
|
||||
if len(idOrNames) == 1 {
|
||||
q.Filter(sqlchemy.OR(sqlchemy.Equals(q.Field("id"), idOrNames[0]), sqlchemy.Equals(q.Field("name"), idOrNames[0])))
|
||||
} else {
|
||||
q.Filter(sqlchemy.OR(sqlchemy.In(q.Field("id"), idOrNames[0]), sqlchemy.In(q.Field("name"), idOrNames[0])))
|
||||
}
|
||||
ret := make([]SWire, 0, len(idOrNames))
|
||||
err := db.FetchModelObjects(sm, q, &ret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (w *SWire) PerformMerge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.WireMergeInput) (ret jsonutils.JSONObject, err error) {
|
||||
func (w *SWire) AllowPerformMergeFrom(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
|
||||
return w.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, w, "merge-from")
|
||||
}
|
||||
|
||||
func (w *SWire) PerformMergeFrom(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.WireMergeFromInput) (ret jsonutils.JSONObject, err error) {
|
||||
if len(input.Sources) == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("sources")
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
logclient.AddActionLogWithContext(ctx, w, logclient.ACT_MERGE, err.Error(), userCred, false)
|
||||
}
|
||||
}()
|
||||
|
||||
wires, err := WireManager.FetchByIdsOrNames(input.Sources)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
wireIdOrNameSet := sets.NewString(input.Sources...)
|
||||
for i := range wires {
|
||||
id, name := wires[i].GetId(), wires[i].GetName()
|
||||
if wireIdOrNameSet.Has(id) {
|
||||
wireIdOrNameSet.Delete(id)
|
||||
continue
|
||||
}
|
||||
if wireIdOrNameSet.Has(name) {
|
||||
wireIdOrNameSet.Delete(name)
|
||||
}
|
||||
}
|
||||
if wireIdOrNameSet.Len() > 0 {
|
||||
return nil, httperrors.NewInputParameterError("invalid wire id or name %v", wireIdOrNameSet.UnsortedList())
|
||||
}
|
||||
|
||||
lockman.LockClass(ctx, WireManager, db.GetLockClassKey(WireManager, userCred))
|
||||
defer lockman.ReleaseClass(ctx, WireManager, db.GetLockClassKey(WireManager, userCred))
|
||||
|
||||
for _, tw := range wires {
|
||||
err = WireManager.handleWireIdChange(ctx, &wireIdChangeArgs{
|
||||
oldWire: &tw,
|
||||
newWire: w,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "unable to merge wire %s to %s", tw.GetId(), w.GetId())
|
||||
}
|
||||
if err = tw.Delete(ctx, userCred); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
logclient.AddActionLogWithContext(ctx, w, logclient.ACT_MERGE_FROM, "", userCred, true)
|
||||
if input.MergeNetwork {
|
||||
err = w.StartMergeNetwork(ctx, userCred, "")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unableto StartMergeNetwork")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (w *SWire) AllowPerformMergeTo(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
|
||||
return w.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, w, "merge-to")
|
||||
}
|
||||
|
||||
func (w *SWire) PerformMergeTo(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.WireMergeInput) (ret jsonutils.JSONObject, err error) {
|
||||
if len(input.Target) == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("target")
|
||||
}
|
||||
@@ -1033,7 +1110,7 @@ func (w *SWire) PerformMerge(ctx context.Context, userCred mcclient.TokenCredent
|
||||
return nil, err
|
||||
}
|
||||
if input.MergeNetwork {
|
||||
err = w.StartMergeNetwork(ctx, userCred, "")
|
||||
err = tw.StartMergeNetwork(ctx, userCred, "")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unableto StartMergeNetwork")
|
||||
}
|
||||
|
||||
@@ -91,13 +91,13 @@ func (wo *WirePublicOptions) Params() (jsonutils.JSONObject, error) {
|
||||
}
|
||||
|
||||
type WireMergeOptions struct {
|
||||
FROM string `help:"ID or name of merge wire from"`
|
||||
TARGET string `help:"ID or name of merge wire target"`
|
||||
MergeNetwork bool `help:"whether to merge network under wire"`
|
||||
Froms []string `help:"IDs or names of merge wire from" json:"sources"`
|
||||
TARGET string `help:"ID or name of merge wire target"`
|
||||
MergeNetwork bool `help:"whether to merge network under wire"`
|
||||
}
|
||||
|
||||
func (wo *WireMergeOptions) GetId() string {
|
||||
return wo.FROM
|
||||
return wo.TARGET
|
||||
}
|
||||
|
||||
func (wo *WireMergeOptions) Params() (jsonutils.JSONObject, error) {
|
||||
|
||||
@@ -35,6 +35,7 @@ const (
|
||||
ACT_GUEST_ATTACH_ISOLATED_DEVICE = "guest_attach_isolated_device"
|
||||
ACT_GUEST_DETACH_ISOLATED_DEVICE = "guest_detach_isolated_device"
|
||||
ACT_MERGE = "merge"
|
||||
ACT_MERGE_FROM = "merge_from"
|
||||
ACT_OFFLINE = "offline"
|
||||
ACT_ONLINE = "online"
|
||||
ACT_PRIVATE = "private"
|
||||
|
||||
Reference in New Issue
Block a user