2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 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 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 * ============LICENSE_END=========================================================
25 package org.openecomp.appc.adapter.chef.impl;
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.List;
32 import java.util.Properties;
34 import java.util.regex.Pattern;
38 import org.openecomp.appc.Constants;
39 import org.openecomp.appc.adapter.chef.ChefAdapter;
40 import org.openecomp.appc.adapter.chef.chefapi.*;
41 import org.openecomp.appc.adapter.chef.chefclient.*;
42 import org.openecomp.appc.configuration.Configuration;
43 import org.openecomp.appc.configuration.ConfigurationFactory;
44 import org.openecomp.appc.exceptions.APPCException;
45 import org.openecomp.appc.exceptions.UnknownProviderException;
46 import org.openecomp.appc.i18n.Msg;
47 import org.openecomp.appc.pool.Pool;
48 import org.openecomp.appc.pool.PoolExtensionException;
49 import org.openecomp.appc.util.StructuredPropertyHelper;
50 import org.openecomp.appc.util.StructuredPropertyHelper.Node;
51 import com.att.cdp.exceptions.ContextConnectionException;
52 import com.att.cdp.exceptions.ResourceNotFoundException;
53 import com.att.cdp.exceptions.TimeoutException;
54 import com.att.cdp.exceptions.ZoneException;
55 import com.att.cdp.pal.util.StringHelper;
56 import com.att.cdp.zones.ComputeService;
57 import com.att.cdp.zones.Context;
58 import com.att.cdp.zones.ImageService;
59 import com.att.cdp.zones.Provider;
60 import com.att.cdp.zones.model.Image;
61 import com.att.cdp.zones.model.Server;
62 import com.att.cdp.zones.model.ServerBootSource;
63 import com.att.cdp.zones.model.Server.Status;
64 import com.att.eelf.configuration.EELFLogger;
65 import com.att.eelf.configuration.EELFManager;
66 import com.att.eelf.i18n.EELFResourceManager;
67 import org.openecomp.sdnc.sli.SvcLogicContext;
70 import java.net.InetAddress;
71 import java.util.Locale;
72 import java.util.UUID;
74 import org.apache.http.*;
75 import org.apache.http.client.*;
76 import org.apache.http.client.methods.*;
77 import org.apache.http.impl.client.*;
78 import org.apache.http.util.EntityUtils;
80 import static com.att.eelf.configuration.Configuration.*;
82 import java.io.IOException;
84 import java.net.InetAddress;
86 import java.io.BufferedInputStream;
88 import java.io.FileInputStream;
89 import java.io.FileOutputStream;
90 import java.io.IOException;
91 import java.io.InputStream;
92 import java.io.OutputStream;
93 import java.util.Properties;
95 import org.openecomp.appc.adapter.chef.chefapi.*;
96 import org.openecomp.appc.adapter.chef.chefclient.*;
99 import org.json.JSONArray;
100 import org.json.JSONException;
101 import org.json.JSONObject;
103 * This class implements the {@link ChefAdapter} interface. This interface
104 * defines the behaviors that our service provides.
106 public class ChefAdapterImpl implements ChefAdapter {
108 // chef server Initialize variable
109 public String clientName = "";
110 public String clientPrivatekey = "";
111 public String chefserver = "";
112 public String serverAddress = "";
113 public String organizations = "";
114 @SuppressWarnings("nls")
115 public static final String MDC_ADAPTER = "adapter";
117 @SuppressWarnings("nls")
118 public static final String MDC_SERVICE = "service";
120 @SuppressWarnings("nls")
121 public static final String OUTCOME_FAILURE = "failure";
123 @SuppressWarnings("nls")
124 public static final String OUTCOME_SUCCESS = "success";
126 @SuppressWarnings("nls")
127 public static final String PROPERTY_PROVIDER = "provider";
129 @SuppressWarnings("nls")
130 public static final String PROPERTY_PROVIDER_IDENTITY = "identity";
132 @SuppressWarnings("nls")
133 public static final String PROPERTY_PROVIDER_NAME = "name";
135 @SuppressWarnings("nls")
136 public static final String PROPERTY_PROVIDER_TENANT = "tenant";
138 @SuppressWarnings("nls")
139 public static final String PROPERTY_PROVIDER_TENANT_NAME = "name";
141 @SuppressWarnings("nls")
142 public static final String PROPERTY_PROVIDER_TENANT_PASSWORD = "password"; // NOSONAR
144 @SuppressWarnings("nls")
145 public static final String PROPERTY_PROVIDER_TENANT_USERID = "userid";
147 @SuppressWarnings("nls")
148 public static final String PROPERTY_PROVIDER_TYPE = "type";
151 private static final EELFLogger logger = EELFManager.getInstance().getLogger(ChefAdapterImpl.class);
153 private static final char LPAREN = '(';
155 private static final char NL = '\n';
157 private static final char QUOTE = '\'';
159 private static final char RPAREN = ')';
161 private static final char SPACE = ' ';
163 public ChefAdapterImpl() {
168 public ChefAdapterImpl(boolean initialize) {
176 public ChefAdapterImpl(Properties props) {
181 public ChefAdapterImpl(String key) {
188 public String getAdapterName() {
189 return "chef adapter";
193 @SuppressWarnings("nls")
195 public void VnfcEnvironment(Map<String, String> params, SvcLogicContext ctx) {
196 logger.info("environment of VNF-C");
198 RequestContext rc = new RequestContext(ctx);
200 String env = params.get("Environment");
202 chefServerResult(rc, "200", "Skip Environment block ");}
204 JSONObject env_J = new JSONObject(env);
205 String envName = env_J.getString("name");
207 String message = null;
208 if (privateKeyCheck()) {
209 // update the details of an environment on the Chef server.
210 ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations);
211 ApiMethod am = cac.put("/environments/"+envName).body(env);
213 code = am.getReturnCode();
214 message = am.getResponseBodyAsString();
216 //need create a new environment
217 am = cac.post("/environments").body(env);
219 code = am.getReturnCode();
220 message = am.getResponseBodyAsString();
225 message = "Cannot find the private key in the APPC file system, please load the private key to "
228 chefServerResult(rc, Integer.toString(code), message);
233 @SuppressWarnings("nls")
235 public void VnfcNodeobjects(Map<String, String> params, SvcLogicContext ctx) {
236 logger.info("update the nodeObjects of VNF-C");
238 String nodeList_S = params.get("NodeList");
239 String node_S = params.get("Node");
240 nodeList_S = nodeList_S.replace("[","");
241 nodeList_S = nodeList_S.replace("]","");
242 nodeList_S = nodeList_S.replace("\"","");
243 nodeList_S = nodeList_S.replace(" ","");
244 List<String> nodes = Arrays.asList(nodeList_S.split("\\s*,\\s*"));
245 RequestContext rc = new RequestContext(ctx);
248 String message = null;
249 if (privateKeyCheck()) {
250 ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations);
252 for(int i = 0; i < nodes.size(); i++){
253 String nodeName=nodes.get(i);
254 JSONObject node_J = new JSONObject(node_S);
255 node_J.remove("name");
256 node_J.put("name",nodeName);
257 String nodeObject=node_J.toString();
258 logger.info(nodeObject);
259 ApiMethod am = cac.put("/nodes/"+nodeName).body(nodeObject);
261 code = am.getReturnCode();
262 message = am.getResponseBodyAsString();
270 message = "Cannot find the private key in the APPC file system, please load the private key to "
273 chefServerResult(rc, Integer.toString(code), message);
277 @SuppressWarnings("nls")
279 public void VnfcPushJob(Map<String, String> params, SvcLogicContext ctx) {
281 String nodeList = params.get("NodeList");
282 String isCallback = params.get("CallbackCapable");
283 String chefAction = "/pushy/jobs";
285 String pushRequest="";
286 if(isCallback.equals("true")){
287 String requestId = params.get("RequestId");
288 String callbackUrl = params.get("CallbackUrl");
290 "\"command\": \"chef-client\","+
291 "\"run_timeout\": 300,"+
292 "\"nodes\":" +nodeList +","+
293 "\"env\": {\"RequestId\": \""+ requestId +"\", \"CallbackUrl\": \""+ callbackUrl +"\"},"+
294 "\"capture_output\": true"+
298 "\"command\": \"chef-client\","+
299 "\"run_timeout\": 300,"+
300 "\"nodes\":" +nodeList +","+
302 "\"capture_output\": true"+
305 RequestContext rc = new RequestContext(ctx);
308 SvcLogicContext svcLogic = rc.getSvcLogicContext();
309 ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations);
310 ApiMethod am = cac.post(chefAction).body(pushRequest);
313 int code = am.getReturnCode();
314 String message = am.getResponseBodyAsString();
316 int startIndex = message.indexOf("jobs") + 5;
317 int endIndex = message.length() - 2;
318 String jobID = message.substring(startIndex, endIndex);
319 svcLogic.setAttribute("jobID", jobID);
322 chefServerResult(rc, Integer.toString(code), message);
326 @SuppressWarnings("nls")
328 public void fetchResults (Map<String, String> params, SvcLogicContext ctx) {
330 String nodeList_S = params.get("NodeList");
331 nodeList_S = nodeList_S.replace("[","");
332 nodeList_S = nodeList_S.replace("]","");
333 nodeList_S = nodeList_S.replace("\"","");
334 nodeList_S = nodeList_S.replace(" ","");
335 List<String> nodes = Arrays.asList(nodeList_S.split("\\s*,\\s*"));
336 JSONObject Result = new JSONObject();
337 String returnCode= "200";
338 String returnMessage="";
339 for (int i = 0; i < nodes.size(); i++){
340 String node=nodes.get(i);
341 String chefAction="/nodes/"+node;
343 String message = null;
344 if (privateKeyCheck()) {
345 ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations);
346 ApiMethod am = cac.get(chefAction);
348 code = am.getReturnCode();
349 message = am.getResponseBodyAsString();
352 message = "Cannot find the private key in the APPC file system, please load the private key to "
356 JSONObject nodeResult = new JSONObject();
357 JSONObject allNodeData = new JSONObject(message);
358 String attribute= "PushJobOutput";
360 allNodeData=allNodeData.getJSONObject("normal");
362 resultData = allNodeData.getString(attribute);
363 } catch (Exception exc1) {
365 resultData = allNodeData.getJSONObject(attribute).toString();
366 } catch (Exception exc2) {
368 resultData = allNodeData.getJSONArray(attribute).toString();
369 }catch (Exception exc3){
371 returnMessage="cannot find "+attribute;
376 nodeResult.put(attribute,resultData);
378 Result.put(node,nodeResult);
381 returnMessage = message+" Cannot access: "+ node;
386 RequestContext rc = new RequestContext(ctx);
388 if (!returnCode.equals("500")){
389 returnMessage=Result.toString();
392 chefServerResult(rc, returnCode, returnMessage);
401 @SuppressWarnings("nls")
403 public void nodeObejctBuilder(Map<String, String> params, SvcLogicContext ctx) {
404 logger.info("nodeObejctBuilder");
405 String name = params.get("org.openecomp.appc.instance.nodeobject.name");
406 String normal = params.get("org.openecomp.appc.instance.nodeobject.normal");
407 String overrides = params.get("org.openecomp.appc.instance.nodeobject.overrides");
408 String defaults = params.get("org.openecomp.appc.instance.nodeobject.defaults");
409 String run_list = params.get("org.openecomp.appc.instance.nodeobject.run_list");
410 String chef_environment = params.get("org.openecomp.appc.instance.nodeobject.chef_environment");
411 String nodeObject = "{\"json_class\":\"Chef::Node\",\"default\":{" + defaults
412 + "},\"chef_type\":\"node\",\"run_list\":[" + run_list + "],\"override\":{" + overrides
413 + "},\"normal\": {" + normal + "},\"automatic\":{},\"name\":\"" + name + "\",\"chef_environment\":\""
414 + chef_environment + "\"}";
415 logger.info(nodeObject);
417 RequestContext rc = new RequestContext(ctx);
419 SvcLogicContext svcLogic = rc.getSvcLogicContext();
420 svcLogic.setAttribute("org.openecomp.appc.chef.nodeObject", nodeObject);
425 * Nicolas send get request to chef server
428 public void chefInfo(Map<String, String> params) {
429 clientName = params.get("org.openecomp.appc.instance.username");
430 serverAddress = params.get("org.openecomp.appc.instance.serverAddress");
431 organizations = params.get("org.openecomp.appc.instance.organizations");
432 chefserver = "https://" + serverAddress + "/organizations/" + organizations;
433 clientPrivatekey = "/opt/app/bvc/chef/" + serverAddress + "/" + organizations + "/" + clientName + ".pem";
436 public Boolean privateKeyCheck() {
437 File f = new File(clientPrivatekey);
445 @SuppressWarnings("nls")
447 public void retrieveData(Map<String, String> params, SvcLogicContext ctx) {
448 String contextData = "someValue";
449 String allConfigData = params.get("org.openecomp.appc.instance.allConfig");
450 String key = params.get("org.openecomp.appc.instance.key");
451 String dgContext = params.get("org.openecomp.appc.instance.dgContext");
452 JSONObject josnConfig = new JSONObject(allConfigData);
454 contextData = josnConfig.getString(key);
455 } catch (Exception ex) {
457 contextData = josnConfig.getJSONObject(key).toString();
458 } catch (Exception exc) {
459 contextData = josnConfig.getJSONArray(key).toString();
463 RequestContext rc = new RequestContext(ctx);
465 SvcLogicContext svcLogic = rc.getSvcLogicContext();
466 svcLogic.setAttribute(dgContext, contextData);
469 @SuppressWarnings("nls")
471 public void combineStrings(Map<String, String> params, SvcLogicContext ctx) {
473 String String1 = params.get("org.openecomp.appc.instance.String1");
474 String String2 = params.get("org.openecomp.appc.instance.String2");
475 String dgContext = params.get("org.openecomp.appc.instance.dgContext");
476 String contextData = String1 + String2;
477 RequestContext rc = new RequestContext(ctx);
479 SvcLogicContext svcLogic = rc.getSvcLogicContext();
480 svcLogic.setAttribute(dgContext, contextData);
485 * Send GET request to chef server
488 @SuppressWarnings("nls")
490 public void chefGet(Map<String, String> params, SvcLogicContext ctx) {
491 logger.info("chef get method");
493 String chefAction = params.get("org.openecomp.appc.instance.chefAction");
494 RequestContext rc = new RequestContext(ctx);
497 String message = null;
498 if (privateKeyCheck()) {
499 ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations);
500 ApiMethod am = cac.get(chefAction);
502 code = am.getReturnCode();
503 message = am.getResponseBodyAsString();
506 message = "Cannot find the private key in the APPC file system, please load the private key to "
509 chefServerResult(rc, Integer.toString(code), message);
514 * send put request to chef server
517 @SuppressWarnings("nls")
519 public void chefPut(Map<String, String> params, SvcLogicContext ctx) {
521 String chefAction = params.get("org.openecomp.appc.instance.chefAction");
522 String CHEF_NODE_STR = params.get("org.openecomp.appc.instance.chefRequestBody");
523 RequestContext rc = new RequestContext(ctx);
526 String message = null;
527 if (privateKeyCheck()) {
528 ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations);
530 ApiMethod am = cac.put(chefAction).body(CHEF_NODE_STR);
532 code = am.getReturnCode();
533 message = am.getResponseBodyAsString();
536 message = "Cannot find the private key in the APPC file system, please load the private key to "
539 logger.info(code + " " + message);
540 chefServerResult(rc, Integer.toString(code), message);
545 * Nicolas send Post request to chef server
548 @SuppressWarnings("nls")
550 public void chefPost(Map<String, String> params, SvcLogicContext ctx) {
552 logger.info("chef Post method");
553 logger.info(clientName + " " + clientPrivatekey + " " + chefserver + " " + organizations);
554 String CHEF_NODE_STR = params.get("org.openecomp.appc.instance.chefRequestBody");
555 String chefAction = params.get("org.openecomp.appc.instance.chefAction");
557 // attributes="\"reconfig-test\":{\"secret\":\"newpass2\"}";
558 // String CHEF_NODE_STR =
559 // "{\"json_class\":\"Chef::Node\",\"default\":{},\"chef_type\":\"node\",\"run_list\":[\""+runList+"\"],\"override\":{},\"automatic\":{},\"normal\":{"+attributes+"},\"name\":\"testnode\",\"chef_environment\":\"_default\"}";
560 // String CHEF_NODE_STR = "{\"json_class\":\"Chef::Node\"}";
561 // logger.info(vm_url);
562 RequestContext rc = new RequestContext(ctx);
565 String message = null;
566 // should load pem from somewhere else
567 if (privateKeyCheck()) {
568 ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations);
570 // need pass path into it
572 ApiMethod am = cac.post(chefAction).body(CHEF_NODE_STR);
574 code = am.getReturnCode();
575 message = am.getResponseBodyAsString();
578 message = "Cannot find the private key in the APPC file system, please load the private key to "
581 logger.info(code + " " + message);
582 chefServerResult(rc, Integer.toString(code), message);
586 * Nicolas send delete request to chef server
589 @SuppressWarnings("nls")
591 public void chefDelete(Map<String, String> params, SvcLogicContext ctx) {
592 logger.info("chef delete method");
594 String chefAction = params.get("org.openecomp.appc.instance.chefAction");
595 RequestContext rc = new RequestContext(ctx);
598 String message = null;
599 if (privateKeyCheck()) {
600 ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations);
601 ApiMethod am = cac.delete(chefAction);
603 code = am.getReturnCode();
604 message = am.getResponseBodyAsString();
607 message = "Cannot find the private key in the APPC file system, please load the private key to "
610 logger.info(code + " " + message);
611 chefServerResult(rc, Integer.toString(code), message);
619 @SuppressWarnings("nls")
621 public void trigger(Map<String, String> params, SvcLogicContext ctx) {
622 logger.info("Run trigger method");
623 String tVmIp = params.get("ip");
624 // String tUrl = "http://" + tVmIp;
625 RequestContext rc = new RequestContext(ctx);
628 HttpGet httpGet = new HttpGet(tVmIp);
629 try ( CloseableHttpClient httpClient = HttpClients.createDefault();
630 CloseableHttpResponse response = httpClient.execute(httpGet); )
632 int responseCode = response.getStatusLine().getStatusCode();
633 HttpEntity entity = response.getEntity();
634 String responseOutput = EntityUtils.toString(entity);
635 chefClientResult(rc, Integer.toString(responseCode), responseOutput);
637 } catch (Exception ex) {
638 doFailure(rc, 500, ex.toString());
645 @SuppressWarnings("nls")
647 public void checkPushJob(Map<String, String> params, SvcLogicContext ctx) {
649 String jobID = params.get("org.openecomp.appc.instance.jobid");
650 int retryTimes = Integer.parseInt(params.get("org.openecomp.appc.instance.retryTimes"));
651 int retryInterval = Integer.parseInt(params.get("org.openecomp.appc.instance.retryInterval"));
652 String chefAction = "/pushy/jobs/" + jobID;
654 RequestContext rc = new RequestContext(ctx);
656 SvcLogicContext svcLogic = rc.getSvcLogicContext();
659 for (int i = 0; i < retryTimes; i++) {
661 Thread.sleep(retryInterval); // 1000 milliseconds is one second.
662 } catch (InterruptedException ex) {
663 Thread.currentThread().interrupt();
665 ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations);
666 ApiMethod am = cac.get(chefAction);
668 int code = am.getReturnCode();
669 message = am.getResponseBodyAsString();
670 JSONObject obj = new JSONObject(message);
671 status = obj.getString("status");
672 if (!status.equals("running")) {
673 logger.info(i + " time " + code + " " + status);
678 if (status.equals("complete")) {
679 svcLogic.setAttribute("org.openecomp.appc.chefServerResult.code", "200");
680 svcLogic.setAttribute("org.openecomp.appc.chefServerResult.message", message);
682 if (status.equals("running")) {
683 svcLogic.setAttribute("org.openecomp.appc.chefServerResult.code", "202");
684 svcLogic.setAttribute("org.openecomp.appc.chefServerResult.message", "chef client runtime out");
686 svcLogic.setAttribute("org.openecomp.appc.chefServerResult.code", "500");
687 svcLogic.setAttribute("org.openecomp.appc.chefServerResult.message", message);
693 @SuppressWarnings("nls")
695 public void pushJob(Map<String, String> params, SvcLogicContext ctx) {
697 String pushRequest = params.get("org.openecomp.appc.instance.pushRequest");
698 String chefAction = "/pushy/jobs";
699 RequestContext rc = new RequestContext(ctx);
701 SvcLogicContext svcLogic = rc.getSvcLogicContext();
702 ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations);
703 ApiMethod am = cac.post(chefAction).body(pushRequest);
706 int code = am.getReturnCode();
707 String message = am.getResponseBodyAsString();
709 int startIndex = message.indexOf("jobs") + 6;
710 int endIndex = message.length() - 2;
711 String jobID = message.substring(startIndex, endIndex);
712 svcLogic.setAttribute("org.openecomp.appc.jobID", jobID);
715 chefServerResult(rc, Integer.toString(code), message);
718 @SuppressWarnings("static-method")
719 private void doFailure(RequestContext rc, int code, String message) {
720 SvcLogicContext svcLogic = rc.getSvcLogicContext();
721 String msg = (message == null) ? Integer.toString(code) : message;
722 if (msg.contains("\n")) {
723 msg = msg.substring(msg.indexOf("\n"));
728 status = Integer.toString(code);
729 } catch (Exception e) {
732 svcLogic.setAttribute("chefAgent.code", status);
733 svcLogic.setAttribute("chefAgent.message", msg);
737 @SuppressWarnings("static-method")
738 private void doSuccess(RequestContext rc) {
739 SvcLogicContext svcLogic = rc.getSvcLogicContext();
740 svcLogic.setAttribute("chefAgent.code", "200");
743 @SuppressWarnings("static-method")
744 private void chefServerResult(RequestContext rc, String code, String message) {
745 String msg = (message == null) ? " " : message;
746 SvcLogicContext svcLogic = rc.getSvcLogicContext();
747 svcLogic.setStatus(OUTCOME_SUCCESS);
748 svcLogic.setAttribute("chefServerResult.code", code);
749 svcLogic.setAttribute("chefServerResult.message", message);
752 @SuppressWarnings("static-method")
753 private void chefClientResult(RequestContext rc, String code, String message) {
754 String msg = (message == null) ? " " : message;
755 SvcLogicContext svcLogic = rc.getSvcLogicContext();
756 svcLogic.setStatus(OUTCOME_SUCCESS);
757 svcLogic.setAttribute("chefClientResult.code", code);
758 svcLogic.setAttribute("chefClientResult.message", message);
762 private void initialize() {
764 logger.info("init chef adapter!!!!!");