add NetworkPolicyListener
[netvirt.git] / coe / impl / src / test / java / org / opendaylight / netvirt / coe / listeners / NetworkPolicyListenerTest.java
diff --git a/coe/impl/src/test/java/org/opendaylight/netvirt/coe/listeners/NetworkPolicyListenerTest.java b/coe/impl/src/test/java/org/opendaylight/netvirt/coe/listeners/NetworkPolicyListenerTest.java
new file mode 100644 (file)
index 0000000..b6a1b46
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2018 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netvirt.coe.listeners;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.netvirt.coe.utils.AclUtils.getAceIid;
+import static org.opendaylight.netvirt.coe.utils.AclUtils.getAclIid;
+import static org.opendaylight.netvirt.coe.utils.NetworkPolicyUtils.buildEgress;
+import static org.opendaylight.netvirt.coe.utils.NetworkPolicyUtils.buildEgressPorts;
+import static org.opendaylight.netvirt.coe.utils.NetworkPolicyUtils.buildFrom;
+import static org.opendaylight.netvirt.coe.utils.NetworkPolicyUtils.buildIngress;
+import static org.opendaylight.netvirt.coe.utils.NetworkPolicyUtils.buildIngressPorts;
+import static org.opendaylight.netvirt.coe.utils.NetworkPolicyUtils.buildIpBlock;
+import static org.opendaylight.netvirt.coe.utils.NetworkPolicyUtils.buildMatchLabels;
+import static org.opendaylight.netvirt.coe.utils.NetworkPolicyUtils.buildNetworkPolicy;
+import static org.opendaylight.netvirt.coe.utils.NetworkPolicyUtils.buildNetworkPolicyEgressRule;
+import static org.opendaylight.netvirt.coe.utils.NetworkPolicyUtils.buildNetworkPolicyIngressRule;
+import static org.opendaylight.netvirt.coe.utils.NetworkPolicyUtils.buildNetworkPolicyPeer;
+import static org.opendaylight.netvirt.coe.utils.NetworkPolicyUtils.buildNetworkPolicyPort;
+import static org.opendaylight.netvirt.coe.utils.NetworkPolicyUtils.buildNetworkPolicySpec;
+import static org.opendaylight.netvirt.coe.utils.NetworkPolicyUtils.buildPodSelector;
+import static org.opendaylight.netvirt.coe.utils.NetworkPolicyUtils.buildTo;
+import static org.opendaylight.netvirt.coe.utils.NetworkPolicyUtils.getNetworkPolicyIid;
+
+import com.google.common.base.Optional;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.test.AbstractConcurrentDataBrokerTest;
+import org.opendaylight.genius.infra.RetryingManagedNewTransactionRunner;
+import org.opendaylight.infrautils.utils.concurrent.LoggingFutures;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.Acl;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.core.rev181205.Protocol;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.meta.v1.rev181205.label.selector.MatchLabels;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.PolicyType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.egress.rule.NetworkPolicyEgressRule;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.egress.rule.network.policy.egress.rule.EgressPorts;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.egress.rule.network.policy.egress.rule.To;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.ingress.rule.NetworkPolicyIngressRule;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.ingress.rule.network.policy.ingress.rule.From;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.ingress.rule.network.policy.ingress.rule.IngressPorts;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.network.policies.NetworkPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.peer.NetworkPolicyPeer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.spec.NetworkPolicySpec;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.spec.network.policy.spec.Egress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.spec.network.policy.spec.Ingress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.spec.network.policy.spec.PodSelector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.SecurityRuleAttr;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NetworkPolicyListenerTest extends AbstractConcurrentDataBrokerTest {
+    private static final Logger LOG = LoggerFactory.getLogger(NetworkPolicyListenerTest.class);
+    private RetryingManagedNewTransactionRunner txRunner;
+    private Verifications verifications;
+
+    @Before
+    public void setUp() {
+        DataBroker dataBroker = getDataBroker();
+        NetworkPolicyListener networkPolicyListener = new NetworkPolicyListener(dataBroker);
+        networkPolicyListener.register();
+        verifications = new Verifications(dataBroker);
+        txRunner = new RetryingManagedNewTransactionRunner(dataBroker, 3);
+    }
+
+    @Test
+    public void testNetworkPolicy() throws ExecutionException, InterruptedException {
+        String policyUuid = "11111111-1111-1111-1111-111111111111";
+        String policyName = "network-policy-1";
+
+        NetworkPolicy networkPolicy1 = buildNetworkPolicy1(policyUuid, policyName);
+        InstanceIdentifier<NetworkPolicy> networkPolicyIid = getNetworkPolicyIid(policyUuid);
+
+        // write and verify NetworkPolicy to ds
+        LoggingFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
+            tx.put(networkPolicyIid, networkPolicy1, true);
+        }), LOG, "writing network policy").get();
+
+        LoggingFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
+            Optional<NetworkPolicy> networkPolicyOptional = tx.read(networkPolicyIid).get();
+            assertTrue(networkPolicyOptional.isPresent());
+            assertEquals(networkPolicyOptional.get().getName(), policyName);
+        }), LOG, "reading network policy {}", networkPolicyIid);
+
+        // wait and verify for the NetworkPolicyListener to write an acl from the policy just written
+        InstanceIdentifier<Acl> aclIid = getAclIid(policyUuid);
+        verifications.awaitForData(CONFIGURATION, aclIid);
+        verifyAcl(policyUuid);
+
+        // verify children Ace's have been written
+        verifyAce(policyUuid, "11111111-1111-1111-1111-111111111111_ingress_port_TCP_53", false);
+        verifyAce(policyUuid, "11111111-1111-1111-1111-111111111111_ingress_port_UDP_53", false);
+        verifyAce(policyUuid, "11111111-1111-1111-1111-111111111111_ingress_peer_cidr_10.1.1.1/16", false);
+        verifyAce(policyUuid, "11111111-1111-1111-1111-111111111111_egress_port_TCP_53", false);
+        verifyAce(policyUuid, "11111111-1111-1111-1111-111111111111_egress_port_UDP_53", false);
+        verifyAce(policyUuid, "11111111-1111-1111-1111-111111111111_egress_peer_cidr_10.1.1.1/16", false);
+
+        // Update the policy and verify the acl is updated
+
+        NetworkPolicy networkPolicy2 = buildNetworkPolicy2(policyUuid, policyName + "updated");
+        LoggingFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
+            tx.put(networkPolicyIid, networkPolicy2, true);
+        }), LOG, "writing network policy").get();
+
+        LoggingFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
+            Optional<NetworkPolicy> networkPolicyOptional = tx.read(networkPolicyIid).get();
+            assertTrue(networkPolicyOptional.isPresent());
+            assertEquals(networkPolicyOptional.get().getName(), policyName + "updated");
+        }), LOG, "reading network policy {}", networkPolicyIid);
+
+        // wait and verify for the NetworkPolicyListener to write an acl from the policy just written
+        verifications.awaitForData(CONFIGURATION, aclIid);
+        verifyAcl(policyUuid);
+        // verify children Ace's have been written
+        verifyAce(policyUuid, "11111111-1111-1111-1111-111111111111_ingress_port_TCP_69", false);
+        verifyAce(policyUuid, "11111111-1111-1111-1111-111111111111_ingress_port_UDP_69", false);
+        verifyAce(policyUuid, "11111111-1111-1111-1111-111111111111_ingress_peer_cidr_10.2.1.1/16", false);
+
+        // wait and verify a deleted policy will updates acls to deleted
+        LoggingFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
+            tx.delete(networkPolicyIid);
+        }), LOG, "deleting network policy").get();
+        verifications.awaitForData(CONFIGURATION, aclIid);
+        verifyAce(policyUuid, "11111111-1111-1111-1111-111111111111_ingress_port_TCP_69", true);
+    }
+
+    private void verifyAcl(String policyUuid) {
+        InstanceIdentifier<Acl> aclIid = getAclIid(policyUuid);
+        LoggingFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
+            Optional<Acl> aclOptional = tx.read(aclIid).get();
+            assertTrue(aclOptional.isPresent());
+            LOG.info("acl: {}", aclOptional.get());
+        }), LOG, "reading acl {}", aclIid);
+    }
+
+    private void verifyAce(String policyUuid, String ruleName, boolean isDeleted) {
+        InstanceIdentifier<Ace> aceIid = getAceIid(policyUuid, ruleName);
+        LoggingFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
+            Optional<Ace> aceOptional = tx.read(aceIid).get();
+            assertTrue(aceOptional.isPresent());
+            assertEquals(aceOptional.get().augmentation(SecurityRuleAttr.class).isDeleted(), isDeleted);
+            LOG.info("ace: {}", aceOptional.get());
+        }), LOG, "reading ace {}", aceIid);
+    }
+
+    private NetworkPolicy buildNetworkPolicy1(String policyUuid, String policyName) {
+        List<IngressPorts> ingressPorts = Arrays.asList(
+            buildIngressPorts(buildNetworkPolicyPort("53", Protocol.TCP)),
+            buildIngressPorts(buildNetworkPolicyPort("53", Protocol.UDP)));
+        List<String> except = Arrays.asList("10.1.2.1/24", "10.1.3.1/24");
+        NetworkPolicyPeer ingressNetworkPolicyPeer = buildNetworkPolicyPeer(buildIpBlock("10.1.1.1/16", except));
+        List<From> fromList = Collections.singletonList(buildFrom(ingressNetworkPolicyPeer));
+        NetworkPolicyIngressRule networkPolicyIngressRule = buildNetworkPolicyIngressRule(ingressPorts, fromList);
+        List<Ingress> ingressList = Collections.singletonList(buildIngress(networkPolicyIngressRule));
+
+        List<EgressPorts> egressPorts = Arrays.asList(
+            buildEgressPorts(buildNetworkPolicyPort("53", Protocol.TCP)),
+            buildEgressPorts(buildNetworkPolicyPort("53", Protocol.UDP)));
+        List<String> exceptEgress = Arrays.asList("10.1.2.1/24", "10.1.3.1/24");
+        NetworkPolicyPeer egressNetworkPolicyPeer = buildNetworkPolicyPeer(buildIpBlock("10.1.1.1/16", exceptEgress));
+        List<To> toList = Collections.singletonList(buildTo(egressNetworkPolicyPeer));
+        NetworkPolicyEgressRule networkPolicyEgressRule = buildNetworkPolicyEgressRule(egressPorts, toList);
+        List<Egress> egressList = Collections.singletonList(buildEgress(networkPolicyEgressRule));
+
+        List<PolicyType> policyTypes = Collections.singletonList(PolicyType.Egress);
+        MatchLabels matchLabels = buildMatchLabels("app", "db");
+        PodSelector podSelector = buildPodSelector(Collections.singletonList(matchLabels));
+        NetworkPolicySpec networkPolicySpec = buildNetworkPolicySpec(podSelector, ingressList, egressList, policyTypes);
+        return buildNetworkPolicy(policyUuid, policyName, networkPolicySpec);
+    }
+
+    private NetworkPolicy buildNetworkPolicy2(String policyUuid, String policyName) {
+        List<IngressPorts> ingressPorts = Arrays.asList(
+            buildIngressPorts(buildNetworkPolicyPort("69", Protocol.TCP)),
+            buildIngressPorts(buildNetworkPolicyPort("69", Protocol.UDP)));
+        List<String> except = Arrays.asList("10.2.2.1/24", "10.2.3.1/24");
+        NetworkPolicyPeer ingressNetworkPolicyPeer = buildNetworkPolicyPeer(buildIpBlock("10.2.1.1/16", except));
+        List<From> fromList = Collections.singletonList(buildFrom(ingressNetworkPolicyPeer));
+        NetworkPolicyIngressRule networkPolicyIngressRule = buildNetworkPolicyIngressRule(ingressPorts, fromList);
+        List<Ingress> ingressList = Collections.singletonList(buildIngress(networkPolicyIngressRule));
+
+        List<EgressPorts> egressPorts = Arrays.asList(
+            buildEgressPorts(buildNetworkPolicyPort("53", Protocol.TCP)),
+            buildEgressPorts(buildNetworkPolicyPort("53", Protocol.UDP)));
+        List<String> exceptEgress = Arrays.asList("10.1.2.1/24", "10.1.3.1/24");
+        NetworkPolicyPeer egressNetworkPolicyPeer = buildNetworkPolicyPeer(buildIpBlock("10.1.1.1/16", exceptEgress));
+        List<To> toList = Collections.singletonList(buildTo(egressNetworkPolicyPeer));
+        NetworkPolicyEgressRule networkPolicyEgressRule = buildNetworkPolicyEgressRule(egressPorts, toList);
+        List<Egress> egressList = Collections.singletonList(buildEgress(networkPolicyEgressRule));
+
+        List<PolicyType> policyTypes = Collections.singletonList(PolicyType.Egress);
+        MatchLabels matchLabels = buildMatchLabels("app", "db");
+        PodSelector podSelector = buildPodSelector(Collections.singletonList(matchLabels));
+        NetworkPolicySpec networkPolicySpec = buildNetworkPolicySpec(podSelector, ingressList, egressList, policyTypes);
+        return buildNetworkPolicy(policyUuid, policyName, networkPolicySpec);
+    }
+}