8af6cd6b1fcf65085dc0de8395ad1d63ffe28f10 — Louis Solofrizzo 16 days ago 9711600
csc: Add new command line utility

Signed-off-by: Louis Solofrizzo <lsolofrizzo@online.net>
A csc/CMakeLists.txt => csc/CMakeLists.txt +3 -0
@@ 0,0 1,3 @@
+ add_go_component(csc
+     main.go
+ )

A csc/cmd/admin.go => csc/cmd/admin.go +14 -0
@@ 0,0 1,14 @@
+ package cmd
+ 
+ import (
+ 	"github.com/spf13/cobra"
+ )
+ 
+ var AdminRootCmd = &cobra.Command{
+ 	Use:   "admin",
+ 	Short: "Utilities for admins",
+ }
+ 
+ func init() {
+ 	RootCmd.AddCommand(AdminRootCmd)
+ }

A csc/cmd/admin/quotas.go => csc/cmd/admin/quotas.go +15 -0
@@ 0,0 1,15 @@
+ package admin
+ 
+ import (
+ 	"cisco/csc/cmd"
+ 	"github.com/spf13/cobra"
+ )
+ 
+ var AdminQuotasRootCmd = &cobra.Command{
+ 	Use:   "quotas",
+ 	Short: "Administrator utilities for quotas",
+ }
+ 
+ func init() {
+ 	cmd.AdminRootCmd.AddCommand(AdminQuotasRootCmd)
+ }

A csc/cmd/admin/quotas/create.go => csc/cmd/admin/quotas/create.go +25 -0
@@ 0,0 1,25 @@
+ package adminquotas
+ 
+ import (
+ 	"cisco/csc/cmd/admin"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/spf13/cobra"
+ )
+ 
+ var AdminQuotasCreateRootCmd = &cobra.Command{
+ 	Use:   "create",
+ 	Short: "Create a new quota",
+ 	Args:  cobra.ExactArgs(1),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 		err := cisco.CreateQuota(args[0])
+ 
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 		}
+ 	},
+ }
+ 
+ func init() {
+ 	admin.AdminQuotasRootCmd.AddCommand(AdminQuotasCreateRootCmd)
+ }

A csc/cmd/admin/quotas/delete.go => csc/cmd/admin/quotas/delete.go +25 -0
@@ 0,0 1,25 @@
+ package adminquotas
+ 
+ import (
+ 	"cisco/csc/cmd/admin"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/spf13/cobra"
+ )
+ 
+ var AdminQuotasDeleteRootCmd = &cobra.Command{
+ 	Use:   "delete",
+ 	Short: "Delete a quota",
+ 	Args:  cobra.ExactArgs(1),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 		err := cisco.DeleteQuota(args[0])
+ 
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 		}
+ 	},
+ }
+ 
+ func init() {
+ 	admin.AdminQuotasRootCmd.AddCommand(AdminQuotasDeleteRootCmd)
+ }

A csc/cmd/admin/quotas/list.go => csc/cmd/admin/quotas/list.go +36 -0
@@ 0,0 1,36 @@
+ package adminquotas
+ 
+ import (
+ 	"cisco/csc/cmd/admin"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/olekukonko/tablewriter"
+ 	"github.com/spf13/cobra"
+ 	"os"
+ 	"strconv"
+ )
+ 
+ var AdminQuotasListRootCmd = &cobra.Command{
+ 	Use:   "list",
+ 	Short: "List quotas",
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 		quotas, err := cisco.ListQuota()
+ 
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 
+ 		table := tablewriter.NewWriter(os.Stdout)
+ 		table.SetHeader([]string{"Role", "Instances", "IPv4", "Storage", "Invites"})
+ 
+ 		for _, quota := range quotas {
+ 			table.Append([]string{quota.Role, strconv.Itoa(quota.Instances), strconv.Itoa(quota.Ipv4), strconv.Itoa(quota.Storage), strconv.Itoa(quota.Invites)})
+ 		}
+ 		table.Render()
+ 	},
+ }
+ 
+ func init() {
+ 	admin.AdminQuotasRootCmd.AddCommand(AdminQuotasListRootCmd)
+ }

A csc/cmd/admin/quotas/update.go => csc/cmd/admin/quotas/update.go +15 -0
@@ 0,0 1,15 @@
+ package adminquotas
+ 
+ import (
+ 	"cisco/csc/cmd/admin"
+ 	"github.com/spf13/cobra"
+ )
+ 
+ var AdminQuotasUpdateRootCmd = &cobra.Command{
+ 	Use:   "update",
+ 	Short: "Update quota values",
+ }
+ 
+ func init() {
+ 	admin.AdminQuotasRootCmd.AddCommand(AdminQuotasUpdateRootCmd)
+ }

