Exemple #1
0
    def assign_zebra_address(self, session, dbmachine, dbdns_rec,
                             zebra_interfaces):
        """ Assign a Zebra-managed address to multiple interfaces """

        # Reset the routing configuration
        for iface in dbmachine.interfaces:
            if iface.default_route:
                iface.default_route = False

        # Disable autoflush, since the ServiceAddress object won't be complete
        # until add_resource() is called
        with session.no_autoflush:
            resholder = HostResource(host=dbmachine.host)
            session.add(resholder)
            dbsrv_addr = ServiceAddress(name="hostname", dns_record=dbdns_rec)
            resholder.resources.append(dbsrv_addr)

            for name in zebra_interfaces.split(","):
                dbinterface = None
                for iface in dbmachine.interfaces:
                    if iface.name == name:
                        dbinterface = iface
                if not dbinterface:
                    raise ArgumentError("{0} does not have an interface named "
                                        "{1}.".format(dbmachine, name))
                assign_address(dbinterface,
                               dbdns_rec.ip,
                               dbdns_rec.network,
                               label="hostname",
                               resource=dbsrv_addr)

                # Make sure the transit IPs resolve to the primary name
                for addr in dbinterface.assignments:
                    if addr.label:
                        continue
                    for dnr in addr.dns_records:
                        dnr.reverse_ptr = dbdns_rec.fqdn

                # Transits should be providers of the default route
                dbinterface.default_route = True

        return dbsrv_addr
Exemple #2
0
    def render(self, session, logger, service_address, ip, name, interfaces,
               hostname, cluster, resourcegroup, network_environment,
               map_to_primary, comments, **arguments):

        validate_basic("name", name)

        # TODO: generalize the error message - Layer-3 failover may be
        # implemented by other software, not just Zebra.
        if name == "hostname":
            raise ArgumentError(
                "The hostname service address is reserved for "
                "Zebra.  Please specify the --zebra_interfaces "
                "option when calling add_host if you want the "
                "primary name of the host to be managed by "
                "Zebra.")

        ifnames = [ifname.strip().lower() for ifname in interfaces.split(",")]
        if not ifnames:
            raise ArgumentError("Please specify at least one interface name.")

        holder = get_resource_holder(session,
                                     hostname,
                                     cluster,
                                     resourcegroup,
                                     compel=False)

        # Address assignments should be added based on the host/cluster, so we
        # have to resolve resource groups first
        if isinstance(holder.holder_object, ResourceGroup):
            real_holder = holder.holder_object.holder.holder_object
        else:
            real_holder = holder.holder_object

        ServiceAddress.get_unique(session,
                                  name=name,
                                  holder=holder,
                                  preclude=True)

        # TODO: add allow_multi=True
        dbdns_rec, newly_created = grab_address(session, service_address, ip,
                                                network_environment)
        ip = dbdns_rec.ip
        dbnetwork = dbdns_rec.network

        if map_to_primary:
            if not isinstance(real_holder, Host):
                raise ArgumentError("The --map_to_primary option works only "
                                    "for host-based service addresses.")
            dbdns_rec.reverse_ptr = real_holder.machine.primary_name.fqdn

        # Disable autoflush, since the ServiceAddress object won't be complete
        # until add_resource() is called
        with session.no_autoflush:
            dbsrv = ServiceAddress(name=name,
                                   dns_record=dbdns_rec,
                                   comments=comments)
            holder.resources.append(dbsrv)

            oldinfo = None
            if isinstance(real_holder, Cluster):
                if not real_holder.hosts:
                    # The interface names are only stored in the
                    # AddressAssignment objects, so we can't handle a cluster
                    # with no hosts and thus no interfaces
                    raise ArgumentError("Cannot assign a service address to a "
                                        "cluster that has no members.")
                for host in real_holder.hosts:
                    apply_service_address(host, ifnames, dbsrv)
            elif isinstance(real_holder, Host):
                oldinfo = DSDBRunner.snapshot_hw(real_holder.machine)
                apply_service_address(real_holder, ifnames, dbsrv)
            else:  # pragma: no cover
                raise UnimplementedError("{0} as a resource holder is not "
                                         "implemented.".format(real_holder))

        add_resource(session,
                     logger,
                     holder,
                     dbsrv,
                     dsdb_callback=add_srv_dsdb_callback,
                     real_holder=real_holder,
                     oldinfo=oldinfo,
                     newly_created=newly_created,
                     comments=comments)

        return