From 2f4be7e35bcd775dbad27ea9c01e7ffc40c6ce23 Mon Sep 17 00:00:00 2001 From: Charlie Jones Date: Tue, 1 Oct 2024 13:54:46 -0500 Subject: [PATCH] DRY up the configs a bit --- .../log_executioner/log_executioner.go | 8 ++-- .../shell_executioner/shell_executioner.go | 20 +++++----- .../shell_executioner_test.go | 14 ++++--- .../watcher/file_watcher/file_watcher.go | 28 +++++++------ .../watcher/file_watcher/file_watcher_test.go | 14 ++++--- .../gce_metadata_watcher.go | 39 +++++++------------ .../gce_metadata_watcher_test.go | 34 +++++++++------- .../watcher/time_watcher/time_watcher.go | 19 ++++----- .../watcher/time_watcher/time_watcher_test.go | 2 +- 9 files changed, 89 insertions(+), 89 deletions(-) diff --git a/internal/goverseer/executioner/log_executioner/log_executioner.go b/internal/goverseer/executioner/log_executioner/log_executioner.go index 801b594..07eb983 100644 --- a/internal/goverseer/executioner/log_executioner/log_executioner.go +++ b/internal/goverseer/executioner/log_executioner/log_executioner.go @@ -13,20 +13,20 @@ const ( ) // LogExecutionerConfig is the configuration for a log executioner -type LogExecutionerConfig struct { +type Config struct { // Tag is a tag to add to the logs, by default it is empty Tag string } // ParseConfig parses the config for a log executioner // It validates the config, sets defaults if missing, and returns the config -func ParseConfig(config interface{}) (*LogExecutionerConfig, error) { +func ParseConfig(config interface{}) (*Config, error) { cfgMap, ok := config.(map[string]interface{}) if !ok { return nil, fmt.Errorf("invalid config") } - lec := &LogExecutionerConfig{ + lec := &Config{ Tag: DefaultTag, } @@ -40,6 +40,8 @@ func ParseConfig(config interface{}) (*LogExecutionerConfig, error) { // LogExecutioner logs the data to stdout // It implements the Executioner interface type LogExecutioner struct { + Config + // log is the logger log *slog.Logger } diff --git a/internal/goverseer/executioner/shell_executioner/shell_executioner.go b/internal/goverseer/executioner/shell_executioner/shell_executioner.go index 1e27b61..d3fb2bb 100644 --- a/internal/goverseer/executioner/shell_executioner/shell_executioner.go +++ b/internal/goverseer/executioner/shell_executioner/shell_executioner.go @@ -22,8 +22,8 @@ const ( DefaultShell = "/bin/sh" ) -// ShellExecutionerConfig is the configuration for a shell executioner -type ShellExecutionerConfig struct { +// Config is the configuration for a shell executioner +type Config struct { // Command is the command to execute Command string @@ -33,13 +33,13 @@ type ShellExecutionerConfig struct { // ParseConfig parses the config for a log executioner // It validates the config, sets defaults if missing, and returns the config -func ParseConfig(config interface{}) (*ShellExecutionerConfig, error) { +func ParseConfig(config interface{}) (*Config, error) { cfgMap, ok := config.(map[string]interface{}) if !ok { return nil, fmt.Errorf("invalid config") } - cfg := &ShellExecutionerConfig{ + cfg := &Config{ Shell: DefaultShell, } @@ -73,11 +73,7 @@ func ParseConfig(config interface{}) (*ShellExecutionerConfig, error) { // ShellExecutioner runs a shell command // It implements the Executioner interface type ShellExecutioner struct { - // Command is the command to execute - Command string - - // Shell is the shell to use when executing the command - Shell string + Config // workDir is the directory in which the ShellExecutioner will store // the command to run and the data to pass into the command @@ -112,8 +108,10 @@ func New(cfg config.Config, log *slog.Logger) (*ShellExecutioner, error) { ctx, cancel := context.WithCancel(context.Background()) return &ShellExecutioner{ - Command: pcfg.Command, - Shell: pcfg.Shell, + Config: Config{ + Command: pcfg.Command, + Shell: pcfg.Shell, + }, workDir: workDir, log: log, stop: make(chan struct{}), diff --git a/internal/goverseer/executioner/shell_executioner/shell_executioner_test.go b/internal/goverseer/executioner/shell_executioner/shell_executioner_test.go index 65bfde1..e8568a1 100644 --- a/internal/goverseer/executioner/shell_executioner/shell_executioner_test.go +++ b/internal/goverseer/executioner/shell_executioner/shell_executioner_test.go @@ -13,7 +13,7 @@ import ( ) func TestParseConfig(t *testing.T) { - var parsedConfig *ShellExecutionerConfig + var parsedConfig *Config parsedConfig, err := ParseConfig(map[string]interface{}{ "command": "echo 123", @@ -125,8 +125,10 @@ func TestShellExecutioner_Execute(t *testing.T) { tempDir, _ := os.MkdirTemp("", "goverseer-test") ctx, cancel := context.WithCancel(context.Background()) executioner := ShellExecutioner{ - Command: "echo ${GOVERSEER_DATA}", - Shell: DefaultShell, + Config: Config{ + Command: "echo ${GOVERSEER_DATA}", + Shell: DefaultShell, + }, workDir: tempDir, log: log, stop: make(chan struct{}), @@ -144,8 +146,10 @@ func TestShellExecutioner_Stop(t *testing.T) { tempDir, _ := os.MkdirTemp("", "goverseer-test") ctx, cancel := context.WithCancel(context.Background()) executioner := ShellExecutioner{ - Command: "for i in {1..1000}; do echo $i; sleep 1; done", - Shell: DefaultShell, + Config: Config{ + Command: "for i in {1..1000}; do echo $i; sleep 1; done", + Shell: DefaultShell, + }, workDir: tempDir, log: log, stop: make(chan struct{}), diff --git a/internal/goverseer/watcher/file_watcher/file_watcher.go b/internal/goverseer/watcher/file_watcher/file_watcher.go index 3c27f3c..9050925 100644 --- a/internal/goverseer/watcher/file_watcher/file_watcher.go +++ b/internal/goverseer/watcher/file_watcher/file_watcher.go @@ -15,8 +15,8 @@ const ( DefaultPollSeconds = 5 ) -// FileWatcherConfig is the configuration for a file watcher -type FileWatcherConfig struct { +// Config is the configuration for a file watcher +type Config struct { // Path is the path to the file to watch Path string @@ -26,13 +26,13 @@ type FileWatcherConfig struct { // ParseConfig parses the config for a file watcher // It validates the config, sets defaults if missing, and returns the config -func ParseConfig(config interface{}) (*FileWatcherConfig, error) { +func ParseConfig(config interface{}) (*Config, error) { cfgMap, ok := config.(map[string]interface{}) if !ok { return nil, fmt.Errorf("invalid config") } - cfg := &FileWatcherConfig{ + cfg := &Config{ PollSeconds: DefaultPollSeconds, } @@ -63,11 +63,7 @@ func ParseConfig(config interface{}) (*FileWatcherConfig, error) { // FileWatcher watches a file for changes and sends the path thru change channel type FileWatcher struct { - // Path is the path to the file to watch - Path string - - // PollInterval is the interval to poll the file for changes - PollInterval time.Duration + Config // lastValue is the last time the file was modified lastValue time.Time @@ -87,11 +83,13 @@ func New(cfg config.Config, log *slog.Logger) (*FileWatcher, error) { } return &FileWatcher{ - Path: tcfg.Path, - PollInterval: time.Duration(tcfg.PollSeconds) * time.Second, - lastValue: time.Now(), - log: log, - stop: make(chan struct{}), + Config: Config{ + Path: tcfg.Path, + PollSeconds: tcfg.PollSeconds, + }, + lastValue: time.Now(), + log: log, + stop: make(chan struct{}), }, nil } @@ -104,7 +102,7 @@ func (w *FileWatcher) Watch(changes chan interface{}) { select { case <-w.stop: return - case <-time.After(w.PollInterval): + case <-time.After(time.Duration(w.PollSeconds) * time.Second): info, err := os.Stat(w.Path) if err != nil { w.log.Error("error getting file info", diff --git a/internal/goverseer/watcher/file_watcher/file_watcher_test.go b/internal/goverseer/watcher/file_watcher/file_watcher_test.go index d54b33e..2465f1d 100644 --- a/internal/goverseer/watcher/file_watcher/file_watcher_test.go +++ b/internal/goverseer/watcher/file_watcher/file_watcher_test.go @@ -35,7 +35,7 @@ func touchFile(t *testing.T, filename string) { } func TestParseConfig(t *testing.T) { - var parsedConfig *FileWatcherConfig + var parsedConfig *Config var err error parsedConfig, err = ParseConfig(map[string]interface{}{ @@ -172,11 +172,13 @@ func TestFileWatcher_Stop(t *testing.T) { touchFile(t, testFilePath) watcher := FileWatcher{ - Path: testFilePath, - PollInterval: 1 * time.Second, - lastValue: time.Now(), - log: log, - stop: make(chan struct{}), + Config: Config{ + Path: testFilePath, + PollSeconds: 1, + }, + lastValue: time.Now(), + log: log, + stop: make(chan struct{}), } changes := make(chan interface{}) diff --git a/internal/goverseer/watcher/gce_metadata_watcher/gce_metadata_watcher.go b/internal/goverseer/watcher/gce_metadata_watcher/gce_metadata_watcher.go index d4f6aa2..0b71101 100644 --- a/internal/goverseer/watcher/gce_metadata_watcher/gce_metadata_watcher.go +++ b/internal/goverseer/watcher/gce_metadata_watcher/gce_metadata_watcher.go @@ -34,8 +34,8 @@ const ( DefaultMetadataErrorWaitSeconds = 1 ) -// GceMetadataWatcherConfig is the configuration for a GCE metadata watcher -type GceMetadataWatcherConfig struct { +// Config is the configuration for a GCE metadata watcher +type Config struct { // Source is the metadata source to watch // Valid values are 'instance' and 'project' // Default is 'instance' @@ -63,13 +63,13 @@ type GceMetadataWatcherConfig struct { // ParseConfig parses the config for the watcher // It validates the config, sets defaults if missing, and returns the config -func ParseConfig(config interface{}) (*GceMetadataWatcherConfig, error) { +func ParseConfig(config interface{}) (*Config, error) { cfgMap, ok := config.(map[string]interface{}) if !ok { return nil, fmt.Errorf("invalid config") } - cfg := &GceMetadataWatcherConfig{ + cfg := &Config{ Source: DefaultSource, Recursive: DefaultRecursive, MetadataUrl: DefaultMetadataUrl, @@ -134,18 +134,7 @@ func ParseConfig(config interface{}) (*GceMetadataWatcherConfig, error) { } type GceMetadataWatcher struct { - // Key is the key to watch in the GCE metadata - Key string - - // Recursive is whether to recurse the metadata keys - Recursive bool - - // MetadataUrl is the URL this watcher will use when reading from the GCE - // metadata server - MetadataUrl string - - // MetadataErrorWait is the time to wait before trying failed metadata request - MetadataErrorWait time.Duration + Config // lastETag is the last etag, used to compare changes lastETag string @@ -170,13 +159,15 @@ func New(cfg config.Config, log *slog.Logger) (*GceMetadataWatcher, error) { ctx, cancel := context.WithCancel(context.Background()) return &GceMetadataWatcher{ - Key: pcfg.Key, - Recursive: pcfg.Recursive, - MetadataUrl: pcfg.MetadataUrl, - MetadataErrorWait: time.Duration(pcfg.MetadataErrorWaitSeconds) * time.Second, - log: log, - ctx: ctx, - cancel: cancel, + Config: Config{ + Key: pcfg.Key, + Recursive: pcfg.Recursive, + MetadataUrl: pcfg.MetadataUrl, + MetadataErrorWaitSeconds: pcfg.MetadataErrorWaitSeconds, + }, + log: log, + ctx: ctx, + cancel: cancel, }, nil } @@ -256,7 +247,7 @@ func (w *GceMetadataWatcher) Watch(change chan interface{}) { // bit before trying again to prevent hammering the metadata server. // Since we're in a for loop here the retrys will come VERY fast without // this sleep. - time.Sleep(w.MetadataErrorWait) + time.Sleep(time.Duration(w.MetadataErrorWaitSeconds) * time.Second) continue } diff --git a/internal/goverseer/watcher/gce_metadata_watcher/gce_metadata_watcher_test.go b/internal/goverseer/watcher/gce_metadata_watcher/gce_metadata_watcher_test.go index 427b34c..9c79d40 100644 --- a/internal/goverseer/watcher/gce_metadata_watcher/gce_metadata_watcher_test.go +++ b/internal/goverseer/watcher/gce_metadata_watcher/gce_metadata_watcher_test.go @@ -17,7 +17,7 @@ import ( // TestParseConfig tests the ParseConfig function func TestParseConfig(t *testing.T) { - var parsedConfig *GceMetadataWatcherConfig + var parsedConfig *Config testKey := "valid" parsedConfig, err := ParseConfig(map[string]interface{}{ @@ -203,13 +203,15 @@ func TestGceMetadataWatcher_Watch(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) watcher := GceMetadataWatcher{ - Key: "test", - Recursive: true, - MetadataUrl: mockServer.URL, - MetadataErrorWait: 1 * time.Second, - log: log, - ctx: ctx, - cancel: cancel, + Config: Config{ + Key: "test", + Recursive: true, + MetadataUrl: mockServer.URL, + MetadataErrorWaitSeconds: 1, + }, + log: log, + ctx: ctx, + cancel: cancel, } changes := make(chan interface{}) @@ -253,13 +255,15 @@ func TestGceMetadataWatcher_Stop(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) watcher := GceMetadataWatcher{ - Key: "test", - Recursive: true, - MetadataUrl: mockServer.URL, - MetadataErrorWait: 1 * time.Second, - log: log, - ctx: ctx, - cancel: cancel, + Config: Config{ + Key: "test", + Recursive: true, + MetadataUrl: mockServer.URL, + MetadataErrorWaitSeconds: 1, + }, + log: log, + ctx: ctx, + cancel: cancel, } changes := make(chan interface{}) diff --git a/internal/goverseer/watcher/time_watcher/time_watcher.go b/internal/goverseer/watcher/time_watcher/time_watcher.go index bf0d5d8..2555d5d 100644 --- a/internal/goverseer/watcher/time_watcher/time_watcher.go +++ b/internal/goverseer/watcher/time_watcher/time_watcher.go @@ -14,20 +14,20 @@ const ( ) // TimeWatcherConfig is the configuration for a time watcher -type TimeWatcherConfig struct { +type Config struct { // PollSeconds is the number of seconds to wait between ticks PollSeconds int } // ParseConfig parses the config for a time watcher // It validates the config, sets defaults if missing, and returns the config -func ParseConfig(config interface{}) (*TimeWatcherConfig, error) { +func ParseConfig(config interface{}) (*Config, error) { cfgMap, ok := config.(map[string]interface{}) if !ok { return nil, fmt.Errorf("invalid config") } - twc := &TimeWatcherConfig{ + twc := &Config{ PollSeconds: DefaultPollSeconds, } @@ -45,8 +45,7 @@ func ParseConfig(config interface{}) (*TimeWatcherConfig, error) { // TimeWatcher is a time watcher that ticks at a regular interval type TimeWatcher struct { - // PollInterval is the interval to to wait between ticks - PollInterval time.Duration + Config // log is the logger log *slog.Logger @@ -63,9 +62,11 @@ func New(cfg config.Config, log *slog.Logger) (*TimeWatcher, error) { } return &TimeWatcher{ - PollInterval: time.Duration(tcfg.PollSeconds) * time.Second, - log: log, - stop: make(chan struct{}), + Config: Config{ + PollSeconds: tcfg.PollSeconds, + }, + log: log, + stop: make(chan struct{}), }, nil } @@ -77,7 +78,7 @@ func (w *TimeWatcher) Watch(change chan interface{}) { select { case <-w.stop: return - case value := <-time.After(w.PollInterval): + case value := <-time.After(time.Duration(w.PollSeconds) * time.Second): w.log.Info("time watcher tick", slog.Time("value", value)) change <- value } diff --git a/internal/goverseer/watcher/time_watcher/time_watcher_test.go b/internal/goverseer/watcher/time_watcher/time_watcher_test.go index 64b7541..7247b1a 100644 --- a/internal/goverseer/watcher/time_watcher/time_watcher_test.go +++ b/internal/goverseer/watcher/time_watcher/time_watcher_test.go @@ -67,7 +67,7 @@ func TestTimeWatcher_Watch(t *testing.T) { // Create a new TimeWatcher watcher, err := New(cfg, log) assert.NoError(t, err) - t.Log(watcher.PollInterval) + t.Log(watcher.PollSeconds) // Start watching the file wg.Add(1) go func() {