From 17cd70cea546e287713a3d4c086528a85abefa2e Mon Sep 17 00:00:00 2001 From: Niall Sheridan Date: Tue, 4 Oct 2016 14:37:01 -0700 Subject: Add support for Hashicorp Vault Vault is supported for the following: As a well-known filesystem for TLS cert, TLS key and SSH signing key. For configuration secrets for cookie_secret, csrf_secret, oauth_client_id and oauth_client_secret options. --- vendor/github.com/hashicorp/hcl/decoder.go | 59 +++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) (limited to 'vendor/github.com/hashicorp/hcl/decoder.go') diff --git a/vendor/github.com/hashicorp/hcl/decoder.go b/vendor/github.com/hashicorp/hcl/decoder.go index a6938fe..c8a077d 100644 --- a/vendor/github.com/hashicorp/hcl/decoder.go +++ b/vendor/github.com/hashicorp/hcl/decoder.go @@ -409,7 +409,6 @@ func (d *decoder) decodeSlice(name string, node ast.Node, result reflect.Value) if result.Kind() == reflect.Interface { result = result.Elem() } - // Create the slice if it isn't nil resultType := result.Type() resultElemType := resultType.Elem() @@ -443,6 +442,12 @@ func (d *decoder) decodeSlice(name string, node ast.Node, result reflect.Value) // Decode val := reflect.Indirect(reflect.New(resultElemType)) + + // if item is an object that was decoded from ambiguous JSON and + // flattened, make sure it's expanded if it needs to decode into a + // defined structure. + item := expandObject(item, val) + if err := d.decode(fieldName, item, val); err != nil { return err } @@ -455,6 +460,57 @@ func (d *decoder) decodeSlice(name string, node ast.Node, result reflect.Value) return nil } +// expandObject detects if an ambiguous JSON object was flattened to a List which +// should be decoded into a struct, and expands the ast to properly deocode. +func expandObject(node ast.Node, result reflect.Value) ast.Node { + item, ok := node.(*ast.ObjectItem) + if !ok { + return node + } + + elemType := result.Type() + + // our target type must be a struct + switch elemType.Kind() { + case reflect.Ptr: + switch elemType.Elem().Kind() { + case reflect.Struct: + //OK + default: + return node + } + case reflect.Struct: + //OK + default: + return node + } + + // A list value will have a key and field name. If it had more fields, + // it wouldn't have been flattened. + if len(item.Keys) != 2 { + return node + } + + keyToken := item.Keys[0].Token + item.Keys = item.Keys[1:] + + // we need to un-flatten the ast enough to decode + newNode := &ast.ObjectItem{ + Keys: []*ast.ObjectKey{ + &ast.ObjectKey{ + Token: keyToken, + }, + }, + Val: &ast.ObjectType{ + List: &ast.ObjectList{ + Items: []*ast.ObjectItem{item}, + }, + }, + } + + return newNode +} + func (d *decoder) decodeString(name string, node ast.Node, result reflect.Value) error { switch n := node.(type) { case *ast.LiteralType: @@ -606,6 +662,7 @@ func (d *decoder) decodeStruct(name string, node ast.Node, result reflect.Value) // match (only object with the field), then we decode it exactly. // If it is a prefix match, then we decode the matches. filter := list.Filter(fieldName) + prefixMatches := filter.Children() matches := filter.Elem() if len(matches.Items) == 0 && len(prefixMatches.Items) == 0 { -- cgit v1.2.3