Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (6.9 kB)

1
# Copyright 2012 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
from optparse import make_option
35

    
36
from django.core.management.base import BaseCommand, CommandError
37
from synnefo.management.common import convert_api_faults
38
from snf_django.management.utils import parse_bool
39

    
40
from synnefo.db.models import Network
41
from synnefo.logic import networks, subnets
42
from synnefo.management import pprint
43

    
44
NETWORK_FLAVORS = Network.FLAVORS.keys()
45

    
46

    
47
class Command(BaseCommand):
48
    can_import_settings = True
49
    output_transaction = True
50

    
51
    help = "Create a new network"
52

    
53
    option_list = BaseCommand.option_list + (
54
        make_option(
55
            '--name',
56
            dest='name',
57
            help="Name of the network"),
58
        make_option(
59
            '--owner',
60
            dest='owner',
61
            help="The owner of the network"),
62
        make_option(
63
            '--subnet',
64
            dest='subnet',
65
            default=None,
66
            # required=True,
67
            help='IPv4 subnet of the network'),
68
        make_option(
69
            '--gateway',
70
            dest='gateway',
71
            default=None,
72
            help='IPv4 gateway of the network'),
73
        make_option(
74
            '--subnet6',
75
            dest='subnet6',
76
            default=None,
77
            help='IPv6 subnet of the network'),
78
        make_option(
79
            '--gateway6',
80
            dest='gateway6',
81
            default=None,
82
            help='IPv6 gateway of the network'),
83
        make_option(
84
            '--dhcp',
85
            dest='dhcp',
86
            default="True",
87
            choices=["True", "False"],
88
            metavar="True|False",
89
            help='Automatically assign IPs'),
90
        make_option(
91
            '--public',
92
            dest='public',
93
            action='store_true',
94
            default=False,
95
            help='Network is public'),
96
        make_option(
97
            '--flavor',
98
            dest='flavor',
99
            default=None,
100
            choices=NETWORK_FLAVORS,
101
            help='Network flavor. Choices: ' + ', '.join(NETWORK_FLAVORS)),
102
        make_option(
103
            '--mode',
104
            dest='mode',
105
            default=None,
106
            help="Overwrite flavor connectivity mode."),
107
        make_option(
108
            '--link',
109
            dest='link',
110
            default=None,
111
            help="Overwrite flavor connectivity link."),
112
        make_option(
113
            '--mac-prefix',
114
            dest='mac_prefix',
115
            default=None,
116
            help="Overwrite flavor connectivity MAC prefix"),
117
        make_option(
118
            '--tags',
119
            dest='tags',
120
            default=None,
121
            help='The tags of the Network (comma separated strings)'),
122
        make_option(
123
            '--floating-ip-pool',
124
            dest='floating_ip_pool',
125
            default="False",
126
            choices=["True", "False"],
127
            metavar="True|False",
128
            help="Use the network as a Floating IP pool."),
129
    )
130

    
131
    @convert_api_faults
132
    def handle(self, *args, **options):
133
        if args:
134
            raise CommandError("Command doesn't accept any arguments")
135

    
136
        name = options['name']
137
        subnet = options['subnet']
138
        gateway = options['gateway']
139
        subnet6 = options['subnet6']
140
        gateway6 = options['gateway6']
141
        public = options['public']
142
        flavor = options['flavor']
143
        mode = options['mode']
144
        link = options['link']
145
        mac_prefix = options['mac_prefix']
146
        tags = options['tags']
147
        userid = options["owner"]
148
        floating_ip_pool = parse_bool(options["floating_ip_pool"])
149
        dhcp = parse_bool(options["dhcp"])
150

    
151
        if name is None:
152
            name = ""
153
        if flavor is None:
154
            raise CommandError("flavor is required")
155

    
156
        if (subnet is None) and (subnet6 is None):
157
            raise CommandError("subnet or subnet6 is required")
158

    
159
        if subnet is None and gateway is not None:
160
            raise CommandError("Cannot use gateway without subnet")
161
        if subnet6 is None and gateway6 is not None:
162
            raise CommandError("Cannot use gateway6 without subnet6")
163

    
164
        if not (userid or public):
165
            raise CommandError("'owner' is required for private networks")
166

    
167
        network = networks.create(userid=userid, name=name, flavor=flavor,
168
                                  public=public, mode=mode,
169
                                  link=link, mac_prefix=mac_prefix, tags=tags,
170
                                  floating_ip_pool=floating_ip_pool)
171

    
172
        if subnet is not None:
173
            name = "IPv4 Subnet of Network %s" % network.id
174
            subnets.create_subnet(network.id, cidr=subnet, name=name,
175
                                  ipversion=4, gateway=gateway, dhcp=dhcp,
176
                                  user_id=userid)
177

    
178
        if subnet6 is not None:
179
            name = "IPv6 Subnet of Network %s" % network.id
180
            subnets.create_subnet(network.id, cidr=subnet6, name=name,
181
                                  ipversion=6, gateway=gateway6,
182
                                  dhcp=dhcp, user_id=userid)
183

    
184
        self.stdout.write("Created network '%s' in DB:\n" % network)
185
        pprint.pprint_network(network, stdout=self.stdout)
186
        pprint.pprint_network_subnets(network, stdout=self.stdout)
187

    
188
        networks.create_network_in_backends(network)
189
        # TODO: Add --wait option to track job progress and report successful
190
        # creation in each backend.
191
        self.stdout.write("\nSuccessfully issued job to create network in"
192
                          " in backends\n")