Skip to content

Commit

Permalink
Add adapt credentials endpoint (#190)
Browse files Browse the repository at this point in the history
* Add adapt credentials endpoint

Co-authored-by: Ulrich Kramer <[email protected]>

* Add test cases for adapt credentials.

Co-authored-by: Axel Siebenborn <[email protected]>

* Add adapt_credentials to plugin code.

Co-authored-by: Axel Siebenborn <[email protected]>

* Fix test case for adapt credentials

Co-authored-by: Ulrich Kramer <[email protected]>
  • Loading branch information
2 people authored and dzahariev committed Dec 7, 2018
1 parent 2820247 commit d047a5e
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 15 deletions.
12 changes: 7 additions & 5 deletions api/osb/osb.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ const (
// baseURL is the OSB API controller path
baseURL = web.OSBURL + "/{" + BrokerIDPathParam + "}"

catalogURL = baseURL + "/v2/catalog"
serviceInstanceURL = baseURL + "/v2/service_instances/{instance_id}"
serviceInstanceLastOperationURL = baseURL + "/v2/service_instances/{instance_id}/last_operation"
serviceBindingURL = baseURL + "/v2/service_instances/{instance_id}/service_bindings/{binding_id}"
serviceBindingLastOperationURL = baseURL + "/v2/service_instances/{instance_id}/service_bindings/{binding_id}/last_operation"
catalogURL = baseURL + "/v2/catalog"
serviceInstanceURL = baseURL + "/v2/service_instances/{instance_id}"
serviceInstanceLastOperationURL = baseURL + "/v2/service_instances/{instance_id}/last_operation"
serviceBindingURL = baseURL + "/v2/service_instances/{instance_id}/service_bindings/{binding_id}"
serviceBindingLastOperationURL = baseURL + "/v2/service_instances/{instance_id}/service_bindings/{binding_id}/last_operation"
serviceBindingAdaptCredentialsURL = baseURL + "/v2/service_instances/{instance_id}/service_bindings/{binding_id}/adapt_credentials"
)

// Routes implements api.Controller.Routes by providing the routes for the OSB API
Expand All @@ -53,5 +54,6 @@ func (c *controller) Routes() []web.Route {

{Endpoint: web.Endpoint{Method: http.MethodGet, Path: serviceInstanceLastOperationURL}, Handler: c.handler},
{Endpoint: web.Endpoint{Method: http.MethodGet, Path: serviceBindingLastOperationURL}, Handler: c.handler},
{Endpoint: web.Endpoint{Method: http.MethodPost, Path: serviceBindingAdaptCredentialsURL}, Handler: c.handler},
}
}
4 changes: 4 additions & 0 deletions pkg/web/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,10 @@ func (api *API) decomposePlugin(plug Plugin) []Filter {
filter := newPluginSegment(plug.Name()+":PollBinding", http.MethodGet, "/v1/osb/*/v2/service_instances/*/service_bindings/*/last_operation", MiddlewareFunc(p.PollBinding))
filters = append(filters, filter)
}
if p, ok := plug.(CredentialsAdapter); ok {
filter := newPluginSegment(plug.Name()+":AdaptCredentials", http.MethodPost, "/v1/osb/*/v2/service_instances/*/service_bindings/*/adapt_credentials", MiddlewareFunc(p.AdaptCredentials))
filters = append(filters, filter)
}

return filters
}
6 changes: 6 additions & 0 deletions pkg/web/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,9 @@ type BindingPoller interface {

PollBinding(request *Request, next Handler) (*Response, error)
}

