smart_proxy_ipam 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6b3ac65296507b0ad85c10e613a774692b1547ef25d39ce59bc5f28db6c28734
4
- data.tar.gz: 2058474b34f87a243cadc4960c75de19041f532d6c6dc7e2d30a9d63cfc4786d
3
+ metadata.gz: 0754301cca6caabaf785d9c4a7753d8543289fa9754339c12f706d23610577d2
4
+ data.tar.gz: ad1c8b77662f0ff667ff1c2127bfb9af6221dfe67cd7877968c6425e20fc4074
5
5
  SHA512:
6
- metadata.gz: 25200a0e7c4a88d00b79995863277879ea5f8e479f6b4626426e1b14c2237b43d7cf6c50c11e9f50158c7d8b6ca7dcee48794498931076994a72396434bcc327
7
- data.tar.gz: b320b8cfbb6f7b2b92944dc2629d28bcfa7d3a1c2626661abdab510bb3866dfb59d75b0640f7e489015066a6c960a727b4039633ac22e0f328d45bc6927fe0ff
6
+ metadata.gz: 74ba390d81e5be049f0ab15c1586babb91feddbde52c513cf65c35cc140a7471d3f531d578da899b406c09bdebbf8f6039a15e8105bf8ee7bafd67bb5ec3e4a9
7
+ data.tar.gz: a6fe51e572df5e809546fea30864b5bdf153e7eb297bc0a6ae909eda79c181fc028f6b7c2421c1745f62ef20e94bbf55f2cfcd1f5a86270c1ed372db22c3722d
@@ -21,20 +21,17 @@ module Proxy::Ipam
21
21
  request = Net::HTTP::Get.new(uri)
22
22
  request[@auth_header] = @token
23
23
  request['Accept'] = 'application/json'
24
- request['Content-Type'] = 'application/json'
25
24
 
26
25
  Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
27
26
  http.request(request)
28
27
  end
29
28
  end
30
29
 
31
- def delete(path, body = nil)
30
+ def delete(path)
32
31
  uri = URI(@api_base + path)
33
- uri.query = URI.encode_www_form(body) if body
34
32
  request = Net::HTTP::Delete.new(uri)
35
33
  request[@auth_header] = @token
36
34
  request['Accept'] = 'application/json'
37
- request['Content-Type'] = 'application/json'
38
35
 
39
36
  Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
40
37
  http.request(request)
@@ -4,38 +4,45 @@ require 'monitor'
4
4
  require 'concurrent'
5
5
  require 'time'
6
6
  require 'smart_proxy_ipam/ipam_helper'
7
+ require 'singleton'
7
8
 
8
9
  module Proxy::Ipam
9
10
  # Class for managing temp in-memory cache to prevent same IP's being suggested in race conditions
10
11
  class IpCache
12
+ include Singleton
11
13
  include Proxy::Log
12
14
  include Proxy::Ipam::IpamHelper
13
15
 
14
16
  DEFAULT_CLEANUP_INTERVAL = 60
15
- @@ip_cache = nil
16
- @@timer_task = nil
17
-
18
- def initialize(params = {})
19
- @@m = Monitor.new
20
- @provider = params[:provider].to_s
21
- init_cache if @@ip_cache.nil?
22
- start_cleanup_task if @@timer_task.nil?
17
+
18
+ def initialize
19
+ @m = Monitor.new
20
+ init_cache
21
+ start_cleanup_task
22
+ end
23
+
24
+ def set_provider(provider)
25
+ @provider = provider
26
+ end
27
+
28
+ def get_provider
29
+ @provider
23
30
  end
24
31
 
25
32
  def set_group(group, value)
26
- @@ip_cache[group.to_sym] = value
33
+ @ip_cache[group.to_sym] = value
27
34
  end
28
35
 
29
36
  def get_group(group)
30
- @@ip_cache[group.to_sym]
37
+ @ip_cache[group.to_sym]
31
38
  end
32
39
 
33
40
  def get_cidr(group, cidr)
34
- @@ip_cache[group.to_sym][cidr.to_sym]
41
+ @ip_cache[group.to_sym][cidr.to_sym]
35
42
  end
36
43
 
37
44
  def get_ip(group_name, cidr, mac)
38
- @@ip_cache[group_name.to_sym][cidr.to_sym][mac.to_sym][:ip]
45
+ @ip_cache[group_name.to_sym][cidr.to_sym][mac.to_sym][:ip]
39
46
  end
40
47
 
41
48
  def get_cleanup_interval
@@ -43,27 +50,27 @@ module Proxy::Ipam
43
50
  end
