Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions config/rest-gateway/rest.json.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
},

"port": 3000,
"protocol": "{{{restProtocol}}}",
"sslKeyPath": "{{{restSSLPath}}}/{{{restSSLKeyFileName}}}",
"sslCertificatePath": "{{{restSSLPath}}}/{{{restSSLCertificateFileName}}}",

"crossDomain": {
"allowedHosts": ["*"],
"allowedMethods": ["GET", "POST", "PUT", "OPTIONS"]
Expand Down
8 changes: 8 additions & 0 deletions presets/bootstrap/network.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,14 @@ faucets:
BLACKLIST_MOSAIC_IDS: '[]'
EXPLORER_URL: 'http://localhost:{{add $index 90}}/'
openPort: '{{add $index 100}}'
httpsProxies:
- name: 'https-proxy'
excludeDockerService: true #disabled as default
openPort: 3001
#domains: 'symbol-node.example.com -> http://rest-gateway:3000'
stage: 'production'
webSocket: 'true'
serverNamesHashBucketSize: 128
inflation:
starting-at-height-1: 0
starting-at-height-10000: 0
8 changes: 8 additions & 0 deletions presets/mainnet/assembly-api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,11 @@ gateways:
databaseHost: 'db'
openPort: true
ipv4_address: 172.20.0.25
httpsProxies:
- name: 'https-proxy'
excludeDockerService: true #disabled as default
openPort: 3001
#domains: 'symbol-node.example.com -> http://rest-gateway:3000'
stage: 'production'
webSocket: 'true'
serverNamesHashBucketSize: 128
8 changes: 8 additions & 0 deletions presets/mainnet/assembly-dual.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,11 @@ gateways:
databaseHost: 'db'
openPort: true
ipv4_address: 172.20.0.25
httpsProxies:
- name: 'https-proxy'
excludeDockerService: true #disabled as default
openPort: 3001
#domains: 'symbol-node.example.com -> http://rest-gateway:3000'
stage: 'production'
webSocket: 'true'
serverNamesHashBucketSize: 128
Comment thread
Jaguar0625 marked this conversation as resolved.
2 changes: 1 addition & 1 deletion presets/mainnet/network.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ minVotingKeyLifetime: 112
maxVotingKeyLifetime: 360
votingKeyDesiredLifetime: 360
votingKeyDesiredFutureLifetime: 60
lastKnownNetworkEpoch: 255
lastKnownNetworkEpoch: 280
stepDuration: 5m
maxBlockFutureTime: 300ms
maxAccountRestrictionValues: 100
Expand Down
7 changes: 6 additions & 1 deletion presets/shared.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,13 @@ maxChildNamespaces: 256
maxNamespaceDepth: 3
batchVerificationRandomSource:
symbolServerImage: symbolplatform/symbol-server:gcc-10-1.0.1.0
symbolRestImage: symbolplatform/symbol-rest:2.3.6
symbolRestImage: symbolplatform/symbol-rest:2.3.7-alpha
symbolExplorerImage: symbolplatform/symbol-explorer:1.1.0-alpha
symbolWalletImage: symbolplatform/symbol-desktop-wallet:1.0.1
symbolFaucetImage: symbolplatform/symbol-faucet:1.0.1-alpha
symbolAgentImage: symbolplatform/symbol-node-rewards-agent:2.0.0
mongoImage: mongo:4.4.3-bionic
httpsPortalImage: steveltn/https-portal:1.19
mongoComposeRunParam: --wiredTigerCacheSizeGB 2
logLevel: 'Info'
# brokerLogLevel: 'Info'
Expand Down Expand Up @@ -214,3 +215,7 @@ connectionPoolSize: 10
maxSubscriptions: 300
restExtensions: 'accountLink, aggregate, lockHash, lockSecret, mosaic, metadata, multisig, namespace, receipts, restrictions, transfer, cmc'
restDeploymentTool: symbol-bootstrap
restProtocol: HTTP
Comment thread
Jaguar0625 marked this conversation as resolved.
restSSLPath: '/symbol-workdir'
restSSLKeyFileName: 'restSSL.key'
restSSLCertificateFileName: 'restSSL.crt'
8 changes: 8 additions & 0 deletions presets/testnet/assembly-api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,11 @@ gateways:
databaseHost: 'db'
openPort: true
ipv4_address: 172.20.0.25
httpsProxies:
- name: 'https-proxy'
excludeDockerService: true #disabled as default
openPort: 3001
#domains: 'symbol-node.example.com -> http://rest-gateway:3000'
stage: 'production'
webSocket: 'true'
serverNamesHashBucketSize: 128
8 changes: 8 additions & 0 deletions presets/testnet/assembly-dual.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,11 @@ gateways:
databaseHost: 'db'
openPort: true
ipv4_address: 172.20.0.25
httpsProxies:
- name: 'https-proxy'
excludeDockerService: true #disabled as default
openPort: 3001
#domains: 'symbol-node.example.com -> http://rest-gateway:3000'
stage: 'production'
webSocket: 'true'
serverNamesHashBucketSize: 128
2 changes: 1 addition & 1 deletion presets/testnet/network.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ importanceGrouping: 180
votingSetGrouping: 720
votingKeyDesiredLifetime: 720
votingKeyDesiredFutureLifetime: 120
lastKnownNetworkEpoch: 365
lastKnownNetworkEpoch: 408
minVotingKeyLifetime: 28
maxVotingKeyLifetime: 720
stepDuration: 4m
Expand Down
109 changes: 101 additions & 8 deletions src/commands/wizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import { Command, flags } from '@oclif/command';
import { IOptionFlag } from '@oclif/command/lib/flags';
import { existsSync } from 'fs';
import { existsSync, readFileSync } from 'fs';
import { prompt } from 'inquirer';
import { Account, NetworkType, PublicAccount } from 'symbol-sdk';
import { CustomPreset, PrivateKeySecurityMode } from '../model';
Expand All @@ -39,6 +39,11 @@ export const assemblies: Record<Preset, { value: string; description: string }[]
{ value: 'api', description: 'Api Node' },
],
};
export enum HttpsOption {
Native = 'Native',
Automatic = 'Automatic',
None = 'None',
}
export enum Network {
mainnet = 'mainnet',
testnet = 'testnet',
Expand Down Expand Up @@ -123,9 +128,7 @@ export default class Wizard extends Command {

if (!flags.skipPull) {
const service = await new BootstrapService();
console.log();
console.log('Pulling catapult tools image before asking to go offline...');
console.log();
console.log('\nPulling catapult tools image before asking to go offline...\n');
Comment thread
Jaguar0625 marked this conversation as resolved.
ConfigLoader.presetInfoLogged = true;
await BootstrapUtils.pullImage(
service.resolveConfigPreset({
Expand Down Expand Up @@ -183,13 +186,46 @@ export default class Wizard extends Command {
console.log();
console.log();

const symbolHostRequired = !!rewardProgram;
const httpsOption: HttpsOption = await this.resolveHttpsOptions();

const symbolHostNameRequired = httpsOption !== HttpsOption.None;
const host = await Wizard.resolveHost(
`Enter the public hostname or IP of your future node. ${
symbolHostRequired ? 'This value is required when you are in a reward program!' : ''
`Enter the public domain name(eg. node-01.mysymbolnodes.com) that's pointing to your outbound host IP ${
symbolHostNameRequired ? 'This value is required when you are running on HTTPS!' : ''
}`,
symbolHostRequired,
symbolHostNameRequired,
);

const resolveHttpsCustomPreset = async (): Promise<CustomPreset> => {
if (httpsOption === HttpsOption.Native) {
const restSSLKeyBase64 = await Wizard.resolveRestSSLKeyAsBase64();
const restSSLCertificateBase64 = await Wizard.resolveRestSSLCertAsBase64();
return {
gateways: [
{
restProtocol: 'HTTPS',
openPort: 3001,
restSSLKeyBase64,
restSSLCertificateBase64,
},
],
};
} else if (httpsOption === HttpsOption.Automatic) {
return {
httpsProxies: [
{
excludeDockerService: false,
},
],
};
} else {
// HttpsOption.None
console.log(`Warning! You've chosen to proceed with http, which is less secure in comparison to https.`);
return {};
}
};

const httpsCustomPreset = await resolveHttpsCustomPreset();
const friendlyName = await Wizard.resolveFriendlyName(host || accounts.main.publicKey.substr(0, 7));
const privateKeySecurityMode = await Wizard.resolvePrivateKeySecurityMode();
const voting = await Wizard.isVoting();
Expand All @@ -210,7 +246,9 @@ export default class Wizard extends Command {
agentPrivateKey: accounts.agent?.privateKey,
},
],
...httpsCustomPreset,
};

const defaultParams = ConfigService.defaultParams;
await BootstrapUtils.writeYaml(customPresetFile, presetContent, password);
console.log();
Expand Down Expand Up @@ -512,6 +550,37 @@ export default class Wizard extends Command {
return host || undefined;
}

public static async resolveRestSSLKeyAsBase64(): Promise<string> {
return this.resolveFileContent('base64', 'Enter your SSL key file path:', 'Invalid path, cannot find SSL key file!');
}

public static async resolveRestSSLCertAsBase64(): Promise<string> {
return this.resolveFileContent(
'base64',
'Enter your SSL Certificate file path:',
'Invalid path, cannot find SSL certificate file!',
);
}

public static async resolveFileContent(encoding: string, message: string, notFoundMessage: string): Promise<string> {
const { value } = await prompt([
{
name: 'value',
message: message,
type: 'input',
validate: (value) => {
if (!existsSync(value)) {
return notFoundMessage;
}
return true;
},
},
]);

return readFileSync(value, encoding);
}

// TODO Refactor this
public static isValidHost(input: string): boolean | string {
if (input.trim() == '') {
return 'Host is required.';
Expand Down Expand Up @@ -546,4 +615,28 @@ export default class Wizard extends Command {
]);
return friendlyName;
}

public static async resolveHttpsOptions(): Promise<HttpsOption> {
// TODO work on these messages, should be concise and clearer
console.log(
'Your REST Gateway should be running on HTTPS (which is a secure protocol) so that it can be recognized by the Symbol Explorer.',
);
const { value } = await prompt([
{
name: 'value',
message: 'Select your HTTPS setup method:',
type: 'list',
default: HttpsOption.Native,
choices: [
{ name: 'Native support, I have the SSL certificate and key.', value: HttpsOption.Native },
{
name: `Automatic, all of your keys and certs will be generated/renewed automatically, using letsencyrpt.`,
value: HttpsOption.Automatic,
},
{ name: 'None', value: HttpsOption.None },
],
},
]);
return value;
}
}
17 changes: 17 additions & 0 deletions src/model/ConfigPreset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,12 @@ export interface GatewayConfigPreset {
restDeploymentTool: string;
restDeploymentToolVersion?: string; // default is dynamic, current bootstrap version
restDeploymentToolLastUpdatedDate?: string; // default is dynamic, current datetime
restProtocol: 'HTTPS' | 'HTTP';
restSSLPath: string;
restSSLKeyFileName: string;
restSSLCertificateFileName: string;
restSSLKeyBase64?: string;
restSSLCertificateBase64?: string;
Comment thread
Jaguar0625 marked this conversation as resolved.
}

export interface GatewayPreset extends DockerServicePreset, Partial<GatewayConfigPreset> {
Expand All @@ -329,6 +335,14 @@ export interface GatewayPreset extends DockerServicePreset, Partial<GatewayConfi
name: string;
}

export interface HttpsProxyPreset extends DockerServicePreset {
name?: string;
domains: string;
stage: string;
webSocket?: string;
serverNamesHashBucketSize?: number;
}

export interface ExplorerPreset extends DockerServicePreset {
// At least these properties.
repeat?: number;
Expand Down Expand Up @@ -394,6 +408,7 @@ export interface CommonConfigPreset extends NodeConfigPreset, GatewayConfigPrese
symbolAgentImage: string;
symbolRestImage: string;
symbolFaucetImage: string;
httpsPortalImage: string;

dockerComposeVersion: number | string;
dockerComposeServiceRestart: string;
Expand Down Expand Up @@ -439,6 +454,7 @@ export interface ConfigPreset extends CommonConfigPreset {
explorers?: ExplorerPreset[];
wallets?: WalletPreset[];
faucets?: FaucetPreset[];
httpsProxies?: HttpsProxyPreset[];
}

export interface CustomPreset extends Partial<CommonConfigPreset> {
Expand All @@ -449,4 +465,5 @@ export interface CustomPreset extends Partial<CommonConfigPreset> {
explorers?: Partial<ExplorerPreset>[];
wallets?: Partial<WalletPreset>[];
faucets?: Partial<FaucetPreset>[];
httpsProxies?: Partial<HttpsProxyPreset>[];
}
2 changes: 2 additions & 0 deletions src/service/BootstrapUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,8 @@ export class BootstrapUtils {
// Create a promise that rejects in <ms> milliseconds
return new Promise<void>((resolve) => {
setTimeout(() => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
resolve();
}, ms);
});
Expand Down
Loading