diff --git a/pkg/compute/models/cloudsync.go b/pkg/compute/models/cloudsync.go index e265047e7b..02ea57c88e 100644 --- a/pkg/compute/models/cloudsync.go +++ b/pkg/compute/models/cloudsync.go @@ -127,14 +127,16 @@ func syncRegionSkus(ctx context.Context, userCred mcclient.TokenCredential, loca } } - cnt, err = ElasticcacheSkuManager.GetSkuCountByRegion(regionId) - if err != nil { - log.Errorf("ElasticcacheSkuManager.GetSkuCountByRegion fail %s", err) - return - } + if localRegion.GetDriver().IsSupportedElasticcache() { + cnt, err = ElasticcacheSkuManager.GetSkuCountByRegion(regionId) + if err != nil { + log.Errorf("ElasticcacheSkuManager.GetSkuCountByRegion fail %s", err) + return + } - if cnt == 0 { - syncElasticCacheSkusByRegion(ctx, userCred, localRegion) + if cnt == 0 { + syncElasticCacheSkusByRegion(ctx, userCred, localRegion) + } } } diff --git a/pkg/compute/models/elasticcache_accounts.go b/pkg/compute/models/elasticcache_accounts.go index 9015ef82a3..473f7a299f 100644 --- a/pkg/compute/models/elasticcache_accounts.go +++ b/pkg/compute/models/elasticcache_accounts.go @@ -34,6 +34,7 @@ import ( "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/choices" + "yunion.io/x/onecloud/pkg/util/rbacutils" "yunion.io/x/onecloud/pkg/util/seclib2" ) @@ -154,6 +155,10 @@ func (self *SElasticcacheAccount) GetRegion() *SCloudregion { return iec.(*SElasticcache).GetRegion() } +func (self *SElasticcacheAccount) GetOwnerId() mcclient.IIdentityProvider { + return ElasticcacheManager.GetOwnerIdByElasticcacheId(self.ElasticcacheId) +} + func (manager *SElasticcacheAccountManager) newFromCloudElasticcacheAccount(ctx context.Context, userCred mcclient.TokenCredential, elasticcache *SElasticcache, extAccount cloudprovider.ICloudElasticcacheAccount) (*SElasticcacheAccount, error) { lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, userCred)) defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, userCred)) @@ -177,8 +182,19 @@ func (manager *SElasticcacheAccountManager) newFromCloudElasticcacheAccount(ctx } func (manager *SElasticcacheAccountManager) FetchParentId(ctx context.Context, data jsonutils.JSONObject) string { - parentId, _ := data.GetString("elasticcache_id") - return parentId + return jsonutils.GetAnyString(data, []string{"elasticcache_id", "elasticcache"}) +} + +func (manager *SElasticcacheAccountManager) ResourceScope() rbacutils.TRbacScope { + return rbacutils.ScopeProject +} + +func (manager *SElasticcacheAccountManager) FetchOwnerId(ctx context.Context, data jsonutils.JSONObject) (mcclient.IIdentityProvider, error) { + return elasticcacheSubResourceFetchOwnerId(ctx, data) +} + +func (manager *SElasticcacheAccountManager) FilterByOwner(q *sqlchemy.SQuery, userCred mcclient.IIdentityProvider, scope rbacutils.TRbacScope) *sqlchemy.SQuery { + return elasticcacheSubResourceFetchOwner(q, userCred, scope) } func (manager *SElasticcacheAccountManager) FilterByParentId(q *sqlchemy.SQuery, parentId string) *sqlchemy.SQuery { diff --git a/pkg/compute/models/elasticcache_acls.go b/pkg/compute/models/elasticcache_acls.go index 7499a6a855..c4403e4a21 100644 --- a/pkg/compute/models/elasticcache_acls.go +++ b/pkg/compute/models/elasticcache_acls.go @@ -33,6 +33,7 @@ import ( "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/onecloud/pkg/util/rbacutils" ) // SElasticcache.Acl @@ -161,8 +162,19 @@ func (manager *SElasticcacheAclManager) newFromCloudElasticcacheAcl(ctx context. } func (manager *SElasticcacheAclManager) FetchParentId(ctx context.Context, data jsonutils.JSONObject) string { - parentId, _ := data.GetString("elasticcache_id") - return parentId + return jsonutils.GetAnyString(data, []string{"elasticcache_id", "elasticcache"}) +} + +func (manager *SElasticcacheAclManager) ResourceScope() rbacutils.TRbacScope { + return rbacutils.ScopeProject +} + +func (manager *SElasticcacheAclManager) FetchOwnerId(ctx context.Context, data jsonutils.JSONObject) (mcclient.IIdentityProvider, error) { + return elasticcacheSubResourceFetchOwnerId(ctx, data) +} + +func (manager *SElasticcacheAclManager) FilterByOwner(q *sqlchemy.SQuery, userCred mcclient.IIdentityProvider, scope rbacutils.TRbacScope) *sqlchemy.SQuery { + return elasticcacheSubResourceFetchOwner(q, userCred, scope) } func (manager *SElasticcacheAclManager) FilterByParentId(q *sqlchemy.SQuery, parentId string) *sqlchemy.SQuery { @@ -200,6 +212,10 @@ func (manager *SElasticcacheAclManager) ValidateCreateData(ctx context.Context, return region.GetDriver().ValidateCreateElasticcacheAclData(ctx, userCred, ownerId, data) } +func (self *SElasticcacheAcl) GetOwnerId() mcclient.IIdentityProvider { + return ElasticcacheManager.GetOwnerIdByElasticcacheId(self.ElasticcacheId) +} + func (self *SElasticcacheAcl) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) { self.SStandaloneResourceBase.PostCreate(ctx, userCred, ownerId, query, data) self.SetStatus(userCred, api.ELASTIC_CACHE_ACL_STATUS_CREATING, "") diff --git a/pkg/compute/models/elasticcache_backups.go b/pkg/compute/models/elasticcache_backups.go index 0058a4fae2..08a5582afd 100644 --- a/pkg/compute/models/elasticcache_backups.go +++ b/pkg/compute/models/elasticcache_backups.go @@ -32,6 +32,7 @@ import ( "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/onecloud/pkg/util/rbacutils" ) // SElasticcache.Backup @@ -201,8 +202,19 @@ func (manager *SElasticcacheBackupManager) newFromCloudElasticcacheBackup(ctx co } func (manager *SElasticcacheBackupManager) FetchParentId(ctx context.Context, data jsonutils.JSONObject) string { - parentId, _ := data.GetString("elasticcache_id") - return parentId + return jsonutils.GetAnyString(data, []string{"elasticcache_id", "elasticcache"}) +} + +func (manager *SElasticcacheBackupManager) ResourceScope() rbacutils.TRbacScope { + return rbacutils.ScopeProject +} + +func (manager *SElasticcacheBackupManager) FetchOwnerId(ctx context.Context, data jsonutils.JSONObject) (mcclient.IIdentityProvider, error) { + return elasticcacheSubResourceFetchOwnerId(ctx, data) +} + +func (manager *SElasticcacheBackupManager) FilterByOwner(q *sqlchemy.SQuery, userCred mcclient.IIdentityProvider, scope rbacutils.TRbacScope) *sqlchemy.SQuery { + return elasticcacheSubResourceFetchOwner(q, userCred, scope) } func (manager *SElasticcacheBackupManager) FilterByParentId(q *sqlchemy.SQuery, parentId string) *sqlchemy.SQuery { @@ -244,6 +256,10 @@ func (manager *SElasticcacheBackupManager) ValidateCreateData(ctx context.Contex return driver.ValidateCreateElasticcacheBackupData(ctx, userCred, ownerId, data) } +func (self *SElasticcacheBackup) GetOwnerId() mcclient.IIdentityProvider { + return ElasticcacheManager.GetOwnerIdByElasticcacheId(self.ElasticcacheId) +} + func (self *SElasticcacheBackup) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) { self.SStandaloneResourceBase.PostCreate(ctx, userCred, ownerId, query, data) self.SetStatus(userCred, api.ELASTIC_CACHE_BACKUP_STATUS_CREATING, "") diff --git a/pkg/compute/models/elasticcache_instances.go b/pkg/compute/models/elasticcache_instances.go index 227abffe47..f26114cfca 100644 --- a/pkg/compute/models/elasticcache_instances.go +++ b/pkg/compute/models/elasticcache_instances.go @@ -19,6 +19,7 @@ import ( "fmt" "regexp" "strings" + "time" "yunion.io/x/jsonutils" "yunion.io/x/log" @@ -33,12 +34,14 @@ 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/policy" "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" bc "yunion.io/x/onecloud/pkg/util/billing" "yunion.io/x/onecloud/pkg/util/choices" + "yunion.io/x/onecloud/pkg/util/rbacutils" "yunion.io/x/onecloud/pkg/util/seclib2" ) @@ -99,6 +102,44 @@ type SElasticcache struct { // AutoRenewPeriod // 自动续费周期 } +// elastic cache 子资源获取owner id +func elasticcacheSubResourceFetchOwnerId(ctx context.Context, data jsonutils.JSONObject) (mcclient.IIdentityProvider, error) { + parentId := jsonutils.GetAnyString(data, []string{"elasticcache_id", "elasticcache"}) + if len(parentId) > 0 { + userCred := policy.FetchUserCredential(ctx) + ec, err := db.FetchByIdOrName(ElasticcacheManager, userCred, parentId) + if err != nil { + log.Errorf("elasticcache sub resource FetchOwnerId %s", err) + return nil, nil + } + + return ec.(*SElasticcache).GetOwnerId(), nil + } + + return nil, nil +} + +// elastic cache 子资源获取owner query +func elasticcacheSubResourceFetchOwner(q *sqlchemy.SQuery, userCred mcclient.IIdentityProvider, scope rbacutils.TRbacScope) *sqlchemy.SQuery { + if userCred != nil { + var subq *sqlchemy.SSubQuery + + q1 := ElasticcacheManager.Query() + switch scope { + case rbacutils.ScopeProject: + subq = q1.Equals("tenant_id", userCred.GetProjectId()).SubQuery() + case rbacutils.ScopeDomain: + subq = q1.Equals("domain_id", userCred.GetProjectDomainId()).SubQuery() + } + + if subq != nil { + q = q.Join(subq, sqlchemy.Equals(q.Field("elasticcache_id"), subq.Field("id"))) + } + } + + return q +} + func (self *SElasticcache) getCloudProviderInfo() SCloudProviderInfo { region := self.GetRegion() provider := self.GetCloudprovider() @@ -199,6 +240,16 @@ func (self *SElasticcache) GetDetailsLoginInfo(ctx context.Context, userCred mcc return ret, nil } +func (manager *SElasticcacheManager) GetOwnerIdByElasticcacheId(elasticcacheId string) mcclient.IIdentityProvider { + ec, err := db.FetchById(ElasticcacheManager, elasticcacheId) + if err != nil { + log.Errorf("SElasticcacheManager.GetOwnerIdByElasticcacheId %s", err) + return nil + } + + return ec.(*SElasticcache).GetOwnerId() +} + func (manager *SElasticcacheManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) { q, err := manager.SVirtualResourceBaseManager.ListItemFilter(ctx, q, userCred, query) if err != nil { @@ -697,6 +748,10 @@ func (self *SElasticcache) ValidateDeleteCondition(ctx context.Context) error { return httperrors.NewInvalidStatusError("Elastic cache is locked, cannot delete") } + if self.GetChargeType() == billing.BILLING_TYPE_PREPAID && self.ExpiredAt.Sub(time.Now()).Seconds() > 0 { + return httperrors.NewInvalidStatusError("Elastic cache is not expired, cannot delete") + } + return self.ValidatePurgeCondition(ctx) } diff --git a/pkg/compute/models/elasticcache_parameters.go b/pkg/compute/models/elasticcache_parameters.go index 3a8c60754a..3dba52e2dc 100644 --- a/pkg/compute/models/elasticcache_parameters.go +++ b/pkg/compute/models/elasticcache_parameters.go @@ -21,6 +21,7 @@ import ( "yunion.io/x/log" "yunion.io/x/pkg/errors" "yunion.io/x/pkg/util/compare" + "yunion.io/x/sqlchemy" api "yunion.io/x/onecloud/pkg/apis/compute" "yunion.io/x/onecloud/pkg/cloudcommon/db" @@ -29,6 +30,7 @@ import ( "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/onecloud/pkg/util/rbacutils" ) // SElasticcache.Parameter @@ -168,6 +170,22 @@ func (manager *SElasticcacheParameterManager) newFromCloudElasticcacheParameter( return ¶meter, nil } +func (manager *SElasticcacheParameterManager) ResourceScope() rbacutils.TRbacScope { + return rbacutils.ScopeProject +} + +func (manager *SElasticcacheParameterManager) FetchOwnerId(ctx context.Context, data jsonutils.JSONObject) (mcclient.IIdentityProvider, error) { + return elasticcacheSubResourceFetchOwnerId(ctx, data) +} + +func (manager *SElasticcacheParameterManager) FilterByOwner(q *sqlchemy.SQuery, userCred mcclient.IIdentityProvider, scope rbacutils.TRbacScope) *sqlchemy.SQuery { + return elasticcacheSubResourceFetchOwner(q, userCred, scope) +} + +func (self *SElasticcacheParameter) GetOwnerId() mcclient.IIdentityProvider { + return ElasticcacheManager.GetOwnerIdByElasticcacheId(self.ElasticcacheId) +} + func (self *SElasticcacheParameter) GetRegion() *SCloudregion { ieb, err := db.FetchById(ElasticcacheManager, self.ElasticcacheId) if err != nil { diff --git a/pkg/compute/models/regiondrivers.go b/pkg/compute/models/regiondrivers.go index 7388cfde20..eb0cc4c84b 100644 --- a/pkg/compute/models/regiondrivers.go +++ b/pkg/compute/models/regiondrivers.go @@ -142,6 +142,7 @@ type IRegionDriver interface { } type IElasticcacheDriver interface { + IsSupportedElasticcache() bool AllowCreateElasticcacheBackup(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, elasticcache *SElasticcache) error AllowUpdateElasticcacheAuthMode(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, elasticcache *SElasticcache) error ValidateCreateElasticcacheData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) diff --git a/pkg/compute/regiondrivers/aliyun.go b/pkg/compute/regiondrivers/aliyun.go index 76373826b9..2462950756 100644 --- a/pkg/compute/regiondrivers/aliyun.go +++ b/pkg/compute/regiondrivers/aliyun.go @@ -1535,3 +1535,7 @@ func (self *SAliyunRegionDriver) RequestElasticcacheAccountResetPassword(ctx con return ea.SyncWithCloudElasticcacheAccount(ctx, userCred, iea) } + +func (self *SAliyunRegionDriver) IsSupportedElasticcache() bool { + return true +} diff --git a/pkg/compute/regiondrivers/base.go b/pkg/compute/regiondrivers/base.go index 48022676fc..fb8ce4dafd 100644 --- a/pkg/compute/regiondrivers/base.go +++ b/pkg/compute/regiondrivers/base.go @@ -294,3 +294,7 @@ func (self *SBaseRegionDriver) ValidateResetDBInstancePassword(ctx context.Conte func (self *SBaseRegionDriver) IsSupportKeepDBInstanceManualBackup() bool { return false } + +func (self *SBaseRegionDriver) IsSupportedElasticcache() bool { + return false +} diff --git a/pkg/compute/regiondrivers/huawei.go b/pkg/compute/regiondrivers/huawei.go index 49d06f7bb4..d7e1a5dde2 100644 --- a/pkg/compute/regiondrivers/huawei.go +++ b/pkg/compute/regiondrivers/huawei.go @@ -2562,3 +2562,7 @@ func (self *SHuaWeiRegionDriver) AllowCreateElasticcacheBackup(ctx context.Conte func (self *SHuaWeiRegionDriver) AllowUpdateElasticcacheAuthMode(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, elasticcache *models.SElasticcache) error { return fmt.Errorf("not support update huawei elastic cache auth_mode") } + +func (self *SHuaWeiRegionDriver) IsSupportedElasticcache() bool { + return true +}