Files
ubicloud/routes/project/location/load_balancer.rb
Jeremy Evans d4bb9e8619 Allow access to objects in internal locations in web/api routes
However, do not allow creation of objects in internal locations
in web/api routes.

Show helpful error message if using an invalid location in the api.
This error message shows what the problem is, and the available
valid locations the user can use.
2025-03-25 11:48:42 -07:00

122 lines
3.7 KiB
Ruby

# frozen_string_literal: true
class Clover
hash_branch(:project_location_prefix, "load-balancer") do |r|
r.get api? do
load_balancer_list
end
r.on LOAD_BALANCER_NAME_OR_UBID do |lb_name, lb_id|
if lb_name
r.post api? do
check_visible_location
load_balancer_post(lb_name)
end
filter = {Sequel[:load_balancer][:name] => lb_name}
else
filter = {Sequel[:load_balancer][:id] => UBID.to_uuid(lb_id)}
end
filter[:private_subnet_id] = @project.private_subnets_dataset.where(location_id: @location.id).select(Sequel[:private_subnet][:id])
lb = LoadBalancer.first(filter)
next (r.delete? ? 204 : 404) unless lb
r.post %w[attach-vm detach-vm] do |action|
authorize("LoadBalancer:edit", lb.id)
required_parameters = %w[vm_id]
request_body_params = validate_request_params(required_parameters)
unless (vm = Vm.from_ubid(request_body_params["vm_id"]))
fail Validation::ValidationFailed.new("vm_id" => "VM not found")
end
authorize("Vm:view", vm.id)
if action == "attach-vm"
if vm.load_balancer
fail Validation::ValidationFailed.new("vm_id" => "VM is already attached to a load balancer")
end
lb.add_vm(vm)
actioned = "attached to"
else
lb.detach_vm(vm)
actioned = "detached from"
end
if api?
Serializers::LoadBalancer.serialize(lb, {detailed: true})
else
flash["notice"] = "VM is #{actioned} the load balancer"
r.redirect "#{@project.path}#{lb.path}"
end
end
r.get true do
authorize("LoadBalancer:view", lb.id)
@lb = Serializers::LoadBalancer.serialize(lb, {detailed: true, vms_serialized: !api?})
if api?
@lb
else
vms = dataset_authorize(lb.private_subnet.vms_dataset.eager(:location), "Vm:view").exclude(Sequel[:vm][:id] => lb.vms_dataset.select(Sequel[:vm][:id])).all
@attachable_vms = Serializers::Vm.serialize(vms)
view "networking/load_balancer/show"
end
end
r.delete true do
authorize("LoadBalancer:delete", lb.id)
lb.incr_destroy
204
end
r.patch api? do
authorize("LoadBalancer:edit", lb.id)
request_body_params = validate_request_params(%w[algorithm src_port dst_port health_check_endpoint vms])
DB.transaction do
lb.update(
algorithm: request_body_params["algorithm"],
health_check_endpoint: request_body_params["health_check_endpoint"]
)
lb.ports.first.update(src_port: Validation.validate_port(:src_port, request_body_params["src_port"]),
dst_port: Validation.validate_port(:dst_port, request_body_params["dst_port"]))
end
new_vms = request_body_params["vms"].map { Vm.from_ubid(_1.delete("\"")) }
new_vms.each do |vm|
unless vm
fail Validation::ValidationFailed.new("vms" => "VM not found")
end
authorize("Vm:view", vm.id)
if vm.load_balancer
next if vm.load_balancer.id == lb.id
fail Validation::ValidationFailed.new("vms" => "VM is already attached to a load balancer")
end
lb.add_vm(vm)
end
lb.vms.each do |vm|
next if new_vms.any? { _1.id == vm.id }
lb.evacuate_vm(vm)
lb.remove_vm(vm)
end
lb.incr_update_load_balancer
Serializers::LoadBalancer.serialize(lb.reload, {detailed: true})
end
end
# 204 response for invalid names
r.is String do |lb_name|
r.post { load_balancer_post(lb_name) }
r.delete do
204
end
end
end
end