def destroy_scenario(self, scenario_name_or_path, profile, confirmed=False): # Information gathering. scenario_name = normalize_scenario_name(scenario_name_or_path) scenario_instance_dir_path = find_scenario_instance_dir( self.base_dir, scenario_name) if scenario_instance_dir_path is None: print( f'[cloudgoat] Error: No scenario instance for "{scenario_name}" found.' f" Try: cloudgoat.py list deployed") return instance_name = os.path.basename(scenario_instance_dir_path) # Confirmation. if not confirmed: delete_permission = input( f'Destroy "{instance_name}"? [y/n]: ').strip() if not delete_permission or not delete_permission[0].lower( ) == "y": print(f"\nCancelled destruction of {instance_name}.\n") return # Terraform execution. terraform_directory = os.path.join(scenario_instance_dir_path, "terraform") if os.path.exists( os.path.join(terraform_directory, "terraform.tfstate")): terraform = Terraform(working_dir=terraform_directory) cgid = extract_cgid_from_dir_name( os.path.basename(scenario_instance_dir_path)) destroy_retcode, destroy_stdout, destroy_stderr = terraform.destroy( capture_output=False, var={ "cgid": cgid, "cg_whitelist": list(), "profile": profile, "region": self.aws_region, }, no_color=IsNotFlagged, ) if destroy_retcode != 0: display_terraform_step_error("terraform destroy", destroy_retcode, destroy_stdout, destroy_stderr) return else: print( "\n[cloudgoat] terraform destroy completed with no error code." ) else: print( f"\nNo terraform.tfstate file was found in the scenario instance's" f' terraform directory, so "terraform destroy" will not be run.' ) # Scenario instance directory trashing. trash_dir = create_dir_if_nonexistent(self.base_dir, "trash") trashed_instance_path = os.path.join( trash_dir, os.path.basename(scenario_instance_dir_path)) shutil.move(scenario_instance_dir_path, trashed_instance_path) print( f"\nSuccessfully destroyed {instance_name}." f"\nScenario instance files have been moved to {trashed_instance_path}" ) return
def destroy_all_scenarios(self, profile): # Information gathering. extant_scenario_instance_names_and_paths = list() for scenario_name in self.scenario_names: scenario_instance_dir_path = find_scenario_instance_dir( self.base_dir, scenario_name) if scenario_instance_dir_path is None: continue else: extant_scenario_instance_names_and_paths.append( (scenario_name, scenario_instance_dir_path)) print(f"Scenario instance for {scenario_name} found.") if not extant_scenario_instance_names_and_paths: print(f"\n No scenario instance directories exist.\n") return else: print( f"\n {len(extant_scenario_instance_names_and_paths)} scenario" f" instance directories found.") # Iteration. success_count, failure_count, skipped_count = 0, 0, 0 for scenario_name, instance_path in extant_scenario_instance_names_and_paths: print(f"\n--------------------------------\n") # Confirmation. delete_permission = input(f'Destroy "{scenario_name}"? [y/n]: ') if not delete_permission.strip()[0].lower() == "y": skipped_count += 1 print(f"\nSkipped destruction of {scenario_name}.\n") continue # Terraform execution. terraform_directory = os.path.join(instance_path, "terraform") if os.path.exists( os.path.join(terraform_directory, "terraform.tfstate")): terraform = Terraform(working_dir=terraform_directory) cgid = extract_cgid_from_dir_name( os.path.basename(instance_path)) destroy_retcode, destroy_stdout, destroy_stderr = terraform.destroy( capture_output=False, var={ "cgid": cgid, "cg_whitelist": list(), "profile": profile, "region": self.aws_region, }, no_color=IsNotFlagged, ) if destroy_retcode != 0: display_terraform_step_error( "terraform destroy", destroy_retcode, destroy_stdout, destroy_stderr, ) failure_count += 1 # Subsequent destroys should not be skipped when one fails. continue else: print( f"\n[cloudgoat] terraform destroy completed with no error code." ) else: print( f"\nNo terraform.tfstate file was found in the scenario instance's" f' terraform directory, so "terraform destroy" will not be run.' ) # Scenario instance directory trashing. trash_dir = create_dir_if_nonexistent(self.base_dir, "trash") trashed_instance_path = os.path.join( trash_dir, os.path.basename(instance_path)) shutil.move(instance_path, trashed_instance_path) success_count += 1 print( f"\nSuccessfully destroyed {scenario_name}." f"\nScenario instance files have been moved to {trashed_instance_path}" ) # Iteration summary. print(f"\nDestruction complete." f"\n {success_count} scenarios successfully destroyed" f"\n {failure_count} destroys failed" f"\n {skipped_count} skipped\n") return