Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add the ability to inject a ca certificate for use in gRPC and gRPC Web #753

Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
ef27998
initial implementation
instamenta Oct 25, 2024
16fe662
successfully copy cert to secret and accept the flags
instamenta Oct 28, 2024
3bf0848
switch the strategy for the grpc tls cert to not depend on grpc web t…
instamenta Oct 28, 2024
b0cf02b
merge with main
instamenta Oct 28, 2024
703a9fc
added tests for certificate manager
instamenta Oct 28, 2024
bce591d
Add comments that explains what the new functionality does and how to…
instamenta Oct 29, 2024
3dc64a8
added the task to the node add commmand
instamenta Oct 29, 2024
98a88e0
add new flag soo the certificate key can be passed
instamenta Oct 29, 2024
962794f
change the strategy and implement a functionality for creating secret…
instamenta Oct 30, 2024
63a54ec
fix the unit tests
instamenta Oct 30, 2024
0303059
Merge remote-tracking branch 'origin/main' into 00719-add-ability-to-…
instamenta Oct 30, 2024
aaac9b8
fix prompting
instamenta Oct 30, 2024
a871e9d
remove oboslete code and unnecessary changes
instamenta Oct 30, 2024
235c36d
merge with main
instamenta Oct 31, 2024
a896382
fix tests and flags of node add command
instamenta Nov 1, 2024
0f837d2
Merge remote-tracking branch 'origin/main' into 00719-add-ability-to-…
instamenta Nov 1, 2024
5c468e2
fix test
instamenta Nov 1, 2024
c799c4a
Apply suggestions from code review
instamenta Nov 6, 2024
6c8c08d
merge with main
instamenta Nov 6, 2024
b4f5c51
Merge remote-tracking branch 'origin/main' into 00719-add-ability-to-…
instamenta Nov 7, 2024
0892da7
Apply suggestions from code review
instamenta Nov 7, 2024
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
60 changes: 59 additions & 1 deletion src/commands/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,60 @@ export const hederaExplorerVersion: CommandFlag = {
}
}

//* ------------- Node Proxy Certificates ------------- !//

export const grpcTlsCertificatePath: CommandFlag = {
constName: 'grpcTlsCertificatePath',
name: 'grpc-tls-cert',
definition: {
describe:
'TLS Certificate path for the gRPC ' +
'(e.g. "node1=/Users/username/node1-grpc.cert" ' +
'with multiple nodes comma seperated',
instamenta marked this conversation as resolved.
Show resolved Hide resolved
defaultValue: '',
type: 'string'
}
}

export const grpcWebTlsCertificatePath: CommandFlag = {
constName: 'grpcWebTlsCertificatePath',
name: 'grpc-web-tls-cert',
definition: {
describe:
'TLS Certificate path for gRPC Web ' +
'(e.g. "node1=/Users/username/node1-grpc-web.cert" ' +
'with multiple nodes comma seperated',
instamenta marked this conversation as resolved.
Show resolved Hide resolved
defaultValue: '',
type: 'string'
}
}

export const grpcTlsKeyPath: CommandFlag = {
constName: 'grpcTlsKeyPath',
name: 'grpc-tls-key',
definition: {
describe:
'TLS Certificate key path for the gRPC ' +
'(e.g. "node1=/Users/username/node1-grpc.key" ' +
'with multiple nodes comma seperated',
instamenta marked this conversation as resolved.
Show resolved Hide resolved
defaultValue: '',
type: 'string'
}
}

export const grpcWebTlsKeyPath: CommandFlag = {
constName: 'grpcWebTlsKeyPath',
name: 'grpc-web-tls-key',
definition: {
describe:
'TLC Certificate key path for gRPC Web ' +
'(e.g. "node1=/Users/username/node1-grpc-web.key" ' +
'with multiple nodes comma seperated',
instamenta marked this conversation as resolved.
Show resolved Hide resolved
defaultValue: '',
type: 'string'
}
}

