~ubuntu-branches/ubuntu/vivid/neutron-vpnaas/vivid-proposed

« back to all changes in this revision

Viewing changes to neutron_vpnaas/services/vpn/vpn_service.py

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2015-02-16 14:17:35 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20150216141735-6yqtzx2o0owp3xi0
Tags: 1:2015.1~b2-0ubuntu1
* New upstream release:
  - d/control: Update/align dependencies with upstream.
  - d/neutron-vpn-agent: Install rootwrap filters and vpnaas specific
    configuration files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2014 OpenStack Foundation.
 
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 oslo.config import cfg
 
17
from oslo.utils import importutils
 
18
 
 
19
from neutron import context as n_context
 
20
from neutron.openstack.common import log as logging
 
21
from neutron.services import advanced_service
 
22
from neutron.services import provider_configuration as provconfig
 
23
 
 
24
from neutron_vpnaas.extensions import vpnaas
 
25
 
 
26
LOG = logging.getLogger(__name__)
 
27
 
 
28
DEVICE_DRIVERS = 'device_drivers'
 
29
 
 
30
 
 
31
class VPNService(advanced_service.AdvancedService):
 
32
    """VPN Service observer."""
 
33
 
 
34
    def __init__(self, l3_agent):
 
35
        """Creates a VPN Service instance with context.
 
36
 
 
37
        DO NOT CALL THIS DIRECTLY! Use the instance() class method to Creates
 
38
        a singleton instance of the service.
 
39
        """
 
40
        self.context = n_context.get_admin_context_without_session()
 
41
        super(VPNService, self).__init__(l3_agent)
 
42
 
 
43
    def load_device_drivers(self, host):
 
44
        """Loads one or more device drivers for VPNaaS."""
 
45
        self.devices = []
 
46
        for device_driver in cfg.CONF.vpnagent.vpn_device_driver:
 
47
            device_driver = provconfig.get_provider_driver_class(
 
48
                device_driver, DEVICE_DRIVERS)
 
49
            try:
 
50
                self.devices.append(importutils.import_object(device_driver,
 
51
                                                              self,
 
52
                                                              host))
 
53
                LOG.debug('Loaded VPNaaS device driver: %s', device_driver)
 
54
            except ImportError:
 
55
                raise vpnaas.DeviceDriverImportError(
 
56
                    device_driver=device_driver)
 
57
        return self.devices
 
58
 
 
59
    # Overridden handlers for L3 agent events.
 
60
    def after_router_added(self, ri):
 
61
        """Create the router and sync for each loaded device driver."""
 
62
        for device in self.devices:
 
63
            device.create_router(ri.router_id)
 
64
            device.sync(self.context, [ri.router])
 
65
 
 
66
    def after_router_removed(self, ri):
 
67
        """Remove the router from each loaded device driver."""
 
68
        for device in self.devices:
 
69
            device.destroy_router(ri.router_id)
 
70
 
 
71
    def after_router_updated(self, ri):
 
72
        """Perform a sync on each loaded device driver."""
 
73
        for device in self.devices:
 
74
            device.sync(self.context, [ri.router])
 
75
 
 
76
    # Device driver methods calling back to L3 agent
 
77
    def get_namespace(self, router_id):
 
78
        """Get namespace of router.
 
79
 
 
80
        :router_id: router_id
 
81
        :returns: namespace string.
 
82
            Note if the router is not exist, this function
 
83
            returns None
 
84
        """
 
85
        router_info = self.l3_agent.router_info.get(router_id)
 
86
        if not router_info:
 
87
            return
 
88
        # Added for handling the distributed Routers within SNAT namespace
 
89
        if router_info.router['distributed']:
 
90
            #return self.get_snat_ns_name(router_id)
 
91
            return self.l3_agent.get_snat_ns_name(router_id)
 
92
        else:
 
93
            return router_info.ns_name
 
94
 
 
95
    def get_router_based_iptables_manager(self, router_info):
 
96
        """Returns router based iptables manager
 
97
 
 
98
        In DVR routers the IPsec VPN service should run inside
 
99
        the snat namespace. So the iptables manager used for
 
100
        snat namespace is different from the iptables manager
 
101
        used for the qr namespace in a non dvr based router.
 
102
 
 
103
        This function will check the router type and then will
 
104
        return the right iptables manager. If DVR enabled router
 
105
        it will return the snat_iptables_manager otherwise it will
 
106
        return the legacy iptables_manager.
 
107
        """
 
108
        if router_info.router['distributed']:
 
109
            return router_info.snat_iptables_manager
 
110
        else:
 
111
            return router_info.iptables_manager
 
112
 
 
113
    def add_nat_rule(self, router_id, chain, rule, top=False):
 
114
        """Add nat rule in namespace.
 
115
 
 
116
        :param router_id: router_id
 
117
        :param chain: a string of chain name
 
118
        :param rule: a string of rule
 
119
        :param top: if top is true, the rule
 
120
            will be placed on the top of chain
 
121
            Note if there is no rotuer, this method do nothing
 
122
        """
 
123
        router_info = self.l3_agent.router_info.get(router_id)
 
124
        if not router_info:
 
125
            return
 
126
        iptables_manager = self.get_router_based_iptables_manager(router_info)
 
127
        iptables_manager.ipv4['nat'].add_rule(chain, rule, top=top)
 
128
 
 
129
    def remove_nat_rule(self, router_id, chain, rule, top=False):
 
130
        """Remove nat rule in namespace.
 
131
 
 
132
        :param router_id: router_id
 
133
        :param chain: a string of chain name
 
134
        :param rule: a string of rule
 
135
        :param top: unused
 
136
            needed to have same argument with add_nat_rule
 
137
        """
 
138
        router_info = self.l3_agent.router_info.get(router_id)
 
139
        if not router_info:
 
140
            return
 
141
        iptables_manager = self.get_router_based_iptables_manager(router_info)
 
142
        iptables_manager.ipv4['nat'].remove_rule(chain, rule, top=top)
 
143
 
 
144
    def iptables_apply(self, router_id):
 
145
        """Apply IPtables.
 
146
 
 
147
        :param router_id: router_id
 
148
        This method do nothing if there is no router
 
149
        """
 
150
        router_info = self.l3_agent.router_info.get(router_id)
 
151
        if not router_info:
 
152
            return
 
153
        iptables_manager = self.get_router_based_iptables_manager(router_info)
 
154
        iptables_manager.apply()