github.com/circl-dev/go-swagger@v0.31.0/generator/templates/cli/cli.gotmpl (about) 1 // Code generated by go-swagger; DO NOT EDIT. 2 3 4 {{ if .Copyright -}}// {{ comment .Copyright -}}{{ end }} 5 6 7 package {{ .GenOpts.CliPackage }} 8 9 // This file was generated by the swagger tool. 10 // Editing this file might prove futile when you re-run the swagger generate command 11 12 import ( 13 {{ imports .DefaultImports }} 14 {{ imports .Imports }} 15 16 "github.com/spf13/cobra" 17 "github.com/spf13/viper" 18 "github.com/circl-dev/runtime" 19 "github.com/go-openapi/swag" 20 httptransport "github.com/circl-dev/runtime/client" 21 homedir "github.com/mitchellh/go-homedir" 22 ) 23 24 // debug flag indicating that cli should output debug logs 25 var debug bool 26 // config file location 27 var configFile string 28 // dry run flag 29 var dryRun bool 30 31 // name of the executable 32 var exeName string = filepath.Base(os.Args[0]) 33 34 // logDebugf writes debug log to stdout 35 func logDebugf(format string, v ...interface{}) { 36 if !debug{ 37 return 38 } 39 log.Printf(format, v...) 40 } 41 42 {{/*TODO: make this a swagger cli option*/}} 43 // depth of recursion to construct model flags 44 var maxDepth int = 5 45 46 // makeClient constructs a client object 47 func makeClient(cmd *cobra.Command, args []string) (*client.{{ pascalize .Name }}, error) { 48 hostname := viper.GetString("hostname") 49 scheme := viper.GetString("scheme") 50 51 r := httptransport.New(hostname, client.DefaultBasePath, []string{scheme}) 52 r.SetDebug(debug) 53 54 {{- /* user might define custom mediatype xxx/json and there is no registered ones to handle. */}} 55 // set custom producer and consumer to use the default ones 56 {{ range .Consumes }} 57 {{ range .AllSerializers }} 58 {{- if stringContains .MediaType "json" }} 59 r.Consumers["{{ .MediaType }}"] = runtime.JSONConsumer() 60 {{- else }} 61 // warning: consumes {{ .MediaType }} is not supported by go-swagger cli yet 62 {{- end }} 63 {{- end }} 64 {{ end }} 65 {{ range .Produces }} 66 {{- range .AllSerializers }} 67 {{- if stringContains .MediaType "json" }} 68 r.Producers["{{ .MediaType }}"] = runtime.JSONProducer() 69 {{- else }} 70 // warning: produces {{ .MediaType }} is not supported by go-swagger cli yet 71 {{- end }} 72 {{- end }} 73 {{ end }} 74 75 {{- if .SecurityDefinitions }} 76 auth, err := makeAuthInfoWriter(cmd) 77 if err != nil { 78 return nil, err 79 } 80 r.DefaultAuthentication = auth 81 {{ end }} 82 appCli := client.New(r, strfmt.Default) 83 logDebugf("Server url: %v://%v", scheme, hostname) 84 return appCli, nil 85 } 86 87 // MakeRootCmd returns the root cmd 88 func MakeRootCmd() (*cobra.Command, error) { 89 cobra.OnInitialize(initViperConfigs) 90 91 // Use executable name as the command name 92 rootCmd := &cobra.Command{ 93 Use: exeName, 94 } 95 {{/*note: viper binded flag value must be retrieved from viper rather than cmd*/}} 96 // register basic flags 97 rootCmd.PersistentFlags().String("hostname", client.DefaultHost, "hostname of the service") 98 viper.BindPFlag("hostname", rootCmd.PersistentFlags().Lookup("hostname")) 99 rootCmd.PersistentFlags().String("scheme", client.DefaultSchemes[0], fmt.Sprintf("Choose from: %v", client.DefaultSchemes)) 100 viper.BindPFlag("scheme", rootCmd.PersistentFlags().Lookup("scheme")) 101 102 // configure debug flag 103 rootCmd.PersistentFlags().BoolVar(&debug, "debug", false, "output debug logs") 104 // configure config location 105 rootCmd.PersistentFlags().StringVar(&configFile, "config", "", "config file path") 106 // configure dry run flag 107 rootCmd.PersistentFlags().BoolVar(&dryRun, "dry-run", false, "do not send the request to server") 108 109 // register security flags 110 {{- if .SecurityDefinitions }} 111 if err := registerAuthInoWriterFlags(rootCmd); err != nil{ 112 return nil, err 113 } 114 {{- end }} 115 // add all operation groups 116 {{- range .OperationGroups -}} 117 {{- $operationGroupCmdVarName := printf "operationGroup%vCmd" (pascalize .Name) }} 118 {{ $operationGroupCmdVarName }}, err := makeOperationGroup{{ pascalize .Name }}Cmd() 119 if err != nil { 120 return nil, err 121 } 122 rootCmd.AddCommand({{ $operationGroupCmdVarName }}) 123 {{ end }} 124 125 // add cobra completion 126 rootCmd.AddCommand(makeGenCompletionCmd()) 127 128 return rootCmd, nil 129 } 130 131 // initViperConfigs initialize viper config using config file in '$HOME/.config/<cli name>/config.<json|yaml...>' 132 // currently hostname, scheme and auth tokens can be specified in this config file. 133 func initViperConfigs() { 134 if configFile != "" { 135 // use user specified config file location 136 viper.SetConfigFile(configFile) 137 }else{ 138 // look for default config 139 // Find home directory. 140 home, err := homedir.Dir() 141 cobra.CheckErr(err) 142 143 // Search config in home directory with name ".cobra" (without extension). 144 viper.AddConfigPath(path.Join(home, ".config", exeName)) 145 viper.SetConfigName("config") 146 } 147 148 if err := viper.ReadInConfig(); err != nil { 149 logDebugf("Error: loading config file: %v", err) 150 return 151 } 152 logDebugf("Using config file: %v", viper.ConfigFileUsed()) 153 } 154 155 {{- if .SecurityDefinitions }} 156 {{- /*youyuan: rework this since spec may define multiple auth schemes. 157 cli needs to detect which one user passed rather than add all of them.*/}} 158 // registerAuthInoWriterFlags registers all flags needed to perform authentication 159 func registerAuthInoWriterFlags(cmd *cobra.Command) error { 160 {{- range .SecurityDefinitions }} 161 /*{{.Name}} {{.Description}}*/ 162 {{- if .IsBasicAuth }} 163 cmd.PersistentFlags().String("username", "", "username for basic auth") 164 viper.BindPFlag("username", cmd.PersistentFlags().Lookup("username")) 165 cmd.PersistentFlags().String("password", "", "password for basic auth") 166 viper.BindPFlag("password", cmd.PersistentFlags().Lookup("password")) 167 {{- end }} 168 {{- if .IsAPIKeyAuth }} 169 cmd.PersistentFlags().String("{{.Name}}", "", `{{.Description}}`) 170 viper.BindPFlag("{{.Name}}", cmd.PersistentFlags().Lookup("{{.Name}}")) 171 {{- end }} 172 {{- if .IsOAuth2 }} 173 // oauth2: let user provide the token in a flag, rather than implement the logic to fetch the token. 174 cmd.PersistentFlags().String("oauth2-token", "", `{{.Description}}`) 175 viper.BindPFlag("oauth2-token", cmd.PersistentFlags().Lookup("oauth2-token")) 176 {{- end }} 177 {{- end }} 178 return nil 179 } 180 181 // makeAuthInfoWriter retrieves cmd flags and construct an auth info writer 182 func makeAuthInfoWriter(cmd *cobra.Command) (runtime.ClientAuthInfoWriter, error) { 183 auths := []runtime.ClientAuthInfoWriter{} 184 {{- range .SecurityDefinitions }} 185 /*{{.Name}} {{.Description}}*/ 186 {{- if .IsBasicAuth }} 187 if viper.IsSet("username") { 188 usr := viper.GetString("username") 189 if !viper.IsSet("password"){ 190 return nil, fmt.Errorf("Basic Auth password for user [%v] is not provided.", usr) 191 } 192 pwd := viper.GetString("password") 193 auths = append(auths, httptransport.BasicAuth(usr,pwd)) 194 } 195 {{- end }} 196 {{- if .IsAPIKeyAuth }} 197 if viper.IsSet("{{.Name}}") { 198 {{ pascalize .Name }}Key := viper.GetString("{{.Name}}") 199 auths = append(auths, httptransport.APIKeyAuth("{{.Name}}", "{{.In}}", {{ pascalize .Name }}Key)) 200 } 201 {{- end }} 202 {{- if .IsOAuth2 }} 203 if viper.IsSet("oauth2-token") { 204 // oauth2 workflow for generated CLI is not ideal. 205 // If you have suggestions on how to support it, raise an issue here: https://github.com/circl-dev/go-swagger/issues 206 // This will be added to header: "Authorization: Bearer {oauth2-token value}" 207 token := viper.GetString("oauth2-token") 208 auths = append(auths, httptransport.BearerToken(token)) 209 } 210 {{- end }} 211 {{- end }} 212 if len(auths) == 0 { 213 logDebugf("Warning: No auth params detected.") 214 return nil, nil 215 } 216 // compose all auths together 217 return httptransport.Compose(auths...), nil 218 } 219 {{- end }} 220 221 {{ range .OperationGroups -}} 222 func makeOperationGroup{{ pascalize .Name }}Cmd() (*cobra.Command, error) { 223 {{- $operationGroupCmdVarName := printf "operationGroup%vCmd" (pascalize .Name) }} 224 {{ $operationGroupCmdVarName }} := &cobra.Command{ 225 Use: "{{ .Name }}", 226 Long: `{{ .Description }}`, 227 } 228 {{ range .Operations }} 229 {{- $operationCmdVarName := printf "operation%vCmd" (pascalize .Name) }} 230 {{ $operationCmdVarName }}, err := makeOperation{{pascalize .Package}}{{ pascalize .Name }}Cmd() 231 if err != nil { 232 return nil, err 233 } 234 {{ $operationGroupCmdVarName }}.AddCommand({{ $operationCmdVarName }}) 235 {{ end }} 236 return {{ $operationGroupCmdVarName }}, nil 237 } 238 {{ end }} {{/*operation group*/}}