Remove get/set-authinfo/cluster commands

These commands are no longer required since we going to remove
clusters and users from config. Appropriate fields will be removed
from Config struct in different PS.

Change-Id: I121280e91e394a38384202d9f5ffaaf4e458f82f
Signed-off-by: Ruslan Aliev <raliev@mirantis.com>
Relates-To: #327
This commit is contained in:
Ruslan Aliev 2020-08-28 17:52:44 -05:00
parent a567007199
commit 5a94f9f99c
32 changed files with 1 additions and 1656 deletions

View File

@ -39,12 +39,6 @@ func NewConfigCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Comma
},
}
configRootCmd.AddCommand(NewGetAuthInfoCommand(rootSettings))
configRootCmd.AddCommand(NewSetAuthInfoCommand(rootSettings))
configRootCmd.AddCommand(NewGetClusterCommand(rootSettings))
configRootCmd.AddCommand(NewSetClusterCommand(rootSettings))
configRootCmd.AddCommand(NewGetContextCommand(rootSettings))
configRootCmd.AddCommand(NewSetContextCommand(rootSettings))

View File

@ -1,80 +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"
"github.com/spf13/cobra"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/environment"
)
const (
getAuthInfoLong = `
Display a specific user's credentials, or all defined user
credentials if no name is provided.
`
getAuthInfoExample = `
# List all user credentials
airshipctl config get-credentials
# Display a specific user's credentials
airshipctl config get-credential exampleUser
`
)
// NewGetAuthInfoCommand creates a command for viewing the user credentials
// defined in the airshipctl config file.
func NewGetAuthInfoCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
o := &config.AuthInfoOptions{}
cmd := &cobra.Command{
Use: "get-credential [NAME]",
Short: "Get user credentials from the airshipctl config",
Long: getAuthInfoLong[1:],
Example: getAuthInfoExample,
Aliases: []string{"get-credentials"},
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
airconfig := rootSettings.Config
if len(args) == 1 {
o.Name = args[0]
authinfo, err := airconfig.GetAuthInfo(o.Name)
if err != nil {
return err
}
fmt.Fprintln(cmd.OutOrStdout(), authinfo)
} else {
authinfos, err := airconfig.GetAuthInfos()
if err != nil {
return err
}
if len(authinfos) == 0 {
fmt.Fprintln(cmd.OutOrStdout(), "No User credentials found in the configuration.")
}
for _, authinfo := range authinfos {
fmt.Fprintln(cmd.OutOrStdout(), authinfo)
}
}
return nil
},
}
return cmd
}

View File

@ -1,119 +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 (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
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/pkg/environment"
"opendev.org/airship/airshipctl/testutil"
)
const (
fooAuthInfo = "AuthInfoFoo"
barAuthInfo = "AuthInfoBar"
bazAuthInfo = "AuthInfoBaz"
missingAuthInfo = "authinfoMissing"
)
func TestGetAuthInfoCmd(t *testing.T) {
settings := &environment.AirshipCTLSettings{
Config: &config.Config{
AuthInfos: map[string]*config.AuthInfo{
fooAuthInfo: getTestAuthInfo(fooAuthInfo),
},
},
}
settingsWithMultipleAuth := &environment.AirshipCTLSettings{
Config: &config.Config{
AuthInfos: map[string]*config.AuthInfo{
barAuthInfo: getTestAuthInfo(barAuthInfo),
bazAuthInfo: getTestAuthInfo(bazAuthInfo),
},
},
}
cmdTests := []*testutil.CmdTest{
{
Name: "get-specific-credentials",
CmdLine: fooAuthInfo,
Cmd: cmd.NewGetAuthInfoCommand(settings),
},
{
Name: "get-all-credentials",
CmdLine: "",
Cmd: cmd.NewGetAuthInfoCommand(settingsWithMultipleAuth),
},
{
Name: "missing",
CmdLine: missingAuthInfo,
Cmd: cmd.NewGetAuthInfoCommand(settings),
Error: fmt.Errorf("user %s information was not "+
"found in the configuration", missingAuthInfo),
},
}
for _, tt := range cmdTests {
testutil.RunTest(t, tt)
}
}
func TestNoAuthInfosGetAuthInfoCmd(t *testing.T) {
settings := &environment.AirshipCTLSettings{Config: new(config.Config)}
cmdTest := &testutil.CmdTest{
Name: "no-credentials",
CmdLine: "",
Cmd: cmd.NewGetAuthInfoCommand(settings),
}
testutil.RunTest(t, cmdTest)
}
func TestDecodeAuthInfo(t *testing.T) {
_, err := config.DecodeAuthInfo(&kubeconfig.AuthInfo{Password: "dummy_password"})
assert.Error(t, err, config.ErrDecodingCredentials{Given: "dummy_password"})
_, err = config.DecodeAuthInfo(&kubeconfig.AuthInfo{ClientCertificate: "dummy_certificate"})
assert.Error(t, err, config.ErrDecodingCredentials{Given: "dummy_certificate"})
_, err = config.DecodeAuthInfo(&kubeconfig.AuthInfo{ClientKey: "dummy_key"})
assert.Error(t, err, config.ErrDecodingCredentials{Given: "dummy_key"})
_, err = config.DecodeAuthInfo(&kubeconfig.AuthInfo{Token: "dummy_token"})
assert.Error(t, err, config.ErrDecodingCredentials{Given: "dummy_token"})
}
func getTestAuthInfo(authName string) *config.AuthInfo {
kAuthInfo := &kubeconfig.AuthInfo{
Username: authName + "_user",
Password: authName + "_password",
ClientCertificate: authName + "_certificate",
ClientKey: authName + "_key",
Token: authName + "_token",
}
newAuthInfo := &config.AuthInfo{}
encodedKAuthInfo := config.EncodeAuthInfo(kAuthInfo)
newAuthInfo.SetKubeAuthInfo(encodedKAuthInfo)
return newAuthInfo
}

