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")
}
GetManagementServerCredentials - Given a management server URL, returns the associated credentials
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
}