@pagopa/dx-cli 0.18.6 → 0.18.7

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
@@ -178,13 +178,14 @@ dx savemoney [options]
178
178
 
179
179
  **Options:**
180
180
 
181
- | Option | Alias | Description | Default |
182
- | :----------- | :---- | :-------------------------------------------------------------------- | :----------- |
183
- | `--config` | `-c` | Path to a JSON configuration file. | N/A |
184
- | `--format` | `-f` | Report format (`table`, `json`, `detailed-json`). | `table` |
185
- | `--days` | `-d` | Metric analysis period in days. | `30` |
186
- | `--location` | `-l` | Preferred Azure location for resources. | `italynorth` |
187
- | `--verbose` | `-v` | Enable verbose mode with detailed logging for each resource analyzed. | `false` |
181
+ | Option | Alias | Description | Default |
182
+ | :----------- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------- | :----------- |
183
+ | `--config` | `-c` | Path to a YAML configuration file. | N/A |
184
+ | `--format` | `-f` | Report format: `table`, `json`, `detailed-json`, or `lint`. | `table` |
185
+ | `--days` | `-d` | Metric analysis period in days (overrides config file). | `30` |
186
+ | `--location` | `-l` | Preferred Azure location for resources (overrides config file). | `italynorth` |
187
+ | `--verbose` | `-v` | Enable verbose mode with detailed logging for each resource analyzed. | `false` |
188
+ | `--tags` | `-t` | Filter resources by tags (`key=value key2=value2`). Only resources matching **all** specified tags are analyzed (variadic: space-separated). | N/A |
188
189
 
189
190
  **Example usage:**
190
191
 
@@ -193,24 +194,38 @@ dx savemoney [options]
193
194
  dx savemoney
194
195
 
195
196
  # Use a configuration file
196
- dx savemoney --config config.json
197
+ dx savemoney --config config.yaml
197
198
 
198
199
  # Output as JSON with verbose logging
199
200
  dx savemoney --format json --verbose
200
201
 
202
+ # Linter-style output for CI pipelines
203
+ dx savemoney --config config.yaml --format lint
204
+
205
+ # Analyze only resources tagged environment=prod
206
+ dx savemoney --config config.yaml --tags "environment=prod"
207
+
201
208
  # Analyze with specific timespan
202
209
  dx savemoney --days 60 --location italynorth
203
210
  ```
204
211
 
205
- **Configuration file example (`config.json`):**
206
-
207
- ```json
208
- {
209
- "tenantId": "your-tenant-id",
210
- "subscriptionIds": ["subscription-1", "subscription-2"],
211
- "preferredLocation": "italynorth",
212
- "timespanDays": 30
213
- }
212
+ **Configuration file example (`config.yaml`):**
213
+
214
+ ```yaml
215
+ azure:
216
+ subscriptionIds:
217
+ - subscription-1
218
+ - subscription-2
219
+ preferredLocation: italynorth
220
+ timespanDays: 30
221
+ thresholds: # optional — omit to use built-in defaults
222
+ vm:
223
+ cpuPercent: 5
224
+ appService:
225
+ cpuPercent: 10
226
+ memoryPercent: 20
227
+ storage:
228
+ transactionsPerDay: 50
214
229
  ```
215
230
 
216
231
  **Analyzed Azure resources:**
@@ -2,17 +2,21 @@ import { azure, loadConfig } from "@pagopa/dx-savemoney";
2
2
  import { Command } from "commander";
3
3
  export const makeSavemoneyCommand = () => new Command("savemoney")
4
4
  .description("Analyze Azure subscriptions and report unused or inefficient resources")
5
- .option("-c, --config <path>", "Path to configuration file (JSON)")
6
- .option("-f, --format <format>", "Report format: json, table, or detailed-json (default: table)", "table")
7
- .option("-l, --location <string>", "Preferred Azure location for resources", "italynorth")
8
- .option("-d, --days <number>", "Number of days for metrics analysis", "30")
5
+ .option("-c, --config <path>", "Path to YAML configuration file")
6
+ .option("-f, --format <format>", "Report format: json, table, detailed-json, or lint (default: table)", "table")
7
+ .option("-l, --location <string>", "Preferred Azure location for resources (overrides config file)", "italynorth")
8
+ .option("-d, --days <number>", "Number of days for metrics analysis (overrides config file)", "30")
9
9
  .option("-v, --verbose", "Enable verbose logging")
10
+ .option("-t, --tags <tags...>", "Filter resources by tags (key=value key2=value2). Only resources matching ALL specified tags are analyzed.")
10
11
  .action(async function (options) {
11
12
  try {
12
- // Load configuration
13
+ // Load configuration from YAML (includes subscriptionIds, location, timespanDays, thresholds)
13
14
  const config = await loadConfig(options.config);
15
+ // Parse tag filter
16
+ const filterTags = parseTagsOption(options.tags);
14
17
  const finalConfig = {
15
18
  ...config,
19
+ filterTags,
16
20
  preferredLocation: options.location || config.preferredLocation,
17
21
  timespanDays: Number.parseInt(options.days, 10) || config.timespanDays,
18
22
  verbose: options.verbose || false,
@@ -24,3 +28,23 @@ export const makeSavemoneyCommand = () => new Command("savemoney")
24
28
  this.error(`Analysis failed: ${error instanceof Error ? error.message : error}`);
25
29
  }
26
30
  });
31
+ /**
32
+ * Parses an array of "key=value" strings (from commander variadic option) into a Map<string, string>.
33
+ * Returns an empty Map when the option is not provided or empty.
34
+ * Supports values that contain "=" (only the first "=" is treated as separator).
35
+ */
36
+ function parseTagsOption(tagsOption) {
37
+ const result = new Map();
38
+ if (!tagsOption || tagsOption.length === 0) {
39
+ return result;
40
+ }
41
+ for (const pair of tagsOption) {
42
+ const [rawKey, ...rest] = pair.split("=");
43
+ const key = rawKey?.trim();
44
+ const value = rest.join("=").trim();
45
+ if (key && rest.length > 0) {
46
+ result.set(key, value);
47
+ }
48
+ }
49
+ return result;
50
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pagopa/dx-cli",
3
- "version": "0.18.6",
3
+ "version": "0.18.7",
4
4
  "type": "module",
5
5
  "description": "A CLI useful to manage DX tools.",
6
6
  "repository": {
@@ -47,7 +47,7 @@
47
47
  "semver": "^7.7.4",
48
48
  "yaml": "^2.8.2",
49
49
  "zod": "^4.3.6",
50
- "@pagopa/dx-savemoney": "^0.1.6"
50
+ "@pagopa/dx-savemoney": "^0.2.0"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@tsconfig/node24": "24.0.4",