Skip to content

Commit

Permalink
Instance ls/inspect/tag CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
divolgin committed Jan 5, 2024
1 parent c4a22dd commit ce8b20a
Show file tree
Hide file tree
Showing 15 changed files with 444 additions and 47 deletions.
19 changes: 0 additions & 19 deletions cli/cmd/cluster.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package cmd

import (
"strings"

"github.com/pkg/errors"
"github.com/replicatedhq/replicated/pkg/kotsclient"
"github.com/spf13/cobra"
)

Expand All @@ -22,19 +19,3 @@ func (r *runners) InitClusterCommand(parent *cobra.Command) *cobra.Command {

return cmd
}

func parseTags(tags []string) ([]kotsclient.ClusterTag, error) {
clusterTags := []kotsclient.ClusterTag{}
for _, tag := range tags {
tagParts := strings.SplitN(tag, "=", 2)
if len(tagParts) != 2 {
return nil, errors.Errorf("invalid tag format: %s", tag)
}

clusterTags = append(clusterTags, kotsclient.ClusterTag{
Key: tagParts[0],
Value: tagParts[1],
})
}
return clusterTags, nil
}
4 changes: 2 additions & 2 deletions cli/cmd/customer_inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (r *runners) inspectCustomer(_ *cobra.Command, _ []string) error {

ch, err := r.customerChannel(customer)
if err != nil {
return err
return errors.Wrap(err, "get customer channel")
}

regHost, err := r.registryHostname(customer, ch)
Expand All @@ -47,7 +47,7 @@ func (r *runners) inspectCustomer(_ *cobra.Command, _ []string) error {
}

if err = print.CustomerAttrs(r.outputFormat, r.w, r.appType, r.appSlug, ch, regHost, customer); err != nil {
return err
return errors.Wrap(err, "print customer attrs")
}

return nil
Expand Down
56 changes: 56 additions & 0 deletions cli/cmd/instance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package cmd

import (
"github.com/pkg/errors"
"github.com/replicatedhq/replicated/pkg/types"
"github.com/spf13/cobra"
)

func (r *runners) InitInstanceCommand(parent *cobra.Command) *cobra.Command {
instanceCmd := &cobra.Command{
Use: "instance",
Short: "Manage instances",
Long: `The instance command allows vendors to display and tag customer instances.`,
}
parent.AddCommand(instanceCmd)

return instanceCmd
}

func findInstanceByNameOrID(nameOrID string, instances []types.Instance) (types.Instance, error) {
var instance types.Instance

isFound := false
for _, i := range instances {
if i.InstanceID == nameOrID || i.Name() == nameOrID {
if isFound {
return types.Instance{}, errors.Errorf("multiple instances found with name or id %q", nameOrID)
}
instance = i
isFound = true
}
}

if !isFound {
return types.Instance{}, errors.Errorf("instance %q not found", nameOrID)
}

return instance, nil
}

func findInstancesByTags(tags []types.Tag, instances []types.Instance) []types.Instance {
result := []types.Instance{}

for _, instance := range instances {
for _, instanceTag := range instance.Tags {
for _, tag := range tags {
if instanceTag.Key == tag.Key && instanceTag.Value == tag.Value {
result = append(result, instance)
break
}
}
}
}

return result
}
55 changes: 55 additions & 0 deletions cli/cmd/instance_inspect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package cmd

import (
"github.com/pkg/errors"
"github.com/spf13/cobra"

"github.com/replicatedhq/replicated/cli/print"
)

func (r *runners) InitInstanceInspectCommand(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "inspect",
Short: "Show full details for a customer instance",
Long: `Show full details for a customer instance`,
RunE: r.inspectInstance,
SilenceUsage: false,
SilenceErrors: true, // this command uses custom error printing
}
parent.AddCommand(cmd)
cmd.Flags().StringVar(&r.args.instanceInspectCustomer, "customer", "", "Customer Name or ID")
cmd.Flags().StringVar(&r.args.instanceInspectInstance, "instance", "", "Instance Name or ID")
cmd.Flags().StringVar(&r.outputFormat, "output", "table", "The output format to use. One of: json|table (default: table)")

return cmd
}

