UNPKG

@hashgraph/solo

Version:

An opinionated CLI tool to deploy and manage private Hedera Networks.

112 lines (101 loc) 4.33 kB
// SPDX-License-Identifier: Apache-2.0 import {Flags as flags} from '../../commands/flags.js'; import {type ConfigManager} from '../config-manager.js'; import {type K8Factory} from '../../integration/kube/k8-factory.js'; import {type SoloLogger} from '../logging/solo-logger.js'; import {type Lock, type LockRenewalService} from './lock.js'; import {IntervalLock} from './interval-lock.js'; import {LockHolder} from './lock-holder.js'; import {inject, injectable} from 'tsyringe-neo'; import {patchInject} from '../dependency-injection/container-helper.js'; import {type NamespaceName} from '../../types/namespace/namespace-name.js'; import {InjectTokens} from '../dependency-injection/inject-tokens.js'; import {LockAcquisitionError} from './lock-acquisition-error.js'; import {type RemoteConfigRuntimeStateApi} from '../../business/runtime-state/api/remote-config-runtime-state-api.js'; /** * Manages the acquisition and renewal of locks. */ @injectable() export class LockManager { /** * Creates a new lock manager. * * @param _renewalService - the lock renewal service. * @param _logger - the logger. * @param k8Factory - the Kubernetes client. * @param configManager - the configuration manager. * @param remoteConfigRuntimeState */ public constructor( @inject(InjectTokens.LockRenewalService) private readonly _renewalService?: LockRenewalService, @inject(InjectTokens.SoloLogger) private readonly _logger?: SoloLogger, @inject(InjectTokens.K8Factory) private readonly k8Factory?: K8Factory, @inject(InjectTokens.ConfigManager) private readonly configManager?: ConfigManager, @inject(InjectTokens.RemoteConfigRuntimeState) private readonly remoteConfigRuntimeState?: RemoteConfigRuntimeStateApi, ) { this._renewalService = patchInject(_renewalService, InjectTokens.LockRenewalService, this.constructor.name); this._logger = patchInject(_logger, InjectTokens.SoloLogger, this.constructor.name); this.k8Factory = patchInject(k8Factory, InjectTokens.K8Factory, this.constructor.name); this.configManager = patchInject(configManager, InjectTokens.ConfigManager, this.constructor.name); this.remoteConfigRuntimeState = patchInject( remoteConfigRuntimeState, InjectTokens.RemoteConfigRuntimeState, this.constructor.name, ); } /** * Creates a new lease. This lease is not acquired until the `acquire` method is called. * * @returns a new lease instance. */ public async create(): Promise<Lock> { let namespace: NamespaceName; try { namespace = this.remoteConfigRuntimeState.getNamespace(); } catch { // If the namespace is not set in the remote config, we will use the current namespace. } if (!namespace) { namespace = await this.currentNamespace(); } return new IntervalLock(this.k8Factory, this._renewalService, LockHolder.default(), namespace); } /** * Retrieves the renewal service implementation. * * @returns the lease renewal service. */ public get renewalService(): LockRenewalService { return this._renewalService; } /** * Retrieves the logger instance. * * @returns the logger. */ public get logger(): SoloLogger { return this._logger; } /** * Retrieves the user or configuration supplied namespace to use for lease acquisition. * * @returns the namespace to use for lease acquisition or null if no namespace is specified. * @throws LockAcquisitionError if the namespace does not exist and cannot be created. */ private async currentNamespace(): Promise<NamespaceName> { const deploymentNamespace: NamespaceName = this.configManager.getFlag(flags.namespace); const clusterSetupNamespace: NamespaceName = this.configManager.getFlag(flags.clusterSetupNamespace); if (!deploymentNamespace && !clusterSetupNamespace) { return null; } const namespace: NamespaceName = deploymentNamespace || clusterSetupNamespace; if (!(await this.k8Factory.default().namespaces().has(namespace))) { await this.k8Factory.default().namespaces().create(namespace); if (!(await this.k8Factory.default().namespaces().has(namespace))) { throw new LockAcquisitionError(`failed to create the '${namespace}' namespace`); } } return namespace; } }