def get_or_create(cls, session, dns_environment=None, preclude=False, ignore_name_check=False, query_options=None, **kwargs): fqdn = cls.get_unique(session, dns_environment=dns_environment, query_options=query_options, **kwargs) if fqdn: if preclude: _raise_custom(preclude, ArgumentError, "{0} already exists.".format(fqdn)) return fqdn if not isinstance(dns_environment, DnsEnvironment): dns_environment = DnsEnvironment.get_unique_or_default( session, dns_environment) fqdn = cls(session=session, dns_environment=dns_environment, ignore_name_check=ignore_name_check, **kwargs) session.add(fqdn) return fqdn
def __init__(self, session=None, name=None, dns_domain=None, fqdn=None, dns_environment=None, ignore_name_check=False, **kwargs): if fqdn: if name or dns_domain: # pragma: no cover raise TypeError("fqdn and name/dns_domain should not be mixed") self._check_session(session) (name, dns_domain) = parse_fqdn(session, fqdn) self.check_name(name, dns_domain, ignore_name_check) if not isinstance(dns_environment, DnsEnvironment): self._check_session(session) dns_environment = DnsEnvironment.get_unique_or_default( session, dns_environment) super(Fqdn, self).__init__(name=name, dns_domain=dns_domain, dns_environment=dns_environment, **kwargs)
def render(self, session, logger, fqdn, dns_environment, target, comments, **kwargs): dbdns_env = DnsEnvironment.get_unique_or_default( session, dns_environment) dbalias = Alias.get_unique(session, fqdn=fqdn, dns_environment=dbdns_env, compel=True) old_target_fqdn = str(dbalias.target.fqdn) old_comments = dbalias.comments if target: old_target = dbalias.target dbalias.target = create_target_if_needed(session, logger, target, dbdns_env) if dbalias.target != old_target: delete_target_if_needed(session, old_target) if comments is not None: dbalias.comments = comments session.flush() if dbdns_env.is_default and dbalias.fqdn.dns_domain.name == "ms.com": dsdb_runner = DSDBRunner(logger=logger) dsdb_runner.update_alias(fqdn, dbalias.target.fqdn, dbalias.comments, old_target_fqdn, old_comments) dsdb_runner.commit_or_rollback("Could not update alias in DSDB") return
def hostlist_to_hosts(session, hostlist): dbdns_env = DnsEnvironment.get_unique_or_default(session) failed = [] dbhosts = [] dns_domains = {} for host in hostlist: if "." not in host: failed.append("%s: Not an FQDN." % host) continue short, dns_domain = host.split(".", 1) try: if dns_domain not in dns_domains: dbdns_domain = DnsDomain.get_unique(session, dns_domain, compel=True) dns_domains[dns_domain] = dbdns_domain dbdns_rec = DnsRecord.get_unique(session, name=short, dns_domain=dns_domains[dns_domain], dns_environment=dbdns_env, query_options=[joinedload('hardware_entity')], compel=True) if not dbdns_rec.hardware_entity or \ not dbdns_rec.hardware_entity.host: raise NotFoundException("Host %s not found." % host) dbhosts.append(dbdns_rec.hardware_entity.host) except NotFoundException, err: failed.append("%s: %s" % (host, err)) continue except ArgumentError, err: failed.append("%s: %s" % (host, err)) continue
def render(self, session, service, protocol, dns_domain, priority, weight, target, port, dns_environment, comments, **kwargs): dbdns_env = DnsEnvironment.get_unique_or_default(session, dns_environment) dbdns_domain = DnsDomain.get_unique(session, dns_domain, compel=True) if dbdns_domain.restricted: raise ArgumentError("{0} is restricted, SRV records are not allowed." .format(dbdns_domain)) # TODO: we could try looking up the port based on the service, but there # are some caveats: # - the protocol name used in SRV record may not match the name used in # /etc/services # - socket.getservent() may return bogus information (like it does for # e.g. 'kerberos') service = service.strip().lower() target = target.strip().lower() dbtarget = Fqdn.get_unique(session, target, compel=True) dbsrv_rec = SrvRecord(service=service, protocol=protocol, priority=priority, weight=weight, target=dbtarget, port=port, dns_domain=dbdns_domain, dns_environment=dbdns_env, comments=comments) session.add(dbsrv_rec) session.flush() return
def render(self, session, fqdn, ip, dns_environment, **arguments): dbdns_env = DnsEnvironment.get_unique_or_default(session, dns_environment) if fqdn: dbdns_rec = DynamicStub.get_unique(session, fqdn=fqdn, dns_environment=dbdns_env, compel=True) dbnetwork = dbdns_rec.network ip = dbdns_rec.ip if ip: dbnetwork = get_net_id_from_ip(session, ip) all_stubs = {} q = session.query(DynamicStub.ip) q = q.filter_by(network=dbnetwork) for stub in q: all_stubs[int(stub.ip)] = True start = int(ip) while start > int(dbnetwork.ip) and start - 1 in all_stubs: start = start - 1 end = int(ip) while end < int(dbnetwork.broadcast) and end + 1 in all_stubs: end = end + 1 return DynamicRange(dbnetwork, IPv4Address(start), IPv4Address(end))
def render(self, session, logger, fqdn, dns_environment, target, comments, **kwargs): dbdns_env = DnsEnvironment.get_unique_or_default(session, dns_environment) dbalias = Alias.get_unique(session, fqdn=fqdn, dns_environment=dbdns_env, compel=True) old_target_fqdn = str(dbalias.target.fqdn) old_comments = dbalias.comments if target: old_target = dbalias.target dbalias.target = create_target_if_needed(session, logger, target, dbdns_env) if dbalias.target != old_target: delete_target_if_needed(session, old_target) if comments is not None: dbalias.comments = comments session.flush() if dbdns_env.is_default and dbalias.fqdn.dns_domain.name == "ms.com": dsdb_runner = DSDBRunner(logger=logger) dsdb_runner.update_alias(fqdn, dbalias.target.fqdn, dbalias.comments, old_target_fqdn, old_comments) dsdb_runner.commit_or_rollback("Could not update alias in DSDB") return
def render(self, session, service, protocol, dns_domain, priority, weight, target, port, dns_environment, comments, **kwargs): dbdns_env = DnsEnvironment.get_unique_or_default( session, dns_environment) dbdns_domain = DnsDomain.get_unique(session, dns_domain, compel=True) if dbdns_domain.restricted: raise ArgumentError( "{0} is restricted, SRV records are not allowed.".format( dbdns_domain)) # TODO: we could try looking up the port based on the service, but there # are some caveats: # - the protocol name used in SRV record may not match the name used in # /etc/services # - socket.getservent() may return bogus information (like it does for # e.g. 'kerberos') service = service.strip().lower() target = target.strip().lower() dbtarget = Fqdn.get_unique(session, target, compel=True) dbsrv_rec = SrvRecord(service=service, protocol=protocol, priority=priority, weight=weight, target=dbtarget, port=port, dns_domain=dbdns_domain, dns_environment=dbdns_env, comments=comments) session.add(dbsrv_rec) session.flush() return
def render(self, session, fqdn, ip, dns_environment, **arguments): dbdns_env = DnsEnvironment.get_unique_or_default( session, dns_environment) if fqdn: dbdns_rec = DynamicStub.get_unique(session, fqdn=fqdn, dns_environment=dbdns_env, compel=True) dbnetwork = dbdns_rec.network ip = dbdns_rec.ip if ip: dbnetwork = get_net_id_from_ip(session, ip) all_stubs = {} q = session.query(DynamicStub.ip) q = q.filter_by(network=dbnetwork) for stub in q: all_stubs[int(stub.ip)] = True start = int(ip) while start > int(dbnetwork.ip) and start - 1 in all_stubs: start = start - 1 end = int(ip) while end < int(dbnetwork.broadcast) and end + 1 in all_stubs: end = end + 1 return DynamicRange(dbnetwork, IPv4Address(start), IPv4Address(end))
def render(self, session, fqdn, dns_environment, **kwargs): self.deprecated_command("The show_fqdn command is deprecated. Please " "use search_dns instead.", **kwargs) dbdns_env = DnsEnvironment.get_unique_or_default(session, dns_environment) dbfqdn = Fqdn.get_unique(session, fqdn=fqdn, dns_environment=dbdns_env, compel=True) q = session.query(DnsRecord) q = q.filter_by(fqdn=dbfqdn) return q.all()
def lookup_target(session, plenaries, hostname, ip, cluster, resourcegroup, service_address, alias): """ Check the parameters of the server providing a given service Look for potential conflicts, and return a dict that is suitable to be passed to either the constructor of ServiceInstanceServer, or to the find_server() function. """ params = {} if cluster and hostname: raise ArgumentError("Only one of --cluster and --hostname may be " "specified.") if alias: dbdns_env = DnsEnvironment.get_unique_or_default(session) dbdns_rec = Alias.get_unique(session, fqdn=alias, dns_environment=dbdns_env, compel=True) params["alias"] = dbdns_rec if hostname: params["host"] = hostname_to_host(session, hostname) plenaries.append(Plenary.get_plenary(params["host"])) if cluster: params["cluster"] = Cluster.get_unique(session, cluster, compel=True) plenaries.append(Plenary.get_plenary(params["cluster"])) if service_address: # TODO: calling get_resource_holder() means doing redundant DB lookups # TODO: it would be nice to also accept an FQDN for the service address, # to be consistent with the usage of the --service_address option in # add_service_address/del_service_address holder = get_resource_holder(session, hostname=hostname, cluster=cluster, resgroup=resourcegroup, compel=True) dbsrv_addr = ServiceAddress.get_unique(session, name=service_address, holder=holder, compel=True) params["service_address"] = dbsrv_addr elif ip: for addr in params["host"].hardware_entity.all_addresses(): if ip != addr.ip: continue if addr.service_address: params["service_address"] = addr.service_address else: params["address_assignment"] = addr break return params
def render(self, session, dns_environment, **arguments): self.deprecated_command("The show_fqdn command is deprecated. Please " "use search_dns instead.", **arguments) dbdns_env = DnsEnvironment.get_unique_or_default(session, dns_environment) q = session.query(Fqdn) q = q.filter_by(dns_environment=dbdns_env) q = q.join(DnsDomain) q = q.options(contains_eager("dns_domain")) q = q.order_by(DnsDomain.name, Fqdn.name) return StringList(q.all())
def render(self, session, dns_environment, **arguments): self.deprecated_command( "The show_fqdn command is deprecated. Please " "use search_dns instead.", **arguments) dbdns_env = DnsEnvironment.get_unique_or_default( session, dns_environment) q = session.query(Fqdn) q = q.filter_by(dns_environment=dbdns_env) q = q.join(DnsDomain) q = q.options(contains_eager("dns_domain")) q = q.order_by(DnsDomain.name, Fqdn.name) return StringList(q.all())
def render(self, session, fqdn, dns_environment, **kwargs): self.deprecated_command( "The show_fqdn command is deprecated. Please " "use search_dns instead.", **kwargs) dbdns_env = DnsEnvironment.get_unique_or_default( session, dns_environment) dbfqdn = Fqdn.get_unique(session, fqdn=fqdn, dns_environment=dbdns_env, compel=True) q = session.query(DnsRecord) q = q.filter_by(fqdn=dbfqdn) return q.all()
def get_unique(cls, session, fqdn=None, dns_environment=None, name=None, dns_domain=None, **kwargs): if fqdn: if name or dns_domain: # pragma: no cover raise TypeError("fqdn and name/dns_domain should not be mixed") (name, dns_domain) = parse_fqdn(session, fqdn) if not isinstance(dns_environment, DnsEnvironment): dns_environment = DnsEnvironment.get_unique_or_default(session, dns_environment) return super(Fqdn, cls).get_unique(session, name=name, dns_domain=dns_domain, dns_environment=dns_environment, **kwargs)
def get_unique(cls, session, fqdn=None, name=None, dns_domain=None, dns_environment=None, compel=False, preclude=False, **kwargs): # Proxy FQDN lookup to the Fqdn class if not fqdn or not isinstance(fqdn, Fqdn): if not isinstance(dns_environment, DnsEnvironment): dns_environment = DnsEnvironment.get_unique_or_default( session, dns_environment) if fqdn: if name or dns_domain: # pragma: no cover raise TypeError("fqdn and name/dns_domain cannot be mixed") (name, dns_domain) = parse_fqdn(session, fqdn) try: # Do not pass preclude=True to Fqdn fqdn = Fqdn.get_unique(session, name=name, dns_domain=dns_domain, dns_environment=dns_environment, compel=compel) except NotFoundException: # Replace the "Fqdn ... not found" message with a more user # friendly one msg = "%s %s.%s, %s not found." % ( cls._get_class_label(), name, dns_domain, format(dns_environment, "l")) raise NotFoundException(msg) if not fqdn: return None # We already have the FQDN, no need to load it again if "query_options" not in kwargs: kwargs["query_options"] = [lazyload("fqdn")] result = super(DnsRecord, cls).get_unique(session, fqdn=fqdn, compel=compel, preclude=preclude, **kwargs) if result: # Make sure not to load the relation again if we already know its # value set_committed_value(result, 'fqdn', fqdn) return result
def __init__(self, session=None, name=None, dns_domain=None, fqdn=None, dns_environment=None, ignore_name_check=False, **kwargs): if fqdn: if name or dns_domain: # pragma: no cover raise TypeError("fqdn and name/dns_domain should not be mixed") self._check_session(session) (name, dns_domain) = parse_fqdn(session, fqdn) self.check_name(name, dns_domain, ignore_name_check) if not isinstance(dns_environment, DnsEnvironment): self._check_session(session) dns_environment = DnsEnvironment.get_unique_or_default(session, dns_environment) super(Fqdn, self).__init__(name=name, dns_domain=dns_domain, dns_environment=dns_environment, **kwargs)
def get_or_create(cls, session, dns_environment=None, preclude=False, ignore_name_check=False, query_options=None, **kwargs): fqdn = cls.get_unique(session, dns_environment=dns_environment, query_options=query_options, **kwargs) if fqdn: if preclude: _raise_custom(preclude, ArgumentError, "{0} already exists.".format(fqdn)) return fqdn if not isinstance(dns_environment, DnsEnvironment): dns_environment = DnsEnvironment.get_unique_or_default(session, dns_environment) fqdn = cls(session=session, dns_environment=dns_environment, ignore_name_check=ignore_name_check, **kwargs) session.add(fqdn) return fqdn
def render(self, session, logger, fqdn, dns_environment, **kwargs): dbdns_env = DnsEnvironment.get_unique_or_default(session, dns_environment) dbdns_rec = Alias.get_unique(session, fqdn=fqdn, dns_environment=dbdns_env, compel=True) domain = dbdns_rec.fqdn.dns_domain.name old_target_fqdn = str(dbdns_rec.target) old_comments = dbdns_rec.comments target_is_restricted = dbdns_rec.target.dns_domain.restricted delete_dns_record(dbdns_rec) session.flush() if dbdns_env.is_default and domain == "ms.com" and not target_is_restricted: dsdb_runner = DSDBRunner(logger=logger) dsdb_runner.del_alias(fqdn, old_target_fqdn, old_comments) dsdb_runner.commit_or_rollback("Could not delete alias from DSDB") return
def render(self, session, logger, fqdn, dns_environment, target, comments, **kwargs): dbdns_env = DnsEnvironment.get_unique_or_default(session, dns_environment) dbalias = Alias.get_unique(session, fqdn=fqdn, dns_environment=dbdns_env, compel=True) old_target_fqdn = str(dbalias.target.fqdn) old_comments = dbalias.comments if target: old_target = dbalias.target dbalias.target = create_target_if_needed(session, logger, target, dbdns_env) # TODO: at some day we should verify that the new target is also # bound as a server, and modify the ServiceInstanceServer bindings # accordingly for srv in dbalias.services_provided: if srv.host or srv.cluster: provider = srv.host or srv.cluster logger.client_info("Warning: {0} provides {1:l}, and is " "bound to {2:l}. Updating the target of " "the alias may leave that server " "binding in an inconsistent state." .format(dbalias, srv.service_instance, provider)) if dbalias.target != old_target: delete_target_if_needed(session, old_target) if comments is not None: dbalias.comments = comments session.flush() if dbdns_env.is_default and dbalias.fqdn.dns_domain.name == "ms.com": dsdb_runner = DSDBRunner(logger=logger) dsdb_runner.update_alias(fqdn, dbalias.target.fqdn, dbalias.comments, old_target_fqdn, old_comments) dsdb_runner.commit_or_rollback("Could not update alias in DSDB") return
def render(self, session, fqdn, record_type, dns_environment, network_environment=None, **arguments): if network_environment: if not isinstance(network_environment, NetworkEnvironment): network_environment = NetworkEnvironment.get_unique_or_default( session, network_environment) if not dns_environment: dns_environment = network_environment.dns_environment dbdns_env = DnsEnvironment.get_unique_or_default( session, dns_environment) # No compel here. query(DnsRecord).filter_by(fqdn=None) will fail if the # FQDN is invalid, and that will give a better error message. dbfqdn = Fqdn.get_unique(session, fqdn=fqdn, dns_environment=dbdns_env) if record_type: if record_type in DNS_RRTYPE_MAP: cls = DNS_RRTYPE_MAP[record_type] else: cls = DnsRecord.polymorphic_subclass( record_type, "Unknown DNS record type") else: cls = DnsRecord # We want to query(ARecord) instead of # query(DnsRecord).filter_by(record_type='a_record'), because the former # works for DynamicStub as well q = session.query(cls) if cls == DnsRecord: q = q.with_polymorphic('*') q = q.filter_by(fqdn=dbfqdn) result = q.all() if not result: raise NotFoundException("%s %s not found." % (cls._get_class_label(), fqdn)) return result
def get_unique(cls, session, fqdn=None, dns_environment=None, name=None, dns_domain=None, **kwargs): if fqdn: if name or dns_domain: # pragma: no cover raise TypeError("fqdn and name/dns_domain should not be mixed") (name, dns_domain) = parse_fqdn(session, fqdn) if not isinstance(dns_environment, DnsEnvironment): dns_environment = DnsEnvironment.get_unique_or_default( session, dns_environment) return super(Fqdn, cls).get_unique(session, name=name, dns_domain=dns_domain, dns_environment=dns_environment, **kwargs)
def render(self, session, logger, fqdn, dns_environment, target, comments, **kwargs): dbdns_env = DnsEnvironment.get_unique_or_default(session, dns_environment) dbfqdn = Fqdn.get_or_create(session, dns_environment=dbdns_env, fqdn=fqdn) if dbfqdn.dns_domain.restricted: raise ArgumentError("{0} is restricted, aliases are not allowed." .format(dbfqdn.dns_domain)) DnsRecord.get_unique(session, fqdn=dbfqdn, preclude=True) dbtarget = create_target_if_needed(session, logger, target, dbdns_env) try: db_record = Alias(fqdn=dbfqdn, target=dbtarget, comments=comments) session.add(db_record) except ValueError, err: raise ArgumentError(err.message)
def render(self, session, service, protocol, dns_domain, dns_environment, **kwargs): dbdns_env = DnsEnvironment.get_unique_or_default(session, dns_environment) dbdns_domain = DnsDomain.get_unique(session, dns_domain, compel=True) name = "_%s._%s" % (service.strip().lower(), protocol.strip().lower()) q = session.query(SrvRecord) q = q.join((Fqdn, SrvRecord.fqdn_id == Fqdn.id)) q = q.options(contains_eager('fqdn')) q = q.filter_by(dns_domain=dbdns_domain) q = q.filter_by(name=name) q = q.filter_by(dns_environment=dbdns_env) result = q.all() if not result: raise NotFoundException("%s for service %s, protocol %s in DNS " "domain %s not found." % (SrvRecord._get_class_label(), service, protocol, dns_domain)) return result
def render(self, session, service, protocol, dns_domain, dns_environment, **kwargs): dbdns_env = DnsEnvironment.get_unique_or_default( session, dns_environment) dbdns_domain = DnsDomain.get_unique(session, dns_domain, compel=True) name = "_%s._%s" % (service.strip().lower(), protocol.strip().lower()) q = session.query(SrvRecord) q = q.join((Fqdn, SrvRecord.fqdn_id == Fqdn.id)) q = q.options(contains_eager('fqdn')) q = q.filter_by(dns_domain=dbdns_domain) q = q.filter_by(name=name) q = q.filter_by(dns_environment=dbdns_env) result = q.all() if not result: raise NotFoundException( "%s for service %s, protocol %s in DNS " "domain %s not found." % (SrvRecord._get_class_label(), service, protocol, dns_domain)) return result
def get_unique(cls, session, fqdn=None, name=None, dns_domain=None, dns_environment=None, compel=False, preclude=False, **kwargs): # Proxy FQDN lookup to the Fqdn class if not fqdn or not isinstance(fqdn, Fqdn): if not isinstance(dns_environment, DnsEnvironment): dns_environment = DnsEnvironment.get_unique_or_default(session, dns_environment) if fqdn: if name or dns_domain: # pragma: no cover raise TypeError("fqdn and name/dns_domain cannot be mixed") (name, dns_domain) = parse_fqdn(session, fqdn) try: # Do not pass preclude=True to Fqdn fqdn = Fqdn.get_unique(session, name=name, dns_domain=dns_domain, dns_environment=dns_environment, compel=compel) except NotFoundException: # Replace the "Fqdn ... not found" message with a more user # friendly one msg = "%s %s.%s, %s not found." % (cls._get_class_label(), name, dns_domain, format(dns_environment, "l")) raise NotFoundException(msg) if not fqdn: return None # We already have the FQDN, no need to load it again if "query_options" not in kwargs: kwargs["query_options"] = [lazyload("fqdn")] result = super(DnsRecord, cls).get_unique(session, fqdn=fqdn, compel=compel, preclude=preclude, **kwargs) if result: # Make sure not to load the relation again if we already know its # value set_committed_value(result, 'fqdn', fqdn) return result
def render(self, session, logger, fqdn, dns_environment, target, comments, **kwargs): dbdns_env = DnsEnvironment.get_unique_or_default( session, dns_environment) dbfqdn = Fqdn.get_or_create(session, dns_environment=dbdns_env, fqdn=fqdn) if dbfqdn.dns_domain.restricted: raise ArgumentError( "{0} is restricted, aliases are not allowed.".format( dbfqdn.dns_domain)) DnsRecord.get_unique(session, fqdn=dbfqdn, preclude=True) dbtarget = create_target_if_needed(session, logger, target, dbdns_env) try: db_record = Alias(fqdn=dbfqdn, target=dbtarget, comments=comments) session.add(db_record) except ValueError, err: raise ArgumentError(err.message)
def search_system_query(session, dns_record_type=DnsRecord, **kwargs): q = session.query(dns_record_type) # Outer-join in all the subclasses so that each access of # system doesn't (necessarily) issue another query. if dns_record_type is DnsRecord: q = q.with_polymorphic('*') dbdns_env = DnsEnvironment.get_unique_or_default(session, kwargs.get("dns_environment", None)) q = q.join((Fqdn, DnsRecord.fqdn_id == Fqdn.id)) q = q.filter_by(dns_environment=dbdns_env) q = q.options(contains_eager('fqdn')) if kwargs.get('fqdn', None): (short, dbdns_domain) = parse_fqdn(session, kwargs['fqdn']) q = q.filter_by(name=short, dns_domain=dbdns_domain) if kwargs.get('dns_domain', None): dbdns_domain = DnsDomain.get_unique(session, kwargs['dns_domain'], compel=True) q = q.filter_by(dns_domain=dbdns_domain) if kwargs.get('shortname', None): q = q.filter_by(name=kwargs['shortname']) q = q.reset_joinpoint() if kwargs.get('ip', None): q = q.filter(ARecord.ip == kwargs['ip']) if kwargs.get('networkip', None): net_env = kwargs.get('network_environment', None) dbnet_env = NetworkEnvironment.get_unique_or_default(session, net_env) dbnetwork = get_network_byip(session, kwargs['networkip'], dbnet_env) q = q.filter(ARecord.network == dbnetwork) if kwargs.get('mac', None): raise UnimplementedError("search_system --mac is no longer supported, " "try search_hardware.") if kwargs.get('type', None): # Deprecated... remove if it becomes a problem. type_arg = kwargs['type'].strip().lower() q = q.filter_by(dns_record_type=type_arg) return q
def render(self, session, logger, fqdn, dns_environment, **kwargs): dbdns_env = DnsEnvironment.get_unique_or_default( session, dns_environment) dbdns_rec = Alias.get_unique(session, fqdn=fqdn, dns_environment=dbdns_env, compel=True) domain = dbdns_rec.fqdn.dns_domain.name old_target_fqdn = str(dbdns_rec.target) old_comments = dbdns_rec.comments target_is_restricted = dbdns_rec.target.dns_domain.restricted delete_dns_record(dbdns_rec) session.flush() if dbdns_env.is_default and domain == "ms.com" and not target_is_restricted: dsdb_runner = DSDBRunner(logger=logger) dsdb_runner.del_alias(fqdn, old_target_fqdn, old_comments) dsdb_runner.commit_or_rollback("Could not delete alias from DSDB") return
def render(self, session, fqdn, record_type, dns_environment, network_environment=None, **arguments): if network_environment: if not isinstance(network_environment, NetworkEnvironment): network_environment = NetworkEnvironment.get_unique_or_default(session, network_environment) if not dns_environment: dns_environment = network_environment.dns_environment dbdns_env = DnsEnvironment.get_unique_or_default(session, dns_environment) # No compel here. query(DnsRecord).filter_by(fqdn=None) will fail if the # FQDN is invalid, and that will give a better error message. dbfqdn = Fqdn.get_unique(session, fqdn=fqdn, dns_environment=dbdns_env) if record_type: if record_type in DNS_RRTYPE_MAP: cls = DNS_RRTYPE_MAP[record_type] else: cls = DnsRecord.polymorphic_subclass(record_type, "Unknown DNS record type") else: cls = DnsRecord # We want to query(ARecord) instead of # query(DnsRecord).filter_by(record_type='a_record'), because the former # works for DynamicStub as well q = session.query(cls) if cls == DnsRecord: q = q.with_polymorphic('*') q = q.filter_by(fqdn=dbfqdn) result = q.all() if not result: raise NotFoundException("%s %s not found." % (cls._get_class_label(), fqdn)) return result
def render(self, session, dns_domain, dns_environment, **arguments): dbdns_env = DnsEnvironment.get_unique_or_default(session, dns_environment) if dns_domain: dbdns_domain = DnsDomain.get_unique(session, dns_domain, compel=True) else: dbdns_domain = None q = session.query(DnsRecord) q = q.with_polymorphic('*') q = q.join((Fqdn, DnsRecord.fqdn_id == Fqdn.id)) q = q.options(contains_eager('fqdn')) q = q.filter_by(dns_environment=dbdns_env) if dbdns_domain: q = q.filter_by(dns_domain=dbdns_domain) dns_domains = [dbdns_domain] else: # Preload DNS domains, and keep a reference to prevent them being # evicted from the session's cache dns_domains = session.query(DnsDomain).all() return DnsDump(q.all(), dns_domains)
def __init__(self, session, logger, dbbuilding, dryrun, incremental): self.session = session self.logger = logger self.building = dbbuilding self.dryrun = dryrun self.incremental = incremental # Synchronize the internal environment only self.net_env = NetworkEnvironment.get_unique_or_default(session) self.errors = [] self.dns_env = DnsEnvironment.get_unique_or_default(session) # Cache building and bunker information. Load all buildings even if # we're interested in only one, so we can verify subnetdata.txt self.buildings = {} for item in session.query(Building): self.buildings[item.name] = item self.bunkers = {} for item in session.query(Bunker): self.bunkers[item.name] = item # Used to limit the number of warnings self.unknown_syslocs = set() # Load existing networks. We have to load all, otherwise we won't be # able to fix networks with wrong location self.aqnetworks = {} q = session.query(Network) q = q.filter_by(network_environment=self.net_env) q = q.options(subqueryload("routers")) for item in q: self.aqnetworks[item.ip] = item # Save how many networks we had initially self.networks_before = len(self.aqnetworks.keys())
def render(self, session, dns_domain, dns_environment, **arguments): dbdns_env = DnsEnvironment.get_unique_or_default( session, dns_environment) if dns_domain: dbdns_domain = DnsDomain.get_unique(session, dns_domain, compel=True) else: dbdns_domain = None q = session.query(DnsRecord) q = q.with_polymorphic('*') q = q.join((Fqdn, DnsRecord.fqdn_id == Fqdn.id)) q = q.options(contains_eager('fqdn')) q = q.filter_by(dns_environment=dbdns_env) if dbdns_domain: q = q.filter_by(dns_domain=dbdns_domain) dns_domains = [dbdns_domain] else: # Preload DNS domains, and keep a reference to prevent them being # evicted from the session's cache dns_domains = session.query(DnsDomain).all() return DnsDump(q.all(), dns_domains)
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')
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, logger, startip, endip, dns_domain, prefix, **arguments): if not prefix: prefix = 'dynamic' dbnet_env = NetworkEnvironment.get_unique_or_default(session) dbdns_env = DnsEnvironment.get_unique_or_default(session) startnet = get_net_id_from_ip(session, startip, dbnet_env) endnet = get_net_id_from_ip(session, endip, dbnet_env) if startnet != endnet: raise ArgumentError("IP addresses %s (%s) and %s (%s) must be on " "the same subnet." % (startip, startnet.ip, endip, endnet.ip)) dbdns_domain = DnsDomain.get_unique(session, dns_domain, compel=True) dbdns_domain.lock_row() startnet.lock_row() q = session.query(AddressAssignment.ip) q = q.filter_by(network=startnet) q = q.filter(AddressAssignment.ip >= startip) q = q.filter(AddressAssignment.ip <= endip) q = q.order_by(AddressAssignment.ip) conflicts = q.all() if conflicts: raise ArgumentError( "Cannot allocate the address range because the " "following IP addresses are already in use:\n" + ", ".join([str(c.ip) for c in conflicts])) # No filtering on DNS environment. If an address is dynamic in one # environment, it should not be considered static in a different # environment. q = session.query(ARecord) q = q.filter_by(network=startnet) q = q.filter(ARecord.ip >= startip) q = q.filter(ARecord.ip <= endip) q = q.order_by(ARecord.ip) conflicts = q.all() if conflicts: raise ArgumentError( "Cannot allocate the address range because the " "following DNS records already exist:\n" + "\n".join([format(c, "a") for c in conflicts])) dsdb_runner = DSDBRunner(logger=logger) with session.no_autoflush: for ipint in range(int(startip), int(endip) + 1): ip = IPv4Address(ipint) check_ip_restrictions(startnet, ip) name = "%s-%s" % (prefix, str(ip).replace('.', '-')) dbfqdn = Fqdn.get_or_create(session, name=name, dns_domain=dbdns_domain, dns_environment=dbdns_env, preclude=True) dbdynamic_stub = DynamicStub(fqdn=dbfqdn, ip=ip, network=startnet) session.add(dbdynamic_stub) dsdb_runner.add_host_details(dbfqdn, ip) session.flush() # This may take some time if the range is big, so be verbose dsdb_runner.commit_or_rollback("Could not add addresses to DSDB", verbose=True) return
def render(self, session, logger, startip, endip, dns_domain, prefix, **arguments): if not prefix: prefix = 'dynamic' dbnet_env = NetworkEnvironment.get_unique_or_default(session) dbdns_env = DnsEnvironment.get_unique_or_default(session) startnet = get_net_id_from_ip(session, startip, dbnet_env) endnet = get_net_id_from_ip(session, endip, dbnet_env) if startnet != endnet: raise ArgumentError("IP addresses %s (%s) and %s (%s) must be on " "the same subnet." % (startip, startnet.ip, endip, endnet.ip)) dbdns_domain = DnsDomain.get_unique(session, dns_domain, compel=True) dbdns_domain.lock_row() startnet.lock_row() q = session.query(AddressAssignment.ip) q = q.filter_by(network=startnet) q = q.filter(AddressAssignment.ip >= startip) q = q.filter(AddressAssignment.ip <= endip) q = q.order_by(AddressAssignment.ip) conflicts = q.all() if conflicts: raise ArgumentError("Cannot allocate the address range because the " "following IP addresses are already in use:\n" + ", ".join([str(c.ip) for c in conflicts])) # No filtering on DNS environment. If an address is dynamic in one # environment, it should not be considered static in a different # environment. q = session.query(ARecord) q = q.filter_by(network=startnet) q = q.filter(ARecord.ip >= startip) q = q.filter(ARecord.ip <= endip) q = q.order_by(ARecord.ip) conflicts = q.all() if conflicts: raise ArgumentError("Cannot allocate the address range because the " "following DNS records already exist:\n" + "\n".join([format(c, "a") for c in conflicts])) dsdb_runner = DSDBRunner(logger=logger) with session.no_autoflush: for ipint in range(int(startip), int(endip) + 1): ip = IPv4Address(ipint) check_ip_restrictions(startnet, ip) name = "%s-%s" % (prefix, str(ip).replace('.', '-')) dbfqdn = Fqdn.get_or_create(session, name=name, dns_domain=dbdns_domain, dns_environment=dbdns_env, preclude=True) dbdynamic_stub = DynamicStub(fqdn=dbfqdn, ip=ip, network=startnet) session.add(dbdynamic_stub) dsdb_runner.add_host_details(dbfqdn, ip) session.flush() # This may take some time if the range is big, so be verbose dsdb_runner.commit_or_rollback("Could not add addresses to DSDB", verbose=True) return