]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/rgw/rgw_pubsub.cc
update ceph source to reef 18.2.1
[ceph.git] / ceph / src / rgw / rgw_pubsub.cc
index 6ebd87e3fe434ff574e5d2f989c31fcb554aa473..2b0cffd47c1fb72d74d24b257c773dd337eecfc9 100644 (file)
@@ -22,6 +22,27 @@ void set_event_id(std::string& id, const std::string& hash, const utime_t& ts) {
   }
 }
 
+void rgw_s3_key_filter::dump(Formatter *f) const {
+  if (!prefix_rule.empty()) {
+    f->open_object_section("FilterRule");
+    ::encode_json("Name", "prefix", f);
+    ::encode_json("Value", prefix_rule, f);
+    f->close_section();
+  }
+  if (!suffix_rule.empty()) {
+    f->open_object_section("FilterRule");
+    ::encode_json("Name", "suffix", f);
+    ::encode_json("Value", suffix_rule, f);
+    f->close_section();
+  }
+  if (!regex_rule.empty()) {
+    f->open_object_section("FilterRule");
+    ::encode_json("Name", "regex", f);
+    ::encode_json("Value", regex_rule, f);
+    f->close_section();
+  }
+}
+
 bool rgw_s3_key_filter::decode_xml(XMLObj* obj) {
   XMLObjIter iter = obj->find("FilterRule");
   XMLObj *o;
@@ -75,6 +96,15 @@ bool rgw_s3_key_filter::has_content() const {
     return !(prefix_rule.empty() && suffix_rule.empty() && regex_rule.empty());
 }
 
+void rgw_s3_key_value_filter::dump(Formatter *f) const {
+  for (const auto& key_value : kv) {
+    f->open_object_section("FilterRule");
+    ::encode_json("Name", key_value.first, f);
+    ::encode_json("Value", key_value.second, f);
+    f->close_section();
+  }
+}
+
 bool rgw_s3_key_value_filter::decode_xml(XMLObj* obj) {
   kv.clear();
   XMLObjIter iter = obj->find("FilterRule");
@@ -106,6 +136,12 @@ bool rgw_s3_key_value_filter::has_content() const {
     return !kv.empty();
 }
 
+void rgw_s3_filter::dump(Formatter *f) const {
+  encode_json("S3Key", key_filter, f);
+  encode_json("S3Metadata", metadata_filter, f);
+  encode_json("S3Tags", tag_filter, f);
+}
+
 bool rgw_s3_filter::decode_xml(XMLObj* obj) {
     RGWXMLDecoder::decode_xml("S3Key", key_filter, obj);
     RGWXMLDecoder::decode_xml("S3Metadata", metadata_filter, obj);
@@ -343,13 +379,15 @@ void encode_json(const char *name, const rgw::notify::EventTypeList& l, Formatte
 
 void rgw_pubsub_topic_filter::dump(Formatter *f) const
 {
-  encode_json("topic", topic, f);
-  encode_json("events", events, f);
+  encode_json("TopicArn", topic.arn, f);
+  encode_json("Id", s3_id, f);
+  encode_json("Events", events, f);
+  encode_json("Filter", s3_filter, f);
 }
 
 void rgw_pubsub_bucket_topics::dump(Formatter *f) const
 {
-  Formatter::ArraySection s(*f, "topics");
+  Formatter::ArraySection s(*f, "notifications");
   for (auto& t : topics) {
     encode_json(t.first.c_str(), t.second, f);
   }
@@ -359,7 +397,10 @@ void rgw_pubsub_topics::dump(Formatter *f) const
 {
   Formatter::ArraySection s(*f, "topics");
   for (auto& t : topics) {
-    encode_json(t.first.c_str(), t.second, f);
+    auto& topic = t.second;
+    if (topic.name == topic.dest.arn_topic) {
+      encode_json(t.first.c_str(), topic, f);
+    }
   }
 }
 
@@ -472,6 +513,35 @@ int RGWPubSub::get_topic(const DoutPrefixProvider *dpp, const std::string& name,
   return 0;
 }
 
+// from list of bucket topics, find the one that was auto-generated by a notification
+auto find_unique_topic(const rgw_pubsub_bucket_topics &bucket_topics, const std::string &notification_id) {
+  auto it = std::find_if(bucket_topics.topics.begin(), bucket_topics.topics.end(),
+                         [&](const auto& val) { return notification_id == val.second.s3_id; });
+  return it != bucket_topics.topics.end() ?
+         std::optional<std::reference_wrapper<const rgw_pubsub_topic_filter>>(it->second):
+         std::nullopt;
+}
+
+int RGWPubSub::Bucket::get_notification_by_id(const DoutPrefixProvider *dpp, const std::string& notification_id,
+                                              rgw_pubsub_topic_filter& result, optional_yield y) const {
+  rgw_pubsub_bucket_topics bucket_topics;
+  const int ret = read_topics(dpp, bucket_topics, nullptr, y);
+  if (ret < 0) {
+    ldpp_dout(dpp, 1) << "ERROR: failed to read bucket_topics info: ret=" << ret << dendl;
+    return ret;
+  }
+
+  auto iter = find_unique_topic(bucket_topics, notification_id);
+  if (!iter) {
+    ldpp_dout(dpp, 1) << "ERROR: notification was not found" << dendl;
+    return -ENOENT;
+  }
+
+  result = iter->get();
+  return 0;
+}
+
+
 int RGWPubSub::Bucket::create_notification(const DoutPrefixProvider *dpp, const std::string& topic_name, 
     const rgw::notify::EventTypeList& events, optional_yield y) const {
   return create_notification(dpp, topic_name, events, std::nullopt, "", y);
@@ -520,6 +590,12 @@ int RGWPubSub::Bucket::create_notification(const DoutPrefixProvider *dpp, const
 }
 
 int RGWPubSub::Bucket::remove_notification(const DoutPrefixProvider *dpp, const std::string& topic_name, optional_yield y) const
+{
+  return remove_notification_inner(dpp, topic_name, false, y);
+}
+
+int RGWPubSub::Bucket::remove_notification_inner(const DoutPrefixProvider *dpp, const std::string& notification_id,
+                                  bool is_notification_id, optional_yield y) const
 {
   RGWObjVersionTracker objv_tracker;
   rgw_pubsub_bucket_topics bucket_topics;
@@ -530,7 +606,18 @@ int RGWPubSub::Bucket::remove_notification(const DoutPrefixProvider *dpp, const
     return ret;
   }
 
-  if (bucket_topics.topics.erase(topic_name) == 0) {
+
+  std::unique_ptr<std::string> topic_name = std::make_unique<std::string>(notification_id);
+  if(is_notification_id) {
+    auto iter = find_unique_topic(bucket_topics, notification_id);
+    if (!iter) {
+      ldpp_dout(dpp, 1) << "ERROR: notification was not found" << dendl;
+      return -ENOENT;
+    }
+    topic_name = std::make_unique<std::string>(iter->get().topic.name);
+  }
+
+  if (bucket_topics.topics.erase(*topic_name) == 0) {
     ldpp_dout(dpp, 1) << "INFO: no need to remove, topic does not exist" << dendl;
     return 0;
   }
@@ -555,6 +642,11 @@ int RGWPubSub::Bucket::remove_notification(const DoutPrefixProvider *dpp, const
   return 0;
 }
 
+int RGWPubSub::Bucket::remove_notification_by_id(const DoutPrefixProvider *dpp, const std::string& notif_id, optional_yield y) const
+{
+  return remove_notification_inner(dpp, notif_id, true, y);
+}
+
 int RGWPubSub::Bucket::remove_notifications(const DoutPrefixProvider *dpp, optional_yield y) const
 {
   // get all topics on a bucket