Generate CRD for postgresteam resource (#3004)

* Sort postgresteam.crd.yaml

Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>

* Generate CRD for postgresteam resource

Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>

---------

Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
Co-authored-by: Felix Kunde <felix-kunde@gmx.de>
This commit is contained in:
Mikkel Oscar Lyderik Larsen
2026-01-10 19:39:08 +01:00
committed by GitHub
co-authored by Felix Kunde
parent c331fd9434
commit 0a44252534
9 changed files with 252 additions and 85 deletions
@@ -8,18 +8,33 @@ import (
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PostgresTeam defines Custom Resource Definition Object for team management.
// +k8s:deepcopy-gen=true
// +kubebuilder:resource:shortName=pgteam,categories=all
// +kubebuilder:subresource:status
type PostgresTeam struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
metav1.ObjectMeta `json:"metadata"`
Spec PostgresTeamSpec `json:"spec"`
}
// List of users who will also be added to the Postgres cluster.
type Users []string
// List of teams whose members will also be added to the Postgres cluster.
type Teams []string
// List of teams to become Postgres superusers
type SuperUserTeams []string
// PostgresTeamSpec defines the specification for the PostgresTeam TPR.
type PostgresTeamSpec struct {
AdditionalSuperuserTeams map[string][]string `json:"additionalSuperuserTeams,omitempty"`
AdditionalTeams map[string][]string `json:"additionalTeams,omitempty"`
AdditionalMembers map[string][]string `json:"additionalMembers,omitempty"`
// Map for teamId and associated additional superuser teams
AdditionalSuperuserTeams map[string]SuperUserTeams `json:"additionalSuperuserTeams,omitempty"`
// Map for teamId and associated additional teams
AdditionalTeams map[string]Teams `json:"additionalTeams,omitempty"`
// Map for teamId and associated additional users
AdditionalMembers map[string]Users `json:"additionalMembers,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
@@ -975,14 +975,14 @@ func (in *PostgresTeamSpec) DeepCopyInto(out *PostgresTeamSpec) {
*out = *in
if in.AdditionalSuperuserTeams != nil {
in, out := &in.AdditionalSuperuserTeams, &out.AdditionalSuperuserTeams
*out = make(map[string][]string, len(*in))
*out = make(map[string]SuperUserTeams, len(*in))
for key, val := range *in {
var outVal []string
if val == nil {
(*out)[key] = nil
} else {
in, out := &val, &outVal
*out = make([]string, len(*in))
*out = make(SuperUserTeams, len(*in))
copy(*out, *in)
}
(*out)[key] = outVal
@@ -990,14 +990,14 @@ func (in *PostgresTeamSpec) DeepCopyInto(out *PostgresTeamSpec) {
}
if in.AdditionalTeams != nil {
in, out := &in.AdditionalTeams, &out.AdditionalTeams
*out = make(map[string][]string, len(*in))
*out = make(map[string]Teams, len(*in))
for key, val := range *in {
var outVal []string
if val == nil {
(*out)[key] = nil
} else {
in, out := &val, &outVal
*out = make([]string, len(*in))
*out = make(Teams, len(*in))
copy(*out, *in)
}
(*out)[key] = outVal
@@ -1005,14 +1005,14 @@ func (in *PostgresTeamSpec) DeepCopyInto(out *PostgresTeamSpec) {
}
if in.AdditionalMembers != nil {
in, out := &in.AdditionalMembers, &out.AdditionalMembers
*out = make(map[string][]string, len(*in))
*out = make(map[string]Users, len(*in))
for key, val := range *in {
var outVal []string
if val == nil {
(*out)[key] = nil
} else {
in, out := &val, &outVal
*out = make([]string, len(*in))
*out = make(Users, len(*in))
copy(*out, *in)
}
(*out)[key] = outVal
@@ -1400,6 +1400,26 @@ func (in *StreamTable) DeepCopy() *StreamTable {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in SuperUserTeams) DeepCopyInto(out *SuperUserTeams) {
{
in := &in
*out = make(SuperUserTeams, len(*in))
copy(*out, *in)
return
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SuperUserTeams.
func (in SuperUserTeams) DeepCopy() SuperUserTeams {
if in == nil {
return nil
}
out := new(SuperUserTeams)
in.DeepCopyInto(out)
return *out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TLSDescription) DeepCopyInto(out *TLSDescription) {
*out = *in
@@ -1416,6 +1436,26 @@ func (in *TLSDescription) DeepCopy() *TLSDescription {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in Teams) DeepCopyInto(out *Teams) {
{
in := &in
*out = make(Teams, len(*in))
copy(*out, *in)
return
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Teams.
func (in Teams) DeepCopy() Teams {
if in == nil {
return nil
}
out := new(Teams)
in.DeepCopyInto(out)
return *out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TeamsAPIConfiguration) DeepCopyInto(out *TeamsAPIConfiguration) {
*out = *in
@@ -1469,6 +1509,26 @@ func (in UserFlags) DeepCopy() UserFlags {
return *out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in Users) DeepCopyInto(out *Users) {
{
in := &in
*out = make(Users, len(*in))
copy(*out, *in)
return
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Users.
func (in Users) DeepCopy() Users {
if in == nil {
return nil
}
out := new(Users)
in.DeepCopyInto(out)
return *out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Volume) DeepCopyInto(out *Volume) {
*out = *in
+33 -6
View File
@@ -14,8 +14,39 @@ import (
"k8s.io/client-go/rest"
)
// NamespacedName describes the namespace/name pairs used in Kubernetes names.
type NamespacedName types.NamespacedName
// NamespacedName comprises a resource name, with a mandatory namespace,
// rendered as "<namespace>/<name>". Being a type captures intent and
// helps make sure that UIDs, namespaced names and non-namespaced names
// do not get conflated in code. For most use cases, namespace and name
// will already have been format validated at the API entry point, so we
// don't do that here. Where that's not the case (e.g. in testing),
// consider using NamespacedNameOrDie() in testing.go in this package.
//
// from: https://github.com/kubernetes/apimachinery/blob/master/pkg/types/namespacedname.go
type NamespacedName struct {
Namespace string `json:"namespace,omitempty"`
Name string `json:"name"`
}
const (
Separator = '/'
)
// String returns the general purpose string representation
func (n NamespacedName) String() string {
return n.Namespace + string(Separator) + n.Name
}
// MarshalLog emits a struct containing required key/value pair
func (n NamespacedName) MarshalLog() interface{} {
return struct {
Name string `json:"name"`
Namespace string `json:"namespace,omitempty"`
}{
Name: n.Name,
Namespace: n.Namespace,
}
}
const fileWithNamespace = "/var/run/secrets/kubernetes.io/serviceaccount/namespace"
@@ -131,10 +162,6 @@ type ControllerConfig struct {
// cached value for the GetOperatorNamespace
var operatorNamespace string
func (n NamespacedName) String() string {
return types.NamespacedName(n).String()
}
// MarshalJSON defines marshaling rule for the namespaced name type.
func (n NamespacedName) MarshalJSON() ([]byte, error) {
return []byte("\"" + n.String() + "\""), nil
+11 -3
View File
@@ -44,6 +44,14 @@ func (ths *teamHashSet) toMap() map[string][]string {
return newTeamMap
}
func mapStringSliceToStringSliceMap[T ~[]string](input map[string]T) map[string][]string {
output := make(map[string][]string)
for k, v := range input {
output[k] = []string(v)
}
return output
}
func (ths *teamHashSet) mergeCrdMap(crdTeamMap map[string][]string) {
for t, at := range crdTeamMap {
ths.add(t, at)
@@ -110,9 +118,9 @@ func (ptm *PostgresTeamMap) Load(pgTeams *acidv1.PostgresTeamList) {
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)
superuserTeamSet.mergeCrdMap(mapStringSliceToStringSliceMap(pgTeam.Spec.AdditionalSuperuserTeams))
teamSet.mergeCrdMap(mapStringSliceToStringSliceMap(pgTeam.Spec.AdditionalTeams))
teamMemberSet.mergeCrdMap(mapStringSliceToStringSliceMap(pgTeam.Spec.AdditionalMembers))
}
fetchTeams(&teamIDs, superuserTeamSet)
fetchTeams(&teamIDs, teamSet)
+9 -9
View File
@@ -24,9 +24,9 @@ var (
Name: "teamAB",
},
Spec: acidv1.PostgresTeamSpec{
AdditionalSuperuserTeams: map[string][]string{"teamA": []string{"teamB", "team24x7"}, "teamB": []string{"teamA", "teamC", "team24x7"}},
AdditionalTeams: map[string][]string{"teamA": []string{"teamC"}, "teamB": []string{}},
AdditionalMembers: map[string][]string{"team24x7": []string{"optimusprime"}, "teamB": []string{"drno"}},
AdditionalSuperuserTeams: map[string]acidv1.SuperUserTeams{"teamA": []string{"teamB", "team24x7"}, "teamB": []string{"teamA", "teamC", "team24x7"}},
AdditionalTeams: map[string]acidv1.Teams{"teamA": []string{"teamC"}, "teamB": []string{}},
AdditionalMembers: map[string]acidv1.Users{"team24x7": []string{"optimusprime"}, "teamB": []string{"drno"}},
},
}, {
TypeMeta: metav1.TypeMeta{
@@ -37,9 +37,9 @@ var (
Name: "teamC",
},
Spec: acidv1.PostgresTeamSpec{
AdditionalSuperuserTeams: map[string][]string{"teamC": []string{"team24x7"}},
AdditionalTeams: map[string][]string{"teamA": []string{"teamC"}, "teamC": []string{"teamA", "teamB", "acid"}},
AdditionalMembers: map[string][]string{"acid": []string{"batman"}},
AdditionalSuperuserTeams: map[string]acidv1.SuperUserTeams{"teamC": []string{"team24x7"}},
AdditionalTeams: map[string]acidv1.Teams{"teamA": []string{"teamC"}, "teamC": []string{"teamA", "teamB", "acid"}},
AdditionalMembers: map[string]acidv1.Users{"acid": []string{"batman"}},
},
},
{
@@ -51,9 +51,9 @@ var (
Name: "teamD",
},
Spec: acidv1.PostgresTeamSpec{
AdditionalSuperuserTeams: map[string][]string{},
AdditionalTeams: map[string][]string{"teamA": []string{"teamD"}, "teamC": []string{"teamD"}, "teamD": []string{"teamA", "teamB", "teamC"}},
AdditionalMembers: map[string][]string{"acid": []string{"batman"}},
AdditionalSuperuserTeams: map[string]acidv1.SuperUserTeams{},
AdditionalTeams: map[string]acidv1.Teams{"teamA": []string{"teamD"}, "teamC": []string{"teamD"}, "teamD": []string{"teamA", "teamB", "teamC"}},
AdditionalMembers: map[string]acidv1.Users{"acid": []string{"batman"}},
},
},
},