Add template based generator plugin
Plugin is responsible for resource generation based on template (go template format is used) supplied to its configuration. Go template can use an object (map) specified under 'spec' configuration parameter. Change-Id: I8c1b7dc5676bfff2f9b1a47f6433177ae796a15f
This commit is contained in:
parent
009794e408
commit
c458e8cde4
5
go.mod
5
go.mod
@ -3,6 +3,9 @@ module opendev.org/airship/airshipctl
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/Masterminds/goutils v1.1.0 // indirect
|
||||
github.com/Masterminds/semver v1.5.0 // indirect
|
||||
github.com/Masterminds/sprig v2.22.0+incompatible
|
||||
github.com/Microsoft/go-winio v0.4.12 // indirect
|
||||
github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 // indirect
|
||||
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0
|
||||
@ -16,6 +19,8 @@ require (
|
||||
github.com/go-git/go-git/v5 v5.0.0
|
||||
github.com/gorilla/mux v1.7.4 // indirect
|
||||
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc // indirect
|
||||
github.com/huandu/xstrings v1.3.1 // indirect
|
||||
github.com/mitchellh/copystructure v1.0.0 // indirect
|
||||
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c // indirect
|
||||
github.com/opencontainers/image-spec v1.0.1 // indirect
|
||||
github.com/spf13/cobra v0.0.6
|
||||
|
12
go.sum
12
go.sum
@ -23,6 +23,12 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
|
||||
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
|
||||
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
|
||||
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
|
||||
github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg=
|
||||
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
||||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
|
||||
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
|
||||
github.com/Microsoft/go-winio v0.4.12 h1:xAfWHN1IrQ0NJ9TBC0KBZoqLjzDTr1ML+4MywiUOryc=
|
||||
github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
@ -327,6 +333,8 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs=
|
||||
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=
|
||||
@ -402,6 +410,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mholt/certmagic v0.6.2-0.20190624175158-6a42ef9fe8c2/go.mod h1:g4cOPxcjV0oFq3qwpjSA30LReKD8AoIfwAY9VvG35NY=
|
||||
github.com/miekg/dns v1.1.3/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
|
||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
|
||||
@ -409,6 +419,8 @@ github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9
|
||||
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
|
||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/document/plugin/replacement"
|
||||
"opendev.org/airship/airshipctl/pkg/document/plugin/templater"
|
||||
"opendev.org/airship/airshipctl/pkg/document/plugin/types"
|
||||
"opendev.org/airship/airshipctl/pkg/environment"
|
||||
)
|
||||
@ -32,6 +33,7 @@ var Registry = make(map[schema.GroupVersionKind]types.Factory)
|
||||
|
||||
func init() {
|
||||
replacement.RegisterPlugin(Registry)
|
||||
templater.RegisterPlugin(Registry)
|
||||
}
|
||||
|
||||
// ConfigureAndRun executes particular plugin based on group, version, kind
|
||||
|
27
pkg/document/plugin/templater/init.go
Normal file
27
pkg/document/plugin/templater/init.go
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package templater
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
tmplv1alpha1 "opendev.org/airship/airshipctl/pkg/document/plugin/templater/v1alpha1"
|
||||
"opendev.org/airship/airshipctl/pkg/document/plugin/types"
|
||||
)
|
||||
|
||||
// RegisterPlugin registers BareMetalHost generator plugin
|
||||
func RegisterPlugin(registry map[schema.GroupVersionKind]types.Factory) {
|
||||
registry[tmplv1alpha1.GetGVK()] = tmplv1alpha1.New
|
||||
}
|
55
pkg/document/plugin/templater/v1alpha1/templater.go
Normal file
55
pkg/document/plugin/templater/v1alpha1/templater.go
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"io"
|
||||
"text/template"
|
||||
|
||||
"github.com/Masterminds/sprig"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
plugtypes "opendev.org/airship/airshipctl/pkg/document/plugin/types"
|
||||
"opendev.org/airship/airshipctl/pkg/environment"
|
||||
)
|
||||
|
||||
// GetGVK returns group, version, kind object used to register version
|
||||
// of the plugin
|
||||
func GetGVK() schema.GroupVersionKind {
|
||||
return schema.GroupVersionKind{
|
||||
Group: "airshipit.org",
|
||||
Version: "v1alpha1",
|
||||
Kind: "Templater",
|
||||
}
|
||||
}
|
||||
|
||||
// New creates new instance of the plugin
|
||||
func New(_ *environment.AirshipCTLSettings, cfg []byte) (plugtypes.Plugin, error) {
|
||||
t := &Templater{}
|
||||
if err := yaml.Unmarshal(cfg, t); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
// Run templater plugin
|
||||
func (t *Templater) Run(_ io.Reader, out io.Writer) error {
|
||||
tmpl, err := template.New("tmpl").Funcs(sprig.TxtFuncMap()).Parse(t.Template)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tmpl.Execute(out, t.Values)
|
||||
}
|
98
pkg/document/plugin/templater/v1alpha1/templater_test.go
Normal file
98
pkg/document/plugin/templater/v1alpha1/templater_test.go
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
tmplv1alpha1 "opendev.org/airship/airshipctl/pkg/document/plugin/templater/v1alpha1"
|
||||
)
|
||||
|
||||
func TestMalformedConfig(t *testing.T) {
|
||||
_, err := tmplv1alpha1.New(nil, []byte("--"))
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestTemplater(t *testing.T) {
|
||||
testCases := []struct {
|
||||
cfg string
|
||||
expectedOut string
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
cfg: `
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
kind: Templater
|
||||
metadata:
|
||||
name: notImportantHere
|
||||
values:
|
||||
hosts:
|
||||
- macAddress: 00:aa:bb:cc:dd
|
||||
name: node-1
|
||||
- macAddress: 00:aa:bb:cc:ee
|
||||
name: node-2
|
||||
template: |
|
||||
{{ range .hosts -}}
|
||||
---
|
||||
apiVersion: metal3.io/v1alpha1
|
||||
kind: BareMetalHost
|
||||
metadata:
|
||||
name: {{ .name }}
|
||||
spec:
|
||||
bootMACAddress: {{ .macAddress }}
|
||||
{{ end -}}`,
|
||||
expectedOut: `---
|
||||
apiVersion: metal3.io/v1alpha1
|
||||
kind: BareMetalHost
|
||||
metadata:
|
||||
name: node-1
|
||||
spec:
|
||||
bootMACAddress: 00:aa:bb:cc:dd
|
||||
---
|
||||
apiVersion: metal3.io/v1alpha1
|
||||
kind: BareMetalHost
|
||||
metadata:
|
||||
name: node-2
|
||||
spec:
|
||||
bootMACAddress: 00:aa:bb:cc:ee
|
||||
`,
|
||||
},
|
||||
{
|
||||
cfg: `
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
kind: Templater
|
||||
metadata:
|
||||
name: notImportantHere
|
||||
template: |
|
||||
{{ end }`,
|
||||
expectedErr: "template: tmpl:1: unexpected \"}\" in end",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
plugin, err := tmplv1alpha1.New(nil, []byte(tc.cfg))
|
||||
require.NoError(t, err)
|
||||
buf := &bytes.Buffer{}
|
||||
err = plugin.Run(nil, buf)
|
||||
if tc.expectedErr != "" {
|
||||
assert.EqualError(t, err, tc.expectedErr)
|
||||
}
|
||||
assert.Equal(t, tc.expectedOut, buf.String())
|
||||
}
|
||||
}
|
31
pkg/document/plugin/templater/v1alpha1/types.go
Normal file
31
pkg/document/plugin/templater/v1alpha1/types.go
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// Templater plugin for airship document model
|
||||
type Templater struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Values contains map with object parameters to render
|
||||
Values map[string]interface{} `json:"values,omitempty"`
|
||||
// Template field is used to specify actual go-template which is going
|
||||
// to be used to render the object defined in Spec field
|
||||
Template string `json:"template,omitempty"`
|
||||
}
|
Loading…
Reference in New Issue
Block a user