Revision fdc94944 snf-cyclades-app/synnefo/logic/management/commands/reconcile-networks.py

b/snf-cyclades-app/synnefo/logic/management/commands/reconcile-networks.py
44 44
from django.db import transaction
45 45

  
46 46
from synnefo.db.models import Backend, Network, BackendNetwork
47
from synnefo.db.pools import IPPool
47 48
from synnefo.logic import reconciliation, backend, utils
48 49

  
49 50

  
......
88 89
        destroying = network.action == 'DESTROY'
89 90
        uses_pool = not (network.type == 'PUBLIC_ROUTED' and (not
90 91
                        PUBLIC_ROUTED_USE_POOL))
91
        ip_address_maps = []
92
        ip_available_maps = []
93
        ip_reserved_maps = []
92 94

  
93 95
        # Perform reconcilliation for each backend
94 96
        for b in backends:
......
164 166

  
165 167
            if uses_pool:
166 168
                # Reconcile IP Pools
167
                ip_map = ganeti_networks[b][net_id]['map']
168
                ip_address_maps.append(bitarray_from_o1(ip_map))
169

  
170
        if ip_address_maps and uses_pool:
171
            network_bitarray = reduce(lambda x, y: x | y, ip_address_maps)
172
            if not network.pool.reservations == network_bitarray:
173
                out.write('D: Unsynced pool of network %d\n' % net_id)
174
                out.write('\t DB:\t%s\n' % network.pool.reservations.to01())
175
                out.write('\t Ganeti:%s\n' % network_bitarray.to01())
169
                gnet = ganeti_networks[b][net_id]
170
                converter = IPPool(Foo(gnet['network']))
171
                a_map = bitarray_from_map(gnet['map'])
172
                reserved = gnet['external_reservations']
173
                r_map = a_map.copy()
174
                r_map.setall(True)
175
                for address in reserved.split(','):
176
                    index = converter.value_to_index(address)
177
                    a_map[index] = True
178
                    r_map[index] = False
179
                ip_available_maps.append(a_map)
180
                ip_reserved_maps.append(r_map)
181

  
182
        if uses_pool and (ip_available_maps or ip_reserved_maps):
183
            available_map = reduce(lambda x, y: x | y, ip_available_maps)
184
            available_map.invert()
185
            reserved_map = reduce(lambda x, y: x | y, ip_reserved_maps)
186

  
187
            pool = network.get_pool()
188
            un_available = pool.available != available_map
189
            un_reserved = pool.reserved != reserved_map
190
            if un_available or un_reserved:
191
                out.write("Detected unsynchronized pool for network %r:\n" %
192
                          network.id)
193
                if un_available:
194
                    out.write("Available:\n\tDB: %r\n\tGB: %r\n" %
195
                             (pool.available.to01(), available_map.to01()))
196
                    if fix:
197
                        pool.available = available_map
198
                if un_reserved:
199
                    out.write("Reserved:\n\tDB: %r\n\tGB: %r\n" %
200
                             (pool.reserved.to01(), reserved_map.to01()))
201
                    if fix:
202
                        pool.reserved = reserved_map
176 203
                if fix:
177
                    update_network_reservations(network, network_bitarray)
178
                    out.write('F: Synchronized network pools\n')
204
                    out.write("Synchronized pools for network %r.\n" % network.id)
205
            pool.save()
179 206

  
180 207
        # Detect conflicting IPs: Detect NIC's that have the same IP
181 208
        # in the same network.
......
206 233
        if len(orphans) > 0:
207 234
            out.write('D: Orphan Networks in backend %s:\n' % back_end.clustername)
208 235
            out.write('-  ' + '\n-  '.join([str(o) for o in orphans]) + '\n')
209
            client = back_end.client
210 236
            if fix:
211
                #XXX:Move this to backend
212
                for id in orphans:
213
                    out.write('Disconnecting and deleting network %d\n' % id)
214
                    network = utils.id_to_network_name(id)
215
                    for group in client.GetGroups():
216
                        client.DisconnectNetwork(network, group)
217
                        client.DeleteNetwork(network)
237
                for net_id in orphans:
238
                    out.write('Disconnecting and deleting network %d\n' % net_id)
239
                    network = Network.objects.get(id=net_id)
240
                    backend.delete_network(network, backends=[back_end])
218 241

  
219 242

  
220
def bitarray_from_o1(bitmap):
243
def bitarray_from_map(bitmap):
221 244
    return bitarray.bitarray(bitmap.replace("X", "1").replace(".", "0"))
222 245

  
223 246

  
......
225 248
def update_network_reservations(network, reservations):
226 249
    network.pool.reservations = reservations
227 250
    network.pool.save()
251

  
252

  
253
class Foo():
254
    def __init__(self, subnet):
255
        self.available_map = ''
256
        self.reserved_map = ''
257
        self.size = 0
258
        self.network = Foo.Foo1(subnet)
259

  
260
    class Foo1():
261
        def __init__(self, subnet):
262
            self.subnet = subnet
263
            self.gateway = None

Also available in: Unified diff