44
51
 
45
52
  def ip_exists(ip, cidr, group_name)
46
- cidr_key = @@ip_cache[group_name.to_sym][cidr.to_sym]&.to_s
53
+ cidr_key = @ip_cache[group_name.to_sym][cidr.to_sym]&.to_s
47
54
  cidr_key.include?(ip.to_s)
48
55
  end
49
56
 
50
57
  def add(ip, mac, cidr, group_name)
51
- logger.debug("Adding IP '#{ip}' to cache for subnet '#{cidr}' in group '#{group_name}' for provider #{@provider}")
52
- @@m.synchronize do
58
+ logger.debug("Adding IP '#{ip}' to cache for subnet '#{cidr}' in group '#{group_name}' for IPAM provider #{@provider.to_s}")
59
+ @m.synchronize do
53
60
  mac_addr = mac.nil? || mac.empty? ? SecureRandom.uuid : mac
54
- group_hash = @@ip_cache[group_name.to_sym]
61
+ group_hash = @ip_cache[group_name.to_sym]
55
62
 
56
63
  group_hash.each do |key, values|
57
64
  if values.keys.include? mac_addr.to_sym
58
- @@ip_cache[group_name.to_sym][key].delete(mac_addr.to_sym)
65
+ @ip_cache[group_name.to_sym][key].delete(mac_addr.to_sym)
59
66
  end
60
- @@ip_cache[group_name.to_sym].delete(key) if @@ip_cache[group_name.to_sym][key].nil? || @@ip_cache[group_name.to_sym][key].empty?
67
+ @ip_cache[group_name.to_sym].delete(key) if @ip_cache[group_name.to_sym][key].nil? || @ip_cache[group_name.to_sym][key].empty?
61
68
  end
62
69
 
63
70
  if group_hash.key?(cidr.to_sym)
64
- @@ip_cache[group_name.to_sym][cidr.to_sym][mac_addr.to_sym] = {ip: ip.to_s, timestamp: Time.now.to_s}
71
+ @ip_cache[group_name.to_sym][cidr.to_sym][mac_addr.to_sym] = {ip: ip.to_s, timestamp: Time.now.to_s}
65
72
  else
66
- @@ip_cache = @@ip_cache.merge({group_name.to_sym => {cidr.to_sym => {mac_addr.to_sym => {ip: ip.to_s, timestamp: Time.now.to_s}}}})
73
+ @ip_cache = @ip_cache.merge({group_name.to_sym => {cidr.to_sym => {mac_addr.to_sym => {ip: ip.to_s, timestamp: Time.now.to_s}}}})
67
74
  end
68
75
  end
69
76
  end
@@ -71,12 +78,12 @@ module Proxy::Ipam
71
78
  private
72
79
 
73
80
  def start_cleanup_task
74
- logger.info("Starting ip cache maintenance for provider #{@provider}, used by /next_ip.")
75
- @@timer_task = Concurrent::TimerTask.new(execution_interval: DEFAULT_CLEANUP_INTERVAL) { init_cache }
76
- @@timer_task.execute
81
+ logger.info("Starting ip cache maintenance for IPAM provider #{@provider.to_s}, used by /next_ip.")
82
+ @timer_task = Concurrent::TimerTask.new(execution_interval: DEFAULT_CLEANUP_INTERVAL) { init_cache }
83
+ @timer_task.execute
77
84
  end
78
85
 
79
- # @@ip_cache structure
86
+ # @ip_cache structure
80
87
  #
81
88
  # Groups of subnets are cached under the External IPAM Group name. For example,
82
89
  # "IPAM Group Name" would be the section name in phpIPAM. All IP's cached for subnets
@@ -107,22 +114,22 @@ module Proxy::Ipam
107
114
  # }
108
115
  # }
109
116
  def init_cache
110
- @@m.synchronize do
111
- if @@ip_cache && !@@ip_cache.empty?
112
- logger.debug("Processing ip cache for provider #{@provider}")
113
- @@ip_cache.each do |group, subnets|
117
+ @m.synchronize do
118
+ if @ip_cache && !@ip_cache.empty?
119
+ logger.debug("Processing ip cache for IPAM provider #{@provider.to_s}")
120
+ @ip_cache.each do |group, subnets|
114
121
  subnets.each do |cidr, macs|
115
122
  macs.each do |mac, ip|
116
123
  if Time.now - Time.parse(ip[:timestamp]) > DEFAULT_CLEANUP_INTERVAL
117
- @@ip_cache[group][cidr].delete(mac)
124
+ @ip_cache[group][cidr].delete(mac)
118
125
  end
