sangho
Committed by Gerrit Code Review

[ONOS-3953] Implements Security Group of Openstack

Change-Id: I30766097a2894a26e46a7a399176d99e95af6abf
......@@ -15,6 +15,8 @@
*/
package org.onosproject.openstackinterface;
import org.onlab.packet.IpPrefix;
import java.util.Objects;
import static com.google.common.base.Preconditions.checkNotNull;
......@@ -24,25 +26,34 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/
public final class OpenstackSecurityGroupRule {
private final String direction;
private final Direction direction;
private final String ethertype;
private final String id;
private final String portRangeMax;
private final String portRangeMin;
private final int portRangeMax;
private final int portRangeMin;
private final String protocol;
private final String remoteGroupId;
private final String remoteIpPrefix;
private final IpPrefix remoteIpPrefix;
private final String secuityGroupId;
private final String tenantId;
private OpenstackSecurityGroupRule(String direction,
/**
* Direction of the Security Group.
*
*/
public enum Direction {
INGRESS,
EGRESS
}
private OpenstackSecurityGroupRule(Direction direction,
String ethertype,
String id,
String portRangeMax,
String portRangeMin,
int portRangeMax,
int portRangeMin,
String protocol,
String remoteGroupId,
String remoteIpPrefix,
IpPrefix remoteIpPrefix,
String securityGroupId,
String tenantId) {
this.direction = direction;
......@@ -57,6 +68,105 @@ public final class OpenstackSecurityGroupRule {
this.tenantId = tenantId;
}
/**
* Returns the builder object for the OpenstackSecurityGroupRule.
*
* @return OpenstackSecurityGroupRule builder object
*/
public static OpenstackSecurityGroupRule.Builder builder() {
return new Builder();
}
/**
* Returns the direction.
*
* @return direction
*/
public Direction direction() {
return direction;
}
/**
* Returns the Ethernet type.
*
* @return Ethernet type
*/
public String ethertype() {
return ethertype;
}
/**
* Returns the Security Group ID.
*
* @return Security Group ID
*/
public String id() {
return id;
}
/**
* Returns the max of the port range.
*
* @return max of the port range
*/
public int portRangeMax() {
return portRangeMax;
}
/**
* Returns the min of the port range.
*
* @return min of the port range
*/
public int portRangeMin() {
return portRangeMin;
}
/**
* Returns the IP protocol.
*
* @return IP protocol
*/
public String protocol() {
return protocol;
}
/**
* Returns the remote group ID.
*
* @return remote group ID
*/
public String remoteGroupId() {
return remoteGroupId;
}
/**
* Returns the remote IP address.
*
* @return remote IP address
*/
public IpPrefix remoteIpPrefix() {
return this.remoteIpPrefix;
}
/**
* Returns the Security Group ID.
*
* @return security group ID
*/
public String secuityGroupId() {
return secuityGroupId;
}
/**
* Returns the tenant ID.
*
* @return tenant ID
*/
public String tenantId() {
return tenantId;
}
@Override
public String toString() {
return new StringBuilder(" [")
......@@ -84,8 +194,8 @@ public final class OpenstackSecurityGroupRule {
return this.direction.equals(that.direction) &&
this.ethertype.equals(that.direction) &&
this.id.equals(that.id) &&
this.portRangeMax.equals(that.portRangeMax) &&
this.portRangeMin.equals(that.portRangeMin) &&
this.portRangeMax == that.portRangeMax &&
this.portRangeMin == that.portRangeMin &&
this.protocol.equals(that.protocol) &&
this.remoteGroupId.equals(that.remoteGroupId) &&
this.secuityGroupId.equals(that.secuityGroupId) &&
......@@ -235,8 +345,16 @@ public final class OpenstackSecurityGroupRule {
* @return OpenstackSecurityGroupRule object
*/
public OpenstackSecurityGroupRule build() {
return new OpenstackSecurityGroupRule(direction, etherType, id, portRangeMax,
portRangeMin, protocol, remoteGroupId, remoteIpPrefix, secuityGroupId, tenantId);
int portRangeMinInt = (portRangeMin == null || portRangeMin.equals("null")) ?
-1 : Integer.parseInt(portRangeMax);
int portRangeMaxInt = (portRangeMax == null || portRangeMax.equals("null")) ?
-1 : Integer.parseInt(portRangeMax);
IpPrefix ipPrefix = (remoteIpPrefix == null || remoteIpPrefix.equals("null")) ?
null : IpPrefix.valueOf(remoteIpPrefix);
return new OpenstackSecurityGroupRule(Direction.valueOf(direction.toUpperCase()), etherType, id,
portRangeMaxInt, portRangeMinInt, protocol, remoteGroupId, ipPrefix, secuityGroupId, tenantId);
}
}
}
......
......@@ -48,7 +48,7 @@ public class OpenstackSecurityGroupCodec extends JsonCodec<OpenstackSecurityGrou
private static final String REMOTE_GROUP_ID = "remote_group_id";
private static final String REMOTE_IP_PREFIX = "remote_ip_prefix";
private static final String SECURITY_GROUP_ID = "security_group_id";
private static final String TENAN_ID = "tenant_id";
private static final String TENANT_ID = "tenant_id";
@Override
public OpenstackSecurityGroup decode(ObjectNode json, CodecContext context) {
......@@ -75,12 +75,12 @@ public class OpenstackSecurityGroupCodec extends JsonCodec<OpenstackSecurityGrou
.remoteGroupId(ruleInfo.path(REMOTE_GROUP_ID).asText())
.remoteIpPrefix(ruleInfo.path(REMOTE_IP_PREFIX).asText())
.securityGroupId(ruleInfo.path(SECURITY_GROUP_ID).asText())
.tenantId(ruleInfo.path(TENAN_ID).asText())
.tenantId(ruleInfo.path(TENANT_ID).asText())
.build();
rules.add(openstackSecurityGroupRule);
}
String tenantId = securityGroupNode.path(TENAN_ID).asText();
String tenantId = securityGroupNode.path(TENANT_ID).asText();
OpenstackSecurityGroup openstackSecurityGroup = OpenstackSecurityGroup.builder()
.description(description)
......
......@@ -18,6 +18,10 @@ package org.onosproject.openstacknetworking;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.MacAddress;
import org.onosproject.net.DeviceId;
import java.util.Collection;
import java.util.Collections;
import static com.google.common.base.Preconditions.checkNotNull;
/**
......@@ -29,70 +33,174 @@ public class OpenstackPortInfo {
private final DeviceId deviceId;
private final long vni;
private final Ip4Address gatewayIP;
public OpenstackPortInfo(Ip4Address hostIp, MacAddress hostMac, DeviceId deviceId, long vni, Ip4Address gatewayIP) {
private final Collection<String> securityGroups;
/**
* Returns OpenstackPortInfo reference.
*
* @param hostIp host IP address
* @param hostMac host MAC address
* @param deviceId device ID
* @param vni tunnel ID
* @param gatewayIP gateway IP address
* @param securityGroups security group list
*/
public OpenstackPortInfo(Ip4Address hostIp, MacAddress hostMac, DeviceId deviceId, long vni,
Ip4Address gatewayIP, Collection<String> securityGroups) {
this.hostIp = hostIp;
this.hostMac = hostMac;
this.deviceId = deviceId;
this.vni = vni;
this.gatewayIP = gatewayIP;
this.securityGroups = securityGroups;
}
/**
* Returns IP address of the port.
*
* @return IP address
*/
public Ip4Address ip() {
return hostIp;
}
/**
* Returns MAC address of the port.
*
* @return MAC address
*/
public MacAddress mac() {
return hostMac;
}
/**
* Returns device ID.
*
* @return device ID
*/
public DeviceId deviceId() {
return deviceId;
}
/**
* Returns tunnel ID.
*
* @return tunnel ID
*/
public long vni() {
return vni;
}
/**
* Returns gateway IP address.
*
* @return gateway IP address
*/
public Ip4Address gatewayIP() {
return gatewayIP;
}
/**
* Returns Security Group ID list.
*
* @return list of Security Group ID
*/
public Collection<String> securityGroups() {
return Collections.unmodifiableCollection(securityGroups);
}
/**
* Returns the builder of the OpenstackPortInfo.
*
* @return OpenstackPortInfo builder reference
*/
public static OpenstackPortInfo.Builder builder() {
return new Builder();
}
/**
* Represents the OpenstackPortInfo Builder.
*
*/
public static final class Builder {
private Ip4Address hostIp;
private MacAddress hostMac;
private DeviceId deviceId;
private long vni;
private Ip4Address gatewayIP;
private Collection<String> securityGroups;
/**
* Sets the IP address of the port.
*
* @param gatewayIP
* @return Builder reference
*/
public Builder setGatewayIP(Ip4Address gatewayIP) {
this.gatewayIP = checkNotNull(gatewayIP, "gatewayIP cannot be null");
return this;
}
/**
* Sets the host IP address of the port.
*
* @param hostIp host IP address
* @return Builder reference
*/
public Builder setHostIp(Ip4Address hostIp) {
this.hostIp = checkNotNull(hostIp, "hostIp cannot be null");
return this;
}
/**
* Sets the host MAC address of the port.
*
* @param hostMac host MAC address
* @return Builder reference
*/
public Builder setHostMac(MacAddress hostMac) {
this.hostMac = checkNotNull(hostMac, "hostMac cannot be bull");
return this;
}
/**
* Sets the device ID.
*
* @param deviceId device ID
* @return Builder reference
*/
public Builder setDeviceId(DeviceId deviceId) {
this.deviceId = checkNotNull(deviceId, "deviceId cannot be null");
return this;
}
/**
* Sets the tunnel ID.
*
* @param vni tunnel ID
* @return Builder reference
*/
public Builder setVni(long vni) {
this.vni = checkNotNull(vni, "vni cannot be null");
return this;
}
/**
* Sets the security group ID list.
*
* @param securityGroups security group ID list
* @return Builder reference
*/
public Builder setSecurityGroups(Collection<String> securityGroups) {
this.securityGroups = securityGroups;
return this;
}
/**
* Builds the OpenstackPortInfo reference.
*
* @return OpenstackPortInfo reference
*/
public OpenstackPortInfo build() {
return new OpenstackPortInfo(this);
}
......@@ -104,5 +212,6 @@ public class OpenstackPortInfo {
deviceId = builder.deviceId;
vni = builder.vni;
gatewayIP = builder.gatewayIP;
securityGroups = builder.securityGroups;
}
}
......
......@@ -58,7 +58,6 @@ public class OpenstackSwitchingRulePopulator {
private static Logger log = LoggerFactory
.getLogger(OpenstackSwitchingRulePopulator.class);
private static final int SWITCHING_RULE_PRIORITY = 30000;
private static final int EAST_WEST_ROUTING_RULE_PRIORITY = 29000;
private static final int TUNNELTAG_RULE_PRIORITY = 30000;
private FlowObjectiveService flowObjectiveService;
......@@ -490,4 +489,5 @@ public class OpenstackSwitchingRulePopulator {
}
return port.number();
}
}
......
......@@ -84,6 +84,23 @@ public class OpenstackPortWebResource extends AbstractWebResource {
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response updatePorts(InputStream input) {
return Response.status(Response.Status.OK).build();
try {
ObjectMapper mapper = new ObjectMapper();
ObjectNode portNode = (ObjectNode) mapper.readTree(input);
OpenstackPort openstackPort = PORT_CODEC.decode(portNode, this);
OpenstackSwitchingService switchingService =
getService(OpenstackSwitchingService.class);
switchingService.updatePort(openstackPort);
log.debug("REST API update port is called with {}", portNode.toString());
return Response.status(Response.Status.OK).build();
} catch (Exception e) {
log.error("Update Port failed because of exception {}",
e.toString());
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString())
.build();
}
}
}
......
......@@ -64,6 +64,7 @@ public class OpenstackPipeline extends DefaultSingleTablePipeline
protected static final int VNI_TABLE = 0;
protected static final int FORWARDING_TABLE = 1;
protected static final int ACL_TABLE = 2;
private static final int DROP_PRIORITY = 0;
private static final int TIME_OUT = 0;
......@@ -136,6 +137,7 @@ public class OpenstackPipeline extends DefaultSingleTablePipeline
private void initializePipeline() {
processVniTable(true);
processForwardingTable(true);
processAclTable(true);
}
private void processVniTable(boolean install) {
......@@ -176,6 +178,26 @@ public class OpenstackPipeline extends DefaultSingleTablePipeline
applyRules(install, flowRule);
}
private void processAclTable(boolean install) {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
treatment.wipeDeferred();
treatment.drop();
FlowRule flowRule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(DROP_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(ACL_TABLE)
.build();
applyRules(install, flowRule);
}
private void applyRules(boolean install, FlowRule flowRule) {
FlowRuleOperations.Builder flowOpsBuilder = FlowRuleOperations.builder();
......@@ -264,8 +286,15 @@ public class OpenstackPipeline extends DefaultSingleTablePipeline
tBuilder.transition(FORWARDING_TABLE);
ruleBuilder.withTreatment(tBuilder.build());
ruleBuilder.forTable(VNI_TABLE);
} else {
} else if (forwardingObjective.selector().getCriterion(Criterion.Type.TUNNEL_ID) != null) {
TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
tBuilder.deferred();
forwardingObjective.treatment().allInstructions().forEach(tBuilder::add);
tBuilder.transition(ACL_TABLE);
ruleBuilder.withTreatment(tBuilder.build());
ruleBuilder.forTable(FORWARDING_TABLE);
} else {
ruleBuilder.forTable(ACL_TABLE);
}
return Collections.singletonList(ruleBuilder.build());
......