Revision e6a42a96

b/snf-cyclades-app/synnefo/app_settings/default/api.py
27 27
# This link id is assigned to NICs that should be isolated from anything else
28 28
# (e.g., right before the NIC gets deleted).
29 29
# This value is also hardcoded in a fixture in db/fixtures/initial_data.json.
30
GANETI_NULL_LINK = 'snf_null'
30
GANETI_NULL_LINK = 'snf_public'
31 31

  
32 32
# The pool of private network links to use is
33 33
# $GANETI_LINK_PREFIX{1..$GANETI_MAX_LINK_NUMBER}.
......
36 36
GANETI_LINK_PREFIX = 'prv'
37 37
# The number of private network links to use.
38 38
GANETI_MAX_LINK_NUMBER = 100
39
# The first mac prefix to use
40
GANETI_BASE_MAC_PREFIX = 'aa:00:01'
41
# The number of mac prefixes to use.
42
GANETI_MAX_MAC_PREFIX_NUMBER = 4096
43

  
39 44
# Firewalling
40 45
GANETI_FIREWALL_ENABLED_TAG = 'synnefo:network:0:protected'
41 46
GANETI_FIREWALL_DISABLED_TAG = 'synnefo:network:0:unprotected'
42 47
GANETI_FIREWALL_PROTECTED_TAG = 'synnefo:network:0:limited'
43 48

  
49

  
44 50
# The default firewall profile that will be in effect if no tags are defined
45 51
DEFAULT_FIREWALL_PROFILE = 'DISABLED'
46 52

  
b/snf-cyclades-app/synnefo/db/fixtures/initial_data.json
1 1
[
2 2
    {
3
        "model": "db.NetworkLink",
4
        "pk": 1,
5
        "fields": {
6
            "index": 0,
7
            "name": "snf_null",
8
            "available": 0
9
        }
10
    },
11
    {
12 3
        "model": "db.Network",
13 4
        "pk": 1,
14 5
        "fields": {
......
17 8
            "updated": "2011-04-01",
18 9
            "state": "ACTIVE",
19 10
            "public": 1,
20
            "link": 1
11
            "link": "snf_public",
12
            "dhcp": 1,
13
            "type": "PUBLIC_ROUTED"
21 14
        }
22 15
    }
23 16
]
b/snf-cyclades-app/synnefo/db/migrations/0036_auto__add_bridgepool__add_macprefixpool__add_field_network_backendtime.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 'BridgePool'
12
        db.create_table('db_bridgepool', (
13
            ('available', self.gf('django.db.models.fields.BooleanField')(default=True, blank=True)),
14
            ('index', self.gf('django.db.models.fields.IntegerField')(unique=True)),
15
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
16
            ('value', self.gf('django.db.models.fields.CharField')(unique=True, max_length=128)),
17
        ))
18
        db.send_create_signal('db', ['BridgePool'])
19

  
20
        # Adding model 'MacPrefixPool'
21
        db.create_table('db_macprefixpool', (
22
            ('available', self.gf('django.db.models.fields.BooleanField')(default=True, blank=True)),
23
            ('index', self.gf('django.db.models.fields.IntegerField')(unique=True)),
24
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
25
            ('value', self.gf('django.db.models.fields.CharField')(unique=True, max_length=128)),
26
        ))
27
        db.send_create_signal('db', ['MacPrefixPool'])
28

  
29
        # Adding field 'Network.backendtime'
30
        db.add_column('db_network', 'backendtime', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime(1, 1, 1, 0, 0)), keep_default=False)
31

  
32
        # Adding field 'Network.subnet'
33
        db.add_column('db_network', 'subnet', self.gf('django.db.models.fields.CharField')(default='10.0.0.0/24', max_length=32), keep_default=False)
34

  
35
        # Adding field 'Network.netlink'
36
        db.add_column('db_network', 'netlink', self.gf('django.db.models.fields.CharField')(max_length=128, null=True), keep_default=False)
