feat(region): add metadata prefix 'cls'

Such tags have inherited and isolated properties
This commit is contained in:
rainzm
2022-02-09 15:26:42 +08:00
parent 6d615bad96
commit eaa03232d9
5 changed files with 109 additions and 8 deletions
+1
View File
@@ -20,4 +20,5 @@ const (
CLOUD_TAG_PREFIX = apis.CLOUD_TAG_PREFIX
USER_TAG_PREFIX = apis.USER_TAG_PREFIX
SYS_CLOUD_TAG_PREFIX = apis.SYS_CLOUD_TAG_PREFIX
CLASS_TAT_PREFIX = apis.CLASS_TAT_PREFIX
)
+2
View File
@@ -51,6 +51,8 @@ const (
CLOUD_TAG_PREFIX = "ext:"
USER_TAG_PREFIX = "user:"
SYS_CLOUD_TAG_PREFIX = "sys:"
// Such tags have inherited and isolated properties
CLASS_TAT_PREFIX = "cls:"
)
var (
+4
View File
@@ -344,6 +344,10 @@ type PerformUserMetadataInput map[string]string
// 全量替换资源的用户标签(元数据)输入
type PerformSetUserMetadataInput map[string]string
type PerformSetClassMetadataInput map[string]string
type GetClassMetadataOutput map[string]string
// 获取资源的元数据输入
type GetMetadataInput struct {
// 指定需要获取的所有标签的KEY列表,如果列表为空,则获取全部标签
+10 -8
View File
@@ -45,6 +45,7 @@ const (
CLOUD_TAG_PREFIX = dbapi.CLOUD_TAG_PREFIX
USER_TAG_PREFIX = dbapi.USER_TAG_PREFIX
SYS_CLOUD_TAG_PREFIX = dbapi.SYS_CLOUD_TAG_PREFIX
CLASS_TAG_PREFIX = dbapi.CLASS_TAT_PREFIX
// TAG_DELETE_RANGE_USER = "user"
// TAG_DELETE_RANGE_CLOUD = CLOUD_TAG_PREFIX // "cloud"
@@ -602,14 +603,15 @@ func (manager *SMetadataManager) rawSetValues(ctx context.Context, objType strin
if replace {
records := []SMetadata{}
q := manager.Query().Equals("id", idStr).NotLike("key", `\_\_%`) //避免删除系统内置的metadata, _ 在mysql里面有特殊含义,需要转义
switch replaceRange {
case USER_TAG_PREFIX:
q = q.Startswith("key", USER_TAG_PREFIX)
case CLOUD_TAG_PREFIX:
q = q.Startswith("key", CLOUD_TAG_PREFIX)
case SYS_CLOUD_TAG_PREFIX:
q = q.Startswith("key", SYS_CLOUD_TAG_PREFIX)
}
// switch replaceRange {
// case USER_TAG_PREFIX:
// q = q.Startswith("key", USER_TAG_PREFIX)
// case CLOUD_TAG_PREFIX:
// q = q.Startswith("key", CLOUD_TAG_PREFIX)
// case SYS_CLOUD_TAG_PREFIX:
// q = q.Startswith("key", SYS_CLOUD_TAG_PREFIX)
// }
q = q.Startswith("key", replaceRange)
q = q.Filter(sqlchemy.NOT(sqlchemy.In(q.Field("key"), keys)))
if err := FetchModelObjects(manager, q, &records); err != nil {
log.Errorf("failed to fetch metadata error: %v", err)
+92
View File
@@ -29,6 +29,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/policy"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/util/rbacutils"
"yunion.io/x/onecloud/pkg/util/stringutils2"
"yunion.io/x/onecloud/pkg/util/tagutils"
@@ -63,6 +64,7 @@ func (model *SStandaloneAnonResourceBase) BeforeInsert() {
type SStandaloneAnonResourceBaseManager struct {
SResourceBaseManager
SMetadataResourceBaseModelManager
SSecretResourceBaseModelManager
}
func NewStandaloneAnonResourceBaseManager(
@@ -139,6 +141,8 @@ func (manager *SStandaloneAnonResourceBaseManager) ListItemFilter(
q = manager.SMetadataResourceBaseModelManager.ListItemFilter(manager.GetIModelManager(), q, input.MetadataResourceListInput)
q = manager.SSecretResourceBaseModelManager.ListItemFilter(manager.GetIModelManager(), q, input.SecretResourceListInput)
return q, nil
}
@@ -274,6 +278,58 @@ func (model *SStandaloneAnonResourceBase) SetCloudMetadataAll(ctx context.Contex
return Metadata.SetAll(ctx, model, userTags, userCred, USER_TAG_PREFIX)
}
func (model *SStandaloneAnonResourceBase) SetClassMetadataAll(ctx context.Context, dictstore map[string]interface{}, userCred mcclient.TokenCredential) error {
afterCheck := make(map[string]interface{}, len(dictstore))
for k, v := range dictstore {
if !strings.HasPrefix(k, CLASS_TAG_PREFIX) {
afterCheck[CLASS_TAG_PREFIX+k] = v
} else {
afterCheck[k] = v
}
}
err := Metadata.SetAll(ctx, model, afterCheck, userCred, CLASS_TAG_PREFIX)
if err != nil {
return errors.Wrap(err, "SetAll")
}
return nil
}
func (model *SStandaloneAnonResourceBase) Inherit(ctx context.Context, sonModel *SStandaloneAnonResourceBase) error {
metadata, err := model.GetAllClassMetadata()
if err != nil {
return errors.Wrap(err, "GetAllPureMetadata")
}
if len(metadata) == 0 {
return nil
}
userCred := auth.AdminCredential()
dictstore := make(map[string]interface{}, 0)
for k, v := range metadata {
dictstore[k] = v
}
return sonModel.SetClassMetadataAll(ctx, dictstore, userCred)
}
func (model *SStandaloneAnonResourceBase) IsInSameClass(ctx context.Context, pModel *SStandaloneAnonResourceBase) (bool, error) {
pureTags, err := model.GetAllClassMetadata()
if err != nil {
return false, errors.Wrap(err, "GetAllPureMetadata")
}
pureTagsP, err := pModel.GetAllClassMetadata()
if err != nil {
return false, errors.Wrap(err, "GetAllPureMetadata")
}
if len(pureTags) != len(pureTagsP) {
return false, nil
}
for k, v := range pureTags {
if vp, ok := pureTagsP[k]; !ok || vp != v {
return false, nil
}
}
return true, nil
}
func (model *SStandaloneAnonResourceBase) SetSysCloudMetadataAll(ctx context.Context, dictstore map[string]interface{}, userCred mcclient.TokenCredential) error {
err := Metadata.SetAll(ctx, model, dictstore, userCred, SYS_CLOUD_TAG_PREFIX)
if err != nil {
@@ -326,6 +382,18 @@ func (model *SStandaloneAnonResourceBase) GetAllCloudMetadata() (map[string]stri
return ret, nil
}
func (model *SStandaloneAnonResourceBase) GetAllClassMetadata() (map[string]string, error) {
meta, err := Metadata.GetAll(nil, model, nil, CLASS_TAG_PREFIX, nil)
if err != nil {
return nil, errors.Wrap(err, "Metadata.GetAll")
}
ret := make(map[string]string)
for k, v := range meta {
ret[k[len(CLASS_TAG_PREFIX):]] = v
}
return ret, nil
}
// 获取资源标签(元数据)
func (model *SStandaloneAnonResourceBase) GetDetailsMetadata(ctx context.Context, userCred mcclient.TokenCredential, input apis.GetMetadataInput) (apis.GetMetadataOutput, error) {
val, err := Metadata.GetAll(ctx, model, input.Field, input.Prefix, userCred)
@@ -393,6 +461,28 @@ func (model *SStandaloneAnonResourceBase) PerformSetUserMetadata(ctx context.Con
return nil, nil
}
func (model *SStandaloneAnonResourceBase) PerformSetClassMetadata(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformSetClassMetadataInput) (jsonutils.JSONObject, error) {
dictStore := make(map[string]interface{})
for k, v := range input {
if len(k) > 64-len(CLASS_TAG_PREFIX) {
return nil, httperrors.NewInputParameterError("input key too long > %d", 64-len(CLASS_TAG_PREFIX))
}
if len(v) > 65535 {
return nil, httperrors.NewInputParameterError("input value too long > %d", 65535)
}
dictStore[k] = v
}
err := model.SetClassMetadataAll(ctx, dictStore, userCred)
if err != nil {
return nil, errors.Wrap(err, "SetUserMetadataAll")
}
return nil, nil
}
func (model *SStandaloneAnonResourceBase) GetDetailsClassMetadata(ctx context.Context, userCred mcclient.TokenCredential, input apis.GetClassMetadataOutput) (apis.GetClassMetadataOutput, error) {
return model.GetAllClassMetadata()
}
type sPolicyTags struct {
PolicyObjectTags tagutils.TTagSetList `json:"policy_object_tags"`
PolicyProjectTags tagutils.TTagSetList `json:"policy_project_tags"`
@@ -487,10 +577,12 @@ func (manager *SStandaloneAnonResourceBaseManager) FetchCustomizeColumns(
ret := make([]apis.StandaloneAnonResourceDetails, len(objs))
upperRet := manager.SResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
metaRet := manager.SMetadataResourceBaseModelManager.FetchCustomizeColumns(manager.GetIModelManager(), userCred, objs, fields)
secretRet := manager.SSecretResourceBaseModelManager.FetchCustomizeColumns(manager.GetIModelManager(), userCred, objs, fields)
for i := range objs {
ret[i] = apis.StandaloneAnonResourceDetails{
ResourceBaseDetails: upperRet[i],
MetadataResourceInfo: metaRet[i],
SecretResourceInfo: secretRet[i],
}
}
return ret