2014-01-26 FUJITA Tomonori <[email protected]>
> Signed-off-by: FUJITA Tomonori <[email protected]>
> ---
> ryu/services/protocols/vrrp/event.py | 4 +-
> ryu/services/protocols/vrrp/rpc_manager.py | 197
> +++++++++++++++++++++++++++++
> 2 files changed, 199 insertions(+), 2 deletions(-)
> create mode 100644 ryu/services/protocols/vrrp/rpc_manager.py
>
> diff --git a/ryu/services/protocols/vrrp/event.py
> b/ryu/services/protocols/vrrp/event.py
> index b1872c6..e339a96 100644
> --- a/ryu/services/protocols/vrrp/event.py
> +++ b/ryu/services/protocols/vrrp/event.py
> @@ -116,11 +116,11 @@ class VRRPConfig(object):
> advertmisement_interval is in seconds as float. (Not in centiseconds)
> """
> def __init__(self, version=vrrp.VRRP_VERSION_V3, vrid=None,
> - admin_state=None,
> + admin_state=True,
> priority=vrrp.VRRP_PRIORITY_BACKUP_DEFAULT,
> ip_addresses=None,
>
> advertisement_interval=vrrp.VRRP_MAX_ADVER_INT_DEFAULT_IN_SEC,
> preempt_mode=True, preempt_delay=0, accept_mode=False,
> - statistics_interval=None, resource_id=None):
> + statistics_interval=0, resource_id=None):
> # To allow version and priority default
> assert vrid is not None
> assert ip_addresses is not None
> diff --git a/ryu/services/protocols/vrrp/rpc_manager.py
> b/ryu/services/protocols/vrrp/rpc_manager.py
> new file mode 100644
> index 0000000..3aa03b2
> --- /dev/null
> +++ b/ryu/services/protocols/vrrp/rpc_manager.py
> @@ -0,0 +1,197 @@
> +# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation.
> +#
> +# 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
> +import socket
> +import eventlet
> +
> +import netaddr
> +from ryu.base import app_manager
> +from ryu.controller import handler
> +from ryu.services.protocols.vrrp import event as vrrp_event
> +from ryu.services.protocols.vrrp import api as vrrp_api
> +from ryu.lib import rpc
> +from ryu.lib import hub
> +from ryu.lib import mac
> +
> +VRRP_RPC_PORT = 50004 # random
> +CONF = cfg.CONF
> +
> +CONF.register_opts([
> + cfg.IntOpt('vrrp-rpc-port', default=VRRP_RPC_PORT,
> + help='port for vrrp rpc interface')])
> +
> +
> +class RPCError(Exception):
> + pass
> +
> +
> +class Peer(object):
> + def __init__(self, queue):
> + super(Peer, self).__init__()
> + self.queue = queue
> +
> + def _handle_vrrp_request(self, data):
> + self.queue.put((self, data))
> +
> +
> +class RpcVRRPManager(app_manager.RyuApp):
> + def __init__(self, *args, **kwargs):
> + super(RpcVRRPManager, self).__init__(*args, **kwargs)
> + self._args = args
> + self._kwargs = kwargs
> + self._peers = []
> + self._rpc_events = hub.Queue(128)
> + self.serverThread = hub.spawn(self._peer_accept_thread)
>
This should use snakecase.
> + self.event_thread = hub.spawn(self._rpc_request_loop_thread)
> +
> + def _rpc_request_loop_thread(self):
> + while True:
> + (peer, data) = self._rpc_events.get()
> + msgid, target_method, params = data
> + error = None
> + result = None
> + try:
> + if target_method == "vrrp_config":
> + result = self._config(msgid, params)
> + elif target_method == "vrrp_list":
> + result = self._list(msgid, params)
> + elif target_method == "vrrp_config_change":
> + result = self._config_change(msgid, params)
> + else:
> + error = 'Unknown method %s' % (target_method)
> + except RPCError as e:
> + error = str(e)
> + peer._endpoint.send_response(msgid, error=error,
> result=result)
> +
> + def _peer_loop_thread(self, peer):
> + peer._endpoint.serve()
> + # the peer connection is closed
> + self._peers.remove(peer)
> +
> + def _peer_accept_thread(self):
> + server = eventlet.listen(('', CONF.vrrp_rpc_port))
> + while True:
> + new_sock, address = server.accept()
> + peer = Peer(self._rpc_events)
> + table = {
> + rpc.MessageType.REQUEST: peer._handle_vrrp_request,
> + }
> + peer._endpoint = rpc.EndPoint(new_sock, disp_table=table)
> + self._peers.append(peer)
> + hub.spawn(self._peer_loop_thread, peer)
> +
> + def _params_to_dict(self, params, keys):
> + d = {}
> + for k, v in params.items():
> + if k in keys:
> + d[k] = v
> + return d
> +
> + def _config(self, msgid, params):
> + self.logger.debug('handle vrrp_config request')
> + try:
> + param_dict = params[0]
> + except:
> + raise RPCError('parameters are missing')
> +
> + if_params = self._params_to_dict(param_dict,
> + ('primary_ip_address',
> + 'device_name'))
> + # drop vlan support later
> + if_params['vlan_id'] = None
> + if_params['mac_address'] = mac.DONTCARE_STR
> + try:
> + interface = vrrp_event.VRRPInterfaceNetworkDevice(**if_params)
> + except:
> + raise RPCError('parameters are invalid, %s' %
> (str(param_dict)))
> +
> + config_params = self._params_to_dict(param_dict,
> + ('vrid', # mandatory
> + 'ip_addresses', # mandatory
> + 'version',
> + 'admin_state',
> + 'priority',
> + 'advertisement_interval',
> + 'preempt_mode',
> + 'preempt_delay',
> + 'statistics_interval'))
> + try:
> + config = vrrp_event.VRRPConfig(**config_params)
> + except:
> + raise RPCError('parameters are invalid, %s' %
> (str(param_dict)))
> +
> + config_result = vrrp_api.vrrp_config(self, interface, config)
> +
> + api_result = [
> + config_result.config.vrid,
> + config_result.config.priority,
> + str(netaddr.IPAddress(config_result.config.ip_addresses[0]))]
> + return api_result
> +
> + def _lookup_instance(self, vrid):
> + for instance in vrrp_api.vrrp_list(self).instance_list:
> + if vrid == instance.config.vrid:
> + return instance.instance_name
> + return None
> +
> + def _config_change(self, msgid, params):
> + self.logger.debug('handle vrrp_config_change request')
> + try:
> + config_values = params[0]
> + except:
> + raise RPCError('parameters are missing')
> +
> + vrid = config_values.get('vrid')
> + instance_name = self._lookup_instance(vrid)
> + if not instance_name:
> + raise RPCError('vrid %d is not found' % (vrid))
> +
> + priority = config_values.get('priority')
> + interval = config_values.get('advertisement_interval')
> + vrrp_api.vrrp_config_change(self, instance_name,
> priority=priority,
> + advertisement_interval=interval)
> + return {}
> +
> + def _list(self, msgid, params):
> + self.logger.debug('handle vrrp_list request')
> + result = vrrp_api.vrrp_list(self)
> + instance_list = result.instance_list
> + ret_list = []
> + for instance in instance_list:
> + c = instance.config
> + info_dict = {
> + "instance_name": instance.instance_name,
> + "vrid": c.vrid,
> + "version": c.version,
> + "advertisement_interval": c.advertisement_interval,
> + "priority": c.priority,
> + "virtual_ip_address":
> str(netaddr.IPAddress(c.ip_addresses[0]))
> + }
> + ret_list.append(info_dict)
> + return ret_list
> +
> + @handler.set_ev_cls(vrrp_event.EventVRRPStateChanged)
> + def vrrp_state_changed_handler(self, ev):
> + self.logger.info('handle EventVRRPStateChanged')
> + name = ev.instance_name
> + old_state = ev.old_state
> + new_state = ev.new_state
> + vrid = ev.config.vrid
> + self.logger.info('VRID:%s %s: %s -> %s', vrid, name, old_state,
> + new_state)
> + params = {'vrid': vrid, 'old_state': old_state, 'new_state':
> new_state}
> + for peer in self._peers:
> + peer._endpoint.send_notification("notify_status", [params])
> --
> 1.8.3.4 (Apple Git-47)
>
>
>
> ------------------------------------------------------------------------------
> CenturyLink Cloud: The Leader in Enterprise Cloud Services.
> Learn Why More Businesses Are Choosing CenturyLink Cloud For
> Critical Workloads, Development Environments & Everything In Between.
> Get a Quote or Start a Free Trial Today.
>
> http://pubads.g.doubleclick.net/gampad/clk?id=119420431&iu=/4140/ostg.clktrk
> _______________________________________________
> Ryu-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/ryu-devel
>
--
Satoshi Kobayashi <[email protected]>
------------------------------------------------------------------------------
CenturyLink Cloud: The Leader in Enterprise Cloud Services.
Learn Why More Businesses Are Choosing CenturyLink Cloud For
Critical Workloads, Development Environments & Everything In Between.
Get a Quote or Start a Free Trial Today.
http://pubads.g.doubleclick.net/gampad/clk?id=119420431&iu=/4140/ostg.clktrk
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel