何の話かというと
ここの説明にあるように、Keystoneが発行するトークンには、「Unscoped Token」と「Scoped Token」があります。
流れとしては、最初に、UserID/Password認証で「Unscoped Token」を取得して、その後は、Unscoped Tokenを使って、自分のテナント情報を取得して、さらに、Unscoped Tokenを使って、該当テナントのサービスを利用するための「Scoped Token」を取得します。
この流れに沿って、Scoped Tokenを取得するまでの処理をPythonで書いて見ました。
tokentest.py
#!/usr/bin/python import re, json from httplib import HTTPConnection username = "demo_user" password = "xxxxxxxxx" keystone = "http://xx.xx.xx.xx:5000/v2.0" def get_unscoped_token(): u = re.match(r"^(http|https)://([^/]*)(/.*)$", keystone).groups() conn = HTTPConnection(u[1]) header = {"Content-Type":"application/json"} request = """ { "auth":{ "passwordCredentials":{ "username":"%s", "password":"%s" } } }""" % (username, password) print "Header:%s" % header print "Request:%s" % request conn.request("POST", u[2]+"/tokens", request, header) print "\nResponce:" print json.dumps(json.load(conn.getresponse()), indent=2) conn.close() def get_tenants(id): u = re.match(r"^(http|https)://([^/]*)(/.*)$", keystone).groups() conn = HTTPConnection(u[1]) header = {"X-Auth-Token":"%s" % id, "Content-Type":"application/json"} print "Header:%s" % header conn.request("GET", u[2]+"/tenants", None, header) print "\nResponce:" print json.dumps(json.load(conn.getresponse()), indent=2) conn.close() def get_scoped_token(tenant, id): u = re.match(r"^(http|https)://([^/]*)(/.*)$", keystone).groups() conn = HTTPConnection(u[1]) header = {"Content-Type":"application/json"} request = """ { "auth":{ "tenantName":"%s", "token":{ "id":"%s" } } }""" % (tenant, id) print "Header:%s" % header print "Request:%s" % request conn.request("POST", u[2]+"/tokens", request, header) print "\nResponce:" print json.dumps(json.load(conn.getresponse()), indent=2) conn.close() if __name__ == '__main__': get_unscoped_token() id = raw_input('\ntoke id: ') get_tenants(id) tenant = raw_input('\ntenant name: ') get_scoped_token(tenant, id)
実行例はこんな感じです。最初に、UserID/passwordでUnscoped Tokenを取得します。
# ./tokentest.py Header:{'Content-Type': 'application/json'} Request: { "auth":{ "passwordCredentials":{ "username":"demo_user", "password":"xxxxxxxx" } } } Responce: { "access": { "token": { "issued_at": "2013-11-21T08:36:25.921898", "expires": "2013-11-22T08:36:25Z", "id": "149226c5f191445b90d7bb45925ed9f1" ←Unscoped TokenのID }, "serviceCatalog": [], "user": { "username": "demo_user", "roles_links": [], "id": "44be5165fdf64bd5907d07aa1aaa5dab", "roles": [], "name": "demo_user" }, "metadata": { "is_admin": 0, "roles": [] } } }
Unscoped TokenのIDを入力して、テナント情報を取得します。
toke id: 149226c5f191445b90d7bb45925ed9f1 Header:{'Content-Type': 'application/json', 'X-Auth-Token': '149226c5f191445b90d7bb45925ed9f1'} Responce: { "tenants": [ { "enabled": true, "description": "", "name": "production", "id": "ee18bc8d37184ed0b013cd612c92f45a" }, { "enabled": true, "description": "", "name": "demo", "id": "f057a8457a8144b48fded7e6ba644e92" } ], "tenants_links": [] }
「demo」「production」の2つのテナントに属していることが分かります。最後にテナント名を入力して、Scoped Tokenを取得します。
tenant name: demo Header:{'Content-Type': 'application/json'} Request: { "auth":{ "tenantName":"demo", "token":{ "id":"149226c5f191445b90d7bb45925ed9f1" } } } Responce: { "access": { "token": { "issued_at": "2013-11-21T08:36:33.995777", "expires": "2013-11-22T08:36:25Z", "id": "8312676d28b546d0b801b7b44dfdf70f", ← Scoped TokenのID "tenant": { "enabled": true, "description": "", "name": "demo", "id": "f057a8457a8144b48fded7e6ba644e92" } }, "serviceCatalog": [ { "endpoints_links": [], "endpoints": [ { "adminURL": "http://10.64.200.97:8774/v2/f057a8457a8144b48fded7e6ba644e92", "region": "RegionOne", "publicURL": "http://10.64.200.97:8774/v2/f057a8457a8144b48fded7e6ba644e92", "internalURL": "http://10.64.200.97:8774/v2/f057a8457a8144b48fded7e6ba644e92", "id": "9aed292e70e9468499dd6c77e7a258f3" } ], "type": "compute", "name": "nova" }, { "endpoints_links": [], "endpoints": [ { "adminURL": "http://10.64.200.97:9696/", "region": "RegionOne", "publicURL": "http://10.64.200.97:9696/", "internalURL": "http://10.64.200.97:9696/", "id": "6f3ba4ff43df4a44aad80756cad4d23a" } ], "type": "network", "name": "quantum" }, { "endpoints_links": [], "endpoints": [ { "adminURL": "http://10.64.200.97:9292", "region": "RegionOne", "publicURL": "http://10.64.200.97:9292", "internalURL": "http://10.64.200.97:9292", "id": "2dd545884c9144778ffdcff5d3447b8f" } ], "type": "image", "name": "glance" }, { "endpoints_links": [], "endpoints": [ { "adminURL": "http://10.64.200.97:8776/v1/f057a8457a8144b48fded7e6ba644e92", "region": "RegionOne", "publicURL": "http://10.64.200.97:8776/v1/f057a8457a8144b48fded7e6ba644e92", "internalURL": "http://10.64.200.97:8776/v1/f057a8457a8144b48fded7e6ba644e92", "id": "4ae8335bb0054fb9a20009ddc03302f6" } ], "type": "volume", "name": "cinder" }, { "endpoints_links": [], "endpoints": [ { "adminURL": "http://10.64.200.97:8773/services/Admin", "region": "RegionOne", "publicURL": "http://10.64.200.97:8773/services/Cloud", "internalURL": "http://10.64.200.97:8773/services/Cloud", "id": "710312d624d546f8ab9fc30e224167c5" } ], "type": "ec2", "name": "nova_ec2" }, { "endpoints_links": [], "endpoints": [ { "adminURL": "http://10.64.200.97:35357/v2.0", "region": "RegionOne", "publicURL": "http://10.64.200.97:5000/v2.0", "internalURL": "http://10.64.200.97:5000/v2.0", "id": "32b37f27c01a47a6ae79411f2c160e39" } ], "type": "identity", "name": "keystone" } ], "user": { "username": "demo_user", "roles_links": [], "id": "44be5165fdf64bd5907d07aa1aaa5dab", "roles": [ { "name": "Member" } ], "name": "demo_user" }, "metadata": { "is_admin": 0, "roles": [ "08b79ba58e2b497cae98e38600aff847" ] } } }
Scoped TokenのIDと併せて、サービスエンドポイントの情報が返ってくるので、あとは、Scoped Tokenを使ってエンドポイントにリクエストを投げればOKです。