119
126
  end
120
- @@ip_cache[group].delete(cidr) if @@ip_cache[group][cidr].nil? || @@ip_cache[group][cidr].empty?
127
+ @ip_cache[group].delete(cidr) if @ip_cache[group][cidr].nil? || @ip_cache[group][cidr].empty?
121
128
  end
122
129
  end
123
130
  else
124
- logger.debug("Clearing ip cache for provider #{@provider}")
125
- @@ip_cache = {'': {}}
131
+ logger.debug("Clearing ip cache for IPAM provider #{@provider.to_s}")
132
+ @ip_cache = {'': {}}
126
133
  end
127
134
  end
128
135
  end
@@ -51,7 +51,7 @@ module Proxy::Ipam
51
51
  group_name = get_request_group(params)
52
52
 
53
53
  next_ip = provider.get_next_ip(mac, cidr, group_name)
54
- halt 404, { error: errors[:no_free_ips] }.to_json if next_ip.nil?
54
+ halt 404, { error: ERRORS[:no_free_ips] }.to_json if next_ip.nil?
55
55
  next_ip.to_json
56
56
  rescue Proxy::Validations::Error => e
57
57
  logger.warn(e.message)
@@ -60,8 +60,8 @@ module Proxy::Ipam
60
60
  logger.warn(e.message)
61
61
  halt 500, { error: e.message }.to_json
62
62
  rescue Errno::ECONNREFUSED, Errno::ECONNRESET
63
- logger.warn(errors[:no_connection])
64
- halt 500, { error: errors[:no_connection] }.to_json
63
+ logger.warn(ERRORS[:no_connection])
64
+ halt 500, { error: ERRORS[:no_connection] }.to_json
65
65
  end
66
66
  end
67
67
 
@@ -98,7 +98,7 @@ module Proxy::Ipam
98
98
  group_name = get_request_group(params)
99
99
  subnet = provider.get_ipam_subnet(cidr, group_name)
100
100
 
101
- halt 404, { error: errors[:no_subnet] }.to_json if subnet.nil?
101
+ halt 404, { error: ERRORS[:no_subnet] }.to_json if subnet.nil?
102
102
  subnet.to_json
103
103
  rescue Proxy::Validations::Error => e
104
104
  logger.warn(e.message)
@@ -107,8 +107,8 @@ module Proxy::Ipam
107
107
  logger.warn(e.message)
108
108
  halt 500, { error: e.message }.to_json
109
109
  rescue Errno::ECONNREFUSED, Errno::ECONNRESET
110
- logger.warn(errors[:no_connection])
111
- halt 500, { error: errors[:no_connection] }.to_json
110
+ logger.warn(ERRORS[:no_connection])
111
+ halt 500, { error: ERRORS[:no_connection] }.to_json
112
112
  end
113
113
  end
114
114
 
@@ -139,9 +139,8 @@ module Proxy::Ipam
139
139
  content_type :json
140
140
 
141
141
  begin
142
- halt 500, { error: errors[:groups_not_supported] }.to_json unless provider.groups_supported?
142
+ halt 500, { error: ERRORS[:groups_not_supported] }.to_json unless provider.groups_supported?
143
143
  groups = provider.get_ipam_groups
144
- halt 404, { error: errors[:no_groups] }.to_json if groups.nil?
145
144
  groups.to_json
146
145
  rescue Proxy::Validations::Error => e
147
146
  logger.warn(e.message)
@@ -150,8 +149,8 @@ module Proxy::Ipam
150
149
  logger.warn(e.message)
151
150
  halt 500, { error: e.message }.to_json
152
151
  rescue Errno::ECONNREFUSED, Errno::ECONNRESET
153
- logger.warn(errors[:no_connection])
154
- halt 500, { error: errors[:no_connection] }.to_json
152
+ logger.warn(ERRORS[:no_connection])
153
+ halt 500, { error: ERRORS[:no_connection] }.to_json
155
154
  end
156
155
  end
157
156
 
@@ -186,7 +185,7 @@ module Proxy::Ipam
186
185
  group_name = get_request_group(params)
187
186
  group = provider.get_ipam_group(group_name)
188
187
 
189
- halt 404, { error: errors[:no_group] }.to_json if group.nil?
188
+ halt 404, { error: ERRORS[:no_group] }.to_json if group.nil?
190
189
  group.to_json
191
190
  rescue Proxy::Validations::Error => e
192
191
  logger.warn(e.message)
@@ -195,8 +194,8 @@ module Proxy::Ipam
195
194
  logger.warn(e.message)
