@@ -26,6 +26,8 @@ import (
2626const (
2727 superUserName = "postgres"
2828 replicationUserName = "standby"
29+ poolerUserName = "pooler"
30+ adminUserName = "admin"
2931 exampleSpiloConfig = `{"postgresql":{"bin_dir":"/usr/lib/postgresql/12/bin","parameters":{"autovacuum_analyze_scale_factor":"0.1"},"pg_hba":["hostssl all all 0.0.0.0/0 md5","host all all 0.0.0.0/0 md5"]},"bootstrap":{"initdb":[{"auth-host":"md5"},{"auth-local":"trust"},"data-checksums",{"encoding":"UTF8"},{"locale":"en_US.UTF-8"}],"users":{"test":{"password":"","options":["CREATEDB","NOLOGIN"]}},"dcs":{"ttl":30,"loop_wait":10,"retry_timeout":10,"maximum_lag_on_failover":33554432,"postgresql":{"parameters":{"max_connections":"100","max_locks_per_transaction":"64","max_worker_processes":"4"}}}}}`
3032 spiloConfigDiff = `{"postgresql":{"bin_dir":"/usr/lib/postgresql/12/bin","parameters":{"autovacuum_analyze_scale_factor":"0.1"},"pg_hba":["hostssl all all 0.0.0.0/0 md5","host all all 0.0.0.0/0 md5"]},"bootstrap":{"initdb":[{"auth-host":"md5"},{"auth-local":"trust"},"data-checksums",{"encoding":"UTF8"},{"locale":"en_US.UTF-8"}],"users":{"test":{"password":"","options":["CREATEDB","NOLOGIN"]}},"dcs":{"loop_wait":10,"retry_timeout":10,"maximum_lag_on_failover":33554432,"postgresql":{"parameters":{"max_locks_per_transaction":"64","max_worker_processes":"4"}}}}}`
3133)
@@ -37,7 +39,7 @@ var cl = New(
3739 Config {
3840 OpConfig : config.Config {
3941 PodManagementPolicy : "ordered_ready" ,
40- ProtectedRoles : []string {"admin" , "cron_admin" , "part_man" },
42+ ProtectedRoles : []string {adminUserName , "cron_admin" , "part_man" },
4143 Auth : config.Auth {
4244 SuperUsername : superUserName ,
4345 ReplicationUsername : replicationUserName ,
@@ -46,6 +48,9 @@ var cl = New(
4648 Resources : config.Resources {
4749 DownscalerAnnotations : []string {"downscaler/*" },
4850 },
51+ ConnectionPooler : config.ConnectionPooler {
52+ User : poolerUserName ,
53+ },
4954 },
5055 },
5156 k8sutil .NewMockKubernetesClient (),
@@ -55,6 +60,20 @@ var cl = New(
5560 Namespace : "test" ,
5661 Annotations : map [string ]string {"downscaler/downtime_replicas" : "0" },
5762 },
63+ Spec : acidv1.PostgresSpec {
64+ EnableConnectionPooler : util .True (),
65+ Streams : []acidv1.Stream {
66+ acidv1.Stream {
67+ ApplicationId : "test-app" ,
68+ Database : "test_db" ,
69+ Tables : map [string ]acidv1.StreamTable {
70+ "test_table" : acidv1.StreamTable {
71+ EventType : "test-app.test" ,
72+ },
73+ },
74+ },
75+ },
76+ },
5877 },
5978 logger ,
6079 eventRecorder ,
@@ -127,56 +146,85 @@ func TestStatefulSetUpdateWithEnv(t *testing.T) {
127146
128147func TestInitRobotUsers (t * testing.T ) {
129148 tests := []struct {
149+ testCase string
130150 manifestUsers map [string ]acidv1.UserFlags
131151 infraRoles map [string ]spec.PgUser
132152 result map [string ]spec.PgUser
133153 err error
134154 }{
135155 {
156+ testCase : "manifest user called like infrastructure role - latter should take percedence" ,
136157 manifestUsers : map [string ]acidv1.UserFlags {"foo" : {"superuser" , "createdb" }},
137158 infraRoles : map [string ]spec.PgUser {"foo" : {Origin : spec .RoleOriginInfrastructure , Name : "foo" , Namespace : cl .Namespace , Password : "bar" }},
138159 result : map [string ]spec.PgUser {"foo" : {Origin : spec .RoleOriginInfrastructure , Name : "foo" , Namespace : cl .Namespace , Password : "bar" }},
139160 err : nil ,
140161 },
141162 {
163+ testCase : "manifest user with forbidden characters" ,
142164 manifestUsers : map [string ]acidv1.UserFlags {"!fooBar" : {"superuser" , "createdb" }},
143165 err : fmt .Errorf (`invalid username: "!fooBar"` ),
144166 },
145167 {
168+ testCase : "manifest user with unknown privileges (should be catched by CRD, too)" ,
146169 manifestUsers : map [string ]acidv1.UserFlags {"foobar" : {"!superuser" , "createdb" }},
147170 err : fmt .Errorf (`invalid flags for user "foobar": ` +
148171 `user flag "!superuser" is not alphanumeric` ),
149172 },
150173 {
174+ testCase : "manifest user with unknown privileges - part 2 (should be catched by CRD, too)" ,
151175 manifestUsers : map [string ]acidv1.UserFlags {"foobar" : {"superuser1" , "createdb" }},
152176 err : fmt .Errorf (`invalid flags for user "foobar": ` +
153177 `user flag "SUPERUSER1" is not valid` ),
154178 },
155179 {
180+ testCase : "manifest user with conflicting flags" ,
156181 manifestUsers : map [string ]acidv1.UserFlags {"foobar" : {"inherit" , "noinherit" }},
157182 err : fmt .Errorf (`invalid flags for user "foobar": ` +
158183 `conflicting user flags: "NOINHERIT" and "INHERIT"` ),
159184 },
160185 {
161- manifestUsers : map [string ]acidv1.UserFlags {"admin" : {"superuser" }, superUserName : {"createdb" }},
186+ testCase : "manifest user called like Spilo system users" ,
187+ manifestUsers : map [string ]acidv1.UserFlags {superUserName : {"createdb" }, replicationUserName : {"replication" }},
188+ infraRoles : map [string ]spec.PgUser {},
189+ result : map [string ]spec.PgUser {},
190+ err : nil ,
191+ },
192+ {
193+ testCase : "manifest user called like protected user name" ,
194+ manifestUsers : map [string ]acidv1.UserFlags {adminUserName : {"superuser" }},
195+ infraRoles : map [string ]spec.PgUser {},
196+ result : map [string ]spec.PgUser {},
197+ err : nil ,
198+ },
199+ {
200+ testCase : "manifest user called like pooler system user" ,
201+ manifestUsers : map [string ]acidv1.UserFlags {poolerUserName : {}},
202+ infraRoles : map [string ]spec.PgUser {},
203+ result : map [string ]spec.PgUser {},
204+ err : nil ,
205+ },
206+ {
207+ testCase : "manifest user called like stream system user" ,
208+ manifestUsers : map [string ]acidv1.UserFlags {"fes_user" : {"replication" }},
162209 infraRoles : map [string ]spec.PgUser {},
163210 result : map [string ]spec.PgUser {},
164211 err : nil ,
165212 },
166213 }
214+ cl .initSystemUsers ()
167215 for _ , tt := range tests {
168216 cl .Spec .Users = tt .manifestUsers
169217 cl .pgUsers = tt .infraRoles
170218 if err := cl .initRobotUsers (); err != nil {
171219 if tt .err == nil {
172- t .Errorf ("%s got an unexpected error: %v" , t .Name (), err )
220+ t .Errorf ("%s - %s: got an unexpected error: %v" , tt . testCase , t .Name (), err )
173221 }
174222 if err .Error () != tt .err .Error () {
175- t .Errorf ("%s expected error %v, got %v" , t .Name (), tt .err , err )
223+ t .Errorf ("%s - %s: expected error %v, got %v" , tt . testCase , t .Name (), tt .err , err )
176224 }
177225 } else {
178226 if ! reflect .DeepEqual (cl .pgUsers , tt .result ) {
179- t .Errorf ("%s expected: %#v, got %#v" , t .Name (), tt .result , cl .pgUsers )
227+ t .Errorf ("%s - %s: expected: %#v, got %#v" , tt . testCase , t .Name (), tt .result , cl .pgUsers )
180228 }
181229 }
182230 }
@@ -269,7 +317,7 @@ func TestInitHumanUsers(t *testing.T) {
269317 },
270318 {
271319 existingRoles : map [string ]spec.PgUser {},
272- teamRoles : []string {"admin" , replicationUserName },
320+ teamRoles : []string {adminUserName , replicationUserName },
273321 result : map [string ]spec.PgUser {},
274322 err : nil ,
275323 },
@@ -896,6 +944,11 @@ func TestServiceAnnotations(t *testing.T) {
896944}
897945
898946func TestInitSystemUsers (t * testing.T ) {
947+ // reset system users, pooler and stream section
948+ cl .systemUsers = make (map [string ]spec.PgUser )
949+ cl .Spec .EnableConnectionPooler = boolToPointer (false )
950+ cl .Spec .Streams = []acidv1.Stream {}
951+
899952 // default cluster without connection pooler and event streams
900953 cl .initSystemUsers ()
901954 if _ , exist := cl .systemUsers [constants .ConnectionPoolerUserKeyName ]; exist {
@@ -914,35 +967,35 @@ func TestInitSystemUsers(t *testing.T) {
914967
915968 // superuser is not allowed as connection pool user
916969 cl .Spec .ConnectionPooler = & acidv1.ConnectionPooler {
917- User : "postgres" ,
970+ User : superUserName ,
918971 }
919- cl .OpConfig .SuperUsername = "postgres"
920- cl .OpConfig .ConnectionPooler .User = "pooler"
972+ cl .OpConfig .SuperUsername = superUserName
973+ cl .OpConfig .ConnectionPooler .User = poolerUserName
921974
922975 cl .initSystemUsers ()
923- if _ , exist := cl .systemUsers ["pooler" ]; ! exist {
976+ if _ , exist := cl .systemUsers [poolerUserName ]; ! exist {
924977 t .Errorf ("%s, Superuser is not allowed to be a connection pool user" , t .Name ())
925978 }
926979
927980 // neither protected users are
928- delete (cl .systemUsers , "pooler" )
981+ delete (cl .systemUsers , poolerUserName )
929982 cl .Spec .ConnectionPooler = & acidv1.ConnectionPooler {
930- User : "admin" ,
983+ User : adminUserName ,
931984 }
932- cl .OpConfig .ProtectedRoles = []string {"admin" }
985+ cl .OpConfig .ProtectedRoles = []string {adminUserName }
933986
934987 cl .initSystemUsers ()
935- if _ , exist := cl .systemUsers ["pooler" ]; ! exist {
988+ if _ , exist := cl .systemUsers [poolerUserName ]; ! exist {
936989 t .Errorf ("%s, Protected user are not allowed to be a connection pool user" , t .Name ())
937990 }
938991
939- delete (cl .systemUsers , "pooler" )
992+ delete (cl .systemUsers , poolerUserName )
940993 cl .Spec .ConnectionPooler = & acidv1.ConnectionPooler {
941- User : "standby" ,
994+ User : replicationUserName ,
942995 }
943996
944997 cl .initSystemUsers ()
945- if _ , exist := cl .systemUsers ["pooler" ]; ! exist {
998+ if _ , exist := cl .systemUsers [poolerUserName ]; ! exist {
946999 t .Errorf ("%s, System users are not allowed to be a connection pool user" , t .Name ())
9471000 }
9481001
@@ -960,8 +1013,8 @@ func TestInitSystemUsers(t *testing.T) {
9601013 ApplicationId : "test-app" ,
9611014 Database : "test_db" ,
9621015 Tables : map [string ]acidv1.StreamTable {
963- "data. test_table" : {
964- EventType : "test_event " ,
1016+ "test_table" : {
1017+ EventType : "test-app.test " ,
9651018 },
9661019 },
9671020 },
@@ -1017,7 +1070,7 @@ func TestPreparedDatabases(t *testing.T) {
10171070 subTest : "Test admin role of owner" ,
10181071 role : "foo_owner" ,
10191072 memberOf : "" ,
1020- admin : "admin" ,
1073+ admin : adminUserName ,
10211074 },
10221075 {
10231076 subTest : "Test writer is a member of reader" ,
0 commit comments