Skip to content

Commit

Permalink
Return OpenTofu with version in response (#69)
Browse files Browse the repository at this point in the history
  • Loading branch information
baixinsui authored Oct 15, 2024
1 parent c185dc2 commit e228200
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ public class OpenTofuPlan {
@Schema(description = "OpenTofu plan as a JSON string")
String plan;

@Schema(description = "The exact version of the OpenTofu which executed the scripts.")
String openTofuVersion;
@Schema(description = "The version of the OpenTofu binary used to execute scripts.")
String openTofuVersionUsed;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ public class OpenTofuResult {

@Schema(description = "Id of the request.")
private UUID requestId;
@Schema(description = "The exact version of the OpenTofu which executed the scripts.")
String openTofuVersion;
@NotNull
@Schema(description = "defines if the command was successfully executed")
private boolean isCommandSuccessful;
Expand All @@ -35,4 +33,6 @@ public class OpenTofuResult {
@Schema(description = "Data of all other files generated by the openTofu execution."
+ "The map key contains the file name and value is the file contents as string.")
private Map<String, String> importantFileContentMap;
@Schema(description = "The version of the OpenTofu binary used to execute scripts.")
String openTofuVersionUsed;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
package org.eclipse.xpanse.tofu.maker.models.validation;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import lombok.Data;

Expand All @@ -16,7 +18,13 @@
@JsonIgnoreProperties(ignoreUnknown = true)
public class OpenTofuValidationResult {

@NotNull
@Schema(description = "Defines if the scripts is valid.")
private boolean valid;
private String openTofuVersion;

@Schema(description = "The version of the OpenTofu binary used to execute scripts.")
private String openTofuVersionUsed;

@Schema(description = "List of validation errors.")
private List<OpenTofuValidateDiagnostics> diagnostics;
}
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public OpenTofuValidationResult tfValidateFromDirectory(String moduleDirectory,
OpenTofuValidationResult validationResult =
new ObjectMapper().readValue(result.getCommandStdOutput(),
OpenTofuValidationResult.class);
validationResult.setOpenTofuVersion(
validationResult.setOpenTofuVersionUsed(
versionHelper.getExactVersionOfExecutor(executorPath));
return validationResult;
} catch (JsonProcessingException ex) {
Expand Down Expand Up @@ -164,7 +164,8 @@ public OpenTofuResult deployFromDirectory(OpenTofuDeployFromDirectoryRequest req
}
String workspace = executor.getModuleFullPath(moduleDirectory);
OpenTofuResult openTofuResult = transSystemCmdResultToOpenTofuResult(result, workspace);
openTofuResult.setOpenTofuVersion(versionHelper.getExactVersionOfExecutor(executorPath));
openTofuResult.setOpenTofuVersionUsed(
versionHelper.getExactVersionOfExecutor(executorPath));
if (cleanWorkspaceAfterDeployment) {
deleteWorkspace(workspace);
}
Expand Down Expand Up @@ -200,7 +201,8 @@ public OpenTofuResult modifyFromDirectory(OpenTofuModifyFromDirectoryRequest req
String workspace = executor.getModuleFullPath(moduleDirectory);
OpenTofuResult openTofuResult =
transSystemCmdResultToOpenTofuResult(result, workspace);
openTofuResult.setOpenTofuVersion(versionHelper.getExactVersionOfExecutor(executorPath));
openTofuResult.setOpenTofuVersionUsed(
versionHelper.getExactVersionOfExecutor(executorPath));
if (cleanWorkspaceAfterDeployment) {
deleteWorkspace(workspace);
}
Expand Down Expand Up @@ -228,7 +230,8 @@ public OpenTofuResult destroyFromDirectory(OpenTofuDestroyFromDirectoryRequest r
}
String workspace = executor.getModuleFullPath(moduleDirectory);
OpenTofuResult openTofuResult = transSystemCmdResultToOpenTofuResult(result, workspace);
openTofuResult.setOpenTofuVersion(versionHelper.getExactVersionOfExecutor(executorPath));
openTofuResult.setOpenTofuVersionUsed(
versionHelper.getExactVersionOfExecutor(executorPath));
deleteWorkspace(workspace);
openTofuResult.setRequestId(request.getRequestId());
return openTofuResult;
Expand All @@ -245,7 +248,8 @@ public OpenTofuPlan getOpenTofuPlanFromDirectory(OpenTofuPlanFromDirectoryReques
request.getEnvVariables(), moduleDirectory);
deleteWorkspace(executor.getModuleFullPath(moduleDirectory));
OpenTofuPlan openTofuPlan = OpenTofuPlan.builder().plan(result).build();
openTofuPlan.setOpenTofuVersion(versionHelper.getExactVersionOfExecutor(executorPath));
openTofuPlan.setOpenTofuVersionUsed(
versionHelper.getExactVersionOfExecutor(executorPath));
return openTofuPlan;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public String getExecutorPathThatMatchesRequiredVersion(String requiredVersion)
this.versionHelper.getOperatorAndNumberFromRequiredVersion(requiredVersion);
String requiredOperator = operatorAndNumber[0];
String requiredNumber = operatorAndNumber[1];
// Get path of the executor matched required version in the environment.
// Find executor in the installation path that matches the required version.
String matchedVersionExecutorPath =
this.versionHelper.getExecutorPathMatchedRequiredVersion(
this.openTofuInstallDir, requiredOperator, requiredNumber);
Expand All @@ -71,9 +71,8 @@ private String installOpenTofuByRequiredVersion(String requiredOperator,
requiredOperator, requiredNumber);
File installedExecutorFile = this.versionHelper.installOpenTofuWithVersion(
bestVersionNumber, this.openTofuDownloadBaseUrl, this.openTofuInstallDir);
if (this.versionHelper.checkIfExecutorVersionIsValid(installedExecutorFile,
requiredOperator, requiredNumber)) {
log.info("OpenTofu with version {} installed successfully.", installedExecutorFile);
if (this.versionHelper.checkIfExecutorCanBeExecuted(installedExecutorFile)) {
log.info("OpenTofu with version {} installed successfully.", installedExecutorFile);
return installedExecutorFile.getAbsolutePath();
}
String errorMsg = String.format("Installing OpenTofu with version %s into the dir %s "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ public String getExecutorPathMatchedRequiredVersion(String installationDir,
executorVersionFileMap.keySet(), requiredOperator, requiredNumber);
if (StringUtils.isNotBlank(findBestVersion)) {
File executorFile = executorVersionFileMap.get(findBestVersion);
if (checkIfExecutorVersionIsValid(executorFile, requiredOperator, requiredNumber)) {
if (checkIfExecutorIsMatchedRequiredVersion(
executorFile, requiredOperator, requiredNumber)) {
return executorFile.getAbsolutePath();
}
}
Expand Down Expand Up @@ -154,52 +155,76 @@ public String findBestVersionFromAllAvailableVersions(Set<String> allAvailableVe
}

/**
* Check if the exact version of openTofu executor is valid.
* Check the version of installed executor is matched required version.
*
* @param executorFile executor file
* @param requiredOperator operator in required version
* @param requiredNumber number in required version
* @return true if the version is valid, otherwise return false.
*/
public boolean checkIfExecutorVersionIsValid(File executorFile,
String requiredOperator,
String requiredNumber) {
if (!executorFile.exists() && !executorFile.isFile()) {
return false;
public boolean checkIfExecutorIsMatchedRequiredVersion(File executorFile,
String requiredOperator,
String requiredNumber) {
String versionNumber = getExactVersionOfExecutor(executorFile.getAbsolutePath());
if (StringUtils.isNotBlank(versionNumber)) {
return isVersionSatisfied(versionNumber, requiredOperator, requiredNumber);
}
if (!executorFile.canExecute()) {
SystemCmdResult chmodResult = systemCmd.execute(
String.format("chmod +x %s", executorFile.getAbsolutePath()),
5, System.getProperty("java.io.tmpdir"), false, new HashMap<>());
if (!chmodResult.isCommandSuccessful()) {
log.error(chmodResult.getCommandStdError());
return false;
}
}
String actualVersion = getExactVersionOfExecutor(executorFile.getAbsolutePath());
if (StringUtils.isBlank(actualVersion)) {
return false;
}
return isVersionSatisfied(actualVersion, requiredOperator, requiredNumber);
return false;
}


/**
* Get the exact version of openTofu executor.
* Check if the executor can be executed.
*
* @param executorFile executor file
* @return If true, the executor can be executed, otherwise return false.
*/
public boolean checkIfExecutorCanBeExecuted(File executorFile) {
String versionOutput = getVersionCommandOutput(executorFile);
return StringUtils.isNotBlank(versionOutput);
}

/**
* Get exact version of executor.
*
* @param executorPath the path of openTofu executor
* @return the exact version of openTofu executor
* @param executorPath executor path
* @return exact version of executor.
*/
public String getExactVersionOfExecutor(String executorPath) {
if (StringUtils.isBlank(executorPath)) {
return null;
String versionOutput = getVersionCommandOutput(new File(executorPath));
Matcher matcher = OPENTOFU_VERSION_OUTPUT_PATTERN.matcher(versionOutput);
if (matcher.find()) {
// return only the version number.
return matcher.group(1);
}
SystemCmdResult versionCheckResult = systemCmd.execute(executorPath + " -v",
5, System.getProperty("java.io.tmpdir"), false, new HashMap<>());
if (versionCheckResult.isCommandSuccessful()) {
return getActualVersionFromCommandOutput(versionCheckResult.getCommandStdOutput());
} else {
log.error(versionCheckResult.getCommandStdError());
return null;
}


private String getVersionCommandOutput(File executorFile) {
try {
if (!executorFile.exists() && !executorFile.isFile()) {
return null;
}
if (!executorFile.canExecute()) {
SystemCmdResult chmodResult = systemCmd.execute(
String.format("chmod +x %s", executorFile.getAbsolutePath()),
5, System.getProperty("java.io.tmpdir"), false, new HashMap<>());
if (!chmodResult.isCommandSuccessful()) {
log.error(chmodResult.getCommandStdError());
}
}
SystemCmdResult versionCheckResult =
systemCmd.execute(executorFile.getAbsolutePath() + " version",
5, System.getProperty("java.io.tmpdir"), false, new HashMap<>());
if (versionCheckResult.isCommandSuccessful()) {
return versionCheckResult.getCommandStdOutput();
} else {
log.error(versionCheckResult.getCommandStdError());
return null;
}
} catch (Exception e) {
log.error("Failed to get version of executor {}.", executorFile.getAbsolutePath(), e);
return null;
}
}
Expand Down Expand Up @@ -323,14 +348,6 @@ private String getVersionFromExecutorPath(String executorPath) {
return null;
}

private String getActualVersionFromCommandOutput(String commandOutput) {
Matcher matcher = OPENTOFU_VERSION_OUTPUT_PATTERN.matcher(commandOutput);
if (matcher.find()) {
return matcher.group(1);
}
return null;
}

private boolean isVersionSatisfied(String actualNumber, String requiredOperator,
String requiredNumber) {
Semver actualSemver = new Semver(actualNumber);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,23 @@ void testGetExecutableOpenTofuByVersion() {
requiredVersion1);
String openTofuPath1 =
installer.getExecutorPathThatMatchesRequiredVersion(requiredVersion1);
assertTrue(versionHelper.checkIfExecutorVersionIsValid(new File(openTofuPath1),
assertTrue(versionHelper.checkIfExecutorIsMatchedRequiredVersion(new File(openTofuPath1),
operatorAndNumber1[0], operatorAndNumber1[1]));

String requiredVersion2 = "= 1.6.0";
String[] operatorAndNumber2 = versionHelper.getOperatorAndNumberFromRequiredVersion(
requiredVersion2);
String openTofuPath2 =
installer.getExecutorPathThatMatchesRequiredVersion(requiredVersion2);
assertTrue(versionHelper.checkIfExecutorVersionIsValid(new File(openTofuPath2),
assertTrue(versionHelper.checkIfExecutorIsMatchedRequiredVersion(new File(openTofuPath2),
operatorAndNumber2[0], operatorAndNumber2[1]));

String requiredVersion3 = ">= v1.8.0";
String[] operatorAndNumber3 = versionHelper.getOperatorAndNumberFromRequiredVersion(
requiredVersion3);
String openTofuPath3 =
installer.getExecutorPathThatMatchesRequiredVersion(requiredVersion3);
assertTrue(versionHelper.checkIfExecutorVersionIsValid(new File(openTofuPath3),
assertTrue(versionHelper.checkIfExecutorIsMatchedRequiredVersion(new File(openTofuPath3),
operatorAndNumber3[0], operatorAndNumber3[1]));

String requiredVersion4 = ">= 100.0.0";
Expand Down

0 comments on commit e228200

Please sign in to comment.