A csc/cmd/admin/quotas/update/instances.go => csc/cmd/admin/quotas/update/instances.go +39 -0
@@ 0,0 1,39 @@
+ package adminquotasupdate
+ 
+ import (
+ 	"cisco/csc/cmd/admin/quotas"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/spf13/cobra"
+ 	"strconv"
+ )
+ 
+ var AdminQuotasUpdateInstancesRootCmd = &cobra.Command{
+ 	Use:   "instances",
+ 	Short: "Update instances quota",
+ 	Args:  cobra.ExactArgs(2),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 		var instances int
+ 		var err error
+ 
+ 		if args[1] == "infinite" {
+ 			instances = -1
+ 		} else {
+ 			instances, err = strconv.Atoi(args[1])
+ 			if err != nil {
+ 				fmt.Printf("Error: %s\n", err.Error())
+ 				return
+ 			}
+ 		}
+ 
+ 		err = cisco.UpdateInstanceQuota(args[0], instances)
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 	},
+ }
+ 
+ func init() {
+ 	adminquotas.AdminQuotasUpdateRootCmd.AddCommand(AdminQuotasUpdateInstancesRootCmd)
+ }

A csc/cmd/admin/quotas/update/invites.go => csc/cmd/admin/quotas/update/invites.go +39 -0
@@ 0,0 1,39 @@
+ package adminquotasupdate
+ 
+ import (
+ 	"cisco/csc/cmd/admin/quotas"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/spf13/cobra"
+ 	"strconv"
+ )
+ 
+ var AdminQuotasUpdateInvitesRootCmd = &cobra.Command{
+ 	Use:   "invites",
+ 	Short: "Update invites quota",
+ 	Args:  cobra.ExactArgs(2),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 		var invites int
+ 		var err error
+ 
+ 		if args[1] == "infinite" {
+ 			invites = -1
+ 		} else {
+ 			invites, err = strconv.Atoi(args[1])
+ 			if err != nil {
+ 				fmt.Printf("Error: %s\n", err.Error())
+ 				return
+ 			}
+ 		}
+ 
+ 		err = cisco.UpdateInvitesQuota(args[0], invites)
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 	},
+ }
+ 
+ func init() {
+ 	adminquotas.AdminQuotasUpdateRootCmd.AddCommand(AdminQuotasUpdateInvitesRootCmd)
+ }

A csc/cmd/admin/quotas/update/ipv4.go => csc/cmd/admin/quotas/update/ipv4.go +39 -0
@@ 0,0 1,39 @@
+ package adminquotasupdate
+ 
+ import (
+ 	"cisco/csc/cmd/admin/quotas"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/spf13/cobra"
+ 	"strconv"
+ )
+ 
+ var AdminQuotasUpdateIpv4RootCmd = &cobra.Command{
+ 	Use:   "ipv4",
+ 	Short: "Update ipv4 quota",
+ 	Args:  cobra.ExactArgs(2),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 		var ipv4 int
+ 		var err error
+ 
+ 		if args[1] == "infinite" {
+ 			ipv4 = -1
+ 		} else {
+ 			ipv4, err = strconv.Atoi(args[1])
+ 			if err != nil {
+ 				fmt.Printf("Error: %s\n", err.Error())
+ 				return
+ 			}
+ 		}
+ 
+ 		err = cisco.UpdateIpv4Quota(args[0], ipv4)
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 	},
+ }
+ 
+ func init() {
+ 	adminquotas.AdminQuotasUpdateRootCmd.AddCommand(AdminQuotasUpdateIpv4RootCmd)
+ }

A csc/cmd/admin/quotas/update/storage.go => csc/cmd/admin/quotas/update/storage.go +39 -0
@@ 0,0 1,39 @@
+ package adminquotasupdate
+ 
+ import (
+ 	"cisco/csc/cmd/admin/quotas"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/spf13/cobra"
+ 	"strconv"
+ )
+ 
+ var AdminQuotasUpdateStorageRootCmd = &cobra.Command{
+ 	Use:   "storage",
+ 	Short: "Update storage quota",
+ 	Args:  cobra.ExactArgs(2),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 		var storage int
+ 		var err error
+ 
+ 		if args[1] == "infinite" {
+ 			storage = -1
+ 		} else {
+ 			storage, err = strconv.Atoi(args[1])
+ 			if err != nil {
+ 				fmt.Printf("Error: %s\n", err.Error())
+ 				return
+ 			}
+ 		}
+ 
+ 		err = cisco.UpdateStorageQuota(args[0], storage)
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 	},
+ }
+ 
+ func init() {
+ 	adminquotas.AdminQuotasUpdateRootCmd.AddCommand(AdminQuotasUpdateStorageRootCmd)
+ }

