Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion cli/cmd/cluster_addon.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,44 @@
package cmd

import (
"time"

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

func (r *runners) InitClusterAddOn(parent *cobra.Command) *cobra.Command {
func (r *runners) InitClusterAddon(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "addon",
Short: "Manage cluster addons",
Hidden: true, // this feature is not fully implemented and controlled behind a feature toggle in the api until ready
}
parent.AddCommand(cmd)

return cmd
}

func waitForAddon(kotsRestClient *kotsclient.VendorV3Client, clusterID, id string, duration time.Duration) (*types.ClusterAddon, error) {
start := time.Now()
for {
addon, err := kotsRestClient.GetClusterAddon(clusterID, id)
if err != nil {
return nil, errors.Wrap(err, "get cluster addon")
}

if addon.Status == types.ClusterAddonStatusRunning {
return addon, nil
} else if addon.Status == types.ClusterAddonStatusError {
return nil, errors.New("cluster addon failed to provision")
} else {
if time.Now().After(start.Add(duration)) {
// In case of timeout, return the cluster and a WaitDurationExceeded error
return addon, ErrWaitDurationExceeded
}
}

time.Sleep(time.Second * 5)
}
}
15 changes: 15 additions & 0 deletions cli/cmd/cluster_addon_create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package cmd

import (
"github.com/spf13/cobra"
)

func (r *runners) InitClusterAddonCreate(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "create",
Short: "Create cluster addons",
}
parent.AddCommand(cmd)

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

import (
"fmt"
"os"
"time"

"github.com/pkg/errors"
"github.com/replicatedhq/replicated/cli/print"
"github.com/replicatedhq/replicated/pkg/kotsclient"
"github.com/replicatedhq/replicated/pkg/platformclient"
"github.com/replicatedhq/replicated/pkg/types"
"github.com/spf13/cobra"
)

type clusterAddonCreateObjectStoreArgs struct {
objectStoreBucket string
clusterID string
waitDuration time.Duration
dryRun bool
outputFormat string
}

func (r *runners) InitClusterAddonCreateObjectStore(parent *cobra.Command) *cobra.Command {
args := clusterAddonCreateObjectStoreArgs{}

cmd := &cobra.Command{
Use: "object-store CLUSTER_ID --bucket BUCKET_NAME",
Short: "Create an object store for a cluster",
Args: cobra.ExactArgs(1),
RunE: func(_ *cobra.Command, cmdArgs []string) error {
args.clusterID = cmdArgs[0]
return r.clusterAddonCreateObjectStoreCreateRun(args)
},
}
parent.AddCommand(cmd)

_ = clusterAddonCreateObjectStoreFlags(cmd, &args)

return cmd
}

func clusterAddonCreateObjectStoreFlags(cmd *cobra.Command, args *clusterAddonCreateObjectStoreArgs) error {
cmd.Flags().StringVar(&args.objectStoreBucket, "bucket", "", "The object store bucket name to create (required)")
err := cmd.MarkFlagRequired("bucket")
if err != nil {
return err
}
cmd.Flags().DurationVar(&args.waitDuration, "wait", 0, "Wait duration for addon to be ready (leave empty to not wait)")
cmd.Flags().BoolVar(&args.dryRun, "dry-run", false, "Dry run")
cmd.Flags().StringVar(&args.outputFormat, "output", "table", "The output format to use. One of: json|table|wide (default: table)")
return nil
}

func (r *runners) clusterAddonCreateObjectStoreCreateRun(args clusterAddonCreateObjectStoreArgs) error {
opts := kotsclient.CreateClusterAddonObjectStoreOpts{
ClusterID: args.clusterID,
Bucket: args.objectStoreBucket,
DryRun: args.dryRun,
}

addon, err := r.createAndWaitForClusterAddonCreateObjectStore(opts, args.waitDuration)
if err != nil {
if errors.Cause(err) == ErrWaitDurationExceeded {
defer func() {
os.Exit(124)
}()
} else {
return err
}
}

if opts.DryRun {
_, err := fmt.Fprintln(r.w, "Dry run succeeded.")
return err
}

return print.Addon(args.outputFormat, r.w, addon)
}

func (r *runners) createAndWaitForClusterAddonCreateObjectStore(opts kotsclient.CreateClusterAddonObjectStoreOpts, waitDuration time.Duration) (*types.ClusterAddon, error) {
addon, err := r.kotsAPI.CreateClusterAddonObjectStore(opts)
if errors.Cause(err) == platformclient.ErrForbidden {
return nil, ErrCompatibilityMatrixTermsNotAccepted
} else if err != nil {
return nil, errors.Wrap(err, "create cluster addon object store")
}

if opts.DryRun {
return addon, nil
}

// if the wait flag was provided, we poll the api until the cluster is ready, or a timeout
if waitDuration > 0 {
return waitForAddon(r.kotsAPI, opts.ClusterID, addon.ID, waitDuration)
}

return addon, nil
}
14 changes: 0 additions & 14 deletions cli/cmd/cluster_addon_ingress.go

This file was deleted.

73 changes: 0 additions & 73 deletions cli/cmd/cluster_addon_ingress_create.go

This file was deleted.

31 changes: 25 additions & 6 deletions cli/cmd/cluster_addon_ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,40 @@ import (
"github.com/spf13/cobra"
)

func (r *runners) InitClusterAddOnLs(parent *cobra.Command) *cobra.Command {
type clusterAddonLsArgs struct {
clusterID string
outputFormat string
}

func (r *runners) InitClusterAddonLs(parent *cobra.Command) *cobra.Command {
args := clusterAddonLsArgs{}

cmd := &cobra.Command{
Use: "ls",
RunE: r.addOnClusterLs,
Use: "ls CLUSTER_ID",
Short: "List cluster addons for a cluster",
Args: cobra.ExactArgs(1),
RunE: func(_ *cobra.Command, cmdArgs []string) error {
args.clusterID = cmdArgs[0]
return r.addonClusterLsRun(args)
},
}
parent.AddCommand(cmd)

_ = clusterAddonLsFlags(cmd, &args)

return cmd
}

func (r *runners) addOnClusterLs(_ *cobra.Command, args []string) error {
addons, err := r.kotsAPI.ListClusterAddOns()
func clusterAddonLsFlags(cmd *cobra.Command, args *clusterAddonLsArgs) error {
cmd.Flags().StringVar(&args.outputFormat, "output", "table", "The output format to use. One of: json|table|wide (default: table)")
return nil
}

func (r *runners) addonClusterLsRun(args clusterAddonLsArgs) error {
addons, err := r.kotsAPI.ListClusterAddons(args.clusterID)
if err != nil {
return err
}

return print.AddOns(r.outputFormat, r.w, addons, true)
return print.Addons(r.outputFormat, r.w, addons, true)
}
39 changes: 32 additions & 7 deletions cli/cmd/cluster_addon_rm.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,50 @@
package cmd

import (
"fmt"

"github.com/spf13/cobra"
)

func (r *runners) InitClusterAddOnRm(parent *cobra.Command) *cobra.Command {
type clusterAddonRmArgs struct {
id string
clusterID string
}

func (r *runners) InitClusterAddonRm(parent *cobra.Command) *cobra.Command {
args := clusterAddonRmArgs{}

cmd := &cobra.Command{
Use: "rm",
RunE: r.addOnClusterRm,
Args: cobra.ExactArgs(1),
Use: "rm CLUSTER_ID --id ADDON_ID",
Short: "Remove cluster addon by ID",
Args: cobra.ExactArgs(1),
RunE: func(_ *cobra.Command, cmdArgs []string) error {
args.clusterID = cmdArgs[0]
return r.clusterAddonRmRun(args)
},
}
parent.AddCommand(cmd)

_ = clusterAddonRmFlags(cmd, &args)

return cmd
}

func (r *runners) addOnClusterRm(_ *cobra.Command, args []string) error {
err := r.kotsAPI.DeleteClusterAddOn(args[0])
func clusterAddonRmFlags(cmd *cobra.Command, args *clusterAddonRmArgs) error {
cmd.Flags().StringVar(&args.id, "id", "", "The ID of the cluster addon to remove (required)")
err := cmd.MarkFlagRequired("id")
if err != nil {
return err
}

return nil
}

func (r *runners) clusterAddonRmRun(args clusterAddonRmArgs) error {
err := r.kotsAPI.DeleteClusterAddon(args.clusterID, args.id)
if err != nil {
return err
}

_, err = fmt.Fprintf(r.w, "Addon %s has been deleted\n", args.id)
return err
}
2 changes: 1 addition & 1 deletion cli/cmd/cluster_port_expose.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

func (r *runners) InitClusterPortExpose(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "expose <cluster-id> --port <port> --protocol <protocol>",
Use: "expose CLUSTER_ID --port PORT --protocol PROTOCOL",
RunE: r.clusterPortExpose,
Args: cobra.ExactArgs(1),
}
Expand Down
2 changes: 1 addition & 1 deletion cli/cmd/cluster_port_ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

func (r *runners) InitClusterPortLs(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "ls",
Use: "ls CLUSTER_ID",
RunE: r.clusterPortList,
Args: cobra.ExactArgs(1),
}
Expand Down
2 changes: 1 addition & 1 deletion cli/cmd/cluster_port_rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

func (r *runners) InitClusterPortRm(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "rm",
Use: "rm CLUSTER_ID",
RunE: r.clusterPortRemove,
Args: cobra.ExactArgs(1),
}
Expand Down
Loading