See `OpenStack Barbican Integration`_, `HashiCorp Vault Integration`_,
and `KMIP Integration`_.
+Bucket Encryption APIs
+======================
+
+Bucket Encryption APIs to support server-side encryption with Amazon
+S3-managed keys (SSE-S3) or AWS KMS customer master keys (SSE-KMS).
+SSE-KMS implementation via BucketEncryption APIs is not supported yet.
+
+See `PutBucketEncryption`_, `GetBucketEncryption`_, `DeleteBucketEncryption`_
+
Automatic Encryption (for testing only)
=======================================
.. _Barbican: https://wiki.openstack.org/wiki/Barbican
.. _Vault: https://www.vaultproject.io/docs/
.. _KMIP: http://www.oasis-open.org/committees/kmip/
+.. _PutBucketEncryption: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html
+.. _GetBucketEncryption: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html
+.. _DeleteBucketEncryption: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketEncryption.html
.. _OpenStack Barbican Integration: ../barbican
.. _HashiCorp Vault Integration: ../vault
.. _KMIP Integration: ../kmip
cls_fifo_legacy.cc
rgw_lua_utils.cc
rgw_lua.cc
- rgw_lua_request.cc)
+ rgw_lua_request.cc
+ rgw_bucket_encryption.cc)
if(WITH_RADOSGW_AMQP_ENDPOINT)
list(APPEND librgw_common_srcs rgw_amqp.cc)
"acl",
"cors",
"delete",
+ "encryption",
"lifecycle",
"location",
"logging",
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+//
+#include "rgw_bucket_encryption.h"
+#include "rgw_xml.h"
+
+void ApplyServerSideEncryptionByDefault::decode_xml(XMLObj *obj) {
+ RGWXMLDecoder::decode_xml("KMSMasterKeyID", kmsMasterKeyID, obj, false);
+ RGWXMLDecoder::decode_xml("SSEAlgorithm", sseAlgorithm, obj, false);
+}
+
+void ApplyServerSideEncryptionByDefault::dump_xml(Formatter *f) const {
+ encode_xml("SSEAlgorithm", sseAlgorithm, f);
+}
+
+void ServerSideEncryptionConfiguration::decode_xml(XMLObj *obj) {
+ RGWXMLDecoder::decode_xml("ApplyServerSideEncryptionByDefault", applyServerSideEncryptionByDefault, obj, true);
+ RGWXMLDecoder::decode_xml("BucketKeyEnabled", bucketKeyEnabled, obj, false);
+}
+
+void ServerSideEncryptionConfiguration::dump_xml(Formatter *f) const {
+ encode_xml("ApplyServerSideEncryptionByDefault", applyServerSideEncryptionByDefault, f);
+}
+
+void RGWBucketEncryptionConfig::decode_xml(XMLObj *obj) {
+ rule_exist = RGWXMLDecoder::decode_xml("Rule", rule, obj);
+ if(!rule_exist) {
+ throw RGWXMLDecoder::err("rule must be present in XML");
+ }
+}
+
+void RGWBucketEncryptionConfig::dump_xml(Formatter *f) const {
+ encode_xml("Rule", rule, f);
+}
--- /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 <include/types.h>
+
+class XMLObj;
+
+class ApplyServerSideEncryptionByDefault
+{
+ string kmsMasterKeyID;
+ string sseAlgorithm;
+
+public:
+ ApplyServerSideEncryptionByDefault(): kmsMasterKeyID(""), sseAlgorithm("") {};
+
+ const string& kms_master_key_id() const {
+ return kmsMasterKeyID;
+ }
+
+ const string& sse_algorithm() const {
+ return sseAlgorithm;
+ }
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(kmsMasterKeyID, bl);
+ encode(sseAlgorithm, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::const_iterator& bl) {
+ DECODE_START(1, bl);
+ decode(kmsMasterKeyID, bl);
+ decode(sseAlgorithm, bl);
+ DECODE_FINISH(bl);
+ }
+
+ void decode_xml(XMLObj *obj);
+ void dump_xml(Formatter *f) const;
+};
+WRITE_CLASS_ENCODER(ApplyServerSideEncryptionByDefault)
+
+class ServerSideEncryptionConfiguration
+{
+protected:
+ ApplyServerSideEncryptionByDefault applyServerSideEncryptionByDefault;
+ bool bucketKeyEnabled;
+
+public:
+ ServerSideEncryptionConfiguration(): bucketKeyEnabled(false) {};
+
+ const string& kms_master_key_id() const {
+ return applyServerSideEncryptionByDefault.kms_master_key_id();
+ }
+
+ const string& sse_algorithm() const {
+ return applyServerSideEncryptionByDefault.sse_algorithm();
+ }
+
+ bool bucket_key_enabled() const {
+ return bucketKeyEnabled;
+ }
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(applyServerSideEncryptionByDefault, bl);
+ encode(bucketKeyEnabled, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::const_iterator& bl) {
+ DECODE_START(1, bl);
+ decode(applyServerSideEncryptionByDefault, bl);
+ decode(bucketKeyEnabled, bl);
+ DECODE_FINISH(bl);
+ }
+
+ void decode_xml(XMLObj *obj);
+ void dump_xml(Formatter *f) const;
+};
+WRITE_CLASS_ENCODER(ServerSideEncryptionConfiguration)
+
+class RGWBucketEncryptionConfig
+{
+protected:
+ bool rule_exist;
+ ServerSideEncryptionConfiguration rule;
+
+public:
+ RGWBucketEncryptionConfig(): rule_exist(false) {}
+
+ const string& kms_master_key_id() const {
+ return rule.kms_master_key_id();
+ }
+
+ const string& sse_algorithm() const {
+ return rule.sse_algorithm();
+ }
+
+ bool bucket_key_enabled() const {
+ return rule.bucket_key_enabled();
+ }
+
+ bool has_rule() const {
+ return rule_exist;
+ }
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(rule_exist, bl);
+ if (rule_exist) {
+ encode(rule, bl);
+ }
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::const_iterator& bl) {
+ DECODE_START(1, bl);
+ decode(rule_exist, bl);
+ if (rule_exist) {
+ decode(rule, bl);
+ }
+ DECODE_FINISH(bl);
+ }
+
+ void decode_xml(XMLObj *obj);
+ void dump_xml(Formatter *f) const;
+};
+WRITE_CLASS_ENCODER(RGWBucketEncryptionConfig)
{ ERR_RATE_LIMITED, {503, "SlowDown"}},
{ ERR_ZERO_IN_URL, {400, "InvalidRequest" }},
{ ERR_NO_SUCH_TAG_SET, {404, "NoSuchTagSetError"}},
+ { ERR_NO_SUCH_BUCKET_ENCRYPTION_CONFIGURATION, {404, "ServerSideEncryptionConfigurationNotFoundError"}},
});
rgw_http_errors rgw_http_swift_errors({
#include "cls/rgw/cls_rgw_types.h"
#include "include/rados/librados.hpp"
#include "rgw_public_access.h"
+#include "rgw_bucket_encryption.h"
namespace ceph {
class Formatter;
#define RGW_ATTR_CRYPT_CONTEXT RGW_ATTR_CRYPT_PREFIX "context"
#define RGW_ATTR_CRYPT_DATAKEY RGW_ATTR_CRYPT_PREFIX "datakey"
+/* SSE-S3 Encryption Attributes */
+#define RGW_ATTR_BUCKET_ENCRYPTION_PREFIX RGW_ATTR_PREFIX "sse-s3."
+#define RGW_ATTR_BUCKET_ENCRYPTION_POLICY RGW_ATTR_BUCKET_ENCRYPTION_PREFIX "policy"
+#define RGW_ATTR_BUCKET_ENCRYPTION_KEY_ID RGW_ATTR_BUCKET_ENCRYPTION_PREFIX "key-id"
+
#define RGW_FORMAT_PLAIN 0
#define RGW_FORMAT_XML 1
#define ERR_NO_SUCH_CORS_CONFIGURATION 2045
#define ERR_NO_SUCH_OBJECT_LOCK_CONFIGURATION 2046
#define ERR_INVALID_RETENTION_PERIOD 2047
+#define ERR_NO_SUCH_BUCKET_ENCRYPTION_CONFIGURATION 2048
#define ERR_USER_SUSPENDED 2100
#define ERR_INTERNAL_ERROR 2200
#define ERR_NOT_IMPLEMENTED 2201
{ "s3:GetAccelerateConfiguration", s3GetAccelerateConfiguration },
{ "s3:GetBucketAcl", s3GetBucketAcl },
{ "s3:GetBucketCORS", s3GetBucketCORS },
+ { "s3:GetBucketEncryption", s3GetBucketEncryption },
{ "s3:GetBucketLocation", s3GetBucketLocation },
{ "s3:GetBucketLogging", s3GetBucketLogging },
{ "s3:GetBucketNotification", s3GetBucketNotification },
{ "s3:PutAccelerateConfiguration", s3PutAccelerateConfiguration },
{ "s3:PutBucketAcl", s3PutBucketAcl },
{ "s3:PutBucketCORS", s3PutBucketCORS },
+ { "s3:PutBucketEncryption", s3PutBucketEncryption },
{ "s3:PutBucketLogging", s3PutBucketLogging },
{ "s3:PutBucketNotification", s3PutBucketNotification },
{ "s3:PutBucketPolicy", s3PutBucketPolicy },
case s3PutBucketCORS:
return "s3:PutBucketCORS";
+ case s3GetBucketEncryption:
+ return "s3:GetBucketEncryption";
+
+ case s3PutBucketEncryption:
+ return "s3:PutBucketEncryption";
+
case s3GetBucketVersioning:
return "s3:GetBucketVersioning";
static constexpr std::uint64_t s3GetBucketPublicAccessBlock = 65;
static constexpr std::uint64_t s3PutBucketPublicAccessBlock = 66;
static constexpr std::uint64_t s3DeleteBucketPublicAccessBlock = 67;
-static constexpr std::uint64_t s3All = 68;
+static constexpr std::uint64_t s3GetBucketEncryption = 68;
+static constexpr std::uint64_t s3PutBucketEncryption = 69;
+static constexpr std::uint64_t s3DeleteBucketEncryption = 70;
+static constexpr std::uint64_t s3All = 71;
static constexpr std::uint64_t iamPutUserPolicy = s3All + 1;
static constexpr std::uint64_t iamGetUserPolicy = s3All + 2;
case s3GetAccelerateConfiguration:
case s3GetBucketAcl:
case s3GetBucketCORS:
+ case s3GetBucketEncryption:
case s3GetBucketLocation:
case s3GetBucketLogging:
case s3GetBucketNotification:
case s3PutAccelerateConfiguration:
case s3PutBucketAcl:
case s3PutBucketCORS:
+ case s3PutBucketEncryption:
case s3PutBucketLogging:
case s3PutBucketNotification:
case s3PutBucketPolicy:
return op_ret;
});
}
+
+int RGWPutBucketEncryption::get_params(optional_yield y)
+{
+ const auto max_size = s->cct->_conf->rgw_max_put_param_size;
+ std::tie(op_ret, data) = read_all_input(s, max_size, false);
+ return op_ret;
+}
+
+int RGWPutBucketEncryption::verify_permission(optional_yield y)
+{
+ if (!verify_bucket_permission(this, s, rgw::IAM::s3PutBucketEncryption)) {
+ return -EACCES;
+ }
+ return 0;
+}
+
+void RGWPutBucketEncryption::execute(optional_yield y)
+{
+ RGWXMLDecoder::XMLParser parser;
+ if (!parser.init()) {
+ ldpp_dout(this, 0) << "ERROR: failed to initialize parser" << dendl;
+ op_ret = -EINVAL;
+ return;
+ }
+ op_ret = get_params(y);
+ if (op_ret < 0) {
+ return;
+ }
+ if (!parser.parse(data.c_str(), data.length(), 1)) {
+ ldpp_dout(this, 0) << "ERROR: malformed XML" << dendl;
+ op_ret = -ERR_MALFORMED_XML;
+ return;
+ }
+
+ try {
+ RGWXMLDecoder::decode_xml("ServerSideEncryptionConfiguration", bucket_encryption_conf, &parser, true);
+ } catch (RGWXMLDecoder::err& err) {
+ ldpp_dout(this, 5) << "unexpected xml:" << err << dendl;
+ op_ret = -ERR_MALFORMED_XML;
+ return;
+ }
+
+ if(bucket_encryption_conf.kms_master_key_id().compare("") != 0) {
+ ldpp_dout(this, 5) << "encryption not supported with sse-kms" << dendl;
+ op_ret = -ERR_NOT_IMPLEMENTED;
+ s->err.message = "SSE-KMS support is not provided";
+ return;
+ }
+
+ if(bucket_encryption_conf.sse_algorithm().compare("AES256") != 0) {
+ ldpp_dout(this, 5) << "only aes256 algorithm is supported for encryption" << dendl;
+ op_ret = -ERR_NOT_IMPLEMENTED;
+ s->err.message = "Encryption is supported only with AES256 algorithm";
+ return;
+ }
+
+ op_ret = store->forward_request_to_master(this, s->user.get(), nullptr, data, nullptr, s->info, y);
+ if (op_ret < 0) {
+ ldpp_dout(this, 20) << "forward_request_to_master returned ret=" << op_ret << dendl;
+ return;
+ }
+
+ bufferlist key_id_bl;
+ string bucket_owner_id = s->bucket->get_info().owner.id;
+ key_id_bl.append(bucket_owner_id.c_str(), bucket_owner_id.size() + 1);
+
+ bufferlist conf_bl;
+ bucket_encryption_conf.encode(conf_bl);
+ op_ret = retry_raced_bucket_write(this, s->bucket.get(), [this, y, &conf_bl, &key_id_bl] {
+ rgw::sal::Attrs attrs = s->bucket->get_attrs();
+ attrs[RGW_ATTR_BUCKET_ENCRYPTION_POLICY] = conf_bl;
+ attrs[RGW_ATTR_BUCKET_ENCRYPTION_KEY_ID] = key_id_bl;
+ return s->bucket->set_instance_attrs(this, attrs, y);
+ });
+}
+
+int RGWGetBucketEncryption::verify_permission(optional_yield y)
+{
+ if (!verify_bucket_permission(this, s, rgw::IAM::s3GetBucketEncryption)) {
+ return -EACCES;
+ }
+ return 0;
+}
+
+void RGWGetBucketEncryption::execute(optional_yield y)
+{
+ const auto& attrs = s->bucket_attrs;
+ if (auto aiter = attrs.find(RGW_ATTR_BUCKET_ENCRYPTION_POLICY);
+ aiter == attrs.end()) {
+ ldpp_dout(this, 0) << "can't find BUCKET ENCRYPTION attr for bucket_name = " << s->bucket_name << dendl;
+ op_ret = -ENOENT;
+ s->err.message = "The server side encryption configuration was not found";
+ return;
+ } else {
+ bufferlist::const_iterator iter{&aiter->second};
+ try {
+ bucket_encryption_conf.decode(iter);
+ } catch (const buffer::error& e) {
+ ldpp_dout(this, 0) << __func__ << "decode bucket_encryption_conf failed" << dendl;
+ op_ret = -EIO;
+ return;
+ }
+ }
+}
+
+int RGWDeleteBucketEncryption::verify_permission(optional_yield y)
+{
+ if (!verify_bucket_permission(this, s, rgw::IAM::s3PutBucketEncryption)) {
+ return -EACCES;
+ }
+ return 0;
+}
+
+void RGWDeleteBucketEncryption::execute(optional_yield y)
+{
+ bufferlist data;
+ op_ret = store->forward_request_to_master(this, s->user.get(), nullptr, data, nullptr, s->info, y);
+ if (op_ret < 0) {
+ ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
+ return;
+ }
+
+ op_ret = retry_raced_bucket_write(this, s->bucket.get(), [this, y] {
+ rgw::sal::Attrs attrs = s->bucket->get_attrs();
+ attrs.erase(RGW_ATTR_BUCKET_ENCRYPTION_POLICY);
+ attrs.erase(RGW_ATTR_BUCKET_ENCRYPTION_KEY_ID);
+ op_ret = s->bucket->set_instance_attrs(this, attrs, y);
+ return op_ret;
+ });
+}
#include "rgw_object_lock.h"
#include "cls/rgw/cls_rgw_client.h"
#include "rgw_public_access.h"
+#include "rgw_bucket_encryption.h"
#include "services/svc_sys_obj.h"
#include "services/svc_tier_rados.h"
uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
};
+class RGWPutBucketEncryption : public RGWOp {
+protected:
+ RGWBucketEncryptionConfig bucket_encryption_conf;
+ bufferlist data;
+public:
+ RGWPutBucketEncryption() = default;
+ ~RGWPutBucketEncryption() {}
+
+ int get_params(optional_yield y);
+ int verify_permission(optional_yield y) override;
+ void execute(optional_yield y) override;
+ const char* name() const override { return "put_bucket_encryption"; }
+ RGWOpType get_type() override { return RGW_OP_PUT_BUCKET_ENCRYPTION; }
+ uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
+};
+
+class RGWGetBucketEncryption : public RGWOp {
+protected:
+ RGWBucketEncryptionConfig bucket_encryption_conf;
+public:
+ RGWGetBucketEncryption() {}
+
+ int get_params(optional_yield y);
+ int verify_permission(optional_yield y) override;
+ void execute(optional_yield y) override;
+ const char* name() const override { return "get_bucket_encryption"; }
+ RGWOpType get_type() override { return RGW_OP_GET_BUCKET_ENCRYPTION; }
+ uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
+};
+
+class RGWDeleteBucketEncryption : public RGWOp {
+protected:
+ RGWBucketEncryptionConfig bucket_encryption_conf;
+public:
+ RGWDeleteBucketEncryption() {}
+
+ int get_params(optional_yield y);
+ int verify_permission(optional_yield y) override;
+ void execute(optional_yield y) override;
+ const char* name() const override { return "delete_bucket_encryption"; }
+ RGWOpType get_type() override { return RGW_OP_DELETE_BUCKET_ENCRYPTION; }
+ uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
+};
+
class RGWGetRequestPayment : public RGWOp {
protected:
bool requester_pays;
RGW_OP_PUT_CORS,
RGW_OP_DELETE_CORS,
RGW_OP_OPTIONS_CORS,
+ RGW_OP_GET_BUCKET_ENCRYPTION,
+ RGW_OP_PUT_BUCKET_ENCRYPTION,
+ RGW_OP_DELETE_BUCKET_ENCRYPTION,
RGW_OP_GET_REQUEST_PAYMENT,
RGW_OP_SET_REQUEST_PAYMENT,
RGW_OP_INIT_MULTIPART,
~RGWOptionsCORS_ObjStore() override {}
};
+class RGWGetBucketEncryption_ObjStore : public RGWGetBucketEncryption {
+public:
+ RGWGetBucketEncryption_ObjStore() {}
+ ~RGWGetBucketEncryption_ObjStore() override {}
+};
+
+class RGWPutBucketEncryption_ObjStore : public RGWPutBucketEncryption {
+public:
+ RGWPutBucketEncryption_ObjStore() {}
+ ~RGWPutBucketEncryption_ObjStore() override {}
+};
+
+class RGWDeleteBucketEncryption_ObjStore : public RGWDeleteBucketEncryption {
+public:
+ RGWDeleteBucketEncryption_ObjStore() {}
+ ~RGWDeleteBucketEncryption_ObjStore() override {}
+};
+
class RGWInitMultipart_ObjStore : public RGWInitMultipart {
public:
RGWInitMultipart_ObjStore() {}
end_header(s, NULL);
}
+void RGWPutBucketEncryption_ObjStore_S3::send_response()
+{
+ if (op_ret) {
+ set_req_state_err(s, op_ret);
+ }
+ dump_errno(s);
+ end_header(s);
+}
+
+void RGWGetBucketEncryption_ObjStore_S3::send_response()
+{
+ if (op_ret) {
+ if (op_ret == -ENOENT)
+ set_req_state_err(s, ERR_NO_SUCH_BUCKET_ENCRYPTION_CONFIGURATION);
+ else
+ set_req_state_err(s, op_ret);
+ }
+
+ dump_errno(s);
+ end_header(s, this, "application/xml");
+ dump_start(s);
+
+ if (!op_ret) {
+ encode_xml("ServerSideEncryptionConfiguration", bucket_encryption_conf, s->formatter);
+ rgw_flush_formatter_and_reset(s, s->formatter);
+ }
+}
+
+void RGWDeleteBucketEncryption_ObjStore_S3::send_response()
+{
+ if (op_ret == 0) {
+ op_ret = STATUS_NO_CONTENT;
+ }
+
+ set_req_state_err(s, op_ret);
+ dump_errno(s);
+ end_header(s);
+}
+
void RGWGetRequestPayment_ObjStore_S3::send_response()
{
dump_errno(s);
return new RGWGetBucketPolicyStatus_ObjStore_S3;
} else if (is_block_public_access_op()) {
return new RGWGetBucketPublicAccessBlock_ObjStore_S3;
+ } else if (is_bucket_encryption_op()) {
+ return new RGWGetBucketEncryption_ObjStore_S3;
}
return get_obj_op(true);
}
return new RGWPutBucketReplication_ObjStore_S3;
} else if (is_block_public_access_op()) {
return new RGWPutBucketPublicAccessBlock_ObjStore_S3;
+ } else if (is_bucket_encryption_op()) {
+ return new RGWPutBucketEncryption_ObjStore_S3;
}
return new RGWCreateBucket_ObjStore_S3;
}
return new RGWDeleteBucketReplication_ObjStore_S3;
} else if (is_block_public_access_op()) {
return new RGWDeleteBucketPublicAccessBlock;
+ } else if (is_bucket_encryption_op()) {
+ return new RGWDeleteBucketEncryption_ObjStore_S3;
}
if (s->info.args.sub_resource_exists("website")) {
case RGW_OP_PUT_OBJ:
case RGW_OP_PUT_ACLS:
case RGW_OP_PUT_CORS:
+ case RGW_OP_PUT_BUCKET_ENCRYPTION:
+ case RGW_OP_GET_BUCKET_ENCRYPTION:
+ case RGW_OP_DELETE_BUCKET_ENCRYPTION:
case RGW_OP_INIT_MULTIPART: // in case that Init Multipart uses CHUNK encoding
case RGW_OP_COMPLETE_MULTIPART:
case RGW_OP_SET_BUCKET_VERSIONING:
void send_response() override;
};
+class RGWGetBucketEncryption_ObjStore_S3 : public RGWGetBucketEncryption_ObjStore {
+public:
+ RGWGetBucketEncryption_ObjStore_S3() {}
+ ~RGWGetBucketEncryption_ObjStore_S3() override {}
+
+ void send_response() override;
+};
+
+class RGWPutBucketEncryption_ObjStore_S3 : public RGWPutBucketEncryption_ObjStore {
+public:
+ RGWPutBucketEncryption_ObjStore_S3() {}
+ ~RGWPutBucketEncryption_ObjStore_S3() override {}
+
+ void send_response() override;
+};
+
+class RGWDeleteBucketEncryption_ObjStore_S3 : public RGWDeleteBucketEncryption_ObjStore {
+public:
+ RGWDeleteBucketEncryption_ObjStore_S3() {}
+ ~RGWDeleteBucketEncryption_ObjStore_S3() override {}
+
+ void send_response() override;
+};
+
class RGWGetRequestPayment_ObjStore_S3 : public RGWGetRequestPayment {
public:
RGWGetRequestPayment_ObjStore_S3() {}
bool is_block_public_access_op() {
return s->info.args.exists("publicAccessBlock");
}
+ bool is_bucket_encryption_op() {
+ return s->info.args.exists("encryption");
+ }
RGWOp *get_obj_op(bool get_data) const;
RGWOp *op_get() override;
using rgw::IAM::s3GetBucketPolicy;
using rgw::IAM::s3GetBucketPolicyStatus;
using rgw::IAM::s3GetBucketPublicAccessBlock;
+using rgw::IAM::s3GetBucketEncryption;
using rgw::IAM::s3GetBucketRequestPayment;
using rgw::IAM::s3GetBucketTagging;
using rgw::IAM::s3GetBucketVersioning;
act2[s3GetBucketPolicyStatus] = 1;
act2[s3GetBucketPublicAccessBlock] = 1;
act2[s3GetPublicAccessBlock] = 1;
+ act2[s3GetBucketEncryption] = 1;
EXPECT_EQ(p->statements[2].action, act2);
EXPECT_EQ(p->statements[2].notaction, None);
s3allow[s3GetBucketPolicyStatus] = 1;
s3allow[s3GetBucketPublicAccessBlock] = 1;
s3allow[s3GetPublicAccessBlock] = 1;
+ s3allow[s3GetBucketEncryption] = 1;
EXPECT_EQ(p.eval(em, none, s3PutBucketPolicy,
ARN(Partition::aws, Service::s3,