196
195
  halt 500, { error: e.message }.to_json
197
196
  rescue Errno::ECONNREFUSED, Errno::ECONNRESET
198
- logger.warn(errors[:no_connection])
199
- halt 500, { error: errors[:no_connection] }.to_json
197
+ logger.warn(ERRORS[:no_connection])
198
+ halt 500, { error: ERRORS[:no_connection] }.to_json
200
199
  end
201
200
  end
202
201
 
@@ -234,7 +233,7 @@ module Proxy::Ipam
234
233
  group_name = get_request_group(params)
235
234
  subnets = provider.get_ipam_subnets(group_name)
236
235
 
237
- halt 404, { error: errors[:no_subnets_in_group] }.to_json if subnets.nil?
236
+ halt 404, { error: ERRORS[:no_subnets_in_group] }.to_json if subnets.nil?
238
237
  subnets.to_json
239
238
  rescue Proxy::Validations::Error => e
240
239
  logger.warn(e.message)
@@ -243,8 +242,8 @@ module Proxy::Ipam
243
242
  logger.warn(e.message)
244
243
  halt 500, { error: e.message }.to_json
245
244
  rescue Errno::ECONNREFUSED, Errno::ECONNRESET
246
- logger.warn(errors[:no_connection])
247
- halt 500, { error: errors[:no_connection] }.to_json
245
+ logger.warn(ERRORS[:no_connection])
246
+ halt 500, { error: ERRORS[:no_connection] }.to_json
248
247
  end
249
248
  end
250
249
 
@@ -276,7 +275,7 @@ module Proxy::Ipam
276
275
  group_name = get_request_group(params)
277
276
  subnet = provider.get_ipam_subnet(cidr, group_name)
278
277
 
279
- halt 404, { error: errors[:no_subnet] }.to_json if subnet.nil?
278
+ halt 404, { error: ERRORS[:no_subnet] }.to_json if subnet.nil?
280
279
  validate_ip_in_cidr!(ip, cidr)
281
280
  ip_exists = provider.ip_exists?(ip, subnet[:id], group_name)
282
281
  halt 200, ip_exists.to_json
@@ -287,8 +286,8 @@ module Proxy::Ipam
287
286
  logger.warn(e.message)
288
287
  halt 500, { error: e.message }.to_json
289
288
  rescue Errno::ECONNREFUSED, Errno::ECONNRESET
290
- logger.warn(errors[:no_connection])
291
- halt 500, { error: errors[:no_connection] }.to_json
289
+ logger.warn(ERRORS[:no_connection])
290
+ halt 500, { error: ERRORS[:no_connection] }.to_json
292
291
  end
293
292
  end
294
293
 
@@ -321,13 +320,13 @@ module Proxy::Ipam
321
320
  group_name = get_request_group(params)
322
321
  subnet = provider.get_ipam_subnet(cidr, group_name)
323
322
 
324
- halt 404, { error: errors[:no_subnet] }.to_json if subnet.nil?
323
+ halt 404, { error: ERRORS[:no_subnet] }.to_json if subnet.nil?
325
324
  add_ip_params = { cidr: cidr, subnet_id: subnet[:id], group_name: group_name }
326
325
  validate_ip_in_cidr!(ip, cidr)
327
326
 
328
327
  ip_added = provider.add_ip_to_subnet(ip, add_ip_params) # Returns nil on success
329
328
  halt 500, ip_added.to_json unless ip_added.nil?
330
- halt 201
329
+ status 201
331
330
  rescue Proxy::Validations::Error => e
332
331
  logger.warn(e.message)
333
332
  halt 400, { error: e.to_s }.to_json
@@ -335,8 +334,8 @@ module Proxy::Ipam
335
334
  logger.warn(e.message)
336
335
  halt 500, { error: e.message }.to_json
337
336
  rescue Errno::ECONNREFUSED, Errno::ECONNRESET
338
- logger.warn(errors[:no_connection])
339
- halt 500, { error: errors[:no_connection] }.to_json
337
+ logger.warn(ERRORS[:no_connection])
338
+ halt 500, { error: ERRORS[:no_connection] }.to_json
340
339
  end
341
340
  end
342
341
 
@@ -369,13 +368,13 @@ module Proxy::Ipam
369
368
  group_name = get_request_group(params)
370
369
  subnet = provider.get_ipam_subnet(cidr, group_name)
371
370
 
372
- halt 404, { error: errors[:no_subnet] }.to_json if subnet.nil?
371
+ halt 404, { error: ERRORS[:no_subnet] }.to_json if subnet.nil?
373
372
  del_ip_params = { cidr: cidr, subnet_id: subnet[:id], group_name: group_name }
