Service Implementation for COE Kube Proxy 48/70648/16
authorFaseela K <faseela.k@ericsson.com>
Mon, 9 Apr 2018 12:01:50 +0000 (17:31 +0530)
committerSam Hague <shague@redhat.com>
Tue, 12 Jun 2018 00:53:24 +0000 (00:53 +0000)
Change-Id: I92800f1c95a67063843192d8a3f9a3183589d0d9
Signed-off-by: Faseela K <faseela.k@ericsson.com>
coe/impl/pom.xml
coe/impl/src/main/java/org/opendaylight/netvirt/coe/listeners/InventoryNodeListener.java [new file with mode: 0644]
coe/impl/src/main/java/org/opendaylight/netvirt/coe/listeners/PodListener.java
coe/impl/src/main/java/org/opendaylight/netvirt/coe/listeners/TerminationPointStateListener.java
coe/impl/src/main/java/org/opendaylight/netvirt/coe/utils/CoeUtils.java
coe/impl/src/main/resources/org/opendaylight/blueprint/coe-renderer.xml

index 4ced776ac2fecb09298a71d297c1332f1c14b49b..23baf45d9c12b516f0695b7051a25c019d8b73e3 100644 (file)
@@ -65,6 +65,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
             <artifactId>tools-api</artifactId>
             <version>${genius.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.genius</groupId>
+            <artifactId>mdsalutil-api</artifactId>
+            <version>${genius.version}</version>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/coe/impl/src/main/java/org/opendaylight/netvirt/coe/listeners/InventoryNodeListener.java b/coe/impl/src/main/java/org/opendaylight/netvirt/coe/listeners/InventoryNodeListener.java
new file mode 100644 (file)
index 0000000..ee60f23
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017, 2018 Ericsson India Global Services Pvt Ltd. 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 java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Nonnull;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.mdsalutil.ActionInfo;
+import org.opendaylight.genius.mdsalutil.FlowEntity;
+import org.opendaylight.genius.mdsalutil.InstructionInfo;
+import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.genius.mdsalutil.MatchInfo;
+import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
+import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
+import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.genius.tools.mdsal.listener.AbstractSyncDataTreeChangeListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class InventoryNodeListener extends AbstractSyncDataTreeChangeListener<Node> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(InventoryNodeListener.class);
+    private final IMdsalApiManager mdsalApiManager;
+
+    @Inject
+    public InventoryNodeListener(final DataBroker dataBroker, final IMdsalApiManager mdsalApiManager) {
+        super(dataBroker, LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class).child(Node.class));
+        this.mdsalApiManager = mdsalApiManager;
+
+    }
+
+    @Override
+    public void remove(@Nonnull InstanceIdentifier<Node> instanceIdentifier, @Nonnull Node node) {
+        // Do nothing
+    }
+
+    @Override
+    public void update(@Nonnull InstanceIdentifier<Node> instanceIdentifier, @Nonnull Node originalNode,
+                       @Nonnull final Node updatedNode) {
+        // Nothing to do
+    }
+
+    @Override
+    public void add(@Nonnull InstanceIdentifier<Node> instanceIdentifier, @Nonnull Node node) {
+        NodeId nodeId = node.getId();
+        String[] nodeIdVal =  nodeId.getValue().split(":");
+        if (nodeIdVal.length < 2) {
+            LOG.warn("Unexpected nodeId {}", nodeId.getValue());
+            return;
+        }
+        BigInteger dpId = new BigInteger(nodeIdVal[1]);
+        setupTableMissForCoeKubeProxyTable(dpId);
+    }
+
+    private void setupTableMissForCoeKubeProxyTable(BigInteger dpId) {
+        List<MatchInfo> matches = new ArrayList<>();
+        List<InstructionInfo> instructions = new ArrayList<>();
+        List<ActionInfo> actionsInfos = new ArrayList<>();
+        actionsInfos.add(new ActionNxResubmit(NwConstants.LPORT_DISPATCHER_TABLE));
+        instructions.add(new InstructionApplyActions(actionsInfos));
+        FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.COE_KUBE_PROXY_TABLE,
+                "COEKubeProxyTableMissFlow",0,
+                "COEKubeProxy Table Miss Flow", 0, 0,
+                NwConstants.COOKIE_COE_KUBE_PROXY_TABLE, matches, instructions);
+        mdsalApiManager.installFlow(flowEntity);
+    }
+}
index 8ef74064c6d547fe9d980a99ecdbe3d16d744780..f46c39a0d709ee3d031b81279485eac0dc8be963 100644 (file)
@@ -217,6 +217,7 @@ public class PodListener implements DataTreeChangeListener<Pods> {
                 CoeUtils.deleteElanInterface(podInterfaceName, tx);
                 LOG.info("interface deletion for pod {}", podInterfaceName);
                 CoeUtils.deleteOfPortInterface(podInterfaceName, tx);
+                CoeUtils.unbindKubeProxyService(podInterfaceName, tx);
                 // TODO delete elan-instance if this is the last pod in the host
                 // TODO delete vpn-instance if this is the last pod in the network
             }));
