Updated BgpManager for Be
[vpnservice.git] / bgpmanager / bgpmanager-impl / src / main / java / org / opendaylight / bgpmanager / ConfigureBgpCli.java
diff --git a/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/ConfigureBgpCli.java b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/ConfigureBgpCli.java
new file mode 100644 (file)
index 0000000..71d9786
--- /dev/null
@@ -0,0 +1,398 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.bgpmanager;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Future;
+
+import org.apache.karaf.shell.commands.*;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.bgpmanager.thrift.gen.af_afi;
+import org.opendaylight.bgpmanager.thrift.gen.af_safi;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.*;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.*;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.*;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.*;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+
+@Command(scope = "odl", name = "configure-bgp", description = "")
+public class ConfigureBgpCli extends OsgiCommandSupport {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(ConfigureBgpCli.class);
+
+    private static BgpManager bgpManager;
+
+    public static void setBgpManager(BgpManager mgr) {
+        bgpManager = mgr;
+    }
+
+    @Option(name = "-op", aliases = {"--operation","--op"}, description = "[start-bgp-server, stop-bgp-server, add-neighbor, delete-neighbor, graceful-restart, enable-log ]",
+            required = false, multiValued = false)
+    String op;
+
+    //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>
+
+    @Option(name = "--as-num", description = "as number of the bgp neighbor", required = false, multiValued = false)
+    String asNumber = null;
+
+    @Option(name = "--ip", description = "ip of the bgp neighbor", required = false, multiValued = false)
+    String ip = null;
+
+    @Option(name = "--address-family", description = "address family of the bgp neighbor SAFI_IPV4_LABELED_UNICAST|SAFI_MPLS_VPN", 
+            required = false, multiValued = false)
+    String addressFamily = null;
+
+    @Option(name = "--use-source-ip", description = "source ip to be used for neighborship connection establishment", 
+            required = false, multiValued = false)
+    String sourceIp = null;
+
+    @Option(name = "--ebgp-multihops", description = "ebgp multihops of the bgp neighbor", 
+            required = false, multiValued = false)
+    String ebgpMultihops = null;
+
+    @Option(name = "--router-id", description = "router id of the bgp instance", 
+            required = false, multiValued = false)
+    String routerId = null;
+
+    @Option(name = "--stalepath-time", description = "the time delay after bgp restart stalepaths are cleaned", 
+            required = false, multiValued = false)
+    String stalePathTime = null;
+
+    @Option(name = "--log-file-path", description = "bgp log file path", 
+            required = false, multiValued = false)
+    String logFile = null;
+
+    @Option(name = "--log-level", description = "log level emergencies,alerts,critical,errors,warnings,notifications,informational,debugging",
+            required = false, multiValued = false)
+    String logLevel = null;
+
+    enum LogLevels {
+        emergencies,alerts,critical,errors,warnings,notifications,informational,debugging;
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+        try {
+            if (op == null) {
+                System.out.println("Please provide valid operation");
+                usage();
+                System.out.println("exec configure-bgp -op [start-bgp-server | stop-bgp-server | add-neighbor | delete-neighbor| graceful-restart| enable-log ]");
+            }
+            switch(op) {
+            case "start-bgp-server":
+                startBgp();
+                break;
+            case "stop-bgp-server":
+                stopBgp();
+                break;
+            case "add-neighbor":
+                addNeighbor();
+                break;
+            case "delete-neighbor":
+                deleteNeighbor();
+                break;
+            case "graceful-restart":
+                configureGR();
+                break;
+            case "enable-log" :
+                enableBgpLogLevel();
+                break;
+            default :
+                System.out.println("invalid operation");
+                usage();
+                System.out.println("exec configure-bgp -op [start-bgp-server | stop-bgp-server | add-neighbor | delete-neighbor| graceful-restart| enable-log ]");
+            }
+        } catch (Exception e) {
+            log.error("failed to handle the command",e);
+        }
+        return null;
+    }
+
+    public boolean validateStalepathTime() {
+        try {
+            int time = Integer.parseInt(stalePathTime);
+            if (time < 30 || time > 3600) {
+                System.out.println("invalid stale path time valid range [30-3600]");
+                printGracefulRestartHelp();
+                return false;
+            }
+        } catch (Exception e) {
+            System.out.println("invalid stale path time");
+            printGracefulRestartHelp();
+            return false;
+        }
+        return true;
+    }
+
+    private void configureGR() throws Exception {
+        boolean validStalepathTime = validateStalepathTime();
+        if (!validStalepathTime) {
+            return;
+        }
+        bgpManager.configureGR(Integer.parseInt(stalePathTime));
+    }
+
+    private void deleteNeighbor() throws Exception {
+        if (ip == null || !validateIp(ip)) {
+            System.out.println("invalid neighbor ip");
+            printDeleteNeighborHelp();
+            return;
+        }
+        long asNo = getAsNumber(ip);
+        if (asNo < 0) {
+            System.out.println("neighbor does not exist");
+            printDeleteNeighborHelp();
+            return;
+        }
+        bgpManager.deleteNeighbor(ip);
+    }
+
+    public long getAsNumber(String nbrIp) {
+        Bgp conf = bgpManager.getConfig();
+        if (conf == null) {
+          return -1;
+        }
+        List<Neighbors> nbrs = conf.getNeighbors();
+        if (nbrs == null) {
+          return -1;
+        }
+        for (Neighbors nbr : nbrs) {
+          if (nbrIp.equals(nbr.getAddress().getValue())) {
+             return nbr.getRemoteAs().longValue();
+          }
+        }
+        return -1;
+    }
+
+    private void stopBgp() throws Exception {
+        Bgp conf = bgpManager.getConfig();
+        if (conf == null) {
+            return;
+        }
+        List<Neighbors> nbrs = conf.getNeighbors();
+        if (nbrs != null && nbrs.size() > 0) {
+            System.err.println("error: all BGP congiguration must be deleted before stopping the router instance");
+            return;
+        }
+        bgpManager.stopBgp();
+    }
+
+    void usage() {
+        System.out.println("usage:");
+    }
+
+    void printStartBgpHelp() {
+        usage();
+        System.out.println("exec configure-bgp -op start-bgp-server --as-num <asnum> --router-id <routerid> [--stalepath-time <time>]");
+    }
+
+    void printAddNeighborHelp() {
+        usage();
+        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> ]");
+    }
+
+    void printDeleteNeighborHelp() {
+        usage();
+        System.out.println("exec configure-bgp -op delete-neighbor --ip <neighbor-ip>");
+    }
+
+    void printEnableLogHelp() {
+        usage();
+        System.out.println("exec configure-bgp -op enable-logging --filename <filename> --log-level [emergencies|alerts|critical|errors|warnings|notifications|informational|debugging]");
+    }
+
+    void printGracefulRestartHelp() {
+        usage();
+        System.out.println("exec configure-bgp -op graceful-restart --stalepath-time <30-3600>");
+    }
+
+    private void startBgp() throws Exception {
+        boolean validRouterId = false;
+
+        if (bgpManager.getConfig() != null &&
+               bgpManager.getConfig().getAsId() != null) {
+            System.out.println("bgp is already started please use stop-bgp-server and start again");
+            return;
+        }
+        try {
+            long asno = Long.valueOf(asNumber);
+            switch((int)asno) {
+            case 0:
+            case 65535:
+            case 23456:
+                System.out.println("reserved as number supplied ");
+                printStartBgpHelp();
+                return;
+            }
+            if (asno <= 0 || asno > Integer.MAX_VALUE) {
+                System.out.println("invalid as number , supported range [1,"+Integer.MAX_VALUE+"]");
+                printStartBgpHelp();
+                return;
+            }
+        } catch (Exception e) {
+            System.out.println("invalid as number ");
+            printStartBgpHelp();
+            return;
+        }
+        validRouterId = validateIp(routerId);
+        if (!validRouterId) {
+            System.out.println("invalid router id please supply valid ip address");
+            printStartBgpHelp();
+            return;
+        }
+
+        if (stalePathTime != null) {
+            boolean validStalepathTime = validateStalepathTime();
+            if (!validStalepathTime) {
+                return;
+            }
+        }
+        bgpManager.startBgp(Integer.parseInt(asNumber), routerId, 
+          stalePathTime == null? 0 : Integer.parseInt(stalePathTime), false);
+    }
+
+    protected void addNeighbor() throws Exception {
+        try {
+            long asno = Long.valueOf(asNumber);
+            switch((int)asno) {
+            case 0:
+            case 65535:
+            case 23456:
+                System.out.println("reserved as number supplied ");
+                printStartBgpHelp();
+                return;
+            }
+            if (asno <= 0 || asno > Integer.MAX_VALUE) {
+                System.out.println("invalid as number , supported range [1,"+Integer.MAX_VALUE+"]");
+                printAddNeighborHelp();
+                return;
+            }
+        } catch (Exception e) {
+            System.out.println("invalid as number");
+            printAddNeighborHelp();
+            return;
+        }
+        boolean validIp = validateIp(ip);
+        if (!validIp) {
+            System.out.println("invalid neighbor ip");
+            printAddNeighborHelp();
+            return;
+        }
+
+        if (sourceIp != null) {
+            validIp = validateIp(sourceIp);
+            if (!validIp) {
+                System.out.println("invalid source ip");
+                printAddNeighborHelp();
+                return;
+            }
+        }
+
+        if (ebgpMultihops != null) {
+            try {
+                long val = Long.valueOf(ebgpMultihops);
+                if (val < 1 || val > 255) {
+                    System.out.println("invalid ebgpMultihops number , valid range [1,255] ");
+                    printAddNeighborHelp();
+                    return;
+                }
+            } catch (Exception e) {
+                System.out.println("invalid ebgpMultihops number, valid range [1-255]");
+                printAddNeighborHelp();
+                return;
+            }
+        }
+        if (addressFamily != null) {
+            try {
+                af_safi.valueOf(addressFamily);
+            } catch (Exception e) {
+                System.out.println("invalid addressFamily valid values SAFI_IPV4_LABELED_UNICAST | SAFI_MPLS_VPN");
+                printAddNeighborHelp();
+                return;
+            }
+        }
+        if (getAsNumber(ip) != -1) {
+            System.out.println("neighbor with ip "+ip+" already exists");
+            return;
+        }
+        bgpManager.addNeighbor(ip, Long.valueOf(asNumber));
+        if (addressFamily != null) {
+            bgpManager.addAddressFamily(ip, af_afi.AFI_IP, 
+                                 af_safi.valueOf(addressFamily));
+        }
+        if (ebgpMultihops != null) {
+            bgpManager.addEbgpMultihop(ip, Integer.parseInt(ebgpMultihops));
+        }
+        if (sourceIp != null) {
+            bgpManager.addUpdateSource(ip, sourceIp);
+        }
+    }
+
+    private boolean validateIp(String inputIp) {
+        boolean validIp = false;
+        try {
+            if (inputIp != null) {
+                InetAddress addr = InetAddress.getByName(inputIp);
+                if (addr.isMulticastAddress()) {
+                    System.out.println("ip cannot be multicast address");
+                    return false;
+                }
+                if (addr.isLoopbackAddress()) {
+                    System.out.println("ip cannot be loopback address");
+                    return false;
+                }
+                byte addrBytes[] = addr.getAddress();
+                int lastPart = addrBytes[3] & 0xFF;
+                int firstPart = addrBytes[0] & 0xFF;
+                if (firstPart == 0) {
+                       return false;//cannot start with 0 "0.1.2.3"
+                }
+                if (lastPart == 0 || lastPart == 255) {
+                    return false;
+                }
+                validIp = true;
+            }
+        } catch (Exception e) {
+        }
+        return validIp;
+    }
+
+    private void enableBgpLogLevel() throws Exception {
+        if (logFile == null) {
+            System.out.println("Please provide log file name ");
+            usage();
+            System.out.println("exec configure-bgp -op enable-log --log-file-path <logfile> --log-level <level>");
+            return;
+        }
+        boolean validLoglevel = false;
+        try {
+            LogLevels.valueOf(logLevel);
+            validLoglevel = true;
+        } catch (Exception e) {
+        }
+        if (!validLoglevel) {
+            System.out.println("Please provide valid log level emergencies|alerts|critical|errors|warnings|notifications|informational|debugging");
+            usage();
+            System.out.println("exec configure-bgp -op enable-log --log-file-path <logfile> --log-level <level>");
+            return;
+        }
+        bgpManager.setQbgpLog(logFile, logLevel);
+    }
+}