Skip to content

Commit

Permalink
fix: write s-public-alias.pem file for each node to a configurable lo…
Browse files Browse the repository at this point in the history
…cation (#15266)

Signed-off-by: Iris Simon <iris.simon@swirldslabs.com>
  • Loading branch information
iwsimon authored Aug 30, 2024
1 parent 97e886a commit 37d1891
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
*
* @param upgradeArtifactsPath path to the location where upgrade files are stored once uncompressed, and upgrade
* marker files are written
* @param keysPath path to the generated public key *.pem files during freeze prepare upgrade
* @param upgradeSysFilesLoc path to the location where post-upgrade system files are located
* @param upgradeFeeSchedulesFile name of the file containing the post-upgrade fee schedules
* @param upgradeThrottlesFile name of the file containing the post-upgrade throttles
Expand All @@ -34,6 +35,7 @@
@ConfigData("networkAdmin")
public record NetworkAdminConfig(
@ConfigProperty(defaultValue = "data/upgrade/current") @NodeProperty String upgradeArtifactsPath,
@ConfigProperty(defaultValue = "data/upgrade/current/data/keys") @NodeProperty String keysPath,
@ConfigProperty(defaultValue = "data/config") String upgradeSysFilesLoc,
@ConfigProperty(defaultValue = "feeSchedules.json") String upgradeFeeSchedulesFile,
@ConfigProperty(defaultValue = "throttles.json") String upgradeThrottlesFile,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,9 @@ private CompletableFuture<Void> extractNow(
requireNonNull(marker);

final Path artifactsLoc = getAbsolutePath(adminServiceConfig.upgradeArtifactsPath());
final Path keysLoc = getAbsolutePath(adminServiceConfig.keysPath());
requireNonNull(artifactsLoc);
requireNonNull(keysLoc);
final long size = archiveData.length();
log.info("About to unzip {} bytes for {} update into {}", size, desc, artifactsLoc);
// we spin off a separate thread to avoid blocking handleTransaction
Expand All @@ -235,7 +237,7 @@ private CompletableFuture<Void> extractNow(
final var nextNodeId = getNextNodeID(nodeStore);
return runAsync(
() -> extractAndReplaceArtifacts(
artifactsLoc, archiveData, size, desc, marker, now, activeNodes, nextNodeId),
artifactsLoc, keysLoc, archiveData, size, desc, marker, now, activeNodes, nextNodeId),
executor);
}

Expand All @@ -254,6 +256,7 @@ private List<ActiveNode> allActiveNodes() {

private void extractAndReplaceArtifacts(
@NonNull final Path artifactsLoc,
@NonNull final Path keysLoc,
@NonNull final Bytes archiveData,
final long size,
@NonNull final String desc,
Expand All @@ -263,14 +266,19 @@ private void extractAndReplaceArtifacts(
long nextNodeId) {
try {
final var artifactsDir = artifactsLoc.toFile();
final var keysDir = keysLoc.toFile();
if (!FileUtils.isDirectory(artifactsDir)) {
FileUtils.forceMkdir(artifactsDir);
}
FileUtils.cleanDirectory(artifactsDir);
if (!FileUtils.isDirectory(keysDir)) {
FileUtils.forceMkdir(keysDir);
}
FileUtils.cleanDirectory(keysDir);
UnzipUtility.unzip(archiveData.toByteArray(), artifactsLoc);
log.info("Finished unzipping {} bytes for {} update into {}", size, desc, artifactsLoc);
if (nodes != null && nodesConfig.enableDAB()) {
generateConfigPem(artifactsLoc, nodes, nextNodeId);
generateConfigPem(artifactsLoc, keysLoc, nodes, nextNodeId);
log.info("Finished generating config.txt and pem files into {}", artifactsLoc);
}
writeSecondMarker(marker, now);
Expand All @@ -284,8 +292,12 @@ private void extractAndReplaceArtifacts(
}

private void generateConfigPem(
@NonNull final Path artifactsLoc, @NonNull final List<ActiveNode> activeNodes, long nextNodeId) {
@NonNull final Path artifactsLoc,
@NonNull final Path keysLoc,
@NonNull final List<ActiveNode> activeNodes,
long nextNodeId) {
requireNonNull(artifactsLoc, "Cannot generate config.txt without a valid artifacts location");
requireNonNull(keysLoc, "Cannot generate pem files without a valid keys location");
requireNonNull(activeNodes, "Cannot generate config.txt without a valid list of active nodes");
final var configTxt = artifactsLoc.resolve("config.txt");

Expand All @@ -296,7 +308,7 @@ private void generateConfigPem(

try (final var fw = new FileWriter(configTxt.toFile());
final var bw = new BufferedWriter(fw)) {
activeNodes.forEach(node -> writeConfigLineAndPem(node, bw, artifactsLoc));
activeNodes.forEach(node -> writeConfigLineAndPem(node, bw, keysLoc));
bw.write("nextNodeId, " + nextNodeId);
bw.flush();
} catch (final IOException e) {
Expand All @@ -305,17 +317,17 @@ private void generateConfigPem(
}

private void writeConfigLineAndPem(
@NonNull final ActiveNode activeNode, @NonNull final BufferedWriter bw, @NonNull final Path pathToWrite) {
@NonNull final ActiveNode activeNode, @NonNull final BufferedWriter bw, @NonNull final Path keysLoc) {
requireNonNull(activeNode);
requireNonNull(bw);
requireNonNull(pathToWrite);
requireNonNull(keysLoc);

var line = new StringBuilder();
int weight = 0;
final var node = activeNode.node();
final var name = "node" + (node.nodeId() + 1);
final var alias = nameToAlias(name);
final var pemFile = pathToWrite.resolve("s-public-" + alias + ".pem");
final var pemFile = keysLoc.resolve("s-public-" + alias + ".pem");
final int INT = 0;
final int EXT = 1;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ class ReadableFreezeUpgradeActionsTest {
@TempDir
private File zipOutputDir; // temp directory to place marker files and output of zip extraction

@TempDir
private File keysDir;

@Mock
private WritableFreezeStore writableFreezeStore;

Expand Down Expand Up @@ -196,6 +199,7 @@ void complainsLoudlyWhenUnableToUnzipArchive() {
rmIfPresent(EXEC_IMMEDIATE_MARKER);

given(adminServiceConfig.upgradeArtifactsPath()).willReturn(zipOutputDir.toString());
given(adminServiceConfig.keysPath()).willReturn(keysDir.toString());

final Bytes invalidArchive = Bytes.wrap("Not a valid zip archive".getBytes(StandardCharsets.UTF_8));
subject.extractSoftwareUpgrade(invalidArchive).join();
Expand All @@ -214,6 +218,7 @@ void preparesForUpgrade() throws IOException {
rmIfPresent(EXEC_IMMEDIATE_MARKER);

given(adminServiceConfig.upgradeArtifactsPath()).willReturn(zipOutputDir.toString());
given(adminServiceConfig.keysPath()).willReturn(keysDir.toString());
given(nodesConfig.enableDAB()).willReturn(true);

final Bytes realArchive = Bytes.wrap(Files.readAllBytes(zipArchivePath));
Expand All @@ -230,12 +235,13 @@ void preparesForUpgradeWithDAB() throws IOException, CertificateException {
setupNodes();

given(adminServiceConfig.upgradeArtifactsPath()).willReturn(zipOutputDir.toString());
given(adminServiceConfig.keysPath()).willReturn(keysDir.toString());
given(nodesConfig.enableDAB()).willReturn(true);

final Bytes realArchive = Bytes.wrap(Files.readAllBytes(zipArchivePath));
subject.extractSoftwareUpgrade(realArchive).join();

assertDABFilesCreated(EXEC_IMMEDIATE_MARKER, zipOutputDir.toPath());
assertDABFilesCreated(EXEC_IMMEDIATE_MARKER, zipOutputDir.toPath(), keysDir.toPath());
assertMarkerCreated(EXEC_IMMEDIATE_MARKER, null);
}

Expand All @@ -246,12 +252,13 @@ void preparesForUpgradeWithDAB2() throws IOException, CertificateException {
setupNodes2();

given(adminServiceConfig.upgradeArtifactsPath()).willReturn(zipOutputDir.toString());
given(adminServiceConfig.keysPath()).willReturn(keysDir.toString());
given(nodesConfig.enableDAB()).willReturn(true);

final Bytes realArchive = Bytes.wrap(Files.readAllBytes(zipArchivePath));
subject.extractSoftwareUpgrade(realArchive).join();

assertDABFilesCreated2(EXEC_IMMEDIATE_MARKER, zipOutputDir.toPath());
assertDABFilesCreated2(EXEC_IMMEDIATE_MARKER, zipOutputDir.toPath(), keysDir.toPath());
assertMarkerCreated(EXEC_IMMEDIATE_MARKER, null);
}

Expand All @@ -260,6 +267,7 @@ void upgradesTelemetry() throws IOException {
rmIfPresent(EXEC_TELEMETRY_MARKER);

given(adminServiceConfig.upgradeArtifactsPath()).willReturn(zipOutputDir.toString());
given(adminServiceConfig.keysPath()).willReturn(keysDir.toString());

final Bytes realArchive = Bytes.wrap(Files.readAllBytes(zipArchivePath));
subject.extractTelemetryUpgrade(realArchive, then).join();
Expand Down Expand Up @@ -481,19 +489,20 @@ private void setupNodes() throws CertificateException, IOException {
given(stakingInfoStore.get(4)).willReturn(stakingNodeInfo4);
}

private void assertDABFilesCreated(final String file, final Path baseDir) throws IOException, CertificateException {
private void assertDABFilesCreated(final String file, final Path baseDir, final Path keyDir)
throws IOException, CertificateException {
final Path filePath = baseDir.resolve(file);
final Path configFilePath = baseDir.resolve("config.txt");
assertTrue(configFilePath.toFile().exists());
final var configFile = Files.readString(configFilePath);

final Path pemFilePath1 = baseDir.resolve("s-public-node2.pem");
final Path pemFilePath1 = keyDir.resolve("s-public-node2.pem");
assertTrue(pemFilePath1.toFile().exists());
final Path pemFilePath2 = baseDir.resolve("s-public-node3.pem");
final Path pemFilePath2 = keyDir.resolve("s-public-node3.pem");
assertTrue(pemFilePath2.toFile().exists());
final Path pemFilePath3 = baseDir.resolve("s-public-node4.pem");
final Path pemFilePath3 = keyDir.resolve("s-public-node4.pem");
assertFalse(pemFilePath3.toFile().exists());
final Path pemFilePath4 = baseDir.resolve("s-public-node5.pem");
final Path pemFilePath4 = keyDir.resolve("s-public-node5.pem");
assertTrue(pemFilePath4.toFile().exists());
final var pemFile1 = readCertificatePemFile(pemFilePath1);
final var pemFile2 = readCertificatePemFile(pemFilePath2);
Expand Down Expand Up @@ -605,20 +614,20 @@ private void setupNodes2() throws CertificateException, IOException {
given(stakingInfoStore.get(2)).willReturn(stakingNodeInfo3);
}

private void assertDABFilesCreated2(final String file, final Path baseDir)
private void assertDABFilesCreated2(final String file, final Path baseDir, final Path keyDir)
throws IOException, CertificateException {
final Path filePath = baseDir.resolve(file);
final Path configFilePath = baseDir.resolve("config.txt");
assertTrue(configFilePath.toFile().exists());
final var configFile = Files.readString(configFilePath);

final Path pemFilePath1 = baseDir.resolve("s-public-node1.pem");
final Path pemFilePath1 = keyDir.resolve("s-public-node1.pem");
assertTrue(pemFilePath1.toFile().exists());
final Path pemFilePath2 = baseDir.resolve("s-public-node2.pem");
final Path pemFilePath2 = keyDir.resolve("s-public-node2.pem");
assertTrue(pemFilePath2.toFile().exists());
final Path pemFilePath3 = baseDir.resolve("s-public-node3.pem");
final Path pemFilePath3 = keyDir.resolve("s-public-node3.pem");
assertTrue(pemFilePath3.toFile().exists());
final Path pemFilePath4 = baseDir.resolve("s-public-node4.pem");
final Path pemFilePath4 = keyDir.resolve("s-public-node4.pem");
assertFalse(pemFilePath4.toFile().exists());
final var pemFile1 = readCertificatePemFile(pemFilePath1);
final var pemFile2 = readCertificatePemFile(pemFilePath2);
Expand Down

0 comments on commit 37d1891

Please sign in to comment.