blob: 828e647c4bf345ae5a28949a29aa78f9d0465c57 [file] [log] [blame]
Hyunsun Moon44aac662017-02-18 02:07:01 +09001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Hyunsun Moon44aac662017-02-18 02:07:01 +09003 *
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.impl;
17
18import com.google.common.base.Strings;
Hyunsun Moon44aac662017-02-18 02:07:01 +090019import org.onlab.packet.IpAddress;
20import org.onlab.packet.MacAddress;
21import org.onlab.packet.VlanId;
22import org.onlab.util.Tools;
23import org.onosproject.core.CoreService;
24import org.onosproject.mastership.MastershipService;
25import org.onosproject.net.ConnectPoint;
26import org.onosproject.net.DefaultAnnotations;
27import org.onosproject.net.Device;
28import org.onosproject.net.Host;
29import org.onosproject.net.HostId;
30import org.onosproject.net.HostLocation;
31import org.onosproject.net.Port;
32import org.onosproject.net.device.DeviceEvent;
33import org.onosproject.net.device.DeviceListener;
34import org.onosproject.net.device.DeviceService;
35import org.onosproject.net.host.DefaultHostDescription;
36import org.onosproject.net.host.HostDescription;
37import org.onosproject.net.host.HostProvider;
38import org.onosproject.net.host.HostProviderRegistry;
39import org.onosproject.net.host.HostProviderService;
40import org.onosproject.net.host.HostService;
41import org.onosproject.net.provider.AbstractProvider;
42import org.onosproject.net.provider.ProviderId;
Daniel Park7e8c4d82018-08-13 23:47:49 +090043import org.onosproject.openstacknetworking.api.Constants;
Hyunsun Moon44aac662017-02-18 02:07:01 +090044import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
Hyunsun Moon0d457362017-06-27 17:19:41 +090045import org.onosproject.openstacknode.api.OpenstackNode;
46import org.onosproject.openstacknode.api.OpenstackNodeEvent;
47import org.onosproject.openstacknode.api.OpenstackNodeListener;
48import org.onosproject.openstacknode.api.OpenstackNodeService;
Hyunsun Moon44aac662017-02-18 02:07:01 +090049import org.openstack4j.model.network.Network;
daniel park796c2eb2018-03-22 17:01:51 +090050import org.openstack4j.model.network.NetworkType;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070051import org.osgi.service.component.annotations.Activate;
52import org.osgi.service.component.annotations.Component;
53import org.osgi.service.component.annotations.Deactivate;
54import org.osgi.service.component.annotations.Reference;
55import org.osgi.service.component.annotations.ReferenceCardinality;
Hyunsun Moon44aac662017-02-18 02:07:01 +090056import org.slf4j.Logger;
57import org.slf4j.LoggerFactory;
58
Jian Liec5c32b2018-07-13 14:28:58 +090059import java.util.Optional;
Hyunsun Moon44aac662017-02-18 02:07:01 +090060import java.util.Set;
61import java.util.concurrent.ExecutorService;
62import java.util.concurrent.Executors;
63import java.util.stream.Collectors;
64
65import static org.onlab.util.Tools.groupedThreads;
66import static org.onosproject.net.AnnotationKeys.PORT_NAME;
Jian Liec5c32b2018-07-13 14:28:58 +090067import static org.onosproject.openstacknetworking.api.Constants.ANNOTATION_CREATE_TIME;
68import static org.onosproject.openstacknetworking.api.Constants.ANNOTATION_NETWORK_ID;
69import static org.onosproject.openstacknetworking.api.Constants.ANNOTATION_PORT_ID;
70import static org.onosproject.openstacknetworking.api.Constants.ANNOTATION_SEGMENT_ID;
daniel park796c2eb2018-03-22 17:01:51 +090071import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
Daniel Park7e8c4d82018-08-13 23:47:49 +090072import static org.onosproject.openstacknetworking.api.Constants.PORT_NAME_PREFIX_VM;
73import static org.onosproject.openstacknetworking.api.Constants.PORT_NAME_VHOST_USER_PREFIX_VM;
Ray Milkey9dc57392018-06-08 08:52:31 -070074import static org.onosproject.openstacknetworking.api.Constants.portNamePrefixMap;
Daniel Park7e8c4d82018-08-13 23:47:49 +090075import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.vnicType;
Jian Li51b844c2018-05-31 10:59:03 +090076import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.CONTROLLER;
Hyunsun Moon44aac662017-02-18 02:07:01 +090077
Ray Milkeyd84f89b2018-08-17 14:54:17 -070078@Component(immediate = true, service = HostProvider.class)
Jian Li6a47fd02018-11-27 21:51:03 +090079public class OpenstackSwitchingHostProvider
Jian Li46b74002018-07-15 18:39:08 +090080 extends AbstractProvider implements HostProvider {
Hyunsun Moon44aac662017-02-18 02:07:01 +090081
82 private final Logger log = LoggerFactory.getLogger(getClass());
83
Hyunsun Moon44aac662017-02-18 02:07:01 +090084 private static final String ERR_ADD_HOST = "Failed to add host: ";
Jian Li9d676fb2018-03-02 15:25:36 +090085 private static final String SONA_HOST_SCHEME = "sona";
Hyunsun Moon44aac662017-02-18 02:07:01 +090086
Ray Milkeyd84f89b2018-08-17 14:54:17 -070087 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Li9d676fb2018-03-02 15:25:36 +090088 protected CoreService coreService;
Hyunsun Moon44aac662017-02-18 02:07:01 +090089
Ray Milkeyd84f89b2018-08-17 14:54:17 -070090 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Li9d676fb2018-03-02 15:25:36 +090091 protected DeviceService deviceService;
Hyunsun Moon44aac662017-02-18 02:07:01 +090092
Ray Milkeyd84f89b2018-08-17 14:54:17 -070093 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Li9d676fb2018-03-02 15:25:36 +090094 protected HostProviderRegistry hostProviderRegistry;
Hyunsun Moon44aac662017-02-18 02:07:01 +090095
Ray Milkeyd84f89b2018-08-17 14:54:17 -070096 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Li9d676fb2018-03-02 15:25:36 +090097 protected HostService hostService;
Hyunsun Moon44aac662017-02-18 02:07:01 +090098
Ray Milkeyd84f89b2018-08-17 14:54:17 -070099 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Li9d676fb2018-03-02 15:25:36 +0900100 protected MastershipService mastershipService;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900101
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700102 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Li9d676fb2018-03-02 15:25:36 +0900103 protected OpenstackNetworkService osNetworkService;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900104
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700105 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Li9d676fb2018-03-02 15:25:36 +0900106 protected OpenstackNodeService osNodeService;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900107
Jian Li07598ff2018-07-23 18:34:34 +0900108 private HostProviderService hostProviderService;
Jian Li24ec59f2018-05-23 19:01:25 +0900109
Jian Li5ecfd1a2018-12-10 11:41:03 +0900110 private final ExecutorService executor = Executors.newSingleThreadExecutor(
111 groupedThreads(this.getClass().getSimpleName(), "device-event"));
Jian Li46b74002018-07-15 18:39:08 +0900112 private final InternalDeviceListener internalDeviceListener =
113 new InternalDeviceListener();
114 private final InternalOpenstackNodeListener internalNodeListener =
115 new InternalOpenstackNodeListener();
Hyunsun Moon44aac662017-02-18 02:07:01 +0900116
Hyunsun Moon44aac662017-02-18 02:07:01 +0900117 /**
118 * Creates OpenStack switching host provider.
119 */
120 public OpenstackSwitchingHostProvider() {
Jian Li9d676fb2018-03-02 15:25:36 +0900121 super(new ProviderId(SONA_HOST_SCHEME, OPENSTACK_NETWORKING_APP_ID));
Hyunsun Moon44aac662017-02-18 02:07:01 +0900122 }
123
124 @Activate
Jian Li6a47fd02018-11-27 21:51:03 +0900125 protected void activate() {
Hyunsun Moon44aac662017-02-18 02:07:01 +0900126 coreService.registerApplication(OPENSTACK_NETWORKING_APP_ID);
127 deviceService.addListener(internalDeviceListener);
128 osNodeService.addListener(internalNodeListener);
Jian Li07598ff2018-07-23 18:34:34 +0900129 hostProviderService = hostProviderRegistry.register(this);
Hyunsun Moon44aac662017-02-18 02:07:01 +0900130
131 log.info("Started");
132 }
133
134 @Deactivate
Jian Li6a47fd02018-11-27 21:51:03 +0900135 protected void deactivate() {
Hyunsun Moon44aac662017-02-18 02:07:01 +0900136 hostProviderRegistry.unregister(this);
137 osNodeService.removeListener(internalNodeListener);
138 deviceService.removeListener(internalDeviceListener);
139
Jian Li07598ff2018-07-23 18:34:34 +0900140 executor.shutdown();
Hyunsun Moon44aac662017-02-18 02:07:01 +0900141
142 log.info("Stopped");
143 }
144
145 @Override
146 public void triggerProbe(Host host) {
147 // no probe is required
148 }
149
Jian Li9d676fb2018-03-02 15:25:36 +0900150 /**
Jian Li07598ff2018-07-23 18:34:34 +0900151 * A helper method which logs the port addition event and performs port
152 * addition action.
153 *
154 * @param event device event
155 */
Jian Li6a47fd02018-11-27 21:51:03 +0900156 void portAddedHelper(DeviceEvent event) {
Jian Li07598ff2018-07-23 18:34:34 +0900157 log.debug("Instance port {} is detected from {}",
158 event.port().annotations().value(PORT_NAME),
159 event.subject().id());
160 processPortAdded(event.port());
161 }
162
163 /**
164 * A helper method which logs the port removal event and performs port
165 * removal action.
166 *
167 * @param event device event
168 */
Jian Li6a47fd02018-11-27 21:51:03 +0900169 void portRemovedHelper(DeviceEvent event) {
Jian Li07598ff2018-07-23 18:34:34 +0900170 log.debug("Instance port {} is removed from {}",
171 event.port().annotations().value(PORT_NAME),
172 event.subject().id());
173 processPortRemoved(event.port());
174 }
175
176 /**
Jian Li9d676fb2018-03-02 15:25:36 +0900177 * Processes port addition event.
178 * Once a port addition event is detected, it tries to create a host instance
179 * with openstack augmented host information such as networkId, portId,
180 * createTime, segmentId and notifies to host provider.
181 *
182 * @param port port object used in ONOS
183 */
Jian Li6a47fd02018-11-27 21:51:03 +0900184 void processPortAdded(Port port) {
Hyunsun Moon44aac662017-02-18 02:07:01 +0900185 // TODO check the node state is COMPLETE
186 org.openstack4j.model.network.Port osPort = osNetworkService.port(port);
187 if (osPort == null) {
188 log.warn(ERR_ADD_HOST + "OpenStack port for {} not found", port);
189 return;
190 }
191
192 Network osNet = osNetworkService.network(osPort.getNetworkId());
193 if (osNet == null) {
194 log.warn(ERR_ADD_HOST + "OpenStack network {} not found",
195 osPort.getNetworkId());
196 return;
197 }
198
199 if (osPort.getFixedIps().isEmpty()) {
200 log.warn(ERR_ADD_HOST + "no fixed IP for port {}", osPort.getId());
201 return;
202 }
203
Jian Liec5c32b2018-07-13 14:28:58 +0900204 MacAddress mac = MacAddress.valueOf(osPort.getMacAddress());
205 HostId hostId = HostId.hostId(mac);
206
Jian Li6a47fd02018-11-27 21:51:03 +0900207 /* typically one openstack port should only be bound to one fix IP address;
208 however, openstack4j binds multiple fixed IPs to one port, this might
209 be a defect of openstack4j implementation */
Jian Liec5c32b2018-07-13 14:28:58 +0900210
211 // TODO: we need to find a way to bind multiple ports from multiple
212 // openstack networks into one host sooner or later
Hyunsun Moon44aac662017-02-18 02:07:01 +0900213 Set<IpAddress> fixedIps = osPort.getFixedIps().stream()
Jian Li46b74002018-07-15 18:39:08 +0900214 .map(ip -> IpAddress.valueOf(ip.getIpAddress()))
215 .collect(Collectors.toSet());
Jian Liec5c32b2018-07-13 14:28:58 +0900216
217 // connect point is the combination of switch ID with port number where
218 // the host is attached to
Hyunsun Moon44aac662017-02-18 02:07:01 +0900219 ConnectPoint connectPoint = new ConnectPoint(port.element().id(), port.number());
Jian Li24ec59f2018-05-23 19:01:25 +0900220
Jian Liec5c32b2018-07-13 14:28:58 +0900221 long createTime = System.currentTimeMillis();
Jian Li24ec59f2018-05-23 19:01:25 +0900222
Jian Liee8214a2018-07-21 20:07:28 +0900223 // we check whether the host already attached to same locations
Jian Liec5c32b2018-07-13 14:28:58 +0900224 Host host = hostService.getHost(hostId);
Jian Li46b74002018-07-15 18:39:08 +0900225
226 // build host annotations to include a set of meta info from neutron
227 DefaultAnnotations.Builder annotations = DefaultAnnotations.builder()
228 .set(ANNOTATION_NETWORK_ID, osPort.getNetworkId())
229 .set(ANNOTATION_PORT_ID, osPort.getId())
230 .set(ANNOTATION_CREATE_TIME, String.valueOf(createTime));
231
Jian Liee8214a2018-07-21 20:07:28 +0900232 // FLAT typed network does not require segment ID
Jian Li46b74002018-07-15 18:39:08 +0900233 if (osNet.getNetworkType() != NetworkType.FLAT) {
234 annotations.set(ANNOTATION_SEGMENT_ID, osNet.getProviderSegID());
235 }
236
237 // build host description object
238 HostDescription hostDesc = new DefaultHostDescription(
239 mac,
240 VlanId.NONE,
241 new HostLocation(connectPoint, createTime),
242 fixedIps,
243 annotations.build());
244
Jian Liec5c32b2018-07-13 14:28:58 +0900245 if (host != null) {
246 Set<HostLocation> locations = host.locations().stream()
247 .filter(l -> l.deviceId().equals(connectPoint.deviceId()))
248 .filter(l -> l.port().equals(connectPoint.port()))
249 .collect(Collectors.toSet());
Jian Li46b74002018-07-15 18:39:08 +0900250
251 // newly added location is not in the existing location list,
252 // therefore, we simply add this into the location list
Jian Li6a47fd02018-11-27 21:51:03 +0900253 if (locations.isEmpty()) {
Jian Li07598ff2018-07-23 18:34:34 +0900254 hostProviderService.addLocationToHost(hostId,
Jian Li46b74002018-07-15 18:39:08 +0900255 new HostLocation(connectPoint, createTime));
256 }
257
258 // newly added location is in the existing location list,
259 // the hostDetected method invocation in turn triggers host Update event
260 if (locations.size() == 1) {
Jian Li07598ff2018-07-23 18:34:34 +0900261 hostProviderService.hostDetected(hostId, hostDesc, false);
Jian Li24ec59f2018-05-23 19:01:25 +0900262 }
Jian Liec5c32b2018-07-13 14:28:58 +0900263 } else {
Jian Li07598ff2018-07-23 18:34:34 +0900264 hostProviderService.hostDetected(hostId, hostDesc, false);
Jian Li24ec59f2018-05-23 19:01:25 +0900265 }
Hyunsun Moon44aac662017-02-18 02:07:01 +0900266 }
267
Jian Li9d676fb2018-03-02 15:25:36 +0900268 /**
269 * Processes port removal event.
270 * Once a port removal event is detected, it tries to look for a host
271 * instance through host provider by giving connect point information,
272 * and vanishes it.
273 *
Jian Li07598ff2018-07-23 18:34:34 +0900274 * @param port ONOS port
Jian Li9d676fb2018-03-02 15:25:36 +0900275 */
Jian Li6a47fd02018-11-27 21:51:03 +0900276 private void processPortRemoved(Port port) {
Hyunsun Moon44aac662017-02-18 02:07:01 +0900277 ConnectPoint connectPoint = new ConnectPoint(port.element().id(), port.number());
Jian Li24ec59f2018-05-23 19:01:25 +0900278
Jian Liec5c32b2018-07-13 14:28:58 +0900279 Set<Host> hosts = hostService.getConnectedHosts(connectPoint);
Jian Li24ec59f2018-05-23 19:01:25 +0900280
Jian Liec5c32b2018-07-13 14:28:58 +0900281 hosts.forEach(h -> {
282 Optional<HostLocation> hostLocation = h.locations().stream()
283 .filter(l -> l.deviceId().equals(port.element().id()))
284 .filter(l -> l.port().equals(port.number())).findAny();
Jian Li24ec59f2018-05-23 19:01:25 +0900285
Jian Liec5c32b2018-07-13 14:28:58 +0900286 // if the host contains only one filtered location, we remove the host
287 if (h.locations().size() == 1) {
Jian Li07598ff2018-07-23 18:34:34 +0900288 hostProviderService.hostVanished(h.id());
Jian Li24ec59f2018-05-23 19:01:25 +0900289 }
290
Jian Liec5c32b2018-07-13 14:28:58 +0900291 // if the host contains multiple locations, we simply remove the
292 // host location
293 if (h.locations().size() > 1 && hostLocation.isPresent()) {
Jian Li07598ff2018-07-23 18:34:34 +0900294 hostProviderService.removeLocationFromHost(h.id(), hostLocation.get());
Jian Liec5c32b2018-07-13 14:28:58 +0900295 }
296 });
Hyunsun Moon44aac662017-02-18 02:07:01 +0900297 }
298
Jian Li9d676fb2018-03-02 15:25:36 +0900299 /**
300 * An internal device listener which listens the port events generated from
301 * OVS integration bridge.
302 */
Hyunsun Moon44aac662017-02-18 02:07:01 +0900303 private class InternalDeviceListener implements DeviceListener {
304
305 @Override
306 public boolean isRelevant(DeviceEvent event) {
Hyunsun Moon44aac662017-02-18 02:07:01 +0900307 Port port = event.port();
308 if (port == null) {
309 return false;
310 }
Jian Li34220ea2018-11-14 01:30:24 +0900311
Hyunsun Moon44aac662017-02-18 02:07:01 +0900312 String portName = port.annotations().value(PORT_NAME);
Jian Li9d676fb2018-03-02 15:25:36 +0900313
314 return !Strings.isNullOrEmpty(portName) &&
Daniel Park7e8c4d82018-08-13 23:47:49 +0900315 (portName.startsWith(PORT_NAME_PREFIX_VM) ||
316 isDirectPort(portName) ||
317 portName.startsWith(PORT_NAME_VHOST_USER_PREFIX_VM));
Daniel Parkc4d06402018-05-28 15:57:37 +0900318 }
319
Jian Li34220ea2018-11-14 01:30:24 +0900320 private boolean isRelevantHelper(DeviceEvent event) {
321 return mastershipService.isLocalMaster(event.subject().id());
322 }
323
Daniel Parkc4d06402018-05-28 15:57:37 +0900324 private boolean isDirectPort(String portName) {
Jian Li07598ff2018-07-23 18:34:34 +0900325 return portNamePrefixMap().values().stream().anyMatch(portName::startsWith);
Hyunsun Moon44aac662017-02-18 02:07:01 +0900326 }
327
328 @Override
329 public void event(DeviceEvent event) {
Daniel Parkc4d06402018-05-28 15:57:37 +0900330 log.info("Device event occurred with type {}", event.type());
Hyunsun Moon44aac662017-02-18 02:07:01 +0900331 switch (event.type()) {
332 case PORT_UPDATED:
Jian Li6a47fd02018-11-27 21:51:03 +0900333 executor.execute(() -> processPortUpdate(event));
Hyunsun Moon44aac662017-02-18 02:07:01 +0900334 break;
335 case PORT_ADDED:
Jian Li6a47fd02018-11-27 21:51:03 +0900336 executor.execute(() -> processPortAddition(event));
Hyunsun Moon44aac662017-02-18 02:07:01 +0900337 break;
Hyunsun Moonb7a9cd22017-02-24 11:12:53 +0900338 case PORT_REMOVED:
Jian Li6a47fd02018-11-27 21:51:03 +0900339 executor.execute(() -> processPortRemoval(event));
Ray Milkeyd6a67c32018-02-02 10:30:35 -0800340 break;
Hyunsun Moon44aac662017-02-18 02:07:01 +0900341 default:
342 break;
343 }
344 }
Jian Li6a47fd02018-11-27 21:51:03 +0900345
346 private void processPortUpdate(DeviceEvent event) {
347 if (!isRelevantHelper(event)) {
348 return;
349 }
350
351 if (!event.port().isEnabled()) {
352 portRemovedHelper(event);
353 } else if (event.port().isEnabled()) {
354 portAddedHelper(event);
355 }
356 }
357
358 private void processPortAddition(DeviceEvent event) {
359 if (!isRelevantHelper(event)) {
360 return;
361 }
362
363 portAddedHelper(event);
364 }
365
366 private void processPortRemoval(DeviceEvent event) {
367 if (!isRelevantHelper(event)) {
368 return;
369 }
370
371 portRemovedHelper(event);
372 }
Hyunsun Moon44aac662017-02-18 02:07:01 +0900373 }
374
375 private class InternalOpenstackNodeListener implements OpenstackNodeListener {
376
377 @Override
Jian Li9d676fb2018-03-02 15:25:36 +0900378 public boolean isRelevant(OpenstackNodeEvent event) {
Jian Li34220ea2018-11-14 01:30:24 +0900379 return event.subject().type() != CONTROLLER;
380 }
Jian Li51b844c2018-05-31 10:59:03 +0900381
Jian Li34220ea2018-11-14 01:30:24 +0900382 private boolean isRelevantHelper(OpenstackNodeEvent event) {
Jian Li9d676fb2018-03-02 15:25:36 +0900383 // do not allow to proceed without mastership
384 Device device = deviceService.getDevice(event.subject().intgBridge());
Jian Li7ddea782018-03-30 11:17:42 +0900385 if (device == null) {
386 return false;
387 }
Jian Li9d676fb2018-03-02 15:25:36 +0900388 return mastershipService.isLocalMaster(device.id());
389 }
390
391 @Override
Hyunsun Moon44aac662017-02-18 02:07:01 +0900392 public void event(OpenstackNodeEvent event) {
393 OpenstackNode osNode = event.subject();
Hyunsun Moon44aac662017-02-18 02:07:01 +0900394
395 switch (event.type()) {
Hyunsun Moon0d457362017-06-27 17:19:41 +0900396 case OPENSTACK_NODE_COMPLETE:
Jian Li6a47fd02018-11-27 21:51:03 +0900397 executor.execute(() -> processCompleteNode(event, event.subject()));
Hyunsun Moon44aac662017-02-18 02:07:01 +0900398 break;
Hyunsun Moon0d457362017-06-27 17:19:41 +0900399 case OPENSTACK_NODE_INCOMPLETE:
Hyunsun Moon44aac662017-02-18 02:07:01 +0900400 log.warn("{} is changed to INCOMPLETE state", osNode);
401 break;
Hyunsun Moon0d457362017-06-27 17:19:41 +0900402 case OPENSTACK_NODE_CREATED:
403 case OPENSTACK_NODE_UPDATED:
404 case OPENSTACK_NODE_REMOVED:
Hyunsun Moon44aac662017-02-18 02:07:01 +0900405 default:
406 break;
407 }
408 }
409
Jian Li6a47fd02018-11-27 21:51:03 +0900410 private void processCompleteNode(OpenstackNodeEvent event,
411 OpenstackNode osNode) {
412
413 if (!isRelevantHelper(event)) {
414 return;
415 }
416
417 log.info("COMPLETE node {} is detected", osNode.hostname());
418
Hyunsun Moon0d457362017-06-27 17:19:41 +0900419 deviceService.getPorts(osNode.intgBridge()).stream()
Jian Li32b03622018-11-06 17:54:24 +0900420 .filter(port -> vnicType(port.annotations().value(PORT_NAME))
421 .equals(Constants.VnicType.NORMAL) ||
422 vnicType(port.annotations().value(PORT_NAME))
423 .equals(Constants.VnicType.DIRECT))
Daniel Park7e8c4d82018-08-13 23:47:49 +0900424 .filter(Port::isEnabled)
Hyunsun Moon44aac662017-02-18 02:07:01 +0900425 .forEach(port -> {
426 log.debug("Instance port {} is detected from {}",
Jian Li46b74002018-07-15 18:39:08 +0900427 port.annotations().value(PORT_NAME),
428 osNode.hostname());
Jian Li07598ff2018-07-23 18:34:34 +0900429 processPortAdded(port);
Hyunsun Moon44aac662017-02-18 02:07:01 +0900430 });
431
Hyunsun Moon44aac662017-02-18 02:07:01 +0900432 Tools.stream(hostService.getHosts())
433 .filter(host -> deviceService.getPort(
434 host.location().deviceId(),
435 host.location().port()) == null)
436 .forEach(host -> {
437 log.info("Remove stale host {}", host.id());
Jian Li07598ff2018-07-23 18:34:34 +0900438 hostProviderService.hostVanished(host.id());
Jian Li46b74002018-07-15 18:39:08 +0900439 });
Hyunsun Moon44aac662017-02-18 02:07:01 +0900440 }
441 }
442}