374
373
  validate_ip_in_cidr!(ip, cidr)
375
374
 
376
375
  ip_deleted = provider.delete_ip_from_subnet(ip, del_ip_params) # Returns nil on success
377
376
  halt 500, ip_deleted.to_json unless ip_deleted.nil?
378
- halt 200
377
+ halt 204
379
378
  rescue Proxy::Validations::Error => e
380
379
  logger.warn(e.message)
381
380
  halt 400, { error: e.to_s }.to_json
@@ -383,8 +382,8 @@ module Proxy::Ipam
383
382
  logger.warn(e.message)
384
383
  halt 500, { error: e.message }.to_json
385
384
  rescue Errno::ECONNREFUSED, Errno::ECONNRESET
386
- logger.warn(errors[:no_connection])
387
- halt 500, { error: errors[:no_connection] }.to_json
385
+ logger.warn(ERRORS[:no_connection])
386
+ halt 500, { error: ERRORS[:no_connection] }.to_json
388
387
  end
389
388
  end
390
389
  end
@@ -3,12 +3,31 @@ module Proxy::Ipam::IpamHelper
3
3
  include ::Proxy::Validations
4
4
 
5
5
  MAX_IP_RETRIES = 5
6
+ ERRORS = {
7
+ cidr: "A 'cidr' parameter for the subnet must be provided(e.g. IPv4: 100.10.10.0/24, IPv6: 2001:db8:abcd:12::/124)",
8
+ mac: "A 'mac' address must be provided(e.g. 00:0a:95:9d:68:10)",
9
+ ip: "Missing 'ip' parameter. An IPv4 or IPv6 address must be provided(e.g. IPv4: 100.10.10.22, IPv6: 2001:db8:abcd:12::3)",
10
+ group_name: "A 'group_name' must be provided",
11
+ no_ip: 'IP address not found',
12
+ no_free_ips: 'No free addresses found',
13
+ no_connection: 'Unable to connect to External IPAM server',
14
+ no_group: 'Group not found in External IPAM',
15
+ no_groups: 'No groups found in External IPAM',
16
+ no_subnet: 'Subnet not found in External IPAM',
17
+ no_subnets_in_group: 'No subnets found in External IPAM group',
18
+ provider: "The IPAM provider must be specified(e.g. 'phpipam' or 'netbox')",
19
+ groups_not_supported: 'Groups are not supported',
20
+ add_ip: 'Error adding IP to External IPAM',
21
+ bad_mac: 'Mac address is invalid',
22
+ bad_ip: 'IP address is invalid',
23
+ bad_cidr: 'The network cidr is invalid'
24
+ }.freeze
6
25
 
7
26
  def provider
8
27
  @provider ||=
9
28
  begin
10
29
  unless client.authenticated?
11
- halt 500, {error: 'Invalid credentials for External IPAM'}.to_json
30
+ halt 500, { error: 'Invalid credentials for External IPAM' }.to_json
12
31
  end
13
32
  client
14
33
  end
@@ -71,7 +90,7 @@ module Proxy::Ipam::IpamHelper
71
90
  end
72
91
  end
73
92
 
74
- next_ip
93
+ {data: next_ip}
75
94
  end
76
95
 
77
96
  def increment_ip(ip)
@@ -88,26 +107,4 @@ module Proxy::Ipam::IpamHelper
88
107
  halt 500, { error: errors[:groups_not_supported] }.to_json if group && !provider.groups_supported?
89
108
  group
90
109
  end
91
-
92
- def errors
93
- {
94
- cidr: "A 'cidr' parameter for the subnet must be provided(e.g. IPv4: 100.10.10.0/24, IPv6: 2001:db8:abcd:12::/124)",
95
- mac: "A 'mac' address must be provided(e.g. 00:0a:95:9d:68:10)",
96
- ip: "Missing 'ip' parameter. An IPv4 or IPv6 address must be provided(e.g. IPv4: 100.10.10.22, IPv6: 2001:db8:abcd:12::3)",
97
- group_name: "A 'group_name' must be provided",
98
- no_ip: 'IP address not found',
99
- no_free_ips: 'No free addresses found',
100
- no_connection: 'Unable to connect to External IPAM server',
101
- no_group: 'Group not found in External IPAM',
102
- no_groups: 'No groups found in External IPAM',
103
- no_subnet: 'Subnet not found in External IPAM',
104
- no_subnets_in_group: 'No subnets found in External IPAM group',
105
- provider: "The IPAM provider must be specified(e.g. 'phpipam' or 'netbox')",
106
- groups_not_supported: 'Groups are not supported',
107
- add_ip: 'Error adding IP to External IPAM',
108
- bad_mac: 'Mac address is invalid',
109
- bad_ip: 'IP address is invalid',
110
- bad_cidr: 'The network cidr is invalid'
111
- }
112
- end
113
110
  end
