nyl 0.6.0__tar.gz → 0.7.0__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.
Files changed (119) hide show
  1. nyl-0.7.0/.changelog/0.7.0.toml +70 -0
  2. {nyl-0.6.0 → nyl-0.7.0}/.github/workflows/docker.yaml +4 -4
  3. {nyl-0.6.0 → nyl-0.7.0}/.github/workflows/python.yaml +33 -5
  4. nyl-0.7.0/.github/workflows/update-flake-lock.yaml +23 -0
  5. {nyl-0.6.0 → nyl-0.7.0}/PKG-INFO +10 -3
  6. {nyl-0.6.0 → nyl-0.7.0}/README.md +8 -1
  7. {nyl-0.6.0 → nyl-0.7.0}/argocd-cmp/Dockerfile +3 -3
  8. {nyl-0.6.0 → nyl-0.7.0}/argocd-with-nyl/argocd.yaml +2 -2
  9. nyl-0.7.0/docs/content/changelog.md +69 -0
  10. {nyl-0.6.0 → nyl-0.7.0}/docs/content/reference/applysets.md +1 -1
  11. {nyl-0.6.0 → nyl-0.7.0}/docs/content/reference/argocd-plugin.md +1 -1
  12. {nyl-0.6.0 → nyl-0.7.0}/docs/content/reference/templating/inlining/helmcharts.md +3 -0
  13. {nyl-0.6.0 → nyl-0.7.0}/docs/content/reference/templating/inlining/postprocessor.md +38 -2
  14. {nyl-0.6.0 → nyl-0.7.0}/flake.nix +1 -1
  15. {nyl-0.6.0 → nyl-0.7.0}/pyproject.toml +20 -1
  16. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/commands/__init__.py +1 -1
  17. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/commands/new.py +20 -11
  18. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/commands/run.py +5 -5
  19. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/commands/template.py +96 -71
  20. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/commands/tools/sops.py +1 -1
  21. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/generator/helmchart.py +8 -4
  22. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/profiles/__init__.py +2 -2
  23. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/profiles/kubeconfig.py +3 -3
  24. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/profiles/tunnel.py +2 -2
  25. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/project/config.py +1 -1
  26. nyl-0.7.0/src/nyl/resources/helmchart_test.py +81 -0
  27. nyl-0.7.0/src/nyl/resources/postprocessor.py +206 -0
  28. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/resources/postprocessor_test.py +18 -2
  29. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/secrets/sops.py +4 -4
  30. nyl-0.7.0/src/nyl/tools/kubernetes.py +69 -0
  31. nyl-0.6.0/src/nyl/resources/postprocessor.py +0 -128
  32. nyl-0.6.0/src/nyl/tools/kubernetes.py +0 -34
  33. {nyl-0.6.0 → nyl-0.7.0}/.envrc +0 -0
  34. {nyl-0.6.0 → nyl-0.7.0}/.github/workflows/docs.yaml +0 -0
  35. {nyl-0.6.0 → nyl-0.7.0}/.gitignore +0 -0
  36. {nyl-0.6.0 → nyl-0.7.0}/argocd-cmp/README.md +0 -0
  37. {nyl-0.6.0 → nyl-0.7.0}/argocd-cmp/plugin.yaml +0 -0
  38. {nyl-0.6.0 → nyl-0.7.0}/argocd-with-nyl/.envrc +0 -0
  39. {nyl-0.6.0 → nyl-0.7.0}/argocd-with-nyl/.secrets.yaml +0 -0
  40. {nyl-0.6.0 → nyl-0.7.0}/argocd-with-nyl/.sops.yaml +0 -0
  41. {nyl-0.6.0 → nyl-0.7.0}/argocd-with-nyl/README.md +0 -0
  42. {nyl-0.6.0 → nyl-0.7.0}/argocd-with-nyl/nyl-project.yaml +0 -0
  43. {nyl-0.6.0 → nyl-0.7.0}/argocd-with-nyl/nyl-secrets.yaml +0 -0
  44. {nyl-0.6.0 → nyl-0.7.0}/docs/content/index.md +0 -0
  45. {nyl-0.6.0 → nyl-0.7.0}/docs/content/reference/cluster-connectivity.md +0 -0
  46. {nyl-0.6.0 → nyl-0.7.0}/docs/content/reference/configuration/environment.md +0 -0
  47. {nyl-0.6.0 → nyl-0.7.0}/docs/content/reference/configuration/profiles.md +0 -0
  48. {nyl-0.6.0 → nyl-0.7.0}/docs/content/reference/configuration/projects.md +0 -0
  49. {nyl-0.6.0 → nyl-0.7.0}/docs/content/reference/configuration/secrets.md +0 -0
  50. {nyl-0.6.0 → nyl-0.7.0}/docs/content/reference/configuration-api/profiles.md +0 -0
  51. {nyl-0.6.0 → nyl-0.7.0}/docs/content/reference/configuration-api/secrets.md +0 -0
  52. {nyl-0.6.0 → nyl-0.7.0}/docs/content/reference/glossary.md +0 -0
  53. {nyl-0.6.0 → nyl-0.7.0}/docs/content/reference/templating/basics.md +0 -0
  54. {nyl-0.6.0 → nyl-0.7.0}/docs/content/reference/templating/components.md +0 -0
  55. {nyl-0.6.0 → nyl-0.7.0}/docs/content/reference/templating/inlining/overview.md +0 -0
  56. {nyl-0.6.0 → nyl-0.7.0}/docs/content/reference/templating/secrets.md +0 -0
  57. {nyl-0.6.0 → nyl-0.7.0}/docs/mkdocs.yml +0 -0
  58. {nyl-0.6.0 → nyl-0.7.0}/docs/pyproject.toml +0 -0
  59. {nyl-0.6.0 → nyl-0.7.0}/docs/uv.lock +0 -0
  60. {nyl-0.6.0 → nyl-0.7.0}/example/manifests/postgres.yaml +0 -0
  61. {nyl-0.6.0 → nyl-0.7.0}/example/nyl-profiles.yaml +0 -0
  62. {nyl-0.6.0 → nyl-0.7.0}/example/nyl-secrets.yaml +0 -0
  63. {nyl-0.6.0 → nyl-0.7.0}/example/secrets.yaml +0 -0
  64. {nyl-0.6.0 → nyl-0.7.0}/flake.lock +0 -0
  65. {nyl-0.6.0 → nyl-0.7.0}/nix/uv.nix +0 -0
  66. {nyl-0.6.0 → nyl-0.7.0}/renovate.json +0 -0
  67. {nyl-0.6.0 → nyl-0.7.0}/src/kubernetes/README.md +0 -0
  68. {nyl-0.6.0 → nyl-0.7.0}/src/kubernetes/__init__.pyi +0 -0
  69. {nyl-0.6.0 → nyl-0.7.0}/src/kubernetes/dynamic/__init__.pyi +0 -0
  70. {nyl-0.6.0 → nyl-0.7.0}/src/kubernetes/dynamic/client.pyi +0 -0
  71. {nyl-0.6.0 → nyl-0.7.0}/src/kubernetes/dynamic/discovery.pyi +0 -0
  72. {nyl-0.6.0 → nyl-0.7.0}/src/kubernetes/dynamic/exceptions.pyi +0 -0
  73. {nyl-0.6.0 → nyl-0.7.0}/src/kubernetes/dynamic/resource.pyi +0 -0
  74. {nyl-0.6.0 → nyl-0.7.0}/src/kubernetes/watch/__init__.pyi +0 -0
  75. {nyl-0.6.0 → nyl-0.7.0}/src/kubernetes/watch/watch.pyi +0 -0
  76. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/__init__.py +0 -0
  77. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/commands/argocd.py +0 -0
  78. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/commands/crds.py +0 -0
  79. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/commands/profile.py +0 -0
  80. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/commands/secrets.py +0 -0
  81. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/commands/tools/__init__.py +0 -0
  82. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/commands/tools/bcrypt.py +0 -0
  83. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/commands/tun.py +0 -0
  84. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/generator/__init__.py +0 -0
  85. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/generator/components.py +0 -0
  86. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/generator/dispatch.py +0 -0
  87. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/generator/dispatch_test.py +0 -0
  88. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/generator/statefulsecret.py +0 -0
  89. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/profiles/config.py +0 -0
  90. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/profiles/config_test.py +0 -0
  91. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/resources/__init__.py +0 -0
  92. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/resources/applyset.py +0 -0
  93. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/resources/applyset_test.py +0 -0
  94. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/resources/helmchart.py +0 -0
  95. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/resources/placeholder.py +0 -0
  96. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/resources/statefulsecret.py +0 -0
  97. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/secrets/__init__.py +0 -0
  98. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/secrets/config.py +0 -0
  99. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/secrets/config_test.py +0 -0
  100. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/secrets/kubernetes.py +0 -0
  101. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/secrets/null.py +0 -0
  102. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/secrets/sops_test.py +0 -0
  103. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/templating.py +0 -0
  104. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/templating_test.py +0 -0
  105. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/tools/di.py +0 -0
  106. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/tools/fs.py +0 -0
  107. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/tools/fs_test.py +0 -0
  108. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/tools/kubectl.py +0 -0
  109. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/tools/kvstore.py +0 -0
  110. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/tools/loads.py +0 -0
  111. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/tools/logging.py +0 -0
  112. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/tools/shell.py +0 -0
  113. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/tools/testing.py +0 -0
  114. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/tools/typer.py +0 -0
  115. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/tools/types.py +0 -0
  116. {nyl-0.6.0 → nyl-0.7.0}/src/nyl/tools/yaml.py +0 -0
  117. {nyl-0.6.0 → nyl-0.7.0}/tests/__init__.py +0 -0
  118. {nyl-0.6.0 → nyl-0.7.0}/tests/conftest.py +0 -0
  119. {nyl-0.6.0 → nyl-0.7.0}/uv.lock +0 -0
