Hyunsun Moon

Use openstack4j for OpenStack data model and rest client

Change-Id: I4eb52c3c82d847c442420d1287392fe9079bf699
......@@ -18,7 +18,7 @@
category="Traffic Steering" url="http://onosproject.org" title="CORD Virtual Tenant Network"
featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
features="${project.artifactId}"
apps="org.onosproject.ovsdb-base,org.onosproject.openstackinterface,org.onosproject.dhcp">
apps="org.onosproject.ovsdb-base,org.onosproject.dhcp">
<description>${project.description}</description>
<artifact>mvn:${project.groupId}/onos-app-cordvtn/${project.version}</artifact>
</app>
......
......@@ -19,5 +19,6 @@
<feature>onos-api</feature>
<bundle>mvn:${project.groupId}/onos-app-cordvtn/${project.version}</bundle>
<bundle>wrap:mvn:com.jcraft/jsch/0.1.53$Bundle-SymbolicName=jsch&amp;Bundle-Version=0.1.53</bundle>
<bundle>wrap:mvn:org.pacesys/openstack4j/2.11/jar/withdeps$Bundle-SymbolicName=openstack4j&amp;Bundle-Version=2.11</bundle>
</feature>
</features>
......
......@@ -112,6 +112,21 @@
<artifactId>jsch</artifactId>
<version>0.1.53</version>
</dependency>
<dependency>
<groupId>org.pacesys</groupId>
<artifactId>openstack4j-core</artifactId>
<version>2.11</version>
</dependency>
<dependency>
<groupId>org.pacesys.openstack4j.connectors</groupId>
<artifactId>openstack4j-http-connector</artifactId>
<version>2.11</version>
</dependency>
<dependency>
<groupId>org.pacesys.openstack4j.connectors</groupId>
<artifactId>openstack4j-httpclient</artifactId>
<version>2.11</version>
</dependency>
</dependencies>
<build>
......@@ -131,8 +146,14 @@
${project.groupId}.${project.artifactId}
</Bundle-SymbolicName>
<Import-Package>
!org.apache.http.*,
*,org.glassfish.jersey.servlet
</Import-Package>
<Embed-Dependency>
openstack4j-core,
openstack4j-http-connector,
openstack4j-httpclient
</Embed-Dependency>
<Web-ContextPath>${web.context}</Web-ContextPath>
</instructions>
</configuration>
......
......@@ -19,8 +19,8 @@ import com.google.common.base.MoreObjects;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onosproject.net.Host;
import org.onosproject.openstackinterface.OpenstackNetwork;
import org.onosproject.openstackinterface.OpenstackSubnet;
import org.openstack4j.model.network.Network;
import org.openstack4j.model.network.Subnet;
import java.util.Map;
import java.util.Objects;
......@@ -47,18 +47,18 @@ public final class CordService {
/**
* Default constructor.
*
* @param vNet OpenStack network
* @param subnet OpenStack subnet
* @param osNet OpenStack network
* @param osSubnet OpenStack subnet
* @param hosts host and tunnel ip map
* @param tenantServices list of tenant service ids
*/
public CordService(OpenstackNetwork vNet, OpenstackSubnet subnet,
public CordService(Network osNet, Subnet osSubnet,
Map<Host, IpAddress> hosts, Set<CordServiceId> tenantServices) {
this.id = CordServiceId.of(vNet.id());
this.segmentationId = Long.parseLong(vNet.segmentId());
this.serviceType = getServiceType(vNet.name());
this.serviceIpRange = IpPrefix.valueOf(subnet.cidr());
this.serviceIp = IpAddress.valueOf(subnet.gatewayIp());
this.id = CordServiceId.of(osNet.getId());
this.segmentationId = Long.parseLong(osNet.getProviderSegID());
this.serviceType = getServiceType(osNet.getName());
this.serviceIpRange = IpPrefix.valueOf(osSubnet.getCidr());
this.serviceIp = IpAddress.valueOf(osSubnet.getGateway());
this.hosts = hosts;
this.tenantServices = tenantServices;
}
......
......@@ -46,10 +46,6 @@ public class CordVtnConfig extends Config<ApplicationId> {
public static final String LOCAL_MANAGEMENT_IP = "localManagementIp";
public static final String OVSDB_PORT = "ovsdbPort";
public static final String SSH_PORT = "sshPort";
public static final String SSH_USER = "sshUser";
public static final String SSH_KEY_FILE = "sshKeyFile";
public static final String CORDVTN_NODES = "nodes";
public static final String HOSTNAME = "hostname";
public static final String HOST_MANAGEMENT_IP = "hostManagementIp";
......@@ -57,6 +53,17 @@ public class CordVtnConfig extends Config<ApplicationId> {
public static final String DATA_PLANE_INTF = "dataPlaneIntf";
public static final String BRIDGE_ID = "bridgeId";
public static final String SSH = "ssh";
public static final String SSH_PORT = "sshPort";
public static final String SSH_USER = "sshUser";
public static final String SSH_KEY_FILE = "sshKeyFile";
public static final String OPENSTACK = "openstack";
public static final String OPENSTACK_ENDPOINT = "endpoint";
public static final String OPENSTACK_TENANT = "tenant";
public static final String OPENSTACK_USER = "user";
public static final String OPENSTACK_PASSWORD = "password";
/**
* Returns the set of nodes read from network config.
*
......@@ -65,15 +72,22 @@ public class CordVtnConfig extends Config<ApplicationId> {
public Set<CordVtnNode> cordVtnNodes() {
Set<CordVtnNode> nodes = Sets.newHashSet();
JsonNode jsonNodes = object.get(CORDVTN_NODES);
if (jsonNodes == null) {
JsonNode cordvtnNodes = object.get(CORDVTN_NODES);
if (cordvtnNodes == null) {
log.debug("No CORD VTN nodes found");
return nodes;
}
for (JsonNode jsonNode : jsonNodes) {
JsonNode sshNode = object.get(SSH);
if (sshNode == null) {
log.warn("SSH information not found");
return nodes;
}
for (JsonNode cordvtnNode : cordvtnNodes) {
try {
NetworkAddress hostMgmt = NetworkAddress.valueOf(getConfig(jsonNode, HOST_MANAGEMENT_IP));
NetworkAddress hostMgmt = NetworkAddress.valueOf(getConfig(cordvtnNode, HOST_MANAGEMENT_IP));
NetworkAddress localMgmt = NetworkAddress.valueOf(getConfig(object, LOCAL_MANAGEMENT_IP));
if (hostMgmt.prefix().contains(localMgmt.prefix()) ||
localMgmt.prefix().contains(hostMgmt.prefix())) {
......@@ -84,22 +98,22 @@ public class CordVtnConfig extends Config<ApplicationId> {
Ip4Address hostMgmtIp = hostMgmt.ip().getIp4Address();
SshAccessInfo sshInfo = new SshAccessInfo(
hostMgmtIp,
TpPort.tpPort(Integer.parseInt(getConfig(object, SSH_PORT))),
getConfig(object, SSH_USER), getConfig(object, SSH_KEY_FILE));
TpPort.tpPort(Integer.parseInt(getConfig(sshNode, SSH_PORT))),
getConfig(sshNode, SSH_USER), getConfig(sshNode, SSH_KEY_FILE));
String hostname = getConfig(jsonNode, HOSTNAME);
String hostname = getConfig(cordvtnNode, HOSTNAME);
CordVtnNode newNode = new CordVtnNode(
hostname, hostMgmt, localMgmt,
NetworkAddress.valueOf(getConfig(jsonNode, DATA_PLANE_IP)),
NetworkAddress.valueOf(getConfig(cordvtnNode, DATA_PLANE_IP)),
TpPort.tpPort(Integer.parseInt(getConfig(object, OVSDB_PORT))),
sshInfo,
DeviceId.deviceId(getConfig(jsonNode, BRIDGE_ID)),
getConfig(jsonNode, DATA_PLANE_INTF),
DeviceId.deviceId(getConfig(cordvtnNode, BRIDGE_ID)),
getConfig(cordvtnNode, DATA_PLANE_INTF),
CordVtnNodeState.noState());
nodes.add(newNode);
} catch (IllegalArgumentException | NullPointerException e) {
log.error("{}", e.toString());
log.error("{}", e);
}
}
......@@ -167,5 +181,90 @@ public class CordVtnConfig extends Config<ApplicationId> {
return publicGateways;
}
}
/**
* Returns OpenStack API access information.
*
* @return openstack config
*/
public OpenStackConfig openstackConfig() {
JsonNode jsonNode = object.get(OPENSTACK);
if (jsonNode == null) {
log.error("Failed to get OpenStack configurations");
return null;
}
try {
return new OpenStackConfig(
jsonNode.path(OPENSTACK_ENDPOINT).asText(),
jsonNode.path(OPENSTACK_TENANT).asText(),
jsonNode.path(OPENSTACK_USER).asText(),
jsonNode.path(OPENSTACK_PASSWORD).asText());
} catch (IllegalArgumentException | NullPointerException e) {
log.error("Failed to get OpenStack configurations");
return null;
}
}
/**
* Configuration for OpenStack API access.
*/
public static class OpenStackConfig {
private final String endpoint;
private final String tenant;
private final String user;
private final String password;
/**
* Default constructor.
*
* @param endpoint Keystone endpoint
* @param tenant tenant name
* @param user user name
* @param password passwowrd
*/
public OpenStackConfig(String endpoint, String tenant, String user, String password) {
this.endpoint = endpoint;
this.tenant = tenant;
this.user = user;
this.password = password;
}
/**
* Returns OpenStack API endpoint.
*
* @return endpoint
*/
public String endpoint() {
return this.endpoint;
}
/**
* Returns OpenStack tenant name.
*
* @return tenant name
*/
public String tenant() {
return this.tenant;
}
/**
* Returns OpenStack user.
*
* @return user name
*/
public String user() {
return this.user;
}
/**
* Returns OpenStack password for the user.
*
* @return password
*/
public String password() {
return this.password;
}
}
}
......
......@@ -75,8 +75,8 @@ import org.onosproject.net.group.GroupBuckets;
import org.onosproject.net.group.GroupDescription;
import org.onosproject.net.group.GroupKey;
import org.onosproject.net.group.GroupService;
import org.onosproject.openstackinterface.OpenstackNetwork;
import org.onosproject.openstackinterface.OpenstackSubnet;
import org.openstack4j.model.network.Network;
import org.openstack4j.model.network.Subnet;
import org.slf4j.Logger;
import java.util.ArrayList;
......@@ -190,30 +190,31 @@ public class CordVtnRuleInstaller {
*
* @param host host
* @param tunnelIp tunnel ip
* @param vNet openstack network
* @param osNet openstack network
*/
public void populateBasicConnectionRules(Host host, IpAddress tunnelIp, OpenstackNetwork vNet) {
public void populateBasicConnectionRules(Host host, IpAddress tunnelIp, Network osNet) {
checkNotNull(host);
checkNotNull(vNet);
checkNotNull(osNet);
DeviceId deviceId = host.location().deviceId();
PortNumber inPort = host.location().port();
MacAddress dstMac = host.mac();
IpAddress hostIp = host.ipAddresses().stream().findFirst().get();
long tunnelId = Long.parseLong(vNet.segmentId());
long tunnelId = Long.parseLong(osNet.getProviderSegID());
OpenstackSubnet subnet = vNet.subnets().stream()
Subnet osSubnet = osNet.getNeutronSubnets().stream()
.findFirst()
.orElse(null);
if (subnet == null) {
if (osSubnet == null) {
log.error("Failed to get subnet for {}", host.id());
return;
}
Ip4Prefix cidr = Ip4Prefix.valueOf(osSubnet.getCidr());
populateLocalInPortRule(deviceId, inPort, hostIp);
populateDirectAccessRule(Ip4Prefix.valueOf(subnet.cidr()), Ip4Prefix.valueOf(subnet.cidr()));
populateServiceIsolationRule(Ip4Prefix.valueOf(subnet.cidr()));
populateDirectAccessRule(cidr, cidr);
populateServiceIsolationRule(cidr);
populateDstIpRule(deviceId, inPort, dstMac, hostIp, tunnelId, tunnelIp);
populateTunnelInRule(deviceId, inPort, dstMac, tunnelId);
}
......
......@@ -47,6 +47,10 @@
<param-name>javax.ws.rs.Application</param-name>
<param-value>org.onosproject.cordvtn.rest.CordVtnWebApplication</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.disableAutoDiscovery</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
......