smart_proxy_dhcp_infoblox 0.0.5 → 0.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 1f93a00fc3b3226cd13507406635a76d39fdf5bf
4
- data.tar.gz: 2af103b766051daba129f8a05918f704692f7362
2
+ SHA256:
3
+ metadata.gz: 644a754d3e910db7479ae0a9bb5329dcb9c690af8c25ce1eba5a92425855f397
4
+ data.tar.gz: cb1a382785eb1accea703a945b187aa83cb74184ca06194829969d1d33b915a5
5
5
  SHA512:
6
- metadata.gz: 629785c6c921e5a356af8ab70703bc13d9db487dc3b4cdc2fb24ab1ff320d620e67b6762ff557a400cc1a77b4a73e7d7817c07591160e6d3de4011cf65abef48
7
- data.tar.gz: 442344c94cb0cf17e7e8915139149be7f50c545d771e570dcc7ae921c8ae98649a2f207c72e2c91c66bfdfc655fe73ab8b1b3a9ff1191c7ed2ecf470a4118fb7
6
+ metadata.gz: 07c4763058d119b947ff381d9977090aebd9365d556ad9ca61ede8e85f2f5191b214a4d6254ea042730cf85893df69c3040d67d7c91309148fdddc44946c6b6f
7
+ data.tar.gz: 1ab4070a4260f0e97ee442c50fb3e7eccf92c44b5afc75484ef300cfb222b8d536d21815475fdabd555ddabd6c05d12795f588e980100a796c5ccc0b52fea3c3
data/README.md CHANGED
@@ -9,6 +9,19 @@ for how to install Smart Proxy plugins
9
9
 
10
10
  This plugin is compatible with Smart Proxy 1.11 or higher.
11
11
 
12
+ Example installation command via foreman-installer:
13
+
14
+ ```
15
+ # foreman-installer --enable-foreman-proxy-plugin-dhcp-infoblox \
16
+ --foreman-proxy-dhcp-provider infoblox \
17
+ --foreman-proxy-plugin-dhcp-infoblox-record-type host \
18
+ --foreman-proxy-dhcp-server 192.168.201.2 \
19
+ --foreman-proxy-plugin-dhcp-infoblox-username admin \
20
+ --foreman-proxy-plugin-dhcp-infoblox-password infoblox \
21
+ --foreman-proxy-plugin-dhcp-infoblox-network-view default \
22
+ --foreman-proxy-plugin-dhcp-infoblox-dns-view default
23
+ ```
24
+
12
25
  When installing using "gem", make sure to install the bundle file:
13
26
 
14
27
  echo "gem 'smart_proxy_dhcp_infoblox'" > /usr/share/foreman-proxy/bundler.d/dhcp_infoblox.rb
@@ -24,15 +37,57 @@ To enable this DHCP provider, edit `/etc/foreman-proxy/settings.d/dhcp.yml` and
24
37
  Configuration options for this plugin are in `/etc/foreman-proxy/settings.d/dhcp_infoblox.yml` and include:
25
38
 
26
39
  * username: API Username
27
- * passowrd: API Password
40
+ * password: API Password
28
41
  * record_type: host / fixedaddress (see different record types chapter)
29
- * use_range: use infoblox ranges (true) or infoblox networks (false) to find the next free ip in your infoblox
42
+ * used_ips_search_type: record_type / used
30
43
 
31
44
  ## Different record types
32
45
  The main difference between host and fixedaddress is that a host record already includes the dns records. It's an infoblox object that includes dhcp/a record/ptr records. If you use the host objects there is no need to use a dns smart proxy. Everything gets handled inside the dhcp smart proxy. This does however limit functionality. You can't delete conflicting records or you can't change dns names using foreman gui. Beware when editing host objects manually in infoblox, once you delete a host in foreman all associated host objects get deleted.
33
46
 
34
47
  If you chose to use fixedaddress you'll need to use the infoblox dns smart proxy (https://github.com/theforeman/smart_proxy_dns_infoblox) if you want to manage dns records.
35
48
 
