Skip to content

Commit

Permalink
Implement DELETE /v3/service_brokers/guid
Browse files Browse the repository at this point in the history
fixes #3268

Co-authored-by: Danail Branekov <danailster@gmail.com>
  • Loading branch information
georgethebeatle and danail-branekov committed Jul 18, 2024
1 parent 55a890b commit 28dd19f
Show file tree
Hide file tree
Showing 12 changed files with 526 additions and 56 deletions.
161 changes: 161 additions & 0 deletions api/handlers/fake/cfservice_broker_repository.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions api/handlers/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const (
DomainDeleteJobType = "domain.delete"
RoleDeleteJobType = "role.delete"
ServiceBrokerCreateJobType = "service_broker.create"
ServiceBrokerDeleteJobType = "service_broker.delete"

JobTimeoutDuration = 120.0
)
Expand Down
24 changes: 24 additions & 0 deletions api/handlers/service_broker.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@ import (

const (
ServiceBrokersPath = "/v3/service_brokers"
ServiceBrokerPath = ServiceBrokersPath + "/{guid}"
)

//counterfeiter:generate -o fake -fake-name CFServiceBrokerRepository . CFServiceBrokerRepository
type CFServiceBrokerRepository interface {
CreateServiceBroker(context.Context, authorization.Info, repositories.CreateServiceBrokerMessage) (repositories.ServiceBrokerResource, error)
ListServiceBrokers(context.Context, authorization.Info, repositories.ListServiceBrokerMessage) ([]repositories.ServiceBrokerResource, error)
GetServiceBroker(context.Context, authorization.Info, string) (repositories.ServiceBrokerResource, error)
DeleteServiceBroker(context.Context, authorization.Info, string) error
}

type ServiceBroker struct {
Expand Down Expand Up @@ -76,6 +79,26 @@ func (h *ServiceBroker) list(r *http.Request) (*routing.Response, error) {
return routing.NewResponse(http.StatusOK).WithBody(presenter.ForList(presenter.ForServiceBroker, brokers, h.serverURL, *r.URL)), nil
}

func (h *ServiceBroker) delete(r *http.Request) (*routing.Response, error) {
authInfo, _ := authorization.InfoFromContext(r.Context())
logger := logr.FromContextOrDiscard(r.Context()).WithName("handlers.service-broker.delete")

guid := routing.URLParam(r, "guid")

_, err := h.serviceBrokerRepo.GetServiceBroker(r.Context(), authInfo, guid)
if err != nil {
return nil, apierrors.LogAndReturn(logger, apierrors.ForbiddenAsNotFound(err), "failed to get service broker")
}

err = h.serviceBrokerRepo.DeleteServiceBroker(r.Context(), authInfo, guid)
if err != nil {
return nil, apierrors.LogAndReturn(logger, err, "error when deleting service broker", "guid", guid)
}

return routing.NewResponse(http.StatusAccepted).
WithHeader("Location", presenter.JobURLForRedirects(guid, presenter.ServiceBrokerDeleteOperation, h.serverURL)), nil
}

func (h *ServiceBroker) UnauthenticatedRoutes() []routing.Route {
return nil
}
Expand All @@ -84,5 +107,6 @@ func (h *ServiceBroker) AuthenticatedRoutes() []routing.Route {
return []routing.Route{
{Method: "POST", Pattern: ServiceBrokersPath, Handler: h.create},
{Method: "GET", Pattern: ServiceBrokersPath, Handler: h.list},
{Method: "DELETE", Pattern: ServiceBrokerPath, Handler: h.delete},
}
}
60 changes: 60 additions & 0 deletions api/handlers/service_broker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"net/http"
"strings"

apierrors "code.cloudfoundry.org/korifi/api/errors"
"code.cloudfoundry.org/korifi/api/handlers"
"code.cloudfoundry.org/korifi/api/handlers/fake"
"code.cloudfoundry.org/korifi/api/payloads"
Expand Down Expand Up @@ -167,4 +168,63 @@ var _ = Describe("ServiceBroker", func() {
})
})
})

