Support control plane recovery from failure for kubevirt networking
Change-Id: I8ac901cde85321f20b95f0d144a21d1a69d8026b
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtIpPool.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtIpPool.java
index fb2906e..9cc3066 100644
--- a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtIpPool.java
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtIpPool.java
@@ -117,6 +117,27 @@
}
/**
+ * Reserves the given IP address.
+ *
+ * @param ip IP address to be reserved
+ * @return result for IP address reservation
+ */
+ public synchronized boolean reserveIp(IpAddress ip) {
+ if (availableIps.size() <= 0) {
+ return false;
+ }
+
+ if (allocatedIps.contains(ip) || !availableIps.contains(ip)) {
+ return false;
+ }
+
+ availableIps.remove(ip);
+ allocatedIps.add(ip);
+
+ return true;
+ }
+
+ /**
* Releases the given IP address.
*
* @param ip IP address to be released
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtNetworkAdminService.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtNetworkAdminService.java
index aeabd84..a8fbf34 100644
--- a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtNetworkAdminService.java
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtNetworkAdminService.java
@@ -49,6 +49,15 @@
IpAddress allocateIp(String networkId);
/**
+ * Reserve the given IP address.
+ *
+ * @param networkId network identifier
+ * @param ip IP address to be reserved
+ * @return reserve result
+ */
+ boolean reserveIp(String networkId, IpAddress ip);
+
+ /**
* Release the existing IP address.
*
* @param networkId network identifier
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtNetworkManager.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtNetworkManager.java
index d761ff7..cb00052 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtNetworkManager.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtNetworkManager.java
@@ -15,7 +15,6 @@
*/
package org.onosproject.kubevirtnetworking.impl;
-
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import org.onlab.packet.IpAddress;
@@ -146,6 +145,22 @@
}
@Override
+ public boolean reserveIp(String networkId, IpAddress ip) {
+ checkArgument(!Strings.isNullOrEmpty(networkId), ERR_NULL_NETWORK_ID);
+ checkArgument(ip != null, ERR_NULL_IP);
+
+ KubevirtNetwork network = networkStore.network(networkId);
+ boolean result = network.ipPool().reserveIp(ip);
+ if (result) {
+ networkStore.updateNetwork(network);
+ } else {
+ log.warn("Failed to reserve IP address");
+ }
+
+ return result;
+ }
+
+ @Override
public void releaseIp(String networkId, IpAddress ip) {
checkArgument(!Strings.isNullOrEmpty(networkId), ERR_NULL_NETWORK_ID);
checkArgument(ip != null, ERR_NULL_IP);
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtPodPortMapper.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtPodPortMapper.java
index 595b775..d9076da 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtPodPortMapper.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtPodPortMapper.java
@@ -142,12 +142,65 @@
eventExecutor.execute(() -> processPodDeletion(event.subject()));
break;
case KUBEVIRT_POD_CREATED:
+ eventExecutor.execute(() -> processPodCreation(event.subject()));
+ break;
default:
// do nothing
break;
}
}
+ private void processPodCreation(Pod pod) {
+ if (!isRelevantHelper()) {
+ return;
+ }
+
+ KubernetesClient client = k8sClient(kubevirtApiConfigService);
+
+ if (client == null) {
+ return;
+ }
+
+ Map<String, String> annots = pod.getMetadata().getAnnotations();
+ if (annots == null) {
+ return;
+ }
+
+ if (!annots.containsKey(NETWORK_STATUS_KEY)) {
+ return;
+ }
+
+ try {
+ String networkStatusStr = pod.getMetadata().getAnnotations().get(NETWORK_STATUS_KEY);
+ JSONArray networkStatus = new JSONArray(networkStatusStr);
+ for (int i = 0; i < networkStatus.length(); i++) {
+ JSONObject object = networkStatus.getJSONObject(i);
+ String name = object.getString(NAME);
+ KubevirtNetwork jsonNetwork = kubevirtNetworkAdminService.networks().stream()
+ .filter(n -> (NETWORK_PREFIX + n.name()).equals(name))
+ .findAny().orElse(null);
+ if (jsonNetwork != null) {
+ JSONArray ips = object.getJSONArray(IPS);
+ if (ips != null && ips.length() > 0) {
+ IpAddress ip = IpAddress.valueOf(ips.getString(0));
+ kubevirtNetworkAdminService.reserveIp(jsonNetwork.networkId(), ip);
+ }
+ }
+ }
+ } catch (Exception e) {
+ log.error("Failed to reserve IP address", e);
+ }
+
+ KubevirtPort port = getPort(kubevirtNetworkAdminService.networks(), pod);
+ if (port == null) {
+ return;
+ }
+
+ if (kubevirtPortAdminService.port(port.macAddress()) == null) {
+ kubevirtPortAdminService.createPort(port);
+ }
+ }
+
private void processPodUpdate(Pod pod) {
if (!isRelevantHelper()) {
return;
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/NetworkAttachmentDefinitionWatcher.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/NetworkAttachmentDefinitionWatcher.java
index 93a3504..bae08bc 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/NetworkAttachmentDefinitionWatcher.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/NetworkAttachmentDefinitionWatcher.java
@@ -293,35 +293,39 @@
IpAddress.valueOf(start), IpAddress.valueOf(end)));
}
- JSONArray routesJson = configJson.getJSONArray(HOST_ROUTES);
- Set<KubevirtHostRoute> hostRoutes = new HashSet<>();
- if (routesJson != null) {
- for (int i = 0; i < routesJson.length(); i++) {
- JSONObject route = routesJson.getJSONObject(i);
- String destinationStr = route.getString(DESTINATION);
- String nexthopStr = route.getString(NEXTHOP);
+ if (configJson.has(HOST_ROUTES)) {
+ JSONArray routesJson = configJson.getJSONArray(HOST_ROUTES);
+ Set<KubevirtHostRoute> hostRoutes = new HashSet<>();
+ if (routesJson != null) {
+ for (int i = 0; i < routesJson.length(); i++) {
+ JSONObject route = routesJson.getJSONObject(i);
+ String destinationStr = route.getString(DESTINATION);
+ String nexthopStr = route.getString(NEXTHOP);
- if (StringUtils.isNotEmpty(destinationStr) &&
- StringUtils.isNotEmpty(nexthopStr)) {
- hostRoutes.add(new KubevirtHostRoute(
- IpPrefix.valueOf(destinationStr),
- IpAddress.valueOf(nexthopStr)));
+ if (StringUtils.isNotEmpty(destinationStr) &&
+ StringUtils.isNotEmpty(nexthopStr)) {
+ hostRoutes.add(new KubevirtHostRoute(
+ IpPrefix.valueOf(destinationStr),
+ IpAddress.valueOf(nexthopStr)));
+ }
}
}
+ builder.hostRoutes(hostRoutes);
}
- builder.hostRoutes(hostRoutes);
- JSONArray dnsesJson = configJson.getJSONArray(DNSES);
- Set<IpAddress> dnses = new HashSet<>();
- if (dnsesJson != null) {
- for (int i = 0; i < dnsesJson.length(); i++) {
- String dns = dnsesJson.getString(i);
- if (StringUtils.isNotEmpty(dns)) {
- dnses.add(IpAddress.valueOf(dns));
- }
+ if (configJson.has(DNSES)) {
+ JSONArray dnsesJson = configJson.getJSONArray(DNSES);
+ Set<IpAddress> dnses = new HashSet<>();
+ if (dnsesJson != null) {
+ for (int i = 0; i < dnsesJson.length(); i++) {
+ String dns = dnsesJson.getString(i);
+ if (StringUtils.isNotEmpty(dns)) {
+ dnses.add(IpAddress.valueOf(dns));
+ }
+ }
}
+ builder.dnses(dnses);
}
- builder.dnses(dnses);
builder.networkId(name).name(name).type(Type.valueOf(type))
.mtu(mtu).gatewayIp(IpAddress.valueOf(gatewayIp)).cidr(cidr);
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/util/KubevirtNetworkingUtil.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/util/KubevirtNetworkingUtil.java
index d9ea01e..db54054 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/util/KubevirtNetworkingUtil.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/util/KubevirtNetworkingUtil.java
@@ -262,6 +262,10 @@
return null;
}
+ if (!annots.containsKey(NETWORK_STATUS_KEY)) {
+ return null;
+ }
+
String networkStatusStr = annots.get(NETWORK_STATUS_KEY);
if (networkStatusStr == null) {
diff --git a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/OsgiPropertyConstants.java b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/OsgiPropertyConstants.java
index 9c1b8f8..0891d8c 100644
--- a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/OsgiPropertyConstants.java
+++ b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/OsgiPropertyConstants.java
@@ -24,7 +24,7 @@
}
static final String OVSDB_PORT = "ovsdbPortNum";
- static final int OVSDB_PORT_NUM_DEFAULT = 6653;
+ static final int OVSDB_PORT_NUM_DEFAULT = 6650;
static final String AUTO_RECOVERY = "autoRecovery";
static final boolean AUTO_RECOVERY_DEFAULT = true;