diff --git a/go.sum b/go.sum index 7f228b509..af937e487 100644 --- a/go.sum +++ b/go.sum @@ -671,7 +671,9 @@ 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/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/klauspost/readahead v1.3.1 h1:QqXNYvm+VvqYcbrRT4LojUciM0XrznFRIDrbHiJtu/0= github.com/klauspost/readahead v1.3.1/go.mod h1:AH9juHzNH7xqdqFHrMRSHeH2Ps+vFf+kblDqzPFiLJg= +github.com/klauspost/reedsolomon v1.9.9 h1:qCL7LZlv17xMixl55nq2/Oa1Y86nfO8EqDfv2GHND54= github.com/klauspost/reedsolomon v1.9.9/go.mod h1:O7yFFHiQwDR6b2t63KPUpccPtNdp5ADgh1gg4fd12wo= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -738,6 +740,7 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.8 h1:1QYRAKU3lN5cRfLCkPU08hwvLJFhvjP6MqNMmQz6ZVI= github.com/miekg/dns v1.1.8/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/minio/cli v1.22.0 h1:VTQm7lmXm3quxO917X3p+el1l0Ca5X3S4PM2ruUYO68= github.com/minio/cli v1.22.0/go.mod h1:bYxnK0uS629N3Bq+AOZZ+6lwF77Sodk4+UL9vNuXhOY= @@ -761,6 +764,7 @@ github.com/minio/selfupdate v0.3.1 h1:BWEFSNnrZVMUWXbXIgLDNDjbejkmpAmZvy/nCz1HlE github.com/minio/selfupdate v0.3.1/go.mod h1:b8ThJzzH7u2MkF6PcIra7KaXO9Khf6alWPvMSyTDCFM= github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/minio/simdjson-go v0.1.5 h1:6T5mHh7r3kUvgwhmFWQAjoPV5Yt5oD/VPjAI9ViH1kM= github.com/minio/simdjson-go v0.1.5/go.mod h1:oKURrZZEBtqObgJrSjN1Ln2n9MJj2icuBTkeJzZnvSI= github.com/minio/sio v0.2.1 h1:NjzKiIMSMcHediVQR0AFVx2tp7Wxh9tKPfDI3kH7aHQ= github.com/minio/sio v0.2.1/go.mod h1:8b0yPp2avGThviy/+OCJBI6OMpvxoUuiLvE6F1lebhw= @@ -912,6 +916,7 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= @@ -922,6 +927,7 @@ github.com/ryancurrah/gomodguard v1.0.4/go.mod h1:9T/Cfuxs5StfsocWr4WzDL36HqnX0f github.com/ryancurrah/gomodguard v1.1.0/go.mod h1:4O8tr7hBODaGE6VIhfJDHcwzh5GUccKSJBU0UMXJFVM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= @@ -965,6 +971,7 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE= github.com/sourcegraph/go-diff v0.5.3/go.mod h1:v9JDtjCE4HHHCZGId75rg8gkKKa98RVjBcBGsVmMmak= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= @@ -1001,10 +1008,13 @@ github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2/go.mod h1:yHp0 github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= github.com/tetafro/godot v0.3.7/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0= github.com/tetafro/godot v0.4.2/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0= +github.com/tidwall/gjson v1.3.5 h1:2oW9FBNu8qt9jy5URgrzsVx/T/KSn3qn/smJQ0crlDQ= github.com/tidwall/gjson v1.3.5/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= +github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc= github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/sjson v1.0.4 h1:UcdIRXff12Lpnu3OLtZvnc03g4vH2suXDXhBwBqmzYg= github.com/tidwall/sjson v1.0.4/go.mod h1:bURseu1nuBkFpIES5cz6zBtjmYeOQmEESshn7VpF15Y= github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= @@ -1039,6 +1049,7 @@ github.com/vdemeester/k8s-pkg-credentialprovider v1.17.4/go.mod h1:inCTmtUdr5KJb github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= +github.com/willf/bloom v2.0.3+incompatible h1:QDacWdqcAUI1MPOwIQZRy9kOR7yxfyEmxX8Wdm2/JPA= github.com/willf/bloom v2.0.3+incompatible/go.mod h1:MmAltL9pDMNTrvUkxdg0k0q5I0suxmuwp3KbyrZLOZ8= github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug= github.com/xanzy/go-gitlab v0.32.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug= @@ -1072,6 +1083,7 @@ go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1385,6 +1397,7 @@ google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/ google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.25.0 h1:LodzhlzZEUfhXzNUMIfVlf9Gr6Ua5MMtoFWh7+f47qA= google.golang.org/api v0.25.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1450,6 +1463,7 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1480,6 +1494,7 @@ gopkg.in/jcmturner/gokrb5.v7 v7.3.0 h1:0709Jtq/6QXEuWRfAm260XqlpcwL1vxtO1tUE2qK8 gopkg.in/jcmturner/gokrb5.v7 v7.3.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= gopkg.in/jcmturner/rpc.v1 v1.1.0 h1:QHIUxTX1ISuAv9dD2wJ9HWQVuWDX/Zc0PfeC2tjc4rU= gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= +gopkg.in/ldap.v3 v3.0.3 h1:YKRHW/2sIl05JsCtx/5ZuUueFuJyoj/6+DGXe3wp6ro= gopkg.in/ldap.v3 v3.0.3/go.mod h1:oxD7NyBuxchC+SgJDE1Q5Od05eGt29SDQVBmV+HYbzw= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/olivere/elastic.v5 v5.0.86 h1:xFy6qRCGAmo5Wjx96srho9BitLhZl2fcnpuidPwduXM= diff --git a/models/get_bucket_retention_config.go b/models/get_bucket_retention_config.go new file mode 100644 index 000000000..de341b92d --- /dev/null +++ b/models/get_bucket_retention_config.go @@ -0,0 +1,112 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2020 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// GetBucketRetentionConfig get bucket retention config +// +// swagger:model getBucketRetentionConfig +type GetBucketRetentionConfig struct { + + // mode + Mode ObjectRetentionMode `json:"mode,omitempty"` + + // unit + Unit ObjectRetentionUnit `json:"unit,omitempty"` + + // validity + Validity int32 `json:"validity,omitempty"` +} + +// Validate validates this get bucket retention config +func (m *GetBucketRetentionConfig) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateMode(formats); err != nil { + res = append(res, err) + } + + if err := m.validateUnit(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *GetBucketRetentionConfig) validateMode(formats strfmt.Registry) error { + + if swag.IsZero(m.Mode) { // not required + return nil + } + + if err := m.Mode.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("mode") + } + return err + } + + return nil +} + +func (m *GetBucketRetentionConfig) validateUnit(formats strfmt.Registry) error { + + if swag.IsZero(m.Unit) { // not required + return nil + } + + if err := m.Unit.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("unit") + } + return err + } + + return nil +} + +// MarshalBinary interface implementation +func (m *GetBucketRetentionConfig) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *GetBucketRetentionConfig) UnmarshalBinary(b []byte) error { + var res GetBucketRetentionConfig + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/restapi/client.go b/restapi/client.go index 08ed0d079..310b43bbd 100644 --- a/restapi/client.go +++ b/restapi/client.go @@ -69,6 +69,7 @@ type MinioClient interface { putObjectTagging(ctx context.Context, bucketName, objectName string, otags *tags.Tags, opts minio.PutObjectTaggingOptions) error getObjectTagging(ctx context.Context, bucketName, objectName string, opts minio.GetObjectTaggingOptions) (*tags.Tags, error) setObjectLockConfig(ctx context.Context, bucketName string, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit) error + getBucketObjectLockConfig(ctx context.Context, bucketName string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) } // Interface implementation @@ -174,6 +175,10 @@ func (c minioClient) setObjectLockConfig(ctx context.Context, bucketName string, return c.client.SetObjectLockConfig(ctx, bucketName, mode, validity, unit) } +func (c minioClient) getBucketObjectLockConfig(ctx context.Context, bucketName string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { + return c.client.GetBucketObjectLockConfig(ctx, bucketName) +} + // MCClient interface with all functions to be implemented // by mock when testing, it should include all mc/S3Client respective api calls // that are used within this project. diff --git a/restapi/embedded_spec.go b/restapi/embedded_spec.go index d154ca02b..37a8e054d 100644 --- a/restapi/embedded_spec.go +++ b/restapi/embedded_spec.go @@ -940,6 +940,35 @@ func init() { } }, "/buckets/{bucket_name}/retention": { + "get": { + "tags": [ + "UserAPI" + ], + "summary": "Get Bucket's retention config", + "operationId": "GetBucketRetentionConfig", + "parameters": [ + { + "type": "string", + "name": "bucket_name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/getBucketRetentionConfig" + } + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } + }, "put": { "tags": [ "UserAPI" @@ -3563,6 +3592,21 @@ func init() { } } }, + "getBucketRetentionConfig": { + "type": "object", + "properties": { + "mode": { + "$ref": "#/definitions/objectRetentionMode" + }, + "unit": { + "$ref": "#/definitions/objectRetentionUnit" + }, + "validity": { + "type": "integer", + "format": "int32" + } + } + }, "group": { "type": "object", "properties": { @@ -6020,6 +6064,35 @@ func init() { } }, "/buckets/{bucket_name}/retention": { + "get": { + "tags": [ + "UserAPI" + ], + "summary": "Get Bucket's retention config", + "operationId": "GetBucketRetentionConfig", + "parameters": [ + { + "type": "string", + "name": "bucket_name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/getBucketRetentionConfig" + } + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } + }, "put": { "tags": [ "UserAPI" @@ -9166,6 +9239,21 @@ func init() { } } }, + "getBucketRetentionConfig": { + "type": "object", + "properties": { + "mode": { + "$ref": "#/definitions/objectRetentionMode" + }, + "unit": { + "$ref": "#/definitions/objectRetentionUnit" + }, + "validity": { + "type": "integer", + "format": "int32" + } + } + }, "group": { "type": "object", "properties": { diff --git a/restapi/operations/console_api.go b/restapi/operations/console_api.go index dc075dae1..2b11e3a98 100644 --- a/restapi/operations/console_api.go +++ b/restapi/operations/console_api.go @@ -151,6 +151,9 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI { UserAPIGetBucketReplicationHandler: user_api.GetBucketReplicationHandlerFunc(func(params user_api.GetBucketReplicationParams, principal *models.Principal) middleware.Responder { return middleware.NotImplemented("operation user_api.GetBucketReplication has not yet been implemented") }), + UserAPIGetBucketRetentionConfigHandler: user_api.GetBucketRetentionConfigHandlerFunc(func(params user_api.GetBucketRetentionConfigParams, principal *models.Principal) middleware.Responder { + return middleware.NotImplemented("operation user_api.GetBucketRetentionConfig has not yet been implemented") + }), UserAPIGetBucketVersioningHandler: user_api.GetBucketVersioningHandlerFunc(func(params user_api.GetBucketVersioningParams, principal *models.Principal) middleware.Responder { return middleware.NotImplemented("operation user_api.GetBucketVersioning has not yet been implemented") }), @@ -423,6 +426,8 @@ type ConsoleAPI struct { UserAPIGetBucketQuotaHandler user_api.GetBucketQuotaHandler // UserAPIGetBucketReplicationHandler sets the operation handler for the get bucket replication operation UserAPIGetBucketReplicationHandler user_api.GetBucketReplicationHandler + // UserAPIGetBucketRetentionConfigHandler sets the operation handler for the get bucket retention config operation + UserAPIGetBucketRetentionConfigHandler user_api.GetBucketRetentionConfigHandler // UserAPIGetBucketVersioningHandler sets the operation handler for the get bucket versioning operation UserAPIGetBucketVersioningHandler user_api.GetBucketVersioningHandler // AdminAPIGetMaxAllocatableMemHandler sets the operation handler for the get max allocatable mem operation @@ -694,6 +699,9 @@ func (o *ConsoleAPI) Validate() error { if o.UserAPIGetBucketReplicationHandler == nil { unregistered = append(unregistered, "user_api.GetBucketReplicationHandler") } + if o.UserAPIGetBucketRetentionConfigHandler == nil { + unregistered = append(unregistered, "user_api.GetBucketRetentionConfigHandler") + } if o.UserAPIGetBucketVersioningHandler == nil { unregistered = append(unregistered, "user_api.GetBucketVersioningHandler") } @@ -1077,6 +1085,10 @@ func (o *ConsoleAPI) initHandlerCache() { if o.handlers["GET"] == nil { o.handlers["GET"] = make(map[string]http.Handler) } + o.handlers["GET"]["/buckets/{bucket_name}/retention"] = user_api.NewGetBucketRetentionConfig(o.context, o.UserAPIGetBucketRetentionConfigHandler) + if o.handlers["GET"] == nil { + o.handlers["GET"] = make(map[string]http.Handler) + } o.handlers["GET"]["/buckets/{bucket_name}/versioning"] = user_api.NewGetBucketVersioning(o.context, o.UserAPIGetBucketVersioningHandler) if o.handlers["GET"] == nil { o.handlers["GET"] = make(map[string]http.Handler) diff --git a/restapi/operations/user_api/get_bucket_retention_config.go b/restapi/operations/user_api/get_bucket_retention_config.go new file mode 100644 index 000000000..041ef6e64 --- /dev/null +++ b/restapi/operations/user_api/get_bucket_retention_config.go @@ -0,0 +1,90 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2020 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + +package user_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime/middleware" + + "github.com/minio/console/models" +) + +// GetBucketRetentionConfigHandlerFunc turns a function with the right signature into a get bucket retention config handler +type GetBucketRetentionConfigHandlerFunc func(GetBucketRetentionConfigParams, *models.Principal) middleware.Responder + +// Handle executing the request and returning a response +func (fn GetBucketRetentionConfigHandlerFunc) Handle(params GetBucketRetentionConfigParams, principal *models.Principal) middleware.Responder { + return fn(params, principal) +} + +// GetBucketRetentionConfigHandler interface for that can handle valid get bucket retention config params +type GetBucketRetentionConfigHandler interface { + Handle(GetBucketRetentionConfigParams, *models.Principal) middleware.Responder +} + +// NewGetBucketRetentionConfig creates a new http.Handler for the get bucket retention config operation +func NewGetBucketRetentionConfig(ctx *middleware.Context, handler GetBucketRetentionConfigHandler) *GetBucketRetentionConfig { + return &GetBucketRetentionConfig{Context: ctx, Handler: handler} +} + +/*GetBucketRetentionConfig swagger:route GET /buckets/{bucket_name}/retention UserAPI getBucketRetentionConfig + +Get Bucket's retention config + +*/ +type GetBucketRetentionConfig struct { + Context *middleware.Context + Handler GetBucketRetentionConfigHandler +} + +func (o *GetBucketRetentionConfig) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + r = rCtx + } + var Params = NewGetBucketRetentionConfigParams() + + uprinc, aCtx, err := o.Context.Authorize(r, route) + if err != nil { + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + if aCtx != nil { + r = aCtx + } + var principal *models.Principal + if uprinc != nil { + principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise + } + + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params, principal) // actually handle the request + + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/restapi/operations/user_api/get_bucket_retention_config_parameters.go b/restapi/operations/user_api/get_bucket_retention_config_parameters.go new file mode 100644 index 000000000..ab336f361 --- /dev/null +++ b/restapi/operations/user_api/get_bucket_retention_config_parameters.go @@ -0,0 +1,89 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2020 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + +package user_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/strfmt" +) + +// NewGetBucketRetentionConfigParams creates a new GetBucketRetentionConfigParams object +// no default values defined in spec. +func NewGetBucketRetentionConfigParams() GetBucketRetentionConfigParams { + + return GetBucketRetentionConfigParams{} +} + +// GetBucketRetentionConfigParams contains all the bound params for the get bucket retention config operation +// typically these are obtained from a http.Request +// +// swagger:parameters GetBucketRetentionConfig +type GetBucketRetentionConfigParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` + + /* + Required: true + In: path + */ + BucketName string +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewGetBucketRetentionConfigParams() beforehand. +func (o *GetBucketRetentionConfigParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + rBucketName, rhkBucketName, _ := route.Params.GetOK("bucket_name") + if err := o.bindBucketName(rBucketName, rhkBucketName, route.Formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +// bindBucketName binds and validates parameter BucketName from path. +func (o *GetBucketRetentionConfigParams) bindBucketName(rawData []string, hasKey bool, formats strfmt.Registry) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: true + // Parameter is provided by construction from the route + + o.BucketName = raw + + return nil +} diff --git a/restapi/operations/user_api/get_bucket_retention_config_responses.go b/restapi/operations/user_api/get_bucket_retention_config_responses.go new file mode 100644 index 000000000..e0ee9a3e9 --- /dev/null +++ b/restapi/operations/user_api/get_bucket_retention_config_responses.go @@ -0,0 +1,133 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2020 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + +package user_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" + + "github.com/minio/console/models" +) + +// GetBucketRetentionConfigOKCode is the HTTP code returned for type GetBucketRetentionConfigOK +const GetBucketRetentionConfigOKCode int = 200 + +/*GetBucketRetentionConfigOK A successful response. + +swagger:response getBucketRetentionConfigOK +*/ +type GetBucketRetentionConfigOK struct { + + /* + In: Body + */ + Payload *models.GetBucketRetentionConfig `json:"body,omitempty"` +} + +// NewGetBucketRetentionConfigOK creates GetBucketRetentionConfigOK with default headers values +func NewGetBucketRetentionConfigOK() *GetBucketRetentionConfigOK { + + return &GetBucketRetentionConfigOK{} +} + +// WithPayload adds the payload to the get bucket retention config o k response +func (o *GetBucketRetentionConfigOK) WithPayload(payload *models.GetBucketRetentionConfig) *GetBucketRetentionConfigOK { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the get bucket retention config o k response +func (o *GetBucketRetentionConfigOK) SetPayload(payload *models.GetBucketRetentionConfig) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *GetBucketRetentionConfigOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(200) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +/*GetBucketRetentionConfigDefault Generic error response. + +swagger:response getBucketRetentionConfigDefault +*/ +type GetBucketRetentionConfigDefault struct { + _statusCode int + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewGetBucketRetentionConfigDefault creates GetBucketRetentionConfigDefault with default headers values +func NewGetBucketRetentionConfigDefault(code int) *GetBucketRetentionConfigDefault { + if code <= 0 { + code = 500 + } + + return &GetBucketRetentionConfigDefault{ + _statusCode: code, + } +} + +// WithStatusCode adds the status to the get bucket retention config default response +func (o *GetBucketRetentionConfigDefault) WithStatusCode(code int) *GetBucketRetentionConfigDefault { + o._statusCode = code + return o +} + +// SetStatusCode sets the status to the get bucket retention config default response +func (o *GetBucketRetentionConfigDefault) SetStatusCode(code int) { + o._statusCode = code +} + +// WithPayload adds the payload to the get bucket retention config default response +func (o *GetBucketRetentionConfigDefault) WithPayload(payload *models.Error) *GetBucketRetentionConfigDefault { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the get bucket retention config default response +func (o *GetBucketRetentionConfigDefault) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *GetBucketRetentionConfigDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(o._statusCode) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} diff --git a/restapi/operations/user_api/get_bucket_retention_config_urlbuilder.go b/restapi/operations/user_api/get_bucket_retention_config_urlbuilder.go new file mode 100644 index 000000000..ebd6b3129 --- /dev/null +++ b/restapi/operations/user_api/get_bucket_retention_config_urlbuilder.go @@ -0,0 +1,116 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2020 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + +package user_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" + "strings" +) + +// GetBucketRetentionConfigURL generates an URL for the get bucket retention config operation +type GetBucketRetentionConfigURL struct { + BucketName string + + _basePath string + // avoid unkeyed usage + _ struct{} +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *GetBucketRetentionConfigURL) WithBasePath(bp string) *GetBucketRetentionConfigURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *GetBucketRetentionConfigURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *GetBucketRetentionConfigURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/buckets/{bucket_name}/retention" + + bucketName := o.BucketName + if bucketName != "" { + _path = strings.Replace(_path, "{bucket_name}", bucketName, -1) + } else { + return nil, errors.New("bucketName is required on GetBucketRetentionConfigURL") + } + + _basePath := o._basePath + if _basePath == "" { + _basePath = "/api/v1" + } + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *GetBucketRetentionConfigURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *GetBucketRetentionConfigURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *GetBucketRetentionConfigURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on GetBucketRetentionConfigURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on GetBucketRetentionConfigURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *GetBucketRetentionConfigURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/restapi/user_buckets.go b/restapi/user_buckets.go index ec47f474e..d75274db0 100644 --- a/restapi/user_buckets.go +++ b/restapi/user_buckets.go @@ -24,6 +24,7 @@ import ( "strings" "time" + "github.com/minio/mc/pkg/probe" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/replication" "github.com/minio/minio-go/v7/pkg/sse" @@ -134,6 +135,14 @@ func registerBucketsHandlers(api *operations.ConsoleAPI) { } return user_api.NewSetBucketRetentionConfigOK() }) + // get bucket retention config + api.UserAPIGetBucketRetentionConfigHandler = user_api.GetBucketRetentionConfigHandlerFunc(func(params user_api.GetBucketRetentionConfigParams, session *models.Principal) middleware.Responder { + response, err := getBucketRetentionConfigResponse(session, params.BucketName) + if err != nil { + return user_api.NewGetBucketRetentionConfigDefault(int(err.Code)).WithPayload(err) + } + return user_api.NewGetBucketRetentionConfigOK().WithPayload(response) + }) } func getAddBucketReplicationdResponse(session *models.Principal, bucketName string, params *user_api.AddBucketReplicationParams) error { @@ -636,3 +645,58 @@ func getSetBucketRetentionConfigResponse(session *models.Principal, params user_ } return nil } + +func getBucketRetentionConfig(ctx context.Context, client MinioClient, bucketName string) (*models.GetBucketRetentionConfig, error) { + m, v, u, err := client.getBucketObjectLockConfig(ctx, bucketName) + if err != nil { + errResp := minio.ToErrorResponse(probe.NewError(err).ToGoError()) + if errResp.Code == "ObjectLockConfigurationNotFoundError" { + return &models.GetBucketRetentionConfig{}, nil + } + return nil, err + } + var mode models.ObjectRetentionMode + var unit models.ObjectRetentionUnit + switch *m { + case minio.Governance: + mode = models.ObjectRetentionModeGovernance + case minio.Compliance: + mode = models.ObjectRetentionModeCompliance + default: + return nil, errors.New("invalid retention mode") + } + + switch *u { + case minio.Days: + unit = models.ObjectRetentionUnitDays + case minio.Years: + unit = models.ObjectRetentionUnitYears + default: + return nil, errors.New("invalid retention unit") + } + + config := &models.GetBucketRetentionConfig{ + Mode: mode, + Unit: unit, + Validity: int32(*v), + } + return config, nil +} + +func getBucketRetentionConfigResponse(session *models.Principal, bucketName string) (*models.GetBucketRetentionConfig, *models.Error) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*20) + defer cancel() + mClient, err := newMinioClient(session) + if err != nil { + return nil, prepareError(err) + } + // create a minioClient interface implementation + // defining the client to be used + minioClient := minioClient{client: mClient} + + config, err := getBucketRetentionConfig(ctx, minioClient, bucketName) + if err != nil { + return nil, prepareError(err) + } + return config, nil +} diff --git a/restapi/user_buckets_test.go b/restapi/user_buckets_test.go index 5ed246682..97905bdb9 100644 --- a/restapi/user_buckets_test.go +++ b/restapi/user_buckets_test.go @@ -42,7 +42,8 @@ var minioGetBucketPolicyMock func(bucketName string) (string, error) var minioSetBucketEncryptionMock func(ctx context.Context, bucketName string, config *sse.Configuration) error var minioRemoveBucketEncryptionMock func(ctx context.Context, bucketName string) error var minioGetBucketEncryptionMock func(ctx context.Context, bucketName string) (*sse.Configuration, error) -var minioSetObjectLockConfig func(ctx context.Context, bucketName string, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit) error +var minioSetObjectLockConfigMock func(ctx context.Context, bucketName string, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit) error +var minioGetObjectLockConfigMock func(ctx context.Context, bucketName string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) // Define a mock struct of minio Client interface implementation type minioClientMock struct { @@ -86,7 +87,11 @@ func (mc minioClientMock) getBucketEncryption(ctx context.Context, bucketName st } func (mc minioClientMock) setObjectLockConfig(ctx context.Context, bucketName string, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit) error { - return minioSetObjectLockConfig(ctx, bucketName, mode, validity, unit) + return minioSetObjectLockConfigMock(ctx, bucketName, mode, validity, unit) +} + +func (mc minioClientMock) getBucketObjectLockConfig(ctx context.Context, bucketName string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { + return minioGetObjectLockConfigMock(ctx, bucketName) } var minioAccountInfoMock func(ctx context.Context) (madmin.AccountInfo, error) @@ -632,7 +637,7 @@ func Test_SetBucketRetentionConfig(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - minioSetObjectLockConfig = tt.args.mockBucketRetentionFunc + minioSetObjectLockConfigMock = tt.args.mockBucketRetentionFunc err := setBucketRetentionConfig(tt.args.ctx, tt.args.client, tt.args.bucketName, tt.args.mode, tt.args.unit, tt.args.validity) if tt.expectedError != nil { fmt.Println(t.Name()) @@ -643,3 +648,120 @@ func Test_SetBucketRetentionConfig(t *testing.T) { }) } } + +func Test_GetBucketRetentionConfig(t *testing.T) { + assert := assert.New(t) + ctx := context.Background() + minClient := minioClientMock{} + type args struct { + ctx context.Context + client MinioClient + bucketName string + getRetentionFunc func(ctx context.Context, bucketName string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) + } + tests := []struct { + name string + args args + expectedResponse *models.GetBucketRetentionConfig + expectedError error + }{ + { + name: "Get Bucket Retention Config", + args: args{ + ctx: ctx, + client: minClient, + bucketName: "test", + getRetentionFunc: func(ctx context.Context, bucketName string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { + m := minio.Governance + u := minio.Days + return &m, swag.Uint(2), &u, nil + }, + }, + expectedResponse: &models.GetBucketRetentionConfig{ + Mode: models.ObjectRetentionModeGovernance, + Unit: models.ObjectRetentionUnitDays, + Validity: int32(2), + }, + expectedError: nil, + }, + { + name: "Handle Error on minio func", + args: args{ + ctx: ctx, + client: minClient, + bucketName: "test", + getRetentionFunc: func(ctx context.Context, bucketName string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { + return nil, nil, nil, errors.New("error func") + }, + }, + expectedResponse: nil, + expectedError: errors.New("error func"), + }, + { + // Description: if minio return NoSuchObjectLockConfiguration, don't panic + // and return empty response + name: "Handle NoLock Config error", + args: args{ + ctx: ctx, + client: minClient, + bucketName: "test", + getRetentionFunc: func(ctx context.Context, bucketName string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { + return nil, nil, nil, minio.ErrorResponse{ + Code: "ObjectLockConfigurationNotFoundError", + Message: "Object Lock configuration does not exist for this bucket", + } + }, + }, + expectedResponse: &models.GetBucketRetentionConfig{}, + expectedError: nil, + }, + { + name: "Return error on invalid mode", + args: args{ + ctx: ctx, + client: minClient, + bucketName: "test", + getRetentionFunc: func(ctx context.Context, bucketName string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { + m := minio.RetentionMode("other") + u := minio.Days + return &m, swag.Uint(2), &u, nil + }, + }, + expectedResponse: nil, + expectedError: errors.New("invalid retention mode"), + }, + { + name: "Return error on invalid unit", + args: args{ + ctx: ctx, + client: minClient, + bucketName: "test", + getRetentionFunc: func(ctx context.Context, bucketName string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { + m := minio.Governance + u := minio.ValidityUnit("otherUnit") + return &m, swag.Uint(2), &u, nil + }, + }, + expectedResponse: nil, + expectedError: errors.New("invalid retention unit"), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + minioGetObjectLockConfigMock = tt.args.getRetentionFunc + resp, err := getBucketRetentionConfig(tt.args.ctx, tt.args.client, tt.args.bucketName) + + if tt.expectedError != nil { + fmt.Println(t.Name()) + assert.Equal(tt.expectedError.Error(), err.Error(), fmt.Sprintf("getBucketRetentionConfig() error: `%s`, wantErr: `%s`", err, tt.expectedError)) + } else { + assert.Nil(err, fmt.Sprintf("getBucketRetentionConfig() error: %v, wantErr: %v", err, tt.expectedError)) + if !reflect.DeepEqual(resp, tt.expectedResponse) { + t.Errorf("getBucketRetentionConfig() resp: %v, expectedResponse: %v", resp, tt.expectedResponse) + return + } + } + }) + } +} diff --git a/swagger.yml b/swagger.yml index 84be2fc0a..dbdf4b73c 100644 --- a/swagger.yml +++ b/swagger.yml @@ -246,6 +246,25 @@ paths: - UserAPI /buckets/{bucket_name}/retention: + get: + summary: Get Bucket's retention config + operationId: GetBucketRetentionConfig + parameters: + - name: bucket_name + in: path + required: true + type: string + responses: + 200: + description: A successful response. + schema: + $ref: "#/definitions/getBucketRetentionConfig" + default: + description: Generic error response. + schema: + $ref: "#/definitions/error" + tags: + - UserAPI put: summary: Set Bucket's retention config operationId: SetBucketRetentionConfig @@ -3676,3 +3695,15 @@ definitions: validity: type: integer format: int32 + + getBucketRetentionConfig: + type: object + properties: + mode: + $ref: "#/definitions/objectRetentionMode" + unit: + $ref: "#/definitions/objectRetentionUnit" + validity: + type: integer + format: int32 + \ No newline at end of file