From: Radoslaw Zarzynski Date: Tue, 2 Feb 2016 16:05:23 +0000 (+0100) Subject: rgw: basic data structures for Keystone v3. X-Git-Tag: v10.1.0~352^2~11 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=38ee66143e6f7557a608114220df63a964584946;p=ceph.git rgw: basic data structures for Keystone v3. The change has been extracted from changeset proposed in commit af71f6a518529ea6cccb25bd46da2b6d1458c1da by Mark Barnes (lperiquito). Signed-off-by: Mark Barnes Signed-off-by: Radoslaw Zarzynski --- diff --git a/src/common/config_opts.h b/src/common/config_opts.h index 160ed36cb018..5a6d1ce3a49f 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -1185,7 +1185,10 @@ OPTION(rgw_keystone_url, OPT_STR, "") // url for keystone server 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 diff --git a/src/rgw/rgw_json_enc.cc b/src/rgw/rgw_json_enc.cc index 03eeac6c314d..182bf6bdd57d 100644 --- a/src/rgw/rgw_json_enc.cc +++ b/src/rgw/rgw_json_enc.cc @@ -1048,42 +1048,13 @@ void RGWRealm::decode_json(JSONObj *obj) 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)) { @@ -1094,26 +1065,59 @@ void KeystoneToken::Token::decode_json(JSONObj *obj) } } -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) diff --git a/src/rgw/rgw_keystone.cc b/src/rgw/rgw_keystone.cc index 7c5d206390f9..5188ec81b5a7 100644 --- a/src/rgw/rgw_keystone.cc +++ b/src/rgw/rgw_keystone.cc @@ -14,7 +14,7 @@ #define dout_subsys ceph_subsys_rgw -bool KeystoneToken::User::has_role(const string& r) { +bool KeystoneToken::has_role(const string& r) { list::iterator iter; for (iter = roles.begin(); iter != roles.end(); ++iter) { if (fnmatch(r.c_str(), ((*iter).name.c_str()), 0) == 0) { @@ -33,7 +33,12 @@ int KeystoneToken::parse(CephContext *cct, bufferlist& bl) } try { - JSONDecoder::decode_json("access", *this, &parser); + if (version == "2.0") { + JSONDecoder::decode_json("access", *this, &parser); + } + if (version == "3") { + JSONDecoder::decode_json("token", *this, &parser); + } } catch (JSONDecoder::err& err) { ldout(cct, 0) << "Keystone token parse error: " << err.message << dendl; return -EINVAL; diff --git a/src/rgw/rgw_keystone.h b/src/rgw/rgw_keystone.h index a9600acaac87..291947561405 100644 --- a/src/rgw/rgw_keystone.h +++ b/src/rgw/rgw_keystone.h @@ -7,78 +7,70 @@ #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 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 roles; + Domain domain; + list roles_v2; void decode_json(JSONObj *obj); - bool has_role(const string& r); }; - Metadata metadata; - list service_catalog; Token token; + Project project; User user; + list 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); };