Merge "Groom phase/executors package"

This commit is contained in:
Zuul 2021-01-13 12:42:23 +00:00 committed by Gerrit Code Review
commit 80a8b53c42
16 changed files with 293 additions and 334 deletions

View File

@ -49,6 +49,7 @@ type BootstrapIsoOptions struct {
Writer io.Writer Writer io.Writer
} }
// VerifyInputs verifies image configuration
func VerifyInputs(cfg *v1alpha1.IsoConfiguration) error { func VerifyInputs(cfg *v1alpha1.IsoConfiguration) error {
if cfg.IsoContainer.Volume == "" { if cfg.IsoContainer.Volume == "" {
return config.ErrMissingConfig{ return config.ErrMissingConfig{

View File

@ -37,20 +37,11 @@ type ExecutorRegistry func() map[schema.GroupVersionKind]ifc.ExecutorFactory
func DefaultExecutorRegistry() map[schema.GroupVersionKind]ifc.ExecutorFactory { func DefaultExecutorRegistry() map[schema.GroupVersionKind]ifc.ExecutorFactory {
execMap := make(map[schema.GroupVersionKind]ifc.ExecutorFactory) execMap := make(map[schema.GroupVersionKind]ifc.ExecutorFactory)
if err := executors.RegisterExecutor(execMap); err != nil { for _, execName := range []string{executors.Clusterctl, executors.KubernetesApply,
log.Fatal(ErrExecutorRegistration{ExecutorName: "clusterctl", Err: err}) executors.Isogen, executors.GenericContainer, executors.Ephemeral} {
} if err := executors.RegisterExecutor(execName, execMap); err != nil {
if err := executors.RegisterKubeApplierExecutor(execMap); err != nil { log.Fatal(ErrExecutorRegistration{ExecutorName: execName, Err: err})
log.Fatal(ErrExecutorRegistration{ExecutorName: "kubernetes-apply", Err: err}) }
}
if err := executors.RegisterIsogenExecutor(execMap); err != nil {
log.Fatal(ErrExecutorRegistration{ExecutorName: "isogen", Err: err})
}
if err := executors.RegisterContainerExecutor(execMap); err != nil {
log.Fatal(ErrExecutorRegistration{ExecutorName: "generic-container", Err: err})
}
if err := executors.RegisterEphemeralExecutor(execMap); err != nil {
log.Fatal(ErrExecutorRegistration{ExecutorName: "ephemeral", Err: err})
} }
return execMap return execMap
} }

View File

@ -17,8 +17,6 @@ package executors
import ( import (
"io" "io"
"k8s.io/apimachinery/pkg/runtime/schema"
airshipv1 "opendev.org/airship/airshipctl/pkg/api/v1alpha1" airshipv1 "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
"opendev.org/airship/airshipctl/pkg/cluster/clustermap" "opendev.org/airship/airshipctl/pkg/cluster/clustermap"
"opendev.org/airship/airshipctl/pkg/clusterctl/client" "opendev.org/airship/airshipctl/pkg/clusterctl/client"
@ -41,19 +39,8 @@ type ClusterctlExecutor struct {
kubecfg kubeconfig.Interface kubecfg kubeconfig.Interface
} }
// RegisterExecutor adds executor to phase executor registry // NewClusterctlExecutor creates instance of 'clusterctl init' phase executor
func RegisterExecutor(registry map[schema.GroupVersionKind]ifc.ExecutorFactory) error { func NewClusterctlExecutor(cfg ifc.ExecutorConfig) (ifc.Executor, error) {
obj := &airshipv1.Clusterctl{}
gvks, _, err := airshipv1.Scheme.ObjectKinds(obj)
if err != nil {
return err
}
registry[gvks[0]] = NewExecutor
return nil
}
// NewExecutor creates instance of 'clusterctl init' phase executor
func NewExecutor(cfg ifc.ExecutorConfig) (ifc.Executor, error) {
options := airshipv1.DefaultClusterctl() options := airshipv1.DefaultClusterctl()
if err := cfg.ExecutorDocument.ToAPIObject(options, airshipv1.Scheme); err != nil { if err := cfg.ExecutorDocument.ToAPIObject(options, airshipv1.Scheme); err != nil {
return nil, err return nil, err
@ -80,7 +67,7 @@ func (c *ClusterctlExecutor) Run(evtCh chan events.Event, opts ifc.RunOptions) {
case airshipv1.Init: case airshipv1.Init:
c.init(opts, evtCh) c.init(opts, evtCh)
default: default:
c.handleErr(ErrUnknownExecutorAction{Action: string(c.options.Action)}, evtCh) handleError(evtCh, ErrUnknownExecutorAction{Action: string(c.options.Action)})
} }
} }
@ -92,23 +79,23 @@ func (c *ClusterctlExecutor) move(opts ifc.RunOptions, evtCh chan events.Event)
ns := c.options.MoveOptions.Namespace ns := c.options.MoveOptions.Namespace
kubeConfigFile, cleanup, err := c.kubecfg.GetFile() kubeConfigFile, cleanup, err := c.kubecfg.GetFile()
if err != nil { if err != nil {
c.handleErr(err, evtCh) handleError(evtCh, err)
return return
} }
defer cleanup() defer cleanup()
fromCluster, err := c.clusterMap.ParentCluster(c.clusterName) fromCluster, err := c.clusterMap.ParentCluster(c.clusterName)
if err != nil { if err != nil {
c.handleErr(err, evtCh) handleError(evtCh, err)
return return
} }
fromContext, err := c.clusterMap.ClusterKubeconfigContext(fromCluster) fromContext, err := c.clusterMap.ClusterKubeconfigContext(fromCluster)
if err != nil { if err != nil {
c.handleErr(err, evtCh) handleError(evtCh, err)
return return
} }
toContext, err := c.clusterMap.ClusterKubeconfigContext(c.clusterName) toContext, err := c.clusterMap.ClusterKubeconfigContext(c.clusterName)
if err != nil { if err != nil {
c.handleErr(err, evtCh) handleError(evtCh, err)
return return
} }
@ -117,7 +104,7 @@ func (c *ClusterctlExecutor) move(opts ifc.RunOptions, evtCh chan events.Event)
if !opts.DryRun { if !opts.DryRun {
err = c.Move(kubeConfigFile, fromContext, kubeConfigFile, toContext, ns) err = c.Move(kubeConfigFile, fromContext, kubeConfigFile, toContext, ns)
if err != nil { if err != nil {
c.handleErr(err, evtCh) handleError(evtCh, err)
return return
} }
} }
@ -135,7 +122,7 @@ func (c *ClusterctlExecutor) init(opts ifc.RunOptions, evtCh chan events.Event)
}) })
kubeConfigFile, cleanup, err := c.kubecfg.GetFile() kubeConfigFile, cleanup, err := c.kubecfg.GetFile()
if err != nil { if err != nil {
c.handleErr(err, evtCh) handleError(evtCh, err)
return return
} }
@ -153,14 +140,14 @@ func (c *ClusterctlExecutor) init(opts ifc.RunOptions, evtCh chan events.Event)
context, err := c.clusterMap.ClusterKubeconfigContext(c.clusterName) context, err := c.clusterMap.ClusterKubeconfigContext(c.clusterName)
if err != nil { if err != nil {
c.handleErr(err, evtCh) handleError(evtCh, err)
return return
} }
// Use cluster name as context in kubeconfig file // Use cluster name as context in kubeconfig file
err = c.Init(kubeConfigFile, context) err = c.Init(kubeConfigFile, context)
if err != nil { if err != nil {
c.handleErr(err, evtCh) handleError(evtCh, err)
return return
} }
evtCh <- events.NewEvent().WithClusterctlEvent(events.ClusterctlEvent{ evtCh <- events.NewEvent().WithClusterctlEvent(events.ClusterctlEvent{
@ -169,12 +156,6 @@ func (c *ClusterctlExecutor) init(opts ifc.RunOptions, evtCh chan events.Event)
}) })
} }
func (c *ClusterctlExecutor) handleErr(err error, evtCh chan events.Event) {
evtCh <- events.NewEvent().WithErrorEvent(events.ErrorEvent{
Error: err,
})
}
// Validate executor configuration and documents // Validate executor configuration and documents
func (c *ClusterctlExecutor) Validate() error { func (c *ClusterctlExecutor) Validate() error {
return errors.ErrNotImplemented{} return errors.ErrNotImplemented{}

View File

@ -23,17 +23,14 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/runtime/schema"
"opendev.org/airship/airshipctl/pkg/api/v1alpha1" "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
"opendev.org/airship/airshipctl/pkg/cluster/clustermap" "opendev.org/airship/airshipctl/pkg/cluster/clustermap"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/document" "opendev.org/airship/airshipctl/pkg/document"
airerrors "opendev.org/airship/airshipctl/pkg/errors" airerrors "opendev.org/airship/airshipctl/pkg/errors"
"opendev.org/airship/airshipctl/pkg/events" "opendev.org/airship/airshipctl/pkg/events"
"opendev.org/airship/airshipctl/pkg/fs" "opendev.org/airship/airshipctl/pkg/fs"
"opendev.org/airship/airshipctl/pkg/k8s/kubeconfig" "opendev.org/airship/airshipctl/pkg/k8s/kubeconfig"
"opendev.org/airship/airshipctl/pkg/phase"
"opendev.org/airship/airshipctl/pkg/phase/executors" "opendev.org/airship/airshipctl/pkg/phase/executors"
"opendev.org/airship/airshipctl/pkg/phase/ifc" "opendev.org/airship/airshipctl/pkg/phase/ifc"
testfs "opendev.org/airship/airshipctl/testutil/fs" testfs "opendev.org/airship/airshipctl/testutil/fs"
@ -59,22 +56,8 @@ providers:
v0.3.3: manifests/function/capi/v0.3.3` v0.3.3: manifests/function/capi/v0.3.3`
) )
func TestRegisterExecutor(t *testing.T) {
registry := make(map[schema.GroupVersionKind]ifc.ExecutorFactory)
expectedGVK := schema.GroupVersionKind{
Group: "airshipit.org",
Version: "v1alpha1",
Kind: "Clusterctl",
}
err := executors.RegisterExecutor(registry)
require.NoError(t, err)
_, found := registry[expectedGVK]
assert.True(t, found)
}
func TestNewExecutor(t *testing.T) { func TestNewExecutor(t *testing.T) {
sampleCfgDoc := executorDoc(t, "init") sampleCfgDoc := executorDoc(t, fmt.Sprintf(executorConfigTmpl, "init"))
testCases := []struct { testCases := []struct {
name string name string
helper ifc.Helper helper ifc.Helper
@ -82,13 +65,13 @@ func TestNewExecutor(t *testing.T) {
}{ }{
{ {
name: "New Clusterctl Executor", name: "New Clusterctl Executor",
helper: makeDefaultHelper(t), helper: makeDefaultHelper(t, "../../clusterctl/client/testdata"),
}, },
} }
for _, test := range testCases { for _, test := range testCases {
tt := test tt := test
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
_, actualErr := executors.NewExecutor(ifc.ExecutorConfig{ _, actualErr := executors.NewClusterctlExecutor(ifc.ExecutorConfig{
ExecutorDocument: sampleCfgDoc, ExecutorDocument: sampleCfgDoc,
Helper: tt.helper, Helper: tt.helper,
}) })
@ -110,7 +93,7 @@ func TestExecutorRun(t *testing.T) {
}{ }{
{ {
name: "Error unknown action", name: "Error unknown action",
cfgDoc: executorDoc(t, "someAction"), cfgDoc: executorDoc(t, fmt.Sprintf(executorConfigTmpl, "someAction")),
bundlePath: "testdata/executor_init", bundlePath: "testdata/executor_init",
expectedEvt: []events.Event{ expectedEvt: []events.Event{
wrapError(executors.ErrUnknownExecutorAction{Action: "someAction"}), wrapError(executors.ErrUnknownExecutorAction{Action: "someAction"}),
@ -119,7 +102,7 @@ func TestExecutorRun(t *testing.T) {
}, },
{ {
name: "Error temporary file", name: "Error temporary file",
cfgDoc: executorDoc(t, "init"), cfgDoc: executorDoc(t, fmt.Sprintf(executorConfigTmpl, "init")),
fs: testfs.MockFileSystem{ fs: testfs.MockFileSystem{
MockTempFile: func(string, string) (fs.File, error) { MockTempFile: func(string, string) (fs.File, error) {
return nil, errTmpFile return nil, errTmpFile
@ -136,7 +119,7 @@ func TestExecutorRun(t *testing.T) {
}, },
{ {
name: "Regular Run init", name: "Regular Run init",
cfgDoc: executorDoc(t, "init"), cfgDoc: executorDoc(t, fmt.Sprintf(executorConfigTmpl, "init")),
fs: testfs.MockFileSystem{ fs: testfs.MockFileSystem{
MockTempFile: func(string, string) (fs.File, error) { MockTempFile: func(string, string) (fs.File, error) {
return testfs.TestFile{ return testfs.TestFile{
@ -167,10 +150,10 @@ func TestExecutorRun(t *testing.T) {
kubeconfig.FromByte([]byte("someKubeConfig")), kubeconfig.FromByte([]byte("someKubeConfig")),
kubeconfig.InjectFileSystem(tt.fs), kubeconfig.InjectFileSystem(tt.fs),
) )
executor, err := executors.NewExecutor( executor, err := executors.NewClusterctlExecutor(
ifc.ExecutorConfig{ ifc.ExecutorConfig{
ExecutorDocument: tt.cfgDoc, ExecutorDocument: tt.cfgDoc,
Helper: makeDefaultHelper(t), Helper: makeDefaultHelper(t, "../../clusterctl/client/testdata"),
KubeConfig: kubeCfg, KubeConfig: kubeCfg,
ClusterMap: tt.clusterMap, ClusterMap: tt.clusterMap,
}) })
@ -197,11 +180,11 @@ func TestExecutorRun(t *testing.T) {
} }
func TestExecutorValidate(t *testing.T) { func TestExecutorValidate(t *testing.T) {
sampleCfgDoc := executorDoc(t, "init") sampleCfgDoc := executorDoc(t, fmt.Sprintf(executorConfigTmpl, "init"))
executor, err := executors.NewExecutor( executor, err := executors.NewClusterctlExecutor(
ifc.ExecutorConfig{ ifc.ExecutorConfig{
ExecutorDocument: sampleCfgDoc, ExecutorDocument: sampleCfgDoc,
Helper: makeDefaultHelper(t), Helper: makeDefaultHelper(t, "../../clusterctl/client/testdata"),
}) })
require.NoError(t, err) require.NoError(t, err)
expectedErr := airerrors.ErrNotImplemented{} expectedErr := airerrors.ErrNotImplemented{}
@ -210,11 +193,11 @@ func TestExecutorValidate(t *testing.T) {
} }
func TestExecutorRender(t *testing.T) { func TestExecutorRender(t *testing.T) {
sampleCfgDoc := executorDoc(t, "init") sampleCfgDoc := executorDoc(t, fmt.Sprintf(executorConfigTmpl, "init"))
executor, err := executors.NewExecutor( executor, err := executors.NewClusterctlExecutor(
ifc.ExecutorConfig{ ifc.ExecutorConfig{
ExecutorDocument: sampleCfgDoc, ExecutorDocument: sampleCfgDoc,
Helper: makeDefaultHelper(t), Helper: makeDefaultHelper(t, "../../clusterctl/client/testdata"),
}) })
require.NoError(t, err) require.NoError(t, err)
actualOut := &bytes.Buffer{} actualOut := &bytes.Buffer{}
@ -222,29 +205,3 @@ func TestExecutorRender(t *testing.T) {
assert.Len(t, actualOut.Bytes(), 0) assert.Len(t, actualOut.Bytes(), 0)
assert.NoError(t, actualErr) assert.NoError(t, actualErr)
} }
func makeDefaultHelper(t *testing.T) ifc.Helper {
t.Helper()
cfg := config.NewConfig()
cfg.Manifests[config.AirshipDefaultManifest].TargetPath = "../../clusterctl/client/testdata"
cfg.Manifests[config.AirshipDefaultManifest].MetadataPath = "metadata.yaml"
cfg.Manifests[config.AirshipDefaultManifest].Repositories[config.DefaultTestPhaseRepo].URLString = ""
cfg.SetLoadedConfigPath(".")
helper, err := phase.NewHelper(cfg)
require.NoError(t, err)
require.NotNil(t, helper)
return helper
}
func executorDoc(t *testing.T, action string) document.Document {
cfg := []byte(fmt.Sprintf(executorConfigTmpl, action))
cfgDoc, err := document.NewDocumentFromBytes(cfg)
require.NoError(t, err)
return cfgDoc
}
func wrapError(err error) events.Event {
return events.NewEvent().WithErrorEvent(events.ErrorEvent{
Error: err,
})
}

71
pkg/phase/executors/common.go Executable file
View File

@ -0,0 +1,71 @@
/*
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 executors
import (
"k8s.io/apimachinery/pkg/runtime/schema"
airshipv1 "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
"opendev.org/airship/airshipctl/pkg/events"
"opendev.org/airship/airshipctl/pkg/phase/ifc"
)
// Constants related to phase executor names
const (
Clusterctl = "clusterctl"
KubernetesApply = "kubernetes-apply"
Isogen = "isogen"
GenericContainer = "generic-container"
Ephemeral = "ephemeral"
)
// RegisterExecutor adds executor to phase executor registry
func RegisterExecutor(executorName string, registry map[schema.GroupVersionKind]ifc.ExecutorFactory) error {
var gvks []schema.GroupVersionKind
var execObj ifc.ExecutorFactory
var err error
switch executorName {
case Clusterctl:
gvks, _, err = airshipv1.Scheme.ObjectKinds(&airshipv1.Clusterctl{})
execObj = NewClusterctlExecutor
case KubernetesApply:
gvks, _, err = airshipv1.Scheme.ObjectKinds(&airshipv1.KubernetesApply{})
execObj = NewKubeApplierExecutor
case Isogen:
gvks, _, err = airshipv1.Scheme.ObjectKinds(airshipv1.DefaultIsoConfiguration())
execObj = NewIsogenExecutor
case GenericContainer:
gvks, _, err = airshipv1.Scheme.ObjectKinds(airshipv1.DefaultGenericContainer())
execObj = NewContainerExecutor
case Ephemeral:
gvks, _, err = airshipv1.Scheme.ObjectKinds(airshipv1.DefaultBootConfiguration())
execObj = NewEphemeralExecutor
default:
return ErrUnknownExecutorName{ExecutorName: executorName}
}
if err != nil {
return err
}
registry[gvks[0]] = execObj
return nil
}
func handleError(ch chan<- events.Event, err error) {
ch <- events.NewEvent().WithErrorEvent(events.ErrorEvent{
Error: err,
})
}

View File

@ -0,0 +1,134 @@
/*
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 executors_test
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/runtime/schema"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/document"
"opendev.org/airship/airshipctl/pkg/events"
"opendev.org/airship/airshipctl/pkg/phase"
"opendev.org/airship/airshipctl/pkg/phase/executors"
"opendev.org/airship/airshipctl/pkg/phase/ifc"
)
func TestRegisterExecutor(t *testing.T) {
testCases := []struct {
name string
executorName string
registry map[schema.GroupVersionKind]ifc.ExecutorFactory
expectedGVK schema.GroupVersionKind
expectedErr error
}{
{
name: "register clusterctl executor",
executorName: executors.Clusterctl,
registry: make(map[schema.GroupVersionKind]ifc.ExecutorFactory),
expectedGVK: schema.GroupVersionKind{
Group: "airshipit.org",
Version: "v1alpha1",
Kind: "Clusterctl",
},
},
{
name: "register container executor",
executorName: executors.GenericContainer,
registry: make(map[schema.GroupVersionKind]ifc.ExecutorFactory),
expectedGVK: schema.GroupVersionKind{
Group: "airshipit.org",
Version: "v1alpha1",
Kind: "GenericContainer",
},
},
{
name: "register isogen executor",
executorName: executors.Isogen,
registry: make(map[schema.GroupVersionKind]ifc.ExecutorFactory),
expectedGVK: schema.GroupVersionKind{
Group: "airshipit.org",
Version: "v1alpha1",
Kind: "IsoConfiguration",
},
},
{
name: "register k8s applier executor",
executorName: executors.KubernetesApply,
registry: make(map[schema.GroupVersionKind]ifc.ExecutorFactory),
expectedGVK: schema.GroupVersionKind{
Group: "airshipit.org",
Version: "v1alpha1",
Kind: "KubernetesApply",
},
},
{
name: "register ephemeral executor",
executorName: executors.Ephemeral,
registry: make(map[schema.GroupVersionKind]ifc.ExecutorFactory),
expectedGVK: schema.GroupVersionKind{
Group: "airshipit.org",
Version: "v1alpha1",
Kind: "BootConfiguration",
},
},
}
for _, test := range testCases {
tt := test
t.Run(tt.name, func(t *testing.T) {
err := executors.RegisterExecutor(tt.executorName, tt.registry)
require.NoError(t, err)
_, found := tt.registry[tt.expectedGVK]
assert.True(t, found)
})
}
}
func makeDefaultHelper(t *testing.T, targetPath string) ifc.Helper {
t.Helper()
cfg := config.NewConfig()
cfg.Manifests[config.AirshipDefaultManifest].TargetPath = targetPath
cfg.Manifests[config.AirshipDefaultManifest].MetadataPath = "metadata.yaml"
cfg.Manifests[config.AirshipDefaultManifest].Repositories[config.DefaultTestPhaseRepo].URLString = ""
cfg.SetLoadedConfigPath(".")
helper, err := phase.NewHelper(cfg)
require.NoError(t, err)
require.NotNil(t, helper)
return helper
}
// executorDoc converts string to document object
func executorDoc(t *testing.T, s string) document.Document {
doc, err := document.NewDocumentFromBytes([]byte(s))
require.NoError(t, err)
require.NotNil(t, doc)
return doc
}
func testBundleFactory(path string) document.BundleFactoryFunc {
return func() (document.Bundle, error) {
return document.NewBundleByPath(path)
}
}
func wrapError(err error) events.Event {
return events.NewEvent().WithErrorEvent(events.ErrorEvent{
Error: err,
})
}

View File

@ -26,8 +26,6 @@ import (
kyaml "sigs.k8s.io/kustomize/kyaml/yaml" kyaml "sigs.k8s.io/kustomize/kyaml/yaml"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
"k8s.io/apimachinery/pkg/runtime/schema"
"opendev.org/airship/airshipctl/pkg/api/v1alpha1" "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
"opendev.org/airship/airshipctl/pkg/document" "opendev.org/airship/airshipctl/pkg/document"
"opendev.org/airship/airshipctl/pkg/errors" "opendev.org/airship/airshipctl/pkg/errors"
@ -47,17 +45,6 @@ type ContainerExecutor struct {
targetPath string targetPath string
} }
// RegisterContainerExecutor adds executor to phase executor registry
func RegisterContainerExecutor(registry map[schema.GroupVersionKind]ifc.ExecutorFactory) error {
obj := v1alpha1.DefaultGenericContainer()
gvks, _, err := v1alpha1.Scheme.ObjectKinds(obj)
if err != nil {
return err
}
registry[gvks[0]] = NewContainerExecutor
return nil
}
// NewContainerExecutor creates instance of phase executor // NewContainerExecutor creates instance of phase executor
func NewContainerExecutor(cfg ifc.ExecutorConfig) (ifc.Executor, error) { func NewContainerExecutor(cfg ifc.ExecutorConfig) (ifc.Executor, error) {
bundle, err := cfg.BundleFactory() bundle, err := cfg.BundleFactory()

View File

@ -20,15 +20,12 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/kustomize/kyaml/fn/runtime/runtimeutil" "sigs.k8s.io/kustomize/kyaml/fn/runtime/runtimeutil"
"sigs.k8s.io/kustomize/kyaml/runfn" "sigs.k8s.io/kustomize/kyaml/runfn"
kyaml "sigs.k8s.io/kustomize/kyaml/yaml" kyaml "sigs.k8s.io/kustomize/kyaml/yaml"
"opendev.org/airship/airshipctl/pkg/api/v1alpha1" "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/document" "opendev.org/airship/airshipctl/pkg/document"
"opendev.org/airship/airshipctl/pkg/phase"
"opendev.org/airship/airshipctl/pkg/phase/executors" "opendev.org/airship/airshipctl/pkg/phase/executors"
"opendev.org/airship/airshipctl/pkg/phase/ifc" "opendev.org/airship/airshipctl/pkg/phase/ifc"
yaml_util "opendev.org/airship/airshipctl/pkg/util/yaml" yaml_util "opendev.org/airship/airshipctl/pkg/util/yaml"
@ -109,27 +106,13 @@ type: Opaque
` `
) )
func TestRegisterContainerExecutor(t *testing.T) {
registry := make(map[schema.GroupVersionKind]ifc.ExecutorFactory)
expectedGVK := schema.GroupVersionKind{
Group: "airshipit.org",
Version: "v1alpha1",
Kind: "GenericContainer",
}
err := executors.RegisterContainerExecutor(registry)
require.NoError(t, err)
_, found := registry[expectedGVK]
assert.True(t, found)
}
func TestNewContainerExecutor(t *testing.T) { func TestNewContainerExecutor(t *testing.T) {
execDoc, err := document.NewDocumentFromBytes([]byte(containerExecutorDoc)) execDoc, err := document.NewDocumentFromBytes([]byte(containerExecutorDoc))
require.NoError(t, err) require.NoError(t, err)
_, err = executors.NewContainerExecutor(ifc.ExecutorConfig{ _, err = executors.NewContainerExecutor(ifc.ExecutorConfig{
ExecutorDocument: execDoc, ExecutorDocument: execDoc,
BundleFactory: testBundleFactory(singleExecutorBundlePath), BundleFactory: testBundleFactory(singleExecutorBundlePath),
Helper: makeDefaultContainerHelper(t), Helper: makeDefaultHelper(t, "../../container/testdata"),
}) })
require.NoError(t, err) require.NoError(t, err)
} }
@ -236,16 +219,3 @@ func TestPrepareFunctions(t *testing.T) {
assert.Equal(t, transformedFunction, strFuncs) assert.Equal(t, transformedFunction, strFuncs)
} }
func makeDefaultContainerHelper(t *testing.T) ifc.Helper {
t.Helper()
cfg := config.NewConfig()
cfg.Manifests[config.AirshipDefaultManifest].TargetPath = "../../container/testdata"
cfg.Manifests[config.AirshipDefaultManifest].MetadataPath = "metadata.yaml"
cfg.Manifests[config.AirshipDefaultManifest].Repositories[config.DefaultTestPhaseRepo].URLString = ""
cfg.SetLoadedConfigPath(".")
helper, err := phase.NewHelper(cfg)
require.NoError(t, err)
require.NotNil(t, helper)
return helper
}

View File

@ -19,8 +19,6 @@ import (
"io" "io"
"time" "time"
"k8s.io/apimachinery/pkg/runtime/schema"
"opendev.org/airship/airshipctl/pkg/api/v1alpha1" "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
"opendev.org/airship/airshipctl/pkg/bootstrap/ephemeral" "opendev.org/airship/airshipctl/pkg/bootstrap/ephemeral"
"opendev.org/airship/airshipctl/pkg/container" "opendev.org/airship/airshipctl/pkg/container"
@ -42,17 +40,6 @@ type EphemeralExecutor struct {
Container container.Container Container container.Container
} }
// RegisterEphemeralExecutor adds executor to phase executor registry
func RegisterEphemeralExecutor(registry map[schema.GroupVersionKind]ifc.ExecutorFactory) error {
obj := v1alpha1.DefaultBootConfiguration()
gvks, _, err := v1alpha1.Scheme.ObjectKinds(obj)
if err != nil {
return err
}
registry[gvks[0]] = NewEphemeralExecutor
return nil
}
// NewEphemeralExecutor creates instance of phase executor // NewEphemeralExecutor creates instance of phase executor
func NewEphemeralExecutor(cfg ifc.ExecutorConfig) (ifc.Executor, error) { func NewEphemeralExecutor(cfg ifc.ExecutorConfig) (ifc.Executor, error) {
apiObj := &v1alpha1.BootConfiguration{} apiObj := &v1alpha1.BootConfiguration{}
@ -92,7 +79,7 @@ func (c *EphemeralExecutor) Run(evtCh chan events.Event, opts ifc.RunOptions) {
c.BootConf.BootstrapContainer.ContainerRuntime, c.BootConf.BootstrapContainer.ContainerRuntime,
c.BootConf.BootstrapContainer.Image) c.BootConf.BootstrapContainer.Image)
if err != nil { if err != nil {
handleEphemeralError(evtCh, err) handleError(evtCh, err)
return return
} }
c.Container = builder c.Container = builder
@ -111,7 +98,7 @@ func (c *EphemeralExecutor) Run(evtCh chan events.Event, opts ifc.RunOptions) {
err := bootstrapOpts.VerifyInputs() err := bootstrapOpts.VerifyInputs()
if err != nil { if err != nil {
handleEphemeralError(evtCh, err) handleError(evtCh, err)
return return
} }
@ -122,7 +109,7 @@ func (c *EphemeralExecutor) Run(evtCh chan events.Event, opts ifc.RunOptions) {
err = bootstrapOpts.CreateBootstrapContainer() err = bootstrapOpts.CreateBootstrapContainer()
if err != nil { if err != nil {
handleEphemeralError(evtCh, err) handleError(evtCh, err)
return return
} }
@ -133,7 +120,7 @@ func (c *EphemeralExecutor) Run(evtCh chan events.Event, opts ifc.RunOptions) {
err = bootstrapOpts.VerifyArtifacts() err = bootstrapOpts.VerifyArtifacts()
if err != nil { if err != nil {
handleEphemeralError(evtCh, err) handleError(evtCh, err)
return return
} }
@ -153,12 +140,3 @@ func (c *EphemeralExecutor) Render(w io.Writer, _ ifc.RenderOptions) error {
log.Print("Ephemeral Executor Render() will be implemented later.") log.Print("Ephemeral Executor Render() will be implemented later.")
return nil return nil
} }
func handleEphemeralError(ch chan<- events.Event, err error) {
ch <- events.Event{
Type: events.ErrorType,
ErrorEvent: events.ErrorEvent{
Error: err,
},
}
}

View File

@ -24,8 +24,6 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/runtime/schema"
"opendev.org/airship/airshipctl/pkg/api/v1alpha1" "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
"opendev.org/airship/airshipctl/pkg/bootstrap/ephemeral" "opendev.org/airship/airshipctl/pkg/bootstrap/ephemeral"
"opendev.org/airship/airshipctl/pkg/container" "opendev.org/airship/airshipctl/pkg/container"
@ -57,21 +55,6 @@ bootstrapContainer:
` `
) )
// TestRegisterEphemeralExecutor - Unit testing function RegisterEphemeralExecutor()
func TestRegisterEphemeralExecutor(t *testing.T) {
registry := make(map[schema.GroupVersionKind]ifc.ExecutorFactory)
expectedGVK := schema.GroupVersionKind{
Group: "airshipit.org",
Version: "v1alpha1",
Kind: "BootConfiguration",
}
err := executors.RegisterEphemeralExecutor(registry)
require.NoError(t, err)
_, found := registry[expectedGVK]
assert.True(t, found)
}
// TestNewEphemeralExecutor - Unit testing function NewExecutor() // TestNewEphemeralExecutor - Unit testing function NewExecutor()
func TestNewEphemeralExecutor(t *testing.T) { func TestNewEphemeralExecutor(t *testing.T) {
execDoc, err := document.NewDocumentFromBytes([]byte(executorEphemeralDoc)) execDoc, err := document.NewDocumentFromBytes([]byte(executorEphemeralDoc))

View File

@ -35,3 +35,13 @@ type ErrIsogenNilBundle struct {
func (e ErrIsogenNilBundle) Error() string { func (e ErrIsogenNilBundle) Error() string {
return "Cannot build iso with empty bundle, no data source is available" return "Cannot build iso with empty bundle, no data source is available"
} }
// ErrUnknownExecutorName is returned for unknown executor name parameter
// received by RegisterExecutor function
type ErrUnknownExecutorName struct {
ExecutorName string
}
func (e ErrUnknownExecutorName) Error() string {
return fmt.Sprintf("unknown executor name '%s'", e.ExecutorName)
}

View File

@ -21,8 +21,6 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"k8s.io/apimachinery/pkg/runtime/schema"
"opendev.org/airship/airshipctl/pkg/api/v1alpha1" "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
"opendev.org/airship/airshipctl/pkg/bootstrap/isogen" "opendev.org/airship/airshipctl/pkg/bootstrap/isogen"
"opendev.org/airship/airshipctl/pkg/container" "opendev.org/airship/airshipctl/pkg/container"
@ -44,17 +42,6 @@ type IsogenExecutor struct {
Builder container.Container Builder container.Container
} }
// RegisterIsogenExecutor adds executor to phase executor registry
func RegisterIsogenExecutor(registry map[schema.GroupVersionKind]ifc.ExecutorFactory) error {
obj := v1alpha1.DefaultIsoConfiguration()
gvks, _, err := v1alpha1.Scheme.ObjectKinds(obj)
if err != nil {
return err
}
registry[gvks[0]] = NewIsogenExecutor
return nil
}
// NewIsogenExecutor creates instance of phase executor // NewIsogenExecutor creates instance of phase executor
func NewIsogenExecutor(cfg ifc.ExecutorConfig) (ifc.Executor, error) { func NewIsogenExecutor(cfg ifc.ExecutorConfig) (ifc.Executor, error) {
apiObj := &v1alpha1.IsoConfiguration{ apiObj := &v1alpha1.IsoConfiguration{
@ -161,9 +148,3 @@ func (c *IsogenExecutor) Render(w io.Writer, _ ifc.RenderOptions) error {
_, err := w.Write([]byte{}) _, err := w.Write([]byte{})
return err return err
} }
func handleError(ch chan<- events.Event, err error) {
ch <- events.NewEvent().WithErrorEvent(events.ErrorEvent{
Error: err,
})
}

View File

@ -23,7 +23,6 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/runtime/schema"
"opendev.org/airship/airshipctl/pkg/api/v1alpha1" "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
"opendev.org/airship/airshipctl/pkg/container" "opendev.org/airship/airshipctl/pkg/container"
@ -53,20 +52,6 @@ container:
executorBundlePath = "../../bootstrap/isogen/testdata/primary/site/test-site/ephemeral/bootstrap" executorBundlePath = "../../bootstrap/isogen/testdata/primary/site/test-site/ephemeral/bootstrap"
) )
func TestRegisterIsogenExecutor(t *testing.T) {
registry := make(map[schema.GroupVersionKind]ifc.ExecutorFactory)
expectedGVK := schema.GroupVersionKind{
Group: "airshipit.org",
Version: "v1alpha1",
Kind: "IsoConfiguration",
}
err := executors.RegisterIsogenExecutor(registry)
require.NoError(t, err)
_, found := registry[expectedGVK]
assert.True(t, found)
}
func TestNewIsogenExecutor(t *testing.T) { func TestNewIsogenExecutor(t *testing.T) {
execDoc, err := document.NewDocumentFromBytes([]byte(isogenExecutorDoc)) execDoc, err := document.NewDocumentFromBytes([]byte(isogenExecutorDoc))
require.NoError(t, err) require.NoError(t, err)
@ -176,9 +161,3 @@ func TestIsogenExecutorRun(t *testing.T) {
}) })
} }
} }
func testBundleFactory(path string) document.BundleFactoryFunc {
return func() (document.Bundle, error) {
return document.NewBundleByPath(path)
}
}

View File

@ -18,7 +18,6 @@ import (
"io" "io"
"time" "time"
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/cli-utils/pkg/common" "sigs.k8s.io/cli-utils/pkg/common"
airshipv1 "opendev.org/airship/airshipctl/pkg/api/v1alpha1" airshipv1 "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
@ -33,73 +32,47 @@ import (
"opendev.org/airship/airshipctl/pkg/phase/ifc" "opendev.org/airship/airshipctl/pkg/phase/ifc"
) )
// ExecutorOptions provide a way to configure executor var _ ifc.Executor = &KubeApplierExecutor{}
type ExecutorOptions struct {
BundleName string
ClusterName string
// KubeApplierExecutor applies resources to kubernetes
type KubeApplierExecutor struct {
ExecutorBundle document.Bundle
ExecutorDocument document.Document ExecutorDocument document.Document
BundleFactory document.BundleFactoryFunc BundleName string
Kubeconfig kubeconfig.Interface
Helper ifc.Helper Helper ifc.Helper
ClusterMap clustermap.ClusterMap
}
var _ ifc.Executor = &Executor{} apiObject *airshipv1.KubernetesApply
cleanup kubeconfig.Cleanup
// RegisterKubeApplierExecutor adds executor to phase executor registry clusterMap clustermap.ClusterMap
func RegisterKubeApplierExecutor(registry map[schema.GroupVersionKind]ifc.ExecutorFactory) error { clusterName string
obj := &airshipv1.KubernetesApply{} kubeconfig kubeconfig.Interface
gvks, _, err := airshipv1.Scheme.ObjectKinds(obj)
if err != nil {
return err
}
registry[gvks[0]] = registerExecutor
return nil
}
// registerExecutor is here so that executor in theory can be used outside phases
func registerExecutor(cfg ifc.ExecutorConfig) (ifc.Executor, error) {
return NewKubeApplierExecutor(ExecutorOptions{
ClusterName: cfg.ClusterName,
BundleName: cfg.PhaseName,
Helper: cfg.Helper,
ExecutorDocument: cfg.ExecutorDocument,
BundleFactory: cfg.BundleFactory,
Kubeconfig: cfg.KubeConfig,
ClusterMap: cfg.ClusterMap,
})
}
// Executor applies resources to kubernetes
type Executor struct {
Options ExecutorOptions
ExecutorBundle document.Bundle
apiObject *airshipv1.KubernetesApply
cleanup kubeconfig.Cleanup
} }
// NewKubeApplierExecutor returns instance of executor // NewKubeApplierExecutor returns instance of executor
func NewKubeApplierExecutor(opts ExecutorOptions) (*Executor, error) { func NewKubeApplierExecutor(cfg ifc.ExecutorConfig) (ifc.Executor, error) {
apiObj := &airshipv1.KubernetesApply{} apiObj := &airshipv1.KubernetesApply{}
err := opts.ExecutorDocument.ToAPIObject(apiObj, airshipv1.Scheme) err := cfg.ExecutorDocument.ToAPIObject(apiObj, airshipv1.Scheme)
if err != nil { if err != nil {
return nil, err return nil, err
} }
bundle, err := opts.BundleFactory() bundle, err := cfg.BundleFactory()
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &Executor{ return &KubeApplierExecutor{
ExecutorBundle: bundle, ExecutorBundle: bundle,
Options: opts, BundleName: cfg.PhaseName,
apiObject: apiObj, Helper: cfg.Helper,
ExecutorDocument: cfg.ExecutorDocument,
apiObject: apiObj,
clusterMap: cfg.ClusterMap,
clusterName: cfg.ClusterName,
kubeconfig: cfg.KubeConfig,
}, nil }, nil
} }
// Run executor, should be performed in separate go routine // Run executor, should be performed in separate go routine
func (e *Executor) Run(ch chan events.Event, runOpts ifc.RunOptions) { func (e *KubeApplierExecutor) Run(ch chan events.Event, runOpts ifc.RunOptions) {
applier, filteredBundle, err := e.prepareApplier(ch) applier, filteredBundle, err := e.prepareApplier(ch)
if err != nil { if err != nil {
handleError(ch, err) handleError(ch, err)
@ -120,20 +93,20 @@ func (e *Executor) Run(ch chan events.Event, runOpts ifc.RunOptions) {
applyOptions := k8sapplier.ApplyOptions{ applyOptions := k8sapplier.ApplyOptions{
DryRunStrategy: dryRunStrategy, DryRunStrategy: dryRunStrategy,
Prune: e.apiObject.Config.PruneOptions.Prune, Prune: e.apiObject.Config.PruneOptions.Prune,
BundleName: e.Options.BundleName, BundleName: e.BundleName,
WaitTimeout: timeout, WaitTimeout: timeout,
} }
applier.ApplyBundle(filteredBundle, applyOptions) applier.ApplyBundle(filteredBundle, applyOptions)
} }
func (e *Executor) prepareApplier(ch chan events.Event) (*k8sapplier.Applier, document.Bundle, error) { func (e *KubeApplierExecutor) prepareApplier(ch chan events.Event) (*k8sapplier.Applier, document.Bundle, error) {
log.Debug("Getting kubeconfig context name from cluster map") log.Debug("Getting kubeconfig context name from cluster map")
context, err := e.Options.ClusterMap.ClusterKubeconfigContext(e.Options.ClusterName) context, err := e.clusterMap.ClusterKubeconfigContext(e.clusterName)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
log.Debug("Getting kubeconfig file information from kubeconfig provider") log.Debug("Getting kubeconfig file information from kubeconfig provider")
path, cleanup, err := e.Options.Kubeconfig.GetFile() path, cleanup, err := e.kubeconfig.GetFile()
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -151,12 +124,12 @@ func (e *Executor) prepareApplier(ch chan events.Event) (*k8sapplier.Applier, do
} }
// Validate document set // Validate document set
func (e *Executor) Validate() error { func (e *KubeApplierExecutor) Validate() error {
return errors.ErrNotImplemented{} return errors.ErrNotImplemented{}
} }
// Render document set // Render document set
func (e *Executor) Render(w io.Writer, o ifc.RenderOptions) error { func (e *KubeApplierExecutor) Render(w io.Writer, o ifc.RenderOptions) error {
bundle, err := e.ExecutorBundle.SelectBundle(o.FilterSelector) bundle, err := e.ExecutorBundle.SelectBundle(o.FilterSelector)
if err != nil { if err != nil {
return err return err

View File

@ -23,13 +23,11 @@ import (
"opendev.org/airship/airshipctl/pkg/api/v1alpha1" "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
"opendev.org/airship/airshipctl/pkg/cluster/clustermap" "opendev.org/airship/airshipctl/pkg/cluster/clustermap"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/document" "opendev.org/airship/airshipctl/pkg/document"
"opendev.org/airship/airshipctl/pkg/events" "opendev.org/airship/airshipctl/pkg/events"
"opendev.org/airship/airshipctl/pkg/fs" "opendev.org/airship/airshipctl/pkg/fs"
"opendev.org/airship/airshipctl/pkg/k8s/kubeconfig" "opendev.org/airship/airshipctl/pkg/k8s/kubeconfig"
"opendev.org/airship/airshipctl/pkg/k8s/utils" "opendev.org/airship/airshipctl/pkg/k8s/utils"
"opendev.org/airship/airshipctl/pkg/phase"
"opendev.org/airship/airshipctl/pkg/phase/executors" "opendev.org/airship/airshipctl/pkg/phase/executors"
"opendev.org/airship/airshipctl/pkg/phase/ifc" "opendev.org/airship/airshipctl/pkg/phase/ifc"
testfs "opendev.org/airship/airshipctl/testutil/fs" testfs "opendev.org/airship/airshipctl/testutil/fs"
@ -96,7 +94,7 @@ func TestNewKubeApplierExecutor(t *testing.T) {
name: "valid executor", name: "valid executor",
cfgDoc: ValidExecutorDoc, cfgDoc: ValidExecutorDoc,
kubeconf: testKubeconfig(testValidKubeconfig), kubeconf: testKubeconfig(testValidKubeconfig),
helper: makeKubeApplierDefaultHelper(t), helper: makeDefaultHelper(t, "../../k8s/applier/testdata"),
bundleFactory: testBundleFactory("../../k8s/applier/testdata/source_bundle"), bundleFactory: testBundleFactory("../../k8s/applier/testdata/source_bundle"),
}, },
{ {
@ -109,7 +107,7 @@ metadata:
labels: labels:
cli-utils.sigs.k8s.io/inventory-id: "some id"`, cli-utils.sigs.k8s.io/inventory-id: "some id"`,
expectedErr: "wrong config document", expectedErr: "wrong config document",
helper: makeKubeApplierDefaultHelper(t), helper: makeDefaultHelper(t, "../../k8s/applier/testdata"),
bundleFactory: testBundleFactory("../../k8s/applier/testdata/source_bundle"), bundleFactory: testBundleFactory("../../k8s/applier/testdata/source_bundle"),
}, },
@ -118,7 +116,7 @@ metadata:
cfgDoc: ValidExecutorDoc, cfgDoc: ValidExecutorDoc,
expectedErr: "no such file or directory", expectedErr: "no such file or directory",
kubeconf: testKubeconfig(testValidKubeconfig), kubeconf: testKubeconfig(testValidKubeconfig),
helper: makeKubeApplierDefaultHelper(t), helper: makeDefaultHelper(t, "../../k8s/applier/testdata"),
bundleFactory: testBundleFactory("does not exist"), bundleFactory: testBundleFactory("does not exist"),
}, },
} }
@ -131,10 +129,10 @@ metadata:
require.NotNil(t, doc) require.NotNil(t, doc)
exec, err := executors.NewKubeApplierExecutor( exec, err := executors.NewKubeApplierExecutor(
executors.ExecutorOptions{ ifc.ExecutorConfig{
ExecutorDocument: doc, ExecutorDocument: doc,
BundleFactory: tt.bundleFactory, BundleFactory: tt.bundleFactory,
Kubeconfig: tt.kubeconf, KubeConfig: tt.kubeconf,
Helper: tt.helper, Helper: tt.helper,
}) })
if tt.expectedErr != "" { if tt.expectedErr != "" {
@ -167,10 +165,10 @@ func TestKubeApplierExecutorRun(t *testing.T) {
{ {
name: "cant read kubeconfig error", name: "cant read kubeconfig error",
containsErr: "no such file or directory", containsErr: "no such file or directory",
helper: makeKubeApplierDefaultHelper(t), helper: makeDefaultHelper(t, "../../k8s/applier/testdata"),
bundleFactory: testBundleFactory("../../k8s/applier/testdata/source_bundle"), bundleFactory: testBundleFactory("../../k8s/applier/testdata/source_bundle"),
kubeconf: testKubeconfig(`invalid kubeconfig`), kubeconf: testKubeconfig(`invalid kubeconfig`),
execDoc: toKubernetesApply(t, ValidExecutorDocNamespaced), execDoc: executorDoc(t, ValidExecutorDocNamespaced),
clusterName: "ephemeral-cluster", clusterName: "ephemeral-cluster",
clusterMap: clustermap.NewClusterMap(&v1alpha1.ClusterMap{ clusterMap: clustermap.NewClusterMap(&v1alpha1.ClusterMap{
Map: map[string]*v1alpha1.Cluster{ Map: map[string]*v1alpha1.Cluster{
@ -181,10 +179,10 @@ func TestKubeApplierExecutorRun(t *testing.T) {
{ {
name: "error cluster not defined", name: "error cluster not defined",
containsErr: "cluster is not defined in in cluster map", containsErr: "cluster is not defined in in cluster map",
helper: makeKubeApplierDefaultHelper(t), helper: makeDefaultHelper(t, "../../k8s/applier/testdata"),
bundleFactory: testBundleFactory("../../k8s/applier/testdata/source_bundle"), bundleFactory: testBundleFactory("../../k8s/applier/testdata/source_bundle"),
kubeconf: testKubeconfig(testValidKubeconfig), kubeconf: testKubeconfig(testValidKubeconfig),
execDoc: toKubernetesApply(t, ValidExecutorDocNamespaced), execDoc: executorDoc(t, ValidExecutorDocNamespaced),
clusterMap: clustermap.NewClusterMap(v1alpha1.DefaultClusterMap()), clusterMap: clustermap.NewClusterMap(v1alpha1.DefaultClusterMap()),
}, },
} }
@ -192,11 +190,11 @@ func TestKubeApplierExecutorRun(t *testing.T) {
tt := tt tt := tt
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
exec, err := executors.NewKubeApplierExecutor( exec, err := executors.NewKubeApplierExecutor(
executors.ExecutorOptions{ ifc.ExecutorConfig{
ExecutorDocument: tt.execDoc, ExecutorDocument: tt.execDoc,
Helper: tt.helper, Helper: tt.helper,
BundleFactory: tt.bundleFactory, BundleFactory: tt.bundleFactory,
Kubeconfig: tt.kubeconf, KubeConfig: tt.kubeconf,
ClusterMap: tt.clusterMap, ClusterMap: tt.clusterMap,
ClusterName: tt.clusterName, ClusterName: tt.clusterName,
}) })
@ -225,7 +223,7 @@ func TestRender(t *testing.T) {
execDoc, err := document.NewDocumentFromBytes([]byte(ValidExecutorDoc)) execDoc, err := document.NewDocumentFromBytes([]byte(ValidExecutorDoc))
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, execDoc) require.NotNil(t, execDoc)
exec, err := executors.NewKubeApplierExecutor(executors.ExecutorOptions{ exec, err := executors.NewKubeApplierExecutor(ifc.ExecutorConfig{
BundleFactory: testBundleFactory("../../k8s/applier/testdata/source_bundle"), BundleFactory: testBundleFactory("../../k8s/applier/testdata/source_bundle"),
ExecutorDocument: execDoc, ExecutorDocument: execDoc,
}) })
@ -240,42 +238,6 @@ func TestRender(t *testing.T) {
assert.Contains(t, result, "ReplicationController") assert.Contains(t, result, "ReplicationController")
} }
func makeKubeApplierDefaultHelper(t *testing.T) ifc.Helper {
t.Helper()
conf := &config.Config{
CurrentContext: "default",
Contexts: map[string]*config.Context{
"default": {
Manifest: "default-manifest",
},
},
Manifests: map[string]*config.Manifest{
"default-manifest": {
MetadataPath: "metadata.yaml",
TargetPath: "../../k8s/applier/testdata",
PhaseRepositoryName: config.DefaultTestPhaseRepo,
Repositories: map[string]*config.Repository{
config.DefaultTestPhaseRepo: {
URLString: "",
},
},
},
},
}
helper, err := phase.NewHelper(conf)
require.NoError(t, err)
require.NotNil(t, helper)
return helper
}
// toKubernetesApply converts string to document object
func toKubernetesApply(t *testing.T, s string) document.Document {
doc, err := document.NewDocumentFromBytes([]byte(s))
require.NoError(t, err)
require.NotNil(t, doc)
return doc
}
func testKubeconfig(stringData string) kubeconfig.Interface { func testKubeconfig(stringData string) kubeconfig.Interface {
return kubeconfig.NewKubeConfig( return kubeconfig.NewKubeConfig(
kubeconfig.FromByte([]byte(stringData)), kubeconfig.FromByte([]byte(stringData)),

View File

@ -57,6 +57,7 @@ type ExecutorFactory func(config ExecutorConfig) (Executor, error)
type ExecutorConfig struct { type ExecutorConfig struct {
PhaseName string PhaseName string
ClusterName string ClusterName string
BundleName string
ClusterMap clustermap.ClusterMap ClusterMap clustermap.ClusterMap
ExecutorDocument document.Document ExecutorDocument document.Document