2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping;
10 import static com.google.common.base.Preconditions.checkNotNull;
12 import java.util.ArrayList;
13 import java.util.List;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.DataStoreHelper;
19 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.IidFactory;
20 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
21 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
22 import org.opendaylight.neutron.spi.INeutronSecurityGroupAware;
23 import org.opendaylight.neutron.spi.NeutronSecurityGroup;
24 import org.opendaylight.neutron.spi.NeutronSecurityRule;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroupBuilder;
32 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
36 import com.google.common.base.Optional;
37 import com.google.common.base.Preconditions;
38 import com.google.common.base.Strings;
39 import com.google.common.collect.ArrayListMultimap;
40 import com.google.common.collect.ImmutableList;
41 import com.google.common.collect.ImmutableListMultimap;
42 import com.google.common.collect.ListMultimap;
44 public class NeutronSecurityGroupAware implements INeutronSecurityGroupAware {
46 private static final Logger LOG = LoggerFactory.getLogger(NeutronSecurityGroupAware.class);
47 private final DataBroker dataProvider;
49 public NeutronSecurityGroupAware(DataBroker dataProvider) {
50 this.dataProvider = checkNotNull(dataProvider);
54 * @see org.opendaylight.neutron.spi.INeutronSecurityGroupAware#canCreateNeutronSecurityGroup(org.opendaylight.neutron.spi.NeutronSecurityGroup)
57 public int canCreateNeutronSecurityGroup(NeutronSecurityGroup securityGroup) {
58 LOG.trace("canCreateNeutronSecurityGroup - {}", securityGroup);
59 // nothing to consider
64 * @see org.opendaylight.neutron.spi.INeutronSecurityGroupAware#neutronSecurityGroupCreated(org.opendaylight.neutron.spi.NeutronSecurityGroup)
67 public void neutronSecurityGroupCreated(NeutronSecurityGroup secGroup) {
68 LOG.trace("neutronSecurityGroupCreated - {}", secGroup);
69 ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
70 boolean isSecGroupCreated = addNeutronSecurityGroup(secGroup, rwTx);
71 if (isSecGroupCreated) {
72 DataStoreHelper.submitToDs(rwTx);
78 public static boolean addNeutronSecurityGroup(NeutronSecurityGroup secGroup, ReadWriteTransaction rwTx) {
79 TenantId tenantId = new TenantId(Utils.normalizeUuid(secGroup.getSecurityGroupTenantID()));
80 EndpointGroupId providerEpgId = new EndpointGroupId(secGroup.getSecurityGroupUUID());
81 EndpointGroupBuilder providerEpgBuilder = new EndpointGroupBuilder().setId(providerEpgId);
82 providerEpgBuilder.setName(new Name(MappingUtils.NEUTRON_GROUP__ + Strings.nullToEmpty(secGroup.getSecurityGroupName())));
83 providerEpgBuilder.setDescription(new Description(MappingUtils.NEUTRON_GROUP__
84 + Strings.nullToEmpty(secGroup.getSecurityGroupDescription())));
85 rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.endpointGroupIid(tenantId, providerEpgId),
86 providerEpgBuilder.build(), true);
87 List<NeutronSecurityRule> secRules = secGroup.getSecurityRules();
88 SortedSecurityGroupRules sortedSecGrpRules = new SortedSecurityGroupRules(secRules);
89 ListMultimap<EndpointGroupId, NeutronSecurityRule> secRuleByRemoteSecGrpId = sortedSecGrpRules.secRuleByRemoteSecGrpId;
90 for (EndpointGroupId consumerEpgId : secRuleByRemoteSecGrpId.keySet()) {
91 addEpgIfMissing(tenantId, consumerEpgId, rwTx);
92 boolean areSecRulesAdded = addNeutronSecurityRule(secRuleByRemoteSecGrpId.get(consumerEpgId), rwTx);
93 if (!areSecRulesAdded) {
97 ListMultimap<IpPrefix, NeutronSecurityRule> secRuleByRemoteIpPrefix = sortedSecGrpRules.secRuleByRemoteIpPrefix;
98 for (IpPrefix remoteIpPrefex : secRuleByRemoteIpPrefix.keySet()) {
99 boolean areSecRulesAdded = addNeutronSecurityRule(secRuleByRemoteIpPrefix.get(remoteIpPrefex), rwTx);
100 if (!areSecRulesAdded) {
104 boolean areSecRulesAdded = addNeutronSecurityRule(sortedSecGrpRules.secRulesWithoutRemote, rwTx);
105 if (!areSecRulesAdded) {
111 public static void addEpgIfMissing(TenantId tenantId, EndpointGroupId epgId, ReadWriteTransaction rwTx) {
112 InstanceIdentifier<EndpointGroup> epgIid = IidFactory.endpointGroupIid(tenantId, epgId);
113 Optional<EndpointGroup> potentialConsumerEpg = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
115 if (!potentialConsumerEpg.isPresent()) {
116 EndpointGroup epg = new EndpointGroupBuilder().setId(epgId)
117 .setName(new Name(MappingUtils.NEUTRON_GROUP__))
118 .setDescription(new Description(MappingUtils.NEUTRON_GROUP__ + "EPG was created just based on remote group ID from a security rule."))
120 rwTx.put(LogicalDatastoreType.CONFIGURATION, epgIid, epg);
124 private static boolean addNeutronSecurityRule(List<NeutronSecurityRule> secRules, ReadWriteTransaction rwTx) {
125 for (NeutronSecurityRule secRule : secRules) {
126 boolean isSecRuleAdded = NeutronSecurityRuleAware.addNeutronSecurityRule(secRule, rwTx);
127 if (!isSecRuleAdded) {
135 * @see org.opendaylight.neutron.spi.INeutronSecurityGroupAware#canUpdateNeutronSecurityGroup(org.opendaylight.neutron.spi.NeutronSecurityGroup,
136 * org.opendaylight.neutron.spi.NeutronSecurityGroup)
139 public int canUpdateNeutronSecurityGroup(NeutronSecurityGroup delta, NeutronSecurityGroup original) {
140 LOG.warn("canUpdateNeutronSecurityGroup - Never should be called "
141 + "- neutron API does not allow UPDATE on neutron security group. \nDelta: {} \nOriginal: {}", delta,
143 return StatusCode.BAD_REQUEST;
147 * @see org.opendaylight.neutron.spi.INeutronSecurityGroupAware#neutronSecurityGroupUpdated(org.opendaylight.neutron.spi.NeutronSecurityGroup)
150 public void neutronSecurityGroupUpdated(NeutronSecurityGroup securityGroup) {
151 LOG.warn("neutronSecurityGroupUpdated - Never should be called "
152 + "- neutron API does not allow UPDATE on neutron security group. \nSecurity group: {}", securityGroup);
156 * @see org.opendaylight.neutron.spi.INeutronSecurityGroupAware#canDeleteNeutronSecurityGroup(org.opendaylight.neutron.spi.NeutronSecurityGroup)
159 public int canDeleteNeutronSecurityGroup(NeutronSecurityGroup securityGroup) {
160 LOG.trace("canDeleteNeutronSecurityGroup - {}", securityGroup);
161 // nothing to consider
162 return StatusCode.OK;
166 * @see org.opendaylight.neutron.spi.INeutronSecurityGroupAware#neutronSecurityGroupDeleted(org.opendaylight.neutron.spi.NeutronSecurityGroup)
169 public void neutronSecurityGroupDeleted(NeutronSecurityGroup secGroup) {
170 LOG.trace("neutronSecurityGroupDeleted - {}", secGroup);
171 ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
172 List<NeutronSecurityRule> secRules = secGroup.getSecurityRules();
173 if (secRules != null) {
174 boolean areSecRulesAdded = deleteNeutronSecurityRules(secRules, rwTx);
175 if (!areSecRulesAdded) {
180 TenantId tenantId = new TenantId(Utils.normalizeUuid(secGroup.getSecurityGroupTenantID()));
181 EndpointGroupId epgId = new EndpointGroupId(secGroup.getSecurityGroupUUID());
182 Optional<EndpointGroup> potentialEpg = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
183 IidFactory.endpointGroupIid(tenantId, epgId), rwTx);
184 if (!potentialEpg.isPresent()) {
185 LOG.warn("Illegal state - Endpoint group {} does not exist.", epgId.getValue());
190 DataStoreHelper.submitToDs(rwTx);
193 private boolean deleteNeutronSecurityRules(List<NeutronSecurityRule> secRules, ReadWriteTransaction rwTx) {
194 for (NeutronSecurityRule secRule : secRules) {
195 boolean isSecRuleDeleted = NeutronSecurityRuleAware.deleteNeutronSecurityRule(secRule, rwTx);
196 if (!isSecRuleDeleted) {
203 private static final class SortedSecurityGroupRules {
205 private final ListMultimap<EndpointGroupId, NeutronSecurityRule> secRuleByRemoteSecGrpId;
206 private final ListMultimap<IpPrefix, NeutronSecurityRule> secRuleByRemoteIpPrefix;
207 private final List<NeutronSecurityRule> secRulesWithoutRemote;
209 private SortedSecurityGroupRules(List<NeutronSecurityRule> securityRules) {
210 Preconditions.checkNotNull(securityRules);
211 ListMultimap<EndpointGroupId, NeutronSecurityRule> tmpSecRuleByRemoteSecGrpId = ArrayListMultimap.create();
212 ListMultimap<IpPrefix, NeutronSecurityRule> tmpSecRuleByRemoteIpPrefix = ArrayListMultimap.create();
213 List<NeutronSecurityRule> tmpSecRulesWithoutRemote = new ArrayList<>();
214 for (NeutronSecurityRule securityRule : securityRules) {
215 String remoteSecGroupId = securityRule.getSecurityRemoteGroupID();
216 String remoteIpPrefix = securityRule.getSecurityRuleRemoteIpPrefix();
217 boolean isRemoteSecGroupId = remoteSecGroupId != null && !"null".equals(remoteSecGroupId);
218 boolean isRemoteIpPrefix = remoteIpPrefix != null && !"null".equals(remoteIpPrefix);
219 if (isRemoteSecGroupId && isRemoteIpPrefix) {
220 throw new IllegalArgumentException("Either remote group id or ip prefix "
221 + "must be speciefied in neutron security group rule." + securityRule.toString());
223 if (isRemoteSecGroupId) {
224 tmpSecRuleByRemoteSecGrpId.put(new EndpointGroupId(remoteSecGroupId), securityRule);
225 } else if (isRemoteIpPrefix) {
226 tmpSecRuleByRemoteIpPrefix.put(Utils.createIpPrefix(remoteIpPrefix), securityRule);
228 tmpSecRulesWithoutRemote.add(securityRule);
231 secRuleByRemoteSecGrpId = ImmutableListMultimap.copyOf(tmpSecRuleByRemoteSecGrpId);
232 secRuleByRemoteIpPrefix = ImmutableListMultimap.copyOf(tmpSecRuleByRemoteIpPrefix);
233 secRulesWithoutRemote = ImmutableList.copyOf(tmpSecRulesWithoutRemote);