예제 #1
0
    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
예제 #2
0
    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)
예제 #3
0
    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
예제 #4
0
파일: host.py 프로젝트: piojo/aquilon
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
예제 #5
0
    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
예제 #6
0
    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))
예제 #7
0
    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
예제 #8
0
    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
예제 #9
0
    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))
예제 #10
0
 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()
예제 #11
0
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
예제 #12
0
 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())
예제 #13
0
 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())
예제 #14
0
 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()
예제 #15
0
파일: fqdn.py 프로젝트: jrha/aquilon
    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)
예제 #16
0
    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
예제 #17
0
파일: fqdn.py 프로젝트: jrha/aquilon
    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)
예제 #18
0
파일: fqdn.py 프로젝트: jrha/aquilon
    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
예제 #19
0
    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
예제 #20
0
    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
예제 #21
0
    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
예제 #22
0
    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)
예제 #23
0
파일: add_alias.py 프로젝트: jrha/aquilon
    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)
예제 #24
0
    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
예제 #25
0
    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
예제 #26
0
파일: dns_record.py 프로젝트: piojo/aquilon
    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
예제 #27
0
파일: add_alias.py 프로젝트: ned21/aquilon
    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)
예제 #28
0
파일: system.py 프로젝트: jrha/aquilon
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
예제 #29
0
파일: del_alias.py 프로젝트: ned21/aquilon
    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
예제 #30
0
    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
예제 #31
0
파일: dump_dns.py 프로젝트: jrha/aquilon
    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)
예제 #32
0
파일: qip.py 프로젝트: jrha/aquilon
    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())
예제 #33
0
    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())
예제 #34
0
파일: dump_dns.py 프로젝트: ned21/aquilon
    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)
예제 #35
0
파일: search_dns.py 프로젝트: piojo/aquilon
    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')
예제 #36
0
파일: search_dns.py 프로젝트: ned21/aquilon
    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()
예제 #37
0
    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
예제 #38
0
    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