Support NodePort communication  model at k8s passthrough mode

Change-Id: I2179ebc9a4812493619c56aa270d8fc4821efbb2
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sNode.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sNode.java
index c4d7ac3..e914977 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sNode.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sNode.java
@@ -80,7 +80,7 @@
     private final DeviceId tunBridge;
     private final IpAddress managementIp;
     private final IpAddress dataIp;
-    private final IpAddress nodeIp;
+    private final K8sNodeInfo nodeInfo;
     private final K8sNodeState state;
     private final K8sExternalNetwork extNetwork;
     private final String podCidr;
@@ -103,7 +103,7 @@
      * @param tunBridge         tunnel bridge
      * @param managementIp      management IP address
      * @param dataIp            data IP address
-     * @param nodeIp            node IP address
+     * @param nodeInfo          node info
      * @param state             node state
      * @param extNetwork        external network
      * @param podCidr           POD CIDR
@@ -112,7 +112,7 @@
                              int segmentId, Mode mode, DeviceId intgBridge,
                              DeviceId extBridge, DeviceId localBridge,
                              DeviceId tunBridge, IpAddress managementIp,
-                             IpAddress dataIp, IpAddress nodeIp, K8sNodeState state,
+                             IpAddress dataIp, K8sNodeInfo nodeInfo, K8sNodeState state,
                              K8sExternalNetwork extNetwork, String podCidr) {
         this.clusterName = clusterName;
         this.hostname = hostname;
@@ -125,7 +125,7 @@
         this.tunBridge = tunBridge;
         this.managementIp = managementIp;
         this.dataIp = dataIp;
-        this.nodeIp = nodeIp;
+        this.nodeInfo = nodeInfo;
         this.state = state;
         this.extNetwork = extNetwork;
         this.podCidr = podCidr;
@@ -237,7 +237,7 @@
                 .tunBridge(tunBridge)
                 .managementIp(managementIp)
                 .dataIp(dataIp)
-                .nodeIp(nodeIp)
+                .nodeInfo(nodeInfo)
                 .state(state)
                 .extBridgeIp(extNetwork.extBridgeIp())
                 .extGatewayIp(extNetwork.extGatewayIp())
@@ -261,7 +261,7 @@
                 .tunBridge(tunBridge)
                 .managementIp(managementIp)
                 .dataIp(dataIp)
-                .nodeIp(nodeIp)
+                .nodeInfo(nodeInfo)
                 .state(state)
                 .extBridgeIp(extNetwork.extBridgeIp())
                 .extGatewayIp(extNetwork.extGatewayIp())
@@ -285,7 +285,7 @@
                 .tunBridge(tunBridge)
                 .managementIp(managementIp)
                 .dataIp(dataIp)
-                .nodeIp(nodeIp)
+                .nodeInfo(nodeInfo)
                 .state(state)
                 .extBridgeIp(extNetwork.extBridgeIp())
                 .extGatewayIp(extNetwork.extGatewayIp())
@@ -309,7 +309,7 @@
                 .tunBridge(deviceId)
                 .managementIp(managementIp)
                 .dataIp(dataIp)
-                .nodeIp(nodeIp)
+                .nodeInfo(nodeInfo)
                 .state(state)
                 .extBridgeIp(extNetwork.extBridgeIp())
                 .extGatewayIp(extNetwork.extGatewayIp())
@@ -330,8 +330,22 @@
     }
 
     @Override
+    public K8sNodeInfo nodeInfo() {
+        return nodeInfo;
+    }
+
+    @Override
     public IpAddress nodeIp() {
-        return nodeIp;
+        return nodeInfo.nodeIp();
+    }
+
+    @Override
+    public MacAddress nodeMac() {
+        if (nodeInfo == null) {
+            return null;
+        } else {
+            return nodeInfo.nodeMac();
+        }
     }
 
     @Override
@@ -358,7 +372,7 @@
                 .tunBridge(tunBridge)
                 .managementIp(managementIp)
                 .dataIp(dataIp)
-                .nodeIp(nodeIp)
+                .nodeInfo(nodeInfo)
                 .state(newState)
                 .extBridgeIp(extNetwork.extBridgeIp())
                 .extGatewayIp(extNetwork.extGatewayIp())
@@ -382,7 +396,7 @@
                 .tunBridge(tunBridge)
                 .managementIp(managementIp)
                 .dataIp(dataIp)
-                .nodeIp(nodeIp)
+                .nodeInfo(nodeInfo)
                 .state(state)
                 .extBridgeIp(extNetwork.extBridgeIp())
                 .extGatewayIp(extNetwork.extGatewayIp())
