def _validateLoopbackPrefix(self, pod, podDict, inventoryData): inventoryDeviceCount = len(inventoryData['spines']) + len(inventoryData['leafs']) lo0Block = IPNetwork(podDict['loopbackPrefix']) lo0Ips = list(lo0Block.iter_hosts()) availableIps = len(lo0Ips) if availableIps < inventoryDeviceCount: raise ValueError("Pod[id='%s', name='%s']: loopbackPrefix available IPs %d not enough: required %d" % (pod.id, pod.name, availableIps, inventoryDeviceCount))
def create_address_pools(interfaceorder, networks_pools): address_pools = { iname: { 'net': ':'.join(networks_pools[iname]), 'params': { 'ip_reserved': { # Gateway will be used for configure OpenStack networks 'gateway': 1, # l2_network_device will be used for configure local bridge 'l2_network_device': 1, }, 'ip_ranges': { 'default': [2, -2], }, }, } for iname in interfaceorder } if 'public' in interfaceorder: # Put floating IP range for public network default_pool_name = 'default' floating_pool_name = 'floating' # Take a first subnet with necessary size and calculate the size net = IPNetwork(networks_pools['public'][0]) new_prefix = int(networks_pools['public'][1]) subnet = next(net.subnet(prefixlen=new_prefix)) network_size = subnet.size address_pools['public']['params']['ip_ranges'][default_pool_name] = [ 2, network_size // 2 - 1] address_pools['public']['params']['ip_ranges'][floating_pool_name] = [ network_size // 2, -2] return address_pools
def createNewVlanRange(cls): """ Increment current cidr of vlan range present in network and create new range """ publicIpRange = PublicIpRange.list(cls.api_client) cls.startIp = publicIpRange[0].startip cls.endIp = publicIpRange[0].endip cls.gateway = publicIpRange[0].gateway cls.netmask = publicIpRange[0].netmask # Pass ip address and mask length to IPNetwork to findout the CIDR ip = IPNetwork(cls.startIp + "/" + cls.netmask) # Take random increment factor to avoid adding the same vlan ip range # in each test case networkIncrementFactor = random.randint(1,255) new_cidr = ip.__iadd__(networkIncrementFactor) ip2 = IPNetwork(new_cidr) test_nw = ip2.network ip = IPAddress(test_nw) # Add IP range(5 IPs) in the new CIDR test_gateway = ip.__add__(1) test_startIp = ip.__add__(3) test_endIp = ip.__add__(10) # Populating services with new IP range cls.testdata["vlan_ip_range"]["startip"] = test_startIp cls.testdata["vlan_ip_range"]["endip"] = test_endIp cls.testdata["vlan_ip_range"]["gateway"] = test_gateway cls.testdata["vlan_ip_range"]["netmask"] = cls.netmask cls.testdata["vlan_ip_range"]["zoneid"] = cls.zone.id cls.testdata["vlan_ip_range"]["podid"] = cls.pod.id return PublicIpRange.create( cls.api_client, cls.testdata["vlan_ip_range"])
def calculate_vip_start(self, vip_start, mgmtip, selfip_external): if not selfip_external and not vip_start: LOG.info('Skipping auto VIP generation.') return if selfip_external: if not isinstance(selfip_external, IPNetwork): selfip_external = IPNetwork(selfip_external) if selfip_external.prefixlen == 32: LOG.info('Self IP external has no prefix. Assuming /16.') selfip_external.prefixlen = 16 if vip_start is None: # '1.1.1.1/24' -> '1.1.1.0/24' cidr = "{0.network}/{0.prefixlen}".format(mgmtip) host_id = mgmtip.ip.value - mgmtip.network.value subnet_index = SUBNET_MAP.get(cidr) if subnet_index is None: LOG.warning('The %s subnet was not found! ' 'Skipping Virtual Servers.' % cidr) return # Start from 10.11.50.0 - 10.11.147.240 (planned for 10 subnets, 8 VIPs each) offset = 1 + 50 * 256 + DEFAULT_VIPS * (256 * subnet_index + host_id) vip_start = selfip_external.network + offset else: vip_start = IPAddress(vip_start) return vip_start
def reserve_ip_addr(self): """Picks first available IP address from weave network. If there's no available IP address anymore, ``IndexError`` will be raised. To prevent this error, catch the exception or checks the value ``GluuCluster.ip_addr_available`` first before trying to call this method. :returns: A 2-elements tuple consists of IP address and network prefix, e.g. ``("10.10.10.1", 24)``. """ # represents a pool of IP addresses pool = IPNetwork(self.weave_ip_network) # a generator holds possible IP addresses range, excluding exposed weave IP ip_range = IPSet(pool.iter_hosts()) ^ IPSet(self.reserved_ip_addrs) ^ IPSet([self.exposed_weave_ip[0]]) # retrieves first IP address from ``ip_range`` generator ip_addr = list(itertools.islice(ip_range, 1))[0] # register the IP address so it will be excluded # from possible IP range in subsequent requests self.reserved_ip_addrs.append(str(ip_addr)) # weave IP address for container expects a traditional CIDR, # e.g. 10.10.10.1/24, hence we return the actual IP and # its prefix length return str(ip_addr), pool.prefixlen
def split_subnets(cidr, split): """ Finds the nearest power of two to the number of desired subnets, Splits a CIDR into that many sub CIDRs, and returns the array. :param cidr: CIDR for entire range :type cidr: str. :param split: Number to split into :type split: int. :raises: :class:`pmcf.exceptions.PropertyException` :returns: list. """ # Find the next closest power of two to a number # For 3, return 4, for 5 return 8 if split == 1: return [cidr] power = 0 while split > 0: split >>= 1 power += 1 try: ipaddr = IPNetwork(cidr) prefix = ipaddr.prefixlen newprefix = prefix + power return list(ipaddr.subnet(newprefix)) except Exception, exc: raise PropertyException(str(exc))
def populateDhcpGlobalSettings(self): ztp = {} ztpGlobalSettings = util.loadClosDefinition()['ztp'] subnet = ztpGlobalSettings['dhcpSubnet'] dhcpBlock = IPNetwork(subnet) ipList = list(dhcpBlock.iter_hosts()) ztp['network'] = str(dhcpBlock.network) ztp['netmask'] = str(dhcpBlock.netmask) ztp['defaultRoute'] = ztpGlobalSettings.get('dhcpOptionRoute') if ztp['defaultRoute'] is None or ztp['defaultRoute'] == '': ztp['defaultRoute'] = str(ipList[0]) ztp['rangeStart'] = ztpGlobalSettings.get('dhcpOptionRangeStart') if ztp['rangeStart'] is None or ztp['rangeStart'] == '': ztp['rangeStart'] = str(ipList[1]) ztp['rangeEnd'] = ztpGlobalSettings.get('dhcpOptionRangeEnd') if ztp['rangeEnd'] is None or ztp['rangeEnd'] == '': ztp['rangeEnd'] = str(ipList[-1]) ztp['broadcast'] = str(dhcpBlock.broadcast) ztp['httpServerIp'] = self.conf['httpServer']['ipAddr'] ztp['imageUrl'] = ztpGlobalSettings.get('junosImage') return ztp
def _create_subnets(self): logging.debug("creating subnets") zones = self.vpc.vpc.connection.get_all_zones() logging.debug("zones: %s", zones) # We'll need to split each subnet into smaller ones, one per zone # offset is how much we need to add to cidr divisor to create at least # that len(zone) subnets zone_cidr_offset = ceil(log(len(zones), 2)) logging.debug("zone_offset: %s", zone_cidr_offset) network_cidr = IPNetwork(self.vpc.get_config("{0}_cidr".format(self.name))) zone_cidrs = network_cidr.subnet( int(network_cidr.prefixlen + zone_cidr_offset) ) subnets = [] for zone, cidr in zip(zones, zone_cidrs): logging.debug("%s %s", zone, cidr) subnet = self.vpc.vpc.connection.create_subnet(self.vpc.vpc.id, cidr, zone.name) self.vpc.vpc.connection.associate_route_table(self.route_table.id, subnet.id) self._tag_resource(subnet, zone.name) subnets.append(subnet) logging.debug("%s subnet: %s", self.name, subnet) return subnets
def _add_search_filters(filters, query): """ Add Search Service response to filters """ search_query = query # Try to parse IP/CIDR search if IP_CIDR_RE.match(query): try: network = IPNetwork(query) if network.size <= 4096: search_query = ' '.join([str(host) for host in network.iter_hosts()]) search_query = search_query if search_query else query except (AttributeError, IndexError, AddrFormatError, AddrConversionError): pass try: reports = ImplementationFactory.instance.get_singleton_of('SearchServiceBase').search_reports(search_query) if not reports: reports = [None] except SearchServiceException: return if 'in' in filters['where']: for field in filters['where']['in']: for key, values in field.iteritems(): if key == 'id' and len(values): reports.extend(values) filters['where']['in'].remove({key: values}) filters['where']['in'].append({'id': list(set(reports))}) else: filters['where']['in'] = [{'id': reports}]
def allocateInterconnect(self, interConnectPrefix, spines, leafs): numOfIpsPerInterconnect = 2 numOfSubnets = len(spines) * len(leafs) # no need to add +2 for network and broadcast, as junos supports /31 # TODO: it should be configurable and come from property file bitsPerSubnet = int(math.ceil(math.log(numOfIpsPerInterconnect, 2))) # value is 1 cidrForEachSubnet = 32 - bitsPerSubnet # value is 31 as junos supports /31 numOfIps = (numOfSubnets * (numOfIpsPerInterconnect)) # no need to add +2 for network and broadcast numOfBits = int(math.ceil(math.log(numOfIps, 2))) cidr = 32 - numOfBits interconnectBlock = IPNetwork(interConnectPrefix + "/" + str(cidr)) interconnectSubnets = list(interconnectBlock.subnet(cidrForEachSubnet)) interfaces = [] spines[0].pod.allocatedInterConnectBlock = str(interconnectBlock.cidr) for spine in spines: ifdsHasPeer = self.dao.Session().query(InterfaceDefinition).filter(InterfaceDefinition.device_id == spine.id).filter(InterfaceDefinition.peer != None).order_by(InterfaceDefinition.name_order_num).all() for spineIfdHasPeer in ifdsHasPeer: subnet = interconnectSubnets.pop(0) ips = list(subnet) spineEndIfl= InterfaceLogical(spineIfdHasPeer.name + '.0', spine, str(ips.pop(0)) + '/' + str(cidrForEachSubnet)) spineIfdHasPeer.layerAboves.append(spineEndIfl) interfaces.append(spineEndIfl) leafEndIfd = spineIfdHasPeer.peer leafEndIfl= InterfaceLogical(leafEndIfd.name + '.0', leafEndIfd.device, str(ips.pop(0)) + '/' + str(cidrForEachSubnet)) leafEndIfd.layerAboves.append(leafEndIfl) interfaces.append(leafEndIfl) self.dao.createObjects(interfaces)
def validate_ip(self, request, remote_ip): # When we aren't configured to restrict on IP address if not getattr(settings, 'RESTRICTEDSESSIONS_RESTRICT_IP', True): return True # When the IP address key hasn't yet been set on the request session if SESSION_IP_KEY not in request.session: return True # When there is no remote IP, check if one has been set on the session session_ip = request.session[SESSION_IP_KEY] if not remote_ip: if session_ip: # session has remote IP value so validate :-( return False else: # Session doesn't have remote IP value so possibly :-) return True # Compute fuzzy IP compare based on settings on compare sensitivity session_network = IPNetwork(session_ip) remote_ip = IPAddress(remote_ip) try: session_network = session_network.ipv4() remote_ip = remote_ip.ipv4() session_network.prefixlen = getattr(settings, 'RESTRICTEDSESSIONS_IPV4_LENGTH', 32) except AddrConversionError: try: session_network.prefixlen = getattr(settings, 'RESTRICTEDSESSIONS_IPV6_LENGTH', 64) except AddrFormatError: # session_network must be IPv4, but remote_ip is IPv6 return False return remote_ip in session_network
def add(caller_id, address, mask): networks = [] for net in AvailableNetwork.objects.all(): networks.append(net.to_ipnetwork()) networks.sort() # Find duplicate ipnet = IPNetwork('%s/%d' % (address, mask)) for i in xrange(len(networks)): if ipnet.prefixlen > networks[i].prefixlen and ipnet > networks[i].previous() and ipnet < networks[i].next(): raise CMException('network_exists') elif ipnet.prefixlen < networks[i].prefixlen and ipnet.previous() < networks[i] and ipnet.next() > networks[i]: raise CMException('network_exists') # Add new network new_net = AvailableNetwork() new_net.address = ipnet.network new_net.mask = mask if ipnet.is_private(): new_net.state = available_network_states['ok'] else: new_net.state = available_network_states['locked'] new_net.save()
def __init__(self): self.net1 = IPNetwork(NETWORK_1) self.net1_ip_pool = cycle(self.net1.iter_hosts()) self.net2 = IPNetwork(NETWORK_2) self.net2_ip_pool = cycle(self.net2.iter_hosts()) self.mcounter = dict() self.mac_counter = 0
def _validateLoopbackPrefix(self, pod, podDict, inventoryData): inventoryDeviceCount = len(inventoryData['spines']) + len(inventoryData['leafs']) lo0Block = IPNetwork(podDict['loopbackPrefix']) lo0Ips = list(lo0Block.iter_hosts()) availableIps = len(lo0Ips) cidr = 32 - int(math.ceil(math.log(inventoryDeviceCount, 2))) if availableIps < inventoryDeviceCount: raise InsufficientLoopbackIp("Pod[id='%s', name='%s']: loopbackPrefix minimum required: %s/%d" % (pod.id, pod.name, lo0Block.ip, cidr))
def test_ip_v4_to_ipv6_compatible(): assert IPAddress('192.0.2.15').ipv6(ipv4_compatible=True) == IPAddress('::192.0.2.15') assert IPAddress('192.0.2.15').ipv6(ipv4_compatible=True).is_ipv4_compat() assert IPAddress('192.0.2.15').ipv6(True) == IPAddress('::192.0.2.15') ip = IPNetwork('192.0.2.1/23') assert ip.ipv4() == IPNetwork('192.0.2.1/23') assert ip.ipv6() == IPNetwork('::ffff:192.0.2.1/119') assert ip.ipv6(ipv4_compatible=True) == IPNetwork('::192.0.2.1/119')
def _allocateLoopback(self, session, pod, loopbackPrefix, devices): loopbackIp = IPNetwork(loopbackPrefix).network numOfIps = len(devices) + 2 # +2 for network and broadcast numOfBits = int(math.ceil(math.log(numOfIps, 2))) cidr = 32 - numOfBits lo0Block = IPNetwork(str(loopbackIp) + "/" + str(cidr)) lo0Ips = list(lo0Block.iter_hosts()) pod.allocatedLoopbackBlock = str(lo0Block.cidr) self._assignAllocatedLoopbackToDevices(session, devices, lo0Ips)
def allocate_tap_ips(self): #TODO: take tap subnet parameter lab_topology = self.nidb.topology[self.host] from netaddr import IPNetwork address_block = IPNetwork("172.16.0.0/16").iter_hosts() lab_topology.tap_host = address_block.next() lab_topology.tap_vm = address_block.next() # for tunnel host for node in self.nidb.nodes("is_l3device", host = self.host): #TODO: check this works for switches node.tap.ip = address_block.next()
def split_network(request): try: network = IPNetwork(request.GET['network']) except (KeyError, AddrFormatError): return HttpResponseBadRequest() return render(request, 'pammy/split_network.html', { 'networks': network.subnet(network.prefixlen + 1), })
def is_cidr_reserved(cidr, vpccidr): """ Check if CIDR is in the first 2 x /22 in the VPC Range """ cidr = str(cidr) vpc = IPNetwork(vpccidr) reserved1 = list(vpc.subnet(22))[0] reserved2 = list(vpc.subnet(22))[1] if reserved1 == IPNetwork(cidr).supernet(22)[0] or reserved2 == IPNetwork(cidr).supernet(22)[0]: return True return False
def targets(self, targets): # Always append, never overwrite. # Fix target URLs if the scheme part is missing. # Make sure self._targets contains a list. self._targets = getattr(self, "_targets", []) # Ignore the trivial case. if not targets: return # Strip whitespace. targets = [ x.strip() for x in targets if x not in self._targets ] # Remove duplicates. targets = [ x for x in set(targets) if x not in self._targets ] # Encode all Unicode strings as UTF-8. targets = [ x.encode("UTF-8") if isinstance(x, unicode) else str(x) for x in targets if x not in self._targets ] # Detect network ranges, like 30.30.30.0/24, and get all IPs on it. parsed_targets = [] for host in targets: # Try to parse the address as a network range. try: tmp_target = IPNetwork(host) except: parsed_targets.append(host) continue # If it's a range, iterate it and get all IP addresses. # If it's a single IP address, just add it. if tmp_target.size != 1: parsed_targets.extend( str(x) for x in tmp_target.iter_hosts() ) else: parsed_targets.append( str(tmp_target.ip) ) # Add the new targets. self._targets.extend(parsed_targets)
def allocate_tap_ipsOriginal(self): #TODO: take tap subnet parameter lab_topology = self.nidb.topology[self.host] #TODO: also store platform from netaddr import IPNetwork address_block = IPNetwork("172.16.0.0/16").iter_hosts() #TODO: read this from config lab_topology.tap_host = address_block.next() lab_topology.tap_vm = address_block.next() # for tunnel host for node in sorted(self.nidb.nodes("is_l3device", host = self.host)): #TODO: fix sorting order #TODO: check this works for switches node.tap.ip = address_block.next()
def create_networks(self, nw_group): ''' Method for creation of networks for network group. :param nw_group: NetworkGroup object. :type nw_group: NetworkGroup :returns: None ''' fixnet = IPNetwork(nw_group.cidr) subnet_bits = int(math.ceil(math.log(nw_group.network_size, 2))) logger.debug("Specified network size requires %s bits", subnet_bits) subnets = list(fixnet.subnet(32 - subnet_bits, count=nw_group.amount)) logger.debug("Base CIDR sliced on subnets: %s", subnets) for net in nw_group.networks: logger.debug("Deleting old network with id=%s, cidr=%s", net.id, net.cidr) ips = db().query(IPAddr).filter( IPAddr.network == net.id ).all() map(db().delete, ips) db().delete(net) db().commit() # Dmitry's hack for clearing VLANs without networks self.clear_vlans() db().commit() nw_group.networks = [] for n in xrange(nw_group.amount): vlan_id = None if nw_group.vlan_start is not None: vlan_db = db().query(Vlan).get(nw_group.vlan_start + n) if vlan_db: logger.warning("Intersection with existing vlan_id: %s", vlan_db.id) else: vlan_db = Vlan(id=nw_group.vlan_start + n) db().add(vlan_db) vlan_id = vlan_db.id logger.debug("Created VLAN object, vlan_id=%s", vlan_id) gateway = None if nw_group.gateway: gateway = nw_group.gateway net_db = Network( release=nw_group.release, name=nw_group.name, access=nw_group.access, cidr=str(subnets[n]), vlan_id=vlan_id, gateway=gateway, network_group_id=nw_group.id) db().add(net_db) db().commit()
def allocate_tap_ips(self): """Allocates TAP IPs""" settings = autonetkit.config.settings lab_topology = self.nidb.topology[self.host] from netaddr import IPNetwork address_block = IPNetwork(settings.get("tapsn") or "172.16.0.0/16").iter_hosts() # added for backwards compatibility lab_topology.tap_host = address_block.next() lab_topology.tap_vm = address_block.next() # for tunnel host for node in sorted(self.nidb.nodes("is_l3device", host=self.host)): node.tap.ip = address_block.next()
def get_admin_ip_w_prefix(node): """Getting admin ip and assign prefix from admin network.""" network_manager = objects.Node.get_network_manager(node) admin_ip = network_manager.get_admin_ip_for_node(node) admin_ip = IPNetwork(admin_ip) # Assign prefix from admin network admin_net = IPNetwork(network_manager.get_admin_network_group().cidr) admin_ip.prefixlen = admin_net.prefixlen return str(admin_ip)
def parse(self, data): mynets = IPSet() for line in data.split("\n"): if not line or line[0] == ";": continue ip, sbl = line.split(";") ip = IPNetwork(ip.strip()) mynets.add(ip) return mynets
def ipv4_to_cidr(address, netmask=None, prefixlen=None): a = IPAddress(address) n = IPNetwork(a) if netmask: assert prefixlen is None, 'Cannot provide both netmask and prefixlen' m = IPAddress(netmask) assert m.is_netmask(), 'A valid netmask is required' n.prefixlen = m.netmask_bits() else: assert prefixlen, 'Provide either netmask or prefixlen' n.prefixlen = int(prefixlen) return str(n.cidr)
def get_admin_ip(cls, node): """Getting admin ip and assign prefix from admin network.""" network_manager = NetworkManager() admin_ip = network_manager.get_admin_ips_for_interfaces( node)[node.admin_interface.name] admin_ip = IPNetwork(admin_ip) # Assign prefix from admin network admin_net = IPNetwork(network_manager.get_admin_network().cidr) admin_ip.prefixlen = admin_net.prefixlen return str(admin_ip)
def discovery_rule(ip_range,proxy_hostid,proxy_name): """ criar/atualizar a regra dentro do zabbix, passando apenas o range de ip ignora o primeiro ip e os 2 ultimos aceita de /19 ate /32 """ rule_name = 'SNMP_auto - {0}'.format(ip_range) ip = IPNetwork(ip_range) ip_list = list(ip) ip_range_small = '' if ip.prefixlen >= 30: ip_range_small = ip_range elif ip.prefixlen >= 24 and ip.prefixlen < 30: ip_range_small = '{0}-{1}'.format(str(ip_list[2]), str(ip_list[-4]).split('.')[3]) elif ip.prefixlen > 18 and ip.prefixlen < 24: nets = list(ip.subnet(24)) for index in range(nets.__len__()): ip_list = list(IPNetwork(nets[index])) if index == 0: # Primeiro ip_range_small = '{0}-{1}'.format(str(ip_list[2]), str(ip_list[-1]).split('.')[3]) elif index == (nets.__len__()-1): # Ultimo ip_range_small = '{0},{1}-{2}'.format(ip_range_small,str(ip_list[2]), str(ip_list[-4]).split('.')[3]) else: # Do meio ip_range_small = '{0},{1}-{2}'.format(ip_range_small,str(ip_list[1]), str(ip_list[-1]).split('.')[3]) else: logger.warning('Tamanho de rede invalido: {0}'.format(ip_range)) dchecks = discovery_checks() out={ 'druleids': 'fake data' } exists = zapi.drule.get(output=['name'],filter={'name': rule_name}) params = { 'name': rule_name, 'iprange': ip_range_small, 'delay': '86400', 'proxy_hostid': proxy_hostid, 'dchecks': dchecks, 'status': 1 } if exists.__len__() == 1: query = { 'output':[ 'druleids' ], 'search': { 'name': rule_name } } params['druleid'] = zapi.drule.get(**query)[0]['druleid'] if not args.move: del params['proxy_hostid'] if not fake: out = zapi.drule.update(**params) elif exists.__len__() == 0: # Nao existe a regra de discovery ainda.. if not fake: out = zapi.drule.create(**params) #fecha zapi.drule.create else: logger.error('Too many discovery rules for {0}: {1}'.format(rule_name,exists.__len__())) if ( out or fake ): logger.debug('\t{0} --> rule {1} ({2})'.format(proxy_name,rule_name,out['druleids'])) else: logger.error('\tFAILED:\t{0} --> rule {1} ({2})'.format(proxy_name,rule_name,out['druleids'])) return
def allocate_tap_ips(self): # TODO: take tap subnet parameter lab_topology = self.nidb.topology[self.host] # TODO: also store platform from netaddr import IPNetwork address_block = IPNetwork(settings.get("tapsn") or "172.16.0.0/16").iter_hosts() # added for backwards compatibility lab_topology.tap_host = address_block.next() lab_topology.tap_vm = address_block.next() # for tunnel host for node in sorted(self.nidb.nodes("is_l3device", host=self.host)): # TODO: fix sorting order # TODO: check this works for switches node.tap.ip = address_block.next()
def allocateLoopback(self, pod, loopbackPrefix, devices): numOfIps = len(devices) + 2 # +2 for network and broadcast numOfBits = int(math.ceil(math.log(numOfIps, 2))) cidr = 32 - numOfBits lo0Block = IPNetwork(loopbackPrefix + "/" + str(cidr)) lo0Ips = list(lo0Block.iter_hosts()) interfaces = [] pod.allocatedLoopbackBlock = str(lo0Block.cidr) for device in devices: ifl = InterfaceLogical('lo0.0', device, str(lo0Ips.pop(0)) + '/32') interfaces.append(ifl) self.dao.createObjects(interfaces)
def handleEvent(self, event): eventName = event.eventType srcModuleName = event.module eventData = event.data self.debug(f"Received event, {eventName}, from {srcModuleName}") if self.errorState: return if srcModuleName == "sfp_tool_testsslsh": self.debug("Skipping event from myself.") return if not self.opts['testsslsh_path']: self.error("You enabled sfp_tool_testsslsh but did not set a path to the tool!") self.errorState = True return exe = self.opts['testsslsh_path'] if self.opts['testsslsh_path'].endswith('/'): exe = f"{exe}testssl.sh" if not os.path.isfile(exe): self.error(f"File does not exist: {exe}") self.errorState = True return if not SpiderFootHelpers.sanitiseInput(eventData, extra=['/']): self.debug("Invalid input, skipping.") return targets = list() try: if eventName == "NETBLOCK_OWNER" and self.opts['netblockscan']: net = IPNetwork(eventData) if net.prefixlen < self.opts['netblockscanmax']: self.debug("Skipping scanning of " + eventData + ", too big.") return for addr in net.iter_hosts(): targets.append(str(addr)) except BaseException as e: self.error(f"Strange netblock identified, unable to parse: {eventData} ({e})") return # Don't look up stuff twice, check IP == IP here if eventData in self.results: self.debug(f"Skipping {eventData} as already scanned.") return else: if eventName != "INTERNET_NAME": # Might be a subnet within a subnet or IP within a subnet for addr in self.results: try: if IPNetwork(eventData) in IPNetwork(addr): self.debug(f"Skipping {eventData} as already within a scanned range.") return except BaseException: # self.results will also contain hostnames continue self.results[eventData] = True # If we weren't passed a netblock, this will be empty if not targets: targets.append(eventData) for target in targets: # Create a temporary output file _, fname = tempfile.mkstemp("testssl.json") args = [ exe, "-U", "--connect-timeout", "5", "--openssl-timeout", "5", "--jsonfile", fname, target ] try: p = Popen(args, stdout=PIPE, stderr=PIPE) out, stderr = p.communicate(input=None) stdout = out.decode(sys.stdin.encoding) except Exception as e: self.error(f"Unable to run testssl.sh: {e}") os.unlink(fname) continue if p.returncode != 0: err = None if "Unable to open a socket" in stdout: err = "Unable to connect" else: err = "Internal error" self.error(f"Unable to read testssl.sh output for {target}: {err}") os.unlink(fname) continue if not stdout: self.debug(f"testssl.sh returned no output for {target}") os.unlink(fname) continue try: with open(fname, "r") as f: result_json = json.loads(f.read()) os.unlink(fname) except Exception as e: self.error(f"Could not parse testssl.sh output as JSON: {e}\nstderr: {stderr}\nstdout: {stdout}") continue if not result_json: self.debug(f"testssl.sh returned no output for {target}") continue cves = list() for result in result_json: if result['finding'] == "not vulnerable": continue if result['severity'] not in ["LOW", "MEDIUM", "HIGH", "CRITICAL"]: continue if 'cve' in result: for cve in result['cve'].split(" "): if cve in cves: continue cves.append(cve) etype, cvetext = self.sf.cveInfo(cve) evt = SpiderFootEvent(etype, cvetext, self.__name__, event) self.notifyListeners(evt) else: if result['id'] in cves: continue cves.append(result['id']) evt = SpiderFootEvent("VULNERABILITY_GENERAL", f"{result['id']} ({result['finding']})", self.__name__, event) self.notifyListeners(evt)
def _get_proxy_ip(cidr): return IPNetwork(cidr).ip + 1
def resourceList(self, id, target, targetType): targetDom = '' # Get the base domain if we're supplied a domain if targetType == "domain": targetDom = self.sf.hostDomain(target, self.opts['_internettlds']) for check in malchecks.keys(): cid = malchecks[check]['id'] if id == cid and malchecks[check]['type'] == "list": data = dict() url = malchecks[check]['url'] data['content'] = self.sf.cacheGet( "sfmal_" + cid, self.opts.get('cacheperiod', 0)) if data['content'] is None: data = self.sf.fetchUrl(url, timeout=self.opts['_fetchtimeout'], useragent=self.opts['_useragent']) if data['content'] is None: self.sf.error("Unable to fetch " + url, False) return None else: self.sf.cachePut("sfmal_" + cid, data['content']) # If we're looking at netblocks if targetType == "netblock": iplist = list() # Get the regex, replace {0} with an IP address matcher to # build a list of IP. # Cycle through each IP and check if it's in the netblock. if 'regex' in malchecks[check]: rx = malchecks[check]['regex'].replace( "{0}", "(\d+\.\d+\.\d+\.\d+)") pat = re.compile(rx, re.IGNORECASE) self.sf.debug("New regex for " + check + ": " + rx) for line in data['content'].split('\n'): grp = re.findall(pat, line) if len(grp) > 0: #self.sf.debug("Adding " + grp[0] + " to list.") iplist.append(grp[0]) else: iplist = data['content'].split('\n') for ip in iplist: if len(ip) < 8 or ip.startswith("#"): continue ip = ip.strip() try: if IPAddress(ip) in IPNetwork(target): self.sf.debug( ip + " found within netblock/subnet " + target + " in " + check) return url except Exception as e: self.sf.debug("Error encountered parsing: " + str(e)) continue return None # If we're looking at hostnames/domains/IPs if 'regex' not in malchecks[check]: for line in data['content'].split('\n'): if line == target or (targetType == "domain" and line == targetDom): self.sf.debug(target + "/" + targetDom + " found in " + check + " list.") return url else: try: # Check for the domain and the hostname rxDom = unicode( malchecks[check]['regex']).format(targetDom) rxTgt = unicode( malchecks[check]['regex']).format(target) for line in data['content'].split('\n'): if (targetType == "domain" and re.match(rxDom, line, re.IGNORECASE)) or \ re.match(rxTgt, line, re.IGNORECASE): self.sf.debug(target + "/" + targetDom + " found in " + check + " list.") return url except BaseException as e: self.sf.debug("Error encountered parsing 2: " + str(e)) continue return None
def edit(container=None): ''' edit containers page and actions if form post request ''' if 'logged_in' in session: host_memory = lwp.host_memory_usage() if request.method == 'POST': cfg = lwp.get_container_settings(container) ip_regex = '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/(3[0-2]|[12]?[0-9]))?' info = lxc.info(container) form = {} form['type'] = request.form['type'] form['link'] = request.form['link'] try: form['flags'] = request.form['flags'] except KeyError: form['flags'] = 'down' form['hwaddr'] = request.form['hwaddress'] form['rootfs'] = request.form['rootfs'] form['utsname'] = request.form['hostname'] form['ipv4'] = request.form['ipaddress'] try: form['gateway'] = request.form['gatewayaddress'] except KeyError: form['gateway'] = '' form['memlimit'] = request.form['memlimit'] form['swlimit'] = request.form['swlimit'] form['cpus'] = request.form['cpus'] form['shares'] = request.form['cpushares'] try: form['autostart'] = request.form['autostart'] except KeyError: form['autostart'] = False if form['utsname'] != cfg['utsname'] and re.match( '(?!^containers$)|^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$', form['utsname']): lwp.push_config_value('lxc.utsname', form['utsname'], container=container) flash(u'Hostname updated for %s!' % container, 'success') if form['flags'] != cfg['flags'] and re.match( '^(up|down)$', form['flags']): lwp.push_config_value('lxc.network.flags', form['flags'], container=container) flash(u'Network flag updated for %s!' % container, 'success') if form['type'] != cfg['type'] and re.match('^\w+$', form['type']): lwp.push_config_value('lxc.network.type', form['type'], container=container) flash(u'Link type updated for %s!' % container, 'success') if form['link'] != cfg['link'] and re.match( '^[a-zA-Z0-9_-]+$', form['link']): lwp.push_config_value('lxc.network.link', form['link'], container=container) flash(u'Link name updated for %s!' % container, 'success') if form['hwaddr'] != cfg['hwaddr'] and re.match( '^([a-fA-F0-9]{2}[:|\-]?){6}$', form['hwaddr']): lwp.push_config_value('lxc.network.hwaddr', form['hwaddr'], container=container) flash(u'Hardware address updated for %s!' % container, 'success') if (not form['ipv4'] and form['ipv4'] != cfg['ipv4']) or ( form['ipv4'] != cfg['ipv4'] and re.match('^%s$' % ip_regex, form['ipv4'])): lwp.push_config_value('lxc.network.ipv4', form['ipv4'], container=container) flash(u'IP address updated for %s!' % container, 'success') if (not form['gateway'] and form['gateway'] != cfg['gateway']) or ( form['gateway'] != cfg['gateway'] and re.match('^%s$' % ip_regex, form['gateway'])): if IPAddress(form['gateway']) in IPNetwork(form['ipv4']): lwp.push_config_value('lxc.network.ipv4.gateway', form['gateway'], container=container) flash(u'Gateway address updated for %s!' % container, 'success') else: flash(u'Gateway address not in same network of ip address', 'error') if form['memlimit'] != cfg['memlimit'] and form[ 'memlimit'].isdigit() and int(form['memlimit']) <= int( host_memory['total']): if int(form['memlimit']) == int(host_memory['total']): form['memlimit'] = '' if form['memlimit'] != cfg['memlimit']: lwp.push_config_value('lxc.cgroup.memory.limit_in_bytes', form['memlimit'], container=container) if info["state"].lower() != 'stopped': lxc.cgroup(container, 'lxc.cgroup.memory.limit_in_bytes', form['memlimit']) flash(u'Memory limit updated for %s!' % container, 'success') if form['swlimit'] != cfg['swlimit'] and form['swlimit'].isdigit( ) and int(form['swlimit']) <= int(host_memory['total'] * 2): if int(form['swlimit']) == int(host_memory['total'] * 2): form['swlimit'] = '' if form['swlimit'].isdigit(): form['swlimit'] = int(form['swlimit']) if form['memlimit'].isdigit(): form['memlimit'] = int(form['memlimit']) if (form['memlimit'] == '' and form['swlimit'] != '') or ( form['memlimit'] > form['swlimit'] and form['swlimit'] != ''): flash( u'Can\'t assign swap memory lower than the memory limit', 'warning') elif form['swlimit'] != cfg['swlimit'] and form[ 'memlimit'] <= form['swlimit']: lwp.push_config_value( 'lxc.cgroup.memory.memsw.limit_in_bytes', form['swlimit'], container=container) if info["state"].lower() != 'stopped': lxc.cgroup(container, 'lxc.cgroup.memory.memsw.limit_in_bytes', form['swlimit']) flash(u'Swap limit updated for %s!' % container, 'success') if (not form['cpus'] and form['cpus'] != cfg['cpus']) or ( form['cpus'] != cfg['cpus'] and re.match('^[0-9,-]+$', form['cpus'])): lwp.push_config_value('lxc.cgroup.cpuset.cpus', form['cpus'], container=container) if info["state"].lower() != 'stopped': lxc.cgroup(container, 'lxc.cgroup.cpuset.cpus', form['cpus']) flash(u'CPUs updated for %s!' % container, 'success') if (not form['shares'] and form['shares'] != cfg['shares']) or ( form['shares'] != cfg['shares'] and re.match('^[0-9]+$', form['shares'])): lwp.push_config_value('lxc.cgroup.cpu.shares', form['shares'], container=container) if info["state"].lower() != 'stopped': lxc.cgroup(container, 'lxc.cgroup.cpu.shares', form['shares']) flash(u'CPU shares updated for %s!' % container, 'success') if form['rootfs'] != cfg['rootfs'] and re.match( '^[a-zA-Z0-9_/\-]+', form['rootfs']): lwp.push_config_value('lxc.rootfs', form['rootfs'], container=container) flash(u'Rootfs updated!' % container, 'success') auto = lwp.ls_auto() if form['autostart'] == 'True' and not ('%s.conf' % container) in auto: try: os.symlink('/var/lib/lxc/%s/config' % container, '/etc/lxc/auto/%s.conf' % container) flash(u'Autostart enabled for %s' % container, 'success') except OSError: flash( u'Unable to create symlink \'/etc/lxc/auto/%s.conf\'' % container, 'error') elif not form['autostart'] and ('%s.conf' % container) in auto: try: os.remove('/etc/lxc/auto/%s.conf' % container) flash(u'Autostart disabled for %s' % container, 'success') except OSError: flash(u'Unable to remove symlink', 'error') info = lxc.info(container) status = info['state'] pid = info['pid'] infos = { 'status': status, 'pid': pid, 'memusg': lwp.memory_usage(container) } return render_template('edit.html', containers=lxc.ls(), container=container, infos=infos, settings=lwp.get_container_settings(container), host_memory=host_memory) return render_template('login.html')
def create_network_objects_from_valid_ips(self, ip_range_list): for ip_range in ip_range_list: try: yield IPNetwork(ip_range) except AddrFormatError: pass
def test_fip_on_multiple_ip_port(self): network = self.create_network() self.assertIsNotNone(network, "Unable to create network") subnet = self.create_subnet(network) self.assertIsNotNone(subnet, "Unable to create subnet") router = self.create_router( admin_state_up=True, external_network_id=CONF.network.public_network_id) self.assertIsNotNone(router, "Unable to create router") self.create_router_interface(router_id=router["id"], subnet_id=subnet["id"]) # 1. Assigning fip to port with multiple ip address cidr4 = IPNetwork(CONF.network.project_network_cidr) port_args = { 'fixed_ips': [ {'subnet_id': subnet['id'], 'ip_address': str(IPAddress(cidr4.first) + 4)}, {'subnet_id': subnet['id'], 'ip_address': str(IPAddress(cidr4.first) + 5)}, {'subnet_id': subnet['id'], 'ip_address': str(IPAddress(cidr4.first) + 6)}, {'subnet_id': subnet['id'], 'ip_address': str(IPAddress(cidr4.first) + 7)}], } port = self.create_port(network=network, **port_args) floating_ip = self.create_floatingip( external_network_id=CONF.network.public_network_id) self.assertIsNotNone(floating_ip, "Unabe to create floating ip") msg = 'floating ip cannot be associated to port %s ' \ 'because it has multiple ipv4 or multiple ipv6ips' % port['id'] # Neutron does not allow you to attach a fip to a port with multiple # ipv4 ips without specifying which one you attach. self.assertRaisesRegex(exceptions.BadRequest, msg, self.floating_ips_client.update_floatingip, floating_ip['id'], port_id=port['id'], fixed_ip_address=str( IPAddress(cidr4.first) + 4)) # Verify update did not go through floating_ip = self.floating_ips_client.show_floatingip( floating_ip['id'])['floatingip'] self.assertIsNone(floating_ip['port_id']) # Explicit floating ip deletion check self.floating_ips_client.delete_floatingip(floating_ip['id']) # 2. Assigning multiple ip address to a port with fip port = self.create_port(network=network) floating_ip = self.create_floatingip( external_network_id=CONF.network.public_network_id) self.assertIsNotNone(floating_ip, "Unable to create floating ip") self.floating_ips_client.update_floatingip( floating_ip['id'], port_id=port['id']) port_args = { 'fixed_ips': [ {'subnet_id': subnet['id'], 'ip_address': str(IPAddress(cidr4.first) + 8)}, {'subnet_id': subnet['id'], 'ip_address': str(IPAddress(cidr4.first) + 9)}]} msg = ("It is not possible to add multiple ipv4 or multiple ipv6" " addresses on port {} since it has fip {} associated" "to it.").format(port['id'], floating_ip['id']) self.assertRaisesRegex(exceptions.BadRequest, msg, self.update_port, port=port, **port_args) floating_ip = self.floating_ips_client.show_floatingip( floating_ip['id'])['floatingip'] # Explicit floating ip deletion check self.floating_ips_client.delete_floatingip(floating_ip['id'])
def etalon_get_rule(ip): for rule in rules: if IPAddress(ip) in IPNetwork(rule.net) and rule.pred: return rule.handler return None
def _get_host_ip_from_cidr(cidr): return str(IPNetwork(cidr).ip + 1)
def is_suspicious_ip_range(self, ip_range): return not any([IPNetwork(ip_range) in allowed_range for allowed_range in self.whitelisted_ips])
if len(sys.argv) >= 1: try: ip = IPAddress(sys.argv[1]) result = {'status': 'ok', 'matches': []} tables = [] # Fetch tables sp = subprocess.run(['/sbin/pfctl', '-sT'], capture_output=True, text=True) for line in sp.stdout.strip().split('\n'): tables.append(line.strip()) # Fetch IP ranges in this table and check if they match for table in tables: sp = subprocess.run(['/sbin/pfctl', '-t', table, '-T', 'show'], capture_output=True, text=True) for line in sp.stdout.strip().split('\n'): if line.strip() != "": if ip in IPNetwork(line.strip()): result['matches'].append(table) print(ujson.dumps(result)) except AddrFormatError: print(ujson.dumps({'status': 'Invalid IP specified!'})) else: print(ujson.dumps({'status': 'IP parameter not specified!'}))
def ip_in_subnet(self, ip): ipo = IPAddress(ip) net = IPNetwork("%s/%s" % (self.get_ip(), self.get_size())) return ipo in list(net)
def test_form_ipv6(self): form = self.form_class({'field': '2001:0:1::2/64'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], IPNetwork('2001:0:1::2/64'))
def handleEvent(self, event): eventName = event.eventType srcModuleName = event.module eventData = event.data self.debug(f"Received event, {eventName}, from {srcModuleName}") if self.errorState: return if srcModuleName == "sfp_tool_onesixtyone": self.debug("Skipping event from myself.") return if not self.opts['onesixtyone_path']: self.error("You enabled sfp_tool_onesixtyone but did not set a path to the tool!") self.errorState = True return exe = self.opts['onesixtyone_path'] if self.opts['onesixtyone_path'].endswith('/'): exe = f"{exe}onesixtyone" if not os.path.isfile(exe): self.error(f"File does not exist: {exe}") self.errorState = True return if not SpiderFootHelpers.sanitiseInput(eventData, extra=['/']): self.debug("Invalid input, skipping.") return targets = [] try: if eventName == "NETBLOCK_OWNER" and self.opts['netblockscan']: net = IPNetwork(eventData) if net.prefixlen < self.opts['netblockscanmax']: self.debug(f"Skipping scanning of {eventData}, too big.") return for addr in net.iter_hosts(): targets.append(str(addr)) except BaseException as e: self.error(f"Strange netblock identified, unable to parse: {eventData} ({e})") return # Don't look up stuff twice, check IP == IP here if eventData in self.results: self.debug(f"Skipping {eventData} as already scanned.") return else: # Might be a subnet within a subnet or IP within a subnet for addr in self.results: if IPNetwork(eventData) in IPNetwork(addr): self.debug(f"Skipping {eventData} as already within a scanned range.") return self.results[eventData] = True # If we weren't passed a netblock, this will be empty if not targets: targets.append(eventData) for target in targets: args = [ exe, "-c", self.communitiesFile, target ] try: p = Popen(args, stdout=PIPE, stderr=PIPE) out, stderr = p.communicate(input=None) stdout = out.decode(sys.stdin.encoding) except Exception as e: self.error(f"Unable to run onesixtyone: {e}") continue if p.returncode != 0: self.error(f"Unable to read onesixtyone output\nstderr: {stderr}\nstdout: {stdout}") continue if not stdout: self.debug(f"onesixtyone returned no output for {target}") continue for result in stdout.split("\n"): srcevent = event if target not in result: continue if target != eventData: srcevent = SpiderFootEvent("IP_ADDRESS", target, self.__name__, event) self.notifyListeners(srcevent) e = SpiderFootEvent('UDP_PORT_OPEN', f"{target}:161", self.__name__, srcevent) self.notifyListeners(e) e = SpiderFootEvent("UDP_PORT_OPEN_INFO", result, self.__name__, e) self.notifyListeners(e)
except Exception as e: with print_lock: print("[ERROR] [%s] - %s" % (ip_address, e)) finally: semaphore.release() if ip: check_ip(ip) elif filename: with open(filename, "r") as fp: for line in fp: semaphore.acquire() ip_address = line.strip() t = threading.Thread(target=threaded_check, args=(ip_address, )) t.start() elif net: from netaddr import IPNetwork network = IPNetwork(net) for addr in network: # Skip the network and broadcast addresses if (network.size != 1) and ((addr == network.network) or (addr == network.broadcast)): continue semaphore.acquire() ip_address = str(addr) t = threading.Thread(target=threaded_check, args=(ip_address, )) t.start()
@staticmethod def getlinefromip(ip, blockfile) f = open(blockfile, r) # skip header line f.readline() for line in f # a line looks like this # ffff1.0.128.0,113,1605651,1605651,,,,,0,0 startip = line.split(,)[0].split()[-1] # some lines contain ip6 but not ip4 addresses if not startip continue # I don't understand the logic behind subtracting 96 but it works netrange = int(line.split(,)[1]) - 96 # httpstackoverflow.comquestions819355how-can-i-check-if-an-ip-is-in-a-network-in-python if IPAddress(ip) in IPNetwork(startip + + str(netrange)) print(range + startip + + str(netrange)) f.close() return line.strip() f.close() return @staticmethod def getinfofromid(id, locationfile) f = open(locationfile, r) headerline = f.readline() for line in f # a line looks like this # 2921044,EU,Europe,DE,Germany,,,,, if line.startswith(id + ,) f.close()
#print "Protocol: %s %s -> %s" % (ip_header.protocol, ip_header.src_address, ip_header.dst_address) # 如果为ICMP,进行处理 if ip_header.protocol == "ICMP": # 计算ICMP包的起始位置,并获取ICMP包的数据 offset = ip_header.ihl * 4 #ihl是头部长度,代表32位(即4字节)长的分片的个数 [我的理解是因为一个字节表示一个符号,所以这里的offset要搞成以字节为单位的,为的是下一句的提取数据] buf = raw_buffer[offset:offset + sizeof(ICMP)] # 解析ICMP数据 icmp_header = ICMP(buf) #print "ICMP -> Type: %d Code: %d" % (icmp_header.type, icmp_header.code) # 检查类型和代码值是否都为2 if icmp_header.type == 3 and icmp_header.code == 3: # 确认响应的主机再我们的目标子网之内 if IPAddress(ip_header.src_address) in IPNetwork(subnet): # 确认ICMP包中包含我们发送的自定义的字符串 if raw_buffer[len(raw_buffer) - len(magic_message):] == magic_message: print "Host Up: %s" % ip_header.src_address # 处理CTRL-C except KeyboardInterrupt: # 如果运行再Windows上,关闭混杂模式 if os.name == "nt": sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF) #-*- coding:utf8 -*-
from netaddr import IPNetwork ipc = raw_input('Enter The IP Range ') n = 0 #for ip in IPNetwork(ipc): for ip in list(IPNetwork(ipc))[1:-1]: n = n + 1 print '%s' % ip print 'Total No of IPs are ' + str(n) raw_input()
#!/usr/bin/env python """ Get Possible IPs for a specific CIDR Example: $ ./get_ips_from_cidr.py 10.65.36.23/29 Possible IPs for CIDR 10.65.36.23/29: 10.65.36.16 10.65.36.17 10.65.36.18 10.65.36.19 10.65.36.20 10.65.36.21 10.65.36.22 10.65.36.23 """ from netaddr import IPNetwork import argparse parser = argparse.ArgumentParser() parser.add_argument("cidr") args = parser.parse_args() cidr = args.cidr print "Possible IPs for CIDR {}:".format(cidr) for ip in IPNetwork(cidr): print ip
def _generate_addresses(self, version=1): """Generate the various addresses needed for this interface.""" v1_config = [] v2_cidrs = [] v2_config = {} v2_nameservers = {} addresses = list( self.iface.ip_addresses.exclude(alloc_type__in=[ IPADDRESS_TYPE.DISCOVERED, IPADDRESS_TYPE.DHCP ]).order_by("id")) dhcp_type = self._get_dhcp_type() if _is_link_up(addresses) and not dhcp_type: if version == 1: v1_config.append({"type": "manual"}) else: for address in addresses: subnet = address.subnet if subnet is not None: subnet_len = subnet.cidr.split("/")[1] cidr = "%s/%s" % (str(address.ip), subnet_len) v1_subnet_operation = {"type": "static", "address": cidr} if address.ip is not None: # If the address is None, that means we're generating a # preseed for a Node that is not (or is no longer) in # the READY state; so it might have auto-assigned IP # addresses which have not yet been determined. It # would be nice if there was a way to express this, if # only for debugging purposes. For now, just ignore # such addresses. v1_subnet_operation["address"] = cidr v2_cidrs.append(cidr) if "addresses" not in v2_config: v2_config["addresses"] = v2_cidrs v1_config.append(v1_subnet_operation) self.addr_family_present[IPNetwork( subnet.cidr).version] = True matching_subnet_routes = self._get_matching_routes(subnet) # Keep track of routes which apply to the context of this # interface for rendering the v2 YAML. self.matching_routes.update(matching_subnet_routes) # The default gateway is set on the subnet operation for # the v1 YAML, but it's per-interface for the v2 YAML. self._set_default_gateway( subnet, v1_subnet_operation if version == 1 else v2_config, version, ) if "dns_nameservers" not in v1_subnet_operation: v1_subnet_operation["dns_nameservers"] = [] v1_subnet_operation[ "dns_search"] = self.node_config.default_search_list if "nameservers" not in v2_config: v2_nameservers[ "search"] = self.node_config.default_search_list v2_config["nameservers"] = v2_nameservers if "addresses" not in v2_nameservers: v2_nameservers["addresses"] = [] if subnet.allow_dns: for ip in StaticIPAddress.objects.filter( interface__node__in=[ subnet.vlan.primary_rack, subnet.vlan.secondary_rack, ], subnet__vlan=subnet.vlan, alloc_type__in=[ IPADDRESS_TYPE.AUTO, IPADDRESS_TYPE.STICKY, ], ).exclude(ip=None): if ip.ip in v2_nameservers["addresses"]: continue ip_address = IPAddress(ip.ip) if ip_address.version != subnet.get_ip_version(): continue if not subnet.gateway_ip: if ip_address not in subnet.get_ipnetwork(): # without gateway, only use in-subnet addrs continue v1_subnet_operation["dns_nameservers"].append( ip.ip) v2_nameservers["addresses"].append(ip.ip) for ip in subnet.dns_servers: if ip in v2_nameservers["addresses"]: continue v1_subnet_operation["dns_nameservers"].append(ip) v2_nameservers["addresses"].append(ip) if len(matching_subnet_routes) > 0 and version == 1: # For the v1 YAML, the list of routes is rendered # within the context of each subnet. routes = self._generate_route_operations( matching_subnet_routes, version=version) v1_subnet_operation["routes"] = routes # Delete if no DNS servers were added. if len(v1_subnet_operation["dns_nameservers"]) == 0: del v1_subnet_operation["dns_nameservers"] del v1_subnet_operation["dns_search"] if len(v2_nameservers["addresses"]) == 0: del v2_config["nameservers"] if dhcp_type: v1_config.append({"type": dhcp_type}) if dhcp_type == "dhcp": v2_config.update({"dhcp4": True, "dhcp6": True}) elif dhcp_type == "dhcp4": v2_config.update({"dhcp4": True}) elif dhcp_type == "dhcp6": v2_config.update({"dhcp6": True}) if version == 1: return v1_config elif version == 2: return v2_config
import os import socket # import fcntl # import struct import psutil import netaddr from netaddr import IPNetwork from oslocfg import cfg CONF = cfg.CONF CLASSA = IPNetwork('10.0.0.0/255.0.0.0') CLASSB = IPNetwork('172.16.0.0/255.240.0.0') CLASSC = IPNetwork('192.168.0.0/255.255.0.0') CLASST = IPNetwork('100.64.0.0/255.192.0.0') INTERNALS = frozenset([CLASSA, CLASSB, CLASSC, CLASST]) def register_guess(name, func): addresBase.GUESSPLUGUNS.setdefault(name, func) class addresBase(object): GUESSPLUGUNS = {} def __init__(self):
def _generate_addresses(self, version=1): """Generate the various addresses needed for this interface.""" v1_config = [] v2_cidrs = [] v2_config = {} v2_nameservers = {} addresses = list( self.iface.ip_addresses.exclude( alloc_type__in=[ IPADDRESS_TYPE.DISCOVERED, IPADDRESS_TYPE.DHCP, ]).order_by('id')) dhcp_type = self._get_dhcp_type() if _is_link_up(addresses) and not dhcp_type: if version == 1: v1_config.append({"type": "manual"}) else: for address in addresses: subnet = address.subnet if subnet is not None: subnet_len = subnet.cidr.split('/')[1] cidr = "%s/%s" % (str(address.ip), subnet_len) v1_subnet_operation = { "type": "static", "address": cidr } if address.ip is not None: # If the address is None, that means we're generating a # preseed for a Node that is not (or is no longer) in # the READY state; so it might have auto-assigned IP # addresses which have not yet been determined. It # would be nice if there was a way to express this, if # only for debugging purposes. For now, just ignore # such addresses. v1_subnet_operation['address'] = cidr v2_cidrs.append(cidr) if "addresses" not in v2_config: v2_config["addresses"] = v2_cidrs v1_config.append(v1_subnet_operation) self.addr_family_present[ IPNetwork(subnet.cidr).version] = True # The default gateway is set on the subnet operation for # the v1 YAML, but it's per-interface for the v2 YAML. self._set_default_gateway( subnet, v1_subnet_operation if version == 1 else v2_config) if (subnet.dns_servers is not None and len(subnet.dns_servers) > 0): v1_subnet_operation["dns_nameservers"] = ( subnet.dns_servers) if "nameservers" not in v2_config: v2_config["nameservers"] = v2_nameservers # XXX should also support search paths. if "addresses" not in v2_nameservers: v2_nameservers["addresses"] = [] v2_nameservers["addresses"].extend( [server for server in subnet.dns_servers]) matching_subnet_routes = self._get_matching_routes(subnet) if len(matching_subnet_routes) > 0 and version == 1: # For the v1 YAML, the list of routes is rendered # within the context of each subnet. routes = self._generate_route_operations( matching_subnet_routes, version=version) v1_subnet_operation['routes'] = routes # Keep track of routes which apply to the context of this # interface for rendering the v2 YAML. self.matching_routes.update(matching_subnet_routes) if dhcp_type: v1_config.append( {"type": dhcp_type} ) if dhcp_type == "dhcp": v2_config.update({ "dhcp4": True, "dhcp6": True, }) elif dhcp_type == "dhcp4": v2_config.update({ "dhcp4": True, }) elif dhcp_type == "dhcp6": v2_config.update({ "dhcp6": True, }) if version == 1: return v1_config elif version == 2: return v2_config
def handleEvent(self, event): eventName = event.eventType srcModuleName = event.module eventData = event.data if self.errorState: return None self.sf.debug(f"Received event, {eventName}, from {srcModuleName}") # Don't look up stuff twice if eventData in self.results: self.sf.debug(f"Skipping {eventData}, already checked.") return None else: self.results[eventData] = True if eventName == 'NETBLOCK_OWNER': if not self.opts['netblocklookup']: return None if IPNetwork(eventData).prefixlen < self.opts['maxnetblock']: self.sf.debug("Network size bigger than permitted: " + str(IPNetwork(eventData).prefixlen) + " > " + str(self.opts['maxnetblock'])) return None if eventName == 'NETBLOCK_MEMBER': if not self.opts['subnetlookup']: return None if IPNetwork(eventData).prefixlen < self.opts['maxsubnet']: self.sf.debug("Network size bigger than permitted: " + str(IPNetwork(eventData).prefixlen) + " > " + str(self.opts['maxsubnet'])) return None qrylist = list() if eventName.startswith("NETBLOCK_"): for ipaddr in IPNetwork(eventData): qrylist.append(str(ipaddr)) self.results[str(ipaddr)] = True else: # If user has enabled affiliate checking if eventName == "AFFILIATE_IPADDR" and not self.opts[ 'checkaffiliates']: return None qrylist.append(eventData) for addr in qrylist: if self.checkForStop(): return None data = self.queryIPAddress(addr) if data is None: break try: maliciousIP = data[0].get('ip') except: # If ArrayIndex is out of bounds then data doesn't exist continue if maliciousIP is None: continue if addr != maliciousIP: self.sf.error( "Reported address doesn't match requested, skipping", False) continue # Data is reported about the IP Address if eventName.startswith("NETBLOCK_"): ipEvt = SpiderFootEvent("IP_ADDRESS", addr, self.__name__, event) self.notifyListeners(ipEvt) if eventName.startswith("NETBLOCK_"): evt = SpiderFootEvent("RAW_RIR_DATA", str(data), self.__name__, ipEvt) self.notifyListeners(evt) else: evt = SpiderFootEvent("RAW_RIR_DATA", str(data), self.__name__, event) self.notifyListeners(evt) maliciousIPDesc = "Phishstats [" + str(maliciousIP) + "]\n" maliciousIPDescHash = self.sf.hashstring(maliciousIPDesc) if maliciousIPDescHash in self.results: continue self.results[maliciousIPDescHash] = True if eventName.startswith("NETBLOCK_"): evt = SpiderFootEvent("MALICIOUS_IPADDR", maliciousIPDesc, self.__name__, ipEvt) elif eventName.startswith("AFFILIATE_"): evt = SpiderFootEvent("MALICIOUS_AFFILIATE_IPADDR", maliciousIPDesc, self.__name__, event) else: evt = SpiderFootEvent("MALICIOUS_IPADDR", maliciousIPDesc, self.__name__, event) self.notifyListeners(evt) return None
def ping(self, targets=list(), filename=str(), status=str()): """ Attempt to ping a list of hosts or networks (can be a single host) :param targets: List - Name(s) or IP(s) of the host(s). :param filename: String - name of the file containing hosts to ping :param status: String - if one of ['alive', 'dead', 'noip'] then only return results that have that status. If this is not specified, then all results will be returned. :return: Type and results depends on whether status is specified: if status == '': return dict: {targets: results} if status != '': return list: targets if targets == status """ if targets and filename: raise SyntaxError("You must specify only one of either targets=[] " "or filename=''.") elif not targets and not filename: raise SyntaxError("You must specify either a list of targets or " "filename='', but not both.") elif filename: targets = self.read_file(filename) my_targets = {'hosts': [], 'nets': []} addresses = [] # Check for valid networks and add hosts and nets to my_targets for target in targets: # Targets may include networks in the format "network mask", or, # a file could contain multiple hosts or IP's on a single line. if len(target.split()) > 1: target_items = target.split() for item in target_items: try: ip = IPAddress(item) # If it is an IPv4 address or mask put in in addresses if ip.version == 4: addresses.append(str(ip)) except AddrFormatError: # IP Address not detected, so assume it's a host name my_targets['hosts'].append(item) except ValueError: # CIDR network detected net = IPNetwork(item) # Make sure it is a CIDR address acceptable to fping if net.ip.is_unicast() and net.version == 4 and \ net.netmask.netmask_bits() in range(8, 31): my_targets['nets'].append(target_items[0]) else: msg = str(str(net) + ':Only IPv4 unicast addresses' ' with bit masks\n ' ' from 8 to 30 are supported.') raise AttributeError(msg) # Iterate over the IP strings in addresses while len(addresses) > 1: ip = IPAddress(addresses[0]) mask = IPAddress(addresses[1]) # Test to see if IP is unicast, and mask is an actual mask if ip.is_unicast() and mask.is_netmask(): net = IPNetwork(str(ip) + '/' + str( mask.netmask_bits())) # Convert ip and mask to CIDR and remove from addresses my_targets['nets'].append(str(net.cidr)) addresses.pop(0) addresses.pop(0) elif ip.is_unicast() and not ip.is_netmask(): # mask was not a mask so only remove IP and start over my_targets['hosts'].append(str(ip)) addresses.pop(0) # There could be one more item in addresses, so check it if addresses: ip = IPAddress(addresses[0]) if ip.is_unicast() and not ip.is_netmask(): my_targets['hosts'].append(addresses[0]) addresses.pop() # target has only one item, so check it else: try: ip = IPAddress(target) if ip.version == 4 and ip.is_unicast() and \ not ip.is_netmask(): my_targets['hosts'].append(target) else: msg = str(target + 'Only IPv4 unicast addresses are ' 'supported.') raise AttributeError(msg) except AddrFormatError: # IP Address not detected, so assume it's a host name my_targets['hosts'].append(target) except ValueError: # CIDR network detected net = IPNetwork(target) if net.ip.is_unicast() and net.version == 4 and \ net.netmask.netmask_bits() in range(8, 31): my_targets['nets'].append(target) else: msg = str(str(net) + ':Only IPv4 unicast addresses' ' with bit masks\n ' ' from 8 to 30 are supported.') raise AttributeError(msg) """ Build the list of commands to run. """ commands = [] if len(my_targets['hosts']) != 0: for target in range(len(my_targets['hosts'])): commands.append([self.fping, '-nV', my_targets['hosts'][ target]]) if len(my_targets['nets']) != 0: for target in range(len(my_targets['nets'])): commands.append([self.fping, '-ngV', my_targets['nets'][ target]]) """ Start pinging each item in my_targets and return the requested results when done. """ pool = ThreadPool(self.num_pools) raw_results = pool.map(self.get_results, commands) pool.close() pool.join() self.results = {host: result for host, result in csv.reader( ''.join(raw_results).splitlines())} if not status: return self.results elif status == 'alive': return self.alive elif status == 'dead': return self.dead elif status == 'noip': return self.noip else: raise SyntaxError("Valid status options are 'alive', 'dead' or " "'noip'")
def _get_provisioning_cidr6(cidr, ns_index): provisioning_cidr = IPNetwork(cidr) provisioning_cidr += ns_index for _ in range(4): provisioning_cidr += (1 << 63) return str(provisioning_cidr)
def handleEvent(self, event): eventName = event.eventType srcModuleName = event.module eventData = event.data if self.errorState: return self.debug(f"Received event, {eventName}, from {srcModuleName}") if self.opts["api_key"] == "": self.error( f"You enabled {self.__class__.__name__} but did not set an API key!" ) self.errorState = True return if eventData in self.results: self.debug(f"Skipping {eventData}, already checked.") return self.results[eventData] = True if eventName.startswith( "AFFILIATE") and not self.opts['checkaffiliates']: return if eventName == 'CO_HOSTED_SITE' and not self.opts['checkcohosts']: return if eventName == 'NETBLOCK_OWNER': if not self.opts['netblocklookup']: return net_size = IPNetwork(eventData).prefixlen max_netblock = self.opts['maxnetblock'] if net_size < max_netblock: self.debug( f"Network size {net_size} bigger than permitted: {max_netblock}" ) return if eventName == 'NETBLOCK_MEMBER': if not self.opts['subnetlookup']: return net_size = IPNetwork(eventData).prefixlen max_subnet = self.opts['maxsubnet'] if net_size < max_subnet: self.debug( f"Network size {net_size} bigger than permitted: {max_subnet}" ) return qrylist = list() if eventName.startswith("NETBLOCK_"): for ipaddr in IPNetwork(eventData): qrylist.append(str(ipaddr)) self.results[str(ipaddr)] = True else: qrylist.append(eventData) for addr in qrylist: if self.checkForStop(): return if self.sf.validIP(addr): info = self.queryIp(addr) else: info = self.queryDomain(addr) if info is None: continue if len(info.get('detected_urls', [])) > 0: self.info(f"Found VirusTotal URL data for {addr}") if eventName in ["IP_ADDRESS" ] or eventName.startswith("NETBLOCK_"): evt = "MALICIOUS_IPADDR" infotype = "ip-address" if eventName == "AFFILIATE_IPADDR": evt = "MALICIOUS_AFFILIATE_IPADDR" infotype = "ip-address" if eventName == "INTERNET_NAME": evt = "MALICIOUS_INTERNET_NAME" infotype = "domain" if eventName == "AFFILIATE_INTERNET_NAME": evt = "MALICIOUS_AFFILIATE_INTERNET_NAME" infotype = "domain" if eventName == "CO_HOSTED_SITE": evt = "MALICIOUS_COHOST" infotype = "domain" infourl = f"<SFURL>https://www.virustotal.com/en/{infotype}/{addr}/information/</SFURL>" e = SpiderFootEvent(evt, f"VirusTotal [{addr}]\n{infourl}", self.__name__, event) self.notifyListeners(e) domains = list() # Treat siblings as affiliates if they are of the original target, otherwise # they are additional hosts within the target. if 'domain_siblings' in info: if eventName in ["IP_ADDRESS", "INTERNET_NAME"]: for domain in info['domain_siblings']: domains.append(domain) if 'subdomains' in info: if eventName == "INTERNET_NAME": for domain in info['subdomains']: domains.append(domain) for domain in set(domains): if domain in self.results: continue if self.getTarget().matches(domain): evt_type = 'INTERNET_NAME' else: evt_type = 'AFFILIATE_INTERNET_NAME' if self.opts['verify'] and not self.sf.resolveHost( domain) and not self.sf.resolveHost6(domain): self.debug(f"Host {domain} could not be resolved") evt_type += '_UNRESOLVED' evt = SpiderFootEvent(evt_type, domain, self.__name__, event) self.notifyListeners(evt) if self.sf.isDomain(domain, self.opts['_internettlds']): if evt_type.startswith('AFFILIATE'): evt = SpiderFootEvent('AFFILIATE_DOMAIN_NAME', domain, self.__name__, event) self.notifyListeners(evt) else: evt = SpiderFootEvent('DOMAIN_NAME', domain, self.__name__, event) self.notifyListeners(evt)
def _get_provisioning_cidr(cidr, ns_index): provisioning_cidr = IPNetwork(cidr) provisioning_cidr += ns_index + consts.NAMESPACE_POOL_SIZE return str(provisioning_cidr)
def handleEvent(self, event): eventName = event.eventType srcModuleName = event.module eventData = event.data if srcModuleName == "sfp_tool_nmap": self.debug("Skipping event from myself.") return self.debug(f"Received event, {eventName}, from {srcModuleName}") if self.errorState: return try: if eventName == "NETBLOCK_OWNER" and self.opts['netblockscan']: net = IPNetwork(eventData) if net.prefixlen < self.opts['netblockscanmax']: self.debug("Skipping port scanning of " + eventData + ", too big.") return except Exception as e: self.error("Strange netblock identified, unable to parse: " + eventData + " (" + str(e) + ")") return # Don't look up stuff twice, check IP == IP here if eventData in self.results: self.debug("Skipping " + eventData + " as already scanned.") return else: # Might be a subnet within a subnet or IP within a subnet for addr in self.results: if IPNetwork(eventData) in IPNetwork(addr): self.debug("Skipping " + eventData + " as already within a scanned range.") return self.results[eventData] = True if not self.opts['nmappath']: self.error("You enabled sfp_tool_nmap but did not set a path to the tool!") self.errorState = True return # Normalize path if self.opts['nmappath'].endswith('nmap'): exe = self.opts['nmappath'] elif self.opts['nmappath'].endswith('/'): exe = self.opts['nmappath'] + "nmap" else: self.error("Could not recognize your nmap path configuration.") self.errorState = True return # If tool is not found, abort if not os.path.isfile(exe): self.error("File does not exist: " + exe) self.errorState = True return # Sanitize domain name. if not self.sf.validIP(eventData) and not self.sf.validIpNetwork(eventData): self.error("Invalid input, refusing to run.") return try: p = Popen([exe, "-O", "--osscan-limit", eventData], stdout=PIPE, stderr=PIPE) stdout, stderr = p.communicate(input=None) if p.returncode == 0: content = stdout.decode('utf-8', errors='replace') else: self.error("Unable to read Nmap content.") self.debug(f"Error running Nmap: {stderr}, {stdout}") return if "No exact OS matches for host" in content or "OSScan results may be unreliable" in content: self.debug(f"Couldn't reliably detect the OS for {eventData}") return except Exception as e: self.error(f"Unable to run Nmap: {e}") return if not content: self.debug("No content from Nmap to parse.") return if eventName == "IP_ADDRESS": try: opsys = None for line in content.split('\n'): if "OS details:" in line: junk, opsys = line.split(": ") if opsys: evt = SpiderFootEvent("OPERATING_SYSTEM", opsys, self.__name__, event) self.notifyListeners(evt) except Exception as e: self.error("Couldn't parse the output of Nmap: " + str(e)) return if eventName == "NETBLOCK_OWNER": try: currentIp = None for line in content.split('\n'): opsys = None if "scan report for" in line: currentIp = line.split("(")[1].replace(")", "") if "OS details:" in line: junk, opsys = line.split(": ") if opsys and currentIp: ipevent = SpiderFootEvent("IP_ADDRESS", currentIp, self.__name__, event) self.notifyListeners(ipevent) evt = SpiderFootEvent("OPERATING_SYSTEM", opsys, self.__name__, ipevent) self.notifyListeners(evt) currentIp = None except Exception as e: self.error(f"Couldn't parse the output of Nmap: {e}") return
def handleEvent(self, event): eventName = event.eventType srcModuleName = event.module eventData = event.data if self.errorState: return None self.sf.debug("Received event, %s, from %s" % (eventName, srcModuleName)) if self.opts['api_key'] == "": self.sf.error( "You enabled sfp_alienvault but did not set an API key/password!", False) self.errorState = True return None # Don't look up stuff twice if eventData in self.results: self.sf.debug("Skipping " + eventData + " as already mapped.") return None else: self.results[eventData] = True if eventName == 'NETBLOCK_OWNER': if not self.opts['netblocklookup']: return None else: if IPNetwork(eventData).prefixlen < self.opts['maxnetblock']: self.sf.debug("Network size bigger than permitted: " + str(IPNetwork(eventData).prefixlen) + " > " + str(self.opts['maxnetblock'])) return None if eventName == 'AFFILIATE_IPADDR' and not self.opts.get( 'checkaffiliates', False): return None if eventName == 'NETBLOCK_MEMBER': if not self.opts['subnetlookup']: return None else: if IPNetwork(eventData).prefixlen < self.opts['maxsubnet']: self.sf.debug("Network size bigger than permitted: " + str(IPNetwork(eventData).prefixlen) + " > " + str(self.opts['maxsubnet'])) return None qrylist = list() if eventName.startswith("NETBLOCK_"): for ipaddr in IPNetwork(eventData): qrylist.append(str(ipaddr)) self.results[str(ipaddr)] = True else: qrylist.append(eventData) # For IP Addresses, do the additional passive DNS lookup if eventName == "IP_ADDRESS": evtType = "CO_HOSTED_SITE" ret = self.query(eventData, "passve_dns") if ret is None: self.sf.info("No Passive DNS info for " + eventData) elif "passve_dns" in ret: self.sf.debug("Found passive DNS results in AlienVault OTX") res = ret["passive_dns"] for rec in res: if "hostname" in rec: host = rec['hostname'] try: last = rec.get("last", "") last_dt = datetime.strptime( last, '%Y-%m-%d %H:%M:%S') last_ts = int(time.mktime(last_dt.timetuple())) age_limit_ts = int(time.time()) - ( 86400 * self.opts['age_limit_days']) if self.opts[ 'age_limit_days'] > 0 and last_ts < age_limit_ts: self.sf.debug( "Record found but too old, skipping.") continue except BaseException as e: self.sf.debug( "Couldn't parse date from AlienVault so assuming it's OK." ) e = SpiderFootEvent(evtType, host, self.__name__, event) self.notifyListeners(e) for addr in qrylist: if self.checkForStop(): return None if eventName == 'IP_ADDRESS' or eventName.startswith('NETBLOCK_'): evtType = 'MALICIOUS_IPADDR' if eventName == "AFFILIATE_IPADDR": evtType = 'MALICIOUS_AFFILIATE_IPADDR' rec = self.query(addr, "reputation") if rec is not None: if rec.get("reputation", None): self.sf.debug("Found reputation info in AlienVault OTX") rec_history = rec['reputation'].get("activities", list()) if rec['reputation']['threat_score'] < self.opts[ 'threat_score_min']: continue descr = "AlienVault Threat Score: " + str( rec['reputation']['threat_score']) + ":" for result in rec_history: nm = result.get("name", None) if nm is None or nm in descr: continue descr += "\n - " + nm created = result.get("last_date", "") # 2014-11-06T10:45:00.000 try: created_dt = datetime.strptime( created, '%Y-%m-%dT%H:%M:%S') created_ts = int( time.mktime(created_dt.timetuple())) age_limit_ts = int(time.time()) - ( 86400 * self.opts['age_limit_days']) if self.opts[ 'age_limit_days'] > 0 and created_ts < age_limit_ts: self.sf.debug( "Record found but too old, skipping.") continue except BaseException as e: self.sf.debug( "Couldn't parse date from AlienVault so assuming it's OK." ) # For netblocks, we need to create the IP address event so that # the threat intel event is more meaningful. if eventName.startswith('NETBLOCK_'): pevent = SpiderFootEvent("IP_ADDRESS", addr, self.__name__, event) self.notifyListeners(pevent) else: pevent = event e = SpiderFootEvent(evtType, descr, self.__name__, pevent) self.notifyListeners(e)
def clone(self): """ Command Section: clone Clone a VM from a template """ self.config['hostname'] = self.config['hostname'].lower() self.config['mem'] = int(self.config['mem'] * 1024) # convert GB to MB print "Cloning %s to new host %s with %sMB RAM..." % ( self.config['template'], self.config['hostname'], 'same ammount of ' if self.config['mem'] == 0 else self.config['mem']) # initialize a list to hold our network settings ip_settings = list() # Get network settings for each IP net_data = self.config['ips'] matched_network = None for network in self.config['networks']: if (net_data == network) and ( self.config['networks'][network]['type'] == 'dhcp'): # we got a match for a network with dhcp matched_network = network break # if no matched network yet, try to match static settings if not matched_network: ip = IPAddress(net_data) for network in self.config['networks']: if self.config['networks'][network]['type'] != 'static': continue if ip not in IPNetwork( self.config['networks'][network]['network']): continue self.config['networks'][network]['ip'] = ip ipnet = IPNetwork(self.config['networks'][network]['network']) self.config['networks'][network]['subnet_mask'] = str( ipnet.netmask) ip_settings.append(self.config['networks'][network]) matched_network = network break if not matched_network: print "I don't know what network %s is in. You can supply " \ "settings for this network in config.yml." % net_data sys.exit(1) network_label = self.config['networks'][matched_network][ 'network_label'] self.get_obj([vim.Network], network_label) # validate VLAN datacenter = self.get_obj( [vim.Datacenter], self.config['networks'][matched_network]['datacenter']) destfolder = datacenter.vmFolder cluster = self.get_obj( [vim.ClusterComputeResource], self.config['networks'][matched_network]['cluster']) relospec = vim.vm.RelocateSpec() datastore = self.get_obj( [vim.Datastore], self.config['networks'][matched_network]['datastore']) relospec.datastore = datastore resource_pool_str = self.config['resource_pool'] if resource_pool_str == 'Resources' and ( 'resource_pool' in self.config['networks'][matched_network]): resource_pool_str = self.config['networks'][matched_network][ 'resource_pool'] resource_pool = self.get_resource_pool(cluster, resource_pool_str) if resource_pool: relospec.pool = resource_pool host_system = self.config['host'] if host_system != "": host_system = self.get_obj([vim.HostSystem], self.config['host']) if host_system: relospec.host = host_system template_vm = self.get_vm_failfast(self.config['template'], False, 'Template VM') devices = [] # delete existing NIC devices from template try: for device in template_vm.config.hardware.device: if hasattr(device, 'addressType'): # this is a VirtualEthernetCard, so we'll delete it nic = vim.vm.device.VirtualDeviceSpec() nic.operation = \ vim.vm.device.VirtualDeviceSpec.Operation.remove nic.device = device devices.append(nic) except: # not the most graceful handling, but unable to reproduce # user's issues in #57 at this time. pass # add a new NIC device nic = vim.vm.device.VirtualDeviceSpec() nic.operation = vim.vm.device.VirtualDeviceSpec.Operation.add nic.device = vim.vm.device.VirtualVmxnet3() nic.device.wakeOnLanEnabled = True nic.device.addressType = 'assigned' nic.device.key = 4000 # 4000 seems to be the value to use for a vmxnet3 device nic.device.deviceInfo = vim.Description() nic.device.deviceInfo.label = 'Network adapter %s' % (1) nic.device.deviceInfo.summary = network_label nic.device.backing = ( vim.vm.device.VirtualEthernetCard.NetworkBackingInfo()) nic.device.backing.network = (self.get_obj([vim.Network], network_label)) nic.device.backing.deviceName = network_label nic.device.backing.useAutoDetect = True nic.device.connectable = vim.vm.device.VirtualDevice.ConnectInfo() nic.device.connectable.startConnected = True nic.device.connectable.allowGuestControl = True devices.append(nic) adaptermaps = [] if self.config['networks'][matched_network]['type'] == 'dhcp': guest_map = vim.vm.customization.AdapterMapping() guest_map.adapter = vim.vm.customization.IPSettings( ip=vim.vm.customization.DhcpIpGenerator(), dnsDomain='domain.local') adaptermaps.append(guest_map) else: # guest NIC settings, i.e. 'adapter map' guest_map = vim.vm.customization.AdapterMapping() guest_map.adapter = vim.vm.customization.IPSettings() guest_map.adapter.ip = vim.vm.customization.FixedIp() guest_map.adapter.ip.ipAddress = str( self.config['networks'][matched_network]['ip']) guest_map.adapter.subnetMask = str( self.config['networks'][matched_network]['subnet_mask']) # these may not be set for certain IPs try: guest_map.adapter.gateway = self.config['networks'][ matched_network]['gateway'] except: pass try: guest_map.adapter.dnsDomain = self.config['domain'] except: pass adaptermaps.append(guest_map) if len(adaptermaps) == 0: print "I cannot apply network settings to new VM" sys.exit(1) # VM config spec vmconf = vim.vm.ConfigSpec() if self.config['cpus'] == 0: vmconf.numCPUs = template_vm.summary.config.numCpu else: vmconf.numCPUs = self.config['cpus'] if self.config['mem'] == 0: vmconf.memoryMB = template_vm.summary.config.memorySizeMB else: vmconf.memoryMB = self.config['mem'] vmconf.cpuHotAddEnabled = True vmconf.memoryHotAddEnabled = True vmconf.deviceChange = devices # DNS settings globalip = vim.vm.customization.GlobalIPSettings() globalip.dnsServerList = self.config['dns_servers'] globalip.dnsSuffixList = self.config['domain'] # Hostname settings ident = vim.vm.customization.LinuxPrep() ident.domain = self.config['domain'] ident.hostName = vim.vm.customization.FixedName() ident.hostName.name = self.config['hostname'] customspec = vim.vm.customization.Specification() customspec.nicSettingMap = adaptermaps customspec.globalIPSettings = globalip customspec.identity = ident # Clone spec clonespec = vim.vm.CloneSpec() clonespec.location = relospec clonespec.config = vmconf clonespec.customization = customspec clonespec.powerOn = not self.config['suppress_power_on'] clonespec.template = False self.addDisks(template_vm, clonespec) if self.debug: self.print_debug("CloneSpec", clonespec) # fire the clone task tasks = [ template_vm.Clone(folder=destfolder, name=self.config['hostname'], spec=clonespec) ] result = self.WaitForTasks(tasks) if self.config['post_clone_cmd']: try: # helper env variables os.environ['EZMOMI_CLONE_HOSTNAME'] = self.config['hostname'] print "Running --post-clone-cmd %s" % \ self.config['post_clone_cmd'] os.system(self.config['post_clone_cmd']) except Exception as e: print "Error running post-clone command. Exception: %s" % e pass # send notification email if self.config['mail']: self.send_email()
def test_form_ipv4_valid(self): form = self.form_class({'field': '10.0.0.1/24'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], IPNetwork('10.0.0.1/24'))