mirror of
https://codeberg.org/scip/esctl.git
synced 2026-08-24 10:04:18 +02:00
allow multiline json data in repl (#24)
This commit is contained in:
172
pkg/es/repl.go
172
pkg/es/repl.go
@@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
package es
|
package es
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
@@ -34,19 +35,98 @@ import (
|
|||||||
"github.com/chzyer/readline"
|
"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/<Ret> [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 {
|
func encodeAuth(username, password string) string {
|
||||||
return base64.StdEncoding.EncodeToString([]byte(username + ":" + password))
|
return base64.StdEncoding.EncodeToString([]byte(username + ":" + password))
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallAPI(conf *cfg.Config, input []string) error {
|
func CallAPI(conf *cfg.Config, verb, path, data string) error {
|
||||||
var data string
|
verb = strings.ToUpper(verb)
|
||||||
|
|
||||||
verb := strings.ToUpper(input[0])
|
|
||||||
path := input[1]
|
|
||||||
|
|
||||||
if len(input) == 3 {
|
|
||||||
data = input[2]
|
|
||||||
}
|
|
||||||
|
|
||||||
// we're using port-forwards anyway
|
// we're using port-forwards anyway
|
||||||
tr := &http.Transport{
|
tr := &http.Transport{
|
||||||
@@ -108,69 +188,37 @@ func prettyfiJson(conf *cfg.Config, raw []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Repl(conf *cfg.Config) error {
|
// interactively read arbitrary JSON data from STDIN, which is
|
||||||
verbs := []string{"post", "get", "put", "delete"}
|
// virtually a repl inside the primary repl
|
||||||
|
func readJSON(input string) (string, error) {
|
||||||
|
data := ""
|
||||||
|
|
||||||
fmt.Println("Input format: verb path [data]")
|
if input != "" {
|
||||||
fmt.Println("example: post /yourindex/_ccr/pause_follow")
|
data = input
|
||||||
|
} else {
|
||||||
|
scanner := bufio.NewScanner(os.Stdin)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := strings.TrimSpace(scanner.Text())
|
||||||
|
|
||||||
reader, err := readline.NewEx(&readline.Config{
|
if line == "" {
|
||||||
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
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
text = strings.TrimSpace(text)
|
data += line
|
||||||
|
}
|
||||||
if text == "" {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parts := strings.SplitN(strings.TrimSpace(text), " ", 3)
|
if data == "" {
|
||||||
if len(parts) < 2 {
|
return data, nil
|
||||||
fmt.Println("error: you need to input a verb, uri [and post data]")
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !slices.Contains(verbs, strings.ToLower(parts[0])) {
|
// validate
|
||||||
fmt.Println("error: verb must be one of " + strings.Join(verbs, ","))
|
check := map[string]any{}
|
||||||
continue
|
err := json.Unmarshal([]byte(data), &check)
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
if err != nil {
|
||||||
fmt.Printf("error: input data is not proper JSON: %s", err)
|
return "", fmt.Errorf("error: input data is not proper JSON: %s", err)
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = CallAPI(conf, parts)
|
return data, nil
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("failed to call API: %s\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
reader.SetPrompt("> ")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user