Upgrade ietf-{inet,yang}-types to 2013-07-15
[vpnservice.git] / bgpmanager / bgpmanager-impl / src / main / java / org / opendaylight / bgpmanager / ConfigureBgpCli.java
1 /*
2  * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.bgpmanager;
10
11 import java.net.InetAddress;
12 import java.net.UnknownHostException;
13 import java.util.HashMap;
14 import java.util.Map;
15 import java.util.concurrent.Future;
16
17 import org.apache.karaf.shell.commands.*;
18 import org.apache.karaf.shell.console.OsgiCommandSupport;
19 import org.opendaylight.bgpmanager.thrift.gen.af_afi;
20 import org.opendaylight.bgpmanager.thrift.gen.af_safi;
21 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.*;
22 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.*;
23 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.*;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
26 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29 import java.util.*;
30
31 import com.google.common.base.Optional;
32 import com.google.common.util.concurrent.FutureCallback;
33 import com.google.common.util.concurrent.Futures;
34
35 @Command(scope = "odl", name = "configure-bgp", description = "")
36 public class ConfigureBgpCli extends OsgiCommandSupport {
37
38     private static final Logger LOGGER = LoggerFactory.getLogger(ConfigureBgpCli.class);
39
40     private static BgpManager bgpManager;
41
42     public static void setBgpManager(BgpManager mgr) {
43         bgpManager = mgr;
44     }
45
46     @Option(name = "-op", aliases = {"--operation","--op"}, description = "[start-bgp-server, stop-bgp-server, add-neighbor, delete-neighbor, graceful-restart, enable-log ]",
47             required = false, multiValued = false)
48     String op;
49
50     //exec configure-bgp  add-neighbor --ip <neighbor-ip> --as-num <as-num> --address-family <af> --use-source-ip <sip> --ebgp-multihops <em> --next-hop <nh>
51
52     @Option(name = "--as-num", description = "as number of the bgp neighbor", required = false, multiValued = false)
53     String asNumber = null;
54
55     @Option(name = "--ip", description = "ip of the bgp neighbor", required = false, multiValued = false)
56     String ip = null;
57
58     @Option(name = "--address-family", description = "address family of the bgp neighbor SAFI_IPV4_LABELED_UNICAST|SAFI_MPLS_VPN", 
59             required = false, multiValued = false)
60     String addressFamily = null;
61
62     @Option(name = "--use-source-ip", description = "source ip to be used for neighborship connection establishment", 
63             required = false, multiValued = false)
64     String sourceIp = null;
65
66     @Option(name = "--ebgp-multihops", description = "ebgp multihops of the bgp neighbor", 
67             required = false, multiValued = false)
68     String ebgpMultihops = null;
69
70     @Option(name = "--router-id", description = "router id of the bgp instance", 
71             required = false, multiValued = false)
72     String routerId = null;
73
74     @Option(name = "--stalepath-time", description = "the time delay after bgp restart stalepaths are cleaned", 
75             required = false, multiValued = false)
76     String stalePathTime = null;
77
78     @Option(name = "--log-file-path", description = "bgp log file path", 
79             required = false, multiValued = false)
80     String logFile = null;
81
82     @Option(name = "--log-level", description = "log level emergencies,alerts,critical,errors,warnings,notifications,informational,debugging",
83             required = false, multiValued = false)
84     String logLevel = null;
85
86     enum LogLevels {
87         emergencies,alerts,critical,errors,warnings,notifications,informational,debugging;
88     }
89
90     @Override
91     protected Object doExecute() throws Exception {
92         try {
93             if (op == null) {
94                 System.out.println("Please provide valid operation");
95                 usage();
96                 System.out.println("exec configure-bgp -op [start-bgp-server | stop-bgp-server | add-neighbor | delete-neighbor| graceful-restart| enable-log ]");
97             }
98             switch(op) {
99             case "start-bgp-server":
100                 startBgp();
101                 break;
102             case "stop-bgp-server":
103                 stopBgp();
104                 break;
105             case "add-neighbor":
106                 addNeighbor();
107                 break;
108             case "delete-neighbor":
109                 deleteNeighbor();
110                 break;
111             case "graceful-restart":
112                 configureGR();
113                 break;
114             case "enable-log" :
115                 enableBgpLogLevel();
116                 break;
117             default :
118                 System.out.println("invalid operation");
119                 usage();
120                 System.out.println("exec configure-bgp -op [start-bgp-server | stop-bgp-server | add-neighbor | delete-neighbor| graceful-restart| enable-log ]");
121             }
122         } catch (Exception e) {
123             log.error("failed to handle the command",e);
124         }
125         return null;
126     }
127
128     public boolean validateStalepathTime() {
129         try {
130             int time = Integer.parseInt(stalePathTime);
131             if (time < 30 || time > 3600) {
132                 System.out.println("invalid stale path time valid range [30-3600]");
133                 printGracefulRestartHelp();
134                 return false;
135             }
136         } catch (Exception e) {
137             System.out.println("invalid stale path time");
138             printGracefulRestartHelp();
139             return false;
140         }
141         return true;
142     }
143
144     private void configureGR() throws Exception {
145         boolean validStalepathTime = validateStalepathTime();
146         if (!validStalepathTime) {
147             return;
148         }
149         bgpManager.configureGR(Integer.parseInt(stalePathTime));
150     }
151
152     private void deleteNeighbor() throws Exception {
153         if (ip == null || !validateIp(ip)) {
154             System.out.println("invalid neighbor ip");
155             printDeleteNeighborHelp();
156             return;
157         }
158         long asNo = getAsNumber(ip);
159         if (asNo < 0) {
160             System.out.println("neighbor does not exist");
161             printDeleteNeighborHelp();
162             return;
163         }
164         bgpManager.deleteNeighbor(ip);
165     }
166
167     public long getAsNumber(String nbrIp) {
168         Bgp conf = bgpManager.getConfig();
169         if (conf == null) {
170           return -1;
171         }
172         List<Neighbors> nbrs = conf.getNeighbors();
173         if (nbrs == null) {
174           return -1;
175         }
176         for (Neighbors nbr : nbrs) {
177           if (nbrIp.equals(nbr.getAddress().getValue())) {
178              return nbr.getRemoteAs().longValue();
179           }
180         }
181         return -1;
182     }
183
184     private void stopBgp() throws Exception {
185         Bgp conf = bgpManager.getConfig();
186         if (conf == null) {
187             return;
188         }
189         List<Neighbors> nbrs = conf.getNeighbors();
190         if (nbrs != null && nbrs.size() > 0) {
191             System.err.println("error: all BGP congiguration must be deleted before stopping the router instance");
192             return;
193         }
194         bgpManager.stopBgp();
195     }
196
197     void usage() {
198         System.out.println("usage:");
199     }
200
201     void printStartBgpHelp() {
202         usage();
203         System.out.println("exec configure-bgp -op start-bgp-server --as-num <asnum> --router-id <routerid> [--stalepath-time <time>]");
204     }
205
206     void printAddNeighborHelp() {
207         usage();
208         System.out.println("exec configure-bgp -op add-neighbor --ip <neighbor-ip> --as-num <as-num> [--address-family <af>]  [--use-source-ip <sip>] [--ebgp-multihops <em> ]");
209     }
210
211     void printDeleteNeighborHelp() {
212         usage();
213         System.out.println("exec configure-bgp -op delete-neighbor --ip <neighbor-ip>");
214     }
215
216     void printEnableLogHelp() {
217         usage();
218         System.out.println("exec configure-bgp -op enable-logging --filename <filename> --log-level [emergencies|alerts|critical|errors|warnings|notifications|informational|debugging]");
219     }
220
221     void printGracefulRestartHelp() {
222         usage();
223         System.out.println("exec configure-bgp -op graceful-restart --stalepath-time <30-3600>");
224     }
225
226     private void startBgp() throws Exception {
227         boolean validRouterId = false;
228
229         if (bgpManager.getConfig() != null &&
230                bgpManager.getConfig().getAsId() != null) {
231             System.out.println("bgp is already started please use stop-bgp-server and start again");
232             return;
233         }
234         try {
235             long asno = Long.valueOf(asNumber);
236             switch((int)asno) {
237             case 0:
238             case 65535:
239             case 23456:
240                 System.out.println("reserved as number supplied ");
241                 printStartBgpHelp();
242                 return;
243             }
244             if (asno <= 0 || asno > Integer.MAX_VALUE) {
245                 System.out.println("invalid as number , supported range [1,"+Integer.MAX_VALUE+"]");
246                 printStartBgpHelp();
247                 return;
248             }
249         } catch (Exception e) {
250             System.out.println("invalid as number ");
251             printStartBgpHelp();
252             return;
253         }
254         validRouterId = validateIp(routerId);
255         if (!validRouterId) {
256             System.out.println("invalid router id please supply valid ip address");
257             printStartBgpHelp();
258             return;
259         }
260
261         if (stalePathTime != null) {
262             boolean validStalepathTime = validateStalepathTime();
263             if (!validStalepathTime) {
264                 return;
265             }
266         }
267         bgpManager.startBgp(Integer.parseInt(asNumber), routerId, 
268           stalePathTime == null? 0 : Integer.parseInt(stalePathTime), false);
269     }
270
271     protected void addNeighbor() throws Exception {
272         try {
273             long asno = Long.valueOf(asNumber);
274             switch((int)asno) {
275             case 0:
276             case 65535:
277             case 23456:
278                 System.out.println("reserved as number supplied ");
279                 printStartBgpHelp();
280                 return;
281             }
282             if (asno <= 0 || asno > Integer.MAX_VALUE) {
283                 System.out.println("invalid as number , supported range [1,"+Integer.MAX_VALUE+"]");
284                 printAddNeighborHelp();
285                 return;
286             }
287         } catch (Exception e) {
288             System.out.println("invalid as number");
289             printAddNeighborHelp();
290             return;
291         }
292         boolean validIp = validateIp(ip);
293         if (!validIp) {
294             System.out.println("invalid neighbor ip");
295             printAddNeighborHelp();
296             return;
297         }
298
299         if (sourceIp != null) {
300             validIp = validateIp(sourceIp);
301             if (!validIp) {
302                 System.out.println("invalid source ip");
303                 printAddNeighborHelp();
304                 return;
305             }
306         }
307
308         if (ebgpMultihops != null) {
309             try {
310                 long val = Long.valueOf(ebgpMultihops);
311                 if (val < 1 || val > 255) {
312                     System.out.println("invalid ebgpMultihops number , valid range [1,255] ");
313                     printAddNeighborHelp();
314                     return;
315                 }
316             } catch (Exception e) {
317                 System.out.println("invalid ebgpMultihops number, valid range [1-255]");
318                 printAddNeighborHelp();
319                 return;
320             }
321         }
322         if (addressFamily != null) {
323             try {
324                 af_safi.valueOf(addressFamily);
325             } catch (Exception e) {
326                 System.out.println("invalid addressFamily valid values SAFI_IPV4_LABELED_UNICAST | SAFI_MPLS_VPN");
327                 printAddNeighborHelp();
328                 return;
329             }
330         }
331         if (getAsNumber(ip) != -1) {
332             System.out.println("neighbor with ip "+ip+" already exists");
333             return;
334         }
335         bgpManager.addNeighbor(ip, Long.valueOf(asNumber));
336         if (addressFamily != null) {
337             bgpManager.addAddressFamily(ip, af_afi.AFI_IP, 
338                                  af_safi.valueOf(addressFamily));
339         }
340         if (ebgpMultihops != null) {
341             bgpManager.addEbgpMultihop(ip, Integer.parseInt(ebgpMultihops));
342         }
343         if (sourceIp != null) {
344             bgpManager.addUpdateSource(ip, sourceIp);
345         }
346     }
347
348     private boolean validateIp(String inputIp) {
349         boolean validIp = false;
350         try {
351             if (inputIp != null) {
352                 InetAddress addr = InetAddress.getByName(inputIp);
353                 if (addr.isMulticastAddress()) {
354                     System.out.println("ip cannot be multicast address");
355                     return false;
356                 }
357                 if (addr.isLoopbackAddress()) {
358                     System.out.println("ip cannot be loopback address");
359                     return false;
360                 }
361                 byte addrBytes[] = addr.getAddress();
362                 int lastPart = addrBytes[3] & 0xFF;
363                 int firstPart = addrBytes[0] & 0xFF;
364                 if (firstPart == 0) {
365                         return false;//cannot start with 0 "0.1.2.3"
366                 }
367                 if (lastPart == 0 || lastPart == 255) {
368                     return false;
369                 }
370                 validIp = true;
371             }
372         } catch (Exception e) {
373         }
374         return validIp;
375     }
376
377     private void enableBgpLogLevel() throws Exception {
378         if (logFile == null) {
379             System.out.println("Please provide log file name ");
380             usage();
381             System.out.println("exec configure-bgp -op enable-log --log-file-path <logfile> --log-level <level>");
382             return;
383         }
384         boolean validLoglevel = false;
385         try {
386             LogLevels.valueOf(logLevel);
387             validLoglevel = true;
388         } catch (Exception e) {
389         }
390         if (!validLoglevel) {
391             System.out.println("Please provide valid log level emergencies|alerts|critical|errors|warnings|notifications|informational|debugging");
392             usage();
393             System.out.println("exec configure-bgp -op enable-log --log-file-path <logfile> --log-level <level>");
394             return;
395         }
396         bgpManager.setQbgpLog(logFile, logLevel);
397     }
398 }