From 91529ca046841d01efc155086a46328234f6bafd Mon Sep 17 00:00:00 2001 From: Ruslan Aliev Date: Thu, 27 Aug 2020 13:21:09 -0500 Subject: [PATCH] Introduce new approach of config object loading The new approach of config loading allows us to combine and move all the config loading and verifications actions from cmd to pkg module; it will be executed on demand only and save us from non expected runtime errors. The examples of usage will be introduced in further changes. Change-Id: I1b4c29f9c5b1de3e46a1faf5c28fea5c7b3eb4e1 Signed-off-by: Ruslan Aliev --- pkg/config/config.go | 75 ++++++++++++++++++++++++++++--------- pkg/config/utils.go | 24 ++++++++++++ pkg/environment/settings.go | 3 ++ 3 files changed, 84 insertions(+), 18 deletions(-) diff --git a/pkg/config/config.go b/pkg/config/config.go index 2c8824d42..b517cb553 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -29,6 +29,7 @@ import ( clientcmdapi "k8s.io/client-go/tools/clientcmd/api" "sigs.k8s.io/yaml" + "opendev.org/airship/airshipctl/pkg/log" "opendev.org/airship/airshipctl/pkg/util" ) @@ -87,6 +88,61 @@ type Permissions struct { FilePermission uint32 } +// Factory is a function which returns ready to use config object and error (if any) +type Factory func() (*Config, error) + +// CreateFactory returns function which creates ready to use Config object +func CreateFactory(airshipConfigPath *string, kubeConfigPath *string) Factory { + return func() (*Config, error) { + cfg := NewConfig() + cfg.kubeConfig = NewKubeConfig() + + var acp, kcp string + if airshipConfigPath != nil { + acp = *airshipConfigPath + } + if kubeConfigPath != nil { + kcp = *kubeConfigPath + } + + cfg.initConfigPath(acp, kcp) + err := cfg.LoadConfig(cfg.loadedConfigPath, cfg.kubeConfigPath, false) + if err != nil { + // Should stop airshipctl + log.Fatal("Failed to load or initialize config: ", err) + } + + return cfg, cfg.EnsureComplete() + } +} + +// initConfigPath - Initializes loadedConfigPath and kubeConfigPath variable for Config object +func (c *Config) initConfigPath(airshipConfigPath string, kubeConfigPath string) { + switch { + case airshipConfigPath != "": + // The loadedConfigPath may already have been received as a command line argument + c.loadedConfigPath = airshipConfigPath + case os.Getenv(AirshipConfigEnv) != "": + // Otherwise, we can check if we got the path via ENVIRONMENT variable + c.loadedConfigPath = os.Getenv(AirshipConfigEnv) + default: + // Otherwise, we'll try putting it in the home directory + c.loadedConfigPath = filepath.Join(util.UserHomeDir(), AirshipConfigDir, AirshipConfig) + } + + switch { + case kubeConfigPath != "": + // The kubeConfigPath may already have been received as a command line argument + c.kubeConfigPath = kubeConfigPath + case os.Getenv(AirshipKubeConfigEnv) != "": + // Otherwise, we can check if we got the path via ENVIRONMENT variable + c.kubeConfigPath = os.Getenv(AirshipKubeConfigEnv) + default: + // Otherwise, we'll try putting it in the home directory + c.kubeConfigPath = filepath.Join(util.UserHomeDir(), AirshipConfigDir, AirshipKubeConfig) + } +} + // LoadConfig populates the Config object using the files found at // airshipConfigPath and kubeConfigPath func (c *Config) LoadConfig(airshipConfigPath, kubeConfigPath string, create bool) error { @@ -137,24 +193,7 @@ func (c *Config) loadKubeConfig(kubeConfigPath string, create bool) error { var err error if _, err = os.Stat(kubeConfigPath); os.IsNotExist(err) && create { // Default kubeconfig matching Airship target cluster - c.kubeConfig = &clientcmdapi.Config{ - Clusters: map[string]*clientcmdapi.Cluster{ - AirshipDefaultContext: { - Server: "https://172.17.0.1:6443", - }, - }, - AuthInfos: map[string]*clientcmdapi.AuthInfo{ - "admin": { - Username: "airship-admin", - }, - }, - Contexts: map[string]*clientcmdapi.Context{ - AirshipDefaultContext: { - Cluster: AirshipDefaultContext, - AuthInfo: "admin", - }, - }, - } + c.kubeConfig = NewKubeConfig() return nil } else if err != nil { return err diff --git a/pkg/config/utils.go b/pkg/config/utils.go index 3acc14b1f..15757ef06 100644 --- a/pkg/config/utils.go +++ b/pkg/config/utils.go @@ -18,6 +18,8 @@ package config import ( "encoding/base64" + + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" ) // NewConfig returns a newly initialized Config object @@ -58,6 +60,28 @@ func NewConfig() *Config { } } +// NewKubeConfig returns a newly initialized clientcmdapi.Config object, will be removed later +func NewKubeConfig() *clientcmdapi.Config { + return &clientcmdapi.Config{ + Clusters: map[string]*clientcmdapi.Cluster{ + AirshipDefaultContext: { + Server: "https://172.17.0.1:6443", + }, + }, + AuthInfos: map[string]*clientcmdapi.AuthInfo{ + "admin": { + Username: "airship-admin", + }, + }, + Contexts: map[string]*clientcmdapi.Context{ + AirshipDefaultContext: { + Cluster: AirshipDefaultContext, + AuthInfo: "admin", + }, + }, + } +} + // NewContext is a convenience function that returns a new Context func NewContext() *Context { return &Context{} diff --git a/pkg/environment/settings.go b/pkg/environment/settings.go index c93038bac..d3e3dee03 100644 --- a/pkg/environment/settings.go +++ b/pkg/environment/settings.go @@ -59,6 +59,7 @@ func (a *AirshipCTLSettings) InitFlags(cmd *cobra.Command) { } // InitConfig - Initializes and loads Config if exists. +// TODO (raliev) remove this function after completely switching to new approach of Config loading func (a *AirshipCTLSettings) InitConfig() { a.Config = config.NewConfig() @@ -73,6 +74,7 @@ func (a *AirshipCTLSettings) InitConfig() { } // InitAirshipConfigPath - Initializes AirshipConfigPath variable for Config object +// TODO (raliev) remove this function after completely switching to new approach of Config loading func (a *AirshipCTLSettings) InitAirshipConfigPath() { // The airshipConfigPath may already have been received as a command line argument if a.AirshipConfigPath != "" { @@ -91,6 +93,7 @@ func (a *AirshipCTLSettings) InitAirshipConfigPath() { } // InitKubeConfigPath - Initializes KubeConfigPath variable for Config object +// TODO (raliev) remove this function after completely switching to new approach of Config loading func (a *AirshipCTLSettings) InitKubeConfigPath() { // NOTE(howell): This function will set the kubeConfigPath to the // default location under the airship directory unless the user