-
Notifications
You must be signed in to change notification settings - Fork 84
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
Async bind feature #625
Async bind feature #625
Conversation
I will remove or cleanup some of the debug logging statements. They're still needed as I continue testing. |
Changes Unknown when pulling 6db4ec3 on async-bind into ** on master**. |
pkg/broker/binding_job.go
Outdated
// Run - run the binding job. | ||
func (p *BindingJob) Run(token string, msgBuffer chan<- JobMsg) { | ||
metrics.BindingJobStarted() | ||
var podName 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.
Probably don't need to declare extCreds
, podName
, and err
ahead of time because if apb.Bind(p.serviceInstance, p.params)
fails in anyway, these variables will still get set.
podName, extCreds, err := ...
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.
totally, I copied it from the broker.go where there was a conditional hence the variables being defined before hand. Will fix.
pkg/broker/binding_job.go
Outdated
var extCreds *apb.ExtractedCredentials | ||
var err error | ||
|
||
log.Debug("BJ: binding job started, calling apb.Bind") |
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.
Can you spell out Bind Job:
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 will for the statements I plan to keep. Thanks.
pkg/broker/broker.go
Outdated
@@ -769,8 +770,38 @@ func (a AnsibleBroker) isJobInProgress(instance *apb.ServiceInstance, | |||
return len(methodJobs) > 0, token, nil | |||
} | |||
|
|||
func (a AnsibleBroker) GetBind(instance apb.ServiceInstance, bindingUUID uuid.UUID) (*BindResponse, error) { | |||
|
|||
log.Debug("XXX entered GetBind") |
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 'XXX' suppose to be substituted for something? Or is this to log that "we're running GetBind"?
pkg/broker/broker.go
Outdated
|
||
log.Debug("XXX entered GetBind") | ||
|
||
// this might not be required |
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 like your honesty. Why might this not be required? Is this to verify that a provision has completed?
pkg/handler/handler.go
Outdated
var async bool | ||
|
||
// ignore the error, if async can't be parsed it will be false | ||
async, _ = strconv.ParseBool(r.FormValue("accepts_incomplete")) |
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.
Should we turn on accepts_incomplete
if LaunchApbOnBind
is enabled and accepts_incomplete
is not explicitly set to false? Also, should we have a warning if we have LaunchApbOnBind=true
and accepts_incomplete=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.
Yeah, I'll add a warning.
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.
Actually, accepts_incomplete
will be given to us from the service-catalog. We can not change its value once we get it since the caller needs to know how to monitor the last_operation
endpoint.
I will add a warning when LaunchApbOnBind=true
and accepts_incomplete=false
condition occurs. Worst case it means that during synchronous binds we WILL launch the apb, which COULD timeout.
@jmrodri nice work. Mostly nits. |
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 change that I think needs to happen
pkg/handler/handler.go
Outdated
si, err := h.broker.GetServiceInstance(instanceUUID) | ||
if err != nil { | ||
// return 404 or 422 | ||
log.Debugf("service instance %v", si) |
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 needs to return from here with the status code of 404 or 422
Changes Unknown when pulling 06af68d on async-bind into ** on master**. |
Changes Unknown when pulling 1a385b0 on async-bind into ** on master**. |
* async bind update * reformat comments
* update MockBroker to match new broker interface
* Update binding job to use JobMsg
|
bind.sh used in testing $ cat bind.sh
INSTANCE_ID=$1
BINDING_ID=$2
PLAN_UUID="7f4a5e35e4af2beb70076e72fab0b7ff"
SERVICE_UUID="dh-postgresql-apb-s964m"
req="{
\"plan_id\": \"$PLAN_UUID\",
\"service_id\": \"$SERVICE_UUID\",
\"context\": \"blog-project\",
\"app_guid\":\"\",
\"bind_resource\":{},
\"parameters\": {}
}"
curl \
-k \
-X PUT \
-H "Authorization: bearer $(oc whoami -t)" \
-H "Content-type: application/json" \
-H "Accept: application/json" \
-H "X-Broker-API-Originating-Identity: " \
-d "$req" \
"https://asb-1338-ansible-service-broker.172.17.0.1.nip.io/ansible-service-broker/v2/service_instances/$INSTANCE_ID/service_bindings/$BINDING_ID?accepts_incomplete=true" |
last_operation.sh used in testing $ cat last_operation.sh
INSTANCE_ID=$1
OPERATION=$2
PLAN_UUID="7f4a5e35e4af2beb70076e72fab0b7ff"
SERVICE_UUID="dh-postgresql-apb-s964m"
curl \
-k \
-X GET \
-H "Authorization: bearer $(oc whoami -t)" \
-H "Content-type: application/json" \
-H "Accept: application/json" \
-H "X-Broker-API-Originating-Identity: " \
"https://asb-1338-ansible-service-broker.172.17.0.1.nip.io/ansible-service-broker/v2/service_instances/$INSTANCE_ID/last_operation?operation=$OPERATION&service_id=$SERVICE_UUID&plan_id=$PLAN_UUID"
|
getbind.sh used in testing $ cat getbind.sh
INSTANCE_ID=$1
BINDING_ID=$2
PLAN_UUID="7f4a5e35e4af2beb70076e72fab0b7ff"
SERVICE_UUID="dh-postgresql-apb-s964m"
req="{
\"plan_id\": \"$PLAN_UUID\",
\"service_id\": \"$SERVICE_UUID\",
\"context\": \"blog-project\",
\"app_guid\":\"\",
\"bind_resource\":{},
\"parameters\": {}
}"
curl \
-k \
-X GET \
-H "Authorization: bearer $(oc whoami -t)" \
-H "Content-type: application/json" \
-H "Accept: application/json" \
-H "X-Broker-API-Originating-Identity: " \
"https://asb-1338-ansible-service-broker.172.17.0.1.nip.io/ansible-service-broker/v2/service_instances/$INSTANCE_ID/service_bindings/$BINDING_ID"
|
getinstance.sh used in testing $ cat getinstance.sh
INSTANCE_ID=$1
curl \
-k \
-X GET \
-H "Authorization: bearer $(oc whoami -t)" \
-H "Content-type: application/json" \
-H "Accept: application/json" \
-H "X-Broker-API-Originating-Identity: " \
"https://asb-1338-ansible-service-broker.172.17.0.1.nip.io/ansible-service-broker/v2/service_instances/$INSTANCE_ID"
|
Changes Unknown when pulling 0590138 on async-bind into ** on master**. |
Changes Unknown when pulling 0590138 on async-bind into ** on master**. |
Test setupI modified catasb dockerhub_org: jmrodri
asb_template_url: file:///home/jesusr/dev/src/github.com/openshift/ansible-service-broker/templates/deploy-ansible-service-broker.template.yaml
origin_image_tag: v3.9.0-alpha.0
broker_launch_apb_on_bind: true
broker_auto_escalate: true
broker_image_name: docker.io/jmrodri/origin-ansible-service-broker
broker_tag: "async"
local_oc_client: true I built my image as follows:
You should probably use your OWN organization or just use the image I already pushed up. |
TEST
Deploy PostgreSQL APB
Create async bind
|
Also consider testing the getters with different ids. Ones that don't exist, invalid ones to see how the broker responds. We are trying to avoid PANICs :) |
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.
nits but overall LGTM
pkg/broker/binding_subscriber.go
Outdated
Token: bmsg.JobToken, | ||
State: apb.StateFailed, | ||
Podname: bmsg.PodName, | ||
Method: apb.JobMethodBind, |
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 might need a follow-on PR to pass errors back when the last operation is called.
I don't think this needs to be solved in the PR, but want to make a note of it.
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
pkg/broker/unbinding_subscriber.go
Outdated
}) | ||
} else { | ||
json.Unmarshal([]byte(bmsg.Msg), &extCreds) | ||
b.dao.SetState(bmsg.InstanceUUID, apb.JobState{ |
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.
Might want to handle the errors here
pkg/broker/unbinding_subscriber.go
Outdated
Podname: bmsg.PodName, | ||
Method: apb.JobMethodBind, | ||
}) | ||
b.dao.SetExtractedCredentials(bmsg.BindingUUID, extCreds) |
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.
Especially want to handle the error if the setting of the extracted credentials fail
pkg/handler/handler.go
Outdated
@@ -219,6 +222,42 @@ func (h handler) catalog(w http.ResponseWriter, r *http.Request, params map[stri | |||
writeDefaultResponse(w, http.StatusOK, resp, err) | |||
} | |||
|
|||
func (h handler) getinstance(w http.ResponseWriter, r *http.Request, params map[string]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.
nit: getinstance
-> getInstance
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 it's ugly and isn't all lower like the others in handler :) I really wanted to use get_instance :)
pkg/handler/handler.go
Outdated
switch err { | ||
case broker.ErrorNotFound: | ||
log.Debug("handler: bind not found") | ||
writeResponse(w, http.StatusNotFound, broker.ErrorResponse{Description: err.Error()}) |
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.
need to return after the writeResponse
otherwise, you will get multiple writes to the response writer.
pkg/handler/handler.go
Outdated
log.Debug("handler: something went bad during the getbind") | ||
writeResponse(w, http.StatusBadRequest, broker.ErrorResponse{Description: err.Error()}) | ||
} | ||
} else { |
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 this should not be in an else block
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 needs to be in the else block otherwise we'll write TWO responses out. It's consistent with some of the other calls. Probably a better alternative would be to do a return after the writeResponse
in the if block.
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'll add a return and remove the else, I like that better.
unbind.sh script INSTANCE_ID=$1
BINDING_ID=$2
PLAN_UUID="7f4a5e35e4af2beb70076e72fab0b7ff"
curl \
-k \
-X DELETE \
-H "Authorization: bearer $(oc whoami -t)" \
-H "Content-type: application/json" \
-H "Accept: application/json" \
-H "X-Broker-API-Originating-Identity: " \
"https://asb-1338-ansible-service-broker.172.17.0.1.nip.io/ansible-service-broker/v2/service_instances/$INSTANCE_ID/service_bindings/$BINDING_ID?accepts_incomplete=true&plan_id=$PLAN_UUID"
|
Changes Unknown when pulling b2429ef on async-bind into ** on master**. |
Changes Unknown when pulling efd42b3 on async-bind into ** on master**. |
Changes Unknown when pulling 7e1592f on async-bind into ** on master**. |
The async bind feature is used to allow binds that need more time to execute than the 60 seconds response time allotted in the Open Service Broker API spec. Async bind will spawn a binding job and return the job token immediately. The catalog will use the last_operation to monitor the state of the running job until either successful completion or a failure.
There are no new dependencies for this feature.
There is a new binding_subscriber to monitor the JobMsgs sent from the new binding_job. The Bind method in the broker was updated to take in the async flag and determine if it should spawn an APB for bind or simply return what was already stored like it did before.
Another set of critical additions was the new getserviceinstance and getbind calls added to the handler. These are to implement the required getters for async bind, particularly the getbind. Prior to async bind, when bind was called we would return the credentials at the end of the request. Since it is now asynchronous, we return the job token as the operation, but we will need a way to get the bind that was created once the job is done.
Aysnc bind is gated by the LaunchApbOnBind broker configuration setting. This MUST be set to True for the async bind to even be an option. Also, accepts_incomplete=true must accompany all PUT requests on the bind endpoint for async to be used. Both of those conditions need to be satisfied before using the async feature.