49
+ ## Used IP search type
50
+ When using "record_type" here, used IPs will be looked up among the record type you select on the record_type setting (host or fixedaddress). So everything which is not a host or a fixedaddress (depending on the setting), will be defined as free and can be selected as an IP to provision a host.
51
+ If the IP is used by just a DNS A entry for example, this can lead to conflicts. If "used" is set here, any usage of an IP will mark it as used and the IP will not be selected as free ip to provision a host.
52
+ Usages without a mac address will get a dummy mac address ("00:00:00:00:00:00"), when Foreman looks for "all_hosts".
53
+
54
+ ## SSL
55
+
56
+ The plugin enforces HTTPS server certificate verification. Follow a standard CA cert installation procedure for your operating system. It's possible to either download the server certificate from Infoblox web UI or use openssl command to extract it from server response. Here are example steps for Red Hat compatible systems:
57
+
58
+ ```
59
+ # update-ca-trust enable
60
+ # openssl s_client -showcerts -connect 192.168.201.2:443 </dev/null | openssl x509 -text >/etc/pki/ca-trust/source/anchors/infoblox.crt
61
+ # update-ca-trust extract
62
+ ```
63
+
64
+ For Debian-compatible systems:
65
+
66
+ ```
67
+ # openssl s_client -showcerts -connect 192.168.201.2:443 </dev/null | openssl x509 -text >/usr/local/share/ca-certificates/infoblox.crt
68
+ # update-ca-certificates
69
+ ```
70
+
71
+ To test the CA certificate, a simple curl query can be used. This is a positive test:
72
+
73
+ ```
74
+ # curl -u admin:infoblox https://192.168.201.2/wapi/v2.0/network
75
+ [
76
+ {
77
+ "_ref": "network/ZG5zLm5ldHdvcmskMTkyLjE2OC4yMDIuMC8yNC8w:192.168.202.0/24/default",
78
+ "network": "192.168.202.0/24",
79
+ "network_view": "default"
80
+ }
81
+ ]
82
+ ```
83
+
84
+ And a negative one:
85
+
86
+ ```
87
+ # curl -u admin:infoblox https://192.168.201.2/wapi/v2.0/network
88
+ curl: (60) SSL certificate problem: self signed certificate
89
+ ```
90
+
36
91
  ## Contributing
37
92
 
38
93
  Fork and send a Pull Request. Thanks!
@@ -1,17 +1,38 @@
1
1
  ---
2
- #
3
2
  # Configuration file for 'dhcp_infoblox' dhcp provider
4
3
  #
5
- # use :server setting in dhcp.yml if you are managing a dhcp server which is not localhost
6
- # use :subnets setting in dhcp.yml if you want to restrict subnets available to smart-proxy
7
- #
8
- :username: "infoblox"
4
+ # Use :server setting in dhcp.yml if you are managing a dhcp server which is not localhost.
5
+ # Use :subnets setting in dhcp.yml if you want to restrict subnets available to smart-proxy.
6
+
7
+ # Credentials for Infoblox API, make sure the DHCP Role is assigned
8
+ :username: "admin"
9
9
  :password: "infoblox"
