Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / api / management / commands / network-create.py @ adc46059

History | View | Annotate | Download (6.7 kB)

1 6dd70a5c Christos Stavrakakis
# Copyright 2012 GRNET S.A. All rights reserved.
2 6dd70a5c Christos Stavrakakis
#
3 6dd70a5c Christos Stavrakakis
# Redistribution and use in source and binary forms, with or
4 6dd70a5c Christos Stavrakakis
# without modification, are permitted provided that the following
5 6dd70a5c Christos Stavrakakis
# conditions are met:
6 6dd70a5c Christos Stavrakakis
#
7 6dd70a5c Christos Stavrakakis
#   1. Redistributions of source code must retain the above
8 6dd70a5c Christos Stavrakakis
#      copyright notice, this list of conditions and the following
9 6dd70a5c Christos Stavrakakis
#      disclaimer.
10 6dd70a5c Christos Stavrakakis
#
11 6dd70a5c Christos Stavrakakis
#   2. Redistributions in binary form must reproduce the above
12 6dd70a5c Christos Stavrakakis
#      copyright notice, this list of conditions and the following
13 6dd70a5c Christos Stavrakakis
#      disclaimer in the documentation and/or other materials
14 6dd70a5c Christos Stavrakakis
#      provided with the distribution.
15 6dd70a5c Christos Stavrakakis
#
16 6dd70a5c Christos Stavrakakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 6dd70a5c Christos Stavrakakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 6dd70a5c Christos Stavrakakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 6dd70a5c Christos Stavrakakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 6dd70a5c Christos Stavrakakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 6dd70a5c Christos Stavrakakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 6dd70a5c Christos Stavrakakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 6dd70a5c Christos Stavrakakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 6dd70a5c Christos Stavrakakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 6dd70a5c Christos Stavrakakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 6dd70a5c Christos Stavrakakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 6dd70a5c Christos Stavrakakis
# POSSIBILITY OF SUCH DAMAGE.
28 6dd70a5c Christos Stavrakakis
#
29 6dd70a5c Christos Stavrakakis
# The views and conclusions contained in the software and
30 6dd70a5c Christos Stavrakakis
# documentation are those of the authors and should not be
31 6dd70a5c Christos Stavrakakis
# interpreted as representing official policies, either expressed
32 6dd70a5c Christos Stavrakakis
# or implied, of GRNET S.A.
33 6dd70a5c Christos Stavrakakis
34 6dd70a5c Christos Stavrakakis
from optparse import make_option
35 6dd70a5c Christos Stavrakakis
36 6dd70a5c Christos Stavrakakis
from django.core.management.base import BaseCommand, CommandError
37 6dd70a5c Christos Stavrakakis
38 7fede91e Christos Stavrakakis
from synnefo.db.models import Network, Backend
39 af6a3bc5 Christos Stavrakakis
from synnefo.api.util import net_resources, validate_network_size
40 6dd70a5c Christos Stavrakakis
from synnefo.logic.backend import create_network
41 b14725eb Christos Stavrakakis
from synnefo import settings
42 6dd70a5c Christos Stavrakakis
43 6dd70a5c Christos Stavrakakis
import ipaddr
44 6dd70a5c Christos Stavrakakis
45 6dd70a5c Christos Stavrakakis
NETWORK_TYPES = ['PUBLIC_ROUTED', 'PRIVATE_MAC_FILTERED',
46 6dd70a5c Christos Stavrakakis
                 'PRIVATE_PHYSICAL_VLAN', 'CUSTOM_ROUTED',
47 6dd70a5c Christos Stavrakakis
                 'CUSTOM_BRIDGED']
48 6dd70a5c Christos Stavrakakis
49 6dd70a5c Christos Stavrakakis
50 6dd70a5c Christos Stavrakakis
class Command(BaseCommand):
51 b14725eb Christos Stavrakakis
    can_import_settings = True
52 b7e74f05 Christos Stavrakakis
    output_transaction = True
53 b14725eb Christos Stavrakakis
54 6dd70a5c Christos Stavrakakis
    help = "Create a new network"
