a47f1e6352
Closes-Bug: #1302007 Change-Id: I02a9b92eea06010569d3d9c5a987e69f89b23be5
149 lines
4.9 KiB
Python
149 lines
4.9 KiB
Python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
#
|
|
# Copyright 2013, Nachi Ueno, NTT I3, Inc.
|
|
# All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
from oslo.config import cfg
|
|
|
|
from neutron.agent import l3_agent
|
|
from neutron.extensions import vpnaas
|
|
from neutron.openstack.common import importutils
|
|
|
|
vpn_agent_opts = [
|
|
cfg.MultiStrOpt(
|
|
'vpn_device_driver',
|
|
default=['neutron.services.vpn.device_drivers.'
|
|
'ipsec.OpenSwanDriver'],
|
|
help=_("The vpn device drivers Neutron will use")),
|
|
]
|
|
cfg.CONF.register_opts(vpn_agent_opts, 'vpnagent')
|
|
|
|
|
|
class VPNAgent(l3_agent.L3NATAgentWithStateReport):
|
|
"""VPNAgent class which can handle vpn service drivers."""
|
|
def __init__(self, host, conf=None):
|
|
super(VPNAgent, self).__init__(host=host, conf=conf)
|
|
self.setup_device_drivers(host)
|
|
|
|
def setup_device_drivers(self, host):
|
|
"""Setting up device drivers.
|
|
|
|
:param host: hostname. This is needed for rpc
|
|
Each devices will stays as processes.
|
|
They will communiate with
|
|
server side service plugin using rpc with
|
|
device specific rpc topic.
|
|
:returns: None
|
|
"""
|
|
device_drivers = cfg.CONF.vpnagent.vpn_device_driver
|
|
self.devices = []
|
|
for device_driver in device_drivers:
|
|
try:
|
|
self.devices.append(
|
|
importutils.import_object(device_driver, self, host))
|
|
except ImportError:
|
|
raise vpnaas.DeviceDriverImportError(
|
|
device_driver=device_driver)
|
|
|
|
def get_namespace(self, router_id):
|
|
"""Get namespace of router.
|
|
|
|
:router_id: router_id
|
|
:returns: namespace string.
|
|
Note if the router is not exist, this function
|
|
returns None
|
|
"""
|
|
router_info = self.router_info.get(router_id)
|
|
if not router_info:
|
|
return
|
|
return router_info.ns_name
|
|
|
|
def add_nat_rule(self, router_id, chain, rule, top=False):
|
|
"""Add nat rule in namespace.
|
|
|
|
:param router_id: router_id
|
|
:param chain: a string of chain name
|
|
:param rule: a string of rule
|
|
:param top: if top is true, the rule
|
|
will be placed on the top of chain
|
|
Note if there is no rotuer, this method do nothing
|
|
"""
|
|
router_info = self.router_info.get(router_id)
|
|
if not router_info:
|
|
return
|
|
router_info.iptables_manager.ipv4['nat'].add_rule(
|
|
chain, rule, top=top)
|
|
|
|
def remove_nat_rule(self, router_id, chain, rule, top=False):
|
|
"""Remove nat rule in namespace.
|
|
|
|
:param router_id: router_id
|
|
:param chain: a string of chain name
|
|
:param rule: a string of rule
|
|
:param top: unused
|
|
needed to have same argument with add_nat_rule
|
|
"""
|
|
router_info = self.router_info.get(router_id)
|
|
if not router_info:
|
|
return
|
|
router_info.iptables_manager.ipv4['nat'].remove_rule(
|
|
chain, rule)
|
|
|
|
def iptables_apply(self, router_id):
|
|
"""Apply IPtables.
|
|
|
|
:param router_id: router_id
|
|
This method do nothing if there is no router
|
|
"""
|
|
router_info = self.router_info.get(router_id)
|
|
if not router_info:
|
|
return
|
|
router_info.iptables_manager.apply()
|
|
|
|
def _router_added(self, router_id, router):
|
|
"""Router added event.
|
|
|
|
This method overwrites parent class method.
|
|
:param router_id: id of added router
|
|
:param router: dict of rotuer
|
|
"""
|
|
super(VPNAgent, self)._router_added(router_id, router)
|
|
for device in self.devices:
|
|
device.create_router(router_id)
|
|
|
|
def _router_removed(self, router_id):
|
|
"""Router removed event.
|
|
|
|
This method overwrites parent class method.
|
|
:param router_id: id of removed router
|
|
"""
|
|
super(VPNAgent, self)._router_removed(router_id)
|
|
for device in self.devices:
|
|
device.destroy_router(router_id)
|
|
|
|
def _process_routers(self, routers, all_routers=False):
|
|
"""Router sync event.
|
|
|
|
This method overwrites parent class method.
|
|
:param routers: list of routers
|
|
"""
|
|
super(VPNAgent, self)._process_routers(routers, all_routers)
|
|
for device in self.devices:
|
|
device.sync(self.context, routers)
|
|
|
|
|
|
def main():
|
|
l3_agent.main(
|
|
manager='neutron.services.vpn.agent.VPNAgent')
|