37

  
38
        # Adding field 'Network.deleted'
39
        db.add_column('db_network', 'deleted', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True), keep_default=False)
40

  
41
        # Adding field 'Network.backendlogmsg'
42
        db.add_column('db_network', 'backendlogmsg', self.gf('django.db.models.fields.TextField')(null=True), keep_default=False)
43

  
44
        # Adding field 'Network.mac_prefix'
45
        db.add_column('db_network', 'mac_prefix', self.gf('django.db.models.fields.CharField')(max_length=128, null=True), keep_default=False)
46

  
47
        # Adding field 'Network.backendopcode'
48
        db.add_column('db_network', 'backendopcode', self.gf('django.db.models.fields.CharField')(max_length=30, null=True), keep_default=False)
49

  
50
        # Adding field 'Network.backendjobid'
51
        db.add_column('db_network', 'backendjobid', self.gf('django.db.models.fields.PositiveIntegerField')(null=True), keep_default=False)
52

  
53
        # Adding field 'Network.action'
54
        db.add_column('db_network', 'action', self.gf('django.db.models.fields.CharField')(max_length=30, null=True), keep_default=False)
55

  
56
        # Adding field 'Network.dhcp'
57
        db.add_column('db_network', 'dhcp', self.gf('django.db.models.fields.BooleanField')(default=True, blank=True), keep_default=False)
58

  
59
        # Adding field 'Network.type'
60
        db.add_column('db_network', 'type', self.gf('django.db.models.fields.CharField')(default='PRIVATE_VLAN', max_length=50), keep_default=False)
61

  
62
        # Adding field 'Network.gateway'
63
        db.add_column('db_network', 'gateway', self.gf('django.db.models.fields.CharField')(max_length=32, null=True), keep_default=False)
64

  
65
        # Adding field 'Network.backendjobstatus'
66
        db.add_column('db_network', 'backendjobstatus', self.gf('django.db.models.fields.CharField')(max_length=30, null=True), keep_default=False)
67

  
68
        # Changing field 'Network.name'
69
        db.alter_column('db_network', 'name', self.gf('django.db.models.fields.CharField')(max_length=128))
70

  
71
        # Changing field 'Network.userid'
72
        db.alter_column('db_network', 'userid', self.gf('django.db.models.fields.CharField')(max_length=128, null=True))
73
    
74
    
75
    def backwards(self, orm):
76
        
77
        # Deleting model 'BridgePool'
78
        db.delete_table('db_bridgepool')
79

  
80
        # Deleting model 'MacPrefixPool'
81
        db.delete_table('db_macprefixpool')
82

  
83
        # Deleting field 'Network.backendtime'
84
        db.delete_column('db_network', 'backendtime')
85

  
86
        # Deleting field 'Network.subnet'
87
        db.delete_column('db_network', 'subnet')
88

  
89
        # Deleting field 'Network.netlink'
90
        db.delete_column('db_network', 'netlink')
91

  
92
        # Deleting field 'Network.deleted'
93
        db.delete_column('db_network', 'deleted')
94

  
95
        # Deleting field 'Network.backendlogmsg'
96
        db.delete_column('db_network', 'backendlogmsg')
97

  
98
        # Deleting field 'Network.mac_prefix'
99
        db.delete_column('db_network', 'mac_prefix')
100

  
101
        # Deleting field 'Network.backendopcode'
102
        db.delete_column('db_network', 'backendopcode')
103

  
104
        # Deleting field 'Network.backendjobid'
105
        db.delete_column('db_network', 'backendjobid')
106

  
107
        # Deleting field 'Network.action'
108
        db.delete_column('db_network', 'action')
109

  
110
        # Deleting field 'Network.dhcp'
111
        db.delete_column('db_network', 'dhcp')
112

  
113
        # Deleting field 'Network.type'
114
        db.delete_column('db_network', 'type')
115

  
116
        # Deleting field 'Network.gateway'
