On Mon, Nov 28, 2022 at 08:57:37PM +0000, Sean Hennessey wrote:

> I searched the list archives and saw the thread of gradual shift of
> traffic from back in February of this year. That gives me some ideas,
> but that seems to be for all traffic, not a subset.
> 
> I'd really like a way to send X% of gmail.com traffic to one relay and
> the rest to another relay. Ditto for a couple of other major ESP's
> like Yahoo, MS, etc...

If you're willing to spin up a small Postgres database (modulo typos
on my part that should be easy to correct):

    query = SELECT U."transport"
            FROM (
                SELECT CASE WHEN floor(random()*100) <= T."weight"
                       THEN T."transport"
                       END AS "transport"
                FROM "transports" AS T
                WHERE T."domain" = '%s'
            ) AS U
            WHERE U."transport" IS NOT NULL;

Just populate a table:

    CREATE TABLE IF NOT EXISTS "transports" (
        "domain" TEXT PRIMARY KEY,
        "transport" TEXT NOT NULL,
        "weight" INTEGER NOT NULL
        );
    INSERT INTO "transports" ("domain", "transport", "weight")
    VALUES ( "gmail.com", "relay:[gmail-relay.example]", 99),
           ( "yahoo.com", "relay:[yahoo-relay.example]", 50),
           ... ;

And gradually lower the weights until, at weight 0, 99% of the traffic
is direct to MX and just 1% of the traffic goes to the bypass relay and
after that the row can be deleted.  Initially, at weight 99, all the
traffic goes to the bypass relay.

If you want to specify a custom transport even after removing the relay,
add a fourth (nullable) column and use that value in an ELSE clause of
the CASE statement, in which case that value will be used when the
bypass is not selected.

Keeping the Postgres database local to the MTA will improve performance
and reliability.  I'd resist the temptation to centralise it, but that
is an option if you're willing to have Postfix stall when a remote DB
server is unreachable or slow, or can somehow avoid that.

It is not obvious to me, just at the moment, how to do this with the
built-in Postfix randmap, pipemap, uniomap, ...

-- 
    Viktor.

Reply via email to