mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
feat(region): add no_tags options to filter guests
no_tags filter the guests without `no_tags`
This commit is contained in:
+5
-2
@@ -195,10 +195,13 @@ type STag struct {
|
||||
}
|
||||
|
||||
type MetadataResourceListInput struct {
|
||||
// 通过标签过滤
|
||||
// 通过标签过滤(包含这些标签)
|
||||
Tags []STag `json:"tags"`
|
||||
|
||||
// 通过标签过滤
|
||||
// 通过标签过滤(不包含这些标签)
|
||||
NoTags []STag `json:"no_tags"`
|
||||
|
||||
// 通过标签排序
|
||||
OrderByTag string `json:"order_by_tag"`
|
||||
|
||||
// deprecated
|
||||
|
||||
@@ -30,13 +30,9 @@ import (
|
||||
|
||||
type SMetadataResourceBaseModelManager struct{}
|
||||
|
||||
func (meta *SMetadataResourceBaseModelManager) ListItemFilter(
|
||||
manager IModelManager,
|
||||
q *sqlchemy.SQuery,
|
||||
input apis.MetadataResourceListInput,
|
||||
) *sqlchemy.SQuery {
|
||||
func (meta *SMetadataResourceBaseModelManager) objIdQueryWithTags(modelName string, oTags ...apis.STag) *sqlchemy.SQuery {
|
||||
tags := map[string][]string{}
|
||||
for _, tag := range input.Tags {
|
||||
for _, tag := range oTags {
|
||||
if _, ok := tags[tag.Key]; !ok {
|
||||
tags[tag.Key] = []string{}
|
||||
}
|
||||
@@ -46,7 +42,7 @@ func (meta *SMetadataResourceBaseModelManager) ListItemFilter(
|
||||
}
|
||||
|
||||
if len(tags) > 0 {
|
||||
metadataResQ := Metadata.Query().Equals("obj_type", manager.Keyword()).SubQuery()
|
||||
metadataResQ := Metadata.Query().Equals("obj_type", modelName).SubQuery()
|
||||
metadataView := metadataResQ.Query()
|
||||
idx := 0
|
||||
for key, values := range tags {
|
||||
@@ -66,8 +62,30 @@ func (meta *SMetadataResourceBaseModelManager) ListItemFilter(
|
||||
idx++
|
||||
}
|
||||
metadatas := metadataView.SubQuery()
|
||||
sq := metadatas.Query(metadatas.Field("obj_id")).Distinct().SubQuery()
|
||||
q = q.Filter(sqlchemy.In(q.Field("id"), sq))
|
||||
return metadatas.Query(metadatas.Field("obj_id")).Distinct()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (meta *SMetadataResourceBaseModelManager) ListItemFilter(
|
||||
manager IModelManager,
|
||||
q *sqlchemy.SQuery,
|
||||
input apis.MetadataResourceListInput,
|
||||
) *sqlchemy.SQuery {
|
||||
if len(input.Tags) > 0 {
|
||||
sq := meta.objIdQueryWithTags(manager.Keyword(), input.Tags...)
|
||||
if sq != nil {
|
||||
q = q.Filter(sqlchemy.In(q.Field("id"), sq.SubQuery()))
|
||||
}
|
||||
}
|
||||
|
||||
if len(input.NoTags) > 0 {
|
||||
for _, tag := range input.NoTags {
|
||||
sq := meta.objIdQueryWithTags(manager.Keyword(), tag)
|
||||
if sq != nil {
|
||||
q = q.Filter(sqlchemy.NotIn(q.Field("id"), sq.SubQuery()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if input.WithoutUserMeta != nil || input.WithUserMeta != nil {
|
||||
|
||||
@@ -221,6 +221,7 @@ type BaseListOptions struct {
|
||||
ExtraListOptions
|
||||
|
||||
Tags []string `help:"Tags info, eg: hypervisor=aliyun, os_type=Linux, os_version" json:"-"`
|
||||
NoTags []string `help:"List resources without this tags, eg: os_type=Linux, os_version" json:"-"`
|
||||
UserTags []string `help:"UserTags info, eg: group=rd" json:"-"`
|
||||
CloudTags []string `help:"CloudTags info, eg: price_key=cn-beijing" json:"-"`
|
||||
|
||||
@@ -240,21 +241,47 @@ type BaseListOptions struct {
|
||||
}
|
||||
|
||||
func (opts *BaseListOptions) addTag(prefix, tag string, idx int, params *jsonutils.JSONDict) error {
|
||||
tagInfo := strings.Split(tag, "=")
|
||||
if len(tagInfo) > 2 {
|
||||
return fmt.Errorf("Too many equal characters %s", tag)
|
||||
key, value, err := opts.spliteTag(tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key := tagInfo[0]
|
||||
if len(key) == 0 {
|
||||
return fmt.Errorf("Key must not be empty")
|
||||
}
|
||||
params.Add(jsonutils.NewString(prefix+key), fmt.Sprintf("tags.%d.key", idx))
|
||||
if len(tagInfo) == 2 {
|
||||
params.Add(jsonutils.NewString(tagInfo[1]), fmt.Sprintf("tags.%d.value", idx))
|
||||
if len(value) > 0 {
|
||||
params.Add(jsonutils.NewString(value), fmt.Sprintf("tags.%d.value", idx))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (opts *BaseListOptions) addNoTag(prefix, tag string, idx int, params *jsonutils.JSONDict) error {
|
||||
key, value, err := opts.spliteTag(tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(key) == 0 {
|
||||
return fmt.Errorf("Key must not be empty")
|
||||
}
|
||||
params.Add(jsonutils.NewString(prefix+key), fmt.Sprintf("no_tags.%d.key", idx))
|
||||
if len(value) > 0 {
|
||||
params.Add(jsonutils.NewString(value), fmt.Sprintf("no_tags.%d.value", idx))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (opts *BaseListOptions) spliteTag(tag string) (key string, value string, err error) {
|
||||
tagInfo := strings.Split(tag, "=")
|
||||
if len(tagInfo) > 2 {
|
||||
return "", "", fmt.Errorf("Too many equal characters %s", tag)
|
||||
}
|
||||
key = tagInfo[0]
|
||||
if len(tagInfo) > 1 {
|
||||
value = tagInfo[1]
|
||||
}
|
||||
return key, value, nil
|
||||
}
|
||||
|
||||
func (opts *BaseListOptions) Params() (*jsonutils.JSONDict, error) {
|
||||
params, err := optionsStructToParams(opts)
|
||||
if err != nil {
|
||||
@@ -279,7 +306,7 @@ func (opts *BaseListOptions) Params() (*jsonutils.JSONDict, error) {
|
||||
params.Set("admin", jsonutils.JSONTrue)
|
||||
}
|
||||
}*/
|
||||
tagIdx := 0
|
||||
tagIdx, noTagIdx := 0, 0
|
||||
for _, tag := range opts.Tags {
|
||||
err = opts.addTag("", tag, tagIdx, params)
|
||||
if err != nil {
|
||||
@@ -287,6 +314,13 @@ func (opts *BaseListOptions) Params() (*jsonutils.JSONDict, error) {
|
||||
}
|
||||
tagIdx++
|
||||
}
|
||||
for _, tag := range opts.NoTags {
|
||||
err = opts.addNoTag("", tag, noTagIdx, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
noTagIdx++
|
||||
}
|
||||
for _, tag := range opts.UserTags {
|
||||
err = opts.addTag(dbapi.USER_TAG_PREFIX, tag, tagIdx, params)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user