@rollupdate/hctl 0.0.0-stage → 3.1.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.
Files changed (143) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1071 -2
  3. package/dist/auction/cache.d.ts +6 -0
  4. package/dist/auction/cache.js +55 -0
  5. package/dist/auction/client.d.ts +24 -0
  6. package/dist/auction/client.js +236 -0
  7. package/dist/auction/commands.d.ts +2 -0
  8. package/dist/auction/commands.js +440 -0
  9. package/dist/auction/diff-formatter.d.ts +3 -0
  10. package/dist/auction/diff-formatter.js +61 -0
  11. package/dist/auction/diff.d.ts +11 -0
  12. package/dist/auction/diff.js +28 -0
  13. package/dist/auction/formatter.d.ts +21 -0
  14. package/dist/auction/formatter.js +182 -0
  15. package/dist/auction/store.d.ts +24 -0
  16. package/dist/auction/store.js +177 -0
  17. package/dist/auction/types.d.ts +74 -0
  18. package/dist/auction/types.js +5 -0
  19. package/dist/cli.d.ts +2 -0
  20. package/dist/cli.js +74 -0
  21. package/dist/client.d.ts +2 -0
  22. package/dist/client.js +4 -0
  23. package/dist/cloud/browser-bootstrap.d.ts +28 -0
  24. package/dist/cloud/browser-bootstrap.js +480 -0
  25. package/dist/cloud/client.d.ts +520 -0
  26. package/dist/cloud/client.js +755 -0
  27. package/dist/cloud/commands/certificate.d.ts +2 -0
  28. package/dist/cloud/commands/certificate.js +108 -0
  29. package/dist/cloud/commands/context.d.ts +2 -0
  30. package/dist/cloud/commands/context.js +133 -0
  31. package/dist/cloud/commands/datacenter.d.ts +2 -0
  32. package/dist/cloud/commands/datacenter.js +24 -0
  33. package/dist/cloud/commands/firewall.d.ts +2 -0
  34. package/dist/cloud/commands/firewall.js +142 -0
  35. package/dist/cloud/commands/floating-ip.d.ts +2 -0
  36. package/dist/cloud/commands/floating-ip.js +138 -0
  37. package/dist/cloud/commands/image.d.ts +2 -0
  38. package/dist/cloud/commands/image.js +98 -0
  39. package/dist/cloud/commands/index.d.ts +2 -0
  40. package/dist/cloud/commands/index.js +47 -0
  41. package/dist/cloud/commands/inventory.d.ts +2 -0
  42. package/dist/cloud/commands/inventory.js +13 -0
  43. package/dist/cloud/commands/iso.d.ts +2 -0
  44. package/dist/cloud/commands/iso.js +27 -0
  45. package/dist/cloud/commands/load-balancer-type.d.ts +2 -0
  46. package/dist/cloud/commands/load-balancer-type.js +24 -0
  47. package/dist/cloud/commands/load-balancer.d.ts +2 -0
  48. package/dist/cloud/commands/load-balancer.js +269 -0
  49. package/dist/cloud/commands/location.d.ts +2 -0
  50. package/dist/cloud/commands/location.js +24 -0
  51. package/dist/cloud/commands/network.d.ts +2 -0
  52. package/dist/cloud/commands/network.js +157 -0
  53. package/dist/cloud/commands/placement-group.d.ts +2 -0
  54. package/dist/cloud/commands/placement-group.js +79 -0
  55. package/dist/cloud/commands/pricing.d.ts +2 -0
  56. package/dist/cloud/commands/pricing.js +15 -0
  57. package/dist/cloud/commands/primary-ip.d.ts +2 -0
  58. package/dist/cloud/commands/primary-ip.js +139 -0
  59. package/dist/cloud/commands/server-type.d.ts +2 -0
  60. package/dist/cloud/commands/server-type.js +24 -0
  61. package/dist/cloud/commands/server.d.ts +2 -0
  62. package/dist/cloud/commands/server.js +346 -0
  63. package/dist/cloud/commands/ssh-key.d.ts +2 -0
  64. package/dist/cloud/commands/ssh-key.js +94 -0
  65. package/dist/cloud/commands/volume.d.ts +2 -0
  66. package/dist/cloud/commands/volume.js +138 -0
  67. package/dist/cloud/context.d.ts +34 -0
  68. package/dist/cloud/context.js +215 -0
  69. package/dist/cloud/formatter.d.ts +40 -0
  70. package/dist/cloud/formatter.js +824 -0
  71. package/dist/cloud/helpers.d.ts +27 -0
  72. package/dist/cloud/helpers.js +67 -0
  73. package/dist/cloud/inventory.d.ts +100 -0
  74. package/dist/cloud/inventory.js +229 -0
  75. package/dist/cloud/pricing.d.ts +27 -0
  76. package/dist/cloud/pricing.js +103 -0
  77. package/dist/cloud/token-instructions.d.ts +2 -0
  78. package/dist/cloud/token-instructions.js +21 -0
  79. package/dist/cloud/types.d.ts +437 -0
  80. package/dist/cloud/types.js +5 -0
  81. package/dist/config.d.ts +1 -0
  82. package/dist/config.js +2 -0
  83. package/dist/formatter.d.ts +3 -0
  84. package/dist/formatter.js +6 -0
  85. package/dist/index.d.ts +12 -0
  86. package/dist/index.js +21 -0
  87. package/dist/robot/client.d.ts +256 -0
  88. package/dist/robot/client.js +745 -0
  89. package/dist/robot/commands/auth.d.ts +2 -0
  90. package/dist/robot/commands/auth.js +54 -0
  91. package/dist/robot/commands/boot.d.ts +2 -0
  92. package/dist/robot/commands/boot.js +76 -0
  93. package/dist/robot/commands/cancel.d.ts +2 -0
  94. package/dist/robot/commands/cancel.js +37 -0
  95. package/dist/robot/commands/failover.d.ts +2 -0
  96. package/dist/robot/commands/failover.js +46 -0
  97. package/dist/robot/commands/firewall.d.ts +2 -0
  98. package/dist/robot/commands/firewall.js +72 -0
  99. package/dist/robot/commands/index.d.ts +2 -0
  100. package/dist/robot/commands/index.js +36 -0
  101. package/dist/robot/commands/interactive.d.ts +2 -0
  102. package/dist/robot/commands/interactive.js +152 -0
  103. package/dist/robot/commands/ip.d.ts +2 -0
  104. package/dist/robot/commands/ip.js +55 -0
  105. package/dist/robot/commands/key.d.ts +2 -0
  106. package/dist/robot/commands/key.js +68 -0
  107. package/dist/robot/commands/order.d.ts +2 -0
  108. package/dist/robot/commands/order.js +33 -0
  109. package/dist/robot/commands/rdns.d.ts +2 -0
  110. package/dist/robot/commands/rdns.js +41 -0
  111. package/dist/robot/commands/reset.d.ts +2 -0
  112. package/dist/robot/commands/reset.js +77 -0
  113. package/dist/robot/commands/server.d.ts +2 -0
  114. package/dist/robot/commands/server.js +32 -0
  115. package/dist/robot/commands/storagebox.d.ts +2 -0
  116. package/dist/robot/commands/storagebox.js +126 -0
  117. package/dist/robot/commands/subnet.d.ts +2 -0
  118. package/dist/robot/commands/subnet.js +24 -0
  119. package/dist/robot/commands/traffic.d.ts +2 -0
  120. package/dist/robot/commands/traffic.js +23 -0
  121. package/dist/robot/commands/vswitch.d.ts +2 -0
  122. package/dist/robot/commands/vswitch.js +81 -0
  123. package/dist/robot/commands/wol.d.ts +2 -0
  124. package/dist/robot/commands/wol.js +20 -0
  125. package/dist/robot/formatter.d.ts +57 -0
  126. package/dist/robot/formatter.js +582 -0
  127. package/dist/robot/types.d.ts +359 -0
  128. package/dist/robot/types.js +5 -0
  129. package/dist/shared/config.d.ts +86 -0
  130. package/dist/shared/config.js +289 -0
  131. package/dist/shared/formatter.d.ts +29 -0
  132. package/dist/shared/formatter.js +121 -0
  133. package/dist/shared/helpers.d.ts +39 -0
  134. package/dist/shared/helpers.js +86 -0
  135. package/dist/shared/init.d.ts +2 -0
  136. package/dist/shared/init.js +107 -0
  137. package/dist/shared/reference.d.ts +5 -0
  138. package/dist/shared/reference.js +689 -0
  139. package/dist/shared/schemas.d.ts +1 -0
  140. package/dist/shared/schemas.js +1031 -0
  141. package/dist/types.d.ts +2 -0
  142. package/dist/types.js +2 -0
  143. package/package.json +127 -4
