Completed
Push — master ( f8c35a...0dc7c6 )
by Thomas
14:34
created

_show_adjrib_callback()   B

Complexity

Conditions 7

Size

Total Lines 20
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 18
nop 7
dl 0
loc 20
rs 8
c 0
b 0
f 0
1
# encoding: utf-8
2
"""
3
line/rib.py
4
5
Created by Thomas Mangin on 2017-07-01.
6
Copyright (c) 2009-2017 Exa Networks. All rights reserved.
7
License: 3-clause BSD. (See the COPYRIGHT file)
8
"""
9
10
from exabgp.reactor.api.command.command import Command
11
from exabgp.reactor.api.command.limit import match_neighbors
12
from exabgp.reactor.api.command.limit import extract_neighbors
13
14
from exabgp.bgp.message.update.nlri.nlri import NLRI
15
from exabgp.bgp.message.update.nlri.inet import INET
16
from exabgp.bgp.message.update.nlri.flow import Flow
17
from exabgp.bgp.message.update.nlri.vpls import VPLS
18
from exabgp.bgp.message.update.nlri.evpn.nlri import EVPN
19
20
from exabgp.configuration.environment import environment
21
22
23
def register_rib ():
24
	pass
25
26
27
def _show_adjrib_callback(reactor, service, last, route_type, advertised, rib_name, extensive):
28
	def callback ():
29
		lines_per_yield = environment.settings().api.chunk
30
		if last in ('routes', 'extensive', 'static', 'flow', 'l2vpn'):
31
			peers = reactor.peers()
32
		else:
33
			peers = [n for n in reactor.peers() if 'neighbor %s' % last in n]
34
		for key in peers:
35
			routes = reactor.neighor_rib(key, rib_name, advertised)
36
			while routes:
37
				changes, routes = routes[:lines_per_yield], routes[lines_per_yield:]
38
				for change in changes:
39
					if isinstance(change.nlri, route_type):
40
						if extensive:
41
							reactor.processes.write(service,'%s %s %s' % (reactor.neighbor_name(key),'%s %s' % change.nlri.family(),change.extensive()))
42
						else:
43
							reactor.processes.write(service,'neighbor %s %s %s' % (reactor.neighbor_ip(key),'%s %s' % change.nlri.family(),str(change.nlri)))
44
				yield True
45
		reactor.processes.answer_done(service)
46
	return callback
47
48
49
@Command.register('text', 'show adj-rib out', False, ['extensive', ])
50
@Command.register('text', 'show adj-rib in', False, ['extensive', ])
51
def show_adj_rib (self, reactor, service, line):
52
	words = line.split()
53
	extensive = line.endswith(' extensive')
54
	try:
55
		rib = words[2]
56
		if not rib in ('in','out'):
57
			reactor.processes.answer_error(service)
58
			return False
59
	except IndexError:
60
		if words[1] == 'adj-rib-in':
61
			rib = 'in'
62
		elif words[1] == 'adj-rib-out':
63
			rib = 'out'
64
		else:
65
			reactor.processes.answer_error(service)
66
			return False
67
68
	if rib not in ('in','out'):
69
		reactor.processes.answer_error(service)
70
		return False
71
72
	klass = NLRI
73
74
	if 'inet' in words:
75
		klass = INET
76
	elif 'flow' in words:
77
		klass = Flow
78
	elif 'l2vpn' in words:
79
		klass = (VPLS, EVPN)
80
81
	for remove in ('show','adj-rib','adj-rib-in','adj-rib-out','in','out','extensive'):
82
		if remove in words:
83
			words.remove(remove)
84
	last = '' if not words else words[0]
85
	callback = _show_adjrib_callback(reactor, service, last, klass, False, rib, extensive)
86
	reactor.asynchronous.schedule(service, line, callback())
87
	return True
88
89
90
@Command.register('text','flush adj-rib out')
91
def flush_adj_rib_out (self, reactor, service, line):
92
	def callback (self, peers):
93
		self.log_message("Flushing adjb-rib out for %s" % ', '.join(peers if peers else []) if peers is not None else 'all peers')
94
		for peer_name in peers:
95
			reactor.neighbor_rib_resend(peer_name)
96
			yield False
97
98
		reactor.processes.answer_done(service)
99
100
	try:
101
		descriptions,command = extract_neighbors(line)
102
		peers = match_neighbors(reactor.peers(),descriptions)
103
		if not peers:
104
			self.log_failure('no neighbor matching the command : %s' % command,'warning')
105
			reactor.processes.answer_error(service)
106
			return False
107
		reactor.asynchronous.schedule(service, command, callback(self, peers))
108
		return True
109
	except ValueError:
110
		self.log_failure('issue parsing the command')
111
		reactor.processes.answer_error(service)
112
		return False
113
	except IndexError:
114
		self.log_failure('issue parsing the command')
115
		reactor.processes.answer_error(service)
116
		return False
117
118
119
@Command.register('text','clear adj-rib')
120
def clear_adj_rib (self, reactor, service, line):
121
	def callback (self, peers, direction):
122
		self.log_message("clearing adjb-rib-%s for %s" % (direction,', '.join(peers if peers else []) if peers is not None else 'all peers'))
123
		for peer_name in peers:
124
			if direction == 'out':
125
				reactor.neighbor_rib_out_withdraw(peer_name)
126
			else:
127
				reactor.neighbor_rib_in_clear(peer_name)
128
			yield False
129
130
		reactor.processes.answer_done(service)
131
132
	try:
133
		descriptions,command = extract_neighbors(line)
134
		peers = match_neighbors(reactor.peers(),descriptions)
135
		if not peers:
136
			self.log_failure('no neighbor matching the command : %s' % command,'warning')
137
			reactor.processes.answer_error(service)
138
			return False
139
		words = line.split()
140
		direction = 'in' if 'adj-rib-in' in words or 'in' in words else 'out'
141
		reactor.asynchronous.schedule(service, command, callback(self, peers, direction))
142
		return True
143
	except ValueError:
144
		self.log_failure('issue parsing the command')
145
		reactor.processes.answer_error(service)
146
		return False
147
	except IndexError:
148
		self.log_failure('issue parsing the command')
149
		reactor.processes.answer_error(service)
150
		return False
151