and is available at http://www.eclipse.org/legal/epl-v10.html -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
+ <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.groupbasedpolicy</groupId>
- <artifactId>groupbasedpolicy-renderers</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- <relativePath>../</relativePath>
- </parent>
+ <parent>
+ <groupId>org.opendaylight.groupbasedpolicy</groupId>
+ <artifactId>groupbasedpolicy-renderers</artifactId>
+ <version>0.4.0-SNAPSHOT</version>
+ <relativePath>../</relativePath>
+ </parent>
- <artifactId>ios-xe-renderer</artifactId>
- <packaging>bundle</packaging>
+ <artifactId>ios-xe-renderer</artifactId>
+ <packaging>bundle</packaging>
- <dependencies>
- <!-- model dependencies -->
- <dependency>
- <groupId>org.opendaylight.groupbasedpolicy</groupId>
- <artifactId>sxp-mapper</artifactId>
- </dependency>
+ <properties>
+ <netconf.version>1.1.0-SNAPSHOT</netconf.version>
+ </properties>
- <!-- testing dependencies -->
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-broker-impl</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.groupbasedpolicy</groupId>
- <artifactId>groupbasedpolicy</artifactId>
- <version>${project.version}</version>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- </dependencies>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.netconf</groupId>
+ <artifactId>netconf-artifacts</artifactId>
+ <version>${netconf.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>mdsal-artifacts</artifactId>
+ <version>${mdsal.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
- <build>
- <plugins>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>config</id>
- <goals>
- <goal>generate-sources</goal>
- </goals>
- <configuration>
- <codeGenerators>
- <generator>
- <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
- <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
- <additionalConfiguration>
- <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
- <namespaceToPackage2>urn:opendaylight:params:xml:ns:yang:groupbasedpolicy:renderer==org.opendaylight.groupbasedpolicy.renderer</namespaceToPackage2>
- </additionalConfiguration>
- </generator>
- </codeGenerators>
- <inspectDependencies>true</inspectDependencies>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
+ <dependencies>
+ <!-- testing dependencies -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-broker-impl</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.groupbasedpolicy</groupId>
+ <artifactId>groupbasedpolicy</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.sfc</groupId>
+ <artifactId>sfc-model</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.groupbasedpolicy</groupId>
+ <artifactId>sxp-mapper</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.sfc</groupId>
+ <artifactId>sfc-provider</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.model</groupId>
+ <artifactId>model-inventory</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.netconf</groupId>
+ <artifactId>sal-netconf-connector</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>config</id>
+ <goals>
+ <goal>generate-sources</goal>
+ </goals>
+ <configuration>
+ <codeGenerators>
+ <generator>
+ <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
+ <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
+ <additionalConfiguration>
+ <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
+ <namespaceToPackage2>urn:opendaylight:params:xml:ns:yang:groupbasedpolicy:renderer==org.opendaylight.groupbasedpolicy.renderer</namespaceToPackage2>
+ </additionalConfiguration>
+ </generator>
+ </codeGenerators>
+ <inspectDependencies>true</inspectDependencies>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
</project>
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, 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.groupbasedpolicy.renderer.ios_xe_provider.api.manager;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
+
+/**
+ * Purpose: general policy manager prescription
+ */
+public interface PolicyManager extends AutoCloseable {
+
+ /**
+ * synchronize given configuration with device
+ * @param dataBefore
+ * @param dataAfter
+ */
+ ListenableFuture<Boolean> syncPolicy(Configuration dataBefore, Configuration dataAfter);
+
+ @Override
+ void close();
+}
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.IosXeRendererProvider;
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.cache.EpPolicyCacheImpl;
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.listener.EpPolicyTemplateBySgtListenerImpl;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.listener.IosXeCapableNodeListenerImpl;
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.listener.RendererConfigurationListenerImpl;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.NodeManager;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private final RendererName rendererName;
private RendererConfigurationListenerImpl rendererConfigurationListener;
private EpPolicyTemplateBySgtListenerImpl epPolicyTemplateBySgtListener;
+ private IosXeCapableNodeListenerImpl iosXeCapableNodeListener;
private EpPolicyCacheImpl epPolicyCache;
+ private PolicyManagerImpl policyManager;
+ private NodeManager nodeManager;
public IosXeRendererProviderImpl(final DataBroker dataBroker, final BindingAwareBroker broker,
final RendererName rendererName) {
if (epPolicyTemplateBySgtListener != null) {
epPolicyTemplateBySgtListener.close();
}
+ if (iosXeCapableNodeListener != null) {
+ iosXeCapableNodeListener.close();
+ }
if (epPolicyCache != null) {
epPolicyCache.invalidateAll();
}
public void onSessionInitiated(final BindingAwareBroker.ProviderContext providerContext) {
LOG.info("starting ios-xe renderer");
//TODO register listeners:
+ // node-manager
+ nodeManager = new NodeManager(dataBroker, providerContext);
// ep-policy-template-by-sgt
epPolicyCache = new EpPolicyCacheImpl();
epPolicyTemplateBySgtListener = new EpPolicyTemplateBySgtListenerImpl(dataBroker, epPolicyCache);
+ // network-topology
+ iosXeCapableNodeListener = new IosXeCapableNodeListenerImpl(dataBroker, nodeManager);
+ // policy-manager
+ policyManager = new PolicyManagerImpl(dataBroker, epPolicyCache);
// renderer-configuration endpoints
- rendererConfigurationListener = new RendererConfigurationListenerImpl(dataBroker, rendererName, epPolicyCache);
+ rendererConfigurationListener = new RendererConfigurationListenerImpl(dataBroker, rendererName, policyManager);
// supported node list maintenance
// TODO: upkeep of available renderer-nodes
}
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, 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.groupbasedpolicy.renderer.ios_xe_provider.impl.listener;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.NodeManager;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nonnull;
+import java.util.Collection;
+
+import static org.opendaylight.sfc.provider.SfcProviderDebug.printTraceStart;
+
+public class IosXeCapableNodeListenerImpl implements DataTreeChangeListener<NetworkTopology>, AutoCloseable {
+
+ private static final Logger LOG = LoggerFactory.getLogger(IosXeCapableNodeListenerImpl.class);
+ private final NodeManager nodeManager;
+
+ private final ListenerRegistration listenerRegistration;
+
+
+ public IosXeCapableNodeListenerImpl(final DataBroker dataBroker, final NodeManager nodeManager) {
+ this.nodeManager = Preconditions.checkNotNull(nodeManager);
+ final DataTreeIdentifier<NetworkTopology> networkTopologyPath = new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+ InstanceIdentifier.builder(NetworkTopology.class).build());
+ listenerRegistration = Preconditions.checkNotNull(dataBroker
+ .registerDataTreeChangeListener(networkTopologyPath, this));
+ LOG.info("network-topology listener registered");
+ }
+
+ @Override
+ public void onDataTreeChanged(@Nonnull Collection<DataTreeModification<NetworkTopology>> changes) {
+ printTraceStart(LOG);
+ for (DataTreeModification<NetworkTopology> modification : changes) {
+ DataObjectModification<NetworkTopology> rootNode = modification.getRootNode();
+ NetworkTopology dataAfter = rootNode.getDataAfter();
+ NetworkTopology dataBefore = rootNode.getDataBefore();
+ if (dataAfter != null && dataBefore == null) {
+ nodeManager.syncNodes(dataAfter.getTopology(), null);
+ }
+ else if (dataAfter == null && dataBefore != null) {
+ nodeManager.syncNodes(null, dataBefore.getTopology());
+ }
+ else if (dataAfter != null) {
+ nodeManager.syncNodes(dataAfter.getTopology(), dataBefore.getTopology());
+ }
+ }
+ }
+
+ @Override
+ public void close() {
+ listenerRegistration.close();
+ }
+}
package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.listener;
import com.google.common.base.Preconditions;
-import java.util.Collection;
-import javax.annotation.Nonnull;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.cache.DSTreeBasedCache;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.cache.EpPolicyTemplateCacheKey;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.RendererPolicyUtil;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.manager.PolicyManager;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.RendererKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicy;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicy;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.annotation.Nonnull;
+import java.util.Collection;
+
/**
* Purpose: process changes of configured renderer policies
*/
private static final Logger LOG = LoggerFactory.getLogger(RendererConfigurationListenerImpl.class);
private final ListenerRegistration<RendererConfigurationListenerImpl> listenerRegistration;
- private final DSTreeBasedCache<EndpointPolicyTemplateBySgt, EpPolicyTemplateCacheKey, Sgt> epPolicyCache;
+ private final PolicyManager policyManager;
public RendererConfigurationListenerImpl(final DataBroker dataBroker, final RendererName rendererName,
- final DSTreeBasedCache<EndpointPolicyTemplateBySgt, EpPolicyTemplateCacheKey, Sgt> epPolicyCache) {
- this.epPolicyCache = Preconditions.checkNotNull(epPolicyCache, "missing endpoint template cache");
+ final PolicyManager policyManager) {
+ this.policyManager = Preconditions.checkNotNull(policyManager, "missing endpoint template cache");
final InstanceIdentifier<RendererPolicy> policyPath = InstanceIdentifier.create(Renderers.class)
.child(Renderer.class, new RendererKey(rendererName))
.child(RendererPolicy.class);
for (DataTreeModification<RendererPolicy> rendererPolicyDataTreeModification : collection) {
final DataObjectModification<RendererPolicy> rootNode = rendererPolicyDataTreeModification.getRootNode();
+ final RendererPolicy dataBefore = rootNode.getDataBefore();
final RendererPolicy dataAfter = rootNode.getDataAfter();
- if (dataAfter != null && dataAfter.getConfiguration() != null) {
- // find sgt
- final Configuration configuration = dataAfter.getConfiguration();
- for (RendererEndpoint rendererEndpoint : configuration.getRendererEndpoints().getRendererEndpoint()) {
- // lookup endpoints 1 source | * destination
- AddressEndpointWithLocation sourceEp = RendererPolicyUtil.lookupEndpoint(rendererEndpoint, configuration.getEndpoints().getAddressEndpointWithLocation());
- //resolve sgt
- final Sgt sourceSgt = epPolicyCache.lookupValue(new EpPolicyTemplateCacheKey(sourceEp));
- for (PeerEndpointWithPolicy peerEndpoint : rendererEndpoint.getPeerEndpointWithPolicy()) {
- AddressEndpointWithLocation destinationEp = RendererPolicyUtil.lookupEndpoint(peerEndpoint, configuration.getEndpoints().getAddressEndpointWithLocation());
- //resolve sgt
- final Sgt destinationSgt = epPolicyCache.lookupValue(new EpPolicyTemplateCacheKey(destinationEp));
- // invoke policy manager
- }
- }
+ if (dataAfter != null && dataBefore == null) {
+ policyManager.syncPolicy(dataAfter.getConfiguration(), null);
+ }
+ else if (dataAfter == null && dataBefore != null) {
+ policyManager.syncPolicy(null, dataBefore.getConfiguration());
+ }
+ else if (dataAfter != null) {
+ policyManager.syncPolicy(dataAfter.getConfiguration(), dataBefore.getConfiguration());
}
}
}
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, 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.groupbasedpolicy.renderer.ios_xe_provider.impl.manager;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.MountPoint;
+import org.opendaylight.controller.md.sal.binding.api.MountPointService;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.NodeWriter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus;
+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.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class NodeManager {
+
+ private static final Logger LOG = LoggerFactory.getLogger(NodeManager.class);
+ private static Map<InstanceIdentifier, DataBroker> netconfNodeCache = new HashMap<>();
+ private final DataBroker dataBroker;
+ private MountPointService mountService;
+
+ public NodeManager(final DataBroker dataBroker, BindingAwareBroker.ProviderContext session) {
+ this.dataBroker = Preconditions.checkNotNull(dataBroker);
+ mountService = Preconditions.checkNotNull(session.getSALService(MountPointService.class));
+ }
+
+ public static DataBroker getDataBrokerFromCache(InstanceIdentifier iid) {
+ return netconfNodeCache.get(iid); // TODO read from DS
+ }
+
+ public void syncNodes(List<Topology> dataAfter, List<Topology> dataBefore) {
+ if (dataAfter != null && !dataAfter.isEmpty()) {
+ updateNodes(dataAfter);
+ }
+ }
+
+ private void updateNodes(List<Topology> data) {
+ // WRITE
+ NodeWriter nodeWriter = new NodeWriter();
+ for (Topology topology : data) {
+ if (topology.getNode() == null || topology.getNode().isEmpty()) {
+ continue;
+ }
+ topology.getNode().stream().filter(this::isNetconfDevice).forEach(node -> {
+ DataBroker mountpoint = getNodeMountPoint(topology.getTopologyId(), node);
+ if (mountpoint != null) {
+ netconfNodeCache.put(getMountpointIid(topology.getTopologyId(), node), mountpoint);
+ RendererNode rendererNode = remap(topology.getTopologyId(), node);
+ nodeWriter.write(rendererNode);
+ }
+ });
+ }
+ nodeWriter.commitToDatastore(dataBroker);
+ }
+
+ private DataBroker getNodeMountPoint(TopologyId topologyId, Node node) {
+ NetconfNode netconfNode = node.getAugmentation(NetconfNode.class);
+ if (netconfNode == null) {
+ return null;
+ }
+ InstanceIdentifier mountPointIid = getMountpointIid(topologyId, node);
+ Optional<MountPoint> optionalObject = mountService.getMountPoint(mountPointIid);
+ MountPoint mountPoint;
+ if (optionalObject.isPresent()) {
+ mountPoint = optionalObject.get();
+ if (mountPoint != null) {
+ Optional<DataBroker> optionalDataBroker = mountPoint.getService(DataBroker.class);
+ if (optionalDataBroker.isPresent()) {
+ return optionalDataBroker.get();
+ } else {
+ LOG.debug("Cannot obtain data broker from mountpoint {}", mountPoint);
+ }
+ } else {
+ LOG.debug("Cannot obtain mountpoint with IID {}", mountPointIid);
+ }
+ }
+ return null;
+ }
+
+ private InstanceIdentifier getMountpointIid(TopologyId topologyId, Node node) {
+ return InstanceIdentifier.builder(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(topologyId))
+ .child(Node.class, new NodeKey(node.getNodeId())).build();
+ }
+
+ private RendererNode remap(TopologyId topologyId, Node node) {
+ InstanceIdentifier<Node> nodeIid = InstanceIdentifier.builder(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(topologyId))
+ .child(Node.class, new NodeKey(node.getNodeId())).build();
+ RendererNodeBuilder rendererNodeBuilder = new RendererNodeBuilder();
+ rendererNodeBuilder.setKey(new RendererNodeKey(nodeIid))
+ .setNodePath(nodeIid);
+ return rendererNodeBuilder.build();
+ }
+
+ private boolean isNetconfDevice(Node node) {
+ NetconfNode netconfAugmentation = node.getAugmentation(NetconfNode.class);
+ if (netconfAugmentation == null) {
+ LOG.debug("Node {} is not a netconf device", node.getNodeId().getValue());
+ return false;
+ }
+ if (netconfAugmentation.getConnectionStatus().equals(NetconfNodeConnectionStatus.ConnectionStatus.Connected)) {
+ LOG.info("Node {} ready", node.getNodeId().getValue());
+ return true;
+ }
+ LOG.info("Node {} not connected yet", node.getNodeId().getValue());
+ return false;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, 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.groupbasedpolicy.renderer.ios_xe_provider.impl.manager;
+
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.groupbasedpolicy.api.sf.AllowActionDefinition;
+import org.opendaylight.groupbasedpolicy.api.sf.ChainActionDefinition;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.cache.DSTreeBasedCache;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.manager.PolicyManager;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.cache.EpPolicyTemplateCacheKey;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyWriter;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.RendererPolicyUtil;
+import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SffName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.rendered.service.path.RenderedServicePathHop;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChainBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._class.map.Match;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePath;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePathBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePathKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.LocalBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfNameBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfNameKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.ConfigServiceChainPathModeBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.ServiceIndexBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.Services;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.ServicesBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.services.ServiceTypeChoice;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.services.service.type.choice.ServiceFunctionForwarderBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308.config.service.chain.grouping.IpBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.AddressEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.LocationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionDefinitionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.actions.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.Classifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRule;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction.In;
+import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction.Out;
+import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation.CONSUMER;
+import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation.PROVIDER;
+
+public class PolicyManagerImpl implements PolicyManager {
+
+ private static final Logger LOG = LoggerFactory.getLogger(PolicyMapper.class);
+ private final DataBroker dataBroker;
+ private DSTreeBasedCache<EndpointPolicyTemplateBySgt, EpPolicyTemplateCacheKey, Sgt> epPolicyCache;
+ private final PolicyMapper mapper;
+ private final String policyMapName = "service-chains";
+ private Map<DataBroker, PolicyWriter> perDeviceWriterCache = new HashMap<>();
+
+ public enum ActionCase {ALLOW, CHAIN}
+
+
+ public PolicyManagerImpl(final DataBroker dataBroker,
+ final DSTreeBasedCache<EndpointPolicyTemplateBySgt, EpPolicyTemplateCacheKey, Sgt> epPolicyCache) {
+ this.dataBroker = Preconditions.checkNotNull(dataBroker);
+ this.epPolicyCache = Preconditions.checkNotNull(epPolicyCache);
+ mapper = new PolicyMapper(dataBroker);
+ }
+
+ @Override
+ public ListenableFuture<Boolean> syncPolicy(final Configuration dataAfter, final Configuration dataBefore) {
+ // CREATE
+ for (RendererEndpoint rendererEndpoint : dataAfter.getRendererEndpoints().getRendererEndpoint()) {
+ // Get mountpoint
+ if (dataAfter.getEndpoints() == null) {
+ continue;
+ }
+ DataBroker mountpoint = getAbsoluteLocationMountpoint(rendererEndpoint, dataAfter.getEndpoints()
+ .getAddressEndpointWithLocation());
+ if (mountpoint == null) {
+ continue;
+ }
+ // Initialize appropriate writer
+ PolicyWriter policyWriter;
+ if (perDeviceWriterCache.containsKey(mountpoint)) {
+ policyWriter = perDeviceWriterCache.get(mountpoint);
+ } else {
+ policyWriter = new PolicyWriter(mountpoint);
+ perDeviceWriterCache.put(mountpoint, policyWriter);
+ }
+ // Peer Endpoint
+ for (PeerEndpointWithPolicy peerEndpoint : rendererEndpoint.getPeerEndpointWithPolicy()) {
+ // Sgt Tags
+ final Sgt sourceSgt = findSgtTag(rendererEndpoint, dataAfter.getEndpoints()
+ .getAddressEndpointWithLocation());
+ final Sgt destinationSgt = findSgtTag(peerEndpoint, dataAfter.getEndpoints()
+ .getAddressEndpointWithLocation());
+ if (sourceSgt == null || destinationSgt == null) {
+ continue;
+ }
+ syncPolicyEntities(sourceSgt, destinationSgt, policyWriter, dataAfter, peerEndpoint);
+ }
+ }
+ // Flush
+ perDeviceWriterCache.values().forEach(PolicyWriter::commitToDatastore);
+ perDeviceWriterCache.clear();
+
+ return Futures.immediateFuture(true);
+ }
+
+ private void syncPolicyEntities(final Sgt sourceSgt, final Sgt destinationSgt, PolicyWriter policyWriter,
+ final Configuration dataAfter, final PeerEndpointWithPolicy peerEndpoint) {
+ // Class map
+ String classMapName = generateClassMapName(sourceSgt.getValue(), destinationSgt.getValue());
+ Match match = mapper.createSecurityGroupMatch(sourceSgt.getValue(), destinationSgt.getValue());
+ ClassMap classMap = mapper.createClassMap(classMapName, match);
+ policyWriter.write(classMap);
+
+ Map<ActionCase, Action> actionMap = getActionInDirection(dataAfter, peerEndpoint);
+ if (actionMap == null || actionMap.isEmpty()) {
+ return;
+ }
+ // Policy map entry
+ List<Class> policyMapEntries = new ArrayList<>();
+ if (actionMap.containsKey(ActionCase.ALLOW)) {
+ policyMapEntries = resolveAllowAction();
+ }
+ if (actionMap.containsKey(ActionCase.CHAIN)) {
+ policyMapEntries = resolveChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, classMapName);
+ }
+ policyWriter.write(policyMapEntries);
+ }
+
+ private Sgt findSgtTag(final AddressEndpointKey endpointKey,
+ final List<AddressEndpointWithLocation> endpointsWithLocation) {
+ if (endpointKey == null || endpointsWithLocation == null) {
+ return null;
+ }
+ AddressEndpointWithLocation endpointWithLocation = RendererPolicyUtil.lookupEndpoint(endpointKey,
+ endpointsWithLocation);
+ return epPolicyCache.lookupValue(new EpPolicyTemplateCacheKey(endpointWithLocation));
+ }
+
+ private List<Class> resolveChainAction(final PeerEndpointWithPolicy peerEndpoint, final Sgt sourceSgt,
+ final Sgt destinationSgt, final Map<ActionCase, Action> actionMap,
+ final String classMapName) {
+ List<Class> entries = new ArrayList<>();
+ final Action action = actionMap.get(ActionCase.CHAIN);
+ ServiceFunctionPath servicePath = PolicyManagerUtil.getServicePath(action.getParameterValue());
+ if (servicePath == null) {
+ return null;
+ }
+ TenantId tenantId = getTenantId(peerEndpoint);
+ if (tenantId == null) {
+ return null;
+ }
+ RenderedServicePath renderedPath = PolicyManagerUtil.createRenderedPath(servicePath, tenantId);
+ entries.add(mapper.createPolicyEntry(classMapName, renderedPath, ActionCase.CHAIN));
+ if (servicePath.isSymmetric()) {
+ // symmetric path is in opposite direction. Roles of renderer and peer endpoint will invert
+ RenderedServicePath symmetricPath = PolicyManagerUtil
+ .createSymmetricRenderedPath(servicePath, renderedPath, tenantId);
+ String oppositeClassMapName = generateClassMapName(destinationSgt.getValue(), sourceSgt.getValue());
+ entries.add(mapper.createPolicyEntry(oppositeClassMapName, symmetricPath, ActionCase.CHAIN));
+ }
+ return entries;
+ }
+
+ private List<Class> resolveAllowAction() {
+ List<Class> entries = new ArrayList<>();
+ entries.add(mapper.createPolicyEntry(policyMapName, null, ActionCase.ALLOW));
+ return entries;
+ }
+
+ private DataBroker getAbsoluteLocationMountpoint(final RendererEndpoint endpoint,
+ final List<AddressEndpointWithLocation> endpointsWithLocation) {
+ if (endpoint == null || endpointsWithLocation == null) {
+ return null;
+ }
+ AddressEndpointWithLocation endpointWithLocation = RendererPolicyUtil.lookupEndpoint(endpoint,
+ endpointsWithLocation);
+ final AbsoluteLocation absoluteLocation = endpointWithLocation.getAbsoluteLocation();
+ final LocationType locationType = absoluteLocation.getLocationType();
+ ExternalLocationCase location = (ExternalLocationCase) locationType;
+ if (location == null) {
+ LOG.warn("Endpoint {} does not contain info about external location",
+ endpointWithLocation.getKey().toString());
+ return null;
+ }
+ InstanceIdentifier mountPointId = location.getExternalNodeMountPoint();
+ return NodeManager.getDataBrokerFromCache(mountPointId);
+ }
+
+ private String generateClassMapName(Integer sourceTag, Integer destinationTag) {
+ return "srcTag" + sourceTag + "_dstTag" + destinationTag;
+ }
+
+ private Map<ActionCase, Action> getActionInDirection(Configuration data, PeerEndpointWithPolicy peer) {
+ List<ResolvedRule> rulesInDirection = new ArrayList<>();
+ // Find all rules in desired direction
+ for (RuleGroupWithRendererEndpointParticipation ruleGroupKey :
+ peer.getRuleGroupWithRendererEndpointParticipation()) {
+ EndpointPolicyParticipation participation = ruleGroupKey.getRendererEndpointParticipation();
+ RuleGroup ruleGroup = findRuleGroup(data, ruleGroupKey);
+ if (ruleGroup == null || ruleGroup.getResolvedRule() == null) {
+ continue;
+ }
+
+ for (ResolvedRule resolvedRule : ruleGroup.getResolvedRule()) {
+ if (resolvedRule == null) {
+ continue;
+ }
+ if (resolvedRule.getClassifier() == null || resolvedRule.getAction() == null) {
+ continue;
+ }
+ // TODO only first Classifier used
+ Classifier classifier = resolvedRule.getClassifier().get(0);
+ HasDirection.Direction direction = classifier.getDirection();
+ if ((participation.equals(PROVIDER) && direction.equals(Out)) ||
+ (participation.equals(CONSUMER) && direction.equals(In))) {
+ rulesInDirection.add(resolvedRule);
+ }
+ }
+ }
+ if (rulesInDirection.isEmpty()) {
+ return null; // TODO define drop?
+ }
+ // TODO use only first rule with ActionDefinitionID for now
+ Map<ActionCase, Action> result = new HashMap<>();
+ for (ResolvedRule resolvedRule : rulesInDirection) {
+ // TODO only first action used for now
+ Action action = resolvedRule.getAction().get(0);
+ if (action.getActionDefinitionId() != null) {
+ ActionDefinitionId actionDefinitionId = action.getActionDefinitionId();
+ if (actionDefinitionId.equals(AllowActionDefinition.ID)) {
+ result.put(ActionCase.ALLOW, action);
+ return result;
+ } else if (actionDefinitionId.equals(ChainActionDefinition.ID)) {
+ result.put(ActionCase.CHAIN, action);
+ return result;
+ }
+ }
+ }
+ return null;
+ }
+
+ private RuleGroup findRuleGroup(final Configuration data,
+ final RuleGroupWithRendererEndpointParticipation ruleGroupWithParticipation) {
+ final TenantId tenantId = ruleGroupWithParticipation.getTenantId();
+ final ContractId contractId = ruleGroupWithParticipation.getContractId();
+ final SubjectName subjectName = ruleGroupWithParticipation.getSubjectName();
+ for (RuleGroup ruleGroup : data.getRuleGroups().getRuleGroup()) {
+ if (!ruleGroup.getTenantId().equals(tenantId))
+ continue;
+ if (!ruleGroup.getContractId().equals(contractId)) {
+ continue;
+ }
+ if (ruleGroup.getSubjectName().equals(subjectName)) {
+ return ruleGroup;
+ }
+ }
+ return null;
+ }
+
+ private TenantId getTenantId(PeerEndpointWithPolicy peer) {
+ for (RuleGroupWithRendererEndpointParticipation ruleGroup :
+ peer.getRuleGroupWithRendererEndpointParticipation()) {
+ if (ruleGroup.getTenantId() != null) {
+ return ruleGroup.getTenantId();
+ }
+ }
+ return null;
+ }
+
+
+ private void resolveFirstSffOnClassifier(final Ipv4Address nodeIpAddress,
+ final Set<RenderedServicePath> firstHops) {
+ // Local forwarder
+ LocalBuilder localSffBuilder = new LocalBuilder();
+ localSffBuilder.setIp(new IpBuilder().setAddress(nodeIpAddress).build());
+
+ // TODO add sff to writer
+
+ for (RenderedServicePath renderedPath : firstHops) {
+ // Remote forwarder
+ RenderedServicePathHop firstRenderedPathHop = renderedPath.getRenderedServicePathHop().get(0);
+ SffName sffName = firstRenderedPathHop.getServiceFunctionForwarder();
+
+ // Remap sff and its management ip address
+ org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder serviceFunctionForwarder =
+ SfcProviderServiceForwarderAPI.readServiceFunctionForwarder(sffName);
+ String sffMgmtIpAddress = serviceFunctionForwarder.getIpMgmtAddress().getIpv4Address().getValue();
+
+ ServiceFfNameBuilder remoteSffBuilder = new ServiceFfNameBuilder();
+ remoteSffBuilder.setName(sffName.getValue())
+ .setKey(new ServiceFfNameKey(sffName.getValue()))
+ .setIp(new IpBuilder().setAddress(new Ipv4Address(sffMgmtIpAddress)).build());
+ // TODO add sff to writer
+
+ // Service chain
+ List<Services> services = new ArrayList<>();
+ ServiceTypeChoice serviceTypeChoice = sffTypeChoice(sffName.getValue());
+ ServicesBuilder servicesBuilder = new ServicesBuilder();
+ servicesBuilder.setServiceIndexId(renderedPath.getStartingIndex())
+ .setServiceTypeChoice(serviceTypeChoice);
+ List<ServicePath> servicePaths = new ArrayList<>();
+ ServicePathBuilder servicePathBuilder = new ServicePathBuilder();
+ servicePathBuilder.setKey(new ServicePathKey(renderedPath.getPathId()))
+ .setServicePathId(renderedPath.getPathId())
+ .setConfigServiceChainPathMode(new ConfigServiceChainPathModeBuilder()
+ .setServiceIndex(new ServiceIndexBuilder()
+ .setServices(services).build()).build());
+ servicePaths.add(servicePathBuilder.build());
+ ServiceChainBuilder chainBuilder = new ServiceChainBuilder();
+ chainBuilder.setServicePath(servicePaths);
+ ServiceChain serviceChain = chainBuilder.build();
+ // TODO add service-chain to writer
+ }
+ }
+
+ private ServiceTypeChoice sffTypeChoice(String forwarderName) {
+ ServiceFunctionForwarderBuilder sffBuilder = new ServiceFunctionForwarderBuilder();
+ sffBuilder.setServiceFunctionForwarder(forwarderName);
+ return sffBuilder.build();
+ }
+
+ @Override
+ public void close() {
+ //NOOP
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, 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.groupbasedpolicy.renderer.ios_xe_provider.impl.manager;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308.ClassNameType;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308.PolicyActionType;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.SecurityGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.security.group.Destination;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.security.group.DestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.security.group.Source;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.security.group.SourceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.Type;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.TypeBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMapBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMapKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMap;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMapBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMapKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._class.map.Match;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._class.map.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.ClassBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.ClassKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.ActionList;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.ActionListBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.ActionListKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.ForwardCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.ForwardBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.forward.ServicePath;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.forward.ServicePathBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.forward.ServicePathKey;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.ActionCase.CHAIN;
+
+class PolicyMapper {
+
+ private final DataBroker dataBroker;
+ private static final Logger LOG = LoggerFactory.getLogger(PolicyMapper.class);
+
+ PolicyMapper(final DataBroker dataBroker) {
+ this.dataBroker = Preconditions.checkNotNull(dataBroker);
+ }
+
+ Match createSecurityGroupMatch(int sourceTag, int destinationTag) {
+ MatchBuilder matchBuilder = new MatchBuilder();
+ SecurityGroupBuilder sgBuilder = new SecurityGroupBuilder();
+ Source source = new SourceBuilder().setTag(sourceTag).build();
+ Destination destination = new DestinationBuilder().setTag(destinationTag).build();
+ sgBuilder.setSource(source)
+ .setDestination(destination);
+ return matchBuilder.setSecurityGroup(sgBuilder.build()).build();
+ }
+
+ ClassMap createClassMap(final String classMapName, Match match) {
+ ClassMapBuilder cmBuilder = new ClassMapBuilder();
+ cmBuilder.setName(classMapName)
+ .setKey(new ClassMapKey(classMapName))
+ .setMatch(match)
+ .setPrematch(ClassMap.Prematch.MatchAll);
+ return cmBuilder.build();
+ }
+
+ Class createPolicyEntry(String policyClassName, RenderedServicePath renderedPath,
+ PolicyManagerImpl.ActionCase actionCase) {
+ // Forward Case
+ ForwardCaseBuilder forwardCaseBuilder = new ForwardCaseBuilder();
+ if (actionCase.equals(CHAIN) && renderedPath != null) {
+ // Chain Action
+ ForwardBuilder forwardBuilder = new ForwardBuilder();
+ List<ServicePath> servicePaths = new ArrayList<>();
+ ServicePathBuilder servicePathBuilder = new ServicePathBuilder();
+ servicePathBuilder.setKey(new ServicePathKey(renderedPath.getPathId()))
+ .setServicePathId(renderedPath.getPathId())
+ .setServiceIndex(renderedPath.getStartingIndex());
+ servicePaths.add(servicePathBuilder.build());
+ forwardBuilder.setServicePath(servicePaths);
+ forwardCaseBuilder.setForward(forwardBuilder.build());
+ }
+ // Create Action List
+ List<ActionList> actionList = new ArrayList<>();
+ ActionListBuilder actionListBuilder = new ActionListBuilder();
+ actionListBuilder.setKey(new ActionListKey(PolicyActionType.Forward))
+ .setActionType(PolicyActionType.Forward)
+ .setActionParam(forwardCaseBuilder.build());
+ actionList.add(actionListBuilder.build());
+ // Build class entry
+ ClassBuilder policyClassBuilder = new ClassBuilder();
+ policyClassBuilder.setName(new ClassNameType(policyClassName))
+ .setKey(new ClassKey(new ClassNameType(policyClassName)))
+ .setActionList(actionList);
+ return policyClassBuilder.build();
+ }
+
+ public Type getServicePolicyType(String name) {
+ TypeBuilder typeBuilder = new TypeBuilder();
+ org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.type.ServiceChainBuilder serviceChainBuilder =
+ new org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.type.ServiceChainBuilder();
+ serviceChainBuilder.setName(name)
+ .setDirection(org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.type.ServiceChain.Direction.Input);
+ typeBuilder.setServiceChain(serviceChainBuilder.build());
+ return typeBuilder.build();
+ }
+
+ PolicyMap policyMap(String policyMapName) {
+ PolicyMapBuilder pmBuilder = new PolicyMapBuilder();
+ pmBuilder.setName(policyMapName)
+ .setKey(new PolicyMapKey(policyMapName))
+ .setType(null);
+ return pmBuilder.build();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, 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.groupbasedpolicy.renderer.ios_xe_provider.impl.util;
+
+import com.google.common.util.concurrent.CheckedFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+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.TransactionCommitFailedException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.RendererKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererNodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererNodesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNode;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class NodeWriter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(NodeWriter.class);
+ private List<RendererNode> rendererNodesCache;
+
+ public NodeWriter() {
+ rendererNodesCache = new ArrayList<>();
+ }
+
+ public void write(RendererNode node) {
+ rendererNodesCache.add(node);
+ }
+
+ public void commitToDatastore(DataBroker dataBroker) {
+ RendererNodes rendererNodes = buildRendererNodes();
+ WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
+ InstanceIdentifier<RendererNodes> Iid = InstanceIdentifier.builder(Renderers.class)
+ .child(Renderer.class, new RendererKey(new RendererName("ios-xe-renderer"))) // TODO unify renderer name
+ .child(RendererNodes.class)
+ .build();
+ try {
+ wtx.merge(LogicalDatastoreType.OPERATIONAL, Iid, rendererNodes, true);
+ CheckedFuture<Void, TransactionCommitFailedException> submitFuture = wtx.submit();
+ submitFuture.checkedGet();
+ // Clear cache
+ rendererNodesCache.clear();
+ } catch (TransactionCommitFailedException e) {
+ LOG.error("Write transaction failed to {}", e.getMessage());
+ } catch (Exception e) {
+ LOG.error("Failed to .. {}", e.getMessage());
+ }
+ }
+
+ private RendererNodes buildRendererNodes() {
+ RendererNodesBuilder rendererNodesBuilder = new RendererNodesBuilder();
+ rendererNodesBuilder.setRendererNode(rendererNodesCache);
+ return rendererNodesBuilder.build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, 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.groupbasedpolicy.renderer.ios_xe_provider.impl.util;
+
+import org.opendaylight.groupbasedpolicy.api.sf.ChainActionDefinition;
+import org.opendaylight.sfc.provider.api.SfcProviderRenderedPathAPI;
+import org.opendaylight.sfc.provider.api.SfcProviderServicePathAPI;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.RspName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfcName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInput;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPaths;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class PolicyManagerUtil {
+
+ private static final Logger LOG = LoggerFactory.getLogger(PolicyManagerUtil.class);
+
+ public static ServiceFunctionPath getServicePath(List<ParameterValue> params) {
+ if (params == null || params.isEmpty()) {
+ LOG.error("Cannot found service path, parameter value is null");
+ return null;
+ }
+ Map<String, Object> paramsMap = new HashMap<>();
+ for (ParameterValue value : params) {
+ if (value.getName() == null)
+ continue;
+ if (value.getIntValue() != null) {
+ paramsMap.put(value.getName().getValue(), value.getIntValue());
+ } else if (value.getStringValue() != null) {
+ paramsMap.put(value.getName().getValue(), value.getStringValue());
+ }
+ }
+ String chainName = null;
+ for (String name : paramsMap.keySet()) {
+ if (name.equals(ChainActionDefinition.SFC_CHAIN_NAME)) {
+ chainName = (String) paramsMap.get(name);
+ }
+ }
+ if (chainName == null) {
+ LOG.error("Cannot found service path, chain name is null");
+ return null;
+ }
+ ServiceFunctionPath serviceFunctionPath = findServiceFunctionPath(new SfcName(chainName));
+ if (serviceFunctionPath == null) {
+ LOG.error("Service function path not found for name {}", chainName);
+ return null;
+ }
+ return serviceFunctionPath;
+ }
+
+ public static RenderedServicePath createRenderedPath(ServiceFunctionPath sfp, TenantId tenantId) {
+ RenderedServicePath renderedServicePath;
+ // Try to read existing RSP
+ RspName rspName = new RspName(sfp.getName().getValue() + tenantId.getValue() + "-gbp-rsp");
+ renderedServicePath = SfcProviderRenderedPathAPI.readRenderedServicePath(rspName);
+ if (renderedServicePath != null) {
+ return renderedServicePath;
+ }
+ LOG.info("Rendered service path with name {} not found, creating a new one ..", rspName.getValue());
+ CreateRenderedPathInput input = new CreateRenderedPathInputBuilder()
+ .setParentServiceFunctionPath(sfp.getName().getValue())
+ .setName(rspName.getValue())
+ .setSymmetric(sfp.isSymmetric())
+ .build();
+ renderedServicePath = SfcProviderRenderedPathAPI.createRenderedServicePathAndState(sfp, input);
+ LOG.info("Rendered service path {} created", rspName.getValue());
+ return renderedServicePath;
+ }
+
+ private static ServiceFunctionPath findServiceFunctionPath(SfcName chainName) {
+ ServiceFunctionPaths allPaths = SfcProviderServicePathAPI.readAllServiceFunctionPaths();
+ for (ServiceFunctionPath serviceFunctionPath : allPaths.getServiceFunctionPath()) {
+ if (serviceFunctionPath.getServiceChainName().equals(chainName)) {
+ return serviceFunctionPath;
+ }
+ }
+ return null;
+ }
+
+ public static RenderedServicePath createSymmetricRenderedPath(ServiceFunctionPath sfp, RenderedServicePath rsp,
+ TenantId tenantId) {
+ RenderedServicePath reversedRenderedPath;
+ // Try to read existing RSP
+ RspName rspName = new RspName(sfp.getName().getValue() + tenantId.getValue() + "-gbp-rsp-Reverse");
+ reversedRenderedPath = SfcProviderRenderedPathAPI.readRenderedServicePath(rspName);
+ if (reversedRenderedPath != null) {
+ return reversedRenderedPath;
+ }
+ LOG.info("Reversed rendered service path with name {} not found, creating a new one ..", rspName.getValue());
+ reversedRenderedPath = SfcProviderRenderedPathAPI.createSymmetricRenderedServicePathAndState(rsp);
+ LOG.info("Rendered service path {} created", rspName.getValue());
+ return reversedRenderedPath;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, 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.groupbasedpolicy.renderer.ios_xe_provider.impl.util;
+
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+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.TransactionCommitFailedException;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308.Native;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMapKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PolicyWriter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(PolicyWriter.class);
+
+ private final DataBroker mountpoint;
+ // Local cache
+ private List<ClassMap> classMapEntries;
+ private List<Class> policyMapEntries;
+
+ public PolicyWriter(final DataBroker dataBroker) {
+ mountpoint = Preconditions.checkNotNull(dataBroker);
+ classMapEntries = new ArrayList<>();
+ policyMapEntries = new ArrayList<>();
+ }
+
+ public void write(ClassMap classMap) {
+ classMapEntries.add(classMap);
+ }
+
+ public void write(List<Class> policyMapEntries) {
+ this.policyMapEntries.addAll(policyMapEntries);
+ }
+
+ public void commitToDatastore() {
+ // create and write service-policy
+ // create and write policy-map with policyMapEntries
+ // create and write class-maps
+
+ WriteTransaction wtx = mountpoint.newWriteOnlyTransaction();
+ // Class maps
+ for (ClassMap entry : classMapEntries) {
+ InstanceIdentifier<ClassMap> iid = classMapInstanceIdentifier(entry);
+ try {
+ wtx.merge(LogicalDatastoreType.CONFIGURATION, iid, entry, true);
+ CheckedFuture<Void, TransactionCommitFailedException> submitFuture = wtx.submit();
+ submitFuture.checkedGet();
+ // Clear cache
+ classMapEntries.clear();
+ } catch (TransactionCommitFailedException e) {
+ LOG.error("Write transaction failed to {}", e.getMessage());
+ } catch (Exception e) {
+ LOG.error("Failed to .. {}", e.getMessage());
+ }
+ }
+ }
+
+ private InstanceIdentifier<ClassMap> classMapInstanceIdentifier(ClassMap classMap) {
+ return InstanceIdentifier.builder(Native.class)
+ .child(ClassMap.class, new ClassMapKey(classMap.getName())).build();
+ }
+}
-package org.opendaylight.yang.gen.v1.urn.ios.rev160516;
+package org.opendaylight.yang.gen.v1.urn.ios.rev160308;
/**
-package org.opendaylight.yang.gen.v1.urn.ios.rev160516;
+package org.opendaylight.yang.gen.v1.urn.ios.rev160308;
/**
-package org.opendaylight.yang.gen.v1.urn.ios.rev160516;
+package org.opendaylight.yang.gen.v1.urn.ios.rev160308;
/**
-package org.opendaylight.yang.gen.v1.urn.ios.rev160516;
+package org.opendaylight.yang.gen.v1.urn.ios.rev160308;
/**
-package org.opendaylight.yang.gen.v1.urn.ios.rev160516;
+package org.opendaylight.yang.gen.v1.urn.ios.rev160308;
/**
-package org.opendaylight.yang.gen.v1.urn.ios.rev160516;
+package org.opendaylight.yang.gen.v1.urn.ios.rev160308;
/**
-package org.opendaylight.yang.gen.v1.urn.ios.rev160516;
+package org.opendaylight.yang.gen.v1.urn.ios.rev160308;
/**
-package org.opendaylight.yang.gen.v1.urn.ios.rev160516;
+package org.opendaylight.yang.gen.v1.urn.ios.rev160308;
/**
-package org.opendaylight.yang.gen.v1.urn.ios.rev160516._native.mls.qos;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160516._native.mls.qos.Map.PolicedDscp;
+package org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.mls.qos;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.mls.qos.Map.PolicedDscp;
/**
-package org.opendaylight.yang.gen.v1.urn.ios.rev160516._native.policy.map._class.pm.policy.monitor.metric.rtp;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160516._native.policy.map._class.pm.policy.monitor.metric.rtp.ClockRate.Number;
+package org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.pm.policy.monitor.metric.rtp;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.pm.policy.monitor.metric.rtp.ClockRate.Number;
/**
"This file was adapted to be parsed by yangtools for groupbasedpolicy project purpose";
revision
- 2016-05-16;
+ 2016-03-8;
/// ========================================================================
/// typedefs
}
}
+ grouping interface-atm-grouping {
+ // Removed body
+ }
+
+ grouping interface-cellular-grouping {
+ //interface * / dialer
+ container dialer {
+ leaf in-band {
+ type empty;
+ }
+ leaf idle-timeout {
+ type uint32;
+ }
+ leaf string {
+ type string;
+ }
+ leaf watch-group {
+ type uint32;
+ }
+ }
+ //interface * / async
+ container async {
+ leaf mode {
+ type enumeration {
+ enum interactive;
+ }
+ }
+ }
+ }
+
+ grouping interface-common-grouping {
+ // interface * / service-policy
+ container service-policy {
+ tailf:info "Configure QoS Service Policy";
+ description "Configure QoS Service Policy";
+ leaf history {
+ tailf:cli-full-command;
+ tailf:info "Keep history of QoS metrics";
+ description "Keep history of QoS metrics";
+ type empty;
+ }
+ leaf "input" {
+ tailf:cli-full-command;
+ tailf:info "Assign policy-map to the input of an interface";
+ description "Assign policy-map to the input of an interface";
+ type string {
+ tailf:info "WORD;;policy-map name";
+ }
+ tailf:non-strict-leafref {
+ path "/ios:native/policy-map/name";
+ }
+ }
+ leaf "output" {
+ tailf:cli-full-command;
+ tailf:info "Assign policy-map to the output of an interface";
+ description "Assign policy-map to the output of an interface";
+ type string {
+ tailf:info "WORD;;policy-map name";
+ }
+ tailf:non-strict-leafref {
+ path "/ios:native/policy-map/name";
+ }
+ }
+ container "type" {
+ tailf:info "Configure CPL Service Policy";
+ description "Configure CPL Service Policy";
+ container performance-monitor {
+ tailf:info "Configure media monitor service-policy type";
+ description "Configure media monitor service-policy type";
+ tailf:cli-sequence-commands;
+ tailf:cli-compact-syntax;
+ leaf direction {
+ tailf:cli-drop-node-name;
+ type enumeration {
+ enum "input" {
+ tailf:info "Assign policy-map to the input of an interfcae";
+ }
+ enum "output" {
+ tailf:info "Assign policy-map to the output of an interfcae";
+ }
+ }
+ }
+ leaf name {
+ tailf:cli-drop-node-name;
+ type string {
+ tailf:info "WORD;;policy-map name";
+ }
+ tailf:non-strict-leafref {
+ path "/ios:native/policy-map/name";
+ }
+ }
+ }
+ // interface * / service-policy type * / service-chain
+ container service-chain {
+ tailf:info "Configure Service-chain Service Policy";
+ description "Configure Service-chain Service Policy";
+ tailf:cli-sequence-commands;
+ tailf:cli-compact-syntax;
+ leaf direction {
+ tailf:cli-drop-node-name;
+ type enumeration {
+ enum "input" {
+ tailf:info "Assign policy-map to the input of an interfcae";
+ }
+ enum "output" {
+ tailf:info "Assign policy-map to the output of an interfcae";
+ }
+ }
+ }
+ leaf name {
+ tailf:cli-drop-node-name;
+ type string {
+ tailf:info "WORD;;policy-map name";
+ }
+ tailf:non-strict-leafref {
+ path "/ios:native/policy-map/name";
+ }
+ }
+ }
+ }
+ }
+ }
+
+ grouping interface-ethernet-grouping {
+ // Removed body
+ }
+
+ grouping interface-grouping {
+ // Removed body
+ }
+
+ grouping interface-overlay-grouping {
+ // Removed body
+ }
+
+ grouping interface-pointtopoint-grouping {
+ // Removed body
+ }
+
+ grouping interface-pseudowire-grouping {
+ // Removed body
+ }
+
+ grouping interface-switch-grouping {
+ // Removed body
+ }
+
+ grouping interface-tunnel-grouping {
+ // Removed body
+ }
+
+ grouping interface-zone-member-grouping {
+ // interface * / zone-member
+ container zone-member {
+ tailf:info "Apply zone name";
+ description "Apply zone name";
+ leaf security {
+ tailf:info "Security zone";
+ description "Security zone";
+ type string;
+ tailf:non-strict-leafref {
+ path "/ios:native/zone/security/id";
+ }
+ }
+ }
+ }
+
grouping police-action-drop-grouping {
leaf drop {
tailf:info "drop packet";
}
}
+ grouping pseudowire-grouping {
+ // Removed body
+ }
+
grouping random-detect-grouping {
leaf min-threshold {
tailf:cli-drop-node-name;
}
}
+
/// ========================================================================
/// native
/// ========================================================================
}
}
+/// ========================================================================
+/// interface
+/// ========================================================================
+
+ container interface {
+ tailf:info "Configure interfaces";
+ description "Configure interfaces";
+ tailf:cli-diff-dependency "/ios:native/vrf";
+ tailf:cli-explicit-exit;
+
+ // interface AppNav-Compress
+ list AppNav-Compress {
+ tailf:info "Service-Context Virtual Interface Compress";
+ description "Service-Context Virtual Interface Compress";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ tailf:cli-suppress-key-abbreviation;
+ key name;
+ leaf name {
+ type uint16 {
+ tailf:info "<1-1000>;;AppNav-Compress interface number";
+ range "1..1000";
+ }
+ }
+ uses interface-common-grouping;
+ }
+ // interface AppNav-UnCompress
+ list AppNav-UnCompress {
+ tailf:info "Service-Context Virtual Interface UnCompress";
+ description "Service-Context Virtual Interface UnCompress";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ tailf:cli-suppress-key-abbreviation;
+ key name;
+ leaf name {
+ type uint16 {
+ tailf:info "<1-1000>;;AppNav-UnCompress interface number";
+ range "1..1000";
+ }
+ }
+ uses interface-common-grouping;
+ }
+
+ // interface ATM #
+ list ATM {
+ tailf:info "ATM interface";
+ description "ATM interface";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ tailf:cli-suppress-key-abbreviation;
+ key name;
+ leaf name {
+ type string {
+ tailf:info "<slot>/<subslot>/<port>;;ATM interface number";
+ pattern "([0-9]/){2}([0-9]|(ima[0-9]))(:[0-9])?";
+ }
+ }
+ uses interface-atm-grouping;
+ }
+
+ // subinterface ATM #.#
+ container ATM-subinterface {
+ tailf:cli-drop-node-name;
+ list ATM {
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-subif";
+ tailf:cli-suppress-key-abbreviation;
+ key name;
+ leaf name {
+ type string {
+ pattern "([0-9]/){2}[0-9]\.([0-9]/){3}[0-9]";
+ }
+ }
+ uses interface-atm-grouping;
+ }
+ }
+
+ // interface ATM-ACR #
+ list ATM-ACR {
+ tailf:info "ATM-ACR interface";
+ description "ATM-ACR interface";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ tailf:cli-suppress-key-abbreviation;
+ key name;
+ leaf name {
+ type string {
+ tailf:info "<slot>/<subslot>/<port>;;ATM-ACR interface number";
+ pattern "[0-9]";
+ }
+ }
+ uses interface-atm-grouping;
+ }
+
+ // subinterface ATM-ACR #.#
+ container ATM-ACRsubinterface {
+ tailf:cli-drop-node-name;
+ list ATM-ACR {
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-subif";
+ tailf:cli-suppress-key-abbreviation;
+ key name;
+ leaf name {
+ type string {
+ pattern "[0-9]\.([0-9]/){3}[0-9]";
+ }
+ }
+ uses interface-atm-grouping;
+ }
+ }
+ // interface BDI
+ list BDI {
+ tailf:info "Bridge-Domain interface";
+ description "Bridge-Domain interface";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ key name;
+ leaf name {
+ type string {
+ // pattern "([0-9])+/([0-9])+(/([0-9])+)?";
+ tailf:info "<1-16000>;;BDI interface number";
+ }
+ }
+ uses interface-common-grouping;
+ }
+
+ // interface CEM #
+ list CEM {
+ tailf:info "Circuit Emulation interface";
+ description "Circuit Emulation interface";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ tailf:cli-suppress-key-abbreviation;
+ key name;
+ leaf name {
+ type string {
+ tailf:info "<slot>/<port>;;CEM interface number";
+ pattern "([0-9]/){2}[0-9]";
+ }
+ }
+ uses interface-atm-grouping;
+ }
+
+ // interface CEM-ACR #
+ list CEM-ACR {
+ tailf:info "Circuit Emulation interface";
+ description "Circuit Emulation interface";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ tailf:cli-suppress-key-abbreviation;
+ key name;
+ leaf name {
+ type uint8 {
+ tailf:info "<0-255>;;CEM-ACR interface number";
+ range "0..255";
+ }
+ }
+ uses interface-atm-grouping;
+ }
+
+ // interface Embedded-Service-Engine
+ list Embedded-Service-Engine {
+ tailf:info "cisco embedded service engine module";
+ description "cisco embedded service engine module";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ // tailf:cli-full-command;
+ key name;
+ leaf name {
+ type string {
+ tailf:info "<0-2>/<0-0>;;Embedded-Service-Engine interface number";
+ }
+ }
+ uses interface-common-grouping;
+ }
+
+ // interface FastEthernet
+ list FastEthernet {
+ tailf:info "FastEthernet IEEE 802.3";
+ description "FastEthernet IEEE 802.3";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ // tailf:cli-full-command;
+ key name;
+ leaf name {
+ type string {
+ //pattern "([0-9])+(/([0-9])+)*";
+ tailf:info "<0-66>/<0-128>;;FastEthernet interface number";
+ }
+ }
+ uses interface-ethernet-grouping;
+ uses interface-common-grouping;
+ uses interface-zone-member-grouping;
+ uses interface-switch-grouping; //CATALYST
+ }
+
+ // interface GigabitEthernet
+ list GigabitEthernet {
+ tailf:info "GigabitEthernet IEEE 802.3z";
+ description "GigabitEthernet IEEE 802.3z";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ // tailf:cli-full-command;
+ key name;
+ leaf name {
+ type string {
+ //pattern "([0-9])+(/([0-9])+)*";
+ tailf:info "<0-66>/<0-128>;;"+
+ "GigabitEthernet interface number";
+ }
+ }
+ leaf media-type {
+ tailf:info "Media type";
+ description "Media type";
+ type enumeration {
+ enum auto-select {
+ tailf:info "Use whichever connector is attached";
+ }
+ enum rj45 {
+ tailf:info "Copper";
+ }
+ enum sfp {
+ tailf:info "Fiber";
+ }
+ }
+ }
+ leaf port-type {
+ //FIXME: tailf:info
+ //FIXME: 3600 only?
+ type enumeration {
+ enum nni;
+ }
+ }
+ uses interface-ethernet-grouping;
+ uses interface-common-grouping;
+ uses interface-zone-member-grouping;
+ uses interface-switch-grouping; //CATALYST
+ }
+
+ // interface TenGigabitEthernet
+ list TenGigabitEthernet {
+ tailf:info "Ten Gigabit Ethernet";
+ description "Ten Gigabit Ethernet";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ // tailf:cli-full-command;
+ key name;
+ leaf name {
+ type string {
+ //pattern "([0-9])+(/([0-9])+)*";
+ tailf:info "<0-66>/<0-128>;;"+
+ "TenGigabitEthernet interface number";
+ }
+ }
+ leaf media-type {
+ tailf:info "Media type";
+ description "Media type";
+ type enumeration {
+ enum auto-select {
+ tailf:info "Use whichever connector is attached";
+ }
+ enum rj45 {
+ tailf:info "Copper";
+ }
+ enum sfp {
+ tailf:info "Fiber";
+ }
+ }
+ }
+ leaf port-type {
+ //FIXME: tailf:info
+ //FIXME: 3600 only?
+ type enumeration {
+ enum nni;
+ }
+ }
+ uses interface-ethernet-grouping;
+ uses interface-common-grouping;
+ uses interface-zone-member-grouping;
+ uses interface-switch-grouping; //CATALYST
+ }
+
+ // interface Loopback
+ list Loopback {
+ // pvh hide Loopback interfaces
+ // tailf:hidden full;
+ tailf:info "Loopback interface";
+ description "Loopback interface";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ // tailf:cli-full-command;
+ key name;
+ leaf name {
+ type string {
+ // pattern "([0-9])+/([0-9])+(/([0-9])+)?";
+ tailf:info "<0-2147483647>;;Loopback interface number";
+ }
+ }
+ uses interface-common-grouping;
+ }
+
+ list nve {
+ tailf:info "Network virtualization endpoint interface";
+ description "Network virtualization endpoint interface";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ key name;
+ leaf name {
+ type uint16 {
+ tailf:info "<1-4096>;;nve interface number";
+ range "1..4096";
+ }
+ }
+
+ container source-interface {
+ tailf:info "Specify source interface for NVE";
+ description "Specify source interface for NVE";
+ // FIXME: tailf:cli-diff-dependency "/ios:native/interface";
+ uses interface-grouping;
+ }
+ container member {
+ tailf:cli-incomplete-command;
+ tailf:cli-sequence-commands;
+ list vni {
+ tailf:info "Configure VNI information";
+ description "Configure VNI information";
+ tailf:cli-sequence-commands;
+ tailf:cli-compact-syntax;
+
+ key vni-range;
+ leaf vni-range {
+ type string {
+ tailf:info "WORD;;VNI range or instance between 4096-16777215 example: 6010-6030 or 7115";
+ }
+ }
+ container mcast-group {
+ tailf:cli-incomplete-command;
+ tailf:cli-sequence-commands;
+ leaf multicast-group-min {
+ tailf:cli-drop-node-name;
+ tailf:info "Starting Multicast Group IPv4 Address";
+ description "Starting Multicast Group IPv4 Address";
+ type inet:ipv4-address {
+ tailf:info "A.B.C.D;;IP address";
+ }
+ }
+ leaf multicast-group-max {
+ tailf:cli-drop-node-name;
+ tailf:info "Ending Multicast Group IPv4 Address";
+ description "Ending Multicast Group IPv4 Address";
+ type inet:ipv4-address {
+ tailf:info "A.B.C.D;;IP address";
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // interface overlay
+ list overlay {
+ tailf:info "Overlay interface";
+ description "Overlay interface";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ key name;
+ leaf name {
+ type uint16 {
+ tailf:info "<0-512>;;Overlay interface number";
+ range "0..512";
+ }
+ }
+ uses interface-common-grouping;
+ uses interface-ethernet-grouping;
+ uses interface-overlay-grouping;
+ }
+
+ // interface Port-channel
+ list Port-channel {
+ tailf:info "Ethernet Channel of interfaces";
+ description "Ethernet Channel of interfaces";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ // tailf:cli-full-command;
+ key name;
+ leaf name {
+ type uint32 {
+ tailf:info "<1-512>;;Port-channel interface number";
+ range "1..512";
+ }
+ }
+ leaf pc-speed {
+ tailf:alt-name "speed";
+ tailf:info "Configure speed operation.";
+ description "Configure speed operation.";
+ type enumeration {
+ enum "10" {
+ tailf:info "Force 10 Mbps operation";
+ }
+ enum "100" {
+ tailf:info "Force 100 Mbps operation";
+ }
+ enum "1000" {
+ tailf:info "Enable AUTO speed configuration";
+ }
+ enum "nonegotiate" {
+ //FIXME
+ }
+ enum "auto" {
+ tailf:info "Enable AUTO speed configuration";
+ }
+ }
+ }
+ uses interface-common-grouping;
+ uses interface-switch-grouping; //CATALYST
+ uses interface-ethernet-grouping;
+ }
+
+ // subinterface Port-channel #.#
+ container Port-channel-subinterface {
+ tailf:cli-drop-node-name;
+ list Port-channel {
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-subif";
+ tailf:cli-suppress-key-abbreviation;
+ key name;
+ leaf name {
+ type string;
+ }
+ uses interface-common-grouping;
+ uses interface-switch-grouping; //CATALYST
+ uses interface-ethernet-grouping;
+ }
+ }
+
+ //interface pseudowire
+ list pseudowire {
+ tailf:info "Pseudowire Interface";
+ description "Pseudowire Interface";
+ tailf:cli-mode-name "config-if";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ key name;
+ leaf name {
+ type uint32 {
+ tailf:info "<1-231072>;;pseudowire interface number";
+ range "1..231072";
+ }
+ }
+ uses pseudowire-grouping;
+ }
+ //interface SM
+ list "SM" {
+ tailf:info "SM Interface";
+ description "SM Interface";
+ tailf:cli-mode-name "config-if";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ key name;
+ leaf name {
+ type string {
+ pattern "([0-9])+(/([0-9])+)?";
+ }
+ }
+ uses interface-common-grouping;
+ }
+ //interface Cellular
+ list Cellular {
+ tailf:info "Cellular Interface";
+ description "Cellular Interface";
+ tailf:cli-mode-name "config-if";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ key name;
+ leaf name {
+ type string {
+ pattern "([0-9])+(/([0-9])+)?";
+ }
+ }
+ uses interface-common-grouping;
+ uses interface-cellular-grouping;
+ }
+
+ // interface Vlan
+ list Vlan {
+ tailf:info "Catalyst Vlans";
+ description "Catalyst Vlans";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ key name;
+ leaf name {
+ type uint16 {
+ tailf:info "<1-4094>;;Vlan interface number";
+ range "1..4094";
+ }
+ }
+ uses interface-common-grouping;
+ uses interface-zone-member-grouping;
+ }
+
+ // interface Group-Async
+ list Group-Async {
+ tailf:info "Async Group interface";
+ description "Async Group interface";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ key name;
+ leaf name {
+ type uint16 {
+ tailf:info "<0-64>;;Group-Async interface number";
+ range "0..64";
+ }
+ }
+ leaf physical-layer {
+ tailf:info "Configure sync or async physical layer on serial "+
+ "interface";
+ description "Configure sync or async physical layer on serial "+
+ "interface";
+ type enumeration {
+ enum async {
+ tailf:info "Configure asynchronous physical layer on serial "
+ +"interface";
+ }
+ enum sync {
+ tailf:info "Configure synchronous physical layer on serial "+
+ "interface";
+ }
+ }
+ }
+ uses interface-common-grouping;
+ }
+
+ // interface Multilink
+ list Multilink {
+ tailf:info "Multilink-group interface";
+ description "Multilink-group interface";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ tailf:cli-full-command;
+ key name;
+ leaf name {
+ type uint16 {
+ tailf:info "<1-65535>;;Multilink interface number";
+ range "1..65535";
+ }
+ }
+ uses interface-common-grouping;
+ uses interface-pointtopoint-grouping;
+ }
+
+ // interface Serial
+ list Serial {
+ tailf:info "Serial interface";
+ description "Serial interface";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ tailf:cli-full-command;
+ key name;
+ leaf name {
+ type string {
+ pattern "([0-9])+/([0-9])+/([0-9])+\.([0-9])+/([0-9])+/([0-9])+/([0-9])+:([0-9])";
+ //FIXME: info + syntax
+ }
+ }
+ uses interface-common-grouping;
+ uses interface-pointtopoint-grouping;
+ }
+
+ // interface Tunnel #
+ list Tunnel {
+ tailf:info "Tunnel interface";
+ description "Tunnel interface";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ tailf:cli-suppress-key-abbreviation;
+ key name;
+ leaf name {
+ type uint32 {
+ tailf:info "<0-2147483647>;;Tunnel interface number";
+ }
+ }
+ uses interface-common-grouping;
+
+ // interface Tunnel* / qos
+ container qos {
+ tailf:info "Quality of Service related commands";
+ description "Quality of Service related commands";
+ leaf pre-classify {
+ tailf:info "Enable QOS classification before packets are tunnel "+
+ "encapsulated";
+ description "Enable QOS classification before packets are tunnel "+
+ "encapsulated";
+ type empty;
+ }
+ }
+
+ // interface Tunnel* / tunnel
+ uses interface-tunnel-grouping;
+ }
+
+ // interface Virtual-Template
+ list Virtual-Template {
+ tailf:info "Virtual Template interface";
+ description "Virtual Template interface";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ tailf:cli-full-command;
+ tailf:cli-explicit-exit;
+ key name;
+ leaf name {
+ type uint16 {
+ tailf:info "<1-4095>;;Virtual-Template interface number";
+ range "1..4095";
+ }
+ }
+ leaf type {
+ tailf:info "type of the virtual-template";
+ description "type of the virtual-template";
+ tailf:cli-hide-in-submode;
+ type enumeration {
+ enum ethernet {
+ tailf:info "Set VT type as ethernet";
+ }
+ enum serial {
+ tailf:info "Set VT type as serial";
+ }
+ enum tunnel {
+ tailf:info "Set VT type as tunnel";
+ }
+ enum vpn {
+ tailf:info "Set VT type as vpn";
+ }
+ }
+ }
+
+ uses interface-ethernet-grouping;
+ uses interface-common-grouping;
+ uses interface-zone-member-grouping;
+ uses interface-switch-grouping; //CATALYST
+ uses interface-pointtopoint-grouping;
+ // interface Tunnel* / tunnel
+ uses interface-tunnel-grouping;
+ }
+
+ // interface VirtualPortGroup
+ list VirtualPortGroup {
+ tailf:info "Virtual Port Group";
+ description "Virtual Port Group";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ tailf:cli-full-command;
+ tailf:cli-explicit-exit;
+ key name;
+ leaf name {
+ type uint16 {
+ tailf:info " <0-31>;;VirtualPortGroup interface number";
+ range "0..31";
+ }
+ }
+ uses interface-switch-grouping; //CATALYST
+ uses interface-ethernet-grouping;
+ uses interface-common-grouping;
+ }
+ // interface vasileft
+ list vasileft {
+ tailf:info "vasileft";
+ description "vasileft";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ tailf:cli-full-command;
+ tailf:cli-explicit-exit;
+ key name;
+ leaf name {
+ type uint16 {
+ tailf:info "<1-2000>;;vasileft interface number";
+ range "1..2000";
+ }
+ }
+ uses interface-switch-grouping; //CATALYST
+ uses interface-ethernet-grouping;
+ uses interface-common-grouping;
+ }
+
+ // interface vasiright
+ list vasiright {
+ tailf:info "vasiright";
+ description "vasiright";
+ tailf:cli-allow-join-with-key {
+ tailf:cli-display-joined;
+ }
+ tailf:cli-mode-name "config-if";
+ tailf:cli-full-command;
+ tailf:cli-explicit-exit;
+ key name;
+ leaf name {
+ type uint16 {
+ tailf:info "<1-2000>;;vasiright interface number";
+ range "1..2000";
+ }
+ }
+ uses interface-switch-grouping; //CATALYST
+ uses interface-ethernet-grouping;
+ uses interface-common-grouping;
+ }
+ }
+
+
/// ========================================================================
/// mls
/// ========================================================================
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.cache.DSTreeBasedCache;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.cache.EpPolicyTemplateCacheKey;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicy;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicyBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
/**
private static final RendererName RENDERER_NAME = new RendererName("renderer1");
private final RendererPolicy policy1;
+ private final RendererPolicy policy2;
@Mock
private DataBroker dataBroker;
@Mock
- private DSTreeBasedCache<EndpointPolicyTemplateBySgt, EpPolicyTemplateCacheKey, Sgt> cache;
+ private PolicyManagerImpl policyManager;
@Mock
private ListenerRegistration<RendererConfigurationListenerImpl> listenerRegistration;
@Mock
public RendererConfigurationListenerImplTest() {
policy1 = new RendererPolicyBuilder().build();
+ policy2 = new RendererPolicyBuilder().build();
}
@Before
Matchers.<DataTreeIdentifier<RendererPolicy>>any(),
Matchers.<RendererConfigurationListenerImpl>any()))
.thenReturn(listenerRegistration);
- listener = new RendererConfigurationListenerImpl(dataBroker, RENDERER_NAME, cache);
+ listener = new RendererConfigurationListenerImpl(dataBroker, RENDERER_NAME, policyManager);
}
@After
@Test
public void testOnDataTreeChanged_add() throws Exception {
Mockito.when(rootNode.getDataAfter()).thenReturn(policy1);
+ Mockito.when(rootNode.getDataBefore()).thenReturn(policy2);
Mockito.when(rootNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);
Mockito.when(dataTreeModification.getRootNode()).thenReturn(rootNode);
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+ ~ Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.\r
+ ~\r
+ ~ This program and the accompanying materials are made available under the\r
+ ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ ~ and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ -->\r
+\r
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">\r
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">\r
+\r
+ <appender name="console" class="org.apache.log4j.ConsoleAppender">\r
+ <layout class="org.apache.log4j.PatternLayout">\r
+ <param name="ConversionPattern" value="%-6p %d{HH:mm:ss.SSS} [%10.10t] %30.30c %x - %m%n"/>\r
+ </layout>\r
+ <!-- <param name="Threshold" value="DEBUG" /> -->\r
+ </appender>\r
+\r
+ <logger name="org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider" additivity="false">\r
+ <level value="DEBUG"/>\r
+ <appender-ref ref="console"/>\r
+ </logger>\r
+\r
+ <logger name="org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerZipImpl" additivity="false">\r
+ <level value="TRACE"/>\r
+ <appender-ref ref="console"/>\r
+ </logger>\r
+\r
+ <root>\r
+ <priority value="INFO"/>\r
+ <appender-ref ref="console"/>\r
+ </root>\r
+</log4j:configuration>\r
<ovsdb.version>1.3.0-SNAPSHOT</ovsdb.version>
<openflowplugin.version>0.3.0-SNAPSHOT</openflowplugin.version>
<liblldp.version>0.11.0-SNAPSHOT</liblldp.version>
- <sfc.version>0.3.0-SNAPSHOT</sfc.version>
</properties>
<dependencies>
<dependency>
<groupId>org.opendaylight.sfc</groupId>
<artifactId>sfc-provider</artifactId>
- <version>${sfc.version}</version>
</dependency>
<!-- testing dependencies -->
<dependency>
<version>0.4.0-SNAPSHOT</version>
<packaging>pom</packaging>
+ <properties>
+ <sfc.version>0.3.0-SNAPSHOT</sfc.version>
+ </properties>
+
+
<modules>
<module>ofoverlay</module>
<module>faas</module>
<scope>import</scope>
<type>pom</type>
</dependency>
+
+ <!-- sfc -->
+ <dependency>
+ <groupId>org.opendaylight.sfc</groupId>
+ <artifactId>sfc-provider</artifactId>
+ <version>${sfc.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.sfc</groupId>
+ <artifactId>sfc-model</artifactId>
+ <version>${sfc.version}</version>
+ </dependency>
</dependencies>
</dependencyManagement>