예제 #1
0
 def allowed_addresses(self):
     if self._values['allowed_addresses'] is None:
         return None
     result = []
     addresses = self._values['allowed_addresses']
     if isinstance(addresses, string_types):
         if addresses in ['', 'none']:
             return []
         else:
             addresses = [addresses]
     if len(addresses) == 1 and addresses[0] in ['default', '']:
         result = ['127.0.0.0/8']
         return result
     for address in addresses:
         try:
             # Check for valid IPv4 or IPv6 entries
             ip_network(u'%s' % str(address))
             result.append(address)
         except ValueError:
             # else fallback to checking reasonably well formatted hostnames
             if is_valid_hostname(address):
                 result.append(str(address))
                 continue
             raise F5ModuleError(
                 "The provided 'allowed_address' value {0} is not a valid IP or hostname"
                 .format(address))
     result = list(set(result))
     result.sort()
     return result
예제 #2
0
    def _check_overlaps(self, ipfield, netfield):
        """ check new address does not overlaps with one existing """

        if not self.obj.get(ipfield) or self.obj.get(netfield) is None:
            return

        our_addr = ip_network(u'{0}/{1}'.format(self.obj[ipfield],
                                                self.obj[netfield]),
                              strict=False)

        for iface in self.root_elt:
            if iface == self.target_elt:
                continue

            ipaddr_elt = iface.find(ipfield)
            subnet_elt = iface.find(netfield)
            if ipaddr_elt is None or subnet_elt is None or ipaddr_elt.text in [
                    'dhcp', None
            ] or ipaddr_elt.text in ['dhcpv6', None]:
                continue

            other_addr = ip_network(u'{0}/{1}'.format(ipaddr_elt.text,
                                                      subnet_elt.text),
                                    strict=False)
            if our_addr.overlaps(other_addr):
                descr_elt = iface.find('descr')
                if descr_elt is not None and descr_elt.text:
                    ifname = descr_elt.text
                else:
                    ifname = iface.tag
                msg = 'IP address {0}/{1} is being used by or overlaps with: {2} ({3}/{4})'.format(
                    self.obj[ipfield], self.obj[netfield], ifname,
                    ipaddr_elt.text, subnet_elt.text)
                self.module.fail_json(msg=msg)
예제 #3
0
    def netmask(self):
        if self._values['netmask'] is None:
            return None
        try:
            result = int(self._values['netmask'])

            # CIDRs between 0 and 128 are allowed
            if 0 <= result <= 128:
                return result
            else:
                raise F5ModuleError(
                    "The provided netmask must be between 0 and 32 for IPv4, or "
                    "0 and 128 for IPv6.")
        except ValueError:
            # not a number, but that's ok. Further processing necessary
            pass

        if not is_valid_ip(self._values['netmask']):
            raise F5ModuleError(
                'The provided netmask {0} is neither in IP or CIDR format'.
                format(result))

        # Create a temporary address to check if the netmask IP is v4 or v6
        addr = ip_address(u'{0}'.format(str(self._values['netmask'])))
        if addr.version == 4:
            # Create a more real v4 address using a wildcard, so that we can determine
            # the CIDR value from it.
            ip = ip_network(u'0.0.0.0/%s' % str(self._values['netmask']))
            result = ip.prefixlen
        else:
            result = ipv6_netmask_to_cidr(self._values['netmask'])

        return result
예제 #4
0
 def _convert_address(self, item):
     if item == '0.0.0.0/0':
         return 'any', None
     result = ip_network(u'{0}'.format(item))
     if result.prefixlen == 32:
         return str(result.network_address), None
     else:
         return str(result.network_address), str(result.netmask)
예제 #5
0
파일: addresses.py 프로젝트: ch3m7r411/core
def is_ipv6_network(address, strict=True):
    """ test if address is a valid ipv6 network """
    try:
        addr = ip_network(u'{0}'.format(address), strict=strict)
        return isinstance(addr, IPv6Network)
    except ValueError:
        pass
    return False
예제 #6
0
def _search_prefix(nb_endpoint, data):
    if data.get("prefix"):
        prefix = ipaddress.ip_network(data["prefix"])
    elif data.get("parent"):
        prefix = ipaddress.ip_network(data["parent"])

    network = to_text(prefix.network_address)
    mask = prefix.prefixlen

    if data.get("vrf"):
        if not isinstance(data["vrf"], int):
            raise ValueError("%s does not exist - Please create VRF" % (data["vrf"]))
        else:
            prefix = nb_endpoint.get(q=network, mask_length=mask, vrf_id=data["vrf"])
    else:
        prefix = nb_endpoint.get(q=network, mask_length=mask, vrf="null")

    return prefix
