何の話かというと
ここの説明にあるように、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です。