tag filter for rbac

This commit is contained in:
Qiu Jian
2021-12-02 07:43:10 +08:00
parent ae7c972afc
commit fbe741f6cd
21 changed files with 276 additions and 155 deletions
+15
View File
@@ -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
View File
@@ -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
+23
View File
@@ -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{
+19 -7
View File
@@ -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]
}
+50 -1
View File
@@ -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))
}
}
}