BaseEndpointService baseEpService) {
EndpointRegistrator epRegistrator = new EndpointRegistrator(epService, baseEpService);
networkAware = new NeutronNetworkAware(dataProvider);
- securityGroupAware = new NeutronSecurityGroupAware(dataProvider);
securityRuleAware = new NeutronSecurityRuleAware(dataProvider);
+ securityGroupAware = new NeutronSecurityGroupAware(dataProvider, securityRuleAware);
subnetAware = new NeutronSubnetAware(dataProvider, epRegistrator);
portAware = new NeutronPortAware(dataProvider, epRegistrator);
routerAware = new NeutronRouterAware(dataProvider, epRegistrator);
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule.NeutronSecurityRuleAware;
import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
import org.opendaylight.groupbasedpolicy.util.IidFactory;
public static final InstanceIdentifier<SecurityGroup> SECURITY_GROUP_WILDCARD_IID =
InstanceIdentifier.builder(Neutron.class).child(SecurityGroups.class).child(SecurityGroup.class).build();
private final DataBroker dataProvider;
+ private final NeutronSecurityRuleAware ruleAware;
- public NeutronSecurityGroupAware(DataBroker dataProvider) {
+ public NeutronSecurityGroupAware(DataBroker dataProvider, NeutronSecurityRuleAware ruleAware) {
this.dataProvider = checkNotNull(dataProvider);
+ this.ruleAware = checkNotNull(ruleAware);
}
@Override
} else {
rwTx.cancel();
}
+ ruleAware.flushPendingSecurityRulesFor(createdSecGroup.getKey(), neutron);
}
public boolean addNeutronSecurityGroup(SecurityGroup secGroup, ReadWriteTransaction rwTx) {
@Override
public void onDeleted(SecurityGroup deletedSecGroup, Neutron oldNeutron, Neutron newNeutron) {
LOG.trace("deleted securityGroup - {}", deletedSecGroup);
- ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
- TenantId tenantId = new TenantId(deletedSecGroup.getTenantId().getValue());
- EndpointGroupId epgId = new EndpointGroupId(deletedSecGroup.getUuid().getValue());
+ if (newNeutron != null && newNeutron.getSecurityRules() != null
+ && newNeutron.getSecurityRules().getSecurityRule() != null
+ && newNeutron.getSecurityRules()
+ .getSecurityRule()
+ .stream()
+ .filter(sr -> sr.getSecurityGroupId().equals(deletedSecGroup.getUuid()))
+ .findAny()
+ .isPresent()) {
+ LOG.warn("Cannot remove security group {} before removing last security rule.", deletedSecGroup.getKey());
+ ruleAware.addPendingDeletedSecGroup(deletedSecGroup);
+ return;
+ }
+ deleteGbpEndpointGroup(dataProvider, new TenantId(deletedSecGroup.getTenantId().getValue()),
+ new EndpointGroupId(deletedSecGroup.getUuid().getValue()));
+ }
+
+ public static void deleteGbpEndpointGroup(DataBroker dataBroker, TenantId tenantId, EndpointGroupId epgId) {
+ ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
Optional<EndpointGroup> potentialEpg = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
IidFactory.endpointGroupIid(tenantId, epgId), rwTx);
if (!potentialEpg.isPresent()) {
rwTx.cancel();
return;
}
-
DataStoreHelper.submitToDs(rwTx);
}
-
}
import java.util.Collections;
import java.util.List;
+import java.util.function.Function;
import java.util.stream.Collectors;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.NetworkProviderExtension;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnet.attributes.AllocationPools;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
sb.setIsTenant(NetworkUtils.isTenantNetwork(potentialNetwork.get()));
}
if (subnet.getAllocationPools() != null) {
- List<AllocationPool> pools = subnet.getAllocationPools()
- .stream()
- .map(s -> new AllocationPoolBuilder().setFirst(s.getStart().getIpv4Address().getValue())
- .setLast(s.getEnd().getIpv4Address().getValue())
- .build())
- .collect(Collectors.toList());
+ List<AllocationPool> pools =
+ subnet.getAllocationPools().stream().map(new Function<AllocationPools, AllocationPool>() {
+
+ @Override
+ public AllocationPool apply(AllocationPools ap) {
+ IpAddress start = ap.getStart();
+ IpAddress end = ap.getEnd();
+ AllocationPoolBuilder ab = new AllocationPoolBuilder();
+ if (start.getIpv4Address() != null || end.getIpv4Address() != null) {
+ ab.setFirst(start.getIpv4Address().getValue());
+ ab.setLast(end.getIpv4Address().getValue());
+ } else {
+ ab.setFirst(start.getIpv6Address().getValue());
+ ab.setLast(end.getIpv6Address().getValue());
+ }
+ return ab.build();
+ }
+ }).collect(Collectors.toList());
sb.setAllocationPool(pools);
}
NetworkDomainBuilder ndb = new NetworkDomainBuilder();
import static com.google.common.base.Preconditions.checkNotNull;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import java.util.Set;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
+
+import javax.annotation.Nonnull;
import org.opendaylight.controller.config.yang.config.neutron_mapper.impl.NeutronMapperModule;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.groupbasedpolicy.api.sf.ChainActionDefinition;
import org.opendaylight.groupbasedpolicy.dto.EpgKeyDto;
import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.NeutronAware;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.NeutronSecurityGroupAware;
import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
import org.opendaylight.groupbasedpolicy.neutron.mapper.util.SecurityGroupUtils;
import org.opendaylight.groupbasedpolicy.neutron.mapper.util.SecurityRuleUtils;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.groups.attributes.security.groups.SecurityGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.groups.attributes.security.groups.SecurityGroupKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.SecurityRules;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.security.rules.SecurityRule;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.security.rules.SecurityRuleKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multiset;
private final DataBroker dataProvider;
private final Multiset<InstanceIdentifier<ClassifierInstance>> createdClassifierInstances;
private final Multiset<InstanceIdentifier<ActionInstance>> createdActionInstances;
+ private final Map<SecurityRuleKey, SecurityRule> pendingCreatedRules;
+ private final Map<SecurityGroupKey, SecurityGroup> pendingDeletedGroups;
final static String PROVIDED_BY = "provided_by-";
final static String POSSIBLE_CONSUMER = "possible_consumer-";
this.dataProvider = checkNotNull(dataProvider);
this.createdClassifierInstances = checkNotNull(classifierInstanceNames);
this.createdActionInstances = checkNotNull(createdActionInstances);
+ this.pendingCreatedRules = new HashMap<>();
+ this.pendingDeletedGroups = new HashMap<>();
}
@Override
public void onCreated(SecurityRule secRule, Neutron neutron) {
LOG.trace("created securityRule - {}", secRule);
+ if (neutron.getSecurityGroups() == null || neutron.getSecurityGroups().getSecurityGroup() == null
+ || !neutron.getSecurityGroups()
+ .getSecurityGroup()
+ .stream()
+ .filter(sg -> sg.getKey().getUuid().equals(secRule.getSecurityGroupId()))
+ .findFirst()
+ .isPresent()) {
+ pendingCreatedRules.put(secRule.getKey(), secRule);
+ LOG.warn("Security group of security rule {} does not exist yet. The rule will be processed"
+ + "when the missing security group is created.", secRule.getKey());
+ return;
+ }
ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
boolean isNeutronSecurityRuleAdded = addNeutronSecurityRule(secRule, neutron, rwTx);
if (isNeutronSecurityRuleAdded) {
}
}
+ public void flushPendingSecurityRulesFor(@Nonnull SecurityGroupKey secGroupKey, Neutron neutron) {
+ List<SecurityRule> rules = pendingCreatedRules.values()
+ .stream()
+ .filter(sr -> sr.getSecurityGroupId().equals(secGroupKey.getUuid()))
+ .collect(Collectors.toList());
+ rules.forEach(sr -> {
+ LOG.trace("Flushing pending security rule {}", sr);
+ ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
+ boolean isNeutronSecurityRuleAdded = addNeutronSecurityRule(sr, neutron, rwTx);
+ if (isNeutronSecurityRuleAdded) {
+ DataStoreHelper.submitToDs(rwTx);
+ } else {
+ rwTx.cancel();
+ }
+ pendingCreatedRules.remove(sr.getKey());
+ });
+ }
+
public boolean addNeutronSecurityRule(SecurityRule secRule, Neutron neutron, ReadWriteTransaction rwTx) {
return addNeutronSecurityRuleWithAction(secRule, neutron, MappingUtils.ALLOW_ACTION_CHOICE, rwTx);
}
newSecRule);
}
+ public void addPendingDeletedSecGroup(SecurityGroup secGroup) {
+ LOG.trace("Caching pending deleted security group {}", secGroup.getKey());
+ pendingDeletedGroups.put(secGroup.getKey(), secGroup);
+ }
+
@Override
public void onDeleted(SecurityRule deletedSecRule, Neutron oldNeutron, Neutron newNeutron) {
LOG.trace("deleted securityRule - {}", deletedSecRule);
boolean isNeutronSecurityRuleDeleted = deleteNeutronSecurityRule(deletedSecRule, oldNeutron, rwTx);
if (isNeutronSecurityRuleDeleted) {
DataStoreHelper.submitToDs(rwTx);
+ if (newNeutron == null || newNeutron.getSecurityRules() == null
+ || newNeutron.getSecurityRules().getSecurityRule() == null
+ || !newNeutron.getSecurityRules()
+ .getSecurityRule()
+ .stream()
+ .filter(rule -> rule.getSecurityGroupId().equals(deletedSecRule.getSecurityGroupId()))
+ .findAny()
+ .isPresent()) {
+ SecurityGroupKey secGroupKey = new SecurityGroupKey(deletedSecRule.getSecurityGroupId());
+ SecurityGroup pendingSg = pendingDeletedGroups.get(secGroupKey);
+ if (pendingSg != null) {
+ LOG.trace("Processing pending deleted security group {}", secGroupKey);
+ NeutronSecurityGroupAware.deleteGbpEndpointGroup(dataProvider,
+ new TenantId(deletedSecRule.getTenantId().getValue()),
+ new EndpointGroupId(secGroupKey.getUuid().getValue()));
+ pendingDeletedGroups.remove(secGroupKey);
+ }
+ }
} else {
rwTx.cancel();
}
import org.junit.rules.ExpectedException;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronMapperDataBrokerTest;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule.NeutronSecurityRuleAware;
import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronEntityFactory;
import org.opendaylight.groupbasedpolicy.neutron.mapper.test.PolicyAssert;
import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
@Before
public void init() {
dataBroker = getDataBroker();
- groupAware = new NeutronSecurityGroupAware(dataBroker);
+ groupAware = new NeutronSecurityGroupAware(dataBroker, new NeutronSecurityRuleAware(dataBroker));
secGroup1 = NeutronEntityFactory.securityGroup(secGroupId1, tenantId);
secGroup2 = NeutronEntityFactory.securityGroup(secGroupId2, tenantId);
@Test
public void testConstructor_invalidArgument() throws NullPointerException {
thrown.expect(NullPointerException.class);
- new NeutronSecurityGroupAware(null);
+ new NeutronSecurityGroupAware(null, null);
}
@Test
import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;\r
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;\r
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;\r
import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;\r
import org.opendaylight.groupbasedpolicy.util.NetUtils;\r
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;\r
if (natEntries != null) {\r
for (MappingEntryBuilder natEntry : natEntries) {\r
Ipv4Address externalSrcAddress = natEntry.getExternalSrcAddress();\r
- ext.remove(Integer.toUnsignedLong(subnet.getInfo().asInteger(externalSrcAddress.getValue())));\r
+ long id = Integer.toUnsignedLong(subnet.getInfo().asInteger(externalSrcAddress.getValue()));\r
+ if (ext.get(id) != null) {\r
+ ext.remove(id);\r
+ }\r
}\r
}\r
-\r
return ext;\r
}\r
}\r