Upgrade minio-go to version 7

This commit is contained in:
Lena Fuhrimann 2021-08-05 11:44:40 +02:00
parent 07c0c2d9f7
commit 2499415fea
24 changed files with 274 additions and 206 deletions

View file

@ -18,4 +18,4 @@ jobs:
with:
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"

6
.gitignore vendored
View file

@ -1,14 +1,16 @@
# Binaries for programs and plugins
bin/
dist/
*.exe
*.exe~
*.dll
*.so
*.dylib
bin/
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/

View file

@ -14,15 +14,10 @@ lint:
test:
go test -race -cover ./...
.PHONY: build-docker
build-docker:
.PHONY: build-image
build-image:
docker build -t s3manager .
.PHONY: deploy-cf
deploy-cf:
GOOS=linux go build -ldflags="-s -w" -o bin/s3manager
cf push -f deployments/cf/manifest.yml
.PHONY: clean
clean:
rm -rf bin

View file

@ -15,6 +15,7 @@ A Web GUI written in Go to manage S3 buckets from any provider.
The application can be configured with the following environment variables:
- `ENDPOINT`: The endpoint of your S3 server (defaults to `s3.amazonaws.com`)
- `REGION`: The region of your S3 server (defaults to `""`)
- `ACCESS_KEY_ID`: Your S3 access key ID (required)
- `SECRET_ACCESS_KEY`: Your S3 secret access key (required)
- `USE_SSL`: Whether your S3 server uses SSL or not (defaults to `true`)
@ -26,15 +27,10 @@ The application can be configured with the following environment variables:
1. Run `make build`
1. Execute the created binary and visit <http://localhost:8080>
### Run Docker image
### Run Container image
1. Run `docker run -p 8080:8080 -e 'ACCESS_KEY_ID=XXX' -e 'SECRET_ACCESS_KEY=xxx' mastertinner/s3manager`
### Deploy to Cloud Foundry
1. Modify `deployments/cf/*` to your liking
1. Run `make deploy-cf`
## Development
### Lint Code
@ -45,11 +41,11 @@ The application can be configured with the following environment variables:
1. Run `make test`
### Build Docker Image
### Build Container Image
The image is available on [Docker Hub](https://hub.docker.com/r/mastertinner/s3manager/)
1. Run `make build-docker`
1. Run `make build-image`
### Run Locally for Testing

View file

@ -1,26 +0,0 @@
#!/bin/bash
set -e -u
if [ -z "${PORT}" ]; then
echo "Error: No PORT found" >&2
exit 1
fi
if [ -z "${VCAP_SERVICES}" ]; then
echo "Error: No VCAP_SERVICES found" >&2
exit 1
fi
# S3
s3_credentials="$(echo "${VCAP_SERVICES}" | jq -r '.["dynstrg"][0].credentials // ""')"
if [ -z "${s3_credentials}" ]; then
echo "Error: Please bind an S3 service" >&2
exit 1
fi
s3_endpoint="$(echo "${s3_credentials}" | jq -r '.accessHost // ""')"
s3_endpoint="${s3_endpoint#'https://'}"
s3_access_key_id="$(echo "${s3_credentials}" | jq -r '.accessKey // ""')"
s3_secret_access_key="$(echo "${s3_credentials}" | jq -r '.sharedSecret // ""')"
# Run binary
ENDPOINT="${s3_endpoint}" ACCESS_KEY_ID="${s3_access_key_id}" SECRET_ACCESS_KEY="${s3_secret_access_key}" ./s3manager

View file

@ -1,8 +0,0 @@
applications:
- name: s3-manager
buildpacks:
- https://github.com/cloudfoundry/binary-buildpack.git
memory: 64M
command: ./deployments/cf/entrypoint.sh
services:
- my-storage

20
go.mod
View file

@ -3,15 +3,23 @@ module github.com/mastertinner/s3manager
go 1.16
require (
github.com/go-ini/ini v1.62.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gopherjs/gopherjs v0.0.0-20210803090616-8f023c250c89 // indirect
github.com/mastertinner/adapters v0.0.0-20210601115127-f9c5f1df5ec2
github.com/json-iterator/go v1.1.11 // indirect
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
github.com/mastertinner/adapters v0.0.0-20210813140839-f946b3f928f1
github.com/matryer/is v1.4.0
github.com/matryer/way v0.0.0-20180416093233-9632d0c407b0
github.com/minio/minio-go v6.0.14+incompatible
github.com/minio/md5-simd v1.1.2 // indirect
github.com/minio/minio-go/v7 v7.0.12
github.com/minio/sha256-simd v1.0.0 // indirect
github.com/rs/xid v1.3.0 // indirect
github.com/smartystreets/assertions v1.2.0 // indirect
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985 // indirect
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
github.com/stretchr/testify v1.7.0 // indirect
golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e // indirect
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect
golang.org/x/sys v0.0.0-20210817133320-13f9c583af74 // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)

70
go.sum
View file

@ -58,9 +58,12 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@ -72,14 +75,13 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-ini/ini v1.62.0 h1:7VJT/ZXjzqSrvtraFp4ONq80hTcRQth1c9ZnQ3uNQvU=
github.com/go-ini/ini v1.62.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@ -116,6 +118,7 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
@ -126,6 +129,9 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
@ -159,6 +165,9 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
@ -166,14 +175,21 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s=
github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4=
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mastertinner/adapters v0.0.0-20210601115127-f9c5f1df5ec2 h1:1xj8GPMA06VxvfKVUa3W1za7/eODStJG3lYWIYqypTo=
github.com/mastertinner/adapters v0.0.0-20210601115127-f9c5f1df5ec2/go.mod h1:CLHlHgTXdyVYGucevVppiRddQVtVop2ORWbgSXObP0I=
github.com/mastertinner/adapters v0.0.0-20210813140839-f946b3f928f1 h1:ZPvesDqKoVIeQFkfikuck4ILJTFUrRv5wV36bzSBQs8=
github.com/mastertinner/adapters v0.0.0-20210813140839-f946b3f928f1/go.mod h1:2wARZp3HPycyJvAbmX3k6ufim3fpiEJLqGUmNYuVUHA=
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
github.com/matryer/way v0.0.0-20180416093233-9632d0c407b0 h1:KWiqy3hl8yCUPAq1frD0DKXKyn7d9h2nVhj2r5ISq2o=
@ -182,8 +198,14 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/minio/minio-go v6.0.14+incompatible h1:fnV+GD28LeqdN6vT2XdGKW8Qe/IfjJDswNVuni6km9o=
github.com/minio/minio-go v6.0.14+incompatible/go.mod h1:7guKYtitv8dktvNUGrhzmNlA5wrAABTQXCoesZdFQO8=
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
github.com/minio/minio-go/v7 v7.0.12 h1:/4pxUdwn9w0QEryNkrrWaodIESPRX+NxpO0Q6hVdaAA=
github.com/minio/minio-go/v7 v7.0.12/go.mod h1:S23iSP5/gbMwtxeY5FM71R+TkAYyzEdoNEDDwpt8yWs=
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
@ -193,7 +215,11 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
@ -203,6 +229,7 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@ -217,6 +244,9 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/xid v1.3.0 h1:6NjYksEUlhurdVehpc7S7dk6DAmcKv8V9gG0FsVN2U4=
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
@ -225,6 +255,8 @@ github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJ
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
@ -244,6 +276,8 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
@ -267,9 +301,10 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e h1:VvfwVmMH40bpMeizC9/K7ipM5Qjucuu16RWfneFPyhQ=
golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -332,8 +367,8 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985 h1:4CSI6oo7cOjJKajidEljs9h+uP0rRZBPPPhcCbj5mw8=
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c=
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -366,6 +401,7 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -380,6 +416,7 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -387,16 +424,18 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210817133320-13f9c583af74 h1:b3RvH1NpRl6xu9OF46sZVLhjgJ0G7DteZbCC5zFknyY=
golang.org/x/sys v0.0.0-20210817133320-13f9c583af74/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -527,6 +566,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
@ -534,7 +574,11 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View file

@ -8,7 +8,7 @@ import (
"path"
"github.com/matryer/way"
minio "github.com/minio/minio-go"
"github.com/minio/minio-go/v7"
)
// HandleBucketView shows the details page of a bucket.
@ -29,7 +29,7 @@ func HandleBucketView(s3 S3, templates fs.FS) http.HandlerFunc {
var objs []objectWithIcon
doneCh := make(chan struct{})
defer close(doneCh)
objectCh := s3.ListObjectsV2(bucketName, "", true, doneCh)
objectCh := s3.ListObjects(r.Context(), bucketName, minio.ListObjectsOptions{})
for object := range objectCh {
if object.Err != nil {
handleHTTPError(w, fmt.Errorf("error listing objects: %w", object.Err))

View file

@ -1,6 +1,7 @@
package s3manager_test
import (
"context"
"fmt"
"io"
"net/http"
@ -14,7 +15,7 @@ import (
"github.com/mastertinner/s3manager/internal/app/s3manager/mocks"
"github.com/matryer/is"
"github.com/matryer/way"
minio "github.com/minio/minio-go"
"github.com/minio/minio-go/v7"
)
func TestHandleBucketView(t *testing.T) {
@ -22,14 +23,14 @@ func TestHandleBucketView(t *testing.T) {
cases := []struct {
it string
listObjectsV2Func func(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo
listObjectsFunc func(context.Context, string, minio.ListObjectsOptions) <-chan minio.ObjectInfo
bucketName string
expectedStatusCode int
expectedBodyContains string
}{
{
it: "renders a bucket containing a file",
listObjectsV2Func: func(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo {
listObjectsFunc: func(context.Context, string, minio.ListObjectsOptions) <-chan minio.ObjectInfo {
objCh := make(chan minio.ObjectInfo)
go func() {
objCh <- minio.ObjectInfo{Key: "testFile"}
@ -43,7 +44,7 @@ func TestHandleBucketView(t *testing.T) {
},
{
it: "renders placeholder for an empty bucket",
listObjectsV2Func: func(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo {
listObjectsFunc: func(context.Context, string, minio.ListObjectsOptions) <-chan minio.ObjectInfo {
objCh := make(chan minio.ObjectInfo)
close(objCh)
return objCh
@ -54,7 +55,7 @@ func TestHandleBucketView(t *testing.T) {
},
{
it: "renders a bucket containing an archive",
listObjectsV2Func: func(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo {
listObjectsFunc: func(context.Context, string, minio.ListObjectsOptions) <-chan minio.ObjectInfo {
objCh := make(chan minio.ObjectInfo)
go func() {
objCh <- minio.ObjectInfo{Key: "archive.tar.gz"}
@ -68,7 +69,7 @@ func TestHandleBucketView(t *testing.T) {
},
{
it: "renders a bucket containing an image",
listObjectsV2Func: func(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo {
listObjectsFunc: func(context.Context, string, minio.ListObjectsOptions) <-chan minio.ObjectInfo {
objCh := make(chan minio.ObjectInfo)
go func() {
objCh <- minio.ObjectInfo{Key: "testImage.png"}
@ -82,7 +83,7 @@ func TestHandleBucketView(t *testing.T) {
},
{
it: "renders a bucket containing a sound file",
listObjectsV2Func: func(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo {
listObjectsFunc: func(context.Context, string, minio.ListObjectsOptions) <-chan minio.ObjectInfo {
objCh := make(chan minio.ObjectInfo)
go func() {
objCh <- minio.ObjectInfo{Key: "testSound.mp3"}
@ -96,7 +97,7 @@ func TestHandleBucketView(t *testing.T) {
},
{
it: "returns error if the bucket doesn't exist",
listObjectsV2Func: func(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo {
listObjectsFunc: func(context.Context, string, minio.ListObjectsOptions) <-chan minio.ObjectInfo {
objCh := make(chan minio.ObjectInfo)
go func() {
objCh <- minio.ObjectInfo{Err: errBucketDoesNotExist}
@ -110,7 +111,7 @@ func TestHandleBucketView(t *testing.T) {
},
{
it: "returns error if there is an S3 error",
listObjectsV2Func: func(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo {
listObjectsFunc: func(context.Context, string, minio.ListObjectsOptions) <-chan minio.ObjectInfo {
objCh := make(chan minio.ObjectInfo)
go func() {
objCh <- minio.ObjectInfo{Err: errS3}
@ -131,7 +132,7 @@ func TestHandleBucketView(t *testing.T) {
is := is.New(t)
s3 := &mocks.S3Mock{
ListObjectsV2Func: tc.listObjectsV2Func,
ListObjectsFunc: tc.listObjectsFunc,
}
templates := os.DirFS(filepath.Join("..", "..", "..", "web", "template"))

View file

@ -9,8 +9,8 @@ import (
// HandleBucketsView renders all buckets on an HTML page.
func HandleBucketsView(s3 S3, templates fs.FS) http.HandlerFunc {
return func(w http.ResponseWriter, _ *http.Request) {
buckets, err := s3.ListBuckets()
return func(w http.ResponseWriter, r *http.Request) {
buckets, err := s3.ListBuckets(r.Context())
if err != nil {
handleHTTPError(w, fmt.Errorf("error listing buckets: %w", err))
return

View file

@ -1,6 +1,7 @@
package s3manager_test
import (
"context"
"io"
"net/http"
"net/http/httptest"
@ -12,7 +13,7 @@ import (
"github.com/mastertinner/s3manager/internal/app/s3manager"
"github.com/mastertinner/s3manager/internal/app/s3manager/mocks"
"github.com/matryer/is"
minio "github.com/minio/minio-go"
"github.com/minio/minio-go/v7"
)
func TestHandleBucketsView(t *testing.T) {
@ -20,13 +21,13 @@ func TestHandleBucketsView(t *testing.T) {
cases := []struct {
it string
listBucketsFunc func() ([]minio.BucketInfo, error)
listBucketsFunc func(context.Context) ([]minio.BucketInfo, error)
expectedStatusCode int
expectedBodyContains string
}{
{
it: "renders a list of buckets",
listBucketsFunc: func() ([]minio.BucketInfo, error) {
listBucketsFunc: func(context.Context) ([]minio.BucketInfo, error) {
return []minio.BucketInfo{{Name: "testBucket"}}, nil
},
expectedStatusCode: http.StatusOK,
@ -34,7 +35,7 @@ func TestHandleBucketsView(t *testing.T) {
},
{
it: "renders placeholder if no buckets",
listBucketsFunc: func() ([]minio.BucketInfo, error) {
listBucketsFunc: func(context.Context) ([]minio.BucketInfo, error) {
return []minio.BucketInfo{}, nil
},
expectedStatusCode: http.StatusOK,
@ -42,7 +43,7 @@ func TestHandleBucketsView(t *testing.T) {
},
{
it: "returns error if there is an S3 error",
listBucketsFunc: func() ([]minio.BucketInfo, error) {
listBucketsFunc: func(context.Context) ([]minio.BucketInfo, error) {
return []minio.BucketInfo{}, errS3
},
expectedStatusCode: http.StatusInternalServerError,

View file

@ -5,7 +5,7 @@ import (
"fmt"
"net/http"
minio "github.com/minio/minio-go"
"github.com/minio/minio-go/v7"
)
// HandleCreateBucket creates a new bucket.
@ -18,7 +18,7 @@ func HandleCreateBucket(s3 S3) http.HandlerFunc {
return
}
err = s3.MakeBucket(bucket.Name, "")
err = s3.MakeBucket(r.Context(), bucket.Name, minio.MakeBucketOptions{})
if err != nil {
handleHTTPError(w, fmt.Errorf("error making bucket: %w", err))
return

View file

@ -2,6 +2,7 @@ package s3manager_test
import (
"bytes"
"context"
"io"
"net/http"
"net/http/httptest"
@ -11,6 +12,7 @@ import (
"github.com/mastertinner/s3manager/internal/app/s3manager"
"github.com/mastertinner/s3manager/internal/app/s3manager/mocks"
"github.com/matryer/is"
"github.com/minio/minio-go/v7"
)
func TestHandleCreateBucket(t *testing.T) {
@ -18,14 +20,14 @@ func TestHandleCreateBucket(t *testing.T) {
cases := []struct {
it string
makeBucketFunc func(string, string) error
makeBucketFunc func(context.Context, string, minio.MakeBucketOptions) error
body string
expectedStatusCode int
expectedBodyContains string
}{
{
it: "creates a new bucket",
makeBucketFunc: func(string, string) error {
makeBucketFunc: func(context.Context, string, minio.MakeBucketOptions) error {
return nil
},
body: `{"name":"myBucket"}`,
@ -34,7 +36,7 @@ func TestHandleCreateBucket(t *testing.T) {
},
{
it: "returns error for empty request",
makeBucketFunc: func(string, string) error {
makeBucketFunc: func(context.Context, string, minio.MakeBucketOptions) error {
return nil
},
body: "",
@ -43,7 +45,7 @@ func TestHandleCreateBucket(t *testing.T) {
},
{
it: "returns error for malformed request",
makeBucketFunc: func(string, string) error {
makeBucketFunc: func(context.Context, string, minio.MakeBucketOptions) error {
return nil
},
body: "}",
@ -52,7 +54,7 @@ func TestHandleCreateBucket(t *testing.T) {
},
{
it: "returns error if there is an S3 error",
makeBucketFunc: func(string, string) error {
makeBucketFunc: func(context.Context, string, minio.MakeBucketOptions) error {
return errS3
},
body: `{"name":"myBucket"}`,

View file

@ -5,7 +5,7 @@ import (
"net/http"
"github.com/matryer/way"
minio "github.com/minio/minio-go"
"github.com/minio/minio-go/v7"
)
// HandleCreateObject uploads a new object.
@ -26,7 +26,7 @@ func HandleCreateObject(s3 S3) http.HandlerFunc {
defer file.Close()
opts := minio.PutObjectOptions{ContentType: "application/octet-stream"}
_, err = s3.PutObject(bucketName, header.Filename, file, -1, opts)
_, err = s3.PutObject(r.Context(), bucketName, header.Filename, file, -1, opts)
if err != nil {
handleHTTPError(w, fmt.Errorf("error putting object: %w", err))
return

View file

@ -12,7 +12,7 @@ func HandleDeleteBucket(s3 S3) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
bucketName := way.Param(r.Context(), "bucketName")
err := s3.RemoveBucket(bucketName)
err := s3.RemoveBucket(r.Context(), bucketName)
if err != nil {
handleHTTPError(w, fmt.Errorf("error removing bucket: %w", err))
return

View file

@ -1,6 +1,7 @@
package s3manager_test
import (
"context"
"io"
"net/http"
"net/http/httptest"
@ -17,13 +18,13 @@ func TestHandleDeleteBucket(t *testing.T) {
cases := []struct {
it string
removeBucketFunc func(string) error
removeBucketFunc func(context.Context, string) error
expectedStatusCode int
expectedBodyContains string
}{
{
it: "deletes an existing bucket",
removeBucketFunc: func(string) error {
removeBucketFunc: func(context.Context, string) error {
return nil
},
expectedStatusCode: http.StatusNoContent,
@ -31,7 +32,7 @@ func TestHandleDeleteBucket(t *testing.T) {
},
{
it: "returns error if there is an S3 error",
removeBucketFunc: func(string) error {
removeBucketFunc: func(context.Context, string) error {
return errS3
},
expectedStatusCode: http.StatusInternalServerError,

View file

@ -5,6 +5,7 @@ import (
"net/http"
"github.com/matryer/way"
"github.com/minio/minio-go/v7"
)
// HandleDeleteObject deletes an object.
@ -13,7 +14,7 @@ func HandleDeleteObject(s3 S3) http.HandlerFunc {
bucketName := way.Param(r.Context(), "bucketName")
objectName := way.Param(r.Context(), "objectName")
err := s3.RemoveObject(bucketName, objectName)
err := s3.RemoveObject(r.Context(), bucketName, objectName, minio.RemoveObjectOptions{})
if err != nil {
handleHTTPError(w, fmt.Errorf("error removing object: %w", err))
return

View file

@ -1,6 +1,7 @@
package s3manager_test
import (
"context"
"net/http"
"net/http/httptest"
"strings"
@ -9,6 +10,7 @@ import (
"github.com/mastertinner/s3manager/internal/app/s3manager"
"github.com/mastertinner/s3manager/internal/app/s3manager/mocks"
"github.com/matryer/is"
"github.com/minio/minio-go/v7"
)
func TestHandleDeleteObject(t *testing.T) {
@ -16,13 +18,13 @@ func TestHandleDeleteObject(t *testing.T) {
cases := []struct {
it string
removeObjectFunc func(string, string) error
removeObjectFunc func(context.Context, string, string, minio.RemoveObjectOptions) error
expectedStatusCode int
expectedBodyContains string
}{
{
it: "deletes an existing object",
removeObjectFunc: func(string, string) error {
removeObjectFunc: func(context.Context, string, string, minio.RemoveObjectOptions) error {
return nil
},
expectedStatusCode: http.StatusNoContent,
@ -30,7 +32,7 @@ func TestHandleDeleteObject(t *testing.T) {
},
{
it: "returns error if there is an S3 error",
removeObjectFunc: func(string, string) error {
removeObjectFunc: func(context.Context, string, string, minio.RemoveObjectOptions) error {
return errS3
},
expectedStatusCode: http.StatusInternalServerError,

View file

@ -6,7 +6,7 @@ import (
"net/http"
"github.com/matryer/way"
minio "github.com/minio/minio-go"
"github.com/minio/minio-go/v7"
)
// HandleGetObject downloads an object to the client.
@ -15,7 +15,7 @@ func HandleGetObject(s3 S3) http.HandlerFunc {
bucketName := way.Param(r.Context(), "bucketName")
objectName := way.Param(r.Context(), "objectName")
object, err := s3.GetObject(bucketName, objectName, minio.GetObjectOptions{})
object, err := s3.GetObject(r.Context(), bucketName, objectName, minio.GetObjectOptions{})
if err != nil {
handleHTTPError(w, fmt.Errorf("error getting object: %w", err))
return

View file

@ -1,6 +1,7 @@
package s3manager_test
import (
"context"
"fmt"
"io"
"net/http"
@ -12,7 +13,7 @@ import (
"github.com/mastertinner/s3manager/internal/app/s3manager/mocks"
"github.com/matryer/is"
"github.com/matryer/way"
minio "github.com/minio/minio-go"
"github.com/minio/minio-go/v7"
)
func TestHandleGetObject(t *testing.T) {
@ -20,7 +21,7 @@ func TestHandleGetObject(t *testing.T) {
cases := []struct {
it string
getObjectFunc func(string, string, minio.GetObjectOptions) (*minio.Object, error)
getObjectFunc func(context.Context, string, string, minio.GetObjectOptions) (*minio.Object, error)
bucketName string
objectName string
expectedStatusCode int
@ -28,7 +29,7 @@ func TestHandleGetObject(t *testing.T) {
}{
{
it: "returns error if there is an S3 error",
getObjectFunc: func(string, string, minio.GetObjectOptions) (*minio.Object, error) {
getObjectFunc: func(context.Context, string, string, minio.GetObjectOptions) (*minio.Object, error) {
return nil, errS3
},
bucketName: "testBucket",

View file

@ -4,8 +4,9 @@
package mocks
import (
"context"
"github.com/mastertinner/s3manager/internal/app/s3manager"
minio "github.com/minio/minio-go"
"github.com/minio/minio-go/v7"
"io"
"sync"
)
@ -20,25 +21,25 @@ var _ s3manager.S3 = &S3Mock{}
//
// // make and configure a mocked s3manager.S3
// mockedS3 := &S3Mock{
// GetObjectFunc: func(bucketName string, objectName string, opts minio.GetObjectOptions) (*minio.Object, error) {
// GetObjectFunc: func(ctx context.Context, bucketName string, objectName string, opts minio.GetObjectOptions) (*minio.Object, error) {
// panic("mock out the GetObject method")
// },
// ListBucketsFunc: func() ([]minio.BucketInfo, error) {
// ListBucketsFunc: func(ctx context.Context) ([]minio.BucketInfo, error) {
// panic("mock out the ListBuckets method")
// },
// ListObjectsV2Func: func(bucketName string, objectPrefix string, recursive bool, doneCh <-chan struct{}) <-chan minio.ObjectInfo {
// panic("mock out the ListObjectsV2 method")
// ListObjectsFunc: func(ctx context.Context, bucketName string, opts minio.ListObjectsOptions) <-chan minio.ObjectInfo {
// panic("mock out the ListObjects method")
// },
// MakeBucketFunc: func(bucketName string, location string) error {
// MakeBucketFunc: func(ctx context.Context, bucketName string, opts minio.MakeBucketOptions) error {
// panic("mock out the MakeBucket method")
// },
// PutObjectFunc: func(bucketName string, objectName string, reader io.Reader, objectSize int64, opts minio.PutObjectOptions) (int64, error) {
// PutObjectFunc: func(ctx context.Context, bucketName string, objectName string, reader io.Reader, objectSize int64, opts minio.PutObjectOptions) (minio.UploadInfo, error) {
// panic("mock out the PutObject method")
// },
// RemoveBucketFunc: func(bucketName string) error {
// RemoveBucketFunc: func(ctx context.Context, bucketName string) error {
// panic("mock out the RemoveBucket method")
// },
// RemoveObjectFunc: func(bucketName string, objectName string) error {
// RemoveObjectFunc: func(ctx context.Context, bucketName string, objectName string, opts minio.RemoveObjectOptions) error {
// panic("mock out the RemoveObject method")
// },
// }
@ -49,30 +50,32 @@ var _ s3manager.S3 = &S3Mock{}
// }
type S3Mock struct {
// GetObjectFunc mocks the GetObject method.
GetObjectFunc func(bucketName string, objectName string, opts minio.GetObjectOptions) (*minio.Object, error)
GetObjectFunc func(ctx context.Context, bucketName string, objectName string, opts minio.GetObjectOptions) (*minio.Object, error)
// ListBucketsFunc mocks the ListBuckets method.
ListBucketsFunc func() ([]minio.BucketInfo, error)
ListBucketsFunc func(ctx context.Context) ([]minio.BucketInfo, error)
// ListObjectsV2Func mocks the ListObjectsV2 method.
ListObjectsV2Func func(bucketName string, objectPrefix string, recursive bool, doneCh <-chan struct{}) <-chan minio.ObjectInfo
// ListObjectsFunc mocks the ListObjects method.
ListObjectsFunc func(ctx context.Context, bucketName string, opts minio.ListObjectsOptions) <-chan minio.ObjectInfo
// MakeBucketFunc mocks the MakeBucket method.
MakeBucketFunc func(bucketName string, location string) error
MakeBucketFunc func(ctx context.Context, bucketName string, opts minio.MakeBucketOptions) error
// PutObjectFunc mocks the PutObject method.
PutObjectFunc func(bucketName string, objectName string, reader io.Reader, objectSize int64, opts minio.PutObjectOptions) (int64, error)
PutObjectFunc func(ctx context.Context, bucketName string, objectName string, reader io.Reader, objectSize int64, opts minio.PutObjectOptions) (minio.UploadInfo, error)
// RemoveBucketFunc mocks the RemoveBucket method.
RemoveBucketFunc func(bucketName string) error
RemoveBucketFunc func(ctx context.Context, bucketName string) error
// RemoveObjectFunc mocks the RemoveObject method.
RemoveObjectFunc func(bucketName string, objectName string) error
RemoveObjectFunc func(ctx context.Context, bucketName string, objectName string, opts minio.RemoveObjectOptions) error
// calls tracks calls to the methods.
calls struct {
// GetObject holds details about calls to the GetObject method.
GetObject []struct {
// Ctx is the ctx argument value.
Ctx context.Context
// BucketName is the bucketName argument value.
BucketName string
// ObjectName is the objectName argument value.
@ -82,27 +85,31 @@ type S3Mock struct {
}
// ListBuckets holds details about calls to the ListBuckets method.
ListBuckets []struct {
// Ctx is the ctx argument value.
Ctx context.Context
}
// ListObjectsV2 holds details about calls to the ListObjectsV2 method.
ListObjectsV2 []struct {
// ListObjects holds details about calls to the ListObjects method.
ListObjects []struct {
// Ctx is the ctx argument value.
Ctx context.Context
// BucketName is the bucketName argument value.
BucketName string
// ObjectPrefix is the objectPrefix argument value.
ObjectPrefix string
// Recursive is the recursive argument value.
Recursive bool
// DoneCh is the doneCh argument value.
DoneCh <-chan struct{}
// Opts is the opts argument value.
Opts minio.ListObjectsOptions
}
// MakeBucket holds details about calls to the MakeBucket method.
MakeBucket []struct {
// Ctx is the ctx argument value.
Ctx context.Context
// BucketName is the bucketName argument value.
BucketName string
// Location is the location argument value.
Location string
// Opts is the opts argument value.
Opts minio.MakeBucketOptions
}
// PutObject holds details about calls to the PutObject method.
PutObject []struct {
// Ctx is the ctx argument value.
Ctx context.Context
// BucketName is the bucketName argument value.
BucketName string
// ObjectName is the objectName argument value.
@ -116,36 +123,44 @@ type S3Mock struct {
}
// RemoveBucket holds details about calls to the RemoveBucket method.
RemoveBucket []struct {
// Ctx is the ctx argument value.
Ctx context.Context
// BucketName is the bucketName argument value.
BucketName string
}
// RemoveObject holds details about calls to the RemoveObject method.
RemoveObject []struct {
// Ctx is the ctx argument value.
Ctx context.Context
// BucketName is the bucketName argument value.
BucketName string
// ObjectName is the objectName argument value.
ObjectName string
// Opts is the opts argument value.
Opts minio.RemoveObjectOptions
}
}
lockGetObject sync.RWMutex
lockListBuckets sync.RWMutex
lockListObjectsV2 sync.RWMutex
lockMakeBucket sync.RWMutex
lockPutObject sync.RWMutex
lockRemoveBucket sync.RWMutex
lockRemoveObject sync.RWMutex
lockGetObject sync.RWMutex
lockListBuckets sync.RWMutex
lockListObjects sync.RWMutex
lockMakeBucket sync.RWMutex
lockPutObject sync.RWMutex
lockRemoveBucket sync.RWMutex
lockRemoveObject sync.RWMutex
}
// GetObject calls GetObjectFunc.
func (mock *S3Mock) GetObject(bucketName string, objectName string, opts minio.GetObjectOptions) (*minio.Object, error) {
func (mock *S3Mock) GetObject(ctx context.Context, bucketName string, objectName string, opts minio.GetObjectOptions) (*minio.Object, error) {
if mock.GetObjectFunc == nil {
panic("S3Mock.GetObjectFunc: method is nil but S3.GetObject was just called")
}
callInfo := struct {
Ctx context.Context
BucketName string
ObjectName string
Opts minio.GetObjectOptions
}{
Ctx: ctx,
BucketName: bucketName,
ObjectName: objectName,
Opts: opts,
@ -153,18 +168,20 @@ func (mock *S3Mock) GetObject(bucketName string, objectName string, opts minio.G
mock.lockGetObject.Lock()
mock.calls.GetObject = append(mock.calls.GetObject, callInfo)
mock.lockGetObject.Unlock()
return mock.GetObjectFunc(bucketName, objectName, opts)
return mock.GetObjectFunc(ctx, bucketName, objectName, opts)
}
// GetObjectCalls gets all the calls that were made to GetObject.
// Check the length with:
// len(mockedS3.GetObjectCalls())
func (mock *S3Mock) GetObjectCalls() []struct {
Ctx context.Context
BucketName string
ObjectName string
Opts minio.GetObjectOptions
} {
var calls []struct {
Ctx context.Context
BucketName string
ObjectName string
Opts minio.GetObjectOptions
@ -176,24 +193,29 @@ func (mock *S3Mock) GetObjectCalls() []struct {
}
// ListBuckets calls ListBucketsFunc.
func (mock *S3Mock) ListBuckets() ([]minio.BucketInfo, error) {
func (mock *S3Mock) ListBuckets(ctx context.Context) ([]minio.BucketInfo, error) {
if mock.ListBucketsFunc == nil {
panic("S3Mock.ListBucketsFunc: method is nil but S3.ListBuckets was just called")
}
callInfo := struct {
}{}
Ctx context.Context
}{
Ctx: ctx,
}
mock.lockListBuckets.Lock()
mock.calls.ListBuckets = append(mock.calls.ListBuckets, callInfo)
mock.lockListBuckets.Unlock()
return mock.ListBucketsFunc()
return mock.ListBucketsFunc(ctx)
}
// ListBucketsCalls gets all the calls that were made to ListBuckets.
// Check the length with:
// len(mockedS3.ListBucketsCalls())
func (mock *S3Mock) ListBucketsCalls() []struct {
Ctx context.Context
} {
var calls []struct {
Ctx context.Context
}
mock.lockListBuckets.RLock()
calls = mock.calls.ListBuckets
@ -201,77 +223,77 @@ func (mock *S3Mock) ListBucketsCalls() []struct {
return calls
}
// ListObjectsV2 calls ListObjectsV2Func.
func (mock *S3Mock) ListObjectsV2(bucketName string, objectPrefix string, recursive bool, doneCh <-chan struct{}) <-chan minio.ObjectInfo {
if mock.ListObjectsV2Func == nil {
panic("S3Mock.ListObjectsV2Func: method is nil but S3.ListObjectsV2 was just called")
// ListObjects calls ListObjectsFunc.
func (mock *S3Mock) ListObjects(ctx context.Context, bucketName string, opts minio.ListObjectsOptions) <-chan minio.ObjectInfo {
if mock.ListObjectsFunc == nil {
panic("S3Mock.ListObjectsFunc: method is nil but S3.ListObjects was just called")
}
callInfo := struct {
BucketName string
ObjectPrefix string
Recursive bool
DoneCh <-chan struct{}
Ctx context.Context
BucketName string
Opts minio.ListObjectsOptions
}{
BucketName: bucketName,
ObjectPrefix: objectPrefix,
Recursive: recursive,
DoneCh: doneCh,
Ctx: ctx,
BucketName: bucketName,
Opts: opts,
}
mock.lockListObjectsV2.Lock()
mock.calls.ListObjectsV2 = append(mock.calls.ListObjectsV2, callInfo)
mock.lockListObjectsV2.Unlock()
return mock.ListObjectsV2Func(bucketName, objectPrefix, recursive, doneCh)
mock.lockListObjects.Lock()
mock.calls.ListObjects = append(mock.calls.ListObjects, callInfo)
mock.lockListObjects.Unlock()
return mock.ListObjectsFunc(ctx, bucketName, opts)
}
// ListObjectsV2Calls gets all the calls that were made to ListObjectsV2.
// ListObjectsCalls gets all the calls that were made to ListObjects.
// Check the length with:
// len(mockedS3.ListObjectsV2Calls())
func (mock *S3Mock) ListObjectsV2Calls() []struct {
BucketName string
ObjectPrefix string
Recursive bool
DoneCh <-chan struct{}
// len(mockedS3.ListObjectsCalls())
func (mock *S3Mock) ListObjectsCalls() []struct {
Ctx context.Context
BucketName string
Opts minio.ListObjectsOptions
} {
var calls []struct {
BucketName string
ObjectPrefix string
Recursive bool
DoneCh <-chan struct{}
Ctx context.Context
BucketName string
Opts minio.ListObjectsOptions
}
mock.lockListObjectsV2.RLock()
calls = mock.calls.ListObjectsV2
mock.lockListObjectsV2.RUnlock()
mock.lockListObjects.RLock()
calls = mock.calls.ListObjects
mock.lockListObjects.RUnlock()
return calls
}
// MakeBucket calls MakeBucketFunc.
func (mock *S3Mock) MakeBucket(bucketName string, location string) error {
func (mock *S3Mock) MakeBucket(ctx context.Context, bucketName string, opts minio.MakeBucketOptions) error {
if mock.MakeBucketFunc == nil {
panic("S3Mock.MakeBucketFunc: method is nil but S3.MakeBucket was just called")
}
callInfo := struct {
Ctx context.Context
BucketName string
Location string
Opts minio.MakeBucketOptions
}{
Ctx: ctx,
BucketName: bucketName,
Location: location,
Opts: opts,
}
mock.lockMakeBucket.Lock()
mock.calls.MakeBucket = append(mock.calls.MakeBucket, callInfo)
mock.lockMakeBucket.Unlock()
return mock.MakeBucketFunc(bucketName, location)
return mock.MakeBucketFunc(ctx, bucketName, opts)
}
// MakeBucketCalls gets all the calls that were made to MakeBucket.
// Check the length with:
// len(mockedS3.MakeBucketCalls())
func (mock *S3Mock) MakeBucketCalls() []struct {
Ctx context.Context
BucketName string
Location string
Opts minio.MakeBucketOptions
} {
var calls []struct {
Ctx context.Context
BucketName string
Location string
Opts minio.MakeBucketOptions
}
mock.lockMakeBucket.RLock()
calls = mock.calls.MakeBucket
@ -280,17 +302,19 @@ func (mock *S3Mock) MakeBucketCalls() []struct {
}
// PutObject calls PutObjectFunc.
func (mock *S3Mock) PutObject(bucketName string, objectName string, reader io.Reader, objectSize int64, opts minio.PutObjectOptions) (int64, error) {
func (mock *S3Mock) PutObject(ctx context.Context, bucketName string, objectName string, reader io.Reader, objectSize int64, opts minio.PutObjectOptions) (minio.UploadInfo, error) {
if mock.PutObjectFunc == nil {
panic("S3Mock.PutObjectFunc: method is nil but S3.PutObject was just called")
}
callInfo := struct {
Ctx context.Context
BucketName string
ObjectName string
Reader io.Reader
ObjectSize int64
Opts minio.PutObjectOptions
}{
Ctx: ctx,
BucketName: bucketName,
ObjectName: objectName,
Reader: reader,
@ -300,13 +324,14 @@ func (mock *S3Mock) PutObject(bucketName string, objectName string, reader io.Re
mock.lockPutObject.Lock()
mock.calls.PutObject = append(mock.calls.PutObject, callInfo)
mock.lockPutObject.Unlock()
return mock.PutObjectFunc(bucketName, objectName, reader, objectSize, opts)
return mock.PutObjectFunc(ctx, bucketName, objectName, reader, objectSize, opts)
}
// PutObjectCalls gets all the calls that were made to PutObject.
// Check the length with:
// len(mockedS3.PutObjectCalls())
func (mock *S3Mock) PutObjectCalls() []struct {
Ctx context.Context
BucketName string
ObjectName string
Reader io.Reader
@ -314,6 +339,7 @@ func (mock *S3Mock) PutObjectCalls() []struct {
Opts minio.PutObjectOptions
} {
var calls []struct {
Ctx context.Context
BucketName string
ObjectName string
Reader io.Reader
@ -327,28 +353,32 @@ func (mock *S3Mock) PutObjectCalls() []struct {
}
// RemoveBucket calls RemoveBucketFunc.
func (mock *S3Mock) RemoveBucket(bucketName string) error {
func (mock *S3Mock) RemoveBucket(ctx context.Context, bucketName string) error {
if mock.RemoveBucketFunc == nil {
panic("S3Mock.RemoveBucketFunc: method is nil but S3.RemoveBucket was just called")
}
callInfo := struct {
Ctx context.Context
BucketName string
}{
Ctx: ctx,
BucketName: bucketName,
}
mock.lockRemoveBucket.Lock()
mock.calls.RemoveBucket = append(mock.calls.RemoveBucket, callInfo)
mock.lockRemoveBucket.Unlock()
return mock.RemoveBucketFunc(bucketName)
return mock.RemoveBucketFunc(ctx, bucketName)
}
// RemoveBucketCalls gets all the calls that were made to RemoveBucket.
// Check the length with:
// len(mockedS3.RemoveBucketCalls())
func (mock *S3Mock) RemoveBucketCalls() []struct {
Ctx context.Context
BucketName string
} {
var calls []struct {
Ctx context.Context
BucketName string
}
mock.lockRemoveBucket.RLock()
@ -358,33 +388,41 @@ func (mock *S3Mock) RemoveBucketCalls() []struct {
}
// RemoveObject calls RemoveObjectFunc.
func (mock *S3Mock) RemoveObject(bucketName string, objectName string) error {
func (mock *S3Mock) RemoveObject(ctx context.Context, bucketName string, objectName string, opts minio.RemoveObjectOptions) error {
if mock.RemoveObjectFunc == nil {
panic("S3Mock.RemoveObjectFunc: method is nil but S3.RemoveObject was just called")
}
callInfo := struct {
Ctx context.Context
BucketName string
ObjectName string
Opts minio.RemoveObjectOptions
}{
Ctx: ctx,
BucketName: bucketName,
ObjectName: objectName,
Opts: opts,
}
mock.lockRemoveObject.Lock()
mock.calls.RemoveObject = append(mock.calls.RemoveObject, callInfo)
mock.lockRemoveObject.Unlock()
return mock.RemoveObjectFunc(bucketName, objectName)
return mock.RemoveObjectFunc(ctx, bucketName, objectName, opts)
}
// RemoveObjectCalls gets all the calls that were made to RemoveObject.
// Check the length with:
// len(mockedS3.RemoveObjectCalls())
func (mock *S3Mock) RemoveObjectCalls() []struct {
Ctx context.Context
BucketName string
ObjectName string
Opts minio.RemoveObjectOptions
} {
var calls []struct {
Ctx context.Context
BucketName string
ObjectName string
Opts minio.RemoveObjectOptions
}
mock.lockRemoveObject.RLock()
calls = mock.calls.RemoveObject

View file

@ -1,20 +1,21 @@
package s3manager
import (
"context"
"io"
minio "github.com/minio/minio-go"
"github.com/minio/minio-go/v7"
)
//go:generate moq -out mocks/s3.go -pkg mocks . S3
// S3 is a client to interact with S3 storage.
type S3 interface {
GetObject(bucketName, objectName string, opts minio.GetObjectOptions) (*minio.Object, error)
ListBuckets() ([]minio.BucketInfo, error)
ListObjectsV2(bucketName, objectPrefix string, recursive bool, doneCh <-chan struct{}) <-chan minio.ObjectInfo
MakeBucket(bucketName, location string) error
PutObject(bucketName, objectName string, reader io.Reader, objectSize int64, opts minio.PutObjectOptions) (int64, error)
RemoveBucket(bucketName string) error
RemoveObject(bucketName, objectName string) error
GetObject(ctx context.Context, bucketName, objectName string, opts minio.GetObjectOptions) (*minio.Object, error)
ListBuckets(ctx context.Context) ([]minio.BucketInfo, error)
ListObjects(ctx context.Context, bucketName string, opts minio.ListObjectsOptions) <-chan minio.ObjectInfo
MakeBucket(ctx context.Context, bucketName string, opts minio.MakeBucketOptions) error
PutObject(ctx context.Context, bucketName, objectName string, reader io.Reader, objectSize int64, opts minio.PutObjectOptions) (minio.UploadInfo, error)
RemoveBucket(ctx context.Context, bucketName string) error
RemoveObject(ctx context.Context, bucketName, objectName string, opts minio.RemoveObjectOptions) error
}

19
main.go
View file

@ -13,7 +13,8 @@ import (
"github.com/mastertinner/adapters/logging"
"github.com/mastertinner/s3manager/internal/app/s3manager"
"github.com/matryer/way"
minio "github.com/minio/minio-go"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
)
//go:embed web/template
@ -32,6 +33,7 @@ func main() {
if !ok {
log.Fatal("please provide SECRET_ACCESS_KEY")
}
region := os.Getenv("REGION")
useSSL := getBoolEnvWithDefault("USE_SSL", true)
skipSSLVerification := getBoolEnvWithDefault("SKIP_SSL_VERIFICATION", false)
port, ok := os.LookupEnv("PORT")
@ -46,12 +48,19 @@ func main() {
}
// Set up S3 client
s3, err := minio.New(endpoint, accessKeyID, secretAccessKey, useSSL)
if err != nil {
log.Fatalln(fmt.Errorf("error creating s3 client: %w", err))
opts := &minio.Options{
Creds: credentials.NewStaticV4(accessKeyID, secretAccessKey, ""),
Secure: useSSL,
}
if region != "" {
opts.Region = region
}
if useSSL && skipSSLVerification {
s3.SetCustomTransport(&http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}) //nolint:gosec
opts.Transport = &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}} //nolint:gosec
}
s3, err := minio.New(endpoint, opts)
if err != nil {
log.Fatalln(fmt.Errorf("error creating s3 client: %w", err))
}
// Set up router