root / snf-cyclades-app / synnefo / logic / management / commands / reconcile-networks.py @ c346aed0
History | View | Annotate | Download (11.9 kB)
1 | 0e9a423f | Christos Stavrakakis | # Copyright 2011-2012 GRNET S.A. All rights reserved.
|
---|---|---|---|
2 | 0e9a423f | Christos Stavrakakis | #
|
3 | 0e9a423f | Christos Stavrakakis | # Redistribution and use in source and binary forms, with or without
|
4 | 0e9a423f | Christos Stavrakakis | # modification, are permitted provided that the following conditions
|
5 | 0e9a423f | Christos Stavrakakis | # are met:
|
6 | 0e9a423f | Christos Stavrakakis | #
|
7 | 0e9a423f | Christos Stavrakakis | # 1. Redistributions of source code must retain the above copyright
|
8 | 0e9a423f | Christos Stavrakakis | # notice, this list of conditions and the following disclaimer.
|
9 | 0e9a423f | Christos Stavrakakis | #
|
10 | 0e9a423f | Christos Stavrakakis | # 2. Redistributions in binary form must reproduce the above copyright
|
11 | 0e9a423f | Christos Stavrakakis | # notice, this list of conditions and the following disclaimer in the
|
12 | 0e9a423f | Christos Stavrakakis | # documentation and/or other materials provided with the distribution.
|
13 | 0e9a423f | Christos Stavrakakis | #
|
14 | 0e9a423f | Christos Stavrakakis | # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
15 | 0e9a423f | Christos Stavrakakis | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
16 | 0e9a423f | Christos Stavrakakis | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
17 | 0e9a423f | Christos Stavrakakis | # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
18 | 0e9a423f | Christos Stavrakakis | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
19 | 0e9a423f | Christos Stavrakakis | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
20 | 0e9a423f | Christos Stavrakakis | # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
21 | 0e9a423f | Christos Stavrakakis | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
22 | 0e9a423f | Christos Stavrakakis | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
23 | 0e9a423f | Christos Stavrakakis | # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
24 | 0e9a423f | Christos Stavrakakis | # SUCH DAMAGE.
|
25 | 0e9a423f | Christos Stavrakakis | #
|
26 | 0e9a423f | Christos Stavrakakis | # The views and conclusions contained in the software and documentation are
|
27 | 0e9a423f | Christos Stavrakakis | # those of the authors and should not be interpreted as representing official
|
28 | 0e9a423f | Christos Stavrakakis | # policies, either expressed or implied, of GRNET S.A.
|
29 | 0e9a423f | Christos Stavrakakis | #
|
30 | 0e9a423f | Christos Stavrakakis | """Reconciliation management command
|
31 | 0e9a423f | Christos Stavrakakis |
|
32 | 0e9a423f | Christos Stavrakakis | Management command to reconcile the contents of the Synnefo DB with
|
33 | 0e9a423f | Christos Stavrakakis | the state of the Ganeti backend. See docstring on top of
|
34 | 0e9a423f | Christos Stavrakakis | logic/reconciliation.py for a description of reconciliation rules.
|
35 | 0e9a423f | Christos Stavrakakis |
|
36 | 0e9a423f | Christos Stavrakakis | """
|
37 | c346aed0 | Christos Stavrakakis | import sys |
38 | 0e9a423f | Christos Stavrakakis | import datetime |
39 | c55b0cdc | Christos Stavrakakis | import bitarray |
40 | 0e9a423f | Christos Stavrakakis | |
41 | 0e9a423f | Christos Stavrakakis | from optparse import make_option |
42 | 0e9a423f | Christos Stavrakakis | |
43 | d1b1e683 | Dimitris Aragiorgis | from synnefo.settings import PUBLIC_USE_POOL |
44 | c55b0cdc | Christos Stavrakakis | from django.core.management.base import BaseCommand |
45 | c55b0cdc | Christos Stavrakakis | from django.db import transaction |
46 | 0e9a423f | Christos Stavrakakis | |
47 | 0e9a423f | Christos Stavrakakis | from synnefo.db.models import Backend, Network, BackendNetwork |
48 | fdc94944 | Christos Stavrakakis | from synnefo.db.pools import IPPool |
49 | c346aed0 | Christos Stavrakakis | from synnefo.logic import reconciliation, utils |
50 | c346aed0 | Christos Stavrakakis | from synnefo.logic import backend as backend_mod |
51 | c346aed0 | Christos Stavrakakis | |
52 | c346aed0 | Christos Stavrakakis | fix = False
|
53 | c346aed0 | Christos Stavrakakis | write = sys.stdout.write |
54 | 0e9a423f | Christos Stavrakakis | |
55 | 0e9a423f | Christos Stavrakakis | |
56 | 0e9a423f | Christos Stavrakakis | class Command(BaseCommand): |
57 | c346aed0 | Christos Stavrakakis | help = """Reconcile contents of Synnefo DB with state of Ganeti backend
|
58 | c346aed0 | Christos Stavrakakis |
|
59 | c346aed0 | Christos Stavrakakis | Network reconciliation can detect and fix the following cases:
|
60 | c346aed0 | Christos Stavrakakis | - Missing database entries for a network in a Ganeti backend
|
61 | c346aed0 | Christos Stavrakakis | - Stale database networks, which do no exist in the Ganeti backend
|
62 | c346aed0 | Christos Stavrakakis | - Missing Ganeti networks
|
63 | c346aed0 | Christos Stavrakakis | - Ganeti networks that are not connected to all Ganeti nodegroups
|
64 | c346aed0 | Christos Stavrakakis | - Networks that have unsynced state
|
65 | c346aed0 | Christos Stavrakakis | - Networks that have unsynced IP pools
|
66 | c346aed0 | Christos Stavrakakis | - Orphan networks in the Ganeti backend
|
67 | c346aed0 | Christos Stavrakakis | """
|
68 | c346aed0 | Christos Stavrakakis | |
69 | ad297723 | Christos Stavrakakis | can_import_settings = True
|
70 | 0e9a423f | Christos Stavrakakis | output_transaction = True # The management command runs inside |
71 | 0e9a423f | Christos Stavrakakis | # an SQL transaction
|
72 | 0e9a423f | Christos Stavrakakis | option_list = BaseCommand.option_list + ( |
73 | 0e9a423f | Christos Stavrakakis | make_option('--fix-all', action='store_true', |
74 | 0e9a423f | Christos Stavrakakis | dest='fix', default=False, |
75 | 0e9a423f | Christos Stavrakakis | help='Fix all issues.'),
|
76 | c55b0cdc | Christos Stavrakakis | make_option('--conflicting-ips', action='store_true', |
77 | c55b0cdc | Christos Stavrakakis | dest='conflicting_ips', default=False, |
78 | c55b0cdc | Christos Stavrakakis | help='Detect conflicting ips')
|
79 | 0e9a423f | Christos Stavrakakis | ) |
80 | 0e9a423f | Christos Stavrakakis | |
81 | 0e9a423f | Christos Stavrakakis | def handle(self, **options): |
82 | c346aed0 | Christos Stavrakakis | global fix, write
|
83 | 0e9a423f | Christos Stavrakakis | fix = options['fix']
|
84 | c346aed0 | Christos Stavrakakis | write = self.stdout.write
|
85 | c346aed0 | Christos Stavrakakis | self.verbosity = int(options['verbosity']) |
86 | c55b0cdc | Christos Stavrakakis | conflicting_ips = options['conflicting_ips']
|
87 | c346aed0 | Christos Stavrakakis | reconcile_networks(conflicting_ips) |
88 | 0e9a423f | Christos Stavrakakis | |
89 | 0e9a423f | Christos Stavrakakis | |
90 | c346aed0 | Christos Stavrakakis | def reconcile_networks(conflicting_ips=False): |
91 | 0e9a423f | Christos Stavrakakis | # Get models from DB
|
92 | 0e9a423f | Christos Stavrakakis | backends = Backend.objects.exclude(offline=True)
|
93 | 0e9a423f | Christos Stavrakakis | networks = Network.objects.filter(deleted=False)
|
94 | 0e9a423f | Christos Stavrakakis | |
95 | 0e9a423f | Christos Stavrakakis | # Get info from all ganeti backends
|
96 | 0e9a423f | Christos Stavrakakis | ganeti_networks = {} |
97 | 0e9a423f | Christos Stavrakakis | ganeti_hanging_networks = {} |
98 | 0e9a423f | Christos Stavrakakis | for b in backends: |
99 | 0e9a423f | Christos Stavrakakis | g_nets = reconciliation.get_networks_from_ganeti(b) |
100 | 0e9a423f | Christos Stavrakakis | ganeti_networks[b] = g_nets |
101 | 0e9a423f | Christos Stavrakakis | g_hanging_nets = reconciliation.hanging_networks(b, g_nets) |
102 | 0e9a423f | Christos Stavrakakis | ganeti_hanging_networks[b] = g_hanging_nets |
103 | 0e9a423f | Christos Stavrakakis | |
104 | 0e9a423f | Christos Stavrakakis | # Perform reconciliation for each network
|
105 | 0e9a423f | Christos Stavrakakis | for network in networks: |
106 | fdc94944 | Christos Stavrakakis | ip_available_maps = [] |
107 | fdc94944 | Christos Stavrakakis | ip_reserved_maps = [] |
108 | c346aed0 | Christos Stavrakakis | uses_pool = not network.public or PUBLIC_USE_POOL |
109 | c346aed0 | Christos Stavrakakis | for bend in backends: |
110 | c346aed0 | Christos Stavrakakis | bnet = get_backend_network(network, bend) |
111 | c346aed0 | Christos Stavrakakis | if not bnet: |
112 | c346aed0 | Christos Stavrakakis | # CASE-1: Paritioned network
|
113 | c346aed0 | Christos Stavrakakis | if not network.public: |
114 | c346aed0 | Christos Stavrakakis | bnet = reconcile_parted_network(network, bend) |
115 | c346aed0 | Christos Stavrakakis | if not fix: |
116 | c346aed0 | Christos Stavrakakis | continue
|
117 | 3308a83f | Christos Stavrakakis | else:
|
118 | 3308a83f | Christos Stavrakakis | continue
|
119 | 0e9a423f | Christos Stavrakakis | |
120 | 0e9a423f | Christos Stavrakakis | try:
|
121 | c346aed0 | Christos Stavrakakis | gnet = ganeti_networks[b][network.id] |
122 | 0e9a423f | Christos Stavrakakis | except KeyError: |
123 | c346aed0 | Christos Stavrakakis | # Network does not exist in backend. If the network action is
|
124 | c346aed0 | Christos Stavrakakis | # DESTROY, then we must destroy the network in the backend.
|
125 | c346aed0 | Christos Stavrakakis | # Else we have to create it!
|
126 | c346aed0 | Christos Stavrakakis | if network.action == "DESTROY" and bnet.operstate != "DELETED": |
127 | c346aed0 | Christos Stavrakakis | # CASE-2: Stale DB network
|
128 | c346aed0 | Christos Stavrakakis | reconcile_stale_network(bnet) |
129 | c346aed0 | Christos Stavrakakis | # Skip rest reconciliation as the backend is just being
|
130 | c346aed0 | Christos Stavrakakis | # deleted
|
131 | 0e9a423f | Christos Stavrakakis | continue
|
132 | 0e9a423f | Christos Stavrakakis | else:
|
133 | c346aed0 | Christos Stavrakakis | # CASE-3: Missing Ganeti network
|
134 | c346aed0 | Christos Stavrakakis | reconcile_missing_network(network, bend) |
135 | c346aed0 | Christos Stavrakakis | # Skip rest reconciliation as the network is just
|
136 | c346aed0 | Christos Stavrakakis | # being created
|
137 | 0e9a423f | Christos Stavrakakis | continue
|
138 | 0e9a423f | Christos Stavrakakis | |
139 | 0e9a423f | Christos Stavrakakis | try:
|
140 | c346aed0 | Christos Stavrakakis | hanging_groups = ganeti_hanging_networks[bend][network.id] |
141 | 0e9a423f | Christos Stavrakakis | except KeyError: |
142 | 0e9a423f | Christos Stavrakakis | # Network is connected to all nodegroups
|
143 | 0e9a423f | Christos Stavrakakis | hanging_groups = [] |
144 | 0e9a423f | Christos Stavrakakis | |
145 | c346aed0 | Christos Stavrakakis | if hanging_groups:
|
146 | c346aed0 | Christos Stavrakakis | # CASE-3: Ganeti networks not connected to all nodegroups
|
147 | c346aed0 | Christos Stavrakakis | reconcile_hanging_groups(network, bend, hanging_groups) |
148 | c346aed0 | Christos Stavrakakis | continue
|
149 | c346aed0 | Christos Stavrakakis | |
150 | c346aed0 | Christos Stavrakakis | if bnet.operstate != 'ACTIVE': |
151 | c346aed0 | Christos Stavrakakis | # CASE-4: Unsynced network state. At this point the network
|
152 | c346aed0 | Christos Stavrakakis | # exists and is connected to all nodes so is must be active!
|
153 | c346aed0 | Christos Stavrakakis | reconcile_unsynced_network(network, bend, bnet) |
154 | 0e9a423f | Christos Stavrakakis | |
155 | ad297723 | Christos Stavrakakis | if uses_pool:
|
156 | c346aed0 | Christos Stavrakakis | # Get ganeti IP Pools
|
157 | c346aed0 | Christos Stavrakakis | available_map, reserved_map = get_network_pool(gnet) |
158 | c346aed0 | Christos Stavrakakis | ip_available_maps.append(available_map) |
159 | c346aed0 | Christos Stavrakakis | ip_reserved_maps.append(reserved_map) |
160 | fdc94944 | Christos Stavrakakis | |
161 | fdc94944 | Christos Stavrakakis | if uses_pool and (ip_available_maps or ip_reserved_maps): |
162 | c346aed0 | Christos Stavrakakis | # CASE-5: Unsynced IP Pools
|
163 | c346aed0 | Christos Stavrakakis | reconcile_ip_pools(network, ip_available_maps, ip_reserved_maps) |
164 | c346aed0 | Christos Stavrakakis | |
165 | c55b0cdc | Christos Stavrakakis | if conflicting_ips:
|
166 | c346aed0 | Christos Stavrakakis | detect_conflicting_ips() |
167 | c346aed0 | Christos Stavrakakis | |
168 | c346aed0 | Christos Stavrakakis | # CASE-6: Orphan networks
|
169 | c346aed0 | Christos Stavrakakis | reconcile_orphan_networks(networks, ganeti_networks) |
170 | c346aed0 | Christos Stavrakakis | |
171 | c346aed0 | Christos Stavrakakis | |
172 | c346aed0 | Christos Stavrakakis | def get_backend_network(network, backend): |
173 | c346aed0 | Christos Stavrakakis | try:
|
174 | c346aed0 | Christos Stavrakakis | return BackendNetwork.objects.get(network=network, backend=backend)
|
175 | c346aed0 | Christos Stavrakakis | except BackendNetwork.DoesNotExist:
|
176 | c346aed0 | Christos Stavrakakis | return None |
177 | c346aed0 | Christos Stavrakakis | |
178 | c346aed0 | Christos Stavrakakis | |
179 | c346aed0 | Christos Stavrakakis | def reconcile_parted_network(network, backend): |
180 | c346aed0 | Christos Stavrakakis | write("D: Missing DB entry for network %s in backend %s\n" %
|
181 | c346aed0 | Christos Stavrakakis | (network, backend)) |
182 | c346aed0 | Christos Stavrakakis | if fix:
|
183 | c346aed0 | Christos Stavrakakis | network.create_backend_network(backend) |
184 | c346aed0 | Christos Stavrakakis | write("F: Created DB entry\n")
|
185 | c346aed0 | Christos Stavrakakis | bnet = get_backend_network(network, backend) |
186 | c346aed0 | Christos Stavrakakis | return bnet
|
187 | c55b0cdc | Christos Stavrakakis | |
188 | c346aed0 | Christos Stavrakakis | |
189 | c346aed0 | Christos Stavrakakis | def reconcile_stale_network(backend_network): |
190 | c346aed0 | Christos Stavrakakis | write("D: Stale DB entry for network %s in backend %s\n" %
|
191 | c346aed0 | Christos Stavrakakis | (backend_network.network, backend_network.backend)) |
192 | c346aed0 | Christos Stavrakakis | if fix:
|
193 | c346aed0 | Christos Stavrakakis | etime = datetime.datetime.now() |
194 | c346aed0 | Christos Stavrakakis | backend_mod.process_network_status(backend_network, etime, 0,
|
195 | c346aed0 | Christos Stavrakakis | "OP_NETWORK_REMOVE",
|
196 | c346aed0 | Christos Stavrakakis | "success",
|
197 | c346aed0 | Christos Stavrakakis | "Reconciliation simulated event")
|
198 | c346aed0 | Christos Stavrakakis | write("F: Reconciled event: OP_NETWORK_REMOVE\n")
|
199 | c346aed0 | Christos Stavrakakis | |
200 | c346aed0 | Christos Stavrakakis | |
201 | c346aed0 | Christos Stavrakakis | def reconcile_missing_network(network, backend): |
202 | c346aed0 | Christos Stavrakakis | write("D: Missing Ganeti network %s in backend %s\n" %
|
203 | c346aed0 | Christos Stavrakakis | (network, backend)) |
204 | c346aed0 | Christos Stavrakakis | if fix:
|
205 | c346aed0 | Christos Stavrakakis | backend_mod.create_network(network, [backend]) |
206 | c346aed0 | Christos Stavrakakis | write("F: Issued OP_NETWORK_CONNECT\n")
|
207 | c346aed0 | Christos Stavrakakis | |
208 | c346aed0 | Christos Stavrakakis | |
209 | c346aed0 | Christos Stavrakakis | def reconcile_hanging_groups(network, backend, hanging_groups): |
210 | c346aed0 | Christos Stavrakakis | write('D: Network %s in backend %s is not connected to '
|
211 | c346aed0 | Christos Stavrakakis | 'the following groups:\n' % (network, backend))
|
212 | c346aed0 | Christos Stavrakakis | write('- ' + '\n- '.join(hanging_groups) + '\n') |
213 | c346aed0 | Christos Stavrakakis | if fix:
|
214 | c346aed0 | Christos Stavrakakis | for group in hanging_groups: |
215 | c346aed0 | Christos Stavrakakis | write('F: Connecting network %s to nodegroup %s\n'
|
216 | c346aed0 | Christos Stavrakakis | % (network, group)) |
217 | c346aed0 | Christos Stavrakakis | backend_mod.connect_network(network, backend, group=group) |
218 | c346aed0 | Christos Stavrakakis | |
219 | c346aed0 | Christos Stavrakakis | |
220 | c346aed0 | Christos Stavrakakis | def reconcile_unsynced_network(network, backend, backend_network): |
221 | c346aed0 | Christos Stavrakakis | write("D: Unsynced network %s in backend %s\n" % (network, backend))
|
222 | c346aed0 | Christos Stavrakakis | if fix:
|
223 | c346aed0 | Christos Stavrakakis | write("F: Issuing OP_NETWORK_CONNECT\n")
|
224 | c346aed0 | Christos Stavrakakis | etime = datetime.datetime.now() |
225 | c346aed0 | Christos Stavrakakis | backend_mod.process_network_status(backend_network, etime, 0,
|
226 | c346aed0 | Christos Stavrakakis | "OP_NETWORK_CONNECT",
|
227 | c346aed0 | Christos Stavrakakis | "success",
|
228 | c346aed0 | Christos Stavrakakis | "Reconciliation simulated eventd")
|
229 | c346aed0 | Christos Stavrakakis | |
230 | c346aed0 | Christos Stavrakakis | |
231 | c346aed0 | Christos Stavrakakis | def reconcile_ip_pools(network, available_maps, reserved_maps): |
232 | c346aed0 | Christos Stavrakakis | available_map = reduce(lambda x, y: x & y, available_maps) |
233 | c346aed0 | Christos Stavrakakis | reserved_map = reduce(lambda x, y: x & y, reserved_maps) |
234 | c346aed0 | Christos Stavrakakis | |
235 | c346aed0 | Christos Stavrakakis | pool = network.get_pool() |
236 | c346aed0 | Christos Stavrakakis | if pool.available != available_map:
|
237 | c346aed0 | Christos Stavrakakis | write("D: Unsynced available map of network %s:\n"
|
238 | c346aed0 | Christos Stavrakakis | "\tDB: %r\n\tGB: %r\n" %
|
239 | c346aed0 | Christos Stavrakakis | (network, pool.available.to01(), available_map.to01(), network)) |
240 | c346aed0 | Christos Stavrakakis | if fix:
|
241 | c346aed0 | Christos Stavrakakis | pool.available = available_map |
242 | c346aed0 | Christos Stavrakakis | if pool.reserved != reserved_map:
|
243 | c346aed0 | Christos Stavrakakis | write("D: Unsynced reserved map of network %s:\n"
|
244 | c346aed0 | Christos Stavrakakis | "\tDB: %r\n\tGB: %r\n" %
|
245 | c346aed0 | Christos Stavrakakis | (network, pool.reserved.to01(), reserved_map.to01())) |
246 | c346aed0 | Christos Stavrakakis | if fix:
|
247 | c346aed0 | Christos Stavrakakis | pool.reserved = reserved_map |
248 | c346aed0 | Christos Stavrakakis | pool.save() |
249 | c346aed0 | Christos Stavrakakis | |
250 | c346aed0 | Christos Stavrakakis | |
251 | c346aed0 | Christos Stavrakakis | def detect_conflicting_ips(network): |
252 | c346aed0 | Christos Stavrakakis | """Detect NIC's that have the same IP in the same network."""
|
253 | c346aed0 | Christos Stavrakakis | machine_ips = network.nics.all().values_list('ipv4', 'machine') |
254 | c346aed0 | Christos Stavrakakis | ips = map(lambda x: x[0], machine_ips) |
255 | c346aed0 | Christos Stavrakakis | distinct_ips = set(ips)
|
256 | c346aed0 | Christos Stavrakakis | if len(distinct_ips) < len(ips): |
257 | c346aed0 | Christos Stavrakakis | for i in distinct_ips: |
258 | c346aed0 | Christos Stavrakakis | ips.remove(i) |
259 | c346aed0 | Christos Stavrakakis | for i in ips: |
260 | c346aed0 | Christos Stavrakakis | machines = [utils.id_to_instance_name(x[1]) \
|
261 | c346aed0 | Christos Stavrakakis | for x in machine_ips if x[0] == i] |
262 | c346aed0 | Christos Stavrakakis | write('D: Conflicting IP:%s Machines: %s\n' %
|
263 | c346aed0 | Christos Stavrakakis | (i, ', '.join(machines)))
|
264 | c346aed0 | Christos Stavrakakis | |
265 | c346aed0 | Christos Stavrakakis | |
266 | c346aed0 | Christos Stavrakakis | def reconcile_orphan_networks(db_networks, ganeti_networks): |
267 | 0e9a423f | Christos Stavrakakis | # Detect Orphan Networks in Ganeti
|
268 | c346aed0 | Christos Stavrakakis | db_network_ids = set([net.id for net in db_networks]) |
269 | 0e9a423f | Christos Stavrakakis | for back_end, ganeti_networks in ganeti_networks.items(): |
270 | 0e9a423f | Christos Stavrakakis | ganeti_network_ids = set(ganeti_networks.keys())
|
271 | 0e9a423f | Christos Stavrakakis | orphans = ganeti_network_ids - db_network_ids |
272 | 0e9a423f | Christos Stavrakakis | |
273 | 0e9a423f | Christos Stavrakakis | if len(orphans) > 0: |
274 | c346aed0 | Christos Stavrakakis | write('D: Orphan Networks in backend %s:\n' % back_end.clustername)
|
275 | c346aed0 | Christos Stavrakakis | write('- ' + '\n- '.join([str(o) for o in orphans]) + '\n') |
276 | 0e9a423f | Christos Stavrakakis | if fix:
|
277 | fdc94944 | Christos Stavrakakis | for net_id in orphans: |
278 | c346aed0 | Christos Stavrakakis | write('Disconnecting and deleting network %d\n' % net_id)
|
279 | fdc94944 | Christos Stavrakakis | network = Network.objects.get(id=net_id) |
280 | c346aed0 | Christos Stavrakakis | backend_mod.delete_network(network, backends=[back_end]) |
281 | c346aed0 | Christos Stavrakakis | |
282 | c346aed0 | Christos Stavrakakis | |
283 | c346aed0 | Christos Stavrakakis | def get_network_pool(gnet): |
284 | c346aed0 | Christos Stavrakakis | """Return available and reserved IP maps.
|
285 | c346aed0 | Christos Stavrakakis |
|
286 | c346aed0 | Christos Stavrakakis | Extract the available and reserved IP map from the info return from Ganeti
|
287 | c346aed0 | Christos Stavrakakis | for a network.
|
288 | c346aed0 | Christos Stavrakakis |
|
289 | c346aed0 | Christos Stavrakakis | """
|
290 | c346aed0 | Christos Stavrakakis | converter = IPPool(Foo(gnet['network']))
|
291 | c346aed0 | Christos Stavrakakis | a_map = bitarray_from_map(gnet['map'])
|
292 | c346aed0 | Christos Stavrakakis | a_map.invert() |
293 | c346aed0 | Christos Stavrakakis | reserved = gnet['external_reservations']
|
294 | c346aed0 | Christos Stavrakakis | r_map = a_map.copy() |
295 | c346aed0 | Christos Stavrakakis | r_map.setall(True)
|
296 | c346aed0 | Christos Stavrakakis | for address in reserved.split(','): |
297 | c346aed0 | Christos Stavrakakis | index = converter.value_to_index(address) |
298 | c346aed0 | Christos Stavrakakis | a_map[index] = True
|
299 | c346aed0 | Christos Stavrakakis | r_map[index] = False
|
300 | c346aed0 | Christos Stavrakakis | return a_map, r_map
|
301 | c55b0cdc | Christos Stavrakakis | |
302 | c55b0cdc | Christos Stavrakakis | |
303 | fdc94944 | Christos Stavrakakis | def bitarray_from_map(bitmap): |
304 | c55b0cdc | Christos Stavrakakis | return bitarray.bitarray(bitmap.replace("X", "1").replace(".", "0")) |
305 | c55b0cdc | Christos Stavrakakis | |
306 | c55b0cdc | Christos Stavrakakis | |
307 | fdc94944 | Christos Stavrakakis | class Foo(): |
308 | fdc94944 | Christos Stavrakakis | def __init__(self, subnet): |
309 | fdc94944 | Christos Stavrakakis | self.available_map = '' |
310 | fdc94944 | Christos Stavrakakis | self.reserved_map = '' |
311 | fdc94944 | Christos Stavrakakis | self.size = 0 |
312 | fdc94944 | Christos Stavrakakis | self.network = Foo.Foo1(subnet)
|
313 | fdc94944 | Christos Stavrakakis | |
314 | fdc94944 | Christos Stavrakakis | class Foo1(): |
315 | fdc94944 | Christos Stavrakakis | def __init__(self, subnet): |
316 | fdc94944 | Christos Stavrakakis | self.subnet = subnet
|
317 | fdc94944 | Christos Stavrakakis | self.gateway = None |