@@ -0,0 +1,157 @@
1
+ import { success } from "../../shared/formatter.js";
2
+ import { confirmAction, output } from "../../shared/helpers.js";
3
+ import { formatNetworkDetails, formatNetworkList } from "../formatter.js";
4
+ import { cloudAction, resolveIdOrName, } from "../helpers.js";
5
+ export function registerNetworkCommands(parent) {
6
+ const network = parent.command("network").description("Network management");
7
+ network
8
+ .command("list")
9
+ .alias("ls")
10
+ .description("List all networks")
11
+ .option("-l, --label-selector <selector>", "Label selector")
12
+ .action(cloudAction(async (client, options) => {
13
+ const networks = await client.listNetworks({
14
+ label_selector: options.labelSelector,
15
+ });
16
+ output(networks, formatNetworkList, options);
17
+ }));
18
+ network
19
+ .command("describe <id-or-name>")
20
+ .description("Show network details")
21
+ .action(cloudAction(async (client, idOrName, options) => {
22
+ const id = await resolveIdOrName(idOrName, "network", (name) => client.listNetworks({ name }));
23
+ const net = await client.getNetwork(id);
24
+ output(net, formatNetworkDetails, options);
25
+ }));
26
+ network
27
+ .command("create")
28
+ .description("Create a network")
29
+ .requiredOption("--name <name>", "Network name")
30
+ .requiredOption("--ip-range <range>", "IP range (CIDR)")
31
+ .action(cloudAction(async (client, options) => {
32
+ const { network: net } = await client.createNetwork({
33
+ name: options.name,
34
+ ip_range: options.ipRange,
35
+ });
36
+ console.log(success(`Network '${net.name}' created (ID: ${net.id})`));
37
+ }));
38
+ network
39
+ .command("delete <id-or-name>")
40
+ .description("Delete a network")
41
+ .option("-y, --yes", "Skip confirmation")
42
+ .action(cloudAction(async (client, idOrName, options) => {
43
+ const id = await resolveIdOrName(idOrName, "network", (name) => client.listNetworks({ name }));
44
+ const net = await client.getNetwork(id);
45
+ if (!(await confirmAction(`Delete network '${net.name}' (ID: ${id})?`, options))) {
46
+ return;
47
+ }
48
+ await client.deleteNetwork(id);
49
+ console.log(success(`Network '${net.name}' (ID: ${id}) deleted.`));
50
+ }));
51
+ network
52
+ .command("update <id-or-name>")
53
+ .description("Update a network")
54
+ .option("--name <name>", "New name")
55
+ .action(cloudAction(async (client, idOrName, options) => {
56
+ const id = await resolveIdOrName(idOrName, "network", (name) => client.listNetworks({ name }));
57
+ await client.updateNetwork(id, { name: options.name });
58
+ console.log(success(`Network ${id} updated.`));
59
+ }));
60
+ network
61
+ .command("add-subnet <id-or-name>")
62
+ .description("Add subnet to network")
63
+ .requiredOption("--ip-range <range>", "Subnet IP range")
64
+ .requiredOption("--type <type>", "Subnet type (cloud, server, vswitch)")
65
+ .requiredOption("--network-zone <zone>", "Network zone")
66
+ .action(cloudAction(async (client, idOrName, options) => {
67
+ const id = await resolveIdOrName(idOrName, "network", (name) => client.listNetworks({ name }));
68
+ await client.addSubnetToNetwork(id, {
69
+ ip_range: options.ipRange,
70
+ type: options.type,
71
+ network_zone: options.networkZone,
72
+ });
73
+ console.log(success("Subnet added."));
74
+ }));
75
+ network
76
+ .command("delete-subnet <id-or-name>")
77
+ .description("Delete subnet from network")
78
+ .requiredOption("--ip-range <range>", "Subnet IP range to delete")
79
+ .action(cloudAction(async (client, idOrName, options) => {
80
+ const id = await resolveIdOrName(idOrName, "network", (name) => client.listNetworks({ name }));
81
+ await client.deleteSubnetFromNetwork(id, options.ipRange);
82
+ console.log(success("Subnet deleted."));
83
+ }));
84
+ network
85
+ .command("add-route <id-or-name>")
86
+ .description("Add route to network")
87
+ .requiredOption("--destination <cidr>", "Destination CIDR")
88
+ .requiredOption("--gateway <ip>", "Gateway IP")
89
+ .action(cloudAction(async (client, idOrName, options) => {
90
+ const id = await resolveIdOrName(idOrName, "network", (name) => client.listNetworks({ name }));
91
+ await client.addRouteToNetwork(id, {
92
+ destination: options.destination,
93
+ gateway: options.gateway,
94
+ });
95
+ console.log(success("Route added."));
96
+ }));
97
+ network
98
+ .command("delete-route <id-or-name>")
99
+ .description("Delete route from network")
100
+ .requiredOption("--destination <cidr>", "Destination CIDR")
101
+ .requiredOption("--gateway <ip>", "Gateway IP")
102
+ .action(cloudAction(async (client, idOrName, options) => {
103
+ const id = await resolveIdOrName(idOrName, "network", (name) => client.listNetworks({ name }));
104
+ await client.deleteRouteFromNetwork(id, {
105
+ destination: options.destination,
106
+ gateway: options.gateway,
107
+ });
108
+ console.log(success("Route deleted."));
109
+ }));
110
+ network
111
+ .command("change-ip-range <id-or-name>")
112
+ .description("Change network IP range")
113
+ .requiredOption("--ip-range <range>", "New IP range")
114
+ .action(cloudAction(async (client, idOrName, options) => {
115
+ const id = await resolveIdOrName(idOrName, "network", (name) => client.listNetworks({ name }));
116
+ await client.changeNetworkIpRange(id, options.ipRange);
117
+ console.log(success("IP range changed."));
118
+ }));
119
+ network
120
+ .command("enable-protection <id-or-name>")
121
+ .description("Enable delete protection")
122
+ .action(cloudAction(async (client, idOrName) => {
123
+ const id = await resolveIdOrName(idOrName, "network", (name) => client.listNetworks({ name }));
124
+ await client.changeNetworkProtection(id, true);
125
+ console.log(success(`Protection enabled for network ${id}.`));
126
+ }));
127
+ network
128
+ .command("disable-protection <id-or-name>")
129
+ .description("Disable delete protection")
130
+ .action(cloudAction(async (client, idOrName) => {
131
+ const id = await resolveIdOrName(idOrName, "network", (name) => client.listNetworks({ name }));
132
+ await client.changeNetworkProtection(id, false);
133
+ console.log(success(`Protection disabled for network ${id}.`));
134
+ }));
135
+ network
136
+ .command("add-label <id-or-name> <label>")
137
+ .description("Add a label (key=value)")
138
+ .action(cloudAction(async (client, idOrName, label) => {
139
+ const id = await resolveIdOrName(idOrName, "network", (name) => client.listNetworks({ name }));
140
+ const net = await client.getNetwork(id);
141
+ const [key, value] = label.split("=");
142
+ await client.updateNetwork(id, {
143
+ labels: { ...net.labels, [key]: value || "" },
144
+ });
145
+ console.log(success(`Label '${key}' added.`));
146
+ }));
147
+ network
148
+ .command("remove-label <id-or-name> <key>")
149
+ .description("Remove a label")
150
+ .action(cloudAction(async (client, idOrName, key) => {
151
+ const id = await resolveIdOrName(idOrName, "network", (name) => client.listNetworks({ name }));
152
+ const net = await client.getNetwork(id);
153
+ const labels = Object.fromEntries(Object.entries(net.labels).filter(([k]) => k !== key));
154
+ await client.updateNetwork(id, { labels });
155
+ console.log(success(`Label '${key}' removed.`));
156
+ }));
157
+ }
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerPlacementGroupCommands(parent: Command): void;
@@ -0,0 +1,79 @@
1
+ import { success } from "../../shared/formatter.js";
2
+ import { confirmAction, output } from "../../shared/helpers.js";
3
+ import { formatPlacementGroupDetails, formatPlacementGroupList, } from "../formatter.js";
4
+ import { cloudAction, resolveIdOrName, } from "../helpers.js";
5
+ export function registerPlacementGroupCommands(parent) {
6
+ const pg = parent
7
+ .command("placement-group")
8
+ .description("Placement group management");
9
+ pg.command("list")
10
+ .alias("ls")
11
+ .description("List all placement groups")
12
+ .option("-l, --label-selector <selector>", "Label selector")
13
+ .option("-s, --sort <field>", "Sort by field")
14
+ .action(cloudAction(async (client, options) => {
15
+ const groups = await client.listPlacementGroups({
16
+ label_selector: options.labelSelector,
17
+ sort: options.sort,
18
+ });
19
+ output(groups, formatPlacementGroupList, options);
20
+ }));
21
+ pg.command("describe <id-or-name>")
22
+ .description("Show placement group details")
23
+ .action(cloudAction(async (client, idOrName, options) => {
24
+ const id = await resolveIdOrName(idOrName, "placement group", (name) => client.listPlacementGroups({ name }));
25
+ const group = await client.getPlacementGroup(id);
26
+ output(group, formatPlacementGroupDetails, options);
27
+ }));
28
+ pg.command("create")
29
+ .description("Create a placement group")
30
+ .requiredOption("--name <name>", "Placement group name")
31
+ .option("--type <type>", "Placement group type", "spread")
32
+ .action(cloudAction(async (client, options) => {
33
+ const { placement_group: group } = await client.createPlacementGroup({
34
+ name: options.name,
35
+ type: (options.type || "spread"),
36
+ });
37
+ console.log(success(`Placement group '${group.name}' created (ID: ${group.id})`));
38
+ }));
39
+ pg.command("delete <id-or-name>")
40
+ .description("Delete a placement group")
41
+ .option("-y, --yes", "Skip confirmation")
42
+ .action(cloudAction(async (client, idOrName, options) => {
43
+ const id = await resolveIdOrName(idOrName, "placement group", (name) => client.listPlacementGroups({ name }));
44
+ const group = await client.getPlacementGroup(id);
45
+ if (!(await confirmAction(`Delete placement group '${group.name}' (ID: ${id})?`, options))) {
46
+ return;
47
+ }
48
+ await client.deletePlacementGroup(id);
49
+ console.log(success(`Placement group '${group.name}' (ID: ${id}) deleted.`));
50
+ }));
51
+ pg.command("update <id-or-name>")
52
+ .description("Update placement group")
53
+ .option("--name <name>", "New name")
54
+ .action(cloudAction(async (client, idOrName, options) => {
55
+ const id = await resolveIdOrName(idOrName, "placement group", (name) => client.listPlacementGroups({ name }));
56
+ await client.updatePlacementGroup(id, { name: options.name });
57
+ console.log(success(`Placement group ${id} updated.`));
58
+ }));
59
+ pg.command("add-label <id-or-name> <label>")
60
+ .description("Add a label (key=value)")
61
+ .action(cloudAction(async (client, idOrName, label) => {
62
+ const id = await resolveIdOrName(idOrName, "placement group", (name) => client.listPlacementGroups({ name }));
63
+ const group = await client.getPlacementGroup(id);
64
+ const [key, value] = label.split("=");
65
+ await client.updatePlacementGroup(id, {
66
+ labels: { ...group.labels, [key]: value || "" },
67
+ });
68
+ console.log(success(`Label '${key}' added.`));
69
+ }));
70
+ pg.command("remove-label <id-or-name> <key>")
71
+ .description("Remove a label")
72
+ .action(cloudAction(async (client, idOrName, key) => {
73
+ const id = await resolveIdOrName(idOrName, "placement group", (name) => client.listPlacementGroups({ name }));
74
+ const group = await client.getPlacementGroup(id);
75
+ const labels = Object.fromEntries(Object.entries(group.labels).filter(([k]) => k !== key));
76
+ await client.updatePlacementGroup(id, { labels });
77
+ console.log(success(`Label '${key}' removed.`));
78
+ }));
79
+ }
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerPricingCommands(parent: Command): void;
@@ -0,0 +1,15 @@
1
+ import { output } from "../../shared/helpers.js";
2
+ import { formatPricingSummary } from "../formatter.js";
3
+ import { cloudAction } from "../helpers.js";
4
+ export function registerPricingCommands(parent) {
5
+ const pricing = parent
6
+ .command("pricing")
7
+ .description("List prices from GET /pricing (list prices, not per-account billing)");
8
+ pricing
9
+ .command("show", { isDefault: true })
10
+ .description("Show current list prices (server types, load balancers, IPs, storage)")
11
+ .action(cloudAction(async (client, options) => {
12
+ const data = await client.getPricing();
13
+ output(data, formatPricingSummary, options);
14
+ }));
15
+ }
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerPrimaryIpCommands(parent: Command): void;
@@ -0,0 +1,139 @@
1
+ import { success } from "../../shared/formatter.js";
2
+ import { confirmAction, output } from "../../shared/helpers.js";
3
+ import { formatPrimaryIpDetails, formatPrimaryIpList } from "../formatter.js";
4
+ import { cloudAction, resolveIdOrName, } from "../helpers.js";
5
+ export function registerPrimaryIpCommands(parent) {
6
+ const pip = parent.command("primary-ip").description("Primary IP management");
7
+ pip
8
+ .command("list")
9
+ .alias("ls")
10
+ .description("List all primary IPs")
11
+ .option("-l, --label-selector <selector>", "Label selector")
12
+ .action(cloudAction(async (client, options) => {
13
+ const ips = await client.listPrimaryIps({
14
+ label_selector: options.labelSelector,
15
+ });
16
+ output(ips, formatPrimaryIpList, options);
17
+ }));
18
+ pip
19
+ .command("describe <id-or-name>")
20
+ .description("Show primary IP details")
21
+ .action(cloudAction(async (client, idOrName, options) => {
22
+ const id = await resolveIdOrName(idOrName, "primary IP", (name) => client.listPrimaryIps({ name }));
23
+ const ip = await client.getPrimaryIp(id);
24
+ output(ip, formatPrimaryIpDetails, options);
25
+ }));
26
+ pip
27
+ .command("create")
28
+ .description("Create a primary IP")
29
+ .requiredOption("--type <type>", "IP type (ipv4, ipv6)")
30
+ .requiredOption("--name <name>", "Name")
31
+ .option("--location <location>", "Location, e.g. fsn1 (required unless --assignee-id is set)")
32
+ .option("--assignee-id <id>", "Server to assign to")
33
+ .option("--auto-delete", "Auto-delete with server")
34
+ .action(cloudAction(async (client, options) => {
35
+ const { primary_ip: ip } = await client.createPrimaryIp({
36
+ type: options.type,
37
+ name: options.name,
38
+ assignee_type: "server",
39
+ location: options.location,
40
+ assignee_id: options.assigneeId
41
+ ? Number.parseInt(options.assigneeId, 10)
42
+ : undefined,
43
+ auto_delete: options.autoDelete,
44
+ });
45
+ console.log(success(`Primary IP created (ID: ${ip.id}, IP: ${ip.ip})`));
46
+ }));
47
+ pip
48
+ .command("delete <id-or-name>")
49
+ .description("Delete a primary IP")
50
+ .option("-y, --yes", "Skip confirmation")
51
+ .action(cloudAction(async (client, idOrName, options) => {
52
+ const id = await resolveIdOrName(idOrName, "primary IP", (name) => client.listPrimaryIps({ name }));
53
+ const ip = await client.getPrimaryIp(id);
54
+ if (!(await confirmAction(`Delete primary IP '${ip.name}' (ID: ${id})?`, options))) {
55
+ return;
56
+ }
57
+ await client.deletePrimaryIp(id);
58
+ console.log(success(`Primary IP '${ip.name}' (ID: ${id}) deleted.`));
59
+ }));
60
+ pip
61
+ .command("update <id-or-name>")
62
+ .description("Update primary IP")
63
+ .option("--name <name>", "New name")
64
+ .option("--auto-delete <bool>", "Auto-delete with server (true/false)")
65
+ .action(cloudAction(async (client, idOrName, options) => {
66
+ const id = await resolveIdOrName(idOrName, "primary IP", (name) => client.listPrimaryIps({ name }));
67
+ await client.updatePrimaryIp(id, {
68
+ name: options.name,
69
+ auto_delete: options.autoDelete
70
+ ? options.autoDelete === "true"
71
+ : undefined,
72
+ });
73
+ console.log(success(`Primary IP ${id} updated.`));
74
+ }));
75
+ pip
76
+ .command("assign <id-or-name> <server>")
77
+ .description("Assign primary IP to server")
78
+ .action(cloudAction(async (client, idOrName, server) => {
79
+ const id = await resolveIdOrName(idOrName, "primary IP", (name) => client.listPrimaryIps({ name }));
80
+ await client.assignPrimaryIp(id, Number.parseInt(server, 10));
81
+ console.log(success(`Primary IP ${id} assigned to server ${server}.`));
82
+ }));
83
+ pip
84
+ .command("unassign <id-or-name>")
85
+ .description("Unassign primary IP")
86
+ .action(cloudAction(async (client, idOrName) => {
87
+ const id = await resolveIdOrName(idOrName, "primary IP", (name) => client.listPrimaryIps({ name }));
88
+ await client.unassignPrimaryIp(id);
89
+ console.log(success(`Primary IP ${id} unassigned.`));
90
+ }));
91
+ pip
92
+ .command("enable-protection <id-or-name>")
93
+ .description("Enable delete protection")
94
+ .action(cloudAction(async (client, idOrName) => {
95
+ const id = await resolveIdOrName(idOrName, "primary IP", (name) => client.listPrimaryIps({ name }));
96
+ await client.changePrimaryIpProtection(id, true);
97
+ console.log(success(`Protection enabled for primary IP ${id}.`));
98
+ }));
99
+ pip
100
+ .command("disable-protection <id-or-name>")
101
+ .description("Disable delete protection")
102
+ .action(cloudAction(async (client, idOrName) => {
103
+ const id = await resolveIdOrName(idOrName, "primary IP", (name) => client.listPrimaryIps({ name }));
104
+ await client.changePrimaryIpProtection(id, false);
105
+ console.log(success(`Protection disabled for primary IP ${id}.`));
106
+ }));
107
+ pip
108
+ .command("set-rdns <id-or-name>")
109
+ .description("Set reverse DNS")
110
+ .requiredOption("--ip <ip>", "IP address")
111
+ .requiredOption("--dns-ptr <ptr>", "DNS pointer (empty to reset)")
112
+ .action(cloudAction(async (client, idOrName, options) => {
113
+ const id = await resolveIdOrName(idOrName, "primary IP", (name) => client.listPrimaryIps({ name }));
114
+ await client.changePrimaryIpDnsPtr(id, options.ip, options.dnsPtr || null);
115
+ console.log(success("rDNS updated."));
116
+ }));
117
+ pip
118
+ .command("add-label <id-or-name> <label>")
119
+ .description("Add a label (key=value)")
120
+ .action(cloudAction(async (client, idOrName, label) => {
121
+ const id = await resolveIdOrName(idOrName, "primary IP", (name) => client.listPrimaryIps({ name }));
122
+ const ip = await client.getPrimaryIp(id);
123
+ const [key, value] = label.split("=");
124
+ await client.updatePrimaryIp(id, {
125
+ labels: { ...ip.labels, [key]: value || "" },
126
+ });
127
+ console.log(success(`Label '${key}' added.`));
128
+ }));
129
+ pip
130
+ .command("remove-label <id-or-name> <key>")
131
+ .description("Remove a label")
132
+ .action(cloudAction(async (client, idOrName, key) => {
133
+ const id = await resolveIdOrName(idOrName, "primary IP", (name) => client.listPrimaryIps({ name }));
134
+ const ip = await client.getPrimaryIp(id);
135
+ const labels = Object.fromEntries(Object.entries(ip.labels).filter(([k]) => k !== key));
136
+ await client.updatePrimaryIp(id, { labels });
137
+ console.log(success(`Label '${key}' removed.`));
138
+ }));
139
+ }
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerServerTypeCommands(parent: Command): void;
@@ -0,0 +1,24 @@
1
+ import { output } from "../../shared/helpers.js";
2
+ import { formatServerTypeDetails, formatServerTypeList } from "../formatter.js";
3
+ import { cloudAction, resolveIdOrName, } from "../helpers.js";
4
+ export function registerServerTypeCommands(parent) {
5
+ const serverType = parent
6
+ .command("server-type")
7
+ .description("Server type information");
8
+ serverType
9
+ .command("list")
10
+ .alias("ls")
11
+ .description("List all server types")
12
+ .action(cloudAction(async (client, options) => {
13
+ const types = await client.listServerTypes();
14
+ output(types, formatServerTypeList, options);
15
+ }));
16
+ serverType
17
+ .command("describe <id-or-name>")
18
+ .description("Show server type details")
19
+ .action(cloudAction(async (client, idOrName, options) => {
20
+ const id = await resolveIdOrName(idOrName, "server type", (name) => client.listServerTypes({ name }));
21
+ const type = await client.getServerType(id);
22
+ output(type, formatServerTypeDetails, options);
23
+ }));
24
+ }
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerCloudServerCommands(parent: Command): void;