func (r *runners) inspectInstance(cmd *cobra.Command, _ []string) (err error) {
defer func() {
printIfError(cmd, err)
}()

if r.args.instanceInspectCustomer == "" {
return errors.Errorf("missing or invalid parameters: customer")
}

if r.args.instanceInspectInstance == "" {
return errors.Errorf("missing or invalid parameters: instance")
}

customer, err := r.api.GetCustomerByNameOrId(r.appType, r.appID, r.args.instanceInspectCustomer)
if err != nil {
return errors.Wrapf(err, "get customer %q", r.args.instanceInspectCustomer)
}

instance, err := findInstanceByNameOrID(r.args.instanceInspectInstance, customer.Instances)
if err != nil {
return errors.Wrap(err, "find instance")
}

if err = print.Instance(r.outputFormat, r.w, instance); err != nil {
return errors.Wrap(err, "print instance")
}

return nil
}
55 changes: 55 additions & 0 deletions cli/cmd/instance_ls.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package cmd

import (
"github.com/pkg/errors"
"github.com/replicatedhq/replicated/cli/print"
"github.com/spf13/cobra"
)

func (r *runners) InitInstanceLSCommand(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "ls",
Short: "list customer instances",
Long: `list customer instances`,
RunE: r.listInstances,
SilenceUsage: false,
SilenceErrors: true, // this command uses custom error printing
}

parent.AddCommand(cmd)
cmd.Flags().StringVar(&r.args.instanceListCustomer, "customer", "", "Customer Name or ID")
cmd.Flags().StringArrayVar(&r.args.instanceListTags, "tag", []string{}, "Tags to use to filter instances (key=value format, can be specified multiple times). Only one tag needs to match (an OR operation)")
cmd.Flags().StringVar(&r.outputFormat, "output", "table", "The output format to use. One of: json|table (default: table)")

return cmd
}

func (r *runners) listInstances(cmd *cobra.Command, _ []string) (err error) {
defer func() {
printIfError(cmd, err)
}()

if r.args.instanceListCustomer == "" {
return errors.Errorf("missing or invalid parameters: customer")
}

customer, err := r.api.GetCustomerByNameOrId(r.appType, r.appID, r.args.instanceListCustomer)
if err != nil {
return errors.Wrapf(err, "get customer %q", r.args.instanceListCustomer)
}

instances := customer.Instances
if len(r.args.instanceListTags) > 0 {
tags, err := parseTags(r.args.instanceListTags)
if err != nil {
return errors.Wrap(err, "parse tags")
}
instances = findInstancesByTags(tags, customer.Instances)
}

if err := print.Instances(r.outputFormat, r.w, instances); err != nil {
return errors.Wrap(err, "print instances")
}

return nil
}
77 changes: 77 additions & 0 deletions cli/cmd/instance_tag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package cmd

import (
"github.com/pkg/errors"
"github.com/replicatedhq/replicated/cli/print"
"github.com/replicatedhq/replicated/pkg/kotsclient"
"github.com/spf13/cobra"
)

func (r *runners) InitInstanceTagCommand(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "tag",
Short: "tag an instance",
Long: `remove or add instance tags`,
RunE: r.tagInstance,
SilenceUsage: true,
}
parent.AddCommand(cmd)
cmd.Flags().StringVar(&r.args.instanceTagCustomer, "customer", "", "Customer Name or ID")
cmd.Flags().StringVar(&r.args.instanceTagInstacne, "instance", "", "Instance Name or ID")
cmd.Flags().StringArrayVar(&r.args.instanceTagTags, "tag", []string{}, "Tags to use to filter instances (key=value format, can be specified multiple times). Only one tag needs to match (an OR operation)")
cmd.Flags().StringVar(&r.outputFormat, "output", "table", "The output format to use. One of: json|table (default: table)")

return cmd
}

