Hi team
My question is that no matter which tenant I use to send emails, both egress_pool and egress_source are unspecified.
Is this by design or is there a problem with my test process? If both are unspecified, I can’t confirm which IP the emails are sent from.
init.lua
kumo.on('get_queue_config', function(domain, tenant, campaign, routing_domain)
local params = {
max_age = '5 minutes',
retry_interval = '10 minutes',
max_retry_interval = '100 minutes',
}
return kumo.make_queue_config (params)
end)
local queue_helper =
queue_module:setup { '/opt/kumomta/etc/policy/queues.toml' }
kumo.on('smtp_server_message_received', function(msg)
queue_helper:apply(msg)
end)
source.toml
[source."ip-1"]
source_address = "127.0.0.1"
[source."ip-2"]
source_address = '127.0.0.1'
# Pool containing just ip-1, which has weight=1
[pool."pool-1"]
[pool."pool-1"."ip-1"]
# Pool with multiple ips
[pool."pool-2"]
[pool."pool-2"."ip-2"]
queue.toml
scheduling_header = "X-Schedule"
tenant_header = "X-Tenant"
remove_tenant_header = true
campaign_header = "X-Campaign"
remove_campaign_header = true
default_tenant = "default-tenant"
[tenant.'default-tenant']
egress_pool = 'pool-1'
[tenant.'mytenant']
egress_pool = 'pool-2'
I add some logs in /opt/kumomta/share/policy-extras/queue.lua , → local function resolve_config
if domain_config then
local tenant_config = domain_config.tenants[tenant]
if tenant_config then
for k, v in pairs(tenant_config) do
if allow_all or is_queue_config_option(k, v) then
print('key ,value is ',k ,v )
params[k] = v
end
end
local campaign = tenant_config.campaigns[campaign]
if campaign then
for k, v in pairs(campaign) do
if allow_all or is_queue_config_option(k, v) then
print('key ,value is ',k ,v )
params[k] = v
end
end
end
end
end
if utils.table_is_empty(params) then
return nil
end
print('after kv set -->',kumo.json_encode_pretty(params))
return params
Use swaks as a testing tool.
swaks --to myemail@gmail.com --from kumomta-test@kumomta-test.com \
--header "X-Tenant : default-tenant" \
--server localhost \
--header "Subject: xxxx" \
--port 25 \
--body "<p>this is content.</p>"
The log output seems ok.
kv set after–>
{
“refresh_strategy”: “Epoch”,
“max_age”: “10 hours”,
“egress_pool”: “pool-1”,
“tenants”: {}
}
second test
swaks --to myemail@gmail.com --from kumomta-test@kumomta-test.com \
--header "X-Tenant : mytenant" \
--server localhost \
--header "Subject: xxxx" \
--port 25 \
--body "<p>this is content.</p>"
kv set after–>
{
“refresh_strategy”: “Epoch”,
“max_age”: “10 hours”,
“egress_pool”: “pool-2”,
“tenants”: {}
}
but in both log, are unspecified
{"type":"Delivery","id":"a7adb2ca053911f0a811000c29d06603","sender":"kumomta-test@kumomta-test.com","recipient":"xxxxxx","queue":"mytenant@gmail.com","site":"unspecified->(126mx01|126mx02|126mx03|126mx00).mxmail.netease.com@smtp_client","size":616,"response":{"code":250,"enhanced_code":null,"content":"Mail OK queued as gzga-mx-mtada-g1-3,_____wD3X9CHiNtnCdJnAA--.52864S3 1742440589","command":".\r\n"},"peer_address":{"name":"126mx03.xxxxxx.","addr":"xxxxxx"},"timestamp":1742440589,"created":1742440563,"num_attempts":0,"bounce_classification":"Uncategorized","egress_pool":"unspecified","egress_source":"unspecified","source_address":{"address":"192.168.1.31:35916"},"feedback_report":null,"meta":{},"headers":{"Subject":"xxxx","X-Mailer":"swaks v20240103.0 jetmore.org/john/code/swaks/","X-KumoRef":"eyJfQF8iOiJcXF8vIiwicmVjaXBpZW50IjoicXFsaXVzaGVuZ2ppZUAxMjYuY29tIn0="},"delivery_protocol":"ESMTP","reception_protocol":"ESMTP","nodeid":"8d36c855-70cb-4b75-9246-d951a972eadb","tls_cipher":"TLS13_AES_256_GCM_SHA384","tls_protocol_version":"TLSv1_3","session_id":"16c732c5-55e1-4f3b-9ab1-84bdd0ad9676"}
if in get_queue_config add egress_pool = ‘pool-1’ , th log are all ok(all are pool-1)
kumo.on('get_queue_config', function(domain, tenant, campaign, routing_domain)
local params = {
max_age = '5 minutes',
retry_interval = '10 minutes',
max_retry_interval = '100 minutes',
egress_pool = 'pool-1',
}
return kumo.make_queue_config (params)
end)
unspecified means no pool has been selected so it will use the host default. your code has not assigned a pool with a valid source.
I’m not sure routing outbound messages through localhost is a good idea.
You should use EITHER the helper or the Lua config, not both.
I’m writing to confirm if you meant that my code fails to assign a pool from the get_queue_config function. As shown in the previous code snippet, there’s an example of directly assigning the egress_pool, like egress_pool = ‘pool-1’;.
Here’s the situation I’m facing. When I configure using Lua code directly, everything works smoothly. However, when I opt to use the helper function, it seems unable to utilize pool-2 based on the configuration of tenant.‘mytenant’ in the queue.toml file.
Could you provide some insights on what might be causing this issue?
Is it a necessary action to set ‘pools’ in ‘get_queue_config’? That is, even if the ‘helper’ is used. If so, there might be something wrong with my thinking.
You do not need to set pools and the way you have written it, the queue selection will never fire
Thank you for your reply. Perhaps need to explain in detail why it won’t be triggered. As I understand it, queue_helper:apply(msg) in smtp_server_message_received should trigger queue selection. Thanks again
It will probably help to remove the get_queue_config section completely and move the parameters to the queue helper.
Thanks , I know the problem. Just delete all the get_queue_config.
But in my case, I need to set the webhook in get_queue_config.
As long as this method exists, you need to explicitly specify the egress_pool. I expect both to be usable, and get_queue_config only controls the webhook.
kumo.on('get_queue_config', function(domain, tenant, campaign, routing_domain)
if domain == 'webhook' then
return kumo.make_queue_config {
protocol = {
custom_lua = {
constructor = 'make.webhook',
},
},
}
end
if domain == 'kafka' then
return kumo.make_queue_config {
protocol = {
custom_lua = {
constructor = 'make.kafka',
},
},
}
end
return kumo.make_queue_config {}
end)
When calling get_queue_config, the queue helper stops working. If I don’t call get_queue_config, I can’t complete the separation of the webhook. This seems to be a paradox.
It seems that I can only implement the rules in queue.toml in get_queue_config.
I will try ,let webhook and kafka config to queue.toml files.
Thanks, I’ve already solved it. The solution is to comment out the last – return kumo.make_queue_config {}
Ah yeah that will do it. Depends on whether you need multiple queue configs and that was not clear in your question.