Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / logic / management / commands / network-modify.py @ a6e6fe48

History | View | Annotate | Download (7.6 kB)

1 a6e6fe48 Christos Stavrakakis
# Copyright 2012-2014 GRNET S.A. All rights reserved.
2 8fad925a Giorgos Verigakis
#
3 8fad925a Giorgos Verigakis
# Redistribution and use in source and binary forms, with or
4 8fad925a Giorgos Verigakis
# without modification, are permitted provided that the following
5 8fad925a Giorgos Verigakis
# conditions are met:
6 8fad925a Giorgos Verigakis
#
7 8fad925a Giorgos Verigakis
#   1. Redistributions of source code must retain the above
8 8fad925a Giorgos Verigakis
#      copyright notice, this list of conditions and the following
9 8fad925a Giorgos Verigakis
#      disclaimer.
10 8fad925a Giorgos Verigakis
#
11 8fad925a Giorgos Verigakis
#   2. Redistributions in binary form must reproduce the above
12 8fad925a Giorgos Verigakis
#      copyright notice, this list of conditions and the following
13 8fad925a Giorgos Verigakis
#      disclaimer in the documentation and/or other materials
14 8fad925a Giorgos Verigakis
#      provided with the distribution.
15 8fad925a Giorgos Verigakis
#
16 8fad925a Giorgos Verigakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 8fad925a Giorgos Verigakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 8fad925a Giorgos Verigakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 8fad925a Giorgos Verigakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 8fad925a Giorgos Verigakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 8fad925a Giorgos Verigakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 8fad925a Giorgos Verigakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 8fad925a Giorgos Verigakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 8fad925a Giorgos Verigakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 8fad925a Giorgos Verigakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 8fad925a Giorgos Verigakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 8fad925a Giorgos Verigakis
# POSSIBILITY OF SUCH DAMAGE.
28 8fad925a Giorgos Verigakis
#
29 8fad925a Giorgos Verigakis
# The views and conclusions contained in the software and
30 8fad925a Giorgos Verigakis
# documentation are those of the authors and should not be
31 8fad925a Giorgos Verigakis
# interpreted as representing official policies, either expressed
32 8fad925a Giorgos Verigakis
# or implied, of GRNET S.A.
33 8fad925a Giorgos Verigakis
34 8fad925a Giorgos Verigakis
from optparse import make_option
35 8fad925a Giorgos Verigakis
36 8fad925a Giorgos Verigakis
from django.core.management.base import BaseCommand, CommandError
37 8fad925a Giorgos Verigakis
38 d2036274 Christos Stavrakakis
from synnefo.db.models import Backend
39 a6e6fe48 Christos Stavrakakis
from synnefo.management.common import get_resource
40 d758784b Christos Stavrakakis
from snf_django.management.utils import parse_bool
41 2a2f9ffa Christos Stavrakakis
from synnefo.logic import networks, backend as backend_mod
42 2a2f9ffa Christos Stavrakakis
from django.db import transaction
43 8fad925a Giorgos Verigakis
44 8fad925a Giorgos Verigakis
45 8fad925a Giorgos Verigakis
class Command(BaseCommand):
46 689d7a07 Dionysis Grigoropoulos
    args = "<Network ID>"
47 2a2f9ffa Christos Stavrakakis
    help = "Modify a network."
