SSHApiCallNode sshExec API Impl
[ccsdk/sli/plugins.git] / sshapi-call-node / provider / src / main / java / org / onap / ccsdk / sli / plugins / sshapicall / SshApiCallNode.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
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
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
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.
20  *
21  * ============LICENSE_END=========================================================
22  */
23
24 package org.onap.ccsdk.sli.plugins.sshapicall;
25
26 //import com.fasterxml.jackson.databind.ObjectMapper;
27
28 import java.io.ByteArrayOutputStream;
29 import java.util.Collections;
30 import java.util.HashSet;
31 import java.util.Map;
32 import java.util.Set;
33
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;
46
47
48 public class SshApiCallNode implements SvcLogicJavaPlugin {
49
50     private static final EELFLogger logger = EELFManager.getInstance().getApplicationLogger();
51
52     /**
53      * Output parameter - SSH command execution status.
54      */
55     String PARAM_OUT_status = "status";
56
57     /**
58      * Output parameter - content of SSH command stdout.
59      */
60     String PARAM_OUT_stdout = "stdout";
61
62     /**
63      * Output parameter - content of SSH command stderr.
64      */
65     String PARAM_OUT_stderr = "stderr";
66
67     /**
68      * Default success status.
69      */
70     int DEF_SUCCESS_STATUS = 0;
71
72     private SshAdapter sshAdapter;
73
74     public void setSshAdapter(SshAdapter sshAdapter) {
75         this.sshAdapter = sshAdapter;
76     }
77
78     /**
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
81      * <table border="1">
82      *  <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th><th>example values</th></thead>
83      *  <tbody>
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>
103      *  </tbody>
104      * </table>
105      * Exec remote command over SSH. Return command execution status.
106      * Command output is written to out or err stream.
107      *
108      * @param ctx Reference to context memory
109      */
110
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();
117         try {
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");
127
128             if(status == DEF_SUCCESS_STATUS) {
129                 parser.parseOutput(ctx, stdoutRes);
130             }
131             ctx.setAttribute(PARAM_OUT_status, String.format("%01d", status));
132             ctx.setAttribute(PARAM_OUT_stdout, stdoutRes);
133             ctx.setAttribute(PARAM_OUT_stderr, stderrRes);
134         } finally {
135             sshConnection.disconnect();
136         }
137     }
138
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");
146         }
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");
150         }
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");
156         }
157         throw new SvcLogicException("SSH Auth type required, BASIC auth in support");
158     }
159
160
161     /**
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
164      * <table border="1">
165      *  <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th><th>example values</th></thead>
166      *  <tbody>
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>
186      *  </tbody>
187      * </table>
188      * Exec remote command over SSH. Return command execution status.
189      * Command output is written to out or err stream.
190      *
191      * @param ctx Reference to context memory
192      */
193
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(']');
206             }
207             throw new SvcLogicException(errmsg.toString());
208         }
209     }
210
211     /**
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
214      * <table border="1">
215      *  <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th><th>example values</th></thead>
216      *  <tbody>
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>
236      *  </tbody>
237      * </table>
238      * Exec remote command over SSH. Return command execution status.
239      * Command output is written to out or err stream.
240      *
241      * @param ctx Reference to context memory
242      */
243     public void execCommandWithPty(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
244
245     }
246 }