Support string formated target port of k8s service resource

Change-Id: I429702548281bf28624e2c4debe20133dee2ee03
diff --git a/apps/k8s-networking/api/src/main/java/org/onosproject/k8snetworking/api/Constants.java b/apps/k8s-networking/api/src/main/java/org/onosproject/k8snetworking/api/Constants.java
index 8444122..9854ce2 100644
--- a/apps/k8s-networking/api/src/main/java/org/onosproject/k8snetworking/api/Constants.java
+++ b/apps/k8s-networking/api/src/main/java/org/onosproject/k8snetworking/api/Constants.java
@@ -15,6 +15,8 @@
  */
 package org.onosproject.k8snetworking.api;
 
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
 import org.onlab.packet.MacAddress;
 
 /**
@@ -111,4 +113,34 @@
 
     public static final int EXT_ENTRY_TABLE = 0;
     public static final int POD_RESOLUTION_TABLE = 11;
+
+    public static final BiMap<String, Integer> SERVICE_PORT_MAP = HashBiMap.create();
+
+    static {
+        SERVICE_PORT_MAP.put("ftp", 21);
+        SERVICE_PORT_MAP.put("ssh", 22);
+        SERVICE_PORT_MAP.put("telnet", 23);
+        SERVICE_PORT_MAP.put("smtp", 25);
+        SERVICE_PORT_MAP.put("time", 37);
+        SERVICE_PORT_MAP.put("login", 49);
+        SERVICE_PORT_MAP.put("dns", 53);
+        SERVICE_PORT_MAP.put("tftp", 69);
+        SERVICE_PORT_MAP.put("finger", 79);
+        SERVICE_PORT_MAP.put("http", 8080);
+        SERVICE_PORT_MAP.put("x400", 103);
+        SERVICE_PORT_MAP.put("pop2", 109);
+        SERVICE_PORT_MAP.put("pop3", 110);
+        SERVICE_PORT_MAP.put("sftp", 115);
+        SERVICE_PORT_MAP.put("nntp", 119);
+        SERVICE_PORT_MAP.put("imap", 143);
+        SERVICE_PORT_MAP.put("bgp", 179);
+        SERVICE_PORT_MAP.put("gacp", 190);
+        SERVICE_PORT_MAP.put("dls", 197);
+        SERVICE_PORT_MAP.put("ldap", 389);
+        SERVICE_PORT_MAP.put("https", 443);
+        SERVICE_PORT_MAP.put("snpp", 444);
+        SERVICE_PORT_MAP.put("dhcp-client", 546);
+        SERVICE_PORT_MAP.put("dhcp-server", 547);
+        SERVICE_PORT_MAP.put("socks", 1080);
+    }
 }
diff --git a/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sNetworkPolicyHandler.java b/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sNetworkPolicyHandler.java
index 8136db9..dda9b58 100644
--- a/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sNetworkPolicyHandler.java
+++ b/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sNetworkPolicyHandler.java
@@ -20,6 +20,8 @@
 import com.google.common.collect.Sets;
 import io.fabric8.kubernetes.api.model.Pod;
 import io.fabric8.kubernetes.api.model.networking.NetworkPolicy;
+import io.fabric8.kubernetes.api.model.networking.NetworkPolicyEgressRule;
+import io.fabric8.kubernetes.api.model.networking.NetworkPolicyIngressRule;
 import io.fabric8.kubernetes.api.model.networking.NetworkPolicyPort;
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.IPv4;
@@ -166,39 +168,44 @@
     }
 
     private void setBlockRulesByPolicy(NetworkPolicy policy, boolean install) {
-        Map<String, String> labels =
-                policy.getSpec().getPodSelector().getMatchLabels();
-        Map<String, List<String>> filter = Maps.newConcurrentMap();
+        final Map<String, List<String>> filter = Maps.newConcurrentMap();
 
-        k8sPodService.pods().forEach(pod -> {
-            pod.getMetadata().getLabels().forEach((k, v) -> {
-                if (labels.get(k) != null && labels.get(k).equals(v) &&
-                        policy.getSpec().getPolicyTypes() != null) {
-                    filter.put(pod.getStatus().getPodIP(),
-                            policy.getSpec().getPolicyTypes());
-                }
-            });
-        });
+        k8sPodService.pods().forEach(pod ->
+            filter.putAll(getBlockRuleFilter(pod, policy)));
 
         setBlockRules(filter, install);
     }
 
     private void setBlockRulesByPod(Pod pod, boolean install) {
-        Map<String, List<String>> filter = Maps.newConcurrentMap();
+        final Map<String, List<String>> filter = Maps.newConcurrentMap();
 
-        k8sNetworkPolicyService.networkPolicies().forEach(policy -> {
-            Map<String, String> labels = policy.getSpec().getPodSelector().getMatchLabels();
-            pod.getMetadata().getLabels().forEach((k, v) -> {
-                if (labels.get(k) != null && labels.get(k).equals(v) &&
-                        policy.getSpec().getPolicyTypes() != null) {
-                    filter.put(pod.getStatus().getPodIP(), policy.getSpec().getPolicyTypes());
-                }
-            });
-        });
+        k8sNetworkPolicyService.networkPolicies().forEach(policy ->
+            filter.putAll(getBlockRuleFilter(pod, policy)));
 
         setBlockRules(filter, install);
     }
 
+    private Map<String, List<String>> getBlockRuleFilter(Pod pod, NetworkPolicy policy) {
+        Map<String, String> labels = policy.getSpec().getPodSelector().getMatchLabels();
+        Map<String, List<String>> filter = Maps.newConcurrentMap();
+        String podIp = pod.getStatus().getPodIP();
+        List<String> policyTypes = policy.getSpec().getPolicyTypes();
+
+        if (podIp != null && policyTypes != null) {
+            if (labels == null) {
+                filter.put(podIp, policyTypes);
+            } else {
+                pod.getMetadata().getLabels().forEach((k, v) -> {
+                    if (labels.get(k) != null && labels.get(k).equals(v)) {
+                        filter.put(podIp, policyTypes);
+                    }
+                });
+            }
+        }
+
+        return filter;
+    }
+
     private void setBlockRules(Map<String, List<String>> filter, boolean install) {
         filter.forEach((k, v) -> {
             v.forEach(d -> {
@@ -232,6 +239,14 @@
         Map<String, Map<String, List<NetworkPolicyPort>>>
                 white = Maps.newConcurrentMap();
 
+        List<NetworkPolicyIngressRule> ingress = policy.getSpec().getIngress();
+        if (ingress != null && ingress.size() == 1) {
+            NetworkPolicyIngressRule rule = ingress.get(0);
+            if (rule.getFrom().size() == 0 && rule.getPorts().size() == 0) {
+                setAllowAllRule(DIRECTION_INGRESS, install);
+            }
+        }
+
         policy.getSpec().getIngress().forEach(i -> {
             Map<String, List<NetworkPolicyPort>> direction = Maps.newConcurrentMap();
             direction.put(DIRECTION_INGRESS, i.getPorts());
@@ -258,7 +273,8 @@
 
                     k8sPodService.pods().forEach(pod -> {
                         pod.getMetadata().getLabels().forEach((k, v) -> {
-                            if (podLabels.get(k) != null && podLabels.get(k).equals(v)) {
+                            if (podLabels != null && podLabels.get(k) != null &&
+                                    podLabels.get(k).equals(v)) {
                                 pods.add(pod);
                             }
                         });
@@ -284,6 +300,14 @@
             });
         });
 
+        List<NetworkPolicyEgressRule> egress = policy.getSpec().getEgress();
+        if (egress != null && egress.size() == 1) {
+            NetworkPolicyEgressRule rule = egress.get(0);
+            if (rule.getTo().size() == 0 && rule.getPorts().size() == 0) {
+                setAllowAllRule(DIRECTION_EGRESS, install);
+            }
+        }
+
         policy.getSpec().getEgress().forEach(e -> {
             Map<String, List<NetworkPolicyPort>> direction = Maps.newConcurrentMap();
             direction.put(DIRECTION_EGRESS, e.getPorts());
@@ -324,7 +348,8 @@
                     Map<String, String> podLabels = p.getPodSelector().getMatchLabels();
                     k8sPodService.pods().forEach(pod -> {
                         pod.getMetadata().getLabels().forEach((k, v) -> {
-                            if (podLabels.get(k) != null && podLabels.get(k).equals(v)) {
+                            if (podLabels != null && podLabels.get(k) != null &&
+                                    podLabels.get(k).equals(v)) {
                                 pods.add(pod);
                             }
                         });
@@ -374,6 +399,8 @@
         Map<String, Map<String, List<NetworkPolicyPort>>>
                 white = Maps.newConcurrentMap();
         k8sNetworkPolicyService.networkPolicies().forEach(policy -> {
+            String podIp = pod.getStatus().getPodIP();
+
             policy.getSpec().getIngress().forEach(i -> {
                 Map<String, List<NetworkPolicyPort>>
                         direction = Maps.newConcurrentMap();
@@ -381,11 +408,9 @@
                 i.getFrom().forEach(peer -> {
                     if (peer.getPodSelector() != null) {
                         Map<String, String> podLabels = peer.getPodSelector().getMatchLabels();
-                        String podIp = pod.getStatus().getPodIP();
                         pod.getMetadata().getLabels().forEach((k, v) -> {
-                            if ((podLabels.get(k) != null &&
-                                    podLabels.get(k).equals(v)) &&
-                                    podIp != null) {
+                            if (podLabels != null && podLabels.get(k) != null &&
+                                    podLabels.get(k).equals(v) && podIp != null) {
                                 white.compute(shiftIpDomain(podIp, SHIFTED_IP_PREFIX) +
                                         "/" + HOST_PREFIX, (m, n) -> direction);
                                 white.compute(podIp + "/" +
@@ -394,10 +419,14 @@
                         });
 
                         if (peer.getNamespaceSelector() != null &&
-                                (podsFromNamespace(peer.getNamespaceSelector().getMatchLabels()).contains(pod) ||
-                                        (peer.getNamespaceSelector().getMatchLabels().size() == 0))) {
-                            white.compute(pod.getStatus().getPodIP() + "/" +
-                                    HOST_PREFIX, (m, n) -> direction);
+                                peer.getNamespaceSelector().getMatchLabels() != null) {
+                            Set<Pod> pods = podsFromNamespace(
+                                    peer.getNamespaceSelector().getMatchLabels());
+                            if ((pods != null && pods.contains(pod)) ||
+                                    (peer.getNamespaceSelector().getMatchLabels().size() == 0)) {
+                                white.compute(pod.getStatus().getPodIP() + "/" +
+                                        HOST_PREFIX, (m, n) -> direction);
+                            }
                         }
                     }
                 });
@@ -405,15 +434,17 @@
         });
 
         k8sNetworkPolicyService.networkPolicies().forEach(policy -> {
+            String podIp = pod.getStatus().getPodIP();
+
             policy.getSpec().getEgress().forEach(e -> {
                 Map<String, List<NetworkPolicyPort>> direction = Maps.newConcurrentMap();
                 direction.put(DIRECTION_EGRESS, e.getPorts());
                 e.getTo().forEach(peer -> {
                     if (peer.getPodSelector() != null) {
                         Map<String, String> podLabels = peer.getPodSelector().getMatchLabels();
-                        String podIp = pod.getStatus().getPodIP();
                         pod.getMetadata().getLabels().forEach((k, v) -> {
-                            if (podLabels.get(k) != null && podLabels.get(k).equals(v)) {
+                            if (podLabels != null && podLabels.get(k) != null &&
+                                    podLabels.get(k).equals(v) && podIp != null) {
                                 white.compute(shiftIpDomain(podIp, SHIFTED_IP_PREFIX) +
                                         "/" + HOST_PREFIX, (m, n) -> {
                                     if (n != null) {
@@ -437,26 +468,30 @@
                         });
 
                         if (peer.getNamespaceSelector() != null &&
-                                (podsFromNamespace(peer.getNamespaceSelector().getMatchLabels()).contains(pod) ||
-                                        (peer.getNamespaceSelector().getMatchLabels().size() == 0))) {
-                            white.compute(shiftIpDomain(podIp, SHIFTED_IP_PREFIX) +
-                                    "/" + HOST_PREFIX, (m, n) -> {
-                                if (n != null) {
-                                    n.put(DIRECTION_EGRESS, e.getPorts());
-                                    return n;
-                                } else {
-                                    return direction;
-                                }
-                            });
+                                peer.getNamespaceSelector().getMatchLabels() != null) {
+                            Set<Pod> pods = podsFromNamespace(
+                                    peer.getNamespaceSelector().getMatchLabels());
+                            if ((pods != null && pods.contains(pod)) ||
+                                    (peer.getNamespaceSelector().getMatchLabels().size() == 0)) {
+                                white.compute(shiftIpDomain(podIp, SHIFTED_IP_PREFIX) +
+                                        "/" + HOST_PREFIX, (m, n) -> {
+                                    if (n != null) {
+                                        n.put(DIRECTION_EGRESS, e.getPorts());
+                                        return n;
+                                    } else {
+                                        return direction;
+                                    }
+                                });
 
-                            white.compute(podIp + "/" + HOST_PREFIX, (m, n) -> {
-                                if (n != null) {
-                                    n.put(DIRECTION_EGRESS, e.getPorts());
-                                    return n;
-                                } else {
-                                    return direction;
-                                }
-                            });
+                                white.compute(podIp + "/" + HOST_PREFIX, (m, n) -> {
+                                    if (n != null) {
+                                        n.put(DIRECTION_EGRESS, e.getPorts());
+                                        return n;
+                                    } else {
+                                        return direction;
+                                    }
+                                });
+                            }
                         }
                     }
                 });
@@ -471,7 +506,7 @@
         Set<Pod> pods = Sets.newConcurrentHashSet();
         k8sNamespaceService.namespaces().forEach(ns -> {
             if (ns != null && ns.getMetadata() != null &&
-                    ns.getMetadata().getLabels() != null) {
+                    ns.getMetadata().getLabels() != null && nsLabels != null) {
                 ns.getMetadata().getLabels().forEach((k, v) -> {
                     if (nsLabels.get(k) != null && nsLabels.get(k).equals(v)) {
                         pods.addAll(k8sPodService.pods().stream()
@@ -486,6 +521,33 @@
         return pods;
     }
 
+    private void setAllowAllRule(String direction, boolean install) {
+        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
+                .transition(ROUTING_TABLE);
+
+        int table = 0;
+
+        if (DIRECTION_INGRESS.equalsIgnoreCase(direction)) {
+            table = ACL_INGRESS_WHITE_TABLE;
+        } else if (DIRECTION_EGRESS.equalsIgnoreCase(direction)) {
+            table = ACL_EGRESS_WHITE_TABLE;
+        }
+
+        int finalTable = table;
+        k8sNodeService.completeNodes().forEach(n -> {
+            k8sFlowRuleService.setRule(
+                    appId,
+                    n.intgBridge(),
+                    sBuilder.build(),
+                    tBuilder.build(),
+                    PRIORITY_CIDR_RULE,
+                    finalTable,
+                    install
+            );
+        });
+    }
+
     private void setAllowRules(Map<String, Map<String, List<NetworkPolicyPort>>> white,
                                boolean install) {
         white.forEach((k, v) -> {
@@ -514,11 +576,19 @@
                         pv.forEach(p -> {
                             if (p.getProtocol().equalsIgnoreCase(PROTOCOL_TCP)) {
                                 sBuilder.matchIPProtocol(IPv4.PROTOCOL_TCP);
-                                sBuilder.matchTcpSrc(TpPort.tpPort(p.getPort().getIntVal()));
+
+                                if (p.getPort() != null &&
+                                        p.getPort().getIntVal() != null) {
+                                    sBuilder.matchTcpSrc(TpPort.tpPort(p.getPort().getIntVal()));
+                                }
                             }
                             if (p.getProtocol().equalsIgnoreCase(PROTOCOL_UDP)) {
                                 sBuilder.matchIPProtocol(IPv4.PROTOCOL_UDP);
-                                sBuilder.matchUdpSrc(TpPort.tpPort(p.getPort().getIntVal()));
+
+                                if (p.getPort() != null &&
+                                        p.getPort().getIntVal() != null) {
+                                    sBuilder.matchUdpSrc(TpPort.tpPort(p.getPort().getIntVal()));
+                                }
                             }
 
                             k8sNodeService.completeNodes().forEach(n -> {
@@ -555,11 +625,19 @@
                         pv.forEach(p -> {
                             if (p.getProtocol().equalsIgnoreCase(PROTOCOL_TCP)) {
                                 sBuilder.matchIPProtocol(IPv4.PROTOCOL_TCP);
-                                sBuilder.matchTcpDst(TpPort.tpPort(p.getPort().getIntVal()));
+
+                                if (p.getPort() != null &&
+                                        p.getPort().getIntVal() != null) {
+                                    sBuilder.matchTcpDst(TpPort.tpPort(p.getPort().getIntVal()));
+                                }
                             }
                             if (p.getProtocol().equalsIgnoreCase(PROTOCOL_UDP)) {
                                 sBuilder.matchIPProtocol(IPv4.PROTOCOL_UDP);
-                                sBuilder.matchUdpDst(TpPort.tpPort(p.getPort().getIntVal()));
+
+                                if (p.getPort() != null &&
+                                        p.getPort().getIntVal() != null) {
+                                    sBuilder.matchUdpDst(TpPort.tpPort(p.getPort().getIntVal()));
+                                }
                             }
 
                             k8sNodeService.completeNodes().forEach(n -> {
diff --git a/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sServiceHandler.java b/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sServiceHandler.java
index 38493f3..5660b56 100644
--- a/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sServiceHandler.java
+++ b/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sServiceHandler.java
@@ -103,6 +103,7 @@
 import static org.onosproject.k8snetworking.api.Constants.PRIORITY_NAT_RULE;
 import static org.onosproject.k8snetworking.api.Constants.ROUTING_TABLE;
 import static org.onosproject.k8snetworking.api.Constants.SERVICE_FAKE_MAC_STR;
+import static org.onosproject.k8snetworking.api.Constants.SERVICE_PORT_MAP;
 import static org.onosproject.k8snetworking.api.Constants.SERVICE_TABLE;
 import static org.onosproject.k8snetworking.api.Constants.SHIFTED_IP_CIDR;
 import static org.onosproject.k8snetworking.api.Constants.SHIFTED_IP_PREFIX;
@@ -369,9 +370,13 @@
         service.getSpec().getPorts().stream()
                 .filter(Objects::nonNull)
                 .filter(sp -> sp.getTargetPort() != null)
-                .filter(sp -> sp.getTargetPort().getIntVal() != null)
+                .filter(sp -> sp.getTargetPort().getIntVal() != null ||
+                        (sp.getTargetPort().getStrVal() != null &&
+                                SERVICE_PORT_MAP.get(sp.getTargetPort().getStrVal()) != null))
                 .forEach(sp -> {
-            int targetPort = sp.getTargetPort().getIntVal();
+            int targetPort = sp.getTargetPort().getIntVal() != null ?
+                    sp.getTargetPort().getIntVal() :
+                    SERVICE_PORT_MAP.get(sp.getTargetPort().getStrVal());
             String targetProtocol = sp.getProtocol();
 
             for (Endpoints endpoints : endpointses) {
@@ -428,26 +433,31 @@
             spEpasMap.forEach((sp, epas) ->
                 // add flow rules for unshifting IP domain
                 epas.forEach(epa -> {
-                            setUnshiftDomainRules(node.intgBridge(), POD_TABLE,
-                                    PRIORITY_NAT_RULE, serviceIp, sp.getPort(),
-                                    sp.getProtocol(), nodeIpGatewayIpMap.getOrDefault(epa, epa),
-                                    sp.getTargetPort().getIntVal(), install);
-                        }
-                )
+                    int targetPort = sp.getTargetPort().getIntVal() != null ?
+                            sp.getTargetPort().getIntVal() :
+                            SERVICE_PORT_MAP.get(sp.getTargetPort().getStrVal());
+
+                    setUnshiftDomainRules(node.intgBridge(), POD_TABLE,
+                            PRIORITY_NAT_RULE, serviceIp, sp.getPort(),
+                            sp.getProtocol(), nodeIpGatewayIpMap.getOrDefault(epa, epa),
+                            targetPort, install);
+                })
             );
         }
     }
 
-    private GroupBucket buildBuckets(DeviceId deviceId,
-                                           String podIpStr,
-                                           ServicePort sp) {
+    private GroupBucket buildBuckets(DeviceId deviceId, String podIpStr, ServicePort sp) {
         TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
                 .setIpDst(IpAddress.valueOf(podIpStr));
 
+        int targetPort = sp.getTargetPort().getIntVal() != null ?
+                sp.getTargetPort().getIntVal() :
+                SERVICE_PORT_MAP.get(sp.getTargetPort().getStrVal());
+
         if (TCP.equals(sp.getProtocol())) {
-            tBuilder.setTcpDst(TpPort.tpPort(sp.getTargetPort().getIntVal()));
+            tBuilder.setTcpDst(TpPort.tpPort(targetPort));
         } else if (UDP.equals(sp.getProtocol())) {
-            tBuilder.setUdpDst(TpPort.tpPort(sp.getTargetPort().getIntVal()));
+            tBuilder.setUdpDst(TpPort.tpPort(targetPort));
         }
 
         ExtensionTreatment resubmitTreatment = buildResubmitExtension(
@@ -463,7 +473,9 @@
         Set<ServicePort> sps = service.getSpec().getPorts().stream()
                 .filter(Objects::nonNull)
                 .filter(sp -> sp.getTargetPort() != null)
-                .filter(sp -> sp.getTargetPort().getIntVal() != null)
+                .filter(sp -> sp.getTargetPort().getIntVal() != null ||
+                        (sp.getTargetPort().getStrVal() != null &&
+                                SERVICE_PORT_MAP.get(sp.getTargetPort().getStrVal()) != null))
                 .collect(Collectors.toSet());
 
         String serviceIp = service.getSpec().getClusterIP();