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(topic.user.tenant, topic.name);
+ const std::string key = get_topic_metadata_key(topic);
int ret = 0;
if (add_mapping) {
ret = rgwrados::topic::link_bucket(dpp, y, rados, zone, key, bucket_key);
{
librados::Rados& rados = *getRados()->get_rados_handle();
const RGWZoneParams& zone = svc()->zone->get_zone_params();
- const std::string key = get_topic_metadata_key(topic.user.tenant, topic.name);
+ const std::string key = get_topic_metadata_key(topic);
constexpr int max_chunk = 1024;
std::string marker;
const rgw_pubsub_topic& info, RGWObjVersionTracker& objv,
ceph::real_time mtime, bool exclusive)
{
- const std::string topic_key = get_topic_metadata_key(info.user.tenant, info.name);
+ const std::string topic_key = get_topic_metadata_key(info);
const rgw_raw_obj obj = get_topic_obj(zone, topic_key);
bufferlist bl;
RGWPubSub ps(driver, tenant, *site);
std::string next_token = marker;
+ std::optional<rgw_owner> owner;
+ if (!rgw::sal::User::empty(user)) {
+ owner = user->get_id();
+ } else if (!account_id.empty()) {
+ owner = rgw_account_id{account_id};
+ }
+
formatter->open_object_section("result");
formatter->open_array_section("topics");
do {
return -ret;
}
for (const auto& [_, topic] : result.topics) {
- if (!rgw::sal::User::empty(user) && user->get_id() != topic.user) {
+ if (owner && *owner != topic.owner) {
continue;
}
std::set<std::string> subscribed_buckets;
#include "rgw_pubsub_push.h"
#include "rgw_bucket.h"
#include "common/errno.h"
+#include "include/function2.hpp"
#include <regex>
#include <algorithm>
return string_cat_reserve(tenant, topic_tenant_delim, topic_name);
}
+std::string get_topic_metadata_key(const rgw_pubsub_topic& topic)
+{
+ // use account id or tenant name
+ std::string_view tenant = std::visit(fu2::overload(
+ [] (const rgw_user& u) -> std::string_view { return u.tenant; },
+ [] (const rgw_account_id& a) -> std::string_view { return a; }
+ ), topic.owner);
+ return get_topic_metadata_key(tenant, topic.name);
+}
+
void parse_topic_metadata_key(const std::string& key,
std::string& tenant,
std::string& name)
void rgw_pubsub_topic::dump(Formatter *f) const
{
- encode_json("user", user, f);
+ encode_json("owner", owner, f);
encode_json("name", name, f);
encode_json("dest", dest, f);
encode_json("arn", arn, f);
void rgw_pubsub_topic::dump_xml(Formatter *f) const
{
- encode_xml("User", user, f);
+ encode_xml("User", to_string(owner), f);
encode_xml("Name", name, f);
encode_xml("EndPoint", dest, f);
encode_xml("TopicArn", arn, f);
void rgw_pubsub_topic::dump_xml_as_attributes(Formatter *f) const
{
f->open_array_section("Attributes");
- std::string str_user;
- user.to_str(str_user);
- encode_xml_key_value_entry("User", str_user, f);
+ encode_xml_key_value_entry("User", to_string(owner), f);
encode_xml_key_value_entry("Name", name, f);
encode_xml_key_value_entry("EndPoint", dest.to_json_str(), f);
encode_xml_key_value_entry("TopicArn", arn, f);
}
void rgw_pubsub_topic::decode_json(JSONObj* f) {
- JSONDecoder::decode_json("user", user, f);
+ JSONDecoder::decode_json("owner", owner, f);
JSONDecoder::decode_json("name", name, f);
JSONDecoder::decode_json("dest", dest, f);
JSONDecoder::decode_json("arn", arn, f);
const std::string& name,
const rgw_pubsub_dest& dest, const std::string& arn,
const std::string& opaque_data,
- const rgw_user& user,
+ const rgw_owner& owner,
const std::string& policy_text,
optional_yield y) const {
if (use_notification_v2) {
return -ERR_SERVICE_UNAVAILABLE;
}
rgw_pubsub_topic new_topic;
- new_topic.user = user;
+ new_topic.owner = owner;
new_topic.name = name;
new_topic.dest = dest;
new_topic.arn = arn;
}
rgw_pubsub_topic& new_topic = topics.topics[name];
- new_topic.user = user;
+ new_topic.owner = owner;
new_topic.name = name;
new_topic.dest = dest;
new_topic.arn = arn;
#pragma once
-#include "rgw_sal.h"
+#include "common/versioned_variant.h"
+#include "rgw_sal_fwd.h"
#include "rgw_tools.h"
#include "rgw_zone.h"
#include "rgw_notify_event_type.h"
WRITE_CLASS_ENCODER(rgw_pubsub_dest)
struct rgw_pubsub_topic {
- rgw_user user;
+ rgw_owner owner;
std::string name;
rgw_pubsub_dest dest;
std::string arn;
void encode(bufferlist& bl) const {
ENCODE_START(4, 1, bl);
- encode(user, bl);
+ // converted from rgw_user to rgw_owner
+ ceph::converted_variant::encode(owner, bl);
encode(name, bl);
encode(dest, bl);
encode(arn, bl);
void decode(bufferlist::const_iterator& bl) {
DECODE_START(4, bl);
- decode(user, bl);
+ // converted from rgw_user to rgw_owner
+ ceph::converted_variant::decode(owner, bl);
decode(name, bl);
if (struct_v >= 2) {
decode(dest, bl);
DECODE_FINISH(bl);
}
- std::string to_str() const {
- return user.tenant + "/" + name;
- }
-
void dump(Formatter *f) const;
void dump_xml(Formatter *f) const;
void dump_xml_as_attributes(Formatter *f) const;
void decode_json(JSONObj* obj);
-
- bool operator<(const rgw_pubsub_topic& t) const {
- return to_str().compare(t.to_str());
- }
};
WRITE_CLASS_ENCODER(rgw_pubsub_topic)
// return 0 on success, error code otherwise
int create_topic(const DoutPrefixProvider* dpp, const std::string& name,
const rgw_pubsub_dest& dest, const std::string& arn,
- const std::string& opaque_data, const rgw_user& user,
+ const std::string& opaque_data, const rgw_owner& owner,
const std::string& policy_text, optional_yield y) const;
// remove a topic according to its name
// if the topic does not exists it is a no-op (considered success)
rgw_pubsub_bucket_topics& bucket_topics);
// format and parse topic metadata keys as tenant:name
-std::string get_topic_metadata_key(std::string_view topic_name,
- std::string_view tenant);
+std::string get_topic_metadata_key(std::string_view tenant,
+ std::string_view topic_name);
+std::string get_topic_metadata_key(const rgw_pubsub_topic& topic);
void parse_topic_metadata_key(const std::string& key,
std::string& tenant_name,
std::string& topic_name);
const rgw_pubsub_topic& topic,
const std::string& zonegroup_name,
const uint64_t op) {
- if (topic.user == s->owner.id) {
+ if (s->auth.identity->is_owner_of(topic.owner)) {
return 0;
}
// no policy set.
if (op == rgw::IAM::snsPublish && !s->cct->_conf->rgw_topic_require_publish_policy) {
return 0;
}
- if (topic.user.empty()) {
+ if (std::visit([] (const auto& o) { return o.empty(); }, topic.owner)) {
// if we don't know the original user and there is no policy
// we will not reject the request.
// this is for compatibility with versions that did not store the user in the topic
std::string opaque_data;
std::string policy_text;
rgw_pubsub_dest dest;
- rgw_user topic_owner;
+ rgw_owner topic_owner;
std::string attribute_name;
int get_params() {
<< "', ret=" << ret << dendl;
return ret;
}
- topic_owner = result.user;
+ topic_owner = result.owner;
ret = verify_topic_owner_or_policy(
s, result, driver->get_zone()->get_zonegroup().get_name(),
rgw::IAM::snsSetTopicAttributes);
parsed_result = json.loads(result[0])
assert_equal(parsed_result['arn'], topic_arn3)
matches = [tenant, UID_PREFIX]
- assert_true( all([x in parsed_result['user'] for x in matches]))
+ assert_true( all([x in parsed_result['owner'] for x in matches]))
# delete topic 3
_, result = admin(['topic', 'rm', '--topic', topic_name+'_3', '--tenant', tenant], get_config_cluster())