@@ -17,7 +17,7 @@ module Proxy::Ipam::IpamValidator
17
17
 
18
18
  def validate_ip!(ip)
19
19
  good_ip = ip =~ Regexp.union([Resolv::IPv4::Regex, Resolv::IPv6::Regex])
20
- raise Proxy::Validations::Error, errors[:bad_ip] if good_ip.nil?
20
+ raise Proxy::Validations::Error, ERRORS[:bad_ip] if good_ip.nil?
21
21
  ip
22
22
  end
23
23
 
@@ -39,9 +39,9 @@ module Proxy::Ipam::IpamValidator
39
39
  end
40
40
 
41
41
  def validate_mac!(mac)
42
- raise Proxy::Validations::Error.new, errors[:mac] if mac.nil? || mac.empty?
42
+ raise Proxy::Validations::Error.new, ERRORS[:mac] if mac.nil? || mac.empty?
43
43
  unless mac.match(/^([0-9a-fA-F]{2}[:]){5}[0-9a-fA-F]{2}$/i)
44
- raise Proxy::Validations::Error.new, errors[:bad_mac]
44
+ raise Proxy::Validations::Error.new, ERRORS[:bad_mac]
45
45
  end
46
46
  mac
47
47
  end
@@ -16,13 +16,12 @@ module Proxy::Netbox
16
16
  include Proxy::Ipam::IpamHelper
17
17
  include Proxy::Ipam::IpamValidator
18
18
 
19
- @ip_cache = nil
20
-
21
19
  def initialize(conf)
22
20
  @api_base = "#{conf[:url]}/api/"
23
21
  @token = conf[:token]
24
- @api_resource = Proxy::Ipam::ApiResource.new(api_base: @api_base, token: 'Token ' + @token)
25
- @ip_cache = Proxy::Ipam::IpCache.new(provider: 'netbox')
22
+ @api_resource = Proxy::Ipam::ApiResource.new(api_base: @api_base, token: "Token #{@token}")
23
+ @ip_cache = Proxy::Ipam::IpCache.instance
24
+ @ip_cache.set_provider('netbox')
26
25
  end
27
26
 
28
27
  def get_ipam_subnet(cidr, group_name = nil)
@@ -35,7 +34,8 @@ module Proxy::Netbox
35
34
  end
36
35
 
37
36
  def get_ipam_subnet_by_group(cidr, group_id)
38
- response = @api_resource.get("ipam/prefixes/?status=active&prefix=#{cidr}&vrf_id=#{group_id}")
37
+ params = URI.encode_www_form({ status: 'active', prefix: cidr, vrf_id: group_id })
38
+ response = @api_resource.get("ipam/prefixes/?#{params}")
39
39
  json_body = JSON.parse(response.body)
40
40
  return nil if json_body['count'].zero?
41
41
  subnet = subnet_from_result(json_body['results'][0])
@@ -43,7 +43,8 @@ module Proxy::Netbox
43
43
  end
44
44
 
45
45
  def get_ipam_subnet_by_cidr(cidr)
46
- response = @api_resource.get("ipam/prefixes/?status=active&prefix=#{cidr}")
46
+ params = URI.encode_www_form({ status: 'active', prefix: cidr })
47
+ response = @api_resource.get("ipam/prefixes/?#{params}")
47
48
  json_body = JSON.parse(response.body)
48
49
  return nil if json_body['count'].zero?
49
50
  subnet = subnet_from_result(json_body['results'][0])
@@ -55,7 +56,7 @@ module Proxy::Netbox
55
56
  json_body = JSON.parse(response.body)
56
57
  groups = []
57
58
 
58
- return nil if json_body['count'].zero?
59
+ return groups if json_body['count'].zero?
59
60
 
60
61
  json_body['results'].each do |group|
