OPTION(rgw_keystone_admin_token, OPT_STR, "") // keystone admin token (shared secret)
OPTION(rgw_keystone_admin_user, OPT_STR, "") // keystone admin user name
OPTION(rgw_keystone_admin_password, OPT_STR, "") // keystone admin user password
-OPTION(rgw_keystone_admin_tenant, OPT_STR, "") // keystone admin user tenant
+OPTION(rgw_keystone_admin_tenant, OPT_STR, "") // keystone admin user tenant (for keystone v2.0)
+OPTION(rgw_keystone_admin_project, OPT_STR, "") // keystone admin user project (for keystone v3)
+OPTION(rgw_keystone_admin_domain, OPT_STR, "") // keystone admin user domain
+OPTION(rgw_keystone_api_version, OPT_STR, "2.0") // Version of Keystone API to use ("2.0" or "3")
OPTION(rgw_keystone_accepted_roles, OPT_STR, "Member, admin") // roles required to serve requests
OPTION(rgw_keystone_token_cache_size, OPT_INT, 10000) // max number of entries in keystone token cache
OPTION(rgw_keystone_revocation_interval, OPT_INT, 15 * 60) // seconds between tokens revocation check
JSONDecoder::decode_json("epoch", epoch, obj);
}
-void KeystoneToken::Metadata::decode_json(JSONObj *obj)
-{
- JSONDecoder::decode_json("is_admin", is_admin, obj);
-}
-
-void KeystoneToken::Service::Endpoint::decode_json(JSONObj *obj)
-{
- JSONDecoder::decode_json("id", id, obj);
- JSONDecoder::decode_json("adminURL", admin_url, obj);
- JSONDecoder::decode_json("publicURL", public_url, obj);
- JSONDecoder::decode_json("internalURL", internal_url, obj);
- JSONDecoder::decode_json("region", region, obj);
-}
-
-void KeystoneToken::Service::decode_json(JSONObj *obj)
-{
- JSONDecoder::decode_json("type", type, obj, true);
- JSONDecoder::decode_json("name", name, obj, true);
- JSONDecoder::decode_json("endpoints", endpoints, obj);
-}
-
-void KeystoneToken::Token::Tenant::decode_json(JSONObj *obj)
-{
- JSONDecoder::decode_json("id", id, obj, true);
- JSONDecoder::decode_json("name", name, obj, true);
- JSONDecoder::decode_json("description", description, obj);
- JSONDecoder::decode_json("enabled", enabled, obj);
-}
-
void KeystoneToken::Token::decode_json(JSONObj *obj)
{
string expires_iso8601;
struct tm t;
JSONDecoder::decode_json("id", id, obj, true);
- JSONDecoder::decode_json("tenant", tenant, obj, true);
+ JSONDecoder::decode_json("tenant", tenant_v2, obj, true);
JSONDecoder::decode_json("expires", expires_iso8601, obj, true);
if (parse_iso8601(expires_iso8601.c_str(), &t)) {
}
}
-void KeystoneToken::User::Role::decode_json(JSONObj *obj)
+void KeystoneToken::Role::decode_json(JSONObj *obj)
{
- JSONDecoder::decode_json("id", id, obj);
- JSONDecoder::decode_json("name", name, obj);
+ JSONDecoder::decode_json("id", id, obj, true);
+ JSONDecoder::decode_json("name", name, obj, true);
+}
+
+void KeystoneToken::Domain::decode_json(JSONObj *obj)
+{
+ JSONDecoder::decode_json("id", id, obj, true);
+ JSONDecoder::decode_json("name", name, obj, true);
+}
+
+void KeystoneToken::Project::decode_json(JSONObj *obj)
+{
+ JSONDecoder::decode_json("id", id, obj, true);
+ JSONDecoder::decode_json("name", name, obj, true);
+ JSONDecoder::decode_json("domain", domain, obj);
}
void KeystoneToken::User::decode_json(JSONObj *obj)
{
JSONDecoder::decode_json("id", id, obj, true);
- JSONDecoder::decode_json("name", name, obj);
- JSONDecoder::decode_json("username", user_name, obj, true);
- JSONDecoder::decode_json("roles", roles, obj);
+ JSONDecoder::decode_json("name", name, obj, true);
+ JSONDecoder::decode_json("domain", domain, obj);
+ JSONDecoder::decode_json("roles", roles_v2, obj);
}
-void KeystoneToken::decode_json(JSONObj *access_obj)
+void KeystoneToken::decode_json(JSONObj *root_obj)
{
- JSONDecoder::decode_json("metadata", metadata, access_obj);
- JSONDecoder::decode_json("token", token, access_obj, true);
- JSONDecoder::decode_json("user", user, access_obj, true);
- JSONDecoder::decode_json("serviceCatalog", service_catalog, access_obj);
+ if (version == "2.0") {
+ JSONDecoder::decode_json("token", token, root_obj, true);
+ }
+ if (version == "3") {
+ string expires_iso8601;
+ struct tm t;
+
+ JSONDecoder::decode_json("expires_at", expires_iso8601, root_obj, true);
+
+ if (parse_iso8601(expires_iso8601.c_str(), &t)) {
+ token.expires = timegm(&t);
+ } else {
+ token.expires = 0;
+ throw JSONDecoder::err("Failed to parse ISO8601 expiration date from Keystone response.");
+ }
+ JSONDecoder::decode_json("roles", roles, root_obj, true);
+ JSONDecoder::decode_json("project", project, root_obj, true);
+ }
+
+ JSONDecoder::decode_json("user", user, root_obj, true);
+ if (version == "2.0") {
+ roles = user.roles_v2;
+ project = token.tenant_v2;
+ }
}
void rgw_slo_entry::decode_json(JSONObj *obj)
#include "rgw_common.h"
class KeystoneToken {
+protected:
+ string version;
+
public:
- class Metadata {
+ class Domain {
public:
- Metadata() : is_admin(false) { }
- bool is_admin;
+ string id;
+ string name;
void decode_json(JSONObj *obj);
};
-
- class Service {
+ class Project {
public:
- class Endpoint {
- public:
- string id;
- string admin_url;
- string public_url;
- string internal_url;
- string region;
- void decode_json(JSONObj *obj);
- };
- string type;
+ Domain domain;
+ string id;
string name;
- list<Endpoint> endpoints;
void decode_json(JSONObj *obj);
};
class Token {
public:
Token() : expires(0) { }
- class Tenant {
- public:
- Tenant() : enabled(false) { }
- string id;
- string name;
- string description;
- bool enabled;
- void decode_json(JSONObj *obj);
- };
string id;
time_t expires;
- Tenant tenant;
+ Project tenant_v2;
+ void decode_json(JSONObj *obj);
+ };
+
+ class Role {
+ public:
+ string id;
+ string name;
void decode_json(JSONObj *obj);
};
class User {
public:
- class Role {
- public:
- string id;
- string name;
- void decode_json(JSONObj *obj);
- };
string id;
string name;
- string user_name;
- list<Role> roles;
+ Domain domain;
+ list<Role> roles_v2;
void decode_json(JSONObj *obj);
- bool has_role(const string& r);
};
- Metadata metadata;
- list<Service> service_catalog;
Token token;
+ Project project;
User user;
+ list<Role> roles;
public:
- int parse(CephContext *cct, bufferlist& bl);
-
+ KeystoneToken() : version("") {};
+ KeystoneToken(string _version) : version(_version) {};
+ time_t get_expires() { return token.expires; }
+ string get_domain_id() {return project.domain.id;};
+ string get_domain_name() {return project.domain.name;};
+ string get_project_id() {return project.id;};
+ string get_project_name() {return project.name;};
+ string get_user_id() {return user.id;};
+ string get_user_name() {return user.name;};
+ bool has_role(const string& r);
bool expired() {
uint64_t now = ceph_clock_now(NULL).sec();
- return (now >= (uint64_t)token.expires);
+ return (now >= (uint64_t)get_expires());
}
-
+ int parse(CephContext *cct, bufferlist& bl);
void decode_json(JSONObj *access_obj);
};