<feature version='${project.version}'>odl-netconf-mapping-api</feature>
<feature version='${yangtools.version}'>odl-yangtools-yang-data</feature>
<bundle>mvn:org.opendaylight.netconf/netconf-util/{{VERSION}}</bundle>
+ <configfile finalname="etc/netconf.cfg">mvn:org.opendaylight.netconf/netconf-util/{{VERSION}}/cfg/config</configfile>
</feature>
<feature name='odl-netconf-impl' version='${project.version}' description="OpenDaylight :: Netconf :: Impl">
</feature>
<feature name='odl-netconf-ssh' version='${project.version}' description="OpenDaylight :: Netconf Connector :: SSH">
+ <feature version='${project.version}'>odl-netconf-util</feature>
<feature version='${project.version}'>odl-netconf-tcp</feature>
<feature version='${project.version}'>odl-aaa-netconf-plugin</feature>
<bundle>mvn:org.opendaylight.netconf/netconf-ssh/{{VERSION}}</bundle>
</feature>
<feature name='odl-netconf-tcp' version='${project.version}' description="OpenDaylight :: Netconf Connector :: TCP">
+ <feature version='${project.version}'>odl-netconf-util</feature>
<feature version='${project.version}'>odl-netconf-impl</feature>
<feature version='${config.version}'>odl-config-netty</feature>
<bundle>mvn:org.opendaylight.netconf/netconf-tcp/{{VERSION}}</bundle>
<artifactId>netconf-client</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ </dependency>
</dependencies>
<build>
</execution>
</executions>
</plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- </plugin>
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ </plugin>
</plugins>
</build>
*/
package org.opendaylight.netconf.ssh.osgi;
-import com.google.common.base.Optional;
import io.netty.channel.local.LocalAddress;
import io.netty.channel.nio.NioEventLoopGroup;
import java.io.IOException;
import org.opendaylight.netconf.ssh.SshProxyServer;
import org.opendaylight.netconf.ssh.SshProxyServerConfigurationBuilder;
import org.opendaylight.netconf.util.osgi.NetconfConfigUtil;
-import org.opendaylight.netconf.util.osgi.NetconfConfigUtil.InfixProp;
+import org.opendaylight.netconf.util.osgi.NetconfConfiguration;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
}
private SshProxyServer startSSHServer(final BundleContext bundleContext) throws IOException {
- final Optional<InetSocketAddress> maybeSshSocketAddress = NetconfConfigUtil.extractNetconfServerAddress(bundleContext, InfixProp.ssh);
- if (!maybeSshSocketAddress.isPresent()) {
- LOG.warn("SSH bridge not configured. Using default value {}", NetconfConfigUtil.DEFAULT_SSH_SERVER_ADRESS);
- }
- final InetSocketAddress sshSocketAddress = maybeSshSocketAddress
- .or(NetconfConfigUtil.DEFAULT_SSH_SERVER_ADRESS);
- LOG.info("Starting netconf SSH bridge at {}", sshSocketAddress);
+ final NetconfConfiguration netconfConfiguration = NetconfConfigUtil.getNetconfConfigurationService(bundleContext).
+ orElseThrow(() -> new IllegalStateException("Configuration for SSH not found."));
- final LocalAddress localAddress = NetconfConfigUtil.getNetconfLocalAddress();
+ final InetSocketAddress sshSocketAddress = netconfConfiguration.getSshServerAddress();
+ LOG.info("Starting netconf SSH server at {}", sshSocketAddress);
+ final LocalAddress localAddress = NetconfConfigUtil.getNetconfLocalAddress();
authProviderTracker = new AuthProviderTracker(bundleContext);
- final Optional<String> maybePath = NetconfConfigUtil.getPrivateKeyPath(bundleContext);
- if(!maybePath.isPresent()) {
- LOG.warn("Private key path not configured. Using default value {}",
- NetconfConfigUtil.DEFAULT_PRIVATE_KEY_PATH);
- }
- final String path = maybePath.or(NetconfConfigUtil.DEFAULT_PRIVATE_KEY_PATH);
- LOG.trace("Starting netconf SSH bridge with path to ssh private key {}", path);
+ final String path = netconfConfiguration.getPrivateKeyPath();
+ LOG.trace("Starting netconf SSH server with path to ssh private key {}", path);
final SshProxyServer sshProxyServer = new SshProxyServer(minaTimerExecutor, clientGroup, nioExecutor);
sshProxyServer.bind(
.createSshProxyServerConfiguration());
return sshProxyServer;
}
-
}
<artifactId>mockito-configuration</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ </dependency>
</dependencies>
<build>
package org.opendaylight.netconf.tcp.osgi;
-import com.google.common.base.Optional;
import java.net.InetSocketAddress;
import org.opendaylight.netconf.tcp.netty.ProxyServer;
import org.opendaylight.netconf.util.osgi.NetconfConfigUtil;
import org.opendaylight.netconf.util.osgi.NetconfConfigUtil.InfixProp;
+import org.opendaylight.netconf.util.osgi.NetconfConfiguration;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
@Override
public void start(BundleContext context) {
- final Optional<InetSocketAddress> maybeAddress = NetconfConfigUtil.extractNetconfServerAddress(context, InfixProp.tcp);
- if (maybeAddress.isPresent() == false) {
- LOG.warn("Netconf tcp server is not configured. Using default value {}",
- NetconfConfigUtil.DEFAULT_TCP_SERVER_ADRESS);
- }
+ final NetconfConfiguration netconfConfiguration = NetconfConfigUtil.getNetconfConfigurationService(context).
+ orElseThrow(() -> new IllegalStateException("Configuration for TCP not found."));
- InetSocketAddress address = maybeAddress.or(NetconfConfigUtil.DEFAULT_TCP_SERVER_ADRESS);
+ final InetSocketAddress address = netconfConfiguration.getTcpServerAddress();
if (address.getAddress().isAnyLocalAddress()) {
LOG.warn("Unprotected netconf TCP address is configured to ANY local address. This is a security risk. Consider changing {} to 127.0.0.1",
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-data-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ </dependency>
</dependencies>
<build>
<plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Bundle-Activator>org.opendaylight.netconf.util.osgi.NetconfConfigurationActivator</Bundle-Activator>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/netconf.cfg</file>
+ <type>cfg</type>
+ <classifier>config</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
import com.google.common.base.Optional;
import io.netty.channel.local.LocalAddress;
import java.net.InetSocketAddress;
+import java.util.Collection;
import java.util.concurrent.TimeUnit;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ManagedService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
}
return Optional.fromNullable(value);
}
+
+ public static java.util.Optional<NetconfConfiguration> getNetconfConfigurationService(BundleContext bundleContext) {
+ final Collection<ServiceReference<ManagedService>> serviceReferences;
+ try {
+ serviceReferences = bundleContext.getServiceReferences(ManagedService.class, null);
+ for (final ServiceReference<ManagedService> serviceReference : serviceReferences) {
+ ManagedService service = bundleContext.getService(serviceReference);
+ if (service instanceof NetconfConfiguration){
+ return java.util.Optional.of((NetconfConfiguration) service);
+ }
+ }
+ } catch (InvalidSyntaxException e) {
+ LOG.error("Unable to retrieve references for ManagedService: {}", e);
+ }
+ LOG.error("Unable to retrieve NetconfConfiguration service. Not found. Bundle netconf-util probably failed.");
+ return java.util.Optional.empty();
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.util.osgi;
+
+import java.net.InetSocketAddress;
+import java.util.Dictionary;
+import org.osgi.service.cm.ManagedService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NetconfConfiguration implements ManagedService {
+ private static final Logger LOG = LoggerFactory.getLogger(NetconfConfiguration.class);
+
+ private static final NetconfConfiguration instance = new NetconfConfiguration();
+ private NetconfConfigurationHolder netconfConfiguration;
+
+ public static final String KEY_SSH_ADDRESS = "ssh-address";
+ public static final String KEY_SSH_PORT = "ssh-port";
+ public static final String KEY_TCP_ADDRESS = "tcp-address";
+ public static final String KEY_TCP_PORT = "tcp-port";
+ public static final String KEY_SSH_PK_PATH = "ssh-pk-path";
+
+ public static NetconfConfiguration getInstance() {
+ return instance;
+ }
+
+ private NetconfConfiguration() {
+ netconfConfiguration = new NetconfConfigurationHolder(NetconfConfigUtil.DEFAULT_TCP_SERVER_ADRESS,
+ NetconfConfigUtil.DEFAULT_SSH_SERVER_ADRESS, NetconfConfigUtil.DEFAULT_PRIVATE_KEY_PATH);
+ }
+
+ @Override
+ public void updated(final Dictionary<String, ?> dictionaryConfig) {
+ if (dictionaryConfig == null) {
+ LOG.warn("Netconf configuration cannot be updated.");
+ return;
+ }
+ final InetSocketAddress sshServerAddress = new InetSocketAddress((String) dictionaryConfig.get(KEY_SSH_ADDRESS),
+ Integer.parseInt((String) dictionaryConfig.get(KEY_SSH_PORT)));
+ final InetSocketAddress tcpServerAddress = new InetSocketAddress((String) dictionaryConfig.get(KEY_TCP_ADDRESS),
+ Integer.parseInt((String) dictionaryConfig.get(KEY_TCP_PORT)));
+
+ netconfConfiguration = new NetconfConfigurationHolder(tcpServerAddress, sshServerAddress,
+ (String) dictionaryConfig.get(KEY_SSH_PK_PATH));
+
+ LOG.info("Netconf configuration was updated: {}", dictionaryConfig.toString());
+ }
+
+ public InetSocketAddress getSshServerAddress(){
+ return netconfConfiguration.getSshServerAddress();
+ }
+
+ public InetSocketAddress getTcpServerAddress(){
+ return netconfConfiguration.getTcpServerAddress();
+ }
+
+ public String getPrivateKeyPath() {
+ return netconfConfiguration.getPrivateKeyPath();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.util.osgi;
+
+import java.util.Hashtable;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ManagedService;
+
+public class NetconfConfigurationActivator implements BundleActivator {
+ private static final String CONFIG_PID = "netconf";
+ private ServiceRegistration configService;
+
+ @Override
+ public void start(BundleContext bundleContext) {
+ configService = bundleContext.registerService(ManagedService.class,
+ NetconfConfiguration.getInstance(), getNetconfConfigProperties());
+ }
+
+ @Override
+ public void stop(BundleContext bundleContext) {
+ if (configService != null) {
+ configService.unregister();
+ configService = null;
+ }
+ }
+
+ private Hashtable<String, String> getNetconfConfigProperties(){
+ Hashtable<String, String> properties = new Hashtable<>();
+ properties.put(Constants.SERVICE_PID, CONFIG_PID);
+ return properties;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.util.osgi;
+
+import java.net.InetSocketAddress;
+
+final class NetconfConfigurationHolder {
+
+ private final InetSocketAddress tcpServerAddress;
+ private final InetSocketAddress sshServerAddress;
+ private final String privateKeyPath;
+
+ NetconfConfigurationHolder(InetSocketAddress tcpServerAddress, InetSocketAddress sshServerAddress, String privateKeyPath){
+ this.tcpServerAddress = tcpServerAddress;
+ this.sshServerAddress = sshServerAddress;
+ this.privateKeyPath = privateKeyPath;
+ }
+
+ String getPrivateKeyPath() {
+ return privateKeyPath;
+ }
+
+ InetSocketAddress getSshServerAddress() {
+ return sshServerAddress;
+ }
+
+ InetSocketAddress getTcpServerAddress() {
+ return tcpServerAddress;
+ }
+
+}
--- /dev/null
+# netconf-tcp:
+
+tcp-address=127.0.0.1
+tcp-port=8383
+
+# netconf-ssh:
+
+ssh-address=0.0.0.0
+ssh-port=1830
+# Use Linux style path
+ssh-pk-path = ./configuration/RSA.pk
\ No newline at end of file