예제 #7
0
    def check_params(self):
        rules_by_host = {}
        for host in self.hosts:
            rules_by_host[host.name] = self.firewall_facts[host.name].keys()

        for rule_option in self.rule_options:
            rule_name = rule_option.get('name')
            if rule_name is None:
                self.module.fail_json(
                    msg="Please specify rule.name for rule set"
                    " as it is required parameter.")
            hosts_with_rule_name = [
                h for h, r in rules_by_host.items() if rule_name in r
            ]
            hosts_without_rule_name = set([i.name for i in self.hosts
                                           ]) - set(hosts_with_rule_name)
            if hosts_without_rule_name:
                self.module.fail_json(
                    msg="rule named '%s' wasn't found on hosts: %s" %
                    (rule_name, hosts_without_rule_name))

            if 'enabled' not in rule_option:
                self.module.fail_json(
                    msg="Please specify rules.enabled for rule set"
                    " %s as it is required parameter." % rule_name)

            allowed_hosts = rule_option.get('allowed_hosts', {})
            ip_addresses = allowed_hosts.get('ip_address', [])
            ip_networks = allowed_hosts.get('ip_network', [])
            for ip_address in ip_addresses:
                try:
                    ipaddress.ip_address(ip_address)
                except ValueError:
                    self.module.fail_json(
                        msg="The provided IP address %s is not a valid IP"
                        " for the rule %s" % (ip_address, rule_name))

            for ip_network in ip_networks:
                try:
                    ipaddress.ip_network(ip_network)
                except ValueError:
                    self.module.fail_json(
                        msg="The provided IP network %s is not a valid network"
                        " for the rule %s" % (ip_network, rule_name))
예제 #8
0
 def network(self):
     if self._values['network'] is None:
         return None
     if self._values['network'] == 'default':
         return 'default'
     try:
         addr = ip_network(u"{0}".format(str(self._values['network'])))
         return str(addr)
     except ValueError:
         raise F5ModuleError(
             "The 'network' must either be a network address (with CIDR) or the word 'default'."
         )
예제 #9
0
파일: gateway.py 프로젝트: ch3m7r411/core
        def _check_vips():
            virtualips = self.pfsense.get_element('virtualip')
            if virtualips is None:
                return False

            for vip_elt in virtualips:
                if vip_elt.find('interface').text != self.interface_elt.tag or vip_elt.find('mode').text != 'other' or vip_elt.find('type').text != 'network':
                    continue

                subnet = ip_network(u'{0}/{1}'.format(vip_elt.find('subnet').text, vip_elt.find('subnet_bits').text), strict=False)
                if addr in subnet:
                    return True
            return False
예제 #10
0
    def destination_ip(self):
        if self._values['destination'] is None:
            return None
        destination = self.destination_to_network()

        try:
            pattern = r'(?P<rd>%[0-9]+)'
            addr = re.sub(pattern, '', destination)
            ip = ip_network(u'%s' % str(addr))
            return '{0}/{1}'.format(str(ip.network_address), ip.prefixlen)
        except ValueError:
            raise F5ModuleError(
                "The provided destination is not an IP address.")
def map_config_to_obj(module):
    obj = []

    out = get_config(module, flags='| include ip route')
    for line in out.splitlines():
        # Split by whitespace but do not split quotes, needed for description
        splitted_line = findall(r'[^"\s]\S*|".+?"', line)
        route = {}
        prefix_with_mask = splitted_line[2]
        prefix = None
        mask = None
        iface = None
        nhop = None
        if validate_ip_address(prefix_with_mask) is True:
            my_net = ipaddress.ip_network(prefix_with_mask)
            prefix = str(my_net.network_address)
            mask = str(my_net.netmask)
            route.update({
                'prefix': prefix,
                'mask': mask,
                'admin_distance': '1'
            })
        if splitted_line[3] is not None:
            if validate_ip_address(splitted_line[3]) is False:
                iface = str(splitted_line[3])
                route.update(interface=iface)
                if validate_ip_address(splitted_line[4]) is True:
                    nhop = str(splitted_line[4])
                    route.update(next_hop=nhop)
                    if splitted_line[5].isdigit():
                        route.update(admin_distance=str(splitted_line[5]))
                elif splitted_line[4].isdigit():
                    route.update(admin_distance=str(splitted_line[4]))
                else:
                    if splitted_line[6] is not None and splitted_line[
                            6].isdigit():
                        route.update(admin_distance=str(splitted_line[6]))
            else:
                nhop = str(splitted_line[3])
                route.update(next_hop=nhop)
                if splitted_line[4].isdigit():
                    route.update(admin_distance=str(splitted_line[4]))

        index = 0
        for word in splitted_line:
            if word in ('tag', 'description'):
                route.update(word=splitted_line[index + 1])
            index = index + 1
        obj.append(route)

    return obj
