diff --git a/pkg/document/bundle.go b/pkg/document/bundle.go index 17855d829..a6aa4557a 100644 --- a/pkg/document/bundle.go +++ b/pkg/document/bundle.go @@ -16,10 +16,17 @@ import ( "sigs.k8s.io/kustomize/v3/pkg/target" "sigs.k8s.io/kustomize/v3/pkg/types" + docplugins "opendev.org/airship/airshipctl/pkg/document/plugins" "opendev.org/airship/airshipctl/pkg/log" utilyaml "opendev.org/airship/airshipctl/pkg/util/yaml" ) +func init() { + // NOTE (dukov) This is sort of a hack but it's the only way to add an + // external 'builtin' plugin to Kustomize + plugins.TransformerFactories[plugins.Unknown] = docplugins.NewTransformerLoader +} + // KustomizeBuildOptions contain the options for running a Kustomize build on a bundle type KustomizeBuildOptions struct { KustomizationPath string diff --git a/pkg/document/plugins/errors.go b/pkg/document/plugins/errors.go new file mode 100644 index 000000000..0c9f5cd69 --- /dev/null +++ b/pkg/document/plugins/errors.go @@ -0,0 +1,28 @@ +/* +Copyright 2014 The Kubernetes Authors. + +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 + + http://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 plugins + +import "fmt" + +// ErrUnknownPlugin raised for unregistered plugins +type ErrUnknownPlugin struct { + Kind string +} + +func (e ErrUnknownPlugin) Error() string { + return fmt.Sprintf("Unknown airship plugin with Kind: %s", e.Kind) +} diff --git a/pkg/document/plugins/loader.go b/pkg/document/plugins/loader.go new file mode 100644 index 000000000..8eec1b77f --- /dev/null +++ b/pkg/document/plugins/loader.go @@ -0,0 +1,60 @@ +/* +Copyright 2014 The Kubernetes Authors. + +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 + + http://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 plugins + +import ( + "sigs.k8s.io/kustomize/v3/pkg/ifc" + "sigs.k8s.io/kustomize/v3/pkg/resid" + "sigs.k8s.io/kustomize/v3/pkg/resmap" + "sigs.k8s.io/yaml" +) + +// PluginRegistry map of plugin kinds to plugin instance +var PluginRegistry = make(map[string]resmap.TransformerPlugin) + +// TransformerLoader airship document plugin loader. Loads external +// Kustomize plugins as builtin +type TransformerLoader struct { + resid.ResId +} + +// Config reads plugin configuration structure +func (l *TransformerLoader) Config( + ldr ifc.Loader, rf *resmap.Factory, c []byte) error { + if err := yaml.Unmarshal(c, l); err != nil { + return err + } + airshipPlugin, found := PluginRegistry[l.Kind] + if !found { + return ErrUnknownPlugin{Kind: l.Kind} + } + return airshipPlugin.Config(ldr, rf, c) +} + +// Transform executes Transform method of an external plugin +func (l *TransformerLoader) Transform(m resmap.ResMap) error { + airshipPlugin, found := PluginRegistry[l.Kind] + if !found { + return ErrUnknownPlugin{Kind: l.Kind} + } + return airshipPlugin.Transform(m) +} + +// NewTransformerLoader returns plugin loader instance +func NewTransformerLoader() resmap.TransformerPlugin { + return &TransformerLoader{} +} diff --git a/pkg/document/plugins/loader_test.go b/pkg/document/plugins/loader_test.go new file mode 100644 index 000000000..848dbb77f --- /dev/null +++ b/pkg/document/plugins/loader_test.go @@ -0,0 +1,33 @@ +/* +Copyright 2014 The Kubernetes Authors. + +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 + + http://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 plugins_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "opendev.org/airship/airshipctl/pkg/document" + "opendev.org/airship/airshipctl/testutil" +) + +func TestLoaderConfig(t *testing.T) { + t.Run("Try load non-existent plugin", func(t *testing.T) { + _, err := document.NewBundle(testutil.SetupTestFs(t, "testdata/unknownplugin"), "/", "/") + assert.Error(t, err) + }) +} diff --git a/pkg/document/plugins/testdata/unknownplugin/dummyplugin.yaml b/pkg/document/plugins/testdata/unknownplugin/dummyplugin.yaml new file mode 100644 index 000000000..e1f830ba8 --- /dev/null +++ b/pkg/document/plugins/testdata/unknownplugin/dummyplugin.yaml @@ -0,0 +1,4 @@ +apiVersion: builtin +kind: SomeKind +metadata: + name: notImportantHere \ No newline at end of file diff --git a/pkg/document/plugins/testdata/unknownplugin/kustomization.yaml b/pkg/document/plugins/testdata/unknownplugin/kustomization.yaml new file mode 100644 index 000000000..fc03de19f --- /dev/null +++ b/pkg/document/plugins/testdata/unknownplugin/kustomization.yaml @@ -0,0 +1,2 @@ +transformers: + - dummyplugin.yaml \ No newline at end of file