Merge "Add phase status command"

This commit is contained in:
Zuul 2021-03-25 21:36:44 +00:00 committed by Gerrit Code Review
commit fc00c180ff
9 changed files with 244 additions and 0 deletions

View File

@ -40,6 +40,7 @@ func NewPhaseCommand(cfgFactory config.Factory) *cobra.Command {
phaseRootCmd.AddCommand(NewRunCommand(cfgFactory))
phaseRootCmd.AddCommand(NewTreeCommand(cfgFactory))
phaseRootCmd.AddCommand(NewValidateCommand(cfgFactory))
phaseRootCmd.AddCommand(NewStatusCommand(cfgFactory))
return phaseRootCmd
}

51
cmd/phase/status.go Normal file
View File

@ -0,0 +1,51 @@
/*
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 (
"github.com/spf13/cobra"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/phase"
)
const (
statusLong = `Status of the specific life-cycle phase such as ephemeral-control-plane, target-initinfra etc...`
statusExample = `
#Status of initinfra phase
airshipctl phase status ephemeral-control-plane
`
)
// NewStatusCommand creates a command to find status of specific phase
func NewStatusCommand(cfgFactory config.Factory) *cobra.Command {
ph := &phase.StatusCommand{
Factory: cfgFactory,
Options: phase.StatusFlags{},
}
statusCmd := &cobra.Command{
Use: "status",
Short: "Status of the phase",
Long: statusLong,
Args: cobra.ExactArgs(1),
Example: statusExample,
RunE: func(cmd *cobra.Command, args []string) error {
ph.Options.PhaseID.Name = args[0]
return ph.RunE()
},
}
return statusCmd
}

35
cmd/phase/status_test.go Normal file
View 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 TestStatus(t *testing.T) {
tests := []*testutil.CmdTest{
{
Name: "run-with-help",
CmdLine: "-h",
Cmd: phase.NewStatusCommand(nil),
},
}
for _, tt := range tests {
testutil.RunTest(t, tt)
}
}

View File

@ -9,6 +9,7 @@ Available Commands:
list List phases
render Render phase documents from model
run Run phase
status Status of the phase
tree Tree view of kustomize entrypoints of phase
validate Assert that a phase is valid

View File

@ -0,0 +1,13 @@
Status of the specific life-cycle phase such as ephemeral-control-plane, target-initinfra etc...
Usage:
status [flags]
Examples:
#Status of initinfra phase
airshipctl phase status ephemeral-control-plane
Flags:
-h, --help help for status

View File

@ -27,6 +27,7 @@ such as getting list and applying specific one.
* [airshipctl phase list](airshipctl_phase_list.md) - List phases
* [airshipctl phase render](airshipctl_phase_render.md) - Render phase documents from model
* [airshipctl phase run](airshipctl_phase_run.md) - Run phase
* [airshipctl phase status](airshipctl_phase_status.md) - Status of the phase
* [airshipctl phase tree](airshipctl_phase_tree.md) - Tree view of kustomize entrypoints of phase
* [airshipctl phase validate](airshipctl_phase_validate.md) - Assert that a phase is valid

View File

@ -0,0 +1,38 @@
## airshipctl phase status
Status of the phase
### Synopsis
Status of the specific life-cycle phase such as ephemeral-control-plane, target-initinfra etc...
```
airshipctl phase status [flags]
```
### Examples
```
#Status of initinfra phase
airshipctl phase status ephemeral-control-plane
```
### Options
```
-h, --help help for status
```
### Options inherited from parent commands
```
--airshipconf string Path to file for airshipctl configuration. (default "$HOME/.airship/config")
--debug enable verbose output
```
### SEE ALSO
* [airshipctl phase](airshipctl_phase.md) - Manage phases

View File

@ -302,3 +302,37 @@ func (c *ValidateCommand) RunE() error {
}
return phase.Validate()
}
// StatusFlags is a struct to define status type
type StatusFlags struct {
Timeout time.Duration
PhaseID ifc.ID
Progress bool
}
// StatusCommand is a struct which defines status
type StatusCommand struct {
Options StatusFlags
Factory config.Factory
}
// RunE returns the status of the given phase
func (s *StatusCommand) RunE() error {
cfg, err := s.Factory()
if err != nil {
return err
}
helper, err := NewHelper(cfg)
if err != nil {
return err
}
ph, err := NewClient(helper).PhaseByID(s.Options.PhaseID)
if err != nil {
return err
}
_, err = ph.Status()
return err
}

View File

@ -535,3 +535,73 @@ func TestValidateCommand(t *testing.T) {
})
}
}
func TestStatusCommand(t *testing.T) {
tests := []struct {
name string
errContains string
statusFlags phase.StatusFlags
factory config.Factory
}{
{
name: "Error config factory",
factory: func() (*config.Config, error) {
return nil, fmt.Errorf(testFactoryErr)
},
errContains: testFactoryErr,
},
{
name: "Error new helper",
factory: func() (*config.Config, error) {
return &config.Config{
CurrentContext: "does not exist",
Contexts: make(map[string]*config.Context),
}, nil
},
errContains: testNewHelperErr,
},
{
name: "Error phase by id",
factory: func() (*config.Config, error) {
conf := config.NewConfig()
conf.Manifests = map[string]*config.Manifest{
"manifest": {
MetadataPath: "broken_metadata.yaml",
TargetPath: "testdata",
PhaseRepositoryName: config.DefaultTestPhaseRepo,
Repositories: map[string]*config.Repository{
config.DefaultTestPhaseRepo: {
URLString: "",
},
},
},
}
conf.CurrentContext = "context"
conf.Contexts = map[string]*config.Context{
"context": {
Manifest: "manifest",
},
}
return conf, nil
},
errContains: testNoBundlePath,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
command := phase.StatusCommand{
Options: tt.statusFlags,
Factory: tt.factory,
}
err := command.RunE()
if tt.errContains != "" {
require.Error(t, err)
assert.Contains(t, err.Error(), tt.errContains)
} else {
assert.NoError(t, err)
}
})
}
}