@@ -393,6 +407,30 @@
     }
 
     @Override
+    public K8sNode updateNodeInfo(K8sNodeInfo newNodeInfo) {
+        return new Builder()
+                .hostname(hostname)
+                .clusterName(clusterName)
+                .type(type)
+                .segmentId(segmentId)
+                .mode(mode)
+                .intgBridge(intgBridge)
+                .extBridge(extBridge)
+                .localBridge(localBridge)
+                .tunBridge(tunBridge)
+                .managementIp(managementIp)
+                .dataIp(dataIp)
+                .nodeInfo(newNodeInfo)
+                .state(state)
+                .extBridgeIp(extNetwork.extBridgeIp())
+                .extGatewayIp(extNetwork.extGatewayIp())
+                .extGatewayMac(extNetwork.extGatewayMac())
+                .extIntf(extNetwork.extIntf())
+                .podCidr(podCidr)
+                .build();
+    }
+
+    @Override
     public PortNumber grePortNum() {
         return tunnelPortNum(grePortName());
     }
@@ -617,20 +655,20 @@
     }
 
     @Override
-    public MacAddress portMacByName(String portName) {
+    public MacAddress portMacByName(DeviceId deviceId, String portName) {
         if (portName == null) {
             return null;
         } else {
-            return macAddress(this.intgBridge, portName);
+            return macAddress(deviceId, portName);
         }
     }
 
     @Override
-    public PortNumber portNumByName(String portName) {
+    public PortNumber portNumByName(DeviceId deviceId, String portName) {
         if (portName == null) {
             return null;
         } else {
-            return portNumber(this.intgBridge, portName);
+            return portNumber(deviceId, portName);
         }
     }
 
@@ -843,7 +881,7 @@
                     tunBridge.equals(that.tunBridge) &&
                     managementIp.equals(that.managementIp) &&
                     dataIp.equals(that.dataIp) &&
-                    nodeIp.equals(that.nodeIp) &&
+                    nodeInfo.equals(that.nodeInfo) &&
                     extNetwork.equals(that.extNetwork) &&
                     podCidr.equals(that.podCidr) &&
                     state == that.state;
@@ -855,7 +893,7 @@
     @Override
     public int hashCode() {
         return Objects.hash(clusterName, hostname, type, segmentId, mode, intgBridge, extBridge,
-                localBridge, tunBridge, managementIp, dataIp, nodeIp, state, extNetwork, podCidr);
+                localBridge, tunBridge, managementIp, dataIp, nodeInfo, state, extNetwork, podCidr);
     }
 
     @Override
@@ -872,7 +910,7 @@
                 .add("tunBridge", tunBridge)
                 .add("managementIp", managementIp)
                 .add("dataIp", dataIp)
-                .add("nodeIp", nodeIp)
+                .add("nodeInfo", nodeInfo)
                 .add("state", state)
                 .add("extBridgeIp", extNetwork.extBridgeIp())
                 .add("extGatewayIp", extNetwork.extGatewayIp())
@@ -937,7 +975,7 @@
                 .extIntf(node.extIntf())
                 .managementIp(node.managementIp())
                 .dataIp(node.dataIp())
-                .nodeIp(node.nodeIp())
+                .nodeInfo(node.nodeInfo())
                 .state(node.state())
                 .extBridgeIp(node.extBridgeIp())
                 .extGatewayIp(node.extGatewayIp())
@@ -959,7 +997,7 @@
         private DeviceId tunBridge;
         private IpAddress managementIp;
         private IpAddress dataIp;
-        private IpAddress nodeIp;
+        private K8sNodeInfo nodeInfo;
         private K8sNodeState state;
         private K8sApiConfig apiConfig;
         private String extIntf;
@@ -978,7 +1016,7 @@
             checkArgument(type != null, NOT_NULL_MSG, "type");
             checkArgument(state != null, NOT_NULL_MSG, "state");
             checkArgument(managementIp != null, NOT_NULL_MSG, "management IP");
-            checkArgument(nodeIp != null, NOT_NULL_MSG, "node IP");
+            checkArgument(nodeInfo != null, NOT_NULL_MSG, "node info");
 
             if (StringUtils.isEmpty(clusterName)) {
                 clusterName = DEFAULT_CLUSTER_NAME;
@@ -1006,7 +1044,7 @@
                     tunBridge,
                     managementIp,
                     dataIp,
-                    nodeIp,
+                    nodeInfo,
                     state,
                     extNetwork,
                     podCidr);
@@ -1079,8 +1117,8 @@
         }
 
         @Override
