mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-21 22:32:15 +08:00
Merge pull request #15933 from swordqiu/hotfix/qj-usage-policy-filter-revisit2
fix: usage filter by policy tags revisit2
This commit is contained in:
@@ -950,12 +950,13 @@ func guestHypervisorsUsage(
|
||||
count := make(map[string]interface{})
|
||||
|
||||
results := db.UsagePolicyCheck(userToken, models.GuestManager, scope)
|
||||
log.Debugf("guestHypervisorsUsage origin %s", results.String())
|
||||
results = results.Merge(policyResult)
|
||||
if results.Result.IsDeny() {
|
||||
// deny
|
||||
return count
|
||||
}
|
||||
log.Debugf("guestHypervisorsUsage results %s", results.String())
|
||||
log.Debugf("guestHypervisorsUsage policyResults %s results %s", policyResult.String(), results.String())
|
||||
// temporarily hide system resources
|
||||
// XXX needs more work later
|
||||
guest := models.GuestManager.TotalCount(scope, ownerId, rangeObjs, status, hypervisors,
|
||||
|
||||
@@ -75,13 +75,7 @@ func (result SPolicyResult) Json() jsonutils.JSONObject {
|
||||
}
|
||||
|
||||
func mergeTagList(t1, t2 tagutils.TTagSetList) tagutils.TTagSetList {
|
||||
ret := tagutils.TTagSetList{}
|
||||
for i := range t1 {
|
||||
for j := range t2 {
|
||||
ret = append(ret, t1[i].Append(t2[j]...))
|
||||
}
|
||||
}
|
||||
return ret
|
||||
return t1.IntersectList(t2)
|
||||
}
|
||||
|
||||
func (r1 SPolicyResult) Merge(r2 SPolicyResult) SPolicyResult {
|
||||
|
||||
@@ -59,6 +59,28 @@ func TestSTagCompare(t *testing.T) {
|
||||
},
|
||||
cmp: -1,
|
||||
},
|
||||
{
|
||||
t1: STag{
|
||||
Key: "a",
|
||||
Value: AnyValue,
|
||||
},
|
||||
t2: STag{
|
||||
Key: "a",
|
||||
Value: NoValue,
|
||||
},
|
||||
cmp: -1,
|
||||
},
|
||||
{
|
||||
t1: STag{
|
||||
Key: "a",
|
||||
Value: NoValue,
|
||||
},
|
||||
t2: STag{
|
||||
Key: "a",
|
||||
Value: AnyValue,
|
||||
},
|
||||
cmp: 1,
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
got := Compare(c.t1, c.t2)
|
||||
|
||||
+44
-16
@@ -47,6 +47,19 @@ func (ts TTagSet) index(needle STag) (int, bool) {
|
||||
return j + 1, false
|
||||
}
|
||||
|
||||
/*
|
||||
* TagSet Append
|
||||
* 对相同的key,是并集
|
||||
* 对不同的key,是交集
|
||||
* 逻辑上有些问题,暂时这样
|
||||
*
|
||||
* TODO:
|
||||
* type STag struct {
|
||||
* Key string
|
||||
* Values []string
|
||||
* }
|
||||
*
|
||||
*/
|
||||
func (ts TTagSet) Append(ele ...STag) TTagSet {
|
||||
for _, e := range ele {
|
||||
ts = ts.add(e)
|
||||
@@ -65,24 +78,32 @@ func (ts TTagSet) add(e STag) TTagSet {
|
||||
ts = append(ts, e)
|
||||
copy(ts[pos+1:], ts[pos:])
|
||||
ts[pos] = e
|
||||
if e.Value == AnyValue {
|
||||
for i := pos + 1; i < len(ts); i++ {
|
||||
if ts[i].Key != e.Key {
|
||||
if i > pos+1 {
|
||||
copy(ts[pos+1:], ts[i:])
|
||||
ts = ts[:len(ts)-i+pos+1]
|
||||
}
|
||||
break
|
||||
} else if ts[i].Value == NoValue {
|
||||
// remove this key completely
|
||||
copy(ts[pos:], ts[i+1:])
|
||||
ts = ts[:len(ts)-i+pos-1]
|
||||
break
|
||||
start := pos
|
||||
for start > 0 && ts[start-1].Key == e.Key {
|
||||
start--
|
||||
}
|
||||
end := pos
|
||||
for end < len(ts)-1 && ts[end+1].Key == e.Key {
|
||||
end++
|
||||
}
|
||||
if ts[start].Value == AnyValue {
|
||||
if ts[end].Value == NoValue {
|
||||
// remove start ... end
|
||||
if end < len(ts)-1 {
|
||||
copy(ts[start:], ts[end+1:])
|
||||
ts = ts[0 : len(ts)-end+start-1]
|
||||
} else {
|
||||
ts = ts[0:start]
|
||||
}
|
||||
} else {
|
||||
// remove start + 1 ... end
|
||||
if end < len(ts)-1 {
|
||||
copy(ts[start+1:], ts[end+1:])
|
||||
ts = ts[0 : len(ts)-end+start]
|
||||
} else {
|
||||
ts = ts[0 : start+1]
|
||||
}
|
||||
}
|
||||
} else if e.Value == NoValue && pos > 0 && ts[pos-1].Key == e.Key && ts[pos-1].Value == AnyValue {
|
||||
copy(ts[pos-1:], ts[pos:])
|
||||
ts = ts[:len(ts)-1]
|
||||
}
|
||||
return ts
|
||||
}
|
||||
@@ -107,6 +128,13 @@ func (ts TTagSet) Remove(ele ...STag) TTagSet {
|
||||
return ts
|
||||
}
|
||||
|
||||
func (a TTagSet) Len() int { return len(a) }
|
||||
func (a TTagSet) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a TTagSet) Less(i, j int) bool {
|
||||
r := Compare(a[i], a[j])
|
||||
return r < 0
|
||||
}
|
||||
|
||||
func (a TTagSet) Compact() TTagSet {
|
||||
ret := make(TTagSet, 0, len(a))
|
||||
ret = ret.Append(a...)
|
||||
|
||||
@@ -434,3 +434,144 @@ func TestTagset2MapString(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTagSetAppend(t *testing.T) {
|
||||
cases := []struct {
|
||||
set1 TTagSet
|
||||
set2 TTagSet
|
||||
want TTagSet
|
||||
}{
|
||||
{
|
||||
set1: TTagSet{
|
||||
{
|
||||
Key: "a",
|
||||
Value: "1",
|
||||
},
|
||||
},
|
||||
set2: TTagSet{
|
||||
{
|
||||
Key: "b",
|
||||
Value: "2",
|
||||
},
|
||||
},
|
||||
want: TTagSet{
|
||||
{
|
||||
Key: "a",
|
||||
Value: "1",
|
||||
},
|
||||
{
|
||||
Key: "b",
|
||||
Value: "2",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
set1: TTagSet{
|
||||
{
|
||||
Key: "a",
|
||||
Value: AnyValue,
|
||||
},
|
||||
},
|
||||
set2: TTagSet{
|
||||
{
|
||||
Key: "a",
|
||||
Value: "1",
|
||||
},
|
||||
{
|
||||
Key: "b",
|
||||
Value: "2",
|
||||
},
|
||||
},
|
||||
want: TTagSet{
|
||||
{
|
||||
Key: "a",
|
||||
Value: AnyValue,
|
||||
},
|
||||
{
|
||||
Key: "b",
|
||||
Value: "2",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
set1: TTagSet{
|
||||
{
|
||||
Key: "a",
|
||||
Value: AnyValue,
|
||||
},
|
||||
},
|
||||
set2: TTagSet{
|
||||
{
|
||||
Key: "a",
|
||||
Value: NoValue,
|
||||
},
|
||||
{
|
||||
Key: "b",
|
||||
Value: "2",
|
||||
},
|
||||
},
|
||||
want: TTagSet{
|
||||
{
|
||||
Key: "b",
|
||||
Value: "2",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
set1: TTagSet{
|
||||
{
|
||||
Key: "a",
|
||||
Value: AnyValue,
|
||||
},
|
||||
},
|
||||
set2: TTagSet{
|
||||
{
|
||||
Key: "a",
|
||||
Value: NoValue,
|
||||
},
|
||||
},
|
||||
want: TTagSet{},
|
||||
},
|
||||
{
|
||||
set1: TTagSet{
|
||||
{
|
||||
Key: "a",
|
||||
Value: AnyValue,
|
||||
},
|
||||
},
|
||||
set2: TTagSet{},
|
||||
want: TTagSet{
|
||||
{
|
||||
Key: "a",
|
||||
Value: AnyValue,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
set1: TTagSet{
|
||||
{
|
||||
Key: "a",
|
||||
Value: AnyValue,
|
||||
},
|
||||
},
|
||||
set2: TTagSet{
|
||||
{
|
||||
Key: "a",
|
||||
Value: AnyValue,
|
||||
},
|
||||
},
|
||||
want: TTagSet{
|
||||
{
|
||||
Key: "a",
|
||||
Value: AnyValue,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
got := c.set1.Append(c.set2...)
|
||||
if jsonutils.Marshal(got).String() != jsonutils.Marshal(c.want).String() {
|
||||
t.Errorf("got: %s want: %s", jsonutils.Marshal(got).String(), jsonutils.Marshal(c.want).String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,34 @@ func (tsl TTagSetList) Append(t TTagSet) TTagSetList {
|
||||
return ret
|
||||
}
|
||||
|
||||
func (tsl TTagSetList) Intersect(t TTagSet) TTagSetList {
|
||||
ret := TTagSetList{}
|
||||
for i := 0; i < len(tsl); i++ {
|
||||
ret = ret.Append(tsl[i].Append(t...))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (tsl TTagSetList) IntersectList(t TTagSetList) TTagSetList {
|
||||
if len(tsl) == 0 && len(t) == 0 {
|
||||
return TTagSetList{}
|
||||
}
|
||||
if len(tsl) == 0 && len(t) > 0 {
|
||||
return t
|
||||
}
|
||||
if len(tsl) > 0 && len(t) == 0 {
|
||||
return tsl
|
||||
}
|
||||
ret := TTagSetList{}
|
||||
for i := 0; i < len(t); i++ {
|
||||
tmp := tsl.Intersect(t[i])
|
||||
for j := 0; j < len(tmp); j++ {
|
||||
ret = ret.Append(tmp[j])
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (tsl TTagSetList) String() string {
|
||||
tss := make([]string, len(tsl))
|
||||
for i := 0; i < len(tss); i++ {
|
||||
|
||||
@@ -292,3 +292,138 @@ func TestTTagSetList_Flattern(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntersect(t *testing.T) {
|
||||
cases := []struct {
|
||||
tsl TTagSetList
|
||||
ts TTagSet
|
||||
want TTagSetList
|
||||
}{
|
||||
{
|
||||
tsl: TTagSetList{
|
||||
TTagSet{
|
||||
{
|
||||
Key: "a",
|
||||
Value: "1",
|
||||
},
|
||||
},
|
||||
},
|
||||
ts: TTagSet{
|
||||
{
|
||||
Key: "b",
|
||||
Value: "2",
|
||||
},
|
||||
},
|
||||
want: TTagSetList{
|
||||
TTagSet{
|
||||
{
|
||||
Key: "a",
|
||||
Value: "1",
|
||||
},
|
||||
{
|
||||
Key: "b",
|
||||
Value: "2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
got := c.tsl.Intersect(c.ts)
|
||||
if jsonutils.Marshal(got).String() != jsonutils.Marshal(c.want).String() {
|
||||
t.Errorf("got %s want %s", jsonutils.Marshal(got).String(), jsonutils.Marshal(c.want).String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntersects(t *testing.T) {
|
||||
cases := []struct {
|
||||
tsl TTagSetList
|
||||
ts2 TTagSetList
|
||||
want TTagSetList
|
||||
}{
|
||||
{
|
||||
tsl: TTagSetList{
|
||||
TTagSet{
|
||||
{
|
||||
Key: "a",
|
||||
Value: "1",
|
||||
},
|
||||
},
|
||||
TTagSet{
|
||||
{
|
||||
Key: "b",
|
||||
Value: "1",
|
||||
},
|
||||
},
|
||||
},
|
||||
ts2: TTagSetList{
|
||||
TTagSet{
|
||||
{
|
||||
Key: "c",
|
||||
Value: "2",
|
||||
},
|
||||
},
|
||||
},
|
||||
want: TTagSetList{
|
||||
TTagSet{
|
||||
{
|
||||
Key: "a",
|
||||
Value: "1",
|
||||
},
|
||||
{
|
||||
Key: "c",
|
||||
Value: "2",
|
||||
},
|
||||
},
|
||||
TTagSet{
|
||||
{
|
||||
Key: "b",
|
||||
Value: "1",
|
||||
},
|
||||
{
|
||||
Key: "c",
|
||||
Value: "2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
tsl: TTagSetList{
|
||||
TTagSet{
|
||||
{
|
||||
Key: "a",
|
||||
Value: "1",
|
||||
},
|
||||
},
|
||||
TTagSet{
|
||||
{
|
||||
Key: "b",
|
||||
Value: "1",
|
||||
},
|
||||
},
|
||||
},
|
||||
ts2: TTagSetList{},
|
||||
want: TTagSetList{
|
||||
TTagSet{
|
||||
{
|
||||
Key: "a",
|
||||
Value: "1",
|
||||
},
|
||||
},
|
||||
TTagSet{
|
||||
{
|
||||
Key: "b",
|
||||
Value: "1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
got := c.tsl.IntersectList(c.ts2)
|
||||
if jsonutils.Marshal(got).String() != jsonutils.Marshal(c.want).String() {
|
||||
t.Errorf("got %s want %s", jsonutils.Marshal(got).String(), jsonutils.Marshal(c.want).String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user