LDAP 预处理

bp ldap-preprocessing

Keystone 可以使用 LDAP 作为身份后端。LDAP 属性可能不是 uuid4,我们需要我们的实体拥有 uuid4 ID。为了执行 ldap_attribute <-> keystone_id 映射,存在 id_mapping_api。但是,当存在许多身份时,它会非常慢。

问题描述

id_mapping_api 是 LDAP 实体和 Keystone 实体之间的映射层。当对实体执行操作时,id_mapping_api 会将 ID 从公共 (uuid4) 更改为本地 (LDAP 特定的) 或反之亦然。

它通过查找每个实体的公共 ID 和本地 ID 来实现。对于 LDAP 中的 N 个用户,它会向数据库发出 N 个 SELECT 查询。更糟糕的是,如果 M 个实体还没有公共 ID,id_mapping_api 会执行 M 个 INSERT 查询。所有这些都发生在用户对 Keystone 发出 API 调用时。当 N 和 M 很大时,调用将导致超时。

可以通过选择映射表中的所有行并在内存中执行公共 ID 或本地 ID 的查找来解决 N 个 SELECT 查询的问题。但是,M 个 INSERT 查询的问题不容易解决。

人们可能会想使用批量插入。但是,在这种情况下可能会发生竞争条件

                           +
              Process 1    |    Process 2
                    +-------------+
Select entities #1, #2, #3 | Select entity #2
from the table; 0 returned | from the table; 0 returned
since they don't exist yet | since it does not exist yet
                    +-------------+
                           | Generate public id for #2
                           | Insert public_id for #2
                           |
                    +-------------+
Generate public_id for     |
#1, #2, #3. Bulk insert    |
for all items.             |
                           |
                           v

此时,进程 1 将失败,因为已经存在关于实体 #2 的条目。它不能被忽略,因为在进程 2 中分配的 ID 已经返回给用户。

提议的变更

keystone-manage 实现新命令:prepare_ldap。它将:1. 从 LDAP 获取所有用户 2. 为所有用户创建映射

当操作员知道 LDAP 包含许多条目时,将执行该命令。

运行该命令不是必需的用于集成 LDAP。它将为 LDAP 中存在许多实体的情况提供更好的用户和操作员体验。

备选方案

仅实现 N 个 SELECT 查询的解决方法。

安全影响

通知影响

其他最终用户影响

性能影响

使用 N 个查询的解决方法将减少 SQL 查询的数量到恒定数量,并需要 O(N) 的额外内存。

keystone-manage prepare_ldap 命令将由操作员运行。它不会暴露给用户。它将加快第一次调用或在添加许多新的 LDAP 用户后的调用速度。

其他部署者影响

部署者可以在配置 LDAP 后立即运行该命令。

运行它不是必需的。现有的部署脚本不会受到影响。

开发人员影响

实现

负责人

主要负责人

bbobrov (breton)

依赖项

无依赖

文档影响

记录新命令。

参考资料