diff --git a/api/credentials/internal/identity.go b/api/credentials/internal/identity.go index d8b3e84d91..7aacf8f30e 100644 --- a/api/credentials/internal/identity.go +++ b/api/credentials/internal/identity.go @@ -93,6 +93,10 @@ func orMatcher(list []IdentityMatcher) IdentityMatcher { // ConsumerIdentity describes the identity of a credential consumer. type ConsumerIdentity map[string]string +// UnmarshalJSON allows a yaml specification containing a data type other +// string, e.g. a hostpath spec with a port. Previously, it would error if the +// user specified `port: 5000` and instead, the user had to specify +// `port: "5000"` func (c *ConsumerIdentity) UnmarshalJSON(data []byte) error { var m map[string]interface{} err := runtime.DefaultJSONEncoding.Unmarshal(data, &m) @@ -100,15 +104,21 @@ func (c *ConsumerIdentity) UnmarshalJSON(data []byte) error { return err } + if len(m) == 0 { + return nil + } *c = make(map[string]string, len(m)) for k, v := range m { switch v.(type) { + case nil: + (*c)[k] = "" case map[string]interface{}: return fmt.Errorf("cannot unmarshal complex type into consumer identity") case []interface{}: return fmt.Errorf("cannot unmarshal complex type into consumer identity") + default: + (*c)[k] = fmt.Sprintf("%v", v) } - (*c)[k] = fmt.Sprintf("%v", v) } return nil } diff --git a/api/credentials/internal/identity_test.go b/api/credentials/internal/identity_test.go index 990a19997a..66633df813 100644 --- a/api/credentials/internal/identity_test.go +++ b/api/credentials/internal/identity_test.go @@ -70,4 +70,19 @@ port: cid := internal.ConsumerIdentity{} Expect(yaml.Unmarshal([]byte(data), &cid)).NotTo(Succeed()) }) + It("with nil", func() { + data := ` +scheme: http +hostname: 127.0.0.1 +port: +` + id := internal.ConsumerIdentity{ + "scheme": "http", + "hostname": "127.0.0.1", + "port": "", + } + cid := internal.ConsumerIdentity{} + Expect(yaml.Unmarshal([]byte(data), &cid)).To(Succeed()) + Expect(cid).To(Equal(id)) + }) })