Initial support for multi kubernetes clusters for k8s nodes

Change-Id: I6ca132898f8e157e0583de38a637fdc135f21d6f
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/Constants.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/Constants.java
index 513d21a..c32f766 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/Constants.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/Constants.java
@@ -26,10 +26,16 @@
     public static final String INTEGRATION_BRIDGE = "kbr-int";
     public static final String EXTERNAL_BRIDGE = "kbr-ex";
     public static final String LOCAL_BRIDGE = "kbr-local";
+    public static final String TUNNEL_BRIDGE = "kbr-tun";
+    public static final String EXTERNAL_ROUTER = "kbr-router";
     public static final String INTEGRATION_TO_EXTERNAL_BRIDGE = "kbr-int-ex";
     public static final String PHYSICAL_EXTERNAL_BRIDGE = "phy-kbr-ex";
     public static final String INTEGRATION_TO_LOCAL_BRIDGE = "kbr-int-local";
     public static final String LOCAL_TO_INTEGRATION_BRIDGE = "kbr-local-int";
+    public static final String EXTERNAL_TO_ROUTER = "kbr-ex-router";
+    public static final String ROUTER_TO_EXTERNAL = "kbr-router-ex";
+    public static final String INTEGRATION_TO_TUN_BRIDGE = "kbr-int-tun";
+    public static final String TUN_TO_INTEGRATION_BRIDGE = "kbr-tun-int";
     public static final String VXLAN_TUNNEL = "vxlan";
     public static final String GRE_TUNNEL = "gre";
     public static final String GENEVE_TUNNEL = "geneve";
@@ -37,4 +43,9 @@
     public static final String VXLAN = "vxlan";
     public static final String GRE = "gre";
     public static final String GENEVE = "geneve";
