package org.opendaylight.netconf.callhome.mount;
import io.netty.util.concurrent.EventExecutor;
+import org.opendaylight.aaa.encrypt.AAAEncryptionService;
import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
import org.opendaylight.controller.config.threadpool.ThreadPool;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
final ThreadPool processingExecutor,
final SchemaRepositoryProvider schemaRepositoryProvider,
final DataBroker dataBroker,
- final DOMMountPointService mountPointService) {
+ final DOMMountPointService mountPointService,
+ final AAAEncryptionService encryptionService) {
super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor,
- processingExecutor, schemaRepositoryProvider, dataBroker, mountPointService);
+ processingExecutor, schemaRepositoryProvider, dataBroker, mountPointService,
+ encryptionService);
this.mountPointService = mountPointService;
}
}
import io.netty.util.concurrent.FailedFuture;
import io.netty.util.concurrent.Future;
import java.net.InetSocketAddress;
+import org.opendaylight.aaa.encrypt.AAAEncryptionService;
import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
import org.opendaylight.controller.config.threadpool.ThreadPool;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
private final CallHomeMountSessionManager sessionManager;
private final DataBroker dataBroker;
private final DOMMountPointService mountService;
+ private final AAAEncryptionService encryptionService;
protected CallHomeTopology topology;
public CallHomeMountDispatcher(final String topologyId, final EventExecutor eventExecutor,
final ScheduledThreadPool keepaliveExecutor, final ThreadPool processingExecutor,
final SchemaRepositoryProvider schemaRepositoryProvider, final DataBroker dataBroker,
- final DOMMountPointService mountService) {
+ final DOMMountPointService mountService,
+ final AAAEncryptionService encryptionService) {
this.topologyId = topologyId;
this.eventExecutor = eventExecutor;
this.keepaliveExecutor = keepaliveExecutor;
this.sessionManager = new CallHomeMountSessionManager();
this.dataBroker = dataBroker;
this.mountService = mountService;
+ this.encryptionService = encryptionService;
}
@Override
void createTopology() {
this.topology = new CallHomeTopology(topologyId, this, eventExecutor, keepaliveExecutor, processingExecutor,
- schemaRepositoryProvider, dataBroker, mountService);
+ schemaRepositoryProvider, dataBroker, mountService, encryptionService);
}
@Override
package org.opendaylight.netconf.callhome.mount;
import io.netty.util.concurrent.EventExecutor;
+import org.opendaylight.aaa.encrypt.AAAEncryptionService;
import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
import org.opendaylight.controller.config.threadpool.ThreadPool;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
final EventExecutor eventExecutor,
final ScheduledThreadPool keepaliveExecutor, final ThreadPool processingExecutor,
final SchemaRepositoryProvider schemaRepositoryProvider,
- final DataBroker dataBroker, final DOMMountPointService mountPointService) {
+ final DataBroker dataBroker, final DOMMountPointService mountPointService,
+ final AAAEncryptionService encryptionService) {
super(topologyId, clientDispatcher, eventExecutor,
keepaliveExecutor, processingExecutor, schemaRepositoryProvider,
- dataBroker, mountPointService);
+ dataBroker, mountPointService, encryptionService);
}
@Override
interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"/>
<reference id="domMountPointService"
interface="org.opendaylight.controller.md.sal.dom.api.DOMMountPointService"/>
+ <reference id="encryptionService"
+ interface="org.opendaylight.aaa.encrypt.AAAEncryptionService" />
<bean id="schemaRepository" class="org.opendaylight.netconf.callhome.mount.SchemaRepositoryProviderImpl">
<argument value="shared-schema-repository-impl"/>
<argument ref="schemaRepository"/>
<argument ref="dataBroker"/>
<argument ref="domMountPointService"/>
+ <argument ref="encryptionService"/>
</bean>
-
-</blueprint>
\ No newline at end of file
+</blueprint>
import java.net.UnknownHostException;
import org.junit.Before;
import org.junit.Test;
+import org.opendaylight.aaa.encrypt.AAAEncryptionService;
import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
import org.opendaylight.controller.config.threadpool.ThreadPool;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
private CallHomeMountSessionManager mockSessMgr;
private CallHomeTopology mockTopology;
private CallHomeProtocolSessionContext mockProtoSess;
+ private AAAEncryptionService mockEncryptionService;
@Before
public void setup() {
mockSessMgr = mock(CallHomeMountSessionManager.class);
mockTopology = mock(CallHomeTopology.class);
mockProtoSess = mock(CallHomeProtocolSessionContext.class);
+ mockEncryptionService = mock(AAAEncryptionService.class);
instance = new CallHomeMountDispatcher(topologyId, mockExecutor, mockKeepAlive,
- mockProcessingExecutor, mockSchemaRepoProvider, mockDataBroker, mockMount) {
+ mockProcessingExecutor, mockSchemaRepoProvider, mockDataBroker, mockMount,
+ mockEncryptionService) {
@Override
public CallHomeMountSessionManager getSessionManager() {
return mockSessMgr;
import java.io.IOException;
import org.apache.sshd.ClientSession;
import org.apache.sshd.client.future.AuthFuture;
+import org.opendaylight.aaa.encrypt.AAAEncryptionService;
/**
* Class Providing username/password authentication option to
public class LoginPassword extends AuthenticationHandler {
protected final String username;
protected final String password;
+ protected final AAAEncryptionService encryptionService;
public LoginPassword(String username, String password) {
+ this(username, password, null);
+ }
+
+ public LoginPassword(final String username, final String password, final AAAEncryptionService encryptionService) {
this.username = username;
this.password = password;
+ this.encryptionService = encryptionService;
}
@Override
@Override
public AuthFuture authenticate(final ClientSession session) throws IOException {
- session.addPasswordIdentity(password);
+ if (encryptionService != null) {
+ String decryptedPassword = encryptionService.decrypt(password);
+ session.addPasswordIdentity(decryptedPassword);
+ } else {
+ session.addPasswordIdentity(password);
+ }
return session.auth();
}
}
import java.security.KeyPair;
import org.apache.sshd.ClientSession;
import org.apache.sshd.client.future.AuthFuture;
+import org.opendaylight.aaa.encrypt.AAAEncryptionService;
import org.opendaylight.aaa.encrypt.PKIUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private KeyPair keyPair = null;
private static final Logger LOG = LoggerFactory.getLogger(PublicKeyAuth.class);
- public PublicKeyAuth(String username, String password, String keyPath, String passPhrase) {
- super(username, password);
+ public PublicKeyAuth(String username, String password, String keyPath,
+ String passPhrase, AAAEncryptionService encryptionService) {
+ super(username, password, encryptionService);
try {
boolean isKeyPathAbsent = Strings.isNullOrEmpty(keyPath);
passPhrase = Strings.isNullOrEmpty(passPhrase) ? "" : passPhrase;
if (keyPair != null) {
session.addPublicKeyIdentity(keyPair);
}
- session.addPasswordIdentity(password);
- return session.auth();
+
+ return super.authenticate(session);
}
}
<reference id="mountPointService"
interface="org.opendaylight.controller.md.sal.dom.api.DOMMountPointService"
odl:type="default"/>
+ <reference id="encryptionService"
+ interface="org.opendaylight.aaa.encrypt.AAAEncryptionService" />
<bean id="schemaRepository" class="org.opendaylight.netconf.topology.impl.SchemaRepositoryProviderImpl">
<argument value="shared-schema-repository-impl"/>
</bean>
- <cm:property-placeholder persistent-id="odl-sb-netconf-client-keypair" update-strategy="none">
+ <cm:property-placeholder persistent-id="org.opendaylight.netconf.topology.sb.keypair" update-strategy="none">
<cm:default-properties>
- <cm:property name="private-key-path" value=""/>
+ <cm:property name="private-key-path" value="etc/RSA"/>
<cm:property name="private-key-passphrase" value=""/>
</cm:default-properties>
</cm:property-placeholder>
<bean id="netconfTopology" class="org.opendaylight.netconf.topology.impl.NetconfTopologyImpl"
init-method="init"
destroy-method="close">
- <cm:managed-properties persistent-id="odl-sb-netconf-client-keypair"
+ <cm:managed-properties persistent-id="org.opendaylight.netconf.topology.sb.keypair"
update-strategy="container-managed"/>
<argument value="topology-netconf"/>
<argument ref="clientDispatcherDependency"/>
<argument ref="mountPointService"/>
<property name="privateKeyPath" value="${private-key-path}"/>
<property name="privateKeyPassphrase" value="${private-key-passphrase}"/>
+ <argument ref="encryptionService" />
</bean>
<bean id="netconfConnectorFactory" class="org.opendaylight.netconf.topology.impl.NetconfConnectorFactoryImpl"/>
<service ref="netconfConnectorFactory" interface="org.opendaylight.netconf.topology.api.NetconfConnectorFactory"
odl:type="default"/>
+ <bean id="netconfNodeRegisterEncryptedRPC"
+ class="org.opendaylight.netconf.sal.connect.util.NetconfTopologyRPCProvider">
+ <argument value="topology-netconf"/>
+ <argument ref="dataBroker"/>
+ <argument ref="encryptionService"/>
+ </bean>
+
+ <odl:rpc-implementation ref="netconfNodeRegisterEncryptedRPC"/>
+
</blueprint>
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
+import org.opendaylight.aaa.encrypt.AAAEncryptionService;
import org.opendaylight.controller.cluster.ActorSystemProvider;
import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
import org.opendaylight.controller.config.threadpool.ThreadPool;
private final String topologyId;
private final Duration writeTxIdleTimeout;
private final DOMMountPointService mountPointService;
-
+ private final AAAEncryptionService encryptionService;
private ListenerRegistration<NetconfTopologyManager> dataChangeListenerRegistration;
private String privateKeyPath;
private String privateKeyPassphrase;
public NetconfTopologyManager(final DataBroker dataBroker, final RpcProviderRegistry rpcProviderRegistry,
final ClusterSingletonServiceProvider clusterSingletonServiceProvider,
final ScheduledThreadPool keepaliveExecutor, final ThreadPool processingExecutor,
- final ActorSystemProvider actorSystemProvider, final EventExecutor eventExecutor,
- final NetconfClientDispatcher clientDispatcher, final String topologyId,
- final Config config, final DOMMountPointService mountPointService) {
+ final ActorSystemProvider actorSystemProvider,
+ final EventExecutor eventExecutor, final NetconfClientDispatcher clientDispatcher,
+ final String topologyId, final Config config,
+ final DOMMountPointService mountPointService,
+ final AAAEncryptionService encryptionService) {
+
this.dataBroker = Preconditions.checkNotNull(dataBroker);
this.rpcProviderRegistry = Preconditions.checkNotNull(rpcProviderRegistry);
this.clusterSingletonServiceProvider = Preconditions.checkNotNull(clusterSingletonServiceProvider);
this.topologyId = Preconditions.checkNotNull(topologyId);
this.writeTxIdleTimeout = Duration.apply(config.getWriteTransactionIdleTimeout(), TimeUnit.SECONDS);
this.mountPointService = mountPointService;
+ this.encryptionService = Preconditions.checkNotNull(encryptionService);
+
}
// Blueprint init method
.setSchemaResourceDTO(NetconfTopologyUtils.setupSchemaCacheDTO(node))
.setIdleTimeout(writeTxIdleTimeout)
.setPrivateKeyPath(privateKeyPath)
- .setPrivateKeyPassphrase(privateKeyPassphrase);
+ .setPrivateKeyPassphrase(privateKeyPassphrase)
+ .setEncryptionService(encryptionService);
return builder.build();
}
import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nullable;
+import org.opendaylight.aaa.encrypt.AAAEncryptionService;
import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
import org.opendaylight.netconf.api.NetconfMessage;
import org.opendaylight.netconf.client.NetconfClientSessionListener;
private final Timeout actorResponseWaitTime;
private final String privateKeyPath;
private final String privateKeyPassphrase;
-
+ private final AAAEncryptionService encryptionService;
private NetconfConnectorDTO deviceCommunicatorDTO;
public RemoteDeviceConnectorImpl(final NetconfTopologySetup netconfTopologyDeviceSetup,
this.mountService = mountService;
this.privateKeyPath = netconfTopologyDeviceSetup.getPrivateKeyPath();
this.privateKeyPassphrase = netconfTopologyDeviceSetup.getPrivateKeyPassphrase();
+ this.encryptionService = netconfTopologyDeviceSetup.getEncryptionService();
}
@Override
.node.credentials.credentials.LoginPassword) credentials).getUsername(),
((org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf
.node.credentials.credentials.LoginPassword) credentials).getPassword(),
- this.privateKeyPath, this.privateKeyPassphrase);
+ this.privateKeyPath, this.privateKeyPassphrase, encryptionService);
+
} else {
throw new IllegalStateException(remoteDeviceId + ": Only login/password authentication is supported");
}
import akka.actor.ActorSystem;
import io.netty.util.concurrent.EventExecutor;
+import org.opendaylight.aaa.encrypt.AAAEncryptionService;
import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
import org.opendaylight.controller.config.threadpool.ThreadPool;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
private final Duration idleTimeout;
private final String privateKeyPath;
private final String privateKeyPassphrase;
+ private final AAAEncryptionService encryptionService;
private NetconfTopologySetup(final NetconfTopologySetupBuilder builder) {
this.clusterSingletonServiceProvider = builder.getClusterSingletonServiceProvider();
this.idleTimeout = builder.getIdleTimeout();
this.privateKeyPath = builder.getPrivateKeyPath();
this.privateKeyPassphrase = builder.getPrivateKeyPassphrase();
+ this.encryptionService = builder.getEncryptionService();
}
public ClusterSingletonServiceProvider getClusterSingletonServiceProvider() {
return privateKeyPassphrase;
}
+ public AAAEncryptionService getEncryptionService() {
+ return encryptionService;
+ }
+
public static class NetconfTopologySetupBuilder {
private ClusterSingletonServiceProvider clusterSingletonServiceProvider;
private Duration idleTimeout;
private String privateKeyPath;
private String privateKeyPassphrase;
+ private AAAEncryptionService encryptionService;
public NetconfTopologySetupBuilder() {
}
return this.privateKeyPassphrase;
}
+ private AAAEncryptionService getEncryptionService() {
+ return this.encryptionService;
+ }
+
+ public NetconfTopologySetupBuilder setEncryptionService(final AAAEncryptionService encryptionService) {
+ this.encryptionService = encryptionService;
+ return this;
+ }
+
public static NetconfTopologySetupBuilder create() {
return new NetconfTopologySetupBuilder();
}
binding-class="org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.topology.singleton.config.rev170419.Config"
/>
- <cm:property-placeholder persistent-id="odl-sb-netconf-client-keypair" update-strategy="none">
+ <cm:property-placeholder persistent-id="org.opendaylight.netconf.topology.sb.keypair" update-strategy="none">
<cm:default-properties>
<cm:property name="private-key-path" value=""/>
<cm:property name="private-key-passphrase" value=""/>
</cm:default-properties>
</cm:property-placeholder>
+ <reference id="encryptionService"
+ interface="org.opendaylight.aaa.encrypt.AAAEncryptionService" />
+
<bean id="netconfTopologyManager"
class="org.opendaylight.netconf.topology.singleton.impl.NetconfTopologyManager"
init-method="init" destroy-method="close">
- <cm:managed-properties persistent-id="odl-sb-netconf-client-keypair"
+ <cm:managed-properties persistent-id="org.opendaylight.netconf.topology.sb.keypair"
update-strategy="container-managed"/>
<argument ref="dataBroker"/>
<argument ref="rpcRegistry"/>
<argument ref="mountPointService"/>
<property name="privateKeyPath" value="${private-key-path}"/>
<property name="privateKeyPassphrase" value="${private-key-passphrase}"/>
+ <argument ref="encryptionService" />
</bean>
<service ref="netconfTopologyManager"
interface="org.opendaylight.netconf.topology.singleton.api.NetconfTopologySingletonService"/>
+ <bean id="netconfNodeRegisterEncryptedRPC"
+ class="org.opendaylight.netconf.sal.connect.util.NetconfTopologyRPCProvider"
+ >
+ <argument value="topology-netconf"/>
+ <argument ref="dataBroker"/>
+ <argument ref="encryptionService"/>
+ </bean>
+
+ <odl:rpc-implementation ref="netconfNodeRegisterEncryptedRPC"/>
+
</blueprint>
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
+import org.opendaylight.aaa.encrypt.AAAEncryptionService;
import org.opendaylight.controller.cluster.ActorSystemProvider;
import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
import org.opendaylight.controller.config.threadpool.ThreadPool;
final EventExecutor eventExecutor = mock(EventExecutor.class);
final NetconfClientDispatcher clientDispatcher = mock(NetconfClientDispatcher.class);
final DOMMountPointService mountPointService = mock(DOMMountPointService.class);
+ final AAAEncryptionService encryptionService = mock(AAAEncryptionService.class);
final Config config = new ConfigBuilder().setWriteTransactionIdleTimeout(0).build();
netconfTopologyManager = new NetconfTopologyManager(dataBroker, rpcProviderRegistry,
clusterSingletonServiceProvider, keepaliveExecutor, processingExecutor,
- actorSystemProvider, eventExecutor, clientDispatcher, topologyId, config, mountPointService);
+ actorSystemProvider, eventExecutor, clientDispatcher, topologyId, config,
+ mountPointService, encryptionService);
}
@Test
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-model-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.aaa</groupId>
+ <artifactId>aaa-encrypt-service</artifactId>
+ <version>0.7.0-SNAPSHOT</version>
+ </dependency>
</dependencies>
<build>
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.opendaylight.aaa.encrypt.AAAEncryptionService;
import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
import org.opendaylight.controller.config.threadpool.ThreadPool;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
protected final SharedSchemaRepository sharedSchemaRepository;
protected final DataBroker dataBroker;
protected final DOMMountPointService mountPointService;
-
protected SchemaSourceRegistry schemaRegistry = DEFAULT_SCHEMA_REPOSITORY;
protected SchemaRepository schemaRepository = DEFAULT_SCHEMA_REPOSITORY;
protected SchemaContextFactory schemaContextFactory = DEFAULT_SCHEMA_CONTEXT_FACTORY;
protected String privateKeyPath;
protected String privateKeyPassphrase;
-
+ protected final AAAEncryptionService encryptionService;
protected final HashMap<NodeId, NetconfConnectorDTO> activeConnectors = new HashMap<>();
protected AbstractNetconfTopology(final String topologyId, final NetconfClientDispatcher clientDispatcher,
final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor,
final ThreadPool processingExecutor,
final SchemaRepositoryProvider schemaRepositoryProvider,
- final DataBroker dataBroker, final DOMMountPointService mountPointService) {
+ final DataBroker dataBroker, final DOMMountPointService mountPointService,
+ final AAAEncryptionService encryptionService) {
this.topologyId = topologyId;
this.clientDispatcher = clientDispatcher;
this.eventExecutor = eventExecutor;
this.sharedSchemaRepository = schemaRepositoryProvider.getSharedSchemaRepository();
this.dataBroker = dataBroker;
this.mountPointService = mountPointService;
+ this.encryptionService = encryptionService;
}
public void setSchemaRegistry(final SchemaSourceRegistry schemaRegistry) {
}
protected ListenableFuture<NetconfDeviceCapabilities> setupConnection(final NodeId nodeId,
- final Node configNode) {
+ final Node configNode) {
final NetconfNode netconfNode = configNode.getAugmentation(NetconfNode.class);
Preconditions.checkNotNull(netconfNode.getHost());
}
protected NetconfConnectorDTO createDeviceCommunicator(final NodeId nodeId,
- final NetconfNode node) {
+ final NetconfNode node) {
//setup default values since default value is not supported in mdsal
final Long defaultRequestTimeoutMillis = node.getDefaultRequestTimeoutMillis() == null
? DEFAULT_REQUEST_TIMEOUT_MILLIS : node.getDefaultRequestTimeoutMillis();
.netconf.node.credentials.credentials.LoginPassword) credentials).getUsername(),
((org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114
.netconf.node.credentials.credentials.LoginPassword) credentials).getPassword(),
- privateKeyPath, privateKeyPassphrase);
+ privateKeyPath, privateKeyPassphrase, encryptionService);
} else {
throw new IllegalStateException("Only login/password authentification is supported");
}
import io.netty.util.concurrent.EventExecutor;
import java.util.Collection;
import javax.annotation.Nonnull;
+import org.opendaylight.aaa.encrypt.AAAEncryptionService;
import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
import org.opendaylight.controller.config.threadpool.ThreadPool;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
public NetconfTopologyImpl(final String topologyId, final NetconfClientDispatcher clientDispatcher,
final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor,
final ThreadPool processingExecutor,
- final SchemaRepositoryProvider schemaRepositoryProvider, final DataBroker dataBroker,
- final DOMMountPointService mountPointService) {
+ final SchemaRepositoryProvider schemaRepositoryProvider,
+ final DataBroker dataBroker, final DOMMountPointService mountPointService,
+ final AAAEncryptionService encryptionService) {
super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor, processingExecutor,
- schemaRepositoryProvider, dataBroker, mountPointService);
+ schemaRepositoryProvider, dataBroker, mountPointService, encryptionService);
}
@Override
dataBroker.registerDataTreeChangeListener(
new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
TopologyUtil.createTopologyListPath(topologyId).child(Node.class)), this);
-
-
}
@Override
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.opendaylight.aaa.encrypt.AAAEncryptionService;
import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
import org.opendaylight.controller.config.threadpool.ThreadPool;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
@Mock
private DOMMountPointService mountPointService;
+ @Mock
+ private AAAEncryptionService encryptionService;
+
private TestingNetconfTopologyImpl topology;
private TestingNetconfTopologyImpl spyTopology;
topology = new TestingNetconfTopologyImpl(TOPOLOGY_ID, mockedClientDispatcher,
mockedEventExecutor, mockedKeepaliveExecutor, mockedProcessingExecutor, mockedSchemaRepositoryProvider,
- dataBroker, mountPointService);
+ dataBroker, mountPointService, encryptionService);
spyTopology = spy(topology);
}
final ScheduledThreadPool keepaliveExecutor,
final ThreadPool processingExecutor,
final SchemaRepositoryProvider schemaRepositoryProvider,
- final DataBroker dataBroker, final DOMMountPointService mountPointService) {
+ final DataBroker dataBroker, final DOMMountPointService mountPointService,
+ final AAAEncryptionService encryptionService) {
super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor,
- processingExecutor, schemaRepositoryProvider, dataBroker, mountPointService);
+ processingExecutor, schemaRepositoryProvider, dataBroker,
+ mountPointService, encryptionService);
}
@Override
--- /dev/null
+/*
+ * Copyright (c) 2017 Brocade Communication Systems 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.netconf.sal.connect.util;
+
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.SettableFuture;
+import java.util.concurrent.Future;
+import org.opendaylight.aaa.encrypt.AAAEncryptionService;
+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.netconf.node.topology.rev150114.AddNetconfNodeInput;
+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.NetconfNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeTopologyService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPassword;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPasswordBuilder;
+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.NodeId;
+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.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NetconfTopologyRPCProvider implements NetconfNodeTopologyService {
+ private final AAAEncryptionService encryptionService;
+ private final DataBroker dataBroker;
+ private final String topologyId;
+ private static final Logger LOG = LoggerFactory.getLogger(NetconfTopologyRPCProvider.class);
+
+ public NetconfTopologyRPCProvider(final DataBroker dataBroker,
+ final AAAEncryptionService encryptionService,
+ final String topologyId) {
+ this.dataBroker = dataBroker;
+ this.encryptionService = Preconditions.checkNotNull(encryptionService);
+ this.topologyId = Preconditions.checkNotNull(topologyId);
+ }
+
+ @Override
+ public Future<RpcResult<Void>> addNetconfNode(AddNetconfNodeInput input) {
+ NetconfNode node = this.encryptPassword(input);
+ final SettableFuture<RpcResult<Void>> futureResult = SettableFuture.create();
+ NodeId nodeId = new NodeId(input.getNodeId());
+ writeToConfigDS(node, nodeId, topologyId, futureResult);
+ return futureResult;
+ }
+
+ private NetconfNode encryptPassword(AddNetconfNodeInput input) {
+ NetconfNodeBuilder builder = new NetconfNodeBuilder();
+ builder.fieldsFrom(input);
+
+ boolean encrypt = input.isEncrypt();
+ LoginPassword loginPassword = (LoginPassword) input.getCredentials();
+ if (encrypt) {
+ String encryptedPassword = encryptionService.encrypt(loginPassword.getPassword());
+ LoginPassword newCreds = new LoginPasswordBuilder().setPassword(encryptedPassword)
+ .setUsername(loginPassword.getUsername()).build();
+ builder.setCredentials(newCreds);
+ }
+
+ NetconfNode node = builder.build();
+ return node;
+ }
+
+ private void writeToConfigDS(NetconfNode node, NodeId nodeId, String topologyId,
+ final SettableFuture<RpcResult<Void>> futureResult) {
+
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
+ final InstanceIdentifier<NetworkTopology> networkTopologyId =
+ InstanceIdentifier.builder(NetworkTopology.class).build();
+ final InstanceIdentifier<NetconfNode> niid = networkTopologyId.child(Topology.class,
+ new TopologyKey(new TopologyId(topologyId))).child(Node.class,
+ new NodeKey(nodeId)).augmentation(NetconfNode.class);
+ writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, niid, node, true);
+ final CheckedFuture<Void, TransactionCommitFailedException> future = writeTransaction.submit();
+ Futures.addCallback(future, new FutureCallback<Void>() {
+
+ @Override
+ public void onSuccess(Void result) {
+ LOG.info("add-netconf-node RPC: Added netconf node successfully.");
+ futureResult.set(RpcResultBuilder.<Void>success().build());
+ }
+
+ @Override
+ public void onFailure(Throwable exception) {
+ LOG.error("add-netconf-node RPC: Unable to add netconf node.", exception);
+ futureResult.setException(exception);
+ }
+ });
+ }
+
+}
}
+ rpc add-netconf-node {
+ input {
+ uses netconf-node-fields;
+ leaf node-id {
+ type string;
+ }
+ leaf encrypt {
+ type boolean;
+ default false;
+ }
+ }
+ }
+
augment "/nt:network-topology/nt:topology/nt:node" {
when "../../nt:topology-types/topology-netconf";
ext:augment-identifier "netconf-node";
uses netconf-node-fields;
}
+
}
--- /dev/null
+/*
+ * Copyright (c) 2017 Brocade Communication Systems 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.netconf.sal.connect.netconf.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Method;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.aaa.encrypt.AAAEncryptionService;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.netconf.sal.connect.util.NetconfTopologyRPCProvider;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.AddNetconfNodeInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.AddNetconfNodeInputBuilder;
+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.netconf.node.credentials.credentials.LoginPassword;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPasswordBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+
+public class NetconfTopologyRPCProviderTest {
+ private static final NodeId NODE_ID = new NodeId("testing-node");
+ private static final String TOPOLOGY_ID = "testing-topology";
+ private static final String TEST_PWD = "test";
+ private static final String ENC_PWD = "4o9/Hn3Pi4150YrP12N/1g==";
+
+ @Mock
+ private DataBroker dataBroker;
+
+ @Mock
+ private AAAEncryptionService encryptionService;
+
+ NetconfTopologyRPCProvider rpcProvider ;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ when(encryptionService.encrypt(TEST_PWD)).thenReturn(ENC_PWD);
+ rpcProvider = new NetconfTopologyRPCProvider(dataBroker, encryptionService, TOPOLOGY_ID);
+ }
+
+ @Test
+ public void testEncryptPassword() throws Exception {
+
+ NetconfNode node = invokeEncryption(true);
+ assertNotEquals(TEST_PWD, ((LoginPassword)node.getCredentials()).getPassword());
+
+ node = invokeEncryption(false);
+ assertEquals(TEST_PWD, ((LoginPassword)node.getCredentials()).getPassword());
+ }
+
+ private NetconfNode invokeEncryption(boolean encrypt) throws Exception {
+ Method method = null;
+
+ method = NetconfTopologyRPCProvider.class.getDeclaredMethod("encryptPassword", AddNetconfNodeInput.class);
+
+ method.setAccessible(true);
+ NetconfNode node = null;
+
+ node = (NetconfNode)method.invoke(rpcProvider, getInput(encrypt));
+
+ return node;
+ }
+
+ private AddNetconfNodeInput getInput(boolean encrypt) {
+ AddNetconfNodeInputBuilder builder = new AddNetconfNodeInputBuilder();
+ builder.setCredentials(new LoginPasswordBuilder().setPassword(TEST_PWD).setUsername("test").build());
+ builder.setHost(new Host(new IpAddress(new Ipv4Address("10.18.16.188"))));
+ builder.setPort(new PortNumber(830));
+ builder.setTcpOnly(false);
+ builder.setNodeId(NODE_ID.toString());
+ builder.setEncrypt(encrypt);
+ return builder.build();
+ }
+
+}