@pagopa/dx-savemoney 0.6.2 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/telemetry/savemoney-command-telemetry.d.ts +20 -0
- package/dist/telemetry/savemoney-command-telemetry.d.ts.map +1 -0
- package/dist/telemetry/savemoney-command-telemetry.js +42 -0
- package/dist/telemetry/savemoney-command-telemetry.js.map +1 -0
- package/package.json +1 -1
- package/src/__tests__/savemoney-command-telemetry.test.ts +117 -0
- package/src/index.ts +7 -0
- package/src/telemetry/savemoney-command-telemetry.ts +83 -0
package/dist/index.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ import * as azureModule from "./azure/index.js";
|
|
|
19
19
|
export declare const azure: typeof azureModule;
|
|
20
20
|
export { type Finding, type FindingCategory, findingsFromAnalysisResult, type FindingSource, type Money, type ResourceReport, } from "./finding.js";
|
|
21
21
|
export { AZURE_SOURCE_VALUES } from "./schema.js";
|
|
22
|
+
export { buildSavemoneyInvocationTelemetryAttributes, buildSavemoneyOutcomeTelemetryAttributes, type SavemoneyAzqrReportSource, type SavemoneyCommandInput, type SavemoneySubscriptionsSource, } from "./telemetry/savemoney-command-telemetry.js";
|
|
22
23
|
export * from "./types.js";
|
|
23
24
|
import type { AzureConfig } from "./azure/types.js";
|
|
24
25
|
/**
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,sBAAsB,GACvB,MAAM,4BAA4B,CAAC;AAGpC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG7E,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC;AAChD,eAAO,MAAM,KAAK,oBAAc,CAAC;AAGjC,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,eAAe,EACpB,0BAA0B,EAC1B,KAAK,aAAa,EAClB,KAAK,KAAK,EACV,KAAK,cAAc,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,sBAAsB,GACvB,MAAM,4BAA4B,CAAC;AAGpC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG7E,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC;AAChD,eAAO,MAAM,KAAK,oBAAc,CAAC;AAGjC,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,eAAe,EACpB,0BAA0B,EAC1B,KAAK,aAAa,EAClB,KAAK,KAAK,EACV,KAAK,cAAc,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EACL,2CAA2C,EAC3C,wCAAwC,EACxC,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC1B,KAAK,4BAA4B,GAClC,MAAM,4CAA4C,CAAC;AAEpD,cAAc,YAAY,CAAC;AAE3B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAIpD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAE1E"}
|
package/dist/index.js
CHANGED
|
@@ -19,6 +19,7 @@ export const azure = azureModule;
|
|
|
19
19
|
// Phase 0: unified Finding model and analyzer plugin layer
|
|
20
20
|
export { findingsFromAnalysisResult, } from "./finding.js";
|
|
21
21
|
export { AZURE_SOURCE_VALUES } from "./schema.js";
|
|
22
|
+
export { buildSavemoneyInvocationTelemetryAttributes, buildSavemoneyOutcomeTelemetryAttributes, } from "./telemetry/savemoney-command-telemetry.js";
|
|
22
23
|
export * from "./types.js";
|
|
23
24
|
import { loadAzureConfig } from "./azure/config.js";
|
|
24
25
|
/**
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAIL,sBAAsB,GACvB,MAAM,4BAA4B,CAAC;AAMpC,sBAAsB;AACtB,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC;AAChD,MAAM,CAAC,MAAM,KAAK,GAAG,WAAW,CAAC;AAEjC,2DAA2D;AAC3D,OAAO,EAGL,0BAA0B,GAI3B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAIL,sBAAsB,GACvB,MAAM,4BAA4B,CAAC;AAMpC,sBAAsB;AACtB,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC;AAChD,MAAM,CAAC,MAAM,KAAK,GAAG,WAAW,CAAC;AAEjC,2DAA2D;AAC3D,OAAO,EAGL,0BAA0B,GAI3B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EACL,2CAA2C,EAC3C,wCAAwC,GAIzC,MAAM,4CAA4C,CAAC;AAEpD,cAAc,YAAY,CAAC;AAI3B,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,UAAmB;IAClD,OAAO,eAAe,CAAC,UAAU,CAAC,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SaveMoney command telemetry helpers.
|
|
3
|
+
*
|
|
4
|
+
* Keeps telemetry attribute derivation close to the SaveMoney domain so the
|
|
5
|
+
* same mapping can be reused by both the DX CLI adapter and a future standalone
|
|
6
|
+
* SaveMoney CLI entrypoint.
|
|
7
|
+
*/
|
|
8
|
+
import type { AzureConfig, AzureDetailedResourceReport } from "../azure/types.js";
|
|
9
|
+
export type SavemoneyAzqrReportSource = "cli" | "config" | "none";
|
|
10
|
+
export type SavemoneyCommandInput = {
|
|
11
|
+
azqrReportPathOption?: string;
|
|
12
|
+
configPathOption?: string;
|
|
13
|
+
format: string;
|
|
14
|
+
resolvedConfig: Pick<AzureConfig, "azqrReportPath" | "pricing" | "sources" | "subscriptionIds">;
|
|
15
|
+
subscriptionIdsEnv?: string;
|
|
16
|
+
};
|
|
17
|
+
export type SavemoneySubscriptionsSource = "config" | "env" | "prompt";
|
|
18
|
+
export declare function buildSavemoneyInvocationTelemetryAttributes(input: SavemoneyCommandInput): Record<string, boolean | number | string>;
|
|
19
|
+
export declare function buildSavemoneyOutcomeTelemetryAttributes(reports: readonly Pick<AzureDetailedResourceReport, "findings">[]): Record<string, number>;
|
|
20
|
+
//# sourceMappingURL=savemoney-command-telemetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"savemoney-command-telemetry.d.ts","sourceRoot":"","sources":["../../src/telemetry/savemoney-command-telemetry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,2BAA2B,EAC5B,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,yBAAyB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAElE,MAAM,MAAM,qBAAqB,GAAG;IAClC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,IAAI,CAClB,WAAW,EACX,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,iBAAiB,CAC7D,CAAC;IACF,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,CAAC;AAEvE,wBAAgB,2CAA2C,CACzD,KAAK,EAAE,qBAAqB,GAC3B,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC,CAqB3C;AAED,wBAAgB,wCAAwC,CACtD,OAAO,EAAE,SAAS,IAAI,CAAC,2BAA2B,EAAE,UAAU,CAAC,EAAE,GAChE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQxB"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SaveMoney command telemetry helpers.
|
|
3
|
+
*
|
|
4
|
+
* Keeps telemetry attribute derivation close to the SaveMoney domain so the
|
|
5
|
+
* same mapping can be reused by both the DX CLI adapter and a future standalone
|
|
6
|
+
* SaveMoney CLI entrypoint.
|
|
7
|
+
*/
|
|
8
|
+
export function buildSavemoneyInvocationTelemetryAttributes(input) {
|
|
9
|
+
const azqrReportSource = resolveAzqrReportSource(input.azqrReportPathOption, input.resolvedConfig.azqrReportPath);
|
|
10
|
+
const subscriptionsSource = resolveSubscriptionsSource(input.configPathOption, input.subscriptionIdsEnv);
|
|
11
|
+
return {
|
|
12
|
+
"savemoney.azqr_report_source": azqrReportSource,
|
|
13
|
+
"savemoney.format": input.format,
|
|
14
|
+
"savemoney.has_config": Boolean(input.configPathOption),
|
|
15
|
+
"savemoney.pricing_enabled": input.resolvedConfig.pricing?.enabled !== false,
|
|
16
|
+
"savemoney.sources": input.resolvedConfig.sources.join(","),
|
|
17
|
+
"savemoney.subscriptions_count": input.resolvedConfig.subscriptionIds.length,
|
|
18
|
+
"savemoney.subscriptions_source": subscriptionsSource,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export function buildSavemoneyOutcomeTelemetryAttributes(reports) {
|
|
22
|
+
return {
|
|
23
|
+
"savemoney.findings_count": reports.reduce((sum, report) => sum + (report.findings?.length ?? 0), 0),
|
|
24
|
+
"savemoney.resources_analyzed": reports.length,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function resolveAzqrReportSource(azqrReportPathOption, azqrReportPathResolved) {
|
|
28
|
+
if (azqrReportPathOption)
|
|
29
|
+
return "cli";
|
|
30
|
+
if (azqrReportPathResolved)
|
|
31
|
+
return "config";
|
|
32
|
+
return "none";
|
|
33
|
+
}
|
|
34
|
+
function resolveSubscriptionsSource(configPathOption, subscriptionIdsEnv) {
|
|
35
|
+
// Mirrors loadAzureConfig() priority: config file > ARM_SUBSCRIPTION_ID > prompt.
|
|
36
|
+
if (configPathOption)
|
|
37
|
+
return "config";
|
|
38
|
+
if (subscriptionIdsEnv)
|
|
39
|
+
return "env";
|
|
40
|
+
return "prompt";
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=savemoney-command-telemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"savemoney-command-telemetry.js","sourceRoot":"","sources":["../../src/telemetry/savemoney-command-telemetry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsBH,MAAM,UAAU,2CAA2C,CACzD,KAA4B;IAE5B,MAAM,gBAAgB,GAAG,uBAAuB,CAC9C,KAAK,CAAC,oBAAoB,EAC1B,KAAK,CAAC,cAAc,CAAC,cAAc,CACpC,CAAC;IACF,MAAM,mBAAmB,GAAG,0BAA0B,CACpD,KAAK,CAAC,gBAAgB,EACtB,KAAK,CAAC,kBAAkB,CACzB,CAAC;IAEF,OAAO;QACL,8BAA8B,EAAE,gBAAgB;QAChD,kBAAkB,EAAE,KAAK,CAAC,MAAM;QAChC,sBAAsB,EAAE,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC;QACvD,2BAA2B,EACzB,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,KAAK,KAAK;QACjD,mBAAmB,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;QAC3D,+BAA+B,EAC7B,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC,MAAM;QAC7C,gCAAgC,EAAE,mBAAmB;KACtD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wCAAwC,CACtD,OAAiE;IAEjE,OAAO;QACL,0BAA0B,EAAE,OAAO,CAAC,MAAM,CACxC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC,EACrD,CAAC,CACF;QACD,8BAA8B,EAAE,OAAO,CAAC,MAAM;KAC/C,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAC9B,oBAAwC,EACxC,sBAA0C;IAE1C,IAAI,oBAAoB;QAAE,OAAO,KAAK,CAAC;IACvC,IAAI,sBAAsB;QAAE,OAAO,QAAQ,CAAC;IAC5C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,0BAA0B,CACjC,gBAAoC,EACpC,kBAAsC;IAEtC,kFAAkF;IAClF,IAAI,gBAAgB;QAAE,OAAO,QAAQ,CAAC;IACtC,IAAI,kBAAkB;QAAE,OAAO,KAAK,CAAC;IACrC,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import type { Finding } from "../finding.js";
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
buildSavemoneyInvocationTelemetryAttributes,
|
|
7
|
+
buildSavemoneyOutcomeTelemetryAttributes,
|
|
8
|
+
} from "../telemetry/savemoney-command-telemetry.js";
|
|
9
|
+
|
|
10
|
+
const BASE_FINDING: Finding = {
|
|
11
|
+
category: "cost",
|
|
12
|
+
code: "vm.low-cpu",
|
|
13
|
+
reason: "Low CPU usage.",
|
|
14
|
+
resourceId:
|
|
15
|
+
"/subscriptions/sub/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/vm",
|
|
16
|
+
severity: "low",
|
|
17
|
+
source: "custom",
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
describe("buildSavemoneyInvocationTelemetryAttributes", () => {
|
|
21
|
+
it("sets azqr_report_source to cli when --azqr-report is provided", () => {
|
|
22
|
+
const attributes = buildSavemoneyInvocationTelemetryAttributes({
|
|
23
|
+
azqrReportPathOption: "./azqr.json",
|
|
24
|
+
format: "table",
|
|
25
|
+
resolvedConfig: {
|
|
26
|
+
azqrReportPath: "./from-config.json",
|
|
27
|
+
pricing: { enabled: true },
|
|
28
|
+
sources: ["advisor", "custom"],
|
|
29
|
+
subscriptionIds: ["sub-a"],
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
expect(attributes["savemoney.azqr_report_source"]).toBe("cli");
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("sets azqr_report_source to config when only config path is present", () => {
|
|
37
|
+
const attributes = buildSavemoneyInvocationTelemetryAttributes({
|
|
38
|
+
format: "table",
|
|
39
|
+
resolvedConfig: {
|
|
40
|
+
azqrReportPath: "./from-config.json",
|
|
41
|
+
pricing: { enabled: true },
|
|
42
|
+
sources: ["advisor", "custom"],
|
|
43
|
+
subscriptionIds: ["sub-a"],
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
expect(attributes["savemoney.azqr_report_source"]).toBe("config");
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("sets azqr_report_source to none when azqr is absent", () => {
|
|
51
|
+
const attributes = buildSavemoneyInvocationTelemetryAttributes({
|
|
52
|
+
format: "table",
|
|
53
|
+
resolvedConfig: {
|
|
54
|
+
pricing: { enabled: true },
|
|
55
|
+
sources: ["advisor", "custom"],
|
|
56
|
+
subscriptionIds: ["sub-a"],
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
expect(attributes["savemoney.azqr_report_source"]).toBe("none");
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("derives subscriptions_source as config, env, or prompt", () => {
|
|
64
|
+
const fromConfig = buildSavemoneyInvocationTelemetryAttributes({
|
|
65
|
+
configPathOption: "./config.yaml",
|
|
66
|
+
format: "table",
|
|
67
|
+
resolvedConfig: {
|
|
68
|
+
pricing: { enabled: true },
|
|
69
|
+
sources: ["advisor", "custom"],
|
|
70
|
+
subscriptionIds: ["sub-a"],
|
|
71
|
+
},
|
|
72
|
+
subscriptionIdsEnv: "sub-env",
|
|
73
|
+
});
|
|
74
|
+
const fromEnv = buildSavemoneyInvocationTelemetryAttributes({
|
|
75
|
+
format: "table",
|
|
76
|
+
resolvedConfig: {
|
|
77
|
+
pricing: { enabled: true },
|
|
78
|
+
sources: ["advisor", "custom"],
|
|
79
|
+
subscriptionIds: ["sub-a"],
|
|
80
|
+
},
|
|
81
|
+
subscriptionIdsEnv: "sub-env",
|
|
82
|
+
});
|
|
83
|
+
const fromPrompt = buildSavemoneyInvocationTelemetryAttributes({
|
|
84
|
+
format: "table",
|
|
85
|
+
resolvedConfig: {
|
|
86
|
+
pricing: { enabled: true },
|
|
87
|
+
sources: ["advisor", "custom"],
|
|
88
|
+
subscriptionIds: ["sub-a"],
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
expect(fromConfig["savemoney.subscriptions_source"]).toBe("config");
|
|
93
|
+
expect(fromEnv["savemoney.subscriptions_source"]).toBe("env");
|
|
94
|
+
expect(fromPrompt["savemoney.subscriptions_source"]).toBe("prompt");
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
describe("buildSavemoneyOutcomeTelemetryAttributes", () => {
|
|
99
|
+
it("counts findings and analyzed resources", () => {
|
|
100
|
+
const attributes = buildSavemoneyOutcomeTelemetryAttributes([
|
|
101
|
+
{
|
|
102
|
+
findings: [BASE_FINDING, { ...BASE_FINDING, code: "disk.unattached" }],
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
findings: [
|
|
106
|
+
{ ...BASE_FINDING, code: "advisor.right-size", source: "advisor" },
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
{},
|
|
110
|
+
]);
|
|
111
|
+
|
|
112
|
+
expect(attributes).toEqual({
|
|
113
|
+
"savemoney.findings_count": 3,
|
|
114
|
+
"savemoney.resources_analyzed": 3,
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -38,6 +38,13 @@ export {
|
|
|
38
38
|
type ResourceReport,
|
|
39
39
|
} from "./finding.js";
|
|
40
40
|
export { AZURE_SOURCE_VALUES } from "./schema.js";
|
|
41
|
+
export {
|
|
42
|
+
buildSavemoneyInvocationTelemetryAttributes,
|
|
43
|
+
buildSavemoneyOutcomeTelemetryAttributes,
|
|
44
|
+
type SavemoneyAzqrReportSource,
|
|
45
|
+
type SavemoneyCommandInput,
|
|
46
|
+
type SavemoneySubscriptionsSource,
|
|
47
|
+
} from "./telemetry/savemoney-command-telemetry.js";
|
|
41
48
|
|
|
42
49
|
export * from "./types.js";
|
|
43
50
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SaveMoney command telemetry helpers.
|
|
3
|
+
*
|
|
4
|
+
* Keeps telemetry attribute derivation close to the SaveMoney domain so the
|
|
5
|
+
* same mapping can be reused by both the DX CLI adapter and a future standalone
|
|
6
|
+
* SaveMoney CLI entrypoint.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type {
|
|
10
|
+
AzureConfig,
|
|
11
|
+
AzureDetailedResourceReport,
|
|
12
|
+
} from "../azure/types.js";
|
|
13
|
+
|
|
14
|
+
export type SavemoneyAzqrReportSource = "cli" | "config" | "none";
|
|
15
|
+
|
|
16
|
+
export type SavemoneyCommandInput = {
|
|
17
|
+
azqrReportPathOption?: string;
|
|
18
|
+
configPathOption?: string;
|
|
19
|
+
format: string;
|
|
20
|
+
resolvedConfig: Pick<
|
|
21
|
+
AzureConfig,
|
|
22
|
+
"azqrReportPath" | "pricing" | "sources" | "subscriptionIds"
|
|
23
|
+
>;
|
|
24
|
+
subscriptionIdsEnv?: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type SavemoneySubscriptionsSource = "config" | "env" | "prompt";
|
|
28
|
+
|
|
29
|
+
export function buildSavemoneyInvocationTelemetryAttributes(
|
|
30
|
+
input: SavemoneyCommandInput,
|
|
31
|
+
): Record<string, boolean | number | string> {
|
|
32
|
+
const azqrReportSource = resolveAzqrReportSource(
|
|
33
|
+
input.azqrReportPathOption,
|
|
34
|
+
input.resolvedConfig.azqrReportPath,
|
|
35
|
+
);
|
|
36
|
+
const subscriptionsSource = resolveSubscriptionsSource(
|
|
37
|
+
input.configPathOption,
|
|
38
|
+
input.subscriptionIdsEnv,
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
"savemoney.azqr_report_source": azqrReportSource,
|
|
43
|
+
"savemoney.format": input.format,
|
|
44
|
+
"savemoney.has_config": Boolean(input.configPathOption),
|
|
45
|
+
"savemoney.pricing_enabled":
|
|
46
|
+
input.resolvedConfig.pricing?.enabled !== false,
|
|
47
|
+
"savemoney.sources": input.resolvedConfig.sources.join(","),
|
|
48
|
+
"savemoney.subscriptions_count":
|
|
49
|
+
input.resolvedConfig.subscriptionIds.length,
|
|
50
|
+
"savemoney.subscriptions_source": subscriptionsSource,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function buildSavemoneyOutcomeTelemetryAttributes(
|
|
55
|
+
reports: readonly Pick<AzureDetailedResourceReport, "findings">[],
|
|
56
|
+
): Record<string, number> {
|
|
57
|
+
return {
|
|
58
|
+
"savemoney.findings_count": reports.reduce(
|
|
59
|
+
(sum, report) => sum + (report.findings?.length ?? 0),
|
|
60
|
+
0,
|
|
61
|
+
),
|
|
62
|
+
"savemoney.resources_analyzed": reports.length,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function resolveAzqrReportSource(
|
|
67
|
+
azqrReportPathOption: string | undefined,
|
|
68
|
+
azqrReportPathResolved: string | undefined,
|
|
69
|
+
): SavemoneyAzqrReportSource {
|
|
70
|
+
if (azqrReportPathOption) return "cli";
|
|
71
|
+
if (azqrReportPathResolved) return "config";
|
|
72
|
+
return "none";
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function resolveSubscriptionsSource(
|
|
76
|
+
configPathOption: string | undefined,
|
|
77
|
+
subscriptionIdsEnv: string | undefined,
|
|
78
|
+
): SavemoneySubscriptionsSource {
|
|
79
|
+
// Mirrors loadAzureConfig() priority: config file > ARM_SUBSCRIPTION_ID > prompt.
|
|
80
|
+
if (configPathOption) return "config";
|
|
81
|
+
if (subscriptionIdsEnv) return "env";
|
|
82
|
+
return "prompt";
|
|
83
|
+
}
|