SSHApiCallNode sshExec API Impl
[ccsdk/sli/plugins.git] / sshapi-call-node / provider / src / main / java / org / onap / ccsdk / sli / plugins / sshapicall / model / ParseParam.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : SDN-C
4  * ================================================================================
5  * * Copyright (C) 2017 AT&T Intellectual Property.
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  * ============LICENSE_END=========================================================
22  */
23
24 package org.onap.ccsdk.sli.plugins.sshapicall.model;
25
26 import com.google.common.base.Strings;
27 import org.json.JSONException;
28 import org.json.JSONObject;
29 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
30 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 import java.io.ByteArrayInputStream;
35 import java.io.ByteArrayOutputStream;
36 import java.io.File;
37 import java.io.FileInputStream;
38 import java.io.FileNotFoundException;
39 import java.io.IOException;
40 import java.io.InputStream;
41 import java.nio.charset.StandardCharsets;
42 import java.util.Collections;
43 import java.util.HashSet;
44 import java.util.Map;
45 import java.util.Properties;
46 import java.util.Set;
47
48 public class ParseParam {
49     private static final Logger log = LoggerFactory.getLogger(ParseParam.class);
50     /**
51      * Default SSH command timeout
52      */
53     private long dEF_timeout = 12000;
54     /**
55      * Default SSH connection port.
56      */
57     private int dEF_port = 22;
58     /**
59      * Default SSH command timeout
60      */
61     private final String FILE_PARAMETERS_OPT_KEY = "FileParameters";
62     /**
63      * Default SSH connection port.
64      */
65     private final String ENV_PARAMETERS_OPT_KEY = "EnvParameters";
66     private Parameters p = new Parameters();
67
68     public Parameters getParameters(Map<String, String> paramMap) throws SvcLogicException {
69         p.sshapiUrl = parseParam(paramMap, "Url", true, null);
70         p.sshapiPort = Integer.parseInt(parseParam(paramMap, "Port", true, Integer.toString(dEF_port)));
71         p.sshapiUser = parseParam(paramMap, "User", false, null);
72         p.sshapiPassword = parseParam(paramMap, "Password", false, null);
73         p.sshKey = parseParam(paramMap, "SshKey", false, null);
74         p.sshExecTimeout = Long.parseLong(parseParam(paramMap, "ExecTimeout", false, Long.toString(dEF_timeout)));
75         p.sshWithRetry = Boolean.valueOf(parseParam(paramMap, "Retry", false, "false"));
76         p.cmd = parseParam(paramMap, "Cmd", true, null);
77         p.responsePrefix = parseParam(paramMap, "ResponsePrefix", false, null);
78         p.responseType = Format.fromString(parseParam(paramMap, "ResponseType", false, "none"));
79         p.listNameList = getListNameList(paramMap);
80         p.convertResponse = Boolean.valueOf(parseParam(paramMap, "ConvertResponse", false, "true"));
81         p.authtype = AuthType.fromString(parseParam(paramMap, "AuthType", false, "unspecified"));
82
83         return p;
84     }
85
86     public void parseOutput (SvcLogicContext ctx, String outMessage) throws SvcLogicException {
87         if (p.convertResponse) {
88             if (p.responseType == Format.NONE) {
89                 classifyOutput(ctx, outMessage);
90             } else if (p.responseType == Format.JSON) {
91                 classifyOutput(ctx, outMessage);
92             } else if (p.responseType == Format.XML) {
93                 classifyOutput(ctx, outMessage, p.listNameList);
94             }
95         }
96     }
97
98     private void classifyOutput(SvcLogicContext ctx, String outMessage, Set<String> listNameList) throws SvcLogicException {
99         Map<String, String> mm = XmlParser.convertToProperties(outMessage, p.listNameList);
100         toCtx (ctx, mm);
101     }
102
103     private void toCtx (SvcLogicContext ctx, Map<String, String> mm) {
104         if (mm != null) {
105             for (Map.Entry<String, String> entry : mm.entrySet()) {
106                 if (p.responsePrefix != null) {
107                     ctx.setAttribute(p.responsePrefix + "." + entry.getKey(), entry.getValue());
108                     log.info("+++ " + p.responsePrefix + "." + entry.getKey() + ": [" + entry.getValue() + "]");
109                 } else {
110                     ctx.setAttribute(entry.getKey(), entry.getValue());
111                     log.info("+++ " + entry.getKey() + ": [" + entry.getValue() + "]");
112                 }
113             }
114         }
115     }
116
117     private void classifyOutput(SvcLogicContext ctx, String outMessage) throws SvcLogicException {
118         try {
119             Map<String, String> mm = JsonParser.convertToProperties(outMessage);
120             toCtx (ctx, mm);
121         } catch (org.codehaus.jettison.json.JSONException e) {
122             log.info("Output not in JSON format");
123             putToProperties(ctx, p.responsePrefix);
124         } catch (Exception e) {
125             throw  new SvcLogicException("error parsing response file");
126         }
127     }
128
129     private void putToProperties(SvcLogicContext ctx, String outMessage) throws SvcLogicException {
130
131         try {
132             Properties prop = new Properties();
133             prop.load(new ByteArrayInputStream(outMessage.getBytes(StandardCharsets.UTF_8)));
134             for (Object key : prop.keySet()) {
135                 String name = (String) key;
136                 String value = prop.getProperty(name);
137                 if (value != null && value.trim().length() > 0) {
138                     if (p.responsePrefix != null) {
139                         ctx.setAttribute(p.responsePrefix + "." + name, value.trim());
140                         log.info("+++ " + p.responsePrefix + "." + name + ": [" + value + "]");
141                     } else {
142                         ctx.setAttribute(name, value.trim());
143                         log.info("+++ " + name + ": [" + value + "]");
144                     }
145                 }
146             }
147         } catch (Exception e) {
148             throw  new SvcLogicException( "Error parsing response file.");
149         }
150     }
151
152     public String makeCommand (Map<String, String> params) {
153         JSONObject jsonPayload = new JSONObject();
154         final String[] optionalTestParams = {ENV_PARAMETERS_OPT_KEY, FILE_PARAMETERS_OPT_KEY};
155         parseParam(params, optionalTestParams, jsonPayload);
156         JSONObject envParams = (JSONObject) jsonPayload.remove(ENV_PARAMETERS_OPT_KEY);
157         JSONObject fileParams = (JSONObject) jsonPayload.remove(FILE_PARAMETERS_OPT_KEY);
158
159         StringBuilder constructedCommand = new StringBuilder();
160         constructedCommand.append(parseFileParam(fileParams)).append(p.cmd).append(" ").append(parseEnvParam(envParams));
161
162         return constructedCommand.toString();
163     }
164
165     private String parseEnvParam(JSONObject envParams) {
166         StringBuilder envParamBuilder = new StringBuilder();
167         if (envParams != null) {
168             for (Object key : envParams.keySet()) {
169                 if (envParamBuilder.length() > 0) {
170                     envParamBuilder.append(", ");
171                 }
172                 envParamBuilder.append(key + "=" + envParams.get((String) key));
173             }
174         }
175         return envParamBuilder.toString();
176     }
177
178     private String parseFileParam(JSONObject fileParams) {
179         StringBuilder fileParamBuilder = new StringBuilder();
180         if (fileParams != null) {
181             for (Object key : fileParams.keySet()) {
182                 fileParamBuilder.append("echo -e \"" + fileParams.get((String) key) + "\" > /srv/salt/" + key).append("; ");
183             }
184         }
185         return fileParamBuilder.toString();
186     }
187
188     private void parseParam(Map<String, String> params, String[] optionalTestParams, JSONObject jsonPayload)
189             throws JSONException {
190
191         Set<String> optionalParamsSet = new HashSet<>();
192         Collections.addAll(optionalParamsSet, optionalTestParams);
193
194         //@formatter:off
195         params.entrySet()
196                 .stream()
197                 .filter(entry -> optionalParamsSet.contains(entry.getKey()))
198                 .filter(entry -> !Strings.isNullOrEmpty(entry.getValue()))
199                 .forEach(entry -> parseParam(entry, jsonPayload));
200         //@formatter:on
201     }
202
203     private void parseParam(Map.Entry<String, String> params, JSONObject jsonPayload)
204             throws JSONException {
205         String key = params.getKey();
206         String payload = params.getValue();
207
208         switch (key) {
209             case ENV_PARAMETERS_OPT_KEY:
210                 JSONObject paramsJson = new JSONObject(payload);
211                 jsonPayload.put(key, paramsJson);
212                 break;
213
214             case FILE_PARAMETERS_OPT_KEY:
215                 jsonPayload.put(key, getFilePayload(payload));
216                 break;
217
218             default:
219                 break;
220         }
221     }
222
223     /**
224      * Return payload with escaped newlines
225      */
226     private JSONObject getFilePayload(String payload) {
227         String formattedPayload = payload.replace("\n", "\\n").replace("\r", "\\r");
228         return new JSONObject(formattedPayload);
229     }
230
231     private Set<String> getListNameList(Map<String, String> paramMap) {
232         Set<String> ll = new HashSet<>();
233         for (Map.Entry<String,String> entry : paramMap.entrySet())
234             if (entry.getKey().startsWith("listName"))
235                 ll.add(entry.getValue());
236         return ll;
237     }
238
239     private String parseParam(Map<String, String> paramMap, String name, boolean required, String def)
240             throws SvcLogicException {
241         String s = paramMap.get(name);
242
243         if (s == null || s.trim().length() == 0) {
244             if (!required)
245                 return def;
246             throw new SvcLogicException("Parameter " + name + " is required in sshapiCallNode");
247         }
248
249         s = s.trim();
250         StringBuilder value = new StringBuilder();
251         int i = 0;
252         int i1 = s.indexOf('%');
253         while (i1 >= 0) {
254             int i2 = s.indexOf('%', i1 + 1);
255             if (i2 < 0)
256                 break;
257
258             String varName = s.substring(i1 + 1, i2);
259             String varValue = System.getenv(varName);
260             if (varValue == null)
261                 varValue = "%" + varName + "%";
262
263             value.append(s.substring(i, i1));
264             value.append(varValue);
265
266             i = i2 + 1;
267             i1 = s.indexOf('%', i);
268         }
269         value.append(s.substring(i));
270
271         log.info("Parameter {}: [{}]", name, value);
272         return value.toString();
273     }
274 }