~midonet-drivers/python-networking-midonet/liberty

« back to all changes in this revision

Viewing changes to midonet/neutron/db/loadbalancer_db.py

  • Committer: Jaume Devesa
  • Date: 2015-08-25 12:33:00 UTC
  • Revision ID: devvesa@gmail.com-20150825123300-x39xyxc5wjsrm7me
Removing tarball data

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2015 Midokura SARL.
2
 
# All Rights Reserved.
3
 
#
4
 
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
5
 
#    not use this file except in compliance with the License. You may obtain
6
 
#    a copy of the License at
7
 
#
8
 
#         http://www.apache.org/licenses/LICENSE-2.0
9
 
#
10
 
#    Unless required by applicable law or agreed to in writing, software
11
 
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
 
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
 
#    License for the specific language governing permissions and limitations
14
 
#    under the License.
15
 
 
16
 
from neutron.common import constants as n_const
17
 
from neutron.common import exceptions as n_exc
18
 
from neutron.db import l3_db
19
 
from neutron.db import models_v2
20
 
from neutron import i18n
21
 
from sqlalchemy.orm import exc
22
 
 
23
 
_LE = i18n._LE
24
 
 
25
 
 
26
 
class LoadBalancerDriverDbMixin(object):
27
 
 
28
 
    def _check_and_get_router_id_for_pool(self, context, subnet_id):
29
 
 
30
 
        subnet = self.core_plugin._get_subnet(context, subnet_id)
31
 
 
32
 
        # Check whether the network is external
33
 
        if self._is_subnet_external(context, subnet):
34
 
            msg = (_LE("pool subnet must not be public"))
35
 
            raise n_exc.BadRequest(resource='pool', msg=msg)
36
 
 
37
 
        router_id = self._get_router_from_subnet(context, subnet)
38
 
        if not router_id:
39
 
            msg = (_LE("pool subnet must be associated with router"))
40
 
            raise n_exc.BadRequest(resource='pool', msg=msg)
41
 
        return router_id
42
 
 
43
 
    def _get_router_from_pool(self, context, pool):
44
 
        subnet = self.core_plugin._get_subnet(context, pool['subnet_id'])
45
 
        return self._get_router_from_subnet(context, subnet)
46
 
 
47
 
    def _get_router_from_port(self, context, port_id):
48
 
        routers = context.session.query(l3_db.Router)
49
 
        routers = routers.join(models_v2.Port,
50
 
                               l3_db.Router.id == models_v2.Port.device_id)
51
 
        routers = routers.filter(models_v2.Port.id == port_id)
52
 
        try:
53
 
            return routers.one().id
54
 
        except exc.NoResultFound:
55
 
            return None
56
 
 
57
 
    def _get_router_from_subnet(self, context, subnet):
58
 
        iport = self._get_router_interface_port(context, subnet)
59
 
        if iport is None:
60
 
            return None
61
 
        else:
62
 
            return self._get_router_from_port(context, iport)
63
 
 
64
 
    def _get_router_interface_port(self, context, subnet):
65
 
        all_ports = context.session.query(models_v2.Port).join(
66
 
            models_v2.Port.fixed_ips)
67
 
        ports = all_ports.filter(
68
 
            models_v2.Port.device_owner == n_const.DEVICE_OWNER_ROUTER_INTF)
69
 
        ports = ports.filter(models_v2.Port.network_id == subnet['network_id'])
70
 
        ports = ports.filter(
71
 
            models_v2.IPAllocation.ip_address == subnet['gateway_ip'])
72
 
        try:
73
 
            return ports.one().id
74
 
        except exc.NoResultFound:
75
 
            return None
76
 
 
77
 
    def _is_subnet_external(self, context, subnet):
78
 
        network = self.core_plugin._get_network(context, subnet['network_id'])
79
 
        return network.external
80
 
 
81
 
    def _validate_vip_subnet(self, context, vip):
82
 
        subnet = self.core_plugin._get_subnet(context, vip['subnet_id'])
83
 
        pool = self.plugin.get_pool(context, vip['pool_id'])
84
 
 
85
 
        # VIP and pool must not be on the same subnet if pool is associated
86
 
        # with a health monitor.  Health monitor would not work in that case.
87
 
        if pool['health_monitors'] and pool['subnet_id'] == subnet['id']:
88
 
            msg = (_LE("The VIP and pool cannot be on the same subnet if"
89
 
                       "health monitor is associated"))
90
 
            raise n_exc.BadRequest(resource='vip', msg=msg)
91
 
 
92
 
        if not self._is_subnet_external(context, subnet):
93
 
            return
94
 
 
95
 
        # ensure that if the vip subnet is public, the router has its
96
 
        # gateway set.
97
 
        router_id = self._get_router_from_pool(context, pool)
98
 
 
99
 
        # router_id should never be None because it was already validated
100
 
        # when we created the pool
101
 
        assert router_id is not None
102
 
 
103
 
        router = self.core_plugin._get_router(context, router_id)
104
 
        if router.get('gw_port_id') is None:
105
 
            msg = (_LE("The router must have its gateway set if the "
106
 
                       "VIP subnet is external"))
107
 
            raise n_exc.BadRequest(resource='vip', msg=msg)
108
 
 
109
 
    def _validate_pool_hm_assoc(self, context, pool_id, hm_id):
110
 
        pool = self.plugin.get_pool(context, pool_id)
111
 
        assoc = next((x for x in pool['health_monitors'] if x != hm_id), None)
112
 
 
113
 
        # There is an association with a different health monitor
114
 
        if assoc:
115
 
            msg = (_LE("The pool is already associated with a different "
116
 
                       "health monitor"))
117
 
            raise n_exc.BadRequest(resource='pool_monitor_association',
118
 
                                   msg=msg)
119
 
 
120
 
        # When associating health monitor, the subnet of VIP and Pool must not
121
 
        # match
122
 
        if pool['vip_id']:
123
 
            vip = self.plugin.get_vip(context, pool['vip_id'])
124
 
            if vip['subnet_id'] == pool['subnet_id']:
125
 
                msg = (_LE("The VIP and pool cannot be on the same subnet if"
126
 
                           "health monitor is associated"))
127
 
                raise n_exc.BadRequest(resource='pool_monitor_association',
128
 
                                       msg=msg)