func ReadConfig(configFile, configPath string) (*ProxyConfigMap, error) {
	viper.New()
	viper.SetConfigName(configFile)
	viper.SetConfigType("yaml")
	viper.AddConfigPath(configPath)
	err := viper.ReadInConfig()
	if err != nil {
		return nil, err
	}
	fmt.Println(viper.AllSettings())
	var configMap ProxyConfigMap
	err = viper.Unmarshal(&configMap)
	if err != nil {
		return nil, err
	}
	return &configMap, nil
}
ReadConfig - uses viper to read the config from the config map
package config
import (
	"crypto/subtle"
	"fmt"
	"net/url"
	"reflect"
	"revproxy/v2/pkg/common"
	"revproxy/v2/pkg/k8sutils"
	"revproxy/v2/pkg/utils"
	log "github.com/sirupsen/logrus"
	"github.com/spf13/viper"
	corev1 "k8s.io/api/core/v1"
)
type ProxyMode string
const (
	Linked     = ProxyMode("Linked")
	StandAlone = ProxyMode("StandAlone")
)
type StorageArrayConfig struct {
	StorageArrayID         string   `yaml:"storageArrayId"`
	PrimaryURL             string   `yaml:"primaryURL"`
	BackupURL              string   `yaml:"backupURL,omitempty"`
	ProxyCredentialSecrets []string `yaml:"proxyCredentialSecrets"`
}
type ProxyCredentialSecret struct {
	Credentials      common.Credentials
	CredentialSecret string
}
type StorageArray struct {
	StorageArrayIdentifier string
	PrimaryURL             url.URL
	SecondaryURL           url.URL
	ProxyCredentialSecrets map[string]ProxyCredentialSecret
}
type StorageArrayServer struct {
	Array         StorageArray
	PrimaryServer ManagementServer
	BackupServer  *ManagementServer
}
func (sa *StorageArray) DeepCopy() *StorageArray {
	if sa == nil {
		return nil
	}
	cloned := StorageArray{}
	cloned = *sa
	cloned.ProxyCredentialSecrets = make(map[string]ProxyCredentialSecret, len(sa.ProxyCredentialSecrets))
	for secret, proxySecret := range sa.ProxyCredentialSecrets {
		cloned.ProxyCredentialSecrets[secret] = proxySecret
	}
	return &cloned
}
type ManagementServerConfig struct {
	URL                       string        `yaml:"url"`
	ArrayCredentialSecret     string        `yaml:"arrayCredentialSecret,omitempty"`
	SkipCertificateValidation bool          `yaml:"skipCertificateValidation,omitempty"`
	CertSecret                string        `yaml:"certSecret,omitempty"`
	Limits                    common.Limits `yaml:"limits,omitempty" mapstructure:"limits"`
}
type ManagementServer struct {
	URL                       url.URL
	StorageArrayIdentifiers   []string
	Credentials               common.Credentials
	CredentialSecret          string
	SkipCertificateValidation bool
	CertFile                  string
	CertSecret                string
	Limits                    common.Limits
}
func (ms *ManagementServer) DeepCopy() *ManagementServer {
	clone := ManagementServer{}
	clone = *ms
	clone.StorageArrayIdentifiers = make([]string, len(ms.StorageArrayIdentifiers))
	copy(clone.StorageArrayIdentifiers, ms.StorageArrayIdentifiers)
	return &clone
}
type LinkConfig struct {
	Primary ManagementServerConfig `yaml:"primary" mapstructure:"primary"`
	Backup  ManagementServerConfig `yaml:"backup,omitempty" mapstructure:"backup"`
}
type StandAloneConfig struct {
	StorageArrayConfig     []StorageArrayConfig     `yaml:"storageArrays" mapstructure:"storageArrays"`
	ManagementServerConfig []ManagementServerConfig `yaml:"managementServers" mapstructure:"managementServers"`
}
type ProxyConfigMap struct {
	Mode             ProxyMode         `yaml:"mode,omitempty"`
	Port             string            `yaml:"port,omitempty"`
	LogLevel         string            `yaml:"logLevel,omitempty"`
	LogFormat        string            `yaml:"logFormat,omitempty"`
	LinkConfig       *LinkConfig       `yaml:"linkConfig,omitempty" mapstructure:"linkConfig"`
	StandAloneConfig *StandAloneConfig `yaml:"standAloneConfig,omitempty" mapstructure:"standAloneConfig"`
}
type LinkedProxyConfig struct {
	Primary *ManagementServer
	Backup  *ManagementServer
}
func (proxy *LinkedProxyConfig) DeepCopy() *LinkedProxyConfig {
	if proxy == nil {
		return nil
	}
	cloned := new(LinkedProxyConfig)
	cloned.Primary = proxy.Primary.DeepCopy()
	if proxy.Backup != nil {
		cloned.Backup = proxy.Backup.DeepCopy()
	}
	return cloned
}
func (proxy *LinkedProxyConfig) Log() {
	log.Debug("-----------------------")
	log.Debug("-----------------------")
	log.Debug("primary config")
	log.Debugf("%+v\n", proxy.Primary)
	log.Debug("-----------------------")
	log.Debug("backup config")
	log.Debugf("%+v\n", proxy.Backup)
	log.Debug("-----------------------")
}
func (proxy *LinkedProxyConfig) IsCertSecretRelated(secretName string) bool {
	if proxy.Primary.CertSecret == secretName {
		return true
	}
	if proxy.Backup != nil && proxy.Backup.CertSecret == secretName {
		return true
	}
	return false
}
func (proxy *LinkedProxyConfig) UpdateCertFileName(secretName, certFileName string) bool {
	isUpdated := false
	if proxy.Primary.CertSecret == secretName {
		proxy.Primary.CertFile = certFileName
		isUpdated = true
	}
	if proxy.Backup != nil && proxy.Backup.CertSecret == secretName {
		proxy.Backup.CertFile = certFileName
		isUpdated = true
	}
	return isUpdated
}
type StandAloneProxyConfig struct {
	managedArrays     map[string]*StorageArray
	managementServers map[url.URL]*ManagementServer
	proxyCredentials  map[string]*ProxyUser
}
func (proxy *StandAloneProxyConfig) DeepCopy() *StandAloneProxyConfig {
	if proxy == nil {
		return nil
	}
	cloned := new(StandAloneProxyConfig)
	cloned.proxyCredentials = make(map[string]*ProxyUser)
	cloned.managementServers = make(map[url.URL]*ManagementServer)
	cloned.managedArrays = make(map[string]*StorageArray)
	for key, value := range proxy.managedArrays {
		array := *value
		cloned.managedArrays[key] = &array
	}
	for key, value := range proxy.managementServers {
		cloned.managementServers[key] = value.DeepCopy()
	}
	for key, value := range proxy.proxyCredentials {
		creds := *value
		cloned.proxyCredentials[key] = &creds
	}
	return cloned
}
func (proxy *StandAloneProxyConfig) Log() {
	fmt.Println("---------------------")
	fmt.Println("managedArrays")
	for key, val := range proxy.managedArrays {
		fmt.Printf("%s ::: %+v\n", key, val)
	}
	fmt.Println("---------------------")
	fmt.Println("---------------------")
	fmt.Println("managementServers")
	for key, val := range proxy.managementServers {
		fmt.Printf("%v ::: %+v\n", key, val)
	}
	fmt.Println("---------------------")
	fmt.Println("---------------------")
	fmt.Println("proxyCredentials")
	for key, val := range proxy.proxyCredentials {
		fmt.Printf("%s ::: %+v\n", key, val)
	}
	fmt.Println("---------------------")
}
func (proxy *StandAloneProxyConfig) updateProxyCredentials(creds common.Credentials, storageArrayIdentifier string) {
	if proxyUser, ok := proxy.proxyCredentials[creds.UserName]; ok {
		if subtle.ConstantTimeCompare([]byte(creds.Password), []byte(proxyUser.ProxyCredential.Password)) == 1 {
			proxyUser.StorageArrayIdentifiers = utils.AppendIfMissingStringSlice(
				proxyUser.StorageArrayIdentifiers, storageArrayIdentifier)
		}
	} else {
		proxyUser := ProxyUser{
			ProxyCredential:         creds,
			StorageArrayIdentifiers: []string{storageArrayIdentifier},
		}
		proxy.proxyCredentials[creds.UserName] = &proxyUser
	}
}
func (proxy *StandAloneProxyConfig) GetManagementServers() []ManagementServer {
	var mgmtServers = make([]ManagementServer, 0)
	for _, v := range proxy.managementServers {
		mgmtServers = append(mgmtServers, *v)
	}
	return mgmtServers
}
func (proxy *StandAloneProxyConfig) GetManagedArraysAndServers() map[string]StorageArrayServer {
	arrayServers := make(map[string]StorageArrayServer)
	for _, server := range proxy.managementServers {
		for _, arrayID := range server.StorageArrayIdentifiers {
			var (
				arrayServer StorageArrayServer
				ok          bool
			)
			if arrayServer, ok = arrayServers[arrayID]; !ok {
				arrayServer = StorageArrayServer{}
				arrayServer.Array = *(proxy.managedArrays[arrayID])
			}
			if server.URL == arrayServer.Array.PrimaryURL {
				arrayServer.PrimaryServer = *(server)
			} else if server.URL == arrayServer.Array.SecondaryURL {
				arrayServer.BackupServer = server
			}
			arrayServers[arrayID] = arrayServer
		}
	}
	return arrayServers
}
func (proxy *StandAloneProxyConfig) IsSecretConfiguredForCerts(secretName string) bool {
	found := false
	for _, server := range proxy.managementServers {
		if server.CertSecret == secretName {
			found = true
			break
		}
	}
	return found
}
func (proxy *StandAloneProxyConfig) IsSecretConfiguredForArrays(secretName string) bool {
	for _, array := range proxy.managedArrays {
		if array.ProxyCredentialSecrets[secretName].CredentialSecret == secretName {
			return true
		}
	}
	return false
}
func (proxy *StandAloneProxyConfig) UpdateCerts(secretName, certFileName string) bool {
	isUpdated := false
	for _, server := range proxy.managementServers {
		if server.CertSecret == secretName {
			server.CertFile = certFileName
			isUpdated = true
		}
	}
	return isUpdated
}
func (proxy *StandAloneProxyConfig) UpdateCreds(secretName string, credentials *common.Credentials) bool {
	isUpdated := false
	for _, server := range proxy.managementServers {
		if server.CredentialSecret == secretName {
			if server.Credentials != *credentials {
				server.Credentials = *credentials
				isUpdated = true
			}
		}
	}
	for _, array := range proxy.managedArrays {
		if array.ProxyCredentialSecrets[secretName].CredentialSecret == secretName {
			if array.ProxyCredentialSecrets[secretName].Credentials != *credentials {
				storageArrayIdentifiers := proxy.proxyCredentials[array.ProxyCredentialSecrets[secretName].Credentials.UserName].StorageArrayIdentifiers
				delete(proxy.proxyCredentials, array.ProxyCredentialSecrets[secretName].Credentials.UserName)
				newProxyCredentialSecret := &ProxyCredentialSecret{
					Credentials:      *credentials,
					CredentialSecret: secretName,
				}
				array.ProxyCredentialSecrets[secretName] = *newProxyCredentialSecret
				proxy.proxyCredentials[credentials.UserName] = &ProxyUser{
					ProxyCredential:         *credentials,
					StorageArrayIdentifiers: storageArrayIdentifiers,
				}
				isUpdated = true
			}
		}
	}
	return isUpdated
}
func (proxy *StandAloneProxyConfig) UpdateCertsAndCredentials(k8sUtils k8sutils.UtilsInterface, secret *corev1.Secret) (bool, error) {
	hasChanged := false
	for _, server := range proxy.managementServers {
		if server.CredentialSecret == secret.Name {
			credentials, err := k8sUtils.GetCredentialsFromSecret(secret)
			if err != nil {
				return hasChanged, err
			}
			if server.Credentials != *credentials {
				server.Credentials = *credentials
				hasChanged = true
			}
		} else if server.CertSecret == secret.Name {
			certFile, err := k8sUtils.GetCertFileFromSecret(secret)
			if err != nil {
				return hasChanged, err
			}
			server.CertFile = certFile
			hasChanged = true
		}
	}
	for _, array := range proxy.managedArrays {
		if array.ProxyCredentialSecrets[secret.Name].CredentialSecret == secret.Name {
			credentials, err := k8sUtils.GetCredentialsFromSecret(secret)
			if err != nil {
				return hasChanged, err
			}
			if array.ProxyCredentialSecrets[secret.Name].Credentials != *credentials {
				storageArrayIdentifiers := proxy.proxyCredentials[array.ProxyCredentialSecrets[secret.Name].Credentials.UserName].StorageArrayIdentifiers
				delete(proxy.proxyCredentials, array.ProxyCredentialSecrets[secret.Name].Credentials.UserName)
				newProxyCredentialSecret := &ProxyCredentialSecret{
					Credentials:      *credentials,
					CredentialSecret: secret.Name,
				}
				array.ProxyCredentialSecrets[secret.Name] = *newProxyCredentialSecret
				proxy.proxyCredentials[credentials.UserName] = &ProxyUser{
					ProxyCredential:         *credentials,
					StorageArrayIdentifiers: storageArrayIdentifiers,
				}
				hasChanged = true
			}
		}
	}
	return hasChanged, nil
}
func (proxy *StandAloneProxyConfig) UpdateManagementServers(config *StandAloneProxyConfig) ([]ManagementServer, []ManagementServer, error) {
	deletedManagementServers := make([]ManagementServer, 0)
	updatedManagemetServers := make([]ManagementServer, 0)
	for url, server := range proxy.managementServers {
		if _, ok := config.managementServers[url]; !ok {
			deletedManagementServers = append(deletedManagementServers, *server)
			delete(proxy.managementServers, url)
		}
	}
	for url, mgmntServer := range config.managementServers {
		if _, ok := proxy.managementServers[url]; !ok {
			updatedManagemetServers = append(updatedManagemetServers, *mgmntServer)
			proxy.managementServers[url] = config.managementServers[url]
		} else {
			if !reflect.DeepEqual(proxy.managementServers[url], config.managementServers[url]) {
				updatedManagemetServers = append(updatedManagemetServers, *mgmntServer)
				proxy.managementServers[url] = config.managementServers[url]
			}
		}
	}
	if !reflect.DeepEqual(proxy.managementServers, config.managementServers) {
		return nil, nil, fmt.Errorf("something wrong in adding/removing servers")
	}
	return deletedManagementServers, updatedManagemetServers, nil
}
func (proxy *StandAloneProxyConfig) UpdateManagedArrays(config *StandAloneProxyConfig) {
	if !reflect.DeepEqual(proxy.managedArrays, config.managedArrays) {
		log.Info("Detected changes, updating managed array config")
		proxy.managedArrays = config.managedArrays
		proxy.proxyCredentials = config.proxyCredentials
	}
}
func (proxy *StandAloneProxyConfig) GetAuthorizedArrays(username, password string) []string {
	var authorisedArrays = make([]string, 0)
	for _, a := range proxy.managedArrays {
		isAuth, err := proxy.IsUserAuthorized(username, password, a.StorageArrayIdentifier)
		if err != nil {
			log.Errorf("error : (%s)", err.Error())
		}
		if isAuth {
			authorisedArrays = append(authorisedArrays, a.StorageArrayIdentifier)
		}
	}
	return authorisedArrays
}
func (proxy *StandAloneProxyConfig) GetManagementServerCredentials(mgmtURL url.URL) (common.Credentials, error) {
	if mgmtServer, ok := proxy.managementServers[mgmtURL]; ok {
		return mgmtServer.Credentials, nil
	}
	return common.Credentials{}, fmt.Errorf("url not configured")
}
func (proxy *StandAloneProxyConfig) IsUserAuthorized(username, password, storageArrayID string) (bool, error) {
	if creds, ok := proxy.proxyCredentials[username]; ok {
		if utils.IsStringInSlice(creds.StorageArrayIdentifiers, storageArrayID) {
			if subtle.ConstantTimeCompare([]byte(creds.ProxyCredential.Password), []byte(password)) == 1 {
				return true, nil
			}
			return false, fmt.Errorf("incorrect password")
		}
		return false, fmt.Errorf("unauthorized for this array")
	}
	return false, fmt.Errorf("unknown credentials")
}
func (proxy *StandAloneProxyConfig) GetStorageArray(storageArrayID string) []StorageArray {
	var storageArrays = make([]StorageArray, 0)
	if storageArrayID != "" {
		if storageArray, ok := proxy.managedArrays[storageArrayID]; ok {
			storageArrays = append(storageArrays, *storageArray)
		}
	} else {
		for _, v := range proxy.managedArrays {
			storageArrays = append(storageArrays, *v)
		}
	}
	return storageArrays
}
func (proxy *StandAloneProxyConfig) GetManagementServer(url url.URL) (ManagementServer, bool) {
	if server, ok := proxy.managementServers[url]; ok {
		return *server, ok
	}
	return ManagementServer{}, false
}
type ProxyConfig struct {
	Mode                  ProxyMode
	Port                  string
	LinkProxyConfig       *LinkedProxyConfig
	StandAloneProxyConfig *StandAloneProxyConfig
}
func (proxyConfig *ProxyConfig) DeepCopy() *ProxyConfig {
	if proxyConfig == nil {
		return nil
	}
	cloned := ProxyConfig{}
	cloned = *proxyConfig
	cloned.LinkProxyConfig = proxyConfig.LinkProxyConfig.DeepCopy()
	cloned.StandAloneProxyConfig = proxyConfig.StandAloneProxyConfig.DeepCopy()
	return &cloned
}
type ProxyUser struct {
	StorageArrayIdentifiers []string
	ProxyCredential         common.Credentials
}
func (pu *ProxyUser) DeepClone() *ProxyUser {
	if pu == nil {
		return nil
	}
	cloned := ProxyUser{}
	cloned = *pu
	cloned.StorageArrayIdentifiers = make([]string, len(pu.StorageArrayIdentifiers))
	copy(cloned.StorageArrayIdentifiers, pu.StorageArrayIdentifiers)
	return &cloned
}
func (proxyConfig *ProxyConfig) ParseConfig(proxyConfigMap ProxyConfigMap, k8sUtils k8sutils.UtilsInterface) error {
	proxyMode := proxyConfigMap.Mode
	proxyConfig.Mode = proxyMode
	proxyConfig.Port = proxyConfigMap.Port
	fmt.Printf("ConfigMap: %v\n", proxyConfigMap)
	if proxyMode == Linked {
		config := proxyConfigMap.LinkConfig
		if config == nil {
			return fmt.Errorf("proxy mode is specified as Linked but unable to parse config")
		}
		if config.Primary.URL == "" {
			return fmt.Errorf("must provide Primary url")
		}
		primaryURL, err := url.Parse(config.Primary.URL)
		if err != nil {
			return err
		}
		primaryManagementServer := ManagementServer{
			URL:                       *primaryURL,
			SkipCertificateValidation: config.Primary.SkipCertificateValidation,
			Limits:                    config.Primary.Limits,
		}
		if config.Primary.CertSecret != "" {
			primaryCertFile, err := k8sUtils.GetCertFileFromSecretName(config.Primary.CertSecret)
			if err != nil {
				return err
			}
			primaryManagementServer.CertFile = primaryCertFile
			primaryManagementServer.CertSecret = config.Primary.CertSecret
		}
		linkedProxyConfig := LinkedProxyConfig{
			Primary: &primaryManagementServer,
		}
		if config.Backup.URL != "" {
			backupURL, err := url.Parse(config.Backup.URL)
			if err != nil {
				return err
			}
			backupManagementServer := ManagementServer{
				URL:                       *backupURL,
				SkipCertificateValidation: config.Backup.SkipCertificateValidation,
				Limits:                    config.Backup.Limits,
			}
			if config.Backup.CertSecret != "" {
				backupCertFile, err := k8sUtils.GetCertFileFromSecretName(config.Backup.CertSecret)
				if err != nil {
					return err
				}
				backupManagementServer.CertFile = backupCertFile
				backupManagementServer.CertSecret = config.Backup.CertSecret
			}
			linkedProxyConfig.Backup = &backupManagementServer
		}
		proxyConfig.LinkProxyConfig = &linkedProxyConfig
	} else if proxyMode == StandAlone {
		config := proxyConfigMap.StandAloneConfig
		if config == nil {
			return fmt.Errorf("proxy mode is specified as StandAlone but unable to parse config")
		}
		var proxy StandAloneProxyConfig
		proxy.managedArrays = make(map[string]*StorageArray)
		proxy.managementServers = make(map[url.URL]*ManagementServer)
		proxy.proxyCredentials = make(map[string]*ProxyUser)
		storageArrayIdentifiers := make(map[url.URL][]string)
		ipAddresses := make([]string, 0)
		for _, mgmtServer := range config.ManagementServerConfig {
			ipAddresses = append(ipAddresses, mgmtServer.URL)
		}
		for _, array := range config.StorageArrayConfig {
			if array.PrimaryURL == "" {
				return fmt.Errorf("primary URL not configured for array: %s", array.StorageArrayID)
			}
			if !utils.IsStringInSlice(ipAddresses, array.PrimaryURL) {
				return fmt.Errorf("primary URL: %s for array: %s not present among management URL addresses",
					array.PrimaryURL, array)
			}
			if array.BackupURL != "" {
				if !utils.IsStringInSlice(ipAddresses, array.BackupURL) {
					return fmt.Errorf("backup URL: %s for array: %s is not in the list of management URL addresses. Ignoring it",
						array.BackupURL, array)
				}
			}
			primaryURL, err := url.Parse(array.PrimaryURL)
			if err != nil {
				return err
			}
			backupURL := &url.URL{}
			if array.BackupURL != "" {
				backupURL, err = url.Parse(array.BackupURL)
				if err != nil {
					return err
				}
			}
			proxy.managedArrays[array.StorageArrayID] = &StorageArray{
				StorageArrayIdentifier: array.StorageArrayID,
				PrimaryURL:             *primaryURL,
				SecondaryURL:           *backupURL,
			}
			if _, ok := storageArrayIdentifiers[*primaryURL]; ok {
				storageArrayIdentifiers[*primaryURL] = append(storageArrayIdentifiers[*primaryURL], array.StorageArrayID)
			} else {
				storageArrayIdentifiers[*primaryURL] = []string{array.StorageArrayID}
			}
			if _, ok := storageArrayIdentifiers[*backupURL]; ok {
				storageArrayIdentifiers[*backupURL] = append(storageArrayIdentifiers[*backupURL], array.StorageArrayID)
			} else {
				storageArrayIdentifiers[*backupURL] = []string{array.StorageArrayID}
			}
			if len(array.ProxyCredentialSecrets) > 0 {
				proxy.managedArrays[array.StorageArrayID].ProxyCredentialSecrets = make(map[string]ProxyCredentialSecret)
				for _, secret := range array.ProxyCredentialSecrets {
					proxyCredentials, err := k8sUtils.GetCredentialsFromSecretName(secret)
					if err != nil {
						return err
					}
					proxyCredentialSecret := &ProxyCredentialSecret{
						Credentials:      *proxyCredentials,
						CredentialSecret: secret,
					}
					proxy.managedArrays[array.StorageArrayID].ProxyCredentialSecrets[secret] = *proxyCredentialSecret
					proxy.updateProxyCredentials(*proxyCredentials, array.StorageArrayID)
				}
			}
		}
		for _, managementServer := range config.ManagementServerConfig {
			var arrayCredentials common.Credentials
			if managementServer.ArrayCredentialSecret != "" {
				credentials, err := k8sUtils.GetCredentialsFromSecretName(managementServer.ArrayCredentialSecret)
				if err != nil {
					return err
				}
				arrayCredentials = *credentials
			}
			mgmtURL, err := url.Parse(managementServer.URL)
			if err != nil {
				return err
			}
			var certFile string
			if managementServer.CertSecret != "" {
				certFile, err = k8sUtils.GetCertFileFromSecretName(managementServer.CertSecret)
				if err != nil {
					return nil
				}
			}
			proxy.managementServers[*mgmtURL] = &ManagementServer{
				URL:                       *mgmtURL,
				StorageArrayIdentifiers:   storageArrayIdentifiers[*mgmtURL],
				SkipCertificateValidation: managementServer.SkipCertificateValidation,
				CertFile:                  certFile,
				CertSecret:                managementServer.CertSecret,
				Credentials:               arrayCredentials,
				CredentialSecret:          managementServer.ArrayCredentialSecret,
				Limits:                    managementServer.Limits,
			}
		}
		proxyConfig.StandAloneProxyConfig = &proxy
	} else {
		return fmt.Errorf("unknown proxy mode: %s specified", string(proxyMode))
	}
	if proxyConfig.LinkProxyConfig == nil && proxyConfig.StandAloneProxyConfig == nil {
		return fmt.Errorf("no configuration provided for the proxy")
	}
	return nil
}
func NewProxyConfig(configMap *ProxyConfigMap, k8sUtils k8sutils.UtilsInterface) (*ProxyConfig, error) {
	var proxyConfig ProxyConfig
	err := proxyConfig.ParseConfig(*configMap, k8sUtils)
	if err != nil {
		return nil, err
	}
	return &proxyConfig, nil
}