add some changes
This commit is contained in:
@@ -11,9 +11,9 @@ import (
|
||||
|
||||
// Handler handles HTTP requests for object storage
|
||||
type Handler struct {
|
||||
service *Service
|
||||
service *Service
|
||||
setupService *SetupService
|
||||
logger *logger.Logger
|
||||
logger *logger.Logger
|
||||
}
|
||||
|
||||
// NewHandler creates a new object storage handler
|
||||
@@ -283,3 +283,18 @@ func (h *Handler) DeleteServiceAccount(c *gin.Context) {
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "service account deleted successfully"})
|
||||
}
|
||||
|
||||
// ListObjects lists objects in a bucket
|
||||
func (h *Handler) ListObjects(c *gin.Context) {
|
||||
bucketName := c.Param("name") // Changed from "bucket" to "name" to match route
|
||||
prefix := c.DefaultQuery("prefix", "") // Optional prefix (folder path)
|
||||
|
||||
objects, err := h.service.ListObjects(c.Request.Context(), bucketName, prefix)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to list objects", "bucket", bucketName, "prefix", prefix, "error", err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to list objects: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"objects": objects})
|
||||
}
|
||||
|
||||
@@ -4,23 +4,24 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/atlasos/calypso/internal/common/logger"
|
||||
madmin "github.com/minio/madmin-go/v3"
|
||||
"github.com/minio/minio-go/v7"
|
||||
"github.com/minio/minio-go/v7/pkg/credentials"
|
||||
madmin "github.com/minio/madmin-go/v3"
|
||||
)
|
||||
|
||||
// Service handles MinIO object storage operations
|
||||
type Service struct {
|
||||
client *minio.Client
|
||||
client *minio.Client
|
||||
adminClient *madmin.AdminClient
|
||||
logger *logger.Logger
|
||||
endpoint string
|
||||
accessKey string
|
||||
secretKey string
|
||||
logger *logger.Logger
|
||||
endpoint string
|
||||
accessKey string
|
||||
secretKey string
|
||||
}
|
||||
|
||||
// NewService creates a new MinIO service
|
||||
@@ -54,8 +55,8 @@ func NewService(endpoint, accessKey, secretKey string, log *logger.Logger) (*Ser
|
||||
type Bucket struct {
|
||||
Name string `json:"name"`
|
||||
CreationDate time.Time `json:"creation_date"`
|
||||
Size int64 `json:"size"` // Total size in bytes
|
||||
Objects int64 `json:"objects"` // Number of objects
|
||||
Size int64 `json:"size"` // Total size in bytes
|
||||
Objects int64 `json:"objects"` // Number of objects
|
||||
AccessPolicy string `json:"access_policy"` // private, public-read, public-read-write
|
||||
}
|
||||
|
||||
@@ -153,7 +154,6 @@ func (s *Service) getBucketPolicy(ctx context.Context, bucketName string) string
|
||||
return "private"
|
||||
}
|
||||
|
||||
|
||||
// CreateBucket creates a new bucket
|
||||
func (s *Service) CreateBucket(ctx context.Context, bucketName string) error {
|
||||
err := s.client.MakeBucket(ctx, bucketName, minio.MakeBucketOptions{})
|
||||
@@ -177,6 +177,82 @@ func (s *Service) GetBucketStats(ctx context.Context, bucketName string) (*Bucke
|
||||
return s.getBucketInfo(ctx, bucketName)
|
||||
}
|
||||
|
||||
// Object represents a MinIO object (file or folder)
|
||||
type Object struct {
|
||||
Name string `json:"name"`
|
||||
Key string `json:"key"` // Full path/key
|
||||
Size int64 `json:"size"` // Size in bytes (0 for folders)
|
||||
LastModified time.Time `json:"last_modified"`
|
||||
IsDir bool `json:"is_dir"` // True if this is a folder/prefix
|
||||
ETag string `json:"etag,omitempty"`
|
||||
}
|
||||
|
||||
// ListObjects lists objects in a bucket with optional prefix (folder path)
|
||||
func (s *Service) ListObjects(ctx context.Context, bucketName, prefix string) ([]*Object, error) {
|
||||
// Ensure prefix ends with / if it's not empty and doesn't already end with /
|
||||
if prefix != "" && !strings.HasSuffix(prefix, "/") {
|
||||
prefix += "/"
|
||||
}
|
||||
|
||||
// List objects with prefix
|
||||
objectCh := s.client.ListObjects(ctx, bucketName, minio.ListObjectsOptions{
|
||||
Prefix: prefix,
|
||||
Recursive: false, // Don't recurse, show folders as separate items
|
||||
})
|
||||
|
||||
var objects []*Object
|
||||
seenFolders := make(map[string]bool)
|
||||
|
||||
for object := range objectCh {
|
||||
if object.Err != nil {
|
||||
s.logger.Warn("Error listing object", "bucket", bucketName, "prefix", prefix, "error", object.Err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Extract folder name from object key
|
||||
relativeKey := strings.TrimPrefix(object.Key, prefix)
|
||||
|
||||
// Check if this is a folder (has / in relative path)
|
||||
if strings.Contains(relativeKey, "/") {
|
||||
// Extract folder name (first part before /)
|
||||
folderName := strings.Split(relativeKey, "/")[0]
|
||||
folderKey := prefix + folderName + "/"
|
||||
|
||||
// Only add folder once
|
||||
if !seenFolders[folderKey] {
|
||||
seenFolders[folderKey] = true
|
||||
objects = append(objects, &Object{
|
||||
Name: folderName,
|
||||
Key: folderKey,
|
||||
Size: 0,
|
||||
LastModified: time.Time{},
|
||||
IsDir: true,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// This is a file in the current directory
|
||||
objects = append(objects, &Object{
|
||||
Name: relativeKey,
|
||||
Key: object.Key,
|
||||
Size: object.Size,
|
||||
LastModified: object.LastModified,
|
||||
IsDir: false,
|
||||
ETag: object.ETag,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Sort: folders first, then files, both alphabetically
|
||||
sort.Slice(objects, func(i, j int) bool {
|
||||
if objects[i].IsDir != objects[j].IsDir {
|
||||
return objects[i].IsDir // Folders first
|
||||
}
|
||||
return objects[i].Name < objects[j].Name
|
||||
})
|
||||
|
||||
return objects, nil
|
||||
}
|
||||
|
||||
// User represents a MinIO IAM user
|
||||
type User struct {
|
||||
AccessKey string `json:"access_key"`
|
||||
@@ -229,11 +305,11 @@ func (s *Service) DeleteUser(ctx context.Context, accessKey string) error {
|
||||
|
||||
// ServiceAccount represents a MinIO service account (access key)
|
||||
type ServiceAccount struct {
|
||||
AccessKey string `json:"access_key"`
|
||||
SecretKey string `json:"secret_key,omitempty"` // Only returned on creation
|
||||
ParentUser string `json:"parent_user"`
|
||||
Expiration time.Time `json:"expiration,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
AccessKey string `json:"access_key"`
|
||||
SecretKey string `json:"secret_key,omitempty"` // Only returned on creation
|
||||
ParentUser string `json:"parent_user"`
|
||||
Expiration time.Time `json:"expiration,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// ListServiceAccounts lists all service accounts in MinIO
|
||||
|
||||
Reference in New Issue
Block a user