allow infra cli to add email aliases

This commit is contained in:
viktorbarzin 2021-04-08 22:12:45 +01:00
parent ebe864ee4c
commit b46a5722c6
5 changed files with 121 additions and 6 deletions

81
cli/email_alias.go Normal file
View file

@ -0,0 +1,81 @@
package main
import (
"fmt"
"io/ioutil"
"os"
"strings"
"github.com/badoux/checkmail"
"github.com/brianvoe/gofakeit/v6"
"github.com/golang/glog"
"github.com/pkg/errors"
)
const (
addEmailAliasUseCase = "add-email-alias"
emailAliasFlagName = "forward-to"
fromEmailDomainFlagName = "from-domain"
emailAliasesConfigFileRelative = "/modules/kubernetes/mailserver/extra/aliases.txt"
)
func addEmailAlias(gitFs *GitFS, to, fromDomain string) (string, error) {
if err := checkmail.ValidateFormat(to); err != nil {
return "", errors.Wrapf(err, fmt.Sprintf("failed to create new email aliases because invalid input format: %s", to))
}
if err := checkmail.ValidateHost(to); err != nil {
return "", errors.Wrapf(err, fmt.Sprintf("failed to create new email aliases because domain for %s does not exist", to))
}
aliasEmail := generateRandomEmail(fromDomain)
glog.Infof("Adding %s -> %s alias to %s", aliasEmail, to, emailAliasesConfigFileRelative)
contents := fmt.Sprintf("%s %s", aliasEmail, to)
// Read existing contents
fRead, err := (*gitFs.fs).OpenFile(emailAliasesConfigFileRelative, os.O_RDONLY, 0644)
if err != nil {
return "", errors.Wrapf(err, "failed to open file where email aliases are recorded")
}
fileContentsBytes, err := ioutil.ReadAll(fRead)
if err != nil {
return "", errors.Wrapf(err, "failed to read existing aliases file")
}
defer fRead.Close()
newContents := getAddedAliasContents(string(fileContentsBytes), aliasEmail, to)
// Write new contents
fWrite, err := (*gitFs.fs).OpenFile(emailAliasesConfigFileRelative, os.O_WRONLY, 0644)
if err != nil {
return "", errors.Wrapf(err, "failed to open file where new email alias will be added")
}
defer fWrite.Close()
glog.Infof("writing new contents to file: %s", newContents)
fRead.Write([]byte(newContents))
if _, err = fWrite.Write([]byte(contents)); err != nil {
return "", errors.Wrapf(err, "failed to write config to file")
}
return aliasEmail, nil
}
func generateRandomEmail(fromDomain string) string {
return fmt.Sprintf("%s-%s-generated%s", strings.ToLower(gofakeit.Adverb()), strings.ToLower(gofakeit.FirstName()), fromDomain)
}
func getPostFixAlias(from, to string) string {
return fmt.Sprintf("%s %s", from, to)
}
func getAddedAliasContents(currentContents, from, to string) string {
glog.Infof("Existingcontent: %s", currentContents)
lines := strings.Split(currentContents, "\n")
newLines := []string{}
// If `to` already has an alias, overwrite it
for _, l := range lines {
if !strings.HasSuffix(l, to) {
newLines = append(newLines, l)
}
}
newLines = append(newLines, getPostFixAlias(from, to))
return strings.Join(newLines, "\n")
}

View file

@ -3,6 +3,8 @@ module viktorbarzin/infra/cli
go 1.16
require (
github.com/badoux/checkmail v1.2.1 // indirect
github.com/brianvoe/gofakeit/v6 v6.3.0 // indirect
github.com/go-git/go-billy/v5 v5.1.0 // indirect
github.com/go-git/go-git/v5 v5.3.0 // indirect
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect

View file

@ -4,6 +4,10 @@ github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugX
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/badoux/checkmail v1.2.1 h1:TzwYx5pnsV6anJweMx2auXdekBwGr/yt1GgalIx9nBQ=
github.com/badoux/checkmail v1.2.1/go.mod h1:XroCOBU5zzZJcLvgwU15I+2xXyCdTWXyR9MGfRhBYy0=
github.com/brianvoe/gofakeit/v6 v6.3.0 h1:h1M5XPubl81K+41Ry0g5P4Q9a7OCM8FgFf2Heey5j24=
github.com/brianvoe/gofakeit/v6 v6.3.0/go.mod h1:palrJUk4Fyw38zIFB/uBZqsgzW5VsNllhHKKwAebzew=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

View file

@ -42,6 +42,10 @@ func run() error {
// OpenWRT DNS flags
openWRTNewDNS := flag.String(setupOpenWRTNewDNSFlagName, "", fmt.Sprintf("New DNS server to set."))
// add email alias flags
emailToForwardTo := flag.String(emailAliasFlagName, "", "Email which is used to forward emails to.")
fromDomain := flag.String(fromEmailDomainFlagName, "@viktorbarzin.me", "Domain name which will receive emails. Example @viktorbarzin.me")
// Flag definitions above!
flag.Parse()
@ -115,6 +119,36 @@ func run() error {
if *printResultOnly {
println(fmt.Sprintf("Successfully set DNS server to '%s'", *openWRTNewDNS))
}
case addEmailAliasUseCase:
if *emailToForwardTo == "" {
return fmt.Errorf("%s must not be empty when using %s use case", emailAliasFlagName, addEmailAliasUseCase)
}
glog.Infof("Trying to add %s email alias", *emailToForwardTo)
gitFs, err := NewGitFS(repository)
if err != nil {
return errors.Wrapf(err, "failed to initialize git fs")
}
worktree, err := gitFs.repo.Worktree()
if err != nil {
return errors.Wrapf(err, "failed to get worktree")
}
emailAlias, err := addEmailAlias(gitFs, *emailToForwardTo, *fromDomain)
if err != nil {
return errors.Wrapf(err, "failed to add email alias")
}
glog.Infof("generated %s email alias", emailAlias)
// commit changes
if _, err = worktree.Commit("Added new email alias", &git.CommitOptions{All: true, Author: &object.Signature{Name: "Webhook Handler Bot"}}); err != nil {
return errors.Wrapf(err, "failed to commit")
}
if *printResultOnly {
fmt.Printf("Successfully created '%s' -> '%s' forwarding", emailAlias, *emailToForwardTo)
// println(ip)
}
if err = gitFs.Push(); err != nil {
return errors.Wrapf(err, "failed to push changes")
}
glog.Infof("successfully added %s -> %s email aliasing", emailAlias, *emailToForwardTo)
default:
err = errors.New(fmt.Sprintf("unsupported use case: %s", *useCase))
}

View file

@ -1,7 +1 @@
utterly-breana@viktorbarzin.me me@viktorbarzin.mee me@viktorbarzin.me' will point test@ -> me@
# Add aliases here. Example: 'test@viktorbarzin.me me@viktorbarzin.me' will point test@ -> me@
nonetheless-tyshawn@viktorbarzin.me me@viktorbarzin.menonetheless-tyshawn@viktorbarzin.me me@viktorbarzin.me# Add aliases here. Example: 'test@viktorbarzin.me me@viktorbarzin.me' will point test@ -> me@
# Add aliases here. Example: 'test@viktorbarzin.me me@viktorbarzin.me' will point test@ -> me@
instead-mertie@viktorbarzin.me me@viktorbarzin.meinstead-mertie@viktorbarzin.me me@viktorbarzin.me