Skip to content

Commit

Permalink
Add more configuration automated tests
Browse files Browse the repository at this point in the history
Signed-off-by: Marc Khouzam <marc.khouzam@gmail.com>
  • Loading branch information
marckhouzam committed Jan 6, 2019
1 parent 36b0740 commit 5be4241
Show file tree
Hide file tree
Showing 4 changed files with 345 additions and 25 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
custom-prometheus-exporter
.vscode
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,21 +94,21 @@ You can obtain a list of main endpoints by navigating to ```http://localhost:953
The format of the YAML configuration is the following:

```
name: string # A name for the exporter
port: int # The TCP port serving the metrics
endpoint: string # The endpoint serving the metrics
metrics: # An array of metrics to be generated
- name: string # The published name of the metric
help: string # The published help message of the metric
type: gauge # Only Prometheus "gauge" is currently supported
executions: # An array of executions to generate the metric
- type: sh # Only sh is currently supported
command: string # An sh command that will be run exactly as-specified
name: string # A name for the exporter - MANDATORY
port: int # The TCP port serving the metrics - MANDATORY
endpoint: string # The endpoint serving the metrics - OPTIONAL, defaults to /metrics
metrics: # An array of metrics to be generated - MANDATORY
- name: string # The published name of the metric - MANDATORY
help: string # The published help message of the metric - MANDATORY
type: gauge # Only Prometheus "gauge" is currently supported - MANDATORY
executions: # An array of executions to generate the metric - MANDATORY
- type: sh # Only sh is currently supported - MANDATORY
command: string # An sh command that will be run exactly as-specified - MANDATORY
# Shell pipes (|) are allowed.
# The result of the command must be the single
# integer to be used in the metric
labels: map(string, string)
# A map of label to value which qualifies an instance
# A map of label to value which qualifies an instance - MANDATORY
# of the metric
```

Expand Down
82 changes: 75 additions & 7 deletions configparser/configparser.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
package configparser

import (
"errors"
"io/ioutil"
"os"
"strings"

yaml "gopkg.in/yaml.v2"
)

const (
defaultEndpoint = "/metrics"
)

// Config is the structure that holds the configuration of the custom-prometheus-exporter
// as defined by the user.
type Config struct {
Expand Down Expand Up @@ -42,12 +48,74 @@ type MetricsConfig struct {
}
}

func verifyExporterConfig(config ExporterConfig) error {
// TODO check that fields that have limited possible values
// respect those values e.g,
// ExecutionType must be sh,
// Endpoint must start with /
// MetricType is only gauge (for now)
func verifyExporterConfig(config *ExporterConfig) error {
// Make sure 'name' is present
if config.Name == "" {
return errors.New("Missing field 'name' in top configuration")
}

// Make sure 'port' is present
if config.Port == 0 {
return errors.New("Missing field 'port' in top configuration")
}

// If 'endpoint' is absent, use the the default endpoint
if config.Endpoint == "" {
config.Endpoint = defaultEndpoint
return nil
}

// Add '/' at the start of 'endpoint' if it is missing
if config.Endpoint[0] != '/' {
config.Endpoint = strings.Join([]string{"/", config.Endpoint}, "")
return nil
}

// Make sure 'metrics' is present
if config.Metrics == nil || len(config.Metrics) == 0 {
return errors.New("Missing field 'metrics' in top configuration")
}

for i, metric := range config.Metrics {
if metric.Name == "" {
return errors.New("Missing field 'name' in 'metrics' configuration of metric " + string(i))
}

if metric.Help == "" {
return errors.New("Missing field 'help' in 'metrics' configuration of metric " + string(i))
}

if metric.MetricType == "" {
return errors.New("Missing field 'type' in 'metrics' configuration of metric " + string(i))
}

if metric.MetricType != "gauge" {
return errors.New("Wrong value for field 'type' in 'metrics' configuration of metric " + string(i) +
". Supported values are: gauge")
}

// Make sure 'executions' is present
if metric.Executions == nil || len(metric.Executions) == 0 {
return errors.New("Missing field 'executions' in 'metrics' configuration of metric " + string(i))
}

for j, execution := range metric.Executions {
if execution.ExecutionType == "" {
return errors.New("Missing field 'type' in 'executions' configuration of metric " + string(i) +
" and execution " + string(j))
}

if execution.ExecutionType != "sh" {
return errors.New("Wrong value for field 'type' in 'executions' configuration of metric " + string(i) +
" and execution " + string(j) + ". Supported values are: sh")
}

if execution.Command == "" {
return errors.New("Missing field 'command' in 'executions' configuration of metric " + string(i) +
" and execution " + string(j))
}
}
}
return nil
}

Expand Down Expand Up @@ -76,7 +144,7 @@ func (c *Config) ParseConfig() error {
}

// Do some sanity checks on the configuration
if err = verifyExporterConfig(newExporter); err != nil {
if err = verifyExporterConfig(&newExporter); err != nil {
return err
}

Expand Down
Loading

0 comments on commit 5be4241

Please sign in to comment.