Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
63 changes: 63 additions & 0 deletions cfenv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,69 @@ func testcfenv(t *testing.T, when spec.G, it spec.S) {
})
})

// Issue #25: everything CF puts in a binding object should survive the
// decode. A user-provided instance carries a syslog drain URL, and a
// named binding has an instance name distinct from its binding name.
when("binding metadata", func() {
var service *cfenv.Service

it.Before(func() {
env, err := cfenv.New(map[string]string{
"VCAP_APPLICATION": "{}",
"VCAP_SERVICES": `{"user-provided":[{
"binding_guid":"bd0f0b8a-2a4e-4b1e-9a4f-6f1a2c3d4e5f",
"binding_name":"my-binding",
"instance_guid":"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"instance_name":"my-ups",
"name":"my-binding",
"label":"user-provided",
"tags":["logging"],
"credentials":{"url":"https://example.com"},
"syslog_drain_url":"syslog://logs.example.com:514"
}]}`,
})
Expect(err).To(BeNil())

service, err = env.Services.WithName("my-binding")
Expect(err).To(BeNil())
})

it("captures the syslog drain URL", func() {
Expect(service.SyslogDrainURL).To(Equal("syslog://logs.example.com:514"))
})

it("captures the instance identity", func() {
Expect(service.InstanceGUID).To(Equal("1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d"))
Expect(service.InstanceName).To(Equal("my-ups"))
})

it("captures the binding identity", func() {
Expect(service.BindingGUID).To(Equal("bd0f0b8a-2a4e-4b1e-9a4f-6f1a2c3d4e5f"))
Expect(service.BindingName).To(Equal("my-binding"))
})

it("keeps the instance name distinct from the binding name", func() {
Expect(service.Name).To(Equal("my-binding"))
Expect(service.InstanceName).To(Equal("my-ups"))
})

it("leaves the new fields empty when CF omits them", func() {
env, err := cfenv.New(map[string]string{
"VCAP_APPLICATION": "{}",
"VCAP_SERVICES": `{"sendgrid":[{"name":"mysendgrid","label":"sendgrid","plan":"free","credentials":{}}]}`,
})
Expect(err).To(BeNil())

plain, err := env.Services.WithName("mysendgrid")
Expect(err).To(BeNil())
Expect(plain.SyslogDrainURL).To(Equal(""))
Expect(plain.InstanceGUID).To(Equal(""))
Expect(plain.InstanceName).To(Equal(""))
Expect(plain.BindingGUID).To(Equal(""))
Expect(plain.BindingName).To(Equal(""))
})
})

// Issue #11: a credential whose value was a nested object once panicked
// the decoder, which expected every credential to be a string. Pins the
// payload from that report so the fix cannot silently regress.
Expand Down
3 changes: 0 additions & 3 deletions changelog.d/0001-adopt-changelog-fragments.md

This file was deleted.

2 changes: 2 additions & 0 deletions changelog.d/0001-binding-metadata.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[Features]
- `Service` now captures the binding metadata Cloud Foundry sends but the decoder previously discarded: `SyslogDrainURL`, `InstanceGUID`, `InstanceName`, `BindingGUID` and `BindingName`. `SyslogDrainURL` is what `cf cups -l` sets on a user-provided instance, and `InstanceName` recovers the instance name for a named binding, where `Name` holds the binding name instead. (#25)
2 changes: 0 additions & 2 deletions changelog.d/0002-add-actionlint-target.md

This file was deleted.

6 changes: 0 additions & 6 deletions changelog.d/0003-nested-credentials.md

This file was deleted.

10 changes: 8 additions & 2 deletions service.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,18 @@ import (
// service object contains a child object for each service instance of that
// service that is bound to the application.
type Service struct {
Name string // name of the service
Label string // label of the service
Name string // the binding name if the binding has one, otherwise the instance name
Label string // name of the service offering; "user-provided" for a user-provided instance
Tags []string // tags for the service
Plan string // plan of the service
Credentials map[string]interface{} // credentials for the service
VolumeMounts []map[string]string `mapstructure:"volume_mounts"` // volume mount info as provided by the nfsbroker

SyslogDrainURL string `mapstructure:"syslog_drain_url"` // where the service wants app logs streamed; set by `cf cups -l`
InstanceGUID string `mapstructure:"instance_guid"` // GUID of the service instance
InstanceName string `mapstructure:"instance_name"` // name the user gave the service instance
BindingGUID string `mapstructure:"binding_guid"` // GUID of the service binding
BindingName string `mapstructure:"binding_name"` // name the user gave the binding, if any
}

func (s *Service) CredentialString(key string) (string, bool) {
Expand Down