Skip to content

Commit

Permalink
Support synchronous service provisioning from OSBAPI Brokers
Browse files Browse the repository at this point in the history
fixes #3481
  • Loading branch information
zabanov-lab committed Sep 27, 2024
1 parent a3d4864 commit ad6e0a8
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,10 @@ func (r *Reconciler) provisionServiceInstance(
return ctrl.Result{}, fmt.Errorf("failed to provision service: %w", err)
}

if provisionResponse.Complete {
return ctrl.Result{}, nil
}

serviceInstance.Status.ProvisionOperation = provisionResponse.Operation
meta.SetStatusCondition(&serviceInstance.Status.Conditions, metav1.Condition{
Type: korifiv1alpha1.ProvisionRequestedCondition,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,32 @@ var _ = Describe("CFServiceInstance", func() {
})
})

When("the provisioning is synchronous", func() {
BeforeEach(func() {
brokerClient.ProvisionReturns(osbapi.ServiceInstanceOperationResponse{
Operation: "operation-1",
Complete: true,
}, nil)
})

It("does not check last operation", func() {
Consistently(func(g Gomega) {
g.Expect(brokerClient.GetServiceInstanceLastOperationCallCount()).To(Equal(0))
}).Should(Succeed())
})

It("set sets ready condition to true", func() {
Eventually(func(g Gomega) {
g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(instance), instance)).To(Succeed())

g.Expect(instance.Status.Conditions).To(ContainElement(SatisfyAll(
HasType(Equal(korifiv1alpha1.StatusConditionReady)),
HasStatus(Equal(metav1.ConditionTrue)),
)))
}).Should(Succeed())
})
})

When("service provisioning fails", func() {
BeforeEach(func() {
brokerClient.ProvisionReturns(osbapi.ServiceInstanceOperationResponse{}, errors.New("provision-failed"))
Expand Down
6 changes: 5 additions & 1 deletion controllers/controllers/services/osbapi/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,11 @@ func (c *Client) Provision(ctx context.Context, payload InstanceProvisionPayload
return ServiceInstanceOperationResponse{}, fmt.Errorf("provision request failed with status code: %d", statusCode)
}

var response ServiceInstanceOperationResponse
response := ServiceInstanceOperationResponse{}
if statusCode == http.StatusCreated {
response.Complete = true
}

err = json.Unmarshal(respBytes, &response)
if err != nil {
return ServiceInstanceOperationResponse{}, fmt.Errorf("failed to unmarshal response: %w", err)
Expand Down
37 changes: 29 additions & 8 deletions controllers/controllers/services/osbapi/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ var _ = Describe("OSBAPI Client", func() {
)

BeforeEach(func() {
brokerServer.WithResponse(
brokerServer = broker.NewServer().WithResponse(
"/v2/service_instances/{id}",
map[string]any{
"operation": "provision_op1",
Expand All @@ -162,13 +162,6 @@ var _ = Describe("OSBAPI Client", func() {
})
})

It("provisions the service", func() {
Expect(provisionErr).NotTo(HaveOccurred())
Expect(provisionResp).To(Equal(osbapi.ServiceInstanceOperationResponse{
Operation: "provision_op1",
}))
})

It("sends async provision request to broker", func() {
Expect(provisionErr).NotTo(HaveOccurred())
requests := brokerServer.ServedRequests()
Expand Down Expand Up @@ -203,6 +196,34 @@ var _ = Describe("OSBAPI Client", func() {
}))
})

It("provisions the service synchronously", func() {
Expect(provisionErr).NotTo(HaveOccurred())
Expect(provisionResp).To(Equal(osbapi.ServiceInstanceOperationResponse{
Operation: "provision_op1",
Complete: true,
}))
})

When("the broker accepts the provision request", func() {
BeforeEach(func() {
brokerServer = broker.NewServer().WithResponse(
"/v2/service_instances/{id}",
map[string]any{
"operation": "provision_op1",
},
http.StatusAccepted,
)
})

It("provisions the service asynchronously", func() {
Expect(provisionErr).NotTo(HaveOccurred())
Expect(provisionResp).To(Equal(osbapi.ServiceInstanceOperationResponse{
Operation: "provision_op1",
Complete: false,
}))
})
})

When("the provision request fails", func() {
BeforeEach(func() {
brokerServer = broker.NewServer().WithHandler("/v2/service_instances/{id}", http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
Expand Down
1 change: 1 addition & 0 deletions controllers/controllers/services/osbapi/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ type Plan struct {

type ServiceInstanceOperationResponse struct {
Operation string `json:"operation"`
Complete bool
}

type LastOperationResponse struct {
Expand Down
3 changes: 2 additions & 1 deletion tests/helpers/broker/broker.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ func (b *BrokerServer) WithResponse(pattern string, response map[string]any, sta
Expect(err).NotTo(HaveOccurred())

return b.WithHandler(pattern, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write(respBytes)
w.WriteHeader(statusCode)
_, err := w.Write(respBytes)
Expect(err).NotTo(HaveOccurred())
}))
}

Expand Down

0 comments on commit ad6e0a8

Please sign in to comment.