-
Notifications
You must be signed in to change notification settings - Fork 104
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Package List (Parameters | Tasks | Plans) (#1223)
Co-authored-by: Jan Schlicht <jan.schlicht+gh@gmail.com> Signed-off-by: Ken Sipe <kensipe@gmail.com>
- Loading branch information
Showing
12 changed files
with
438 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
|
||
"github.com/spf13/afero" | ||
"github.com/spf13/cobra" | ||
|
||
"github.com/kudobuilder/kudo/pkg/kudoctl/clog" | ||
"github.com/kudobuilder/kudo/pkg/kudoctl/env" | ||
"github.com/kudobuilder/kudo/pkg/kudoctl/packages" | ||
pkgresolver "github.com/kudobuilder/kudo/pkg/kudoctl/packages/resolver" | ||
"github.com/kudobuilder/kudo/pkg/kudoctl/util/repo" | ||
) | ||
|
||
const packageListDesc = ` | ||
This command consists of multiple sub-commands to interact with KUDO packages. These commands are used in the listing | ||
of an operator details such as parameters, tasks or plans. | ||
For list commands, the argument passed represents an operator. That representation can be: | ||
- name of operator in the repository | ||
- url to the operator package (tgz file) | ||
- local operator package | ||
- local operator folder | ||
` | ||
|
||
const packageListExamples = ` # show list of parameters from local operator folder | ||
kubectl kudo package list parameters local-folder | ||
# show list of parameters from zookeeper (where zookeeper is name of package in KUDO repository) | ||
kubectl kudo package list parameters zookeeper | ||
# show list of tasks from local operator folder | ||
kubectl kudo package list tasks local-folder | ||
# show list of tasks from zookeeper (where zookeeper is name of package in KUDO repository) | ||
kubectl kudo package list tasks zookeeper | ||
# show list of plans from local operator folder | ||
kubectl kudo package list plans local-folder | ||
# show plans from zookeeper (where zookeeper is name of package in KUDO repository) | ||
kubectl kudo package list plans zookeeper | ||
` | ||
|
||
// newPackageParamsCmd for repo commands such as building a repo index | ||
func newPackageParamsCmd(fs afero.Fs, out io.Writer) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "list [FLAGS]", | ||
Short: "list context from an operator package", | ||
Long: packageListDesc, | ||
Example: packageListExamples, | ||
} | ||
cmd.AddCommand(newPackageListParamsCmd(fs, out)) | ||
cmd.AddCommand(newPackageListPlansCmd(fs, out)) | ||
cmd.AddCommand(newPackageListTasksCmd(fs, out)) | ||
|
||
return cmd | ||
} | ||
|
||
// packageDiscovery is used by all list cmds to "discover" the packages | ||
func packageDiscovery(fs afero.Fs, settings *env.Settings, repoName, pathOrName, packageVersion string) (*packages.Package, error) { | ||
repository, err := repo.ClientFromSettings(fs, settings.Home, repoName) | ||
if err != nil { | ||
return nil, fmt.Errorf("could not build operator repository: %w", err) | ||
} | ||
clog.V(3).Printf("repository used %s", repository) | ||
|
||
clog.V(3).Printf("getting package pkg files for %v with version: %v", pathOrName, packageVersion) | ||
resolver := pkgresolver.New(repository) | ||
pf, err := resolver.Resolve(pathOrName, packageVersion) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to resolve package files for operator: %s: %w", pathOrName, err) | ||
} | ||
return pf, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"sort" | ||
|
||
"github.com/spf13/afero" | ||
"github.com/spf13/cobra" | ||
"github.com/thoas/go-funk" | ||
"github.com/xlab/treeprint" | ||
|
||
"github.com/kudobuilder/kudo/pkg/engine/task" | ||
"github.com/kudobuilder/kudo/pkg/kudoctl/env" | ||
"github.com/kudobuilder/kudo/pkg/kudoctl/packages" | ||
) | ||
|
||
type packageListPlansCmd struct { | ||
fs afero.Fs | ||
out io.Writer | ||
pathOrName string | ||
RepoName string | ||
PackageVersion string | ||
WithTasksResources bool | ||
} | ||
|
||
const ( | ||
packageListPlansExample = ` # show plans from local-folder (where local-folder is a folder in the current directory) | ||
kubectl kudo package list plans local-folder | ||
# show plans from zookeeper (where zookeeper is name of package in KUDO repository) | ||
kubectl kudo package list plans zookeeper` | ||
) | ||
|
||
func newPackageListPlansCmd(fs afero.Fs, out io.Writer) *cobra.Command { | ||
lc := &packageListPlansCmd{fs: fs, out: out} | ||
|
||
cmd := &cobra.Command{ | ||
Use: "plans [operator]", | ||
Short: "List operator plans", | ||
Example: packageListPlansExample, | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
if err := validateOperatorArg(args); err != nil { | ||
return err | ||
} | ||
lc.pathOrName = args[0] | ||
return lc.run(&Settings) | ||
}, | ||
} | ||
|
||
f := cmd.Flags() | ||
f.StringVar(&lc.RepoName, "repo", "", "Name of repository configuration to use. (default defined by context)") | ||
f.StringVar(&lc.PackageVersion, "version", "", "A specific package version on the official GitHub repo. (default to the most recent)") | ||
f.BoolVarP(&lc.WithTasksResources, "with-tasks", "t", false, "Display task resources with plans") | ||
|
||
return cmd | ||
} | ||
|
||
func (c *packageListPlansCmd) run(settings *env.Settings) error { | ||
pf, err := packageDiscovery(c.fs, settings, c.RepoName, c.pathOrName, c.PackageVersion) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
displayPlanTable(pf.Files, c.WithTasksResources, c.out) | ||
return nil | ||
} | ||
|
||
func displayPlanTable(pf *packages.Files, withTasks bool, out io.Writer) { | ||
tree := treeprint.New() | ||
planNames := sortedPlanNames(pf) | ||
tree.SetValue("plans") | ||
for _, name := range planNames { | ||
plan := pf.Operator.Plans[name] | ||
pNode := tree.AddBranch(fmt.Sprintf("%s (%s)", name, plan.Strategy)) | ||
|
||
for _, phase := range plan.Phases { | ||
phNode := pNode.AddMetaBranch("phase", fmt.Sprintf("%s (%s)", phase.Name, phase.Strategy)) | ||
for _, step := range phase.Steps { | ||
sNode := phNode.AddMetaBranch("step", step.Name) | ||
for _, taskName := range step.Tasks { | ||
if withTasks { | ||
addTaskNodeWithResources(sNode, taskName, pf) | ||
} else { | ||
sNode.AddNode(taskName) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
if len(pf.Operator.Plans) == 0 { | ||
fmt.Fprintf(out, "no plans found\n") | ||
} else { | ||
fmt.Fprintln(out, tree.String()) | ||
} | ||
} | ||
|
||
func sortedPlanNames(pf *packages.Files) []string { | ||
planNames := funk.Keys(pf.Operator.Plans).([]string) | ||
sort.Strings(planNames) | ||
return planNames | ||
} | ||
|
||
func addTaskNodeWithResources(sNode treeprint.Tree, taskName string, pf *packages.Files) { | ||
for _, t := range pf.Operator.Tasks { | ||
if t.Name == taskName { | ||
switch t.Kind { | ||
case task.ApplyTaskKind: | ||
tNode := sNode.AddMetaBranch("apply", taskName) | ||
for _, resource := range t.Spec.Resources { | ||
tNode.AddNode(resource) | ||
} | ||
case task.DeleteTaskKind: | ||
tNode := sNode.AddMetaBranch("delete", taskName) | ||
for _, resource := range t.Spec.Resources { | ||
tNode.AddNode(resource) | ||
} | ||
case task.PipeTaskKind: | ||
tNode := sNode.AddMetaBranch("pipe", taskName) | ||
tNode.AddNode(t.Spec.Pod) | ||
case task.DummyTaskKind: | ||
sNode.AddMetaBranch("dummy", taskName) | ||
default: | ||
sNode.AddMetaBranch("unknown", taskName) | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.