Merge "Allow to perform phase render using document entrypoint"

This commit is contained in:
Zuul 2020-12-16 16:51:46 +00:00 committed by Gerrit Code Review
commit b6d52343dc
7 changed files with 56 additions and 19 deletions

View File

@ -35,14 +35,14 @@ airshipctl phase render initinfra -l app=helm,service=tiller -k Deployment
// NewRenderCommand create a new command for document rendering
func NewRenderCommand(cfgFactory config.Factory) *cobra.Command {
filterOptions := &phase.FilterOptions{}
filterOptions := &phase.RenderCommand{}
renderCmd := &cobra.Command{
Use: "render PHASE_NAME",
Short: "Render phase documents from model",
Example: renderExample,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return filterOptions.Render(cfgFactory, args[0], cmd.OutOrStdout())
return filterOptions.RunE(cfgFactory, args[0], cmd.OutOrStdout())
},
}
@ -51,7 +51,7 @@ func NewRenderCommand(cfgFactory config.Factory) *cobra.Command {
}
// addRenderFlags adds flags for document render sub-command
func addRenderFlags(filterOptions *phase.FilterOptions, cmd *cobra.Command) {
func addRenderFlags(filterOptions *phase.RenderCommand, cmd *cobra.Command) {
flags := cmd.Flags()
flags.StringVarP(
@ -81,4 +81,12 @@ func addRenderFlags(filterOptions *phase.FilterOptions, cmd *cobra.Command) {
"k",
"",
"filter documents by Kinds")
flags.BoolVarP(
&filterOptions.Executor,
"executor",
"e",
false,
"if set to true rendering will be performed by executor "+
"otherwise phase entrypoint will be rendered by kustomize, if entrypoint is not specified "+
"error will be returned")
}

View File

@ -17,6 +17,7 @@ airshipctl phase render initinfra -l app=helm,service=tiller -k Deployment
Flags:
-a, --annotation string filter documents by Annotations
-g, --apiversion string filter documents by API version
-e, --executor if set to true rendering will be performed by executor otherwise phase entrypoint will be rendered by kustomize, if entrypoint is not specified error will be returned
-h, --help help for render
-k, --kind string filter documents by Kinds
-l, --label string filter documents by Labels

View File

@ -29,6 +29,7 @@ airshipctl phase render initinfra -l app=helm,service=tiller -k Deployment
```
-a, --annotation string filter documents by Annotations
-g, --apiversion string filter documents by API version
-e, --executor if set to true rendering will be performed by executor otherwise phase entrypoint will be rendered by kustomize, if entrypoint is not specified error will be returned
-h, --help help for render
-k, --kind string filter documents by Kinds
-l, --label string filter documents by Labels

View File

@ -136,13 +136,30 @@ func (p *phase) Validate() error {
}
// Render executor documents
func (p *phase) Render(w io.Writer, options ifc.RenderOptions) error {
executor, err := p.Executor()
func (p *phase) Render(w io.Writer, executorRender bool, options ifc.RenderOptions) error {
if executorRender {
executor, err := p.Executor()
if err != nil {
return err
}
return executor.Render(w, options)
}
root, err := p.DocumentRoot()
if err != nil {
return err
}
return executor.Render(w, options)
bundle, err := document.NewBundleByPath(root)
if err != nil {
return err
}
rendered, err := bundle.SelectBundle(options.FilterSelector)
if err != nil {
return err
}
return rendered.Write(w)
}
// DocumentRoot root that holds all the documents associated with the phase

View File

@ -28,7 +28,7 @@ type Phase interface {
DocumentRoot() (string, error)
Details() (string, error)
Executor() (Executor, error)
Render(io.Writer, RenderOptions) error
Render(io.Writer, bool, RenderOptions) error
}
// ID uniquely identifies the phase

View File

@ -23,8 +23,8 @@ import (
"opendev.org/airship/airshipctl/pkg/phase/ifc"
)
// FilterOptions holds filters for selector
type FilterOptions struct {
// RenderCommand holds filters for selector
type RenderCommand struct {
// Label filters documents by label string
Label string
// Annotation filters documents by annotation string
@ -33,10 +33,12 @@ type FilterOptions struct {
APIVersion string
// Kind filters documents by document kind
Kind string
// Executor identifies if executor should perform rendering
Executor bool
}
// Render prints out filtered documents
func (fo *FilterOptions) Render(cfgFactory config.Factory, phaseName string, out io.Writer) error {
// RunE prints out filtered documents
func (fo *RenderCommand) RunE(cfgFactory config.Factory, phaseName string, out io.Writer) error {
cfg, err := cfgFactory()
if err != nil {
return err
@ -62,6 +64,5 @@ func (fo *FilterOptions) Render(cfgFactory config.Factory, phaseName string, out
}
sel := document.NewSelector().ByLabel(fo.Label).ByAnnotation(fo.Annotation).ByGvk(group, version, fo.Kind)
return phase.Render(out, ifc.RenderOptions{FilterSelector: sel})
return phase.Render(out, fo.Executor, ifc.RenderOptions{FilterSelector: sel})
}

View File

@ -43,19 +43,19 @@ func TestRender(t *testing.T) {
fixturePath := "phase"
tests := []struct {
name string
settings *phase.FilterOptions
settings *phase.RenderCommand
expResFile string
expErr error
}{
{
name: "No Filters",
settings: &phase.FilterOptions{},
settings: &phase.RenderCommand{},
expResFile: "noFilter.yaml",
expErr: nil,
},
{
name: "All Filters",
settings: &phase.FilterOptions{
settings: &phase.RenderCommand{
Label: "airshipit.org/deploy-k8s=false",
Annotation: "airshipit.org/clustertype=ephemeral",
APIVersion: "metal3.io/v1alpha1",
@ -66,7 +66,7 @@ func TestRender(t *testing.T) {
},
{
name: "Multiple Labels",
settings: &phase.FilterOptions{
settings: &phase.RenderCommand{
Label: "airshipit.org/deploy-k8s=false, airshipit.org/ephemeral-node=true",
},
expResFile: "multiLabels.yaml",
@ -74,12 +74,21 @@ func TestRender(t *testing.T) {
},
{
name: "Malformed Label",
settings: &phase.FilterOptions{
settings: &phase.RenderCommand{
Label: "app=(",
},
expResFile: "",
expErr: fmt.Errorf("unable to parse requirement: found '(', expected: identifier"),
},
{
name: "Malformed Label",
settings: &phase.RenderCommand{
Label: "app=(",
Executor: true,
},
expResFile: "",
expErr: fmt.Errorf("unable to parse requirement: found '(', expected: identifier"),
},
}
for _, tt := range tests {
@ -92,7 +101,7 @@ func TestRender(t *testing.T) {
require.NoError(t, err)
}
out := &bytes.Buffer{}
err = tt.settings.Render(func() (*config.Config, error) {
err = tt.settings.RunE(func() (*config.Config, error) {
return rs, nil
}, fixturePath, out)
assert.Equal(t, tt.expErr, err)