CORD-506 Apply existing service dependency when VM is detected
Change-Id: Ib0872c823347bfb6091d6c5f872657f10b7b1083
diff --git a/src/main/java/org/onosproject/cordvtn/impl/CordVtn.java b/src/main/java/org/onosproject/cordvtn/impl/CordVtn.java
index 61f37b5..f7039c3 100644
--- a/src/main/java/org/onosproject/cordvtn/impl/CordVtn.java
+++ b/src/main/java/org/onosproject/cordvtn/impl/CordVtn.java
@@ -30,6 +30,7 @@
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.cordvtn.api.CordService;
+import org.onosproject.cordvtn.api.CordService.ServiceType;
import org.onosproject.cordvtn.api.CordServiceId;
import org.onosproject.cordvtn.api.CordVtnConfig;
import org.onosproject.cordvtn.api.CordVtnNode;
@@ -66,6 +67,8 @@
import org.onosproject.net.packet.PacketService;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
+import org.onosproject.xosclient.api.XosAccess;
+import org.onosproject.xosclient.api.XosClientService;
import org.openstack4j.api.OSClient;
import org.openstack4j.api.exceptions.AuthenticationException;
import org.openstack4j.model.identity.Access;
@@ -85,6 +88,7 @@
import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.cordvtn.api.CordService.getServiceType;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -130,6 +134,9 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DhcpService dhcpService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected XosClientService xosClient;
+
private final ConfigFactory configFactory =
new ConfigFactory(SubjectFactories.APP_SUBJECT_FACTORY, CordVtnConfig.class, "cordvtn") {
@Override
@@ -412,23 +419,7 @@
return null;
}
- // here it assumes all cord service networks has only one subnet
- Subnet osSubnet = osNet.getNeutronSubnets().stream()
- .findFirst()
- .orElse(null);
- if (osSubnet == null) {
- log.warn("Couldn't find OpenStack subnet for service {}", serviceId.id());
- return null;
- }
-
- Set<CordServiceId> tServices = Sets.newHashSet();
- // TODO get tenant services from XOS
-
- Map<Host, IpAddress> hosts = getHostsWithOpenstackNetwork(osNet)
- .stream()
- .collect(Collectors.toMap(host -> host, this::getTunnelIp));
-
- return new CordService(osNet, osSubnet, hosts, tServices);
+ return getCordService(osNet);
}
/**
@@ -450,14 +441,28 @@
return null;
}
- Set<CordServiceId> tServices = Sets.newHashSet();
- // TODO get tenant services from XOS
-
Map<Host, IpAddress> hosts = getHostsWithOpenstackNetwork(osNet)
.stream()
.collect(Collectors.toMap(host -> host, this::getTunnelIp));
- return new CordService(osNet, osSubnet, hosts, tServices);
+ ServiceType serviceType = getServiceType(osNet.getName());
+ // allows working without XOS for now
+ Set<CordServiceId> tServices = Sets.newHashSet();
+ Set<CordServiceId> pServices = Sets.newHashSet();
+
+ if (xosClient.access() != null && serviceType != ServiceType.MANAGEMENT) {
+ tServices = xosClient.vtnServiceApi().getTenantServices(serviceId.id())
+ .stream()
+ .map(CordServiceId::of)
+ .collect(Collectors.toSet());
+
+ pServices = xosClient.vtnServiceApi().getProviderServices(serviceId.id())
+ .stream()
+ .map(CordServiceId::of)
+ .collect(Collectors.toSet());
+ }
+
+ return new CordService(osNet, osSubnet, hosts, tServices, pServices);
}
/**
@@ -576,6 +581,7 @@
CordService service = getCordService(osNet);
if (service == null) {
+ log.warn("Failed to get CordService for {}", osNet.getName());
return;
}
@@ -587,7 +593,12 @@
arpProxy.addGateway(service.serviceIp(), privateGatewayMac);
case PUBLIC:
default:
- // TODO check if the service needs an update on its group buckets after done CORD-433
+ // TODO get bidirectional information from XOS once XOS supports
+ service.tenantServices().stream().forEach(
+ tServiceId -> createServiceDependency(tServiceId, service.id(), true));
+ service.providerServices().stream().forEach(
+ pServiceId -> createServiceDependency(service.id(), pServiceId, true));
+
ruleInstaller.updateServiceGroup(service);
// sends gratuitous ARP here for the case of adding existing VMs
// when ONOS or cordvtn app is restarted
@@ -648,8 +659,9 @@
}
case PUBLIC:
default:
- // TODO check if the service needs an update on its group buckets after done CORD-433
- ruleInstaller.updateServiceGroup(service);
+ if (!service.tenantServices().isEmpty()) {
+ ruleInstaller.updateServiceGroup(service);
+ }
break;
}
}
@@ -717,6 +729,8 @@
* @param newMac mac address to update
*/
private void setPrivateGatewayMac(MacAddress newMac) {
+ checkNotNull(osAccess, "OpenStack access is not set");
+
if (newMac == null || newMac.equals(privateGatewayMac)) {
// no updates, do nothing
return;
@@ -725,13 +739,11 @@
privateGatewayMac = newMac;
log.debug("Set service gateway MAC address to {}", privateGatewayMac.toString());
- // TODO get existing service list from XOS and replace the loop below
- Set<String> vNets = Sets.newHashSet();
- hostService.getHosts().forEach(host -> vNets.add(host.annotations().value(SERVICE_ID)));
- vNets.remove(null);
+ OSClient osClient = OSFactory.clientFromAccess(osAccess);
+ List<Network> vNets = Lists.newArrayList(osClient.networking().network().list().iterator());
vNets.stream().forEach(vNet -> {
- CordService service = getCordService(CordServiceId.of(vNet));
+ CordService service = getCordService(vNet);
if (service != null) {
arpProxy.addGateway(service.serviceIp(), privateGatewayMac);
arpProxy.sendGratuitousArpForGateway(service.serviceIp(), service.hosts().keySet());
@@ -763,6 +775,8 @@
* @param osConfig openstack config
*/
private void setOpenstackAccess(CordVtnConfig.OpenStackConfig osConfig) {
+ checkNotNull(osConfig, "OpenStack access is not configured");
+
log.debug("Get OpenStack access with Endpoint: {} Tenant: {} User: {} Passwd: {}",
osConfig.endpoint(),
osConfig.tenant(),
@@ -781,6 +795,22 @@
}
/**
+ * Sets XOS access information.
+ *
+ * @param xosAccess xos access
+ */
+ private void setXosAccess(XosAccess xosAccess) {
+ checkNotNull(xosAccess, "XOS access is not configured");
+
+ log.debug("Set XOS access with Endpoint: {} User: {} Passwd: {}",
+ xosAccess.endpoint(),
+ xosAccess.username(),
+ xosAccess.password());
+
+ xosClient.setAccess(xosAccess);
+ }
+
+ /**
* Updates configurations.
*/
private void readConfiguration() {
@@ -790,6 +820,7 @@
return;
}
+ setXosAccess(config.xosAccess());
setOpenstackAccess(config.openstackConfig());
setPrivateGatewayMac(config.privateGatewayMac());
setPublicGatewayMac(config.publicGateways());
diff --git a/src/main/java/org/onosproject/cordvtn/impl/CordVtnRuleInstaller.java b/src/main/java/org/onosproject/cordvtn/impl/CordVtnRuleInstaller.java
index 5914b71..823a5b1 100644
--- a/src/main/java/org/onosproject/cordvtn/impl/CordVtnRuleInstaller.java
+++ b/src/main/java/org/onosproject/cordvtn/impl/CordVtnRuleInstaller.java
@@ -282,12 +282,12 @@
GroupId groupId = createServiceGroup(deviceId, pService);
outGroups.put(deviceId, groupId);
- Set<PortNumber> vms = tService.hosts().keySet()
+ Set<PortNumber> tServiceVms = tService.hosts().keySet()
.stream()
.filter(host -> host.location().deviceId().equals(deviceId))
.map(host -> host.location().port())
.collect(Collectors.toSet());
- inPorts.put(deviceId, vms);
+ inPorts.put(deviceId, tServiceVms);
});
populateIndirectAccessRule(srcRange, serviceIp, outGroups);