Addition of module - cisco-xe-driver. 78/52378/8
authorMarek Ryznar <marek.ryznar@amartus.com>
Tue, 14 Feb 2017 09:28:44 +0000 (10:28 +0100)
committerDonald Hunter <donaldh@cisco.com>
Mon, 13 Mar 2017 15:19:58 +0000 (15:19 +0000)
The cisco-xe-driver is responsible for creating forwarding constructs
in cisco devices with IOS XE Operating System.

Developer's Certificate of Origin 1.1

        By making a contribution to this project, I certify that:

        (a) The contribution was created in whole or in part by me and I
            have the right to submit it under the open source license
            indicated in the file; or

        (b) The contribution is based upon previous work that, to the best
            of my knowledge, is covered under an appropriate open source
            license and I have the right under that license to submit that
            work with modifications, whether created in whole or in part
            by me, under the same open source license (unless I am
            permitted to submit under a different license), as indicated
            in the file; or

        (c) The contribution was provided directly to me by some other
            person who certified (a), (b) or (c) and I have not modified
            it.

        (d) I understand and agree that this project and the contribution
            are public and that a record of the contribution (including all
            personal information I submit with it, including my sign-off) is
            maintained indefinitely and may be redistributed consistent with
            this project or the open source license(s) involved.

Change-Id: I290c14046969dfa3f2b597a78376a4368da50045
Signed-off-by: Marek Ryznar <marek.ryznar@amartus.com>
Signed-off-by: Donald Hunter <donaldh@cisco.com>
22 files changed:
artifacts/pom.xml
cisco-xe-driver/pom.xml [new file with mode: 0644]
cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/CiscoExecutor.java [new file with mode: 0644]
cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/CiscoRestRunner.java [new file with mode: 0644]
cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/core/CiscoRestExecutor.java [new file with mode: 0644]
cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/core/ClientProvider.java [new file with mode: 0644]
cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/core/RestExecutor.java [new file with mode: 0644]
cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/core/TargetProvider.java [new file with mode: 0644]
cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/response/AuthResponse.java [new file with mode: 0644]
cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/activator/P2pConnectionActivator.java [new file with mode: 0644]
cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/driver/P2pConnectionDriverBuilder.java [new file with mode: 0644]
cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/util/CliGeneratorUtil.java [new file with mode: 0644]
cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/util/IpAddressLoopbackNotFoundException.java [new file with mode: 0644]
cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/util/RunningConfig.java [new file with mode: 0644]
cisco-xe-driver/src/main/resources/org/opendaylight/blueprint/cisco-xe-driver.xml [new file with mode: 0644]
cisco-xe-driver/src/main/resources/org/opendaylight/unimgr/mef/nrp/cisco/xe/util/createServiceInstance.mustache [new file with mode: 0644]
cisco-xe-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/util/CliGeneratorUtilTest.java [new file with mode: 0644]
cisco-xe-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/util/RunningConfigTest.java [new file with mode: 0644]
features/pom.xml
features/src/main/features/features.xml
pom.xml
presto-api/src/main/yang/mef-unimgr-ext.yang

index b24a6c8513fc56edf09d045a38f0f084a26d6432..e9d9c5a34d026e3752fad49ed5e863f1c4e846b4 100644 (file)
@@ -42,6 +42,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
         <artifactId>unimgr-cisco-xr-driver</artifactId>
         <version>${project.version}</version>
       </dependency>
+      <dependency>
+        <groupId>${project.groupId}</groupId>
+        <artifactId>unimgr-cisco-xe-driver</artifactId>
+        <version>${project.version}</version>
+      </dependency>
       <dependency>
         <groupId>${project.groupId}</groupId>
         <artifactId>ovs-driver</artifactId>
