GitHub Links
The source code below is also available from GitHub at the following locations:
Example Configuration
01 Remote-rpc meachanism works only with ssh-agent setup. The prerequisite for
02 this script to work is the ssh-agent should be configured properly and the
03 ssh connection from the current node to all the peers in the BGP mesh should
04 work without password/passpharse.
05
06 This scripts takes the following input:
07
08 bgp-peer-group BGP peer group name
09 bgp-peer-type BGP peer type
10 local-address IP-address of local machine (This node)
11 local-as-number Local AS Number
12 peer-address IP-address of one of the peer
13
14 'peer-address' is the address of one-of-the member in the BGP mesh.
15
16 The script gets the BGP peer information from 'peer-address' and add this
17 node ('local-address') as neighbor in all the peers. Also configure the
18 peer details locally.
19
20 Run the script from the node which you want to add to BGP mesh.
21
22 Steps to setup ssh-agent.
23 -------------------------
24
25 Note: The below steps are given very briefly, for details please refer the
26 appropriate manuals.
27
28 1) Configure user's to connect.
29
30 Note: User name should be same in desktop and all the peers. Since I am
31 executing this from my desktop with my userid, I have created the
32 same user in all the peers.
33
34 user@cli# show system login user rsankar
35 uid 2000;
36 class super-user;
37
38 user@cli# show system login user rsankar
39 uid 2000;
40 class super-user;
41
42 2) Configure ssh-key and associate the public key with rsankar login account
43 in both the machines.
44
45 Please refer the below JUNOS document for details regarding ssh key generation.
46
47 http://www.juniper.net/techpubs/software/junos/junos90/netconf-guide/creating-a-publicprivate-key-pair.html#id-10314765
48
49 3) Make sure routers are added to ssh-known-hosts under
50 [security ssh-know-hosts]
51
52 4) Run ssh-agent in desktop
53
54 # Execute the below command from bash shell.
55
56 >`ssh-agent -s `
57
58 # Make sure ssh-agent is running.
59
60 >ps -auwwx | grep ssh-agent
61 rsankar 99086 0.0 0.1 3164 2000 ?? Is 3:23PM 0:00.00 ssh-agent -s
62
63 5) Add identities to ssh-agent.
64
65 > ssh-add
66
67 # ssh-add will ask for passphrase, give the passphrase given during the
68 # key generation.
69
70 6) Make sure the ssh forwarding is enabled in your desktop.
71
72 To enable forwarding add the following lines to ~/.ssh/config
73
74 Host *
75 ForwardAgent yes
76 ForwardX11 yes
77
78 7) Login to all the peers and verify the setup. Login should succeed without
79 asking password or passphras
SLAX Script Contents
001 /*
002 * Script to add a node to the existing BGP mesh.
003 *
004 * This script uses the remote-rpc mechanism available from 9.3 onwards.
005 *
006 * Remote-rpc meachanism works only with ssh-agent setup. The prerequisite for
007 * this script to work is the ssh-agent should be configured properly and the
008 * ssh connection from the current node to all the peers in the BGP mesh should
009 * work without password/passpharse.
010 *
011 * This scripts takes the following input:
012 *
013 * bgp-peer-group BGP peer group name
014 * bgp-peer-type BGP peer type
015 * local-address IP-address of local machine (This node)
016 * local-as-number Local AS Number
017 * peer-address IP-address of one of the peer
018 *
019 * 'peer-address' is the address of one-of-the member in the BGP mesh.
020 * The script gets the BGP peer information from 'peer-address' and add this
021 * node ('local-address') as neighbor in all the peers. Also configure the
022 * peer details locally.
023 *
024 * Run the script from the node which you want to add to BGP mesh.
025 *
026 * Steps to setup ssh-agent.
027 * -------------------------
028 *
029 Note: The below steps are given very briefly, for details please refer the
030 appropriate manuals.
031
032 1) Configure user's to connect.
033
034 Note: User name should be same in desktop and all the peers. Since I am
035 executing this from my desktop with my userid, I have created the
036 same user in all the peers.
037
038 user1@ritter# show system login user rsankar
039 uid 2000;
040 class super-user;
041
042 user1@waffy# show system login user rsankar
043 uid 2000;
044 class super-user;
045
046 2) Configure ssh-key and associate the public key with rsankar login account
047 in both the machines.
048
049 Please refer the below JUNOS document for details regarding ssh key generation.
050
051 http://www.juniper.net/techpubs/software/junos/junos90/netconf-guide/creating-a-publicprivate-key-pair.html#id-10314765
052
053 3) Make sure routers are added to ssh-known-hosts under
054 [security ssh-know-hosts]
055
056 4) Run ssh-agent in desktop
057
058 # Execute the below command from bash shell.
059
060 >`ssh-agent -s `
061
062 # Make sure ssh-agent is running.
063
064 >ps -auwwx | grep ssh-agent
065 rsankar 99086 0.0 0.1 3164 2000 ?? Is 3:23PM 0:00.00 ssh-agent -s
066
067 5) Add identities to ssh-agent.
068
069 > ssh-add
070
071 # ssh-add will ask for passphrase, give the passphrase given during the
072 # key generation.
073
074 6) Make sure the ssh forwarding is enabled in your desktop.
075
076 To enable forwarding add the following lines to ~/.ssh/config
077
078 Host *
079 ForwardAgent yes
080 ForwardX11 yes
081
082 7) Login to all the peers and verify the setup. Login should succeed without
083 asking password or passphrase.
084
085 *
086 */
087 version 1.0;
088
089 ns junos = "http://xml.juniper.net/junos/*/junos";
090 ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
091 ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
092
093 import "../import/junos.xsl";
094
095 var $arguments = {
096 <argument> {
097 <name> "bgp-peer-group";
098 <description> "BGP peer group name";
099 }
100 <argument> {
101 <name> "bgp-peer-type";
102 <description> "BGP peer type";
103 }
104 <argument> {
105 <name> "local-as-number";
106 <description> "Local AS Number";
107 }
108 <argument> {
109 <name> "peer-address";
110 <description> "IP-address of one of the peer";
111 }
112 <argument> {
113 <name> "local-address";
114 <description> "IP-address of local machine (This node)";
115 }
116 }
117
118 param $bgp-peer-group;
119 param $bgp-peer-type;
120 param $local-as-number;
121 param $peer-address;
122 param $local-address;
123
124 match / {
125 <op-script-results> {
126 /*
127 * Validate the paramaters passed
128 */
129 if ($bgp-peer-type != "internal" && $bgp-peer-type != "external") {
130 call emit-error($message = "bgp-peer-type is mandatory and should" _
131 " be either 'internal' or 'external'");
132 } else if (jcs:empty($local-address)) {
133 call emit-error($message = "local-address is mandatory");
134 } else if (jcs:empty($local-as-number)) {
135 call emit-error($message = "local-as-number is mandatory");
136 } else if (jcs:empty($peer-address)) {
137 call emit-error($message = "peer-address is mandatory");
138 } else if (jcs:empty($bgp-peer-group)) {
139 call emit-error($message = "bgp-peer-group is mandatory");
140 } else {
141 call main-template();
142 }
143 }
144
145 }
146
147 template main-template()
148 {
149 expr jcs:progress("Connecting locally ... ");
150
151 var $local-con = jcs:open();
152
153 if (jcs:empty($local-con)) {
154 call emit-error($message = "Not able to connect locally");
155 } else {
156 expr jcs:progress("Connected locally ... ");
157
158 var $peer-bgp-config := {
159 call get-peer-bgp-group-config($address = $peer-address);
160 }
161
162 var $peer-group =
163 $peer-bgp-config/configuration/protocols/bgp/group[name == $bgp-peer-group];
164
165 if (not($peer-group)) {
166 call emit-error($message = "BGP configuration for group '" _
167 $bgp-peer-group _ "' does not exist in peer '" _
168 $peer-address _ "'");
169 } else if ($peer-group/type != $bgp-peer-type) {
170 call emit-error($message = "Given peer type does not match with " _
171 "the peer type configured in '" _
172 $peer-address _ "'");
173 } else {
174 expr jcs:progress("Adding this node as peer in all the BGP ",
175 "peers ...");
176
177 call add-bgp-peer($peer = $peer-address);
178 for-each ($peer-group/neighbor) {
179 if (name != $local-address) {
180 call add-bgp-peer($peer = name);
181 }
182 }
183
184 expr jcs:progress("Added this node as peer in all the BGP ",
185 "peers ...");
186
187 /*
188 * BGP group config in the given peer will not have its own
189 * entry in 'protocols bgp group <group-name> neighbor' hierarchy.
190 * So, get the detail about the given peer from one of the
191 * neighbor configured.
192 */
193
194 var $another-peer-bgp-config := {
195 call get-peer-bgp-group-config($address =
196 $peer-group/neighbor/name);
197 }
198
199 var $given-peer-detail =
200 $another-peer-bgp-config/configuration/protocols/bgp/group[name == $bgp-peer-group]/neighbor[name == $peer-address];
201
202
203 expr jcs:progress("Configuring BGP locally ...");
204
205 var $local-xml = {
206 <configuration> {
207 <protocols> {
208 <bgp> {
209 <group> {
210 <name> $bgp-peer-group;
211 <type> $bgp-peer-type;
212 <local-as> {
213 <as-number> $local-as-number;
214 }
215 <local-address> $local-address;
216 for-each ($peer-group/neighbor) {
217 if (name != $local-address) {
218 copy-of .;
219 }
220 }
221 copy-of $given-peer-detail;
222 }
223 }
224 }
225 }
226 }
227
228 var $results := {
229 call jcs:load-configuration($connection = $local-con,
230 $configuration = $local-xml);
231 }
232
233 if ($results//xnm:error) {
234 call emit-warning($message = "Got the following error while " _
235 "adding configuring BGP locally");
236
237 for-each ($results//xnm:error) {
238 call emit-error($message = message);
239 }
240 } else {
241 expr jcs:progress("Successfully configured BGP locally");
242 }
243 }
244 expr jcs:close($local-con);
245 }
246 }
247
248 /*
249 * Add the current node as BGP peer in the given peer machine
250 */
251 template add-bgp-peer($peer)
252 {
253
254 expr jcs:progress("Adding this node as peer in '", $peer, "' ...");
255
256 expr jcs:progress("Connecting to peer '", $peer, "' ...");
257
258 var $conn = jcs:open($peer);
259
260 var $xml = {
261 <configuration> {
262 <protocols> {
263 <bgp> {
264 <group> {
265 <name> $bgp-peer-group;
266 <type> $bgp-peer-type;
267 <neighbor> {
268 <name> $local-address;
269 if ($bgp-peer-type == "external") {
270 <peer-as> $local-as-number;
271 }
272 }
273 }
274 }
275 }
276 }
277 }
278
279 if (jcs:empty($conn)) {
280 call emit-warning($message = "Not able to connect to peer " _
281 $peer-address);
282 call emit-warning($message = "Not able to add this node as peer in '" _
283 $peer _ "', add it manually");
284 } else {
285
286 expr jcs:progress("Connected to peer '", $peer, "' ...");
287 expr jcs:progress("Loading configuration on to peer '", $peer, "' ...");
288
289 var $results := {
290 call jcs:load-configuration($connection = $conn,
291 $configuration = $xml);
292 }
293
294 if ($results//xnm:error) {
295 call emit-warning($message = "Got the following error while " _
296 "adding the node as peer in '" _ $peer _
297 "', add it manually");
298
299 for-each ($results//xnm:error) {
300 call emit-error($message = message);
301 }
302 } else {
303 expr jcs:progress("Successfully loaded configuration on to peer '",
304 $peer, "' ...");
305 }
306 }
307
308 expr jcs:close($conn);
309
310 }
311
312 /*
313 * Get the bgp group configuration of the peer
314 */
315 template get-peer-bgp-group-config ($address)
316 {
317 var $conn = jcs:open($address);
318
319 if (jcs:empty($conn)) {
320 call emit-error($message = "Not able to connect to peer " _ $address);
321 }
322
323 if ($conn) {
324 var $get-config-remote = {
325 <get-configuration database="committed" inherit="inherit"> {
326 <configuration> {
327 <protocols> {
328 <bgp> {
329 <group> {
330 <name> $bgp-peer-group;
331 }
332 }
333 }
334 }
335 }
336 }
337
338 expr jcs:progress("Getting BGP group '", $bgp-peer-group,
339 "' configuration from '", $address, "' ...");
340
341 var $peer-config = jcs:execute($conn, $get-config-remote);
342
343 expr jcs:close($conn);
344
345 copy-of $peer-config;
346 }
347 }
348
349 /*
350 * Emit the give error message
351 */
352 template emit-error($message) {
353 <xnm:error> {
354 <message> $message;
355 }
356 }
357
358 /*
359 * Emit the give warning message
360 */
361 template emit-warning($message) {
362 <xnm:warning> {
363 <message> $message;
364 }
365 }
XML Script Contents
01 <?xml version="1.0"?>
02 <script>
03 <title>add-node-bgp.slax</title>
04 <author>rsankar</author>
05 <synopsis>
06 Auto-configure all nodes via remote-rpc mechanism when a node is inserted to an existing BGP mesh
07 </synopsis>
08 <coe>op</coe>
09 <type>protocols</type>
10
11 <description>
12 This script uses the remote-rpc (cross-box scripting) mechanism available from 9.3 onwards
13
14 </description>
15
16 <example>
17 <title>Configuration</title>
18 <description>Configuration required for this op script.</description>
19 <config>example-1.conf</config>
20 </example>
21
22 <xhtml:script xmlns:xhtml="http://www.w3.org/1999/xhtml"
23 src="../../../../../web/leaf.js"
24 type="text/javascript"/>
25 </script>