func setupViper(v *viper.Viper, p *pflag.FlagSet) {
	v.AddConfigPath(".")
	v.AddConfigPath("./config")
	v.AddConfigPath("$HOME/config")
	p.Init(FriendlyServiceName, pflag.ExitOnError)
	pflag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage of %s:\n", FriendlyServiceName)
		pflag.PrintDefaults()
	}
	v.BindPFlags(p)  
	v.SetEnvPrefix(ConfigEnvPrefix)
	v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
	v.AutomaticEnv()
}
setupViper configures some defaults in the Viper instance
package main
import (
	"fmt"
	"os"
	"reflect"
	"strings"
	"emperror.dev/errors"
	"github.com/spf13/pflag"
	"github.com/spf13/viper"
	"github.com/banzaicloud/nodepool-labels-operator/internal/platform/healthcheck"
	"github.com/banzaicloud/nodepool-labels-operator/internal/platform/log"
	"github.com/banzaicloud/nodepool-labels-operator/pkg/controller"
	"github.com/banzaicloud/nodepool-labels-operator/pkg/labeler"
)
var configuration Config
type Config struct {
	Environment string `mapstucture:"environment"`
	Debug bool `mapstructure:"debug"`
	Log log.Config `mapstructure:"log"`
	Healthcheck healthcheck.Config `mapstructure:"healthcheck"`
	Controller controller.Config `mapstructure:"controller"`
	Labeler labeler.Config `mapstructure:"labeler"`
}
func (c Config) Validate() error {
	err := c.Log.Validate()
	if err != nil {
		return errors.WrapIf(err, "could not validate log config")
	}
	err = c.Healthcheck.Validate()
	if err != nil {
		return errors.WrapIf(err, "could not validate healthcheck config")
	}
	return nil
}
func configure() {
	setupViper(viper.GetViper(), pflag.CommandLine)
	pflag.Parse()
	err := viper.ReadInConfig()
	if _, ok := err.(viper.ConfigFileNotFoundError); err != nil && !ok {
		panic(errors.WrapIf(err, "failed to read configuration"))
	}
	bindEnvs(configuration)
	err = viper.Unmarshal(&configuration)
	if err != nil {
		panic(errors.WrapIf(err, "failed to unmarshal configuration"))
	}
	err = configuration.Validate()
	if err != nil {
		panic(errors.WrapIf(err, "cloud not validate configuration"))
	}
}