driver/rados/rgw_zone.cc
driver/rados/sync_fairness.cc
driver/rados/topic.cc
- driver/rados/topic_migration.cc)
+ driver/rados/topic_migration.cc
+ driver/rados/users.cc)
list(APPEND librgw_common_srcs
driver/immutable_config/store.cc
#include "account.h"
#include <boost/algorithm/string.hpp>
+#include "include/rados/librados.hpp"
+#include "cls/user/cls_user_types.h"
#include "common/errno.h"
#include "rgw_account.h"
#include "rgw_common.h"
namespace rgwrados::account {
static constexpr std::string_view buckets_oid_prefix = "buckets.";
+static constexpr std::string_view users_oid_prefix = "users.";
static const std::string account_oid_prefix = "account.";
static constexpr std::string_view name_oid_prefix = "name.";
return {zone.account_pool, get_buckets_key(account_id)};
}
+static std::string get_users_key(std::string_view account_id) {
+ return string_cat_reserve(users_oid_prefix, account_id);
+}
+rgw_raw_obj get_users_obj(const RGWZoneParams& zone,
+ std::string_view account_id) {
+ return {zone.account_pool, get_users_key(account_id)};
+}
+
static std::string get_account_key(std::string_view account_id) {
return string_cat_reserve(account_oid_prefix, account_id);
}
<< obj << " with: " << cpp_strerror(r) << dendl;
} // not fatal
}
+ {
+ // remove the users object
+ const rgw_raw_obj obj = get_users_obj(zone, info.id);
+ r = rgw_delete_system_obj(dpp, &sysobj, obj.pool, obj.oid, nullptr, y);
+ if (r < 0) {
+ ldpp_dout(dpp, 20) << "WARNING: failed to remove users obj "
+ << obj << " with: " << cpp_strerror(r) << dendl;
+ } // not fatal
+ }
+
+ return 0;
+}
+
+// read the resource count from cls_user_account_header
+int resource_count(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ uint32_t& count)
+{
+ rgw_rados_ref ref;
+ int r = rgw_get_rados_ref(dpp, &rados, obj, &ref);
+ if (r < 0) {
+ return r;
+ }
+
+ librados::ObjectReadOperation op;
+ bufferlist bl;
+ int ret = 0;
+ op.omap_get_header(&bl, &ret);
+
+ r = ref.operate(dpp, &op, nullptr, y);
+ if (r == -ENOENT) { // doesn't exist yet
+ count = 0;
+ return 0;
+ }
+ if (r < 0) {
+ return r;
+ }
+
+ if (!bl.length()) { // exists but no header yet
+ count = 0;
+ return 0;
+ }
+
+ cls_user_account_header header;
+ try {
+ auto p = bl.cbegin();
+ decode(header, p);
+ } catch (const buffer::error&) {
+ return -EIO;
+ }
+ count = header.count;
return 0;
}
#include <memory>
#include <string>
#include "include/encoding.h"
+#include "include/rados/librados_fwd.hpp"
#include "common/async/yield_context.h"
namespace ceph { class Formatter; }
rgw_raw_obj get_buckets_obj(const RGWZoneParams& zone,
std::string_view account_id);
+/// Return the rados object that tracks the given account's users. This
+/// can be used with the cls_user interface in namespace rgwrados::users.
+rgw_raw_obj get_users_obj(const RGWZoneParams& zone,
+ std::string_view account_id);
+
/// Read account info by id
int read(const DoutPrefixProvider* dpp,
const RGWAccountInfo& info,
RGWObjVersionTracker& objv);
+
+/// Read the resource count from an account index object.
+int resource_count(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ uint32_t& count);
+
} // namespace rgwrados::account
--- /dev/null
+// -*- 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 "users.h"
+
+#include "include/rados/librados.hpp"
+#include "common/ceph_json.h"
+#include "common/dout.h"
+#include "cls/user/cls_user_client.h"
+#include "rgw_common.h"
+#include "rgw_sal.h"
+
+namespace rgwrados::users {
+
+int add(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ const RGWUserInfo& user,
+ bool exclusive, uint32_t limit)
+{
+ resource_metadata meta;
+ meta.user_id = user.user_id.id;
+
+ cls_user_account_resource resource;
+ resource.name = user.display_name;
+ resource.path = user.path;
+ encode(meta, resource.metadata);
+
+ 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 get(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ std::string_view name,
+ std::string& user_id)
+{
+ cls_user_account_resource resource;
+
+ rgw_rados_ref ref;
+ int r = rgw_get_rados_ref(dpp, &rados, obj, &ref);
+ if (r < 0) {
+ return r;
+ }
+
+ librados::ObjectReadOperation op;
+ int ret = 0;
+ ::cls_user_account_resource_get(op, name, resource, &ret);
+
+ r = ref.operate(dpp, &op, nullptr, y);
+ if (r < 0) {
+ return r;
+ }
+ if (ret < 0) {
+ return ret;
+ }
+
+ resource_metadata meta;
+ try {
+ auto p = resource.metadata.cbegin();
+ decode(meta, p);
+ } catch (const buffer::error&) {
+ return -EIO;
+ }
+ user_id = std::move(meta.user_id);
+ return 0;
+}
+
+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,
+ std::string_view path_prefix,
+ uint32_t max_items,
+ std::vector<std::string>& ids,
+ 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;
+ 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) {
+ resource_metadata meta;
+ try {
+ auto p = resource.metadata.cbegin();
+ decode(meta, p);
+ } catch (const buffer::error&) {
+ return -EIO;
+ }
+ ids.push_back(std::move(meta.user_id));
+ }
+
+ if (!truncated) {
+ next_marker.clear();
+ }
+ return 0;
+}
+
+
+void resource_metadata::dump(ceph::Formatter* f) const
+{
+ encode_json("user_id", user_id, f);
+}
+
+void resource_metadata::generate_test_instances(std::list<resource_metadata*>& o)
+{
+ o.push_back(new resource_metadata);
+ auto m = new resource_metadata;
+ m->user_id = "uid";
+ o.push_back(m);
+}
+
+} // namespace rgwrados::users
--- /dev/null
+// -*- 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 <list>
+#include <string>
+#include "include/rados/librados_fwd.hpp"
+#include "include/encoding.h"
+#include "rgw_sal_fwd.h"
+
+namespace ceph { class Formatter; }
+class DoutPrefixProvider;
+class optional_yield;
+struct rgw_raw_obj;
+struct RGWUserInfo;
+
+
+namespace rgwrados::users {
+
+/// Add the given user to the list.
+int add(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ const RGWUserInfo& user,
+ bool exclusive, uint32_t limit);
+
+/// Look up a user's id by name in the list.
+int get(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ std::string_view name,
+ std::string& user_id);
+
+/// Remove the given user 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 user ids.
+int list(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ std::string_view marker,
+ std::string_view path_prefix,
+ uint32_t max_items,
+ std::vector<std::string>& ids,
+ std::string& next_marker);
+
+// user-specific metadata for cls_user_account_resource
+struct resource_metadata {
+ std::string user_id;
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(user_id, bl);
+ ENCODE_FINISH(bl);
+ }
+ void decode(bufferlist::const_iterator& bl) {
+ DECODE_START(1, bl);
+ decode(user_id, bl);
+ DECODE_FINISH(bl);
+ }
+
+ void dump(ceph::Formatter* f) const;
+ static void generate_test_instances(std::list<resource_metadata*>& o);
+};
+WRITE_CLASS_ENCODER(resource_metadata);
+
+} // namespace rgwrados::users
#include "rgw_user_types.h"
TYPE(rgw_user)
+#include "driver/rados/users.h"
+TYPE(rgwrados::users::resource_metadata)
+
#endif