blob: c409641b61af1fcaa3123848465249e2dcae29cd [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()))) {
Jian Li43d04282018-08-22 14:31:21 +090082 error("Current node is not the master for all gateway nodes. " +
83 "Please enforce mastership first using openstack-reset-mastership -c !");
Jian Lic38e9032018-08-09 17:08:38 +090084 return;
85 }
86 }
87
88 if (isAll) {
89 printHeader();
90
91 // send ICMP PACKET_OUT to all connect VMs whose instance port state is ACTIVE
92 instPortService.instancePorts().stream()
93 .filter(p -> p.state() == ACTIVE)
94 .filter(p -> instPortService.floatingIp(p.portId()) != null)
95 .forEach(port -> printReachability(tsService.probeNorthSouth(port)));
96 } else {
97
98 final Set<InstancePort> ports = Sets.newConcurrentHashSet();
99
100 for (String ip : vmIps) {
101 instPortService.instancePorts().stream()
102 .filter(p -> p.state().equals(InstancePort.State.ACTIVE))
103 .filter(p -> instPortService.floatingIp(p.portId()) != null)
104 .filter(p -> ip.equals(instPortService.floatingIp(p.portId()).toString()))
105 .forEach(ports::add);
106 }
107
108 printHeader();
109 ports.forEach(port -> printReachability(tsService.probeNorthSouth(port)));
110 }
111 }
112
113 private void printHeader() {
114 print(FORMAT, "Source IP", "", "Destination IP", "Reachability");
115 }
116
117 private void printReachability(Reachability r) {
118 if (r == null) {
119 return;
120 }
121 String result = r.isReachable() ? REACHABLE : UNREACHABLE;
122 print(FORMAT, r.srcIp().toString(), ARROW, r.dstIp().toString(), result);
123 }
124}