Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Expand Headers Feature #117

Merged
merged 3 commits into from
Sep 26, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Fix -expand-headers Help String
Also fix all other PR feedback.
  • Loading branch information
jammerful committed Sep 26, 2019
commit 9dad8ec412dac8a963b2f6a1fff111b610217da5
19 changes: 10 additions & 9 deletions cmd/grpcurl/grpcurl.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,13 @@ var (
rpcHeaders multiString
reflHeaders multiString
expandHeaders = flags.Bool("expand-headers", false, prettify(`
If set any environmental variables contained contained in any additional, rpc,
or reflection header string will be substituted for by the value of the environmental
variable. For instance, for the header 'key: ${VALUE}' where VALUE="foo"
will be expanded to 'key: foo'. Any undefined environmental variables
will throw an error. Note that verbose mode shows that the headers are
being expanded to. Escaping '${' is not supported.`))
If set, headers may use '${NAME}' syntax to reference environment variables.
These will be expanded to the actual environment variable value before
sending to the server. For example, if there is an environment variable
defined like FOO=bar, then a header of 'key: ${FOO}' would expand to 'key: bar'.
This applies to -H, -rpc-header, and -reflect-header options. No other
expansion/escaping is performed. This can be used to supply
credentials/secrets without having to put them in command-line arguments.`))
authority = flags.String("authority", "", prettify(`
Value of :authority pseudo-header to be use with underlying HTTP/2
requests. It defaults to the given address.`))
Expand Down Expand Up @@ -324,15 +325,15 @@ func main() {
var err error
addlHeaders, err = grpcurl.ExpandHeaders(addlHeaders)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know if you wanted this DRY'd, was on the fence.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems fine.

if err != nil {
fail(err, "Failed to expand additional headers, missing environmental variable")
fail(err, "Failed to expand additional headers")
}
rpcHeaders, err = grpcurl.ExpandHeaders(rpcHeaders)
if err != nil {
fail(err, "Failed to expand rpc headers, missing environmental variable")
fail(err, "Failed to expand rpc headers")
}
reflHeaders, err = grpcurl.ExpandHeaders(reflHeaders)
if err != nil {
fail(err, "Failed to expand reflection headers, missing environmental variable")
fail(err, "Failed to expand reflection headers")
}
}

Expand Down
36 changes: 18 additions & 18 deletions grpcurl.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,30 +165,30 @@ func MetadataFromHeaders(headers []string) metadata.MD {

var envVarRegex = regexp.MustCompile(`\${\w+}`)

// ExpandHeaders expands environmental variables contained in the header string.
// If no corresponding environmental variable is found an error is thrown.
// ExpandHeaders expands environment variables contained in the header string.
// If no corresponding environment variable is found an error is returned.
// TODO: Add escaping for `${`
func ExpandHeaders(headers []string) ([]string, error) {
expandedHeaders := make([]string, len(headers))
for idx, header := range headers {
if header != "" {
results := envVarRegex.FindAllString(header, -1)
if results != nil {
expandedHeader := header
for _, result := range results {
envVarName := result[2 : len(result)-1]
envVarValue := os.Getenv(envVarName)
replacementValue := envVarValue
if len(envVarValue) == 0 {
return nil, fmt.Errorf("environmental variable '%s' is not set", envVarName)
}
expandedHeader = strings.Replace(expandedHeader, result, replacementValue, -1)
}
expandedHeaders[idx] = expandedHeader
} else {
expandedHeaders[idx] = headers[idx]
if header == "" {
continue
}
results := envVarRegex.FindAllString(header, -1)
if len(results) == 0 {
expandedHeaders[idx] = headers[idx]
continue
}
expandedHeader := header
for _, result := range results {
envVarName := result[2 : len(result)-1] // strip leading `${` and trailing `}`
envVarValue, ok := os.LookupEnv(envVarName)
if !ok {
return nil, fmt.Errorf("header %q refers to missing environment variable %q", header, envVarName)
}
expandedHeader = strings.Replace(expandedHeader, result, envVarValue, -1)
}
expandedHeaders[idx] = expandedHeader
}
return expandedHeaders, nil
}
Expand Down
13 changes: 7 additions & 6 deletions grpcurl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,28 +301,29 @@ func TestGetAllFiles(t *testing.T) {
}

func TestExpandHeaders(t *testing.T) {
inHeaders := []string{"", "key1: ${value}", "key2: bar", "key3: ${woo", "key4: woo}", "key5: ${TEST}",
"key6: ${TEST_VAR}", "${TEST}: ${TEST_VAR}"}
inHeaders := []string{"key1: ${value}", "key2: bar", "key3: ${woo", "key4: woo}", "key5: ${TEST}",
"key6: ${TEST_VAR}", "${TEST}: ${TEST_VAR}", "key8: ${EMPTY}"}
os.Setenv("value", "value")
os.Setenv("TEST", "value5")
os.Setenv("TEST_VAR", "value6")
expectedHeaders := map[string]bool{"": true, "key1: value": true, "key2: bar": true, "key3: ${woo": true, "key4: woo}": true,
"key5: value5": true, "key6: value6": true, "value5: value6": true}
os.Setenv("EMPTY", "")
expectedHeaders := map[string]bool{"key1: value": true, "key2: bar": true, "key3: ${woo": true, "key4: woo}": true,
"key5: value5": true, "key6: value6": true, "value5: value6": true, "key8: ": true}

outHeaders, err := ExpandHeaders(inHeaders)
if err != nil {
t.Errorf("The ExpandHeaders function generated an unexpected error %s", err)
}
for _, expandedHeader := range outHeaders {
if _, ok := expectedHeaders[expandedHeader]; !ok {
t.Errorf("The ExpandHeaders function has generated an unexpected header. Recieved unexpected header %s", expandedHeader)
t.Errorf("The ExpandHeaders function has returned an unexpected header. Received unexpected header %s", expandedHeader)
}
}

badHeaders := []string{"key: ${DNE}"}
_, err = ExpandHeaders(badHeaders)
if err == nil {
t.Errorf("The ExpandHeaders function should generate an error for missing environmental variables %q", badHeaders)
t.Errorf("The ExpandHeaders function should return an error for missing environment variables %q", badHeaders)
}
}

Expand Down