diff --git a/apps/openstacktroubleshoot/api/BUCK b/apps/openstacktroubleshoot/api/BUCK index 520bddff29..27cd4a27ed 100644 --- a/apps/openstacktroubleshoot/api/BUCK +++ b/apps/openstacktroubleshoot/api/BUCK @@ -2,6 +2,7 @@ COMPILE_DEPS = [ '//lib:CORE_DEPS', '//lib:org.apache.karaf.shell.console', '//cli:onos-cli', + '//apps/openstacknetworking/api:onos-apps-openstacknetworking-api', ] TEST_DEPS = [ diff --git a/apps/openstacktroubleshoot/api/BUILD b/apps/openstacktroubleshoot/api/BUILD index b22d9f60e2..7c159a7673 100644 --- a/apps/openstacktroubleshoot/api/BUILD +++ b/apps/openstacktroubleshoot/api/BUILD @@ -1,4 +1,6 @@ -COMPILE_DEPS = CORE_DEPS + CLI +COMPILE_DEPS = CORE_DEPS + CLI + [ + "//apps/openstacknetworking/api:onos-apps-openstacknetworking-api", +] TEST_DEPS = TEST_ADAPTERS + [ "//core/api:onos-api-tests", diff --git a/apps/openstacktroubleshoot/api/src/main/java/org/onosproject/openstacktroubleshoot/api/OpenstackTroubleshootService.java b/apps/openstacktroubleshoot/api/src/main/java/org/onosproject/openstacktroubleshoot/api/OpenstackTroubleshootService.java index 4ad6cfd4b4..272e257984 100644 --- a/apps/openstacktroubleshoot/api/src/main/java/org/onosproject/openstacktroubleshoot/api/OpenstackTroubleshootService.java +++ b/apps/openstacktroubleshoot/api/src/main/java/org/onosproject/openstacktroubleshoot/api/OpenstackTroubleshootService.java @@ -16,6 +16,7 @@ package org.onosproject.openstacktroubleshoot.api; import org.onlab.packet.IpAddress; +import org.onosproject.openstacknetworking.api.InstancePort; import java.util.Map; @@ -34,14 +35,12 @@ public interface OpenstackTroubleshootService { /** * Checks a single VM-to-Vm connectivity. * - * @param srcNetId source network ID - * @param srcIp source IP address - * @param dstNetId destination network ID - * @param dstIp destination IP address + * @param srcInstancePort source instance port + * @param dstInstancePort destination instance port * @return reachability */ - Reachability probeEastWest(String srcNetId, IpAddress srcIp, - String dstNetId, IpAddress dstIp); + Reachability probeEastWest(InstancePort srcInstancePort, + InstancePort dstInstancePort); /** * Checks all north-south router to VMs' connectivity. diff --git a/apps/openstacktroubleshoot/app/src/main/java/org/onosproject/openstacktroubleshoot/cli/ActiveVmIpCompleter.java b/apps/openstacktroubleshoot/app/src/main/java/org/onosproject/openstacktroubleshoot/cli/ActiveVmIpCompleter.java new file mode 100644 index 0000000000..326b041957 --- /dev/null +++ b/apps/openstacktroubleshoot/app/src/main/java/org/onosproject/openstacktroubleshoot/cli/ActiveVmIpCompleter.java @@ -0,0 +1,48 @@ +/* + * Copyright 2018-present Open Networking Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openstacktroubleshoot.cli; + +import org.apache.karaf.shell.console.Completer; +import org.apache.karaf.shell.console.completer.StringsCompleter; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.openstacknetworking.api.InstancePort; +import org.onosproject.openstacknetworking.api.InstancePortService; + +import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import java.util.stream.Collectors; + +/** + * Active VM IP address completer. + */ +public class ActiveVmIpCompleter implements Completer { + + @Override + public int complete(String buffer, int cursor, List candidates) { + StringsCompleter delegate = new StringsCompleter(); + InstancePortService service = AbstractShellCommand.get(InstancePortService.class); + Set set = service.instancePorts().stream() + .filter(p -> p.state() == InstancePort.State.ACTIVE) + .map(p -> p.ipAddress().getIp4Address().toString()) + .collect(Collectors.toSet()); + + SortedSet strings = delegate.getStrings(); + strings.addAll(set); + + return delegate.complete(buffer, cursor, candidates); + } +} diff --git a/apps/openstacktroubleshoot/app/src/main/java/org/onosproject/openstacktroubleshoot/cli/OpenstackEastWestProbeCommand.java b/apps/openstacktroubleshoot/app/src/main/java/org/onosproject/openstacktroubleshoot/cli/OpenstackEastWestProbeCommand.java index f9786ac4fb..696cb11d6a 100644 --- a/apps/openstacktroubleshoot/app/src/main/java/org/onosproject/openstacktroubleshoot/cli/OpenstackEastWestProbeCommand.java +++ b/apps/openstacktroubleshoot/app/src/main/java/org/onosproject/openstacktroubleshoot/cli/OpenstackEastWestProbeCommand.java @@ -15,12 +15,21 @@ */ package org.onosproject.openstacktroubleshoot.cli; +import com.google.common.collect.Sets; +import org.apache.karaf.shell.commands.Argument; import org.apache.karaf.shell.commands.Command; +import org.apache.karaf.shell.commands.Option; +import org.onlab.packet.IpAddress; import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.openstacknetworking.api.InstancePort; +import org.onosproject.openstacknetworking.api.InstancePortService; import org.onosproject.openstacktroubleshoot.api.OpenstackTroubleshootService; import org.onosproject.openstacktroubleshoot.api.Reachability; import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; /** * Checks the east-west VMs connectivity. @@ -35,23 +44,90 @@ public class OpenstackEastWestProbeCommand extends AbstractShellCommand { private static final String FORMAT = "%-20s%-5s%-20s%-20s"; + @Option(name = "-a", aliases = "--all", description = "Apply this command to all VMs", + required = false, multiValued = false) + private boolean isAll = false; + + @Argument(index = 0, name = "vmIps", description = "VMs' IP addresses", + required = false, multiValued = true) + private String[] vmIps = null; + @Override protected void execute() { - OpenstackTroubleshootService troubleshootService = - AbstractShellCommand.get(OpenstackTroubleshootService.class); + OpenstackTroubleshootService tsService = + get(OpenstackTroubleshootService.class); - if (troubleshootService == null) { + InstancePortService instPortService = + get(InstancePortService.class); + + if (tsService == null) { error("Failed to troubleshoot openstack networking."); return; } + if ((!isAll && vmIps == null) || (isAll && vmIps != null)) { + print("Please specify one of VM IP address or -a option."); + return; + } + + if (isAll) { + printHeader(); + Map map = tsService.probeEastWestBulk(); + map.values().forEach(this::printReachability); + } else { + if (vmIps.length > 2) { + print("Too many VM IPs. The number of IP should be limited to 2."); + return; + } + + IpAddress srcIp = IpAddress.valueOf(vmIps[0]); + InstancePort srcPort = instPort(instPortService, srcIp); + + if (srcPort == null) { + print("Specified source IP is not existing."); + return; + } + + final Set dstIps = Sets.newConcurrentHashSet(); + + if (vmIps.length == 2) { + dstIps.add(IpAddress.valueOf(vmIps[1])); + } + + if (vmIps.length == 1) { + dstIps.addAll(instPortService.instancePorts().stream() + .filter(p -> !p.ipAddress().equals(srcIp)) + .filter(p -> p.state().equals(InstancePort.State.ACTIVE)) + .map(InstancePort::ipAddress) + .collect(Collectors.toSet())); + } + + printHeader(); + dstIps.stream() + .filter(ip -> instPort(instPortService, ip) != null) + .map(ip -> instPort(instPortService, ip)) + .forEach(port -> printReachability(tsService.probeEastWest(srcPort, port))); + } + } + + private InstancePort instPort(InstancePortService service, IpAddress ip) { + Optional port = service.instancePorts().stream() + .filter(p -> p.ipAddress().equals(ip)).findFirst(); + + if (port.isPresent()) { + return port.get(); + } else { + print("Specified destination IP is not existing."); + return null; + } + } + + private void printHeader() { print(FORMAT, "Source IP", "", "Destination IP", "Reachability"); + } - Map map = troubleshootService.probeEastWestBulk(); - - map.values().forEach(r -> { - String result = r.isReachable() ? REACHABLE : UNREACHABLE; - print(FORMAT, r.srcIp().toString(), ARROW, r.dstIp().toString(), result); - }); + private void printReachability(Reachability r) { + String result = r.isReachable() ? REACHABLE : UNREACHABLE; + print(FORMAT, r.srcIp().toString(), ARROW, r.dstIp().toString(), result); } } diff --git a/apps/openstacktroubleshoot/app/src/main/java/org/onosproject/openstacktroubleshoot/impl/OpenstackTroubleshootManager.java b/apps/openstacktroubleshoot/app/src/main/java/org/onosproject/openstacktroubleshoot/impl/OpenstackTroubleshootManager.java index 3124da6d82..235407611d 100644 --- a/apps/openstacktroubleshoot/app/src/main/java/org/onosproject/openstacktroubleshoot/impl/OpenstackTroubleshootManager.java +++ b/apps/openstacktroubleshoot/app/src/main/java/org/onosproject/openstacktroubleshoot/impl/OpenstackTroubleshootManager.java @@ -257,21 +257,17 @@ public class OpenstackTroubleshootManager implements OpenstackTroubleshootServic } @Override - public Reachability probeEastWest(String srcNetId, IpAddress srcIp, - String dstNetId, IpAddress dstIp) { + public Reachability probeEastWest(InstancePort srcPort, InstancePort dstPort) { Reachability.Builder rBuilder = DefaultReachability.builder() - .srcIp(srcIp) - .dstIp(dstIp); + .srcIp(srcPort.ipAddress()) + .dstIp(dstPort.ipAddress()); - if (srcIp.equals(dstIp)) { + if (srcPort.equals(dstPort)) { // self probing should always return true rBuilder.isReachable(true); return rBuilder.build(); } else { - InstancePort srcPort = instancePortService.instancePort(srcIp, srcNetId); - InstancePort dstPort = instancePortService.instancePort(dstIp, dstNetId); - if (srcPort.state() == ACTIVE && dstPort.state() == ACTIVE) { // install flow rules to enforce ICMP_REQUEST to be tagged and direct to ACL table diff --git a/apps/openstacktroubleshoot/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/openstacktroubleshoot/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml index 67a13644f4..c7fd715458 100644 --- a/apps/openstacktroubleshoot/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml +++ b/apps/openstacktroubleshoot/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml @@ -1,5 +1,5 @@