From: Or Friedmann Date: Thu, 15 Oct 2020 15:40:27 +0000 (+0300) Subject: rgw: send headers of quota settings X-Git-Tag: v16.1.0~390^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=706e077a79306f9c1efd66af7e5d9fdb474f629b;p=ceph.git rgw: send headers of quota settings Make the quota settings visible to s3 and swift users rgw send headers of quota settings Fixes: https://tracker.ceph.com/issues/47752 Signed-off-by: Or Friedmann --- diff --git a/examples/boto3/delete_notification.py b/examples/boto3/delete_notification.py index 8e4d3d7b7193..ca5958e52ec1 100755 --- a/examples/boto3/delete_notification.py +++ b/examples/boto3/delete_notification.py @@ -13,7 +13,7 @@ elif len(sys.argv) == 2: bucketname = sys.argv[1] notification_name = "" else: - print 'Usage: ' + sys.argv[0] + ' [notification]' + print('Usage: ' + sys.argv[0] + ' [notification]') sys.exit(1) # endpoint and keys from vstart @@ -30,7 +30,7 @@ client = boto3.client('s3', # deleting all notification configurations on a bucket (without deleting the bucket itself) are extension to AWS S3 API if notification_name == "": - print client.delete_bucket_notification_configuration(Bucket=bucketname) + print(client.delete_bucket_notification_configuration(Bucket=bucketname)) else: - print client.delete_bucket_notification_configuration(Bucket=bucketname, - Notification=notification_name) + print(client.delete_bucket_notification_configuration(Bucket=bucketname, + Notification=notification_name)) diff --git a/examples/boto3/get_notification.py b/examples/boto3/get_notification.py index 6e32198950c6..490c018d4ca2 100755 --- a/examples/boto3/get_notification.py +++ b/examples/boto3/get_notification.py @@ -4,7 +4,7 @@ import boto3 import sys if len(sys.argv) != 3: - print 'Usage: ' + sys.argv[0] + ' ' + print('Usage: ' + sys.argv[0] + ' ') sys.exit(1) # bucket name as first argument @@ -24,5 +24,5 @@ client = boto3.client('s3', # getting a specific notification configuration is an extension to AWS S3 API -print client.get_bucket_notification_configuration(Bucket=bucketname, - Notification=notification_name) +print(client.get_bucket_notification_configuration(Bucket=bucketname, + Notification=notification_name)) diff --git a/examples/boto3/list_unordered.py b/examples/boto3/list_unordered.py index b2339eaa6369..2aa5a8e0608d 100755 --- a/examples/boto3/list_unordered.py +++ b/examples/boto3/list_unordered.py @@ -4,7 +4,7 @@ import boto3 import sys if len(sys.argv) != 2: - print 'Usage: ' + sys.argv[0] + ' ' + print('Usage: ' + sys.argv[0] + ' ') sys.exit(1) # bucket name as first argument @@ -22,4 +22,4 @@ client = boto3.client('s3', # geting an unordered list of objets is an extension to AWS S3 API -print client.list_objects(Bucket=bucketname, AllowUnordered=True) +print(client.list_objects(Bucket=bucketname, AllowUnordered=True)) diff --git a/examples/boto3/notification_filters.py b/examples/boto3/notification_filters.py index a45393c74f9b..2687c8b3aad5 100755 --- a/examples/boto3/notification_filters.py +++ b/examples/boto3/notification_filters.py @@ -4,7 +4,7 @@ import boto3 import sys if len(sys.argv) != 4: - print 'Usage: ' + sys.argv[0] + ' ' + print('Usage: ' + sys.argv[0] + ' ') sys.exit(1) # bucket name as first argument @@ -44,5 +44,5 @@ topic_conf_list = [{'Id': notification_id, } }}] -print client.put_bucket_notification_configuration(Bucket=bucketname, - NotificationConfiguration={'TopicConfigurations': topic_conf_list}) +print(client.put_bucket_notification_configuration(Bucket=bucketname, + NotificationConfiguration={'TopicConfigurations': topic_conf_list})) diff --git a/examples/boto3/service-2.sdk-extras.json b/examples/boto3/service-2.sdk-extras.json index 65883226366f..9ee66730e852 100644 --- a/examples/boto3/service-2.sdk-extras.json +++ b/examples/boto3/service-2.sdk-extras.json @@ -191,12 +191,22 @@ "UsageStatsSummary": { "type": "structure", "members": { - "TotalBytes":{"shape":"TotalBytes"}, + "QuotaMaxBytes":{"shape":"QuotaMaxBytes"}, + "QuotaMaxBuckets":{"shape": "QuotaMaxBuckets"}, + "QuotaMaxObjCount":{"shape":"QuotaMaxObjCount"}, + "QuotaMaxBytesPerBucket":{"shape":"QuotaMaxBytesPerBucket"}, + "QuotaMaxObjCountPerBucket":{"shape":"QuotaMaxObjCountPerBucket"}, + "TotalBytes":{"shape":"TotalBytes"}, "TotalBytesRounded":{"shape":"TotalBytesRounded"}, "TotalEntries":{"shape":"TotalEntries"} } }, - "TotalBytesRounded":{"type":"integer"}, + "QuotaMaxBytes":{"type":"integer"}, + "QuotaMaxBuckets":{"type": "integer"}, + "QuotaMaxObjCount":{"type":"integer"}, + "QuotaMaxBytesPerBucket":{"type":"integer"}, + "QuotaMaxObjCountPerBucket":{"type":"integer"}, + "TotalBytesRounded":{"type":"integer"}, "TotalBytes":{"type":"integer"}, "TotalEntries":{"type":"integer"} }, diff --git a/examples/boto3/topic_with_endpoint.py b/examples/boto3/topic_with_endpoint.py index b6e626e02002..3137cee7d406 100755 --- a/examples/boto3/topic_with_endpoint.py +++ b/examples/boto3/topic_with_endpoint.py @@ -15,7 +15,7 @@ elif len(sys.argv) == 2: topic_name = sys.argv[1] region_name = "" else: - print 'Usage: ' + sys.argv[0] + ' [region name]' + print('Usage: ' + sys.argv[0] + ' [region name]') sys.exit(1) # endpoint and keys from vstart @@ -38,4 +38,4 @@ client = boto3.client('sns', endpoint_args = 'push-endpoint=amqp://127.0.0.1:5672&amqp-exchange=ex1&amqp-ack-level=broker' attributes = {nvp[0] : nvp[1] for nvp in urlparse.parse_qsl(endpoint_args, keep_blank_values=True)} -print client.create_topic(Name=topic_name, Attributes=attributes) +print(client.create_topic(Name=topic_name, Attributes=attributes)) diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index f7cc9069a233..5ec270978a53 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -2414,7 +2414,7 @@ void RGWGetUsage::execute() RGWUsageIter usage_iter; - while (is_truncated) { + while (s->bucket && is_truncated) { op_ret = s->bucket->read_usage(start_epoch, end_epoch, max_entries, &is_truncated, usage_iter, usage); if (op_ret == -ENOENT) { diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index b15b213d2173..ec6f03ad892c 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -1410,6 +1410,14 @@ void RGWGetUsage_ObjStore_S3::send_response() formatter->open_object_section("Stats"); } + // send info about quota config + auto user_info = s->user->get_info(); + encode_json("QuotaMaxBytes", user_info.user_quota.max_size, formatter); + encode_json("QuotaMaxBuckets", user_info.max_buckets, formatter); + encode_json("QuotaMaxObjCount", user_info.user_quota.max_objects, formatter); + encode_json("QuotaMaxBytesPerBucket", user_info.bucket_quota.max_objects, formatter); + encode_json("QuotaMaxObjCountPerBucket", user_info.bucket_quota.max_size, formatter); + // send info about user's capacity utilization encode_json("TotalBytes", stats.size, formatter); encode_json("TotalBytesRounded", stats.size_rounded, formatter); encode_json("TotalEntries", stats.num_objects, formatter); @@ -2140,6 +2148,15 @@ static void dump_bucket_metadata(struct req_state *s, rgw::sal::RGWBucket* bucke { dump_header(s, "X-RGW-Object-Count", static_cast(bucket->get_count())); dump_header(s, "X-RGW-Bytes-Used", static_cast(bucket->get_size())); + // only bucket's owner is allowed to get the quota settings of the account + if (bucket->is_owner(s->user.get())) { + auto user_info = s->user->get_info(); + dump_header(s, "X-RGW-Quota-User-Size", static_cast(user_info.user_quota.max_size)); + dump_header(s, "X-RGW-Quota-User-Objects", static_cast(user_info.user_quota.max_objects)); + dump_header(s, "X-RGW-Quota-Max-Buckets", static_cast(user_info.max_buckets)); + dump_header(s, "X-RGW-Quota-Bucket-Size", static_cast(user_info.bucket_quota.max_size)); + dump_header(s, "X-RGW-Quota-Bucket-Objects", static_cast(user_info.bucket_quota.max_objects)); + } } void RGWStatBucket_ObjStore_S3::send_response() diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index f78008de3a95..aa2e17639985 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -176,7 +176,7 @@ void RGWListBuckets_ObjStore_SWIFT::send_response_begin(bool has_buckets) global_stats, policies_stats, attrs, - user_quota, + s->user->get_info().user_quota, static_cast(*s->user_acl)); dump_errno(s); dump_header(s, "Accept-Ranges", "bytes"); @@ -282,7 +282,7 @@ void RGWListBuckets_ObjStore_SWIFT::send_response_end() global_stats, policies_stats, attrs, - user_quota, + s->user->get_info().user_quota, static_cast(*s->user_acl)); dump_errno(s); end_header(s, nullptr, nullptr, s->formatter->get_len(), true); @@ -556,7 +556,7 @@ void RGWStatAccount_ObjStore_SWIFT::send_response() global_stats, policies_stats, attrs, - user_quota, + s->user->get_info().user_quota, static_cast(*s->user_acl)); }