Remove bridges and associated flow rules when removing k8s nodes
Change-Id: Iab54503a4bb75874f69e8e1623bb11c66cad9eee
diff --git a/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/impl/DefaultK8sHostHandler.java b/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/impl/DefaultK8sHostHandler.java
index 2fc26be..a3a6fcd 100644
--- a/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/impl/DefaultK8sHostHandler.java
+++ b/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/impl/DefaultK8sHostHandler.java
@@ -448,6 +448,7 @@
log.error("Exception caused during init state checking...");
}
+ // checks whether all tunneling ports exist
for (K8sTunnelBridge bridge: k8sHost.tunBridges()) {
if (!isTunPortEnabled(bridge, bridge.vxlanPortName())) {
return false;
@@ -460,6 +461,26 @@
}
}
+ // checks whether all patch ports attached to tunnel bridge exist
+ for (K8sTunnelBridge bridge : k8sHost.tunBridges()) {
+ for (String node : k8sHost.nodeNames()) {
+ K8sNode k8sNode = k8sNodeAdminService.node(node);
+ if (!isTunPortEnabled(bridge, k8sNode.tunToIntgPatchPortName())) {
+ return false;
+ }
+ }
+ }
+
+ // checks whether all patch ports attached to router bridge exist
+ for (K8sRouterBridge bridge : k8sHost.routerBridges()) {
+ for (String node : k8sHost.nodeNames()) {
+ K8sNode k8sNode = k8sNodeAdminService.node(node);
+ if (!isRouterPortEnabled(bridge, k8sNode.routerToExtPatchPortName())) {
+ return false;
+ }
+ }
+ }
+
return true;
}
@@ -471,6 +492,14 @@
port.isEnabled());
}
+ private boolean isRouterPortEnabled(K8sRouterBridge routerBridge, String intf) {
+ return deviceService.isAvailable(routerBridge.deviceId()) &&
+ deviceService.getPorts(routerBridge.deviceId()).stream()
+ .anyMatch(port -> Objects.equals(
+ port.annotations().value(PORT_NAME), intf) &&
+ port.isEnabled());
+ }
+
/**
* Configures the kubernetes host with new state.
*
@@ -600,29 +629,30 @@
return;
}
- K8sHost k8sHost = k8sHostAdminService.hostByTunBridge(device.id());
+ K8sHost tunnelHost = k8sHostAdminService.hostByTunBridge(device.id());
- if (k8sHost == null) {
+ if (tunnelHost == null) {
return;
}
- Port port = event.port();
- String portName = port.annotations().value(PORT_NAME);
- if (k8sHost.state() == DEVICE_CREATED) {
-
- K8sTunnelBridge tunBridge = k8sHost.tunBridges().stream().filter(
+ if (tunnelHost.state() == DEVICE_CREATED) {
+ // we bootstrap the host whenever any ports added to the tunnel bridge
+ tunnelHost.tunBridges().stream().filter(
br -> br.deviceId().equals(device.id())
- ).findAny().orElse(null);
+ ).findAny().ifPresent(tunBridge -> bootstrapHost(tunnelHost));
+ }
- if (tunBridge != null) {
- if (Objects.equals(portName, tunBridge.vxlanPortName()) ||
- Objects.equals(portName, tunBridge.grePortName()) ||
- Objects.equals(portName, tunBridge.genevePortName())) {
- log.info("Interface {} added or updated to {}",
- portName, device.id());
- bootstrapHost(k8sHost);
- }
- }
+ K8sHost routerHost = k8sHostAdminService.hostByRouterBridge(device.id());
+
+ if (routerHost == null) {
+ return;
+ }
+
+ if (routerHost.state() == DEVICE_CREATED) {
+ // we bootstrap the host whenever any ports added to the router bridge
+ routerHost.routerBridges().stream().filter(
+ br -> br.deviceId().equals(device.id())
+ ).findAny().ifPresent(routerBridge -> bootstrapHost(routerHost));
}
});
break;
diff --git a/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/impl/DefaultK8sNodeHandler.java b/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/impl/DefaultK8sNodeHandler.java
index 46f56a6..e5c8b00 100644
--- a/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/impl/DefaultK8sNodeHandler.java
+++ b/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/impl/DefaultK8sNodeHandler.java
@@ -86,6 +86,7 @@
import static org.onosproject.net.AnnotationKeys.PORT_NAME;
import static org.slf4j.LoggerFactory.getLogger;
+
/**
* Service bootstraps kubernetes node based on its type.
*/
@@ -261,6 +262,11 @@
// do something if needed
}
+ @Override
+ public void processOffBoardedState(K8sNode k8sNode) {
+ // do something if needed
+ }
+
/**
* Extracts properties from the component configuration context.
*
@@ -630,6 +636,18 @@
return;
}
+ if (k8sNode.mode() == NORMAL) {
+ // delete tunnel bridge from the node
+ client.dropBridge(k8sNode.tunBridgeName());
+ } else {
+ // remove the patch ports direct to the integration bridge from tunnel bridge
+ removeTunnelPatchPort(k8sNode);
+ // remove the patch ports direct to the external bridge from the router bridge
+ removeRouterPatchPort(k8sNode);
+ // remove the patch ports directs to the openstack's br-int bridge from the int and ext bridges
+ removeOpenstackPatchPorts(k8sNode);
+ }
+
// delete integration bridge from the node
client.dropBridge(k8sNode.intgBridgeName());
@@ -639,13 +657,42 @@
// delete local bridge from the node
client.dropBridge(k8sNode.localBridgeName());
- if (k8sNode.mode() == NORMAL) {
- // delete tunnel bridge from the node
- client.dropBridge(k8sNode.tunBridgeName());
+ // disconnect ovsdb
+ // client.disconnect();
+ }
+
+ private void removeTunnelPatchPort(K8sNode k8sNode) {
+ OvsdbClientService client = getOvsdbClient(k8sNode, ovsdbPortNum, ovsdbController);
+ if (client == null) {
+ log.info("Failed to get ovsdb client");
+ return;
}
- // disconnect ovsdb
- client.disconnect();
+ client.dropInterface(k8sNode.tunToIntgPatchPortName());
+ }
+
+ private void removeRouterPatchPort(K8sNode k8sNode) {
+ OvsdbClientService client = getOvsdbClient(k8sNode, ovsdbPortNum, ovsdbController);
+ if (client == null) {
+ log.info("Failed to get ovsdb client");
+ return;
+ }
+
+ client.dropInterface(k8sNode.routerToExtPatchPortName());
+ }
+
+ private void removeOpenstackPatchPorts(K8sNode k8sNode) {
+ OvsdbClientService client = getOvsdbClient(k8sNode, ovsdbPortNum, ovsdbController);
+ if (client == null) {
+ log.info("Failed to get ovsdb client");
+ return;
+ }
+
+ // remove patch port attached at br-int peers with the k8s integration bridge
+ client.dropInterface(k8sNode.osToK8sIntgPatchPortName());
+
+ // remove patch port attached at br-int peers with the k8s external bridge
+ client.dropInterface(k8sNode.osToK8sExtPatchPortName());
}
/**
@@ -831,21 +878,17 @@
case K8S_NODE_CREATED:
case K8S_NODE_UPDATED:
eventExecutor.execute(() -> {
-
if (!isRelevantHelper()) {
return;
}
-
bootstrapNode(event.subject());
});
break;
case K8S_NODE_REMOVED:
eventExecutor.execute(() -> {
-
if (!isRelevantHelper()) {
return;
}
-
processK8sNodeRemoved(event.subject());
});
break;
diff --git a/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/impl/DistributedK8sNodeStore.java b/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/impl/DistributedK8sNodeStore.java
index 90ec2a0..b221ac4 100644
--- a/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/impl/DistributedK8sNodeStore.java
+++ b/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/impl/DistributedK8sNodeStore.java
@@ -51,13 +51,8 @@
import static com.google.common.base.Preconditions.checkArgument;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static org.onlab.util.Tools.groupedThreads;
-import static org.onosproject.k8snode.api.K8sNodeEvent.Type.K8S_NODE_COMPLETE;
-import static org.onosproject.k8snode.api.K8sNodeEvent.Type.K8S_NODE_CREATED;
-import static org.onosproject.k8snode.api.K8sNodeEvent.Type.K8S_NODE_INCOMPLETE;
-import static org.onosproject.k8snode.api.K8sNodeEvent.Type.K8S_NODE_REMOVED;
-import static org.onosproject.k8snode.api.K8sNodeEvent.Type.K8S_NODE_UPDATED;
-import static org.onosproject.k8snode.api.K8sNodeState.COMPLETE;
-import static org.onosproject.k8snode.api.K8sNodeState.INCOMPLETE;
+import static org.onosproject.k8snode.api.K8sNodeEvent.Type.*;
+import static org.onosproject.k8snode.api.K8sNodeState.*;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -190,6 +185,11 @@
K8S_NODE_INCOMPLETE,
event.newValue().value()
));
+ } else if (event.newValue().value().state() == OFF_BOARDED) {
+ notifyDelegate(new K8sNodeEvent(
+ K8S_NODE_OFF_BOARDED,
+ event.newValue().value()
+ ));
}
});
break;
diff --git a/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/impl/K8sHostManager.java b/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/impl/K8sHostManager.java
index 1747ada..b527dd1 100644
--- a/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/impl/K8sHostManager.java
+++ b/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/impl/K8sHostManager.java
@@ -206,6 +206,18 @@
return null;
}
+ @Override
+ public K8sHost hostByRouterBridge(DeviceId deviceId) {
+ for (K8sHost host : hostStore.hosts()) {
+ long cnt = host.routerBridges().stream().filter(
+ br -> br.dpid().equals(deviceId.toString())).count();
+ if (cnt > 0) {
+ return host;
+ }
+ }
+ return null;
+ }
+
private class InternalHostStoreDelegate implements K8sHostStoreDelegate {
@Override