diff --git a/pkg/es/repl.go b/pkg/es/repl.go
index b9a6404..c3b357d 100644
--- a/pkg/es/repl.go
+++ b/pkg/es/repl.go
@@ -17,6 +17,7 @@ along with this program. If not, see .
package es
import (
+ "bufio"
"bytes"
"context"
"crypto/tls"
@@ -34,19 +35,98 @@ import (
"github.com/chzyer/readline"
)
+const intro = `Input format: verb path [data]"
+
+Example:
+
+post /yourindex/_ccr/pause_follow
+put /yourindex/_settings {"number_of_replicas": 1}
+
+You can also put multiline JSON after the path like:
+
+put /yourindex/_settings
+{
+ "number_of_replicas": 1
+}
+
+If you do NOT supply a JSON in the first line, you need to hit ENTER
+twice to complete.`
+
+func Repl(conf *cfg.Config) error {
+ verbs := []string{"post", "get", "put", "delete"}
+
+ fmt.Println(intro)
+ fmt.Println()
+
+ reader, err := readline.NewEx(&readline.Config{
+ Prompt: "> ",
+ HistoryFile: os.Getenv("HOME") + "/.config/esctl/history",
+ HistoryLimit: 500,
+ InterruptPrompt: "^C",
+ EOFPrompt: "exit",
+ HistorySearchFold: true,
+ })
+
+ if err != nil {
+ return fmt.Errorf("failed to initialize readline lib: %s", err)
+ }
+
+ for {
+ text, err := reader.Readline()
+ if err != nil {
+ break
+ }
+
+ text = strings.TrimSpace(text)
+
+ if text == "" {
+ continue
+ }
+
+ parts := strings.SplitN(strings.TrimSpace(text), " ", 3)
+ if len(parts) < 2 {
+ fmt.Println("error: you need to input a verb, uri [and post data]")
+ continue
+ }
+
+ if !slices.Contains(verbs, strings.ToLower(parts[0])) {
+ fmt.Println("error: verb must be one of " + strings.Join(verbs, ","))
+ continue
+ }
+
+ if !strings.HasPrefix(parts[1], "/") {
+ parts[1] = "/" + parts[1]
+ }
+
+ json := ""
+ if len(parts) == 3 {
+ // put /uri {json}
+ json = parts[2]
+ }
+
+ // put /uri/ [json]
+ data, err := readJSON(json)
+ if err != nil {
+ fmt.Println(err)
+ }
+
+ err = CallAPI(conf, parts[0], parts[1], data)
+ if err != nil {
+ fmt.Printf("failed to call API: %s\n", err)
+ }
+
+ reader.SetPrompt("> ")
+ }
+
+ return nil
+}
+
func encodeAuth(username, password string) string {
return base64.StdEncoding.EncodeToString([]byte(username + ":" + password))
}
-func CallAPI(conf *cfg.Config, input []string) error {
- var data string
-
- verb := strings.ToUpper(input[0])
- path := input[1]
-
- if len(input) == 3 {
- data = input[2]
- }
+func CallAPI(conf *cfg.Config, verb, path, data string) error {
+ verb = strings.ToUpper(verb)
// we're using port-forwards anyway
tr := &http.Transport{
@@ -108,69 +188,37 @@ func prettyfiJson(conf *cfg.Config, raw []byte) error {
return nil
}
-func Repl(conf *cfg.Config) error {
- verbs := []string{"post", "get", "put", "delete"}
+// interactively read arbitrary JSON data from STDIN, which is
+// virtually a repl inside the primary repl
+func readJSON(input string) (string, error) {
+ data := ""
- fmt.Println("Input format: verb path [data]")
- fmt.Println("example: post /yourindex/_ccr/pause_follow")
+ if input != "" {
+ data = input
+ } else {
+ scanner := bufio.NewScanner(os.Stdin)
+ for scanner.Scan() {
+ line := strings.TrimSpace(scanner.Text())
- reader, err := readline.NewEx(&readline.Config{
- Prompt: "> ",
- HistoryFile: os.Getenv("HOME") + "/.config/esctl/history",
- HistoryLimit: 500,
- InterruptPrompt: "^C",
- EOFPrompt: "exit",
- HistorySearchFold: true,
- })
-
- if err != nil {
- return fmt.Errorf("failed to initialize readline lib: %s", err)
- }
-
- for {
- text, err := reader.Readline()
- if err != nil {
- break
- }
-
- text = strings.TrimSpace(text)
-
- if text == "" {
- continue
- }
-
- parts := strings.SplitN(strings.TrimSpace(text), " ", 3)
- if len(parts) < 2 {
- fmt.Println("error: you need to input a verb, uri [and post data]")
- continue
- }
-
- if !slices.Contains(verbs, strings.ToLower(parts[0])) {
- fmt.Println("error: verb must be one of " + strings.Join(verbs, ","))
- continue
- }
-
- if !strings.HasPrefix(parts[1], "/") {
- fmt.Println("error: url path must start with /")
- continue
- }
-
- if len(parts) == 3 {
- data := map[string]any{}
- err := json.Unmarshal([]byte(parts[2]), &data)
- if err != nil {
- fmt.Printf("error: input data is not proper JSON: %s", err)
- continue
+ if line == "" {
+ break
}
- }
- err = CallAPI(conf, parts)
- if err != nil {
- fmt.Printf("failed to call API: %s\n", err)
+ data += line
}
-
- reader.SetPrompt("> ")
}
- return nil
+ if data == "" {
+ return data, nil
+ }
+
+ // validate
+ check := map[string]any{}
+ err := json.Unmarshal([]byte(data), &check)
+ if err != nil {
+ return "", fmt.Errorf("error: input data is not proper JSON: %s", err)
+
+ }
+
+ return data, nil
}