Files
ubicloud/model/load_balancer.rb
Jeremy Evans e78a7bb897 Allow using ubid without location in the cli
For example:

```
ubi vm vmdzyppz6j166jh5e9t2dwrfas show
```

This adds an object-info api route under project that returns the type,
location, and name of a supported object (currently the objects supported
by the api).  If there is no slash in the object reference in the cli,
and the object reference is a supported ubid format, then assume the
object reference is a ubid, and have the cli use the object-info endpoint
to get the location, and if a location is returned, it then uses that
location for the request.

Fix the error message for invalid references to not include an
underscore for the ubid, and to separate the location/name and ubid
formats to make it apparent to the user that location is not needed for
ubid (it is still accepted, but we don't need to document that).

Add LoadBalancer#display_location to avoid having different code for
LoadBalancer.
2025-02-26 09:23:01 -08:00

140 lines
6.1 KiB
Ruby

# frozen_string_literal: true
require_relative "../model"
class LoadBalancer < Sequel::Model
many_to_one :project
many_to_many :vms
many_to_many :active_vms, class: :Vm, left_key: :load_balancer_id, right_key: :vm_id, join_table: :load_balancers_vms, conditions: {state: "up"}
many_to_many :vms_to_dns, class: :Vm, left_key: :load_balancer_id, right_key: :vm_id, join_table: :load_balancers_vms, conditions: Sequel.~(state: Sequel.any_type(["evacuating", "detaching"], :lb_node_state))
one_to_one :strand, key: :id
many_to_one :private_subnet
one_to_many :load_balancers_vms, key: :load_balancer_id, class: :LoadBalancersVms
many_to_many :certs, join_table: :certs_load_balancers, left_key: :load_balancer_id, right_key: :cert_id
one_to_many :certs_load_balancers, key: :load_balancer_id, class: :CertsLoadBalancers
many_to_one :custom_hostname_dns_zone, class: :DnsZone, key: :custom_hostname_dns_zone_id
plugin :association_dependencies, load_balancers_vms: :destroy, certs_load_balancers: :destroy
include ResourceMethods
include SemaphoreMethods
include ObjectTag::Cleanup
dataset_module Pagination
semaphore :destroy, :update_load_balancer, :rewrite_dns_records, :refresh_cert
def display_location
private_subnet.display_location
end
def path
"/location/#{private_subnet.display_location}/load-balancer/#{name}"
end
def add_vm(vm)
DB.transaction do
LoadBalancersVms.create_with_id(load_balancer_id: id, vm_id: vm.id)
Strand.create_with_id(prog: "Vnet::CertServer", label: "put_certificate", stack: [{subject_id: id, vm_id: vm.id}], parent_id: id)
incr_rewrite_dns_records
end
end
def detach_vm(vm)
load_balancers_vms_dataset.where(vm_id: vm.id, state: Sequel.any_type(["up", "down", "evacuating"], :lb_node_state)).update(state: "detaching")
Strand.create_with_id(prog: "Vnet::CertServer", label: "remove_cert_server", stack: [{subject_id: id, vm_id: vm.id}], parent_id: id)
incr_update_load_balancer
end
def evacuate_vm(vm)
DB.transaction do
load_balancers_vms_dataset.where(vm_id: vm.id, state: Sequel.any_type(["up", "down"], :lb_node_state)).update(state: "evacuating")
Strand.create_with_id(prog: "Vnet::CertServer", label: "remove_cert_server", stack: [{subject_id: id, vm_id: vm.id}], parent_id: id)
incr_update_load_balancer
incr_rewrite_dns_records
end
end
def remove_vm(vm)
load_balancers_vms_dataset[vm_id: vm.id].destroy
incr_rewrite_dns_records
end
def hostname
custom_hostname || "#{name}.#{private_subnet.ubid[-5...]}.#{Config.load_balancer_service_hostname}"
end
def dns_zone
custom_hostname_dns_zone || DnsZone[project_id: Config.load_balancer_service_project_id, name: Config.load_balancer_service_hostname]
end
def need_certificates?
return true if certs_dataset.empty?
certs_dataset.where { created_at > Time.now - 60 * 60 * 24 * 30 * 2 }.empty?
end
def active_cert
certs_dataset.where { created_at > Time.now - 60 * 60 * 24 * 30 * 3 }.order(Sequel.desc(:created_at)).first
end
def ipv4_enabled?
stack == Stack::IPV4 || stack == Stack::DUAL
end
def ipv6_enabled?
stack == Stack::IPV6 || stack == Stack::DUAL
end
def validate
super
validates_includes(%w[round_robin hash_based], :algorithm) if algorithm
validates_includes(%w[http https tcp], :health_check_protocol) if health_check_protocol
validates_includes(%w[dual ipv4 ipv6], :stack) if stack
end
module Stack
IPV4 = "ipv4"
IPV6 = "ipv6"
DUAL = "dual"
end
end
# Table: load_balancer
# Columns:
# id | uuid | PRIMARY KEY
# name | text | NOT NULL
# algorithm | lb_algorithm | NOT NULL DEFAULT 'round_robin'::lb_algorithm
# src_port | integer | NOT NULL
# dst_port | integer | NOT NULL
# private_subnet_id | uuid | NOT NULL
# health_check_endpoint | text | NOT NULL
# health_check_interval | integer | NOT NULL DEFAULT 10
# health_check_timeout | integer | NOT NULL DEFAULT 5
# health_check_up_threshold | integer | NOT NULL DEFAULT 5
# health_check_down_threshold | integer | NOT NULL DEFAULT 3
# health_check_protocol | lb_hc_protocol | NOT NULL DEFAULT 'http'::lb_hc_protocol
# custom_hostname | text |
# custom_hostname_dns_zone_id | uuid |
# stack | lb_stack | NOT NULL DEFAULT 'dual'::lb_stack
# project_id | uuid | NOT NULL
# Indexes:
# load_balancer_pkey | PRIMARY KEY btree (id)
# load_balancer_custom_hostname_key | UNIQUE btree (custom_hostname)
# load_balancer_private_subnet_id_name_uidx | UNIQUE btree (private_subnet_id, name)
# Check constraints:
# health_check_down_threshold_gt_0 | (health_check_down_threshold > 0)
# health_check_interval_gt_0 | (health_check_interval > 0)
# health_check_interval_lt_600 | (health_check_interval < 600)
# health_check_timeout_gt_0 | (health_check_timeout > 0)
# health_check_timeout_lt_health_check_interval | (health_check_timeout <= health_check_interval)
# health_check_up_threshold_gt_0 | (health_check_up_threshold > 0)
# Foreign key constraints:
# load_balancer_custom_hostname_dns_zone_id_fkey | (custom_hostname_dns_zone_id) REFERENCES dns_zone(id)
# load_balancer_private_subnet_id_fkey | (private_subnet_id) REFERENCES private_subnet(id)
# load_balancer_project_id_fkey | (project_id) REFERENCES project(id)
# Referenced By:
# certs_load_balancers | certs_load_balancers_load_balancer_id_fkey | (load_balancer_id) REFERENCES load_balancer(id)
# inference_endpoint | inference_endpoint_load_balancer_id_fkey | (load_balancer_id) REFERENCES load_balancer(id)
# kubernetes_cluster | kubernetes_cluster_api_server_lb_id_fkey | (api_server_lb_id) REFERENCES load_balancer(id)
# load_balancers_vms | load_balancers_vms_load_balancer_id_fkey | (load_balancer_id) REFERENCES load_balancer(id)