blob: 6d27da80e0b44864d3a0ca3f96d1d691fab42c51 [file] [log] [blame]
Jian Li0b564282018-06-20 00:50:53 +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.openstacknetworking.web;
17
Jian Li803a1d52018-06-21 21:47:48 +090018import com.fasterxml.jackson.databind.node.ArrayNode;
19import com.fasterxml.jackson.databind.node.ObjectNode;
20import com.google.common.base.Strings;
21import com.google.common.collect.Lists;
Jian Li7b8c3682019-05-12 13:57:15 +090022import org.onlab.packet.IpAddress;
Jian Li0b564282018-06-20 00:50:53 +090023import org.onlab.util.ItemNotFoundException;
Jian Li7f024de2018-07-07 03:51:02 +090024import org.onosproject.cfg.ComponentConfigService;
Jian Li0b564282018-06-20 00:50:53 +090025import org.onosproject.core.ApplicationId;
26import org.onosproject.core.CoreService;
27import org.onosproject.net.flow.FlowRuleService;
28import org.onosproject.openstacknetworking.api.Constants;
Jian Li7b8c3682019-05-12 13:57:15 +090029import org.onosproject.openstacknetworking.api.OpenstackHaService;
Jian Li0b564282018-06-20 00:50:53 +090030import org.onosproject.openstacknetworking.api.OpenstackNetworkAdminService;
31import org.onosproject.openstacknetworking.api.OpenstackRouterAdminService;
32import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupAdminService;
Jian Li7f024de2018-07-07 03:51:02 +090033import org.onosproject.openstacknetworking.impl.OpenstackRoutingArpHandler;
Jian Li25257212019-03-26 13:31:14 +090034import org.onosproject.openstacknetworking.impl.OpenstackRoutingSnatHandler;
Jian Licad36c72018-09-13 17:44:54 +090035import org.onosproject.openstacknetworking.impl.OpenstackSecurityGroupHandler;
Jian Li7f024de2018-07-07 03:51:02 +090036import org.onosproject.openstacknetworking.impl.OpenstackSwitchingArpHandler;
Jian Li0b564282018-06-20 00:50:53 +090037import org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil;
38import org.onosproject.openstacknode.api.NodeState;
39import org.onosproject.openstacknode.api.OpenstackNode;
40import org.onosproject.openstacknode.api.OpenstackNodeAdminService;
Jian Li0b564282018-06-20 00:50:53 +090041import org.onosproject.rest.AbstractWebResource;
42import org.openstack4j.api.OSClient;
Jian Li803a1d52018-06-21 21:47:48 +090043import org.openstack4j.model.network.NetFloatingIP;
Jian Li0b564282018-06-20 00:50:53 +090044import org.slf4j.Logger;
45import org.slf4j.LoggerFactory;
46
Jian Li7b8c3682019-05-12 13:57:15 +090047import javax.ws.rs.Consumes;
Jian Li0b564282018-06-20 00:50:53 +090048import javax.ws.rs.GET;
Jian Li7b8c3682019-05-12 13:57:15 +090049import javax.ws.rs.PUT;
Jian Li0b564282018-06-20 00:50:53 +090050import javax.ws.rs.Path;
Jian Li7f024de2018-07-07 03:51:02 +090051import javax.ws.rs.PathParam;
Jian Li0b564282018-06-20 00:50:53 +090052import javax.ws.rs.Produces;
53import javax.ws.rs.core.MediaType;
54import javax.ws.rs.core.Response;
Jian Li803a1d52018-06-21 21:47:48 +090055import java.util.Comparator;
sanghoshin2a354e32018-11-09 12:52:44 +080056import java.util.HashMap;
Jian Li803a1d52018-06-21 21:47:48 +090057import java.util.List;
sanghoshin2a354e32018-11-09 12:52:44 +080058import java.util.Map;
Jian Li0b564282018-06-20 00:50:53 +090059import java.util.Objects;
60import java.util.Optional;
61
Jian Lif7934d52018-07-10 16:27:02 +090062import static java.lang.Thread.sleep;
Jian Li167f0c42018-11-18 11:03:51 +090063import static java.util.stream.StreamSupport.stream;
Jian Li7b8c3682019-05-12 13:57:15 +090064import static javax.ws.rs.core.Response.status;
Jian Li7f024de2018-07-07 03:51:02 +090065import static org.onlab.util.Tools.nullIsIllegal;
Jian Li5c777c62018-11-11 00:31:20 +090066import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.addRouterIface;
67import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.checkActivationFlag;
68import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.checkArpMode;
69import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getPropertyValue;
Jian Li25257212019-03-26 13:31:14 +090070import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getPropertyValueAsBoolean;
Jian Li8b5599b2018-11-19 18:45:46 +090071import static org.onosproject.openstacknode.api.NodeState.COMPLETE;
Jian Li5c777c62018-11-11 00:31:20 +090072import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
Jian Li0b564282018-06-20 00:50:53 +090073import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.CONTROLLER;
Jian Li5c777c62018-11-11 00:31:20 +090074import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
Jian Li0b564282018-06-20 00:50:53 +090075
76/**
77 * REST interface for synchronizing openstack network states and rules.
78 */
79@Path("management")
80public class OpenstackManagementWebResource extends AbstractWebResource {
81 private final Logger log = LoggerFactory.getLogger(getClass());
82
Jian Li803a1d52018-06-21 21:47:48 +090083 private static final String FLOATINGIPS = "floatingips";
Jian Li7f024de2018-07-07 03:51:02 +090084 private static final String ARP_MODE_NAME = "arpMode";
Jian Licad36c72018-09-13 17:44:54 +090085 private static final String USE_SECURITY_GROUP_NAME = "useSecurityGroup";
Jian Li25257212019-03-26 13:31:14 +090086 private static final String USE_STATEFUL_SNAT_NAME = "useStatefulSnat";
Jian Li803a1d52018-06-21 21:47:48 +090087
Jian Lif7934d52018-07-10 16:27:02 +090088 private static final long SLEEP_MS = 3000; // we wait 3s for init each node
Jian Li167f0c42018-11-18 11:03:51 +090089 private static final long TIMEOUT_MS = 10000; // we wait 10s
Jian Li88ae51e2018-07-10 02:23:35 +090090
Jian Li0b564282018-06-20 00:50:53 +090091 private static final String DEVICE_OWNER_IFACE = "network:router_interface";
Jian Li7f024de2018-07-07 03:51:02 +090092
93 private static final String ARP_MODE_REQUIRED = "ARP mode is not specified";
Jian Li25257212019-03-26 13:31:14 +090094 private static final String STATEFUL_SNAT_REQUIRED = "Stateful SNAT flag nis not specified";
Jian Li7f024de2018-07-07 03:51:02 +090095
Jian Licad36c72018-09-13 17:44:54 +090096 private static final String SECURITY_GROUP_FLAG_REQUIRED = "Security Group flag is not specified";
97
sanghoshin2a354e32018-11-09 12:52:44 +080098 private static final String HTTP_HEADER_ACCEPT = "accept";
99 private static final String HTTP_HEADER_VALUE_JSON = "application/json";
100
Jian Li812460d2019-05-13 15:41:30 +0900101 private static final String IS_ACTIVE = "isActive";
Jian Li7b8c3682019-05-12 13:57:15 +0900102 private static final String FLAG_TRUE = "true";
103 private static final String FLAG_FALSE = "false";
104
Jian Li803a1d52018-06-21 21:47:48 +0900105 private final ObjectNode root = mapper().createObjectNode();
106 private final ArrayNode floatingipsNode = root.putArray(FLOATINGIPS);
Jian Li0b564282018-06-20 00:50:53 +0900107
108 private final OpenstackSecurityGroupAdminService osSgAdminService =
109 get(OpenstackSecurityGroupAdminService.class);
110 private final OpenstackNetworkAdminService osNetAdminService =
111 get(OpenstackNetworkAdminService.class);
112 private final OpenstackRouterAdminService osRouterAdminService =
113 get(OpenstackRouterAdminService.class);
Jian Li0b564282018-06-20 00:50:53 +0900114 private final OpenstackNodeAdminService osNodeAdminService =
115 get(OpenstackNodeAdminService.class);
Jian Li7b8c3682019-05-12 13:57:15 +0900116 private final OpenstackHaService osHaService = get(OpenstackHaService.class);
Jian Li0b564282018-06-20 00:50:53 +0900117 private final FlowRuleService flowRuleService = get(FlowRuleService.class);
118 private final CoreService coreService = get(CoreService.class);
119
120 /**
121 * Synchronizes the network states with openstack.
122 *
123 * @return 200 OK with sync result, 404 not found
124 */
125 @GET
126 @Produces(MediaType.APPLICATION_JSON)
127 @Path("sync/states")
128 public Response syncStates() {
129
sanghoshin2a354e32018-11-09 12:52:44 +0800130 Map<String, String> headerMap = new HashMap();
131 headerMap.put(HTTP_HEADER_ACCEPT, HTTP_HEADER_VALUE_JSON);
132
Jian Li78ac0652018-07-17 18:10:16 +0900133 Optional<OpenstackNode> node = osNodeAdminService.nodes(CONTROLLER).stream().findFirst();
Jian Li0b564282018-06-20 00:50:53 +0900134 if (!node.isPresent()) {
135 throw new ItemNotFoundException("Auth info is not found");
136 }
137
138 OSClient osClient = OpenstackNetworkingUtil.getConnectedClient(node.get());
139
140 if (osClient == null) {
141 throw new ItemNotFoundException("Auth info is not correct");
142 }
143
Jian Lib6bc15d2019-09-24 17:19:05 +0900144 try {
145 osClient.headers(headerMap).networking().securitygroup().list().forEach(osSg -> {
146 if (osSgAdminService.securityGroup(osSg.getId()) != null) {
147 osSgAdminService.updateSecurityGroup(osSg);
148 } else {
149 osSgAdminService.createSecurityGroup(osSg);
150 }
151 });
152 } catch (Exception e) {
153 log.warn("Failed to retrieve security group due to {}", e.getMessage());
154 return Response.serverError().build();
155 }
Jian Li0b564282018-06-20 00:50:53 +0900156
Jian Lib6bc15d2019-09-24 17:19:05 +0900157 try {
158 osClient.headers(headerMap).networking().network().list().forEach(osNet -> {
159 if (osNetAdminService.network(osNet.getId()) != null) {
160 osNetAdminService.updateNetwork(osNet);
161 } else {
162 osNetAdminService.createNetwork(osNet);
163 }
164 });
165 } catch (Exception e) {
166 log.warn("Failed to retrieve network due to {}", e.getMessage());
167 return Response.serverError().build();
168 }
Jian Li0b564282018-06-20 00:50:53 +0900169
Jian Lib6bc15d2019-09-24 17:19:05 +0900170 try {
171 osClient.headers(headerMap).networking().subnet().list().forEach(osSubnet -> {
172 if (osNetAdminService.subnet(osSubnet.getId()) != null) {
173 osNetAdminService.updateSubnet(osSubnet);
174 } else {
175 osNetAdminService.createSubnet(osSubnet);
176 }
177 });
178 } catch (Exception e) {
179 log.warn("Failed to retrieve subnet due to {}", e.getMessage());
180 return Response.serverError().build();
181 }
Jian Li0b564282018-06-20 00:50:53 +0900182
Jian Lib6bc15d2019-09-24 17:19:05 +0900183 try {
184 osClient.headers(headerMap).networking().port().list().forEach(osPort -> {
185 if (osNetAdminService.port(osPort.getId()) != null) {
186 osNetAdminService.updatePort(osPort);
187 } else {
188 osNetAdminService.createPort(osPort);
189 }
190 });
191 } catch (Exception e) {
192 log.warn("Failed to retrieve port due to {}", e.getMessage());
193 return Response.serverError().build();
194 }
Jian Li0b564282018-06-20 00:50:53 +0900195
Jian Lib6bc15d2019-09-24 17:19:05 +0900196 try {
197 osClient.headers(headerMap).networking().router().list().forEach(osRouter -> {
198 if (osRouterAdminService.router(osRouter.getId()) != null) {
199 osRouterAdminService.updateRouter(osRouter);
200 } else {
201 osRouterAdminService.createRouter(osRouter);
202 }
Jian Li0b564282018-06-20 00:50:53 +0900203
Jian Lib6bc15d2019-09-24 17:19:05 +0900204 osNetAdminService.ports().stream()
205 .filter(osPort -> Objects.equals(osPort.getDeviceId(), osRouter.getId()) &&
206 Objects.equals(osPort.getDeviceOwner(), DEVICE_OWNER_IFACE))
207 .forEach(osPort -> addRouterIface(osPort, osRouterAdminService));
208 });
209 } catch (Exception e) {
210 log.warn("Failed to retrieve router due to {}", e.getMessage());
211 return Response.serverError().build();
212 }
Jian Li0b564282018-06-20 00:50:53 +0900213
Jian Lib6bc15d2019-09-24 17:19:05 +0900214 try {
215 osClient.headers(headerMap).networking().floatingip().list().forEach(osFloating -> {
216 if (osRouterAdminService.floatingIp(osFloating.getId()) != null) {
217 osRouterAdminService.updateFloatingIp(osFloating);
218 } else {
219 osRouterAdminService.createFloatingIp(osFloating);
220 }
221 });
222 } catch (Exception e) {
223 log.warn("Failed to retrieve floating IP due to {}", e.getMessage());
224 return Response.serverError().build();
225 }
Jian Li0b564282018-06-20 00:50:53 +0900226
227 return ok(mapper().createObjectNode()).build();
228 }
229
230 /**
231 * Synchronizes the flow rules.
232 *
233 * @return 200 OK with sync result, 404 not found
234 */
235 @GET
236 @Produces(MediaType.APPLICATION_JSON)
237 @Path("sync/rules")
238 public Response syncRules() {
239
Jian Li7f024de2018-07-07 03:51:02 +0900240 syncRulesBase();
Jian Li0b564282018-06-20 00:50:53 +0900241 return ok(mapper().createObjectNode()).build();
242 }
243
244 /**
Jian Li0b564282018-06-20 00:50:53 +0900245 * Purges the flow rules installed by openstacknetworking.
246 *
247 * @return 200 OK with purge result, 404 not found
248 */
249 @GET
250 @Produces(MediaType.APPLICATION_JSON)
251 @Path("purge/rules")
252 public Response purgeRules() {
253
Jian Li167f0c42018-11-18 11:03:51 +0900254 if (purgeRulesBase()) {
255 return ok(mapper().createObjectNode()).build();
256 } else {
257 return Response.serverError().build();
258 }
Jian Li7f024de2018-07-07 03:51:02 +0900259 }
260
261 /**
262 * Configures the ARP mode (proxy | broadcast).
263 *
264 * @param arpmode ARP mode
265 * @return 200 OK with config result, 404 not found
266 */
267 @GET
268 @Produces(MediaType.APPLICATION_JSON)
269 @Path("config/arpmode/{arpmode}")
270 public Response configArpMode(@PathParam("arpmode") String arpmode) {
271
272 String arpModeStr = nullIsIllegal(arpmode, ARP_MODE_REQUIRED);
273 if (checkArpMode(arpModeStr)) {
274 configArpModeBase(arpModeStr);
275
276 ComponentConfigService service = get(ComponentConfigService.class);
277 String switchingComponent = OpenstackSwitchingArpHandler.class.getName();
278 String routingComponent = OpenstackRoutingArpHandler.class.getName();
279
280 // we check the arpMode configured in each component, and purge and
281 // reinstall all rules only if the arpMode is changed to the configured one
282 while (true) {
283 String switchingValue =
284 getPropertyValue(service.getProperties(switchingComponent), ARP_MODE_NAME);
285 String routingValue =
286 getPropertyValue(service.getProperties(routingComponent), ARP_MODE_NAME);
287
288 if (arpModeStr.equals(switchingValue) && arpModeStr.equals(routingValue)) {
289 break;
290 }
291 }
292
293 purgeRulesBase();
294 syncRulesBase();
295 } else {
296 throw new IllegalArgumentException("The ARP mode is not valid");
Jian Li0b564282018-06-20 00:50:53 +0900297 }
Jian Li0b564282018-06-20 00:50:53 +0900298
299 return ok(mapper().createObjectNode()).build();
300 }
Jian Li803a1d52018-06-21 21:47:48 +0900301
302 /**
Jian Li25257212019-03-26 13:31:14 +0900303 * Configures the stateful SNAT flag (enable | disable).
304 *
305 * @param statefulSnat stateful SNAT flag
306 * @return 200 OK with config result, 404 not found
307 */
308 @GET
309 @Produces(MediaType.APPLICATION_JSON)
310 @Path("config/statefulSnat/{statefulSnat}")
311 public Response configStatefulSnat(@PathParam("statefulSnat") String statefulSnat) {
312 String statefulSnatStr = nullIsIllegal(statefulSnat, STATEFUL_SNAT_REQUIRED);
313 boolean flag = checkActivationFlag(statefulSnatStr);
314 configStatefulSnatBase(flag);
315
316 ComponentConfigService service = get(ComponentConfigService.class);
317 String snatComponent = OpenstackRoutingSnatHandler.class.getName();
318
319 while (true) {
320 boolean snatValue =
321 getPropertyValueAsBoolean(
322 service.getProperties(snatComponent), USE_STATEFUL_SNAT_NAME);
323
324 if (flag == snatValue) {
325 break;
326 }
327 }
328
329 purgeRulesBase();
330 syncRulesBase();
331
332 return ok(mapper().createObjectNode()).build();
333 }
334
335 /**
Jian Licad36c72018-09-13 17:44:54 +0900336 * Configures the security group (enable | disable).
337 *
338 * @param securityGroup security group activation flag
339 * @return 200 OK with config result, 404 not found
340 */
341 @GET
342 @Produces(MediaType.APPLICATION_JSON)
343 @Path("config/securityGroup/{securityGroup}")
344 public Response configSecurityGroup(@PathParam("securityGroup") String securityGroup) {
345 String securityGroupStr = nullIsIllegal(securityGroup, SECURITY_GROUP_FLAG_REQUIRED);
346
347 boolean flag = checkActivationFlag(securityGroupStr);
348
349 ComponentConfigService service = get(ComponentConfigService.class);
350 String securityGroupComponent = OpenstackSecurityGroupHandler.class.getName();
351
352 service.setProperty(securityGroupComponent, USE_SECURITY_GROUP_NAME, String.valueOf(flag));
353
354 return ok(mapper().createObjectNode()).build();
355 }
356
357 /**
Jian Li803a1d52018-06-21 21:47:48 +0900358 * Obtains a collection of all floating IPs.
359 *
360 * @return 200 OK with a collection of floating IPs, 404 not found
361 */
362 @GET
363 @Produces(MediaType.APPLICATION_JSON)
364 @Path("floatingips/all")
365 public Response allFloatingIps() {
366
367 List<NetFloatingIP> floatingIps =
368 Lists.newArrayList(osRouterAdminService.floatingIps());
369 floatingIps.stream()
370 .sorted(Comparator.comparing(NetFloatingIP::getFloatingIpAddress))
371 .forEach(fip -> floatingipsNode.add(fip.getFloatingIpAddress()));
372
373 return ok(root).build();
374 }
375
376 /**
377 * Obtains a collection of all floating IPs mapped with fixed IPs.
378 *
379 * @return 200 OK with a collection of floating IPs mapped with fixed IPs,
380 * 404 not found
381 */
382 @GET
383 @Produces(MediaType.APPLICATION_JSON)
384 @Path("floatingips/mapped")
385 public Response mappedFloatingIps() {
386
387 List<NetFloatingIP> floatingIps =
388 Lists.newArrayList(osRouterAdminService.floatingIps());
389
390 floatingIps.stream()
391 .filter(fip -> !Strings.isNullOrEmpty(fip.getFixedIpAddress()))
392 .sorted(Comparator.comparing(NetFloatingIP::getFloatingIpAddress))
393 .forEach(fip -> floatingipsNode.add(fip.getFloatingIpAddress()));
394
395 return ok(root).build();
396 }
Jian Li7f024de2018-07-07 03:51:02 +0900397
Jian Li7b8c3682019-05-12 13:57:15 +0900398 /**
399 * Configures the HA active-standby status.
400 *
401 * @param flag active-standby status
402 * @return 200 OK or 400 BAD_REQUEST
403 */
404 @PUT
405 @Path("active/status/{flag}")
406 @Consumes(MediaType.APPLICATION_JSON)
407 @Produces(MediaType.APPLICATION_JSON)
408 public Response updateActiveStatus(@PathParam("flag") String flag) {
409
410 if (FLAG_TRUE.equalsIgnoreCase(flag)) {
411 osHaService.setActive(true);
412 }
413
414 if (FLAG_FALSE.equalsIgnoreCase(flag)) {
415 osHaService.setActive(false);
416 }
417
418 return status(Response.Status.OK).build();
419 }
420
421 /**
Jian Li812460d2019-05-13 15:41:30 +0900422 * Configures the HA active-standby status.
423 *
424 * @return 200 OK with HA status.
425 * True if the node runs in active mode, false otherwise
426 */
427 @GET
428 @Path("active/status")
429 @Produces(MediaType.APPLICATION_JSON)
430 public Response getActiveStatus() {
431 return ok(mapper().createObjectNode().put(IS_ACTIVE, osHaService.isActive())).build();
432 }
433
434 /**
Jian Li7b8c3682019-05-12 13:57:15 +0900435 * Configures the HA active IP address.
436 *
437 * @param ip IP address of active node
438 * @return 200 OK or 400 BAD_REQUEST
439 */
440 @PUT
441 @Path("active/ip/{ip}")
442 @Consumes(MediaType.APPLICATION_JSON)
443 @Produces(MediaType.APPLICATION_JSON)
444 public Response updateActiveIp(@PathParam("ip") String ip) {
445
446 osHaService.setActiveIp(IpAddress.valueOf(ip));
447
448 return status(Response.Status.OK).build();
449 }
450
Jian Li7f024de2018-07-07 03:51:02 +0900451 private void syncRulesBase() {
Jian Li5c777c62018-11-11 00:31:20 +0900452 // we first initialize the COMPUTE node, in order to feed all instance ports
453 // by referring to ports' information obtained from neutron server
454 osNodeAdminService.completeNodes(COMPUTE).forEach(this::syncRulesBaseForNode);
455 osNodeAdminService.completeNodes(GATEWAY).forEach(this::syncRulesBaseForNode);
456 }
Jian Li88ae51e2018-07-10 02:23:35 +0900457
Jian Li5c777c62018-11-11 00:31:20 +0900458 private void syncRulesBaseForNode(OpenstackNode osNode) {
459 OpenstackNode updated = osNode.updateState(NodeState.INIT);
460 osNodeAdminService.updateNode(updated);
Jian Li88ae51e2018-07-10 02:23:35 +0900461
Jian Li8b5599b2018-11-19 18:45:46 +0900462 boolean result = true;
463 long timeoutExpiredMs = System.currentTimeMillis() + TIMEOUT_MS;
464
465 while (osNodeAdminService.node(osNode.hostname()).state() != COMPLETE) {
466
467 long waitMs = timeoutExpiredMs - System.currentTimeMillis();
468
469 try {
470 sleep(SLEEP_MS);
471 } catch (InterruptedException e) {
472 log.error("Exception caused during node synchronization...");
473 }
474
475 if (osNodeAdminService.node(osNode.hostname()).state() == COMPLETE) {
476 break;
477 } else {
478 osNodeAdminService.updateNode(updated);
479 log.info("Failed to synchronize flow rules, retrying...");
480 }
481
482 if (waitMs <= 0) {
483 result = false;
484 break;
485 }
Jian Li5c777c62018-11-11 00:31:20 +0900486 }
487
Jian Li8b5599b2018-11-19 18:45:46 +0900488 if (result) {
489 log.info("Successfully synchronize flow rules for node {}!", osNode.hostname());
Jian Li5c777c62018-11-11 00:31:20 +0900490 } else {
Jian Li8b5599b2018-11-19 18:45:46 +0900491 log.warn("Failed to synchronize flow rules for node {}.", osNode.hostname());
Jian Li5c777c62018-11-11 00:31:20 +0900492 }
Jian Li7f024de2018-07-07 03:51:02 +0900493 }
494
Jian Li167f0c42018-11-18 11:03:51 +0900495 private boolean purgeRulesBase() {
Jian Li7f024de2018-07-07 03:51:02 +0900496 ApplicationId appId = coreService.getAppId(Constants.OPENSTACK_NETWORKING_APP_ID);
497 if (appId == null) {
498 throw new ItemNotFoundException("application not found");
499 }
Jian Li167f0c42018-11-18 11:03:51 +0900500
Jian Li7f024de2018-07-07 03:51:02 +0900501 flowRuleService.removeFlowRulesById(appId);
Jian Li167f0c42018-11-18 11:03:51 +0900502
503 boolean result = true;
504 long timeoutExpiredMs = System.currentTimeMillis() + TIMEOUT_MS;
505
506 // we make sure all flow rules are removed from the store
507 while (stream(flowRuleService.getFlowEntriesById(appId)
508 .spliterator(), false).count() > 0) {
509
510 long waitMs = timeoutExpiredMs - System.currentTimeMillis();
511
512 try {
513 sleep(SLEEP_MS);
514 } catch (InterruptedException e) {
515 log.error("Exception caused during rule purging...");
516 }
517
518 if (stream(flowRuleService.getFlowEntriesById(appId)
519 .spliterator(), false).count() == 0) {
520 break;
521 } else {
522 flowRuleService.removeFlowRulesById(appId);
523 log.info("Failed to purging flow rules, retrying rule purging...");
524 }
525
526 if (waitMs <= 0) {
527 result = false;
528 break;
529 }
530 }
531
532 if (result) {
533 log.info("Successfully purged flow rules!");
534 } else {
535 log.warn("Failed to purge flow rules.");
536 }
537
538 return result;
Jian Li7f024de2018-07-07 03:51:02 +0900539 }
540
541 private void configArpModeBase(String arpMode) {
542 ComponentConfigService service = get(ComponentConfigService.class);
543 String switchingComponent = OpenstackSwitchingArpHandler.class.getName();
544 String routingComponent = OpenstackRoutingArpHandler.class.getName();
545
546 service.setProperty(switchingComponent, ARP_MODE_NAME, arpMode);
547 service.setProperty(routingComponent, ARP_MODE_NAME, arpMode);
548 }
Jian Li25257212019-03-26 13:31:14 +0900549
550 private void configStatefulSnatBase(boolean snatFlag) {
551 ComponentConfigService service = get(ComponentConfigService.class);
552 String snatComponent = OpenstackRoutingSnatHandler.class.getName();
553
554 service.setProperty(snatComponent, USE_STATEFUL_SNAT_NAME, String.valueOf(snatFlag));
555 }
Jian Li0b564282018-06-20 00:50:53 +0900556}