[ONOS-3953] Implements Security Group of Openstack
Change-Id: I30766097a2894a26e46a7a399176d99e95af6abf
diff --git a/apps/openstacknetworking/openstackswitching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingManager.java b/apps/openstacknetworking/openstackswitching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingManager.java
index 4e66d95..2c88b3a 100644
--- a/apps/openstacknetworking/openstackswitching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingManager.java
+++ b/apps/openstacknetworking/openstackswitching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingManager.java
@@ -104,7 +104,9 @@
public static final String DEVICE_OWNER_GATEWAY = "network:router_gateway";
private ApplicationId appId;
- private OpenstackArpHandler arpHandler = new OpenstackArpHandler(openstackService, packetService, hostService);
+
+ private OpenstackArpHandler arpHandler;
+ private OpenstackSecurityGroupRulePopulator sgRulePopulator;
private ExecutorService deviceEventExcutorService =
Executors.newSingleThreadExecutor(groupedThreads("onos/openstackswitching", "device-event"));
@@ -114,6 +116,7 @@
private InternalHostListener internalHostListener = new InternalHostListener();
private Map<String, OpenstackPortInfo> openstackPortInfoMap = Maps.newHashMap();
+ private Map<String, OpenstackSecurityGroup> securityGroupMap = Maps.newConcurrentMap();
@Activate
protected void activate() {
@@ -124,6 +127,9 @@
deviceService.addListener(internalDeviceListener);
hostService.addListener(internalHostListener);
+ arpHandler = new OpenstackArpHandler(openstackService, packetService, hostService);
+ sgRulePopulator = new OpenstackSecurityGroupRulePopulator(appId, openstackService, flowObjectiveService);
+
initializeFlowRules();
log.info("Started");
@@ -148,13 +154,6 @@
registerDhcpInfo(openstackPort);
}
}
-
- if (!openstackPort.securityGroups().isEmpty()) {
- openstackPort.securityGroups().forEach(sgId -> {
- OpenstackSecurityGroup sg = openstackService.getSecurityGroup(sgId);
- log.debug("SecurityGroup : {}", sg.toString());
- });
- }
}
@Override
@@ -185,6 +184,22 @@
@Override
public void updatePort(OpenstackPort openstackPort) {
+ if (openstackPort.status().equals(OpenstackPort.PortStatus.ACTIVE)) {
+ String portName = PORTNAME_PREFIX_VM + openstackPort.id().substring(0, 11);
+ OpenstackPortInfo osPortInfo = openstackPortInfoMap.get(portName);
+ if (osPortInfo != null) {
+ // Remove all security group rules based on the ones stored in security group map.
+ osPortInfo.securityGroups().stream().forEach(
+ sgId -> sgRulePopulator.removeSecurityGroupRules(osPortInfo.deviceId(), sgId,
+ osPortInfo.ip(), openstackPortInfoMap, securityGroupMap));
+ // Add all security group rules based on the updated security group.
+ openstackPort.securityGroups().stream().forEach(
+ sgId -> sgRulePopulator.populateSecurityGroupRules(osPortInfo.deviceId(), sgId,
+ osPortInfo.ip(), openstackPortInfoMap));
+ updatePortMap(osPortInfo.deviceId(), portName, openstackService.networks(),
+ openstackService.subnets(), openstackPort);
+ }
+ }
}
@Override
@@ -205,26 +220,37 @@
}
private void processPortUpdated(Device device, Port port) {
- if (!port.annotations().value(PORTNAME).equals(PORTNAME_PREFIX_TUNNEL)) {
- if (port.isEnabled() || port.annotations().value(PORTNAME).startsWith(PORTNAME_PREFIX_ROUTER)) {
- OpenstackSwitchingRulePopulator rulePopulator =
- new OpenstackSwitchingRulePopulator(appId, flowObjectiveService,
- deviceService, openstackService, driverService);
+ String portName = port.annotations().value(PORTNAME);
+ synchronized (openstackPortInfoMap) {
+ if (portName.startsWith(PORTNAME_PREFIX_VM)) {
+ if (port.isEnabled()) {
+ OpenstackSwitchingRulePopulator rulePopulator =
+ new OpenstackSwitchingRulePopulator(appId, flowObjectiveService,
+ deviceService, openstackService, driverService);
- rulePopulator.populateSwitchingRules(device, port);
- updatePortMap(device.id(), port, openstackService.networks(), openstackService.subnets(),
- rulePopulator.openstackPort(port));
+ rulePopulator.populateSwitchingRules(device, port);
+ OpenstackPort openstackPort = rulePopulator.openstackPort(port);
+ Ip4Address vmIp = (Ip4Address) openstackPort.fixedIps().values().stream()
+ .findAny().orElseGet(null);
+ openstackPort.securityGroups().stream().forEach(
+ sgId -> sgRulePopulator.populateSecurityGroupRules(device.id(), sgId, vmIp,
+ openstackPortInfoMap));
+ updatePortMap(device.id(), port.annotations().value(PORTNAME),
+ openstackService.networks(), openstackService.subnets(), openstackPort);
- //In case portupdate event is driven by vm shutoff from openstack
- } else if (!port.isEnabled() && openstackPortInfoMap.containsKey(port.annotations().value(PORTNAME))) {
- log.debug("Flowrules according to the port {} were removed", port.number().toString());
- OpenstackSwitchingRulePopulator rulePopulator =
- new OpenstackSwitchingRulePopulator(appId, flowObjectiveService,
- deviceService, openstackService, driverService);
-
- rulePopulator.removeSwitchingRules(port, openstackPortInfoMap);
- dhcpService.removeStaticMapping(openstackPortInfoMap.get(port.annotations().value(PORTNAME)).mac());
- openstackPortInfoMap.remove(port.annotations().value(PORTNAME));
+ //In case portupdate event is driven by vm shutoff from openstack
+ } else if (!port.isEnabled() && openstackPortInfoMap.containsKey(portName)) {
+ log.debug("Flowrules according to the port {} were removed", port.number().toString());
+ OpenstackSwitchingRulePopulator rulePopulator =
+ new OpenstackSwitchingRulePopulator(appId, flowObjectiveService,
+ deviceService, openstackService, driverService);
+ rulePopulator.removeSwitchingRules(port, openstackPortInfoMap);
+ openstackPortInfoMap.get(portName).securityGroups().stream().forEach(
+ sgId -> sgRulePopulator.removeSecurityGroupRules(device.id(), sgId,
+ openstackPortInfoMap.get(portName).ip(), openstackPortInfoMap, securityGroupMap));
+ dhcpService.removeStaticMapping(openstackPortInfoMap.get(port.annotations().value(PORTNAME)).mac());
+ openstackPortInfoMap.remove(port.annotations().value(PORTNAME));
+ }
}
}
}
@@ -242,27 +268,33 @@
Collection<OpenstackSubnet> subnets = openstackService.subnets();
deviceService.getDevices().forEach(device -> {
- log.debug("device {} num of ports {} ", device.id(),
- deviceService.getPorts(device.id()).size());
- deviceService.getPorts(device.id()).stream()
- .filter(port -> port.annotations().value(PORTNAME).startsWith(PORTNAME_PREFIX_VM) ||
- port.annotations().value(PORTNAME).startsWith(PORTNAME_PREFIX_ROUTER))
- .forEach(vmPort -> {
- OpenstackPort osPort = rulePopulator.openstackPort(vmPort);
- if (osPort != null && !osPort.deviceOwner().equals(DEVICE_OWNER_GATEWAY)) {
- rulePopulator.populateSwitchingRules(device, vmPort);
- updatePortMap(device.id(), vmPort, networks, subnets, osPort);
- registerDhcpInfo(osPort);
- } else {
- log.warn("No openstackPort information for port {}", vmPort);
- }
- }
- );
+ log.debug("device {} num of ports {} ", device.id(),
+ deviceService.getPorts(device.id()).size());
+ deviceService.getPorts(device.id()).stream()
+ .filter(port -> port.annotations().value(PORTNAME).startsWith(PORTNAME_PREFIX_VM) ||
+ port.annotations().value(PORTNAME).startsWith(PORTNAME_PREFIX_ROUTER))
+ .forEach(vmPort -> {
+ OpenstackPort osPort = rulePopulator.openstackPort(vmPort);
+ if (osPort != null && !osPort.deviceOwner().equals(DEVICE_OWNER_GATEWAY)) {
+ rulePopulator.populateSwitchingRules(device, vmPort);
+ Ip4Address vmIp = (Ip4Address) osPort.fixedIps().values().stream()
+ .findAny().orElseGet(null);
+ osPort.securityGroups().stream().forEach(
+ sgId -> sgRulePopulator.populateSecurityGroupRules(device.id(),
+ sgId, vmIp, openstackPortInfoMap));
+ updatePortMap(device.id(), vmPort.annotations().value(PORTNAME), networks,
+ subnets, osPort);
+ registerDhcpInfo(osPort);
+ } else {
+ log.warn("No openstackPort information for port {}", vmPort);
+ }
+ }
+ );
}
);
}
- private void updatePortMap(DeviceId deviceId, Port port, Collection<OpenstackNetwork> networks,
+ private void updatePortMap(DeviceId deviceId, String portName, Collection<OpenstackNetwork> networks,
Collection<OpenstackSubnet> subnets, OpenstackPort openstackPort) {
long vni = Long.parseLong(networks.stream()
.filter(n -> n.id().equals(openstackPort.networkId()))
@@ -279,10 +311,17 @@
.setHostIp((Ip4Address) openstackPort.fixedIps().values().stream().findFirst().orElse(null))
.setHostMac(openstackPort.macAddress())
.setVni(vni)
- .setGatewayIP(gatewayIPAddress);
+ .setGatewayIP(gatewayIPAddress)
+ .setSecurityGroups(openstackPort.securityGroups());
- openstackPortInfoMap.putIfAbsent(port.annotations().value(PORTNAME),
- portBuilder.build());
+ openstackPortInfoMap.put(portName, portBuilder.build());
+
+ openstackPort.securityGroups().stream().forEach(sgId -> {
+ if (!securityGroupMap.containsKey(sgId)) {
+ securityGroupMap.put(sgId, openstackService.getSecurityGroup(sgId));
+ }
+ });
+
}
private void processHostRemoved(Host host) {