Implement an Internal API to handle mailroom webhook
What does this MR do and why?
For gitlab-com/gl-infra/scalability#1457 (closed)
GitLab's incoming email feature enables the users to perform some actions on GitLab by replying to the notification directly. This feature depends on a service called MailRoom. Internally, this service uses a forked version of mailroom gem for the core logic. When the service starts, it periodically scans the configured email inboxes. New emails are pushed to GitLab Sidekiq fleet via EmailReceiverWorker and ServiceDeskEmailReceiverWorker. The recent configuration uses mailroom gem's sidekiq delivery strategy. This strategy pushes the job payloads directly into Redis without going through Sidekiq client middleware. This creates some issues:
- The queue name is hard-coded. This blocks gitlab-com/gl-infra&596 (closed)
- The Redis configuration is fixed. This blocks gitlab-com/gl-infra&423 (closed)
- As the jobs bypass the middleware layer, Sidekiq job compressor and limiter are bypassed.
We are making an attempt to migrate the sidekiq strategy to a webhook mechanism. This MR is one of the first step to accomplish that goal. Changes are in this MR:
- Implement an internal API:
POST /api/v4/internal/mail_room/*mailbox_type
. This internal endpoint uses a JWT-style authentication header. This pattern was used in gitlab-pages and kas. - Create
secret_file
field toincoming_email
andservice_desk_email
configuration. This field is the path to a shared symmetric secret file used to verify the JWT token in the Rails application. This field is essential to collaborate between mailroom processes and rails application in later iterations (gitlab-com/gl-infra/scalability#1456 (closed), gitlab-com/gl-infra/scalability#1458 (closed), gitlab-com/gl-infra/scalability#1461 (closed)). - Add
JwtAuthenticable
authentication to the aforementioned endpoint. This concern supports a single secret path at the moment. We'll need to modify it a bit to support two mailbox type secret files.
This MR should be review as a pair of the mailroom change.
Screenshots or screen recordings
This MR adds one internal endpoint. There shouldn't be any change from the user perspective.
How to set up and validate locally
- Point the mail_room gem
0.0.17
(https://gitlab.com/gitlab-org/gitlab-mail_room/-/merge_requests/45#note_797929096) - Create a temporary secret file.
echo "eao1Q7WZpH41L3tPdr0+NbUC6h8nHcQ9XE78mHxs5+A=" > /path/to/gdk/gitlab_mailroom_secret
- Add
secret_file
fields toincoming_email
andservice_desk_email
configurations inconfig/gitlab.yml
file. Setenabled
of both to true
incoming_email:
enabled: true
secret_file: /path/to/gdk/gitlab_mailroom_secret
service_desk_email:
enabled: true
secret_file: /path/to/gdk/gitlab_mailroom_secrett
- Start rails-web and rails-background-jobs
- Paste the following script to rails console. The script snippet is to add a command and close the latest issue. This script uses the new webhook delivery method in the gem, fires a POST request of the new endpoint.
require 'mail_room/delivery/postback'
incoming_email = Gitlab.config.incoming_email[:address].gsub('%{key}', SentNotification.where(noteable_type: "Issue").last.reply_key)
content = File.read("spec/fixtures/emails/commands_in_reply.eml")
content.gsub!("reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo", incoming_email)
::MailRoom::Delivery::Postback.new(MailRoom::Delivery::Postback::Options.new(MailRoom::Mailbox.new(
name: "inbox",
email: "user@example.com",
password: "password123",
delivery_options: {
delivery_url: 'http://localhost:3000/api/v4/internal/mail_room/incoming_email',
jwt_auth_header: "Gitlab-Mailroom-Api-Request",
jwt_issuer: "gitlab-mailroom",
jwt_algorithm: "HS256",
jwt_secret_path: Gitlab::MailRoom.enabled_configs[:incoming_email][:secret_file]
}
))).deliver(content)
- Ensure that email_receiver queue is drained (http://localhost:3000/admin/sidekiq/queues/email_receiver)
- Open letter_opener dashboard, you'll see the latest notification of the comment created from the above script.
- Click on the comment, the issue page shows the comment:
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.