@pagopa/dx-cli 0.8.1 → 0.9.0
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 +58 -0
- package/bin/index.js +40 -8
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -71,6 +71,64 @@ Checking monorepo scripts...
|
|
|
71
71
|
✅ Monorepo scripts are correctly set up
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
+
#### `savemoney`
|
|
75
|
+
|
|
76
|
+
Analyze Azure subscriptions to identify unused or underutilized resources that could be costing you money.
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
dx savemoney [options]
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Options:**
|
|
83
|
+
|
|
84
|
+
| Option | Alias | Description | Default |
|
|
85
|
+
| :----------- | :---- | :-------------------------------------------------------------------- | :----------- |
|
|
86
|
+
| `--config` | `-c` | Path to a JSON configuration file. | N/A |
|
|
87
|
+
| `--format` | `-f` | Report format (`table`, `json`, `detailed-json`). | `table` |
|
|
88
|
+
| `--days` | `-d` | Metric analysis period in days. | `30` |
|
|
89
|
+
| `--location` | `-l` | Preferred Azure location for resources. | `italynorth` |
|
|
90
|
+
| `--verbose` | `-v` | Enable verbose mode with detailed logging for each resource analyzed. | `false` |
|
|
91
|
+
|
|
92
|
+
**Example usage:**
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Analyze with default settings (interactive prompts)
|
|
96
|
+
dx savemoney
|
|
97
|
+
|
|
98
|
+
# Use a configuration file
|
|
99
|
+
dx savemoney --config config.json
|
|
100
|
+
|
|
101
|
+
# Output as JSON with verbose logging
|
|
102
|
+
dx savemoney --format json --verbose
|
|
103
|
+
|
|
104
|
+
# Analyze with specific timespan
|
|
105
|
+
dx savemoney --days 60 --location italynorth
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Configuration file example (`config.json`):**
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"tenantId": "your-tenant-id",
|
|
113
|
+
"subscriptionIds": ["subscription-1", "subscription-2"],
|
|
114
|
+
"preferredLocation": "italynorth",
|
|
115
|
+
"timespanDays": 30
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Analyzed Azure resources:**
|
|
120
|
+
|
|
121
|
+
- **Virtual Machines**: Deallocated or stopped VMs, low CPU usage
|
|
122
|
+
- **Managed Disks**: Unattached disks
|
|
123
|
+
- **Network Interfaces**: Unattached NICs
|
|
124
|
+
- **Public IP Addresses**: Unassociated static IPs
|
|
125
|
+
- **Storage Accounts**: Low transaction counts
|
|
126
|
+
- **App Service Plans**: Empty plans or oversized tiers
|
|
127
|
+
- **Private Endpoints**: Unused or misconfigured endpoints
|
|
128
|
+
|
|
129
|
+
> [!NOTE]
|
|
130
|
+
> Currently only Azure is supported. Support for additional cloud providers (AWS) is planned for future releases.
|
|
131
|
+
|
|
74
132
|
### Global Options
|
|
75
133
|
|
|
76
134
|
- `--version, -V`: Display version number
|
package/bin/index.js
CHANGED
|
@@ -280,7 +280,7 @@ async function replacePMOccurrences() {
|
|
|
280
280
|
"https://yarnpkg.com/",
|
|
281
281
|
"https://classic.yarnpkg.com/",
|
|
282
282
|
/\b(yarn workspace|npm -(\b-workspace\b|\bw\b)) (\S+)\b/g,
|
|
283
|
-
/\b(yarn workspace|npm -(\b-workspace\b|\bw\b))
|
|
283
|
+
/\b(yarn workspace|npm -(\b-workspace\b|\bw\b))\b/g,
|
|
284
284
|
/\b(yarn install --immutable|npm ci)\b/g,
|
|
285
285
|
/\b(yarn -q dlx|npx)\b/g,
|
|
286
286
|
/\b(Yarn|npm)\b/gi
|
|
@@ -289,7 +289,7 @@ async function replacePMOccurrences() {
|
|
|
289
289
|
to: [
|
|
290
290
|
"https://pnpm.io/",
|
|
291
291
|
"https://pnpm.io/",
|
|
292
|
-
"pnpm --filter $
|
|
292
|
+
"pnpm --filter $3",
|
|
293
293
|
"pnpm --filter <package-selector>",
|
|
294
294
|
"pnpm install --frozen-lockfile",
|
|
295
295
|
"pnpm dlx",
|
|
@@ -399,7 +399,7 @@ registry.add(updateCodeReview);
|
|
|
399
399
|
var codemods_default = registry;
|
|
400
400
|
|
|
401
401
|
// src/adapters/commander/index.ts
|
|
402
|
-
import { Command as
|
|
402
|
+
import { Command as Command7 } from "commander";
|
|
403
403
|
|
|
404
404
|
// src/adapters/commander/commands/codemod.ts
|
|
405
405
|
import { getLogger as getLogger5 } from "@logtape/logtape";
|
|
@@ -756,25 +756,56 @@ var makeInitCommand = () => new Command4().name("init").description(
|
|
|
756
756
|
})
|
|
757
757
|
);
|
|
758
758
|
|
|
759
|
-
// src/adapters/commander/commands/
|
|
759
|
+
// src/adapters/commander/commands/savemoney.ts
|
|
760
|
+
import { azure, loadConfig } from "@pagopa/dx-savemoney";
|
|
760
761
|
import { Command as Command5 } from "commander";
|
|
762
|
+
var makeSavemoneyCommand = () => new Command5("savemoney").description(
|
|
763
|
+
"Analyze Azure subscriptions and report unused or inefficient resources"
|
|
764
|
+
).option("-c, --config <path>", "Path to configuration file (JSON)").option(
|
|
765
|
+
"-f, --format <format>",
|
|
766
|
+
"Report format: json, table, or detailed-json (default: table)",
|
|
767
|
+
"table"
|
|
768
|
+
).option(
|
|
769
|
+
"-l, --location <string>",
|
|
770
|
+
"Preferred Azure location for resources",
|
|
771
|
+
"italynorth"
|
|
772
|
+
).option("-d, --days <number>", "Number of days for metrics analysis", "30").option("-v, --verbose", "Enable verbose logging").action(async function(options) {
|
|
773
|
+
try {
|
|
774
|
+
const config2 = await loadConfig(options.config);
|
|
775
|
+
const finalConfig = {
|
|
776
|
+
...config2,
|
|
777
|
+
preferredLocation: options.location || config2.preferredLocation,
|
|
778
|
+
timespanDays: Number.parseInt(options.days, 10) || config2.timespanDays,
|
|
779
|
+
verbose: options.verbose || false
|
|
780
|
+
};
|
|
781
|
+
await azure.analyzeAzureResources(finalConfig, options.format);
|
|
782
|
+
} catch (error) {
|
|
783
|
+
this.error(
|
|
784
|
+
`Analysis failed: ${error instanceof Error ? error.message : error}`
|
|
785
|
+
);
|
|
786
|
+
}
|
|
787
|
+
});
|
|
788
|
+
|
|
789
|
+
// src/adapters/commander/commands/version.ts
|
|
790
|
+
import { Command as Command6 } from "commander";
|
|
761
791
|
|
|
762
792
|
// src/domain/version.ts
|
|
763
793
|
import { getLogger as getLogger7 } from "@logtape/logtape";
|
|
764
794
|
function printVersion() {
|
|
765
795
|
const logger2 = getLogger7(["dx-cli", "version"]);
|
|
766
|
-
logger2.info(`dx CLI version: ${"0.
|
|
796
|
+
logger2.info(`dx CLI version: ${"0.9.0"}`);
|
|
767
797
|
}
|
|
768
798
|
|
|
769
799
|
// src/adapters/commander/commands/version.ts
|
|
770
|
-
var makeVersionCommand = () => new
|
|
800
|
+
var makeVersionCommand = () => new Command6().name("version").alias("v").action(() => printVersion());
|
|
771
801
|
|
|
772
802
|
// src/adapters/commander/index.ts
|
|
773
803
|
var makeCli = (deps2, config2, cliDeps) => {
|
|
774
|
-
const program2 = new
|
|
775
|
-
program2.name("dx").description("The CLI for DX-Platform").version("0.
|
|
804
|
+
const program2 = new Command7();
|
|
805
|
+
program2.name("dx").description("The CLI for DX-Platform").version("0.9.0");
|
|
776
806
|
program2.addCommand(makeDoctorCommand(deps2, config2));
|
|
777
807
|
program2.addCommand(makeCodemodCommand(cliDeps));
|
|
808
|
+
program2.addCommand(makeSavemoneyCommand());
|
|
778
809
|
if (process.env.ENABLE_INIT_COMMAND) {
|
|
779
810
|
program2.addCommand(makeInitCommand());
|
|
780
811
|
}
|
|
@@ -962,6 +993,7 @@ var listCodemods = (registry2) => () => registry2.getAll();
|
|
|
962
993
|
await configure({
|
|
963
994
|
loggers: [
|
|
964
995
|
{ category: ["dx-cli"], lowestLevel: "info", sinks: ["console"] },
|
|
996
|
+
{ category: ["savemoney"], lowestLevel: "debug", sinks: ["console"] },
|
|
965
997
|
{ category: ["json"], lowestLevel: "info", sinks: ["rawJson"] },
|
|
966
998
|
{
|
|
967
999
|
category: ["logtape", "meta"],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pagopa/dx-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A CLI useful to manage DX tools.",
|
|
6
6
|
"repository": {
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
"semver": "^7.7.2",
|
|
32
32
|
"yaml": "^2.8.0",
|
|
33
33
|
"zod": "^3.25.28",
|
|
34
|
-
"@pagopa/
|
|
34
|
+
"@pagopa/dx-savemoney": "^0.1.0",
|
|
35
|
+
"@pagopa/monorepo-generator": "^0.8.3"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
38
|
"@tsconfig/node22": "22.0.2",
|