From 1f87cdbf0885f8c131652f7a0318b2cef4f63eb6 Mon Sep 17 00:00:00 2001 From: Stefan Koelle <50440224+skoelle@users.noreply.github.com> Date: Sun, 9 Aug 2026 13:49:38 +0200 Subject: [PATCH] Add pure template-resolution logic (kctl.ResolveTemplate) with unit tests --- internal/kctl/template.go | 16 +++++++++++++ internal/kctl/template_test.go | 41 ++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 internal/kctl/template.go create mode 100644 internal/kctl/template_test.go diff --git a/internal/kctl/template.go b/internal/kctl/template.go new file mode 100644 index 0000000..c2fb4f5 --- /dev/null +++ b/internal/kctl/template.go @@ -0,0 +1,16 @@ +package kctl + +import "strings" + +// ResolveTemplate replaces "{key}" placeholders in template with the +// corresponding value from values. Placeholders with no matching key are +// left untouched, so a misconfigured template is visible (e.g. a literal +// "{typo}" in the result) instead of silently collapsing to an empty +// string. +func ResolveTemplate(template string, values map[string]string) string { + result := template + for k, v := range values { + result = strings.ReplaceAll(result, "{"+k+"}", v) + } + return result +} diff --git a/internal/kctl/template_test.go b/internal/kctl/template_test.go new file mode 100644 index 0000000..1e5f3ae --- /dev/null +++ b/internal/kctl/template_test.go @@ -0,0 +1,41 @@ +package kctl + +import "testing" + +func TestResolveTemplate_SinglePlaceholder(t *testing.T) { + got := ResolveTemplate("secret-{namespace}", map[string]string{"namespace": "example-ns"}) + want := "secret-example-ns" + if got != want { + t.Fatalf("got %q, want %q", got, want) + } +} + +func TestResolveTemplate_MultiplePlaceholders(t *testing.T) { + template := "arn:aws:eks:{region}:{account_id}:cluster/tf-{env}-{context}-1" + values := map[string]string{ + "region": "eu-central-1", + "account_id": "123456789012", + "env": "beta", + "context": "internal", + } + got := ResolveTemplate(template, values) + want := "arn:aws:eks:eu-central-1:123456789012:cluster/tf-beta-internal-1" + if got != want { + t.Fatalf("got %q, want %q", got, want) + } +} + +func TestResolveTemplate_UnknownPlaceholderLeftAsIs(t *testing.T) { + got := ResolveTemplate("secret-{unknown}", map[string]string{"namespace": "example-ns"}) + want := "secret-{unknown}" + if got != want { + t.Fatalf("got %q, want %q", got, want) + } +} + +func TestResolveTemplate_EmptyTemplate(t *testing.T) { + got := ResolveTemplate("", map[string]string{"namespace": "example-ns"}) + if got != "" { + t.Fatalf("expected empty result, got %q", got) + } +}