Skip to content

Commit

Permalink
fix: recode sync public_src of cloud resources
Browse files Browse the repository at this point in the history
  • Loading branch information
Qiu Jian committed May 9, 2020
1 parent ffd8ab6 commit bea90b4
Show file tree
Hide file tree
Showing 6 changed files with 435 additions and 70 deletions.
7 changes: 4 additions & 3 deletions pkg/apis/compute/cloudaccount_const.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package compute

import (
"yunion.io/x/onecloud/pkg/apis"
"yunion.io/x/onecloud/pkg/cloudprovider"
)

Expand Down Expand Up @@ -103,9 +104,9 @@ const (
)

const (
CLOUD_ACCOUNT_SHARE_MODE_ACCOUNT_DOMAIN = "account_domain"
CLOUD_ACCOUNT_SHARE_MODE_SYSTEM = "system"
CLOUD_ACCOUNT_SHARE_MODE_PROVIDER_DOMAIN = "provider_domain"
CLOUD_ACCOUNT_SHARE_MODE_ACCOUNT_DOMAIN = apis.CLOUD_ACCOUNT_SHARE_MODE_ACCOUNT_DOMAIN
CLOUD_ACCOUNT_SHARE_MODE_SYSTEM = apis.CLOUD_ACCOUNT_SHARE_MODE_SYSTEM
CLOUD_ACCOUNT_SHARE_MODE_PROVIDER_DOMAIN = apis.CLOUD_ACCOUNT_SHARE_MODE_PROVIDER_DOMAIN
)

