Skip to content

Commit 319c381

Browse files
Feature/refactor grants (#19)
* Enhance logging in grant_object macro to include detailed information about grants and roles being processed * Refactor grant_object macro to improve logging and ensure unique role privileges are processed correctly * Refactor grant management macros for consistency and improved logging - Updated grant_share_read and grant_share_read_specific_schema macros to implement early exits and structured logging. - Refactored ownership macros to include early exits and enhanced logging for ownership changes. - Introduced shared helper macros for grant management to reduce redundancy and improve maintainability. - Updated documentation in grants.yml and other macro YAML files for clarity and consistency. - Added a new grants_smoke_test macro for lightweight validation of grant macros in dry-run mode. - Standardized argument signatures and descriptions across macros for better usability. * Add grant_schema_procedure_usage macros for managing procedure usage privileges * Fix grant_procedure_usage macro to correctly access procedure names from query results * Update README.md Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> * Update macros/grants/_helpers.sql Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> --------- Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
1 parent 882a3db commit 319c381

33 files changed

+993
-590
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Data Engineers Snowflake DataOps Utils Project Changelog
22
This file contains the changelog for the Data Engineers Snowflake DataOps Utils project, detailing updates, fixes, and enhancements made to the project over time.
33

4+
## v0.3.9 2024-06-10 - Grant Object For Procedures
5+
6+
* added macro `grant_procedure_usage` to enable the ability to grant usage of a stored procedure to a role
7+
48
## v0.3.8.5 2025-08-25 - Grant Usage to Application
59

610
* added grant usage to application for `sp_sync_` in the `grant_privileges` macro

README.md

Lines changed: 96 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,54 @@
11
This [dbt](https://github.com/dbt-labs/dbt) package contains macros that can be (re)used across dbt projects.
22

3-
> require-dbt-version: [">=1.6.0", "<2.0.0"]
3+
> require-dbt-version: [">=1.8.0", "<2.0.0"]
44
----
55

66
## Installation Instructions
77
Add the following to your packages.yml file
88
```
99
- git: https://github.com/DataEngineersNZ/dbt-snowflake-datops-utils.git
10-
revision: "0.3.8"
10+
revision: "0.3.8.2"
1111
```
1212
----
1313

1414
## Contents
1515

16-
**Checks**
16+
Below is a catalogue of publicly supported macros grouped by domain. Internal helpers (those with docs.show: false or purely supportive behavior) are intentionally excluded. Where helpful, a short description is inlined; consult the YAML files for full argument metadata.
1717

18-
- `get_populated_array`
19-
- `get_populated_array_value_as_string`
20-
- `get_populated_array_value_as_number`
21-
- `get_populated_numeric_value`
22-
- `get_populated_string_value`
18+
**checks**
19+
20+
- `get_populated_array` – first non-empty array from two candidates
21+
- `get_populated_array_value_as_string` – join first non-empty array
22+
- `get_populated_array_value_or_string_as_string` – array joined or fallback string
23+
- `get_populated_numeric_value` – first numeric else 0
24+
- `get_populated_string_value` – first string else ''
2325

2426
**clean**
2527

26-
- `clean_functions`
27-
- `clean_generic`
28-
- `clean_models`
29-
- `clean_objects`
30-
- `clean_schemas`
31-
- `clean_stale_models`
32-
- `drop_object`
28+
- `clean_functions` – drop orphaned UDFs
29+
- `clean_generic` – drop orphaned streams/tasks/stages
30+
- `clean_models` – drop orphaned tables/views/external tables
31+
- `clean_objects` – orchestrate all clean macros
32+
- `clean_schemas` – drop schemas not in project
33+
- `clean_stale_models` – drop models older than N days
3334

3435
**database**
3536

36-
- `database_clone`
37-
- `database_desctroy`
38-
- `schema_clone`
37+
- `database_clone` – zero-copy clone a database
38+
- `database_destroy` – drop database
39+
- `schema_clone` – zero-copy clone a schema
3940

40-
**dependancies**
41+
**dependencies** (non-lineage referencing)
4142

42-
- `depends_on_ref`
43-
- `depends_on_source`
43+
- `depends_on_ref` – commented reference to model
44+
- `depends_on_source` – commented reference to source
4445

4546
**dynamic_tables**
4647

47-
- `target_lag_environment`
48-
- `target_warehouse_environment`
48+
- `target_lag_environment` – lag by environment
49+
- `target_warehouse_environment` – warehouse by environment
4950

50-
**grants**
51+
**grants** (see refactored patterns section below)
5152

5253
- `grant_database_ownership`
5354
- `grant_integration_ownership`
@@ -56,15 +57,23 @@ Add the following to your packages.yml file
5657
- `grant_object`
5758
- `grant_privileges`
5859
- `grant_schema_monitor`
60+
- `grant_schema_monitor_specific`
5961
- `grant_schema_operate`
60-
- `grant_schema_onwership`
62+
- `grant_schema_operate_specific`
63+
- `grant_schema_ownership`
64+
- `grant_schema_procedure_usage`
65+
- `grant_schema_procedure_usage_specific`
6166
- `grant_schema_read`
67+
- `grant_schema_read_specific`
6268
- `grant_share_read`
69+
- `grant_share_read_specific_schema`
6370
- `grant_usage_to_application`
71+
- `grants_smoke_test` – CI/dry-run validation harness
6472

6573
**merge**
6674

6775
- `get_merge_statement`
76+
- `get_default_merge_statement`
6877

6978
**modelling**
7079

@@ -96,23 +105,80 @@ Add the following to your packages.yml file
96105

97106
**schema**
98107

99-
- `generate_schema_name`
108+
- `generate_schema_name` (override)
100109
- `model_ref`
101110
- `model_source`
102-
- `ref`
103-
- `source`
111+
- `ref` (enhanced include_database)
112+
- `source` (enhanced include_database)
104113

105114
**tags**
106115

107116
- `apply_meta_as_tags`
108-
- `model_columns_contains_tag_meta`
109-
- `set_column_tag_value`
110117

111118
**tasks**
112119

113120
- `enable_dependent_tasks`
114121
- `execute_task`
115122

123+
### Grants Management (Refactored Patterns)
124+
125+
Recent refactors introduced a consistent pattern across grant-related macros for clarity, auditability, and safety:
126+
127+
Key characteristics:
128+
- Early exit guards: macros skip execution outside `run` / `run-operation` contexts.
129+
- Logging only for top-level macros: operational macros write human-readable summaries instead of returning data structures.
130+
- Statement batching with consistent formatting and explicit counts (revokes vs grants).
131+
- Ownership helper macros still return statement lists internally (consumed by `grant_schema_ownership`).
132+
- Optional dry-run mode to preview changes.
133+
134+
Dry-run mode:
135+
Set a project or CLI var `grants_dry_run: true` to log all statements without executing them for the following macros:
136+
`grant_schema_monitor`, `grant_schema_operate`, `grant_share_read`, `grant_share_read_specific_schema`, `grant_privileges`.
137+
138+
Example CLI usage:
139+
```
140+
dbt run-operation grant_schema_operate --args '{"exclude_schemas": [], "grant_roles": ["OPS_SUPPORT"]}' --vars '{"grants_dry_run": true}'
141+
```
142+
143+
Example project-level configuration (`dbt_project.yml`):
144+
```yaml
145+
vars:
146+
grants_dry_run: true # disable to allow execution
147+
```
148+
149+
Sample log output pattern:
150+
```
151+
grant_schema_operate: processing 5 schemas for roles: OPS_SUPPORT
152+
revoke operate on TASK in schema MY_DB.MY_SCHEMA.MY_TASK from role OLD_ROLE;
153+
grant operate on all tasks in schema MY_DB.MY_SCHEMA to role ops_support;
154+
grant_schema_operate_specific summary: 1 revokes, 2 grants (dry_run=True)
155+
```
156+
157+
Recommended workflow:
158+
1. Run with `grants_dry_run: true` and review logs in CI.
159+
2. Approve changes, re-run with dry-run disabled to apply.
160+
161+
High-level macro intent summary:
162+
- `grant_schema_read*`: Ensures read usage, SELECT/REFERENCE privileges, optional future grants.
163+
- `grant_schema_monitor*`: Grants MONITOR on tasks/pipes + schema usage.
164+
- `grant_schema_operate*`: Grants OPERATE on tasks/pipes + schema usage.
165+
- `grant_schema_procedure_usage*`: Grants USAGE on all procedures + schema usage, with future grants.
166+
- `grant_share_read*`: Manages secure view exposure to outbound shares (revokes unmanaged, grants managed).
167+
- `grant_object`: Reconciles privilege sets on specific objects (TABLE/VIEW/PROCEDURE/FUNCTION/etc).
168+
- `grant_privileges`: Environment-aware bundle orchestrator.
169+
170+
Notes:
171+
- Privilege diffing avoids redundant grants.
172+
- Revokes are only issued for privileges outside desired scope (or for unmanaged grantees when revocation is enabled).
173+
- Ownership grants always use `revoke current grants` to move ownership cleanly.
174+
175+
Future enhancement ideas (not yet implemented):
176+
- Generic unified privilege macro parameterized by privilege type.
177+
- Aggregated dry-run report macro producing a JSON artifact.
178+
- Caching of SHOW results across macros within a single run-operation invocation.
179+
180+
Contributions welcome. Keep macro signatures stable to avoid breaking downstream usage.
181+
116182
---
117183

118184
### Tagging macros

macros/checks/checks.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ version: 2
22

33
macros:
44
- name: get_populated_array
5-
description: This macro returns an array of values based on two input string arrays
5+
description: Return the first non-empty array among two candidate string arrays.
66
docs:
77
show: true
88
arguments:
@@ -14,7 +14,7 @@ macros:
1414
description: Column to fall back on if col_to_check is not populated
1515

1616
- name: get_populated_array_value_as_string
17-
description: This macro returns a string of values based on two input string arrays
17+
description: Join the first non-empty array (of two candidates) into a delimited string.
1818
docs:
1919
show: true
2020
arguments:
@@ -26,7 +26,7 @@ macros:
2626
description: Column to fall back on if col_to_check is not populated
2727

2828
- name: get_populated_array_value_or_string_as_string
29-
description: This macro returns a string of values based on an input string array and a fall back string option
29+
description: Return array contents as string if present else fall back to provided string value.
3030
docs:
3131
show: true
3232
arguments:
@@ -38,7 +38,7 @@ macros:
3838
description: Text based Column to fall back on if col_to_check is not populated
3939

4040
- name: get_populated_numeric_value
41-
description: This macro returns a numeric value based on two input numeric inputs. If both are empty, it returns 0
41+
description: Return first non-null numeric value from two candidates else 0.
4242
docs:
4343
show: true
4444
arguments:
@@ -50,7 +50,7 @@ macros:
5050
description: Column to fall back on if col_to_check is not populated
5151

5252
- name: get_populated_string_value
53-
description: This macro returns a numeric value based on two input numeric inputs. If both are empty, it returns 0
53+
description: Return first non-empty string value from two candidates else empty string.
5454
docs:
5555
show: true
5656
arguments:

macros/clean/clean.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ version: 2
22

33
macros:
44
- name: clean_functions
5-
description: This macro compares dbt user defined functions with those deployed and removes from snowflake if they no longer exist in dbt.
5+
description: Reconcile dbt-defined user defined functions vs deployed; drop any orphaned in Snowflake.
66
docs:
77
show: true
88
arguments:
@@ -14,7 +14,7 @@ macros:
1414
description: specifies if the macro should run in dry run mode
1515

1616
- name: clean_generic
17-
description: This macro compares dbt streams or tasks with those deployed and removes from snowflake if they no longer exist in dbt.
17+
description: Reconcile streams / tasks / stages vs dbt definitions; drop those no longer present.
1818
docs:
1919
show: true
2020
arguments:
@@ -29,7 +29,7 @@ macros:
2929
description: specifies if the macro should run in dry run mode
3030

3131
- name: clean_models
32-
description: This macro compares dbt tables, external tables and views with those deployed and removes from snowflake if they no longer exist in dbt.
32+
description: Reconcile dbt tables, external tables & views with deployed objects; remove orphans.
3333
docs:
3434
show: true
3535
arguments:
@@ -41,7 +41,7 @@ macros:
4141
description: specifies if the macro should run in dry run mode
4242

4343
- name: clean_objects
44-
description: This macro runs all the other clean macros and should be used on a post-hook event
44+
description: Convenience orchestrator to run all clean_* macros (suitable for post-hook usage).
4545
docs:
4646
show: true
4747
arguments:
@@ -57,7 +57,7 @@ macros:
5757

5858

5959
- name: clean_schemas
60-
description: This macro compares dbt schemas with those deployed and removes from snowflake if they no longer exist in dbt.
60+
description: Reconcile schema list vs dbt; drop schemas no longer defined.
6161
docs:
6262
show: true
6363
arguments:
@@ -108,7 +108,7 @@ macros:
108108
description: arguments of the sql object
109109

110110
- name: clean_stale_models
111-
description: This macro removes stale models from snowflake
111+
description: Drop models in a schema older than N days (stale artifact cleanup).
112112
docs:
113113
show: true
114114
arguments:

macros/database/database.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ version: 2
22

33
macros:
44
- name: database_clone
5+
description: Clone (zero-copy) a source database into a new destination database optionally transferring ownership.
56
arguments:
67
- name: source_database
78
description: Source database name, i.e. database to be cloned
@@ -11,6 +12,7 @@ macros:
1112
description: "[Optional] The new owner role of the newly created object"
1213

1314
- name: schema_clone
15+
description: Clone (zero-copy) a source schema into a destination schema; database defaults to target if not supplied.
1416
arguments:
1517
- name: source_schema
1618
description: Source schema name, i.e. schema to be cloned
@@ -24,6 +26,7 @@ macros:
2426
description: "[Optional] The new owner role of the newly created object"
2527

2628
- name: database_destroy
29+
description: Drop the supplied database (destructive operation).
2730
arguments:
2831
- name: database_name
2932
description: Database to drop

macros/dependancies/dependancies.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ version: 2
22

33
macros:
44
- name: depends_on_ref
5-
description: This macro adds a commented refrence to a reference model
5+
description: This macro adds a commented reference to a reference model so downstream lineage remains implicit.
66
docs:
77
show: true
88
arguments:
@@ -14,7 +14,7 @@ macros:
1414
description: the reference model to add
1515

1616
- name: depends_on_source
17-
description: This macro adds a commented refrence to a source model
17+
description: This macro adds a commented reference to a source model so downstream lineage remains implicit.
1818
docs:
1919
show: true
2020
arguments:

macros/dynamic_tables/dynamic_tables.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ version: 2
22

33
macros:
44
- name: target_lag_environment
5-
description: This macro sets the lag duration for the target environment
5+
description: Set the dynamic table target lag duration based on the active target (prod/test/other) to tune freshness vs cost.
66
docs:
77
show: true
88
arguments:
@@ -16,6 +16,6 @@ macros:
1616
type: number
1717
description: specifies the lag duration for other environments
1818
- name: target_warehouse_environment
19-
description: This macro sets the warehouse to be used for the dynamic table for the target environment
19+
description: Select the warehouse to be used for dynamic tables based on target environment (e.g. smaller warehouse for dev/test).
2020
docs:
2121
show: true

0 commit comments

Comments
 (0)