From 7ff14a833edaa554477370250ffa1ca2e1633a57 Mon Sep 17 00:00:00 2001 From: Tomasz Janiszewski Date: Thu, 23 Nov 2017 13:37:49 +0100 Subject: [PATCH] Inject hooks to executor constructor. Move creation and configuration of hooks to main function. This will enable users to simply replace main.go with their own implementation to use custom hooks. Hooks configuration is indepenedent from Executor configuration so there is no need to keep it in Executor. --- cmd/executor/main.go | 27 ++++++++++++++++++++++++++- executor.go | 32 +++----------------------------- hook/consul/hook.go | 10 ++++++++-- hook/vaas/hook.go | 18 ++++++++++++++---- 4 files changed, 51 insertions(+), 36 deletions(-) diff --git a/cmd/executor/main.go b/cmd/executor/main.go index 923cfb62..985b0d0b 100644 --- a/cmd/executor/main.go +++ b/cmd/executor/main.go @@ -11,6 +11,9 @@ import ( "github.com/mesos/mesos-go/api/v1/lib/executor/config" "github.com/allegro/mesos-executor" + "github.com/allegro/mesos-executor/hook" + "github.com/allegro/mesos-executor/hook/consul" + "github.com/allegro/mesos-executor/hook/vaas" "github.com/allegro/mesos-executor/runenv" ) @@ -75,6 +78,28 @@ func initSentry(config executor.Config) error { return nil } +func createHooks() []hook.Hook { + var consulConfig consul.Config + if err := envconfig.Process(environmentPrefix, &consulConfig); err != nil { + log.WithError(err).Fatal("Failed to load Consul hook configuration") + } + consulHook, err := consul.NewHook(consulConfig) + if err != nil { + log.WithError(err).Fatalf("Error loading Consul hook %s", err) + } + + var vaasConfig vaas.Config + if err := envconfig.Process(environmentPrefix, &vaasConfig); err != nil { + log.WithError(err).Fatal("Failed to load VaaS hook configuration") + } + vaasHook, err := vaas.NewHook(vaasConfig) + if err != nil { + log.WithError(err).Fatalf("Error loading VaaS service hook %s", err) + } + + return []hook.Hook{consulHook, vaasHook} +} + func main() { log.Infof("Allegro Mesos Executor (version: %s)", Version) cfg, err := config.FromEnv() @@ -82,7 +107,7 @@ func main() { log.WithError(err).Fatal("Failed to load Mesos configuration") } Config.MesosConfig = cfg - exec := executor.NewExecutor(Config) + exec := executor.NewExecutor(Config, createHooks()...) if err := exec.Start(); err != nil { log.WithError(err).Fatal("Executor exited with error") } diff --git a/executor.go b/executor.go index d6c7fc8c..027a66bd 100644 --- a/executor.go +++ b/executor.go @@ -21,8 +21,6 @@ import ( "github.com/mesos/mesos-go/api/v1/lib/httpcli" "github.com/allegro/mesos-executor/hook" - "github.com/allegro/mesos-executor/hook/consul" - "github.com/allegro/mesos-executor/hook/vaas" "github.com/allegro/mesos-executor/mesosutils" "github.com/allegro/mesos-executor/state" ) @@ -47,16 +45,6 @@ type Config struct { // Mesos framework configuration MesosConfig config.Config `ignore:"true"` - // Varnish as a Service API url - VaasAPIHost string `default:"" envconfig:"vaas_host"` - // Varnish as a Service username - VaasAPIUsername string `default:"" envconfig:"vaas_username"` - // Varnish as a Service access token - VaasAPIKey string `default:"" envconfig:"vaas_token"` - - // Consul ACL Token - ConsulToken string `default:"" envconfig:"consul_token"` - // SentryDSN is an address used for sending logs to Sentry SentryDSN string `split_words:"true"` @@ -124,8 +112,8 @@ const ( Launch ) -// NewExecutor creates new instance of executor configured with by `cfg`. -func NewExecutor(cfg Config) *Executor { +// NewExecutor creates new instance of executor configured with by `cfg` with hooks +func NewExecutor(cfg Config, hooks ...hook.Hook) *Executor { log.Info("Initializing executor with following configuration:") log.Infof("AgentEndpoint = %s", cfg.MesosConfig.AgentEndpoint) @@ -145,27 +133,13 @@ func NewExecutor(cfg Config) *Executor { context: ctx, contextCancel: ctxCancel, events: make(chan Event), - hookManager: newHookManager(cfg), + hookManager: hook.Manager{hooks}, stateUpdater: state.BufferedUpdater(cfg.MesosConfig, cfg.StateUpdateBufferSize), clock: systemClock{}, random: newRandom(), } } -func newHookManager(config Config) hook.Manager { - vaasHook, err := vaas.NewHook(config.VaasAPIHost, config.VaasAPIUsername, config.VaasAPIKey) - if err != nil { - log.WithError(err).Fatalf("Error loading VaaS service hook %s", err) - } - - consulHook, err := consul.NewHook(config.ConsulToken) - if err != nil { - log.WithError(err).Fatalf("Error loading Consul hook %s", err) - } - - return hook.Manager{Hooks: []hook.Hook{vaasHook, consulHook}} -} - // Start registers executor in Mesos agent and waits for events from it. func (e *Executor) Start() error { diff --git a/hook/consul/hook.go b/hook/consul/hook.go index 36f2e625..b781f1cd 100644 --- a/hook/consul/hook.go +++ b/hook/consul/hook.go @@ -37,6 +37,12 @@ type Hook struct { serviceInstances []instance } +// Config is Consul hook configuration settable from environment +type Config struct { + // Consul ACL Token + ConsulToken string `default:"" envconfig:"consul_token"` +} + // HandleEvent calls appropriate hook functions that correspond to supported // event types. Unsupported events are ignored. func (h *Hook) HandleEvent(event hook.Event) error { @@ -206,9 +212,9 @@ func generateURL(info *mesos.HealthCheck_HTTPCheckInfo, port int) string { } // NewHook creates new Consul hook that is responsible for graceful Consul deregistration. -func NewHook(token string) (hook.Hook, error) { +func NewHook(cfg Config) (hook.Hook, error) { config := api.DefaultConfig() - config.Token = token + config.Token = cfg.ConsulToken client, err := api.NewClient(config) if err != nil { return nil, err diff --git a/hook/vaas/hook.go b/hook/vaas/hook.go index 01d57395..7b75c37f 100644 --- a/hook/vaas/hook.go +++ b/hook/vaas/hook.go @@ -31,6 +31,16 @@ type Hook struct { client Client } +// Config is Varnish configuration settable from environment +type Config struct { + // Varnish as a Service API url + VaasAPIHost string `default:"" envconfig:"vaas_host"` + // Varnish as a Service username + VaasAPIUsername string `default:"" envconfig:"vaas_username"` + // Varnish as a Service access token + VaasAPIKey string `default:"" envconfig:"vaas_token"` +} + // RegisterBackend adds new backend to VaaS if it does not exist. func (sh *Hook) RegisterBackend(taskInfo mesos.TaskInfo) error { handyTaskInfo := mesosutils.TaskInfo{TaskInfo: taskInfo} @@ -200,12 +210,12 @@ func (sh *Hook) HandleEvent(event hook.Event) error { } // NewHook returns new instance of Hook. -func NewHook(apiHost string, apiUsername string, apiKey string) (*Hook, error) { +func NewHook(cfg Config) (*Hook, error) { return &Hook{ client: NewClient( - apiHost, - apiUsername, - apiKey, + cfg.VaasAPIHost, + cfg.VaasAPIUsername, + cfg.VaasAPIKey, ), }, nil }