add_rule.py 5.23 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE.  If not, see <http://www.gnu.org/licenses/>.

from __future__ import unicode_literals, absolute_import

from django.core.management.base import BaseCommand, CommandError
18
import logging
19

20
from firewall.models import Firewall, VlanGroup, Rule
21 22
from django.contrib.auth.models import User

23 24
logger = logging.getLogger(__name__)

25 26 27 28 29

class Command(BaseCommand):

    def add_arguments(self, parser):

30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
        group = parser.add_mutually_exclusive_group(required=True)

        group.add_argument('--port',
                           action='store',
                           dest='port',
                           type=int,
                           help='port which will open (0-65535)')

        group.add_argument('--port-range',
                           action='store',
                           dest='range',
                           type=int,
                           nargs=2,
                           help='closed port range which will open (0-65535)',
                           metavar=('LOWER', 'HIGHER'))
45 46 47 48

        parser.add_argument('--protocol',
                            action='store',
                            dest='proto',
49
                            required=True,
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
                            choices=('tcp', 'udp', 'icmp'),
                            help='protocol name')

        parser.add_argument('--action',
                            action='store',
                            dest='action',
                            default='accept',
                            choices=('accept', 'drop', 'ignore'),
                            help='action of the rule')

        parser.add_argument('--dir',
                            action='store',
                            dest='dir',
                            default='in',
                            choices=('in', 'out'),
                            help='direction of the rule')

67
        parser.add_argument('--firewall',
68
                            action='store',
69
                            dest='firewall',
70
                            required=True,
71
                            help='firewall name which open the given port')
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87

        parser.add_argument('--vlan-group',
                            action='store',
                            dest='vlan_group',
                            required=True,
                            help='vlan group name where the port will open')

        parser.add_argument('--owner',
                            action='store',
                            dest='owner',
                            required=True,
                            help='name of user who owns the rule')

    def handle(self, *args, **options):

        port = options['port']
88
        range = options['range']
89 90 91 92
        proto = options['proto']
        action = options['action']
        dir = options['dir']
        owner = options['owner']
93
        firewall = options['firewall']
94 95 96 97
        fnet = options['vlan_group']

        try:
            owner = User.objects.get(username=owner)
98
            firewall = Firewall.objects.get(name=firewall)
99 100 101
            fnet = VlanGroup.objects.get(name=fnet)
        except User.DoesNotExist:
            raise CommandError("User '%s' does not exist" % owner)
102 103
        except Firewall.DoesNotExist:
            raise CommandError("Firewall '%s' does not exist" % firewall)
104 105 106
        except VlanGroup.DoesNotExist:
            raise CommandError("VlanGroup '%s' does not exist" % fnet)

107 108
        if port:
            self.validate_port(port)
109
            try:
110 111 112
                rule = self.make_rule(dport=port, proto=proto, action=action,
                                      direction=dir, owner=owner,
                                      firewall=firewall, foreign_network=fnet)
113 114 115
                rule.save()
            except Warning as e:
                logger.warning(e)
116
        else:
117 118 119 120
            lower = min(range)
            higher = max(range)
            self.validate_port(lower)
            self.validate_port(higher)
121

122
            rules = []
123

124
            for port in xrange(lower, higher+1):
125 126
                try:
                    rule = self.make_rule(port, proto, action, dir,
127
                                          owner, firewall, fnet)
128 129 130
                    rules.append(rule)
                except Warning as e:
                    logger.warning(e)
131 132 133

            Rule.objects.bulk_create(rules)

134
    def make_rule(self, **kwargs):
135

136
        rule, created = Rule.objects.get_or_create(**kwargs)
137

138
        if not created:
139 140
            raise Warning(('Rule does exist: %s' %
                          unicode(rule)).encode('utf-8'))
141

142
        rule.full_clean()
143 144

        return rule
145

146 147 148
    def validate_port(self, port):
        if port < 0 or port > 65535:
            raise CommandError("Port '%i' not in range [0-65535]" % port)