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

Refactor Nomad policy parsing and add tests #114

Merged
merged 3 commits into from
May 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
## UNRELEASED

__BACKWARDS INCOMPATIBILITIES:__
* agent: configuration `scan_interval` renamed to `default_evaluation_interval` [[GH-114](https://github.com/hashicorp/nomad-autoscaler/pull/114)]

FEATURES:
* agent: allow policies to specify `evaluation_interval` [[GH-30](https://github.com/hashicorp/nomad-autoscaler/pull/30)]

Expand Down
5 changes: 4 additions & 1 deletion agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ func (a *Agent) Run(ctx context.Context) error {
a.healthServer = healthServer
go a.healthServer.run()

source := nomadpolicy.NewNomadSource(a.logger, a.nomadClient)
sourceConfig := &nomadpolicy.SourceConfig{
DefaultEvaluationInterval: a.config.DefaultEvaluationInterval,
}
source := nomadpolicy.NewNomadSource(a.logger, a.nomadClient, sourceConfig)
manager := policy.NewManager(a.logger, source, a.pluginManager)

policyEvalCh := make(chan *policy.Evaluation, 10)
Expand Down
30 changes: 15 additions & 15 deletions agent/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ type Agent struct {
// PluginDir is the directory that holds the autoscaler plugin binaries.
PluginDir string `hcl:"plugin_dir,optional"`

// ScanInterval is the time duration interval at which the autoscaler runs
// evaluations.
ScanInterval time.Duration
ScanIntervalHCL string `hcl:"scan_interval,optional" json:"-"`
// DefaultEvaluationInterval is the time duration interval used when
// `evaluation_interval` is not defined in a policy.
DefaultEvaluationInterval time.Duration
DefaultEvaluationIntervalHCL string `hcl:"default_evaluation_interval,optional" json:"-"`

// HTTP is the configuration used to setup the HTTP health server.
HTTP *HTTP `hcl:"http,block"`
Expand Down Expand Up @@ -124,9 +124,9 @@ const (
// defaultHTTPBindPort is the default port used for the HTTP health server.
defaultHTTPBindPort = 8080

// defaultScanInterval is the default value for the ScaInterval in nano
// seconds.
defaultScanInterval = time.Duration(10000000000)
// defaultEvaluationInterval is the default value for the
// DefaultEvaluationInterval in nano seconds.
defaultEvaluationInterval = time.Duration(10000000000)

// defaultPluginDirSuffix is the suffix appended to the PWD when building
// the PluginDir default value.
Expand All @@ -152,9 +152,9 @@ func Default() (*Agent, error) {
}

return &Agent{
LogLevel: defaultLogLevel,
PluginDir: pwd + defaultPluginDirSuffix,
ScanInterval: defaultScanInterval,
LogLevel: defaultLogLevel,
PluginDir: pwd + defaultPluginDirSuffix,
DefaultEvaluationInterval: defaultEvaluationInterval,
HTTP: &HTTP{
BindAddress: defaultHTTPBindAddress,
BindPort: defaultHTTPBindPort,
Expand All @@ -181,8 +181,8 @@ func (a *Agent) Merge(b *Agent) *Agent {
if b.PluginDir != "" {
result.PluginDir = b.PluginDir
}
if b.ScanInterval != 0 {
result.ScanInterval = b.ScanInterval
if b.DefaultEvaluationInterval != 0 {
result.DefaultEvaluationInterval = b.DefaultEvaluationInterval
}

if b.HTTP != nil {
Expand Down Expand Up @@ -349,12 +349,12 @@ func parseFile(file string, cfg *Agent) error {
return err
}

if cfg.ScanIntervalHCL != "" {
d, err := time.ParseDuration(cfg.ScanIntervalHCL)
if cfg.DefaultEvaluationIntervalHCL != "" {
d, err := time.ParseDuration(cfg.DefaultEvaluationIntervalHCL)
if err != nil {
return err
}
cfg.ScanInterval = d
cfg.DefaultEvaluationInterval = d
}
return nil
}
Expand Down
36 changes: 18 additions & 18 deletions agent/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func Test_Default(t *testing.T) {
assert.False(t, def.LogJson)
assert.Equal(t, def.LogLevel, "info")
assert.True(t, strings.HasSuffix(def.PluginDir, "/plugins"))
assert.Equal(t, def.ScanInterval, time.Duration(10000000000))
assert.Equal(t, def.DefaultEvaluationInterval, time.Duration(10000000000))
assert.Equal(t, def.Nomad.Address, "http://127.0.0.1:4646")
assert.Equal(t, "127.0.0.1", def.HTTP.BindAddress)
assert.Equal(t, 8080, def.HTTP.BindPort)
Expand All @@ -31,8 +31,8 @@ func TestAgent_Merge(t *testing.T) {
assert.Nil(t, err)

cfg1 := &Agent{
PluginDir: "/opt/nomad-autoscaler/plugins",
ScanInterval: 5000000000,
PluginDir: "/opt/nomad-autoscaler/plugins",
DefaultEvaluationInterval: 5000000000,
HTTP: &HTTP{
BindAddress: "scaler.nomad",
},
Expand All @@ -49,10 +49,10 @@ func TestAgent_Merge(t *testing.T) {
}

cfg2 := &Agent{
LogLevel: "trace",
LogJson: true,
PluginDir: "/var/lib/nomad-autoscaler/plugins",
ScanInterval: 10000000000,
LogLevel: "trace",
LogJson: true,
PluginDir: "/var/lib/nomad-autoscaler/plugins",
DefaultEvaluationInterval: 10000000000,
HTTP: &HTTP{
BindPort: 4646,
},
Expand Down Expand Up @@ -90,10 +90,10 @@ func TestAgent_Merge(t *testing.T) {
}

expectedResult := &Agent{
LogLevel: "trace",
LogJson: true,
PluginDir: "/var/lib/nomad-autoscaler/plugins",
ScanInterval: 10000000000,
LogLevel: "trace",
LogJson: true,
PluginDir: "/var/lib/nomad-autoscaler/plugins",
DefaultEvaluationInterval: 10000000000,
HTTP: &HTTP{
BindAddress: "scaler.nomad",
BindPort: 4646,
Expand Down Expand Up @@ -149,7 +149,7 @@ func TestAgent_Merge(t *testing.T) {
assert.Equal(t, expectedResult.LogLevel, actualResult.LogLevel)
assert.Equal(t, expectedResult.Nomad, actualResult.Nomad)
assert.Equal(t, expectedResult.PluginDir, actualResult.PluginDir)
assert.Equal(t, expectedResult.ScanInterval, actualResult.ScanInterval)
assert.Equal(t, expectedResult.DefaultEvaluationInterval, actualResult.DefaultEvaluationInterval)
assert.ElementsMatch(t, expectedResult.APMs, actualResult.APMs)
assert.ElementsMatch(t, expectedResult.Targets, actualResult.Targets)
assert.ElementsMatch(t, expectedResult.Strategies, actualResult.Strategies)
Expand Down Expand Up @@ -181,11 +181,11 @@ func TestAgent_parseFile(t *testing.T) {
// Write some valid content, and ensure this is read and parsed.
cfg := &Agent{}

if _, err := fh.WriteString("scan_interval = \"10s\"\nplugin_dir = \"/opt/nomad-autoscaler/plugins\""); err != nil {
if _, err := fh.WriteString("default_evaluation_interval = \"10s\"\nplugin_dir = \"/opt/nomad-autoscaler/plugins\""); err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(t, parseFile(fh.Name(), cfg))
assert.Equal(t, time.Duration(10000000000), cfg.ScanInterval)
assert.Equal(t, time.Duration(10000000000), cfg.DefaultEvaluationInterval)
assert.Equal(t, "/opt/nomad-autoscaler/plugins", cfg.PluginDir)
}

Expand All @@ -198,13 +198,13 @@ func TestConfig_Load(t *testing.T) {
assert.Nil(t, err)
defer os.Remove(fh.Name())

_, err = fh.WriteString("scan_interval = \"10s\"")
_, err = fh.WriteString("default_evaluation_interval = \"10s\"")
assert.Nil(t, err)

// Works on a config file
cfg, err := Load(fh.Name())
assert.Nil(t, err)
assert.Equal(t, time.Duration(10000000000), cfg.ScanInterval)
assert.Equal(t, time.Duration(10000000000), cfg.DefaultEvaluationInterval)

dir, err := ioutil.TempDir("", "nomad-autoscaler")
assert.Nil(t, err)
Expand Down Expand Up @@ -234,7 +234,7 @@ func TestAgent_loadDir(t *testing.T) {
assert.Equal(t, config, &Agent{})

file1 := filepath.Join(dir, "config1.hcl")
assert.Nil(t, ioutil.WriteFile(file1, []byte("scan_interval = \"10s\""), 0600))
assert.Nil(t, ioutil.WriteFile(file1, []byte("default_evaluation_interval = \"10s\""), 0600))

file2 := filepath.Join(dir, "config2.hcl")
assert.Nil(t, ioutil.WriteFile(file2, []byte("plugin_dir = \"/opt/nomad-autoscaler/plugins\""), 0600))
Expand All @@ -252,7 +252,7 @@ func TestAgent_loadDir(t *testing.T) {
// We should now be able to load as all the configs are valid.
cfg, err := loadDir(dir)
assert.Nil(t, err)
assert.Equal(t, time.Duration(10000000000), cfg.ScanInterval)
assert.Equal(t, time.Duration(10000000000), cfg.DefaultEvaluationInterval)
assert.Equal(t, "/opt/nomad-autoscaler/plugins", cfg.PluginDir)
}

Expand Down
4 changes: 2 additions & 2 deletions command/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ Nomad Options:

-nomad-skip-verify
Do not verify TLS certificates. This is strongly discouraged.

`
return strings.TrimSpace(helpText)
}
Expand Down Expand Up @@ -165,7 +165,7 @@ func (c *AgentCommand) readConfig() *config.Agent {
flags.BoolVar(&cmdConfig.LogJson, "log-json", false, "")
flags.StringVar(&cmdConfig.PluginDir, "plugin-dir", "", "")
flags.Var((flaghelper.FuncDurationVar)(func(d time.Duration) error {
cmdConfig.ScanInterval = d
cmdConfig.DefaultEvaluationInterval = d
return nil
}), "scan-interval", "")

Expand Down
2 changes: 1 addition & 1 deletion docs/agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ As each file is processed, its contents are merged into the existing configurati
* `log_level` `(string: "INFO")` - Specify the verbosity level of Nomad Autoscaler's logs. Valid values include `DEBUG`, `INFO`, and `WARN`, in decreasing order of verbosity.
* `log_json` `(bool: false)` - Output logs in a JSON format.
* `plugin_dir` `(string: "./plugins")` - The plugin directory used to discover Nomad Autoscaler plugins.
* `scan_interval` `(duration: "10s")` - The time to wait between Nomad Autoscaler evaluations.
* `default_evaluation_interval` `(duration: "10s")` - The default time to use when a policy doesn't specify an `evaluation_interval`.

## `http` Block
The `http` block configures the Nomad Autoscaler's HTTP health endpoint.
Expand Down
Loading