Statistics
| Branch: | Tag: | Revision:

root / flowspec / tasks.py @ 2cff73d0

History | View | Annotate | Download (7.6 kB)

1
from utils import proxy as PR
2
from celery.task import task
3
from celery.task.sets import subtask
4
import logging
5
import json
6
from celery.task.http import *
7
import beanstalkc
8
from django.conf import settings
9
import datetime
10
from django.core.mail import send_mail
11
from django.template.loader import render_to_string
12
from django.core.urlresolvers import reverse
13
import os
14

    
15

    
16

    
17
LOG_FILENAME = os.path.join(settings.LOG_FILE_LOCATION, 'celery_jobs.log')
18

    
19
#FORMAT = '%(asctime)s %(levelname)s: %(message)s'
20
#logging.basicConfig(format=FORMAT)
21
formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s')
22

    
23
logger = logging.getLogger(__name__)
24
logger.setLevel(logging.DEBUG)
25
handler = logging.FileHandler(LOG_FILENAME)
26
handler.setFormatter(formatter)
27
logger.addHandler(handler)
28

    
29

    
30
@task(ignore_result=True)
31
def add(route, callback=None):
32
    applier = PR.Applier(route_object=route)
33
    commit, response = applier.apply()
34
    if commit:
35
        status = "ACTIVE"
36
    else:
37
        status = "ERROR"
38
    route.status = status
39
    route.response = response
40
    route.save()
41
    announce("[%s] Rule add: %s - Result: %s" %(route.applier, route.name, response), route.applier)
42

    
43
@task(ignore_result=True)
44
def add_set(routes, callback=None):
45
    applier = PR.Applier(route_objects=routes)
46
    commit, response = applier.apply()
47
    route_names = ''
48
    if commit:
49
        status = "ACTIVE"
50
    else:
51
        status = "ERROR"
52
    for route in routes:
53
        route.status = status
54
        route.response = response
55
        route.save()
56
        route_names = "%s, %s" %(route.name, route_names)
57
    announce("[%s] Rules add: %s - Result: %s" %(route.applier, route_names.rstrip(','), response), route.applier)
58

    
59
@task(ignore_result=True)
60
def edit(route, callback=None):
61
    applier = PR.Applier(route_object=route)
62
    commit, response = applier.apply(operation="replace")
63
    if commit:
64
        status = "ACTIVE"
65
    else:
66
        status = "ERROR"
67
    route.status = status
68
    route.response = response
69
    route.save()
70
    announce("[%s] Rule edit: %s - Result: %s"%(route.applier, route.name, response), route.applier)
71

    
72

    
73

    
74
@task(ignore_result=True)
75
def delete(route, **kwargs):
76
    applier = PR.Applier(route_object=route)
77
    commit, response = applier.apply(operation="delete")
78
    reason_text = ''
79
    if commit:
80
        status = "INACTIVE"
81
        if "reason" in kwargs and kwargs['reason']=='EXPIRED':
82
            status = 'EXPIRED'
83
            reason_text = " Reason: %s " %status
84
    else:
85
        status = "ERROR"
86
    route.status = status
87
    route.response = response
88
    route.save()
89
    announce("[%s] Suspending rule : %s%s- Result %s" %(route.applier, route.name, reason_text, response), route.applier)
90

    
91
# May not work in the first place... proxy is not aware of Route models
92
@task
93
def batch_delete(routes, **kwargs):
94
    if routes:
95
        for route in routes:
96
            route.status='PENDING';route.save()
97
        applier = PR.Applier(route_objects=routes)
98
        conf = applier.delete_routes()
99
        commit, response = applier.apply(configuration = conf)
100
        reason_text = ''
101
        if commit:
102
            status = "INACTIVE"
103
            if "reason" in kwargs and kwargs['reason']=='EXPIRED':
104
                status = 'EXPIRED'
105
                reason_text = " Reason: %s " %status
106
            elif "reason" in kwargs and kwargs['reason']!='EXPIRED':
107
                status = kwargs['reason']
108
                reason_text = " Reason: %s " %status
109
        else:
110
            status = "ERROR"
111
        for route in routes:
112
            route.status = status
113
            route.response = response
