kubernetes_template_rendering 0.6.2 → 0.7.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +37 -0
- data/lib/kubernetes_template_rendering/cli.rb +20 -4
- data/lib/kubernetes_template_rendering/template.rb +2 -1
- data/lib/kubernetes_template_rendering/variable_override_parser.rb +79 -0
- data/lib/kubernetes_template_rendering/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2834614aaa2465ab9be3a1c50b6c2d2a1b1f4264ecadafddcb5bf8365c5bb151
|
|
4
|
+
data.tar.gz: 6142bd0df1d9da48f1058409017f2080082deb81d13b4c02b4dce2bef2ed80ef
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bd84f186eda857691bb2825188bcabb8dfc8af8e9c9054623263d72db981d3bba853177f31fd63de4a57f6b982ead442724515a54cc2c42b0454c41c0a9aff6f
|
|
7
|
+
data.tar.gz: 8aa7fac766cd4f19e6994a1a51a68bbaf09db56384ae979d403ee4f795a6d7d78a0d9fc4211330d620253033a730306a7eb3d0541995a6436ecfe150a720320e
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,15 @@ Inspired by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
|
4
4
|
|
|
5
5
|
Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.7.0] - 2026-07-23
|
|
8
|
+
### Added
|
|
9
|
+
- `--variable-override` now supports dotted-path keys (`components.webServer.hpa.minReplicas:2`) that deep-merge into nested variables, with JSON value coercion (integers, floats, booleans, `null`, quoted strings; non-JSON values stay raw strings) and `\.` escaping for literal dots. Plain `KEY:VALUE` (no dot) behaves exactly as before: top-level key, raw string value.
|
|
10
|
+
- Added `--variable-override-json '<json object>'` (repeatable), deep-merged with all other override flags in command-line order (later flags win). Use it for values containing commas or whole structures.
|
|
11
|
+
- Overrides are echoed once to stdout at render start (`Variable overrides (deep-merged after definitions.yaml): {...}`). Rendered files still carry no override comment (see 0.3.0).
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- `Template#initialize` merges `variable_overrides` with `deep_merge` instead of `merge`. Behavior-identical for all previously-valid inputs (legacy override values are always strings, so no hash-vs-hash merge could occur).
|
|
15
|
+
|
|
7
16
|
## [0.6.2] - 2026-07-15
|
|
8
17
|
### Fixed
|
|
9
18
|
- Fixed the `--reconcile` sweep root for entries whose `subdirectory:` nests more than one level deep (e.g. `subdirectory: exclude-argocd/auth`). The sweep root is now the entry's canonical base — `<region>/<cluster_type>/<color>` for non-SPP entries and `<region>/<cluster_type>/<color>/spp/SPP-PLACEHOLDER` for SPP entries — regardless of `subdirectory:` depth, rather than the immediate parent of the rendered output directory. Previously a nested `subdirectory:` pushed the sweep root one level too deep, so when a `subdirectory:` was renamed or nested deeper the files left at the old shallower path were siblings of the sweep root and were never swept.
|
data/README.md
CHANGED
|
@@ -71,6 +71,43 @@ Useful when one `--cluster_type` matches multiple sibling entries (e.g. `staging
|
|
|
71
71
|
|
|
72
72
|
If an `--only` value matches no entry across any template directory, the gem raises with the list of valid keys so the caller can self-correct.
|
|
73
73
|
|
|
74
|
+
### Variable overrides
|
|
75
|
+
|
|
76
|
+
Pass `--variable-override KEY:VALUE` (repeatable) to override values from `definitions.yaml` after all per-section variables and auto-injected region/cluster vars are resolved. Overrides always win.
|
|
77
|
+
|
|
78
|
+
**Legacy form (no dot in KEY):** sets a top-level key to the raw string value — exactly the pre-0.7.0 behavior. Values are never type-coerced (`deploySha:12345` stays the string `"12345"`; `enabled:true` stays `"true"`). The value is everything after the first colon (`image:registry:5000/app` → `"registry:5000/app"`). Arguments with no colon are silently ignored.
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
gem exec -g kubernetes_template_rendering render_templates \
|
|
82
|
+
--rendered-directory path/to/resources \
|
|
83
|
+
--variable-override deploySha:abc123 \
|
|
84
|
+
deployment/templates
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Dotted-path form (KEY contains `.`):** the key is split on unescaped dots into a nested path and deep-merged into variables. The value is JSON-coerced when it parses as JSON (`2` → integer, `true`/`false` → booleans, `null` → nil, `"2"` → string); otherwise the raw string is kept (`hello` → `"hello"`, `02` → `"02"`).
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
gem exec -g kubernetes_template_rendering render_templates \
|
|
91
|
+
--rendered-directory path/to/resources \
|
|
92
|
+
--variable-override components.webServer.hpa.minReplicas:2 \
|
|
93
|
+
deployment/templates
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Escape literal dots in a segment with `\.` (e.g. `metadata.labels.app\.kubernetes\.io/name:foo`). Only `\.` is an escape sequence; all other backslashes — including trailing ones — are kept literally. Keys that would need a literal backslash immediately before a path-splitting dot must use `--variable-override-json` instead.
|
|
97
|
+
|
|
98
|
+
**`--variable-override-json` (repeatable):** deep-merges a JSON object. Use this for values containing commas or whole arrays/objects (the legacy Array acceptor comma-splits `KEY:VALUE` arguments).
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
gem exec -g kubernetes_template_rendering render_templates \
|
|
102
|
+
--rendered-directory path/to/resources \
|
|
103
|
+
--variable-override-json '{"ephemeral":{"mysql":{"enabled":true}}}' \
|
|
104
|
+
deployment/templates
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Precedence:** all override flags are folded into one hash in command-line order via deep merge (later flags win on conflict), then deep-merged last over the fully-resolved variables.
|
|
108
|
+
|
|
109
|
+
Overrides are echoed once to stdout at render start (`Variable overrides (deep-merged after definitions.yaml): {...}`). Rendered files carry no override comment (removed in [0.3.0](CHANGELOG.md#030---2026-06-24) to avoid content-free diffs on every deploy).
|
|
110
|
+
|
|
74
111
|
### Staging Partial Platforms
|
|
75
112
|
|
|
76
113
|
Pass `--spp NAME` (repeatable) to expand any entry whose `definitions.yaml` name contains `SPP-PLACEHOLDER` into a per-SPP sibling output. Substitutes `SPP-PLACEHOLDER` with `NAME` and the `PLACEHOLDER` suffix with the suffix of `NAME` (everything after the last `-`), in both file paths and contents. Source mtimes are preserved.
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
3
5
|
require_relative "template_directory_renderer"
|
|
4
6
|
require_relative "cli_arguments"
|
|
7
|
+
require_relative "variable_override_parser"
|
|
5
8
|
|
|
6
9
|
module KubernetesTemplateRendering
|
|
7
10
|
class CLI
|
|
@@ -43,21 +46,30 @@ module KubernetesTemplateRendering
|
|
|
43
46
|
args.only << name
|
|
44
47
|
end
|
|
45
48
|
|
|
46
|
-
op.on("--variable-override=KEY:VALUE", "override a variable value set within definitions.yaml", Array) do |overrides|
|
|
49
|
+
op.on("--variable-override=KEY:VALUE", "override a variable value set within definitions.yaml (KEY may be a dotted path, e.g. components.webServer.hpa.minReplicas:2; escape literal dots as \\.)", Array) do |overrides|
|
|
47
50
|
args.variable_overrides ||= {} # Initialize as a Hash
|
|
48
51
|
overrides.each do |override|
|
|
49
|
-
|
|
50
|
-
args.variable_overrides[key] = value if key && value
|
|
52
|
+
VariableOverrideParser.merge_override!(args.variable_overrides, override)
|
|
51
53
|
end
|
|
52
54
|
end
|
|
53
55
|
|
|
56
|
+
op.on("--variable-override-json=JSON", "deep-merge a JSON object of variable overrides (repeatable; later flags win)") do |json|
|
|
57
|
+
args.variable_overrides ||= {}
|
|
58
|
+
VariableOverrideParser.merge_json!(args.variable_overrides, json)
|
|
59
|
+
end
|
|
60
|
+
|
|
54
61
|
op.on("-h", "--help") do
|
|
55
62
|
puts op
|
|
56
63
|
exit
|
|
57
64
|
end
|
|
58
65
|
end
|
|
59
66
|
|
|
60
|
-
|
|
67
|
+
begin
|
|
68
|
+
parser.parse!(options)
|
|
69
|
+
rescue VariableOverrideParser::ParseError => ex
|
|
70
|
+
STDERR.puts(ex.message)
|
|
71
|
+
exit(1)
|
|
72
|
+
end
|
|
61
73
|
args.template_directory = options.first
|
|
62
74
|
args.spps = (args.spps || []).uniq
|
|
63
75
|
args.only = (args.only || []).uniq
|
|
@@ -80,6 +92,10 @@ module KubernetesTemplateRendering
|
|
|
80
92
|
exit(1)
|
|
81
93
|
end
|
|
82
94
|
|
|
95
|
+
if args.variable_overrides&.any?
|
|
96
|
+
puts "Variable overrides (deep-merged after definitions.yaml): #{JSON.generate(args.variable_overrides)}"
|
|
97
|
+
end
|
|
98
|
+
|
|
83
99
|
[renderer_from_args(args), args]
|
|
84
100
|
end
|
|
85
101
|
|
|
@@ -4,6 +4,7 @@ require "ostruct"
|
|
|
4
4
|
require "open3"
|
|
5
5
|
require "shellwords"
|
|
6
6
|
require "yaml"
|
|
7
|
+
require "active_support/core_ext/hash/deep_merge"
|
|
7
8
|
|
|
8
9
|
# This is a base class for all Templates. Derived classes must implement the render method.
|
|
9
10
|
module KubernetesTemplateRendering
|
|
@@ -12,7 +13,7 @@ module KubernetesTemplateRendering
|
|
|
12
13
|
|
|
13
14
|
def initialize(template_path, variables, source_repo: nil, variable_overrides: {})
|
|
14
15
|
@template_path = template_path
|
|
15
|
-
@variables = variables.
|
|
16
|
+
@variables = variables.deep_merge(variable_overrides)
|
|
16
17
|
@source_repo = source_repo
|
|
17
18
|
@variable_overrides = variable_overrides
|
|
18
19
|
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "active_support/core_ext/hash/deep_merge"
|
|
5
|
+
|
|
6
|
+
module KubernetesTemplateRendering
|
|
7
|
+
# Parses --variable-override / --variable-override-json values into (possibly nested)
|
|
8
|
+
# override fragments and deep-merges them, in command-line order, into one overrides hash.
|
|
9
|
+
#
|
|
10
|
+
# Key forms:
|
|
11
|
+
# * Legacy: KEY contains no "." -> top-level key, value kept as the raw string
|
|
12
|
+
# (exactly the pre-0.7.0 behavior; never type-coerced).
|
|
13
|
+
# * Dotted: KEY contains "." -> split on unescaped dots into a nested path ("\." is a
|
|
14
|
+
# literal dot within a segment). The value is JSON-coerced when it parses as JSON
|
|
15
|
+
# (2 -> Integer, true/false -> booleans, null -> nil, "2" -> String), else kept raw.
|
|
16
|
+
class VariableOverrideParser
|
|
17
|
+
class ParseError < StandardError; end
|
|
18
|
+
|
|
19
|
+
UNESCAPED_DOT = /(?<!\\)\./.freeze
|
|
20
|
+
|
|
21
|
+
class << self
|
|
22
|
+
# Deep-merges a KEY:VALUE override fragment into +overrides+.
|
|
23
|
+
#
|
|
24
|
+
# @param overrides [Hash] accumulated overrides hash (mutated in place)
|
|
25
|
+
# @param raw [String] raw KEY:VALUE argument
|
|
26
|
+
# @return [Hash] +overrides+ after merging
|
|
27
|
+
def merge_override!(overrides, raw)
|
|
28
|
+
key, value = raw.split(":", 2)
|
|
29
|
+
return overrides if key.nil? || value.nil? # preserve legacy silent-skip of colon-less args
|
|
30
|
+
|
|
31
|
+
overrides.deep_merge!(fragment_for(key, value))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Deep-merges a JSON object string into +overrides+.
|
|
35
|
+
#
|
|
36
|
+
# @param overrides [Hash] accumulated overrides hash (mutated in place)
|
|
37
|
+
# @param json [String] JSON object string
|
|
38
|
+
# @return [Hash] +overrides+ after merging
|
|
39
|
+
# @raise [ParseError] when +json+ is invalid or not a JSON object
|
|
40
|
+
def merge_json!(overrides, json)
|
|
41
|
+
fragment =
|
|
42
|
+
begin
|
|
43
|
+
JSON.parse(json)
|
|
44
|
+
rescue JSON::ParserError => ex
|
|
45
|
+
raise ParseError, "--variable-override-json value is not valid JSON: #{ex.message}"
|
|
46
|
+
end
|
|
47
|
+
fragment.is_a?(Hash) or raise ParseError, "--variable-override-json value must be a JSON object, got #{fragment.class}: #{json.inspect}"
|
|
48
|
+
overrides.deep_merge!(fragment)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def fragment_for(key, value)
|
|
54
|
+
if key.include?(".")
|
|
55
|
+
nest(path_segments(key), coerce(value))
|
|
56
|
+
else
|
|
57
|
+
{ key => value } # legacy: literal key, raw string value
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def path_segments(key)
|
|
62
|
+
segments = key.split(UNESCAPED_DOT, -1)
|
|
63
|
+
segments.none?(&:empty?) or
|
|
64
|
+
raise ParseError, "--variable-override key #{key.inspect} has an empty path segment (leading, trailing, or doubled '.')"
|
|
65
|
+
segments.map { |segment| segment.gsub("\\.", ".") }
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def nest(segments, value)
|
|
69
|
+
segments.reverse.reduce(value) { |acc, segment| { segment => acc } }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def coerce(value)
|
|
73
|
+
JSON.parse(value)
|
|
74
|
+
rescue JSON::ParserError
|
|
75
|
+
value
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kubernetes_template_rendering
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Octothorpe
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-07-
|
|
11
|
+
date: 2026-07-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -101,6 +101,7 @@ files:
|
|
|
101
101
|
- lib/kubernetes_template_rendering/resource_set.rb
|
|
102
102
|
- lib/kubernetes_template_rendering/template.rb
|
|
103
103
|
- lib/kubernetes_template_rendering/template_directory_renderer.rb
|
|
104
|
+
- lib/kubernetes_template_rendering/variable_override_parser.rb
|
|
104
105
|
- lib/kubernetes_template_rendering/version.rb
|
|
105
106
|
- mkdocs.yml
|
|
106
107
|
- sig/kubernetes_template_rendering.rbs
|