Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subcommands enhancements #4510

Merged
merged 10 commits into from
Jun 26, 2017
2 changes: 1 addition & 1 deletion filebeat/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ func init() {

RootCmd = cmd.GenRootCmdWithRunFlags(Name, "", beater.New, runFlags)
RootCmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("M"))
RootCmd.ConfigTest.Flags().AddGoFlag(flag.CommandLine.Lookup("modules"))
RootCmd.ConfigTestCmd.Flags().AddGoFlag(flag.CommandLine.Lookup("modules"))
RootCmd.SetupCmd.Flags().AddGoFlag(flag.CommandLine.Lookup("modules"))
}
9 changes: 7 additions & 2 deletions heartbeat/cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package cmd

import cmd "github.com/elastic/beats/libbeat/cmd"
import "github.com/elastic/beats/heartbeat/beater"
import (
// register default heartbeat monitors
_ "github.com/elastic/beats/heartbeat/monitors/defaults"

"github.com/elastic/beats/heartbeat/beater"
cmd "github.com/elastic/beats/libbeat/cmd"
)

// Name of this beat
var Name = "heartbeat"
Expand Down
3 changes: 0 additions & 3 deletions heartbeat/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ import (
"os"

"github.com/elastic/beats/heartbeat/cmd"

// register default heartbeat monitors
_ "github.com/elastic/beats/heartbeat/monitors/defaults"
)

