mirror of
https://github.com/zitadel/zitadel.git
synced 2025-11-03 06:42:56 +00:00
# Which Problems Are Solved Using the service ping, we want to have some additional insights to how zitadel is configured. The current resource count report contains already some amount of configured policies, such as the login_policy. But we do not know if for example MFA is enforced. # How the Problems Are Solved - Added the following counts to the report: - service users per organization - MFA enforcements (though login policy) - Notification policies with password change option enabled - SCIM provisioned users (using user metadata) - Since all of the above are conditional based on at least a column inside a projection, a new `migration.CountTriggerConditional` has been added, where a condition (column values) and an option to track updates on that column should be considered for the count. - For this to be possible, the following changes had to be made to the existing sql resources: - the `resource_name` has been added to unique constraint on the `projection.resource_counts` table - triggers have been added / changed to individually track `INSERT`, `UPDATE`(s) and `DELETE` and be able to handle conditions - an optional argument has been added to the `projections.count_resource()` function to allow providing the information to `UP` or `DOWN` count the resource on an update. # Additional Changes None # Additional Context - partially solves #10244 (reporting audit log retention limit will be handled in #10245 directly) - backport to v4.x
93 lines
2.9 KiB
SQL
93 lines
2.9 KiB
SQL
{{ define "count_trigger" -}}
|
|
-- In case the old trigger exists, drop it to prevent duplicated counts.
|
|
DROP TRIGGER IF EXISTS count_{{ .Resource }} ON {{ .Table }};
|
|
|
|
CREATE OR REPLACE TRIGGER count_{{ .Resource }}_insert
|
|
AFTER INSERT
|
|
ON {{ .Table }}
|
|
FOR EACH ROW
|
|
-- Only count if the conditions are met in the newly added row.
|
|
{{if .Conditions}}WHEN ({{.Conditions.ToSQL "NEW" true}}){{end}}
|
|
EXECUTE FUNCTION projections.count_resource(
|
|
'{{ .ParentType }}',
|
|
'{{ .InstanceIDColumn }}',
|
|
'{{ .ParentIDColumn }}',
|
|
'{{ .Resource }}'
|
|
);
|
|
|
|
CREATE OR REPLACE TRIGGER count_{{ .Resource }}_delete
|
|
AFTER DELETE
|
|
ON {{ .Table }}
|
|
FOR EACH ROW
|
|
-- Only count down if the conditions were met in the old / deleted row.
|
|
{{if .Conditions}}WHEN ({{.Conditions.ToSQL "OLD" true}}){{end}}
|
|
EXECUTE FUNCTION projections.count_resource(
|
|
'{{ .ParentType }}',
|
|
'{{ .InstanceIDColumn }}',
|
|
'{{ .ParentIDColumn }}',
|
|
'{{ .Resource }}'
|
|
);
|
|
|
|
{{if .TrackChange}}
|
|
CREATE OR REPLACE TRIGGER count_{{ .Resource }}_update_up
|
|
AFTER UPDATE
|
|
ON {{ .Table }}
|
|
FOR EACH ROW
|
|
-- Only count up if the conditions are met in the new state, but were not in the old.
|
|
WHEN ({{.Conditions.ToSQL "NEW" true}} AND {{.Conditions.ToSQL "OLD" false}})
|
|
EXECUTE FUNCTION projections.count_resource(
|
|
'{{ .ParentType }}',
|
|
'{{ .InstanceIDColumn }}',
|
|
'{{ .ParentIDColumn }}',
|
|
'{{ .Resource }}',
|
|
'UP'
|
|
);
|
|
|
|
CREATE OR REPLACE TRIGGER count_{{ .Resource }}_update_down
|
|
AFTER UPDATE
|
|
ON {{ .Table }}
|
|
FOR EACH ROW
|
|
-- Only count down if the conditions are not met in the new state, but were in the old.
|
|
WHEN ({{.Conditions.ToSQL "NEW" false}} AND {{.Conditions.ToSQL "OLD" true}})
|
|
EXECUTE FUNCTION projections.count_resource(
|
|
'{{ .ParentType }}',
|
|
'{{ .InstanceIDColumn }}',
|
|
'{{ .ParentIDColumn }}',
|
|
'{{ .Resource }}',
|
|
'DOWN'
|
|
);
|
|
{{end}}
|
|
|
|
CREATE OR REPLACE TRIGGER truncate_{{ .Resource }}_counts
|
|
AFTER TRUNCATE
|
|
ON {{ .Table }}
|
|
FOR EACH STATEMENT
|
|
EXECUTE FUNCTION projections.delete_table_counts();
|
|
|
|
-- Prevent inserts and deletes while we populate the counts.
|
|
LOCK TABLE {{ .Table }} IN SHARE MODE;
|
|
|
|
-- Populate the resource counts for the existing data in the table.
|
|
INSERT INTO projections.resource_counts(
|
|
instance_id,
|
|
table_name,
|
|
parent_type,
|
|
parent_id,
|
|
resource_name,
|
|
amount
|
|
)
|
|
SELECT
|
|
{{ .InstanceIDColumn }},
|
|
'{{ .Table }}',
|
|
'{{ .ParentType }}',
|
|
{{ .ParentIDColumn }},
|
|
'{{ .Resource }}',
|
|
COUNT(*) AS amount
|
|
FROM {{ .Table }}
|
|
{{if .Conditions}}WHERE {{.Conditions.ToSQL .Table true}}{{end}}
|
|
GROUP BY ({{ .InstanceIDColumn }}, {{ .ParentIDColumn }})
|
|
ON CONFLICT (instance_id, table_name, parent_type, parent_id, resource_name) DO
|
|
UPDATE SET updated_at = now(), amount = EXCLUDED.amount;
|
|
|
|
{{- end -}}
|