Skip to content
This repository was archived by the owner on May 6, 2022. It is now read-only.
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
4 changes: 2 additions & 2 deletions v2/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,12 @@ func doResponseChecks(t *testing.T, name string, response interface{}, err error
t.Errorf("%v: unexpected error message: expected %v, got %v", name, expectedErrMessage, err)
return
} else if err != nil && expectedErr != nil && !reflect.DeepEqual(expectedErr, err) {
t.Errorf("%v: unexpected error: expected %+v, got %v", name, expectedErr, err)
t.Errorf("%v: unexpected error:\n\nexpected: %+v\n\ngot: %+v", name, expectedErr, err)
return
}

if e, a := expectedResponse, response; !reflect.DeepEqual(e, a) {
t.Errorf("%v: unexpected diff in response; expected %+v, got %+v", name, e, a)
t.Errorf("%v: unexpected diff in response;\n\nexpected: %+v\n\ngot: %+v", name, e, a)
return
}
}
Expand Down
4 changes: 4 additions & 0 deletions v2/provision_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ func (c *client) ProvisionInstance(r *ProvisionRequest) (*ProvisionResponse, err
return nil, HTTPStatusCodeError{StatusCode: response.StatusCode, ResponseError: err}
}

if !c.APIVersion.AtLeast(Version2_13()) || !c.EnableAlphaFeatures {
userResponse.ExtensionAPIs = nil
}

return userResponse, nil
case http.StatusAccepted:
if !r.AcceptsIncomplete {
Expand Down
74 changes: 74 additions & 0 deletions v2/provision_instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,51 @@ func successProvisionResponseAsync() *ProvisionResponse {

const contextProvisionRequestBody = `{"service_id":"test-service-id","plan_id":"test-plan-id","organization_guid":"test-organization-guid","space_guid":"test-space-guid","context":{"foo":"bar"}}`

const provisionResponseBodyWithExtensions = `{
"extension_apis":[{
"discovery_url": "http://example-openapi-doc.example.com/extensions",
"server_url": "http://myremoteserver.example.com",
"credentials": {
"basic": {
"username": "admin",
"password": "changeme"
},
"api_key": {
"api_key": "some_key_value"
},
"petstore_auth": {
"token": "some_token_value"
}
},
"adheres_to": "http://example-specification.example.com"
}]
}`

func successProvisionResponseWithExtensions() *ProvisionResponse {
response := &ProvisionResponse{}
response.ExtensionAPIs = []ExtensionAPI{
{
DiscoveryURL: "http://example-openapi-doc.example.com/extensions",
ServerURL: "http://myremoteserver.example.com",
Credentials: map[string]interface{}{
"basic": map[string]interface{}{
"username": "admin",
"password": "changeme",
},
"api_key": map[string]interface{}{
"api_key": "some_key_value",
},
"petstore_auth": map[string]interface{}{
"token": "some_token_value",
},
},
AdheresTo: "http://example-specification.example.com",
},
}

return response
}

func TestProvisionInstance(t *testing.T) {
cases := []struct {
name string
Expand Down Expand Up @@ -220,6 +265,35 @@ func TestProvisionInstance(t *testing.T) {
},
expectedResponse: successProvisionResponse(),
},
{
name: "success with extension APIs",
version: Version2_13(),
enableAlpha: true,
httpReaction: httpReaction{
status: http.StatusCreated,
body: provisionResponseBodyWithExtensions,
},
expectedResponse: successProvisionResponseWithExtensions(),
},
{
name: "extension APIs shouldn't be returned for < 2.13",
version: Version2_12(),
enableAlpha: true,
httpReaction: httpReaction{
status: http.StatusCreated,
body: provisionResponseBodyWithExtensions,
},
expectedResponse: &ProvisionResponse{},
},
{
name: "extension APIs shouldn't be returned when alpha features disabled",
version: Version2_13(),
httpReaction: httpReaction{
status: http.StatusCreated,
body: provisionResponseBodyWithExtensions,
},
expectedResponse: &ProvisionResponse{},
},
}

for _, tc := range cases {
Expand Down
37 changes: 37 additions & 0 deletions v2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,43 @@ type ProvisionResponse struct {
// OperationKey is an extra identifier supplied by the broker to identify
// asynchronous operations.
OperationKey *OperationKey `json:"operation,omitempty"`
// ExtensionAPIs is a list of extension APIs for this instance.
//
// ExtensionsAPI is an ALPHA API attribute and may change. Alpha
// features must be enabled and the client must be using the
// latest API Version in order to use this.
ExtensionAPIs []ExtensionAPI `json:"extension_apis,omitempty"`
}

// ExtensionAPI contains information about an API endpoint that describes
// extension operations on a ServiceInstance.
//
// ExtensionAPI is an ALPHA API attribute and may change. Alpha
// features must be enabled and the client must be using the
// latest API Version in order to use this.
type ExtensionAPI struct {
// DiscoveryURL is a URI pointing to a valid OpenAPI 3.0+ document
// describing the API extension(s) to the Open Service Broker API including,
// endpoints, parameters, authentication mechanism and any other detail the
// platform needs for invocation. The location of the API extension
// endpoint(s) can be local to the Service Broker or on a remote server. If
// local to the Service Broker the same authentication method for normal
// Service Broker calls must be used.
DiscoveryURL string `json:"discovery_url,omitempty"`
// ServerURL is a URI pointing to a remote server where API extensions will
// run. This URI will be used as the basepath for the paths objects
// described by the `discovery_url` OpenAPI document. If ServerURL is
// missing, it means that the paths are invoked relative to the service
// broker URL.
ServerURL string `json:"server_url,omitempty"`
// Credentials is a set of authentication details for running any of the
// extension API calls, especially for those running on remote servers.
//
// The information in Credentials should be treated as SECRET.
Credentials map[string]interface{} `json:"credentials,omitempty"`
// AdheresTo is a URI refering to a specification detailing the interface
// the OpenAPI document hosted at the `discovery_url` adheres to.
AdheresTo string `json:"adheres_to,omitempty"`
}

// OperationKey is an extra identifier from the broker in order to provide extra
Expand Down