~ubuntu-branches/ubuntu/vivid/neutron/vivid-updates

« back to all changes in this revision

Viewing changes to neutron/db/l3_dvr_db.py

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2015-03-30 11:17:19 UTC
  • mfrom: (1.1.21)
  • Revision ID: package-import@ubuntu.com-20150330111719-h0gx7233p4jkkgfh
Tags: 1:2015.1~b3-0ubuntu1
* New upstream milestone release:
  - d/control: Align version requirements with upstream.
  - d/control: Add new dependency on oslo-log.
  - d/p/*: Rebase.
  - d/control,d/neutron-plugin-hyperv*: Dropped, decomposed into
    separate project upstream.
  - d/control,d/neutron-plugin-openflow*: Dropped, decomposed into
    separate project upstream.
  - d/neutron-common.install: Add neutron-rootwrap-daemon and 
    neutron-keepalived-state-change binaries.
  - d/rules: Ignore neutron-hyperv-agent when installing; only for Windows.
  - d/neutron-plugin-cisco.install: Drop neutron-cisco-cfg-agent as
    decomposed into separate project upstream.
  - d/neutron-plugin-vmware.install: Drop neutron-check-nsx-config and
    neutron-nsx-manage as decomposed into separate project upstream.
  - d/control: Add dependency on python-neutron-fwaas to neutron-l3-agent.
* d/pydist-overrides: Add overrides for oslo packages.
* d/control: Fixup type in package description (LP: #1263539).
* d/p/fixup-driver-test-execution.patch: Cherry pick fix from upstream VCS
  to support unit test exection in out-of-tree vendor drivers.
* d/neutron-common.postinst: Allow general access to /etc/neutron but limit
  access to root/neutron to /etc/neutron/neutron.conf to support execution
  of unit tests in decomposed vendor drivers.
* d/control: Add dependency on python-neutron-fwaas to neutron-l3-agent
  package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#    License for the specific language governing permissions and limitations
13
13
#    under the License.
14
14
 
15
 
from oslo.config import cfg
 
15
from oslo_config import cfg
 
16
from oslo_log import log as logging
16
17
 
17
18
from neutron.api.v2 import attributes
18
19
from neutron.common import constants as l3_const
26
27
from neutron.extensions import portbindings
27
28
from neutron.i18n import _LI
28
29
from neutron import manager
29
 
from neutron.openstack.common import log as logging
30
30
from neutron.plugins.common import constants
31
31
 
32
32
 
54
54
 
55
55
    router_device_owners = (
56
56
        l3_db.L3_NAT_db_mixin.router_device_owners +
57
 
        (DEVICE_OWNER_DVR_INTERFACE,))
 
57
        (DEVICE_OWNER_DVR_INTERFACE,
 
58
         DEVICE_OWNER_DVR_SNAT,
 
59
         DEVICE_OWNER_AGENT_GW))
58
60
 
59
61
    extra_attributes = (
60
62
        l3_attrs_db.ExtraAttributesMixin.extra_attributes + [{
191
193
        )
192
194
 
193
195
    def _update_fip_assoc(self, context, fip, floatingip_db, external_port):
194
 
        """Override to delete the fip agent gw port on disassociate."""
 
196
        """Override to create and delete floating agent gw port for DVR.
 
197
 
 
198
        Floating IP Agent gateway port will be created when a
 
199
        floatingIP association happens.
 
200
        Floating IP Agent gateway port will be deleted when a
 
201
        floatingIP disassociation happens.
 
202
        """
195
203
        fip_port = fip.get('port_id')
196
204
        unused_fip_agent_gw_port = (
197
205
            fip_port is None and floatingip_db['fixed_port_id'])
198
 
        if unused_fip_agent_gw_port:
 
206
        if unused_fip_agent_gw_port and floatingip_db.get('router_id'):
199
207
            admin_ctx = context.elevated()
200
 
            self.clear_unused_fip_agent_gw_port(
201
 
                admin_ctx, floatingip_db)
 
208
            router_dict = self.get_router(
 
209
                admin_ctx, floatingip_db['router_id'])
 
210
            # Check if distributed router and then delete the
 
211
            # FloatingIP agent gateway port
 
212
            if router_dict.get('distributed'):
 
213
                self.clear_unused_fip_agent_gw_port(
 
214
                    admin_ctx, floatingip_db)
202
215
        super(L3_NAT_with_dvr_db_mixin, self)._update_fip_assoc(
203
216
            context, fip, floatingip_db, external_port)
 
217
        associate_fip = fip_port and floatingip_db['id']
 
218
        if associate_fip and floatingip_db.get('router_id'):
 
219
            admin_ctx = context.elevated()
 
220
            router_dict = self.get_router(
 
221
                admin_ctx, floatingip_db['router_id'])
 
222
            # Check if distributed router and then create the
 
223
            # FloatingIP agent gateway port
 
224
            if router_dict.get('distributed'):
 
225
                vm_hostid = self.get_vm_port_hostid(
 
226
                    context, fip_port)
 
227
                if vm_hostid:
 
228
                    # FIXME (Swami): This FIP Agent Gateway port should be
 
229
                    # created only once and there should not be a duplicate
 
230
                    # for the same host. Until we find a good solution for
 
231
                    # augmenting multiple server requests we should use the
 
232
                    # existing flow.
 
233
                    fip_agent_port = (
 
234
                        self.create_fip_agent_gw_port_if_not_exists(
 
235
                            admin_ctx, external_port['network_id'],
 
236
                            vm_hostid))
 
237
                    LOG.debug("FIP Agent gateway port: %s", fip_agent_port)
204
238
 
205
239
    def clear_unused_fip_agent_gw_port(
206
240
            self, context, floatingip_db):
214
248
        """
215
249
        fip_hostid = self.get_vm_port_hostid(
216
250
            context, floatingip_db['fixed_port_id'])
217
 
        if fip_hostid and self.check_fips_availability_on_host(
218
 
            context, fip_hostid):
219
 
            LOG.debug('Deleting the Agent GW Port on host: %s', fip_hostid)
220
 
            self.delete_floatingip_agent_gateway_port(context, fip_hostid)
 
251
        if fip_hostid and self.check_fips_availability_on_host_ext_net(
 
252
            context, fip_hostid, floatingip_db['floating_network_id']):
 
253
            LOG.debug('Deleting the Agent GW Port for ext-net: '
 
254
                      '%s', floatingip_db['floating_network_id'])
 
255
            self.delete_floatingip_agent_gateway_port(
 
256
                context, fip_hostid, floatingip_db['floating_network_id'])
221
257
 
222
258
    def delete_floatingip(self, context, id):
223
259
        floatingip = self._get_floatingip(context, id)
297
333
            port, subnet = self._remove_interface_by_subnet(
298
334
                context, router_id, subnet_id, device_owner)
299
335
 
300
 
        if router.extra_attributes.distributed and router.gw_port:
301
 
            self.delete_csnat_router_interface_ports(
302
 
                context.elevated(), router, subnet_id=subnet_id)
 
336
        if router.extra_attributes.distributed:
 
337
            if router.gw_port:
 
338
                self.delete_csnat_router_interface_ports(
 
339
                    context.elevated(), router, subnet_id=subnet_id)
 
340
            plugin = manager.NeutronManager.get_service_plugins().get(
 
341
                        constants.L3_ROUTER_NAT)
 
342
            l3_agents = plugin.get_l3_agents_hosting_routers(context,
 
343
                                                             [router_id])
 
344
            for l3_agent in l3_agents:
 
345
                if not plugin.check_ports_exist_on_l3agent(context, l3_agent,
 
346
                                                           router_id):
 
347
                    plugin.remove_router_from_l3_agent(
 
348
                        context, l3_agent['id'], router_id)
303
349
 
304
350
        router_interface_info = self._make_router_interface_info(
305
351
            router_id, port['tenant_id'], port['id'],
329
375
 
330
376
    def _build_routers_list(self, context, routers, gw_ports):
331
377
        # Perform a single query up front for all routers
 
378
        if not routers:
 
379
            return []
332
380
        router_ids = [r['id'] for r in routers]
333
381
        snat_binding = l3_dvrsched_db.CentralizedSnatL3AgentBinding
334
382
        query = (context.session.query(snat_binding).
439
487
        if ports:
440
488
            return ports[0]
441
489
 
442
 
    def check_fips_availability_on_host(self, context, host_id):
443
 
        """Query all floating_ips and filter by particular host."""
 
490
    def check_fips_availability_on_host_ext_net(
 
491
        self, context, host_id, fip_ext_net_id):
 
492
        """Query all floating_ips and filter on host and external net."""
444
493
        fip_count_on_host = 0
445
494
        with context.session.begin(subtransactions=True):
446
495
            routers = self._get_sync_routers(context, router_ids=None)
449
498
            # Check for the active floatingip in the host
450
499
            for fip in floating_ips:
451
500
                f_host = self.get_vm_port_hostid(context, fip['port_id'])
452
 
                if f_host == host_id:
 
501
                if (f_host == host_id and
 
502
                    (fip['floating_network_id'] == fip_ext_net_id)):
453
503
                    fip_count_on_host += 1
454
504
            # If fip_count greater than 1 or equal to zero no action taken
455
505
            # if the fip_count is equal to 1, then this would be last active
458
508
                return True
459
509
            return False
460
510
 
461
 
    def delete_floatingip_agent_gateway_port(self, context, host_id):
462
 
        """Function to delete the FIP agent gateway port on host."""
 
511
    def delete_floatingip_agent_gateway_port(
 
512
        self, context, host_id, ext_net_id):
 
513
        """Function to delete FIP gateway port with given ext_net_id."""
463
514
        # delete any fip agent gw port
464
 
        device_filter = {'device_owner': [DEVICE_OWNER_AGENT_GW]}
 
515
        device_filter = {'device_owner': [DEVICE_OWNER_AGENT_GW],
 
516
                         'network_id': [ext_net_id]}
465
517
        ports = self._core_plugin.get_ports(context,
466
518
                                            filters=device_filter)
467
519
        for p in ports:
495
547
                              'fixed_ips': attributes.ATTR_NOT_SPECIFIED,
496
548
                              'device_id': l3_agent_db['id'],
497
549
                              'device_owner': DEVICE_OWNER_AGENT_GW,
 
550
                              'binding:host_id': host,
498
551
                              'admin_state_up': True,
499
552
                              'name': ''}})
500
553
                if agent_port: