Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / neutron / models.py @ 5cf968ab

History | View | Annotate | Download (8.2 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 5cf968ab Marios Kogias
    machine = models.ForeignKey(VirtualMachine, null=True,
173 5cf968ab Marios Kogias
                                related_name='neutron_nics')
174 d6b24130 Marios Kogias
    network = models.ForeignKey(Network, related_name='neutron_nics')
175 5cf968ab Marios Kogias
    subnet = models.ForeignKey(Subnet, related_name='neutron_nics', null=True)
176 d6b24130 Marios Kogias
    created = models.DateTimeField(auto_now_add=True)
177 d6b24130 Marios Kogias
    updated = models.DateTimeField(auto_now=True)
178 d6b24130 Marios Kogias
    index = models.IntegerField(null=True)
179 d6b24130 Marios Kogias
    mac = models.CharField(max_length=32, null=True, unique=True)
180 d6b24130 Marios Kogias
    ipv4 = models.CharField(max_length=15, null=True)
181 d6b24130 Marios Kogias
    ipv6 = models.CharField(max_length=100, null=True)
182 d6b24130 Marios Kogias
    #firewall_profile = models.CharField(choices=FIREWALL_PROFILES,
183 d6b24130 Marios Kogias
    #                                    max_length=30, null=True)
184 d6b24130 Marios Kogias
    dirty = models.BooleanField(default=False)
185 d6b24130 Marios Kogias
    state = models.CharField(max_length=32, null=False, default="ACTIVE",
186 d6b24130 Marios Kogias
                             choices=STATES)
187 d6b24130 Marios Kogias
    admin_state_up = models.BooleanField(default=False, db_index=True)
188 d6b24130 Marios Kogias
189 d6b24130 Marios Kogias
    def __unicode__(self):
190 d6b24130 Marios Kogias
        return "<%s:vm:%s network:%s ipv4:%s ipv6:%s>" % \
191 d6b24130 Marios Kogias
            (self.index, self.machine_id, self.network_id, self.ipv4,
192 d6b24130 Marios Kogias
             self.ipv6)
193 d6b24130 Marios Kogias
194 d6b24130 Marios Kogias
    @property
195 d6b24130 Marios Kogias
    def is_floating_ip(self):
196 d6b24130 Marios Kogias
        network = self.network
197 d6b24130 Marios Kogias
        if self.ipv4 and network.floating_ip_pool:
198 d6b24130 Marios Kogias
            return network.floating_ips.filter(machine=self.machine,
199 d6b24130 Marios Kogias
                                               ipv4=self.ipv4,
200 d6b24130 Marios Kogias
                                               deleted=False).exists()