Migrate shell components to new APIs
[netconf.git] / netconf / netconf-console / src / main / java / org / opendaylight / netconf / console / commands / NetconfConnectDeviceCommand.java
1 /*
2  * Copyright (c) 2016 Inocybe Technologies and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.netconf.console.commands;
10
11 import com.google.common.annotations.VisibleForTesting;
12 import com.google.common.base.Strings;
13 import java.util.Arrays;
14 import org.apache.karaf.shell.api.action.Action;
15 import org.apache.karaf.shell.api.action.Command;
16 import org.apache.karaf.shell.api.action.Option;
17 import org.opendaylight.netconf.console.api.NetconfCommands;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.Protocol.Name;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.ProtocolBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.protocol.specification.TlsCase;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.protocol.specification.TlsCaseBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.protocol.specification.tls._case.TlsBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPasswordBuilder;
30
31 @Command(name = "netconf:connect-device", scope = "netconf", description = "Connect to a netconf device.")
32 public class NetconfConnectDeviceCommand implements Action {
33
34     protected final NetconfCommands service;
35
36     public NetconfConnectDeviceCommand(final NetconfCommands service) {
37         this.service = service;
38     }
39
40     @VisibleForTesting
41     NetconfConnectDeviceCommand(final NetconfCommands service, final String deviceIp, final String devicePort) {
42         this.service = service;
43         this.deviceIp = deviceIp;
44         this.devicePort = devicePort;
45     }
46
47     @Option(name = "-i",
48             aliases = { "--ipaddress" },
49             description = "IP address of the netconf device",
50             required = true,
51             multiValued = false)
52     private String deviceIp;
53
54     @Option(name = "-p",
55             aliases = { "--port" },
56             description = "Port of the netconf device",
57             required = true,
58             multiValued = false)
59     private String devicePort;
60
61     @Option(name = "-U",
62             aliases = { "--username" },
63             description = "Username for netconf connection",
64             required = false,
65             multiValued = false)
66     private String username;
67
68     @Option(name = "-P",
69             aliases = { "--password" },
70             description = "Password for netconf connection",
71             required = false,
72             multiValued = false)
73     private String password;
74
75     @Option(name = "-t",
76             aliases = { "--tcp-only" },
77             description = "Type of connection, true for tcp only",
78             required = false,
79             multiValued = false)
80     private String connectionType = "false";
81
82     @Option(name = "-pr",
83             aliases = { "--protocol" },
84             description = "Which protocol to be used, ssh or tls",
85             required = false,
86             multiValued = false)
87     private String protocol = "ssh";
88
89     @Option(name = "-ev",
90             aliases = { "--excluded-versions" },
91             description = "TLS versions not supported by target device",
92             required = false,
93             multiValued = false)
94     private String excludedTlsVersions;
95
96     @Option(name = "-sl",
97             aliases = { "--schemaless" },
98             description = "Schemaless surpport, true for schemaless",
99             required = false,
100             multiValued = false)
101     private String schemaless = "false";
102
103     @Option(name = "-id",
104             aliases = { "--identifier" },
105             description = "Node Identifier of the netconf device",
106             required = false,
107             multiValued = false)
108     private String deviceId;
109
110     @Override
111     public Object execute() {
112         if (!NetconfCommandUtils.isIpValid(deviceIp) || !NetconfCommandUtils.isPortValid(devicePort)) {
113             return "Invalid IP:" + deviceIp + " or Port:" + devicePort + "Please enter a valid entry to proceed.";
114         }
115
116         final boolean isTcpOnly = connectionType.equals("true");
117         final boolean isSchemaless = schemaless.equals("true");
118
119         final NetconfNodeBuilder netconfNodeBuilder = new NetconfNodeBuilder();
120         netconfNodeBuilder.setHost(new Host(new IpAddress(new Ipv4Address(deviceIp))))
121                           .setPort(new PortNumber(Integer.decode(devicePort)))
122                           .setTcpOnly(isTcpOnly)
123                           .setSchemaless(isSchemaless);
124
125         if (isTcpOnly || protocol.equalsIgnoreCase("ssh")) {
126             if (Strings.isNullOrEmpty(username) || Strings.isNullOrEmpty(password)) {
127                 return "Empty Username:" + username + " or Password:" + password
128                         + ". In TCP or SSH mode, you must provide valid username and password.";
129             }
130             final Credentials credentials =
131                     new LoginPasswordBuilder().setPassword(password).setUsername(username).build();
132             netconfNodeBuilder.setCredentials(credentials);
133             if (!isTcpOnly) {
134                 netconfNodeBuilder.setProtocol(new ProtocolBuilder().setName(Name.SSH).build());
135             }
136         } else if (protocol.equalsIgnoreCase("tls")) {
137             TlsCase tlsCase = null;
138             if (!Strings.isNullOrEmpty(excludedTlsVersions)) {
139                 tlsCase = new TlsCaseBuilder()
140                             .setTls(new TlsBuilder()
141                                     .setExcludedVersions(Arrays.asList(excludedTlsVersions.split(","))).build())
142                             .build();
143             }
144             netconfNodeBuilder.setProtocol(new ProtocolBuilder()
145                                             .setName(Name.TLS)
146                                             .setSpecification(tlsCase)
147                                             .build());
148         } else {
149             return "Invalid protocol: " + protocol + ". Only SSH and TLS are supported.";
150         }
151
152         service.connectDevice(netconfNodeBuilder.build(), deviceId);
153         final String message = "Netconf connector added succesfully";
154         return message;
155     }
156 }