initial code repo
[stor4nfv.git] / src / ceph / src / mon / MonCap.h
diff --git a/src/ceph/src/mon/MonCap.h b/src/ceph/src/mon/MonCap.h
new file mode 100644 (file)
index 0000000..1ff4b83
--- /dev/null
@@ -0,0 +1,177 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_MONCAP_H
+#define CEPH_MONCAP_H
+
+#include <ostream>
+using std::ostream;
+
+#include "include/types.h"
+#include "common/entity_name.h"
+
+class CephContext;
+
+static const __u8 MON_CAP_R     = (1 << 1);      // read
+static const __u8 MON_CAP_W     = (1 << 2);      // write
+static const __u8 MON_CAP_X     = (1 << 3);      // execute
+static const __u8 MON_CAP_ALL   = MON_CAP_R | MON_CAP_W | MON_CAP_X;
+static const __u8 MON_CAP_ANY   = 0xff;          // *
+
+struct mon_rwxa_t {
+  __u8 val;
+
+  // cppcheck-suppress noExplicitConstructor
+  mon_rwxa_t(__u8 v = 0) : val(v) {}
+  mon_rwxa_t& operator=(__u8 v) {
+    val = v;
+    return *this;
+  }
+  operator __u8() const {
+    return val;
+  }
+};
+
+ostream& operator<<(ostream& out, const mon_rwxa_t& p);
+
+struct StringConstraint {
+  enum MatchType {
+    MATCH_TYPE_NONE,
+    MATCH_TYPE_EQUAL,
+    MATCH_TYPE_PREFIX,
+    MATCH_TYPE_REGEX
+  };
+
+  MatchType match_type = MATCH_TYPE_NONE;
+  string value;
+
+  StringConstraint() {}
+  StringConstraint(MatchType match_type, string value)
+    : match_type(match_type), value(value) {
+  }
+};
+
+ostream& operator<<(ostream& out, const StringConstraint& c);
+
+struct MonCapGrant {
+  /*
+   * A grant can come in one of four forms:
+   *
+   *  - a blanket allow ('allow rw', 'allow *')
+   *    - this will match against any service and the read/write/exec flags
+   *      in the mon code.  semantics of what X means are somewhat ad hoc.
+   *
+   *  - a service allow ('allow service mds rw')
+   *    - this will match against a specific service and the r/w/x flags.
+   *
+   *  - a profile ('allow profile osd')
+   *    - this will match against specific monitor-enforced semantics of what
+   *      this type of user should need to do.  examples include 'osd', 'mds',
+   *      'bootstrap-osd'.
+   *
+   *  - a command ('allow command foo', 'allow command bar with arg1=val1 arg2 prefix val2')
+   *      this includes the command name (the prefix string), and a set
+   *      of key/value pairs that constrain use of that command.  if no pairs
+   *      are specified, any arguments are allowed; if a pair is specified, that
+   *      argument must be present and equal or match a prefix.
+   */
+  std::string service;
+  std::string profile;
+  std::string command;
+  map<std::string,StringConstraint> command_args;
+
+  mon_rwxa_t allow;
+
+  // explicit grants that a profile grant expands to; populated as
+  // needed by expand_profile() (via is_match()) and cached here.
+  mutable list<MonCapGrant> profile_grants;
+
+  void expand_profile(int daemon_type, const EntityName& name) const;
+  void expand_profile_mon(const EntityName& name) const;
+  void expand_profile_mgr(const EntityName& name) const;
+
+  MonCapGrant() : allow(0) {}
+  // cppcheck-suppress noExplicitConstructor
+  MonCapGrant(mon_rwxa_t a) : allow(a) {}
+  MonCapGrant(string s, mon_rwxa_t a) : service(std::move(s)), allow(a) {}
+  // cppcheck-suppress noExplicitConstructor  
+  MonCapGrant(string c) : command(std::move(c)) {}
+  MonCapGrant(string c, string a, StringConstraint co) : command(std::move(c)) {
+    command_args[a] = co;
+  }
+
+  /**
+   * check if given request parameters match our constraints
+   *
+   * @param cct context
+   * @param name entity name
+   * @param service service (if any)
+   * @param command command (if any)
+   * @param command_args command args (if any)
+   * @return bits we allow
+   */
+  mon_rwxa_t get_allowed(CephContext *cct,
+                        int daemon_type, ///< CEPH_ENTITY_TYPE_*
+                        EntityName name,
+                        const std::string& service,
+                        const std::string& command,
+                        const map<string,string>& command_args) const;
+
+  bool is_allow_all() const {
+    return
+      allow == MON_CAP_ANY &&
+      service.length() == 0 &&
+      profile.length() == 0 &&
+      command.length() == 0;
+  }
+};
+
+ostream& operator<<(ostream& out, const MonCapGrant& g);
+
+struct MonCap {
+  string text;
+  std::vector<MonCapGrant> grants;
+
+  MonCap() {}
+  explicit MonCap(std::vector<MonCapGrant> g) : grants(g) {}
+
+  string get_str() const {
+    return text;
+  }
+
+  bool is_allow_all() const;
+  void set_allow_all();
+  bool parse(const std::string& str, ostream *err=NULL);
+
+  /**
+   * check if we are capable of something
+   *
+   * This method actually checks a description of a particular operation against
+   * what the capability has specified.
+   *
+   * @param daemon_type CEPH_ENTITY_TYPE_* for the service (MON or MGR)
+   * @param service service name
+   * @param command command id
+   * @param command_args
+   * @param op_may_read whether the operation may need to read
+   * @param op_may_write whether the operation may need to write
+   * @param op_may_exec whether the operation may exec
+   * @return true if the operation is allowed, false otherwise
+   */
+  bool is_capable(CephContext *cct,
+                 int daemon_type,
+                 EntityName name,
+                 const string& service,
+                 const string& command, const map<string,string>& command_args,
+                 bool op_may_read, bool op_may_write, bool op_may_exec) const;
+
+  void encode(bufferlist& bl) const;
+  void decode(bufferlist::iterator& bl);
+  void dump(Formatter *f) const;
+  static void generate_test_instances(list<MonCap*>& ls);
+};
+WRITE_CLASS_ENCODER(MonCap)
+
+ostream& operator<<(ostream& out, const MonCap& cap);
+
+#endif