secretzero 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- secretzero-0.1.1/.envrc +7 -0
- secretzero-0.1.1/.github/FUNDING.yml +1 -0
- secretzero-0.1.1/.github/PULL_REQUEST_TEMPLATE.md +29 -0
- secretzero-0.1.1/.github/TEMPLATE_TARGET_IMPLEMENTATION.md +513 -0
- secretzero-0.1.1/.github/TEMPLATE_TARGET_QUICK_START.md +251 -0
- secretzero-0.1.1/.github/copilot-instructions.md +560 -0
- secretzero-0.1.1/.github/dependabot.yml +10 -0
- secretzero-0.1.1/.github/prompts/build.yml +63 -0
- secretzero-0.1.1/.github/workflows/actionsup.disabled +21 -0
- secretzero-0.1.1/.github/workflows/docker.yaml +87 -0
- secretzero-0.1.1/.github/workflows/docs.yaml +47 -0
- secretzero-0.1.1/.github/workflows/release.yaml +104 -0
- secretzero-0.1.1/.github/workflows/test.yaml +55 -0
- secretzero-0.1.1/.gitignore +39 -0
- secretzero-0.1.1/.gitsecrets.lock +41 -0
- secretzero-0.1.1/Dockerfile +55 -0
- secretzero-0.1.1/LICENSE +201 -0
- secretzero-0.1.1/PKG-INFO +591 -0
- secretzero-0.1.1/README.md +507 -0
- secretzero-0.1.1/Secretfile.example.yml +203 -0
- secretzero-0.1.1/Secretfile.schema.json +416 -0
- secretzero-0.1.1/Secretfile.test.yml +104 -0
- secretzero-0.1.1/Secretfile.yml +66 -0
- secretzero-0.1.1/Taskfile.yml +252 -0
- secretzero-0.1.1/configure.sh +24 -0
- secretzero-0.1.1/docker-compose.yml +110 -0
- secretzero-0.1.1/docs/api-getting-started.md +373 -0
- secretzero-0.1.1/docs/development.md +120 -0
- secretzero-0.1.1/docs/examples/complete.md +913 -0
- secretzero-0.1.1/docs/examples/index.md +426 -0
- secretzero-0.1.1/docs/examples/repository.md +675 -0
- secretzero-0.1.1/docs/extending.md +288 -0
- secretzero-0.1.1/docs/getting-started/concepts.md +986 -0
- secretzero-0.1.1/docs/getting-started/first-project.md +861 -0
- secretzero-0.1.1/docs/getting-started/index.md +176 -0
- secretzero-0.1.1/docs/getting-started/installation.md +438 -0
- secretzero-0.1.1/docs/getting-started/quickstart.md +456 -0
- secretzero-0.1.1/docs/inc/Secret0_logo.png +0 -0
- secretzero-0.1.1/docs/inc/secret0_angel.png +0 -0
- secretzero-0.1.1/docs/inc/secret0_angel_small.png +0 -0
- secretzero-0.1.1/docs/index.md +302 -0
- secretzero-0.1.1/docs/javascripts/mermaid.js +28 -0
- secretzero-0.1.1/docs/reference/architecture.md +998 -0
- secretzero-0.1.1/docs/reference/changelog.md +429 -0
- secretzero-0.1.1/docs/reference/faq.md +934 -0
- secretzero-0.1.1/docs/reference/troubleshooting.md +1220 -0
- secretzero-0.1.1/docs/schema.md +434 -0
- secretzero-0.1.1/docs/status.md +280 -0
- secretzero-0.1.1/docs/stylesheets/extra.css +103 -0
- secretzero-0.1.1/docs/use-cases/compliance.md +1726 -0
- secretzero-0.1.1/docs/use-cases/github-actions.md +892 -0
- secretzero-0.1.1/docs/use-cases/gitlab-cicd.md +849 -0
- secretzero-0.1.1/docs/use-cases/index.md +99 -0
- secretzero-0.1.1/docs/use-cases/jenkins.md +723 -0
- secretzero-0.1.1/docs/use-cases/kubernetes.md +1599 -0
- secretzero-0.1.1/docs/use-cases/local-development.md +643 -0
- secretzero-0.1.1/docs/use-cases/migration.md +2197 -0
- secretzero-0.1.1/docs/use-cases/multi-cloud.md +2114 -0
- secretzero-0.1.1/docs/use_cases.md +31 -0
- secretzero-0.1.1/docs/user-guide/api/authentication.md +554 -0
- secretzero-0.1.1/docs/user-guide/api/deployment.md +932 -0
- secretzero-0.1.1/docs/user-guide/api/endpoints.md +844 -0
- secretzero-0.1.1/docs/user-guide/api/getting-started.md +541 -0
- secretzero-0.1.1/docs/user-guide/api/index.md +179 -0
- secretzero-0.1.1/docs/user-guide/api/python-client.md +790 -0
- secretzero-0.1.1/docs/user-guide/cli/create.md +490 -0
- secretzero-0.1.1/docs/user-guide/cli/drift.md +466 -0
- secretzero-0.1.1/docs/user-guide/cli/graph.md +461 -0
- secretzero-0.1.1/docs/user-guide/cli/index.md +657 -0
- secretzero-0.1.1/docs/user-guide/cli/init.md +341 -0
- secretzero-0.1.1/docs/user-guide/cli/policy.md +603 -0
- secretzero-0.1.1/docs/user-guide/cli/rotate.md +583 -0
- secretzero-0.1.1/docs/user-guide/cli/show.md +399 -0
- secretzero-0.1.1/docs/user-guide/cli/sync.md +586 -0
- secretzero-0.1.1/docs/user-guide/cli/test.md +669 -0
- secretzero-0.1.1/docs/user-guide/cli/validate.md +398 -0
- secretzero-0.1.1/docs/user-guide/configuration/index.md +552 -0
- secretzero-0.1.1/docs/user-guide/configuration/secretfile.md +980 -0
- secretzero-0.1.1/docs/user-guide/configuration/validation.md +872 -0
- secretzero-0.1.1/docs/user-guide/configuration/variables.md +811 -0
- secretzero-0.1.1/docs/user-guide/index.md +306 -0
- secretzero-0.1.1/docs/user-guide/providers/aws.md +902 -0
- secretzero-0.1.1/docs/user-guide/providers/azure.md +953 -0
- secretzero-0.1.1/docs/user-guide/providers/github.md +1062 -0
- secretzero-0.1.1/docs/user-guide/providers/gitlab.md +1598 -0
- secretzero-0.1.1/docs/user-guide/providers/index.md +447 -0
- secretzero-0.1.1/docs/user-guide/providers/jenkins.md +1303 -0
- secretzero-0.1.1/docs/user-guide/providers/kubernetes.md +2273 -0
- secretzero-0.1.1/docs/user-guide/providers/local.md +456 -0
- secretzero-0.1.1/docs/user-guide/providers/vault.md +1360 -0
- secretzero-0.1.1/docs/user-guide/targets/aws.md +857 -0
- secretzero-0.1.1/docs/user-guide/targets/azure.md +1510 -0
- secretzero-0.1.1/docs/user-guide/targets/github.md +1291 -0
- secretzero-0.1.1/docs/user-guide/targets/gitlab.md +1498 -0
- secretzero-0.1.1/docs/user-guide/targets/index.md +355 -0
- secretzero-0.1.1/docs/user-guide/targets/jenkins.md +1326 -0
- secretzero-0.1.1/docs/user-guide/targets/kubernetes.md +2409 -0
- secretzero-0.1.1/docs/user-guide/targets/local.md +823 -0
- secretzero-0.1.1/docs/user-guide/targets/vault.md +1674 -0
- secretzero-0.1.1/examples/README.md +404 -0
- secretzero-0.1.1/examples/api-example.yml +180 -0
- secretzero-0.1.1/examples/aws-only.yml +52 -0
- secretzero-0.1.1/examples/compliance.yml +79 -0
- secretzero-0.1.1/examples/drift-detection.yml +72 -0
- secretzero-0.1.1/examples/github-actions.yml +80 -0
- secretzero-0.1.1/examples/gitlab-cicd.md +296 -0
- secretzero-0.1.1/examples/jenkins-credentials.md +400 -0
- secretzero-0.1.1/examples/kubernetes-basic.yml +114 -0
- secretzero-0.1.1/examples/kubernetes-complete.yml +270 -0
- secretzero-0.1.1/examples/kubernetes-external-secrets.yml +127 -0
- secretzero-0.1.1/examples/kubernetes-multi-namespace.yml +168 -0
- secretzero-0.1.1/examples/local-only.yml +73 -0
- secretzero-0.1.1/examples/multi-cicd.yml +472 -0
- secretzero-0.1.1/examples/multi-cloud.yml +151 -0
- secretzero-0.1.1/examples/rotation-policies.yml +123 -0
- secretzero-0.1.1/mise.toml +10 -0
- secretzero-0.1.1/mkdocs.yml +233 -0
- secretzero-0.1.1/project/ROADMAP.md +358 -0
- secretzero-0.1.1/project/phase1.md +274 -0
- secretzero-0.1.1/project/phase2.md +475 -0
- secretzero-0.1.1/project/phase3.md +619 -0
- secretzero-0.1.1/project/phase4.md +607 -0
- secretzero-0.1.1/project/phase5.md +569 -0
- secretzero-0.1.1/project/phase6.md +433 -0
- secretzero-0.1.1/project/phase7.md +621 -0
- secretzero-0.1.1/project/phase8.md +1 -0
- secretzero-0.1.1/pyproject.toml +156 -0
- secretzero-0.1.1/scripts/detect-project-secrets.sh +321 -0
- secretzero-0.1.1/setup.cfg +4 -0
- secretzero-0.1.1/site/404.html +4312 -0
- secretzero-0.1.1/site/api-getting-started/index.html +4647 -0
- secretzero-0.1.1/site/assets/_mkdocstrings.css +237 -0
- secretzero-0.1.1/site/assets/images/favicon.png +0 -0
- secretzero-0.1.1/site/assets/javascripts/bundle.79ae519e.min.js +16 -0
- secretzero-0.1.1/site/assets/javascripts/bundle.79ae519e.min.js.map +7 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.ar.min.js +1 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.da.min.js +18 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.de.min.js +18 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.du.min.js +18 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.el.min.js +1 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.es.min.js +18 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.fi.min.js +18 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.fr.min.js +18 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.he.min.js +1 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.hi.min.js +1 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.hu.min.js +18 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.hy.min.js +1 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.it.min.js +18 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.ja.min.js +1 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.jp.min.js +1 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.kn.min.js +1 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.ko.min.js +1 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.multi.min.js +1 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.nl.min.js +18 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.no.min.js +18 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.pt.min.js +18 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.ro.min.js +18 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.ru.min.js +18 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.sa.min.js +1 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.stemmer.support.min.js +1 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.sv.min.js +18 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.ta.min.js +1 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.te.min.js +1 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.th.min.js +1 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.tr.min.js +18 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.vi.min.js +1 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/min/lunr.zh.min.js +1 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/tinyseg.js +206 -0
- secretzero-0.1.1/site/assets/javascripts/lunr/wordcut.js +6708 -0
- secretzero-0.1.1/site/assets/javascripts/workers/search.2c215733.min.js +42 -0
- secretzero-0.1.1/site/assets/javascripts/workers/search.2c215733.min.js.map +7 -0
- secretzero-0.1.1/site/assets/stylesheets/main.484c7ddc.min.css +1 -0
- secretzero-0.1.1/site/assets/stylesheets/main.484c7ddc.min.css.map +1 -0
- secretzero-0.1.1/site/assets/stylesheets/palette.ab4e12ef.min.css +1 -0
- secretzero-0.1.1/site/assets/stylesheets/palette.ab4e12ef.min.css.map +1 -0
- secretzero-0.1.1/site/extending/index.html +4569 -0
- secretzero-0.1.1/site/getting-started/index.html +4536 -0
- secretzero-0.1.1/site/getting-started/installation/index.html +5184 -0
- secretzero-0.1.1/site/getting-started/quickstart/index.html +5028 -0
- secretzero-0.1.1/site/index.html +4889 -0
- secretzero-0.1.1/site/objects.inv +0 -0
- secretzero-0.1.1/site/schema/index.html +4865 -0
- secretzero-0.1.1/site/search/search_index.json +1 -0
- secretzero-0.1.1/site/sitemap.xml +275 -0
- secretzero-0.1.1/site/sitemap.xml.gz +0 -0
- secretzero-0.1.1/site/stylesheets/extra.css +103 -0
- secretzero-0.1.1/site/use_cases/index.html +4360 -0
- secretzero-0.1.1/src/secretzero/__init__.py +13 -0
- secretzero-0.1.1/src/secretzero/_version.py +34 -0
- secretzero-0.1.1/src/secretzero/api/__init__.py +5 -0
- secretzero-0.1.1/src/secretzero/api/app.py +654 -0
- secretzero-0.1.1/src/secretzero/api/audit.py +107 -0
- secretzero-0.1.1/src/secretzero/api/auth.py +70 -0
- secretzero-0.1.1/src/secretzero/api/schemas.py +168 -0
- secretzero-0.1.1/src/secretzero/api/server.py +64 -0
- secretzero-0.1.1/src/secretzero/cli.py +2588 -0
- secretzero-0.1.1/src/secretzero/cli_providers.py +491 -0
- secretzero-0.1.1/src/secretzero/config.py +134 -0
- secretzero-0.1.1/src/secretzero/drift.py +260 -0
- secretzero-0.1.1/src/secretzero/generators/__init__.py +17 -0
- secretzero-0.1.1/src/secretzero/generators/base.py +52 -0
- secretzero-0.1.1/src/secretzero/generators/provider_backed.py +156 -0
- secretzero-0.1.1/src/secretzero/generators/random_password.py +67 -0
- secretzero-0.1.1/src/secretzero/generators/random_string.py +42 -0
- secretzero-0.1.1/src/secretzero/generators/script.py +68 -0
- secretzero-0.1.1/src/secretzero/generators/static.py +120 -0
- secretzero-0.1.1/src/secretzero/graph.py +414 -0
- secretzero-0.1.1/src/secretzero/lockfile.py +225 -0
- secretzero-0.1.1/src/secretzero/models.py +149 -0
- secretzero-0.1.1/src/secretzero/policy.py +269 -0
- secretzero-0.1.1/src/secretzero/providers/__init__.py +24 -0
- secretzero-0.1.1/src/secretzero/providers/aws.py +419 -0
- secretzero-0.1.1/src/secretzero/providers/azure.py +368 -0
- secretzero-0.1.1/src/secretzero/providers/base.py +255 -0
- secretzero-0.1.1/src/secretzero/providers/capabilities.py +150 -0
- secretzero-0.1.1/src/secretzero/providers/github.py +416 -0
- secretzero-0.1.1/src/secretzero/providers/gitlab.py +382 -0
- secretzero-0.1.1/src/secretzero/providers/jenkins.py +346 -0
- secretzero-0.1.1/src/secretzero/providers/kubernetes.py +381 -0
- secretzero-0.1.1/src/secretzero/providers/registry.py +123 -0
- secretzero-0.1.1/src/secretzero/providers/vault.py +442 -0
- secretzero-0.1.1/src/secretzero/rotation.py +113 -0
- secretzero-0.1.1/src/secretzero/sync.py +1104 -0
- secretzero-0.1.1/src/secretzero/targets/__init__.py +40 -0
- secretzero-0.1.1/src/secretzero/targets/aws.py +283 -0
- secretzero-0.1.1/src/secretzero/targets/azure.py +149 -0
- secretzero-0.1.1/src/secretzero/targets/base.py +65 -0
- secretzero-0.1.1/src/secretzero/targets/file.py +216 -0
- secretzero-0.1.1/src/secretzero/targets/github.py +216 -0
- secretzero-0.1.1/src/secretzero/targets/gitlab.py +177 -0
- secretzero-0.1.1/src/secretzero/targets/jenkins.py +227 -0
- secretzero-0.1.1/src/secretzero/targets/kubernetes.py +265 -0
- secretzero-0.1.1/src/secretzero/targets/template.py +117 -0
- secretzero-0.1.1/src/secretzero/targets/vault.py +164 -0
- secretzero-0.1.1/src/secretzero.egg-info/PKG-INFO +591 -0
- secretzero-0.1.1/src/secretzero.egg-info/SOURCES.txt +273 -0
- secretzero-0.1.1/src/secretzero.egg-info/dependency_links.txt +1 -0
- secretzero-0.1.1/src/secretzero.egg-info/entry_points.txt +3 -0
- secretzero-0.1.1/src/secretzero.egg-info/requires.txt +76 -0
- secretzero-0.1.1/src/secretzero.egg-info/top_level.txt +1 -0
- secretzero-0.1.1/tasks/Taskfile.docker.yml +100 -0
- secretzero-0.1.1/tasks/Taskfile.git.yml +117 -0
- secretzero-0.1.1/tasks/Taskfile.github.yml +53 -0
- secretzero-0.1.1/tests/test_api.py +376 -0
- secretzero-0.1.1/tests/test_aws_capability_methods.py +337 -0
- secretzero-0.1.1/tests/test_azure_capability_methods.py +154 -0
- secretzero-0.1.1/tests/test_capabilities.py +343 -0
- secretzero-0.1.1/tests/test_cicd_providers.py +553 -0
- secretzero-0.1.1/tests/test_cli.py +332 -0
- secretzero-0.1.1/tests/test_cli_providers.py +260 -0
- secretzero-0.1.1/tests/test_config.py +157 -0
- secretzero-0.1.1/tests/test_file_target_validation.py +134 -0
- secretzero-0.1.1/tests/test_generators.py +265 -0
- secretzero-0.1.1/tests/test_github_capability_methods.py +147 -0
- secretzero-0.1.1/tests/test_github_token_info.py +186 -0
- secretzero-0.1.1/tests/test_gitlab_capability_methods.py +148 -0
- secretzero-0.1.1/tests/test_graph.py +348 -0
- secretzero-0.1.1/tests/test_integration_capability_workflows.py +401 -0
- secretzero-0.1.1/tests/test_jenkins_capability_methods.py +155 -0
- secretzero-0.1.1/tests/test_kubernetes.py +355 -0
- secretzero-0.1.1/tests/test_kubernetes_capability_methods.py +174 -0
- secretzero-0.1.1/tests/test_lockfile.py +142 -0
- secretzero-0.1.1/tests/test_lockfile_partial_success.py +60 -0
- secretzero-0.1.1/tests/test_lockfile_rotation.py +168 -0
- secretzero-0.1.1/tests/test_models.py +162 -0
- secretzero-0.1.1/tests/test_policy.py +342 -0
- secretzero-0.1.1/tests/test_provider_backed_generator.py +397 -0
- secretzero-0.1.1/tests/test_providers.py +309 -0
- secretzero-0.1.1/tests/test_rotation.py +150 -0
- secretzero-0.1.1/tests/test_static_empty_values.py +73 -0
- secretzero-0.1.1/tests/test_sync_by_name.py +207 -0
- secretzero-0.1.1/tests/test_targets.py +228 -0
- secretzero-0.1.1/tests/test_template_target.py +329 -0
- secretzero-0.1.1/tests/test_vault_capability_methods.py +348 -0
- secretzero-0.1.1/uv.lock +1998 -0
secretzero-0.1.1/.envrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
github: [zloeber]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
## Description
|
|
2
|
+
[Provide a detailed description of the changes in this PR]
|
|
3
|
+
|
|
4
|
+
## Related Issues
|
|
5
|
+
[Link to related issues using #issue-number format]
|
|
6
|
+
|
|
7
|
+
## Documentation PR
|
|
8
|
+
[Link to related associated PR in the repo]
|
|
9
|
+
|
|
10
|
+
## Type of Change
|
|
11
|
+
- Bug fix
|
|
12
|
+
- New feature
|
|
13
|
+
- Breaking change
|
|
14
|
+
- Documentation update
|
|
15
|
+
- Other (please describe):
|
|
16
|
+
|
|
17
|
+
[Choose one of the above types of changes]
|
|
18
|
+
|
|
19
|
+
## Testing
|
|
20
|
+
[How have you tested the change?]
|
|
21
|
+
|
|
22
|
+
## Checklist
|
|
23
|
+
- [ ] I have added tests that prove my fix is effective or my feature works
|
|
24
|
+
- [ ] I have updated the documentation accordingly
|
|
25
|
+
- [ ] I have added an appropriate example to the documentation to outline the feature
|
|
26
|
+
- [ ] My changes generate no new warnings
|
|
27
|
+
- [ ] Any dependent changes have been merged and published
|
|
28
|
+
|
|
29
|
+
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
|
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
# Jinja2 Template Target Implementation
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
I've successfully implemented a Jinja2 template target for SecretZero that allows you to:
|
|
6
|
+
- Define Jinja2 templates in your repository
|
|
7
|
+
- Process them with secrets to generate configuration files
|
|
8
|
+
- Support conditional logic, loops, and Jinja2 filters
|
|
9
|
+
|
|
10
|
+
## What Was Implemented
|
|
11
|
+
|
|
12
|
+
### 1. Template Target Class (`src/secretzero/targets/template.py`)
|
|
13
|
+
|
|
14
|
+
A new target type that renders Jinja2 templates with secret values:
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
class TemplateTarget(BaseTarget):
|
|
18
|
+
"""Render Jinja2 templates with secret values."""
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Key Features:**
|
|
22
|
+
- Validates required config (template_path, output_path)
|
|
23
|
+
- Collects secrets during sync
|
|
24
|
+
- Renders templates with all collected secrets as context
|
|
25
|
+
- Creates parent directories automatically
|
|
26
|
+
- Proper error handling with clear messages
|
|
27
|
+
- Full Jinja2 feature support (filters, conditionals, loops)
|
|
28
|
+
|
|
29
|
+
### 2. Integration with SecretZero
|
|
30
|
+
|
|
31
|
+
- Registered in `src/secretzero/targets/__init__.py`
|
|
32
|
+
- Updated `src/secretzero/sync.py` to:
|
|
33
|
+
- Import TemplateTarget
|
|
34
|
+
- Handle template targets in `_retrieve_from_target()`
|
|
35
|
+
- Handle template targets in `_store_in_target()`
|
|
36
|
+
- Track collected secrets for templates
|
|
37
|
+
- Call rendering after all secrets are synced via new `_render_template_targets()` method
|
|
38
|
+
- Uses existing `TEMPLATE = "template"` enum value in `TargetKind`
|
|
39
|
+
|
|
40
|
+
### 3. Comprehensive Tests (15 new tests)
|
|
41
|
+
|
|
42
|
+
All passing in `tests/test_template_target.py`:
|
|
43
|
+
- Basic initialization and validation
|
|
44
|
+
- Template rendering with different Jinja2 features
|
|
45
|
+
- Error handling (missing files, invalid syntax)
|
|
46
|
+
- Directory creation
|
|
47
|
+
- File overwriting
|
|
48
|
+
- Jinja2 filters, conditionals, and loops
|
|
49
|
+
|
|
50
|
+
## How to Use
|
|
51
|
+
|
|
52
|
+
### 1. Create a Jinja2 Template File
|
|
53
|
+
|
|
54
|
+
```jinja2
|
|
55
|
+
{# config.j2 #}
|
|
56
|
+
# Database Configuration
|
|
57
|
+
export DB_HOST={{ DB_HOST }}
|
|
58
|
+
export DB_USER={{ DB_USER }}
|
|
59
|
+
export DB_PASS={{ DB_PASSWORD }}
|
|
60
|
+
|
|
61
|
+
# API Configuration
|
|
62
|
+
{% if ENV == 'production' %}
|
|
63
|
+
export DEBUG=False
|
|
64
|
+
export LOG_LEVEL=WARNING
|
|
65
|
+
{% else %}
|
|
66
|
+
export DEBUG=True
|
|
67
|
+
export LOG_LEVEL=DEBUG
|
|
68
|
+
{% endif %}
|
|
69
|
+
|
|
70
|
+
# Additional servers
|
|
71
|
+
servers:
|
|
72
|
+
{% for server in SERVERS.split(',') %}
|
|
73
|
+
- {{ server }}
|
|
74
|
+
{% endfor %}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 2. Define in Secretfile.yml
|
|
78
|
+
|
|
79
|
+
```yaml
|
|
80
|
+
version: "1.0"
|
|
81
|
+
|
|
82
|
+
secrets:
|
|
83
|
+
- name: DB_HOST
|
|
84
|
+
kind: static
|
|
85
|
+
config:
|
|
86
|
+
value: "localhost"
|
|
87
|
+
targets:
|
|
88
|
+
- provider: local
|
|
89
|
+
kind: template
|
|
90
|
+
config:
|
|
91
|
+
template_path: "config.j2"
|
|
92
|
+
output_path: ".env"
|
|
93
|
+
|
|
94
|
+
- name: DB_USER
|
|
95
|
+
kind: static
|
|
96
|
+
config:
|
|
97
|
+
value: "admin"
|
|
98
|
+
targets:
|
|
99
|
+
- provider: local
|
|
100
|
+
kind: template
|
|
101
|
+
config:
|
|
102
|
+
template_path: "config.j2"
|
|
103
|
+
output_path: ".env"
|
|
104
|
+
|
|
105
|
+
- name: DB_PASSWORD
|
|
106
|
+
kind: random_password
|
|
107
|
+
config:
|
|
108
|
+
length: 32
|
|
109
|
+
targets:
|
|
110
|
+
- provider: local
|
|
111
|
+
kind: template
|
|
112
|
+
config:
|
|
113
|
+
template_path: "config.j2"
|
|
114
|
+
output_path: ".env"
|
|
115
|
+
|
|
116
|
+
- name: ENV
|
|
117
|
+
kind: static
|
|
118
|
+
config:
|
|
119
|
+
value: "development"
|
|
120
|
+
targets:
|
|
121
|
+
- provider: local
|
|
122
|
+
kind: template
|
|
123
|
+
config:
|
|
124
|
+
template_path: "config.j2"
|
|
125
|
+
output_path: ".env"
|
|
126
|
+
|
|
127
|
+
- name: SERVERS
|
|
128
|
+
kind: static
|
|
129
|
+
config:
|
|
130
|
+
value: "server1.example.com,server2.example.com"
|
|
131
|
+
targets:
|
|
132
|
+
- provider: local
|
|
133
|
+
kind: template
|
|
134
|
+
config:
|
|
135
|
+
template_path: "config.j2"
|
|
136
|
+
output_path: ".env"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### 3. Run Sync
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
secretzero sync -f Secretfile.yml
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
This will:
|
|
146
|
+
1. Generate/retrieve all secrets
|
|
147
|
+
2. Collect them for each template target
|
|
148
|
+
3. Render the templates with those secrets
|
|
149
|
+
4. Write output files (.env in this example)
|
|
150
|
+
|
|
151
|
+
## Template Syntax
|
|
152
|
+
|
|
153
|
+
### Access Secrets
|
|
154
|
+
|
|
155
|
+
Both of these work:
|
|
156
|
+
```jinja2
|
|
157
|
+
{{ DB_HOST }} # Direct access
|
|
158
|
+
{{ secrets.DB_HOST }} # Dict access (recommended for clarity)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Jinja2 Features
|
|
162
|
+
|
|
163
|
+
**Conditionals:**
|
|
164
|
+
```jinja2
|
|
165
|
+
{% if ENV == 'production' %}
|
|
166
|
+
DEBUG=False
|
|
167
|
+
{% else %}
|
|
168
|
+
DEBUG=True
|
|
169
|
+
{% endif %}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**Loops:**
|
|
173
|
+
```jinja2
|
|
174
|
+
{% for host in HOSTS.split(',') %}
|
|
175
|
+
- {{ host }}
|
|
176
|
+
{% endfor %}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Filters:**
|
|
180
|
+
```jinja2
|
|
181
|
+
{{ API_KEY | upper }} # Uppercase
|
|
182
|
+
{{ API_KEY | length }} # Length
|
|
183
|
+
{{ DB_PASS | string }} # Convert to string
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**Default Values:**
|
|
187
|
+
```jinja2
|
|
188
|
+
{{ DB_PORT | default('5432') }}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Multi-line:**
|
|
192
|
+
```jinja2
|
|
193
|
+
{% if ENABLED | bool %}
|
|
194
|
+
enabled = true
|
|
195
|
+
{% endif %}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Configuration Options
|
|
199
|
+
|
|
200
|
+
| Option | Type | Required | Default | Description |
|
|
201
|
+
|--------|------|----------|---------|-------------|
|
|
202
|
+
| `template_path` | string | Yes | - | Path to Jinja2 template file (relative or absolute) |
|
|
203
|
+
| `output_path` | string | Yes | - | Path where rendered file will be written |
|
|
204
|
+
| `overwrite` | boolean | No | true | Whether to overwrite existing output file |
|
|
205
|
+
|
|
206
|
+
## How It Works
|
|
207
|
+
|
|
208
|
+
### Architecture Flow
|
|
209
|
+
|
|
210
|
+
```
|
|
211
|
+
Secretfile.yml
|
|
212
|
+
↓
|
|
213
|
+
Generate/retrieve secrets for "template" targets
|
|
214
|
+
↓
|
|
215
|
+
Collect secrets in _template_targets (keyed by output_path)
|
|
216
|
+
↓
|
|
217
|
+
After all secrets synced:
|
|
218
|
+
↓
|
|
219
|
+
Call _render_template_targets()
|
|
220
|
+
↓
|
|
221
|
+
For each template target:
|
|
222
|
+
- Load Jinja2 template
|
|
223
|
+
- Render with collected secrets
|
|
224
|
+
- Write to output_path
|
|
225
|
+
↓
|
|
226
|
+
Update lockfile
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Key Implementation Details
|
|
230
|
+
|
|
231
|
+
1. **Collection Phase**: When `_store_in_target()` is called for a template target, secrets are collected in memory (not written immediately)
|
|
232
|
+
|
|
233
|
+
2. **Rendering Phase**: After all secrets are synced, `_render_template_targets()` renders all templates together with their collected secrets
|
|
234
|
+
|
|
235
|
+
3. **Context Data**: Templates have access to:
|
|
236
|
+
- Direct variable access: `{{ SECRET_NAME }}`
|
|
237
|
+
- Dict access: `{{ secrets.SECRET_NAME }}`
|
|
238
|
+
- Full dictionary: `secrets` variable contains all secrets
|
|
239
|
+
|
|
240
|
+
4. **Error Handling**: If template rendering fails:
|
|
241
|
+
- Clear error message is returned
|
|
242
|
+
- Sync continues with other targets
|
|
243
|
+
- Error is reported in sync results
|
|
244
|
+
|
|
245
|
+
## Advanced Examples
|
|
246
|
+
|
|
247
|
+
### Environment-Specific Configuration
|
|
248
|
+
|
|
249
|
+
```yaml
|
|
250
|
+
secrets:
|
|
251
|
+
- name: APP_CONFIG
|
|
252
|
+
kind: static
|
|
253
|
+
config:
|
|
254
|
+
value: "prod"
|
|
255
|
+
targets:
|
|
256
|
+
- provider: local
|
|
257
|
+
kind: template
|
|
258
|
+
config:
|
|
259
|
+
template_path: "config.template.j2"
|
|
260
|
+
output_path: "config.yml"
|
|
261
|
+
|
|
262
|
+
- name: DB_CONNECTION_STRING
|
|
263
|
+
kind: random_string
|
|
264
|
+
config:
|
|
265
|
+
length: 32
|
|
266
|
+
targets:
|
|
267
|
+
- provider: local
|
|
268
|
+
kind: template
|
|
269
|
+
config:
|
|
270
|
+
template_path: "config.template.j2"
|
|
271
|
+
output_path: "config.yml"
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
**config.template.j2:**
|
|
275
|
+
```yaml
|
|
276
|
+
application:
|
|
277
|
+
name: myapp
|
|
278
|
+
environment: {{ APP_CONFIG }}
|
|
279
|
+
|
|
280
|
+
database:
|
|
281
|
+
connection_string: {{ DB_CONNECTION_STRING }}
|
|
282
|
+
|
|
283
|
+
{% if APP_CONFIG == 'prod' %}
|
|
284
|
+
timeout: 30
|
|
285
|
+
pool_size: 20
|
|
286
|
+
{% else %}
|
|
287
|
+
timeout: 5
|
|
288
|
+
pool_size: 5
|
|
289
|
+
{% endif %}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Multi-format Configuration
|
|
293
|
+
|
|
294
|
+
Generate both `.env` and `config.json` from the same secrets:
|
|
295
|
+
|
|
296
|
+
```yaml
|
|
297
|
+
secrets:
|
|
298
|
+
- name: API_KEY
|
|
299
|
+
kind: random_string
|
|
300
|
+
config:
|
|
301
|
+
length: 32
|
|
302
|
+
targets:
|
|
303
|
+
- provider: local
|
|
304
|
+
kind: template
|
|
305
|
+
config:
|
|
306
|
+
template_path: "env.template.j2"
|
|
307
|
+
output_path: ".env"
|
|
308
|
+
|
|
309
|
+
- provider: local
|
|
310
|
+
kind: template
|
|
311
|
+
config:
|
|
312
|
+
template_path: "config.template.j2"
|
|
313
|
+
output_path: "config.json"
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
## Requirements
|
|
317
|
+
|
|
318
|
+
### Dependencies
|
|
319
|
+
|
|
320
|
+
Jinja2 must be available (included in SecretZero by default):
|
|
321
|
+
```bash
|
|
322
|
+
pip install secretzero
|
|
323
|
+
# or
|
|
324
|
+
pip install jinja2
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### File Permissions
|
|
328
|
+
|
|
329
|
+
- Read access to template files
|
|
330
|
+
- Write access to output directories
|
|
331
|
+
|
|
332
|
+
## Testing
|
|
333
|
+
|
|
334
|
+
Run the template target tests:
|
|
335
|
+
```bash
|
|
336
|
+
pytest tests/test_template_target.py -v
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
All 241 tests pass (15 new template tests + 226 existing tests).
|
|
340
|
+
|
|
341
|
+
## Integration with Existing Features
|
|
342
|
+
|
|
343
|
+
### With Lockfile Tracking
|
|
344
|
+
|
|
345
|
+
Template targets are tracked in the lockfile like other targets:
|
|
346
|
+
- Rotation history recorded
|
|
347
|
+
- Change detection supported
|
|
348
|
+
- Drift detection compatible
|
|
349
|
+
|
|
350
|
+
### With Rotation Policies
|
|
351
|
+
|
|
352
|
+
Template targets support rotation:
|
|
353
|
+
```yaml
|
|
354
|
+
secrets:
|
|
355
|
+
- name: API_KEY
|
|
356
|
+
kind: random_string
|
|
357
|
+
rotation_period: 30
|
|
358
|
+
config:
|
|
359
|
+
length: 32
|
|
360
|
+
targets:
|
|
361
|
+
- provider: local
|
|
362
|
+
kind: template
|
|
363
|
+
config:
|
|
364
|
+
template_path: "config.j2"
|
|
365
|
+
output_path: "app_config.json"
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### With Dry-Run
|
|
369
|
+
|
|
370
|
+
Test template rendering without writing files:
|
|
371
|
+
```bash
|
|
372
|
+
secretzero sync -f Secretfile.yml --dry-run
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
## Troubleshooting
|
|
376
|
+
|
|
377
|
+
### Template File Not Found
|
|
378
|
+
```
|
|
379
|
+
Failed to render template: Template file not found: /path/to/template.j2
|
|
380
|
+
```
|
|
381
|
+
**Solution:** Verify template_path is correct (absolute or relative to where sync is run)
|
|
382
|
+
|
|
383
|
+
### Undefined Variable in Template
|
|
384
|
+
```
|
|
385
|
+
Template rendering failed: ... undefined variable ...
|
|
386
|
+
```
|
|
387
|
+
**Solution:** Ensure all variables used in template are defined as secrets with template targets
|
|
388
|
+
|
|
389
|
+
### Invalid Jinja2 Syntax
|
|
390
|
+
```
|
|
391
|
+
Template rendering failed: ... 'nonexistent_filter' is undefined
|
|
392
|
+
```
|
|
393
|
+
**Solution:** Check Jinja2 filter names and syntax
|
|
394
|
+
|
|
395
|
+
### Permission Denied
|
|
396
|
+
```
|
|
397
|
+
Failed to render template: ... Permission denied ...
|
|
398
|
+
```
|
|
399
|
+
**Solution:** Verify write permissions on output directory
|
|
400
|
+
|
|
401
|
+
## Future Enhancements
|
|
402
|
+
|
|
403
|
+
Potential features (not yet implemented):
|
|
404
|
+
- Variable scope/namespacing
|
|
405
|
+
- Template inheritance
|
|
406
|
+
- Custom Jinja2 filters
|
|
407
|
+
- Template validation before rendering
|
|
408
|
+
- Template version tracking
|
|
409
|
+
- Multiple template rendering per secret
|
|
410
|
+
|
|
411
|
+
## Files Changed
|
|
412
|
+
|
|
413
|
+
### New Files
|
|
414
|
+
- `src/secretzero/targets/template.py` - TemplateTarget implementation
|
|
415
|
+
- `tests/test_template_target.py` - 15 comprehensive tests
|
|
416
|
+
|
|
417
|
+
### Modified Files
|
|
418
|
+
- `src/secretzero/targets/__init__.py` - Added TemplateTarget import and export
|
|
419
|
+
- `src/secretzero/sync.py` - Added template target handling in sync engine
|
|
420
|
+
|
|
421
|
+
### Test Results
|
|
422
|
+
- ✅ All 241 tests passing (15 new + 226 existing)
|
|
423
|
+
- ✅ 98% coverage for template.py
|
|
424
|
+
- ✅ No regressions in existing functionality
|
|
425
|
+
|
|
426
|
+
## Example Complete Secretfile
|
|
427
|
+
|
|
428
|
+
```yaml
|
|
429
|
+
version: "1.0"
|
|
430
|
+
|
|
431
|
+
secrets:
|
|
432
|
+
# Database credentials
|
|
433
|
+
- name: db_host
|
|
434
|
+
kind: static
|
|
435
|
+
config:
|
|
436
|
+
value: "postgres.example.com"
|
|
437
|
+
targets:
|
|
438
|
+
- provider: local
|
|
439
|
+
kind: template
|
|
440
|
+
config:
|
|
441
|
+
template_path: "templates/docker-compose.j2"
|
|
442
|
+
output_path: "docker-compose.yml"
|
|
443
|
+
|
|
444
|
+
- name: db_user
|
|
445
|
+
kind: static
|
|
446
|
+
config:
|
|
447
|
+
value: "appuser"
|
|
448
|
+
targets:
|
|
449
|
+
- provider: local
|
|
450
|
+
kind: template
|
|
451
|
+
config:
|
|
452
|
+
template_path: "templates/docker-compose.j2"
|
|
453
|
+
output_path: "docker-compose.yml"
|
|
454
|
+
|
|
455
|
+
- name: db_password
|
|
456
|
+
kind: random_password
|
|
457
|
+
config:
|
|
458
|
+
length: 32
|
|
459
|
+
targets:
|
|
460
|
+
- provider: local
|
|
461
|
+
kind: template
|
|
462
|
+
config:
|
|
463
|
+
template_path: "templates/docker-compose.j2"
|
|
464
|
+
output_path: "docker-compose.yml"
|
|
465
|
+
|
|
466
|
+
# API secrets
|
|
467
|
+
- name: api_key
|
|
468
|
+
kind: random_string
|
|
469
|
+
config:
|
|
470
|
+
length: 64
|
|
471
|
+
targets:
|
|
472
|
+
- provider: local
|
|
473
|
+
kind: template
|
|
474
|
+
config:
|
|
475
|
+
template_path: "templates/api-config.j2"
|
|
476
|
+
output_path: ".env.local"
|
|
477
|
+
|
|
478
|
+
- name: environment
|
|
479
|
+
kind: static
|
|
480
|
+
config:
|
|
481
|
+
value: "development"
|
|
482
|
+
targets:
|
|
483
|
+
- provider: local
|
|
484
|
+
kind: template
|
|
485
|
+
config:
|
|
486
|
+
template_path: "templates/api-config.j2"
|
|
487
|
+
output_path: ".env.local"
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
**templates/docker-compose.j2:**
|
|
491
|
+
```yaml
|
|
492
|
+
version: '3.9'
|
|
493
|
+
|
|
494
|
+
services:
|
|
495
|
+
postgres:
|
|
496
|
+
image: postgres:15
|
|
497
|
+
environment:
|
|
498
|
+
POSTGRES_USER: {{ db_user }}
|
|
499
|
+
POSTGRES_PASSWORD: {{ db_password }}
|
|
500
|
+
POSTGRES_HOST_NAME: {{ db_host }}
|
|
501
|
+
ports:
|
|
502
|
+
- "5432:5432"
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
**templates/api-config.j2:**
|
|
506
|
+
```bash
|
|
507
|
+
# Generated configuration file
|
|
508
|
+
API_KEY={{ api_key }}
|
|
509
|
+
ENVIRONMENT={{ environment }}
|
|
510
|
+
DEBUG={% if environment == 'development' %}true{% else %}false{% endif %}
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
This provides a complete, production-ready template target implementation integrated with SecretZero's architecture!
|