Remove redundant names in paths
[netvirt.git] / fibmanager / shell / src / main / java / org / opendaylight / netvirt / fibmanager / shell / ShowFibCommand.java
diff --git a/fibmanager/shell/src/main/java/org/opendaylight/netvirt/fibmanager/shell/ShowFibCommand.java b/fibmanager/shell/src/main/java/org/opendaylight/netvirt/fibmanager/shell/ShowFibCommand.java
new file mode 100644 (file)
index 0000000..d56776f
--- /dev/null
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2015 - 2017 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.netvirt.fibmanager.shell;
+
+import java.io.PrintStream;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.List;
+import java.util.Locale;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.datastoreutils.ExpectedDataObjectNotFoundException;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
+import org.opendaylight.netvirt.fibmanager.api.FibHelper;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.VrfEntryBase.EncapType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentrybase.RoutePaths;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Command(scope = "vpnservice", name = "fib-show", description = "Displays fib entries.\t"
+        + "To get more help use cli fib-show fullHelp")
+public class ShowFibCommand extends OsgiCommandSupport {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ShowFibCommand.class);
+
+    private static final String TABULAR_FORMAT = "   %-7s  %-20s  %-20s  %-7s  %-7s";
+    private static final String HEADER = String.format(TABULAR_FORMAT, "RD", "Prefix", "NextHop", "Label", "Origin")
+                                           + "\n   -------------------------------------------------------------------";
+    private static final String ADDRFAMILY = "--addr-family";
+    private static final String SUBNET = "--subnet";
+
+    @Argument(name = "addFam|fullHelp", description = "type of address families to show, or full help cli",
+            required = false, multiValued = false)
+    private final String options = null;
+
+    @Option(name = ADDRFAMILY, aliases = {"-af"},
+            description = "show address family ipv4 and/or ipv6 and/or l2vpn",
+            required = false, multiValued = true)
+    private final List<String> addrFamList = null;
+
+    @Option(name = SUBNET, aliases = {"-sub"},
+            description = "show only one IP or subnet sorted by mask ex \"x.x.x.x/32\" or \"2001::1/128\"",
+            required = false, multiValued = true)
+    private final String prefixOrSubnetOption = null;
+    private String prefixOrSubnet = null;
+
+    private SingleTransactionDataBroker singleTxDb;
+
+    public void setDataBroker(DataBroker dataBroker) {
+        this.singleTxDb = new SingleTransactionDataBroker(dataBroker);
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+        PrintStream console = session.getConsole();
+        if (prefixOrSubnetOption != null && prefixOrSubnetOption.length() > 0) {
+            prefixOrSubnet = prefixOrSubnetOption.replace("[", "");
+            prefixOrSubnet = prefixOrSubnet.replace("]", "");
+            if (prefixOrSubnet.indexOf("/") < 0) {
+                String maskFull = null;
+                try {
+                    Inet4Address tempAdd = (Inet4Address) InetAddress.getByName(prefixOrSubnet);
+                    maskFull = "/32";
+                } catch (SecurityException | UnknownHostException | ClassCastException e) {
+                    maskFull = null;
+                }
+                if (maskFull == null) {
+                    try {
+                        Inet6Address tempAdd = (Inet6Address) InetAddress.getByName(prefixOrSubnet);
+                        maskFull = "/128";
+                    } catch (SecurityException | UnknownHostException | ClassCastException e) {
+                        maskFull = null;
+                    }
+                }
+                if (maskFull == null) {
+                    console.println("a part of cli " + SUBNET + " is wrong => " + prefixOrSubnet);
+                    return usage(console);
+                }
+                prefixOrSubnet += maskFull;
+            }
+        }
+        console.println(HEADER);
+        if (options == null && prefixOrSubnet == null && (addrFamList == null || addrFamList.isEmpty())) {
+            InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
+            try {
+                FibEntries fibEntries = singleTxDb.syncRead(LogicalDatastoreType.CONFIGURATION, id);
+
+                List<VrfTables> vrfTablesList = fibEntries.getVrfTables();
+                if (vrfTablesList == null || vrfTablesList.isEmpty()) {
+                    console.println(" No Fib entries found");
+                    return null;
+                }
+
+                for (VrfTables vrfTable : vrfTablesList) {
+                    printVrfTable(vrfTable, console);
+                }
+            } catch (ExpectedDataObjectNotFoundException e404) {
+                String errMsg = "FATAL: fib-entries container is missing from MD-SAL";
+                console.println("\n" + errMsg);
+                LOG.error(errMsg, e404);
+            } catch (ReadFailedException rfe) {
+                String errMsg = "Internal Error occurred while processing vpnservice:fib-show command";
+                console.println("\n" + errMsg);
+                LOG.error(errMsg, rfe);
+            }
+            return null;
+        } else {
+            String optionsLowerCase = options != null ? options.toLowerCase(Locale.getDefault()) : "";
+            switch (optionsLowerCase) {
+                case "fullhelp":
+                    return usage(console);
+                default :
+            }
+
+            if ((addrFamList == null || addrFamList.isEmpty()) && (prefixOrSubnet == null
+                    || prefixOrSubnet.indexOf("/") < 5)) {
+                console.println("any address family is requiered or " + SUBNET + " is wrong");
+                usage(console);
+            } else {
+                boolean isIpv4 = false;
+                boolean isIpv6 = false;
+                boolean isL2vpn = false;
+                if (addrFamList != null && addrFamList.size() > 0) {
+                    for (String addF : addrFamList) {
+                        switch (addF.toLowerCase(Locale.getDefault())) {
+                            case "ipv4":
+                                isIpv4 = true;
+                                break;
+                            case "ipv6":
+                                isIpv6 = true;
+                                break;
+                            case "l2vpn":
+                                isL2vpn = true;
+                                break;
+                            default :
+                        }
+                    }
+                }
+                InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
+                try {
+                    FibEntries fibEntries = singleTxDb.syncRead(LogicalDatastoreType.CONFIGURATION, id);
+
+                    List<VrfTables> vrfTablesList = fibEntries.getVrfTables();
+                    if (vrfTablesList == null || vrfTablesList.isEmpty()) {
+                        console.println(" No Fib entries found");
+                        return null;
+                    }
+
+                    for (VrfTables vrfTable : vrfTablesList) {
+                        printVrfTable(vrfTable, console, isIpv4, isIpv6, isL2vpn, prefixOrSubnet);
+                    }
+                } catch (ExpectedDataObjectNotFoundException e404) {
+                    String errMsg = "FATAL: fib-entries container is missing from MD-SAL";
+                    console.println("\n" + errMsg);
+                    LOG.error(errMsg, e404);
+                } catch (ReadFailedException rfe) {
+                    String errMsg = "Internal Error occurred while processing vpnservice:fib-show command";
+                    console.println("\n" + errMsg);
+                    LOG.error(errMsg, rfe);
+                }
+                return null;
+            }
+        }
+        return null;
+    }
+
+    private void printVrfTable(VrfTables vrfTable, PrintStream console) {
+        printVrfTable(vrfTable, console, true, true, true, null);
+    }
+
+    private void printVrfTable(VrfTables vrfTable, PrintStream console, boolean isIpv4, boolean isIpv6,
+            boolean isL2vpn, String inputPrefixOrSubnet) {
+
+        List<VrfEntry> vrfEntries = vrfTable.getVrfEntry();
+        if (vrfEntries == null) {
+            LOG.warn("Null vrfEntries found for VPN with rd={}", vrfTable.getRouteDistinguisher());
+            return;
+        }
+
+        for (VrfEntry vrfEntry : vrfEntries) {
+            boolean showIt = false;
+            if (isIpv4 && isIpv6 && isL2vpn) {
+                showIt = true;
+            }
+            if (!showIt && isIpv4) {
+                LOG.debug("is ipv4 address family=> vrfEntry.getDestPrefix() = " + vrfEntry.getDestPrefix());
+                showIt = FibHelper.isIpv4Prefix(vrfEntry.getDestPrefix());
+            }
+            if (!showIt && isIpv6) {
+                LOG.debug("is ipv6 address family=> vrfEntry.getDestPrefix() = " + vrfEntry.getDestPrefix());
+                showIt = FibHelper.isIpv6Prefix(vrfEntry.getDestPrefix());
+            }
+            if (!showIt && isL2vpn) {
+                if (vrfEntry.getEncapType() != null && !EncapType.Mplsgre.equals(vrfEntry.getEncapType())) {
+                    LOG.debug("is l2vpn address family=> vrfEntry.getEncapType() = " + vrfEntry.getEncapType());
+                    showIt = true;
+                }
+            }
+            if (!showIt && inputPrefixOrSubnet != null) {
+                showIt = FibHelper.isBelongingPrefix(vrfEntry.getDestPrefix(), inputPrefixOrSubnet);
+            }
+            if (!showIt) {
+                continue;
+            }
+            List<RoutePaths> routePaths = vrfEntry.getRoutePaths();
+            if (routePaths == null || routePaths.isEmpty()) {
+                console.println(String.format(TABULAR_FORMAT,
+                                              vrfTable.getRouteDistinguisher(), vrfEntry.getDestPrefix(),
+                                              "local", routePaths == null ? "<not set>" : "<empty>",
+                                              vrfEntry.getOrigin()));
+                continue;
+            }
+            for (RoutePaths routePath : routePaths) {
+                console.println(String.format(TABULAR_FORMAT,
+                                              vrfTable.getRouteDistinguisher(), vrfEntry.getDestPrefix(),
+                                              routePath.getNexthopAddress(), routePath.getLabel(),
+                                              vrfEntry.getOrigin()));
+            }
+        }
+    }
+
+    private Object usage(PrintStream console) {
+        String nl = System.getProperty("line.separator");
+        console.println("===================================================");
+        console.println("usage cli =>" + nl);
+        console.println("fib-show --help => to get the current help");
+        console.println("fib-show fullHelp => to get the FULL help" + nl);
+        console.println("fib-show -af ipv4  => to get ipv4 address family");
+        console.println("fib-show -af ipv4 -af ipv6 => to get ipv4 and ipv6 address family");
+        console.println("fib-show -af ipv4 -af ipv6 -af l2vpn => to get ipv4 and ipv6 and l2vpn address family");
+        console.println("---------------------------------------------------");
+        console.println("fib-show -sub 40.1.1.0/24 => to get all IPv4 from fib belonging to this subnet");
+        console.println("fib-show -sub 40.1.1.1/32 => to get the IPv4 from fib");
+        console.println("---------------------------------------------------");
+        console.println("fib-show -sub 2001::1/64 => to get all IPv6 from fib belonging to this subnet");
+        console.println("fib-show -sub 2001::1/128 => to get all IPv6 from fib");
+        console.println("===================================================");
+        return null;
+    }
+
+
+}