diff --git a/api_test.go b/api_test.go index 34922600..451a1d31 100644 --- a/api_test.go +++ b/api_test.go @@ -1546,41 +1546,7 @@ var _ = Describe("Service Broker API", func() { } }) - Context("the request is malformed", func() { - BeforeEach(func() { - bindingID = uniqueBindingID() - }) - - It("missing header X-Broker-API-Version", func() { - response := makeBindingRequestWithSpecificAPIVersion(instanceID, bindingID, map[string]interface{}{}, "", false) - Expect(response.StatusCode).To(Equal(412)) - Expect(lastLogLine().Message).To(ContainSubstring("version-header-check.broker-api-version-invalid")) - Expect(lastLogLine().Data["error"]).To(ContainSubstring("X-Broker-API-Version Header not set")) - }) - - It("has wrong version of API", func() { - response := makeBindingRequestWithSpecificAPIVersion(instanceID, bindingID, map[string]interface{}{}, "1.14", false) - Expect(response.StatusCode).To(Equal(412)) - Expect(lastLogLine().Message).To(ContainSubstring("version-header-check.broker-api-version-invalid")) - Expect(lastLogLine().Data["error"]).To(ContainSubstring("X-Broker-API-Version Header must be 2.x")) - }) - - It("missing service-id", func() { - response := makeBindingRequestWithSpecificAPIVersion(instanceID, bindingID, map[string]interface{}{"plan_id": "123"}, "2.14", false) - Expect(response.StatusCode).To(Equal(400)) - Expect(lastLogLine().Message).To(ContainSubstring(".bind.service-id-missing")) - Expect(lastLogLine().Data["error"]).To(ContainSubstring("service_id missing")) - }) - - It("missing plan-id", func() { - response := makeBindingRequestWithSpecificAPIVersion(instanceID, bindingID, map[string]interface{}{"service_id": "123"}, "2.14", false) - Expect(response.StatusCode).To(Equal(400)) - Expect(lastLogLine().Message).To(ContainSubstring(".bind.plan-id-missing")) - Expect(lastLogLine().Data["error"]).To(ContainSubstring("plan_id missing")) - }) - }) - - Context("when the associated instance exists", func() { + When("can bind", func() { It("calls Bind on the service broker with the instance and binding ids", func() { makeBindingRequest(instanceID, bindingID, details) Expect(fakeServiceBroker.BoundInstanceIDs).To(ContainElement(instanceID)) @@ -1766,6 +1732,21 @@ var _ = Describe("Service Broker API", func() { }) }) + When("backup_agent is requested", func() { + BeforeEach(func() { + details["bind_resource"] = map[string]interface{}{"backup_agent": true} + fakeServiceBroker.BackupAgentURL = "http://backup.example.com" + }) + + It("responds with the backup agent url", func() { + response := makeBindingRequest(instanceID, bindingID, details) + Expect(fakeServiceBroker.BoundBindings[bindingID].BindResource).NotTo(BeNil()) + Expect(fakeServiceBroker.BoundBindings[bindingID].BindResource.BackupAgent).To(BeTrue()) + + Expect(response.StatusCode).To(Equal(http.StatusCreated)) + Expect(response.Body).To(MatchJSON(`{"backup_agent_url":"http://backup.example.com"}`)) + }) + }) }) Context("when the associated instance does not exist", func() { @@ -1940,6 +1921,41 @@ var _ = Describe("Service Broker API", func() { }) }) }) + + Context("the request is malformed", func() { + BeforeEach(func() { + bindingID = uniqueBindingID() + }) + + It("missing header X-Broker-API-Version", func() { + response := makeBindingRequestWithSpecificAPIVersion(instanceID, bindingID, map[string]interface{}{}, "", false) + Expect(response.StatusCode).To(Equal(412)) + Expect(lastLogLine().Message).To(ContainSubstring("version-header-check.broker-api-version-invalid")) + Expect(lastLogLine().Data["error"]).To(ContainSubstring("X-Broker-API-Version Header not set")) + }) + + It("has wrong version of API", func() { + response := makeBindingRequestWithSpecificAPIVersion(instanceID, bindingID, map[string]interface{}{}, "1.14", false) + Expect(response.StatusCode).To(Equal(412)) + Expect(lastLogLine().Message).To(ContainSubstring("version-header-check.broker-api-version-invalid")) + Expect(lastLogLine().Data["error"]).To(ContainSubstring("X-Broker-API-Version Header must be 2.x")) + }) + + It("missing service-id", func() { + response := makeBindingRequestWithSpecificAPIVersion(instanceID, bindingID, map[string]interface{}{"plan_id": "123"}, "2.14", false) + Expect(response.StatusCode).To(Equal(400)) + Expect(lastLogLine().Message).To(ContainSubstring(".bind.service-id-missing")) + Expect(lastLogLine().Data["error"]).To(ContainSubstring("service_id missing")) + }) + + It("missing plan-id", func() { + response := makeBindingRequestWithSpecificAPIVersion(instanceID, bindingID, map[string]interface{}{"service_id": "123"}, "2.14", false) + Expect(response.StatusCode).To(Equal(400)) + Expect(lastLogLine().Message).To(ContainSubstring(".bind.plan-id-missing")) + Expect(lastLogLine().Data["error"]).To(ContainSubstring("plan_id missing")) + }) + }) + }) Describe("unbinding", func() { diff --git a/domain/apiresponses/responses.go b/domain/apiresponses/responses.go index bb993872..3b4655c5 100644 --- a/domain/apiresponses/responses.go +++ b/domain/apiresponses/responses.go @@ -59,10 +59,11 @@ type AsyncBindResponse struct { } type BindingResponse struct { - Credentials interface{} `json:"credentials"` + Credentials interface{} `json:"credentials,omitempty"` SyslogDrainURL string `json:"syslog_drain_url,omitempty"` RouteServiceURL string `json:"route_service_url,omitempty"` VolumeMounts []domain.VolumeMount `json:"volume_mounts,omitempty"` + BackupAgentURL string `json:"backup_agent_url,omitempty"` } type GetBindingResponse struct { @@ -75,8 +76,9 @@ type UnbindResponse struct { } type ExperimentalVolumeMountBindingResponse struct { - Credentials interface{} `json:"credentials"` + Credentials interface{} `json:"credentials,omitempty"` SyslogDrainURL string `json:"syslog_drain_url,omitempty"` RouteServiceURL string `json:"route_service_url,omitempty"` VolumeMounts []domain.ExperimentalVolumeMount `json:"volume_mounts,omitempty"` + BackupAgentURL string `json:"backup_agent_url,omitempty"` } diff --git a/domain/apiresponses/responses_test.go b/domain/apiresponses/responses_test.go index 41b61c6a..d76e082a 100644 --- a/domain/apiresponses/responses_test.go +++ b/domain/apiresponses/responses_test.go @@ -70,17 +70,6 @@ var _ = Describe("Update Response", func() { }) }) -var _ = Describe("Binding Response", func() { - Describe("JSON encoding", func() { - It("has a credentials object", func() { - binding := apiresponses.BindingResponse{} - jsonString := `{"credentials":null}` - - Expect(json.Marshal(binding)).To(MatchJSON(jsonString)) - }) - }) -}) - var _ = Describe("Error Response", func() { Describe("JSON encoding", func() { It("has a description field", func() { diff --git a/domain/service_broker.go b/domain/service_broker.go index dbc6d22e..9aff08e1 100644 --- a/domain/service_broker.go +++ b/domain/service_broker.go @@ -157,6 +157,7 @@ type BindResource struct { SpaceGuid string `json:"space_guid,omitempty"` Route string `json:"route,omitempty"` CredentialClientID string `json:"credential_client_id,omitempty"` + BackupAgent bool `json:"backup_agent,omitempty"` } type UnbindDetails struct { @@ -176,6 +177,7 @@ type Binding struct { Credentials interface{} `json:"credentials"` SyslogDrainURL string `json:"syslog_drain_url"` RouteServiceURL string `json:"route_service_url"` + BackupAgentURL string `json:"backup_agent_url,omitempty"` VolumeMounts []VolumeMount `json:"volume_mounts"` } diff --git a/fakes/fake_service_broker.go b/fakes/fake_service_broker.go index 7707727c..2f69c8c5 100644 --- a/fakes/fake_service_broker.go +++ b/fakes/fake_service_broker.go @@ -24,6 +24,7 @@ type FakeServiceBroker struct { BoundBindings map[string]brokerapi.BindDetails SyslogDrainURL string RouteServiceURL string + BackupAgentURL string VolumeMounts []brokerapi.VolumeMount UnbindingDetails brokerapi.UnbindDetails @@ -386,6 +387,10 @@ func (fakeBroker *FakeServiceBroker) Bind(context context.Context, instanceID, b VolumeMounts: fakeBroker.VolumeMounts, } + if fakeBroker.BackupAgentURL != "" { + binding = brokerapi.Binding{BackupAgentURL: fakeBroker.BackupAgentURL} + } + if _, ok := fakeBroker.BoundBindings[bindingID]; ok { if reflect.DeepEqual(fakeBroker.BoundBindings[bindingID], details) { binding.AlreadyExists = true diff --git a/handlers/bind.go b/handlers/bind.go index a81d1e9e..f6f4aea7 100644 --- a/handlers/bind.go +++ b/handlers/bind.go @@ -88,6 +88,7 @@ func (h APIHandler) Bind(w http.ResponseWriter, req *http.Request) { SyslogDrainURL: binding.SyslogDrainURL, RouteServiceURL: binding.RouteServiceURL, VolumeMounts: binding.VolumeMounts, + BackupAgentURL: binding.BackupAgentURL, }) return } @@ -126,6 +127,7 @@ func (h APIHandler) Bind(w http.ResponseWriter, req *http.Request) { RouteServiceURL: binding.RouteServiceURL, SyslogDrainURL: binding.SyslogDrainURL, VolumeMounts: experimentalVols, + BackupAgentURL: binding.BackupAgentURL, } h.respond(w, http.StatusCreated, experimentalBinding) return @@ -136,5 +138,6 @@ func (h APIHandler) Bind(w http.ResponseWriter, req *http.Request) { SyslogDrainURL: binding.SyslogDrainURL, RouteServiceURL: binding.RouteServiceURL, VolumeMounts: binding.VolumeMounts, + BackupAgentURL: binding.BackupAgentURL, }) } diff --git a/response_test.go b/response_test.go index 39cf1622..b13856f3 100644 --- a/response_test.go +++ b/response_test.go @@ -84,17 +84,6 @@ var _ = Describe("Update Response", func() { }) }) -var _ = Describe("Binding Response", func() { - Describe("JSON encoding", func() { - It("has a credentials object", func() { - binding := brokerapi.BindingResponse{} - jsonString := `{"credentials":null}` - - Expect(json.Marshal(binding)).To(MatchJSON(jsonString)) - }) - }) -}) - var _ = Describe("Error Response", func() { Describe("JSON encoding", func() { It("has a description field", func() { diff --git a/v7/domain/apiresponses/responses.go b/v7/domain/apiresponses/responses.go index bb993872..3b4655c5 100644 --- a/v7/domain/apiresponses/responses.go +++ b/v7/domain/apiresponses/responses.go @@ -59,10 +59,11 @@ type AsyncBindResponse struct { } type BindingResponse struct { - Credentials interface{} `json:"credentials"` + Credentials interface{} `json:"credentials,omitempty"` SyslogDrainURL string `json:"syslog_drain_url,omitempty"` RouteServiceURL string `json:"route_service_url,omitempty"` VolumeMounts []domain.VolumeMount `json:"volume_mounts,omitempty"` + BackupAgentURL string `json:"backup_agent_url,omitempty"` } type GetBindingResponse struct { @@ -75,8 +76,9 @@ type UnbindResponse struct { } type ExperimentalVolumeMountBindingResponse struct { - Credentials interface{} `json:"credentials"` + Credentials interface{} `json:"credentials,omitempty"` SyslogDrainURL string `json:"syslog_drain_url,omitempty"` RouteServiceURL string `json:"route_service_url,omitempty"` VolumeMounts []domain.ExperimentalVolumeMount `json:"volume_mounts,omitempty"` + BackupAgentURL string `json:"backup_agent_url,omitempty"` } diff --git a/v7/domain/service_broker.go b/v7/domain/service_broker.go index dbc6d22e..9aff08e1 100644 --- a/v7/domain/service_broker.go +++ b/v7/domain/service_broker.go @@ -157,6 +157,7 @@ type BindResource struct { SpaceGuid string `json:"space_guid,omitempty"` Route string `json:"route,omitempty"` CredentialClientID string `json:"credential_client_id,omitempty"` + BackupAgent bool `json:"backup_agent,omitempty"` } type UnbindDetails struct { @@ -176,6 +177,7 @@ type Binding struct { Credentials interface{} `json:"credentials"` SyslogDrainURL string `json:"syslog_drain_url"` RouteServiceURL string `json:"route_service_url"` + BackupAgentURL string `json:"backup_agent_url,omitempty"` VolumeMounts []VolumeMount `json:"volume_mounts"` } diff --git a/v7/handlers/bind.go b/v7/handlers/bind.go index a81d1e9e..f6f4aea7 100644 --- a/v7/handlers/bind.go +++ b/v7/handlers/bind.go @@ -88,6 +88,7 @@ func (h APIHandler) Bind(w http.ResponseWriter, req *http.Request) { SyslogDrainURL: binding.SyslogDrainURL, RouteServiceURL: binding.RouteServiceURL, VolumeMounts: binding.VolumeMounts, + BackupAgentURL: binding.BackupAgentURL, }) return } @@ -126,6 +127,7 @@ func (h APIHandler) Bind(w http.ResponseWriter, req *http.Request) { RouteServiceURL: binding.RouteServiceURL, SyslogDrainURL: binding.SyslogDrainURL, VolumeMounts: experimentalVols, + BackupAgentURL: binding.BackupAgentURL, } h.respond(w, http.StatusCreated, experimentalBinding) return @@ -136,5 +138,6 @@ func (h APIHandler) Bind(w http.ResponseWriter, req *http.Request) { SyslogDrainURL: binding.SyslogDrainURL, RouteServiceURL: binding.RouteServiceURL, VolumeMounts: binding.VolumeMounts, + BackupAgentURL: binding.BackupAgentURL, }) }