117
        db.delete_column('db_network', 'gateway')
118

  
119
        # Deleting field 'Network.backendjobstatus'
120
        db.delete_column('db_network', 'backendjobstatus')
121

  
122
        # Changing field 'Network.name'
123
        db.alter_column('db_network', 'name', self.gf('django.db.models.fields.CharField')(max_length=255))
124

  
125
        # Changing field 'Network.userid'
126
        db.alter_column('db_network', 'userid', self.gf('django.db.models.fields.CharField')(max_length=100, null=True))
127
    
128
    
129
    models = {
130
        'db.backend': {
131
            'Meta': {'object_name': 'Backend'},
132
            'clustername': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
133
            'ctotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
134
            'dfree': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
135
            'drained': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
136
            'dtotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
137
            'hash': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
138
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
139
            'mfree': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
140
            'mtotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
141
            'offline': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
142
            'password': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}),
143
            'pinst_cnt': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
144
            'port': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5080'}),
145
            'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
146
            'username': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'})
147
        },
148
        'db.bridgepool': {
149
            'Meta': {'object_name': 'BridgePool'},
150
            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
151
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
152
            'index': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}),
153
            'value': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'})
154
        },
155
        'db.flavor': {
156
            'Meta': {'unique_together': "(('cpu', 'ram', 'disk', 'disk_template'),)", 'object_name': 'Flavor'},
157
            'cpu': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
158
            'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
159
            'disk': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
160
            'disk_template': ('django.db.models.fields.CharField', [], {'default': "'drbd'", 'max_length': '32'}),
161
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
162
            'ram': ('django.db.models.fields.IntegerField', [], {'default': '0'})
163
        },
164
        'db.macprefixpool': {
165
            'Meta': {'object_name': 'MacPrefixPool'},
166
            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
167
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
168
            'index': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}),
169
            'value': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'})
170
        },
171
        'db.network': {
172
            'Meta': {'object_name': 'Network'},
173
            'action': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
174
            'backendjobid': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}),
175
            'backendjobstatus': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
176
            'backendlogmsg': ('django.db.models.fields.TextField', [], {'null': 'True'}),
177
            'backendopcode': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
178
            'backendtime': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(1, 1, 1, 0, 0)'}),
179
            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
180
            'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
181
            'dhcp': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
182
            'gateway': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
183
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
184
            'link': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['db.NetworkLink']"}),
185
            'mac_prefix': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}),
186
            'machines': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['db.VirtualMachine']", 'through': "orm['db.NetworkInterface']", 'symmetrical': 'False'}),
187
            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
188
            'netlink': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}),
189
            'public': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
190
            'state': ('django.db.models.fields.CharField', [], {'default': "'PENDING'", 'max_length': '30'}),
191
            'subnet': ('django.db.models.fields.CharField', [], {'default': "'10.0.0.0/24'", 'max_length': '32'}),
192
            'type': ('django.db.models.fields.CharField', [], {'default': "'PRIVATE_VLAN'", 'max_length': '50'}),
193
            'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
194
            'userid': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'})
195
        },
196
        'db.networkinterface': {
197
            'Meta': {'object_name': 'NetworkInterface'},
198
            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
199
            'firewall_profile': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
200
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
201
            'index': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
202
            'ipv4': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True'}),
203
            'ipv6': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}),
204
            'mac': ('django.db.models.fields.CharField', [], {'max_length': '17', 'null': 'True'}),
205
            'machine': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nics'", 'to': "orm['db.VirtualMachine']"}),
206
            'network': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nics'", 'to': "orm['db.Network']"}),
207
            'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
208
        },
209
        'db.networklink': {
210
            'Meta': {'object_name': 'NetworkLink'},
211
            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
212
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
213
            'index': ('django.db.models.fields.IntegerField', [], {}),
214
            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
215
            'network': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['db.Network']"})
216
        },
