Browse Source

auto create buckets

pull/7549/head
chrislu 1 week ago
parent
commit
a3af4d4077
  1. 25
      weed/s3api/s3api_bucket_handlers.go
  2. 12
      weed/s3api/s3api_object_handlers_multipart.go
  3. 15
      weed/s3api/s3api_object_handlers_put.go

25
weed/s3api/s3api_bucket_handlers.go

@ -565,6 +565,31 @@ func (s3a *S3ApiServer) checkBucket(r *http.Request, bucket string) s3err.ErrorC
return s3err.ErrNone
}
// autoCreateBucket creates a bucket if it doesn't exist, setting the owner from the request context
func (s3a *S3ApiServer) autoCreateBucket(r *http.Request, bucket string) error {
currentIdentityId := s3_constants.GetIdentityNameFromContext(r)
fn := func(entry *filer_pb.Entry) {
if currentIdentityId != "" {
if entry.Extended == nil {
entry.Extended = make(map[string][]byte)
}
entry.Extended[s3_constants.AmzIdentityId] = []byte(currentIdentityId)
}
}
if err := s3a.mkdir(s3a.option.BucketsPath, bucket, fn); err != nil {
return fmt.Errorf("failed to auto-create bucket %s: %w", bucket, err)
}
// Remove bucket from negative cache after successful creation
if s3a.bucketConfigCache != nil {
s3a.bucketConfigCache.RemoveNegativeCache(bucket)
}
glog.V(1).Infof("Auto-created bucket %s for identity %s", bucket, currentIdentityId)
return nil
}
func (s3a *S3ApiServer) hasAccess(r *http.Request, entry *filer_pb.Entry) bool {
// Check if user is properly authenticated as admin through IAM system
if s3a.isUserAdmin(r) {

12
weed/s3api/s3api_object_handlers_multipart.go

@ -33,8 +33,16 @@ const (
func (s3a *S3ApiServer) NewMultipartUploadHandler(w http.ResponseWriter, r *http.Request) {
bucket, object := s3_constants.GetBucketAndObject(r)
// Check if bucket exists before creating multipart upload
if err := s3a.checkBucket(r, bucket); err != s3err.ErrNone {
// Check if bucket exists, and create it if it doesn't (auto-create bucket)
if err := s3a.checkBucket(r, bucket); err == s3err.ErrNoSuchBucket {
// Auto-create bucket if it doesn't exist
if mkdirErr := s3a.autoCreateBucket(r, bucket); mkdirErr != nil {
glog.Errorf("NewMultipartUploadHandler: %v", mkdirErr)
s3err.WriteErrorResponse(w, r, s3err.ErrInternalError)
return
}
} else if err != s3err.ErrNone {
// Other errors (like access denied) should still fail
s3err.WriteErrorResponse(w, r, err)
return
}

15
weed/s3api/s3api_object_handlers_put.go

@ -135,12 +135,19 @@ func (s3a *S3ApiServer) PutObjectHandler(w http.ResponseWriter, r *http.Request)
versioningState, err := s3a.getVersioningState(bucket)
if err != nil {
if errors.Is(err, filer_pb.ErrNotFound) {
s3err.WriteErrorResponse(w, r, s3err.ErrNoSuchBucket)
// Auto-create bucket if it doesn't exist
if mkdirErr := s3a.autoCreateBucket(r, bucket); mkdirErr != nil {
glog.Errorf("PutObjectHandler: %v", mkdirErr)
s3err.WriteErrorResponse(w, r, s3err.ErrInternalError)
return
}
// After creating the bucket, versioning state is empty (not configured)
versioningState = ""
} else {
glog.Errorf("Error checking versioning status for bucket %s: %v", bucket, err)
s3err.WriteErrorResponse(w, r, s3err.ErrInternalError)
return
}
glog.Errorf("Error checking versioning status for bucket %s: %v", bucket, err)
s3err.WriteErrorResponse(w, r, s3err.ErrInternalError)
return
}
versioningEnabled := (versioningState == s3_constants.VersioningEnabled)

Loading…
Cancel
Save