Implement kubernetes external loadbalancer handler.
Change-Id: I0f3057d66769f0ca7db7d508483835cdd1ff1593
(cherry picked from commit 5ff76b7bd3ef45b8538464a6fc510995d120739e)
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 3496008..539323f 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
@@ -53,6 +53,7 @@
import org.onosproject.kubevirtnetworking.api.KubevirtRouterService;
import org.onosproject.kubevirtnode.api.DefaultKubevirtNode;
import org.onosproject.kubevirtnode.api.DefaultKubevirtPhyInterface;
+import org.onosproject.kubevirtnode.api.KubernetesExternalLbInterface;
import org.onosproject.kubevirtnode.api.KubevirtApiConfig;
import org.onosproject.kubevirtnode.api.KubevirtApiConfigService;
import org.onosproject.kubevirtnode.api.KubevirtNode;
@@ -89,6 +90,7 @@
import static org.onosproject.kubevirtnode.api.KubevirtNode.Type.MASTER;
import static org.onosproject.kubevirtnode.api.KubevirtNode.Type.OTHER;
import static org.onosproject.kubevirtnode.api.KubevirtNode.Type.WORKER;
+import static org.onosproject.net.AnnotationKeys.PORT_MAC;
import static org.onosproject.net.AnnotationKeys.PORT_NAME;
/**
@@ -545,7 +547,7 @@
/**
* Returns the gateway node for the specified kubernetes external lb.
* Among gateways, only one gateway would act as a gateway per external lb.
- * Currently gateway node is selected based on modulo operation with router hashcode.
+ * Currently gateway node is selected based on modulo operation with external lb hashcode.
*
* @param nodeService kubevirt node service
* @param externalLb kubernetes external lb
@@ -565,6 +567,28 @@
}
/**
+ * Returns the worker node for the specified kubernetes external lb.
+ * Among worker nodes, only one worker would serve the traffic from and to the gateway.
+ * Currently worker node is selected based on modulo operation with external lb hashcode.
+ *
+ * @param nodeService kubevirt node service
+ * @param externalLb kubernetes external lb
+ * @return elected worker node
+ */
+ public static KubevirtNode workerNodeForSpecifiedService(KubevirtNodeService nodeService,
+ KubernetesExternalLb externalLb) {
+ //TODO: enhance election logic for a better load balancing
+
+ int numOfWorkers = nodeService.completeNodes(WORKER).size();
+ if (numOfWorkers == 0) {
+ return null;
+ }
+
+ return (KubevirtNode) nodeService.completeNodes(WORKER)
+ .toArray()[externalLb.hashCode() % numOfWorkers];
+ }
+
+ /**
* Returns the mac address of the router.
*
* @param router kubevirt router
@@ -659,6 +683,73 @@
}
/**
+ * Returns the external lb patch port number with specified gateway.
+ *
+ * @param deviceService device service
+ * @param gateway gateway node
+ * @return external lb bridge patch port number
+ */
+ public static PortNumber elbPatchPortNum(DeviceService deviceService, KubevirtNode gateway) {
+ KubernetesExternalLbInterface kubernetesExternalLbInterface =
+ gateway.kubernetesExternalLbInterface();
+
+ if (kubernetesExternalLbInterface == null) {
+ log.warn("No elb interface is attached to gateway {}", gateway.hostname());
+ return null;
+ }
+
+ String elbBridgeName = kubernetesExternalLbInterface.externalLbBridgeName();
+
+ String patchPortName = "int-to-" + elbBridgeName;
+
+ Port port = deviceService.getPorts(gateway.intgBridge()).stream()
+ .filter(p -> p.isEnabled() &&
+ Objects.equals(p.annotations().value(PORT_NAME), patchPortName))
+ .findAny().orElse(null);
+
+ return port != null ? port.number() : null;
+ }
+
+ /**
+ * Returns the external lb patch port Mac with specified gateway.
+ *
+ * @param deviceService device service
+ * @param gateway gateway node
+ * @return external lb bridge patch Mac Address
+ */
+ public static MacAddress kubernetesElbMac(DeviceService deviceService, KubevirtNode gateway) {
+
+ KubernetesExternalLbInterface kubernetesExternalLbInterface =
+ gateway.kubernetesExternalLbInterface();
+
+ if (kubernetesExternalLbInterface == null) {
+ log.warn("No elb interface is attached to gateway {}", gateway.hostname());
+ return null;
+ }
+
+ String elbBridgeName = kubernetesExternalLbInterface.externalLbBridgeName();
+
+ String patchPortName = "int-to-" + elbBridgeName;
+
+ Port port = deviceService.getPorts(gateway.intgBridge()).stream()
+ .filter(p -> p.isEnabled() &&
+ Objects.equals(p.annotations().value(PORT_NAME), patchPortName))
+ .findAny().orElse(null);
+
+ if (port == null) {
+ return null;
+ }
+
+ String portMacStr = port.annotations().value(PORT_MAC);
+
+ if (portMacStr == null) {
+ return null;
+ }
+
+ return MacAddress.valueOf(portMacStr);
+ }
+
+ /**
* Returns the kubevirt external network with specified router.
*
* @param networkService kubevirt network service