smart_proxy_dhcp_infoblox 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +15 -10
- data/config/dhcp_infoblox.yml.example +17 -0
- data/lib/smart_proxy_dhcp_infoblox.rb +9 -3
- data/lib/smart_proxy_dhcp_infoblox/common_crud.rb +75 -0
- data/lib/smart_proxy_dhcp_infoblox/dhcp_infoblox_main.rb +39 -225
- data/lib/smart_proxy_dhcp_infoblox/dhcp_infoblox_plugin.rb +9 -17
- data/lib/smart_proxy_dhcp_infoblox/dhcp_infoblox_version.rb +1 -1
- data/lib/smart_proxy_dhcp_infoblox/fixed_address_crud.rb +53 -0
- data/lib/smart_proxy_dhcp_infoblox/grid_restart.rb +31 -0
- data/lib/smart_proxy_dhcp_infoblox/host_ipv4_address_crud.rb +60 -0
- data/lib/smart_proxy_dhcp_infoblox/ip_address_arithmetic.rb +34 -0
- data/lib/smart_proxy_dhcp_infoblox/network_address_range_regex_generator.rb +131 -0
- data/lib/smart_proxy_dhcp_infoblox/plugin_configuration.rb +37 -0
- data/lib/smart_proxy_dhcp_infoblox/record_type_validator.rb +8 -0
- data/lib/smart_proxy_dhcp_infoblox/unused_ips.rb +47 -0
- data/test/host_and_fixedaddress_crud_test.rb +169 -0
- data/test/infoblox_provider_test.rb +61 -0
- data/test/plugin_configuration_test.rb +73 -0
- data/test/record_type_validator_test.rb +20 -0
- data/test/regex_generator_test.rb +86 -0
- data/test/test_helper.rb +0 -2
- data/test/unused_ip_test.rb +48 -0
- metadata +25 -49
- data/config/dhcp_infoblox.yml +0 -14
- data/lib/smart_proxy_dhcp_infoblox/dhcp_infoblox_dependencies.rb +0 -5
- data/test/dhcp_infoblox_record_test.rb +0 -95
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f93a00fc3b3226cd13507406635a76d39fdf5bf
|
4
|
+
data.tar.gz: 2af103b766051daba129f8a05918f704692f7362
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 629785c6c921e5a356af8ab70703bc13d9db487dc3b4cdc2fb24ab1ff320d620e67b6762ff557a400cc1a77b4a73e7d7817c07591160e6d3de4011cf65abef48
|
7
|
+
data.tar.gz: 442344c94cb0cf17e7e8915139149be7f50c545d771e570dcc7ae921c8ae98649a2f207c72e2c91c66bfdfc655fe73ab8b1b3a9ff1191c7ed2ecf470a4118fb7
|
data/README.md
CHANGED
@@ -1,32 +1,37 @@
|
|
1
1
|
# SmartProxyDhcpInfoblox
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
This plugin adds a new DHCP provider for managing records with Infoblox Servers
|
3
|
+
This plugin adds a new DHCP provider for managing records with infoblox servers
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
9
7
|
See [How_to_Install_a_Smart-Proxy_Plugin](http://projects.theforeman.org/projects/foreman/wiki/How_to_Install_a_Smart-Proxy_Plugin)
|
10
8
|
for how to install Smart Proxy plugins
|
11
9
|
|
12
|
-
This plugin is compatible with Smart Proxy 1.
|
10
|
+
This plugin is compatible with Smart Proxy 1.11 or higher.
|
11
|
+
|
12
|
+
When installing using "gem", make sure to install the bundle file:
|
13
|
+
|
14
|
+
echo "gem 'smart_proxy_dhcp_infoblox'" > /usr/share/foreman-proxy/bundler.d/dhcp_infoblox.rb
|
13
15
|
|
14
16
|
## Configuration
|
15
17
|
|
16
18
|
To enable this DHCP provider, edit `/etc/foreman-proxy/settings.d/dhcp.yml` and set:
|
17
19
|
|
18
20
|
:use_provider: dhcp_infoblox
|
21
|
+
:server: IP of infoblox server
|
22
|
+
:subnets: subnets you want to use (optional unless you set infoblox_subnets to false)
|
19
23
|
|
20
24
|
Configuration options for this plugin are in `/etc/foreman-proxy/settings.d/dhcp_infoblox.yml` and include:
|
21
25
|
|
22
|
-
*
|
23
|
-
*
|
24
|
-
*
|
26
|
+
* username: API Username
|
27
|
+
* passowrd: API Password
|
28
|
+
* 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
|
25
30
|
|
26
|
-
|
27
|
-
|
31
|
+
## Different record types
|
32
|
+
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.
|
28
33
|
|
29
|
-
|
34
|
+
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.
|
30
35
|
|
31
36
|
## Contributing
|
32
37
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
---
|
2
|
+
#
|
3
|
+
# Configuration file for 'dhcp_infoblox' dhcp provider
|
4
|
+
#
|
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"
|
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
|
@@ -1,4 +1,10 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Proxy
|
2
|
+
module DHCP
|
3
|
+
module Infoblox; end
|
4
|
+
end
|
5
|
+
end
|
3
6
|
|
4
|
-
|
7
|
+
require 'smart_proxy_dhcp_infoblox/plugin_configuration'
|
8
|
+
require 'smart_proxy_dhcp_infoblox/record_type_validator'
|
9
|
+
require 'smart_proxy_dhcp_infoblox/dhcp_infoblox_version'
|
10
|
+
require 'smart_proxy_dhcp_infoblox/dhcp_infoblox_plugin'
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'resolv'
|
2
|
+
require 'smart_proxy_dhcp_infoblox/ip_address_arithmetic'
|
3
|
+
require "proxy/validations"
|
4
|
+
|
5
|
+
module ::Proxy::DHCP::Infoblox
|
6
|
+
class CommonCRUD
|
7
|
+
include Proxy::Validations
|
8
|
+
include IpAddressArithmetic
|
9
|
+
|
10
|
+
attr_reader :connection
|
11
|
+
|
12
|
+
def initialize(connection)
|
13
|
+
@connection = connection
|
14
|
+
end
|
15
|
+
|
16
|
+
def all_leases(network_address)
|
17
|
+
[] # infoblox doesn't support leases
|
18
|
+
end
|
19
|
+
|
20
|
+
def find_record(subnet_address, an_address)
|
21
|
+
return find_record_by_ip(subnet_address, an_address) if Resolv::IPv4::Regex =~ an_address
|
22
|
+
find_record_by_mac(subnet_address, an_address)
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_record(options)
|
26
|
+
validate_ip(options[:ip])
|
27
|
+
validate_mac(options[:mac])
|
28
|
+
raise(Proxy::DHCP::Error, "Must provide hostname") unless options[:hostname]
|
29
|
+
|
30
|
+
build_host(options).post
|
31
|
+
# TODO: DELETE ME needed for testing on infoblox ipam express
|
32
|
+
#host.configure_for_dns = false
|
33
|
+
rescue Infoblox::Error => e
|
34
|
+
raise e unless e.message.include?("IB.Data.Conflict") # not a conflict
|
35
|
+
|
36
|
+
begin
|
37
|
+
existing_name, existing_host = find_host_and_name_by_ip(options[:ip])
|
38
|
+
rescue Exception
|
39
|
+
raise e
|
40
|
+
end
|
41
|
+
raise e if existing_host.nil? # something weird going on, re-raise the original exception
|
42
|
+
|
43
|
+
if options[:mac] != existing_host.mac || options[:hostname] != existing_name
|
44
|
+
raise Proxy::DHCP::Collision, "Record #{options[:ip]} conflicts with an existing record."
|
45
|
+
end
|
46
|
+
raise Proxy::DHCP::AlreadyExists, "Record #{options[:ip]} already exists."
|
47
|
+
end
|
48
|
+
|
49
|
+
def del_record(_, record)
|
50
|
+
raise InvalidRecord, "#{record} is static - unable to delete" unless record.deleteable?
|
51
|
+
found = find_host('ipv4addr' => record.ip)
|
52
|
+
return if found.nil?
|
53
|
+
found.delete
|
54
|
+
end
|
55
|
+
|
56
|
+
def build_reservation(name, host, full_subnet_address)
|
57
|
+
return nil if host.nil?
|
58
|
+
return nil if name.nil? || name.empty?
|
59
|
+
return nil if (host.respond_to?(:configure_for_dhcp) && !host.configure_for_dhcp)
|
60
|
+
return nil if host.mac.nil? || host.mac.empty?
|
61
|
+
|
62
|
+
opts = { :hostname => name }
|
63
|
+
opts[:mac] = host.mac
|
64
|
+
opts[:ip] = host.ipv4addr
|
65
|
+
opts[:deleteable] = true
|
66
|
+
# TODO: nextserver, use_nextserver, bootfile, and use_bootfile attrs exist but are not available in the Fixedaddress model
|
67
|
+
# Might be useful to extend the model to include these
|
68
|
+
opts[:nextServer] = host.nextserver if (host.respond_to?(:use_nextserver) && host.use_nextserver)
|
69
|
+
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)))
|
71
|
+
|
72
|
+
Proxy::DHCP::Reservation.new(opts)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -1,256 +1,70 @@
|
|
1
1
|
require 'dhcp_common/server'
|
2
|
-
require '
|
3
|
-
require 'ipaddr'
|
2
|
+
require 'smart_proxy_dhcp_infoblox/ip_address_arithmetic'
|
4
3
|
|
5
4
|
module Proxy::DHCP::Infoblox
|
6
5
|
class Provider < ::Proxy::DHCP::Server
|
7
6
|
include Proxy::Log
|
8
7
|
include Proxy::Util
|
8
|
+
include IpAddressArithmetic
|
9
9
|
|
10
|
-
attr_reader :
|
10
|
+
attr_reader :connection, :crud, :restart_grid, :unused_ips
|
11
11
|
|
12
|
-
def initialize
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
@range = Proxy::DHCP::Infoblox::Plugin.settings.range
|
19
|
-
wapi_version = Proxy::DHCP::Infoblox::Plugin.settings.wapi_version
|
20
|
-
::Infoblox.wapi_version = "#{wapi_version}"
|
21
|
-
@connection = ::Infoblox::Connection.new(username: infoblox_user, password: infoblox_pw, host: server)
|
22
|
-
logger.debug "Loaded infoblox provider with #{@record_type} record_type and #{wapi_version} wapi_version"
|
12
|
+
def initialize(connection, crud, restart_grid, unused_ips, managed_subnets)
|
13
|
+
@connection = connection
|
14
|
+
@crud = crud
|
15
|
+
@restart_grid = restart_grid
|
16
|
+
@unused_ips = unused_ips
|
17
|
+
super('infoblox', managed_subnets, nil)
|
23
18
|
end
|
24
19
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
28
|
-
@dhcp_server = params[:dhcp_server] || @dhcp_server
|
29
|
-
@username = params[:username] || @username
|
30
|
-
@password = params[:password] || @password
|
31
|
-
@record_type = params[:record_type] || @record_type
|
32
|
-
@wapi_version = params[:wapi_version] || @wapi_version
|
33
|
-
self
|
34
|
-
end
|
35
|
-
|
36
|
-
def load_subnets
|
37
|
-
logger.debug 'load_subnets'
|
38
|
-
::Infoblox::Network.all(@connection).each do |obj|
|
39
|
-
if match = obj.network.split('/')
|
40
|
-
tmp = IPAddr.new(obj.network)
|
41
|
-
netmask = IPAddr.new(tmp.instance_variable_get("@mask_addr"), Socket::AF_INET).to_s
|
42
|
-
next unless managed_subnet? "#{match[0]}/#{netmask}"
|
43
|
-
options = {}
|
44
|
-
service.add_subnets(Proxy::DHCP::Subnet.new(match[0], netmask, options))
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def find_subnet(network_address)
|
50
|
-
# returns Proxy::DHCP::Subnet that has network_address or nil if none was found
|
51
|
-
# network = ::Infoblox::Ipv4address.find(connection, "ip_address" => network_address).first.network
|
52
|
-
super
|
53
|
-
end
|
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
|
54
23
|
|
55
|
-
def
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
logger.debug 'load_infoblox_subnet_data'
|
62
|
-
if @record_type == 'host'
|
63
|
-
# max results are currently set to work in my setup, one could calculate that setting by looking at netmask :)
|
64
|
-
network = ::Infoblox::Ipv4address.find(@connection, 'network' => "#{subnet.network}/#{subnet.cidr}", 'status' => 'USED', 'usage' => 'DHCP', '_max_results' => 2**(32-subnet.cidr))
|
65
|
-
# Find out which hosts are in use
|
66
|
-
network.each do |host|
|
67
|
-
# next if certain values are not set
|
68
|
-
next if host.names.empty? || host.mac_address.empty? || host.ip_address.empty?
|
69
|
-
hostdhcp = ::Infoblox::HostIpv4addr.find(@connection, 'ipv4addr' => host.ip_address).first
|
70
|
-
next unless hostdhcp.configure_for_dhcp
|
71
|
-
opts = { :hostname => host.names.first }
|
72
|
-
opts[:mac] = host.mac_address
|
73
|
-
opts[:ip] = host.ip_address
|
74
|
-
# broadcast and network entrys are not deleteable
|
75
|
-
opts[:deleteable] = true unless (host.types & %w(BROADCAST NETWORK)).any?
|
76
|
-
opts[:nextServer] = hostdhcp.nextserver unless hostdhcp.use_nextserver
|
77
|
-
opts[:filename] = hostdhcp.bootfile unless hostdhcp.use_bootfile
|
78
|
-
service.add_host(subnet.network, Proxy::DHCP::Reservation.new(opts.merge(:subnet => subnet)))
|
79
|
-
end
|
80
|
-
elsif @record_type == 'fixed_address'
|
81
|
-
network = ::Infoblox::Fixedaddress.find(@connection, 'network' => "#{subnet.network}/#{subnet.cidr}", '_max_results' => 2**(32-subnet.cidr))
|
82
|
-
network.each do |host|
|
83
|
-
logger.debug "Processing host: #{host.name} #{host.mac} #{host.ipv4addr}"
|
84
|
-
next if host.name == nil || host.mac == nil || host.ipv4addr == nil
|
85
|
-
opts = { :hostname => host.name }
|
86
|
-
opts[:mac] = host.mac
|
87
|
-
opts[:ip] = host.ipv4addr
|
88
|
-
service.add_host(subnet.network, Proxy::DHCP::Reservation.new(opts.merge(:subnet => subnet)))
|
89
|
-
end
|
90
|
-
end
|
24
|
+
def subnets
|
25
|
+
::Infoblox::Network.all(connection).map do |network|
|
26
|
+
address, prefix_length = network.network.split("/")
|
27
|
+
netmask = cidr_to_ip_mask(prefix_length.to_i)
|
28
|
+
managed_subnet?("#{address}/#{netmask}") ? Proxy::DHCP::Subnet.new(address, netmask, {}) : nil
|
29
|
+
end.compact
|
91
30
|
end
|
92
31
|
|
93
32
|
def all_hosts(network_address)
|
94
|
-
|
95
|
-
logger.debug "infoblox.all_hosts #{network_address}"
|
96
|
-
load_infoblox_subnet_data(find_subnet(network_address))
|
97
|
-
super
|
33
|
+
crud.all_hosts(full_network_address(network_address))
|
98
34
|
end
|
99
35
|
|
100
|
-
def
|
101
|
-
|
102
|
-
# Deliberatly ignoring everything but first argument
|
103
|
-
logger.debug "Infoblox unused_ip Network_address: #{network_address} #{mac_address}, #{from_ip_address}, #{to_ip_address}"
|
104
|
-
#next_available_ip can take a number to return (1), and an array of ips to exclude. So, we need to:
|
105
|
-
#build a list of all ips in the network (all_addresses)
|
106
|
-
#build a list of all ips in between from_ip_address and to_ip_address (include_addresses)
|
107
|
-
#remove all of the from_ip_address and to_ip_address from the all_address (exclude_addresses)
|
108
|
-
#and call next_available_ip with exclude_addresses passed
|
109
|
-
all_addresses = Array.new
|
110
|
-
net=IPAddr.new("#{network_address.network}/#{network_address.cidr}")
|
111
|
-
net.to_range.each do |ip|
|
112
|
-
all_addresses.push(ip.to_s)
|
113
|
-
end
|
114
|
-
range_start=IPAddr.new(from_ip_address)
|
115
|
-
range_stop=IPAddr.new(to_ip_address)
|
116
|
-
included_addresses=Array.new
|
117
|
-
(range_start..range_stop).each do |ip|
|
118
|
-
included_addresses.push(ip.to_s)
|
119
|
-
end
|
120
|
-
excluded_addresses=all_addresses-included_addresses
|
121
|
-
#excluded_addresses is now an array of ips containing all the ips from the network not between from, and to_ip_address
|
122
|
-
|
123
|
-
if @range
|
124
|
-
::Infoblox::Range.find(@connection, network: "#{network_address.network}/#{network_address.cidr}").first.next_available_ip(1,excluded_addresses)
|
125
|
-
else
|
126
|
-
::Infoblox::Network.find(@connection, network: "#{network_address.network}/#{network_address.cidr}").first.next_available_ip(1,excluded_addresses)
|
127
|
-
end
|
128
|
-
# Idea for randomisation in case of concurrent installs:
|
129
|
-
#::Infoblox::Network.find(@connection, network: "#{network_address.network}/#{network_address.cidr}").first.next_available_ip(15).sample
|
36
|
+
def all_leases(network_address)
|
37
|
+
crud.all_leases(full_network_address(network_address))
|
130
38
|
end
|
131
39
|
|
132
40
|
def find_record(subnet_address, an_address)
|
133
|
-
|
134
|
-
# record can be either ip or mac, true = mac --> lookup ip
|
135
|
-
if an_address.is_a?(String) && valid_mac?(an_address)
|
136
|
-
if @record_type == 'host'
|
137
|
-
hostdhcp = ::Infoblox::HostIpv4addr.find(@connection, 'mac' => an_address)
|
138
|
-
elsif @record_type == 'fixed_address'
|
139
|
-
hostdhcp = ::Infoblox::Fixedaddress.find(@connection,'mac' => an_address)
|
140
|
-
end
|
141
|
-
return nil if hostdhcp.empty?
|
142
|
-
ipv4address = hostdhcp.first.ipv4addr
|
143
|
-
elsif an_address.is_a?(String)
|
144
|
-
validate_ip(an_address)
|
145
|
-
ipv4address = an_address
|
146
|
-
end
|
147
|
-
|
148
|
-
if @record_type == 'host'
|
149
|
-
host = ::Infoblox::Host.find(@connection, 'ipv4addr' => ipv4address)
|
150
|
-
return nil if host.empty? || host.first.name.empty?
|
151
|
-
hostdhcp = ::Infoblox::HostIpv4addr.find(@connection, 'ipv4addr' => ipv4address).first
|
152
|
-
return nil unless hostdhcp.configure_for_dhcp
|
153
|
-
return nil if hostdhcp.mac.empty? || hostdhcp.ipv4addr.empty?
|
154
|
-
opts = { :hostname => host.first.name }
|
155
|
-
opts[:mac] = hostdhcp.mac
|
156
|
-
opts[:ip] = hostdhcp.ipv4addr
|
157
|
-
opts[:deleteable] = true
|
158
|
-
opts[:nextServer] = hostdhcp.nextserver if hostdhcp.use_nextserver
|
159
|
-
opts[:filename] = hostdhcp.bootfile if hostdhcp.use_bootfile
|
160
|
-
elsif @record_type == 'fixed_address'
|
161
|
-
logger.debug "find_record for #{an_address}"
|
162
|
-
fixed_address = ::Infoblox::Fixedaddress.find(@connection, 'ipv4addr' => ipv4address)
|
163
|
-
#logger.debug "#{fixed_address.inspect}"
|
164
|
-
return nil if fixed_address == []
|
165
|
-
#return nil if fixed_address.emtpy? || fixed_address.first.name.empty?
|
166
|
-
#return nil if fixed_address.emtpy?
|
167
|
-
opts = { :hostname => fixed_address.first.name }
|
168
|
-
opts[:deleteable] = true
|
169
|
-
opts[:mac] = fixed_address.first.mac
|
170
|
-
opts[:ip] = fixed_address.first.ipv4addr
|
171
|
-
end
|
172
|
-
# Subnet should only be one, not checking that yet
|
173
|
-
subnet = subnets.find { |s| s.include? ipv4address }
|
174
|
-
Proxy::DHCP::Record.new(opts.merge(:subnet => subnet))
|
41
|
+
crud.find_record(full_network_address(subnet_address), an_address)
|
175
42
|
end
|
176
43
|
|
177
|
-
def
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
host.add_ipv4addr(record.ip)
|
182
|
-
host.post
|
44
|
+
def add_record(options)
|
45
|
+
crud.add_record(options)
|
46
|
+
logger.debug("Added DHCP reservation for #{options[:ip]}/#{options[:mac]}")
|
47
|
+
restart_grid.try_restart
|
183
48
|
end
|
184
49
|
|
185
|
-
def
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
fixed_address.ipv4addr = record.ip
|
190
|
-
fixed_address.mac = record.mac
|
191
|
-
fixed_address.post
|
50
|
+
def del_record(subnet, record)
|
51
|
+
crud.del_record(full_network_address(subnet.network), record)
|
52
|
+
logger.debug("Removed DHCP reservation for #{record.ip} => #{record}")
|
53
|
+
restart_grid.try_restart
|
192
54
|
end
|
193
55
|
|
194
|
-
def
|
195
|
-
|
196
|
-
record = super
|
197
|
-
#Since we support 2 types of records, do the right thing with each one.
|
198
|
-
if @record_type == 'host'
|
199
|
-
host = ::Infoblox::Host.find(@connection, 'ipv4addr' => record.ip)
|
200
|
-
# If empty create:
|
201
|
-
if host.empty?
|
202
|
-
create_infoblox_host_record(record)
|
203
|
-
end
|
204
|
-
host = ::Infoblox::Host.find(@connection, 'ipv4addr' => record.ip).first
|
205
|
-
options = record.options
|
206
|
-
# Overwrite values without checking
|
207
|
-
# Select correct ipv4addr object from ipv4addrs array
|
208
|
-
hostip = host.ipv4addrs.find { |ip| ip.ipv4addr == record.ip }
|
209
|
-
logger.debug "Add Record - record.name: #{record.name}, hostip.host #{hostip.host}, record.mac #{record.mac}, record.ip #{record.ip}"
|
210
|
-
logger.debug "Add Record - options[:nextServer] #{options[:nextServer]}, options[:filename] #{options[:filename]}, hostip.ipv4addr: #{hostip.ipv4addr} "
|
211
|
-
raise InvalidRecord, "#{record} Hostname mismatch" unless hostip.host == record.name
|
212
|
-
hostip.mac = record.mac
|
213
|
-
hostip.configure_for_dhcp = true
|
214
|
-
hostip.nextserver = options[:nextServer]
|
215
|
-
hostip.use_nextserver = true
|
216
|
-
hostip.bootfile = options[:filename]
|
217
|
-
hostip.use_bootfile = true
|
218
|
-
## Test if Host Entry has correct IP
|
219
|
-
raise InvalidRecord, "#{record} IP mismatch" unless hostip.ipv4addr == record.ip
|
220
|
-
# Send object
|
221
|
-
host.put
|
222
|
-
record
|
223
|
-
elsif @record_type == 'fixed_address'
|
224
|
-
create_infoblox_fixed_address(record)
|
225
|
-
record
|
226
|
-
end
|
56
|
+
def unused_ip(subnet, _, from_ip_address, to_ip_address)
|
57
|
+
unused_ips.unused_ip(subnet.network, from_ip_address, to_ip_address)
|
227
58
|
end
|
228
59
|
|
229
|
-
def
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
raise InvalidRecord, "#{record} is static - unable to delete" unless record.deleteable?
|
235
|
-
if @record_type == 'host'
|
236
|
-
# "Deleting" a record here means just disabling dhcp
|
237
|
-
host = ::Infoblox::Host.find(@connection, 'ipv4addr' => record.ip)
|
238
|
-
unless host.empty?
|
239
|
-
# if not empty, first element is what we want to edit
|
240
|
-
host = host.first
|
241
|
-
# Select correct ipv4addr object from ipv4addrs array
|
242
|
-
hostip = host.ipv4addrs.find { |ip| ip.ipv4addr == record.ip }
|
243
|
-
hostip.configure_for_dhcp = false
|
244
|
-
# Send object
|
245
|
-
host.put
|
246
|
-
end
|
247
|
-
elsif @record_type == 'fixed_address'
|
248
|
-
#Delete the fixed address record.
|
249
|
-
fixed_address = ::Infoblox::Fixedaddress.find(@connection, 'ipv4addr' => record.ip).first
|
250
|
-
fixed_address.delete
|
251
|
-
end
|
60
|
+
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?
|
63
|
+
network
|
64
|
+
end
|
252
65
|
|
253
|
-
|
66
|
+
def full_network_address(network_address)
|
67
|
+
find_network(network_address).network
|
254
68
|
end
|
255
69
|
end
|
256
70
|
end
|