114
            route.expires = datetime.date.today()
115
            route.save()
116
            announce("[%s] Rule removal: %s%s- Result %s" %(route.applier, route.name, reason_text, response), route.applier)
117
    else:
118
        return False
119

    
120
#@task(ignore_result=True)
121
def announce(messg, user):
122
    messg = str(messg)
123
#    username = user.username
124
    username = user.get_profile().peer.domain_name
125
    b = beanstalkc.Connection()
126
    b.use(settings.POLLS_TUBE)
127
    tube_message = json.dumps({'message': messg, 'username':username})
128
    b.put(tube_message)
129
    b.close()
130

    
131
@task
132
def check_sync(route_name=None, selected_routes = []):
133
    from flowspy.flowspec.models import Route, MatchPort, MatchDscp, ThenAction
134
    if not selected_routes:
135
        routes = Route.objects.all()
136
    else:
137
        routes = selected_routes
138
    if route_name:
139
        routes = routes.filter(name=route_name)
140
    for route in routes:
141
        if route.has_expired() and (route.status != 'EXPIRED' and route.status != 'ADMININACTIVE' and route.status != 'INACTIVE'):
142
            logger.info('Expiring route %s' %route.name)
143
            subtask(delete).delay(route, reason="EXPIRED")
144
#        elif route.has_expired() and (route.status == 'ADMININACTIVE' or route.status == 'INACTIVE'):
145
#            route.status = 'EXPIRED'
146
#            route.response = 'Rule Expired'
147
#            logger.info('Expiring route %s' %route.name)
148
#            route.save()
149
        else:
150
            if route.status != 'EXPIRED':
151
                route.check_sync()
152

    
153
@task(ignore_result=True)
154
def notify_expired():
155
    from flowspy.flowspec.models import *
156
    from django.contrib.sites.models import Site
157
    logger.info('Initializing expiration notification')
158
    routes = Route.objects.all()
159
    for route in routes:
160
        if route.status not in ['EXPIRED', 'ADMININACTIVE', 'INACTIVE', 'ERROR']:
161
            expiration_days = (route.expires - datetime.date.today()).days
162
            if expiration_days < settings.EXPIRATION_NOTIFY_DAYS:
163
                try:
164
                    fqdn = Site.objects.get_current().domain
165
                    admin_url = "https://%s%s" % \
166
                    (fqdn,
167
                     "/fod/edit/%s"%route.name)
168
                    mail_body = render_to_string("rule_expiration.txt",
169
                                             {"route": route, 'expiration_days':expiration_days, 'url':admin_url})
170
                    days_num = ' days'
171
                    expiration_days_text = "%s %s" %('in',expiration_days)
172
                    if expiration_days == 0:
173
                        days_num = ' today'
174
                        expiration_days_text = ''
175
                    if expiration_days == 1:
176
                        days_num = ' day'
177
                    logger.info('Route %s expires %s%s. Notifying %s (%s)' %(route.name, expiration_days_text, days_num, route.applier.username, route.applier.email))
178
                    send_mail(settings.EMAIL_SUBJECT_PREFIX + "Rule %s expires %s%s" %
179
                              (route.name,expiration_days_text, days_num),
180
                              mail_body, settings.SERVER_EMAIL,
181
                              [route.applier.email])
182
                except Exception as e:
183
                    logger.info("Exception: %s"%e)
184
                    pass
185
    logger.info('Expiration notification process finished')
186

    
187
#def delete(route):
188
#    
189
#    applier = PR.Applier(route_object=route)
190
#    commit, response = applier.apply(configuration=applier.delete_routes())
191
#    if commit:
192
#            rows = queryset.update(is_online=False, is_active=False)
193
#            queryset.update(response="Successfully removed route from network")
194
#            self.message_user(request, "Successfully removed %s routes from network" % rows)
195
#        else:
196
#            self.message_user(request, "Could not remove routes from network")
197
#    if commit:
198
#        is_online = False
199
#        is_active = False
200
#        response = "Successfully removed route from network"
201
#    else:
202
#        is_online = False
203
#        is_active = True
204
#    route.is_online = is_online
205
#    route.is_active = is_active
206
#    route.response = response
207
#    route.save()