UNPKG

armpit

Version:

Another resource manager programming interface toolkit.

205 lines 9.17 kB
import { ContainerAppsAPIClient } from "@azure/arm-appcontainers"; import { mergeAbortSignals } from "./tsUtils.js"; import { applySourceToTargetObjectWithTemplate, applySourceToTargetObject, applyUnorderedValueArrayProp, wrapPropObjectApply, createKeyedArrayPropApplyFn, shallowCloneDefinedValues, shallowMergeDefinedValues, } from "./optionsUtils.js"; import { applyManagedServiceIdentity, extractSubscriptionFromId, locationNameOrCodeEquals, } from "./azureUtils.js"; import { handleGet } from "./azureSdkUtils.js"; function splitContainerAppOptionsAndDescriptor(optionsDescriptor) { const { groupName, location, subscriptionId, abortSignal, ...rest } = optionsDescriptor; return { options: { groupName, location, subscriptionId, abortSignal }, descriptor: rest, }; } function applyManagedEnvironment(env, descriptor, context) { let appliedChanges = false; if (applySourceToTargetObjectWithTemplate(env, descriptor, { identity: wrapPropObjectApply(applyManagedServiceIdentity), workloadProfiles: createKeyedArrayPropApplyFn("name", applySourceToTargetObject, true, true), }, context)) { appliedChanges = true; } return appliedChanges; } function applyConfiguration(config, descriptor, context) { let appliedChanges = false; if (applySourceToTargetObjectWithTemplate(config, descriptor, { identitySettings: createKeyedArrayPropApplyFn("identity", applySourceToTargetObject, true, true), registries: createKeyedArrayPropApplyFn("server", applySourceToTargetObject, true, true), secrets: createKeyedArrayPropApplyFn("name", applySourceToTargetObject, true, true), }, context)) { appliedChanges = true; } return appliedChanges; } function applyContainer(target, source, context) { return applySourceToTargetObjectWithTemplate(target, source, { args: applyUnorderedValueArrayProp, command: applyUnorderedValueArrayProp, env: createKeyedArrayPropApplyFn("name", applySourceToTargetObject, true, true), volumeMounts: createKeyedArrayPropApplyFn("volumeName", applySourceToTargetObject, true, true), }, context); } function applyContainerTemplate(template, descriptor, context) { return applySourceToTargetObjectWithTemplate(template, descriptor, { initContainers: createKeyedArrayPropApplyFn("name", applyContainer, true, true), containers: createKeyedArrayPropApplyFn("name", applyContainer, true, true), scale: { rules: createKeyedArrayPropApplyFn("name", applySourceToTargetObject, true, true), }, serviceBinds: createKeyedArrayPropApplyFn("name", applySourceToTargetObject, true, true), volumes: createKeyedArrayPropApplyFn("name", applySourceToTargetObject, true, true), }, context); } function applyContainerApp(app, descriptor, context) { let appliedChanges = false; if (applySourceToTargetObjectWithTemplate(app, descriptor, { identity: wrapPropObjectApply(applyManagedServiceIdentity), configuration: wrapPropObjectApply(applyConfiguration), template: wrapPropObjectApply(applyContainerTemplate), }, context)) { appliedChanges = true; } return appliedChanges; } export class ContainerAppTools { #invoker; #managementClientFactory; #options; constructor(dependencies, options) { this.#invoker = dependencies.invoker; this.#managementClientFactory = dependencies.managementClientFactory; this.#options = shallowCloneDefinedValues(options); } async envGet(name, options) { const { groupName, subscriptionId, abortSignal } = this.#buildMergedOptions(options); if (subscriptionId != null && groupName != null) { const client = this.getClient(subscriptionId); return await handleGet(client.managedEnvironments.get(groupName, name, { abortSignal })); } const args = ["--name", name]; if (groupName) { args.push("--resource-group", groupName); } return this.#getLaxInvokerFn(options) `containerapp env show ${args}`; } async envUpsert(name, optionsDescriptor) { const { options, descriptor } = optionsDescriptor ? splitContainerAppOptionsAndDescriptor(optionsDescriptor) : { descriptor: {} }; const opContext = this.#buildMergedOptions(options); if (opContext.groupName == null) { throw new Error("A group name is required to perform operations."); } let upsertRequired = false; let appEnv = await this.envGet(name, options); let subscriptionId = opContext.subscriptionId; const location = opContext.location; if (appEnv) { subscriptionId ??= extractSubscriptionFromId(appEnv.id); if (location != null && appEnv.location != null && !locationNameOrCodeEquals(location, appEnv.location)) { throw new Error(`Specified location ${location} conflicts with existing ${appEnv.location}.`); } } else { if (location == null) { throw new Error("A location is required"); } upsertRequired = true; appEnv = { name, location }; } if (applyManagedEnvironment(appEnv, descriptor)) { upsertRequired = true; } if (upsertRequired) { const client = this.getClient(subscriptionId); appEnv = await client.managedEnvironments.beginCreateOrUpdateAndWait(opContext.groupName, name, appEnv, { abortSignal: opContext.abortSignal, }); } return appEnv; } async appGet(name, options) { const { groupName, subscriptionId, abortSignal } = this.#buildMergedOptions(options); if (subscriptionId != null && groupName != null) { const client = this.getClient(subscriptionId); return await handleGet(client.containerApps.get(groupName, name, { abortSignal })); } const args = ["--name", name]; if (groupName) { args.push("--resource-group", groupName); } return this.#getLaxInvokerFn(options) `containerapp show ${args}`; } async appUpsert(name, optionsDescriptor) { const { options, descriptor } = splitContainerAppOptionsAndDescriptor(optionsDescriptor); const opContext = this.#buildMergedOptions(options); if (opContext.groupName == null) { throw new Error("A group name is required to perform operations."); } let upsertRequired = false; let app = await this.appGet(name, options); let subscriptionId = opContext.subscriptionId; const location = opContext.location; if (app) { subscriptionId ??= extractSubscriptionFromId(app.id); if (location != null && app.location != null && !locationNameOrCodeEquals(location, app.location)) { throw new Error(`Specified location ${location} conflicts with existing ${app.location}.`); } } else { if (location == null) { throw new Error("A location is required"); } upsertRequired = true; app = { name, location }; } if (applyContainerApp(app, descriptor)) { upsertRequired = true; } if (upsertRequired) { const client = this.getClient(subscriptionId); app = await client.containerApps.beginCreateOrUpdateAndWait(opContext.groupName, name, app, { abortSignal: opContext.abortSignal, }); } return app; } getClient(subscriptionId, options) { return this.#managementClientFactory.get(ContainerAppsAPIClient, (subscriptionId ?? this.#options.subscriptionId), options); } #buildMergedOptions(options) { if (options == null) { return this.#options; } const merged = shallowMergeDefinedValues(this.#options, options); const abortSignal = mergeAbortSignals(options.abortSignal, this.#options.abortSignal); if (abortSignal) { merged.abortSignal = abortSignal; } return merged; } #buildInvokerOptions(options) { const mergedOptions = this.#buildMergedOptions(options); const result = { forceAzCommandPrefix: true, simplifyContainerAppResults: true, // required for most containerapp responses }; if (mergedOptions.abortSignal != null) { result.abortSignal = mergedOptions.abortSignal; } if (mergedOptions.location != null) { result.defaultLocation = mergedOptions.location; } if (mergedOptions.groupName != null) { result.defaultResourceGroup = mergedOptions.groupName; } return result; } #getLaxInvokerFn(options) { return this.#invoker({ ...this.#buildInvokerOptions(options), allowBlanks: true, }); } } //# sourceMappingURL=containerAppTools.js.map