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