@@ -0,0 +1,70 @@
1
+ release-date = "2025-01-17"
2
+
3
+ [[entries]]
4
+ id = "d86d5d47-3d02-4321-94a3-bea25c512ecc"
5
+ type = "breaking change"
6
+ description = "Recognize `nyl.io/default-namespace: \"true\"` on Namespace resources to choose between one of multiple namespaces defined in the same manifest file."
7
+ author = "@NiklasRosenstein"
8
+
9
+ [[entries]]
10
+ id = "056ab3d5-fc80-449c-af24-d7bca6f3e522"
11
+ type = "breaking change"
12
+ description = "Instead of not assuming a default namespace when multiple `Namespace` resources are defined in a manifest file, pick the first one alphabetically when none have the `nyl.io/default-namespace: \"true\"` annotation"
13
+ author = "@NiklasRosenstein"
14
+
15
+ [[entries]]
16
+ id = "d0798272-7c1c-402d-8e04-d578cea6a410"
17
+ type = "improvement"
18
+ description = "Apply Nyl `PostProcessor` instructions at the end, after Nyl had a chance to fill in the manifest file's determined default namespace. Kyverno might add the `namespace: default` field to any resource that has no namespace set, making it impossbile for Nyl after the fact to tell which resources need to have their namespace injected."
19
+ author = "@NiklasRosenstein"
20
+
21
+ [[entries]]
22
+ id = "8a3b94a4-0dd9-45a0-8cb2-bd679979527e"
23
+ type = "fix"
24
+ description = "Update `PostProcessor`, pointing Kyverno to a directory and expecting it to output all manifest, not just the mutated ones. The `PostProcessor` is now invoked at the very end, even after Nyl patches resources with the default namespace in the current manifest file."
25
+ author = "@NiklasRosenstein"
26
+
27
+ [[entries]]
28
+ id = "843a3744-7e50-49d3-8dc5-8800e866ca01"
29
+ type = "fix"
30
+ description = "fix #57 -- `ARGOCD_APP_NAMESPACE` and the `--default-namespace` option are used now only when no namespace is defined in the manifest file"
31
+ author = "@NiklasRosenstein"
32
+
33
+ [[entries]]
34
+ id = "3152517a-b701-4d38-ba18-f97f2f03cd09"
35
+ type = "improvement"
36
+ description = "Resources generated by the Nyl `HelmChart` resource now get the chart resource's `metadata.namespace` populated before they are passed up and inlined into the rest of the manifest. Fixes #56"
37
+ author = "@NiklasRosenstein"
38
+
39
+ [[entries]]
40
+ id = "cdbd2567-9801-4514-8552-6fdc352a8185"
41
+ type = "improvement"
42
+ description = "Fix deprecation warnings of using the `loguru.logger.opt(ansi)` keyword argument and use the new `colors` kwarg instead"
43
+ author = "@NiklasRosenstein"
44
+
45
+ [[entries]]
46
+ id = "dd1038ab-19cf-406a-bc06-ccc14ad8fbbb"
47
+ type = "feature"
48
+ description = "Add `PostProcessor.spec.kyvernoRules` field as a shorthand for defining Kyverno policies in a Nyl manifest."
49
+ author = "@NiklasRosenstein"
50
+
51
+ [[entries]]
52
+ id = "2eed140a-4d16-448a-96fb-997b3ca81297"
53
+ type = "refactor"
54
+ description = "Refactor `PostProcessor` implementation for generating policy files and invoking Kyverno"
55
+ author = "@NiklasRosenstein"
56
+
57
+ [[entries]]
58
+ id = "320c1dce-1ba6-451b-9f25-a279ae8b9eb2"
59
+ type = "improvement"
60
+ description = "`PostProcessor` log for invoking Kyverno now lists the policy file paths that are going to be applied"
61
+ author = "@NiklasRosenstein"
62
+
63
+ [[entries]]
64
+ id = "138bdc5d-848b-45fe-a5f4-4c658535339d"
65
+ type = "fix"
66
+ description = "`nyl new chart` now generates 2-space indented YAML and has a more complete template"
67
+ author = "@NiklasRosenstein"
68
+ issues = [
69
+ "https://github.com/NiklasRosenstein/nyl/issues/47",
70
+ ]
@@ -36,8 +36,8 @@ jobs:
36
36
  push: true
