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

enhancement: Add ability to attach files to email #6

Merged
merged 7 commits into from
Mar 21, 2022
Merged
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
6 changes: 6 additions & 0 deletions DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,12 @@ The following parameters are used to configure the image:

### Attachment

| Parameter | Description | Required | Default | Environment Variables |
| ------------ | ------------------------------ | -------- | ------- | -------------------------------------------- |
| `attachment` | file will be attached to email | false | N/A | `PARAMETER_ATTACHMENT`<br>`EMAIL_ATTACHMENT` |

### Email Filename

| Parameter | Description | Required | Default | Environment Variables |
| ---------- | --------------------------------------------------------- | -------- | ------- | ---------------------------------------- |
| `filename` | data in attached file will be used to populate the email. | false | N/A | `PARAMETER_FILENAME`<br>`EMAIL_FILENAME` |
Expand Down
23 changes: 16 additions & 7 deletions cmd/vela-email/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ func main() {
Name: "readreceipt",
Usage: "request read receipts and delivery notifications",
},
// Attachment flag
&cli.StringFlag{
EnvVars: []string{"PARAMETER_ATTACHMENT", "EMAIL_ATTACHMENT"},
Name: "attachment",
Usage: "file to attach to email",
},
// SmtpHost flags
&cli.StringFlag{
EnvVars: []string{"PARAMETER_HOST", "EMAIL_HOST"},
Expand All @@ -129,11 +135,11 @@ func main() {
Name: "password",
Usage: "smtp host password",
},
// Attachment flag
// EmailFilename flag
&cli.StringFlag{
EnvVars: []string{"PARAMETER_FILENAME", "EMAIL_FILENAME"},
Name: "filename",
Usage: "file to attach to email",
Usage: "file that contains email information (To, From, Subject, etc.)",
},
// TLSConfig flag
&cli.BoolFlag{
Expand Down Expand Up @@ -229,11 +235,6 @@ func run(c *cli.Context) error {
// auth configuration
Auth: c.String("auth"),

// attachment configuration
Attachment: &email.Attachment{
Filename: c.String("filename"),
},

// email configuration
Email: &email.Email{
ReplyTo: c.StringSlice("replyto"),
Expand All @@ -248,6 +249,14 @@ func run(c *cli.Context) error {
ReadReceipt: c.StringSlice("readreceipt"),
},

// email filename configuration
EmailFilename: c.String("filename"),

// attachment configuration
Attachment: &email.Attachment{
Filename: c.String("attachment"),
},

// smtp configuration
SMTPHost: &SMTPHost{
Host: c.String("host"),
Expand Down
30 changes: 24 additions & 6 deletions cmd/vela-email/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ var (
// ErrorMissingEmailFromParam is returned when the plugin is missing the From email parameter.
ErrorMissingEmailFromParam = errors.New("missing email parameter: From")

// ErrorEmptyAttach is returned when the plugin finds the provided attachment to be empty.
ErrorEmptyAttach = errors.New("attachment provided is empty")
// ErrorEmptyFile is returned when the plugin finds the provided attachment to be empty.
ErrorEmptyFile = errors.New("file provided is empty")

// ErrorMissingSMTPParam is returned when the plugin is missing a smtp host or port parameter.
ErrorMissingSMTPParam = errors.New("missing smtp parameter (host/port)")
Expand All @@ -38,6 +38,8 @@ type (
Plugin struct {
// Email arguments loaded for the plugin
Email *email.Email
// EmailFilename arguments loaded for the plugin
EmailFilename string
// Attachment arguments loaded for the plugin
Attachment *email.Attachment
// SmtpHost arguments loaded for the plugin
Expand Down Expand Up @@ -78,17 +80,17 @@ func (p *Plugin) Validate() error {

logrus.Info("Validating Parameters...")

if len(p.Attachment.Filename) != 0 {
fileInfo, err := os.Stat(p.Attachment.Filename)
if len(p.EmailFilename) != 0 {
fileInfo, err := os.Stat(p.EmailFilename)
if errors.Is(err, os.ErrNotExist) {
kaymckay marked this conversation as resolved.
Show resolved Hide resolved
return os.ErrNotExist
}

if fileInfo.Size() == 0 {
return ErrorEmptyAttach
return ErrorEmptyFile
}

file, err := os.Open(p.Attachment.Filename)
file, err := os.Open(p.EmailFilename)
if err != nil {
return err
}
Expand Down Expand Up @@ -119,6 +121,22 @@ func (p *Plugin) Validate() error {
return ErrorMissingEmailFromParam
}

if len(p.Attachment.Filename) != 0 {
fileInfo, err := os.Stat(p.Attachment.Filename)
if errors.Is(err, os.ErrNotExist) {
kaymckay marked this conversation as resolved.
Show resolved Hide resolved
return os.ErrNotExist
}

if fileInfo.Size() == 0 {
return ErrorEmptyFile
}

p.Attachment, err = p.Email.AttachFile(p.Attachment.Filename)
if err != nil {
return err
}
}

if len(p.SMTPHost.Host) == 0 || len(p.SMTPHost.Port) == 0 {
return ErrorMissingSMTPParam
}
Expand Down
121 changes: 91 additions & 30 deletions cmd/vela-email/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ var (
Username: "username",
Password: "password",
}

noAttachment = &email.Attachment{
Filename: "",
}
Expand All @@ -38,10 +39,11 @@ var (
}

mockPlugin = &Plugin{
Email: mockEmail,
SMTPHost: mockSMTPHost,
Attachment: noAttachment,
BuildEnv: mockBuildEnv,
Email: mockEmail,
EmailFilename: "",
SMTPHost: mockSMTPHost,
Attachment: noAttachment,
BuildEnv: mockBuildEnv,
}
)

Expand All @@ -68,9 +70,10 @@ func TestValidateSuccess(t *testing.T) {
{
name: "return no errors: single To email",
parameters: Plugin{
Email: mockEmail,
SMTPHost: mockSMTPHost,
Attachment: noAttachment,
Email: mockEmail,
EmailFilename: "",
SMTPHost: mockSMTPHost,
Attachment: noAttachment,
},
},
{
Expand All @@ -80,8 +83,9 @@ func TestValidateSuccess(t *testing.T) {
To: []string{"[email protected]", "[email protected]"},
From: "[email protected]",
},
SMTPHost: mockSMTPHost,
Attachment: noAttachment,
EmailFilename: "",
SMTPHost: mockSMTPHost,
Attachment: noAttachment,
},
},
{
Expand All @@ -91,6 +95,7 @@ func TestValidateSuccess(t *testing.T) {
To: []string{"[email protected]", "[email protected]"},
From: "[email protected]",
},
EmailFilename: "",
SMTPHost: &SMTPHost{
Host: "smtphost.com",
Port: "587",
Expand All @@ -113,8 +118,9 @@ func TestValidateSuccess(t *testing.T) {
Sender: "sender",
ReadReceipt: []string{"idk"},
},
SMTPHost: mockSMTPHost,
Attachment: noAttachment,
EmailFilename: "",
SMTPHost: mockSMTPHost,
Attachment: noAttachment,
},
},
{
Expand All @@ -124,9 +130,32 @@ func TestValidateSuccess(t *testing.T) {
To: []string{""},
From: "",
},
SMTPHost: mockSMTPHost,
EmailFilename: "testdata/example1.txt",
SMTPHost: mockSMTPHost,
Attachment: &email.Attachment{
Filename: "testdata/example1.txt",
Filename: "",
},
},
},
{
name: "return no errors: add txt attachment to email",
parameters: Plugin{
Email: mockEmail,
EmailFilename: "",
SMTPHost: mockSMTPHost,
Attachment: &email.Attachment{
Filename: "",
},
},
},
{
name: "return no errors: add png image attachment to email",
parameters: Plugin{
Email: mockEmail,
EmailFilename: "",
SMTPHost: mockSMTPHost,
Attachment: &email.Attachment{
Filename: "testdata/vela.png",
},
},
},
Expand All @@ -153,7 +182,8 @@ func TestValidateErrors(t *testing.T) {
Email: &email.Email{
From: "[email protected]",
},
Attachment: noAttachment,
EmailFilename: "",
Attachment: noAttachment,
},
wantErr: ErrorMissingEmailToParam,
},
Expand All @@ -163,27 +193,51 @@ func TestValidateErrors(t *testing.T) {
Email: &email.Email{
To: []string{"[email protected]"},
},
Attachment: noAttachment,
EmailFilename: "",
Attachment: noAttachment,
},
wantErr: ErrorMissingEmailFromParam,
},
{
name: "Email parameters missing from attachment",
name: "Email parameters missing from file",
parameters: Plugin{
Email: &email.Email{
To: []string{""},
From: "",
},
SMTPHost: mockSMTPHost,
EmailFilename: "testdata/badattachment.txt",
SMTPHost: mockSMTPHost,
Attachment: &email.Attachment{
Filename: "testdata/badattachment.txt",
Filename: "",
},
},
wantErr: io.EOF,
},
{
name: "Email file missing",
parameters: Plugin{
EmailFilename: "testdata/doesnotexist.txt",
Attachment: &email.Attachment{
Filename: "",
},
},
wantErr: os.ErrNotExist,
},
{
name: "Email file empty",
parameters: Plugin{
EmailFilename: "testdata/empty.txt",
Attachment: &email.Attachment{
Filename: "",
},
},
wantErr: ErrorEmptyFile,
},
{
name: "Email attachment missing",
parameters: Plugin{
Email: mockEmail,
EmailFilename: "",
Attachment: &email.Attachment{
Filename: "testdata/doesnotexist.txt",
},
Expand All @@ -193,16 +247,19 @@ func TestValidateErrors(t *testing.T) {
{
name: "Email attachment empty",
parameters: Plugin{
Email: mockEmail,
EmailFilename: "",
Attachment: &email.Attachment{
Filename: "testdata/empty.txt",
},
},
wantErr: ErrorEmptyAttach,
wantErr: ErrorEmptyFile,
},
{
name: "SMTP host missing",
parameters: Plugin{
Email: mockEmail,
Email: mockEmail,
EmailFilename: "",
SMTPHost: &SMTPHost{
Port: "1902",
},
Expand All @@ -213,7 +270,8 @@ func TestValidateErrors(t *testing.T) {
{
name: "SMTP port missing",
parameters: Plugin{
Email: mockEmail,
Email: mockEmail,
EmailFilename: "",
SMTPHost: &SMTPHost{
Host: "smtphost.com",
},
Expand Down Expand Up @@ -252,9 +310,10 @@ func TestInjectEnvSuccess(t *testing.T) {
Subject: DefaultSubject,
Text: []byte("This is some text for repo: {{ .VELA_REPO_FULL_NAME }}"),
},
SMTPHost: mockSMTPHost,
Attachment: noAttachment,
BuildEnv: mockBuildEnv,
EmailFilename: "",
SMTPHost: mockSMTPHost,
Attachment: noAttachment,
BuildEnv: mockBuildEnv,
},
},
{
Expand All @@ -266,9 +325,10 @@ func TestInjectEnvSuccess(t *testing.T) {
Subject: "Commit failure on vela build: {{ .VELA_BUILD_NUMBER }}",
Text: []byte("This is some text for repo: {{ .VELA_REPO_FULL_NAME }}"),
},
SMTPHost: mockSMTPHost,
Attachment: noAttachment,
BuildEnv: mockBuildEnv,
EmailFilename: "",
SMTPHost: mockSMTPHost,
Attachment: noAttachment,
BuildEnv: mockBuildEnv,
},
},
}
Expand Down Expand Up @@ -319,9 +379,10 @@ func TestInjectEnvBadVar(t *testing.T) {
From: "[email protected]",
Subject: "This is a bad subject {{ .SOME_OTHER_VARIABLE }}",
},
SMTPHost: mockSMTPHost,
Attachment: noAttachment,
BuildEnv: mockBuildEnv,
EmailFilename: "",
SMTPHost: mockSMTPHost,
Attachment: noAttachment,
BuildEnv: mockBuildEnv,
},
},
}
Expand Down
2 changes: 2 additions & 0 deletions cmd/vela-email/testdata/example1.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
From: [email protected]
To: [email protected], [email protected]
Bcc: [email protected]
Cc: [email protected]
Subject: Vela Pipeline for {{ .VELA_REPO_FULL_NAME }} {{ .VELA_BUILD_BRANCH }}
Content-Type: text/plain

Expand Down
Binary file added cmd/vela-email/testdata/vela.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.