10
- #
11
- # Record type to manage: can be "host" or "fixed_address"
12
- #
13
- :record_type: 'host'
14
- #
15
- # Use pre-definded ranges in networks to find available IP's
16
- #
17
- :use_ranges: false
10
+
11
+ # Record type to manage: can be "host" or "fixedaddress". The latter is recommended as
12
+ # "host" setting will cause conflicts when using Infoblox DNS smart proxy plugin. When
13
+ # using "host" setting make sure domain exists in Infoblox.
14
+ :record_type: 'fixedaddress'
15
+
16
+ # Search type used when looking for used IPs: can be "record_type" or "used". The latter can be used when you want to include all "USED"
17
+ # IPs in the search for used IPs, so that only really "UNUSED" (no Host, no DNS object, no DHCP Range, not unmanaged, etc.) are used, when
18
+ # searching for a unused IP. Defaults to "record_type", which uses the record_type selected above to look for used IPs.
19
+ #:used_ips_search_type: 'record_type'
20
+
21
+ # View used for fixedaddress record type.
22
+ #:network_view: 'default'
23
+
24
+ # View used for host record type, usually 'default.myview' for custom names.
25
+ #:dns_view: 'default'
26
+
27
+ # Number of seconds to wait after successful Grid restart (make sure to increase Foreman and CLI timeouts).
28
+ # Set to 0 to disable the delay.
29
+ #:wait_after_restart: 10
30
+
31
+ # DHCP custom options (name, num, value and vendor_class). Set to blank to ignore.
32
+ # This is only used for 'fixedaddress' record types.
33
+ #:options:
34
+ #-
35
+ #name: "DHCP option name"
36
+ #num: 1234
37
+ #value: "A value"
38
+ #vendor_class: "A vendor class"
@@ -1,5 +1,6 @@
1
1
  require 'resolv'
2
2
  require 'smart_proxy_dhcp_infoblox/ip_address_arithmetic'
3
+ require 'smart_proxy_dhcp_infoblox/network_address_range_regex_generator'
3
4
  require "proxy/validations"
4
5
 
5
6
  module ::Proxy::DHCP::Infoblox
@@ -9,16 +10,33 @@ module ::Proxy::DHCP::Infoblox
9
10
 
10
11
  attr_reader :connection
11
12
 
12
- def initialize(connection)
13
+ def initialize(connection, used_ips_search_type)
13
14
  @connection = connection
15
+ @used_ips_search_type = used_ips_search_type
14
16
  end
15
17
 
16
- def all_leases(network_address)
17
- [] # infoblox doesn't support leases
18
+ def all_leases(network_address, subnet)
19
+ address_range_regex = NetworkAddressesRegularExpressionGenerator.new.generate_regex(network_address)
20
+ ::Infoblox::Lease.find(@connection, 'address~' => address_range_regex).map do |lease|
21
+ # Infoblox can return MAC address set to nil
22
+ next unless lease.hardware
23
+
24
+ Proxy::DHCP::Lease.new(
25
+ lease.client_hostname,
26
+ lease.address,
27
+ lease.hardware,
28
+ subnet,
29
+ lease.starts,
30
+ lease.ends,
31
+ lease.binding_state,
32
+ :hostname => lease.client_hostname
33
+ )
34
+ end.compact
18
35
  end
19
36
 
20
37
  def find_record(subnet_address, an_address)
21
38
  return find_record_by_ip(subnet_address, an_address) if Resolv::IPv4::Regex =~ an_address
39
+
22
40
  find_record_by_mac(subnet_address, an_address)
23
41
  end
24
42
 
@@ -43,14 +61,33 @@ module ::Proxy::DHCP::Infoblox
43
61
  if options[:mac] != existing_host.mac || options[:hostname] != existing_name
44
62
  raise Proxy::DHCP::Collision, "Record #{options[:ip]} conflicts with an existing record."
45
63
  end
64
+
46
65
  raise Proxy::DHCP::AlreadyExists, "Record #{options[:ip]} already exists."
47
66
  end
48
67
 
49
68
  def del_record(_, record)
50
69
  raise InvalidRecord, "#{record} is static - unable to delete" unless record.deleteable?
51
- found = find_host('ipv4addr' => record.ip)
70
+
71
+ found = find_hosts('ipv4addr' => record.ip).first
52
72
  return if found.nil?
73
+
74
+ found.delete
75
+ end
76
+
77
+ def del_records_by_ip(ip_address)
78
+ found = find_hosts({ 'ipv4addr' => ip_address }, 2147483646)
79
+ return if found.empty?
80
+
81
+ found.each { |record| record.delete }
82
+ nil
83
+ end
84
+
85
+ def del_record_by_mac(mac_address)
86
+ found = find_hosts('mac' => mac_address).first
87
+ return if found.nil?
88
+
53
89
  found.delete
90
+ nil
54
91
  end
55
92
 
56
93
  def build_reservation(name, host, full_subnet_address)
