mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-10-29 17:58:36 +08:00
tag filter for rbac
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
// 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 tagutils // import "yunion.io/x/onecloud/pkg/util/tagutils"
|
||||
+25
-45
@@ -17,6 +17,8 @@ package tagutils
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
)
|
||||
|
||||
type TTagSet []STag
|
||||
@@ -76,54 +78,22 @@ func (ts TTagSet) Remove(ele ...STag) TTagSet {
|
||||
return ts
|
||||
}
|
||||
|
||||
func contains(v1, v2 []string) bool {
|
||||
vv1 := stringutils2.SSortedStrings(v1)
|
||||
vv2 := stringutils2.SSortedStrings(v2)
|
||||
return stringutils2.Contains(vv1, vv2)
|
||||
}
|
||||
|
||||
func (a TTagSet) Contains(b TTagSet) bool {
|
||||
aNoB, _, _ := Split(a, b)
|
||||
if len(aNoB) == 0 {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
mapA := Tagset2Map(a)
|
||||
mapB := Tagset2Map(b)
|
||||
|
||||
func (a TTagSet) Equals(b TTagSet) bool {
|
||||
aNoB, _, bNoA := Split(a, b)
|
||||
if len(aNoB) == 0 && len(bNoA) == 0 {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func Split(a, b TTagSet) (aNoB TTagSet, aAndB TTagSet, bNoA TTagSet) {
|
||||
a_b := make([]STag, 0)
|
||||
b_a := make([]STag, 0)
|
||||
anb := make([]STag, 0)
|
||||
i := 0
|
||||
j := 0
|
||||
for i < len(a) && j < len(b) {
|
||||
switch Compare(a[i], b[j]) {
|
||||
case 0:
|
||||
anb = append(anb, a[i])
|
||||
i += 1
|
||||
j += 1
|
||||
case -1:
|
||||
a_b = append(a_b, a[i])
|
||||
i += 1
|
||||
case 1:
|
||||
b_a = append(b_a, b[j])
|
||||
j += 1
|
||||
for k, v := range mapA {
|
||||
if vs, ok := mapB[k]; !ok || !contains(v, vs) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if i < len(a) {
|
||||
a_b = append(a_b, a[i:]...)
|
||||
}
|
||||
if j < len(b) {
|
||||
b_a = append(b_a, b[j:]...)
|
||||
}
|
||||
aNoB = a_b
|
||||
aAndB = anb
|
||||
bNoA = b_a
|
||||
return
|
||||
return true
|
||||
}
|
||||
|
||||
func Map2Tagset(meta map[string]string) TTagSet {
|
||||
@@ -144,7 +114,17 @@ func Tagset2Map(oTags TTagSet) map[string][]string {
|
||||
tags[tag.Key] = []string{}
|
||||
}
|
||||
if len(tag.Value) > 0 && !utils.IsInStringArray(tag.Value, tags[tag.Key]) {
|
||||
tags[tag.Key] = append(tags[tag.Key], tag.Value)
|
||||
tags[tag.Key] = stringutils2.SSortedStrings(tags[tag.Key]).Append(tag.Value)
|
||||
}
|
||||
}
|
||||
return tags
|
||||
}
|
||||
|
||||
func Tagset2MapString(oTags TTagSet) map[string]string {
|
||||
tags := map[string]string{}
|
||||
for _, tag := range oTags {
|
||||
if _, ok := tags[tag.Key]; !ok {
|
||||
tags[tag.Key] = tag.Value
|
||||
}
|
||||
}
|
||||
return tags
|
||||
|
||||
@@ -46,6 +46,29 @@ func TestTTagSet_Contains(t *testing.T) {
|
||||
},
|
||||
contains: true,
|
||||
},
|
||||
{
|
||||
t1: TTagSet{
|
||||
STag{
|
||||
Key: "project",
|
||||
Value: "a",
|
||||
},
|
||||
STag{
|
||||
Key: "project",
|
||||
Value: "b",
|
||||
},
|
||||
},
|
||||
t2: TTagSet{
|
||||
STag{
|
||||
Key: "project",
|
||||
Value: "a",
|
||||
},
|
||||
STag{
|
||||
Key: "env",
|
||||
Value: "c",
|
||||
},
|
||||
},
|
||||
contains: true,
|
||||
},
|
||||
{
|
||||
t1: TTagSet{
|
||||
STag{
|
||||
|
||||
@@ -85,12 +85,24 @@ func (tsl TTagSetList) String() string {
|
||||
return "[" + strings.Join(tss, ",") + "]"
|
||||
}
|
||||
|
||||
func (tsl TTagSetList) Flattern() TTagSet {
|
||||
ret := TTagSet{}
|
||||
for _, ts := range tsl {
|
||||
for k, v := range ts {
|
||||
ret[k] = v
|
||||
}
|
||||
func (a TTagSetList) Len() int { return len(a) }
|
||||
func (a TTagSetList) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a TTagSetList) Less(i, j int) bool {
|
||||
if len(a[i]) < len(a[j]) {
|
||||
return true
|
||||
} else if len(a[i]) > len(a[j]) {
|
||||
return false
|
||||
}
|
||||
return ret
|
||||
if a[i].Contains(a[j]) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (tsl TTagSetList) Flattern() TTagSet {
|
||||
if len(tsl) == 0 {
|
||||
return TTagSet{}
|
||||
}
|
||||
sort.Sort(tsl)
|
||||
return tsl[len(tsl)-1]
|
||||
}
|
||||
|
||||
@@ -14,7 +14,12 @@
|
||||
|
||||
package tagutils
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
)
|
||||
|
||||
func TestTTagSetList_Contains(t *testing.T) {
|
||||
cases := []struct {
|
||||
@@ -243,3 +248,47 @@ func TestTTagSetList_Append(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTTagSetList_Flattern(t *testing.T) {
|
||||
cases := []struct {
|
||||
tsl TTagSetList
|
||||
want TTagSet
|
||||
}{
|
||||
{
|
||||
tsl: TTagSetList{
|
||||
TTagSet{
|
||||
STag{
|
||||
Key: "project",
|
||||
Value: "a",
|
||||
},
|
||||
STag{
|
||||
Key: "env",
|
||||
Value: "product",
|
||||
},
|
||||
},
|
||||
TTagSet{
|
||||
STag{
|
||||
Key: "project",
|
||||
Value: "b",
|
||||
},
|
||||
},
|
||||
},
|
||||
want: TTagSet{
|
||||
STag{
|
||||
Key: "project",
|
||||
Value: "a",
|
||||
},
|
||||
STag{
|
||||
Key: "env",
|
||||
Value: "product",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
got := c.tsl.Flattern()
|
||||
if !reflect.DeepEqual(got, c.want) {
|
||||
t.Errorf("want %s got %s", jsonutils.Marshal(c.want), jsonutils.Marshal(got))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user