Add VM name field to floating IP CRD of kubevirt

Change-Id: I493199f0e2a5c0b7b5fffc65c513bb4feeb2eb10
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/Constants.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/Constants.java
index c6a9179..e3e9bce 100644
--- a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/Constants.java
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/Constants.java
@@ -85,6 +85,7 @@
     // CLI item length
     public static final int CLI_ID_LENGTH = 30;
     public static final int CLI_NAME_LENGTH = 30;
+    public static final int CLI_LONG_NAME_LENGTH = 50;
     public static final int CLI_IP_ADDRESSES_LENGTH = 50;
     public static final int CLI_IP_ADDRESS_LENGTH = 25;
     public static final int CLI_IP_ADDRESS_AVAILABILITY = 15;
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtFloatingIp.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtFloatingIp.java
index 213fa4e..488ef8d 100644
--- a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtFloatingIp.java
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtFloatingIp.java
@@ -32,6 +32,7 @@
     private final String id;
     private final String routerName;
     private final String podName;
+    private final String vmName;
     private final String networkName;
     private final IpAddress floatingIp;
     private final IpAddress fixedIp;
@@ -42,15 +43,17 @@
      * @param id            floating IP identifier
      * @param routerName    router name
      * @param podName       POD name
+     * @param vmName        VM name
      * @param networkName   network name
      * @param floatingIp    floating IP address
      * @param fixedIp       fixed IP address
      */
-    public DefaultKubevirtFloatingIp(String id, String routerName, String podName,
+    public DefaultKubevirtFloatingIp(String id, String routerName, String podName, String vmName,
                                      String networkName, IpAddress floatingIp, IpAddress fixedIp) {
         this.id = id;
         this.routerName = routerName;
         this.podName = podName;
+        this.vmName = vmName;
         this.networkName = networkName;
         this.floatingIp = floatingIp;
         this.fixedIp = fixedIp;
@@ -82,6 +85,11 @@
     }
 
     @Override
+    public String vmName() {
+        return vmName;
+    }
+
+    @Override
     public String podName() {
         return podName;
     }
@@ -94,6 +102,7 @@
                 .routerName(routerName)
                 .floatingIp(floatingIp)
                 .fixedIp(ip)
+                .vmName(vmName)
                 .podName(podName)
                 .build();
     }
@@ -106,11 +115,25 @@
                 .routerName(routerName)
                 .floatingIp(floatingIp)
                 .fixedIp(fixedIp)
+                .vmName(vmName)
                 .podName(name)
                 .build();
     }
 
     @Override
+    public KubevirtFloatingIp updateVmName(String name) {
+        return DefaultKubevirtFloatingIp.builder()
+                .id(id)
+                .networkName(networkName)
+                .routerName(routerName)
+                .floatingIp(floatingIp)
+                .fixedIp(fixedIp)
+                .vmName(name)
+                .podName(podName)
+                .build();
+    }
+
+    @Override
     public boolean equals(Object o) {
         if (this == o) {
             return true;
@@ -157,6 +180,7 @@
         private String id;
         private String routerName;
         private String podName;
+        private String vmName;
         private String networkName;
         private IpAddress floatingIp;
         private IpAddress fixedIp;
@@ -168,7 +192,8 @@
             checkArgument(routerName != null, NOT_NULL_MSG, "routerName");
             checkArgument(floatingIp != null, NOT_NULL_MSG, "floatingIp");
 
-            return new DefaultKubevirtFloatingIp(id, routerName, podName, networkName, floatingIp, fixedIp);
+            return new DefaultKubevirtFloatingIp(id, routerName, podName, vmName,
+                    networkName, floatingIp, fixedIp);
         }
 
         @Override
@@ -202,6 +227,12 @@
         }
 
         @Override