View File

@ -1,104 +0,0 @@
/*l
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"
"github.com/spf13/cobra"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/environment"
)
const (
getClusterLong = `
Display a specific cluster or all defined clusters if no name is provided.
Note that if a specific cluster's name is provided, the --cluster-type flag
must also be provided.
Valid values for the --cluster-type flag are [ephemeral|target].
`
getClusterExample = `
# List all clusters
airshipctl config get-clusters
# Display a specific cluster
airshipctl config get-cluster --cluster-type=ephemeral exampleCluster
`
)
// NewGetClusterCommand creates a command for viewing the cluster information
// defined in the airshipctl config file.
func NewGetClusterCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
o := &config.ClusterOptions{}
cmd := &cobra.Command{
Use: "get-cluster [NAME]",
Short: "Get cluster information from the airshipctl config",
Long: getClusterLong[1:],
Example: getClusterExample,
Aliases: []string{"get-clusters"},
RunE: func(cmd *cobra.Command, args []string) error {
airconfig := rootSettings.Config
if len(args) == 1 {
o.Name = args[0]
err := validate(o)
if err != nil {
return err
}
cluster, err := airconfig.GetCluster(o.Name, o.ClusterType)
if err != nil {
return err
}
fmt.Fprintln(cmd.OutOrStdout(), cluster.PrettyString())
return nil
}
clusters := airconfig.GetClusters()
if len(clusters) == 0 {
fmt.Fprintln(cmd.OutOrStdout(), "No clusters found in the configuration.")
}
for _, cluster := range clusters {
fmt.Fprintln(cmd.OutOrStdout(), cluster.PrettyString())
}
return nil
},
}
addGetClusterFlags(o, cmd)
return cmd
}
func addGetClusterFlags(o *config.ClusterOptions, cmd *cobra.Command) {
flags := cmd.Flags()
flags.StringVar(
&o.ClusterType,
"cluster-type",
"",
"type of the desired cluster")
}
func validate(o *config.ClusterOptions) error {
// Only an error if asking for a specific cluster
if len(o.Name) == 0 {
return nil
}
return config.ValidClusterType(o.ClusterType)
}

View File

@ -1,143 +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 (
"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/pkg/environment"
"opendev.org/airship/airshipctl/testutil"
)
const (
ephemeralFlag = "--cluster-type=ephemeral"
targetFlag = "--cluster-type=target"
fooCluster = "clusterFoo"
barCluster = "clusterBar"
bazCluster = "clusterBaz"
missingCluster = "clusterMissing"
)
func TestGetClusterCmd(t *testing.T) {
settings := &environment.AirshipCTLSettings{
Config: &config.Config{
Clusters: map[string]*config.ClusterPurpose{
fooCluster: {
ClusterTypes: map[string]*config.Cluster{
config.Ephemeral: getNamedTestCluster(fooCluster, config.Ephemeral),
config.Target: getNamedTestCluster(fooCluster, config.Target),
},
},
barCluster: {
ClusterTypes: map[string]*config.Cluster{
config.Ephemeral: getNamedTestCluster(barCluster, config.Ephemeral),
config.Target: getNamedTestCluster(barCluster, config.Target),
},
},
bazCluster: {
ClusterTypes: map[string]*config.Cluster{
config.Ephemeral: getNamedTestCluster(bazCluster, config.Ephemeral),
config.Target: getNamedTestCluster(bazCluster, config.Target),
},
},
},
},
}
cmdTests := []*testutil.CmdTest{
{
Name: "get-ephemeral",
CmdLine: fmt.Sprintf("%s %s", ephemeralFlag, fooCluster),
Cmd: cmd.NewGetClusterCommand(settings),
},
{
Name: "get-target",
CmdLine: fmt.Sprintf("%s %s", targetFlag, fooCluster),
Cmd: cmd.NewGetClusterCommand(settings),
},
// FIXME(howell): "airshipctl config get-cluster foo bar" will
// print *all* clusters, regardless of whether they are
// specified on the command line
// In this case, the bazCluster should not be included in the
// output, yet it is
{
Name: "get-multiple-ephemeral",
CmdLine: fmt.Sprintf("%s %s %s", ephemeralFlag, fooCluster, barCluster),
Cmd: cmd.NewGetClusterCommand(settings),
},
{
Name: "get-multiple-target",
CmdLine: fmt.Sprintf("%s %s %s", targetFlag, fooCluster, barCluster),
Cmd: cmd.NewGetClusterCommand(settings),
},
// FIXME(howell): "airshipctl config get-cluster
// --cluster-type=ephemeral" will print *all* clusters,
// regardless of whether they are ephemeral or target
{
Name: "get-all-ephemeral",
CmdLine: ephemeralFlag,
Cmd: cmd.NewGetClusterCommand(settings),
},
{
Name: "get-all-target",
CmdLine: targetFlag,
Cmd: cmd.NewGetClusterCommand(settings),
},
{
Name: "missing",
CmdLine: fmt.Sprintf("%s %s", targetFlag, missingCluster),
Cmd: cmd.NewGetClusterCommand(settings),
Error: fmt.Errorf("cluster clustermissing information was not " +
"found in the configuration"),
},
}
for _, tt := range cmdTests {
testutil.RunTest(t, tt)
}
}
func TestNoClustersGetClusterCmd(t *testing.T) {
settings := &environment.AirshipCTLSettings{Config: new(config.Config)}
cmdTest := &testutil.CmdTest{
Name: "no-clusters",
CmdLine: "",
Cmd: cmd.NewGetClusterCommand(settings),
}
testutil.RunTest(t, cmdTest)
}
func getNamedTestCluster(clusterName, clusterType string) *config.Cluster {
kCluster := &kubeconfig.Cluster{
LocationOfOrigin: "",
InsecureSkipTLSVerify: true,
Server: "",
}
newCluster := &config.Cluster{NameInKubeconf: fmt.Sprintf("%s_%s", clusterName, clusterType)}
newCluster.SetKubeCluster(kCluster)
return newCluster
}

View File

@ -1,124 +0,0 @@
/*
Copyright 2016 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"
"github.com/spf13/cobra"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/environment"
)
const (
setAuthInfoLong = `
Create or modify a user credential in the airshipctl config file.
Note that specifying more than one authentication method is an error.
`
setAuthInfoExample = `
# Create a new user credential with basic auth
airshipctl config set-credentials exampleUser \
--username=exampleUser \
--password=examplePassword
# Change the client-key of a user named admin
airshipctl config set-credentials admin \
--client-key=$HOME/.kube/admin.key
# Change the username and password of the admin user
airshipctl config set-credentials admin \
--username=admin \
--password=uXFGweU9l35qcif
# Embed client certificate data of the admin user
airshipctl config set-credentials admin \
--client-certificate=$HOME/.kube/admin.crt \
--embed-certs
`
)
// NewSetAuthInfoCommand creates a command for creating and modifying user
// credentials in the airshipctl config file.
func NewSetAuthInfoCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
o := &config.AuthInfoOptions{}
cmd := &cobra.Command{
Use: "set-credentials NAME",
Short: "Manage user credentials",
Long: setAuthInfoLong[1:],
Example: setAuthInfoExample,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
o.Name = args[0]
modified, err := config.RunSetAuthInfo(o, rootSettings.Config, true)
if err != nil {
return err
}
if modified {
fmt.Fprintf(cmd.OutOrStdout(), "User information %q modified.\n", o.Name)
} else {
fmt.Fprintf(cmd.OutOrStdout(), "User information %q created.\n", o.Name)
}
return nil
},
}
addSetAuthInfoFlags(o, cmd)
return cmd
}
func addSetAuthInfoFlags(o *config.AuthInfoOptions, cmd *cobra.Command) {
flags := cmd.Flags()
flags.StringVar(
&o.ClientCertificate,
"client-certificate",
"",
"path to a certificate")
flags.StringVar(
&o.ClientKey,
"client-key",
"",
"path to a key file")
flags.StringVar(
&o.Token,
"token",
"",
"token to use for the credential; mutually exclusive with username and password flags.")
flags.StringVar(
&o.Username,
"username",
"",
"username for the credential; mutually exclusive with token flag.")
flags.StringVar(
&o.Password,
"password",
"",
"password for the credential; mutually exclusive with token flag.")
flags.BoolVar(
&o.EmbedCertData,
"embed-certs",
false,
"if set, embed the client certificate/key into the credential")
}

View File

@ -1,157 +0,0 @@
/*
Copyright 2017 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 (
"fmt"
"strings"
"testing"
kubeconfig "k8s.io/client-go/tools/clientcmd/api"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
cmd "opendev.org/airship/airshipctl/cmd/config"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/environment"
"opendev.org/airship/airshipctl/testutil"
)
const (
testUsername = "admin@kubernetes"
testPassword = "adminPassword"
newUserName = "dummy"
existingUserName = "def-user"
pwdDelta = "_changed"
)
type setAuthInfoTest struct {
inputConfig *config.Config
cmdTest *testutil.CmdTest
userName string
userPassword string
}
func TestConfigSetAuthInfo(t *testing.T) {
cmdTests := []*testutil.CmdTest{
{
Name: "config-cmd-set-authinfo-with-help",
CmdLine: "--help",
Cmd: cmd.NewSetAuthInfoCommand(nil),
},
{
Name: "config-cmd-set-authinfo-too-many-args",
CmdLine: "arg1 arg2",
Cmd: cmd.NewSetAuthInfoCommand(nil),
Error: fmt.Errorf("accepts %d arg(s), received %d", 1, 2),
},
{
Name: "config-cmd-set-authinfo-too-few-args",
CmdLine: "",
Cmd: cmd.NewSetAuthInfoCommand(nil),
Error: fmt.Errorf("accepts %d arg(s), received %d", 1, 0),
},
}
for _, tt := range cmdTests {
testutil.RunTest(t, tt)
}
}
// initInputConfig creates an input config
// Each of these config objects are associated with real files. Those files can be
// cleaned up by calling cleanup
func initInputConfig(t *testing.T) (given *config.Config, cleanup func(*testing.T)) {
given, givenCleanup := testutil.InitConfig(t)
kubeAuthInfo := kubeconfig.NewAuthInfo()
kubeAuthInfo.Username = testUsername
kubeAuthInfo.Password = testPassword
encodedKAuthInfo := config.EncodeAuthInfo(kubeAuthInfo)
given.KubeConfig().AuthInfos[existingUserName] = encodedKAuthInfo
given.AuthInfos[existingUserName].SetKubeAuthInfo(encodedKAuthInfo)
return given, givenCleanup
}
func (test setAuthInfoTest) run(t *testing.T) {
settings := &environment.AirshipCTLSettings{Config: test.inputConfig}
test.cmdTest.Cmd = cmd.NewSetAuthInfoCommand(settings)
testutil.RunTest(t, test.cmdTest)
afterRunConf := settings.Config
// Find the AuthInfo Created or Modified
afterRunAuthInfo, err := afterRunConf.GetAuthInfo(test.userName)
require.NoError(t, err)
require.NotNil(t, afterRunAuthInfo)
afterKauthinfo := afterRunAuthInfo.KubeAuthInfo()
require.NotNil(t, afterKauthinfo)
assert.EqualValues(t, afterKauthinfo.Username, testUsername)
assert.EqualValues(t, afterKauthinfo.Password, test.userPassword)
}
func TestSetAuthInfo(t *testing.T) {
given, cleanup := testutil.InitConfig(t)
defer cleanup(t)
input, cleanupInput := initInputConfig(t)
defer cleanupInput(t)
tests := []struct {
testName string
flags []string
userName string
userPassword string
inputConfig *config.Config
}{
{
testName: "set-auth-info",
flags: []string{
"--username=" + testUsername,
"--password=" + testPassword,
},
userName: newUserName,
userPassword: testPassword,
inputConfig: given,
},
{
testName: "modify-auth-info",
flags: []string{
"--password=" + testPassword + pwdDelta,
},
userName: existingUserName,
userPassword: testPassword + pwdDelta,
inputConfig: input,
},
}
for _, tt := range tests {
tt := tt
cmd := &testutil.CmdTest{
Name: tt.testName,
CmdLine: fmt.Sprintf("%s %s", tt.userName, strings.Join(tt.flags, " ")),
}
test := setAuthInfoTest{
inputConfig: tt.inputConfig,
cmdTest: cmd,
userName: tt.userName,
userPassword: tt.userPassword,
}
test.run(t)
}
}

View File

@ -1,130 +0,0 @@
/*
Copyright 2016 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"
"github.com/spf13/cobra"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/environment"
"opendev.org/airship/airshipctl/pkg/log"
)
const (
setClusterLong = `
Create or modify a cluster in the airshipctl config files.
Since a cluster can be either "ephemeral" or "target", you must specify
cluster-type when managing clusters.
`
setClusterExample = `
# Set the server field on the ephemeral exampleCluster
airshipctl config set-cluster exampleCluster \
--cluster-type=ephemeral \
--server=https://1.2.3.4
# Embed certificate authority data for the target exampleCluster
airshipctl config set-cluster exampleCluster \
--cluster-type=target \
--client-certificate-authority=$HOME/.airship/ca/kubernetes.ca.crt \
--embed-certs
# Disable certificate checking for the target exampleCluster
airshipctl config set-cluster exampleCluster
--cluster-type=target \
--insecure-skip-tls-verify
# Configure client certificate for the target exampleCluster
airshipctl config set-cluster exampleCluster \
--cluster-type=target \
--embed-certs \
--client-certificate=$HOME/.airship/cert_file
`
)
// NewSetClusterCommand creates a command for creating and modifying clusters
// in the airshipctl config file.
func NewSetClusterCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
o := &config.ClusterOptions{}
cmd := &cobra.Command{
Use: "set-cluster NAME",
Short: "Manage clusters",
Long: setClusterLong[1:],
Example: setClusterExample,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
o.Name = args[0]
modified, err := config.RunSetCluster(o, rootSettings.Config, true)
if err != nil {
return err
}
if modified {
fmt.Fprintf(cmd.OutOrStdout(), "Cluster %q of type %q modified.\n",
o.Name, o.ClusterType)
} else {
fmt.Fprintf(cmd.OutOrStdout(), "Cluster %q of type %q created.\n",
o.Name, o.ClusterType)
}
return nil
},
}
addSetClusterFlags(o, cmd)
return cmd
}
func addSetClusterFlags(o *config.ClusterOptions, cmd *cobra.Command) {
flags := cmd.Flags()
flags.StringVar(
&o.Server,
"server",
"",
"server to use for the cluster")
flags.StringVar(
&o.ClusterType,
"cluster-type",
"",
"the type of the cluster to add or modify")
err := cmd.MarkFlagRequired("cluster-type")
if err != nil {
log.Fatal(err)
}
flags.BoolVar(
&o.InsecureSkipTLSVerify,
"insecure-skip-tls-verify",
true,
"if set, disable certificate checking")
flags.StringVar(
&o.CertificateAuthority,
"certificate-authority",
"",
"path to a certificate authority")
flags.BoolVar(
&o.EmbedCAData,
"embed-certs",
false,
"if set, embed the client certificate/key into the cluster")
}

View File

@ -1,266 +0,0 @@
/*
Copyright 2017 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 (
"bytes"
"fmt"
"io/ioutil"
"testing"
kubeconfig "k8s.io/client-go/tools/clientcmd/api"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
cmd "opendev.org/airship/airshipctl/cmd/config"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/environment"
"opendev.org/airship/airshipctl/testutil"
)
type setClusterTest struct {
description string
givenConfig *config.Config
args []string
flags []string
expectedOutput string
expectedConfig *config.Config
}
const (
testCluster = "my_new-cluster"
)
func TestConfigSetCluster(t *testing.T) {
cmdTests := []*testutil.CmdTest{
{
Name: "config-cmd-set-cluster-with-help",
CmdLine: "--help",
Cmd: cmd.NewSetClusterCommand(nil),
},
{
Name: "config-cmd-set-cluster-with-no-flags",
CmdLine: "",
Cmd: cmd.NewSetClusterCommand(nil),
Error: fmt.Errorf("accepts %d arg(s), received %d", 1, 0),
},
{
Name: "config-cmd-set-cluster-too-many-args",
CmdLine: "arg1 arg2",
Cmd: cmd.NewSetClusterCommand(nil),
Error: fmt.Errorf("accepts at most %d arg(s), received %d", 1, 2),
},
}
for _, tt := range cmdTests {
testutil.RunTest(t, tt)
}
}
func TestSetClusterWithCAFile(t *testing.T) {
given, cleanupGiven := testutil.InitConfig(t)
defer cleanupGiven(t)
certFile := "../../pkg/config/testdata/ca.crt"
tname := testCluster
tctype := config.Ephemeral
expected, cleanupExpected := testutil.InitConfig(t)
defer cleanupExpected(t)
expected.Clusters[tname] = config.NewClusterPurpose()
expected.Clusters[tname].ClusterTypes[tctype] = config.NewCluster()
clusterName := config.NewClusterComplexName(tname, tctype)
expected.Clusters[tname].ClusterTypes[tctype].NameInKubeconf = clusterName.String()
expkCluster := kubeconfig.NewCluster()
expkCluster.CertificateAuthority = certFile
expkCluster.InsecureSkipTLSVerify = false
expected.KubeConfig().Clusters[clusterName.String()] = expkCluster
test := setClusterTest{
description: "Testing 'airshipctl config set-cluster' with a new cluster",
givenConfig: given,
args: []string{tname},
flags: []string{
"--cluster-type=ephemeral",
"--certificate-authority=" + certFile,
"--insecure-skip-tls-verify=false",
},
expectedOutput: fmt.Sprintf("Cluster %q of type %q created.\n", testCluster, config.Ephemeral),
expectedConfig: expected,
}
test.run(t)
}
func TestSetClusterWithCAFileData(t *testing.T) {
given, cleanupGiven := testutil.InitConfig(t)
defer cleanupGiven(t)
certFile := "../../pkg/config/testdata/ca.crt"
tname := testCluster
tctype := config.Ephemeral
expected, cleanupExpected := testutil.InitConfig(t)
defer cleanupExpected(t)
expected.Clusters[tname] = config.NewClusterPurpose()
expected.Clusters[tname].ClusterTypes[tctype] = config.NewCluster()
clusterName := config.NewClusterComplexName(tname, tctype)
expected.Clusters[tname].ClusterTypes[tctype].NameInKubeconf = clusterName.String()
expkCluster := kubeconfig.NewCluster()
readData, err := ioutil.ReadFile(certFile)
require.NoError(t, err)
expkCluster.CertificateAuthorityData = readData
expkCluster.InsecureSkipTLSVerify = false
expected.KubeConfig().Clusters[clusterName.String()] = expkCluster
test := setClusterTest{
description: "Testing 'airshipctl config set-cluster' with a new cluster",
givenConfig: given,
args: []string{tname},
flags: []string{
"--cluster-type=ephemeral",
"--embed-certs",
"--certificate-authority=" + certFile,
"--insecure-skip-tls-verify=false",
},
expectedOutput: fmt.Sprintf("Cluster %q of type %q created.\n", tname, config.Ephemeral),
expectedConfig: expected,
}
test.run(t)
}
func TestSetCluster(t *testing.T) {
given, cleanupGiven := testutil.InitConfig(t)
defer cleanupGiven(t)
tname := testCluster
tctype := config.Ephemeral
expected, cleanupExpected := testutil.InitConfig(t)
defer cleanupExpected(t)
expected.Clusters[tname] = config.NewClusterPurpose()
expected.Clusters[tname].ClusterTypes[tctype] = config.NewCluster()
clusterName := config.NewClusterComplexName(tname, tctype)
expected.Clusters[tname].ClusterTypes[tctype].NameInKubeconf = clusterName.String()
expkCluster := kubeconfig.NewCluster()
expkCluster.Server = "https://192.168.0.11"
expkCluster.InsecureSkipTLSVerify = false
expected.KubeConfig().Clusters[clusterName.String()] = expkCluster
test := setClusterTest{
description: "Testing 'airshipctl config set-cluster' with a new cluster",
givenConfig: given,
args: []string{tname},
flags: []string{
"--cluster-type=ephemeral",
"--server=https://192.168.0.11",
},
expectedOutput: fmt.Sprintf("Cluster %q of type %q created.\n", tname, config.Ephemeral),
expectedConfig: expected,
}
test.run(t)
}
func TestModifyCluster(t *testing.T) {
tname := "testCluster"
tctype := config.Ephemeral
given, cleanupGiven := testutil.InitConfig(t)
defer cleanupGiven(t)
given.Clusters[tname] = config.NewClusterPurpose()
clusterName := config.NewClusterComplexName(tname, tctype)
given.Clusters[tname].ClusterTypes[tctype] = config.NewCluster()
given.Clusters[tname].ClusterTypes[tctype].NameInKubeconf = clusterName.String()
cluster := kubeconfig.NewCluster()
cluster.Server = "https://192.168.0.10"
given.KubeConfig().Clusters[clusterName.String()] = cluster
given.Clusters[tname].ClusterTypes[tctype].SetKubeCluster(cluster)
expected, cleanupExpected := testutil.InitConfig(t)
defer cleanupExpected(t)
expected.Clusters[tname] = config.NewClusterPurpose()
expected.Clusters[tname].ClusterTypes[tctype] = config.NewCluster()
expected.Clusters[tname].ClusterTypes[tctype].NameInKubeconf = clusterName.String()
expkCluster := kubeconfig.NewCluster()
expkCluster.Server = "https://192.168.0.10"
expected.KubeConfig().Clusters[clusterName.String()] = expkCluster
expected.Clusters[tname].ClusterTypes[tctype].SetKubeCluster(expkCluster)
test := setClusterTest{
description: "Testing 'airshipctl config set-cluster' with an existing cluster",
givenConfig: given,
args: []string{tname},
flags: []string{
"--cluster-type=ephemeral",
"--server=https://192.168.0.99",
},
expectedOutput: fmt.Sprintf("Cluster %q of type %q modified.\n", tname, tctype),
expectedConfig: expected,
}
test.run(t)
}
func (test setClusterTest) run(t *testing.T) {
settings := &environment.AirshipCTLSettings{Config: test.givenConfig}
buf := bytes.NewBuffer([]byte{})
cmd := cmd.NewSetClusterCommand(settings)
cmd.SetOut(buf)
cmd.SetArgs(test.args)
err := cmd.Flags().Parse(test.flags)
require.NoErrorf(t, err, "unexpected error flags args to command: %v, flags: %v", err, test.flags)
// Execute the Command
// Which should Persist the File
err = cmd.Execute()
require.NoErrorf(t, err, "unexpected error executing command: %v, args: %v, flags: %v", err, test.args, test.flags)
// Loads the Config File that was updated
afterRunConf := settings.Config
// Get ClusterType
tctypeFlag := cmd.Flag("cluster-type")
require.NotNil(t, tctypeFlag)
tctype := tctypeFlag.Value.String()
// Find the Cluster Created or Modified
afterRunCluster, err := afterRunConf.GetCluster(test.args[0], tctype)
require.NoError(t, err)
require.NotNil(t, afterRunCluster)
afterKcluster := afterRunCluster.KubeCluster()
require.NotNil(t, afterKcluster)
testKcluster := test.givenConfig.KubeConfig().
Clusters[test.givenConfig.Clusters[test.args[0]].ClusterTypes[tctype].NameInKubeconf]
assert.EqualValues(t, afterKcluster.Server, testKcluster.Server)
// Test that the Return Message looks correct
if len(test.expectedOutput) != 0 {
assert.EqualValues(t, test.expectedOutput, buf.String())
}
}

View File

@ -4,17 +4,13 @@ Usage:
config [command]
Available Commands:
get-cluster Get cluster information from the airshipctl config
get-context Get context information from the airshipctl config
get-credential Get user credentials from the airshipctl config
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-cluster Manage clusters
set-context Manage contexts
set-credentials Manage user credentials
set-management-config Modify an out-of-band management configuration
set-manifest Manage manifests in airship config
use-context Switch to a different context

View File

@ -1,35 +0,0 @@
Error: accepts 1 arg(s), received 0
Usage:
set-credentials NAME [flags]
Examples:
# Create a new user credential with basic auth
airshipctl config set-credentials exampleUser \
--username=exampleUser \
--password=examplePassword
# Change the client-key of a user named admin
airshipctl config set-credentials admin \
--client-key=$HOME/.kube/admin.key
# Change the username and password of the admin user
airshipctl config set-credentials admin \
--username=admin \
--password=uXFGweU9l35qcif
# Embed client certificate data of the admin user
airshipctl config set-credentials admin \
--client-certificate=$HOME/.kube/admin.crt \
--embed-certs
Flags:
--client-certificate string path to a certificate
--client-key string path to a key file
--embed-certs if set, embed the client certificate/key into the credential
-h, --help help for set-credentials
--password string password for the credential; mutually exclusive with token flag.
--token string token to use for the credential; mutually exclusive with username and password flags.
--username string username for the credential; mutually exclusive with token flag.

View File

@ -1,35 +0,0 @@
Error: accepts 1 arg(s), received 2
Usage:
set-credentials NAME [flags]
Examples:
# Create a new user credential with basic auth
airshipctl config set-credentials exampleUser \
--username=exampleUser \
--password=examplePassword
# Change the client-key of a user named admin
airshipctl config set-credentials admin \
--client-key=$HOME/.kube/admin.key
# Change the username and password of the admin user
airshipctl config set-credentials admin \
--username=admin \
--password=uXFGweU9l35qcif
# Embed client certificate data of the admin user
airshipctl config set-credentials admin \
--client-certificate=$HOME/.kube/admin.crt \
--embed-certs
Flags:
--client-certificate string path to a certificate
--client-key string path to a key file
--embed-certs if set, embed the client certificate/key into the credential
-h, --help help for set-credentials
--password string password for the credential; mutually exclusive with token flag.
--token string token to use for the credential; mutually exclusive with username and password flags.
--username string username for the credential; mutually exclusive with token flag.

View File

@ -1,37 +0,0 @@
Create or modify a user credential in the airshipctl config file.
Note that specifying more than one authentication method is an error.
Usage:
set-credentials NAME [flags]
Examples:
# Create a new user credential with basic auth
airshipctl config set-credentials exampleUser \
--username=exampleUser \
--password=examplePassword
# Change the client-key of a user named admin
airshipctl config set-credentials admin \
--client-key=$HOME/.kube/admin.key
# Change the username and password of the admin user
airshipctl config set-credentials admin \
--username=admin \
--password=uXFGweU9l35qcif
# Embed client certificate data of the admin user
airshipctl config set-credentials admin \
--client-certificate=$HOME/.kube/admin.crt \
--embed-certs
Flags:
--client-certificate string path to a certificate
--client-key string path to a key file
--embed-certs if set, embed the client certificate/key into the credential
-h, --help help for set-credentials
--password string password for the credential; mutually exclusive with token flag.
--token string token to use for the credential; mutually exclusive with username and password flags.
--username string username for the credential; mutually exclusive with token flag.

View File

@ -1,37 +0,0 @@
Error: accepts 1 arg(s), received 2
Usage:
set-cluster NAME [flags]
Examples:
# Set the server field on the ephemeral exampleCluster
airshipctl config set-cluster exampleCluster \
--cluster-type=ephemeral \
--server=https://1.2.3.4
# Embed certificate authority data for the target exampleCluster
airshipctl config set-cluster exampleCluster \
--cluster-type=target \
--client-certificate-authority=$HOME/.airship/ca/kubernetes.ca.crt \
--embed-certs
# Disable certificate checking for the target exampleCluster
airshipctl config set-cluster exampleCluster
--cluster-type=target \
--insecure-skip-tls-verify
# Configure client certificate for the target exampleCluster
airshipctl config set-cluster exampleCluster \
--cluster-type=target \
--embed-certs \
--client-certificate=$HOME/.airship/cert_file
Flags:
--certificate-authority string path to a certificate authority
--cluster-type string the type of the cluster to add or modify
--embed-certs if set, embed the client certificate/key into the cluster
-h, --help help for set-cluster
--insecure-skip-tls-verify if set, disable certificate checking (default true)
--server string server to use for the cluster

View File

@ -1,40 +0,0 @@
Create or modify a cluster in the airshipctl config files.
Since a cluster can be either "ephemeral" or "target", you must specify
cluster-type when managing clusters.
Usage:
set-cluster NAME [flags]
Examples:
# Set the server field on the ephemeral exampleCluster
airshipctl config set-cluster exampleCluster \
--cluster-type=ephemeral \
--server=https://1.2.3.4
# Embed certificate authority data for the target exampleCluster
airshipctl config set-cluster exampleCluster \
--cluster-type=target \
--client-certificate-authority=$HOME/.airship/ca/kubernetes.ca.crt \
--embed-certs
# Disable certificate checking for the target exampleCluster
airshipctl config set-cluster exampleCluster
--cluster-type=target \
--insecure-skip-tls-verify
# Configure client certificate for the target exampleCluster
airshipctl config set-cluster exampleCluster \
--cluster-type=target \
--embed-certs \
--client-certificate=$HOME/.airship/cert_file
Flags:
--certificate-authority string path to a certificate authority
--cluster-type string the type of the cluster to add or modify
--embed-certs if set, embed the client certificate/key into the cluster
-h, --help help for set-cluster
--insecure-skip-tls-verify if set, disable certificate checking (default true)
--server string server to use for the cluster

View File

@ -1,37 +0,0 @@
Error: accepts 1 arg(s), received 0
Usage:
set-cluster NAME [flags]
Examples:
# Set the server field on the ephemeral exampleCluster
airshipctl config set-cluster exampleCluster \
--cluster-type=ephemeral \
--server=https://1.2.3.4
# Embed certificate authority data for the target exampleCluster
airshipctl config set-cluster exampleCluster \
--cluster-type=target \
--client-certificate-authority=$HOME/.airship/ca/kubernetes.ca.crt \
--embed-certs
# Disable certificate checking for the target exampleCluster
airshipctl config set-cluster exampleCluster
--cluster-type=target \
--insecure-skip-tls-verify
# Configure client certificate for the target exampleCluster
airshipctl config set-cluster exampleCluster \
--cluster-type=target \
--embed-certs \
--client-certificate=$HOME/.airship/cert_file
Flags:
--certificate-authority string path to a certificate authority
--cluster-type string the type of the cluster to add or modify
--embed-certs if set, embed the client certificate/key into the cluster
-h, --help help for set-cluster
--insecure-skip-tls-verify if set, disable certificate checking (default true)
--server string server to use for the cluster

View File

@ -1,14 +0,0 @@
LocationOfOrigin: ""
client-certificate: AuthInfoBar_certificate
client-key: AuthInfoBar_key
password: AuthInfoBar_password
token: AuthInfoBar_token
username: AuthInfoBar_user
LocationOfOrigin: ""
client-certificate: AuthInfoBaz_certificate
client-key: AuthInfoBaz_key
password: AuthInfoBaz_password
token: AuthInfoBaz_token
username: AuthInfoBaz_user

View File

@ -1,7 +0,0 @@
LocationOfOrigin: ""
client-certificate: AuthInfoFoo_certificate
client-key: AuthInfoFoo_key
password: AuthInfoFoo_password
token: AuthInfoFoo_token
username: AuthInfoFoo_user

View File

@ -1,19 +0,0 @@
Error: Missing configuration: User credentials with name 'authinfoMissing'
Usage:
get-credential [NAME] [flags]
Aliases:
get-credential, get-credentials
Examples:
# List all user credentials
airshipctl config get-credentials
# Display a specific user's credentials
airshipctl config get-credential exampleUser
Flags:
-h, --help help for get-credential

View File

@ -1,54 +0,0 @@
Cluster: clusterBar
ephemeral:
clusterKubeconf: clusterBar_ephemeral
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""
Cluster: clusterBar
target:
clusterKubeconf: clusterBar_target
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""
Cluster: clusterBaz
ephemeral:
clusterKubeconf: clusterBaz_ephemeral
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""
Cluster: clusterBaz
target:
clusterKubeconf: clusterBaz_target
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""
Cluster: clusterFoo
ephemeral:
clusterKubeconf: clusterFoo_ephemeral
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""
Cluster: clusterFoo
target:
clusterKubeconf: clusterFoo_target
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""

View File

@ -1,54 +0,0 @@
Cluster: clusterBar
ephemeral:
clusterKubeconf: clusterBar_ephemeral
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""
Cluster: clusterBar
target:
clusterKubeconf: clusterBar_target
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""
Cluster: clusterBaz
ephemeral:
clusterKubeconf: clusterBaz_ephemeral
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""
Cluster: clusterBaz
target:
clusterKubeconf: clusterBaz_target
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""
Cluster: clusterFoo
ephemeral:
clusterKubeconf: clusterFoo_ephemeral
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""
Cluster: clusterFoo
target:
clusterKubeconf: clusterFoo_target
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""

View File

@ -1,9 +0,0 @@
Cluster: clusterFoo
ephemeral:
clusterKubeconf: clusterFoo_ephemeral
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""

View File

@ -1,54 +0,0 @@
Cluster: clusterBar
ephemeral:
clusterKubeconf: clusterBar_ephemeral
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""
Cluster: clusterBar
target:
clusterKubeconf: clusterBar_target
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""
Cluster: clusterBaz
ephemeral:
clusterKubeconf: clusterBaz_ephemeral
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""
Cluster: clusterBaz
target:
clusterKubeconf: clusterBaz_target
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""
Cluster: clusterFoo
ephemeral:
clusterKubeconf: clusterFoo_ephemeral
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""
Cluster: clusterFoo
target:
clusterKubeconf: clusterFoo_target
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""

View File

@ -1,54 +0,0 @@
Cluster: clusterBar
ephemeral:
clusterKubeconf: clusterBar_ephemeral
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""
Cluster: clusterBar
target:
clusterKubeconf: clusterBar_target
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""
Cluster: clusterBaz
ephemeral:
clusterKubeconf: clusterBaz_ephemeral
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""
Cluster: clusterBaz
target:
clusterKubeconf: clusterBaz_target
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""
Cluster: clusterFoo
ephemeral:
clusterKubeconf: clusterFoo_ephemeral
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""
Cluster: clusterFoo
target:
clusterKubeconf: clusterFoo_target
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""

View File

@ -1,9 +0,0 @@
Cluster: clusterFoo
target:
clusterKubeconf: clusterFoo_target
managementConfiguration: ""
LocationOfOrigin: ""
insecure-skip-tls-verify: true
server: ""

View File

@ -1,20 +0,0 @@
Error: Missing configuration: Cluster with name 'clusterMissing' of type 'target'
Usage:
get-cluster [NAME] [flags]
Aliases:
get-cluster, get-clusters
Examples:
# List all clusters
airshipctl config get-clusters
# Display a specific cluster
airshipctl config get-cluster --cluster-type=ephemeral exampleCluster
Flags:
--cluster-type string type of the desired cluster
-h, --help help for get-cluster

View File

@ -1 +0,0 @@
No User credentials found in the configuration.

View File

@ -1 +0,0 @@
No clusters found in the configuration.

View File

@ -1 +0,0 @@
User information "def-user" modified.

View File

@ -1 +0,0 @@
User information "dummy" created.

View File

@ -23,16 +23,12 @@ Manage the airshipctl config file
### SEE ALSO
* [airshipctl](airshipctl.md) - A unified entrypoint to various airship components
* [airshipctl config get-cluster](airshipctl_config_get-cluster.md) - Get cluster information from the airshipctl config
* [airshipctl config get-context](airshipctl_config_get-context.md) - Get context information from the airshipctl config
* [airshipctl config get-credential](airshipctl_config_get-credential.md) - Get user credentials 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-cluster](airshipctl_config_set-cluster.md) - Manage clusters
* [airshipctl config set-context](airshipctl_config_set-context.md) - Manage contexts
* [airshipctl config set-credentials](airshipctl_config_set-credentials.md) - Manage user credentials
* [airshipctl config set-management-config](airshipctl_config_set-management-config.md) - Modify an out-of-band management configuration
* [airshipctl config set-manifest](airshipctl_config_set-manifest.md) - Manage manifests in airship config
* [airshipctl config use-context](airshipctl_config_use-context.md) - Switch to a different context

View File

@ -232,6 +232,7 @@ func TestVerifyInputs(t *testing.T) {
func TestGenerateBootstrapIso(t *testing.T) {
airshipConfigPath := "testdata/config/config"
kubeConfigPath := "testdata/config/kubeconfig"
t.Run("EnsureCompleteError", func(t *testing.T) {
settings, err := config.CreateFactory(&airshipConfigPath, &kubeConfigPath)()
require.NoError(t, err)