A csc/cmd/admin/user.go => csc/cmd/admin/user.go +15 -0
@@ 0,0 1,15 @@
+ package admin
+ 
+ import (
+ 	"cisco/csc/cmd"
+ 	"github.com/spf13/cobra"
+ )
+ 
+ var AdminUserRootCmd = &cobra.Command{
+ 	Use:   "user",
+ 	Short: "Administrator utilities for users",
+ }
+ 
+ func init() {
+ 	cmd.AdminRootCmd.AddCommand(AdminUserRootCmd)
+ }

A csc/cmd/admin/user/get.go => csc/cmd/admin/user/get.go +28 -0
@@ 0,0 1,28 @@
+ package adminuser
+ 
+ import (
+ 	"cisco/csc/cmd/admin"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/spf13/cobra"
+ )
+ 
+ var AdminUserGetRootCmd = &cobra.Command{
+ 	Use:   "get",
+ 	Short: "Get an user",
+ 	Args:  cobra.ExactArgs(1),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 		userinfo, err := cisco.GetUserInfoAdmin(args[0])
+ 
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 
+ 		fmt.Printf("%v", userinfo)
+ 	},
+ }
+ 
+ func init() {
+ 	admin.AdminUserRootCmd.AddCommand(AdminUserGetRootCmd)
+ }

A csc/cmd/admin/user/list.go => csc/cmd/admin/user/list.go +35 -0
@@ 0,0 1,35 @@
+ package adminuser
+ 
+ import (
+ 	"cisco/csc/cmd/admin"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/olekukonko/tablewriter"
+ 	"github.com/spf13/cobra"
+ 	"os"
+ )
+ 
+ var AdminUserListRootCmd = &cobra.Command{
+ 	Use:   "list",
+ 	Short: "List users",
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 		users, err := cisco.ListUser()
+ 
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 
+ 		table := tablewriter.NewWriter(os.Stdout)
+ 		table.SetHeader([]string{"Username", "Email", "Role"})
+ 		for _, user := range users {
+ 			table.Append([]string{user.Username, user.Email, user.Role})
+ 		}
+ 
+ 		table.Render()
+ 	},
+ }
+ 
+ func init() {
+ 	admin.AdminUserRootCmd.AddCommand(AdminUserListRootCmd)
+ }

A csc/cmd/invite.go => csc/cmd/invite.go +14 -0
@@ 0,0 1,14 @@
+ package cmd
+ 
+ import (
+ 	"github.com/spf13/cobra"
+ )
+ 
+ var InviteRootCmd = &cobra.Command{
+ 	Use:   "invite",
+ 	Short: "Utilities for invite",
+ }
+ 
+ func init() {
+ 	RootCmd.AddCommand(InviteRootCmd)
+ }

A csc/cmd/invite/claim.go => csc/cmd/invite/claim.go +85 -0
@@ 0,0 1,85 @@
+ package invite
+ 
+ import (
+ 	"bufio"
+ 	"cisco/csc/cmd"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/spf13/cobra"
+ 	"github.com/spf13/viper"
+ 	"golang.org/x/crypto/ssh/terminal"
+ 	"os"
+ 	"strings"
+ 	"syscall"
+ )
+ 
+ var inviteClaim = &cobra.Command{
+ 	Use:   "claim",
+ 	Short: "Claim an invite",
+ 	Args:  cobra.ExactArgs(1),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 		reader := bufio.NewReader(os.Stdin)
+ 		var err error
+ 		username := ""
+ 		password := ""
+ 		password2 := " "
+ 
+ 		invite, err := cisco.GetInvite(args[0])
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		} else if invite.Claimed == true {
+ 			fmt.Printf("Error: This invite has already been claimed\n")
+ 			return
+ 		}
+ 
+ 		for username == "" {
+ 			fmt.Print("Choose an username: ")
+ 			username, err = reader.ReadString('\n')
+ 			username = strings.TrimSpace(username)
+ 		}
+ 
+ 		for password != password2 {
+ 			fmt.Print("Enter a password: ")
+ 			bytePassword, _ := terminal.ReadPassword(int(syscall.Stdin))
+ 			password = string(bytePassword)
+ 			fmt.Printf("\n")
+ 
+ 			fmt.Print("Please confirm password: ")
+ 			bytePassword, _ = terminal.ReadPassword(int(syscall.Stdin))
+ 			password2 = string(bytePassword)
+ 			fmt.Printf("\n")
+ 
+ 			if password != password2 {
+ 				fmt.Printf("Passwords did not match!\n")
+ 			} else if password == "" {
+ 				fmt.Printf("You cannot use an empty password\n")
+ 				password = " "
+ 			}
+ 		}
+ 
+ 		err = cisco.ClaimInvite(args[0], username, password)
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 
+ 		fmt.Printf("Account created, getting your credentials for the configuration...\n")
+ 		token, err := cisco.NewToken(username, password, "Default keys (Created by the command line tool)")
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 
+ 		viper.Set("key", token.Key)
+ 		viper.Set("secret", token.Secret)
+ 		viper.Set("debug", false)
+ 		viper.WriteConfig()
+ 
+ 		fmt.Printf("All done! You can now query the service. You should take a look at 'csc help' for more information\n")
+ 	},
+ }
+ 
+ func init() {
+ 	cmd.InviteRootCmd.AddCommand(inviteClaim)
+ }

