blob: c41c6dc68b8821497e9591cb80d775edb328e43e [file] [log] [blame]
sangho6a9ff0d2017-03-27 11:23:37 +09001/*
2* Copyright 2017-present Open Networking Laboratory
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*/
16
17package org.onosproject.openstacknetworking.impl;
18
19import com.google.common.base.Strings;
20import org.apache.felix.scr.annotations.Activate;
21import org.apache.felix.scr.annotations.Component;
22import org.apache.felix.scr.annotations.Deactivate;
sangho0248ca22017-05-31 13:22:47 +090023import org.apache.felix.scr.annotations.Modified;
24import org.apache.felix.scr.annotations.Property;
sangho6a9ff0d2017-03-27 11:23:37 +090025import org.apache.felix.scr.annotations.Reference;
26import org.apache.felix.scr.annotations.ReferenceCardinality;
27import org.onlab.packet.Ethernet;
28import org.onlab.packet.IPv4;
29import org.onlab.packet.Ip4Address;
30import org.onlab.packet.Ip4Prefix;
31import org.onlab.packet.IpPrefix;
32import org.onlab.packet.TpPort;
sangho0248ca22017-05-31 13:22:47 +090033import org.onlab.util.Tools;
34import org.onosproject.cfg.ComponentConfigService;
sangho6a9ff0d2017-03-27 11:23:37 +090035import org.onosproject.core.ApplicationId;
36import org.onosproject.core.CoreService;
37import org.onosproject.mastership.MastershipService;
38import org.onosproject.net.flow.DefaultTrafficSelector;
39import org.onosproject.net.flow.DefaultTrafficTreatment;
40import org.onosproject.net.flow.TrafficSelector;
41import org.onosproject.net.flowobjective.DefaultForwardingObjective;
42import org.onosproject.net.flowobjective.FlowObjectiveService;
43import org.onosproject.net.flowobjective.ForwardingObjective;
44import org.onosproject.openstacknetworking.api.InstancePort;
45import org.onosproject.openstacknetworking.api.InstancePortEvent;
46import org.onosproject.openstacknetworking.api.InstancePortListener;
47import org.onosproject.openstacknetworking.api.InstancePortService;
48import org.onosproject.openstacknetworking.api.OpenstackNetworkEvent;
49import org.onosproject.openstacknetworking.api.OpenstackNetworkListener;
50import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
51import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupEvent;
52import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupListener;
53import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupService;
54import org.openstack4j.model.network.Port;
55import org.openstack4j.model.network.SecurityGroup;
56import org.openstack4j.model.network.SecurityGroupRule;
57import org.openstack4j.openstack.networking.domain.NeutronSecurityGroupRule;
sangho0248ca22017-05-31 13:22:47 +090058import org.osgi.service.component.ComponentContext;
sangho6a9ff0d2017-03-27 11:23:37 +090059import org.slf4j.Logger;
60
sangho6a9ff0d2017-03-27 11:23:37 +090061import java.util.Collections;
sangho0248ca22017-05-31 13:22:47 +090062import java.util.Dictionary;
sangho6a9ff0d2017-03-27 11:23:37 +090063import java.util.Objects;
64import java.util.Set;
65import java.util.concurrent.ExecutorService;
66import java.util.stream.Collectors;
67
68import static java.util.concurrent.Executors.newSingleThreadExecutor;
69import static org.onlab.util.Tools.groupedThreads;
70import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
71import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ACL_RULE;
72import static org.slf4j.LoggerFactory.getLogger;
73
74/**
75 * Populates flow rules to handle OpenStack SecurityGroups.
76 */
77@Component(immediate = true)
78public class OpenstackSecurityGroupHandler {
79
80 private final Logger log = getLogger(getClass());
81
sangho0248ca22017-05-31 13:22:47 +090082 private static final boolean USE_SECURITY_GROUP = false;
83
84 @Property(name = "useSecurityGroup", boolValue = USE_SECURITY_GROUP,
85 label = "Apply OpenStack security group rule for VM traffic")
86 private boolean useSecurityGroup = USE_SECURITY_GROUP;
87
sangho6a9ff0d2017-03-27 11:23:37 +090088 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
89 protected CoreService coreService;
90
91 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
92 protected InstancePortService instancePortService;
93
94 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
95 protected MastershipService mastershipService;
96
97 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Hyunsun Moonae51e732017-04-25 17:46:21 +090098 protected OpenstackNetworkService osNetService;
sangho6a9ff0d2017-03-27 11:23:37 +090099
100 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
101 protected OpenstackSecurityGroupService securityGroupService;
102
103 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
104 protected FlowObjectiveService flowObjectiveService;
105
sangho0248ca22017-05-31 13:22:47 +0900106 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
107 protected ComponentConfigService configService;
108
sangho6a9ff0d2017-03-27 11:23:37 +0900109 private final InstancePortListener instancePortListener = new InternalInstancePortListener();
110 private final OpenstackNetworkListener portListener = new InternalOpenstackPortListener();
111 private final OpenstackSecurityGroupListener securityGroupListener = new InternalSecurityGroupListener();
112 private ApplicationId appId;
113
114 private final ExecutorService eventExecutor = newSingleThreadExecutor(
115 groupedThreads(this.getClass().getSimpleName(), "event-handler"));
116
117 private static final String PROTO_ICMP = "ICMP";
118 private static final String PROTO_TCP = "TCP";
119 private static final String PROTO_UDP = "UDP";
120 private static final String ETHTYPE_IPV4 = "IPV4";
121 private static final String EGRESS = "EGRESS";
122 private static final String INGRESS = "INGRESS";
123 private static final IpPrefix IP_PREFIX_ANY = Ip4Prefix.valueOf("0.0.0.0/0");
124
125 @Activate
126 protected void activate() {
127 appId = coreService.registerApplication(OPENSTACK_NETWORKING_APP_ID);
128 instancePortService.addListener(instancePortListener);
129 securityGroupService.addListener(securityGroupListener);
Hyunsun Moonae51e732017-04-25 17:46:21 +0900130 osNetService.addListener(portListener);
sangho0248ca22017-05-31 13:22:47 +0900131 configService.registerProperties(getClass());
sangho6a9ff0d2017-03-27 11:23:37 +0900132
133 log.info("Started");
134 }
135
136 @Deactivate
137 protected void deactivate() {
138 instancePortService.removeListener(instancePortListener);
139 securityGroupService.removeListener(securityGroupListener);
Hyunsun Moonae51e732017-04-25 17:46:21 +0900140 osNetService.removeListener(portListener);
sangho0248ca22017-05-31 13:22:47 +0900141 configService.unregisterProperties(getClass(), false);
sangho6a9ff0d2017-03-27 11:23:37 +0900142 eventExecutor.shutdown();
143
144 log.info("Stopped");
145 }
146
sangho0248ca22017-05-31 13:22:47 +0900147 @Modified
148 protected void modified(ComponentContext context) {
149 Dictionary<?, ?> properties = context.getProperties();
150 Boolean flag;
151
152 flag = Tools.isPropertyEnabled(properties, "useSecurityGroup");
153 if (flag == null) {
154 log.info("useSecurityGroup is not configured, " +
155 "using current value of {}", useSecurityGroup);
156 } else {
157 useSecurityGroup = flag;
158 log.info("Configured. useSecurityGroup is {}",
159 useSecurityGroup ? "enabled" : "disabled");
160 }
161
162 resetSecurityGroupRules();
163 }
164
sangho6a9ff0d2017-03-27 11:23:37 +0900165 private void setSecurityGroupRules(InstancePort instPort, Port port, boolean install) {
166 port.getSecurityGroups().forEach(sgId -> {
sangho6a9ff0d2017-03-27 11:23:37 +0900167 SecurityGroup sg = securityGroupService.securityGroup(sgId);
168 if (sg == null) {
169 log.error("Security Group Not Found : {}", sgId);
170 return;
171 }
172 sg.getRules().forEach(sgRule -> updateSecurityGroupRule(instPort, port, sgRule, install));
Hyunsun Moonae51e732017-04-25 17:46:21 +0900173 final String action = install ? "Installed " : "Removed ";
174 log.debug(action + "security group rule ID : " + sgId);
sangho6a9ff0d2017-03-27 11:23:37 +0900175 });
176 }
177
178 private void updateSecurityGroupRule(InstancePort instPort, Port port, SecurityGroupRule sgRule, boolean install) {
179 if (sgRule.getRemoteGroupId() != null && !sgRule.getRemoteGroupId().isEmpty()) {
180 getRemoteInstPorts(port.getTenantId(), sgRule.getRemoteGroupId())
181 .forEach(rInstPort -> {
182 populateSecurityGroupRule(sgRule, instPort, rInstPort.ipAddress().toIpPrefix(), install);
183 populateSecurityGroupRule(sgRule, rInstPort, instPort.ipAddress().toIpPrefix(), install);
184
185 SecurityGroupRule rSgRule = new NeutronSecurityGroupRule.SecurityGroupRuleConcreteBuilder()
186 .from(sgRule)
187 .direction(sgRule.getDirection().toUpperCase().equals(EGRESS) ? INGRESS : EGRESS).build();
188 populateSecurityGroupRule(rSgRule, instPort, rInstPort.ipAddress().toIpPrefix(), install);
189 populateSecurityGroupRule(rSgRule, rInstPort, instPort.ipAddress().toIpPrefix(), install);
190 });
191 } else {
192 populateSecurityGroupRule(sgRule, instPort, sgRule.getRemoteIpPrefix() == null ? IP_PREFIX_ANY :
193 IpPrefix.valueOf(sgRule.getRemoteIpPrefix()), install);
194 }
195 }
196
197 private void populateSecurityGroupRule(SecurityGroupRule sgRule, InstancePort instPort,
198 IpPrefix remoteIp, boolean install) {
199 ForwardingObjective.Builder foBuilder = buildFlowObjective(sgRule,
200 Ip4Address.valueOf(instPort.ipAddress().toInetAddress()), remoteIp);
201 if (foBuilder == null) {
202 return;
203 }
204
205 if (install) {
206 flowObjectiveService.forward(instPort.deviceId(), foBuilder.add());
207 } else {
208 flowObjectiveService.forward(instPort.deviceId(), foBuilder.remove());
209 }
210 }
211
212 /**
213 * Returns a set of host IP addresses engaged with supplied security group ID.
214 * It only searches a VM in the same tenant boundary.
215 *
216 * @param tenantId tenant id
217 * @param sgId security group id
218 * @return set of ip addresses
219 */
220 private Set<InstancePort> getRemoteInstPorts(String tenantId, String sgId) {
221 Set<InstancePort> remoteInstPorts;
222
Hyunsun Moonae51e732017-04-25 17:46:21 +0900223 remoteInstPorts = osNetService.ports().stream()
sangho6a9ff0d2017-03-27 11:23:37 +0900224 .filter(port -> port.getTenantId().equals(tenantId))
225 .filter(port -> port.getSecurityGroups().contains(sgId))
226 .map(port -> instancePortService.instancePort(port.getId()))
227 .filter(instPort -> instPort != null && instPort.ipAddress() != null)
228 .collect(Collectors.toSet());
229
230 return Collections.unmodifiableSet(remoteInstPorts);
231 }
232
233 private ForwardingObjective.Builder buildFlowObjective(SecurityGroupRule sgRule,
234 Ip4Address vmIp,
235 IpPrefix remoteIp) {
236 if (remoteIp != null && remoteIp.equals(IpPrefix.valueOf(vmIp, 32))) {
237 // do nothing if the remote IP is my IP
238 return null;
239 }
240
241 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
242 buildMatchs(sBuilder, sgRule, vmIp, remoteIp);
243
244 return DefaultForwardingObjective.builder()
245 .withSelector(sBuilder.build())
246 .withTreatment(DefaultTrafficTreatment.builder().build())
247 .withPriority(PRIORITY_ACL_RULE)
248 .withFlag(ForwardingObjective.Flag.SPECIFIC)
249 .fromApp(appId);
250 }
251
252 private void buildMatchs(TrafficSelector.Builder sBuilder, SecurityGroupRule sgRule,
253 Ip4Address vmIp, IpPrefix remoteIp) {
254 buildMatchEthType(sBuilder, sgRule.getEtherType());
255 buildMatchDirection(sBuilder, sgRule.getDirection(), vmIp);
256 buildMatchProto(sBuilder, sgRule.getProtocol());
257 buildMatchPort(sBuilder, sgRule.getProtocol(), sgRule.getDirection(),
258 sgRule.getPortRangeMax() == null ? 0 : sgRule.getPortRangeMax(),
259 sgRule.getPortRangeMin() == null ? 0 : sgRule.getPortRangeMin());
260 buildMatchRemoteIp(sBuilder, remoteIp, sgRule.getDirection());
261 if (sgRule.getRemoteGroupId() != null && sgRule.getRemoteGroupId().isEmpty()) {
262 buildMatchRemoteIp(sBuilder, remoteIp, sgRule.getDirection());
263 }
264 }
265
266 private void buildMatchDirection(TrafficSelector.Builder sBuilder,
267 String direction,
268 Ip4Address vmIp) {
269 if (direction.toUpperCase().equals(EGRESS)) {
270 sBuilder.matchIPSrc(IpPrefix.valueOf(vmIp, 32));
271 } else {
272 sBuilder.matchIPDst(IpPrefix.valueOf(vmIp, 32));
273 }
274 }
275
276 private void buildMatchEthType(TrafficSelector.Builder sBuilder, String etherType) {
277 // Either IpSrc or IpDst (or both) is set by default, and we need to set EthType as IPv4.
278 sBuilder.matchEthType(Ethernet.TYPE_IPV4);
279 if (etherType != null && !Objects.equals(etherType, "null") &&
280 !etherType.toUpperCase().equals(ETHTYPE_IPV4)) {
281 log.debug("EthType {} is not supported yet in Security Group", etherType);
282 }
283 }
284
285 private void buildMatchRemoteIp(TrafficSelector.Builder sBuilder, IpPrefix remoteIpPrefix, String direction) {
286 if (remoteIpPrefix != null && !remoteIpPrefix.getIp4Prefix().equals(IP_PREFIX_ANY)) {
287 if (direction.toUpperCase().equals(EGRESS)) {
288 sBuilder.matchIPDst(remoteIpPrefix);
289 } else {
290 sBuilder.matchIPSrc(remoteIpPrefix);
291 }
292 }
293 }
294
295 private void buildMatchProto(TrafficSelector.Builder sBuilder, String protocol) {
296 if (protocol != null) {
297 switch (protocol.toUpperCase()) {
298 case PROTO_ICMP:
299 sBuilder.matchIPProtocol(IPv4.PROTOCOL_ICMP);
300 break;
301 case PROTO_TCP:
302 sBuilder.matchIPProtocol(IPv4.PROTOCOL_TCP);
303 break;
304 case PROTO_UDP:
305 sBuilder.matchIPProtocol(IPv4.PROTOCOL_UDP);
306 break;
307 default:
308 }
309 }
310 }
311
312 private void buildMatchPort(TrafficSelector.Builder sBuilder, String protocol, String direction,
313 int portMin, int portMax) {
314 if (portMin > 0 && portMax > 0 && portMin == portMax) {
315 if (protocol.toUpperCase().equals(PROTO_TCP)) {
316 if (direction.toUpperCase().equals(EGRESS)) {
317 sBuilder.matchTcpSrc(TpPort.tpPort(portMax));
318 } else {
319 sBuilder.matchTcpDst(TpPort.tpPort(portMax));
320 }
321 } else if (protocol.toUpperCase().equals(PROTO_UDP)) {
322 if (direction.toUpperCase().equals(EGRESS)) {
323 sBuilder.matchUdpSrc(TpPort.tpPort(portMax));
324 } else {
325 sBuilder.matchUdpDst(TpPort.tpPort(portMax));
326 }
327 }
328 }
329 }
330
sangho0248ca22017-05-31 13:22:47 +0900331 private void resetSecurityGroupRules() {
332
333 if (useSecurityGroup) {
334 securityGroupService.securityGroups().forEach(securityGroup ->
335 securityGroup.getRules().forEach(this::securityGroupRuleAdded));
336 } else {
337 securityGroupService.securityGroups().forEach(securityGroup ->
338 securityGroup.getRules().forEach(this::securityGroupRuleRemoved));
339 }
340
341 log.info("Reset security group info " + (useSecurityGroup ? " with " : " without") + " Security Group");
342 }
343
344 private void securityGroupRuleAdded(SecurityGroupRule sgRule) {
345 osNetService.ports().stream()
346 .filter(port -> port.getSecurityGroups().contains(sgRule.getSecurityGroupId()))
347 .forEach(port -> {
348 updateSecurityGroupRule(
349 instancePortService.instancePort(port.getId()),
350 port, sgRule, true);
351 log.debug("Applied security group rule {} to port {}",
352 sgRule.getId(), port.getId());
353 });
354 }
355
356 private void securityGroupRuleRemoved(SecurityGroupRule sgRule) {
357 osNetService.ports().stream()
358 .filter(port -> port.getSecurityGroups().contains(sgRule.getSecurityGroupId()))
359 .forEach(port -> {
360 updateSecurityGroupRule(
361 instancePortService.instancePort(port.getId()),
362 port, sgRule, false);
363 log.debug("Removed security group rule {} from port {}",
364 sgRule.getId(), port.getId());
365 });
366 }
367
sangho6a9ff0d2017-03-27 11:23:37 +0900368 private class InternalInstancePortListener implements InstancePortListener {
369
370 @Override
371 public boolean isRelevant(InstancePortEvent event) {
372 InstancePort instPort = event.subject();
sangho0248ca22017-05-31 13:22:47 +0900373 if (!useSecurityGroup) {
374 return false;
375 }
sangho6a9ff0d2017-03-27 11:23:37 +0900376 return mastershipService.isLocalMaster(instPort.deviceId());
377 }
378
379 @Override
380 public void event(InstancePortEvent event) {
381 InstancePort instPort = event.subject();
382 switch (event.type()) {
383 case OPENSTACK_INSTANCE_PORT_UPDATED:
384 case OPENSTACK_INSTANCE_PORT_DETECTED:
Hyunsun Moonae51e732017-04-25 17:46:21 +0900385 log.debug("Instance port detected MAC:{} IP:{}",
386 instPort.macAddress(),
387 instPort.ipAddress());
sangho6a9ff0d2017-03-27 11:23:37 +0900388 eventExecutor.execute(() -> {
Hyunsun Moonae51e732017-04-25 17:46:21 +0900389 setSecurityGroupRules(instPort,
390 osNetService.port(event.subject().portId()),
391 true);
sangho6a9ff0d2017-03-27 11:23:37 +0900392 });
393 break;
394 case OPENSTACK_INSTANCE_PORT_VANISHED:
Hyunsun Moonae51e732017-04-25 17:46:21 +0900395 log.debug("Instance port vanished MAC:{} IP:{}",
396 instPort.macAddress(),
397 instPort.ipAddress());
sangho6a9ff0d2017-03-27 11:23:37 +0900398 eventExecutor.execute(() -> {
Hyunsun Moonae51e732017-04-25 17:46:21 +0900399 setSecurityGroupRules(instPort,
400 osNetService.port(event.subject().portId()),
401 false);
sangho6a9ff0d2017-03-27 11:23:37 +0900402 });
403 break;
404 default:
405 break;
406 }
407 }
sangho6a9ff0d2017-03-27 11:23:37 +0900408 }
409
410 private class InternalOpenstackPortListener implements OpenstackNetworkListener {
411
412 @Override
413 public boolean isRelevant(OpenstackNetworkEvent event) {
Hyunsun Moonae51e732017-04-25 17:46:21 +0900414 if (event.port() == null || !Strings.isNullOrEmpty(event.port().getId())) {
sangho6a9ff0d2017-03-27 11:23:37 +0900415 return false;
416 }
Hyunsun Moonae51e732017-04-25 17:46:21 +0900417 if (event.securityGroupId() == null ||
418 securityGroupService.securityGroup(event.securityGroupId()) == null) {
419 return false;
420 }
421 if (instancePortService.instancePort(event.port().getId()) == null) {
422 return false;
423 }
sangho0248ca22017-05-31 13:22:47 +0900424 if (!useSecurityGroup) {
425 return false;
426 }
Hyunsun Moonae51e732017-04-25 17:46:21 +0900427 return true;
sangho6a9ff0d2017-03-27 11:23:37 +0900428 }
429
430 @Override
431 public void event(OpenstackNetworkEvent event) {
Hyunsun Moonae51e732017-04-25 17:46:21 +0900432 Port osPort = event.port();
433 InstancePort instPort = instancePortService.instancePort(osPort.getId());
434 SecurityGroup osSg = securityGroupService.securityGroup(event.securityGroupId());
435
sangho6a9ff0d2017-03-27 11:23:37 +0900436 switch (event.type()) {
Hyunsun Moonae51e732017-04-25 17:46:21 +0900437 case OPENSTACK_PORT_SECURITY_GROUP_ADDED:
438 eventExecutor.execute(() -> {
439 osSg.getRules().forEach(sgRule -> {
440 updateSecurityGroupRule(instPort, osPort, sgRule, true);
441 });
442 log.info("Added security group {} to port {}",
443 event.securityGroupId(), event.port().getId());
444 });
sangho6a9ff0d2017-03-27 11:23:37 +0900445 break;
Hyunsun Moonae51e732017-04-25 17:46:21 +0900446 case OPENSTACK_PORT_SECURITY_GROUP_REMOVED:
447 eventExecutor.execute(() -> {
448 osSg.getRules().forEach(sgRule -> {
449 updateSecurityGroupRule(instPort, osPort, sgRule, false);
450 });
451 log.info("Removed security group {} from port {}",
452 event.securityGroupId(), event.port().getId());
453 });
sangho6a9ff0d2017-03-27 11:23:37 +0900454 break;
455 default:
Hyunsun Moonae51e732017-04-25 17:46:21 +0900456 // do nothing for the other events
sangho6a9ff0d2017-03-27 11:23:37 +0900457 break;
458 }
459 }
sangho6a9ff0d2017-03-27 11:23:37 +0900460 }
461
462 private class InternalSecurityGroupListener implements OpenstackSecurityGroupListener {
463
464 @Override
sangho0248ca22017-05-31 13:22:47 +0900465 public boolean isRelevant(OpenstackSecurityGroupEvent event) {
466 if (!useSecurityGroup) {
467 return false;
468 }
469 return true;
470 }
471
472 @Override
sangho6a9ff0d2017-03-27 11:23:37 +0900473 public void event(OpenstackSecurityGroupEvent event) {
474 switch (event.type()) {
sangho6a9ff0d2017-03-27 11:23:37 +0900475 case OPENSTACK_SECURITY_GROUP_RULE_CREATED:
476 SecurityGroupRule securityGroupRuleToAdd = event.securityGroupRule();
477 eventExecutor.execute(() -> {
sangho6a9ff0d2017-03-27 11:23:37 +0900478 securityGroupRuleAdded(securityGroupRuleToAdd);
Hyunsun Moonae51e732017-04-25 17:46:21 +0900479 log.info("Applied new security group rule {} to ports",
480 securityGroupRuleToAdd.getId());
sangho6a9ff0d2017-03-27 11:23:37 +0900481 });
482 break;
483
484 case OPENSTACK_SECURITY_GROUP_RULE_REMOVED:
485 SecurityGroupRule securityGroupRuleToRemove = event.securityGroupRule();
486 eventExecutor.execute(() -> {
sangho6a9ff0d2017-03-27 11:23:37 +0900487 securityGroupRuleRemoved(securityGroupRuleToRemove);
Hyunsun Moonae51e732017-04-25 17:46:21 +0900488 log.info("Removed security group rule {} from ports",
489 securityGroupRuleToRemove.getId());
sangho6a9ff0d2017-03-27 11:23:37 +0900490 });
491 break;
Hyunsun Moonae51e732017-04-25 17:46:21 +0900492 case OPENSTACK_SECURITY_GROUP_CREATED:
493 case OPENSTACK_SECURITY_GROUP_REMOVED:
sangho6a9ff0d2017-03-27 11:23:37 +0900494 default:
Hyunsun Moonae51e732017-04-25 17:46:21 +0900495 // do nothing
496 break;
sangho6a9ff0d2017-03-27 11:23:37 +0900497 }
498 }
sangho6a9ff0d2017-03-27 11:23:37 +0900499 }
500}