mirror of https://github.com/minio/minio.git
feat: Add ListBucketsWithMetadata extension API (#13219)
This commit is contained in:
parent
78dc08bdc2
commit
45bcf73185
|
@ -240,6 +240,16 @@ type CommonPrefix struct {
|
|||
type Bucket struct {
|
||||
Name string
|
||||
CreationDate string // time string of format "2006-01-02T15:04:05.000Z"
|
||||
|
||||
// Usage size of the bucket not reflective of
|
||||
// actual usage atomically, but an ever increasing
|
||||
// value.
|
||||
Usage *BucketUsageInfo `xml:"Usage,omitempty"`
|
||||
|
||||
// Provides information about various bucket features
|
||||
// enabled such as versioning, object locking, tagging
|
||||
// quota, replication config etc.
|
||||
Details *BucketDetailsInfo `xml:"Details,omitempty"`
|
||||
}
|
||||
|
||||
// ObjectVersion container for object version metadata
|
||||
|
@ -263,7 +273,7 @@ func (o ObjectVersion) MarshalXML(e *xml.Encoder, start xml.StartElement) error
|
|||
return e.EncodeElement(objectVersionWrapper(o), start)
|
||||
}
|
||||
|
||||
// StringMap is a map[string]string.
|
||||
// StringMap is a map[string]string
|
||||
type StringMap map[string]string
|
||||
|
||||
// MarshalXML - StringMap marshals into XML.
|
||||
|
@ -424,10 +434,12 @@ func generateListBucketsResponse(buckets []BucketInfo) ListBucketsResponse {
|
|||
}
|
||||
|
||||
for _, bucket := range buckets {
|
||||
var listbucket = Bucket{}
|
||||
listbucket.Name = bucket.Name
|
||||
listbucket.CreationDate = bucket.Created.UTC().Format(iso8601TimeFormat)
|
||||
listbuckets = append(listbuckets, listbucket)
|
||||
listbuckets = append(listbuckets, Bucket{
|
||||
Name: bucket.Name,
|
||||
CreationDate: bucket.Created.UTC().Format(iso8601TimeFormat),
|
||||
Usage: bucket.Usage,
|
||||
Details: bucket.Details,
|
||||
})
|
||||
}
|
||||
|
||||
data.Owner = owner
|
||||
|
|
|
@ -306,6 +306,8 @@ func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.R
|
|||
return
|
||||
}
|
||||
|
||||
metadata := r.Form.Get("metadata") == "true"
|
||||
|
||||
// If etcd, dns federation configured list buckets from etcd.
|
||||
var bucketsInfo []BucketInfo
|
||||
if globalDNSConfig != nil && globalBucketFederation {
|
||||
|
@ -370,6 +372,49 @@ func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.R
|
|||
}
|
||||
}
|
||||
|
||||
if metadata && !globalIsGateway {
|
||||
usageInfo, err := loadDataUsageFromBackend(ctx, objectAPI)
|
||||
if err != nil {
|
||||
writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
for i, bucket := range bucketsInfo {
|
||||
if bu, ok := usageInfo.BucketsUsage[bucket.Name]; ok {
|
||||
bucketsInfo[i].Usage = &BucketUsageInfo{
|
||||
Size: bu.Size,
|
||||
ObjectsCount: bu.ObjectsCount,
|
||||
ObjectSizesHistogram: StringMap{},
|
||||
}
|
||||
for k, v := range bu.ObjectSizesHistogram {
|
||||
bucketsInfo[i].Usage.ObjectSizesHistogram[k] = fmt.Sprint(v)
|
||||
}
|
||||
} else {
|
||||
bucketsInfo[i].Usage = &BucketUsageInfo{
|
||||
ObjectSizesHistogram: StringMap{},
|
||||
}
|
||||
}
|
||||
lcfg, _ := globalBucketObjectLockSys.Get(bucket.Name)
|
||||
quota, _ := globalBucketQuotaSys.Get(bucket.Name)
|
||||
var bquota *BucketQuotaConfig
|
||||
if quota != nil {
|
||||
bquota = &BucketQuotaConfig{
|
||||
Quota: quota.Quota,
|
||||
Type: quota.Type,
|
||||
}
|
||||
}
|
||||
rcfg, _ := globalBucketMetadataSys.GetReplicationConfig(ctx, bucket.Name)
|
||||
tcfg, _ := globalBucketMetadataSys.GetTaggingConfig(bucket.Name)
|
||||
bucketsInfo[i].Details = &BucketDetailsInfo{
|
||||
Versioning: globalBucketVersioningSys.Enabled(bucket.Name),
|
||||
VersioningSuspended: globalBucketVersioningSys.Suspended(bucket.Name),
|
||||
Replication: rcfg != nil,
|
||||
Locking: lcfg.LockEnabled,
|
||||
Quota: bquota,
|
||||
Tagging: tcfg,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate response.
|
||||
response := generateListBucketsResponse(bucketsInfo)
|
||||
encodedSuccessResponse := encodeResponse(response)
|
||||
|
|
|
@ -104,7 +104,10 @@ func (er erasureObjects) getBucketInfo(ctx context.Context, bucketName string) (
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bucketsInfo[index] = BucketInfo(volInfo)
|
||||
bucketsInfo[index] = BucketInfo{
|
||||
Name: volInfo.Name,
|
||||
Created: volInfo.Created,
|
||||
}
|
||||
return nil
|
||||
}, index)
|
||||
}
|
||||
|
|
|
@ -859,7 +859,10 @@ func (s *erasureSets) ListBuckets(ctx context.Context) (buckets []BucketInfo, er
|
|||
}
|
||||
|
||||
for _, v := range healBuckets {
|
||||
listBuckets = append(listBuckets, BucketInfo(v))
|
||||
listBuckets = append(listBuckets, BucketInfo{
|
||||
Name: v.Name,
|
||||
Created: v.Created,
|
||||
})
|
||||
}
|
||||
|
||||
sort.Slice(listBuckets, func(i, j int) bool {
|
||||
|
|
|
@ -24,6 +24,7 @@ import (
|
|||
|
||||
humanize "github.com/dustin/go-humanize"
|
||||
"github.com/minio/madmin-go"
|
||||
"github.com/minio/minio-go/v7/pkg/tags"
|
||||
"github.com/minio/minio/internal/bucket/replication"
|
||||
"github.com/minio/minio/internal/hash"
|
||||
)
|
||||
|
@ -70,6 +71,30 @@ var ObjectsHistogramIntervals = []objectHistogramInterval{
|
|||
{"GREATER_THAN_512_MB", humanize.MiByte * 512, math.MaxInt64},
|
||||
}
|
||||
|
||||
// BucketUsageInfo represents per bucket usage statistics
|
||||
type BucketUsageInfo struct {
|
||||
Size uint64
|
||||
ObjectsCount uint64
|
||||
ObjectSizesHistogram StringMap
|
||||
}
|
||||
|
||||
// BucketQuotaConfig holds bucket quota restrictions
|
||||
type BucketQuotaConfig struct {
|
||||
Quota uint64
|
||||
Type madmin.QuotaType
|
||||
}
|
||||
|
||||
// BucketDetailsInfo provides information about features currently
|
||||
// turned-on per bucket.
|
||||
type BucketDetailsInfo struct {
|
||||
Versioning bool
|
||||
VersioningSuspended bool
|
||||
Locking bool
|
||||
Replication bool
|
||||
Tagging *tags.Tags `xml:",omitempty"`
|
||||
Quota *BucketQuotaConfig `xml:",omitempty"`
|
||||
}
|
||||
|
||||
// BucketInfo - represents bucket metadata.
|
||||
type BucketInfo struct {
|
||||
// Name of the bucket.
|
||||
|
@ -77,6 +102,16 @@ type BucketInfo struct {
|
|||
|
||||
// Date and time when the bucket was created.
|
||||
Created time.Time
|
||||
|
||||
// Usage size of the bucket not reflective of
|
||||
// actual usage atomically, but an ever increasing
|
||||
// value.
|
||||
Usage *BucketUsageInfo `xml:",omitempty"`
|
||||
|
||||
// Provides information about various bucket features
|
||||
// enabled such as versioning, object locking, tagging
|
||||
// quota, replication config etc.
|
||||
Details *BucketDetailsInfo `xml:",omitempty"`
|
||||
}
|
||||
|
||||
// ObjectInfo - represents object metadata.
|
||||
|
|
Loading…
Reference in New Issue