mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2025-11-24 16:53:14 +08:00
optionally set the default retention when creating buckets
This commit is contained in:
@@ -23,15 +23,16 @@ type S3BucketsData struct {
|
||||
}
|
||||
|
||||
type CreateBucketRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Region string `json:"region"`
|
||||
QuotaSize int64 `json:"quota_size"` // Quota size in bytes
|
||||
QuotaUnit string `json:"quota_unit"` // Unit: MB, GB, TB
|
||||
QuotaEnabled bool `json:"quota_enabled"` // Whether quota is enabled
|
||||
VersioningEnabled bool `json:"versioning_enabled"` // Whether versioning is enabled
|
||||
ObjectLockEnabled bool `json:"object_lock_enabled"` // Whether object lock is enabled
|
||||
ObjectLockMode string `json:"object_lock_mode"` // Object lock mode: "GOVERNANCE" or "COMPLIANCE"
|
||||
ObjectLockDuration int32 `json:"object_lock_duration"` // Default retention duration in days
|
||||
Name string `json:"name" binding:"required"`
|
||||
Region string `json:"region"`
|
||||
QuotaSize int64 `json:"quota_size"` // Quota size in bytes
|
||||
QuotaUnit string `json:"quota_unit"` // Unit: MB, GB, TB
|
||||
QuotaEnabled bool `json:"quota_enabled"` // Whether quota is enabled
|
||||
VersioningEnabled bool `json:"versioning_enabled"` // Whether versioning is enabled
|
||||
ObjectLockEnabled bool `json:"object_lock_enabled"` // Whether object lock is enabled
|
||||
ObjectLockMode string `json:"object_lock_mode"` // Object lock mode: "GOVERNANCE" or "COMPLIANCE"
|
||||
SetDefaultRetention bool `json:"set_default_retention"` // Whether to set default retention
|
||||
ObjectLockDuration int32 `json:"object_lock_duration"` // Default retention duration in days
|
||||
}
|
||||
|
||||
// S3 Bucket Management Handlers
|
||||
@@ -105,17 +106,19 @@ func (s *AdminServer) CreateBucket(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// Validate retention duration
|
||||
if req.ObjectLockDuration <= 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Object lock duration must be greater than 0 days"})
|
||||
return
|
||||
// Validate retention duration if default retention is enabled
|
||||
if req.SetDefaultRetention {
|
||||
if req.ObjectLockDuration <= 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Object lock duration must be greater than 0 days when default retention is enabled"})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert quota to bytes
|
||||
quotaBytes := convertQuotaToBytes(req.QuotaSize, req.QuotaUnit)
|
||||
|
||||
err := s.CreateS3BucketWithObjectLock(req.Name, quotaBytes, req.QuotaEnabled, req.VersioningEnabled, req.ObjectLockEnabled, req.ObjectLockMode, req.ObjectLockDuration)
|
||||
err := s.CreateS3BucketWithObjectLock(req.Name, quotaBytes, req.QuotaEnabled, req.VersioningEnabled, req.ObjectLockEnabled, req.ObjectLockMode, req.SetDefaultRetention, req.ObjectLockDuration)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create bucket: " + err.Error()})
|
||||
return
|
||||
@@ -285,11 +288,11 @@ func (s *AdminServer) SetBucketQuota(bucketName string, quotaBytes int64, quotaE
|
||||
|
||||
// CreateS3BucketWithQuota creates a new S3 bucket with quota settings
|
||||
func (s *AdminServer) CreateS3BucketWithQuota(bucketName string, quotaBytes int64, quotaEnabled bool) error {
|
||||
return s.CreateS3BucketWithObjectLock(bucketName, quotaBytes, quotaEnabled, false, false, "", 0)
|
||||
return s.CreateS3BucketWithObjectLock(bucketName, quotaBytes, quotaEnabled, false, false, "", false, 0)
|
||||
}
|
||||
|
||||
// CreateS3BucketWithObjectLock creates a new S3 bucket with quota, versioning, and object lock settings
|
||||
func (s *AdminServer) CreateS3BucketWithObjectLock(bucketName string, quotaBytes int64, quotaEnabled, versioningEnabled, objectLockEnabled bool, objectLockMode string, objectLockDuration int32) error {
|
||||
func (s *AdminServer) CreateS3BucketWithObjectLock(bucketName string, quotaBytes int64, quotaEnabled, versioningEnabled, objectLockEnabled bool, objectLockMode string, setDefaultRetention bool, objectLockDuration int32) error {
|
||||
return s.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error {
|
||||
// First ensure /buckets directory exists
|
||||
_, err := client.CreateEntry(context.Background(), &filer_pb.CreateEntryRequest{
|
||||
@@ -360,13 +363,17 @@ func (s *AdminServer) CreateS3BucketWithObjectLock(bucketName string, quotaBytes
|
||||
|
||||
// Handle Object Lock configuration using shared utilities
|
||||
if objectLockEnabled {
|
||||
// Validate Object Lock parameters
|
||||
if err := s3api.ValidateObjectLockParameters(objectLockEnabled, objectLockMode, objectLockDuration); err != nil {
|
||||
return fmt.Errorf("invalid Object Lock parameters: %w", err)
|
||||
var duration int32 = 0
|
||||
if setDefaultRetention {
|
||||
// Validate Object Lock parameters only when setting default retention
|
||||
if err := s3api.ValidateObjectLockParameters(objectLockEnabled, objectLockMode, objectLockDuration); err != nil {
|
||||
return fmt.Errorf("invalid Object Lock parameters: %w", err)
|
||||
}
|
||||
duration = objectLockDuration
|
||||
}
|
||||
|
||||
// Create Object Lock configuration using shared utility
|
||||
objectLockConfig := s3api.CreateObjectLockConfigurationFromParams(objectLockEnabled, objectLockMode, objectLockDuration)
|
||||
objectLockConfig := s3api.CreateObjectLockConfigurationFromParams(objectLockEnabled, objectLockMode, duration)
|
||||
|
||||
// Store Object Lock configuration in extended attributes using shared utility
|
||||
if err := s3api.StoreObjectLockConfigurationInExtended(bucketEntry, objectLockConfig); err != nil {
|
||||
|
||||
@@ -336,11 +336,22 @@ templ S3Buckets(data dash.S3BucketsData) {
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="objectLockDuration" class="form-label">Default Retention (days)</label>
|
||||
<input type="number" class="form-control" id="objectLockDuration" name="object_lock_duration"
|
||||
placeholder="30" min="1" max="36500" step="1">
|
||||
<div class="form-text">
|
||||
Default retention period for new objects (1-36500 days).
|
||||
<div class="form-check mb-3">
|
||||
<input class="form-check-input" type="checkbox" id="setDefaultRetention" name="set_default_retention">
|
||||
<label class="form-check-label" for="setDefaultRetention">
|
||||
Set Default Retention
|
||||
</label>
|
||||
<div class="form-text">
|
||||
Apply default retention to all new objects in this bucket.
|
||||
</div>
|
||||
</div>
|
||||
<div id="defaultRetentionSettings" style="display: none;">
|
||||
<label for="objectLockDuration" class="form-label">Default Retention (days)</label>
|
||||
<input type="number" class="form-control" id="objectLockDuration" name="object_lock_duration"
|
||||
placeholder="30" min="1" max="36500" step="1">
|
||||
<div class="form-text">
|
||||
Default retention period for new objects (1-36500 days).
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -478,6 +489,8 @@ templ S3Buckets(data dash.S3BucketsData) {
|
||||
const versioningCheckbox = document.getElementById('enableVersioning');
|
||||
const objectLockCheckbox = document.getElementById('enableObjectLock');
|
||||
const objectLockSettings = document.getElementById('objectLockSettings');
|
||||
const setDefaultRetentionCheckbox = document.getElementById('setDefaultRetention');
|
||||
const defaultRetentionSettings = document.getElementById('defaultRetentionSettings');
|
||||
const createBucketForm = document.getElementById('createBucketForm');
|
||||
|
||||
// Toggle quota settings
|
||||
@@ -493,9 +506,17 @@ templ S3Buckets(data dash.S3BucketsData) {
|
||||
versioningCheckbox.disabled = true;
|
||||
} else {
|
||||
versioningCheckbox.disabled = false;
|
||||
// Reset default retention settings when object lock is disabled
|
||||
setDefaultRetentionCheckbox.checked = false;
|
||||
defaultRetentionSettings.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
// Toggle default retention settings
|
||||
setDefaultRetentionCheckbox.addEventListener('change', function() {
|
||||
defaultRetentionSettings.style.display = this.checked ? 'block' : 'none';
|
||||
});
|
||||
|
||||
// Handle form submission
|
||||
createBucketForm.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
@@ -510,11 +531,12 @@ templ S3Buckets(data dash.S3BucketsData) {
|
||||
versioning_enabled: versioningCheckbox.checked,
|
||||
object_lock_enabled: objectLockCheckbox.checked,
|
||||
object_lock_mode: formData.get('object_lock_mode') || 'GOVERNANCE',
|
||||
object_lock_duration: objectLockCheckbox.checked ? parseInt(formData.get('object_lock_duration')) || 30 : 0
|
||||
set_default_retention: setDefaultRetentionCheckbox.checked,
|
||||
object_lock_duration: setDefaultRetentionCheckbox.checked ? parseInt(formData.get('object_lock_duration')) || 30 : 0
|
||||
};
|
||||
|
||||
// Validate object lock settings
|
||||
if (data.object_lock_enabled && data.object_lock_duration <= 0) {
|
||||
if (data.object_lock_enabled && data.set_default_retention && data.object_lock_duration <= 0) {
|
||||
alert('Please enter a valid retention duration for object lock.');
|
||||
return;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user