cmd/rc: add --user and --pass flags and interpret --rc-user, --rc-pass, --rc-addr

This commit is contained in:
Nick Craig-Wood 2018-11-03 12:40:50 +00:00
parent 75e8ea383c
commit 181267e20e

View file

@ -22,6 +22,8 @@ var (
noOutput = false
url = "http://localhost:5572/"
jsonInput = ""
authUser = ""
authPass = ""
)
func init() {
@ -29,14 +31,24 @@ func init() {
commandDefintion.Flags().BoolVarP(&noOutput, "no-output", "", noOutput, "If set don't output the JSON result.")
commandDefintion.Flags().StringVarP(&url, "url", "", url, "URL to connect to rclone remote control.")
commandDefintion.Flags().StringVarP(&jsonInput, "json", "", jsonInput, "Input JSON - use instead of key=value args.")
commandDefintion.Flags().StringVarP(&authUser, "user", "", "", "Username to use to rclone remote control.")
commandDefintion.Flags().StringVarP(&authPass, "pass", "", "", "Password to use to connect to rclone remote control.")
}
var commandDefintion = &cobra.Command{
Use: "rc commands parameter",
Short: `Run a command against a running rclone.`,
Long: `
This runs a command against a running rclone. By default it will use
that specified in the --rc-addr command.
This runs a command against a running rclone. Use the --url flag to
specify an non default URL to connect on. This can be either a
":port" which is taken to mean "http://localhost:port" or a
"host:port" which is taken to mean "http://host:port"
A username and password can be passed in with --user and --pass.
Note that --rc-addr, --rc-user, --rc-pass will be read also for --url,
--user, --pass.
Arguments should be passed in as parameter=value.
@ -50,6 +62,7 @@ Use "rclone rc" to see a list of all possible commands.`,
Run: func(command *cobra.Command, args []string) {
cmd.CheckArgs(0, 1E9, command, args)
cmd.Run(false, false, command, func() error {
parseFlags()
if len(args) == 0 {
return list()
}
@ -58,30 +71,56 @@ Use "rclone rc" to see a list of all possible commands.`,
},
}
// Parse the flags
func parseFlags() {
// set alternates from alternate flags
setAlternateFlag("rc-addr", &url)
setAlternateFlag("rc-user", &authUser)
setAlternateFlag("rc-pass", &authPass)
// If url is just :port then fix it up
if strings.HasPrefix(url, ":") {
url = "localhost" + url
}
// if url is just host:port add http://
if !strings.HasPrefix(url, "http:") && !strings.HasPrefix(url, "https:") {
url = "http://" + url
}
// if url doesn't end with / add it
if !strings.HasSuffix(url, "/") {
url += "/"
}
}
// If the user set flagName set the output to its value
func setAlternateFlag(flagName string, output *string) {
if rcFlag := pflag.Lookup(flagName); rcFlag != nil && rcFlag.Changed {
*output = rcFlag.Value.String()
}
}
// do a call from (path, in) to (out, err).
//
// if err is set, out may be a valid error return or it may be nil
func doCall(path string, in rc.Params) (out rc.Params, err error) {
// Do HTTP request
client := fshttp.NewClient(fs.Config)
url := url
// set the user use --rc-addr as well as --url
if rcAddrFlag := pflag.Lookup("rc-addr"); rcAddrFlag != nil && rcAddrFlag.Changed {
url = rcAddrFlag.Value.String()
if strings.HasPrefix(url, ":") {
url = "localhost" + url
}
url = "http://" + url + "/"
}
if !strings.HasSuffix(url, "/") {
url += "/"
}
url += path
data, err := json.Marshal(in)
if err != nil {
return nil, errors.Wrap(err, "failed to encode JSON")
}
resp, err := client.Post(url, "application/json", bytes.NewBuffer(data))
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
if err != nil {
return nil, errors.Wrap(err, "failed to make request")
}
req.Header.Set("Content-Type", "application/json")
if authUser != "" || authPass != "" {
req.SetBasicAuth(authUser, authPass)
}
resp, err := client.Do(req)
if err != nil {
return nil, errors.Wrap(err, "connection failed")
}
@ -172,6 +211,11 @@ func list() error {
}
fmt.Printf("### %s: %s\n\n", info["Path"], info["Title"])
fmt.Printf("%s\n\n", info["Help"])
if authRequired := info["AuthRequired"]; authRequired != nil {
if authRequired.(bool) {
fmt.Printf("Authentication is required for this call.\n\n")
}
}
}
return nil
}