in pkg/broker/api.go [459:555]
func (b *AwsBroker) Unbind(request *osb.UnbindRequest, c *broker.RequestContext) (*broker.UnbindResponse, error) {
glog.V(10).Infof("request=%+v", *request)
// Get the binding
binding, err := b.db.DataStorePort.GetServiceBinding(request.BindingID)
if err != nil {
desc := fmt.Sprintf("Failed to get the service binding %s: %v", request.BindingID, err)
return nil, newHTTPStatusCodeError(http.StatusInternalServerError, "", desc)
} else if binding == nil {
desc := fmt.Sprintf("The service binding %s was not found.", request.BindingID)
return nil, newHTTPStatusCodeError(http.StatusGone, "", desc)
}
service, err := b.db.DataStorePort.GetServiceDefinition(request.ServiceID)
if err != nil {
desc := fmt.Sprintf("Failed to get the service %s: %v", request.ServiceID, err)
return nil, newHTTPStatusCodeError(http.StatusInternalServerError, "", desc)
} else if service == nil {
desc := fmt.Sprintf("The service %s was not found.", request.ServiceID)
return nil, newHTTPStatusCodeError(http.StatusBadRequest, "", desc)
}
// Get the instance
instance, err := b.db.DataStorePort.GetServiceInstance(binding.InstanceID)
if err != nil {
desc := fmt.Sprintf("Failed to get the service instance %s: %v", binding.InstanceID, err)
return nil, newHTTPStatusCodeError(http.StatusInternalServerError, "", desc)
} else if instance == nil {
desc := fmt.Sprintf("The service instance %s was not found.", binding.InstanceID)
return nil, newHTTPStatusCodeError(http.StatusBadRequest, "", desc)
}
sess := b.GetSession(b.keyid, b.secretkey, b.region, b.accountId, b.profile, instance.Params)
if bindViaLambda(service) {
// Get the CFN stack outputs
resp, err := b.Clients.NewCfn(sess).Client.DescribeStacks(&cloudformation.DescribeStacksInput{
StackName: aws.String(instance.StackID),
})
if err != nil {
desc := fmt.Sprintf("Failed to describe the CloudFormation stack %s: %v", instance.StackID, err)
return nil, newHTTPStatusCodeError(http.StatusInternalServerError, "", desc)
}
// Get the credentials from the CFN stack outputs
credentials, err := getCredentials(service, resp.Stacks[0].Outputs, b.Clients.NewSsm(sess))
if err != nil {
desc := fmt.Sprintf("Failed to get the credentials from CloudFormation stack %s: %v", instance.StackID, err)
return nil, newHTTPStatusCodeError(http.StatusInternalServerError, "", desc)
}
// Copy in the instance and binding IDs because we can
// use this as a stable reference to uniquely identify
// dynamically created resources (for exmaple, you can
// use these in the Path prefix of an IAM User).
credentials["INSTANCE_ID"] = binding.InstanceID
credentials["BINDING_ID"] = binding.ID
_, err = invokeLambdaBindFunc(sess, b.Clients.NewLambda, credentials, "unbind")
if err != nil {
desc := fmt.Sprintf("Error running lambda function for unbind from: %vo", err)
return nil, newHTTPStatusCodeError(http.StatusInternalServerError, "", desc)
}
}
if binding.PolicyArn != "" {
// Detach the scoped policy from the role
_, err = b.Clients.NewIam(sess).DetachRolePolicy(&iam.DetachRolePolicyInput{
PolicyArn: aws.String(binding.PolicyArn),
RoleName: aws.String(binding.RoleName),
})
if err != nil {
if aerr, ok := err.(awserr.Error); ok && aerr.Code() == iam.ErrCodeNoSuchEntityException {
glog.Infof("The policy %s was already detached from role %s.", binding.PolicyArn, binding.RoleName)
} else {
desc := fmt.Sprintf("Failed to detach the policy %s from role %s: %v", binding.PolicyArn, binding.RoleName, err)
return nil, newHTTPStatusCodeError(http.StatusInternalServerError, "", desc)
}
}
}
// Delete the binding
err = b.db.DataStorePort.DeleteServiceBinding(binding.ID)
if err != nil {
desc := fmt.Sprintf("Failed to delete the service binding %s: %v", binding.ID, err)
return nil, newHTTPStatusCodeError(http.StatusInternalServerError, "", desc)
}
b.metrics.Actions.With(
prom.Labels{
"action": "unbind",
"service": service.Name,
"plan": "",
}).Inc()
return &broker.UnbindResponse{}, nil
}