diff --git a/cmd/cluster/status_test.go b/cmd/cluster/status_test.go index e649476f0..e3217f889 100644 --- a/cmd/cluster/status_test.go +++ b/cmd/cluster/status_test.go @@ -82,8 +82,6 @@ func TestNewClusterStatusCmd(t *testing.T) { func clusterStatusTestSettings() config.Factory { return func() (*config.Config, error) { return &config.Config{ - Clusters: map[string]*config.ClusterPurpose{"testCluster": nil}, - AuthInfos: map[string]*config.AuthInfo{"testAuthInfo": nil}, Contexts: map[string]*config.Context{ "testContext": {Manifest: "testManifest"}, }, diff --git a/cmd/config/config.go b/cmd/config/config.go index 278fa9a93..8fed8f3af 100644 --- a/cmd/config/config.go +++ b/cmd/config/config.go @@ -34,7 +34,6 @@ func NewConfigCommand(cfgFactory config.Factory) *cobra.Command { configRootCmd.AddCommand(NewGetManagementConfigCommand(cfgFactory)) configRootCmd.AddCommand(NewSetManagementConfigCommand(cfgFactory)) - configRootCmd.AddCommand(NewImportCommand(cfgFactory)) configRootCmd.AddCommand(NewUseContextCommand(cfgFactory)) configRootCmd.AddCommand(NewGetManifestCommand(cfgFactory)) diff --git a/cmd/config/get_context_test.go b/cmd/config/get_context_test.go index 1ab74c127..2899ed368 100644 --- a/cmd/config/get_context_test.go +++ b/cmd/config/get_context_test.go @@ -20,8 +20,6 @@ import ( "fmt" "testing" - kubeconfig "k8s.io/client-go/tools/clientcmd/api" - cmd "opendev.org/airship/airshipctl/cmd/config" "opendev.org/airship/airshipctl/pkg/config" "opendev.org/airship/airshipctl/testutil" @@ -94,17 +92,10 @@ func TestNoContextsGetContextCmd(t *testing.T) { } func getNamedTestContext(contextName string) *config.Context { - kContext := &kubeconfig.Context{ - Namespace: "dummy_namespace", - AuthInfo: "dummy_user", - Cluster: fmt.Sprintf("dummycluster_%s", config.Ephemeral), - } - newContext := &config.Context{ NameInKubeconf: fmt.Sprintf("%s_%s", contextName, config.Ephemeral), Manifest: fmt.Sprintf("Manifest_%s", contextName), } - newContext.SetKubeContext(kContext) return newContext } diff --git a/cmd/config/import.go b/cmd/config/import.go deleted file mode 100644 index d52ec7838..000000000 --- a/cmd/config/import.go +++ /dev/null @@ -1,62 +0,0 @@ -/* - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package config - -import ( - "fmt" - - "github.com/spf13/cobra" - - "opendev.org/airship/airshipctl/pkg/config" -) - -const ( - useImportLong = ` -Merge the clusters, contexts, and users from an existing kubeConfig file into the airshipctl config file. -` - - useImportExample = ` -# Import from a kubeConfig file" -airshipctl config import $HOME/.kube/config -` -) - -// NewImportCommand creates a command that merges clusters, contexts, and -// users from a kubeConfig file into the airshipctl config file. -func NewImportCommand(cfgFactory config.Factory) *cobra.Command { - cmd := &cobra.Command{ - Use: "import ", - Short: "Merge information from a kubernetes config file", - Long: useImportLong[1:], - Example: useImportExample, - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - cfg, err := cfgFactory() - if err != nil { - return err - } - kubeConfigPath := args[0] - err = cfg.ImportFromKubeConfig(kubeConfigPath) - if err != nil { - return err - } - - fmt.Fprintf(cmd.OutOrStdout(), "Updated airship config with content imported from %q.\n", kubeConfigPath) - return nil - }, - } - - return cmd -} diff --git a/cmd/config/import_test.go b/cmd/config/import_test.go deleted file mode 100644 index c7d43d90d..000000000 --- a/cmd/config/import_test.go +++ /dev/null @@ -1,55 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config_test - -import ( - "errors" - "testing" - - cmd "opendev.org/airship/airshipctl/cmd/config" - "opendev.org/airship/airshipctl/pkg/config" - "opendev.org/airship/airshipctl/testutil" -) - -func TestConfigImport(t *testing.T) { - settings := func() (*config.Config, error) { - return testutil.DummyConfig(), nil - } - - cmdTests := []*testutil.CmdTest{ - { - Name: "config-import-with-help", - CmdLine: "--help", - Cmd: cmd.NewImportCommand(nil), - }, - { - Name: "config-import-no-args", - CmdLine: "", - Cmd: cmd.NewImportCommand(settings), - Error: errors.New("accepts 1 arg(s), received 0"), - }, - { - Name: "config-import-file-does-not-exist", - CmdLine: "foo", - Cmd: cmd.NewImportCommand(settings), - Error: errors.New("stat foo: no such file or directory"), - }, - } - - for _, tt := range cmdTests { - testutil.RunTest(t, tt) - } -} diff --git a/cmd/config/set_context.go b/cmd/config/set_context.go index 4a0d3541b..408a412d2 100644 --- a/cmd/config/set_context.go +++ b/cmd/config/set_context.go @@ -32,10 +32,7 @@ Create or modify a context in the airshipctl config files. setContextExample = ` # Create a new context named "exampleContext" airshipctl config set-context exampleContext \ - --namespace=kube-system \ --manifest=exampleManifest \ - --user=exampleUser - --cluster-type=target --encryption-config=exampleEncryptionConfig # Update the manifest of the current-context @@ -91,18 +88,6 @@ func NewSetContextCommand(cfgFactory config.Factory) *cobra.Command { func addSetContextFlags(o *config.ContextOptions, cmd *cobra.Command) { flags := cmd.Flags() - flags.StringVar( - &o.Cluster, - "cluster", - "", - "set the cluster for the specified context") - - flags.StringVar( - &o.AuthInfo, - "user", - "", - "set the user for the specified context") - flags.StringVar( &o.Manifest, "manifest", @@ -115,12 +100,6 @@ func addSetContextFlags(o *config.ContextOptions, cmd *cobra.Command) { "", "set the encryption config for the specified context") - flags.StringVar( - &o.Namespace, - "namespace", - "", - "set the namespace for the specified context") - flags.StringVar( &o.ClusterType, "cluster-type", diff --git a/cmd/config/set_context_test.go b/cmd/config/set_context_test.go index ea33ccefd..e69abb5d0 100644 --- a/cmd/config/set_context_test.go +++ b/cmd/config/set_context_test.go @@ -30,11 +30,9 @@ import ( ) const ( - testUser = "admin@kubernetes" - defaultManifest = "edge_cloud" - defaultNamespace = "kube-system" - testManifest = "test_manifest" testEncryptionConfig = "test_encryption_config" + defaultManifest = "edge_cloud" + testManifest = "test_manifest" ) type setContextTest struct { @@ -86,9 +84,7 @@ func TestSetContext(t *testing.T) { contextName: "dummycontext", flags: []string{ "--cluster-type=target", - "--user=" + testUser, "--manifest=" + defaultManifest, - "--namespace=" + defaultNamespace, "--encryption-config=" + testEncryptionConfig, }, givenConfig: given, @@ -153,9 +149,6 @@ func (test setContextTest) run(t *testing.T) { require.NoError(t, err) require.NotNil(t, afterRunContext) - afterKcontext := afterRunContext.KubeContext() - require.NotNil(t, afterKcontext) - if test.manifest != "" { assert.EqualValues(t, afterRunContext.Manifest, test.manifest) } diff --git a/cmd/config/testdata/TestConfigGoldenOutput/config-cmd-with-help.golden b/cmd/config/testdata/TestConfigGoldenOutput/config-cmd-with-help.golden index 6ba799f4d..6912569ee 100644 --- a/cmd/config/testdata/TestConfigGoldenOutput/config-cmd-with-help.golden +++ b/cmd/config/testdata/TestConfigGoldenOutput/config-cmd-with-help.golden @@ -9,7 +9,6 @@ Available Commands: get-management-config View a management config or all management configs defined in the airshipctl config get-manifest Get a manifest information from the airshipctl config help Help about any command - import Merge information from a kubernetes config file init Generate initial configuration files for airshipctl set-context Manage contexts set-encryption-config Manage encryption configs in airship config diff --git a/cmd/config/testdata/TestConfigImportGoldenOutput/config-import-file-does-not-exist.golden b/cmd/config/testdata/TestConfigImportGoldenOutput/config-import-file-does-not-exist.golden deleted file mode 100644 index 8e1a21907..000000000 --- a/cmd/config/testdata/TestConfigImportGoldenOutput/config-import-file-does-not-exist.golden +++ /dev/null @@ -1,13 +0,0 @@ -Error: stat foo: no such file or directory -Usage: - import [flags] - -Examples: - -# Import from a kubeConfig file" -airshipctl config import $HOME/.kube/config - - -Flags: - -h, --help help for import - diff --git a/cmd/config/testdata/TestConfigImportGoldenOutput/config-import-no-args.golden b/cmd/config/testdata/TestConfigImportGoldenOutput/config-import-no-args.golden deleted file mode 100644 index 2bdb3dc3f..000000000 --- a/cmd/config/testdata/TestConfigImportGoldenOutput/config-import-no-args.golden +++ /dev/null @@ -1,13 +0,0 @@ -Error: accepts 1 arg(s), received 0 -Usage: - import [flags] - -Examples: - -# Import from a kubeConfig file" -airshipctl config import $HOME/.kube/config - - -Flags: - -h, --help help for import - diff --git a/cmd/config/testdata/TestConfigImportGoldenOutput/config-import-with-help.golden b/cmd/config/testdata/TestConfigImportGoldenOutput/config-import-with-help.golden deleted file mode 100644 index d4b0a866c..000000000 --- a/cmd/config/testdata/TestConfigImportGoldenOutput/config-import-with-help.golden +++ /dev/null @@ -1,13 +0,0 @@ -Merge the clusters, contexts, and users from an existing kubeConfig file into the airshipctl config file. - -Usage: - import [flags] - -Examples: - -# Import from a kubeConfig file" -airshipctl config import $HOME/.kube/config - - -Flags: - -h, --help help for import diff --git a/cmd/config/testdata/TestConfigSetContextGoldenOutput/config-cmd-set-context-too-many-args.golden b/cmd/config/testdata/TestConfigSetContextGoldenOutput/config-cmd-set-context-too-many-args.golden index c7c0fd88b..e3c5d29aa 100644 --- a/cmd/config/testdata/TestConfigSetContextGoldenOutput/config-cmd-set-context-too-many-args.golden +++ b/cmd/config/testdata/TestConfigSetContextGoldenOutput/config-cmd-set-context-too-many-args.golden @@ -6,10 +6,7 @@ Examples: # Create a new context named "exampleContext" airshipctl config set-context exampleContext \ - --namespace=kube-system \ --manifest=exampleManifest \ - --user=exampleUser - --cluster-type=target --encryption-config=exampleEncryptionConfig # Update the manifest of the current-context @@ -19,12 +16,9 @@ airshipctl config set-context \ Flags: - --cluster string set the cluster for the specified context --cluster-type string set the cluster-type for the specified context --current update the current context --encryption-config string set the encryption config for the specified context -h, --help help for set-context --manifest string set the manifest for the specified context - --namespace string set the namespace for the specified context - --user string set the user for the specified context diff --git a/cmd/config/testdata/TestConfigSetContextGoldenOutput/config-cmd-set-context-with-help.golden b/cmd/config/testdata/TestConfigSetContextGoldenOutput/config-cmd-set-context-with-help.golden index 4dab3e1ea..2da37a70b 100644 --- a/cmd/config/testdata/TestConfigSetContextGoldenOutput/config-cmd-set-context-with-help.golden +++ b/cmd/config/testdata/TestConfigSetContextGoldenOutput/config-cmd-set-context-with-help.golden @@ -7,10 +7,7 @@ Examples: # Create a new context named "exampleContext" airshipctl config set-context exampleContext \ - --namespace=kube-system \ --manifest=exampleManifest \ - --user=exampleUser - --cluster-type=target --encryption-config=exampleEncryptionConfig # Update the manifest of the current-context @@ -20,11 +17,8 @@ airshipctl config set-context \ Flags: - --cluster string set the cluster for the specified context --cluster-type string set the cluster-type for the specified context --current update the current context --encryption-config string set the encryption config for the specified context -h, --help help for set-context --manifest string set the manifest for the specified context - --namespace string set the namespace for the specified context - --user string set the user for the specified context diff --git a/cmd/config/testdata/TestGetContextCmdGoldenOutput/get-all-contexts.golden b/cmd/config/testdata/TestGetContextCmdGoldenOutput/get-all-contexts.golden index 88ac45bbe..0977b5e98 100644 --- a/cmd/config/testdata/TestGetContextCmdGoldenOutput/get-all-contexts.golden +++ b/cmd/config/testdata/TestGetContextCmdGoldenOutput/get-all-contexts.golden @@ -1,30 +1,18 @@ Context: ContextBar contextKubeconf: ContextBar_ephemeral +managementConfiguration: "" manifest: Manifest_ContextBar -LocationOfOrigin: "" -cluster: dummycluster_ephemeral -namespace: dummy_namespace -user: dummy_user - Context: ContextBaz contextKubeconf: ContextBaz_ephemeral +managementConfiguration: "" manifest: Manifest_ContextBaz -LocationOfOrigin: "" -cluster: dummycluster_ephemeral -namespace: dummy_namespace -user: dummy_user - Context: ContextFoo contextKubeconf: ContextFoo_ephemeral +managementConfiguration: "" manifest: Manifest_ContextFoo -LocationOfOrigin: "" -cluster: dummycluster_ephemeral -namespace: dummy_namespace -user: dummy_user - diff --git a/cmd/config/testdata/TestGetContextCmdGoldenOutput/get-context.golden b/cmd/config/testdata/TestGetContextCmdGoldenOutput/get-context.golden index d5195ef78..693d927f2 100644 --- a/cmd/config/testdata/TestGetContextCmdGoldenOutput/get-context.golden +++ b/cmd/config/testdata/TestGetContextCmdGoldenOutput/get-context.golden @@ -1,10 +1,6 @@ Context: ContextFoo contextKubeconf: ContextFoo_ephemeral +managementConfiguration: "" manifest: Manifest_ContextFoo -LocationOfOrigin: "" -cluster: dummycluster_ephemeral -namespace: dummy_namespace -user: dummy_user - diff --git a/cmd/config/testdata/TestGetContextCmdGoldenOutput/get-current-context.golden b/cmd/config/testdata/TestGetContextCmdGoldenOutput/get-current-context.golden index 5afc037ec..8d4609403 100644 --- a/cmd/config/testdata/TestGetContextCmdGoldenOutput/get-current-context.golden +++ b/cmd/config/testdata/TestGetContextCmdGoldenOutput/get-current-context.golden @@ -1,10 +1,6 @@ Context: ContextBaz contextKubeconf: ContextBaz_ephemeral +managementConfiguration: "" manifest: Manifest_ContextBaz -LocationOfOrigin: "" -cluster: dummycluster_ephemeral -namespace: dummy_namespace -user: dummy_user - diff --git a/cmd/config/testdata/TestGetContextCmdGoldenOutput/get-multiple-contexts.golden b/cmd/config/testdata/TestGetContextCmdGoldenOutput/get-multiple-contexts.golden index 88ac45bbe..0977b5e98 100644 --- a/cmd/config/testdata/TestGetContextCmdGoldenOutput/get-multiple-contexts.golden +++ b/cmd/config/testdata/TestGetContextCmdGoldenOutput/get-multiple-contexts.golden @@ -1,30 +1,18 @@ Context: ContextBar contextKubeconf: ContextBar_ephemeral +managementConfiguration: "" manifest: Manifest_ContextBar -LocationOfOrigin: "" -cluster: dummycluster_ephemeral -namespace: dummy_namespace -user: dummy_user - Context: ContextBaz contextKubeconf: ContextBaz_ephemeral +managementConfiguration: "" manifest: Manifest_ContextBaz -LocationOfOrigin: "" -cluster: dummycluster_ephemeral -namespace: dummy_namespace -user: dummy_user - Context: ContextFoo contextKubeconf: ContextFoo_ephemeral +managementConfiguration: "" manifest: Manifest_ContextFoo -LocationOfOrigin: "" -cluster: dummycluster_ephemeral -namespace: dummy_namespace -user: dummy_user - diff --git a/docs/source/cli/airshipctl_config.md b/docs/source/cli/airshipctl_config.md index 81ce4233b..68c010701 100644 --- a/docs/source/cli/airshipctl_config.md +++ b/docs/source/cli/airshipctl_config.md @@ -27,7 +27,6 @@ Manage the airshipctl config file * [airshipctl config get-encryption-config](airshipctl_config_get-encryption-config.md) - Get an encryption config information from the airshipctl config * [airshipctl config get-management-config](airshipctl_config_get-management-config.md) - View a management config or all management configs defined in the airshipctl config * [airshipctl config get-manifest](airshipctl_config_get-manifest.md) - Get a manifest information from the airshipctl config -* [airshipctl config import](airshipctl_config_import.md) - Merge information from a kubernetes config file * [airshipctl config init](airshipctl_config_init.md) - Generate initial configuration files for airshipctl * [airshipctl config set-context](airshipctl_config_set-context.md) - Manage contexts * [airshipctl config set-encryption-config](airshipctl_config_set-encryption-config.md) - Manage encryption configs in airship config diff --git a/docs/source/cli/airshipctl_config_set-context.md b/docs/source/cli/airshipctl_config_set-context.md index 1fd691010..83c56b44f 100644 --- a/docs/source/cli/airshipctl_config_set-context.md +++ b/docs/source/cli/airshipctl_config_set-context.md @@ -17,10 +17,7 @@ airshipctl config set-context NAME [flags] # Create a new context named "exampleContext" airshipctl config set-context exampleContext \ - --namespace=kube-system \ --manifest=exampleManifest \ - --user=exampleUser - --cluster-type=target --encryption-config=exampleEncryptionConfig # Update the manifest of the current-context @@ -33,14 +30,11 @@ airshipctl config set-context \ ### Options ``` - --cluster string set the cluster for the specified context --cluster-type string set the cluster-type for the specified context --current update the current context --encryption-config string set the encryption config for the specified context -h, --help help for set-context --manifest string set the manifest for the specified context - --namespace string set the namespace for the specified context - --user string set the user for the specified context ``` ### Options inherited from parent commands diff --git a/pkg/clusterctl/cmd/command.go b/pkg/clusterctl/cmd/command.go index 62c6d0069..c1db5a369 100644 --- a/pkg/clusterctl/cmd/command.go +++ b/pkg/clusterctl/cmd/command.go @@ -66,6 +66,7 @@ func NewCommand(cfgFactory config.Factory) (*Command, error) { // Init runs clusterctl init func (c *Command) Init() error { + log.Printf("config %s \n context %s", c.kubeconfigPath, c.kubeconfigContext) return c.client.Init(c.kubeconfigPath, c.kubeconfigContext) } diff --git a/pkg/clusterctl/cmd/testdata/airshipconfig.yaml b/pkg/clusterctl/cmd/testdata/airshipconfig.yaml index ecb5b921f..fe1b4ecdf 100644 --- a/pkg/clusterctl/cmd/testdata/airshipconfig.yaml +++ b/pkg/clusterctl/cmd/testdata/airshipconfig.yaml @@ -1,25 +1,7 @@ apiVersion: airshipit.org/v1alpha1 -bootstrapInfo: - dummy_bootstrap_config: - container: - volume: /tmp/airship:/config - image: quay.io/airshipit/isogen:latest-ubuntu_focal - containerRuntime: docker - builder: - userDataFileName: user-data - networkConfigFileName: network-config - outputMetadataFileName: output-metadata.yaml - remoteDirect: - isoUrl: http://localhost:8099/ubuntu-focal.iso -clusters: - dummycluster: - clusterType: - ephemeral: - bootstrapInfo: dummy_bootstrap_config - clusterKubeconf: dummycluster_ephemeral contexts: dummy_cluster: - contextKubeconf: dummy_cluster + contextKubeconf: dummycluster_ephemeral manifest: dummy_manifest currentContext: dummy_cluster kind: Config @@ -39,5 +21,3 @@ manifests: url: http://dummy.url.com/primary.git subPath: site targetPath: testdata -users: - dummy_user: {} \ No newline at end of file diff --git a/pkg/config/authinfo.go b/pkg/config/authinfo.go deleted file mode 100644 index fa53eebc1..000000000 --- a/pkg/config/authinfo.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config - -import ( - "k8s.io/client-go/tools/clientcmd/api" - "sigs.k8s.io/yaml" -) - -// AuthInfo contains kubeConfig AuthInfo Object -type AuthInfo struct { - // KubeConfig AuthInfo Object - authInfo *api.AuthInfo -} - -// AuthInfo functions -func (c *AuthInfo) String() string { - kauthinfo := c.KubeAuthInfo() - kyaml, err := yaml.Marshal(&kauthinfo) - if err != nil { - return "" - } - return string(kyaml) -} - -// KubeAuthInfo returns kubeConfig AuthInfo Object -func (c *AuthInfo) KubeAuthInfo() *api.AuthInfo { - return c.authInfo -} - -// SetKubeAuthInfo sets kubeConfig in AuthInfo -func (c *AuthInfo) SetKubeAuthInfo(kc *api.AuthInfo) { - c.authInfo = kc -} diff --git a/pkg/config/authinfo_test.go b/pkg/config/authinfo_test.go deleted file mode 100644 index c93961755..000000000 --- a/pkg/config/authinfo_test.go +++ /dev/null @@ -1,82 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config_test - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "opendev.org/airship/airshipctl/testutil" -) - -func TestGetAuthInfos(t *testing.T) { - conf, cleanup := testutil.InitConfig(t) - defer cleanup(t) - - authinfos, err := conf.GetAuthInfos() - require.NoError(t, err) - assert.Len(t, authinfos, 3) -} - -func TestGetAuthInfo(t *testing.T) { - conf, cleanup := testutil.InitConfig(t) - defer cleanup(t) - - authinfo, err := conf.GetAuthInfo("def-user") - require.NoError(t, err) - - // Test Positives - assert.EqualValues(t, authinfo.KubeAuthInfo().Username, "dummy_username") - - // Test Wrong Cluster - _, err = conf.GetAuthInfo("unknown") - assert.Error(t, err) -} - -func TestAddAuthInfo(t *testing.T) { - conf, cleanup := testutil.InitConfig(t) - defer cleanup(t) - - co := testutil.DummyAuthInfoOptions() - authinfo := conf.AddAuthInfo(co) - assert.EqualValues(t, conf.AuthInfos[co.Name], authinfo) -} - -func TestModifyAuthInfo(t *testing.T) { - conf, cleanup := testutil.InitConfig(t) - defer cleanup(t) - - co := testutil.DummyAuthInfoOptions() - authinfo := conf.AddAuthInfo(co) - - co.Username += stringDelta - co.Password = newPassword - co.ClientCertificate = newCertificate - co.ClientKey = newKey - co.Token = newToken - conf.ModifyAuthInfo(authinfo, co) - modifiedAuthinfo, err := conf.GetAuthInfo(co.Name) - assert.NoError(t, err) - assert.EqualValues(t, modifiedAuthinfo.KubeAuthInfo().Username, co.Username) - assert.EqualValues(t, modifiedAuthinfo.KubeAuthInfo().Password, co.Password) - assert.EqualValues(t, modifiedAuthinfo.KubeAuthInfo().ClientCertificate, co.ClientCertificate) - assert.EqualValues(t, modifiedAuthinfo.KubeAuthInfo().ClientKey, co.ClientKey) - assert.EqualValues(t, modifiedAuthinfo.KubeAuthInfo().Token, co.Token) - assert.EqualValues(t, modifiedAuthinfo, authinfo) -} diff --git a/pkg/config/cluster.go b/pkg/config/cluster.go deleted file mode 100644 index c8850dba5..000000000 --- a/pkg/config/cluster.go +++ /dev/null @@ -1,141 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config - -import ( - "fmt" - "strings" - - "k8s.io/client-go/tools/clientcmd/api" - "sigs.k8s.io/yaml" -) - -// Cluster contains information about how to communicate with a kubernetes cluster -type Cluster struct { - // Complex cluster name defined by the using _) - NameInKubeconf string `json:"clusterKubeconf"` - - // KubeConfig Cluster Object - cluster *api.Cluster - - // Management configuration which will be used for all hosts in the cluster - ManagementConfiguration string `json:"managementConfiguration"` -} - -// ClusterPurpose encapsulates the Cluster Type as an enumeration -type ClusterPurpose struct { - // Cluster map of referenceable names to cluster configs - ClusterTypes map[string]*Cluster `json:"clusterType"` -} - -// ClusterComplexName holds the complex cluster name information -// Encapsulates the different operations around using it. -type ClusterComplexName struct { - Name string - Type string -} - -func (c *Cluster) String() string { - cyaml, err := yaml.Marshal(&c) - if err != nil { - return "" - } - kcluster := c.KubeCluster() - kyaml, err := yaml.Marshal(&kcluster) - if err != nil { - return string(cyaml) - } - - return fmt.Sprintf("%s\n%s", string(cyaml), string(kyaml)) -} - -// PrettyString returns cluster information in a formatted string -func (c *Cluster) PrettyString() string { - clusterName := NewClusterComplexNameFromKubeClusterName(c.NameInKubeconf) - return fmt.Sprintf("Cluster: %s\n%s:\n%s", clusterName.Name, clusterName.Type, c) -} - -// KubeCluster returns KubeConfig Cluster Object -func (c *Cluster) KubeCluster() *api.Cluster { - return c.cluster -} - -// SetKubeCluster sets cluster in KubeConfig -func (c *Cluster) SetKubeCluster(kc *api.Cluster) { - c.cluster = kc -} - -// String returns cluster's complex name, formed by combining name and type with a delimiter('_') -func (c *ClusterComplexName) String() string { - return strings.Join([]string{c.Name, c.Type}, AirshipClusterNameSeparator) -} - -// ValidClusterType checks for the possible options for cluster type -// Returns error when invalid cluster type is given -func ValidClusterType(clusterType string) error { - for _, validType := range AllClusterTypes { - if clusterType == validType { - return nil - } - } - return fmt.Errorf("cluster type must be one of %v", AllClusterTypes) -} - -// NewClusterPurpose is a convenience function that returns a new ClusterPurpose -func NewClusterPurpose() *ClusterPurpose { - return &ClusterPurpose{ - ClusterTypes: make(map[string]*Cluster), - } -} - -// NewClusterComplexName returns a ClusterComplexName with the given name and type. -func NewClusterComplexName(clusterName, clusterType string) ClusterComplexName { - return ClusterComplexName{ - Name: clusterName, - Type: clusterType, - } -} - -// NewClusterComplexNameFromKubeClusterName takes the name of a cluster in a -// format which might be found in a kubeconfig file. This may be a simple -// string (e.g. myCluster), or it may be prepended with the type of the cluster -// (e.g. myCluster_target) -// -// If a valid cluster type was appended, the returned ClusterComplexName will -// have that type. If no cluster type is provided, the -// AirshipDefaultClusterType will be used. -func NewClusterComplexNameFromKubeClusterName(kubeClusterName string) ClusterComplexName { - parts := strings.Split(kubeClusterName, AirshipClusterNameSeparator) - - if len(parts) == 1 { - return NewClusterComplexName(kubeClusterName, AirshipDefaultClusterType) - } - - // kubeClusterName matches the format myCluster_something. - // Let's check if "something" is a clusterType. - potentialType := parts[len(parts)-1] - for _, ct := range AllClusterTypes { - if potentialType == ct { - // Rejoin the parts in the case of "my_cluster_etc_etc_" - name := strings.Join(parts[:len(parts)-1], AirshipClusterNameSeparator) - return NewClusterComplexName(name, potentialType) - } - } - - // "something" is not a valid clusterType, so just use the default - return NewClusterComplexName(kubeClusterName, AirshipDefaultClusterType) -} diff --git a/pkg/config/cluster_test.go b/pkg/config/cluster_test.go deleted file mode 100644 index 805532b47..000000000 --- a/pkg/config/cluster_test.go +++ /dev/null @@ -1,72 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config_test - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "opendev.org/airship/airshipctl/pkg/config" - "opendev.org/airship/airshipctl/testutil" -) - -func TestPrettyString(t *testing.T) { - fSys := testutil.SetupTestFs(t, "testdata") - data, err := fSys.ReadFile("/prettycluster-string.yaml") - require.NoError(t, err) - - cluster := testutil.DummyCluster() - assert.EqualValues(t, cluster.PrettyString(), string(data)) -} - -func TestValidClusterTypeFail(t *testing.T) { - err := config.ValidClusterType("Fake") - assert.Error(t, err) -} - -func TestGetCluster(t *testing.T) { - conf, cleanup := testutil.InitConfig(t) - defer cleanup(t) - - cluster, err := conf.GetCluster("def", config.Ephemeral) - require.NoError(t, err) - - // Test Positives - assert.EqualValues(t, cluster.NameInKubeconf, "def_ephemeral") - assert.EqualValues(t, cluster.KubeCluster().Server, "http://5.6.7.8") - - // Test Wrong Cluster - _, err = conf.GetCluster("unknown", config.Ephemeral) - assert.Error(t, err) - - // Test Wrong Cluster Type - _, err = conf.GetCluster("def", "Unknown") - assert.Error(t, err) -} - -func TestAddCluster(t *testing.T) { - conf, cleanup := testutil.InitConfig(t) - defer cleanup(t) - - co := testutil.DummyClusterOptions() - cluster, err := conf.AddCluster(co) - require.NoError(t, err) - - assert.EqualValues(t, conf.Clusters[co.Name].ClusterTypes[co.ClusterType], cluster) -} diff --git a/pkg/config/config.go b/pkg/config/config.go index 7d4995e13..37b20d829 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -1,6 +1,4 @@ /* -Copyright 2014 The Kubernetes Authors. - Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -47,12 +45,6 @@ type Config struct { // +optional APIVersion string `json:"apiVersion,omitempty"` - // Clusters is a map of referenceable names to cluster configs - Clusters map[string]*ClusterPurpose `json:"clusters"` - - // AuthInfos is a map of referenceable names to user configs - AuthInfos map[string]*AuthInfo `json:"users"` - // Permissions is a struct of permissions for file and directory Permissions Permissions `json:"permissions,omitempty"` @@ -124,9 +116,6 @@ func CreateConfig(airshipConfigPath string, kubeConfigPath string) error { cfg := NewConfig() cfg.kubeConfig = NewKubeConfig() cfg.initConfigPath(airshipConfigPath, kubeConfigPath) - if err := cfg.reconcileConfig(); err != nil { - return err - } return cfg.PersistConfig(true) } @@ -170,8 +159,7 @@ func (c *Config) LoadConfig(airshipConfigPath, kubeConfigPath string, create boo return err } - // Lets navigate through the kubeconfig to populate the references in airship config - return c.reconcileConfig() + return nil } // loadFromAirConfig populates the Config from the file found at airshipConfigPath. @@ -217,220 +205,14 @@ func (c *Config) loadKubeConfig(kubeConfigPath string, create bool) error { return err } -// reconcileConfig serves two functions: -// 1 - it will consume from kubeconfig and update airship config -// For cluster that do not comply with the airship cluster type expectations a default -// behavior will be implemented. Such as ,by default they will be tar or ephemeral -// 2 - it will update kubeconfig cluster objects with the appropriate _ convention -func (c *Config) reconcileConfig() error { - updatedClusterNames, persistIt := c.reconcileClusters() - c.reconcileContexts(updatedClusterNames) - c.reconcileAuthInfos() - c.reconcileCurrentContext() - - // I changed things during the reconciliation - // Lets reflect them in the config files - // Specially useful if the config is loaded during a get operation - // If it was a Set this would have happened eventually any way - if persistIt { - return c.PersistConfig(true) - } - return nil -} - -// reconcileClusters synchronizes the airshipconfig file with the kubeconfig file. -// -// It iterates over the clusters listed in the kubeconfig. If any cluster in -// the kubeconfig does not meet the _ convention, the name is -// first changed to the airship default. -// -// It then updates the airshipconfig's names of those clusters, as well as the -// pointer to the clusters. -// If the cluster wasn't referenced prior to the call, it is created; otherwise -// it is modified. -// -// Finally, any clusters listed in the airshipconfig that are no longer -// referenced in the kubeconfig are deleted -// -// The function returns a mapping of changed names in the kubeconfig, as well -// as a boolean denoting that the config files need to be written to file -func (c *Config) reconcileClusters() (map[string]string, bool) { - // updatedClusterNames is a mapping from OLD cluster names to NEW - // cluster names. This will be used later when we update contexts - updatedClusterNames := map[string]string{} - - persistIt := false - for clusterName, cluster := range c.kubeConfig.Clusters { - clusterComplexName := NewClusterComplexNameFromKubeClusterName(clusterName) - // Check if the cluster from the kubeconfig file complies with - // the airship naming convention - if clusterName != clusterComplexName.String() { - // Update the kubeconfig with proper airship name - c.kubeConfig.Clusters[clusterComplexName.String()] = cluster - delete(c.kubeConfig.Clusters, clusterName) - - // We also need to save the mapping from the old name - // so we can update the context in the kubeconfig later - updatedClusterNames[clusterName] = clusterComplexName.String() - - // Since we've modified the kubeconfig object, we'll - // need to let the caller know that the kubeconfig file - // needs to be updated - persistIt = true - - // Otherwise this is a cluster that didnt have an - // airship cluster type, however when you added the - // cluster type - // Probable should just add a number __ entries -func (c *Config) rmConfigClusterStragglers(persistIt bool) bool { - rccs := persistIt - // Checking if there is any Cluster reference in airship config that does not match - // an actual Cluster struct in kubeconfig - for clusterName := range c.Clusters { - for cType, cluster := range c.Clusters[clusterName].ClusterTypes { - if _, found := c.kubeConfig.Clusters[cluster.NameInKubeconf]; !found { - // Instead of removing it , I could add a empty entry in kubeconfig as well - // Will see what is more appropriate with use of Modules configuration - delete(c.Clusters[clusterName].ClusterTypes, cType) - - // If that was the last cluster type, then we - // should delete the cluster entry - if len(c.Clusters[clusterName].ClusterTypes) == 0 { - delete(c.Clusters, clusterName) - } - rccs = true - } - } - } - return rccs -} - -func (c *Config) reconcileContexts(updatedClusterNames map[string]string) { - for key, context := range c.kubeConfig.Contexts { - // Check if the Cluster name referred to by the context - // was updated during the cluster reconcile - if newName, ok := updatedClusterNames[context.Cluster]; ok { - context.Cluster = newName - } - - if c.Contexts[key] == nil { - c.Contexts[key] = NewContext() - } - // Make sure the name matches - c.Contexts[key].NameInKubeconf = context.Cluster - c.Contexts[key].SetKubeContext(context) - - // What about if a Context refers to a cluster that does not - // exist in airship config - clusterName := NewClusterComplexNameFromKubeClusterName(context.Cluster) - if c.Clusters[clusterName.Name] == nil { - // I cannot create this cluster, it will have empty information - // Best course of action is to delete it I think - delete(c.kubeConfig.Contexts, key) - } - } - // Checking if there is any Context reference in airship config that does not match - // an actual Context struct in kubeconfig, if they do not exists I will delete - // Since context in airship config are only references mainly. - for key := range c.Contexts { - if c.kubeConfig.Contexts[key] == nil { - delete(c.Contexts, key) - } - } -} - -func (c *Config) reconcileAuthInfos() { - for key, authinfo := range c.kubeConfig.AuthInfos { - // Simple check if the AuthInfo name is referenced in airship config - if c.AuthInfos[key] == nil && authinfo != nil { - // Add the reference - c.AuthInfos[key] = NewAuthInfo() - } - c.AuthInfos[key].authInfo = authinfo - } - // Checking if there is any AuthInfo reference in airship config that does not match - // an actual Auth Info struct in kubeconfig - for key := range c.AuthInfos { - if c.kubeConfig.AuthInfos[key] == nil { - delete(c.AuthInfos, key) - } - } -} - -func (c *Config) reconcileCurrentContext() { - // If the Airship current context is different that the current context in the kubeconfig - // then - // - if the airship current context is valid, then updated kubeconfig CC - // - if the airship currentcontext is invalid, and the kubeconfig CC is valid, then create the reference - // - otherwise , they are both empty. Make sure - - if c.Contexts[c.CurrentContext] == nil { // Its not valid - if c.Contexts[c.kubeConfig.CurrentContext] != nil { - c.CurrentContext = c.kubeConfig.CurrentContext - } - } else { - // Overpowers kubeConfig CurrentContext - if c.kubeConfig.CurrentContext != c.CurrentContext { - c.kubeConfig.CurrentContext = c.CurrentContext - } - } -} - // EnsureComplete verifies that a Config object is ready to use. // A complete Config object meets the following criteria: -// * At least 1 Cluster is defined -// * At least 1 AuthInfo (user) is defined // * At least 1 Context is defined // * At least 1 Manifest is defined // * The CurrentContext is set // * The CurrentContext identifies an existing Context // * The CurrentContext identifies an existing Manifest func (c *Config) EnsureComplete() error { - if len(c.Clusters) == 0 { - return ErrMissingConfig{ - What: "At least one cluster needs to be defined", - } - } - - if len(c.AuthInfos) == 0 { - return ErrMissingConfig{ - What: "At least one Authentication Information (User) needs to be defined", - } - } - if len(c.Contexts) == 0 { return ErrMissingConfig{ What: "At least one Context needs to be defined", @@ -560,113 +342,6 @@ func (c *Config) SetKubeConfig(kubeConfig *clientcmdapi.Config) { c.kubeConfig = kubeConfig } -// GetCluster returns a cluster instance -func (c *Config) GetCluster(cName, cType string) (*Cluster, error) { - _, exists := c.Clusters[cName] - if !exists { - return nil, ErrMissingConfig{What: fmt.Sprintf("Cluster with name '%s' of type '%s'", cName, cType)} - } - // Alternative to this would be enhance Cluster.String() to embed the appropriate kubeconfig cluster information - cluster, exists := c.Clusters[cName].ClusterTypes[cType] - if !exists { - return nil, ErrMissingConfig{What: fmt.Sprintf("Cluster with name '%s' of type '%s'", cName, cType)} - } - return cluster, nil -} - -// AddCluster creates a new cluster and returns the -// newly created cluster object -func (c *Config) AddCluster(theCluster *ClusterOptions) (*Cluster, error) { - // Need to create new cluster placeholder - // Get list of ClusterPurposes that match the theCluster.name - // Cluster might exists, but ClusterPurpose should not - _, exists := c.Clusters[theCluster.Name] - if !exists { - c.Clusters[theCluster.Name] = NewClusterPurpose() - } - // Create the new Airship config Cluster - nCluster := NewCluster() - c.Clusters[theCluster.Name].ClusterTypes[theCluster.ClusterType] = nCluster - // Create a new KubeConfig Cluster object as well - kcluster := clientcmdapi.NewCluster() - clusterName := NewClusterComplexName(theCluster.Name, theCluster.ClusterType) - nCluster.NameInKubeconf = clusterName.String() - nCluster.SetKubeCluster(kcluster) - - c.KubeConfig().Clusters[clusterName.String()] = kcluster - - // Ok , I have initialized structs for the Cluster information - // We can use Modify to populate the correct information - return c.ModifyCluster(nCluster, theCluster) -} - -// ModifyCluster updates cluster object with given cluster options -func (c *Config) ModifyCluster(cluster *Cluster, theCluster *ClusterOptions) (*Cluster, error) { - kcluster := cluster.KubeCluster() - if kcluster == nil { - return cluster, nil - } - if theCluster.Server != "" { - kcluster.Server = theCluster.Server - } - if theCluster.InsecureSkipTLSVerify { - kcluster.InsecureSkipTLSVerify = theCluster.InsecureSkipTLSVerify - // Specifying insecur mode clears any certificate authority - if kcluster.InsecureSkipTLSVerify { - kcluster.CertificateAuthority = "" - kcluster.CertificateAuthorityData = nil - } - } - if theCluster.CertificateAuthority == "" { - return cluster, nil - } - - if theCluster.EmbedCAData { - readData, err := ioutil.ReadFile(theCluster.CertificateAuthority) - kcluster.CertificateAuthorityData = readData - if err != nil { - return cluster, err - } - kcluster.InsecureSkipTLSVerify = false - kcluster.CertificateAuthority = "" - } else { - caPath, err := filepath.Abs(theCluster.CertificateAuthority) - if err != nil { - return cluster, err - } - kcluster.CertificateAuthority = caPath - // Specifying a certificate authority file clears certificate authority data and insecure mode - if caPath != "" { - kcluster.InsecureSkipTLSVerify = false - kcluster.CertificateAuthorityData = nil - } - } - return cluster, nil -} - -// GetClusters returns all of the clusters associated with the Config sorted by name -func (c *Config) GetClusters() []*Cluster { - keys := make([]string, 0, len(c.Clusters)) - for name := range c.Clusters { - keys = append(keys, name) - } - sort.Strings(keys) - - clusters := make([]*Cluster, 0, len(c.Clusters)) - for _, name := range keys { - for _, clusterType := range AllClusterTypes { - cluster, exists := c.Clusters[name].ClusterTypes[clusterType] - if exists { - // If it doesn't exist, then there must not be - // a cluster with this name/type combination. - // This is expected behavior - clusters = append(clusters, cluster) - } - } - } - return clusters -} - // GetContext returns a context instance func (c *Config) GetContext(cName string) (*Context, error) { context, exists := c.Contexts[cName] @@ -707,30 +382,19 @@ func (c *Config) AddContext(theContext *ContextOptions) *Context { // Create the new Airship config context nContext := NewContext() c.Contexts[theContext.Name] = nContext - // Create a new KubeConfig Context object as well - context := clientcmdapi.NewContext() nContext.NameInKubeconf = theContext.Name - nContext.SetKubeContext(context) - c.KubeConfig().Contexts[theContext.Name] = context - // Ok , I have initialized structs for the Context information // We can use Modify to populate the correct information c.ModifyContext(nContext, theContext) + nContext.ClusterType() return nContext } // ModifyContext updates Context object with given given context options func (c *Config) ModifyContext(context *Context, theContext *ContextOptions) { - kubeContext := context.KubeContext() - if kubeContext == nil { - return - } - if theContext.Cluster != "" { - kubeContext.Cluster = theContext.Cluster - } - if theContext.AuthInfo != "" { - kubeContext.AuthInfo = theContext.AuthInfo + if theContext.ManagementConfiguration != "" { + context.ManagementConfiguration = theContext.ManagementConfiguration } if theContext.Manifest != "" { context.Manifest = theContext.Manifest @@ -738,16 +402,11 @@ func (c *Config) ModifyContext(context *Context, theContext *ContextOptions) { if theContext.EncryptionConfig != "" { context.EncryptionConfig = theContext.EncryptionConfig } - if theContext.Namespace != "" { - kubeContext.Namespace = theContext.Namespace - } } // GetCurrentContext methods Returns the appropriate information for the current context // Current Context holds labels for the approriate config objects -// Cluster is the name of the cluster for this context // ClusterType is the name of the clustertype for this context, it should be a flag we pass to it?? -// AuthInfo is the name of the authInfo for this context // Manifest is the default manifest to be use with this context // Purpose for this method is simplifying the current context information func (c *Config) GetCurrentContext() (*Context, error) { @@ -759,27 +418,6 @@ func (c *Config) GetCurrentContext() (*Context, error) { return currentContext, nil } -// CurrentContextCluster returns the Cluster for the current context -func (c *Config) CurrentContextCluster() (*Cluster, error) { - currentContext, err := c.GetCurrentContext() - if err != nil { - return nil, err - } - clusterName := NewClusterComplexNameFromKubeClusterName(currentContext.KubeContext().Cluster) - - return c.Clusters[clusterName.Name].ClusterTypes[currentContext.ClusterType()], nil -} - -// CurrentContextAuthInfo returns the AuthInfo for the current context -func (c *Config) CurrentContextAuthInfo() (*AuthInfo, error) { - currentContext, err := c.GetCurrentContext() - if err != nil { - return nil, err - } - - return c.AuthInfos[currentContext.KubeContext().AuthInfo], nil -} - // CurrentContextManifest returns the manifest for the current context func (c *Config) CurrentContextManifest() (*Manifest, error) { currentContext, err := c.GetCurrentContext() @@ -798,10 +436,6 @@ func (c *Config) CurrentContextEntryPoint(phase string) (string, error) { return "", err } - err = ValidClusterType(clusterType) - if err != nil { - return "", err - } ccm, err := c.CurrentContextManifest() if err != nil { return "", err @@ -844,167 +478,6 @@ func (c *Config) CurrentContextClusterName() (string, error) { return context.ClusterName(), nil } -// GetAuthInfo returns an instance of authino -// Credential or AuthInfo related methods -func (c *Config) GetAuthInfo(aiName string) (*AuthInfo, error) { - authinfo, exists := c.AuthInfos[aiName] - if !exists { - return nil, ErrMissingConfig{What: fmt.Sprintf("User credentials with name '%s'", aiName)} - } - decodedAuthInfo, err := DecodeAuthInfo(authinfo.authInfo) - if err != nil { - return nil, err - } - authinfo.authInfo = decodedAuthInfo - return authinfo, nil -} - -// GetAuthInfos returns a slice containing all the AuthInfos associated with -// the Config sorted by name -func (c *Config) GetAuthInfos() ([]*AuthInfo, error) { - keys := make([]string, 0, len(c.AuthInfos)) - for name := range c.AuthInfos { - keys = append(keys, name) - } - sort.Strings(keys) - - authInfos := make([]*AuthInfo, 0, len(c.AuthInfos)) - for _, name := range keys { - decodedAuthInfo, err := DecodeAuthInfo(c.AuthInfos[name].authInfo) - if err != nil { - return []*AuthInfo{}, err - } - c.AuthInfos[name].authInfo = decodedAuthInfo - authInfos = append(authInfos, c.AuthInfos[name]) - } - return authInfos, nil -} - -// AddAuthInfo creates new AuthInfo with context details updated -// in the airship config and kube config -func (c *Config) AddAuthInfo(theAuthInfo *AuthInfoOptions) *AuthInfo { - // Create the new Airship config context - nAuthInfo := NewAuthInfo() - c.AuthInfos[theAuthInfo.Name] = nAuthInfo - // Create a new KubeConfig AuthInfo object as well - authInfo := clientcmdapi.NewAuthInfo() - nAuthInfo.authInfo = authInfo - c.KubeConfig().AuthInfos[theAuthInfo.Name] = authInfo - - c.ModifyAuthInfo(nAuthInfo, theAuthInfo) - return nAuthInfo -} - -// ModifyAuthInfo updates the AuthInfo in the Config object -func (c *Config) ModifyAuthInfo(authinfo *AuthInfo, theAuthInfo *AuthInfoOptions) { - kubeAuthInfo := EncodeAuthInfo(authinfo.KubeAuthInfo()) - if kubeAuthInfo == nil { - return - } - if theAuthInfo.ClientCertificate != "" { - kubeAuthInfo.ClientCertificate = EncodeString(theAuthInfo.ClientCertificate) - } - if theAuthInfo.Token != "" { - kubeAuthInfo.Token = EncodeString(theAuthInfo.Token) - } - if theAuthInfo.Username != "" { - kubeAuthInfo.Username = theAuthInfo.Username - } - if theAuthInfo.Password != "" { - kubeAuthInfo.Password = EncodeString(theAuthInfo.Password) - } - if theAuthInfo.ClientKey != "" { - kubeAuthInfo.ClientKey = EncodeString(theAuthInfo.ClientKey) - } -} - -// ImportFromKubeConfig absorbs the clusters, contexts and credentials from the -// given kubeConfig -func (c *Config) ImportFromKubeConfig(kubeConfigPath string) error { - _, err := os.Stat(kubeConfigPath) - if err != nil { - return err - } - - kubeConfig, err := clientcmd.LoadFromFile(kubeConfigPath) - if err != nil { - return err - } - c.importClusters(kubeConfig) - c.importContexts(kubeConfig) - c.importAuthInfos(kubeConfig) - return c.PersistConfig(true) -} - -func (c *Config) importClusters(importKubeConfig *clientcmdapi.Config) { - for clusterName, cluster := range importKubeConfig.Clusters { - clusterComplexName := NewClusterComplexNameFromKubeClusterName(clusterName) - if _, err := c.GetCluster(clusterComplexName.Name, clusterComplexName.Type); err == nil { - // err == nil implies that we were successfully able to - // get the cluster from the existing configuration. - // Since existing clusters takes precedence, skip this cluster - continue - } - - // Initialize the new cluster for the airship configuration - airshipCluster := NewCluster() - airshipCluster.NameInKubeconf = clusterComplexName.String() - // Store the reference to the KubeConfig Cluster in the Airship Config - airshipCluster.SetKubeCluster(cluster) - - // Update the airship configuration - if _, ok := c.Clusters[clusterComplexName.Name]; !ok { - c.Clusters[clusterComplexName.Name] = NewClusterPurpose() - } - c.Clusters[clusterComplexName.Name].ClusterTypes[clusterComplexName.Type] = airshipCluster - c.kubeConfig.Clusters[clusterComplexName.String()] = cluster - } -} - -func (c *Config) importContexts(importKubeConfig *clientcmdapi.Config) { - // TODO(howell): This function doesn't handle the case when an incoming - // context refers to a cluster that doesn't exist in the airship - // configuration. - for kubeContextName, kubeContext := range importKubeConfig.Contexts { - if _, ok := c.kubeConfig.Contexts[kubeContextName]; ok { - // Since existing contexts take precedence, skip this context - continue - } - - clusterComplexName := NewClusterComplexNameFromKubeClusterName(kubeContext.Cluster) - if kubeContext.Cluster != clusterComplexName.String() { - // If the name of cluster from the kubeConfig doesn't - // match the clusterComplexName, it needs to be updated - kubeContext.Cluster = clusterComplexName.String() - } - - airshipContext, ok := c.Contexts[kubeContextName] - if !ok { - airshipContext = NewContext() - } - airshipContext.NameInKubeconf = kubeContext.Cluster - airshipContext.Manifest = AirshipDefaultManifest - airshipContext.SetKubeContext(kubeContext) - - // Store the contexts in the airship configuration - c.Contexts[kubeContextName] = airshipContext - c.kubeConfig.Contexts[kubeContextName] = kubeContext - } -} - -func (c *Config) importAuthInfos(importKubeConfig *clientcmdapi.Config) { - for key, authinfo := range importKubeConfig.AuthInfos { - if _, ok := c.AuthInfos[key]; ok { - // Since existing credentials take precedence, skip this credential - continue - } - - c.AuthInfos[key] = NewAuthInfo() - c.AuthInfos[key].SetKubeAuthInfo(authinfo) - c.kubeConfig.AuthInfos[key] = authinfo - } -} - // GetManifests returns all of the Manifests associated with the Config sorted by name func (c *Config) GetManifests() []*Manifest { keys := make([]string, 0, len(c.Manifests)) @@ -1164,20 +637,20 @@ func (c *Config) ModifyEncryptionConfig(encryptionConfig *EncryptionConfig, opti // CurrentContextManagementConfig returns the management options for the current context func (c *Config) CurrentContextManagementConfig() (*ManagementConfiguration, error) { - currentCluster, err := c.CurrentContextCluster() + currentContext, err := c.GetCurrentContext() if err != nil { return nil, err } - if currentCluster.ManagementConfiguration == "" { + if currentContext.ManagementConfiguration == "" { return nil, ErrMissingConfig{ - What: fmt.Sprintf("No management config listed for cluster %s", currentCluster.NameInKubeconf), + What: fmt.Sprintf("No management config listed for cluster %s", currentContext.NameInKubeconf), } } - managementCfg, exists := c.ManagementConfiguration[currentCluster.ManagementConfiguration] + managementCfg, exists := c.ManagementConfiguration[currentContext.ManagementConfiguration] if !exists { - return nil, ErrMissingManagementConfiguration{cluster: currentCluster} + return nil, ErrMissingManagementConfiguration{context: currentContext} } return managementCfg, nil @@ -1205,44 +678,3 @@ func (c *Config) CurrentContextManifestMetadata() (*Metadata, error) { } return meta, nil } - -// DecodeAuthInfo returns authInfo with credentials decoded -func DecodeAuthInfo(authinfo *clientcmdapi.AuthInfo) (*clientcmdapi.AuthInfo, error) { - password := authinfo.Password - decodedPassword, err := DecodeString(password) - if err != nil { - return nil, ErrDecodingCredentials{Given: password} - } - authinfo.Password = decodedPassword - - token := authinfo.Token - decodedToken, err := DecodeString(token) - if err != nil { - return nil, ErrDecodingCredentials{Given: token} - } - authinfo.Token = decodedToken - - clientCert := authinfo.ClientCertificate - decodedClientCertificate, err := DecodeString(clientCert) - if err != nil { - return nil, ErrDecodingCredentials{Given: clientCert} - } - authinfo.ClientCertificate = decodedClientCertificate - - clientKey := authinfo.ClientKey - decodedClientKey, err := DecodeString(clientKey) - if err != nil { - return nil, ErrDecodingCredentials{Given: clientKey} - } - authinfo.ClientKey = decodedClientKey - return authinfo, nil -} - -// EncodeAuthInfo returns authInfo with credentials base64 encoded -func EncodeAuthInfo(authinfo *clientcmdapi.AuthInfo) *clientcmdapi.AuthInfo { - authinfo.Password = EncodeString(authinfo.Password) - authinfo.Token = EncodeString(authinfo.Token) - authinfo.ClientCertificate = EncodeString(authinfo.ClientCertificate) - authinfo.ClientKey = EncodeString(authinfo.ClientKey) - return authinfo -} diff --git a/pkg/config/config_helper.go b/pkg/config/config_helper.go index 4e9be8193..24a273949 100644 --- a/pkg/config/config_helper.go +++ b/pkg/config/config_helper.go @@ -20,86 +20,6 @@ import ( "errors" ) -// RunSetAuthInfo validates the given command line options and invokes AddAuthInfo/ModifyAuthInfo -func RunSetAuthInfo(o *AuthInfoOptions, airconfig *Config, writeToStorage bool) (bool, error) { - modified := false - err := o.Validate() - if err != nil { - return modified, err - } - - authinfo, err := airconfig.GetAuthInfo(o.Name) - if err != nil { - var cerr ErrMissingConfig - if !errors.As(err, &cerr) { - // An error occurred, but it wasn't a "missing" config error. - return modified, err - } - - // authinfo didn't exist, create it - // ignoring the returned added authinfo - airconfig.AddAuthInfo(o) - } else { - // AuthInfo exists, lets update - airconfig.ModifyAuthInfo(authinfo, o) - modified = true - } - // Update configuration file just in time persistence approach - if writeToStorage { - if err := airconfig.PersistConfig(true); err != nil { - // Error that it didnt persist the changes - return modified, ErrConfigFailed{} - } - } - - return modified, nil -} - -// RunSetCluster validates the given command line options and invokes AddCluster/ModifyCluster -func RunSetCluster(o *ClusterOptions, airconfig *Config, writeToStorage bool) (bool, error) { - modified := false - err := o.Validate() - if err != nil { - return modified, err - } - - cluster, err := airconfig.GetCluster(o.Name, o.ClusterType) - if err != nil { - var cerr ErrMissingConfig - if !errors.As(err, &cerr) { - // An error occurred, but it wasn't a "missing" config error. - return modified, err - } - - // Cluster didn't exist, create it - _, err := airconfig.AddCluster(o) - if err != nil { - return modified, err - } - modified = false - } else { - // Cluster exists, lets update - _, err := airconfig.ModifyCluster(cluster, o) - if err != nil { - return modified, err - } - modified = true - } - - // Update configuration file - // Just in time persistence approach - if writeToStorage { - if err := airconfig.PersistConfig(true); err != nil { - // Some warning here , that it didnt persist the changes because of this - // Or should we float this up - // What would it mean? No value. - return modified, err - } - } - - return modified, nil -} - // RunSetContext validates the given command line options and invokes AddContext/ModifyContext func RunSetContext(o *ContextOptions, airconfig *Config, writeToStorage bool) (bool, error) { modified := false diff --git a/pkg/config/config_helper_test.go b/pkg/config/config_helper_test.go index 6d4272a3a..d3513813c 100644 --- a/pkg/config/config_helper_test.go +++ b/pkg/config/config_helper_test.go @@ -25,61 +25,6 @@ import ( "opendev.org/airship/airshipctl/testutil" ) -func TestRunSetAuthInfo(t *testing.T) { - t.Run("testAddAuthInfo", func(t *testing.T) { - conf := testutil.DummyConfig() - dummyAuthInfoOptions := testutil.DummyAuthInfoOptions() - dummyAuthInfoOptions.Name = "second_user" - dummyAuthInfoOptions.Token = "" - - modified, err := config.RunSetAuthInfo(dummyAuthInfoOptions, conf, false) - assert.NoError(t, err) - assert.False(t, modified) - assert.Contains(t, conf.AuthInfos, "second_user") - }) - - t.Run("testModifyAuthInfo", func(t *testing.T) { - conf := testutil.DummyConfig() - dummyAuthInfoOptions := testutil.DummyAuthInfoOptions() - dummyAuthInfoOptions.Name = "dummy_user" - dummyAuthInfoOptions.Password = "testpassword123" - dummyAuthInfoOptions.Token = "" - - modified, err := config.RunSetAuthInfo(dummyAuthInfoOptions, conf, false) - assert.NoError(t, err) - assert.True(t, modified) - authInfo, err := conf.GetAuthInfo("dummy_user") - assert.NoError(t, err) - assert.Equal(t, dummyAuthInfoOptions.Password, authInfo.KubeAuthInfo().Password) - }) -} - -func TestRunSetCluster(t *testing.T) { - t.Run("testAddCluster", func(t *testing.T) { - conf := testutil.DummyConfig() - dummyClusterOptions := testutil.DummyClusterOptions() - dummyClusterOptions.Name = "second_cluster" - - modified, err := config.RunSetCluster(dummyClusterOptions, conf, false) - assert.NoError(t, err) - assert.False(t, modified) - assert.Contains(t, conf.Clusters, "second_cluster") - }) - - t.Run("testModifyCluster", func(t *testing.T) { - conf := testutil.DummyConfig() - dummyClusterOptions := testutil.DummyClusterOptions() - dummyClusterOptions.Server = "http://123.45.67.890" - - modified, err := config.RunSetCluster(dummyClusterOptions, conf, false) - assert.NoError(t, err) - assert.True(t, modified) - assert.Equal( - t, "http://123.45.67.890", - conf.Clusters["dummy_cluster"].ClusterTypes["ephemeral"].KubeCluster().Server) - }) -} - func TestRunSetContext(t *testing.T) { t.Run("testAddContext", func(t *testing.T) { conf := testutil.DummyConfig() @@ -95,12 +40,10 @@ func TestRunSetContext(t *testing.T) { t.Run("testModifyContext", func(t *testing.T) { conf := testutil.DummyConfig() dummyContextOptions := testutil.DummyContextOptions() - dummyContextOptions.Namespace = "new_namespace" modified, err := config.RunSetContext(dummyContextOptions, conf, false) assert.NoError(t, err) assert.True(t, modified) - assert.Equal(t, "new_namespace", conf.Contexts["dummy_context"].KubeContext().Namespace) }) } diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 8e5fb1bef..79938e2a2 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -18,9 +18,7 @@ package config_test import ( "fmt" - "io/ioutil" "os" - "path/filepath" "strings" "testing" @@ -35,10 +33,6 @@ const ( stringDelta = "_changed" currentContextName = "def_ephemeral" defaultString = "default" - newToken = "dummy_token_changed" - newPassword = "dummy_password_changed" - newCertificate = "dummy_certificate_changed" - newKey = "dummy_key_changed" ) func TestString(t *testing.T) { @@ -56,14 +50,6 @@ func TestString(t *testing.T) { name: "context", stringer: testutil.DummyContext(), }, - { - name: "cluster", - stringer: testutil.DummyCluster(), - }, - { - name: "authinfo", - stringer: testutil.DummyAuthInfo(), - }, { name: "manifest", stringer: testutil.DummyManifest(), @@ -106,11 +92,7 @@ func TestLoadConfig(t *testing.T) { conf, cleanup := testutil.InitConfig(t) defer cleanup(t) - assert.Len(t, conf.Clusters, 6) - require.Contains(t, conf.Clusters, "def") - assert.Len(t, conf.Clusters["def"].ClusterTypes, 2) - assert.Len(t, conf.Contexts, 3) - assert.Len(t, conf.AuthInfos, 3) + assert.Len(t, conf.Contexts, 4) } func TestPersistConfig(t *testing.T) { @@ -124,13 +106,7 @@ func TestPersistConfig(t *testing.T) { assert.FileExists(t, conf.LoadedConfigPath()) assert.FileExists(t, conf.KubeConfigPath()) // Check that the invalid name was changed to a valid one - assert.Contains(t, conf.KubeConfig().Clusters, "invalidName_target") - - // Check that the missing cluster was added to the airshipconfig - assert.Contains(t, conf.Clusters, "onlyinkubeconf") - - // Check that the "stragglers" were removed from the airshipconfig - assert.NotContains(t, conf.Clusters, "straggler") + assert.Contains(t, conf.KubeConfig().Clusters, "def_ephemeral") } func TestEnsureComplete(t *testing.T) { @@ -143,33 +119,9 @@ func TestEnsureComplete(t *testing.T) { config config.Config expectedErr error }{ - { - name: "no clusters defined", - config: config.Config{ - Clusters: map[string]*config.ClusterPurpose{}, - AuthInfos: map[string]*config.AuthInfo{"testAuthInfo": {}}, - Contexts: map[string]*config.Context{"testContext": {Manifest: "testManifest"}}, - Manifests: map[string]*config.Manifest{"testManifest": {}}, - CurrentContext: "testContext", - }, - expectedErr: config.ErrMissingConfig{What: "At least one cluster needs to be defined"}, - }, - { - name: "no users defined", - config: config.Config{ - Clusters: map[string]*config.ClusterPurpose{"testCluster": {}}, - AuthInfos: map[string]*config.AuthInfo{}, - Contexts: map[string]*config.Context{"testContext": {Manifest: "testManifest"}}, - Manifests: map[string]*config.Manifest{"testManifest": {}}, - CurrentContext: "testContext", - }, - expectedErr: config.ErrMissingConfig{What: "At least one Authentication Information (User) needs to be defined"}, - }, { name: "no contexts defined", config: config.Config{ - Clusters: map[string]*config.ClusterPurpose{"testCluster": {}}, - AuthInfos: map[string]*config.AuthInfo{"testAuthInfo": {}}, Contexts: map[string]*config.Context{}, Manifests: map[string]*config.Manifest{"testManifest": {}}, CurrentContext: "testContext", @@ -179,8 +131,6 @@ func TestEnsureComplete(t *testing.T) { { name: "no manifests defined", config: config.Config{ - Clusters: map[string]*config.ClusterPurpose{"testCluster": {}}, - AuthInfos: map[string]*config.AuthInfo{"testAuthInfo": {}}, Contexts: map[string]*config.Context{"testContext": {Manifest: "testManifest"}}, Manifests: map[string]*config.Manifest{}, CurrentContext: "testContext", @@ -190,8 +140,6 @@ func TestEnsureComplete(t *testing.T) { { name: "current context not defined", config: config.Config{ - Clusters: map[string]*config.ClusterPurpose{"testCluster": {}}, - AuthInfos: map[string]*config.AuthInfo{"testAuthInfo": {}}, Contexts: map[string]*config.Context{"testContext": {Manifest: "testManifest"}}, Manifests: map[string]*config.Manifest{"testManifest": {}}, CurrentContext: "", @@ -201,8 +149,6 @@ func TestEnsureComplete(t *testing.T) { { name: "no context for current context", config: config.Config{ - Clusters: map[string]*config.ClusterPurpose{"testCluster": {}}, - AuthInfos: map[string]*config.AuthInfo{"testAuthInfo": {}}, Contexts: map[string]*config.Context{"DIFFERENT_CONTEXT": {Manifest: "testManifest"}}, Manifests: map[string]*config.Manifest{"testManifest": {}}, CurrentContext: "testContext", @@ -212,8 +158,6 @@ func TestEnsureComplete(t *testing.T) { { name: "no manifest for current context", config: config.Config{ - Clusters: map[string]*config.ClusterPurpose{"testCluster": {}}, - AuthInfos: map[string]*config.AuthInfo{"testAuthInfo": {}}, Contexts: map[string]*config.Context{"testContext": {Manifest: "testManifest"}}, Manifests: map[string]*config.Manifest{"DIFFERENT_MANIFEST": {}}, CurrentContext: "testContext", @@ -223,11 +167,9 @@ func TestEnsureComplete(t *testing.T) { { name: "complete config", config: config.Config{ - Clusters: map[string]*config.ClusterPurpose{"testCluster": {}}, - AuthInfos: map[string]*config.AuthInfo{"testAuthInfo": {}}, + EncryptionConfigs: map[string]*config.EncryptionConfig{"testEncryptionConfig": {}}, Contexts: map[string]*config.Context{"testContext": {Manifest: "testManifest"}}, Manifests: map[string]*config.Manifest{"testManifest": {}}, - EncryptionConfigs: map[string]*config.EncryptionConfig{"testEncryptionConfig": {}}, CurrentContext: "testContext", }, expectedErr: nil, @@ -247,17 +189,13 @@ func TestCurrentContextManagementConfig(t *testing.T) { conf, cleanup := testutil.InitConfig(t) defer cleanup(t) - clusterName := "def" - clusterType := "ephemeral" - managementConfig, err := conf.CurrentContextManagementConfig() require.Error(t, err) assert.Nil(t, managementConfig) conf.CurrentContext = currentContextName - conf.Clusters[clusterName].ClusterTypes[clusterType].ManagementConfiguration = defaultString + conf.Contexts[currentContextName].ManagementConfiguration = defaultString conf.Contexts[currentContextName].Manifest = defaultString - conf.Contexts[currentContextName].KubeContext().Cluster = clusterName managementConfig, err = conf.CurrentContextManagementConfig() require.NoError(t, err) @@ -308,42 +246,12 @@ func TestSetKubeConfigPath(t *testing.T) { assert.Equal(t, testPath, conf.KubeConfigPath()) } -func TestModifyCluster(t *testing.T) { - conf, cleanup := testutil.InitConfig(t) - defer cleanup(t) - - co := testutil.DummyClusterOptions() - cluster, err := conf.AddCluster(co) - require.NoError(t, err) - - co.Server += stringDelta - co.InsecureSkipTLSVerify = true - co.EmbedCAData = true - mcluster, err := conf.ModifyCluster(cluster, co) - require.NoError(t, err) - assert.EqualValues(t, conf.Clusters[co.Name].ClusterTypes[co.ClusterType].KubeCluster().Server, co.Server) - assert.EqualValues(t, conf.Clusters[co.Name].ClusterTypes[co.ClusterType], mcluster) - - // Error case - co.CertificateAuthority = "unknown" - _, err = conf.ModifyCluster(cluster, co) - assert.Error(t, err) -} - -func TestGetClusters(t *testing.T) { - conf, cleanup := testutil.InitConfig(t) - defer cleanup(t) - - clusters := conf.GetClusters() - assert.Len(t, clusters, 6) -} - func TestGetContexts(t *testing.T) { conf, cleanup := testutil.InitConfig(t) defer cleanup(t) contexts := conf.GetContexts() - assert.Len(t, contexts, 3) + assert.Len(t, contexts, 4) } func TestGetContext(t *testing.T) { @@ -355,7 +263,6 @@ func TestGetContext(t *testing.T) { // Test Positives assert.EqualValues(t, context.NameInKubeconf, "def_ephemeral") - assert.EqualValues(t, context.KubeContext().Cluster, "def_ephemeral") // Test Wrong Cluster _, err = conf.GetContext("unknown") @@ -378,14 +285,8 @@ func TestModifyContext(t *testing.T) { co := testutil.DummyContextOptions() context := conf.AddContext(co) - co.Namespace += stringDelta - co.Cluster += stringDelta - co.AuthInfo += stringDelta co.Manifest += stringDelta conf.ModifyContext(context, co) - assert.EqualValues(t, conf.Contexts[co.Name].KubeContext().Namespace, co.Namespace) - assert.EqualValues(t, conf.Contexts[co.Name].KubeContext().Cluster, co.Cluster) - assert.EqualValues(t, conf.Contexts[co.Name].KubeContext().AuthInfo, co.AuthInfo) assert.EqualValues(t, conf.Contexts[co.Name].Manifest, co.Manifest) assert.EqualValues(t, conf.Contexts[co.Name], context) } @@ -408,55 +309,16 @@ func TestGetCurrentContext(t *testing.T) { }) } -func TestCurrentContextCluster(t *testing.T) { - conf, cleanup := testutil.InitConfig(t) - defer cleanup(t) - - clusterName := "def" - clusterType := "ephemeral" - - cluster, err := conf.CurrentContextCluster() - require.Error(t, err) - assert.Nil(t, cluster) - - conf.CurrentContext = currentContextName - conf.Contexts[currentContextName].Manifest = defaultString - conf.Contexts[currentContextName].KubeContext().Cluster = clusterName - - cluster, err = conf.CurrentContextCluster() - require.NoError(t, err) - assert.Equal(t, conf.Clusters[clusterName].ClusterTypes[clusterType], cluster) -} - -func TestCurrentContextAuthInfo(t *testing.T) { - conf, cleanup := testutil.InitConfig(t) - defer cleanup(t) - - authInfo, err := conf.CurrentContextAuthInfo() - require.Error(t, err) - assert.Nil(t, authInfo) - - conf.CurrentContext = currentContextName - conf.Contexts[currentContextName].Manifest = defaultString - - authInfo, err = conf.CurrentContextAuthInfo() - require.NoError(t, err) - assert.Equal(t, conf.AuthInfos["k-admin"], authInfo) -} - func TestCurrentContextManifest(t *testing.T) { conf, cleanup := testutil.InitConfig(t) defer cleanup(t) - clusterName := "def" - manifest, err := conf.CurrentContextManifest() require.Error(t, err) assert.Nil(t, manifest) conf.CurrentContext = currentContextName conf.Contexts[currentContextName].Manifest = defaultString - conf.Contexts[currentContextName].KubeContext().Cluster = clusterName manifest, err = conf.CurrentContextManifest() require.NoError(t, err) @@ -467,15 +329,12 @@ func TestCurrentTargetPath(t *testing.T) { conf, cleanup := testutil.InitConfig(t) defer cleanup(t) - clusterName := "def" - manifest, err := conf.CurrentContextManifest() require.Error(t, err) assert.Nil(t, manifest) conf.CurrentContext = currentContextName conf.Contexts[currentContextName].Manifest = defaultString - conf.Contexts[currentContextName].KubeContext().Cluster = clusterName targetPath, err := conf.CurrentContextTargetPath() require.NoError(t, err) @@ -486,15 +345,12 @@ func TestCurrentContextEntryPoint(t *testing.T) { conf, cleanup := testutil.InitConfig(t) defer cleanup(t) - clusterName := "def" - entryPoint, err := conf.CurrentContextEntryPoint(defaultString) require.Error(t, err) assert.Equal(t, "", entryPoint) conf.CurrentContext = currentContextName conf.Contexts[currentContextName].Manifest = defaultString - conf.Contexts[currentContextName].KubeContext().Cluster = clusterName entryPoint, err = conf.CurrentContextEntryPoint(defaultString) assert.Equal(t, config.ErrMissingPhaseDocument{PhaseName: defaultString}, err) @@ -661,144 +517,6 @@ func TestNewClusterComplexNameFromKubeClusterName(t *testing.T) { } } -func TestImport(t *testing.T) { - conf, cleanupConfig := testutil.InitConfig(t) - defer cleanupConfig(t) - - kubeDir, cleanupKubeConfig := testutil.TempDir(t, "airship-import-tests") - defer cleanupKubeConfig(t) - - kubeConfigPath := filepath.Join(kubeDir, "config") - //nolint: lll - kubeConfigContent := ` -apiVersion: v1 -clusters: -- cluster: - server: https://1.2.3.4:9000 - name: cluster_target -- cluster: - server: https://1.2.3.4:9001 - name: dummycluster_ephemeral -- cluster: - server: https://1.2.3.4:9002 - name: def_target -- cluster: - server: https://1.2.3.4:9003 - name: noncomplex -contexts: -- context: - cluster: cluster_target - user: cluster-admin - name: cluster-admin@cluster -- context: - cluster: dummycluster_ephemeral - user: kubernetes-admin - name: dummy_cluster -- context: - cluster: dummycluster_ephemeral - user: kubernetes-admin - name: def_target -- context: - cluster: noncomplex - user: kubernetes-admin - name: noncomplex -current-context: dummy_cluster -kind: Config -preferences: {} -users: -- name: cluster-admin - user: - client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM4akNDQWRxZ0F3SUJBZ0lJQXhEdzk2RUY4SXN3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB4T1RBNU1qa3hOekF6TURsYUZ3MHlNREE1TWpneE56QXpNVEphTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXV6R0pZdlBaNkRvaTQyMUQKSzhXSmFaQ25OQWQycXo1cC8wNDJvRnpRUGJyQWd6RTJxWVZrek9MOHhBVmVSN1NONXdXb1RXRXlGOEVWN3JyLwo0K0hoSEdpcTVQbXF1SUZ5enpuNi9JWmM4alU5eEVmenZpa2NpckxmVTR2UlhKUXdWd2dBU05sMkFXQUloMmRECmRUcmpCQ2ZpS1dNSHlqMFJiSGFsc0J6T3BnVC9IVHYzR1F6blVRekZLdjJkajVWMU5rUy9ESGp5UlJKK0VMNlEKQlltR3NlZzVQNE5iQzllYnVpcG1NVEFxL0p1bU9vb2QrRmpMMm5acUw2Zkk2ZkJ0RjVPR2xwQ0IxWUo4ZnpDdApHUVFaN0hUSWJkYjJ0cDQzRlZPaHlRYlZjSHFUQTA0UEoxNSswV0F5bVVKVXo4WEE1NDRyL2J2NzRKY0pVUkZoCmFyWmlRd0lEQVFBQm95Y3dKVEFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFMMmhIUmVibEl2VHJTMFNmUVg1RG9ueVVhNy84aTg1endVWApSd3dqdzFuS0U0NDJKbWZWRGZ5b0hRYUM4Ti9MQkxyUXM0U0lqU1JYdmFHU1dSQnRnT1RRV21Db1laMXdSbjdwCndDTXZQTERJdHNWWm90SEZpUFl2b1lHWFFUSXA3YlROMmg1OEJaaEZ3d25nWUovT04zeG1rd29IN1IxYmVxWEYKWHF1TTluekhESk41VlZub1lQR09yRHMwWlg1RnNxNGtWVU0wVExNQm9qN1ZIRDhmU0E5RjRYNU4yMldsZnNPMAo4aksrRFJDWTAyaHBrYTZQQ0pQS0lNOEJaMUFSMG9ZakZxT0plcXpPTjBqcnpYWHh4S2pHVFVUb1BldVA5dCtCCjJOMVA1TnI4a2oxM0lrend5Q1NZclFVN09ZM3ltZmJobHkrcXZxaFVFa014MlQ1SkpmQT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= - client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBdXpHSll2UFo2RG9pNDIxREs4V0phWkNuTkFkMnF6NXAvMDQyb0Z6UVBickFnekUyCnFZVmt6T0w4eEFWZVI3U041d1dvVFdFeUY4RVY3cnIvNCtIaEhHaXE1UG1xdUlGeXp6bjYvSVpjOGpVOXhFZnoKdmlrY2lyTGZVNHZSWEpRd1Z3Z0FTTmwyQVdBSWgyZERkVHJqQkNmaUtXTUh5ajBSYkhhbHNCek9wZ1QvSFR2MwpHUXpuVVF6Rkt2MmRqNVYxTmtTL0RIanlSUkorRUw2UUJZbUdzZWc1UDROYkM5ZWJ1aXBtTVRBcS9KdW1Pb29kCitGakwyblpxTDZmSTZmQnRGNU9HbHBDQjFZSjhmekN0R1FRWjdIVEliZGIydHA0M0ZWT2h5UWJWY0hxVEEwNFAKSjE1KzBXQXltVUpVejhYQTU0NHIvYnY3NEpjSlVSRmhhclppUXdJREFRQUJBb0lCQVFDU0pycjlaeVpiQ2dqegpSL3VKMFZEWCt2aVF4c01BTUZyUjJsOE1GV3NBeHk1SFA4Vk4xYmc5djN0YUVGYnI1U3hsa3lVMFJRNjNQU25DCm1uM3ZqZ3dVQWlScllnTEl5MGk0UXF5VFBOU1V4cnpTNHRxTFBjM3EvSDBnM2FrNGZ2cSsrS0JBUUlqQnloamUKbnVFc1JpMjRzT3NESlM2UDE5NGlzUC9yNEpIM1M5bFZGbkVuOGxUR2c0M1kvMFZoMXl0cnkvdDljWjR5ZUNpNwpjMHFEaTZZcXJZaFZhSW9RRW1VQjdsbHRFZkZzb3l4VDR6RTE5U3pVbkRoMmxjYTF1TzhqcmI4d2xHTzBoQ2JyClB1R1l2WFFQa3Q0VlNmalhvdGJ3d2lBNFRCVERCRzU1bHp6MmNKeS9zSS8zSHlYbEMxcTdXUmRuQVhhZ1F0VzkKOE9DZGRkb0JBb0dCQU5NcUNtSW94REtyckhZZFRxT1M1ZFN4cVMxL0NUN3ZYZ0pScXBqd2Y4WHA2WHo0KzIvTAozVXFaVDBEL3dGTkZkc1Z4eFYxMnNYMUdwMHFWZVlKRld5OVlCaHVSWGpTZ0ZEWldSY1Z1Y01sNVpPTmJsbmZGCjVKQ0xnNXFMZ1g5VTNSRnJrR3A0R241UDQxamg4TnhKVlhzZG5xWE9xNTFUK1RRT1UzdkpGQjc1QW9HQkFPTHcKalp1cnZtVkZyTHdaVGgvRDNpWll5SVV0ZUljZ2NKLzlzbTh6L0pPRmRIbFd4dGRHUFVzYVd1MnBTNEhvckFtbgpqTm4vSTluUXd3enZ3MWUzVVFPbUhMRjVBczk4VU5hbk5TQ0xNMW1yaXZHRXJ1VHFnTDM1bU41eFZPdTUxQU5JCm4yNkFtODBJT2JDeEtLa0R0ZXJSaFhHd3g5c1pONVJCbG9VRThZNGJBb0dBQ3ZsdVhMZWRxcng5VkE0bDNoNXUKVDJXRVUxYjgxZ1orcmtRc1I1S0lNWEw4cllBTElUNUpHKzFuendyN3BkaEFXZmFWdVV2SDRhamdYT0h6MUs5aQpFODNSVTNGMG9ldUg0V01PY1RwU0prWm0xZUlXcWRiaEVCb1FGdUlWTXRib1BsV0d4ZUhFRHJoOEtreGp4aThSCmdEcUQyajRwY1IzQ0g5QjJ5a0lqQjVFQ2dZRUExc0xXLys2enE1c1lNSm14K1JXZThhTXJmL3pjQnVTSU1LQWgKY0dNK0wwMG9RSHdDaUU4TVNqcVN1ajV3R214YUFuanhMb3ZwSFlRV1VmUEVaUW95UE1YQ2VhRVBLOU4xbk8xMwp0V2lHRytIZkIxaU5PazFCc0lhNFNDbndOM1FRVTFzeXBaeEgxT3hueS9LYmkvYmEvWEZ5VzNqMGFUK2YvVWxrCmJGV1ZVdWtDZ1lFQTBaMmRTTFlmTjV5eFNtYk5xMWVqZXdWd1BjRzQxR2hQclNUZEJxdHFac1doWGE3aDdLTWEKeHdvamh5SXpnTXNyK2tXODdlajhDQ2h0d21sQ1p5QU92QmdOZytncnJ1cEZLM3FOSkpKeU9YREdHckdpbzZmTQp5aXB3Q2tZVGVxRThpZ1J6UkI5QkdFUGY4eVpjMUtwdmZhUDVhM0lRZmxiV0czbGpUemNNZVZjPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo= -- name: kubernetes-admin - user: - client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM4akNDQWRxZ0F3SUJBZ0lJQXhEdzk2RUY4SXN3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB4T1RBNU1qa3hOekF6TURsYUZ3MHlNREE1TWpneE56QXpNVEphTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXV6R0pZdlBaNkRvaTQyMUQKSzhXSmFaQ25OQWQycXo1cC8wNDJvRnpRUGJyQWd6RTJxWVZrek9MOHhBVmVSN1NONXdXb1RXRXlGOEVWN3JyLwo0K0hoSEdpcTVQbXF1SUZ5enpuNi9JWmM4alU5eEVmenZpa2NpckxmVTR2UlhKUXdWd2dBU05sMkFXQUloMmRECmRUcmpCQ2ZpS1dNSHlqMFJiSGFsc0J6T3BnVC9IVHYzR1F6blVRekZLdjJkajVWMU5rUy9ESGp5UlJKK0VMNlEKQlltR3NlZzVQNE5iQzllYnVpcG1NVEFxL0p1bU9vb2QrRmpMMm5acUw2Zkk2ZkJ0RjVPR2xwQ0IxWUo4ZnpDdApHUVFaN0hUSWJkYjJ0cDQzRlZPaHlRYlZjSHFUQTA0UEoxNSswV0F5bVVKVXo4WEE1NDRyL2J2NzRKY0pVUkZoCmFyWmlRd0lEQVFBQm95Y3dKVEFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFMMmhIUmVibEl2VHJTMFNmUVg1RG9ueVVhNy84aTg1endVWApSd3dqdzFuS0U0NDJKbWZWRGZ5b0hRYUM4Ti9MQkxyUXM0U0lqU1JYdmFHU1dSQnRnT1RRV21Db1laMXdSbjdwCndDTXZQTERJdHNWWm90SEZpUFl2b1lHWFFUSXA3YlROMmg1OEJaaEZ3d25nWUovT04zeG1rd29IN1IxYmVxWEYKWHF1TTluekhESk41VlZub1lQR09yRHMwWlg1RnNxNGtWVU0wVExNQm9qN1ZIRDhmU0E5RjRYNU4yMldsZnNPMAo4aksrRFJDWTAyaHBrYTZQQ0pQS0lNOEJaMUFSMG9ZakZxT0plcXpPTjBqcnpYWHh4S2pHVFVUb1BldVA5dCtCCjJOMVA1TnI4a2oxM0lrend5Q1NZclFVN09ZM3ltZmJobHkrcXZxaFVFa014MlQ1SkpmQT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= - client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBdXpHSll2UFo2RG9pNDIxREs4V0phWkNuTkFkMnF6NXAvMDQyb0Z6UVBickFnekUyCnFZVmt6T0w4eEFWZVI3U041d1dvVFdFeUY4RVY3cnIvNCtIaEhHaXE1UG1xdUlGeXp6bjYvSVpjOGpVOXhFZnoKdmlrY2lyTGZVNHZSWEpRd1Z3Z0FTTmwyQVdBSWgyZERkVHJqQkNmaUtXTUh5ajBSYkhhbHNCek9wZ1QvSFR2MwpHUXpuVVF6Rkt2MmRqNVYxTmtTL0RIanlSUkorRUw2UUJZbUdzZWc1UDROYkM5ZWJ1aXBtTVRBcS9KdW1Pb29kCitGakwyblpxTDZmSTZmQnRGNU9HbHBDQjFZSjhmekN0R1FRWjdIVEliZGIydHA0M0ZWT2h5UWJWY0hxVEEwNFAKSjE1KzBXQXltVUpVejhYQTU0NHIvYnY3NEpjSlVSRmhhclppUXdJREFRQUJBb0lCQVFDU0pycjlaeVpiQ2dqegpSL3VKMFZEWCt2aVF4c01BTUZyUjJsOE1GV3NBeHk1SFA4Vk4xYmc5djN0YUVGYnI1U3hsa3lVMFJRNjNQU25DCm1uM3ZqZ3dVQWlScllnTEl5MGk0UXF5VFBOU1V4cnpTNHRxTFBjM3EvSDBnM2FrNGZ2cSsrS0JBUUlqQnloamUKbnVFc1JpMjRzT3NESlM2UDE5NGlzUC9yNEpIM1M5bFZGbkVuOGxUR2c0M1kvMFZoMXl0cnkvdDljWjR5ZUNpNwpjMHFEaTZZcXJZaFZhSW9RRW1VQjdsbHRFZkZzb3l4VDR6RTE5U3pVbkRoMmxjYTF1TzhqcmI4d2xHTzBoQ2JyClB1R1l2WFFQa3Q0VlNmalhvdGJ3d2lBNFRCVERCRzU1bHp6MmNKeS9zSS8zSHlYbEMxcTdXUmRuQVhhZ1F0VzkKOE9DZGRkb0JBb0dCQU5NcUNtSW94REtyckhZZFRxT1M1ZFN4cVMxL0NUN3ZYZ0pScXBqd2Y4WHA2WHo0KzIvTAozVXFaVDBEL3dGTkZkc1Z4eFYxMnNYMUdwMHFWZVlKRld5OVlCaHVSWGpTZ0ZEWldSY1Z1Y01sNVpPTmJsbmZGCjVKQ0xnNXFMZ1g5VTNSRnJrR3A0R241UDQxamg4TnhKVlhzZG5xWE9xNTFUK1RRT1UzdkpGQjc1QW9HQkFPTHcKalp1cnZtVkZyTHdaVGgvRDNpWll5SVV0ZUljZ2NKLzlzbTh6L0pPRmRIbFd4dGRHUFVzYVd1MnBTNEhvckFtbgpqTm4vSTluUXd3enZ3MWUzVVFPbUhMRjVBczk4VU5hbk5TQ0xNMW1yaXZHRXJ1VHFnTDM1bU41eFZPdTUxQU5JCm4yNkFtODBJT2JDeEtLa0R0ZXJSaFhHd3g5c1pONVJCbG9VRThZNGJBb0dBQ3ZsdVhMZWRxcng5VkE0bDNoNXUKVDJXRVUxYjgxZ1orcmtRc1I1S0lNWEw4cllBTElUNUpHKzFuendyN3BkaEFXZmFWdVV2SDRhamdYT0h6MUs5aQpFODNSVTNGMG9ldUg0V01PY1RwU0prWm0xZUlXcWRiaEVCb1FGdUlWTXRib1BsV0d4ZUhFRHJoOEtreGp4aThSCmdEcUQyajRwY1IzQ0g5QjJ5a0lqQjVFQ2dZRUExc0xXLys2enE1c1lNSm14K1JXZThhTXJmL3pjQnVTSU1LQWgKY0dNK0wwMG9RSHdDaUU4TVNqcVN1ajV3R214YUFuanhMb3ZwSFlRV1VmUEVaUW95UE1YQ2VhRVBLOU4xbk8xMwp0V2lHRytIZkIxaU5PazFCc0lhNFNDbndOM1FRVTFzeXBaeEgxT3hueS9LYmkvYmEvWEZ5VzNqMGFUK2YvVWxrCmJGV1ZVdWtDZ1lFQTBaMmRTTFlmTjV5eFNtYk5xMWVqZXdWd1BjRzQxR2hQclNUZEJxdHFac1doWGE3aDdLTWEKeHdvamh5SXpnTXNyK2tXODdlajhDQ2h0d21sQ1p5QU92QmdOZytncnJ1cEZLM3FOSkpKeU9YREdHckdpbzZmTQp5aXB3Q2tZVGVxRThpZ1J6UkI5QkdFUGY4eVpjMUtwdmZhUDVhM0lRZmxiV0czbGpUemNNZVZjPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo= -- name: def-user - user: - client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM4akNDQWRxZ0F3SUJBZ0lJQXhEdzk2RUY4SXN3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB4T1RBNU1qa3hOekF6TURsYUZ3MHlNREE1TWpneE56QXpNVEphTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXV6R0pZdlBaNkRvaTQyMUQKSzhXSmFaQ25OQWQycXo1cC8wNDJvRnpRUGJyQWd6RTJxWVZrek9MOHhBVmVSN1NONXdXb1RXRXlGOEVWN3JyLwo0K0hoSEdpcTVQbXF1SUZ5enpuNi9JWmM4alU5eEVmenZpa2NpckxmVTR2UlhKUXdWd2dBU05sMkFXQUloMmRECmRUcmpCQ2ZpS1dNSHlqMFJiSGFsc0J6T3BnVC9IVHYzR1F6blVRekZLdjJkajVWMU5rUy9ESGp5UlJKK0VMNlEKQlltR3NlZzVQNE5iQzllYnVpcG1NVEFxL0p1bU9vb2QrRmpMMm5acUw2Zkk2ZkJ0RjVPR2xwQ0IxWUo4ZnpDdApHUVFaN0hUSWJkYjJ0cDQzRlZPaHlRYlZjSHFUQTA0UEoxNSswV0F5bVVKVXo4WEE1NDRyL2J2NzRKY0pVUkZoCmFyWmlRd0lEQVFBQm95Y3dKVEFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFMMmhIUmVibEl2VHJTMFNmUVg1RG9ueVVhNy84aTg1endVWApSd3dqdzFuS0U0NDJKbWZWRGZ5b0hRYUM4Ti9MQkxyUXM0U0lqU1JYdmFHU1dSQnRnT1RRV21Db1laMXdSbjdwCndDTXZQTERJdHNWWm90SEZpUFl2b1lHWFFUSXA3YlROMmg1OEJaaEZ3d25nWUovT04zeG1rd29IN1IxYmVxWEYKWHF1TTluekhESk41VlZub1lQR09yRHMwWlg1RnNxNGtWVU0wVExNQm9qN1ZIRDhmU0E5RjRYNU4yMldsZnNPMAo4aksrRFJDWTAyaHBrYTZQQ0pQS0lNOEJaMUFSMG9ZakZxT0plcXpPTjBqcnpYWHh4S2pHVFVUb1BldVA5dCtCCjJOMVA1TnI4a2oxM0lrend5Q1NZclFVN09ZM3ltZmJobHkrcXZxaFVFa014MlQ1SkpmQT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= - client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBdXpHSll2UFo2RG9pNDIxREs4V0phWkNuTkFkMnF6NXAvMDQyb0Z6UVBickFnekUyCnFZVmt6T0w4eEFWZVI3U041d1dvVFdFeUY4RVY3cnIvNCtIaEhHaXE1UG1xdUlGeXp6bjYvSVpjOGpVOXhFZnoKdmlrY2lyTGZVNHZSWEpRd1Z3Z0FTTmwyQVdBSWgyZERkVHJqQkNmaUtXTUh5ajBSYkhhbHNCek9wZ1QvSFR2MwpHUXpuVVF6Rkt2MmRqNVYxTmtTL0RIanlSUkorRUw2UUJZbUdzZWc1UDROYkM5ZWJ1aXBtTVRBcS9KdW1Pb29kCitGakwyblpxTDZmSTZmQnRGNU9HbHBDQjFZSjhmekN0R1FRWjdIVEliZGIydHA0M0ZWT2h5UWJWY0hxVEEwNFAKSjE1KzBXQXltVUpVejhYQTU0NHIvYnY3NEpjSlVSRmhhclppUXdJREFRQUJBb0lCQVFDU0pycjlaeVpiQ2dqegpSL3VKMFZEWCt2aVF4c01BTUZyUjJsOE1GV3NBeHk1SFA4Vk4xYmc5djN0YUVGYnI1U3hsa3lVMFJRNjNQU25DCm1uM3ZqZ3dVQWlScllnTEl5MGk0UXF5VFBOU1V4cnpTNHRxTFBjM3EvSDBnM2FrNGZ2cSsrS0JBUUlqQnloamUKbnVFc1JpMjRzT3NESlM2UDE5NGlzUC9yNEpIM1M5bFZGbkVuOGxUR2c0M1kvMFZoMXl0cnkvdDljWjR5ZUNpNwpjMHFEaTZZcXJZaFZhSW9RRW1VQjdsbHRFZkZzb3l4VDR6RTE5U3pVbkRoMmxjYTF1TzhqcmI4d2xHTzBoQ2JyClB1R1l2WFFQa3Q0VlNmalhvdGJ3d2lBNFRCVERCRzU1bHp6MmNKeS9zSS8zSHlYbEMxcTdXUmRuQVhhZ1F0VzkKOE9DZGRkb0JBb0dCQU5NcUNtSW94REtyckhZZFRxT1M1ZFN4cVMxL0NUN3ZYZ0pScXBqd2Y4WHA2WHo0KzIvTAozVXFaVDBEL3dGTkZkc1Z4eFYxMnNYMUdwMHFWZVlKRld5OVlCaHVSWGpTZ0ZEWldSY1Z1Y01sNVpPTmJsbmZGCjVKQ0xnNXFMZ1g5VTNSRnJrR3A0R241UDQxamg4TnhKVlhzZG5xWE9xNTFUK1RRT1UzdkpGQjc1QW9HQkFPTHcKalp1cnZtVkZyTHdaVGgvRDNpWll5SVV0ZUljZ2NKLzlzbTh6L0pPRmRIbFd4dGRHUFVzYVd1MnBTNEhvckFtbgpqTm4vSTluUXd3enZ3MWUzVVFPbUhMRjVBczk4VU5hbk5TQ0xNMW1yaXZHRXJ1VHFnTDM1bU41eFZPdTUxQU5JCm4yNkFtODBJT2JDeEtLa0R0ZXJSaFhHd3g5c1pONVJCbG9VRThZNGJBb0dBQ3ZsdVhMZWRxcng5VkE0bDNoNXUKVDJXRVUxYjgxZ1orcmtRc1I1S0lNWEw4cllBTElUNUpHKzFuendyN3BkaEFXZmFWdVV2SDRhamdYT0h6MUs5aQpFODNSVTNGMG9ldUg0V01PY1RwU0prWm0xZUlXcWRiaEVCb1FGdUlWTXRib1BsV0d4ZUhFRHJoOEtreGp4aThSCmdEcUQyajRwY1IzQ0g5QjJ5a0lqQjVFQ2dZRUExc0xXLys2enE1c1lNSm14K1JXZThhTXJmL3pjQnVTSU1LQWgKY0dNK0wwMG9RSHdDaUU4TVNqcVN1ajV3R214YUFuanhMb3ZwSFlRV1VmUEVaUW95UE1YQ2VhRVBLOU4xbk8xMwp0V2lHRytIZkIxaU5PazFCc0lhNFNDbndOM1FRVTFzeXBaeEgxT3hueS9LYmkvYmEvWEZ5VzNqMGFUK2YvVWxrCmJGV1ZVdWtDZ1lFQTBaMmRTTFlmTjV5eFNtYk5xMWVqZXdWd1BjRzQxR2hQclNUZEJxdHFac1doWGE3aDdLTWEKeHdvamh5SXpnTXNyK2tXODdlajhDQ2h0d21sQ1p5QU92QmdOZytncnJ1cEZLM3FOSkpKeU9YREdHckdpbzZmTQp5aXB3Q2tZVGVxRThpZ1J6UkI5QkdFUGY4eVpjMUtwdmZhUDVhM0lRZmxiV0czbGpUemNNZVZjPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo= -` - err := ioutil.WriteFile(kubeConfigPath, []byte(kubeConfigContent), 0600) - require.NoError(t, err) - - err = conf.ImportFromKubeConfig(kubeConfigPath) - require.NoError(t, err) - - t.Run("importClusters", func(t *testing.T) { - // Verify that only 3 clusters have been added (original 5 plus 3 new clusters) - // This is important since the above kubeconfig actually has 4 - // clusters, but one was already defined in the airship config - assert.Len(t, conf.Clusters, 6+3) - - // verify that the new clusters have been added to the config - _, err := conf.GetCluster("cluster", config.Target) - assert.NoError(t, err) - _, err = conf.GetCluster("dummycluster", config.Ephemeral) - assert.NoError(t, err) - - // verify that the "noncomplex" cluster was added as a target cluster - _, err = conf.GetCluster("noncomplex", config.Target) - assert.NoError(t, err) - }) - - t.Run("importContexts", func(t *testing.T) { - // Verify that only 3 contexts have been added (original 3 plus 3 new contexts) - // This is important since the above kubeconfig actually has 4 - // contexts, but one was already defined in the airship config - assert.Len(t, conf.Contexts, 3+3) - - // verify that the new contexts have been added to the config - _, err := conf.GetContext("cluster-admin@cluster") - assert.NoError(t, err) - _, err = conf.GetContext("dummy_cluster") - assert.NoError(t, err) - - // verify that the "noncomplex" context refers to the proper target "noncomplex" cluster - noncomplex, err := conf.GetContext("noncomplex") - require.NoError(t, err) - assert.Equal(t, "noncomplex_target", noncomplex.NameInKubeconf) - }) - - t.Run("importAuthInfos", func(t *testing.T) { - // Verify that only 2 users have been added (original 3 plus 2 new users) - // This is important since the above kubeconfig actually has 3 - // users, but one was already defined in the airship config - assert.Len(t, conf.AuthInfos, 3+2) - - // verify that the new users have been added to the config - _, err := conf.GetAuthInfo("cluster-admin") - assert.NoError(t, err) - _, err = conf.GetAuthInfo("kubernetes-admin") - assert.NoError(t, err) - }) -} - -func TestImportErrors(t *testing.T) { - conf, cleanupConfig := testutil.InitConfig(t) - defer cleanupConfig(t) - - t.Run("nonexistent kubeConfig", func(t *testing.T) { - err := conf.ImportFromKubeConfig("./non/existent/file/path") - assert.Contains(t, err.Error(), "no such file or directory") - }) - - t.Run("malformed kubeConfig", func(t *testing.T) { - kubeDir, cleanupKubeConfig := testutil.TempDir(t, "airship-import-tests") - defer cleanupKubeConfig(t) - - kubeConfigPath := filepath.Join(kubeDir, "config") - //nolint: lll - kubeConfigContent := "malformed content" - - err := ioutil.WriteFile(kubeConfigPath, []byte(kubeConfigContent), 0600) - require.NoError(t, err) - - err = conf.ImportFromKubeConfig(kubeConfigPath) - assert.Contains(t, err.Error(), "json parse error") - }) -} - func TestManagementConfigurationByName(t *testing.T) { conf, cleanupConfig := testutil.InitConfig(t) defer cleanupConfig(t) diff --git a/pkg/config/context.go b/pkg/config/context.go index 2af9dbd65..523f2f1d5 100644 --- a/pkg/config/context.go +++ b/pkg/config/context.go @@ -18,8 +18,8 @@ package config import ( "fmt" + "strings" - "k8s.io/client-go/tools/clientcmd/api" "sigs.k8s.io/yaml" ) @@ -37,8 +37,8 @@ type Context struct { // +optional EncryptionConfig string `json:"encryptionConfig,omitempty"` - // KubeConfig Context Object - context *api.Context + // Management configuration which will be used for all hosts in the cluster + ManagementConfiguration string `json:"managementConfiguration"` } func (c *Context) String() string { @@ -46,12 +46,10 @@ func (c *Context) String() string { if err != nil { return "" } - kcluster := c.KubeContext() - kyaml, err := yaml.Marshal(&kcluster) if err != nil { return string(cyaml) } - return fmt.Sprintf("%s\n%s", string(cyaml), string(kyaml)) + return string(cyaml) } // PrettyString returns cluster name in a formatted string @@ -60,16 +58,6 @@ func (c *Context) PrettyString() string { return fmt.Sprintf("Context: %s\n%s\n", clusterName.Name, c) } -// KubeContext returns kube context object -func (c *Context) KubeContext() *api.Context { - return c.context -} - -// SetKubeContext updates kube contect with given context details -func (c *Context) SetKubeContext(kc *api.Context) { - c.context = kc -} - // ClusterType returns cluster type by extracting the type portion from // the complex cluster name func (c *Context) ClusterType() string { @@ -81,3 +69,48 @@ func (c *Context) ClusterType() string { func (c *Context) ClusterName() string { return NewClusterComplexNameFromKubeClusterName(c.NameInKubeconf).Name } + +// ClusterComplexName holds the complex cluster name information +// Encapsulates the different operations around using it. +type ClusterComplexName struct { + Name string + Type string +} + +// NewClusterComplexName returns a ClusterComplexName with the given name and type. +func NewClusterComplexName(clusterName, clusterType string) ClusterComplexName { + return ClusterComplexName{ + Name: clusterName, + Type: clusterType, + } +} + +// NewClusterComplexNameFromKubeClusterName takes the name of a cluster in a +// format which might be found in a kubeconfig file. This may be a simple +// string (e.g. myCluster), or it may be prepended with the type of the cluster +// (e.g. myCluster_target) +// +// If a valid cluster type was appended, the returned ClusterComplexName will +// have that type. If no cluster type is provided, the +// AirshipDefaultClusterType will be used. +func NewClusterComplexNameFromKubeClusterName(kubeClusterName string) ClusterComplexName { + parts := strings.Split(kubeClusterName, AirshipClusterNameSeparator) + + if len(parts) == 1 { + return NewClusterComplexName(kubeClusterName, AirshipDefaultClusterType) + } + + // kubeClusterName matches the format myCluster_something. + // Let's check if "something" is a clusterType. + potentialType := parts[len(parts)-1] + for _, ct := range AllClusterTypes { + if potentialType == ct { + // Rejoin the parts in the case of "my_cluster_etc_etc_" + name := strings.Join(parts[:len(parts)-1], AirshipClusterNameSeparator) + return NewClusterComplexName(name, potentialType) + } + } + + // "something" is not a valid clusterType, so just use the default + return NewClusterComplexName(kubeClusterName, AirshipDefaultClusterType) +} diff --git a/pkg/config/errors.go b/pkg/config/errors.go index c910ac05b..cf22f5349 100644 --- a/pkg/config/errors.go +++ b/pkg/config/errors.go @@ -163,12 +163,12 @@ func (e ErrMissingCurrentContext) Error() string { // ErrMissingManagementConfiguration means the management configuration was not defined for the active cluster. type ErrMissingManagementConfiguration struct { - cluster *Cluster + context *Context } func (e ErrMissingManagementConfiguration) Error() string { - return fmt.Sprintf("Management configuration %s for cluster %s undefined.", e.cluster.ManagementConfiguration, - e.cluster.NameInKubeconf) + return fmt.Sprintf("Management configuration %s for cluster %s undefined.", e.context.ManagementConfiguration, + e.context.NameInKubeconf) } // ErrMissingPrimaryRepo returned when Primary Repository is not set in context manifest @@ -206,14 +206,6 @@ func (e ErrConflictingClusterOptions) Error() string { return "Specifying certificate-authority and insecure-skip-tls-verify mode is not allowed at the same time." } -// ErrEmptyClusterName returned when empty cluster name is set -type ErrEmptyClusterName struct { -} - -func (e ErrEmptyClusterName) Error() string { - return "Cluster name must not be empty." -} - // ErrConflictingContextOptions returned when both context and --current is set at same time type ErrConflictingContextOptions struct { } diff --git a/pkg/config/options.go b/pkg/config/options.go index f3e0913f4..5e43e3810 100644 --- a/pkg/config/options.go +++ b/pkg/config/options.go @@ -22,39 +22,15 @@ import ( "opendev.org/airship/airshipctl/pkg/errors" ) -// AuthInfoOptions holds all configurable options for -// authentication information or credential -type AuthInfoOptions struct { - Name string - ClientCertificate string - ClientKey string - Token string - Username string - Password string - EmbedCertData bool -} - // ContextOptions holds all configurable options for context type ContextOptions struct { - Name string - ClusterType string - CurrentContext bool - Cluster string - AuthInfo string - Manifest string - EncryptionConfig string - Namespace string - Current bool -} - -// ClusterOptions holds all configurable options for cluster configuration -type ClusterOptions struct { - Name string - ClusterType string - Server string - InsecureSkipTLSVerify bool - CertificateAuthority string - EmbedCAData bool + Name string + ClusterType string + CurrentContext bool + Manifest string + Current bool + ManagementConfiguration string + EncryptionConfig string } // ManifestOptions holds all configurable options for manifest configuration @@ -86,33 +62,6 @@ type EncryptionConfigOptions struct { // is possible to create (and validate) these objects without using the command // line. -// Validate checks for the possible authentication values and returns -// Error when invalid value or incompatible choice of values given -func (o *AuthInfoOptions) Validate() error { - // TODO(howell): This prevents a user of airshipctl from creating a - // credential with both a bearer-token and a user/password, but it does - // not prevent a user from adding a bearer-token to a credential which - // already had a user/pass and visa-versa. This could create bugs if a - // user at first chooses one method, but later switches to another. - if o.Token != "" && (o.Username != "" || o.Password != "") { - return ErrConflictingAuthOptions{} - } - - if !o.EmbedCertData { - return nil - } - - if err := checkExists("client-certificate", o.ClientCertificate); err != nil { - return err - } - - if err := checkExists("client-key", o.ClientKey); err != nil { - return err - } - - return nil -} - // Validate checks for the possible context option values and returns // Error when invalid value or incompatible choice of values given func (o *ContextOptions) Validate() error { @@ -129,58 +78,10 @@ func (o *ContextOptions) Validate() error { return nil } - // If the cluster-type was specified, verify that it's valid - if o.ClusterType != "" { - if err := ValidClusterType(o.ClusterType); err != nil { - return err - } - } - // TODO Manifest, Cluster could be validated against the existing config maps return nil } -// Validate checks for the possible cluster option values and returns -// Error when invalid value or incompatible choice of values given -func (o *ClusterOptions) Validate() error { - if o.Name == "" { - return ErrEmptyClusterName{} - } - - err := ValidClusterType(o.ClusterType) - if err != nil { - return err - } - - if o.InsecureSkipTLSVerify && o.CertificateAuthority != "" { - return ErrConflictingClusterOptions{} - } - - if !o.EmbedCAData { - return nil - } - - if err := checkExists("certificate-authority", o.CertificateAuthority); err != nil { - return err - } - - return nil -} - -func checkExists(flagName, path string) error { - if path == "" { - return ErrMissingFlag{FlagName: flagName} - } - if _, err := os.Stat(path); err != nil { - return ErrCheckFile{ - FlagName: flagName, - Path: path, - InternalErr: err, - } - } - return nil -} - // Validate checks for the possible manifest option values and returns // Error when invalid value or incompatible choice of values given func (o *ManifestOptions) Validate() error { @@ -247,3 +148,17 @@ func (o EncryptionConfigOptions) backedByFileSystem() bool { func (o EncryptionConfigOptions) backedByAPIServer() bool { return o.KeySecretName != "" || o.KeySecretNamespace != "" } + +func checkExists(flagName, path string) error { + if path == "" { + return ErrMissingFlag{FlagName: flagName} + } + if _, err := os.Stat(path); err != nil { + return ErrCheckFile{ + FlagName: flagName, + Path: path, + InternalErr: err, + } + } + return nil +} diff --git a/pkg/config/options_test.go b/pkg/config/options_test.go index 932b37008..b9c54661c 100644 --- a/pkg/config/options_test.go +++ b/pkg/config/options_test.go @@ -17,83 +17,13 @@ limitations under the License. package config_test import ( - "io/ioutil" - "os" "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "opendev.org/airship/airshipctl/pkg/config" ) -func TestAuthInfoOptionsValidate(t *testing.T) { - aRealFile, err := ioutil.TempFile("", "a-real-file") - require.NoError(t, err) - - aRealFilename := aRealFile.Name() - defer os.Remove(aRealFilename) - - tests := []struct { - name string - testOptions config.AuthInfoOptions - expectError bool - }{ - { - name: "TokenAndUserPass", - testOptions: config.AuthInfoOptions{ - Token: "testToken", - Username: "testUser", - Password: "testPassword", - }, - expectError: true, - }, - { - name: "DontEmbed", - testOptions: config.AuthInfoOptions{ - EmbedCertData: false, - }, - expectError: false, - }, - { - name: "EmbedWithoutCert", - testOptions: config.AuthInfoOptions{ - EmbedCertData: true, - }, - expectError: true, - }, - { - name: "EmbedWithoutClientKey", - testOptions: config.AuthInfoOptions{ - EmbedCertData: true, - ClientCertificate: aRealFilename, - }, - expectError: true, - }, - { - name: "EmbedWithCertAndClientKey", - testOptions: config.AuthInfoOptions{ - EmbedCertData: true, - ClientCertificate: aRealFilename, - ClientKey: aRealFilename, - }, - expectError: false, - }, - } - - for _, tt := range tests { - tt := tt - t.Run(tt.name, func(subTest *testing.T) { - err := tt.testOptions.Validate() - if tt.expectError { - assert.Error(t, err) - } else { - assert.NoError(t, err) - } - }) - } -} - func TestContextOptionsValidate(t *testing.T) { tests := []struct { name string @@ -107,14 +37,6 @@ func TestContextOptionsValidate(t *testing.T) { }, expectError: true, }, - { - name: "InvalidClusterType", - testOptions: config.ContextOptions{ - Name: "testContext", - ClusterType: "badType", - }, - expectError: true, - }, { name: "SettingCurrentContext", testOptions: config.ContextOptions{ @@ -152,93 +74,3 @@ func TestContextOptionsValidate(t *testing.T) { }) } } - -func TestClusterOptionsValidate(t *testing.T) { - aRealfile, err := ioutil.TempFile("", "a-real-file") - require.NoError(t, err) - - aRealFilename := aRealfile.Name() - defer os.Remove(aRealFilename) - - tests := []struct { - name string - testOptions config.ClusterOptions - expectError bool - }{ - { - name: "MissingName", - testOptions: config.ClusterOptions{ - Name: "", - }, - expectError: true, - }, - { - name: "InvalidClusterType", - testOptions: config.ClusterOptions{ - Name: "testCluster", - ClusterType: "badType", - }, - expectError: true, - }, - { - name: "InsecureSkipTLSVerifyAndCertificateAuthority", - testOptions: config.ClusterOptions{ - Name: "testCluster", - ClusterType: "target", - InsecureSkipTLSVerify: true, - CertificateAuthority: "cert_file", - }, - expectError: true, - }, - { - name: "DontEmbed", - testOptions: config.ClusterOptions{ - Name: "testCluster", - ClusterType: "target", - EmbedCAData: false, - }, - expectError: false, - }, - { - name: "EmbedWithoutCA", - testOptions: config.ClusterOptions{ - Name: "testCluster", - ClusterType: "target", - EmbedCAData: true, - }, - expectError: true, - }, - { - name: "EmbedWithFaultyCA", - testOptions: config.ClusterOptions{ - Name: "testCluster", - ClusterType: "target", - EmbedCAData: true, - CertificateAuthority: "not-a-real-file", - }, - expectError: true, - }, - { - name: "EmbedWithGoodCA", - testOptions: config.ClusterOptions{ - Name: "testCluster", - ClusterType: "target", - EmbedCAData: true, - CertificateAuthority: aRealFilename, - }, - expectError: false, - }, - } - - for _, tt := range tests { - tt := tt - t.Run(tt.name, func(subTest *testing.T) { - err := tt.testOptions.Validate() - if tt.expectError { - assert.Error(t, err) - } else { - assert.NoError(t, err) - } - }) - } -} diff --git a/pkg/config/testdata/authinfo-string.yaml b/pkg/config/testdata/authinfo-string.yaml deleted file mode 100644 index b3c2f6793..000000000 --- a/pkg/config/testdata/authinfo-string.yaml +++ /dev/null @@ -1,6 +0,0 @@ -LocationOfOrigin: "" -client-certificate: ZHVtbXlfY2VydGlmaWNhdGU= -client-key: ZHVtbXlfa2V5 -password: ZHVtbXlfcGFzc3dvcmQ= -token: ZHVtbXlfdG9rZW4= -username: dummy_username diff --git a/pkg/config/testdata/cluster-string.yaml b/pkg/config/testdata/cluster-string.yaml deleted file mode 100644 index e277ed957..000000000 --- a/pkg/config/testdata/cluster-string.yaml +++ /dev/null @@ -1,6 +0,0 @@ -clusterKubeconf: dummy_cluster_target -managementConfiguration: dummy_management_config - -LocationOfOrigin: "" -certificate-authority: dummy_ca -server: http://dummy.server diff --git a/pkg/config/testdata/config-string.yaml b/pkg/config/testdata/config-string.yaml index 5fcd1f976..df5ab2f51 100644 --- a/pkg/config/testdata/config-string.yaml +++ b/pkg/config/testdata/config-string.yaml @@ -1,17 +1,9 @@ apiVersion: airshipit.org/v1alpha1 -clusters: - dummy_cluster: - clusterType: - ephemeral: - clusterKubeconf: dummy_cluster_ephemeral - managementConfiguration: dummy_management_config - target: - clusterKubeconf: dummy_cluster_target - managementConfiguration: dummy_management_config contexts: dummy_context: contextKubeconf: dummy_cluster_ephemeral encryptionConfig: dummy_encryption_config + managementConfiguration: dummy_management_config manifest: dummy_manifest currentContext: dummy_context encryptionConfigs: @@ -43,5 +35,3 @@ manifests: permissions: DirectoryPermission: 488 FilePermission: 416 -users: - dummy_user: {} diff --git a/pkg/config/testdata/context-string.yaml b/pkg/config/testdata/context-string.yaml index 60b77d672..36bfd566d 100644 --- a/pkg/config/testdata/context-string.yaml +++ b/pkg/config/testdata/context-string.yaml @@ -1,8 +1,4 @@ contextKubeconf: dummy_cluster_ephemeral encryptionConfig: dummy_encryption_config +managementConfiguration: dummy_management_config manifest: dummy_manifest - -LocationOfOrigin: "" -cluster: dummy_cluster_ephemeral -namespace: dummy_namespace -user: dummy_user diff --git a/pkg/config/testdata/prettycluster-string.yaml b/pkg/config/testdata/prettycluster-string.yaml deleted file mode 100644 index bf8866c2c..000000000 --- a/pkg/config/testdata/prettycluster-string.yaml +++ /dev/null @@ -1,8 +0,0 @@ -Cluster: dummy_cluster -target: -clusterKubeconf: dummy_cluster_target -managementConfiguration: dummy_management_config - -LocationOfOrigin: "" -certificate-authority: dummy_ca -server: http://dummy.server diff --git a/pkg/config/utils.go b/pkg/config/utils.go index 15757ef06..29f0e5697 100644 --- a/pkg/config/utils.go +++ b/pkg/config/utils.go @@ -27,15 +27,14 @@ func NewConfig() *Config { return &Config{ Kind: AirshipConfigKind, APIVersion: AirshipConfigAPIVersion, - Clusters: make(map[string]*ClusterPurpose), Permissions: Permissions{ DirectoryPermission: AirshipDefaultDirectoryPermission, FilePermission: AirshipDefaultFilePermission, }, - AuthInfos: make(map[string]*AuthInfo), Contexts: map[string]*Context{ AirshipDefaultContext: { - Manifest: AirshipDefaultManifest, + Manifest: AirshipDefaultManifest, + ManagementConfiguration: AirshipDefaultManagementConfiguration, }, }, CurrentContext: AirshipDefaultContext, @@ -87,14 +86,6 @@ func NewContext() *Context { return &Context{} } -// NewCluster is a convenience function that returns a new Cluster -func NewCluster() *Cluster { - return &Cluster{ - NameInKubeconf: "", - ManagementConfiguration: AirshipDefaultManagementConfiguration, - } -} - // NewManifest is a convenience function that returns a new Manifest // object with non-nil maps func NewManifest() *Manifest { @@ -114,11 +105,6 @@ func NewRepository() *Repository { } } -// NewAuthInfo is a convenience function that returns a new AuthInfo -func NewAuthInfo() *AuthInfo { - return &AuthInfo{} -} - // EncodeString returns the base64 encoding of given string func EncodeString(given string) string { return base64.StdEncoding.EncodeToString([]byte(given)) diff --git a/pkg/phase/apply/apply_test.go b/pkg/phase/apply/apply_test.go index eeab7455e..218b5fe35 100644 --- a/pkg/phase/apply/apply_test.go +++ b/pkg/phase/apply/apply_test.go @@ -60,7 +60,6 @@ func TestDeploy(t *testing.T) { tests := []struct { name string expectedErrorString string - clusterPurposes map[string]*config.ClusterPurpose phaseName string events []applyevent.Event }{ @@ -95,9 +94,6 @@ func TestDeploy(t *testing.T) { ao.Applier = cliApplier ao.EventChannel = ch } - if tt.clusterPurposes != nil { - rs.Clusters = tt.clusterPurposes - } if tt.phaseName != "" { ao.PhaseName = tt.phaseName } diff --git a/pkg/phase/apply/testdata/config.yaml b/pkg/phase/apply/testdata/config.yaml index 81b280473..44e60e15b 100644 --- a/pkg/phase/apply/testdata/config.yaml +++ b/pkg/phase/apply/testdata/config.yaml @@ -1,25 +1,7 @@ apiVersion: airshipit.org/v1alpha1 -bootstrapInfo: - dummy_bootstrap_config: - container: - volume: /tmp/airship:/config - image: quay.io/airshipit/isogen:latest-ubuntu_focal - containerRuntime: docker - builder: - userDataFileName: user-data - networkConfigFileName: network-config - outputMetadataFileName: output-metadata.yaml - remoteDirect: - isoUrl: http://localhost:8099/ubuntu-focal.iso -clusters: - dummycluster: - clusterType: - ephemeral: - bootstrapInfo: dummy_bootstrap_config - clusterKubeconf: dummycluster_ephemeral contexts: dummy_cluster: - contextKubeconf: dummy_cluster + contextKubeconf: dummycluster_ephemeral manifest: dummy_manifest currentContext: dummy_cluster kind: Config @@ -39,5 +21,3 @@ manifests: url: http://dummy.url.com/primary.git subPath: primary/site/test-site targetPath: testdata -users: - dummy_user: {} \ No newline at end of file diff --git a/pkg/phase/testdata/airshipconfig.yaml b/pkg/phase/testdata/airshipconfig.yaml index 1e9c40270..38a5bace2 100644 --- a/pkg/phase/testdata/airshipconfig.yaml +++ b/pkg/phase/testdata/airshipconfig.yaml @@ -1,26 +1,7 @@ apiVersion: airshipit.org/v1alpha1 -bootstrapInfo: - dummy_bootstrap_config: - container: - volume: /tmp/airship:/config - image: quay.io/airshipit/isogen:latest-ubuntu_focal - containerRuntime: docker - builder: - userDataFileName: user-data - networkConfigFileName: network-config - outputMetadataFileName: output-metadata.yaml - remoteDirect: - isoUrl: http://localhost:8099/ubuntu-focal.iso - remoteType: redfish -clusters: - dummycluster: - clusterType: - ephemeral: - bootstrapInfo: dummy_bootstrap_config - clusterKubeconf: dummycluster_ephemeral contexts: dummy_cluster: - contextKubeconf: dummy_cluster + contextKubeconf: dummycluster_ephemeral manifest: dummy_manifest currentContext: dummy_cluster kind: Config @@ -41,5 +22,3 @@ manifests: tag: v1.0.1 url: http://dummy.url.com/primary.git subPath: valid_site -users: - dummy_user: {} \ No newline at end of file diff --git a/testdata/k8s/config.yaml b/testdata/k8s/config.yaml index 79a4ca59c..f7ac37512 100644 --- a/testdata/k8s/config.yaml +++ b/testdata/k8s/config.yaml @@ -1,24 +1,4 @@ apiVersion: airshipit.org/v1alpha1 -bootstrapInfo: - default: - builder: - networkConfigFileName: network-config - outputMetadataFileName: output-metadata.yaml - userDataFileName: user-data - container: - containerRuntime: docker - image: quay.io/airshipit/isogen:latest-ubuntu_focal - volume: /srv/iso:/config - remoteDirect: - isoUrl: http://localhost:8099/ubuntu-focal.iso -clusters: - default: - clusterType: - target: - bootstrapInfo: "" - clusterKubeconf: default_target - kubernetes: - clusterType: {} contexts: default: contextKubeconf: default_target @@ -36,5 +16,3 @@ manifests: tag: "" url: https://opendev.org/airship/treasuremap targetPath: /tmp/default -users: - admin: {} diff --git a/testutil/testconfig.go b/testutil/testconfig.go index 81b950d98..8efcd50e1 100644 --- a/testutil/testconfig.go +++ b/testutil/testconfig.go @@ -36,12 +36,6 @@ func DummyConfig() *config.Config { conf := &config.Config{ Kind: config.AirshipConfigKind, APIVersion: config.AirshipConfigAPIVersion, - Clusters: map[string]*config.ClusterPurpose{ - "dummy_cluster": DummyClusterPurpose(), - }, - AuthInfos: map[string]*config.AuthInfo{ - "dummy_user": DummyAuthInfo(), - }, Permissions: config.Permissions{ DirectoryPermission: config.AirshipDefaultDirectoryPermission, FilePermission: config.AirshipDefaultFilePermission, @@ -61,10 +55,6 @@ func DummyConfig() *config.Config { CurrentContext: "dummy_context", } conf.SetKubeConfig(kubeconfig.NewConfig()) - - dummyCluster := conf.Clusters["dummy_cluster"] - conf.KubeConfig().Clusters["dummy_cluster_target"] = dummyCluster.ClusterTypes[config.Target].KubeCluster() - conf.KubeConfig().Clusters["dummy_cluster_ephemeral"] = dummyCluster.ClusterTypes[config.Ephemeral].KubeCluster() return conf } @@ -73,26 +63,7 @@ func DummyContext() *config.Context { c := config.NewContext() c.NameInKubeconf = "dummy_cluster_ephemeral" c.Manifest = "dummy_manifest" - context := kubeconfig.NewContext() - context.Namespace = "dummy_namespace" - context.AuthInfo = "dummy_user" - context.Cluster = "dummy_cluster_ephemeral" c.EncryptionConfig = "dummy_encryption_config" - c.SetKubeContext(context) - - return c -} - -// DummyCluster creates a Cluster config object for unit testing -func DummyCluster() *config.Cluster { - c := config.NewCluster() - - cluster := kubeconfig.NewCluster() - cluster.Server = "http://dummy.server" - cluster.InsecureSkipTLSVerify = false - cluster.CertificateAuthority = "dummy_ca" - c.SetKubeCluster(cluster) - c.NameInKubeconf = "dummy_cluster_target" c.ManagementConfiguration = "dummy_management_config" return c } @@ -140,29 +111,6 @@ func DummyRepoCheckout() *config.RepoCheckout { } } -// DummyAuthInfo creates a AuthInfo config object for unit testing -func DummyAuthInfo() *config.AuthInfo { - a := config.NewAuthInfo() - authinfo := kubeconfig.NewAuthInfo() - authinfo.Username = "dummy_username" - authinfo.Password = "dummy_password" - authinfo.ClientCertificate = "dummy_certificate" - authinfo.ClientKey = "dummy_key" - authinfo.Token = "dummy_token" - encodedAuthInfo := config.EncodeAuthInfo(authinfo) - a.SetKubeAuthInfo(encodedAuthInfo) - return a -} - -// DummyClusterPurpose creates ClusterPurpose config object for unit testing -func DummyClusterPurpose() *config.ClusterPurpose { - cp := config.NewClusterPurpose() - cp.ClusterTypes["ephemeral"] = DummyCluster() - cp.ClusterTypes["ephemeral"].NameInKubeconf = "dummy_cluster_ephemeral" - cp.ClusterTypes["target"] = DummyCluster() - return cp -} - // InitConfig creates a Config object meant for testing. // // The returned config object will be associated with real files stored in a @@ -188,46 +136,17 @@ func InitConfig(t *testing.T) (conf *config.Config, cleanup func(*testing.T)) { return conf, cleanup } -// DummyClusterOptions creates ClusterOptions config object -// for unit testing -func DummyClusterOptions() *config.ClusterOptions { - co := &config.ClusterOptions{} - co.Name = "dummy_cluster" - co.ClusterType = config.Ephemeral - co.Server = "http://1.1.1.1" - co.InsecureSkipTLSVerify = false - co.CertificateAuthority = "" - co.EmbedCAData = false - - return co -} - // DummyContextOptions creates ContextOptions config object // for unit testing func DummyContextOptions() *config.ContextOptions { co := &config.ContextOptions{} co.Name = "dummy_context" co.Manifest = "dummy_manifest" - co.AuthInfo = "dummy_user" co.CurrentContext = false - co.Namespace = "dummy_namespace" co.EncryptionConfig = "dummy_encryption_config" - return co } -// DummyAuthInfoOptions creates AuthInfoOptions config object -// for unit testing -func DummyAuthInfoOptions() *config.AuthInfoOptions { - authinfo := &config.AuthInfoOptions{} - authinfo.Username = "dummy_username" - authinfo.Password = "dummy_password" - authinfo.ClientCertificate = "dummy_certificate" - authinfo.ClientKey = "dummy_key" - authinfo.Token = "dummy_token" - return authinfo -} - // DummyEncryptionConfig creates EncryptionConfigOptions object // for unit testing func DummyEncryptionConfig() *config.EncryptionConfig { @@ -275,31 +194,6 @@ func DummyManifestOptions() *config.ManifestOptions { const ( testConfigYAML = `apiVersion: airshipit.org/v1alpha1 -bootstrapInfo: - default: {} -clusters: - straggler: - clusterType: - ephemeral: - clusterKubeconf: notThere - def: - clusterType: - ephemeral: - clusterKubeconf: def_ephemeral - target: - clusterKubeconf: def_target - onlyinkubeconf: - clusterType: - target: - clusterKubeconf: onlyinkubeconf_target - wrongonlyinconfig: - clusterType: {} - wrongonlyinkubeconf: - clusterType: - target: - clusterKubeconf: wrongonlyinkubeconf_target - clustertypenil: - clusterType: null contexts: def_ephemeral: contextKubeconf: def_ephemeral @@ -310,11 +204,7 @@ contexts: encryptionConfigs: {} currentContext: "" kind: Config -manifests: {} -users: - k-admin: {} - k-other: {} - def-user: {}` +manifests: {}` //nolint:lll testKubeConfigYAML = `apiVersion: v1 diff --git a/tools/deployment/22_test_configs.sh b/tools/deployment/22_test_configs.sh index e503bf67a..f64c1f01e 100755 --- a/tools/deployment/22_test_configs.sh +++ b/tools/deployment/22_test_configs.sh @@ -53,4 +53,3 @@ mkdir -p $HOME/.airship echo "Generate ~/.airship/config and ~/.airship/kubeconfig" envsubst <"${AIRSHIPCTL_WS}/tools/deployment/templates/airshipconfig_template" > ~/.airship/config envsubst <"${AIRSHIPCTL_WS}/tools/deployment/templates/kubeconfig_template" > ~/.airship/kubeconfig - diff --git a/tools/deployment/templates/airshipconfig_template b/tools/deployment/templates/airshipconfig_template index c9eccb194..977a4dabe 100644 --- a/tools/deployment/templates/airshipconfig_template +++ b/tools/deployment/templates/airshipconfig_template @@ -1,19 +1,4 @@ apiVersion: airshipit.org/v1alpha1 -bootstrapInfo: - dummy_bootstrap_config: - container: - volume: ${AIRSHIP_CONFIG_ISO_GEN_TARGET_PATH}:/config - image: ${AIRSHIP_CONFIG_ISO_BUILDER_DOCKER_IMAGE} - containerRuntime: docker - remoteDirect: - remoteType: ${REMOTE_TYPE} - insecure: ${REMOTE_INSECURE} - useproxy: ${REMOTE_PROXY} - isoUrl: http://${AIRSHIP_CONFIG_ISO_SERVE_HOST}:${AIRSHIP_CONFIG_ISO_PORT}/${AIRSHIP_CONFIG_ISO_NAME} - builder: - userDataFileName: user-data - networkConfigFileName: network-config - outputMetadataFileName: output-metadata.yaml managementConfiguration: dummy_management_config: type: ${REMOTE_TYPE} @@ -21,26 +6,15 @@ managementConfiguration: useproxy: ${REMOTE_PROXY} systemActionRetries: ${SYSTEM_ACTION_RETRIES} systemRebootDelay: ${SYSTEM_REBOOT_DELAY} - -clusters: - ephemeral-cluster: - clusterType: - ephemeral: - bootstrapInfo: dummy_bootstrap_config - clusterKubeconf: ephemeral-cluster_ephemeral - managementConfiguration: dummy_management_config - target-cluster: - clusterType: - target: - clusterKubeconf: target-cluster_target - managementConfiguration: dummy_management_config contexts: ephemeral-cluster: - contextKubeconf: ephemeral-context + contextKubeconf: ephemeral-cluster_ephemeral manifest: dummy_manifest + managementConfiguration: dummy_management_config target-cluster: - contextKubeconf: target-context + contextKubeconf: target-cluster_target manifest: dummy_manifest + managementConfiguration: dummy_management_config currentContext: ephemeral-cluster kind: Config manifests: @@ -57,6 +31,3 @@ manifests: metadataPath: manifests/metadata.yaml subPath: ${AIRSHIP_SITE_NAME} targetPath: ${AIRSHIP_CONFIG_MANIFEST_DIRECTORY} -users: - ephemeral-cluster-admin: {} - target-cluster-admin: {} diff --git a/tools/document/validate_site_docs.sh b/tools/document/validate_site_docs.sh index 17cfd6e6c..cc7371c68 100755 --- a/tools/document/validate_site_docs.sh +++ b/tools/document/validate_site_docs.sh @@ -54,17 +54,11 @@ function generate_airshipconf { cat < ${AIRSHIPCONFIG} apiVersion: airshipit.org/v1alpha1 -clusters: - ${CONTEXT}_${cluster}: - clusterType: - ${cluster}: - bootstrapInfo: default - clusterKubeconf: ${CONTEXT}_${cluster} - managementConfiguration: default contexts: ${CONTEXT}_${cluster}: contextKubeconf: ${CONTEXT}_${cluster} manifest: ${CONTEXT}_${cluster} + managementConfiguration: default currentContext: ${CONTEXT}_${cluster} kind: Config managementConfiguration: @@ -86,8 +80,6 @@ manifests: url: https://opendev.org/airship/treasuremap subPath: ${SITE_ROOT}/${SITE} targetPath: ${MANIFEST_ROOT} -users: - ${CONTEXT}_${cluster}: {} EOL }