export const allFlags: CommandFlag[] = [
accountId,
amount,
Expand Down Expand Up @@ -773,7 +827,11 @@ export const allFlags: CommandFlag[] = [
mirrorNodeVersion,
hederaExplorerVersion,
inputDir,
outputDir
outputDir,
grpcTlsCertificatePath,
grpcWebTlsCertificatePath,
grpcTlsKeyPath,
grpcWebTlsKeyPath,
instamenta marked this conversation as resolved.
Show resolved Hide resolved
]

/** Resets the definition.disablePrompt for all flags */
Expand Down
40 changes: 33 additions & 7 deletions src/commands/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,21 @@
* limitations under the License.
*
*/

import { ListrEnquirerPromptAdapter } from '@listr2/prompt-adapter-enquirer'
import chalk from 'chalk'
import { Listr } from 'listr2'
import { SoloError, IllegalArgumentError, MissingArgumentError } from '../core/errors.ts'
import { BaseCommand } from './base.ts'
import * as flags from './flags.ts'
import type { KeyManager, PlatformInstaller, ProfileManager } from '../core/index.ts'
import { constants, Templates } from '../core/index.ts'
import * as prompts from './prompts.ts'
import * as helpers from '../core/helpers.ts'
import path from 'path'
import { addDebugOptions, validatePath } from '../core/helpers.ts'
import fs from 'fs'
import { type NodeAlias, type NodeAliases } from '../types/aliases.ts'
import { type Opts } from '../types/index.ts'
import type { CertificateManager, KeyManager, PlatformInstaller, ProfileManager } from '../core/index.ts'
import type { NodeAlias, NodeAliases } from '../types/aliases.ts'
import type { Opts } from '../types/index.ts'

export interface NetworkDeployConfigClass {
applicationEnv: string
Expand All @@ -48,14 +47,19 @@
nodeAliases: NodeAliases
stagingDir: string
stagingKeysDir: string
valuesArg: string
valuesArg: string,
grpcTlsCertificatePath: string,
grpcWebTlsCertificatePath: string,
grpcTlsKeyPath: string,
grpcWebTlsKeyPath: string,
instamenta marked this conversation as resolved.
Show resolved Hide resolved
getUnusedConfigs: () => string[]
}

export class NetworkCommand extends BaseCommand {
private readonly keyManager: KeyManager
private readonly platformInstaller: PlatformInstaller
private readonly profileManager: ProfileManager
private readonly certificateManager: CertificateManager
private profileValuesFile?: string

constructor (opts: Opts) {
Expand All @@ -65,7 +69,9 @@
if (!opts || !opts.keyManager) throw new IllegalArgumentError('An instance of core/KeyManager is required', opts.keyManager)
if (!opts || !opts.platformInstaller) throw new IllegalArgumentError('An instance of core/PlatformInstaller is required', opts.platformInstaller)
if (!opts || !opts.profileManager) throw new MissingArgumentError('An instance of core/ProfileManager is required', opts.downloader)
if (!opts || !opts.certificateManager) throw new MissingArgumentError('An instance of core/CertificateManager is required', opts.certificateManager)

this.certificateManager = opts.certificateManager
this.keyManager = opts.keyManager
this.platformInstaller = opts.platformInstaller
this.profileManager = opts.profileManager
Expand Down Expand Up @@ -97,7 +103,11 @@
flags.quiet,
flags.releaseTag,
flags.settingTxt,
flags.valuesFile
flags.valuesFile,
flags.grpcTlsCertificatePath,
flags.grpcWebTlsCertificatePath,
flags.grpcTlsKeyPath,
flags.grpcWebTlsKeyPath,
instamenta marked this conversation as resolved.
Show resolved Hide resolved
]
}

Expand Down Expand Up @@ -160,7 +170,11 @@
flags.persistentVolumeClaims,
flags.profileName,
flags.profileFile,
flags.settingTxt
flags.settingTxt,
flags.grpcTlsCertificatePath,
flags.grpcWebTlsCertificatePath,
flags.grpcTlsKeyPath,
flags.grpcWebTlsKeyPath,
instamenta marked this conversation as resolved.
Show resolved Hide resolved
])

