Skip to content

Commit

Permalink
Merge 8c96a53 into 54e7d0c
Browse files Browse the repository at this point in the history
  • Loading branch information
fboucquez committed Jan 12, 2022
2 parents 54e7d0c + 8c96a53 commit 5de3828
Show file tree
Hide file tree
Showing 27 changed files with 505 additions and 131 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -315,6 +315,7 @@ npm run style:fix
* [`symbol-bootstrap link`](docs/link.md) - It announces VRF and Voting Link transactions to the network for each node with 'Peer' or 'Voting' roles. This command finalizes the node registration to an existing network.
* [`symbol-bootstrap modifyMultisig`](docs/modifyMultisig.md) - Create or modify a multisig account
* [`symbol-bootstrap pack`](docs/pack.md) - It configures and packages your node into a zip file that can be uploaded to the final node machine.
* [`symbol-bootstrap renewCertificates`](docs/renewCertificates.md) - It renews the ssl certificates of the node regenerating the main ca.cert.pem and node.csr.pem files but reusing the current private keys.
* [`symbol-bootstrap report`](docs/report.md) - it generates reStructuredText (.rst) reports describing the configuration of each node.
* [`symbol-bootstrap resetData`](docs/resetData.md) - It removes the data keeping the generated configuration, certificates, keys and block 1.
* [`symbol-bootstrap run`](docs/run.md) - It boots the network via docker using the generated `docker-compose.yml` file and configuration. The config and compose methods/commands need to be called before this method. This is just a wrapper for the `docker-compose up` bash call.
Expand Down
2 changes: 1 addition & 1 deletion docs/clean.md
Expand Up @@ -24,4 +24,4 @@ EXAMPLE
$ symbol-bootstrap clean
```

_See code: [src/commands/clean.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.2/src/commands/clean.ts)_
_See code: [src/commands/clean.ts](https://github.com/fboucquez/symbol-bootstrap/blob/v1.1.2/src/commands/clean.ts)_
2 changes: 1 addition & 1 deletion docs/compose.md
Expand Up @@ -36,4 +36,4 @@ EXAMPLE
$ symbol-bootstrap compose
```

