backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / services / protocols / vrrp / manager.py
1 # Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
2 # Copyright (C) 2013 Isaku Yamahata <yamahata at private email ne jp>
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain 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,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13 # implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 """
18 VRRP manager that manages VRRP router instances
19 VRRPManager creates/deletes VRRPRouter, VRRPInterfaceMonitor
20 dynamically as requested.
21
22 Usage example
23 PYTHONPATH=. ./bin/ryu-manager --verbose \
24              ryu.services.protocols.vrrp.manager \
25              ryu.services.protocols.vrrp.dumper
26 """
27
28 import time
29
30 from ryu.base import app_manager
31 from ryu.controller import handler
32 from ryu.lib import hub
33 from ryu.services.protocols.vrrp import event as vrrp_event
34 from ryu.services.protocols.vrrp import monitor as vrrp_monitor
35 from ryu.services.protocols.vrrp import router as vrrp_router
36
37
38 class VRRPInstance(object):
39     def __init__(self, name, monitor_name, config, interface):
40         super(VRRPInstance, self).__init__()
41         self.name = name                        # vrrp_router.name
42         self.monitor_name = monitor_name        # interface_monitor.name
43         self.config = config
44         self.interface = interface
45         self.state = None
46
47     def state_changed(self, new_state):
48         self.state = new_state
49
50
51 class VRRPManager(app_manager.RyuApp):
52     @staticmethod
53     def _instance_name(interface, vrid, is_ipv6):
54         ip_version = 'ipv6' if is_ipv6 else 'ipv4'
55         return 'VRRP-Router-%s-%d-%s' % (str(interface), vrid, ip_version)
56
57     def __init__(self, *args, **kwargs):
58         super(VRRPManager, self).__init__(*args, **kwargs)
59         self._args = args
60         self._kwargs = kwargs
61         self.name = vrrp_event.VRRP_MANAGER_NAME
62         self._instances = {}    # name -> VRRPInstance
63         self.shutdown = hub.Queue()
64
65     def start(self):
66         t = hub.spawn(self._shutdown_loop)
67         super(VRRPManager, self).start()
68         return t
69
70     @handler.set_ev_cls(vrrp_event.EventVRRPConfigRequest)
71     def config_request_handler(self, ev):
72         config = ev.config
73         interface = ev.interface
74         name = self._instance_name(interface, config.vrid, config.is_ipv6)
75         if name in self._instances:
76             rep = vrrp_event.EventVRRPConfigReply(None, interface, config)
77             self.reply_to_request(ev, rep)
78             return
79
80         statistics = VRRPStatistics(name, config.resource_id,
81                                     config.statistics_interval)
82         monitor = vrrp_monitor.VRRPInterfaceMonitor.factory(
83             interface, config, name, statistics, *self._args, **self._kwargs)
84         router = vrrp_router.VRRPRouter.factory(name, monitor.name, interface,
85                                                 config, statistics,
86                                                 *self._args, **self._kwargs)
87         # Event piping
88         #  vrrp_router -> vrrp_manager
89         #    EventVRRPStateChanged to vrrp_manager is handled by framework
90         #  vrrp_manager -> vrrp_rouer
91         self.register_observer(vrrp_event.EventVRRPShutdownRequest,
92                                router.name)
93         #  vrrp_router -> vrrp_monitor
94         router.register_observer(vrrp_event.EventVRRPStateChanged,
95                                  monitor.name)
96         router.register_observer(vrrp_event.EventVRRPTransmitRequest,
97                                  monitor.name)
98         #  vrrp_interface_monitor -> vrrp_router
99         monitor.register_observer(vrrp_event.EventVRRPReceived, router.name)
100
101         instance = VRRPInstance(name, monitor.name, config, interface)
102         self._instances[name] = instance
103         # self.logger.debug('report_bricks')
104         # app_manager.AppManager.get_instance().report_bricks()   # debug
105         monitor.start()
106         router.start()
107
108         rep = vrrp_event.EventVRRPConfigReply(instance.name, interface, config)
109         self.reply_to_request(ev, rep)
110
111     def _proxy_event(self, ev):
112         name = ev.instance_name
113         instance = self._instances.get(name, None)
114         if not instance:
115             self.logger.info('unknown vrrp router %s', name)
116             return
117         self.send_event(instance.name, ev)
118
119     @handler.set_ev_cls(vrrp_event.EventVRRPShutdownRequest)
120     def shutdown_request_handler(self, ev):
121         self._proxy_event(ev)
122
123     @handler.set_ev_cls(vrrp_event.EventVRRPConfigChangeRequest)
124     def config_change_request_handler(self, ev):
125         self._proxy_event(ev)
126
127     @handler.set_ev_cls(vrrp_event.EventVRRPStateChanged)
128     def state_change_handler(self, ev):
129         instance = self._instances.get(ev.instance_name, None)
130         assert instance is not None
131         instance.state_changed(ev.new_state)
132         if ev.old_state and ev.new_state == vrrp_event.VRRP_STATE_INITIALIZE:
133             self.shutdown.put(instance)
134
135     def _shutdown_loop(self):
136         app_mgr = app_manager.AppManager.get_instance()
137         while self.is_active or not self.shutdown.empty():
138             instance = self.shutdown.get()
139             app_mgr.uninstantiate(instance.name)
140             app_mgr.uninstantiate(instance.monitor_name)
141             del self._instances[instance.name]
142
143     @handler.set_ev_cls(vrrp_event.EventVRRPListRequest)
144     def list_request_handler(self, ev):
145         instance_name = ev.instance_name
146         if instance_name is None:
147             instance_list = [vrrp_event.VRRPInstance(
148                 instance.name, instance.monitor_name,
149                 instance.config, instance.interface, instance.state)
150                 for instance in self._instances.values()]
151         else:
152             instance = self._instances.get(instance_name, None)
153             if instance is None:
154                 instance_list = []
155             else:
156                 instance_list = [vrrp_event.VRRPInstance(
157                     instance_name, instance.monitor_name,
158                     instance.config, instance.interface, instance.state)]
159
160         vrrp_list = vrrp_event.EventVRRPListReply(instance_list)
161         self.reply_to_request(ev, vrrp_list)
162
163
164 class VRRPStatistics(object):
165     def __init__(self, name, resource_id, statistics_interval):
166         self.name = name
167         self.resource_id = resource_id
168         self.statistics_interval = statistics_interval
169         self.tx_vrrp_packets = 0
170         self.rx_vrrp_packets = 0
171         self.rx_vrrp_zero_prio_packets = 0
172         self.tx_vrrp_zero_prio_packets = 0
173         self.rx_vrrp_invalid_packets = 0
174         self.rx_vrrp_bad_auth = 0
175         self.idle_to_master_transitions = 0
176         self.idle_to_backup_transitions = 0
177         self.backup_to_master_transitions = 0
178         self.master_to_backup_transitions = 0
179
180     def get_stats(self):
181         ts = time.strftime("%Y-%m-%dT%H:%M:%S")
182         stats_dict = dict(
183             timestamp=ts,
184             resource_id=self.resource_id,
185             tx_vrrp_packets=self.tx_vrrp_packets,
186             rx_vrrp_packets=self.rx_vrrp_packets,
187             rx_vrrp_zero_prio_packets=self.rx_vrrp_zero_prio_packets,
188             tx_vrrp_zero_prio_packets=self.tx_vrrp_zero_prio_packets,
189             rx_vrrp_invalid_packets=self.rx_vrrp_invalid_packets,
190             rx_vrrp_bad_auth=self.rx_vrrp_bad_auth,
191             idle_to_master_transitions=self.idle_to_master_transitions,
192             idle_to_backup_transitions=self.idle_to_backup_transitions,
193             backup_to_master_transitions=self.backup_to_master_transitions,
194             master_to_backup_transitions=self.master_to_backup_transitions
195         )
196         return stats_dict