app/actions/service_route_binding_create.rb
require 'services/service_brokers/service_client_provider'
require 'actions/metadata_update'
require 'actions/v3/service_binding_create'
module VCAP::CloudController
module V3
class ServiceRouteBindingCreate < V3::ServiceBindingCreate
def initialize(user_audit_info, audit_hash)
super()
@user_audit_info = user_audit_info
@audit_hash = audit_hash
@manifest_triggered = false
end
PERMITTED_BINDING_ATTRIBUTES = [:route_service_url].freeze
def precursor(service_instance, route, message:)
validate_service_instance!(service_instance, route)
binding = RouteBinding.first(service_instance:, route:)
validate_binding!(binding)
binding_details = {
service_instance:,
route:
}
RouteBinding.new.tap do |b|
RouteBinding.db.transaction do
binding.destroy if binding
b.save_with_attributes_and_new_operation(
binding_details,
CREATE_INITIAL_OPERATION
)
MetadataUpdate.update(b, message)
end
end
end
class RouteBindingAlreadyExists < StandardError; end
private
def event_repository
@event_repository ||= Repositories::ServiceGenericBindingEventRepository.new(
Repositories::ServiceGenericBindingEventRepository::SERVICE_ROUTE_BINDING
)
end
def validate_service_instance!(service_instance, route)
not_supported! unless service_instance.route_service?
not_bindable! unless service_instance.bindable?
route_is_internal! if route.try(:internal?)
space_mismatch! unless route.space == service_instance.space
already_bound! if route.service_instance && route.service_instance != service_instance
return unless service_instance.managed_instance?
service_instance_not_found! if service_instance.create_failed?
operation_in_progress! if service_instance.operation_in_progress?
end
def validate_binding!(binding)
return unless binding
already_exists! if binding.create_succeeded? || binding.create_in_progress?
incomplete_deletion! if binding.delete_failed? || binding.delete_in_progress?
end
def permitted_binding_attributes
PERMITTED_BINDING_ATTRIBUTES
end
def post_bind_action(binding)
binding.notify_diego
end
def route_is_internal!
raise UnprocessableCreate.new('Route services cannot be bound to internal routes')
end
def space_mismatch!
raise UnprocessableCreate.new('The service instance and the route are in different spaces')
end
def already_bound!
raise UnprocessableCreate.new('A route may only be bound to a single service instance')
end
def not_supported!
raise UnprocessableCreate.new('This service instance does not support route binding')
end
def not_bindable!
raise UnprocessableCreate.new('This service instance does not support binding')
end
def already_exists!
raise RouteBindingAlreadyExists.new('The route and service instance are already bound')
end
def incomplete_deletion!
raise UnprocessableCreate.new('The binding is getting deleted or its deletion failed')
end
end
end
end