type CredentialsAdapter interface {
Plugin

AdaptCredentials(request *Request, next Handler) (*Response, error)
}
37 changes: 27 additions & 10 deletions test/common/broker.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,22 +209,24 @@ var AnotherPlan = `
type BrokerServer struct {
*httptest.Server

CatalogHandler http.HandlerFunc // /v2/catalog
ServiceInstanceHandler http.HandlerFunc // /v2/service_instances/{instance_id}
ServiceInstanceLastOpHandler http.HandlerFunc // /v2/service_instances/{instance_id}/last_operation
BindingHandler http.HandlerFunc // /v2/service_instances/{instance_id}/service_bindings/{binding_id}
BindingLastOpHandler http.HandlerFunc // /v2/service_instances/{instance_id}/service_bindings/{binding_id}/last_operation
CatalogHandler http.HandlerFunc // /v2/catalog
ServiceInstanceHandler http.HandlerFunc // /v2/service_instances/{instance_id}
ServiceInstanceLastOpHandler http.HandlerFunc // /v2/service_instances/{instance_id}/last_operation
BindingHandler http.HandlerFunc // /v2/service_instances/{instance_id}/service_bindings/{binding_id}
BindingLastOpHandler http.HandlerFunc // /v2/service_instances/{instance_id}/service_bindings/{binding_id}/last_operation
BindingAdaptCredentialsHandler http.HandlerFunc // /v2/service_instances/{instance_id}/service_bindings/{binding_id}/adapt_credentials

Username, Password string
Catalog interface{}
LastRequestBody []byte
LastRequest *http.Request

CatalogEndpointRequests []*http.Request
ServiceInstanceEndpointRequests []*http.Request
ServiceInstanceLastOpEndpointRequests []*http.Request
BindingEndpointRequests []*http.Request
BindingLastOpEndpointRequests []*http.Request
CatalogEndpointRequests []*http.Request
ServiceInstanceEndpointRequests []*http.Request
ServiceInstanceLastOpEndpointRequests []*http.Request
BindingEndpointRequests []*http.Request
BindingLastOpEndpointRequests []*http.Request
BindingAdaptCredentialsEndpointRequests []*http.Request

router *mux.Router
}
Expand Down Expand Up @@ -271,6 +273,7 @@ func (b *BrokerServer) ResetHandlers() {
b.ServiceInstanceLastOpHandler = b.defaultServiceInstanceLastOpHandler
b.BindingHandler = b.defaultBindingHandler
b.BindingLastOpHandler = b.defaultBindingLastOpHandler
b.BindingAdaptCredentialsHandler = b.defaultBindingAdaptCredentialsHandler
}

func (b *BrokerServer) ResetCallHistory() {
Expand Down Expand Up @@ -308,6 +311,11 @@ func (b *BrokerServer) initRouter() {
b.BindingLastOpHandler(rw, req)
}).Methods(http.MethodGet)

router.HandleFunc("/v2/service_instances/{instance_id}/service_bindings/{binding_id}/adapt_credentials", func(rw http.ResponseWriter, req *http.Request) {
b.BindingAdaptCredentialsEndpointRequests = append(b.BindingAdaptCredentialsEndpointRequests, req)
b.BindingAdaptCredentialsHandler(rw, req)
}).Methods(http.MethodPost)

router.Use(b.authenticationMiddleware)
router.Use(b.saveRequestMiddleware)

Expand Down Expand Up @@ -391,6 +399,15 @@ func (b *BrokerServer) defaultBindingLastOpHandler(rw http.ResponseWriter, req *
})
}

func (b *BrokerServer) defaultBindingAdaptCredentialsHandler(rw http.ResponseWriter, req *http.Request) {
SetResponse(rw, http.StatusOK, Object{
"credentials": Object{
"instance_id": mux.Vars(req)["instance_id"],
"binding_id": mux.Vars(req)["binding_id"],
},
})
}

func SetResponse(rw http.ResponseWriter, status int, message interface{}) {
err := util.WriteJSON(rw, status, message)
if err != nil {
Expand Down
44 changes: 44 additions & 0 deletions test/osb_test/osb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ var _ = Describe("Service Manager OSB API", func() {
failingBrokerServer.CatalogHandler = failingHandler
failingBrokerServer.ServiceInstanceLastOpHandler = failingHandler
failingBrokerServer.BindingLastOpHandler = failingHandler
failingBrokerServer.BindingAdaptCredentialsHandler = failingHandler

UUID, err := uuid.NewV4()
if err != nil {
Expand Down Expand Up @@ -445,6 +446,49 @@ var _ = Describe("Service Manager OSB API", func() {
})
})

Describe("Post Binding Adapt Credentials", func() {
Context("when call to working service broker", func() {
It("should succeed", func() {
assertWorkingBrokerResponse(
ctx.SMWithBasic.POST(workingBrokerURL+"/v2/service_instances/iid/service_bindings/bid/adapt_credentials").WithHeader("X-Broker-API-Version", "oidc_authn.13").WithJSON(&object{}),
http.StatusOK, "credentials")
})
})

Context("when call to broken service broker", func() {
It("should fail", func() {
assertBrokenBrokerError(
ctx.SMWithBasic.POST(brokerBrokerURL+"/v2/service_instances/iid/service_bindings/bid/adapt_credentials").WithHeader("X-Broker-API-Version", "oidc_authn.13").WithJSON(&object{}))

})
})

Context("when call to missing service broker", func() {
It("should fail", func() {
assertMissingBrokerError(
ctx.SMWithBasic.POST(missingBrokerURL+"/v2/service_instances/iid/service_bindings/bid/adapt_credentials").WithHeader("X-Broker-API-Version", "oidc_authn.13").WithJSON(&object{}))

})
})

Context("when call to stopped service broker", func() {
It("should fail", func() {
assertStoppedBrokerError(
ctx.SMWithBasic.POST(stoppedBrokerURL+"/v2/service_instances/iid/service_bindings/bid/adapt_credentials").WithHeader("X-Broker-API-Version", "oidc_authn.13").WithJSON(&object{}))

})
})

Context("when call contains query params", func() {
It("propagates them to the service broker", func() {
assertWorkingBrokerResponse(
ctx.SMWithBasic.GET(queryParamVerificationBrokerOSBURL+"/v2/service_instances/iid/service_bindings/bid/last_operation").WithHeader("X-Broker-API-Version", "oidc_authn.13").
WithJSON(getDummyService()).WithQuery(headerKey, headerValue), http.StatusOK)
})
})

})

Describe("Prefixed broker path", func() {
Context("when call to working broker", func() {

Expand Down
5 changes: 5 additions & 0 deletions test/plugin_test/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ var _ = Describe("Service Manager Plugins", func() {
{"fetchBinding", "GET", "/v2/service_instances/1234/service_bindings/111", []string{""}, http.StatusOK},
{"pollInstance", "GET", "/v2/service_instances/1234/last_operation", []string{"", "service_id=serviceId", "plan_id=planId", "operation=provision", "service_id=serviceId&plan_id=planId&operation=provision"}, http.StatusOK},
{"pollBinding", "GET", "/v2/service_instances/1234/service_bindings/111/last_operation", []string{"", "service_id=serviceId", "plan_id=planId", "operation=provision", "service_id=serviceId&plan_id=planId&operation=provision"}, http.StatusOK},
{"adaptCredentials", "POST", "/v2/service_instances/1234/service_bindings/111/adapt_credentials", []string{""}, http.StatusOK},
}

for _, op := range osbOperations {
Expand Down Expand Up @@ -258,6 +259,10 @@ func (p TestPlugin) PollBinding(request *web.Request, next web.Handler) (*web.Re
return p.call(p["pollBinding"], request, next)
}

func (p TestPlugin) AdaptCredentials(request *web.Request, next web.Handler) (*web.Response, error) {
return p.call(p["adaptCredentials"], request, next)
}

type PartialPlugin struct{}

func (p PartialPlugin) Name() string { return "PartialPlugin" }
Expand Down

0 comments on commit d047a5e

Please sign in to comment.