await prompts.execute(task, this.configManager, NetworkCommand.DEPLOY_FLAGS_LIST)
Expand Down Expand Up @@ -230,6 +244,18 @@
return lease.buildAcquireTask(task)
}
},
{
title: 'Copy gRPC TLS Certificates',
task: (ctx, parentTask) =>
self.certificateManager.buildCopyTlsCertificatesTasks(
parentTask,
ctx.config.grpcTlsCertificatePath,
ctx.config.grpcWebTlsCertificatePath,
ctx.config.grpcTlsKeyPath,
ctx.config.grpcWebTlsKeyPath

Check warning on line 255 in src/commands/network.ts

View check run for this annotation

Codecov / codecov/patch

src/commands/network.ts#L250-L255

Added lines #L250 - L255 were not covered by tests
),
skip: (ctx) => !ctx.config.grpcTlsCertificatePath && !ctx.config.grpcWebTlsCertificatePath
},
{
title: 'Prepare staging directory',
task: (_, parentTask) => {
Expand Down
4 changes: 4 additions & 0 deletions src/commands/node/configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,10 @@ export interface NodeAddConfigClass {
treasuryKey: PrivateKey
stagingDir: string
stagingKeysDir: string
grpcTlsCertificatePath: string,
grpcWebTlsCertificatePath: string,
grpcTlsKeyPath: string,
grpcWebTlsKeyPath: string,
instamenta marked this conversation as resolved.
Show resolved Hide resolved
getUnusedConfigs: () => string[]
}

Expand Down
6 changes: 5 additions & 1 deletion src/commands/node/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,11 @@ const COMMON_ADD_REQUIRED_NO_PROMPT_FLAGS = [
flags.chainId,
flags.debugNodeAlias,
flags.soloChartVersion,
flags.persistentVolumeClaims
flags.persistentVolumeClaims,
flags.grpcTlsCertificatePath,
flags.grpcWebTlsCertificatePath,
flags.grpcTlsKeyPath,
flags.grpcWebTlsKeyPath,
instamenta marked this conversation as resolved.
Show resolved Hide resolved
]

const COMMON_ADD_OPTIONAL_FLAGS = [
Expand Down
1 change: 1 addition & 0 deletions src/commands/node/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ export class NodeCommandHandlers {
this.tasks.checkPVCsEnabled(),
this.tasks.identifyExistingNodes(),
this.tasks.determineNewNodeAccountNumber(),
this.tasks.copyGrpcTlsCertificates(),
this.tasks.generateGossipKey(),
this.tasks.generateGrpcTlsKey(),
this.tasks.loadSigningKeyCertificate(),
Expand Down
2 changes: 2 additions & 0 deletions src/commands/node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export class NodeCommand extends BaseCommand {
if (!opts || !opts.keyManager) throw new IllegalArgumentError('An instance of core/KeyManager is required', opts.keyManager)
if (!opts || !opts.accountManager) throw new IllegalArgumentError('An instance of core/AccountManager is required', opts.accountManager)
if (!opts || !opts.profileManager) throw new IllegalArgumentError('An instance of ProfileManager is required', opts.profileManager)
if (!opts || !opts.certificateManager) throw new IllegalArgumentError('An instance of CertificateManager is required', opts.certificateManager)

this.accountManager = opts.accountManager
this._portForwards = []
Expand All @@ -55,6 +56,7 @@ export class NodeCommand extends BaseCommand {
k8: opts.k8,
keyManager: opts.keyManager,
chartManager: opts.chartManager,
certificateManager: opts.certificateManager,
parent: this
})

Expand Down
25 changes: 21 additions & 4 deletions src/commands/node/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
* limitations under the License.
*
*/


import {
type ChartManager,
type ConfigManager,
Expand All @@ -26,7 +24,8 @@
Task,
Templates,
Zippy,
type AccountManager
type AccountManager,
type CertificateManager
} from '../../core/index.ts'
import {
DEFAULT_NETWORK_NODE_NAME,
Expand Down Expand Up @@ -82,12 +81,13 @@
private readonly k8: K8
private readonly parent: NodeCommand
private readonly chartManager: ChartManager
private readonly certificateManager: CertificateManager

private readonly prepareValuesFiles: any

constructor (opts: { logger: SoloLogger; accountManager: AccountManager; configManager: ConfigManager,
k8: K8, platformInstaller: PlatformInstaller, keyManager: KeyManager, profileManager: ProfileManager,
chartManager: ChartManager, parent: NodeCommand}
chartManager: ChartManager, certificateManager: CertificateManager, parent: NodeCommand}
) {
if (!opts || !opts.accountManager) throw new IllegalArgumentError('An instance of core/AccountManager is required', opts.accountManager as any)
if (!opts || !opts.configManager) throw new Error('An instance of core/ConfigManager is required')
Expand All @@ -96,6 +96,8 @@
if (!opts || !opts.platformInstaller) throw new IllegalArgumentError('An instance of core/PlatformInstaller is required', opts.platformInstaller)
if (!opts || !opts.keyManager) throw new IllegalArgumentError('An instance of core/KeyManager is required', opts.keyManager)
if (!opts || !opts.profileManager) throw new IllegalArgumentError('An instance of ProfileManager is required', opts.profileManager)
if (!opts || !opts.certificateManager) throw new IllegalArgumentError('An instance of CertificateManager is required', opts.certificateManager)


this.accountManager = opts.accountManager
this.configManager = opts.configManager
Expand All @@ -106,6 +108,7 @@
this.profileManager = opts.profileManager
this.keyManager = opts.keyManager
this.chartManager = opts.chartManager
this.certificateManager = opts.certificateManager
this.prepareValuesFiles = opts.parent.prepareValuesFiles.bind(opts.parent)
}

Expand Down Expand Up @@ -414,6 +417,20 @@
}, (ctx: any) => !ctx.config.generateTlsKeys)
}

copyGrpcTlsCertificates () {
return new Task('Copy gRPC TLS Certificates',
(ctx: { config: NodeAddConfigClass }, parentTask: ListrTaskWrapper<any, any, any>) =>
this.certificateManager.buildCopyTlsCertificatesTasks(
parentTask,
ctx.config.grpcTlsCertificatePath,
ctx.config.grpcWebTlsCertificatePath,
ctx.config.grpcTlsKeyPath,
ctx.config.grpcWebTlsKeyPath

Check warning on line 428 in src/commands/node/tasks.ts

View check run for this annotation

Codecov / codecov/patch

src/commands/node/tasks.ts#L423-L428

Added lines #L423 - L428 were not covered by tests
),
(ctx: any) => !ctx.config.grpcTlsCertificatePath && !ctx.config.grpcWebTlsCertificatePath
)
}

_loadPermCertificate (certFullPath: string) {
const certPem = fs.readFileSync(certFullPath).toString()
const decodedDers = x509.PemConverter.decode(certPem)
Expand Down
40 changes: 40 additions & 0 deletions src/commands/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,40 @@
flags.outputDir.name)
}

