UNPKG

@studion/infra-code-blocks

Version:
154 lines (153 loc) 6.27 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Grafana = void 0; const pulumi = require("@pulumi/pulumi"); const grafana = require("@pulumiverse/grafana"); const merge_with_defaults_1 = require("../../shared/merge-with-defaults"); const plugin_ready_1 = require("./plugin-ready"); const REQUIRED_ACCESS_POLICY_SCOPES = [ 'accesspolicies:read', 'accesspolicies:write', 'accesspolicies:delete', 'datasources:read', 'datasources:write', 'datasources:delete', 'stacks:read', 'stack-dashboards:read', 'stack-dashboards:write', 'stack-dashboards:delete', 'stack-plugins:read', 'stack-plugins:write', 'stack-plugins:delete', ]; const defaults = { serviceAccountTokenRotation: { secondsToLive: 7_776_000, // 90 days earlyRotationWindowSeconds: 604_800, // 7 days }, accessPolicyTokenRotation: { expireAfter: '2160h', // 90 days earlyRotationWindow: '168h', // 7 days }, }; /** * This component requires a grafana cloud access policy token to be created and set * as `GRAFANA_CLOUD_ACCESS_POLICY_TOKEN` with the following scopes: * accesspolicies:read, accesspolicies:write, accesspolicies:delete, stacks:read, stack-service-accounts:write */ class Grafana extends pulumi.ComponentResource { name; stack; accessPolicy; accessPolicyToken; serviceAccount; serviceAccountToken; provider; plugins; connections; folder; dashboards; constructor(name, args, opts = {}) { super('studion:grafana:Grafana', name, {}, opts); const argsWithDefaults = (0, merge_with_defaults_1.mergeWithDefaults)(defaults, args); this.name = name; this.stack = grafana.cloud.getStackOutput({ slug: argsWithDefaults.stackSlug, }); this.accessPolicy = this.createAccessPolicy(argsWithDefaults.scopes); this.accessPolicyToken = this.createAccessPolicyToken(argsWithDefaults.accessPolicyTokenRotation); this.serviceAccount = this.createServiceAccount(); this.serviceAccountToken = this.createServiceAccountToken(argsWithDefaults.serviceAccountTokenRotation); this.provider = this.createProvider(); const pluginsReadiness = []; if (argsWithDefaults.plugins?.length) { this.plugins = []; let previous; for (const pluginArgs of argsWithDefaults.plugins) { const { plugin, readiness } = this.createPlugin(pluginArgs, { dependsOn: previous ? [previous] : [], }); this.plugins.push(plugin); pluginsReadiness.push(readiness); previous = this.plugins.at(-1); } } this.connections = argsWithDefaults.connectionBuilders.map(build => { return build({ stack: this.stack }, { parent: this, provider: this.provider, dependsOn: pluginsReadiness }); }); this.folder = this.createFolder(argsWithDefaults.folderName, this.provider); this.dashboards = argsWithDefaults.dashboardBuilders.map(build => { return build(this.folder, { parent: this.folder, provider: this.provider, }); }); this.registerOutputs(); } static getStackSlug(grafanaUrl) { return new URL(grafanaUrl).hostname.split('.')[0]; } createAccessPolicy(scopes) { return new grafana.cloud.AccessPolicy(`${this.name}-access-policy`, { region: this.stack.regionSlug, name: `${this.name}-ap-icb-observability-rwd-${pulumi.getStack()}`, scopes: [ ...new Set([...REQUIRED_ACCESS_POLICY_SCOPES, ...(scopes ?? [])]), ], realms: [{ type: 'stack', identifier: this.stack.id }], }, { parent: this }); } createAccessPolicyToken(rotation) { return new grafana.cloud.AccessPolicyRotatingToken(`${this.name}-access-policy-token`, { region: this.stack.regionSlug, accessPolicyId: this.accessPolicy.policyId, namePrefix: `${this.name}-apt-icb-${pulumi.getStack()}`, expireAfter: rotation.expireAfter, earlyRotationWindow: rotation.earlyRotationWindow, deleteOnDestroy: true, }, { parent: this }); } createServiceAccount() { return new grafana.cloud.StackServiceAccount(`${this.name}-service-account`, { stackSlug: this.stack.slug, name: `${this.name}-sa-icb-provisioner-${pulumi.getStack()}`, role: 'Admin', }, { parent: this }); } createServiceAccountToken(rotation) { return new grafana.cloud.StackServiceAccountRotatingToken(`${this.name}-service-account-token`, { stackSlug: this.stack.slug, serviceAccountId: this.serviceAccount.id, namePrefix: `${this.name}-sat-icb-${pulumi.getStack()}`, secondsToLive: rotation.secondsToLive, earlyRotationWindowSeconds: rotation.earlyRotationWindowSeconds, deleteOnDestroy: true, }, { parent: this }); } createFolder(folderName, provider) { return new grafana.oss.Folder(`${this.name}-folder`, { title: folderName ?? `${this.name}-ICB-GENERATED` }, { parent: this, provider }); } createPlugin({ name, slug, version = 'latest' }, opts) { const plugin = new grafana.cloud.PluginInstallation(`${this.name}-${name}-plugin`, { stackSlug: this.stack.slug, slug, version, }, { ...opts, parent: this, provider: this.provider }); const readiness = new plugin_ready_1.PluginReady(`${this.name}-${name}-plugin-ready`, { grafanaToken: this.serviceAccountToken.key, grafanaUrl: this.stack.url, slug, }, { dependsOn: [plugin], }); return { plugin, readiness }; } createProvider() { return new grafana.Provider(`${this.name}-provider`, { cloudAccessPolicyToken: this.accessPolicyToken.token, url: this.stack.url, auth: this.serviceAccountToken.key, }, { parent: this }); } } exports.Grafana = Grafana;