translator: remove dependency of neutron.spi
[netvirt.git] / openstack / net-virt / src / main / java / org / opendaylight / netvirt / openstack / netvirt / impl / SecurityGroupCacheManagerImpl.java
1 /*
2  * Copyright (c) 2014, 2015 HP, Inc. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.netvirt.openstack.netvirt.impl;
10
11 import org.opendaylight.netvirt.openstack.netvirt.api.SecurityServicesManager;
12 import org.opendaylight.netvirt.openstack.netvirt.translator.crud.INeutronPortCRUD;
13 import org.opendaylight.netvirt.openstack.netvirt.ConfigInterface;
14 import org.opendaylight.netvirt.openstack.netvirt.api.SecurityGroupCacheManger;
15 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronPort;
16 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronSecurityGroup;
17 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronSecurityRule;
18 import org.opendaylight.netvirt.openstack.netvirt.translator.Neutron_IPs;
19 import org.opendaylight.netvirt.openstack.netvirt.translator.crud.INeutronSecurityRuleCRUD;
20 import org.opendaylight.netvirt.utils.servicehelper.ServiceHelper;
21 import org.osgi.framework.ServiceReference;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 import java.util.ArrayList;
26 import java.util.HashSet;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.concurrent.ConcurrentHashMap;
32
33
34 /**
35  * @author Aswin Suryanarayanan.
36  */
37
38 public class SecurityGroupCacheManagerImpl implements ConfigInterface, SecurityGroupCacheManger {
39
40     private final Map<String, Set<String>> securityGroupCache = new ConcurrentHashMap<>();
41     private static final Logger LOG = LoggerFactory.getLogger(SecurityGroupCacheManagerImpl.class);
42     private volatile SecurityServicesManager securityServicesManager;
43     private volatile INeutronPortCRUD neutronPortCache;
44     private volatile NeutronL3Adapter neutronL3Adapter;
45     private volatile INeutronSecurityRuleCRUD neutronSecurityRule;
46
47     @Override
48     public void portAdded(String securityGroupUuid, String portUuid) {
49         LOG.debug("In portAdded securityGroupUuid:" + securityGroupUuid + " portUuid:" + portUuid);
50         NeutronPort port = neutronPortCache.getPort(portUuid);
51         if (port == null) {
52             port = neutronL3Adapter.getPortFromCleanupCache(portUuid);
53             if (port == null) {
54                 LOG.error("In portAdded no neutron port found:" + " portUuid:" + portUuid);
55                 return;
56             }
57         }
58         processPortAdded(securityGroupUuid,port);
59     }
60
61     @Override
62     public void portRemoved(String securityGroupUuid, String portUuid) {
63         LOG.debug("In portRemoved securityGroupUuid:" + securityGroupUuid + " portUuid:" + portUuid);
64         NeutronPort port = neutronPortCache.getPort(portUuid);
65
66         if (port == null) {
67             port = neutronL3Adapter.getPortFromCleanupCache(portUuid);
68             if (port == null) {
69                 LOG.error("In portRemoved no neutron port found:" + " portUuid:" + portUuid);
70                 return;
71             }
72         }
73         processPortRemoved(securityGroupUuid,port);
74     }
75
76     @Override
77     public void addToCache(String remoteSgUuid, String portUuid) {
78         LOG.debug("In addToCache remoteSgUuid:" + remoteSgUuid + "portUuid:" + portUuid);
79         Set<String> portList = securityGroupCache.get(remoteSgUuid);
80         if (null == portList) {
81             portList = new HashSet<>();
82             securityGroupCache.put(remoteSgUuid, portList);
83         }
84         portList.add(portUuid);
85     }
86
87     @Override
88     public void removeFromCache(String remoteSgUuid, String portUuid) {
89         LOG.debug("In removeFromCache remoteSgUuid:" + remoteSgUuid + " portUuid:" + portUuid);
90         Set<String> portList = securityGroupCache.get(remoteSgUuid);
91         if (null == portList) {
92             LOG.debug("The port list is empty for security group:" + remoteSgUuid);
93             return;
94         }
95         for (Iterator<String> iterator = portList.iterator(); iterator.hasNext();) {
96             String cachedPort = iterator.next();
97             if (cachedPort.equals(portUuid)) {
98                 iterator.remove();
99                 break;
100             }
101         }
102         if (portList.isEmpty()) {
103             securityGroupCache.remove(remoteSgUuid);
104         }
105     }
106
107     private void processPortAdded(String securityGroupUuid, NeutronPort port) {
108         /*
109          * Itreate through the cache maintained for the security group added. For each port in the cache
110          * add the rule to allow traffic to/from the new port added.
111          */
112         LOG.debug("In processPortAdded securityGroupUuid:" + securityGroupUuid + " NeutronPort:" + port);
113         Set<String> portList = this.securityGroupCache.get(securityGroupUuid);
114         if (null == portList) {
115             LOG.debug("The port list is empty for security group:" + securityGroupUuid);
116             return;
117         }
118         for (String cachedportUuid : portList) {
119             if (cachedportUuid.equals(port.getID())) {
120                 continue;
121             }
122             NeutronPort cachedport = neutronPortCache.getPort(cachedportUuid);
123             if (null == cachedport) {
124                 LOG.error("In processPortAdded cachedport port not found in neuton cache:"
125                             + " cachedportUuid:" + cachedportUuid);
126                 continue;
127             }
128             List<NeutronSecurityRule> remoteSecurityRules = retrieveSecurityRules(securityGroupUuid, cachedportUuid);
129             for (NeutronSecurityRule securityRule : remoteSecurityRules) {
130                 if (port.getFixedIPs() == null) {
131                     continue;
132                 }
133                 for (Neutron_IPs vmIp : port.getFixedIPs()) {
134                     securityServicesManager.syncSecurityRule(cachedport, securityRule, vmIp, true);
135                 }
136             }
137         }
138     }
139
140     private void processPortRemoved(String securityGroupUuid, NeutronPort port) {
141         /*
142          * Itreate through the cache maintained for the security group added. For each port in the cache remove
143          * the rule to allow traffic to/from the  port that got deleted.
144          */
145         LOG.debug("In processPortRemoved securityGroupUuid:" + securityGroupUuid + " port:" + port);
146         Set<String> portList = this.securityGroupCache.get(securityGroupUuid);
147         if (null == portList) {
148             LOG.debug("The port list is empty for security group:" + securityGroupUuid);
149             return;
150         }
151         for (String cachedportUuid : portList) {
152             if (cachedportUuid.equals(port.getID())) {
153                 continue;
154             }
155             NeutronPort cachedport = neutronPortCache.getPort(cachedportUuid);
156             if (cachedport == null) {
157                 cachedport = neutronL3Adapter.getPortFromCleanupCache(cachedportUuid);
158                 if (null == cachedport) {
159                     LOG.error("In processPortRemoved cachedport port not found in neuton cache:"
160                                 + " cachedportUuid:" + cachedportUuid);
161                     continue;
162                 }
163             }
164             List<NeutronSecurityRule> remoteSecurityRules = retrieveSecurityRules(securityGroupUuid, cachedportUuid);
165             for (NeutronSecurityRule securityRule : remoteSecurityRules) {
166                 if (port.getFixedIPs() == null) {
167                     continue;
168                 }
169                 for (Neutron_IPs vmIp : port.getFixedIPs()) {
170                     securityServicesManager.syncSecurityRule(cachedport, securityRule, vmIp, false);
171                 }
172             }
173         }
174     }
175
176     private List<NeutronSecurityRule> retrieveSecurityRules(String securityGroupUuid, String portUuid) {
177         /*
178          * Get the list of security rules in the port with portUuid that has securityGroupUuid as a remote
179          * security group.
180          */
181         LOG.debug("In retrieveSecurityRules securityGroupUuid:" + securityGroupUuid + " portUuid:" + portUuid);
182         NeutronPort port = neutronPortCache.getPort(portUuid);
183         if (port == null) {
184             port = neutronL3Adapter.getPortFromCleanupCache(portUuid);
185             if (null == port) {
186                 LOG.error("In retrieveSecurityRules no neutron port found:" + " portUuid:" + portUuid);
187                 return null;
188             }
189         }
190         List<NeutronSecurityRule> remoteSecurityRules = new ArrayList<>();
191         List<NeutronSecurityGroup> securityGroups = port.getSecurityGroups();
192         for (NeutronSecurityGroup securityGroup : securityGroups) {
193             List<NeutronSecurityRule> securityRules = getSecurityRulesforGroup(securityGroup);
194             for (NeutronSecurityRule securityRule : securityRules) {
195                 if (securityGroupUuid.equals(securityRule.getSecurityRemoteGroupID())) {
196                     remoteSecurityRules.add(securityRule);
197                 }
198             }
199         }
200         return remoteSecurityRules;
201     }
202
203     private void init() {
204         /*
205          * Rebuild the cache in case of a restart.
206          */
207         List<NeutronPort> portList = neutronPortCache.getAllPorts();
208         for (NeutronPort port:portList) {
209             List<NeutronSecurityGroup> securityGroupList = port.getSecurityGroups();
210             if ( null != securityGroupList) {
211                 for (NeutronSecurityGroup securityGroup : securityGroupList) {
212                     List<NeutronSecurityRule> securityRuleList = getSecurityRulesforGroup(securityGroup);
213                     if ( null != securityRuleList) {
214                         for (NeutronSecurityRule securityRule : securityRuleList) {
215                             if (null != securityRule.getSecurityRemoteGroupID()) {
216                                 this.addToCache(securityRule.getSecurityRemoteGroupID(), port.getID());
217                             }
218                         }
219                     }
220                 }
221             }
222         }
223     }
224
225     private List<NeutronSecurityRule> getSecurityRulesforGroup(NeutronSecurityGroup securityGroup) {
226         List<NeutronSecurityRule> securityRules = new ArrayList<>();
227         List<NeutronSecurityRule> rules = neutronSecurityRule.getAllNeutronSecurityRules();
228         for (NeutronSecurityRule securityRule : rules) {
229             if (securityGroup.getID().equals(securityRule.getSecurityRuleGroupID())) {
230                 securityRules.add(securityRule);
231             }
232         }
233         return securityRules;
234     }
235
236     @Override
237     public void setDependencies(ServiceReference serviceReference) {
238         neutronL3Adapter =
239                 (NeutronL3Adapter) ServiceHelper.getGlobalInstance(NeutronL3Adapter.class, this);
240         securityServicesManager =
241                 (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
242         neutronPortCache = (INeutronPortCRUD) ServiceHelper.getGlobalInstance(INeutronPortCRUD.class, this);
243         neutronSecurityRule = (INeutronSecurityRuleCRUD) ServiceHelper.getGlobalInstance(INeutronSecurityRuleCRUD.class, this);
244         init();
245     }
246
247     @Override
248     public void setDependencies(Object impl) {
249     }
250 }