Problem:
We are currently experiencing the problem that foreman-proxy suggests IP addresses as free that have a DNS record associated with the via Infoblox host object, but no DHCP object.
There is a somewhat large subset of systems in our datacenter that are not managed by Foreman (mainly legacy and Windows servers). Those usually do not have DHCP enabled on all of their interfaces, but have DNS entries in our Infoblox system.
I have by now found out that the proxy now tries to ping addresses before marking them as unused, but on some subnets that our Foreman server cannot ping to due to network restrictions, this does not protect us from ending up with duplicate IP usage.
Is there a way to prevent this behaviour and/or make the smartproxy check for host objects on that IP regardless of related DHCP objects?
Expected outcome:
No IPs are beeing assinged to multiple servers.
Foreman and Proxy versions:
1.20.3
Foreman and Proxy plugin versions:
rubygem-algebrick.noarch 0.7.3-4.el7
rubygem-dynflow.noarch 0.8.34-2.fm1_17.el7
rubygem-faraday.noarch 0.9.1-6.el7
rubygem-faraday_middleware.noarch 0.10.0-2.el7
rubygem-sequel.noarch 4.20.0-6.el7
rubygem-smart_proxy_dhcp_infoblox.noarch 0.0.13-1.fm1_18.el7
rubygem-smart_proxy_dynflow.noarch 0.2.1-1.el7
rubygem-smart_proxy_remote_execution_ssh.noarch 0.2.0-2.el7
tfm-rubygem-angular-rails-templates.noarch 1:1.0.2-4.el7
tfm-rubygem-bastion.noarch 6.1.16-1.fm1_20.el7
tfm-rubygem-deface.noarch 1.3.2-1.el7
tfm-rubygem-diffy.noarch 3.0.1-5.el7
tfm-rubygem-docker-api.noarch 1.28.0-4.el7
tfm-rubygem-foreman-tasks.noarch 0.14.3-1.fm1_20.el7
tfm-rubygem-foreman-tasks-core.noarch 0.2.5-2.fm1_20.el7
tfm-rubygem-foreman_docker.noarch 4.1.0-2.fm1_20.el7
tfm-rubygem-foreman_hooks.noarch 0.3.15-1.fm1_20.el7
tfm-rubygem-foreman_remote_execution.noarch 1.6.7-1.fm1_20.el7
tfm-rubygem-foreman_remote_execution_core.noarch 1.1.4-1.el7
tfm-rubygem-foreman_snapshot_management.noarch 1.5.1-1.fm1_20.el7
tfm-rubygem-foreman_templates.noarch 6.0.3-2.fm1_20.el7
tfm-rubygem-git.noarch 1.2.5-9.el7
tfm-rubygem-hammer_cli_foreman_bootdisk.noarch 0.1.3-7.el7
tfm-rubygem-hammer_cli_foreman_docker.noarch 0.0.4-4.el7
tfm-rubygem-hammer_cli_foreman_tasks.noarch 0.0.13-1.fm1_20.el7
tfm-rubygem-parse-cron.noarch 0.1.4-4.fm1_20.el7
tfm-rubygem-polyglot.noarch 0.3.5-2.el7
tfm-rubygem-rainbow.noarch 2.2.1-3.el7
tfm-rubygem-smart_proxy_dynflow_core.noarch 0.2.1-1.fm1_20.el7
tfm-rubygem-wicked.noarch 1.3.3-1.el7
Other relevant data:
I think we had a patch in place back in 1.15 that prevented that behaviour. I can not recall though and am unable (due to lack of ruby knowledge) to tell whether the patch file I found would solve my issue (or even work on the current plugin version). The coworker that wrote this patch left the company some time ago. For completions sake, here is the patch I could find, maybe someone will be able to tell me what that does
diff -Naur smart_proxy_dhcp_infoblox.orig/common_crud.rb smart_proxy_dhcp_infoblox/common_crud.rb
--- smart_proxy_dhcp_infoblox.orig/common_crud.rb 2017-02-21 13:28:11.362928366 +0100
+++ smart_proxy_dhcp_infoblox/common_crud.rb 2017-02-28 11:00:08.208631398 +0100
@@ -27,7 +27,7 @@
validate_mac(options[:mac])
raise(Proxy::DHCP::Error, "Must provide hostname") unless options[:hostname]
- build_host(options).post
+ build_host(options).put
# TODO: DELETE ME needed for testing on infoblox ipam express
#host.configure_for_dns = false
rescue Infoblox::Error => e
diff -Naur smart_proxy_dhcp_infoblox.orig/host_ipv4_address_crud.rb smart_proxy_dhcp_infoblox/host_ipv4_address_crud.rb
--- smart_proxy_dhcp_infoblox.orig/host_ipv4_address_crud.rb 2017-02-21 13:28:11.363928394 +0100
+++ smart_proxy_dhcp_infoblox/host_ipv4_address_crud.rb 2017-02-28 11:00:31.490276324 +0100
@@ -3,6 +3,7 @@
module ::Proxy::DHCP::Infoblox
class HostIpv4AddressCRUD < CommonCRUD
+ include ::Proxy::Log
def initialize(connection)
@memoized_host = nil
@memoized_condition = nil
@@ -45,9 +46,21 @@
end
def build_host(options)
- host = ::Infoblox::Host.new(:connection => @connection)
- host.name = options[:hostname]
- host_addr = host.add_ipv4addr(options[:ip]).last
+ logger.debug "in build_host"
+ logger.debug @connection.inspect
+ logger.debug options[:ip]
+ host = ::Infoblox::Host.find(@connection, 'ipv4addr' => options[:ip])
+ if host.empty?
+ logger.debug "in host.empty if"
+ host = ::Infoblox::Host.new(:connection => @connection)
+ host.name = options[:hostname]
+ host_addr = host.add_ipv4addr(options[:ip]).last
+ host.post
+ end
+ host = ::Infoblox::Host.find(@connection, 'ipv4addr' => options[:ip]).first
+ raise "Hostname #{options[:hostname]} does not match infoblox host record #{host.name}" unless host.name == options[:hostname]
+ logger.debug host.ipv4addrs.inspect
+ host_addr = host.ipv4addrs.find { |ip| ip.ipv4addr == options[:ip] }
host_addr.mac = options[:mac]
host_addr.configure_for_dhcp = true
host_addr.nextserver = options[:nextServer]