yunion.io/x/cloudmux@v0.3.10-0-alpha.1/cmd/googlecli/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/jsonutils" 26 "yunion.io/x/log" 27 "yunion.io/x/pkg/errors" 28 "yunion.io/x/structarg" 29 30 "yunion.io/x/cloudmux/pkg/cloudprovider" 31 "yunion.io/x/cloudmux/pkg/multicloud/google" 32 _ "yunion.io/x/cloudmux/pkg/multicloud/google/shell" 33 "yunion.io/x/onecloud/pkg/util/fileutils2" 34 "yunion.io/x/onecloud/pkg/util/shellutils" 35 ) 36 37 type BaseOptions struct { 38 Debug bool `help:"debug mode"` 39 AuthFile string `help:"google cloud auth json file path" default:"$GOOGLE_AUTH_FILE" metavar:"GOOGLE_AUTH_FILE"` 40 ClientEmail string `help:"Client email" default:"$GOOGLE_CLIENT_EMAIL" metavar:"GOOGLE_CLIENT_EMAIL"` 41 ProjectID string `help:"Project ID" default:"$GOOGLE_PROJECT_ID" metavar:"GOOGLE_PROJECT_ID"` 42 PrivateKeyID string `help:"Private Key ID" default:"$GOOGLE_PRIVATE_KEY_ID" metavar:"GOOGLE_PRIVATE_KEY_ID"` 43 PrivateKey string `help:"Private Key" default:"$GOOGLE_PRIVATE_KEY" metavar:"GOOGLE_PRIVATE_KEY"` 44 RegionID string `help:"RegionID" default:"$GOOGLE_REGION" metavar:"GOOGLE_REGION"` 45 SUBCOMMAND string `help:"googlecli subcommand" subcommand:"true"` 46 } 47 48 func getSubcommandParser() (*structarg.ArgumentParser, error) { 49 parse, e := structarg.NewArgumentParserWithHelp(&BaseOptions{}, 50 "googlecli", 51 "Command-line interface to google API.", 52 `See "googlecli COMMAND --help" for help on a specific command.`) 53 54 if e != nil { 55 return nil, e 56 } 57 58 subcmd := parse.GetSubcommand() 59 if subcmd == nil { 60 return nil, fmt.Errorf("No subcommand argument.") 61 } 62 for _, v := range shellutils.CommandTable { 63 _, e := subcmd.AddSubParserWithHelp(v.Options, v.Command, v.Desc, v.Callback) 64 if e != nil { 65 return nil, e 66 } 67 } 68 return parse, nil 69 } 70 71 func showErrorAndExit(e error) { 72 log.Errorf("%s", e) 73 os.Exit(1) 74 } 75 76 func newClient(options *BaseOptions) (*google.SRegion, error) { 77 if len(options.AuthFile) > 0 { 78 jsonStr, err := fileutils2.FileGetContents(options.AuthFile) 79 if err != nil { 80 return nil, errors.Wrap(err, "FileGetContents") 81 } 82 jsonCfg, err := jsonutils.ParseString(jsonStr) 83 if err != nil { 84 return nil, errors.Wrap(err, "jsonutils.ParseString") 85 } 86 options.ClientEmail, _ = jsonCfg.GetString("client_email") 87 options.PrivateKeyID, _ = jsonCfg.GetString("private_key_id") 88 options.PrivateKey, _ = jsonCfg.GetString("private_key") 89 options.ProjectID, _ = jsonCfg.GetString("project_id") 90 } 91 if len(options.ClientEmail) == 0 { 92 return nil, fmt.Errorf("Missing ClientEmail") 93 } 94 95 if len(options.PrivateKeyID) == 0 { 96 return nil, fmt.Errorf("Missing PrivateKeyID") 97 } 98 99 if len(options.PrivateKey) == 0 { 100 return nil, fmt.Errorf("Missing PrivateKey") 101 } 102 103 if len(options.ProjectID) == 0 { 104 return nil, fmt.Errorf("Missing ProjectID") 105 } 106 107 cfg := &httpproxy.Config{ 108 HTTPProxy: os.Getenv("HTTP_PROXY"), 109 HTTPSProxy: os.Getenv("HTTPS_PROXY"), 110 NoProxy: os.Getenv("NO_PROXY"), 111 } 112 cfgProxyFunc := cfg.ProxyFunc() 113 proxyFunc := func(req *http.Request) (*url.URL, error) { 114 return cfgProxyFunc(req.URL) 115 } 116 117 cli, err := google.NewGoogleClient( 118 google.NewGoogleClientConfig( 119 options.ProjectID, 120 options.ClientEmail, 121 options.PrivateKeyID, 122 options.PrivateKey, 123 ).Debug(options.Debug). 124 CloudproviderConfig( 125 cloudprovider.ProviderConfig{ 126 ProxyFunc: proxyFunc, 127 }, 128 ), 129 ) 130 if err != nil { 131 return nil, err 132 } 133 134 region := cli.GetRegion(options.RegionID) 135 if region == nil { 136 return nil, fmt.Errorf("No such region %s", options.RegionID) 137 } 138 139 return region, nil 140 } 141 142 func main() { 143 parser, e := getSubcommandParser() 144 if e != nil { 145 showErrorAndExit(e) 146 } 147 e = parser.ParseArgs(os.Args[1:], false) 148 options := parser.Options().(*BaseOptions) 149 150 if parser.IsHelpSet() { 151 fmt.Print(parser.HelpString()) 152 return 153 } 154 subcmd := parser.GetSubcommand() 155 subparser := subcmd.GetSubParser() 156 if e != nil || subparser == nil { 157 if subparser != nil { 158 fmt.Print(subparser.Usage()) 159 } else { 160 fmt.Print(parser.Usage()) 161 } 162 showErrorAndExit(e) 163 return 164 } 165 suboptions := subparser.Options() 166 if subparser.IsHelpSet() { 167 fmt.Print(subparser.HelpString()) 168 return 169 } 170 var region *google.SRegion 171 region, e = newClient(options) 172 if e != nil { 173 showErrorAndExit(e) 174 } 175 e = subcmd.Invoke(region, suboptions) 176 if e != nil { 177 showErrorAndExit(e) 178 } 179 }