dependancy and tests cases added
[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) 2018 Samsung Electronics. All rights
8                         reserved.
9 *  * ================================================================================
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  * ============LICENSE_END=========================================================
23  */
24
25 package org.onap.ccsdk.sli.plugins.sshapicall;
26
27 //import com.fasterxml.jackson.databind.ObjectMapper;
28
29 import java.io.ByteArrayOutputStream;
30 import java.util.Collections;
31 import java.util.HashSet;
32 import java.util.Map;
33 import java.util.Set;
34
35 import com.google.common.base.Strings;
36 import org.json.JSONObject;
37 import org.onap.appc.adapter.ssh.SshAdapter;
38 import org.onap.appc.adapter.ssh.SshConnection;
39 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
40 import com.att.eelf.configuration.EELFLogger;
41 import com.att.eelf.configuration.EELFManager;
42 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
43 import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
44 import org.onap.ccsdk.sli.plugins.sshapicall.model.AuthType;
45 import org.onap.ccsdk.sli.plugins.sshapicall.model.Parameters;
46 import org.onap.ccsdk.sli.plugins.sshapicall.model.ParseParam;
47
48
49 public class SshApiCallNode implements SvcLogicJavaPlugin {
50
51     private static final EELFLogger logger = EELFManager.getInstance().getApplicationLogger();
52
53     /**
54      * Output parameter - SSH command execution status.
55      */
56     private String PARAM_OUT_status = "sshApi.call.node.status";
57
58     /**
59      * Output parameter - content of SSH command stdout.
60      */
61     private String PARAM_OUT_stdout = "sshApi.call.node.stdout";
62
63     /**
64      * Output parameter - content of SSH command stderr.
65      */
66     private String PARAM_OUT_stderr = "sshApi.call.node.stderr";
67
68     /**
69      * Default success status.
70      */
71     private int DEF_SUCCESS_STATUS = 0;
72
73     private SshAdapter sshAdapter;
74
75     public void setSshAdapter(SshAdapter sshAdapter) {
76         this.sshAdapter = sshAdapter;
77     }
78
79     /**
80      * Allows Directed Graphs  the ability to interact with SSH APIs.
81      * @param params HashMap<String,String> of parameters passed by the DG to this function
82      * <table border="1">
83      *  <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th><th>example values</th></thead>
84      *  <tbody>
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></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></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         execSshCommand(params, ctx, false);
113     }
114
115     private void execSshCommand(Map<String, String> params, SvcLogicContext ctx, boolean withPty) throws SvcLogicException {
116         ParseParam parser = new ParseParam();
117         Parameters p = parser.getParameters(params);
118         logger.debug("=> Connecting to SSH server...");
119         SshConnection sshConnection = null;
120         try {
121             sshConnection = getSshConnection(p);
122             sshConnection.connect();
123             logger.debug("=> Connected to SSH server...");
124             logger.debug("=> Running SSH command...");
125             sshConnection.setExecTimeout(p.sshExecTimeout);
126             ByteArrayOutputStream stdout = new ByteArrayOutputStream();
127             ByteArrayOutputStream stderr = new ByteArrayOutputStream();
128             int status;
129             if (withPty) {
130                 status = sshConnection.execCommandWithPty(parser.makeCommand(params), stdout);
131                 stderr = stdout;
132             }
133             else
134                 status = sshConnection.execCommand(parser.makeCommand(params), stdout, stderr);
135             String stdoutRes = stdout.toString();
136             String stderrRes = stderr.toString();
137             logger.debug("=> executed SSH command");
138
139             if(status == DEF_SUCCESS_STATUS) {
140                 parser.parseOutput(ctx, stdoutRes);
141             }
142             ctx.setAttribute(PARAM_OUT_status, String.format("%01d", status));
143             ctx.setAttribute(PARAM_OUT_stdout, stdoutRes);
144             ctx.setAttribute(PARAM_OUT_stderr, stderrRes);
145         } catch (Exception e){
146             throw new SvcLogicException("Exception in SSH adaptor : " + e.getMessage());
147         } finally {
148             if (sshConnection != null)
149                sshConnection.disconnect();
150         }
151     }
152
153     private SshConnection getSshConnection(Parameters p) throws SvcLogicException {
154         if (p.authtype == AuthType.BASIC)
155             return sshAdapter.getConnection(p.sshapiUrl, p.sshapiPort, p.sshapiUser, p.sshapiPassword);
156         // This is not supported yet in the API, patch has already been added to APPC
157         else if (p.authtype == AuthType.KEY){
158             //return sshAdapter.getConnection(p.sshapiUrl, p.sshapiPort, p.sshKey);
159             throw new SvcLogicException("SSH Key based Auth method not supported");
160         }
161         else if (p.authtype == AuthType.NONE){
162             //return sshAdapter.getConnection(p.sshapiUrl, p.sshapiPort, p.sshKey);
163             throw new SvcLogicException("SSH Auth type required, BASIC auth in support");
164         }
165         else if (p.authtype == AuthType.UNSPECIFIED){
166             if (p.sshapiUser != null && p.sshapiPassword != null)
167                 return sshAdapter.getConnection(p.sshapiUrl, p.sshapiPort, p.sshapiUser, p.sshapiPassword);
168             else if (p.sshKey != null)
169                 throw new SvcLogicException("SSH Key based Auth method not supported");
170         }
171         throw new SvcLogicException("SSH Auth type required, BASIC auth in support");
172     }
173
174
175     /**
176      * Allows Directed Graphs  the ability to interact with SSH APIs.
177      * @param params HashMap<String,String> of parameters passed by the DG to this function
178      * <table border="1">
179      *  <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th><th>example values</th></thead>
180      *  <tbody>
181      *      <tr><td>Url</td><td>Mandatory</td><td>url to make the SSH connection request to.</td></tr>
182      *      <tr><td>Port</td><td>Mandatory</td><td>port to make the SSH connection request to.</td></tr>
183      *      <tr><td>User</td><td>Optional</td><td>user name to use for ssh basic authentication</td><td>sdnc_ws</td></tr>
184      *      <tr><td>Password</td><td>Optional</td><td>unencrypted password to use for ssh basic authentication</td><td>plain_password</td></tr>
185      *      <tr><td>SshKey</td><td>Optional</td><td>Consumer SSH key to use for ssh authentication</td><td>plain_key</td></tr>
186      *      <tr><td>ExecTimeout</td><td>Optional</td><td>SSH command execution timeout</td><td>plain_key</td></tr>
187      *      <tr><td>Retry</td><td>Optional</td><td>Make ssh connection with default retry policy</td><td>plain_key</td></tr>
188      *      <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>
189      *      <tr><td>ResponsePrefix</td><td>Optional</td><td>location the response will be written to in context memory</td></tr>
190      *      <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></tr>
191      *      <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>
192      *      <tr><td>ConvertResponse </td><td>Optional</td><td>whether the response should be converted</td><td>true or false</td></tr>
193      *      <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>
194      *      <tr><td>EnvParameters</td><td>Optional</td><td>A JSON dictionary which should list key value pairs to be passed to the command execution.
195      *               These values would correspond to instance specific parameters that a command may need to execute an action.</td></tr>
196      *      <tr><td>FileParameters</td><td>Optional</td><td>A JSON dictionary where keys are filenames and values are contents of files.
197      *               The SSH Server will utilize this feature to generate files with keys as filenames and values as content.
198      *               This attribute can be used to generate files that a command may require as part of execution.</td></tr>
199      *  </tbody>
200      * </table>
201      * Exec remote command over SSH. Return command execution status.
202      * Command output is written to out or err stream.
203      *
204      * @param ctx Reference to context memory
205      */
206
207     public void execWithStatusCheck(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
208         execCommand(params, ctx);
209         ParseParam parser = new ParseParam();
210         String responsePrefix = parser.getStringParameters(params, parser.SSH_ResponsePrefix);
211         parseResponse(ctx, responsePrefix);
212     }
213
214     private void parseResponse (SvcLogicContext ctx, String responsePrefix) throws SvcLogicException {
215         int status = Integer.parseInt(ctx.getAttribute(PARAM_OUT_status));
216         if(status != DEF_SUCCESS_STATUS) {
217             StringBuilder errmsg = new StringBuilder();
218             errmsg.append("SSH command returned error status [").append(status).append(']');
219             String stderr = ctx.getAttribute(PARAM_OUT_stderr);
220             if((stderr != null) && !stderr.isEmpty()) {
221                 errmsg.append(". Error: [").append(stderr).append(']');
222             }
223             throw new SvcLogicException(errmsg.toString());
224         }
225     }
226
227     /**
228      * Allows Directed Graphs  the ability to interact with SSH APIs.
229      * @param params HashMap<String,String> of parameters passed by the DG to this function
230      * <table border="1">
231      *  <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th><th>example values</th></thead>
232      *  <tbody>
233      *      <tr><td>Url</td><td>Mandatory</td><td>url to make the SSH connection request to.</td></tr>
234      *      <tr><td>Port</td><td>Mandatory</td><td>port to make the SSH connection request to.</td></tr>
235      *      <tr><td>User</td><td>Optional</td><td>user name to use for ssh basic authentication</td><td>sdnc_ws</td></tr>
236      *      <tr><td>Password</td><td>Optional</td><td>unencrypted password to use for ssh basic authentication</td><td>plain_password</td></tr>
237      *      <tr><td>SshKey</td><td>Optional</td><td>Consumer SSH key to use for ssh authentication</td><td>plain_key</td></tr>
238      *      <tr><td>ExecTimeout</td><td>Optional</td><td>SSH command execution timeout</td><td>plain_key</td></tr>
239      *      <tr><td>Retry</td><td>Optional</td><td>Make ssh connection with default retry policy</td><td>plain_key</td></tr>
240      *      <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>
241      *      <tr><td>ResponsePrefix</td><td>Optional</td><td>location the response will be written to in context memory</td></tr>
242      *      <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></tr>
243      *      <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>
244      *      <tr><td>ConvertResponse </td><td>Optional</td><td>whether the response should be converted</td><td>true or false</td></tr>
245      *      <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>
246      *      <tr><td>EnvParameters</td><td>Optional</td><td>A JSON dictionary which should list key value pairs to be passed to the command execution.
247      *               These values would correspond to instance specific parameters that a command may need to execute an action.</td></tr>
248      *      <tr><td>FileParameters</td><td>Optional</td><td>A JSON dictionary where keys are filenames and values are contents of files.
249      *               The SSH Server will utilize this feature to generate files with keys as filenames and values as content.
250      *               This attribute can be used to generate files that a command may require as part of execution.</td></tr>
251      *  </tbody>
252      * </table>
253      * Exec remote command over SSH. Return command execution status.
254      * Command output is written to out or err stream.
255      *
256      * @param ctx Reference to context memory
257      */
258     public void execCommandWithPty(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
259         execSshCommand(params, ctx, true);
260     }
261 }