Skip to content

Commit 3d14754

Browse files
committed
feat: beef up testing
1 parent fdd809e commit 3d14754

File tree

3 files changed

+207
-6
lines changed

3 files changed

+207
-6
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ This repository serves as a child module for managing Postgres Logical Databases
1414

1515
### Prerequisites
1616

17-
1. Postgres user with `LOGIN` privileges
17+
1. Postgres user with `LOGIN` privileges.
18+
2. Postgres user should have appropriate privileges for the specifiic operations you're doing. For example, if you want to create a role, your postgres user should have the `CREATEROLE` privilege.
1819

1920
### Example
2021

main.tf

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ locals {
1313
}
1414
)]
1515

16-
_database_grants = [for role in local._roles_with_passwords : role.database_grants if try(role.database_grants, null) != null]
17-
database_grants_map = { for grant in local._database_grants : format("%s-%s", grant.role, grant.database) => grant }
18-
1916
_default_privileges = flatten([for role in local._roles_with_passwords : role.default_privileges if try(role.default_privileges, null) != null])
2017
default_privileges_map = { for grant in local._default_privileges : format("%s-%s-%s-%s", grant.role, grant.database, grant.schema, grant.object_type) => grant }
2118

19+
_database_grants = [for role in local._roles_with_passwords : role.database_grants if try(role.database_grants, null) != null]
20+
database_grants_map = { for grant in local._database_grants : format("%s-%s", grant.role, grant.database) => grant }
21+
2222
_schema_grants = [for role in local._roles_with_passwords : role.schema_grants if try(role.schema_grants, null) != null]
2323
schema_grants_map = { for grant in local._schema_grants : format("%s-%s-%s", grant.role, grant.schema, grant.database) => grant }
2424

@@ -79,6 +79,9 @@ resource "postgresql_role" "role" {
7979
}
8080

8181
resource "postgresql_default_privileges" "privileges" {
82+
# Postgres documentation specific to default privileges
83+
# https://www.postgresql.org/docs/current/sql-alterdefaultprivileges.html
84+
8285
for_each = local.default_privileges_map
8386

8487
role = each.value.role
@@ -91,7 +94,6 @@ resource "postgresql_default_privileges" "privileges" {
9194
depends_on = [postgresql_database.logical_dbs, postgresql_role.role]
9295
}
9396

94-
9597
resource "postgresql_grant" "database_access" {
9698
for_each = local.database_grants_map
9799

tests/main.tftest.hcl

Lines changed: 199 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,146 @@ variables {
1515
name = "app_user"
1616
password = "app_user_password"
1717
}
18+
default_privileges = [
19+
{
20+
role = "app_user"
21+
database = "app"
22+
owner = "app_user"
23+
schema = "public"
24+
object_type = "schema"
25+
privileges = ["ALL"]
26+
},
27+
{
28+
role = "app_user"
29+
database = "app"
30+
owner = "app_user"
31+
schema = "public"
32+
object_type = "table"
33+
objects = []
34+
privileges = ["ALL"]
35+
},
36+
{
37+
role = "app_user"
38+
database = "app"
39+
owner = "app_user"
40+
schema = "public"
41+
object_type = "sequence"
42+
objects = []
43+
privileges = ["ALL"]
44+
}
45+
]
46+
database_grants = {
47+
role = "app_user"
48+
database = "app2"
49+
object_type = "database"
50+
privileges = ["CONNECT"]
51+
}
52+
schema_grants = {
53+
role = "app_user"
54+
database = "app2"
55+
schema = "public"
56+
object_type = "schema"
57+
objects = ["public"]
58+
privileges = ["USAGE"]
59+
}
60+
sequence_grants = {
61+
role = "app_user"
62+
database = "app2"
63+
schema = "public"
64+
object_type = "sequence"
65+
objects = [] # all sequences
66+
privileges = ["USAGE", "SELECT"]
67+
}
68+
table_grants = {
69+
role = "app_user"
70+
database = "app2"
71+
schema = "public"
72+
object_type = "table"
73+
objects = [] # all tables
74+
privileges = ["SELECT"]
75+
}
1876
}, {
1977
role = {
2078
name = "app_user2"
2179
}
2280
}]
2381
}
2482

