|
|
Package conf contains definition of data type named ConfigStruct that
represents configuration of Content 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
several specific functions named GetServerConfiguration, GetGroupsConfiguration,
GetContentPathConfiguration, GetMetricsConfiguration, GetLoggingConfiguration and
GetCloudWatchConfiguration are to be used to return specific
configuration options.
Generated documentation is available at:
https://godoc.org/github.com/RedHatInsights/insights-content-service/conf
Documentation in literate-programming-style is available at:
https://redhatinsights.github.io/insights-content-service/packages/conf/configuration.html
|
package conf
import (
"bytes"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/BurntSushi/toml"
"github.com/RedHatInsights/insights-operator-utils/logger"
clowder "github.com/redhatinsights/app-common-go/pkg/api/v1"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
"github.com/RedHatInsights/insights-content-service/groups"
"github.com/RedHatInsights/insights-content-service/server"
)
const (
configFileEnvVariableName = "INSIGHTS_CONTENT_SERVICE_CONFIG_FILE"
defaultContentPath = "/rules-content"
)
|
MetricsConf contains the metrics configuration
|
type MetricsConf struct {
Namespace string `mapstructure:"namespace" toml:"namespace"`
}
|
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"`
Content struct {
ContentPath string `mapstructure:"path" toml:"path"`
} `mapstructure:"content" toml:"content"`
Metrics MetricsConf `mapstructure:"metrics" toml:"metrics"`
Logging logger . LoggingConfiguration `mapstructure:"logging" toml:"logging"`
CloudWatch logger . CloudWatchConfiguration `mapstructure:"cloudwatch" toml:"cloudwatch"`
SentryLoggingConf logger . SentryLoggingConfiguration `mapstructure:"sentry" toml:"sentry"`
KafkaZerologConf logger . KafkaZerologConfiguration `mapstructure:"kafka_zerolog" toml:"kafka_zerolog"`
}
|
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 ) 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 err
}
fakeTomlConfig := fakeTomlConfigWriter . String ( )
viper . SetConfigType ( "toml" )
err = viper . ReadConfig ( strings . NewReader ( fakeTomlConfig ) )
if err != nil {
return err
}
} else if err != nil {
return fmt . Errorf ( "fatal error config file: %s" , err )
}
|
override config from env if there's variable in env
|
const envPrefix = "INSIGHTS_CONTENT_SERVICE_"
viper . AutomaticEnv ( )
viper . SetEnvPrefix ( envPrefix )
viper . SetEnvKeyReplacer ( strings . NewReplacer ( "-" , "_" , "." , "__" ) )
err = viper . Unmarshal ( & Config )
if err != nil {
return fmt . Errorf ( "fatal - can not unmarshal configuration: %s" , err )
}
if clowder . IsClowderEnabled ( ) {
|
can not use Zerolog at this moment!
|
fmt . Println ( "Clowder is enabled" )
|
TODO: insert logic to replace SELECTED configuration variables
|
} else {
|
can not use Zerolog at this moment!
|
fmt . Println ( "Clowder is disabled" )
}
|
everything's should be ok
|
return nil
}
|
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 . Error ( ) . Err ( err ) . Msg ( "The groups configuration file is not defined" )
}
return Config . Groups
}
|
GetContentPathConfiguration get the path to the content files from the
configuration
|
func GetContentPathConfiguration ( ) string {
if Config . Content . ContentPath == "" {
Config . Content . ContentPath = defaultContentPath
}
return Config . Content . ContentPath
}
|
GetMetricsConfiguration get MetricsConf from the loaded configuration
|
func GetMetricsConfiguration ( ) MetricsConf {
return Config . Metrics
}
|
GetLoggingConfiguration returns logging configuration
|
func GetLoggingConfiguration ( ) logger . LoggingConfiguration {
return Config . Logging
}
|
GetCloudWatchConfiguration returns cloudwatch configuration
|
func GetCloudWatchConfiguration ( ) logger . CloudWatchConfiguration {
return Config . CloudWatch
}
|
GetSentryLoggingConfiguration returns the sentry log configuration
|
func GetSentryLoggingConfiguration ( ) logger . SentryLoggingConfiguration {
return Config . SentryLoggingConf
}
|
GetKafkaZerologConfiguration returns the kafkazero log configuration
|
func GetKafkaZerologConfiguration ( ) logger . KafkaZerologConfiguration {
return Config . KafkaZerologConf
}
|
checkIfFileExists returns nil if path doesn't exist or isn't a file,
otherwise it returns corresponding error
|
func checkIfFileExists ( path string ) error {
if path == "" {
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
}
|