From 9c1cf28dd0e7e1eb03abfb3374118b2eb77c092a Mon Sep 17 00:00:00 2001 From: Jiaying Ren Date: Tue, 18 Jul 2017 15:50:55 +0800 Subject: [PATCH] rgw: check placement existence when create bucket Signed-off-by: Jiaying Ren --- src/rgw/rgw_common.cc | 1 + src/rgw/rgw_common.h | 1 + src/rgw/rgw_rados.cc | 55 ++++++++++++++++++++++++++----------------- src/rgw/rgw_rados.h | 2 +- 4 files changed, 36 insertions(+), 23 deletions(-) diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc index 05b92d2ee5a4..4f5c4c7c6f5b 100644 --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@ -62,6 +62,7 @@ rgw_http_errors rgw_http_s3_errors({ { ERR_INVALID_DIGEST, {400, "InvalidDigest" }}, { ERR_BAD_DIGEST, {400, "BadDigest" }}, { ERR_INVALID_LOCATION_CONSTRAINT, {400, "InvalidLocationConstraint" }}, + { ERR_ZONEGROUP_DEFAULT_PLACEMENT_MISCONFIGURATION, {400, "ZonegroupDefaultPlacementMisconfiguration" }}, { ERR_INVALID_BUCKET_NAME, {400, "InvalidBucketName" }}, { ERR_INVALID_OBJECT_NAME, {400, "InvalidObjectName" }}, { ERR_UNRESOLVABLE_EMAIL, {400, "UnresolvableGrantByEmailAddress" }}, diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index b8dfb49d74a3..d76c57c34e74 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -214,6 +214,7 @@ using ceph::crypto::MD5; #define ERR_INVALID_TAG 2210 #define ERR_ZERO_IN_URL 2211 #define ERR_MALFORMED_ACL_ERROR 2212 +#define ERR_ZONEGROUP_DEFAULT_PLACEMENT_MISCONFIGURATION 2213 #define ERR_BUSY_RESHARDING 2300 diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index a928d74912e4..cc917bd59296 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -5865,7 +5865,7 @@ int RGWRados::select_new_bucket_location(RGWUserInfo& user_info, const string& z string *pselected_rule_name, RGWZonePlacementInfo *rule_info) { - /* first check that rule exists within the specific zonegroup */ + /* first check that zonegroup exists within current period. */ RGWZoneGroup zonegroup; int ret = get_zonegroup(zonegroup_id, zonegroup); if (ret < 0) { @@ -5873,37 +5873,48 @@ int RGWRados::select_new_bucket_location(RGWUserInfo& user_info, const string& z return ret; } - /* now check that tag exists within zonegroup */ /* find placement rule. Hierarchy: request rule > user default rule > zonegroup default rule */ - string rule = request_rule; - if (rule.empty()) { - rule = user_info.default_placement; - if (rule.empty()) - rule = zonegroup.default_placement; - } - - if (rule.empty()) { - ldout(cct, 0) << "misconfiguration, should not have an empty placement rule name" << dendl; - return -EIO; - } - - map::iterator titer = zonegroup.placement_targets.find(rule); - if (titer == zonegroup.placement_targets.end()) { - ldout(cct, 0) << "could not find placement rule " << rule << " within zonegroup " << dendl; - return -EINVAL; + std::map::const_iterator titer; + + if (!request_rule.empty()) { + titer = zonegroup.placement_targets.find(request_rule); + if (titer == zonegroup.placement_targets.end()) { + ldout(cct, 0) << "could not find requested placement id " << request_rule + << " within zonegroup " << dendl; + return -ERR_INVALID_LOCATION_CONSTRAINT; + } + } else if (!user_info.default_placement.empty()) { + titer = zonegroup.placement_targets.find(user_info.default_placement); + if (titer == zonegroup.placement_targets.end()) { + ldout(cct, 0) << "could not find user default placement id " << user_info.default_placement + << " within zonegroup " << dendl; + return -ERR_INVALID_LOCATION_CONSTRAINT; + } + } else { + if (zonegroup.default_placement.empty()) { // zonegroup default rule as fallback, it should not be empty. + ldout(cct, 0) << "misconfiguration, zonegroup default placement id should not be empty." << dendl; + return -ERR_ZONEGROUP_DEFAULT_PLACEMENT_MISCONFIGURATION; + } else { + titer = zonegroup.placement_targets.find(zonegroup.default_placement); + if (titer == zonegroup.placement_targets.end()) { + ldout(cct, 0) << "could not find zonegroup default placement id " << zonegroup.default_placement + << " within zonegroup " << dendl; + return -ERR_INVALID_LOCATION_CONSTRAINT; + } + } } /* now check tag for the rule, whether user is permitted to use rule */ - RGWZoneGroupPlacementTarget& target_rule = titer->second; + const auto& target_rule = titer->second; if (!target_rule.user_permitted(user_info.placement_tags)) { - ldout(cct, 0) << "user not permitted to use placement rule" << dendl; + ldout(cct, 0) << "user not permitted to use placement rule " << titer->first << dendl; return -EPERM; } if (pselected_rule_name) - *pselected_rule_name = rule; + *pselected_rule_name = titer->first; - return select_bucket_location_by_rule(rule, rule_info); + return select_bucket_location_by_rule(titer->first, rule_info); } int RGWRados::select_bucket_location_by_rule(const string& location_rule, RGWZonePlacementInfo *rule_info) diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 6397aac056c5..c864d48d2671 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1429,7 +1429,7 @@ struct RGWZoneGroupPlacementTarget { string name; set tags; - bool user_permitted(list& user_tags) { + bool user_permitted(list& user_tags) const { if (tags.empty()) { return true; } -- 2.47.3