Projet

Général

Profil

0001-add-new-agent-task-to-provision-objects-to-tenants-f.patch

Benjamin Dauvergne, 10 septembre 2015 10:02

Télécharger (5,42 ko)

Voir les différences:

Subject: [PATCH] add new agent task to provision objects to tenants (fixes
 #8217)

First use is to connect it to post_save, post_delete signal on Role
model of authentic, to propagate roles to tenants.
 hobo/agent/authentic2/apps.py | 58 +++++++++++++++++++++++++++++++++++++++++++
 hobo/agent/common/__init__.py | 25 +++++++++++++++++++
 hobo/agent/worker/celery.py   |  6 +++++
 hobo/agent/worker/services.py | 18 ++++++++++++++
 4 files changed, 107 insertions(+)
hobo/agent/authentic2/apps.py
1 1
from django.apps import AppConfig
2
from django.db.models.signals import post_save, post_delete, Q
3
from django.db.models import Q
4

  
5
from django_rbac.utils import get_role_model
6

  
7
from hobo.agent.common import notify_agents
8
from authentic2.utils import to_list
9
from authentic2.saml.models import LibertyProvider
10

  
11

  
12
def get_ou(role_or_through):
13
    is hasattr(role_or_through, 'ou'):
14
        return role_or_through.ou
15
    else:
16
        return role_or_through.role.ou
17

  
18

  
19
def get_audience(role_or_through):
20
    ou = get_ou(role_or_through)
21
    if ou:
22
        qs = LibertyProvider.objects.filter(ou=ou)
23
    else:
24
        qs = LibertyProvider.objects.filter(ou__isnull=True)
25
    return qs.values_list('entity_id', flat=True)
26

  
27

  
28
def get_related_roles(role_or_through)
29
    Role = get_role_model()
30
    qs = Role.objects.filter(admin_scope_id__isnull=True)
31
    if ou:
32
        return qs.filter(Q(ou=ou)|Q(ou__isnull=True))
33
    else:
34
        return qs.filter(ou__isnull=True)
35

  
36

  
37
def notify_roles(sender, instance, **kwargs):
38
    notify_agents({
39
        '@type': 'provision',
40
        'audience': get_audience(instance),
41
        'full': True,
42
        'objects': [
43
            {
44
                '@type': 'role',
45
                'uuid': role.uuid,
46
                'name': role.name,
47
                'slug': role.slug,
48
                'description': role.description,
49
            } for role in get_related_roles(instance),
50
        ]
51
    })
52

  
2 53

  
3 54
class Authentic2AgentConfig(AppConfig):
4 55
    name = 'hobo.agent.authentic2'
5 56
    label = 'authentic2_agent'
6 57
    verbose_name = 'Authentic2 Agent'
58

  
59
    def ready(self):
60
        Role = get_role_model()
61
        post_save.connect(notify_roles, Role)
62
        post_delete.connect(notify_roles, Role)
63
        post_save.connect(notify_roles, Role.members.through)
64
        post_delete.connect(notify_roles, Role.members.through)
hobo/agent/common/__init__.py
1
from celery import Celery
2
from kombu.common import Broadcast
3

  
4
from django.conf import settings
5
from django.db import connection
6

  
7

  
8
def notify_agents(data):
9
    '''Send notifications to all other tenants'''
10
    notification = {
11
        'tenant': connection.get_tenant().domain_url,
12
        'data': data,
13
    }
14
    with Celery('hobo', broker=settings.BROKER_URL) as app:
15
        app.conf.update(
16
            CELERY_TASK_SERIALIZER='json',
17
            CELERY_ACCEPT_CONTENT=['json'],
18
            CELERY_RESULT_SERIALIZER='json',
19
            CELERY_QUEUES=(Broadcast('broadcast_tasks'), )
20
        )
21
        # see called method in hobo.agent.worker.celery
22
        app.send_task('hobo-notify',
23
                      (notification,),
24
                      expires=settings.BROKER_TASK_EXPIRES,
25
                      queue='broadcast_tasks')
hobo/agent/worker/celery.py
13 13
    CELERY_QUEUES=(Broadcast('broadcast_tasks'), )
14 14
)
15 15

  
16

  
16 17
@app.task(name='hobo-deploy', bind=True)
17 18
def deploy(self, environment):
18 19
    services.deploy(environment)
20

  
21

  
22
@app.task(name='hobo-notify', bind=True, acks_late=True)
23
def hobo_notify(self, data):
24
    services.notify(data)
hobo/agent/worker/services.py
55 55
                shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
56 56
        stdout = cmd_process.communicate(input=json.dumps(environment))
57 57

  
58
    @classmethod
59
    def notify(cls, data):
60
        cmd = settings.service_manage_cmd + ' hobo_notify -'
61
        try:
62
            cmd_process = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
63
                                           stdout=subprocess.PIPE)
64
        except OSError:
65
            return
66
        cmd_process.communicate(input=json.dumps(data))
67
        if cmd_process.returncode != 0:
68
            raise RuntimeError('command "%s" failed' % what)
69

  
58 70

  
59 71
class Passerelle(BaseService):
60 72
    service_id = 'passerelle'
......
113 125
            logger.debug('skipping uptodate site: %r', service_obj)
114 126
            continue
115 127
        service_obj.execute(environment)
128

  
129
def notify(data):
130
    for klassname, service in globals().items():
131
        if not hasattr(service, 'notify'):
132
            continue
133
        service.notify(data)
116
-