}
}
+int RGWSwift::get_keystone_url(CephContext * const cct,
+ std::string& url)
+{
+ // FIXME: it seems we don't need RGWGetRevokedToken here
+ bufferlist bl;
+ RGWGetRevokedTokens req(cct, &bl);
+
+ url = cct->_conf->rgw_keystone_url;
+ if (url.empty()) {
+ ldout(cct, 0) << "ERROR: keystone url is not configured" << dendl;
+ return -EINVAL;
+ }
+ if (url[url.size() - 1] != '/')
+ url.append("/");
+ return 0;
+}
+
+int RGWSwift::get_keystone_admin_token(CephContext * const cct,
+ std::string& token)
+{
+ std::string token_url;
+
+ if (get_keystone_url(cct, token_url) < 0) {
+ return -EINVAL;
+ }
+
+ if (!cct->_conf->rgw_keystone_admin_token.empty()) {
+ token = cct->_conf->rgw_keystone_admin_token;
+ return 0;
+ }
+
+ KeystoneToken t;
+
+ /* Try cache first. */
+ if (RGWKeystoneTokenCache::get_instance().find_admin(t)) {
+ ldout(cct, 20) << "found cached admin token" << dendl;
+ token = t.token.id;
+ return 0;
+ }
+
+ bufferlist token_bl;
+ RGWGetKeystoneAdminToken token_req(cct, &token_bl);
+ token_req.append_header("Content-Type", "application/json");
+ JSONFormatter jf;
+
+ const auto keystone_version = KeystoneService::get_api_version();
+ if (keystone_version == KeystoneApiVersion::VER_2) {
+ KeystoneAdminTokenRequestVer2 req_serializer(cct);
+ req_serializer.dump(&jf);
+
+ std::stringstream ss;
+ jf.flush(ss);
+ token_req.set_post_data(ss.str());
+ token_req.set_send_length(ss.str().length());
+ token_url.append("v2.0/tokens");
+
+ } else if (keystone_version == KeystoneApiVersion::VER_3) {
+ KeystoneAdminTokenRequestVer3 req_serializer(cct);
+ req_serializer.dump(&jf);
+
+ std::stringstream ss;
+ jf.flush(ss);
+ token_req.set_post_data(ss.str());
+ token_req.set_send_length(ss.str().length());
+ token_url.append("v3/auth/tokens");
+ } else {
+ return -ENOTSUP;
+ }
+
+ const int ret = token_req.process("POST", token_url.c_str());
+ if (ret < 0) {
+ return ret;
+ }
+ if (t.parse(cct, token_req.get_subject_token(), token_bl) != 0) {
+ return -EINVAL;
+ }
+
+ RGWKeystoneTokenCache::get_instance().add_admin(t);
+ token = t.token.id;
+ return 0;
+}
+
bool KeystoneToken::has_role(const string& r) const
{
list<Role>::const_iterator iter;