armpit
Version:
Another resource manager programming interface toolkit.
205 lines • 9.17 kB
JavaScript
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