diff --git a/pkg/api/v1alpha1/phase_types.go b/pkg/api/v1alpha1/phase_types.go index 7ed4394cc..9f79373db 100644 --- a/pkg/api/v1alpha1/phase_types.go +++ b/pkg/api/v1alpha1/phase_types.go @@ -38,8 +38,6 @@ type PhaseConfig struct { // DefaultPhase can be used to safely unmarshal phase object without nil pointers func DefaultPhase() *Phase { return &Phase{ - Config: PhaseConfig{ - ExecutorRef: &corev1.ObjectReference{}, - }, + Config: PhaseConfig{}, } } diff --git a/pkg/phase/errors.go b/pkg/phase/errors.go index ce2573dd0..7a888f14c 100644 --- a/pkg/phase/errors.go +++ b/pkg/phase/errors.go @@ -51,3 +51,15 @@ func (e ErrDocumentEntrypointNotDefined) Error() string { e.PhaseName, e.PhaseNamespace) } + +// ErrExecutorRefNotDefined returned when phase has no entrypoint defined and phase needs it +type ErrExecutorRefNotDefined struct { + PhaseName string + PhaseNamespace string +} + +func (e ErrExecutorRefNotDefined) Error() string { + return fmt.Sprintf("Phase name '%s', namespace '%s' must have executorRef field defined in config", + e.PhaseName, + e.PhaseNamespace) +} diff --git a/pkg/phase/helper.go b/pkg/phase/helper.go index b530fa580..aca4712ce 100644 --- a/pkg/phase/helper.go +++ b/pkg/phase/helper.go @@ -186,6 +186,10 @@ func (helper *Helper) ExecutorDoc(phaseID ifc.ID) (document.Document, error) { } phaseConfig := phaseObj.Config + if phaseConfig.ExecutorRef == nil { + return nil, ErrExecutorRefNotDefined{PhaseName: phaseID.Name, PhaseNamespace: phaseID.Namespace} + } + // Searching executor configuration document referenced in // phase configuration refGVK := phaseConfig.ExecutorRef.GroupVersionKind() diff --git a/pkg/phase/helper_test.go b/pkg/phase/helper_test.go index 23dd03efd..bdfbbd787 100644 --- a/pkg/phase/helper_test.go +++ b/pkg/phase/helper_test.go @@ -194,7 +194,7 @@ func TestHelperListPhases(t *testing.T) { }{ { name: "Success phase list", - phaseLen: 3, + phaseLen: 4, config: testConfig, }, { @@ -372,6 +372,14 @@ func TestHelperExecutorDoc(t *testing.T) { }, errContains: "no such file or directory", }, + { + name: "Error get phase without executor", + config: testConfig, + phaseID: ifc.ID{Name: "no_executor_phase"}, + errContains: phase.ErrExecutorRefNotDefined{ + PhaseName: "no_executor_phase", + }.Error(), + }, } for _, test := range testCases { diff --git a/pkg/phase/testdata/valid_site/phases/kustomization.yaml b/pkg/phase/testdata/valid_site/phases/kustomization.yaml index 977c07f9d..fc7e6fbd1 100644 --- a/pkg/phase/testdata/valid_site/phases/kustomization.yaml +++ b/pkg/phase/testdata/valid_site/phases/kustomization.yaml @@ -7,3 +7,4 @@ resources: - kubernetes_apply.yaml - cluster_map.yaml - phase_no_docentrypoint.yaml + - no_executor_phase.yaml diff --git a/pkg/phase/testdata/valid_site/phases/no_executor_phase.yaml b/pkg/phase/testdata/valid_site/phases/no_executor_phase.yaml new file mode 100644 index 000000000..ecaf14c03 --- /dev/null +++ b/pkg/phase/testdata/valid_site/phases/no_executor_phase.yaml @@ -0,0 +1,7 @@ +apiVersion: airshipit.org/v1alpha1 +kind: Phase +metadata: + name: no_executor_phase +config: + documentEntryPoint: valid_site/phases +