129 lines
3.8 KiB
Go
129 lines
3.8 KiB
Go
package teams
|
|
|
|
import (
|
|
acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1"
|
|
"github.com/zalando/postgres-operator/pkg/util"
|
|
)
|
|
|
|
// PostgresTeamMap is the operator's internal representation of all PostgresTeam CRDs
|
|
type PostgresTeamMap map[string]postgresTeamMembership
|
|
|
|
type postgresTeamMembership struct {
|
|
AdditionalSuperuserTeams []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, superuserTeams bool, transitive bool, exclude []string) []string {
|
|
|
|
var teams []string
|
|
|
|
if superuserTeams {
|
|
teams = (*ptm)[team].AdditionalSuperuserTeams
|
|
} else {
|
|
teams = (*ptm)[team].AdditionalTeams
|
|
}
|
|
if transitive {
|
|
for _, additionalTeam := range teams {
|
|
if !(util.SliceContains(exclude, additionalTeam)) {
|
|
// remember to not check team and additionalTeam again
|
|
exclude = append(exclude, additionalTeam)
|
|
transitiveTeams := (*ptm).fetchAdditionalTeams(additionalTeam, superuserTeams, transitive, exclude)
|
|
for _, transitiveTeam := range transitiveTeams {
|
|
if !(util.SliceContains(exclude, transitiveTeam)) {
|
|
// remember to not check transitive team again in case
|
|
// it is one of the next additional teams of the outer loop
|
|
exclude = append(exclude, transitiveTeam)
|
|
if !(util.SliceContains(teams, transitiveTeam)) {
|
|
// found a new transitive additional team
|
|
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{team})
|
|
}
|
|
|
|
// GetAdditionalSuperuserTeams function to retrieve list of additional superuser teams
|
|
func (ptm *PostgresTeamMap) GetAdditionalSuperuserTeams(team string, transitive bool) []string {
|
|
return ptm.fetchAdditionalTeams(team, true, transitive, []string{team})
|
|
}
|
|
|
|
// Load function to import data from PostgresTeam CRD
|
|
func (ptm *PostgresTeamMap) Load(pgTeams *acidv1.PostgresTeamList) {
|
|
// reset the team map
|
|
*ptm = make(PostgresTeamMap, 0)
|
|
|
|
superuserTeamSet := teamHashSet{}
|
|
teamSet := teamHashSet{}
|
|
teamMemberSet := teamHashSet{}
|
|
teamIDs := make(map[string]struct{})
|
|
|
|
for _, pgTeam := range pgTeams.Items {
|
|
superuserTeamSet.mergeCrdMap(pgTeam.Spec.AdditionalSuperuserTeams)
|
|
teamSet.mergeCrdMap(pgTeam.Spec.AdditionalTeams)
|
|
teamMemberSet.mergeCrdMap(pgTeam.Spec.AdditionalMembers)
|
|
}
|
|
fetchTeams(&teamIDs, superuserTeamSet)
|
|
fetchTeams(&teamIDs, teamSet)
|
|
fetchTeams(&teamIDs, teamMemberSet)
|
|
|
|
for teamID := range teamIDs {
|
|
(*ptm)[teamID] = postgresTeamMembership{
|
|
AdditionalSuperuserTeams: util.CoalesceStrArr(superuserTeamSet.toMap()[teamID], []string{}),
|
|
AdditionalTeams: util.CoalesceStrArr(teamSet.toMap()[teamID], []string{}),
|
|
AdditionalMembers: util.CoalesceStrArr(teamMemberSet.toMap()[teamID], []string{}),
|
|
}
|
|
}
|
|
}
|