1
0
mirror of https://github.com/lus/pasty.git synced 2023-08-10 21:13:09 +03:00

Implement S3 storage driver

This commit is contained in:
Lukas SP
2020-08-23 23:44:47 +02:00
parent 8317fef5f7
commit 5149434cff
9 changed files with 175 additions and 24 deletions

7
internal/env/env.go vendored
View File

@@ -4,6 +4,7 @@ import (
"github.com/Lukaesebrot/pasty/internal/static"
"github.com/joho/godotenv"
"os"
"strconv"
)
// Load loads an optional .env file
@@ -19,3 +20,9 @@ func Get(key, fallback string) string {
}
return found
}
// Bool uses Get and parses it into a boolean
func Bool(key string, fallback bool) bool {
parsed, _ := strconv.ParseBool(Get(key, strconv.FormatBool(fallback)))
return parsed
}

View File

@@ -22,17 +22,25 @@ type Driver interface {
// Load loads the current storage driver
func Load() error {
// Define the driver to use
var driver Driver
storageType := strings.ToLower(env.Get("STORAGE_TYPE", "file"))
switch storageType {
case "file":
driver := new(FileDriver)
err := driver.Initialize()
if err != nil {
return err
}
Current = driver
return nil
driver = new(FileDriver)
break
case "s3":
driver = new(S3Driver)
break
default:
return fmt.Errorf("invalid storage type '%s'", storageType)
}
// Initialize the driver
err := driver.Initialize()
if err != nil {
return err
}
Current = driver
return nil
}

View File

@@ -26,7 +26,7 @@ func (driver *FileDriver) Terminate() error {
return nil
}
// Get loads a paste out of a file
// Get loads a paste
func (driver *FileDriver) Get(id snowflake.ID) (*pastes.Paste, error) {
// Read the file
data, err := ioutil.ReadFile(filepath.Join(driver.FilePath, id.String()+".json"))
@@ -46,7 +46,7 @@ func (driver *FileDriver) Get(id snowflake.ID) (*pastes.Paste, error) {
return paste, nil
}
// Save saves a paste into a file
// Save saves a paste
func (driver *FileDriver) Save(paste *pastes.Paste) error {
// Marshal the paste
jsonBytes, err := json.Marshal(paste)

View File

@@ -0,0 +1,81 @@
package storage
import (
"bytes"
"context"
"encoding/json"
"github.com/Lukaesebrot/pasty/internal/env"
"github.com/Lukaesebrot/pasty/internal/pastes"
"github.com/bwmarrin/snowflake"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
"io/ioutil"
)
// S3Driver represents the AWS S3 storage driver
type S3Driver struct {
Client *minio.Client
Bucket string
}
// Initialize initializes the AWS S3 storage driver
func (driver *S3Driver) Initialize() error {
client, err := minio.New(env.Get("STORAGE_S3_ENDPOINT", ""), &minio.Options{
Creds: credentials.NewStaticV4(env.Get("STORAGE_S3_ACCESS_KEY_ID", ""), env.Get("STORAGE_S3_SECRET_ACCESS_KEY", ""), env.Get("STORAGE_S3_SECRET_TOKEN", "")),
Secure: env.Bool("STORAGE_S3_SECURE", true),
Region: env.Get("STORAGE_S3_REGION", ""),
})
if err != nil {
return err
}
driver.Client = client
driver.Bucket = env.Get("STORAGE_S3_BUCKET", "pasty")
return nil
}
// Terminate terminates the AWS S3 storage driver
func (driver *S3Driver) Terminate() error {
return nil
}
// Get loads a paste
func (driver *S3Driver) Get(id snowflake.ID) (*pastes.Paste, error) {
// Read the object
object, err := driver.Client.GetObject(context.Background(), driver.Bucket, id.String()+".json", minio.GetObjectOptions{})
if err != nil {
return nil, err
}
data, err := ioutil.ReadAll(object)
if err != nil {
return nil, err
}
// Unmarshal the object into a paste
paste := new(pastes.Paste)
err = json.Unmarshal(data, &paste)
if err != nil {
return nil, err
}
return paste, nil
}
// Save saves a paste
func (driver *S3Driver) Save(paste *pastes.Paste) error {
// Marshal the paste
jsonBytes, err := json.Marshal(paste)
if err != nil {
return err
}
// Put the object
reader := bytes.NewReader(jsonBytes)
_, err = driver.Client.PutObject(context.Background(), driver.Bucket, paste.ID.String()+".json", reader, reader.Size(), minio.PutObjectOptions{
ContentType: "application/json",
})
return err
}
// Delete deletes a paste
func (driver *S3Driver) Delete(id snowflake.ID) error {
return driver.Client.RemoveObject(context.Background(), driver.Bucket, id.String()+".json", minio.RemoveObjectOptions{})
}

View File

@@ -60,7 +60,7 @@ func Serve() error {
}
// Route the hastebin documents route if hastebin support is enabled
if env.Get("HASTEBIN_SUPPORT", "false") == "true" {
if env.Bool("HASTEBIN_SUPPORT", false) {
router.POST("/documents", rateLimiterMiddleware.Handle(v1.HastebinSupportHandler))
}