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, logger, fillnetwork, **arguments): dbnet_env = NetworkEnvironment.get_unique_or_default(session) dbnetwork = Network.get_unique(session, fillnetwork, network_environment=dbnet_env, compel=True) arguments['startip'] = dbnetwork.first_usable_host arguments['endip'] = dbnetwork.broadcast - 1 return CommandAddDynamicRange.render(self, session, logger, **arguments)
def del_dynamic_network(self, session, logger, network): dbnet_env = NetworkEnvironment.get_unique_or_default(session) dbnetwork = Network.get_unique(session, network, network_environment=dbnet_env, compel=True) q = session.query(DynamicStub) q = q.filter_by(network=dbnetwork) q = q.order_by(asc(DynamicStub.ip)) existing = q.all() if not existing: raise ArgumentError("No dynamic stubs found on network.") self.del_dynamic_stubs(session, logger, existing)
def add_network(self, qipinfo): dbnetwork = Network(name=qipinfo.name, network=qipinfo.address, network_type=qipinfo.network_type, side=qipinfo.side, location=qipinfo.location, network_environment=self.net_env) self.session.add(dbnetwork) self.logger.client_info("Adding network {0:a}".format(dbnetwork)) for ip in qipinfo.routers: self.add_router(dbnetwork, ip) self.session.flush() return dbnetwork
def setup(): dmn = DnsDomain(name=DNS_DOMAIN_NAME) create(sess, dmn) assert dmn, 'no dns domain in %s' % func_name() pi = Building.get_unique(sess, name='pi', compel=True) n = IPv4Network(TEST_NET) net = Network(name=TEST_NET_NAME, network=n, location=pi) create(sess, net) assert net, 'no network created by %s' % func_name() ip = IPv4Address(TEST_IP) arec = ARecord(name=AREC_NAME, dns_domain=dmn, ip=ip, network=net) create(sess, arec) assert arec, 'no ARecord created by %s' % func_name()
def render(self, session, logger, fillnetwork, **arguments): dbnet_env = NetworkEnvironment.get_unique_or_default(session) dbnetwork = Network.get_unique(session, fillnetwork, network_environment=dbnet_env, compel=True) arguments["startip"] = dbnetwork.first_usable_host arguments["endip"] = dbnetwork.broadcast - 1 return CommandAddDynamicRange.render(self, session, logger, **arguments)
logger.info("Error parsing vlan number in output " "line #%d: %s error: %s" % (reader.line_num, row, e)) continue try: network = force_ipv4("network", network) except ArgumentError, e: raise InternalError(e) try: bitmask_int = int(bitmask) except ValueError, e: logger.info("Error parsing bitmask in output " "line #%d: %s error: %s" % (reader.line_num, row, e)) continue dbnetwork = Network.get_unique(session, ip=network, network_environment=dbnet_env) if not dbnetwork: logger.info("Unknown network %s in output line #%d: %s" % (network, reader.line_num, row)) continue if dbnetwork.cidr != bitmask_int: logger.client_info("{0}: skipping VLAN {1}, because network " "bitmask value {2} differs from prefixlen " "{3.cidr} of {3:l}.".format(switch, vlan, bitmask, dbnetwork)) continue vlan_info = VlanInfo.get_unique(session, vlan_id=vlan_int, compel=False) if not vlan_info:
dbnetwork = q.first() if dbnetwork: logger.client_info("WARNING: Network name %s is already used for " "address %s." % (network, str(dbnetwork.network))) # Check if the address is free try: dbnetwork = get_net_id_from_ip(session, address.ip, network_environment=dbnet_env) raise ArgumentError( "IP address %s is part of existing network " "named %s with address %s." % (str(address.ip), dbnetwork.name, str(dbnetwork.network))) except NotFoundException: pass # Okay, all looks good, let's create the network net = Network(name=network, network=address, network_environment=dbnet_env, network_type=type, side=side, location=location, comments=comments) session.add(net) session.flush() return
def render(self, session, fqdn, dns_environment, dns_domain, shortname, record_type, ip, network, network_environment, target, target_domain, primary_name, used, reverse_override, reverse_ptr, fullinfo, style, **kwargs): if record_type: record_type = record_type.strip().lower() if record_type in DNS_RRTYPE_MAP: cls = DNS_RRTYPE_MAP[record_type] else: cls = DnsRecord.polymorphic_subclass( record_type, "Unknown DNS record type") q = session.query(cls) else: q = session.query(DnsRecord) q = q.with_polymorphic('*') dbnet_env = NetworkEnvironment.get_unique_or_default( session, network_environment) if network_environment: # The network environment determines the DNS environment dbdns_env = dbnet_env.dns_environment else: dbdns_env = DnsEnvironment.get_unique_or_default( session, dns_environment) if fqdn: dbfqdn = Fqdn.get_unique(session, fqdn=fqdn, dns_environment=dbdns_env, compel=True) q = q.filter_by(fqdn=dbfqdn) q = q.join((Fqdn, DnsRecord.fqdn_id == Fqdn.id)) q = q.filter_by(dns_environment=dbdns_env) q = q.options(contains_eager('fqdn')) if dns_domain: dbdns_domain = DnsDomain.get_unique(session, dns_domain, compel=True) q = q.filter_by(dns_domain=dbdns_domain) if shortname: q = q.filter_by(name=shortname) q = q.join(DnsDomain) q = q.options(contains_eager('fqdn.dns_domain')) q = q.order_by(Fqdn.name, DnsDomain.name) q = q.reset_joinpoint() if ip: q = q.join(Network) q = q.filter_by(network_environment=dbnet_env) q = q.reset_joinpoint() q = q.filter(ARecord.ip == ip) if network: dbnetwork = Network.get_unique(session, network, network_environment=dbnet_env, compel=True) q = q.filter(ARecord.network == dbnetwork) if target: dbtarget = Fqdn.get_unique(session, fqdn=target, dns_environment=dbdns_env, compel=True) q = q.filter( or_(Alias.target == dbtarget, SrvRecord.target == dbtarget)) if target_domain: dbdns_domain = DnsDomain.get_unique(session, target_domain, compel=True) TargetFqdn = aliased(Fqdn) q = q.join((TargetFqdn, or_(Alias.target_id == TargetFqdn.id, SrvRecord.target_id == TargetFqdn.id))) q = q.filter(TargetFqdn.dns_domain == dbdns_domain) if primary_name is not None: if primary_name: q = q.filter(DnsRecord.hardware_entity.has()) else: q = q.filter(~DnsRecord.hardware_entity.has()) if used is not None: if used: q = q.join( AddressAssignment, and_(ARecord.network_id == AddressAssignment.network_id, ARecord.ip == AddressAssignment.ip)) else: q = q.outerjoin( AddressAssignment, and_(ARecord.network_id == AddressAssignment.network_id, ARecord.ip == AddressAssignment.ip)) q = q.filter(AddressAssignment.id == None) q = q.reset_joinpoint() if reverse_override is not None: if reverse_override: q = q.filter(ARecord.reverse_ptr.has()) else: q = q.filter(~ARecord.reverse_ptr.has()) if reverse_ptr: dbtarget = Fqdn.get_unique(session, fqdn=reverse_ptr, dns_environment=dbdns_env, compel=True) q = q.filter(ARecord.reverse_ptr == dbtarget) if fullinfo: q = q.options(undefer('comments')) q = q.options(subqueryload('hardware_entity')) q = q.options(undefer('alias_cnt')) return q.all() elif style == "raw": return StringAttributeList(q.all(), 'fqdn') else: # This is for the CSV formatter return q.all()
def render(self, session, fqdn, dns_environment, dns_domain, shortname, record_type, ip, network, network_environment, target, target_domain, primary_name, used, reverse_override, reverse_ptr, fullinfo, style, **kwargs): if record_type: record_type = record_type.strip().lower() if record_type in DNS_RRTYPE_MAP: cls = DNS_RRTYPE_MAP[record_type] else: cls = DnsRecord.polymorphic_subclass(record_type, "Unknown DNS record type") q = session.query(cls) else: q = session.query(DnsRecord) q = q.with_polymorphic('*') dbnet_env = NetworkEnvironment.get_unique_or_default(session, network_environment) if network_environment: # The network environment determines the DNS environment dbdns_env = dbnet_env.dns_environment else: dbdns_env = DnsEnvironment.get_unique_or_default(session, dns_environment) if fqdn: dbfqdn = Fqdn.get_unique(session, fqdn=fqdn, dns_environment=dbdns_env, compel=True) q = q.filter_by(fqdn=dbfqdn) q = q.join((Fqdn, DnsRecord.fqdn_id == Fqdn.id)) q = q.filter_by(dns_environment=dbdns_env) q = q.options(contains_eager('fqdn')) if dns_domain: dbdns_domain = DnsDomain.get_unique(session, dns_domain, compel=True) q = q.filter_by(dns_domain=dbdns_domain) if shortname: q = q.filter_by(name=shortname) q = q.join(DnsDomain) q = q.options(contains_eager('fqdn.dns_domain')) q = q.order_by(Fqdn.name, DnsDomain.name) q = q.reset_joinpoint() if ip: q = q.join(Network) q = q.filter_by(network_environment=dbnet_env) q = q.reset_joinpoint() q = q.filter(ARecord.ip == ip) if network: dbnetwork = Network.get_unique(session, network, network_environment=dbnet_env, compel=True) q = q.filter(ARecord.network == dbnetwork) if target: dbtarget = Fqdn.get_unique(session, fqdn=target, dns_environment=dbdns_env, compel=True) q = q.filter(or_(Alias.target == dbtarget, SrvRecord.target == dbtarget)) if target_domain: dbdns_domain = DnsDomain.get_unique(session, target_domain, compel=True) TargetFqdn = aliased(Fqdn) q = q.join((TargetFqdn, or_(Alias.target_id == TargetFqdn.id, SrvRecord.target_id == TargetFqdn.id))) q = q.filter(TargetFqdn.dns_domain == dbdns_domain) if primary_name is not None: if primary_name: q = q.filter(DnsRecord.hardware_entity.has()) else: q = q.filter(~DnsRecord.hardware_entity.has()) if used is not None: if used: q = q.join(AddressAssignment, and_(ARecord.network_id == AddressAssignment.network_id, ARecord.ip == AddressAssignment.ip)) else: q = q.outerjoin(AddressAssignment, and_(ARecord.network_id == AddressAssignment.network_id, ARecord.ip == AddressAssignment.ip)) q = q.filter(AddressAssignment.id == None) q = q.reset_joinpoint() if reverse_override is not None: if reverse_override: q = q.filter(ARecord.reverse_ptr.has()) else: q = q.filter(~ARecord.reverse_ptr.has()) if reverse_ptr: dbtarget = Fqdn.get_unique(session, fqdn=reverse_ptr, dns_environment=dbdns_env, compel=True) q = q.filter(ARecord.reverse_ptr == dbtarget) if fullinfo or style != "raw": q = q.options(undefer('comments'), subqueryload('hardware_entity'), lazyload('hardware_entity.primary_name'), undefer('alias_cnt')) return q.all() else: return StringAttributeList(q.all(), 'fqdn')
"line #%d: %s error: %s" % (reader.line_num, row, e)) continue try: network = force_ipv4("network", network) except ArgumentError, e: raise InternalError(e) try: bitmask_int = int(bitmask) except ValueError, e: logger.info("Error parsing bitmask in output " "line #%d: %s error: %s" % (reader.line_num, row, e)) continue dbnetwork = Network.get_unique(session, ip=network, network_environment=dbnet_env) if not dbnetwork: logger.info("Unknown network %s in output line #%d: %s" % (network, reader.line_num, row)) continue if dbnetwork.cidr != bitmask_int: logger.client_info( "{0}: skipping VLAN {1}, because network " "bitmask value {2} differs from prefixlen " "{3.cidr} of {3:l}.".format(switch, vlan, bitmask, dbnetwork)) continue vlan_info = VlanInfo.get_unique(session, vlan_id=vlan_int,
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()