index f2dd9b659f98737a06edd45fb466eef41922a728..7fd6b66cedde9bd818b66e37b2c79ce021c45a31 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.netvirt.coe.listeners;
 
-import com.google.common.util.concurrent.ListenableFuture;
+import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
@@ -16,16 +16,28 @@ import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.apache.commons.lang3.tuple.Pair;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.genius.mdsalutil.NwConstants;
 import org.opendaylight.genius.tools.mdsal.listener.AbstractSyncDataTreeChangeListener;
+import org.opendaylight.genius.utils.ServiceIndex;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
 import org.opendaylight.netvirt.coe.caches.PodsCache;
 import org.opendaylight.netvirt.coe.utils.CoeUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.coe.northbound.pod.rev170611.coe.Pods;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceTypeFlowBased;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.StypeOpenflow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.StypeOpenflowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
@@ -75,21 +87,23 @@ public class TerminationPointStateListener extends
                 LOG.debug("Detected external interface-id {} and attached mac address {} for {}", interfaceName,
                         macAddress, tpNew.getName());
                 eventCallbacks.onAddOrUpdate(LogicalDatastoreType.OPERATIONAL,
-                    CoeUtils.getPodMetaInstanceId(interfaceName), (unused, alsoUnused) -> {
+                        CoeUtils.getPodMetaInstanceId(interfaceName), (unused, alsoUnused) -> {
                         LOG.info("Pod configuration {} detected for termination-point {},"
-                            + "proceeding with l2 and l3 configurations", interfaceName, tpNew.getName());
-                        List<ListenableFuture<Void>> futures = new ArrayList<>();
-                        futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
-                            InstanceIdentifier<Pods> instanceIdentifier = CoeUtils.getPodUUIDforPodName(interfaceName,
-                                    tx);
+                                    + "proceeding with l2 and l3 configurations", interfaceName, tpNew.getName());
+                        ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
+                            InstanceIdentifier<Pods> instanceIdentifier = CoeUtils.getPodUUIDforPodName(
+                                        interfaceName, tx);
                             Pods pods = podsCache.get(instanceIdentifier).get();
                             if (pods != null) {
                                 IpAddress podIpAddress = pods.getInterface().get(0).getIpAddress();
                                 CoeUtils.createVpnInterface(pods.getNetworkNS(), pods, interfaceName, macAddress,
                                         false, tx);
-                                CoeUtils.updateElanInterfaceWithStaticMac(macAddress, podIpAddress, interfaceName, tx);
+                                CoeUtils.updateElanInterfaceWithStaticMac(macAddress, podIpAddress,
+                                        interfaceName, tx);
+                                LOG.debug("Bind Kube Proxy Service for {}", interfaceName);
+                                bindKubeProxyService(tx, interfaceName);
                             }
-                        }));
+                        }), LOG, "Error handling pod configuration for termination-point");
                         return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
                     });
             }
@@ -100,4 +114,30 @@ public class TerminationPointStateListener extends
     public void add(OvsdbTerminationPointAugmentation tpNew) {
         update(null, tpNew);
     }