+
+    public static final String DEFAULT_CLUSTER_NAME = "default";
+    public static final String DEFAULT_CONFIG_MODE = "NORMAL";
+
+    public static final int DEFAULT_SEGMENT_ID = 100;
 }
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultHostNodesInfo.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultHostNodesInfo.java
new file mode 100644
index 0000000..94be29e
--- /dev/null
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultHostNodesInfo.java
@@ -0,0 +1,114 @@
+/*
+ * 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 com.google.common.collect.ImmutableSet;
+import org.onlab.packet.IpAddress;
+
+import java.util.Objects;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Default implementation of host to nodes mapping info.
+ */
+public final class DefaultHostNodesInfo implements HostNodesInfo {
+
+    private static final String NOT_NULL_MSG = "HostNodesInfo % cannot be null";
+
+    private final IpAddress hostIp;
+    private final Set<String> nodes;
+
+    private DefaultHostNodesInfo(IpAddress hostIp, Set<String> nodes) {
+        this.hostIp = hostIp;
+        this.nodes = ImmutableSet.copyOf(nodes);
+    }
+
+    @Override
+    public IpAddress hostIp() {
+        return hostIp;
+    }
+
+    @Override
+    public Set<String> nodes() {
+        return ImmutableSet.copyOf(nodes);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        DefaultHostNodesInfo that = (DefaultHostNodesInfo) o;
+        return Objects.equals(hostIp, that.hostIp) &&
+                Objects.equals(nodes, that.nodes);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(hostIp, nodes);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("hostIp", hostIp)
+                .add("nodes", nodes)
+                .toString();
+    }
+
+    /**
+     * Returns new builder instance.
+     *
+     * @return HostNodesInfo builder
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    public static final class Builder implements HostNodesInfo.Builder {
+
+        private IpAddress hostIp;
+        private Set<String> nodes;
+
+        @Override
+        public HostNodesInfo build() {
+            checkArgument(hostIp != null, NOT_NULL_MSG, "Host IP address");
+            if (nodes == null) {
+                nodes = ImmutableSet.of();
+            }
+
+            return new DefaultHostNodesInfo(hostIp, nodes);
+        }
+
+        @Override
+        public HostNodesInfo.Builder hostIp(IpAddress hostIp) {
+            this.hostIp = hostIp;
+            return this;
+        }
+
+        @Override
+        public HostNodesInfo.Builder nodes(Set<String> nodes) {
+            this.nodes = nodes;
+            return this;
+        }
+    }
+}
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sApiConfig.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sApiConfig.java
index dc8d030..cbc62e6 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sApiConfig.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sApiConfig.java
@@ -16,11 +16,17 @@
 package org.onosproject.k8snode.api;
 
 import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableSet;
+import org.apache.commons.lang.StringUtils;
 import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
 
 import java.util.Objects;
+import java.util.Set;
 
 import static com.google.common.base.Preconditions.checkArgument;
+import static org.onosproject.k8snode.api.Constants.DEFAULT_CLUSTER_NAME;
+import static org.onosproject.k8snode.api.K8sApiConfig.Mode.NORMAL;
 import static org.onosproject.k8snode.api.K8sApiConfig.Scheme.HTTPS;
 
 /**
@@ -30,7 +36,13 @@
 
     private static final String NOT_NULL_MSG = "API Config % cannot be null";
 
+    private static final int SHORT_NAME_LENGTH = 10;
+
+    private final String clusterName;
+    private final int segmentId;
+    private final IpPrefix extNetworkCidr;
     private final Scheme scheme;
+    private final Mode mode;
     private final IpAddress ipAddress;
     private final int port;
     private final State state;
@@ -38,18 +50,45 @@
     private final String caCertData;
     private final String clientCertData;
     private final String clientKeyData;
+    private final Set<HostNodesInfo> infos;
 
-    private DefaultK8sApiConfig(Scheme scheme, IpAddress ipAddress, int port,
-                                State state, String token, String caCertData,
-                                String clientCertData, String clientKeyData) {
+    private DefaultK8sApiConfig(String clusterName, int segmentId, IpPrefix extNetworkCidr,
+                                Scheme scheme, IpAddress ipAddress, int port,
+                                Mode mode, State state, String token, String caCertData,
+                                String clientCertData, String clientKeyData, Set<HostNodesInfo> infos) {
+        this.clusterName = clusterName;
+        this.segmentId = segmentId;
+        this.extNetworkCidr = extNetworkCidr;
         this.scheme = scheme;
         this.ipAddress = ipAddress;
         this.port = port;
+        this.mode = mode;
         this.state = state;
         this.token = token;
         this.caCertData = caCertData;
         this.clientCertData = clientCertData;
         this.clientKeyData = clientKeyData;
+        this.infos = infos;
+    }
+
+    @Override
+    public String clusterName() {
+        return clusterName;
+    }
+
+    @Override
+    public String clusterShortName() {
+        return StringUtils.substring(clusterName, 0, SHORT_NAME_LENGTH);
+    }
+
+    @Override
+    public int segmentId() {
+        return segmentId;
+    }
+
+    @Override
+    public IpPrefix extNetworkCidr() {
+        return extNetworkCidr;
     }
 
     @Override
@@ -73,16 +112,26 @@
     }
 
     @Override
+    public Mode mode() {
+        return mode;
+    }
+
+    @Override
     public K8sApiConfig updateState(State newState) {
         return new Builder()
+                .clusterName(clusterName)
+                .segmentId(segmentId)
+                .extNetworkCidr(extNetworkCidr)
                 .scheme(scheme)
                 .ipAddress(ipAddress)
                 .port(port)
                 .state(newState)
+                .mode(mode)
                 .token(token)
                 .caCertData(caCertData)
                 .clientCertData(clientCertData)
                 .clientKeyData(clientKeyData)
+                .infos(infos)
                 .build();
     }
 
@@ -107,6 +156,11 @@
     }
 
     @Override
+    public Set<HostNodesInfo> infos() {
+        return ImmutableSet.copyOf(infos);
+    }
+
+    @Override
     public boolean equals(Object o) {
         if (this == o) {
             return true;
@@ -117,31 +171,41 @@
         DefaultK8sApiConfig that = (DefaultK8sApiConfig) o;
         return port == that.port &&
                 scheme == that.scheme &&
+                clusterName.equals(that.clusterName) &&
+                segmentId == that.segmentId &&
+                extNetworkCidr == that.extNetworkCidr &&
                 ipAddress.equals(that.ipAddress) &&
+                mode == that.mode &&
                 state == that.state &&
                 token.equals(that.token) &&
                 caCertData.equals(that.caCertData) &&
                 clientCertData.equals(that.clientCertData) &&
-                clientKeyData.equals(that.clientKeyData);
+                clientKeyData.equals(that.clientKeyData) &&
+                infos.equals(that.infos);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(scheme, ipAddress, port, state, token, caCertData,
-                clientCertData, clientKeyData);
+        return Objects.hash(clusterName, segmentId, extNetworkCidr, scheme, ipAddress,
+                port, mode, state, token, caCertData, clientCertData, clientKeyData, infos);
     }
 
     @Override
     public String toString() {
         return MoreObjects.toStringHelper(this)
+                .add("clusterName", clusterName)
+                .add("segmentID", segmentId)
+                .add("extNetworkCIDR", extNetworkCidr)
                 .add("scheme", scheme)
                 .add("ipAddress", ipAddress)
                 .add("port", port)
+                .add("mode", mode)
                 .add("state", state)
                 .add("token", token)
                 .add("caCertData", caCertData)
                 .add("clientCertData", clientCertData)
                 .add("clientKeyData", clientKeyData)
+                .add("infos", infos)
                 .toString();
     }
 
@@ -156,7 +220,11 @@
 
     public static final class Builder implements K8sApiConfig.Builder {
 
+        private String clusterName;
+        private int segmentId;
+        private IpPrefix extNetworkCidr;
         private Scheme scheme;
+        private Mode mode;
         private IpAddress ipAddress;
         private int port;
         private State state;
@@ -164,6 +232,7 @@
         private String caCertData;
         private String clientCertData;
         private String clientKeyData;
+        private Set<HostNodesInfo> infos;
 
         @Override
         public K8sApiConfig build() {
@@ -177,8 +246,38 @@
                 checkArgument(clientKeyData != null, NOT_NULL_MSG, "clientKeyData");
             }
 
-            return new DefaultK8sApiConfig(scheme, ipAddress, port, state, token,
-                    caCertData, clientCertData, clientKeyData);
+            if (StringUtils.isEmpty(clusterName)) {
+                clusterName = DEFAULT_CLUSTER_NAME;
+            }
+
+            if (mode == null) {
+                mode = NORMAL;
+            }
+
+            if (infos == null) {
+                infos = ImmutableSet.of();
+            }
+
+            return new DefaultK8sApiConfig(clusterName, segmentId, extNetworkCidr, scheme, ipAddress,
+                    port, mode, state, token, caCertData, clientCertData, clientKeyData, infos);
+        }
+
+        @Override
+        public Builder clusterName(String clusterName) {
+            this.clusterName = clusterName;
+            return this;
+        }
+
+        @Override
+        public Builder segmentId(int segmentId) {
+            this.segmentId = segmentId;
+            return this;
+        }
+
+        @Override
+        public K8sApiConfig.Builder extNetworkCidr(IpPrefix extNetworkCidr) {
+            this.extNetworkCidr = extNetworkCidr;
+            return this;
         }
 
         @Override
@@ -206,6 +305,12 @@
         }
 
         @Override
+        public K8sApiConfig.Builder mode(Mode mode) {
+            this.mode = mode;
+            return this;
+        }
+
+        @Override
         public Builder token(String token) {
             this.token = token;
             return this;
@@ -228,5 +333,11 @@
             this.clientKeyData = clientKeyData;
             return this;
         }
+
+        @Override
+        public K8sApiConfig.Builder infos(Set<HostNodesInfo> infos) {
+            this.infos = infos;
+            return this;
+        }
     }
 }
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sExternalNetwork.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sExternalNetwork.java
new file mode 100644
index 0000000..cc19ff7
--- /dev/null
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sExternalNetwork.java
@@ -0,0 +1,124 @@
+/*
+ * 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;
+
+/**
+ * Representation of a external network.
+ */
+public class DefaultK8sExternalNetwork implements K8sExternalNetwork {
+
+    private final IpAddress extBridgeIp;
+    private final IpAddress extGatewayIp;
+    private final MacAddress extGatewayMac;
+
+    protected DefaultK8sExternalNetwork(IpAddress extBridgeIp, IpAddress extGatewayIp,
+                                        MacAddress extGatewayMac) {
+        this.extBridgeIp = extBridgeIp;
+        this.extGatewayIp = extGatewayIp;
+        this.extGatewayMac = extGatewayMac;
+    }
+
+    @Override
+    public IpAddress extBridgeIp() {
+        return extBridgeIp;
+    }
+
+    @Override
+    public IpAddress extGatewayIp() {
+        return extGatewayIp;
+    }
+
+    @Override
+    public MacAddress extGatewayMac() {
+        return extGatewayMac;
+    }
+
+    /**
+     * Returns new builder instance.
+     *
+     * @return kubernetes node builder
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        DefaultK8sExternalNetwork that = (DefaultK8sExternalNetwork) o;
+        return extBridgeIp.equals(that.extBridgeIp) &&
+                extGatewayIp.equals(that.extGatewayIp);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(extBridgeIp, extGatewayIp, extGatewayMac);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("extBridgeIp", extBridgeIp)
+                .add("extGatewayIp", extGatewayIp)
+                .add("extGatewayMac", extGatewayMac)
+                .toString();
+    }
+
+    public static final class Builder implements K8sExternalNetwork.Builder {
+
+        private IpAddress extBridgeIp;
+        private IpAddress extGatewayIp;
+        private MacAddress extGatewayMac;
+
+        // private constructor not intended to use from external
+        private Builder() {
+        }
+
+        @Override
+        public K8sExternalNetwork build() {
+            return new DefaultK8sExternalNetwork(extBridgeIp, extGatewayIp, extGatewayMac);
+        }
+
+        @Override
+        public Builder extBridgeIp(IpAddress extBridgeIp) {
+            this.extBridgeIp = extBridgeIp;
+            return this;
+        }
+
+        @Override
+        public Builder extGatewayIp(IpAddress extGatewayIp) {
+            this.extGatewayIp = extGatewayIp;
+            return this;
+        }
+
+        @Override
+        public Builder extGatewayMac(MacAddress extGatewayMac) {
+            this.extGatewayMac = extGatewayMac;
+            return this;
+        }
+    }
+}
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sHost.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sHost.java
new file mode 100644
index 0000000..1d49757
--- /dev/null
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sHost.java
@@ -0,0 +1,171 @@
+/*
+ * 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 com.google.common.collect.ImmutableSet;
+import org.onlab.packet.IpAddress;
+import org.onosproject.net.DeviceId;
+
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Representation of a kubernetes host.
+ */
+public class DefaultK8sHost implements K8sHost {
+
+    private final IpAddress hostIp;
+    private final Set<String> nodeNames;
+    private final K8sHostState state;
+
+    private static final String NOT_NULL_MSG = "Host % cannot be null";
+
+    private static final String OVSDB = "ovsdb:";
+
+    /**
+     * A default constructor of kubernetes host.
+     *
+     * @param hostIp        host IP address
+     * @param nodeNames     node names
+     * @param state         host state
+     */
+    protected DefaultK8sHost(IpAddress hostIp, Set<String> nodeNames,
+                             K8sHostState state) {
+        this.hostIp = hostIp;
+        this.nodeNames = nodeNames;
+        this.state = state;
+    }
+
+    @Override
+    public IpAddress hostIp() {
+        return hostIp;
+    }
+
+    @Override
+    public Set<String> nodeNames() {
+        return ImmutableSet.copyOf(nodeNames);
+    }
+
+    @Override
+    public K8sHostState state() {
+        return state;
+    }
+
+    @Override
+    public DeviceId ovsdb() {
+        return DeviceId.deviceId(OVSDB + hostIp.toString());
+    }
+
+    @Override
+    public K8sHost updateState(K8sHostState newState) {
+        return new Builder()
+                .hostIp(hostIp)
+                .nodeNames(nodeNames)
+                .state(newState)
+                .build();
+    }
+
+    @Override
+    public K8sHost updateNodeNames(Set<String> nodeNames) {
+        return new Builder()
+                .hostIp(hostIp)
+                .nodeNames(nodeNames)
+                .state(state)
+                .build();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        DefaultK8sHost that = (DefaultK8sHost) o;
+        return Objects.equals(hostIp, that.hostIp) &&
+                Objects.equals(nodeNames, that.nodeNames) &&
+                state == that.state;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(hostIp, nodeNames, state);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("hostIp", hostIp)
+                .add("nodeNames", nodeNames)
+                .add("state", state)
+                .toString();
+    }
+
+    /**
+     * Returns new builder instance.
+     *
+     * @return kubernetes host builder
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    public static final class Builder implements K8sHost.Builder {
+
+        private IpAddress hostIp;
+        private Set<String> nodeNames;
+        private K8sHostState state;
+
+        // private constructor not intended to use from external
+        private Builder() {
+        }
+
+        @Override
+        public K8sHost build() {
+            checkArgument(hostIp != null, NOT_NULL_MSG, "hostIp");
+            checkArgument(state != null, NOT_NULL_MSG, "state");
+
+            if (nodeNames == null) {
+                nodeNames = new HashSet<>();
+            }
+
+            return new DefaultK8sHost(hostIp, nodeNames, state);
+        }
+
+        @Override
+        public Builder hostIp(IpAddress hostIp) {
+            this.hostIp = hostIp;
+            return this;
+        }
+
+        @Override
+        public Builder nodeNames(Set<String> nodeNames) {
+            this.nodeNames = nodeNames;
+            return this;
+        }
+
+        @Override
+        public Builder state(K8sHostState state) {
+            this.state = state;
+            return this;
+        }
+    }
+}
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 6a18194..56039b5 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
@@ -16,9 +16,11 @@
 package org.onosproject.k8snode.api;
 
 import com.google.common.base.MoreObjects;
+import org.apache.commons.lang.StringUtils;
 import org.onlab.osgi.DefaultServiceDirectory;
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.MacAddress;
+import org.onosproject.k8snode.api.K8sApiConfig.Mode;
 import org.onosproject.net.Annotations;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Port;
@@ -26,17 +28,25 @@
 import org.onosproject.net.device.DeviceService;
 
 import java.util.Objects;
+import java.util.UUID;
 
 import static com.google.common.base.Preconditions.checkArgument;
+import static org.onosproject.k8snode.api.Constants.DEFAULT_CLUSTER_NAME;
 import static org.onosproject.k8snode.api.Constants.EXTERNAL_BRIDGE;
 import static org.onosproject.k8snode.api.Constants.GENEVE_TUNNEL;
 import static org.onosproject.k8snode.api.Constants.GRE_TUNNEL;
 import static org.onosproject.k8snode.api.Constants.INTEGRATION_BRIDGE;
 import static org.onosproject.k8snode.api.Constants.INTEGRATION_TO_EXTERNAL_BRIDGE;
 import static org.onosproject.k8snode.api.Constants.INTEGRATION_TO_LOCAL_BRIDGE;
+import static org.onosproject.k8snode.api.Constants.INTEGRATION_TO_TUN_BRIDGE;
+import static org.onosproject.k8snode.api.Constants.LOCAL_BRIDGE;
 import static org.onosproject.k8snode.api.Constants.LOCAL_TO_INTEGRATION_BRIDGE;
 import static org.onosproject.k8snode.api.Constants.PHYSICAL_EXTERNAL_BRIDGE;
+import static org.onosproject.k8snode.api.Constants.TUNNEL_BRIDGE;
+import static org.onosproject.k8snode.api.Constants.TUN_TO_INTEGRATION_BRIDGE;
 import static org.onosproject.k8snode.api.Constants.VXLAN_TUNNEL;
+import static org.onosproject.k8snode.api.K8sApiConfig.Mode.NORMAL;
+import static org.onosproject.k8snode.api.K8sApiConfig.Mode.PASSTHROUGH;
 import static org.onosproject.net.AnnotationKeys.PORT_NAME;
 
 /**
@@ -45,19 +55,24 @@
 public class DefaultK8sNode implements K8sNode {
 
     private static final String PORT_MAC = "portMac";
+    private static final String FLOW_KEY = "flow";
 
+    private static final int SHORT_NAME_LENGTH = 10;
+
+    private final String clusterName;
     private final String hostname;
     private final Type type;
+    private final int segmentId;
+    private final Mode mode;
     private final DeviceId intgBridge;
     private final DeviceId extBridge;
     private final DeviceId localBridge;
+    private final DeviceId tunBridge;
     private final IpAddress managementIp;
     private final IpAddress dataIp;
     private final K8sNodeState state;
     private final String extIntf;
-    private final IpAddress extBridgeIp;
-    private final IpAddress extGatewayIp;
-    private final MacAddress extGatewayMac;
+    private final K8sExternalNetwork extNetwork;
     private final String podCidr;
 
     private static final String NOT_NULL_MSG = "Node % cannot be null";
@@ -67,42 +82,81 @@
     /**
      * A default constructor of kubernetes Node.
      *
+     * @param clusterName       clusterName
      * @param hostname          hostname
      * @param type              node type
+     * @param segmentId         segment identifier
+     * @param mode              CNI running mode
      * @param intgBridge        integration bridge
      * @param extBridge         external bridge
      * @param localBridge       local bridge
+     * @param tunBridge         tunnel bridge
      * @param extIntf           external interface
      * @param managementIp      management IP address
      * @param dataIp            data IP address
      * @param state             node state
-     * @param extBridgeIp       external bridge IP address
-     * @param extGatewayIp      external gateway IP address
-     * @param extGatewayMac     external gateway MAC address
+     * @param extNetwork        external network
      * @param podCidr           POD CIDR
      */
-    protected DefaultK8sNode(String hostname, Type type, DeviceId intgBridge,
+    protected DefaultK8sNode(String clusterName, String hostname, Type type,
+                             int segmentId, Mode mode, DeviceId intgBridge,
                              DeviceId extBridge, DeviceId localBridge,
-                             String extIntf, IpAddress managementIp,
+                             DeviceId tunBridge, String extIntf, IpAddress managementIp,
                              IpAddress dataIp, K8sNodeState state,
-                             IpAddress extBridgeIp, IpAddress extGatewayIp,
-                             MacAddress extGatewayMac, String podCidr) {
+                             K8sExternalNetwork extNetwork, String podCidr) {
+        this.clusterName = clusterName;
         this.hostname = hostname;
         this.type = type;
+        this.mode = mode;
+        this.segmentId = segmentId;
         this.intgBridge = intgBridge;
         this.extBridge = extBridge;
         this.localBridge = localBridge;
+        this.tunBridge = tunBridge;
         this.extIntf = extIntf;
         this.managementIp = managementIp;
         this.dataIp = dataIp;
         this.state = state;
-        this.extBridgeIp = extBridgeIp;
-        this.extGatewayIp = extGatewayIp;
-        this.extGatewayMac = extGatewayMac;
+        this.extNetwork = extNetwork;
         this.podCidr = podCidr;
     }
 
     @Override
+    public String clusterName() {
+        return clusterName;
+    }
+
+    @Override
+    public String hostShortName() {
+        return StringUtils.substring(hostname, 0, SHORT_NAME_LENGTH);
+    }
+
+    @Override
+    public String uniqueString(int length) {
+        String uuid = UUID.nameUUIDFromBytes(hostname.getBytes()).toString();
+        return StringUtils.substring(uuid, 0, length);
+    }
+
+    @Override
+    public int segmentId() {
+        return segmentId;
+    }
+
+    @Override
+    public String tunnelKey() {
+        if (mode == PASSTHROUGH) {
+            return String.valueOf(segmentId);
+        } else {
+            return FLOW_KEY;
+        }
+    }
+
+    @Override
+    public Mode mode() {
+        return mode;
+    }
+
+    @Override
     public String hostname() {
         return hostname;
     }
@@ -133,6 +187,11 @@
     }
 
     @Override
+    public DeviceId tunBridge() {
+        return tunBridge;
+    }
+
+    @Override
     public String extIntf() {
         return extIntf;
     }
@@ -141,17 +200,21 @@
     public K8sNode updateIntgBridge(DeviceId deviceId) {
         return new Builder()
                 .hostname(hostname)
+                .clusterName(clusterName)
                 .type(type)
+                .segmentId(segmentId)
+                .mode(mode)
                 .intgBridge(deviceId)
                 .extBridge(extBridge)
                 .localBridge(localBridge)
+                .tunBridge(tunBridge)
                 .extIntf(extIntf)
                 .managementIp(managementIp)
                 .dataIp(dataIp)
                 .state(state)
-                .extBridgeIp(extBridgeIp)
-                .extGatewayIp(extGatewayIp)
-                .extGatewayMac(extGatewayMac)
+                .extBridgeIp(extNetwork.extBridgeIp())
+                .extGatewayIp(extNetwork.extGatewayIp())
+                .extGatewayMac(extNetwork.extGatewayMac())
                 .podCidr(podCidr)
                 .build();
     }
@@ -160,17 +223,21 @@
     public K8sNode updateExtBridge(DeviceId deviceId) {
         return new Builder()
                 .hostname(hostname)
+                .clusterName(clusterName)
                 .type(type)
+                .segmentId(segmentId)
+                .mode(mode)
                 .intgBridge(intgBridge)
                 .extBridge(deviceId)
                 .localBridge(localBridge)
+                .tunBridge(tunBridge)
                 .extIntf(extIntf)
                 .managementIp(managementIp)
                 .dataIp(dataIp)
                 .state(state)
-                .extBridgeIp(extBridgeIp)
-                .extGatewayIp(extGatewayIp)
-                .extGatewayMac(extGatewayMac)
+                .extBridgeIp(extNetwork.extBridgeIp())
+                .extGatewayIp(extNetwork.extGatewayIp())
+                .extGatewayMac(extNetwork.extGatewayMac())
                 .podCidr(podCidr)
                 .build();
     }
@@ -179,17 +246,44 @@
     public K8sNode updateLocalBridge(DeviceId deviceId) {
         return new Builder()
                 .hostname(hostname)
+                .clusterName(clusterName)
                 .type(type)
+                .segmentId(segmentId)
+                .mode(mode)
                 .intgBridge(intgBridge)
                 .extBridge(extBridge)
                 .localBridge(deviceId)
+                .tunBridge(tunBridge)
                 .extIntf(extIntf)
                 .managementIp(managementIp)
                 .dataIp(dataIp)
                 .state(state)
-                .extBridgeIp(extBridgeIp)
-                .extGatewayIp(extGatewayIp)
-                .extGatewayMac(extGatewayMac)
+                .extBridgeIp(extNetwork.extBridgeIp())
+                .extGatewayIp(extNetwork.extGatewayIp())
+                .extGatewayMac(extNetwork.extGatewayMac())
+                .podCidr(podCidr)
+                .build();
+    }
+
+    @Override
+    public K8sNode updateTunBridge(DeviceId deviceId) {
+        return new Builder()
+                .hostname(hostname)
+                .clusterName(clusterName)
+                .type(type)
+                .segmentId(segmentId)
+                .mode(mode)
+                .intgBridge(intgBridge)
+                .extBridge(extBridge)
+                .localBridge(localBridge)
+                .tunBridge(deviceId)
+                .extIntf(extIntf)
+                .managementIp(managementIp)
+                .dataIp(dataIp)
+                .state(state)
+                .extBridgeIp(extNetwork.extBridgeIp())
+                .extGatewayIp(extNetwork.extGatewayIp())
+                .extGatewayMac(extNetwork.extGatewayMac())
                 .podCidr(podCidr)
                 .build();
     }
@@ -218,17 +312,21 @@
     public K8sNode updateState(K8sNodeState newState) {
         return new Builder()
                 .hostname(hostname)
+                .clusterName(clusterName)
                 .type(type)
+                .segmentId(segmentId)
+                .mode(mode)
                 .intgBridge(intgBridge)
                 .extBridge(extBridge)
                 .localBridge(localBridge)
+                .tunBridge(tunBridge)
                 .extIntf(extIntf)
                 .managementIp(managementIp)
                 .dataIp(dataIp)
                 .state(newState)
-                .extBridgeIp(extBridgeIp)
-                .extGatewayIp(extGatewayIp)
-                .extGatewayMac(extGatewayMac)
+                .extBridgeIp(extNetwork.extBridgeIp())
+                .extGatewayIp(extNetwork.extGatewayIp())
+                .extGatewayMac(extNetwork.extGatewayMac())
                 .podCidr(podCidr)
                 .build();
     }
@@ -237,16 +335,20 @@
     public K8sNode updateExtGatewayMac(MacAddress newMac) {
         return new Builder()
                 .hostname(hostname)
+                .clusterName(clusterName)
                 .type(type)
+                .segmentId(segmentId)
+                .mode(mode)
                 .intgBridge(intgBridge)
                 .extBridge(extBridge)
                 .localBridge(localBridge)
+                .tunBridge(tunBridge)
                 .extIntf(extIntf)
                 .managementIp(managementIp)
                 .dataIp(dataIp)
                 .state(state)
-                .extBridgeIp(extBridgeIp)
-                .extGatewayIp(extGatewayIp)
+                .extBridgeIp(extNetwork.extBridgeIp())
+                .extGatewayIp(extNetwork.extGatewayIp())
                 .extGatewayMac(newMac)
                 .podCidr(podCidr)
                 .build();
@@ -254,42 +356,43 @@
 
     @Override
     public PortNumber grePortNum() {
-        return tunnelPortNum(GRE_TUNNEL);
+        return tunnelPortNum(grePortName());
     }
 
     @Override
     public PortNumber vxlanPortNum() {
-        return tunnelPortNum(VXLAN_TUNNEL);
+        return tunnelPortNum(vxlanPortName());
     }
 
     @Override
     public PortNumber genevePortNum() {
-        return tunnelPortNum(GENEVE_TUNNEL);
+        return tunnelPortNum(genevePortName());
     }
 
     @Override
     public PortNumber intgBridgePortNum() {
-        return portNumber(intgBridge, INTEGRATION_BRIDGE);
+        return portNumber(intgBridge, intgBridgePortName());
     }
 
     @Override
     public PortNumber intgToExtPatchPortNum() {
-        return portNumber(intgBridge, INTEGRATION_TO_EXTERNAL_BRIDGE);
+        return portNumber(intgBridge, intgToExtPatchPortName());
     }
 
     @Override
     public PortNumber intgToLocalPatchPortNum() {
-        return portNumber(intgBridge, INTEGRATION_TO_LOCAL_BRIDGE);
+        return portNumber(intgBridge, intgToLocalPatchPortName());
+
     }
 
     @Override
-    public PortNumber localToIntgPatchPortNumber() {
-        return portNumber(localBridge, LOCAL_TO_INTEGRATION_BRIDGE);
+    public PortNumber localToIntgPatchPortNum() {
+        return portNumber(localBridge, localToIntgPatchPortName());
     }
 
     @Override
     public PortNumber extToIntgPatchPortNum() {
-        return portNumber(extBridge, PHYSICAL_EXTERNAL_BRIDGE);
+        return portNumber(extBridge, extToIntgPatchPortName());
     }
 
     @Override
@@ -297,33 +400,176 @@
         if (this.extIntf == null) {
             return null;
         }
-
-        return portNumber(extBridge, this.extIntf);
+        return portNumber(extBridge, extBridgePortName());
     }
 
     @Override
     public MacAddress intgBridgeMac() {
-        return macAddress(intgBridge, INTEGRATION_BRIDGE);
+        return macAddress(intgBridge, intgBridgeName());
     }
 
     @Override
     public IpAddress extBridgeIp() {
-        return extBridgeIp;
+        return extNetwork.extBridgeIp();
     }
 
     @Override
     public MacAddress extBridgeMac() {
-        return macAddress(extBridge, EXTERNAL_BRIDGE);
+        return macAddress(extBridge, extBridgeName());
     }
 
     @Override
     public IpAddress extGatewayIp() {
-        return extGatewayIp;
+        return extNetwork.extGatewayIp();
     }
 
     @Override
     public MacAddress extGatewayMac() {
-        return extGatewayMac;
+        return extNetwork.extGatewayMac();
+    }
+
+    @Override
+    public String grePortName() {
+        if (mode == PASSTHROUGH) {
+            return GRE_TUNNEL + "-" + segmentId;
+        } else {
+            return GRE_TUNNEL;
+        }
+    }
+
+    @Override
+    public String vxlanPortName() {
+        if (mode == PASSTHROUGH) {
+            return VXLAN_TUNNEL + "-" + segmentId;
+        } else {
+            return VXLAN_TUNNEL;
+        }
+    }
+
+    @Override
+    public String genevePortName() {
+        if (mode == PASSTHROUGH) {
+            return GENEVE_TUNNEL + "-" + segmentId;
+        } else {
+            return GENEVE_TUNNEL;
+        }
+    }
+
+    @Override
+    public String intgBridgeName() {
+        if (mode == PASSTHROUGH) {
+            return INTEGRATION_BRIDGE + "-" + uniqueString(5);
+        } else {
+            return INTEGRATION_BRIDGE;
+        }
+    }
+
+    @Override
+    public String extBridgeName() {
+        if (mode == PASSTHROUGH) {
+            return EXTERNAL_BRIDGE + "-" + uniqueString(5);
+        } else {
+            return EXTERNAL_BRIDGE;
+        }
+    }
+
+    @Override
+    public String localBridgeName() {
+        if (mode == PASSTHROUGH) {
+            return LOCAL_BRIDGE + "-" + uniqueString(5);
+        } else {
+            return LOCAL_BRIDGE;
+        }
+    }
+
+    @Override
+    public String tunBridgeName() {
+        if (mode == PASSTHROUGH) {
+            return TUNNEL_BRIDGE + "-" + segmentId;
+        } else {
+            return TUNNEL_BRIDGE;
+        }
+    }
+
+    @Override
+    public String intgBridgePortName() {
+        if (mode == PASSTHROUGH) {
+            return INTEGRATION_BRIDGE + "-" + uniqueString(5);
+        } else {
+            return INTEGRATION_BRIDGE;
+        }
+    }
+
+    @Override
+    public String extBridgePortName() {
+        if (mode == PASSTHROUGH) {
+            return EXTERNAL_BRIDGE + "-" + uniqueString(5);
+        } else {
+            return EXTERNAL_BRIDGE;
+        }
+    }
+
+    @Override
+    public String localBridgePortName() {
+        if (mode == PASSTHROUGH) {
+            return LOCAL_BRIDGE + "-" + uniqueString(5);
+        } else {
+            return LOCAL_BRIDGE;
+        }
+    }
+
+    @Override
+    public String intgToExtPatchPortName() {
+        if (mode == PASSTHROUGH) {
+            return INTEGRATION_TO_EXTERNAL_BRIDGE + "-" + uniqueString(5);
+        } else {
+            return INTEGRATION_TO_EXTERNAL_BRIDGE;
+        }
+    }
+
+    @Override
+    public String intgToTunPatchPortName() {
+        if (mode == PASSTHROUGH) {
+            return INTEGRATION_TO_TUN_BRIDGE + "-" + uniqueString(5);
+        } else {
+            return INTEGRATION_TO_TUN_BRIDGE;
+        }
+    }
+
+    @Override
+    public String intgToLocalPatchPortName() {
+        if (mode == PASSTHROUGH) {
+            return INTEGRATION_TO_LOCAL_BRIDGE + "-" + uniqueString(5);
+        } else {
+            return INTEGRATION_TO_LOCAL_BRIDGE;
+        }
+    }
+
+    @Override
+    public String localToIntgPatchPortName() {
+        if (mode == PASSTHROUGH) {
+            return LOCAL_TO_INTEGRATION_BRIDGE + "-" + uniqueString(5);
+        } else {
+            return LOCAL_TO_INTEGRATION_BRIDGE;
+        }
+    }
+
+    @Override
+    public String extToIntgPatchPortName() {
+        if (mode == PASSTHROUGH) {
+            return PHYSICAL_EXTERNAL_BRIDGE + "-" + uniqueString(5);
+        } else {
+            return PHYSICAL_EXTERNAL_BRIDGE;
+        }
+    }
+
+    @Override
+    public String tunToIntgPatchPortName() {
+        if (mode == PASSTHROUGH) {
+            return TUN_TO_INTEGRATION_BRIDGE + "-" + uniqueString(5);
+        } else {
+            return TUN_TO_INTEGRATION_BRIDGE;
+        }
     }
 
     @Override
@@ -335,16 +581,19 @@
         if (obj instanceof DefaultK8sNode) {
             DefaultK8sNode that = (DefaultK8sNode) obj;
 
-            return hostname.equals(that.hostname) &&
+            return clusterName.equals(that.clusterName) &&
+                    hostname.equals(that.hostname) &&
                     type == that.type &&
+                    segmentId == that.segmentId &&
+                    mode == that.mode &&
                     intgBridge.equals(that.intgBridge) &&
                     extBridge.equals(that.extBridge) &&
                     localBridge.equals(that.localBridge) &&
+                    tunBridge.equals(that.tunBridge) &&
                     extIntf.equals(that.extIntf) &&
                     managementIp.equals(that.managementIp) &&
                     dataIp.equals(that.dataIp) &&
-                    extBridgeIp.equals(that.extBridgeIp) &&
-                    extGatewayIp.equals(that.extGatewayIp) &&
+                    extNetwork.equals(that.extNetwork) &&
                     podCidr.equals(that.podCidr) &&
                     state == that.state;
         }
@@ -354,26 +603,29 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(hostname, type, intgBridge, extBridge, localBridge,
-                            extIntf, managementIp, dataIp, state, extBridgeIp,
-                            extGatewayIp, extGatewayMac, podCidr);
+        return Objects.hash(clusterName, hostname, type, segmentId, mode, intgBridge, extBridge,
+                localBridge, tunBridge, extIntf, managementIp, dataIp, state, extNetwork, podCidr);
     }
 
     @Override
     public String toString() {
         return MoreObjects.toStringHelper(this)
+                .add("clusterName", clusterName)
                 .add("hostname", hostname)
                 .add("type", type)
+                .add("segmentId", segmentId)
+                .add("mode", mode)
                 .add("intgBridge", intgBridge)
                 .add("extBridge", extBridge)
                 .add("localBridge", localBridge)
+                .add("tunBridge", tunBridge)
                 .add("extIntf", extIntf)
                 .add("managementIp", managementIp)
                 .add("dataIp", dataIp)
                 .add("state", state)
-                .add("extBridgeIp", extBridgeIp)
-                .add("extGatewayIp", extGatewayIp)
-                .add("extGatewayMac", extGatewayMac)
+                .add("extBridgeIp", extNetwork.extBridgeIp())
+                .add("extGatewayIp", extNetwork.extGatewayIp())
+                .add("extGatewayMac", extNetwork.extGatewayMac())
                 .add("podCidr", podCidr)
                 .toString();
     }
@@ -383,7 +635,7 @@
             return null;
         }
 
-        return portNumber(intgBridge, tunnelType);
+        return portNumber(tunBridge, tunnelType);
     }
 
     private MacAddress macAddress(DeviceId deviceId, String portName) {
@@ -423,10 +675,13 @@
     public static Builder from(K8sNode node) {
         return new Builder()
                 .hostname(node.hostname())
+                .clusterName(node.clusterName())
                 .type(node.type())
+                .segmentId(node.segmentId())
                 .intgBridge(node.intgBridge())
                 .extBridge(node.extBridge())
                 .localBridge(node.localBridge())
+                .tunBridge(node.tunBridge())
                 .extIntf(node.extIntf())
                 .managementIp(node.managementIp())
                 .dataIp(node.dataIp())
@@ -439,11 +694,15 @@
 
     public static final class Builder implements K8sNode.Builder {
 
+        private String clusterName;
         private String hostname;
         private Type type;
+        private int segmentId;
+        private Mode mode;
         private DeviceId intgBridge;
         private DeviceId extBridge;
         private DeviceId localBridge;
+        private DeviceId tunBridge;
         private IpAddress managementIp;
         private IpAddress dataIp;
         private K8sNodeState state;
@@ -465,22 +724,44 @@
             checkArgument(state != null, NOT_NULL_MSG, "state");
             checkArgument(managementIp != null, NOT_NULL_MSG, "management IP");
 
-            return new DefaultK8sNode(hostname,
+            if (StringUtils.isEmpty(clusterName)) {
+                clusterName = DEFAULT_CLUSTER_NAME;
+            }
+
+            if (mode == null) {
+                mode = NORMAL;
+            }
+
+            K8sExternalNetwork extNetwork = DefaultK8sExternalNetwork.builder()
+                    .extBridgeIp(extBridgeIp)
+                    .extGatewayIp(extGatewayIp)
+                    .extGatewayMac(extGatewayMac)
+                    .build();
+
+            return new DefaultK8sNode(clusterName,
+                    hostname,
                     type,
+                    segmentId,
+                    mode,
                     intgBridge,
                     extBridge,
                     localBridge,
+                    tunBridge,
                     extIntf,
                     managementIp,
                     dataIp,
                     state,
-                    extBridgeIp,
-                    extGatewayIp,
-                    extGatewayMac,
+                    extNetwork,
                     podCidr);
         }
 
         @Override
+        public Builder clusterName(String clusterName) {
+            this.clusterName = clusterName;
+            return this;
+        }
+
+        @Override
         public Builder hostname(String hostname) {
             this.hostname = hostname;
             return this;
@@ -493,6 +774,18 @@
         }
 
         @Override
+        public Builder segmentId(int segmentId) {
+            this.segmentId = segmentId;
+            return this;
+        }
+
+        @Override
+        public Builder mode(Mode mode) {
+            this.mode = mode;
+            return this;
+        }
+
+        @Override
         public Builder intgBridge(DeviceId deviceId) {
             this.intgBridge = deviceId;
             return this;
@@ -511,6 +804,12 @@
         }
 
         @Override
+        public Builder tunBridge(DeviceId deviceId) {
+            this.tunBridge = deviceId;
+            return this;
+        }
+
+        @Override
         public Builder extIntf(String intf) {
             this.extIntf = intf;
             return this;
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/ExternalNetworkService.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/ExternalNetworkService.java
new file mode 100644
index 0000000..4a66e26
--- /dev/null
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/ExternalNetworkService.java
@@ -0,0 +1,73 @@
+/*
+ * 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 org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+
+import java.util.Set;
+
+/**
+ * A service manages external network objects including IP addresses.
+ */
+public interface ExternalNetworkService {
+
+    /**
+     * Registers an external network.
+     *
+     * @param cidr network CIDR
+     */
+    void registerNetwork(IpPrefix cidr);
+
+    /**
+     * Unregisters an existing external network.
+     *
+     * @param cidr network CIDR
+     */
+    void unregisterNetwork(IpPrefix cidr);
+
+    /**
+     * Obtains a gateway IP address of the given network CIDR.
+     *
+     * @param cidr network CIDR
+     * @return a gateway IP address
+     */
+    IpAddress getGatewayIp(IpPrefix cidr);
+
+    /**
+     * Obtains an allocated IP address of the given network CIDR.
+     *
+     * @param cidr network CIDR
+     * @return an IP address exists in the given network CIDR IP pool
+     */
+    IpAddress allocateIp(IpPrefix cidr);
+
+    /**
+     * Releases the given IP address to the given network CIDR.
+     *
+     * @param cidr network CIDR
+     * @param ip IP address to be released
+     */
+    void releaseIp(IpPrefix cidr, IpAddress ip);
+
+    /**
+     * Obtains all IP addresses of the given network CIDR.
+     *
+     * @param cidr network CIDR
+     * @return all IP addresses
+     */
+    Set<String> getAllIps(IpPrefix cidr);
+}
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/HostNodesInfo.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/HostNodesInfo.java
new file mode 100644
index 0000000..c420d20
--- /dev/null
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/HostNodesInfo.java
@@ -0,0 +1,69 @@
+/*
+ * 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 org.onlab.packet.IpAddress;
+
+import java.util.Set;
+
+/**
+ * Representation of host and kubernetes nodes mapping info.
+ */
+public interface HostNodesInfo {
+
+    /**
+     * Returns the host's IP address.
+     *
+     * @return host IP address
+     */
+    IpAddress hostIp();
+
+    /**
+     * Returns the list of nodes associated with the host.
+     *
+     * @return a set of node's names
+     */
+    Set<String> nodes();
+
+    /**
+     * Builder of new HostNodesInfo entity.
+     */
+    interface Builder {
+
+        /**
+         * Builds an immutable host IP to nodes mapping instance.
+         *
+         * @return HostNodesInfo instance
+         */
+        HostNodesInfo build();
+
+        /**
+         * Returns HostNodesInfo builder with host IP address.
+         *
+         * @param hostIp host IP address
+         * @return HostNodesInfo builder
+         */
+        Builder hostIp(IpAddress hostIp);
+
+        /**
+         * Returns HostNodesInfo builder with nodes.
+         *
+         * @param nodes a set of node's names
+         * @return HostNodesInfo builder
+         */
+        Builder nodes(Set<String> nodes);
+    }
+}
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sApiConfig.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sApiConfig.java
index 62d050d..d01f3a2 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sApiConfig.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sApiConfig.java
@@ -16,6 +16,9 @@
 package org.onosproject.k8snode.api;
 
 import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+
+import java.util.Set;
 
 /**
  * Representation of configuration used in kubernetes API server.
@@ -52,6 +55,46 @@
         DISCONNECTED,
     }
 
+    enum Mode {
+        /**
+         * Signifies that the CNI is running in normal mode.
+         */
+        NORMAL,
+
+        /**
+         * Signifies that the CNI is running in pass-through mode.
+         */
+        PASSTHROUGH,
+    }
+
+    /**
+     * Returns the cluster name.
+     *
+     * @return cluster name
+     */
+    String clusterName();
+
+    /**
+     * Returns cluster short name.
+     *
+     * @return cluster short name
+     */
+    String clusterShortName();
+
+    /**
+     * Returns the segmentation ID.
+     *
+     * @return segmentation ID
+     */
+    int segmentId();
+
+    /**
+     * Returns the external network CIDR.
+     *
+     * @return external network CIDR
+     */
+    IpPrefix extNetworkCidr();
+
     /**
      * Returns the authentication scheme.
      *
@@ -81,6 +124,13 @@
     State state();
 
     /**
+     * Returns the CNI running mode.
+     *
+     * @return running mode
+     */
+    Mode mode();
+
+    /**
      * Returns new kubernetes API config instance with given state.
      *
      * @param newState updated state
@@ -117,6 +167,13 @@
     String clientKeyData();
 
     /**
+     * Returns the host Nodes info set.
+     *
+     * @return host nodes info set
+     */
+    Set<HostNodesInfo> infos();
+
+    /**
      * Builder of new API config entity.
      */
     interface Builder {
@@ -129,6 +186,30 @@
         K8sApiConfig build();
 
         /**
+         * Returns kubernetes API server config builder with cluster name.
+         *
+         * @param clusterName cluster name
+         * @return kubernetes API config builder
+         */
+        Builder clusterName(String clusterName);
+
+        /**
+         * Returns kubernetes API server config builder with segment ID.
+         *
+         * @param segmentId segment ID
+         * @return kubernetes API config builder
+         */
+        Builder segmentId(int segmentId);
+
+        /**
+         * Returns kubernetes API server config builder with external network CIDR.
+         *
+         * @param extNetworkCidr external network CIDR
+         * @return kubernetes API config builder
+         */
+        Builder extNetworkCidr(IpPrefix extNetworkCidr);
+
+        /**
          * Returns kubernetes API server config builder with supplied scheme.
          *
          * @param scheme scheme of authentication
@@ -161,6 +242,14 @@
         Builder state(State state);
 
         /**
+         * Returns kubernetes API server config builder with supplied mode.
+         *
+         * @param mode CNI running mode
+         * @return kubernetes API config builder
+         */
+        Builder mode(Mode mode);
+
+        /**
          * Returns kubernetes API server config builder with supplied token.
          *
          * @param token token for authentication
@@ -191,5 +280,13 @@
          * @return kubernetes API config builder
          */
         Builder clientKeyData(String clientKeyData);
+
+        /**
+         * Returns kubernetes API server config builder with supplied hostNodesInfo.
+         *
+         * @param infos hostNodesInfo
+         * @return kubernetes API config builder
+         */
+        Builder infos(Set<HostNodesInfo> infos);
     }
 }
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sExternalNetwork.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sExternalNetwork.java
new file mode 100644
index 0000000..3462ad0
--- /dev/null
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sExternalNetwork.java
@@ -0,0 +1,83 @@
+/*
+ * 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 org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+
+/**
+ * Representation of an external network.
+ */
+public interface K8sExternalNetwork {
+
+    /**
+     * Returns the external bridge's IP address.
+     *
+     * @return IP address; null if the IP address does not exist
+     */
+    IpAddress extBridgeIp();
+
+    /**
+     * Returns the external gateway IP address.
+     *
+     * @return IP address; null if the IP address does not exist
+     */
+    IpAddress extGatewayIp();
+
+    /**
+     * Returns the external gateway MAC address.
+     *
+     * @return MAC address; null if the MAC address does not exist
+     */
+    MacAddress extGatewayMac();
+
+    /**
+     * Builder of new network entity.
+     */
+    interface Builder {
+
+        /**
+         * Builds an immutable kubernetes external network instance.
+         *
+         * @return kubernetes external network
+         */
+        K8sExternalNetwork build();
+
+        /**
+         * Returns kubernetes node builder with supplied external bridge IP.
+         *
+         * @param extBridgeIp external bridge IP
+         * @return kubernetes node builder
+         */
+        Builder extBridgeIp(IpAddress extBridgeIp);
+
+        /**
+         * Returns kubernetes node builder with supplied gateway IP.
+         *
+         * @param extGatewayIp external gateway IP
+         * @return kubernetes node builder
+         */
+        Builder extGatewayIp(IpAddress extGatewayIp);
+
+        /**
+         * Returns kubernetes node builder with supplied external gateway MAC.
+         *
+         * @param extGatewayMac external gateway MAC address
+         * @return kubernetes node builder
+         */
+        Builder extGatewayMac(MacAddress extGatewayMac);
+    }
+}
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHost.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHost.java
new file mode 100644
index 0000000..c93d4d1
--- /dev/null
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHost.java
@@ -0,0 +1,109 @@
+/*
+ * 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 org.onlab.packet.IpAddress;
+import org.onosproject.net.DeviceId;
+
+import java.util.Set;
+
+/**
+ * Representation of a host used in k8s-networking service.
+ */
+public interface K8sHost {
+
+    /**
+     * Returns the host IP address. Note that the host IP address is unique, and
+     * will be used as an identifier for the host.
+     *
+     * @return host IP address
+     */
+    IpAddress hostIp();
+
+    /**
+     * A set of node names included in this host.
+     *
+     * @return node names
+     */
+    Set<String> nodeNames();
+
+    /**
+     * Returns kubernetes host state.
+     *
+     * @return host state
+     */
+    K8sHostState state();
+
+    /**
+     * Returns the OVSDB device ID of the node.
+     *
+     * @return ovsdb device ID
+     */
+    DeviceId ovsdb();
+
+    /**
+     * Returns new kubernetes host instance with given state.
+     *
+     * @param newState updated state
+     * @return updated kubernetes host
+     */
+    K8sHost updateState(K8sHostState newState);
+
+    /**
+     * Returns new kuberentes host instance with given node names.
+     *
+     * @param nodeNames a set of node names
+     * @return updated kubernetes host
+     */
+    K8sHost updateNodeNames(Set<String> nodeNames);
+
+    /**
+     * Builder of new host entity.
+     */
+    interface Builder {
+
+        /**
+         * Builds an immutable kubernetes host instance.
+         *
+         * @return kubernetes host instance
+         */
+        K8sHost build();
+
+        /**
+         * Returns kubernetes host builder with supplied host IP address.
+         *
+         * @param hostIp host IP address
+         * @return kubernetes host builder
+         */
+        Builder hostIp(IpAddress hostIp);
+
+        /**
+         * Returns kubernetes host builder with supplied node names.
+         *
+         * @param nodeNames node names
+         * @return kubernetes host builder
+         */
+        Builder nodeNames(Set<String> nodeNames);
+
+        /**
+         * Returns kubernetes host builder with supplied host state.
+         *
+         * @param state host state
+         * @return kubernetes host builder
+         */
+        Builder state(K8sHostState state);
+    }
+}
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostAdminService.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostAdminService.java
new file mode 100644
index 0000000..d3f2861
--- /dev/null
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostAdminService.java
@@ -0,0 +1,46 @@
+/*
+ * 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 org.onlab.packet.IpAddress;
+
+/**
+ * Service for administering inventory of Kubernetes hosts.
+ */
+public interface K8sHostAdminService extends K8sHostService {
+
+    /**
+     * Creates a new host.
+     *
+     * @param host kubernetes host
+     */
+    void createHost(K8sHost host);
+
+    /**
+     * Updates the host.
+     *
+     * @param host kubernetes host
+     */
+    void updateHost(K8sHost host);
+
+    /**
+     * Removes the host.
+     *
+     * @param hostIp kubernetes host IP address
+     * @return removed host; null if the host does not exist
+     */
+    K8sHost removeHost(IpAddress hostIp);
+}
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostEvent.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostEvent.java
new file mode 100644
index 0000000..a403d0e
--- /dev/null
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostEvent.java
@@ -0,0 +1,75 @@
+/*
+ * 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 org.onosproject.event.AbstractEvent;
+
+/**
+ * Describes Kubernetes host init state event.
+ */
+public class K8sHostEvent extends AbstractEvent<K8sHostEvent.Type, K8sHost> {
+
+    /**
+     * Lists of kubernetes host event types.
+     */
+    public enum Type {
+
+        /**
+         * Signifies that new host is created.
+         */
+        K8S_HOST_CREATED,
+
+        /**
+         * Signifies that the host is updated.
+         */
+        K8S_HOST_UPDATED,
+
+        /**
+         * Signifies that the host state is completed.
+         */
+        K8S_HOST_COMPLETE,
+
+        /**
+         * Signifies that the host is removed.
+         */
+        K8S_HOST_REMOVED,
+
+        /**
+         * Signifies that the host state is incomplete.
+         */
+        K8S_HOST_INCOMPLETE,
+
+        /**
+         * Signifies that a set of nodes have been added into the host.
+         */
+        K8S_NODES_ADDED,
+
+        /**
+         * Signifies that a set of nodes have been removed from the host.
+         */
+        K8S_NODES_REMOVED,
+    }
+
+    /**
+     * Creates an event with the given type and host.
+     *
+     * @param type event type
+     * @param subject kubernetes host
+     */
+    public K8sHostEvent(Type type, K8sHost subject) {
+        super(type, subject);
+    }
+}
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostHandler.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostHandler.java
new file mode 100644
index 0000000..335c89c
--- /dev/null
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostHandler.java
@@ -0,0 +1,45 @@
+/*
+ * 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;
+
+/**
+ * Service handling kubernetes host stats.
+ */
+public interface K8sHostHandler {
+
+    /**
+     * Processes the given host for init state.
+     * It creates required bridges on OVS by referring to host type.zw
+     *
+     * @param k8sHost kubernetes host
+     */
+    void processInitState(K8sHost k8sHost);
+
+    /**
+     * Processes the given host for complete state.
+     * It performs post-init jobs for the complete host.
+     *
+     * @param k8sHost kubernetes host
+     */
+    void processCompleteState(K8sHost k8sHost);
+
+    /**
+     * Processes the given host for incomplete state.
+     *
+     * @param k8sHost kubernetes host
+     */
+    void processIncompleteState(K8sHost k8sHost);
+}
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostListener.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostListener.java
new file mode 100644
index 0000000..edf5763
--- /dev/null
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostListener.java
@@ -0,0 +1,24 @@
+/*
+ * 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 org.onosproject.event.EventListener;
+
+/**
+ * Listener for Kubernetes Host event.
+ */
+public interface K8sHostListener extends EventListener<K8sHostEvent> {
+}
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostService.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostService.java
new file mode 100644
index 0000000..abdbb74
--- /dev/null
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostService.java
@@ -0,0 +1,51 @@
+/*
+ * 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 org.onlab.packet.IpAddress;
+import org.onosproject.event.ListenerService;
+
+import java.util.Set;
+
+/**
+ * Service for interfacing with the inventory of Kubernetes host.
+ */
+public interface K8sHostService extends ListenerService<K8sHostEvent, K8sHostListener> {
+
+    String APP_ID = "org.onosproject.k8snode";
+
+    /**
+     * Returns all registered hosts.
+     *
+     * @return set of kubernetes hosts
+     */
+    Set<K8sHost> hosts();
+
+    /**
+     * Returns all hosts with complete states.
+     *
+     * @return set of kubernetes hosts
+     */
+    Set<K8sHost> completeHosts();
+
+    /**
+     * Returns the host with the specified IP address.
+     *
+     * @param hostIp host IP address
+     * @return kubernetes host
+     */
+    K8sHost host(IpAddress hostIp);
+}
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostState.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostState.java
new file mode 100644
index 0000000..f9a07c3
--- /dev/null
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostState.java
@@ -0,0 +1,80 @@
+/*
+ * 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;
+
+/**
+ * Defines the initialization state of Kubernetes host.
+ */
+public enum K8sHostState {
+
+    /**
+     * Indicates the host is newly added.
+     */
+    INIT {
+        @Override
+        public void process(K8sHostHandler handler, K8sHost host) {
+            handler.processInitState(host);
+        }
+
+        @Override
+        public K8sHostState nextState() {
+            return COMPLETE;
+        }
+    },
+    /**
+     * Indicates the host initialization is done.
+     */
+    COMPLETE {
+        @Override
+        public void process(K8sHostHandler handler, K8sHost host) {
+            handler.processCompleteState(host);
+        }
+
+        @Override
+        public K8sHostState nextState() {
+            return COMPLETE;
+        }
+    },
+    /**
+     * Indicates host is broken.
+     */
+    INCOMPLETE {
+        @Override
+        public void process(K8sHostHandler handler, K8sHost host) {
+            handler.processIncompleteState(host);
+        }
+
+        @Override
+        public K8sHostState nextState() {
+            return INIT;
+        }
+    };
+
+    /**
+     * Processes the given host which is under a certain state.
+     *
+     * @param handler kubernetes host handler
+     * @param host kubernetes host
+     */
+    public abstract void process(K8sHostHandler handler, K8sHost host);
+
+    /**
+     * Transits to the next state.
+     *
+     * @return the next kubernetes host state
+     */
+    public abstract K8sHostState nextState();
+}
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostStore.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostStore.java
new file mode 100644
index 0000000..aec871a
--- /dev/null
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostStore.java
@@ -0,0 +1,64 @@
+/*
+ * 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 org.onlab.packet.IpAddress;
+import org.onosproject.store.Store;
+
+import java.util.Set;
+
+/**
+ * Manages inventory of Kubernetes Host; not intended for direct use.
+ */
+public interface K8sHostStore extends Store<K8sHostEvent, K8sHostStoreDelegate> {
+
+    /**
+     * Creates a new host.
+     *
+     * @param host kubernetes host
+     */
+    void createHost(K8sHost host);
+
+    /**
+     * Updates the host.
+     *
+     * @param host kubernetes host
+     */
+    void updateHost(K8sHost host);
+
+    /**
+     * Removes the host with the given host IP.
+     *
+     * @param hostIp kubernetes host IP
+     * @return removed kubernetes host; null if no host is associated with the host IP
+     */
+    K8sHost removeHost(IpAddress hostIp);
+
+    /**
+     * Returns all registered hosts.
+     *
+     * @return set of kubernetes hosts
+     */
+    Set<K8sHost> hosts();
+
+    /**
+     * Returns the host with the specified host IP.
+     *
+     * @param hostIp host IP address
+     * @return kubernetes host
+     */
+    K8sHost host(IpAddress hostIp);
+}
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostStoreDelegate.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostStoreDelegate.java
new file mode 100644
index 0000000..2c863db
--- /dev/null
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHostStoreDelegate.java
@@ -0,0 +1,25 @@
+/*
+ * 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 org.onosproject.store.StoreDelegate;
+
+/**
+ * Kubernetes Host store delegate.
+ */
+public interface K8sHostStoreDelegate extends StoreDelegate<K8sHostEvent> {
+}
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 055b0df..8931b45 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
@@ -17,6 +17,7 @@
 
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.MacAddress;
+import org.onosproject.k8snode.api.K8sApiConfig.Mode;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.PortNumber;
 
@@ -37,10 +38,53 @@
         /**
          * Signifies that this is a kubernetes minion node.
          */
-        MINION
+        MINION,
     }
 
     /**
+     * Returns cluster name of the node.
+     *
+     * @return cluster name
+     */
+    String clusterName();
+
+    /**
+     * Returns host short name.
+     *
+     * @return host short name
+     */
+    String hostShortName();
+
+    /**
+     * Returns a unique string with the given length and string.
+     *
+     * @param length target string length
+     * @return a unique string
+     */
+    String uniqueString(int length);
+
+    /**
+     * Returns the segmentation ID.
+     *
+     * @return segmentation ID
+     */
+    int segmentId();
+
+    /**
+     * Returns the key of VXLAN/GRE/GENEVE tunnel.
+     *
+     * @return key of various tunnel
+     */
+    String tunnelKey();
+
+    /**
+     * Returns the CNI running mode.
+     *
+     * @return CNI running mode
+     */
+    Mode mode();
+
+    /**
      * Returns hostname of the node.
      *
      * @return hostname
@@ -83,6 +127,13 @@
     DeviceId localBridge();
 
     /**
+     * Returns the device ID of the tunnel bridge at the node.
+     *
+     * @return device id
+     */
+    DeviceId tunBridge();
+
+    /**
      * Returns the external interface name.
      *
      * @return external interface name
@@ -114,6 +165,14 @@
     K8sNode updateLocalBridge(DeviceId deviceId);
 
     /**
+     * Returns new kubernetes node instance with given tun bridge.
+     *
+     * @param deviceId tunnel bridge device ID
+     * @return updated kubernetes node
+     */
+    K8sNode updateTunBridge(DeviceId deviceId);
+
+    /**
      * Returns the management network IP address of the node.
      *
      * @return ip address
@@ -158,6 +217,118 @@
     K8sNode updateExtGatewayMac(MacAddress macAddress);
 
     /**
+     * Returns GRE port name.
+     *
+     * @return GRE port name
+     */
+    String grePortName();
+
+    /**
+     * Returns VXLAN port name.
+     *
+     * @return VXLAN port name
+     */
+    String vxlanPortName();
+
+    /**
+     * Returns GENEVE port name.
+     *
+     * @return GENEVE port name
+     */
+    String genevePortName();
+
+    /**
+     * Returns integration bridge name.
+     *
+     * @return integration bridge name
+     */
+    String intgBridgeName();
+
+    /**
+     * Returns external bridge name.
+     *
+     * @return external bridge name
+     */
+    String extBridgeName();
+
+    /**
+     * Returns local bridge name.
+     *
+     * @return local bridge name
+     */
+    String localBridgeName();
+
+    /**
+     * Returns tun bridge name.
+     *
+     * @return tun bridge name
+     */
+    String tunBridgeName();
+
+    /**
+     * Returns integration bridge port name.
+     *
+     * @return integration bridge port name
+     */
+    String intgBridgePortName();
+
+    /**
+     * Returns external bridge port name.
+     *
+     * @return external bridge port name
+     */
+    String extBridgePortName();
+
+    /**
+     * Returns local bridge port name.
+     *
+     * @return local bridge port name
+     */
+    String localBridgePortName();
+
+    /**
+     * Returns integration to external patch port name.
+     *
+     * @return integration to external patch port name
+     */
+    String intgToExtPatchPortName();
+
+    /**
+     * Returns integration to tunnel patch port name.
+     *
+     * @return integration to tunnel patch port name
+     */
+    String intgToTunPatchPortName();
+
+    /**
+     * Returns integration to local patch port name.
+     *
+     * @return integration to local patch port name
+     */
+    String intgToLocalPatchPortName();
+
+    /**
+     * Returns local to integration patch port name.
+     *
+     * @return local to integration patch port name
+     */
+    String localToIntgPatchPortName();
+
+    /**
+     * Returns external to integration patch port name.
+     *
+     * @return external to integration patch port name
+     */
+    String extToIntgPatchPortName();
+
+    /**
+     * Returns tunnel to integration patch port name.
+     *
+     * @return tunnel to integration patch port name
+     */
+    String tunToIntgPatchPortName();
+
+    /**
      * Returns the GRE tunnel port number.
      *
      * @return GRE port number; null if the GRE tunnel port does not exist
@@ -204,7 +375,7 @@
      *
      * @return patch port number
      */
-    PortNumber localToIntgPatchPortNumber();
+    PortNumber localToIntgPatchPortNum();
 
     /**
      * Returns the external to integration patch port number.
@@ -268,6 +439,14 @@
         K8sNode build();
 
         /**
+         * Returns kubernetes node builder with supplied cluster name.
+         *
+         * @param clusterName cluster name
+         * @return kubernetes node builder
+         */
+        Builder clusterName(String clusterName);
+
+        /**
          * Returns kubernetes node builder with supplied hostname.
          *
          * @param hostname hostname of the node
@@ -284,6 +463,22 @@
         Builder type(Type type);
 
         /**
+         * Returns kubernetes node builder with supplied segment ID.
+         *
+         * @param segmentId kubernetes node segment ID
+         * @return kubernetes node builder
+         */
+        Builder segmentId(int segmentId);
+
+        /**
+         * Return kubernetes node builder with supplied mode.
+         *
+         * @param mode kubernetes CNI running mode
+         * @return kubernetes node builder
+         */
+        Builder mode(Mode mode);
+
+        /**
          * Returns kubernetes node builder with supplied integration bridge name.
          *
          * @param deviceId integration bridge device ID
@@ -308,6 +503,14 @@
         Builder localBridge(DeviceId deviceId);
 
         /**
+         * Returns kubernetes node builder with supplied tunnel bridge name.
+         *
+         * @param deviceId tunnel bridge device ID
+         * @return kubernetes node builder
+         */
+        Builder tunBridge(DeviceId deviceId);
+
+        /**
          * Returns kubernetes node builder with supplied external interface.
          *
          * @param intf external interface
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNodeService.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNodeService.java
index 455e42c..96ce129 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNodeService.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNodeService.java
@@ -36,6 +36,14 @@
     Set<K8sNode> nodes();
 
     /**
+     * Returns kubernetes nodes associated with cluster name.
+     *
+     * @param clusterName cluster name
+     * @return set of kubernetes nodes
+     */
+    Set<K8sNode> nodes(String clusterName);
+
+    /**
      * Returns all nodes with the specified type.
      *
      * @param type node type