rgw_sts.cc
rgw_rest_sts.cc
rgw_perf_counters.cc
+ rgw_rest_oidc_provider.cc
rgw_rest_iam.cc
rgw_object_lock.cc
rgw_kms.cc
- rgw_url.cc)
+ rgw_url.cc
+ rgw_oidc_provider)
if(WITH_RADOSGW_AMQP_ENDPOINT)
list(APPEND librgw_common_srcs rgw_amqp.cc)
});
rgw_http_errors rgw_http_iam_errors({
+ { EINVAL, {400, "InvalidInput" }},
+ { ENOENT, {404, "NoSuchEntity"}},
{ ERR_ROLE_EXISTS, {409, "EntityAlreadyExists"}},
{ ERR_DELETE_CONFLICT, {409, "DeleteConflict"}},
+ { EEXIST, {409, "EntityAlreadyExists"}},
+ { ERR_INTERNAL_ERROR, {500, "ServiceFailure" }},
});
using namespace ceph::crypto;
"datalog",
"roles",
"user-policy",
- "amz-cache"};
+ "amz-cache",
+ "oidc-provider"};
for (unsigned int i = 0; i < sizeof(cap_type) / sizeof(char *); ++i) {
if (tp.compare(cap_type[i]) == 0) {
RGW_OP_PUT_BUCKET_PUBLIC_ACCESS_BLOCK,
RGW_OP_GET_BUCKET_PUBLIC_ACCESS_BLOCK,
RGW_OP_DELETE_BUCKET_PUBLIC_ACCESS_BLOCK,
+
+ /*OIDC provider specific*/
+ RGW_OP_CREATE_OIDC_PROVIDER,
+ RGW_OP_DELETE_OIDC_PROVIDER,
+ RGW_OP_GET_OIDC_PROVIDER,
+ RGW_OP_LIST_OIDC_PROVIDERS,
};
class RGWAccessControlPolicy;
static constexpr std::uint64_t iamGetRolePolicy = s3All + 11;
static constexpr std::uint64_t iamListRolePolicies = s3All + 12;
static constexpr std::uint64_t iamDeleteRolePolicy = s3All + 13;
-static constexpr std::uint64_t iamAll = s3All + 14;
+static constexpr std::uint64_t iamCreateOIDCProvider = s3All + 14;
+static constexpr std::uint64_t iamDeleteOIDCProvider = s3All + 15;
+static constexpr std::uint64_t iamGetOIDCProvider = s3All + 16;
+static constexpr std::uint64_t iamListOIDCProviders = s3All + 17;
+static constexpr std::uint64_t iamAll = s3All + 18;
static constexpr std::uint64_t stsAssumeRole = iamAll + 1;
static constexpr std::uint64_t stsAssumeRoleWithWebIdentity = iamAll + 2;
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+#include <errno.h>
+#include <ctime>
+#include <regex>
+
+#include "common/errno.h"
+#include "common/Formatter.h"
+#include "common/ceph_json.h"
+#include "common/ceph_time.h"
+#include "rgw_rados.h"
+#include "rgw_zone.h"
+
+#include "include/types.h"
+#include "rgw_string.h"
+
+#include "rgw_common.h"
+#include "rgw_tools.h"
+#include "rgw_oidc_provider.h"
+
+#include "services/svc_zone.h"
+#include "services/svc_sys_obj.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+const string RGWOIDCProvider::oidc_url_oid_prefix = "oidc_url.";
+const string RGWOIDCProvider::oidc_arn_prefix = "arn:aws:iam::";
+
+int RGWOIDCProvider::store_url(const string& url, bool exclusive)
+{
+ using ceph::encode;
+ string oid = tenant + get_url_oid_prefix() + url;
+
+ auto svc = ctl->svc;
+
+ bufferlist bl;
+ encode(*this, bl);
+ auto obj_ctx = svc->sysobj->init_obj_ctx();
+ return rgw_put_system_obj(obj_ctx, svc->zone->get_zone_params().oidc_pool, oid,
+ bl, exclusive, NULL, real_time(), NULL);
+}
+
+int RGWOIDCProvider::get_tenant_url_from_arn(string& tenant, string& url)
+{
+ auto provider_arn = rgw::ARN::parse(arn);
+ if (!provider_arn) {
+ return -EINVAL;
+ }
+ url = provider_arn->resource;
+ tenant = provider_arn->account;
+ auto pos = url.find("oidc-provider/");
+ if (pos != std::string::npos) {
+ url.erase(pos, 14);
+ }
+ return 0;
+}
+
+int RGWOIDCProvider::create(bool exclusive)
+{
+ int ret;
+
+ if (! validate_input()) {
+ return -EINVAL;
+ }
+
+ string idp_url = provider_url;
+ auto pos = idp_url.find("http://");
+ if (pos == std::string::npos) {
+ pos = idp_url.find("https://");
+ if (pos != std::string::npos) {
+ idp_url.erase(pos, 8);
+ } else {
+ pos = idp_url.find("www.");
+ if (pos != std::string::npos) {
+ idp_url.erase(pos, 4);
+ }
+ }
+ } else {
+ idp_url.erase(pos, 7);
+ }
+
+ /* check to see the name is not used */
+ ret = read_url(idp_url, tenant);
+ if (exclusive && ret == 0) {
+ ldout(cct, 0) << "ERROR: url " << provider_url << " already in use"
+ << id << dendl;
+ return -EEXIST;
+ } else if ( ret < 0 && ret != -ENOENT) {
+ ldout(cct, 0) << "failed reading provider url " << provider_url << ": "
+ << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+
+ //arn
+ arn = oidc_arn_prefix + tenant + ":oidc-provider/" + idp_url;
+
+ // Creation time
+ real_clock::time_point t = real_clock::now();
+
+ struct timeval tv;
+ real_clock::to_timeval(t, tv);
+
+ char buf[30];
+ struct tm result;
+ gmtime_r(&tv.tv_sec, &result);
+ strftime(buf,30,"%Y-%m-%dT%H:%M:%S", &result);
+ sprintf(buf + strlen(buf),".%dZ",(int)tv.tv_usec/1000);
+ creation_date.assign(buf, strlen(buf));
+
+ auto svc = ctl->svc;
+
+ auto& pool = svc->zone->get_zone_params().oidc_pool;
+ ret = store_url(idp_url, exclusive);
+ if (ret < 0) {
+ ldout(cct, 0) << "ERROR: storing role info in pool: " << pool.name << ": "
+ << provider_url << ": " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+
+ return 0;
+}
+
+int RGWOIDCProvider::delete_obj()
+{
+ auto svc = ctl->svc;
+ auto& pool = svc->zone->get_zone_params().oidc_pool;
+
+ string url, tenant;
+ auto ret = get_tenant_url_from_arn(tenant, url);
+ if (ret < 0) {
+ ldout(cct, 0) << "ERROR: failed to parse arn" << dendl;
+ return -EINVAL;
+ }
+
+ if (this->tenant != tenant) {
+ ldout(cct, 0) << "ERROR: tenant in arn doesn't match that of user " << this->tenant << ", "
+ << tenant << ": " << dendl;
+ return -EINVAL;
+ }
+
+ // Delete url
+ string oid = tenant + get_url_oid_prefix() + url;
+ ret = rgw_delete_system_obj(svc->sysobj, pool, oid, NULL);
+ if (ret < 0) {
+ ldout(cct, 0) << "ERROR: deleting oidc url from pool: " << pool.name << ": "
+ << provider_url << ": " << cpp_strerror(-ret) << dendl;
+ }
+
+ return ret;
+}
+
+int RGWOIDCProvider::get()
+{
+ string url, tenant;
+ auto ret = get_tenant_url_from_arn(tenant, url);
+ if (ret < 0) {
+ ldout(cct, 0) << "ERROR: failed to parse arn" << dendl;
+ return -EINVAL;
+ }
+
+ if (this->tenant != tenant) {
+ ldout(cct, 0) << "ERROR: tenant in arn doesn't match that of user " << this->tenant << ", "
+ << tenant << ": " << dendl;
+ return -EINVAL;
+ }
+
+ ret = read_url(url, tenant);
+ if (ret < 0) {
+ return ret;
+ }
+
+ return 0;
+}
+
+void RGWOIDCProvider::dump(Formatter *f) const
+{
+ encode_json("OpenIDConnectProviderArn", arn, f);
+}
+
+void RGWOIDCProvider::dump_all(Formatter *f) const
+{
+ f->open_object_section("ClientIDList");
+ for (auto it : client_ids) {
+ encode_json("member", it, f);
+ }
+ f->close_section();
+ encode_json("CreateDate", creation_date, f);
+ f->open_object_section("ThumbprintList");
+ for (auto it : thumbprints) {
+ encode_json("member", it, f);
+ }
+ f->close_section();
+ encode_json("Url", provider_url, f);
+}
+
+void RGWOIDCProvider::decode_json(JSONObj *obj)
+{
+ JSONDecoder::decode_json("OpenIDConnectProviderArn", arn, obj);
+}
+
+int RGWOIDCProvider::read_url(const string& url, const string& tenant)
+{
+ auto svc = ctl->svc;
+ auto& pool = svc->zone->get_zone_params().oidc_pool;
+ string oid = tenant + get_url_oid_prefix() + url;
+ bufferlist bl;
+ auto obj_ctx = svc->sysobj->init_obj_ctx();
+
+ int ret = rgw_get_system_obj(obj_ctx, pool, oid, bl, NULL, NULL, null_yield);
+ if (ret < 0) {
+ return ret;
+ }
+
+ try {
+ using ceph::decode;
+ auto iter = bl.cbegin();
+ decode(*this, iter);
+ } catch (buffer::error& err) {
+ ldout(cct, 0) << "ERROR: failed to decode oidc provider info from pool: " << pool.name <<
+ ": " << url << dendl;
+ return -EIO;
+ }
+
+ return 0;
+}
+
+bool RGWOIDCProvider::validate_input()
+{
+ if (provider_url.length() > MAX_OIDC_URL_LEN) {
+ ldout(cct, 0) << "ERROR: Invalid length of url " << dendl;
+ return false;
+ }
+ if (client_ids.size() > MAX_OIDC_NUM_CLIENT_IDS) {
+ ldout(cct, 0) << "ERROR: Invalid number of client ids " << dendl;
+ return false;
+ }
+
+ for (auto& it : client_ids) {
+ if (it.length() > MAX_OIDC_CLIENT_ID_LEN) {
+ return false;
+ }
+ }
+
+ if (thumbprints.size() > MAX_OIDC_NUM_THUMBPRINTS) {
+ ldout(cct, 0) << "ERROR: Invalid number of thumbprints " << thumbprints.size() << dendl;
+ return false;
+ }
+
+ for (auto& it : thumbprints) {
+ if (it.length() > MAX_OIDC_THUMBPRINT_LEN) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+int RGWOIDCProvider::get_providers(RGWRados *store,
+ const string& tenant,
+ vector<RGWOIDCProvider>& providers)
+{
+ auto ctl = store->pctl;
+ auto svc = ctl->svc;
+ auto pool = store->svc.zone->get_zone_params().oidc_pool;
+ string prefix = tenant + oidc_url_oid_prefix;
+
+ //Get the filtered objects
+ list<string> result;
+ bool is_truncated;
+ RGWListRawObjsCtx ctx;
+ do {
+ list<string> oids;
+ int r = store->list_raw_objects(pool, prefix, 1000, ctx, oids, &is_truncated);
+ if (r < 0) {
+ ldout(ctl->cct, 0) << "ERROR: listing filtered objects failed: " << pool.name << ": "
+ << prefix << ": " << cpp_strerror(-r) << dendl;
+ return r;
+ }
+ for (const auto& iter : oids) {
+ RGWOIDCProvider provider(ctl->cct, store->pctl);
+ bufferlist bl;
+ auto obj_ctx = svc->sysobj->init_obj_ctx();
+
+ int ret = rgw_get_system_obj(obj_ctx, pool, iter, bl, NULL, NULL, null_yield);
+ if (ret < 0) {
+ return ret;
+ }
+
+ try {
+ using ceph::decode;
+ auto iter = bl.cbegin();
+ decode(provider, iter);
+ } catch (buffer::error& err) {
+ ldout(ctl->cct, 0) << "ERROR: failed to decode oidc provider info from pool: " << pool.name <<
+ ": " << iter << dendl;
+ return -EIO;
+ }
+
+ providers.push_back(std::move(provider));
+ }
+ } while (is_truncated);
+
+ return 0;
+}
+
+const string& RGWOIDCProvider::get_url_oid_prefix()
+{
+ return oidc_url_oid_prefix;
+}
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+#ifndef CEPH_RGW_OIDC_PROVIDER_H
+#define CEPH_RGW_OIDC_PROVIDER_H
+
+#include <string>
+
+#include "common/ceph_context.h"
+
+class RGWCtl;
+
+class RGWOIDCProvider
+{
+ using string = std::string;
+ static const string oidc_url_oid_prefix;
+ static const string oidc_arn_prefix;
+ static constexpr int MAX_OIDC_NUM_CLIENT_IDS = 100;
+ static constexpr int MAX_OIDC_CLIENT_ID_LEN = 255;
+ static constexpr int MAX_OIDC_NUM_THUMBPRINTS = 5;
+ static constexpr int MAX_OIDC_THUMBPRINT_LEN = 40;
+ static constexpr int MAX_OIDC_URL_LEN = 255;
+
+ CephContext *cct;
+ RGWCtl *ctl;
+ string id;
+ string provider_url;
+ string arn;
+ string creation_date;
+ string tenant;
+ vector<string> client_ids;
+ vector<string> thumbprints;
+
+ int get_tenant_url_from_arn(string& tenant, string& url);
+ int store_url(const string& url, bool exclusive);
+ int read_url(const string& url, const string& tenant);
+ bool validate_input();
+
+public:
+ RGWOIDCProvider(CephContext *cct,
+ RGWCtl *ctl,
+ string provider_url,
+ string tenant,
+ vector<string> client_ids,
+ vector<string> thumbprints)
+ : cct(cct),
+ ctl(ctl),
+ provider_url(std::move(provider_url)),
+ tenant(std::move(tenant)),
+ client_ids(std::move(client_ids)),
+ thumbprints(std::move(thumbprints)) {
+ }
+
+ RGWOIDCProvider(CephContext *cct,
+ RGWCtl *ctl,
+ string arn,
+ string tenant)
+ : cct(cct),
+ ctl(ctl),
+ arn(std::move(arn)),
+ tenant(std::move(tenant)) {
+ }
+
+ RGWOIDCProvider(CephContext *cct,
+ RGWCtl *ctl,
+ string tenant)
+ : cct(cct),
+ ctl(ctl),
+ tenant(std::move(tenant)) {}
+
+ RGWOIDCProvider(CephContext *cct,
+ RGWCtl *ctl)
+ : cct(cct),
+ ctl(ctl) {}
+
+ RGWOIDCProvider() {}
+
+ ~RGWOIDCProvider() = default;
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(3, 1, bl);
+ encode(id, bl);
+ encode(provider_url, bl);
+ encode(arn, bl);
+ encode(creation_date, bl);
+ encode(tenant, bl);
+ encode(client_ids, bl);
+ encode(thumbprints, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::const_iterator& bl) {
+ DECODE_START(2, bl);
+ decode(id, bl);
+ decode(provider_url, bl);
+ decode(arn, bl);
+ decode(creation_date, bl);
+ decode(tenant, bl);
+ decode(client_ids, bl);
+ decode(thumbprints, bl);
+ DECODE_FINISH(bl);
+ }
+
+ const string& get_provider_url() const { return provider_url; }
+ const string& get_arn() const { return arn; }
+ const string& get_create_date() const { return creation_date; }
+ const vector<string>& get_client_ids() const { return client_ids;}
+ const vector<string>& get_thumbprints() const { return thumbprints; }
+
+ int create(bool exclusive);
+ int delete_obj();
+ int get();
+ void dump(Formatter *f) const;
+ void dump_all(Formatter *f) const;
+ void decode_json(JSONObj *obj);
+
+ static const string& get_url_oid_prefix();
+ static int get_providers(RGWRados *store,
+ const string& tenant,
+ vector<RGWOIDCProvider>& providers);
+};
+WRITE_CLASS_ENCODER(RGWOIDCProvider)
+#endif /* CEPH_RGW_OIDC_PROVIDER_H */
+
#include "rgw_rest_role.h"
#include "rgw_rest_user_policy.h"
+#include "rgw_rest_oidc_provider.h"
#define dout_context g_ceph_context
#define dout_subsys ceph_subsys_rgw
return new RGWListUserPolicies;
if (action.compare("DeleteUserPolicy") == 0)
return new RGWDeleteUserPolicy;
+ if (action.compare("CreateOpenIDConnectProvider") == 0)
+ return new RGWCreateOIDCProvider;
+ if (action.compare("ListOpenIDConnectProviders") == 0)
+ return new RGWListOIDCProviders;
+ if (action.compare("GetOpenIDConnectProvider") == 0)
+ return new RGWGetOIDCProvider;
+ if (action.compare("DeleteOpenIDConnectProvider") == 0)
+ return new RGWDeleteOIDCProvider;
}
return nullptr;
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+#include <errno.h>
+
+#include "common/errno.h"
+#include "common/Formatter.h"
+#include "common/ceph_json.h"
+
+#include "include/types.h"
+#include "rgw_string.h"
+
+#include "rgw_common.h"
+#include "rgw_op.h"
+#include "rgw_rest.h"
+#include "rgw_role.h"
+#include "rgw_rest_oidc_provider.h"
+#include "rgw_oidc_provider.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+int RGWRestOIDCProvider::verify_permission()
+{
+ if (s->auth.identity->is_anonymous()) {
+ return -EACCES;
+ }
+
+ provider_arn = s->info.args.get("OpenIDConnectProviderArn");
+ if (provider_arn.empty()) {
+ ldout(s->cct, 20) << "ERROR: Provider ARN is empty"<< dendl;
+ return -EINVAL;
+ }
+
+ auto ret = check_caps(s->user->get_caps());
+ if (ret == 0) {
+ return ret;
+ }
+
+ uint64_t op = get_op();
+ auto rgw_arn = rgw::ARN::parse(provider_arn, true);
+ if (rgw_arn) {
+ if (!verify_user_permission(this, s, *rgw_arn, op)) {
+ return -EACCES;
+ }
+ } else {
+ return -EACCES;
+ }
+
+ return 0;
+}
+
+void RGWRestOIDCProvider::send_response()
+{
+ if (op_ret) {
+ set_req_state_err(s, op_ret);
+ }
+ dump_errno(s);
+ end_header(s, this);
+}
+
+int RGWRestOIDCProviderRead::check_caps(const RGWUserCaps& caps)
+{
+ return caps.check_cap("oidc-provider", RGW_CAP_READ);
+}
+
+int RGWRestOIDCProviderWrite::check_caps(const RGWUserCaps& caps)
+{
+ return caps.check_cap("oidc-provider", RGW_CAP_WRITE);
+}
+
+int RGWCreateOIDCProvider::verify_permission()
+{
+ if (s->auth.identity->is_anonymous()) {
+ return -EACCES;
+ }
+
+ auto ret = check_caps(s->user->get_caps());
+ if (ret == 0) {
+ return ret;
+ }
+
+ string idp_url = provider_url;
+ auto pos = idp_url.find("http://");
+ if (pos == std::string::npos) {
+ pos = idp_url.find("https://");
+ if (pos != std::string::npos) {
+ idp_url.erase(pos, 8);
+ } else {
+ pos = idp_url.find("www.");
+ if (pos != std::string::npos) {
+ idp_url.erase(pos, 4);
+ }
+ }
+ } else {
+ idp_url.erase(pos, 7);
+ }
+ if (!verify_user_permission(this,
+ s,
+ rgw::ARN(idp_url,
+ "oidc-provider",
+ s->user->get_tenant(), true),
+ get_op())) {
+ return -EACCES;
+ }
+ return 0;
+}
+
+int RGWCreateOIDCProvider::get_params()
+{
+ provider_url = s->info.args.get("Url");
+
+ auto val_map = s->info.args.get_params();
+ for (auto& it : val_map) {
+ if (it.first.find("ClientIDList.member.") != string::npos) {
+ client_ids.emplace_back(it.second);
+ }
+ if (it.first.find("ThumbprintList.member.") != string::npos) {
+ thumbprints.emplace_back(it.second);
+ }
+ }
+
+ if (provider_url.empty() || thumbprints.empty()) {
+ ldout(s->cct, 20) << "ERROR: one of url or thumbprints is empty" << dendl;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void RGWCreateOIDCProvider::execute()
+{
+ op_ret = get_params();
+ if (op_ret < 0) {
+ return;
+ }
+
+ RGWOIDCProvider provider(s->cct, store->getRados()->pctl, provider_url,
+ s->user->get_tenant(), client_ids, thumbprints);
+ op_ret = provider.create(true);
+
+ if (op_ret == 0) {
+ s->formatter->open_object_section("CreateOpenIDConnectProviderResponse");
+ s->formatter->open_object_section("CreateOpenIDConnectProviderResult");
+ provider.dump(s->formatter);
+ s->formatter->close_section();
+ s->formatter->open_object_section("ResponseMetadata");
+ s->formatter->dump_string("RequestId", s->trans_id);
+ s->formatter->close_section();
+ s->formatter->close_section();
+ }
+
+}
+
+void RGWDeleteOIDCProvider::execute()
+{
+ RGWOIDCProvider provider(s->cct, store->getRados()->pctl, provider_arn, s->user->get_tenant());
+ op_ret = provider.delete_obj();
+
+ if (op_ret < 0 && op_ret != -ENOENT && op_ret != -EINVAL) {
+ op_ret = ERR_INTERNAL_ERROR;
+ }
+
+ if (op_ret == 0) {
+ s->formatter->open_object_section("DeleteOpenIDConnectProviderResponse");
+ s->formatter->open_object_section("ResponseMetadata");
+ s->formatter->dump_string("RequestId", s->trans_id);
+ s->formatter->close_section();
+ s->formatter->close_section();
+ }
+}
+
+void RGWGetOIDCProvider::execute()
+{
+ RGWOIDCProvider provider(s->cct, store->getRados()->pctl, provider_arn, s->user->get_tenant());
+ op_ret = provider.get();
+
+ if (op_ret < 0 && op_ret != -ENOENT && op_ret != -EINVAL) {
+ op_ret = ERR_INTERNAL_ERROR;
+ }
+
+ if (op_ret == 0) {
+ s->formatter->open_object_section("GetOpenIDConnectProviderResponse");
+ s->formatter->open_object_section("ResponseMetadata");
+ s->formatter->dump_string("RequestId", s->trans_id);
+ s->formatter->close_section();
+ s->formatter->open_object_section("GetOpenIDConnectProviderResult");
+ provider.dump_all(s->formatter);
+ s->formatter->close_section();
+ s->formatter->close_section();
+ }
+}
+
+int RGWListOIDCProviders::verify_permission()
+{
+ if (s->auth.identity->is_anonymous()) {
+ return -EACCES;
+ }
+
+ if (int ret = check_caps(s->user->get_caps()); ret == 0) {
+ return ret;
+ }
+
+ if (!verify_user_permission(this,
+ s,
+ rgw::ARN(),
+ get_op())) {
+ return -EACCES;
+ }
+
+ return 0;
+}
+
+void RGWListOIDCProviders::execute()
+{
+ vector<RGWOIDCProvider> result;
+ op_ret = RGWOIDCProvider::get_providers(store->getRados(), s->user->get_tenant(), result);
+
+ if (op_ret == 0) {
+ s->formatter->open_array_section("ListOpenIDConnectProvidersResponse");
+ s->formatter->open_object_section("ResponseMetadata");
+ s->formatter->dump_string("RequestId", s->trans_id);
+ s->formatter->close_section();
+ s->formatter->open_object_section("ListOpenIDConnectProvidersResult");
+ s->formatter->open_array_section("OpenIDConnectProviderList");
+ for (const auto& it : result) {
+ s->formatter->open_object_section("Arn");
+ auto& arn = it.get_arn();
+ ldout(s->cct, 0) << "ARN: " << arn << dendl;
+ s->formatter->dump_string("Arn", arn);
+ s->formatter->close_section();
+ }
+ s->formatter->close_section();
+ s->formatter->close_section();
+ s->formatter->close_section();
+ }
+}
+
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+#pragma once
+
+#include "rgw_oidc_provider.h"
+
+class RGWRestOIDCProvider : public RGWRESTOp {
+protected:
+ vector<string> client_ids;
+ vector<string> thumbprints;
+ string provider_url; //'iss' field in JWT
+ string provider_arn;
+public:
+ int verify_permission() override;
+ void send_response() override;
+ virtual uint64_t get_op() = 0;
+};
+
+class RGWRestOIDCProviderRead : public RGWRestOIDCProvider {
+public:
+ RGWRestOIDCProviderRead() = default;
+ int check_caps(const RGWUserCaps& caps) override;
+};
+
+class RGWRestOIDCProviderWrite : public RGWRestOIDCProvider {
+public:
+ RGWRestOIDCProviderWrite() = default;
+ int check_caps(const RGWUserCaps& caps) override;
+};
+
+class RGWCreateOIDCProvider : public RGWRestOIDCProviderWrite {
+public:
+ RGWCreateOIDCProvider() = default;
+ int verify_permission() override;
+ void execute() override;
+ int get_params();
+ const char* name() const override { return "create_oidc_provider"; }
+ RGWOpType get_type() override { return RGW_OP_CREATE_OIDC_PROVIDER; }
+ uint64_t get_op() { return rgw::IAM::iamCreateOIDCProvider; }
+};
+
+class RGWDeleteOIDCProvider : public RGWRestOIDCProviderWrite {
+public:
+ RGWDeleteOIDCProvider() = default;
+ void execute() override;
+ const char* name() const override { return "delete_oidc_provider"; }
+ RGWOpType get_type() override { return RGW_OP_DELETE_OIDC_PROVIDER; }
+ uint64_t get_op() { return rgw::IAM::iamDeleteOIDCProvider; }
+};
+
+class RGWGetOIDCProvider : public RGWRestOIDCProviderRead {
+public:
+ RGWGetOIDCProvider() = default;
+ void execute() override;
+ const char* name() const override { return "get_oidc_provider"; }
+ RGWOpType get_type() override { return RGW_OP_GET_OIDC_PROVIDER; }
+ uint64_t get_op() { return rgw::IAM::iamGetOIDCProvider; }
+};
+
+class RGWListOIDCProviders : public RGWRestOIDCProviderRead {
+public:
+ RGWListOIDCProviders() = default;
+ int verify_permission() override;
+ void execute() override;
+ int get_params();
+ const char* name() const override { return "list_oidc_providers"; }
+ RGWOpType get_type() override { return RGW_OP_LIST_OIDC_PROVIDERS; }
+ uint64_t get_op() { return rgw::IAM::iamListOIDCProviders; }
+};
s->op_type == RGW_OP_PUT_USER_POLICY ||
s->op_type == RGW_OP_GET_USER_POLICY ||
s->op_type == RGW_OP_LIST_USER_POLICIES ||
- s->op_type == RGW_OP_DELETE_USER_POLICY) {
+ s->op_type == RGW_OP_DELETE_USER_POLICY ||
+ s->op_type == RGW_OP_CREATE_OIDC_PROVIDER ||
+ s->op_type == RGW_OP_DELETE_OIDC_PROVIDER ||
+ s->op_type == RGW_OP_GET_OIDC_PROVIDER ||
+ s->op_type == RGW_OP_LIST_OIDC_PROVIDERS) {
is_non_s3_op = true;
}
}
pool_names.insert(iter.second.data_extra_pool);
}
+ pool_names.insert(zone.oidc_pool);
}
}
return 0;
roles_pool = fix_zone_pool_dup(pools, name, ".rgw.meta:roles", roles_pool);
reshard_pool = fix_zone_pool_dup(pools, name, ".rgw.log:reshard", reshard_pool);
otp_pool = fix_zone_pool_dup(pools, name, ".rgw.otp", otp_pool);
+ oidc_pool = fix_zone_pool_dup(pools, name, ".rgw.meta:oidc", oidc_pool);
for(auto& iter : placement_pools) {
iter.second.index_pool = fix_zone_pool_dup(pools, name, "." + default_bucket_index_pool_suffix,
rgw_pool roles_pool;
rgw_pool reshard_pool;
rgw_pool otp_pool;
+ rgw_pool oidc_pool;
RGWAccessKey system_key;
const string& get_compression_type(const rgw_placement_rule& placement_rule) const;
void encode(bufferlist& bl) const override {
- ENCODE_START(12, 1, bl);
+ ENCODE_START(13, 1, bl);
encode(domain_root, bl);
encode(control_pool, bl);
encode(gc_pool, bl);
encode(reshard_pool, bl);
encode(otp_pool, bl);
encode(tier_config, bl);
+ encode(oidc_pool, bl);
ENCODE_FINISH(bl);
}
void decode(bufferlist::const_iterator& bl) override {
- DECODE_START(12, bl);
+ DECODE_START(13, bl);
decode(domain_root, bl);
decode(control_pool, bl);
decode(gc_pool, bl);
tier_config.set(kv.first, kv.second);
}
}
+ if (struct_v >= 13) {
+ ::decode(oidc_pool, bl);
+ } else {
+ oidc_pool = name + ".rgw.oidc";
+ }
DECODE_FINISH(bl);
}
void dump(Formatter *f) const;