Skip to content

Commit

Permalink
Updating the CMX CLI for Cluster/VM/Network (#417)
Browse files Browse the repository at this point in the history
* New CMX CLI

* update post review
  • Loading branch information
marccampbell authored Oct 8, 2024
1 parent 8a3c96b commit f189d92
Show file tree
Hide file tree
Showing 46 changed files with 724 additions and 337 deletions.
15 changes: 13 additions & 2 deletions cli/cmd/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,19 @@ var (
func (r *runners) InitClusterCommand(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "cluster",
Short: "Manage test clusters",
Long: ``,
Short: "Manage test Kubernetes clusters.",
Long: `The 'cluster' command allows you to manage and interact with Kubernetes clusters used for testing purposes. With this command, you can create, list, remove, and manage node groups within clusters, as well as retrieve information about available clusters.`,
Example: ` # Create a single-node EKS cluster
replicated cluster create --distribution eks --version 1.31
# List all clusters
replicated cluster ls
# Remove a specific cluster by ID
replicated cluster rm <cluster-id>
# Create a node group within a specific cluster
replicated cluster nodegroup create --cluster-id <cluster-id> --instance-type m6.large --nodes 3`,
}
parent.AddCommand(cmd)

Expand Down
22 changes: 21 additions & 1 deletion cli/cmd/cluster_addon.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,27 @@ import (
func (r *runners) InitClusterAddon(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "addon",
Short: "Manage cluster add-ons",
Short: "Manage cluster add-ons.",
Long: `The 'cluster addon' command allows you to manage add-ons installed on a test cluster. Add-ons are additional components or services that can be installed and configured to enhance or extend the functionality of the cluster.
You can use various subcommands to create, list, remove, or check the status of add-ons on a cluster. This command is useful for adding databases, object storage, monitoring, security, or other specialized tools to your cluster environment.`,
Example: ` # List all add-ons installed on a cluster
replicated cluster addon ls CLUSTER_ID
# Remove an add-on from a cluster
replicated cluster addon rm CLUSTER_ID --id ADDON_ID
# Create a Postgres database add-on for a cluster
replicated cluster addon create postgres CLUSTER_ID --version 13 --disk 100 --instance-type db.t3.micro
# Create an object store bucket add-on for a cluster
replicated cluster addon create object-store CLUSTER_ID --bucket-prefix mybucket
# List add-ons with JSON output
replicated cluster addon ls CLUSTER_ID --output json
# Create a Postgres add-on and wait for it to be ready
replicated cluster addon create postgres CLUSTER_ID --version 13 --wait 5m`,
}
parent.AddCommand(cmd)

Expand Down
14 changes: 13 additions & 1 deletion cli/cmd/cluster_addon_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,19 @@ import (
func (r *runners) InitClusterAddonCreate(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "create",
Short: "Create cluster add-ons",
Short: "Create cluster add-ons.",
Long: `Create new add-ons for a cluster. This command allows you to add functionality or services to a cluster by provisioning the required add-ons.`,
Example: ` # Create a Postgres database add-on for a cluster
replicated cluster addon create postgres CLUSTER_ID --version 13 --disk 100 --instance-type db.t3.micro
# Create an object store bucket add-on for a cluster
replicated cluster addon create object-store CLUSTER_ID --bucket-prefix mybucket
# Create a Postgres add-on and wait for it to be ready
replicated cluster addon create postgres CLUSTER_ID --version 13 --wait 5m
# Perform a dry run for creating an object store add-on
replicated cluster addon create object-store CLUSTER_ID --bucket-prefix mybucket --dry-run`,
}
parent.AddCommand(cmd)

Expand Down
36 changes: 22 additions & 14 deletions cli/cmd/cluster_addon_create_objectstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,32 @@ type clusterAddonCreateObjectStoreArgs struct {
outputFormat string
}

const (
clusterAddonCreateObjectStoreShort = "Create an object store bucket for a cluster"
clusterAddonCreateObjectStoreLong = `Create an object store bucket for a cluster.
Requires a bucket name prefix (using flag "--bucket-prefix") that will be used to create a unique bucket name with format "[BUCKET_PREFIX]-[ADDON_ID]-cmx".`
clusterAddonCreateObjectStoreExample = ` $ replicated cluster addon create object-store 05929b24 --bucket-prefix mybucket
05929b24 Object Store pending {"bucket_prefix":"mybucket"}`
)

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

cmd := &cobra.Command{
Use: "object-store CLUSTER_ID --bucket-prefix BUCKET_PREFIX",
Short: clusterAddonCreateObjectStoreShort,
Long: clusterAddonCreateObjectStoreLong,
Example: clusterAddonCreateObjectStoreExample,
Args: cobra.ExactArgs(1),
Use: "object-store CLUSTER_ID --bucket-prefix BUCKET_PREFIX",
Short: "Create an object store bucket for a cluster.",
Long: `Creates an object store bucket for a cluster, requiring a bucket name prefix. The bucket name will be auto-generated using the format "[BUCKET_PREFIX]-[ADDON_ID]-cmx". This feature provisions an object storage bucket that can be used for storage in your cluster environment.
Examples:
# Create an object store bucket with a specified prefix
replicated cluster addon create object-store CLUSTER_ID --bucket-prefix mybucket
# Create an object store bucket and wait for it to be ready (up to 5 minutes)
replicated cluster addon create object-store CLUSTER_ID --bucket-prefix mybucket --wait 5m
# Perform a dry run to validate inputs without creating the bucket
replicated cluster addon create object-store CLUSTER_ID --bucket-prefix mybucket --dry-run
# Create an object store bucket and output the result in JSON format
replicated cluster addon create object-store CLUSTER_ID --bucket-prefix mybucket --output json
# Create an object store bucket with a custom prefix and wait for 10 minutes
replicated cluster addon create object-store CLUSTER_ID --bucket-prefix custom-prefix --wait 10m`,
Example: `$ replicated cluster addon create object-store 05929b24 --bucket-prefix mybucket
05929b24 Object Store pending {"bucket_prefix":"mybucket"}`,
Args: cobra.ExactArgs(1),
RunE: func(_ *cobra.Command, cmdArgs []string) error {
args.clusterID = cmdArgs[0]
return r.clusterAddonCreateObjectStoreCreateRun(args)
Expand Down
21 changes: 19 additions & 2 deletions cli/cmd/cluster_addon_create_postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,25 @@ func (r *runners) InitClusterAddonCreatePostgres(parent *cobra.Command) *cobra.C

cmd := &cobra.Command{
Use: "postgres CLUSTER_ID",
Short: "Create a Postgres database for a cluster",
Args: cobra.ExactArgs(1),
Short: "Create a Postgres database for a cluster.",
Long: `Creates a Postgres database instance for the specified cluster, provisioning it with a specified version, disk size, and instance type. This allows you to attach a managed Postgres instance to your cluster for database functionality.
Examples:
# Create a Postgres database with default settings
replicated cluster addon create postgres CLUSTER_ID
# Create a Postgres 13 database with 500GB disk and a larger instance type
replicated cluster addon create postgres CLUSTER_ID --version 13 --disk 500 --instance-type db.t3.large
# Perform a dry run to validate inputs without creating the database
replicated cluster addon create postgres CLUSTER_ID --dry-run
# Create a Postgres database and wait for it to be ready (up to 10 minutes)
replicated cluster addon create postgres CLUSTER_ID --wait 10m
# Create a Postgres database and output the result in JSON format
replicated cluster addon create postgres CLUSTER_ID --output json`,
Args: cobra.ExactArgs(1),
RunE: func(_ *cobra.Command, cmdArgs []string) error {
args.clusterID = cmdArgs[0]
return r.clusterAddonCreatePostgresCreateRun(args)
Expand Down
15 changes: 13 additions & 2 deletions cli/cmd/cluster_addon_ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,19 @@ func (r *runners) InitClusterAddonLs(parent *cobra.Command) *cobra.Command {

cmd := &cobra.Command{
Use: "ls CLUSTER_ID",
Short: "List cluster add-ons for a cluster",
Args: cobra.ExactArgs(1),
Short: "List cluster add-ons for a cluster.",
Long: `The 'cluster addon ls' command allows you to list all add-ons for a specific cluster. This command provides a detailed overview of the add-ons currently installed on the cluster, including their status and any relevant configuration details.
This can be useful for monitoring the health and configuration of add-ons or performing troubleshooting tasks.`,
Example: ` # List add-ons for a cluster with default table output
replicated cluster addon ls CLUSTER_ID
# List add-ons for a cluster with JSON output
replicated cluster addon ls CLUSTER_ID --output json
# List add-ons for a cluster with wide table output
replicated cluster addon ls CLUSTER_ID --output wide`,
Args: cobra.ExactArgs(1),
RunE: func(_ *cobra.Command, cmdArgs []string) error {
args.clusterID = cmdArgs[0]
return r.addonClusterLsRun(args)
Expand Down
9 changes: 7 additions & 2 deletions cli/cmd/cluster_addon_rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,13 @@ func (r *runners) InitClusterAddonRm(parent *cobra.Command) *cobra.Command {

cmd := &cobra.Command{
Use: "rm CLUSTER_ID --id ADDON_ID",
Short: "Remove cluster add-on by ID",
Args: cobra.ExactArgs(1),
Short: "Remove cluster add-on by ID.",
Long: `The 'cluster addon rm' command allows you to remove a specific add-on from a cluster by specifying the cluster ID and the add-on ID.
This command is useful when you want to deprovision an add-on that is no longer needed or when troubleshooting issues related to specific add-ons. The add-on will be removed immediately, and you will receive confirmation upon successful removal.`,
Example: ` # Remove an add-on with ID 'abc123' from cluster 'cluster456'
replicated cluster addon rm cluster456 --id abc123`,
Args: cobra.ExactArgs(1),
RunE: func(_ *cobra.Command, cmdArgs []string) error {
args.clusterID = cmdArgs[0]
return r.clusterAddonRmRun(args)
Expand Down
31 changes: 27 additions & 4 deletions cli/cmd/cluster_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,37 @@ var ErrWaitDurationExceeded = errors.New("wait duration exceeded")

func (r *runners) InitClusterCreate(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "create",
Short: "Create test clusters",
Long: `Create test clusters.`,
Use: "create",
Short: "Create test clusters.",
Long: `The 'cluster create' command provisions a new test cluster with the specified Kubernetes distribution and configuration. You can customize the cluster's size, version, node groups, disk space, IP family, and other parameters.
This command supports creating clusters on multiple Kubernetes distributions, including setting up node groups with different instance types and counts. You can also specify a TTL (Time-To-Live) to automatically terminate the cluster after a set duration.
Use the '--dry-run' flag to simulate the creation process and get an estimated cost without actually provisioning the cluster.`,
Example: ` # Create a new cluster with basic configuration
replicated cluster create --distribution eks --version 1.21 --nodes 3 --instance-type t3.large --disk 100 --ttl 24h
# Create a cluster with a custom node group
replicated cluster create --distribution eks --version 1.21 --nodegroup name=workers,instance-type=t3.large,nodes=5 --ttl 24h
# Simulate cluster creation (dry-run)
replicated cluster create --distribution eks --version 1.21 --nodes 3 --disk 100 --ttl 24h --dry-run
# Create a cluster with autoscaling configuration
replicated cluster create --distribution eks --version 1.21 --min-nodes 2 --max-nodes 5 --instance-type t3.large --ttl 24h
# Create a cluster with multiple node groups
replicated cluster create --distribution eks --version 1.21 \
--nodegroup name=workers,instance-type=t3.large,nodes=3 \
--nodegroup name=cpu-intensive,instance-type=c5.2xlarge,nodes=2 \
--ttl 24h
# Create a cluster with custom tags
replicated cluster create --distribution eks --version 1.21 --nodes 3 --tag env=test --tag project=demo --ttl 24h`,
SilenceUsage: true,
RunE: r.createCluster,
}
parent.AddCommand(cmd)

cmd.Flags().StringVar(&r.args.createClusterName, "name", "", "Cluster name (defaults to random name)")
cmd.Flags().StringVar(&r.args.createClusterKubernetesDistribution, "distribution", "", "Kubernetes distribution of the cluster to provision")
cmd.Flags().StringVar(&r.args.createClusterKubernetesVersion, "version", "", "Kubernetes version to provision (format is distribution dependent)")
Expand Down
24 changes: 21 additions & 3 deletions cli/cmd/cluster_kubeconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,27 @@ const (

func (r *runners) InitClusterKubeconfig(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "kubeconfig [ID]",
Short: "Download credentials for a test cluster",
Long: `Download credentials for a test cluster`,
Use: "kubeconfig [ID]",
Short: "Download credentials for a test cluster.",
Long: `The 'cluster kubeconfig' command downloads the credentials (kubeconfig) required to access a test cluster. You can either merge these credentials into your existing kubeconfig file or save them as a new file.
This command ensures that the kubeconfig is correctly configured for use with your Kubernetes tools. You can specify the cluster by ID or by name. Additionally, the kubeconfig can be written to a specific file path or printed to stdout.
You can also use this command to automatically update your current Kubernetes context with the downloaded credentials.`,
Example: ` # Download and merge kubeconfig into your existing configuration
replicated cluster kubeconfig CLUSTER_ID
# Save the kubeconfig to a specific file
replicated cluster kubeconfig CLUSTER_ID --output-path ./kubeconfig
# Print the kubeconfig to stdout
replicated cluster kubeconfig CLUSTER_ID --stdout
# Download kubeconfig for a cluster by name
replicated cluster kubeconfig --name "My Cluster"
# Download kubeconfig for a cluster by ID
replicated cluster kubeconfig --id CLUSTER_ID`,
RunE: r.kubeconfigCluster,
ValidArgsFunction: r.completeClusterIDs,
}
Expand Down
27 changes: 24 additions & 3 deletions cli/cmd/cluster_ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,30 @@ 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,
Short: "List test clusters.",
Long: `The 'cluster ls' command lists all test clusters. This command provides information about the clusters, such as their status, name, distribution, version, and creation time. The output can be formatted in different ways, depending on your needs.
You can filter the list of clusters by time range and status (e.g., show only terminated clusters). You can also watch clusters in real-time, which updates the list every few seconds.
Clusters that have been deleted will be shown with a 'deleted' status.`,
Example: ` # List all clusters with default table output
replicated cluster ls
# Show clusters created after a specific date
replicated cluster ls --start-time 2023-01-01T00:00:00Z
# Watch for real-time updates
replicated cluster ls --watch
# List clusters with JSON output
replicated cluster ls --output json
# List only terminated clusters
replicated cluster ls --show-terminated
# List clusters with wide table output
replicated cluster ls --output wide`,
RunE: r.listClusters,
}
parent.AddCommand(cmd)

Expand Down
17 changes: 16 additions & 1 deletion cli/cmd/cluster_nodegroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,22 @@ import (

func (r *runners) InitClusterNodeGroup(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "nodegroup",
Use: "nodegroup",
Short: "Manage node groups for clusters.",
Long: `The 'cluster nodegroup' command provides functionality to manage node groups within a cluster. This command allows you to create, list, update, or remove node groups in a Kubernetes or VM-based cluster.
Node groups define a set of nodes with specific configurations, such as instance types, node counts, or scaling rules. You can use subcommands to perform various actions on node groups.`,
Example: ` # List all node groups for a cluster
replicated cluster nodegroup ls CLUSTER_ID
# Create a new node group in a cluster
replicated cluster nodegroup create CLUSTER_ID --nodes 3 --instance-type m6.large
# Update an existing node group
replicated cluster nodegroup update CLUSTER_ID NODEGROUP_ID --nodes 5
# Remove a node group from a cluster
replicated cluster nodegroup rm CLUSTER_ID NODEGROUP_ID`,
}
parent.AddCommand(cmd)

Expand Down
18 changes: 15 additions & 3 deletions cli/cmd/cluster_nodegroup_ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,21 @@ import (

func (r *runners) InitClusterNodeGroupList(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "ls [ID]",
Short: "List node groups for a cluster",
Long: `List node groups for a cluster`,
Use: "ls [ID]",
Short: "List node groups for a cluster.",
Long: `The 'cluster nodegroup ls' command lists all the node groups associated with a given cluster. Each node group defines a specific set of nodes with particular configurations, such as instance types and scaling options.
You can view information about the node groups within the specified cluster, including their ID, name, node count, and other configuration details.
You must provide the cluster ID to list its node groups.`,
Example: ` # List all node groups in a cluster with default table output
replicated cluster nodegroup ls CLUSTER_ID
# List node groups with JSON output
replicated cluster nodegroup ls CLUSTER_ID --output json
# List node groups with wide table output
replicated cluster nodegroup ls CLUSTER_ID --output wide`,
Args: cobra.ExactArgs(1),
RunE: r.listNodeGroups,
ValidArgsFunction: r.completeClusterIDs,
Expand Down
14 changes: 13 additions & 1 deletion cli/cmd/cluster_port.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,19 @@ import (

func (r *runners) InitClusterPort(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "port",
Use: "port",
Short: "Manage cluster ports.",
Long: `The 'cluster port' command is a parent command for managing ports in a cluster. It allows users to list, remove, or expose specific ports used by the cluster. Use the subcommands (such as 'ls', 'rm', and 'expose') to manage port configurations effectively.
This command provides flexibility for handling ports in various test clusters, ensuring efficient management of cluster networking settings.`,
Example: ` # List all exposed ports in a cluster
replicated cluster port ls [CLUSTER_ID]
# Remove an exposed port from a cluster
replicated cluster port rm [CLUSTER_ID] [PORT]
# Expose a new port in a cluster
replicated cluster port expose [CLUSTER_ID] [PORT]`,
SilenceUsage: true,
Hidden: false,
}
Expand Down
Loading

0 comments on commit f189d92

Please sign in to comment.