37
37
  file: argocd-cmp/Dockerfile
38
38
  tags: |
39
- ghcr.io/niklasrosenstein/nyl/argocd-cmp:${{ github.sha }}
40
- ${{ github.ref_type == 'tag' && format('ghcr.io/niklasrosenstein/nyl/argocd-cmp:{0}', github.ref_name) || '' }}
41
- cache-to: type=registry,ref=ghcr.io/niklasrosenstein/nyl/argocd-cmp:cache,mode=max
42
- cache-from: type=registry,ref=ghcr.io/niklasrosenstein/nyl/argocd-cmp:cache
39
+ ghcr.io/helsing-ai/nyl/argocd-cmp:${{ github.sha }}
40
+ ${{ github.ref_type == 'tag' && format('ghcr.io/helsing-ai/nyl/argocd-cmp:{0}', github.ref_name) || '' }}
41
+ cache-to: type=registry,ref=ghcr.io/helsing-ai/nyl/argocd-cmp:cache,mode=max
42
+ cache-from: type=registry,ref=ghcr.io/helsing-ai/nyl/argocd-cmp:cache
43
43
  platforms: linux/amd64,linux/arm64
@@ -8,7 +8,7 @@ on:
8
8
  branches: [ develop ]
9
9
 
10
10
  jobs:
