Revision fdc94944
b/snf-cyclades-app/synnefo/api/actions.py | ||
---|---|---|
42 | 42 |
|
43 | 43 |
from synnefo.api.faults import (BadRequest, ServiceUnavailable, |
44 | 44 |
ItemNotFound, BuildInProgress) |
45 |
from synnefo.api.util import random_password, get_vm, get_nic_from_index |
|
45 |
from synnefo.api.util import (random_password, get_vm, get_nic_from_index, |
|
46 |
get_network_free_address) |
|
46 | 47 |
from synnefo.db.models import NetworkInterface, Network |
47 |
from synnefo.db.pools import IPPool
|
|
48 |
from synnefo.db.pools import EmptyPool
|
|
48 | 49 |
from synnefo.logic import backend |
49 | 50 |
from synnefo.logic.utils import get_rsapi_state |
50 | 51 |
|
... | ... | |
314 | 315 |
raise ServiceUnavailable('Network not active yet') |
315 | 316 |
|
316 | 317 |
# Get a free IP from the address pool. |
317 |
pool = IPPool(net) |
|
318 | 318 |
try: |
319 |
address = pool.get_free_address()
|
|
320 |
except IPPool.IPPoolExhausted:
|
|
319 |
address = get_network_free_address(net)
|
|
320 |
except EmptyPool:
|
|
321 | 321 |
raise ServiceUnavailable('Network is full') |
322 |
pool.save() |
|
323 | 322 |
|
324 | 323 |
backend.connect_to_network(vm, net, address) |
325 | 324 |
return HttpResponse(status=202) |
b/snf-cyclades-app/synnefo/api/util.py | ||
---|---|---|
63 | 63 |
|
64 | 64 |
from synnefo.lib.astakos import get_user |
65 | 65 |
from synnefo.plankton.backend import ImageBackend |
66 |
from synnefo.db.pools import IPPool |
|
67 | 66 |
from synnefo.settings import MAX_CIDR_BLOCK |
68 | 67 |
|
69 | 68 |
|
... | ... | |
231 | 230 |
def get_network_free_address(network): |
232 | 231 |
"""Reserve an IP address from the IP Pool of the network. |
233 | 232 |
|
234 |
Raises Network.DoesNotExist , IPPool.IPPoolExhausted
|
|
233 |
Raises EmptyPool
|
|
235 | 234 |
|
236 | 235 |
""" |
237 | 236 |
|
238 |
# Get the Network object in exclusive mode in order to |
|
239 |
# safely (isolated) reserve an IP address |
|
240 |
network = Network.objects.select_for_update().get(id=network.id) |
|
241 |
pool = IPPool(network) |
|
242 |
address = pool.get_free_address() |
|
237 |
pool = network.get_pool() |
|
238 |
address = pool.get() |
|
243 | 239 |
pool.save() |
244 | 240 |
return address |
245 | 241 |
|
b/snf-cyclades-app/synnefo/db/migrations/0054_auto__add_ippooltable__add_field_network_pool.py | ||
---|---|---|
1 |
# encoding: utf-8 |
|
2 |
import datetime |
|
3 |
from south.db import db |
|
4 |
from south.v2 import SchemaMigration |
|
5 |
from django.db import models |
|
6 |
|
|
7 |
class Migration(SchemaMigration): |
|
8 |
|
|
9 |
def forwards(self, orm): |
|
10 |
|
|
11 |
# Adding model 'IPPoolTable' |
|
12 |
db.create_table('db_ippooltable', ( |
|
13 |
('reserved_map', self.gf('django.db.models.fields.TextField')(default='')), |
|
14 |
('base', self.gf('django.db.models.fields.CharField')(max_length=32, null=True)), |
|
15 |
('offset', self.gf('django.db.models.fields.IntegerField')(null=True)), |
|
16 |
('available_map', self.gf('django.db.models.fields.TextField')(default='')), |
|
17 |
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), |
|
18 |
('size', self.gf('django.db.models.fields.IntegerField')()), |
|
19 |
)) |
|
20 |
db.send_create_signal('db', ['IPPoolTable']) |
|
21 |
|
|
22 |
# Adding field 'Network.pool' |
|
23 |
db.add_column('db_network', 'pool', self.gf('django.db.models.fields.related.OneToOneField')(related_name='network', unique=True, null=True, to=orm['db.IPPoolTable']), keep_default=False) |
|
24 |
|
|
25 |
|
|
26 |
def backwards(self, orm): |
|
27 |
|
|
28 |
# Deleting model 'IPPoolTable' |
|
29 |
db.delete_table('db_ippooltable') |
|
30 |
|
|
31 |
# Deleting field 'Network.pool' |
|
32 |
db.delete_column('db_network', 'pool_id') |
|
33 |
|
|
34 |
|
|
35 |
models = { |
|
36 |
'db.backend': { |
|
37 |
'Meta': {'object_name': 'Backend'}, |
|
38 |
'clustername': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}), |
|
39 |
'ctotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
40 |
'dfree': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
41 |
'drained': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
42 |
'dtotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
43 |
'hash': ('django.db.models.fields.CharField', [], {'max_length': '40'}), |
|
44 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
45 |
'index': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'unique': 'True'}), |
|
46 |
'mfree': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
47 |
'mtotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
48 |
'offline': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
49 |
'password_hash': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), |
|
50 |
'pinst_cnt': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
51 |
'port': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5080'}), |
|
52 |
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
|
53 |
'username': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}) |
|
54 |
}, |
|
55 |
'db.backendnetwork': { |
|
56 |
'Meta': {'unique_together': "(('network', 'backend'),)", 'object_name': 'BackendNetwork'}, |
|
57 |
'backend': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'networks'", 'to': "orm['db.Backend']"}), |
|
58 |
'backendjobid': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), |
|
59 |
'backendjobstatus': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
60 |
'backendlogmsg': ('django.db.models.fields.TextField', [], {'null': 'True'}), |
|
61 |
'backendopcode': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
62 |
'backendtime': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(1, 1, 1, 0, 0)'}), |
|
63 |
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
|
64 |
'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
65 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
66 |
'mac_prefix': ('django.db.models.fields.CharField', [], {'max_length': '32'}), |
|
67 |
'network': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'backend_networks'", 'to': "orm['db.Network']"}), |
|
68 |
'operstate': ('django.db.models.fields.CharField', [], {'default': "'PENDING'", 'max_length': '30'}), |
|
69 |
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) |
|
70 |
}, |
|
71 |
'db.bridgepooltable': { |
|
72 |
'Meta': {'object_name': 'BridgePoolTable'}, |
|
73 |
'available_map': ('django.db.models.fields.TextField', [], {'default': "''"}), |
|
74 |
'base': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), |
|
75 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
76 |
'offset': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), |
|
77 |
'reserved_map': ('django.db.models.fields.TextField', [], {'default': "''"}), |
|
78 |
'size': ('django.db.models.fields.IntegerField', [], {}) |
|
79 |
}, |
|
80 |
'db.flavor': { |
|
81 |
'Meta': {'unique_together': "(('cpu', 'ram', 'disk', 'disk_template'),)", 'object_name': 'Flavor'}, |
|
82 |
'cpu': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
83 |
'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
84 |
'disk': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
85 |
'disk_template': ('django.db.models.fields.CharField', [], {'default': "'plain'", 'max_length': '32'}), |
|
86 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
87 |
'ram': ('django.db.models.fields.IntegerField', [], {'default': '0'}) |
|
88 |
}, |
|
89 |
'db.ippooltable': { |
|
90 |
'Meta': {'object_name': 'IPPoolTable'}, |
|
91 |
'available_map': ('django.db.models.fields.TextField', [], {'default': "''"}), |
|
92 |
'base': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), |
|
93 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
94 |
'offset': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), |
|
95 |
'reserved_map': ('django.db.models.fields.TextField', [], {'default': "''"}), |
|
96 |
'size': ('django.db.models.fields.IntegerField', [], {}) |
|
97 |
}, |
|
98 |
'db.macprefixpooltable': { |
|
99 |
'Meta': {'object_name': 'MacPrefixPoolTable'}, |
|
100 |
'available_map': ('django.db.models.fields.TextField', [], {'default': "''"}), |
|
101 |
'base': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), |
|
102 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
103 |
'offset': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), |
|
104 |
'reserved_map': ('django.db.models.fields.TextField', [], {'default': "''"}), |
|
105 |
'size': ('django.db.models.fields.IntegerField', [], {}) |
|
106 |
}, |
|
107 |
'db.network': { |
|
108 |
'Meta': {'object_name': 'Network'}, |
|
109 |
'action': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '32', 'null': 'True'}), |
|
110 |
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
|
111 |
'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
112 |
'dhcp': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), |
|
113 |
'gateway': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), |
|
114 |
'gateway6': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True'}), |
|
115 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
116 |
'link': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}), |
|
117 |
'mac_prefix': ('django.db.models.fields.CharField', [], {'max_length': '32'}), |
|
118 |
'machines': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['db.VirtualMachine']", 'through': "orm['db.NetworkInterface']", 'symmetrical': 'False'}), |
|
119 |
'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}), |
|
120 |
'pool': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'network'", 'unique': 'True', 'null': 'True', 'to': "orm['db.IPPoolTable']"}), |
|
121 |
'public': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
122 |
'reservations': ('django.db.models.fields.TextField', [], {'default': "''"}), |
|
123 |
'state': ('django.db.models.fields.CharField', [], {'default': "'PENDING'", 'max_length': '32'}), |
|
124 |
'subnet': ('django.db.models.fields.CharField', [], {'default': "'10.0.0.0/24'", 'max_length': '32'}), |
|
125 |
'subnet6': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True'}), |
|
126 |
'type': ('django.db.models.fields.CharField', [], {'default': "'PRIVATE_PHYSICAL_VLAN'", 'max_length': '50'}), |
|
127 |
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), |
|
128 |
'userid': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}) |
|
129 |
}, |
|
130 |
'db.networkinterface': { |
|
131 |
'Meta': {'object_name': 'NetworkInterface'}, |
|
132 |
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
|
133 |
'dirty': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
134 |
'firewall_profile': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
135 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
136 |
'index': ('django.db.models.fields.IntegerField', [], {}), |
|
137 |
'ipv4': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True'}), |
|
138 |
'ipv6': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), |
|
139 |
'mac': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'}), |
|
140 |
'machine': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nics'", 'to': "orm['db.VirtualMachine']"}), |
|
141 |
'network': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nics'", 'to': "orm['db.Network']"}), |
|
142 |
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) |
|
143 |
}, |
|
144 |
'db.virtualmachine': { |
|
145 |
'Meta': {'object_name': 'VirtualMachine'}, |
|
146 |
'action': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
147 |
'backend': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'virtual_machines'", 'null': 'True', 'to': "orm['db.Backend']"}), |
|
148 |
'backend_hash': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}), |
|
149 |
'backendjobid': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), |
|
150 |
'backendjobstatus': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
151 |
'backendlogmsg': ('django.db.models.fields.TextField', [], {'null': 'True'}), |
|
152 |
'backendopcode': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
153 |
'backendtime': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(1, 1, 1, 0, 0)'}), |
|
154 |
'buildpercentage': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
155 |
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
|
156 |
'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
157 |
'flavor': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.Flavor']"}), |
|
158 |
'hostid': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
|
159 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
160 |
'imageid': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
|
161 |
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
162 |
'operstate': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
163 |
'suspended': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
164 |
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), |
|
165 |
'userid': ('django.db.models.fields.CharField', [], {'max_length': '100'}) |
|
166 |
}, |
|
167 |
'db.virtualmachinemetadata': { |
|
168 |
'Meta': {'unique_together': "(('meta_key', 'vm'),)", 'object_name': 'VirtualMachineMetadata'}, |
|
169 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
170 |
'meta_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}), |
|
171 |
'meta_value': ('django.db.models.fields.CharField', [], {'max_length': '500'}), |
|
172 |
'vm': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'metadata'", 'to': "orm['db.VirtualMachine']"}) |
|
173 |
} |
|
174 |
} |
|
175 |
|
|
176 |
complete_apps = ['db'] |
b/snf-cyclades-app/synnefo/db/migrations/0055_data_migrate_ip_pools.py | ||
---|---|---|
1 |
# encoding: utf-8 |
|
2 |
import datetime |
|
3 |
from south.db import db |
|
4 |
from south.v2 import DataMigration |
|
5 |
from django.db import models |
|
6 |
|
|
7 |
from bitarray import bitarray |
|
8 |
from base64 import b64encode, b64decode |
|
9 |
|
|
10 |
|
|
11 |
class Migration(DataMigration): |
|
12 |
|
|
13 |
def forwards(self, orm): |
|
14 |
"Write your forwards methods here." |
|
15 |
for network in orm.Network.objects.all(): |
|
16 |
if not network.reservations: |
|
17 |
continue |
|
18 |
old_res = bitarray() |
|
19 |
old_res.fromstring(b64decode(network.reservations)) |
|
20 |
old_res.invert() |
|
21 |
|
|
22 |
available_map = b64encode(old_res.tostring()) |
|
23 |
|
|
24 |
size = old_res.length() |
|
25 |
|
|
26 |
new_res = bitarray(size) |
|
27 |
new_res.setall(True) |
|
28 |
new_res[0] = False |
|
29 |
new_res[size-1] = False |
|
30 |
|
|
31 |
reserved_map = b64encode(new_res.tostring()) |
|
32 |
|
|
33 |
pool = orm.IPPoolTable.objects.create(size=size, |
|
34 |
available_map=available_map, |
|
35 |
reserved_map=reserved_map) |
|
36 |
|
|
37 |
network.pool = pool |
|
38 |
network.save() |
|
39 |
|
|
40 |
|
|
41 |
|
|
42 |
def backwards(self, orm): |
|
43 |
"Write your backwards methods here." |
|
44 |
for network in orm.Network.objects.all(): |
|
45 |
if not network.pool: |
|
46 |
network.reservations = '' |
|
47 |
network.save() |
|
48 |
continue |
|
49 |
pool = network.pool |
|
50 |
|
|
51 |
available = bitarray() |
|
52 |
available.fromstring(b64decode(pool.available_map)) |
|
53 |
reserved = bitarray() |
|
54 |
reserved.fromstring(b64decode(pool.reserved_map)) |
|
55 |
|
|
56 |
both = (available & reserved) |
|
57 |
both.invert() |
|
58 |
network.reservations = b64encode(both.tostring()) |
|
59 |
network.save() |
|
60 |
|
|
61 |
models = { |
|
62 |
'db.backend': { |
|
63 |
'Meta': {'object_name': 'Backend'}, |
|
64 |
'clustername': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}), |
|
65 |
'ctotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
66 |
'dfree': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
67 |
'drained': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
68 |
'dtotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
69 |
'hash': ('django.db.models.fields.CharField', [], {'max_length': '40'}), |
|
70 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
71 |
'index': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'unique': 'True'}), |
|
72 |
'mfree': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
73 |
'mtotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
74 |
'offline': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
75 |
'password_hash': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), |
|
76 |
'pinst_cnt': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
77 |
'port': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5080'}), |
|
78 |
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
|
79 |
'username': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}) |
|
80 |
}, |
|
81 |
'db.backendnetwork': { |
|
82 |
'Meta': {'unique_together': "(('network', 'backend'),)", 'object_name': 'BackendNetwork'}, |
|
83 |
'backend': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'networks'", 'to': "orm['db.Backend']"}), |
|
84 |
'backendjobid': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), |
|
85 |
'backendjobstatus': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
86 |
'backendlogmsg': ('django.db.models.fields.TextField', [], {'null': 'True'}), |
|
87 |
'backendopcode': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
88 |
'backendtime': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(1, 1, 1, 0, 0)'}), |
|
89 |
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
|
90 |
'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
91 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
92 |
'mac_prefix': ('django.db.models.fields.CharField', [], {'max_length': '32'}), |
|
93 |
'network': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'backend_networks'", 'to': "orm['db.Network']"}), |
|
94 |
'operstate': ('django.db.models.fields.CharField', [], {'default': "'PENDING'", 'max_length': '30'}), |
|
95 |
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) |
|
96 |
}, |
|
97 |
'db.bridgepooltable': { |
|
98 |
'Meta': {'object_name': 'BridgePoolTable'}, |
|
99 |
'available_map': ('django.db.models.fields.TextField', [], {'default': "''"}), |
|
100 |
'base': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), |
|
101 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
102 |
'offset': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), |
|
103 |
'reserved_map': ('django.db.models.fields.TextField', [], {'default': "''"}), |
|
104 |
'size': ('django.db.models.fields.IntegerField', [], {}) |
|
105 |
}, |
|
106 |
'db.flavor': { |
|
107 |
'Meta': {'unique_together': "(('cpu', 'ram', 'disk', 'disk_template'),)", 'object_name': 'Flavor'}, |
|
108 |
'cpu': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
109 |
'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
110 |
'disk': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
111 |
'disk_template': ('django.db.models.fields.CharField', [], {'default': "'plain'", 'max_length': '32'}), |
|
112 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
113 |
'ram': ('django.db.models.fields.IntegerField', [], {'default': '0'}) |
|
114 |
}, |
|
115 |
'db.ippooltable': { |
|
116 |
'Meta': {'object_name': 'IPPoolTable'}, |
|
117 |
'available_map': ('django.db.models.fields.TextField', [], {'default': "''"}), |
|
118 |
'base': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), |
|
119 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
120 |
'offset': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), |
|
121 |
'reserved_map': ('django.db.models.fields.TextField', [], {'default': "''"}), |
|
122 |
'size': ('django.db.models.fields.IntegerField', [], {}) |
|
123 |
}, |
|
124 |
'db.macprefixpooltable': { |
|
125 |
'Meta': {'object_name': 'MacPrefixPoolTable'}, |
|
126 |
'available_map': ('django.db.models.fields.TextField', [], {'default': "''"}), |
|
127 |
'base': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), |
|
128 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
129 |
'offset': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), |
|
130 |
'reserved_map': ('django.db.models.fields.TextField', [], {'default': "''"}), |
|
131 |
'size': ('django.db.models.fields.IntegerField', [], {}) |
|
132 |
}, |
|
133 |
'db.network': { |
|
134 |
'Meta': {'object_name': 'Network'}, |
|
135 |
'action': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '32', 'null': 'True'}), |
|
136 |
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
|
137 |
'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
138 |
'dhcp': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), |
|
139 |
'gateway': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), |
|
140 |
'gateway6': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True'}), |
|
141 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
142 |
'link': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}), |
|
143 |
'mac_prefix': ('django.db.models.fields.CharField', [], {'max_length': '32'}), |
|
144 |
'machines': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['db.VirtualMachine']", 'through': "orm['db.NetworkInterface']", 'symmetrical': 'False'}), |
|
145 |
'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}), |
|
146 |
'pool': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'network'", 'unique': 'True', 'null': 'True', 'to': "orm['db.IPPoolTable']"}), |
|
147 |
'public': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
148 |
'reservations': ('django.db.models.fields.TextField', [], {'default': "''"}), |
|
149 |
'state': ('django.db.models.fields.CharField', [], {'default': "'PENDING'", 'max_length': '32'}), |
|
150 |
'subnet': ('django.db.models.fields.CharField', [], {'default': "'10.0.0.0/24'", 'max_length': '32'}), |
|
151 |
'subnet6': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True'}), |
|
152 |
'type': ('django.db.models.fields.CharField', [], {'default': "'PRIVATE_PHYSICAL_VLAN'", 'max_length': '50'}), |
|
153 |
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), |
|
154 |
'userid': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}) |
|
155 |
}, |
|
156 |
'db.networkinterface': { |
|
157 |
'Meta': {'object_name': 'NetworkInterface'}, |
|
158 |
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
|
159 |
'dirty': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
160 |
'firewall_profile': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
161 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
162 |
'index': ('django.db.models.fields.IntegerField', [], {}), |
|
163 |
'ipv4': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True'}), |
|
164 |
'ipv6': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), |
|
165 |
'mac': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'}), |
|
166 |
'machine': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nics'", 'to': "orm['db.VirtualMachine']"}), |
|
167 |
'network': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nics'", 'to': "orm['db.Network']"}), |
|
168 |
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) |
|
169 |
}, |
|
170 |
'db.virtualmachine': { |
|
171 |
'Meta': {'object_name': 'VirtualMachine'}, |
|
172 |
'action': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
173 |
'backend': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'virtual_machines'", 'null': 'True', 'to': "orm['db.Backend']"}), |
|
174 |
'backend_hash': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}), |
|
175 |
'backendjobid': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), |
|
176 |
'backendjobstatus': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
177 |
'backendlogmsg': ('django.db.models.fields.TextField', [], {'null': 'True'}), |
|
178 |
'backendopcode': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
179 |
'backendtime': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(1, 1, 1, 0, 0)'}), |
|
180 |
'buildpercentage': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
181 |
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
|
182 |
'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
183 |
'flavor': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.Flavor']"}), |
|
184 |
'hostid': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
|
185 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
186 |
'imageid': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
|
187 |
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
188 |
'operstate': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
189 |
'suspended': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
190 |
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), |
|
191 |
'userid': ('django.db.models.fields.CharField', [], {'max_length': '100'}) |
|
192 |
}, |
|
193 |
'db.virtualmachinemetadata': { |
|
194 |
'Meta': {'unique_together': "(('meta_key', 'vm'),)", 'object_name': 'VirtualMachineMetadata'}, |
|
195 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
196 |
'meta_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}), |
|
197 |
'meta_value': ('django.db.models.fields.CharField', [], {'max_length': '500'}), |
|
198 |
'vm': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'metadata'", 'to': "orm['db.VirtualMachine']"}) |
|
199 |
} |
|
200 |
} |
|
201 |
|
|
202 |
complete_apps = ['db'] |
b/snf-cyclades-app/synnefo/db/migrations/0056_auto__del_field_network_reservations.py | ||
---|---|---|
1 |
# encoding: utf-8 |
|
2 |
import datetime |
|
3 |
from south.db import db |
|
4 |
from south.v2 import SchemaMigration |
|
5 |
from django.db import models |
|
6 |
|
|
7 |
class Migration(SchemaMigration): |
|
8 |
|
|
9 |
def forwards(self, orm): |
|
10 |
|
|
11 |
# Deleting field 'Network.reservations' |
|
12 |
db.delete_column('db_network', 'reservations') |
|
13 |
|
|
14 |
|
|
15 |
def backwards(self, orm): |
|
16 |
|
|
17 |
# Adding field 'Network.reservations' |
|
18 |
db.add_column('db_network', 'reservations', self.gf('django.db.models.fields.TextField')(default=''), keep_default=False) |
|
19 |
|
|
20 |
|
|
21 |
models = { |
|
22 |
'db.backend': { |
|
23 |
'Meta': {'object_name': 'Backend'}, |
|
24 |
'clustername': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}), |
|
25 |
'ctotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
26 |
'dfree': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
27 |
'drained': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
28 |
'dtotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
29 |
'hash': ('django.db.models.fields.CharField', [], {'max_length': '40'}), |
|
30 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
31 |
'index': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'unique': 'True'}), |
|
32 |
'mfree': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
33 |
'mtotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
34 |
'offline': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
35 |
'password_hash': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), |
|
36 |
'pinst_cnt': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
37 |
'port': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5080'}), |
|
38 |
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
|
39 |
'username': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}) |
|
40 |
}, |
|
41 |
'db.backendnetwork': { |
|
42 |
'Meta': {'unique_together': "(('network', 'backend'),)", 'object_name': 'BackendNetwork'}, |
|
43 |
'backend': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'networks'", 'to': "orm['db.Backend']"}), |
|
44 |
'backendjobid': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), |
|
45 |
'backendjobstatus': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
46 |
'backendlogmsg': ('django.db.models.fields.TextField', [], {'null': 'True'}), |
|
47 |
'backendopcode': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
48 |
'backendtime': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(1, 1, 1, 0, 0)'}), |
|
49 |
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
|
50 |
'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
51 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
52 |
'mac_prefix': ('django.db.models.fields.CharField', [], {'max_length': '32'}), |
|
53 |
'network': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'backend_networks'", 'to': "orm['db.Network']"}), |
|
54 |
'operstate': ('django.db.models.fields.CharField', [], {'default': "'PENDING'", 'max_length': '30'}), |
|
55 |
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) |
|
56 |
}, |
|
57 |
'db.bridgepooltable': { |
|
58 |
'Meta': {'object_name': 'BridgePoolTable'}, |
|
59 |
'available_map': ('django.db.models.fields.TextField', [], {'default': "''"}), |
|
60 |
'base': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), |
|
61 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
62 |
'offset': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), |
|
63 |
'reserved_map': ('django.db.models.fields.TextField', [], {'default': "''"}), |
|
64 |
'size': ('django.db.models.fields.IntegerField', [], {}) |
|
65 |
}, |
|
66 |
'db.flavor': { |
|
67 |
'Meta': {'unique_together': "(('cpu', 'ram', 'disk', 'disk_template'),)", 'object_name': 'Flavor'}, |
|
68 |
'cpu': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
69 |
'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
70 |
'disk': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
71 |
'disk_template': ('django.db.models.fields.CharField', [], {'default': "'plain'", 'max_length': '32'}), |
|
72 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
73 |
'ram': ('django.db.models.fields.IntegerField', [], {'default': '0'}) |
|
74 |
}, |
|
75 |
'db.ippooltable': { |
|
76 |
'Meta': {'object_name': 'IPPoolTable'}, |
|
77 |
'available_map': ('django.db.models.fields.TextField', [], {'default': "''"}), |
|
78 |
'base': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), |
|
79 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
80 |
'offset': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), |
|
81 |
'reserved_map': ('django.db.models.fields.TextField', [], {'default': "''"}), |
|
82 |
'size': ('django.db.models.fields.IntegerField', [], {}) |
|
83 |
}, |
|
84 |
'db.macprefixpooltable': { |
|
85 |
'Meta': {'object_name': 'MacPrefixPoolTable'}, |
|
86 |
'available_map': ('django.db.models.fields.TextField', [], {'default': "''"}), |
|
87 |
'base': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), |
|
88 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
89 |
'offset': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), |
|
90 |
'reserved_map': ('django.db.models.fields.TextField', [], {'default': "''"}), |
|
91 |
'size': ('django.db.models.fields.IntegerField', [], {}) |
|
92 |
}, |
|
93 |
'db.network': { |
|
94 |
'Meta': {'object_name': 'Network'}, |
|
95 |
'action': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '32', 'null': 'True'}), |
|
96 |
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
|
97 |
'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
98 |
'dhcp': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), |
|
99 |
'gateway': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), |
|
100 |
'gateway6': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True'}), |
|
101 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
102 |
'link': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}), |
|
103 |
'mac_prefix': ('django.db.models.fields.CharField', [], {'max_length': '32'}), |
|
104 |
'machines': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['db.VirtualMachine']", 'through': "orm['db.NetworkInterface']", 'symmetrical': 'False'}), |
|
105 |
'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}), |
|
106 |
'pool': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'network'", 'unique': 'True', 'null': 'True', 'to': "orm['db.IPPoolTable']"}), |
|
107 |
'public': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
108 |
'state': ('django.db.models.fields.CharField', [], {'default': "'PENDING'", 'max_length': '32'}), |
|
109 |
'subnet': ('django.db.models.fields.CharField', [], {'default': "'10.0.0.0/24'", 'max_length': '32'}), |
|
110 |
'subnet6': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True'}), |
|
111 |
'type': ('django.db.models.fields.CharField', [], {'default': "'PRIVATE_PHYSICAL_VLAN'", 'max_length': '50'}), |
|
112 |
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), |
|
113 |
'userid': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}) |
|
114 |
}, |
|
115 |
'db.networkinterface': { |
|
116 |
'Meta': {'object_name': 'NetworkInterface'}, |
|
117 |
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
|
118 |
'dirty': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
119 |
'firewall_profile': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
120 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
121 |
'index': ('django.db.models.fields.IntegerField', [], {}), |
|
122 |
'ipv4': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True'}), |
|
123 |
'ipv6': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), |
|
124 |
'mac': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'}), |
|
125 |
'machine': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nics'", 'to': "orm['db.VirtualMachine']"}), |
|
126 |
'network': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nics'", 'to': "orm['db.Network']"}), |
|
127 |
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) |
|
128 |
}, |
|
129 |
'db.virtualmachine': { |
|
130 |
'Meta': {'object_name': 'VirtualMachine'}, |
|
131 |
'action': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
132 |
'backend': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'virtual_machines'", 'null': 'True', 'to': "orm['db.Backend']"}), |
|
133 |
'backend_hash': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}), |
|
134 |
'backendjobid': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), |
|
135 |
'backendjobstatus': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
136 |
'backendlogmsg': ('django.db.models.fields.TextField', [], {'null': 'True'}), |
|
137 |
'backendopcode': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
138 |
'backendtime': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(1, 1, 1, 0, 0)'}), |
|
139 |
'buildpercentage': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
140 |
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
|
141 |
'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
142 |
'flavor': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.Flavor']"}), |
|
143 |
'hostid': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
|
144 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
145 |
'imageid': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
|
146 |
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
147 |
'operstate': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
148 |
'suspended': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
149 |
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), |
|
150 |
'userid': ('django.db.models.fields.CharField', [], {'max_length': '100'}) |
|
151 |
}, |
|
152 |
'db.virtualmachinemetadata': { |
|
153 |
'Meta': {'unique_together': "(('meta_key', 'vm'),)", 'object_name': 'VirtualMachineMetadata'}, |
|
154 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
155 |
'meta_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}), |
|
156 |
'meta_value': ('django.db.models.fields.CharField', [], {'max_length': '500'}), |
|
157 |
'vm': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'metadata'", 'to': "orm['db.VirtualMachine']"}) |
|
158 |
} |
|
159 |
} |
|
160 |
|
|
161 |
complete_apps = ['db'] |
b/snf-cyclades-app/synnefo/db/models.py | ||
---|---|---|
467 | 467 |
action = models.CharField(choices=ACTIONS, max_length=32, null=True, |
468 | 468 |
default=None) |
469 | 469 |
|
470 |
reservations = models.TextField(default='') |
|
471 |
|
|
472 |
ip_pool = None |
|
470 |
pool = models.OneToOneField('IPPoolTable', related_name='network', |
|
471 |
null=True) |
|
473 | 472 |
|
474 | 473 |
objects = ForUpdateManager() |
475 | 474 |
|
... | ... | |
559 | 558 |
for backend in backends: |
560 | 559 |
BackendNetwork.objects.create(backend=backend, network=self) |
561 | 560 |
|
562 |
@property
|
|
563 |
def pool(self):
|
|
564 |
if self.ip_pool:
|
|
565 |
return self.ip_pool
|
|
566 |
else:
|
|
567 |
self.ip_pool = pools.IPPool(self)
|
|
568 |
return self.ip_pool
|
|
561 |
def get_pool(self):
|
|
562 |
if not self.pool_id:
|
|
563 |
self.pool = IPPoolTable.objects.create(available_map='',
|
|
564 |
reserved_map='',
|
|
565 |
size=0)
|
|
566 |
self.save()
|
|
567 |
return IPPoolTable.objects.select_for_update().get(id=self.pool_id).pool
|
|
569 | 568 |
|
570 |
def reserve_address(self, address, pool=None):
|
|
571 |
pool = pool or self.pool
|
|
569 |
def reserve_address(self, address): |
|
570 |
pool = self.get_pool()
|
|
572 | 571 |
pool.reserve(address) |
573 |
pool._update_network() |
|
574 |
self.save() |
|
572 |
pool.save() |
|
575 | 573 |
|
576 |
def release_address(self, address, pool=None): |
|
577 |
pool = pool or self.pool |
|
578 |
pool.release(address) |
|
579 |
pool._update_network() |
|
580 |
self.save() |
|
574 |
def release_address(self, address): |
|
575 |
pool = self.get_pool() |
|
576 |
pool.put(address) |
|
577 |
pool.save() |
|
581 | 578 |
|
582 | 579 |
|
583 | 580 |
class BackendNetwork(models.Model): |
... | ... | |
712 | 709 |
class BridgePoolTable(PoolTable): |
713 | 710 |
manager = pools.BridgePool |
714 | 711 |
|
712 |
|
|
715 | 713 |
class MacPrefixPoolTable(PoolTable): |
716 | 714 |
manager = pools.MacPrefixPool |
715 |
|
|
716 |
|
|
717 |
class IPPoolTable(PoolTable): |
|
718 |
manager = pools.IPPool |
b/snf-cyclades-app/synnefo/db/pools/__init__.py | ||
---|---|---|
67 | 67 |
index = self.value_to_index(value) |
68 | 68 |
self._release(index, external) |
69 | 69 |
|
70 |
def reserve(self, value, external=True):
|
|
70 |
def reserve(self, value, external=False):
|
|
71 | 71 |
"""Reserve a value.""" |
72 | 72 |
index = self.value_to_index(value) |
73 | 73 |
self._reserve(index, external) |
... | ... | |
206 | 206 |
return bin_[6] == '1' and bin_[7] == '0' |
207 | 207 |
|
208 | 208 |
|
209 |
# class IPPool(PoolManager): |
|
210 |
# def __init__(self, network): |
|
211 |
# do_init = False if network.pool else True |
|
212 |
# self.net = ipaddr.IPNetwork(network.subnet) |
|
213 |
# network.size = self.net.numhosts |
|
214 |
# super(IPPool, self).__init__(network) |
|
215 |
# gateway = network.gateway |
|
216 |
# self.gateway = gateway and ipaddr.IPAddress(gateway) or None |
|
217 |
# if do_init: |
|
218 |
# self._reserve(0) |
|
219 |
# self.put(gateway) |
|
220 |
# self._reserve(self.size() - 1) |
|
221 |
# |
|
222 |
# def value_to_index(self, value): |
|
223 |
# addr = ipaddr.IPAddress(value) |
|
224 |
# return int(addr) - int(self.net.network) |
|
225 |
# |
|
226 |
# def index_to_value(self, index): |
|
227 |
# return str(self.net[index]) |
|
228 |
|
|
229 |
class IPPool(object): |
|
230 |
"""IP pool class, based on a models.Network object |
|
231 |
|
|
232 |
Implementation of an IP address pool based on a models.Network |
|
233 |
object. |
|
234 |
|
|
235 |
""" |
|
236 |
def __init__(self, network): |
|
237 |
self.net = network |
|
238 |
self.network = ipaddr.IPNetwork(self.net.subnet) |
|
239 |
|
|
240 |
gateway = self.net.gateway |
|
209 |
class IPPool(PoolManager): |
|
210 |
def __init__(self, pool_table): |
|
211 |
do_init = False if pool_table.available_map else True |
|
212 |
network = pool_table.network |
|
213 |
self.net = ipaddr.IPNetwork(network.subnet) |
|
214 |
if not pool_table.size: |
|
215 |
pool_table.size = self.net.numhosts |
|
216 |
super(IPPool, self).__init__(pool_table) |
|
217 |
gateway = network.gateway |
|
241 | 218 |
self.gateway = gateway and ipaddr.IPAddress(gateway) or None |
219 |
if do_init: |
|
220 |
self._reserve(0) |
|
221 |
self.reserve(gateway) |
|
222 |
self._reserve(self.size() - 1) |
|
242 | 223 |
|
243 |
if self.net.reservations: |
|
244 |
self.reservations = bitarray() |
|
245 |
self.reservations.fromstring(b64decode(self.net.reservations)) |
|
246 |
else: |
|
247 |
numhosts = self.network.numhosts |
|
248 |
self.reservations = bitarray(numhosts) |
|
249 |
self.reservations.setall(False) |
|
250 |
self.reservations[0] = True |
|
251 |
self.reservations[numhosts - 1] = True |
|
252 |
if self.gateway: |
|
253 |
self.reserve(self.gateway) |
|
254 |
|
|
255 |
def _contains(self, address): |
|
256 |
if address is None: |
|
257 |
return False |
|
258 |
addr = ipaddr.IPAddress(address) |
|
259 |
|
|
260 |
return (addr in self.network) |
|
261 |
|
|
262 |
def _address_index(self, address): |
|
263 |
"""Convert IP address to bitarray index |
|
264 |
|
|
265 |
""" |
|
266 |
if not self._contains(address): |
|
267 |
raise Exception("%s does not contain %s" % |
|
268 |
(str(self.network), address)) |
|
269 |
addr = ipaddr.IPAddress(address) |
|
270 |
|
|
271 |
return int(addr) - int(self.network.network) |
|
272 |
|
|
273 |
def _mark(self, address, value): |
|
274 |
index = self._address_index(address) |
|
275 |
self.reservations[index] = value |
|
276 |
|
|
277 |
def reserve(self, address): |
|
278 |
self._mark(address, True) |
|
279 |
|
|
280 |
def release(self, address): |
|
281 |
self._mark(address, False) |
|
282 |
|
|
283 |
def is_reserved(self, address): |
|
284 |
index = self._address_index(address) |
|
285 |
return self.reservations[index] |
|
286 |
|
|
287 |
def is_full(self): |
|
288 |
return self.reservations.all() |
|
289 |
|
|
290 |
def count_reserved(self): |
|
291 |
return self.reservations.count(True) |
|
292 |
|
|
293 |
def count_free(self): |
|
294 |
return self.reservations.count(False) |
|
295 |
|
|
296 |
def get_map(self): |
|
297 |
return self.reservations.to01().replace("1", "X").replace("0", ".") |
|
298 |
|
|
299 |
def get_free_address(self): |
|
300 |
"""Get the first available address.""" |
|
301 |
if self.is_full(): |
|
302 |
raise IPPool.IPPoolExhausted("%s if full" % str(self.network)) |
|
303 |
|
|
304 |
index = self.reservations.index(False) |
|
305 |
address = str(self.network[index]) |
|
306 |
self.reserve(address) |
|
307 |
return address |
|
308 |
|
|
309 |
def save(self): |
|
310 |
"""Update the Network model and save it to DB.""" |
|
311 |
self._update_network() |
|
312 |
self.net.save() |
|
313 |
|
|
314 |
def _update_network(self): |
|
315 |
self.net.reservations = b64encode(self.reservations.tostring()) |
|
224 |
def value_to_index(self, value): |
|
225 |
addr = ipaddr.IPAddress(value) |
|
226 |
return int(addr) - int(self.net.network) |
|
316 | 227 |
|
317 |
class IPPoolExhausted(Exception): |
|
318 |
pass |
|
228 |
def index_to_value(self, index): |
|
229 |
return str(self.net[index]) |
b/snf-cyclades-app/synnefo/logic/allocators/default_allocator.py | ||
---|---|---|
75 | 75 |
def has_free_ip(backend): |
76 | 76 |
"""Find if Backend has any free public IP.""" |
77 | 77 |
for network in backend_public_networks(backend): |
78 |
if not network.pool.is_full():
|
|
78 |
if not network.get_pool().empty():
|
|
79 | 79 |
return True |
80 | 80 |
return False |
b/snf-cyclades-app/synnefo/logic/backend.py | ||
---|---|---|
41 | 41 |
from synnefo.db.models import (Backend, VirtualMachine, Network, |
42 | 42 |
BackendNetwork, BACKEND_STATUSES) |
43 | 43 |
from synnefo.logic import utils |
44 |
from synnefo.db.pools import IPPool
|
|
44 |
from synnefo.db.pools import EmptyPool
|
|
45 | 45 |
from synnefo.api.faults import OverLimit |
46 | 46 |
from synnefo.api.util import backend_public_networks, get_network_free_address |
47 | 47 |
from synnefo.util.rapi import GanetiRapiClient |
... | ... | |
118 | 118 |
Update the state of the VM in the DB accordingly. |
119 | 119 |
""" |
120 | 120 |
|
121 |
# Release the ips of the old nics. Get back the networks as multiple |
|
122 |
# changes in the same network, must happen in the same Network object, |
|
123 |
# because transaction will be commited only on exit of the function. |
|
124 |
networks = release_instance_nics(vm) |
|
121 |
release_instance_nics(vm) |
|
125 | 122 |
|
126 | 123 |
new_nics = enumerate(nics) |
127 | 124 |
for i, new_nic in new_nics: |
... | ... | |
129 | 126 |
n = str(network) |
130 | 127 |
pk = utils.id_from_network_name(n) |
131 | 128 |
|
132 |
# Get the cached Network or get it from DB |
|
133 |
if pk in networks: |
|
134 |
net = networks[pk] |
|
135 |
else: |
|
136 |
net = Network.objects.select_for_update().get(pk=pk) |
|
129 |
net = Network.objects.get(pk=pk) |
|
137 | 130 |
|
138 | 131 |
# Get the new nic info |
139 | 132 |
mac = new_nic.get('mac', '') |
... | ... | |
162 | 155 |
|
163 | 156 |
|
164 | 157 |
def release_instance_nics(vm): |
165 |
networks = {} |
|
166 |
|
|
167 | 158 |
for nic in vm.nics.all(): |
168 |
pk = nic.network.pk |
|
169 |
# Get the cached Network or get it from DB |
|
170 |
if pk in networks: |
|
171 |
net = networks[pk] |
|
172 |
else: |
|
173 |
# Get the network object in exclusive mode in order |
|
174 |
# to guarantee consistency of the address pool |
|
175 |
net = Network.objects.select_for_update().get(pk=pk) |
|
176 |
if nic.ipv4: |
|
177 |
net.release_address(nic.ipv4) |
|
159 |
nic.network.release_address(nic.ipv4) |
|
178 | 160 |
nic.delete() |
179 | 161 |
|
180 |
return networks |
|
181 |
|
|
182 | 162 |
|
183 | 163 |
@transaction.commit_on_success |
184 | 164 |
def process_network_status(back_network, etime, jobid, opcode, status, logmsg): |
... | ... | |
367 | 347 |
try: |
368 | 348 |
address = get_network_free_address(network) |
369 | 349 |
return (network, address) |
370 |
except IPPool.IPPoolExhausted:
|
|
350 |
except EmptyPool:
|
|
371 | 351 |
pass |
372 | 352 |
return (None, None) |
373 | 353 |
|
b/snf-cyclades-app/synnefo/logic/management/commands/network-inspect.py | ||
---|---|---|
63 | 63 |
str(net.subnet), str(net.gateway), str(net.mac_prefix), |
64 | 64 |
str(net.link), str(net.public), str(net.dhcp), |
65 | 65 |
str(net.type), str(net.deleted), str(net.action), |
66 |
str(splitPoolMap(net.pool.get_map(), 64)))
|
|
66 |
str(splitPoolMap(net.get_pool().to_map(), 64)))
|
|
67 | 67 |
|
68 | 68 |
self.stdout.write(sep) |
69 | 69 |
self.stdout.write('State of Network in DB\n') |
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