217
        'db.virtualmachine': {
218
            'Meta': {'object_name': 'VirtualMachine'},
219
            'action': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
220
            'backend': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'virtual_machines'", 'null': 'True', 'to': "orm['db.Backend']"}),
221
            'backend_hash': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}),
222
            'backendjobid': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}),
223
            'backendjobstatus': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
224
            'backendlogmsg': ('django.db.models.fields.TextField', [], {'null': 'True'}),
225
            'backendopcode': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
226
            'backendtime': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(1, 1, 1, 0, 0)'}),
227
            'buildpercentage': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
228
            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
229
            'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
230
            'flavor': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.Flavor']"}),
231
            'hostid': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
232
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
233
            'imageid': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
234
            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
235
            'operstate': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
236
            'suspended': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
237
            'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
238
            'userid': ('django.db.models.fields.CharField', [], {'max_length': '100'})
239
        },
240
        'db.virtualmachinemetadata': {
241
            'Meta': {'unique_together': "(('meta_key', 'vm'),)", 'object_name': 'VirtualMachineMetadata'},
242
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
243
            'meta_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
244
            'meta_value': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
245
            'vm': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'metadata'", 'to': "orm['db.VirtualMachine']"})
246
        }
247
    }
248
    
249
    complete_apps = ['db']
b/snf-cyclades-app/synnefo/db/migrations/0037_network_migration.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
from synnefo.db.models import BridgePool
7

  
8
class Migration(DataMigration):
9
    
10
    def forwards(self, orm):
11
        "Write your forwards methods here."
12
        for network in orm.Network.objects.all():
13
            if network.state == 'DELETED':
14
                network.deleted = True
15

  
16
            if network.public == True:
17
                # Public Network
18
                network.netlink = network.link.name
19
                network.dhcp = True
20
                network.type = 'PUBLIC_ROUTED'
21
            else:
22
                network.dhcp = False
23
                network.type = 'PRIVATE_VLAN'
24
                bridge = BridgePool.get_available()
25
                network.netlink = bridge.value
26

  
27
            network.save()
28
    
29
    
30
    def backwards(self, orm):
31
        "Write your backwards methods here."
32
        pass
33
    
34
    models = {
35
        'db.backend': {
36
            'Meta': {'object_name': 'Backend'},
37
            'clustername': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
38
            'ctotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
39
            'dfree': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
40
            'drained': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
41
            'dtotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
42
            'hash': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
43
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
44
            'mfree': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
45
            'mtotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
46
            'offline': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
47
            'password': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}),
48
            'pinst_cnt': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
49
            'port': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5080'}),
50
            'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
51
            'username': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'})
52
        },
53
        'db.bridgepool': {
54
            'Meta': {'object_name': 'BridgePool'},
55
            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
56
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
57
            'index': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}),
58
            'value': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'})
59
        },
60
        'db.flavor': {
61
            'Meta': {'unique_together': "(('cpu', 'ram', 'disk', 'disk_template'),)", 'object_name': 'Flavor'},
62
            'cpu': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
63
            'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
64
            'disk': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
65
            'disk_template': ('django.db.models.fields.CharField', [], {'default': "'drbd'", 'max_length': '32'}),
66
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
67
            'ram': ('django.db.models.fields.IntegerField', [], {'default': '0'})
68
        },
69
        'db.macprefixpool': {
70
            'Meta': {'object_name': 'MacPrefixPool'},
71
            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
72
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
73
            'index': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}),
74
            'value': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'})
75
        },
76
        'db.network': {
77
            'Meta': {'object_name': 'Network'},
78
            'action': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
79
            'backendjobid': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}),
80
            'backendjobstatus': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
81
            'backendlogmsg': ('django.db.models.fields.TextField', [], {'null': 'True'}),
82
            'backendopcode': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
83
            'backendtime': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(1, 1, 1, 0, 0)'}),
84
            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
85
            'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
86
            'dhcp': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
87
            'gateway': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