48 8fad925a Giorgos Verigakis
49 8fad925a Giorgos Verigakis
    option_list = BaseCommand.option_list + (
50 9621c777 Christos Stavrakakis
        make_option(
51 9621c777 Christos Stavrakakis
            '--name',
52 8fad925a Giorgos Verigakis
            dest='name',
53 8fad925a Giorgos Verigakis
            metavar='NAME',
54 2a2f9ffa Christos Stavrakakis
            help="Rename a network"),
55 9621c777 Christos Stavrakakis
        make_option(
56 9621c777 Christos Stavrakakis
            '--userid',
57 53b9ba10 Christos Stavrakakis
            dest='userid',
58 2a2f9ffa Christos Stavrakakis
            help="Change the owner of the network."),
59 9621c777 Christos Stavrakakis
        make_option(
60 2a2f9ffa Christos Stavrakakis
            "--drained",
61 2a2f9ffa Christos Stavrakakis
            dest="drained",
62 052ef3b9 Christos Stavrakakis
            metavar="True|False",
63 052ef3b9 Christos Stavrakakis
            choices=["True", "False"],
64 d193a5c8 Christos Stavrakakis
            help="Set network as drained to prevent creation of new ports."),
65 9621c777 Christos Stavrakakis
        make_option(
66 2a2f9ffa Christos Stavrakakis
            "--floating-ip-pool",
67 2a2f9ffa Christos Stavrakakis
            dest="floating_ip_pool",
68 2a2f9ffa Christos Stavrakakis
            metavar="True|False",
69 2a2f9ffa Christos Stavrakakis
            choices=["True", "False"],
70 2a2f9ffa Christos Stavrakakis
            help="Convert network to a floating IP pool. During this"
71 2a2f9ffa Christos Stavrakakis
                 " conversation the network will be created to all"
72 2a2f9ffa Christos Stavrakakis
                 " available Ganeti backends."),
73 9621c777 Christos Stavrakakis
        make_option(
74 be7c5377 Christos Stavrakakis
            '--add-reserved-ips',
75 be7c5377 Christos Stavrakakis
            dest="add_reserved_ips",
76 be7c5377 Christos Stavrakakis
            help="Comma seperated list of IPs to externally reserve."),
77 be7c5377 Christos Stavrakakis
        make_option(
78 be7c5377 Christos Stavrakakis
            '--remove-reserved-ips',
79 be7c5377 Christos Stavrakakis
            dest="remove_reserved_ips",
80 be7c5377 Christos Stavrakakis
            help="Comma seperated list of IPs to externally release."),
81 be7c5377 Christos Stavrakakis
        make_option(
82 5ec446aa Christos Stavrakakis
            "--add-to-backend",
83 5ec446aa Christos Stavrakakis
            dest="add_to_backend",
84 2a2f9ffa Christos Stavrakakis
            metavar="BACKEND_ID",
85 2a2f9ffa Christos Stavrakakis
            help="Create a network to a Ganeti backend."),
86 5ec446aa Christos Stavrakakis
        make_option(
87 5ec446aa Christos Stavrakakis
            "--remove-from-backend",
88 5ec446aa Christos Stavrakakis
            dest="remove_from_backend",
89 2a2f9ffa Christos Stavrakakis
            metavar="BACKEND_ID",
90 2a2f9ffa Christos Stavrakakis
            help="Remove a network from a Ganeti backend."),
91 8fad925a Giorgos Verigakis
    )
92 8fad925a Giorgos Verigakis
93 2a2f9ffa Christos Stavrakakis
    @transaction.commit_on_success
94 8fad925a Giorgos Verigakis
    def handle(self, *args, **options):
95 8fad925a Giorgos Verigakis
        if len(args) != 1:
96 c2d969cb Christos Stavrakakis
            raise CommandError("Please provide a network ID")
97 8fad925a Giorgos Verigakis
98 a6e6fe48 Christos Stavrakakis
        network = get_resource("network", args[0])
99 8fad925a Giorgos Verigakis
100 2a2f9ffa Christos Stavrakakis
        new_name = options.get("name")
101 2a2f9ffa Christos Stavrakakis
        if new_name is not None:
102 2a2f9ffa Christos Stavrakakis
            old_name = network.name
103 2a2f9ffa Christos Stavrakakis
            network = networks.rename(network, new_name)
104 2a2f9ffa Christos Stavrakakis
            self.stdout.write("Renamed network '%s' from '%s' to '%s'.\n" %
105 2a2f9ffa Christos Stavrakakis
                              (network, old_name, new_name))
106 bf1d3a70 Christos Stavrakakis
107 2a2f9ffa Christos Stavrakakis
        drained = options.get("drained")
108 2a2f9ffa Christos Stavrakakis
        if drained is not None:
109 2a2f9ffa Christos Stavrakakis
            drained = parse_bool(drained)
110 2a2f9ffa Christos Stavrakakis
            network.drained = drained
111 2a2f9ffa Christos Stavrakakis
            network.save()
112 2a2f9ffa Christos Stavrakakis
            self.stdout.write("Set network '%s' as drained=%s.\n" %
113 2a2f9ffa Christos Stavrakakis
                              (network, drained))
114 2a2f9ffa Christos Stavrakakis
115 2a2f9ffa Christos Stavrakakis
        new_owner = options.get("userid")
116 2a2f9ffa Christos Stavrakakis
        if new_owner is not None:
117 2a2f9ffa Christos Stavrakakis
            if "@" in new_owner:
118 2a2f9ffa Christos Stavrakakis
                raise CommandError("Invalid owner UUID.")
119 2a2f9ffa Christos Stavrakakis
            old_owner = network.userid
120 2a2f9ffa Christos Stavrakakis
            network.userid = new_owner
121 2a2f9ffa Christos Stavrakakis
            network.save()
122 2a2f9ffa Christos Stavrakakis
            msg = "Changed the owner of network '%s' from '%s' to '%s'.\n"
123 2a2f9ffa Christos Stavrakakis
            self.stdout.write(msg % (network, old_owner, new_owner))
124 53b9ba10 Christos Stavrakakis
125 5e5b2476 Christos Stavrakakis
        floating_ip_pool = options["floating_ip_pool"]
126 b47f167a Christos Stavrakakis
        if floating_ip_pool is not None:
127 b47f167a Christos Stavrakakis
            floating_ip_pool = parse_bool(floating_ip_pool)