11
- test:
11
+ test-nix:
12
12
  runs-on: ubuntu-latest
13
13
 
14
14
  steps:
@@ -22,12 +22,40 @@ jobs:
22
22
  with:
23
23
  name: mycache
24
24
 
25
- - run: nix flake check
26
- - run: nix run .#test
25
+ # Ignore failures until we can fix the Nix build.
26
+ - run: nix flake check || true
27
+ - run: nix run .#test || true
28
+
29
+ test-native:
30
+ runs-on: ubuntu-latest
31
+
32
+ steps:
33
+ - uses: actions/checkout@v4
34
+
35
+ - uses: kyverno/action-install-cli@v0.2.0
36
+ with:
37
+ release: 'v1.13.2'
38
+
39
+ - name: Install SOPS
40
+ run: |
41
+ curl -LO https://github.com/getsops/sops/releases/download/v3.9.3/sops-v3.9.3.linux.amd64
42
+ mv sops-v3.9.3.linux.amd64 /usr/local/bin/sops
43
+ chmod +x /usr/local/bin/sops
44
+
45
+ - name: Install uv
46
+ uses: astral-sh/setup-uv@v5
47
+ with:
48
+ version: "0.5.20"
49
+
50
+ - run: uv sync
51
+ - run: uv run pytest .
52
+ - run: uv run mypy .
53
+ - run: uv run ruff check .
54
+ - run: uv run ruff format --check .
27
55
 
28
56
  publish:
29
57
  runs-on: ubuntu-latest
30
- needs: test
58
+ needs: test-native
31
59
  environment: release
32
60
  permissions:
33
61
  id-token: write
@@ -45,7 +73,7 @@ jobs:
45
73
  python-version: "3.10"
46
74
 
47
75
  - name: Bump version
48
- run: sed 's/version = "0.0.0"/version = "${{ github.ref_name }}"/' -i pyproject.toml && git diff
76
+ run: sed 's/version = ".*"/version = "${{ github.ref_name }}"/' -i pyproject.toml && git diff
49
77
 
50
78
  - name: Install uv
51
79
  run: python -m pip install uv
@@ -0,0 +1,23 @@
1
+ # See https://github.com/determinateSystems/update-flake-lock
2
+
3
+ name: update-flake-lock
4
+ on:
5
+ workflow_dispatch: # allows manual triggering
6
+ schedule:
7
+ - cron: '0 0 * * 0' # runs weekly on Sunday at 00:00
8
+
9
+ jobs:
10
+ lockfile:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout repository
14
+ uses: actions/checkout@v4
15
+ - name: Install Nix
16
+ uses: DeterminateSystems/nix-installer-action@main
17
+ - name: Update flake.lock
18
+ uses: DeterminateSystems/update-flake-lock@main
19
+ with:
20
+ pr-title: "Update flake.lock" # Title of PR to be created
21
+ pr-labels: | # Labels to be set on the PR
22
+ dependencies
23
+ automated
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: nyl
3
- Version: 0.6.0
3
+ Version: 0.7.0
4
4
  Summary: Advanced templating engine for Kubernetes and GitOps.
5
5
  Author-email: Niklas Rosenstein <rosensteinniklas@gmail.com>
6
6
  License: MIT
@@ -34,7 +34,7 @@ Requires Python 3.11 or newer.
34
34
  For some features, additional programs must be available:
35
35
 
