]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/sts: code changes to store multi-valued tags
authorPritha Srivastava <prsrivas@redhat.com>
Sat, 5 Jun 2021 15:42:02 +0000 (21:12 +0530)
committerPritha Srivastava <prsrivas@redhat.com>
Tue, 23 Aug 2022 04:14:46 +0000 (09:44 +0530)
for objects and buckets (to be used as s3:ResourceTags
in Identity and Resource policies).

Test code changes as suggested by Yuval Lifshitz.

Signed-off-by: Pritha Srivastava <prsrivas@redhat.com>
(cherry picked from commit b682db4f6cf9aba4b09d8b323a6593c65c20eff1)

src/rgw/rgw_notify.cc
src/rgw/rgw_pubsub.cc
src/rgw/rgw_pubsub.h
src/rgw/rgw_tag.cc
src/rgw/rgw_tag.h
src/rgw/rgw_tag_s3.cc

index 31e2034d5d50d55e7a839c5851a3d9070e221f3d..8d86b493bd37c07b0f8718d1338002bd8e49d6ec 100644 (file)
@@ -646,7 +646,7 @@ void metadata_from_attributes(const req_state* s, rgw::sal::RGWObject* obj, KeyV
   }
 }
 
-void tags_from_attributes(const req_state* s, rgw::sal::RGWObject* obj, KeyValueMap& tags) {
+void tags_from_attributes(const req_state* s, rgw::sal::RGWObject* obj, KeyMultiValueMap& tags) {
   const auto src_obj = get_object_with_atttributes(s, obj);
   if (!src_obj) {
     return;
@@ -747,7 +747,7 @@ bool notification_match(reservation_t& res, const rgw_pubsub_topic_filter& filte
       }
     } else {
       // try to fetch tags from the attributes
-      KeyValueMap tags;
+      KeyMultiValueMap tags;
       tags_from_attributes(s, obj, tags);
       if (!match(filter.s3_filter.tag_filter, tags)) {
         return false;
index 17d9ae221f60fd4aa2420744aca3bd2451dc2250..8a6341e6e9868eda4aaff687517ad3c2cb7574cb 100644 (file)
@@ -172,6 +172,19 @@ bool match(const rgw_s3_key_value_filter& filter, const KeyValueMap& kv) {
   return std::includes(kv.begin(), kv.end(), filter.kv.begin(), filter.kv.end());
 }
 
+bool match(const rgw_s3_key_value_filter& filter, const KeyMultiValueMap& kv) {
+  // all filter pairs must exist with the same value in the object's metadata/tags
+  // object metadata/tags may include items not in the filter
+  for (auto& filter : filter.kv) {
+    auto result = kv.equal_range(filter.first);
+    if (std::any_of(result.first, result.second, [&filter](const pair<string,string>& p) { return p.second == filter.second;}))
+      continue;
+    else
+      return false;
+  }
+  return true;
+}
+
 bool match(const rgw::notify::EventTypeList& events, rgw::notify::EventType event) {
   // if event list exists, and none of the events in the list matches the event type, filter the message
   if (!events.empty() && std::find(events.begin(), events.end(), event) == events.end()) {
index 958fb9ce2e27f8c18952cd6ce4209ef1347a6eac..096ff3ea6266f3193236857dafbafa917746b657 100644 (file)
@@ -42,6 +42,7 @@ struct rgw_s3_key_filter {
 WRITE_CLASS_ENCODER(rgw_s3_key_filter)
 
 using KeyValueMap = boost::container::flat_map<std::string, std::string>;
+using KeyMultiValueMap = std::multimap<std::string, std::string>;
 
 struct rgw_s3_key_value_filter {
   KeyValueMap kv;
@@ -148,8 +149,13 @@ struct rgw_pubsub_s3_notification {
 
 // return true if the key matches the prefix/suffix/regex rules of the key filter
 bool match(const rgw_s3_key_filter& filter, const std::string& key);
-// return true if the key matches the metadata/tags rules of the metadata/tags filter
+
+// return true if the key matches the metadata rules of the metadata filter
 bool match(const rgw_s3_key_value_filter& filter, const KeyValueMap& kv);
+
+// return true if the key matches the tag rules of the tag filter
+bool match(const rgw_s3_key_value_filter& filter, const KeyMultiValueMap& kv);
+
 // return true if the event type matches (equal or contained in) one of the events in the list
 bool match(const rgw::notify::EventTypeList& events, rgw::notify::EventType event);
 
@@ -252,7 +258,7 @@ struct rgw_pubsub_s3_event {
   // meta data
   KeyValueMap x_meta_map;
   // tags
-  KeyValueMap tags;
+  KeyMultiValueMap tags;
   // opaque data received from the topic
   // could be used to identify the gateway
   std::string opaque_data;
index f43a1824868562dc226eaf411cd031dcde1d8a31..e60a265e7384e3e08f9047e59dd1ca92f0d89a68 100644 (file)
 #include "rgw_tag.h"
 #include "rgw_common.h"
 
-bool RGWObjTags::add_tag(const string&key, const string& val){
-  return tag_map.emplace(std::make_pair(key,val)).second;
+void RGWObjTags::add_tag(const string& key, const string& val){
+  tag_map.emplace(std::make_pair(key,val));
 }
 
-bool RGWObjTags::emplace_tag(std::string&& key, std::string&& val){
-  return tag_map.emplace(std::move(key), std::move(val)).second;
+void RGWObjTags::emplace_tag(std::string&& key, std::string&& val){
+  tag_map.emplace(std::move(key), std::move(val));
 }
 
 int RGWObjTags::check_and_add_tag(const string&key, const string& val){
@@ -26,10 +26,7 @@ int RGWObjTags::check_and_add_tag(const string&key, const string& val){
     return -ERR_INVALID_TAG;
   }
 
-  // if we get a conflicting key, either the XML is malformed or the user
-  // supplied an invalid string
-  if (!add_tag(key,val))
-    return -EINVAL;
+  add_tag(key,val);
 
   return 0;
 }
index e8531031dbf6fbabdb95a818123b96ca8fa6b32f..88a4e6652288a0a45c383df2ce7c9118c3a1d8f3 100644 (file)
@@ -6,12 +6,12 @@
 
 #include <string>
 #include <include/types.h>
-#include <boost/container/flat_map.hpp>
+#include <map>
 
 class RGWObjTags
 {
 public:
-  using tag_map_t = boost::container::flat_map <std::string, std::string>;
+  using tag_map_t = std::multimap <std::string, std::string>;
 
 protected:
   tag_map_t tag_map;
@@ -37,8 +37,8 @@ protected:
   }
 
   void dump(Formatter *f) const;
-  bool add_tag(const std::string& key, const std::string& val="");
-  bool emplace_tag(std::string&& key, std::string&& val);
+  void add_tag(const std::string& key, const std::string& val="");
+  void emplace_tag(std::string&& key, std::string&& val);
   int check_and_add_tag(const std::string& key, const std::string& val="");
   size_t count() const {return tag_map.size();}
   int set_from_string(const std::string& input);
index b03607f73a7e68976e7ad6160e2f39cbc7ce0910..2c352c592030254bf6f076bfe2a47022ab953df9 100644 (file)
@@ -35,9 +35,7 @@ void RGWObjTagSet_S3::decode_xml(XMLObj *obj) {
   for (auto& entry : entries) {
     const std::string& key = entry.get_key();
     const std::string& val = entry.get_val();
-    if (!add_tag(key,val)) {
-      throw RGWXMLDecoder::err("failed to add tag");
-    }
+    add_tag(key,val);
   }
 }