pomerium/internal/autocert/storage_s3.go
dependabot[bot] c9df5156d4
chore(deps): bump github.com/aws/aws-sdk-go-v2 from 1.22.2 to 1.24.0 (#4840)
* chore(deps): bump github.com/aws/aws-sdk-go-v2 from 1.22.2 to 1.24.0

Bumps [github.com/aws/aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2) from 1.22.2 to 1.24.0.
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.22.2...v1.24.0)

---
updated-dependencies:
- dependency-name: github.com/aws/aws-sdk-go-v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* upgrade all aws deps

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Caleb Doxsey <cdoxsey@pomerium.com>
2023-12-28 08:40:54 -07:00

129 lines
2.9 KiB
Go

package autocert
import (
"bytes"
"context"
"errors"
"io"
"io/fs"
"sort"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/aws/aws-sdk-go-v2/service/s3/types"
"github.com/caddyserver/certmagic"
)
type s3Storage struct {
client *s3.Client
bucket string
prefix string
*locker
}
func newS3Storage(client *s3.Client, bucket, prefix string) *s3Storage {
s := &s3Storage{
client: client,
bucket: bucket,
prefix: prefix,
}
s.locker = &locker{
store: s.Store,
load: s.Load,
delete: s.Delete,
}
return s
}
func (s *s3Storage) Store(ctx context.Context, key string, value []byte) error {
_, err := s.client.PutObject(ctx, &s3.PutObjectInput{
Bucket: aws.String(s.bucket),
Key: aws.String(s.prefix + key),
Body: bytes.NewReader(value),
})
return err
}
func (s *s3Storage) Load(ctx context.Context, key string) ([]byte, error) {
output, err := s.client.GetObject(ctx, &s3.GetObjectInput{
Bucket: aws.String(s.bucket),
Key: aws.String(s.prefix + key),
})
var nsk *types.NoSuchKey
if err != nil && errors.As(err, &nsk) {
return nil, fs.ErrNotExist
} else if err != nil {
return nil, err
}
defer output.Body.Close()
return io.ReadAll(output.Body)
}
func (s *s3Storage) Delete(ctx context.Context, key string) error {
_, err := s.client.DeleteObject(ctx, &s3.DeleteObjectInput{
Bucket: aws.String(s.bucket),
Key: aws.String(s.prefix + key),
})
return err
}
func (s *s3Storage) Exists(ctx context.Context, key string) bool {
_, err := s.client.HeadObject(ctx, &s3.HeadObjectInput{
Bucket: aws.String(s.bucket),
Key: aws.String(s.prefix + key),
})
return err == nil
}
func (s *s3Storage) List(ctx context.Context, prefix string, recursive bool) ([]string, error) {
var delimiter *string
if !recursive {
delimiter = aws.String("/")
}
var keys []string
paginator := s3.NewListObjectsV2Paginator(s.client, &s3.ListObjectsV2Input{
Bucket: aws.String(s.bucket),
Prefix: aws.String(s.prefix + prefix),
Delimiter: delimiter,
})
for paginator.HasMorePages() {
output, err := paginator.NextPage(ctx)
if err != nil {
return nil, err
}
for _, commonPrefix := range output.CommonPrefixes {
keys = append(keys, (*commonPrefix.Prefix)[len(s.prefix):])
}
for _, object := range output.Contents {
keys = append(keys, (*object.Key)[len(s.prefix):])
}
}
sort.Strings(keys)
return keys, nil
}
func (s *s3Storage) Stat(ctx context.Context, key string) (certmagic.KeyInfo, error) {
output, err := s.client.HeadObject(ctx, &s3.HeadObjectInput{
Bucket: aws.String(s.bucket),
Key: aws.String(s.prefix + key),
})
if err != nil {
return certmagic.KeyInfo{}, err
}
var size int64
if output.ContentLength != nil {
size = *output.ContentLength
}
return certmagic.KeyInfo{
Key: key,
Modified: *output.LastModified,
Size: size,
IsTerminal: true,
}, nil
}