@@ -60,16 +97,16 @@ module ::Proxy::DHCP::Infoblox
60
97
  return nil if host.mac.nil? || host.mac.empty?
61
98
 
62
99
  opts = { :hostname => name }
63
- opts[:mac] = host.mac
64
- opts[:ip] = host.ipv4addr
65
100
  opts[:deleteable] = true
66
- # TODO: nextserver, use_nextserver, bootfile, and use_bootfile attrs exist but are not available in the Fixedaddress model
101
+ # TODO: nextserver, use_nextserver, bootfile, and use_bootfile attrs exist
102
+ # but are not available in the Fixedaddress model
67
103
  # Might be useful to extend the model to include these
68
104
  opts[:nextServer] = host.nextserver if (host.respond_to?(:use_nextserver) && host.use_nextserver)
69
105
  opts[:filename] = host.bootfile if (host.respond_to?(:use_bootfile) && host.use_bootfile)
70
- opts[:subnet] = ::Proxy::DHCP::Subnet.new(full_subnet_address.split('/').first, cidr_to_ip_mask(cidr_to_i(full_subnet_address.split('/').last)))
106
+ subnet = ::Proxy::DHCP::Subnet.new(full_subnet_address.split('/').first,
107
+ cidr_to_ip_mask(cidr_to_i(full_subnet_address.split('/').last)))
71
108
 
72
- Proxy::DHCP::Reservation.new(opts)
109
+ Proxy::DHCP::Reservation.new(name, host.ipv4addr, host.mac, subnet, opts)
73
110
  end
74
111
  end
75
112
  end
@@ -7,19 +7,17 @@ module Proxy::DHCP::Infoblox
7
7
  include Proxy::Util
8
8
  include IpAddressArithmetic
9
9
 
10
- attr_reader :connection, :crud, :restart_grid, :unused_ips
10
+ attr_reader :connection, :crud, :restart_grid, :network_view
11
11
 
12
- def initialize(connection, crud, restart_grid, unused_ips, managed_subnets)
12
+ def initialize(connection, crud, restart_grid, unused_ips, managed_subnets, network_view)
13
13
  @connection = connection
14
14
  @crud = crud
15
15
  @restart_grid = restart_grid
16
- @unused_ips = unused_ips
17
- super('infoblox', managed_subnets, nil)
16
+ @network_view = network_view
17
+ super('infoblox', managed_subnets, nil, unused_ips)
18
18
  end
19
19
 
20
- def find_subnet(address);::Proxy::DHCP::Subnet.new(address, '255.255.255.0'); end
21
- def load_subnets; end
22
- def load_subnet_data(_); end
20
+ def find_subnet(address); ::Proxy::DHCP::Subnet.new(address, '255.255.255.0'); end
23
21
 
24
22
  def subnets
25
23
  ::Infoblox::Network.all(connection).map do |network|
@@ -34,32 +32,68 @@ module Proxy::DHCP::Infoblox
34
32
  end
35
33
 
36
34
  def all_leases(network_address)
37
- crud.all_leases(full_network_address(network_address))
35
+ crud.all_leases(full_network_address(network_address), find_subnet(network_address))
38
36
  end
39
37
 
40
38
  def find_record(subnet_address, an_address)
41
39
  crud.find_record(full_network_address(subnet_address), an_address)
42
40
  end
43
41
 
42
+ def find_record_by_mac(subnet_address, mac_address)
43
+ crud.find_record_by_mac(full_network_address(subnet_address), mac_address)
44
+ end
45
+
46
+ def find_records_by_ip(subnet_address, ip_address)
47
+ crud.find_records_by_ip(full_network_address(subnet_address), ip_address)
48
+ end
49
+
44
50
  def add_record(options)
45
51
  crud.add_record(options)
46
52
  logger.debug("Added DHCP reservation for #{options[:ip]}/#{options[:mac]}")
47
53
  restart_grid.try_restart
48
54
  end
49
55
 
