2019-01-12 04:58:27 +00:00
/ *
Copyright 2015 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 create
import (
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
2019-09-27 21:51:53 +00:00
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/generate"
generateversioned "k8s.io/kubectl/pkg/generate/versioned"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
2019-01-12 04:58:27 +00:00
)
// NewCmdCreateSecret groups subcommands to create various types of secrets
func NewCmdCreateSecret ( f cmdutil . Factory , ioStreams genericclioptions . IOStreams ) * cobra . Command {
cmd := & cobra . Command {
Use : "secret" ,
Short : i18n . T ( "Create a secret using specified subcommand" ) ,
Long : "Create a secret using specified subcommand." ,
Run : cmdutil . DefaultSubCommandRun ( ioStreams . ErrOut ) ,
}
cmd . AddCommand ( NewCmdCreateSecretDockerRegistry ( f , ioStreams ) )
cmd . AddCommand ( NewCmdCreateSecretTLS ( f , ioStreams ) )
cmd . AddCommand ( NewCmdCreateSecretGeneric ( f , ioStreams ) )
return cmd
}
var (
secretLong = templates . LongDesc ( i18n . T ( `
Create a secret based on a file , directory , or specified literal value .
A single secret may package one or more key / value pairs .
When creating a secret based on a file , the key will default to the basename of the file , and the value will
default to the file content . If the basename is an invalid key or you wish to chose your own , you may specify
an alternate key .
When creating a secret based on a directory , each file whose basename is a valid key in the directory will be
packaged into the secret . Any directory entries except regular files are ignored ( e . g . subdirectories ,
symlinks , devices , pipes , etc ) . ` ) )
secretExample = templates . Examples ( i18n . T ( `
# Create a new secret named my - secret with keys for each file in folder bar
kubectl create secret generic my - secret -- from - file = path / to / bar
# Create a new secret named my - secret with specified keys instead of names on disk
2019-08-30 18:33:25 +00:00
kubectl create secret generic my - secret -- from - file = ssh - privatekey = path / to / id_rsa -- from - file = ssh - publickey = path / to / id_rsa . pub
2019-01-12 04:58:27 +00:00
# Create a new secret named my - secret with key1 = supersecret and key2 = topsecret
kubectl create secret generic my - secret -- from - literal = key1 = supersecret -- from - literal = key2 = topsecret
# Create a new secret named my - secret using a combination of a file and a literal
2019-08-30 18:33:25 +00:00
kubectl create secret generic my - secret -- from - file = ssh - privatekey = path / to / id_rsa -- from - literal = passphrase = topsecret
2019-01-12 04:58:27 +00:00
# Create a new secret named my - secret from an env file
kubectl create secret generic my - secret -- from - env - file = path / to / bar . env ` ) )
)
2019-04-07 17:07:55 +00:00
// SecretGenericOpts holds the options for 'create secret' sub command
2019-01-12 04:58:27 +00:00
type SecretGenericOpts struct {
CreateSubcommandOptions * CreateSubcommandOptions
}
// NewCmdCreateSecretGeneric is a command to create generic secrets from files, directories, or literal values
func NewCmdCreateSecretGeneric ( f cmdutil . Factory , ioStreams genericclioptions . IOStreams ) * cobra . Command {
options := & SecretGenericOpts {
CreateSubcommandOptions : NewCreateSubcommandOptions ( ioStreams ) ,
}
cmd := & cobra . Command {
2020-03-26 21:07:15 +00:00
Use : "generic NAME [--type=string] [--from-file=[key=]source] [--from-literal=key1=value1] [--dry-run=server|client|none]" ,
2019-01-12 04:58:27 +00:00
DisableFlagsInUseLine : true ,
Short : i18n . T ( "Create a secret from a local file, directory or literal value" ) ,
Long : secretLong ,
Example : secretExample ,
Run : func ( cmd * cobra . Command , args [ ] string ) {
cmdutil . CheckErr ( options . Complete ( f , cmd , args ) )
cmdutil . CheckErr ( options . Run ( ) )
} ,
}
options . CreateSubcommandOptions . PrintFlags . AddFlags ( cmd )
cmdutil . AddApplyAnnotationFlags ( cmd )
cmdutil . AddValidateFlags ( cmd )
cmdutil . AddGeneratorFlags ( cmd , generateversioned . SecretV1GeneratorName )
cmd . Flags ( ) . StringSlice ( "from-file" , [ ] string { } , "Key files can be specified using their file path, in which case a default name will be given to them, or optionally with a name and file path, in which case the given name will be used. Specifying a directory will iterate each named file in the directory that is a valid secret key." )
cmd . Flags ( ) . StringArray ( "from-literal" , [ ] string { } , "Specify a key and literal value to insert in secret (i.e. mykey=somevalue)" )
cmd . Flags ( ) . String ( "from-env-file" , "" , "Specify the path to a file to read lines of key=val pairs to create a secret (i.e. a Docker .env file)." )
cmd . Flags ( ) . String ( "type" , "" , i18n . T ( "The type of secret to create" ) )
cmd . Flags ( ) . Bool ( "append-hash" , false , "Append a hash of the secret to its name." )
2020-08-10 17:43:49 +00:00
cmdutil . AddFieldManagerFlagVar ( cmd , & options . CreateSubcommandOptions . FieldManager , "kubectl-create" )
2019-01-12 04:58:27 +00:00
return cmd
}
2019-04-07 17:07:55 +00:00
// Complete completes all the required options
2019-01-12 04:58:27 +00:00
func ( o * SecretGenericOpts ) Complete ( f cmdutil . Factory , cmd * cobra . Command , args [ ] string ) error {
name , err := NameFromCommandArgs ( cmd , args )
if err != nil {
return err
}
var generator generate . StructuredGenerator
switch generatorName := cmdutil . GetFlagString ( cmd , "generator" ) ; generatorName {
case generateversioned . SecretV1GeneratorName :
generator = & generateversioned . SecretGeneratorV1 {
Name : name ,
Type : cmdutil . GetFlagString ( cmd , "type" ) ,
FileSources : cmdutil . GetFlagStringSlice ( cmd , "from-file" ) ,
LiteralSources : cmdutil . GetFlagStringArray ( cmd , "from-literal" ) ,
EnvFileSource : cmdutil . GetFlagString ( cmd , "from-env-file" ) ,
AppendHash : cmdutil . GetFlagBool ( cmd , "append-hash" ) ,
}
default :
return errUnsupportedGenerator ( cmd , generatorName )
}
return o . CreateSubcommandOptions . Complete ( f , cmd , args , generator )
}
2019-04-07 17:07:55 +00:00
// Run calls the CreateSubcommandOptions.Run in SecretGenericOpts instance
2019-01-12 04:58:27 +00:00
func ( o * SecretGenericOpts ) Run ( ) error {
return o . CreateSubcommandOptions . Run ( )
}
var (
secretForDockerRegistryLong = templates . LongDesc ( i18n . T ( `
Create a new secret for use with Docker registries .
Dockercfg secrets are used to authenticate against Docker registries .
When using the Docker command line to push images , you can authenticate to a given registry by running :
' $ docker login DOCKER_REGISTRY_SERVER -- username = DOCKER_USER -- password = DOCKER_PASSWORD -- email = DOCKER_EMAIL ' .
That produces a ~ / . dockercfg file that is used by subsequent ' docker push ' and ' docker pull ' commands to
authenticate to the registry . The email address is optional .
When creating applications , you may have a Docker registry that requires authentication . In order for the
nodes to pull images on your behalf , they have to have the credentials . You can provide this information
by creating a dockercfg secret and attaching it to your service account . ` ) )
secretForDockerRegistryExample = templates . Examples ( i18n . T ( `
# If you don ' t already have a . dockercfg file , you can create a dockercfg secret directly by using :
kubectl create secret docker - registry my - secret -- docker - server = DOCKER_REGISTRY_SERVER -- docker - username = DOCKER_USER -- docker - password = DOCKER_PASSWORD -- docker - email = DOCKER_EMAIL ` ) )
)
2019-04-07 17:07:55 +00:00
// SecretDockerRegistryOpts holds the options for 'create secret docker-registry' sub command
2019-01-12 04:58:27 +00:00
type SecretDockerRegistryOpts struct {
CreateSubcommandOptions * CreateSubcommandOptions
}
// NewCmdCreateSecretDockerRegistry is a macro command for creating secrets to work with Docker registries
func NewCmdCreateSecretDockerRegistry ( f cmdutil . Factory , ioStreams genericclioptions . IOStreams ) * cobra . Command {
options := & SecretDockerRegistryOpts {
CreateSubcommandOptions : NewCreateSubcommandOptions ( ioStreams ) ,
}
cmd := & cobra . Command {
2020-03-26 21:07:15 +00:00
Use : "docker-registry NAME --docker-username=user --docker-password=password --docker-email=email [--docker-server=string] [--from-literal=key1=value1] [--dry-run=server|client|none]" ,
2019-01-12 04:58:27 +00:00
DisableFlagsInUseLine : true ,
Short : i18n . T ( "Create a secret for use with a Docker registry" ) ,
Long : secretForDockerRegistryLong ,
Example : secretForDockerRegistryExample ,
Run : func ( cmd * cobra . Command , args [ ] string ) {
cmdutil . CheckErr ( options . Complete ( f , cmd , args ) )
cmdutil . CheckErr ( options . Run ( ) )
} ,
}
options . CreateSubcommandOptions . PrintFlags . AddFlags ( cmd )
cmdutil . AddApplyAnnotationFlags ( cmd )
cmdutil . AddValidateFlags ( cmd )
cmdutil . AddGeneratorFlags ( cmd , generateversioned . SecretForDockerRegistryV1GeneratorName )
cmd . Flags ( ) . String ( "docker-username" , "" , i18n . T ( "Username for Docker registry authentication" ) )
cmd . Flags ( ) . String ( "docker-password" , "" , i18n . T ( "Password for Docker registry authentication" ) )
cmd . Flags ( ) . String ( "docker-email" , "" , i18n . T ( "Email for Docker registry" ) )
cmd . Flags ( ) . String ( "docker-server" , "https://index.docker.io/v1/" , i18n . T ( "Server location for Docker registry" ) )
cmd . Flags ( ) . Bool ( "append-hash" , false , "Append a hash of the secret to its name." )
cmd . Flags ( ) . StringSlice ( "from-file" , [ ] string { } , "Key files can be specified using their file path, in which case a default name will be given to them, or optionally with a name and file path, in which case the given name will be used. Specifying a directory will iterate each named file in the directory that is a valid secret key." )
2020-08-10 17:43:49 +00:00
cmdutil . AddFieldManagerFlagVar ( cmd , & options . CreateSubcommandOptions . FieldManager , "kubectl-create" )
2019-01-12 04:58:27 +00:00
return cmd
}
2019-04-07 17:07:55 +00:00
// Complete completes all the required options
2019-01-12 04:58:27 +00:00
func ( o * SecretDockerRegistryOpts ) Complete ( f cmdutil . Factory , cmd * cobra . Command , args [ ] string ) error {
name , err := NameFromCommandArgs ( cmd , args )
if err != nil {
return err
}
fromFileFlag := cmdutil . GetFlagStringSlice ( cmd , "from-file" )
if len ( fromFileFlag ) == 0 {
requiredFlags := [ ] string { "docker-username" , "docker-password" , "docker-server" }
for _ , requiredFlag := range requiredFlags {
if value := cmdutil . GetFlagString ( cmd , requiredFlag ) ; len ( value ) == 0 {
return cmdutil . UsageErrorf ( cmd , "flag %s is required" , requiredFlag )
}
}
}
var generator generate . StructuredGenerator
switch generatorName := cmdutil . GetFlagString ( cmd , "generator" ) ; generatorName {
case generateversioned . SecretForDockerRegistryV1GeneratorName :
generator = & generateversioned . SecretForDockerRegistryGeneratorV1 {
Name : name ,
Username : cmdutil . GetFlagString ( cmd , "docker-username" ) ,
Email : cmdutil . GetFlagString ( cmd , "docker-email" ) ,
Password : cmdutil . GetFlagString ( cmd , "docker-password" ) ,
Server : cmdutil . GetFlagString ( cmd , "docker-server" ) ,
AppendHash : cmdutil . GetFlagBool ( cmd , "append-hash" ) ,
FileSources : cmdutil . GetFlagStringSlice ( cmd , "from-file" ) ,
}
default :
return errUnsupportedGenerator ( cmd , generatorName )
}
return o . CreateSubcommandOptions . Complete ( f , cmd , args , generator )
}
2019-04-07 17:07:55 +00:00
// Run calls CreateSubcommandOptions.Run in SecretDockerRegistryOpts instance
2019-01-12 04:58:27 +00:00
func ( o * SecretDockerRegistryOpts ) Run ( ) error {
return o . CreateSubcommandOptions . Run ( )
}
var (
secretForTLSLong = templates . LongDesc ( i18n . T ( `
Create a TLS secret from the given public / private key pair .
The public / private key pair must exist before hand . The public key certificate must be . PEM encoded and match
the given private key . ` ) )
secretForTLSExample = templates . Examples ( i18n . T ( `
# Create a new TLS secret named tls - secret with the given key pair :
kubectl create secret tls tls - secret -- cert = path / to / tls . cert -- key = path / to / tls . key ` ) )
)
2019-04-07 17:07:55 +00:00
// SecretTLSOpts holds the options for 'create secret tls' sub command
2019-01-12 04:58:27 +00:00
type SecretTLSOpts struct {
CreateSubcommandOptions * CreateSubcommandOptions
}
// NewCmdCreateSecretTLS is a macro command for creating secrets to work with Docker registries
func NewCmdCreateSecretTLS ( f cmdutil . Factory , ioStreams genericclioptions . IOStreams ) * cobra . Command {
options := & SecretTLSOpts {
CreateSubcommandOptions : NewCreateSubcommandOptions ( ioStreams ) ,
}
cmd := & cobra . Command {
2020-03-26 21:07:15 +00:00
Use : "tls NAME --cert=path/to/cert/file --key=path/to/key/file [--dry-run=server|client|none]" ,
2019-01-12 04:58:27 +00:00
DisableFlagsInUseLine : true ,
Short : i18n . T ( "Create a TLS secret" ) ,
Long : secretForTLSLong ,
Example : secretForTLSExample ,
Run : func ( cmd * cobra . Command , args [ ] string ) {
cmdutil . CheckErr ( options . Complete ( f , cmd , args ) )
cmdutil . CheckErr ( options . Run ( ) )
} ,
}
options . CreateSubcommandOptions . PrintFlags . AddFlags ( cmd )
cmdutil . AddApplyAnnotationFlags ( cmd )
cmdutil . AddValidateFlags ( cmd )
cmdutil . AddGeneratorFlags ( cmd , generateversioned . SecretForTLSV1GeneratorName )
cmd . Flags ( ) . String ( "cert" , "" , i18n . T ( "Path to PEM encoded public key certificate." ) )
cmd . Flags ( ) . String ( "key" , "" , i18n . T ( "Path to private key associated with given certificate." ) )
cmd . Flags ( ) . Bool ( "append-hash" , false , "Append a hash of the secret to its name." )
2020-08-10 17:43:49 +00:00
cmdutil . AddFieldManagerFlagVar ( cmd , & options . CreateSubcommandOptions . FieldManager , "kubectl-create" )
2019-01-12 04:58:27 +00:00
return cmd
}
2019-04-07 17:07:55 +00:00
// Complete completes all the required options
2019-01-12 04:58:27 +00:00
func ( o * SecretTLSOpts ) Complete ( f cmdutil . Factory , cmd * cobra . Command , args [ ] string ) error {
name , err := NameFromCommandArgs ( cmd , args )
if err != nil {
return err
}
requiredFlags := [ ] string { "cert" , "key" }
for _ , requiredFlag := range requiredFlags {
if value := cmdutil . GetFlagString ( cmd , requiredFlag ) ; len ( value ) == 0 {
return cmdutil . UsageErrorf ( cmd , "flag %s is required" , requiredFlag )
}
}
var generator generate . StructuredGenerator
switch generatorName := cmdutil . GetFlagString ( cmd , "generator" ) ; generatorName {
case generateversioned . SecretForTLSV1GeneratorName :
generator = & generateversioned . SecretForTLSGeneratorV1 {
Name : name ,
Key : cmdutil . GetFlagString ( cmd , "key" ) ,
Cert : cmdutil . GetFlagString ( cmd , "cert" ) ,
AppendHash : cmdutil . GetFlagBool ( cmd , "append-hash" ) ,
}
default :
return errUnsupportedGenerator ( cmd , generatorName )
}
return o . CreateSubcommandOptions . Complete ( f , cmd , args , generator )
}
2019-04-07 17:07:55 +00:00
// Run calls CreateSubcommandOptions.Run in the SecretTLSOpts instance
2019-01-12 04:58:27 +00:00
func ( o * SecretTLSOpts ) Run ( ) error {
return o . CreateSubcommandOptions . Run ( )
}