]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/rgw/rgw_rest_role.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / rgw / rgw_rest_role.cc
index a831d80711e4c08b34e52941aaa48cf8fa5e5a60..0fa0f8f011554cf755b1aaf36f69ec2edcf3ad25 100644 (file)
@@ -2,6 +2,7 @@
 // vim: ts=8 sw=2 smarttab ft=cpp
 
 #include <errno.h>
+#include <regex>
 
 #include "common/errno.h"
 #include "common/Formatter.h"
 #include "rgw_rest.h"
 #include "rgw_role.h"
 #include "rgw_rest_role.h"
-#include "rgw_sal_rados.h"
+#include "rgw_sal.h"
 
 #define dout_subsys ceph_subsys_rgw
 
+using namespace std;
+
 int RGWRestRole::verify_permission(optional_yield y)
 {
   if (s->auth.identity->is_anonymous()) {
@@ -26,8 +29,9 @@ int RGWRestRole::verify_permission(optional_yield y)
   }
 
   string role_name = s->info.args.get("RoleName");
-  RGWRole role(s->cct, store->getRados()->pctl, role_name, s->user->get_tenant());
-  if (op_ret = role.get(s, y); op_ret < 0) {
+  std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(role_name,
+                                                           s->user->get_tenant());
+  if (op_ret = role->get(s, y); op_ret < 0) {
     if (op_ret == -ENOENT) {
       op_ret = -ERR_NO_ROLE_FOUND;
     }
@@ -39,7 +43,7 @@ int RGWRestRole::verify_permission(optional_yield y)
     return ret;
   }
 
-  string resource_name = role.get_path() + role_name;
+  string resource_name = role->get_path() + role_name;
   uint64_t op = get_op();
   if (!verify_user_permission(this,
                               s,
@@ -55,6 +59,52 @@ int RGWRestRole::verify_permission(optional_yield y)
   return 0;
 }
 
+int RGWRestRole::parse_tags()
+{
+  vector<string> keys, vals;
+  auto val_map = s->info.args.get_params();
+  const regex pattern_key("Tags.member.([0-9]+).Key");
+  const regex pattern_value("Tags.member.([0-9]+).Value");
+  for (auto& v : val_map) {
+    string key_index="", value_index="";
+    for(sregex_iterator it = sregex_iterator(
+        v.first.begin(), v.first.end(), pattern_key);
+        it != sregex_iterator(); it++) {
+        smatch match;
+        match = *it;
+        key_index = match.str(1);
+        ldout(s->cct, 20) << "Key index: " << match.str(1) << dendl;
+        if (!key_index.empty()) {
+          int index = stoi(key_index);
+          auto pos = keys.begin() + (index-1);
+          keys.insert(pos, v.second);
+        }
+    }
+    for(sregex_iterator it = sregex_iterator(
+        v.first.begin(), v.first.end(), pattern_value);
+        it != sregex_iterator(); it++) {
+        smatch match;
+        match = *it;
+        value_index = match.str(1);
+        ldout(s->cct, 20) << "Value index: " << match.str(1) << dendl;
+        if (!value_index.empty()) {
+          int index = stoi(value_index);
+          auto pos = vals.begin() + (index-1);
+          vals.insert(pos, v.second);
+        }
+    }
+  }
+  if (keys.size() != vals.size()) {
+    ldout(s->cct, 0) << "No. of keys doesn't match with no. of values in tags" << dendl;
+    return -EINVAL;
+  }
+  for (size_t i = 0; i < keys.size(); i++) {
+    tags.emplace(keys[i], vals[i]);
+    ldout(s->cct, 0) << "Tag Key: " << keys[i] << " Tag Value is: " << vals[i] << dendl;
+  }
+  return 0;
+}
+
 void RGWRestRole::send_response()
 {
   if (op_ret) {
@@ -121,6 +171,16 @@ int RGWCreateRole::get_params()
     return -ERR_MALFORMED_DOC;
   }
 
+  int ret = parse_tags();
+  if (ret < 0) {
+    return ret;
+  }
+
+  if (tags.size() > 50) {
+    ldout(s->cct, 0) << "No. tags is greater than 50" << dendl;
+    return -EINVAL;
+  }
+
   return 0;
 }
 
@@ -131,16 +191,19 @@ void RGWCreateRole::execute(optional_yield y)
     return;
   }
   std::string user_tenant = s->user->get_tenant();
-  RGWRole role(s->cct, store->getRados()->pctl, role_name, role_path, trust_policy,
-             user_tenant, max_session_duration);
-  if (!user_tenant.empty() && role.get_tenant() != user_tenant) {
+  std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(role_name,
+                                                           user_tenant,
+                                                           role_path,
+                                                           trust_policy,
+                                                           max_session_duration,
+                       tags);
+  if (!user_tenant.empty() && role->get_tenant() != user_tenant) {
     ldpp_dout(this, 20) << "ERROR: the tenant provided in the role name does not match with the tenant of the user creating the role"
-                        << dendl;
+    << dendl;
     op_ret = -EINVAL;
     return;
   }
-  op_ret = role.create(s, true, y);
-
+  op_ret = role->create(s, true, y);
   if (op_ret == -EEXIST) {
     op_ret = -ERR_ROLE_EXISTS;
   }
@@ -149,7 +212,7 @@ void RGWCreateRole::execute(optional_yield y)
     s->formatter->open_object_section("CreateRoleResponse");
     s->formatter->open_object_section("CreateRoleResult");
     s->formatter->open_object_section("Role");
-    role.dump(s->formatter);
+    role->dump(s->formatter);
     s->formatter->close_section();
     s->formatter->close_section();
     s->formatter->open_object_section("ResponseMetadata");
@@ -178,7 +241,7 @@ void RGWDeleteRole::execute(optional_yield y)
     return;
   }
 
-  op_ret = _role.delete_obj(s, y);
+  op_ret = _role->delete_obj(s, y);
 
   if (op_ret == -ENOENT) {
     op_ret = -ERR_NO_ROLE_FOUND;
@@ -197,7 +260,7 @@ int RGWGetRole::verify_permission(optional_yield y)
   return 0;
 }
 
-int RGWGetRole::_verify_permission(const RGWRole& role)
+int RGWGetRole::_verify_permission(const rgw::sal::RGWRole* role)
 {
   if (s->auth.identity->is_anonymous()) {
     return -EACCES;
@@ -207,7 +270,7 @@ int RGWGetRole::_verify_permission(const RGWRole& role)
     return ret;
   }
 
-  string resource_name = role.get_path() + role.get_name();
+  string resource_name = role->get_path() + role->get_name();
   if (!verify_user_permission(this,
                               s,
                               rgw::ARN(resource_name,
@@ -237,15 +300,16 @@ void RGWGetRole::execute(optional_yield y)
   if (op_ret < 0) {
     return;
   }
-  RGWRole role(s->cct, store->getRados()->pctl, role_name, s->user->get_tenant());
-  op_ret = role.get(s, y);
+  std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(role_name,
+                                                           s->user->get_tenant());
+  op_ret = role->get(s, y);
 
   if (op_ret == -ENOENT) {
     op_ret = -ERR_NO_ROLE_FOUND;
     return;
   }
 
-  op_ret = _verify_permission(role);
+  op_ret = _verify_permission(role.get());
 
   if (op_ret == 0) {
     s->formatter->open_object_section("GetRoleResponse");
@@ -254,7 +318,7 @@ void RGWGetRole::execute(optional_yield y)
     s->formatter->close_section();
     s->formatter->open_object_section("GetRoleResult");
     s->formatter->open_object_section("Role");
-    role.dump(s->formatter);
+    role->dump(s->formatter);
     s->formatter->close_section();
     s->formatter->close_section();
     s->formatter->close_section();
@@ -286,8 +350,8 @@ void RGWModifyRole::execute(optional_yield y)
     return;
   }
 
-  _role.update_trust_policy(trust_policy);
-  op_ret = _role.update(this, y);
+  _role->update_trust_policy(trust_policy);
+  op_ret = _role->update(this, y);
 
   s->formatter->open_object_section("UpdateAssumeRolePolicyResponse");
   s->formatter->open_object_section("ResponseMetadata");
@@ -329,23 +393,23 @@ void RGWListRoles::execute(optional_yield y)
   if (op_ret < 0) {
     return;
   }
-  vector<RGWRole> result;
-  op_ret = RGWRole::get_roles_by_path_prefix(s, store->getRados(), s->cct, path_prefix, s->user->get_tenant(), result, y);
+  vector<std::unique_ptr<rgw::sal::RGWRole>> result;
+  op_ret = store->get_roles(s, y, path_prefix, s->user->get_tenant(), result);
 
   if (op_ret == 0) {
     s->formatter->open_array_section("ListRolesResponse");
-    s->formatter->open_object_section("ResponseMetadata");
-    s->formatter->dump_string("RequestId", s->trans_id);
-    s->formatter->close_section();
     s->formatter->open_array_section("ListRolesResult");
     s->formatter->open_object_section("Roles");
     for (const auto& it : result) {
       s->formatter->open_object_section("member");
-      it.dump(s->formatter);
+      it->dump(s->formatter);
       s->formatter->close_section();
     }
     s->formatter->close_section();
     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();
   }
 }
@@ -378,8 +442,8 @@ void RGWPutRolePolicy::execute(optional_yield y)
     return;
   }
 
-  _role.set_perm_policy(policy_name, perm_policy);
-  op_ret = _role.update(this, y);
+  _role->set_perm_policy(policy_name, perm_policy);
+  op_ret = _role->update(this, y);
 
   if (op_ret == 0) {
     s->formatter->open_object_section("PutRolePolicyResponse");
@@ -410,7 +474,7 @@ void RGWGetRolePolicy::execute(optional_yield y)
   }
 
   string perm_policy;
-  op_ret = _role.get_role_policy(policy_name, perm_policy);
+  op_ret = _role->get_role_policy(this, policy_name, perm_policy);
   if (op_ret == -ENOENT) {
     op_ret = -ERR_NO_SUCH_ENTITY;
   }
@@ -447,7 +511,7 @@ void RGWListRolePolicies::execute(optional_yield y)
     return;
   }
 
-  std::vector<string> policy_names = _role.get_role_policy_names();
+  std::vector<string> policy_names = _role->get_role_policy_names();
   s->formatter->open_object_section("ListRolePoliciesResponse");
   s->formatter->open_object_section("ResponseMetadata");
   s->formatter->dump_string("RequestId", s->trans_id);
@@ -481,13 +545,13 @@ void RGWDeleteRolePolicy::execute(optional_yield y)
     return;
   }
 
-  op_ret = _role.delete_policy(policy_name);
+  op_ret = _role->delete_policy(this, policy_name);
   if (op_ret == -ENOENT) {
     op_ret = -ERR_NO_ROLE_FOUND;
   }
 
   if (op_ret == 0) {
-    op_ret = _role.update(this, y);
+    op_ret = _role->update(this, y);
   }
 
   s->formatter->open_object_section("DeleteRolePoliciesResponse");
@@ -496,3 +560,118 @@ void RGWDeleteRolePolicy::execute(optional_yield y)
   s->formatter->close_section();
   s->formatter->close_section();
 }
+
+int RGWTagRole::get_params()
+{
+  role_name = s->info.args.get("RoleName");
+
+  if (role_name.empty()) {
+    ldout(s->cct, 0) << "ERROR: Role name is empty" << dendl;
+    return -EINVAL;
+  }
+  int ret = parse_tags();
+  if (ret < 0) {
+    return ret;
+  }
+
+  return 0;
+}
+
+void RGWTagRole::execute(optional_yield y)
+{
+  op_ret = get_params();
+  if (op_ret < 0) {
+    return;
+  }
+
+  op_ret = _role->set_tags(this, tags);
+  if (op_ret == 0) {
+    op_ret = _role->update(this, y);
+  }
+
+  if (op_ret == 0) {
+    s->formatter->open_object_section("TagRoleResponse");
+    s->formatter->open_object_section("ResponseMetadata");
+    s->formatter->dump_string("RequestId", s->trans_id);
+    s->formatter->close_section();
+    s->formatter->close_section();
+  }
+}
+
+int RGWListRoleTags::get_params()
+{
+  role_name = s->info.args.get("RoleName");
+
+  if (role_name.empty()) {
+    ldout(s->cct, 0) << "ERROR: Role name is empty" << dendl;
+    return -EINVAL;
+  }
+
+  return 0;
+}
+
+void RGWListRoleTags::execute(optional_yield y)
+{
+  op_ret = get_params();
+  if (op_ret < 0) {
+    return;
+  }
+
+  boost::optional<multimap<string,string>> tag_map = _role->get_tags();
+  s->formatter->open_object_section("ListRoleTagsResponse");
+  s->formatter->open_object_section("ListRoleTagsResult");
+  if (tag_map) {
+    s->formatter->open_array_section("Tags");
+    for (const auto& it : tag_map.get()) {
+      s->formatter->open_object_section("Key");
+      encode_json("Key", it.first, s->formatter);
+      s->formatter->close_section();
+      s->formatter->open_object_section("Value");
+      encode_json("Value", it.second, s->formatter);
+      s->formatter->close_section();
+    }
+    s->formatter->close_section();
+  }
+  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();
+}
+
+int RGWUntagRole::get_params()
+{
+  role_name = s->info.args.get("RoleName");
+
+  if (role_name.empty()) {
+    ldout(s->cct, 0) << "ERROR: Role name is empty" << dendl;
+    return -EINVAL;
+  }
+
+  auto val_map = s->info.args.get_params();
+  for (auto& it : val_map) {
+    if (it.first.find("TagKeys.member.") != string::npos) {
+        tagKeys.emplace_back(it.second);
+    }
+  }
+  return 0;
+}
+
+void RGWUntagRole::execute(optional_yield y)
+{
+  op_ret = get_params();
+  if (op_ret < 0) {
+    return;
+  }
+
+  _role->erase_tags(tagKeys);
+  op_ret = _role->update(this, y);
+
+  if (op_ret == 0) {
+    s->formatter->open_object_section("UntagRoleResponse");
+    s->formatter->open_object_section("ResponseMetadata");
+    s->formatter->dump_string("RequestId", s->trans_id);
+    s->formatter->close_section();
+    s->formatter->close_section();
+  }
+}
\ No newline at end of file