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 <raliev@mirantis.com>
This commit is contained in:
Ruslan Aliev 2020-08-27 13:21:09 -05:00
parent 4c0d2c0b57
commit 91529ca046
3 changed files with 84 additions and 18 deletions

View File

@ -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

View File

@ -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{}

View File

@ -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