Projet

Général

Profil

0001-provisionning-add-sync-1-parameter-to-__provision__-.patch

Benjamin Dauvergne, 14 septembre 2021 10:37

Télécharger (7,63 ko)

Voir les différences:

Subject: [PATCH] provisionning: add ?sync=1 parameter to /__provision__ API
 (#56920)

When used by the /api/provision API on authentic, it garantees the
provisionning is made synchronously.
 hobo/agent/authentic2/provisionning.py | 30 +++++++++++++++-----------
 hobo/agent/authentic2/views.py         |  8 +++----
 hobo/provisionning/middleware.py       |  4 ++--
 3 files changed, 23 insertions(+), 19 deletions(-)
hobo/agent/authentic2/provisionning.py
122 122
            if instance.ou_id in ous:
123 123
                instance.ou = ous[instance.ou_id]
124 124

  
125
    def notify_users(self, ous, users, mode='provision'):
125
    def notify_users(self, ous, users, mode='provision', sync=False):
126 126
        allowed_technical_roles_prefixes = getattr(settings, 'HOBO_PROVISION_ROLE_PREFIXES', []) or []
127 127

  
128 128
        if mode == 'provision':
......
240 240
                                            for user in batched_users
241 241
                                        ],
242 242
                                    },
243
                                }
243
                                },
244
                                sync=sync,
244 245
                            )
245 246
            else:
246 247
                for ou, users in ous.items():
......
262 263
                                '@type': 'user',
263 264
                                'data': [user_to_json(ou, None, user, user_roles) for user in users],
264 265
                            },
265
                        }
266
                        },
267
                        sync=sync,
266 268
                    )
267 269
        elif users:
268 270
            audience = [audience for ou in ous.keys() for s, audience in self.get_audience(ou)]
......
284 286
                            for user in users
285 287
                        ],
286 288
                    },
287
                }
289
                },
290
                sync=sync,
288 291
            )
289 292

  
290
    def notify_roles(self, ous, roles, mode='provision', full=False):
293
    def notify_roles(self, ous, roles, mode='provision', full=False, sync=False):
291 294
        allowed_technical_roles_prefixes = getattr(settings, 'HOBO_PROVISION_ROLE_PREFIXES', []) or []
292 295

  
293 296
        def is_forbidden_technical_role(role):
......
340 343
                        '@type': 'role',
341 344
                        'data': data,
342 345
                    },
343
                }
346
                },
347
                sync=sync,
344 348
            )
345 349

  
346 350
        global_roles = set(ous.get(None, []))
......
486 490
                    for other_instance in instance.members.all():
487 491
                        self.add_saved(other_instance)
488 492

  
489
    def notify_agents(self, data):
493
    def notify_agents(self, data, sync=False):
490 494
        log_path = getattr(settings, 'DEBUG_PROVISIONNING_LOG_PATH', '')
491 495
        if log_path and getattr(settings, 'HOBO_PROVISIONNING_DEBUG', False):
492 496
            try:
......
498 502
                pass
499 503

  
500 504
        if getattr(settings, 'HOBO_HTTP_PROVISIONNING', False):
501
            leftover_audience = self.notify_agents_http(data)
505
            leftover_audience = self.notify_agents_http(data, sync=sync)
502 506
            if not leftover_audience:
503 507
                return
504 508
            logger.info('leftover AMQP audience: %s', leftover_audience)
......
515 519
                    services_by_url[service['saml-sp-metadata-url']] = service
516 520
        return services_by_url
517 521

  
518
    def notify_agents_http(self, data):
522
    def notify_agents_http(self, data, sync=False):
519 523
        services_by_url = self.get_http_services_by_url()
520 524
        audience = data.get('audience')
521 525
        rest_audience = [x for x in audience if x in services_by_url]
......
523 527
        for audience in rest_audience:
524 528
            service = services_by_url[audience]
525 529
            data['audience'] = [audience]
530
            url = service['provisionning-url'] + '?orig=%s' % service['orig']
531
            if sync:
532
                url += '&sync=1'
526 533
            try:
527
                response = requests.put(
528
                    sign_url(service['provisionning-url'] + '?orig=%s' % service['orig'], service['secret']),
529
                    json=data,
530
                )
534
                response = requests.put(sign_url(url, service['secret']), json=data)
531 535
                response.raise_for_status()
532 536
            except requests.RequestException as e:
533 537
                logger.error(u'error provisionning to %s (%s)', audience, e)
hobo/agent/authentic2/views.py
57 57
                user = provisionning.User.objects.get(uuid=user_uuid)
58 58
            except provisionning.User.DoesNotExist:
59 59
                return Response({'err': 1, 'err_desc': 'unknown user UUID'})
60
            engine.notify_users(ous=None, users=[user])
60
            engine.notify_users(ous=None, users=[user], sync=True)
61 61
        elif role_uuid:
62 62
            try:
63 63
                role = provisionning.Role.objects.get(uuid=role_uuid)
64 64
            except provisionning.Role.DoesNotExist:
65 65
                return Response({'err': 1, 'err_desc': 'unknown role UUID'})
66 66
            ous = {ou.id: ou for ou in provisionning.OU.objects.all()}
67
            engine.notify_roles(ous=ous, roles=[role])
67
            engine.notify_roles(ous=ous, roles=[role], sync=True)
68 68

  
69 69
        response = {
70 70
            'err': 0,
......
97 97
            services_by_url = {k: v for k, v in services_by_url.items() if self.service_url in v['url']}
98 98
        return services_by_url
99 99

  
100
    def notify_agents(self, data):
101
        self.leftover_audience = self.notify_agents_http(data)
100
    def notify_agents(self, data, sync=False):
101
        self.leftover_audience = self.notify_agents_http(data, sync=sync)
102 102
        # only include filtered services in leftovers
103 103
        services_by_url = self.get_http_services_by_url()
104 104
        self.leftover_audience = [x for x in self.leftover_audience if x in services_by_url]
hobo/provisionning/middleware.py
24 24
from django.utils.encoding import force_text
25 25
from django.utils.six.moves.urllib.parse import urlparse
26 26

  
27
from hobo.provisionning.utils import NotificationProcessing, TryAgain
27
from hobo.provisionning.utils import NotificationProcessing
28 28
from hobo.rest_authentication import PublikAuthentication, PublikAuthenticationFailed
29 29

  
30 30

  
......
54 54
        full = notification['full'] if 'full' in notification else False
55 55
        data = notification['objects']['data']
56 56

  
57
        if 'uwsgi' in sys.modules:
57
        if 'uwsgi' in sys.modules and 'sync' not in request.GET:
58 58
            from hobo.provisionning.spooler import provision
59 59

  
60 60
            tenant = getattr(connection, 'tenant', None)
61
-