Hyunsun Moon

Use openstack4j for OpenStack data model and rest client

Change-Id: I4eb52c3c82d847c442420d1287392fe9079bf699
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
18 category="Traffic Steering" url="http://onosproject.org" title="CORD Virtual Tenant Network" 18 category="Traffic Steering" url="http://onosproject.org" title="CORD Virtual Tenant Network"
19 featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features" 19 featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
20 features="${project.artifactId}" 20 features="${project.artifactId}"
21 - apps="org.onosproject.ovsdb-base,org.onosproject.openstackinterface,org.onosproject.dhcp"> 21 + apps="org.onosproject.ovsdb-base,org.onosproject.dhcp">
22 <description>${project.description}</description> 22 <description>${project.description}</description>
23 <artifact>mvn:${project.groupId}/onos-app-cordvtn/${project.version}</artifact> 23 <artifact>mvn:${project.groupId}/onos-app-cordvtn/${project.version}</artifact>
24 </app> 24 </app>
......
...@@ -19,5 +19,6 @@ ...@@ -19,5 +19,6 @@
19 <feature>onos-api</feature> 19 <feature>onos-api</feature>
20 <bundle>mvn:${project.groupId}/onos-app-cordvtn/${project.version}</bundle> 20 <bundle>mvn:${project.groupId}/onos-app-cordvtn/${project.version}</bundle>
21 <bundle>wrap:mvn:com.jcraft/jsch/0.1.53$Bundle-SymbolicName=jsch&amp;Bundle-Version=0.1.53</bundle> 21 <bundle>wrap:mvn:com.jcraft/jsch/0.1.53$Bundle-SymbolicName=jsch&amp;Bundle-Version=0.1.53</bundle>
22 + <bundle>wrap:mvn:org.pacesys/openstack4j/2.11/jar/withdeps$Bundle-SymbolicName=openstack4j&amp;Bundle-Version=2.11</bundle>
22 </feature> 23 </feature>
23 </features> 24 </features>
......
...@@ -112,6 +112,21 @@ ...@@ -112,6 +112,21 @@
112 <artifactId>jsch</artifactId> 112 <artifactId>jsch</artifactId>
113 <version>0.1.53</version> 113 <version>0.1.53</version>
114 </dependency> 114 </dependency>
115 + <dependency>
116 + <groupId>org.pacesys</groupId>
117 + <artifactId>openstack4j-core</artifactId>
118 + <version>2.11</version>
119 + </dependency>
120 + <dependency>
121 + <groupId>org.pacesys.openstack4j.connectors</groupId>
122 + <artifactId>openstack4j-http-connector</artifactId>
123 + <version>2.11</version>
124 + </dependency>
125 + <dependency>
126 + <groupId>org.pacesys.openstack4j.connectors</groupId>
127 + <artifactId>openstack4j-httpclient</artifactId>
128 + <version>2.11</version>
129 + </dependency>
115 </dependencies> 130 </dependencies>
116 131
117 <build> 132 <build>
...@@ -131,8 +146,14 @@ ...@@ -131,8 +146,14 @@
131 ${project.groupId}.${project.artifactId} 146 ${project.groupId}.${project.artifactId}
132 </Bundle-SymbolicName> 147 </Bundle-SymbolicName>
133 <Import-Package> 148 <Import-Package>
149 + !org.apache.http.*,
134 *,org.glassfish.jersey.servlet 150 *,org.glassfish.jersey.servlet
135 </Import-Package> 151 </Import-Package>
152 + <Embed-Dependency>
153 + openstack4j-core,
154 + openstack4j-http-connector,
155 + openstack4j-httpclient
156 + </Embed-Dependency>
136 <Web-ContextPath>${web.context}</Web-ContextPath> 157 <Web-ContextPath>${web.context}</Web-ContextPath>
137 </instructions> 158 </instructions>
138 </configuration> 159 </configuration>
......
...@@ -19,8 +19,8 @@ import com.google.common.base.MoreObjects; ...@@ -19,8 +19,8 @@ import com.google.common.base.MoreObjects;
19 import org.onlab.packet.IpAddress; 19 import org.onlab.packet.IpAddress;
20 import org.onlab.packet.IpPrefix; 20 import org.onlab.packet.IpPrefix;
21 import org.onosproject.net.Host; 21 import org.onosproject.net.Host;
22 -import org.onosproject.openstackinterface.OpenstackNetwork; 22 +import org.openstack4j.model.network.Network;
23 -import org.onosproject.openstackinterface.OpenstackSubnet; 23 +import org.openstack4j.model.network.Subnet;
24 24
25 import java.util.Map; 25 import java.util.Map;
26 import java.util.Objects; 26 import java.util.Objects;
...@@ -47,18 +47,18 @@ public final class CordService { ...@@ -47,18 +47,18 @@ public final class CordService {
47 /** 47 /**
48 * Default constructor. 48 * Default constructor.
49 * 49 *
50 - * @param vNet OpenStack network 50 + * @param osNet OpenStack network
51 - * @param subnet OpenStack subnet 51 + * @param osSubnet OpenStack subnet
52 * @param hosts host and tunnel ip map 52 * @param hosts host and tunnel ip map
53 * @param tenantServices list of tenant service ids 53 * @param tenantServices list of tenant service ids
54 */ 54 */
55 - public CordService(OpenstackNetwork vNet, OpenstackSubnet subnet, 55 + public CordService(Network osNet, Subnet osSubnet,
56 Map<Host, IpAddress> hosts, Set<CordServiceId> tenantServices) { 56 Map<Host, IpAddress> hosts, Set<CordServiceId> tenantServices) {
57 - this.id = CordServiceId.of(vNet.id()); 57 + this.id = CordServiceId.of(osNet.getId());
58 - this.segmentationId = Long.parseLong(vNet.segmentId()); 58 + this.segmentationId = Long.parseLong(osNet.getProviderSegID());
59 - this.serviceType = getServiceType(vNet.name()); 59 + this.serviceType = getServiceType(osNet.getName());
60 - this.serviceIpRange = IpPrefix.valueOf(subnet.cidr()); 60 + this.serviceIpRange = IpPrefix.valueOf(osSubnet.getCidr());
61 - this.serviceIp = IpAddress.valueOf(subnet.gatewayIp()); 61 + this.serviceIp = IpAddress.valueOf(osSubnet.getGateway());
62 this.hosts = hosts; 62 this.hosts = hosts;
63 this.tenantServices = tenantServices; 63 this.tenantServices = tenantServices;
64 } 64 }
......
...@@ -46,10 +46,6 @@ public class CordVtnConfig extends Config<ApplicationId> { ...@@ -46,10 +46,6 @@ public class CordVtnConfig extends Config<ApplicationId> {
46 public static final String LOCAL_MANAGEMENT_IP = "localManagementIp"; 46 public static final String LOCAL_MANAGEMENT_IP = "localManagementIp";
47 public static final String OVSDB_PORT = "ovsdbPort"; 47 public static final String OVSDB_PORT = "ovsdbPort";
48 48
49 - public static final String SSH_PORT = "sshPort";
50 - public static final String SSH_USER = "sshUser";
51 - public static final String SSH_KEY_FILE = "sshKeyFile";
52 -
53 public static final String CORDVTN_NODES = "nodes"; 49 public static final String CORDVTN_NODES = "nodes";
54 public static final String HOSTNAME = "hostname"; 50 public static final String HOSTNAME = "hostname";
55 public static final String HOST_MANAGEMENT_IP = "hostManagementIp"; 51 public static final String HOST_MANAGEMENT_IP = "hostManagementIp";
...@@ -57,6 +53,17 @@ public class CordVtnConfig extends Config<ApplicationId> { ...@@ -57,6 +53,17 @@ public class CordVtnConfig extends Config<ApplicationId> {
57 public static final String DATA_PLANE_INTF = "dataPlaneIntf"; 53 public static final String DATA_PLANE_INTF = "dataPlaneIntf";
58 public static final String BRIDGE_ID = "bridgeId"; 54 public static final String BRIDGE_ID = "bridgeId";
59 55
56 + public static final String SSH = "ssh";
57 + public static final String SSH_PORT = "sshPort";
58 + public static final String SSH_USER = "sshUser";
59 + public static final String SSH_KEY_FILE = "sshKeyFile";
60 +
61 + public static final String OPENSTACK = "openstack";
62 + public static final String OPENSTACK_ENDPOINT = "endpoint";
63 + public static final String OPENSTACK_TENANT = "tenant";
64 + public static final String OPENSTACK_USER = "user";
65 + public static final String OPENSTACK_PASSWORD = "password";
66 +
60 /** 67 /**
61 * Returns the set of nodes read from network config. 68 * Returns the set of nodes read from network config.
62 * 69 *
...@@ -65,15 +72,22 @@ public class CordVtnConfig extends Config<ApplicationId> { ...@@ -65,15 +72,22 @@ public class CordVtnConfig extends Config<ApplicationId> {
65 public Set<CordVtnNode> cordVtnNodes() { 72 public Set<CordVtnNode> cordVtnNodes() {
66 73
67 Set<CordVtnNode> nodes = Sets.newHashSet(); 74 Set<CordVtnNode> nodes = Sets.newHashSet();
68 - JsonNode jsonNodes = object.get(CORDVTN_NODES); 75 +
69 - if (jsonNodes == null) { 76 + JsonNode cordvtnNodes = object.get(CORDVTN_NODES);
77 + if (cordvtnNodes == null) {
70 log.debug("No CORD VTN nodes found"); 78 log.debug("No CORD VTN nodes found");
71 return nodes; 79 return nodes;
72 } 80 }
73 81
74 - for (JsonNode jsonNode : jsonNodes) { 82 + JsonNode sshNode = object.get(SSH);
83 + if (sshNode == null) {
84 + log.warn("SSH information not found");
85 + return nodes;
86 + }
87 +
88 + for (JsonNode cordvtnNode : cordvtnNodes) {
75 try { 89 try {
76 - NetworkAddress hostMgmt = NetworkAddress.valueOf(getConfig(jsonNode, HOST_MANAGEMENT_IP)); 90 + NetworkAddress hostMgmt = NetworkAddress.valueOf(getConfig(cordvtnNode, HOST_MANAGEMENT_IP));
77 NetworkAddress localMgmt = NetworkAddress.valueOf(getConfig(object, LOCAL_MANAGEMENT_IP)); 91 NetworkAddress localMgmt = NetworkAddress.valueOf(getConfig(object, LOCAL_MANAGEMENT_IP));
78 if (hostMgmt.prefix().contains(localMgmt.prefix()) || 92 if (hostMgmt.prefix().contains(localMgmt.prefix()) ||
79 localMgmt.prefix().contains(hostMgmt.prefix())) { 93 localMgmt.prefix().contains(hostMgmt.prefix())) {
...@@ -84,22 +98,22 @@ public class CordVtnConfig extends Config<ApplicationId> { ...@@ -84,22 +98,22 @@ public class CordVtnConfig extends Config<ApplicationId> {
84 Ip4Address hostMgmtIp = hostMgmt.ip().getIp4Address(); 98 Ip4Address hostMgmtIp = hostMgmt.ip().getIp4Address();
85 SshAccessInfo sshInfo = new SshAccessInfo( 99 SshAccessInfo sshInfo = new SshAccessInfo(
86 hostMgmtIp, 100 hostMgmtIp,
87 - TpPort.tpPort(Integer.parseInt(getConfig(object, SSH_PORT))), 101 + TpPort.tpPort(Integer.parseInt(getConfig(sshNode, SSH_PORT))),
88 - getConfig(object, SSH_USER), getConfig(object, SSH_KEY_FILE)); 102 + getConfig(sshNode, SSH_USER), getConfig(sshNode, SSH_KEY_FILE));
89 103
90 - String hostname = getConfig(jsonNode, HOSTNAME); 104 + String hostname = getConfig(cordvtnNode, HOSTNAME);
91 CordVtnNode newNode = new CordVtnNode( 105 CordVtnNode newNode = new CordVtnNode(
92 hostname, hostMgmt, localMgmt, 106 hostname, hostMgmt, localMgmt,
93 - NetworkAddress.valueOf(getConfig(jsonNode, DATA_PLANE_IP)), 107 + NetworkAddress.valueOf(getConfig(cordvtnNode, DATA_PLANE_IP)),
94 TpPort.tpPort(Integer.parseInt(getConfig(object, OVSDB_PORT))), 108 TpPort.tpPort(Integer.parseInt(getConfig(object, OVSDB_PORT))),
95 sshInfo, 109 sshInfo,
96 - DeviceId.deviceId(getConfig(jsonNode, BRIDGE_ID)), 110 + DeviceId.deviceId(getConfig(cordvtnNode, BRIDGE_ID)),
97 - getConfig(jsonNode, DATA_PLANE_INTF), 111 + getConfig(cordvtnNode, DATA_PLANE_INTF),
98 CordVtnNodeState.noState()); 112 CordVtnNodeState.noState());
99 113
100 nodes.add(newNode); 114 nodes.add(newNode);
101 } catch (IllegalArgumentException | NullPointerException e) { 115 } catch (IllegalArgumentException | NullPointerException e) {
102 - log.error("{}", e.toString()); 116 + log.error("{}", e);
103 } 117 }
104 } 118 }
105 119
...@@ -167,5 +181,90 @@ public class CordVtnConfig extends Config<ApplicationId> { ...@@ -167,5 +181,90 @@ public class CordVtnConfig extends Config<ApplicationId> {
167 181
168 return publicGateways; 182 return publicGateways;
169 } 183 }
170 -}
171 184
185 + /**
186 + * Returns OpenStack API access information.
187 + *
188 + * @return openstack config
189 + */
190 + public OpenStackConfig openstackConfig() {
191 + JsonNode jsonNode = object.get(OPENSTACK);
192 + if (jsonNode == null) {
193 + log.error("Failed to get OpenStack configurations");
194 + return null;
195 + }
196 +
197 + try {
198 + return new OpenStackConfig(
199 + jsonNode.path(OPENSTACK_ENDPOINT).asText(),
200 + jsonNode.path(OPENSTACK_TENANT).asText(),
201 + jsonNode.path(OPENSTACK_USER).asText(),
202 + jsonNode.path(OPENSTACK_PASSWORD).asText());
203 + } catch (IllegalArgumentException | NullPointerException e) {
204 + log.error("Failed to get OpenStack configurations");
205 + return null;
206 + }
207 + }
208 +
209 + /**
210 + * Configuration for OpenStack API access.
211 + */
212 + public static class OpenStackConfig {
213 +
214 + private final String endpoint;
215 + private final String tenant;
216 + private final String user;
217 + private final String password;
218 +
219 + /**
220 + * Default constructor.
221 + *
222 + * @param endpoint Keystone endpoint
223 + * @param tenant tenant name
224 + * @param user user name
225 + * @param password passwowrd
226 + */
227 + public OpenStackConfig(String endpoint, String tenant, String user, String password) {
228 + this.endpoint = endpoint;
229 + this.tenant = tenant;
230 + this.user = user;
231 + this.password = password;
232 + }
233 +
234 + /**
235 + * Returns OpenStack API endpoint.
236 + *
237 + * @return endpoint
238 + */
239 + public String endpoint() {
240 + return this.endpoint;
241 + }
242 +
243 + /**
244 + * Returns OpenStack tenant name.
245 + *
246 + * @return tenant name
247 + */
248 + public String tenant() {
249 + return this.tenant;
250 + }
251 +
252 + /**
253 + * Returns OpenStack user.
254 + *
255 + * @return user name
256 + */
257 + public String user() {
258 + return this.user;
259 + }
260 +
261 + /**
262 + * Returns OpenStack password for the user.
263 + *
264 + * @return password
265 + */
266 + public String password() {
267 + return this.password;
268 + }
269 + }
270 +}
......
...@@ -67,10 +67,13 @@ import org.onosproject.net.packet.PacketProcessor; ...@@ -67,10 +67,13 @@ import org.onosproject.net.packet.PacketProcessor;
67 import org.onosproject.net.packet.PacketService; 67 import org.onosproject.net.packet.PacketService;
68 import org.onosproject.net.provider.AbstractProvider; 68 import org.onosproject.net.provider.AbstractProvider;
69 import org.onosproject.net.provider.ProviderId; 69 import org.onosproject.net.provider.ProviderId;
70 -import org.onosproject.openstackinterface.OpenstackInterfaceService; 70 +
71 -import org.onosproject.openstackinterface.OpenstackNetwork; 71 +import org.openstack4j.api.OSClient;
72 -import org.onosproject.openstackinterface.OpenstackPort; 72 +import org.openstack4j.api.exceptions.AuthenticationException;
73 -import org.onosproject.openstackinterface.OpenstackSubnet; 73 +import org.openstack4j.model.identity.Access;
74 +import org.openstack4j.model.network.Network;
75 +import org.openstack4j.model.network.Subnet;
76 +import org.openstack4j.openstack.OSFactory;
74 import org.slf4j.Logger; 77 import org.slf4j.Logger;
75 78
76 import java.util.List; 79 import java.util.List;
...@@ -130,9 +133,6 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -130,9 +133,6 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
130 protected GroupService groupService; 133 protected GroupService groupService;
131 134
132 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 135 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
133 - protected OpenstackInterfaceService openstackService;
134 -
135 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
136 protected DhcpService dhcpService; 136 protected DhcpService dhcpService;
137 137
138 private final ConfigFactory configFactory = 138 private final ConfigFactory configFactory =
...@@ -165,6 +165,8 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -165,6 +165,8 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
165 private HostProviderService hostProvider; 165 private HostProviderService hostProvider;
166 private CordVtnRuleInstaller ruleInstaller; 166 private CordVtnRuleInstaller ruleInstaller;
167 private CordVtnArpProxy arpProxy; 167 private CordVtnArpProxy arpProxy;
168 +
169 + private volatile Access osAccess = null;
168 private volatile MacAddress privateGatewayMac = MacAddress.NONE; 170 private volatile MacAddress privateGatewayMac = MacAddress.NONE;
169 171
170 /** 172 /**
...@@ -250,20 +252,26 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -250,20 +252,26 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
250 252
251 @Override 253 @Override
252 public void addServiceVm(CordVtnNode node, ConnectPoint connectPoint) { 254 public void addServiceVm(CordVtnNode node, ConnectPoint connectPoint) {
255 + checkNotNull(osAccess, "OpenStack access is not set");
256 +
257 + OSClient osClient = OSFactory.clientFromAccess(osAccess);
253 Port port = deviceService.getPort(connectPoint.deviceId(), connectPoint.port()); 258 Port port = deviceService.getPort(connectPoint.deviceId(), connectPoint.port());
254 - OpenstackPort vPort = openstackService.port(port); 259 + org.openstack4j.model.network.Port osPort = osClient.networking().port().list()
255 - if (vPort == null) { 260 + .stream()
256 - log.warn("Failed to get OpenstackPort for {}", getPortName(port)); 261 + .filter(p -> p.getId().contains(getPortName(port).substring(3)))
262 + .findFirst().orElse(null);
263 + if (osPort == null) {
264 + log.warn("Failed to get OpenStack port for {}", getPortName(port));
257 return; 265 return;
258 } 266 }
259 267
260 - MacAddress mac = vPort.macAddress(); 268 + MacAddress mac = MacAddress.valueOf(osPort.getMacAddress());
261 HostId hostId = HostId.hostId(mac); 269 HostId hostId = HostId.hostId(mac);
262 270
263 Host existingHost = hostService.getHost(hostId); 271 Host existingHost = hostService.getHost(hostId);
264 if (existingHost != null) { 272 if (existingHost != null) {
265 String serviceId = existingHost.annotations().value(SERVICE_ID); 273 String serviceId = existingHost.annotations().value(SERVICE_ID);
266 - if (serviceId == null || !serviceId.equals(vPort.networkId())) { 274 + if (serviceId == null || !serviceId.equals(osPort.getNetworkId())) {
267 // this host is not injected by cordvtn or a stale host, remove it 275 // this host is not injected by cordvtn or a stale host, remove it
268 hostProvider.hostVanished(existingHost.id()); 276 hostProvider.hostVanished(existingHost.id());
269 } 277 }
...@@ -273,15 +281,18 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -273,15 +281,18 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
273 // event so that the flow rule population for this host can happen. 281 // event so that the flow rule population for this host can happen.
274 // This ensures refreshing data plane by pushing network config always make 282 // This ensures refreshing data plane by pushing network config always make
275 // the data plane synced. 283 // the data plane synced.
276 - Set<IpAddress> fixedIp = Sets.newHashSet(vPort.fixedIps().values()); 284 + Set<IpAddress> fixedIps = osPort.getFixedIps().stream()
285 + .map(ip -> IpAddress.valueOf(ip.getIpAddress()))
286 + .collect(Collectors.toSet());
287 +
277 DefaultAnnotations.Builder annotations = DefaultAnnotations.builder() 288 DefaultAnnotations.Builder annotations = DefaultAnnotations.builder()
278 - .set(SERVICE_ID, vPort.networkId()) 289 + .set(SERVICE_ID, osPort.getNetworkId())
279 - .set(OPENSTACK_PORT_ID, vPort.id()) 290 + .set(OPENSTACK_PORT_ID, osPort.getId())
280 .set(DATA_PLANE_IP, node.dpIp().ip().toString()) 291 .set(DATA_PLANE_IP, node.dpIp().ip().toString())
281 .set(DATA_PLANE_INTF, node.dpIntf()) 292 .set(DATA_PLANE_INTF, node.dpIntf())
282 .set(CREATED_TIME, String.valueOf(System.currentTimeMillis())); 293 .set(CREATED_TIME, String.valueOf(System.currentTimeMillis()));
283 294
284 - String serviceVlan = getServiceVlan(vPort); 295 + String serviceVlan = getServiceVlan(osPort);
285 if (serviceVlan != null) { 296 if (serviceVlan != null) {
286 annotations.set(S_TAG, serviceVlan); 297 annotations.set(S_TAG, serviceVlan);
287 } 298 }
...@@ -290,7 +301,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -290,7 +301,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
290 mac, 301 mac,
291 VlanId.NONE, 302 VlanId.NONE,
292 new HostLocation(connectPoint, System.currentTimeMillis()), 303 new HostLocation(connectPoint, System.currentTimeMillis()),
293 - fixedIp, 304 + fixedIps,
294 annotations.build()); 305 annotations.build());
295 306
296 hostProvider.hostDetected(hostId, hostDesc, false); 307 hostProvider.hostDetected(hostId, hostDesc, false);
...@@ -365,21 +376,30 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -365,21 +376,30 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
365 * @return map of ip and mac address, or empty map 376 * @return map of ip and mac address, or empty map
366 */ 377 */
367 private Map<IpAddress, MacAddress> getSubscriberGateways(Host vSgHost) { 378 private Map<IpAddress, MacAddress> getSubscriberGateways(Host vSgHost) {
368 - String vPortId = vSgHost.annotations().value(OPENSTACK_PORT_ID); 379 + checkNotNull(osAccess, "OpenStack access is not set");
380 +
381 + String osPortId = vSgHost.annotations().value(OPENSTACK_PORT_ID);
369 String serviceVlan = vSgHost.annotations().value(S_TAG); 382 String serviceVlan = vSgHost.annotations().value(S_TAG);
370 383
371 - OpenstackPort vPort = openstackService.port(vPortId); 384 + OSClient osClient = OSFactory.clientFromAccess(osAccess);
372 - if (vPort == null) { 385 + org.openstack4j.model.network.Port osPort = osClient.networking().port().get(osPortId);
373 - log.warn("Failed to get OpenStack port {} for VM {}", vPortId, vSgHost.id()); 386 + if (osPort == null) {
387 + log.warn("Failed to get OpenStack port {} for VM {}", osPortId, vSgHost.id());
374 return Maps.newHashMap(); 388 return Maps.newHashMap();
375 } 389 }
376 390
377 - if (!serviceVlan.equals(getServiceVlan(vPort))) { 391 + if (!serviceVlan.equals(getServiceVlan(osPort))) {
378 - log.error("Host({}) s-tag does not match with vPort s-tag", vSgHost.id()); 392 + log.error("Host({}) s-tag does not match with OpenStack port s-tag", vSgHost.id());
379 return Maps.newHashMap(); 393 return Maps.newHashMap();
380 } 394 }
381 395
382 - return vPort.allowedAddressPairs(); 396 + Map<IpAddress, MacAddress> addressPairs = Maps.newHashMap();
397 + osPort.getAllowedAddressPairs()
398 + .stream().forEach(p -> addressPairs.put(
399 + IpAddress.valueOf(p.getIpAddress()),
400 + MacAddress.valueOf(p.getMacAddress())));
401 +
402 + return addressPairs;
383 } 403 }
384 404
385 /** 405 /**
...@@ -389,16 +409,20 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -389,16 +409,20 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
389 * @return cord service, or null if it fails to get network from OpenStack 409 * @return cord service, or null if it fails to get network from OpenStack
390 */ 410 */
391 private CordService getCordService(CordServiceId serviceId) { 411 private CordService getCordService(CordServiceId serviceId) {
392 - OpenstackNetwork vNet = openstackService.network(serviceId.id()); 412 + checkNotNull(osAccess, "OpenStack access is not set");
393 - if (vNet == null) { 413 +
414 + OSClient osClient = OSFactory.clientFromAccess(osAccess);
415 + Network osNet = osClient.networking().network().get(serviceId.id());
416 + if (osNet == null) {
394 log.warn("Couldn't find OpenStack network for service {}", serviceId.id()); 417 log.warn("Couldn't find OpenStack network for service {}", serviceId.id());
395 return null; 418 return null;
396 } 419 }
397 420
398 - OpenstackSubnet subnet = vNet.subnets().stream() 421 + // here it assumes all cord service networks has only one subnet
422 + Subnet osSubnet = osNet.getNeutronSubnets().stream()
399 .findFirst() 423 .findFirst()
400 .orElse(null); 424 .orElse(null);
401 - if (subnet == null) { 425 + if (osSubnet == null) {
402 log.warn("Couldn't find OpenStack subnet for service {}", serviceId.id()); 426 log.warn("Couldn't find OpenStack subnet for service {}", serviceId.id());
403 return null; 427 return null;
404 } 428 }
...@@ -406,39 +430,40 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -406,39 +430,40 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
406 Set<CordServiceId> tServices = Sets.newHashSet(); 430 Set<CordServiceId> tServices = Sets.newHashSet();
407 // TODO get tenant services from XOS 431 // TODO get tenant services from XOS
408 432
409 - Map<Host, IpAddress> hosts = getHostsWithOpenstackNetwork(vNet) 433 + Map<Host, IpAddress> hosts = getHostsWithOpenstackNetwork(osNet)
410 .stream() 434 .stream()
411 .collect(Collectors.toMap(host -> host, this::getTunnelIp)); 435 .collect(Collectors.toMap(host -> host, this::getTunnelIp));
412 436
413 - return new CordService(vNet, subnet, hosts, tServices); 437 + return new CordService(osNet, osSubnet, hosts, tServices);
414 } 438 }
415 439
416 /** 440 /**
417 * Returns CordService by OpenStack network. 441 * Returns CordService by OpenStack network.
418 * 442 *
419 - * @param vNet OpenStack network 443 + * @param osNet OpenStack network
420 * @return cord service 444 * @return cord service
421 */ 445 */
422 - private CordService getCordService(OpenstackNetwork vNet) { 446 + private CordService getCordService(Network osNet) {
423 - checkNotNull(vNet); 447 + checkNotNull(osNet);
424 448
425 - CordServiceId serviceId = CordServiceId.of(vNet.id()); 449 + CordServiceId serviceId = CordServiceId.of(osNet.getId());
426 - OpenstackSubnet subnet = vNet.subnets().stream() 450 + // here it assumes all cord service networks has only one subnet
451 + Subnet osSubnet = osNet.getNeutronSubnets().stream()
427 .findFirst() 452 .findFirst()
428 .orElse(null); 453 .orElse(null);
429 - if (subnet == null) { 454 + if (osSubnet == null) {
430 - log.warn("Couldn't find OpenStack subnet for service {}", serviceId); 455 + log.warn("Couldn't find OpenStack subnet for service {}", serviceId.id());
431 return null; 456 return null;
432 } 457 }
433 458
434 Set<CordServiceId> tServices = Sets.newHashSet(); 459 Set<CordServiceId> tServices = Sets.newHashSet();
435 // TODO get tenant services from XOS 460 // TODO get tenant services from XOS
436 461
437 - Map<Host, IpAddress> hosts = getHostsWithOpenstackNetwork(vNet) 462 + Map<Host, IpAddress> hosts = getHostsWithOpenstackNetwork(osNet)
438 .stream() 463 .stream()
439 .collect(Collectors.toMap(host -> host, this::getTunnelIp)); 464 .collect(Collectors.toMap(host -> host, this::getTunnelIp));
440 465
441 - return new CordService(vNet, subnet, hosts, tServices); 466 + return new CordService(osNet, osSubnet, hosts, tServices);
442 } 467 }
443 468
444 /** 469 /**
...@@ -465,14 +490,15 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -465,14 +490,15 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
465 /** 490 /**
466 * Returns s-tag from a given OpenStack port. 491 * Returns s-tag from a given OpenStack port.
467 * 492 *
468 - * @param vPort openstack port 493 + * @param osPort openstack port
469 * @return s-tag string 494 * @return s-tag string
470 */ 495 */
471 - private String getServiceVlan(OpenstackPort vPort) { 496 + private String getServiceVlan(org.openstack4j.model.network.Port osPort) {
472 - checkNotNull(vPort); 497 + checkNotNull(osPort);
473 498
474 - if (vPort.name() != null && vPort.name().startsWith(S_TAG)) { 499 + String portName = osPort.getName();
475 - return vPort.name().split("-")[1]; 500 + if (portName != null && portName.startsWith(S_TAG)) {
501 + return portName.split("-")[1];
476 } else { 502 } else {
477 return null; 503 return null;
478 } 504 }
...@@ -491,15 +517,15 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -491,15 +517,15 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
491 /** 517 /**
492 * Returns hosts associated with a given OpenStack network. 518 * Returns hosts associated with a given OpenStack network.
493 * 519 *
494 - * @param vNet openstack network 520 + * @param osNet openstack network
495 * @return set of hosts 521 * @return set of hosts
496 */ 522 */
497 - private Set<Host> getHostsWithOpenstackNetwork(OpenstackNetwork vNet) { 523 + private Set<Host> getHostsWithOpenstackNetwork(Network osNet) {
498 - checkNotNull(vNet); 524 + checkNotNull(osNet);
499 525
500 - String vNetId = vNet.id(); 526 + String osNetId = osNet.getId();
501 return StreamSupport.stream(hostService.getHosts().spliterator(), false) 527 return StreamSupport.stream(hostService.getHosts().spliterator(), false)
502 - .filter(host -> Objects.equals(vNetId, getServiceId(host))) 528 + .filter(host -> Objects.equals(osNetId, getServiceId(host)))
503 .collect(Collectors.toSet()); 529 .collect(Collectors.toSet());
504 } 530 }
505 531
...@@ -529,21 +555,24 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -529,21 +555,24 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
529 * @param host host 555 * @param host host
530 */ 556 */
531 private void serviceVmAdded(Host host) { 557 private void serviceVmAdded(Host host) {
558 + checkNotNull(osAccess, "OpenStack access is not set");
559 +
532 String serviceVlan = host.annotations().value(S_TAG); 560 String serviceVlan = host.annotations().value(S_TAG);
533 if (serviceVlan != null) { 561 if (serviceVlan != null) {
534 virtualSubscriberGatewayAdded(host, serviceVlan); 562 virtualSubscriberGatewayAdded(host, serviceVlan);
535 } 563 }
536 564
537 - String vNetId = host.annotations().value(SERVICE_ID); 565 + String osNetId = host.annotations().value(SERVICE_ID);
538 - if (vNetId == null) { 566 + if (osNetId == null) {
539 // ignore this host, it is not the service VM, or it's a vSG 567 // ignore this host, it is not the service VM, or it's a vSG
540 return; 568 return;
541 } 569 }
542 570
543 - OpenstackNetwork vNet = openstackService.network(vNetId); 571 + OSClient osClient = OSFactory.clientFromAccess(osAccess);
544 - if (vNet == null) { 572 + Network osNet = osClient.networking().network().get(osNetId);
573 + if (osNet == null) {
545 log.warn("Failed to get OpenStack network {} for VM {}.", 574 log.warn("Failed to get OpenStack network {} for VM {}.",
546 - vNetId, host.id()); 575 + osNetId, host.id());
547 return; 576 return;
548 } 577 }
549 578
...@@ -551,7 +580,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -551,7 +580,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
551 host.mac(), 580 host.mac(),
552 host.ipAddresses().stream().findFirst().get()); 581 host.ipAddresses().stream().findFirst().get());
553 582
554 - CordService service = getCordService(vNet); 583 + CordService service = getCordService(osNet);
555 if (service == null) { 584 if (service == null) {
556 return; 585 return;
557 } 586 }
...@@ -573,7 +602,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -573,7 +602,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
573 } 602 }
574 603
575 registerDhcpLease(host, service); 604 registerDhcpLease(host, service);
576 - ruleInstaller.populateBasicConnectionRules(host, getTunnelIp(host), vNet); 605 + ruleInstaller.populateBasicConnectionRules(host, getTunnelIp(host), osNet);
577 } 606 }
578 607
579 /** 608 /**
...@@ -582,21 +611,24 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -582,21 +611,24 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
582 * @param host host 611 * @param host host
583 */ 612 */
584 private void serviceVmRemoved(Host host) { 613 private void serviceVmRemoved(Host host) {
614 + checkNotNull(osAccess, "OpenStack access is not set");
615 +
585 String serviceVlan = host.annotations().value(S_TAG); 616 String serviceVlan = host.annotations().value(S_TAG);
586 if (serviceVlan != null) { 617 if (serviceVlan != null) {
587 virtualSubscriberGatewayRemoved(host); 618 virtualSubscriberGatewayRemoved(host);
588 } 619 }
589 620
590 - String vNetId = host.annotations().value(SERVICE_ID); 621 + String osNetId = host.annotations().value(SERVICE_ID);
591 - if (vNetId == null) { 622 + if (osNetId == null) {
592 // ignore it, it's not the service VM or it's a vSG 623 // ignore it, it's not the service VM or it's a vSG
593 return; 624 return;
594 } 625 }
595 626
596 - OpenstackNetwork vNet = openstackService.network(vNetId); 627 + OSClient osClient = OSFactory.clientFromAccess(osAccess);
597 - if (vNet == null) { 628 + Network osNet = osClient.networking().network().get(osNetId);
629 + if (osNet == null) {
598 log.warn("Failed to get OpenStack network {} for VM {}", 630 log.warn("Failed to get OpenStack network {} for VM {}",
599 - vNetId, host.id()); 631 + osNetId, host.id());
600 return; 632 return;
601 } 633 }
602 634
...@@ -607,7 +639,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -607,7 +639,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
607 ruleInstaller.removeBasicConnectionRules(host); 639 ruleInstaller.removeBasicConnectionRules(host);
608 dhcpService.removeStaticMapping(host.mac()); 640 dhcpService.removeStaticMapping(host.mac());
609 641
610 - CordService service = getCordService(vNet); 642 + CordService service = getCordService(osNet);
611 if (service == null) { 643 if (service == null) {
612 return; 644 return;
613 } 645 }
...@@ -617,7 +649,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -617,7 +649,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
617 ruleInstaller.removeManagementNetworkRules(host, service); 649 ruleInstaller.removeManagementNetworkRules(host, service);
618 break; 650 break;
619 case PRIVATE: 651 case PRIVATE:
620 - if (getHostsWithOpenstackNetwork(vNet).isEmpty()) { 652 + if (getHostsWithOpenstackNetwork(osNet).isEmpty()) {
621 arpProxy.removeGateway(service.serviceIp()); 653 arpProxy.removeGateway(service.serviceIp());
622 } 654 }
623 case PUBLIC: 655 case PUBLIC:
...@@ -723,13 +755,38 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -723,13 +755,38 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
723 .stream() 755 .stream()
724 .forEach(entry -> { 756 .forEach(entry -> {
725 arpProxy.addGateway(entry.getKey(), entry.getValue()); 757 arpProxy.addGateway(entry.getKey(), entry.getValue());
726 - log.info("Added public gateway IP {}, MAC {}", 758 + log.debug("Added public gateway IP {}, MAC {}",
727 - entry.getKey().toString(), entry.getValue().toString()); 759 + entry.getKey().toString(), entry.getValue().toString());
728 }); 760 });
729 // TODO notice gateway MAC change to VMs holds this gateway IP 761 // TODO notice gateway MAC change to VMs holds this gateway IP
730 } 762 }
731 763
732 /** 764 /**
765 + * Sets OpenStack access information.
766 + * Access is the entity returned when authenticated and provides a singleton client
767 + * between multiple threads.
768 + *
769 + * @param osConfig openstack config
770 + */
771 + private void setOpenstackAccess(CordVtnConfig.OpenStackConfig osConfig) {
772 + log.debug("Get OpenStack access with Endpoint: {} Tenant: {} User: {} Passwd: {}",
773 + osConfig.endpoint(),
774 + osConfig.tenant(),
775 + osConfig.user(),
776 + osConfig.password());
777 + try {
778 + osAccess = OSFactory.builder()
779 + .endpoint(osConfig.endpoint())
780 + .credentials(osConfig.user(), osConfig.password())
781 + .tenantName(osConfig.tenant())
782 + .authenticate()
783 + .getAccess();
784 + } catch (AuthenticationException e) {
785 + log.error("Failed to get OpenStack Access");
786 + }
787 + }
788 +
789 + /**
733 * Updates configurations. 790 * Updates configurations.
734 */ 791 */
735 private void readConfiguration() { 792 private void readConfiguration() {
...@@ -739,9 +796,10 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -739,9 +796,10 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
739 return; 796 return;
740 } 797 }
741 798
799 + setOpenstackAccess(config.openstackConfig());
742 setPrivateGatewayMac(config.privateGatewayMac()); 800 setPrivateGatewayMac(config.privateGatewayMac());
743 setPublicGatewayMac(config.publicGateways()); 801 setPublicGatewayMac(config.publicGateways());
744 - } 802 + }
745 803
746 private class InternalHostListener implements HostListener { 804 private class InternalHostListener implements HostListener {
747 805
......
...@@ -75,8 +75,8 @@ import org.onosproject.net.group.GroupBuckets; ...@@ -75,8 +75,8 @@ import org.onosproject.net.group.GroupBuckets;
75 import org.onosproject.net.group.GroupDescription; 75 import org.onosproject.net.group.GroupDescription;
76 import org.onosproject.net.group.GroupKey; 76 import org.onosproject.net.group.GroupKey;
77 import org.onosproject.net.group.GroupService; 77 import org.onosproject.net.group.GroupService;
78 -import org.onosproject.openstackinterface.OpenstackNetwork; 78 +import org.openstack4j.model.network.Network;
79 -import org.onosproject.openstackinterface.OpenstackSubnet; 79 +import org.openstack4j.model.network.Subnet;
80 import org.slf4j.Logger; 80 import org.slf4j.Logger;
81 81
82 import java.util.ArrayList; 82 import java.util.ArrayList;
...@@ -190,30 +190,31 @@ public class CordVtnRuleInstaller { ...@@ -190,30 +190,31 @@ public class CordVtnRuleInstaller {
190 * 190 *
191 * @param host host 191 * @param host host
192 * @param tunnelIp tunnel ip 192 * @param tunnelIp tunnel ip
193 - * @param vNet openstack network 193 + * @param osNet openstack network
194 */ 194 */
195 - public void populateBasicConnectionRules(Host host, IpAddress tunnelIp, OpenstackNetwork vNet) { 195 + public void populateBasicConnectionRules(Host host, IpAddress tunnelIp, Network osNet) {
196 checkNotNull(host); 196 checkNotNull(host);
197 - checkNotNull(vNet); 197 + checkNotNull(osNet);
198 198
199 DeviceId deviceId = host.location().deviceId(); 199 DeviceId deviceId = host.location().deviceId();
200 PortNumber inPort = host.location().port(); 200 PortNumber inPort = host.location().port();
201 MacAddress dstMac = host.mac(); 201 MacAddress dstMac = host.mac();
202 IpAddress hostIp = host.ipAddresses().stream().findFirst().get(); 202 IpAddress hostIp = host.ipAddresses().stream().findFirst().get();
203 - long tunnelId = Long.parseLong(vNet.segmentId()); 203 + long tunnelId = Long.parseLong(osNet.getProviderSegID());
204 204
205 - OpenstackSubnet subnet = vNet.subnets().stream() 205 + Subnet osSubnet = osNet.getNeutronSubnets().stream()
206 .findFirst() 206 .findFirst()
207 .orElse(null); 207 .orElse(null);
208 208
209 - if (subnet == null) { 209 + if (osSubnet == null) {
210 log.error("Failed to get subnet for {}", host.id()); 210 log.error("Failed to get subnet for {}", host.id());
211 return; 211 return;
212 } 212 }
213 + Ip4Prefix cidr = Ip4Prefix.valueOf(osSubnet.getCidr());
213 214
214 populateLocalInPortRule(deviceId, inPort, hostIp); 215 populateLocalInPortRule(deviceId, inPort, hostIp);
215 - populateDirectAccessRule(Ip4Prefix.valueOf(subnet.cidr()), Ip4Prefix.valueOf(subnet.cidr())); 216 + populateDirectAccessRule(cidr, cidr);
216 - populateServiceIsolationRule(Ip4Prefix.valueOf(subnet.cidr())); 217 + populateServiceIsolationRule(cidr);
217 populateDstIpRule(deviceId, inPort, dstMac, hostIp, tunnelId, tunnelIp); 218 populateDstIpRule(deviceId, inPort, dstMac, hostIp, tunnelId, tunnelIp);
218 populateTunnelInRule(deviceId, inPort, dstMac, tunnelId); 219 populateTunnelInRule(deviceId, inPort, dstMac, tunnelId);
219 } 220 }
......
...@@ -47,6 +47,10 @@ ...@@ -47,6 +47,10 @@
47 <param-name>javax.ws.rs.Application</param-name> 47 <param-name>javax.ws.rs.Application</param-name>
48 <param-value>org.onosproject.cordvtn.rest.CordVtnWebApplication</param-value> 48 <param-value>org.onosproject.cordvtn.rest.CordVtnWebApplication</param-value>
49 </init-param> 49 </init-param>
50 + <init-param>
51 + <param-name>jersey.config.server.disableAutoDiscovery</param-name>
52 + <param-value>true</param-value>
53 + </init-param>
50 <load-on-startup>1</load-on-startup> 54 <load-on-startup>1</load-on-startup>
51 </servlet> 55 </servlet>
52 56
......