summaryrefslogtreecommitdiffstats
path: root/client/go/cmd/curl.go
diff options
context:
space:
mode:
Diffstat (limited to 'client/go/cmd/curl.go')
-rw-r--r--client/go/cmd/curl.go143
1 files changed, 143 insertions, 0 deletions
diff --git a/client/go/cmd/curl.go b/client/go/cmd/curl.go
new file mode 100644
index 00000000000..4d949b51e8f
--- /dev/null
+++ b/client/go/cmd/curl.go
@@ -0,0 +1,143 @@
+package cmd
+
+import (
+ "fmt"
+ "log"
+ "os"
+ "os/exec"
+ "strings"
+
+ "github.com/kballard/go-shellquote"
+ "github.com/spf13/cobra"
+ "github.com/vespa-engine/vespa/client/go/vespa"
+)
+
+var curlDryRun bool
+var curlPath string
+
+func init() {
+ rootCmd.AddCommand(curlCmd)
+ curlCmd.Flags().StringVarP(&curlPath, "path", "p", "", "The path to curl. If this is unset, curl from PATH is used")
+ curlCmd.Flags().BoolVarP(&curlDryRun, "dry-run", "n", false, "Print the curl command that would be executed")
+}
+
+var curlCmd = &cobra.Command{
+ Use: "curl [curl-options] path",
+ Short: "Query Vespa using curl",
+ Long: `Query Vespa using curl.
+
+Execute curl with the appropriate URL, certificate and private key for your application.`,
+ Example: `$ vespa curl /search/?yql=query
+$ vespa curl -- -v --data-urlencode "yql=select * from sources * where title contains 'foo';" /search/
+$ vespa curl -t local -- -v /search/?yql=query
+`,
+ DisableAutoGenTag: true,
+ Args: cobra.MinimumNArgs(1),
+ Run: func(cmd *cobra.Command, args []string) {
+ cfg, err := LoadConfig()
+ if err != nil {
+ fatalErr(err, "Could not load config")
+ return
+ }
+ app, err := vespa.ApplicationFromString(getApplication())
+ if err != nil {
+ fatalErr(err)
+ return
+ }
+ privateKeyFile, err := cfg.PrivateKeyPath(app)
+ if err != nil {
+ fatalErr(err)
+ return
+ }
+ certificateFile, err := cfg.CertificatePath(app)
+ if err != nil {
+ fatalErr(err)
+ return
+ }
+ service := getService("query", 0)
+ c := &curl{privateKeyPath: privateKeyFile, certificatePath: certificateFile}
+ if curlDryRun {
+ cmd, err := c.command(service.BaseURL, args...)
+ if err != nil {
+ fatalErr(err, "Failed to create curl command")
+ return
+ }
+ log.Print(shellquote.Join(cmd.Args...))
+ } else {
+ if err := c.run(service.BaseURL, args...); err != nil {
+ fatalErr(err, "Failed to run curl")
+ return
+ }
+ }
+ },
+}
+
+type curl struct {
+ path string
+ certificatePath string
+ privateKeyPath string
+}
+
+func (c *curl) run(baseURL string, args ...string) error {
+ cmd, err := c.command(baseURL, args...)
+ if err != nil {
+ return err
+ }
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ if err := cmd.Start(); err != nil {
+ return err
+ }
+ return cmd.Wait()
+}
+
+func (c *curl) command(baseURL string, args ...string) (*exec.Cmd, error) {
+ if len(args) == 0 {
+ return nil, fmt.Errorf("need at least one argument")
+ }
+
+ if c.path == "" {
+ resolvedPath, err := resolveCurlPath()
+ if err != nil {
+ return nil, err
+ }
+ c.path = resolvedPath
+ }
+
+ path := args[len(args)-1]
+ args = args[:len(args)-1]
+ if !hasOption("--key", args) && c.privateKeyPath != "" {
+ args = append(args, "--key", c.privateKeyPath)
+ }
+ if !hasOption("--cert", args) && c.certificatePath != "" {
+ args = append(args, "--cert", c.certificatePath)
+ }
+
+ baseURL = strings.TrimSuffix(baseURL, "/")
+ path = strings.TrimPrefix(path, "/")
+ args = append(args, baseURL+"/"+path)
+
+ return exec.Command(c.path, args...), nil
+}
+
+func hasOption(option string, args []string) bool {
+ for _, arg := range args {
+ if arg == option {
+ return true
+ }
+ }
+ return false
+}
+
+func resolveCurlPath() (string, error) {
+ var curlPath string
+ var err error
+ curlPath, err = exec.LookPath("curl")
+ if err != nil {
+ curlPath, err = exec.LookPath("curl.exe")
+ if err != nil {
+ return "", err
+ }
+ }
+ return curlPath, nil
+}