50
- def del_record(subnet, record)
51
- crud.del_record(full_network_address(subnet.network), record)
56
+ def del_record(record)
57
+ crud.del_record(full_network_address(record.subnet_address), record)
52
58
  logger.debug("Removed DHCP reservation for #{record.ip} => #{record}")
53
59
  restart_grid.try_restart
54
60
  end
55
61
 
56
- def unused_ip(subnet, _, from_ip_address, to_ip_address)
57
- unused_ips.unused_ip(subnet.network, from_ip_address, to_ip_address)
62
+ def del_record_by_mac(_, mac_address)
63
+ crud.del_record_by_mac(mac_address)
64
+ logger.debug("Removed DHCP reservation for #{mac_address}")
65
+ restart_grid.try_restart
66
+ end
67
+
68
+ def del_records_by_ip(_, ip_address)
69
+ crud.del_records_by_ip(ip_address)
70
+ logger.debug("Removed DHCP reservation(s) for #{ip_address}")
71
+ restart_grid.try_restart
72
+ end
73
+
74
+ require 'dhcp_common/subnet'
75
+ def get_subnet(subnet_address)
76
+ address, prefix_length = full_network_address(subnet_address).split("/")
77
+ netmask = cidr_to_ip_mask(prefix_length.to_i)
78
+ ::Proxy::DHCP::Subnet.new(address, netmask)
79
+ end
80
+
81
+ def find_ip_by_mac_address_and_range(subnet, mac_address, from_address, to_address)
82
+ r = crud.find_record_by_mac("#{subnet.network}/#{subnet.cidr}", mac_address)
83
+
84
+ if r && (IPAddr.new(from_address)..IPAddr.new(to_address)).cover?(IPAddr.new(r.ip))
85
+ logger.debug "Found an existing DHCP record #{r}, reusing..."
86
+ return r.ip
87
+ end
88
+
89
+ nil
58
90
  end
59
91
 
60
92
  def find_network(network_address)
61
- network = ::Infoblox::Network.find(connection, 'network~' => network_address, '_max_results' => 1).first
62
- raise "Subnet #{network_address} not found" if network.nil?
93
+ network = ::Infoblox::Network.find(connection, 'network' => network_address, 'network_view' => network_view,
94
+ '_max_results' => 1).first
95
+ raise "Subnet #{network_address} not found in network view #{network_view}" if network.nil?
96
+
63
97
  network
64
98
  end
65
99
 
@@ -2,15 +2,24 @@ module Proxy::DHCP::Infoblox
2
2
  class Plugin < ::Proxy::Provider
3
3
  plugin :dhcp_infoblox, ::Proxy::DHCP::Infoblox::VERSION
4
4
 
5
- default_settings :record_type => 'host', :range => false
5
+ default_settings :record_type => 'fixedaddress',
6
+ :used_ips_search_type => "record_type",
7
+ :dns_view => "default",
8
+ :network_view => "default",
9
+ :blacklist_duration_minutes => 30 * 60,
10
+ :wait_after_restart => 10,
11
+ :options => []
12
+
6
13
  validate_presence :username, :password
7
14
 
8
- requires :dhcp, '>= 1.13'
15
+ requires :dhcp, '>= 3.2'
9
16
 
10
17
  load_classes ::Proxy::DHCP::Infoblox::PluginConfiguration
11
- load_validators :record_type_validator => ::Proxy::DHCP::Infoblox::RecordTypeValidator
12
18
  load_dependency_injection_wirings ::Proxy::DHCP::Infoblox::PluginConfiguration
13
19
 
14
- validate :record_type, :record_type_validator => true
20
+ validate :record_type, enum: %w[host fixedaddress]
21
+ validate :used_ips_search_type, enum: %w[record_type used]
22
+
23
+ start_services :unused_ips
15
24
  end
16
25
  end
@@ -1,7 +1,7 @@
1
1
  module Proxy
2
2
  module DHCP
3
3
  module Infoblox
4
- VERSION = '0.0.5'
4
+ VERSION = '0.0.18'.freeze
5
5
  end
6
6
  end
