Module: Proxy::Ipam::IpamHelper
- Includes:
- Validations
- Included in:
- Api, ApiResource, IpCache, IpamValidator, Netbox::NetboxClient, Phpipam::PhpipamClient
- Defined in:
- lib/smart_proxy_ipam/ipam_helper.rb
Overview
Module containing helper methods for use by all External IPAM provider implementations
Constant Summary collapse
- MAX_IP_RETRIES =
5
- ERRORS =
{ cidr: "A 'cidr' parameter for the subnet must be provided(e.g. IPv4: 100.10.10.0/24, IPv6: 2001:db8:abcd:12::/124)", mac: "A 'mac' address must be provided(e.g. 00:0a:95:9d:68:10)", 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)", group_name: "A 'group_name' must be provided", no_ip: 'IP address not found', no_free_ips: 'No free addresses found', no_connection: 'Unable to connect to External IPAM server', no_group: 'Group not found in External IPAM', no_groups: 'No groups found in External IPAM', no_subnet: 'Subnet not found in External IPAM', no_subnets_in_group: 'No subnets found in External IPAM group', provider: "The IPAM provider must be specified(e.g. 'phpipam' or 'netbox')", groups_not_supported: 'Groups are not supported', add_ip: 'Error adding IP to External IPAM', bad_mac: 'Mac address is invalid', bad_ip: 'IP address is invalid', bad_cidr: 'The network cidr is invalid' }.freeze
Instance Method Summary collapse
-
#cache_next_ip(ip_cache, ip, mac, cidr, subnet_id, group_name) ⇒ Object
Checks the cache for existing ip, and returns it if it exists.
-
#find_new_ip(ip_cache, subnet_id, ip, mac, cidr, group_name) ⇒ Object
Called when next available IP from External IPAM has been cached by another user/host, but not actually persisted in External IPAM yet.
- #get_request_group(params) ⇒ Object
- #increment_ip(ip) ⇒ Object
- #provider ⇒ Object
- #usable_ip(ip, cidr) ⇒ Object
Instance Method Details
#cache_next_ip(ip_cache, ip, mac, cidr, subnet_id, group_name) ⇒ Object
Checks the cache for existing ip, and returns it if it exists. If not exists, it will find a new ip (using find_new_ip), and it is added to the cache.
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/smart_proxy_ipam/ipam_helper.rb', line 69 def cache_next_ip(ip_cache, ip, mac, cidr, subnet_id, group_name) group = group_name.nil? ? '' : group_name ip_cache.set_group(group, {}) if ip_cache.get_group(group).nil? subnet_hash = ip_cache.get_cidr(group, cidr) next_ip = nil if mac && subnet_hash&.key?(mac.to_sym) next_ip = ip_cache.get_ip(group, cidr, mac) else new_ip = ip ip_not_in_cache = subnet_hash.nil? ? true : !subnet_hash.to_s.include?(new_ip.to_s) if ip_not_in_cache next_ip = new_ip.to_s ip_cache.add(new_ip, mac, cidr, group) else next_ip = find_new_ip(ip_cache, subnet_id, new_ip, mac, cidr, group) end unless usable_ip(next_ip, cidr) return { error: "No free addresses found in subnet #{cidr}. Some available ip's may be cached. Try again in #{@ip_cache.get_cleanup_interval} seconds after cache is cleared." } end end next_ip end |
#find_new_ip(ip_cache, subnet_id, ip, mac, cidr, group_name) ⇒ Object
Called when next available IP from External IPAM has been cached by another user/host, but not actually persisted in External IPAM yet. This method will increment the IP, up to MAX_IP_RETRIES times, and check if it is available in External IPAM each iteration. It will return the original IP(the ‘ip’ param) if no new IP’s are found after MAX_IP_RETRIES iterations.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/smart_proxy_ipam/ipam_helper.rb', line 41 def find_new_ip(ip_cache, subnet_id, ip, mac, cidr, group_name) found_ip = nil temp_ip = ip retry_count = 0 loop do new_ip = increment_ip(temp_ip) ipam_ip = ip_exists?(new_ip, subnet_id, group_name) # If new IP doesn't exist in IPAM and not in the cache if !ipam_ip && !ip_cache.ip_exists(new_ip, cidr, group_name) found_ip = new_ip.to_s ip_cache.add(found_ip, mac, cidr, group_name) break end temp_ip = new_ip retry_count += 1 break if retry_count >= MAX_IP_RETRIES end return ip if found_ip.nil? found_ip end |
#get_request_group(params) ⇒ Object
105 106 107 108 109 |
# File 'lib/smart_proxy_ipam/ipam_helper.rb', line 105 def get_request_group(params) group = params[:group] ? URI.escape(URI.decode(params[:group])) : nil halt 500, { error: errors[:groups_not_supported] }.to_json if group && !provider.groups_supported? group end |
#increment_ip(ip) ⇒ Object
96 97 98 |
# File 'lib/smart_proxy_ipam/ipam_helper.rb', line 96 def increment_ip(ip) IPAddr.new(ip.to_s).succ.to_s end |
#provider ⇒ Object
26 27 28 29 30 31 32 33 34 |
# File 'lib/smart_proxy_ipam/ipam_helper.rb', line 26 def provider @provider ||= begin unless client.authenticated? halt 500, { error: 'Invalid credentials for External IPAM' }.to_json end client end end |
#usable_ip(ip, cidr) ⇒ Object
100 101 102 103 |
# File 'lib/smart_proxy_ipam/ipam_helper.rb', line 100 def usable_ip(ip, cidr) network = IPAddr.new(cidr) network.include?(IPAddr.new(ip)) && network.to_range.last != ip end |