36
36
  * [kubectl](https://kubernetes.io/de/docs/reference/kubectl/) for most operations
37
- * [kyverno](https://kyverno.io/docs/kyverno-cli/) when using the Nyl `PostProcessor` resource
37
+ * [kyverno](https://kyverno.io/docs/kyverno-cli/) ^1.13.x when using the Nyl `PostProcessor` resource
38
38
  * [sops](https://github.com/getsops/sops) when using the SOPS secrets provider
39
39
 
40
40
  You can install Nyl with Nix to ensure all dependencies are met.
@@ -53,6 +53,13 @@ And to format code, run
53
53
 
54
54
  $ nix fmt
55
55
 
56
+ To build or serve the documentation, run
57
+
58
+ $ nix run .#docs serve
59
+ $ nix run .#docs build
60
+
61
+ respectively.
62
+
56
63
  ## Tracking upstream information
57
64
 
58
65
  * Discussion around ArgoCD supporting Helm lookups (maybe with Project-level service account?), see
@@ -12,7 +12,7 @@ Requires Python 3.11 or newer.
12
12
  For some features, additional programs must be available:
13
13
 
14
14
  * [kubectl](https://kubernetes.io/de/docs/reference/kubectl/) for most operations
15
- * [kyverno](https://kyverno.io/docs/kyverno-cli/) when using the Nyl `PostProcessor` resource
15
+ * [kyverno](https://kyverno.io/docs/kyverno-cli/) ^1.13.x when using the Nyl `PostProcessor` resource
16
16
  * [sops](https://github.com/getsops/sops) when using the SOPS secrets provider
17
17
 
18
18
  You can install Nyl with Nix to ensure all dependencies are met.
@@ -31,6 +31,13 @@ And to format code, run
31
31
 
32
32
  $ nix fmt
33
33
 
34
+ To build or serve the documentation, run
35
+
36
+ $ nix run .#docs serve
37
+ $ nix run .#docs build
38
+
39
+ respectively.
40
+
34
41
  ## Tracking upstream information
35
42
 
36
43
  * Discussion around ArgoCD supporting Helm lookups (maybe with Project-level service account?), see
@@ -3,7 +3,7 @@
3
3
  #: -----------------
4
4
 
5
5
  FROM python:3.13-alpine AS build
6
- COPY --from=ghcr.io/astral-sh/uv:0.5.5 /uv /bin/uv
6
+ COPY --from=ghcr.io/astral-sh/uv:0.5.7 /uv /bin/uv
7
7
 
8
8
  WORKDIR /opt/nyl
9
9
 
@@ -59,7 +59,7 @@ RUN curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/s
59
59
  FROM fetch-bin-base AS sops-bin
60
60
  # Find SOPS releases at https://github.com/getsops/sops/releases
61
61
  # renovate: datasource=github-releases depName=sops packageName=getsops/sops
62
- ARG SOPS_VERSION=v3.9.1
62
+ ARG SOPS_VERSION=v3.9.2
63
63
  RUN curl -fLO https://github.com/getsops/sops/releases/download/${SOPS_VERSION}/sops-${SOPS_VERSION}.linux.$(cat /BINARY_ARCH) \
64
64
  && mv sops-${SOPS_VERSION}.linux.$(cat /BINARY_ARCH) /usr/local/bin/sops \
65
65
  && chmod +x /usr/local/bin/sops \
@@ -68,7 +68,7 @@ RUN curl -fLO https://github.com/getsops/sops/releases/download/${SOPS_VERSION}/
68
68
 
69
69
  FROM fetch-bin-base AS kyverno-bin
70
70
  # renovate: datasource=github-releases depName=kyverno packageName=kyverno/kyverno
71
- ARG KYVERNO_VERSION=1.13.1
71
+ ARG KYVERNO_VERSION=1.13.2
72
72
  RUN \
73
73
  case "$(uname -m)" in \
74
74
  x86_64) KYVERNO_ARCH='x86_64' ;; \
@@ -40,7 +40,7 @@ spec:
40
40
  repoServer:
41
41
  extraContainers:
42
42
  - name: nyl-v1
43
- image: ghcr.io/niklasrosenstein/nyl/argocd-cmp:0.0.7
43
+ image: ghcr.io/helsing-ai/nyl/argocd-cmp:0.0.7
44
44
  securityContext:
45
45
  runAsNonRoot: true
46
46
  runAsUser: 999
@@ -76,7 +76,7 @@ metadata:
76
76
  spec:
77
77
  project: default
78
78
  source:
79
- repoURL: https://github.com/NiklasRosenstein/nyl.git
79
+ repoURL: https://github.com/helsing-ai/nyl.git
80
80
  targetRevision: HEAD
81
81
  path: argocd-with-nyl
82
82
  destination:
@@ -0,0 +1,69 @@
1
+ # Changelog
2
+
3
+ ## 0.7.0
4
+
5
+ <table><tr><th>Type</th><th>Description</th><th>PR</th><th>Issues</th><th>Author</th></tr>
6
+ <tr><td>Breaking change</td><td>
7
+
8
+ Recognize `nyl.io/default-namespace: "true"` on Namespace resources to choose between one of multiple namespaces defined in the same manifest file.</td><td></td><td></td><td>@NiklasRosenstein</td></tr>
9
+ <tr><td>Breaking change</td><td>
10
+
11
+ Instead of not assuming a default namespace when multiple `Namespace` resources are defined in a manifest file, pick the first one alphabetically when none have the `nyl.io/default-namespace: "true"` annotation</td><td></td><td></td><td>@NiklasRosenstein</td></tr>
12
+ <tr><td>Improvement</td><td>
13
+
14
+ Apply Nyl `PostProcessor` instructions at the end, after Nyl had a chance to fill in the manifest file's determined default namespace. Kyverno might add the `namespace: default` field to any resource that has no namespace set, making it impossbile for Nyl after the fact to tell which resources need to have their namespace injected.</td><td></td><td></td><td>@NiklasRosenstein</td></tr>
15
+ <tr><td>Fix</td><td>
16
+
17
+ Update `PostProcessor`, pointing Kyverno to a directory and expecting it to output all manifest, not just the mutated ones. The `PostProcessor` is now invoked at the very end, even after Nyl patches resources with the default namespace in the current manifest file.</td><td></td><td></td><td>@NiklasRosenstein</td></tr>
18
+ <tr><td>Fix</td><td>
19
+
20
+ fix #57 -- `ARGOCD_APP_NAMESPACE` and the `--default-namespace` option are used now only when no namespace is defined in the manifest file</td><td></td><td></td><td>@NiklasRosenstein</td></tr>
21
+ <tr><td>Improvement</td><td>
22
+
23
+ Resources generated by the Nyl `HelmChart` resource now get the chart resource's `metadata.namespace` populated before they are passed up and inlined into the rest of the manifest. Fixes #56</td><td></td><td></td><td>@NiklasRosenstein</td></tr>
24
+ <tr><td>Improvement</td><td>
25
+
26
+ Fix deprecation warnings of using the `loguru.logger.opt(ansi)` keyword argument and use the new `colors` kwarg instead</td><td></td><td></td><td>@NiklasRosenstein</td></tr>
27
+ <tr><td>Feature</td><td>
28
+
29
+ Add `PostProcessor.spec.kyvernoRules` field as a shorthand for defining Kyverno policies in a Nyl manifest.</td><td></td><td></td><td>@NiklasRosenstein</td></tr>
30
+ <tr><td>Refactor</td><td>
31
+
32
+ Refactor `PostProcessor` implementation for generating policy files and invoking Kyverno</td><td></td><td></td><td>@NiklasRosenstein</td></tr>
33
+ <tr><td>Improvement</td><td>
34
+
35
+ `PostProcessor` log for invoking Kyverno now lists the policy file paths that are going to be applied</td><td></td><td></td><td>@NiklasRosenstein</td></tr>
36
+ <tr><td>Fix</td><td>
37
+
38
+ `nyl new chart` now generates 2-space indented YAML and has a more complete template</td><td></td><td><a href="https://github.com/NiklasRosenstein/nyl/issues/47">47</a></td><td>@NiklasRosenstein</td></tr>
39
+ </table>
40
+
41
+ ## 0.6.0
42
+
43
+ * Upgraded `argocd-cmp-server` in `nyl/argocd-cmp` container image to `v2.13.1` (see [#46](https://github.com/helsing-ai/nyl/pull/46))
44
+ * Re-introduce `settings.generate_placeholders` in `nyl-project.toml`, but warn if it is used. Enabling the option will have the
45
+ same effect as setting `on_lookup_failure = "CreatePlaceholder"` and take precedence over the original value of `on_lookup_failure`.
46
+
47
+ ## 0.5.1
48
+
49
+ * Add Nix flake
50
+ * Docs: Add missing API docs for `nyl.secrets.kubernetes`
51
+
52
+ ## 0.5.0
53
+
54
+ * Add the [`KubernetesSecret`](./reference/configuration/secrets.md#provider-kubernetessecret) secret provider
55
+ * Add the `ntyl secrets set` and `nyl secrets unset` commands
56
+ * Breaking: Replace the `settings.generate_placeholders` option with `settings.on_lookup_failure`
57
+
58
+ ## 0.4.0
59
+
60
+ * Automatically replace the host in Kubeconfig `server` field if it is set to `localhost`, `0.0.0.0` or `127.0.0.1`
61
+ when a Kubeconfig is retrieved via SSH (saving you to configure `replace_apiserver_hostname` when sourcing a
62
+ Kubeconfig from a K3s/RKE2 cluster via SSH).
63
+ * Add `port` and `sudo` option to `KubeconfigFromSsh` config
64
+
65
+ ## 0.3.0
66
+
67
+ * Add [`PostProcessor`](./reference/templating/inlining/postprocessor.md) inline resource which supports applying
68
+ Kyverno policies to the generated resources.
69
+ * Fixed a bug in the construction of the local Helm chart path when referencing a Helm chart in a Git repository.
@@ -7,4 +7,4 @@ resources in a cluster. Nyl provides basic support for ApplySets, allowing you t
7
7
  and prune resources as they are removed from your configuration.
8
8
 
9
9
  Note that ApplySet support is experimental and has still has various issues. You can following the progress of the
10
- feature in the [nyl#5](https://github.com/NiklasRosenstein/nyl/issues/5).
10
+ feature in the [nyl#5](https://github.com/helsing-ai/nyl/issues/5).
@@ -16,7 +16,7 @@ We recommend the following configuration:
16
16
  repoServer:
17
17
  extraContainers:
18
18
  - name: nyl-v1
19
- image: ghcr.io/niklasrosenstein/nyl/argocd-cmp:{{ NYL_VERSION }}
19
+ image: ghcr.io/helsing-ai/nyl/argocd-cmp:{{ NYL_VERSION }}
20
20
  securityContext:
21
21
  runAsNonRoot: true
22
22
  runAsUser: 999
@@ -52,6 +52,9 @@ application, you would need to create a Helm chart that includes all the other c
52
52
  complicated setup that is hard to maintain: It either requires you to repeat the same values in multiple places, or
53
53
  all subcharts support `globals`.
54
54
 
55
+ The `HelmChart` generator populates its own Kubernetes namespace to that of its generated resources that lack a
56
+ namespace.
57
+
55
58
  #### Secret injection
56
59
 
57
60
  Natively, ArgoCD applications do not support injecting secrets into the Helm chart values. With Nyl, you can connect
@@ -6,14 +6,21 @@ not accept a `metadata` field.
6
6
 
7
7
  ## Prerequisites
8
8
 
9
- * You need the [`kyverno` CLI](https://kyverno.io/docs/kyverno-cli/) installed
9
+ You need the [`kyverno` CLI](https://kyverno.io/docs/kyverno-cli/) >1.13.x installed
10
+
11
+ !!! danger
12
+ In Kyverno 1.12.6, the `kyverno apply` command with the `-o` option outputs only the mutated resources. In
13
+ Kyverno 1.13.2, all resources are outputted. Nyl relies on the latter behavior.
10
14
 
11
15
  ## API Spec
12
16
 
13
17
  ```yaml
14
18
  apiVersion: inline.nyl.io/v1
15
19
  kind: PostProcessor
20
+ metadata:
21
+ name: my-post-processor
16
22
  spec:
23
+ # Configure Kyverno policies to apply.
17
24
  kyverno:
18
25
  # A list of files that each contain a Kyverno policy resource, usually a `ClusterPolicy`. The paths are first
19
26
  # considered relative to the manifest that this resource is defined in, and will then be searched in the project
@@ -29,7 +36,36 @@ spec:
29
36
  kind: ClusterPolicy
30
37
  metadata:
31
38
  name: enforce-pod-security-context
32
- spec: {} # ...
39
+ spec:
40
+ rules:
41
+ - name: my-rule
42
+ match:
43
+ resources:
44
+ kinds:
45
+ - Pod
46
+ validate:
47
+ message: "Pod must have security context"
48
+ pattern:
49
+ spec:
50
+ securityContext:
51
+ runAsNonRoot: true
52
+
53
+ # Define rules for a single Kyverno `ClusterPolicy` to apply. The `name` field of the rule configuration may be
54
+ # ommited. Applies after policies defined in `kyverno`.
55
+ #
56
+ # To find more about Kyverno policies and rules, read https://kyverno.io/docs/writing-policies/.
57
+ kyvernoRules:
58
+ - match:
59
+ resources:
60
+ kinds:
61
+ - Service
62
+ mutate:
63
+ patchStrategicMerge:
64
+ spec:
65
+ (type): LoadBalancer
66
+ allocateLoadBalancerNodePorts: false
67
+ loadBalancerClass: ngrok
68
+
33
69
  ```
34
70
 
35
71
  ## Example
@@ -108,6 +108,6 @@
108
108
  '';
109
109
 
110
110
  devShells.default =
111
- pkgs.mkShell { buildInputs = [ uvProject.venv.dev ]; };
111
+ pkgs.mkShell { buildInputs = [ uvProject.venv.dev ] ++ dependencies; };
112
112
  });
113
113
  }
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "nyl"
7
- version = "0.6.0" # sed'ed on publish in CI
7
+ version = "0.7.0"
8
8
  description = "Advanced templating engine for Kubernetes and GitOps."
9
9
  authors = [
10
10
  {name = "Niklas Rosenstein", email = "rosensteinniklas@gmail.com"},
@@ -40,3 +40,22 @@ dev-dependencies = [
40
40
  "types-pyyaml>=6.0.12.20240311",
41
41
  "types-requests>=2.32.0.20240712",
42
42
  ]
43
+
44
+ [tool.mypy]
45
+ explicit_package_bases = true
46
+ namespace_packages = true
47
+ show_column_numbers = true
48
+ strict = true
49
+ mypy_path = ["src"]
50
+
51
+ [tool.ruff]
52
+ line-length = 120
53
+
54
+ [tool.slap.test]
55
+ pytest = "uv run pytest ."
56
+ mypy = "uv run mypy ."
57
+ ruff-check = "uv run ruff check ."
58
+ ruff-fmt = "uv run ruff format --check ."
59
+
60
+ [tool.slap.run]
61
+ fmt = "uv run ruff format . && uv run ruff check --fix ."
@@ -79,7 +79,7 @@ def _callback(
79
79
  logger.add(sys.stderr, level=LogLevel.ERROR.name if quiet else log_level.name, format=fmt)
80
80
  if log_file:
81
81
  logger.add(log_file, level=log_level.name, format=fmt)
82
- logger.opt(ansi=True).debug("Nyl v{} run from <yellow>{}</>.", __version__, Path.cwd())
82
+ logger.opt(colors=True).debug("Nyl v{} run from <yellow>{}</>.", __version__, Path.cwd())
83
83
 
84
84
  # Log some helpful information for debugging purposes.
85
85
  logger.debug("Used command-line arguments: {}", lazy_str(pretty_cmd, sys.argv))
@@ -52,7 +52,11 @@ def chart(dir: Path) -> None:
52
52
  dir,
53
53
  "values.yaml",
54
54
  """
55
- image: my/image:tag
55
+ image:
56
+ repository: my/image
57
+ tag: 1.0.0
58
+ pullPolicy: IfNotPresent
59
+ pullSecret: ""
56
60
  """,
57
61
  )
58
62
 
@@ -82,20 +86,25 @@ def chart(dir: Path) -> None:
82
86
  apiVersion: apps/v1
83
87
  kind: Deployment
84
88
  metadata:
85
- name: {{ .Release.Name }}
89
+ name: {{ .Release.Name }}
86
90
  spec:
87
- replicas: 1
88
- selector:
91
+ replicas: 1
92
+ selector:
89
93
  matchLabels:
90
- app: {{ .Release.Name }}
91
- template:
94
+ app.kubernetes.io/name: {{ .Release.Name }}
95
+ template:
92
96
  metadata:
93
- labels:
94
- app: {{ .Release.Name }}
97
+ labels:
98
+ app.kubernetes.io/name: {{ .Release.Name }}
95
99
  spec:
96
- containers:
97
- - name: {{ .Release.Name }}
98
- image: {{ .Values.image }}
100
+ {{- if .Values.image.pullSecret }}
101
+ imagePullSecrets:
102
+ - name: {{ .Values.image.pullSecret }}
103
+ {{- end }}
104
+ containers:
105
+ - name: {{ .Release.Name }}
106
+ image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
107
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
99
108
  """,
100
109
  )
101
110
 
@@ -54,7 +54,7 @@ def run(
54
54
  # Check if the context exists in the kubeconfig.
55
55
  kubeconfig = Path(os.environ.get("KUBECONFIG", "~/.kube/config")).expanduser()
56
56
  if not kubeconfig.is_file():
57
- logger.opt(ansi=True).info("Profile <yellow>{}</> not found.", profile_name)
57
+ logger.opt(colors=True).info("Profile <yellow>{}</> not found.", profile_name)
58
58
  sys.exit(1)
59
59
 
60
60
  try:
@@ -62,11 +62,11 @@ def run(
62
62
  kubeconfig_data = _trim_to_context(kubeconfig_data, profile_name)
63
63
  except ValueError:
64
64
  logger.debug("Failed to parse the kubeconfig file/find context '{}'.", profile_name)
65
- logger.opt(ansi=True).info("Profile <yellow>{}</> not found.", profile_name)
65
+ logger.opt(colors=True).info("Profile <yellow>{}</> not found.", profile_name)
66
66
  sys.exit(1)
67
67
  else:
68
68
  if not inherit_kubeconfig:
69
- logger.opt(ansi=True).error(
69
+ logger.opt(colors=True).error(
70
70
  "Found context <yellow>{}</> in the kubeconfig ({}), but no Nyl profile with that name. "
71
71
  "Consider using --inherit-kubeconfig,-I to run the command in that Kubernetes context.",
72
72
  profile_name,
@@ -74,7 +74,7 @@ def run(
74
74
  )
75
75
  sys.exit(1)
76
76
 
77
- logger.opt(ansi=True).info(
77
+ logger.opt(colors=True).info(
78
78
  "Falling back to context <yellow>{}</> from the kubeconfig ({}) due to --inherit-kubeconfig,-I option.",
79
79
  profile_name,
80
80
  kubeconfig,
@@ -89,7 +89,7 @@ def run(
89
89
  kubeconfig.chmod(0o600)
90
90
 
91
91
  profile = ActivatedProfile(kubeconfig)
92
- logger.opt(ansi=True).info(
92
+ logger.opt(colors=True).info(
93
93
  "Running command `<blue>{}</>` with {} <yellow>{}</>.",
94
94
  lazy_str(pretty_cmd, command),
95
95
  kind,