mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
Merge pull request #3282 from pwittrock/main
Fn framework utilities for parsing templates from directories
This commit is contained in:
@@ -1,12 +0,0 @@
|
||||
# Copyright 2019 The Kubernetes Authors.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
FROM golang:1.13-stretch
|
||||
ENV CGO_ENABLED=0
|
||||
WORKDIR /go/src/
|
||||
COPY . .
|
||||
RUN go build -v -o /usr/local/bin/function ./
|
||||
|
||||
FROM alpine:latest
|
||||
COPY --from=0 /usr/local/bin/function /usr/local/bin/function
|
||||
CMD ["function"]
|
||||
@@ -1,7 +1,6 @@
|
||||
# Copyright 2019 The Kubernetes Authors.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
apiVersion: example.com/v1alpha1
|
||||
kind: Example
|
||||
key: key
|
||||
value: value
|
||||
env:
|
||||
key: {{ .Key }}
|
||||
value: {{ .Value }}
|
||||
@@ -0,0 +1,5 @@
|
||||
# Copyright 2019 The Kubernetes Authors.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
spec:
|
||||
replicas: {{ .Replicas }}
|
||||
@@ -0,0 +1,14 @@
|
||||
# Copyright 2019 The Kubernetes Authors.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: foo
|
||||
namespace: bar
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: foo
|
||||
image: {{ .Image }}
|
||||
4
kyaml/fn/framework/example2/doc.go
Normal file
4
kyaml/fn/framework/example2/doc.go
Normal file
@@ -0,0 +1,4 @@
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package example2
|
||||
241
kyaml/fn/framework/example2/example_test.go
Normal file
241
kyaml/fn/framework/example2/example_test.go
Normal file
@@ -0,0 +1,241 @@
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//go:generate go run github.com/markbates/pkger/cmd/pkger -o fn/framework/example2
|
||||
package example2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/markbates/pkger"
|
||||
"github.com/stretchr/testify/require"
|
||||
"sigs.k8s.io/kustomize/kyaml/fn/framework"
|
||||
)
|
||||
|
||||
func TestTemplate(t *testing.T) {
|
||||
type API struct {
|
||||
Image string `json:"image" yaml:"image"`
|
||||
}
|
||||
|
||||
tpl, err := framework.TemplatesFromDir(pkger.Dir("/fn/framework/example2/data/templates"))(nil)
|
||||
require.NoError(t, err)
|
||||
cmd := framework.TemplateCommand{
|
||||
API: &API{},
|
||||
Templates: tpl,
|
||||
}.GetCommand()
|
||||
|
||||
var in, out bytes.Buffer
|
||||
cmd.SetIn(&in)
|
||||
cmd.SetOut(&out)
|
||||
|
||||
in.WriteString(`
|
||||
apiVersion: config.kubernetes.io/v1alpha1
|
||||
kind: ResourceList
|
||||
items:
|
||||
- apiVersion: v1
|
||||
kind: Service
|
||||
functionConfig:
|
||||
image: baz
|
||||
`)
|
||||
|
||||
require.NoError(t, cmd.Execute())
|
||||
require.Equal(t, strings.TrimSpace(`
|
||||
apiVersion: config.kubernetes.io/v1alpha1
|
||||
kind: ResourceList
|
||||
items:
|
||||
- apiVersion: v1
|
||||
kind: Service
|
||||
- apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: foo
|
||||
namespace: bar
|
||||
annotations:
|
||||
config.kubernetes.io/index: '0'
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: foo
|
||||
image: baz
|
||||
functionConfig:
|
||||
image: baz
|
||||
`), strings.TrimSpace(out.String()))
|
||||
}
|
||||
|
||||
func TestPatchTemplate(t *testing.T) {
|
||||
type API struct {
|
||||
Replicas int `json:"replicas" yaml:"replicas"`
|
||||
}
|
||||
|
||||
cmd := framework.TemplateCommand{
|
||||
API: &API{},
|
||||
PatchTemplatesFn: framework.PatchTemplatesFromDir(
|
||||
framework.PT{
|
||||
Dir: pkger.Dir("/fn/framework/example2/data/patches"),
|
||||
Selector: func() *framework.Selector {
|
||||
return &framework.Selector{Names: []string{"foo"}}
|
||||
},
|
||||
},
|
||||
),
|
||||
}.GetCommand()
|
||||
|
||||
var in, out bytes.Buffer
|
||||
cmd.SetIn(&in)
|
||||
cmd.SetOut(&out)
|
||||
|
||||
in.WriteString(`
|
||||
apiVersion: config.kubernetes.io/v1alpha1
|
||||
kind: ResourceList
|
||||
items:
|
||||
- apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: foo
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: foo
|
||||
image: baz
|
||||
- apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: bar
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: foo
|
||||
image: baz
|
||||
functionConfig:
|
||||
replicas: 5
|
||||
`)
|
||||
|
||||
require.NoError(t, cmd.Execute())
|
||||
require.Equal(t, strings.TrimSpace(`
|
||||
apiVersion: config.kubernetes.io/v1alpha1
|
||||
kind: ResourceList
|
||||
items:
|
||||
- apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: foo
|
||||
annotations:
|
||||
config.kubernetes.io/index: '0'
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: foo
|
||||
image: baz
|
||||
replicas: 5
|
||||
- apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: bar
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: foo
|
||||
image: baz
|
||||
functionConfig:
|
||||
replicas: 5
|
||||
`), strings.TrimSpace(out.String()))
|
||||
}
|
||||
|
||||
func TestContainerPatchTemplate(t *testing.T) {
|
||||
type API struct {
|
||||
Key string `json:"key" yaml:"key"`
|
||||
Value string `json:"value" yaml:"value"`
|
||||
}
|
||||
|
||||
cmd := framework.TemplateCommand{
|
||||
API: &API{},
|
||||
PatchContainerTemplatesFn: framework.ContainerPatchTemplatesFromDir(
|
||||
framework.CPT{
|
||||
Dir: pkger.Dir("/fn/framework/example2/data/container-patches"),
|
||||
Selector: func() *framework.Selector {
|
||||
return &framework.Selector{Names: []string{"foo"}}
|
||||
},
|
||||
},
|
||||
),
|
||||
}.GetCommand()
|
||||
|
||||
var in, out bytes.Buffer
|
||||
cmd.SetIn(&in)
|
||||
cmd.SetOut(&out)
|
||||
|
||||
in.WriteString(`
|
||||
apiVersion: config.kubernetes.io/v1alpha1
|
||||
kind: ResourceList
|
||||
items:
|
||||
- apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: foo
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: a
|
||||
- name: b
|
||||
- name: c
|
||||
- apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: bar
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: foo
|
||||
image: baz
|
||||
functionConfig:
|
||||
key: Hello
|
||||
value: World
|
||||
`)
|
||||
|
||||
require.NoError(t, cmd.Execute())
|
||||
require.Equal(t, strings.TrimSpace(`
|
||||
apiVersion: config.kubernetes.io/v1alpha1
|
||||
kind: ResourceList
|
||||
items:
|
||||
- apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: foo
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: a
|
||||
env:
|
||||
key: Hello
|
||||
value: World
|
||||
- name: b
|
||||
env:
|
||||
key: Hello
|
||||
value: World
|
||||
- name: c
|
||||
env:
|
||||
key: Hello
|
||||
value: World
|
||||
- apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: bar
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: foo
|
||||
image: baz
|
||||
functionConfig:
|
||||
key: Hello
|
||||
value: World
|
||||
`), strings.TrimSpace(out.String()))
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"text/template"
|
||||
|
||||
"sigs.k8s.io/kustomize/kyaml/fn/framework"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type api struct {
|
||||
Key string `json:"key" yaml:"key"`
|
||||
Value string `json:"value" yaml:"value"`
|
||||
}
|
||||
cmd := framework.TemplateCommand{
|
||||
API: &api{},
|
||||
Template: template.Must(template.New("example").Parse(`
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: foo
|
||||
namespace: default
|
||||
annotations:
|
||||
{{ .Key }}: {{ .Value }}
|
||||
`)),
|
||||
}.GetCommand()
|
||||
if err := cmd.Execute(); err != nil {
|
||||
fmt.Fprintln(cmd.OutOrStderr(), err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
15
kyaml/fn/framework/example2/pkged.go
Normal file
15
kyaml/fn/framework/example2/pkged.go
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by pkger; DO NOT EDIT.
|
||||
|
||||
// +build !skippkger
|
||||
|
||||
package example2
|
||||
|
||||
import (
|
||||
"github.com/markbates/pkger"
|
||||
"github.com/markbates/pkger/pkging/mem"
|
||||
)
|
||||
|
||||
var _ = pkger.Apply(mem.UnmarshalEmbed([]byte(`1f8b08000000000000ffec996d73a23a1b80ff0a93cfac10de02cc9c0fa53d52dbd5b6da8a7a66a71320626a200e606dedf8df9f01aaf6d9ed0b9e63bb333b8e1f20e14ec29d848b6bf009d064cc33603f818c4659636a660dcaa5e93ccb794c97449a3ee29815974f680a6c20dd6424cda4d982e679ca83a91471294b03e9bdc62268c5339ee697389f00fbdd7144d0c131013658174f78006c708983298e8850d60a014f724c934c60d44f714a49268c792aa404873489049c84c222a579717e3ef7499a909c644297647c9e06a4683ea6d13cc539e5898033a1e8b40144708dd388e46f24399b465288d3054d6e711c1ada7b193730104197f337fa022268e33c9800fb1fd0003f44d0cb3123c0ced339792e7409ce78026c90f05ca0499663c64828f8f35cc0f79832ec3322d044f0e79485428083090122707993329215fd863c6844bce8bc9afb0cd8c99c31119c90d9e6fc9a64f9a6cdb6eaa7166d1ece8bdb7b02b516b08d69b2cee5bfec1997b779f8ef5a4b116fc43c2c3be99334a3e554c206d4c16ab512c1b8caf8dd2d6f4be3441aa738260b9e4e25f280e319238a14e21c4bcf3b90a4df66c542569d150f52710c498e292bab926a33ff1a2e828c2e09b02d4304310f09b015a821cdd4a006cb9adb9c964d155991bf41f84d31aea16ccb9aad180d03299aa919a6f94d366d590622a0d96d584c7535ebd96339f809b907363410428a02cb652445d94448041d469329b05511b4120e6c8874d544c5cddcd010d8ba0c45e016678a2c826e5874248be01287b741c46f6560ff238be5ef87088e8a3bcd662428c6ec150768c8860655d33045d0c98a1ad5b42c8854d35889a0fd76bcb18edf64b812c1f18ef10e4df3499d3650d6a0a959d64a04bdcd62388c07d3ac4cd761d36a9134b9b8d26438aa2eb824298fdfb3194e49797af57c5acccb8f728f4d487aa0e6819a7f0a3545302bd3780297d3a8ee76dc0da12b111457d613583c5049be1d71db6d793b7b43f7b6a6919378c6704e1a6be7a981f49f1aadc10e156d4d76ad80e8c748d7151569fa2f481f63967dc0745585a6b9613a7cc974136a7b663a5af3d34286ac2364edc0f42ac5fa4cdfc4d7663a5234649aa6b2617ab90e6ba89bbf1bead2983efc0cf6edbeae2e56ec7e09d62d16b70cac9e9167043eef91ff67e04bb255d107a67d35d3de64cb8675a0f5e89cf8aaa307314bf0e955d4be3b7ab8e83937d8bd897a6a9f8e0667f3d1a0cb8247c709075deeab67cbef11bf6b353b57dd66945fbbec6ee4e9cb510f9e8ddcfe3c74598cbdfee305759cc06dde61f7266f536d711ccd989f0c8d637a1461a5af5f500791c7a3794fe9ebad536815f561dccc42efc6689de6a875ac7b43ef018e7a8e35befaeb2ff06944aea5d0fb1167289b4851556bdfe26cee19b22f2455438aa1cbb521bbceb02e645fc4ef20cea66c58967610e783381fc4f9ab5f325fabcbeb175979dc45905f6bb09163a8ee24c750b610429aba67394696f589726c982a44667d6e5729d6e7f6267e176e1b4835e0568e8b7538c8f1418ebf905baf92e4b7e8f03270fb7717118f5aa7672c701f6643a5b95c6bf14ddc5ff82ebb1b0edad178207fa2feae67e20301de86fd47058610225545fb556053963f53817564587a6d943e67581ba5dbf8fa2885b20ed18bef0c07053e28f04181bfe855b265e1d748f0663c292433c61f77f1e0575bac11ae68e66e220c95f22fab7d7f252e98fd59226ca282af4a7d7a2beb7fe56ad27b13bf03bd2154745dded0bb5c8783081f44f84be9f53a4d7e8b0b4f029779a3c1d9127bd6fc823a93e0d4597e57870fc7713ef3e32ba3f577b770e47be241e62757e7bed797875e7712ba7f979f94fdb8998fae79348aadfb4d79d0590cbd0ebba00e1d0e5ae781eab0e1929fb78e1d79e4c185ef36e5d175513e8a5aa79dc5c86b977d9565b773ef27dd09f67416242fea8fe55fc6aaea8f22ecc1c948d97cbe3ef3bd66527dbee61ffa7bf5d89283761db4eb4f01d7ea7f000000ffff010000ffff631c0417dc270000`)))
|
||||
@@ -283,6 +283,9 @@ type TemplateCommand struct {
|
||||
// Templates is a list of templates to render.
|
||||
Templates []*template.Template
|
||||
|
||||
// TemplatesFn returns a list of templates
|
||||
TemplatesFn func(*ResourceList) ([]*template.Template, error)
|
||||
|
||||
// PatchTemplates is a list of templates to render into Patches and apply.
|
||||
PatchTemplates []PatchTemplate
|
||||
|
||||
@@ -307,8 +310,12 @@ type TemplateCommand struct {
|
||||
// PreProcess is run on the ResourceList before the template is invoked
|
||||
PreProcess func(*ResourceList) error
|
||||
|
||||
PreProcessFilters []kio.Filter
|
||||
|
||||
// PostProcess is run on the ResourceList after the template is invoked
|
||||
PostProcess func(*ResourceList) error
|
||||
|
||||
PostProcessFilters []kio.Filter
|
||||
}
|
||||
|
||||
// ContainerPatchTemplate defines a patch to be applied to containers
|
||||
@@ -353,6 +360,134 @@ func (tc TemplateCommand) doTemplate(t *template.Template, rl *ResourceList) err
|
||||
return nil
|
||||
}
|
||||
|
||||
// Defaulter is implemented by APIs to have Default invoked
|
||||
type Defaulter interface {
|
||||
Default() error
|
||||
}
|
||||
|
||||
func (tc *TemplateCommand) doPreProcess(rl *ResourceList) error {
|
||||
// do any preprocessing
|
||||
if tc.PreProcess != nil {
|
||||
if err := tc.PreProcess(rl); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: test this
|
||||
if tc.PreProcessFilters != nil {
|
||||
for i := range tc.PreProcessFilters {
|
||||
fltr := tc.PreProcessFilters[i]
|
||||
var err error
|
||||
rl.Items, err = fltr.Filter(rl.Items)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tc *TemplateCommand) doMerge(rl *ResourceList) error {
|
||||
var err error
|
||||
if tc.MergeResources {
|
||||
rl.Items, err = filters.MergeFilter{}.Filter(rl.Items)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (tc *TemplateCommand) doPostProcess(rl *ResourceList) error {
|
||||
// finish up
|
||||
if tc.PostProcess != nil {
|
||||
if err := tc.PostProcess(rl); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// TODO: test this
|
||||
if tc.PostProcessFilters != nil {
|
||||
for i := range tc.PostProcessFilters {
|
||||
fltr := tc.PostProcessFilters[i]
|
||||
var err error
|
||||
rl.Items, err = fltr.Filter(rl.Items)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tc *TemplateCommand) doTemplates(rl *ResourceList) error {
|
||||
if tc.Template != nil {
|
||||
tc.Templates = append(tc.Templates, tc.Template)
|
||||
}
|
||||
|
||||
// TODO: test this
|
||||
if tc.TemplatesFn != nil {
|
||||
t, err := tc.TemplatesFn(rl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tc.Templates = append(tc.Templates, t...)
|
||||
}
|
||||
|
||||
for i := range tc.TemplatesFiles {
|
||||
tbytes, err := ioutil.ReadFile(tc.TemplatesFiles[i])
|
||||
if err != nil {
|
||||
return errors.WrapPrefixf(err, "unable to read template file")
|
||||
}
|
||||
t, err := template.New("files").Parse(string(tbytes))
|
||||
if err != nil {
|
||||
return errors.WrapPrefixf(err, "unable to parse template files %v", tc.TemplatesFiles)
|
||||
}
|
||||
tc.Templates = append(tc.Templates, t)
|
||||
}
|
||||
|
||||
for i := range tc.Templates {
|
||||
if err := tc.doTemplate(tc.Templates[i], rl); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tc *TemplateCommand) doPatchTemplates(rl *ResourceList) error {
|
||||
if tc.PatchTemplatesFn != nil {
|
||||
pt, err := tc.PatchTemplatesFn(rl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tc.PatchTemplates = append(tc.PatchTemplates, pt...)
|
||||
}
|
||||
for i := range tc.PatchTemplates {
|
||||
if err := tc.PatchTemplates[i].Apply(rl); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tc *TemplateCommand) doPatchContainerTemplates(rl *ResourceList) error {
|
||||
if tc.PatchContainerTemplatesFn != nil {
|
||||
ct, err := tc.PatchContainerTemplatesFn(rl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tc.PatchContainerTemplates = append(tc.PatchContainerTemplates, ct...)
|
||||
}
|
||||
for i := range tc.PatchContainerTemplates {
|
||||
ct := tc.PatchContainerTemplates[i]
|
||||
matches, err := ct.Selector.GetMatches(rl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = PatchContainersWithTemplate(matches, ct.Template, rl.FunctionConfig, ct.ContainerNames...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetCommand returns a new cobra command
|
||||
func (tc TemplateCommand) GetCommand() *cobra.Command {
|
||||
rl := ResourceList{
|
||||
@@ -360,81 +495,29 @@ func (tc TemplateCommand) GetCommand() *cobra.Command {
|
||||
NoPrintError: true,
|
||||
}
|
||||
c := Command(&rl, func() error {
|
||||
// do any preprocessing
|
||||
if tc.PreProcess != nil {
|
||||
if err := tc.PreProcess(&rl); err != nil {
|
||||
if d, ok := rl.FunctionConfig.(Defaulter); ok {
|
||||
if err := d.Default(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if tc.Template != nil {
|
||||
tc.Templates = append(tc.Templates, tc.Template)
|
||||
if err := tc.doPreProcess(&rl); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := range tc.TemplatesFiles {
|
||||
tbytes, err := ioutil.ReadFile(tc.TemplatesFiles[i])
|
||||
if err != nil {
|
||||
return errors.WrapPrefixf(err, "unable to read template file")
|
||||
}
|
||||
t, err := template.New("files").Parse(string(tbytes))
|
||||
if err != nil {
|
||||
return errors.WrapPrefixf(err, "unable to parse template files %v", tc.TemplatesFiles)
|
||||
}
|
||||
tc.Templates = append(tc.Templates, t)
|
||||
if err := tc.doTemplates(&rl); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := range tc.Templates {
|
||||
if err := tc.doTemplate(tc.Templates[i], &rl); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tc.doPatchTemplates(&rl); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if tc.PatchTemplatesFn != nil {
|
||||
pt, err := tc.PatchTemplatesFn(&rl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tc.PatchTemplates = append(tc.PatchTemplates, pt...)
|
||||
if err := tc.doPatchContainerTemplates(&rl); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := range tc.PatchTemplates {
|
||||
if err := tc.PatchTemplates[i].Apply(&rl); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tc.doMerge(&rl); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if tc.PatchContainerTemplatesFn != nil {
|
||||
ct, err := tc.PatchContainerTemplatesFn(&rl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tc.PatchContainerTemplates = append(tc.PatchContainerTemplates, ct...)
|
||||
}
|
||||
for i := range tc.PatchContainerTemplates {
|
||||
ct := tc.PatchContainerTemplates[i]
|
||||
matches, err := ct.Selector.GetMatches(&rl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = PatchContainersWithTemplate(matches, ct.Template, rl.FunctionConfig, ct.ContainerNames...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
if tc.MergeResources {
|
||||
rl.Items, err = filters.MergeFilter{}.Filter(rl.Items)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// finish up
|
||||
if tc.PostProcess != nil {
|
||||
if err := tc.PostProcess(&rl); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tc.doPostProcess(&rl); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -482,3 +565,10 @@ func execute(rl *ResourceList, function Function, cmd *cobra.Command, args []str
|
||||
|
||||
return retErr
|
||||
}
|
||||
|
||||
// Filters returns a function which returns the provided Filters
|
||||
func Filters(fltrs ...kio.Filter) func(*ResourceList) []kio.Filter {
|
||||
return func(*ResourceList) []kio.Filter {
|
||||
return fltrs
|
||||
}
|
||||
}
|
||||
|
||||
154
kyaml/fn/framework/pkger.go
Normal file
154
kyaml/fn/framework/pkger.go
Normal file
@@ -0,0 +1,154 @@
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package framework
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/markbates/pkger"
|
||||
)
|
||||
|
||||
type TemplatesFn func(*ResourceList) ([]*template.Template, error)
|
||||
|
||||
// TemplatesFromDir applies a directory of templates as generated resources.
|
||||
func TemplatesFromDir(dirs ...pkger.Dir) TemplatesFn {
|
||||
return func(_ *ResourceList) ([]*template.Template, error) {
|
||||
var pt []*template.Template
|
||||
for i := range dirs {
|
||||
d := dirs[i]
|
||||
err := pkger.Walk(string(d), func(p string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !strings.HasSuffix(info.Name(), ".template.yaml") {
|
||||
return nil
|
||||
}
|
||||
name := path.Join(string(d), info.Name())
|
||||
f, err := pkger.Open(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t, err := template.New(info.Name()).Parse(string(b))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pt = append(pt, t)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return pt, nil
|
||||
}
|
||||
}
|
||||
|
||||
// PatchTemplatesFn returns a slice of PatchTemplate
|
||||
type PatchTemplatesFn func(*ResourceList) ([]PatchTemplate, error)
|
||||
|
||||
// PT applies a directory of patches using the Selector
|
||||
type PT struct {
|
||||
Selector func() *Selector
|
||||
Dir pkger.Dir
|
||||
}
|
||||
|
||||
// PatchTemplatesFromDir applies a directory of templates as patches.
|
||||
func PatchTemplatesFromDir(templates ...PT) PatchTemplatesFn {
|
||||
return func(*ResourceList) ([]PatchTemplate, error) {
|
||||
var pt []PatchTemplate
|
||||
for i := range templates {
|
||||
v := templates[i]
|
||||
err := pkger.Walk(string(v.Dir), func(p string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name := path.Join(string(v.Dir), info.Name())
|
||||
|
||||
if !strings.HasSuffix(info.Name(), ".template.yaml") {
|
||||
return nil
|
||||
}
|
||||
f, err := pkger.Open(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t, err := template.New(info.Name()).Parse(string(b))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pt = append(pt, PatchTemplate{Template: t, Selector: v.Selector()})
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return pt, nil
|
||||
}
|
||||
}
|
||||
|
||||
// ContainerPatchTemplateFn returns a slice of ContainerPatchTemplate
|
||||
type ContainerPatchTemplateFn func(*ResourceList) ([]ContainerPatchTemplate, error)
|
||||
|
||||
// CPT applies a directory of container patches using the Selector
|
||||
type CPT struct {
|
||||
Selector func() *Selector
|
||||
Dir pkger.Dir
|
||||
Names []string
|
||||
}
|
||||
|
||||
// ContainerPatchTemplatesFromDir applies a directory of templates as container patches.
|
||||
func ContainerPatchTemplatesFromDir(templates ...CPT) ContainerPatchTemplateFn {
|
||||
return func(*ResourceList) ([]ContainerPatchTemplate, error) {
|
||||
var cpt []ContainerPatchTemplate
|
||||
for i := range templates {
|
||||
v := templates[i]
|
||||
err := pkger.Walk(string(v.Dir), func(p string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !strings.HasSuffix(info.Name(), ".template.yaml") {
|
||||
return nil
|
||||
}
|
||||
|
||||
name := path.Join(string(v.Dir), info.Name())
|
||||
f, err := pkger.Open(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t, err := template.New(info.Name()).Parse(string(b))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cpt = append(cpt, ContainerPatchTemplate{
|
||||
PatchTemplate: PatchTemplate{Template: t, Selector: v.Selector()},
|
||||
ContainerNames: v.Names,
|
||||
})
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return cpt, nil
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ require (
|
||||
github.com/go-openapi/spec v0.19.5
|
||||
github.com/go-openapi/strfmt v0.19.5
|
||||
github.com/go-openapi/validate v0.19.8
|
||||
github.com/markbates/pkger v0.17.1
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00
|
||||
github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d
|
||||
github.com/sergi/go-diff v1.1.0
|
||||
|
||||
@@ -102,6 +102,8 @@ github.com/go-openapi/validate v0.19.8 h1:YFzsdWIDfVuLvIOF+ZmKjVg1MbPJ1QgY9PihMw
|
||||
github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gobuffalo/here v0.6.0 h1:hYrd0a6gDmWxBM4TnrGw8mQg24iSVoIkHEk7FodQcBI=
|
||||
github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
@@ -147,6 +149,8 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
|
||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||
github.com/markbates/pkger v0.17.1 h1:/MKEtWqtc0mZvu9OinB9UzVN9iYCwLWuyUv4Bw+PCno=
|
||||
github.com/markbates/pkger v0.17.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
@@ -288,6 +292,7 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71 h1:Xe2gvTZUJpsvOWUnvmL/tmhVBZUmHSvLbMjRj6NUUKo=
|
||||
|
||||
Reference in New Issue
Block a user