Add UT for SouthboundMapper and SouthboundProvider
[netvirt.git] / openstack / net-virt / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / impl / SecurityServicesImpl.java
1 /*
2  * Copyright (c) 2014, 2015 Red Hat, 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.ovsdb.openstack.netvirt.impl;
10
11 import java.util.ArrayList;
12 import java.util.List;
13
14 import org.opendaylight.neutron.spi.INeutronPortCRUD;
15 import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
16 import org.opendaylight.neutron.spi.NeutronPort;
17 import org.opendaylight.neutron.spi.NeutronSecurityGroup;
18 import org.opendaylight.neutron.spi.NeutronSubnet;
19 import org.opendaylight.neutron.spi.Neutron_IPs;
20 import org.opendaylight.ovsdb.openstack.netvirt.ConfigInterface;
21 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
22 import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
23 import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
24 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
26 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
27 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
28 import org.osgi.framework.BundleContext;
29 import org.osgi.framework.ServiceReference;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 public class SecurityServicesImpl implements ConfigInterface, SecurityServicesManager {
34     private static final Logger LOG = LoggerFactory.getLogger(TenantNetworkManagerImpl.class);
35     private volatile INeutronPortCRUD neutronPortCache;
36     private volatile INeutronSubnetCRUD neutronSubnetCache;
37     private volatile Southbound southbound;
38
39     @Override
40     public boolean isPortSecurityReady(OvsdbTerminationPointAugmentation terminationPointAugmentation) {
41         if (neutronPortCache == null) {
42             LOG.error("neutron port is null");
43             return false;
44         }
45         LOG.trace("isPortSecurityReady for {}", terminationPointAugmentation.getName());
46         String neutronPortId = southbound.getInterfaceExternalIdsValue(terminationPointAugmentation,
47                                                                        Constants.EXTERNAL_ID_INTERFACE_ID);
48         if (neutronPortId == null) {
49             return false;
50         }
51         NeutronPort neutronPort = neutronPortCache.getPort(neutronPortId);
52         if (neutronPort == null) {
53             return false;
54         }
55         String deviceOwner = neutronPort.getDeviceOwner();
56         if (!deviceOwner.contains("compute")) {
57             LOG.debug("Port {} is not a compute host, it is a: {}", neutronPortId, deviceOwner);
58         }
59         LOG.debug("isPortSecurityReady() is a {} ", deviceOwner);
60         List<NeutronSecurityGroup> securityGroups = neutronPort.getSecurityGroups();
61         if (securityGroups.isEmpty()) {
62             LOG.debug("Check for device: {} does not contain a Security Group for port: {}", deviceOwner,
63                       neutronPortId);
64             return false;
65         }
66         LOG.debug("Security Group Check {} does contain a Neutron Security Group", neutronPortId);
67         return true;
68     }
69
70     @Override
71     public List<NeutronSecurityGroup> getSecurityGroupInPortList(OvsdbTerminationPointAugmentation
72                                                              terminationPointAugmentation) {
73         List<NeutronSecurityGroup> neutronSecurityGroups = new ArrayList<NeutronSecurityGroup>();
74         if (neutronPortCache == null) {
75             LOG.error("neutron port is null");
76             return neutronSecurityGroups;
77         }
78         LOG.trace("isPortSecurityReady for {}", terminationPointAugmentation.getName());
79         String neutronPortId = southbound.getInterfaceExternalIdsValue(terminationPointAugmentation,
80                                                                        Constants.EXTERNAL_ID_INTERFACE_ID);
81         if (neutronPortId == null) {
82             return neutronSecurityGroups;
83         }
84         NeutronPort neutronPort = neutronPortCache.getPort(neutronPortId);
85         if (neutronPort == null) {
86             return neutronSecurityGroups;
87         }
88         neutronSecurityGroups = neutronPort.getSecurityGroups();
89         return neutronSecurityGroups;
90
91     }
92
93     @Override
94     public NeutronPort getDhcpServerPort(OvsdbTerminationPointAugmentation terminationPointAugmentation) {
95         if (neutronPortCache == null) {
96             LOG.error("getDHCPServerPort: neutron port is null");
97             return null;
98         }
99         LOG.trace("getDHCPServerPort for {}",
100                   terminationPointAugmentation.getName());
101         try {
102             String neutronPortId = southbound.getInterfaceExternalIdsValue(terminationPointAugmentation,
103                                                                            Constants.EXTERNAL_ID_INTERFACE_ID);
104             if (neutronPortId == null) {
105                 return null;
106             }
107             NeutronPort neutronPort = neutronPortCache.getPort(neutronPortId);
108             if (neutronPort == null) {
109                 LOG.error("getDHCPServerPort: neutron port of {} is not found", neutronPortId);
110                 return null;
111             }
112             /* if the current port is a DHCP port, return the same*/
113             if (neutronPort.getDeviceOwner().contains("dhcp")) {
114                 return neutronPort;
115             }
116             /*Since all the fixed ip assigned to a port should be
117              *from the same network, first port is sufficient.*/
118             List<Neutron_IPs> fixedIps = neutronPort.getFixedIPs();
119             if (null == fixedIps || 0 == fixedIps.size() ) {
120                 LOG.error("getDHCPServerPort: No fixed ip is assigned");
121                 return null;
122             }
123             /* Get all the ports in the subnet and identify the dhcp port*/
124             String subnetUuid = fixedIps.iterator().next().getSubnetUUID();
125             NeutronSubnet neutronSubnet = neutronSubnetCache.getSubnet(subnetUuid);
126             List<NeutronPort> ports = neutronSubnet.getPortsInSubnet();
127             for (NeutronPort port : ports) {
128                 if (port.getDeviceOwner().contains("dhcp")) {
129                     return port;
130                 }
131             }
132         } catch (Exception e) {
133             LOG.error("getDHCPServerPort:getDHCPServerPort failed due to ", e);
134             return null;
135         }
136
137         return null;
138
139     }
140
141     @Override
142     public boolean isComputePort(OvsdbTerminationPointAugmentation terminationPointAugmentation) {
143         if (neutronPortCache == null) {
144             LOG.error("neutron port is null");
145             return false;
146         }
147         LOG.trace("isComputePort for {}", terminationPointAugmentation.getName());
148         String neutronPortId = southbound.getInterfaceExternalIdsValue(terminationPointAugmentation,
149                                                                        Constants.EXTERNAL_ID_INTERFACE_ID);
150         if (neutronPortId == null) {
151             return false;
152         }
153         NeutronPort neutronPort = neutronPortCache.getPort(neutronPortId);
154         if (neutronPort == null) {
155             return false;
156         }
157         /*Check the device owner and if it contains compute to identify
158          * whether it is a compute port.*/
159         String deviceOwner = neutronPort.getDeviceOwner();
160         if (!deviceOwner.contains("compute")) {
161             LOG.debug("isComputePort : Port {} is not a DHCP server port for device owner {}",
162                       neutronPortId,deviceOwner);
163             return false;
164         }
165         return true;
166     }
167
168     @Override
169     public boolean isLastPortinSubnet(Node node, OvsdbTerminationPointAugmentation terminationPointAugmentation) {
170         if (neutronPortCache == null) {
171             LOG.error("isLastPortinSubnet: neutron port is null");
172             return false;
173         }
174         try {
175             LOG.trace("isLastPortinSubnet: for {}", terminationPointAugmentation.getName());
176             String neutronPortId = southbound.getInterfaceExternalIdsValue(terminationPointAugmentation,
177                                                                            Constants.EXTERNAL_ID_INTERFACE_ID);
178             if (neutronPortId == null) {
179                 return false;
180             }
181             NeutronPort neutronPort = neutronPortCache.getPort(neutronPortId);
182             if (neutronPort == null) {
183                 LOG.error("isLastPortinSubnet: neutron port of {} is not found", neutronPortId);
184                 return false;
185             }
186             List<Neutron_IPs> neutronPortFixedIp = neutronPort.getFixedIPs();
187             if (null == neutronPortFixedIp || neutronPortFixedIp.isEmpty()) {
188                 return false;
189             }
190             /*Get all the ports in the current node and check whether there
191              * is any port belonging to the same subnet of the input
192              */
193             List<TerminationPoint> terminationPoints = node.getTerminationPoint();
194             if (terminationPoints != null && !terminationPoints.isEmpty()) {
195                 for (TerminationPoint tp : terminationPoints) {
196                     OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
197                             tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
198                     if (ovsdbTerminationPointAugmentation != null && !ovsdbTerminationPointAugmentation
199                             .getName().equals(Constants.INTEGRATION_BRIDGE)) {
200                         String portId = southbound.getInterfaceExternalIdsValue(ovsdbTerminationPointAugmentation,
201                                                                                 Constants.EXTERNAL_ID_INTERFACE_ID);
202                         if (null != portId) {
203                             NeutronPort port = neutronPortCache.getPort(portId);
204                             if (null != port && !(port.getID().equals(neutronPort.getID()))
205                                     && port.getDeviceOwner().contains("compute")) {
206                                 List<Neutron_IPs> portFixedIp = port.getFixedIPs();
207                                 if (null == portFixedIp || portFixedIp.isEmpty()) {
208                                     return false;
209                                 }
210                                 if (portFixedIp.iterator().next().getSubnetUUID()
211                                         .equals(neutronPort.getFixedIPs().iterator().next().getSubnetUUID())) {
212                                     LOG.trace("isLastPortinSubnet: Port is not the only port.");
213                                     return false;
214                                 }
215                             }
216                         }
217                     }
218                 }
219             }
220         } catch (Exception e) {
221             LOG.error("isLastPortinSubnet: isLastPortinSubnet failed due to ", e);
222             return false;
223         }
224         return true;
225     }
226
227     @Override
228     public boolean isLastPortinBridge(Node node, OvsdbTerminationPointAugmentation terminationPointAugmentation) {
229         LOG.trace("isLastPortinBridge: for {}", terminationPointAugmentation.getName());
230         List<TerminationPoint> terminationPoints = node.getTerminationPoint();
231         /*Check whether the node has any port other than br-int*/
232         if (terminationPoints != null && !terminationPoints.isEmpty()) {
233             for (TerminationPoint tp : terminationPoints) {
234                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
235                         tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
236                 if (null != ovsdbTerminationPointAugmentation
237                         && !(ovsdbTerminationPointAugmentation.getName().equals(Constants.INTEGRATION_BRIDGE))
238                         && !(terminationPointAugmentation.getInterfaceUuid()
239                         .equals(ovsdbTerminationPointAugmentation.getInterfaceUuid()))) {
240                     LOG.debug("isLastPortinBridge: it the last port in bridge {}",
241                             terminationPointAugmentation.getName());
242                     return false;
243                 }
244             }
245         }
246         return true;
247     }
248
249     @Override
250     public List<Neutron_IPs> getIpAddressList(Node node,
251                                           OvsdbTerminationPointAugmentation terminationPointAugmentation) {
252         if (neutronPortCache == null) {
253             LOG.error("getIpAddress: neutron port is null");
254             return null;
255         }
256         LOG.trace("getIpAddress: for {}", terminationPointAugmentation.getName());
257         String neutronPortId = southbound.getInterfaceExternalIdsValue(terminationPointAugmentation,
258                                                                        Constants.EXTERNAL_ID_INTERFACE_ID);
259         if (neutronPortId == null) {
260             return null;
261         }
262         NeutronPort neutronPort = neutronPortCache.getPort(neutronPortId);
263         if (neutronPort == null) {
264             LOG.error("getIpAddress: neutron port of {} is not found", neutronPortId);
265             return null;
266         }
267         return neutronPort.getFixedIPs();
268     }
269
270     @Override
271     public List<Neutron_IPs> getVmListForSecurityGroup(List<Neutron_IPs> srcAddressList, String securityGroupUuid) {
272         List<Neutron_IPs> vmListForSecurityGroup = new ArrayList<Neutron_IPs>();
273         /*For every port check whether security grouplist contains the current
274          * security group.*/
275         try {
276             for (NeutronPort neutronPort:neutronPortCache.getAllPorts()) {
277                 if (!neutronPort.getDeviceOwner().contains("compute")) {
278                     LOG.debug("getVMListForSecurityGroup : the port {} is not "
279                             + "compute port belongs to {}", neutronPort.getID(), neutronPort.getDeviceOwner());
280                     continue;
281                 }
282                 List<NeutronSecurityGroup> securityGroups = neutronPort.getSecurityGroups();
283                 if (null != securityGroups) {
284                     for (NeutronSecurityGroup securityGroup:securityGroups) {
285                         if (securityGroup.getSecurityGroupUUID().equals(securityGroupUuid)
286                                 && !neutronPort.getFixedIPs().containsAll(srcAddressList)) {
287                             LOG.debug("getVMListForSecurityGroup : adding ports with ips {} "
288                                     + "compute port", neutronPort.getFixedIPs());
289                             vmListForSecurityGroup.addAll(neutronPort.getFixedIPs());
290                         }
291                     }
292                 }
293
294             }
295         } catch (Exception e) {
296             LOG.error("getVMListForSecurityGroup: getVMListForSecurityGroup"
297                     + " failed due to ", e);
298             return null;
299         }
300         return vmListForSecurityGroup;
301
302     }
303
304     @Override
305     public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
306         southbound =
307                 (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
308     }
309
310     @Override
311     public void setDependencies(Object impl) {
312         if (impl instanceof INeutronPortCRUD) {
313             neutronPortCache = (INeutronPortCRUD)impl;
314         } else if (impl instanceof INeutronSubnetCRUD) {
315             neutronSubnetCache = (INeutronSubnetCRUD) impl;
316         }
317     }
318 }