summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@inktank.com>2012-10-23 10:15:36 -0700
committerYehuda Sadeh <yehuda@inktank.com>2012-10-23 10:43:09 -0700
commit5b90d10bc25372f8a0b34f1c958daa9ec42b0518 (patch)
tree2fc596409492c25c3813d52ad64539b42e0b6308
parent81f257d5839c63aaab33e4070f1e9597b3240890 (diff)
downloadceph-5b90d10bc25372f8a0b34f1c958daa9ec42b0518.tar.gz
rgw: basic policy functionality
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r--src/Makefile.am2
-rw-r--r--src/rgw/rgw_policy_s3.cc170
-rw-r--r--src/rgw/rgw_policy_s3.h41
3 files changed, 213 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 50feab6c15a..5754c94da0f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -326,6 +326,7 @@ librgw_a_SOURCES = \
rgw/rgw_formats.cc \
rgw/rgw_log.cc \
rgw/rgw_multi.cc \
+ rgw/rgw_policy_s3.cc \
rgw/rgw_gc.cc \
rgw/rgw_multi_del.cc \
rgw/rgw_env.cc
@@ -1761,6 +1762,7 @@ noinst_HEADERS = \
rgw/rgw_html_errors.h\
rgw/rgw_log.h\
rgw/rgw_multi.h\
+ rgw/rgw_policy_s3.h\
rgw/rgw_gc.h\
rgw/rgw_multi_del.h\
rgw/rgw_op.h\
diff --git a/src/rgw/rgw_policy_s3.cc b/src/rgw/rgw_policy_s3.cc
new file mode 100644
index 00000000000..4edaa94fe14
--- /dev/null
+++ b/src/rgw/rgw_policy_s3.cc
@@ -0,0 +1,170 @@
+
+#include <errno.h>
+
+#include "rgw_policy_s3.h"
+#include "rgw_json.h"
+
+#include "rgw_common.h"
+
+
+#define dout_subsys ceph_subsys_rgw
+
+
+class RGWPolicyCondition {
+protected:
+ string v1;
+ string v2;
+
+ virtual bool check(const string& first, const string& second) = 0;
+
+public:
+ virtual ~RGWPolicyCondition() {}
+
+ void set_vals(const string& _v1, const string& _v2) {
+ v1 = _v1;
+ v2 = _v2;
+ }
+
+ bool check(RGWPolicyEnv *env) {
+ string first, second;
+ env->get_value(v1, first);
+ env->get_value(v2, second);
+ dout(1) << "policy condition check " << v1 << " [" << first << "] " << v2 << " [" << second << "]" << dendl;
+ return check(first, second);
+ }
+
+};
+
+
+class RGWPolicyCondition_StrEqual : public RGWPolicyCondition {
+protected:
+ bool check(const string& first, const string& second) {
+ return first.compare(second) == 0;
+ }
+};
+
+class RGWPolicyCondition_StrStartsWith : public RGWPolicyCondition {
+protected:
+ bool check(const string& first, const string& second) {
+ return first.compare(0, second.size(), second) == 0;
+ }
+};
+
+void RGWPolicyEnv::add_var(const string& name, const string& value)
+{
+ vars[name] = value;
+}
+
+bool RGWPolicyEnv::get_var(const string& name, string& val)
+{
+ map<string, string>::iterator iter = vars.find(name);
+ if (iter == vars.end())
+ return false;
+
+ val = iter->second;
+
+ return true;
+}
+
+bool RGWPolicyEnv::get_value(const string& s, string& val)
+{
+ if (s.empty() || s[0] != '$') {
+ val = s;
+ return true;
+ }
+
+ return get_var(s.substr(1), val);
+}
+
+
+RGWPolicy::~RGWPolicy()
+{
+ list<RGWPolicyCondition *>::iterator citer;
+ for (citer = conditions.begin(); citer != conditions.end(); ++citer) {
+ RGWPolicyCondition *cond = *citer;
+ delete cond;
+ }
+}
+
+int RGWPolicy::add_condition(const string& op, const string& first, const string& second)
+{
+ RGWPolicyCondition *cond = NULL;
+ if (op.compare("eq") == 0)
+ cond = new RGWPolicyCondition_StrEqual;
+ else if (op.compare("starts-with") == 0)
+ cond = new RGWPolicyCondition_StrStartsWith;
+
+ if (!cond)
+ return -EINVAL;
+
+ cond->set_vals(first, second);
+
+ conditions.push_back(cond);
+
+ return 0;
+}
+
+bool RGWPolicy::check(RGWPolicyEnv *env)
+{
+ list<pair<string, string> >::iterator viter;
+ for (viter = var_checks.begin(); viter != var_checks.end(); ++viter) {
+ pair<string, string>& p = *viter;
+ const string& name = p.first;
+ const string& check_val = p.second;
+ string val;
+ if (!env->get_var(name, val))
+ return false;
+
+ dout(20) << "comparing " << name << " [" << val << "], " << check_val << dendl;
+ if (val.compare(check_val) != 0) {
+ dout(1) << "policy check failed, val=" << val << " != " << check_val << dendl;
+ return false;
+ }
+ }
+
+ list<RGWPolicyCondition *>::iterator citer;
+ for (citer = conditions.begin(); citer != conditions.end(); ++citer) {
+ RGWPolicyCondition *cond = *citer;
+ if (!cond->check(env)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+int RGWPolicy::from_json(bufferlist& bl)
+{
+ RGWJSONParser parser;
+
+ if (!parser.parse(bl.c_str(), bl.length()))
+ return -EINVAL;
+
+ JSONObjIter iter = parser.find_first("conditions");
+ if (iter.end())
+ return 0;
+
+ JSONObj *obj = *iter;
+
+ iter = obj->find_first();
+ for (; !iter.end(); ++iter) {
+ JSONObj *child = *iter;
+ dout(20) << "is_object=" << child->is_object() << dendl;
+ dout(20) << "is_array=" << child->is_array() << dendl;
+ if (child->is_array()) {
+ JSONObjIter aiter = child->find_first();
+ vector<string> v;
+ int i;
+ for (i = 0; !aiter.end() && i < 3; ++aiter, ++i) {
+ JSONObj *o = *aiter;
+ v.push_back(o->get_data());
+ }
+ if (i != 3 || !aiter.end()) /* we expect exactly 3 arguments here */
+ return -EINVAL;
+ add_condition(v[0], v[1], v[2]);
+ } else {
+ add_simple_check(child->get_name(), child->get_data());
+ }
+ }
+ return 0;
+}
diff --git a/src/rgw/rgw_policy_s3.h b/src/rgw/rgw_policy_s3.h
new file mode 100644
index 00000000000..5461642fb13
--- /dev/null
+++ b/src/rgw/rgw_policy_s3.h
@@ -0,0 +1,41 @@
+#ifndef CEPH_RGW_POLICY_H
+#define CEPH_RGW_POLICY_H
+
+#include <map>
+#include <list>
+#include <string>
+
+#include "include/utime.h"
+
+
+class RGWPolicyEnv {
+ std::map<std::string, std::string> vars;
+
+public:
+ void add_var(const string& name, const string& value);
+ bool get_var(const string& name, string& val);
+ bool get_value(const string& s, string& val);
+};
+
+class RGWPolicyCondition;
+
+
+class RGWPolicy {
+ utime_t expires;
+ std::list<RGWPolicyCondition *> conditions;
+ std::list<pair<std::string, std::string> > var_checks;
+
+public:
+ RGWPolicy() {}
+ ~RGWPolicy();
+ void set_expires(utime_t& e) { expires = e; }
+
+ int add_condition(const std::string& op, const std::string& first, const std::string& second);
+ void add_simple_check(const std::string& var, const std::string& value) {
+ var_checks.push_back(pair<string, string>(var, value));
+ }
+
+ bool check(RGWPolicyEnv *env);
+ int from_json(bufferlist& bl);
+};
+#endif