88
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
89
            'link': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['db.NetworkLink']"}),
90
            'mac_prefix': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}),
91
            'machines': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['db.VirtualMachine']", 'through': "orm['db.NetworkInterface']", 'symmetrical': 'False'}),
92
            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
93
            'netlink': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}),
94
            'public': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
95
            'state': ('django.db.models.fields.CharField', [], {'default': "'PENDING'", 'max_length': '30'}),
96
            'subnet': ('django.db.models.fields.CharField', [], {'default': "'10.0.0.0/24'", 'max_length': '32'}),
97
            'type': ('django.db.models.fields.CharField', [], {'default': "'PRIVATE_VLAN'", 'max_length': '50'}),
98
            'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
99
            'userid': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'})
100
        },
101
        'db.networkinterface': {
102
            'Meta': {'object_name': 'NetworkInterface'},
103
            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
104
            'firewall_profile': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
105
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
106
            'index': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
107
            'ipv4': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True'}),
108
            'ipv6': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}),
109
            'mac': ('django.db.models.fields.CharField', [], {'max_length': '17', 'null': 'True'}),
110
            'machine': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nics'", 'to': "orm['db.VirtualMachine']"}),
111
            'network': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nics'", 'to': "orm['db.Network']"}),
112
            'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
113
        },
114
        'db.networklink': {
115
            'Meta': {'object_name': 'NetworkLink'},
116
            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
117
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
118
            'index': ('django.db.models.fields.IntegerField', [], {}),
119
            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
120
            'network': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['db.Network']"})
121
        },
122
        'db.virtualmachine': {
123
            'Meta': {'object_name': 'VirtualMachine'},
124
            'action': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
125
            'backend': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'virtual_machines'", 'null': 'True', 'to': "orm['db.Backend']"}),
126
            'backend_hash': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}),
127
            'backendjobid': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}),
128
            'backendjobstatus': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
129
            'backendlogmsg': ('django.db.models.fields.TextField', [], {'null': 'True'}),
130
            'backendopcode': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
131
            'backendtime': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(1, 1, 1, 0, 0)'}),
132
            'buildpercentage': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
133
            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
134
            'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
135
            'flavor': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.Flavor']"}),
136
            'hostid': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
137
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
138
            'imageid': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
139
            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
140
            'operstate': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
141
            'suspended': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
142
            'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
143
            'userid': ('django.db.models.fields.CharField', [], {'max_length': '100'})
144
        },
145
        'db.virtualmachinemetadata': {
146
            'Meta': {'unique_together': "(('meta_key', 'vm'),)", 'object_name': 'VirtualMachineMetadata'},
147
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
148
            'meta_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
149
            'meta_value': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
150
            'vm': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'metadata'", 'to': "orm['db.VirtualMachine']"})
151
        }
152
    }
153
    
154
    complete_apps = ['db']
b/snf-cyclades-app/synnefo/db/migrations/0038_auto__del_networklink__del_field_network_netlink__chg_field_network_li.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.netlink'
12
        db.delete_column('db_network', 'link_id')
13

  
14
        # Renaming column for 'Network.link' to match new field type.
15
        db.rename_column('db_network', 'netlink', 'link')
16

  
17
        # Deleting model 'NetworkLink'
18
        db.delete_table('db_networklink')
19

  
20
    
21
    
22
    def backwards(self, orm):
23
        
24
        # Adding model 'NetworkLink'
