1 package org.opendaylight.controller.config.yang.netconf.northbound.ssh;
3 import io.netty.channel.ChannelFuture;
4 import io.netty.channel.local.LocalAddress;
5 import io.netty.util.concurrent.GenericFutureListener;
6 import java.io.IOException;
7 import java.net.InetAddress;
8 import java.net.InetSocketAddress;
9 import java.net.UnknownHostException;
10 import java.util.concurrent.Executors;
11 import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
12 import org.opendaylight.netconf.api.NetconfServerDispatcher;
13 import org.opendaylight.netconf.ssh.SshProxyServer;
14 import org.opendaylight.netconf.ssh.SshProxyServerConfigurationBuilder;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
18 public class NetconfNorthboundSshModule extends org.opendaylight.controller.config.yang.netconf.northbound.ssh.AbstractNetconfNorthboundSshModule {
20 private static final Logger LOG = LoggerFactory.getLogger(NetconfNorthboundSshModule.class);
22 public NetconfNorthboundSshModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
23 super(identifier, dependencyResolver);
26 public NetconfNorthboundSshModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, final org.opendaylight.controller.config.yang.netconf.northbound.ssh.NetconfNorthboundSshModule oldModule, final java.lang.AutoCloseable oldInstance) {
27 super(identifier, dependencyResolver, oldModule, oldInstance);
31 public void customValidation() {
32 // add custom validation form module attributes here.
36 public java.lang.AutoCloseable createInstance() {
37 final NetconfServerDispatcher dispatch = getDispatcherDependency();
39 final LocalAddress localAddress = new LocalAddress(getPort().toString());
40 final ChannelFuture localServer = dispatch.createLocalServer(localAddress);
42 final SshProxyServer sshProxyServer = new SshProxyServer(Executors.newScheduledThreadPool(1), getWorkerThreadGroupDependency(), getEventExecutorDependency());
44 final InetSocketAddress bindingAddress = getInetAddress();
45 final SshProxyServerConfigurationBuilder sshProxyServerConfigurationBuilder = new SshProxyServerConfigurationBuilder();
46 sshProxyServerConfigurationBuilder.setBindingAddress(bindingAddress);
47 sshProxyServerConfigurationBuilder.setLocalAddress(localAddress);
48 sshProxyServerConfigurationBuilder.setAuthenticator(getAuthProviderDependency());
49 sshProxyServerConfigurationBuilder.setIdleTimeout(Integer.MAX_VALUE);
50 sshProxyServerConfigurationBuilder.setKeyPairProvider(new PEMGeneratorHostKeyProvider());
52 localServer.addListener(new GenericFutureListener<ChannelFuture>() {
55 public void operationComplete(final ChannelFuture future) {
56 if(future.isDone() && !future.isCancelled()) {
58 sshProxyServer.bind(sshProxyServerConfigurationBuilder.createSshProxyServerConfiguration());
59 LOG.info("Netconf SSH endpoint started successfully at {}", bindingAddress);
60 } catch (final IOException e) {
61 throw new RuntimeException("Unable to start SSH netconf server", e);
64 LOG.warn("Unable to start SSH netconf server at {}", bindingAddress, future.cause());
65 throw new RuntimeException("Unable to start SSH netconf server", future.cause());
70 return new NetconfServerCloseable(localServer, sshProxyServer);
73 private InetSocketAddress getInetAddress() {
75 final InetAddress inetAd = InetAddress.getByName(getBindingAddress().getIpv4Address() == null ? getBindingAddress().getIpv6Address().getValue() : getBindingAddress().getIpv4Address().getValue());
76 return new InetSocketAddress(inetAd, getPort().getValue());
77 } catch (final UnknownHostException e) {
78 throw new IllegalArgumentException("Unable to bind netconf endpoint to address " + getBindingAddress(), e);
82 private static final class NetconfServerCloseable implements AutoCloseable {
83 private final ChannelFuture localServer;
84 private final SshProxyServer sshProxyServer;
86 public NetconfServerCloseable(final ChannelFuture localServer, final SshProxyServer sshProxyServer) {
87 this.localServer = localServer;
88 this.sshProxyServer = sshProxyServer;
92 public void close() throws Exception {
93 sshProxyServer.close();
95 if(localServer.isDone()) {
96 localServer.channel().close();
98 localServer.cancel(true);