metricator/internal/configuration/config.go

96 lines
2.4 KiB
Go

package configuration
import (
"errors"
"flag"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"time"
"gopkg.in/yaml.v2"
)
var (
ErrConfigurationFileDoesNotExist = errors.New("configuration file does not exist")
ErrConfigurationFilePathUndefined = errors.New("configuration file path wasn't provided")
)
// Config is an application's configuration.
type Config struct {
configPath string
// Applications describes configuration for remote application's endpoints.
// Key is an application's name.
Applications map[string]struct {
// Endpoint is a remote application endpoint which should give us metrics
// in Prometheus format.
Endpoint string
// Headers is a list of headers that should be added to metrics request.
Headers map[string]string
// TimeBetweenRequests is a minimal amount of time which should pass
// between requests.
TimeBetweenRequests time.Duration
}
// Datastore describes data storage configuration.
Datastore struct {
// ValidTimeout is a timeout for which every data entry will be considered
// as valid. After that timeout if value wasn't updated it will be considered
// as invalid and purged from memory.
ValidTimeout time.Duration `yaml:"valid_timeout"`
} `yaml:"datastore"`
}
// NewConfig returns new configuration.
func NewConfig() *Config {
c := &Config{}
c.initialize()
return c
}
// Initializes configuration.
func (c *Config) initialize() {
flag.StringVar(&c.configPath, "config", "", "Configuration file path.")
}
// Parse parses configuration.
func (c *Config) Parse() error {
if c.configPath == "" {
return ErrConfigurationFilePathUndefined
}
if strings.HasPrefix(c.configPath, "~") {
userDir, err := os.UserHomeDir()
if err != nil {
return fmt.Errorf("%s: %w", "file path normalization: getting user's home directory", err)
}
c.configPath = strings.Replace(c.configPath, "~", userDir, 1)
}
cfgPath, err := filepath.Abs(c.configPath)
if err != nil {
return fmt.Errorf("%s: %w", "file path normalization: getting absolute path", err)
}
c.configPath = cfgPath
if c.configPath == "" {
return fmt.Errorf("%s: %w", "file path normalization", ErrConfigurationFilePathUndefined)
}
fileData, err := ioutil.ReadFile(c.configPath)
if err != nil {
return fmt.Errorf("%s: %w", "configuration file read", err)
}
err = yaml.Unmarshal(fileData, c)
if err != nil {
return fmt.Errorf("%s: %w", "configuration file parsing", err)
}
return nil
}