Class: Proxy::DHCP::KeaApi::SubnetService
- Inherits:
-
SubnetService
- Object
- SubnetService
- Proxy::DHCP::KeaApi::SubnetService
- Includes:
- Log
- Defined in:
- lib/smart_proxy_dhcp_kea_api/dhcp_kea_api_subnet_service.rb
Overview
Manages the in-memory cache of DHCP data for the Kea provider.
This class is responsible for fetching all subnet, reservation, and lease information from the Kea API. It inherits from the core ‘DHCP::SubnetService` to get the underlying data structures (e.g. hashes for leases and hosts) and caching logic. Its primary public method, `load!`, orchestrates the population of this cache. It also maintains a mapping of Foreman subnet networks to their internal Kea API subnet IDs.
Defined Under Namespace
Classes: Staging
Constant Summary collapse
- OPTION_MAP =
Maps Kea option-data names to their Foreman option keys and whether they are lists.
{ 'routers' => { key: :routers, list: true }, 'domain-name-servers' => { key: :dns_servers, list: true }, 'domain-name' => { key: :domain_name, list: false }, 'ntp-servers' => { key: :ntp_servers, list: true } }.freeze
Instance Attribute Summary collapse
-
#kea_id_map ⇒ Object
readonly
A hash mapping a subnet network address (e.g. “192.168.1.0”) to its internal Kea API integer ID (e.g. 1).
-
#subnet_options ⇒ Object
readonly
A hash mapping a subnet network address to its DHCP options hash.
Instance Method Summary collapse
-
#all_hosts(subnet_address = nil) ⇒ Array<Proxy::DHCP::Reservation>
Returns all host reservations, refreshing the cache if stale.
-
#all_leases(subnet_address = nil) ⇒ Array<Proxy::DHCP::Lease>
Returns all leases, refreshing the cache if stale.
-
#all_subnets ⇒ Array<Proxy::DHCP::Subnet>
Returns all subnets, refreshing the cache if stale.
-
#initialize(client, leases_by_ip, leases_by_mac, reservations_by_ip, reservations_by_mac, reservations_by_name, cache_ttl: 60, managed_subnets: nil) ⇒ void
constructor
Initialises the SubnetService.
-
#load! ⇒ true
The main entry point for loading all DHCP data from the Kea server.
-
#load_leases_from_kea(staging) ⇒ void
Fetches all active leases from the Kea API for the subnets currently in the cache.
-
#load_reservations_from_database(staging) ⇒ void
Fetches dynamically added reservations from Kea’s hosts-database via ‘reservation-get-all`.
-
#load_subnets_and_reservations_from_kea(staging) ⇒ void
Fetches all subnets and their associated reservations from the Kea API.
Constructor Details
#initialize(client, leases_by_ip, leases_by_mac, reservations_by_ip, reservations_by_mac, reservations_by_name, cache_ttl: 60, managed_subnets: nil) ⇒ void
Initialises the SubnetService.
rubocop:disable Metrics/ParameterLists
65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/smart_proxy_dhcp_kea_api/dhcp_kea_api_subnet_service.rb', line 65 def initialize(client, leases_by_ip, leases_by_mac, reservations_by_ip, reservations_by_mac, reservations_by_name, cache_ttl: 60, managed_subnets: nil) @client = client @kea_id_map = {} @subnet_options = {} @cache_ttl = cache_ttl @loaded_at = nil @reload_mutex = Mutex.new @managed_subnets = parse_managed_subnets(managed_subnets) super(leases_by_ip, leases_by_mac, reservations_by_ip, reservations_by_mac, reservations_by_name) end |
Instance Attribute Details
#kea_id_map ⇒ Object (readonly)
A hash mapping a subnet network address (e.g. “192.168.1.0”) to its internal Kea API integer ID (e.g. 1). This is crucial for making API calls that require a ‘subnet-id`.
47 48 49 |
# File 'lib/smart_proxy_dhcp_kea_api/dhcp_kea_api_subnet_service.rb', line 47 def kea_id_map @kea_id_map end |
#subnet_options ⇒ Object (readonly)
A hash mapping a subnet network address to its DHCP options hash. Used by the Provider to serve subnet-level options back to Foreman.
51 52 53 |
# File 'lib/smart_proxy_dhcp_kea_api/dhcp_kea_api_subnet_service.rb', line 51 def @subnet_options end |
Instance Method Details
#all_hosts(subnet_address = nil) ⇒ Array<Proxy::DHCP::Reservation>
Returns all host reservations, refreshing the cache if stale.
116 117 118 119 |
# File 'lib/smart_proxy_dhcp_kea_api/dhcp_kea_api_subnet_service.rb', line 116 def all_hosts(subnet_address = nil) reload_if_stale! super end |
#all_leases(subnet_address = nil) ⇒ Array<Proxy::DHCP::Lease>
Returns all leases, refreshing the cache if stale.
125 126 127 128 |
# File 'lib/smart_proxy_dhcp_kea_api/dhcp_kea_api_subnet_service.rb', line 125 def all_leases(subnet_address = nil) reload_if_stale! super end |
#all_subnets ⇒ Array<Proxy::DHCP::Subnet>
Returns all subnets, refreshing the cache if stale.
107 108 109 110 |
# File 'lib/smart_proxy_dhcp_kea_api/dhcp_kea_api_subnet_service.rb', line 107 def all_subnets reload_if_stale! super end |
#load! ⇒ true
The main entry point for loading all DHCP data from the Kea server.
All Kea API calls populate a fresh, off-to-the-side set of stores (‘staging`); only once every fetch has succeeded are the new stores swapped into the live cache under the parent’s monitor. This keeps the slow network fetch off the live cache so concurrent readers never see a half-populated state, and leaves the previous cache intact if the fetch fails partway through.
rubocop:disable Naming/PredicateMethod
92 93 94 95 96 97 98 99 100 101 |
# File 'lib/smart_proxy_dhcp_kea_api/dhcp_kea_api_subnet_service.rb', line 92 def load! staging = Staging.new load_subnets_and_reservations_from_kea(staging) load_reservations_from_database(staging) load_leases_from_kea(staging) commit(staging) true end |
#load_leases_from_kea(staging) ⇒ void
This method returns an undefined value.
Fetches all active leases from the Kea API for the subnets currently in the cache.
187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/smart_proxy_dhcp_kea_api/dhcp_kea_api_subnet_service.rb', line 187 def load_leases_from_kea(staging) return if staging.kea_id_map.empty? response = @client.post_command('dhcp4', 'lease4-get-all', { subnets: staging.kea_id_map.values }) return unless response && response['leases'] response['leases'].each do |lease| process_lease(lease, staging) end rescue Proxy::DHCP::Error => e logger.error "Failed to load all leases from Kea: #{e.}" raise end |
#load_reservations_from_database(staging) ⇒ void
This method returns an undefined value.
Fetches dynamically added reservations from Kea’s hosts-database via ‘reservation-get-all`. These are not included in `config-get` which only returns static reservations from the config file.
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/smart_proxy_dhcp_kea_api/dhcp_kea_api_subnet_service.rb', line 160 def load_reservations_from_database(staging) return if staging.kea_id_map.empty? staging.kea_id_map.each do |network, subnet_id| response = @client.post_command('dhcp4', 'reservation-get-all', { 'subnet-id': subnet_id }) hosts = response&.[]('hosts') next unless hosts subnet_obj = staging.service.find_subnet(network) next unless subnet_obj hosts.each do |res_data| next if staging.service.find_host_by_mac(network, res_data['hw-address']) process_reservation(res_data, subnet_obj, staging) end end rescue Proxy::DHCP::Error => e logger.debug "reservation-get-all not available or failed: #{e.}" end |
#load_subnets_and_reservations_from_kea(staging) ⇒ void
This method returns an undefined value.
Fetches all subnets and their associated reservations from the Kea API. This single ‘config-get` call is the most efficient way to get all static configuration.
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/smart_proxy_dhcp_kea_api/dhcp_kea_api_subnet_service.rb', line 138 def load_subnets_and_reservations_from_kea(staging) config = @client.post_command('dhcp4', 'config-get') subnets_data = config&.dig('Dhcp4', 'subnet4') return unless subnets_data subnets_data.each do |subnet_data| process_subnet(subnet_data, staging) end rescue Proxy::DHCP::Error => e logger.error "Failed to load subnets and reservations from Kea: #{e.}" raise rescue IPAddr::InvalidAddressError => e logger.error "Failed to parse subnet from Kea, invalid address found: #{e.}" raise end |