@celilo/cli 0.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 (267) hide show
  1. package/README.md +1566 -0
  2. package/bin/celilo +16 -0
  3. package/drizzle/0000_complex_puma.sql +179 -0
  4. package/drizzle/0001_dizzy_wolfpack.sql +2 -0
  5. package/drizzle/0002_web_routes.sql +16 -0
  6. package/drizzle/0003_backup_storage.sql +32 -0
  7. package/drizzle/meta/0000_snapshot.json +1151 -0
  8. package/drizzle/meta/0001_snapshot.json +1167 -0
  9. package/drizzle/meta/0002_snapshot.json +1257 -0
  10. package/drizzle/meta/_journal.json +27 -0
  11. package/package.json +64 -0
  12. package/schemas/system_config.json +106 -0
  13. package/src/__integration__/container-services-cli.integration.test.ts +246 -0
  14. package/src/ansible/dependencies.test.ts +309 -0
  15. package/src/ansible/dependencies.ts +896 -0
  16. package/src/ansible/inventory.test.ts +463 -0
  17. package/src/ansible/inventory.ts +445 -0
  18. package/src/ansible/secrets.ts +222 -0
  19. package/src/ansible/validation.test.ts +92 -0
  20. package/src/ansible/validation.ts +272 -0
  21. package/src/api-clients/digitalocean.ts +94 -0
  22. package/src/api-clients/proxmox.ts +655 -0
  23. package/src/capabilities/logging-wrapper.test.ts +217 -0
  24. package/src/capabilities/lookup.test.ts +149 -0
  25. package/src/capabilities/lookup.ts +89 -0
  26. package/src/capabilities/public-web-helpers.test.ts +198 -0
  27. package/src/capabilities/public-web-publish.test.ts +458 -0
  28. package/src/capabilities/registration.test.ts +395 -0
  29. package/src/capabilities/registration.ts +200 -0
  30. package/src/capabilities/route-validation.test.ts +121 -0
  31. package/src/capabilities/route-validation.ts +96 -0
  32. package/src/capabilities/secret-ref.test.ts +313 -0
  33. package/src/capabilities/secret-validation.ts +157 -0
  34. package/src/capabilities/secrets.test.ts +750 -0
  35. package/src/capabilities/secrets.ts +244 -0
  36. package/src/capabilities/validation.test.ts +613 -0
  37. package/src/capabilities/validation.ts +160 -0
  38. package/src/capabilities/well-known.test.ts +238 -0
  39. package/src/capabilities/well-known.ts +222 -0
  40. package/src/cli/cli.test.ts +654 -0
  41. package/src/cli/command-registry.ts +742 -0
  42. package/src/cli/command-tree-parser.test.ts +180 -0
  43. package/src/cli/command-tree-parser.ts +193 -0
  44. package/src/cli/commands/backup-create.ts +137 -0
  45. package/src/cli/commands/backup-delete.ts +74 -0
  46. package/src/cli/commands/backup-import.ts +97 -0
  47. package/src/cli/commands/backup-list.ts +132 -0
  48. package/src/cli/commands/backup-name.ts +73 -0
  49. package/src/cli/commands/backup-prune.ts +98 -0
  50. package/src/cli/commands/backup-restore.ts +122 -0
  51. package/src/cli/commands/capability-info.ts +121 -0
  52. package/src/cli/commands/capability-list.ts +47 -0
  53. package/src/cli/commands/completion.ts +87 -0
  54. package/src/cli/commands/hook-run.ts +176 -0
  55. package/src/cli/commands/ipam.ts +607 -0
  56. package/src/cli/commands/machine-add.ts +235 -0
  57. package/src/cli/commands/machine-earmark.ts +82 -0
  58. package/src/cli/commands/machine-list.ts +77 -0
  59. package/src/cli/commands/machine-remove.ts +90 -0
  60. package/src/cli/commands/machine-status.ts +131 -0
  61. package/src/cli/commands/module-audit.ts +51 -0
  62. package/src/cli/commands/module-build.ts +60 -0
  63. package/src/cli/commands/module-config.ts +170 -0
  64. package/src/cli/commands/module-deploy.ts +71 -0
  65. package/src/cli/commands/module-generate.ts +236 -0
  66. package/src/cli/commands/module-health.ts +108 -0
  67. package/src/cli/commands/module-import.ts +80 -0
  68. package/src/cli/commands/module-list.ts +43 -0
  69. package/src/cli/commands/module-logs.ts +73 -0
  70. package/src/cli/commands/module-remove.ts +162 -0
  71. package/src/cli/commands/module-show.ts +208 -0
  72. package/src/cli/commands/module-status.ts +131 -0
  73. package/src/cli/commands/module-types.ts +189 -0
  74. package/src/cli/commands/module-upgrade.ts +192 -0
  75. package/src/cli/commands/package.ts +68 -0
  76. package/src/cli/commands/secret-list.ts +99 -0
  77. package/src/cli/commands/secret-set.ts +134 -0
  78. package/src/cli/commands/service-add-digitalocean.ts +133 -0
  79. package/src/cli/commands/service-add-proxmox.ts +342 -0
  80. package/src/cli/commands/service-config-get.ts +83 -0
  81. package/src/cli/commands/service-config-set.ts +145 -0
  82. package/src/cli/commands/service-list.ts +74 -0
  83. package/src/cli/commands/service-reconfigure.ts +230 -0
  84. package/src/cli/commands/service-remove.ts +103 -0
  85. package/src/cli/commands/service-verify.ts +240 -0
  86. package/src/cli/commands/status.ts +216 -0
  87. package/src/cli/commands/storage-add-local.ts +106 -0
  88. package/src/cli/commands/storage-add-s3.ts +114 -0
  89. package/src/cli/commands/storage-list.ts +72 -0
  90. package/src/cli/commands/storage-remove.ts +54 -0
  91. package/src/cli/commands/storage-set-default.ts +44 -0
  92. package/src/cli/commands/storage-verify.ts +54 -0
  93. package/src/cli/commands/system-config.ts +168 -0
  94. package/src/cli/commands/system-init.ts +314 -0
  95. package/src/cli/commands/system-secret-get.ts +98 -0
  96. package/src/cli/commands/system-secret-set.ts +76 -0
  97. package/src/cli/commands/system-vault-password.ts +34 -0
  98. package/src/cli/completion.test.ts +37 -0
  99. package/src/cli/completion.ts +482 -0
  100. package/src/cli/fuel-gauge.test.ts +208 -0
  101. package/src/cli/fuel-gauge.ts +405 -0
  102. package/src/cli/generate-zsh-completion.test.ts +95 -0
  103. package/src/cli/generate-zsh-completion.ts +497 -0
  104. package/src/cli/index.ts +1583 -0
  105. package/src/cli/interactive-config.test.ts +201 -0
  106. package/src/cli/interactive-config.ts +62 -0
  107. package/src/cli/parser.test.ts +227 -0
  108. package/src/cli/parser.ts +244 -0
  109. package/src/cli/prompts.test.ts +33 -0
  110. package/src/cli/prompts.ts +121 -0
  111. package/src/cli/types.ts +38 -0
  112. package/src/cli/validators.test.ts +235 -0
  113. package/src/cli/validators.ts +188 -0
  114. package/src/config/env.ts +41 -0
  115. package/src/config/paths.test.ts +172 -0
  116. package/src/config/paths.ts +108 -0
  117. package/src/db/client.ts +190 -0
  118. package/src/db/migrate.ts +30 -0
  119. package/src/db/schema.test.ts +221 -0
  120. package/src/db/schema.ts +434 -0
  121. package/src/hooks/capability-loader-firewall.test.ts +246 -0
  122. package/src/hooks/capability-loader.test.ts +100 -0
  123. package/src/hooks/capability-loader.ts +520 -0
  124. package/src/hooks/define-hook.test.ts +488 -0
  125. package/src/hooks/executor.test.ts +462 -0
  126. package/src/hooks/executor.ts +469 -0
  127. package/src/hooks/logger.test.ts +54 -0
  128. package/src/hooks/logger.ts +95 -0
  129. package/src/hooks/test-fixtures/failing-hook.ts +13 -0
  130. package/src/hooks/test-fixtures/no-default-hook.ts +6 -0
  131. package/src/hooks/test-fixtures/success-hook.ts +20 -0
  132. package/src/hooks/test-fixtures/unbranded-hook.ts +11 -0
  133. package/src/hooks/test-fixtures/void-hook.ts +13 -0
  134. package/src/hooks/types.ts +89 -0
  135. package/src/infrastructure/property-extractor.test.ts +194 -0
  136. package/src/infrastructure/property-extractor.ts +151 -0
  137. package/src/ipam/allocator.test.ts +442 -0
  138. package/src/ipam/allocator.ts +369 -0
  139. package/src/ipam/auto-allocator.test.ts +247 -0
  140. package/src/ipam/auto-allocator.ts +270 -0
  141. package/src/ipam/subnet-parser.test.ts +107 -0
  142. package/src/ipam/subnet-parser.ts +136 -0
  143. package/src/manifest/contracts/index.ts +61 -0
  144. package/src/manifest/contracts/v1.ts +118 -0
  145. package/src/manifest/json-schema-roundtrip.test.ts +99 -0
  146. package/src/manifest/schema.ts +367 -0
  147. package/src/manifest/template-validator.test.ts +231 -0
  148. package/src/manifest/template-validator.ts +322 -0
  149. package/src/manifest/validate.test.ts +1180 -0
  150. package/src/manifest/validate.ts +415 -0
  151. package/src/module/import.test.ts +355 -0
  152. package/src/module/import.ts +676 -0
  153. package/src/module/packaging/audit.ts +169 -0
  154. package/src/module/packaging/build.ts +228 -0
  155. package/src/module/packaging/checksum.ts +41 -0
  156. package/src/module/packaging/extract.ts +234 -0
  157. package/src/module/packaging/signature.ts +47 -0
  158. package/src/secrets/encryption.test.ts +284 -0
  159. package/src/secrets/encryption.ts +162 -0
  160. package/src/secrets/generators.test.ts +112 -0
  161. package/src/secrets/generators.ts +127 -0
  162. package/src/secrets/master-key.test.ts +159 -0
  163. package/src/secrets/master-key.ts +114 -0
  164. package/src/secrets/storage.test.ts +115 -0
  165. package/src/secrets/storage.ts +106 -0
  166. package/src/secrets/vault.test.ts +35 -0
  167. package/src/secrets/vault.ts +42 -0
  168. package/src/services/backup-create.ts +532 -0
  169. package/src/services/backup-metadata.ts +198 -0
  170. package/src/services/backup-restore.ts +229 -0
  171. package/src/services/backup-retention.ts +84 -0
  172. package/src/services/backup-storage.ts +281 -0
  173. package/src/services/build-stream.test.ts +122 -0
  174. package/src/services/build-stream.ts +201 -0
  175. package/src/services/config-interview.ts +694 -0
  176. package/src/services/container-service.test.ts +298 -0
  177. package/src/services/container-service.ts +401 -0
  178. package/src/services/cross-module-data-manager.test.ts +405 -0
  179. package/src/services/cross-module-data-manager.ts +412 -0
  180. package/src/services/deploy-ansible.ts +88 -0
  181. package/src/services/deploy-planner.ts +153 -0
  182. package/src/services/deploy-preflight.ts +274 -0
  183. package/src/services/deploy-ssh.ts +131 -0
  184. package/src/services/deploy-terraform.test.ts +55 -0
  185. package/src/services/deploy-terraform.ts +445 -0
  186. package/src/services/deploy-validation.ts +311 -0
  187. package/src/services/dns-auto-register.ts +211 -0
  188. package/src/services/health-runner.ts +184 -0
  189. package/src/services/infrastructure-selector.test.ts +485 -0
  190. package/src/services/infrastructure-selector.ts +245 -0
  191. package/src/services/infrastructure-variable-resolver.test.ts +751 -0
  192. package/src/services/infrastructure-variable-resolver.ts +234 -0
  193. package/src/services/machine-detector.ts +328 -0
  194. package/src/services/machine-pool.test.ts +405 -0
  195. package/src/services/machine-pool.ts +316 -0
  196. package/src/services/manifest-validation.ts +120 -0
  197. package/src/services/module-build.test.ts +290 -0
  198. package/src/services/module-build.ts +431 -0
  199. package/src/services/module-config.test.ts +237 -0
  200. package/src/services/module-config.ts +298 -0
  201. package/src/services/module-deploy.ts +862 -0
  202. package/src/services/module-types-drift.test.ts +73 -0
  203. package/src/services/module-types-generator.test.ts +288 -0
  204. package/src/services/module-types-generator.ts +189 -0
  205. package/src/services/proxmox-state-recovery.ts +140 -0
  206. package/src/services/schema-validation.ts +155 -0
  207. package/src/services/secret-schema-loader.test.ts +311 -0
  208. package/src/services/secret-schema-loader.ts +239 -0
  209. package/src/services/ssh-key-manager.test.ts +283 -0
  210. package/src/services/ssh-key-manager.ts +193 -0
  211. package/src/services/storage-providers/local.ts +105 -0
  212. package/src/services/storage-providers/s3.ts +182 -0
  213. package/src/services/storage-providers/types.ts +24 -0
  214. package/src/services/system-config-schema-types.ts +25 -0
  215. package/src/services/system-config-validator.test.ts +160 -0
  216. package/src/services/system-config-validator.ts +74 -0
  217. package/src/services/system-init.test.ts +153 -0
  218. package/src/services/system-init.ts +253 -0
  219. package/src/services/terraform-safety.ts +174 -0
  220. package/src/services/zone-detector.test.ts +110 -0
  221. package/src/services/zone-detector.ts +102 -0
  222. package/src/services/zone-policy.test.ts +97 -0
  223. package/src/services/zone-policy.ts +126 -0
  224. package/src/templates/generator.test.ts +645 -0
  225. package/src/templates/generator.ts +1119 -0
  226. package/src/templates/types.ts +62 -0
  227. package/src/test-utils/INTERACTIVE_PROMPTS.md +167 -0
  228. package/src/test-utils/cli-context-interactive.test.ts +152 -0
  229. package/src/test-utils/cli-context-server.test.ts +66 -0
  230. package/src/test-utils/cli-context.test.ts +273 -0
  231. package/src/test-utils/cli-context.ts +677 -0
  232. package/src/test-utils/cli-result.test.ts +282 -0
  233. package/src/test-utils/cli-result.ts +241 -0
  234. package/src/test-utils/cli.ts +55 -0
  235. package/src/test-utils/completion-harness.test.ts +126 -0
  236. package/src/test-utils/completion-harness.ts +82 -0
  237. package/src/test-utils/database.test.ts +182 -0
  238. package/src/test-utils/database.ts +126 -0
  239. package/src/test-utils/filesystem.test.ts +208 -0
  240. package/src/test-utils/filesystem.ts +142 -0
  241. package/src/test-utils/fixtures.test.ts +123 -0
  242. package/src/test-utils/fixtures.ts +160 -0
  243. package/src/test-utils/golden-diff.ts +197 -0
  244. package/src/test-utils/index.ts +77 -0
  245. package/src/test-utils/integration.ts +81 -0
  246. package/src/test-utils/module-fixtures.ts +468 -0
  247. package/src/test-utils/modules.test.ts +144 -0
  248. package/src/test-utils/modules.ts +183 -0
  249. package/src/test-utils/setup-test-db.ts +90 -0
  250. package/src/test-utils/value-extractor.test.ts +231 -0
  251. package/src/test-utils/value-extractor.ts +228 -0
  252. package/src/types/infrastructure.ts +157 -0
  253. package/src/utils/shell.test.ts +365 -0
  254. package/src/utils/shell.ts +159 -0
  255. package/src/validation/schemas.ts +166 -0
  256. package/src/variables/ansible-resolver.test.ts +142 -0
  257. package/src/variables/ansible-resolver.ts +69 -0
  258. package/src/variables/capability-self-ref.test.ts +220 -0
  259. package/src/variables/context.test.ts +1265 -0
  260. package/src/variables/context.ts +624 -0
  261. package/src/variables/declarative-derivation.test.ts +743 -0
  262. package/src/variables/declarative-derivation.ts +200 -0
  263. package/src/variables/parser.test.ts +231 -0
  264. package/src/variables/parser.ts +76 -0
  265. package/src/variables/resolver.test.ts +458 -0
  266. package/src/variables/resolver.ts +282 -0
  267. package/src/variables/types.ts +59 -0
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Value Extraction Testing
3
+ *
4
+ * Extracts values from generated Terraform and Ansible files to verify
5
+ * that variable substitution happened correctly.
6
+ */
7
+
8
+ import { readFile } from 'node:fs/promises';
9
+ import * as yaml from 'yaml';
10
+
11
+ export interface ExtractedValues {
12
+ terraform: {
13
+ vmid?: number;
14
+ hostname?: string;
15
+ ip?: string;
16
+ gateway?: string;
17
+ vlan?: number;
18
+ cores?: number;
19
+ memory?: number;
20
+ storage?: string;
21
+ rootfs_size?: string;
22
+ };
23
+ ansible: {
24
+ dns_primary?: string;
25
+ dns_fallback?: string;
26
+ gateway?: string;
27
+ };
28
+ }
29
+
30
+ export interface ValueExtractionResult {
31
+ pass: boolean;
32
+ extracted: ExtractedValues;
33
+ expected: ExtractedValues;
34
+ mismatches: Array<{
35
+ path: string;
36
+ expected: unknown;
37
+ actual: unknown;
38
+ }>;
39
+ }
40
+
41
+ /**
42
+ * Extract values from Terraform main.tf file
43
+ *
44
+ * @param terraformPath - Path to main.tf file
45
+ * @returns Extracted Terraform values
46
+ */
47
+ export async function extractTerraformValues(
48
+ terraformPath: string,
49
+ ): Promise<ExtractedValues['terraform']> {
50
+ const content = await readFile(terraformPath, 'utf-8');
51
+ const values: ExtractedValues['terraform'] = {};
52
+
53
+ // Extract vmid (integer)
54
+ const vmidMatch = content.match(/vmid\s*=\s*(\d+)/);
55
+ if (vmidMatch) {
56
+ values.vmid = Number.parseInt(vmidMatch[1] || '0', 10);
57
+ }
58
+
59
+ // Extract hostname (string)
60
+ const hostnameMatch = content.match(/hostname\s*=\s*"([^"]+)"/);
61
+ if (hostnameMatch) {
62
+ values.hostname = hostnameMatch[1];
63
+ }
64
+
65
+ // Extract IP address from network block
66
+ const ipMatch = content.match(/ip\s*=\s*"([^"]+)"/);
67
+ if (ipMatch) {
68
+ values.ip = ipMatch[1];
69
+ }
70
+
71
+ // Extract gateway from network block
72
+ const gwMatch = content.match(/gw\s*=\s*"([^"]+)"/);
73
+ if (gwMatch) {
74
+ values.gateway = gwMatch[1];
75
+ }
76
+
77
+ // Extract VLAN tag (integer)
78
+ const tagMatch = content.match(/tag\s*=\s*(\d+)/);
79
+ if (tagMatch) {
80
+ values.vlan = Number.parseInt(tagMatch[1] || '0', 10);
81
+ }
82
+
83
+ // Extract cores (integer)
84
+ const coresMatch = content.match(/cores\s*=\s*(\d+)/);
85
+ if (coresMatch) {
86
+ values.cores = Number.parseInt(coresMatch[1] || '0', 10);
87
+ }
88
+
89
+ // Extract memory (integer)
90
+ const memoryMatch = content.match(/memory\s*=\s*(\d+)/);
91
+ if (memoryMatch) {
92
+ values.memory = Number.parseInt(memoryMatch[1] || '0', 10);
93
+ }
94
+
95
+ // Extract storage from rootfs block
96
+ const storageMatch = content.match(/rootfs\s*{[^}]*storage\s*=\s*"([^"]+)"/s);
97
+ if (storageMatch) {
98
+ values.storage = storageMatch[1];
99
+ }
100
+
101
+ // Extract rootfs size
102
+ const sizeMatch = content.match(/rootfs\s*{[^}]*size\s*=\s*"([^"]+)"/s);
103
+ if (sizeMatch) {
104
+ values.rootfs_size = sizeMatch[1];
105
+ }
106
+
107
+ return values;
108
+ }
109
+
110
+ /**
111
+ * Extract values from Ansible inventory files
112
+ *
113
+ * Now that templates use Ansible Jinja2 syntax, actual values are stored
114
+ * in inventory YAML files, not hardcoded in templates.
115
+ *
116
+ * @param ansibleDir - Path to ansible directory (containing inventory/)
117
+ * @returns Extracted Ansible values
118
+ */
119
+ export async function extractAnsibleValues(
120
+ ansibleDir: string,
121
+ ): Promise<ExtractedValues['ansible']> {
122
+ const values: ExtractedValues['ansible'] = {};
123
+
124
+ try {
125
+ // Read group_vars/all.yml which contains system config
126
+ const groupVarsPath = `${ansibleDir}/inventory/group_vars/all.yml`;
127
+ const groupVarsContent = await readFile(groupVarsPath, 'utf-8');
128
+ const groupVars = yaml.parse(groupVarsContent) as Record<string, unknown>;
129
+
130
+ // Extract system config values
131
+ if (typeof groupVars.dns_primary === 'string') {
132
+ values.dns_primary = groupVars.dns_primary;
133
+ }
134
+ if (typeof groupVars.dns_fallback === 'string') {
135
+ values.dns_fallback = groupVars.dns_fallback;
136
+ }
137
+ if (typeof groupVars.routing_internal_gateway === 'string') {
138
+ values.gateway = groupVars.routing_internal_gateway;
139
+ }
140
+ } catch (error) {
141
+ // If inventory files don't exist, return empty values
142
+ console.error('Failed to extract Ansible values from inventory:', error);
143
+ }
144
+
145
+ return values;
146
+ }
147
+
148
+ /**
149
+ * Compare extracted values against expected test values
150
+ *
151
+ * @param generatedDir - Path to generated output directory
152
+ * @param expectedValues - Expected values from test-values.yml
153
+ * @returns Comparison result
154
+ */
155
+ export async function compareExtractedValues(
156
+ generatedDir: string,
157
+ expectedValues: {
158
+ terraform: ExtractedValues['terraform'];
159
+ ansible: ExtractedValues['ansible'];
160
+ },
161
+ ): Promise<ValueExtractionResult> {
162
+ const mismatches: ValueExtractionResult['mismatches'] = [];
163
+
164
+ // Extract Terraform values
165
+ const terraformPath = `${generatedDir}/terraform/main.tf`;
166
+ const extractedTerraform = await extractTerraformValues(terraformPath);
167
+
168
+ // Extract Ansible values from inventory
169
+ const ansibleDir = `${generatedDir}/ansible`;
170
+ const extractedAnsible = await extractAnsibleValues(ansibleDir);
171
+
172
+ // Compare Terraform values
173
+ for (const [key, expectedValue] of Object.entries(expectedValues.terraform)) {
174
+ const actualValue = extractedTerraform[key as keyof typeof extractedTerraform];
175
+ if (actualValue !== expectedValue) {
176
+ mismatches.push({
177
+ path: `terraform.${key}`,
178
+ expected: expectedValue,
179
+ actual: actualValue,
180
+ });
181
+ }
182
+ }
183
+
184
+ // Compare Ansible values
185
+ for (const [key, expectedValue] of Object.entries(expectedValues.ansible)) {
186
+ const actualValue = extractedAnsible[key as keyof typeof extractedAnsible];
187
+ if (actualValue !== expectedValue) {
188
+ mismatches.push({
189
+ path: `ansible.${key}`,
190
+ expected: expectedValue,
191
+ actual: actualValue,
192
+ });
193
+ }
194
+ }
195
+
196
+ return {
197
+ pass: mismatches.length === 0,
198
+ extracted: {
199
+ terraform: extractedTerraform,
200
+ ansible: extractedAnsible,
201
+ },
202
+ expected: expectedValues,
203
+ mismatches,
204
+ };
205
+ }
206
+
207
+ /**
208
+ * Format value extraction mismatches for display
209
+ *
210
+ * @param result - Value extraction result
211
+ * @returns Formatted string
212
+ */
213
+ export function formatValueMismatches(result: ValueExtractionResult): string {
214
+ if (result.pass) {
215
+ return 'All values match expected configuration';
216
+ }
217
+
218
+ const lines: string[] = [];
219
+
220
+ for (const mismatch of result.mismatches) {
221
+ lines.push(`❌ ${mismatch.path}`);
222
+ lines.push(` Expected: ${JSON.stringify(mismatch.expected)}`);
223
+ lines.push(` Actual: ${JSON.stringify(mismatch.actual)}`);
224
+ lines.push('');
225
+ }
226
+
227
+ return lines.join('\n');
228
+ }
@@ -0,0 +1,157 @@
1
+ import type { NetworkZone } from '../db/schema';
2
+
3
+ /**
4
+ * Machine classification
5
+ * - host: Single-interface machine, used for normal modules
6
+ * - router: Multi-interface machine spanning multiple zones, used for firewall modules
7
+ */
8
+ export type MachineRole = 'host' | 'router';
9
+
10
+ /**
11
+ * Detected network interface on a machine
12
+ */
13
+ export interface NetworkInterface {
14
+ name: string;
15
+ ipAddress: string;
16
+ zone: NetworkZone | 'unknown';
17
+ }
18
+
19
+ /**
20
+ * Container service provider types
21
+ */
22
+ export type ProviderName = 'proxmox' | 'digitalocean' | 'aws' | 'gcp' | 'azure';
23
+
24
+ /**
25
+ * Proxmox provider configuration
26
+ */
27
+ export interface ProxmoxConfig {
28
+ api_url: string;
29
+ api_token_id: string;
30
+ api_token_secret: string;
31
+ default_target_node: string;
32
+ lxc_template: string;
33
+ storage: string;
34
+ }
35
+
36
+ /**
37
+ * Digital Ocean provider configuration
38
+ */
39
+ export interface DigitalOceanConfig {
40
+ api_token: string;
41
+ region: string;
42
+ default_image: string;
43
+ size_mappings: Record<string, string>; // e.g., "1-1024" -> "s-1vcpu-1gb"
44
+ }
45
+
46
+ /**
47
+ * Container service (from database)
48
+ */
49
+ export interface ContainerService {
50
+ id: string;
51
+ serviceId: string; // User-facing kebab-case identifier
52
+ name: string;
53
+ providerName: ProviderName;
54
+ zones: NetworkZone[];
55
+ apiCredentialsEncrypted: string;
56
+ providerConfig: Record<string, unknown>;
57
+ verified: boolean;
58
+ verifiedAt: Date | null;
59
+ verificationError: string | null;
60
+ createdAt: Date;
61
+ updatedAt: Date;
62
+ }
63
+
64
+ /**
65
+ * Machine hardware specifications
66
+ */
67
+ export interface MachineHardware {
68
+ cpu_cores: number;
69
+ memory_mb: number;
70
+ disk_gb: number;
71
+ arch?: string;
72
+ }
73
+
74
+ /**
75
+ * Machine (from database)
76
+ */
77
+ export interface Machine {
78
+ id: string;
79
+ hostname: string;
80
+ zone: NetworkZone;
81
+ ipAddress: string;
82
+ sshUser: string;
83
+ sshKeyEncrypted: string;
84
+ hardware: MachineHardware;
85
+ role: MachineRole;
86
+ interfaces: NetworkInterface[];
87
+ assignedModuleIds: string[];
88
+ /** Module ID this machine is earmarked for, or null/undefined */
89
+ earmarkedModule?: string | null;
90
+ createdAt: Date;
91
+ updatedAt: Date;
92
+ }
93
+
94
+ /**
95
+ * Infrastructure type discriminator
96
+ */
97
+ export type InfrastructureType = 'machine' | 'container_service';
98
+
99
+ /**
100
+ * Module infrastructure tracking
101
+ */
102
+ export interface ModuleInfrastructure {
103
+ id: string;
104
+ moduleId: string;
105
+ infrastructureType: InfrastructureType;
106
+ machineId: string | null;
107
+ serviceId: string | null;
108
+ containerMetadata: Record<string, unknown> | null;
109
+ createdAt: Date;
110
+ }
111
+
112
+ /**
113
+ * Infrastructure selection result
114
+ */
115
+ export interface InfrastructureSelection {
116
+ type: InfrastructureType;
117
+ machineId?: string;
118
+ serviceId?: string;
119
+ }
120
+
121
+ /**
122
+ * Resource requirements (from module manifest)
123
+ */
124
+ export interface ResourceRequirements {
125
+ cpu: number;
126
+ memory: number;
127
+ disk: number;
128
+ storage?: string; // Optional, only for container services
129
+ zone: NetworkZone;
130
+ }
131
+
132
+ /**
133
+ * Resource allocation tracking for machines
134
+ */
135
+ export interface ResourceAllocation {
136
+ cpu: number;
137
+ memory: number;
138
+ disk: number;
139
+ }
140
+
141
+ /**
142
+ * Connection test result
143
+ */
144
+ export interface TestResult {
145
+ success: boolean;
146
+ message?: string;
147
+ details?: Record<string, unknown>;
148
+ }
149
+
150
+ /**
151
+ * Machine detection result
152
+ */
153
+ export interface DetectedMachineInfo {
154
+ hostname: string;
155
+ osInfo: string;
156
+ hardware: MachineHardware;
157
+ }