Merge pull request #8445 from swordqiu/lvyangyang-lyy/resource_tag

resource tags
This commit is contained in:
yunion-ci-robot
2020-10-22 22:43:16 +08:00
committed by GitHub
33 changed files with 707 additions and 25 deletions
+44
View File
@@ -20,6 +20,7 @@ import (
"yunion.io/x/jsonutils"
computeapi "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
"yunion.io/x/onecloud/pkg/mcclient/modules"
@@ -371,4 +372,47 @@ func init() {
return nil
})
R(&options.ResourceMetadataOptions{}, "dbinstance-add-tag", "Set tag of a dbinstance", func(s *mcclient.ClientSession, opts *options.ResourceMetadataOptions) error {
params, err := opts.Params()
if err != nil {
return err
}
result, err := modules.DBInstance.PerformAction(s, opts.ID, "user-metadata", params)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&options.ResourceMetadataOptions{}, "dbinstance-set-tag", "Set tag of a dbinstance", func(s *mcclient.ClientSession, opts *options.ResourceMetadataOptions) error {
params, err := opts.Params()
if err != nil {
return err
}
result, err := modules.DBInstance.PerformAction(s, opts.ID, "set-user-metadata", params)
if err != nil {
return err
}
printObject(result)
return nil
})
type DBInstanceRemoteUpdateOptions struct {
ID string `json:"-"`
computeapi.DBInstanceRemoteUpdateInput
}
R(&DBInstanceRemoteUpdateOptions{}, "dbinstance-remote-update", "Change owner porject of a dbinstance", func(s *mcclient.ClientSession, opts *DBInstanceRemoteUpdateOptions) error {
params, err := options.StructToParams(opts)
if err != nil {
return err
}
result, err := modules.DBInstance.PerformAction(s, opts.ID, "remote-update", params)
if err != nil {
return err
}
printObject(result)
return nil
})
}
+40
View File
@@ -393,4 +393,44 @@ func init() {
printList(result, nil)
return nil
})
R(&options.ResourceMetadataOptions{}, "elastic-cache-add-tag", "Set tag of a server", func(s *mcclient.ClientSession, opts *options.ResourceMetadataOptions) error {
params, err := opts.Params()
if err != nil {
return err
}
result, err := modules.ElasticCache.PerformAction(s, opts.ID, "user-metadata", params)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&options.ResourceMetadataOptions{}, "elastic-cache-set-tag", "Set tag of a server", func(s *mcclient.ClientSession, opts *options.ResourceMetadataOptions) error {
params, err := opts.Params()
if err != nil {
return err
}
result, err := modules.ElasticCache.PerformAction(s, opts.ID, "set-user-metadata", params)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&options.ElasticCacheRemoteUpdateOptions{}, "elastic-cache-remote-update", "Restore elastisc cache backup", func(s *mcclient.ClientSession, opts *options.ElasticCacheRemoteUpdateOptions) error {
params, err := options.StructToParams(opts)
if err != nil {
return err
}
result, err := modules.ElasticCache.PerformAction(s, opts.ID, "remote-update", params)
if err != nil {
return err
}
printObject(result)
return nil
})
}
+39
View File
@@ -108,4 +108,43 @@ func init() {
return nil
})
R(&options.ResourceMetadataOptions{}, "lb-add-tag", "Set tag of a lb", func(s *mcclient.ClientSession, opts *options.ResourceMetadataOptions) error {
params, err := opts.Params()
if err != nil {
return err
}
result, err := modules.Loadbalancers.PerformAction(s, opts.ID, "user-metadata", params)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&options.ResourceMetadataOptions{}, "lb-set-tag", "Set tag of a lb", func(s *mcclient.ClientSession, opts *options.ResourceMetadataOptions) error {
params, err := opts.Params()
if err != nil {
return err
}
result, err := modules.Loadbalancers.PerformAction(s, opts.ID, "set-user-metadata", params)
if err != nil {
return err
}
printObject(result)
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
})
}
+5
View File
@@ -346,3 +346,8 @@ type DBInstanceNetworkListInput struct {
apis.VirtualJointResourceBaseListInput
DBInstanceFilterListInput
}
type DBInstanceRemoteUpdateInput struct {
// 是否覆盖替换所有标签
ReplaceTags *bool `json:"replace_tags" help:"replace all remote tags"`
}
+5
View File
@@ -94,3 +94,8 @@ type ElasticcacheParameterDetails struct {
type ElasticcacheSyncstatusInput struct {
}
type ElasticcacheRemoteUpdateInput struct {
// 是否覆盖替换所有标签
ReplaceTags *bool `json:"replace_tags" help:"replace all remote tags"`
}
+5
View File
@@ -269,3 +269,8 @@ type LoadbalancerCreateInput struct {
CloudproviderResourceInput
// Manager string `json:"manager"`
}
type LoadbalancerRemoteUpdateInput struct {
// 是否覆盖替换所有标签
ReplaceTags *bool `json:"replace_tags" help:"replace all remote tags"`
}
+1
View File
@@ -30,4 +30,5 @@ type SLoadbalancer struct {
EgressMbps int
billingCycle *billing.SBillingCycle
ProjectId string
Tags map[string]string
}
+6
View File
@@ -530,6 +530,8 @@ type ICloudLoadbalancer interface {
CreateILoadBalancerListener(ctx context.Context, listener *SLoadbalancerListener) (ICloudLoadbalancerListener, error)
GetILoadBalancerListenerById(listenerId string) (ICloudLoadbalancerListener, error)
SetMetadata(tags map[string]string, replace bool) error
}
type ICloudLoadbalancerListener interface {
@@ -802,6 +804,8 @@ type ICloudDBInstance interface {
RecoveryFromBackup(conf *SDBInstanceRecoveryConfig) error
Delete() error
SetMetadata(tags map[string]string, replace bool) error
}
type ICloudDBInstanceParameter interface {
@@ -906,6 +910,8 @@ type ICloudElasticcache interface {
UpdateAuthMode(noPasswordAccess bool) error
UpdateInstanceParameters(config jsonutils.JSONObject) error
UpdateBackupPolicy(config SCloudElasticCacheBackupPolicyUpdateInput) error
SetMetadata(tags map[string]string, replace bool) error
}
type ICloudElasticcacheAccount interface {
+37
View File
@@ -464,6 +464,7 @@ func (man *SDBInstanceManager) ValidateCreateData(ctx context.Context, userCred
}
func (self *SDBInstance) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
self.SVirtualResourceBase.PostCreate(ctx, userCred, ownerId, query, data)
pendingUsage := SRegionQuota{Loadbalancer: 1}
pendingUsage.SetKeys(self.GetQuotaKeys())
err := quotas.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage, true)
@@ -1875,3 +1876,39 @@ func (self *SDBInstance) CancelExpireTime(ctx context.Context, userCred mcclient
db.OpsLog.LogEvent(self, db.ACT_RENEW, "dbinstance cancel expire time", userCred)
return nil
}
func (self *SDBInstance) AllowPerformRemoteUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "remote-update")
}
func (self *SDBInstance) PerformRemoteUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.DBInstanceRemoteUpdateInput) (jsonutils.JSONObject, error) {
err := self.StartRemoteUpdateTask(ctx, userCred, (input.ReplaceTags != nil && *input.ReplaceTags), "")
if err != nil {
return nil, errors.Wrap(err, "StartRemoteUpdateTask")
}
return nil, nil
}
func (self *SDBInstance) StartRemoteUpdateTask(ctx context.Context, userCred mcclient.TokenCredential, replaceTags bool, parentTaskId string) error {
data := jsonutils.NewDict()
if replaceTags {
data.Add(jsonutils.JSONTrue, "replace_tags")
}
if task, err := taskman.TaskManager.NewTask(ctx, "DBInstanceRemoteUpdateTask", self, userCred, data, parentTaskId, "", nil); err != nil {
log.Errorln(err)
return errors.Wrap(err, "Start ElasticcacheRemoteUpdateTask")
} else {
task.ScheduleRun(nil)
}
return nil
}
func (self *SDBInstance) OnMetadataUpdated(ctx context.Context, userCred mcclient.TokenCredential) {
if len(self.ExternalId) == 0 {
return
}
err := self.StartRemoteUpdateTask(ctx, userCred, false, "")
if err != nil {
log.Errorf("StartRemoteUpdateTask fail: %s", err)
}
}
@@ -1713,3 +1713,39 @@ func (self *SElasticcache) CancelExpireTime(ctx context.Context, userCred mcclie
db.OpsLog.LogEvent(self, db.ACT_RENEW, "elasticcache cancel expire time", userCred)
return nil
}
func (self *SElasticcache) AllowPerformRemoteUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "remote-update")
}
func (self *SElasticcache) PerformRemoteUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.ElasticcacheRemoteUpdateInput) (jsonutils.JSONObject, error) {
err := self.StartRemoteUpdateTask(ctx, userCred, (input.ReplaceTags != nil && *input.ReplaceTags), "")
if err != nil {
return nil, errors.Wrap(err, "StartRemoteUpdateTask")
}
return nil, nil
}
func (self *SElasticcache) StartRemoteUpdateTask(ctx context.Context, userCred mcclient.TokenCredential, replaceTags bool, parentTaskId string) error {
data := jsonutils.NewDict()
if replaceTags {
data.Add(jsonutils.JSONTrue, "replace_tags")
}
if task, err := taskman.TaskManager.NewTask(ctx, "ElasticcacheRemoteUpdateTask", self, userCred, data, parentTaskId, "", nil); err != nil {
log.Errorln(err)
return errors.Wrap(err, "Start ElasticcacheRemoteUpdateTask")
} else {
task.ScheduleRun(nil)
}
return nil
}
func (self *SElasticcache) OnMetadataUpdated(ctx context.Context, userCred mcclient.TokenCredential) {
if len(self.ExternalId) == 0 {
return
}
err := self.StartRemoteUpdateTask(ctx, userCred, false, "")
if err != nil {
log.Errorf("StartRemoteUpdateTask fail: %s", err)
}
}
+37
View File
@@ -454,6 +454,7 @@ func (lb *SLoadbalancer) GetCreateLoadbalancerParams(iRegion cloudprovider.IClou
ChargeType: lb.ChargeType,
LoadbalancerSpec: lb.LoadbalancerSpec,
}
params.Tags, _ = lb.GetAllUserMetadata()
if len(lb.ZoneId) > 0 {
zone := lb.GetZone()
@@ -1221,3 +1222,39 @@ func (manager *SLoadbalancerManager) ListItemExportKeys(ctx context.Context,
func (self *SLoadbalancer) GetChangeOwnerCandidateDomainIds() []string {
return self.SManagedResourceBase.GetChangeOwnerCandidateDomainIds()
}
func (self *SLoadbalancer) AllowPerformRemoteUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "remote-update")
}
func (self *SLoadbalancer) PerformRemoteUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.LoadbalancerRemoteUpdateInput) (jsonutils.JSONObject, error) {
err := self.StartRemoteUpdateTask(ctx, userCred, (input.ReplaceTags != nil && *input.ReplaceTags), "")
if err != nil {
return nil, errors.Wrap(err, "StartRemoteUpdateTask")
}
return nil, nil
}
func (guest *SLoadbalancer) StartRemoteUpdateTask(ctx context.Context, userCred mcclient.TokenCredential, replaceTags bool, parentTaskId string) error {
data := jsonutils.NewDict()
if replaceTags {
data.Add(jsonutils.JSONTrue, "replace_tags")
}
if task, err := taskman.TaskManager.NewTask(ctx, "LoadbalancerRemoteUpdateTask", guest, userCred, data, parentTaskId, "", nil); err != nil {
log.Errorln(err)
return errors.Wrap(err, "Start LoadbalancerRemoteUpdateTask")
} else {
task.ScheduleRun(nil)
}
return nil
}
func (guest *SLoadbalancer) OnMetadataUpdated(ctx context.Context, userCred mcclient.TokenCredential) {
if len(guest.ExternalId) == 0 {
return
}
err := guest.StartRemoteUpdateTask(ctx, userCred, false, "")
if err != nil {
log.Errorf("StartRemoteUpdateTask fail: %s", err)
}
}
+5
View File
@@ -46,6 +46,7 @@ type IRegionDriver interface {
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
RequestRemoteUpdateLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *SLoadbalancer, replaceTags bool, 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 *SCachedLoadbalancerAcl, task taskman.ITask) error
@@ -167,6 +168,8 @@ type IDBInstanceDriver interface {
IsDBInstanceNeedSecgroup() bool
ValidateDBInstanceRecovery(ctx context.Context, userCred mcclient.TokenCredential, instance *SDBInstance, backup *SDBInstanceBackup, input api.SDBInstanceRecoveryConfigInput) error
RequestRemoteUpdateDBInstance(ctx context.Context, userCred mcclient.TokenCredential, instance *SDBInstance, replaceTags bool, task taskman.ITask) error
}
type IElasticcacheDriver interface {
@@ -198,6 +201,8 @@ type IElasticcacheDriver interface {
RequestElasticcacheUpdateBackupPolicy(ctx context.Context, userCred mcclient.TokenCredential, elasticcache *SElasticcache, task taskman.ITask) error
RequestSyncElasticcacheStatus(ctx context.Context, userCred mcclient.TokenCredential, elasticcache *SElasticcache, task taskman.ITask) error
RequestRemoteUpdateElasticcache(ctx context.Context, userCred mcclient.TokenCredential, elasticcache *SElasticcache, replaceTags bool, task taskman.ITask) error
}
type IElasticcacheAccount interface {
+15
View File
@@ -52,6 +52,11 @@ func (self *SBaseRegionDriver) RequestSyncstatusLoadbalancer(ctx context.Context
return fmt.Errorf("Not Implement RequestSyncstatusLoadbalancer")
}
func (self *SBaseRegionDriver) RequestRemoteUpdateLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, replaceTags bool, task taskman.ITask) error {
// nil ops
return nil
}
func (self *SBaseRegionDriver) RequestDeleteLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error {
return fmt.Errorf("Not Implement RequestDeleteLoadbalancer")
}
@@ -346,6 +351,11 @@ func (self *SBaseRegionDriver) ValidateDBInstanceRecovery(ctx context.Context, u
return errors.Wrap(cloudprovider.ErrNotImplemented, "ValidateDBInstanceRecovery")
}
func (self *SBaseRegionDriver) RequestRemoteUpdateDBInstance(ctx context.Context, userCred mcclient.TokenCredential, instance *models.SDBInstance, replaceTags bool, task taskman.ITask) error {
// nil ops
return nil
}
func (self *SBaseRegionDriver) IsSupportedDBInstance() bool {
return false
}
@@ -378,6 +388,11 @@ func (self *SBaseRegionDriver) RequestSyncElasticcacheStatus(ctx context.Context
return fmt.Errorf("Not Implement RequestSyncElasticcacheStatus")
}
func (self *SBaseRegionDriver) RequestRemoteUpdateElasticcache(ctx context.Context, userCred mcclient.TokenCredential, elasticcache *models.SElasticcache, replaceTags bool, task taskman.ITask) error {
// nil ops
return nil
}
func (self *SBaseRegionDriver) IsDBInstanceNeedSecgroup() bool {
return false
}
@@ -265,6 +265,36 @@ func (self *SManagedVirtualizationRegionDriver) RequestSyncstatusLoadbalancer(ct
return nil
}
func (self *SManagedVirtualizationRegionDriver) RequestRemoteUpdateLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, replaceTags bool, 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
}
tags, err := lb.GetAllUserMetadata()
if err != nil {
log.Errorf("GetAllUserMetadata fail %s", err)
} else {
err := iLoadbalancer.SetMetadata(tags, replaceTags)
if err != nil {
return nil, errors.Wrap(err, "iLoadbalancer.SetMetadata")
}
// sync back cloud metadata
err = models.SyncVirtualResourceMetadata(ctx, userCred, lb, iLoadbalancer)
if err != nil {
return nil, errors.Wrap(err, "syncVirtualResourceMetadata")
}
}
return nil, nil
})
// nil ops
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) {
@@ -2367,6 +2397,32 @@ func (self *SManagedVirtualizationRegionDriver) ValidateResetDBInstancePassword(
return nil
}
func (self *SManagedVirtualizationRegionDriver) RequestRemoteUpdateDBInstance(ctx context.Context, userCred mcclient.TokenCredential, instance *models.SDBInstance, replaceTags bool, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
iRds, err := instance.GetIDBInstance()
if err != nil {
return nil, errors.Wrap(err, "instance.GetIDBInstance")
}
tags, err := instance.GetAllUserMetadata()
if err != nil {
log.Errorf("GetAllUserMetadata fail %s", err)
} else {
err := iRds.SetMetadata(tags, replaceTags)
if err != nil {
return nil, errors.Wrap(err, "iRds.SetMetadata")
}
// sync back cloud metadata
err = models.SyncVirtualResourceMetadata(ctx, userCred, instance, iRds)
if err != nil {
return nil, errors.Wrap(err, "syncVirtualResourceMetadata")
}
}
return nil, nil
})
// nil ops
return nil
}
func (self *SManagedVirtualizationRegionDriver) RequestCreateElasticcacheBackup(ctx context.Context, userCred mcclient.TokenCredential, eb *models.SElasticcacheBackup, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
_ec, err := db.FetchById(models.ElasticcacheManager, eb.ElasticcacheId)
@@ -2736,3 +2792,31 @@ func (self *SManagedVirtualizationRegionDriver) RequestSyncElasticcacheStatus(ct
})
return nil
}
func (self *SManagedVirtualizationRegionDriver) RequestRemoteUpdateElasticcache(ctx context.Context, userCred mcclient.TokenCredential, elasticcache *models.SElasticcache, replaceTags bool, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
iRegion, err := elasticcache.GetIRegion()
if err != nil {
return nil, errors.Wrap(err, "elasticcache.GetIRegion")
}
iElasticcache, err := iRegion.GetIElasticcacheById(elasticcache.ExternalId)
tags, err := elasticcache.GetAllUserMetadata()
if err != nil {
log.Errorf("GetAllUserMetadata fail %s", err)
} else {
err := iElasticcache.SetMetadata(tags, replaceTags)
if err != nil {
return nil, errors.Wrap(err, "iElasticcache.SetMetadata")
}
// sync back cloud metadata
err = models.SyncVirtualResourceMetadata(ctx, userCred, elasticcache, iElasticcache)
if err != nil {
return nil, errors.Wrap(err, "syncVirtualResourceMetadata")
}
}
return nil, nil
})
// nil ops
return nil
}
@@ -0,0 +1,56 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type DBInstanceRemoteUpdateTask struct {
SGuestBaseTask
}
func init() {
taskman.RegisterTask(DBInstanceRemoteUpdateTask{})
}
func (self *DBInstanceRemoteUpdateTask) taskFail(ctx context.Context, lb *models.SDBInstance, reason jsonutils.JSONObject) {
logclient.AddActionLogWithStartable(self, lb, logclient.ACT_ENABLE, reason, self.UserCred, false)
notifyclient.NotifySystemErrorWithCtx(ctx, lb.Id, lb.Name, api.LB_STATUS_DISABLED, reason.String())
self.SetStageFailed(ctx, reason)
}
func (self *DBInstanceRemoteUpdateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
instance := obj.(*models.SDBInstance)
self.SetStage("OnRemoteUpdateComplete", nil)
replaceTags := jsonutils.QueryBoolean(self.Params, "replace_tags", false)
if err := instance.GetRegion().GetDriver().RequestRemoteUpdateDBInstance(ctx, self.GetUserCred(), instance, replaceTags, self); err != nil {
self.taskFail(ctx, instance, jsonutils.Marshal(err))
}
}
func (self *DBInstanceRemoteUpdateTask) OnRemoteUpdateComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,62 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type ElasticcacheRemoteUpdateTask struct {
SGuestBaseTask
}
func init() {
taskman.RegisterTask(ElasticcacheRemoteUpdateTask{})
}
func (self *ElasticcacheRemoteUpdateTask) taskFail(ctx context.Context, elasticcache *models.SElasticcache, reason jsonutils.JSONObject) {
logclient.AddActionLogWithStartable(self, elasticcache, logclient.ACT_ENABLE, reason, self.UserCred, false)
notifyclient.NotifySystemErrorWithCtx(ctx, elasticcache.Id, elasticcache.Name, api.LB_STATUS_DISABLED, reason.String())
self.SetStageFailed(ctx, reason)
}
func (self *ElasticcacheRemoteUpdateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
ec := obj.(*models.SElasticcache)
region := ec.GetRegion()
if region == nil {
self.taskFail(ctx, ec, jsonutils.NewString(fmt.Sprintf("failed to find region for elastic cache %s", ec.GetName())))
return
}
self.SetStage("OnRemoteUpdateComplete", nil)
replaceTags := jsonutils.QueryBoolean(self.Params, "replace_tags", false)
if err := region.GetDriver().RequestRemoteUpdateElasticcache(ctx, self.GetUserCred(), ec, replaceTags, self); err != nil {
self.taskFail(ctx, ec, jsonutils.Marshal(err))
}
}
func (self *ElasticcacheRemoteUpdateTask) OnRemoteUpdateComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,62 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type LoadbalancerRemoteUpdateTask struct {
SGuestBaseTask
}
func init() {
taskman.RegisterTask(LoadbalancerRemoteUpdateTask{})
}
func (self *LoadbalancerRemoteUpdateTask) taskFail(ctx context.Context, lb *models.SLoadbalancer, reason jsonutils.JSONObject) {
logclient.AddActionLogWithStartable(self, lb, logclient.ACT_ENABLE, reason, self.UserCred, false)
notifyclient.NotifySystemErrorWithCtx(ctx, lb.Id, lb.Name, api.LB_STATUS_DISABLED, reason.String())
self.SetStageFailed(ctx, reason)
}
func (self *LoadbalancerRemoteUpdateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
lb := obj.(*models.SLoadbalancer)
region := lb.GetRegion()
if region == nil {
self.taskFail(ctx, lb, jsonutils.NewString(fmt.Sprintf("failed to find region for lb %s", lb.Name)))
return
}
self.SetStage("OnRemoteUpdateComplete", nil)
replaceTags := jsonutils.QueryBoolean(self.Params, "replace_tags", false)
if err := region.GetDriver().RequestRemoteUpdateLoadbalancer(ctx, self.GetUserCred(), lb, replaceTags, self); err != nil {
self.taskFail(ctx, lb, jsonutils.Marshal(err))
}
}
func (self *LoadbalancerRemoteUpdateTask) OnRemoteUpdateComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
self.SetStageComplete(ctx, nil)
}
+7
View File
@@ -14,6 +14,8 @@
package options
import computeapi "yunion.io/x/onecloud/pkg/apis/compute"
type ElasticCacheCreateOptions struct {
NAME string
Manager string
@@ -63,3 +65,8 @@ type ElasticCacheParameterUpdateOptions struct {
type ElasticCacheIdOptions struct {
ID string
}
type ElasticCacheRemoteUpdateOptions struct {
ID string `json:"-"`
computeapi.ElasticcacheRemoteUpdateInput
}
+10
View File
@@ -14,6 +14,10 @@
package options
import (
computeapi "yunion.io/x/onecloud/pkg/apis/compute"
)
type LoadbalancerCreateOptions struct {
NAME string
Network string
@@ -26,6 +30,7 @@ type LoadbalancerCreateOptions struct {
Zone1 string `json:"zone_1" help:"slave zone 1"`
Cluster string `json:"cluster_id"`
Manager string
Meta map[string]string `json:"__meta__"`
}
type LoadbalancerGetOptions struct {
@@ -72,3 +77,8 @@ type LoadbalancerActionSyncStatusOptions struct {
type LoadbalancerIdOptions struct {
ID string `json:"-"`
}
type LoadbalancerRemoteUpdateOptions struct {
ID string `json:"-"`
computeapi.LoadbalancerRemoteUpdateInput
}
+18
View File
@@ -775,3 +775,21 @@ func (region *SRegion) RenewDBInstance(instanceId string, bc billing.SBillingCyc
_, err := region.rdsRequest("RenewInstance", params)
return err
}
func (rds *SDBInstance) GetMetadata() *jsonutils.JSONDict {
data := jsonutils.NewDict()
tags, err := rds.region.ListResourceTags("rds", "INSTANCE", []string{rds.GetId()})
if err != nil {
log.Errorf(`[err:%s]rds.region.FetchResourceTags("slb", "instance", []string{rds.GetId()})`, err.Error())
return nil
}
if _, ok := tags[rds.GetId()]; !ok {
return nil
}
data.Update(jsonutils.Marshal(tags[rds.GetId()]))
return data
}
func (rds *SDBInstance) SetMetadata(tags map[string]string, replace bool) error {
return rds.region.SetResourceTags("rds", "INSTANCE", []string{rds.GetId()}, tags, replace)
}
@@ -911,3 +911,21 @@ func (self *SElasticcache) GetICloudElasticcacheBackup(backupId string) (cloudpr
return nil, cloudprovider.ErrNotFound
}
func (instance *SElasticcache) GetMetadata() *jsonutils.JSONDict {
data := jsonutils.NewDict()
tags, err := instance.region.ListResourceTags("kvs", "INSTANCE", []string{instance.GetId()})
if err != nil {
log.Errorf(`[err:%s]instance.region.FetchResourceTags("kvs", "instance", []string{instance.GetId()})`, err.Error())
return nil
}
if _, ok := tags[instance.GetId()]; !ok {
return nil
}
data.Update(jsonutils.Marshal(tags[instance.GetId()]))
return data
}
func (instance *SElasticcache) SetMetadata(tags map[string]string, replace bool) error {
return instance.region.SetResourceTags("kvs", "INSTANCE", []string{instance.GetId()}, tags, replace)
}
+1 -1
View File
@@ -1077,5 +1077,5 @@ func (self *SInstance) SetAutoRenew(autoRenew bool) error {
}
func (self *SInstance) SetMetadata(tags map[string]string, replace bool) error {
return self.host.zone.region.SetResourceTags("instance", []string{self.InstanceId}, tags, replace)
return self.host.zone.region.SetResourceTags("ecs", "instance", []string{self.InstanceId}, tags, replace)
}
+15 -1
View File
@@ -103,7 +103,17 @@ func (lb *SLoadbalancer) GetStatus() string {
}
func (lb *SLoadbalancer) GetMetadata() *jsonutils.JSONDict {
return nil
data := jsonutils.NewDict()
tags, err := lb.region.ListResourceTags("slb", "instance", []string{lb.GetId()})
if err != nil {
log.Errorf(`[err:%s]lb.region.FetchResourceTags("slb", "instance", []string{lb.GetId()})`, err.Error())
return nil
}
if _, ok := tags[lb.GetId()]; !ok {
return nil
}
data.Update(jsonutils.Marshal(tags[lb.GetId()]))
return data
}
func (lb *SLoadbalancer) GetAddress() string {
@@ -396,3 +406,7 @@ func (lb *SLoadbalancer) GetILoadBalancerListeners() ([]cloudprovider.ICloudLoad
func (lb *SLoadbalancer) GetProjectId() string {
return lb.ResourceGroupId
}
func (lb *SLoadbalancer) SetMetadata(tags map[string]string, replace bool) error {
return lb.region.SetResourceTags("slb", "instance", []string{lb.LoadBalancerId}, tags, replace)
}
+15
View File
@@ -140,6 +140,21 @@ func (self *SRegion) kvsRequest(action string, params map[string]string) (jsonut
return jsonRequest(client, "r-kvstore.aliyuncs.com", ALIYUN_API_VERSION_KVS, action, params, self.client.debug)
}
func (self *SRegion) tagRequest(serviceType string, action string, params map[string]string) (jsonutils.JSONObject, error) {
switch serviceType {
case "ecs":
return self.ecsRequest(action, params)
case "rds":
return self.rdsRequest(action, params)
case "slb":
return self.lbRequest(action, params)
case "kvs":
return self.kvsRequest(action, params)
default:
return nil, errors.Wrapf(errors.ErrNotSupported, "not support %service tag", serviceType)
}
}
type LBRegion struct {
RegionEndpoint string
RegionId string
+20 -20
View File
@@ -30,7 +30,7 @@ type STagResource struct {
TagKey string `json:"TagKey"`
}
func (self *SRegion) rawListTagResources(resourceType string, resIds []string, token string) ([]STagResource, string, error) {
func (self *SRegion) rawListTagResources(serviceType string, resourceType string, resIds []string, token string) ([]STagResource, string, error) {
if len(resIds) > 50 {
return nil, "", errors.Wrap(cloudprovider.ErrNotSupported, "resource count exceed 50 for one request")
}
@@ -42,9 +42,9 @@ func (self *SRegion) rawListTagResources(resourceType string, resIds []string, t
if len(token) != 0 {
params["NextToken"] = token
}
ret, err := self.ecsRequest("ListTagResources", params)
ret, err := self.tagRequest(serviceType, "ListTagResources", params)
if err != nil {
return nil, "", errors.Wrapf(err, `self.ecsRequest("ListTagResources", %s)`, jsonutils.Marshal(params).String())
return nil, "", errors.Wrapf(err, `self.tagRequest(%s,"ListTagResources", %s)`, serviceType, jsonutils.Marshal(params).String())
}
tagResources := []STagResource{}
err = ret.Unmarshal(&tagResources, "TagResources", "TagResource")
@@ -85,14 +85,14 @@ func splitTags(tags map[string]string, stride int) []map[string]string {
return tagsGroups
}
func (self *SRegion) ListResourceTags(resourceType string, resIds []string) (map[string]*map[string]string, error) {
func (self *SRegion) ListResourceTags(serviceType string, resourceType string, resIds []string) (map[string]*map[string]string, error) {
tags := make(map[string]*map[string]string)
tagReources := []STagResource{}
nextToken := ""
resIdsGroups := splitStringSlice(resIds, 50)
for i := range resIdsGroups {
for {
_tagResource, nextToken, err := self.rawListTagResources(resourceType, resIdsGroups[i], nextToken)
_tagResource, nextToken, err := self.rawListTagResources(serviceType, resourceType, resIdsGroups[i], nextToken)
if err != nil {
return nil, errors.Wrapf(err, "self.rawListTagResources(%s,%s,%s)", resourceType, resIds, nextToken)
}
@@ -117,7 +117,7 @@ func (self *SRegion) ListResourceTags(resourceType string, resIds []string) (map
return tags, nil
}
func (self *SRegion) rawTagResources(resourceType string, resIds []string, tags map[string]string) error {
func (self *SRegion) rawTagResources(serviceType string, resourceType string, resIds []string, tags map[string]string) error {
if len(resIds) > 50 {
return errors.Wrap(cloudprovider.ErrNotSupported, "resource count exceed 50 for one request")
}
@@ -135,14 +135,14 @@ func (self *SRegion) rawTagResources(resourceType string, resIds []string, tags
params[fmt.Sprintf("Tag.%d.Value", i+1)] = v
i++
}
_, err := self.ecsRequest("TagResources", params)
_, err := self.tagRequest(serviceType, "TagResources", params)
if err != nil {
return errors.Wrapf(err, `self.ecsRequest("TagResources", %s)`, jsonutils.Marshal(params).String())
return errors.Wrapf(err, `self.tagRequest(%s,"TagResources", %s)`, serviceType, jsonutils.Marshal(params).String())
}
return nil
}
func (self *SRegion) TagResources(resourceType string, resIds []string, tags map[string]string) error {
func (self *SRegion) TagResources(serviceType string, resourceType string, resIds []string, tags map[string]string) error {
if len(resIds) == 0 || len(tags) == 0 {
return nil
}
@@ -150,7 +150,7 @@ func (self *SRegion) TagResources(resourceType string, resIds []string, tags map
tagsGroups := splitTags(tags, 20)
for i := range resIdsGroups {
for j := range tagsGroups {
err := self.rawTagResources(resourceType, resIdsGroups[i], tagsGroups[j])
err := self.rawTagResources(serviceType, resourceType, resIdsGroups[i], tagsGroups[j])
if err != nil {
return errors.Wrapf(err, "self.rawTagResources(resourceType, resIdsGroups[i], tagsGroups[i])")
}
@@ -159,7 +159,7 @@ func (self *SRegion) TagResources(resourceType string, resIds []string, tags map
return nil
}
func (self *SRegion) rawUntagResources(resourceType string, resIds []string, tags []string) error {
func (self *SRegion) rawUntagResources(serviceType string, resourceType string, resIds []string, tags []string) error {
if len(resIds) > 50 {
return errors.Wrap(cloudprovider.ErrNotSupported, "resource count exceed 50 for one request")
}
@@ -174,14 +174,14 @@ func (self *SRegion) rawUntagResources(resourceType string, resIds []string, tag
for i := range tags {
params[fmt.Sprintf("TagKey.%d", i+1)] = tags[i]
}
_, err := self.ecsRequest("UntagResources", params)
_, err := self.tagRequest(serviceType, "UntagResources", params)
if err != nil {
return errors.Wrapf(err, `self.ecsRequest("UntagResources", %s)`, jsonutils.Marshal(params).String())
return errors.Wrapf(err, `self.tagRequest(%s,"UntagResources", %s)`, serviceType, jsonutils.Marshal(params).String())
}
return nil
}
func (self *SRegion) UntagResources(resourceType string, resIds []string, tags []string) error {
func (self *SRegion) UntagResources(serviceType string, resourceType string, resIds []string, tags []string) error {
if len(resIds) == 0 || len(tags) == 0 {
return nil
}
@@ -189,7 +189,7 @@ func (self *SRegion) UntagResources(resourceType string, resIds []string, tags [
tagsGroups := splitStringSlice(tags, 20)
for i := range resIdsGroups {
for j := range tagsGroups {
err := self.rawUntagResources(resourceType, resIdsGroups[i], tagsGroups[j])
err := self.rawUntagResources(serviceType, resourceType, resIdsGroups[i], tagsGroups[j])
if err != nil {
return errors.Wrapf(err, "self.rawTagResources(resourceType, resIdsGroups[i], tagsGroups[i])")
}
@@ -198,15 +198,15 @@ func (self *SRegion) UntagResources(resourceType string, resIds []string, tags [
return nil
}
func (self *SRegion) SetResourceTags(resourceType string, resIds []string, tags map[string]string, replace bool) error {
oldTags, err := self.ListResourceTags(resourceType, resIds)
func (self *SRegion) SetResourceTags(serviceType string, resourceType string, resIds []string, tags map[string]string, replace bool) error {
oldTags, err := self.ListResourceTags(serviceType, resourceType, resIds)
if err != nil {
return errors.Wrapf(err, "self.ListResourceTags(%s,%s)", resourceType, resIds)
}
for i := range resIds {
_, ok := oldTags[resIds[i]]
if !ok {
err := self.TagResources(resourceType, []string{resIds[i]}, tags)
err := self.TagResources(serviceType, resourceType, []string{resIds[i]}, tags)
if err != nil {
return errors.Wrap(err, "self.TagResources(resourceType, []string{resIds[i]}, tags)")
}
@@ -230,11 +230,11 @@ func (self *SRegion) SetResourceTags(resourceType string, resIds []string, tags
}
}
}
err := self.UntagResources(resourceType, []string{resIds[i]}, delTags)
err := self.UntagResources(serviceType, resourceType, []string{resIds[i]}, delTags)
if err != nil {
return errors.Wrap(err, "self.UntagResources(resourceType, []string{resIds[i]}, delTags)")
}
err = self.TagResources(resourceType, []string{resIds[i]}, addTags)
err = self.TagResources(serviceType, resourceType, []string{resIds[i]}, addTags)
if err != nil {
return errors.Wrap(err, "self.TagResources(resourceType, []string{resIds[i]}, addTags)")
}
+3 -2
View File
@@ -24,11 +24,12 @@ import (
func init() {
type TagGetOptions struct {
SERVICE string `help:"service, eg. ecs"`
RESTYPE string `help:"resource type, eg. instance"`
ID []string `help:"resource Id, eg. ins-123xxx"`
}
shellutils.R(&TagGetOptions{}, "tag-show", "show tag of a specific resource", func(cli *aliyun.SRegion, args *TagGetOptions) error {
tags, err := cli.ListResourceTags(args.RESTYPE, args.ID)
tags, err := cli.ListResourceTags(args.SERVICE, args.RESTYPE, args.ID)
if err != nil {
return err
}
@@ -49,7 +50,7 @@ func init() {
parts := strings.Split(t, ":")
tags[parts[0]] = parts[1]
}
err := cli.SetResourceTags(args.RESTYPE, args.ID, tags, args.Replace)
err := cli.SetResourceTags(args.SERVICE, args.RESTYPE, args.ID, tags, args.Replace)
if err != nil {
return err
}
+4
View File
@@ -454,3 +454,7 @@ func (self *SRegion) CreateElbBackendgroup(group *cloudprovider.SLoadbalancerBac
return nil, fmt.Errorf("CreateElbBackendgroup error: %#v", backendgroups)
}
func (self *SElb) SetMetadata(tags map[string]string, replace bool) error {
return cloudprovider.ErrNotSupported
}
+4
View File
@@ -68,6 +68,10 @@ func (instance *SDBInstanceBase) Delete() error {
return errors.Wrapf(cloudprovider.ErrNotImplemented, "Delete")
}
func (instance *SDBInstanceBase) SetMetadata(tags map[string]string, replace bool) error {
return cloudprovider.ErrNotImplemented
}
func (instance *SDBInstanceBase) GetMasterInstanceId() string {
return ""
}
@@ -734,3 +734,7 @@ func (self *SElasticcache) GetICloudElasticcacheBackup(backupId string) (cloudpr
return nil, cloudprovider.ErrNotFound
}
func (instance *SElasticcache) SetMetadata(tags map[string]string, replace bool) error {
return cloudprovider.ErrNotImplemented
}
+4
View File
@@ -540,3 +540,7 @@ func (self *SRegion) UpdateLoadBalancerHealthCheck(healthCheckID string, healthC
func (self *SRegion) DeleteLoadbalancerHealthCheck(healthCheckID string) error {
return DoDelete(self.ecsClient.ElbHealthCheck.Delete, healthCheckID, nil, nil)
}
func (self *SLoadbalancer) SetMetadata(tags map[string]string, replace bool) error {
return cloudprovider.ErrNotSupported
}
+4
View File
@@ -487,3 +487,7 @@ func (lb *SLoadbalancer) GetILoadBalancerListeners() ([]cloudprovider.ICloudLoad
func (lb *SLoadbalancer) GetProjectId() string {
return lb.ProjectID
}
func (self *SLoadbalancer) SetMetadata(tags map[string]string, replace bool) error {
return cloudprovider.ErrNotSupported
}
+18 -1
View File
@@ -270,7 +270,20 @@ func (self *SLoadbalancer) GetMetadata() *jsonutils.JSONDict {
meta.Add(jsonutils.NewInt(self.OpenBGP), "OpenBGP")
meta.Add(jsonutils.NewString(self.Domain), "Domain")
meta.Add(jsonutils.NewInt(self.ProjectID), "ProjectID")
tags, err := self.region.FetchResourceTags("clb", "clb", []string{self.GetId()})
if err != nil {
log.Errorf(`[err:%s]self.region.FetchResourceTags("clb", "clb", []string{self.GetId()})`, err.Error())
return nil
}
if _, ok := tags[self.GetId()]; !ok {
return meta
}
resourceTag := tags[self.GetId()]
if resourceTag != nil {
for k, v := range *resourceTag {
meta.Add(jsonutils.NewString(v), k)
}
}
return meta
}
@@ -645,3 +658,7 @@ func (self *SRegion) WaitLBTaskSuccess(requestId string, interval time.Duration,
func (self *SLoadbalancer) GetProjectId() string {
return strconv.Itoa(int(self.ProjectID))
}
func (self *SLoadbalancer) SetMetadata(tags map[string]string, replace bool) error {
return self.region.SetResourceTags("clb", "clb", []string{self.LoadBalancerID}, tags, replace)
}
+23
View File
@@ -809,3 +809,26 @@ func (self *SMySQLInstance) CreateIBackup(opts *cloudprovider.SDBInstanceBackupC
}
return self.region.CreateMySQLBackup(self.InstanceId, tables)
}
func (self *SMySQLInstance) GetMetadata() *jsonutils.JSONDict {
meta := jsonutils.NewDict()
tags, err := self.region.FetchResourceTags("cdb", "instanceId", []string{self.GetId()})
if err != nil {
log.Errorf(`[err:%s]self.region.FetchResourceTags("cdb", "instanceId", []string{self.GetId()})`, err.Error())
return nil
}
if _, ok := tags[self.GetId()]; !ok {
return meta
}
resourceTag := tags[self.GetId()]
if resourceTag != nil {
for k, v := range *resourceTag {
meta.Add(jsonutils.NewString(v), k)
}
}
return meta
}
func (self *SMySQLInstance) SetMetadata(tags map[string]string, replace bool) error {
return self.region.SetResourceTags("cdb", "instanceId", []string{self.InstanceId}, tags, replace)
}