2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Copyright (C) 2017 Amdocs
8 * =============================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
21 * ============LICENSE_END=========================================================
24 package org.onap.ccsdk.sli.plugins.sshapicall;
26 //import com.fasterxml.jackson.databind.ObjectMapper;
28 import java.io.ByteArrayOutputStream;
29 import java.util.Collections;
30 import java.util.HashSet;
34 import com.google.common.base.Strings;
35 import org.json.JSONObject;
36 import org.onap.appc.adapter.ssh.SshAdapter;
37 import org.onap.appc.adapter.ssh.SshConnection;
38 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
39 import com.att.eelf.configuration.EELFLogger;
40 import com.att.eelf.configuration.EELFManager;
41 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
42 import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
43 import org.onap.ccsdk.sli.plugins.sshapicall.model.AuthType;
44 import org.onap.ccsdk.sli.plugins.sshapicall.model.Parameters;
45 import org.onap.ccsdk.sli.plugins.sshapicall.model.ParseParam;
48 public class SshApiCallNode implements SvcLogicJavaPlugin {
50 private static final EELFLogger logger = EELFManager.getInstance().getApplicationLogger();
53 * Output parameter - SSH command execution status.
55 String PARAM_OUT_status = "status";
58 * Output parameter - content of SSH command stdout.
60 String PARAM_OUT_stdout = "stdout";
63 * Output parameter - content of SSH command stderr.
65 String PARAM_OUT_stderr = "stderr";
68 * Default success status.
70 int DEF_SUCCESS_STATUS = 0;
72 private SshAdapter sshAdapter;
74 public void setSshAdapter(SshAdapter sshAdapter) {
75 this.sshAdapter = sshAdapter;
79 * Allows Directed Graphs the ability to interact with SSH APIs.
80 * @param params HashMap<String,String> of parameters passed by the DG to this function
82 * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th><th>example values</th></thead>
84 * <tr><td>templateFileName</td><td>Optional</td><td>full path to template file that can be used to build a request</td><td>/sdncopt/bvc/sshapi/templates/vnf_service-configuration-operation_minimal.json</td></tr>
85 * <tr><td>Url</td><td>Mandatory</td><td>url to make the SSH connection request to.</td></tr>
86 * <tr><td>Port</td><td>Mandatory</td><td>port to make the SSH connection request to.</td></tr>
87 * <tr><td>User</td><td>Optional</td><td>user name to use for ssh basic authentication</td><td>sdnc_ws</td></tr>
88 * <tr><td>Password</td><td>Optional</td><td>unencrypted password to use for ssh basic authentication</td><td>plain_password</td></tr>
89 * <tr><td>SshKey</td><td>Optional</td><td>Consumer SSH key to use for ssh authentication</td><td>plain_key</td></tr>
90 * <tr><td>ExecTimeout</td><td>Optional</td><td>SSH command execution timeout</td><td>plain_key</td></tr>
91 * <tr><td>Retry</td><td>Optional</td><td>Make ssh connection with default retry policy</td><td>plain_key</td></tr>
92 * <tr><td>Cmd</td><td>Mandatory</td><td>ssh command to be executed on the server.</td><td>get post put delete patch</td></tr>
93 * <tr><td>ResponsePrefix</td><td>Optional</td><td>location the response will be written to in context memory</td><td>tmp.sshapi.result</td></tr>
94 * <tr><td>ResponseType</td><td>Optional</td><td>If we know the response is to be in a specific format (supported are JSON, XML and NONE) </td><td>tmp.sshapi.result</td></tr>
95 * <tr><td>listName[i]</td><td>Optional</td><td>Used for processing XML responses with repeating elements.</td>vpn-information.vrf-details<td></td></tr>
96 * <tr><td>ConvertResponse </td><td>Optional</td><td>whether the response should be converted</td><td>true or false</td></tr>
97 * <tr><td>AuthType</td><td>Optional</td><td>Type of authentiation to be used BASIC or sshKey based</td><td>true or false</td></tr>
98 * <tr><td>EnvParameters</td><td>Optional</td><td>A JSON dictionary which should list key value pairs to be passed to the command execution.
99 * These values would correspond to instance specific parameters that a command may need to execute an action.</td></tr>
100 * <tr><td>FileParameters</td><td>Optional</td><td>A JSON dictionary where keys are filenames and values are contents of files.
101 * The SSH Server will utilize this feature to generate files with keys as filenames and values as content.
102 * This attribute can be used to generate files that a command may require as part of execution.</td></tr>
105 * Exec remote command over SSH. Return command execution status.
106 * Command output is written to out or err stream.
108 * @param ctx Reference to context memory
111 public void execCommand(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
112 ParseParam parser = new ParseParam();
113 Parameters p = parser.getParameters(params);
114 logger.debug("=> Connecting to SSH server...");
115 SshConnection sshConnection = getSshConnection(p);
116 sshConnection.connect();
118 logger.debug("=> Connected to SSH server...");
119 logger.debug("=> Running SSH command...");
120 sshConnection.setExecTimeout(p.sshExecTimeout);
121 ByteArrayOutputStream stdout = new ByteArrayOutputStream();
122 ByteArrayOutputStream stderr = new ByteArrayOutputStream();
123 int status = sshConnection.execCommand(parser.makeCommand(params), stdout, stderr);
124 String stdoutRes = stdout.toString();
125 String stderrRes = stderr.toString();
126 logger.debug("=> executed SSH command");
128 if(status == DEF_SUCCESS_STATUS) {
129 parser.parseOutput(ctx, stdoutRes);
131 ctx.setAttribute(PARAM_OUT_status, String.format("%01d", status));
132 ctx.setAttribute(PARAM_OUT_stdout, stdoutRes);
133 ctx.setAttribute(PARAM_OUT_stderr, stderrRes);
135 sshConnection.disconnect();
139 private SshConnection getSshConnection(Parameters p) throws SvcLogicException{
140 if (p.authtype == AuthType.BASIC)
141 return sshAdapter.getConnection(p.sshapiUrl, p.sshapiPort, p.sshapiUser, p.sshapiPassword);
142 // This is not supported yet in the API, patch has already been added to APPC
143 else if (p.authtype == AuthType.KEY){
144 //return sshAdapter.getConnection(p.sshapiUrl, p.sshapiPort, p.sshKey);
145 throw new SvcLogicException("SSH Key based Auth method not supported");
147 else if (p.authtype == AuthType.NONE){
148 //return sshAdapter.getConnection(p.sshapiUrl, p.sshapiPort, p.sshKey);
149 throw new SvcLogicException("SSH Auth type required, BASIC auth in support");
151 else if (p.authtype == AuthType.UNSPECIFIED){
152 if (p.sshapiUser != null && p.sshapiPassword != null)
153 return sshAdapter.getConnection(p.sshapiUrl, p.sshapiPort, p.sshapiUser, p.sshapiPassword);
154 else if (p.sshKey != null)
155 throw new SvcLogicException("SSH Key based Auth method not supported");
157 throw new SvcLogicException("SSH Auth type required, BASIC auth in support");
162 * Allows Directed Graphs the ability to interact with SSH APIs.
163 * @param params HashMap<String,String> of parameters passed by the DG to this function
165 * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th><th>example values</th></thead>
167 * <tr><td>templateFileName</td><td>Optional</td><td>full path to template file that can be used to build a request</td><td>/sdncopt/bvc/sshapi/templates/vnf_service-configuration-operation_minimal.json</td></tr>
168 * <tr><td>Url</td><td>Mandatory</td><td>url to make the SSH connection request to.</td></tr>
169 * <tr><td>Port</td><td>Mandatory</td><td>port to make the SSH connection request to.</td></tr>
170 * <tr><td>User</td><td>Optional</td><td>user name to use for ssh basic authentication</td><td>sdnc_ws</td></tr>
171 * <tr><td>Password</td><td>Optional</td><td>unencrypted password to use for ssh basic authentication</td><td>plain_password</td></tr>
172 * <tr><td>SshKey</td><td>Optional</td><td>Consumer SSH key to use for ssh authentication</td><td>plain_key</td></tr>
173 * <tr><td>ExecTimeout</td><td>Optional</td><td>SSH command execution timeout</td><td>plain_key</td></tr>
174 * <tr><td>Retry</td><td>Optional</td><td>Make ssh connection with default retry policy</td><td>plain_key</td></tr>
175 * <tr><td>Cmd</td><td>Mandatory</td><td>ssh command to be executed on the server.</td><td>get post put delete patch</td></tr>
176 * <tr><td>ResponsePrefix</td><td>Optional</td><td>location the response will be written to in context memory</td><td>tmp.sshapi.result</td></tr>
177 * <tr><td>ResponseType</td><td>Optional</td><td>If we know the response is to be in a specific format (supported are JSON, XML and NONE) </td><td>tmp.sshapi.result</td></tr>
178 * <tr><td>listName[i]</td><td>Optional</td><td>Used for processing XML responses with repeating elements.</td>vpn-information.vrf-details<td></td></tr>
179 * <tr><td>ConvertResponse </td><td>Optional</td><td>whether the response should be converted</td><td>true or false</td></tr>
180 * <tr><td>AuthType</td><td>Optional</td><td>Type of authentiation to be used BASIC or sshKey based</td><td>true or false</td></tr>
181 * <tr><td>EnvParameters</td><td>Optional</td><td>A JSON dictionary which should list key value pairs to be passed to the command execution.
182 * These values would correspond to instance specific parameters that a command may need to execute an action.</td></tr>
183 * <tr><td>FileParameters</td><td>Optional</td><td>A JSON dictionary where keys are filenames and values are contents of files.
184 * The SSH Server will utilize this feature to generate files with keys as filenames and values as content.
185 * This attribute can be used to generate files that a command may require as part of execution.</td></tr>
188 * Exec remote command over SSH. Return command execution status.
189 * Command output is written to out or err stream.
191 * @param ctx Reference to context memory
194 public void execWithStatusCheck(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
195 execCommand(params, ctx);
196 int status = Integer.parseInt(ctx.getAttribute(PARAM_OUT_status));
197 if(status != DEF_SUCCESS_STATUS) {
198 StringBuilder errmsg = new StringBuilder();
199 errmsg.append("SSH command returned error status [").append(status).append(']');
200 String stderrRes = ctx.getAttribute(PARAM_OUT_stderr);
201 String stdoutRes = ctx.getAttribute(PARAM_OUT_stdout);
202 if((stderrRes != null) && !stderrRes.isEmpty()) {
203 errmsg.append(". Error: [").append(stderrRes).append(']');
204 } else if ((stdoutRes != null) && !stdoutRes.isEmpty()) {
205 errmsg.append(". Error: [").append(stdoutRes).append(']');
207 throw new SvcLogicException(errmsg.toString());
212 * Allows Directed Graphs the ability to interact with SSH APIs.
213 * @param params HashMap<String,String> of parameters passed by the DG to this function
215 * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th><th>example values</th></thead>
217 * <tr><td>templateFileName</td><td>Optional</td><td>full path to template file that can be used to build a request</td><td>/sdncopt/bvc/sshapi/templates/vnf_service-configuration-operation_minimal.json</td></tr>
218 * <tr><td>Url</td><td>Mandatory</td><td>url to make the SSH connection request to.</td></tr>
219 * <tr><td>Port</td><td>Mandatory</td><td>port to make the SSH connection request to.</td></tr>
220 * <tr><td>User</td><td>Optional</td><td>user name to use for ssh basic authentication</td><td>sdnc_ws</td></tr>
221 * <tr><td>Password</td><td>Optional</td><td>unencrypted password to use for ssh basic authentication</td><td>plain_password</td></tr>
222 * <tr><td>SshKey</td><td>Optional</td><td>Consumer SSH key to use for ssh authentication</td><td>plain_key</td></tr>
223 * <tr><td>ExecTimeout</td><td>Optional</td><td>SSH command execution timeout</td><td>plain_key</td></tr>
224 * <tr><td>Retry</td><td>Optional</td><td>Make ssh connection with default retry policy</td><td>plain_key</td></tr>
225 * <tr><td>Cmd</td><td>Mandatory</td><td>ssh command to be executed on the server.</td><td>get post put delete patch</td></tr>
226 * <tr><td>ResponsePrefix</td><td>Optional</td><td>location the response will be written to in context memory</td><td>tmp.sshapi.result</td></tr>
227 * <tr><td>ResponseType</td><td>Optional</td><td>If we know the response is to be in a specific format (supported are JSON, XML and NONE) </td><td>tmp.sshapi.result</td></tr>
228 * <tr><td>listName[i]</td><td>Optional</td><td>Used for processing XML responses with repeating elements.</td>vpn-information.vrf-details<td></td></tr>
229 * <tr><td>ConvertResponse </td><td>Optional</td><td>whether the response should be converted</td><td>true or false</td></tr>
230 * <tr><td>AuthType</td><td>Optional</td><td>Type of authentiation to be used BASIC or sshKey based</td><td>true or false</td></tr>
231 * <tr><td>EnvParameters</td><td>Optional</td><td>A JSON dictionary which should list key value pairs to be passed to the command execution.
232 * These values would correspond to instance specific parameters that a command may need to execute an action.</td></tr>
233 * <tr><td>FileParameters</td><td>Optional</td><td>A JSON dictionary where keys are filenames and values are contents of files.
234 * The SSH Server will utilize this feature to generate files with keys as filenames and values as content.
235 * This attribute can be used to generate files that a command may require as part of execution.</td></tr>
238 * Exec remote command over SSH. Return command execution status.
239 * Command output is written to out or err stream.
241 * @param ctx Reference to context memory
243 public void execCommandWithPty(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {