Skip to content

Commit

Permalink
simplify config and completion
Browse files Browse the repository at this point in the history
  • Loading branch information
lixiaojun629 committed Sep 6, 2018
1 parent 497f916 commit 97fc36b
Show file tree
Hide file tree
Showing 16 changed files with 224 additions and 97 deletions.
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export VERSION=0.1.1
export VERSION=0.1.2

.PHONY : build
build:
Expand All @@ -8,16 +8,19 @@ build:
build_mac:
GOOS=darwin GOARCH=amd64 go build -o out/ucloud main.go
tar zcvf out/ucloud-cli-macosx-${VERSION}-amd64.tgz -C out ucloud
shasum -a 256 out/ucloud-cli-macosx-${VERSION}-amd64.tgz

.PHONY : build_linux
build_linux:
GOOS=linux GOARCH=amd64 go build -o out/ucloud main.go
tar zcvf out/ucloud-cli-linux-${VERSION}-amd64.tgz -C out ucloud
shasum -a 256 out/ucloud-cli-linux-${VERSION}-amd64.tgz

.PHONY : build_windows
build_windows:
GOOS=windows GOARCH=amd64 go build -o out/ucloud.exe main.go
zip -r out/ucloud-cli-windows-${VERSION}-amd64.zip out/ucloud.exe
shasum -a 256 out/ucloud-cli-windows-${VERSION}-amd64.tgz

