generate the rule name in junos
authorStauros Kroustouris <staurosk@noc.grnet.gr>
Fri, 5 Dec 2014 15:18:43 +0000 (17:18 +0200)
committerStauros Kroustouris <staurosk@noc.grnet.gr>
Wed, 7 Jan 2015 14:19:30 +0000 (16:19 +0200)
flowspec/junos.py [new file with mode: 0644]
flowspec/models.py
flowspec/views.py

diff --git a/flowspec/junos.py b/flowspec/junos.py
new file mode 100644 (file)
index 0000000..ce8173d
--- /dev/null
@@ -0,0 +1,207 @@
+PROTOCOL_NUMBERS = {
+    'HOPOPT': '0',
+    'ICMP': '1',
+    'IGMP': '2',
+    'GGP': '3',
+    'IPv4': '4',
+    'ST': '5',
+    'TCP': '6',
+    'CBT': '7',
+    'EGP': '8',
+    'IGP': '9',
+    'BBN-RCC-MON': '10',
+    'NVP-II': '11',
+    'PUP': '12',
+    'ARGUS': '13',
+    'EMCON': '14',
+    'XNET': '15',
+    'CHAOS': '16',
+    'UDP': '17',
+    'MUX': '18',
+    'DCN-MEAS': '19',
+    'HMP': '20',
+    'PRM': '21',
+    'XNS-IDP': '22',
+    'TRUNK-1': '23',
+    'TRUNK-2': '24',
+    'LEAF-1': '25',
+    'LEAF-2': '26',
+    'RDP': '27',
+    'IRTP': '28',
+    'ISO-TP4': '29',
+    'NETBLT': '30',
+    'MFE-NSP': '31',
+    'MERIT-INP': '32',
+    'DCCP': '33',
+    '3PC': '34',
+    'IDPR': '35',
+    'XTP': '36',
+    'DDP': '37',
+    'IDPR-CMTP': '38',
+    'TP++': '39',
+    'IL': '40',
+    'IPv6': '41',
+    'SDRP': '42',
+    'IPv6-Route': '43',
+    'IPv6-Frag ': '44',
+    'IDRP': '45',
+    'RSVP': '46',
+    'GRE': '47',
+    'DSR': '48',
+    'BNA': '49',
+    'ESP': '50',
+    'AH': '51',
+    'I-NLSP': '52',
+    'SWIPE': '53',
+    'NARP': '54',
+    'MOBILE': '55',
+    'TLSP': '56',
+    'SKIP': '57',
+    'IPv6-ICMP': '58',
+    'IPv6-NoNxt': '59',
+    'IPv6-Opts': '60',
+    'CFTP': '62',
+    'SAT-EXPAK': '64',
+    'KRYPTOLAN': '65',
+    'RVD': '66',
+    'IPPC': '67',
+    'SAT-MON': '69',
+    'VISA': '70',
+    'IPCV': '71',
+    'CPNX': '72',
+    'CPHB': '73',
+    'WSN': '74',
+    'PVP': '75',
+    'BR-SAT-MON': '76',
+    'SUN-ND': '77',
+    'WB-MON': '78',
+    'WB-EXPAK': '79',
+    'ISO-IP': '80',
+    'VMTP': '81',
+    'SECURE-VMTP': '82',
+    'VINES': '83',
+    'TTP': '84',
+    'IPTM': '84',
+    'NSFNET-IGP': '85',
+    'DGP': '86',
+    'TCF': '87',
+    'EIGRP': '88',
+    'OSPFIGP': '89',
+    'Sprite-RPC': '90',
+    'LARP': '91',
+    'MTP': '92',
+    'AX.25': '93',
+    'IPIP': '94',
+    'MICP': '95',
+    'SCC-SP': '96',
+    'ETHERIP': '97',
+    'ENCAP': '98',
+    'GMTP': '100',
+    'IFMP': '101',
+    'PNNI': '102',
+    'PIM': '103',
+    'ARIS': '104',
+    'SCPS': '105',
+    'QNX': '106',
+    'A/N': '107',
+    'IPComp': '108',
+    'SNP': '109',
+    'Compaq-Peer': '110',
+    'IPX-in-IP': '111',
+    'VRRP': '112',
+    'PGM': '113',
+    'L2TP': '115',
+    'DDX': '116',
+    'IATP': '117',
+    'STP': '118',
+    'SRP': '119',
+    'UTI': '120',
+    'SMP': '121',
+    'SM': '122',
+    'PTP ': '123',
+    'ISIS': '124',
+    'FIRE': '125',
+    'CRTP': '126',
+    'CRUDP': '127',
+    'SSCOPMCE': '128',
+    'IPLT': '129',
+    'SPS': '130',
+    'PIPE': '131',
+    'SCTP': '132',
+    'FC': '133',
+    'RSVP-E2E-IGNORE': '134',
+    'Mobility Header': '135',
+    'UDPLite': '136',
+    'MPLS-in-IP': '137',
+    'manet': '138',
+    'HIP': '139',
+    'Shim6': '140',
+    'WESP': '141',
+    'ROHC': '142'
+}
+
+
+def get_protocols_numbers(protocols_set):
+    protocols = 'proto'
+    for protocol in protocols_set:
+        protocols += '=%s,' % PROTOCOL_NUMBERS.get(protocol.protocol.upper())
+    return protocols
+
+
+def get_range(addr_range):
+    if '/32' in addr_range:
+        addr_range = addr_range.replace('/32', '')
+    if len(addr_range.split('/')) > 1:
+        mask = addr_range.split('/')[1]
+    else:
+        mask = False
+    elements = addr_range.split('/')[0].split('.')
+    if '0' in elements:
+        if elements == ['0', '0', '0', '0']:
+            addr_range = '0'
+            if mask is not False:
+                addr_range += '/%s' % mask
+        elif elements[1:] == ['0', '0', '0']:
+            addr_range = '.'.join(elements[:2])
+            if mask is not False:
+                addr_range += '/%s' % mask
+        elif elements[2:] == ['0', '0']:
+            addr_range = '.'.join(elements[:3])
+            if mask is not False:
+                addr_range += '/%s' % mask
+    return addr_range + ','
+
+
+def get_ports(rule):
+    if rule.port.all():
+        result = 'port'
+        for port in rule.port.all():
+            result += '=%s,' % port
+    else:
+        result = ''
+        if rule.destinationport.all():
+            result += 'dstport'
+            for port in rule.destinationport.all():
+                result += '=%s,' % port
+        if rule.sourceport.all():
+            result += 'srcport'
+            for port in rule.sourceport.all():
+                result += '=%s,' % port
+    return result
+
+
+def create_junos_name(rule):
+    name = ''
+    # destination
+    name += get_range(rule.destination)
+    # source
+    name += get_range(rule.source)
+    # protocols
+    name += get_protocols_numbers(rule.protocol.all())
+    # ports
+    name += get_ports(rule)
+    frag = ''
+    name += frag
+    if name[-1] == ',':
+        name = name[:-1]
+    return name
index af23a03..5f2f455 100644 (file)
@@ -26,12 +26,14 @@ from ipaddr import *
 import datetime
 import logging
 from time import sleep