diff --git a/cisco-xe-driver/pom.xml b/cisco-xe-driver/pom.xml
new file mode 100644 (file)
index 0000000..fa11740
--- /dev/null
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2015 Cisco Systems, Inc. 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 INTERNAL
+-->
+<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">
+
+    <parent>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>config-parent</artifactId>
+        <version>0.6.0-SNAPSHOT</version>
+        <relativePath />
+    </parent>
+
+    <properties>
+        <checkstyle.skip>true</checkstyle.skip>
+        <powermock.version>1.6.4</powermock.version>
+        <org.springframework.boot.version>1.4.1.RELEASE</org.springframework.boot.version>
+        <jboss.resteasy.version>3.0.19.Final</jboss.resteasy.version>
+        <com.github.spullara.mustache.java.version>0.9.4</com.github.spullara.mustache.java.version>
+    </properties>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.opendaylight.unimgr</groupId>
+    <artifactId>unimgr-cisco-xe-driver</artifactId>
+    <version>0.2.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Embed-Dependency>*;artifactId=compiler</Embed-Dependency>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>unimgr-impl</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.spullara.mustache.java</groupId>
+            <artifactId>mustache.java</artifactId>
+            <version>${com.github.spullara.mustache.java.version}</version>
+            <type>pom</type>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>unimgr-impl</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+
+        <!-- dependencies to use AbstractDataBrokerTest -->
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-broker-impl</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>
+
+        <!-- dependencies to use mustache.java project for CLI generation -->
+        <dependency>
+            <groupId>com.github.spullara.mustache.java</groupId>
+            <artifactId>compiler</artifactId>
+            <version>${com.github.spullara.mustache.java.version}</version>
+        </dependency>
+
+        <!-- Testing Dependencies -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-module-junit4</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-api-mockito</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-api-support</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-reflect</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal.model</groupId>
+            <artifactId>ietf-yang-types-20130715</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+        </dependency>
+        <!-- For REST -->
+        <dependency>
+            <groupId>com.eclipsesource.jaxrs</groupId>
+            <artifactId>jersey-all</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/CiscoExecutor.java b/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/CiscoExecutor.java
new file mode 100644 (file)
index 0000000..595a748
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * 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.unimgr.mef.nrp.cisco.rest;
+
+public interface CiscoExecutor {
+
+       String getRunningConfig() throws Exception;
+       void setRunningConfig(String runningConfig) throws Exception;
+}
diff --git a/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/CiscoRestRunner.java b/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/CiscoRestRunner.java
new file mode 100644 (file)
index 0000000..7f9d0eb
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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.unimgr.mef.nrp.cisco.rest;
+
+import java.net.InetAddress;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.Response;
+
+import org.opendaylight.unimgr.mef.nrp.cisco.rest.core.CiscoRestExecutor;
+import org.opendaylight.unimgr.mef.nrp.cisco.rest.core.RestExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CiscoRestRunner implements CiscoExecutor{
+
+       private static final Logger LOGGER = LoggerFactory.getLogger(CiscoRestRunner.class);
+
+       private InetAddress destination;
+       private String userName;
+       private String password;
+
+       public CiscoRestRunner(InetAddress destination, String userName, String password) {
+               this.destination = destination;
+               this.userName = userName;
+               this.password = password;
+       }
+
+       @Override
+       public String getRunningConfig() throws Exception{
+               LOGGER.info("Getting running config for Cisco: " + destination);
+
+               try(RestExecutor restExecutor = new CiscoRestExecutor(destination, userName, password)) {
+                       restExecutor.setUpConnection();
+
+                       WebTarget target = restExecutor.getWebTarget();
+                       Response response = target.path("global/running-config").request().get();
+                       String runningConfig = response.readEntity(String.class);
+
+                       if(response.getStatus() != 200){
+                               String responseString = response.readEntity(String.class);
+                               LOGGER.warn("Problem with getting running config for " + destination + ". Response is:\n" + responseString);
+                               throw new Exception("Problem with getting running config for " + destination + ". Response is:\n" + responseString);
+                       } else {
+                               LOGGER.info("Successfully got running config for Cisco " + destination);
+                       }
+
+                       return runningConfig;
+               } catch(Exception e){
+                       LOGGER.error("Cannot get running config for " + destination, e);
+                       throw e;
+               }
+       }
+
+       @Override
+       public void setRunningConfig(String runningConfig) throws Exception{
+               LOGGER.info("Setting running config for Cisco: " + destination);
+               LOGGER.debug("Running connfig: " + runningConfig);
+
+               Response response;
+
+               try(RestExecutor restExecutor = new CiscoRestExecutor(destination, userName, password)) {
+                       restExecutor.setUpConnection();
+                       response = restExecutor.getWebTarget().path("global/running-config").request().put(Entity.text(runningConfig));
+               } catch(Exception e){
+                       LOGGER.error("Cannot set running config for " + destination, e);
+                       throw e;
+               }
+
+               if(response.getStatus() != 200 && response.getStatus() != 204){
+                       //Sth went wrong on device
+                       String responseString = response.readEntity(String.class);
+                       LOGGER.warn("Problem with setting running config for " + destination + ". Commands are:\n" + runningConfig + "\nResponse is:\n" + responseString);
+                       throw new Exception("Problem with setting running config for " + destination + ". Commands are:\n" + runningConfig + "\nResponse is:\n" + responseString);
+               } else {
+                       LOGGER.info("Successfully set running config for Cisco " + destination);
+               }
+       }
+
+}
diff --git a/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/core/CiscoRestExecutor.java b/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/core/CiscoRestExecutor.java
new file mode 100644 (file)
index 0000000..cb1ef91
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * 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.unimgr.mef.nrp.cisco.rest.core;
+
+import java.io.IOException;
+import java.net.InetAddress;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.opendaylight.unimgr.mef.nrp.cisco.rest.response.AuthResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class CiscoRestExecutor implements RestExecutor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(CiscoRestExecutor.class);
+    private static final String AUTH_TOKEN_SERVICES = "auth/token-services";
+
+    private AuthResponse authResponse;
+    private ClientProvider clientProvider;
+
+    private final InetAddress destination;
+    private final String userName;
+    private final String password;
+
+    public CiscoRestExecutor(InetAddress destination, String userName, String password) {
+        this.destination = destination;
+        this.userName = userName;
+        this.password = password;
+    }
+
+    @Override
+    public void setUpConnection(){
+        LOGGER.info("Setting up a REST connection to Cisco: " + destination);
+
+        clientProvider = new ClientProvider.DefaultClientProvider();
+
+        TargetProvider defaultTargetProvider = new TargetProvider.DefaultTargetProvider(clientProvider, destination);
+        TargetProvider basicAuthTargetProvider = new TargetProvider.BasicAuthTargetProvider(defaultTargetProvider, userName, password);
+
+        WebTarget target = basicAuthTargetProvider.get().path(AUTH_TOKEN_SERVICES);
+        Response post = target.request(MediaType.APPLICATION_JSON_TYPE).post(Entity.text(""));
+
+        String responseString = post.readEntity(String.class);
+        authResponse = mapToObject(responseString, AuthResponse.class);
+
+        LOGGER.info("REST Connection successfully set up for Cisco: " + destination);
+    }
+
+    @Override
+    public WebTarget getWebTarget() {
+        checkPreconditions();
+
+        TargetProvider targetProvider = new TargetProvider.DefaultTargetProvider(clientProvider, destination);
+        return new TargetProvider.XauthTargetProvider(targetProvider, authResponse.getTokenId()).get();
+    }
+
+    @Override
+    public void close() throws IOException {
+        LOGGER.info("Closing connection for Cisco: " + destination);
+        if(clientProvider!=null){
+            clientProvider.get().close();
+        }
+        clientProvider = null;
+        authResponse = null;
+        LOGGER.info("Successfully closed connection for Cisco: " + destination);
+    }
+
+    private <T> T mapToObject(String input, Class<T> result){
+        ObjectMapper mapper = new ObjectMapper();
+        try {
+            return mapper.readValue(input, result);
+        } catch (IOException e) {
+            throw new RuntimeException("Cannot map input " + input + " to class " + result, e);
+        }
+    }
+
+    private void checkPreconditions(){
+        if(!isConnectionSetUp()){
+            LOGGER.error("Connection is not set up for " + destination);
+            throw new RuntimeException("Connection is not set up for " + destination);
+        }
+    }
+
+    private boolean isConnectionSetUp(){
+        if(authResponse != null) {
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/core/ClientProvider.java b/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/core/ClientProvider.java
new file mode 100644 (file)
index 0000000..ebc3c3c
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * 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.unimgr.mef.nrp.cisco.rest.core;
+
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public interface ClientProvider {
+
+    Client get();
+
+    public static class DefaultClientProvider implements ClientProvider {
+        private static final String SECURE_PROTOCOL_INSTANCE = "TLS";
+
+        private Client client;
+
+        public DefaultClientProvider() {
+            client = buildClient();
+        }
+
+        @Override
+        public Client get() {
+            return client;
+        };
+
+        public Client buildClient()  {
+            return ClientBuilder.newBuilder().sslContext(SslContextProvider.INSTANCE.get()).hostnameVerifier((s1, s2) -> true).build();
+        }
+
+
+        static class EmptyTrustManager implements X509TrustManager {
+            @Override
+            public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
+            }
+            @Override
+            public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
+            }
+            @Override
+            public X509Certificate[] getAcceptedIssuers() {
+                return new X509Certificate[0];
+            }
+        }
+
+        enum SslContextProvider {
+            INSTANCE;
+
+            private static final Logger LOGGER = LoggerFactory.getLogger(SslContextProvider.class);
+
+            private SSLContext sslContext = initSslContext();
+
+            SSLContext get() {
+                if(sslContext == null) {
+                    throw new RuntimeException("SSL Context not initializated", new Throwable());
+                }
+                return sslContext;
+            }
+
+            private static SSLContext initSslContext() {
+                SSLContext sslcontext = null;
+                try {
+                    sslcontext = SSLContext.getInstance(SECURE_PROTOCOL_INSTANCE);
+                    sslcontext.init(null, new TrustManager[] { new EmptyTrustManager() }, new java.security.SecureRandom());
+                    return sslcontext;
+                } catch (KeyManagementException | NoSuchAlgorithmException e) {
+                    LOGGER.error("Cannot initialize SSL Context", e);
+                }
+                return sslcontext;
+            }
+        }
+    }
+}
diff --git a/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/core/RestExecutor.java b/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/core/RestExecutor.java
new file mode 100644 (file)
index 0000000..00089ac
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * 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.unimgr.mef.nrp.cisco.rest.core;
+
+import java.io.Closeable;
+
+import javax.ws.rs.client.WebTarget;
+
+public interface RestExecutor extends Closeable{
+
+    void setUpConnection();
+    WebTarget getWebTarget();
+}
diff --git a/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/core/TargetProvider.java b/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/core/TargetProvider.java
new file mode 100644 (file)
index 0000000..98daed6
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * 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.unimgr.mef.nrp.cisco.rest.core;
+
+import java.io.IOException;
+import java.net.InetAddress;
+
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientRequestFilter;
+import javax.ws.rs.client.WebTarget;
+
+import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
+
+public interface TargetProvider {
+
+    WebTarget get();
+
+    public static class DefaultTargetProvider implements TargetProvider {
+        private ClientProvider clientProvider;
+        private InetAddress destination;
+
+        public DefaultTargetProvider(ClientProvider clientProvider,  InetAddress destination) {
+            this.clientProvider = clientProvider;
+            this.destination = destination;
+        }
+
+        @Override
+        public WebTarget get() {
+            WebTarget target = clientProvider.get().target(buildUriString());
+            return target;
+        }
+
+        private String buildUriString(){
+            return new StringBuilder().append("https://").append(destination.getHostAddress()).append("/api/v1").toString();
+        }
+    }
+
+    public static class BasicAuthTargetProvider implements TargetProvider {
+        private TargetProvider targerProvider;
+        private String userName;
+        private String password;
+
+        public BasicAuthTargetProvider(TargetProvider targerProvider, String userName, String password) {
+            this.targerProvider = targerProvider;
+            this.userName = userName;
+            this.password = password;
+        }
+
+        @Override
+        public WebTarget get() {
+            WebTarget target = targerProvider.get();
+            target.register(HttpAuthenticationFeature.basic(userName, password));
+            return target;
+        }
+    }
+
+    public static class XauthTargetProvider implements TargetProvider {
+        private TargetProvider targerProvider;
+        private String tokenId;
+
+        public XauthTargetProvider(TargetProvider targerProvider, String tokenId) {
+            this.targerProvider = targerProvider;
+            this.tokenId = tokenId;
+        }
+
+        @Override
+        public WebTarget get() {
+            WebTarget target = targerProvider.get();
+            target.register(new AuthRequestFilter(tokenId));
+            return target;
+        }
+
+
+        private static class AuthRequestFilter implements ClientRequestFilter {
+
+            private String tokenId;
+
+            public AuthRequestFilter(String tokenId) {
+                this.tokenId = tokenId;
+            }
+
+            @Override
+            public void filter(ClientRequestContext requestContext) throws IOException {
+                requestContext.getHeaders().add("X-Auth-Token", tokenId);
+
+            }
+        }
+    }
+}
diff --git a/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/response/AuthResponse.java b/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/rest/response/AuthResponse.java
new file mode 100644 (file)
index 0000000..80d8be0
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * 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.unimgr.mef.nrp.cisco.rest.response;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown=true)
+public class AuthResponse {
+
+       @JsonProperty("token-id")
+       private String tokenId;
+
+       public String getTokenId() {
+               return tokenId;
+       }
+
+}
diff --git a/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/activator/P2pConnectionActivator.java b/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/activator/P2pConnectionActivator.java
new file mode 100644 (file)
index 0000000..7bfddd4
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * 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.unimgr.mef.nrp.cisco.xe.activator;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.unimgr.mef.nrp.cisco.rest.CiscoExecutor;
+import org.opendaylight.unimgr.mef.nrp.cisco.rest.CiscoRestRunner;
+import org.opendaylight.unimgr.mef.nrp.cisco.xe.util.CliGeneratorUtil;
+import org.opendaylight.unimgr.mef.nrp.cisco.xe.util.IpAddressLoopbackNotFoundException;
+import org.opendaylight.unimgr.mef.nrp.cisco.xe.util.RunningConfig;
+import org.opendaylight.unimgr.mef.nrp.common.ResourceActivator;
+import org.opendaylight.unimgr.mef.nrp.common.ResourceActivatorException;
+import org.opendaylight.unimgr.mef.nrp.common.ResourceNotAvailableException;
+import org.opendaylight.unimgr.utils.MdsalUtils;
+import org.opendaylight.yang.gen.v1.urn.mef.unimgr.ext.rev160725.CTagVlanId;
+import org.opendaylight.yang.gen.v1.urn.mef.unimgr.ext.rev160725.FcPort1;
+import org.opendaylight.yang.gen.v1.urn.mef.unimgr.ext.rev160725.Node1;
+import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort;
+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;
+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.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Set;
+
+public class P2pConnectionActivator implements ResourceActivator {
+
+    private static final Logger LOG = LoggerFactory.getLogger(P2pConnectionActivator.class);
+
+    private DataBroker dataBroker;
+
+    public P2pConnectionActivator(DataBroker dataBroker) {
+        this.dataBroker = dataBroker;
+    }
+
+    @Override
+    public void activate(String nodeName, String outerName, String innerName, FcPort portA, FcPort portZ, long mtu) throws TransactionCommitFailedException, ResourceActivatorException {
+        LOG.info("Activate\nPort A: " + portA + "\nPort Z: " + portZ);
+
+        checkPreconditions(portA, portZ);
+
+        Node1 node1A = getNode1augmentation(getNode(portA));
+        Node1 node1Z = getNode1augmentation(getNode(portZ));
+
+        CiscoExecutor restExecutorA = createCiscoExecutor(node1A);
+       CiscoExecutor restExecutorZ = createCiscoExecutor(node1Z);
+
+        RunningConfig configA = new RunningConfig(getRunningConfig(restExecutorA));
+        RunningConfig configZ = new RunningConfig(getRunningConfig(restExecutorZ));
+
+        int vcId = getVcId(configA, configZ);
+
+        LOG.info("Activating A side");
+        activateSide(portA, vcId, restExecutorA, configZ);
+
+        LOG.info("Activating Z side");
+        activateSide(portZ, vcId, restExecutorZ, configA);
+
+        LOG.info("Activation finished");
+    }
+
+    @Override
+    public void deactivate(String nodeName, String outerName, String innerName, FcPort portA, FcPort portZ, long mtu)
+               throws TransactionCommitFailedException, ResourceActivatorException {
+       LOG.info("Deactivate\nPort A: " + portA + "\nPort Z: " + portZ);
+
+        checkPreconditions(portA, portZ);
+
+        LOG.info("Deactivating A side");
+        deactivateSide(portA);
+
+        LOG.info("Deactivating Z side");
+        deactivateSide(portZ);
+
+        LOG.info("Deactivation finished");
+    }
+
+    private void checkPreconditions(FcPort portA, FcPort portZ) throws ResourceActivatorException {
+       checkPreconditionsForPort(portA);
+       checkPreconditionsForPort(portZ);
+    }
+
+    private void checkPreconditionsForPort(FcPort port) throws ResourceActivatorException{
+       if(port.getAugmentation(FcPort1.class) == null) {
+               throw new ResourceActivatorException("VLan parameter has to be specified for port: " + port);
+       }
+    }
+
+    private int getVcId(RunningConfig configA, RunningConfig configZ){
+       Set<Integer> usedVcIds = configA.getUsedVcIdValues();
+        usedVcIds.addAll(configZ.getUsedVcIdValues());
+        int vcId = CliGeneratorUtil.generateVcId(usedVcIds);
+        return vcId;
+    }
+
+    private void activateSide(FcPort port, int vcId, CiscoExecutor ciscoExecutor, RunningConfig oppositeSideRunningConfig) throws ResourceActivatorException{
+        String commands = generateCliCommands(port, oppositeSideRunningConfig, vcId);
+        setRunningConfig(ciscoExecutor, commands);
+    }
+
+    private void deactivateSide(FcPort port) throws ResourceActivatorException{
+       Node1 node1 = getNode1augmentation(getNode(port));
+        CiscoExecutor restExecutor = createCiscoExecutor(node1);
+        String commands = generateCliNoCommands(port);
+        setRunningConfig(restExecutor, commands);
+    }
+
+    private Node getNode(FcPort port) throws ResourceNotAvailableException {
+
+        InstanceIdentifier<Node> nodeIid = InstanceIdentifier.builder(NetworkTopology.class)
+                .child(Topology.class, new TopologyKey(port.getTopology()))
+                .child(Node.class, new NodeKey(port.getNode()))
+                .build();
+
+        Optional<Node> result = MdsalUtils.readOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, nodeIid);
+
+        if (result.isPresent()) {
+            return result.get();
+        } else {
+            LOG.error("Node " + nodeIid + " does not exists");
+            throw new ResourceNotAvailableException("Node " + nodeIid + " does not exists");
+        }
+    }
+
+    private CiscoExecutor createCiscoExecutor(Node1 node) throws ResourceActivatorException{
+       try {
+                       return new CiscoRestRunner(
+                                       InetAddress.getByName(new String(node.getConnectionSettings().getHost().getIpAddress().getValue())),
+                                       node.getConnectionSettings().getUserName(),
+                                       node.getConnectionSettings().getPassword());
+               } catch (UnknownHostException e) {
+                       LOG.error("Host name cannot be resolved for: " + node.getConnectionSettings().getHost().toString());
+                       throw new ResourceActivatorException("Host name cannot be resolved for: " + node.getConnectionSettings().getHost().toString(),e);
+               }
+    }
+
+    private Node1 getNode1augmentation(Node node) throws ResourceActivatorException {
+       Node1 node1 = node.getAugmentation(Node1.class);
+        if (node1 == null) {
+            LOG.error("Connection settings can not be obtained from node :" + node);
+            throw new ResourceActivatorException("Connection settings can not be obtained from node :" + node);
+        }
+        return node1;
+    }
+
+    private String getRunningConfig(CiscoExecutor executor) throws ResourceActivatorException{
+       try {
+                       return executor.getRunningConfig();
+               } catch (Exception e) {
+                       throw new ResourceActivatorException(e.getMessage(), e);
+               }
+    }
+
+    private void setRunningConfig(CiscoExecutor executor, String runningConfig) throws ResourceActivatorException{
+       try {
+               executor.setRunningConfig(runningConfig);
+       } catch (Exception e) {
+               throw new ResourceActivatorException(e.getMessage(), e);
+       }
+    }
+
+    private String generateCliCommands(FcPort port, RunningConfig oppsiteSideConfig, int vcId) throws ResourceActivatorException{
+       CTagVlanId cTagVlanId = port.getAugmentation(FcPort1.class).getCTagVlanId();
+       try {
+                       String commands = CliGeneratorUtil.generateServiceCommands(
+                                port.getTp().getValue(),
+                                cTagVlanId.getValue().shortValue(),
+                                cTagVlanId.getValue().shortValue(),
+                                oppsiteSideConfig.getIpAddressLoopback0(),
+                                vcId);
+                       LOG.info("Generated commands:\n" + commands);
+                       return commands;
+               } catch (IOException e) {
+                       throw new ResourceActivatorException("Cannot generate commands for port: " + port, e);
+               } catch (IpAddressLoopbackNotFoundException e) {
+                       LOG.error("Problem with getting loopback address for port: " + port, e);
+                       throw e;
+               }
+    }
+
+    private String generateCliNoCommands(FcPort port) {
+       CTagVlanId cTagVlanId = port.getAugmentation(FcPort1.class).getCTagVlanId();
+       String commands = CliGeneratorUtil.generateNoServiceCommands(
+                port.getTp().getValue(),
+                cTagVlanId.getValue().shortValue());
+       LOG.debug("Generated commands:\nPort: " + port + "\nCommands: \n" + commands);
+       return commands;
+    }
+}
diff --git a/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/driver/P2pConnectionDriverBuilder.java b/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/driver/P2pConnectionDriverBuilder.java
new file mode 100644 (file)
index 0000000..09d1ece
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 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.unimgr.mef.nrp.cisco.xe.driver;
+
+
+import java.util.Optional;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.unimgr.mef.nrp.api.ActivationDriver;
+import org.opendaylight.unimgr.mef.nrp.api.ActivationDriverBuilder;
+import org.opendaylight.unimgr.mef.nrp.cisco.xe.activator.P2pConnectionActivator;
+import org.opendaylight.unimgr.mef.nrp.common.ResourceActivatorException;
+import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.forwarding.constructs.ForwardingConstruct;
+import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class P2pConnectionDriverBuilder implements ActivationDriverBuilder {
+
+    private static final Logger LOG = LoggerFactory.getLogger(P2pConnectionDriverBuilder.class);
+
+    private static final String GROUP_NAME = "local";
+    private static final String XE_TOPOLOGY_ID = "topology-cisco-xe";
+    private P2pConnectionActivator activator;
+
+
+
+    public P2pConnectionDriverBuilder(DataBroker dataBroker) {
+        activator = new P2pConnectionActivator(dataBroker);
+    }
+
+    @Override
+    public Optional<ActivationDriver> driverFor(FcPort port, BuilderContext _ctx) {
+        //TODO: use SBI API to check connectivity
+       if(XE_TOPOLOGY_ID.equals(port.getTopology().getValue())){
+            return Optional.of(getDriver());
+       }
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<ActivationDriver> driverFor(FcPort aPort, FcPort zPort, BuilderContext context) {
+        //TODO: use SBI API to check connectivity
+        if(XE_TOPOLOGY_ID.equals(aPort.getTopology().getValue()) && XE_TOPOLOGY_ID.equals(zPort.getTopology().getValue())){
+            return Optional.of(getDriver());
+        }
+        return Optional.empty();
+    }
+
+    protected ActivationDriver getDriver() {
+        final ActivationDriver driver = new ActivationDriver() {
+            public FcPort aEnd;
+            public FcPort zEnd;
+
+            @Override
+            public void commit() {
+                //ignore for the moment
+            }
+
+            @Override
+            public void rollback() {
+                //ignore for the moment
+            }
+
+            @Override
+            public void initialize(FcPort from, FcPort to, ForwardingConstruct ctx) {
+                this.zEnd = to;
+                this.aEnd = from;
+            }
+
+            @Override
+            public void activate() throws TransactionCommitFailedException, ResourceActivatorException {
+                String aEndNodeName = aEnd.getNode().getValue();
+                activator.activate(aEndNodeName, GROUP_NAME, GROUP_NAME, aEnd, zEnd, 1522);
+            }
+
+            @Override
+            public void deactivate() throws TransactionCommitFailedException, ResourceActivatorException {
+
+                String aEndNodeName = aEnd.getNode().getValue();
+                activator.deactivate(aEndNodeName, GROUP_NAME, GROUP_NAME, aEnd, zEnd, 1522);
+            }
+
+            @Override
+            public int priority() {
+                return 0;
+            }
+        };
+
+        return driver;
+    }
+}
diff --git a/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/util/CliGeneratorUtil.java b/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/util/CliGeneratorUtil.java
new file mode 100644 (file)
index 0000000..0357f86
--- /dev/null
@@ -0,0 +1,71 @@
+package org.opendaylight.unimgr.mef.nrp.cisco.xe.util;
+
+/*
+ * 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
+ */
+
+import com.github.mustachejava.DefaultMustacheFactory;
+import com.github.mustachejava.Mustache;
+import com.github.mustachejava.MustacheFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.Random;
+import java.util.Set;
+
+public class CliGeneratorUtil {
+    private static final Logger LOG = LoggerFactory.getLogger(CliGeneratorUtil.class);
+
+    public static String generateServiceCommands(String interfaceName, short serviceInstanceId, short cTagVlanId, String ipAddressOfPeer, int vcIdValue) throws IOException {
+        StringWriter writer = new StringWriter();
+
+        MustacheFactory mf = new DefaultMustacheFactory(CliGeneratorUtil.class.getPackage().getName().replaceAll("\\.","/"));
+
+        Mustache mustache = mf.compile("createServiceInstance.mustache");
+
+        LOG.debug("Compiled mustache "+mustache);
+
+        mustache.execute(writer, new ServiceInstance(interfaceName, serviceInstanceId, cTagVlanId,ipAddressOfPeer,vcIdValue)).flush();
+        return writer.toString();
+    }
+
+    public static String generateNoServiceCommands(String interfaceName, short serviceInstanceId){
+        StringBuilder sb = new StringBuilder();
+        sb.append("interface ").
+                append(interfaceName).
+                append("\n no service instance ").
+                append(serviceInstanceId).
+                append(" ethernet");
+
+        return sb.toString();
+    }
+
+    public static int generateVcId(Set<Integer> idsInUse){
+        Random random = new Random();
+        int vcId;
+        do {
+            vcId = Math.abs(random.nextInt())+1;  // <1-4294967295>  possible VC ID value in command line while MAX int is 2147483647 . +1 to avoid 0
+        }while (idsInUse.contains(new Integer(vcId)));
+
+        return vcId;
+    }
+    private static class ServiceInstance {
+        ServiceInstance(String interfaceName, short serviceInstanceId, short cTagVlanId, String ipAddressOfPeer, int vcIdValue) {
+            this.interfaceName = interfaceName;
+            this.serviceInstanceId = serviceInstanceId;
+            this.cTagVlanId = cTagVlanId;
+            this.ipAddressOfPeer = ipAddressOfPeer;
+            this.vcIdValue = vcIdValue;
+        }
+
+        String interfaceName, ipAddressOfPeer;
+        short cTagVlanId, serviceInstanceId ;
+        int vcIdValue;
+    }
+}
diff --git a/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/util/IpAddressLoopbackNotFoundException.java b/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/util/IpAddressLoopbackNotFoundException.java
new file mode 100644 (file)
index 0000000..ffe1c89
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * 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.unimgr.mef.nrp.cisco.xe.util;
+
+import org.opendaylight.unimgr.mef.nrp.common.ResourceNotAvailableException;
+
+public class IpAddressLoopbackNotFoundException extends ResourceNotAvailableException {
+
+}
diff --git a/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/util/RunningConfig.java b/cisco-xe-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/util/RunningConfig.java
new file mode 100644 (file)
index 0000000..347210b
--- /dev/null
@@ -0,0 +1,52 @@
+package org.opendaylight.unimgr.mef.nrp.cisco.xe.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class RunningConfig {
+
+    private static final String IP_ADDRESS_LOOPBACK0_PATTERN = "interface Loopback0[\\n\\d]+ ip address (\\d+\\.\\d+\\.\\d+\\.\\d+) \\d+\\.\\d+\\.\\d+\\.\\d+";
+    private static final String VC_VALUE_PATTERN = "xconnect \\d+\\.\\d+\\.\\d+\\.\\d+ (\\d+) encapsulation mpls";
+    private static final Logger LOG = LoggerFactory.getLogger(RunningConfig.class);
+    private String config;
+
+
+    public RunningConfig (String config){
+        this.config = config;
+    }
+
+    public Set<Integer> getUsedVcIdValues(){
+
+        Set values = new HashSet();
+        Pattern p = Pattern.compile(VC_VALUE_PATTERN);
+        Matcher m = p.matcher(config);
+        while(m.find()) {
+            LOG.debug("found vc id value: " + m.group(1));
+            values.add(Integer.parseInt(m.group(1)));
+        }
+        LOG.debug("values : "+values);
+        return values;
+    }
+
+    public String getIpAddressLoopback0() throws IpAddressLoopbackNotFoundException {
+
+        Pattern p = Pattern.compile(IP_ADDRESS_LOOPBACK0_PATTERN);
+        Matcher m = p.matcher(config);
+        if(m.find()) {
+            LOG.debug("IpAddressLoopback0 : "+m.group(1));
+            return m.group(1);
+        }
+        LOG.error("Pattern "+p.toString()+" not found in running config :\n"+config);
+        throw new IpAddressLoopbackNotFoundException();
+    }
+
+    @Override
+    public String toString(){
+        return config;
+    }
+}
diff --git a/cisco-xe-driver/src/main/resources/org/opendaylight/blueprint/cisco-xe-driver.xml b/cisco-xe-driver/src/main/resources/org/opendaylight/blueprint/cisco-xe-driver.xml
new file mode 100644 (file)
index 0000000..9e76ddb
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2015 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 INTERNAL
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+  odl:use-default-for-reference-types="true">
+
+  <reference id="dataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker" />
+
+  <service id="ciscoIosXeP2pConnectionDriverService" interface="org.opendaylight.unimgr.mef.nrp.api.ActivationDriverBuilder">
+    <bean class="org.opendaylight.unimgr.mef.nrp.cisco.xe.driver.P2pConnectionDriverBuilder">
+      <argument ref="dataBroker" />
+    </bean>
+  </service>
+</blueprint>
diff --git a/cisco-xe-driver/src/main/resources/org/opendaylight/unimgr/mef/nrp/cisco/xe/util/createServiceInstance.mustache b/cisco-xe-driver/src/main/resources/org/opendaylight/unimgr/mef/nrp/cisco/xe/util/createServiceInstance.mustache
new file mode 100644 (file)
index 0000000..055c466
--- /dev/null
@@ -0,0 +1,9 @@
+interface {{interfaceName}}
+mtu 1522
+no ip address
+no service instance {{serviceInstanceId}} ethernet
+no shutdown
+service instance {{serviceInstanceId}} ethernet
+encapsulation dot1q {{cTagVlanId}}
+xconnect {{ipAddressOfPeer}} {{vcIdValue}} encapsulation mpls
+mtu 1508
\ No newline at end of file
diff --git a/cisco-xe-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/util/CliGeneratorUtilTest.java b/cisco-xe-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/util/CliGeneratorUtilTest.java
new file mode 100644 (file)
index 0000000..a4dad30
--- /dev/null
@@ -0,0 +1,47 @@
+package org.opendaylight.unimgr.mef.nrp.cisco.xe.util;
+
+/*
+ * 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
+ */
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.IOException;
+
+public class CliGeneratorUtilTest{
+
+    @Test
+    public void createServiceCommandsTest() {
+        StringBuffer expectedResult = new StringBuffer();
+        expectedResult
+                .append("interface GigabitEthernet4\n")
+                .append("mtu 1522\n")
+                .append("no ip address\n")
+                .append("no service instance 23 ethernet\n")
+                .append("no shutdown\n")
+                .append("service instance 23 ethernet\n")
+                .append("encapsulation dot1q 100\n")
+                .append("xconnect 3.3.3.3 3000 encapsulation mpls\n")
+                .append("mtu 1508");
+        try {
+            Assert.assertEquals(expectedResult.toString(),CliGeneratorUtil.generateServiceCommands("GigabitEthernet4", (short) 23, (short) 100,"3.3.3.3", 3000).replaceAll("\r\n","\n"));
+        } catch (IOException e) {
+            Assert.fail(e.toString());
+        }
+    }
+
+    @Test
+    public void createNoServiceCommandsTest() {
+        StringBuffer expectedResult = new StringBuffer();
+        expectedResult
+                .append("interface GigabitEthernet4\n")
+                .append(" no service instance 23 ethernet");
+        Assert.assertEquals(CliGeneratorUtil.generateNoServiceCommands("GigabitEthernet4", (short) 23),expectedResult.toString());
+    }
+
+}
diff --git a/cisco-xe-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/util/RunningConfigTest.java b/cisco-xe-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xe/util/RunningConfigTest.java
new file mode 100644 (file)
index 0000000..04b6f2a
--- /dev/null
@@ -0,0 +1,206 @@
+package org.opendaylight.unimgr.mef.nrp.cisco.xe.util;
+/*
+ * 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
+ */
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class RunningConfigTest {
+    @Test
+    public void getUsedVcIdValuesTest() {
+        Set<Integer> expected = new HashSet<Integer>();
+        expected.add(3000);
+        expected.add(3001);
+        Assert.assertEquals(expected, config.getUsedVcIdValues());
+    }
+
+    @Test
+    public void getIpAddressLoopback0Test(){
+        try {
+            Assert.assertEquals("1.1.1.1", config.getIpAddressLoopback0());
+        } catch (IpAddressLoopbackNotFoundException e) {
+            Assert.fail(e.toString());
+        }
+    }
+
+    private RunningConfig config = new RunningConfig("Building configuration...\n" +
+            "\n" +
+            "Current configuration : 2482 bytes\n" +
+            "!\n" +
+            "! Last configuration change at 14:17:47 UTC Fri Oct 7 2016 by user1\n" +
+            "!\n" +
+            "version 15.4\n" +
+            "service timestamps debug datetime msec\n" +
+            "service timestamps log datetime msec\n" +
+            "no platform punt-keepalive disable-kernel-core\n" +
+            "platform console virtual\n" +
+            "!\n" +
+            "hostname testing\n" +
+            "!\n" +
+            "boot-start-marker\n" +
+            "boot-end-marker\n" +
+            "!\n" +
+            "!\n" +
+            "enable secret 5 _HASH_/\n" +
+            "!\n" +
+            "no aaa new-model\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "\n" +
+            "\n" +
+            "no ip domain lookup\n" +
+            "ip domain name webpage.com\n" +
+            "\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "subscriber templating\n" +
+            "!\n" +
+            "multilink bundle-name authenticated\n" +
+            "!\n" +
+            "!\n" +
+            "license udi pid _pid_ sn _sn_\n" +
+            "license boot level premium\n" +
+            "spanning-tree extend system-id\n" +
+            "!\n" +
+            "username user1 privilege 15 secret 5 _HASH1_\n" +
+            "username user2 privilege 15 secret 5 _HASH2_.\n" +
+            "!\n" +
+            "redundancy\n" +
+            " mode none\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "cdp run\n" +
+            "!\n" +
+            "ip ssh version 2\n" +
+            "no ip ssh server authenticate user keyboard\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "!\n" +
+            "interface Loopback0\n" +
+            " ip address 1.1.1.1 255.255.255.255\n" +
+            "!\n" +
+            "interface VirtualPortGroup0\n" +
+            " ip unnumbered GigabitEthernet1\n" +
+            " no mop enabled\n" +
+            " no mop sysid\n" +
+            "!\n" +
+            "interface GigabitEthernet1\n" +
+            " description <<< Management port - do not modify >>>\n" +
+            " ip address dhcp\n" +
+            " negotiation auto\n" +
+            "!\n" +
+            "interface GigabitEthernet2\n" +
+            " description <<< MPLS network connection >>>\n" +
+            " ip address 10.0.0.1 255.255.255.252\n" +
+            " negotiation auto\n" +
+            " mpls ip\n" +
+            " cdp enable\n" +
+            "!\n" +
+            "interface GigabitEthernet3\n" +
+            " no ip address\n" +
+            " shutdown\n" +
+            " negotiation auto\n" +
+            "!\n" +
+            "interface GigabitEthernet4\n" +
+            " description Connection to Host\n" +
+            " mtu 1522\n" +
+            " no ip address\n" +
+            " negotiation auto\n" +
+            " service instance 1 ethernet\n" +
+            " !\n" +
+            " service instance 100 ethernet\n" +
+            "  encapsulation dot1q 100\n" +
+            "  xconnect 3.3.3.3 3000 encapsulation mpls\n" +
+            "   mtu 1508\n" +
+            " !\n" +
+            " service instance 101 ethernet\n" +
+            "  encapsulation dot1q 101\n" +
+            "  xconnect 3.3.3.3 3001 encapsulation mpls\n" +
+            "   mtu 1508\n" +
+            " !\n" +
+            "!\n" +
+            "router ospf 100\n" +
+            " network 1.1.1.1 0.0.0.0 area 0\n" +
+            " network 10.0.0.0 0.0.0.3 area 0\n" +
+            "!\n" +
+            "!\n" +
+            "virtual-service csr_mgmt\n" +
+            " vnic gateway VirtualPortGroup0\n" +
+            "  guest ip address 178.26.176.38\n" +
+            " activate\n" +
+            "!\n" +
+            "ip forward-protocol nd\n" +
+            "!\n" +
+            "no ip http server\n" +
+            "no ip http secure-server\n" +
+            "ip route 178.26.176.38 255.255.255.255 VirtualPortGroup0\n" +
+            "!\n" +
+            "!\n" +
+            "snmp-server community user1 RO\n" +
+            "!\n" +
+            "!\n" +
+            "control-plane\n" +
+            "!\n" +
+            "!\n" +
+            "line con 0\n" +
+            " stopbits 1\n" +
+            "line vty 0 4\n" +
+            " exec-timeout 30 0\n" +
+            " privilege level 15\n" +
+            " login local\n" +
+            " transport preferred ssh\n" +
+            " transport input telnet ssh\n" +
+            " transport output none\n" +
+            "line vty 5 10\n" +
+            " exec-timeout 30 0\n" +
+            " privilege level 15\n" +
+            " login local\n" +
+            " transport preferred ssh\n" +
+            " transport input telnet ssh\n" +
+            " transport output none\n" +
+            "line vty 11 98\n" +
+            " login\n" +
+            " transport input telnet ssh\n" +
+            "!\n" +
+            "netconf ssh\n" +
+            "!\n" +
+            "end\n");
+}
\ No newline at end of file
index 0300018b1fd87a20cf59dde298dde14602d23a64..61f7db8cfca6e0c924d72a7996b58df307f84520 100644 (file)
       <artifactId>cisco-xrmodels</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>unimgr-cisco-xe-driver</artifactId>
+      <version>${project.version}</version>
+    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>ovs-driver</artifactId>
index a27e3b9b42d4ff7888ec2af4132ef7525ec7a4b4..fec643e25875d49af01abcf343627666c8bf1588 100755 (executable)
     <feature version="${dluxapps.version}">odl-dluxapps-applications</feature>
   </feature>
 
-  <feature name='odl-unimgr-cisco-xr-driver' version='${project.version}'
-    description='OpenDaylight :: UniMgr :: Cisco XR Driver'>
+  <feature name="odl-unimgr-cisco-xe-driver" version="${project.version}" description='OpenDaylight :: UniMgr :: Cisco XE Driver'>
+    <feature version='${project.version}'>odl-unimgr</feature>
+    <bundle>mvn:org.opendaylight.unimgr/unimgr-cisco-xe-driver/{{VERSION}}</bundle>
+    <bundle>mvn:com.eclipsesource.jaxrs/jersey-all/2.22.2</bundle>
+  </feature>
+
+  <feature name='odl-unimgr-cisco-xr-driver' version='${project.version}' description='OpenDaylight :: UniMgr :: Cisco XR Driver'>
     <feature version='${project.version}'>odl-unimgr</feature>
     <bundle>mvn:org.opendaylight.unimgr/cisco-xrmodels/{{VERSION}}</bundle>
     <bundle>mvn:org.opendaylight.unimgr/unimgr-cisco-xr-driver/{{VERSION}}</bundle>
diff --git a/pom.xml b/pom.xml
index 349352bdcb2d957bd52c13dc740a866f2888c0d1..ebc0ceb8ffdcae7fc01c43f325b632544cd4415d 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -64,6 +64,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
         <module>impl</module>
         <module>netvirt</module>
         <module>cisco-xr-driver</module>
+        <module>cisco-xe-driver</module>
         <module>ovs-driver</module>
         <module>dlux</module>
         <module>cli</module>
index fe090e1595cd1181fededb72e8d89afe59691d72..47751f749570e1ac579bb47735d50cf2768c8e2f 100644 (file)
@@ -42,4 +42,21 @@ module mef-unimgr-ext {
         default 0;
       }
    }
+
+  augment "/nt:network-topology/nt:topology/nt:node" {
+      container connection-settings {
+        leaf userName {
+          type string;
+          config true;
+        }
+        leaf password {
+          type string;
+          config true;
+        }
+        leaf host {
+          type inet:host;
+          config true;
+        }
+      }
+  }
 }