A csc/cmd/invite/new.go => csc/cmd/invite/new.go +27 -0
@@ 0,0 1,27 @@
+ package invite
+ 
+ import (
+ 	"cisco/csc/cmd"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/spf13/cobra"
+ )
+ 
+ var inviteNew = &cobra.Command{
+ 	Use:   "new",
+ 	Short: "Invite a new user",
+ 	Args:  cobra.ExactArgs(1),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 		err := cisco.NewInvite(args[0])
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 
+ 		fmt.Printf("Done! User should have received an invite mail\n")
+ 	},
+ }
+ 
+ func init() {
+ 	cmd.InviteRootCmd.AddCommand(inviteNew)
+ }

A csc/cmd/root.go => csc/cmd/root.go +68 -0
@@ 0,0 1,68 @@
+ package cmd
+ 
+ import (
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/spf13/cobra"
+ 	"github.com/spf13/viper"
+ 	"os"
+ )
+ 
+ var Endpoint string
+ var Config string
+ var Key string
+ var Secret string
+ var Debug bool
+ 
+ var RootCmd = &cobra.Command{
+ 	Use:   "csc",
+ 	Short: "The command line helper for the cisco cloud platform",
+ }
+ 
+ func Execute() {
+ 	if err := RootCmd.Execute(); err != nil {
+ 		fmt.Println(err.Error())
+ 		os.Exit(1)
+ 	}
+ }
+ 
+ func init() {
+ 	cobra.OnInitialize(initCisco)
+ 	RootCmd.PersistentFlags().StringVar(&Endpoint, "endpoint", "", "API endpoint to connect to")
+ 	RootCmd.PersistentFlags().StringVar(&Key, "key", "", "Key ID")
+ 	RootCmd.PersistentFlags().StringVar(&Secret, "secret", "", "Secret")
+ 	RootCmd.PersistentFlags().StringVar(&Config, "config", "", "Config file path")
+ 	RootCmd.PersistentFlags().BoolVar(&Debug, "debug", false, "Enable debug mode")
+ 	viper.BindPFlag("endpoint", RootCmd.PersistentFlags().Lookup("endpoint"))
+ 	viper.BindPFlag("key", RootCmd.PersistentFlags().Lookup("key"))
+ 	viper.BindPFlag("secret", RootCmd.PersistentFlags().Lookup("secret"))
+ 	viper.BindPFlag("debug", RootCmd.PersistentFlags().Lookup("debug"))
+ }
+ 
+ func initCisco() {
+ 	if Config != "" {
+ 		viper.SetConfigFile(Config)
+ 	} else {
+ 		viper.SetConfigName("config")
+ 		viper.AddConfigPath("$HOME/.config/csc/")
+ 		viper.AddConfigPath("$HOME/.csc/")
+ 		viper.AddConfigPath("/etc/csc/")
+ 	}
+ 
+ 	if err := viper.ReadInConfig(); err != nil {
+ 		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
+ 			os.MkdirAll(os.Getenv("HOME")+"/.config/csc/", os.ModePerm)
+ 			viper.SetConfigFile(os.Getenv("HOME") + "/.config/csc/config.yml")
+ 			viper.WriteConfig()
+ 		} else {
+ 			fmt.Printf("Can't read configuration: %s\n", err.Error())
+ 		}
+ 	}
+ 
+ 	cisco.SetConfig(&cisco.Config{
+ 		Endpoint: viper.GetString("endpoint"),
+ 		Debug:    viper.GetBool("debug"),
+ 		Key:      viper.GetString("key"),
+ 		Secret:   viper.GetString("secret"),
+ 	})
+ }