var (
Expand Down
147 changes: 146 additions & 1 deletion pkg/apis/share.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,156 @@

package apis

import "yunion.io/x/onecloud/pkg/util/rbacutils"
import (
"yunion.io/x/onecloud/pkg/util/rbacutils"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)

const (
CLOUD_ACCOUNT_SHARE_MODE_ACCOUNT_DOMAIN = "account_domain"
CLOUD_ACCOUNT_SHARE_MODE_SYSTEM = "system"
CLOUD_ACCOUNT_SHARE_MODE_PROVIDER_DOMAIN = "provider_domain"
)

type SAccountShareInfo struct {
IsPublic bool
PublicScope rbacutils.TRbacScope
ShareMode string
SharedDomains []string
}

type SShareInfo struct {
IsPublic bool
PublicScope rbacutils.TRbacScope
SharedDomains []string
SharedProjects []string
}

func (i SAccountShareInfo) GetProjectShareInfo() SShareInfo {
ret := SShareInfo{}
switch i.ShareMode {
case CLOUD_ACCOUNT_SHARE_MODE_ACCOUNT_DOMAIN:
ret.IsPublic = true
ret.PublicScope = rbacutils.ScopeDomain
case CLOUD_ACCOUNT_SHARE_MODE_PROVIDER_DOMAIN:
ret.IsPublic = true
ret.PublicScope = rbacutils.ScopeDomain
case CLOUD_ACCOUNT_SHARE_MODE_SYSTEM:
ret.IsPublic = true
if i.IsPublic && i.PublicScope == rbacutils.ScopeSystem {
ret.PublicScope = rbacutils.ScopeSystem
} else {
ret.PublicScope = rbacutils.ScopeDomain
ret.SharedDomains = i.SharedDomains
}
}
return ret
}

func (i SAccountShareInfo) GetDomainShareInfo() SShareInfo {
ret := SShareInfo{}
switch i.ShareMode {
case CLOUD_ACCOUNT_SHARE_MODE_ACCOUNT_DOMAIN:
ret.IsPublic = false
ret.PublicScope = rbacutils.ScopeNone
case CLOUD_ACCOUNT_SHARE_MODE_PROVIDER_DOMAIN:
ret.IsPublic = false
ret.PublicScope = rbacutils.ScopeNone
case CLOUD_ACCOUNT_SHARE_MODE_SYSTEM:
if i.IsPublic && i.PublicScope == rbacutils.ScopeSystem {
ret.IsPublic = true
ret.PublicScope = rbacutils.ScopeSystem
} else if len(i.SharedDomains) > 0 {
ret.IsPublic = true
ret.PublicScope = rbacutils.ScopeDomain
ret.SharedDomains = i.SharedDomains
} else {
ret.IsPublic = false
ret.PublicScope = rbacutils.ScopeNone
}
}
return ret
}

func (i SShareInfo) IsViolate(i2 SShareInfo) bool {
if i.IsPublic && !i2.IsPublic {
return true
} else if !i.IsPublic && i2.IsPublic {
return false
}
// is_public equals
if i.PublicScope.HigherThan(i2.PublicScope) {
return true
} else if i2.PublicScope.HigherThan(i.PublicScope) {
return false
}
// public_scope equals
aNoB, _, bNoA := stringutils2.Split(stringutils2.NewSortedStrings(i.SharedDomains), stringutils2.NewSortedStrings(i2.SharedDomains))
if len(aNoB) > 0 {
return true
} else if len(bNoA) > 0 {
return false
}
// shared_domains equals
aNoB, _, bNoA = stringutils2.Split(stringutils2.NewSortedStrings(i.SharedProjects), stringutils2.NewSortedStrings(i2.SharedProjects))
if len(aNoB) > 0 {
return true
} else if len(bNoA) > 0 {
return false
}
return false
}

func (i SShareInfo) Intersect(i2 SShareInfo) SShareInfo {
if i.IsPublic && !i2.IsPublic {
return i2
} else if !i.IsPublic && i2.IsPublic {
return i
}
// is_public equals
if i.PublicScope.HigherThan(i2.PublicScope) {
return i2
} else if i2.PublicScope.HigherThan(i.PublicScope) {
return i
}
// public_scope equals
_, domains, _ := stringutils2.Split(stringutils2.NewSortedStrings(i.SharedDomains), stringutils2.NewSortedStrings(i2.SharedDomains))
_, projs, _ := stringutils2.Split(stringutils2.NewSortedStrings(i.SharedProjects), stringutils2.NewSortedStrings(i2.SharedProjects))
ret := SShareInfo{
IsPublic: i.IsPublic,
PublicScope: i.PublicScope,
SharedDomains: domains,
SharedProjects: projs,
}
if ret.PublicScope == rbacutils.ScopeProject && len(ret.SharedProjects) == 0 {
ret.IsPublic = false
ret.PublicScope = rbacutils.ScopeNone
}
return ret
}

func (i SShareInfo) Equals(i2 SShareInfo) bool {
if !i.IsViolate(i2) && !i2.IsViolate(i) {
return true
} else {
return false
}
}

func (i *SShareInfo) FixProjectShare() {
if i.PublicScope == rbacutils.ScopeProject && len(i.SharedProjects) == 0 {
i.IsPublic = false
i.PublicScope = rbacutils.ScopeNone
}
}

func (i *SShareInfo) FixDomainShare() {
if i.PublicScope == rbacutils.ScopeProject {
i.IsPublic = false
i.PublicScope = rbacutils.ScopeNone
i.SharedProjects = nil
} else if i.PublicScope == rbacutils.ScopeDomain && len(i.SharedDomains) == 0 {
i.IsPublic = false
i.PublicScope = rbacutils.ScopeNone
}
}
199 changes: 199 additions & 0 deletions pkg/apis/share_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
// 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 apis

import (
"testing"

"yunion.io/x/onecloud/pkg/util/rbacutils"
)

func TestSShareInfo_IsViolate(t *testing.T) {
cases := []struct {
name string
s1 SShareInfo
s2 SShareInfo
violate1 bool
violate2 bool
}{
{
name: "case1",
s1: SShareInfo{
IsPublic: false,
PublicScope: rbacutils.ScopeNone,
},
s2: SShareInfo{
IsPublic: true,
PublicScope: rbacutils.ScopeSystem,
},
violate1: false,
violate2: true,
},
{
name: "case2",
s1: SShareInfo{
IsPublic: true,
PublicScope: rbacutils.ScopeProject,
SharedProjects: []string{"p1"},
},
s2: SShareInfo{
IsPublic: true,
PublicScope: rbacutils.ScopeProject,
SharedProjects: []string{"p2"},
},
violate1: true,
violate2: true,
},
{
name: "case3",
s1: SShareInfo{
IsPublic: true,
PublicScope: rbacutils.ScopeDomain,
SharedDomains: []string{"p1"},
},
s2: SShareInfo{
IsPublic: true,
PublicScope: rbacutils.ScopeProject,
SharedProjects: []string{"p2"},
},
violate1: true,
violate2: false,
},
{
name: "case4",
s1: SShareInfo{
IsPublic: true,
PublicScope: rbacutils.ScopeDomain,
SharedDomains: []string{"p1", "p2"},
},
s2: SShareInfo{
IsPublic: true,
PublicScope: rbacutils.ScopeDomain,
SharedDomains: []string{"p1", "p2"},
},
violate1: false,
violate2: false,
},
}
for _, c := range cases {
if c.s1.IsViolate(c.s2) != c.violate1 {
t.Errorf("[%s] s1.violate(s2) want %v", c.name, c.violate1)
} else if c.s2.IsViolate(c.s1) != c.violate2 {
t.Errorf("[%s] s2.violate(s1) want: %v", c.name, c.violate2)
}
}
}

func TestSShareInfo_Intersect(t *testing.T) {
cases := []struct {
name string
s1 SShareInfo
s2 SShareInfo
want SShareInfo
}{
{
name: "case1",
s1: SShareInfo{
IsPublic: false,
PublicScope: rbacutils.ScopeNone,
},
s2: SShareInfo{
IsPublic: true,
PublicScope: rbacutils.ScopeSystem,
},
want: SShareInfo{
IsPublic: false,
PublicScope: rbacutils.ScopeNone,
},
},
{
name: "case2",
s1: SShareInfo{
IsPublic: true,
PublicScope: rbacutils.ScopeProject,
SharedProjects: []string{"p1"},
},
s2: SShareInfo{
IsPublic: true,
PublicScope: rbacutils.ScopeProject,
SharedProjects: []string{"p2"},
},
want: SShareInfo{
IsPublic: false,
PublicScope: rbacutils.ScopeNone,
},
},
{
name: "case3",
s1: SShareInfo{
IsPublic: true,
PublicScope: rbacutils.ScopeDomain,
SharedDomains: []string{"p1"},
},
s2: SShareInfo{
IsPublic: true,
PublicScope: rbacutils.ScopeProject,
SharedProjects: []string{"p2"},
},
want: SShareInfo{
IsPublic: true,
PublicScope: rbacutils.ScopeProject,
SharedProjects: []string{"p2"},
},
},
{
name: "case4",
s1: SShareInfo{
IsPublic: true,
PublicScope: rbacutils.ScopeDomain,
SharedDomains: []string{"p1", "p2"},
},
s2: SShareInfo{
IsPublic: true,
PublicScope: rbacutils.ScopeDomain,
SharedDomains: []string{"p1", "p2"},
},
want: SShareInfo{
IsPublic: true,
PublicScope: rbacutils.ScopeDomain,
SharedDomains: []string{"p1", "p2"},
},
},
{
name: "case5",
s1: SShareInfo{
IsPublic: true,
PublicScope: rbacutils.ScopeDomain,
SharedDomains: []string{"p1", "p2", "p4"},
},
s2: SShareInfo{
IsPublic: true,
PublicScope: rbacutils.ScopeDomain,
SharedDomains: []string{"p1", "p2", "p3"},
},
want: SShareInfo{
IsPublic: true,
PublicScope: rbacutils.ScopeDomain,
SharedDomains: []string{"p1", "p2"},
},
},
}
for _, c := range cases {
inter := c.s1.Intersect(c.s2)
if !inter.Equals(c.want) {
t.Errorf("[%s] intersect got %#v != want %#v", c.name, inter, c.want)
}
}
}

0 comments on commit bea90b4

Please sign in to comment.