blob: c6776c7bb6db49e2474f2a50d4d55ba3ddea20e0 [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
Jian Li3423ba12019-09-24 01:01:24 +090098 private static final String AUTH_INFO_NOT_FOUND = "Auth info is not found";
99 private static final String AUTH_INFO_NOT_CORRECT = "Auth info is not correct";
100
sanghoshin2a354e32018-11-09 12:52:44 +0800101 private static final String HTTP_HEADER_ACCEPT = "accept";
102 private static final String HTTP_HEADER_VALUE_JSON = "application/json";
103
Jian Li812460d2019-05-13 15:41:30 +0900104 private static final String IS_ACTIVE = "isActive";
Jian Li7b8c3682019-05-12 13:57:15 +0900105 private static final String FLAG_TRUE = "true";
106 private static final String FLAG_FALSE = "false";
107
Jian Li803a1d52018-06-21 21:47:48 +0900108 private final ObjectNode root = mapper().createObjectNode();
109 private final ArrayNode floatingipsNode = root.putArray(FLOATINGIPS);
Jian Li0b564282018-06-20 00:50:53 +0900110
111 private final OpenstackSecurityGroupAdminService osSgAdminService =
112 get(OpenstackSecurityGroupAdminService.class);
113 private final OpenstackNetworkAdminService osNetAdminService =
114 get(OpenstackNetworkAdminService.class);
115 private final OpenstackRouterAdminService osRouterAdminService =
116 get(OpenstackRouterAdminService.class);
Jian Li0b564282018-06-20 00:50:53 +0900117 private final OpenstackNodeAdminService osNodeAdminService =
118 get(OpenstackNodeAdminService.class);
Jian Li7b8c3682019-05-12 13:57:15 +0900119 private final OpenstackHaService osHaService = get(OpenstackHaService.class);
Jian Li0b564282018-06-20 00:50:53 +0900120 private final FlowRuleService flowRuleService = get(FlowRuleService.class);
121 private final CoreService coreService = get(CoreService.class);
122
123 /**
124 * Synchronizes the network states with openstack.
125 *
126 * @return 200 OK with sync result, 404 not found
127 */
128 @GET
129 @Produces(MediaType.APPLICATION_JSON)
130 @Path("sync/states")
131 public Response syncStates() {
132
sanghoshin2a354e32018-11-09 12:52:44 +0800133 Map<String, String> headerMap = new HashMap();
134 headerMap.put(HTTP_HEADER_ACCEPT, HTTP_HEADER_VALUE_JSON);
135
Jian Li78ac0652018-07-17 18:10:16 +0900136 Optional<OpenstackNode> node = osNodeAdminService.nodes(CONTROLLER).stream().findFirst();
Jian Li0b564282018-06-20 00:50:53 +0900137 if (!node.isPresent()) {
Jian Li3423ba12019-09-24 01:01:24 +0900138 log.error(AUTH_INFO_NOT_FOUND);
139 throw new ItemNotFoundException(AUTH_INFO_NOT_FOUND);
Jian Li0b564282018-06-20 00:50:53 +0900140 }
141
142 OSClient osClient = OpenstackNetworkingUtil.getConnectedClient(node.get());
143
144 if (osClient == null) {
Jian Li3423ba12019-09-24 01:01:24 +0900145 log.error(AUTH_INFO_NOT_CORRECT);
146 throw new ItemNotFoundException(AUTH_INFO_NOT_CORRECT);
Jian Li0b564282018-06-20 00:50:53 +0900147 }
148
Jian Lib6bc15d2019-09-24 17:19:05 +0900149 try {
150 osClient.headers(headerMap).networking().securitygroup().list().forEach(osSg -> {
151 if (osSgAdminService.securityGroup(osSg.getId()) != null) {
152 osSgAdminService.updateSecurityGroup(osSg);
153 } else {
154 osSgAdminService.createSecurityGroup(osSg);
155 }
156 });
157 } catch (Exception e) {
158 log.warn("Failed to retrieve security group due to {}", e.getMessage());
159 return Response.serverError().build();
160 }
Jian Li0b564282018-06-20 00:50:53 +0900161
Jian Lib6bc15d2019-09-24 17:19:05 +0900162 try {
163 osClient.headers(headerMap).networking().network().list().forEach(osNet -> {
164 if (osNetAdminService.network(osNet.getId()) != null) {
165 osNetAdminService.updateNetwork(osNet);
166 } else {
167 osNetAdminService.createNetwork(osNet);
168 }
169 });
170 } catch (Exception e) {
171 log.warn("Failed to retrieve network due to {}", e.getMessage());
172 return Response.serverError().build();
173 }
Jian Li0b564282018-06-20 00:50:53 +0900174
Jian Lib6bc15d2019-09-24 17:19:05 +0900175 try {
176 osClient.headers(headerMap).networking().subnet().list().forEach(osSubnet -> {
177 if (osNetAdminService.subnet(osSubnet.getId()) != null) {
178 osNetAdminService.updateSubnet(osSubnet);
179 } else {
180 osNetAdminService.createSubnet(osSubnet);
181 }
182 });
183 } catch (Exception e) {
184 log.warn("Failed to retrieve subnet due to {}", e.getMessage());
185 return Response.serverError().build();
186 }
Jian Li0b564282018-06-20 00:50:53 +0900187
Jian Lib6bc15d2019-09-24 17:19:05 +0900188 try {
189 osClient.headers(headerMap).networking().port().list().forEach(osPort -> {
190 if (osNetAdminService.port(osPort.getId()) != null) {
191 osNetAdminService.updatePort(osPort);
192 } else {
193 osNetAdminService.createPort(osPort);
194 }
195 });
196 } catch (Exception e) {
197 log.warn("Failed to retrieve port due to {}", e.getMessage());
198 return Response.serverError().build();
199 }
Jian Li0b564282018-06-20 00:50:53 +0900200
Jian Lib6bc15d2019-09-24 17:19:05 +0900201 try {
202 osClient.headers(headerMap).networking().router().list().forEach(osRouter -> {
203 if (osRouterAdminService.router(osRouter.getId()) != null) {
204 osRouterAdminService.updateRouter(osRouter);
205 } else {
206 osRouterAdminService.createRouter(osRouter);
207 }
Jian Li0b564282018-06-20 00:50:53 +0900208
Jian Lib6bc15d2019-09-24 17:19:05 +0900209 osNetAdminService.ports().stream()
210 .filter(osPort -> Objects.equals(osPort.getDeviceId(), osRouter.getId()) &&
211 Objects.equals(osPort.getDeviceOwner(), DEVICE_OWNER_IFACE))
212 .forEach(osPort -> addRouterIface(osPort, osRouterAdminService));
213 });
214 } catch (Exception e) {
215 log.warn("Failed to retrieve router due to {}", e.getMessage());
216 return Response.serverError().build();
217 }
Jian Li0b564282018-06-20 00:50:53 +0900218
Jian Lib6bc15d2019-09-24 17:19:05 +0900219 try {
220 osClient.headers(headerMap).networking().floatingip().list().forEach(osFloating -> {
221 if (osRouterAdminService.floatingIp(osFloating.getId()) != null) {
222 osRouterAdminService.updateFloatingIp(osFloating);
223 } else {
224 osRouterAdminService.createFloatingIp(osFloating);
225 }
226 });
227 } catch (Exception e) {
228 log.warn("Failed to retrieve floating IP due to {}", e.getMessage());
229 return Response.serverError().build();
230 }
Jian Li0b564282018-06-20 00:50:53 +0900231
232 return ok(mapper().createObjectNode()).build();
233 }
234
235 /**
236 * Synchronizes the flow rules.
237 *
238 * @return 200 OK with sync result, 404 not found
239 */
240 @GET
241 @Produces(MediaType.APPLICATION_JSON)
242 @Path("sync/rules")
243 public Response syncRules() {
244
Jian Li7f024de2018-07-07 03:51:02 +0900245 syncRulesBase();
Jian Li0b564282018-06-20 00:50:53 +0900246 return ok(mapper().createObjectNode()).build();
247 }
248
249 /**
Jian Li0b564282018-06-20 00:50:53 +0900250 * Purges the flow rules installed by openstacknetworking.
251 *
252 * @return 200 OK with purge result, 404 not found
253 */
254 @GET
255 @Produces(MediaType.APPLICATION_JSON)
256 @Path("purge/rules")
257 public Response purgeRules() {
258
Jian Li167f0c42018-11-18 11:03:51 +0900259 if (purgeRulesBase()) {
260 return ok(mapper().createObjectNode()).build();
261 } else {
262 return Response.serverError().build();
263 }
Jian Li7f024de2018-07-07 03:51:02 +0900264 }
265
266 /**
267 * Configures the ARP mode (proxy | broadcast).
268 *
269 * @param arpmode ARP mode
270 * @return 200 OK with config result, 404 not found
271 */
272 @GET
273 @Produces(MediaType.APPLICATION_JSON)
274 @Path("config/arpmode/{arpmode}")
275 public Response configArpMode(@PathParam("arpmode") String arpmode) {
276
277 String arpModeStr = nullIsIllegal(arpmode, ARP_MODE_REQUIRED);
278 if (checkArpMode(arpModeStr)) {
279 configArpModeBase(arpModeStr);
280
281 ComponentConfigService service = get(ComponentConfigService.class);
282 String switchingComponent = OpenstackSwitchingArpHandler.class.getName();
283 String routingComponent = OpenstackRoutingArpHandler.class.getName();
284
285 // we check the arpMode configured in each component, and purge and
286 // reinstall all rules only if the arpMode is changed to the configured one
287 while (true) {
288 String switchingValue =
289 getPropertyValue(service.getProperties(switchingComponent), ARP_MODE_NAME);
290 String routingValue =
291 getPropertyValue(service.getProperties(routingComponent), ARP_MODE_NAME);
292
293 if (arpModeStr.equals(switchingValue) && arpModeStr.equals(routingValue)) {
294 break;
295 }
296 }
297
298 purgeRulesBase();
299 syncRulesBase();
300 } else {
301 throw new IllegalArgumentException("The ARP mode is not valid");
Jian Li0b564282018-06-20 00:50:53 +0900302 }
Jian Li0b564282018-06-20 00:50:53 +0900303
304 return ok(mapper().createObjectNode()).build();
305 }
Jian Li803a1d52018-06-21 21:47:48 +0900306
307 /**
Jian Li25257212019-03-26 13:31:14 +0900308 * Configures the stateful SNAT flag (enable | disable).
309 *
310 * @param statefulSnat stateful SNAT flag
311 * @return 200 OK with config result, 404 not found
312 */
313 @GET
314 @Produces(MediaType.APPLICATION_JSON)
315 @Path("config/statefulSnat/{statefulSnat}")
316 public Response configStatefulSnat(@PathParam("statefulSnat") String statefulSnat) {
317 String statefulSnatStr = nullIsIllegal(statefulSnat, STATEFUL_SNAT_REQUIRED);
318 boolean flag = checkActivationFlag(statefulSnatStr);
319 configStatefulSnatBase(flag);
320
321 ComponentConfigService service = get(ComponentConfigService.class);
322 String snatComponent = OpenstackRoutingSnatHandler.class.getName();
323
324 while (true) {
325 boolean snatValue =
326 getPropertyValueAsBoolean(
327 service.getProperties(snatComponent), USE_STATEFUL_SNAT_NAME);
328
329 if (flag == snatValue) {
330 break;
331 }
332 }
333
334 purgeRulesBase();
335 syncRulesBase();
336
337 return ok(mapper().createObjectNode()).build();
338 }
339
340 /**
Jian Licad36c72018-09-13 17:44:54 +0900341 * Configures the security group (enable | disable).
342 *
343 * @param securityGroup security group activation flag
344 * @return 200 OK with config result, 404 not found
345 */
346 @GET
347 @Produces(MediaType.APPLICATION_JSON)
348 @Path("config/securityGroup/{securityGroup}")
349 public Response configSecurityGroup(@PathParam("securityGroup") String securityGroup) {
350 String securityGroupStr = nullIsIllegal(securityGroup, SECURITY_GROUP_FLAG_REQUIRED);
351
352 boolean flag = checkActivationFlag(securityGroupStr);
353
354 ComponentConfigService service = get(ComponentConfigService.class);
355 String securityGroupComponent = OpenstackSecurityGroupHandler.class.getName();
356
357 service.setProperty(securityGroupComponent, USE_SECURITY_GROUP_NAME, String.valueOf(flag));
358
359 return ok(mapper().createObjectNode()).build();
360 }
361
362 /**
Jian Li803a1d52018-06-21 21:47:48 +0900363 * Obtains a collection of all floating IPs.
364 *
365 * @return 200 OK with a collection of floating IPs, 404 not found
366 */
367 @GET
368 @Produces(MediaType.APPLICATION_JSON)
369 @Path("floatingips/all")
370 public Response allFloatingIps() {
371
372 List<NetFloatingIP> floatingIps =
373 Lists.newArrayList(osRouterAdminService.floatingIps());
374 floatingIps.stream()
375 .sorted(Comparator.comparing(NetFloatingIP::getFloatingIpAddress))
376 .forEach(fip -> floatingipsNode.add(fip.getFloatingIpAddress()));
377
378 return ok(root).build();
379 }
380
381 /**
382 * Obtains a collection of all floating IPs mapped with fixed IPs.
383 *
384 * @return 200 OK with a collection of floating IPs mapped with fixed IPs,
385 * 404 not found
386 */
387 @GET
388 @Produces(MediaType.APPLICATION_JSON)
389 @Path("floatingips/mapped")
390 public Response mappedFloatingIps() {
391
392 List<NetFloatingIP> floatingIps =
393 Lists.newArrayList(osRouterAdminService.floatingIps());
394
395 floatingIps.stream()
396 .filter(fip -> !Strings.isNullOrEmpty(fip.getFixedIpAddress()))
397 .sorted(Comparator.comparing(NetFloatingIP::getFloatingIpAddress))
398 .forEach(fip -> floatingipsNode.add(fip.getFloatingIpAddress()));
399
400 return ok(root).build();
401 }
Jian Li7f024de2018-07-07 03:51:02 +0900402
Jian Li7b8c3682019-05-12 13:57:15 +0900403 /**
404 * Configures the HA active-standby status.
405 *
406 * @param flag active-standby status
407 * @return 200 OK or 400 BAD_REQUEST
408 */
409 @PUT
410 @Path("active/status/{flag}")
411 @Consumes(MediaType.APPLICATION_JSON)
412 @Produces(MediaType.APPLICATION_JSON)
413 public Response updateActiveStatus(@PathParam("flag") String flag) {
414
Jian Li3423ba12019-09-24 01:01:24 +0900415 log.info("Update active status to {}", flag);
416
Jian Li7b8c3682019-05-12 13:57:15 +0900417 if (FLAG_TRUE.equalsIgnoreCase(flag)) {
418 osHaService.setActive(true);
419 }
420
421 if (FLAG_FALSE.equalsIgnoreCase(flag)) {
422 osHaService.setActive(false);
423 }
424
425 return status(Response.Status.OK).build();
426 }
427
428 /**
Jian Li812460d2019-05-13 15:41:30 +0900429 * Configures the HA active-standby status.
430 *
431 * @return 200 OK with HA status.
432 * True if the node runs in active mode, false otherwise
433 */
434 @GET
435 @Path("active/status")
436 @Produces(MediaType.APPLICATION_JSON)
437 public Response getActiveStatus() {
438 return ok(mapper().createObjectNode().put(IS_ACTIVE, osHaService.isActive())).build();
439 }
440
441 /**
Jian Li7b8c3682019-05-12 13:57:15 +0900442 * Configures the HA active IP address.
443 *
444 * @param ip IP address of active node
445 * @return 200 OK or 400 BAD_REQUEST
446 */
447 @PUT
448 @Path("active/ip/{ip}")
449 @Consumes(MediaType.APPLICATION_JSON)
450 @Produces(MediaType.APPLICATION_JSON)
451 public Response updateActiveIp(@PathParam("ip") String ip) {
452
Jian Li3423ba12019-09-24 01:01:24 +0900453 log.info("Update active IP address to {}", ip);
454
Jian Li7b8c3682019-05-12 13:57:15 +0900455 osHaService.setActiveIp(IpAddress.valueOf(ip));
456
457 return status(Response.Status.OK).build();
458 }
459
Jian Li7f024de2018-07-07 03:51:02 +0900460 private void syncRulesBase() {
Jian Li5c777c62018-11-11 00:31:20 +0900461 // we first initialize the COMPUTE node, in order to feed all instance ports
462 // by referring to ports' information obtained from neutron server
463 osNodeAdminService.completeNodes(COMPUTE).forEach(this::syncRulesBaseForNode);
464 osNodeAdminService.completeNodes(GATEWAY).forEach(this::syncRulesBaseForNode);
465 }
Jian Li88ae51e2018-07-10 02:23:35 +0900466
Jian Li5c777c62018-11-11 00:31:20 +0900467 private void syncRulesBaseForNode(OpenstackNode osNode) {
468 OpenstackNode updated = osNode.updateState(NodeState.INIT);
469 osNodeAdminService.updateNode(updated);
Jian Li88ae51e2018-07-10 02:23:35 +0900470
Jian Li8b5599b2018-11-19 18:45:46 +0900471 boolean result = true;
472 long timeoutExpiredMs = System.currentTimeMillis() + TIMEOUT_MS;
473
474 while (osNodeAdminService.node(osNode.hostname()).state() != COMPLETE) {
475
476 long waitMs = timeoutExpiredMs - System.currentTimeMillis();
477
478 try {
479 sleep(SLEEP_MS);
480 } catch (InterruptedException e) {
481 log.error("Exception caused during node synchronization...");
482 }
483
484 if (osNodeAdminService.node(osNode.hostname()).state() == COMPLETE) {
485 break;
486 } else {
487 osNodeAdminService.updateNode(updated);
488 log.info("Failed to synchronize flow rules, retrying...");
489 }
490
491 if (waitMs <= 0) {
492 result = false;
493 break;
494 }
Jian Li5c777c62018-11-11 00:31:20 +0900495 }
496
Jian Li8b5599b2018-11-19 18:45:46 +0900497 if (result) {
498 log.info("Successfully synchronize flow rules for node {}!", osNode.hostname());
Jian Li5c777c62018-11-11 00:31:20 +0900499 } else {
Jian Li8b5599b2018-11-19 18:45:46 +0900500 log.warn("Failed to synchronize flow rules for node {}.", osNode.hostname());
Jian Li5c777c62018-11-11 00:31:20 +0900501 }
Jian Li7f024de2018-07-07 03:51:02 +0900502 }
503
Jian Li167f0c42018-11-18 11:03:51 +0900504 private boolean purgeRulesBase() {
Jian Li7f024de2018-07-07 03:51:02 +0900505 ApplicationId appId = coreService.getAppId(Constants.OPENSTACK_NETWORKING_APP_ID);
506 if (appId == null) {
507 throw new ItemNotFoundException("application not found");
508 }
Jian Li167f0c42018-11-18 11:03:51 +0900509
Jian Li7f024de2018-07-07 03:51:02 +0900510 flowRuleService.removeFlowRulesById(appId);
Jian Li167f0c42018-11-18 11:03:51 +0900511
512 boolean result = true;
513 long timeoutExpiredMs = System.currentTimeMillis() + TIMEOUT_MS;
514
515 // we make sure all flow rules are removed from the store
516 while (stream(flowRuleService.getFlowEntriesById(appId)
517 .spliterator(), false).count() > 0) {
518
519 long waitMs = timeoutExpiredMs - System.currentTimeMillis();
520
521 try {
522 sleep(SLEEP_MS);
523 } catch (InterruptedException e) {
524 log.error("Exception caused during rule purging...");
525 }
526
527 if (stream(flowRuleService.getFlowEntriesById(appId)
528 .spliterator(), false).count() == 0) {
529 break;
530 } else {
531 flowRuleService.removeFlowRulesById(appId);
532 log.info("Failed to purging flow rules, retrying rule purging...");
533 }
534
535 if (waitMs <= 0) {
536 result = false;
537 break;
538 }
539 }
540
541 if (result) {
542 log.info("Successfully purged flow rules!");
543 } else {
544 log.warn("Failed to purge flow rules.");
545 }
546
547 return result;
Jian Li7f024de2018-07-07 03:51:02 +0900548 }
549
550 private void configArpModeBase(String arpMode) {
551 ComponentConfigService service = get(ComponentConfigService.class);
552 String switchingComponent = OpenstackSwitchingArpHandler.class.getName();
553 String routingComponent = OpenstackRoutingArpHandler.class.getName();
554
555 service.setProperty(switchingComponent, ARP_MODE_NAME, arpMode);
556 service.setProperty(routingComponent, ARP_MODE_NAME, arpMode);
557 }
Jian Li25257212019-03-26 13:31:14 +0900558
559 private void configStatefulSnatBase(boolean snatFlag) {
560 ComponentConfigService service = get(ComponentConfigService.class);
561 String snatComponent = OpenstackRoutingSnatHandler.class.getName();
562
563 service.setProperty(snatComponent, USE_STATEFUL_SNAT_NAME, String.valueOf(snatFlag));
564 }
Jian Li0b564282018-06-20 00:50:53 +0900565}