root / snf-cyclades-app / synnefo / neutron / models.py @ 2e0916f2
History | View | Annotate | Download (8.1 kB)
1 | d6b24130 | Marios Kogias | # Copyright 2011-2012 GRNET S.A. All rights reserved.
|
---|---|---|---|
2 | d6b24130 | Marios Kogias | #
|
3 | d6b24130 | Marios Kogias | # Redistribution and use in source and binary forms, with or without
|
4 | d6b24130 | Marios Kogias | # modification, are permitted provided that the following conditions
|
5 | d6b24130 | Marios Kogias | # are met:
|
6 | d6b24130 | Marios Kogias | #
|
7 | d6b24130 | Marios Kogias | # 1. Redistributions of source code must retain the above copyright
|
8 | d6b24130 | Marios Kogias | # notice, this list of conditions and the following disclaimer.
|
9 | d6b24130 | Marios Kogias | #
|
10 | d6b24130 | Marios Kogias | # 2. Redistributions in binary form must reproduce the above copyright
|
11 | d6b24130 | Marios Kogias | # notice, this list of conditions and the following disclaimer in the
|
12 | d6b24130 | Marios Kogias | # documentation and/or other materials provided with the distribution.
|
13 | d6b24130 | Marios Kogias | #
|
14 | d6b24130 | Marios Kogias | # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
15 | d6b24130 | Marios Kogias | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
16 | d6b24130 | Marios Kogias | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
17 | d6b24130 | Marios Kogias | # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
18 | d6b24130 | Marios Kogias | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
19 | d6b24130 | Marios Kogias | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
20 | d6b24130 | Marios Kogias | # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
21 | d6b24130 | Marios Kogias | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
22 | d6b24130 | Marios Kogias | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
23 | d6b24130 | Marios Kogias | # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
24 | d6b24130 | Marios Kogias | # SUCH DAMAGE.
|
25 | d6b24130 | Marios Kogias | #
|
26 | d6b24130 | Marios Kogias | # The views and conclusions contained in the software and documentation are
|
27 | d6b24130 | Marios Kogias | # those of the authors and should not be interpreted as representing official
|
28 | d6b24130 | Marios Kogias | # policies, either expressed or implied, of GRNET S.A.
|
29 | d6b24130 | Marios Kogias | |
30 | d6b24130 | Marios Kogias | import datetime |
31 | d6b24130 | Marios Kogias | |
32 | d6b24130 | Marios Kogias | from copy import deepcopy |
33 | d6b24130 | Marios Kogias | from django.conf import settings |
34 | d6b24130 | Marios Kogias | from django.db import models |
35 | d6b24130 | Marios Kogias | from django.db import IntegrityError |
36 | d6b24130 | Marios Kogias | |
37 | d6b24130 | Marios Kogias | from contextlib import contextmanager |
38 | d6b24130 | Marios Kogias | from hashlib import sha1 |
39 | d6b24130 | Marios Kogias | from snf_django.lib.api import faults |
40 | d6b24130 | Marios Kogias | from django.conf import settings as snf_settings |
41 | d6b24130 | Marios Kogias | |
42 | d6b24130 | Marios Kogias | from synnefo.db.managers import ForUpdateManager, ProtectedDeleteManager |
43 | d6b24130 | Marios Kogias | from synnefo.db import pools |
44 | d6b24130 | Marios Kogias | |
45 | d6b24130 | Marios Kogias | from synnefo.db.models import VirtualMachine, QuotaHolderSerial |
46 | d6b24130 | Marios Kogias | |
47 | d6b24130 | Marios Kogias | from synnefo.logic.rapi_pool import (get_rapi_client, |
48 | d6b24130 | Marios Kogias | put_rapi_client) |
49 | d6b24130 | Marios Kogias | |
50 | d6b24130 | Marios Kogias | import logging |
51 | d6b24130 | Marios Kogias | log = logging.getLogger(__name__) |
52 | d6b24130 | Marios Kogias | |
53 | d6b24130 | Marios Kogias | |
54 | d6b24130 | Marios Kogias | class Network(models.Model): |
55 | d6b24130 | Marios Kogias | OPER_STATES = ( |
56 | d6b24130 | Marios Kogias | ('PENDING', 'Pending'), # Unused because of lazy networks |
57 | d6b24130 | Marios Kogias | ('ACTIVE', 'Active'), |
58 | d6b24130 | Marios Kogias | ('DELETED', 'Deleted'), |
59 | d6b24130 | Marios Kogias | ('ERROR', 'Error') |
60 | d6b24130 | Marios Kogias | ) |
61 | d6b24130 | Marios Kogias | |
62 | d6b24130 | Marios Kogias | ACTIONS = ( |
63 | d6b24130 | Marios Kogias | ('CREATE', 'Create Network'), |
64 | d6b24130 | Marios Kogias | ('DESTROY', 'Destroy Network'), |
65 | d6b24130 | Marios Kogias | ('ADD', 'Add server to Network'), |
66 | d6b24130 | Marios Kogias | ('REMOVE', 'Remove server from Network'), |
67 | d6b24130 | Marios Kogias | ) |
68 | d6b24130 | Marios Kogias | |
69 | d6b24130 | Marios Kogias | RSAPI_STATE_FROM_OPER_STATE = { |
70 | d6b24130 | Marios Kogias | 'PENDING': 'PENDING', |
71 | d6b24130 | Marios Kogias | 'ACTIVE': 'ACTIVE', |
72 | d6b24130 | Marios Kogias | 'DELETED': 'DELETED', |
73 | d6b24130 | Marios Kogias | 'ERROR': 'ERROR' |
74 | d6b24130 | Marios Kogias | } |
75 | d6b24130 | Marios Kogias | |
76 | d6b24130 | Marios Kogias | FLAVORS = { |
77 | d6b24130 | Marios Kogias | 'CUSTOM': {
|
78 | d6b24130 | Marios Kogias | 'mode': 'bridged', |
79 | d6b24130 | Marios Kogias | 'link': settings.DEFAULT_BRIDGE,
|
80 | d6b24130 | Marios Kogias | 'mac_prefix': settings.DEFAULT_MAC_PREFIX,
|
81 | d6b24130 | Marios Kogias | 'tags': None, |
82 | d6b24130 | Marios Kogias | 'desc': "Basic flavor used for a bridged network", |
83 | d6b24130 | Marios Kogias | }, |
84 | d6b24130 | Marios Kogias | 'IP_LESS_ROUTED': {
|
85 | d6b24130 | Marios Kogias | 'mode': 'routed', |
86 | d6b24130 | Marios Kogias | 'link': settings.DEFAULT_ROUTING_TABLE,
|
87 | d6b24130 | Marios Kogias | 'mac_prefix': settings.DEFAULT_MAC_PREFIX,
|
88 | d6b24130 | Marios Kogias | 'tags': 'ip-less-routed', |
89 | d6b24130 | Marios Kogias | 'desc': "Flavor used for an IP-less routed network using" |
90 | d6b24130 | Marios Kogias | " Proxy ARP",
|
91 | d6b24130 | Marios Kogias | }, |
92 | d6b24130 | Marios Kogias | 'MAC_FILTERED': {
|
93 | d6b24130 | Marios Kogias | 'mode': 'bridged', |
94 | d6b24130 | Marios Kogias | 'link': settings.DEFAULT_MAC_FILTERED_BRIDGE,
|
95 | d6b24130 | Marios Kogias | 'mac_prefix': 'pool', |
96 | d6b24130 | Marios Kogias | 'tags': 'private-filtered', |
97 | d6b24130 | Marios Kogias | 'desc': "Flavor used for bridged networks that offer isolation" |
98 | d6b24130 | Marios Kogias | " via filtering packets based on their src "
|
99 | d6b24130 | Marios Kogias | " MAC (ebtables)",
|
100 | d6b24130 | Marios Kogias | }, |
101 | d6b24130 | Marios Kogias | 'PHYSICAL_VLAN': {
|
102 | d6b24130 | Marios Kogias | 'mode': 'bridged', |
103 | d6b24130 | Marios Kogias | 'link': 'pool', |
104 | d6b24130 | Marios Kogias | 'mac_prefix': settings.DEFAULT_MAC_PREFIX,
|
105 | d6b24130 | Marios Kogias | 'tags': 'physical-vlan', |
106 | d6b24130 | Marios Kogias | 'desc': "Flavor used for bridged network that offer isolation" |
107 | d6b24130 | Marios Kogias | " via dedicated physical vlan",
|
108 | d6b24130 | Marios Kogias | }, |
109 | d6b24130 | Marios Kogias | } |
110 | d6b24130 | Marios Kogias | |
111 | d6b24130 | Marios Kogias | name = models.CharField('Network Name', max_length=128) |
112 | d6b24130 | Marios Kogias | userid = models.CharField('User ID of the owner', max_length=128, |
113 | d6b24130 | Marios Kogias | null=True, db_index=True) |
114 | d6b24130 | Marios Kogias | flavor = models.CharField('Flavor', max_length=32, null=False) |
115 | d6b24130 | Marios Kogias | mode = models.CharField('Network Mode', max_length=16, null=True) |
116 | d6b24130 | Marios Kogias | link = models.CharField('Network Link', max_length=32, null=True) |
117 | d6b24130 | Marios Kogias | mac_prefix = models.CharField('MAC Prefix', max_length=32, null=False) |
118 | d6b24130 | Marios Kogias | tags = models.CharField('Network Tags', max_length=128, null=True) |
119 | d6b24130 | Marios Kogias | public = models.BooleanField(default=False, db_index=True) |
120 | d6b24130 | Marios Kogias | created = models.DateTimeField(auto_now_add=True)
|
121 | d6b24130 | Marios Kogias | updated = models.DateTimeField(auto_now=True)
|
122 | d6b24130 | Marios Kogias | deleted = models.BooleanField('Deleted', default=False, db_index=True) |
123 | d6b24130 | Marios Kogias | state = models.CharField(choices=OPER_STATES, max_length=32,
|
124 | d6b24130 | Marios Kogias | default='PENDING')
|
125 | d6b24130 | Marios Kogias | machines = models.ManyToManyField(VirtualMachine, |
126 | 7eae8fce | Dionysis Grigoropoulos | through='NetworkInterface',
|
127 | 2e0916f2 | Marios Kogias | related_name='neutron_networks')
|
128 | d6b24130 | Marios Kogias | action = models.CharField(choices=ACTIONS, max_length=32, null=True, |
129 | d6b24130 | Marios Kogias | default=None)
|
130 | 7eae8fce | Dionysis Grigoropoulos | drained = models.BooleanField("Drained", default=False, null=False) |
131 | 7eae8fce | Dionysis Grigoropoulos | # this is the opposite of admin_state_up
|
132 | d6b24130 | Marios Kogias | floating_ip_pool = models.BooleanField('Floating IP Pool', null=False, |
133 | d6b24130 | Marios Kogias | default=False)
|
134 | d6b24130 | Marios Kogias | #serial = models.ForeignKey(QuotaHolderSerial, related_name='network',
|
135 | d6b24130 | Marios Kogias | # null=True)
|
136 | d6b24130 | Marios Kogias | |
137 | 2e0916f2 | Marios Kogias | public = models.BooleanField('public', default=True) |
138 | d6b24130 | Marios Kogias | objects = ForUpdateManager() |
139 | d6b24130 | Marios Kogias | |
140 | 7eae8fce | Dionysis Grigoropoulos | |
141 | d6b24130 | Marios Kogias | class Subnet(models.Model): |
142 | 882b662f | Dionysis Grigoropoulos | SUBNET_NAME_LENGTH = 128
|
143 | 882b662f | Dionysis Grigoropoulos | |
144 | 7eae8fce | Dionysis Grigoropoulos | network = models.ForeignKey('Network')
|
145 | 0dae1b9f | Dionysis Grigoropoulos | name = models.CharField('Network Name', max_length=SUBNET_NAME_LENGTH,
|
146 | 0dae1b9f | Dionysis Grigoropoulos | null=True)
|
147 | 7eae8fce | Dionysis Grigoropoulos | ipversion = models.IntegerField('IP Version', default=4) |
148 | 7eae8fce | Dionysis Grigoropoulos | cidr = models.CharField('Subnet', max_length=32, null=True) |
149 | 7eae8fce | Dionysis Grigoropoulos | gateway = models.CharField('Gateway', max_length=32, null=True) |
150 | 7eae8fce | Dionysis Grigoropoulos | dhcp = models.BooleanField('DHCP', default=True) |
151 | 7eae8fce | Dionysis Grigoropoulos | |
152 | 7eae8fce | Dionysis Grigoropoulos | # Synnefo related fields
|
153 | d6b24130 | Marios Kogias | # subnet6 will be null for IPv4 only networks
|
154 | d6b24130 | Marios Kogias | #pool = models.OneToOneField('IPPoolTable', related_name='network',
|
155 | d6b24130 | Marios Kogias | # default=lambda: IPPoolTable.objects.create(
|
156 | d6b24130 | Marios Kogias | # available_map='',
|
157 | d6b24130 | Marios Kogias | # reserved_map='',
|
158 | d6b24130 | Marios Kogias | # size=0),
|
159 | d6b24130 | Marios Kogias | # null=True)
|
160 | d6b24130 | Marios Kogias | |
161 | 0dae1b9f | Dionysis Grigoropoulos | def __unicode__(self): |
162 | 0dae1b9f | Dionysis Grigoropoulos | return "<Subnet %s>" % str(self.id) |
163 | 0dae1b9f | Dionysis Grigoropoulos | |
164 | 7eae8fce | Dionysis Grigoropoulos | |
165 | d6b24130 | Marios Kogias | class NetworkInterface(models.Model): |
166 | d6b24130 | Marios Kogias | STATES = ( |
167 | d6b24130 | Marios Kogias | ("ACTIVE", "Active"), |
168 | d6b24130 | Marios Kogias | ("BUILDING", "Building"), |
169 | d6b24130 | Marios Kogias | ) |
170 | d6b24130 | Marios Kogias | |
171 | 2e0916f2 | Marios Kogias | name = models.CharField('nic name', max_length=128) |
172 | d6b24130 | Marios Kogias | machine = models.ForeignKey(VirtualMachine, related_name='neutron_nics')
|
173 | d6b24130 | Marios Kogias | network = models.ForeignKey(Network, related_name='neutron_nics')
|
174 | 2e0916f2 | Marios Kogias | subnet = models.ForeignKey(Subnet, related_names='neutron_nics')
|
175 | d6b24130 | Marios Kogias | created = models.DateTimeField(auto_now_add=True)
|
176 | d6b24130 | Marios Kogias | updated = models.DateTimeField(auto_now=True)
|
177 | d6b24130 | Marios Kogias | index = models.IntegerField(null=True)
|
178 | d6b24130 | Marios Kogias | mac = models.CharField(max_length=32, null=True, unique=True) |
179 | d6b24130 | Marios Kogias | ipv4 = models.CharField(max_length=15, null=True) |
180 | d6b24130 | Marios Kogias | ipv6 = models.CharField(max_length=100, null=True) |
181 | d6b24130 | Marios Kogias | #firewall_profile = models.CharField(choices=FIREWALL_PROFILES,
|
182 | d6b24130 | Marios Kogias | # max_length=30, null=True)
|
183 | d6b24130 | Marios Kogias | dirty = models.BooleanField(default=False)
|
184 | d6b24130 | Marios Kogias | state = models.CharField(max_length=32, null=False, default="ACTIVE", |
185 | d6b24130 | Marios Kogias | choices=STATES) |
186 | d6b24130 | Marios Kogias | admin_state_up = models.BooleanField(default=False, db_index=True) |
187 | d6b24130 | Marios Kogias | |
188 | d6b24130 | Marios Kogias | def __unicode__(self): |
189 | d6b24130 | Marios Kogias | return "<%s:vm:%s network:%s ipv4:%s ipv6:%s>" % \ |
190 | d6b24130 | Marios Kogias | (self.index, self.machine_id, self.network_id, self.ipv4, |
191 | d6b24130 | Marios Kogias | self.ipv6)
|
192 | d6b24130 | Marios Kogias | |
193 | d6b24130 | Marios Kogias | @property
|
194 | d6b24130 | Marios Kogias | def is_floating_ip(self): |
195 | d6b24130 | Marios Kogias | network = self.network
|
196 | d6b24130 | Marios Kogias | if self.ipv4 and network.floating_ip_pool: |
197 | d6b24130 | Marios Kogias | return network.floating_ips.filter(machine=self.machine, |
198 | d6b24130 | Marios Kogias | ipv4=self.ipv4,
|
199 | d6b24130 | Marios Kogias | deleted=False).exists()
|
200 | 2e0916f2 | Marios Kogias | |
201 | 2e0916f2 | Marios Kogias |