Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (7.1 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 validate_network_info, get_backend
38
from synnefo.webproject.management.utils import pprint_table
39

    
40
from synnefo.db.models import Network
41
from synnefo.logic.backend import create_network
42
from synnefo.api.util import values_from_flavor
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
            "-n",
56
            "--dry-run",
57
            dest="dry_run",
58
            default=False,
59
            action="store_true"),
60
        make_option(
61
            '--name',
62
            dest='name',
63
            help="Name of network"),
64
        make_option(
65
            '--owner',
66
            dest='owner',
67
            help="The owner of the network"),
68
        make_option(
69
            '--subnet',
70
            dest='subnet',
71
            default=None,
72
            # required=True,
73
            help='Subnet of the network'),
74
        make_option(
75
            '--gateway',
76
            dest='gateway',
77
            default=None,
78
            help='Gateway of the network'),
79
        make_option(
80
            '--subnet6',
81
            dest='subnet6',
82
            default=None,
83
            help='IPv6 subnet of the network'),
84
        make_option(
85
            '--gateway6',
86
            dest='gateway6',
87
            default=None,
88
            help='IPv6 gateway of the network'),
89
        make_option(
90
            '--dhcp',
91
            dest='dhcp',
92
            action='store_true',
93
            default=False,
94
            help='Automatically assign IPs'),
95
        make_option(
96
            '--public',
97
            dest='public',
98
            action='store_true',
99
            default=False,
100
            help='Network is public'),
101
        make_option(
102
            '--flavor',
103
            dest='flavor',
104
            default=None,
105
            choices=NETWORK_FLAVORS,
106
            help='Network flavor. Choices: ' + ', '.join(NETWORK_FLAVORS)),
107
        make_option(
108
            '--mode',
109
            dest='mode',
110
            default=None,
111
            help="Overwrite flavor connectivity mode."),
112
        make_option(
113
            '--link',
114
            dest='link',
115
            default=None,
116
            help="Overwrite flavor connectivity link."),
117
        make_option(
118
            '--mac-prefix',
119
            dest='mac_prefix',
120
            default=None,
121
            help="Overwrite flavor connectivity MAC prefix"),
122
        make_option(
123
            '--tags',
124
            dest='tags',
125
            default=None,
126
            help='The tags of the Network (comma separated strings)'),
127
        make_option(
128
            '--backend-id',
129
            dest='backend_id',
130
            default=None,
131
            help='ID of the backend that the network will be created. Only for'
132
                 ' public networks'),
133
    )
134

    
135
    def handle(self, *args, **options):
136
        if args:
137
            raise CommandError("Command doesn't accept any arguments")
138

    
139
        dry_run = options["dry_run"]
140
        name = options['name']
141
        subnet = options['subnet']
142
        backend_id = options['backend_id']
143
        public = options['public']
144
        flavor = options['flavor']
145
        mode = options['mode']
146
        link = options['link']
147
        mac_prefix = options['mac_prefix']
148
        tags = options['tags']
149
        userid = options["owner"]
150

    
151
        if not name:
152
            raise CommandError("Name is required")
153
        if not subnet:
154
            raise CommandError("Subnet is required")
155
        if not flavor:
156
            raise CommandError("Flavor is required")
157
        if public and not backend_id:
158
            raise CommandError("backend-id is required")
159
        if not userid and not public:
160
            raise CommandError("'owner' is required for private networks")
161

    
162
        if mac_prefix and flavor == "MAC_FILTERED":
163
            raise CommandError("Can not override MAC_FILTERED mac-prefix")
164
        if link and flavor == "PHYSICAL_VLAN":
165
            raise CommandError("Can not override PHYSICAL_VLAN link")
166

    
167
        if backend_id:
168
            backend = get_backend(backend_id)
169

    
170
        fmode, flink, fmac_prefix, ftags = values_from_flavor(flavor)
171
        mode = mode or fmode
172
        link = link or flink
173
        mac_prefix = mac_prefix or fmac_prefix
174
        tags = tags or ftags
175

    
176
        subnet, gateway, subnet6, gateway6 = validate_network_info(options)
177

    
178
        if not link or not mode:
179
            raise CommandError("Can not create network."
180
                               " No connectivity link or mode")
181
        netinfo = {
182
           "name": name,
183
           "userid": options["owner"],
184
           "subnet": subnet,
185
           "gateway": gateway,
186
           "gateway6": gateway6,
187
           "subnet6": subnet6,
188
           "dhcp": options["dhcp"],
189
           "flavor": flavor,
190
           "public": public,
191
           "mode": mode,
192
           "link": link,
193
           "mac_prefix": mac_prefix,
194
           "tags": tags,
195
           "state": "PENDING"}
196

    
197
        if dry_run:
198
            self.stdout.write("Creating network:\n")
199
            pprint_table(self.stdout, tuple(netinfo.items()))
200
            return
201

    
202
        network = Network.objects.create(**netinfo)
203

    
204
        if public:
205
            # Create BackendNetwork only to the specified Backend
206
            network.create_backend_network(backend)
207
            create_network(network, backends=[backend])
208
        else:
209
            # Create BackendNetwork entries for all Backends
210
            network.create_backend_network()
211
            create_network(network)