func main() {
Expand Down
27 changes: 9 additions & 18 deletions libbeat/beat/beat.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ func New(name, v string) (*Beat, error) {
}

// init does initialization of things common to all actions (read confs, flags)
func (b *Beat) init() error {
func (b *Beat) Init() error {
err := b.handleFlags()
if err != nil {
return err
Expand Down Expand Up @@ -266,7 +266,7 @@ func (b *Beat) createBeater(bt Creator) (Beater, error) {
}

func (b *Beat) launch(bt Creator) error {
err := b.init()
err := b.Init()
if err != nil {
return err
}
Expand All @@ -289,13 +289,17 @@ func (b *Beat) launch(bt Creator) error {

// If -configtest was specified, exit now prior to run.
if cfgfile.IsTestConfig() {
logp.Deprecate("6.0", "-configtest flag has been deprecated, use configtest subcommand")
fmt.Println("Config OK")
return GracefulExit
}

svc.HandleSignals(beater.Stop)

// TODO Deprecate this in favor of setup subcommand (7.0)
if *setup {
logp.Deprecate("6.0", "-setup flag has been deprectad, use setup subcommand")
}
err = b.loadDashboards(false)
if err != nil {
return err
Expand All @@ -321,7 +325,7 @@ func (b *Beat) launch(bt Creator) error {
// TestConfig check all settings are ok and the beat can be run
func (b *Beat) TestConfig(bt Creator) error {
return handleError(func() error {
err := b.init()
err := b.Init()
if err != nil {
return err
}
Expand All @@ -340,7 +344,7 @@ func (b *Beat) TestConfig(bt Creator) error {
// Setup registers ES index template and kibana dashboards
func (b *Beat) Setup(bt Creator, template, dashboards, machineLearning bool) error {
return handleError(func() error {
err := b.init()
err := b.Init()
if err != nil {
return err
}
Expand Down Expand Up @@ -414,6 +418,7 @@ func (b *Beat) handleFlags() error {
flag.Parse()

if *printVersion {
logp.Deprecate("6.0", "-version flag has been deprectad, use version subcommand")
fmt.Printf("%s version %s (%s), libbeat %s\n",
b.Info.Beat, b.Info.Version, runtime.GOARCH, version.GetDefaultVersion())
return GracefulExit
Expand Down Expand Up @@ -595,20 +600,6 @@ func (b *Beat) registerTemplateLoading() error {
if err != nil {
return fmt.Errorf("unpacking template config fails: %v", err)
}
if len(cfg.OutputToFile.Path) > 0 {
// output to file is enabled
loader, err := template.NewLoader(b.Config.Template, nil, b.Info)
if err != nil {
return fmt.Errorf("Error creating Elasticsearch template loader: %v", err)
}
err = loader.Generate()
if err != nil {
return fmt.Errorf("Error generating template: %v", err)
}

// XXX: Should we kill the Beat here or just continue?
return fmt.Errorf("Stopping after successfully writing the template to the file.")
}
}

// Loads template by default if esOutput is enabled
Expand Down
11 changes: 5 additions & 6 deletions libbeat/beat/setup.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package beat

type TemplateConfig struct {
Enabled bool `config:"enabled"`
Name string `config:"name"`
Fields string `config:"fields"`
Overwrite bool `config:"overwrite"`
OutputToFile string `config:"output_to_file"`
Settings map[string]string `config:"settings"`
Enabled bool `config:"enabled"`
Name string `config:"name"`
Fields string `config:"fields"`
Overwrite bool `config:"overwrite"`
Settings map[string]string `config:"settings"`
}
32 changes: 32 additions & 0 deletions libbeat/cmd/completion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package cmd

import (
"fmt"
"os"

"github.com/spf13/cobra"
)

func genCompletionCmd(name, version string, rootCmd *BeatsRootCmd) *cobra.Command {
completionCmd := cobra.Command{
Use: "completion SHELL",
Short: "Output shell completion code for the specified shell (bash only by the moment)",
// We don't want to expose this one in help:
Hidden: true,
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 1 {
fmt.Println("Expected one argument with the desired shell")
os.Exit(1)
}

switch args[0] {
case "bash":
rootCmd.GenBashCompletion(os.Stdout)
default:
fmt.Printf("Unknown shell %s, only bash is available\n", args[0])
}
},
}

return &completionCmd
}
2 changes: 2 additions & 0 deletions libbeat/cmd/configtest.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"fmt"
"os"

"github.com/spf13/cobra"
Expand All @@ -15,6 +16,7 @@ func genConfigTestCmd(name, version string, beatCreator beat.Creator) *cobra.Com
Run: func(cmd *cobra.Command, args []string) {
b, err := beat.New(name, version)
if err != nil {
fmt.Fprintf(os.Stderr, "Error initializing beat: %s\n", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like it too much that we get these writes directly to stdout/stderr. Perhaps it would be possible to init logging with stderr on any non-run command?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's your exact concern? I tried to do it just the other way around, strip all log metadata as this is command line

It would be possible though

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just don't like it that logp and fmt.Println are interleaved in the code. But def. not a show stopper.

os.Exit(1)
}

Expand Down
20 changes: 20 additions & 0 deletions libbeat/cmd/export.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package cmd

import (
"github.com/spf13/cobra"

"github.com/elastic/beats/libbeat/beat"
"github.com/elastic/beats/libbeat/cmd/export"
)

func genExportCmd(name, beatVersion string, beatCreator beat.Creator) *cobra.Command {
exportCmd := &cobra.Command{
Use: "export",
Short: "Export current config or index template",
}

exportCmd.AddCommand(export.GenExportConfigCmd(name, beatVersion, beatCreator))
exportCmd.AddCommand(export.GenTemplateConfigCmd(name, beatVersion, beatCreator))

return exportCmd
}
45 changes: 45 additions & 0 deletions libbeat/cmd/export/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package export

import (
"fmt"
"os"

"github.com/spf13/cobra"
"gopkg.in/yaml.v2"

"github.com/elastic/beats/libbeat/beat"
)

func GenExportConfigCmd(name, beatVersion string, beatCreator beat.Creator) *cobra.Command {
return &cobra.Command{
Use: "config",
Short: "Export current config to stdout",
Run: func(cmd *cobra.Command, args []string) {
b, err := beat.New(name, beatVersion)
if err != nil {
fmt.Fprintf(os.Stderr, "Error initializing beat: %s\n", err)
os.Exit(1)
}

err = b.Init()
if err != nil {
fmt.Fprintf(os.Stderr, "Error initializing beat: %s\n", err)
os.Exit(1)
}

var config map[string]interface{}
err = b.RawConfig.Unpack(&config)
if err != nil {
fmt.Fprintf(os.Stderr, "Error unpacking config")
os.Exit(1)
}
res, err := yaml.Marshal(config)
if err != nil {
fmt.Fprintf(os.Stderr, "Error converting config to YAML format")
os.Exit(1)
}

os.Stdout.Write(res)
},
}
}
65 changes: 65 additions & 0 deletions libbeat/cmd/export/template.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package export

import (
"fmt"
"os"

"github.com/spf13/cobra"

"github.com/elastic/beats/libbeat/beat"
"github.com/elastic/beats/libbeat/template"
)

func GenTemplateConfigCmd(name, beatVersion string, beatCreator beat.Creator) *cobra.Command {
genTemplateConfigCmd := &cobra.Command{
Use: "template",
Short: "Export index template to stdout",
Run: func(cmd *cobra.Command, args []string) {
version, _ := cmd.Flags().GetString("es.version")
index, _ := cmd.Flags().GetString("index")

b, err := beat.New(name, beatVersion)
if err != nil {
fmt.Fprintf(os.Stderr, "Error initializing beat: %s\n", err)
os.Exit(1)
}
err = b.Init()
if err != nil {
fmt.Fprintf(os.Stderr, "Error initializing beat: %s\n", err)
os.Exit(1)
}

cfg := template.DefaultConfig
if b.Config.Template.Enabled() {
err = b.Config.Template.Unpack(&cfg)
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting template settings: %+v", err)
os.Exit(1)
}
}

tmpl, err := template.New(b.Info.Version, version, index, cfg.Settings)
if err != nil {
fmt.Fprintf(os.Stderr, "Error generating template: %+v", err)
os.Exit(1)
}

templateString, err := tmpl.Load(cfg.Fields)
if err != nil {
fmt.Fprintf(os.Stderr, "Error generating template: %+v", err)
os.Exit(1)
}

_, err = os.Stdout.WriteString(templateString.StringToPrint() + "\n")
if err != nil {
fmt.Fprintf(os.Stderr, "Error writing template: %+v", err)
os.Exit(1)
}
},
}

genTemplateConfigCmd.Flags().String("es.version", beatVersion, "Elasticsearch version")
genTemplateConfigCmd.Flags().String("index", name, "Base index name")

return genTemplateConfigCmd
}
20 changes: 12 additions & 8 deletions libbeat/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@ import (
"github.com/spf13/pflag"

"github.com/elastic/beats/libbeat/beat"
"github.com/elastic/beats/libbeat/logp"
)

func init() {
// backwards compatibility workaround, convert -flags to --flags:
for i, arg := range os.Args[1:] {
if strings.HasPrefix(arg, "-") && !strings.HasPrefix(arg, "--") && len(arg) > 2 {
logp.Deprecate("6.0", "Argument %s should be -%s", arg, arg)
os.Args[1+i] = "-" + arg
}
}
Expand All @@ -26,10 +24,12 @@ func init() {
// flags and runs subcommands
type BeatsRootCmd struct {
cobra.Command
RunCmd *cobra.Command
SetupCmd *cobra.Command
VersionCmd *cobra.Command
ConfigTest *cobra.Command
RunCmd *cobra.Command
SetupCmd *cobra.Command
VersionCmd *cobra.Command
ConfigTestCmd *cobra.Command
CompletionCmd *cobra.Command
ExportCmd *cobra.Command
}

// GenRootCmd returns the root command to use for your beat. It takes
Expand All @@ -50,7 +50,9 @@ func GenRootCmdWithRunFlags(name, version string, beatCreator beat.Creator, runF
rootCmd.RunCmd = genRunCmd(name, version, beatCreator, runFlags)
rootCmd.SetupCmd = genSetupCmd(name, version, beatCreator)
rootCmd.VersionCmd = genVersionCmd(name, version)
rootCmd.ConfigTest = genConfigTestCmd(name, version, beatCreator)
rootCmd.ConfigTestCmd = genConfigTestCmd(name, version, beatCreator)
rootCmd.CompletionCmd = genCompletionCmd(name, version, rootCmd)
rootCmd.ExportCmd = genExportCmd(name, version, beatCreator)

// Root command is an alias for run
rootCmd.Run = rootCmd.RunCmd.Run
Expand All @@ -75,7 +77,9 @@ func GenRootCmdWithRunFlags(name, version string, beatCreator beat.Creator, runF
rootCmd.AddCommand(rootCmd.RunCmd)
rootCmd.AddCommand(rootCmd.SetupCmd)
rootCmd.AddCommand(rootCmd.VersionCmd)
rootCmd.AddCommand(rootCmd.ConfigTest)
rootCmd.AddCommand(rootCmd.ConfigTestCmd)
rootCmd.AddCommand(rootCmd.CompletionCmd)
rootCmd.AddCommand(rootCmd.ExportCmd)

return rootCmd
}
3 changes: 3 additions & 0 deletions libbeat/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ func genRunCmd(name, version string, beatCreator beat.Creator, runFlags *pflag.F
runCmd.Flags().AddGoFlag(flag.CommandLine.Lookup("setup"))
runCmd.Flags().AddGoFlag(flag.CommandLine.Lookup("version"))

runCmd.Flags().MarkDeprecated("version", "version flag has been deprectad, use version subcommand")
runCmd.Flags().MarkDeprecated("configtest", "setup flag has been deprectad, use configtest subcommand")

if runFlags != nil {
runCmd.Flags().AddFlagSet(runFlags)
}
Expand Down
2 changes: 2 additions & 0 deletions libbeat/cmd/setup.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"fmt"
"os"

"github.com/spf13/cobra"
Expand All @@ -20,6 +21,7 @@ func genSetupCmd(name, version string, beatCreator beat.Creator) *cobra.Command
Run: func(cmd *cobra.Command, args []string) {
beat, err := beat.New(name, version)
if err != nil {
fmt.Fprintf(os.Stderr, "Error initializing beat: %s\n", err)
os.Exit(1)
}

Expand Down
Loading