@pagopa/dx-savemoney 0.1.2 → 0.1.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/README.md CHANGED
@@ -43,6 +43,7 @@ flowchart LR
43
43
  PE[Private Endpoints]
44
44
  SA[Storage Accounts]
45
45
  CA[Container Apps]
46
+ SS[Static Web Apps]
46
47
  end
47
48
  CLI --> Config
48
49
  Config --> Azure
@@ -95,6 +96,7 @@ The tool analyzes the following Azure resource types with specific detection met
95
96
  | **Network Interfaces** | API Details | 🟡 Medium | Not attached to VM or Private Endpoint, No public IP assigned |
96
97
  | **Private Endpoints** | API Details | 🟡 Medium | No private link connections, Rejected/disconnected connections, No network interfaces |
97
98
  | **Storage Accounts** | Metrics | 🟡 Medium | Very low transaction count (<10 per days in timespan) |
99
+ | **Static Web Apps** | Metrics | 🟢 Low | No traffic data available, Very low site hits (<100 requests in 30 days), Very low data transfer (<1MB in 30 days) |
98
100
 
99
101
  #### Generic Checks
100
102
 
@@ -1 +1 @@
1
- {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../src/azure/analyzer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAIrD,OAAO,KAAK,EAAE,WAAW,EAA+B,MAAM,YAAY,CAAC;AAE3E,OAAO,EAAE,KAAK,cAAc,EAAgB,MAAM,aAAa,CAAC;AAahE;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,eAAe,GAAG,MAAM,GAAG,OAAO,iBAmE3C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,YAAY,CAAC,eAAe,EACtC,aAAa,EAAE,aAAa,EAC5B,aAAa,EAAE,uBAAuB,EACtC,aAAa,EAAE,uBAAuB,EACtC,aAAa,EAAE,uBAAuB,EACtC,mBAAmB,EAAE,sBAAsB,EAC3C,iBAAiB,EAAE,MAAM,EACzB,YAAY,EAAE,MAAM,EACpB,OAAO,UAAQ,GACd,OAAO,CAAC,cAAc,CAAC,CAuGzB"}
1
+ {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../src/azure/analyzer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAIrD,OAAO,KAAK,EAAE,WAAW,EAA+B,MAAM,YAAY,CAAC;AAE3E,OAAO,EAAE,KAAK,cAAc,EAAgB,MAAM,aAAa,CAAC;AAchE;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,eAAe,GAAG,MAAM,GAAG,OAAO,iBAmE3C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,YAAY,CAAC,eAAe,EACtC,aAAa,EAAE,aAAa,EAC5B,aAAa,EAAE,uBAAuB,EACtC,aAAa,EAAE,uBAAuB,EACtC,aAAa,EAAE,uBAAuB,EACtC,mBAAmB,EAAE,sBAAsB,EAC3C,iBAAiB,EAAE,MAAM,EACzB,YAAY,EAAE,MAAM,EACpB,OAAO,UAAQ,GACd,OAAO,CAAC,cAAc,CAAC,CAiHzB"}
@@ -11,7 +11,7 @@ import { DefaultAzureCredential } from "@azure/identity";
11
11
  import { getLogger } from "@logtape/logtape";
12
12
  import { mergeResults } from "../types.js";
13
13
  import { generateReport } from "./report.js";
14
- import { analyzeAppServicePlan, analyzeContainerApp, analyzeDisk, analyzeNic, analyzePrivateEndpoint, analyzePublicIp, analyzeStorageAccount, analyzeVM, } from "./resources/index.js";
14
+ import { analyzeAppServicePlan, analyzeContainerApp, analyzeDisk, analyzeNic, analyzePrivateEndpoint, analyzePublicIp, analyzeStaticSite, analyzeStorageAccount, analyzeVM, } from "./resources/index.js";
15
15
  /**
16
16
  * Analyzes resources in multiple Azure subscriptions and generates a report.
17
17
  *
@@ -122,6 +122,11 @@ export async function analyzeResource(resource, monitorClient, computeClient, ne
122
122
  result = mergeResults(result, aspResult);
123
123
  break;
124
124
  }
125
+ case "microsoft.web/staticsites": {
126
+ const staticSiteResult = await analyzeStaticSite(resource, monitorClient, timespanDays, verbose);
127
+ result = mergeResults(result, staticSiteResult);
128
+ break;
129
+ }
125
130
  default:
126
131
  result.reason += "No specific analysis for this resource type. ";
127
132
  break;
@@ -1 +1 @@
1
- {"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../src/azure/analyzer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../src/azure/analyzer.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,7 @@ export { analyzeDisk } from "./disk.js";
7
7
  export { analyzeNic } from "./nic.js";
8
8
  export { analyzePrivateEndpoint } from "./private-endpoint.js";
9
9
  export { analyzePublicIp } from "./public-ip.js";
10
+ export { analyzeStaticSite } from "./static-web-app.js";
10
11
  export { analyzeStorageAccount } from "./storage.js";
11
12
  export { analyzeVM } from "./vm.js";
12
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/azure/resources/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/azure/resources/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC"}
@@ -7,6 +7,7 @@ export { analyzeDisk } from "./disk.js";
7
7
  export { analyzeNic } from "./nic.js";
8
8
  export { analyzePrivateEndpoint } from "./private-endpoint.js";
9
9
  export { analyzePublicIp } from "./public-ip.js";
10
+ export { analyzeStaticSite } from "./static-web-app.js";
10
11
  export { analyzeStorageAccount } from "./storage.js";
11
12
  export { analyzeVM } from "./vm.js";
12
13
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/azure/resources/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/azure/resources/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Azure Static Web App analysis
3
+ */
4
+ import type { MonitorClient } from "@azure/arm-monitor";
5
+ import * as armResources from "@azure/arm-resources";
6
+ import type { AnalysisResult } from "../../types.js";
7
+ /**
8
+ * Analyzes an Azure Static Web App for potential cost optimization.
9
+ *
10
+ * @param resource - The Azure resource object
11
+ * @param monitorClient - Azure Monitor client for metrics
12
+ * @param timespanDays - Number of days to analyze metrics
13
+ * @param verbose - Enable verbose logging
14
+ * @returns Analysis result with cost risk and reason
15
+ */
16
+ export declare function analyzeStaticSite(resource: armResources.GenericResource, monitorClient: MonitorClient, timespanDays: number, verbose?: boolean): Promise<AnalysisResult>;
17
+ //# sourceMappingURL=static-web-app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static-web-app.d.ts","sourceRoot":"","sources":["../../../src/azure/resources/static-web-app.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAGrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AASrD;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,YAAY,CAAC,eAAe,EACtC,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,MAAM,EACpB,OAAO,UAAQ,GACd,OAAO,CAAC,cAAc,CAAC,CA2EzB"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Azure Static Web App analysis
3
+ */
4
+ import { getLogger } from "@logtape/logtape";
5
+ import { getMetric, verboseLog, verboseLogAnalysisResult, verboseLogResourceStart, } from "../utils.js";
6
+ /**
7
+ * Analyzes an Azure Static Web App for potential cost optimization.
8
+ *
9
+ * @param resource - The Azure resource object
10
+ * @param monitorClient - Azure Monitor client for metrics
11
+ * @param timespanDays - Number of days to analyze metrics
12
+ * @param verbose - Enable verbose logging
13
+ * @returns Analysis result with cost risk and reason
14
+ */
15
+ export async function analyzeStaticSite(resource, monitorClient, timespanDays, verbose = false) {
16
+ verboseLogResourceStart(verbose, resource.name || "unknown", "Static Web App (Microsoft.Web/staticSites)");
17
+ verboseLog(verbose, "Resource details:", resource);
18
+ const costRisk = "low";
19
+ let reason = "";
20
+ if (!resource.id) {
21
+ return {
22
+ costRisk,
23
+ reason: "Resource ID is missing.",
24
+ suspectedUnused: false,
25
+ };
26
+ }
27
+ try {
28
+ verboseLog(verbose, "Checking metrics...");
29
+ // Check for site hits (requests to the static site)
30
+ // Note: Static Web Apps metrics use Total aggregation, not Average
31
+ // Ref. https://learn.microsoft.com/en-us/azure/azure-monitor/reference/supported-metrics/microsoft-web-staticsites-metrics
32
+ const siteHits = await getMetric(monitorClient, resource.id, "SiteHits", "Total", timespanDays);
33
+ const bytesSent = await getMetric(monitorClient, resource.id, "BytesSent", "Total", timespanDays);
34
+ verboseLog(verbose, `Site Hits: ${siteHits !== null ? `${siteHits.toFixed(0)} total requests` : "N/A"}`);
35
+ verboseLog(verbose, `Bytes Sent: ${bytesSent !== null ? `${(bytesSent / 1024 / 1024).toFixed(2)} MB total` : "N/A"}`);
36
+ // If both metrics are null, it means no data points exist (no traffic at all)
37
+ if (siteHits === null && bytesSent === null) {
38
+ reason += `No traffic data available in ${timespanDays} days. `;
39
+ }
40
+ else {
41
+ if (siteHits !== null && siteHits < 100) {
42
+ // Less than 100 requests total in the timespan (< ~3.3 requests/day)
43
+ reason += `Very low site traffic (${siteHits.toFixed(0)} requests in ${timespanDays} days). `;
44
+ }
45
+ if (bytesSent !== null && bytesSent < 1048576) {
46
+ // Less than 1MB total in the timespan (< ~34KB/day)
47
+ reason += `Very low data transfer (${(bytesSent / 1024 / 1024).toFixed(2)} MB in ${timespanDays} days). `;
48
+ }
49
+ }
50
+ }
51
+ catch (error) {
52
+ const logger = getLogger(["savemoney", "azure"]);
53
+ logger.warn(`Failed to get metrics for Static Web App ${resource.name}: ${error instanceof Error ? error.message : error}`);
54
+ }
55
+ const suspectedUnused = reason.length > 0;
56
+ const result = { costRisk, reason: reason.trim(), suspectedUnused };
57
+ verboseLogAnalysisResult(verbose, result);
58
+ return result;
59
+ }
60
+ //# sourceMappingURL=static-web-app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static-web-app.js","sourceRoot":"","sources":["../../../src/azure/resources/static-web-app.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pagopa/dx-savemoney",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "description": "Azure resource analyzer for finding unused or cost-inefficient resources.",
6
6
  "repository": {
@@ -22,6 +22,7 @@ import {
22
22
  analyzeNic,
23
23
  analyzePrivateEndpoint,
24
24
  analyzePublicIp,
25
+ analyzeStaticSite,
25
26
  analyzeStorageAccount,
26
27
  analyzeVM,
27
28
  } from "./resources/index.js";
@@ -216,6 +217,16 @@ export async function analyzeResource(
216
217
  result = mergeResults(result, aspResult);
217
218
  break;
218
219
  }
220
+ case "microsoft.web/staticsites": {
221
+ const staticSiteResult = await analyzeStaticSite(
222
+ resource,
223
+ monitorClient,
224
+ timespanDays,
225
+ verbose,
226
+ );
227
+ result = mergeResults(result, staticSiteResult);
228
+ break;
229
+ }
219
230
  default:
220
231
  result.reason += "No specific analysis for this resource type. ";
221
232
  break;
@@ -8,5 +8,6 @@ export { analyzeDisk } from "./disk.js";
8
8
  export { analyzeNic } from "./nic.js";
9
9
  export { analyzePrivateEndpoint } from "./private-endpoint.js";
10
10
  export { analyzePublicIp } from "./public-ip.js";
11
+ export { analyzeStaticSite } from "./static-web-app.js";
11
12
  export { analyzeStorageAccount } from "./storage.js";
12
13
  export { analyzeVM } from "./vm.js";
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Azure Static Web App analysis
3
+ */
4
+
5
+ import type { MonitorClient } from "@azure/arm-monitor";
6
+
7
+ import * as armResources from "@azure/arm-resources";
8
+ import { getLogger } from "@logtape/logtape";
9
+
10
+ import type { AnalysisResult } from "../../types.js";
11
+
12
+ import {
13
+ getMetric,
14
+ verboseLog,
15
+ verboseLogAnalysisResult,
16
+ verboseLogResourceStart,
17
+ } from "../utils.js";
18
+
19
+ /**
20
+ * Analyzes an Azure Static Web App for potential cost optimization.
21
+ *
22
+ * @param resource - The Azure resource object
23
+ * @param monitorClient - Azure Monitor client for metrics
24
+ * @param timespanDays - Number of days to analyze metrics
25
+ * @param verbose - Enable verbose logging
26
+ * @returns Analysis result with cost risk and reason
27
+ */
28
+ export async function analyzeStaticSite(
29
+ resource: armResources.GenericResource,
30
+ monitorClient: MonitorClient,
31
+ timespanDays: number,
32
+ verbose = false,
33
+ ): Promise<AnalysisResult> {
34
+ verboseLogResourceStart(
35
+ verbose,
36
+ resource.name || "unknown",
37
+ "Static Web App (Microsoft.Web/staticSites)",
38
+ );
39
+ verboseLog(verbose, "Resource details:", resource);
40
+
41
+ const costRisk: "high" | "low" | "medium" = "low";
42
+ let reason = "";
43
+
44
+ if (!resource.id) {
45
+ return {
46
+ costRisk,
47
+ reason: "Resource ID is missing.",
48
+ suspectedUnused: false,
49
+ };
50
+ }
51
+
52
+ try {
53
+ verboseLog(verbose, "Checking metrics...");
54
+
55
+ // Check for site hits (requests to the static site)
56
+ // Note: Static Web Apps metrics use Total aggregation, not Average
57
+ // Ref. https://learn.microsoft.com/en-us/azure/azure-monitor/reference/supported-metrics/microsoft-web-staticsites-metrics
58
+ const siteHits = await getMetric(
59
+ monitorClient,
60
+ resource.id,
61
+ "SiteHits",
62
+ "Total",
63
+ timespanDays,
64
+ );
65
+
66
+ const bytesSent = await getMetric(
67
+ monitorClient,
68
+ resource.id,
69
+ "BytesSent",
70
+ "Total",
71
+ timespanDays,
72
+ );
73
+
74
+ verboseLog(
75
+ verbose,
76
+ `Site Hits: ${siteHits !== null ? `${siteHits.toFixed(0)} total requests` : "N/A"}`,
77
+ );
78
+ verboseLog(
79
+ verbose,
80
+ `Bytes Sent: ${bytesSent !== null ? `${(bytesSent / 1024 / 1024).toFixed(2)} MB total` : "N/A"}`,
81
+ );
82
+
83
+ // If both metrics are null, it means no data points exist (no traffic at all)
84
+ if (siteHits === null && bytesSent === null) {
85
+ reason += `No traffic data available in ${timespanDays} days. `;
86
+ } else {
87
+ if (siteHits !== null && siteHits < 100) {
88
+ // Less than 100 requests total in the timespan (< ~3.3 requests/day)
89
+ reason += `Very low site traffic (${siteHits.toFixed(0)} requests in ${timespanDays} days). `;
90
+ }
91
+
92
+ if (bytesSent !== null && bytesSent < 1048576) {
93
+ // Less than 1MB total in the timespan (< ~34KB/day)
94
+ reason += `Very low data transfer (${(bytesSent / 1024 / 1024).toFixed(2)} MB in ${timespanDays} days). `;
95
+ }
96
+ }
97
+ } catch (error) {
98
+ const logger = getLogger(["savemoney", "azure"]);
99
+ logger.warn(
100
+ `Failed to get metrics for Static Web App ${resource.name}: ${error instanceof Error ? error.message : error}`,
101
+ );
102
+ }
103
+
104
+ const suspectedUnused = reason.length > 0;
105
+ const result = { costRisk, reason: reason.trim(), suspectedUnused };
106
+ verboseLogAnalysisResult(verbose, result);
107
+ return result;
108
+ }