func LoadConfiguration(basePath string, dryRunDebug bool, cliOnly bool) {
	conf = &config{}
	conf.initBaseConfig(basePath)
	conf.K8SManagement.DryRunOnly = dryRunDebug
	conf.K8SManagement.CliOnly = cliOnly
	conf.readDeploymentConfigurationFromYamlFile()
}
LoadConfiguration loads the base configuration and merges it with alternative configurations if defined.
package configuration
import (
	"fmt"
	"github.com/imdario/mergo"
	"gopkg.in/yaml.v3"
	"io/ioutil"
	"k8s-management-go/app/constants"
	"k8s-management-go/app/utils/files"
	"k8s-management-go/app/utils/logger"
	"k8s-management-go/app/utils/loggingstate"
	"log"
	"os"
	"path/filepath"
	"strings"
)
type baseCustomConfig struct {
	K8SManagement struct {
		ConfigFile string `yaml:"configFile,omitempty"`
		BasePath   string `yaml:"basePath,omitempty"`
	} `yaml:"k8sManagement,omitempty"`
}
type DeploymentYAMLConfig struct {
	K8SManagement struct {
		IPConfig struct {
			Deployments []DeploymentStruct `yaml:"deployments,omitempty"`
		} `yaml:"ipconfig,omitempty"`
	} `yaml:"k8sManagement,omitempty"`
}
type DeploymentStruct struct {
	IPAddress string `yaml:"ipAddress,omitempty"`
	Namespace string `yaml:"namespace,omitempty"`
	Domain    string `yaml:"domain,omitempty"`
	Dummy     string `yaml:"dummy,omitempty"`
}
type config struct {
	K8SManagement struct {
		Log struct {
			Level              string `yaml:"level,omitempty"`
			File               string `yaml:"file,omitempty"`
			Encoding           string `yaml:"encoding,omitempty"`
			OverwriteOnRestart bool   `yaml:"overwriteOnRestart,omitempty"`
		} `yaml:"log,omitempty"`
		IPConfig struct {
			File        string             `yaml:"file,omitempty"`
			DummyPrefix string             `yaml:"dummyPrefix,omitempty"`
			Deployments []DeploymentStruct `yaml:"-"`
		} `yaml:"ipconfig,omitempty"`
		Project struct {
			BaseDirectory     string `yaml:"baseDirectory,omitempty"`
			TemplateDirectory string `yaml:"templateDirectory,omitempty"`
			SecretFiles       string `yaml:"secretFiles,omitempty"`
		} `yaml:"project,omitempty"`
		VersionCheck           bool   `yaml:"versionCheck,omitempty"`
		KeepGeneratedTemplates bool   `yaml:"keepGeneratedTemplates,omitempty"`
		DryRunOnly             bool   `yaml:"-"`
		CliOnly                bool   `yaml:"-"`
		BasePath               string `yaml:"-"`
	} `yaml:"k8sManagement,omitempty"`
	Jenkins struct {
		Jcasc struct {
			ConfigurationURL      string `yaml:"configurationUrl,omitempty"`
			AuthorizationStrategy struct {
				AllowAnonymousRead bool `yaml:"allowAnonymousRead,omitempty"`
			} `yaml:"authorizationStrategy,omitempty"`
			CredentialIDs struct {
				Docker string `yaml:"docker,omitempty"`
				Maven  string `yaml:"maven,omitempty"`
				Npm    string `yaml:"npm,omitempty"`
				Vcs    string `yaml:"vcs,omitempty"`
			} `yaml:"credentialIDs,omitempty"`
			SeedJobURL string `yaml:"seedJobURL,omitempty"`
		} `yaml:"jcasc,omitempty"`
		JobDSL struct {
			BaseURL             string `yaml:"baseURL,omitempty"`
			RepoValidatePattern string `yaml:"repoValidatePattern,omitempty"`
		} `yaml:"jobDSL,omitempty"`
		Controller struct {
			Passwords struct {
				AdminUser            string `yaml:"adminUser,omitempty"`
				AdminUserEncrypted   string `yaml:"adminUserEncrypted,omitempty"`
				DefaultUserEncrypted string `yaml:"defaultUserEncrypted,omitempty"`
			} `yaml:"passwords,omitempty"`
			CustomJenkinsLabel string `yaml:"customJenkinsLabel,omitempty"`
			DeploymentName     string `yaml:"deploymentName,omitempty"`
			DefaultURIPrefix   string `yaml:"defaultURIPrefix,omitempty"`
		} `yaml:"controller,omitempty"`
		Persistence struct {
			AccessMode   string `yaml:"accessMode,omitempty"`
			StorageClass string `yaml:"storageClass,omitempty"`
			StorageSize  string `yaml:"storageSize,omitempty"`
		} `yaml:"persistence,omitempty"`
		Container struct {
			Image      string `yaml:"image,omitempty"`
			Tag        string `yaml:"tag,omitempty"`
			PullPolicy string `yaml:"pullPolicy,omitempty"`
			PullSecret string `yaml:"pullSecret,omitempty"`
		} `yaml:"container,omitempty"`
	} `yaml:"jenkins,omitempty"`
	Nginx struct {
		Ingress struct {
			Container struct {
				Image      string `yaml:"image,omitempty"`
				PullSecret string `yaml:"pullSecret,omitempty"`
			} `yaml:"container,omitempty"`
			Deployment struct {
				ForEachNamespace bool   `yaml:"forEachNamespace,omitempty"`
				DeploymentName   string `yaml:"deploymentName,omitempty"`
			} `yaml:"deployment,omitempty"`
			Annotationclass string `yaml:"annotationclass,omitempty"`
		} `yaml:"ingress,omitempty"`
		Loadbalancer struct {
			Enabled bool `yaml:"enabled,omitempty"`
			Ports   struct {
				HTTP        uint64 `yaml:"http,omitempty"`
				HTTPTarget  uint64 `yaml:"httpTarget,omitempty"`
				HTTPS       uint64 `yaml:"https,omitempty"`
				HTTPSTarget uint64 `yaml:"httpsTarget,omitempty"`
			} `yaml:"ports,omitempty"`
			Annotations struct {
				Enabled bool `yaml:"enabled,omitempty"`
			} `yaml:"annotations,omitempty"`
			ExternalDNS struct {
				HostName string `yaml:"hostName,omitempty"`
				TTL      uint64 `yaml:"ttl,omitempty"`
			} `yaml:"externalDNS,omitempty"`
		} `yaml:"loadbalancer,omitempty"`
	} `yaml:"nginx,omitempty"`
	Kubernetes struct {
		Certificates struct {
			Default  string            `yaml:"default,omitempty"`
			Contexts map[string]string `yaml:"contexts,omitempty"`
		} `yaml:"certificates,omitempty"`
	} `yaml:"kubernetes,omitempty"`
	CustomConfig baseCustomConfig `yaml:"-"`
}
var conf *config
func EmptyConfiguration() *config {
	return &config{}
}
func GetConfiguration() *config {
	return conf
}
func (conf *config) GetProjectBaseDirectory() string {
	return conf.calculateFullDirectoryPath(conf.K8SManagement.Project.BaseDirectory)
}
func (conf *config) GetProjectTemplateDirectory() string {
	return conf.calculateFullDirectoryPath(conf.K8SManagement.Project.TemplateDirectory)
}
func (conf *config) GetIPConfigurationFile() string {
	return conf.FilePathWithBasePath(conf.K8SManagement.IPConfig.File)
}
func (conf *config) calculateFullDirectoryPath(targetDir string) string {
	if strings.HasPrefix(targetDir, "./") || strings.HasPrefix(targetDir, "../") {
		return conf.FilePathWithBasePath(targetDir)
	} else {
		return targetDir
	}
}
func (conf *config) GetGlobalSecretsPath() (secretsFilePath string) {
	var globalSecretsFile = conf.getGlobalSecretsFile()
	var fileName = filepath.Base(globalSecretsFile)
	return strings.Replace(globalSecretsFile, fileName, "", -1)
}
func (conf *config) GetSecretsFiles() []string {
	var secretsFilePath = conf.GetGlobalSecretsPath()
	if secretsFilePath != "" {
		var filePrefix = "secrets_"
		var fileFilter = files.FileFilter{
			Prefix: &filePrefix,
		}
		var secretFilesWithoutPath, err = files.ListFilesOfDirectoryWithFilter(secretsFilePath, &fileFilter)
		if err != nil {
			loggingstate.AddErrorEntryAndDetails(
				"Unable to filter for secrets files",
				fmt.Sprintf("SearchDirectory: [%s]", secretsFilePath))
		}
		var secretFilesWithPath []string
		if secretFilesWithoutPath != nil && len(*secretFilesWithoutPath) > 0 {
			for _, secretFileOfFilter := range *secretFilesWithoutPath {
				secretFilesWithPath = append(secretFilesWithPath, conf.GetGlobalSecretsPath()+secretFileOfFilter)
			}
		}
		var secretFiles []string
		secretFiles = appendUnique(secretFiles, strings.Replace(conf.getGlobalSecretsFile(), secretsFilePath, "", -1))
		if len(secretFilesWithPath) > 0 {
			for _, secretFile := range secretFilesWithPath {
				secretFile = strings.Replace(secretFile, secretsFilePath, "", -1)
				secretFile = strings.Replace(secretFile, ".gpg", "", -1)
				secretFiles = appendUnique(secretFiles, secretFile)
			}
		}
		return secretFiles
	}
	return nil
}
func (conf *config) getGlobalSecretsFile() string {
	var globalSecretsFile = conf.K8SManagement.Project.SecretFiles
	if globalSecretsFile == "" {
		panic("The configured secrets file is not a file!")
	}
	return conf.FilePathWithBasePath(globalSecretsFile)
}
func (conf *config) SetDryRun(dryRun bool) {
	conf.K8SManagement.DryRunOnly = dryRun
}
func (conf *config) FilePathWithBasePath(configurationFilePath string) string {
	var resultConfigurationFilePath = configurationFilePath
	if conf.K8SManagement.BasePath != "" {
		resultConfigurationFilePath = files.AppendPath(conf.K8SManagement.BasePath, configurationFilePath)
	}
	if !files.FileOrDirectoryExists(resultConfigurationFilePath) {
		var currentDirectory, _ = os.Getwd()
		var currentDirFilePath = files.AppendPath(currentDirectory, configurationFilePath)
		if files.FileOrDirectoryExists(currentDirFilePath) {
			resultConfigurationFilePath = currentDirFilePath
		}
	}
	return resultConfigurationFilePath
}
func (conf *config) AddToIPConfigFile(namespace string, ip string, domain string) (success bool, err error) {
	var logging = logger.Log()
	var newIpAndNamespace = DeploymentStruct{
		IPAddress: ip,
		Namespace: namespace,
		Domain:    domain,
	}
	conf.K8SManagement.IPConfig.Deployments = append(conf.K8SManagement.IPConfig.Deployments, newIpAndNamespace)
	ipConfigFile, err := os.OpenFile(conf.GetIPConfigurationFile(), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
	if err != nil {
		loggingstate.AddErrorEntryAndDetails(fmt.Sprintf("  -> Unable to open IP config file [%s]", conf.GetIPConfigurationFile()), err.Error())
		logging.Errorf("[AddToIPConfigFile] Unable to open IP config file [%s]. \n%s", conf.GetIPConfigurationFile(), err.Error())
		return false, err
	}
	var yamlIPConfig = DeploymentYAMLConfig{}
	yamlIPConfig.K8SManagement.IPConfig.Deployments = conf.K8SManagement.IPConfig.Deployments
	yamlFileOutput, err := yaml.Marshal(yamlIPConfig)
	if err != nil {
		loggingstate.AddErrorEntryAndDetails("Unable to marshall yaml IP deployment configuration.", err.Error())
		logging.Error("Unable to marshall yaml IP deployment configuration.", err.Error())
		_ = ipConfigFile.Close()
		return false, err
	}
	if _, err := ipConfigFile.Write(yamlFileOutput); err != nil {
		loggingstate.AddErrorEntryAndDetails("Unable to write YAML IP deployment configuration.", err.Error())
		logging.Error("Unable to write YAML IP deployment configuration.", err.Error())
		_ = ipConfigFile.Close()
		return false, err
	}
	_ = ipConfigFile.Close()
	return true, err
}