Skip to content

Instantly share code, notes, and snippets.

@jefferai
Created August 3, 2016 17:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jefferai/2d472e08b8dd4ab5adc967eb48919275 to your computer and use it in GitHub Desktop.
Save jefferai/2d472e08b8dd4ab5adc967eb48919275 to your computer and use it in GitHub Desktop.
diff --git a/builtin/credential/approle/path_role.go b/builtin/credential/approle/path_role.go
index 171fa8c..c2a4949 100644
--- a/builtin/credential/approle/path_role.go
+++ b/builtin/credential/approle/path_role.go
@@ -1452,7 +1452,7 @@ func (b *backend) handleRoleSecretIDCommon(req *logical.Request, data *framework
Metadata: make(map[string]string),
}
- if err = strutil.ParseArbitraryKeyValues(data.Get("metadata").(string), secretIDStorage.Metadata); err != nil {
+ if err = strutil.ParseArbitraryKeyValues(data.Get("metadata").(string), secretIDStorage.Metadata, ","); err != nil {
return logical.ErrorResponse(fmt.Sprintf("failed to parse metadata: %v", err)), nil
}
diff --git a/builtin/logical/postgresql/path_role_create.go b/builtin/logical/postgresql/path_role_create.go
index c5538c7..54a7b7a 100644
--- a/builtin/logical/postgresql/path_role_create.go
+++ b/builtin/logical/postgresql/path_role_create.go
@@ -5,6 +5,7 @@ import (
"time"
"github.com/hashicorp/go-uuid"
+ "github.com/hashicorp/vault/helper/strutil"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
_ "github.com/lib/pq"
@@ -100,7 +101,7 @@ func (b *backend) pathRoleCreateRead(
}()
// Execute each query
- for _, query := range SplitSQL(role.SQL) {
+ for _, query := range strutil.ParseArbitraryStringSlice(role.SQL, ";") {
b.logger.Println("[TRACE] postgres/pathRoleCreateRead: preparing statement")
stmt, err := tx.Prepare(Query(query, map[string]string{
"name": username,
diff --git a/builtin/logical/postgresql/path_roles.go b/builtin/logical/postgresql/path_roles.go
index 6d30e71..c6f6db0 100644
--- a/builtin/logical/postgresql/path_roles.go
+++ b/builtin/logical/postgresql/path_roles.go
@@ -3,6 +3,7 @@ package postgresql
import (
"fmt"
+ "github.com/hashicorp/vault/helper/strutil"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
)
@@ -112,7 +113,7 @@ func (b *backend) pathRoleCreate(
}
// Test the query by trying to prepare it
- for _, query := range SplitSQL(sql) {
+ for _, query := range strutil.ParseArbitraryStringSlice(sql, ";") {
stmt, err := db.Prepare(Query(query, map[string]string{
"name": "foo",
"password": "bar",
diff --git a/helper/strutil/strutil.go b/helper/strutil/strutil.go
index 0d53714..f4a63b0 100644
--- a/helper/strutil/strutil.go
+++ b/helper/strutil/strutil.go
@@ -32,20 +32,24 @@ func StrListSubset(super, sub []string) bool {
// Parses a comma separated list of strings into a slice of strings.
// The return slice will be sorted and will not contain duplicate or
// empty items. The values will be converted to lower case.
-func ParseDedupAndSortStrings(input string) []string {
+func ParseDedupAndSortStrings(input string, sep string) []string {
input = strings.TrimSpace(input)
var parsed []string
if input == "" {
// Don't return nil
return parsed
}
- return RemoveDuplicates(strings.Split(input, ","))
+ return RemoveDuplicates(strings.Split(input, sep))
}
// Parses a comma separated list of `<key>=<value>` tuples into a
// map[string]string.
-func ParseKeyValues(input string, out map[string]string) error {
- keyValues := ParseDedupAndSortStrings(input)
+func ParseKeyValues(input string, out map[string]string, sep string) error {
+ if out == nil {
+ return fmt.Errorf("'out is nil")
+ }
+
+ keyValues := ParseDedupAndSortStrings(input, sep)
if len(keyValues) == 0 {
return nil
}
@@ -72,7 +76,7 @@ func ParseKeyValues(input string, out map[string]string) error {
//
// Input will be parsed into the output paramater, which should
// be a non-nil map[string]string.
-func ParseArbitraryKeyValues(input string, out map[string]string) error {
+func ParseArbitraryKeyValues(input string, out map[string]string, sep string) error {
input = strings.TrimSpace(input)
if input == "" {
return nil
@@ -94,7 +98,7 @@ func ParseArbitraryKeyValues(input string, out map[string]string) error {
if err != nil {
// If JSON unmarshalling fails, consider that the input was
// supplied as a comma separated string of 'key=value' pairs.
- if err = ParseKeyValues(input, out); err != nil {
+ if err = ParseKeyValues(input, out, sep); err != nil {
return fmt.Errorf("failed to parse the input: %v", err)
}
}
@@ -109,6 +113,58 @@ func ParseArbitraryKeyValues(input string, out map[string]string) error {
return nil
}
+// Parses a `sep`-separated list of strings into a
+// []string.
+func ParseStringSlice(input string, sep string) []string {
+ input = strings.TrimSpace(input)
+ if input == "" {
+ return []string{}
+ }
+
+ splitStr := strings.Split(input, sep)
+ ret := make([]string, len(splitStr))
+ for i, val := range splitStr {
+ ret[i] = val
+ }
+
+ return ret
+}
+
+// Parses arbitrary string slice. The input can be one of
+// the following:
+// * JSON string
+// * Base64 encoded JSON string
+// * `sep` separated list of values
+// * Base64-encoded string containting a `sep` separated list of values
+//
+// Note that the separator is ignored if the input is found to already be in a
+// structured format (e.g., JSON)
+func ParseArbitraryStringSlice(input string, sep string) []string {
+ if input == "" {
+ return []string{}
+ }
+
+ // Try to base64 decode the input. If successful, consider the decoded
+ // value as input.
+ inputBytes, err := base64.StdEncoding.DecodeString(input)
+ if err == nil {
+ input = string(inputBytes)
+ }
+
+ ret := []string{}
+
+ // Try to JSON unmarshal the input. If successful, consider that the
+ // metadata was supplied as JSON input.
+ err = json.Unmarshal([]byte(input), &ret)
+ if err != nil {
+ // If JSON unmarshalling fails, consider that the input was
+ // supplied as a separated string of values.
+ return ParseStringSlice(input, sep)
+ }
+
+ return ret
+}
+
// Removes duplicate and empty elements from a slice of strings.
// This also converts the items in the slice to lower case and
// returns a sorted slice.
diff --git a/helper/strutil/strutil_test.go b/helper/strutil/strutil_test.go
index f5ceb8c..331270c 100644
--- a/helper/strutil/strutil_test.go
+++ b/helper/strutil/strutil_test.go
@@ -128,7 +128,7 @@ func TestStrutil_ParseArbitraryKeyValues(t *testing.T) {
// Test <key>=<value> as comma separated string
input = "key1=value1,key2=value2"
- err = ParseArbitraryKeyValues(input, actual)
+ err = ParseArbitraryKeyValues(input, actual, ",")
if err != nil {
t.Fatal(err)
}
@@ -141,7 +141,7 @@ func TestStrutil_ParseArbitraryKeyValues(t *testing.T) {
// Test <key>=<value> as base64 encoded comma separated string
input = base64.StdEncoding.EncodeToString([]byte(input))
- err = ParseArbitraryKeyValues(input, actual)
+ err = ParseArbitraryKeyValues(input, actual, ",")
if err != nil {
t.Fatal(err)
}
@@ -154,7 +154,7 @@ func TestStrutil_ParseArbitraryKeyValues(t *testing.T) {
// Test JSON encoded <key>=<value> tuples
input = `{"key1":"value1", "key2":"value2"}`
- err = ParseArbitraryKeyValues(input, actual)
+ err = ParseArbitraryKeyValues(input, actual, ",")
if err != nil {
t.Fatal(err)
}
@@ -167,7 +167,7 @@ func TestStrutil_ParseArbitraryKeyValues(t *testing.T) {
// Test base64 encoded JSON string of <key>=<value> tuples
input = base64.StdEncoding.EncodeToString([]byte(input))
- err = ParseArbitraryKeyValues(input, actual)
+ err = ParseArbitraryKeyValues(input, actual, ",")
if err != nil {
t.Fatal(err)
}
diff --git a/physical/consul.go b/physical/consul.go
index f939dcf..9bc0ae5 100644
--- a/physical/consul.go
+++ b/physical/consul.go
@@ -184,7 +184,7 @@ func newConsulBackend(conf map[string]string, logger *log.Logger) (Backend, erro
kv: client.KV(),
permitPool: NewPermitPool(maxParInt),
serviceName: service,
- serviceTags: strutil.ParseDedupAndSortStrings(tags),
+ serviceTags: strutil.ParseDedupAndSortStrings(tags, ","),
checkTimeout: checkTimeout,
disableRegistration: disableRegistration,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment