Skip to content

Commit 1a87bc4

Browse files
committed
kustomize generator: fix handling of templateSuffix, and add missing auto-generation of kustomization.yaml
1 parent 7d3253f commit 1a87bc4

File tree

2 files changed

+95
-26
lines changed

2 files changed

+95
-26
lines changed

pkg/manifests/kustomize.go

Lines changed: 94 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,19 @@ import (
1212
"io/fs"
1313
"os"
1414
"path/filepath"
15+
"strings"
1516
"text/template"
1617

1718
"github.com/Masterminds/sprig/v3"
1819

1920
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
2021
utilyaml "k8s.io/apimachinery/pkg/util/yaml"
2122
"sigs.k8s.io/controller-runtime/pkg/client"
23+
"sigs.k8s.io/kustomize/api/konfig"
2224
"sigs.k8s.io/kustomize/api/krusty"
2325
kustypes "sigs.k8s.io/kustomize/api/types"
2426
kustfsys "sigs.k8s.io/kustomize/kyaml/filesys"
27+
kyaml "sigs.k8s.io/yaml"
2528

2629
"github.com/sap/component-operator-runtime/internal/templatex"
2730
"github.com/sap/component-operator-runtime/pkg/cluster"
@@ -31,7 +34,8 @@ import (
3134
// KustomizeGenerator is a Generator implementation that basically renders a given Kustomization.
3235
type KustomizeGenerator struct {
3336
kustomizer *krusty.Kustomizer
34-
templates []*template.Template
37+
files map[string][]byte
38+
templates map[string]*template.Template
3539
}
3640

3741
var _ Generator = &KustomizeGenerator{}
@@ -40,7 +44,10 @@ var _ Generator = &KustomizeGenerator{}
4044
// Deprecation warning: the parameter client is ignored (can be passed as nil) and will be removed in a future release;
4145
// the according value will be retrieved from the context passed to Generate().
4246
func NewKustomizeGenerator(fsys fs.FS, kustomizationPath string, templateSuffix string, client client.Client) (*KustomizeGenerator, error) {
43-
g := KustomizeGenerator{}
47+
g := KustomizeGenerator{
48+
files: make(map[string][]byte),
49+
templates: make(map[string]*template.Template),
50+
}
4451

4552
if fsys == nil {
4653
fsys = os.DirFS("/")
@@ -58,7 +65,7 @@ func NewKustomizeGenerator(fsys fs.FS, kustomizationPath string, templateSuffix
5865
g.kustomizer = krusty.MakeKustomizer(options)
5966

6067
var t *template.Template
61-
files, err := find(fsys, kustomizationPath, "*"+templateSuffix, fileTypeRegular, 0)
68+
files, err := find(fsys, kustomizationPath, "*", fileTypeRegular, 0)
6269
if err != nil {
6370
return nil, err
6471
}
@@ -74,23 +81,29 @@ func NewKustomizeGenerator(fsys fs.FS, kustomizationPath string, templateSuffix
7481
// TODO: is it ok to panic here in case of error ?
7582
panic("this cannot happen")
7683
}
77-
if t == nil {
78-
t = template.New(name)
79-
t.Option("missingkey=zero").
80-
Funcs(sprig.TxtFuncMap()).
81-
Funcs(templatex.FuncMap()).
82-
Funcs(templatex.FuncMapForTemplate(t)).
83-
Funcs(templatex.FuncMapForClient(nil)).
84-
Funcs(funcMapForGenerateContext(nil, "", ""))
84+
if strings.HasSuffix(name, templateSuffix) {
85+
if t == nil {
86+
t = template.New(name)
87+
t.Option("missingkey=zero").
88+
Funcs(sprig.TxtFuncMap()).
89+
Funcs(templatex.FuncMap()).
90+
Funcs(templatex.FuncMapForTemplate(t)).
91+
Funcs(templatex.FuncMapForClient(nil)).
92+
Funcs(funcMapForGenerateContext(nil, "", ""))
93+
} else {
94+
t = t.New(name)
95+
}
96+
if _, err := t.Parse(string(raw)); err != nil {
97+
return nil, err
98+
}
99+
g.templates[strings.TrimSuffix(name, templateSuffix)] = t
85100
} else {
86-
t = t.New(name)
87-
}
88-
if _, err := t.Parse(string(raw)); err != nil {
89-
return nil, err
101+
g.files[name] = raw
90102
}
91-
g.templates = append(g.templates, t)
92103
}
93104

105+
// TODO: check that g.files and g.templates are disjoint
106+
94107
return &g, nil
95108
}
96109

@@ -136,22 +149,45 @@ func (g *KustomizeGenerator) Generate(ctx context.Context, namespace string, nam
136149
data := parameters.ToUnstructured()
137150
fsys := kustfsys.MakeFsInMemory()
138151

139-
var t0 *template.Template
140-
if len(g.templates) > 0 {
141-
t0, err = g.templates[0].Clone()
142-
if err != nil {
152+
for n, f := range g.files {
153+
if err := fsys.WriteFile(n, f); err != nil {
143154
return nil, err
144155
}
145-
t0.Option("missingkey=zero").
146-
Funcs(templatex.FuncMapForClient(client)).
147-
Funcs(funcMapForGenerateContext(client, namespace, name))
148156
}
149-
for _, t := range g.templates {
157+
158+
var t0 *template.Template
159+
for n, t := range g.templates {
160+
if t0 == nil {
161+
t0, err = t.Clone()
162+
if err != nil {
163+
return nil, err
164+
}
165+
t0.Option("missingkey=zero").
166+
Funcs(templatex.FuncMapForClient(client)).
167+
Funcs(funcMapForGenerateContext(client, namespace, name))
168+
}
150169
var buf bytes.Buffer
151170
if err := t0.ExecuteTemplate(&buf, t.Name(), data); err != nil {
152171
return nil, err
153172
}
154-
if err := fsys.WriteFile(t.Name(), buf.Bytes()); err != nil {
173+
if err := fsys.WriteFile(n, buf.Bytes()); err != nil {
174+
return nil, err
175+
}
176+
}
177+
178+
haveKustomization := false
179+
for _, kustomizationName := range konfig.RecognizedKustomizationFileNames() {
180+
if fsys.Exists(kustomizationName) {
181+
haveKustomization = true
182+
break
183+
}
184+
}
185+
if !haveKustomization {
186+
kustomization, err := generateKustomization(fsys)
187+
if err != nil {
188+
return nil, err
189+
}
190+
if err := fsys.WriteFile(konfig.DefaultKustomizationFileName(), kustomization); err != nil {
155191
return nil, err
156192
}
157193
}
@@ -191,3 +227,36 @@ func funcMapForGenerateContext(client cluster.Client, namespace string, name str
191227
"name": func() string { return name },
192228
}
193229
}
230+
231+
func generateKustomization(fsys kustfsys.FileSystem) ([]byte, error) {
232+
var resources []string
233+
234+
f := func(path string, info fs.FileInfo, err error) error {
235+
if err != nil {
236+
return err
237+
}
238+
if !info.IsDir() && (strings.HasSuffix(path, ".yaml") || strings.HasSuffix(path, ".yml")) {
239+
resources = append(resources, path)
240+
}
241+
return nil
242+
}
243+
244+
if err := fsys.Walk(".", f); err != nil {
245+
return nil, err
246+
}
247+
248+
kustomization := kustypes.Kustomization{
249+
TypeMeta: kustypes.TypeMeta{
250+
APIVersion: kustypes.KustomizationVersion,
251+
Kind: kustypes.KustomizationKind,
252+
},
253+
Resources: resources,
254+
}
255+
256+
rawKustomization, err := kyaml.Marshal(kustomization)
257+
if err != nil {
258+
return nil, err
259+
}
260+
261+
return rawKustomization, nil
262+
}

website/content/en/docs/generators/kustomize.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ This generator allows to generate the manifests of the component's resources fro
1111
As a special case, one or more simple Kubernetes manifests (without a `kustomization.yaml`) are supported as well.
1212
In addition, all (or selected; see below) files in the kustomization directory can be templatized in a helm'ish way.
1313
That means, they will be considered as a common template group (where all templates are associated with each other),
14-
and the same template function set that is available on helm can be used; so, all the [sprig](http://masterminds.github.io/sprig) functions, and custom functions such as `include`, `tpl`, `lookup` can be used.
14+
and the same template function set that is available on helm can be used; so, all the [sprig](http://masterminds.github.io/sprig) functions, and custom functions such as `include`, `tpl`, `lookup` can be used. In addition, parameterless functions `namespace` and `name` are defined, which return the corresponding arguments passed to `Generate()`.
1515

1616
In the generation step, first, all the go templates will be rendered, and the result of this pre-step will be passed to kustomize.
1717

0 commit comments

Comments
 (0)