예제 #12
0
 def _convert_netmask(self, item):
     result = -1
     try:
         result = int(item)
         if 0 < result < 256:
             pass
     except ValueError:
         if is_valid_ip(item):
             ip = ip_network(u'0.0.0.0/%s' % str(item))
             result = ip.prefixlen
     if result < 0:
         raise F5ModuleError(
             'The provided netmask {0} is neither in IP or CIDR format'.format(result)
         )
     return result
예제 #13
0
파일: addresses.py 프로젝트: ch3m7r411/core
def parse_ip_network(address, strict=True, returns_ip=True):
    """ return cidr parts of address """
    try:
        addr = ip_network(u'{0}'.format(address), strict=strict)
        if strict or not returns_ip:
            return (str(addr.network_address), addr.prefixlen)
        else:
            # we parse the address with ipaddr just for type checking
            # but we use a regex to return the result as it dont kept the address bits
            group = re.match(r'(.*)/(.*)', address)
            if group:
                return (group.group(1), group.group(2))
    except ValueError:
        pass
    return None
예제 #14
0
파일: addresses.py 프로젝트: ch3m7r411/core
def is_within_local_networks(self, address):
    """ test if address is contained in our local networks """
    networks = self.get_interfaces_networks()
    try:
        addr = ip_address(u'{0}'.format(address))
    except ValueError:
        return False

    for network in networks:
        try:
            net = ip_network(u'{0}'.format(network), strict=False)
            if addr in net:
                return True
        except ValueError:
            pass
    return False
예제 #15
0
 def destination(self):
     if self._values['destination'] is None:
         return None
     if self._values['destination'].startswith('default'):
         self._values['destination'] = '0.0.0.0/0'
     if self._values['destination'].startswith('default-inet6'):
         self._values['destination'] = '::/0'
     try:
         ip = ip_network(u'%s' % str(self.destination_ip))
         if self.route_domain:
             return '{0}%{1}/{2}'.format(str(ip.network_address),
                                         self.route_domain, ip.prefixlen)
         else:
             return '{0}/{1}'.format(str(ip.network_address), ip.prefixlen)
     except ValueError:
         raise F5ModuleError(
             "The provided destination is not an IP address")
예제 #16
0
def _get_prefix_id(nb_app, prefix, vrf_id=None):
    ipaddr_prefix = ipaddress.ip_network(prefix)
    network = to_text(ipaddr_prefix.network_address)
    mask = ipaddr_prefix.prefixlen

    prefix_query_params = {"prefix": network, "mask_length": mask}
    if vrf_id:
        prefix_query_params["vrf_id"] = vrf_id

    prefix_id = nb_app.prefixes.get(prefix_query_params)
    if not prefix_id:
        if vrf_id:
            raise ValueError(
                "Prefix %s does not exist in VRF %s - Please create it" %
                (prefix, vrf_id))
        else:
            raise ValueError("Prefix %s does not exist - Please create it" %
                             (prefix))

    return prefix_id
예제 #17
0
 def netmask(self):
     if self._values['netmask'] is None:
         return None
     result = -1
     try:
         result = int(self._values['netmask'])
         if 0 < result < 256:
             pass
     except ValueError:
         if is_valid_ip(self._values['netmask']):
             addr = ip_address(u'{0}'.format(str(self._values['netmask'])))
             if addr.version == 4:
                 ip = ip_network(u'0.0.0.0/%s' % str(self._values['netmask']))
                 result = ip.prefixlen
             else:
                 result = ipv6_netmask_to_cidr(self._values['netmask'])
     if result < 0:
         raise F5ModuleError(
             'The provided netmask {0} is neither in IP or CIDR format'.format(result)
         )
     return result
