Refactor cluster* commands

All the cluster commands was refactored for usage with new config
factory. Config object now is being initialized in pkg module on demand,
which provides more flexibility and cleaner code.

Change-Id: I1088ecbce0c34a146a646270404ff206b152d310
Signed-off-by: Ruslan Aliev <raliev@mirantis.com>
This commit is contained in:
Ruslan Aliev 2020-08-27 18:57:08 -05:00
parent e81116b1a9
commit a567007199
11 changed files with 47 additions and 58 deletions

View File

@ -17,6 +17,7 @@ package cluster
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/environment" "opendev.org/airship/airshipctl/pkg/environment"
"opendev.org/airship/airshipctl/pkg/k8s/client" "opendev.org/airship/airshipctl/pkg/k8s/client"
) )
@ -35,19 +36,13 @@ func NewClusterCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Comm
Use: "cluster", Use: "cluster",
Short: "Manage Kubernetes clusters", Short: "Manage Kubernetes clusters",
Long: clusterLong[1:], Long: clusterLong[1:],
PersistentPreRun: func(cmd *cobra.Command, args []string) {
if parentPreRun := cmd.Root().PersistentPreRun; parentPreRun != nil {
parentPreRun(cmd.Root(), args)
} }
// Load or Initialize airship Config cfgFactory := config.CreateFactory(&rootSettings.AirshipConfigPath, &rootSettings.KubeConfigPath)
rootSettings.InitConfig()
},
}
clusterRootCmd.AddCommand(NewInitCommand(rootSettings)) clusterRootCmd.AddCommand(NewInitCommand(cfgFactory))
clusterRootCmd.AddCommand(NewMoveCommand(rootSettings)) clusterRootCmd.AddCommand(NewMoveCommand(cfgFactory))
clusterRootCmd.AddCommand(NewStatusCommand(rootSettings, client.DefaultClient)) clusterRootCmd.AddCommand(NewStatusCommand(cfgFactory, client.DefaultClient))
return clusterRootCmd return clusterRootCmd
} }

View File

