Inject API svc FQDN into kubevirt node, let onos resolve API svc IP

Change-Id: Idb4294a31353fb9a0e22df45ca6507c2895ed738
(cherry picked from commit 331ef702538931f506f8b65d9844a5c115876343)
diff --git a/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/DefaultKubevirtApiConfig.java b/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/DefaultKubevirtApiConfig.java
index c4e2bb8..af280fb 100644
--- a/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/DefaultKubevirtApiConfig.java
+++ b/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/DefaultKubevirtApiConfig.java
@@ -39,6 +39,7 @@
     private final String clientCertData;
     private final String clientKeyData;
     private final String serviceFqdn;
+    private final String apiServerFqdn;
 
     /**
      * Default constructor for Kubevirt API config.
@@ -52,12 +53,13 @@
      * @param clientCertData    client certificate data
      * @param clientKeyData     client key data
      * @param serviceFqdn       service FQDN
+     * @param apiServerFqdn     API server FQDN
      */
     private DefaultKubevirtApiConfig(Scheme scheme, IpAddress ipAddress,
                                     int port, State state,
                                     String token, String caCertData,
                                     String clientCertData, String clientKeyData,
-                                     String serviceFqdn) {
+                                    String serviceFqdn, String apiServerFqdn) {
         this.scheme = scheme;
         this.ipAddress = ipAddress;
         this.port = port;
@@ -67,6 +69,7 @@
         this.clientCertData = clientCertData;
         this.clientKeyData = clientKeyData;
         this.serviceFqdn = serviceFqdn;
+        this.apiServerFqdn = apiServerFqdn;
     }
 
     @Override
@@ -101,6 +104,39 @@
                 .clientCertData(clientCertData)
                 .clientKeyData(clientKeyData)
                 .serviceFqdn(serviceFqdn)
+                .apiServerFqdn(apiServerFqdn)
+                .build();
+    }
+
+    @Override
+    public KubevirtApiConfig updateIpAddress(IpAddress newIpAddress) {
+        return new Builder()
+                .scheme(scheme)
+                .ipAddress(newIpAddress)
+                .port(port)
+                .state(state)
+                .token(token)
+                .caCertData(caCertData)
+                .clientCertData(clientCertData)
+                .clientKeyData(clientKeyData)
+                .serviceFqdn(serviceFqdn)
+                .apiServerFqdn(apiServerFqdn)
+                .build();
+    }
+
+    @Override
+    public KubevirtApiConfig updatePort(int newPort) {
+        return new Builder()
+                .scheme(scheme)
+                .ipAddress(ipAddress)
+                .port(newPort)
+                .state(state)
+                .token(token)
+                .caCertData(caCertData)
+                .clientCertData(clientCertData)
+                .clientKeyData(clientKeyData)
+                .serviceFqdn(serviceFqdn)
+                .apiServerFqdn(apiServerFqdn)
                 .build();
     }
 
@@ -130,6 +166,11 @@
     }
 
     @Override
+    public String apiServerFqdn() {
+        return apiServerFqdn;
+    }
+
+    @Override
     public boolean equals(Object o) {
         if (this == o) {
             return true;
@@ -143,13 +184,14 @@
                 token.equals(that.token) && caCertData.equals(that.caCertData) &&
                 clientCertData.equals(that.clientCertData) &&
                 clientKeyData.equals(that.clientKeyData) &&
-                Objects.equals(serviceFqdn, that.serviceFqdn);
+                Objects.equals(serviceFqdn, that.serviceFqdn) &&
+                Objects.equals(apiServerFqdn, that.apiServerFqdn);
     }
 
     @Override
     public int hashCode() {
         return Objects.hash(scheme, ipAddress, port, state, token,
-                caCertData, clientCertData, clientKeyData, serviceFqdn);
+                caCertData, clientCertData, clientKeyData, serviceFqdn, apiServerFqdn);
     }
 
     @Override
@@ -164,6 +206,7 @@
                 .add("clientCertData", clientCertData)
                 .add("clientKeyData", clientKeyData)
                 .add("serviceFqdn", serviceFqdn)
+                .add("apiServerFqdn", apiServerFqdn)
                 .toString();
     }
 
@@ -187,6 +230,7 @@
         private String clientCertData;
         private String clientKeyData;
         private String serviceFqdn;
