armpit
Version:
Another resource manager programming interface toolkit.
119 lines • 4.8 kB
JavaScript
import { CallableClassBase } from "./tsUtils.js";
import { ExistingGroupLocationConflictError, GroupNotEmptyError } from "./errors.js";
import { isNamedLocationDescriptor, extractSubscriptionId, } from "./azUtils.js";
import { execaAzCliInvokerFactory } from "./azCliUtils.js";
import { ArmpitCredential } from "./armpitCredential.js";
import { AzNsgTools } from "./azNsgTools.js";
export class AzGroupTools extends CallableClassBase {
#invokers;
#context;
constructor(invokers, context) {
super();
this.#invokers = invokers;
this.#context = context;
}
async fnImpl(nameOrDescriptor, secondArg) {
let descriptor;
if (nameOrDescriptor == null) {
throw new Error("Name or descriptor is required");
}
if (typeof nameOrDescriptor === "string") {
// overload: string, location: string
descriptor = {
name: nameOrDescriptor,
location: secondArg ?? this.#getRequiredDefaultLocation()
};
}
else if ("name" in nameOrDescriptor) {
// overload: {name, location}
if (typeof nameOrDescriptor.name !== "string") {
throw new Error("Group name is required");
}
if (typeof nameOrDescriptor.location !== "string") {
throw new Error("An explicit location is required");
}
descriptor = nameOrDescriptor;
}
else {
throw new Error("Unexpected arguments");
}
if (descriptor.location == null) {
// TODO: Can location be inherited if this.#azCli is AzLocationBound
throw new Error("Location is required");
}
let group = await this.show(descriptor.name);
if (group == null) {
group = await this.create(descriptor.name, descriptor.location);
}
else if (group.location !== descriptor.location) {
throw new ExistingGroupLocationConflictError(group, descriptor.location);
}
if (!isNamedLocationDescriptor(group)) {
throw new Error("Resource group is not correctly formed");
}
const invoker = execaAzCliInvokerFactory({
forceAzCommandPrefix: true,
laxParsing: false,
defaultLocation: group.location ?? descriptor.location,
defaultResourceGroup: group.name ?? descriptor.name,
});
const { name: groupName, ...descriptorWithoutName } = descriptor;
const subscriptionId = extractSubscriptionId(group.id);
let context = {
groupName,
location: descriptor.location,
subscriptionId,
};
const mainFn = invoker.strict;
const cliResult = Object.assign(mainFn, descriptorWithoutName);
Object.defineProperty(cliResult, "name", {
value: groupName,
configurable: true,
enumerable: true,
writable: false,
});
return Object.assign(cliResult, {
strict: invoker.strict,
lax: invoker.lax,
nsg: new AzNsgTools(invoker, context),
getCredential: (options) => new ArmpitCredential(invoker, { subscription: subscriptionId ?? undefined, ...options }),
});
}
async show(name) {
return await this.#invokers.lax `group show --name ${name}`;
}
;
async exists(name) {
return !!(await this.#invokers.lax `group exists --name ${name}`);
}
async create(name, location) {
return await this.#invokers.strict `group create --name ${name} -l ${location}`;
}
async delete(name) {
const group = await this.show(name);
if (group == null) {
return false;
}
if (typeof group.name !== "string") {
throw new Error(`Loaded resource group for ${name} is not valid`);
}
else if (group.name !== name) {
throw new Error(`Loaded resource group for ${name} has a conflicting name: ${group.name}`);
}
const jmesQuery = "[].{id: id, name: name, type: type}"; // passes as an expression for correct escaping
const resources = await this.#invokers.strict `resource list --resource-group ${name} --query ${jmesQuery}`;
if (resources.length !== 0) {
throw new GroupNotEmptyError(name, resources);
}
await this.#invokers.strict `group delete --yes --name ${name}`;
return true;
}
#getRequiredDefaultLocation() {
const location = this.#context.location;
if (location == null) {
throw new Error("No required default location has been set");
}
return location;
}
}
//# sourceMappingURL=azGroupTools.js.map