.PHONY : install
install:
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Archive links:
[Linux](http://ucloud-sdk.ufile.ucloud.com.cn/ucloud-cli-linux-0.1.1-amd64.tgz)
[Windows](http://ucloud-sdk.ufile.ucloud.com.cn/ucloud-cli-windows-0.1.1-amd64.zip)

SHA-256 hashcode
SHA-256 checksum
```
165f1ce4d413bf92e2794efe2722678eb80990602b81fd6e501d0c5f6bbf30bb ucloud-cli-linux-0.1.1-amd64.tgz
e174c2ef268f4b653062d0e1331bf642134a0fafbb745b407969a194d7c1bc0c ucloud-cli-macosx-0.1.1-amd64.tgz
Expand All @@ -33,14 +33,16 @@ If you have installed golang, run the following commands to install the UCloud C
```
$ mkdir -p $GOPATH/src/github.com/ucloud
$ cd $GOPATH/src/github.com/ucloud
$ git clone http://github.com/ucloud/ucloud-cli.git
$ git clone https://github.com/ucloud/ucloud-cli.git
$ cd ucloud-cli
$ make install
```

### Config UCloud CLI

After install the cli, run 'ucloud config' to complete the cli configuration following the tips. Local settings will be saved in directory $HOME/.ucloud
Command 'ucloud ls --object [region|project]' display all the regions and projects. You can change the default region and prject by runing 'ucloud config set [region|project] xxx'.
Execute 'ucloud config --help' for more information.

### Uninstall UCloud CLI

Expand Down
99 changes: 69 additions & 30 deletions cmd/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import (
"fmt"
"io"
"os"
"os/exec"
"regexp"
"runtime"
"strings"

"github.com/spf13/cobra"
Expand All @@ -31,20 +34,17 @@ func NewCmdCompletion() *cobra.Command {
On macOS, using bash
On macOS, you will need to install bash-completion support via Homebrew first:
If running Bash 3.2 included with macOS
> brew install bash-completion
or, if running Bash 4.1+
> brew install bash-completion@2
$ ucloud completion
$ brew install bash-completion
Follow the “caveats” section of brew’s output to add the appropriate bash completion path to your local .bash_profile.
and then generate bash completion scripts for ucloud
> ucloud completion
On Linux, using bash
On CentOS Linux, you may need to install the bash-completion package which is not installed by default.
> yum install bash-completion -y
On Linux, you may need to install the bash-completion package which is not installed by default.
$ ucloud completion
$ yum install bash-completion or apt-get install bash-completion
and then genreate bash completion scripts for ucloud
> ucloud completion
Using zsh
> ucloud completion
Expand Down Expand Up @@ -73,21 +73,65 @@ func NewCmdCompletion() *cobra.Command {
return completionCmd
}

var darwinBash = `
Install bash-completion with command 'brew install bash-completion', and then append the following scripts to ~/.bash_profile
if [ -f $(brew --prefix)/etc/bash_completion ]; then
. $(brew --prefix)/etc/bash_completion
fi
source ~/.ucloud/ucloud.sh
`

var linuxBash = `
Ensure your have installed bash-completion, and then append the following scripts to ~/.bashrc
if [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
source ~/.ucloud/ucloud.sh
`

func getBashVersion() (version string, err error) {
lookupBashVersion := exec.Command("bash", "-version")
out, err := lookupBashVersion.Output()
if err != nil {
context.AppendError(err)
fmt.Println(err)
}

// Example
// $ bash -version
// GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin17)
// Copyright (C) 2007 Free Software Foundation, Inc.
versionStr := string(out)
re := regexp.MustCompile("(\\d)\\.\\d\\.")
strs := re.FindAllStringSubmatch(versionStr, -1)
if len(strs) >= 1 {
result := strs[0]
if len(result) >= 2 {
version = result[1]
}
}
if version == "" {
err = fmt.Errorf("lookup bash version failed")
}
return
}

func bashCompletion(cmd *cobra.Command) {
home := util.GetHomePath()
shellPath := home + "/" + util.ConfigPath + "/ucloud.sh"
cmd.GenBashCompletionFile(shellPath)
for _, rc := range [...]string{".bashrc", ".bash_profile", ".bash_login", ".profile"} {
rcPath := home + "/" + rc
if _, err := os.Stat(rcPath); err == nil {
cmd := "source " + shellPath
if util.LineInFile(rcPath, cmd) == false {
util.AppendToFile(rcPath, cmd)
fmt.Println("Auto completion is on. Please install bash-completion on your platform using brew,yum or apt-get. ucloud completion --help for more information")
} else {
fmt.Println("Auto completion update. Restart session")
}
}
fmt.Printf("Completion scripts has been written to '~/%s/ucloud.sh'\n", util.ConfigPath)

platform := runtime.GOOS

if platform == "darwin" {
fmt.Println(darwinBash)
} else if platform == "linux" {
fmt.Println(linuxBash)
}
}

Expand All @@ -97,22 +141,17 @@ func zshCompletion(cmd *cobra.Command) {
file, err := os.Create(shellPath)
if err != nil {
fmt.Println(err)
context.AppendError(err)
return
}
defer file.Close()

runCompletionZsh(file, cmd)
fmt.Printf("Completion scripts was written to '~/%s/_ucloud'\n", util.ConfigPath)

rcPath := home + "/.zshrc"
if _, err = os.Stat(rcPath); err == nil {
cmd := fmt.Sprintf("fpath=(%s/%s $fpath);", home, util.ConfigPath)
cmd += "autoload -U +X compinit && compinit"
if util.LineInFile(rcPath, cmd) == false {
util.AppendToFile(rcPath, cmd)
fmt.Println("Auto completion is on")
} else {
fmt.Println("Auto completion update. Restart session")
}
}
scripts := fmt.Sprintf("fpath=(~/%s $fpath)\n", util.ConfigPath)
scripts += "autoload -U +X compinit && compinit"
fmt.Printf("Please append the following scripts to your ~/.zshrc\n%s\n", scripts)
}

//参考自 k8s.io/kubernetes/pkg/kubectl/cmd/completion.go
Expand Down
45 changes: 22 additions & 23 deletions cmd/configure.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,7 @@ var config = model.ConfigInstance

//NewCmdConfig ucloud config
func NewCmdConfig() *cobra.Command {

var configDesc = `Command 'ucloud config' is used to configure public-key,private-key and other settings.
Public-key and private-key could be acquired from https://console.ucloud.cn/uapi/apikey.
If you don’t have an UCloud account yet, run 'ucloud sign-up', and authenticate the account with your valid documentation.
If you just want to configure default region or project, please run 'ucloud config set region/project xxx'. Run 'ucloud config --help' for more infomation.
`
var configDesc = `Public-key and private-key could be acquired from https://console.ucloud.cn/uapi/apikey.`
var helloUcloud = `
_ _ _ _ _ _ _____ _ _
| | | | | | | | | | / __ \ | | |
Expand All @@ -49,10 +40,10 @@ If you just want to configure default region or project, please run 'ucloud conf
var configCmd = &cobra.Command{
Use: "config",
Short: "Config UCloud CLI options",
Long: `Config UCloud CLI options such as credentials and other settings.`,
Example: "ucloud config; ucloud config set region cn-bj2",
Long: `Config UCloud CLI options such as private-key,public-key,default region and default project-id.`,
Example: "ucloud config; ucloud config set region cn-bj2; ucloud config set project org-xxx",
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf(configDesc)
fmt.Println(configDesc)
if len(config.PrivateKey) != 0 && len(config.PublicKey) != 0 {
fmt.Printf("Your have already configured public-key and private-key. Do you want to overwrite it? (y/n):")
var overwrite string
Expand All @@ -69,24 +60,32 @@ If you just want to configure default region or project, please run 'ucloud conf
}
config.ConfigPublicKey()
config.ConfigPrivateKey()
fmt.Println("Fetching regions...")
err := listRegion()

region, err := getDefaultRegion()
if err != nil {
context.AppendError(err)
fmt.Println(err)
return
} else {
config.Region = region
fmt.Printf("Configured default region:%s\n", region)
}
config.ConfigRegion()

fmt.Println("Fetching projects...")
err = listProject()
project, err := getDefaultProject()
if err != nil {
context.AppendError(err)
fmt.Println(err)
return
} else {
config.ProjectID = project
fmt.Printf("Configured default project:%s\n", project)
}

config.ConfigProjectID()
config.SaveConfig()
certified, err := isUserCertified()

userInfo, err := getUserInfo()

fmt.Printf("You are logged in as: [%s]\n", userInfo.UserEmail)

certified := isUserCertified(userInfo)
if err != nil {
fmt.Println(err)
} else if certified == false {
Expand Down Expand Up @@ -144,7 +143,7 @@ func NewCmdConfigSet() *cobra.Command {
Use: "set",
Short: "Set a config value",
Long: "Set a config value, including private-key public-key region and project-id.",
Example: "ucloud configure set region cn-bj2",
Example: "ucloud config set region cn-bj2",
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 2 {
fmt.Printf("Error: accepts 2 arg(s), received %d\n", len(args))
Expand Down
4 changes: 2 additions & 2 deletions cmd/eip.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import (
func NewCmdEIP() *cobra.Command {
var cmd = &cobra.Command{
Use: "eip",
Short: "EIP managment",
Long: `EIP managment, such as list,allocate and release`,
Short: "List,allocate and release EIP",
Long: `Manipulate EIP, such as list,allocate and release`,
Args: cobra.NoArgs,
}
cmd.AddCommand(NewCmdEIPList())
Expand Down
6 changes: 3 additions & 3 deletions cmd/globalssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import (
func NewCmdGssh() *cobra.Command {
var cmd = &cobra.Command{
Use: "gssh",
Short: "GlobalSSH management",
Long: `GlobalSSH management, such as create,modify,list and delete`,
Short: "Create and manage globalssh instance",
Long: `Create and manage globalssh instance, such as create,modify,list and delete`,
}
cmd.AddCommand(NewCmdGsshList())
cmd.AddCommand(NewCmdGsshCreate())
Expand Down Expand Up @@ -86,7 +86,7 @@ func NewCmdGsshCreate() *cobra.Command {
fmt.Println("Error:", err)
return
}
if port <= 1 || port >= 65535 || port == 80 || port == 443 {
if port < 1 || port > 65535 || port == 80 || port == 443 {
fmt.Println("The port number should be between 1 and 65535, and cannot be equal to 80 or 443")
return
}
Expand Down
52 changes: 45 additions & 7 deletions cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,23 @@ func NewCmdList() *cobra.Command {
return cmd
}

func getDefaultRegion() (string, error) {
req := &uaccount.GetRegionRequest{}
resp, err := client.GetRegion(req)
if err != nil {
return "", err
}
if resp.RetCode != 0 {
return "", fmt.Errorf("Something wrong. RetCode:%d, Message:%s", resp.RetCode, resp.Message)
}
for _, region := range resp.Regions {
if region.IsDefault == true {
return region.Region, nil
}
}
return "", fmt.Errorf("No default region")
}

func listRegion() error {
req := &uaccount.GetRegionRequest{}
resp, err := client.GetRegion(req)
Expand All @@ -59,12 +76,37 @@ func listRegion() error {
if resp.RetCode != 0 {
return fmt.Errorf("Something wrong. RetCode:%d, Message:%s", resp.RetCode, resp.Message)
}
var regionMap = map[string]bool{}
var regionList []string
for _, region := range resp.Regions {
fmt.Printf("Region: %s, Zone: %s\n", region.Region, region.Zone)
if _, ok := regionMap[region.Region]; !ok {
regionList = append(regionList, region.Region)
}
regionMap[region.Region] = true
}
for index, region := range regionList {
fmt.Printf("[%2d] %s\n", index, region)
}
return nil
}

func getDefaultProject() (string, error) {
req := client.NewGetProjectListRequest()
resp, err := client.GetProjectList(req)
if err != nil {
return "", err
}
if resp.RetCode != 0 {
return "", fmt.Errorf("Something wrong. RetCode:%d, Message:%s", resp.RetCode, resp.Message)
}
for _, project := range resp.ProjectSet {
if project.IsDefault == true {
return project.ProjectId, nil
}
}
return "", fmt.Errorf("No default project")
}

func listProject() error {
req := &uaccount.GetProjectListRequest{}
resp, err := client.GetProjectList(req)
Expand All @@ -80,12 +122,8 @@ func listProject() error {
return nil
}

func isUserCertified() (bool, error) {
userInfo, err := getUserInfo()
if err != nil {
return false, err
}
return userInfo.AuthState == "CERTIFIED", nil
func isUserCertified(userInfo *types.UserInfo) bool {
return userInfo.AuthState == "CERTIFIED"
}

func getUserInfo() (*types.UserInfo, error) {
Expand Down
Loading

0 comments on commit 97fc36b

Please sign in to comment.