func (r *runners) tagInstance(cmd *cobra.Command, _ []string) (err error) {
defer func() {
printIfError(cmd, err)
}()

if r.args.instanceTagCustomer == "" {
return errors.Errorf("missing or invalid parameters: customer")
}

if r.args.instanceTagInstacne == "" {
return errors.Errorf("missing or invalid parameters: instance")
}

if len(r.args.instanceTagTags) == 0 {
return errors.Errorf("missing or invalid parameters: tag")
}

tags, err := parseTags(r.args.instanceTagTags)
if err != nil {
return errors.Wrap(err, "parse tags")
}

customer, err := r.api.GetCustomerByNameOrId(r.appType, r.appID, r.args.instanceTagCustomer)
if err != nil {
return errors.Wrapf(err, "find customer %q", r.args.instanceTagCustomer)
}

instance, err := findInstanceByNameOrID(r.args.instanceTagInstacne, customer.Instances)
if err != nil {
return errors.Wrap(err, "find instance")
}

apiTags := []kotsclient.InstanceTag{}
for _, tag := range tags {
apiTags = append(apiTags, kotsclient.InstanceTag{
Key: tag.Key,
Value: tag.Value,
})
}

updatedInstance, err := r.api.SetInstanceTags(r.appID, r.appType, customer.ID, instance.InstanceID, apiTags)
if err != nil {
return errors.Wrap(err, "set instance tags")
}

if err := print.Instance(r.outputFormat, r.w, *updatedInstance); err != nil {
return errors.Wrap(err, "print instance")
}

return nil
}
24 changes: 24 additions & 0 deletions cli/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import (
"io"
"os"
"path/filepath"
"strings"
"text/tabwriter"

"github.com/pkg/errors"

"github.com/replicatedhq/replicated/pkg/credentials"
"github.com/replicatedhq/replicated/pkg/kotsclient"
"github.com/replicatedhq/replicated/pkg/shipclient"
"github.com/replicatedhq/replicated/pkg/types"
"github.com/replicatedhq/replicated/pkg/version"

"github.com/replicatedhq/replicated/client"
Expand Down Expand Up @@ -170,6 +172,11 @@ func Execute(rootCmd *cobra.Command, stdin io.Reader, stdout io.Writer, stderr i
runCmds.InitCustomersArchiveCommand(customersCmd)
runCmds.InitCustomersInspectCommand(customersCmd)

instanceCmd := runCmds.InitInstanceCommand(runCmds.rootCmd)
runCmds.InitInstanceLSCommand(instanceCmd)
runCmds.InitInstanceInspectCommand(instanceCmd)
runCmds.InitInstanceTagCommand(instanceCmd)

installerCmd := runCmds.InitInstallerCommand(runCmds.rootCmd)
runCmds.InitInstallerCreate(installerCmd)
runCmds.InitInstallerList(installerCmd)
Expand Down Expand Up @@ -308,6 +315,7 @@ func Execute(rootCmd *cobra.Command, stdin io.Reader, stdout io.Writer, stderr i
collectorsCmd.PersistentPreRunE = prerunCommand
installerCmd.PersistentPreRunE = prerunCommand
customersCmd.PersistentPreRunE = prerunCommand
instanceCmd.PersistentPreRunE = prerunCommand
clusterPrepareCmd.PersistentPreRunE = prerunCommand

appCmd.PersistentPreRunE = preRunSetupAPIs
Expand Down Expand Up @@ -337,3 +345,19 @@ func printIfError(cmd *cobra.Command, err error) {
fmt.Fprintf(os.Stderr, "ERROR: %s\n", err.Error())
}
}

func parseTags(tags []string) ([]types.Tag, error) {
parsedTags := []types.Tag{}
for _, tag := range tags {
tagParts := strings.SplitN(tag, "=", 2)
if len(tagParts) != 2 {
return nil, errors.Errorf("invalid tag format: %s", tag)
}

parsedTags = append(parsedTags, types.Tag{
Key: tagParts[0],
Value: tagParts[1],
})
}
return parsedTags, nil
}
8 changes: 8 additions & 0 deletions cli/cmd/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ type runnerArgs struct {
customerCreateEmail string
customerCreateType string

instanceInspectCustomer string
instanceInspectInstance string
instanceListCustomer string
instanceListTags []string
instanceTagCustomer string
instanceTagInstacne string
instanceTagTags []string

createInstallerYaml string
createInstallerYamlFile string
createInstallerPromote string
Expand Down
Loading

0 comments on commit ce8b20a

Please sign in to comment.