import { Rule } from "../rule"; import { Context } from "../context"; import { Options } from "../options"; import { Client } from "../client"; import { GenericResource } from "azure-arm-resource/lib/resource/models"; export default class ResourceCount extends Rule { private readonly pattern: string; private readonly type: string | null; private readonly min: number | null; private readonly max: number | null; constructor(context: Context, options: Options) { super(context, options); this.pattern = options.string("pattern"); this.type = options.string("type", null); this.min = options.number("min", null); this.max = options.number("max", null); if (this.min === -1) { this.min = null; } if (this.max === -1) { this.max = null; } if (this.min == null && this.max == null) { throw new Error(`Invalid options, neither min nor max given!`); } else if (this.min != null && this.max != null && this.min > this.max) { throw new Error(`Invalid options: min=${this.min} max=${this.max}`); } } async run(client: Client): Promise { const pattern = new RegExp(`^${this.pattern}$`); const resources = await client.listResources(); const filtered = resources.filter( resource => resource.name && resource.name.match(pattern) && (this.type == null || resource.type === this.type) ); const count = filtered.length; const resourceNames = filtered.map(resource => resource.name).join(", ") || "none"; if (this.min != null && count < this.min) { const tenant = await client.getTenant(); this.report(tenant, "resourceCountLessThanMin", { pattern: pattern.toString(), type: this.type || "any", count, min: this.min, resources: resourceNames }); } else if (this.max != null && count > this.max) { const tenant = await client.getTenant(); this.report(tenant, "resourceCountMoreThanMax", { pattern: pattern.toString(), type: this.type || "any", count, max: this.max, resources: resourceNames }); } } }