Skip to content

Commit 9139722

Browse files
committed
rebasing and making some fixes
1 parent c09b864 commit 9139722

5 files changed

Lines changed: 108 additions & 72 deletions

File tree

plugins/redis/provisioner.go

Lines changed: 63 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -14,69 +14,41 @@ func redisProvisioner() sdk.Provisioner {
1414
return redisArgsProvisioner{}
1515
}
1616

17-
func (p redisArgsProvisioner) Provision(ctx context.Context, in sdk.ProvisionInput, out *sdk.ProvisionOutput) {
18-
listOfPossibleUserInputArguments := []string{
19-
"--user",
20-
"-h",
21-
"-p",
22-
"--pass",
23-
"-a",
24-
}
25-
26-
var (
27-
commandLineContainsUserArgument bool = false
28-
commandLineContainsHostArgument bool = false
29-
commandLineContainsPortArgument bool = false
30-
commandLineContainsPasswordArgument bool = false
31-
)
17+
// Redis CLI flags that, when already supplied by the user, signal that we
18+
// should not provision the corresponding field from the 1Password item.
19+
var (
20+
hostFlags = []string{"-h"}
21+
portFlags = []string{"-p"}
22+
userFlags = []string{"--user"}
23+
passwordFlags = []string{"-a", "--pass"}
24+
)
3225

33-
for i, arg := range out.CommandLine {
34-
for _, userArg := range listOfPossibleUserInputArguments {
35-
if arg == userArg {
36-
// Get the executable "redis-cli", the matched argument we are looking for and its value
37-
commandLine := []string{out.CommandLine[0], out.CommandLine[i], out.CommandLine[i+1]}
38-
// Remove the matched argument and its value as they will be added to the beginning of the command line
39-
out.CommandLine = append(out.CommandLine[:i], out.CommandLine[i+2:]...)
40-
// Add the executable "redis-cli", the matched argument and its value to the beginning of the command line
41-
commandLine = append(commandLine, out.CommandLine[1:]...)
42-
out.CommandLine = commandLine
43-
// Controller to check if the user has already provided the argument
44-
switch userArg {
45-
case "--user":
46-
commandLineContainsUserArgument = true
47-
case "-h":
48-
commandLineContainsHostArgument = true
49-
case "-p":
50-
commandLineContainsPortArgument = true
51-
case "--pass", "-a":
52-
commandLineContainsPasswordArgument = true
53-
default:
54-
break
55-
}
56-
}
57-
}
58-
}
26+
func (p redisArgsProvisioner) Provision(ctx context.Context, in sdk.ProvisionInput, out *sdk.ProvisionOutput) {
27+
suppliedFlags := flagSet(out.CommandLine)
5928

60-
if value, ok := in.ItemFields[fieldname.Password]; ok && !commandLineContainsPasswordArgument {
29+
// The password is passed via an environment variable so it never appears in
30+
// the process's argument list. Skip it if the user already authenticated on
31+
// the command line.
32+
if value, ok := in.ItemFields[fieldname.Password]; ok && !containsAny(suppliedFlags, passwordFlags) {
6133
out.AddEnvVar("REDISCLI_AUTH", value)
6234
}
6335

64-
if value, ok := in.ItemFields[fieldname.Host]; ok && !commandLineContainsHostArgument {
65-
commandLine := []string{out.CommandLine[0], "-h", value}
66-
commandLine = append(commandLine, out.CommandLine[1:]...)
67-
out.CommandLine = commandLine
36+
// Collect the flags to inject first, then prepend them in a single pass.
37+
// Mutating out.CommandLine while ranging over it risks index-out-of-range
38+
// panics and stale reads, so we never modify it during inspection.
39+
var injected []string
40+
if value, ok := in.ItemFields[fieldname.Host]; ok && !containsAny(suppliedFlags, hostFlags) {
41+
injected = append(injected, "-h", value)
6842
}
69-
70-
if value, ok := in.ItemFields[fieldname.Username]; ok && !commandLineContainsUserArgument {
71-
commandLine := []string{out.CommandLine[0], "--user", value}
72-
commandLine = append(commandLine, out.CommandLine[1:]...)
73-
out.CommandLine = commandLine
43+
if value, ok := in.ItemFields[fieldname.Port]; ok && !containsAny(suppliedFlags, portFlags) {
44+
injected = append(injected, "-p", value)
45+
}
46+
if value, ok := in.ItemFields[fieldname.Username]; ok && !containsAny(suppliedFlags, userFlags) {
47+
injected = append(injected, "--user", value)
7448
}
7549

76-
if value, ok := in.ItemFields[fieldname.Port]; ok && !commandLineContainsPortArgument {
77-
commandLine := []string{out.CommandLine[0], "-p", value}
78-
commandLine = append(commandLine, out.CommandLine[1:]...)
79-
out.CommandLine = commandLine
50+
if len(injected) > 0 {
51+
out.CommandLine = prependArgs(out.CommandLine, injected)
8052
}
8153
}
8254

@@ -85,5 +57,40 @@ func (p redisArgsProvisioner) Deprovision(ctx context.Context, in sdk.Deprovisio
8557
}
8658

8759
func (p redisArgsProvisioner) Description() string {
88-
return "Provision redis secrets as command-line arguments."
60+
return "Provision redis secrets as command-line arguments and the password as an environment variable."
61+
}
62+
63+
// flagSet returns the set of arguments present on the command line, excluding
64+
// the executable name at index 0.
65+
func flagSet(commandLine []string) map[string]bool {
66+
set := make(map[string]bool, len(commandLine))
67+
for i, arg := range commandLine {
68+
if i == 0 {
69+
continue
70+
}
71+
set[arg] = true
72+
}
73+
return set
74+
}
75+
76+
func containsAny(set map[string]bool, flags []string) bool {
77+
for _, f := range flags {
78+
if set[f] {
79+
return true
80+
}
81+
}
82+
return false
83+
}
84+
85+
// prependArgs inserts args immediately after the executable name (index 0),
86+
// leaving the rest of the user-supplied command line intact.
87+
func prependArgs(commandLine []string, args []string) []string {
88+
if len(commandLine) == 0 {
89+
return append([]string{}, args...)
90+
}
91+
result := make([]string, 0, len(commandLine)+len(args))
92+
result = append(result, commandLine[0])
93+
result = append(result, args...)
94+
result = append(result, commandLine[1:]...)
95+
return result
8996
}

plugins/redis/user_credentials.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ func UserCredentials() schema.CredentialType {
1919
MarkdownDescription: "Password used to authenticate to Redis server.",
2020
Secret: true,
2121
Composition: &schema.ValueComposition{
22-
Length: 32,
2322
Charset: schema.Charset{
2423
Uppercase: true,
2524
Lowercase: true,

plugins/redis/user_credentials_test.go

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,49 @@ func TestUserCredentialsProvisioner(t *testing.T) {
2222
Environment: map[string]string{
2323
"REDISCLI_AUTH": "pjtxpc2gaddifapjvalggspojexample",
2424
},
25-
CommandLine: []string{"redis-cli", "-p", "6379", "-h", "127.0.0.1", "--user", "example"}, // Each argument is provisioned at index 1, pushing the existing arguments forward to the next index
25+
CommandLine: []string{"redis-cli", "-h", "127.0.0.1", "-p", "6379", "--user", "example"},
26+
},
27+
},
28+
// User supplies some flags themselves: we must not duplicate them, but
29+
// should still provision the fields they left out (and keep their args).
30+
"user-supplied flags are respected": {
31+
ItemFields: map[sdk.FieldName]string{
32+
fieldname.Password: "pjtxpc2gaddifapjvalggspojexample",
33+
fieldname.Username: "example",
34+
fieldname.Host: "127.0.0.1",
35+
fieldname.Port: "6379",
36+
},
37+
CommandLine: []string{"redis-cli", "-h", "myhost", "PING"},
38+
ExpectedOutput: sdk.ProvisionOutput{
39+
Environment: map[string]string{
40+
"REDISCLI_AUTH": "pjtxpc2gaddifapjvalggspojexample",
41+
},
42+
CommandLine: []string{"redis-cli", "-p", "6379", "--user", "example", "-h", "myhost", "PING"},
43+
},
44+
},
45+
// A recognized flag as the final token used to cause an index-out-of-range
46+
// panic; ensure it is handled gracefully.
47+
"recognized flag as last token": {
48+
ItemFields: map[sdk.FieldName]string{
49+
fieldname.Password: "pjtxpc2gaddifapjvalggspojexample",
50+
fieldname.Host: "127.0.0.1",
51+
},
52+
CommandLine: []string{"redis-cli", "-h"},
53+
ExpectedOutput: sdk.ProvisionOutput{
54+
Environment: map[string]string{
55+
"REDISCLI_AUTH": "pjtxpc2gaddifapjvalggspojexample",
56+
},
57+
CommandLine: []string{"redis-cli", "-h"},
58+
},
59+
},
60+
// User authenticates on the command line: don't also set the env var.
61+
"password flag skips env var": {
62+
ItemFields: map[sdk.FieldName]string{
63+
fieldname.Password: "pjtxpc2gaddifapjvalggspojexample",
64+
},
65+
CommandLine: []string{"redis-cli", "-a", "mypassword"},
66+
ExpectedOutput: sdk.ProvisionOutput{
67+
CommandLine: []string{"redis-cli", "-a", "mypassword"},
2668
},
2769
},
2870
})

sdk/provisioner.go

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -107,20 +107,6 @@ func (out *ProvisionOutput) AddArgs(args ...string) {
107107
out.CommandLine = append(out.CommandLine, args...)
108108
}
109109

110-
// AddArgsAtIndex can be used to add additional arguments to the command line of the provision output, at a specific index.
111-
func (out *ProvisionOutput) AddArgsAtIndex(index uint, args ...string) {
112-
// Provision arguments at the end of the command line input to prevent out of bound errors. But, this isn't entirely a concern is the case of redis-cli where we always provision at index 1 and "redis-cli" is the minimum-required command
113-
if index >= uint(len(out.CommandLine)) {
114-
out.CommandLine = append(out.CommandLine, args...)
115-
return
116-
}
117-
newCommandLine := []string{}
118-
newCommandLine = append(newCommandLine, out.CommandLine[:index]...)
119-
newCommandLine = append(newCommandLine, args...)
120-
newCommandLine = append(newCommandLine, out.CommandLine[index:]...)
121-
out.CommandLine = newCommandLine
122-
}
123-
124110
// AddSecretFile can be used to add a file containing secrets to the provision output.
125111
func (out *ProvisionOutput) AddSecretFile(path string, contents []byte) {
126112
out.AddFile(path, OutputFile{

sdk/schema/fieldname/names.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ func ListAll() []sdk.FieldName {
7272
AccessToken,
7373
Account,
7474
AccountID,
75+
AccountKey,
7576
AccountSID,
7677
Address,
7778
AppKey,
@@ -111,6 +112,7 @@ func ListAll() []sdk.FieldName {
111112
Token,
112113
URL,
113114
User,
115+
UserKey,
114116
Username,
115117
Website,
116118
}

0 commit comments

Comments
 (0)