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.
140 lines
6.1 KiB
Ruby
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)
|