Move plugins configurations to API module
Data structure representing plugin configurations should be a part of airshipctl API module. Plugin implementations will reside in document package. Change-Id: Id2e359b747a16a5573052cfb05c1148d346db508 Relates-To: #322
This commit is contained in:
parent
1660efc231
commit
034efc3682
@ -49,6 +49,8 @@ func init() {
|
|||||||
&ImageConfiguration{},
|
&ImageConfiguration{},
|
||||||
&RemoteDirectConfiguration{},
|
&RemoteDirectConfiguration{},
|
||||||
&ClusterMap{},
|
&ClusterMap{},
|
||||||
|
&ReplacementTransformer{},
|
||||||
|
&Templater{},
|
||||||
)
|
)
|
||||||
_ = AddToScheme(Scheme) //nolint:errcheck
|
_ = AddToScheme(Scheme) //nolint:errcheck
|
||||||
}
|
}
|
||||||
|
57
pkg/api/v1alpha1/replacement_plugin_types.go
Normal file
57
pkg/api/v1alpha1/replacement_plugin_types.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
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"
|
||||||
|
"sigs.k8s.io/kustomize/api/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// +kubebuilder:object:root=true
|
||||||
|
|
||||||
|
// ReplacementTransformer plugin configuration for airship document model
|
||||||
|
type ReplacementTransformer struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||||
|
|
||||||
|
// Replacements list of source and target field to do a replacement
|
||||||
|
Replacements []types.Replacement `json:"replacements,omitempty" yaml:"replacements,omitempty"`
|
||||||
|
Tst []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ReplacementTransformer) DeepCopyInto(out *ReplacementTransformer) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||||
|
if in.Replacements != nil {
|
||||||
|
out.Replacements = make([]types.Replacement, len(in.Replacements))
|
||||||
|
for i, repl := range in.Replacements {
|
||||||
|
out.Replacements[i] = types.Replacement{
|
||||||
|
Source: &types.ReplSource{
|
||||||
|
ObjRef: &types.Target{},
|
||||||
|
FieldRef: repl.Source.FieldRef,
|
||||||
|
Value: repl.Source.Value,
|
||||||
|
},
|
||||||
|
Target: &types.ReplTarget{
|
||||||
|
ObjRef: &types.Selector{},
|
||||||
|
FieldRefs: repl.Target.FieldRefs,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
*(out.Replacements[i].Source.ObjRef) = *(in.Replacements[i].Source.ObjRef)
|
||||||
|
*(out.Replacements[i].Target.ObjRef) = *(in.Replacements[i].Target.ObjRef)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,9 +16,12 @@ package v1alpha1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Templater plugin for airship document model
|
// +kubebuilder:object:root=true
|
||||||
|
|
||||||
|
// Templater plugin configuration for airship document model
|
||||||
type Templater struct {
|
type Templater struct {
|
||||||
metav1.TypeMeta `json:",inline"`
|
metav1.TypeMeta `json:",inline"`
|
||||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||||
@ -29,3 +32,13 @@ type Templater struct {
|
|||||||
// to be used to render the object defined in Spec field
|
// to be used to render the object defined in Spec field
|
||||||
Template string `json:"template,omitempty"`
|
Template string `json:"template,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE map[string]interface is not supported by controller gen
|
||||||
|
|
||||||
|
// DeepCopyInto is copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *Templater) DeepCopyInto(out *Templater) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||||
|
out.Values = runtime.DeepCopyJSON(in.Values)
|
||||||
|
}
|
@ -490,3 +490,39 @@ func (in *RemoteDirectConfiguration) DeepCopyObject() runtime.Object {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplacementTransformer.
|
||||||
|
func (in *ReplacementTransformer) DeepCopy() *ReplacementTransformer {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ReplacementTransformer)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *ReplacementTransformer) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Templater.
|
||||||
|
func (in *Templater) DeepCopy() *Templater {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(Templater)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *Templater) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package v1alpha1
|
package replacement
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
@ -17,11 +17,17 @@ package replacement
|
|||||||
import (
|
import (
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
|
||||||
replv1alpha1 "opendev.org/airship/airshipctl/pkg/document/plugin/replacement/v1alpha1"
|
airshipv1 "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
|
||||||
"opendev.org/airship/airshipctl/pkg/document/plugin/types"
|
"opendev.org/airship/airshipctl/pkg/document/plugin/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RegisterPlugin registers BareMetalHost generator plugin
|
// RegisterPlugin registers BareMetalHost generator plugin
|
||||||
func RegisterPlugin(registry map[schema.GroupVersionKind]types.Factory) {
|
func RegisterPlugin(registry map[schema.GroupVersionKind]types.Factory) error {
|
||||||
registry[replv1alpha1.GetGVK()] = replv1alpha1.New
|
obj := &airshipv1.ReplacementTransformer{}
|
||||||
|
gvks, _, err := airshipv1.Scheme.ObjectKinds(obj)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
registry[gvks[0]] = New
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Copyright 2019 The Kubernetes Authors.
|
// Copyright 2019 The Kubernetes Authors.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package v1alpha1
|
package replacement
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -11,13 +11,13 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
|
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
|
||||||
"sigs.k8s.io/kustomize/api/resmap"
|
"sigs.k8s.io/kustomize/api/resmap"
|
||||||
"sigs.k8s.io/kustomize/api/resource"
|
"sigs.k8s.io/kustomize/api/resource"
|
||||||
"sigs.k8s.io/kustomize/api/types"
|
"sigs.k8s.io/kustomize/api/types"
|
||||||
"sigs.k8s.io/yaml"
|
|
||||||
|
|
||||||
|
airshipv1 "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
|
||||||
plugtypes "opendev.org/airship/airshipctl/pkg/document/plugin/types"
|
plugtypes "opendev.org/airship/airshipctl/pkg/document/plugin/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,22 +31,29 @@ const (
|
|||||||
dotReplacer = "$$$$"
|
dotReplacer = "$$$$"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetGVK returns group, version, kind object used to register version
|
type plugin struct {
|
||||||
// of the plugin
|
*airshipv1.ReplacementTransformer
|
||||||
func GetGVK() schema.GroupVersionKind {
|
|
||||||
return schema.GroupVersionKind{
|
|
||||||
Group: "airshipit.org",
|
|
||||||
Version: "v1alpha1",
|
|
||||||
Kind: "ReplacementTransformer",
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates new instance of the plugin
|
// New creates new instance of the plugin
|
||||||
func New(cfg []byte) (plugtypes.Plugin, error) {
|
func New(obj map[string]interface{}) (plugtypes.Plugin, error) {
|
||||||
p := &plugin{}
|
cfg := &airshipv1.ReplacementTransformer{}
|
||||||
if err := p.Config(nil, cfg); err != nil {
|
err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj, cfg)
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
p := &plugin{ReplacementTransformer: cfg}
|
||||||
|
for _, r := range p.Replacements {
|
||||||
|
if r.Source == nil {
|
||||||
|
return nil, ErrBadConfiguration{Msg: "`from` must be specified in one replacement"}
|
||||||
|
}
|
||||||
|
if r.Target == nil {
|
||||||
|
return nil, ErrBadConfiguration{Msg: "`to` must be specified in one replacement"}
|
||||||
|
}
|
||||||
|
if r.Source.ObjRef != nil && r.Source.Value != "" {
|
||||||
|
return nil, ErrBadConfiguration{Msg: "only one of fieldref and value is allowed in one replacement"}
|
||||||
|
}
|
||||||
|
}
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,28 +89,6 @@ func (p *plugin) Run(in io.Reader, out io.Writer) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config function reads replacements configuration
|
|
||||||
func (p *plugin) Config(
|
|
||||||
_ *resmap.PluginHelpers, c []byte) error {
|
|
||||||
p.Replacements = []types.Replacement{}
|
|
||||||
err := yaml.Unmarshal(c, p)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, r := range p.Replacements {
|
|
||||||
if r.Source == nil {
|
|
||||||
return ErrBadConfiguration{Msg: "`from` must be specified in one replacement"}
|
|
||||||
}
|
|
||||||
if r.Target == nil {
|
|
||||||
return ErrBadConfiguration{Msg: "`to` must be specified in one replacement"}
|
|
||||||
}
|
|
||||||
if r.Source.ObjRef != nil && r.Source.Value != "" {
|
|
||||||
return ErrBadConfiguration{Msg: "only one of fieldref and value is allowed in one replacement"}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transform resources using configured replacements
|
// Transform resources using configured replacements
|
||||||
func (p *plugin) Transform(m resmap.ResMap) error {
|
func (p *plugin) Transform(m resmap.ResMap) error {
|
||||||
var err error
|
var err error
|
@ -1,7 +1,7 @@
|
|||||||
// Copyright 2019 The Kubernetes Authors.
|
// Copyright 2019 The Kubernetes Authors.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package v1alpha1_test
|
package replacement_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@ -11,12 +11,15 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
replv1alpha1 "opendev.org/airship/airshipctl/pkg/document/plugin/replacement/v1alpha1"
|
"sigs.k8s.io/yaml"
|
||||||
|
|
||||||
|
"opendev.org/airship/airshipctl/pkg/document/plugin/replacement"
|
||||||
plugtypes "opendev.org/airship/airshipctl/pkg/document/plugin/types"
|
plugtypes "opendev.org/airship/airshipctl/pkg/document/plugin/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func samplePlugin(t *testing.T) plugtypes.Plugin {
|
func samplePlugin(t *testing.T) plugtypes.Plugin {
|
||||||
plugin, err := replv1alpha1.New([]byte(`
|
cfg := make(map[string]interface{})
|
||||||
|
conf := `
|
||||||
apiVersion: airshipit.org/v1alpha1
|
apiVersion: airshipit.org/v1alpha1
|
||||||
kind: ReplacementTransformer
|
kind: ReplacementTransformer
|
||||||
metadata:
|
metadata:
|
||||||
@ -28,17 +31,15 @@ replacements:
|
|||||||
objref:
|
objref:
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
fieldrefs:
|
fieldrefs:
|
||||||
- spec.template.spec.containers[name=nginx-latest].image`))
|
- spec.template.spec.containers[name=nginx-latest].image`
|
||||||
|
|
||||||
|
err := yaml.Unmarshal([]byte(conf), &cfg)
|
||||||
|
require.NoError(t, err)
|
||||||
|
plugin, err := replacement.New(cfg)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return plugin
|
return plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMalformedConfig(t *testing.T) {
|
|
||||||
_, err := replv1alpha1.New([]byte("--"))
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMalformedInput(t *testing.T) {
|
func TestMalformedInput(t *testing.T) {
|
||||||
plugin := samplePlugin(t)
|
plugin := samplePlugin(t)
|
||||||
err := plugin.Run(strings.NewReader("--"), &bytes.Buffer{})
|
err := plugin.Run(strings.NewReader("--"), &bytes.Buffer{})
|
||||||
@ -978,7 +979,7 @@ metadata:
|
|||||||
name: notImportantHere
|
name: notImportantHere
|
||||||
replacements:
|
replacements:
|
||||||
- source:
|
- source:
|
||||||
value: 12345678
|
value: "12345678"
|
||||||
target:
|
target:
|
||||||
objref:
|
objref:
|
||||||
kind: KubeadmControlPlane
|
kind: KubeadmControlPlane
|
||||||
@ -1011,7 +1012,10 @@ spec:
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
plugin, err := replv1alpha1.New([]byte(tc.cfg))
|
cfg := make(map[string]interface{})
|
||||||
|
err := yaml.Unmarshal([]byte(tc.cfg), &cfg)
|
||||||
|
require.NoError(t, err)
|
||||||
|
plugin, err := replacement.New(cfg)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
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 (
|
|
||||||
"sigs.k8s.io/kustomize/api/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Find matching image declarations and replace
|
|
||||||
// the name, tag and/or digest.
|
|
||||||
type plugin struct {
|
|
||||||
Replacements []types.Replacement `json:"replacements,omitempty" yaml:"replacements,omitempty"`
|
|
||||||
}
|
|
@ -27,28 +27,38 @@ import (
|
|||||||
"opendev.org/airship/airshipctl/pkg/document/plugin/types"
|
"opendev.org/airship/airshipctl/pkg/document/plugin/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Registry contains factory functions for the available plugins
|
// DefaultPlugins returns map with plugin factories
|
||||||
var Registry = make(map[schema.GroupVersionKind]types.Factory)
|
func DefaultPlugins() (map[schema.GroupVersionKind]types.Factory, error) {
|
||||||
|
registry := make(map[schema.GroupVersionKind]types.Factory)
|
||||||
func init() {
|
if err := replacement.RegisterPlugin(registry); err != nil {
|
||||||
replacement.RegisterPlugin(Registry)
|
return nil, err
|
||||||
templater.RegisterPlugin(Registry)
|
}
|
||||||
|
if err := templater.RegisterPlugin(registry); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return registry, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigureAndRun executes particular plugin based on group, version, kind
|
// ConfigureAndRun executes particular plugin based on group, version, kind
|
||||||
// which have been specified in configuration file. Config file should be
|
// which have been specified in configuration file. Config file should be
|
||||||
// supplied as a first element of args slice
|
// supplied as a first element of args slice
|
||||||
func ConfigureAndRun(pluginCfg []byte, in io.Reader, out io.Writer) error {
|
func ConfigureAndRun(pluginCfg []byte, in io.Reader, out io.Writer) error {
|
||||||
var cfg unstructured.Unstructured
|
rawCfg := make(map[string]interface{})
|
||||||
if err := yaml.Unmarshal(pluginCfg, &cfg); err != nil {
|
if err := yaml.Unmarshal(pluginCfg, &rawCfg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
pluginFactory, ok := Registry[cfg.GroupVersionKind()]
|
uCfg := &unstructured.Unstructured{}
|
||||||
|
uCfg.SetUnstructuredContent(rawCfg)
|
||||||
|
registry, err := DefaultPlugins()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pluginFactory, ok := registry[uCfg.GroupVersionKind()]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrPluginNotFound{PluginID: cfg.GroupVersionKind()}
|
return ErrPluginNotFound{PluginID: uCfg.GroupVersionKind()}
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin, err := pluginFactory(pluginCfg)
|
plugin, err := pluginFactory(rawCfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -17,11 +17,17 @@ package templater
|
|||||||
import (
|
import (
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
|
||||||
tmplv1alpha1 "opendev.org/airship/airshipctl/pkg/document/plugin/templater/v1alpha1"
|
airshipv1 "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
|
||||||
"opendev.org/airship/airshipctl/pkg/document/plugin/types"
|
"opendev.org/airship/airshipctl/pkg/document/plugin/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RegisterPlugin registers BareMetalHost generator plugin
|
// RegisterPlugin registers BareMetalHost generator plugin
|
||||||
func RegisterPlugin(registry map[schema.GroupVersionKind]types.Factory) {
|
func RegisterPlugin(registry map[schema.GroupVersionKind]types.Factory) error {
|
||||||
registry[tmplv1alpha1.GetGVK()] = tmplv1alpha1.New
|
obj := &airshipv1.Templater{}
|
||||||
|
gvks, _, err := airshipv1.Scheme.ObjectKinds(obj)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
registry[gvks[0]] = New
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package v1alpha1
|
package templater
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
@ -20,33 +20,31 @@ import (
|
|||||||
|
|
||||||
"github.com/Masterminds/sprig"
|
"github.com/Masterminds/sprig"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"sigs.k8s.io/yaml"
|
"sigs.k8s.io/yaml"
|
||||||
|
|
||||||
|
airshipv1 "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
|
||||||
plugtypes "opendev.org/airship/airshipctl/pkg/document/plugin/types"
|
plugtypes "opendev.org/airship/airshipctl/pkg/document/plugin/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetGVK returns group, version, kind object used to register version
|
type plugin struct {
|
||||||
// of the plugin
|
*airshipv1.Templater
|
||||||
func GetGVK() schema.GroupVersionKind {
|
|
||||||
return schema.GroupVersionKind{
|
|
||||||
Group: "airshipit.org",
|
|
||||||
Version: "v1alpha1",
|
|
||||||
Kind: "Templater",
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates new instance of the plugin
|
// New creates new instance of the plugin
|
||||||
func New(cfg []byte) (plugtypes.Plugin, error) {
|
func New(obj map[string]interface{}) (plugtypes.Plugin, error) {
|
||||||
t := &Templater{}
|
cfg := &airshipv1.Templater{}
|
||||||
if err := yaml.Unmarshal(cfg, t); err != nil {
|
err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj, cfg)
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return t, nil
|
return &plugin{
|
||||||
|
Templater: cfg,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run templater plugin
|
// Run templater plugin
|
||||||
func (t *Templater) Run(_ io.Reader, out io.Writer) error {
|
func (t *plugin) Run(_ io.Reader, out io.Writer) error {
|
||||||
funcMap := sprig.TxtFuncMap()
|
funcMap := sprig.TxtFuncMap()
|
||||||
funcMap["toYaml"] = toYaml
|
funcMap["toYaml"] = toYaml
|
||||||
tmpl, err := template.New("tmpl").Funcs(funcMap).Parse(t.Template)
|
tmpl, err := template.New("tmpl").Funcs(funcMap).Parse(t.Template)
|
@ -12,7 +12,7 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package v1alpha1_test
|
package templater_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@ -20,15 +20,11 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"sigs.k8s.io/yaml"
|
||||||
|
|
||||||
tmplv1alpha1 "opendev.org/airship/airshipctl/pkg/document/plugin/templater/v1alpha1"
|
"opendev.org/airship/airshipctl/pkg/document/plugin/templater"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMalformedConfig(t *testing.T) {
|
|
||||||
_, err := tmplv1alpha1.New([]byte("--"))
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTemplater(t *testing.T) {
|
func TestTemplater(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
cfg string
|
cfg string
|
||||||
@ -119,7 +115,10 @@ template: |
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
plugin, err := tmplv1alpha1.New([]byte(tc.cfg))
|
cfg := make(map[string]interface{})
|
||||||
|
err := yaml.Unmarshal([]byte(tc.cfg), &cfg)
|
||||||
|
require.NoError(t, err)
|
||||||
|
plugin, err := templater.New(cfg)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
err = plugin.Run(nil, buf)
|
err = plugin.Run(nil, buf)
|
@ -25,4 +25,4 @@ type Plugin interface {
|
|||||||
|
|
||||||
// Factory function for plugins. Functions of such type are used in the plugin
|
// Factory function for plugins. Functions of such type are used in the plugin
|
||||||
// registry to instantiate a plugin object
|
// registry to instantiate a plugin object
|
||||||
type Factory func([]byte) (Plugin, error)
|
type Factory func(map[string]interface{}) (Plugin, error)
|
||||||
|
Loading…
Reference in New Issue
Block a user