-
Notifications
You must be signed in to change notification settings - Fork 434
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support asynchronous bindings (requires #333) #334
Support asynchronous bindings (requires #333) #334
Conversation
Hey mattmcneeney! Thanks for submitting this pull request! I'm here to inform the recipients of the pull request that you and the commit authors have already signed the CLA. |
2c53363
to
e843013
Compare
spec.md
Outdated
##### Body | ||
|
||
For success responses, the following fields are supported. Others will be | ||
ignored. For error responses, see [Broker Errors](#service-broker-errors). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this 'Others will be ignored'? I assume the intent here is that some brokers might return some other fields due to the platforms/systems they are built on and we want to allow for that? Question is, will there be some brokers that return additional fields that might not be in the spec yet but the platforms will use. I'm just thinking, who ignores these fields and is the intent that they must be ignored, or something. Just curious :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just brought this across for consistency. 'Others will be ignored' is always kinda weird for a JSON object. If we remove this across the spec I'll happily remove here!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to a follow-on PR to remove it.
spec.md
Outdated
@@ -1126,6 +1209,7 @@ $ curl http://username:password@service-broker-url/v2/service_instances/:instanc | |||
| --- | --- | | |||
| 200 OK | MUST be returned if the binding already exists and the requested parameters are identical to the existing binding. The expected response body is below. | | |||
| 201 Created | MUST be returned if the binding was created as a result of this request. The expected response body is below. | | |||
| 202 Accepted | MUST be returned if the binding is in progress. This triggers the platform marketplace to poll the [Polling Last Operation for Service Bindings](#polling-last-operation-for-service-bindings) endpoint for operation status. Information regarding the service binding (i.e. credentials) MUST NOT be returned in this asynchronous request. Note that a re-sent `PUT` request MUST return a `202 Accepted`, not a `200 OK`, if the binding is not yet fully created. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
re-sent PUT
, does it have to be identical PUT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes!
Still discussing this internally but some immediate feedback I received is that requiring GET might be a bit of a security issue or hardship. This will force the broker to not just persist the credentials during the bind() and last_operation() phase, but then to persist it forever. |
@duglin Isn't that already true? According to the spec, if the broker receives a duplicate
This duplicate binding request can occur at any time, not necessarily within a short amount of time after the initial binding request. |
hmmm that's a good point. I'm curious, for the CF guys who support stateless brokers, how can this check be performed if the broker is stateless? |
spec.md
Outdated
| Status Code | Description | | ||
| --- | --- | | ||
| 200 OK | The expected response body is below. | | ||
| 404 Not Found | MUST be returned if the service instance does not exist or if a provisioning operation is still in progress. The expected response body is `{}`. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What should happen if the instance update request is in progress (i.e. there is an existing resource, but the update processing is not finished yet)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to me like this should be added here as a 422 - Unprocessable Entity
situation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if 409 is more appropriate:
409 Conflict
Indicates that the request could not be processed because of conflict in the request, such as an edit conflict between multiple simultaneous updates.
spec.md
Outdated
`"state": "failed"` will cause the platform to cease polling and, in the case of | ||
a [Binding](#binding) request, information on the service binding can then | ||
immediately be fetched using the | ||
[Fetching a Service Binding](#fetching-a-service-binding) endpoint. The value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But what if the catalog endpoint returns "binding_retrievable": false
? Do we still support async bindings (without being able to fetch any result)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that we should explicitly add that if a binding supports async operations, it must have "binding_retrievable": true
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The wording with binding_retrievable
is a bit ambiguous. It says:
If `"binding_retrievable" :true` is declared for a service in the Catalog endpoint, brokers MUST support this endpoint for all plans of the service.
It doesn't say that having "binding_retrievable": false
means the endpoint is unavailable for all plans, so you could potentially have some plans able to support it and some not, and thus some plans able to be asynchronously bound to and some not.
I think we should tighten the language on the binding_retrievable
definition to say that a platform should not attempt a GET if a service has "binding_retrievable": false
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is sensible, thanks!
c37a2bf
to
20979fd
Compare
Is there anything else that needs to be done before we can move this forward? Service Catalog is working on implementing this and we would like to ensure this is agreed upon asap. Can we make the decisions during tomorrows call for the remaining items? |
20979fd
to
8473e14
Compare
@vaikas-google I totally agree. Let's get this discussed on today's call and get this marked as being validated so we can work on getting this supported in platforms. |
8473e14
to
4187321
Compare
Please all review this PR as we are planning on moving this to |
spec.md
Outdated
|
||
| Response Field | Type | Description | | ||
| --- | --- | --- | | ||
| credentials | object | A free-form hash of credentials that can be used by applications or users to access the service. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the Types of Binding section of the spec it reads:
Credentials are a set of information... If the Service Broker supports generation of credentials it MUST return credentials in the response for a request to create a Service Binding.
I think we should incorporate the MUST in the table. Most of the time I refer to the table, and example responses, to see what I need to return.
Something like this:
A free-form hash of credentials that can be used by applications or users to access the service. If the Service Broker supports generate of credentials it MUST return this in the response.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is the MUST that was asked for? I don't see it in the above table.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, missed that bit. I personally think it's clear enough in the types of binding section, but can add this in here too.
spec.md
Outdated
| credentials | object | A free-form hash of credentials that can be used by applications or users to access the service. | | ||
| syslog_drain_url | string | A URL to which logs MUST be streamed. `"requires":["syslog_drain"]` MUST be declared in the [Catalog](#catalog-management) endpoint or the platform MUST consider the response invalid. | | ||
| route_service_url | string | A URL to which the platform MUST proxy requests for the address sent with `bind_resource.route` in the request body. `"requires":["route_forwarding"]` MUST be declared in the [Catalog](#catalog-management) endpoint or the platform can consider the response invalid. | | ||
| volume_mounts | array-of-objects | An array of configuration for mounting volumes. `"requires":["volume_mount"]` MUST be declared in the [Catalog](#catalog-management) endpoint or the platform can consider the response invalid. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment about volume_mounts
. The Types of Bindings section reads:
A create binding response from one of these services MUST include volume_mounts.
but the table doesn't mention that this field MUST be returned if the broker supports volume mounts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also done!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the MUST someplace else in the doc now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copied here too
Other than the above clarification points, I approve of this PR! |
4187321
to
ed63ec8
Compare
LGTM |
spec.md
Outdated
@@ -590,9 +597,8 @@ code `422 Unprocessable Entity` and the following body | |||
``` | |||
|
|||
If the query parameter described above is present, and the Service Broker | |||
executes the request asynchronously, the Service Broker MUST return the | |||
asynchronous response `202 Accepted`. The response body SHOULD be the same as | |||
if the Service Broker were serving the request synchronously. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we've dropped the statement about the response looking the same between async and sync - is that really ok?
If I were to read the spec w/o any history of what was there in the past, I would probably return a 202 with just {} in the Body for async ops. Is that now ok even for provisioning? And, as a platform author I would probably expect that too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hope so, it was only a SHOULD. Otherwise we can add text stating that async instance provision SHOULD return the same as sync, but leave this open for async bindings? But I'd prefer to just remove this...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm just worried about the dashboard_url. This change pushes us towards not returning it on the provision response during an async provision. While I would prefer this model, I wasn't sure how existing brokers would feel about this shift in direction within the v2 time frame.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. We could explicity change the dashboard_url
in the response table for provision to state that it MUST be returned immediately even in the async case. Do we want to lock ourselves into that though? Or maybe we feel that we already are, no matter what the wording says?
If CF wanted to get dashboard_url at a later date, it would have to use the GET endpoints, which are going to require a change to CF anyway to call those. But I guess for provision the only data is this URL so maybe we can just enforce that to be returned immediately. We haven't had much feedback from service authors on that front as far as I remember.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@duglin we actually already have that on line 922:
Note: a Service Broker that wishes to return `dashboard_url` for a service instance MUST return it with the initial response to the provision request, even if the service is provisioned asynchronously. If present, MUST be a non-empty string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
feels a little inconsistent to have a SHOULD in one spot (or implied SHOULD (or less) now), and a MUST in another. Seems we need to first decide is the MUST should live on - which I suspect it should since that would be a breaking change. If so, then I think we may need to be more explicit that an async provision is not the same as async binding because async provision requires a non-empty response.
spec.md
Outdated
| --- | --- | | ||
| 200 OK | MUST be returned upon successful processing of this request. The expected response body is below. | | ||
| 400 Bad Request | MUST be returned if the request is malformed or missing mandatory data. | | ||
| 410 Gone | Appropriate only for asynchronous delete operations. The Platform MUST consider this response a success and remove the resource from its database. The expected response body is `{}`. Returning this while the Platform is polling for create operations SHOULD be interpreted as an invalid response and the Platform SHOULD continue polling. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In other spots you removed "The expected response body is {}
.". Should we do that here too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -1247,7 +1328,7 @@ binding requests. | |||
|
|||
#### cURL | |||
``` | |||
$ curl http://username:password@service-broker-url/v2/service_instances/:instance_id/service_bindings/:binding_id -d '{ | |||
$ curl http://username:password@service-broker-url/v2/service_instances/:instance_id/service_bindings/:binding_id?accepts_incomplete=true -d '{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's interesting that the example curl here now includes an optional query param
the provision curl request does not include it.
do we care either way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nevermind, curl examples are the same, was looking at the top level request example
spec.md
Outdated
@@ -1270,9 +1351,10 @@ $ curl http://username:password@service-broker-url/v2/service_instances/:instanc | |||
| --- | --- | | |||
| 200 OK | MUST be returned if the binding already exists and the requested parameters are identical to the existing binding. The expected response body is below. | | |||
| 201 Created | MUST be returned if the binding was created as a result of this request. The expected response body is below. | | |||
| 202 Accepted | MUST be returned if the binding is in progress. The `operation` string MUST match that returned for the original request. This triggers the Platform to poll the [Polling Last Operation for Service Bindings](#polling-last-operation-for-service-bindings) endpoint for operation status. Information regarding the Service Binding (i.e. credentials) MUST NOT be returned in this asynchronous request. Note that a re-sent `PUT` request MUST return a `202 Accepted`, not a `200 OK`, if the binding is not yet fully created. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/asynchronous request/asynchronous response/ - maybe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -1450,23 +1543,37 @@ The following HTTP Headers are defined for this operation: | |||
|
|||
``` | |||
$ curl 'http://username:password@service-broker-url/v2/service_instances/:instance_id/ | |||
service_bindings/:binding_id?service_id=service-id-here&plan_id=plan-id-here' -X DELETE -H "X-Broker-API-Version: 2.13" | |||
service_bindings/:binding_id?service_id=service-id-here&plan_id=plan-id-here&accepts_incomplete=true' -X DELETE -H "X-Broker-API-Version: 2.13" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
similar as previous note about including optional query params in curl example
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nevermind, curl examples are the same, was looking at the top level request example
spec.md
Outdated
| syslog_drain_url | string | A URL to which logs MUST be streamed. `"requires":["syslog_drain"]` MUST be declared in the [Catalog](#catalog-management) endpoint or the Platform MUST consider the response invalid. | | ||
| route_service_url | string | A URL to which the Platform MUST proxy requests for the address sent with `bind_resource.route` in the request body. `"requires":["route_forwarding"]` MUST be declared in the [Catalog](#catalog-management) endpoint or the Platform can consider the response invalid. | | ||
| volume_mounts | array of [VolumeMount](#volume-mount-object) objects | An array of configuration for remote storage devices to be mounted into an application container filesystem. `"requires":["volume_mount"]` MUST be declared in the [Catalog](#catalog-management) endpoint or the Platform can consider the response invalid. | | ||
| credentials | object | A free-form hash of credentials that can be used by applications or users to access the service. MUST be returned for a synchronous request if the Service Broker supports generation of credentials. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/sync request/sync bind/
I think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, as a followup?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
spec.md
Outdated
| route_service_url | string | A URL to which the Platform MUST proxy requests for the address sent with `bind_resource.route` in the request body. `"requires":["route_forwarding"]` MUST be declared in the [Catalog](#catalog-management) endpoint or the Platform can consider the response invalid. | | ||
| volume_mounts | array of [VolumeMount](#volume-mount-object) objects | An array of configuration for remote storage devices to be mounted into an application container filesystem. `"requires":["volume_mount"]` MUST be declared in the [Catalog](#catalog-management) endpoint or the Platform can consider the response invalid. | | ||
| credentials | object | A free-form hash of credentials that can be used by applications or users to access the service. MUST be returned for a synchronous request if the Service Broker supports generation of credentials. | | ||
| syslog_drain_url | string | A URL to which logs MUST be streamed. If the service declares `"requires":["syslog_drain"]` in the [Catalog](#catalog-management) endpoint, this MUST be returned for a synchronous request or the Platform can consider the response invalid. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the "if" sentence is right since what you wrote now implies that if the "requires" is there then this field MUST be there which isn't true since it might not want to return one for this.
spec.md
Outdated
| credentials | object | A free-form hash of credentials that can be used by applications or users to access the service. MUST be returned for a synchronous request if the Service Broker supports generation of credentials. | | ||
| syslog_drain_url | string | A URL to which logs MUST be streamed. If the service declares `"requires":["syslog_drain"]` in the [Catalog](#catalog-management) endpoint, this MUST be returned for a synchronous request or the Platform can consider the response invalid. | | ||
| route_service_url | string | A URL to which the Platform MUST proxy requests for the address sent with `bind_resource.route` in the request body. If the service declares `"requires":["route_forwarding"]` in the [Catalog](#catalog-management) endpoint and `"bind_resource":{"route":"some-address.com"}` is included in the request, this MUST be returned for a synchronous request or the Platform can consider the response invalid. | | ||
| volume_mounts | array of [VolumeMount](#volume-mount-object) objects | An array of configuration for remote storage devices to be mounted into an application container filesystem. If the service declares `"requires":["volume_mount"]` in the [Catalog](#catalog-management) endpoint, this MUST be returned for a synchronous request or the Platform can consider the response invalid. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment as above, I don't think the "if" is worded correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all done
spec.md
Outdated
and this endpoint MUST be available immediately after the | ||
[Polling Last Operation for Service Bindings](#polling-last-operation-for-service-bindings) | ||
endpoint returns `"state": "succeeded"` for a [Binding](#binding) operation. | ||
Otherwise, Platforms SHOULD NOT attempt to call this endpoint under any |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not? Wouldn't they just get a 404 if its not ready/there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
6428a5c
to
d86744b
Compare
0e2a751
to
983ccfd
Compare
See issue #137
This depends on #333