Class: Proxy::DHCP::KeaApi::Provider

Inherits:
Server
  • Object
show all
Defined in:
lib/smart_proxy_dhcp_kea_api/dhcp_kea_api_main.rb

Overview

The main provider class for the ‘dhcp_kea_api` module. This class inherits from the Foreman Smart Proxy’s core ‘DHCP::Server` and implements the Kea-specific logic for adding and deleting DHCP reservations and leases.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(subnet_service, client, free_ips) ⇒ Provider

Initialises the Kea API provider.

Parameters:

  • subnet_service (Proxy::DHCP::KeaApi::SubnetService)

    The service that manages the in-memory cache of DHCP data.

  • client (Proxy::DHCP::KeaApi::Client)

    The client for communicating with the Kea API.

  • free_ips (Proxy::DHCP::FreeIps)

    The service that tracks recently suggested IPs to prevent race conditions.



20
21
22
23
24
25
# File 'lib/smart_proxy_dhcp_kea_api/dhcp_kea_api_main.rb', line 20

def initialize(subnet_service, client, free_ips)
  @subnet_service = subnet_service
  @client = client
  subnet_service.load!
  super('localhost', nil, subnet_service, free_ips)
end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



13
14
15
# File 'lib/smart_proxy_dhcp_kea_api/dhcp_kea_api_main.rb', line 13

def client
  @client
end

#subnet_serviceObject (readonly)

Returns the value of attribute subnet_service.



13
14
15
# File 'lib/smart_proxy_dhcp_kea_api/dhcp_kea_api_main.rb', line 13

def subnet_service
  @subnet_service
end

Instance Method Details

#add_record(options = {}) ⇒ Proxy::DHCP::Reservation

Creates a new DHCP reservation in Kea.

Parameters:

  • options (Hash) (defaults to: {})

    A hash containing the details for the new reservation.

Returns:

  • (Proxy::DHCP::Reservation)

    The created reservation object.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/smart_proxy_dhcp_kea_api/dhcp_kea_api_main.rb', line 31

def add_record(options = {})
  logger.debug "DHCP options received from Foreman: #{options.inspect}"
  record = super

  reservation_args = build_base_reservation_args(record)
  add_boot_and_server_options(reservation_args, options)

  option_data = build_option_data(options)
  reservation_args['option-data'] = option_data unless option_data.empty?

  @client.post_command('dhcp4', 'reservation-add', { reservation: reservation_args })
  begin
    subnet_service.add_host(record.subnet.network, record)
  rescue StandardError => e
    logger.error "Cache update failed after successful reservation-add for MAC #{record.mac}. " \
                 "Kea and cache are out of sync: #{e.message}"
    raise
  end

  logger.info "Successfully added reservation for MAC #{record.mac} and IP #{record.ip}"
  record
end

#del_record(record) ⇒ Proxy::DHCP::Record

Deletes a DHCP record from Kea. Handles both reservations and leases.

Parameters:

  • record (Proxy::DHCP::Reservation, Proxy::DHCP::Lease)

    The record to be deleted.

Returns:

  • (Proxy::DHCP::Record)

    The object that was successfully deleted.

Raises:

  • (Proxy::DHCP::Error)

    if the record type is unsupported, the corresponding Kea subnet-id cannot be found, or the API call fails.



60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/smart_proxy_dhcp_kea_api/dhcp_kea_api_main.rb', line 60

def del_record(record)
  logger.debug "Deleting record: #{record.inspect}"

  if record.is_a?(::Proxy::DHCP::Reservation)
    del_reservation(record)
  elsif record.is_a?(::Proxy::DHCP::Lease)
    del_lease(record)
  else
    raise Proxy::DHCP::Error, "Cannot delete unsupported record type: #{record.class.name}"
  end

  record
end

#load_subnet_options(subnet) ⇒ void

This method returns an undefined value.

Loads subnet-level DHCP options from the cached Kea configuration.

Parameters:

  • subnet (Proxy::DHCP::Subnet)

    The subnet to load options for.



78
79
80
81
82
83
84
# File 'lib/smart_proxy_dhcp_kea_api/dhcp_kea_api_main.rb', line 78

def load_subnet_options(subnet)
  opts = @subnet_service.subnet_options[subnet.network]
  return unless opts

  apply_boot_subnet_options(subnet, opts)
  apply_mapped_subnet_options(subnet, opts)
end