+from junos import create_junos_name, policer_name
 
 import beanstalkc
 from utils.randomizer import id_generator as id_gen
 
 from tasks import *
 
+
 def user_unicode_patch(self):
     peer = None
     try:
@@ -66,7 +68,7 @@ THEN_CHOICES = (
     ("next-term", "Next term"),
     ("routing-instance", "Routing Instance"),
     ("rate-limit", "Rate limit"),
-    ("sample", "Sample")                
+    ("sample", "Sample")
 )
 
 MATCH_PROTOCOL = (
@@ -93,18 +95,18 @@ ROUTE_STATES = (
     ("PENDING", "PENDING"),
     ("OUTOFSYNC", "OUTOFSYNC"),
     ("INACTIVE", "INACTIVE"),
-    ("ADMININACTIVE", "ADMININACTIVE"),           
+    ("ADMININACTIVE", "ADMININACTIVE"),
 )
 
 
 def days_offset(): return datetime.date.today() + datetime.timedelta(days = settings.EXPIRATION_DAYS_OFFSET)
-    
+
 class MatchPort(models.Model):
     port = models.CharField(max_length=24, unique=True)
     def __unicode__(self):
         return self.port
     class Meta:
-        db_table = u'match_port'    
+        db_table = u'match_port'
 
 class MatchDscp(models.Model):
     dscp = models.CharField(max_length=24)
@@ -122,7 +124,7 @@ class MatchProtocol(models.Model):
 
 class FragmentType(models.Model):
     fragmenttype = models.CharField(max_length=20, choices=FRAGMENT_CODES, verbose_name="Fragment Type")
-    
+
     def __unicode__(self):
         return "%s" %(self.fragmenttype)
 
@@ -130,14 +132,17 @@ class FragmentType(models.Model):
 class ThenAction(models.Model):
     action = models.CharField(max_length=60, choices=THEN_CHOICES, verbose_name="Action")
     action_value = models.CharField(max_length=255, blank=True, null=True, verbose_name="Action Value")
+
     def __unicode__(self):
         ret = "%s:%s" %(self.action, self.action_value)
         return ret.rstrip(":")
+
     class Meta:
         db_table = u'then_action'
         ordering = ['action', 'action_value']
         unique_together = ("action", "action_value")
 
+
 class Route(models.Model):
     name = models.SlugField(max_length=128, verbose_name=_("Name"))
     applier = models.ForeignKey(User, blank=True, null=True)
@@ -163,22 +168,22 @@ class Route(models.Model):
     response = models.CharField(max_length=512, blank=True, null=True, verbose_name=_("Response"))
     comments = models.TextField(null=True, blank=True, verbose_name=_("Comments"))
 
-    
+
     def __unicode__(self):
         return self.name
-    
+
     class Meta:
         db_table = u'route'
         verbose_name = "Rule"
         verbose_name_plural = "Rules"
-    
+
     def save(self, *args, **kwargs):
         if not self.pk:
             hash = id_gen()
             self.name = "%s_%s" %(self.name, hash)
         super(Route, self).save(*args, **kwargs) # Call the "real" save() method.
 
-        
+
     def clean(self, *args, **kwargs):
         from django.core.exceptions import ValidationError
         if self.destination:
@@ -193,13 +198,13 @@ class Route(models.Model):
                 self.source = address.exploded
             except Exception:
                 raise ValidationError(_('Invalid network address format at Source Field'))
-   
+
     def commit_add(self, *args, **kwargs):
         peer = self.applier.get_profile().peer.peer_tag
         send_message("[%s] Adding rule %s. Please wait..." %(self.applier.username, self.name), peer)
         response = add.delay(self)
         logger.info("Got add job id: %s" %response)
-        
+
     def commit_edit(self, *args, **kwargs):
         peer = self.applier.get_profile().peer.peer_tag
         send_message("[%s] Editing rule %s. Please wait..." %(self.applier.username, self.name), peer)
@@ -222,12 +227,12 @@ class Route(models.Model):
         if today > self.expires:
             return True
         return False
-    
+
     def check_sync(self):
         if not self.is_synced():
             self.status = "OUTOFSYNC"
             self.save()
-    
+
     def is_synced(self):
         found = False
         get_device = PR.Retriever()
@@ -266,7 +271,7 @@ class Route(models.Model):
                         logger.info('Source fields do not match')
                 except:
                     pass
-                
+
                 try:
                     assert(self.fragmenttype.all())
                     assert(devicematch['fragment'])
@@ -281,7 +286,7 @@ class Route(models.Model):
                         logger.info('Fragment type fields do not match')
                 except:
                     pass
-                
+
                 try:
                     assert(self.port.all())
                     assert(devicematch['port'])
@@ -296,7 +301,7 @@ class Route(models.Model):
                         logger.info('Port type fields do not match')
                 except:
                     pass
-                
+
                 try:
                     assert(self.protocol.all())
                     assert(devicematch['protocol'])
@@ -341,8 +346,8 @@ class Route(models.Model):
                         logger.info('Source port type fields do not match')
                 except:
                     pass
-                                
-                
+
+
 #                try:
 #                    assert(self.fragmenttype)
 #                    assert(devicematch['fragment'][0])
@@ -391,10 +396,10 @@ class Route(models.Model):
         for statement in then_statements:
             if statement.action_value:
                 ret = "%s %s %s" %(ret, statement.action, statement.action_value)
-            else: 
+            else:
                 ret = "%s %s" %(ret, statement.action)
         return ret
-    
+
     get_then.short_description = 'Then statement'
     get_then.allow_tags = True
 #
@@ -437,10 +442,10 @@ class Route(models.Model):
                     ret = ret + "%s <dt>Port</dt><dd>%s</dd>" %(ret, dscp)
         ret = ret + "</dl>"
         return ret
-        
+
     get_match.short_description = 'Match statement'
     get_match.allow_tags = True
-    
+
     @property
     def applier_peer(self):
         try:
@@ -448,7 +453,7 @@ class Route(models.Model):
         except:
             applier_peer = None
         return applier_peer
-    
+
     @property
     def days_to_expire(self):
         if self.status not in ['EXPIRED', 'ADMININACTIVE', 'ERROR', 'INACTIVE']:
@@ -460,6 +465,11 @@ class Route(models.Model):
         else:
             return False
 
+    @property
+    def junos_name(self):
+        return create_junos_name(self)
+
+
 def send_message(msg, user):
 #    username = user.username
     peer = user
index 95985f3..44c5f36 100644 (file)
@@ -43,7 +43,7 @@ from django.contrib.auth import authenticate, login
 
 from django.forms.models import model_to_dict
 
-from flowspec.forms import * 
+from flowspec.forms import *
 from flowspec.models import *
 from peers.models import *
 
@@ -125,7 +125,7 @@ def group_routes_ajax(request):
     jresp = {}
     routes = build_routes_json(group_routes)
     jresp['aaData'] = routes
-    return HttpResponse(json.dumps(jresp), mimetype='application/json') 
+    return HttpResponse(json.dumps(jresp), mimetype='application/json')
 
 @login_required
 @never_cache
@@ -145,7 +145,7 @@ def overview_routes_ajax(request):
     jresp = {}
     routes = build_routes_json(group_routes)
     jresp['aaData'] = routes
-    return HttpResponse(json.dumps(jresp), mimetype='application/json') 
+    return HttpResponse(json.dumps(jresp), mimetype='application/json')
 
 def build_routes_json(groutes):
     routes = []
@@ -153,7 +153,10 @@ def build_routes_json(groutes):
         rd = {}
         rd['id'] = r.pk
         rd['name'] = r.name
-        rd['comments'] = r.comments
+        if not r.comments:
+            rd['comments'] = 'Not Any'
+        else:
+            rd['comments'] = r.comments
         rd['match'] = r.get_match()
         rd['then'] = r.get_then()
         rd['status'] = r.status
@@ -340,7 +343,7 @@ def delete_route(request, route_slug):
                                              {"route": route, "address": requesters_address, "action": "removal", "url": admin_url})
             user_mail = "%s" %route.applier.email
             user_mail = user_mail.split(';')
