Skip to content

Commit

Permalink
refactor: use bolt and file for defaults
Browse files Browse the repository at this point in the history
  • Loading branch information
ItsNotGoodName committed Jul 28, 2022
1 parent be13796 commit 661278b
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 36 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ npm-build:
$(NPM_PREFIX) npm run build

dev:
go run --tags dev . --watch
go run --tags dev . --watch --memory

snapshot: npm-build
goreleaser release --snapshot --rm-dist
45 changes: 29 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,51 +15,58 @@ Bridge email to other messaging services.
smtpbridge
```

## Configuration
Run with database and storage in memory.

Configuration file is located at `~/.smtpbridge.yml`.
```
smtpbridge --memory
```

Restart when config file changes.

```
smtpbridge --watch
```

## Config

### Starter Configuration
Config file is located at `~/.smtpbridge.yml`.

### Starter Config

This config prints emails received via SMTP to console.
The SMTP server listens on port `1025` and the HTTP server listens on port `8080`.
This saves emails to `~/.smtpbridge` directory.
The `database` and `storage` keys can be removed to run this entirely in memory.

```yaml
database:
type: bolt

storage:
type: directory

endpoints:
- name: hello world
type: console
```
### Full Configuration
### Full Config
```yaml
memory: false # Run with database and storage in memory

directory: ~/.smtpbridge # Default persistence directory

database: # Database
type: memory # (memory, bolt)
type: bolt # (bolt, memory)
memory:
limit: 100 # Max number of envelopes

storage: # Storage for attachment's data
type: memory # (memory, directory)
storage: # Storage
type: file # (file, memory)
memory:
size: 104857600 # Max memory allocation in bytes, 100 MiB

http: # HTTP server
enable: true # (true, false)
disable: true # (false, true)
host: ""
port: 8080

smtp: # SMTP server
enable: true # (true, false)
disable: false # (false, true)
host: ""
port: 1025
size: 26214400 # Max message size in bytes, 25 MiB
Expand Down Expand Up @@ -106,7 +113,13 @@ bridges: # Bridges to endpoints, if this is empty then envelopes will always be
- console endpoint
```
### Template
Each template has access to the [`Envelope`](./core/envelope/envelope.go) struct.
See [`text/template`](https://pkg.go.dev/text/template) on how to template.

## To Do

- Read mail files
- Save raw emails
- Windows installer
6 changes: 6 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ func init() {

watch = rootCmd.Flags().Bool("watch", false, "restart when config file changes")

rootCmd.Flags().Bool("memory", serverConfig.Memory, "run with database and storage in memory")
viper.BindPFlag("memory", rootCmd.Flags().Lookup("memory"))

rootCmd.Flags().String("directory", serverConfig.Directory, "persistence directory")
viper.BindPFlag("directory", rootCmd.Flags().Lookup("directory"))

rootCmd.Flags().Bool("http-disable", serverConfig.HTTP.Disable, "disable http server")
viper.BindPFlag("http.disable", rootCmd.Flags().Lookup("http-disable"))

Expand Down
19 changes: 13 additions & 6 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
)

type Config struct {
Memory bool `json:"memory" mapstructure:"memory"`
Directory string `json:"directory" mapstructure:"directory"`
Database Database `json:"database" mapstructure:"database"`
Storage Storage `json:"storage" mapstructure:"storage"`
Expand All @@ -28,13 +29,13 @@ func New() *Config {
return &Config{
Directory: directory,
Database: Database{
Type: "memory",
Type: DatabaseTypeBolt,
Memory: DatabaseMemory{
Limit: 100,
},
},
Storage: Storage{
Type: "memory",
Type: StorageTypeFile,
Memory: StorageMemory{
Size: 1024 * 1024 * 100, // 100 MiB
},
Expand Down Expand Up @@ -75,10 +76,16 @@ SUBJECT: {{ .Message.Subject }}
}
}

// Directory
c.Storage.Directory.Path = path.Join(c.Directory, "data")
if c.Storage.IsDirectory() {
mustCreatePath(c.Storage.Directory.Path)
// Override database and storage
if c.Memory {
c.Database.Type = DatabaseTypeMemory
c.Storage.Type = StorageTypeMemory
}

// File
c.Storage.File.Path = path.Join(c.Directory, "attachments")
if c.Storage.IsFile() {
mustCreatePath(c.Storage.File.Path)
}

// Bolt
Expand Down
13 changes: 10 additions & 3 deletions config/database.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
package config

type Database struct {
Type string `json:"type" mapstructure:"type"`
Type DatabaseType `json:"type" mapstructure:"type"`
Memory DatabaseMemory `json:"memory" mapstructure:"memory"`
Bolt DatabaseBolt `json:"bolt" mapstructure:"bolt"`
}

type DatabaseType string

const (
DatabaseTypeBolt = "bolt"
DatabaseTypeMemory = "memory"
)

type DatabaseMemory struct {
Limit int64 `json:"limit" mapstructure:"limit"`
}
Expand All @@ -15,9 +22,9 @@ type DatabaseBolt struct {
}

func (d Database) IsMemory() bool {
return d.Type == "memory"
return d.Type == DatabaseTypeMemory
}

func (d Database) IsBolt() bool {
return d.Type == "bolt"
return d.Type == DatabaseTypeBolt
}
23 changes: 15 additions & 8 deletions config/storage.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
package config

type Storage struct {
Type string `json:"type" mapstructure:"type"`
Memory StorageMemory `json:"memory" mapstructure:"memory"`
Directory StorageDirectory `json:"directory" mapstructure:"directory"`
Type StorageType `json:"type" mapstructure:"type"`
Memory StorageMemory `json:"memory" mapstructure:"memory"`
File StorageFile `json:"file" mapstructure:"file"`
}

func (s Storage) IsMemory() bool {
return s.Type == "memory"
type StorageType string

const (
StorageTypeFile StorageType = "file"
StorageTypeMemory StorageType = "memory"
)

func (s Storage) IsFile() bool {
return s.Type == StorageTypeFile
}

func (s Storage) IsDirectory() bool {
return s.Type == "directory"
func (s Storage) IsMemory() bool {
return s.Type == StorageTypeMemory
}

type StorageMemory struct {
Size int64 `json:"size" mapstructure:"size"`
}

type StorageDirectory struct {
type StorageFile struct {
Path string `json:"-" mapstructure:"-"`
}
6 changes: 4 additions & 2 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ func Start(ctx context.Context, config *config.Config) <-chan struct{} {
var dataStore envelope.DataStore
if config.Storage.IsMemory() {
dataStore = memdb.NewData(config.Storage.Memory.Size)
} else if config.Storage.IsDirectory() {
dataStore = filedb.NewData(config.Storage.Directory.Path)
} else if config.Storage.IsFile() {
dataStore = filedb.NewData(config.Storage.File.Path)
} else {
log.Fatalln("server.Start: storage invalid:", config.Storage.Type)
}
Expand Down Expand Up @@ -70,6 +70,8 @@ func Start(ctx context.Context, config *config.Config) <-chan struct{} {
}); err != nil {
log.Fatalf("server.Start: endpoint '%s': %s", end.Name, err)
}

log.Printf("server.Start: created endpoint '%s'", end.Name)
}

// Create bridges from config
Expand Down

0 comments on commit 661278b

Please sign in to comment.