|
|
Package conf contains definition of data type named ConfigStruct that
represents configuration of the mock service. This package also contains
function named LoadConfiguration that can be used to load configuration from
provided configuration file and/or from environment variables. Additionally
two specific functions named GetServerConfiguration and
GetGroupsConfiguration are to be used to return specific configuration
options.
Generated documentation is available at:
https://godoc.org/github.com/RedHatInsights/insights-results-aggregator-mock/conf
Documentation in literate-programming-style is available at:
https://redhatinsights.github.io/insights-results-aggregator-mock/packages/conf/configuration.html
|
package conf
import (
"bytes"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/BurntSushi/toml"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
"github.com/RedHatInsights/insights-results-aggregator-mock/groups"
"github.com/RedHatInsights/insights-results-aggregator-mock/server"
)
const (
configFileEnvVariableName = "INSIGHTS_RESULTS_AGGREGATOR_MOCK_CONFIG_FILE"
)
|
PathsConfiguration is data structure that represents path to directory
containing files with mock data.
|
type PathsConfiguration struct {
MockDataPath string `mapstructure:"mock_data" toml:"mock_data"`
}
|
ConfigStruct is a structure holding the whole service configuration
|
type ConfigStruct struct {
Server server . Configuration `mapstructure:"server" toml:"server"`
Groups groups . Configuration `mapstructure:"groups" toml:"groups"`
Paths PathsConfiguration `mapstructure:"paths" toml:"paths"`
}
|
Config has exactly the same structure as *.toml file
|
var Config ConfigStruct
|
LoadConfiguration loads configuration from defaultConfigFile, file set in
configFileEnvVariableName or from env
|
func LoadConfiguration ( defaultConfigFile string ) ( ConfigStruct , error ) {
configFile , specified := os . LookupEnv ( configFileEnvVariableName )
if specified {
|
we need to separate the directory name and filename without
extension
|
directory , basename := filepath . Split ( configFile )
file := strings . TrimSuffix ( basename , filepath . Ext ( basename ) )
|
parse the configuration
|
viper . SetConfigName ( file )
viper . AddConfigPath ( directory )
} else {
|
parse the configuration
|
viper . SetConfigName ( defaultConfigFile )
viper . AddConfigPath ( "." )
}
err := viper . ReadInConfig ( )
if _ , isNotFoundError := err . ( viper . ConfigFileNotFoundError ) ; ! specified && isNotFoundError {
|
viper is not smart enough to understand the structure of
config by itself
|
fakeTomlConfigWriter := new ( bytes . Buffer )
err := toml . NewEncoder ( fakeTomlConfigWriter ) . Encode ( Config )
if err != nil {
return Config , err
}
fakeTomlConfig := fakeTomlConfigWriter . String ( )
viper . SetConfigType ( "toml" )
err = viper . ReadConfig ( strings . NewReader ( fakeTomlConfig ) )
if err != nil {
return Config , err
}
} else if err != nil {
return Config , fmt . Errorf ( "fatal error config file: %s" , err )
}
|
override config from env if there's variable in env
|
const envPrefix = "INSIGHTS_RESULTS_AGGREGATOR_MOCK_"
viper . AutomaticEnv ( )
viper . SetEnvPrefix ( envPrefix )
viper . SetEnvKeyReplacer ( strings . NewReplacer ( "-" , "_" , "." , "__" ) )
err = viper . Unmarshal ( & Config )
return Config , err
}
|
GetServerConfiguration returns server configuration
|
func GetServerConfiguration ( ) server . Configuration {
err := checkIfFileExists ( Config . Server . APISpecFile )
if err != nil {
log . Fatal ( ) . Err ( err ) . Msg ( "All customer facing APIs MUST serve the current OpenAPI specification" )
}
return Config . Server
}
|
GetGroupsConfiguration returns groups configuration
|
func GetGroupsConfiguration ( ) groups . Configuration {
err := checkIfFileExists ( Config . Groups . ConfigPath )
if err != nil {
log . Fatal ( ) . Err ( err ) . Msg ( "The groups configuration file is not defined" )
}
return Config . Groups
}
|
checkIfFileExists returns nil if path doesn't exist or isn't a file,
otherwise it returns corresponding error
|
func checkIfFileExists ( path string ) error {
if len ( path ) == 0 {
return fmt . Errorf ( "Empty path provided" )
}
fileInfo , err := os . Stat ( path )
if os . IsNotExist ( err ) {
return fmt . Errorf ( "The following file path does not exist. Path: '%v'" , path )
} else if err != nil {
return err
}
if fileMode := fileInfo . Mode ( ) ; ! fileMode . IsRegular ( ) {
return fmt . Errorf ( "The following file path is not a regular file. Path: '%v'" , path )
}
return nil
}
|