Introduce phases and phase plan
Airship API is extended with Phase and PhasePlan objects which implemet k8s runtime.Object interface. Phase plan command is added to airshipctl. Closes: #262 Closes: #261 Closes: #260 Change-Id: I4c299ec9078af4ace29ab46bd6440f47ae18a094
This commit is contained in:
parent
c05286d3f6
commit
325d824503
@ -45,6 +45,7 @@ func NewPhaseCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Comman
|
||||
|
||||
phaseRootCmd.AddCommand(NewApplyCommand(rootSettings, client.DefaultClient))
|
||||
phaseRootCmd.AddCommand(NewRenderCommand(rootSettings))
|
||||
phaseRootCmd.AddCommand(NewPlanCommand(rootSettings))
|
||||
|
||||
return phaseRootCmd
|
||||
}
|
||||
|
61
cmd/phase/plan.go
Normal file
61
cmd/phase/plan.go
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
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 phase
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/environment"
|
||||
"opendev.org/airship/airshipctl/pkg/phase"
|
||||
"opendev.org/airship/airshipctl/pkg/util"
|
||||
)
|
||||
|
||||
const (
|
||||
cmdLong = `
|
||||
List life-cycle phases which were defined in document model by group.
|
||||
Phases within a group are executed sequentially. Multiple phase groups
|
||||
are executed in parallel.
|
||||
`
|
||||
)
|
||||
|
||||
// NewPlanCommand creates a command which prints available phases
|
||||
func NewPlanCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
|
||||
p := &phase.Cmd{AirshipCTLSettings: rootSettings}
|
||||
|
||||
planCmd := &cobra.Command{
|
||||
Use: "plan",
|
||||
Short: "List phases",
|
||||
Long: cmdLong[1:],
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
phases, err := p.Plan()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tw := util.NewTabWriter(cmd.OutOrStdout())
|
||||
defer tw.Flush()
|
||||
fmt.Fprintf(tw, "GROUP\tPHASE\n")
|
||||
for group, phaseList := range phases {
|
||||
fmt.Fprintf(tw, "%s\t\n", group)
|
||||
for _, phase := range phaseList {
|
||||
fmt.Fprintf(tw, "\t%s\n", phase)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
return planCmd
|
||||
}
|
35
cmd/phase/plan_test.go
Normal file
35
cmd/phase/plan_test.go
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
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 phase_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"opendev.org/airship/airshipctl/cmd/phase"
|
||||
"opendev.org/airship/airshipctl/testutil"
|
||||
)
|
||||
|
||||
func TestNewPlanCommand(t *testing.T) {
|
||||
tests := []*testutil.CmdTest{
|
||||
{
|
||||
Name: "phase-plan-cmd-with-help",
|
||||
CmdLine: "--help",
|
||||
Cmd: phase.NewPlanCommand(nil),
|
||||
},
|
||||
}
|
||||
for _, testcase := range tests {
|
||||
testutil.RunTest(t, testcase)
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ Usage:
|
||||
Available Commands:
|
||||
apply Apply phase to a cluster
|
||||
help Help about any command
|
||||
plan List phases
|
||||
render Render phase documents from model
|
||||
|
||||
Flags:
|
||||
|
9
cmd/phase/testdata/TestNewPlanCommandGoldenOutput/phase-plan-cmd-with-help.golden
vendored
Normal file
9
cmd/phase/testdata/TestNewPlanCommandGoldenOutput/phase-plan-cmd-with-help.golden
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
List life-cycle phases which were defined in document model by group.
|
||||
Phases within a group are executed sequentially. Multiple phase groups
|
||||
are executed in parallel.
|
||||
|
||||
Usage:
|
||||
plan [flags]
|
||||
|
||||
Flags:
|
||||
-h, --help help for plan
|
@ -31,5 +31,6 @@ Manage the airshipctl config file
|
||||
* [airshipctl config set-cluster](airshipctl_config_set-cluster.md) - Manage clusters
|
||||
* [airshipctl config set-context](airshipctl_config_set-context.md) - Manage contexts
|
||||
* [airshipctl config set-credentials](airshipctl_config_set-credentials.md) - Manage user credentials
|
||||
* [airshipctl config set-management-config](airshipctl_config_set-management-config.md) - Modify an out-of-band management configuration
|
||||
* [airshipctl config use-context](airshipctl_config_use-context.md) - Switch to a different context
|
||||
|
||||
|
33
docs/source/cli/airshipctl_config_set-management-config.md
Normal file
33
docs/source/cli/airshipctl_config_set-management-config.md
Normal file
@ -0,0 +1,33 @@
|
||||
## airshipctl config set-management-config
|
||||
|
||||
Modify an out-of-band management configuration
|
||||
|
||||
### Synopsis
|
||||
|
||||
Modify an out-of-band management configuration
|
||||
|
||||
```
|
||||
airshipctl config set-management-config NAME [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for set-management-config
|
||||
--insecure Ignore SSL certificate verification on out-of-band management requests
|
||||
--management-type string Set the out-of-band management type (default "redfish")
|
||||
--use-proxy Use the proxy configuration specified in the local environment (default true)
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--airshipconf string Path to file for airshipctl configuration. (default "$HOME/.airship/config")
|
||||
--debug enable verbose output
|
||||
--kubeconfig string Path to kubeconfig associated with airshipctl configuration. (default "$HOME/.airship/kubeconfig")
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [airshipctl config](airshipctl_config.md) - Manage the airshipctl config file
|
||||
|
@ -26,5 +26,6 @@ such as getting list and applying specific one.
|
||||
|
||||
* [airshipctl](airshipctl.md) - A unified entrypoint to various airship components
|
||||
* [airshipctl phase apply](airshipctl_phase_apply.md) - Apply phase to a cluster
|
||||
* [airshipctl phase plan](airshipctl_phase_plan.md) - List phases
|
||||
* [airshipctl phase render](airshipctl_phase_render.md) - Render phase documents from model
|
||||
|
||||
|
33
docs/source/cli/airshipctl_phase_plan.md
Normal file
33
docs/source/cli/airshipctl_phase_plan.md
Normal file
@ -0,0 +1,33 @@
|
||||
## airshipctl phase plan
|
||||
|
||||
List phases
|
||||
|
||||
### Synopsis
|
||||
|
||||
List life-cycle phases which were defined in document model by group.
|
||||
Phases within a group are executed sequentially. Multiple phase groups
|
||||
are executed in parallel.
|
||||
|
||||
|
||||
```
|
||||
airshipctl phase plan [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for plan
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--airshipconf string Path to file for airshipctl configuration. (default "$HOME/.airship/config")
|
||||
--debug enable verbose output
|
||||
--kubeconfig string Path to kubeconfig associated with airshipctl configuration. (default "$HOME/.airship/kubeconfig")
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [airshipctl phase](airshipctl_phase.md) - Manage phases
|
||||
|
@ -40,6 +40,10 @@ var (
|
||||
func init() {
|
||||
Scheme = runtime.NewScheme()
|
||||
// NOTE add all api objects to scheme here
|
||||
SchemeBuilder.Register(&Clusterctl{})
|
||||
SchemeBuilder.Register(
|
||||
&Clusterctl{},
|
||||
&Phase{},
|
||||
&PhasePlan{},
|
||||
)
|
||||
_ = AddToScheme(Scheme) //nolint:errcheck
|
||||
}
|
||||
|
36
pkg/api/v1alpha1/phase_types.go
Normal file
36
pkg/api/v1alpha1/phase_types.go
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
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 (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// Phase object to control deployment steps
|
||||
type Phase struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Config PhaseConfig `json:"config,omitempty"`
|
||||
}
|
||||
|
||||
// PhaseConfig represents configuration for a particular phase. It contins a reference to
|
||||
// phase runner object which should contain runner configuration
|
||||
type PhaseConfig struct {
|
||||
ExecutorRef *corev1.ObjectReference `json:"executorRef"`
|
||||
DocumentEntryPoint string `json:"documentEntryPoint"`
|
||||
}
|
40
pkg/api/v1alpha1/phaseplan_types.go
Normal file
40
pkg/api/v1alpha1/phaseplan_types.go
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// PhasePlan object represents phase execution sequence
|
||||
type PhasePlan struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
PhaseGroups []PhaseGroup `json:"phaseGroups,omitempty"`
|
||||
}
|
||||
|
||||
// PhaseGroup represents set of phases (i.e. steps) executed sequentially.
|
||||
// Phase groups are executed simultaneously
|
||||
type PhaseGroup struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Phases []PhaseGroupStep `json:"phases,omitempty"`
|
||||
}
|
||||
|
||||
// PhaseGroupStep represents phase (or step) within phase group
|
||||
type PhaseGroupStep struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
@ -5,7 +5,8 @@
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
@ -99,6 +100,119 @@ func (in *MoveOptions) DeepCopy() *MoveOptions {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Phase) DeepCopyInto(out *Phase) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Config.DeepCopyInto(&out.Config)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Phase.
|
||||
func (in *Phase) DeepCopy() *Phase {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Phase)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Phase) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PhaseConfig) DeepCopyInto(out *PhaseConfig) {
|
||||
*out = *in
|
||||
if in.ExecutorRef != nil {
|
||||
in, out := &in.ExecutorRef, &out.ExecutorRef
|
||||
*out = new(v1.ObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PhaseConfig.
|
||||
func (in *PhaseConfig) DeepCopy() *PhaseConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PhaseConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PhaseGroup) DeepCopyInto(out *PhaseGroup) {
|
||||
*out = *in
|
||||
if in.Phases != nil {
|
||||
in, out := &in.Phases, &out.Phases
|
||||
*out = make([]PhaseGroupStep, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PhaseGroup.
|
||||
func (in *PhaseGroup) DeepCopy() *PhaseGroup {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PhaseGroup)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PhaseGroupStep) DeepCopyInto(out *PhaseGroupStep) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PhaseGroupStep.
|
||||
func (in *PhaseGroupStep) DeepCopy() *PhaseGroupStep {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PhaseGroupStep)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PhasePlan) DeepCopyInto(out *PhasePlan) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
if in.PhaseGroups != nil {
|
||||
in, out := &in.PhaseGroups, &out.PhaseGroups
|
||||
*out = make([]PhaseGroup, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PhasePlan.
|
||||
func (in *PhasePlan) DeepCopy() *PhasePlan {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PhasePlan)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *PhasePlan) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Provider) DeepCopyInto(out *Provider) {
|
||||
*out = *in
|
||||
|
74
pkg/phase/phase.go
Normal file
74
pkg/phase/phase.go
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
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 phase
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
airshipv1 "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
"opendev.org/airship/airshipctl/pkg/environment"
|
||||
)
|
||||
|
||||
const (
|
||||
// PhaseDirName directory for bundle with phases
|
||||
// TODO (dukov) Remove this once repository metadata is ready
|
||||
PhaseDirName = "phases"
|
||||
)
|
||||
|
||||
// Cmd object to work with phase api
|
||||
type Cmd struct {
|
||||
*environment.AirshipCTLSettings
|
||||
DryRun bool
|
||||
}
|
||||
|
||||
func (p *Cmd) getBundle() (document.Bundle, error) {
|
||||
ccm, err := p.Config.CurrentContextManifest()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return document.NewBundleByPath(filepath.Join(ccm.TargetPath, ccm.SubPath, PhaseDirName))
|
||||
}
|
||||
|
||||
// Plan shows available phase names
|
||||
func (p *Cmd) Plan() (map[string][]string, error) {
|
||||
bundle, err := p.getBundle()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
plan := &airshipv1.PhasePlan{}
|
||||
selector, err := document.NewSelector().ByObject(plan, airshipv1.Scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
doc, err := bundle.SelectOne(selector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := doc.ToAPIObject(plan, airshipv1.Scheme); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make(map[string][]string)
|
||||
for _, phaseGroup := range plan.PhaseGroups {
|
||||
phases := make([]string, len(phaseGroup.Phases))
|
||||
for i, phase := range phaseGroup.Phases {
|
||||
phases[i] = phase.Name
|
||||
}
|
||||
result[phaseGroup.Name] = phases
|
||||
}
|
||||
return result, nil
|
||||
}
|
99
pkg/phase/phase_test.go
Normal file
99
pkg/phase/phase_test.go
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
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 phase_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"sigs.k8s.io/kustomize/api/resid"
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/config"
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
"opendev.org/airship/airshipctl/pkg/environment"
|
||||
"opendev.org/airship/airshipctl/pkg/phase"
|
||||
)
|
||||
|
||||
func TestPhasePlan(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
settings func() *environment.AirshipCTLSettings
|
||||
expectedPlan map[string][]string
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
name: "No context",
|
||||
settings: func() *environment.AirshipCTLSettings {
|
||||
s := makeDefaultSettings()
|
||||
s.Config.CurrentContext = "badCtx"
|
||||
return s
|
||||
},
|
||||
expectedErr: config.ErrMissingConfig{What: "Context with name 'badCtx'"},
|
||||
},
|
||||
{
|
||||
name: "Valid Phase Plan",
|
||||
settings: makeDefaultSettings,
|
||||
expectedPlan: map[string][]string{
|
||||
"group1": {
|
||||
"isogen",
|
||||
"remotedirect",
|
||||
"initinfra",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "No Phase Plan",
|
||||
settings: func() *environment.AirshipCTLSettings {
|
||||
s := makeDefaultSettings()
|
||||
m, err := s.Config.CurrentContextManifest()
|
||||
require.NoError(t, err)
|
||||
m.SubPath = "no_plan_site"
|
||||
return s
|
||||
},
|
||||
expectedErr: document.ErrDocNotFound{
|
||||
Selector: document.Selector{
|
||||
Selector: types.Selector{
|
||||
Gvk: resid.Gvk{
|
||||
Group: "airshipit.org",
|
||||
Version: "v1alpha1",
|
||||
Kind: "PhasePlan",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
tt := test
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cmd := phase.Cmd{AirshipCTLSettings: tt.settings()}
|
||||
actualPlan, actualErr := cmd.Plan()
|
||||
assert.Equal(t, tt.expectedErr, actualErr)
|
||||
assert.Equal(t, tt.expectedPlan, actualPlan)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func makeDefaultSettings() *environment.AirshipCTLSettings {
|
||||
testSettings := &environment.AirshipCTLSettings{
|
||||
AirshipConfigPath: "testdata/airshipconfig.yaml",
|
||||
KubeConfigPath: "testdata/kubeconfig.yaml",
|
||||
}
|
||||
testSettings.InitConfig()
|
||||
return testSettings
|
||||
}
|
44
pkg/phase/testdata/airshipconfig.yaml
vendored
Normal file
44
pkg/phase/testdata/airshipconfig.yaml
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
bootstrapInfo:
|
||||
dummy_bootstrap_config:
|
||||
container:
|
||||
volume: /tmp/airship:/config
|
||||
image: quay.io/airshipit/isogen:latest-debian_stable
|
||||
containerRuntime: docker
|
||||
builder:
|
||||
userDataFileName: user-data
|
||||
networkConfigFileName: network-config
|
||||
outputMetadataFileName: output-metadata.yaml
|
||||
remoteDirect:
|
||||
isoUrl: http://localhost:8099/debian-custom.iso
|
||||
remoteType: redfish
|
||||
clusters:
|
||||
dummycluster:
|
||||
clusterType:
|
||||
ephemeral:
|
||||
bootstrapInfo: dummy_bootstrap_config
|
||||
clusterKubeconf: dummycluster_ephemeral
|
||||
contexts:
|
||||
dummy_cluster:
|
||||
contextKubeconf: dummy_cluster
|
||||
manifest: dummy_manifest
|
||||
currentContext: dummy_cluster
|
||||
kind: Config
|
||||
manifests:
|
||||
dummy_manifest:
|
||||
primaryRepositoryName: primary
|
||||
repositories:
|
||||
primary:
|
||||
auth:
|
||||
sshKey: testdata/test-key.pem
|
||||
type: ssh-key
|
||||
checkout:
|
||||
branch: ""
|
||||
force: false
|
||||
remoteRef: ""
|
||||
tag: v1.0.1
|
||||
url: http://dummy.url.com/primary.git
|
||||
subPath: valid_site
|
||||
targetPath: testdata
|
||||
users:
|
||||
dummy_user: {}
|
19
pkg/phase/testdata/kubeconfig.yaml
vendored
Normal file
19
pkg/phase/testdata/kubeconfig.yaml
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRFNU1Ea3lPVEUzTURNd09Wb1hEVEk1TURreU5qRTNNRE13T1Zvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTUZyCkdxM0kyb2dZci81Y01Udy9Na1pORTNWQURzdEdyU240WjU2TDhPUGhMcUhDN2t1dno2dVpES3dCSGtGeTBNK2MKRXIzd2piUGE1aTV5NmkyMGtxSHBVMjdPZTA0dzBXV2s4N0RSZVlWaGNoZVJHRXoraWt3SndIcGRmMjJVemZNKwpkSDBzaUhuMVd6UnovYk4za3hMUzJlMnZ2U1Y3bmNubk1YRUd4OXV0MUY0NThHeWxxdmxXTUlWMzg5Q2didXFDCkcwcFdiMTBLM0RVZWdiT25Xa1FmSm5sTWRRVVZDUVdZZEZaaklrcWtkWi9hVTRobkNEV01oZXNWRnFNaDN3VVAKczhQay9BNWh1ZFFPbnFRNDVIWXZLdjZ5RjJWcDUyWExBRUx3NDJ4aVRKZlh0V1h4eHR6cU4wY1lyL2VxeS9XMQp1YVVGSW5xQjFVM0JFL1oxbmFrQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFKUUVKQVBLSkFjVDVuK3dsWGJsdU9mS0J3c2gKZTI4R1c5R2QwM0N0NGF3RzhzMXE1ZHNua2tpZmVTUENHVFZ1SXF6UTZDNmJaSk9SMDMvVEl5ejh6NDJnaitDVApjWUZXZkltM2RKTnpRL08xWkdySXZZNWdtcWJtWDlpV0JaU24rRytEOGxubzd2aGMvY0tBRFR5OTMvVU92MThuCkdhMnIrRGJJcHcyTWVBVEl2elpxRS9RWlVSQ25DMmdjUFhTVzFqN2h4R3o1a3ZNcGVDZTdQYVUvdVFvblVHSWsKZ2t6ZzI4NHQvREhUUzc4N1V1SUg5cXBaV09yTFNMOGFBeUxQUHhWSXBteGZmbWRETE9TS2VUemRlTmxoSitUMwowQlBVaHBQTlJBNTNJN0hRQjhVUDR2elNONTkzZ1VFbVlFQ2Jic2RYSzB6ZVR6SDdWWHR2Zmd5WTVWWT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
|
||||
server: https://127.0.0.1:6443
|
||||
name: dummycluster_ephemeral
|
||||
contexts:
|
||||
- context:
|
||||
cluster: dummycluster_ephemeral
|
||||
user: kubernetes-admin
|
||||
name: dummy_cluster
|
||||
current-context: dummy_cluster
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kubernetes-admin
|
||||
user:
|
||||
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM4akNDQWRxZ0F3SUJBZ0lJQXhEdzk2RUY4SXN3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB4T1RBNU1qa3hOekF6TURsYUZ3MHlNREE1TWpneE56QXpNVEphTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXV6R0pZdlBaNkRvaTQyMUQKSzhXSmFaQ25OQWQycXo1cC8wNDJvRnpRUGJyQWd6RTJxWVZrek9MOHhBVmVSN1NONXdXb1RXRXlGOEVWN3JyLwo0K0hoSEdpcTVQbXF1SUZ5enpuNi9JWmM4alU5eEVmenZpa2NpckxmVTR2UlhKUXdWd2dBU05sMkFXQUloMmRECmRUcmpCQ2ZpS1dNSHlqMFJiSGFsc0J6T3BnVC9IVHYzR1F6blVRekZLdjJkajVWMU5rUy9ESGp5UlJKK0VMNlEKQlltR3NlZzVQNE5iQzllYnVpcG1NVEFxL0p1bU9vb2QrRmpMMm5acUw2Zkk2ZkJ0RjVPR2xwQ0IxWUo4ZnpDdApHUVFaN0hUSWJkYjJ0cDQzRlZPaHlRYlZjSHFUQTA0UEoxNSswV0F5bVVKVXo4WEE1NDRyL2J2NzRKY0pVUkZoCmFyWmlRd0lEQVFBQm95Y3dKVEFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFMMmhIUmVibEl2VHJTMFNmUVg1RG9ueVVhNy84aTg1endVWApSd3dqdzFuS0U0NDJKbWZWRGZ5b0hRYUM4Ti9MQkxyUXM0U0lqU1JYdmFHU1dSQnRnT1RRV21Db1laMXdSbjdwCndDTXZQTERJdHNWWm90SEZpUFl2b1lHWFFUSXA3YlROMmg1OEJaaEZ3d25nWUovT04zeG1rd29IN1IxYmVxWEYKWHF1TTluekhESk41VlZub1lQR09yRHMwWlg1RnNxNGtWVU0wVExNQm9qN1ZIRDhmU0E5RjRYNU4yMldsZnNPMAo4aksrRFJDWTAyaHBrYTZQQ0pQS0lNOEJaMUFSMG9ZakZxT0plcXpPTjBqcnpYWHh4S2pHVFVUb1BldVA5dCtCCjJOMVA1TnI4a2oxM0lrend5Q1NZclFVN09ZM3ltZmJobHkrcXZxaFVFa014MlQ1SkpmQT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
|
||||
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBdXpHSll2UFo2RG9pNDIxREs4V0phWkNuTkFkMnF6NXAvMDQyb0Z6UVBickFnekUyCnFZVmt6T0w4eEFWZVI3U041d1dvVFdFeUY4RVY3cnIvNCtIaEhHaXE1UG1xdUlGeXp6bjYvSVpjOGpVOXhFZnoKdmlrY2lyTGZVNHZSWEpRd1Z3Z0FTTmwyQVdBSWgyZERkVHJqQkNmaUtXTUh5ajBSYkhhbHNCek9wZ1QvSFR2MwpHUXpuVVF6Rkt2MmRqNVYxTmtTL0RIanlSUkorRUw2UUJZbUdzZWc1UDROYkM5ZWJ1aXBtTVRBcS9KdW1Pb29kCitGakwyblpxTDZmSTZmQnRGNU9HbHBDQjFZSjhmekN0R1FRWjdIVEliZGIydHA0M0ZWT2h5UWJWY0hxVEEwNFAKSjE1KzBXQXltVUpVejhYQTU0NHIvYnY3NEpjSlVSRmhhclppUXdJREFRQUJBb0lCQVFDU0pycjlaeVpiQ2dqegpSL3VKMFZEWCt2aVF4c01BTUZyUjJsOE1GV3NBeHk1SFA4Vk4xYmc5djN0YUVGYnI1U3hsa3lVMFJRNjNQU25DCm1uM3ZqZ3dVQWlScllnTEl5MGk0UXF5VFBOU1V4cnpTNHRxTFBjM3EvSDBnM2FrNGZ2cSsrS0JBUUlqQnloamUKbnVFc1JpMjRzT3NESlM2UDE5NGlzUC9yNEpIM1M5bFZGbkVuOGxUR2c0M1kvMFZoMXl0cnkvdDljWjR5ZUNpNwpjMHFEaTZZcXJZaFZhSW9RRW1VQjdsbHRFZkZzb3l4VDR6RTE5U3pVbkRoMmxjYTF1TzhqcmI4d2xHTzBoQ2JyClB1R1l2WFFQa3Q0VlNmalhvdGJ3d2lBNFRCVERCRzU1bHp6MmNKeS9zSS8zSHlYbEMxcTdXUmRuQVhhZ1F0VzkKOE9DZGRkb0JBb0dCQU5NcUNtSW94REtyckhZZFRxT1M1ZFN4cVMxL0NUN3ZYZ0pScXBqd2Y4WHA2WHo0KzIvTAozVXFaVDBEL3dGTkZkc1Z4eFYxMnNYMUdwMHFWZVlKRld5OVlCaHVSWGpTZ0ZEWldSY1Z1Y01sNVpPTmJsbmZGCjVKQ0xnNXFMZ1g5VTNSRnJrR3A0R241UDQxamg4TnhKVlhzZG5xWE9xNTFUK1RRT1UzdkpGQjc1QW9HQkFPTHcKalp1cnZtVkZyTHdaVGgvRDNpWll5SVV0ZUljZ2NKLzlzbTh6L0pPRmRIbFd4dGRHUFVzYVd1MnBTNEhvckFtbgpqTm4vSTluUXd3enZ3MWUzVVFPbUhMRjVBczk4VU5hbk5TQ0xNMW1yaXZHRXJ1VHFnTDM1bU41eFZPdTUxQU5JCm4yNkFtODBJT2JDeEtLa0R0ZXJSaFhHd3g5c1pONVJCbG9VRThZNGJBb0dBQ3ZsdVhMZWRxcng5VkE0bDNoNXUKVDJXRVUxYjgxZ1orcmtRc1I1S0lNWEw4cllBTElUNUpHKzFuendyN3BkaEFXZmFWdVV2SDRhamdYT0h6MUs5aQpFODNSVTNGMG9ldUg0V01PY1RwU0prWm0xZUlXcWRiaEVCb1FGdUlWTXRib1BsV0d4ZUhFRHJoOEtreGp4aThSCmdEcUQyajRwY1IzQ0g5QjJ5a0lqQjVFQ2dZRUExc0xXLys2enE1c1lNSm14K1JXZThhTXJmL3pjQnVTSU1LQWgKY0dNK0wwMG9RSHdDaUU4TVNqcVN1ajV3R214YUFuanhMb3ZwSFlRV1VmUEVaUW95UE1YQ2VhRVBLOU4xbk8xMwp0V2lHRytIZkIxaU5PazFCc0lhNFNDbndOM1FRVTFzeXBaeEgxT3hueS9LYmkvYmEvWEZ5VzNqMGFUK2YvVWxrCmJGV1ZVdWtDZ1lFQTBaMmRTTFlmTjV5eFNtYk5xMWVqZXdWd1BjRzQxR2hQclNUZEJxdHFac1doWGE3aDdLTWEKeHdvamh5SXpnTXNyK2tXODdlajhDQ2h0d21sQ1p5QU92QmdOZytncnJ1cEZLM3FOSkpKeU9YREdHckdpbzZmTQp5aXB3Q2tZVGVxRThpZ1J6UkI5QkdFUGY4eVpjMUtwdmZhUDVhM0lRZmxiV0czbGpUemNNZVZjPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
|
0
pkg/phase/testdata/no_plan_site/phases/kustomization.yaml
vendored
Normal file
0
pkg/phase/testdata/no_plan_site/phases/kustomization.yaml
vendored
Normal file
2
pkg/phase/testdata/valid_site/phases/kustomization.yaml
vendored
Normal file
2
pkg/phase/testdata/valid_site/phases/kustomization.yaml
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
resources:
|
||||
- phaseplan.yaml
|
10
pkg/phase/testdata/valid_site/phases/phaseplan.yaml
vendored
Normal file
10
pkg/phase/testdata/valid_site/phases/phaseplan.yaml
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
kind: PhasePlan
|
||||
metadata:
|
||||
name: phasePlan
|
||||
phaseGroups:
|
||||
- name: group1
|
||||
phases:
|
||||
- name: isogen
|
||||
- name: remotedirect
|
||||
- name: initinfra
|
Loading…
Reference in New Issue
Block a user