@@ -26,6 +26,8 @@ import (
26
26
const (
27
27
superUserName = "postgres"
28
28
replicationUserName = "standby"
29
+ poolerUserName = "pooler"
30
+ adminUserName = "admin"
29
31
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"}}}}}`
30
32
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"}}}}}`
31
33
)
@@ -37,7 +39,7 @@ var cl = New(
37
39
Config {
38
40
OpConfig : config.Config {
39
41
PodManagementPolicy : "ordered_ready" ,
40
- ProtectedRoles : []string {"admin" , "cron_admin" , "part_man" },
42
+ ProtectedRoles : []string {adminUserName , "cron_admin" , "part_man" },
41
43
Auth : config.Auth {
42
44
SuperUsername : superUserName ,
43
45
ReplicationUsername : replicationUserName ,
@@ -46,6 +48,9 @@ var cl = New(
46
48
Resources : config.Resources {
47
49
DownscalerAnnotations : []string {"downscaler/*" },
48
50
},
51
+ ConnectionPooler : config.ConnectionPooler {
52
+ User : poolerUserName ,
53
+ },
49
54
},
50
55
},
51
56
k8sutil .NewMockKubernetesClient (),
@@ -55,6 +60,20 @@ var cl = New(
55
60
Namespace : "test" ,
56
61
Annotations : map [string ]string {"downscaler/downtime_replicas" : "0" },
57
62
},
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
+ },
58
77
},
59
78
logger ,
60
79
eventRecorder ,
@@ -127,56 +146,85 @@ func TestStatefulSetUpdateWithEnv(t *testing.T) {
127
146
128
147
func TestInitRobotUsers (t * testing.T ) {
129
148
tests := []struct {
149
+ testCase string
130
150
manifestUsers map [string ]acidv1.UserFlags
131
151
infraRoles map [string ]spec.PgUser
132
152
result map [string ]spec.PgUser
133
153
err error
134
154
}{
135
155
{
156
+ testCase : "manifest user called like infrastructure role - latter should take percedence" ,
136
157
manifestUsers : map [string ]acidv1.UserFlags {"foo" : {"superuser" , "createdb" }},
137
158
infraRoles : map [string ]spec.PgUser {"foo" : {Origin : spec .RoleOriginInfrastructure , Name : "foo" , Namespace : cl .Namespace , Password : "bar" }},
138
159
result : map [string ]spec.PgUser {"foo" : {Origin : spec .RoleOriginInfrastructure , Name : "foo" , Namespace : cl .Namespace , Password : "bar" }},
139
160
err : nil ,
140
161
},
141
162
{
163
+ testCase : "manifest user with forbidden characters" ,
142
164
manifestUsers : map [string ]acidv1.UserFlags {"!fooBar" : {"superuser" , "createdb" }},
143
165
err : fmt .Errorf (`invalid username: "!fooBar"` ),
144
166
},
145
167
{
168
+ testCase : "manifest user with unknown privileges (should be catched by CRD, too)" ,
146
169
manifestUsers : map [string ]acidv1.UserFlags {"foobar" : {"!superuser" , "createdb" }},
147
170
err : fmt .Errorf (`invalid flags for user "foobar": ` +
148
171
`user flag "!superuser" is not alphanumeric` ),
149
172
},
150
173
{
174
+ testCase : "manifest user with unknown privileges - part 2 (should be catched by CRD, too)" ,
151
175
manifestUsers : map [string ]acidv1.UserFlags {"foobar" : {"superuser1" , "createdb" }},
152
176
err : fmt .Errorf (`invalid flags for user "foobar": ` +
153
177
`user flag "SUPERUSER1" is not valid` ),
154
178
},
155
179
{
180
+ testCase : "manifest user with conflicting flags" ,
156
181
manifestUsers : map [string ]acidv1.UserFlags {"foobar" : {"inherit" , "noinherit" }},
157
182
err : fmt .Errorf (`invalid flags for user "foobar": ` +
158
183
`conflicting user flags: "NOINHERIT" and "INHERIT"` ),
159
184
},
160
185
{
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" }},
162
209
infraRoles : map [string ]spec.PgUser {},
163
210
result : map [string ]spec.PgUser {},
164
211
err : nil ,
165
212
},
166
213
}
214
+ cl .initSystemUsers ()
167
215
for _ , tt := range tests {
168
216
cl .Spec .Users = tt .manifestUsers
169
217
cl .pgUsers = tt .infraRoles
170
218
if err := cl .initRobotUsers (); err != nil {
171
219
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 )
173
221
}
174
222
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 )
176
224
}
177
225
} else {
178
226
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 )
180
228
}
181
229
}
182
230
}
@@ -269,7 +317,7 @@ func TestInitHumanUsers(t *testing.T) {
269
317
},
270
318
{
271
319
existingRoles : map [string ]spec.PgUser {},
272
- teamRoles : []string {"admin" , replicationUserName },
320
+ teamRoles : []string {adminUserName , replicationUserName },
273
321
result : map [string ]spec.PgUser {},
274
322
err : nil ,
275
323
},
@@ -896,6 +944,11 @@ func TestServiceAnnotations(t *testing.T) {
896
944
}
897
945
898
946
func 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
+
899
952
// default cluster without connection pooler and event streams
900
953
cl .initSystemUsers ()
901
954
if _ , exist := cl .systemUsers [constants .ConnectionPoolerUserKeyName ]; exist {
@@ -914,35 +967,35 @@ func TestInitSystemUsers(t *testing.T) {
914
967
915
968
// superuser is not allowed as connection pool user
916
969
cl .Spec .ConnectionPooler = & acidv1.ConnectionPooler {
917
- User : "postgres" ,
970
+ User : superUserName ,
918
971
}
919
- cl .OpConfig .SuperUsername = "postgres"
920
- cl .OpConfig .ConnectionPooler .User = "pooler"
972
+ cl .OpConfig .SuperUsername = superUserName
973
+ cl .OpConfig .ConnectionPooler .User = poolerUserName
921
974
922
975
cl .initSystemUsers ()
923
- if _ , exist := cl .systemUsers ["pooler" ]; ! exist {
976
+ if _ , exist := cl .systemUsers [poolerUserName ]; ! exist {
924
977
t .Errorf ("%s, Superuser is not allowed to be a connection pool user" , t .Name ())
925
978
}
926
979
927
980
// neither protected users are
928
- delete (cl .systemUsers , "pooler" )
981
+ delete (cl .systemUsers , poolerUserName )
929
982
cl .Spec .ConnectionPooler = & acidv1.ConnectionPooler {
930
- User : "admin" ,
983
+ User : adminUserName ,
931
984
}
932
- cl .OpConfig .ProtectedRoles = []string {"admin" }
985
+ cl .OpConfig .ProtectedRoles = []string {adminUserName }
933
986
934
987
cl .initSystemUsers ()
935
- if _ , exist := cl .systemUsers ["pooler" ]; ! exist {
988
+ if _ , exist := cl .systemUsers [poolerUserName ]; ! exist {
936
989
t .Errorf ("%s, Protected user are not allowed to be a connection pool user" , t .Name ())
937
990
}
938
991
939
- delete (cl .systemUsers , "pooler" )
992
+ delete (cl .systemUsers , poolerUserName )
940
993
cl .Spec .ConnectionPooler = & acidv1.ConnectionPooler {
941
- User : "standby" ,
994
+ User : replicationUserName ,
942
995
}
943
996
944
997
cl .initSystemUsers ()
945
- if _ , exist := cl .systemUsers ["pooler" ]; ! exist {
998
+ if _ , exist := cl .systemUsers [poolerUserName ]; ! exist {
946
999
t .Errorf ("%s, System users are not allowed to be a connection pool user" , t .Name ())
947
1000
}
948
1001
@@ -960,8 +1013,8 @@ func TestInitSystemUsers(t *testing.T) {
960
1013
ApplicationId : "test-app" ,
961
1014
Database : "test_db" ,
962
1015
Tables : map [string ]acidv1.StreamTable {
963
- "data. test_table" : {
964
- EventType : "test_event " ,
1016
+ "test_table" : {
1017
+ EventType : "test-app.test " ,
965
1018
},
966
1019
},
967
1020
},
@@ -1017,7 +1070,7 @@ func TestPreparedDatabases(t *testing.T) {
1017
1070
subTest : "Test admin role of owner" ,
1018
1071
role : "foo_owner" ,
1019
1072
memberOf : "" ,
1020
- admin : "admin" ,
1073
+ admin : adminUserName ,
1021
1074
},
1022
1075
{
1023
1076
subTest : "Test writer is a member of reader" ,
0 commit comments