//! ------------- Node Proxy Certificates ------------- !//

export async function promptGrpcTlsCertificatePath (task: ListrTaskWrapper<any, any, any>, input: any) {
return await promptText(task, input,
flags.grpcTlsCertificatePath.definition.defaultValue,
'Enter alias and path to TLS certificate for gRPC (ex. alias=path )',
null,
instamenta marked this conversation as resolved.
Show resolved Hide resolved
flags.grpcTlsCertificatePath.name)
}

Check warning on line 473 in src/commands/prompts.ts

View check run for this annotation

Codecov / codecov/patch

src/commands/prompts.ts#L468-L473

Added lines #L468 - L473 were not covered by tests

export async function promptGrpcWebTlsCertificatePath (task: ListrTaskWrapper<any, any, any>, input: any) {
return await promptText(task, input,
flags.grpcWebTlsCertificatePath.definition.defaultValue,
'Enter alias and path to TLS certificate for gGRPC web (ex. alias=path )',
null,
instamenta marked this conversation as resolved.
Show resolved Hide resolved
flags.grpcWebTlsCertificatePath.name)
}

Check warning on line 481 in src/commands/prompts.ts

View check run for this annotation

Codecov / codecov/patch

src/commands/prompts.ts#L476-L481

Added lines #L476 - L481 were not covered by tests

export async function promptGrpcTlsKeyPath (task: ListrTaskWrapper<any, any, any>, input: any) {
return await promptText(task, input,
flags.grpcTlsKeyPath.definition.defaultValue,
'Enter alias and path to TLS certificate key for gRPC (ex. alias=path )',
null,
instamenta marked this conversation as resolved.
Show resolved Hide resolved
flags.grpcTlsKeyPath.name)
}

Check warning on line 489 in src/commands/prompts.ts

View check run for this annotation

Codecov / codecov/patch

src/commands/prompts.ts#L484-L489

Added lines #L484 - L489 were not covered by tests

export async function promptGrpcWebTlsKeyPath (task: ListrTaskWrapper<any, any, any>, input: any) {
return await promptText(task, input,
flags.grpcWebTlsKeyPath.definition.defaultValue,
'Enter alias and path to TLS certificate key for gGRPC Web (ex. alias=path )',
null,
instamenta marked this conversation as resolved.
Show resolved Hide resolved
flags.grpcWebTlsKeyPath.name)
}

Check warning on line 497 in src/commands/prompts.ts

View check run for this annotation

Codecov / codecov/patch

src/commands/prompts.ts#L492-L497

Added lines #L492 - L497 were not covered by tests

export function getPromptMap (): Map<string, Function> {
return new Map()
.set(flags.accountId.name, promptAccountId)
Expand Down Expand Up @@ -506,6 +540,12 @@
.set(flags.hederaExplorerVersion, promptHederaExplorerVersion)
.set(flags.inputDir.name, promptInputDir)
.set(flags.outputDir.name, promptOutputDir)

//! Node Proxy Certificates
.set(flags.grpcTlsCertificatePath.name, promptGrpcTlsCertificatePath)
.set(flags.grpcWebTlsCertificatePath.name, promptGrpcWebTlsCertificatePath)
.set(flags.grpcTlsKeyPath.name, promptGrpcTlsKeyPath)
.set(flags.grpcWebTlsKeyPath.name, promptGrpcWebTlsKeyPath)
}

// build the prompt registry
Expand Down
Loading
Loading