LDAP preprocessing

bp ldap-preprocessing

Keystone can use LDAP as an identity backend. LDAP attributes probably are not uuid4, and we need our entities have uuid4 ids. To perform ldap_attribute <-> keystone_id mapping, there is id_mapping_api. However, it is very slow when there are many identities.

Problem Description

id_mapping_api is a mapping layer between LDAP entities and keystone entities. When an operation on an entity needs to be performed, id_mapping_api changes the id from public (uuid4) to local (LDAP-specific) or vise versa.

It does that by looking up public and local id for each entity. For N users in LDAP it makes N SELECT queries to the database. Even worse, if M entities don’t yet have a public id, id_mapping_api performs M INSERT queries. All of this happens when a user makes an API call to keystone. When N and M are big, the call will result in timeout.

The problem with N SELECT queries can be worked around by selecting all rows from the mapping table and performing the lookup for public or local id in memory. However, the problem with M INSERT queries cannot be worked around so easily.

One might want to use bulk insert. However, race condition might happen in this case:

                           +
              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

At this point process 1 will fail because there is already an entry about entity #2. It cannot be ignored, because the id, assigned in process 2, was already returned to the user.

Proposed Change

Implement new command for keystone-manage: prepare_ldap. It will: 1. Fetch all users from LDAP 2. For all users create a mapping

The command will be executed by operators, when they know that LDAP has many entries.

Running the command is not required for integrating LDAP. It will provide a better user and operator experience for cases when there are many entities in LDAP.

Alternatives

Only implement a workaround for N SELECT queries.

Security Impact

None

Notifications Impact

None

Other End User Impact

None

Performance Impact

The workaround with N queries it will decrease the number of SQL queries to constant number and will require O(N) additional memory.

keystone-manage prepare_ldap command will be ran by operators. It will not be exposed to the users. It will speed-up the first call or the call after many new LDAP users were added.

Other Deployer Impact

Deployers will have an ability to run the command right after configuring LDAP.

It is not a requirement to run it. No existing deployment scripts will be affected.

Developer Impact

None

Implementation

Assignee(s)

Primary assignee:
bbobrov (breton)

Dependencies

No dependencies

Documentation Impact

Document the new command.