61
62
  groups.push({
@@ -68,8 +69,9 @@ module Proxy::Netbox
68
69
  end
69
70
 
70
71
  def get_ipam_group(group_name)
71
- raise errors[:groups_not_supported] unless groups_supported?
72
- response = @api_resource.get("ipam/vrfs/?name=#{group_name}")
72
+ raise ERRORS[:groups_not_supported] unless groups_supported?
73
+ params = URI.encode_www_form({ name: group_name })
74
+ response = @api_resource.get("ipam/vrfs/?#{params}")
73
75
  json_body = JSON.parse(response.body)
74
76
  return nil if json_body['count'].zero?
75
77
 
@@ -85,18 +87,19 @@ module Proxy::Netbox
85
87
  def get_group_id(group_name)
86
88
  return nil if group_name.nil? || group_name.empty?
87
89
  group = get_ipam_group(group_name)
88
- raise errors[:no_group] if group.nil?
90
+ raise ERRORS[:no_group] if group.nil?
89
91
  group[:id]
90
92
  end
91
93
 
92
94
  def get_ipam_subnets(group_name)
93
95
  if group_name.nil?
94
- response = @api_resource.get('ipam/prefixes/?status=active')
96
+ params = URI.encode_www_form({ status: 'active' })
95
97
  else
96
98
  group_id = get_group_id(group_name)
97
- response = @api_resource.get("ipam/prefixes/?status=active&vrf_id=#{group_id}")
99
+ params = URI.encode_www_form({ status: 'active', vrf_id: group_id })
98
100
  end
99
101
 
102
+ response = @api_resource.get("ipam/prefixes/?#{params}")
100
103
  json_body = JSON.parse(response.body)
101
104
  return nil if json_body['count'].zero?
102
105
  subnets = []
@@ -115,9 +118,9 @@ module Proxy::Netbox
115
118
 
116
119
  def ip_exists?(ip, subnet_id, group_name)
117
120
  group_id = get_group_id(group_name)
118
- url = "ipam/ip-addresses/?address=#{ip}"
119
- url += "&prefix_id=#{subnet_id}" unless subnet_id.nil?
120
- url += "&vrf_id=#{group_id}" unless group_id.nil?
121
+ url = "ipam/ip-addresses/?#{URI.encode_www_form({ address: ip })}"
122
+ url += "&#{URI.encode_www_form({ prefix_id: subnet_id })}" unless subnet_id.nil?
123
+ url += "&#{URI.encode_www_form({ vrf_id: group_id })}" unless group_id.nil?
121
124
  response = @api_resource.get(url)
122
125
  json_body = JSON.parse(response.body)
123
126
  return false if json_body['count'].zero?
@@ -145,15 +148,16 @@ module Proxy::Netbox
145
148
  group_name = params[:group_name]
146
149
 
147
150
  if group_name.nil? || group_name.empty?
148
- response = @api_resource.get("ipam/ip-addresses/?address=#{ip}")
151
+ params = URI.encode_www_form({ address: ip })
149
152
  else
150
153
  group_id = get_group_id(group_name)
151
- response = @api_resource.get("ipam/ip-addresses/?address=#{ip}&vrf_id=#{group_id}")
154
+ params = URI.encode_www_form({ address: ip, vrf_id: group_id })
152
155
  end
153
156
 
157
+ response = @api_resource.get("ipam/ip-addresses/?#{params}")
154
158
  json_body = JSON.parse(response.body)
155
159
 
156
- return { error: errors[:no_ip] } if json_body['count'].zero?
160
+ return { error: ERRORS[:no_ip] } if json_body['count'].zero?
157
161
 
158
162
  address_id = json_body['results'][0]['id']
159
163
  response = @api_resource.delete("ipam/ip-addresses/#{address_id}/")
@@ -163,12 +167,13 @@ module Proxy::Netbox
163
167
 
164
168
  def get_next_ip(mac, cidr, group_name)
165
169
  subnet = get_ipam_subnet(cidr, group_name)
166
- raise errors[:no_subnet] if subnet.nil?
170
+ raise ERRORS[:no_subnet] if subnet.nil?
167
171
  response = @api_resource.get("ipam/prefixes/#{subnet[:id]}/available-ips/?limit=1")
168
172
  json_body = JSON.parse(response.body)
169
173
  return nil if json_body.empty?
170
174
  ip = json_body[0]['address'].split('/').first
171
- cache_next_ip(@ip_cache, ip, mac, cidr, subnet[:id], group_name)
175
+ next_ip = cache_next_ip(@ip_cache, ip, mac, cidr, subnet[:id], group_name)
176
+ { data: next_ip }
172
177
  end
173
178
 
174
179
  def groups_supported?
@@ -16,14 +16,13 @@ module Proxy::Phpipam
16
16
  include Proxy::Ipam::IpamHelper
17
17
  include Proxy::Ipam::IpamValidator
18
18
 
19
- @ip_cache = nil
20
-
21
19
  def initialize(conf)
22
20
  @conf = conf
23
21
  @api_base = "#{@conf[:url]}/api/#{@conf[:user]}/"
24
22
  @token = authenticate
25
23
  @api_resource = Proxy::Ipam::ApiResource.new(api_base: @api_base, token: @token, auth_header: 'Token')
26
- @ip_cache = Proxy::Ipam::IpCache.new(provider: 'phpipam')
24
+ @ip_cache = Proxy::Ipam::IpCache.instance
25
+ @ip_cache.set_provider('phpipam')
27
26
  end
28
27
 
29
28
  def get_ipam_subnet(cidr, group_name = nil)
@@ -41,7 +40,7 @@ module Proxy::Phpipam
41
40
  subnet_id = nil
42
41
 
43
42
  subnets.each do |subnet|
44
- subnet_cidr = subnet[:subnet] + '/' + subnet[:mask]
43
+ subnet_cidr = "#{subnet[:subnet]}/#{subnet[:mask]}"
45
44
  subnet_id = subnet[:id] if subnet_cidr == cidr
46
45
  end
47
46
 
@@ -78,7 +77,7 @@ module Proxy::Phpipam
78
77
  return nil if group_name.nil?
79
78
  group = @api_resource.get("sections/#{group_name}/")
80
79
  json_body = JSON.parse(group.body)
81
- raise errors[:no_group] if json_body['data'].nil?
80
+ raise ERRORS[:no_group] if json_body['data'].nil?
82
81
 
83
82
  data = {
84
83
  id: json_body['data']['id'],
@@ -92,7 +91,7 @@ module Proxy::Phpipam
92
91
  def get_ipam_groups
93
92
  groups = @api_resource.get('sections/')
94
93
  json_body = JSON.parse(groups.body)
95
- return nil if json_body['data'].nil?
94
+ return [] if json_body['data'].nil?
96
95
 
97
96
  data = []
98
97
  json_body['data'].each do |group|
@@ -108,7 +107,7 @@ module Proxy::Phpipam
108
107
 
109
108
  def get_ipam_subnets(group_name)
110
109
  group = get_ipam_group(group_name)
111
- raise errors[:no_group] if group.nil?
110
+ raise ERRORS[:no_group] if group.nil?
112
111
  subnets = @api_resource.get("sections/#{group[:id]}/subnets/")
113
112
  json_body = JSON.parse(subnets.body)
114
113
  return nil if json_body['data'].nil?
@@ -149,12 +148,13 @@ module Proxy::Phpipam
149
148
 
150
149
  def get_next_ip(mac, cidr, group_name)
151
150
  subnet = get_ipam_subnet(cidr, group_name)
152
- raise errors[:no_subnet] if subnet.nil?
151
+ raise ERRORS[:no_subnet] if subnet.nil?
153
152
  response = @api_resource.get("subnets/#{subnet[:id]}/first_free/")
154
153
  json_body = JSON.parse(response.body)
155
154
  return { error: json_body['message'] } if json_body['message']
156
155
  ip = json_body['data']
157
- cache_next_ip(@ip_cache, ip, mac, cidr, subnet[:id], group_name)
156
+ next_ip = cache_next_ip(@ip_cache, ip, mac, cidr, subnet[:id], group_name)
157
+ { data: next_ip }
158
158
  end
159
159
 
160
160
  def groups_supported?
@@ -168,7 +168,7 @@ module Proxy::Phpipam
168
168
  private
169
169
 
170
170
  def authenticate
171
- auth_uri = URI(@api_base + '/user/')
171
+ auth_uri = URI("#{@api_base}/user/")
172
172
  request = Net::HTTP::Post.new(auth_uri)
173
173
  request.basic_auth @conf[:user], @conf[:password]
174
174
 
@@ -1,5 +1,5 @@
1
1
  module Proxy
2
2
  module Ipam
3
- VERSION = '0.1.0'.freeze
3
+ VERSION = '0.1.1'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smart_proxy_ipam
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christopher Smith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-09 00:00:00.000000000 Z
11
+ date: 2020-12-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Smart proxy plugin for IPAM integration with various IPAM providers
13
+ description: Smart proxy plugin for integration with various External IPAM providers
14
14
  email: chrisjsmith001@gmail.com
15
15
  executables: []
16
16
  extensions: []
@@ -60,5 +60,5 @@ requirements: []
60
60
  rubygems_version: 3.0.6
61
61
  signing_key:
62
62
  specification_version: 4
63
- summary: Smart proxy plugin for IPAM integration with various IPAM providers
63
+ summary: Smart proxy plugin for integration with External IPAM providers
64
64
  test_files: []