+        public Builder vmName(String name) {
+            this.vmName = name;
+            return this;
+        }
+
+        @Override
         public Builder podName(String name) {
             this.podName = name;
             return this;
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtFloatingIp.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtFloatingIp.java
index 27019b8..2fe85f1 100644
--- a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtFloatingIp.java
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtFloatingIp.java
@@ -58,6 +58,13 @@
     IpAddress fixedIp();
 
     /**
+     * Returns the name of VM where this floating IP is associated with.
+     *
+     * @return VM name
+     */
+    String vmName();
+
+    /**
      * Returns the name of POD where this floating IP is associated with.
      *
      * @return POD name
@@ -80,6 +87,14 @@
      */
     KubevirtFloatingIp updatePodName(String name);
 
+    /**
+     * Updates the kubevirt floating IP with the supplied VM name.
+     *
+     * @param name VM name
+     * @return kubevirt floating IP
+     */
+    KubevirtFloatingIp updateVmName(String name);
+
     interface Builder {
         /**
          * Builds an immutable floaing IP instance.
@@ -129,6 +144,14 @@
         Builder fixedIp(IpAddress ip);
 
         /**
+         * Returns kubevirt floating IP builder with supplied VM name.
+         *
+         * @param name VM name
+         * @return floating IP builder
+         */
+        Builder vmName(String name);
+
+        /**
          * Returns kubevirt floating IP builder with supplied POD name.
          *
          * @param name POD name
diff --git a/apps/kubevirt-networking/api/src/test/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtFloatingIpTest.java b/apps/kubevirt-networking/api/src/test/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtFloatingIpTest.java
index b63cf00..e995532 100644
--- a/apps/kubevirt-networking/api/src/test/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtFloatingIpTest.java
+++ b/apps/kubevirt-networking/api/src/test/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtFloatingIpTest.java
@@ -38,6 +38,8 @@
     private static final IpAddress FLOATING_IP_2 = IpAddress.valueOf("20.20.20.20");
     private static final String POD_NAME_1 = "pod-1";
     private static final String POD_NAME_2 = "pod-2";
+    private static final String VM_NAME_1 = "vm-1";
+    private static final String VM_NAME_2 = "vm-2";
     private static final IpAddress FIXED_IP_1 = IpAddress.valueOf("30.30.30.30");
     private static final IpAddress FIXED_IP_2 = IpAddress.valueOf("40.40.40.40");
 
@@ -64,6 +66,7 @@
                 .networkName(NETWORK_NAME_1)
                 .floatingIp(FLOATING_IP_1)
                 .podName(POD_NAME_1)
+                .vmName(VM_NAME_1)
                 .fixedIp(FIXED_IP_1)
                 .build();
 
@@ -73,6 +76,7 @@
                 .networkName(NETWORK_NAME_1)
                 .floatingIp(FLOATING_IP_1)
                 .podName(POD_NAME_1)
+                .vmName(VM_NAME_1)
                 .fixedIp(FIXED_IP_1)
                 .build();
 
@@ -82,6 +86,7 @@
                 .networkName(NETWORK_NAME_2)
                 .floatingIp(FLOATING_IP_2)
                 .podName(POD_NAME_2)
+                .vmName(VM_NAME_2)
                 .fixedIp(FIXED_IP_2)
                 .build();
     }
@@ -108,6 +113,7 @@
         assertEquals(NETWORK_NAME_1, fip.networkName());
         assertEquals(FLOATING_IP_1, fip.floatingIp());
         assertEquals(POD_NAME_1, fip.podName());
+        assertEquals(VM_NAME_1, fip.vmName());
         assertEquals(FIXED_IP_1, fip.fixedIp());
     }
 }
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/cli/KubevirtListFloatingIpCommand.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/cli/KubevirtListFloatingIpCommand.java
index 20ab17e..3f5ca15 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/cli/KubevirtListFloatingIpCommand.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/cli/KubevirtListFloatingIpCommand.java
@@ -50,16 +50,17 @@
         fips.sort(Comparator.comparing(KubevirtFloatingIp::networkName));
 
         String format = genFormatString(ImmutableList.of(CLI_NAME_LENGTH,
-                CLI_IP_ADDRESS_LENGTH, CLI_NAME_LENGTH, CLI_IP_ADDRESS_LENGTH));
+                CLI_IP_ADDRESS_LENGTH, CLI_NAME_LENGTH, CLI_NAME_LENGTH, CLI_IP_ADDRESS_LENGTH));
 
         if (outputJson()) {
             print("%s", json(fips));
         } else {
-            print(format, "Network Name", "Floating IP", "POD Name", "Fixed IP");
+            print(format, "Network Name", "Floating IP", "POD Name", "VM Name", "Fixed IP");
             for (KubevirtFloatingIp fip : fips) {
 
                 String fixedIp = fip.fixedIp() == null ? "N/A" : fip.fixedIp().toString();
                 String podName = fip.podName() == null ? "N/A" : fip.podName();
+                String vmName = fip.vmName() == null ? "N/A" : fip.vmName();
 
                 print(format, StringUtils.substring(fip.networkName(), 0,
                         CLI_NAME_LENGTH - CLI_MARGIN_LENGTH),
@@ -67,6 +68,8 @@
                                 CLI_IP_ADDRESS_LENGTH - CLI_MARGIN_LENGTH),
                         StringUtils.substring(podName, 0,
                                 CLI_NAME_LENGTH - CLI_MARGIN_LENGTH),
+                        StringUtils.substring(vmName, 0,
+                                CLI_NAME_LENGTH - CLI_MARGIN_LENGTH),
                         StringUtils.substring(fixedIp, 0,
                                 CLI_IP_ADDRESS_LENGTH - CLI_MARGIN_LENGTH)
                 );
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/cli/KubevirtListPodCommand.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/cli/KubevirtListPodCommand.java
index 2ad937a..5d3dbb3 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/cli/KubevirtListPodCommand.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/cli/KubevirtListPodCommand.java
@@ -33,9 +33,9 @@
 import java.util.List;
 
 import static org.onosproject.kubevirtnetworking.api.Constants.CLI_IP_ADDRESS_LENGTH;
+import static org.onosproject.kubevirtnetworking.api.Constants.CLI_LONG_NAME_LENGTH;
 import static org.onosproject.kubevirtnetworking.api.Constants.CLI_MARGIN_LENGTH;
 import static org.onosproject.kubevirtnetworking.api.Constants.CLI_NAMESPACE_LENGTH;
-import static org.onosproject.kubevirtnetworking.api.Constants.CLI_NAME_LENGTH;
 import static org.onosproject.kubevirtnetworking.api.Constants.CLI_STATUS_LENGTH;
 import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.genFormatString;
 import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.prettyJson;
@@ -53,7 +53,7 @@
         List<Pod> pods = Lists.newArrayList(service.pods());
         pods.sort(Comparator.comparing(p -> p.getMetadata().getName()));
 
-        String format = genFormatString(ImmutableList.of(CLI_NAME_LENGTH,
+        String format = genFormatString(ImmutableList.of(CLI_LONG_NAME_LENGTH,
                 CLI_NAMESPACE_LENGTH, CLI_STATUS_LENGTH, CLI_IP_ADDRESS_LENGTH));
 
         if (outputJson()) {
@@ -69,7 +69,7 @@
 
                 print(format,
                         StringUtils.substring(pod.getMetadata().getName(),
-                                0, CLI_NAME_LENGTH - CLI_MARGIN_LENGTH),
+                                0, CLI_LONG_NAME_LENGTH - CLI_MARGIN_LENGTH),
                         StringUtils.substring(pod.getMetadata().getNamespace(),
                                 0, CLI_NAMESPACE_LENGTH - CLI_MARGIN_LENGTH),
                         pod.getStatus().getPhase(),
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/codec/KubevirtFloatingIpCodec.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/codec/KubevirtFloatingIpCodec.java
index f2a3505..fd530a1 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/codec/KubevirtFloatingIpCodec.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/codec/KubevirtFloatingIpCodec.java
@@ -38,6 +38,7 @@
     private static final String ID = "id";
     private static final String ROUTER_NAME = "routerName";
     private static final String POD_NAME = "podName";
+    private static final String VM_NAME = "vmName";
     private static final String NETWORK_NAME = "networkName";
     private static final String FLOATING_IP = "floatingIp";
     private static final String FIXED_IP = "fixedIp";
@@ -58,6 +59,10 @@
             result.put(POD_NAME, fip.podName());
         }
 
+        if (fip.vmName() != null) {
+            result.put(VM_NAME, fip.vmName());
+        }
+
         if (fip.fixedIp() != null) {
             result.put(FIXED_IP, fip.fixedIp().toString());
         }
@@ -90,6 +95,11 @@
             builder.podName(podName.asText());
         }
 
+        JsonNode vmName = json.get(VM_NAME);
+        if (vmName != null) {
+            builder.vmName(vmName.asText());
+        }
+
         JsonNode fixedIp = json.get(FIXED_IP);
         if (fixedIp != null) {
             builder.fixedIp(IpAddress.valueOf(fixedIp.asText()));
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/DistributedKubevirtRouterStore.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/DistributedKubevirtRouterStore.java
index 9248f06..4b982aa 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/DistributedKubevirtRouterStore.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/DistributedKubevirtRouterStore.java
@@ -415,6 +415,9 @@
             String oldPodName = event.oldValue().value().podName();
             String newPodName = event.newValue().value().podName();
 
+            String oldVmName = event.oldValue().value().vmName();
+            String newVmName = event.newValue().value().vmName();
+
             if (Strings.isNullOrEmpty(oldPodName) && !Strings.isNullOrEmpty(newPodName)) {
                 notifyDelegate(new KubevirtRouterEvent(
                         KUBEVIRT_FLOATING_IP_ASSOCIATED,
@@ -433,6 +436,24 @@
                         event.newValue().value().floatingIp(), MSG_DISASSOCIATED, oldPodName));
             }
 
+            if (Strings.isNullOrEmpty(oldVmName) && !Strings.isNullOrEmpty(newVmName)) {
+                notifyDelegate(new KubevirtRouterEvent(
+                        KUBEVIRT_FLOATING_IP_ASSOCIATED,
+                        router,
+                        event.newValue().value(), newVmName));
+                log.info(String.format(MSG_FLOATING_IP,
+                        event.newValue().value().floatingIp(), MSG_ASSOCIATED, newVmName));
+            }
+
+            if (!Strings.isNullOrEmpty(oldVmName) && Strings.isNullOrEmpty(newVmName)) {
+                notifyDelegate(new KubevirtRouterEvent(
+                        KUBEVIRT_FLOATING_IP_DISASSOCIATED,
+                        router,
+                        event.oldValue().value(), oldVmName));
+                log.info(String.format(MSG_FLOATING_IP,
+                        event.newValue().value().floatingIp(), MSG_DISASSOCIATED, oldVmName));
+            }
+
             IpAddress oldFixedIp = event.oldValue().value().fixedIp();
             IpAddress newFixedIp = event.newValue().value().fixedIp();
 
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtFloatingIpHandler.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtFloatingIpHandler.java
index ed086ae..e9ab1fe 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtFloatingIpHandler.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtFloatingIpHandler.java
@@ -158,7 +158,7 @@
                                           KubevirtNode electedGw,
                                           boolean install) {
 
-        KubevirtPort kubevirtPort = getKubevirtPort(floatingIp);
+        KubevirtPort kubevirtPort = getKubevirtPortByFloatingIp(floatingIp);
         if (kubevirtPort == null) {
             return;
         }
@@ -209,10 +209,11 @@
                 install);
     }
 
-    private KubevirtPort getKubevirtPort(KubevirtFloatingIp floatingIp) {
+    private KubevirtPort getKubevirtPortByFloatingIp(KubevirtFloatingIp floatingIp) {
 
         return kubevirtPortService.ports().stream()
                 .filter(port -> port.ipAddress().equals(floatingIp.fixedIp()))
+                .filter(port -> port.vmName().equals(floatingIp.vmName()))
                 .findAny().orElse(null);
     }
 
@@ -240,7 +241,6 @@
                 .matchIPSrc(IpPrefix.valueOf(floatingIp.fixedIp(), 32))
                 .build();
 
-
         TrafficTreatment treatment = DefaultTrafficTreatment.builder()
                 .setEthDst(peerMacAddress)
                 .setEthSrc(port.macAddress())
@@ -336,7 +336,7 @@
             return;
         }
 
-        KubevirtPort kubevirtPort = getKubevirtPort(floatingIp);
+        KubevirtPort kubevirtPort = getKubevirtPortByFloatingIp(floatingIp);
         if (kubevirtPort == null) {
             return;
         }
diff --git a/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtFloatingIpCodecTest.java b/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtFloatingIpCodecTest.java
index f8b5d14..216f3e0 100644
--- a/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtFloatingIpCodecTest.java
+++ b/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtFloatingIpCodecTest.java
@@ -74,6 +74,7 @@
                 .networkName("flat-1")
                 .floatingIp(IpAddress.valueOf("10.10.10.10"))
                 .podName("pod-1")
+                .vmName("vm-1")
                 .fixedIp(IpAddress.valueOf("20.20.20.20"))
                 .build();
 
@@ -90,6 +91,7 @@
         assertEquals("flat-1", floatingIp.networkName());
         assertEquals("10.10.10.10", floatingIp.floatingIp().toString());
         assertEquals("pod-1", floatingIp.podName());
+        assertEquals("vm-1", floatingIp.vmName());
         assertEquals("20.20.20.20", floatingIp.fixedIp().toString());
     }
 
diff --git a/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtFloatingIpJsonMatcher.java b/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtFloatingIpJsonMatcher.java
index ccfb76c..41d8cfe 100644
--- a/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtFloatingIpJsonMatcher.java
+++ b/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtFloatingIpJsonMatcher.java
@@ -30,6 +30,7 @@
     private static final String ROUTER_NAME = "routerName";
     private static final String NETWORK_NAME = "networkName";
     private static final String POD_NAME = "podName";
+    private static final String VM_NAME = "vmName";
     private static final String FLOATING_IP = "floatingIp";
     private static final String FIXED_IP = "fixedIp";
 
@@ -81,6 +82,15 @@
             }
         }
 
+        JsonNode jsonVmName = jsonNode.get(VM_NAME);
+        if (jsonVmName != null) {
+            if (!floatingIp.vmName().equals(jsonVmName.asText())) {
+                description.appendText("VM name was " + jsonVmName);
+                return false;
+            }
+        }
+
+
         // check fixed IP
         JsonNode jsonFixedIp = jsonNode.get(FIXED_IP);
         if (jsonFixedIp != null) {
diff --git a/apps/kubevirt-networking/app/src/test/resources/org/onosproject/kubevirtnetworking/codec/KubevirtFloatingIp.json b/apps/kubevirt-networking/app/src/test/resources/org/onosproject/kubevirtnetworking/codec/KubevirtFloatingIp.json
index 1424d48..93819ce 100644
--- a/apps/kubevirt-networking/app/src/test/resources/org/onosproject/kubevirtnetworking/codec/KubevirtFloatingIp.json
+++ b/apps/kubevirt-networking/app/src/test/resources/org/onosproject/kubevirtnetworking/codec/KubevirtFloatingIp.json
@@ -4,5 +4,6 @@
   "networkName": "flat-1",
   "floatingIp": "10.10.10.10",
   "podName": "pod-1",
+  "vmName": "vm-1",
   "fixedIp": "20.20.20.20"
 }
\ No newline at end of file