7
7
  end
@@ -1,39 +1,80 @@
1
+ require 'yaml'
1
2
  require 'smart_proxy_dhcp_infoblox/common_crud'
2
3
 
3
4
  module ::Proxy::DHCP::Infoblox
4
5
  class FixedAddressCRUD < CommonCRUD
5
- def initialize(connection)
6
- @memoized_host = nil
6
+ attr_reader :network_view
7
+
8
+ def initialize(connection, network_view, used_ips_search_type)
9
+ @memoized_hosts = []
7
10
  @memoized_condition = nil
8
- super
11
+ @network_view = network_view
12
+ super(connection, used_ips_search_type)
9
13
  end
10
14
 
11
15
  def all_hosts(subnet_address)
12
- network = ::Infoblox::Fixedaddress.find(@connection, 'network' => subnet_address, '_max_results' => 2147483646) #2**(32-cidr_to_i(subnet_address)))
13
- network.map {|h| build_reservation(h.name, h, subnet_address)}.compact
16
+ if @used_ips_search_type == 'used'
17
+ addresses = ::Infoblox::Ipv4address.find(
18
+ @connection,
19
+ 'network' => subnet_address,
20
+ 'status' => 'USED',
21
+ '_max_results' => 2147483646)
22
+ network = addresses.map do |address|
23
+ if address.mac_address.nil? || address.mac_address.empty?
24
+ checked_mac = '00:00:00:00:00:00'
25
+ else
26
+ checked_mac = address.mac_address
27
+ end
28
+ ::Infoblox::Fixedaddress.new(
29
+ :name => address.names[0],
30
+ :ipv4addr => address.ip_address,
31
+ :mac => checked_mac
32
+ )
33
+ end
34
+ else
35
+ network = ::Infoblox::Fixedaddress.find(
36
+ @connection,
37
+ 'network' => subnet_address,
38
+ 'network_view' => network_view,
39
+ '_max_results' => 2147483646) #2**(32-cidr_to_i(subnet_address)))
40
+ end
41
+
42
+ network.map { |h| build_reservation(h.name, h, subnet_address) }.compact
14
43
  end
15
44
 
16
45
  def find_record_by_ip(subnet_address, ip_address)
17
- found = find_host('ipv4addr' => ip_address)
46
+ found = find_hosts('ipv4addr' => ip_address).first
18
47
  return nil if found.nil?
48
+
19
49
  build_reservation(found.name, found, subnet_address)
20
50
  end
21
51
 
52
+ def find_records_by_ip(subnet_address, ip_address)
53
+ found = find_hosts({ 'ipv4addr' => ip_address }, 2147483646)
54
+ return [] if found.empty?
55
+
56
+ to_return = found.map { |record| build_reservation(record.name, record, subnet_address) }
57
+ to_return.compact
58
+ end
59
+
22
60
  def find_record_by_mac(subnet_address, mac_address)
23
- found = find_host('mac' => mac_address)
61
+ found = find_hosts('mac' => mac_address).first
24
62
  return nil if found.nil?
63
+
25
64
  build_reservation(found.name, found, subnet_address)
26
65
  end
27
66
 
28
- def find_host(condition)
29
- return @memoized_host if (!@memoized_host.nil? && @memoized_condition == condition)
67
+ def find_hosts(condition, max_results = 1)
68
+ return @memoized_hosts if (!@memoized_hosts.empty? && @memoized_condition = condition)
69
+
30
70
  @memoized_condition = condition
31
- @memoized_host = ::Infoblox::Fixedaddress.find(@connection, condition.merge('_max_results' => 1)).first
71
+ @memoized_hosts = ::Infoblox::Fixedaddress.find(@connection, condition.merge('_max_results' => max_results,
72
+ 'network_view' => network_view))
32
73
  end
33
74
 
34
75
  def find_host_and_name_by_ip(ip_address)
35
- h = find_host('ipv4addr' => ip_address)
36
- [h.name, h]
76
+ h = find_hosts('ipv4addr' => ip_address).first
77
+ h.nil? ? [nil, nil] : [h.name, h]
37
78
  end
