package main import ( "context" "flag" "fmt" "io/ioutil" "os" elastic "github.com/olivere/elastic/v7" "encoding/json" "strings" ) func handleIndexCommand() { if len(os.Args) < 3 { fmt.Fprintf(os.Stderr, "%s index: subcommand missing\n", os.Args[0]) printIndexUsage() os.Exit(1) } subcmd := strings.ToLower(os.Args[2]) switch subcmd { case "list", "ls", "l": listcmd := flag.NewFlagSet("index list", flag.ExitOnError) listcmd.SetOutput(os.Stdout) cfgpath := listcmd.String("config", "", "path to configuration") server := listcmd.String("server", "", "server name to use") listcmd.Parse(os.Args[3:]) cfg := LoadConfig(*cfgpath) es := cfg.GetClient(*server) indexes, err := es.IndexNames() if err != nil { fmt.Fprintf(os.Stderr, "elastic error: %s\n", err.Error()) os.Exit(1) } for _, index := range indexes { fmt.Printf("%s\n", index) } case "search", "sea", "s": cmd := flag.NewFlagSet("index search", flag.ExitOnError) cmd.SetOutput(os.Stdout) cmd.Usage = func() { fmt.Printf("Usage: %s index %s [args] \n", os.Args[0], subcmd) cmd.PrintDefaults() } cfgpath := cmd.String("config", "", "path to configuration") server := cmd.String("server", "", "server name to use") fields := cmd.String("fields", "*", "fields to include in search") defop := cmd.String("defop", "AND", "default search operator") cmd.Parse(os.Args[3:]) if *defop != "AND" && *defop != "OR" { fmt.Fprintf(os.Stderr, "default operator must be AND or OR\n") cmd.Usage() os.Exit(1) } if len(cmd.Args()) < 2 { fmt.Fprintf(os.Stderr, "index name and query required for index search\n") cmd.Usage() os.Exit(1) } cfg := LoadConfig(*cfgpath) es := cfg.GetClient(*server) res, err := es.Search().Index(cmd.Arg(0)).StoredField(*fields).Query( elastic.NewQueryStringQuery(cmd.Arg(1)).DefaultOperator(*defop), ).Do(context.Background()) if err != nil { fmt.Fprintf(os.Stderr, "elastic error: %s\n", err.Error()) os.Exit(1) } for _, r := range res.Hits.Hits { b, err := json.Marshal(r.Fields) if err != nil { fmt.Fprintf(os.Stderr, "marshal error: %s\n", err.Error()) os.Exit(1) } fmt.Fprintf(os.Stdout, "%s: %s\n", r.Id, string(b)) } fmt.Fprintf(os.Stdout, "Total: %d\n", res.Hits.TotalHits.Value); case "delete", "del", "d": cmd := flag.NewFlagSet("index delete", flag.ExitOnError) cmd.SetOutput(os.Stdout) cmd.Usage = func() { fmt.Printf("Usage: %s index %s [args] ...\n", os.Args[0], subcmd) cmd.PrintDefaults() } cfgpath := cmd.String("config", "", "path to configuration") server := cmd.String("server", "", "server name to use") cmd.Parse(os.Args[3:]) if len(cmd.Args()) < 1 { fmt.Fprintf(os.Stderr, "index name required for index delete\n") cmd.Usage() os.Exit(1) } cfg := LoadConfig(*cfgpath) es := cfg.GetClient(*server) _, err := es.DeleteIndex(cmd.Args()...).Do(context.Background()) if err != nil { fmt.Fprintf(os.Stderr, "elastic error: %s\n", err.Error()) os.Exit(1) } case "add", "a": cmd := flag.NewFlagSet("index add", flag.ExitOnError) cmd.SetOutput(os.Stdout) cmd.Usage = func() { fmt.Printf("Usage: %s index %s [args] \n", os.Args[0], subcmd) cmd.PrintDefaults() } cfgpath := cmd.String("config", "", "path to configuration") server := cmd.String("server", "", "server name to use") bodystr := cmd.String("body", "", "json string to use as body options during add") bodyfile := cmd.String("bodyfile", "", "json file to use as body options during add") cmd.Parse(os.Args[3:]) if len(cmd.Args()) < 1 { fmt.Fprintf(os.Stderr, "index name required for index add\n") cmd.PrintDefaults() os.Exit(1) } if *bodystr != "" && *bodyfile != "" { fmt.Fprintf(os.Stderr, "body parameter cannot be used with bodyfile parameter\n") os.Exit(1) } body := *bodystr if *bodyfile != "" { raw, err := ioutil.ReadFile(*bodyfile) if err != nil { fmt.Fprintf(os.Stderr, "read error: %s\n", err.Error()) os.Exit(1) } body = string(raw) } cfg := LoadConfig(*cfgpath) es := cfg.GetClient(*server) ics := es.CreateIndex(cmd.Arg(0)) if body != "" { ics.Body(body) } _, err := ics.Do(context.Background()) if err != nil { fmt.Fprintf(os.Stderr, "elastic error: %s\n", err.Error()) os.Exit(1) } case "refresh": cmd := flag.NewFlagSet("index refresh", flag.ExitOnError) cmd.SetOutput(os.Stdout) cmd.Usage = func() { fmt.Printf("Usage: %s index %s [args] ...\n", os.Args[0], subcmd) cmd.PrintDefaults() } cfgpath := cmd.String("config", "", "path to configuration") server := cmd.String("server", "", "server name to use") cmd.Parse(os.Args[3:]) if len(cmd.Args()) < 1 { fmt.Fprintf(os.Stderr, "index name required for index refresh\n") cmd.Usage() os.Exit(1) } cfg := LoadConfig(*cfgpath) es := cfg.GetClient(*server) _, err := es.Refresh(cmd.Args()...).Do(context.Background()) if err != nil { fmt.Fprintf(os.Stderr, "elastic error: %s\n", err.Error()) os.Exit(1) } case "--help": printIndexUsage() os.Exit(0) default: fmt.Fprintf(os.Stderr, "%s: index '%s' is not a recognized subcommand\n", os.Args[0], os.Args[2]) printIndexUsage() os.Exit(1) } } func printIndexUsage() { fmt.Printf("Usage: %s index ... \n", os.Args[0]) fmt.Printf("See '%s index --help' for information", os.Args[0]) fmt.Printf(" on a specific command\n") fmt.Printf("valid subcommands:\n") fmt.Printf(" list list indexes\n") fmt.Printf(" add add index\n") fmt.Printf(" delete delete index\n") fmt.Printf(" refresh refresh index\n") }