+        private String apiServerFqdn;
 
         @Override
         public KubevirtApiConfig build() {
@@ -201,7 +245,7 @@
             }
 
             return new DefaultKubevirtApiConfig(scheme, ipAddress, port, state,
-                    token, caCertData, clientCertData, clientKeyData, serviceFqdn);
+                    token, caCertData, clientCertData, clientKeyData, serviceFqdn, apiServerFqdn);
         }
 
         @Override
@@ -257,5 +301,11 @@
             this.serviceFqdn = serviceFqdn;
             return this;
         }
+
+        @Override
+        public Builder apiServerFqdn(String apiServerFqdn) {
+            this.apiServerFqdn = apiServerFqdn;
+            return this;
+        }
     }
 }
diff --git a/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/KubevirtApiConfig.java b/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/KubevirtApiConfig.java
index 4cd03af..c323625 100644
--- a/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/KubevirtApiConfig.java
+++ b/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/KubevirtApiConfig.java
@@ -89,6 +89,22 @@
     KubevirtApiConfig updateState(State newState);
 
     /**
+     * Returns the new KubeVirt API config instance with the given IP address.
+     *
+     * @param ipAddress updated IP address
+     * @return updated kubernetes API config
+     */
+    KubevirtApiConfig updateIpAddress(IpAddress ipAddress);
+
+    /**
+     * Returns the new KubeVirt API config instance with the given port.
+     *
+     * @param port updated port
+     * @return updated kubernetes API config
+     */
+    KubevirtApiConfig updatePort(int port);
+
+    /**
      * Returns the token used for authenticating to API server.
      *
      * @return token value
@@ -119,11 +135,18 @@
     /**
      * Returns the Fully Qualified Domain Name (FQDN) of the service.
      *
-     * @return service Fqdn
+     * @return service FQDN
      */
     String serviceFqdn();
 
     /**
+     * Returns the Fully Qualified Domain Name (FQDN) of the API server.
+     *
+     * @return API server FQDN
+     */
+    String apiServerFqdn();
+
+    /**
      * Builder of new API config entity.
      */
     interface Builder {
@@ -200,11 +223,19 @@
         Builder clientKeyData(String clientKeyData);
 
         /**
-         * Returns KUbevirt API server config builder with supplied service Fqdn.
+         * Returns Kubevirt API server config builder with supplied service Fqdn.
          *
          * @param serviceFqdn service FQDN
          * @return KubeVirt API config builder
          */
         Builder serviceFqdn(String serviceFqdn);
+
+        /**
+         * Returns Kubevirt API server config builder with the supplied API server Fqdn.
+         *
+         * @param apiServerFqdn API server FQDN
+         * @return Kubevirt API config builder
+         */
+        Builder apiServerFqdn(String apiServerFqdn);
     }
 }
diff --git a/apps/kubevirt-node/api/src/test/java/org/onosproject/kubevirtnode/api/DefaultKubevirtApiConfigTest.java b/apps/kubevirt-node/api/src/test/java/org/onosproject/kubevirtnode/api/DefaultKubevirtApiConfigTest.java
index 910ff09..bd40ab1 100644
--- a/apps/kubevirt-node/api/src/test/java/org/onosproject/kubevirtnode/api/DefaultKubevirtApiConfigTest.java
+++ b/apps/kubevirt-node/api/src/test/java/org/onosproject/kubevirtnode/api/DefaultKubevirtApiConfigTest.java
@@ -56,6 +56,9 @@
     private static final String SERVICE_FQDN_1 = "kubevirt.edgestack.svc.cluster.local";
     private static final String SERVICE_FQDN_2 = "sona.edgestack.svc.cluster.local";
 
+    private static final String API_SERVER_FQDN_1 = "kubernetes.default.svc.cluster.local";
+    private static final String API_SERVER_FQDN_2 = "kubernetes.default.svc.cluster.sona";
+
     private KubevirtApiConfig config1;
     private KubevirtApiConfig sameAsConfig1;
     private KubevirtApiConfig config2;
@@ -83,6 +86,7 @@
                 .clientCertData(CLIENT_CERT_DATA_1)
                 .clientKeyData(CLIENT_KEY_DATA_1)
                 .serviceFqdn(SERVICE_FQDN_1)
+                .apiServerFqdn(API_SERVER_FQDN_1)
                 .build();
 
         sameAsConfig1 = DefaultKubevirtApiConfig.builder()
@@ -95,6 +99,7 @@
                 .clientCertData(CLIENT_CERT_DATA_1)
                 .clientKeyData(CLIENT_KEY_DATA_1)
                 .serviceFqdn(SERVICE_FQDN_1)