예제 #18
0
파일: gateway.py 프로젝트: ch3m7r411/core
    def _check_subnet(self):
        """ check if addr lies into interface subnets """
        def _check_vips():
            virtualips = self.pfsense.get_element('virtualip')
            if virtualips is None:
                return False

            for vip_elt in virtualips:
                if vip_elt.find('interface').text != self.interface_elt.tag or vip_elt.find('mode').text != 'other' or vip_elt.find('type').text != 'network':
                    continue

                subnet = ip_network(u'{0}/{1}'.format(vip_elt.find('subnet').text, vip_elt.find('subnet_bits').text), strict=False)
                if addr in subnet:
                    return True
            return False

        if self.params['ipprotocol'] == 'inet':
            inet_type = 'IPv4'
            f1_elt = self.interface_elt.find('ipaddr')
            f2_elt = self.interface_elt.find('subnet')
        else:
            inet_type = 'IPv6'
            f1_elt = self.interface_elt.find('ipaddrv6')
            f2_elt = self.interface_elt.find('subnetv6')
        if f1_elt is None or f1_elt.text is None or f2_elt is None or f2_elt.text is None:
            self.module.fail_json(msg='Cannot add {0} Gateway Address because no {0} address could be found on the interface.'.format(inet_type))

        try:
            if self.params['nonlocalgateway']:
                return

            addr = ip_address(u'{0}'.format(self.params['gateway']))
            subnet = ip_network(u'{0}/{1}'.format(f1_elt.text, f2_elt.text), strict=False)
            if addr in subnet or _check_vips():
                return

            self.module.fail_json(msg="The gateway address {0} does not lie within one of the chosen interface's subnets.".format(self.params['gateway']))
        except ValueError:
            self.module.fail_json(msg='Cannot add {0} Gateway Address because no {0} address could be found on the interface.'.format(inet_type))
예제 #19
0
def is_valid_ip_network(address):
    try:
        ip_network(u'{0}'.format(address))
        return True
    except ValueError:
        return False
예제 #20
0
 def destination_ip(self):
     if self._values['destination']:
         ip = ip_network(u'{0}/{1}'.format(self._values['destination'],
                                           self.netmask))
         return '{0}/{1}'.format(str(ip.network_address), ip.prefixlen)
예제 #21
0
 def netmask(self):
     destination = self.destination_to_network()
     ip = ip_network(u'%s' % str(destination))
     return int(ip.prefixlen)
예제 #22
0
def get_netmask(address):
    addr = ip_network(u'{0}'.format(address))
    netmask = addr.netmask.compressed
    return netmask
예제 #23
0
    def run(self):
        """
        This function should have all necessary code for endpoints within the application
        to create/update/delete the endpoint objects
        Supported endpoints:
        - aggregates
        - ipam_roles
        - ip_addresses
        - prefixes
        - rirs
        - vlans
        - vlan_groups
        - vrfs
        """
        # Used to dynamically set key when returning results
        endpoint_name = ENDPOINT_NAME_MAPPING[self.endpoint]

        self.result = {"changed": False}

        application = self._find_app(self.endpoint)
        nb_app = getattr(self.nb, application)
        nb_endpoint = getattr(nb_app, self.endpoint)

        data = self.data

        if self.endpoint == "ip_addresses":
            if data.get("address"):
                try:
                    data["address"] = to_text(
                        ipaddress.ip_network(data["address"]))
                except ValueError:
                    pass
            name = data.get("address")
        elif self.endpoint in ["aggregates", "prefixes"]:
            name = data.get("prefix")
        else:
            name = data.get("name")

        if self.endpoint in SLUG_REQUIRED:
            if not data.get("slug"):
                data["slug"] = self._to_slug(name)

        if self.module.params.get("first_available"):
            first_available = True
        else:
            first_available = False

        object_query_params = self._build_query_params(endpoint_name, data)
        if data.get("prefix") and self.endpoint == "ip_addresses":
            object_query_params = self._build_query_params("prefix", data)
            self.nb_object = self._nb_endpoint_get(nb_app.prefixes,
                                                   object_query_params, name)
        else:
            self.nb_object = self._nb_endpoint_get(nb_endpoint,
                                                   object_query_params, name)

        if self.state in ("new", "present") and endpoint_name == "ip_address":
            self._handle_state_new_present(nb_app, nb_endpoint, endpoint_name,
                                           name, data)
        elif self.state == "present" and first_available and data.get(
                "parent"):
            self._get_new_available_prefix(data, endpoint_name)
        elif self.state == "present":
            self._ensure_object_exists(nb_endpoint, endpoint_name, name, data)
        elif self.state == "absent":
            self._ensure_object_absent(endpoint_name, name)

        try:
            serialized_object = self.nb_object.serialize()
        except AttributeError:
            serialized_object = self.nb_object

        self.result.update({endpoint_name: serialized_object})

        self.module.exit_json(**self.result)
예제 #24
0
def compress_address(address):
    addr = ip_network(u'{0}'.format(address))
    result = addr.compressed.split('/')[0]
    return result