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