Add timeoutSeconds to secretArgs

This commit is contained in:
Ivan Shvedunov
2018-08-14 22:50:33 +03:00
parent f9577ab540
commit f9a0e671b7
5 changed files with 77 additions and 8 deletions

View File

@@ -83,6 +83,9 @@ secretGenerator:
tls.key: "cat secret/tls.key"
type: "kubernetes.io/tls"
- name: downloaded_secret
# timeoutSeconds specifies the number of seconds to
# wait for the commands below. It defaults to 5 seconds.
timeoutSeconds: 30
commands:
username: "curl -s https://path/to/secrets/username.yaml"
password: "curl -s https://path/to/secrets/password.yaml"

View File

@@ -19,6 +19,7 @@ package app
import (
"encoding/base64"
"reflect"
"strings"
"testing"
"github.com/kubernetes-sigs/kustomize/pkg/constants"
@@ -53,6 +54,14 @@ secretGenerator:
DB_USERNAME: "printf admin"
DB_PASSWORD: "printf somepw"
type: Opaque
`
kustomizationContent2 = `
secretGenerator:
- name: secret
timeoutSeconds: 1
commands:
USER: "sleep 2"
type: Opaque
`
deploymentContent = `apiVersion: apps/v1
metadata:
@@ -340,3 +349,24 @@ func TestRawResources2(t *testing.T) {
t.Fatalf("unexpected inequality: %v", err)
}
}
func TestSecretTimeout(t *testing.T) {
l := loadertest.NewFakeLoader("/testpath")
err := l.AddFile("/testpath/"+constants.KustomizationFileName, []byte(kustomizationContent2))
if err != nil {
t.Fatalf("Failed to setup fake ldr.")
}
fakeFs := fs.MakeFakeFS()
fakeFs.Mkdir("/")
app, err := NewApplication(l, fakeFs)
if err != nil {
t.Fatalf("Unexpected construction error %v", err)
}
_, err = app.MakeCustomizedResMap()
if err == nil {
t.Fatalf("Didn't get the expected error for an unknown resource")
}
if !strings.Contains(err.Error(), "killed") {
t.Fatalf("Unpexpected error message %q", err)
}
}

View File

@@ -31,6 +31,10 @@ import (
"k8s.io/apimachinery/pkg/util/validation"
)
const (
defaultCommandTimeout = 5 * time.Second
)
// SecretFactory makes Secrets.
type SecretFactory struct {
fSys fs.FileSystem
@@ -61,7 +65,12 @@ func (f *SecretFactory) MakeSecret(args *types.SecretArgs) (*corev1.Secret, erro
var err error
s := f.makeFreshSecret(args)
pairs, err := f.keyValuesFromEnvFileCommand(args.EnvCommand)
timeout := defaultCommandTimeout
if args.TimeoutSeconds != nil {
timeout = time.Duration(*args.TimeoutSeconds) * time.Second
}
pairs, err := f.keyValuesFromEnvFileCommand(args.EnvCommand, timeout)
if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf(
"env source file: %s",
@@ -69,7 +78,7 @@ func (f *SecretFactory) MakeSecret(args *types.SecretArgs) (*corev1.Secret, erro
}
all = append(all, pairs...)
pairs, err = f.keyValuesFromCommands(args.Commands)
pairs, err = f.keyValuesFromCommands(args.Commands, timeout)
if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf(
"commands %v", args.Commands))
@@ -98,18 +107,18 @@ func addKvToSecret(secret *corev1.Secret, keyName, data string) error {
return nil
}
func (f *SecretFactory) keyValuesFromEnvFileCommand(cmd string) ([]kvPair, error) {
content, err := f.createSecretKey(cmd)
func (f *SecretFactory) keyValuesFromEnvFileCommand(cmd string, timeout time.Duration) ([]kvPair, error) {
content, err := f.createSecretKey(cmd, timeout)
if err != nil {
return nil, err
}
return keyValuesFromLines(content)
}
func (f *SecretFactory) keyValuesFromCommands(sources map[string]string) ([]kvPair, error) {
func (f *SecretFactory) keyValuesFromCommands(sources map[string]string, timeout time.Duration) ([]kvPair, error) {
var kvs []kvPair
for k, cmd := range sources {
content, err := f.createSecretKey(cmd)
content, err := f.createSecretKey(cmd, timeout)
if err != nil {
return nil, err
}
@@ -119,14 +128,14 @@ func (f *SecretFactory) keyValuesFromCommands(sources map[string]string) ([]kvPa
}
// Run a command, return its output as the secret.
func (f *SecretFactory) createSecretKey(command string) ([]byte, error) {
func (f *SecretFactory) createSecretKey(command string, timeout time.Duration) ([]byte, error) {
if !f.fSys.IsDir(f.wd) {
f.wd = filepath.Dir(f.wd)
if !f.fSys.IsDir(f.wd) {
return nil, errors.New("not a directory: " + f.wd)
}
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
cmd := exec.CommandContext(ctx, "sh", "-c", command)
cmd.Dir = f.wd

View File

@@ -94,3 +94,27 @@ func TestNewResMapFromSecretArgs(t *testing.T) {
t.Fatalf("%#v\ndoesn't match expected:\n%#v", actual, expected)
}
}
func TestSecretTimeout(t *testing.T) {
timeout := int64(1)
secrets := []types.SecretArgs{
{
Name: "slow",
TimeoutSeconds: &timeout,
CommandSources: types.CommandSources{
Commands: map[string]string{
"USER": "sleep 2",
},
},
Type: "Opaque",
},
}
fakeFs := fs.MakeFakeFS()
fakeFs.Mkdir(".")
_, err := NewResMapFromSecretArgs(
configmapandsecret.NewSecretFactory(fakeFs, "."), secrets)
if err == nil {
t.Fatal("didn't get the expected timeout error", err)
}
}

View File

@@ -117,6 +117,9 @@ type SecretArgs struct {
// CommandSources for secret.
CommandSources `json:",inline,omitempty" yaml:",inline,omitempty"`
// TimeoutSeconds specifies the timeout for commands.
TimeoutSeconds *int64 `json:"timeoutSeconds,omitempty" yaml:"timeoutSeconds,omitempty"`
}
// CommandSources contains some generic sources for secrets.