openstack获取用户token(及endpoints)

        对于openstack的api操作来说,大量的命令都依赖相关用户的token来完成,尤其对自动化测试来说,可以说拿到了用户的token就相当于取得了进入openstack这个大工厂大门的钥匙,有了这个钥匙,才能进入这个工厂大显身手。

        要想拿到token, 必须知道用户的相关信息,其中用户名和密码是必须的,如果还想取得更多的信息,例如用户对各种服务包括glance, keystond的访问endpoint, 还需要提供用户的tenant信息。实际上,对于终端用户来说,因为用户名,密码以及tenant名更为直观,所以很少会直接用token进行操作,但对于自动化测试来说,因为要直接和相关api打交道,取得token就相当有必要了。

        命令行取得用户token的命令为:

        # curl -X POST http://localhost:5000/v2.0/tokens -d '{"auth":{"passwordCredentials":{"username": "username", "password":"password"}}}' -H "Content-type: application/json"

        其中localhost:5000是openstack keystone服务的endpoint, 如果没有特殊的设置,5000就是keystone服务进程的端口号。

        /v2.0/token 是openstack api里定义的取得token的URI, 请求方式为POST,这个可以从openstack.org里查到

       后面json结构的数据‘auth’是提供给keystone服务用户信息,包括用户名和密码。下面看一下输出:

       {"access": {"token": {"expires": "2013-06-04T03:06:23Z", "id": "5fcf748e0d5d4a02ae3465e0dd301f40"}, "serviceCatalog": {}, "user": {"username": "username", "roles_links": [], "id": "ce205b61760c463cb46e41909de8495f", "roles": [], "name": "username"}}}

       这是openstack/essex版本下的token输出,其中['token']['id']就是我们得到的用户token。对于openstack/grizzly版本, 用户的token比这个要长得多,但基本结构是一样的。

       下面看一下使用tenant的情况:

       curl -X POST http://localhost:5000/v2.0/tokens -d '{"auth":{"passwordCredentials":{"username": "admin", "password":"crowbar"}, "tenantName":"tenantname"}}' -H "Content-type: application/json"

       输出:

       {"access": {"token": {"expires": "2013-06-04T03:14:12Z", "id": "fc3e38a93e95462da5028b1fb3a688c0", "tenant": {"description": "description", "enabled": true, "id": "4e14ab2a2df045f1a6f02081a46deb2c", "name": "tenantname"}}, "serviceCatalog": [{"endpoints": [{"adminURL": "http://localhost:8776/v1/4e14ab2a2df045f1a6f02081a46deb2c", "region": "RegionOne", "internalURL": "http://localhost:8776/v1/4e14ab2a2df045f1a6f02081a46deb2c", "publicURL": "http://localhost:8776/v1/4e14ab2a2df045f1a6f02081a46deb2c"}], "endpoints_links": [], "type": "volume", "name": "nova-volume"}, {"endpoints": [{"adminURL": "http://localhost:9292/v1", "region": "RegionOne", "internalURL": "http://localhost:9292/v1", "publicURL": "http://localhost:9292/v1"}], "endpoints_links": [], "type": "image", "name": "glance"}, {"endpoints": [{"adminURL": "http://localhost:8774/v2/4e14ab2a2df045f1a6f02081a46deb2c", "region": "RegionOne", "internalURL": "http://localhost:8774/v2/4e14ab2a2df045f1a6f02081a46deb2c", "publicURL": "http://localhost:8774/v2/4e14ab2a2df045f1a6f02081a46deb2c"}], "endpoints_links": [], "type": "compute", "name": "nova"}, {"endpoints": [{"adminURL": "http://localhost:8773/services/Admin", "region": "RegionOne", "internalURL": "http://localhost:8773/services/Cloud", "publicURL": "http://localhost:8773/services/Cloud"}], "endpoints_links": [], "type": "ec2", "name": "ec2"}, {"endpoints": [{"adminURL": "http://localhost:35357/v2.0", "region": "RegionOne", "internalURL": "http://localhost:5000/v2.0", "publicURL": "http://localhost:5000/v2.0"}], "endpoints_links": [], "type": "identity", "name": "keystone"}], "user": {"username": "admin", "roles_links": [], "id": "ce205b61760c463cb46e41909de8495f", "roles": [{"id": "454cb6cbddaf41f2af6f87e68ce58d64", "name": "KeystoneAdmin"}, {"id": "5a80a5b5d4244f48ac7d3079d56555c6", "name": "KeystoneServiceAdmin"}, {"id": "c5a190185ea7434eb2c35bbd1bb52051", "name": "username"}], "name": "tenentname"}}}      

        可以看到,如果在请求token的时候同时提供了tenant信息,则可以额外获取用户相关的endpoints信息。这样,有了token和相关endpoints, 就能够对openstack的api进行相关的访问和操作了。顺便说明,上述提供的tenant的信息也可以是tenant的id, 格式为"tenantId":"“。

        用户每次发出一次请求,就会生成一个token, 同时会在glance数据库的token表内生成一个记录。每个token的有效时间缺省为24个小时。

        编程实现取得用户token也极为简单,代码如下:

import httplib2
import json

http_obj = httplib2.Http()
headers = {}
body = {
    "auth": {
            "passwordCredentials":{
                "username": 'username',
                "password": 'password',
            },
            "tenantName": 'tenantname',
        },
    }

req_url = "http://localhost:5000/v2.0/tokens"
method = "POST"

headers['Content-Type'] = 'application/json'
headers['Accept'] = 'application/json'

resp, token = http_obj.request(req_url, method,
                               headers=headers, body=json.dumps(body))

print resp
print token

如果在body里不提供tenantName或tenantId的数据,则返回的是上述command line命令不包括endpoints的输出。

你可能感兴趣的:(openstack,python)