Python openstacksdk列出服务器身份验证错误

问题描述

我一直在尝试使用openstacksdk library从我的云中查询数据,特别是项目实例。但是,当我像这样列出实例时:

import openstack

conn = openstack.connection.Connection(session=sess)
servers = conn.compute.servers(all_projects=True)

我收到以下错误,并且挂起了一段时间,我猜测它反复尝试进行身份验证:

...
REQ: curl -g -i -X GET https://booboo-booboo.com:443/v2.1 -H "Accept: application/json" -H "User-Agent: test.py keystoneauth1/4.2.1 python-requests/2.24.0 cpython/3.8.5"
RESP: [401] Content-Length: 114 Content-Type: application/json Date: Sat,05 Sep 2020 00:32:26 GMT Www-Authenticate: Keystone uri='https://booboo-booboo.com:443/v2.0' X-Compute-Request-Id: req-a25d0bd5-6297-4d2b-80b9-4da1d5993c6d
RESP BODY: {"error": {"message": "The request you have made requires authentication.","code": 401,"title": "Unauthorized"}}
...

所以我改用nova client API bindings进行连接:

from novaclient import client

conn = client.Client('2',session=sess)
servers = conn.servers.list(detailed=True)  

并成功列出了所有实例:

...
REQ: curl -g -i -X GET https://booboo-booboo.com:443/v2.1/12ecf4ae6a374ca6b21e58a17fed92c3/servers/detail -H "Accept: application/json" -H "User-Agent: python-novaclient" -H "X-Auth-Token: {SHA256}4c803dc6ba5fb03e5cd69ce7c83cef9167e0570dcaa503baeb245fee7c538981"
RESP: [200] Content-Length: 15 Content-Type: application/json Date: Sat,05 Sep 2020 00:50:49 GMT Openstack-Api-Version: compute 2.1 vary: OpenStack-API-Version,X-OpenStack-Nova-API-Version X-Compute-Request-Id: req-401556a9-49e4-4e09-96ce-118536be6b46 X-Openstack-Nova-Api-Version: 2.1
RESP BODY: {"servers": []}
GET call to compute for https://booboo-booboo.com:443/v2.1/12ecf4ae6a374ca6b21e58a17fed92c3/servers/detail used request id req-401556a9-49e4-4e09-96ce-118536be6b46
...

我确实看过他们的openstackclient CLI tool

openstack server list --all-projects --timing --debug

在运行时也可以使用,并带有调试标志,它显示以下输出

...
compute API version 2.1,cmd group openstack.compute.v2
identity API version 3,cmd group openstack.identity.v3
image API version 2,cmd group openstack.image.v2
network API version 2,cmd group openstack.network.v2
object_store API version 1,cmd group openstack.object_store.v1
volume API version 3,cmd group openstack.volume.v3
neutronclient API version 2,cmd group openstack.neutronclient.v2
command: server list -> openstackclient.compute.v2.server.ListServer (auth=True)
...

我猜想它正在为每个服务初始化多个不同的必要客户端。所以我的问题是,有没有一种方法可以使用openstacksdk做同样的事情,因为我需要从OpenStack查询多个服务,而我真的不想跟踪不同服务的几个不同的客户端。

以下是用于创建会话对象的代码

from keystoneauth1.identity import v3
from keystoneauth1 import session
from keystoneauth1 import loading

def create_loader():
    loader = loading.get_plugin_loader('password')
    auth = loader.load_from_options(
        auth_url=os.environ['OS_AUTH_URL'],username=os.environ['OS_USERNAME'],password=os.environ['OS_PASSWORD'],project_id=os.environ['OS_PROJECT_ID'],user_domain_name=os.environ['OS_USER_DOMAIN_NAME']
        )
    sess = session.Session(auth=auth)
    return sess

解决方法

在我看来,问题可能出在OpenStack参数的规范中(文件:clouds.yaml)。如果执行此代码:

import openstack

# Initialize and turn on debug logging
openstack.enable_logging(debug=True)

# Initialize cloud
conn = openstack.connect(cloud='yourcloud')

for server in conn.compute.servers(all_projects=True):
  print(server.to_dict())

配置文件应该像这样:

clouds:
  yourcloud:
    region_name: <your region name>
    auth:
      username: '<username>'
      password: '<password>'
      project_name: '<project name>'
      auth_url: '<keystone auth. url>'
      domain_name: '<domain name>'

如果没有多区域,则可以忽略此参数(region_name)。如果您在环境中定义了域名,通常会要求提供该域名。

鉴于此,请检查您的梯形校正url的配置数据,因为您似乎正在调用版本2,但openstacksdk为您提供了以下信息:

identity API version 3,cmd group openstack.identity.v3

尝试在auth_url的定义中使用版本3

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...