-        public Builder nodeIp(IpAddress nodeIp) {
-            this.nodeIp = nodeIp;
+        public Builder nodeInfo(K8sNodeInfo nodeInfo) {
+            this.nodeInfo = nodeInfo;
             return this;
         }
 
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNode.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNode.java
index 5c13bc1..4609f25 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNode.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNode.java
@@ -187,13 +187,27 @@
     IpAddress dataIp();
 
     /**
+     * Returns the kubernetes node info.
+     *
+     * @return node info; null if node info not exists
+     */
+    K8sNodeInfo nodeInfo();
+
+    /**
      * Returns the kubernetes node IP address.
      *
-     * @return ip address; null if node has no IP address
+     * @return node IP address; null if the node IP not exists
      */
     IpAddress nodeIp();
 
     /**
+     * Returns the kubernetes node MAC address.
+     *
+     * @return node MAC address; null if the node MAC not exists
+     */
+    MacAddress nodeMac();
+
+    /**
      * Returns the initialization state of the node.
      *
      * @return node state
@@ -224,6 +238,14 @@
     K8sNode updateExtGatewayMac(MacAddress macAddress);
 
     /**
+     * Returns new kubernetes node instance with given node info.
+     *
+     * @param nodeInfo updated node info
+     * @return updated kubernetes node
+     */
+    K8sNode updateNodeInfo(K8sNodeInfo nodeInfo);
+
+    /**
      * Returns GRE port name.
      *
      * @return GRE port name
@@ -268,18 +290,20 @@
     /**
      * Returns the port MAC address with the given patch port name.
      *
+     * @param deviceId device identifier
      * @param portName patch port name
      * @return port MAC address
      */
-    MacAddress portMacByName(String portName);
+    MacAddress portMacByName(DeviceId deviceId, String portName);
 
     /**
      * Returns the port number with the given patch port name.
      *
+     * @param deviceId device identifier
      * @param portName patch port name
      * @return port number
      */
-    PortNumber portNumByName(String portName);
+    PortNumber portNumByName(DeviceId deviceId, String portName);
 
     /**
      * Return the port number of integration bridge's entry port.
@@ -677,12 +701,12 @@
         Builder dataIp(IpAddress dataIp);
 
         /**
-         * Returns the kubernetes node builder with supplied node IP address.
+         * Returns the kubernetes node builder with supplied node info.
          *
-         * @param nodeIp node IP address
+         * @param nodeInfo node info
          * @return kubernetes node builder
          */
-        Builder nodeIp(IpAddress nodeIp);
+        Builder nodeInfo(K8sNodeInfo nodeInfo);
 
         /**
          * Returns kubernetes node builder with supplied node state.
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNodeInfo.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNodeInfo.java
new file mode 100644
index 0000000..ecd266e
--- /dev/null
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNodeInfo.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.k8snode.api;
+
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+
+import java.util.Objects;
+
+/**
+ * Kubernetes node info class.
+ */
+public class K8sNodeInfo {
+    private final IpAddress nodeIp;
+    private final MacAddress nodeMac;
+
+    /**
+     * Default constructor.
+     *
+     * @param nodeIp        node IP address
+     * @param nodeMac       node MAC address
+     */
+    public K8sNodeInfo(IpAddress nodeIp, MacAddress nodeMac) {
+        this.nodeIp = nodeIp;
+        this.nodeMac = nodeMac;
+    }
+
+    /**
+     * Obtains Kubernetes node IP address.
+     *
+     * @return node IP address
+     */
+    public IpAddress nodeIp() {
+        return nodeIp;
+    }
+
+    /**
+     * Obtains Kubernetes node MAC address.
+     *
+     * @return node MAC address
+     */
+    public MacAddress nodeMac() {
+        return nodeMac;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        K8sNodeInfo that = (K8sNodeInfo) o;
+        return Objects.equals(nodeIp, that.nodeIp) &&
+                Objects.equals(nodeMac, that.nodeMac);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(nodeIp, nodeMac);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("nodeIp", nodeIp)
+                .add("nodeMac", nodeMac)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/apps/k8s-node/api/src/test/java/org/onosproject/k8snode/api/DefaultK8sNodeTest.java b/apps/k8s-node/api/src/test/java/org/onosproject/k8snode/api/DefaultK8sNodeTest.java
index dec1d48..c953c8b 100644
--- a/apps/k8s-node/api/src/test/java/org/onosproject/k8snode/api/DefaultK8sNodeTest.java
+++ b/apps/k8s-node/api/src/test/java/org/onosproject/k8snode/api/DefaultK8sNodeTest.java
@@ -20,6 +20,7 @@
 import org.junit.Test;
 import org.onlab.packet.ChassisId;
 import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
 import org.onosproject.k8snode.api.K8sNode.Type;
 import org.onosproject.net.DefaultDevice;
 import org.onosproject.net.Device;
@@ -52,6 +53,8 @@
     private static final IpAddress MANAGEMENT_IP = IpAddress.valueOf("10.10.10.10");
     private static final IpAddress DATA_IP = IpAddress.valueOf("20.20.20.20");
     private static final IpAddress NODE_IP = IpAddress.valueOf("30.30.30.30");
+    private static final MacAddress NODE_MAC = MacAddress.valueOf("fa:00:00:00:00:08");
+    private static final K8sNodeInfo NODE_INFO = new K8sNodeInfo(NODE_IP, NODE_MAC);
 
     private static final String BRIDGE_INTF_1 = "eth1";
     private static final String BRIDGE_INTF_2 = "eth2";
@@ -78,6 +81,7 @@
             DEVICE_1,
             BRIDGE_INTF_1,
             TEST_IP,
+            NODE_INFO,
             INIT,
             EXT_BRIDGE_IP_1,
             EXT_GATEWAY_IP_1,
@@ -93,6 +97,7 @@
             DEVICE_1,
             BRIDGE_INTF_1,
             TEST_IP,
+            NODE_INFO,
             INIT,
             EXT_BRIDGE_IP_1,
             EXT_GATEWAY_IP_1,
@@ -108,6 +113,7 @@
             DEVICE_2,
             BRIDGE_INTF_2,
             TEST_IP,
+            NODE_INFO,
             INIT,
             EXT_BRIDGE_IP_2,
             EXT_GATEWAY_IP_2,
@@ -125,7 +131,7 @@
                 .segmentId(SEGMENT_ID_1)
                 .managementIp(MANAGEMENT_IP)
                 .dataIp(DATA_IP)
-                .nodeIp(NODE_IP)
+                .nodeInfo(NODE_INFO)
                 .intgBridge(DEVICE_1.id())
                 .extBridge(DEVICE_1.id())
                 .localBridge(DEVICE_1.id())
@@ -198,7 +204,7 @@
                 .extIntf(BRIDGE_INTF_1)
                 .managementIp(TEST_IP)
                 .dataIp(TEST_IP)
-                .nodeIp(NODE_IP)
+                .nodeInfo(NODE_INFO)
                 .state(INIT)
                 .extBridgeIp(EXT_BRIDGE_IP_1)
                 .extGatewayIp(EXT_GATEWAY_IP_1)
@@ -222,7 +228,7 @@
                 .extIntf(BRIDGE_INTF_1)
                 .managementIp(TEST_IP)
                 .dataIp(TEST_IP)
-                .nodeIp(NODE_IP)
+                .nodeInfo(NODE_INFO)
                 .state(INIT)
                 .extBridgeIp(EXT_BRIDGE_IP_1)
                 .extGatewayIp(EXT_GATEWAY_IP_1)
@@ -247,7 +253,7 @@
                 .tunBridge(DEVICE_1.id())
                 .extIntf(BRIDGE_INTF_1)
                 .dataIp(TEST_IP)
-                .nodeIp(NODE_IP)
+                .nodeInfo(NODE_INFO)
                 .state(INIT)
                 .extBridgeIp(EXT_BRIDGE_IP_1)
                 .extGatewayIp(EXT_GATEWAY_IP_1)
@@ -261,7 +267,7 @@
         assertEquals(node.type(), MINION);
         assertEquals(node.managementIp(), MANAGEMENT_IP);
         assertEquals(node.dataIp(), DATA_IP);
-        assertEquals(node.nodeIp(), NODE_IP);
+        assertEquals(node.nodeInfo(), NODE_INFO);
     }
 
     private static Device createDevice(long devIdNum) {
@@ -278,7 +284,7 @@
     private static K8sNode createNode(String clusterName, String hostname, Type type,
                                       int segmentId, Device intgBridge, Device extBridge,
                                       Device localBridge, Device tunBridge, String bridgeIntf,
-                                      IpAddress ipAddr, K8sNodeState state,
+                                      IpAddress ipAddr, K8sNodeInfo info, K8sNodeState state,
                                       IpAddress extBridgeIp, IpAddress extGatewayIp,
                                       String podCidr) {
         return DefaultK8sNode.builder()
@@ -293,7 +299,7 @@
                 .extIntf(bridgeIntf)
                 .managementIp(ipAddr)
                 .dataIp(ipAddr)
-                .nodeIp(ipAddr)
+                .nodeInfo(info)
                 .state(state)
                 .extBridgeIp(extBridgeIp)
                 .extGatewayIp(extGatewayIp)