smart_proxy_ipam 0.1.0 → 0.1.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 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: []