From d991f7508057c028614c988b90973e67f2fe6513 Mon Sep 17 00:00:00 2001 From: baixinsui Date: Thu, 7 Nov 2024 16:21:46 +0800 Subject: [PATCH] Optimize method for reading the files generated by the Terraform --- .../TerraformBootFromDirectoryApi.java | 41 +-- .../TerraformDestroyFromDirectoryRequest.java | 2 +- .../TerraformModifyFromDirectoryRequest.java | 2 +- .../boot/models/response/TerraformResult.java | 2 +- .../TerraformValidateDiagnostics.java | 2 + .../boot/terraform/TerraformExecutor.java | 103 +++----- .../service/ScriptsGitRepoManage.java | 33 ++- .../service/TerraformDirectoryService.java | 196 ++++---------- .../service/TerraformGitRepoService.java | 177 ++++--------- .../service/TerraformScriptsHelper.java | 250 ++++++++++++++++-- .../service/TerraformScriptsService.java | 154 ++++------- 11 files changed, 486 insertions(+), 476 deletions(-) diff --git a/src/main/java/org/eclipse/xpanse/terraform/boot/api/controllers/TerraformBootFromDirectoryApi.java b/src/main/java/org/eclipse/xpanse/terraform/boot/api/controllers/TerraformBootFromDirectoryApi.java index 6fe2657..7667a0e 100644 --- a/src/main/java/org/eclipse/xpanse/terraform/boot/api/controllers/TerraformBootFromDirectoryApi.java +++ b/src/main/java/org/eclipse/xpanse/terraform/boot/api/controllers/TerraformBootFromDirectoryApi.java @@ -10,9 +10,12 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Pattern; +import java.io.File; +import java.util.List; import java.util.Objects; import java.util.UUID; import lombok.extern.slf4j.Slf4j; @@ -27,10 +30,9 @@ import org.eclipse.xpanse.terraform.boot.models.response.TerraformResult; import org.eclipse.xpanse.terraform.boot.models.validation.TerraformValidationResult; import org.eclipse.xpanse.terraform.boot.terraform.service.TerraformDirectoryService; +import org.eclipse.xpanse.terraform.boot.terraform.service.TerraformScriptsHelper; import org.eclipse.xpanse.terraform.boot.terraform.tool.TerraformVersionsHelper; import org.slf4j.MDC; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.CrossOrigin; @@ -53,14 +55,10 @@ @RequestMapping("/terraform-boot/directory") public class TerraformBootFromDirectoryApi { - private final TerraformDirectoryService terraformDirectoryService; - - @Autowired - public TerraformBootFromDirectoryApi( - @Qualifier("terraformDirectoryService") - TerraformDirectoryService terraformDirectoryService) { - this.terraformDirectoryService = terraformDirectoryService; - } + @Resource + private TerraformDirectoryService directoryService; + @Resource + private TerraformScriptsHelper scriptsHelper; /** * Method to validate Terraform modules. @@ -83,7 +81,7 @@ public TerraformValidationResult validateFromDirectory( @PathVariable("terraform_version") String terraformVersion) { UUID uuid = UUID.randomUUID(); MDC.put(REQUEST_ID, uuid.toString()); - return terraformDirectoryService.tfValidateFromDirectory(moduleDirectory, terraformVersion); + return directoryService.tfValidateFromDirectory(moduleDirectory, terraformVersion); } /** @@ -105,7 +103,8 @@ public TerraformResult deployFromDirectory( ? request.getRequestId() : UUID.randomUUID(); MDC.put(REQUEST_ID, uuid.toString()); request.setRequestId(uuid); - return terraformDirectoryService.deployFromDirectory(request, moduleDirectory); + List scriptFiles = scriptsHelper.getDeploymentFilesFromTaskWorkspace(moduleDirectory); + return directoryService.deployFromDirectory(request, moduleDirectory, scriptFiles); } /** @@ -127,7 +126,8 @@ public TerraformResult modifyFromDirectory( ? request.getRequestId() : UUID.randomUUID(); MDC.put(REQUEST_ID, uuid.toString()); request.setRequestId(uuid); - return terraformDirectoryService.modifyFromDirectory(request, moduleDirectory); + List scriptFiles = scriptsHelper.getDeploymentFilesFromTaskWorkspace(moduleDirectory); + return directoryService.modifyFromDirectory(request, moduleDirectory, scriptFiles); } /** @@ -150,7 +150,8 @@ public TerraformResult destroyFromDirectory( ? request.getRequestId() : UUID.randomUUID(); MDC.put(REQUEST_ID, uuid.toString()); request.setRequestId(uuid); - return terraformDirectoryService.destroyFromDirectory(request, moduleDirectory); + List scriptFiles = scriptsHelper.getDeploymentFilesFromTaskWorkspace(moduleDirectory); + return directoryService.destroyFromDirectory(request, moduleDirectory, scriptFiles); } /** @@ -174,8 +175,7 @@ public TerraformPlan plan( : (Objects.nonNull(uuid) ? uuid : UUID.randomUUID()); MDC.put(REQUEST_ID, uuid.toString()); request.setRequestId(uuid); - return terraformDirectoryService.getTerraformPlanFromDirectory(request, - moduleDirectory); + return directoryService.getTerraformPlanFromDirectory(request, moduleDirectory); } /** @@ -196,7 +196,8 @@ public void asyncDeployFromDirectory( ? request.getRequestId() : UUID.randomUUID(); MDC.put(REQUEST_ID, uuid.toString()); request.setRequestId(uuid); - terraformDirectoryService.asyncDeployWithScripts(request, moduleDirectory); + List scriptFiles = scriptsHelper.getDeploymentFilesFromTaskWorkspace(moduleDirectory); + directoryService.asyncDeployWithScripts(request, moduleDirectory, scriptFiles); } /** @@ -217,7 +218,8 @@ public void asyncModifyFromDirectory( ? request.getRequestId() : UUID.randomUUID(); MDC.put(REQUEST_ID, uuid.toString()); request.setRequestId(uuid); - terraformDirectoryService.asyncModifyWithScripts(request, moduleDirectory); + List scriptFiles = scriptsHelper.getDeploymentFilesFromTaskWorkspace(moduleDirectory); + directoryService.asyncModifyWithScripts(request, moduleDirectory, scriptFiles); } /** @@ -238,6 +240,7 @@ public void asyncDestroyFromDirectory( ? request.getRequestId() : UUID.randomUUID(); MDC.put(REQUEST_ID, uuid.toString()); request.setRequestId(uuid); - terraformDirectoryService.asyncDestroyWithScripts(request, moduleDirectory); + List scriptFiles = scriptsHelper.getDeploymentFilesFromTaskWorkspace(moduleDirectory); + directoryService.asyncDestroyWithScripts(request, moduleDirectory, scriptFiles); } } diff --git a/src/main/java/org/eclipse/xpanse/terraform/boot/models/request/directory/TerraformDestroyFromDirectoryRequest.java b/src/main/java/org/eclipse/xpanse/terraform/boot/models/request/directory/TerraformDestroyFromDirectoryRequest.java index a05b0d5..5cbf3e1 100644 --- a/src/main/java/org/eclipse/xpanse/terraform/boot/models/request/directory/TerraformDestroyFromDirectoryRequest.java +++ b/src/main/java/org/eclipse/xpanse/terraform/boot/models/request/directory/TerraformDestroyFromDirectoryRequest.java @@ -24,7 +24,7 @@ public class TerraformDestroyFromDirectoryRequest { @Schema(description = "Id of the request") - UUID requestId; + private UUID requestId; @NotNull @NotBlank diff --git a/src/main/java/org/eclipse/xpanse/terraform/boot/models/request/directory/TerraformModifyFromDirectoryRequest.java b/src/main/java/org/eclipse/xpanse/terraform/boot/models/request/directory/TerraformModifyFromDirectoryRequest.java index 51e06b5..06e53f7 100644 --- a/src/main/java/org/eclipse/xpanse/terraform/boot/models/request/directory/TerraformModifyFromDirectoryRequest.java +++ b/src/main/java/org/eclipse/xpanse/terraform/boot/models/request/directory/TerraformModifyFromDirectoryRequest.java @@ -24,7 +24,7 @@ public class TerraformModifyFromDirectoryRequest { @Schema(description = "Id of the request") - UUID requestId; + private UUID requestId; @NotNull @NotBlank diff --git a/src/main/java/org/eclipse/xpanse/terraform/boot/models/response/TerraformResult.java b/src/main/java/org/eclipse/xpanse/terraform/boot/models/response/TerraformResult.java index 8557e5a..16149b0 100644 --- a/src/main/java/org/eclipse/xpanse/terraform/boot/models/response/TerraformResult.java +++ b/src/main/java/org/eclipse/xpanse/terraform/boot/models/response/TerraformResult.java @@ -32,7 +32,7 @@ public class TerraformResult { private String terraformState; @Schema(description = "Data of all other files generated by the terraform execution." + "The map key contains the file name and value is the file contents as string.") - private Map importantFileContentMap; + private Map generatedFileContentMap; @Schema(description = "The version of the Terraform binary used to execute scripts.") private String terraformVersionUsed; } diff --git a/src/main/java/org/eclipse/xpanse/terraform/boot/models/validation/TerraformValidateDiagnostics.java b/src/main/java/org/eclipse/xpanse/terraform/boot/models/validation/TerraformValidateDiagnostics.java index fd424d9..453d95e 100644 --- a/src/main/java/org/eclipse/xpanse/terraform/boot/models/validation/TerraformValidateDiagnostics.java +++ b/src/main/java/org/eclipse/xpanse/terraform/boot/models/validation/TerraformValidateDiagnostics.java @@ -6,6 +6,7 @@ package org.eclipse.xpanse.terraform.boot.models.validation; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; /** @@ -15,6 +16,7 @@ @JsonIgnoreProperties(ignoreUnknown = true) public class TerraformValidateDiagnostics { + @Schema(description = "Detail of validation error.") private String detail; } diff --git a/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/TerraformExecutor.java b/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/TerraformExecutor.java index b8ae0dc..9dc7c83 100644 --- a/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/TerraformExecutor.java +++ b/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/TerraformExecutor.java @@ -30,15 +30,13 @@ @Component public class TerraformExecutor { - private static final String VARS_FILE_NAME = "variables.tfvars.json"; + private static final String TF_VARS_FILE_NAME = "variables.tfvars.json"; private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); static { OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); } - private final String moduleParentDirectoryPath; - private final SystemCmd systemCmd; private final boolean isStdoutStdErrLoggingEnabled; @@ -51,15 +49,12 @@ public class TerraformExecutor { * Constructor for the TerraformExecutor bean. * * @param systemCmd SystemCmd bean - * @param moduleParentDirectoryPath value of `terraform.root.module.directory` property * @param isStdoutStdErrLoggingEnabled value of `log.terraform.stdout.stderr` property * @param customTerraformBinary value of `terraform.binary.location` property * @param terraformLogLevel value of `terraform.log.level` property */ @Autowired public TerraformExecutor(SystemCmd systemCmd, - @Value("${terraform.root.module.directory}") - String moduleParentDirectoryPath, @Value("${log.terraform.stdout.stderr:true}") boolean isStdoutStdErrLoggingEnabled, @Value("${terraform.binary.location}") @@ -67,12 +62,6 @@ public TerraformExecutor(SystemCmd systemCmd, @Value("${terraform.log.level}") String terraformLogLevel ) { - if (moduleParentDirectoryPath.isBlank() || moduleParentDirectoryPath.isEmpty()) { - this.moduleParentDirectoryPath = - System.getProperty("java.io.tmpdir"); - } else { - this.moduleParentDirectoryPath = moduleParentDirectoryPath; - } this.systemCmd = systemCmd; this.customTerraformBinary = customTerraformBinary; this.isStdoutStdErrLoggingEnabled = isStdoutStdErrLoggingEnabled; @@ -83,10 +72,10 @@ public TerraformExecutor(SystemCmd systemCmd, * Terraform executes init, plan and destroy commands. */ public SystemCmdResult tfDestroy(String executorPath, Map variables, - Map envVariables, String moduleDirectory) { - tfPlan(executorPath, variables, envVariables, moduleDirectory); + Map envVariables, String taskWorkspace) { + tfPlan(executorPath, variables, envVariables, taskWorkspace); SystemCmdResult applyResult = tfDestroyCommand( - executorPath, variables, envVariables, getModuleFullPath(moduleDirectory)); + executorPath, variables, envVariables, taskWorkspace); if (!applyResult.isCommandSuccessful()) { log.error("TFExecutor.tfDestroy failed."); throw new TerraformExecutorException("TFExecutor.tfDestroy failed.", @@ -99,10 +88,10 @@ public SystemCmdResult tfDestroy(String executorPath, Map variab * Terraform executes init, plan and apply commands. */ public SystemCmdResult tfApply(String executorPath, Map variables, - Map envVariables, String moduleDirectory) { - tfPlan(executorPath, variables, envVariables, moduleDirectory); + Map envVariables, String taskWorkspace) { + tfPlan(executorPath, variables, envVariables, taskWorkspace); SystemCmdResult applyResult = tfApplyCommand(executorPath, variables, envVariables, - getModuleFullPath(moduleDirectory)); + taskWorkspace); if (!applyResult.isCommandSuccessful()) { log.error("TFExecutor.tfApply failed."); throw new TerraformExecutorException("TFExecutor.tfApply failed.", @@ -115,10 +104,10 @@ public SystemCmdResult tfApply(String executorPath, Map variable * Terraform executes init and plan commands. */ public SystemCmdResult tfPlan(String executorPath, Map variables, - Map envVariables, String moduleDirectory) { - tfInit(executorPath, moduleDirectory); + Map envVariables, String taskWorkspace) { + tfInit(executorPath, taskWorkspace); SystemCmdResult planResult = tfPlanCommand( - executorPath, variables, envVariables, getModuleFullPath(moduleDirectory)); + executorPath, variables, envVariables, taskWorkspace); if (!planResult.isCommandSuccessful()) { log.error("TFExecutor.tfPlan failed."); throw new TerraformExecutorException("TFExecutor.tfPlan failed.", @@ -131,12 +120,12 @@ public SystemCmdResult tfPlan(String executorPath, Map variables * Method to execute terraform plan and get the plan as a json string. */ public String getTerraformPlanAsJson(String executorPath, Map variables, - Map envVariables, String moduleDirectory) { - tfInit(executorPath, moduleDirectory); + Map envVariables, String taskWorkspace) { + tfInit(executorPath, taskWorkspace); SystemCmdResult tfPlanResult = executeWithVariables( new StringBuilder(getTerraformCommand(executorPath, "plan -input=false -no-color --out tfplan.binary ")), - variables, envVariables, getModuleFullPath(moduleDirectory)); + variables, envVariables, taskWorkspace); if (!tfPlanResult.isCommandSuccessful()) { log.error("TFExecutor.tfPlan failed."); throw new TerraformExecutorException("TFExecutor.tfPlan failed.", @@ -144,7 +133,7 @@ public String getTerraformPlanAsJson(String executorPath, Map va } SystemCmdResult planJsonResult = execute( getTerraformCommand(executorPath, "show -json tfplan.binary"), - getModuleFullPath(moduleDirectory), envVariables); + taskWorkspace, envVariables); if (!planJsonResult.isCommandSuccessful()) { log.error("Reading Terraform plan as JSON failed."); throw new TerraformExecutorException("Reading Terraform plan as JSON failed.", @@ -156,17 +145,17 @@ public String getTerraformPlanAsJson(String executorPath, Map va /** * Terraform executes the init command. */ - public SystemCmdResult tfValidate(String executorPath, String moduleDirectory) { - tfInit(executorPath, moduleDirectory); - return tfValidateCommand(executorPath, getModuleFullPath(moduleDirectory)); + public SystemCmdResult tfValidate(String executorPath, String taskWorkspace) { + tfInit(executorPath, taskWorkspace); + return tfValidateCommand(executorPath, taskWorkspace); } /** * Terraform executes the init command. */ - public void tfInit(String executorPath, String moduleDirectory) { + public void tfInit(String executorPath, String taskWorkspace) { SystemCmdResult initResult = - tfInitCommand(executorPath, getModuleFullPath(moduleDirectory)); + tfInitCommand(executorPath, taskWorkspace); if (!initResult.isCommandSuccessful()) { log.error("TFExecutor.tfInit failed."); throw new TerraformExecutorException("TFExecutor.tfInit failed.", @@ -174,22 +163,15 @@ public void tfInit(String executorPath, String moduleDirectory) { } } - /** - * Get the full path of Module. - */ - public String getModuleFullPath(String moduleDirectory) { - return this.moduleParentDirectoryPath + File.separator + moduleDirectory; - } - /** * Executes terraform init command. * * @return Returns result of SystemCmd executed. */ - private SystemCmdResult tfInitCommand(String executorPath, String workspace) { + private SystemCmdResult tfInitCommand(String executorPath, String taskWorkspace) { return execute(getTerraformCommand(executorPath, "init -no-color"), - workspace, new HashMap<>()); + taskWorkspace, new HashMap<>()); } /** @@ -197,9 +179,9 @@ private SystemCmdResult tfInitCommand(String executorPath, String workspace) { * * @return Returns result of SystemCmd executed. */ - private SystemCmdResult tfValidateCommand(String executorPath, String workspace) { + private SystemCmdResult tfValidateCommand(String executorPath, String taskWorkspace) { return execute(getTerraformCommand(executorPath, "validate -json -no-color"), - workspace, new HashMap<>()); + taskWorkspace, new HashMap<>()); } /** @@ -208,10 +190,10 @@ private SystemCmdResult tfValidateCommand(String executorPath, String workspace) * @return Returns result of SystemCmd executed. */ private SystemCmdResult tfPlanCommand(String executorPath, Map variables, - Map envVariables, String workspace) { + Map envVariables, String taskWorkspace) { return executeWithVariables(new StringBuilder( getTerraformCommand(executorPath, "plan -input=false -no-color ")), - variables, envVariables, workspace); + variables, envVariables, taskWorkspace); } /** @@ -220,10 +202,10 @@ private SystemCmdResult tfPlanCommand(String executorPath, Map v * @return Returns result of SystemCmd executed. */ private SystemCmdResult tfApplyCommand(String executorPath, Map variables, - Map envVariables, String workspace) { + Map envVariables, String taskWorkspace) { return executeWithVariables(new StringBuilder(getTerraformCommand( executorPath, "apply -auto-approve -input=false -no-color ")), - variables, envVariables, workspace); + variables, envVariables, taskWorkspace); } /** @@ -232,10 +214,11 @@ private SystemCmdResult tfApplyCommand(String executorPath, Map * @return Returns result of SystemCmd executed. */ private SystemCmdResult tfDestroyCommand(String executorPath, Map variables, - Map envVariables, String workspace) { + Map envVariables, + String taskWorkspace) { return executeWithVariables(new StringBuilder( executorPath + " destroy -auto-approve -input=false -no-color "), - variables, envVariables, workspace); + variables, envVariables, taskWorkspace); } /** @@ -246,12 +229,12 @@ private SystemCmdResult tfDestroyCommand(String executorPath, Map variables, Map envVariables, - String workspace) { - createVariablesFile(variables, workspace); + String taskWorkspace) { + createVariablesFile(variables, taskWorkspace); command.append(" -var-file="); - command.append(VARS_FILE_NAME); - SystemCmdResult systemCmdResult = execute(command.toString(), workspace, envVariables); - cleanUpVariablesFile(workspace); + command.append(TF_VARS_FILE_NAME); + SystemCmdResult systemCmdResult = execute(command.toString(), taskWorkspace, envVariables); + cleanUpVariablesFile(taskWorkspace); return systemCmdResult; } @@ -260,10 +243,10 @@ private SystemCmdResult executeWithVariables(StringBuilder command, * * @return SystemCmdResult */ - private SystemCmdResult execute(String cmd, String workspace, + private SystemCmdResult execute(String cmd, String taskWorkspace, @NonNull Map envVariables) { envVariables.putAll(getTerraformLogConfig()); - return this.systemCmd.execute(cmd, workspace, this.isStdoutStdErrLoggingEnabled, + return this.systemCmd.execute(cmd, taskWorkspace, this.isStdoutStdErrLoggingEnabled, envVariables); } @@ -279,18 +262,19 @@ private Map getTerraformLogConfig() { return Collections.singletonMap("TF_LOG", this.terraformLogLevel); } - private void createVariablesFile(Map variables, String workspace) { + private void createVariablesFile(Map variables, String taskWorkspace) { try { log.info("creating variables file"); - OBJECT_MAPPER.writeValue(new File(getVariablesFilePath(workspace)), variables); + File varFile = new File(taskWorkspace, TF_VARS_FILE_NAME); + OBJECT_MAPPER.writeValue(varFile, variables); } catch (IOException ioException) { throw new TerraformExecutorException("Creating variables file failed", ioException.getMessage()); } } - private void cleanUpVariablesFile(String workspace) { - File file = new File(getVariablesFilePath(workspace)); + private void cleanUpVariablesFile(String taskWorkspace) { + File file = new File(taskWorkspace, TF_VARS_FILE_NAME); try { log.info("cleaning up variables file"); Files.deleteIfExists(file.toPath()); @@ -299,7 +283,4 @@ private void cleanUpVariablesFile(String workspace) { } } - private String getVariablesFilePath(String workspace) { - return workspace + File.separator + VARS_FILE_NAME; - } } diff --git a/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/service/ScriptsGitRepoManage.java b/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/service/ScriptsGitRepoManage.java index bfb2b7c..4e34dea 100644 --- a/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/service/ScriptsGitRepoManage.java +++ b/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/service/ScriptsGitRepoManage.java @@ -5,9 +5,15 @@ package org.eclipse.xpanse.terraform.boot.terraform.service; +import static org.eclipse.xpanse.terraform.boot.terraform.service.TerraformScriptsHelper.TF_SCRIPT_FILE_EXTENSION; + import java.io.File; +import java.util.Arrays; +import java.util.List; import java.util.Objects; +import java.util.Optional; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.eclipse.jgit.api.CloneCommand; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; @@ -36,7 +42,7 @@ public class ScriptsGitRepoManage { @Retryable(retryFor = GitRepoCloneException.class, maxAttemptsExpression = "${spring.retry.max-attempts}", backoff = @Backoff(delayExpression = "${spring.retry.delay-millions}")) - public void checkoutScripts(String workspace, TerraformScriptGitRepoDetails scriptsRepo) { + public List checkoutScripts(String workspace, TerraformScriptGitRepoDetails scriptsRepo) { log.info("Clone GIT repo to get the deployment scripts. Retry number: " + Objects.requireNonNull(RetrySynchronizationManager.getContext()).getRetryCount()); File workspaceDirectory = new File(workspace); @@ -60,8 +66,33 @@ public void checkoutScripts(String workspace, TerraformScriptGitRepoDetails scri } else { log.info("Scripts repo is already cloned in the workspace."); } + return folderContainsScripts(workspace, scriptsRepo); } + private List folderContainsScripts(String workspace, + TerraformScriptGitRepoDetails scriptsRepo) { + File directory = new File(workspace + + (StringUtils.isNotBlank(scriptsRepo.getScriptPath()) + ? File.separator + scriptsRepo.getScriptPath() + : "")); + File[] files = directory.listFiles(); + boolean isScriptsExisted = Objects.nonNull(files) && files.length > 0; + if (isScriptsExisted) { + Optional tfFileOptional = Arrays.stream(files).filter(file -> + file.getName().endsWith(TF_SCRIPT_FILE_EXTENSION)).findAny(); + isScriptsExisted = tfFileOptional.isPresent(); + } + if (!isScriptsExisted) { + throw new GitRepoCloneException( + "No terraform scripts found in the " + + scriptsRepo.getRepoUrl() + + " repo's '" + + (StringUtils.isNotBlank(scriptsRepo.getScriptPath()) + ? File.separator + scriptsRepo.getScriptPath() : "root") + + "' folder."); + } + return Arrays.asList(files); + } /** * Recover method for checkoutScripts. diff --git a/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/service/TerraformDirectoryService.java b/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/service/TerraformDirectoryService.java index 750f868..2157bec 100644 --- a/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/service/TerraformDirectoryService.java +++ b/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/service/TerraformDirectoryService.java @@ -9,26 +9,15 @@ import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.annotation.Resource; import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.Comparator; import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.Objects; import java.util.UUID; -import java.util.stream.Stream; import lombok.extern.slf4j.Slf4j; import org.eclipse.xpanse.terraform.boot.async.TaskConfiguration; import org.eclipse.xpanse.terraform.boot.models.TerraformBootSystemStatus; import org.eclipse.xpanse.terraform.boot.models.enums.HealthStatus; import org.eclipse.xpanse.terraform.boot.models.exceptions.InvalidTerraformToolException; import org.eclipse.xpanse.terraform.boot.models.exceptions.TerraformExecutorException; -import org.eclipse.xpanse.terraform.boot.models.exceptions.TerraformHealthCheckException; import org.eclipse.xpanse.terraform.boot.models.plan.TerraformPlan; import org.eclipse.xpanse.terraform.boot.models.plan.TerraformPlanFromDirectoryRequest; import org.eclipse.xpanse.terraform.boot.models.request.directory.TerraformAsyncDeployFromDirectoryRequest; @@ -44,8 +33,6 @@ import org.eclipse.xpanse.terraform.boot.terraform.tool.TerraformVersionsHelper; import org.eclipse.xpanse.terraform.boot.terraform.utils.SystemCmdResult; import org.springframework.beans.BeanUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; @@ -56,33 +43,21 @@ @Slf4j @Service public class TerraformDirectoryService { - - private static final String STATE_FILE_NAME = "terraform.tfstate"; - private static final String TEST_FILE_NAME = "hello-world.tf"; - private static final String HEALTH_CHECK_DIR = UUID.randomUUID().toString(); - private static final List EXCLUDED_FILE_SUFFIX_LIST = - Arrays.asList(".tf", ".tfstate", ".hcl"); private static final String HELLO_WORLD_TEMPLATE = """ output "hello_world" { value = "Hello, World!" } """; - - private final TerraformExecutor executor; - private final RestTemplate restTemplate; + @Resource + private TerraformExecutor executor; @Resource private TerraformInstaller installer; @Resource + private RestTemplate restTemplate; + @Resource private TerraformVersionsHelper versionHelper; - - @Value("${clean.workspace.after.deployment.enabled:true}") - private Boolean cleanWorkspaceAfterDeployment; - - @Autowired - public TerraformDirectoryService(TerraformExecutor executor, RestTemplate restTemplate) { - this.executor = executor; - this.restTemplate = restTemplate; - } + @Resource + private TerraformScriptsHelper scriptsHelper; /** * Perform Terraform health checks by creating a Terraform test configuration file. @@ -90,28 +65,17 @@ public TerraformDirectoryService(TerraformExecutor executor, RestTemplate restTe * @return TerraformBootSystemStatus. */ public TerraformBootSystemStatus tfHealthCheck() { - String filePath = - executor.getModuleFullPath(HEALTH_CHECK_DIR) + File.separator + TEST_FILE_NAME; - try { - File file = new File(filePath); - if (!file.exists()) { - file.getParentFile().mkdirs(); - file.createNewFile(); - } - FileWriter writer = new FileWriter(filePath); - writer.write(HELLO_WORLD_TEMPLATE); - writer.close(); - } catch (IOException e) { - throw new TerraformHealthCheckException( - "Error creating or writing to file '" + filePath + "': " + e.getMessage()); - } + String taskWorkspace = scriptsHelper.buildTaskWorkspace(UUID.randomUUID().toString()); + scriptsHelper.prepareDeploymentFilesWithScripts(taskWorkspace, + List.of(HELLO_WORLD_TEMPLATE), null); TerraformValidationResult terraformValidationResult = - tfValidateFromDirectory(HEALTH_CHECK_DIR, null); + tfValidateFromDirectory(taskWorkspace, null); TerraformBootSystemStatus systemStatus = new TerraformBootSystemStatus(); if (terraformValidationResult.isValid()) { systemStatus.setHealthStatus(HealthStatus.OK); return systemStatus; } + scriptsHelper.deleteTaskWorkspace(taskWorkspace); systemStatus.setHealthStatus(HealthStatus.NOK); return systemStatus; } @@ -121,12 +85,12 @@ public TerraformBootSystemStatus tfHealthCheck() { * * @return TfValidationResult. */ - public TerraformValidationResult tfValidateFromDirectory(String moduleDirectory, + public TerraformValidationResult tfValidateFromDirectory(String taskWorkspace, String terraformVersion) { try { String executorPath = installer.getExecutorPathThatMatchesRequiredVersion(terraformVersion); - SystemCmdResult result = executor.tfValidate(executorPath, moduleDirectory); + SystemCmdResult result = executor.tfValidate(executorPath, taskWorkspace); TerraformValidationResult validationResult = new ObjectMapper().readValue(result.getCommandStdOutput(), TerraformValidationResult.class); @@ -142,7 +106,7 @@ public TerraformValidationResult tfValidateFromDirectory(String moduleDirectory, * Deploy a source by terraform. */ public TerraformResult deployFromDirectory(TerraformDeployFromDirectoryRequest request, - String moduleDirectory) { + String taskWorkspace, List scriptFiles) { SystemCmdResult result; String executorPath = null; try { @@ -150,10 +114,10 @@ public TerraformResult deployFromDirectory(TerraformDeployFromDirectoryRequest r request.getTerraformVersion()); if (Boolean.TRUE.equals(request.getIsPlanOnly())) { result = executor.tfPlan(executorPath, request.getVariables(), - request.getEnvVariables(), moduleDirectory); + request.getEnvVariables(), taskWorkspace); } else { result = executor.tfApply(executorPath, request.getVariables(), - request.getEnvVariables(), moduleDirectory); + request.getEnvVariables(), taskWorkspace); } } catch (InvalidTerraformToolException | TerraformExecutorException tfEx) { log.error("Terraform deploy service failed. error:{}", tfEx.getMessage()); @@ -161,13 +125,11 @@ public TerraformResult deployFromDirectory(TerraformDeployFromDirectoryRequest r result.setCommandSuccessful(false); result.setCommandStdError(tfEx.getMessage()); } - String workspace = executor.getModuleFullPath(moduleDirectory); - TerraformResult terraformResult = transSystemCmdResultToTerraformResult(result, workspace); + TerraformResult terraformResult = + transSystemCmdResultToTerraformResult(result, taskWorkspace, scriptFiles); terraformResult.setTerraformVersionUsed( versionHelper.getExactVersionOfExecutor(executorPath)); - if (cleanWorkspaceAfterDeployment) { - deleteWorkspace(workspace); - } + scriptsHelper.deleteTaskWorkspace(taskWorkspace); return terraformResult; } @@ -175,7 +137,7 @@ public TerraformResult deployFromDirectory(TerraformDeployFromDirectoryRequest r * Modify a source by terraform. */ public TerraformResult modifyFromDirectory(TerraformModifyFromDirectoryRequest request, - String moduleDirectory) { + String taskWorkspace, List scriptFiles) { SystemCmdResult result; String executorPath = null; try { @@ -183,10 +145,10 @@ public TerraformResult modifyFromDirectory(TerraformModifyFromDirectoryRequest r request.getTerraformVersion()); if (Boolean.TRUE.equals(request.getIsPlanOnly())) { result = executor.tfPlan(executorPath, request.getVariables(), - request.getEnvVariables(), moduleDirectory); + request.getEnvVariables(), taskWorkspace); } else { result = executor.tfApply(executorPath, request.getVariables(), - request.getEnvVariables(), moduleDirectory); + request.getEnvVariables(), taskWorkspace); } } catch (InvalidTerraformToolException | TerraformExecutorException tfEx) { log.error("Terraform deploy service failed. error:{}", tfEx.getMessage()); @@ -194,13 +156,11 @@ public TerraformResult modifyFromDirectory(TerraformModifyFromDirectoryRequest r result.setCommandSuccessful(false); result.setCommandStdError(tfEx.getMessage()); } - String workspace = executor.getModuleFullPath(moduleDirectory); - TerraformResult terraformResult = transSystemCmdResultToTerraformResult(result, workspace); + TerraformResult terraformResult = + transSystemCmdResultToTerraformResult(result, taskWorkspace, scriptFiles); terraformResult.setTerraformVersionUsed( versionHelper.getExactVersionOfExecutor(executorPath)); - if (cleanWorkspaceAfterDeployment) { - deleteWorkspace(workspace); - } + scriptsHelper.deleteTaskWorkspace(taskWorkspace); terraformResult.setRequestId(request.getRequestId()); return terraformResult; } @@ -209,25 +169,25 @@ public TerraformResult modifyFromDirectory(TerraformModifyFromDirectoryRequest r * Destroy resource of the service. */ public TerraformResult destroyFromDirectory(TerraformDestroyFromDirectoryRequest request, - String moduleDirectory) { + String taskWorkspace, List scriptFiles) { SystemCmdResult result; String executorPath = null; try { executorPath = installer.getExecutorPathThatMatchesRequiredVersion( request.getTerraformVersion()); result = executor.tfDestroy(executorPath, request.getVariables(), - request.getEnvVariables(), moduleDirectory); + request.getEnvVariables(), taskWorkspace); } catch (InvalidTerraformToolException | TerraformExecutorException tfEx) { log.error("Terraform destroy service failed. error:{}", tfEx.getMessage()); result = new SystemCmdResult(); result.setCommandSuccessful(false); result.setCommandStdError(tfEx.getMessage()); } - String workspace = executor.getModuleFullPath(moduleDirectory); - TerraformResult terraformResult = transSystemCmdResultToTerraformResult(result, workspace); + TerraformResult terraformResult = + transSystemCmdResultToTerraformResult(result, taskWorkspace, scriptFiles); terraformResult.setTerraformVersionUsed( versionHelper.getExactVersionOfExecutor(executorPath)); - deleteWorkspace(workspace); + scriptsHelper.deleteTaskWorkspace(taskWorkspace); terraformResult.setRequestId(request.getRequestId()); return terraformResult; } @@ -236,12 +196,12 @@ public TerraformResult destroyFromDirectory(TerraformDestroyFromDirectoryRequest * Executes terraform plan command on a directory and returns the plan as a JSON string. */ public TerraformPlan getTerraformPlanFromDirectory(TerraformPlanFromDirectoryRequest request, - String moduleDirectory) { + String taskWorkspace) { String executorPath = installer.getExecutorPathThatMatchesRequiredVersion(request.getTerraformVersion()); String result = executor.getTerraformPlanAsJson(executorPath, request.getVariables(), - request.getEnvVariables(), moduleDirectory); - deleteWorkspace(executor.getModuleFullPath(moduleDirectory)); + request.getEnvVariables(), taskWorkspace); + scriptsHelper.deleteTaskWorkspace(taskWorkspace); TerraformPlan terraformPlan = TerraformPlan.builder().plan(result).build(); terraformPlan.setTerraformVersionUsed( versionHelper.getExactVersionOfExecutor(executorPath)); @@ -253,15 +213,15 @@ public TerraformPlan getTerraformPlanFromDirectory(TerraformPlanFromDirectoryReq */ @Async(TaskConfiguration.TASK_EXECUTOR_NAME) public void asyncDeployWithScripts(TerraformAsyncDeployFromDirectoryRequest asyncDeployRequest, - String moduleDirectory) { + String taskWorkspace, List scriptFiles) { TerraformResult result; try { - result = deployFromDirectory(asyncDeployRequest, moduleDirectory); + result = deployFromDirectory(asyncDeployRequest, taskWorkspace, scriptFiles); } catch (RuntimeException e) { result = TerraformResult.builder().commandStdOutput(null).commandStdError(e.getMessage()) .isCommandSuccessful(false).terraformState(null) - .importantFileContentMap(new HashMap<>()).build(); + .generatedFileContentMap(new HashMap<>()).build(); } result.setRequestId(asyncDeployRequest.getRequestId()); String url = asyncDeployRequest.getWebhookConfig().getUrl(); @@ -274,15 +234,15 @@ public void asyncDeployWithScripts(TerraformAsyncDeployFromDirectoryRequest asyn */ @Async(TaskConfiguration.TASK_EXECUTOR_NAME) public void asyncModifyWithScripts(TerraformAsyncModifyFromDirectoryRequest asyncModifyRequest, - String moduleDirectory) { + String taskWorkspace, List scriptFiles) { TerraformResult result; try { - result = modifyFromDirectory(asyncModifyRequest, moduleDirectory); + result = modifyFromDirectory(asyncModifyRequest, taskWorkspace, scriptFiles); } catch (RuntimeException e) { result = TerraformResult.builder().commandStdOutput(null).commandStdError(e.getMessage()) .isCommandSuccessful(false).terraformState(null) - .importantFileContentMap(new HashMap<>()).build(); + .generatedFileContentMap(new HashMap<>()).build(); } result.setRequestId(asyncModifyRequest.getRequestId()); String url = asyncModifyRequest.getWebhookConfig().getUrl(); @@ -295,15 +255,15 @@ public void asyncModifyWithScripts(TerraformAsyncModifyFromDirectoryRequest asyn */ @Async(TaskConfiguration.TASK_EXECUTOR_NAME) public void asyncDestroyWithScripts(TerraformAsyncDestroyFromDirectoryRequest request, - String moduleDirectory) { + String taskWorkspace, List scriptFiles) { TerraformResult result; try { - result = destroyFromDirectory(request, moduleDirectory); + result = destroyFromDirectory(request, taskWorkspace, scriptFiles); } catch (RuntimeException e) { result = TerraformResult.builder().commandStdOutput(null).commandStdError(e.getMessage()) .isCommandSuccessful(false).terraformState(null) - .importantFileContentMap(new HashMap<>()).build(); + .generatedFileContentMap(new HashMap<>()).build(); } result.setRequestId(request.getRequestId()); String url = request.getWebhookConfig().getUrl(); @@ -311,75 +271,13 @@ public void asyncDestroyWithScripts(TerraformAsyncDestroyFromDirectoryRequest re restTemplate.postForLocation(url, result); } - private TerraformResult transSystemCmdResultToTerraformResult(SystemCmdResult result, - String workspace) { + private TerraformResult transSystemCmdResultToTerraformResult( + SystemCmdResult result, String taskWorkspace, List scriptFiles) { TerraformResult terraformResult = TerraformResult.builder().build(); BeanUtils.copyProperties(result, terraformResult); - terraformResult.setTerraformState(getTerraformState(workspace)); - terraformResult.setImportantFileContentMap(getImportantFilesContent(workspace)); + terraformResult.setTerraformState(scriptsHelper.getTerraformState(taskWorkspace)); + terraformResult.setGeneratedFileContentMap( + scriptsHelper.getDeploymentGeneratedFilesContent(taskWorkspace, scriptFiles)); return terraformResult; } - - /** - * Get the content of the tfState file. - */ - private String getTerraformState(String workspace) { - String state = null; - try { - File tfState = new File(workspace + File.separator + STATE_FILE_NAME); - if (tfState.exists()) { - state = Files.readString(tfState.toPath()); - } - } catch (IOException ex) { - log.error("Read state file failed.", ex); - } - return state; - } - - /** - * get file content. - */ - private Map getImportantFilesContent(String workspace) { - Map fileContentMap = new HashMap<>(); - File workPath = new File(workspace); - if (workPath.isDirectory() && workPath.exists()) { - File[] files = workPath.listFiles(); - if (Objects.nonNull(files)) { - Arrays.stream(files).forEach(file -> { - if (file.isFile() && !isExcludedFile(file.getName())) { - String content = readFileContentAndDelete(file); - fileContentMap.put(file.getName(), content); - } - }); - } - } - return fileContentMap; - } - - private String readFileContentAndDelete(File file) { - String fileContent = ""; - try { - fileContent = Files.readString(file.toPath()); - boolean deleted = Files.deleteIfExists(file.toPath()); - log.info("Read file content with name:{} successfully. Delete result:{}", - file.getName(), deleted); - } catch (IOException e) { - log.error("Read file content with name:{} error.", file.getName(), e); - } - return fileContent; - } - - private void deleteWorkspace(String workspace) { - Path path = Paths.get(workspace).toAbsolutePath().normalize(); - try (Stream pathStream = Files.walk(path)) { - pathStream.sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete); - } catch (IOException e) { - log.error("Delete workspace:{} error", workspace, e); - } - } - - private boolean isExcludedFile(String fileName) { - String fileSuffix = fileName.substring(fileName.lastIndexOf(".")); - return EXCLUDED_FILE_SUFFIX_LIST.contains(fileSuffix); - } } diff --git a/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/service/TerraformGitRepoService.java b/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/service/TerraformGitRepoService.java index 6beea62..2eab220 100644 --- a/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/service/TerraformGitRepoService.java +++ b/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/service/TerraformGitRepoService.java @@ -5,19 +5,14 @@ package org.eclipse.xpanse.terraform.boot.terraform.service; +import jakarta.annotation.Resource; import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.UUID; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.eclipse.xpanse.terraform.boot.async.TaskConfiguration; -import org.eclipse.xpanse.terraform.boot.models.exceptions.TerraformExecutorException; import org.eclipse.xpanse.terraform.boot.models.plan.TerraformPlan; import org.eclipse.xpanse.terraform.boot.models.plan.TerraformPlanFromGitRepoRequest; import org.eclipse.xpanse.terraform.boot.models.request.git.TerraformAsyncDeployFromGitRepoRequest; @@ -29,7 +24,6 @@ import org.eclipse.xpanse.terraform.boot.models.request.git.TerraformScriptGitRepoDetails; import org.eclipse.xpanse.terraform.boot.models.response.TerraformResult; import org.eclipse.xpanse.terraform.boot.models.validation.TerraformValidationResult; -import org.eclipse.xpanse.terraform.boot.terraform.TerraformExecutor; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; @@ -39,78 +33,85 @@ */ @Slf4j @Component -public class TerraformGitRepoService extends TerraformDirectoryService { +public class TerraformGitRepoService { - private final RestTemplate restTemplate; - private final TerraformExecutor executor; - private final TerraformScriptsHelper terraformScriptsHelper; - private final ScriptsGitRepoManage scriptsGitRepoManage; - - /** - * Constructor for TerraformGitRepoService bean. - */ - public TerraformGitRepoService(TerraformExecutor executor, RestTemplate restTemplate, - TerraformScriptsHelper terraformScriptsHelper, - ScriptsGitRepoManage scriptsGitRepoManage) { - super(executor, restTemplate); - this.restTemplate = restTemplate; - this.executor = executor; - this.terraformScriptsHelper = terraformScriptsHelper; - this.scriptsGitRepoManage = scriptsGitRepoManage; - } + @Resource + private RestTemplate restTemplate; + @Resource + private TerraformScriptsHelper scriptsHelper; + @Resource + private TerraformDirectoryService directoryService; /** * Method of deployment a service using a script. */ public TerraformValidationResult validateWithScripts( TerraformDeployFromGitRepoRequest request) { - UUID uuid = UUID.randomUUID(); - buildDeployEnv(request.getGitRepoDetails(), uuid); - return tfValidateFromDirectory( - getScriptsLocationInRepo(request.getGitRepoDetails(), uuid), - request.getTerraformVersion()); + String taskWorkspace = scriptsHelper.buildTaskWorkspace(UUID.randomUUID().toString()); + scriptsHelper.prepareDeploymentFilesWithGitRepo( + taskWorkspace, request.getGitRepoDetails(), null); + String scriptsPath = getScriptsLocationInTaskWorkspace( + request.getGitRepoDetails(), taskWorkspace); + return directoryService.tfValidateFromDirectory(scriptsPath, request.getTerraformVersion()); } /** * Method to get terraform plan. */ - public TerraformPlan getTerraformPlanFromGitRepo(TerraformPlanFromGitRepoRequest request, - UUID uuid) { - uuid = getUuidToCreateEmptyWorkspace(uuid); - buildDeployEnv(request.getGitRepoDetails(), uuid); - return getTerraformPlanFromDirectory(request, - getScriptsLocationInRepo(request.getGitRepoDetails(), uuid)); + public TerraformPlan getTerraformPlanFromGitRepo( + TerraformPlanFromGitRepoRequest request, UUID uuid) { + String taskWorkspace = scriptsHelper.buildTaskWorkspace(uuid.toString()); + scriptsHelper.prepareDeploymentFilesWithGitRepo( + taskWorkspace, request.getGitRepoDetails(), null); + String scriptsPath = getScriptsLocationInTaskWorkspace( + request.getGitRepoDetails(), taskWorkspace); + return directoryService.getTerraformPlanFromDirectory(request, scriptsPath); } /** * Method of deployment a service using a script. */ public TerraformResult deployFromGitRepo(TerraformDeployFromGitRepoRequest request, UUID uuid) { - uuid = getUuidToCreateEmptyWorkspace(uuid); - buildDeployEnv(request.getGitRepoDetails(), uuid); - return deployFromDirectory(request, - getScriptsLocationInRepo(request.getGitRepoDetails(), uuid)); + String taskWorkspace = scriptsHelper.buildTaskWorkspace(uuid.toString()); + List scriptFiles = scriptsHelper.prepareDeploymentFilesWithGitRepo( + taskWorkspace, request.getGitRepoDetails(), null); + String scriptsPath = getScriptsLocationInTaskWorkspace( + request.getGitRepoDetails(), taskWorkspace); + TerraformResult result = + directoryService.deployFromDirectory(request, scriptsPath, scriptFiles); + scriptsHelper.deleteTaskWorkspace(taskWorkspace); + return result; } /** * Method of modify a service using a script. */ public TerraformResult modifyFromGitRepo(TerraformModifyFromGitRepoRequest request, UUID uuid) { - uuid = getUuidToCreateEmptyWorkspace(uuid); - buildModifyEnv(request.getGitRepoDetails(), request.getTfState(), uuid); - return modifyFromDirectory(request, - getScriptsLocationInRepo(request.getGitRepoDetails(), uuid)); + String taskWorkspace = scriptsHelper.buildTaskWorkspace(uuid.toString()); + List scriptFiles = scriptsHelper.prepareDeploymentFilesWithGitRepo( + taskWorkspace, request.getGitRepoDetails(), request.getTfState()); + String scriptsPath = getScriptsLocationInTaskWorkspace( + request.getGitRepoDetails(), taskWorkspace); + TerraformResult result = + directoryService.modifyFromDirectory(request, scriptsPath, scriptFiles); + scriptsHelper.deleteTaskWorkspace(taskWorkspace); + return result; } /** * Method of destroy a service using a script. */ - public TerraformResult destroyFromGitRepo(TerraformDestroyFromGitRepoRequest request, - UUID uuid) { - uuid = getUuidToCreateEmptyWorkspace(uuid); - buildDestroyEnv(request.getGitRepoDetails(), request.getTfState(), uuid); - return destroyFromDirectory(request, getScriptsLocationInRepo( - request.getGitRepoDetails(), uuid)); + public TerraformResult destroyFromGitRepo( + TerraformDestroyFromGitRepoRequest request, UUID uuid) { + String taskWorkspace = scriptsHelper.buildTaskWorkspace(uuid.toString()); + List scriptFiles = scriptsHelper.prepareDeploymentFilesWithGitRepo( + taskWorkspace, request.getGitRepoDetails(), request.getTfState()); + String scriptsPath = getScriptsLocationInTaskWorkspace( + request.getGitRepoDetails(), taskWorkspace); + TerraformResult result = + directoryService.destroyFromDirectory(request, scriptsPath, scriptFiles); + scriptsHelper.deleteTaskWorkspace(taskWorkspace); + return result; } /** @@ -128,7 +129,7 @@ public void asyncDeployFromGitRepo(TerraformAsyncDeployFromGitRepoRequest asyncD .commandStdError(e.getMessage()) .isCommandSuccessful(false) .terraformState(null) - .importantFileContentMap(new HashMap<>()) + .generatedFileContentMap(new HashMap<>()) .build(); } result.setRequestId(asyncDeployRequest.getRequestId()); @@ -152,7 +153,7 @@ public void asyncModifyFromGitRepo(TerraformAsyncModifyFromGitRepoRequest asyncM .commandStdError(e.getMessage()) .isCommandSuccessful(false) .terraformState(null) - .importantFileContentMap(new HashMap<>()) + .generatedFileContentMap(new HashMap<>()) .build(); } result.setRequestId(asyncModifyRequest.getRequestId()); @@ -177,7 +178,7 @@ public void asyncDestroyFromGitRepo(TerraformAsyncDestroyFromGitRepoRequest requ .commandStdError(e.getMessage()) .isCommandSuccessful(false) .terraformState(null) - .importantFileContentMap(new HashMap<>()) + .generatedFileContentMap(new HashMap<>()) .build(); } result.setRequestId(request.getRequestId()); @@ -186,75 +187,13 @@ public void asyncDestroyFromGitRepo(TerraformAsyncDestroyFromGitRepoRequest requ restTemplate.postForLocation(url, result); } - private void buildDeployEnv(TerraformScriptGitRepoDetails terraformScriptGitRepoDetails, - UUID uuid) { - String workspace = executor.getModuleFullPath(uuid.toString()); - buildWorkspace(workspace); - scriptsGitRepoManage.checkoutScripts(workspace, terraformScriptGitRepoDetails); - } - - private void buildModifyEnv(TerraformScriptGitRepoDetails terraformScriptGitRepoDetails, - String tfState, UUID uuid) { - buildDeployEnv(terraformScriptGitRepoDetails, uuid); - terraformScriptsHelper.createTfStateFile(tfState, - uuid + File.separator + terraformScriptGitRepoDetails.getScriptPath()); - } - - private void buildDestroyEnv(TerraformScriptGitRepoDetails terraformScriptGitRepoDetails, - String tfState, UUID uuid) { - buildDeployEnv(terraformScriptGitRepoDetails, uuid); - terraformScriptsHelper.createTfStateFile(tfState, - uuid + File.separator + terraformScriptGitRepoDetails.getScriptPath()); - } - - private UUID getUuidToCreateEmptyWorkspace(UUID uuid) { - File ws = new File(executor.getModuleFullPath(uuid.toString())); - if (ws.exists()) { - if (!cleanWorkspace(uuid)) { - uuid = UUID.randomUUID(); - log.info("Clean existed workspace failed. Create empty workspace with id:{}", uuid); - return UUID.randomUUID(); - } - } - return uuid; - } - - private void buildWorkspace(String workspace) { - log.info("start create workspace"); - File ws = new File(workspace); - if (!ws.exists() && !ws.mkdirs()) { - throw new TerraformExecutorException( - "Create workspace failed, File path not created: " + ws.getAbsolutePath()); - } - log.info("workspace create success, Working directory is " + ws.getAbsolutePath()); - } - - private String getScriptsLocationInRepo( - TerraformScriptGitRepoDetails terraformScriptGitRepoDetails, UUID uuid) { + private String getScriptsLocationInTaskWorkspace( + TerraformScriptGitRepoDetails terraformScriptGitRepoDetails, String taskWorkSpace) { if (StringUtils.isNotBlank(terraformScriptGitRepoDetails.getScriptPath())) { - return uuid + File.separator + terraformScriptGitRepoDetails.getScriptPath(); - } - return uuid.toString(); - } - - private boolean cleanWorkspace(UUID uuid) { - boolean cleanSuccess = true; - try { - String workspace = executor.getModuleFullPath(uuid.toString()); - Path path = Paths.get(workspace).toAbsolutePath().normalize(); - List files = - Files.walk(path).sorted(Comparator.reverseOrder()).map(Path::toFile).toList(); - for (File file : files) { - if (!file.delete()) { - cleanSuccess = false; - log.info("Failed to delete file: {}", file.getAbsolutePath()); - } - } - } catch (IOException e) { - return false; + return taskWorkSpace + File.separator + terraformScriptGitRepoDetails.getScriptPath(); } - return cleanSuccess; + return taskWorkSpace; } } diff --git a/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/service/TerraformScriptsHelper.java b/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/service/TerraformScriptsHelper.java index 45a1c06..897f93d 100644 --- a/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/service/TerraformScriptsHelper.java +++ b/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/service/TerraformScriptsHelper.java @@ -5,14 +5,28 @@ package org.eclipse.xpanse.terraform.boot.terraform.service; +import jakarta.annotation.Resource; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Stream; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.eclipse.xpanse.terraform.boot.models.exceptions.TerraformExecutorException; -import org.eclipse.xpanse.terraform.boot.terraform.TerraformExecutor; +import org.eclipse.xpanse.terraform.boot.models.request.git.TerraformScriptGitRepoDetails; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; /** * bean to host all generic methods shared from different types of Terraform deployers. @@ -21,33 +35,235 @@ @Component public class TerraformScriptsHelper { - private static final String STATE_FILE_NAME = "terraform.tfstate"; + public static final String TF_SCRIPT_FILE_EXTENSION = ".tf"; + private static final String TF_SCRIPT_FILE_NAME = "resource.tf"; + private static final String TF_STATE_FILE_NAME = "terraform.tfstate"; + private static final List EXCLUDED_FILE_SUFFIX_LIST = + Arrays.asList(".tf", ".tfstate", ".hcl"); - private final TerraformExecutor terraformExecutor; + @Value("${terraform.root.module.directory}") + private String moduleParentDirectoryPath; + @Value("${clean.workspace.after.deployment.enabled:true}") + private Boolean cleanWorkspaceAfterDeployment; + @Resource + private ScriptsGitRepoManage scriptsGitRepoManage; - public TerraformScriptsHelper(TerraformExecutor terraformExecutor) { - this.terraformExecutor = terraformExecutor; + + /** + * Create workspace for the Terraform deployment task. + * + * @param taskId id of the Terraform deployment task. + * @return workspace path for the Terraform deployment task. + */ + public String buildTaskWorkspace(String taskId) { + File ws = new File(getModuleParentDirectoryPath(), taskId); + if (!ws.exists() && !ws.mkdirs()) { + throw new TerraformExecutorException( + "Create task workspace failed, File path not created: " + ws.getAbsolutePath()); + } + return ws.getAbsolutePath(); } /** - * Creates the tfstate file in the directory of the Terraform module. + * Create the tfstate file in the taskWorkspace for the Terraform deployment task. * - * @param tfState state file contents as string. - * @param moduleLocation module location where the file must be created. + * @param taskWorkspace taskWorkspace path for the Terraform deployment task. + * @param tfState state file contents as string. */ - public void createTfStateFile(String tfState, String moduleLocation) { + public File createTfStateFile(String taskWorkspace, String tfState) { if (StringUtils.isBlank(tfState)) { - throw new TerraformExecutorException("terraform .tfState file create error"); + throw new TerraformExecutorException("tfState file create error"); } - String fileName = terraformExecutor.getModuleFullPath(moduleLocation) - + File.separator + STATE_FILE_NAME; - boolean overwrite = new File(fileName).exists(); - try (FileWriter scriptWriter = new FileWriter(fileName, overwrite)) { + File stateFile = new File(taskWorkspace, TF_STATE_FILE_NAME); + boolean overwrite = stateFile.exists(); + try (FileWriter scriptWriter = new FileWriter(stateFile, overwrite)) { scriptWriter.write(tfState); - log.info("terraform .tfState file create success, fileName: {}", fileName); + log.info("tfState file create success, fileName: {}", stateFile.getAbsolutePath()); + return stateFile; + } catch (IOException ex) { + log.error("tfState file create failed.", ex); + throw new TerraformExecutorException("tfState file create failed.", ex); + } + } + + + /** + * Prepare deployment files with scripts in the workspace for the Terraform deployment task. + * + * @param taskWorkspace workspace path for the Terraform deployment task. + * @param scripts list of script contents as string. + * @param tfState tfState file contents as string. + * @return list of script files. + */ + public List prepareDeploymentFilesWithScripts(String taskWorkspace, + List scripts, String tfState) { + File scriptFile = buildScriptFiles(taskWorkspace, scripts); + List scriptFiles = new ArrayList<>(); + scriptFiles.add(scriptFile); + if (StringUtils.isNotBlank(tfState)) { + File tfStateFile = createTfStateFile(taskWorkspace, tfState); + scriptFiles.add(tfStateFile); + } + return scriptFiles; + } + + + /** + * Prepare deployment files with git repo in the workspace for the Terraform deployment task. + * + * @param taskWorkspace workspace path for the Terraform deployment task. + * @param gitRepoDetails git repo details. + * @param tfState tfState file contents as string. + * @return list of script files. + */ + public List prepareDeploymentFilesWithGitRepo( + String taskWorkspace, TerraformScriptGitRepoDetails gitRepoDetails, String tfState) { + List scriptFiles = + scriptsGitRepoManage.checkoutScripts(taskWorkspace, gitRepoDetails); + List projectFiles = new ArrayList<>(scriptFiles); + if (StringUtils.isNotBlank(tfState)) { + File tfStateFile = createTfStateFile(taskWorkspace, tfState); + projectFiles.add(tfStateFile); + } + return projectFiles; + } + + + private File buildScriptFiles(String taskWorkspace, List scripts) { + log.info("start build terraform script"); + if (CollectionUtils.isEmpty(scripts)) { + throw new TerraformExecutorException("terraform scripts create error, terraform " + + "scripts not exists"); + } + StringBuilder scriptBuilder = new StringBuilder(); + for (String script : scripts) { + scriptBuilder.append(script).append(System.lineSeparator()); + } + if (scriptBuilder.isEmpty()) { + throw new TerraformExecutorException("terraform scripts create error, terraform " + + "scripts content is empty"); + } + File scriptFile = new File(taskWorkspace, TF_SCRIPT_FILE_NAME); + boolean overwrite = scriptFile.exists(); + try (FileWriter scriptWriter = new FileWriter(scriptFile, overwrite)) { + scriptWriter.write(scriptBuilder.toString()); + log.info("terraform script create success, fileName: {}", scriptFile.getAbsolutePath()); + return scriptFile; } catch (IOException ex) { - log.error("terraform .tfState file create failed.", ex); - throw new TerraformExecutorException("terraform .tfState file create failed.", ex); + log.error("terraform script create failed.", ex); + throw new TerraformExecutorException("terraform script create failed.", ex); } } + + /** + * Get the content of the tfState file in the workspace for the Terraform deployment task. + * + * @param taskWorkspace workspace path for the Terraform deployment task. + * @return tfState file contents as string. + */ + public String getTerraformState(String taskWorkspace) { + String state = null; + try { + File tfState = new File(taskWorkspace, TF_STATE_FILE_NAME); + if (tfState.exists()) { + state = Files.readString(tfState.toPath()); + } + } catch (IOException ex) { + log.error("Read state file failed.", ex); + } + return state; + } + + + /** + * Get the list of files in the workspace for the Terraform deployment task. + * + * @param taskWorkspace workspace path for the Terraform deployment task. + * @return list of files. + */ + public List getDeploymentFilesFromTaskWorkspace(String taskWorkspace) { + List scriptFiles = new ArrayList<>(); + File workPath = new File(taskWorkspace); + if (workPath.isDirectory() && workPath.exists()) { + File[] files = workPath.listFiles(); + if (Objects.nonNull(files)) { + Arrays.stream(files).forEach(file -> { + if (file.isFile()) { + scriptFiles.add(file); + } + }); + } + } + return scriptFiles; + } + + /** + * Get map of name and content of these generated files in the workspace for the Terraform + * deployment task. + * + * @param taskWorkspace workspace path for the Terraform deployment task. + * @param scriptFiles List of script files. + * @return Map of file name and file content. + */ + public Map getDeploymentGeneratedFilesContent(String taskWorkspace, + List scriptFiles) { + Map fileContentMap = new HashMap<>(); + File workPath = new File(taskWorkspace); + if (workPath.isDirectory() && workPath.exists()) { + File[] files = workPath.listFiles(); + if (Objects.nonNull(files)) { + Arrays.stream(files).forEach(file -> { + if (file.isFile() && !isExcludedFile(file.getName()) + && !scriptFiles.contains(file)) { + String content = readFileContentAndDelete(file); + fileContentMap.put(file.getName(), content); + } + }); + } + } + return fileContentMap; + } + + private String readFileContentAndDelete(File file) { + String fileContent = ""; + try { + fileContent = Files.readString(file.toPath()); + boolean deleted = Files.deleteIfExists(file.toPath()); + log.info("Read file content with name:{} successfully. Delete result:{}", + file.getName(), deleted); + } catch (IOException e) { + log.error("Read file content with name:{} error.", file.getName(), e); + } + return fileContent; + } + + + /** + * Delete the workspace of the Terraform deployment task. + * + * @param taskWorkspace workspace path for the Terraform deployment task. + */ + public void deleteTaskWorkspace(String taskWorkspace) { + if (cleanWorkspaceAfterDeployment) { + + Path path = Paths.get(taskWorkspace).toAbsolutePath().normalize(); + try (Stream pathStream = Files.walk(path)) { + pathStream.sorted(Comparator.reverseOrder()).map(Path::toFile) + .forEach(File::delete); + } catch (IOException e) { + log.error("Delete task workspace:{} error", taskWorkspace, e); + } + } + + } + + private boolean isExcludedFile(String fileName) { + String fileSuffix = fileName.substring(fileName.lastIndexOf(".")); + return EXCLUDED_FILE_SUFFIX_LIST.contains(fileSuffix); + } + + private String getModuleParentDirectoryPath() { + return StringUtils.isNotBlank(moduleParentDirectoryPath) ? moduleParentDirectoryPath : + System.getProperty("java.io.tmpdir"); + } } \ No newline at end of file diff --git a/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/service/TerraformScriptsService.java b/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/service/TerraformScriptsService.java index ff3faf5..3d40fa2 100644 --- a/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/service/TerraformScriptsService.java +++ b/src/main/java/org/eclipse/xpanse/terraform/boot/terraform/service/TerraformScriptsService.java @@ -5,15 +5,13 @@ package org.eclipse.xpanse.terraform.boot.terraform.service; +import jakarta.annotation.Resource; import java.io.File; -import java.io.FileWriter; -import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.UUID; import lombok.extern.slf4j.Slf4j; import org.eclipse.xpanse.terraform.boot.async.TaskConfiguration; -import org.eclipse.xpanse.terraform.boot.models.exceptions.TerraformExecutorException; import org.eclipse.xpanse.terraform.boot.models.plan.TerraformPlan; import org.eclipse.xpanse.terraform.boot.models.plan.TerraformPlanWithScriptsRequest; import org.eclipse.xpanse.terraform.boot.models.request.scripts.TerraformAsyncDeployFromScriptsRequest; @@ -24,11 +22,8 @@ import org.eclipse.xpanse.terraform.boot.models.request.scripts.TerraformModifyWithScriptsRequest; import org.eclipse.xpanse.terraform.boot.models.response.TerraformResult; import org.eclipse.xpanse.terraform.boot.models.validation.TerraformValidationResult; -import org.eclipse.xpanse.terraform.boot.terraform.TerraformExecutor; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; import org.springframework.web.client.RestTemplate; /** @@ -36,50 +31,47 @@ */ @Slf4j @Service -public class TerraformScriptsService extends TerraformDirectoryService { +public class TerraformScriptsService { - private static final String FILE_SUFFIX = ".tf"; - private final RestTemplate restTemplate; - private final TerraformExecutor executor; - private final TerraformScriptsHelper terraformScriptsHelper; - - /** - * TerraformScriptsService constructor. - */ - @Autowired - public TerraformScriptsService(TerraformExecutor executor, RestTemplate restTemplate, - TerraformScriptsHelper terraformScriptsHelper) { - super(executor, restTemplate); - this.executor = executor; - this.restTemplate = restTemplate; - - this.terraformScriptsHelper = terraformScriptsHelper; - } + @Resource + private RestTemplate restTemplate; + @Resource + private TerraformScriptsHelper scriptsHelper; + @Resource + private TerraformDirectoryService directoryService; /** + * /** * Method of deployment a service using a script. */ public TerraformValidationResult validateWithScripts( TerraformDeployWithScriptsRequest request) { - UUID uuid = UUID.randomUUID(); - buildDeployEnv(request.getScripts(), uuid); - return tfValidateFromDirectory(uuid.toString(), request.getTerraformVersion()); + String taskWorkspace = scriptsHelper.buildTaskWorkspace(UUID.randomUUID().toString()); + scriptsHelper.prepareDeploymentFilesWithScripts(taskWorkspace, request.getScripts(), null); + return directoryService.tfValidateFromDirectory(taskWorkspace, + request.getTerraformVersion()); } /** * Method of deployment a service using a script. */ public TerraformResult deployWithScripts(TerraformDeployWithScriptsRequest request, UUID uuid) { - buildDeployEnv(request.getScripts(), uuid); - return deployFromDirectory(request, uuid.toString()); + String taskWorkspace = scriptsHelper.buildTaskWorkspace(uuid.toString()); + List files = + scriptsHelper.prepareDeploymentFilesWithScripts(taskWorkspace, request.getScripts(), + null); + return directoryService.deployFromDirectory(request, taskWorkspace, files); } /** * Method of modify a service using a script. */ public TerraformResult modifyWithScripts(TerraformModifyWithScriptsRequest request, UUID uuid) { - buildModifyEnv(request.getScripts(), request.getTfState(), uuid); - return modifyFromDirectory(request, uuid.toString()); + String taskWorkspace = scriptsHelper.buildTaskWorkspace(uuid.toString()); + List files = + scriptsHelper.prepareDeploymentFilesWithScripts(taskWorkspace, request.getScripts(), + request.getTfState()); + return directoryService.modifyFromDirectory(request, taskWorkspace, files); } /** @@ -87,8 +79,11 @@ public TerraformResult modifyWithScripts(TerraformModifyWithScriptsRequest reque */ public TerraformResult destroyWithScripts(TerraformDestroyWithScriptsRequest request, UUID uuid) { - buildDestroyEnv(request.getScripts(), request.getTfState(), uuid); - return destroyFromDirectory(request, uuid.toString()); + String taskWorkspace = scriptsHelper.buildTaskWorkspace(uuid.toString()); + List files = + scriptsHelper.prepareDeploymentFilesWithScripts(taskWorkspace, request.getScripts(), + request.getTfState()); + return directoryService.destroyFromDirectory(request, taskWorkspace, files); } /** @@ -96,27 +91,25 @@ public TerraformResult destroyWithScripts(TerraformDestroyWithScriptsRequest req */ public TerraformPlan getTerraformPlanFromScripts(TerraformPlanWithScriptsRequest request, UUID uuid) { - buildDeployEnv(request.getScripts(), uuid); - return getTerraformPlanFromDirectory(request, uuid.toString()); + String taskWorkspace = scriptsHelper.buildTaskWorkspace(uuid.toString()); + scriptsHelper.prepareDeploymentFilesWithScripts(taskWorkspace, request.getScripts(), null); + return directoryService.getTerraformPlanFromDirectory(request, uuid.toString()); } /** * Async deploy a source by terraform. */ @Async(TaskConfiguration.TASK_EXECUTOR_NAME) - public void asyncDeployWithScripts( - TerraformAsyncDeployFromScriptsRequest asyncDeployRequest, UUID uuid) { + public void asyncDeployWithScripts(TerraformAsyncDeployFromScriptsRequest asyncDeployRequest, + UUID uuid) { TerraformResult result; try { result = deployWithScripts(asyncDeployRequest, uuid); } catch (RuntimeException e) { - result = TerraformResult.builder() - .commandStdOutput(null) - .commandStdError(e.getMessage()) - .isCommandSuccessful(false) - .terraformState(null) - .importantFileContentMap(new HashMap<>()) - .build(); + result = + TerraformResult.builder().commandStdOutput(null).commandStdError(e.getMessage()) + .isCommandSuccessful(false).terraformState(null) + .generatedFileContentMap(new HashMap<>()).build(); } result.setRequestId(asyncDeployRequest.getRequestId()); String url = asyncDeployRequest.getWebhookConfig().getUrl(); @@ -128,19 +121,16 @@ public void asyncDeployWithScripts( * Async modify a source by terraform. */ @Async(TaskConfiguration.TASK_EXECUTOR_NAME) - public void asyncModifyWithScripts( - TerraformAsyncModifyFromScriptsRequest asyncModifyRequest, UUID uuid) { + public void asyncModifyWithScripts(TerraformAsyncModifyFromScriptsRequest asyncModifyRequest, + UUID uuid) { TerraformResult result; try { result = modifyWithScripts(asyncModifyRequest, uuid); } catch (RuntimeException e) { - result = TerraformResult.builder() - .commandStdOutput(null) - .commandStdError(e.getMessage()) - .isCommandSuccessful(false) - .terraformState(null) - .importantFileContentMap(new HashMap<>()) - .build(); + result = + TerraformResult.builder().commandStdOutput(null).commandStdError(e.getMessage()) + .isCommandSuccessful(false).terraformState(null) + .generatedFileContentMap(new HashMap<>()).build(); } result.setRequestId(asyncModifyRequest.getRequestId()); String url = asyncModifyRequest.getWebhookConfig().getUrl(); @@ -158,64 +148,14 @@ public void asyncDestroyWithScripts(TerraformAsyncDestroyFromScriptsRequest requ try { result = destroyWithScripts(request, uuid); } catch (RuntimeException e) { - result = TerraformResult.builder() - .commandStdOutput(null) - .commandStdError(e.getMessage()) - .isCommandSuccessful(false) - .terraformState(null) - .importantFileContentMap(new HashMap<>()) - .build(); + result = + TerraformResult.builder().commandStdOutput(null).commandStdError(e.getMessage()) + .isCommandSuccessful(false).terraformState(null) + .generatedFileContentMap(new HashMap<>()).build(); } result.setRequestId(request.getRequestId()); String url = request.getWebhookConfig().getUrl(); log.info("Destroy service complete, callback POST url:{}, requestBody:{}", url, result); restTemplate.postForLocation(url, result); } - - private void buildDeployEnv(List scripts, UUID uuid) { - String workspace = executor.getModuleFullPath(uuid.toString()); - buildWorkspace(workspace); - buildScriptFiles(workspace, uuid, scripts); - } - - private void buildModifyEnv(List scripts, String tfState, UUID uuid) { - buildDeployEnv(scripts, uuid); - terraformScriptsHelper.createTfStateFile(tfState, uuid.toString()); - } - - private void buildDestroyEnv(List scripts, String tfState, UUID uuid) { - buildDeployEnv(scripts, uuid); - terraformScriptsHelper.createTfStateFile(tfState, uuid.toString()); - } - - private void buildWorkspace(String workspace) { - log.info("start create workspace"); - File ws = new File(workspace); - if (!ws.exists() && !ws.mkdirs()) { - throw new TerraformExecutorException( - "Create workspace failed, File path not created: " + ws.getAbsolutePath()); - } - log.info("workspace create success,Working directory is " + ws.getAbsolutePath()); - } - - private void buildScriptFiles(String workspace, UUID uuid, List scripts) { - log.info("start build terraform script"); - if (CollectionUtils.isEmpty(scripts)) { - throw new TerraformExecutorException("terraform scripts create error, terraform " - + "scripts not exists"); - } - StringBuilder scriptBuilder = new StringBuilder(); - for (String script : scripts) { - scriptBuilder.append(script).append(System.lineSeparator()); - } - String fileName = workspace + File.separator + uuid + FILE_SUFFIX; - boolean overwrite = new File(fileName).exists(); - try (FileWriter scriptWriter = new FileWriter(fileName, overwrite)) { - scriptWriter.write(scriptBuilder.toString()); - log.info("terraform script create success, fileName: {}", fileName); - } catch (IOException ex) { - log.error("terraform script create failed.", ex); - throw new TerraformExecutorException("terraform script create failed.", ex); - } - } }