25
        db.create_table('db_networklink', (
26
            ('available', self.gf('django.db.models.fields.BooleanField')(default=True, blank=True)),
27
            ('index', self.gf('django.db.models.fields.IntegerField')()),
28
            ('network', self.gf('django.db.models.fields.related.ForeignKey')(related_name='+', null=True, to=orm['db.Network'])),
29
            ('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
30
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
31
        ))
32
        db.send_create_signal('db', ['NetworkLink'])
33

  
34
        # Renaming column for 'Network.link' to match new field type.
35
        db.rename_column('db_network', 'link', 'netlink')
36

  
37
        # Add column 'Network.link_id'
38
        db.add_column('db_network', 'link_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['db.NetworkLink']))
39

  
40
        # Adding index on 'Network', fields ['link']
41
        db.create_index('db_network', ['link_id'])
42
    
43
    
44
    models = {
45
        'db.backend': {
46
            'Meta': {'object_name': 'Backend'},
47
            'clustername': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
48
            'ctotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
49
            'dfree': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
50
            'drained': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
51
            'dtotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
52
            'hash': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
53
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
54
            'mfree': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
55
            'mtotal': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
56
            'offline': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
57
            'password': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}),
58
            'pinst_cnt': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
59
            'port': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5080'}),
60
            'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
61
            'username': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'})
62
        },
63
        'db.bridgepool': {
64
            'Meta': {'object_name': 'BridgePool'},
65
            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
66
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
67
            'index': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}),
68
            'value': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'})
69
        },
70
        'db.flavor': {
71
            'Meta': {'unique_together': "(('cpu', 'ram', 'disk', 'disk_template'),)", 'object_name': 'Flavor'},
72
            'cpu': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
73
            'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
74
            'disk': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
75
            'disk_template': ('django.db.models.fields.CharField', [], {'default': "'drbd'", 'max_length': '32'}),
76
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
77
            'ram': ('django.db.models.fields.IntegerField', [], {'default': '0'})
78
        },
79
        'db.macprefixpool': {
80
            'Meta': {'object_name': 'MacPrefixPool'},
81
            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
82
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
83
            'index': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}),
84
            'value': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'})
85
        },
86
        'db.network': {
87
            'Meta': {'object_name': 'Network'},
88
            'action': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
89
            'backendjobid': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}),
90
            'backendjobstatus': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
91
            'backendlogmsg': ('django.db.models.fields.TextField', [], {'null': 'True'}),
92
            'backendopcode': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
93
            'backendtime': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(1, 1, 1, 0, 0)'}),
94
            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
95
            'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
96
            'dhcp': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
97
            'gateway': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
98
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
99
            'link': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}),
100
            'mac_prefix': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}),
101
            'machines': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['db.VirtualMachine']", 'through': "orm['db.NetworkInterface']", 'symmetrical': 'False'}),
102
            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
103
            'public': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
104
            'state': ('django.db.models.fields.CharField', [], {'default': "'PENDING'", 'max_length': '30'}),
105
            'subnet': ('django.db.models.fields.CharField', [], {'default': "'10.0.0.0/24'", 'max_length': '32'}),
106
            'type': ('django.db.models.fields.CharField', [], {'default': "'PRIVATE_VLAN'", 'max_length': '50'}),
107
            'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
108
            'userid': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'})
109
        },
110
        'db.networkinterface': {
111
            'Meta': {'object_name': 'NetworkInterface'},
112
            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
113
            'firewall_profile': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
114
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
115
            'index': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
116
            'ipv4': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True'}),
117
            'ipv6': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}),
118
            'mac': ('django.db.models.fields.CharField', [], {'max_length': '17', 'null': 'True'}),
119
            'machine': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nics'", 'to': "orm['db.VirtualMachine']"}),
120
            'network': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nics'", 'to': "orm['db.Network']"}),
121
            'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
122
        },
123
        'db.virtualmachine': {
124
            'Meta': {'object_name': 'VirtualMachine'},
125
            'action': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
126
            'backend': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'virtual_machines'", 'null': 'True', 'to': "orm['db.Backend']"}),
127
            'backend_hash': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}),
128
            'backendjobid': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}),
129
            'backendjobstatus': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
130
            'backendlogmsg': ('django.db.models.fields.TextField', [], {'null': 'True'}),
131
            'backendopcode': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
132
            'backendtime': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(1, 1, 1, 0, 0)'}),
133
            'buildpercentage': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
