mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-04-24 19:31:26 -07:00
* WIP adds network subnetting functions * adds functions to convert between netmask and masklen * adds functions to verify netmask and masklen * adds function to dtermine network and subnet from address / mask pair * network_common: add a function to get the first 48 bits in a IPv6 address. ec2_group: only use network bits of a CIDR. * Add tests for CIDRs with host bits set. * ec2_group: add warning if CIDR isn't the networking address. * Fix pep8. * Improve wording. * fix import for network utils * Update tests to use pytest instead of unittest * add test for to_ipv6_network() * Fix PEP8
This commit is contained in:
parent
5f215337c9
commit
d877c146ab
4 changed files with 385 additions and 101 deletions
|
@ -31,8 +31,11 @@ import operator
|
|||
import socket
|
||||
|
||||
from itertools import chain
|
||||
from struct import pack
|
||||
from socket import inet_aton, inet_ntoa
|
||||
|
||||
from ansible.module_utils.six import iteritems, string_types
|
||||
from ansible.module_utils.six.moves import zip
|
||||
from ansible.module_utils.basic import AnsibleFallbackNotFound
|
||||
|
||||
try:
|
||||
|
@ -45,6 +48,7 @@ except ImportError:
|
|||
|
||||
OPERATORS = frozenset(['ge', 'gt', 'eq', 'neq', 'lt', 'le'])
|
||||
ALIASES = frozenset([('min', 'ge'), ('max', 'le'), ('exactly', 'eq'), ('neq', 'ne')])
|
||||
VALID_MASKS = [2**8 - 2**i for i in range(0, 9)]
|
||||
|
||||
|
||||
def to_list(val):
|
||||
|
@ -426,3 +430,106 @@ class Template:
|
|||
if marker in data:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def is_netmask(val):
|
||||
parts = str(val).split('.')
|
||||
if not len(parts) == 4:
|
||||
return False
|
||||
for part in parts:
|
||||
try:
|
||||
if int(part) not in VALID_MASKS:
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def is_masklen(val):
|
||||
try:
|
||||
return 0 <= int(val) <= 32
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
|
||||
def to_bits(val):
|
||||
""" converts a netmask to bits """
|
||||
bits = ''
|
||||
for octet in val.split('.'):
|
||||
bits += bin(int(octet))[2:].zfill(8)
|
||||
return str
|
||||
|
||||
|
||||
def to_netmask(val):
|
||||
""" converts a masklen to a netmask """
|
||||
if not is_masklen(val):
|
||||
raise ValueError('invalid value for masklen')
|
||||
|
||||
bits = 0
|
||||
for i in range(32 - int(val), 32):
|
||||
bits |= (1 << i)
|
||||
|
||||
return inet_ntoa(pack('>I', bits))
|
||||
|
||||
|
||||
def to_masklen(val):
|
||||
""" converts a netmask to a masklen """
|
||||
if not is_netmask(val):
|
||||
raise ValueError('invalid value for netmask: %s' % val)
|
||||
|
||||
bits = list()
|
||||
for x in val.split('.'):
|
||||
octet = bin(int(x)).count('1')
|
||||
bits.append(octet)
|
||||
|
||||
return sum(bits)
|
||||
|
||||
|
||||
def to_subnet(addr, mask, dotted_notation=False):
|
||||
""" coverts an addr / mask pair to a subnet in cidr notation """
|
||||
try:
|
||||
if not is_masklen(mask):
|
||||
raise ValueError
|
||||
cidr = int(mask)
|
||||
mask = to_netmask(mask)
|
||||
except ValueError:
|
||||
cidr = to_masklen(mask)
|
||||
|
||||
addr = addr.split('.')
|
||||
mask = mask.split('.')
|
||||
|
||||
network = list()
|
||||
for s_addr, s_mask in zip(addr, mask):
|
||||
network.append(str(int(s_addr) & int(s_mask)))
|
||||
|
||||
if dotted_notation:
|
||||
return '%s %s' % ('.'.join(network), to_netmask(cidr))
|
||||
return '%s/%s' % ('.'.join(network), cidr)
|
||||
|
||||
|
||||
def to_ipv6_network(addr):
|
||||
""" IPv6 addresses are eight groupings. The first three groupings (48 bits) comprise the network address. """
|
||||
|
||||
# Split by :: to identify omitted zeros
|
||||
ipv6_prefix = addr.split('::')[0]
|
||||
|
||||
# Get the first three groups, or as many as are found + ::
|
||||
found_groups = []
|
||||
for group in ipv6_prefix.split(':'):
|
||||
found_groups.append(group)
|
||||
if len(found_groups) == 3:
|
||||
break
|
||||
if len(found_groups) < 3:
|
||||
found_groups.append('::')
|
||||
|
||||
# Concatenate network address parts
|
||||
network_addr = ''
|
||||
for group in found_groups:
|
||||
if group != '::':
|
||||
network_addr += str(group)
|
||||
network_addr += str(':')
|
||||
|
||||
# Ensure network address ends with ::
|
||||
if not network_addr.endswith('::'):
|
||||
network_addr += str(':')
|
||||
return network_addr
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue