blob: 77c24bb19af3d3e23f30d8b9ddda7e122f3ae1a8 [file] [log] [blame]
Jian Lic38e9032018-08-09 17:08:38 +09001/*
2 * Copyright 2018-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.openstacktroubleshoot.cli;
17
18import com.google.common.collect.Sets;
19import org.apache.karaf.shell.commands.Argument;
20import org.apache.karaf.shell.commands.Command;
21import org.apache.karaf.shell.commands.Option;
22import org.onosproject.cli.AbstractShellCommand;
23import org.onosproject.cluster.ClusterService;
24import org.onosproject.cluster.NodeId;
25import org.onosproject.mastership.MastershipService;
26import org.onosproject.openstacknetworking.api.InstancePort;
27import org.onosproject.openstacknetworking.api.InstancePortService;
28import org.onosproject.openstacknode.api.OpenstackNode;
29import org.onosproject.openstacknode.api.OpenstackNodeService;
30import org.onosproject.openstacktroubleshoot.api.OpenstackTroubleshootService;
31import org.onosproject.openstacktroubleshoot.api.Reachability;
32
33import java.util.Set;
34
35import static org.onosproject.openstacknetworking.api.InstancePort.State.ACTIVE;
36import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
37
38/**
39 * Checks the north-south VM connectivity.
40 */
41@Command(scope = "onos", name = "openstack-check-north-south",
42 description = "Checks the north-south VMs connectivity")
43public class OpenstackNorthSouthProbeCommand extends AbstractShellCommand {
44
45 private static final String REACHABLE = "Reachable :)";
46 private static final String UNREACHABLE = "Unreachable :(";
47 private static final String ARROW = "->";
48
49 private static final String FORMAT = "%-20s%-5s%-20s%-20s";
50
51 @Option(name = "-a", aliases = "--all", description = "Apply this command to all VMs",
52 required = false, multiValued = false)
53 private boolean isAll = false;
54
55 @Argument(index = 0, name = "vmIps", description = "VMs' IP addresses",
56 required = false, multiValued = true)
57 private String[] vmIps = null;
58
59 @Override
60 protected void execute() {
61 OpenstackTroubleshootService tsService = get(OpenstackTroubleshootService.class);
62 InstancePortService instPortService = get(InstancePortService.class);
63 OpenstackNodeService osNodeService = get(OpenstackNodeService.class);
64 MastershipService mastershipService = get(MastershipService.class);
65 ClusterService clusterService = get(ClusterService.class);
66
67 if (tsService == null || osNodeService == null ||
68 instPortService == null || mastershipService == null) {
69 error("Failed to troubleshoot openstack networking.");
70 return;
71 }
72
73 if ((!isAll && vmIps == null) || (isAll && vmIps != null)) {
74 print("Please specify one of VM IP address or -a option.");
75 return;
76 }
77
78 NodeId localNodeId = clusterService.getLocalNode().id();
79
80 for (OpenstackNode gw : osNodeService.completeNodes(GATEWAY)) {
81 if (!localNodeId.equals(mastershipService.getMasterFor(gw.intgBridge()))) {
82 error("Current node is not the master for all gateway nodes. Please enforce mastership first!");
83 return;
84 }
85 }
86
87 if (isAll) {
88 printHeader();
89
90 // send ICMP PACKET_OUT to all connect VMs whose instance port state is ACTIVE
91 instPortService.instancePorts().stream()
92 .filter(p -> p.state() == ACTIVE)
93 .filter(p -> instPortService.floatingIp(p.portId()) != null)
94 .forEach(port -> printReachability(tsService.probeNorthSouth(port)));
95 } else {
96
97 final Set<InstancePort> ports = Sets.newConcurrentHashSet();
98
99 for (String ip : vmIps) {
100 instPortService.instancePorts().stream()
101 .filter(p -> p.state().equals(InstancePort.State.ACTIVE))
102 .filter(p -> instPortService.floatingIp(p.portId()) != null)
103 .filter(p -> ip.equals(instPortService.floatingIp(p.portId()).toString()))
104 .forEach(ports::add);
105 }
106
107 printHeader();
108 ports.forEach(port -> printReachability(tsService.probeNorthSouth(port)));
109 }
110 }
111
112 private void printHeader() {
113 print(FORMAT, "Source IP", "", "Destination IP", "Reachability");
114 }
115
116 private void printReachability(Reachability r) {
117 if (r == null) {
118 return;
119 }
120 String result = r.isReachable() ? REACHABLE : UNREACHABLE;
121 print(FORMAT, r.srcIp().toString(), ARROW, r.dstIp().toString(), result);
122 }
123}