Skip to content

Commit

Permalink
Merge branch 'main' into joshd/instance-type-example
Browse files Browse the repository at this point in the history
  • Loading branch information
jdewinne authored Sep 11, 2023
2 parents 7a881bb + 6ac323a commit 8968a87
Show file tree
Hide file tree
Showing 17 changed files with 251 additions and 69 deletions.
14 changes: 7 additions & 7 deletions cli/cmd/cluster_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ func (r *runners) InitClusterCreate(parent *cobra.Command) *cobra.Command {
cmd.Flags().IntVar(&r.args.createClusterNodeCount, "nodes", int(1), "Node count")
cmd.Flags().Int64Var(&r.args.createClusterDiskGiB, "disk", int64(50), "Disk Size (GiB) to request per node")
cmd.Flags().StringVar(&r.args.createClusterTTL, "ttl", "", "Cluster TTL (duration, max 48h)")
cmd.Flags().BoolVar(&r.args.createClusterDryRun, "dry-run", false, "Dry run")
cmd.Flags().DurationVar(&r.args.createClusterWaitDuration, "wait", time.Second*0, "Wait duration for cluster to be ready (leave empty to not wait)")

cmd.Flags().StringVar(&r.args.createClusterInstanceType, "instance-type", "", "The type of instance to use (e.g. m6i.large)")
cmd.Flags()
cmd.Flags().BoolVar(&r.args.createClusterDryRun, "dry-run", false, "Dry run")

cmd.Flags().StringVar(&r.outputFormat, "output", "table", "The output format to use. One of: json|table (default: table)")

cmd.MarkFlagRequired("distribution")
cmd.MarkFlagRequired("version")
_ = cmd.MarkFlagRequired("distribution")
_ = cmd.MarkFlagRequired("version")

return cmd
}
Expand All @@ -54,8 +54,8 @@ func (r *runners) createCluster(_ *cobra.Command, args []string) error {
NodeCount: r.args.createClusterNodeCount,
DiskGiB: r.args.createClusterDiskGiB,
TTL: r.args.createClusterTTL,
DryRun: r.args.createClusterDryRun,
InstanceType: r.args.createClusterInstanceType,
DryRun: r.args.createClusterDryRun,
}
cl, err := r.createAndWaitForCluster(opts)
if err != nil {
Expand All @@ -80,7 +80,7 @@ func (r *runners) createAndWaitForCluster(opts kotsclient.CreateClusterOpts) (*t

if ve != nil && len(ve.Errors) > 0 {
if len(ve.SupportedDistributions) > 0 {
print.ClusterVersions("table", r.w, ve.SupportedDistributions)
_ = print.ClusterVersions("table", r.w, ve.SupportedDistributions)
}
return nil, fmt.Errorf("%s", errors.New(strings.Join(ve.Errors, ",")))
}
Expand Down Expand Up @@ -111,7 +111,7 @@ func waitForCluster(kotsRestClient *kotsclient.VendorV3Client, id string, durati

if cluster.Status == types.ClusterStatusRunning {
return cluster, nil
} else if cluster.Status == types.ClusterStatusError {
} else if cluster.Status == types.ClusterStatusError || cluster.Status == types.ClusterStatusUpgradeError {
return nil, errors.New("cluster failed to provision")
} else {
if time.Now().After(start.Add(duration)) {
Expand Down
17 changes: 9 additions & 8 deletions cli/cmd/cluster_ls.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package cmd

import (
"fmt"
"reflect"
"time"

Expand All @@ -15,10 +14,10 @@ import (

func (r *runners) InitClusterList(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "ls",
Short: "list test clusters",
Long: `list test clusters`,
RunE: r.listClusters,
Use: "ls",
Short: "list test clusters",
Long: `list test clusters`,
RunE: r.listClusters,
}
parent.AddCommand(cmd)

Expand Down Expand Up @@ -56,6 +55,7 @@ func (r *runners) listClusters(_ *cobra.Command, args []string) error {
return errors.Wrap(err, "list clusters")
}

header := true
if r.args.lsClusterWatch {

// Checks to see if the outputFormat is table
Expand Down Expand Up @@ -118,17 +118,18 @@ func (r *runners) listClusters(_ *cobra.Command, args []string) error {

// Prints the clusters
if len(clustersToPrint) > 0 {
fmt.Print("\033[H\033[2J") // Clears the console
print.Clusters(r.outputFormat, r.w, clustersToPrint)
print.Clusters(r.outputFormat, r.w, clustersToPrint, header)
header = false // only print the header once
}

clusters = newClusters
clustersToPrint = make([]*types.Cluster, 0)
}
}

if len(clusters) == 0 {
return print.NoClusters(r.outputFormat, r.w)
}

return print.Clusters(r.outputFormat, r.w, clusters)
return print.Clusters(r.outputFormat, r.w, clusters, true)
}
85 changes: 85 additions & 0 deletions cli/cmd/cluster_upgrade.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package cmd

import (
"fmt"
"strings"

"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"
)

func (r *runners) InitClusterUpgrade(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "upgrade [cluster id]",
Short: "Upgrade a test clusters",
Long: `Upgrade a test clusters`,
Args: cobra.ExactArgs(1),
RunE: r.upgradeCluster,
SilenceUsage: true,
}
parent.AddCommand(cmd)

cmd.Flags().StringVar(&r.args.upgradeClusterKubernetesVersion, "version", "", "Kubernetes version to upgrade to (format is distribution dependent)")
cmd.Flags().BoolVar(&r.args.upgradeClusterDryRun, "dry-run", false, "Dry run")
cmd.Flags().DurationVar(&r.args.upgradeClusterWaitDuration, "wait", 0, "Wait duration for cluster to be ready (leave empty to not wait)")

cmd.Flags().StringVar(&r.outputFormat, "output", "table", "The output format to use. One of: json|table (default: table)")

_ = cmd.MarkFlagRequired("version")

return cmd
}

func (r *runners) upgradeCluster(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return errors.New("cluster id is required")
}
clusterID := args[0]

opts := kotsclient.UpgradeClusterOpts{
KubernetesVersion: r.args.upgradeClusterKubernetesVersion,
DryRun: r.args.upgradeClusterDryRun,
}
cl, err := r.upgradeAndWaitForCluster(clusterID, opts)
if err != nil {
return err
}

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

return print.Cluster(r.outputFormat, r.w, cl)
}

func (r *runners) upgradeAndWaitForCluster(clusterID string, opts kotsclient.UpgradeClusterOpts) (*types.Cluster, error) {
cl, ve, err := r.kotsAPI.UpgradeCluster(clusterID, opts)
if errors.Cause(err) == platformclient.ErrForbidden {
return nil, ErrCompatibilityMatrixTermsNotAccepted
} else if err != nil {
return nil, errors.Wrap(err, "upgrade cluster")
}

if ve != nil && len(ve.Errors) > 0 {
if len(ve.SupportedDistributions) > 0 {
_ = print.ClusterVersions("table", r.w, ve.SupportedDistributions)
}
return nil, fmt.Errorf("%s", errors.New(strings.Join(ve.Errors, ",")))
}

if opts.DryRun {
return nil, nil
}

// if the wait flag was provided, we poll the api until the cluster is ready, or a timeout
if r.args.upgradeClusterWaitDuration > 0 {
return waitForCluster(r.kotsAPI, cl.ID, r.args.upgradeClusterWaitDuration)
}

return cl, nil
}
12 changes: 8 additions & 4 deletions cli/cmd/customer_archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,23 @@ func (r *runners) InitCustomersArchiveCommand(parent *cobra.Command) *cobra.Comm
SilenceUsage: true,
}
parent.AddCommand(cmd)
cmd.Flags().StringVar(&r.args.customerLicenseInspectCustomer, "customer", "", "The Customer Name or ID")
cmd.Flags().StringVar(&r.args.customerArchiveNameOrId, "customer", "", "The Customer Name or ID")

return cmd
}

func (r *runners) archiveCustomer(_ *cobra.Command, _ []string) error {
if r.args.customerLicenseInspectCustomer == "" {
if r.args.customerArchiveNameOrId == "" {
return errors.Errorf("missing or invalid parameters: customer")
}

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

if err := r.api.ArchiveCustomer(r.appType, customer.ID); err != nil {
return errors.Wrapf(err, "archive customer %q", r.args.customerArchiveNameOrId)
}

return nil
Expand Down
2 changes: 1 addition & 1 deletion cli/cmd/customer_download_license.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func (r *runners) downloadCustomerLicense(_ *cobra.Command, _ []string) error {
return errors.Errorf("missing or invalid parameters: output")
}

customer, err := r.api.GetCustomerByName(r.appType, r.appID, r.args.customerLicenseInspectCustomer)
customer, err := r.api.GetCustomerByNameOrId(r.appType, r.appID, r.args.customerLicenseInspectCustomer)
if err != nil {
return errors.Wrapf(err, "find customer %q", r.args.customerLicenseInspectCustomer)
}
Expand Down
2 changes: 1 addition & 1 deletion cli/cmd/customer_inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func (r *runners) inspectCustomer(_ *cobra.Command, _ []string) error {
return errors.Errorf("missing or invalid parameters: customer")
}

customer, err := r.api.GetCustomerByName(r.appType, r.appID, r.args.customerInspectCustomer)
customer, err := r.api.GetCustomerByNameOrId(r.appType, r.appID, r.args.customerInspectCustomer)
if err != nil {
return errors.Wrapf(err, "get customer %q", r.args.customerInspectCustomer)
}
Expand Down
8 changes: 4 additions & 4 deletions cli/cmd/release_compatibility.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ import (
func (r *runners) InitReleaseCompatibility(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "compatibility SEQUENCE",
Short: "report release compatibility",
Long: "report release compatibility for a kubernetes distribution and version",
Short: "Report release compatibility",
Long: "Report release compatibility for a kubernetes distribution and version",
RunE: r.reportReleaseCompatibility,
}
parent.AddCommand(cmd)

cmd.Flags().StringVar(&r.args.compatibilityKubernetesDistribution, "distribution", "kind", "Kubernetes distribution of the cluster to report on.")
cmd.Flags().StringVar(&r.args.compatibilityKubernetesVersion, "version", "1.25.3", "Kubernetes version of the cluster to report on (format is distribution dependent)")
cmd.Flags().StringVar(&r.args.compatibilityKubernetesDistribution, "distribution", "", "Kubernetes distribution of the cluster to report on.")
cmd.Flags().StringVar(&r.args.compatibilityKubernetesVersion, "version", "", "Kubernetes version of the cluster to report on (format is distribution dependent)")
cmd.Flags().BoolVar(&r.args.compatibilitySuccess, "success", false, "If set, the compatibility will be reported as a success.")
cmd.Flags().BoolVar(&r.args.compatibilityFailure, "failure", false, "If set, the compatibility will be reported as a failure.")
cmd.Flags().StringVar(&r.args.compatibilityNotes, "notes", "", "Additional notes to report.")
Expand Down
1 change: 1 addition & 0 deletions cli/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ func Execute(rootCmd *cobra.Command, stdin io.Reader, stdout io.Writer, stderr i

clusterCmd := runCmds.InitClusterCommand(runCmds.rootCmd)
runCmds.InitClusterCreate(clusterCmd)
runCmds.InitClusterUpgrade(clusterCmd)
runCmds.InitClusterList(clusterCmd)
runCmds.InitClusterKubeconfig(clusterCmd)
runCmds.InitClusterRemove(clusterCmd)
Expand Down
5 changes: 5 additions & 0 deletions cli/cmd/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ type runnerArgs struct {

customerLsIncludeTest bool

customerArchiveNameOrId string
customerCreateName string
customerCreateChannel string
customerCreateEnsureChannel bool
Expand Down Expand Up @@ -171,6 +172,10 @@ type runnerArgs struct {
createClusterWaitDuration time.Duration
createClusterInstanceType string

upgradeClusterKubernetesVersion string
upgradeClusterDryRun bool
upgradeClusterWaitDuration time.Duration

prepareClusterID string
prepareClusterName string
prepareClusterKubernetesDistribution string
Expand Down
20 changes: 14 additions & 6 deletions cli/print/clusters.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,31 @@ import (
)

// TODO: implement a -o wide, and expose nodecount also?
var clustersTmplSrc = `ID NAME DISTRIBUTION VERSION STATUS CREATED EXPIRES
{{ range . -}}
{{ .ID }} {{ .Name }} {{ .KubernetesDistribution}} {{ .KubernetesVersion }} {{ .Status }} {{ .CreatedAt}} {{if .ExpiresAt.IsZero}}-{{else}}{{ .ExpiresAt }}{{end}}
var clustersTmplHeaderSrc = `ID NAME DISTRIBUTION VERSION STATUS CREATED EXPIRES`
var clustersTmplRowSrc = `{{ range . -}}
{{ .ID }} {{ padding .Name 27 }} {{ padding .KubernetesDistribution 12 }} {{ padding .KubernetesVersion 10 }} {{ padding (printf "%s" .Status) 12 }} {{ .CreatedAt}} {{if .ExpiresAt.IsZero}}-{{else}}{{ .ExpiresAt }}{{end}}
{{ end }}`
var clustersTmplSrc = fmt.Sprintln(clustersTmplHeaderSrc) + clustersTmplRowSrc

var clusterVersionsTmplSrc = `Supported Kubernetes distributions and versions are:
DISTRIBUTION VERSION INSTANCE_TYPES
{{ range $d := . -}}{{ $d.Name }} {{ range $i, $v := $d.Versions -}}{{if $i}}, {{end}}{{ $v }}{{ end }} {{ range $i, $it := $d.InstanceTypes -}}{{if $i}}, {{end}}{{ $it }}{{ end }}
{{ end }}`

var clustersTmpl = template.Must(template.New("clusters").Funcs(funcs).Parse(clustersTmplSrc))
var clustersTmplNoHeader = template.Must(template.New("clusters").Funcs(funcs).Parse(clustersTmplRowSrc))
var clusterVersionsTmpl = template.Must(template.New("clusterVersions").Funcs(funcs).Parse(clusterVersionsTmplSrc))

func Clusters(outputFormat string, w *tabwriter.Writer, clusters []*types.Cluster) error {
func Clusters(outputFormat string, w *tabwriter.Writer, clusters []*types.Cluster, header bool) error {
if outputFormat == "table" {
if err := clustersTmpl.Execute(w, clusters); err != nil {
return err
if header {
if err := clustersTmpl.Execute(w, clusters); err != nil {
return err
}
} else {
if err := clustersTmplNoHeader.Execute(w, clusters); err != nil {
return err
}
}
} else if outputFormat == "json" {
cAsByte, _ := json.MarshalIndent(clusters, "", " ")
Expand Down
6 changes: 6 additions & 0 deletions cli/print/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,10 @@ var funcs = template.FuncMap{
"time": func(t time.Time) string {
return t.Format(time.RFC3339)
},
"padding": func(s string, width int) string {
for len(s) < width {
s += " "
}
return s
},
}
4 changes: 2 additions & 2 deletions client/customer.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ func (c *Client) CreateCustomer(appType string, opts kotsclient.CreateCustomerOp

}

func (c *Client) GetCustomerByName(appType string, appID, name string) (*types.Customer, error) {
func (c *Client) GetCustomerByNameOrId(appType string, appID, nameOrId string) (*types.Customer, error) {
if appType == "platform" {
return nil, errors.New("listing customers is not supported for platform applications")
} else if appType == "kots" {
return c.KotsClient.GetCustomerByName(appID, name)
return c.KotsClient.GetCustomerByNameOrId(appID, nameOrId)
}

return nil, errors.Errorf("unknown app type %q", appType)
Expand Down
Loading

0 comments on commit 8968a87

Please sign in to comment.