2 * Copyright (c) 2016 Inocybe Technologies and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.netconf.console.commands;
11 import com.google.common.annotations.VisibleForTesting;
12 import com.google.common.base.Strings;
14 import java.util.Arrays;
16 import org.apache.karaf.shell.commands.Command;
17 import org.apache.karaf.shell.commands.Option;
18 import org.apache.karaf.shell.console.AbstractAction;
19 import org.opendaylight.netconf.console.api.NetconfCommands;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.Protocol.Name;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.ProtocolBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.protocol.specification.TlsCase;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.protocol.specification.TlsCaseBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.protocol.specification.tls._case.TlsBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPasswordBuilder;
33 @Command(name = "netconf:connect-device", scope = "netconf", description = "Connect to a netconf device.")
34 public class NetconfConnectDeviceCommand extends AbstractAction {
36 protected final NetconfCommands service;
38 public NetconfConnectDeviceCommand(final NetconfCommands service) {
39 this.service = service;
43 NetconfConnectDeviceCommand(final NetconfCommands service, final String deviceIp, final String devicePort) {
44 this.service = service;
45 this.deviceIp = deviceIp;
46 this.devicePort = devicePort;
50 aliases = { "--ipaddress" },
51 description = "IP address of the netconf device",
54 private String deviceIp;
57 aliases = { "--port" },
58 description = "Port of the netconf device",
61 private String devicePort;
64 aliases = { "--username" },
65 description = "Username for netconf connection",
68 private String username;
71 aliases = { "--password" },
72 description = "Password for netconf connection",
75 private String password;
78 aliases = { "--tcp-only" },
79 description = "Type of connection, true for tcp only",
82 private String connectionType = "false";
85 aliases = { "--protocol" },
86 description = "Which protocol to be used, ssh or tls",
89 private String protocol = "ssh";
92 aliases = { "--excluded-versions" },
93 description = "TLS versions not supported by target device",
96 private String excludedTlsVersions;
99 aliases = { "--schemaless" },
100 description = "Schemaless surpport, true for schemaless",
103 private String schemaless = "false";
105 @Option(name = "-id",
106 aliases = { "--identifier" },
107 description = "Node Identifier of the netconf device",
110 private String deviceId;
113 protected Object doExecute() throws Exception {
114 if (!NetconfCommandUtils.isIpValid(deviceIp) || !NetconfCommandUtils.isPortValid(devicePort)) {
115 return "Invalid IP:" + deviceIp + " or Port:" + devicePort + "Please enter a valid entry to proceed.";
118 final boolean isTcpOnly = connectionType.equals("true");
119 final boolean isSchemaless = schemaless.equals("true");
121 final NetconfNodeBuilder netconfNodeBuilder = new NetconfNodeBuilder();
122 netconfNodeBuilder.setHost(new Host(new IpAddress(new Ipv4Address(deviceIp))))
123 .setPort(new PortNumber(Integer.decode(devicePort)))
124 .setTcpOnly(isTcpOnly)
125 .setSchemaless(isSchemaless);
127 if (isTcpOnly || protocol.equalsIgnoreCase("ssh")) {
128 if (Strings.isNullOrEmpty(username) || Strings.isNullOrEmpty(password)) {
129 return "Empty Username:" + username + " or Password:" + password
130 + ". In TCP or SSH mode, you must provide valid username and password.";
132 final Credentials credentials =
133 new LoginPasswordBuilder().setPassword(password).setUsername(username).build();
134 netconfNodeBuilder.setCredentials(credentials);
136 netconfNodeBuilder.setProtocol(new ProtocolBuilder().setName(Name.SSH).build());
138 } else if (protocol.equalsIgnoreCase("tls")) {
139 TlsCase tlsCase = null;
140 if (!Strings.isNullOrEmpty(excludedTlsVersions)) {
141 tlsCase = new TlsCaseBuilder()
142 .setTls(new TlsBuilder()
143 .setExcludedVersions(Arrays.asList(excludedTlsVersions.split(","))).build())
146 netconfNodeBuilder.setProtocol(new ProtocolBuilder()
148 .setSpecification(tlsCase)
151 return "Invalid protocol: " + protocol + ". Only SSH and TLS are supported.";
154 service.connectDevice(netconfNodeBuilder.build(), deviceId);
155 final String message = "Netconf connector added succesfully";