summaryrefslogtreecommitdiffstats
path: root/src/rgw
diff options
context:
space:
mode:
authorCasey Bodley <cbodley@redhat.com>2024-03-12 20:34:44 +0100
committerCasey Bodley <cbodley@redhat.com>2024-04-10 19:09:17 +0200
commit47a18487b27064b7b19e60a6bc1647cbec65a043 (patch)
treedc493975a289592892dbebc4eaa8142a9e778da6 /src/rgw
parentrgw/pubsub: verify_topic_permission handles cross-account access (diff)
downloadceph-47a18487b27064b7b19e60a6bc1647cbec65a043.tar.xz
ceph-47a18487b27064b7b19e60a6bc1647cbec65a043.zip
rgw/rados: add index for account topics
Signed-off-by: Casey Bodley <cbodley@redhat.com>
Diffstat (limited to 'src/rgw')
-rw-r--r--src/rgw/CMakeLists.txt1
-rw-r--r--src/rgw/driver/rados/account.cc9
-rw-r--r--src/rgw/driver/rados/account.h5
-rw-r--r--src/rgw/driver/rados/rgw_sal_rados.cc24
-rw-r--r--src/rgw/driver/rados/rgw_sal_rados.h6
-rw-r--r--src/rgw/driver/rados/rgw_service.cc4
-rw-r--r--src/rgw/driver/rados/topic.cc61
-rw-r--r--src/rgw/driver/rados/topic.h9
-rw-r--r--src/rgw/driver/rados/topics.cc109
-rw-r--r--src/rgw/driver/rados/topics.h57
-rw-r--r--src/rgw/rgw_pubsub.cc37
-rw-r--r--src/rgw/rgw_pubsub.h5
-rw-r--r--src/rgw/rgw_sal.h15
-rw-r--r--src/rgw/rgw_sal_dbstore.cc10
-rw-r--r--src/rgw/rgw_sal_dbstore.h9
-rw-r--r--src/rgw/rgw_sal_filter.h9
-rw-r--r--src/rgw/rgw_sal_fwd.h1
17 files changed, 348 insertions, 23 deletions
diff --git a/src/rgw/CMakeLists.txt b/src/rgw/CMakeLists.txt
index a9594fcbcd2..cf214b39c95 100644
--- a/src/rgw/CMakeLists.txt
+++ b/src/rgw/CMakeLists.txt
@@ -206,6 +206,7 @@ set(librgw_common_srcs
driver/rados/sync_fairness.cc
driver/rados/topic.cc
driver/rados/topic_migration.cc
+ driver/rados/topics.cc
driver/rados/users.cc)
list(APPEND librgw_common_srcs
diff --git a/src/rgw/driver/rados/account.cc b/src/rgw/driver/rados/account.cc
index 02a26993227..fc881d07804 100644
--- a/src/rgw/driver/rados/account.cc
+++ b/src/rgw/driver/rados/account.cc
@@ -36,6 +36,7 @@ static constexpr std::string_view buckets_oid_prefix = "buckets.";
static constexpr std::string_view users_oid_prefix = "users.";
static constexpr std::string_view groups_oid_prefix = "groups.";
static constexpr std::string_view roles_oid_prefix = "roles.";
+static constexpr std::string_view topics_oid_prefix = "topics.";
static const std::string account_oid_prefix = "account.";
static constexpr std::string_view name_oid_prefix = "name.";
@@ -72,6 +73,14 @@ rgw_raw_obj get_roles_obj(const RGWZoneParams& zone,
return {zone.account_pool, get_roles_key(account_id)};
}
+static std::string get_topics_key(std::string_view account_id) {
+ return string_cat_reserve(topics_oid_prefix, account_id);
+}
+rgw_raw_obj get_topics_obj(const RGWZoneParams& zone,
+ std::string_view account_id) {
+ return {zone.account_pool, get_topics_key(account_id)};
+}
+
static std::string get_account_key(std::string_view account_id) {
return string_cat_reserve(account_oid_prefix, account_id);
}
diff --git a/src/rgw/driver/rados/account.h b/src/rgw/driver/rados/account.h
index 635f0968200..36d1d10ffd7 100644
--- a/src/rgw/driver/rados/account.h
+++ b/src/rgw/driver/rados/account.h
@@ -61,6 +61,11 @@ rgw_raw_obj get_groups_obj(const RGWZoneParams& zone,
rgw_raw_obj get_roles_obj(const RGWZoneParams& zone,
std::string_view account_id);
+/// Return the rados object that tracks the given account's topics. This
+/// can be used with the cls_user interface in namespace rgwrados::topics.
+rgw_raw_obj get_topics_obj(const RGWZoneParams& zone,
+ std::string_view account_id);
+
/// Read account info by id
int read(const DoutPrefixProvider* dpp,
diff --git a/src/rgw/driver/rados/rgw_sal_rados.cc b/src/rgw/driver/rados/rgw_sal_rados.cc
index 84267e1b3cc..78f76218e84 100644
--- a/src/rgw/driver/rados/rgw_sal_rados.cc
+++ b/src/rgw/driver/rados/rgw_sal_rados.cc
@@ -77,6 +77,7 @@
#include "users.h"
#include "rgw_pubsub.h"
#include "topic.h"
+#include "topics.h"
#define dout_subsys ceph_subsys_rgw
@@ -1693,9 +1694,10 @@ int RadosStore::write_topic_v2(const rgw_pubsub_topic& topic, bool exclusive,
optional_yield y,
const DoutPrefixProvider* dpp)
{
+ librados::Rados& rados = *getRados()->get_rados_handle();
const RGWZoneParams& zone = svc()->zone->get_zone_params();
- return rgwrados::topic::write(dpp, y, *svc()->sysobj, svc()->mdlog, zone,
- topic, objv_tracker, {}, exclusive);
+ return rgwrados::topic::write(dpp, y, *svc()->sysobj, svc()->mdlog, rados,
+ zone, topic, objv_tracker, {}, exclusive);
}
int RadosStore::remove_topic_v2(const std::string& topic_name,
@@ -1704,10 +1706,24 @@ int RadosStore::remove_topic_v2(const std::string& topic_name,
optional_yield y,
const DoutPrefixProvider* dpp)
{
+ librados::Rados& rados = *getRados()->get_rados_handle();
const RGWZoneParams& zone = svc()->zone->get_zone_params();
- const std::string key = get_topic_metadata_key(tenant, topic_name);
return rgwrados::topic::remove(dpp, y, *svc()->sysobj, svc()->mdlog,
- zone, key, objv_tracker);
+ rados, zone, tenant, topic_name, objv_tracker);
+}
+
+int RadosStore::list_account_topics(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view account_id,
+ std::string_view marker,
+ uint32_t max_items,
+ TopicList& listing)
+{
+ librados::Rados& rados = *getRados()->get_rados_handle();
+ const RGWZoneParams& zone = svc()->zone->get_zone_params();
+ const rgw_raw_obj& obj = rgwrados::account::get_topics_obj(zone, account_id);
+ return rgwrados::topics::list(dpp, y, rados, obj, marker, max_items,
+ listing.topics, listing.next_marker);
}
int RadosStore::remove_bucket_mapping_from_topics(
diff --git a/src/rgw/driver/rados/rgw_sal_rados.h b/src/rgw/driver/rados/rgw_sal_rados.h
index 669bc73de13..78bd849717f 100644
--- a/src/rgw/driver/rados/rgw_sal_rados.h
+++ b/src/rgw/driver/rados/rgw_sal_rados.h
@@ -313,6 +313,12 @@ class RadosStore : public StoreDriver {
RGWObjVersionTracker& objv_tracker,
optional_yield y,
const DoutPrefixProvider* dpp) override;
+ int list_account_topics(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view account_id,
+ std::string_view marker,
+ uint32_t max_items,
+ TopicList& listing) override;
int update_bucket_topic_mapping(const rgw_pubsub_topic& topic,
const std::string& bucket_key,
bool add_mapping,
diff --git a/src/rgw/driver/rados/rgw_service.cc b/src/rgw/driver/rados/rgw_service.cc
index 938589f4807..5e7dd81c716 100644
--- a/src/rgw/driver/rados/rgw_service.cc
+++ b/src/rgw/driver/rados/rgw_service.cc
@@ -416,8 +416,8 @@ int RGWCtlDef::init(RGWServices& svc, rgw::sal::Driver* driver,
meta.topic_cache->init(svc.cache);
meta.topic = rgwrados::topic::create_metadata_handler(
- *svc.sysobj, svc.cache, *svc.mdlog, svc.zone->get_zone_params(),
- *meta.topic_cache);
+ *svc.sysobj, svc.cache, *svc.mdlog, rados,
+ svc.zone->get_zone_params(), *meta.topic_cache);
RGWOTPMetadataHandlerBase *otp_handler = static_cast<RGWOTPMetadataHandlerBase *>(meta.otp.get());
otp_handler->init(svc.zone, svc.meta_be_otp, svc.otp);
diff --git a/src/rgw/driver/rados/topic.cc b/src/rgw/driver/rados/topic.cc
index 9366b6fa3dd..3e43a67012e 100644
--- a/src/rgw/driver/rados/topic.cc
+++ b/src/rgw/driver/rados/topic.cc
@@ -15,6 +15,8 @@
#include "topic.h"
#include "common/errno.h"
+#include "account.h"
+#include "rgw_account.h"
#include "rgw_common.h"
#include "rgw_metadata.h"
#include "rgw_metadata_lister.h"
@@ -26,6 +28,7 @@
#include "rgw_zone.h"
#include "svc_mdlog.h"
#include "svc_sys_obj_cache.h"
+#include "topics.h"
namespace rgwrados::topic {
@@ -95,7 +98,8 @@ int read(const DoutPrefixProvider* dpp, optional_yield y,
}
int write(const DoutPrefixProvider* dpp, optional_yield y,
- RGWSI_SysObj& sysobj, RGWSI_MDLog* mdlog, const RGWZoneParams& zone,
+ RGWSI_SysObj& sysobj, RGWSI_MDLog* mdlog,
+ librados::Rados& rados, const RGWZoneParams& zone,
const rgw_pubsub_topic& info, RGWObjVersionTracker& objv,
ceph::real_time mtime, bool exclusive)
{
@@ -113,6 +117,17 @@ int write(const DoutPrefixProvider* dpp, optional_yield y,
return r;
}
+ if (const auto* id = std::get_if<rgw_account_id>(&info.owner); id) {
+ // link the topic to its account
+ const auto& topics = account::get_topics_obj(zone, *id);
+ r = topics::add(dpp, y, rados, topics, info, false,
+ std::numeric_limits<uint32_t>::max());
+ if (r < 0) {
+ ldpp_dout(dpp, 0) << "WARNING: could not link topic to account "
+ << *id << ": " << cpp_strerror(r) << dendl;
+ } // not fatal
+ }
+
// record in the mdlog on success
if (mdlog) {
return mdlog->complete_entry(dpp, y, "topic", topic_key, &objv);
@@ -121,9 +136,13 @@ int write(const DoutPrefixProvider* dpp, optional_yield y,
}
int remove(const DoutPrefixProvider* dpp, optional_yield y,
- RGWSI_SysObj& sysobj, RGWSI_MDLog* mdlog, const RGWZoneParams& zone,
- const std::string& topic_key, RGWObjVersionTracker& objv)
+ RGWSI_SysObj& sysobj, RGWSI_MDLog* mdlog,
+ librados::Rados& rados, const RGWZoneParams& zone,
+ const std::string& tenant, const std::string& name,
+ RGWObjVersionTracker& objv)
{
+ const std::string topic_key = get_topic_metadata_key(tenant, name);
+
// delete topic info
const rgw_raw_obj topic = get_topic_obj(zone, topic_key);
int r = rgw_delete_system_obj(dpp, &sysobj, topic.pool, topic.oid, &objv, y);
@@ -142,6 +161,16 @@ int remove(const DoutPrefixProvider* dpp, optional_yield y,
<< buckets.oid << " with: " << cpp_strerror(r) << dendl;
} // not fatal
+ if (rgw::account::validate_id(tenant)) {
+ // unlink the name from its account
+ const auto& topics = account::get_topics_obj(zone, tenant);
+ r = topics::remove(dpp, y, rados, topics, name);
+ if (r < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: could not unlink from account "
+ << tenant << ": " << cpp_strerror(r) << dendl;
+ } // not fatal
+ }
+
// record in the mdlog on success
if (mdlog) {
return mdlog->complete_entry(dpp, y, "topic", topic_key, &objv);
@@ -265,14 +294,16 @@ class MetadataHandler : public RGWMetadataHandler {
RGWSI_SysObj& sysobj;
RGWSI_SysObj_Cache* cache_svc;
RGWSI_MDLog& mdlog;
+ librados::Rados& rados;
const RGWZoneParams& zone;
RGWChainedCacheImpl<cache_entry>& cache;
public:
MetadataHandler(RGWSI_SysObj& sysobj, RGWSI_SysObj_Cache* cache_svc,
- RGWSI_MDLog& mdlog, const RGWZoneParams& zone,
+ RGWSI_MDLog& mdlog, librados::Rados& rados,
+ const RGWZoneParams& zone,
RGWChainedCacheImpl<cache_entry>& cache)
: sysobj(sysobj), cache_svc(cache_svc), mdlog(mdlog),
- zone(zone), cache(cache)
+ rados(rados), zone(zone), cache(cache)
{}
std::string get_type() final { return "topic"; }
@@ -316,8 +347,8 @@ class MetadataHandler : public RGWMetadataHandler {
auto mtime = robj->get_mtime();
constexpr bool exclusive = false;
- int r = write(dpp, y, sysobj, &mdlog, zone, info,
- objv_tracker, mtime, exclusive);
+ int r = write(dpp, y, sysobj, &mdlog, rados, zone,
+ info, objv_tracker, mtime, exclusive);
if (r < 0) {
return r;
}
@@ -335,14 +366,17 @@ class MetadataHandler : public RGWMetadataHandler {
int remove(std::string& entry, RGWObjVersionTracker& objv_tracker,
optional_yield y, const DoutPrefixProvider *dpp) override
{
- int r = topic::remove(dpp, y, sysobj, &mdlog, zone, entry, objv_tracker);
+ std::string name;
+ std::string tenant;
+ parse_topic_metadata_key(entry, tenant, name);
+
+ int r = topic::remove(dpp, y, sysobj, &mdlog, rados, zone,
+ tenant, name, objv_tracker);
if (r < 0) {
return r;
}
+
// delete persistent topic queue. expect ENOENT for non-persistent topics
- std::string name;
- std::string tenant;
- parse_topic_metadata_key(entry, tenant, name);
r = rgw::notify::remove_persistent_topic(name, y);
if (r < 0 && r != -ENOENT) {
ldpp_dout(dpp, 1) << "Failed to delete queue for persistent topic: "
@@ -397,12 +431,13 @@ class MetadataHandler : public RGWMetadataHandler {
auto create_metadata_handler(RGWSI_SysObj& sysobj,
RGWSI_SysObj_Cache* cache_svc,
- RGWSI_MDLog& mdlog, const RGWZoneParams& zone,
+ RGWSI_MDLog& mdlog, librados::Rados& rados,
+ const RGWZoneParams& zone,
RGWChainedCacheImpl<cache_entry>& cache)
-> std::unique_ptr<RGWMetadataHandler>
{
return std::make_unique<MetadataHandler>(sysobj, cache_svc, mdlog,
- zone, cache);
+ rados, zone, cache);
}
} // rgwrados::topic
diff --git a/src/rgw/driver/rados/topic.h b/src/rgw/driver/rados/topic.h
index 3799d001ec7..bcd838773bc 100644
--- a/src/rgw/driver/rados/topic.h
+++ b/src/rgw/driver/rados/topic.h
@@ -52,14 +52,16 @@ int read(const DoutPrefixProvider* dpp, optional_yield y,
/// Write or overwrite topic info.
int write(const DoutPrefixProvider* dpp, optional_yield y,
- RGWSI_SysObj& sysobj, RGWSI_MDLog* mdlog, const RGWZoneParams& zone,
+ RGWSI_SysObj& sysobj, RGWSI_MDLog* mdlog,
+ librados::Rados& rados, const RGWZoneParams& zone,
const rgw_pubsub_topic& info, RGWObjVersionTracker& objv,
ceph::real_time mtime, bool exclusive);
/// Remove a topic by metadata key.
int remove(const DoutPrefixProvider* dpp, optional_yield y,
RGWSI_SysObj& sysobj, RGWSI_MDLog* mdlog,
- const RGWZoneParams& zone, const std::string& topic_key,
+ librados::Rados& rados, const RGWZoneParams& zone,
+ const std::string& tenant, const std::string& name,
RGWObjVersionTracker& objv);
@@ -87,7 +89,8 @@ int list_buckets(const DoutPrefixProvider* dpp, optional_yield y,
/// Topic metadata handler factory.
auto create_metadata_handler(RGWSI_SysObj& sysobj,
RGWSI_SysObj_Cache* cache_svc,
- RGWSI_MDLog& mdlog, const RGWZoneParams& zone,
+ RGWSI_MDLog& mdlog, librados::Rados& rados,
+ const RGWZoneParams& zone,
RGWChainedCacheImpl<cache_entry>& cache)
-> std::unique_ptr<RGWMetadataHandler>;
diff --git a/src/rgw/driver/rados/topics.cc b/src/rgw/driver/rados/topics.cc
new file mode 100644
index 00000000000..0da4680d672
--- /dev/null
+++ b/src/rgw/driver/rados/topics.cc
@@ -0,0 +1,109 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright contributors to the Ceph project
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#include "topics.h"
+
+#include "include/rados/librados.hpp"
+#include "common/dout.h"
+#include "cls/user/cls_user_client.h"
+#include "rgw_pubsub.h"
+#include "rgw_sal.h"
+
+namespace rgwrados::topics {
+
+int add(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ const rgw_pubsub_topic& topic,
+ bool exclusive, uint32_t limit)
+{
+ cls_user_account_resource resource;
+ resource.name = topic.name;
+
+ rgw_rados_ref ref;
+ int r = rgw_get_rados_ref(dpp, &rados, obj, &ref);
+ if (r < 0) {
+ return r;
+ }
+
+ librados::ObjectWriteOperation op;
+ ::cls_user_account_resource_add(op, resource, exclusive, limit);
+ return ref.operate(dpp, &op, y);
+}
+
+int remove(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ std::string_view name)
+{
+ rgw_rados_ref ref;
+ int r = rgw_get_rados_ref(dpp, &rados, obj, &ref);
+ if (r < 0) {
+ return r;
+ }
+
+ librados::ObjectWriteOperation op;
+ ::cls_user_account_resource_rm(op, name);
+ return ref.operate(dpp, &op, y);
+}
+
+int list(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ std::string_view marker,
+ uint32_t max_items,
+ std::vector<std::string>& names,
+ std::string& next_marker)
+{
+ rgw_rados_ref ref;
+ int r = rgw_get_rados_ref(dpp, &rados, obj, &ref);
+ if (r < 0) {
+ return r;
+ }
+
+ librados::ObjectReadOperation op;
+ const std::string path_prefix; // unused
+ std::vector<cls_user_account_resource> entries;
+ bool truncated = false;
+ int ret = 0;
+ ::cls_user_account_resource_list(op, marker, path_prefix, max_items,
+ entries, &truncated, &next_marker, &ret);
+
+ r = ref.operate(dpp, &op, nullptr, y);
+ if (r == -ENOENT) {
+ next_marker.clear();
+ return 0;
+ }
+ if (r < 0) {
+ return r;
+ }
+ if (ret < 0) {
+ return ret;
+ }
+
+ for (auto& resource : entries) {
+ names.push_back(std::move(resource.name));
+ }
+
+ if (!truncated) {
+ next_marker.clear();
+ }
+ return 0;
+}
+
+} // namespace rgwrados::topics
diff --git a/src/rgw/driver/rados/topics.h b/src/rgw/driver/rados/topics.h
new file mode 100644
index 00000000000..113db96a90f
--- /dev/null
+++ b/src/rgw/driver/rados/topics.h
@@ -0,0 +1,57 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright contributors to the Ceph project
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <string>
+#include <vector>
+#include "include/rados/librados_fwd.hpp"
+#include "rgw_sal_fwd.h"
+
+class DoutPrefixProvider;
+class optional_yield;
+struct rgw_raw_obj;
+struct rgw_pubsub_topic;
+
+
+namespace rgwrados::topics {
+
+/// Add the given topic to the list.
+int add(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ const rgw_pubsub_topic& info,
+ bool exclusive, uint32_t limit);
+
+/// Remove the given topic from the list.
+int remove(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ std::string_view name);
+
+/// Return a paginated listing of topic names.
+int list(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ std::string_view marker,
+ uint32_t max_items,
+ std::vector<std::string>& names,
+ std::string& next_marker);
+
+} // namespace rgwrados::topics
diff --git a/src/rgw/rgw_pubsub.cc b/src/rgw/rgw_pubsub.cc
index 36b04887edb..33cfd21e1ab 100644
--- a/src/rgw/rgw_pubsub.cc
+++ b/src/rgw/rgw_pubsub.cc
@@ -2,6 +2,7 @@
// vim: ts=8 sw=2 smarttab ft=cpp
#include "services/svc_zone.h"
+#include "rgw_account.h"
#include "rgw_b64.h"
#include "rgw_sal.h"
#include "rgw_pubsub.h"
@@ -552,6 +553,12 @@ int RGWPubSub::get_topics(const DoutPrefixProvider* dpp,
rgw_pubsub_topics& result, std::string& next_marker,
optional_yield y) const
{
+ if (rgw::account::validate_id(tenant)) {
+ // if our tenant is an account, return the account listing
+ return list_account_topics(dpp, start_marker, max_items,
+ result, next_marker, y);
+ }
+
if (!use_notification_v2 || driver->stat_topics_v1(tenant, y, dpp) != -ENOENT) {
// in case of v1 or during migration we use v1 topics
// v1 returns all topics, ignoring marker/max_items
@@ -600,6 +607,36 @@ int RGWPubSub::get_topics(const DoutPrefixProvider* dpp,
return ret;
}
+int RGWPubSub::list_account_topics(const DoutPrefixProvider* dpp,
+ const std::string& start_marker,
+ int max_items, rgw_pubsub_topics& result,
+ std::string& next_marker,
+ optional_yield y) const
+{
+ if (max_items > 1000) {
+ max_items = 1000;
+ }
+
+ rgw::sal::TopicList listing;
+ int ret = driver->list_account_topics(dpp, y, tenant, start_marker,
+ max_items, listing);
+ if (ret < 0) {
+ return ret;
+ }
+
+ for (const auto& topic_name : listing.topics) {
+ rgw_pubsub_topic topic;
+ int r = get_topic(dpp, topic_name, topic, y, nullptr);
+ if (r < 0) {
+ continue;
+ }
+ result.topics[topic_name] = std::move(topic);
+ }
+
+ next_marker = std::move(listing.next_marker);
+ return 0;
+}
+
int RGWPubSub::read_topics_v1(const DoutPrefixProvider *dpp, rgw_pubsub_topics& result,
RGWObjVersionTracker *objv_tracker, optional_yield y) const
{
diff --git a/src/rgw/rgw_pubsub.h b/src/rgw/rgw_pubsub.h
index c394846f901..1ae88bdbe26 100644
--- a/src/rgw/rgw_pubsub.h
+++ b/src/rgw/rgw_pubsub.h
@@ -575,6 +575,11 @@ class RGWPubSub
const rgw_pubsub_topic& topic,
optional_yield y) const;
+ int list_account_topics(const DoutPrefixProvider* dpp,
+ const std::string& start_marker, int max_items,
+ rgw_pubsub_topics& result, std::string& next_marker,
+ optional_yield y) const;
+
public:
RGWPubSub(rgw::sal::Driver* _driver,
const std::string& _tenant,
diff --git a/src/rgw/rgw_sal.h b/src/rgw/rgw_sal.h
index 93de433bcf7..e3a892b6992 100644
--- a/src/rgw/rgw_sal.h
+++ b/src/rgw/rgw_sal.h
@@ -267,6 +267,14 @@ struct GroupList {
std::string next_marker;
};
+/// A list of topic names
+struct TopicList {
+ /// The list of results, sorted by name
+ std::vector<std::string> topics;
+ /// The next marker to resume listing, or empty
+ std::string next_marker;
+};
+
/** A list of key-value attributes */
using Attrs = std::map<std::string, ceph::buffer::list>;
@@ -527,6 +535,13 @@ class Driver {
RGWObjVersionTracker& objv_tracker,
optional_yield y,
const DoutPrefixProvider* dpp) = 0;
+ /** Return a paginated listing of the account's topic names */
+ virtual int list_account_topics(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view account_id,
+ std::string_view marker,
+ uint32_t max_items,
+ TopicList& listing) = 0;
/** Update the bucket-topic mapping in the store, if |add_mapping|=true then
* adding the |bucket_key| |topic| mapping to store, else delete the
* |bucket_key| |topic| mapping from the store. The |bucket_key| is
diff --git a/src/rgw/rgw_sal_dbstore.cc b/src/rgw/rgw_sal_dbstore.cc
index b734432cb4c..2ce6304646e 100644
--- a/src/rgw/rgw_sal_dbstore.cc
+++ b/src/rgw/rgw_sal_dbstore.cc
@@ -1902,6 +1902,16 @@ namespace rgw::sal {
return std::make_unique<DBNotification>(obj, src_obj, event_types);
}
+ int DBStore::list_account_topics(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view account_id,
+ std::string_view marker,
+ uint32_t max_items,
+ TopicList& listing)
+ {
+ return -ENOTSUP;
+ }
+
RGWLC* DBStore::get_rgwlc(void) {
return lc;
}
diff --git a/src/rgw/rgw_sal_dbstore.h b/src/rgw/rgw_sal_dbstore.h
index 7139811544e..4770713e762 100644
--- a/src/rgw/rgw_sal_dbstore.h
+++ b/src/rgw/rgw_sal_dbstore.h
@@ -880,7 +880,14 @@ public:
std::string& _req_id,
optional_yield y) override;
- virtual RGWLC* get_rgwlc(void) override;
+ int list_account_topics(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view account_id,
+ std::string_view marker,
+ uint32_t max_items,
+ TopicList& listing) override;
+
+ virtual RGWLC* get_rgwlc(void) override;
virtual RGWCoroutinesManagerRegistry* get_cr_registry() override { return NULL; }
virtual int log_usage(const DoutPrefixProvider *dpp, std::map<rgw_user_bucket, RGWUsageBatch>& usage_info, optional_yield y) override;
virtual int log_op(const DoutPrefixProvider *dpp, std::string& oid, bufferlist& bl) override;
diff --git a/src/rgw/rgw_sal_filter.h b/src/rgw/rgw_sal_filter.h
index bbba9eafde5..95d00960cbd 100644
--- a/src/rgw/rgw_sal_filter.h
+++ b/src/rgw/rgw_sal_filter.h
@@ -344,6 +344,15 @@ public:
const DoutPrefixProvider* dpp) override {
return next->remove_topic_v2(topic_name, tenant, objv_tracker, y, dpp);
}
+ int list_account_topics(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view account_id,
+ std::string_view marker,
+ uint32_t max_items,
+ TopicList& listing) override {
+ return next->list_account_topics(dpp, y, account_id, marker,
+ max_items, listing);
+ }
int update_bucket_topic_mapping(const rgw_pubsub_topic& topic,
const std::string& bucket_key,
bool add_mapping,
diff --git a/src/rgw/rgw_sal_fwd.h b/src/rgw/rgw_sal_fwd.h
index 39039cf4c3f..e447cba4aae 100644
--- a/src/rgw/rgw_sal_fwd.h
+++ b/src/rgw/rgw_sal_fwd.h
@@ -49,6 +49,7 @@ namespace sal {
class RGWRole;
struct RoleList;
struct GroupList;
+ struct TopicList;
class DataProcessor;
class ObjectProcessor;
class ReadStatsCB;