Revision 5e5b2476

b/snf-cyclades-app/synnefo/api/management/commands/network-modify.py
31 31
# interpreted as representing official policies, either expressed
32 32
# or implied, of GRNET S.A.
33 33

  
34
import re
34 35
from optparse import make_option
35 36

  
36 37
from django.core.management.base import BaseCommand, CommandError
37 38

  
38
from synnefo.db.models import Network, pooled_rapi_client
39
from synnefo.db.models import (Network, Backend, BackendNetwork,
40
                               pooled_rapi_client)
39 41
from synnefo.management.common import (validate_network_info, get_network,
40 42
                                       get_backend)
41 43
from synnefo.webproject.management.utils import parse_bool
......
126 128
            "--remove-from-backend",
127 129
            dest="remove_from_backend",
128 130
            help="Remove a public network from a Ganeti backend."),
131
        make_option(
132
            "--floating-ip-pool",
133
            dest="floating_ip_pool",
134
            metavar="True|False",
135
            choices=["True", "False"],
136
            help="Convert network to a floating IP pool. During this"
137
                 " conversation the network will be created to all"
138
                 " available Ganeti backends."),
129 139
    )
130 140

  
131 141
    def handle(self, *args, **options):
......
146 156
                msg = "Invalid state, must be one of %s" % ', '.join(allowed)
147 157
                raise CommandError(msg)
148 158

  
159
        floating_ip_pool = options["floating_ip_pool"]
160
        if floating_ip_pool is False and network.floating_ip_pool is True:
161
            if network.floating_ips.filter(deleted=False).exists():
162
                msg = "Can not make network a non floating IP pool. There are"\
163
                      " still reserved floating IPs."
164
                raise CommandError(msg)
165
        elif floating_ip_pool is True:
166
            for backend in Backend.objects.filter(offline=False):
167
                check_link_availability(backend, network)
168

  
149 169
        dhcp = options.get("dhcp")
150 170
        if dhcp:
151 171
            options["dhcp"] = parse_bool(dhcp)
......
153 173
        if drained:
154 174
            options["drained"] = parse_bool(drained)
155 175
        fields = ('name', 'userid', 'subnet', 'gateway', 'subnet6', 'gateway6',
156
                  'dhcp', 'state', 'link', 'mac_prefix', 'drained')
176
                  'dhcp', 'state', 'link', 'mac_prefix', 'drained',
177
                  'floating_ip_pool')
157 178
        for field in fields:
158 179
            value = options.get(field, None)
159 180
            if value is not None:
......
175 196
                                    add_reserved_ips=add_reserved_ips,
176 197
                                    remove_reserved_ips=remove_reserved_ips)
177 198

  
199
        if floating_ip_pool is True:
200
            for backend in Backend.objects.filter(offline=False):
201
                try:
202
                    bnet = network.backend_networks.get(backend=backend)
203
                except BackendNetwork.DoesNotExist:
204
                    bnet = network.create_backend_network(backend=backend)
205
                if bnet.operstate != "ACTVE":
206
                    create_network(network, backend, connect=True)
207
                    msg = "Sent job to create network '%s' in backend '%s'\n"
208
                    self.stdout.write(msg % (network, backend))
209

  
178 210
        add_to_backend = options["add_to_backend"]
179 211
        if add_to_backend is not None:
180 212
            backend = get_backend(add_to_backend)
......
196 228
            delete_network(network, backend, disconnect=True)
197 229
            msg = "Sent job to delete network '%s' from backend '%s'\n"
198 230
            self.stdout.write(msg % (network, backend))
231

  
232

  
233
def check_link_availability(backend, network):
234
    """Check if network link is available in backend."""
235
    with pooled_rapi_client(backend) as c:
236
        ganeti_networks = c.GetNetworks(bulk=True)
237
    name = network.backend_id
238
    mode = network.mode
239
    link = network.link
240
    for gnet in ganeti_networks:
241
        if gnet["name"] != name and\
242
           re.search("(%s, %s)" % (mode, link), gnet["group_list"]):
243
            msg = "Can not create network '%s' in backend '%s'. Link '%s'" \
244
                  " is already used by network '%s" % \
245
                  (network, backend, gnet["name"])
246
            raise CommandError(msg)

Also available in: Unified diff