Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / logic / management / commands / network-create.py @ 6fec4302

History | View | Annotate | Download (8.5 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 8c911970 Christos Stavrakakis
from django.core.management.base import CommandError
37 8c911970 Christos Stavrakakis
from snf_django.management.commands import SynnefoCommand
38 7b5263e4 Christos Stavrakakis
from synnefo.management.common import convert_api_faults
39 d758784b Christos Stavrakakis
from snf_django.management.utils import parse_bool
40 6dd70a5c Christos Stavrakakis
41 7b5263e4 Christos Stavrakakis
from synnefo.db.models import Network
42 3785b737 Dionysis Grigoropoulos
from synnefo.logic import networks, subnets
43 d5a4a8d1 Christos Stavrakakis
from synnefo.management import pprint
44 b84ed662 Christos Stavrakakis
45 0d1f9117 Dionysis Grigoropoulos
import ipaddr
46 0d1f9117 Dionysis Grigoropoulos
47 b7d38981 Dimitris Aragiorgis
NETWORK_FLAVORS = Network.FLAVORS.keys()
48 6dd70a5c Christos Stavrakakis
49 6dd70a5c Christos Stavrakakis
50 8c911970 Christos Stavrakakis
class Command(SynnefoCommand):
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 8c911970 Christos Stavrakakis
    option_list = SynnefoCommand.option_list + (
57 9621c777 Christos Stavrakakis
        make_option(
58 9621c777 Christos Stavrakakis
            '--name',
59 6dd70a5c Christos Stavrakakis
            dest='name',
60 3785b737 Dionysis Grigoropoulos
            help="Name of the network"),
61 3785b737 Dionysis Grigoropoulos
        make_option(
62 9621c777 Christos Stavrakakis
            '--owner',
63 6dd70a5c Christos Stavrakakis
            dest='owner',
64 6dd70a5c Christos Stavrakakis
            help="The owner of the network"),
65 9621c777 Christos Stavrakakis
        make_option(
66 9621c777 Christos Stavrakakis
            '--subnet',
67 6dd70a5c Christos Stavrakakis
            dest='subnet',
68 6dd70a5c Christos Stavrakakis
            default=None,
69 6dd70a5c Christos Stavrakakis
            # required=True,
70 3785b737 Dionysis Grigoropoulos
            help='IPv4 subnet of the network'),
71 9621c777 Christos Stavrakakis
        make_option(
72 9621c777 Christos Stavrakakis
            '--gateway',
73 6dd70a5c Christos Stavrakakis
            dest='gateway',
74 6dd70a5c Christos Stavrakakis
            default=None,
75 3785b737 Dionysis Grigoropoulos
            help='IPv4 gateway of the network'),
76 9621c777 Christos Stavrakakis
        make_option(
77 9621c777 Christos Stavrakakis
            '--subnet6',
78 b7d38981 Dimitris Aragiorgis
            dest='subnet6',
79 b7d38981 Dimitris Aragiorgis
            default=None,
80 b7d38981 Dimitris Aragiorgis
            help='IPv6 subnet of the network'),
81 9621c777 Christos Stavrakakis
        make_option(
82 9621c777 Christos Stavrakakis
            '--gateway6',
83 b7d38981 Dimitris Aragiorgis
            dest='gateway6',
84 b7d38981 Dimitris Aragiorgis
            default=None,
85 b7d38981 Dimitris Aragiorgis
            help='IPv6 gateway of the network'),
86 9621c777 Christos Stavrakakis
        make_option(
87 9621c777 Christos Stavrakakis
            '--dhcp',
88 6dd70a5c Christos Stavrakakis
            dest='dhcp',
89 ac17f307 Christos Stavrakakis
            default="False",
90 c75ab92e Christos Stavrakakis
            choices=["True", "False"],
91 c75ab92e Christos Stavrakakis
            metavar="True|False",
92 6dd70a5c Christos Stavrakakis
            help='Automatically assign IPs'),
93 9621c777 Christos Stavrakakis
        make_option(
94 9621c777 Christos Stavrakakis
            '--public',
95 6dd70a5c Christos Stavrakakis
            dest='public',
96 6dd70a5c Christos Stavrakakis
            action='store_true',
97 6dd70a5c Christos Stavrakakis
            default=False,
98 6dd70a5c Christos Stavrakakis
            help='Network is public'),
99 9621c777 Christos Stavrakakis
        make_option(
100 9621c777 Christos Stavrakakis
            '--flavor',
101 b7d38981 Dimitris Aragiorgis
            dest='flavor',
102 6dd70a5c Christos Stavrakakis
            default=None,
103 b7d38981 Dimitris Aragiorgis
            choices=NETWORK_FLAVORS,
104 b7d38981 Dimitris Aragiorgis
            help='Network flavor. Choices: ' + ', '.join(NETWORK_FLAVORS)),
105 9621c777 Christos Stavrakakis
        make_option(
106 9621c777 Christos Stavrakakis
            '--mode',
107 b7d38981 Dimitris Aragiorgis
            dest='mode',
108 7fede91e Christos Stavrakakis
            default=None,
109 b7d38981 Dimitris Aragiorgis
            help="Overwrite flavor connectivity mode."),
110 9621c777 Christos Stavrakakis
        make_option(
111 9621c777 Christos Stavrakakis
            '--link',
112 71ec054d Christos Stavrakakis
            dest='link',
113 71ec054d Christos Stavrakakis
            default=None,
114 b7d38981 Dimitris Aragiorgis
            help="Overwrite flavor connectivity link."),
115 9621c777 Christos Stavrakakis
        make_option(
116 9621c777 Christos Stavrakakis
            '--mac-prefix',
117 71ec054d Christos Stavrakakis
            dest='mac_prefix',
118 71ec054d Christos Stavrakakis
            default=None,
119 b7d38981 Dimitris Aragiorgis
            help="Overwrite flavor connectivity MAC prefix"),
120 9621c777 Christos Stavrakakis
        make_option(
121 9621c777 Christos Stavrakakis
            '--tags',
122 b7d38981 Dimitris Aragiorgis
            dest='tags',
123 b7d38981 Dimitris Aragiorgis
            default=None,
124 b7d38981 Dimitris Aragiorgis
            help='The tags of the Network (comma separated strings)'),
125 9621c777 Christos Stavrakakis
        make_option(
126 64cdd31b Christos Stavrakakis
            '--floating-ip-pool',
127 64cdd31b Christos Stavrakakis
            dest='floating_ip_pool',
128 64cdd31b Christos Stavrakakis
            default="False",
129 64cdd31b Christos Stavrakakis
            choices=["True", "False"],
130 64cdd31b Christos Stavrakakis
            metavar="True|False",
131 7b5263e4 Christos Stavrakakis
            help="Use the network as a Floating IP pool."),
132 0d1f9117 Dionysis Grigoropoulos
        make_option(
133 046c8f11 Christos Stavrakakis
            '--allocation-pool',
134 0d1f9117 Dionysis Grigoropoulos
            dest='allocation_pools',
135 0d1f9117 Dionysis Grigoropoulos
            action='append',
136 0d1f9117 Dionysis Grigoropoulos
            help="IP allocation pools to be used for assigning IPs to"
137 0d1f9117 Dionysis Grigoropoulos
                 " VMs. Can be used multiple times. Syntax: \n"
138 0d1f9117 Dionysis Grigoropoulos
                 "192.168.42.220,192.168.42.240. Starting IP must proceed "
139 44bd008a Dionysis Grigoropoulos
                 "ending IP. If no allocation pools are given, the whole "
140 44bd008a Dionysis Grigoropoulos
                 "subnet range is used, excluding the gateway IP, the "
141 44bd008a Dionysis Grigoropoulos
                 "broadcast address and the network address"),
142 d193a5c8 Christos Stavrakakis
        make_option(
143 d193a5c8 Christos Stavrakakis
            "--drained",
144 d193a5c8 Christos Stavrakakis
            dest="drained",
145 d193a5c8 Christos Stavrakakis
            metavar="True|False",
146 d193a5c8 Christos Stavrakakis
            choices=["True", "False"],
147 d193a5c8 Christos Stavrakakis
            default="False",
148 d193a5c8 Christos Stavrakakis
            help="Set network as drained to prevent creation of new ports."),
149 9621c777 Christos Stavrakakis
    )
150 6dd70a5c Christos Stavrakakis
151 c75ab92e Christos Stavrakakis
    @convert_api_faults
152 6dd70a5c Christos Stavrakakis
    def handle(self, *args, **options):
153 6dd70a5c Christos Stavrakakis
        if args:
154 6dd70a5c Christos Stavrakakis
            raise CommandError("Command doesn't accept any arguments")
155 6dd70a5c Christos Stavrakakis
156 6dd70a5c Christos Stavrakakis
        name = options['name']
157 6dd70a5c Christos Stavrakakis
        subnet = options['subnet']
158 5aeb4e93 Christos Stavrakakis
        gateway = options['gateway']
159 5aeb4e93 Christos Stavrakakis
        subnet6 = options['subnet6']
160 5aeb4e93 Christos Stavrakakis
        gateway6 = options['gateway6']
161 7fede91e Christos Stavrakakis
        public = options['public']
162 b7d38981 Dimitris Aragiorgis
        flavor = options['flavor']
163 b7d38981 Dimitris Aragiorgis
        mode = options['mode']
164 71ec054d Christos Stavrakakis
        link = options['link']
165 71ec054d Christos Stavrakakis
        mac_prefix = options['mac_prefix']
166 b7d38981 Dimitris Aragiorgis
        tags = options['tags']
167 eefb7355 Christos Stavrakakis
        userid = options["owner"]
168 0d1f9117 Dionysis Grigoropoulos
        allocation_pools = options["allocation_pools"]
169 64cdd31b Christos Stavrakakis
        floating_ip_pool = parse_bool(options["floating_ip_pool"])
170 c75ab92e Christos Stavrakakis
        dhcp = parse_bool(options["dhcp"])
171 d193a5c8 Christos Stavrakakis
        drained = parse_bool(options["drained"])
172 6dd70a5c Christos Stavrakakis
173 be7c5377 Christos Stavrakakis
        if name is None:
174 be7c5377 Christos Stavrakakis
            name = ""
175 be7c5377 Christos Stavrakakis
        if flavor is None:
176 5aeb4e93 Christos Stavrakakis
            raise CommandError("flavor is required")
177 5aeb4e93 Christos Stavrakakis
178 28ac6e86 Dionysis Grigoropoulos
        if ((subnet is None) and (subnet6 is None)) and dhcp is not False:
179 28ac6e86 Dionysis Grigoropoulos
            raise CommandError("Cannot set DHCP without subnet or subnet6")
180 7b5263e4 Christos Stavrakakis
181 5aeb4e93 Christos Stavrakakis
        if subnet is None and gateway is not None:
182 8d5795b4 Christos Stavrakakis
            raise CommandError("Cannot use gateway without subnet")
183 0d1f9117 Dionysis Grigoropoulos
        if subnet is None and allocation_pools is not None:
184 0d1f9117 Dionysis Grigoropoulos
            raise CommandError("Cannot use allocation-pools without subnet")
185 5aeb4e93 Christos Stavrakakis
        if subnet6 is None and gateway6 is not None:
186 8d5795b4 Christos Stavrakakis
            raise CommandError("Cannot use gateway6 without subnet6")
187 dce3fc8b Christos Stavrakakis
        if flavor == "IP_LESS_ROUTED" and not (subnet or subnet6):
188 dce3fc8b Christos Stavrakakis
            raise CommandError("Cannot create 'IP_LESS_ROUTED' network without"
189 dce3fc8b Christos Stavrakakis
                               " subnet")
190 7fede91e Christos Stavrakakis
191 7b5263e4 Christos Stavrakakis
        if not (userid or public):
192 7b5263e4 Christos Stavrakakis
            raise CommandError("'owner' is required for private networks")
193 6dd70a5c Christos Stavrakakis
194 e08afd0b Christos Stavrakakis
        network = networks.create(userid=userid, name=name, flavor=flavor,
195 3785b737 Dionysis Grigoropoulos
                                  public=public, mode=mode,
196 c75ab92e Christos Stavrakakis
                                  link=link, mac_prefix=mac_prefix, tags=tags,
197 d193a5c8 Christos Stavrakakis
                                  floating_ip_pool=floating_ip_pool,
198 d193a5c8 Christos Stavrakakis
                                  drained=drained)
199 b47f167a Christos Stavrakakis
200 7b5263e4 Christos Stavrakakis
        if subnet is not None:
201 44bd008a Dionysis Grigoropoulos
            alloc = None
202 44bd008a Dionysis Grigoropoulos
            if allocation_pools is not None:
203 44bd008a Dionysis Grigoropoulos
                alloc = subnets.parse_allocation_pools(allocation_pools)
204 44bd008a Dionysis Grigoropoulos
                alloc.sort()
205 7b5263e4 Christos Stavrakakis
            name = "IPv4 Subnet of Network %s" % network.id
206 7b5263e4 Christos Stavrakakis
            subnets.create_subnet(network.id, cidr=subnet, name=name,
207 7b5263e4 Christos Stavrakakis
                                  ipversion=4, gateway=gateway, dhcp=dhcp,
208 0d1f9117 Dionysis Grigoropoulos
                                  user_id=userid,
209 44bd008a Dionysis Grigoropoulos
                                  allocation_pools=alloc)
210 3785b737 Dionysis Grigoropoulos
211 7b5263e4 Christos Stavrakakis
        if subnet6 is not None:
212 7b5263e4 Christos Stavrakakis
            name = "IPv6 Subnet of Network %s" % network.id
213 7b5263e4 Christos Stavrakakis
            subnets.create_subnet(network.id, cidr=subnet6, name=name,
214 7b5263e4 Christos Stavrakakis
                                  ipversion=6, gateway=gateway6,
215 7b5263e4 Christos Stavrakakis
                                  dhcp=dhcp, user_id=userid)
216 3785b737 Dionysis Grigoropoulos
217 d5a4a8d1 Christos Stavrakakis
        self.stdout.write("Created network '%s' in DB:\n" % network)
218 d5a4a8d1 Christos Stavrakakis
        pprint.pprint_network(network, stdout=self.stdout)
219 d5a4a8d1 Christos Stavrakakis
        pprint.pprint_network_subnets(network, stdout=self.stdout)
220 7b5263e4 Christos Stavrakakis
221 7b5263e4 Christos Stavrakakis
        networks.create_network_in_backends(network)
222 7b5263e4 Christos Stavrakakis
        # TODO: Add --wait option to track job progress and report successful
223 7b5263e4 Christos Stavrakakis
        # creation in each backend.
224 7b5263e4 Christos Stavrakakis
        self.stdout.write("\nSuccessfully issued job to create network in"
225 1709a768 Dionysis Grigoropoulos
                          " backends\n")