Initial implementation of security group for kubevirt tenant network

Change-Id: If49d03021408a134be01267cc4eee9e0091e3c3d
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtVmWatcher.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtVmWatcher.java
index 61b9be0..308707e 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtVmWatcher.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtVmWatcher.java
@@ -87,6 +87,8 @@
     private static final String DOMAIN = "domain";
     private static final String DEVICES = "devices";
     private static final String INTERFACES = "interfaces";
+    private static final String NETWORK_POLICIES = "networkPolicies";
+    private static final String SECURITY_GROUPS = "securityGroups";
     private static final String NAME = "name";
     private static final String NETWORK = "network";
     private static final String MAC = "macAddress";
@@ -211,6 +213,9 @@
                 case DELETED:
                     eventExecutor.execute(() -> processDeletion(resource));
                     break;
+                case MODIFIED:
+                    eventExecutor.execute(() -> processModification(resource));
+                    break;
                 case ERROR:
                     log.warn("Failures processing VM manipulation.");
                     break;
@@ -238,6 +243,9 @@
 
                 String name = parseResourceName(resource);
 
+                Set<String> sgs = parseSecurityGroups(resource);
+                port = port.updateSecurityGroups(sgs);
+
                 Map<String, IpAddress> ips = parseIpAddresses(resource);
                 IpAddress ip;
                 IpAddress existingIp = ips.get(port.networkId());
@@ -303,6 +311,28 @@
             });
         }
 
+        private void processModification(String resource) {
+            if (!isMaster()) {
+                return;
+            }
+
+            parseMacAddresses(resource).forEach((mac, net) -> {
+                KubevirtPort port = DefaultKubevirtPort.builder()
+                        .macAddress(mac)
+                        .networkId(net)
+                        .build();
+
+                KubevirtPort existing = portAdminService.port(port.macAddress());
+
+                if (existing == null) {
+                    return;
+                }
+
+                Set<String> sgs = parseSecurityGroups(resource);
+                portAdminService.updatePort(existing.updateSecurityGroups(sgs));
+            });
+        }
+
         private void processDeletion(String resource) {
             if (!isMaster()) {
                 return;
@@ -410,6 +440,37 @@
             return null;
         }
 
+        private Set<String> parseSecurityGroups(String resource) {
+            try {
+                ObjectMapper mapper = new ObjectMapper();
+                JsonNode json = mapper.readTree(resource);
+                JsonNode metadata = json.get(SPEC).get(TEMPLATE).get(METADATA);
+
+                JsonNode annots = metadata.get(ANNOTATIONS);
+                if (annots == null) {
+                    return new HashSet<>();
+                }
+
+                JsonNode sgsJson = annots.get(SECURITY_GROUPS);
+                if (sgsJson == null) {
+                    return new HashSet<>();
+                }
+
+                Set<String> result = new HashSet<>();
+                ArrayNode sgs = (ArrayNode) mapper.readTree(sgsJson.asText());
+                for (JsonNode sg : sgs) {
+                    result.add(sg.asText());
+                }
+
+                return result;
+
+            } catch (IOException e) {
+                log.error("Failed to parse kubevirt security group IDs.");
+            }
+
+            return new HashSet<>();
+        }
+
         private Map<MacAddress, String> parseMacAddresses(String resource) {
             try {
                 ObjectMapper mapper = new ObjectMapper();