yunion.io/x/cloudmux@v0.3.10-0-alpha.1/cmd/openstackcli/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/openstack" 29 _ "yunion.io/x/cloudmux/pkg/multicloud/openstack/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:"$OPENSTACK_AUTH_URL" metavar:"OPENSTACK_AUTH_URL"` 36 Username string `help:"Username" default:"$OPENSTACK_USERNAME" metavar:"OPENSTACK_USERNAME"` 37 Password string `help:"Password" default:"$OPENSTACK_PASSWORD" metavar:"OPENSTACK_PASSWORD"` 38 Project string `help:"Project" default:"$OPENSTACK_PROJECT" metavar:"OPENSTACK_PROJECT"` 39 EndpointType string `help:"Project" default:"$OPENSTACK_ENDPOINT_TYPE|internal" metavar:"OPENSTACK_ENDPOINT_TYPE"` 40 DomainName string `help:"Domain of user" default:"$OPENSTACK_DOMAIN_NAME|Default" metavar:"OPENSTACK_DOMAIN_NAME"` 41 ProjectDomain string `help:"Domain of project" default:"$OPENSTACK_PROJECT_DOMAIN|Default" metavar:"OPENSTACK_PROJECT_DOMAIN"` 42 RegionID string `help:"RegionId" default:"$OPENSTACK_REGION_ID" metavar:"OPENSTACK_REGION_ID"` 43 SUBCOMMAND string `help:"openstackcli subcommand" subcommand:"true"` 44 } 45 46 func getSubcommandParser() (*structarg.ArgumentParser, error) { 47 parse, e := structarg.NewArgumentParserWithHelp(&BaseOptions{}, 48 "openstackcli", 49 "Command-line interface to openstack API.", 50 `See "openstackcli COMMAND --help" for help on a specific command.`) 51 52 if e != nil { 53 return nil, e 54 } 55 56 subcmd := parse.GetSubcommand() 57 if subcmd == nil { 58 return nil, fmt.Errorf("No subcommand argument.") 59 } 60 for _, v := range shellutils.CommandTable { 61 _, e := subcmd.AddSubParserWithHelp(v.Options, v.Command, v.Desc, v.Callback) 62 if e != nil { 63 return nil, e 64 } 65 } 66 return parse, nil 67 } 68 69 func showErrorAndExit(e error) { 70 fmt.Fprintf(os.Stderr, "%s", e) 71 fmt.Fprintln(os.Stderr) 72 os.Exit(1) 73 } 74 75 func newClient(options *BaseOptions) (*openstack.SRegion, error) { 76 if len(options.AuthURL) == 0 { 77 return nil, fmt.Errorf("Missing AuthURL") 78 } 79 80 if len(options.Username) == 0 { 81 return nil, fmt.Errorf("Missing Username") 82 } 83 84 if len(options.Password) == 0 { 85 return nil, fmt.Errorf("Missing Password") 86 } 87 88 cfg := &httpproxy.Config{ 89 HTTPProxy: os.Getenv("HTTP_PROXY"), 90 HTTPSProxy: os.Getenv("HTTPS_PROXY"), 91 NoProxy: os.Getenv("NO_PROXY"), 92 } 93 cfgProxyFunc := cfg.ProxyFunc() 94 proxyFunc := func(req *http.Request) (*url.URL, error) { 95 return cfgProxyFunc(req.URL) 96 } 97 98 cli, err := openstack.NewOpenStackClient( 99 openstack.NewOpenstackClientConfig( 100 options.AuthURL, 101 options.Username, 102 options.Password, 103 options.Project, 104 options.ProjectDomain, 105 ). 106 EndpointType(options.EndpointType). 107 DomainName(options.DomainName). 108 Debug(options.Debug). 109 CloudproviderConfig( 110 cloudprovider.ProviderConfig{ 111 ProxyFunc: proxyFunc, 112 }, 113 ), 114 ) 115 if err != nil { 116 return nil, err 117 } 118 region := cli.GetRegion(options.RegionID) 119 if region == nil { 120 return nil, fmt.Errorf("No such region %s", options.RegionID) 121 } 122 return region, nil 123 } 124 125 func main() { 126 parser, e := getSubcommandParser() 127 if e != nil { 128 showErrorAndExit(e) 129 } 130 e = parser.ParseArgs(os.Args[1:], false) 131 options := parser.Options().(*BaseOptions) 132 133 if parser.IsHelpSet() { 134 fmt.Print(parser.HelpString()) 135 return 136 } 137 subcmd := parser.GetSubcommand() 138 subparser := subcmd.GetSubParser() 139 if e != nil || subparser == nil { 140 if subparser != nil { 141 fmt.Print(subparser.Usage()) 142 } else { 143 fmt.Print(parser.Usage()) 144 } 145 showErrorAndExit(e) 146 } 147 suboptions := subparser.Options() 148 if subparser.IsHelpSet() { 149 fmt.Print(subparser.HelpString()) 150 return 151 } 152 var region *openstack.SRegion 153 if len(options.RegionID) == 0 { 154 options.RegionID = openstack.OPENSTACK_DEFAULT_REGION 155 } 156 region, e = newClient(options) 157 if e != nil { 158 showErrorAndExit(e) 159 } 160 e = subcmd.Invoke(region, suboptions) 161 if e != nil { 162 showErrorAndExit(e) 163 } 164 }