+
+    private static void bindKubeProxyService(ReadWriteTransaction tx, String interfaceName) {
+        int priority = ServiceIndex.getIndex(NwConstants.COE_KUBE_PROXY_SERVICE_NAME,
+                NwConstants.COE_KUBE_PROXY_SERVICE_INDEX);
+        int instructionKey = 0;
+        List<Instruction> instructions = new ArrayList<>();
+        instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(
+                NwConstants.COE_KUBE_PROXY_TABLE, ++instructionKey));
+        BoundServices serviceInfo =
+                getBoundServices(String.format("%s.%s", NwConstants.COE_KUBE_PROXY_SERVICE_NAME, interfaceName),
+                        ServiceIndex.getIndex(NwConstants.COE_KUBE_PROXY_SERVICE_NAME,
+                                NwConstants.COE_KUBE_PROXY_SERVICE_INDEX),
+                        priority, NwConstants.COOKIE_COE_KUBE_PROXY_TABLE, instructions);
+        InstanceIdentifier<BoundServices> boundServicesInstanceIdentifier =
+                CoeUtils.buildKubeProxyServicesIId(interfaceName);
+        tx.put(LogicalDatastoreType.CONFIGURATION, boundServicesInstanceIdentifier, serviceInfo,true);
+    }
+
+    private static BoundServices getBoundServices(String serviceName, short servicePriority, int flowPriority,
+                                                 BigInteger cookie, List<Instruction> instructions) {
+        StypeOpenflowBuilder augBuilder = new StypeOpenflowBuilder().setFlowCookie(cookie).setFlowPriority(flowPriority)
+                .setInstruction(instructions);
+        return new BoundServicesBuilder().withKey(new BoundServicesKey(servicePriority)).setServiceName(serviceName)
+                .setServicePriority(servicePriority).setServiceType(ServiceTypeFlowBased.class)
+                .addAugmentation(StypeOpenflow.class, augBuilder.build()).build();
+    }
 }
index 487fab62c5fcfbcacd6190ec60d7dd2618261334..e20c34a24960c20ea71c93ec0ef9c2c875c5a326 100644 (file)
@@ -15,6 +15,7 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.UUID;
+
 import org.apache.commons.lang3.tuple.Pair;
 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
@@ -22,6 +23,7 @@ import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 
+import org.opendaylight.genius.mdsalutil.NwConstants;
 import org.opendaylight.netvirt.neutronvpn.api.enums.IpVersionChoice;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
@@ -53,6 +55,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.coe.northbound.pod.rev17061
 import org.opendaylight.yang.gen.v1.urn.opendaylight.coe.northbound.pod.rev170611.coe.Pods;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceBindings;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeIngress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfoKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.coe.meta.rev180118.PodidentifierInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.coe.meta.rev180118.podidentifier.info.PodIdentifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.coe.meta.rev180118.podidentifier.info.PodIdentifierBuilder;
@@ -428,4 +436,13 @@ public final class CoeUtils {
         return new AdjacenciesBuilder().setAdjacency(adjList).build();
     }
 
+    public static InstanceIdentifier<BoundServices> buildKubeProxyServicesIId(String interfaceName) {
+        return InstanceIdentifier.builder(ServiceBindings.class)
+                .child(ServicesInfo.class, new ServicesInfoKey(interfaceName, ServiceModeIngress.class))
+                .child(BoundServices.class, new BoundServicesKey(NwConstants.COE_KUBE_PROXY_SERVICE_INDEX)).build();
+    }
+
+    public static void unbindKubeProxyService(String interfaceName, WriteTransaction tx) {
+        tx.delete(LogicalDatastoreType.CONFIGURATION, buildKubeProxyServicesIId(interfaceName));
+    }
 }
index 23ce7e5809adc04411769b87128e2c70d0a8bec0..46bf47131d9ffaf0fbf230d88dfe4cc20151376a 100644 (file)
@@ -18,4 +18,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
                interface="org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar"/>
     <reference id="cacheProvider"
                interface="org.opendaylight.infrautils.caches.CacheProvider"/>
+    <reference id="iMdsalApiManager"
+               interface="org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager"/>
 </blueprint>