-            send_new_mail(settings.EMAIL_SUBJECT_PREFIX + "Rule %s removal request submitted by %s" %(route.name, route.applier.username), 
+            send_new_mail(settings.EMAIL_SUBJECT_PREFIX + "Rule %s removal request submitted by %s" %(route.name, route.applier.username),
                               mail_body, settings.SERVER_EMAIL, user_mail,
                              get_peer_techc_mails(route.applier))
             d = { 'clientip' : requesters_address, 'user' : route.applier.username }
@@ -382,7 +385,7 @@ def user_login(request):
         mail = lookupShibAttr(settings.SHIB_MAIL, request.META)
         entitlement = lookupShibAttr(settings.SHIB_ENTITLEMENT, request.META)
         #organization = request.META['HTTP_SHIB_HOMEORGANIZATION']
-        
+
         if settings.SHIB_AUTH_ENTITLEMENT in entitlement.split(";"):
             has_entitlement = True
         if not has_entitlement:
@@ -414,7 +417,7 @@ def user_login(request):
         except:
             user_exists = False
         user = authenticate(username=username, firstname=firstname, lastname=lastname, mail=mail, authsource='shibboleth')
-        
+
         if user is not None:
             try:
                 peer = user.get_profile().peer
@@ -448,8 +451,8 @@ def user_login(request):
 def user_activation_notify(user):
     current_site = Site.objects.get_current()
     peer = user.get_profile().peer
-    
-    
+
+
     # Email subject *must not* contain newlines
     # TechCs will be notified about new users.
     # Platform admins will activate the users.
@@ -464,10 +467,10 @@ def user_activation_notify(user):
                                      'user': user })
     if settings.NOTIFY_ADMIN_MAILS:
         admin_mails = settings.NOTIFY_ADMIN_MAILS
