mirror of
https://github.com/minio/minio.git
synced 2025-01-12 07:23:23 -05:00
Add restrictions of object retention to AWS S3 limits (#8514)
This PR also fixes issues related - Peer notification handler was missing "/" - Missing prometheus metrics for retention APIs
This commit is contained in:
parent
64759189f5
commit
069b8ee8ff
@ -112,21 +112,21 @@ func registerAPIRouter(router *mux.Router, encryptionEnabled, allowSSEKMS bool)
|
|||||||
// DeleteObject
|
// DeleteObject
|
||||||
bucket.Methods(http.MethodDelete).Path("/{object:.+}").HandlerFunc(collectAPIStats("deleteobject", httpTraceAll(api.DeleteObjectHandler)))
|
bucket.Methods(http.MethodDelete).Path("/{object:.+}").HandlerFunc(collectAPIStats("deleteobject", httpTraceAll(api.DeleteObjectHandler)))
|
||||||
// PutObjectLegalHold
|
// PutObjectLegalHold
|
||||||
bucket.Methods(http.MethodPut).Path("/{object:.+}").HandlerFunc(httpTraceHdrs(api.PutObjectLegalHoldHandler)).Queries("legal-hold", "").Queries("versionId", "")
|
bucket.Methods(http.MethodPut).Path("/{object:.+}").HandlerFunc(collectAPIStats("putobjectlegalhold", httpTraceHdrs(api.PutObjectLegalHoldHandler))).Queries("legal-hold", "").Queries("versionId", "")
|
||||||
// GetObjectLegalHold
|
// GetObjectLegalHold
|
||||||
bucket.Methods(http.MethodGet).Path("/{object:.+}").HandlerFunc(httpTraceHdrs(api.GetObjectLegalHoldHandler)).Queries("legal-hold", "").Queries("versionId", "")
|
bucket.Methods(http.MethodGet).Path("/{object:.+}").HandlerFunc(collectAPIStats("getobjectlegalhold", httpTraceHdrs(api.GetObjectLegalHoldHandler))).Queries("legal-hold", "").Queries("versionId", "")
|
||||||
// PutObjectRetention
|
// PutObjectRetention
|
||||||
bucket.Methods(http.MethodPut).Path("/{object:.+}").HandlerFunc(httpTraceHdrs(api.PutObjectRetentionHandler)).Queries("retention", "").Queries("versionId", "")
|
bucket.Methods(http.MethodPut).Path("/{object:.+}").HandlerFunc(collectAPIStats("putobjectretention", httpTraceHdrs(api.PutObjectRetentionHandler))).Queries("retention", "").Queries("versionId", "")
|
||||||
// GetObjectRetention
|
// GetObjectRetention
|
||||||
bucket.Methods(http.MethodGet).Path("/{object:.+}").HandlerFunc(httpTraceHdrs(api.GetObjectRetentionHandler)).Queries("retention", "").Queries("versionId", "")
|
bucket.Methods(http.MethodGet).Path("/{object:.+}").HandlerFunc(collectAPIStats("getobjectretention", httpTraceHdrs(api.GetObjectRetentionHandler))).Queries("retention", "").Queries("versionId", "")
|
||||||
|
|
||||||
/// Bucket operations
|
/// Bucket operations
|
||||||
// GetBucketLocation
|
// GetBucketLocation
|
||||||
bucket.Methods(http.MethodGet).HandlerFunc(collectAPIStats("getbucketlocation", httpTraceAll(api.GetBucketLocationHandler))).Queries("location", "")
|
bucket.Methods(http.MethodGet).HandlerFunc(collectAPIStats("getbucketlocation", httpTraceAll(api.GetBucketLocationHandler))).Queries("location", "")
|
||||||
// GetBucketPolicy
|
// GetBucketPolicy
|
||||||
bucket.Methods("GET").HandlerFunc(collectAPIStats("getbucketpolicy", httpTraceAll(api.GetBucketPolicyHandler))).Queries("policy", "")
|
bucket.Methods(http.MethodGet).HandlerFunc(collectAPIStats("getbucketpolicy", httpTraceAll(api.GetBucketPolicyHandler))).Queries("policy", "")
|
||||||
// GetBucketLifecycle
|
// GetBucketLifecycle
|
||||||
bucket.Methods("GET").HandlerFunc(collectAPIStats("getbucketlifecycle", httpTraceAll(api.GetBucketLifecycleHandler))).Queries("lifecycle", "")
|
bucket.Methods(http.MethodGet).HandlerFunc(collectAPIStats("getbucketlifecycle", httpTraceAll(api.GetBucketLifecycleHandler))).Queries("lifecycle", "")
|
||||||
|
|
||||||
// Dummy Bucket Calls
|
// Dummy Bucket Calls
|
||||||
// GetBucketACL -- this is a dummy call.
|
// GetBucketACL -- this is a dummy call.
|
||||||
@ -153,9 +153,9 @@ func registerAPIRouter(router *mux.Router, encryptionEnabled, allowSSEKMS bool)
|
|||||||
bucket.Methods(http.MethodDelete).HandlerFunc(collectAPIStats("deletebuckettagging", httpTraceAll(api.DeleteBucketTaggingHandler))).Queries("tagging", "")
|
bucket.Methods(http.MethodDelete).HandlerFunc(collectAPIStats("deletebuckettagging", httpTraceAll(api.DeleteBucketTaggingHandler))).Queries("tagging", "")
|
||||||
|
|
||||||
// GetBucketObjectLockConfig
|
// GetBucketObjectLockConfig
|
||||||
bucket.Methods(http.MethodGet).HandlerFunc(httpTraceAll(api.GetBucketObjectLockConfigHandler)).Queries("object-lock", "")
|
bucket.Methods(http.MethodGet).HandlerFunc(collectAPIStats("getbucketobjectlockconfiguration", httpTraceAll(api.GetBucketObjectLockConfigHandler))).Queries("object-lock", "")
|
||||||
// GetBucketVersioning
|
// GetBucketVersioning
|
||||||
bucket.Methods(http.MethodGet).HandlerFunc(httpTraceAll(api.GetBucketVersioningHandler)).Queries("versioning", "")
|
bucket.Methods(http.MethodGet).HandlerFunc(collectAPIStats("getbucketversioning", httpTraceAll(api.GetBucketVersioningHandler))).Queries("versioning", "")
|
||||||
// GetBucketNotification
|
// GetBucketNotification
|
||||||
bucket.Methods(http.MethodGet).HandlerFunc(collectAPIStats("getbucketnotification", httpTraceAll(api.GetBucketNotificationHandler))).Queries("notification", "")
|
bucket.Methods(http.MethodGet).HandlerFunc(collectAPIStats("getbucketnotification", httpTraceAll(api.GetBucketNotificationHandler))).Queries("notification", "")
|
||||||
// ListenBucketNotification
|
// ListenBucketNotification
|
||||||
@ -167,16 +167,16 @@ func registerAPIRouter(router *mux.Router, encryptionEnabled, allowSSEKMS bool)
|
|||||||
// ListBucketVersions
|
// ListBucketVersions
|
||||||
bucket.Methods(http.MethodGet).HandlerFunc(collectAPIStats("listbucketversions", httpTraceAll(api.ListBucketObjectVersionsHandler))).Queries("versions", "")
|
bucket.Methods(http.MethodGet).HandlerFunc(collectAPIStats("listbucketversions", httpTraceAll(api.ListBucketObjectVersionsHandler))).Queries("versions", "")
|
||||||
// ListObjectsV1 (Legacy)
|
// ListObjectsV1 (Legacy)
|
||||||
bucket.Methods("GET").HandlerFunc(collectAPIStats("listobjectsv1", httpTraceAll(api.ListObjectsV1Handler)))
|
bucket.Methods(http.MethodGet).HandlerFunc(collectAPIStats("listobjectsv1", httpTraceAll(api.ListObjectsV1Handler)))
|
||||||
// PutBucketLifecycle
|
// PutBucketLifecycle
|
||||||
bucket.Methods("PUT").HandlerFunc(collectAPIStats("putbucketlifecycle", httpTraceAll(api.PutBucketLifecycleHandler))).Queries("lifecycle", "")
|
bucket.Methods(http.MethodPut).HandlerFunc(collectAPIStats("putbucketlifecycle", httpTraceAll(api.PutBucketLifecycleHandler))).Queries("lifecycle", "")
|
||||||
// PutBucketPolicy
|
// PutBucketPolicy
|
||||||
bucket.Methods("PUT").HandlerFunc(collectAPIStats("putbucketpolicy", httpTraceAll(api.PutBucketPolicyHandler))).Queries("policy", "")
|
bucket.Methods(http.MethodPut).HandlerFunc(collectAPIStats("putbucketpolicy", httpTraceAll(api.PutBucketPolicyHandler))).Queries("policy", "")
|
||||||
|
|
||||||
// PutBucketObjectLockConfig
|
// PutBucketObjectLockConfig
|
||||||
bucket.Methods(http.MethodPut).HandlerFunc(httpTraceAll(api.PutBucketObjectLockConfigHandler)).Queries("object-lock", "")
|
bucket.Methods(http.MethodPut).HandlerFunc(collectAPIStats("putbucketobjectlockconfig", httpTraceAll(api.PutBucketObjectLockConfigHandler))).Queries("object-lock", "")
|
||||||
// PutBucketVersioning
|
// PutBucketVersioning
|
||||||
bucket.Methods(http.MethodPut).HandlerFunc(httpTraceAll(api.PutBucketVersioningHandler)).Queries("versioning", "")
|
bucket.Methods(http.MethodPut).HandlerFunc(collectAPIStats("putbucketversioning", httpTraceAll(api.PutBucketVersioningHandler))).Queries("versioning", "")
|
||||||
// PutBucketNotification
|
// PutBucketNotification
|
||||||
bucket.Methods(http.MethodPut).HandlerFunc(collectAPIStats("putbucketnotification", httpTraceAll(api.PutBucketNotificationHandler))).Queries("notification", "")
|
bucket.Methods(http.MethodPut).HandlerFunc(collectAPIStats("putbucketnotification", httpTraceAll(api.PutBucketNotificationHandler))).Queries("notification", "")
|
||||||
// PutBucket
|
// PutBucket
|
||||||
@ -188,9 +188,9 @@ func registerAPIRouter(router *mux.Router, encryptionEnabled, allowSSEKMS bool)
|
|||||||
// DeleteMultipleObjects
|
// DeleteMultipleObjects
|
||||||
bucket.Methods(http.MethodPost).HandlerFunc(collectAPIStats("deletemultipleobjects", httpTraceAll(api.DeleteMultipleObjectsHandler))).Queries("delete", "")
|
bucket.Methods(http.MethodPost).HandlerFunc(collectAPIStats("deletemultipleobjects", httpTraceAll(api.DeleteMultipleObjectsHandler))).Queries("delete", "")
|
||||||
// DeleteBucketPolicy
|
// DeleteBucketPolicy
|
||||||
bucket.Methods("DELETE").HandlerFunc(collectAPIStats("deletebucketpolicy", httpTraceAll(api.DeleteBucketPolicyHandler))).Queries("policy", "")
|
bucket.Methods(http.MethodDelete).HandlerFunc(collectAPIStats("deletebucketpolicy", httpTraceAll(api.DeleteBucketPolicyHandler))).Queries("policy", "")
|
||||||
// DeleteBucketLifecycle
|
// DeleteBucketLifecycle
|
||||||
bucket.Methods("DELETE").HandlerFunc(collectAPIStats("deletebucketlifecycle", httpTraceAll(api.DeleteBucketLifecycleHandler))).Queries("lifecycle", "")
|
bucket.Methods(http.MethodDelete).HandlerFunc(collectAPIStats("deletebucketlifecycle", httpTraceAll(api.DeleteBucketLifecycleHandler))).Queries("lifecycle", "")
|
||||||
// DeleteBucket
|
// DeleteBucket
|
||||||
bucket.Methods(http.MethodDelete).HandlerFunc(collectAPIStats("deletebucket", httpTraceAll(api.DeleteBucketHandler)))
|
bucket.Methods(http.MethodDelete).HandlerFunc(collectAPIStats("deletebucket", httpTraceAll(api.DeleteBucketHandler)))
|
||||||
}
|
}
|
||||||
|
@ -984,7 +984,9 @@ func (api objectAPIHandlers) PutBucketObjectLockConfigHandler(w http.ResponseWri
|
|||||||
|
|
||||||
config, err := parseObjectLockConfig(r.Body)
|
config, err := parseObjectLockConfig(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMalformedXML), r.URL, guessIsBrowserReq(r))
|
apiErr := errorCodes.ToAPIErr(ErrMalformedXML)
|
||||||
|
apiErr.Description = err.Error()
|
||||||
|
writeErrorResponse(ctx, w, apiErr, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,6 +94,13 @@ type DefaultRetention struct {
|
|||||||
Years *uint64 `xml:"Years"`
|
Years *uint64 `xml:"Years"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Maximum support retention days and years supported by AWS S3.
|
||||||
|
const (
|
||||||
|
// This tested by using `mc lock` command
|
||||||
|
maximumRetentionDays = 36500
|
||||||
|
maximumRetentionYears = 100
|
||||||
|
)
|
||||||
|
|
||||||
// UnmarshalXML - decodes XML data.
|
// UnmarshalXML - decodes XML data.
|
||||||
func (dr *DefaultRetention) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
func (dr *DefaultRetention) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||||
// Make subtype to avoid recursive UnmarshalXML().
|
// Make subtype to avoid recursive UnmarshalXML().
|
||||||
@ -120,10 +127,15 @@ func (dr *DefaultRetention) UnmarshalXML(d *xml.Decoder, start xml.StartElement)
|
|||||||
|
|
||||||
if retention.Days != nil {
|
if retention.Days != nil {
|
||||||
if *retention.Days == 0 {
|
if *retention.Days == 0 {
|
||||||
return fmt.Errorf("Days should not be zero")
|
return fmt.Errorf("Default retention period must be a positive integer value for 'Days'")
|
||||||
|
}
|
||||||
|
if *retention.Days > maximumRetentionDays {
|
||||||
|
return fmt.Errorf("Default retention period too large for 'Days' %w", *retention.Days)
|
||||||
}
|
}
|
||||||
} else if *retention.Years == 0 {
|
} else if *retention.Years == 0 {
|
||||||
return fmt.Errorf("Years should not be zero")
|
return fmt.Errorf("Default retention period must be a positive integer value for 'Years'")
|
||||||
|
} else if *retention.Years > maximumRetentionYears {
|
||||||
|
return fmt.Errorf("Default retention period too large for 'Years' %w", *retention.Years)
|
||||||
}
|
}
|
||||||
|
|
||||||
*dr = DefaultRetention(retention)
|
*dr = DefaultRetention(retention)
|
||||||
|
@ -58,7 +58,7 @@ const (
|
|||||||
peerRESTMethodLog = "/log"
|
peerRESTMethodLog = "/log"
|
||||||
peerRESTMethodHardwareCPUInfo = "/cpuhardwareinfo"
|
peerRESTMethodHardwareCPUInfo = "/cpuhardwareinfo"
|
||||||
peerRESTMethodHardwareNetworkInfo = "/networkhardwareinfo"
|
peerRESTMethodHardwareNetworkInfo = "/networkhardwareinfo"
|
||||||
peerRESTMethodPutBucketObjectLockConfig = "putbucketobjectlockconfig"
|
peerRESTMethodPutBucketObjectLockConfig = "/putbucketobjectlockconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
Loading…
Reference in New Issue
Block a user