_See code: [src/commands/compose.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.2/src/commands/compose.ts)_
_See code: [src/commands/compose.ts](https://github.com/fboucquez/symbol-bootstrap/blob/v1.1.2/src/commands/compose.ts)_
2 changes: 1 addition & 1 deletion docs/config.md
Expand Up @@ -62,4 +62,4 @@ EXAMPLES
$ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap config -p testnet -a dual
```

_See code: [src/commands/config.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.2/src/commands/config.ts)_
_See code: [src/commands/config.ts](https://github.com/fboucquez/symbol-bootstrap/blob/v1.1.2/src/commands/config.ts)_
2 changes: 1 addition & 1 deletion docs/decrypt.md
Expand Up @@ -59,4 +59,4 @@ EXAMPLES
plain-addresses.yml
```

_See code: [src/commands/decrypt.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.2/src/commands/decrypt.ts)_
_See code: [src/commands/decrypt.ts](https://github.com/fboucquez/symbol-bootstrap/blob/v1.1.2/src/commands/decrypt.ts)_
2 changes: 1 addition & 1 deletion docs/encrypt.md
Expand Up @@ -49,4 +49,4 @@ EXAMPLES
encrypted-custom-preset.yml
```

_See code: [src/commands/encrypt.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.2/src/commands/encrypt.ts)_
_See code: [src/commands/encrypt.ts](https://github.com/fboucquez/symbol-bootstrap/blob/v1.1.2/src/commands/encrypt.ts)_
2 changes: 1 addition & 1 deletion docs/healthCheck.md
Expand Up @@ -39,4 +39,4 @@ EXAMPLE
$ symbol-bootstrap healthCheck
```

_See code: [src/commands/healthCheck.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.2/src/commands/healthCheck.ts)_
_See code: [src/commands/healthCheck.ts](https://github.com/fboucquez/symbol-bootstrap/blob/v1.1.2/src/commands/healthCheck.ts)_
2 changes: 1 addition & 1 deletion docs/link.md
Expand Up @@ -58,4 +58,4 @@ EXAMPLES
$ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap link --unlink --useKnownRestGateways
```

_See code: [src/commands/link.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.2/src/commands/link.ts)_
_See code: [src/commands/link.ts](https://github.com/fboucquez/symbol-bootstrap/blob/v1.1.2/src/commands/link.ts)_
2 changes: 1 addition & 1 deletion docs/modifyMultisig.md
Expand Up @@ -69,4 +69,4 @@ EXAMPLES
$ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap modifyMultisig --useKnownRestGateways
```

_See code: [src/commands/modifyMultisig.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.2/src/commands/modifyMultisig.ts)_
_See code: [src/commands/modifyMultisig.ts](https://github.com/fboucquez/symbol-bootstrap/blob/v1.1.2/src/commands/modifyMultisig.ts)_
2 changes: 1 addition & 1 deletion docs/pack.md
Expand Up @@ -63,4 +63,4 @@ EXAMPLES
$ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap pack -c custom-preset.yml
```

_See code: [src/commands/pack.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.2/src/commands/pack.ts)_
_See code: [src/commands/pack.ts](https://github.com/fboucquez/symbol-bootstrap/blob/v1.1.2/src/commands/pack.ts)_
54 changes: 54 additions & 0 deletions docs/renewCertificates.md
@@ -0,0 +1,54 @@
`symbol-bootstrap renewCertificates`
====================================

It renews the ssl certificates of the node regenerating the main ca.cert.pem and node.csr.pem files but reusing the current private keys.

This command does not change the node private key (yet). This change would require a harvesters.dat migration and relinking the node key.

It's recommended to backup the target folder before running this operation!

* [`symbol-bootstrap renewCertificates`](#symbol-bootstrap-renewcertificates)

## `symbol-bootstrap renewCertificates`

It renews the ssl certificates of the node regenerating the main ca.cert.pem and node.csr.pem files but reusing the current private keys.

```
USAGE
$ symbol-bootstrap renewCertificates
OPTIONS
-c, --customPreset=customPreset This command uses the encrypted addresses.yml to resolve the main and transport
private key. If the main and transport privates are only stored in the custom preset,
you can provide them using this param. Otherwise, the command may ask for them when
required.
-h, --help It shows the help of this command.
-t, --target=target [default: target] The target folder where the symbol-bootstrap network is generated
-u, --user=user [default: current] User used to run docker images when generating the certificates.
"current" means the current user.
--logger=logger [default: Console,File] The loggers the command will use. Options are:
Console,File,Silent. Use ',' to select multiple loggers.
--noPassword When provided, Bootstrap will not use a password, so private keys will be stored in
plain text. Use with caution.
--password=password A password used to encrypt and decrypt private keys in preset files like
addresses.yml and preset.yml. Bootstrap prompts for a password by default, can be
provided in the command line (--password=XXXX) or disabled in the command line
(--noPassword).
DESCRIPTION
This command does not change the node private key (yet). This change would require a harvesters.dat migration and
relinking the node key.
It's recommended to backup the target folder before running this operation!
EXAMPLE
$ symbol-bootstrap renewCertificates
```

_See code: [src/commands/renewCertificates.ts](https://github.com/fboucquez/symbol-bootstrap/blob/v1.1.2/src/commands/renewCertificates.ts)_
2 changes: 1 addition & 1 deletion docs/report.md
Expand Up @@ -24,4 +24,4 @@ EXAMPLE
$ symbol-bootstrap report
```

_See code: [src/commands/report.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.2/src/commands/report.ts)_
_See code: [src/commands/report.ts](https://github.com/fboucquez/symbol-bootstrap/blob/v1.1.2/src/commands/report.ts)_
2 changes: 1 addition & 1 deletion docs/resetData.md
Expand Up @@ -24,4 +24,4 @@ EXAMPLE
$ symbol-bootstrap resetData
```

_See code: [src/commands/resetData.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.2/src/commands/resetData.ts)_
_See code: [src/commands/resetData.ts](https://github.com/fboucquez/symbol-bootstrap/blob/v1.1.2/src/commands/resetData.ts)_
2 changes: 1 addition & 1 deletion docs/run.md
Expand Up @@ -57,4 +57,4 @@ EXAMPLE
$ symbol-bootstrap run
```

_See code: [src/commands/run.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.2/src/commands/run.ts)_
_See code: [src/commands/run.ts](https://github.com/fboucquez/symbol-bootstrap/blob/v1.1.2/src/commands/run.ts)_
2 changes: 1 addition & 1 deletion docs/start.md
Expand Up @@ -98,4 +98,4 @@ EXAMPLES
$ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap start -p testnet -a dual
```

_See code: [src/commands/start.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.2/src/commands/start.ts)_
_See code: [src/commands/start.ts](https://github.com/fboucquez/symbol-bootstrap/blob/v1.1.2/src/commands/start.ts)_
2 changes: 1 addition & 1 deletion docs/stop.md
Expand Up @@ -24,4 +24,4 @@ EXAMPLE
$ symbol-bootstrap stop
```

_See code: [src/commands/stop.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.2/src/commands/stop.ts)_
_See code: [src/commands/stop.ts](https://github.com/fboucquez/symbol-bootstrap/blob/v1.1.2/src/commands/stop.ts)_
2 changes: 1 addition & 1 deletion docs/updateVotingKeys.md
Expand Up @@ -47,4 +47,4 @@ EXAMPLE
$ symbol-bootstrap updateVotingKeys
```

_See code: [src/commands/updateVotingKeys.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.2/src/commands/updateVotingKeys.ts)_
_See code: [src/commands/updateVotingKeys.ts](https://github.com/fboucquez/symbol-bootstrap/blob/v1.1.2/src/commands/updateVotingKeys.ts)_
2 changes: 1 addition & 1 deletion docs/verify.md
Expand Up @@ -23,4 +23,4 @@ EXAMPLE
$ symbol-bootstrap verify
```

_See code: [src/commands/verify.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.2/src/commands/verify.ts)_
_See code: [src/commands/verify.ts](https://github.com/fboucquez/symbol-bootstrap/blob/v1.1.2/src/commands/verify.ts)_
2 changes: 1 addition & 1 deletion docs/wizard.md
Expand Up @@ -39,4 +39,4 @@ EXAMPLE
$ symbol-bootstrap wizard
```

_See code: [src/commands/wizard.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.2/src/commands/wizard.ts)_
_See code: [src/commands/wizard.ts](https://github.com/fboucquez/symbol-bootstrap/blob/v1.1.2/src/commands/wizard.ts)_
4 changes: 3 additions & 1 deletion presets/shared.yml
Expand Up @@ -87,7 +87,9 @@ catapultAppFolder: /usr/catapult
enableRevoteOnBoot: true
totalVotingBalanceCalculationFix: 0
treasuryReissuance: 0

caCertificateExpirationInDays: 7300 # 20 years
nodeCertificateExpirationInDays: 375 # 1.02 years
certificateExpirationWarningInDays: 30 # certificates are allowed to be renewed 30 before expiring
# config database
databaseName: catapult
maxWriterThreads: 8
Expand Down
107 changes: 107 additions & 0 deletions src/commands/renewCertificates.ts
@@ -0,0 +1,107 @@
/*
* Copyright 2021 Symbol
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Command, flags } from '@oclif/command';
import { Account } from 'symbol-sdk';
import { LoggerFactory, System } from '../logger';
import { CertificatePair, ConfigAccount, ConfigPreset } from '../model';
import { BootstrapUtils, CertificateService, CommandUtils, ConfigLoader } from '../service';

export default class RenewCertificates extends Command {
static description = `It renews the ssl certificates of the node regenerating the main ca.cert.pem and node.csr.pem files but reusing the current private keys.
This command does not change the node private key (yet). This change would require a harvesters.dat migration and relinking the node key.
It's recommended to backup the target folder before running this operation!
`;

static examples = [`$ symbol-bootstrap renewCertificates`];

static flags = {
help: CommandUtils.helpFlag,
target: CommandUtils.targetFlag,
password: CommandUtils.passwordFlag,
noPassword: CommandUtils.noPasswordFlag,
customPreset: flags.string({
char: 'c',
description: `This command uses the encrypted addresses.yml to resolve the main and transport private key. If the main and transport privates are only stored in the custom preset, you can provide them using this param. Otherwise, the command may ask for them when required.`,
required: false,
}),
user: flags.string({
char: 'u',
description: `User used to run docker images when generating the certificates. "${BootstrapUtils.CURRENT_USER}" means the current user.`,
default: BootstrapUtils.CURRENT_USER,
}),
logger: CommandUtils.getLoggerFlag(...System),
};

public async run(): Promise<void> {
const { flags } = this.parse(RenewCertificates);
CommandUtils.showBanner();
const logger = LoggerFactory.getLogger(flags.logger);
const password = await CommandUtils.resolvePassword(
logger,
flags.password,
flags.noPassword,
CommandUtils.passwordPromptDefaultMessage,
true,
);
const target = flags.target;
const configLoader = new ConfigLoader(logger);
const presetData = configLoader.loadExistingPresetData(target, password);
const addresses = configLoader.loadExistingAddresses(target, password);
const customPreset = configLoader.loadCustomPreset(flags.customPreset, password);
const mergedPresetData: ConfigPreset = configLoader.mergePresets(presetData, customPreset);

const networkType = presetData.networkType;
const certificateService = new CertificateService(logger, {
target,
user: flags.user,
});
const certificateUpgraded = (
await Promise.all(
(mergedPresetData.nodes || []).map((nodePreset, index) => {
const nodeAccount = addresses.nodes?.[index];
if (!nodeAccount) {
throw new Error(`There is not node in addresses at index ${index}`);
}
function resolveAccount(configAccount: ConfigAccount, providedPrivateKey: string | undefined): CertificatePair {
if (providedPrivateKey) {
const account = Account.createFromPrivateKey(providedPrivateKey, networkType);
if (account.address.plain() == configAccount.address) {
return account;
}
}
return configAccount;
}
const providedCertificates = {
main: resolveAccount(nodeAccount.main, nodePreset.mainPrivateKey),
transport: resolveAccount(nodeAccount.transport, nodePreset.transportPrivateKey),
};
return certificateService.run(mergedPresetData, nodePreset.name, providedCertificates, true);
}),
)
).find((f) => f);
if (certificateUpgraded) {
logger.warn('');
logger.warn('Bootstrap has created new ssl certificates. Review the logs!');
logger.warn('');
} else {
logger.info('');
logger.info('The ssl certificates are up-to-date. There is nothing to upgrade.');
logger.info('');
}
}
}
3 changes: 3 additions & 0 deletions src/model/ConfigPreset.ts
Expand Up @@ -251,6 +251,9 @@ export interface NodeConfigPreset {
maxProofSize: number;
maxTransactionsPerBlock: number;
localNetworks: string;
caCertificateExpirationInDays: number;
nodeCertificateExpirationInDays: number;
certificateExpirationWarningInDays: number;
}

export interface NodePreset extends DockerServicePreset, Partial<NodeConfigPreset> {
Expand Down
16 changes: 11 additions & 5 deletions src/service/BootstrapUtils.ts
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import { spawn } from 'child_process';
import { ExecException, spawn } from 'child_process';
import {
createWriteStream,
existsSync,
Expand Down Expand Up @@ -271,13 +271,15 @@ export class BootstrapUtils {
workdir,
cmds,
binds,
ignoreErrors,
}: {
catapultAppFolder?: string;
image: string;
userId?: string;
workdir?: string;
cmds: string[];
binds: string[];
ignoreErrors?: boolean;
},
): Promise<{ stdout: string; stderr: string }> {
const volumes = binds.map((b) => `-v ${b}`).join(' ');
Expand All @@ -288,7 +290,7 @@ export class BootstrapUtils {
.map((a) => `"${a}"`)
.join(' ')}`;
logger.info(BootstrapUtils.secureString(`Running image using Exec: ${image} ${cmds.join(' ')}`));
return this.exec(logger, runCommand);
return this.exec(logger, runCommand, ignoreErrors);
}

public static toAns1(privateKey: string): string {
Expand Down Expand Up @@ -508,10 +510,14 @@ export class BootstrapUtils {
return (await this.exec(logger, runCommand)).stdout;
}

public static async exec(logger: Logger, runCommand: string): Promise<{ stdout: string; stderr: string }> {
public static exec(logger: Logger, runCommand: string, ignoreErrors?: boolean): Promise<{ stdout: string; stderr: string }> {
logger.debug(`Exec command: ${runCommand}`);
const { stdout, stderr } = await exec(runCommand);
return { stdout, stderr };
return new Promise((promiseResolve, promiseReject) => {
exec(runCommand, (error: ExecException | null, stdout: string, stderr: string) => {
if (error && !ignoreErrors) promiseReject(error);
else promiseResolve({ stdout, stderr });
});
});
}

public static async spawn(logger: Logger, command: string, args: string[], useLogger: boolean, logPrefix = ''): Promise<string> {
Expand Down

0 comments on commit 5de3828

Please sign in to comment.