-        send_new_mail(settings.EMAIL_SUBJECT_PREFIX + subject, 
+        send_new_mail(settings.EMAIL_SUBJECT_PREFIX + subject,
                                   message, settings.SERVER_EMAIL,
                                  admin_mails, [])
-    
+
     # Mail to domain techCs plus platform admins (no activation hash sent)
     subject = render_to_string('registration/activation_email_peer_notify_subject.txt',
                                    { 'site': current_site,
@@ -476,7 +479,7 @@ def user_activation_notify(user):
     message = render_to_string('registration/activation_email_peer_notify.txt',
                                    { 'user': user,
                                     'peer': peer })
-    send_new_mail(settings.EMAIL_SUBJECT_PREFIX + subject, 
+    send_new_mail(settings.EMAIL_SUBJECT_PREFIX + subject,
                               message, settings.SERVER_EMAIL,
                              get_peer_techc_mails(user), [])
 
@@ -534,7 +537,7 @@ def selectinst(request):
                                   context_instance=RequestContext(request))
         except UserProfile.DoesNotExist:
             pass
-            
+
         form = UserProfileForm(request_data)
         if form.is_valid():
             userprofile = form.save()
@@ -567,7 +570,7 @@ def overview(request):
 def user_logout(request):
     logout(request)
     return HttpResponseRedirect(reverse('group-routes'))
-    
+
 @never_cache
 def load_jscript(request, file):
     long_polling_timeout = int(settings.POLL_SESSION_UPDATE)*1000 + 10000