1515from helper_code .validate_protocols import is_path_supported_protocol
1616from cloudshell .core .logger .qs_logger import get_qs_logger
1717from ansible_configuration import AnsibleConfiguration , HostConfiguration
18+ from get_resource_from_context import get_resource_from_context
1819
1920# HOST OVERRIDE PARAMS - IF PRESENT ON RESOURCE THEY WILL OVERRIDE THE SERVICE DEFAULT
2021# TO BE CREATED IN SYSTEM AS GLOBAL ATTRIBUTE
@@ -53,9 +54,17 @@ def execute_playbook(self, context, cancellation_context, playbook_path, script_
5354 res_id = context .reservation .reservation_id
5455 reporter = self ._get_sandbox_reporter (context , api )
5556 service_name = context .resource .name
56- ansible_config_json = self ._get_ansible_config_json (context , api , reporter , playbook_path , script_params )
5757
58- reporter .info_out ("Service '{}' is Executing Ansible Playbook..." .format (context .resource .name ))
58+ try :
59+ ansible_config_json = self ._get_ansible_config_json (context , api , reporter , playbook_path , script_params )
60+ except Exception as e :
61+ exc_msg = "Error building playbook request on '{}': {}" .format (service_name , str (e ))
62+ reporter .exc_out (exc_msg )
63+ api .SetServiceLiveStatus (reservationId = res_id , serviceAlias = service_name , liveStatusName = "Error" ,
64+ additionalInfo = str (e ))
65+ raise Exception (exc_msg )
66+
67+ reporter .info_out ("'{}' is Executing Ansible Playbook..." .format (context .resource .name ))
5968 try :
6069 self .first_gen_ansible_shell .execute_playbook (context , ansible_config_json , cancellation_context )
6170 except Exception as e :
@@ -108,8 +117,17 @@ def execute_infrastructure_playbook(self, context, cancellation_context, infrast
108117 reporter = self ._get_sandbox_reporter (context , api )
109118 service_name = context .resource .name
110119 resources = self ._get_infrastructure_resources (infrastructure_resources , service_name , api , reporter )
111- ansible_config_json = self ._get_ansible_config_json (context , api , reporter , playbook_path , script_params ,
112- resources )
120+
121+ reporter .info_out ("'{}' is Executing Ansible Playbook..." .format (context .resource .name ))
122+ try :
123+ ansible_config_json = self ._get_ansible_config_json (context , api , reporter , playbook_path , script_params ,
124+ resources )
125+ except Exception as e :
126+ exc_msg = "Error building playbook request on '{}': {}" .format (service_name , str (e ))
127+ reporter .exc_out (exc_msg )
128+ api .SetServiceLiveStatus (reservationId = res_id , serviceAlias = service_name , liveStatusName = "Error" ,
129+ additionalInfo = str (e ))
130+ raise Exception (exc_msg )
113131
114132 try :
115133 self .first_gen_ansible_shell .execute_playbook (context , ansible_config_json , cancellation_context )
@@ -148,12 +166,11 @@ def _build_repo_url(self, resource, playbook_path_input, reporter):
148166 2. full url on service takes precedence over base path
149167 3. base path concatenation last
150168 4. if input is not full url, then tries to concatenate with base bath on service
151- :param AdminAnsibleConfig2G resource:
169+ :param AnsibleConfig2G resource:
152170 :param str playbook_path:
153171 :param SandboxReporter reporter:
154172 :return:
155173 """
156- service_name = resource .name
157174 service_full_url = resource .playbook_url_full
158175 gitlab_branch = resource .gitlab_branch if resource .gitlab_branch else "master"
159176 base_path = resource .playbook_base_path
@@ -202,7 +219,8 @@ def _build_repo_url(self, resource, playbook_path_input, reporter):
202219
203220 # validate base path includes protocol
204221 if not self ._is_path_supported_protocol (base_path ):
205- err_msg = "Input Error - Base Path does not begin with valid protocol. Supported: {}" .format (self .supported_protocols )
222+ err_msg = "Input Error - Base Path does not begin with valid protocol. Supported: {}" .format (
223+ self .supported_protocols )
206224 reporter .err_out (err_msg )
207225 raise ValueError (err_msg )
208226
@@ -273,7 +291,7 @@ def _get_ansible_config_json(self, context, api, reporter, playbook_path, script
273291 :param CloudShellAPISession api:
274292 :return:
275293 """
276- resource = AdminAnsibleConfig2G . create_from_context (context )
294+ resource = get_resource_from_context (context )
277295 service_name = context .resource .name
278296 service_connection_method = resource .connection_method
279297 service_inventory_groups = resource .inventory_groups
@@ -306,11 +324,6 @@ def _get_ansible_config_json(self, context, api, reporter, playbook_path, script
306324 target_host_resource_names = list (set (all_linked_resources ))
307325 target_host_resources = [api .GetResourceDetails (x ) for x in target_host_resource_names ]
308326
309- # REPORT TARGET RESOURCES
310- resource_names = [x .Name for x in target_host_resources ]
311- start_msg = "'{}' is running on : {}" .format (service_name , resource_names )
312- reporter .info_out (start_msg )
313-
314327 # INITIALIZE DATA MODEL AND START POPULATING
315328 ansi_conf = AnsibleConfiguration ()
316329
@@ -333,31 +346,56 @@ def _get_ansible_config_json(self, context, api, reporter, playbook_path, script
333346 ansi_conf .repositoryDetails .password = password_val if password_val else None
334347
335348 # START POPULATING HOSTS
349+ missing_credential_hosts = []
336350 for curr_resource_obj in target_host_resources :
351+ curr_resource_name = curr_resource_obj .Name
337352 host_conf = HostConfiguration ()
338353 host_conf .ip = curr_resource_obj .Address
339-
340354 attrs = curr_resource_obj .ResourceAttributes
341355
342356 user_attr = get_resource_attribute_gen_agostic ("User" , attrs )
343- host_conf .username = user_attr .Value if user_attr else ""
357+ user_attr_val = user_attr .Value if user_attr else ""
358+ host_conf .username = user_attr_val
344359
345360 password_attr = get_resource_attribute_gen_agostic ("Password" , attrs )
346- host_conf .password = password_attr .Value if password_attr else None
361+ encrypted_password_val = password_attr .Value
362+ host_conf .password = encrypted_password_val
347363
348364 # OVERRIDE SERVICE ATTRIBUTES IF ATTRIBUTES EXIST ON RESOURCE
365+ # ACCESS KEY
366+ access_key_attr = get_resource_attribute_gen_agostic (ACCESS_KEY_PARAM , attrs )
367+ encrypted_acces_key_val = access_key_attr .Value if access_key_attr else None
368+ host_conf .accessKey = encrypted_acces_key_val
369+
370+ # VALIDATE HOST CREDENTIALS - NEED USER AND PASSWORD/ACCESS KEY
371+ if user_attr_val :
372+ decrypted_password = api .DecryptPassword (encrypted_password_val ).Value
373+ if encrypted_acces_key_val :
374+ decrypted_access_key = api .DecryptPassword (encrypted_acces_key_val ).Value
375+ else :
376+ decrypted_access_key = None
377+ if not decrypted_password and not decrypted_access_key :
378+ missing_credential_hosts .append ((curr_resource_name , "Empty Credentials Attribute on Resource" ))
379+ else :
380+ missing_credential_hosts .append ((curr_resource_name , "Empty User Attribute on Resource" ))
349381
350382 # GROUPS
351383 ansible_group_attr = get_resource_attribute_gen_agostic (INVENTORY_GROUP_PARAM , attrs )
352384 host_conf .groups = ansible_group_attr .Value if ansible_group_attr else service_inventory_groups
353385
354- # ACCESS KEY
355- access_key_attr = get_resource_attribute_gen_agostic (ACCESS_KEY_PARAM , attrs )
356- host_conf .accessKey = access_key_attr .Value if access_key_attr else None
357-
358386 # CONNECTION METHOD
387+ resource_connection_method = None
359388 connection_method_attr = get_resource_attribute_gen_agostic (CONNECTION_METHOD_PARAM , attrs )
360- host_conf .connectionMethod = connection_method_attr .Value if connection_method_attr else service_connection_method
389+ if connection_method_attr :
390+ connection_val = connection_method_attr .Value
391+ if connection_val :
392+ if connection_val .lower () not in ["na" , "n/a" ]:
393+ resource_connection_method = connection_val
394+
395+ if resource_connection_method :
396+ host_conf .connectionMethod = resource_connection_method
397+ else :
398+ host_conf .connectionMethod = service_connection_method
361399
362400 # CONNECTION SECURED
363401 connection_secured_attr = get_resource_attribute_gen_agostic (CONNECTION_SECURED_PARAM , attrs )
@@ -378,8 +416,19 @@ def _get_ansible_config_json(self, context, api, reporter, playbook_path, script
378416
379417 ansi_conf .hostsDetails .append (host_conf )
380418
381- ansi_conf_json = ansi_conf .get_pretty_json ()
419+ if missing_credential_hosts :
420+ missing_json = json .dumps (missing_credential_hosts , indent = 4 )
421+ warning_msg = "=== '{}' Connected Hosts Missing Credentials ===\n {}" .format (service_name , missing_json )
422+ reporter .info_out (warning_msg )
423+ err_msg = "Missing credentials on target hosts. See console / logs for info."
424+ raise Exception (err_msg )
425+
426+ # REPORT TARGET RESOURCES
427+ resource_names = [x .Name for x in target_host_resources ]
428+ start_msg = "'{}' Target Hosts :\n {}" .format (service_name , json .dumps (resource_names , indent = 4 ))
429+ reporter .info_out (start_msg )
382430
431+ ansi_conf_json = ansi_conf .get_pretty_json ()
383432 # hide repo password in json printout
384433 new_obj = json .loads (ansi_conf_json )
385434 curr_password = new_obj ["repositoryDetails" ]["password" ]
0 commit comments