@@ -209,6 +209,84 @@ class RGWPutBucketLoggingOp : public RGWDefaultResponseOp {
209209 }
210210};
211211
212+ // Post /<bucket name>/?logging
213+ // actual configuration is XML encoded in the body of the message
214+ class RGWPostBucketLoggingOp : public RGWDefaultResponseOp {
215+ int verify_permission (optional_yield y) override {
216+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition (this , s, false );
217+ if (has_s3_resource_tag)
218+ rgw_iam_add_buckettags (this , s);
219+
220+ if (!verify_bucket_permission (this , s, rgw::IAM::s3PostBucketLogging)) {
221+ return -EACCES;
222+ }
223+
224+ return 0 ;
225+ }
226+
227+ const char * name () const override { return " post_bucket_logging" ; }
228+ RGWOpType get_type () override { return RGW_OP_POST_BUCKET_LOGGING; }
229+ uint32_t op_mask () override { return RGW_OP_TYPE_WRITE; }
230+
231+ void execute (optional_yield y) override {
232+ op_ret = verify_bucket_logging_params (this , s);
233+ if (op_ret < 0 ) {
234+ return ;
235+ }
236+
237+ std::unique_ptr<rgw::sal::Bucket> bucket;
238+ op_ret = driver->load_bucket (this , rgw_bucket (s->bucket_tenant , s->bucket_name ),
239+ &bucket, y);
240+ if (op_ret < 0 ) {
241+ ldpp_dout (this , 1 ) << " ERROR: failed to get bucket '" << s->bucket_name << " ', ret = " << op_ret << dendl;
242+ return ;
243+ }
244+ const auto & bucket_attrs = bucket->get_attrs ();
245+ auto iter = bucket_attrs.find (RGW_ATTR_BUCKET_LOGGING);
246+ if (iter == bucket_attrs.end ()) {
247+ ldpp_dout (this , 1 ) << " WARNING: no logging configured on bucket" << dendl;
248+ return ;
249+ }
250+ rgw::bucketlogging::configuration configuration;
251+ try {
252+ configuration.enabled = true ;
253+ decode (configuration, iter->second );
254+ } catch (buffer::error& err) {
255+ ldpp_dout (this , 1 ) << " ERROR: failed to decode logging attribute '" << RGW_ATTR_BUCKET_LOGGING
256+ << " '. error: " << err.what () << dendl;
257+ op_ret = -EINVAL;
258+ return ;
259+ }
260+
261+ std::unique_ptr<rgw::sal::Bucket> target_bucket;
262+ op_ret = driver->load_bucket (this , rgw_bucket (s->bucket_tenant , configuration.target_bucket ),
263+ &target_bucket, y);
264+ if (op_ret < 0 ) {
265+ ldpp_dout (this , 1 ) << " ERROR: failed to get target bucket '" << configuration.target_bucket << " ', ret = " << op_ret << dendl;
266+ return ;
267+ }
268+ std::string obj_name;
269+ RGWObjVersionTracker objv_tracker;
270+ op_ret = target_bucket->get_logging_object_name (obj_name, configuration.target_prefix , null_yield, this , &objv_tracker);
271+ if (op_ret < 0 ) {
272+ ldpp_dout (this , 1 ) << " ERROR: failed to get pending logging object name from target bucket '" << configuration.target_bucket << " '" << dendl;
273+ return ;
274+ }
275+ op_ret = rgw::bucketlogging::rollover_logging_object (configuration, target_bucket, obj_name, this , null_yield, true , &objv_tracker);
276+ if (op_ret < 0 ) {
277+ ldpp_dout (this , 1 ) << " ERROR: failed to flush pending logging object '" << obj_name
278+ << " ' to target bucket '" << configuration.target_bucket << " '" << dendl;
279+ return ;
280+ }
281+ ldpp_dout (this , 20 ) << " flushed pending logging object '" << obj_name
282+ << " ' to target bucket '" << configuration.target_bucket << " '" << dendl;
283+ }
284+ };
285+
286+ RGWOp* RGWHandler_REST_BucketLogging_S3::create_post_op () {
287+ return new RGWPostBucketLoggingOp ();
288+ }
289+
212290RGWOp* RGWHandler_REST_BucketLogging_S3::create_put_op () {
213291 return new RGWPutBucketLoggingOp ();
214292}
0 commit comments