+                .apiServerFqdn(API_SERVER_FQDN_1)
                 .build();
 
         config2 = DefaultKubevirtApiConfig.builder()
@@ -107,6 +112,7 @@
                 .clientCertData(CLIENT_CERT_DATA_2)
                 .clientKeyData(CLIENT_KEY_DATA_2)
                 .serviceFqdn(SERVICE_FQDN_2)
+                .apiServerFqdn(API_SERVER_FQDN_2)
                 .build();
     }
 
@@ -136,5 +142,6 @@
         assertEquals(CLIENT_CERT_DATA_1, config.clientCertData());
         assertEquals(CLIENT_KEY_DATA_1, config.clientKeyData());
         assertEquals(SERVICE_FQDN_1, config.serviceFqdn());
+        assertEquals(API_SERVER_FQDN_1, config.apiServerFqdn());
     }
 }
diff --git a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigCodec.java b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigCodec.java
index 84a17e5..aa2bfa1 100644
--- a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigCodec.java
+++ b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigCodec.java
@@ -42,6 +42,7 @@
     private static final String CLIENT_CERT_DATA = "clientCertData";
     private static final String CLIENT_KEY_DATA = "clientKeyData";
     private static final String SERVICE_FQDN = "serviceFqdn";
+    private static final String API_SERVER_FQDN = "apiServerFqdn";
 
     private static final String MISSING_MESSAGE = " is required in KubevirtApiConfig";
 
@@ -84,6 +85,10 @@
             node.put(SERVICE_FQDN, entity.serviceFqdn());
         }
 
+        if (entity.apiServerFqdn() != null) {
+            node.put(API_SERVER_FQDN, entity.apiServerFqdn());
+        }
+
         return node;
     }
 
@@ -110,6 +115,7 @@
         JsonNode clientCertDataJson = json.get(CLIENT_CERT_DATA);
         JsonNode clientKeyDataJson = json.get(CLIENT_KEY_DATA);
         JsonNode serviceFqdn = json.get(SERVICE_FQDN);
+        JsonNode apiServerFqdn = json.get(API_SERVER_FQDN);
 
         String token = "";
         String caCertData = "";
@@ -166,6 +172,10 @@
             builder.serviceFqdn(serviceFqdn.asText());
         }
 
+        if (apiServerFqdn != null) {
+            builder.apiServerFqdn(apiServerFqdn.asText());
+        }
+
         return builder.build();
     }
 }
diff --git a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/DefaultKubevirtApiConfigHandler.java b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/DefaultKubevirtApiConfigHandler.java
index 27866d4..01784fd 100644
--- a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/DefaultKubevirtApiConfigHandler.java
+++ b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/DefaultKubevirtApiConfigHandler.java
@@ -51,8 +51,6 @@
 
     private final Logger log = getLogger(getClass());
 
-    private static final long SLEEP_MS = 10000; // we wait 10s
-
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
     protected CoreService coreService;
 
diff --git a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/KubevirtApiConfigManager.java b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/KubevirtApiConfigManager.java
index f99b1a2..26dd3f5 100644
--- a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/KubevirtApiConfigManager.java
+++ b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/KubevirtApiConfigManager.java
@@ -16,6 +16,7 @@
 package org.onosproject.kubevirtnode.impl;
 
 import com.google.common.base.Strings;
+import org.onlab.packet.IpAddress;
 import org.onosproject.cluster.ClusterService;
 import org.onosproject.cluster.LeadershipService;
 import org.onosproject.core.ApplicationId;
@@ -43,6 +44,7 @@
 import static java.util.concurrent.Executors.newSingleThreadExecutor;
 import static org.onlab.util.Tools.groupedThreads;
 import static org.onosproject.kubevirtnode.util.KubevirtNodeUtil.endpoint;
+import static org.onosproject.kubevirtnode.util.KubevirtNodeUtil.resolveHostname;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -58,6 +60,8 @@
 
     private final Logger log = getLogger(getClass());
 
+    private static final int API_SERVER_PORT = 443;
+
     private static final String MSG_CONFIG = "KubeVirt API config %s %s";
     private static final String MSG_CREATED = "created";
     private static final String MSG_UPDATED = "updated";
@@ -114,8 +118,19 @@
         checkNotNull(config, ERR_NULL_CONFIG);
         checkArgument(configStore.apiConfigs().size() == 0, ERR_UNIQUE_CONFIG);
 
