Harden the health check logic of kubevirt control plane

Change-Id: I161e71ab473ace323b4433fa4b90860b014fe677
(cherry picked from commit e15a60c16ca78af405fd1681128e0201550d196a)
diff --git a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/util/KubevirtNodeUtil.java b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/util/KubevirtNodeUtil.java
index 46a5ea5..f857364 100644
--- a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/util/KubevirtNodeUtil.java
+++ b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/util/KubevirtNodeUtil.java
@@ -318,6 +318,36 @@
     }
 
     /**
+     * Returns the type of the given kubernetes node.
+     *
+     * @param node kubernetes node
+     * @return node type
+     */
+    public static KubevirtNode.Type getNodeType(Node node) {
+        Set<String> rolesFull = node.getMetadata().getLabels().keySet().stream()
+                .filter(l -> l.contains(K8S_ROLE))
+                .collect(Collectors.toSet());
+
+        KubevirtNode.Type nodeType = WORKER;
+
+        for (String roleStr : rolesFull) {
+            String role = roleStr.split("/")[1];
+            if (MASTER.name().equalsIgnoreCase(role)) {
+                nodeType = MASTER;
+                break;
+            }
+        }
+
+        Map<String, String> annots = node.getMetadata().getAnnotations();
+        String gatewayConfig = annots.get(GATEWAY_CONFIG_KEY);
+        if (gatewayConfig != null) {
+            nodeType = GATEWAY;
+        }
+
+        return nodeType;
+    }
+
+    /**
      * Returns the kubevirt node from the node.
      *
      * @param node a raw node object returned from a k8s client
diff --git a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/web/KubevirtNodeWebResource.java b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/web/KubevirtNodeWebResource.java
index b659ec6..5a9ce5c 100644
--- a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/web/KubevirtNodeWebResource.java
+++ b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/web/KubevirtNodeWebResource.java
@@ -19,6 +19,7 @@
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.google.common.collect.Sets;
+import io.fabric8.kubernetes.client.KubernetesClient;
 import org.onosproject.kubevirtnode.api.KubevirtApiConfig;
 import org.onosproject.kubevirtnode.api.KubevirtApiConfigService;
 import org.onosproject.kubevirtnode.api.KubevirtNode;
@@ -43,14 +44,19 @@
 import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
 import java.io.InputStream;
+import java.util.HashSet;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import static com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT;
 import static javax.ws.rs.core.Response.created;
 import static org.onlab.util.Tools.nullIsIllegal;
 import static org.onlab.util.Tools.readTreeFromStream;
+import static org.onosproject.kubevirtnode.api.KubevirtNode.Type.WORKER;
 import static org.onosproject.kubevirtnode.api.KubevirtNodeState.COMPLETE;
 import static org.onosproject.kubevirtnode.api.KubevirtNodeState.INIT;
+import static org.onosproject.kubevirtnode.util.KubevirtNodeUtil.getNodeType;
+import static org.onosproject.kubevirtnode.util.KubevirtNodeUtil.k8sClient;
 import static org.onosproject.kubevirtnode.util.KubevirtNodeUtil.waitFor;
 
 /**
@@ -303,6 +309,24 @@
             result = OK;
         }
 
+        KubernetesClient client = k8sClient(config);
+        if (client != null) {
+            Set<String> k8sNodeNames = new HashSet<>();
+            client.nodes().list().getItems().forEach(n -> {
+                if (getNodeType(n) == WORKER) {
+                    k8sNodeNames.add(n.getMetadata().getName());
+                }
+            });
+            Set<String> nodeNames = nodeService.nodes(WORKER).stream()
+                    .map(KubevirtNode::hostname).collect(Collectors.toSet());
+            if (!k8sNodeNames.containsAll(nodeNames)) {
+                result = ERROR;
+            }
+            if (!nodeNames.containsAll(k8sNodeNames)) {
+                result = ERROR;
+            }
+        }
+
         ObjectNode jsonResult = mapper().createObjectNode();
         jsonResult.put(API_CONFIG, result);
         return ok(jsonResult).build();