agent/authentic2: batch the provisionning of agents (#52620)
This commit is contained in:
parent
0132005608
commit
9b5e4dde2e
|
@ -1,3 +1,4 @@
|
||||||
|
from itertools import chain, islice
|
||||||
import json
|
import json
|
||||||
from django.utils.six.moves.urllib.parse import urljoin
|
from django.utils.six.moves.urllib.parse import urljoin
|
||||||
import threading
|
import threading
|
||||||
|
@ -26,6 +27,15 @@ RoleParenting = get_role_parenting_model()
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def batch(iterable, size):
|
||||||
|
"""Batch an iterable as an iterable of iterables of at most size element
|
||||||
|
long.
|
||||||
|
"""
|
||||||
|
sourceiter = iter(iterable)
|
||||||
|
for first in sourceiter:
|
||||||
|
yield chain([first], islice(sourceiter, size - 1))
|
||||||
|
|
||||||
|
|
||||||
class Provisionning(threading.local):
|
class Provisionning(threading.local):
|
||||||
__slots__ = ['threads']
|
__slots__ = ['threads']
|
||||||
|
|
||||||
|
@ -166,8 +176,10 @@ class Provisionning(threading.local):
|
||||||
if roles_with_attributes:
|
if roles_with_attributes:
|
||||||
for ou, users in ous.items():
|
for ou, users in ous.items():
|
||||||
for service, audience in self.get_audience(ou):
|
for service, audience in self.get_audience(ou):
|
||||||
for user in users:
|
for batched_users in batch(users, 500):
|
||||||
logger.info(u'provisionning user %s to %s', user, audience)
|
batched_users = list(batched_users)
|
||||||
|
for user in batched_users:
|
||||||
|
logger.info('provisionning user %s to %s', user, audience)
|
||||||
self.notify_agents({
|
self.notify_agents({
|
||||||
'@type': 'provision',
|
'@type': 'provision',
|
||||||
'issuer': issuer,
|
'issuer': issuer,
|
||||||
|
@ -175,7 +187,7 @@ class Provisionning(threading.local):
|
||||||
'full': False,
|
'full': False,
|
||||||
'objects': {
|
'objects': {
|
||||||
'@type': 'user',
|
'@type': 'user',
|
||||||
'data': [user_to_json(ou, service, user, user_roles)],
|
'data': [user_to_json(ou, service, user, user_roles) for user in batched_users],
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -278,41 +278,40 @@ def test_provision_user(transactional_db, tenant, caplog):
|
||||||
role.members.add(user1)
|
role.members.add(user1)
|
||||||
user2.save()
|
user2.save()
|
||||||
|
|
||||||
assert notify_agents.call_count == 3
|
assert notify_agents.call_count == 2
|
||||||
assert notify_agents.call_args_list[0][0][0]['objects']['@type'] == 'role'
|
assert notify_agents.call_args_list[0][0][0]['objects']['@type'] == 'role'
|
||||||
for arg in notify_agents.call_args_list[1:]:
|
arg = notify_agents.call_args_list[1]
|
||||||
assert arg == call(ANY)
|
assert arg == call(ANY)
|
||||||
arg = arg[0][0]
|
arg = arg[0][0]
|
||||||
assert isinstance(arg, dict)
|
assert isinstance(arg, dict)
|
||||||
assert set(arg.keys()) == set([
|
assert set(arg.keys()) == set([
|
||||||
'issuer', 'audience', '@type', 'objects', 'full'])
|
'issuer', 'audience', '@type', 'objects', 'full'])
|
||||||
assert arg['issuer'] == \
|
assert arg['issuer'] == \
|
||||||
'http://%s/idp/saml2/metadata' % tenant.domain_url
|
'http://%s/idp/saml2/metadata' % tenant.domain_url
|
||||||
assert arg['audience'] == ['http://provider.com']
|
assert arg['audience'] == ['http://provider.com']
|
||||||
assert arg['@type'] == 'provision'
|
assert arg['@type'] == 'provision'
|
||||||
assert arg['full'] is False
|
assert arg['full'] is False
|
||||||
objects = arg['objects']
|
objects = arg['objects']
|
||||||
assert isinstance(objects, dict)
|
assert isinstance(objects, dict)
|
||||||
assert set(objects.keys()) == set(['data', '@type'])
|
assert set(objects.keys()) == set(['data', '@type'])
|
||||||
assert objects['@type'] == 'user'
|
assert objects['@type'] == 'user'
|
||||||
data = objects['data']
|
data = objects['data']
|
||||||
assert isinstance(data, list)
|
assert isinstance(data, list)
|
||||||
assert len(data) == 1
|
assert len(data) == 2
|
||||||
for o in data:
|
for o in data:
|
||||||
assert set(o.keys()) >= set(['uuid', 'username', 'first_name',
|
assert set(o.keys()) >= set(['uuid', 'username', 'first_name',
|
||||||
'is_superuser', 'last_name', 'email', 'roles'])
|
'is_superuser', 'last_name', 'email', 'roles'])
|
||||||
assert o['uuid'] in users
|
assert o['uuid'] in users
|
||||||
user = users[o['uuid']]
|
user = users[o['uuid']]
|
||||||
assert o['uuid'] == user.uuid
|
assert o['uuid'] == user.uuid
|
||||||
assert o['username'] == user.username
|
assert o['username'] == user.username
|
||||||
assert o['first_name'] == user.first_name
|
assert o['first_name'] == user.first_name
|
||||||
assert o['last_name'] == user.last_name
|
assert o['last_name'] == user.last_name
|
||||||
assert o['email'] == user.email
|
assert o['email'] == user.email
|
||||||
assert o['roles'] == [{'name': r.name, 'slug': r.slug, 'uuid': r.uuid} for r in
|
assert o['roles'] == [{'name': r.name, 'slug': r.slug, 'uuid': r.uuid} for r in
|
||||||
user.roles.all()]
|
user.roles.all()]
|
||||||
assert o['is_superuser'] is (user == user1)
|
assert o['is_superuser'] is (user == user1)
|
||||||
assert len(set(arg[0][0]['objects']['data'][0]['uuid'] for arg in
|
assert len(set(x['uuid'] for x in notify_agents.call_args_list[1][0][0]['objects']['data'])) == 2
|
||||||
notify_agents.call_args_list[1:])) == 2
|
|
||||||
|
|
||||||
notify_agents.reset_mock()
|
notify_agents.reset_mock()
|
||||||
with provisionning:
|
with provisionning:
|
||||||
|
|
Loading…
Reference in New Issue