Describe("DELETE /v3/service_brokers/guid", func() {
BeforeEach(func() {
serviceBrokerRepo.GetServiceBrokerReturns(repositories.ServiceBrokerResource{
CFResource: model.CFResource{
GUID: "broker-guid",
},
}, nil)

var err error
req, err = http.NewRequestWithContext(ctx, "DELETE", "/v3/service_brokers/broker-guid", nil)
Expect(err).NotTo(HaveOccurred())
})

It("deletes the service broker", func() {
Expect(serviceBrokerRepo.GetServiceBrokerCallCount()).To(Equal(1))
_, actualAuthInfo, actualBrokerGUID := serviceBrokerRepo.GetServiceBrokerArgsForCall(0)
Expect(actualAuthInfo).To(Equal(authInfo))
Expect(actualBrokerGUID).To(Equal("broker-guid"))

Expect(serviceBrokerRepo.DeleteServiceBrokerCallCount()).To(Equal(1))
_, actualAuthInfo, actualBrokerGUID = serviceBrokerRepo.DeleteServiceBrokerArgsForCall(0)
Expect(actualAuthInfo).To(Equal(authInfo))
Expect(actualBrokerGUID).To(Equal("broker-guid"))

Expect(rr).To(HaveHTTPStatus(http.StatusAccepted))
Expect(rr).To(HaveHTTPHeaderWithValue("Location", "https://api.example.org/v3/jobs/service_broker.delete~broker-guid"))
})

When("getting the service broker is not allowed", func() {
BeforeEach(func() {
serviceBrokerRepo.GetServiceBrokerReturns(repositories.ServiceBrokerResource{}, apierrors.NewForbiddenError(nil, repositories.ServiceBrokerResourceType))
})

It("returns a not found error", func() {
expectNotFoundError(repositories.ServiceBrokerResourceType)
})
})

When("getting the service broker fails", func() {
BeforeEach(func() {
serviceBrokerRepo.GetServiceBrokerReturns(repositories.ServiceBrokerResource{}, errors.New("get-broker-err"))
})

It("returns an error", func() {
expectUnknownError()
})
})

When("getting the service broker fails", func() {
BeforeEach(func() {
serviceBrokerRepo.DeleteServiceBrokerReturns(errors.New("delete-broker-err"))
})

It("returns an error", func() {
expectUnknownError()
})
})
})
})
13 changes: 7 additions & 6 deletions api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,12 +343,13 @@ func main() {
handlers.NewJob(
*serverURL,
map[string]handlers.DeletionRepository{
handlers.OrgDeleteJobType: orgRepo,
handlers.SpaceDeleteJobType: spaceRepo,
handlers.AppDeleteJobType: appRepo,
handlers.RouteDeleteJobType: routeRepo,
handlers.DomainDeleteJobType: domainRepo,
handlers.RoleDeleteJobType: roleRepo,
handlers.OrgDeleteJobType: orgRepo,
handlers.SpaceDeleteJobType: spaceRepo,
handlers.AppDeleteJobType: appRepo,
handlers.RouteDeleteJobType: routeRepo,
handlers.DomainDeleteJobType: domainRepo,
handlers.RoleDeleteJobType: roleRepo,
handlers.ServiceBrokerDeleteJobType: serviceBrokerRepo,
},
map[string]handlers.StateRepository{
handlers.ServiceBrokerCreateJobType: serviceBrokerRepo,
Expand Down
2 changes: 1 addition & 1 deletion api/payloads/service_broker.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (b *ServiceBrokerList) DecodeFromURLValues(values url.Values) error {
}

func (b *ServiceBrokerList) SupportedKeys() []string {
return []string{"names"}
return []string{"names", "page", "per_page"}
}

func (b *ServiceBrokerList) ToMessage() repositories.ListServiceBrokerMessage {
Expand Down
1 change: 1 addition & 0 deletions api/presenter/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const (
DomainDeleteOperation = "domain.delete"
RoleDeleteOperation = "role.delete"
ServiceBrokerCreateOperation = "service_broker.create"
ServiceBrokerDeleteOperation = "service_broker.delete"
)

var (
Expand Down
Loading

0 comments on commit 28dd19f

Please sign in to comment.