def render(self, session, dbuser, ip, netmask, prefixlen, network_environment, **arguments): if netmask: # There must me a faster way, but this is the easy one net = IPv4Network("127.0.0.0/%s" % netmask) prefixlen = net.prefixlen if prefixlen is None or prefixlen < 8 or prefixlen > 31: raise ArgumentError("The prefix length must be between 8 and 31.") dbnet_env = NetworkEnvironment.get_unique_or_default( session, network_environment) self.az.check_network_environment(dbuser, dbnet_env) dbnetwork = get_net_id_from_ip(session, ip, network_environment=dbnet_env) if prefixlen >= dbnetwork.cidr: raise ArgumentError("The specified --prefixlen must be smaller " "than the current value.") # IPv4Network has a supernet() object, but that does not normalize the # IP address, i.e. IPv4Network('1.2.3.0/24').supernet() will return # IPv4Network('1.2.3.0/23'). Do the normalization manually. supernet = dbnetwork.network.supernet(new_prefix=prefixlen) supernet = IPv4Network("%s/%d" % (supernet.network, supernet.prefixlen)) q = session.query(Network) q = q.filter_by(network_environment=dbnet_env) q = q.filter( and_(Network.ip >= supernet.ip, Network.ip < supernet.broadcast)) q = q.order_by(Network.ip) dbnets = q.all() if dbnets[0].ip == supernet.ip: dbsuper = dbnets.pop(0) dbsuper.cidr = prefixlen else: # Create a new network, copying the parameters from the one # specified on the command line dbsuper = Network(name=dbnetwork.name, network=supernet, network_environment=dbnet_env, location=dbnetwork.location, side=dbnetwork.side, comments=dbnetwork.comments) session.add(dbsuper) for oldnet in dbnets: # Delete routers of the old subnets for dbrouter in oldnet.routers: map(delete_dns_record, dbrouter.dns_records) oldnet.routers = [] fix_foreign_links(session, oldnet, dbsuper) session.delete(oldnet) session.flush()
def render(self, session, dbuser, ip, netmask, prefixlen, network_environment, **arguments): if netmask: # There must me a faster way, but this is the easy one net = IPv4Network("127.0.0.0/%s" % netmask) prefixlen = net.prefixlen if prefixlen is None or prefixlen < 8 or prefixlen > 31: raise ArgumentError("The prefix length must be between 8 and 31.") dbnet_env = NetworkEnvironment.get_unique_or_default(session, network_environment) self.az.check_network_environment(dbuser, dbnet_env) dbnetwork = get_net_id_from_ip(session, ip, network_environment=dbnet_env) if prefixlen >= dbnetwork.cidr: raise ArgumentError("The specified --prefixlen must be smaller " "than the current value.") # IPv4Network has a supernet() object, but that does not normalize the # IP address, i.e. IPv4Network('1.2.3.0/24').supernet() will return # IPv4Network('1.2.3.0/23'). Do the normalization manually. supernet = dbnetwork.network.supernet(new_prefix=prefixlen) supernet = IPv4Network("%s/%d" % (supernet.network, supernet.prefixlen)) q = session.query(Network) q = q.filter_by(network_environment=dbnet_env) q = q.filter(and_(Network.ip >= supernet.ip, Network.ip < supernet.broadcast)) q = q.order_by(Network.ip) dbnets = q.all() if dbnets[0].ip == supernet.ip: dbsuper = dbnets.pop(0) dbsuper.cidr = prefixlen else: # Create a new network, copying the parameters from the one # specified on the command line dbsuper = Network(name=dbnetwork.name, network=supernet, network_environment=dbnet_env, location=dbnetwork.location, side=dbnetwork.side, comments=dbnetwork.comments) session.add(dbsuper) for oldnet in dbnets: # Delete routers of the old subnets for dbrouter in oldnet.routers: map(delete_dns_record, dbrouter.dns_records) oldnet.routers = [] fix_foreign_links(session, oldnet, dbsuper) session.delete(oldnet) session.flush()
if orig_net == supernet: # Split: # AQ: ******** (one big network) # QIP: --**++++ (smaller networks, some may be missing) if keep_aqnet: # The first subnet was handled above by setting # aqnet.cidr qipinfo = heap_pop(qipnets) else: # The first subnet was deleted pass while qipinfo and qipinfo.address.ip in orig_net: newnet = self.add_network(qipinfo) # Redirect addresses from the split network to the new # subnet fix_foreign_links(self.session, aqnet, newnet) qipinfo = heap_pop(qipnets) if keep_aqnet: self.check_split_network(aqnet) else: self.del_network(aqnet) aqnet = heap_pop(aqnets) else: # Merge: # AQ: --++**** (smaller networks, some may be missing) # QIP: ******** (one big network) if keep_aqnet: # The first subnet was handled above by setting # aqnet.cidr newnet = aqnet aqnet = heap_pop(aqnets)
def render(self, session, dbuser, ip, netmask, prefixlen, network_environment, **arguments): if netmask: # There must me a faster way, but this is the easy one net = IPv4Network("127.0.0.0/%s" % netmask) prefixlen = net.prefixlen if prefixlen < 8 or prefixlen > 32: raise ArgumentError("The prefix length must be between 8 and 32.") dbnet_env = NetworkEnvironment.get_unique_or_default(session, network_environment) self.az.check_network_environment(dbuser, dbnet_env) dbnetwork = get_net_id_from_ip(session, ip, network_environment=dbnet_env) if prefixlen <= dbnetwork.cidr: raise ArgumentError("The specified --prefixlen must be bigger " "than the current value.") subnets = dbnetwork.network.subnet(new_prefix=prefixlen) # Collect IP addresses that will become network/broadcast addresses # after the split bad_ips = [] for subnet in subnets: bad_ips.append(subnet.ip) bad_ips.append(subnet.broadcast) q = session.query(AddressAssignment.ip) q = q.filter_by(network=dbnetwork) q = q.filter(AddressAssignment.ip.in_(bad_ips)) used_addrs = q.all() if used_addrs: raise ArgumentError("Network split failed, because the following " "subnet IP and/or broadcast addresses are " "assigned to hosts: %s" % ", ".join([str(addr.ip) for addr in used_addrs])) q = session.query(ARecord.ip) q = q.filter_by(network=dbnetwork) q = q.filter(ARecord.ip.in_(bad_ips)) used_addrs = q.all() if used_addrs: raise ArgumentError("Network split failed, because the following " "subnet IP and/or broadcast addresses are " "registered in the DNS: %s" % ", ".join([str(addr.ip) for addr in used_addrs])) # Reason of the initial value: we keep the name of the first segment # (e.g. "foo"), and the next segment will be called "foo_2" name_idx = 2 dbnets = [] for subnet in dbnetwork.network.subnet(new_prefix=prefixlen): # Skip the original if subnet.ip == dbnetwork.ip: continue # Generate a new name. Make it unique, even if the DB does not # enforce that currently while True: # TODO: check if the new name is too long name = "%s_%d" % (dbnetwork.name, name_idx) name_idx += 1 q = session.query(Network) q = q.filter_by(network_environment=dbnet_env) q = q.filter_by(name=name) if q.count() == 0: break # Should not happen... if name_idx > 1000: # pragma: no cover raise AquilonError("Could not generate a unique network " "name in a reasonable time, bailing out") # Inherit location & side from the supernet newnet = Network(name=name, network=subnet, network_environment=dbnet_env, location=dbnetwork.location, side=dbnetwork.side, comments="Created by splitting {0:a}".format(dbnetwork)) session.add(newnet) dbnets.append(newnet) dbnetwork.cidr = prefixlen session.flush() for newnet in dbnets: fix_foreign_links(session, dbnetwork, newnet) session.flush()
if orig_net == supernet: # Split: # AQ: ******** (one big network) # QIP: --**++++ (smaller networks, some may be missing) if keep_aqnet: # The first subnet was handled above by setting # aqnet.cidr qipinfo = heap_pop(qipnets) else: # The first subnet was deleted pass while qipinfo and qipinfo.address.ip in orig_net: newnet = self.add_network(qipinfo) # Redirect addresses from the split network to the new # subnet fix_foreign_links(self.session, aqnet, newnet) qipinfo = heap_pop(qipnets) if keep_aqnet: self.check_split_network(aqnet) else: self.del_network(aqnet) aqnet = heap_pop(aqnets) else: # Merge: # AQ: --++**** (smaller networks, some may be missing) # QIP: ******** (one big network) if keep_aqnet: # The first subnet was handled above by setting # aqnet.cidr newnet = aqnet aqnet = heap_pop(aqnets)
def render(self, session, dbuser, ip, netmask, prefixlen, network_environment, **arguments): if netmask: # There must me a faster way, but this is the easy one net = IPv4Network("127.0.0.0/%s" % netmask) prefixlen = net.prefixlen if prefixlen < 8 or prefixlen > 32: raise ArgumentError("The prefix length must be between 8 and 32.") dbnet_env = NetworkEnvironment.get_unique_or_default( session, network_environment) self.az.check_network_environment(dbuser, dbnet_env) dbnetwork = get_net_id_from_ip(session, ip, network_environment=dbnet_env) if prefixlen <= dbnetwork.cidr: raise ArgumentError("The specified --prefixlen must be bigger " "than the current value.") subnets = dbnetwork.network.subnet(new_prefix=prefixlen) # Collect IP addresses that will become network/broadcast addresses # after the split bad_ips = [] for subnet in subnets: bad_ips.append(subnet.ip) bad_ips.append(subnet.broadcast) q = session.query(AddressAssignment.ip) q = q.filter_by(network=dbnetwork) q = q.filter(AddressAssignment.ip.in_(bad_ips)) used_addrs = q.all() if used_addrs: raise ArgumentError( "Network split failed, because the following " "subnet IP and/or broadcast addresses are " "assigned to hosts: %s" % ", ".join([str(addr.ip) for addr in used_addrs])) q = session.query(ARecord.ip) q = q.filter_by(network=dbnetwork) q = q.filter(ARecord.ip.in_(bad_ips)) used_addrs = q.all() if used_addrs: raise ArgumentError( "Network split failed, because the following " "subnet IP and/or broadcast addresses are " "registered in the DNS: %s" % ", ".join([str(addr.ip) for addr in used_addrs])) # Reason of the initial value: we keep the name of the first segment # (e.g. "foo"), and the next segment will be called "foo_2" name_idx = 2 dbnets = [] for subnet in dbnetwork.network.subnet(new_prefix=prefixlen): # Skip the original if subnet.ip == dbnetwork.ip: continue # Generate a new name. Make it unique, even if the DB does not # enforce that currently while True: # TODO: check if the new name is too long name = "%s_%d" % (dbnetwork.name, name_idx) name_idx += 1 q = session.query(Network) q = q.filter_by(network_environment=dbnet_env) q = q.filter_by(name=name) if q.count() == 0: break # Should not happen... if name_idx > 1000: # pragma: no cover raise AquilonError( "Could not generate a unique network " "name in a reasonable time, bailing out") # Inherit location & side from the supernet newnet = Network( name=name, network=subnet, network_environment=dbnet_env, location=dbnetwork.location, side=dbnetwork.side, comments="Created by splitting {0:a}".format(dbnetwork)) session.add(newnet) dbnets.append(newnet) dbnetwork.cidr = prefixlen session.flush() for newnet in dbnets: fix_foreign_links(session, dbnetwork, newnet) session.flush()