Dynamically add or remove gateway node according to GW annotation
Change-Id: Ic7ac799eda0c1d028e934cc1bfd07af34e714e18
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtFloatingIpHandler.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtFloatingIpHandler.java
index 26e27ff..96d111c 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtFloatingIpHandler.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtFloatingIpHandler.java
@@ -37,6 +37,8 @@
import org.onosproject.kubevirtnetworking.api.KubevirtRouterService;
import org.onosproject.kubevirtnetworking.util.RulePopulatorUtil;
import org.onosproject.kubevirtnode.api.KubevirtNode;
+import org.onosproject.kubevirtnode.api.KubevirtNodeEvent;
+import org.onosproject.kubevirtnode.api.KubevirtNodeListener;
import org.onosproject.kubevirtnode.api.KubevirtNodeService;
import org.onosproject.net.Device;
import org.onosproject.net.PortNumber;
@@ -118,15 +120,19 @@
private ApplicationId appId;
private NodeId localNodeId;
- private final InternalRouterEventListener kubevirtRouterlistener =
+ private final InternalRouterEventListener kubevirtRouterListener =
new InternalRouterEventListener();
+ private final InternalNodeEventListener kubevirtNodeListener =
+ new InternalNodeEventListener();
+
@Activate
protected void activate() {
appId = coreService.registerApplication(KUBEVIRT_NETWORKING_APP_ID);
localNodeId = clusterService.getLocalNode().id();
leadershipService.runForLeadership(appId.name());
- kubevirtRouterService.addListener(kubevirtRouterlistener);
+ kubevirtRouterService.addListener(kubevirtRouterListener);
+ kubevirtNodeService.addListener(kubevirtNodeListener);
log.info("Started");
}
@@ -134,7 +140,8 @@
@Deactivate
protected void deactivate() {
leadershipService.withdraw(appId.name());
- kubevirtRouterService.removeListener(kubevirtRouterlistener);
+ kubevirtRouterService.removeListener(kubevirtRouterListener);
+ kubevirtNodeService.removeListener(kubevirtNodeListener);
eventExecutor.shutdown();
@@ -204,6 +211,7 @@
PRE_FLAT_TABLE,
install);
}
+
private KubevirtPort getKubevirtPort(KubevirtFloatingIp floatingIp) {
return kubevirtPortService.ports().stream()
@@ -352,7 +360,6 @@
return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
}
-
@Override
public void event(KubevirtRouterEvent event) {
switch (event.type()) {
@@ -385,4 +392,44 @@
setFloatingIpRules(router, floatingIp, false);
}
}
+
+ private class InternalNodeEventListener implements KubevirtNodeListener {
+
+ private boolean isRelevantHelper() {
+ return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
+ }
+
+ @Override
+ public void event(KubevirtNodeEvent event) {
+ switch (event.type()) {
+ case KUBEVIRT_NODE_COMPLETE:
+ eventExecutor.execute(() -> processNodeCompletion(event.subject()));
+ break;
+ case KUBEVIRT_NODE_REMOVED:
+ case KUBEVIRT_NODE_INCOMPLETE:
+ default:
+ break;
+ }
+ }
+
+ private void processNodeCompletion(KubevirtNode node) {
+ if (!isRelevantHelper()) {
+ return;
+ }
+
+ kubevirtRouterService.floatingIps().forEach(fip -> {
+ KubevirtRouter router = kubevirtRouterService.router(fip.routerName());
+ if (router != null) {
+ KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(kubevirtNodeService, router);
+ if (electedGw == null) {
+ return;
+ }
+
+ if (electedGw.hostname().equals(node.hostname())) {
+ setFloatingIpRules(router, fip, true);
+ }
+ }
+ });
+ }
+ }
}
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtNetworkHandler.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtNetworkHandler.java
index f1b41bc..e682029 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtNetworkHandler.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtNetworkHandler.java
@@ -347,7 +347,7 @@
return;
}
- setDefaulGatewayRuleToWorkerNodeTunBridge(router, network, electedGw.intgBridge(), node, true);
+ setDefaultGatewayRuleToWorkerNodeTunBridge(router, network, electedGw.intgBridge(), node, true);
}
private void setDefaultRulesForTenantNetwork(KubevirtNode node, KubevirtNetwork network) {
@@ -428,7 +428,7 @@
setGatewayIcmpRuleForTenantInternalNetwork(router, network, TENANT_ICMP_TABLE,
electedGateway.intgBridge(),
network.tenantDeviceId(node.hostname()), install);
- setDefaulGatewayRuleToWorkerNodeTunBridge(router, network,
+ setDefaultGatewayRuleToWorkerNodeTunBridge(router, network,
electedGateway.intgBridge(), node, install);
});
break;
@@ -446,11 +446,11 @@
}
}
- private void setDefaulGatewayRuleToWorkerNodeTunBridge(KubevirtRouter router,
- KubevirtNetwork network,
- DeviceId gwDeviceId,
- KubevirtNode workerNode,
- boolean install) {
+ private void setDefaultGatewayRuleToWorkerNodeTunBridge(KubevirtRouter router,
+ KubevirtNetwork network,
+ DeviceId gwDeviceId,
+ KubevirtNode workerNode,
+ boolean install) {
MacAddress routerMacAddress = getRouterMacAddress(router);
if (routerMacAddress == null) {
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtRoutingSnatHandler.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtRoutingSnatHandler.java
index 264017a..20fa0cb 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtRoutingSnatHandler.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtRoutingSnatHandler.java
@@ -42,6 +42,8 @@
import org.onosproject.kubevirtnetworking.api.KubevirtRouterService;
import org.onosproject.kubevirtnetworking.util.RulePopulatorUtil;
import org.onosproject.kubevirtnode.api.KubevirtNode;
+import org.onosproject.kubevirtnode.api.KubevirtNodeEvent;
+import org.onosproject.kubevirtnode.api.KubevirtNodeListener;
import org.onosproject.kubevirtnode.api.KubevirtNodeService;
import org.onosproject.net.Device;
import org.onosproject.net.PortNumber;
@@ -140,6 +142,9 @@
private final InternalRouterEventListener kubevirtRouterlistener =
new InternalRouterEventListener();
+ private final InternalNodeEventListener kubevirtNodeListener =
+ new InternalNodeEventListener();
+
private ApplicationId appId;
private NodeId localNodeId;
@@ -151,6 +156,7 @@
kubevirtPortService.addListener(kubevirtPortListener);
kubevirtRouterService.addListener(kubevirtRouterlistener);
+ kubevirtNodeService.addListener(kubevirtNodeListener);
log.info("Started");
}
@@ -158,6 +164,7 @@
@Deactivate
protected void deactivate() {
leadershipService.withdraw(appId.name());
+ kubevirtNodeService.removeListener(kubevirtNodeListener);
kubevirtPortService.removeListener(kubevirtPortListener);
kubevirtRouterService.removeListener(kubevirtRouterlistener);
@@ -720,4 +727,12 @@
}
}
}
+
+ private class InternalNodeEventListener implements KubevirtNodeListener {
+
+ @Override
+ public void event(KubevirtNodeEvent event) {
+
+ }
+ }
}
diff --git a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/DefaultKubevirtNodeHandler.java b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/DefaultKubevirtNodeHandler.java
index f224dbc..b9c0880 100644
--- a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/DefaultKubevirtNodeHandler.java
+++ b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/DefaultKubevirtNodeHandler.java
@@ -601,13 +601,21 @@
log.info("Creating physnet bridge {}", bridgeName);
log.info("Creating patch ports for physnet {}", bridgeName);
} else {
- // in case physical bridge exists, but patch port is missing on br-int,
- // we will add patch port to connect br-int with physical bridge
+ // in case physical bridge exists, but patch port is missing,
+ // we will add patch port to connect br-physnet with physical bridge
if (!hasPhyPatchPort(node, patchPortName)) {
createPhysicalPatchPorts(node, pi);
log.info("Creating patch ports for physnet {}", bridgeName);
}
+
+ // in case physical bridge exists, but physnet interface is missing,
+ // we will add the physnet interface to connect br-physnet to the external
+ if (!hasPhyIntf(node, pi.intf())) {
+ attachPhysicalPort(node, pi);
+
+ log.info("Attaching external ports for physnet {}", bridgeName);
+ }
}
});
}
@@ -979,6 +987,9 @@
if (!isRelevantHelper()) {
return;
}
+ if (event.subject() == null) {
+ return;
+ }
bootstrapNode(event.subject());
});
break;
diff --git a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/KubevirtNodeWatcher.java b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/KubevirtNodeWatcher.java
index 4ac793d..96662c4 100644
--- a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/KubevirtNodeWatcher.java
+++ b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/KubevirtNodeWatcher.java
@@ -44,6 +44,7 @@
import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.kubevirtnode.api.KubevirtNode.Type.GATEWAY;
+import static org.onosproject.kubevirtnode.api.KubevirtNode.Type.MASTER;
import static org.onosproject.kubevirtnode.api.KubevirtNode.Type.WORKER;
import static org.onosproject.kubevirtnode.api.KubevirtNodeService.APP_ID;
import static org.onosproject.kubevirtnode.api.KubevirtNodeState.INIT;
@@ -203,18 +204,29 @@
log.trace("Process node {} updating event from API server.",
node.getMetadata().getName());
+ KubevirtNode original = buildKubevirtNode(node);
KubevirtNode existing = kubevirtNodeAdminService.node(node.getMetadata().getName());
- if (existing != null) {
- KubevirtNode kubevirtNode = buildKubevirtNode(node);
+ // if a master node is annotated as a gateway node, we simply add
+ // the node into the cluster
+ if (original.type() == GATEWAY && existing == null) {
+ kubevirtNodeAdminService.createNode(original);
+ }
+ // if a gateway annotation removed from the master node, we simply remove
+ // the node from the cluster
+ if (original.type() == MASTER && existing != null && existing.type() == GATEWAY) {
+ kubevirtNodeAdminService.removeNode(original.hostname());
+ }
+
+ if (existing != null) {
// we update the kubevirt node and re-run bootstrapping,
- // only if the updated node has different phyInts and data IP
+ // if the updated node has different phyInts and data IP
// this means we assume that the node's hostname, type and mgmt IP
// are immutable
- if (!kubevirtNode.phyIntfs().equals(existing.phyIntfs()) ||
- !kubevirtNode.dataIp().equals(existing.dataIp())) {
- kubevirtNodeAdminService.updateNode(kubevirtNode.updateState(INIT));
+ if (!original.phyIntfs().equals(existing.phyIntfs()) ||
+ !original.dataIp().equals(existing.dataIp())) {
+ kubevirtNodeAdminService.updateNode(original.updateState(INIT));
}
}
}