UNPKG

armpit

Version:

Another resource manager programming interface toolkit.

159 lines 5.73 kB
import { isSubscriptionIdOrName, isSubscriptionId, isTenantId, } from "./azUtils.js"; import { ArmpitCredential } from "./armpitCredential.js"; export class AzAccountTools { #invokers; constructor(invokers) { this.#invokers = invokers; } async show() { try { return await this.#invokers.lax `account show`; } catch (invocationError) { const stderr = invocationError?.stderr; if (stderr && typeof stderr === "string" && (/az login|az account set/i).test(stderr)) { return null; } throw invocationError; } } async list(opt) { let flags; if (opt) { flags = []; if (opt.all) { flags.push("--all"); } if (opt.refresh) { flags.push("--refresh"); } } let results; if (flags && flags.length > 0) { results = await this.#invokers.lax `account list ${flags}`; } else { results = await this.#invokers.lax `account list`; } return results ?? []; } async set(subscriptionIdOrName) { await this.#invokers.lax `account set -s ${subscriptionIdOrName}`; } async setOrLogin(criteria, secondArg) { let subscription; let tenantId; let filterAccountsToSubscription; if (isSubscriptionIdOrName(criteria)) { // overload: subscription, tenantId? subscription = criteria; if (secondArg != null) { if (isTenantId(secondArg)) { tenantId = secondArg; } else { throw new Error("Given tenant ID is not valid"); } } filterAccountsToSubscription = (accounts) => { let results = accounts.filter(a => a.id === subscription); if (results.length === 0) { results = accounts.filter(a => a.name === subscription); } return results; }; } else if ("subscriptionId" in criteria) { // overload: {subscriptionId, tenantId?} if (isSubscriptionId(criteria.subscriptionId)) { subscription = criteria.subscriptionId; } else { throw new Error("Subscription ID is not valid"); } if ("tenantId" in criteria) { if (isTenantId(criteria.tenantId)) { tenantId = criteria.tenantId; } else { throw new Error("Given tenant ID is not valid"); } } filterAccountsToSubscription = (accounts) => accounts.filter(a => a.id === subscription); } else { throw new Error("Arguments not supported"); } const findAccount = (candidates) => { let matches = filterAccountsToSubscription(candidates.filter(a => a != null)); if (matches.length > 1 && tenantId) { matches = matches.filter(a => a.tenantId == tenantId); } if (matches.length === 0) { return null; } if (matches.length > 1) { throw new Error(`Multiple account matches found: ${matches.map(a => a.id)}`); } const match = matches[0]; if (tenantId && match.tenantId != tenantId) { throw new Error(`Account ${match.id} does not match expected tenant ${tenantId}`); } return match; }; let account = findAccount([await this.show()]); if (account) { return account; } // TODO: Consider refreshing and allowing a search of non-enabled accounts. // That could come at a cost to performance though. let knownAccounts = await this.list(); account = findAccount(knownAccounts); if (account) { await this.set(subscription); return account; } console.debug("No current accounts match. Starting interactive login."); knownAccounts = await this.login(tenantId) ?? []; account = findAccount(knownAccounts); if (!(account?.isDefault)) { await this.set(subscription); account = await this.show(); } return account; } async login(tenantId) { try { let loginAccounts; if (tenantId) { loginAccounts = await this.#invokers.strict `login --tenant ${tenantId}`; } else { loginAccounts = await this.#invokers.strict `login`; } return loginAccounts; } catch (invocationError) { const stderr = invocationError?.stderr; if (stderr && typeof stderr === "string" && (/User cancelled/i).test(stderr)) { return null; } throw invocationError; } } async listLocations(names) { let results; if (names != null && names.length > 0) { const queryFilter = `[? contains([${names.map((n) => `'${n}'`).join(",")}],name)]`; results = await this.#invokers.strict `account list-locations --query ${queryFilter}`; } else { results = await this.#invokers.strict `account list-locations`; } return results ?? []; } getCredential(options) { return new ArmpitCredential(this.#invokers, options); } } //# sourceMappingURL=azAccountTools.js.map