55 6dd70a5c Christos Stavrakakis
56 6dd70a5c Christos Stavrakakis
    option_list = BaseCommand.option_list + (
57 6dd70a5c Christos Stavrakakis
        make_option('--name',
58 6dd70a5c Christos Stavrakakis
            dest='name',
59 6dd70a5c Christos Stavrakakis
            help="Name of network"),
60 6dd70a5c Christos Stavrakakis
        make_option('--owner',
61 6dd70a5c Christos Stavrakakis
            dest='owner',
62 6dd70a5c Christos Stavrakakis
            help="The owner of the network"),
63 6dd70a5c Christos Stavrakakis
        make_option('--subnet',
64 6dd70a5c Christos Stavrakakis
            dest='subnet',
65 6dd70a5c Christos Stavrakakis
            default=None,
66 6dd70a5c Christos Stavrakakis
            # required=True,
67 6dd70a5c Christos Stavrakakis
            help='Subnet of the network'),
68 6dd70a5c Christos Stavrakakis
        make_option('--gateway',
69 6dd70a5c Christos Stavrakakis
            dest='gateway',
70 6dd70a5c Christos Stavrakakis
            default=None,
71 6dd70a5c Christos Stavrakakis
            help='Gateway of the network'),
72 6dd70a5c Christos Stavrakakis
        make_option('--dhcp',
73 6dd70a5c Christos Stavrakakis
            dest='dhcp',
74 6dd70a5c Christos Stavrakakis
            action='store_true',
75 6dd70a5c Christos Stavrakakis
            default=False,
76 6dd70a5c Christos Stavrakakis
            help='Automatically assign IPs'),
77 6dd70a5c Christos Stavrakakis
        make_option('--public',
78 6dd70a5c Christos Stavrakakis
            dest='public',
79 6dd70a5c Christos Stavrakakis
            action='store_true',
80 6dd70a5c Christos Stavrakakis
            default=False,
81 6dd70a5c Christos Stavrakakis
            help='Network is public'),
82 6dd70a5c Christos Stavrakakis
        make_option('--type',
83 6dd70a5c Christos Stavrakakis
            dest='type',
84 6dd70a5c Christos Stavrakakis
            default='PRIVATE_MAC_FILTERED',
85 6dd70a5c Christos Stavrakakis
            choices=NETWORK_TYPES,
86 6dd70a5c Christos Stavrakakis
            help='Type of network. Choices: ' + ', '.join(NETWORK_TYPES)),
87 6dd70a5c Christos Stavrakakis
        make_option('--subnet6',
88 6dd70a5c Christos Stavrakakis
            dest='subnet6',
89 6dd70a5c Christos Stavrakakis
            default=None,
90 6dd70a5c Christos Stavrakakis
            help='IPv6 subnet of the network'),
91 6dd70a5c Christos Stavrakakis
        make_option('--gateway6',
92 6dd70a5c Christos Stavrakakis
            dest='gateway6',
93 6dd70a5c Christos Stavrakakis
            default=None,
94 6dd70a5c Christos Stavrakakis
            help='IPv6 gateway of the network'),
95 7fede91e Christos Stavrakakis
        make_option('--backend-id',
96 7fede91e Christos Stavrakakis
            dest='backend_id',
97 7fede91e Christos Stavrakakis
            default=None,
98 7fede91e Christos Stavrakakis
            help='ID of the backend that the network will be created. Only for'
99 7fede91e Christos Stavrakakis
                 ' public networks')
100 6dd70a5c Christos Stavrakakis
        )
101 6dd70a5c Christos Stavrakakis
102 6dd70a5c Christos Stavrakakis
    def handle(self, *args, **options):
103 6dd70a5c Christos Stavrakakis
        if args:
104 6dd70a5c Christos Stavrakakis
            raise CommandError("Command doesn't accept any arguments")
105 6dd70a5c Christos Stavrakakis
106 6dd70a5c Christos Stavrakakis
        name = options['name']
107 6dd70a5c Christos Stavrakakis
        subnet = options['subnet']
108 af6a3bc5 Christos Stavrakakis
        net_type = options['type']
109 7fede91e Christos Stavrakakis
        backend_id = options['backend_id']
110 7fede91e Christos Stavrakakis
        public = options['public']
111 6dd70a5c Christos Stavrakakis
112 6dd70a5c Christos Stavrakakis
        if not name:
113 6dd70a5c Christos Stavrakakis
            raise CommandError("Name is required")
114 6dd70a5c Christos Stavrakakis
        if not subnet:
115 6dd70a5c Christos Stavrakakis
            raise CommandError("Subnet is required")
116 7fede91e Christos Stavrakakis
        if public and not backend_id:
117 7fede91e Christos Stavrakakis
            raise CommandError("backend-id is required")
118 af6a3bc5 Christos Stavrakakis
        if public and not net_type == 'PUBLIC_ROUTED':
119 b7e74f05 Christos Stavrakakis
            raise CommandError("Invalid type for public network")
120 7fede91e Christos Stavrakakis
        if backend_id and not public:
121 7fede91e Christos Stavrakakis
            raise CommandError("Private networks must be created to"
122 7fede91e Christos Stavrakakis
                               " all backends")
123 7fede91e Christos Stavrakakis
124 7fede91e Christos Stavrakakis
        if backend_id:
125 7fede91e Christos Stavrakakis
            try:
126 7fede91e Christos Stavrakakis
                backend_id = int(backend_id)
127 7fede91e Christos Stavrakakis
                backend = Backend.objects.get(id=backend_id)
128 7fede91e Christos Stavrakakis
            except ValueError:
129 7fede91e Christos Stavrakakis
                raise CommandError("Invalid backend ID")
130 7fede91e Christos Stavrakakis
            except Backend.DoesNotExist:
131 7fede91e Christos Stavrakakis
                raise CommandError("Backend not found in DB")
132 6dd70a5c Christos Stavrakakis
133 af6a3bc5 Christos Stavrakakis
        link, mac_prefix = net_resources(net_type)
134 6dd70a5c Christos Stavrakakis
135 6dd70a5c Christos Stavrakakis
        subnet, gateway, subnet6, gateway6 = validate_network_info(options)
136 6dd70a5c Christos Stavrakakis
137 6dd70a5c Christos Stavrakakis
        if not link:
138 6dd70a5c Christos Stavrakakis
            raise CommandError("Can not create network. No connectivity link")
139 6dd70a5c Christos Stavrakakis
140 6dd70a5c Christos Stavrakakis
        network = Network.objects.create(
141 6dd70a5c Christos Stavrakakis
                name=name,
142 6dd70a5c Christos Stavrakakis
                userid=options['owner'],
143 6dd70a5c Christos Stavrakakis
                subnet=subnet,
144 6dd70a5c Christos Stavrakakis
                gateway=gateway,
145 6dd70a5c Christos Stavrakakis
                dhcp=options['dhcp'],
146 af6a3bc5 Christos Stavrakakis
                type=net_type,
147 7fede91e Christos Stavrakakis
                public=public,
148 6dd70a5c Christos Stavrakakis
                link=link,
149 af6a3bc5 Christos Stavrakakis
                mac_prefix=mac_prefix,
150 6dd70a5c Christos Stavrakakis
                gateway6=gateway6,
151 6dd70a5c Christos Stavrakakis
                subnet6=subnet6,
152 6dd70a5c Christos Stavrakakis
                state='PENDING')
153 6dd70a5c Christos Stavrakakis
154 7fede91e Christos Stavrakakis
        if public:
155 7fede91e Christos Stavrakakis
            # Create BackendNetwork only to the specified Backend
156 7fede91e Christos Stavrakakis
            network.create_backend_network(backend)
157 7fede91e Christos Stavrakakis
            create_network(network, backends=[backend])
158 7fede91e Christos Stavrakakis
        else:
159 7fede91e Christos Stavrakakis
            # Create BackendNetwork entries for all Backends
160 7fede91e Christos Stavrakakis
            network.create_backend_network()
161 7fede91e Christos Stavrakakis
            create_network(network)
162 7cfbbf32 Christos Stavrakakis
163 6dd70a5c Christos Stavrakakis
164 6dd70a5c Christos Stavrakakis
def validate_network_info(options):
165 6dd70a5c Christos Stavrakakis
    subnet = options['subnet']
166 6dd70a5c Christos Stavrakakis
    gateway = options['gateway']
167 6dd70a5c Christos Stavrakakis
    subnet6 = options['subnet6']
168 6dd70a5c Christos Stavrakakis
    gateway6 = options['gateway6']
169 6dd70a5c Christos Stavrakakis
170 6dd70a5c Christos Stavrakakis
    try:
171 b14725eb Christos Stavrakakis
        net = ipaddr.IPv4Network(subnet)
172 b14725eb Christos Stavrakakis
        prefix = net.prefixlen
173 b14725eb Christos Stavrakakis
        if not validate_network_size(prefix):
174 b14725eb Christos Stavrakakis
            raise CommandError("Unsupport network mask %d."
175 b14725eb Christos Stavrakakis
                               " Must be in range (%s,29] "
176 b14725eb Christos Stavrakakis
                               % (prefix, settings.MAX_CIDR_BLOCK))
177 6dd70a5c Christos Stavrakakis
    except ValueError:
178 6dd70a5c Christos Stavrakakis
        raise CommandError('Malformed subnet')
179 6dd70a5c Christos Stavrakakis
    try:
180 6dd70a5c Christos Stavrakakis
        gateway and ipaddr.IPv4Address(gateway) or None
181 6dd70a5c Christos Stavrakakis
    except ValueError:
182 6dd70a5c Christos Stavrakakis
        raise CommandError('Malformed gateway')
183 6dd70a5c Christos Stavrakakis
184 6dd70a5c Christos Stavrakakis
    try:
185 6dd70a5c Christos Stavrakakis
        subnet6 and ipaddr.IPv6Network(subnet6) or None
186 6dd70a5c Christos Stavrakakis
    except ValueError:
187 6dd70a5c Christos Stavrakakis
        raise CommandError('Malformed subnet6')
188 6dd70a5c Christos Stavrakakis
189 6dd70a5c Christos Stavrakakis
    try:
190 6dd70a5c Christos Stavrakakis
        gateway6 and ipaddr.IPv6Address(gateway6) or None
191 6dd70a5c Christos Stavrakakis
    except ValueError:
192 6dd70a5c Christos Stavrakakis
        raise CommandError('Malformed gateway6')
193 6dd70a5c Christos Stavrakakis
194 6dd70a5c Christos Stavrakakis
    return subnet, gateway, subnet6, gateway6