134
            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
135
            'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
136
            'flavor': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.Flavor']"}),
137
            'hostid': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
138
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
139
            'imageid': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
140
            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
141
            'operstate': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
142
            'suspended': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
143
            'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
144
            'userid': ('django.db.models.fields.CharField', [], {'max_length': '100'})
145
        },
146
        'db.virtualmachinemetadata': {
147
            'Meta': {'unique_together': "(('meta_key', 'vm'),)", 'object_name': 'VirtualMachineMetadata'},
148
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
149
            'meta_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
150
            'meta_value': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
151
            'vm': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'metadata'", 'to': "orm['db.VirtualMachine']"})
152
        }
153
    }
154
    
155
    complete_apps = ['db']
b/snf-cyclades-app/synnefo/db/models.py
36 36
from hashlib import sha1
37 37
from synnefo.api.faults import ServiceUnavailable
38 38
from synnefo.util.rapi import GanetiRapiClient
39
from synnefo import settings as snf_settings
39 40

  
40 41

  
41 42
BACKEND_CLIENTS = {}    #{hash:Backend client}
......
391 392
        return u'%s: %s' % (self.meta_key, self.meta_value)
392 393

  
393 394

  
395

  
394 396
class Network(models.Model):
395
    NETWORK_STATES = (
397
    OPER_STATES = (
398
        ('PENDING', 'Pending'),
396 399
        ('ACTIVE', 'Active'),
397
        ('DELETED', 'Deleted')
400
        ('DELETED', 'Deleted'),
401
        ('ERROR', 'Error')
402
    )
403

  
404
    ACTIONS = (
405
       ('CREATE', 'Create Network'),
406
       ('DESTROY', 'Destroy Network'),
407
    )
408

  
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
    RSAPI_STATE_FROM_OPER_STATE = {
435
        'PENDING': 'PENDING',
436
        'ACTIVE': 'ACTIVE',
437
        'DELETED': 'DELETED',
438
        'ERROR': 'ERROR'
439
    }
440

  
441
    NETWORK_TYPES = (
442
        ('PUBLIC_ROUTED', 'Public routed network'),
443
        ('PRIVATE_VLAN', 'Private vlan network'),
444
        ('PRIVATE_FILTERED', 'Private network with mac-filtering')
398 445
    )
399 446

  
400
    name = models.CharField(max_length=255)
447
    NETWORK_TAGS = {
448
        'PUBLIC_ROUTED': ['public-routed'],
449
        'PRIVATE_VLAN': ['private-vlan'],
450
        'PRIVATE_FILTERED': ['private-filtered']
451
    }
452

  
453
    name = models.CharField('Network Name', max_length=128)
454
    userid = models.CharField('User ID of the owner', max_length=128, null=True)
455
    subnet = models.CharField('Subnet', max_length=32, default='10.0.0.0/24')
456
    gateway = models.CharField('Gateway', max_length=32, null=True)
457
    dhcp = models.BooleanField('DHCP', default=True)
458
    type = models.CharField(choices=NETWORK_TYPES, max_length=50, default='PRIVATE_VLAN')
459
    link = models.CharField('Network Link', max_length=128, null=True)
460
    mac_prefix = models.CharField('MAC Prefix', max_length=128, null=True)
461
    public = models.BooleanField(default=False)
401 462
    created = models.DateTimeField(auto_now_add=True)
402 463
    updated = models.DateTimeField(auto_now=True)
403
    userid = models.CharField('User ID of the owner', max_length=100,
404
                              null=True)
405
    state = models.CharField(choices=NETWORK_STATES, max_length=30)
406
    public = models.BooleanField(default=False)
407
    link = models.ForeignKey('NetworkLink', related_name='+')
464
    deleted = models.BooleanField('Deleted', default=False)
465
    state = models.CharField(choices=OPER_STATES, max_length=30, default='PENDING')
408 466
    machines = models.ManyToManyField(VirtualMachine,
409 467
                                      through='NetworkInterface')
410 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

  
478

  
479
    class InvalidBackendIdError(Exception):
480
         def __init__(self, value):
481
            self.value = value
482
         def __str__(self):
483
            return repr(self.value)
484

  
485

  
486
    class InvalidBackendMsgError(Exception):
487
         def __init__(self, opcode, status):
488
            self.opcode = opcode
489
            self.status = status
490
         def __str__(self):
491
            return repr('<opcode: %s, status: %s>' % (self.opcode,
492
                    self.status))
493

  
494
    class InvalidActionError(Exception):
495
         def __init__(self, action):
496
            self._action = action
497
         def __str__(self):
498
            return repr(str(self._action))
499

  
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
512

  
513
    @property
514
    def backend_id(self):
515
        """Returns the backend id for this Network by prepending backend-prefix."""
516
        if not self.id:
517
            raise Network.InvalidBackendIdError("self.id is None")
518
        return '%s%s' % (settings.BACKEND_PREFIX_ID, self.id)
519

  
520
    @property
521
    def backend_tag(self):
522
        """Return the network tag to be used in backend
523

  
524
        """
525
        return Network.NETWORK_TAGS[self.type]
526

  
411 527
    def __unicode__(self):
412 528
        return self.name
413 529

  
......
434 550
        return '%s@%s' % (self.machine.name, self.network.name)
435 551

  
436 552

  
437
class NetworkLink(models.Model):
438
    network = models.ForeignKey(Network, null=True, related_name='+')
439
    index = models.IntegerField()
440
    name = models.CharField(max_length=255)
441
    available = models.BooleanField(default=True)
553
class Pool(models.Model):
554
    available = models.BooleanField(default=True, null=False)
555
    index = models.IntegerField(null=False, unique=True)
556
    value = models.CharField(max_length=128, null=False, unique=True)
557
    max_index = 0
442 558

  
443
    def __unicode__(self):
444
        return self.name
445

  
446
    class NotAvailable(Exception):
559
    class Meta:
560
        abstract = True
561
        ordering = ['index']
562

  
563
    @classmethod
564
    def get_available(cls):
565
        try:
566
            entry = cls.objects.filter(available=True)[0]
567
            entry.available = False
568
            entry.save()
569
            return entry
570
        except IndexError:
571
            return cls.generate_new()
572

  
573
    @classmethod
574
    def generate_new(cls):
575
        try:
576
            last = cls.objects.order_by('-index')[0]
577
            index = last.index + 1
578
        except IndexError:
579
            index = 1
580

  
581
        if index <= cls.max_index:
582
            return cls.objects.create(index=index,
583
                                      value=cls.value_from_index(index),
584
                                      available=False)
585

  
586
        raise Pool.PoolExhausted()
587

  
588
    @classmethod
589
    def set_available(cls, value):
590
        entry = cls.objects.get(value=value)
591
        entry.available = True
592
        entry.save()
593

  
594

  
595
    class PoolExhausted(Exception):
447 596
        pass
448 597

  
598

  
599
class BridgePool(Pool):
600
    max_index = snf_settings.GANETI_MAX_LINK_NUMBER
601

  
602
    @staticmethod
603
    def value_from_index(index):
604
        return snf_settings.GANETI_LINK_PREFIX + str(index)
605

  
606

  
607
class MacPrefixPool(Pool):
608
    max_index = snf_settings.GANETI_MAX_MAC_PREFIX_NUMBER
609

  
610
    @staticmethod
611
    def value_from_index(index):
612
        """Convert number to mac prefix
613

  
614
        """
615
        high = snf_settings.GANETI_BASE_MAC_PREFIX
616
        a = hex(int(high.replace(":", ""), 16) + index).replace("0x", '')
617
        mac_prefix = ":".join([a[x:x + 2] for x in xrange(0, len(a), 2)])
618
        return mac_prefix

Also available in: Unified diff