A csc/cmd/token.go => csc/cmd/token.go +14 -0
@@ 0,0 1,14 @@
+ package cmd
+ 
+ import (
+ 	"github.com/spf13/cobra"
+ )
+ 
+ var TokenRootCmd = &cobra.Command{
+ 	Use:   "token",
+ 	Short: "Utilities for token",
+ }
+ 
+ func init() {
+ 	RootCmd.AddCommand(TokenRootCmd)
+ }

A csc/cmd/token/list.go => csc/cmd/token/list.go +35 -0
@@ 0,0 1,35 @@
+ package token
+ 
+ import (
+ 	"cisco/csc/cmd"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/olekukonko/tablewriter"
+ 	"github.com/spf13/cobra"
+ 	"os"
+ 	"time"
+ )
+ 
+ var tokenList = &cobra.Command{
+ 	Use:   "list",
+ 	Short: "List existing tokens",
+ 	Args:  cobra.ExactArgs(0),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 		tokens, err := cisco.ListToken()
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 
+ 		table := tablewriter.NewWriter(os.Stdout)
+ 		table.SetHeader([]string{"Key", "Description", "Created At"})
+ 		for _, token := range tokens {
+ 			table.Append([]string{token.Key, token.Description, token.Created.Format(time.UnixDate)})
+ 		}
+ 		table.Render()
+ 	},
+ }
+ 
+ func init() {
+ 	cmd.TokenRootCmd.AddCommand(tokenList)
+ }

A csc/cmd/token/new.go => csc/cmd/token/new.go +58 -0
@@ 0,0 1,58 @@
+ package token
+ 
+ import (
+ 	"bufio"
+ 	"cisco/csc/cmd"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/spf13/cobra"
+ 	"golang.org/x/crypto/ssh/terminal"
+ 	"os"
+ 	"strings"
+ 	"syscall"
+ )
+ 
+ var tokenNew = &cobra.Command{
+ 	Use:   "new",
+ 	Short: "Create a new token pair",
+ 	Args:  cobra.ExactArgs(0),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 		var err error
+ 		reader := bufio.NewReader(os.Stdin)
+ 		username := ""
+ 		password := ""
+ 		description := ""
+ 
+ 		for username == "" {
+ 			fmt.Print("Username: ")
+ 			username, err = reader.ReadString('\n')
+ 			username = strings.TrimSpace(username)
+ 		}
+ 
+ 		for password == "" {
+ 			fmt.Print("Password: ")
+ 			bytePassword, _ := terminal.ReadPassword(int(syscall.Stdin))
+ 			password = string(bytePassword)
+ 			fmt.Printf("\n")
+ 		}
+ 
+ 		fmt.Print("Description (can be empty): ")
+ 		description, err = reader.ReadString('\n')
+ 		description = strings.TrimSpace(description)
+ 
+ 		token, err := cisco.NewToken(username, password, description)
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 
+ 		fmt.Printf("===== TOKEN =====\n")
+ 		fmt.Printf("key: %s\n", token.Key)
+ 		fmt.Printf("secret: %s\n", token.Secret)
+ 		fmt.Printf("This is the only time you will see this secret. Do not loose it!\n")
+ 	},
+ }
+ 
+ func init() {
+ 	cmd.TokenRootCmd.AddCommand(tokenNew)
+ }

A csc/cmd/token/revoke.go => csc/cmd/token/revoke.go +24 -0
@@ 0,0 1,24 @@
+ package token
+ 
+ import (
+ 	"cisco/csc/cmd"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/spf13/cobra"
+ )
+ 
+ var tokenRevoke = &cobra.Command{
+ 	Use:   "revoke",
+ 	Short: "Revoke an existing token",
+ 	Args:  cobra.ExactArgs(1),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 		err := cisco.RevokeToken(args[0])
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 		}
+ 	},
+ }
+ 
+ func init() {
+ 	cmd.TokenRootCmd.AddCommand(tokenRevoke)
+ }

A csc/main.go => csc/main.go +15 -0
@@ 0,0 1,15 @@
+ package main
+ 
+ import (
+ 	"cisco/csc/cmd"
+ 	_ "cisco/csc/cmd/admin"
+ 	_ "cisco/csc/cmd/admin/quotas"
+ 	_ "cisco/csc/cmd/admin/quotas/update"
+ 	_ "cisco/csc/cmd/admin/user"
+ 	_ "cisco/csc/cmd/invite"
+ 	_ "cisco/csc/cmd/token"
+ )
+ 
+ func main() {
+ 	cmd.Execute()
+ }