6
6
import json
7
7
import subprocess
8
8
9
- SONIC_CFGGEN_PATH = '/usr/local/bin/sonic-cfggen'
10
- MINIGRAPH_PATH = '/etc/sonic/minigraph.xml'
11
- MINIGRAPH_BGP_ASN_KEY = 'minigraph_bgp_asn'
12
- MINIGRAPH_BGP_SESSIONS = 'minigraph_bgp'
9
+ SONIC_CFGGEN_PATH = "/usr/local/bin/sonic-cfggen"
10
+ MINIGRAPH_PATH = "/etc/sonic/minigraph.xml"
11
+ MINIGRAPH_BGP_ASN_KEY = "minigraph_bgp_asn"
12
+ MINIGRAPH_BGP_SESSIONS = "minigraph_bgp"
13
+
14
+ BGP_ADMIN_STATE_YML_PATH = "/etc/sonic/bgp_admin.yml"
13
15
14
16
#
15
17
# Helper functions
16
18
#
17
19
20
+ # Run bash command and print output to stdout
21
+ def run_command (command , pager = False , display_cmd = False ):
22
+ if display_cmd == True :
23
+ click .echo (click .style ("Running command: " , fg = 'cyan' ) + click .style (command , fg = 'green' ))
24
+
25
+ p = subprocess .Popen (command , shell = True , stdout = subprocess .PIPE )
26
+ stdout = p .communicate ()[0 ]
27
+ p .wait ()
28
+
29
+ if len (stdout ) > 0 :
30
+ if pager is True :
31
+ click .echo_via_pager (p .stdout .read ())
32
+ else :
33
+ click .echo (p .stdout .read ())
34
+
35
+ if p .returncode != 0 :
36
+ sys .exit (p .returncode )
37
+
18
38
# Returns BGP ASN as a string
19
39
def _get_bgp_asn_from_minigraph ():
20
40
# Get BGP ASN from minigraph
@@ -28,7 +48,7 @@ def _get_bgp_asn_from_minigraph():
28
48
29
49
# Returns True if a neighbor has the IP address <ipaddress>, False if not
30
50
def _is_neighbor_ipaddress (ipaddress ):
31
- # Get BGP ASN from minigraph
51
+ # Get BGP sessions from minigraph
32
52
proc = subprocess .Popen ([SONIC_CFGGEN_PATH , '-m' , MINIGRAPH_PATH , '--var-json' , MINIGRAPH_BGP_SESSIONS ],
33
53
stdout = subprocess .PIPE ,
34
54
shell = False ,
@@ -43,9 +63,29 @@ def _is_neighbor_ipaddress(ipaddress):
43
63
44
64
return False
45
65
66
+ # Returns list of strings containing IP addresses of all BGP neighbors
67
+ def _get_all_neighbor_ipaddresses ():
68
+ # Get BGP sessions from minigraph
69
+ proc = subprocess .Popen ([SONIC_CFGGEN_PATH , '-m' , MINIGRAPH_PATH , '--var-json' , MINIGRAPH_BGP_SESSIONS ],
70
+ stdout = subprocess .PIPE ,
71
+ shell = False ,
72
+ stderr = subprocess .STDOUT )
73
+ stdout = proc .communicate ()[0 ]
74
+ proc .wait ()
75
+ bgp_session_list = json .loads (stdout .rstrip ('\n ' ))
76
+
77
+ bgp_neighbor_ip_list = []
78
+
79
+ for session in bgp_session_list :
80
+ bgp_neighbor_ip_list .append (session ['addr' ])
81
+
82
+ return bgp_neighbor_ip_list
83
+
84
+
85
+
46
86
# Returns string containing IP address of neighbor with hostname <hostname> or None if <hostname> not a neighbor
47
87
def _get_neighbor_ipaddress_by_hostname (hostname ):
48
- # Get BGP ASN from minigraph
88
+ # Get BGP sessions from minigraph
49
89
proc = subprocess .Popen ([SONIC_CFGGEN_PATH , '-m' , MINIGRAPH_PATH , '--var-json' , MINIGRAPH_BGP_SESSIONS ],
50
90
stdout = subprocess .PIPE ,
51
91
shell = False ,
@@ -56,22 +96,43 @@ def _get_neighbor_ipaddress_by_hostname(hostname):
56
96
57
97
for session in bgp_session_list :
58
98
if session ['name' ] == hostname :
59
- return session ['addr' ];
99
+ return session ['addr' ]
60
100
61
101
return None
62
102
103
+ # Shut down BGP session by IP address and modify bgp_admin.yml accordingly
104
+ def _bgp_session_shutdown (bgp_asn , ipaddress , verbose ):
105
+ click .echo ("Shutting down BGP session with neighbor {}..." .format (ipaddress ))
63
106
64
- # Run bash command and print output to stdout
65
- def run_command (command , pager = False ):
66
- click .echo (click .style ("Command: " , fg = 'cyan' ) + click .style (command , fg = 'green' ))
67
- p = subprocess .Popen (command , shell = True , stdout = subprocess .PIPE )
68
- if pager is True :
69
- click .echo_via_pager (p .stdout .read ())
70
- else :
71
- click .echo (p .stdout .read ())
72
- p .wait ()
73
- if p .returncode != 0 :
74
- sys .exit (p .returncode )
107
+ # Shut down the BGP session
108
+ command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'neighbor {} shutdown'" .format (bgp_asn , ipaddress )
109
+ run_command (command , display_cmd = verbose )
110
+
111
+ if os .path .isfile (BGP_ADMIN_STATE_YML_PATH ):
112
+ # Remove existing item in bgp_admin.yml about the admin state of this neighbor
113
+ command = "sed -i \" /^\s*{}:/d\" {}" .format (ipaddress , BGP_ADMIN_STATE_YML_PATH )
114
+ run_command (command , display_cmd = verbose )
115
+
116
+ # and add a new line mark it as off
117
+ command = "echo \" {}: off\" >> {}" .format (ipaddress , BGP_ADMIN_STATE_YML_PATH )
118
+ run_command (command , display_cmd = verbose )
119
+
120
+ # Start up BGP session by IP address and modify bgp_admin.yml accordingly
121
+ def _bgp_session_startup (bgp_asn , ipaddress , verbose ):
122
+ click .echo ("Starting up BGP session with neighbor {}..." .format (ipaddress ))
123
+
124
+ # Start up the BGP session
125
+ command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'no neighbor {} shutdown'" .format (bgp_asn , ipaddress )
126
+ run_command (command , display_cmd = verbose )
127
+
128
+ if os .path .isfile (BGP_ADMIN_STATE_YML_PATH ):
129
+ # Remove existing item in bgp_admin.yml about the admin state of this neighbor
130
+ command = "sed -i \" /^\s*{}:/d\" {}" .format (ipaddress , BGP_ADMIN_STATE_YML_PATH )
131
+ run_command (command , display_cmd = verbose )
132
+
133
+ # and add a new line mark it as on
134
+ command = "echo \" {}: on\" >> {}" .format (ipaddress , BGP_ADMIN_STATE_YML_PATH )
135
+ run_command (command , display_cmd = verbose )
75
136
76
137
77
138
# This is our main entrypoint - the main 'config' command
@@ -87,7 +148,7 @@ def cli():
87
148
88
149
@cli .group ()
89
150
def bgp ():
90
- """BGP-related tasks"""
151
+ """BGP-related configuration tasks"""
91
152
pass
92
153
93
154
#
@@ -99,11 +160,23 @@ def shutdown():
99
160
"""Shut down BGP session(s)"""
100
161
pass
101
162
163
+ # 'all' subcommand
164
+ @shutdown .command ()
165
+ @click .option ('-v' , '--verbose' , is_flag = True , help = "Enable verbose output" )
166
+ def all (verbose ):
167
+ """Shut down all BGP sessions"""
168
+
169
+ bgp_asn = _get_bgp_asn_from_minigraph ()
170
+ bgp_neighbor_ip_list = _get_all_neighbor_ipaddresses ()
171
+
172
+ for ipaddress in bgp_neighbor_ip_list :
173
+ _bgp_session_shutdown (bgp_asn , ipaddress , verbose )
102
174
103
175
# 'neighbor' subcommand
104
176
@shutdown .command ()
105
- @click .argument ('ipaddr_or_hostname' , required = True )
106
- def neighbor (ipaddr_or_hostname ):
177
+ @click .argument ('ipaddr_or_hostname' , metavar = '<ipaddr_or_hostname>' , required = True )
178
+ @click .option ('-v' , '--verbose' , is_flag = True , help = "Enable verbose output" )
179
+ def neighbor (ipaddr_or_hostname , verbose ):
107
180
"""Shut down BGP session by neighbor IP address or hostname"""
108
181
bgp_asn = _get_bgp_asn_from_minigraph ()
109
182
@@ -117,25 +190,30 @@ def neighbor(ipaddr_or_hostname):
117
190
print "Error: could not locate neighbor '{}'" .format (ipaddr_or_hostname )
118
191
raise click .Abort
119
192
120
- command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'neighbor {} shutdown'" .format (bgp_asn , ipaddress )
121
- run_command (command )
122
- # Remove existing item in bgp_admin.yml about the admin state of this neighbor
123
- command = 'sed -i "/^\s*{}:/d" /etc/sonic/bgp_admin.yml' .format (ipaddress )
124
- run_command (command )
125
- # and add a new line mark it as off
126
- command = 'echo " {}: off" >> /etc/sonic/bgp_admin.yml' .format (ipaddress )
127
- run_command (command )
193
+ _bgp_session_shutdown (bgp_asn , ipaddress , verbose )
194
+
128
195
129
196
@bgp .group ()
130
197
def startup ():
131
198
"""Start up BGP session(s)"""
132
199
pass
133
200
201
+ # 'all' subcommand
202
+ @startup .command ()
203
+ @click .option ('-v' , '--verbose' , is_flag = True , help = "Enable verbose output" )
204
+ def all (verbose ):
205
+ """Start up all BGP sessions"""
206
+ bgp_asn = _get_bgp_asn_from_minigraph ()
207
+ bgp_neighbor_ip_list = _get_all_neighbor_ipaddresses ()
208
+
209
+ for ipaddress in bgp_neighbor_ip_list :
210
+ _bgp_session_startup (bgp_asn , ipaddress , verbose )
134
211
135
212
# 'neighbor' subcommand
136
213
@startup .command ()
137
- @click .argument ('ipaddr_or_hostname' , required = True )
138
- def neighbor (ipaddr_or_hostname ):
214
+ @click .argument ('ipaddr_or_hostname' , metavar = '<ipaddr_or_hostname>' , required = True )
215
+ @click .option ('-v' , '--verbose' , is_flag = True , help = "Enable verbose output" )
216
+ def neighbor (ipaddr_or_hostname , verbose ):
139
217
"""Start up BGP session by neighbor IP address or hostname"""
140
218
bgp_asn = _get_bgp_asn_from_minigraph ()
141
219
@@ -149,14 +227,7 @@ def neighbor(ipaddr_or_hostname):
149
227
print "Error: could not locate neighbor '{}'" .format (ipaddr_or_hostname )
150
228
raise click .Abort
151
229
152
- command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'no neighbor {} shutdown'" .format (bgp_asn , ipaddress )
153
- run_command (command )
154
- # Remove existing item in bgp_admin.yml about the admin state of this neighbor
155
- command = 'sed -i "/^\s*{}:/d" /etc/sonic/bgp_admin.yml' .format (ipaddress )
156
- run_command (command )
157
- # and add a new line mark it as on
158
- command = 'echo " {}: on" >> /etc/sonic/bgp_admin.yml' .format (ipaddress )
159
- run_command (command )
230
+ _bgp_session_startup (bgp_asn , ipaddress , verbose )
160
231
161
232
162
233
if __name__ == '__main__' :
0 commit comments