Support onboard kubernetes nodes through K8S API configuration

Change-Id: I060a443f45ef9c974d030415a30e9376fc82d124
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNodeHandler.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNodeHandler.java
index e3f371a..71c3914 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNodeHandler.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNodeHandler.java
@@ -30,7 +30,7 @@
 
     /**
      * Processes the given node for device created state.
-     * It creates required ports on the bridges based on the node type
+     * It creates required ports on the bridges based on the node type.
      *
      * @param k8sNode kubernetes node
      */
@@ -50,4 +50,20 @@
      * @param k8sNode kubernetes node
      */
     void processIncompleteState(K8sNode k8sNode);
+
+    /**
+     * Processes the given node for pre-on-board state.
+     * It creates required bridges on OVS by referring to node type.
+     * It creates required ports on the bridges based on the node type.
+     *
+     * @param k8sNode kubernetes node
+     */
+    void processPreOnBoardState(K8sNode k8sNode);
+
+    /**
+     * Processes the given node for on boarded state.
+     *
+     * @param k8sNode kubernetes node
+     */
+    void processOnBoardedState(K8sNode k8sNode);
 }
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNodeState.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNodeState.java
index 88c66c5..2cdbe94 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNodeState.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNodeState.java
@@ -21,6 +21,34 @@
 public enum K8sNodeState {
 
     /**
+     * Indicates the node is in pre-on-board.
+     */
+    PRE_ON_BOARD {
+        @Override
+        public void process(K8sNodeHandler handler, K8sNode node) {
+            handler.processPreOnBoardState(node);
+        }
+
+        @Override
+        public K8sNodeState nextState() {
+            return ON_BOARDED;
+        }
+    },
+    /**
+     * Indicates the node is on-boarded.
+     */
+    ON_BOARDED {
+        @Override
+        public void process(K8sNodeHandler handler, K8sNode node) {
+            handler.processOnBoardedState(node);
+        }
+
+        @Override
+        public K8sNodeState nextState() {
+            return ON_BOARDED;
+        }
+    },
+    /**
      * Indicates the node is newly added.
      */
     INIT {
diff --git a/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/impl/DefaultK8sApiConfigHandler.java b/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/impl/DefaultK8sApiConfigHandler.java
index 5119500..01a5043 100644
--- a/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/impl/DefaultK8sApiConfigHandler.java
+++ b/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/impl/DefaultK8sApiConfigHandler.java
@@ -47,7 +47,7 @@
 import static org.onosproject.k8snode.api.K8sNode.Type.MASTER;
 import static org.onosproject.k8snode.api.K8sNode.Type.MINION;
 import static org.onosproject.k8snode.api.K8sNodeService.APP_ID;
-import static org.onosproject.k8snode.api.K8sNodeState.INIT;
+import static org.onosproject.k8snode.api.K8sNodeState.PRE_ON_BOARD;
 import static org.onosproject.k8snode.util.K8sNodeUtil.k8sClient;
 import static org.slf4j.LoggerFactory.getLogger;
 
@@ -172,7 +172,7 @@
                 .dataIp(dataIp)
                 .extIntf(extIntf)
                 .type(nodeType)
-                .state(INIT)
+                .state(PRE_ON_BOARD)
                 .extBridgeIp(IpAddress.valueOf(extBridgeIpStr))
                 .extGatewayIp(IpAddress.valueOf(extGatewayIpStr))
                 .podCidr(node.getSpec().getPodCIDR())
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 f31301f..1c68f3d 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
@@ -244,6 +244,17 @@
         // do something if needed
     }
 
+    @Override
+    public void processPreOnBoardState(K8sNode k8sNode) {
+        processInitState(k8sNode);
+        processDeviceCreatedState(k8sNode);
+    }
+
+    @Override
+    public void processOnBoardedState(K8sNode k8sNode) {
+        // do something if needed
+    }
+
     /**
      * Extracts properties from the component configuration context.
      *
@@ -455,32 +466,14 @@
     private boolean isCurrentStateDone(K8sNode k8sNode) {
         switch (k8sNode.state()) {
             case INIT:
-                if (!isOvsdbConnected(k8sNode, ovsdbPortNum,
-                        ovsdbController, deviceService)) {
-                    return false;
-                }
-
-                return k8sNode.intgBridge() != null && k8sNode.extBridge() != null &&
-                        deviceService.isAvailable(k8sNode.intgBridge()) &&
-                        deviceService.isAvailable(k8sNode.extBridge()) &&
-                        deviceService.isAvailable(k8sNode.localBridge());
+                return isInitStateDone(k8sNode);
             case DEVICE_CREATED:
-                if (k8sNode.dataIp() != null &&
-                        !isIntfEnabled(k8sNode, VXLAN_TUNNEL)) {
-                    return false;
-                }
-                if (k8sNode.dataIp() != null &&
-                        !isIntfEnabled(k8sNode, GRE_TUNNEL)) {
-                    return false;
-                }
-                if (k8sNode.dataIp() != null &&
-                        !isIntfEnabled(k8sNode, GENEVE_TUNNEL)) {
-                    return false;
-                }
-
-                return true;
+                return isDeviceCreatedStateDone(k8sNode);
+            case PRE_ON_BOARD:
+                return isInitStateDone(k8sNode) && isDeviceCreatedStateDone(k8sNode);
             case COMPLETE:
             case INCOMPLETE:
+            case ON_BOARDED:
                 // always return false
                 // run init CLI to re-trigger node bootstrap
                 return false;
@@ -489,6 +482,35 @@
         }
     }
 
+    private boolean isInitStateDone(K8sNode k8sNode) {
+        if (!isOvsdbConnected(k8sNode, ovsdbPortNum,
+                ovsdbController, deviceService)) {
+            return false;
+        }
+
+        return k8sNode.intgBridge() != null && k8sNode.extBridge() != null &&
+                deviceService.isAvailable(k8sNode.intgBridge()) &&
+                deviceService.isAvailable(k8sNode.extBridge()) &&
+                deviceService.isAvailable(k8sNode.localBridge());
+    }
+
+    private boolean isDeviceCreatedStateDone(K8sNode k8sNode) {
+        if (k8sNode.dataIp() != null &&
+                !isIntfEnabled(k8sNode, VXLAN_TUNNEL)) {
+            return false;
+        }
+        if (k8sNode.dataIp() != null &&
+                !isIntfEnabled(k8sNode, GRE_TUNNEL)) {
+            return false;
+        }
+        if (k8sNode.dataIp() != null &&
+                !isIntfEnabled(k8sNode, GENEVE_TUNNEL)) {
+            return false;
+        }
+
+        return true;
+    }
+
     /**
      * Configures the kubernetes node with new state.
      *