Define a standard for creating commands

This commit cleans up the command constructors in an attempt to make the
codebase more uniform and approachable. This includes several refactors:

* Removed the FlagConstants - this makes the help messages and examples
  significantly more readable without needed to compile and run
  airshipctl
* Long help messages and examples are now constant
* Short, Long, and Examples all begin with a capitol letter
* Flag descriptions begin with a lowercase letter. This matches the flag
  description for the builtin "help" flag, making formatting uniform for
  all flags
* Removed redundant unit tests on non-leaf commands

This change also updates the documentation for the affected commands.

Change-Id: I8b9dcbfd9846b3deaab06dec17f80643dae78de9
This commit is contained in:
Ian Howell 2020-04-15 16:59:49 -05:00
parent e657f448ab
commit 9ffc305392
65 changed files with 835 additions and 600 deletions

View File

@ -20,16 +20,23 @@ import (
"opendev.org/airship/airshipctl/pkg/environment"
)
// NewClusterCommand returns cobra command object of the airshipctl cluster and adds it's subcommands.
const (
// TODO: (kkalynovskyi) Add more description when more subcommands are added
clusterLong = `
This command provides capabilities for interacting with a Kubernetes cluster,
such as getting status and deploying initial infrastructure.
`
)
// NewClusterCommand creates a command for interacting with a Kubernetes cluster.
func NewClusterCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
clusterRootCmd := &cobra.Command{
Use: "cluster",
// TODO: (kkalynovskyi) Add more description when more subcommands are added
Short: "Control Kubernetes cluster",
Long: "Interactions with Kubernetes cluster, such as get status, deploy initial infrastructure",
Use: "cluster",
Short: "Manage Kubernetes clusters",
Long: clusterLong[1:],
}
clusterRootCmd.AddCommand(NewCmdInitInfra(rootSettings))
clusterRootCmd.AddCommand(NewInitInfraCommand(rootSettings))
return clusterRootCmd
}

View File

