diff --git a/api/pod.go b/api/pod.go index 0fe7cf6..a27752c 100644 --- a/api/pod.go +++ b/api/pod.go @@ -20,11 +20,22 @@ type MySelfData struct { Pods []*Pod } type Pod struct { - Id string - Name string - ImageName string - DesiredStatus string - Machine *Machine + Id string + ContainerDiskInGb int + CostPerHr float32 + DesiredStatus string + DockerArgs string + Env []string + GpuCount int + ImageName string + MemoryInGb int + Name string + PodType string + Ports string + VcpuCount int + VolumeInGb int + VolumeMountPath string + Machine *Machine } type Machine struct { GpuDisplayName string @@ -37,25 +48,25 @@ func QueryPods() (pods []*Pod, err error) { myself { pods { id - machineId - name - dockerId + containerDiskInGb + costPerHr + desiredStatus dockerArgs + dockerId + env + gpuCount imageName + lastStatusChange + machineId + memoryInGb + name + podType port ports - podType - gpuCount + uptimeSeconds vcpuCount - containerDiskInGb - memoryInGb volumeInGb volumeMountPath - desiredStatus - uptimeSeconds - costPerHr - env - lastStatusChange machine { gpuDisplayName } diff --git a/cmd/config/config.go b/cmd/config/config.go index 7f37231..fa368c1 100644 --- a/cmd/config/config.go +++ b/cmd/config/config.go @@ -10,16 +10,15 @@ import ( ) var ConfigFile string -var ApiKey string +var apiKey string -// ConfigCmd represents the config command var ConfigCmd = &cobra.Command{ Use: "config", Short: "CLI Config", Long: "RunPod CLI Config Settings", Run: func(c *cobra.Command, args []string) { - ApiKey = strings.TrimSpace(ApiKey) - if len(ApiKey) == 0 { + apiKey = strings.TrimSpace(apiKey) + if len(apiKey) == 0 { cobra.CheckErr(errors.New("apiKey cannot be empty")) } err := viper.WriteConfig() @@ -30,7 +29,7 @@ var ConfigCmd = &cobra.Command{ } func init() { - ConfigCmd.Flags().StringVar(&ApiKey, "apiKey", "", "runpod api key") + ConfigCmd.Flags().StringVar(&apiKey, "apiKey", "", "runpod api key") ConfigCmd.MarkFlagRequired("apiKey") viper.BindPFlag("apiKey", ConfigCmd.Flags().Lookup("apiKey")) viper.SetDefault("apiKey", "") diff --git a/cmd/get.go b/cmd/get.go new file mode 100644 index 0000000..53af74f --- /dev/null +++ b/cmd/get.go @@ -0,0 +1,17 @@ +package cmd + +import ( + "cli/cmd/pod" + + "github.com/spf13/cobra" +) + +var getCmd = &cobra.Command{ + Use: "get [command]", + Short: "get resource", + Long: "get resources for pods", +} + +func init() { + getCmd.AddCommand(pod.GetPodCmd) +} diff --git a/cmd/pod/getPod.go b/cmd/pod/getPod.go new file mode 100644 index 0000000..5f92501 --- /dev/null +++ b/cmd/pod/getPod.go @@ -0,0 +1,63 @@ +package pod + +import ( + "cli/api" + "cli/table" + "fmt" + "os" + "strings" + + "github.com/olekukonko/tablewriter" + "github.com/spf13/cobra" +) + +var AllFields bool + +var GetPodCmd = &cobra.Command{ + Use: "pod [podId]", + Aliases: []string{"pods"}, + Args: cobra.MaximumNArgs(1), + Short: "get all pods", + Long: "get all pods or specify pod id", + Run: func(cmd *cobra.Command, args []string) { + pods, err := api.QueryPods() + cobra.CheckErr(err) + + fmt.Println(AllFields) + + data := make([][]string, len(pods)) + for i, p := range pods { + if len(args) == 1 && p.Id != strings.ToLower(args[0]) { + continue + } + row := []string{p.Id, p.Name, fmt.Sprintf("%d %s", p.GpuCount, p.Machine.GpuDisplayName), p.ImageName, p.DesiredStatus} + if AllFields { + row = append( + row, + p.PodType, + fmt.Sprintf("%d", p.VcpuCount), + fmt.Sprintf("%d", p.MemoryInGb), + fmt.Sprintf("%d", p.ContainerDiskInGb), + fmt.Sprintf("%d", p.VolumeInGb), + fmt.Sprintf("%.3f", p.CostPerHr), + ) + } + data[i] = row + } + + header := []string{"ID", "Name", "GPU", "Image Name", "Status"} + if AllFields { + header = append(header, "Pod Type", "vCPU", "Mem", "Container Disk", "Volume Disk", "$/hr") + } + + tb := tablewriter.NewWriter(os.Stdout) + tb.SetHeader(header) + tb.AppendBulk(data) + table.Defaults(tb) + tb.Render() + }, +} + +func init() { + GetPodCmd.Flags().BoolVarP(&AllFields, "allfields", "a", false, "include all fields in output") +} diff --git a/cmd/pod/ls.go b/cmd/pod/ls.go deleted file mode 100644 index 802d4e9..0000000 --- a/cmd/pod/ls.go +++ /dev/null @@ -1,23 +0,0 @@ -package pod - -import ( - "cli/api" - "fmt" - - "github.com/spf13/cobra" -) - -// lsCmd represents the ls command -var lsCmd = &cobra.Command{ - Use: "ls", - Short: "list of pods", - Long: `List of pods in RUNNING status.`, - Run: func(cmd *cobra.Command, args []string) { - pods, err := api.QueryPods() - cobra.CheckErr(err) - - for _, p := range pods { - fmt.Println(p.Id, p.Name, p.ImageName, p.DesiredStatus) - } - }, -} diff --git a/cmd/pod/pod.go b/cmd/pod/pod.go deleted file mode 100644 index 898213f..0000000 --- a/cmd/pod/pod.go +++ /dev/null @@ -1,21 +0,0 @@ -package pod - -import ( - "github.com/spf13/cobra" -) - -// PodCmd represents the pod command -var PodCmd = &cobra.Command{ - Use: "pod", - Short: "A brief description of your command", - Long: `A longer description that spans multiple lines and likely contains examples -and usage of using your command. For example: - -Cobra is a CLI library for Go that empowers applications. -This application is a tool to generate the needed files -to quickly create a Cobra application.`, -} - -func init() { - PodCmd.AddCommand(lsCmd) -} diff --git a/cmd/root.go b/cmd/root.go index 923d091..08581ef 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -4,7 +4,6 @@ import ( "os" "cli/cmd/config" - "cli/cmd/pod" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -12,9 +11,9 @@ import ( // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ - Use: "runpod-cli", - Short: "RunPod CLI", - Long: "RUNPOD CLI", + Use: "runpodctl", + Short: "runpodctl for runpod.io", + Long: "runpodctl is a CLI tool to manage your pods for runpod.io", } // Execute adds all child commands to the root command and sets flags appropriately. @@ -28,7 +27,7 @@ func Execute() { func init() { cobra.OnInitialize(initConfig) - rootCmd.AddCommand(pod.PodCmd) + rootCmd.AddCommand(getCmd) rootCmd.AddCommand(config.ConfigCmd) } diff --git a/go.mod b/go.mod index 19d0617..d58177f 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,9 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/magiconair/properties v1.8.5 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect github.com/mitchellh/mapstructure v1.4.3 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pelletier/go-toml v1.9.4 // indirect github.com/spf13/afero v1.6.0 // indirect github.com/spf13/cast v1.4.1 // indirect diff --git a/go.sum b/go.sum index 4de8c73..8265a0a 100644 --- a/go.sum +++ b/go.sum @@ -11,8 +11,12 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/table/table.go b/table/table.go new file mode 100644 index 0000000..b8258bb --- /dev/null +++ b/table/table.go @@ -0,0 +1,19 @@ +package table + +import ( + "github.com/olekukonko/tablewriter" +) + +func Defaults(table *tablewriter.Table) { + table.SetAutoWrapText(false) + table.SetAutoFormatHeaders(true) + table.SetHeaderAlignment(tablewriter.ALIGN_LEFT) + table.SetAlignment(tablewriter.ALIGN_LEFT) + table.SetCenterSeparator("") + table.SetColumnSeparator("") + table.SetRowSeparator("") + table.SetHeaderLine(false) + table.SetBorder(false) + table.SetTablePadding("\t") + table.SetNoWhiteSpace(true) +}