[#13] Rename go module name according to NSPCC standards
- refactoring s3 gate structure - cleanup unused code - rename go module to `github.com/nspcc-dev/neofs-s3-gate` closes #13 Signed-off-by: Evgeniy Kulikov <kim@nspcc.ru>
This commit is contained in:
parent
e7f72fc670
commit
0161d2fbd3
25 changed files with 396 additions and 1112 deletions
|
@ -2,15 +2,9 @@ package api
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/minio/minio-go/v7/pkg/tags"
|
||||
"github.com/minio/minio/auth"
|
||||
"github.com/minio/minio/neofs/api/crypto"
|
||||
"path"
|
||||
)
|
||||
|
||||
type (
|
||||
|
@ -24,7 +18,7 @@ const maxEConfigJSONSize = 262272
|
|||
|
||||
// Error codes, non exhaustive list - http://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html
|
||||
const (
|
||||
ErrNone ErrorCode = iota
|
||||
_ ErrorCode = iota
|
||||
ErrAccessDenied
|
||||
ErrBadDigest
|
||||
ErrEntityTooSmall
|
||||
|
@ -1096,7 +1090,7 @@ var errorCodes = errorCodeMap{
|
|||
},
|
||||
ErrObjectTampered: {
|
||||
Code: "XMinioObjectTampered",
|
||||
Description: errObjectTampered.Error(),
|
||||
Description: "The requested object was modified and may be compromised",
|
||||
HTTPStatusCode: http.StatusPartialContent,
|
||||
},
|
||||
ErrMaximumExpires: {
|
||||
|
@ -1618,300 +1612,6 @@ func (e errorCodeMap) ToAPIErr(errCode ErrorCode) Error {
|
|||
return e.ToAPIErrWithErr(errCode, nil)
|
||||
}
|
||||
|
||||
// toAPIErrorCode - Converts embedded errors. Convenience
|
||||
// function written to handle all cases where we have known types of
|
||||
// errors returned by underlying layers.
|
||||
func toAPIErrorCode(_ context.Context, err error) (apiErr ErrorCode) {
|
||||
if err == nil {
|
||||
return ErrNone
|
||||
}
|
||||
|
||||
switch err {
|
||||
case errInvalidArgument:
|
||||
apiErr = ErrAdminInvalidArgument
|
||||
case errNoSuchUser:
|
||||
apiErr = ErrAdminNoSuchUser
|
||||
case errNoSuchGroup:
|
||||
apiErr = ErrAdminNoSuchGroup
|
||||
case errGroupNotEmpty:
|
||||
apiErr = ErrAdminGroupNotEmpty
|
||||
case errNoSuchPolicy:
|
||||
apiErr = ErrAdminNoSuchPolicy
|
||||
case errSignatureMismatch:
|
||||
apiErr = ErrSignatureDoesNotMatch
|
||||
case errInvalidRange:
|
||||
apiErr = ErrInvalidRange
|
||||
case errDataTooLarge:
|
||||
apiErr = ErrEntityTooLarge
|
||||
case errDataTooSmall:
|
||||
apiErr = ErrEntityTooSmall
|
||||
case errAuthentication:
|
||||
apiErr = ErrAccessDenied
|
||||
case auth.ErrInvalidAccessKeyLength:
|
||||
apiErr = ErrAdminInvalidAccessKey
|
||||
case auth.ErrInvalidSecretKeyLength:
|
||||
apiErr = ErrAdminInvalidSecretKey
|
||||
// SSE errors
|
||||
case errInvalidEncryptionParameters:
|
||||
apiErr = ErrInvalidEncryptionParameters
|
||||
case crypto.ErrInvalidEncryptionMethod:
|
||||
apiErr = ErrInvalidEncryptionMethod
|
||||
case crypto.ErrInvalidCustomerAlgorithm:
|
||||
apiErr = ErrInvalidSSECustomerAlgorithm
|
||||
case crypto.ErrMissingCustomerKey:
|
||||
apiErr = ErrMissingSSECustomerKey
|
||||
case crypto.ErrMissingCustomerKeyMD5:
|
||||
apiErr = ErrMissingSSECustomerKeyMD5
|
||||
case crypto.ErrCustomerKeyMD5Mismatch:
|
||||
apiErr = ErrSSECustomerKeyMD5Mismatch
|
||||
case errObjectTampered:
|
||||
apiErr = ErrObjectTampered
|
||||
case errEncryptedObject:
|
||||
apiErr = ErrSSEEncryptedObject
|
||||
case errInvalidSSEParameters:
|
||||
apiErr = ErrInvalidSSECustomerParameters
|
||||
case crypto.ErrInvalidCustomerKey, crypto.ErrSecretKeyMismatch:
|
||||
apiErr = ErrAccessDenied // no access without correct key
|
||||
case crypto.ErrIncompatibleEncryptionMethod:
|
||||
apiErr = ErrIncompatibleEncryptionMethod
|
||||
case errKMSNotConfigured:
|
||||
apiErr = ErrKMSNotConfigured
|
||||
case crypto.ErrKMSAuthLogin:
|
||||
apiErr = ErrKMSAuthFailure
|
||||
case context.Canceled, context.DeadlineExceeded:
|
||||
apiErr = ErrOperationTimedOut
|
||||
case errDiskNotFound:
|
||||
apiErr = ErrSlowDown
|
||||
// case objectlock.ErrInvalidRetentionDate:
|
||||
// apiErr = ErrInvalidRetentionDate
|
||||
// case objectlock.ErrPastObjectLockRetainDate:
|
||||
// apiErr = ErrPastObjectLockRetainDate
|
||||
// case objectlock.ErrUnknownWORMModeDirective:
|
||||
// apiErr = ErrUnknownWORMModeDirective
|
||||
// case objectlock.ErrObjectLockInvalidHeaders:
|
||||
// apiErr = ErrObjectLockInvalidHeaders
|
||||
// case objectlock.ErrMalformedXML:
|
||||
// apiErr = ErrMalformedXML
|
||||
}
|
||||
|
||||
// Compression errors
|
||||
switch err {
|
||||
case errInvalidDecompressedSize:
|
||||
apiErr = ErrInvalidDecompressedSize
|
||||
}
|
||||
|
||||
if apiErr != ErrNone {
|
||||
// If there was a match in the above switch case.
|
||||
return apiErr
|
||||
}
|
||||
|
||||
// etcd specific errors, a key is always a bucket for us return
|
||||
// ErrNoSuchBucket in such a case.
|
||||
if err == ErrNoEntriesFound {
|
||||
return ErrNoSuchBucket
|
||||
}
|
||||
|
||||
switch err.(type) {
|
||||
case StorageFull:
|
||||
apiErr = ErrStorageFull
|
||||
// case hash.BadDigest:
|
||||
// apiErr = ErrBadDigest
|
||||
case AllAccessDisabled:
|
||||
apiErr = ErrAllAccessDisabled
|
||||
case IncompleteBody:
|
||||
apiErr = ErrIncompleteBody
|
||||
case ObjectExistsAsDirectory:
|
||||
apiErr = ErrObjectExistsAsDirectory
|
||||
case PrefixAccessDenied:
|
||||
apiErr = ErrAccessDenied
|
||||
case ParentIsObject:
|
||||
apiErr = ErrParentIsObject
|
||||
case BucketNameInvalid:
|
||||
apiErr = ErrInvalidBucketName
|
||||
case BucketNotFound:
|
||||
apiErr = ErrNoSuchBucket
|
||||
case BucketAlreadyOwnedByYou:
|
||||
apiErr = ErrBucketAlreadyOwnedByYou
|
||||
case BucketNotEmpty:
|
||||
apiErr = ErrBucketNotEmpty
|
||||
case BucketAlreadyExists:
|
||||
apiErr = ErrBucketAlreadyExists
|
||||
case BucketExists:
|
||||
apiErr = ErrBucketAlreadyOwnedByYou
|
||||
case ObjectNotFound:
|
||||
apiErr = ErrNoSuchKey
|
||||
case ObjectAlreadyExists:
|
||||
apiErr = ErrMethodNotAllowed
|
||||
case ObjectNameInvalid:
|
||||
apiErr = ErrInvalidObjectName
|
||||
case ObjectNamePrefixAsSlash:
|
||||
apiErr = ErrInvalidObjectNamePrefixSlash
|
||||
case InvalidUploadID:
|
||||
apiErr = ErrNoSuchUpload
|
||||
case InvalidPart:
|
||||
apiErr = ErrInvalidPart
|
||||
case InsufficientWriteQuorum:
|
||||
apiErr = ErrSlowDown
|
||||
case InsufficientReadQuorum:
|
||||
apiErr = ErrSlowDown
|
||||
case UnsupportedDelimiter:
|
||||
apiErr = ErrNotImplemented
|
||||
case InvalidMarkerPrefixCombination:
|
||||
apiErr = ErrNotImplemented
|
||||
case InvalidUploadIDKeyCombination:
|
||||
apiErr = ErrNotImplemented
|
||||
case MalformedUploadID:
|
||||
apiErr = ErrNoSuchUpload
|
||||
case PartTooSmall:
|
||||
apiErr = ErrEntityTooSmall
|
||||
case SignatureDoesNotMatch:
|
||||
apiErr = ErrSignatureDoesNotMatch
|
||||
// case hash.SHA256Mismatch:
|
||||
// apiErr = ErrContentSHA256Mismatch
|
||||
case ObjectTooLarge:
|
||||
apiErr = ErrEntityTooLarge
|
||||
case ObjectTooSmall:
|
||||
apiErr = ErrEntityTooSmall
|
||||
case NotImplemented:
|
||||
apiErr = ErrNotImplemented
|
||||
case PartTooBig:
|
||||
apiErr = ErrEntityTooLarge
|
||||
case UnsupportedMetadata:
|
||||
apiErr = ErrUnsupportedMetadata
|
||||
case BucketPolicyNotFound:
|
||||
apiErr = ErrNoSuchBucketPolicy
|
||||
case BucketLifecycleNotFound:
|
||||
apiErr = ErrNoSuchLifecycleConfiguration
|
||||
case BucketSSEConfigNotFound:
|
||||
apiErr = ErrNoSuchBucketSSEConfig
|
||||
case BucketTaggingNotFound:
|
||||
apiErr = ErrBucketTaggingNotFound
|
||||
case BucketObjectLockConfigNotFound:
|
||||
apiErr = ErrObjectLockConfigurationNotFound
|
||||
case BucketQuotaConfigNotFound:
|
||||
apiErr = ErrAdminNoSuchQuotaConfiguration
|
||||
case BucketQuotaExceeded:
|
||||
apiErr = ErrAdminBucketQuotaExceeded
|
||||
// case *event.ErrInvalidEventName:
|
||||
// apiErr = ErrEventNotification
|
||||
// case *event.ErrInvalidARN:
|
||||
// apiErr = ErrARNNotification
|
||||
// case *event.ErrARNNotFound:
|
||||
// apiErr = ErrARNNotification
|
||||
// case *event.ErrUnknownRegion:
|
||||
// apiErr = ErrRegionNotification
|
||||
// case *event.ErrInvalidFilterName:
|
||||
// apiErr = ErrFilterNameInvalid
|
||||
// case *event.ErrFilterNamePrefix:
|
||||
// apiErr = ErrFilterNamePrefix
|
||||
// case *event.ErrFilterNameSuffix:
|
||||
// apiErr = ErrFilterNameSuffix
|
||||
// case *event.ErrInvalidFilterValue:
|
||||
// apiErr = ErrFilterValueInvalid
|
||||
// case *event.ErrDuplicateEventName:
|
||||
// apiErr = ErrOverlappingConfigs
|
||||
// case *event.ErrDuplicateQueueConfiguration:
|
||||
// apiErr = ErrOverlappingFilterNotification
|
||||
// case *event.ErrUnsupportedConfiguration:
|
||||
// apiErr = ErrUnsupportedNotification
|
||||
case OperationTimedOut:
|
||||
apiErr = ErrOperationTimedOut
|
||||
case BackendDown:
|
||||
apiErr = ErrBackendDown
|
||||
case ObjectNameTooLong:
|
||||
apiErr = ErrKeyTooLongError
|
||||
default:
|
||||
var ie, iw int
|
||||
// This work-around is to handle the issue golang/go#30648
|
||||
if _, ferr := fmt.Fscanf(strings.NewReader(err.Error()),
|
||||
"request declared a Content-Length of %d but only wrote %d bytes",
|
||||
&ie, &iw); ferr != nil {
|
||||
apiErr = ErrInternalError
|
||||
// Make sure to log the errors which we cannot translate
|
||||
// to a meaningful S3 API errors. This is added to aid in
|
||||
// debugging unexpected/unhandled errors.
|
||||
// logger.LogIf(ctx, err)
|
||||
} else if ie > iw {
|
||||
apiErr = ErrIncompleteBody
|
||||
} else {
|
||||
apiErr = ErrInternalError
|
||||
// Make sure to log the errors which we cannot translate
|
||||
// to a meaningful S3 API errors. This is added to aid in
|
||||
// debugging unexpected/unhandled errors.
|
||||
// logger.LogIf(ctx, err)
|
||||
}
|
||||
}
|
||||
|
||||
return apiErr
|
||||
}
|
||||
|
||||
var noError = Error{}
|
||||
|
||||
// toAPIError - Converts embedded errors. Convenience
|
||||
// function written to handle all cases where we have known types of
|
||||
// errors returned by underlying layers.
|
||||
func toAPIError(ctx context.Context, err error) Error {
|
||||
if err == nil {
|
||||
return noError
|
||||
}
|
||||
|
||||
var apiErr = errorCodes.ToAPIErr(toAPIErrorCode(ctx, err))
|
||||
if apiErr.Code == "InternalError" {
|
||||
// If we see an internal error try to interpret
|
||||
// any underlying errors if possible depending on
|
||||
// their internal error types. This code is only
|
||||
// useful with gateway implementations.
|
||||
switch e := err.(type) {
|
||||
case *xml.SyntaxError:
|
||||
apiErr = Error{
|
||||
Code: "MalformedXML",
|
||||
Description: fmt.Sprintf("%s (%s)", errorCodes[ErrMalformedXML].Description,
|
||||
e.Error()),
|
||||
HTTPStatusCode: errorCodes[ErrMalformedXML].HTTPStatusCode,
|
||||
}
|
||||
case url.EscapeError:
|
||||
apiErr = Error{
|
||||
Code: "XMinioInvalidObjectName",
|
||||
Description: fmt.Sprintf("%s (%s)", errorCodes[ErrInvalidObjectName].Description,
|
||||
e.Error()),
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
}
|
||||
// case lifecycle.Error:
|
||||
// apiErr = Error{
|
||||
// Code: "InvalidRequest",
|
||||
// Description: e.Error(),
|
||||
// HTTPStatusCode: http.StatusBadRequest,
|
||||
// }
|
||||
case tags.Error:
|
||||
apiErr = Error{
|
||||
Code: e.Code(),
|
||||
Description: e.Error(),
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
}
|
||||
// case policy.Error:
|
||||
// apiErr = Error{
|
||||
// Code: "MalformedPolicy",
|
||||
// Description: e.Error(),
|
||||
// HTTPStatusCode: http.StatusBadRequest,
|
||||
// }
|
||||
case crypto.Error:
|
||||
apiErr = Error{
|
||||
Code: "XMinIOEncryptionError",
|
||||
Description: e.Error(),
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
}
|
||||
case ErrorResponse:
|
||||
apiErr = Error{
|
||||
Code: e.Code,
|
||||
Description: e.Message,
|
||||
HTTPStatusCode: e.StatusCode,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return apiErr
|
||||
}
|
||||
|
||||
// GetAPIError provides API Error for input API error code.
|
||||
func GetAPIError(code ErrorCode) Error {
|
||||
if apiErr, ok := errorCodes[code]; ok {
|
||||
|
@ -1930,8 +1630,366 @@ func getAPIErrorResponse(ctx context.Context, err Error, resource, requestID, ho
|
|||
BucketName: reqInfo.BucketName,
|
||||
Key: reqInfo.ObjectName,
|
||||
Resource: resource,
|
||||
Region: "",
|
||||
RequestID: requestID,
|
||||
HostID: hostID,
|
||||
}
|
||||
}
|
||||
|
||||
// SignatureDoesNotMatch - when content md5 does not match with what was sent from client.
|
||||
type SignatureDoesNotMatch struct{}
|
||||
|
||||
func (e SignatureDoesNotMatch) Error() string {
|
||||
return "The request signature we calculated does not match the signature you provided. Check your key and signing method."
|
||||
}
|
||||
|
||||
// StorageFull storage ran out of space.
|
||||
type StorageFull struct{}
|
||||
|
||||
func (e StorageFull) Error() string {
|
||||
return "Storage reached its minimum free disk threshold."
|
||||
}
|
||||
|
||||
// SlowDown too many file descriptors open or backend busy .
|
||||
type SlowDown struct{}
|
||||
|
||||
func (e SlowDown) Error() string {
|
||||
return "Please reduce your request rate"
|
||||
}
|
||||
|
||||
// InsufficientReadQuorum storage cannot satisfy quorum for read operation.
|
||||
type InsufficientReadQuorum struct{}
|
||||
|
||||
func (e InsufficientReadQuorum) Error() string {
|
||||
return "Storage resources are insufficient for the read operation."
|
||||
}
|
||||
|
||||
// InsufficientWriteQuorum storage cannot satisfy quorum for write operation.
|
||||
type InsufficientWriteQuorum struct{}
|
||||
|
||||
func (e InsufficientWriteQuorum) Error() string {
|
||||
return "Storage resources are insufficient for the write operation."
|
||||
}
|
||||
|
||||
// GenericError - generic object layer error.
|
||||
type GenericError struct {
|
||||
Bucket string
|
||||
Object string
|
||||
}
|
||||
|
||||
// BucketNotFound bucket does not exist.
|
||||
type BucketNotFound GenericError
|
||||
|
||||
func (e BucketNotFound) Error() string {
|
||||
return "Bucket not found: " + e.Bucket
|
||||
}
|
||||
|
||||
// BucketAlreadyExists the requested bucket name is not available.
|
||||
type BucketAlreadyExists GenericError
|
||||
|
||||
func (e BucketAlreadyExists) Error() string {
|
||||
return "The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again."
|
||||
}
|
||||
|
||||
// BucketAlreadyOwnedByYou already owned by you.
|
||||
type BucketAlreadyOwnedByYou GenericError
|
||||
|
||||
func (e BucketAlreadyOwnedByYou) Error() string {
|
||||
return "Bucket already owned by you: " + e.Bucket
|
||||
}
|
||||
|
||||
// BucketNotEmpty bucket is not empty.
|
||||
type BucketNotEmpty GenericError
|
||||
|
||||
func (e BucketNotEmpty) Error() string {
|
||||
return "Bucket not empty: " + e.Bucket
|
||||
}
|
||||
|
||||
// ObjectNotFound object does not exist.
|
||||
type ObjectNotFound GenericError
|
||||
|
||||
func (e ObjectNotFound) Error() string {
|
||||
return "Object not found: " + e.Bucket + "#" + e.Object
|
||||
}
|
||||
|
||||
// ObjectAlreadyExists object already exists.
|
||||
type ObjectAlreadyExists GenericError
|
||||
|
||||
func (e ObjectAlreadyExists) Error() string {
|
||||
return "Object: " + e.Bucket + "#" + e.Object + " already exists"
|
||||
}
|
||||
|
||||
// ObjectExistsAsDirectory object already exists as a directory.
|
||||
type ObjectExistsAsDirectory GenericError
|
||||
|
||||
func (e ObjectExistsAsDirectory) Error() string {
|
||||
return "Object exists on : " + e.Bucket + " as directory " + e.Object
|
||||
}
|
||||
|
||||
// PrefixAccessDenied object access is denied.
|
||||
type PrefixAccessDenied GenericError
|
||||
|
||||
func (e PrefixAccessDenied) Error() string {
|
||||
return "Prefix access is denied: " + e.Bucket + SlashSeparator + e.Object
|
||||
}
|
||||
|
||||
// ParentIsObject object access is denied.
|
||||
type ParentIsObject GenericError
|
||||
|
||||
func (e ParentIsObject) Error() string {
|
||||
return "Parent is object " + e.Bucket + SlashSeparator + path.Dir(e.Object)
|
||||
}
|
||||
|
||||
// BucketExists bucket exists.
|
||||
type BucketExists GenericError
|
||||
|
||||
func (e BucketExists) Error() string {
|
||||
return "Bucket exists: " + e.Bucket
|
||||
}
|
||||
|
||||
// UnsupportedDelimiter - unsupported delimiter.
|
||||
type UnsupportedDelimiter struct {
|
||||
Delimiter string
|
||||
}
|
||||
|
||||
func (e UnsupportedDelimiter) Error() string {
|
||||
return fmt.Sprintf("delimiter '%s' is not supported. Only '/' is supported", e.Delimiter)
|
||||
}
|
||||
|
||||
// InvalidUploadIDKeyCombination - invalid upload id and key marker combination.
|
||||
type InvalidUploadIDKeyCombination struct {
|
||||
UploadIDMarker, KeyMarker string
|
||||
}
|
||||
|
||||
func (e InvalidUploadIDKeyCombination) Error() string {
|
||||
return fmt.Sprintf("Invalid combination of uploadID marker '%s' and marker '%s'", e.UploadIDMarker, e.KeyMarker)
|
||||
}
|
||||
|
||||
// InvalidMarkerPrefixCombination - invalid marker and prefix combination.
|
||||
type InvalidMarkerPrefixCombination struct {
|
||||
Marker, Prefix string
|
||||
}
|
||||
|
||||
func (e InvalidMarkerPrefixCombination) Error() string {
|
||||
return fmt.Sprintf("Invalid combination of marker '%s' and prefix '%s'", e.Marker, e.Prefix)
|
||||
}
|
||||
|
||||
// BucketPolicyNotFound - no bucket policy found.
|
||||
type BucketPolicyNotFound GenericError
|
||||
|
||||
func (e BucketPolicyNotFound) Error() string {
|
||||
return "No bucket policy configuration found for bucket: " + e.Bucket
|
||||
}
|
||||
|
||||
// BucketLifecycleNotFound - no bucket lifecycle found.
|
||||
type BucketLifecycleNotFound GenericError
|
||||
|
||||
func (e BucketLifecycleNotFound) Error() string {
|
||||
return "No bucket lifecycle configuration found for bucket : " + e.Bucket
|
||||
}
|
||||
|
||||
// BucketSSEConfigNotFound - no bucket encryption found
|
||||
type BucketSSEConfigNotFound GenericError
|
||||
|
||||
func (e BucketSSEConfigNotFound) Error() string {
|
||||
return "No bucket encryption configuration found for bucket: " + e.Bucket
|
||||
}
|
||||
|
||||
// BucketTaggingNotFound - no bucket tags found
|
||||
type BucketTaggingNotFound GenericError
|
||||
|
||||
func (e BucketTaggingNotFound) Error() string {
|
||||
return "No bucket tags found for bucket: " + e.Bucket
|
||||
}
|
||||
|
||||
// BucketObjectLockConfigNotFound - no bucket object lock config found
|
||||
type BucketObjectLockConfigNotFound GenericError
|
||||
|
||||
func (e BucketObjectLockConfigNotFound) Error() string {
|
||||
return "No bucket object lock configuration found for bucket: " + e.Bucket
|
||||
}
|
||||
|
||||
// BucketQuotaConfigNotFound - no bucket quota config found.
|
||||
type BucketQuotaConfigNotFound GenericError
|
||||
|
||||
func (e BucketQuotaConfigNotFound) Error() string {
|
||||
return "No quota config found for bucket : " + e.Bucket
|
||||
}
|
||||
|
||||
// BucketQuotaExceeded - bucket quota exceeded.
|
||||
type BucketQuotaExceeded GenericError
|
||||
|
||||
func (e BucketQuotaExceeded) Error() string {
|
||||
return "Bucket quota exceeded for bucket: " + e.Bucket
|
||||
}
|
||||
|
||||
// Bucket related errors.
|
||||
|
||||
// BucketNameInvalid - bucketname provided is invalid.
|
||||
type BucketNameInvalid GenericError
|
||||
|
||||
// Error returns string an error formatted as the given text.
|
||||
func (e BucketNameInvalid) Error() string {
|
||||
return "Bucket name invalid: " + e.Bucket
|
||||
}
|
||||
|
||||
// Object related errors.
|
||||
|
||||
// ObjectNameInvalid - object name provided is invalid.
|
||||
type ObjectNameInvalid GenericError
|
||||
|
||||
// ObjectNameTooLong - object name too long.
|
||||
type ObjectNameTooLong GenericError
|
||||
|
||||
// ObjectNamePrefixAsSlash - object name has a slash as prefix.
|
||||
type ObjectNamePrefixAsSlash GenericError
|
||||
|
||||
// Error returns string an error formatted as the given text.
|
||||
func (e ObjectNameInvalid) Error() string {
|
||||
return "Object name invalid: " + e.Bucket + "#" + e.Object
|
||||
}
|
||||
|
||||
// Error returns string an error formatted as the given text.
|
||||
func (e ObjectNameTooLong) Error() string {
|
||||
return "Object name too long: " + e.Bucket + "#" + e.Object
|
||||
}
|
||||
|
||||
// Error returns string an error formatted as the given text.
|
||||
func (e ObjectNamePrefixAsSlash) Error() string {
|
||||
return "Object name contains forward slash as pefix: " + e.Bucket + "#" + e.Object
|
||||
}
|
||||
|
||||
// AllAccessDisabled All access to this object has been disabled
|
||||
type AllAccessDisabled GenericError
|
||||
|
||||
// Error returns string an error formatted as the given text.
|
||||
func (e AllAccessDisabled) Error() string {
|
||||
return "All access to this object has been disabled"
|
||||
}
|
||||
|
||||
// IncompleteBody You did not provide the number of bytes specified by the Content-Length HTTP header.
|
||||
type IncompleteBody GenericError
|
||||
|
||||
// Error returns string an error formatted as the given text.
|
||||
func (e IncompleteBody) Error() string {
|
||||
return e.Bucket + "#" + e.Object + "has incomplete body"
|
||||
}
|
||||
|
||||
// InvalidRange - invalid range typed error.
|
||||
type InvalidRange struct {
|
||||
OffsetBegin int64
|
||||
OffsetEnd int64
|
||||
ResourceSize int64
|
||||
}
|
||||
|
||||
func (e InvalidRange) Error() string {
|
||||
return fmt.Sprintf("The requested range \"bytes %d-%d/%d\" is not satisfiable.", e.OffsetBegin, e.OffsetEnd, e.ResourceSize)
|
||||
}
|
||||
|
||||
// ObjectTooLarge error returned when the size of the object > max object size allowed (5G) per request.
|
||||
type ObjectTooLarge GenericError
|
||||
|
||||
func (e ObjectTooLarge) Error() string {
|
||||
return "size of the object greater than what is allowed(5G)"
|
||||
}
|
||||
|
||||
// ObjectTooSmall error returned when the size of the object < what is expected.
|
||||
type ObjectTooSmall GenericError
|
||||
|
||||
func (e ObjectTooSmall) Error() string {
|
||||
return "size of the object less than what is expected"
|
||||
}
|
||||
|
||||
// OperationTimedOut - a timeout occurred.
|
||||
type OperationTimedOut struct {
|
||||
}
|
||||
|
||||
func (e OperationTimedOut) Error() string {
|
||||
return "Operation timed out"
|
||||
}
|
||||
|
||||
// Multipart related errors.
|
||||
|
||||
// MalformedUploadID malformed upload id.
|
||||
type MalformedUploadID struct {
|
||||
UploadID string
|
||||
}
|
||||
|
||||
func (e MalformedUploadID) Error() string {
|
||||
return "Malformed upload id " + e.UploadID
|
||||
}
|
||||
|
||||
// InvalidUploadID invalid upload id.
|
||||
type InvalidUploadID struct {
|
||||
Bucket string
|
||||
Object string
|
||||
UploadID string
|
||||
}
|
||||
|
||||
func (e InvalidUploadID) Error() string {
|
||||
return "Invalid upload id " + e.UploadID
|
||||
}
|
||||
|
||||
// InvalidPart One or more of the specified parts could not be found
|
||||
type InvalidPart struct {
|
||||
PartNumber int
|
||||
ExpETag string
|
||||
GotETag string
|
||||
}
|
||||
|
||||
func (e InvalidPart) Error() string {
|
||||
return fmt.Sprintf("Specified part could not be found. PartNumber %d, Expected %s, got %s",
|
||||
e.PartNumber, e.ExpETag, e.GotETag)
|
||||
}
|
||||
|
||||
// PartTooSmall - error if part size is less than 5MB.
|
||||
type PartTooSmall struct {
|
||||
PartSize int64
|
||||
PartNumber int
|
||||
PartETag string
|
||||
}
|
||||
|
||||
func (e PartTooSmall) Error() string {
|
||||
return fmt.Sprintf("Part size for %d should be at least 5MB", e.PartNumber)
|
||||
}
|
||||
|
||||
// PartTooBig returned if size of part is bigger than the allowed limit.
|
||||
type PartTooBig struct{}
|
||||
|
||||
func (e PartTooBig) Error() string {
|
||||
return "Part size bigger than the allowed limit"
|
||||
}
|
||||
|
||||
// InvalidETag error returned when the etag has changed on disk
|
||||
type InvalidETag struct{}
|
||||
|
||||
func (e InvalidETag) Error() string {
|
||||
return "etag of the object has changed"
|
||||
}
|
||||
|
||||
// NotImplemented If a feature is not implemented
|
||||
type NotImplemented struct{}
|
||||
|
||||
func (e NotImplemented) Error() string {
|
||||
return "Not Implemented"
|
||||
}
|
||||
|
||||
// UnsupportedMetadata - unsupported metadata
|
||||
type UnsupportedMetadata struct{}
|
||||
|
||||
func (e UnsupportedMetadata) Error() string {
|
||||
return "Unsupported headers in Metadata"
|
||||
}
|
||||
|
||||
// BackendDown is returned for network errors or if the gateway's backend is down.
|
||||
type BackendDown struct{}
|
||||
|
||||
func (e BackendDown) Error() string {
|
||||
return "Backend down"
|
||||
}
|
||||
|
||||
// PreConditionFailed - Check if copy precondition failed
|
||||
type PreConditionFailed struct{}
|
||||
|
||||
func (e PreConditionFailed) Error() string {
|
||||
return "At least one of the pre-conditions you specified did not hold"
|
||||
}
|
|
@ -3,8 +3,8 @@ package handler
|
|||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/minio/minio/neofs/api"
|
||||
"github.com/minio/minio/neofs/layer"
|
||||
"github.com/nspcc-dev/neofs-s3-gate/api"
|
||||
"github.com/nspcc-dev/neofs-s3-gate/api/layer"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
|
@ -3,7 +3,7 @@ package handler
|
|||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/minio/minio/neofs/api"
|
||||
"github.com/nspcc-dev/neofs-s3-gate/api"
|
||||
)
|
||||
|
||||
func (h *handler) ListBucketsHandler(w http.ResponseWriter, r *http.Request) {
|
|
@ -4,10 +4,10 @@ import (
|
|||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio/auth"
|
||||
"github.com/nspcc-dev/neofs-api-go/container"
|
||||
"github.com/nspcc-dev/neofs-api-go/refs"
|
||||
"github.com/nspcc-dev/neofs-api-go/service"
|
||||
"github.com/nspcc-dev/neofs-s3-gate/auth"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
|
@ -7,10 +7,10 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio/neofs/pool"
|
||||
"github.com/nspcc-dev/neofs-api-go/object"
|
||||
"github.com/nspcc-dev/neofs-api-go/refs"
|
||||
"github.com/nspcc-dev/neofs-api-go/service"
|
||||
"github.com/nspcc-dev/neofs-s3-gate/api/pool"
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
)
|
|
@ -5,12 +5,12 @@ import (
|
|||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio/neofs/pool"
|
||||
"github.com/nspcc-dev/neofs-api-go/object"
|
||||
"github.com/nspcc-dev/neofs-api-go/query"
|
||||
"github.com/nspcc-dev/neofs-api-go/refs"
|
||||
"github.com/nspcc-dev/neofs-api-go/service"
|
||||
"github.com/nspcc-dev/neofs-api-go/storagegroup"
|
||||
"github.com/nspcc-dev/neofs-s3-gate/api/pool"
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
)
|
|
@ -49,10 +49,7 @@ type (
|
|||
}
|
||||
)
|
||||
|
||||
const (
|
||||
// TODO: should be imported from routing
|
||||
systemPath = "/system"
|
||||
)
|
||||
const systemPath = "/system"
|
||||
|
||||
var (
|
||||
httpStatsMetric = new(HTTPStats)
|
||||
|
@ -106,12 +103,6 @@ func collectHTTPMetrics(ch chan<- prometheus.Metric) {
|
|||
}
|
||||
}
|
||||
|
||||
func Middleware(h http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
APIStats(r.RequestURI, h.ServeHTTP).ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
func APIStats(api string, f http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
httpStatsMetric.currentS3Requests.Inc(api)
|
|
@ -1,7 +1,7 @@
|
|||
package metrics
|
||||
|
||||
import (
|
||||
"github.com/minio/minio/misc"
|
||||
"github.com/nspcc-dev/neofs-s3-gate/misc"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
|
@ -3,15 +3,11 @@ package pool
|
|||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
crand "crypto/rand"
|
||||
"encoding/binary"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc/grpclog"
|
||||
|
||||
"github.com/nspcc-dev/neofs-api-go/service"
|
||||
"github.com/nspcc-dev/neofs-api-go/state"
|
||||
"github.com/pkg/errors"
|
||||
|
@ -19,6 +15,7 @@ import (
|
|||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/connectivity"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
"google.golang.org/grpc/keepalive"
|
||||
)
|
||||
|
||||
|
@ -121,14 +118,10 @@ func New(cfg *Config) (Pool, error) {
|
|||
grpclog.SetLoggerV2(cfg.GRPCLogger)
|
||||
}
|
||||
|
||||
buf := make([]byte, 8)
|
||||
if _, err := crand.Read(buf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
seed := time.Now().UnixNano()
|
||||
|
||||
seed := binary.BigEndian.Uint64(buf)
|
||||
rand.Seed(int64(seed))
|
||||
cfg.Logger.Info("used random seed", zap.Uint64("seed", seed))
|
||||
rand.Seed(seed)
|
||||
cfg.Logger.Info("used random seed", zap.Int64("seed", seed))
|
||||
|
||||
p.reqHealth = new(state.HealthRequest)
|
||||
p.reqHealth.SetTTL(service.NonForwardingTTL)
|
|
@ -10,7 +10,7 @@ import (
|
|||
"strconv"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/minio/minio/misc"
|
||||
"github.com/nspcc-dev/neofs-s3-gate/misc"
|
||||
)
|
||||
|
||||
type (
|
||||
|
@ -152,7 +152,7 @@ func setCommonHeaders(w http.ResponseWriter) {
|
|||
|
||||
// removeSensitiveHeaders removes confidential encryption
|
||||
// information - e.g. the SSE-C key - from the HTTP headers.
|
||||
// It has the same semantics as RemoveSensitiveEntires.
|
||||
// It has the same semantics as RemoveSensitiveEntries.
|
||||
func removeSensitiveHeaders(h http.Header) {
|
||||
h.Del(hdrSSECustomerKey)
|
||||
h.Del(hdrSSECopyKey)
|
|
@ -4,8 +4,8 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/minio/minio/auth"
|
||||
"github.com/minio/minio/neofs/metrics"
|
||||
"github.com/nspcc-dev/neofs-s3-gate/api/metrics"
|
||||
"github.com/nspcc-dev/neofs-s3-gate/auth"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
@ -79,7 +79,6 @@ type (
|
|||
)
|
||||
|
||||
const (
|
||||
|
||||
// SlashSeparator - slash separator.
|
||||
SlashSeparator = "/"
|
||||
|
|
@ -4,7 +4,7 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/minio/minio/auth"
|
||||
"github.com/nspcc-dev/neofs-s3-gate/auth"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
|
@ -12,13 +12,11 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio/auth"
|
||||
"github.com/minio/minio/neofs/pool"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/minio/minio/misc"
|
||||
|
||||
crypto "github.com/nspcc-dev/neofs-crypto"
|
||||
"github.com/nspcc-dev/neofs-s3-gate/api/pool"
|
||||
"github.com/nspcc-dev/neofs-s3-gate/auth"
|
||||
"github.com/nspcc-dev/neofs-s3-gate/misc"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/spf13/viper"
|
||||
"go.uber.org/zap"
|
||||
|
|
|
@ -7,11 +7,11 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio/auth"
|
||||
"github.com/minio/minio/neofs/api"
|
||||
"github.com/minio/minio/neofs/api/handler"
|
||||
"github.com/minio/minio/neofs/layer"
|
||||
"github.com/minio/minio/neofs/pool"
|
||||
"github.com/nspcc-dev/neofs-s3-gate/api"
|
||||
"github.com/nspcc-dev/neofs-s3-gate/api/handler"
|
||||
"github.com/nspcc-dev/neofs-s3-gate/api/layer"
|
||||
"github.com/nspcc-dev/neofs-s3-gate/api/pool"
|
||||
"github.com/nspcc-dev/neofs-s3-gate/auth"
|
||||
"github.com/spf13/viper"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc/keepalive"
|
||||
|
|
11
go.mod
11
go.mod
|
@ -1,12 +1,11 @@
|
|||
module github.com/minio/minio
|
||||
module github.com/nspcc-dev/neofs-s3-gate
|
||||
|
||||
go 1.13
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/gorilla/mux v1.7.4
|
||||
github.com/klauspost/compress v1.10.10
|
||||
github.com/minio/minio-go/v7 v7.0.3
|
||||
github.com/nspcc-dev/neofs-api-go v1.3.0
|
||||
github.com/nspcc-dev/neofs-crypto v0.3.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
|
@ -15,5 +14,11 @@ require (
|
|||
github.com/spf13/viper v1.7.0
|
||||
go.uber.org/atomic v1.6.0
|
||||
go.uber.org/zap v1.15.0
|
||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 // indirect
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381 // indirect
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae // indirect
|
||||
golang.org/x/text v0.3.3 // indirect
|
||||
google.golang.org/grpc v1.29.1
|
||||
gopkg.in/ini.v1 v1.57.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.8 // indirect
|
||||
)
|
||||
|
|
11
go.sum
11
go.sum
|
@ -182,7 +182,6 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22
|
|||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
|
@ -192,8 +191,6 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL
|
|||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.10.10 h1:a/y8CglcM7gLGYmlbP/stPE5sR3hbhFRUjCBfd/0B3I=
|
||||
github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
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=
|
||||
|
@ -218,12 +215,6 @@ github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcME
|
|||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
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/md5-simd v1.1.0 h1:QPfiOqlZH+Cj9teu0t9b1nTBfPbyTl16Of5MeuShdK4=
|
||||
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
|
||||
github.com/minio/minio-go/v7 v7.0.3 h1:a2VHaXDlKBcB3J5XJhKVfWBRi1+ZmMWFXABQ8TLlWbA=
|
||||
github.com/minio/minio-go/v7 v7.0.3/go.mod h1:TA0CQCjJZHM5SJj9IjqR0NmpmQJ6bCbXifAJ3mUU6Hw=
|
||||
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/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=
|
||||
|
@ -309,7 +300,6 @@ github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4
|
|||
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/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
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=
|
||||
|
@ -317,7 +307,6 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
|
|||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
package crypto
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Error is the generic type for any error happening during decrypting
|
||||
// an object. It indicates that the object itself or its metadata was
|
||||
// modified accidentally or maliciously.
|
||||
type Error struct {
|
||||
err error
|
||||
}
|
||||
|
||||
// Errorf - formats according to a format specifier and returns
|
||||
// the string as a value that satisfies error of type crypto.Error
|
||||
func Errorf(format string, a ...interface{}) error {
|
||||
return Error{err: fmt.Errorf(format, a...)}
|
||||
}
|
||||
|
||||
// Unwrap the internal error.
|
||||
func (e Error) Unwrap() error { return e.err }
|
||||
|
||||
// Error 'error' compatible method.
|
||||
func (e Error) Error() string {
|
||||
if e.err == nil {
|
||||
return "crypto: cause <nil>"
|
||||
}
|
||||
return e.err.Error()
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrInvalidEncryptionMethod indicates that the specified SSE encryption method
|
||||
// is not supported.
|
||||
ErrInvalidEncryptionMethod = Errorf("The encryption method is not supported")
|
||||
|
||||
// ErrInvalidCustomerAlgorithm indicates that the specified SSE-C algorithm
|
||||
// is not supported.
|
||||
ErrInvalidCustomerAlgorithm = Errorf("The SSE-C algorithm is not supported")
|
||||
|
||||
// ErrMissingCustomerKey indicates that the HTTP headers contains no SSE-C client key.
|
||||
ErrMissingCustomerKey = Errorf("The SSE-C request is missing the customer key")
|
||||
|
||||
// ErrMissingCustomerKeyMD5 indicates that the HTTP headers contains no SSE-C client key
|
||||
// MD5 checksum.
|
||||
ErrMissingCustomerKeyMD5 = Errorf("The SSE-C request is missing the customer key MD5")
|
||||
|
||||
// ErrInvalidCustomerKey indicates that the SSE-C client key is not valid - e.g. not a
|
||||
// base64-encoded string or not 256 bits long.
|
||||
ErrInvalidCustomerKey = Errorf("The SSE-C client key is invalid")
|
||||
|
||||
// ErrSecretKeyMismatch indicates that the provided secret key (SSE-C client key / SSE-S3 KMS key)
|
||||
// does not match the secret key used during encrypting the object.
|
||||
ErrSecretKeyMismatch = Errorf("The secret key does not match the secret key used during upload")
|
||||
|
||||
// ErrCustomerKeyMD5Mismatch indicates that the SSE-C key MD5 does not match the
|
||||
// computed MD5 sum. This means that the client provided either the wrong key for
|
||||
// a certain MD5 checksum or the wrong MD5 for a certain key.
|
||||
ErrCustomerKeyMD5Mismatch = Errorf("The provided SSE-C key MD5 does not match the computed MD5 of the SSE-C key")
|
||||
// ErrIncompatibleEncryptionMethod indicates that both SSE-C headers and SSE-S3 headers were specified, and are incompatible
|
||||
// The client needs to remove the SSE-S3 header or the SSE-C headers
|
||||
ErrIncompatibleEncryptionMethod = Errorf("Server side encryption specified with both SSE-C and SSE-S3 headers")
|
||||
|
||||
// ErrKMSAuthLogin is raised when there is a failure authenticating to KMS
|
||||
ErrKMSAuthLogin = Errorf("Vault service did not return auth info")
|
||||
)
|
|
@ -1,474 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"path"
|
||||
)
|
||||
|
||||
// Converts underlying storage error. Convenience function written to
|
||||
// handle all cases where we have known types of errors returned by
|
||||
// underlying storage layer.
|
||||
func toObjectErr(err error, params ...string) error {
|
||||
switch err {
|
||||
case errVolumeNotFound:
|
||||
if len(params) >= 1 {
|
||||
err = BucketNotFound{Bucket: params[0]}
|
||||
}
|
||||
case errVolumeNotEmpty:
|
||||
if len(params) >= 1 {
|
||||
err = BucketNotEmpty{Bucket: params[0]}
|
||||
}
|
||||
case errVolumeExists:
|
||||
if len(params) >= 1 {
|
||||
err = BucketExists{Bucket: params[0]}
|
||||
}
|
||||
case errDiskFull:
|
||||
err = StorageFull{}
|
||||
case errTooManyOpenFiles:
|
||||
err = SlowDown{}
|
||||
case errFileAccessDenied:
|
||||
if len(params) >= 2 {
|
||||
err = PrefixAccessDenied{
|
||||
Bucket: params[0],
|
||||
Object: params[1],
|
||||
}
|
||||
}
|
||||
case errFileParentIsFile:
|
||||
if len(params) >= 2 {
|
||||
err = ParentIsObject{
|
||||
Bucket: params[0],
|
||||
Object: params[1],
|
||||
}
|
||||
}
|
||||
case errIsNotRegular:
|
||||
if len(params) >= 2 {
|
||||
err = ObjectExistsAsDirectory{
|
||||
Bucket: params[0],
|
||||
Object: params[1],
|
||||
}
|
||||
}
|
||||
case errFileNotFound:
|
||||
switch len(params) {
|
||||
case 2:
|
||||
err = ObjectNotFound{
|
||||
Bucket: params[0],
|
||||
Object: params[1],
|
||||
}
|
||||
case 3:
|
||||
err = InvalidUploadID{
|
||||
Bucket: params[0],
|
||||
Object: params[1],
|
||||
UploadID: params[2],
|
||||
}
|
||||
}
|
||||
case errFileNameTooLong:
|
||||
if len(params) >= 2 {
|
||||
err = ObjectNameInvalid{
|
||||
Bucket: params[0],
|
||||
Object: params[1],
|
||||
}
|
||||
}
|
||||
case errDataTooLarge:
|
||||
if len(params) >= 2 {
|
||||
err = ObjectTooLarge{
|
||||
Bucket: params[0],
|
||||
Object: params[1],
|
||||
}
|
||||
}
|
||||
case errDataTooSmall:
|
||||
if len(params) >= 2 {
|
||||
err = ObjectTooSmall{
|
||||
Bucket: params[0],
|
||||
Object: params[1],
|
||||
}
|
||||
}
|
||||
case errXLReadQuorum:
|
||||
err = InsufficientReadQuorum{}
|
||||
case errXLWriteQuorum:
|
||||
err = InsufficientWriteQuorum{}
|
||||
case io.ErrUnexpectedEOF, io.ErrShortWrite:
|
||||
err = IncompleteBody{}
|
||||
case context.Canceled, context.DeadlineExceeded:
|
||||
err = IncompleteBody{}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// SignatureDoesNotMatch - when content md5 does not match with what was sent from client.
|
||||
type SignatureDoesNotMatch struct{}
|
||||
|
||||
func (e SignatureDoesNotMatch) Error() string {
|
||||
return "The request signature we calculated does not match the signature you provided. Check your key and signing method."
|
||||
}
|
||||
|
||||
// StorageFull storage ran out of space.
|
||||
type StorageFull struct{}
|
||||
|
||||
func (e StorageFull) Error() string {
|
||||
return "Storage reached its minimum free disk threshold."
|
||||
}
|
||||
|
||||
// SlowDown too many file descriptors open or backend busy .
|
||||
type SlowDown struct{}
|
||||
|
||||
func (e SlowDown) Error() string {
|
||||
return "Please reduce your request rate"
|
||||
}
|
||||
|
||||
// InsufficientReadQuorum storage cannot satisfy quorum for read operation.
|
||||
type InsufficientReadQuorum struct{}
|
||||
|
||||
func (e InsufficientReadQuorum) Error() string {
|
||||
return "Storage resources are insufficient for the read operation."
|
||||
}
|
||||
|
||||
// InsufficientWriteQuorum storage cannot satisfy quorum for write operation.
|
||||
type InsufficientWriteQuorum struct{}
|
||||
|
||||
func (e InsufficientWriteQuorum) Error() string {
|
||||
return "Storage resources are insufficient for the write operation."
|
||||
}
|
||||
|
||||
// GenericError - generic object layer error.
|
||||
type GenericError struct {
|
||||
Bucket string
|
||||
Object string
|
||||
}
|
||||
|
||||
// BucketNotFound bucket does not exist.
|
||||
type BucketNotFound GenericError
|
||||
|
||||
func (e BucketNotFound) Error() string {
|
||||
return "Bucket not found: " + e.Bucket
|
||||
}
|
||||
|
||||
// BucketAlreadyExists the requested bucket name is not available.
|
||||
type BucketAlreadyExists GenericError
|
||||
|
||||
func (e BucketAlreadyExists) Error() string {
|
||||
return "The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again."
|
||||
}
|
||||
|
||||
// BucketAlreadyOwnedByYou already owned by you.
|
||||
type BucketAlreadyOwnedByYou GenericError
|
||||
|
||||
func (e BucketAlreadyOwnedByYou) Error() string {
|
||||
return "Bucket already owned by you: " + e.Bucket
|
||||
}
|
||||
|
||||
// BucketNotEmpty bucket is not empty.
|
||||
type BucketNotEmpty GenericError
|
||||
|
||||
func (e BucketNotEmpty) Error() string {
|
||||
return "Bucket not empty: " + e.Bucket
|
||||
}
|
||||
|
||||
// ObjectNotFound object does not exist.
|
||||
type ObjectNotFound GenericError
|
||||
|
||||
func (e ObjectNotFound) Error() string {
|
||||
return "Object not found: " + e.Bucket + "#" + e.Object
|
||||
}
|
||||
|
||||
// ObjectAlreadyExists object already exists.
|
||||
type ObjectAlreadyExists GenericError
|
||||
|
||||
func (e ObjectAlreadyExists) Error() string {
|
||||
return "Object: " + e.Bucket + "#" + e.Object + " already exists"
|
||||
}
|
||||
|
||||
// ObjectExistsAsDirectory object already exists as a directory.
|
||||
type ObjectExistsAsDirectory GenericError
|
||||
|
||||
func (e ObjectExistsAsDirectory) Error() string {
|
||||
return "Object exists on : " + e.Bucket + " as directory " + e.Object
|
||||
}
|
||||
|
||||
// PrefixAccessDenied object access is denied.
|
||||
type PrefixAccessDenied GenericError
|
||||
|
||||
func (e PrefixAccessDenied) Error() string {
|
||||
return "Prefix access is denied: " + e.Bucket + SlashSeparator + e.Object
|
||||
}
|
||||
|
||||
// ParentIsObject object access is denied.
|
||||
type ParentIsObject GenericError
|
||||
|
||||
func (e ParentIsObject) Error() string {
|
||||
return "Parent is object " + e.Bucket + SlashSeparator + path.Dir(e.Object)
|
||||
}
|
||||
|
||||
// BucketExists bucket exists.
|
||||
type BucketExists GenericError
|
||||
|
||||
func (e BucketExists) Error() string {
|
||||
return "Bucket exists: " + e.Bucket
|
||||
}
|
||||
|
||||
// UnsupportedDelimiter - unsupported delimiter.
|
||||
type UnsupportedDelimiter struct {
|
||||
Delimiter string
|
||||
}
|
||||
|
||||
func (e UnsupportedDelimiter) Error() string {
|
||||
return fmt.Sprintf("delimiter '%s' is not supported. Only '/' is supported", e.Delimiter)
|
||||
}
|
||||
|
||||
// InvalidUploadIDKeyCombination - invalid upload id and key marker combination.
|
||||
type InvalidUploadIDKeyCombination struct {
|
||||
UploadIDMarker, KeyMarker string
|
||||
}
|
||||
|
||||
func (e InvalidUploadIDKeyCombination) Error() string {
|
||||
return fmt.Sprintf("Invalid combination of uploadID marker '%s' and marker '%s'", e.UploadIDMarker, e.KeyMarker)
|
||||
}
|
||||
|
||||
// InvalidMarkerPrefixCombination - invalid marker and prefix combination.
|
||||
type InvalidMarkerPrefixCombination struct {
|
||||
Marker, Prefix string
|
||||
}
|
||||
|
||||
func (e InvalidMarkerPrefixCombination) Error() string {
|
||||
return fmt.Sprintf("Invalid combination of marker '%s' and prefix '%s'", e.Marker, e.Prefix)
|
||||
}
|
||||
|
||||
// BucketPolicyNotFound - no bucket policy found.
|
||||
type BucketPolicyNotFound GenericError
|
||||
|
||||
func (e BucketPolicyNotFound) Error() string {
|
||||
return "No bucket policy configuration found for bucket: " + e.Bucket
|
||||
}
|
||||
|
||||
// BucketLifecycleNotFound - no bucket lifecycle found.
|
||||
type BucketLifecycleNotFound GenericError
|
||||
|
||||
func (e BucketLifecycleNotFound) Error() string {
|
||||
return "No bucket lifecycle configuration found for bucket : " + e.Bucket
|
||||
}
|
||||
|
||||
// BucketSSEConfigNotFound - no bucket encryption found
|
||||
type BucketSSEConfigNotFound GenericError
|
||||
|
||||
func (e BucketSSEConfigNotFound) Error() string {
|
||||
return "No bucket encryption configuration found for bucket: " + e.Bucket
|
||||
}
|
||||
|
||||
// BucketTaggingNotFound - no bucket tags found
|
||||
type BucketTaggingNotFound GenericError
|
||||
|
||||
func (e BucketTaggingNotFound) Error() string {
|
||||
return "No bucket tags found for bucket: " + e.Bucket
|
||||
}
|
||||
|
||||
// BucketObjectLockConfigNotFound - no bucket object lock config found
|
||||
type BucketObjectLockConfigNotFound GenericError
|
||||
|
||||
func (e BucketObjectLockConfigNotFound) Error() string {
|
||||
return "No bucket object lock configuration found for bucket: " + e.Bucket
|
||||
}
|
||||
|
||||
// BucketQuotaConfigNotFound - no bucket quota config found.
|
||||
type BucketQuotaConfigNotFound GenericError
|
||||
|
||||
func (e BucketQuotaConfigNotFound) Error() string {
|
||||
return "No quota config found for bucket : " + e.Bucket
|
||||
}
|
||||
|
||||
// BucketQuotaExceeded - bucket quota exceeded.
|
||||
type BucketQuotaExceeded GenericError
|
||||
|
||||
func (e BucketQuotaExceeded) Error() string {
|
||||
return "Bucket quota exceeded for bucket: " + e.Bucket
|
||||
}
|
||||
|
||||
// Bucket related errors.
|
||||
|
||||
// BucketNameInvalid - bucketname provided is invalid.
|
||||
type BucketNameInvalid GenericError
|
||||
|
||||
// Error returns string an error formatted as the given text.
|
||||
func (e BucketNameInvalid) Error() string {
|
||||
return "Bucket name invalid: " + e.Bucket
|
||||
}
|
||||
|
||||
// Object related errors.
|
||||
|
||||
// ObjectNameInvalid - object name provided is invalid.
|
||||
type ObjectNameInvalid GenericError
|
||||
|
||||
// ObjectNameTooLong - object name too long.
|
||||
type ObjectNameTooLong GenericError
|
||||
|
||||
// ObjectNamePrefixAsSlash - object name has a slash as prefix.
|
||||
type ObjectNamePrefixAsSlash GenericError
|
||||
|
||||
// Error returns string an error formatted as the given text.
|
||||
func (e ObjectNameInvalid) Error() string {
|
||||
return "Object name invalid: " + e.Bucket + "#" + e.Object
|
||||
}
|
||||
|
||||
// Error returns string an error formatted as the given text.
|
||||
func (e ObjectNameTooLong) Error() string {
|
||||
return "Object name too long: " + e.Bucket + "#" + e.Object
|
||||
}
|
||||
|
||||
// Error returns string an error formatted as the given text.
|
||||
func (e ObjectNamePrefixAsSlash) Error() string {
|
||||
return "Object name contains forward slash as pefix: " + e.Bucket + "#" + e.Object
|
||||
}
|
||||
|
||||
// AllAccessDisabled All access to this object has been disabled
|
||||
type AllAccessDisabled GenericError
|
||||
|
||||
// Error returns string an error formatted as the given text.
|
||||
func (e AllAccessDisabled) Error() string {
|
||||
return "All access to this object has been disabled"
|
||||
}
|
||||
|
||||
// IncompleteBody You did not provide the number of bytes specified by the Content-Length HTTP header.
|
||||
type IncompleteBody GenericError
|
||||
|
||||
// Error returns string an error formatted as the given text.
|
||||
func (e IncompleteBody) Error() string {
|
||||
return e.Bucket + "#" + e.Object + "has incomplete body"
|
||||
}
|
||||
|
||||
// InvalidRange - invalid range typed error.
|
||||
type InvalidRange struct {
|
||||
OffsetBegin int64
|
||||
OffsetEnd int64
|
||||
ResourceSize int64
|
||||
}
|
||||
|
||||
func (e InvalidRange) Error() string {
|
||||
return fmt.Sprintf("The requested range \"bytes %d-%d/%d\" is not satisfiable.", e.OffsetBegin, e.OffsetEnd, e.ResourceSize)
|
||||
}
|
||||
|
||||
// ObjectTooLarge error returned when the size of the object > max object size allowed (5G) per request.
|
||||
type ObjectTooLarge GenericError
|
||||
|
||||
func (e ObjectTooLarge) Error() string {
|
||||
return "size of the object greater than what is allowed(5G)"
|
||||
}
|
||||
|
||||
// ObjectTooSmall error returned when the size of the object < what is expected.
|
||||
type ObjectTooSmall GenericError
|
||||
|
||||
func (e ObjectTooSmall) Error() string {
|
||||
return "size of the object less than what is expected"
|
||||
}
|
||||
|
||||
// OperationTimedOut - a timeout occurred.
|
||||
type OperationTimedOut struct {
|
||||
}
|
||||
|
||||
func (e OperationTimedOut) Error() string {
|
||||
return "Operation timed out"
|
||||
}
|
||||
|
||||
// Multipart related errors.
|
||||
|
||||
// MalformedUploadID malformed upload id.
|
||||
type MalformedUploadID struct {
|
||||
UploadID string
|
||||
}
|
||||
|
||||
func (e MalformedUploadID) Error() string {
|
||||
return "Malformed upload id " + e.UploadID
|
||||
}
|
||||
|
||||
// InvalidUploadID invalid upload id.
|
||||
type InvalidUploadID struct {
|
||||
Bucket string
|
||||
Object string
|
||||
UploadID string
|
||||
}
|
||||
|
||||
func (e InvalidUploadID) Error() string {
|
||||
return "Invalid upload id " + e.UploadID
|
||||
}
|
||||
|
||||
// InvalidPart One or more of the specified parts could not be found
|
||||
type InvalidPart struct {
|
||||
PartNumber int
|
||||
ExpETag string
|
||||
GotETag string
|
||||
}
|
||||
|
||||
func (e InvalidPart) Error() string {
|
||||
return fmt.Sprintf("Specified part could not be found. PartNumber %d, Expected %s, got %s",
|
||||
e.PartNumber, e.ExpETag, e.GotETag)
|
||||
}
|
||||
|
||||
// PartTooSmall - error if part size is less than 5MB.
|
||||
type PartTooSmall struct {
|
||||
PartSize int64
|
||||
PartNumber int
|
||||
PartETag string
|
||||
}
|
||||
|
||||
func (e PartTooSmall) Error() string {
|
||||
return fmt.Sprintf("Part size for %d should be at least 5MB", e.PartNumber)
|
||||
}
|
||||
|
||||
// PartTooBig returned if size of part is bigger than the allowed limit.
|
||||
type PartTooBig struct{}
|
||||
|
||||
func (e PartTooBig) Error() string {
|
||||
return "Part size bigger than the allowed limit"
|
||||
}
|
||||
|
||||
// InvalidETag error returned when the etag has changed on disk
|
||||
type InvalidETag struct{}
|
||||
|
||||
func (e InvalidETag) Error() string {
|
||||
return "etag of the object has changed"
|
||||
}
|
||||
|
||||
// NotImplemented If a feature is not implemented
|
||||
type NotImplemented struct{}
|
||||
|
||||
func (e NotImplemented) Error() string {
|
||||
return "Not Implemented"
|
||||
}
|
||||
|
||||
// UnsupportedMetadata - unsupported metadata
|
||||
type UnsupportedMetadata struct{}
|
||||
|
||||
func (e UnsupportedMetadata) Error() string {
|
||||
return "Unsupported headers in Metadata"
|
||||
}
|
||||
|
||||
// BackendDown is returned for network errors or if the gateway's backend is down.
|
||||
type BackendDown struct{}
|
||||
|
||||
func (e BackendDown) Error() string {
|
||||
return "Backend down"
|
||||
}
|
||||
|
||||
// isErrBucketNotFound - Check if error type is BucketNotFound.
|
||||
func isErrBucketNotFound(err error) bool {
|
||||
var bkNotFound BucketNotFound
|
||||
return errors.As(err, &bkNotFound)
|
||||
}
|
||||
|
||||
// isErrObjectNotFound - Check if error type is ObjectNotFound.
|
||||
func isErrObjectNotFound(err error) bool {
|
||||
var objNotFound ObjectNotFound
|
||||
return errors.As(err, &objNotFound)
|
||||
}
|
||||
|
||||
// PreConditionFailed - Check if copy precondition failed
|
||||
type PreConditionFailed struct{}
|
||||
|
||||
func (e PreConditionFailed) Error() string {
|
||||
return "At least one of the pre-conditions you specified did not hold"
|
||||
}
|
||||
|
||||
func isErrPreconditionFailed(err error) bool {
|
||||
_, ok := err.(PreConditionFailed)
|
||||
return ok
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
package api
|
||||
|
||||
// errUnexpected - unexpected error, requires manual intervention.
|
||||
var errUnexpected = StorageErr("Unexpected error, please report this issue at https://github.com/minio/minio/issues")
|
||||
|
||||
// errCorruptedFormat - corrupted backend format.
|
||||
var errCorruptedFormat = StorageErr("corrupted backend format, please join https://slack.min.io for assistance")
|
||||
|
||||
// errUnformattedDisk - unformatted disk found.
|
||||
var errUnformattedDisk = StorageErr("unformatted disk found")
|
||||
|
||||
// errUnsupporteDisk - when disk does not support O_DIRECT flag.
|
||||
var errUnsupportedDisk = StorageErr("disk does not support O_DIRECT")
|
||||
|
||||
// errDiskFull - cannot create volume or files when disk is full.
|
||||
var errDiskFull = StorageErr("disk path full")
|
||||
|
||||
// errDiskNotFound - cannot find the underlying configured disk anymore.
|
||||
var errDiskNotFound = StorageErr("disk not found")
|
||||
|
||||
// errFaultyRemoteDisk - remote disk is faulty.
|
||||
var errFaultyRemoteDisk = StorageErr("remote disk is faulty")
|
||||
|
||||
// errFaultyDisk - disk is faulty.
|
||||
var errFaultyDisk = StorageErr("disk is faulty")
|
||||
|
||||
// errDiskAccessDenied - we don't have write permissions on disk.
|
||||
var errDiskAccessDenied = StorageErr("disk access denied")
|
||||
|
||||
// errFileNotFound - cannot find the file.
|
||||
var errFileNotFound = StorageErr("file not found")
|
||||
|
||||
// errTooManyOpenFiles - too many open files.
|
||||
var errTooManyOpenFiles = StorageErr("too many open files")
|
||||
|
||||
// errFileNameTooLong - given file name is too long than supported length.
|
||||
var errFileNameTooLong = StorageErr("file name too long")
|
||||
|
||||
// errVolumeExists - cannot create same volume again.
|
||||
var errVolumeExists = StorageErr("volume already exists")
|
||||
|
||||
// errIsNotRegular - not of regular file type.
|
||||
var errIsNotRegular = StorageErr("not of regular file type")
|
||||
|
||||
// errVolumeNotFound - cannot find the volume.
|
||||
var errVolumeNotFound = StorageErr("volume not found")
|
||||
|
||||
// errVolumeNotEmpty - volume not empty.
|
||||
var errVolumeNotEmpty = StorageErr("volume is not empty")
|
||||
|
||||
// errVolumeAccessDenied - cannot access volume, insufficient permissions.
|
||||
var errVolumeAccessDenied = StorageErr("volume access denied")
|
||||
|
||||
// errFileAccessDenied - cannot access file, insufficient permissions.
|
||||
var errFileAccessDenied = StorageErr("file access denied")
|
||||
|
||||
// errFileCorrupt - file has an unexpected size, or is not readable
|
||||
var errFileCorrupt = StorageErr("file is corrupted")
|
||||
|
||||
// errFileParentIsFile - cannot have overlapping objects, parent is already a file.
|
||||
var errFileParentIsFile = StorageErr("parent is a file")
|
||||
|
||||
// errBitrotHashAlgoInvalid - the algo for bit-rot hash
|
||||
// verification is empty or invalid.
|
||||
var errBitrotHashAlgoInvalid = StorageErr("bit-rot hash algorithm is invalid")
|
||||
|
||||
// errCrossDeviceLink - rename across devices not allowed.
|
||||
var errCrossDeviceLink = StorageErr("Rename across devices not allowed, please fix your backend configuration")
|
||||
|
||||
// errMinDiskSize - cannot create volume or files when disk size is less than threshold.
|
||||
var errMinDiskSize = StorageErr("The disk size is less than 900MiB threshold")
|
||||
|
||||
// errLessData - returned when less data available than what was requested.
|
||||
var errLessData = StorageErr("less data available than what was requested")
|
||||
|
||||
// errMoreData = returned when more data was sent by the caller than what it was supposed to.
|
||||
var errMoreData = StorageErr("more data was sent than what was advertised")
|
||||
|
||||
// StorageErr represents error generated by posix call.
|
||||
type StorageErr string
|
||||
|
||||
func (h StorageErr) Error() string {
|
||||
return string(h)
|
||||
}
|
||||
|
||||
// Collection of basic errors.
|
||||
var baseErrs = []error{
|
||||
errDiskNotFound,
|
||||
errFaultyDisk,
|
||||
errFaultyRemoteDisk,
|
||||
}
|
||||
|
||||
var baseIgnoredErrs = baseErrs
|
|
@ -1,107 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// errInvalidArgument means that input argument is invalid.
|
||||
var errInvalidArgument = errors.New("Invalid arguments specified")
|
||||
|
||||
// errMethodNotAllowed means that method is not allowed.
|
||||
var errMethodNotAllowed = errors.New("Method not allowed")
|
||||
|
||||
// errSignatureMismatch means signature did not match.
|
||||
var errSignatureMismatch = errors.New("Signature does not match")
|
||||
|
||||
// used when we deal with data larger than expected
|
||||
var errSizeUnexpected = errors.New("Data size larger than expected")
|
||||
|
||||
// used when we deal with data with unknown size
|
||||
var errSizeUnspecified = errors.New("Data size is unspecified")
|
||||
|
||||
// When upload object size is greater than 5G in a single PUT/POST operation.
|
||||
var errDataTooLarge = errors.New("Object size larger than allowed limit")
|
||||
|
||||
// When upload object size is less than what was expected.
|
||||
var errDataTooSmall = errors.New("Object size smaller than expected")
|
||||
|
||||
// errServerNotInitialized - server not initialized.
|
||||
var errServerNotInitialized = errors.New("Server not initialized, please try again")
|
||||
|
||||
// errRPCAPIVersionUnsupported - unsupported rpc API version.
|
||||
var errRPCAPIVersionUnsupported = errors.New("Unsupported rpc API version")
|
||||
|
||||
// errServerTimeMismatch - server times are too far apart.
|
||||
var errServerTimeMismatch = errors.New("Server times are too far apart")
|
||||
|
||||
// errInvalidBucketName - bucket name is reserved for MinIO, usually
|
||||
// returned for 'minio', '.minio.sys', buckets with capital letters.
|
||||
var errInvalidBucketName = errors.New("The specified bucket is not valid")
|
||||
|
||||
// errInvalidRange - returned when given range value is not valid.
|
||||
var errInvalidRange = errors.New("Invalid range")
|
||||
|
||||
// errInvalidRangeSource - returned when given range value exceeds
|
||||
// the source object size.
|
||||
var errInvalidRangeSource = errors.New("Range specified exceeds source object size")
|
||||
|
||||
// error returned by disks which are to be initialized are waiting for the
|
||||
// first server to initialize them in distributed set to initialize them.
|
||||
var errNotFirstDisk = errors.New("Not first disk")
|
||||
|
||||
// error returned by first disk waiting to initialize other servers.
|
||||
var errFirstDiskWait = errors.New("Waiting on other disks")
|
||||
|
||||
// error returned when a bucket already exists
|
||||
var errBucketAlreadyExists = errors.New("Your previous request to create the named bucket succeeded and you already own it")
|
||||
|
||||
// error returned for a negative actual size.
|
||||
var errInvalidDecompressedSize = errors.New("Invalid Decompressed Size")
|
||||
|
||||
// error returned in IAM subsystem when user doesn't exist.
|
||||
var errNoSuchUser = errors.New("Specified user does not exist")
|
||||
|
||||
// error returned in IAM subsystem when groups doesn't exist.
|
||||
var errNoSuchGroup = errors.New("Specified group does not exist")
|
||||
|
||||
// error returned in IAM subsystem when a non-empty group needs to be
|
||||
// deleted.
|
||||
var errGroupNotEmpty = errors.New("Specified group is not empty - cannot remove it")
|
||||
|
||||
// error returned in IAM subsystem when policy doesn't exist.
|
||||
var errNoSuchPolicy = errors.New("Specified canned policy does not exist")
|
||||
|
||||
// error returned in IAM subsystem when an external users systems is configured.
|
||||
var errIAMActionNotAllowed = errors.New("Specified IAM action is not allowed with LDAP configuration")
|
||||
|
||||
// error returned in IAM subsystem when IAM sub-system is still being initialized.
|
||||
var errIAMNotInitialized = errors.New("IAM sub-system is being initialized, please try again")
|
||||
|
||||
// error returned when access is denied.
|
||||
var errAccessDenied = errors.New("Do not have enough permissions to access this resource")
|
||||
|
||||
// error returned when object is locked.
|
||||
var errLockedObject = errors.New("Object is WORM protected and cannot be overwritten or deleted")
|
||||
|
||||
var (
|
||||
errInvalidAccessKeyID = errors.New("The access key ID you provided does not exist in our records")
|
||||
errChangeCredNotAllowed = errors.New("Changing access key and secret key not allowed")
|
||||
errAuthentication = errors.New("Authentication failed, check your access credentials")
|
||||
errNoAuthToken = errors.New("JWT token missing")
|
||||
errIncorrectCreds = errors.New("Current access key or secret key is incorrect")
|
||||
errPresignedNotAllowed = errors.New("Unable to generate shareable URL due to lack of read permissions")
|
||||
)
|
||||
|
||||
var (
|
||||
// AWS errors for invalid SSE-C requests.
|
||||
errEncryptedObject = errors.New("The object was stored using a form of SSE")
|
||||
errInvalidSSEParameters = errors.New("The SSE-C key for key-rotation is not correct") // special access denied
|
||||
errKMSNotConfigured = errors.New("KMS not configured for a server side encrypted object")
|
||||
// Additional MinIO errors for SSE-C requests.
|
||||
errObjectTampered = errors.New("The requested object was modified and may be compromised")
|
||||
// error returned when invalid encryption parameters are specified
|
||||
errInvalidEncryptionParameters = errors.New("The encryption parameters are not applicable to this object")
|
||||
)
|
||||
|
||||
// ErrNoEntriesFound - Indicates no entries were found for the given key (directory)
|
||||
var ErrNoEntriesFound = errors.New("No entries found for this key")
|
|
@ -1,12 +0,0 @@
|
|||
package api
|
||||
|
||||
import "errors"
|
||||
|
||||
// errXLReadQuorum - did not meet read quorum.
|
||||
var errXLReadQuorum = errors.New("Read failed. Insufficient number of disks online")
|
||||
|
||||
// errXLWriteQuorum - did not meet write quorum.
|
||||
var errXLWriteQuorum = errors.New("Write failed. Insufficient number of disks online")
|
||||
|
||||
// errNoHealRequired - returned when healing is attempted on a previously healed disks.
|
||||
var errNoHealRequired = errors.New("No healing is required")
|
Loading…
Reference in a new issue