@ -22,7 +22,7 @@ import (
"opendev.org/airship/airshipctl/testutil"
)
func TestNewClusterCommandReturn(t *testing.T) {
func TestNewClusterCommand(t *testing.T) {
fakeRootSettings := &environment.AirshipCTLSettings{
AirshipConfigPath: "../../testdata/k8s/config.yaml",
KubeConfigPath: "../../testdata/k8s/kubeconfig.yaml",
@ -31,9 +31,9 @@ func TestNewClusterCommandReturn(t *testing.T) {
tests := []*testutil.CmdTest{
{
Name: "cluster-initinfra-cmd-with-defaults",
Name: "cluster-cmd-with-help",
CmdLine: "--help",
Cmd: cluster.NewCmdInitInfra(fakeRootSettings),
Cmd: cluster.NewClusterCommand(fakeRootSettings),
},
}
for _, testcase := range tests {

View File

@ -25,20 +25,24 @@ import (
const (
// TODO add labels in description, when we have them designed
getInitInfraLong = `Deploy initial infrastructure to kubernetes cluster such as ` +
`metal3.io, argo, tiller and other manifest documents with appropriate labels`
getInitInfraExample = `#deploy infra to cluster
airshipctl cluster initinfra`
initInfraLong = `
Deploy initial infrastructure to kubernetes cluster such as
metal3.io, argo, tiller and other manifest documents with appropriate labels
`
initInfraExample = `
# Deploy infrastructure to a cluster
airshipctl cluster initinfra
`
)
// NewCmdInitInfra creates a command to deploy initial airship infrastructure
func NewCmdInitInfra(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
// NewInitInfraCommand creates a command to deploy initial airship infrastructure.
func NewInitInfraCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
i := initinfra.NewInfra(rootSettings)
initinfraCmd := &cobra.Command{
Use: "initinfra",
Short: "deploy initinfra components to cluster",
Long: getInitInfraLong,
Example: getInitInfraExample,
Short: "Deploy initinfra components to cluster",
Long: initInfraLong[1:],
Example: initInfraExample,
RunE: func(cmd *cobra.Command, args []string) error {
return i.Run()
},
@ -53,19 +57,19 @@ func addInitinfraFlags(i *initinfra.Infra, cmd *cobra.Command) {
&i.DryRun,
"dry-run",
false,
"Don't deliver documents to the cluster, simulate the changes instead")
"don't deliver documents to the cluster, simulate the changes instead")
flags.BoolVar(
&i.Prune,
"prune",
false,
`If set to true, command will delete all kubernetes resources that are not`+
`if set to true, command will delete all kubernetes resources that are not`+
` defined in airship documents and have airshipit.org/deployed=initinfra label`)
flags.StringVar(
&i.ClusterType,
"cluster-type",
"ephemeral",
`Select cluster type to deploy initial infastructure to;`+
`select cluster type to deploy initial infrastructure to;`+
` currently only ephemeral is supported`)
}

View File

@ -0,0 +1,42 @@
/*
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 cluster_test
import (
"testing"
"opendev.org/airship/airshipctl/cmd/cluster"
"opendev.org/airship/airshipctl/pkg/environment"
"opendev.org/airship/airshipctl/testutil"
)
func TestNewInitInfraCommand(t *testing.T) {
fakeRootSettings := &environment.AirshipCTLSettings{
AirshipConfigPath: "../../testdata/k8s/config.yaml",
KubeConfigPath: "../../testdata/k8s/kubeconfig.yaml",
}
fakeRootSettings.InitConfig()
tests := []*testutil.CmdTest{
{
Name: "cluster-initinfra-cmd-with-help",
CmdLine: "--help",
Cmd: cluster.NewInitInfraCommand(fakeRootSettings),
},
}
for _, testcase := range tests {
testutil.RunTest(t, testcase)
}
}

View File

@ -0,0 +1,14 @@
This command provides capabilities for interacting with a Kubernetes cluster,
such as getting status and deploying initial infrastructure.
Usage:
cluster [command]
Available Commands:
help Help about any command
initinfra Deploy initinfra components to cluster
Flags:
-h, --help help for cluster
Use "cluster [command] --help" for more information about a command.

View File

@ -1,14 +0,0 @@
Deploy initial infrastructure to kubernetes cluster such as metal3.io, argo, tiller and other manifest documents with appropriate labels
Usage:
initinfra [flags]
Examples:
#deploy infra to cluster
airshipctl cluster initinfra
Flags:
--cluster-type string Select cluster type to deploy initial infastructure to; currently only ephemeral is supported (default "ephemeral")
--dry-run Don't deliver documents to the cluster, simulate the changes instead
-h, --help help for initinfra
--prune If set to true, command will delete all kubernetes resources that are not defined in airship documents and have airshipit.org/deployed=initinfra label

View File

@ -0,0 +1,17 @@
Deploy initial infrastructure to kubernetes cluster such as
metal3.io, argo, tiller and other manifest documents with appropriate labels
Usage:
initinfra [flags]
Examples:
# Deploy infrastructure to a cluster
airshipctl cluster initinfra
Flags:
--cluster-type string select cluster type to deploy initial infrastructure to; currently only ephemeral is supported (default "ephemeral")
--dry-run don't deliver documents to the cluster, simulate the changes instead
-h, --help help for initinfra
--prune if set to true, command will delete all kubernetes resources that are not defined in airship documents and have airshipit.org/deployed=initinfra label

View File

@ -21,18 +21,20 @@ import (
"github.com/spf13/cobra"
)
const completionDesc = `
Generate autocompletion script for airshipctl for the specified shell (bash or zsh).
This command can generate shell autocompletion. e.g.
$ airshipctl completion bash
Can be sourced as such
$ source <(airshipctl completion bash)
const (
completionLong = `
Generate completion script for airshipctl for the specified shell (bash or zsh).
`
completionExample = `
# Save shell completion to a file
airshipctl completion bash > $HOME/.airship_completions
# Apply completions to the current shell
source <(airshipctl completion bash)
`
)
var (
completionShells = map[string]func(cmd *cobra.Command) error{
"bash": runCompletionBash,
@ -40,6 +42,7 @@ var (
}
)
// NewCompletionCommand creates a cobra command object for generating shell completion scripts.
func NewCompletionCommand() *cobra.Command {
shells := make([]string, 0, len(completionShells))
for s := range completionShells {
@ -48,8 +51,9 @@ func NewCompletionCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "completion SHELL",
Short: "Generate autocompletions script for the specified shell (bash or zsh)",
Long: completionDesc,
Short: "Generate completion script for the specified shell (bash or zsh)",
Long: completionLong[1:],
Example: completionExample,
Args: cobra.ExactArgs(1),
RunE: runCompletion,
ValidArgs: shells,

View File

@ -2,6 +2,15 @@ Error: accepts 1 arg(s), received 0
Usage:
completion SHELL [flags]
Examples:
# Save shell completion to a file
airshipctl completion bash > $HOME/.airship_completions
# Apply completions to the current shell
source <(airshipctl completion bash)
Flags:
-h, --help help for completion

View File

@ -2,6 +2,15 @@ Error: accepts 1 arg(s), received 2
Usage:
completion SHELL [flags]
Examples:
# Save shell completion to a file
airshipctl completion bash > $HOME/.airship_completions
# Apply completions to the current shell
source <(airshipctl completion bash)
Flags:
-h, --help help for completion

View File

@ -2,6 +2,15 @@ Error: unsupported shell type "fish"
Usage:
completion SHELL [flags]
Examples:
# Save shell completion to a file
airshipctl completion bash > $HOME/.airship_completions
# Apply completions to the current shell
source <(airshipctl completion bash)
Flags:
-h, --help help for completion

View File

@ -20,23 +20,21 @@ import (
"opendev.org/airship/airshipctl/pkg/environment"
)
// NewConfigCommand creates a command object for the airshipctl "config" , and adds all child commands to it.
// NewConfigCommand creates a command for interacting with the airshipctl configuration.
func NewConfigCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
configRootCmd := &cobra.Command{
Use: "config",
DisableFlagsInUseLine: true,
Short: "Modify airshipctl config files",
Long: `Modify airshipctl config files using subcommands
like "airshipctl config set-context my-context" `,
Short: "Manage the airshipctl config file",
}
configRootCmd.AddCommand(NewCmdConfigSetCluster(rootSettings))
configRootCmd.AddCommand(NewCmdConfigGetCluster(rootSettings))
configRootCmd.AddCommand(NewCmdConfigSetContext(rootSettings))
configRootCmd.AddCommand(NewCmdConfigGetContext(rootSettings))
configRootCmd.AddCommand(NewCmdConfigInit(rootSettings))
configRootCmd.AddCommand(NewCmdConfigSetAuthInfo(rootSettings))
configRootCmd.AddCommand(NewCmdConfigGetAuthInfo(rootSettings))
configRootCmd.AddCommand(NewCmdConfigUseContext(rootSettings))
configRootCmd.AddCommand(NewSetClusterCommand(rootSettings))
configRootCmd.AddCommand(NewGetClusterCommand(rootSettings))
configRootCmd.AddCommand(NewSetContextCommand(rootSettings))
configRootCmd.AddCommand(NewGetContextCommand(rootSettings))
configRootCmd.AddCommand(NewInitCommand(rootSettings))
configRootCmd.AddCommand(NewSetAuthInfoCommand(rootSettings))
configRootCmd.AddCommand(NewGetAuthInfoCommand(rootSettings))
configRootCmd.AddCommand(NewUseContextCommand(rootSettings))
return configRootCmd
}

View File

@ -25,24 +25,29 @@ import (
"opendev.org/airship/airshipctl/pkg/environment"
)
var (
getAuthInfoLong = `Display a specific user's information, or all defined users if no name is provided`
const (
getAuthInfoLong = `
Display a specific user's credentials, or all defined user
credentials if no name is provided.
`
getAuthInfoExample = `# List all the users airshipctl knows about
getAuthInfoExample = `
# List all user credentials
airshipctl config get-credentials
# Display a specific user information
airshipctl config get-credentials e2e`
# Display a specific user's credentials
airshipctl config get-credentials exampleUser
`
)
// NewCmdConfigGetAuthInfo returns a Command instance for 'config -AuthInfo' sub command
// An AuthInfo refers to a particular user for a cluster
func NewCmdConfigGetAuthInfo(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
// 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-credentials NAME",
Short: "Gets a user entry from the airshipctl config",
Long: getAuthInfoLong,
Use: "get-credentials [NAME]",
Short: "Get user credentials from the airshipctl config",
Long: getAuthInfoLong[1:],
Example: getAuthInfoExample,
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {

View File

@ -47,26 +47,19 @@ func TestGetAuthInfoCmd(t *testing.T) {
}
cmdTests := []*testutil.CmdTest{
{
Name: "get-credentials",
CmdLine: fmt.Sprintf("%s", fooAuthInfo),
Cmd: cmd.NewCmdConfigGetAuthInfo(settings),
},
{
Name: "get-all-credentials",
CmdLine: fmt.Sprintf(""),
Cmd: cmd.NewCmdConfigGetAuthInfo(settings),
},
{
Name: "get-specific-credentials",
CmdLine: fmt.Sprintf("%s", fooAuthInfo),
Cmd: cmd.NewCmdConfigGetAuthInfo(settings),
CmdLine: fooAuthInfo,
Cmd: cmd.NewGetAuthInfoCommand(settings),
},
{
Name: "get-all-credentials",
Cmd: cmd.NewGetAuthInfoCommand(settings),
},
{
Name: "missing",
CmdLine: fmt.Sprintf("%s", missingAuthInfo),
Cmd: cmd.NewCmdConfigGetAuthInfo(settings),
CmdLine: missingAuthInfo,
Cmd: cmd.NewGetAuthInfoCommand(settings),
Error: fmt.Errorf("user %s information was not "+
"found in the configuration", missingAuthInfo),
},
@ -82,7 +75,7 @@ func TestNoAuthInfosGetAuthInfoCmd(t *testing.T) {
cmdTest := &testutil.CmdTest{
Name: "no-credentials",
CmdLine: "",
Cmd: cmd.NewCmdConfigGetAuthInfo(settings),
Cmd: cmd.NewGetAuthInfoCommand(settings),
}
testutil.RunTest(t, cmdTest)
}

View File

@ -25,23 +25,32 @@ import (
"opendev.org/airship/airshipctl/pkg/environment"
)
var (
getClusterLong = "Display a specific cluster or all defined clusters if no name is provided"
const (
getClusterLong = `
Display a specific cluster or all defined clusters if no name is provided.
getClusterExample = fmt.Sprintf(`
# List all the clusters airshipctl knows about
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-cluster
# Display a specific cluster
airshipctl config get-cluster e2e --%v=ephemeral`, config.FlagClusterType)
airshipctl config get-cluster --cluster-type=ephemeral exampleCluster
`
)
// NewCmdConfigGetCluster returns a Command instance for 'config -Cluster' sub command
func NewCmdConfigGetCluster(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
// 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: getClusterLong,
Use: "get-cluster [NAME]",
Short: "Get cluster information from the airshipctl config",
Long: getClusterLong[1:],
Example: getClusterExample,
RunE: func(cmd *cobra.Command, args []string) error {
airconfig := rootSettings.Config
@ -80,9 +89,9 @@ func addGetClusterFlags(o *config.ClusterOptions, cmd *cobra.Command) {
flags := cmd.Flags()
flags.StringVar(
&o.ClusterType,
config.FlagClusterType,
"cluster-type",
"",
config.FlagClusterType+" for the cluster entry in airshipctl config")
"type of the desired cluster")
}
func validate(o *config.ClusterOptions) error {

View File

@ -29,8 +29,8 @@ import (
)
const (
ephemeralFlag = "--" + config.FlagClusterType + "=" + config.Ephemeral
targetFlag = "--" + config.FlagClusterType + "=" + config.Target
ephemeralFlag = "--cluster-type=ephemeral"
targetFlag = "--cluster-type=target"
fooCluster = "clusterFoo"
barCluster = "clusterBar"
@ -68,12 +68,12 @@ func TestGetClusterCmd(t *testing.T) {
{
Name: "get-ephemeral",
CmdLine: fmt.Sprintf("%s %s", ephemeralFlag, fooCluster),
Cmd: cmd.NewCmdConfigGetCluster(settings),
Cmd: cmd.NewGetClusterCommand(settings),
},
{
Name: "get-target",
CmdLine: fmt.Sprintf("%s %s", targetFlag, fooCluster),
Cmd: cmd.NewCmdConfigGetCluster(settings),
Cmd: cmd.NewGetClusterCommand(settings),
},
// FIXME(howell): "airshipctl config get-cluster foo bar" will
@ -84,12 +84,12 @@ func TestGetClusterCmd(t *testing.T) {
{
Name: "get-multiple-ephemeral",
CmdLine: fmt.Sprintf("%s %s %s", ephemeralFlag, fooCluster, barCluster),
Cmd: cmd.NewCmdConfigGetCluster(settings),
Cmd: cmd.NewGetClusterCommand(settings),
},
{
Name: "get-multiple-target",
CmdLine: fmt.Sprintf("%s %s %s", targetFlag, fooCluster, barCluster),
Cmd: cmd.NewCmdConfigGetCluster(settings),
Cmd: cmd.NewGetClusterCommand(settings),
},
// FIXME(howell): "airshipctl config get-cluster
@ -98,17 +98,17 @@ func TestGetClusterCmd(t *testing.T) {
{
Name: "get-all-ephemeral",
CmdLine: ephemeralFlag,
Cmd: cmd.NewCmdConfigGetCluster(settings),
Cmd: cmd.NewGetClusterCommand(settings),
},
{
Name: "get-all-target",
CmdLine: targetFlag,
Cmd: cmd.NewCmdConfigGetCluster(settings),
Cmd: cmd.NewGetClusterCommand(settings),
},
{
Name: "missing",
CmdLine: fmt.Sprintf("%s %s", targetFlag, missingCluster),
Cmd: cmd.NewCmdConfigGetCluster(settings),
Cmd: cmd.NewGetClusterCommand(settings),
Error: fmt.Errorf("cluster clustermissing information was not " +
"found in the configuration"),
},
@ -124,7 +124,7 @@ func TestNoClustersGetClusterCmd(t *testing.T) {
cmdTest := &testutil.CmdTest{
Name: "no-clusters",
CmdLine: "",
Cmd: cmd.NewCmdConfigGetCluster(settings),
Cmd: cmd.NewGetClusterCommand(settings),
}
testutil.RunTest(t, cmdTest)
}

View File

@ -25,30 +25,31 @@ import (
"opendev.org/airship/airshipctl/pkg/environment"
)
var (
getContextLong = "Display a specific context, the current-context or all defined contexts if no name is provided"
const (
getContextLong = `
Display information about contexts such as associated manifests, users, and clusters.
`
getContextExample = fmt.Sprintf(`# List all the contexts airshipctl knows about
getContextExample = `
# List all contexts
airshipctl config get-context
# Display the current context
airshipctl config get-context --%v
airshipctl config get-context --current
# Display a specific Context
airshipctl config get-context e2e`,
config.FlagCurrentContext)
# Display a specific context
airshipctl config get-context exampleContext
`
)
// A Context refers to a particular cluster, however it does not specify which of the cluster types
// it relates to. Getting explicit information about a particular context will depend
// on the ClusterType flag.
// NewCmdConfigGetContext returns a Command instance for 'config -Context' sub command
func NewCmdConfigGetContext(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
// NewGetContextCommand creates a command for viewing cluster information
// defined in the airshipctl config file.
func NewGetContextCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
o := &config.ContextOptions{}
cmd := &cobra.Command{
Use: "get-context NAME",
Short: getContextLong,
Use: "get-context [NAME]",
Short: "Get context information from the airshipctl config",
Long: getContextLong[1:],
Example: getContextExample,
RunE: func(cmd *cobra.Command, args []string) error {
airconfig := rootSettings.Config
@ -88,7 +89,7 @@ func addGetContextFlags(o *config.ContextOptions, cmd *cobra.Command) {
flags.BoolVar(
&o.CurrentContext,
config.FlagCurrentContext,
"current",
false,
"retrieve the current context entry in airshipctl config")
"get the current context")
}

View File

@ -29,8 +29,6 @@ import (
)
const (
currentContextFlag = "--" + config.FlagCurrentContext
fooContext = "ContextFoo"
barContext = "ContextBar"
bazContext = "ContextBaz"
@ -53,31 +51,31 @@ func TestGetContextCmd(t *testing.T) {
{
Name: "get-context",
CmdLine: fmt.Sprintf("%s", fooContext),
Cmd: cmd.NewCmdConfigGetContext(settings),
Cmd: cmd.NewGetContextCommand(settings),
},
{
Name: "get-all-contexts",
CmdLine: fmt.Sprintf("%s %s", fooContext, barContext),
Cmd: cmd.NewCmdConfigGetContext(settings),
Cmd: cmd.NewGetContextCommand(settings),
},
// This is not implemented yet
{
Name: "get-multiple-contexts",
CmdLine: fmt.Sprintf("%s %s", fooContext, barContext),
Cmd: cmd.NewCmdConfigGetContext(settings),
Cmd: cmd.NewGetContextCommand(settings),
},
{
Name: "missing",
CmdLine: fmt.Sprintf("%s", missingContext),
Cmd: cmd.NewCmdConfigGetContext(settings),
Cmd: cmd.NewGetContextCommand(settings),
Error: fmt.Errorf(`Context %s information was not
found in the configuration.`, missingContext),
},
{
Name: "get-current-context",
CmdLine: fmt.Sprintf("%s", currentContextFlag),
Cmd: cmd.NewCmdConfigGetContext(settings),
CmdLine: "--current",
Cmd: cmd.NewGetContextCommand(settings),
},
}
@ -91,7 +89,7 @@ func TestNoContextsGetContextCmd(t *testing.T) {
cmdTest := &testutil.CmdTest{
Name: "no-contexts",
CmdLine: "",
Cmd: cmd.NewCmdConfigGetContext(settings),
Cmd: cmd.NewGetContextCommand(settings),
}
testutil.RunTest(t, cmdTest)
}

View File

@ -22,19 +22,31 @@ import (
"opendev.org/airship/airshipctl/pkg/environment"
)
var (
configInitLong = "Generate initial configuration files for airshipctl"
const (
initLong = `
Generate an airshipctl config file and its associated kubeConfig file.
These files will be written to the $HOME/.airship directory, and will contain
default configurations.
NOTE: This will overwrite any existing config files in $HOME/.airship
`
)
// NewCmdConfigInit returns a Command instance for 'config init' sub command
func NewCmdConfigInit(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
configInitCmd := &cobra.Command{
// NewInitCommand creates a command for generating default airshipctl config files.
func NewInitCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
// TODO(howell): It'd be nice to have a flag to tell
// airshipctl where to store the new files.
// TODO(howell): Currently, this command overwrites whatever the user
// has in their airship directory. We should remove that functionality
// as default and provide and optional --overwrite flag.
cmd := &cobra.Command{
Use: "init",
Short: configInitLong,
Short: "Generate initial configuration files for airshipctl",
Long: initLong[1:],
RunE: func(cmd *cobra.Command, args []string) error {
return rootSettings.Config.PersistConfig()
},
}
return configInitCmd
return cmd
}

View File

@ -27,7 +27,7 @@ func TestConfigInit(t *testing.T) {
{
Name: "config-init-help",
CmdLine: "-h",
Cmd: NewCmdConfigInit(nil),
Cmd: NewInitCommand(nil),
},
}

View File

@ -25,38 +25,43 @@ import (
"opendev.org/airship/airshipctl/pkg/environment"
)
var (
setAuthInfoLong = fmt.Sprintf(`Sets a user entry in airshipctl config
Specifying a name that already exists will merge new fields on top of existing values.`,
)
const (
setAuthInfoLong = `
Create or modify a user credential in the airshipctl config file.
setAuthInfoExample = fmt.Sprintf(`
# Set only the "client-key" field on the "cluster-admin"
# entry, without touching other values:
airshipctl config set-credentials cluster-admin --%v=~/.kube/admin.key
Note that specifying more than one authentication method is an error.
`
# Set basic auth for the "cluster-admin" entry
airshipctl config set-credentials cluster-admin --%v=admin --%v=uXFGweU9l35qcif
setAuthInfoExample = `
# Create a new user credential with basic auth
airshipctl config set-credentials exampleUser \
--username=exampleUser \
--password=examplePassword
# Embed client certificate data in the "cluster-admin" entry
airshipctl config set-credentials cluster-admin --%v=~/.kube/admin.crt --%v=true`,
config.FlagUsername,
config.FlagUsername,
config.FlagPassword,
config.FlagCertFile,
config.FlagEmbedCerts,
)
# 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
`
)
// NewCmdConfigSetAuthInfo creates a command object for the "set-credentials" action, which
// defines a new AuthInfo airship config.
func NewCmdConfigSetAuthInfo(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
// 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: "Sets a user entry in the airshipctl config",
Long: setAuthInfoLong,
Short: "Manage user credentials",
Long: setAuthInfoLong[1:],
Example: setAuthInfoExample,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
@ -83,37 +88,37 @@ func addSetAuthInfoFlags(o *config.AuthInfoOptions, cmd *cobra.Command) {
flags.StringVar(
&o.ClientCertificate,
config.FlagCertFile,
"client-certificate",
"",
"Path to "+config.FlagCertFile+" file for the user entry in airshipctl")
"path to a certificate")
flags.StringVar(
&o.ClientKey,
config.FlagKeyFile,
"client-key",
"",
"Path to "+config.FlagKeyFile+" file for the user entry in airshipctl")
"path to a key file")
flags.StringVar(
&o.Token,
config.FlagBearerToken,
"token",
"",
config.FlagBearerToken+" for the user entry in airshipctl. Mutually exclusive with username and password flags.")
"token to use for the credential; mutually exclusive with username and password flags.")
flags.StringVar(
&o.Username,
config.FlagUsername,
"username",
"",
config.FlagUsername+" for the user entry in airshipctl. Mutually exclusive with token flag.")
"username for the credential; mutually exclusive with token flag.")
flags.StringVar(
&o.Password,
config.FlagPassword,
"password",
"",
config.FlagPassword+" for the user entry in airshipctl. Mutually exclusive with token flag.")
"password for the credential; mutually exclusive with token flag.")
flags.BoolVar(
&o.EmbedCertData,
config.FlagEmbedCerts,
"embed-certs",
false,
"Embed client cert/key for the user entry in airshipctl")
"if set, embed the client certificate/key into the credential")
}

View File

@ -52,18 +52,18 @@ func TestConfigSetAuthInfo(t *testing.T) {
{
Name: "config-cmd-set-authinfo-with-help",
CmdLine: "--help",
Cmd: cmd.NewCmdConfigSetAuthInfo(nil),
Cmd: cmd.NewSetAuthInfoCommand(nil),
},
{
Name: "config-cmd-set-authinfo-too-many-args",
CmdLine: "arg1 arg2",
Cmd: cmd.NewCmdConfigSetAuthInfo(nil),
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.NewCmdConfigSetAuthInfo(nil),
Cmd: cmd.NewSetAuthInfoCommand(nil),
Error: fmt.Errorf("accepts %d arg(s), received %d", 1, 0),
},
}
@ -89,7 +89,7 @@ func initInputConfig(t *testing.T) (given *config.Config, cleanup func(*testing.
func (test setAuthInfoTest) run(t *testing.T) {
settings := &environment.AirshipCTLSettings{Config: test.inputConfig}
test.cmdTest.Cmd = cmd.NewCmdConfigSetAuthInfo(settings)
test.cmdTest.Cmd = cmd.NewSetAuthInfoCommand(settings)
testutil.RunTest(t, test.cmdTest)
afterRunConf := settings.Config
@ -122,8 +122,8 @@ func TestSetAuthInfo(t *testing.T) {
{
testName: "set-auth-info",
flags: []string{
"--" + config.FlagUsername + "=" + testUsername,
"--" + config.FlagPassword + "=" + testPassword,
"--username=" + testUsername,
"--password=" + testPassword,
},
userName: newUserName,
userPassword: testPassword,
@ -132,7 +132,7 @@ func TestSetAuthInfo(t *testing.T) {
{
testName: "modify-auth-info",
flags: []string{
"--" + config.FlagPassword + "=" + testPassword + pwdDelta,
"--password=" + testPassword + pwdDelta,
},
userName: existingUserName,
userPassword: testPassword + pwdDelta,

View File

@ -26,42 +26,47 @@ import (
"opendev.org/airship/airshipctl/pkg/log"
)
var (
const (
setClusterLong = `
Sets a cluster entry in arshipctl config.
Specifying a name that already exists will merge new fields on top of existing values for those fields.`
Create or modify a cluster in the airshipctl config files.
setClusterExample = fmt.Sprintf(`
# Set only the server field on the e2e cluster entry without touching other values.
airshipctl config set-cluster e2e --%v=ephemeral --%v=https://1.2.3.4
Since a cluster can be either "ephemeral" or "target", you must specify
cluster-type when managing clusters.
`
# Embed certificate authority data for the e2e cluster entry
airshipctl config set-cluster e2e --%v=target --%v-authority=~/.airship/e2e/kubernetes.ca.crt
setClusterExample = `
# Set the server field on the ephemeral exampleCluster
airshipctl config set-cluster exampleCluster \
--cluster-type=ephemeral \
--server=https://1.2.3.4
# Disable cert checking for the dev cluster entry
airshipctl config set-cluster e2e --%v=target --%v=true
# 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
# Configure Client Certificate
airshipctl config set-cluster e2e --%v=target --%v=true --%v=".airship/cert_file"`,
config.FlagClusterType,
config.FlagAPIServer,
config.FlagClusterType,
config.FlagCAFile,
config.FlagClusterType,
config.FlagInsecure,
config.FlagClusterType,
config.FlagEmbedCerts,
config.FlagCertFile)
# 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
`
)
// NewCmdConfigSetCluster creates a command object for the "set-cluster" action, which
// defines a new cluster airshipctl config.
func NewCmdConfigSetCluster(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
// 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: "Sets a cluster entry in the airshipctl config",
Long: setClusterLong,
Short: "Manage clusters",
Long: setClusterLong[1:],
Example: setClusterExample,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
@ -90,36 +95,36 @@ func addSetClusterFlags(o *config.ClusterOptions, cmd *cobra.Command) {
flags.StringVar(
&o.Server,
config.FlagAPIServer,
"server",
"",
config.FlagAPIServer+" for the cluster entry in airshipctl config")
"server to use for the cluster")
flags.StringVar(
&o.ClusterType,
config.FlagClusterType,
"cluster-type",
"",
config.FlagClusterType+" for the cluster entry in airshipctl config")
"the type of the cluster to add or modify")
err := cmd.MarkFlagRequired(config.FlagClusterType)
err := cmd.MarkFlagRequired("cluster-type")
if err != nil {
log.Fatal(err)
}
flags.BoolVar(
&o.InsecureSkipTLSVerify,
config.FlagInsecure,
"insecure-skip-tls-verify",
true,
config.FlagInsecure+" for the cluster entry in airshipctl config")
"if set, disable certificate checking")
flags.StringVar(
&o.CertificateAuthority,
config.FlagCAFile,
"certificate-authority",
"",
"Path to "+config.FlagCAFile+" file for the cluster entry in airshipctl config")
"path to a certificate authority")
flags.BoolVar(
&o.EmbedCAData,
config.FlagEmbedCerts,
"embed-certs",
false,
config.FlagEmbedCerts+" for the cluster entry in airshipctl config")
"if set, embed the client certificate/key into the cluster")
}

View File

@ -73,10 +73,9 @@ func TestSetClusterWithCAFile(t *testing.T) {
givenConfig: given,
args: []string{tname},
flags: []string{
"--" + config.FlagClusterType + "=" + config.Ephemeral,
"--" + config.FlagEmbedCerts + "=false",
"--" + config.FlagCAFile + "=" + certFile,
"--" + config.FlagInsecure + "=false",
"--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,
@ -113,10 +112,10 @@ func TestSetClusterWithCAFileData(t *testing.T) {
givenConfig: given,
args: []string{tname},
flags: []string{
"--" + config.FlagClusterType + "=" + config.Ephemeral,
"--" + config.FlagEmbedCerts + "=true",
"--" + config.FlagCAFile + "=" + certFile,
"--" + config.FlagInsecure + "=false",
"--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,
@ -149,9 +148,8 @@ func TestSetCluster(t *testing.T) {
givenConfig: given,
args: []string{tname},
flags: []string{
"--" + config.FlagClusterType + "=" + config.Ephemeral,
"--" + config.FlagAPIServer + "=https://192.168.0.11",
"--" + config.FlagInsecure + "=false",
"--cluster-type=ephemeral",
"--server=https://192.168.0.11",
},
expectedOutput: fmt.Sprintf("Cluster %q of type %q created.\n", tname, config.Ephemeral),
expectedConfig: expected,
@ -191,8 +189,8 @@ func TestModifyCluster(t *testing.T) {
givenConfig: given,
args: []string{tname},
flags: []string{
"--" + config.FlagClusterType + "=" + config.Ephemeral,
"--" + config.FlagAPIServer + "=https://192.168.0.99",
"--cluster-type=ephemeral",
"--server=https://192.168.0.99",
},
expectedOutput: fmt.Sprintf("Cluster %q of type %q modified.\n", tname, tctype),
expectedConfig: expected,
@ -204,7 +202,7 @@ func (test setClusterTest) run(t *testing.T) {
settings := &environment.AirshipCTLSettings{Config: test.givenConfig}
buf := bytes.NewBuffer([]byte{})
cmd := cmd.NewCmdConfigSetCluster(settings)
cmd := cmd.NewSetClusterCommand(settings)
cmd.SetOut(buf)
cmd.SetArgs(test.args)
err := cmd.Flags().Parse(test.flags)
@ -218,7 +216,7 @@ func (test setClusterTest) run(t *testing.T) {
// Loads the Config File that was updated
afterRunConf := settings.Config
// Get ClusterType
tctypeFlag := cmd.Flag(config.FlagClusterType)
tctypeFlag := cmd.Flag("cluster-type")
require.NotNil(t, tctypeFlag)
tctype := tctypeFlag.Value.String()

View File

@ -25,44 +25,40 @@ import (
"opendev.org/airship/airshipctl/pkg/environment"
)
var (
const (
setContextLong = `
Sets a context entry in arshipctl config.
Specifying a name that already exists will merge new fields on top of existing values for those fields.`
Create or modify a context in the airshipctl config files.
`
setContextExample = fmt.Sprintf(`
# Create a completely new e2e context entry
airshipctl config set-context e2e --%v=kube-system --%v=manifest --%v=auth-info --%v=%v
setContextExample = `
# Create a new context named "exampleContext"
airshipctl config set-context exampleContext \
--namespace=kube-system \
--manifest=exampleManifest \
--user=exampleUser
--cluster-type=target
# Update the current-context to e2e
airshipctl config set-context e2e
# Update attributes of the current-context
airshipctl config set-context --%s --%v=manifest`,
config.FlagNamespace,
config.FlagManifest,
config.FlagAuthInfoName,
config.FlagClusterType,
config.Target,
config.FlagCurrent,
config.FlagManifest)
# Update the manifest of the current-context
airshipctl config set-context \
--current \
--manifest=exampleManifest
`
)
// NewCmdConfigSetContext creates a command object for the "set-context" action, which
// creates and modifies contexts in the airshipctl config
func NewCmdConfigSetContext(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
// NewSetContextCommand creates a command for creating and modifying contexts
// in the airshipctl config
func NewSetContextCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
o := &config.ContextOptions{}
cmd := &cobra.Command{
Use: "set-context NAME",
Short: "Switch to a new context or update context values in the airshipctl config",
Long: setContextLong,
Short: "Manage contexts",
Long: setContextLong[1:],
Example: setContextExample,
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
nFlags := cmd.Flags().NFlag()
if len(args) == 1 {
//context name is made optional with --current flag added
// context name is made optional with --current flag added
o.Name = args[0]
}
if o.Name != "" && nFlags == 0 {
@ -93,37 +89,37 @@ func addSetContextFlags(o *config.ContextOptions, cmd *cobra.Command) {
flags.StringVar(
&o.Cluster,
config.FlagClusterName,
"cluster",
"",
"sets the "+config.FlagClusterName+" for the specified context in the airshipctl config")
"set the cluster for the specified context")
flags.StringVar(
&o.AuthInfo,
config.FlagAuthInfoName,
"user",
"",
"sets the "+config.FlagAuthInfoName+" for the specified context in the airshipctl config")
"set the user for the specified context")
flags.StringVar(
&o.Manifest,
config.FlagManifest,
"manifest",
"",
"sets the "+config.FlagManifest+" for the specified context in the airshipctl config")
"set the manifest for the specified context")
flags.StringVar(
&o.Namespace,
config.FlagNamespace,
"namespace",
"",
"sets the "+config.FlagNamespace+" for the specified context in the airshipctl config")
"set the namespace for the specified context")
flags.StringVar(
&o.ClusterType,
config.FlagClusterType,
"cluster-type",
"",
"sets the "+config.FlagClusterType+" for the specified context in the airshipctl config")
"set the cluster-type for the specified context")
flags.BoolVar(
&o.Current,
config.FlagCurrent,
"current",
false,
"use current context from airshipctl config")
"update the current context")
}

View File

@ -49,17 +49,17 @@ func TestConfigSetContext(t *testing.T) {
{
Name: "config-cmd-set-context-with-help",
CmdLine: "--help",
Cmd: cmd.NewCmdConfigSetContext(nil),
Cmd: cmd.NewSetContextCommand(nil),
},
{
Name: "config-cmd-set-context-no-flags",
CmdLine: "context",
Cmd: cmd.NewCmdConfigSetContext(nil),
Cmd: cmd.NewSetContextCommand(nil),
},
{
Name: "config-cmd-set-context-too-many-args",
CmdLine: "arg1 arg2",
Cmd: cmd.NewCmdConfigSetContext(nil),
Cmd: cmd.NewSetContextCommand(nil),
Error: fmt.Errorf("accepts at most %d arg(s), received %d", 1, 2),
},
}
@ -84,10 +84,10 @@ func TestSetContext(t *testing.T) {
testName: "set-context",
contextName: "dummycontext",
flags: []string{
"--" + config.FlagClusterType + "=" + config.Target,
"--" + config.FlagAuthInfoName + "=" + testUser,
"--" + config.FlagManifest + "=" + defaultManifest,
"--" + config.FlagNamespace + "=" + defaultNamespace,
"--cluster-type=target",
"--user=" + testUser,
"--manifest=" + defaultManifest,
"--namespace=" + defaultNamespace,
},
givenConfig: given,
manifest: defaultManifest,
@ -102,7 +102,7 @@ func TestSetContext(t *testing.T) {
testName: "modify-context",
contextName: "def_target",
flags: []string{
"--" + config.FlagManifest + "=" + testManifest,
"--manifest=" + testManifest,
},
givenConfig: given,
manifest: testManifest,
@ -129,7 +129,7 @@ func (test setContextTest) run(t *testing.T) {
// Get the Environment
settings := &environment.AirshipCTLSettings{Config: test.givenConfig}
test.cmdTest.Cmd = cmd.NewCmdConfigSetContext(settings)
test.cmdTest.Cmd = cmd.NewSetContextCommand(settings)
testutil.RunTest(t, test.cmdTest)
afterRunConf := settings.Config

View File

@ -1,19 +1,18 @@
Modify airshipctl config files using subcommands
like "airshipctl config set-context my-context"
Manage the airshipctl config file
Usage:
config [command]
Available Commands:
get-cluster Display a specific cluster or all defined clusters if no name is provided
get-context Display a specific context, the current-context or all defined contexts if no name is provided
get-credentials Gets a user entry from the airshipctl config
get-cluster Get cluster information from the airshipctl config
get-context Get context information from the airshipctl config
get-credentials Get user credentials from the airshipctl config
help Help about any command
init Generate initial configuration files for airshipctl
set-cluster Sets a cluster entry in the airshipctl config
set-context Switch to a new context or update context values in the airshipctl config
set-credentials Sets a user entry in the airshipctl config
use-context Switch to a different airshipctl context.
set-cluster Manage clusters
set-context Manage contexts
set-credentials Manage user credentials
use-context Switch to a different context
Flags:
-h, --help help for config

View File

@ -1,4 +1,8 @@
Generate initial configuration files for airshipctl
Generate an airshipctl config file and its associated kubeConfig file.
These files will be written to the $HOME/.airship directory, and will contain
default configurations.
NOTE: This will overwrite any existing config files in $HOME/.airship
Usage:
init [flags]

View File

@ -4,22 +4,32 @@ Usage:
Examples:
# Set only the "client-key" field on the "cluster-admin"
# entry, without touching other values:
airshipctl config set-credentials cluster-admin --username=~/.kube/admin.key
# Create a new user credential with basic auth
airshipctl config set-credentials exampleUser \
--username=exampleUser \
--password=examplePassword
# Set basic auth for the "cluster-admin" entry
airshipctl config set-credentials cluster-admin --username=admin --password=uXFGweU9l35qcif
# 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
# Embed client certificate data in the "cluster-admin" entry
airshipctl config set-credentials cluster-admin --client-certificate=~/.kube/admin.crt --embed-certs=true
Flags:
--client-certificate string Path to client-certificate file for the user entry in airshipctl
--client-key string Path to client-key file for the user entry in airshipctl
--embed-certs Embed client cert/key for the user entry in airshipctl
--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 user entry in airshipctl. Mutually exclusive with token flag.
--token string token for the user entry in airshipctl. Mutually exclusive with username and password flags.
--username string username for the user entry in airshipctl. Mutually exclusive with token flag.
--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

@ -4,22 +4,32 @@ Usage:
Examples:
# Set only the "client-key" field on the "cluster-admin"
# entry, without touching other values:
airshipctl config set-credentials cluster-admin --username=~/.kube/admin.key
# Create a new user credential with basic auth
airshipctl config set-credentials exampleUser \
--username=exampleUser \
--password=examplePassword
# Set basic auth for the "cluster-admin" entry
airshipctl config set-credentials cluster-admin --username=admin --password=uXFGweU9l35qcif
# 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
# Embed client certificate data in the "cluster-admin" entry
airshipctl config set-credentials cluster-admin --client-certificate=~/.kube/admin.crt --embed-certs=true
Flags:
--client-certificate string Path to client-certificate file for the user entry in airshipctl
--client-key string Path to client-key file for the user entry in airshipctl
--embed-certs Embed client cert/key for the user entry in airshipctl
--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 user entry in airshipctl. Mutually exclusive with token flag.
--token string token for the user entry in airshipctl. Mutually exclusive with username and password flags.
--username string username for the user entry in airshipctl. Mutually exclusive with token flag.
--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,26 +1,37 @@
Sets a user entry in airshipctl config
Specifying a name that already exists will merge new fields on top of existing values.
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:
# Set only the "client-key" field on the "cluster-admin"
# entry, without touching other values:
airshipctl config set-credentials cluster-admin --username=~/.kube/admin.key
# Create a new user credential with basic auth
airshipctl config set-credentials exampleUser \
--username=exampleUser \
--password=examplePassword
# Set basic auth for the "cluster-admin" entry
airshipctl config set-credentials cluster-admin --username=admin --password=uXFGweU9l35qcif
# 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
# Embed client certificate data in the "cluster-admin" entry
airshipctl config set-credentials cluster-admin --client-certificate=~/.kube/admin.crt --embed-certs=true
Flags:
--client-certificate string Path to client-certificate file for the user entry in airshipctl
--client-key string Path to client-key file for the user entry in airshipctl
--embed-certs Embed client cert/key for the user entry in airshipctl
--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 user entry in airshipctl. Mutually exclusive with token flag.
--token string token for the user entry in airshipctl. Mutually exclusive with username and password flags.
--username string username for the user entry in airshipctl. Mutually exclusive with token flag.
--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

@ -4,21 +4,25 @@ Usage:
Examples:
# Create a completely new e2e context entry
airshipctl config set-context e2e --namespace=kube-system --manifest=manifest --user=auth-info --cluster-type=target
# Create a new context named "exampleContext"
airshipctl config set-context exampleContext \
--namespace=kube-system \
--manifest=exampleManifest \
--user=exampleUser
--cluster-type=target
# Update the current-context to e2e
airshipctl config set-context e2e
# Update the manifest of the current-context
airshipctl config set-context \
--current \
--manifest=exampleManifest
# Update attributes of the current-context
airshipctl config set-context --current --manifest=manifest
Flags:
--cluster string sets the cluster for the specified context in the airshipctl config
--cluster-type string sets the cluster-type for the specified context in the airshipctl config
--current use current context from airshipctl config
--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
-h, --help help for set-context
--manifest string sets the manifest for the specified context in the airshipctl config
--namespace string sets the namespace for the specified context in the airshipctl config
--user string sets the user for the specified context in the airshipctl config
--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

View File

@ -1,26 +1,28 @@
Sets a context entry in arshipctl config.
Specifying a name that already exists will merge new fields on top of existing values for those fields.
Create or modify a context in the airshipctl config files.
Usage:
set-context NAME [flags]
Examples:
# Create a completely new e2e context entry
airshipctl config set-context e2e --namespace=kube-system --manifest=manifest --user=auth-info --cluster-type=target
# Create a new context named "exampleContext"
airshipctl config set-context exampleContext \
--namespace=kube-system \
--manifest=exampleManifest \
--user=exampleUser
--cluster-type=target
# Update the current-context to e2e
airshipctl config set-context e2e
# Update the manifest of the current-context
airshipctl config set-context \
--current \
--manifest=exampleManifest
# Update attributes of the current-context
airshipctl config set-context --current --manifest=manifest
Flags:
--cluster string sets the cluster for the specified context in the airshipctl config
--cluster-type string sets the cluster-type for the specified context in the airshipctl config
--current use current context from airshipctl config
--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
-h, --help help for set-context
--manifest string sets the manifest for the specified context in the airshipctl config
--namespace string sets the namespace for the specified context in the airshipctl config
--user string sets the user for the specified context in the airshipctl config
--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

View File

@ -4,8 +4,9 @@ Usage:
Examples:
# Switch to a context named "e2e"
airshipctl config use-context e2e
# Switch to a context named "exampleContext"
airshipctl config use-context exampleContext
Flags:
-h, --help help for use-context

View File

@ -4,8 +4,9 @@ Usage:
Examples:
# Switch to a context named "e2e"
airshipctl config use-context e2e
# Switch to a context named "exampleContext"
airshipctl config use-context exampleContext
Flags:
-h, --help help for use-context

View File

@ -1,7 +0,0 @@
LocationOfOrigin: ""
client-certificate: dummy_certificate
client-key: dummy_key
password: dummy_password
token: dummy_token
username: dummy_user

View File

@ -1,13 +1,15 @@
Error: Missing configuration: User credentials with name 'authinfoMissing'
Usage:
get-credentials NAME [flags]
get-credentials [NAME] [flags]
Examples:
# List all the users airshipctl knows about
# List all user credentials
airshipctl config get-credentials
# Display a specific user information
airshipctl config get-credentials e2e
# Display a specific user's credentials
airshipctl config get-credentials exampleUser
Flags:
-h, --help help for get-credentials

View File

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

View File

@ -1,18 +1,20 @@
Error: Missing configuration: Context with name 'contextMissing'
Usage:
get-context NAME [flags]
get-context [NAME] [flags]
Examples:
# List all the contexts airshipctl knows about
# List all contexts
airshipctl config get-context
# Display the current context
airshipctl config get-context --current-context
airshipctl config get-context --current
# Display a specific context
airshipctl config get-context exampleContext
# Display a specific Context
airshipctl config get-context e2e
Flags:
--current-context retrieve the current context entry in airshipctl config
-h, --help help for get-context
--current get the current context
-h, --help help for get-context

View File

@ -25,21 +25,23 @@ import (
"opendev.org/airship/airshipctl/pkg/environment"
)
var (
useContextLong = "Switch to a new context defined in the airshipctl config file."
const (
useContextLong = `
Switch to a different context defined in the airshipctl config file.
`
useContextExample = `
# Switch to a context named "e2e"
airshipctl config use-context e2e`
# Switch to a context named "exampleContext"
airshipctl config use-context exampleContext
`
)
// NewCmdConfigUseContext creates a command object for the "use-context" action, which
// switches to a defined airshipctl context.
func NewCmdConfigUseContext(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
// NewUseContextCommand creates a command for switching to a defined airshipctl context.
func NewUseContextCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
cmd := &cobra.Command{
Use: "use-context NAME",
Short: "Switch to a different airshipctl context.",
Long: useContextLong,
Short: "Switch to a different context",
Long: useContextLong[1:],
Example: useContextExample,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {

View File

@ -31,18 +31,18 @@ func TestConfigUseContext(t *testing.T) {
{
Name: "config-use-context",
CmdLine: "dummy_context",
Cmd: cmd.NewCmdConfigUseContext(settings),
Cmd: cmd.NewUseContextCommand(settings),
},
{
Name: "config-use-context-no-args",
CmdLine: "",
Cmd: cmd.NewCmdConfigUseContext(settings),
Cmd: cmd.NewUseContextCommand(settings),
Error: errors.New("accepts 1 arg(s), received 0"),
},
{
Name: "config-use-context-does-not-exist",
CmdLine: "foo",
Cmd: cmd.NewCmdConfigUseContext(settings),
Cmd: cmd.NewUseContextCommand(settings),
Error: errors.New("missing configuration: context with name 'foo'"),
},
}

View File

@ -24,12 +24,12 @@ import (
func NewDocumentCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
documentRootCmd := &cobra.Command{
Use: "document",
Short: "manages deployment documents",
Short: "Manage deployment documents",
}
documentRootCmd.AddCommand(NewDocumentPullCommand(rootSettings))
documentRootCmd.AddCommand(NewPullCommand(rootSettings))
documentRootCmd.AddCommand(NewRenderCommand(rootSettings))
documentRootCmd.AddCommand(NewDocumentPluginCommand(rootSettings))
documentRootCmd.AddCommand(NewPluginCommand(rootSettings))
return documentRootCmd
}

View File

@ -23,14 +23,22 @@ import (
"opendev.org/airship/airshipctl/pkg/environment"
)
var longDescription = `Subcommand reads configuration file CONFIG passed as
a first argument and determines a particular plugin to execute. Additional
arguments may be passed to this sub-command abd can be used by the
particular plugin. CONFIG file must be structured as kubernetes
manifest (i.e. resource) and must have 'apiVersion' and 'kind' keys.
const (
pluginLong = `
This command is meant to be used as a kustomize exec plugin.
Example:
$ cat /tmp/generator.yaml
The command reads the configuration file CONFIG passed as a first argument and
determines a particular plugin to execute. Additional arguments may be passed
to this command and can be used by the particular plugin.
CONFIG must be a structured kubernetes manifest (i.e. resource) and must have
'apiVersion' and 'kind' keys. If the appropriate plugin was not found, the
command returns an error.
`
pluginExample = `
# Perform a replacement on a deployment. Prior to running this command,
# the file '/tmp/replacement.yaml' should be created as follows:
---
apiVersion: airshipit.org/v1alpha1
kind: ReplacementTransformer
@ -45,21 +53,20 @@ replacements:
fieldrefs:
- spec.template.spec.containers[name=nginx-latest].image
$ airshipctl document plugin /tmp/generator.yaml
subcommand will try to identify appropriate plugin using apiVersion and
kind keys (a.k.a group, version, kind) as an identifier. If appropriate
plugin was not found command returns an error.
# The replacement can then be performed. Output defaults to stdout.
airshipctl document plugin /tmp/replacement.yaml
`
)
// NewDocumentPluginCommand creates a new command which can act as kustomize
// NewPluginCommand creates a new command which can act as kustomize
// exec plugin.
func NewDocumentPluginCommand(rootSetting *environment.AirshipCTLSettings) *cobra.Command {
func NewPluginCommand(rootSetting *environment.AirshipCTLSettings) *cobra.Command {
pluginCmd := &cobra.Command{
Use: "plugin CONFIG [ARGS]",
Short: "used as kustomize exec plugin",
Long: longDescription,
Args: cobra.MinimumNArgs(1),
Use: "plugin CONFIG [ARGS]",
Short: "Run as a kustomize exec plugin",
Long: pluginLong[1:],
Example: pluginExample,
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cfg, err := ioutil.ReadFile(args[0])
if err != nil {

View File

@ -26,19 +26,19 @@ func TestPlugin(t *testing.T) {
{
Name: "document-plugin-cmd-with-help",
CmdLine: "--help",
Cmd: NewDocumentPluginCommand(nil),
Cmd: NewPluginCommand(nil),
},
{
Name: "document-plugin-cmd-with-empty-args",
CmdLine: "",
Error: fmt.Errorf("requires at least 1 arg(s), only received 0"),
Cmd: NewDocumentPluginCommand(nil),
Cmd: NewPluginCommand(nil),
},
{
Name: "document-plugin-cmd-with-nonexistent-config",
CmdLine: "/some/random/path.yaml",
Error: fmt.Errorf("open /some/random/path.yaml: no such file or directory"),
Cmd: NewDocumentPluginCommand(nil),
Cmd: NewPluginCommand(nil),
},
}

View File

@ -21,12 +21,12 @@ import (
"opendev.org/airship/airshipctl/pkg/environment"
)
// NewDocumentPullCommand creates a new command for pulling airship document repositories
func NewDocumentPullCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
// NewPullCommand creates a new command for pulling airship document repositories
func NewPullCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
settings := pull.Settings{AirshipCTLSettings: rootSettings}
documentPullCmd := &cobra.Command{
Use: "pull",
Short: "pulls documents from remote git repository",
Short: "Pulls documents from remote git repository",
RunE: func(cmd *cobra.Command, args []string) error {
return settings.Pull()
},

View File

@ -50,12 +50,12 @@ func TestPull(t *testing.T) {
{
Name: "document-pull-cmd-with-defaults",
CmdLine: "",
Cmd: NewDocumentPullCommand(getDummyAirshipSettings()),
Cmd: NewPullCommand(getDummyAirshipSettings()),
},
{
Name: "document-pull-cmd-with-help",
CmdLine: "--help",
Cmd: NewDocumentPullCommand(nil),
Cmd: NewPullCommand(nil),
},
}

View File

@ -46,33 +46,33 @@ func addRenderFlags(settings *render.Settings, cmd *cobra.Command) {
"label",
"l",
nil,
"Filter documents by Labels")
"filter documents by Labels")
flags.StringArrayVarP(
&settings.Annotation,
"annotation",
"a",
nil,
"Filter documents by Annotations")
"filter documents by Annotations")
flags.StringArrayVarP(
&settings.GroupVersion,
"apiversion",
"g",
nil,
"Filter documents by API version")
"filter documents by API version")
flags.StringArrayVarP(
&settings.Kind,
"kind",
"k",
nil,
"Filter documents by Kinds")
"filter documents by Kinds")
flags.StringVarP(
&settings.RawFilter,
"filter",
"f",
"",
"Logical expression for document filtering")
"logical expression for document filtering")
}

View File

@ -4,9 +4,9 @@ Usage:
render [flags]
Flags:
-a, --annotation stringArray Filter documents by Annotations
-g, --apiversion stringArray Filter documents by API version
-f, --filter string Logical expression for document filtering
-a, --annotation stringArray filter documents by Annotations
-g, --apiversion stringArray filter documents by API version
-f, --filter string logical expression for document filtering
-h, --help help for render
-k, --kind stringArray Filter documents by Kinds
-l, --label stringArray Filter documents by Labels
-k, --kind stringArray filter documents by Kinds
-l, --label stringArray filter documents by Labels

View File

@ -2,6 +2,28 @@ Error: requires at least 1 arg(s), only received 0
Usage:
plugin CONFIG [ARGS] [flags]
Examples:
# Perform a replacement on a deployment. Prior to running this command,
# the file '/tmp/replacement.yaml' should be created as follows:
---
apiVersion: airshipit.org/v1alpha1
kind: ReplacementTransformer
metadata:
name: notImportantHere
replacements:
- source:
value: nginx:newtag
target:
objref:
kind: Deployment
fieldrefs:
- spec.template.spec.containers[name=nginx-latest].image
# The replacement can then be performed. Output defaults to stdout.
airshipctl document plugin /tmp/replacement.yaml
Flags:
-h, --help help for plugin

View File

@ -1,11 +1,20 @@
Subcommand reads configuration file CONFIG passed as
a first argument and determines a particular plugin to execute. Additional
arguments may be passed to this sub-command abd can be used by the
particular plugin. CONFIG file must be structured as kubernetes
manifest (i.e. resource) and must have 'apiVersion' and 'kind' keys.
This command is meant to be used as a kustomize exec plugin.
Example:
$ cat /tmp/generator.yaml
The command reads the configuration file CONFIG passed as a first argument and
determines a particular plugin to execute. Additional arguments may be passed
to this command and can be used by the particular plugin.
CONFIG must be a structured kubernetes manifest (i.e. resource) and must have
'apiVersion' and 'kind' keys. If the appropriate plugin was not found, the
command returns an error.
Usage:
plugin CONFIG [ARGS] [flags]
Examples:
# Perform a replacement on a deployment. Prior to running this command,
# the file '/tmp/replacement.yaml' should be created as follows:
---
apiVersion: airshipit.org/v1alpha1
kind: ReplacementTransformer
@ -20,14 +29,9 @@ replacements:
fieldrefs:
- spec.template.spec.containers[name=nginx-latest].image
$ airshipctl document plugin /tmp/generator.yaml
# The replacement can then be performed. Output defaults to stdout.
airshipctl document plugin /tmp/replacement.yaml
subcommand will try to identify appropriate plugin using apiVersion and
kind keys (a.k.a group, version, kind) as an identifier. If appropriate
plugin was not found command returns an error.
Usage:
plugin CONFIG [ARGS] [flags]
Flags:
-h, --help help for plugin

View File

@ -2,6 +2,28 @@ Error: open /some/random/path.yaml: no such file or directory
Usage:
plugin CONFIG [ARGS] [flags]
Examples:
# Perform a replacement on a deployment. Prior to running this command,
# the file '/tmp/replacement.yaml' should be created as follows:
---
apiVersion: airshipit.org/v1alpha1
kind: ReplacementTransformer
metadata:
name: notImportantHere
replacements:
- source:
value: nginx:newtag
target:
objref:
kind: Deployment
fieldrefs:
- spec.template.spec.containers[name=nginx-latest].image
# The replacement can then be performed. Output defaults to stdout.
airshipctl document plugin /tmp/replacement.yaml
Flags:
-h, --help help for plugin

View File

@ -1,4 +1,4 @@
pulls documents from remote git repository
Pulls documents from remote git repository
Usage:
pull [flags]

View File

@ -35,17 +35,17 @@ import (
// NewAirshipCTLCommand creates a root `airshipctl` command with the default commands attached
func NewAirshipCTLCommand(out io.Writer) (*cobra.Command, *environment.AirshipCTLSettings, error) {
rootCmd, settings, err := NewRootCmd(out)
rootCmd, settings, err := NewRootCommand(out)
return AddDefaultAirshipCTLCommands(rootCmd, settings), settings, err
}
// NewRootCmd creates the root `airshipctl` command. All other commands are
// NewRootCommand creates the root `airshipctl` command. All other commands are
// subcommands branching from this one
func NewRootCmd(out io.Writer) (*cobra.Command, *environment.AirshipCTLSettings, error) {
func NewRootCommand(out io.Writer) (*cobra.Command, *environment.AirshipCTLSettings, error) {
settings := &environment.AirshipCTLSettings{}
rootCmd := &cobra.Command{
Use: "airshipctl",
Short: "airshipctl is a unified entrypoint to various airship components",
Short: "A unified entrypoint to various airship components",
SilenceErrors: true,
SilenceUsage: true,
PersistentPreRun: func(cmd *cobra.Command, args []string) {

View File

@ -31,19 +31,19 @@ import (
func TestRoot(t *testing.T) {
tests := []*testutil.CmdTest{
{
Name: "rootCmd-with-no-defaults",
CmdLine: "-h",
Cmd: getVanillaRootCmd(t),
Name: "rootCmd-with-no-subcommands",
CmdLine: "--help",
Cmd: getVanillaRootCommand(t),
},
{
Name: "rootCmd-with-defaults",
CmdLine: "-h",
Cmd: getDefaultRootCmd(t),
Name: "rootCmd-with-default-subcommands",
CmdLine: "--help",
Cmd: getDefaultRootCommand(t),
},
{
Name: "specialized-rootCmd-with-bootstrap",
CmdLine: "-h",
Cmd: getSpecializedRootCmd(t),
CmdLine: "--help",
Cmd: getSpecializedRootCommand(t),
},
}
@ -78,7 +78,7 @@ func TestFlagLoading(t *testing.T) {
t.Run(tt.name, func(subTest *testing.T) {
// We don't care about the output of this test, so toss
// it into a throwaway &bytes.buffer{}
rootCmd, settings, err := cmd.NewRootCmd(&bytes.Buffer{})
rootCmd, settings, err := cmd.NewRootCommand(&bytes.Buffer{})
require.NoError(t, err)
rootCmd.SetArgs(tt.args)
@ -90,22 +90,22 @@ func TestFlagLoading(t *testing.T) {
}
}
func getVanillaRootCmd(t *testing.T) *cobra.Command {
func getVanillaRootCommand(t *testing.T) *cobra.Command {
t.Helper()
rootCmd, _, err := cmd.NewRootCmd(nil)
rootCmd, _, err := cmd.NewRootCommand(nil)
require.NoError(t, err, "Could not create root commands")
return rootCmd
}
func getDefaultRootCmd(t *testing.T) *cobra.Command {
func getDefaultRootCommand(t *testing.T) *cobra.Command {
t.Helper()
rootCmd, _, err := cmd.NewAirshipCTLCommand(nil)
require.NoError(t, err, "Could not create root commands")
return rootCmd
}
func getSpecializedRootCmd(t *testing.T) *cobra.Command {
rootCmd := getVanillaRootCmd(t)
func getSpecializedRootCommand(t *testing.T) *cobra.Command {
rootCmd := getVanillaRootCommand(t)
rootCmd.AddCommand(bootstrap.NewBootstrapCommand(&environment.AirshipCTLSettings{}))
return rootCmd
}

View File

@ -21,7 +21,7 @@ func NewGenerateCommand() *cobra.Command {
generateRootCmd := &cobra.Command{
Use: "generate",
// TODO(howell): Make this more expressive
Short: "generates various secrets",
Short: "Generate various secrets",
}
generateRootCmd.AddCommand(NewGenerateMasterPassphraseCommand())

View File

@ -27,7 +27,7 @@ func NewGenerateMasterPassphraseCommand() *cobra.Command {
masterPassphraseCmd := &cobra.Command{
Use: "masterpassphrase",
// TODO(howell): Make this more expressive
Short: "generates a secure master passphrase",
Short: "Generates a secure master passphrase",
Run: func(cmd *cobra.Command, args []string) {
engine := secret.NewPassphraseEngine(nil)
masterPassphrase := engine.GeneratePassphrase()

View File

@ -25,7 +25,7 @@ func NewSecretCommand() *cobra.Command {
secretRootCmd := &cobra.Command{
Use: "secret",
// TODO(howell): Make this more expressive
Short: "manages secrets",
Short: "Manage secrets",
}
secretRootCmd.AddCommand(generate.NewGenerateCommand())

View File

@ -1,17 +1,17 @@
airshipctl is a unified entrypoint to various airship components
A unified entrypoint to various airship components
Usage:
airshipctl [command]
Available Commands:
bootstrap Bootstrap ephemeral Kubernetes cluster
cluster Control Kubernetes cluster
completion Generate autocompletions script for the specified shell (bash or zsh)
config Modify airshipctl config files
document manages deployment documents
cluster Manage Kubernetes clusters
completion Generate completion script for the specified shell (bash or zsh)
config Manage the airshipctl config file
document Manage deployment documents
help Help about any command
remote Control remote entities, i.e. hosts.
secret manages secrets
secret Manage secrets
version Show the version number of airshipctl
Flags:

View File

@ -1,4 +1,4 @@
airshipctl is a unified entrypoint to various airship components
A unified entrypoint to various airship components
Usage:
airshipctl [command]

View File

@ -1,4 +1,4 @@
airshipctl is a unified entrypoint to various airship components
A unified entrypoint to various airship components
Usage:
airshipctl [command]

View File

@ -22,7 +22,7 @@ import (
"opendev.org/airship/airshipctl/pkg/util"
)
// NewVersionCommand prints out the versions of airshipctl and its underlying tools
// NewVersionCommand creates a command for displaying the version of airshipctl.
func NewVersionCommand() *cobra.Command {
versionCmd := &cobra.Command{
Use: "version",

View File

@ -19,8 +19,9 @@
AirshipCTL CLI
==============
The AirshipCTL CLI is used in conjunction with the binary created by running ``make build``. This binary, by default,
is created in the ``airshipctl/bin/`` directory.
The AirshipCTL CLI is used in conjunction with the binary created by running
``make build``. This binary, by default, is created in the ``airshipctl/bin/``
directory.
CLI Options
@ -30,15 +31,15 @@ CLI Options
Prints help for a specific command or command group.
**\\-\\-debug** (Optional, default: false)
**\\-\\-debug** (default: false)
Enables verbose output of commands.
**\\-\\-airshipconf** (Optional, default: `$HOME/.airship/config`)
**\\-\\-airshipconf** (default: `$HOME/.airship/config`)
Path to file for airshipctl configuration.
**\\-\\-kubeconfig** (Optional, default: `$HOME/.airship/kubeconfig`)
**\\-\\-kubeconfig** (default: `$HOME/.airship/kubeconfig`)
Path to kubeconfig associated with airshipctl configuration.
@ -67,11 +68,11 @@ Usage:
Completion
----------
Generate autocompletion script for airshipctl for the specified shell (bash or zsh).
Generate completion script for airshipctl for the specified shell (bash or zsh).
**shell** (Required)
Shell to generate autocompletion script for. Supported values are `bash` and `zsh`
Shell to generate completion script for. Supported values are `bash` and `zsh`
Usage:
@ -82,13 +83,13 @@ Usage:
Examples
^^^^^^^^
This command can generate bash autocompletion. e.g.
Save shell completion to a file
::
$ airshipctl completion bash
$ airshipctl completion bash > $HOME/.airship_completions
Which can be sourced as such:
Apply completions to the current shell
::
@ -128,22 +129,23 @@ Usage:
Cluster Group
=============
Control Kubernetes cluster.
This command provides capabilities for interacting with a Kubernetes cluster,
such as getting status and deploying initial infrastructure.
InitInfra
------------
Deploy initinfra components to cluster.
**cluster-type** (Optional, default:"ephemeral")
**cluster-type** (default:"ephemeral")
Select cluster type to deploy initial infrastructure to, currently only ephemeral is supported.
**\\-\\-dry-run** (Optional).
**\\-\\-dry-run**
Don't deliver documents to the cluster, simulate the changes instead.
**\\-\\-prune** (Optional, default:false)
**\\-\\-prune** (default: false)
If set to true, command will delete all kubernetes resources that are not defined in airship documents and have
airshipit.org/deployed=initinfra label
@ -159,20 +161,20 @@ Usage:
Config Group
============
Modify airshipctl config files
Manage the airshipctl config file
Get-Cluster
-----------
Display cluster information.
Get cluster information from the airshipctl config.
**name** (Optional, default: all defined clusters)
Displays a specific cluster if specified, or if left blank all defined clusters.
Display a specific cluster or all defined clusters if no name is provided.
**\\-\\-cluster-type** (Required).
**\\-\\-cluster-type** (Required if **name** is provided).
cluster-type for the cluster-entry in airshipctl config. Currently only ephemeral cluster types are supported.
The type of the desired cluster. Valid values are from [ephemeral|target].
Usage:
@ -183,7 +185,7 @@ Usage:
Examples
^^^^^^^^
List all the clusters airshipctl knows about:
List all the clusters:
::
@ -198,13 +200,13 @@ Display a specific cluster:
Get-Context
-----------
Displays context information
Display information about contexts such as associated manifests, users, and clusters.
**name** (Optional, default: all defined contexts)
Displays a named context, if no name is provided display all defined contexts.
**\\-\\-current-context** (Optional, default:false)
**\\-\\-current-context** (default: false)
Display the current context, supersedes the `name` argument.
@ -233,43 +235,47 @@ For a named context:
::
airshipctl config get-context e2e
airshipctl config get-context exampleContext
Get-Credentials
---------------
Display a user's information.
Get user credentials from the airshipctl config.
**name** (Optional, default: all defined users)
Display a specific user's information. If no name is specified, list all defined users.
Display a specific user's credentials, or all defined user credentials if no name is provided.
Usage:
::
airshipctl config get-credentials <NAME>
airshipctl config get-credentials <name>
Examples
^^^^^^^^
List all the users airshipctl knows about:
List all user credentials:
::
airshipctl config get-credentials
Display a specific user's information:
Display a specific user's credentials:
::
airshipctl config get-credentials e2e
airshipctl config get-credentials exampleUser
Init
----
Generate initial configuration files for airshipctl
Generate an airshipctl config file and its associated kubeConfig file.
These files will be written to the $HOME/.airship directory, and will contain
default configurations.
.. note:: This will overwrite any existing config files in $HOME/.airship
Usage:
@ -280,35 +286,34 @@ Usage:
Set-Cluster
-----------
Sets a cluster entry in the airshipctl config.
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.
**name** (Required)
The name of the cluster to add to airshipctl config.
The name of the cluster to add or modify in the airshipctl config file.
.. note::
**\\-\\-certificate-authority**
Specifying a name that already exists will merge new fields on top of existing values for those fields.
**\\-\\-certificate-authority** (Optional)
Path to certificate-authority file for the cluster entry in airshipctl config
Path to a certificate authority file
**\\-\\-certificate-authority** (Required)
Cluster-type for the cluster entry in airshipctl config
The type of the cluster to add or modify
**\\-\\-embed-certs** (Optional)
**\\-\\-embed-certs** (default: false)
Embed-certs for the cluster entry in airshipctl config
If set, embed the client certificate/key into the cluster
**\\-\\-insecure-skip-tls-verify** (Optional, default:true)
**\\-\\-insecure-skip-tls-verify** (default: true)
Insecure-skip-tls-verify for the cluster entry in airshipctl config
If set, disable certificate checking
**\\-\\-server** (Optional)
**\\-\\-server**
Server for the cluster entry in airshipctl config
Server to use for the cluster
Usage:
@ -319,62 +324,72 @@ Usage:
Examples
^^^^^^^^
Set only the server field on the e2e cluster entry without touching other values:
Set the server field on the ephemeral exampleCluster:
::
airshipctl config set-cluster e2e --cluster-type=ephemeral --server=https://1.2.3.4
airshipctl config set-cluster exampleCluster \
--cluster-type=ephemeral \
--server=https://1.2.3.4
Embed certificate authority data for the e2e cluster entry:
Embed certificate authority data for the target exampleCluster:
::
airshipctl config set-cluster e2e --cluster-type=target --certificate-authority-authority=~/.airship/e2e/kubernetes.ca.crt
airshipctl config set-cluster exampleCluster \
--cluster-type=target \
--client-certificate-authority=$HOME/.airship/ca/kubernetes.ca.crt \
--embed-certs
Disable cert checking for the dev cluster entry:
Disable certificate checking for the target exampleCluster:
::
airshipctl config set-cluster e2e --cluster-type=target --insecure-skip-tls-verify=true
airshipctl config set-cluster exampleCluster
--cluster-type=target \
--insecure-skip-tls-verify
Configure client certificate:
Configure client certificate for the target exampleCluster:
::
airshipctl config set-cluster e2e --cluster-type=target --embed-certs=true --client-certificate=".airship/cert_file"
airshipctl config set-cluster exampleCluster \
--cluster-type=target \
--embed-certs \
--client-certificate=$HOME/.airship/cert_file
Set-Context
-----------
Switch to a new context, or update context values in the airshipctl config
Create or modify a context in the airshipctl config files.
**name** (Required)
The name of the context to set.
The name of the context to add or modify in the airshipctl config file.
**\\-\\-cluster-string**
**\\-\\-cluster**
Sets the cluster for the specified context in the airshipctl config.
Set the cluster for the specified context.
**\\-\\-cluster-type**
Sets the cluster-type for the specified context in the airshipctl config.
Set the cluster-type for the specified context.
**\\-\\-current**
Use current context from airshipctl config.
Update the current context.
**\\-\\-manifest**
Sets the manifest for the specified context in the airshipctl config.
Set the manifest for the specified context.
**\\-\\-namespace**
Sets the namespace for the specified context in the airshipctl config.
Set the namespace for the specified context.
**\\-\\-user**
Sets the user for the specified context in the airshipctl config.
Set the user for the specified context.
Usage:
@ -385,63 +400,63 @@ Usage:
Examples
^^^^^^^^
Create a completely new e2e context entry:
Create a new context named "exampleContext":
::
airshipctl config set-context e2e --namespace=kube-system --manifest=manifest --user=auth-info --cluster-type=target
airshipctl config set-context exampleContext \
--namespace=kube-system \
--manifest=exampleManifest \
--user=exampleUser
--cluster-type=target
Update the current-context to e2e:
Update the manifest of the current-context:
::
airshipctl config set-context e2e
Update attributes of the current-context:
::
airshipctl config set-context --current --manifest=manifest
airshipctl config set-context \
--current \
--manifest=exampleManifest
Set-Credentials
---------------
Sets a user entry in the airshipctl config.
Create or modify a user credential in the airshipctl config file.
.. note:: Specifying more than one authentication method is an error.
**name** (Required)
The user entry to update in airshipctl config.
.. note:: Specifying a name that already exists will merge new fields on top of existing values.
**\\-\\-client-certificate**
Path to client-certificate file for the user entry in airshipctl
Path to a certificate file.
**\\-\\-client-key**
Path to client-key file for the user entry in airshipctl
Path to a key file.
**\\-\\-embed-certs**
Embed client cert/key for the user entry in airshipctl
If set, embed the client certificate/key into the credential.
**\\-\\-password**
Password for the user entry in airshipctl
Password for the credential
.. note:: Username and Password flags are mutually exclusive with Token flag
**\\-\\-token**
Token for the user entry in airshipctl
Token to use for the credential
.. note:: Username and Password flags are mutually exclusive with Token flag
**\\-\\-username**
Username for the user entry in airshipctl
Username for the credential
.. note:: Username and Password flags are mutually exclusive with Token flag
@ -454,23 +469,36 @@ Usage:
Examples
^^^^^^^^
Set only the "client-key" field on the "cluster-admin" entry, without touching other values:
Create a new user credential with basic auth:
::
airshipctl config set-credentials cluster-admin --username=~/.kube/admin.key
airshipctl config set-credentials exampleUser \
--username=exampleUser \
--password=examplePassword
Set basic auth for the "cluster-admin" entry
Change the client-key of a user named admin
::
airshipctl config set-credentials cluster-admin --username=admin --password=uXFGweU9l35qcif
airshipctl config set-credentials admin \
--client-key=$HOME/.kube/admin.key
Embed client certificate data in the "cluster-admin" entry
Change the username and password of the admin user
::
airshipctl config set-credentials cluster-admin --client-certificate=~/.kube/admin.crt --embed-certs=true
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
.. _document-group:

View File

@ -54,26 +54,3 @@ const (
AirshipDefaultIsoURL = "http://localhost:8099/debian-custom.iso"
AirshipDefaultRemoteType = redfish.ClientType
)
const (
FlagAPIServer = "server"
FlagAuthInfoName = "user"
FlagBearerToken = "token"
FlagCAFile = "certificate-authority"
FlagCertFile = "client-certificate"
FlagClusterName = "cluster"
FlagClusterType = "cluster-type"
FlagCurrentContext = "current-context"
FlagConfigFilePath = "airshipconf"
FlagEmbedCerts = "embed-certs"
FlagInsecure = "insecure-skip-tls-verify"
FlagKeyFile = "client-key"
FlagManifest = "manifest"
FlagNamespace = "namespace"
FlagPassword = "password"
FlagUsername = "username"
FlagCurrent = "current"
)

View File

@ -54,21 +54,33 @@ type ClusterOptions struct {
EmbedCAData bool
}
// TODO(howell): The following functions are tightly coupled with flags passed
// on the command line. We should find a way to remove this coupling, since it
// is possible to create (and validate) these objects without using the command
// line.
// TODO(howell): strongly type the errors in this file
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 fmt.Errorf("you cannot specify more than one authentication method at the same time: --%v or --%v/--%v",
FlagBearerToken, FlagUsername, FlagPassword)
// TODO(howell): strongly type this error
return errors.New("you must specify either token or a username/password")
}
if !o.EmbedCertData {
return nil
}
if err := checkExists(FlagCertFile, o.ClientCertificate); err != nil {
if err := checkExists("client-certificate", o.ClientCertificate); err != nil {
return err
}
if err := checkExists(FlagKeyFile, o.ClientKey); err != nil {
if err := checkExists("client-key", o.ClientKey); err != nil {
return err
}
@ -81,7 +93,7 @@ func (o *ContextOptions) Validate() error {
}
if o.Current && o.Name != "" {
return fmt.Errorf("you cannot specify context and --%s Flag at the same time", FlagCurrent)
return errors.New("you cannot specify context and --current Flag at the same time")
}
// If the user simply wants to change the current context, no further validation is needed
@ -111,14 +123,14 @@ func (o *ClusterOptions) Validate() error {
}
if o.InsecureSkipTLSVerify && o.CertificateAuthority != "" {
return fmt.Errorf("you cannot specify a %s and %s mode at the same time", FlagCAFile, FlagInsecure)
return errors.New("you cannot specify a certificate-authority and insecure-skip-tls-verify mode at the same time")
}
if !o.EmbedCAData {
return nil
}
if err := checkExists(FlagCAFile, o.CertificateAuthority); err != nil {
if err := checkExists("certificate-authority", o.CertificateAuthority); err != nil {
return err
}

View File

@ -49,7 +49,7 @@ func (a *AirshipCTLSettings) InitFlags(cmd *cobra.Command) {
defaultAirshipConfigPath := filepath.Join(defaultAirshipConfigDir, config.AirshipConfig)
flags.StringVar(
&a.AirshipConfigPath,
config.FlagConfigFilePath,
"airshipconf",
"",
`Path to file for airshipctl configuration. (default "`+defaultAirshipConfigPath+`")`)