diff --git a/kyaml/fn/framework/example2/Dockerfile b/kyaml/fn/framework/example2/Dockerfile deleted file mode 100644 index d177d7df1..000000000 --- a/kyaml/fn/framework/example2/Dockerfile +++ /dev/null @@ -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"] diff --git a/kyaml/fn/framework/example2/config.yaml b/kyaml/fn/framework/example2/data/container-patches/container.template.yaml similarity index 53% rename from kyaml/fn/framework/example2/config.yaml rename to kyaml/fn/framework/example2/data/container-patches/container.template.yaml index 9be110fa0..fe54a6035 100644 --- a/kyaml/fn/framework/example2/config.yaml +++ b/kyaml/fn/framework/example2/data/container-patches/container.template.yaml @@ -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 }} \ No newline at end of file diff --git a/kyaml/fn/framework/example2/data/patches/patch.template.yaml b/kyaml/fn/framework/example2/data/patches/patch.template.yaml new file mode 100644 index 000000000..ce2bec2c3 --- /dev/null +++ b/kyaml/fn/framework/example2/data/patches/patch.template.yaml @@ -0,0 +1,5 @@ +# Copyright 2019 The Kubernetes Authors. +# SPDX-License-Identifier: Apache-2.0 + +spec: + replicas: {{ .Replicas }} \ No newline at end of file diff --git a/kyaml/fn/framework/example2/data/templates/deploy.template.yaml b/kyaml/fn/framework/example2/data/templates/deploy.template.yaml new file mode 100644 index 000000000..e2fd90442 --- /dev/null +++ b/kyaml/fn/framework/example2/data/templates/deploy.template.yaml @@ -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 }} diff --git a/kyaml/fn/framework/example2/doc.go b/kyaml/fn/framework/example2/doc.go new file mode 100644 index 000000000..b4fb32979 --- /dev/null +++ b/kyaml/fn/framework/example2/doc.go @@ -0,0 +1,4 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package example2 diff --git a/kyaml/fn/framework/example2/example_test.go b/kyaml/fn/framework/example2/example_test.go new file mode 100644 index 000000000..44db08ca2 --- /dev/null +++ b/kyaml/fn/framework/example2/example_test.go @@ -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())) +} diff --git a/kyaml/fn/framework/example2/main.go b/kyaml/fn/framework/example2/main.go deleted file mode 100644 index 8098f660d..000000000 --- a/kyaml/fn/framework/example2/main.go +++ /dev/null @@ -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) - } -} diff --git a/kyaml/fn/framework/example2/pkged.go b/kyaml/fn/framework/example2/pkged.go new file mode 100644 index 000000000..fa02488c5 --- /dev/null +++ b/kyaml/fn/framework/example2/pkged.go @@ -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`))) diff --git a/kyaml/fn/framework/framework.go b/kyaml/fn/framework/framework.go index 547bc1a4c..611557dd9 100644 --- a/kyaml/fn/framework/framework.go +++ b/kyaml/fn/framework/framework.go @@ -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 + } +} diff --git a/kyaml/fn/framework/pkger.go b/kyaml/fn/framework/pkger.go new file mode 100644 index 000000000..69cc7359e --- /dev/null +++ b/kyaml/fn/framework/pkger.go @@ -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 + } +} diff --git a/kyaml/go.mod b/kyaml/go.mod index c86805141..5bfe0986c 100644 --- a/kyaml/go.mod +++ b/kyaml/go.mod @@ -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 diff --git a/kyaml/go.sum b/kyaml/go.sum index c53591d76..6340dd659 100644 --- a/kyaml/go.sum +++ b/kyaml/go.sum @@ -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=