blob: 7bfd6b981b6ae574b8150300d2a84f175557dac9 [file] [log] [blame]
Thomas Vachuska7d693f52014-10-21 19:17:57 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2014-present Open Networking Foundation
Thomas Vachuska7d693f52014-10-21 19:17:57 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska7d693f52014-10-21 19:17:57 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska7d693f52014-10-21 19:17:57 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.cli.net;
tom89b63c52014-09-16 09:19:51 -070017
Yi Tseng46f3edd2017-05-26 15:14:53 -070018import com.google.common.collect.Sets;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070019import org.apache.karaf.shell.api.action.Argument;
20import org.apache.karaf.shell.api.action.Command;
21import org.apache.karaf.shell.api.action.lifecycle.Service;
Yi Tseng46f3edd2017-05-26 15:14:53 -070022import org.onlab.util.Tools;
Yuta HIGUCHId8119802017-12-20 13:59:38 -080023import org.onosproject.cli.AbstractShellCommand;
Brian O'Connorabafb502014-12-02 22:26:20 -080024import org.onosproject.net.Device;
25import org.onosproject.net.Host;
Thomas Vachuskaf1c42082015-07-10 16:41:31 -070026import org.onosproject.net.Link;
Thomas Vachuska1b1355d2018-02-06 16:53:58 -080027import org.onosproject.net.config.NetworkConfigService;
Brian O'Connorabafb502014-12-02 22:26:20 -080028import org.onosproject.net.device.DeviceAdminService;
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +053029import org.onosproject.net.flow.FlowRuleService;
30import org.onosproject.net.group.GroupService;
Brian O'Connorabafb502014-12-02 22:26:20 -080031import org.onosproject.net.host.HostAdminService;
Brian O'Connorabafb502014-12-02 22:26:20 -080032import org.onosproject.net.intent.Intent;
Yi Tseng46f3edd2017-05-26 15:14:53 -070033import org.onosproject.net.intent.IntentEvent;
34import org.onosproject.net.intent.IntentListener;
Brian O'Connorabafb502014-12-02 22:26:20 -080035import org.onosproject.net.intent.IntentService;
Yi Tseng46f3edd2017-05-26 15:14:53 -070036import org.onosproject.net.intent.Key;
Thomas Vachuskaf1c42082015-07-10 16:41:31 -070037import org.onosproject.net.link.LinkAdminService;
Thomas Vachuskaeb851cd2016-07-21 15:41:05 -070038import org.onosproject.net.region.RegionAdminService;
Thomas Vachuska1b1355d2018-02-06 16:53:58 -080039import org.onosproject.ui.UiExtensionService;
Thomas Vachuskaeb851cd2016-07-21 15:41:05 -070040import org.onosproject.ui.UiTopoLayoutService;
Thomas Vachuska1b1355d2018-02-06 16:53:58 -080041
Yi Tseng46f3edd2017-05-26 15:14:53 -070042import java.util.Set;
43import java.util.concurrent.CompletableFuture;
44import java.util.concurrent.ExecutionException;
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +053045import java.util.concurrent.TimeUnit;
Yi Tseng46f3edd2017-05-26 15:14:53 -070046import java.util.concurrent.TimeoutException;
47import java.util.stream.Collectors;
48
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +053049import static org.onosproject.net.intent.IntentState.WITHDRAWN;
tom89b63c52014-09-16 09:19:51 -070050
51/**
tome2555ff2014-10-07 18:47:58 -070052 * Wipes-out the entire network information base, i.e. devices, links, hosts, intents.
tom89b63c52014-09-16 09:19:51 -070053 */
Ray Milkeyd84f89b2018-08-17 14:54:17 -070054@Service
tom89b63c52014-09-16 09:19:51 -070055@Command(scope = "onos", name = "wipe-out",
Thomas Vachuskaf1c42082015-07-10 16:41:31 -070056 description = "Wipes-out the entire network information base, i.e. devices, links, hosts")
Yuta HIGUCHId8119802017-12-20 13:59:38 -080057public class WipeOutCommand extends AbstractShellCommand {
tom89b63c52014-09-16 09:19:51 -070058
tom1679e182014-10-09 13:50:45 -070059 private static final String PLEASE = "please";
Yi Tseng46f3edd2017-05-26 15:14:53 -070060 @Argument(name = "please", description = "Confirmation phrase")
tom1679e182014-10-09 13:50:45 -070061 String please = null;
tom22288032014-10-07 08:16:53 -070062
tom89b63c52014-09-16 09:19:51 -070063 @Override
Ray Milkeyd84f89b2018-08-17 14:54:17 -070064 protected void doExecute() {
tom1679e182014-10-09 13:50:45 -070065 if (please == null || !please.equals(PLEASE)) {
66 print("I'm afraid I can't do that!\nSay: %s", PLEASE);
tom22288032014-10-07 08:16:53 -070067 return;
68 }
69
Thomas Vachuskad35f8472015-08-04 10:06:48 -070070 wipeOutIntents();
71 wipeOutHosts();
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +053072 wipeOutFlows();
73 wipeOutGroups();
Thomas Vachuskad35f8472015-08-04 10:06:48 -070074 wipeOutDevices();
75 wipeOutLinks();
Thomas Vachuska1b1355d2018-02-06 16:53:58 -080076 wipeOutNetworkConfig();
Thomas Vachuskaeb851cd2016-07-21 15:41:05 -070077
78 wipeOutLayouts();
79 wipeOutRegions();
Thomas Vachuska1b1355d2018-02-06 16:53:58 -080080 wipeOutUiCache();
Thomas Vachuskad35f8472015-08-04 10:06:48 -070081 }
Thomas Vachuskaf1c42082015-07-10 16:41:31 -070082
Thomas Vachuskad35f8472015-08-04 10:06:48 -070083 private void wipeOutIntents() {
84 print("Wiping intents");
85 IntentService intentService = get(IntentService.class);
Yi Tseng46f3edd2017-05-26 15:14:53 -070086 Set<Key> keysToWithdrawn = Sets.newConcurrentHashSet();
87 Set<Intent> intentsToWithdrawn = Tools.stream(intentService.getIntents())
88 .filter(intent -> intentService.getIntentState(intent.key()) != WITHDRAWN)
89 .collect(Collectors.toSet());
90 intentsToWithdrawn.stream()
91 .map(Intent::key)
92 .forEach(keysToWithdrawn::add);
93 CompletableFuture<Void> completableFuture = new CompletableFuture<>();
94 IntentListener listener = e -> {
95 if (e.type() == IntentEvent.Type.WITHDRAWN) {
96 keysToWithdrawn.remove(e.subject().key());
Thomas Vachuskaf1c42082015-07-10 16:41:31 -070097 }
Yi Tseng46f3edd2017-05-26 15:14:53 -070098 if (keysToWithdrawn.isEmpty()) {
99 completableFuture.complete(null);
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +0530100 }
Yi Tseng46f3edd2017-05-26 15:14:53 -0700101 };
102 intentService.addListener(listener);
103 intentsToWithdrawn.forEach(intentService::withdraw);
104 try {
Thomas Vachuska1b1355d2018-02-06 16:53:58 -0800105 if (!intentsToWithdrawn.isEmpty()) {
106 // Wait 1.5 seconds for each Intent
107 completableFuture.get(intentsToWithdrawn.size() * 1500L, TimeUnit.MILLISECONDS);
108 }
109 } catch (InterruptedException | ExecutionException | TimeoutException e) {
110 print("Encountered exception while withdrawing intents: " + e.toString());
Yi Tseng46f3edd2017-05-26 15:14:53 -0700111 } finally {
112 intentService.removeListener(listener);
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +0530113 }
Yi Tseng46f3edd2017-05-26 15:14:53 -0700114 intentsToWithdrawn.forEach(intentService::purge);
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +0530115 }
116
117 private void wipeOutFlows() {
118 print("Wiping Flows");
119 FlowRuleService flowRuleService = get(FlowRuleService.class);
120 DeviceAdminService deviceAdminService = get(DeviceAdminService.class);
121 for (Device device : deviceAdminService.getDevices()) {
122 flowRuleService.purgeFlowRules(device.id());
123 }
124 }
125
126 private void wipeOutGroups() {
127 print("Wiping groups");
128 GroupService groupService = get(GroupService.class);
129 DeviceAdminService deviceAdminService = get(DeviceAdminService.class);
130 for (Device device : deviceAdminService.getDevices()) {
131 groupService.purgeGroupEntries(device.id());
tom89b63c52014-09-16 09:19:51 -0700132 }
Thomas Vachuskad35f8472015-08-04 10:06:48 -0700133 }
tom89b63c52014-09-16 09:19:51 -0700134
Thomas Vachuskad35f8472015-08-04 10:06:48 -0700135 private void wipeOutHosts() {
tome2555ff2014-10-07 18:47:58 -0700136 print("Wiping hosts");
tom89b63c52014-09-16 09:19:51 -0700137 HostAdminService hostAdminService = get(HostAdminService.class);
Thomas Vachuskaf1c42082015-07-10 16:41:31 -0700138 while (hostAdminService.getHostCount() > 0) {
139 try {
140 for (Host host : hostAdminService.getHosts()) {
141 hostAdminService.removeHost(host.id());
142 }
143 } catch (Exception e) {
Ray Milkeyab87ac42016-08-26 13:13:19 -0700144 log.info("Unable to wipe-out hosts", e);
Thomas Vachuskaf1c42082015-07-10 16:41:31 -0700145 }
tom89b63c52014-09-16 09:19:51 -0700146 }
Thomas Vachuskad35f8472015-08-04 10:06:48 -0700147 }
Brian O'Connor958d3812014-10-03 19:46:23 -0700148
Thomas Vachuskad35f8472015-08-04 10:06:48 -0700149 private void wipeOutDevices() {
150 print("Wiping devices");
151 DeviceAdminService deviceAdminService = get(DeviceAdminService.class);
152 while (deviceAdminService.getDeviceCount() > 0) {
153 try {
154 for (Device device : deviceAdminService.getDevices()) {
155 deviceAdminService.removeDevice(device.id());
156 }
157 } catch (Exception e) {
Ray Milkeyab87ac42016-08-26 13:13:19 -0700158 log.info("Unable to wipe-out devices", e);
Hari Krishnaa9293632015-07-16 16:43:40 -0700159 }
Thomas Vachuskad35f8472015-08-04 10:06:48 -0700160 }
161 }
162
163 private void wipeOutLinks() {
164 print("Wiping links");
165 LinkAdminService linkAdminService = get(LinkAdminService.class);
166 while (linkAdminService.getLinkCount() > 0) {
167 try {
168 for (Link link : linkAdminService.getLinks()) {
169 linkAdminService.removeLinks(link.src());
170 linkAdminService.removeLinks(link.dst());
171 }
172 } catch (Exception e) {
Ray Milkeyab87ac42016-08-26 13:13:19 -0700173 log.info("Unable to wipe-out links", e);
Thomas Vachuskad35f8472015-08-04 10:06:48 -0700174 }
Brian O'Connor958d3812014-10-03 19:46:23 -0700175 }
tom89b63c52014-09-16 09:19:51 -0700176 }
Thomas Vachuskaeb851cd2016-07-21 15:41:05 -0700177
178 private void wipeOutLayouts() {
179 print("Wiping UI layouts");
180 UiTopoLayoutService service = get(UiTopoLayoutService.class);
Simon Huntb1ce2602016-07-23 14:04:31 -0700181 // wipe out all layouts except the default, which should always be there
182 service.getLayouts().forEach(l -> {
183 if (!l.id().isDefault()) {
184 service.removeLayout(l);
185 }
186 });
Thomas Vachuskaeb851cd2016-07-21 15:41:05 -0700187 }
188
189 private void wipeOutRegions() {
190 print("Wiping regions");
191 RegionAdminService service = get(RegionAdminService.class);
192 service.getRegions().forEach(r -> service.removeRegion(r.id()));
193 }
Thomas Vachuska1b1355d2018-02-06 16:53:58 -0800194
195 private void wipeOutNetworkConfig() {
196 print("Wiping network configs");
197 get(NetworkConfigService.class).removeConfig();
198 }
199
200 private void wipeOutUiCache() {
201 print("Wiping ui model cache");
202 get(UiExtensionService.class).refreshModel();
203 }
204
tom89b63c52014-09-16 09:19:51 -0700205}