-        configStore.createApiConfig(config);
-        log.info(String.format(MSG_CONFIG, endpoint(config), MSG_CREATED));
+        KubevirtApiConfig newConfig = config;
+        if (config.apiServerFqdn() != null) {
+            IpAddress apiServerIp = resolveHostname(config.apiServerFqdn());
+            if (apiServerIp != null) {
+                newConfig = config.updateIpAddress(apiServerIp);
+                newConfig = newConfig.updatePort(API_SERVER_PORT);
+            } else {
+                log.warn("API server IP is not resolved for host {}", config.apiServerFqdn());
+            }
+        }
+
+        configStore.createApiConfig(newConfig);
+        log.info(String.format(MSG_CONFIG, endpoint(newConfig), MSG_CREATED));
     }
 
     @Override
diff --git a/apps/kubevirt-node/app/src/test/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigCodecTest.java b/apps/kubevirt-node/app/src/test/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigCodecTest.java
index bd1c62b..32a4505 100644
--- a/apps/kubevirt-node/app/src/test/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigCodecTest.java
+++ b/apps/kubevirt-node/app/src/test/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigCodecTest.java
@@ -87,6 +87,7 @@
                 .clientCertData("clientCertData")
                 .clientKeyData("clientKeyData")
                 .serviceFqdn("kubevirt.edgestack.svc.cluster.local")
+                .apiServerFqdn("kubernetes.default.svc.cluster.local")
                 .build();
         ObjectNode configJson = kubevirtApiConfigCodec.encode(config, context);
         assertThat(configJson, matchesKubevirtApiConfig(config));
@@ -109,6 +110,7 @@
         assertEquals("clientCertData", config.clientCertData());
         assertEquals("clientKeyData", config.clientKeyData());
         assertEquals("kubevirt.edgestack.svc.cluster.local", config.serviceFqdn());
+        assertEquals("kubernetes.default.svc.cluster.local", config.apiServerFqdn());
     }
 
     private KubevirtApiConfig getKubevirtApiConfig(String resourceName) throws IOException {
diff --git a/apps/kubevirt-node/app/src/test/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigJsonMatcher.java b/apps/kubevirt-node/app/src/test/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigJsonMatcher.java
index 1372d7d..52c488c 100644
--- a/apps/kubevirt-node/app/src/test/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigJsonMatcher.java
+++ b/apps/kubevirt-node/app/src/test/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigJsonMatcher.java
@@ -36,6 +36,7 @@
     private static final String CLIENT_CERT_DATA = "clientCertData";
     private static final String CLIENT_KEY_DATA = "clientKeyData";
     private static final String SERVICE_FQDN = "serviceFqdn";
+    private static final String API_SERVER_FQDN = "apiServerFqdn";
 
     private KubevirtApiConfigJsonMatcher(KubevirtApiConfig kubevirtApiConfig) {
         this.kubevirtApiConfig = kubevirtApiConfig;
@@ -130,6 +131,17 @@
             }
         }
 
+        // API server FQDN
+        JsonNode jsonApiServerFqdn = jsonNode.get(API_SERVER_FQDN);
+        String apiServerFqdn = kubevirtApiConfig.apiServerFqdn();
+
+        if (jsonApiServerFqdn != null) {
+            if (!jsonApiServerFqdn.asText().equals(apiServerFqdn)) {
+                description.appendText("apiServerFqdn was " + jsonApiServerFqdn);
+                return false;
+            }
+        }
+
         return true;
     }
 
diff --git a/apps/kubevirt-node/app/src/test/resources/org/onosproject/kubevirtnode/codec/KubevirtApiConfig.json b/apps/kubevirt-node/app/src/test/resources/org/onosproject/kubevirtnode/codec/KubevirtApiConfig.json
index b42e618..b19c9e4 100644
--- a/apps/kubevirt-node/app/src/test/resources/org/onosproject/kubevirtnode/codec/KubevirtApiConfig.json
+++ b/apps/kubevirt-node/app/src/test/resources/org/onosproject/kubevirtnode/codec/KubevirtApiConfig.json
@@ -6,5 +6,6 @@
   "caCertData": "caCertData",
   "clientCertData": "clientCertData",
   "clientKeyData": "clientKeyData",
-  "serviceFqdn": "kubevirt.edgestack.svc.cluster.local"
+  "serviceFqdn": "kubevirt.edgestack.svc.cluster.local",
+  "apiServerFqdn": "kubernetes.default.svc.cluster.local"
 }
\ No newline at end of file