Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: add timeout #17

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 56 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ The app knows how skpr mounts configuration into the container (via the mount at
* AWS Region `SKPRMAIL_AWS_REGION`
* From Address `SKPRMAIL_FROM_ADDRESS`

## Testing Locally
## Testing Locally

Create a file `/tmp/test-mail.txt` with the following contents. Adjust from/to address to those which are verified in SES.
Create a file `/tmp/test-mail.txt` with the following contents. Adjust from/to address to those which are verified in SES.
```
To: my@email.com
Subject: sendmail test two
From: [email protected]
And here goes the e-mail body, test test test..
FROM:me@myserver.com
To: [email protected]
Subject: sendmail test two

And here goes the e-mail body, test test test..
```

```bash
Expand All @@ -43,8 +43,56 @@ export SKPRMAIL_AWS_REGION=us-east-1
export [email protected]
$ cat /tmp/test-email.txt | skprmail
```

### Testing with local smtp server

- Create a fresh build of the binary using `make build`
- Create a file `/tmp/test-mail.txt` with the following contents. Adjust from/to address to those which are verified in SES.
```
FROM:[email protected]
To: [email protected]
Subject: sendmail test two

And here goes the e-mail body, test test test..
```
- `export SKPRMAIL_ADDR="localhost:1025"` (to point skprmail to our debug server)
- Start the smtp server in a new terminal window from `utils/smtp-debug-server/cmd/smtp-debug-server` by running `go run main.go` from that location (please note that the smtp server has a delay of 45s during startup set at `utils/smtp-debug-server/server.go:212`, enabling us to test timeout on skprmail)
- Run `$ cat /tmp/test-email.txt | bin/skprmail_linux_amd64 --timeout 10s` to test a 10 second timeout or run `$ cat /tmp/test-email.txt | bin/skprmail_linux_amd64` for a default 30s timeout. (please run the test command within 10 seconds of starting the debug server)
- Timeout error `Contacting the local smtp server timed out, cancelling...` will confirm timeout was engaged.
- Once the SMTP server starts after 45s with log message
```
2024/07/25 07:29:21 Starting SMTP server at 127.0.0.1:1025
220 localhost ESMTP Service Ready
```
You can test delivery of the email.
```
2024/07/25 08:05:06 Starting SMTP server at 127.0.0.1:1025
220 localhost ESMTP Service Ready
EHLO localhost
250-Hello localhost
250-PIPELINING
250-8BITMIME
250-ENHANCEDSTATUSCODES
250-CHUNKING
250 SIZE
MAIL FROM:<[email protected]> BODY=8BITMIME
250 2.0.0 Roger, accepting mail from <[email protected]>
RCPT TO:<[email protected]>
250 2.0.0 I'll make sure <[email protected]> gets this
DATA
354 Go ahead. End your data with <CR><LF>.<CR><LF>
From: [email protected]
To: [email protected]
Subject: sendmail test two

And here goes the e-mail body, test test test..
.
250 2.0.0 OK: queued
QUIT
221 2.0.0 Bye
```

### Releasing
## Releasing

Testing a release:

Expand Down
9 changes: 9 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ require (
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc
)

require (
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 // indirect
github.com/emersion/go-smtp v0.21.3 // indirect
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/tools v0.23.0 // indirect
)

require (
github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1 // indirect
Expand All @@ -27,6 +35,7 @@ require (
github.com/aws/smithy-go v1.20.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jpcornet/go-smtp v0.16.0
github.com/kr/pretty v0.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
Expand Down
23 changes: 23 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,16 @@ github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 h1:OJyUGMJTzHTd1XQp98QTaHernxMYzRaOasRir9hUlFQ=
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
github.com/emersion/go-smtp v0.21.3 h1:7uVwagE8iPYE48WhNsng3RRpCUpFvNl39JGNSIyGVMY=
github.com/emersion/go-smtp v0.21.3/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/jpcornet/go-smtp v0.16.0 h1:gQ3QPRXqyWoU/bY7Lcu8jpH9U6kGcRN125ZTrKK4BEg=
github.com/jpcornet/go-smtp v0.16.0/go.mod h1:ReS/LAjuRDDzerDTVYLuSWrpqDYj7dPoxdsUsUqdsg4=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
Expand All @@ -56,6 +62,23 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc=
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
141 changes: 0 additions & 141 deletions internal/mailutils/mailutils_test.go

This file was deleted.

22 changes: 16 additions & 6 deletions internal/provider/default/default.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package local

import (
"context"
"fmt"
"log"
"net/mail"
Expand All @@ -18,11 +19,22 @@ const (
// FallbackAddr where mail will be forwarded to.
FallbackAddr = "mail:1025"
// FallbackFrom address which will be applied to email.
FallbackFrom = "skprmail"
FallbackFrom = "[email protected]"
)

// Send the email to Mailhog.
func Send(to []string, msg *mail.Message) error {
func Send(ctx context.Context, to []string, msg *mail.Message) error {
ctx, cancel := context.WithCancel(ctx)
defer cancel()

// The GO SMTP package is difficult to cancel using context.
// This provider should only ever be used for local development tasks.
go func() {
<-ctx.Done()
fmt.Printf("Contacting the local smtp server timed out, cancelling...\n")
os.Exit(1)
}()

data, err := mailutils.MessageToBytes(msg)
if err != nil {
return err
Expand All @@ -38,16 +50,14 @@ func Send(to []string, msg *mail.Message) error {
}

from := os.Getenv(EnvFrom)
if addr == "" {
addr = FallbackFrom
if from == "" {
from = FallbackFrom
}

err = smtp.SendMail(addr, nil, from, to, data)
if err != nil {
return fmt.Errorf("failed to send message via mailhog smtp %w", err)
}

log.Println("successfully sent message via mailhog smtp")

return nil
}
6 changes: 3 additions & 3 deletions internal/provider/ses/ses.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import (
const AccessKeyPrefix = "AKIA"

// Send email via AWS SES.
func Send(region, username, password, from string, to []string, msg *mail.Message) error {
cfg, err := config.LoadDefaultConfig(context.TODO(),
func Send(ctx context.Context, region, username, password, from string, to []string, msg *mail.Message) error {
cfg, err := config.LoadDefaultConfig(ctx,
config.WithRegion(region),
config.WithCredentialsProvider(
credentials.NewStaticCredentialsProvider(username, password, ""),
Expand Down Expand Up @@ -53,7 +53,7 @@ func Send(region, username, password, from string, to []string, msg *mail.Messag
Source: aws.String(from),
}

output, err := ses.NewFromConfig(cfg).SendRawEmail(context.TODO(), input)
output, err := ses.NewFromConfig(cfg).SendRawEmail(ctx, input)
if err != nil {
return fmt.Errorf("failed to send message via ses %w", err)
}
Expand Down
Loading
Loading