38
79
 
39
80
  def build_host(options)
@@ -41,12 +82,12 @@ module ::Proxy::DHCP::Infoblox
41
82
  host.name = options[:hostname]
42
83
  host.ipv4addr = options[:ip]
43
84
  host.mac = options[:mac]
44
- # TODO: nextserver, use_nextserver, bootfile, and use_bootfile attrs exist but are not available in the model
45
- # Might be useful to extend the model to include these
46
- #host.nextserver = options[:nextServer]
47
- #host.use_nextserver = true
48
- #host.bootfile = options[:filename]
49
- #host.use_bootfile = true
85
+ host.nextserver = options[:nextServer]
86
+ host.use_nextserver = true
87
+ host.bootfile = options[:filename]
88
+ host.use_bootfile = true
89
+ host.network_view = network_view
90
+ host.options = Proxy::DHCP::Infoblox::Plugin.settings.options
50
91
  host
51
92
  end
52
93
  end
@@ -1,6 +1,6 @@
1
1
  module ::Proxy::DHCP::Infoblox
2
2
  class GridRestart
3
- MAX_ATTEMPTS = 3
3
+ MAX_ATTEMPTS = 5
4
4
 
5
5
  include ::Proxy::Log
6
6
  attr_reader :connection
@@ -10,21 +10,32 @@ module ::Proxy::DHCP::Infoblox
10
10
  end
11
11
 
12
12
  def try_restart
13
- logger.debug 'Restarting grid.'
13
+ logger.info 'Restarting Infoblox Grid'
14
14
 
15
+ delay = Proxy::DHCP::Infoblox::Plugin.settings.wait_after_restart.to_i
15
16
  MAX_ATTEMPTS.times do |tries|
17
+ if restart
18
+ if delay > 0
19
+ logger.info "Starting post-restart delay of #{delay} seconds..."
20
+ sleep delay
21
+ logger.debug "Post-restart delay done"
22
+ end
23
+ return
24
+ end
16
25
  sleep tries
17
- return if restart
18
26
  end
19
27
 
20
- logger.info 'Restarting Grid failed.'
28
+ logger.warn 'Restarting Infoblox Grid failed, giving up'
21
29
  false
22
30
  end
23
31
 
32
+ private
33
+
24
34
  def restart
25
35
  (@grid ||= ::Infoblox::Grid.get(@connection).first).restartservices
26
36
  true
27
37
  rescue Exception => e
38
+ logger.warn "Error during Grid restart: #{e}"
28
39
  false
29
40
  end
30
41
  end
@@ -3,45 +3,86 @@ require 'smart_proxy_dhcp_infoblox/network_address_range_regex_generator'
3
3
 
4
4
  module ::Proxy::DHCP::Infoblox
5
5
  class HostIpv4AddressCRUD < CommonCRUD
6
- def initialize(connection)
7
- @memoized_host = nil
6
+ attr_reader :dns_view
7
+
8
+ def initialize(connection, dns_view, used_ips_search_type)
9
+ @memoized_hosts = []
8
10
  @memoized_condition = nil
9
- super
11
+ @dns_view = dns_view
12
+ super(connection, used_ips_search_type)
10
13
  end
11
14
 
12
15
  def all_hosts(subnet_address)
13
16
  address_range_regex = NetworkAddressesRegularExpressionGenerator.new.generate_regex(subnet_address)
14
17
 
