Skip to content

Commit fe4c1a1

Browse files
stvnksslrarikalon1
andauthored
feat(ses support): (#1873)
* feat(ses support): * fix(test creds): --------- Co-authored-by: arik <alon.arik@gmail.com>
1 parent 8d4fe5a commit fe4c1a1

5 files changed

Lines changed: 770 additions & 54 deletions

File tree

docs/configuration/sinks/mail.rst

Lines changed: 161 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,20 @@ Mail
22
#################
33

44
Robusta can report issues and events in your Kubernetes cluster by sending
5-
emails.
5+
emails using either SMTP servers or Amazon Simple Email Service (SES).
66

77
Connecting the mail sink
88
------------------------------------------------
99

10-
To set up the mail sink, you need access to an SMTP server. You should also
10+
The mail sink supports two modes:
11+
12+
1. **SMTP Mode** (default): Uses any SMTP server via the `Apprise library <https://github.com/caronc/apprise>`_
13+
2. **Amazon SES Mode**: Uses AWS Simple Email Service for improved reliability and deliverability
14+
15+
SMTP Configuration
16+
------------------------------------------------
17+
18+
To set up SMTP mode, you need access to an SMTP server. You should also
1119
set the sender and receiver(s) addresses.
1220

1321
Robusta uses `Apprise library <https://github.com/caronc/apprise>`_ under the hood for running mail
@@ -18,10 +26,7 @@ the convenient and sophisticated syntax provided by Apprise. For more details
1826
.. image:: /images/mail_sink1.png
1927
:width: 640
2028

21-
Configuring the mail sink
22-
------------------------------------------------
23-
24-
.. admonition:: Add this to your generated_values.yaml
29+
.. admonition:: SMTP Configuration - Add this to your generated_values.yaml
2530

2631
.. code-block:: yaml
2732
@@ -31,12 +36,160 @@ Configuring the mail sink
3136
mailto: "mailtos://user:password@server&from=a@x&to=b@y,c@z"
3237
with_header: false # optional
3338
39+
Amazon SES Configuration
40+
------------------------------------------------
41+
42+
Amazon SES provides better deliverability, detailed analytics, and is often more cost-effective than traditional SMTP servers.
43+
44+
Prerequisites
45+
^^^^^^^^^^^^^
46+
47+
1. **AWS Account**: Set up an AWS account with SES enabled
48+
2. **SES Setup**: Verify sender email addresses in SES console
49+
3. **IAM Permissions**: Ensure your AWS credentials have ``ses:SendEmail`` and ``ses:SendRawEmail`` permissions
50+
4. **Production Access**: For production use, request SES production access (initially in sandbox mode)
51+
52+
.. admonition:: SES Configuration - Add this to your generated_values.yaml
53+
54+
.. code-block:: yaml
55+
56+
sinksConfig:
57+
- mail_sink:
58+
name: ses_mail_sink
59+
mailto: "mailtos://alerts@company.com" # Recipient addresses
60+
use_ses: true
61+
aws_region: "us-east-1"
62+
from_email: "robusta-alerts@company.com"
63+
with_header: true # optional
64+
# Optional: explicit AWS credentials (prefer IAM roles)
65+
# aws_access_key_id: "${AWS_ACCESS_KEY_ID}"
66+
# aws_secret_access_key: "${AWS_SECRET_ACCESS_KEY}"
67+
# configuration_set: "robusta-emails" # optional
68+
69+
SES Configuration Parameters
70+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
71+
72+
.. list-table::
73+
:header-rows: 1
74+
:widths: 25 15 60
75+
76+
* - Parameter
77+
- Required
78+
- Description
79+
* - ``use_ses``
80+
- Yes
81+
- Set to ``true`` to enable SES mode
82+
* - ``aws_region``
83+
- Yes
84+
- AWS region where SES is configured (e.g., ``us-east-1``)
85+
* - ``from_email``
86+
- Yes
87+
- Verified sender email address in SES
88+
* - ``mailto``
89+
- Yes
90+
- Recipient email addresses (same format as SMTP mode)
91+
* - ``aws_access_key_id``
92+
- No
93+
- AWS access key (prefer IAM roles over explicit credentials)
94+
* - ``aws_secret_access_key``
95+
- No
96+
- AWS secret key (prefer IAM roles over explicit credentials)
97+
* - ``configuration_set``
98+
- No
99+
- SES configuration set for tracking and analytics
100+
101+
Authentication Options
102+
^^^^^^^^^^^^^^^^^^^^^^
103+
104+
**Option 1: IAM Roles (Recommended)**
105+
106+
For clusters running in AWS (EKS), use IAM roles for service accounts:
107+
108+
.. code-block:: yaml
109+
110+
sinksConfig:
111+
- mail_sink:
112+
name: ses_mail_sink
113+
mailto: "mailtos://alerts@company.com"
114+
use_ses: true
115+
aws_region: "us-east-1"
116+
from_email: "robusta@company.com"
117+
118+
**Option 2: Environment Variables**
119+
120+
Set AWS credentials as environment variables:
121+
122+
.. code-block:: bash
123+
124+
export AWS_ACCESS_KEY_ID="your-access-key"
125+
export AWS_SECRET_ACCESS_KEY="your-secret-key"
126+
127+
**Option 3: Explicit Configuration**
128+
129+
Include credentials directly in configuration (not recommended for production):
130+
131+
.. code-block:: yaml
132+
133+
sinksConfig:
134+
- mail_sink:
135+
name: ses_mail_sink
136+
mailto: "mailtos://alerts@company.com"
137+
use_ses: true
138+
aws_region: "us-east-1"
139+
from_email: "robusta@company.com"
140+
aws_access_key_id: "${AWS_ACCESS_KEY_ID}"
141+
aws_secret_access_key: "${AWS_SECRET_ACCESS_KEY}"
142+
143+
Multiple Recipients
144+
^^^^^^^^^^^^^^^^^^^
145+
146+
SES mode supports multiple recipients using the same mailto format:
147+
148+
.. code-block:: yaml
149+
150+
mailto: "mailtos://primary@company.com?to=secondary@company.com,third@company.com"
151+
152+
Common Parameters
153+
------------------------------------------------
154+
155+
The following parameters apply to both SMTP and SES modes:
156+
157+
.. list-table::
158+
:header-rows: 1
159+
:widths: 25 15 60
160+
161+
* - Parameter
162+
- Default
163+
- Description
164+
* - ``with_header``
165+
- ``true``
166+
- Include finding header, investigate button, and notification source
167+
* - ``name``
168+
- Required
169+
- Unique name for this sink configuration
170+
34171
The default value of the optional `with_header` parameter is `true`. If set to `false`, mails
35172
sent by this sink will *not* include header information, such as the finding header, investigate
36173
button and the source of the notification.
37174

175+
Troubleshooting
176+
------------------------------------------------
177+
178+
**SES Issues**
179+
180+
- **Authentication errors**: Verify AWS credentials and IAM permissions
181+
- **Message rejected**: Check that sender email is verified in SES console
182+
- **Rate limiting**: SES has sending quotas; check your SES console for limits
183+
- **Sandbox mode**: In SES sandbox, you can only send to verified email addresses
184+
185+
**SMTP Issues**
186+
187+
- **Connection errors**: Verify SMTP server details and network connectivity
188+
- **Authentication failures**: Check username/password in mailto URL
189+
- **TLS/SSL issues**: Ensure correct protocol (``mailto://`` vs ``mailtos://``)
190+
38191
.. note::
39192

40-
We highly recommend using the quotes around "mailto" to ensure special characters are handled correctly.
193+
We highly recommend using quotes around "mailto" to ensure special characters are handled correctly.
41194

42-
Then do a :ref:`Helm Upgrade <Simple Upgrade>`.
195+
Then do a :ref:`Helm Upgrade <Simple Upgrade>`.

src/robusta/core/sinks/mail/mail_sink.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,20 @@
77
class MailSink(SinkBase):
88
def __init__(self, sink_config: MailSinkConfigWrapper, registry):
99
super().__init__(sink_config.mail_sink, registry)
10+
params = sink_config.mail_sink
11+
1012
self.sender = MailSender(
11-
sink_config.mail_sink.mailto,
13+
params.mailto,
1214
self.signing_key,
1315
self.account_id,
1416
self.cluster_name,
17+
use_ses=params.use_ses,
18+
aws_region=params.aws_region,
19+
from_email=params.from_email,
20+
aws_access_key_id=params.aws_access_key_id,
21+
aws_secret_access_key=params.aws_secret_access_key,
22+
configuration_set=params.configuration_set,
23+
skip_ses_init=params.skip_ses_init,
1524
)
1625

1726
def write_finding(self, finding: Finding, platform_enabled: bool):

src/robusta/core/sinks/mail/mail_sink_params.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Optional
22

3-
from pydantic import validator
3+
from pydantic import validator, root_validator
44

55
from robusta.core.sinks.sink_base_params import SinkBaseParams
66
from robusta.core.sinks.sink_config import SinkConfigBase
@@ -10,6 +10,15 @@ class MailSinkParams(SinkBaseParams):
1010
mailto: str
1111
with_header: Optional[bool] = True
1212

13+
# SES Configuration
14+
use_ses: Optional[bool] = False
15+
aws_region: Optional[str] = None
16+
from_email: Optional[str] = None
17+
aws_access_key_id: Optional[str] = None
18+
aws_secret_access_key: Optional[str] = None
19+
configuration_set: Optional[str] = None
20+
skip_ses_init: Optional[bool] = False # For testing purposes
21+
1322
@classmethod
1423
def _get_sink_type(cls):
1524
return "mail"
@@ -22,6 +31,17 @@ def validate_mailto(cls, mailto):
2231
raise AttributeError(f"{mailto} is not a mailto(s) address")
2332
return mailto
2433

34+
@root_validator
35+
def validate_ses_configuration(cls, values):
36+
use_ses = values.get("use_ses", False)
37+
if use_ses:
38+
# Check for required fields when SES is enabled
39+
if not values.get("from_email"):
40+
raise ValueError("from_email is required when use_ses=True")
41+
if not values.get("aws_region"):
42+
raise ValueError("aws_region is required when use_ses=True")
43+
return values
44+
2545

2646
class MailSinkConfigWrapper(SinkConfigBase):
2747
mail_sink: MailSinkParams

0 commit comments

Comments
 (0)