@ -20,7 +20,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
clusterctlcmd "opendev.org/airship/airshipctl/pkg/clusterctl/cmd" clusterctlcmd "opendev.org/airship/airshipctl/pkg/clusterctl/cmd"
"opendev.org/airship/airshipctl/pkg/environment" "opendev.org/airship/airshipctl/pkg/config"
) )
const ( const (
@ -71,14 +71,14 @@ airshipctl cluster init
) )
// NewInitCommand creates a command to deploy cluster-api // NewInitCommand creates a command to deploy cluster-api
func NewInitCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command { func NewInitCommand(cfgFactory config.Factory) *cobra.Command {
initCmd := &cobra.Command{ initCmd := &cobra.Command{
Use: "init", Use: "init",
Short: "Deploy cluster-api provider components", Short: "Deploy cluster-api provider components",
Long: initLong, Long: initLong,
Example: initExample, Example: initExample,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
command, err := clusterctlcmd.NewCommand(rootSettings) command, err := clusterctlcmd.NewCommand(cfgFactory)
if err != nil { if err != nil {
return err return err
} }

View File

@ -18,6 +18,7 @@ import (
"testing" "testing"
"opendev.org/airship/airshipctl/cmd/cluster" "opendev.org/airship/airshipctl/cmd/cluster"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/environment" "opendev.org/airship/airshipctl/pkg/environment"
"opendev.org/airship/airshipctl/testutil" "opendev.org/airship/airshipctl/testutil"
) )
@ -33,7 +34,9 @@ func TestNewClusterInitCmd(t *testing.T) {
{ {
Name: "cluster-init-cmd-with-help", Name: "cluster-init-cmd-with-help",
CmdLine: "--help", CmdLine: "--help",
Cmd: cluster.NewInitCommand(fakeRootSettings), Cmd: cluster.NewInitCommand(func() (*config.Config, error) {
return fakeRootSettings.Config, nil
}),
}, },
} }
for _, testcase := range tests { for _, testcase := range tests {

View File

@ -20,7 +20,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
clusterctlcmd "opendev.org/airship/airshipctl/pkg/clusterctl/cmd" clusterctlcmd "opendev.org/airship/airshipctl/pkg/clusterctl/cmd"
"opendev.org/airship/airshipctl/pkg/environment" "opendev.org/airship/airshipctl/pkg/config"
) )
const ( const (
@ -38,7 +38,7 @@ Move Cluster API objects, provider specific objects and all dependencies to the
) )
// NewMoveCommand creates a command to move capi and bmo resources to the target cluster // NewMoveCommand creates a command to move capi and bmo resources to the target cluster
func NewMoveCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command { func NewMoveCommand(cfgFactory config.Factory) *cobra.Command {
var toKubeconfigContext string var toKubeconfigContext string
moveCmd := &cobra.Command{ moveCmd := &cobra.Command{
Use: "move", Use: "move",
@ -46,7 +46,7 @@ func NewMoveCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command
Long: moveLong[1:], Long: moveLong[1:],
Example: moveExample, Example: moveExample,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
command, err := clusterctlcmd.NewCommand(rootSettings) command, err := clusterctlcmd.NewCommand(cfgFactory)
if err != nil { if err != nil {
return err return err
} }

View File

@ -18,21 +18,15 @@ import (
"testing" "testing"
"opendev.org/airship/airshipctl/cmd/cluster" "opendev.org/airship/airshipctl/cmd/cluster"
"opendev.org/airship/airshipctl/pkg/environment"
"opendev.org/airship/airshipctl/testutil" "opendev.org/airship/airshipctl/testutil"
) )
func TestNewClusterMoveCmd(t *testing.T) { func TestNewClusterMoveCmd(t *testing.T) {
fakeRootSettings := &environment.AirshipCTLSettings{
AirshipConfigPath: "../../testdata/k8s/config.yaml",
KubeConfigPath: "../../testdata/k8s/kubeconfig.yaml",
}
tests := []*testutil.CmdTest{ tests := []*testutil.CmdTest{
{ {
Name: "cluster-move-cmd-with-help", Name: "cluster-move-cmd-with-help",
CmdLine: "--help", CmdLine: "--help",
Cmd: cluster.NewMoveCommand(fakeRootSettings), Cmd: cluster.NewMoveCommand(nil),
}, },
} }
for _, testcase := range tests { for _, testcase := range tests {

View File

@ -20,21 +20,21 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"opendev.org/airship/airshipctl/pkg/cluster" "opendev.org/airship/airshipctl/pkg/cluster"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/document" "opendev.org/airship/airshipctl/pkg/document"
"opendev.org/airship/airshipctl/pkg/environment"
"opendev.org/airship/airshipctl/pkg/k8s/client" "opendev.org/airship/airshipctl/pkg/k8s/client"
"opendev.org/airship/airshipctl/pkg/log" "opendev.org/airship/airshipctl/pkg/log"
"opendev.org/airship/airshipctl/pkg/util" "opendev.org/airship/airshipctl/pkg/util"
) )
// NewStatusCommand creates a command which reports the statuses of a cluster's deployed components. // NewStatusCommand creates a command which reports the statuses of a cluster's deployed components.
func NewStatusCommand(rootSettings *environment.AirshipCTLSettings, factory client.Factory) *cobra.Command { func NewStatusCommand(cfgFactory config.Factory, factory client.Factory) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "status", Use: "status",
Short: "Retrieve statuses of deployed cluster components", Short: "Retrieve statuses of deployed cluster components",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
conf := rootSettings.Config conf, err := cfgFactory()
if err := conf.EnsureComplete(); err != nil { if err != nil {
return err return err
} }
@ -53,7 +53,7 @@ func NewStatusCommand(rootSettings *environment.AirshipCTLSettings, factory clie
return err return err
} }
client, err := factory(rootSettings) client, err := factory(conf)
if err != nil { if err != nil {
return err return err
} }

View File

@ -24,7 +24,6 @@ import (
"opendev.org/airship/airshipctl/cmd/cluster" "opendev.org/airship/airshipctl/cmd/cluster"
"opendev.org/airship/airshipctl/pkg/config" "opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/environment"
"opendev.org/airship/airshipctl/pkg/k8s/client" "opendev.org/airship/airshipctl/pkg/k8s/client"
"opendev.org/airship/airshipctl/pkg/k8s/client/fake" "opendev.org/airship/airshipctl/pkg/k8s/client/fake"
"opendev.org/airship/airshipctl/testutil" "opendev.org/airship/airshipctl/testutil"
@ -69,7 +68,7 @@ func TestNewClusterStatusCmd(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
tt := tt tt := tt
testClientFactory := func(_ *environment.AirshipCTLSettings) (client.Interface, error) { testClientFactory := func(_ *config.Config) (client.Interface, error) {
return fake.NewClient( return fake.NewClient(
fake.WithDynamicObjects(tt.resources...), fake.WithDynamicObjects(tt.resources...),
fake.WithCRDs(tt.CRDs...), fake.WithCRDs(tt.CRDs...),
@ -80,9 +79,9 @@ func TestNewClusterStatusCmd(t *testing.T) {
} }
} }
func clusterStatusTestSettings() *environment.AirshipCTLSettings { func clusterStatusTestSettings() config.Factory {
return &environment.AirshipCTLSettings{ return func() (*config.Config, error) {
Config: &config.Config{ return &config.Config{
Clusters: map[string]*config.ClusterPurpose{"testCluster": nil}, Clusters: map[string]*config.ClusterPurpose{"testCluster": nil},
AuthInfos: map[string]*config.AuthInfo{"testAuthInfo": nil}, AuthInfos: map[string]*config.AuthInfo{"testAuthInfo": nil},
Contexts: map[string]*config.Context{ Contexts: map[string]*config.Context{
@ -92,7 +91,7 @@ func clusterStatusTestSettings() *environment.AirshipCTLSettings {
"testManifest": {TargetPath: fixturesPath}, "testManifest": {TargetPath: fixturesPath},
}, },
CurrentContext: "testContext", CurrentContext: "testContext",
}, }, nil
} }
} }

View File

@ -19,7 +19,6 @@ import (
"opendev.org/airship/airshipctl/pkg/clusterctl/client" "opendev.org/airship/airshipctl/pkg/clusterctl/client"
"opendev.org/airship/airshipctl/pkg/config" "opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/document" "opendev.org/airship/airshipctl/pkg/document"
"opendev.org/airship/airshipctl/pkg/environment"
"opendev.org/airship/airshipctl/pkg/log" "opendev.org/airship/airshipctl/pkg/log"
) )
@ -33,15 +32,16 @@ type Command struct {
} }
// NewCommand returns instance of Command // NewCommand returns instance of Command
func NewCommand(rs *environment.AirshipCTLSettings) (*Command, error) { func NewCommand(cfgFactory config.Factory) (*Command, error) {
bundle, err := getBundle(rs.Config) cfg, err := cfgFactory()
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err = rs.Config.EnsureComplete(); err != nil { bundle, err := getBundle(cfg)
if err != nil {
return nil, err return nil, err
} }
root, err := rs.Config.CurrentContextTargetPath() root, err := cfg.CurrentContextTargetPath()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -53,14 +53,14 @@ func NewCommand(rs *environment.AirshipCTLSettings) (*Command, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
kubeConfigPath := rs.Config.KubeConfigPath() kubeConfigPath := cfg.KubeConfigPath()
return &Command{ return &Command{
kubeconfigPath: kubeConfigPath, kubeconfigPath: kubeConfigPath,
documentRoot: root, documentRoot: root,
client: client, client: client,
options: options, options: options,
kubeconfigContext: rs.Config.CurrentContext, kubeconfigContext: cfg.CurrentContext,
}, nil }, nil
} }

View File

@ -120,7 +120,9 @@ func TestNewCommand(t *testing.T) {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
rs.Config.Manifests = manifests rs.Config.Manifests = manifests
rs.Config.CurrentContext = context rs.Config.CurrentContext = context
command, err := NewCommand(rs) command, err := NewCommand(func() (*config.Config, error) {
return rs.Config, nil
})
if expectErr { if expectErr {
assert.Error(t, err) assert.Error(t, err)
assert.Nil(t, command) assert.Nil(t, command)

View File

@ -22,7 +22,7 @@ import (
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd"
"opendev.org/airship/airshipctl/pkg/environment" "opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/k8s/kubectl" "opendev.org/airship/airshipctl/pkg/k8s/kubectl"
k8sutils "opendev.org/airship/airshipctl/pkg/k8s/utils" k8sutils "opendev.org/airship/airshipctl/pkg/k8s/utils"
) )
@ -55,19 +55,19 @@ type Client struct {
var _ Interface = &Client{} var _ Interface = &Client{}
// Factory is a function which creates Interfaces // Factory is a function which creates Interfaces
type Factory func(*environment.AirshipCTLSettings) (Interface, error) type Factory func(*config.Config) (Interface, error)
// DefaultClient is a factory which generates a default client // DefaultClient is a factory which generates a default client
var DefaultClient Factory = NewClient var DefaultClient Factory = NewClient
// NewClient creates a Client initialized from the passed in settings // NewClient creates a Client initialized from the passed in settings
func NewClient(settings *environment.AirshipCTLSettings) (Interface, error) { func NewClient(cfg *config.Config) (Interface, error) {
client := new(Client) client := new(Client)
var err error var err error
f := k8sutils.FactoryFromKubeConfigPath(settings.KubeConfigPath) f := k8sutils.FactoryFromKubeConfigPath(cfg.KubeConfigPath())
pathToBufferDir := filepath.Dir(settings.AirshipConfigPath) pathToBufferDir := filepath.Dir(cfg.LoadedConfigPath())
client.kubectl = kubectl.NewKubectl(f).WithBufferDir(pathToBufferDir) client.kubectl = kubectl.NewKubectl(f).WithBufferDir(pathToBufferDir)
client.clientSet, err = f.KubernetesClientSet() client.clientSet, err = f.KubernetesClientSet()
@ -81,12 +81,12 @@ func NewClient(settings *environment.AirshipCTLSettings) (Interface, error) {
} }
// kubectl factories can't create CRD clients... // kubectl factories can't create CRD clients...
config, err := clientcmd.BuildConfigFromFlags("", settings.KubeConfigPath) kubeConfig, err := clientcmd.BuildConfigFromFlags("", cfg.KubeConfigPath())
if err != nil { if err != nil {
return nil, err return nil, err
} }
client.apixClient, err = apix.NewForConfig(config) client.apixClient, err = apix.NewForConfig(kubeConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -21,7 +21,6 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"opendev.org/airship/airshipctl/pkg/environment"
"opendev.org/airship/airshipctl/pkg/k8s/client" "opendev.org/airship/airshipctl/pkg/k8s/client"
"opendev.org/airship/airshipctl/testutil" "opendev.org/airship/airshipctl/testutil"
) )
@ -41,13 +40,10 @@ func TestNewClient(t *testing.T) {
adir, err := filepath.Abs(airshipConfigDir) adir, err := filepath.Abs(airshipConfigDir)
require.NoError(t, err) require.NoError(t, err)
settings := &environment.AirshipCTLSettings{ conf.SetLoadedConfigPath(adir)
Config: conf, conf.SetKubeConfigPath(akp)
AirshipConfigPath: adir,
KubeConfigPath: akp,
}
client, err := client.NewClient(settings) client, err := client.NewClient(conf)
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, client) assert.NotNil(t, client)
assert.NotNil(t, client.ClientSet()) assert.NotNil(t, client.ClientSet())