128 2a2f9ffa Christos Stavrakakis
            if floating_ip_pool is False and network.floating_ip_pool is True:
129 d2036274 Christos Stavrakakis
                if network.ips.filter(deleted=False, floating_ip=True)\
130 d2036274 Christos Stavrakakis
                              .exists():
131 8d5795b4 Christos Stavrakakis
                    msg = ("Cannot make network a non floating IP pool."
132 2a2f9ffa Christos Stavrakakis
                           " There are still reserved floating IPs.")
133 2a2f9ffa Christos Stavrakakis
                    raise CommandError(msg)
134 2a2f9ffa Christos Stavrakakis
            network.floating_ip_pool = floating_ip_pool
135 2a2f9ffa Christos Stavrakakis
            network.save()
136 2a2f9ffa Christos Stavrakakis
            self.stdout.write("Set network '%s' as floating-ip-pool=%s.\n" %
137 2a2f9ffa Christos Stavrakakis
                              (network, floating_ip_pool))
138 2a2f9ffa Christos Stavrakakis
            if floating_ip_pool is True:
139 2a2f9ffa Christos Stavrakakis
                for backend in Backend.objects.filter(offline=False):
140 d2036274 Christos Stavrakakis
                    bnet, jobs =\
141 d2036274 Christos Stavrakakis
                        backend_mod.ensure_network_is_active(backend,
142 d2036274 Christos Stavrakakis
                                                             network.id)
143 d2036274 Christos Stavrakakis
                    if jobs:
144 2a2f9ffa Christos Stavrakakis
                        msg = ("Sent job to create network '%s' in backend"
145 2a2f9ffa Christos Stavrakakis
                               " '%s'\n" % (network, backend))
146 2a2f9ffa Christos Stavrakakis
                        self.stdout.write(msg)
147 449c2d82 Christos Stavrakakis
148 be7c5377 Christos Stavrakakis
        add_reserved_ips = options.get('add_reserved_ips')
149 be7c5377 Christos Stavrakakis
        remove_reserved_ips = options.get('remove_reserved_ips')
150 be7c5377 Christos Stavrakakis
        if add_reserved_ips or remove_reserved_ips:
151 be7c5377 Christos Stavrakakis
            if add_reserved_ips:
152 be7c5377 Christos Stavrakakis
                add_reserved_ips = add_reserved_ips.split(",")
153 be7c5377 Christos Stavrakakis
                for ip in add_reserved_ips:
154 be7c5377 Christos Stavrakakis
                    network.reserve_address(ip, external=True)
155 be7c5377 Christos Stavrakakis
            if remove_reserved_ips:
156 be7c5377 Christos Stavrakakis
                remove_reserved_ips = remove_reserved_ips.split(",")
157 be7c5377 Christos Stavrakakis
                for ip in remove_reserved_ips:
158 be7c5377 Christos Stavrakakis
                    network.release_address(ip, external=True)
159 be7c5377 Christos Stavrakakis
160 5ec446aa Christos Stavrakakis
        add_to_backend = options["add_to_backend"]
161 5ec446aa Christos Stavrakakis
        if add_to_backend is not None:
162 a6e6fe48 Christos Stavrakakis
            backend = get_resource("backend", add_to_backend)
163 d2036274 Christos Stavrakakis
            bnet, jobs = backend_mod.ensure_network_is_active(backend,
164 d2036274 Christos Stavrakakis
                                                              network.id)
165 d2036274 Christos Stavrakakis
            if jobs:
166 d2036274 Christos Stavrakakis
                msg = "Sent job to create network '%s' in backend '%s'\n"
167 d2036274 Christos Stavrakakis
                self.stdout.write(msg % (network, backend))
168 5ec446aa Christos Stavrakakis
169 5ec446aa Christos Stavrakakis
        remove_from_backend = options["remove_from_backend"]
170 5ec446aa Christos Stavrakakis
        if remove_from_backend is not None:
171 a6e6fe48 Christos Stavrakakis
            backend = get_resource("backend", remove_from_backend)
172 5ec446aa Christos Stavrakakis
            if network.nics.filter(machine__backend=backend,
173 5ec446aa Christos Stavrakakis
                                   machine__deleted=False).exists():
174 8d5795b4 Christos Stavrakakis
                msg = "Cannot remove. There are still connected VMs to this"\
175 5ec446aa Christos Stavrakakis
                      " network"
176 5ec446aa Christos Stavrakakis
                raise CommandError(msg)
177 2a2f9ffa Christos Stavrakakis
            backend_mod.delete_network(network, backend, disconnect=True)
178 5ec446aa Christos Stavrakakis
            msg = "Sent job to delete network '%s' from backend '%s'\n"
179 5ec446aa Christos Stavrakakis
            self.stdout.write(msg % (network, backend))