83+
# -----------------------------------------------------------------------------
84+
# --- validate local values
85+
# -----------------------------------------------------------------------------
86+
87+
run "validate_local_default_privileges" {
88+
command = apply
89+
90+
providers = {
91+
postgresql = postgresql.mock
92+
}
93+
94+
assert {
95+
condition = local.default_privileges_map["app_user-app-public-schema"].role == "app_user"
96+
error_message = "Check intermediate local values"
97+
}
98+
}
99+
100+
101+
run "validate_local_database_grants" {
102+
command = apply
103+
104+
providers = {
105+
postgresql = postgresql.mock
106+
}
107+
108+
assert {
109+
condition = local.database_grants_map["app_user-app2"].role == "app_user"
110+
error_message = "Check intermediate local values"
111+
}
112+
}
113+
114+
run "validate_local_schema_grants" {
115+
command = apply
116+
117+
providers = {
118+
postgresql = postgresql.mock
119+
}
120+
121+
assert {
122+
condition = local.schema_grants_map["app_user-public-app2"].role == "app_user"
123+
error_message = "Check intermediate local values"
124+
}
125+
}
126+
127+
run "validate_local_sequence_grants" {
128+
command = apply
129+
130+
providers = {
131+
postgresql = postgresql.mock
132+
}
133+
134+
assert {
135+
condition = local.sequence_grants_map["app_user-public-app2"].role == "app_user"
136+
error_message = "Check intermediate local values"
137+
}
138+
}
139+
140+
run "validate_local_table_grants" {
141+
command = apply
142+
143+
providers = {
144+
postgresql = postgresql.mock
145+
}
146+
147+
assert {
148+
condition = local.table_grants_map["app_user-public-app2"].role == "app_user"
149+
error_message = "Check intermediate local values"
150+
}
151+
}
152+
153+
154+
# -----------------------------------------------------------------------------
155+
# --- validate resources
156+
# -----------------------------------------------------------------------------
157+
25158
run "validate_databases" {
26159
command = apply
27160

@@ -75,4 +208,69 @@ run "validate_roles_with_random_password" {
75208
condition = alltrue([for c in ["!", "#", "$", "%", "^", "&", "*", "(", ")", "<", ">", "-", "_"] : length(split(c, postgresql_role.role["app_user2"].password)) == 1])
76209
error_message = "Password contains forbidden special characters"
77210
}
78-
}
211+
}
212+
213+
214+
run "validate_default_privileges" {
215+
command = apply
216+
217+
providers = {
218+
postgresql = postgresql.mock
219+
}
220+
assert {
221+
condition = postgresql_default_privileges.privileges["app_user-app-public-schema"].object_type == "schema"
222+
error_message = "Check intermediate local values"
223+
}
224+
}
225+
226+
run "validate_database_grants" {
227+
command = apply
228+
229+
providers = {
230+
postgresql = postgresql.mock
231+
}
232+
233+
assert {
234+
condition = postgresql_grant.database_access["app_user-app2"].privileges == toset(["CONNECT"])
235+
error_message = "Check intermediate local values"
236+
}
237+
}
238+
239+
run "validate_schema_grants" {
240+
command = apply
241+
242+
providers = {
243+
postgresql = postgresql.mock
244+
}
245+
246+
assert {
247+
condition = postgresql_grant.schema_access["app_user-public-app2"].privileges == toset(["USAGE"])
248+
error_message = "Check intermediate local values"
249+
}
250+
}
251+
252+
run "validate_sequence_grants" {
253+
command = apply
254+
255+
providers = {
256+
postgresql = postgresql.mock
257+
}
258+
259+
assert {
260+
condition = postgresql_grant.sequence_access["app_user-public-app2"].privileges == toset(["USAGE", "SELECT"])
261+
error_message = "Check intermediate local values"
262+
}
263+
}
264+
265+
run "validate_table_grants" {
266+
command = apply
267+
268+
providers = {
269+
postgresql = postgresql.mock
270+
}
271+
272+
assert {
273+
condition = postgresql_grant.table_access["app_user-public-app2"].privileges == toset(["SELECT"])
274+
error_message = "Check intermediate local values"
275+
}
276+
}

0 commit comments

Comments
 (0)