15
- hosts = ::Infoblox::Host.find(
18
+ if @used_ips_search_type == 'used'
19
+ addresses = ::Infoblox::Ipv4address.find(
20
+ @connection,
21
+ 'network' => subnet_address,
22
+ 'status' => 'USED',
23
+ '_max_results' => 2147483646
24
+ )
25
+ hosts = addresses.map do |address|
26
+ if address.mac_address.nil? || address.mac_address.empty?
27
+ checked_mac = '00:00:00:00:00:00'
28
+ else
29
+ checked_mac = address.mac_address
30
+ end
31
+ ::Infoblox::Host.new(
32
+ :name => address.names[0],
33
+ :ipv4addrs => [{ :name => address.names[0], :ipv4addr => address.ip_address, :mac => checked_mac,
34
+ :configure_for_dhcp => true }]
35
+ )
36
+ end
37
+ else
38
+ hosts = ::Infoblox::Host.find(
16
39
  @connection,
17
40
  'ipv4addr~' => address_range_regex,
18
- '_max_results' => 2147483646)
41
+ 'view' => dns_view,
42
+ '_max_results' => 2147483646
43
+ )
44
+ end
19
45
 
20
46
  ip_addr_matcher = Regexp.new(address_range_regex) # pre-compile the regex
21
- hosts.map {|host| build_reservation(host.name, host.ipv4addrs.find {|ip| ip_addr_matcher =~ ip.ipv4addr}, subnet_address)}.compact
47
+ hosts.map do |host|
48
+ build_reservation(host.name, host.ipv4addrs.find { |ip| ip_addr_matcher =~ ip.ipv4addr }, subnet_address)
49
+ end.compact
22
50
  end
23
51
 
24
52
  def find_record_by_ip(subnet_address, ip_address)
25
- found = find_host('ipv4addr' => ip_address)
53
+ found = find_hosts('ipv4addr' => ip_address).first
26
54
  return nil if found.nil?
27
- build_reservation(found.name, found.ipv4addrs.find {|ip| ip.ipv4addr == ip_address}, subnet_address)
55
+
56
+ build_reservation(found.name, found.ipv4addrs.find { |ip| ip.ipv4addr == ip_address }, subnet_address)
57
+ end
58
+
59
+ def find_records_by_ip(subnet_address, ip_address)
60
+ found = find_hosts({ 'ipv4addr' => ip_address }, 2147483646)
61
+ return [] if found.empty?
62
+
63
+ found.map do |record|
64
+ build_reservation(record.name, record.ipv4addrs.find { |ip| ip.ipv4addr == ip_address }, subnet_address)
65
+ end.compact
28
66
  end
29
67
 
30
68
  def find_record_by_mac(subnet_address, mac_address)
31
- found = find_host('mac' => mac_address)
69
+ found = find_hosts('mac' => mac_address).first
32
70
  return nil if found.nil?
33
- build_reservation(found.name, found.ipv4addrs.find {|ip| ip.mac == mac_address}, subnet_address)
71
+
72
+ build_reservation(found.name, found.ipv4addrs.find { |ip| ip.mac == mac_address }, subnet_address)
34
73
  end
35
74
 
36
75
  def find_host_and_name_by_ip(ip_address)
37
- h = find_host('ipv4addr' => ip_address)
38
- [h.name, h.ipv4addrs.find {|ip| ip.ipv4addr == ip_address}]
76
+ h = find_hosts('ipv4addr' => ip_address).first
77
+ h.nil? ? [nil, nil] : [h.name, h.ipv4addrs.find { |ip| ip.ipv4addr == ip_address }]
39
78
  end
40
79
 
41
- def find_host(condition)
42
- return @memoized_host if (!@memoized_host.nil? && @memoized_condition == condition)
80
+ def find_hosts(condition, max_results = 1)
81
+ return @memoized_hosts if (!@memoized_hosts.empty? && @memoized_condition == condition)
82
+
43
83
  @memoized_condition = condition
44
- @memoized_host = ::Infoblox::Host.find(@connection, condition.merge('_max_results' => 1)).first
84
+ @memoized_hosts = ::Infoblox::Host.find(@connection, condition.merge('view' => dns_view,
85
+ '_max_results' => max_results))
45
86
  end
46
87
 
47
88
  def build_host(options)
@@ -54,6 +95,7 @@ module ::Proxy::DHCP::Infoblox
54
95
  host_addr.use_nextserver = true
55
96
  host_addr.bootfile = options[:filename]
56
97
  host_addr.use_bootfile = true
98
+ host.view = dns_view
57
99
  host
58
100
  end
59
101
  end