mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-31 15:25:57 +00:00
create secret from-env-file
This commit is contained in:
parent
7eb49628c6
commit
f2815156b0
@ -19,6 +19,7 @@ go_library(
|
||||
"configmap.go",
|
||||
"deployment.go",
|
||||
"doc.go",
|
||||
"env_file.go",
|
||||
"explain.go",
|
||||
"generate.go",
|
||||
"history.go",
|
||||
|
@ -64,7 +64,10 @@ var (
|
||||
kubectl create secret generic my-secret --from-file=ssh-privatekey=~/.ssh/id_rsa --from-file=ssh-publickey=~/.ssh/id_rsa.pub
|
||||
|
||||
# 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`)
|
||||
kubectl create secret generic my-secret --from-literal=key1=supersecret --from-literal=key2=topsecret
|
||||
|
||||
# Create a new secret named my-secret from an env file
|
||||
kubectl create secret generic my-secret --from-env-file=path/to/bar.env`)
|
||||
)
|
||||
|
||||
// NewCmdCreateSecretGeneric is a command to create generic secrets from files, directories, or literal values
|
||||
@ -85,6 +88,7 @@ func NewCmdCreateSecretGeneric(f cmdutil.Factory, cmdOut io.Writer) *cobra.Comma
|
||||
cmdutil.AddGeneratorFlags(cmd, cmdutil.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"))
|
||||
return cmd
|
||||
}
|
||||
@ -103,6 +107,7 @@ func CreateSecretGeneric(f cmdutil.Factory, cmdOut io.Writer, cmd *cobra.Command
|
||||
Type: cmdutil.GetFlagString(cmd, "type"),
|
||||
FileSources: cmdutil.GetFlagStringSlice(cmd, "from-file"),
|
||||
LiteralSources: cmdutil.GetFlagStringArray(cmd, "from-literal"),
|
||||
EnvFileSource: cmdutil.GetFlagString(cmd, "from-env-file"),
|
||||
}
|
||||
default:
|
||||
return cmdutil.UsageError(cmd, fmt.Sprintf("Generator: %s not supported.", generatorName))
|
||||
|
@ -221,7 +221,10 @@ func handleConfigMapFromEnvFileSource(configMap *api.ConfigMap, envFileSource st
|
||||
if info.IsDir() {
|
||||
return fmt.Errorf("must be a file")
|
||||
}
|
||||
return addFromEnvFileToConfigMap(configMap, envFileSource)
|
||||
|
||||
return addFromEnvFile(envFileSource, func(key, value string) error {
|
||||
return addKeyFromLiteralToConfigMap(configMap, key, value)
|
||||
})
|
||||
}
|
||||
|
||||
// addKeyFromFileToConfigMap adds a key with the given name to a ConfigMap, populating
|
||||
|
@ -38,6 +38,8 @@ type SecretGeneratorV1 struct {
|
||||
FileSources []string
|
||||
// LiteralSources to derive the secret from (optional)
|
||||
LiteralSources []string
|
||||
// EnvFileSource to derive the secret from (optional)
|
||||
EnvFileSource string
|
||||
}
|
||||
|
||||
// Ensure it supports the generator pattern that uses parameter injection
|
||||
@ -71,6 +73,15 @@ func (s SecretGeneratorV1) Generate(genericParams map[string]interface{}) (runti
|
||||
delegate.LiteralSources = fromLiteralArray
|
||||
delete(genericParams, "from-literal")
|
||||
}
|
||||
fromEnvFileString, found := genericParams["from-env-file"]
|
||||
if found {
|
||||
fromEnvFile, isString := fromEnvFileString.(string)
|
||||
if !isString {
|
||||
return nil, fmt.Errorf("expected string, found :%v", fromEnvFileString)
|
||||
}
|
||||
delegate.EnvFileSource = fromEnvFile
|
||||
delete(genericParams, "from-env-file")
|
||||
}
|
||||
params := map[string]string{}
|
||||
for key, value := range genericParams {
|
||||
strVal, isString := value.(string)
|
||||
@ -91,6 +102,7 @@ func (s SecretGeneratorV1) ParamNames() []GeneratorParam {
|
||||
{"type", false},
|
||||
{"from-file", false},
|
||||
{"from-literal", false},
|
||||
{"from-env-file", false},
|
||||
{"force", false},
|
||||
}
|
||||
}
|
||||
@ -116,6 +128,11 @@ func (s SecretGeneratorV1) StructuredGenerate() (runtime.Object, error) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if len(s.EnvFileSource) > 0 {
|
||||
if err := handleFromEnvFileSource(secret, s.EnvFileSource); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return secret, nil
|
||||
}
|
||||
|
||||
@ -124,6 +141,9 @@ func (s SecretGeneratorV1) validate() error {
|
||||
if len(s.Name) == 0 {
|
||||
return fmt.Errorf("name must be specified")
|
||||
}
|
||||
if len(s.EnvFileSource) > 0 && (len(s.FileSources) > 0 || len(s.LiteralSources) > 0) {
|
||||
return fmt.Errorf("from-env-file cannot be combined with from-file or from-literal")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -187,6 +207,27 @@ func handleFromFileSources(secret *api.Secret, fileSources []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// handleFromEnvFileSource adds the specified env file source information
|
||||
// into the provided secret
|
||||
func handleFromEnvFileSource(secret *api.Secret, envFileSource string) error {
|
||||
info, err := os.Stat(envFileSource)
|
||||
if err != nil {
|
||||
switch err := err.(type) {
|
||||
case *os.PathError:
|
||||
return fmt.Errorf("error reading %s: %v", envFileSource, err.Err)
|
||||
default:
|
||||
return fmt.Errorf("error reading %s: %v", envFileSource, err)
|
||||
}
|
||||
}
|
||||
if info.IsDir() {
|
||||
return fmt.Errorf("must be a file")
|
||||
}
|
||||
|
||||
return addFromEnvFile(envFileSource, func(key, value string) error {
|
||||
return addKeyFromLiteralToSecret(secret, key, []byte(value))
|
||||
})
|
||||
}
|
||||
|
||||
func addKeyFromFileToSecret(secret *api.Secret, keyName, filePath string) error {
|
||||
data, err := ioutil.ReadFile(filePath)
|
||||
if err != nil {
|
||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
||||
package kubectl
|
||||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
@ -26,6 +27,7 @@ import (
|
||||
|
||||
func TestSecretGenerate(t *testing.T) {
|
||||
tests := []struct {
|
||||
setup func(t *testing.T, params map[string]interface{}) func()
|
||||
params map[string]interface{}
|
||||
expected *api.Secret
|
||||
expectErr bool
|
||||
@ -108,9 +110,84 @@ func TestSecretGenerate(t *testing.T) {
|
||||
},
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
setup: setupEnvFile("key1=value1", "#", "", "key2=value2"),
|
||||
params: map[string]interface{}{
|
||||
"name": "valid_env",
|
||||
"from-env-file": "file.env",
|
||||
},
|
||||
expected: &api.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "valid_env",
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"key1": []byte("value1"),
|
||||
"key2": []byte("value2"),
|
||||
},
|
||||
},
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
setup: func() func(t *testing.T, params map[string]interface{}) func() {
|
||||
os.Setenv("g_key1", "1")
|
||||
os.Setenv("g_key2", "2")
|
||||
return setupEnvFile("g_key1", "g_key2=")
|
||||
}(),
|
||||
params: map[string]interface{}{
|
||||
"name": "getenv",
|
||||
"from-env-file": "file.env",
|
||||
},
|
||||
expected: &api.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "getenv",
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"g_key1": []byte("1"),
|
||||
"g_key2": []byte(""),
|
||||
},
|
||||
},
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
params: map[string]interface{}{
|
||||
"name": "too_many_args",
|
||||
"from-literal": []string{"key1=value1"},
|
||||
"from-env-file": "file.env",
|
||||
},
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
setup: setupEnvFile("key.1=value1"),
|
||||
params: map[string]interface{}{
|
||||
"name": "invalid_key",
|
||||
"from-env-file": "file.env",
|
||||
},
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
setup: setupEnvFile(" key1= value1"),
|
||||
params: map[string]interface{}{
|
||||
"name": "with_spaces",
|
||||
"from-env-file": "file.env",
|
||||
},
|
||||
expected: &api.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "with_spaces",
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"key1": []byte(" value1"),
|
||||
},
|
||||
},
|
||||
expectErr: false,
|
||||
},
|
||||
}
|
||||
generator := SecretGeneratorV1{}
|
||||
for _, test := range tests {
|
||||
if test.setup != nil {
|
||||
if teardown := test.setup(t, test.params); teardown != nil {
|
||||
defer teardown()
|
||||
}
|
||||
}
|
||||
obj, err := generator.Generate(test.params)
|
||||
if !test.expectErr && err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
|
Loading…
Reference in New Issue
Block a user