Revision fd65ab41
b/snf-cyclades-app/synnefo/db/migrations/0039_auto__add_backendnetwork__del_field_network_backendtime__del_field_net.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 'BackendNetwork' |
|
12 |
db.create_table('db_backendnetwork', ( |
|
13 |
('backendtime', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime(1, 1, 1, 0, 0))), |
|
14 |
('updated', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)), |
|
15 |
('network', self.gf('django.db.models.fields.related.ForeignKey')(related_name='backend_networks', to=orm['db.Network'])), |
|
16 |
('created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), |
|
17 |
('deleted', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)), |
|
18 |
('backendopcode', self.gf('django.db.models.fields.CharField')(max_length=30, null=True)), |
|
19 |
('operstate', self.gf('django.db.models.fields.CharField')(default='PENDING', max_length=30)), |
|
20 |
('backendjobid', self.gf('django.db.models.fields.PositiveIntegerField')(null=True)), |
|
21 |
('backendlogmsg', self.gf('django.db.models.fields.TextField')(null=True)), |
|
22 |
('backendjobstatus', self.gf('django.db.models.fields.CharField')(max_length=30, null=True)), |
|
23 |
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), |
|
24 |
('backend', self.gf('django.db.models.fields.related.ForeignKey')(related_name='networks', to=orm['db.Backend'])), |
|
25 |
)) |
|
26 |
db.send_create_signal('db', ['BackendNetwork']) |
|
27 |
|
|
28 |
# Deleting field 'Network.backendtime' |
|
29 |
db.delete_column('db_network', 'backendtime') |
|
30 |
|
|
31 |
# Deleting field 'Network.backendopcode' |
|
32 |
db.delete_column('db_network', 'backendopcode') |
|
33 |
|
|
34 |
# Deleting field 'Network.backendlogmsg' |
|
35 |
db.delete_column('db_network', 'backendlogmsg') |
|
36 |
|
|
37 |
# Deleting field 'Network.backendjobid' |
|
38 |
db.delete_column('db_network', 'backendjobid') |
|
39 |
|
|
40 |
# Deleting field 'Network.backendjobstatus' |
|
41 |
db.delete_column('db_network', 'backendjobstatus') |
|
42 |
|
|
43 |
# Changing field 'Network.mac_prefix' |
|
44 |
db.alter_column('db_network', 'mac_prefix', self.gf('django.db.models.fields.CharField')(max_length=32, null=True)) |
|
45 |
|
|
46 |
# Changing field 'Network.state' |
|
47 |
db.alter_column('db_network', 'state', self.gf('django.db.models.fields.CharField')(max_length=32)) |
|
48 |
|
|
49 |
# Changing field 'Network.action' |
|
50 |
db.alter_column('db_network', 'action', self.gf('django.db.models.fields.CharField')(max_length=32, null=True)) |
|
51 |
|
|
52 |
|
|
53 |
def backwards(self, orm): |
|
54 |
|
|
55 |
# Deleting model 'BackendNetwork' |
|
56 |
db.delete_table('db_backendnetwork') |
|
57 |
|
|
58 |
# Adding field 'Network.backendtime' |
|
59 |
db.add_column('db_network', 'backendtime', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime(1, 1, 1, 0, 0)), keep_default=False) |
|
60 |
|
|
61 |
# Adding field 'Network.backendopcode' |
|
62 |
db.add_column('db_network', 'backendopcode', self.gf('django.db.models.fields.CharField')(max_length=30, null=True), keep_default=False) |
|
63 |
|
|
64 |
# Adding field 'Network.backendlogmsg' |
|
65 |
db.add_column('db_network', 'backendlogmsg', self.gf('django.db.models.fields.TextField')(null=True), keep_default=False) |
|
66 |
|
|
67 |
# Adding field 'Network.backendjobid' |
|
68 |
db.add_column('db_network', 'backendjobid', self.gf('django.db.models.fields.PositiveIntegerField')(null=True), keep_default=False) |
|
69 |
|
|
70 |
# Adding field 'Network.backendjobstatus' |
|
71 |
db.add_column('db_network', 'backendjobstatus', self.gf('django.db.models.fields.CharField')(max_length=30, null=True), keep_default=False) |
|
72 |
|
|
73 |
# Changing field 'Network.mac_prefix' |
|
74 |
db.alter_column('db_network', 'mac_prefix', self.gf('django.db.models.fields.CharField')(max_length=128, null=True)) |
|
75 |
|
|
76 |
# Changing field 'Network.state' |
|
77 |
db.alter_column('db_network', 'state', self.gf('django.db.models.fields.CharField')(max_length=30)) |
|
78 |
|
|
79 |
# Changing field 'Network.action' |
|
80 |
db.alter_column('db_network', 'action', self.gf('django.db.models.fields.CharField')(max_length=30, null=True)) |
|
81 |
|
|
82 |
|
|
83 |
models = { |
|
84 |
'db.backend': { |
|
85 |
'Meta': {'object_name': 'Backend'}, |
|
86 |
'clustername': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}), |
|
87 |
'ctotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
88 |
'dfree': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
89 |
'drained': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
90 |
'dtotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
91 |
'hash': ('django.db.models.fields.CharField', [], {'max_length': '40'}), |
|
92 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
93 |
'mfree': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
94 |
'mtotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
95 |
'offline': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
96 |
'password': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), |
|
97 |
'pinst_cnt': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), |
|
98 |
'port': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5080'}), |
|
99 |
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
|
100 |
'username': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}) |
|
101 |
}, |
|
102 |
'db.backendnetwork': { |
|
103 |
'Meta': {'object_name': 'BackendNetwork'}, |
|
104 |
'backend': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'networks'", 'to': "orm['db.Backend']"}), |
|
105 |
'backendjobid': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), |
|
106 |
'backendjobstatus': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
107 |
'backendlogmsg': ('django.db.models.fields.TextField', [], {'null': 'True'}), |
|
108 |
'backendopcode': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
109 |
'backendtime': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(1, 1, 1, 0, 0)'}), |
|
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 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
113 |
'network': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'backend_networks'", 'to': "orm['db.Network']"}), |
|
114 |
'operstate': ('django.db.models.fields.CharField', [], {'default': "'PENDING'", 'max_length': '30'}), |
|
115 |
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) |
|
116 |
}, |
|
117 |
'db.bridgepool': { |
|
118 |
'Meta': {'object_name': 'BridgePool'}, |
|
119 |
'available': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), |
|
120 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
121 |
'index': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}), |
|
122 |
'value': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}) |
|
123 |
}, |
|
124 |
'db.flavor': { |
|
125 |
'Meta': {'unique_together': "(('cpu', 'ram', 'disk', 'disk_template'),)", 'object_name': 'Flavor'}, |
|
126 |
'cpu': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
127 |
'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
128 |
'disk': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
129 |
'disk_template': ('django.db.models.fields.CharField', [], {'default': "'drbd'", 'max_length': '32'}), |
|
130 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
131 |
'ram': ('django.db.models.fields.IntegerField', [], {'default': '0'}) |
|
132 |
}, |
|
133 |
'db.macprefixpool': { |
|
134 |
'Meta': {'object_name': 'MacPrefixPool'}, |
|
135 |
'available': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), |
|
136 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
137 |
'index': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}), |
|
138 |
'value': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}) |
|
139 |
}, |
|
140 |
'db.network': { |
|
141 |
'Meta': {'object_name': 'Network'}, |
|
142 |
'action': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '32', 'null': 'True'}), |
|
143 |
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
|
144 |
'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
145 |
'dhcp': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), |
|
146 |
'gateway': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), |
|
147 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
148 |
'link': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}), |
|
149 |
'mac_prefix': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), |
|
150 |
'machines': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['db.VirtualMachine']", 'through': "orm['db.NetworkInterface']", 'symmetrical': 'False'}), |
|
151 |
'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}), |
|
152 |
'public': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
153 |
'state': ('django.db.models.fields.CharField', [], {'default': "'PENDING'", 'max_length': '32'}), |
|
154 |
'subnet': ('django.db.models.fields.CharField', [], {'default': "'10.0.0.0/24'", 'max_length': '32'}), |
|
155 |
'type': ('django.db.models.fields.CharField', [], {'default': "'PRIVATE_VLAN'", 'max_length': '50'}), |
|
156 |
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), |
|
157 |
'userid': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}) |
|
158 |
}, |
|
159 |
'db.networkinterface': { |
|
160 |
'Meta': {'object_name': 'NetworkInterface'}, |
|
161 |
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
|
162 |
'firewall_profile': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
163 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
164 |
'index': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), |
|
165 |
'ipv4': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True'}), |
|
166 |
'ipv6': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), |
|
167 |
'mac': ('django.db.models.fields.CharField', [], {'max_length': '17', 'null': 'True'}), |
|
168 |
'machine': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nics'", 'to': "orm['db.VirtualMachine']"}), |
|
169 |
'network': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nics'", 'to': "orm['db.Network']"}), |
|
170 |
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) |
|
171 |
}, |
|
172 |
'db.virtualmachine': { |
|
173 |
'Meta': {'object_name': 'VirtualMachine'}, |
|
174 |
'action': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
175 |
'backend': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'virtual_machines'", 'null': 'True', 'to': "orm['db.Backend']"}), |
|
176 |
'backend_hash': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}), |
|
177 |
'backendjobid': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), |
|
178 |
'backendjobstatus': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
179 |
'backendlogmsg': ('django.db.models.fields.TextField', [], {'null': 'True'}), |
|
180 |
'backendopcode': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
181 |
'backendtime': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(1, 1, 1, 0, 0)'}), |
|
182 |
'buildpercentage': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
183 |
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
|
184 |
'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
185 |
'flavor': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.Flavor']"}), |
|
186 |
'hostid': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
|
187 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
188 |
'imageid': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
|
189 |
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
190 |
'operstate': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}), |
|
191 |
'suspended': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
192 |
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), |
|
193 |
'userid': ('django.db.models.fields.CharField', [], {'max_length': '100'}) |
|
194 |
}, |
|
195 |
'db.virtualmachinemetadata': { |
|
196 |
'Meta': {'unique_together': "(('meta_key', 'vm'),)", 'object_name': 'VirtualMachineMetadata'}, |
|
197 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
198 |
'meta_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}), |
|
199 |
'meta_value': ('django.db.models.fields.CharField', [], {'max_length': '500'}), |
|
200 |
'vm': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'metadata'", 'to': "orm['db.VirtualMachine']"}) |
|
201 |
} |
|
202 |
} |
|
203 |
|
|
204 |
complete_apps = ['db'] |
b/snf-cyclades-app/synnefo/db/models.py | ||
---|---|---|
184 | 184 |
"with backend: %s" % self) |
185 | 185 |
else: |
186 | 186 |
# ON_DELETE = SET NULL |
187 |
self.virtual_machines.all().backend=None
|
|
187 |
self.virtual_machines.all().backend = None
|
|
188 | 188 |
super(Backend, self).delete(*args, **kwargs) |
189 | 189 |
|
190 | 190 |
|
191 |
# A backend job may be in one of the following possible states |
|
192 |
BACKEND_STATUSES = ( |
|
193 |
('queued', 'request queued'), |
|
194 |
('waiting', 'request waiting for locks'), |
|
195 |
('canceling', 'request being canceled'), |
|
196 |
('running', 'request running'), |
|
197 |
('canceled', 'request canceled'), |
|
198 |
('success', 'request completed successfully'), |
|
199 |
('error', 'request returned error') |
|
200 |
) |
|
201 |
|
|
202 |
|
|
191 | 203 |
class VirtualMachine(models.Model): |
192 | 204 |
# The list of possible actions for a VM |
193 | 205 |
ACTIONS = ( |
... | ... | |
230 | 242 |
('OP_INSTANCE_FAILOVER', 'Failover Instance') |
231 | 243 |
) |
232 | 244 |
|
233 |
# A backend job may be in one of the following possible states |
|
234 |
BACKEND_STATUSES = ( |
|
235 |
('queued', 'request queued'), |
|
236 |
('waiting', 'request waiting for locks'), |
|
237 |
('canceling', 'request being canceled'), |
|
238 |
('running', 'request running'), |
|
239 |
('canceled', 'request canceled'), |
|
240 |
('success', 'request completed successfully'), |
|
241 |
('error', 'request returned error') |
|
242 |
) |
|
243 | 245 |
|
244 | 246 |
# The operating state of a VM, |
245 | 247 |
# upon the successful completion of a backend operation. |
... | ... | |
406 | 408 |
('DESTROY', 'Destroy Network'), |
407 | 409 |
) |
408 | 410 |
|
409 |
# The list of possible operations on the backend |
|
410 |
BACKEND_OPCODES = ( |
|
411 |
('OP_NETWORK_ADD', 'Create Network'), |
|
412 |
('OP_NETWORK_CONNECT', 'Activate Network'), |
|
413 |
('OP_NETWORK_DISCONNECT', 'Deactivate Network'), |
|
414 |
('OP_NETWORK_REMOVE', 'Remove Network') |
|
415 |
) |
|
416 |
|
|
417 |
# A backend job may be in one of the following possible states |
|
418 |
BACKEND_STATUSES = ( |
|
419 |
('success', 'request completed successfully'), |
|
420 |
('error', 'request returned error') |
|
421 |
) |
|
422 |
|
|
423 |
# The operating state of a Network, |
|
424 |
# upon the successful completion of a backend operation. |
|
425 |
# IMPORTANT: Make sure all keys have a corresponding |
|
426 |
# entry in BACKEND_OPCODES if you update this field, see #1035, #1111. |
|
427 |
OPER_STATE_FROM_OPCODE = { |
|
428 |
'OP_NETWORK_ADD': 'PENDING', |
|
429 |
'OP_NETWORK_CONNECT': 'ACTIVE', |
|
430 |
'OP_NETWORK_DISCONNECT': 'PENDING', |
|
431 |
'OP_NETWORK_REMOVE': 'DELETED' |
|
432 |
} |
|
433 |
|
|
434 | 411 |
RSAPI_STATE_FROM_OPER_STATE = { |
435 | 412 |
'PENDING': 'PENDING', |
436 | 413 |
'ACTIVE': 'ACTIVE', |
... | ... | |
445 | 422 |
) |
446 | 423 |
|
447 | 424 |
NETWORK_TAGS = { |
448 |
'PUBLIC_ROUTED': ['public-routed'],
|
|
449 |
'PRIVATE_VLAN': ['private-vlan'],
|
|
450 |
'PRIVATE_FILTERED': ['private-filtered']
|
|
425 |
'PUBLIC_ROUTED': ['ip-less-routed'],
|
|
426 |
'PRIVATE_VLAN': ['physical-vlan'],
|
|
427 |
'PRIVATE_FILTERED': ['mac-filtered']
|
|
451 | 428 |
} |
452 | 429 |
|
453 | 430 |
name = models.CharField('Network Name', max_length=128) |
... | ... | |
457 | 434 |
dhcp = models.BooleanField('DHCP', default=True) |
458 | 435 |
type = models.CharField(choices=NETWORK_TYPES, max_length=50, default='PRIVATE_VLAN') |
459 | 436 |
link = models.CharField('Network Link', max_length=128, null=True) |
460 |
mac_prefix = models.CharField('MAC Prefix', max_length=128, null=True)
|
|
437 |
mac_prefix = models.CharField('MAC Prefix', max_length=32, null=True)
|
|
461 | 438 |
public = models.BooleanField(default=False) |
462 | 439 |
created = models.DateTimeField(auto_now_add=True) |
463 | 440 |
updated = models.DateTimeField(auto_now=True) |
464 | 441 |
deleted = models.BooleanField('Deleted', default=False) |
465 |
state = models.CharField(choices=OPER_STATES, max_length=30, default='PENDING') |
|
442 |
state = models.CharField(choices=OPER_STATES, max_length=32, |
|
443 |
default='PENDING') |
|
466 | 444 |
machines = models.ManyToManyField(VirtualMachine, |
467 | 445 |
through='NetworkInterface') |
468 |
|
|
469 |
action = models.CharField(choices=ACTIONS, max_length=30, null=True) |
|
470 |
backendjobid = models.PositiveIntegerField(null=True) |
|
471 |
backendopcode = models.CharField(choices=BACKEND_OPCODES, max_length=30, |
|
472 |
null=True) |
|
473 |
backendjobstatus = models.CharField(choices=BACKEND_STATUSES, |
|
474 |
max_length=30, null=True) |
|
475 |
backendlogmsg = models.TextField(null=True) |
|
476 |
backendtime = models.DateTimeField(default=datetime.datetime.min) |
|
477 |
|
|
446 |
action = models.CharField(choices=ACTIONS, max_length=32, null=True, |
|
447 |
default=None) |
|
478 | 448 |
|
479 | 449 |
class InvalidBackendIdError(Exception): |
480 |
def __init__(self, value):
|
|
450 |
def __init__(self, value): |
|
481 | 451 |
self.value = value |
482 |
def __str__(self): |
|
452 |
|
|
453 |
def __str__(self): |
|
483 | 454 |
return repr(self.value) |
484 | 455 |
|
485 | 456 |
|
486 | 457 |
class InvalidBackendMsgError(Exception): |
487 |
def __init__(self, opcode, status):
|
|
458 |
def __init__(self, opcode, status): |
|
488 | 459 |
self.opcode = opcode |
489 | 460 |
self.status = status |
490 |
def __str__(self): |
|
461 |
|
|
462 |
def __str__(self): |
|
491 | 463 |
return repr('<opcode: %s, status: %s>' % (self.opcode, |
492 | 464 |
self.status)) |
493 | 465 |
|
494 | 466 |
class InvalidActionError(Exception): |
495 |
def __init__(self, action):
|
|
467 |
def __init__(self, action): |
|
496 | 468 |
self._action = action |
497 |
def __str__(self): |
|
498 |
return repr(str(self._action)) |
|
499 | 469 |
|
500 |
def __init__(self, *args, **kw): |
|
501 |
"""Initialize state for just created Network instances.""" |
|
502 |
super(Network, self).__init__(*args, **kw) |
|
503 |
# This gets called BEFORE an instance gets save()d for |
|
504 |
# the first time. |
|
505 |
if not self.pk: |
|
506 |
self.action = None |
|
507 |
self.backendjobid = None |
|
508 |
self.backendjobstatus = None |
|
509 |
self.backendopcode = None |
|
510 |
self.backendlogmsg = None |
|
511 |
self.backendtime = datetime.datetime.min |
|
470 |
def __str__(self): |
|
471 |
return repr(str(self._action)) |
|
512 | 472 |
|
513 | 473 |
@property |
514 | 474 |
def backend_id(self): |
515 |
"""Returns the backend id for this Network by prepending backend-prefix."""
|
|
475 |
"""Return the backend id by prepending backend-prefix."""
|
|
516 | 476 |
if not self.id: |
517 | 477 |
raise Network.InvalidBackendIdError("self.id is None") |
518 | 478 |
return '%s%s' % (settings.BACKEND_PREFIX_ID, self.id) |
... | ... | |
527 | 487 |
def __unicode__(self): |
528 | 488 |
return self.name |
529 | 489 |
|
490 |
def update_oper_state(self): |
|
491 |
"""Update operstate of the Network. |
|
492 |
|
|
493 |
Update the operstate of the Network depending on the related |
|
494 |
backend_networks. When backend networks do not have the same operstate, |
|
495 |
the Network's operstate is PENDING. Otherwise it is the same with |
|
496 |
the BackendNetworks operstate. |
|
497 |
|
|
498 |
""" |
|
499 |
backend_states = [s.operstate for s in self.backend_networks.all()] |
|
500 |
if not backend_states: |
|
501 |
self.operstate = 'PENDING' |
|
502 |
self.save() |
|
503 |
return |
|
504 |
|
|
505 |
all_equal = len(set(backend_states)) <= 1 |
|
506 |
self.operstate = all_equal and backend_states[0] or 'PENDING' |
|
507 |
|
|
508 |
if self.operstate == 'DELETED': |
|
509 |
self.deleted = True |
|
510 |
|
|
511 |
self.save() |
|
512 |
|
|
513 |
def save(self, *args, **kwargs): |
|
514 |
pk = self.pk |
|
515 |
super(Network, self).save(*args, **kwargs) |
|
516 |
if not pk: |
|
517 |
# In case of a new Network, corresponding BackendNetwork's must |
|
518 |
# be created! |
|
519 |
for back in Backend.objects.all(): |
|
520 |
BackendNetwork.objects.create(backend=back, network=self) |
|
521 |
|
|
522 |
|
|
523 |
class BackendNetwork(models.Model): |
|
524 |
OPER_STATES = ( |
|
525 |
('PENDING', 'Pending'), |
|
526 |
('ACTIVE', 'Active'), |
|
527 |
('DELETED', 'Deleted'), |
|
528 |
('ERROR', 'Error') |
|
529 |
) |
|
530 |
|
|
531 |
# The list of possible operations on the backend |
|
532 |
BACKEND_OPCODES = ( |
|
533 |
('OP_NETWORK_ADD', 'Create Network'), |
|
534 |
('OP_NETWORK_CONNECT', 'Activate Network'), |
|
535 |
('OP_NETWORK_DISCONNECT', 'Deactivate Network'), |
|
536 |
('OP_NETWORK_REMOVE', 'Remove Network'), |
|
537 |
# These are listed here for completeness, |
|
538 |
# and are ignored for the time being |
|
539 |
('OP_NETWORK_SET_PARAMS', 'Set Network Parameters'), |
|
540 |
('OP_NETWORK_QUERY_DATA', 'Query Network Data') |
|
541 |
) |
|
542 |
|
|
543 |
# The operating state of a Netowork, |
|
544 |
# upon the successful completion of a backend operation. |
|
545 |
# IMPORTANT: Make sure all keys have a corresponding |
|
546 |
# entry in BACKEND_OPCODES if you update this field, see #1035, #1111. |
|
547 |
OPER_STATE_FROM_OPCODE = { |
|
548 |
'OP_NETWORK_ADD': 'PENDING', |
|
549 |
'OP_NETWORK_CONNECT': 'ACTIVE', |
|
550 |
'OP_NETWORK_DISCONNECT': 'PENDING', |
|
551 |
'OP_NETWORK_REMOVE': 'DELETED', |
|
552 |
'OP_NETWORK_SET_PARAMS': None, |
|
553 |
'OP_NETWORK_QUERY_DATA': None |
|
554 |
} |
|
555 |
|
|
556 |
network = models.ForeignKey(Network, related_name='backend_networks') |
|
557 |
backend = models.ForeignKey(Backend, related_name='networks') |
|
558 |
created = models.DateTimeField(auto_now_add=True) |
|
559 |
updated = models.DateTimeField(auto_now=True) |
|
560 |
deleted = models.BooleanField('Deleted', default=False) |
|
561 |
operstate = models.CharField(choices=OPER_STATES, max_length=30, |
|
562 |
default='PENDING') |
|
563 |
backendjobid = models.PositiveIntegerField(null=True) |
|
564 |
backendopcode = models.CharField(choices=BACKEND_OPCODES, max_length=30, |
|
565 |
null=True) |
|
566 |
backendjobstatus = models.CharField(choices=BACKEND_STATUSES, |
|
567 |
max_length=30, null=True) |
|
568 |
backendlogmsg = models.TextField(null=True) |
|
569 |
backendtime = models.DateTimeField(null=False, |
|
570 |
default=datetime.datetime.min) |
|
571 |
|
|
572 |
def save(self, *args, **kwargs): |
|
573 |
super(BackendNetwork, self).save(*args, **kwargs) |
|
574 |
self.network.update_oper_state() |
|
575 |
|
|
576 |
def delete(self, *args, **kwargs): |
|
577 |
super(BackendNetwork, self).delete(*args, **kwargs) |
|
578 |
self.network.update_oper_state() |
|
579 |
|
|
530 | 580 |
|
531 | 581 |
class NetworkInterface(models.Model): |
532 | 582 |
FIREWALL_PROFILES = ( |
b/snf-cyclades-app/synnefo/logic/backend.py | ||
---|---|---|
38 | 38 |
from django.db import transaction |
39 | 39 |
from datetime import datetime |
40 | 40 |
|
41 |
from synnefo.db.models import (Backend, VirtualMachine, Network, NetworkLink) |
|
41 |
from synnefo.db.models import (Backend, VirtualMachine, Network, NetworkLink, |
|
42 |
BACKEND_STATUSES) |
|
42 | 43 |
from synnefo.logic import utils |
43 | 44 |
from synnefo.util.rapi import GanetiRapiClient |
44 | 45 |
|
... | ... | |
69 | 70 |
""" |
70 | 71 |
# See #1492, #1031, #1111 why this line has been removed |
71 | 72 |
#if (opcode not in [x[0] for x in VirtualMachine.BACKEND_OPCODES] or |
72 |
if status not in [x[0] for x in VirtualMachine.BACKEND_STATUSES]:
|
|
73 |
if status not in [x[0] for x in BACKEND_STATUSES]: |
|
73 | 74 |
raise VirtualMachine.InvalidBackendMsgError(opcode, status) |
74 | 75 |
|
75 | 76 |
vm.backendjobid = jobid |
Also available in: Unified diff