rework internal structure to be closer to CRD
This commit is contained in:
parent
9f0e1f703b
commit
0f86eff13e
|
|
@ -16,8 +16,8 @@ import (
|
|||
"github.com/sirupsen/logrus"
|
||||
acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1"
|
||||
"github.com/zalando/postgres-operator/pkg/generated/clientset/versioned/scheme"
|
||||
"github.com/zalando/postgres-operator/pkg/postgresteams"
|
||||
"github.com/zalando/postgres-operator/pkg/spec"
|
||||
pgteams "github.com/zalando/postgres-operator/pkg/teams"
|
||||
"github.com/zalando/postgres-operator/pkg/util"
|
||||
"github.com/zalando/postgres-operator/pkg/util/config"
|
||||
"github.com/zalando/postgres-operator/pkg/util/constants"
|
||||
|
|
@ -48,7 +48,7 @@ var (
|
|||
type Config struct {
|
||||
OpConfig config.Config
|
||||
RestConfig *rest.Config
|
||||
PgTeamMap postgresteams.PostgresTeamMap
|
||||
PgTeamMap pgteams.PostgresTeamMap
|
||||
InfrastructureRoles map[string]spec.PgUser // inherited from the controller
|
||||
PodServiceAccount *v1.ServiceAccount
|
||||
PodServiceAccountRoleBinding *rbacv1.RoleBinding
|
||||
|
|
@ -1130,22 +1130,27 @@ func (c *Cluster) initTeamMembers(teamID string, isPostgresSuperuserTeam bool) e
|
|||
|
||||
func (c *Cluster) initHumanUsers() error {
|
||||
|
||||
adminTeams := c.PgTeamMap.GetAdditionalTeams(c.Spec.TeamID, true)
|
||||
var clusterIsOwnedBySuperuserTeam bool
|
||||
for _, postgresSuperuserTeam := range c.OpConfig.PostgresSuperuserTeams {
|
||||
isAdditionalAdminTeam := false
|
||||
for _, adminTeam := range adminTeams {
|
||||
if postgresSuperuserTeam == adminTeam {
|
||||
isAdditionalAdminTeam = true
|
||||
}
|
||||
}
|
||||
if !(isAdditionalAdminTeam) {
|
||||
adminTeams = append(adminTeams, postgresSuperuserTeam)
|
||||
}
|
||||
if postgresSuperuserTeam == c.Spec.TeamID {
|
||||
clusterIsOwnedBySuperuserTeam = true
|
||||
}
|
||||
}
|
||||
|
||||
c.PgTeamMap.MergeTeams(c.Spec.TeamID, c.OpConfig.PostgresSuperuserTeams, true)
|
||||
for additionalTeam := range c.PgTeamMap[c.Spec.TeamID].AdditionalTeams {
|
||||
err := c.initTeamMembers(additionalTeam.Name, additionalTeam.IsAdmin)
|
||||
for _, adminTeam := range adminTeams {
|
||||
err := c.initTeamMembers(adminTeam, true)
|
||||
if err != nil {
|
||||
errorMsg := fmt.Sprintf("Cannot create team %q", additionalTeam.Name)
|
||||
if additionalTeam.IsAdmin {
|
||||
errorMsg = errorMsg + " of Postgres superusers"
|
||||
}
|
||||
return fmt.Errorf(errorMsg+": %v", err)
|
||||
return fmt.Errorf("Cannot create team %q of Postgres superusers: %v", adminTeam, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1159,6 +1164,14 @@ func (c *Cluster) initHumanUsers() error {
|
|||
return fmt.Errorf("Cannot create a team %q of admins owning the PG cluster: %v", c.Spec.TeamID, err)
|
||||
}
|
||||
|
||||
additionalTeams := c.PgTeamMap.GetAdditionalTeams(c.Spec.TeamID, true)
|
||||
for _, additionalTeam := range additionalTeams {
|
||||
err := c.initTeamMembers(additionalTeam, false)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Cannot create additional team %q for cluster owner by %q: %v", additionalTeam, c.Spec.TeamID, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ func (c *Cluster) getTeamMembers(teamID string) ([]string, error) {
|
|||
c.logger.Debugf("fetching possible additional team members for team %q", teamID)
|
||||
members := []string{}
|
||||
additionalMembers := c.PgTeamMap[c.Spec.TeamID].AdditionalMembers
|
||||
for member := range additionalMembers {
|
||||
for _, member := range additionalMembers {
|
||||
members = append(members, member)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ import (
|
|||
"github.com/zalando/postgres-operator/pkg/apiserver"
|
||||
"github.com/zalando/postgres-operator/pkg/cluster"
|
||||
acidv1informer "github.com/zalando/postgres-operator/pkg/generated/informers/externalversions/acid.zalan.do/v1"
|
||||
"github.com/zalando/postgres-operator/pkg/postgresteams"
|
||||
"github.com/zalando/postgres-operator/pkg/spec"
|
||||
"github.com/zalando/postgres-operator/pkg/teams"
|
||||
"github.com/zalando/postgres-operator/pkg/util"
|
||||
"github.com/zalando/postgres-operator/pkg/util/config"
|
||||
"github.com/zalando/postgres-operator/pkg/util/constants"
|
||||
|
|
@ -34,7 +34,7 @@ import (
|
|||
type Controller struct {
|
||||
config spec.ControllerConfig
|
||||
opConfig *config.Config
|
||||
pgTeamMap *postgresteams.PostgresTeamMap
|
||||
pgTeamMap *teams.PostgresTeamMap
|
||||
|
||||
logger *logrus.Entry
|
||||
KubeClient k8sutil.KubernetesClient
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ import (
|
|||
|
||||
acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1"
|
||||
"github.com/zalando/postgres-operator/pkg/cluster"
|
||||
"github.com/zalando/postgres-operator/pkg/postgresteams"
|
||||
"github.com/zalando/postgres-operator/pkg/spec"
|
||||
"github.com/zalando/postgres-operator/pkg/teams"
|
||||
"github.com/zalando/postgres-operator/pkg/util"
|
||||
"github.com/zalando/postgres-operator/pkg/util/config"
|
||||
"github.com/zalando/postgres-operator/pkg/util/k8sutil"
|
||||
|
|
@ -396,7 +396,7 @@ func (c *Controller) getInfrastructureRole(
|
|||
}
|
||||
|
||||
func (c *Controller) loadPostgresTeams(obj interface{}) {
|
||||
var pgTeamMap postgresteams.PostgresTeamMap
|
||||
var pgTeamMap teams.PostgresTeamMap
|
||||
|
||||
pgTeam, ok := obj.(*acidv1.PostgresTeam)
|
||||
if !ok {
|
||||
|
|
|
|||
|
|
@ -1,103 +0,0 @@
|
|||
package postgresteams
|
||||
|
||||
import (
|
||||
acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1"
|
||||
)
|
||||
|
||||
// PostgresTeamMap is the operator's internal representation of all PostgresTeam CRDs
|
||||
type PostgresTeamMap map[string]postgresTeamMembership
|
||||
|
||||
type postgresTeamMembership struct {
|
||||
AdditionalTeams map[additionalTeam]struct{}
|
||||
AdditionalMembers map[string]struct{}
|
||||
}
|
||||
|
||||
type additionalTeam struct {
|
||||
Name string
|
||||
IsAdmin bool
|
||||
}
|
||||
|
||||
type teamHashSet map[string]map[string]struct{}
|
||||
|
||||
func (ths *teamHashSet) has(team string) bool {
|
||||
_, ok := (*ths)[team]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (ths *teamHashSet) add(newTeam string, newSet []string) {
|
||||
set := make(map[string]struct{})
|
||||
if ths.has(newTeam) {
|
||||
set = (*ths)[newTeam]
|
||||
}
|
||||
for _, t := range newSet {
|
||||
set[t] = struct{}{}
|
||||
}
|
||||
(*ths)[newTeam] = set
|
||||
}
|
||||
|
||||
func (ths *teamHashSet) mergeCrdMap(crdTeamMap map[string][]string) {
|
||||
for t, at := range crdTeamMap {
|
||||
ths.add(t, at)
|
||||
}
|
||||
}
|
||||
|
||||
func (pgt *PostgresTeamMap) mapTeams(set teamHashSet, isAdmin bool) {
|
||||
for team, items := range set {
|
||||
newAdditionalTeams := make(map[additionalTeam]struct{})
|
||||
newAdditionalMembers := make(map[string]struct{})
|
||||
if currentTeamMembership, exists := (*pgt)[team]; exists {
|
||||
newAdditionalTeams = currentTeamMembership.AdditionalTeams
|
||||
newAdditionalMembers = currentTeamMembership.AdditionalMembers
|
||||
}
|
||||
for newTeam := range items {
|
||||
newAdditionalTeams[additionalTeam{
|
||||
Name: newTeam,
|
||||
IsAdmin: isAdmin,
|
||||
}] = struct{}{}
|
||||
}
|
||||
if len(newAdditionalTeams) > 0 {
|
||||
(*pgt)[team] = postgresTeamMembership{newAdditionalTeams, newAdditionalMembers}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (pgt *PostgresTeamMap) mapMembers(set teamHashSet) {
|
||||
for team, items := range set {
|
||||
newAdditionalTeams := make(map[additionalTeam]struct{})
|
||||
newAdditionalMembers := make(map[string]struct{})
|
||||
if currentTeamMembership, exists := (*pgt)[team]; exists {
|
||||
newAdditionalTeams = currentTeamMembership.AdditionalTeams
|
||||
newAdditionalMembers = currentTeamMembership.AdditionalMembers
|
||||
}
|
||||
for additionalMember := range items {
|
||||
newAdditionalMembers[additionalMember] = struct{}{}
|
||||
}
|
||||
(*pgt)[team] = postgresTeamMembership{newAdditionalTeams, newAdditionalMembers}
|
||||
}
|
||||
}
|
||||
|
||||
// Load function to import data from PostgresTeam CRD
|
||||
func (pgt *PostgresTeamMap) Load(pgTeams *acidv1.PostgresTeamList) {
|
||||
|
||||
adminTeamSet := teamHashSet{}
|
||||
teamSet := teamHashSet{}
|
||||
teamMemberSet := teamHashSet{}
|
||||
|
||||
for _, pgTeam := range pgTeams.Items {
|
||||
adminTeamSet.mergeCrdMap(pgTeam.Spec.AdditionalAdminTeams)
|
||||
teamSet.mergeCrdMap(pgTeam.Spec.AdditionalTeams)
|
||||
teamMemberSet.mergeCrdMap(pgTeam.Spec.AdditionalMembers)
|
||||
}
|
||||
pgt.mapTeams(adminTeamSet, true)
|
||||
pgt.mapTeams(teamSet, false)
|
||||
pgt.mapMembers(teamMemberSet)
|
||||
}
|
||||
|
||||
// MergeTeams function to add additional teams to internal team map
|
||||
func (pgt *PostgresTeamMap) MergeTeams(teamID string, additionalTeams []string, isAdmin bool) {
|
||||
teamSet := teamHashSet{}
|
||||
if len(additionalTeams) > 0 {
|
||||
teamSet.add(teamID, additionalTeams)
|
||||
pgt.mapTeams(teamSet, isAdmin)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
package teams
|
||||
|
||||
import (
|
||||
acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1"
|
||||
)
|
||||
|
||||
// PostgresTeamMap is the operator's internal representation of all PostgresTeam CRDs
|
||||
type PostgresTeamMap map[string]postgresTeamMembership
|
||||
|
||||
type postgresTeamMembership struct {
|
||||
AdditionalAdminTeams []string
|
||||
AdditionalTeams []string
|
||||
AdditionalMembers []string
|
||||
}
|
||||
|
||||
type teamHashSet map[string]map[string]struct{}
|
||||
|
||||
func (ths *teamHashSet) has(team string) bool {
|
||||
_, ok := (*ths)[team]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (ths *teamHashSet) add(newTeam string, newSet []string) {
|
||||
set := make(map[string]struct{})
|
||||
if ths.has(newTeam) {
|
||||
set = (*ths)[newTeam]
|
||||
}
|
||||
for _, t := range newSet {
|
||||
set[t] = struct{}{}
|
||||
}
|
||||
(*ths)[newTeam] = set
|
||||
}
|
||||
|
||||
func (ths *teamHashSet) toMap() map[string][]string {
|
||||
newTeamMap := make(map[string][]string)
|
||||
for team, items := range *ths {
|
||||
list := []string{}
|
||||
for item := range items {
|
||||
list = append(list, item)
|
||||
}
|
||||
newTeamMap[team] = list
|
||||
}
|
||||
return newTeamMap
|
||||
}
|
||||
|
||||
func (ths *teamHashSet) mergeCrdMap(crdTeamMap map[string][]string) {
|
||||
for t, at := range crdTeamMap {
|
||||
ths.add(t, at)
|
||||
}
|
||||
}
|
||||
|
||||
func fetchTeams(teamset *map[string]struct{}, set teamHashSet) {
|
||||
for key := range set {
|
||||
(*teamset)[key] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
func (ptm *PostgresTeamMap) fetchAdditionalTeams(team string, adminTeams bool, transitive bool, exclude *[]string) []string {
|
||||
|
||||
var teams, allTeams []string
|
||||
|
||||
if adminTeams {
|
||||
teams = (*ptm)[team].AdditionalAdminTeams
|
||||
allTeams = teams
|
||||
for _, otherPrivilegedTeam := range (*ptm)[team].AdditionalTeams {
|
||||
allTeams = append(allTeams, otherPrivilegedTeam)
|
||||
}
|
||||
} else {
|
||||
teams = (*ptm)[team].AdditionalTeams
|
||||
allTeams = teams
|
||||
for _, otherPrivilegedTeam := range (*ptm)[team].AdditionalAdminTeams {
|
||||
allTeams = append(allTeams, otherPrivilegedTeam)
|
||||
}
|
||||
}
|
||||
if transitive {
|
||||
*exclude = append(*exclude, team)
|
||||
for _, additionalTeam := range allTeams {
|
||||
getTransitiveTeams := true
|
||||
for _, excludedTeam := range *exclude {
|
||||
if additionalTeam == excludedTeam {
|
||||
getTransitiveTeams = false
|
||||
}
|
||||
}
|
||||
if getTransitiveTeams {
|
||||
transitiveTeams := (*ptm).fetchAdditionalTeams(additionalTeam, adminTeams, transitive, exclude)
|
||||
|
||||
if len(transitiveTeams) > 0 {
|
||||
for _, transitiveTeam := range transitiveTeams {
|
||||
teams = append(teams, transitiveTeam)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return teams
|
||||
}
|
||||
|
||||
// GetAdditionalTeams function to retrieve list of additional teams
|
||||
func (ptm *PostgresTeamMap) GetAdditionalTeams(team string, transitive bool) []string {
|
||||
return ptm.fetchAdditionalTeams(team, false, transitive, &[]string{})
|
||||
}
|
||||
|
||||
// GetAdditionalTeams function to retrieve list of additional teams
|
||||
func (ptm *PostgresTeamMap) GetAdditionalAdminTeams(team string, transitive bool) []string {
|
||||
return ptm.fetchAdditionalTeams(team, true, transitive, &[]string{})
|
||||
}
|
||||
|
||||
// Load function to import data from PostgresTeam CRD
|
||||
func (ptm *PostgresTeamMap) Load(pgTeams *acidv1.PostgresTeamList) {
|
||||
adminTeamSet := teamHashSet{}
|
||||
teamSet := teamHashSet{}
|
||||
teamMemberSet := teamHashSet{}
|
||||
teamIDs := make(map[string]struct{})
|
||||
|
||||
for _, pgTeam := range pgTeams.Items {
|
||||
adminTeamSet.mergeCrdMap(pgTeam.Spec.AdditionalAdminTeams)
|
||||
teamSet.mergeCrdMap(pgTeam.Spec.AdditionalTeams)
|
||||
teamMemberSet.mergeCrdMap(pgTeam.Spec.AdditionalMembers)
|
||||
}
|
||||
fetchTeams(&teamIDs, adminTeamSet)
|
||||
fetchTeams(&teamIDs, teamSet)
|
||||
fetchTeams(&teamIDs, teamMemberSet)
|
||||
|
||||
for teamID := range teamIDs {
|
||||
(*ptm)[teamID] = postgresTeamMembership{
|
||||
AdditionalAdminTeams: adminTeamSet.toMap()[teamID],
|
||||
AdditionalTeams: teamSet.toMap()[teamID],
|
||||
AdditionalMembers: teamMemberSet.toMap()[teamID],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package postgresteams
|
||||
package teams
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
|
@ -14,7 +14,7 @@ var (
|
|||
)
|
||||
|
||||
// PostgresTeamMap is the operator's internal representation of all PostgresTeam CRDs
|
||||
func TestLoadinngPostgresTeamCRD(t *testing.T) {
|
||||
func TestLoadingPostgresTeamCRD(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
crd acidv1.PostgresTeamList
|
||||
|
|
@ -60,41 +60,29 @@ func TestLoadinngPostgresTeamCRD(t *testing.T) {
|
|||
},
|
||||
PostgresTeamMap{
|
||||
"teamA": {
|
||||
AdditionalTeams: map[additionalTeam]struct{}{
|
||||
additionalTeam{Name: "teamB", IsAdmin: True}: {},
|
||||
additionalTeam{Name: "team24/7", IsAdmin: True}: {},
|
||||
additionalTeam{Name: "teamC", IsAdmin: False}: {},
|
||||
},
|
||||
AdditionalMembers: map[string]struct{}{},
|
||||
AdditionalAdminTeams: []string{"teamB", "team24/7"},
|
||||
AdditionalTeams: []string{"teamC"},
|
||||
AdditionalMembers: nil,
|
||||
},
|
||||
"teamB": {
|
||||
AdditionalTeams: map[additionalTeam]struct{}{
|
||||
additionalTeam{Name: "teamA", IsAdmin: True}: {},
|
||||
additionalTeam{Name: "team24/7", IsAdmin: True}: {},
|
||||
},
|
||||
AdditionalMembers: map[string]struct{}{
|
||||
"drno": {},
|
||||
},
|
||||
AdditionalAdminTeams: []string{"teamA", "team24/7"},
|
||||
AdditionalTeams: []string{},
|
||||
AdditionalMembers: []string{"drno"},
|
||||
},
|
||||
"teamC": {
|
||||
AdditionalTeams: map[additionalTeam]struct{}{
|
||||
additionalTeam{Name: "team24/7", IsAdmin: True}: {},
|
||||
additionalTeam{Name: "teamA", IsAdmin: False}: {},
|
||||
additionalTeam{Name: "teamB", IsAdmin: False}: {},
|
||||
},
|
||||
AdditionalMembers: map[string]struct{}{},
|
||||
AdditionalAdminTeams: []string{"team24/7"},
|
||||
AdditionalTeams: []string{"teamA", "teamB"},
|
||||
AdditionalMembers: nil,
|
||||
},
|
||||
"team24/7": {
|
||||
AdditionalTeams: map[additionalTeam]struct{}{},
|
||||
AdditionalMembers: map[string]struct{}{
|
||||
"optimusprime": {},
|
||||
},
|
||||
AdditionalAdminTeams: nil,
|
||||
AdditionalTeams: nil,
|
||||
AdditionalMembers: []string{"optimusprime"},
|
||||
},
|
||||
"acid": {
|
||||
AdditionalTeams: map[additionalTeam]struct{}{},
|
||||
AdditionalMembers: map[string]struct{}{
|
||||
"batman": {},
|
||||
},
|
||||
AdditionalAdminTeams: nil,
|
||||
AdditionalTeams: nil,
|
||||
AdditionalMembers: []string{"batman"},
|
||||
},
|
||||
},
|
||||
"Mismatch between PostgresTeam CRD and internal map",
|
||||
|
|
@ -104,8 +92,9 @@ func TestLoadinngPostgresTeamCRD(t *testing.T) {
|
|||
for _, tt := range tests {
|
||||
postgresTeamMap := PostgresTeamMap{}
|
||||
postgresTeamMap.Load(&tt.crd)
|
||||
// TODO order in slice is not deterministic so choose other compare method
|
||||
if !reflect.DeepEqual(postgresTeamMap, tt.pgt) {
|
||||
t.Errorf("%s: %v", tt.name, tt.error)
|
||||
t.Errorf("%s: %v: expected %#v, got %#v", tt.name, tt.error, tt.pgt, postgresTeamMap)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue