iblox 0.0.1
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 +7 -0
- data/bin/iblox +144 -0
- data/lib/iblox.rb +156 -0
- metadata +74 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 678b86b0e1c03bb31eb8ffcd9367b8e7af450ca0
|
4
|
+
data.tar.gz: 35dbd2fb53c1b7ace8a96cf8ff18564bbf241598
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: af467ec41f2b56d39e0329f28cbd008f0116bb1d90b77c828c76bcacfe9a3473fb8e119984b4198bb2df84b40abc5f0077fd7c23f66324ce9a95694652da3d43
|
7
|
+
data.tar.gz: a35ef0aac5f869c6c3189dda3899a3a5220e092adcbb1198e259d425b4d5106cb10eb3ccef20ea579906bd3eb218a953e81625ec141985aa39d6b1d18bccb4cd
|
data/bin/iblox
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'infoblox'
|
3
|
+
require 'pp'
|
4
|
+
require 'yaml'
|
5
|
+
require 'ipaddr'
|
6
|
+
require 'optparse'
|
7
|
+
require 'blox'
|
8
|
+
|
9
|
+
ENV['WAPI_VERSION']='2.0'
|
10
|
+
options = Hash.new
|
11
|
+
|
12
|
+
OptionParser.new do |opts|
|
13
|
+
opts.banner = "Usage infoblox <Facility (dns|dhcp)> <action>(add|update|delete) [options]"
|
14
|
+
opts.on("-c", "--config /path/to/infoblox.yaml",String, "use custom config path (~/.infoblox.yaml, /etc/infoblox.yaml)") do |config |
|
15
|
+
options.merge!(Hash[YAML::load(open(config)).map { |k, v| [k.to_sym, v] }])
|
16
|
+
options[:config] = config
|
17
|
+
end
|
18
|
+
opts.on("-f", "--fqdn FQDN",String, "FQDN or add/update/remove") do |fqdn|
|
19
|
+
options[:fqdn] = fqdn
|
20
|
+
end
|
21
|
+
opts.on("-h", "--new-fqdn FQDN",String, "New FQDN if updating a record") do |new_fqdn|
|
22
|
+
options[:new_fqdn] = new_fqdn
|
23
|
+
end
|
24
|
+
opts.on("-n", "--network 192.168.0.0/24",String, "CIDR of network to use") do |network|
|
25
|
+
options[:network] = network
|
26
|
+
end
|
27
|
+
opts.on("-i", "--ip 192.168.1.1",String,"IP address to use (if adding a record, this can be ommtted for next avialable, must specify network however)") do |ip|
|
28
|
+
options[:ip] = ip
|
29
|
+
end
|
30
|
+
opts.on("-j", "--new-ip 192.168.1.2",String,"New ip address if updating a record") do |new_ip|
|
31
|
+
options[:new_ip] = new_ip
|
32
|
+
end
|
33
|
+
opts.on("-m", "--mac 00:05:67:45:32:01",String,"Mac Address to use") do |mac|
|
34
|
+
options[:mac] = mac
|
35
|
+
end
|
36
|
+
opts.on("-p", "--new-mac 00:05:67:45:32:02",String,"New Mac Address to use") do |new_mac|
|
37
|
+
options[:new_mac] = new_mac
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on("-v","--verbose", "Be verbose") do |v|
|
41
|
+
options[:verbose] = v
|
42
|
+
end
|
43
|
+
opts.parse!
|
44
|
+
end
|
45
|
+
|
46
|
+
options[:facility] = ARGV[0]
|
47
|
+
if !options[:facility].match(/(dns|dhcp|both)/)
|
48
|
+
raise "Facility must be one of 'dns', 'dhcp' or 'both'!"
|
49
|
+
end
|
50
|
+
|
51
|
+
options[:action] = ARGV[1]
|
52
|
+
if !options[:action].match(/(add|update|delete)/)
|
53
|
+
raise "Action must be one of 'add', 'update' or 'delete'"
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
#load config
|
58
|
+
if options[:config] == nil
|
59
|
+
config=Iblox.config_find()
|
60
|
+
options[:config] = config
|
61
|
+
options.merge!(Hash[YAML::load(open(File.expand_path(config))).map { |k, v| [k.to_sym, v] }])
|
62
|
+
if options[:verbose]
|
63
|
+
pp options
|
64
|
+
end
|
65
|
+
else
|
66
|
+
options.merge!(Hash[YAML::load(open(File.expand_path(options[:config]))).map { |k, v| [k.to_sym, v] }])
|
67
|
+
if options[:verbose]
|
68
|
+
pp options
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
#dns and dhc have different requirements for options and functions.
|
73
|
+
|
74
|
+
case options[:facility]
|
75
|
+
when "dns"
|
76
|
+
if options[:ip] == nil or options[:fqdn] == nil
|
77
|
+
raise "Both IP and FQDN are required for DNS actions"
|
78
|
+
end
|
79
|
+
connection=Iblox.connect(options[:username],options[:password],options[:host])
|
80
|
+
if Iblox.ipv4check(options[:ip])
|
81
|
+
case options[:action]
|
82
|
+
when "add"
|
83
|
+
#Be smarter here, see if we exist, and if so don't #FAIL, just say so.
|
84
|
+
if !Iblox.dns_exists(options[:fqdn],options[:ip],options[:verbose],connection)
|
85
|
+
if options[:verbose] ==true
|
86
|
+
puts "record doesn't exist, adding"
|
87
|
+
end
|
88
|
+
Iblox.dns_add(options[:fqdn],options[:ip],options[:verbose],connection)
|
89
|
+
else
|
90
|
+
if options[:verbose] ==true
|
91
|
+
puts "record exists! not adding"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
when "update"
|
95
|
+
#check we got the new values.
|
96
|
+
if ((options[:new_ip] != nil) or (options[:new_fqdn] != nil))
|
97
|
+
Iblox.dns_update(options[:fqdn],options[:ip],options[:new_fqdn],options[:new_ip],options[:verbose],connection)
|
98
|
+
else
|
99
|
+
raise "No new IP or FQDN provided for update action"
|
100
|
+
end
|
101
|
+
when "delete"
|
102
|
+
Iblox.dns_delete(options[:fqdn],options[:ip],options[:verbose],connection)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
when "dhcp"
|
107
|
+
if (options[:ip] == nil and options[:network] == nil) or options[:fqdn] == nil or options[:mac] ==nil
|
108
|
+
raise "IP or Network, and FQDN and MAC are required for DNS actions"
|
109
|
+
end
|
110
|
+
connection=Iblox.connect(options[:username],options[:password],options[:host])
|
111
|
+
if options[:verbose] ==true
|
112
|
+
puts "Connected to Infoblox"
|
113
|
+
end
|
114
|
+
case options[:action]
|
115
|
+
when "add"
|
116
|
+
#if we have an ip, check for existing reservation
|
117
|
+
# if not check get next avail
|
118
|
+
if (options[:ip] == nil and options[:network] != nil)
|
119
|
+
#get net avail ip
|
120
|
+
options[:ip]=Iblox.dhcp_next(options[:network],options[:verbose],connection)
|
121
|
+
end
|
122
|
+
if Iblox.ipv4check(options[:ip])
|
123
|
+
if !Iblox.dhcp_exists(options[:mac],options[:verbose],connection)
|
124
|
+
if options[:verbose] ==true
|
125
|
+
puts "record doesn't exist, adding"
|
126
|
+
end
|
127
|
+
Iblox.dhcp_add(options[:fqdn],options[:ip],options[:mac],options[:verbose],connection)
|
128
|
+
else
|
129
|
+
if options[:verbose] ==true
|
130
|
+
puts "record exists! not adding"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
when "update"
|
135
|
+
if ((options[:new_ip] != nil) or (options[:new_fqdn] != nil) or (options[:new_mac] != nil ))
|
136
|
+
Iblox.dhcp_update(options[:fqdn],options[:ip],options[:mac],options[:new_fqdn],options[:new_ip],options[:new_mac],options[:verbose],connection)
|
137
|
+
else
|
138
|
+
raise "No new IP, MAC, od FQDN provided for update action"
|
139
|
+
end
|
140
|
+
when "delete"
|
141
|
+
Iblox.dhcp_delete(options[:fqdn],options[:ip],options[:mac],options[:verbose],connection)
|
142
|
+
end
|
143
|
+
#when "both"
|
144
|
+
end
|
data/lib/iblox.rb
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
class Iblox
|
2
|
+
|
3
|
+
#config find
|
4
|
+
def self.config_find()
|
5
|
+
config_search_paths=['~/.iblox.yaml','/etc/iblox.yaml']
|
6
|
+
config_search_paths.each do |path|
|
7
|
+
#If #{path} is a file and re can read it, return it.
|
8
|
+
if File.exists?(File.expand_path(path))
|
9
|
+
return (path)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
#no config found
|
13
|
+
raise ("No config found!")
|
14
|
+
end
|
15
|
+
|
16
|
+
#Open infoblox connection object
|
17
|
+
def self.connect (username, password, host)
|
18
|
+
connection = Infoblox::Connection.new(username: "#{username}",password: "#{password}", host: "#{host}")
|
19
|
+
return connection
|
20
|
+
end
|
21
|
+
|
22
|
+
#Check we got an IPv4 address
|
23
|
+
def self.ipv4check (ip)
|
24
|
+
ipaddr1 = IPAddr.new "#{ip}"
|
25
|
+
if ipaddr1.ipv4?
|
26
|
+
return true
|
27
|
+
else
|
28
|
+
raise "#{ip} is not a valid IP address!"
|
29
|
+
return false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
#check that the ip we got is in the network we got
|
34
|
+
def self.ipv4netcheck(ip, network)
|
35
|
+
net=IPAddr.new "#{network}"
|
36
|
+
if net.include?(IPAddr.new "#{ip}")
|
37
|
+
return true
|
38
|
+
else
|
39
|
+
raise "#{ip} is not within #{network}"
|
40
|
+
return false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
#Check if the record we want exists
|
45
|
+
def self.dns_exists(fqdn,ip,verbose,connection)
|
46
|
+
#try to find A
|
47
|
+
a_record = Infoblox::Arecord.find( connection, { name: fqdn, ipv4addr: ip }).first
|
48
|
+
#try to find PTR
|
49
|
+
ptr_record = Infoblox::Ptr.find( connection, { ptrdname: fqdn, ipv4addr: ip}).first
|
50
|
+
if a_record == nil or ptr_record == nil
|
51
|
+
return false
|
52
|
+
else
|
53
|
+
return true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
#Add dns A record + PTR record
|
57
|
+
def self.dns_add(fqdn,ip,verbose,connection)
|
58
|
+
if verbose == true
|
59
|
+
puts "Adding DNS A Record for #{fqdn}(#{ip})"
|
60
|
+
end
|
61
|
+
a_record = Infoblox::Arecord.new(connection: connection, name: fqdn, ipv4addr: ip)
|
62
|
+
ptr_record = Infoblox::Ptr.new(connection: connection, ptrdname: fqdn, ipv4addr: ip)
|
63
|
+
a_record.post
|
64
|
+
ptr_record.post
|
65
|
+
end
|
66
|
+
#Update dns record
|
67
|
+
def self.dns_update(fqdn,ip,new_fqdn,new_ip,verbose,connection)
|
68
|
+
a_record = Infoblox::Arecord.find( connection, { name: fqdn, ipv4addr: ip }).first
|
69
|
+
ptr_record = Infoblox::Ptr.find( connection, { ptrdname: fqdn, ipv4addr: ip}).first
|
70
|
+
if a_record == nil or ptr_record == nil
|
71
|
+
raise 'no record to update found'
|
72
|
+
else
|
73
|
+
if new_fqdn != nil
|
74
|
+
a_record.name = new_fqdn
|
75
|
+
ptr_record.ptrdname = new_fqdn
|
76
|
+
end
|
77
|
+
if new_ip != nil
|
78
|
+
a_record.ipv4addr = new_ip
|
79
|
+
ptr_record.ipv4addr = new_ip
|
80
|
+
end
|
81
|
+
a_record.view=nil
|
82
|
+
ptr_record.view=nil
|
83
|
+
ptr_record.ipv6addr=nil
|
84
|
+
a_record.put
|
85
|
+
ptr_record.put
|
86
|
+
end
|
87
|
+
end
|
88
|
+
#Delete DNS record
|
89
|
+
def self.dns_delete(fqdn,ip,verbose,connection)
|
90
|
+
if verbose == true
|
91
|
+
puts "Deleting DNS A Record for #{fqdn}(#{ip})"
|
92
|
+
end
|
93
|
+
a_record = Infoblox::Arecord.find( connection, { name: fqdn, ipv4addr: ip }).first
|
94
|
+
ptr_record = Infoblox::Ptr.find( connection, { ptrdname: fqdn, ipv4addr: ip}).first
|
95
|
+
#pp a_record
|
96
|
+
#pp ptr_record
|
97
|
+
a_record.delete
|
98
|
+
ptr_record.delete
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
#check for DHCP reservation by mac
|
103
|
+
def self.dhcp_exists(mac,verbose,connection)
|
104
|
+
dhcp_res = Infoblox::Fixedaddress.find( connection, { mac: mac}).first
|
105
|
+
if dhcp_res == nil
|
106
|
+
return false
|
107
|
+
else
|
108
|
+
return true
|
109
|
+
end
|
110
|
+
end
|
111
|
+
def self.dhcp_next(network,verbose,connection)
|
112
|
+
if verbose == true
|
113
|
+
puts "Getting next available IP address for network #{network}"
|
114
|
+
end
|
115
|
+
#net = Infoblox::Network.find(connection, network: network).first
|
116
|
+
range = Infoblox::Range.find(connection, network: network).first
|
117
|
+
ip = range.next_available_ip[0]
|
118
|
+
return ip
|
119
|
+
end
|
120
|
+
def self.dhcp_add(fqdn,ip,mac,verbose,connection)
|
121
|
+
if verbose == true
|
122
|
+
puts "Adding DHCP fixed address for #{fqdn}(#{ip} #{mac})"
|
123
|
+
end
|
124
|
+
dhcp_res = Infoblox::Fixedaddress.new(connection: connection,
|
125
|
+
name: fqdn,
|
126
|
+
mac: mac,
|
127
|
+
ipv4addr: ip,
|
128
|
+
)
|
129
|
+
dhcp_res.post
|
130
|
+
end
|
131
|
+
def self.dhcp_update(fqdn,ip,mac,new_fqdn,new_ip,new_mac,verbose,connection)
|
132
|
+
dhcp_res = Infoblox::Fixedaddress.find( connection, { ipv4addr: ip, mac: mac}).first
|
133
|
+
if dhcp_res == nil
|
134
|
+
raise 'no record to update found'
|
135
|
+
else
|
136
|
+
if new_fqdn != nil
|
137
|
+
dhcp_res.name = new_fqdn
|
138
|
+
end
|
139
|
+
if new_ip != nil
|
140
|
+
dhcp_res.ipv4addr = new_ip
|
141
|
+
end
|
142
|
+
if new_mac != nil
|
143
|
+
dhcp_res.mac = new_mac
|
144
|
+
end
|
145
|
+
dhcp_res.post
|
146
|
+
end
|
147
|
+
end
|
148
|
+
def self.dhcp_delete(fqdn,ip,mac,verbose,connection)
|
149
|
+
if verbose == true
|
150
|
+
puts "Deleting DHCP fixed address for #{fqdn}(#{ip} #{mac})"
|
151
|
+
end
|
152
|
+
dhcp_res = Infoblox::Fixedaddress.find( connection, { ipv4addr: ip, mac: mac}).first
|
153
|
+
dhcp_res.delete
|
154
|
+
|
155
|
+
end
|
156
|
+
end
|
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: iblox
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matthew Nicholson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2012-05-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.10'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: infoblox
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.0'
|
41
|
+
description: A simple Infoblox CLI wrapper
|
42
|
+
email: matthew.a.nicholson@gmail.com
|
43
|
+
executables:
|
44
|
+
- iblox
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- bin/iblox
|
49
|
+
- lib/iblox.rb
|
50
|
+
homepage: http://rubygems.org/gems/iblox
|
51
|
+
licenses:
|
52
|
+
- GPL
|
53
|
+
metadata: {}
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options: []
|
56
|
+
require_paths:
|
57
|
+
- lib
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
requirements: []
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 2.2.2
|
71
|
+
signing_key:
|
72
|
+
specification_version: 4
|
73
|
+
summary: 'iBlox: Infoblox cli wrapper'
|
74
|
+
test_files: []
|