Skip to content

Commit

Permalink
Redesign cli flag parsing. Use new library to generate options from c…
Browse files Browse the repository at this point in the history
…onfig objects
  • Loading branch information
gdiazlo committed Apr 10, 2019
1 parent 8a610d9 commit 40d10bb
Show file tree
Hide file tree
Showing 15 changed files with 541 additions and 681 deletions.
83 changes: 21 additions & 62 deletions cmd/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,76 +17,35 @@
package cmd

import (
"regexp"

"github.com/spf13/cobra"
v "github.com/spf13/viper"
"context"

"github.com/bbva/qed/gossip"
"github.com/bbva/qed/log"
"github.com/octago/sflags/gen/gpflag"
"github.com/spf13/cobra"
)

func newAgentCommand(cmdCtx *cmdContext, args []string) *cobra.Command {

config := gossip.DefaultConfig()

cmd := &cobra.Command{
Use: "agent",
Short: "Start a gossip agent for the verifiable log QED",
}

f := cmd.PersistentFlags()
f.StringVar(&config.NodeName, "node", "", "Unique name for node. If not set, fallback to hostname")
f.StringVar(&config.BindAddr, "bind", "", "Bind address for TCP/UDP gossip on (host:port)")
f.StringVar(&config.AdvertiseAddr, "advertise", "", "Address to advertise to cluster")
f.StringVar(&config.MetricsAddr, "metrics", "", "Address to bind metrics endpoint")
f.StringSliceVar(&config.StartJoin, "join", []string{}, "Comma-delimited list of nodes ([host]:port), through which a cluster can be joined")
f.StringSliceVar(&config.AlertsUrls, "alertsUrls", []string{}, "Comma-delimited list of Alert servers ([host]:port), through which an agent can post alerts")

// Lookups
v.BindPFlag("agent.node", f.Lookup("node"))
v.BindPFlag("agent.bind", f.Lookup("bind"))
v.BindPFlag("agent.advertise", f.Lookup("advertise"))
v.BindPFlag("agent.metrics", f.Lookup("metrics"))
v.BindPFlag("agent.join", f.Lookup("join"))
v.BindPFlag("agent.alerts_urls", f.Lookup("alertsUrls"))

agentPreRun := func(config gossip.Config) gossip.Config {
config.EnableCompression = true
config.NodeName = v.GetString("agent.node")
config.BindAddr = v.GetString("agent.bind")
config.AdvertiseAddr = v.GetString("agent.advertise")
config.MetricsAddr = v.GetString("agent.metrics")
config.StartJoin = v.GetStringSlice("agent.join")
config.AlertsUrls = v.GetStringSlice("agent.alerts_urls")

markStringRequired(config.NodeName, "node")
markStringRequired(config.BindAddr, "bind")
markSliceStringRequired(config.StartJoin, "join")
markSliceStringRequired(config.AlertsUrls, "alertsUrls")

return config
}
var agentCmd *cobra.Command = &cobra.Command{
Use: "agent",
Short: "Provides access to the QED gossip agents",
TraverseChildren: true,
}

var kind string
re := regexp.MustCompile("^monitor$|^auditor$|^publisher$")
for _, arg := range args {
if re.MatchString(arg) {
kind = arg
break
}
}
var agentCtx context.Context = configAgent()

switch kind {
case "publisher":
cmd.AddCommand(newAgentPublisherCommand(cmdCtx, *config, agentPreRun))
func init() {
Root.AddCommand(agentCmd)
}

case "auditor":
cmd.AddCommand(newAgentAuditorCommand(cmdCtx, *config, agentPreRun))
func configAgent() context.Context {

case "monitor":
cmd.AddCommand(newAgentMonitorCommand(cmdCtx, *config, agentPreRun))
conf := gossip.DefaultConfig()
a := &struct{ Agent *gossip.Config }{conf}
err := gpflag.ParseTo(a, agentCmd.PersistentFlags())
if err != nil {
log.Fatalf("err: %v", err)
}

return cmd

return context.WithValue(Ctx, k("agent.config"), conf)
}

61 changes: 5 additions & 56 deletions cmd/agent_auditor.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Expand All @@ -14,74 +16,21 @@
package cmd

import (
"github.com/spf13/cobra"
v "github.com/spf13/viper"
"context"

"github.com/bbva/qed/gossip"
"github.com/bbva/qed/gossip/auditor"
"github.com/bbva/qed/gossip/member"
"github.com/bbva/qed/log"
"github.com/bbva/qed/metrics"
"github.com/bbva/qed/util"
"github.com/spf13/cobra"
)

func newAgentAuditorCommand(ctx *cmdContext, config gossip.Config, agentPreRun func(gossip.Config) gossip.Config) *cobra.Command {

auditorConfig := auditor.DefaultConfig()
func newAgentAuditorCommand(ctx context.Context, args []string) *cobra.Command {

cmd := &cobra.Command{
Use: "auditor",
Short: "Start a QED auditor",
Long: `Start a QED auditor that reacts to snapshot batches propagated by QED servers and periodically executes membership queries to verify the inclusion of events`,
PreRun: func(cmd *cobra.Command, args []string) {

log.SetLogger("QEDAuditor", ctx.logLevel)

// WARN: PersitentPreRun can't be nested and we're using it in cmd/root so inbetween preRuns
// must be curried.
config = agentPreRun(config)

auditorConfig.QEDUrls = v.GetStringSlice("agent.server_urls")
auditorConfig.PubUrls = v.GetStringSlice("agent.snapshots_store_urls")
auditorConfig.AlertsUrls = v.GetStringSlice("agent.alerts_urls")

markSliceStringRequired(auditorConfig.QEDUrls, "qedUrls")
markSliceStringRequired(auditorConfig.PubUrls, "pubUrls")
markSliceStringRequired(auditorConfig.AlertsUrls, "alertsUrls")
},
Run: func(cmd *cobra.Command, args []string) {

config.Role = member.Auditor
auditorConfig.APIKey = ctx.apiKey

auditor, err := auditor.NewAuditor(*auditorConfig)
if err != nil {
log.Fatalf("Failed to start the QED monitor: %v", err)
}
metricsServer := metrics.NewServer(config.MetricsAddr)
agent, err := gossip.NewAgent(&config, []gossip.Processor{auditor}, metricsServer)
if err != nil {
log.Fatalf("Failed to start the QED auditor: %v", err)
}

contacted, err := agent.Join(config.StartJoin)
if err != nil {
log.Fatalf("Failed to join the cluster: %v", err)
}
log.Debugf("Number of nodes contacted: %d (%v)", contacted, config.StartJoin)

defer agent.Shutdown()
util.AwaitTermSignal(agent.Leave)
},
}

f := cmd.Flags()
f.StringSliceVarP(&auditorConfig.QEDUrls, "qedUrls", "", []string{}, "Comma-delimited list of QED servers ([host]:port), through which an auditor can make queries")
f.StringSliceVarP(&auditorConfig.PubUrls, "pubUrls", "", []string{}, "Comma-delimited list of store servers ([host]:port), through which an auditor can make queries")
f.StringSliceVarP(&auditorConfig.AlertsUrls, "alertsUrls", "", []string{}, "Comma-delimited list of alerts servers ([host]:port), through which an auditor can make queries")
// Lookups
v.BindPFlag("agent.server_urls", f.Lookup("qedUrls"))
v.BindPFlag("agent.snapshots_store_urls", f.Lookup("pubUrls"))
v.BindPFlag("agent.alerts_urls", f.Lookup("alertsUrls"))
return cmd
}
Loading

0 comments on commit 40d10bb

Please sign in to comment.