yunion.io/x/cloudmux@v0.3.10-0-alpha.1/cmd/zstackcli/main.go (about) 1 // Copyright 2019 Yunion 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package main 16 17 import ( 18 "fmt" 19 "net/http" 20 "net/url" 21 "os" 22 23 "golang.org/x/net/http/httpproxy" 24 25 "yunion.io/x/structarg" 26 27 "yunion.io/x/cloudmux/pkg/cloudprovider" 28 "yunion.io/x/cloudmux/pkg/multicloud/zstack" 29 _ "yunion.io/x/cloudmux/pkg/multicloud/zstack/shell" 30 "yunion.io/x/onecloud/pkg/util/shellutils" 31 ) 32 33 type BaseOptions struct { 34 Debug bool `help:"debug mode"` 35 AuthURL string `help:"Auth URL" default:"$ZSTACK_AUTH_URL" metavar:"ZSTACK_AUTH_URL"` 36 Username string `help:"Username" default:"$ZSTACK_USERNAME" metavar:"ZSTACK_USERNAME"` 37 Password string `help:"Password" default:"$ZSTACK_PASSWORD" metavar:"ZSTACK_PASSWORD"` 38 RegionID string `help:"RegionId" default:"$ZSTACK_REGION_ID" metavar:"ZSTACK_REGION_ID"` 39 SUBCOMMAND string `help:"zstackcli subcommand" subcommand:"true"` 40 } 41 42 func getSubcommandParser() (*structarg.ArgumentParser, error) { 43 parse, e := structarg.NewArgumentParserWithHelp(&BaseOptions{}, 44 "zstackcli", 45 "Command-line interface to zstack API.", 46 `See "zstackcli COMMAND --help" for help on a specific command.`) 47 48 if e != nil { 49 return nil, e 50 } 51 52 subcmd := parse.GetSubcommand() 53 if subcmd == nil { 54 return nil, fmt.Errorf("No subcommand argument.") 55 } 56 for _, v := range shellutils.CommandTable { 57 _, e := subcmd.AddSubParserWithHelp(v.Options, v.Command, v.Desc, v.Callback) 58 if e != nil { 59 return nil, e 60 } 61 } 62 return parse, nil 63 } 64 65 func showErrorAndExit(e error) { 66 fmt.Fprintf(os.Stderr, "%s", e) 67 fmt.Fprintln(os.Stderr) 68 os.Exit(1) 69 } 70 71 func newClient(options *BaseOptions) (*zstack.SRegion, error) { 72 if len(options.AuthURL) == 0 { 73 return nil, fmt.Errorf("Missing AuthURL") 74 } 75 76 if len(options.Username) == 0 { 77 return nil, fmt.Errorf("Missing Username") 78 } 79 80 if len(options.Password) == 0 { 81 return nil, fmt.Errorf("Missing Password") 82 } 83 84 cfg := &httpproxy.Config{ 85 HTTPProxy: os.Getenv("HTTP_PROXY"), 86 HTTPSProxy: os.Getenv("HTTPS_PROXY"), 87 NoProxy: os.Getenv("NO_PROXY"), 88 } 89 cfgProxyFunc := cfg.ProxyFunc() 90 proxyFunc := func(req *http.Request) (*url.URL, error) { 91 return cfgProxyFunc(req.URL) 92 } 93 94 cli, err := zstack.NewZStackClient( 95 zstack.NewZstackClientConfig( 96 options.AuthURL, 97 options.Username, 98 options.Password, 99 ).Debug(options.Debug). 100 CloudproviderConfig( 101 cloudprovider.ProviderConfig{ 102 ProxyFunc: proxyFunc, 103 }, 104 ), 105 ) 106 if err != nil { 107 return nil, err 108 } 109 region := cli.GetRegion(options.RegionID) 110 if region == nil { 111 return nil, fmt.Errorf("No such region %s", options.RegionID) 112 } 113 return region, nil 114 } 115 116 func main() { 117 parser, e := getSubcommandParser() 118 if e != nil { 119 showErrorAndExit(e) 120 } 121 e = parser.ParseArgs(os.Args[1:], false) 122 options := parser.Options().(*BaseOptions) 123 124 if parser.IsHelpSet() { 125 fmt.Print(parser.HelpString()) 126 return 127 } 128 subcmd := parser.GetSubcommand() 129 subparser := subcmd.GetSubParser() 130 if e != nil || subparser == nil { 131 if subparser != nil { 132 fmt.Print(subparser.Usage()) 133 } else { 134 fmt.Print(parser.Usage()) 135 } 136 showErrorAndExit(e) 137 } 138 suboptions := subparser.Options() 139 if subparser.IsHelpSet() { 140 fmt.Print(subparser.HelpString()) 141 return 142 } 143 var region *zstack.SRegion 144 if len(options.RegionID) == 0 { 145 options.RegionID = zstack.ZSTACK_DEFAULT_REGION 146 } 147 region, e = newClient(options) 148 if e != nil { 149 showErrorAndExit(e) 150 } 151 e = subcmd.Invoke(region, suboptions) 152 if e != nil { 153 showErrorAndExit(e) 154 } 155 }