@mtndev/cli 1.1.0 → 2.0.1

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 (260) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/cjs/__chunks/VH7oDXx4.cjs +28 -0
  3. package/cjs/commands/aws/ec2/allow-ip/handler.cjs +261 -0
  4. package/cjs/commands/aws/ec2/allow-ip/handler.d.ts +6 -0
  5. package/cjs/commands/aws/ec2/allow-ip/index.cjs +25 -0
  6. package/cjs/commands/aws/ec2/allow-ip/index.d.ts +3 -0
  7. package/cjs/commands/aws/ec2/allow-ip/schema.cjs +33 -0
  8. package/cjs/commands/aws/ec2/allow-ip/schema.d.ts +33 -0
  9. package/cjs/commands/aws/ec2/allow-ip/utils.cjs +379 -0
  10. package/cjs/commands/aws/ec2/allow-ip/utils.d.ts +189 -0
  11. package/cjs/commands/aws/iam/admin-group.cjs +111 -0
  12. package/cjs/commands/aws/iam/admin-group.d.ts +55 -0
  13. package/cjs/commands/aws/iam/break-glass/handler.cjs +127 -0
  14. package/cjs/commands/aws/iam/break-glass/handler.d.ts +7 -0
  15. package/cjs/commands/aws/iam/break-glass/index.cjs +7 -0
  16. package/cjs/commands/aws/iam/break-glass/index.d.ts +2 -0
  17. package/cjs/commands/aws/iam/break-glass/schema.cjs +21 -0
  18. package/cjs/commands/aws/iam/break-glass/schema.d.ts +25 -0
  19. package/cjs/commands/aws/iam/check-admin/handler.cjs +89 -0
  20. package/cjs/commands/aws/iam/check-admin/handler.d.ts +5 -0
  21. package/cjs/commands/aws/iam/check-admin/index.cjs +7 -0
  22. package/cjs/commands/aws/iam/check-admin/index.d.ts +2 -0
  23. package/cjs/commands/aws/iam/check-admin/schema.cjs +19 -0
  24. package/cjs/commands/aws/iam/check-admin/schema.d.ts +19 -0
  25. package/cjs/commands/aws/iam/policies/s3-restrictions-deny-non-s3-services.json +20 -0
  26. package/cjs/commands/aws/iam/policies/sts-federation.json +11 -0
  27. package/cjs/commands/aws/iam/policies/user-admins-deny-list.json +175 -0
  28. package/cjs/commands/aws/iam/policies/user-admins-deny-regions-list.json +41 -0
  29. package/cjs/commands/aws/iam/policies/user-admins-self-service-iam.json +56 -0
  30. package/cjs/commands/aws/iam/policies/user-admins-write-list.json +117 -0
  31. package/cjs/commands/aws/iam/remove-admin/handler.cjs +120 -0
  32. package/cjs/commands/aws/iam/remove-admin/handler.d.ts +6 -0
  33. package/cjs/commands/aws/iam/remove-admin/index.cjs +7 -0
  34. package/cjs/commands/aws/iam/remove-admin/index.d.ts +2 -0
  35. package/cjs/commands/aws/iam/remove-admin/schema.cjs +22 -0
  36. package/cjs/commands/aws/iam/remove-admin/schema.d.ts +28 -0
  37. package/cjs/commands/aws/iam/setup-acl/handler.cjs +227 -0
  38. package/cjs/commands/aws/iam/setup-acl/handler.d.ts +6 -0
  39. package/cjs/commands/aws/iam/setup-acl/index.cjs +13 -0
  40. package/cjs/commands/aws/iam/setup-acl/index.d.ts +3 -0
  41. package/cjs/commands/aws/iam/setup-acl/schema.cjs +19 -0
  42. package/cjs/commands/aws/iam/setup-acl/schema.d.ts +24 -0
  43. package/cjs/commands/aws/iam/setup-acl/utils.cjs +305 -0
  44. package/cjs/commands/aws/iam/setup-acl/utils.d.ts +61 -0
  45. package/cjs/commands/aws/iam/users/handler.cjs +59 -0
  46. package/cjs/commands/aws/iam/users/handler.d.ts +5 -0
  47. package/cjs/commands/aws/iam/users/index.cjs +18 -0
  48. package/cjs/commands/aws/iam/users/index.d.ts +3 -0
  49. package/cjs/commands/aws/iam/users/schema.cjs +17 -0
  50. package/cjs/commands/aws/iam/users/schema.d.ts +18 -0
  51. package/cjs/commands/aws/iam/users/utils.cjs +454 -0
  52. package/cjs/commands/aws/iam/users/utils.d.ts +119 -0
  53. package/cjs/commands/aws/index.cjs +223 -0
  54. package/cjs/commands/aws/index.d.ts +14 -0
  55. package/cjs/commands/aws/route53/add-record/handler.cjs +264 -0
  56. package/cjs/commands/aws/route53/add-record/handler.d.ts +36 -0
  57. package/cjs/commands/aws/route53/add-record/index.cjs +26 -0
  58. package/cjs/commands/aws/route53/add-record/index.d.ts +3 -0
  59. package/cjs/commands/aws/route53/add-record/schema.cjs +43 -0
  60. package/cjs/commands/aws/route53/add-record/schema.d.ts +45 -0
  61. package/cjs/commands/aws/route53/add-record/utils.cjs +404 -0
  62. package/cjs/commands/aws/route53/add-record/utils.d.ts +216 -0
  63. package/cjs/commands/aws/route53/remove-record/handler.cjs +114 -0
  64. package/cjs/commands/aws/route53/remove-record/handler.d.ts +6 -0
  65. package/cjs/commands/aws/route53/remove-record/index.cjs +5 -0
  66. package/cjs/commands/aws/route53/remove-record/index.d.ts +2 -0
  67. package/cjs/commands/aws/route53/remove-record/schema.cjs +22 -0
  68. package/cjs/commands/aws/route53/remove-record/schema.d.ts +30 -0
  69. package/cjs/commands/aws/schema.cjs +19 -0
  70. package/cjs/commands/aws/schema.d.ts +13 -0
  71. package/cjs/commands/aws/ses/send-email/handler.cjs +73 -0
  72. package/cjs/commands/aws/ses/send-email/handler.d.ts +5 -0
  73. package/cjs/commands/aws/ses/send-email/index.cjs +9 -0
  74. package/cjs/commands/aws/ses/send-email/index.d.ts +3 -0
  75. package/cjs/commands/aws/ses/send-email/schema.cjs +24 -0
  76. package/cjs/commands/aws/ses/send-email/schema.d.ts +39 -0
  77. package/cjs/commands/aws/ses/send-email/utils.cjs +87 -0
  78. package/cjs/commands/aws/ses/send-email/utils.d.ts +47 -0
  79. package/cjs/commands/aws/ses/smtp-password.cjs +72 -0
  80. package/cjs/commands/aws/ses/smtp-password.d.ts +21 -0
  81. package/cjs/commands/aws/utils/exec-aws.cjs +145 -0
  82. package/cjs/commands/aws/utils/exec-aws.d.ts +79 -0
  83. package/cjs/commands/aws/utils/resolve-policy-path.cjs +15 -0
  84. package/cjs/commands/aws/utils/resolve-policy-path.d.ts +8 -0
  85. package/cjs/commands/aws/utils/resolve-profile.cjs +93 -0
  86. package/cjs/commands/aws/utils/resolve-profile.d.ts +28 -0
  87. package/cjs/commands/aws/utils/tty.cjs +54 -0
  88. package/cjs/commands/aws/utils/tty.d.ts +24 -0
  89. package/cjs/commands/db/create-readonly-user/handler.cjs +254 -0
  90. package/cjs/commands/db/create-readonly-user/handler.d.ts +5 -0
  91. package/cjs/commands/db/create-readonly-user/index.cjs +18 -0
  92. package/cjs/commands/db/create-readonly-user/index.d.ts +3 -0
  93. package/cjs/commands/db/create-readonly-user/mysql.cjs +102 -0
  94. package/cjs/commands/db/create-readonly-user/mysql.d.ts +33 -0
  95. package/cjs/commands/db/create-readonly-user/postgres.cjs +209 -0
  96. package/cjs/commands/db/create-readonly-user/postgres.d.ts +31 -0
  97. package/cjs/commands/db/create-readonly-user/schema.cjs +39 -0
  98. package/cjs/commands/db/create-readonly-user/schema.d.ts +55 -0
  99. package/cjs/commands/db/create-readonly-user/utils.cjs +160 -0
  100. package/cjs/commands/db/create-readonly-user/utils.d.ts +112 -0
  101. package/cjs/commands/db/index.cjs +46 -0
  102. package/cjs/commands/db/index.d.ts +6 -0
  103. package/cjs/commands/doppler/handler.cjs +95 -9
  104. package/cjs/commands/doppler/index.cjs +33 -41
  105. package/cjs/commands/doppler/index.d.ts +1 -0
  106. package/cjs/commands/doppler/schema.cjs +130 -6
  107. package/cjs/commands/doppler/schema.d.ts +233 -17
  108. package/cjs/commands/doppler/set-secret.cjs +378 -0
  109. package/cjs/commands/doppler/set-secret.d.ts +113 -0
  110. package/cjs/commands/doppler/utils/exec.cjs +106 -12
  111. package/cjs/commands/doppler/utils.cjs +412 -30
  112. package/cjs/commands/doppler/utils.d.ts +32 -8
  113. package/cjs/commands/icons/handler.cjs +82 -8
  114. package/cjs/commands/icons/index.cjs +15 -31
  115. package/cjs/commands/icons/schema.cjs +101 -13
  116. package/cjs/commands/icons/schema.d.ts +1 -1
  117. package/cjs/commands/icons/utils.cjs +131 -13
  118. package/cjs/commands/index.cjs +54 -82
  119. package/cjs/commands/schema.cjs +25 -8
  120. package/cjs/index.cjs +3 -4
  121. package/esm/commands/aws/ec2/allow-ip/handler.d.ts +6 -0
  122. package/esm/commands/aws/ec2/allow-ip/handler.js +258 -0
  123. package/esm/commands/aws/ec2/allow-ip/index.d.ts +3 -0
  124. package/esm/commands/aws/ec2/allow-ip/index.js +4 -0
  125. package/esm/commands/aws/ec2/allow-ip/schema.d.ts +33 -0
  126. package/esm/commands/aws/ec2/allow-ip/schema.js +29 -0
  127. package/esm/commands/aws/ec2/allow-ip/utils.d.ts +189 -0
  128. package/esm/commands/aws/ec2/allow-ip/utils.js +363 -0
  129. package/esm/commands/aws/iam/admin-group.d.ts +55 -0
  130. package/esm/commands/aws/iam/admin-group.js +104 -0
  131. package/esm/commands/aws/iam/break-glass/handler.d.ts +7 -0
  132. package/esm/commands/aws/iam/break-glass/handler.js +124 -0
  133. package/esm/commands/aws/iam/break-glass/index.d.ts +2 -0
  134. package/esm/commands/aws/iam/break-glass/index.js +4 -0
  135. package/esm/commands/aws/iam/break-glass/schema.d.ts +25 -0
  136. package/esm/commands/aws/iam/break-glass/schema.js +19 -0
  137. package/esm/commands/aws/iam/check-admin/handler.d.ts +5 -0
  138. package/esm/commands/aws/iam/check-admin/handler.js +86 -0
  139. package/esm/commands/aws/iam/check-admin/index.d.ts +2 -0
  140. package/esm/commands/aws/iam/check-admin/index.js +4 -0
  141. package/esm/commands/aws/iam/check-admin/schema.d.ts +19 -0
  142. package/esm/commands/aws/iam/check-admin/schema.js +17 -0
  143. package/esm/commands/aws/iam/policies/s3-restrictions-deny-non-s3-services.json +20 -0
  144. package/esm/commands/aws/iam/policies/sts-federation.json +11 -0
  145. package/esm/commands/aws/iam/policies/user-admins-deny-list.json +175 -0
  146. package/esm/commands/aws/iam/policies/user-admins-deny-regions-list.json +41 -0
  147. package/esm/commands/aws/iam/policies/user-admins-self-service-iam.json +56 -0
  148. package/esm/commands/aws/iam/policies/user-admins-write-list.json +117 -0
  149. package/esm/commands/aws/iam/remove-admin/handler.d.ts +6 -0
  150. package/esm/commands/aws/iam/remove-admin/handler.js +117 -0
  151. package/esm/commands/aws/iam/remove-admin/index.d.ts +2 -0
  152. package/esm/commands/aws/iam/remove-admin/index.js +4 -0
  153. package/esm/commands/aws/iam/remove-admin/schema.d.ts +28 -0
  154. package/esm/commands/aws/iam/remove-admin/schema.js +20 -0
  155. package/esm/commands/aws/iam/setup-acl/handler.d.ts +6 -0
  156. package/esm/commands/aws/iam/setup-acl/handler.js +224 -0
  157. package/esm/commands/aws/iam/setup-acl/index.d.ts +3 -0
  158. package/esm/commands/aws/iam/setup-acl/index.js +4 -0
  159. package/esm/commands/aws/iam/setup-acl/schema.d.ts +24 -0
  160. package/esm/commands/aws/iam/setup-acl/schema.js +18 -0
  161. package/esm/commands/aws/iam/setup-acl/utils.d.ts +61 -0
  162. package/esm/commands/aws/iam/setup-acl/utils.js +298 -0
  163. package/esm/commands/aws/iam/users/handler.d.ts +5 -0
  164. package/esm/commands/aws/iam/users/handler.js +56 -0
  165. package/esm/commands/aws/iam/users/index.d.ts +3 -0
  166. package/esm/commands/aws/iam/users/index.js +4 -0
  167. package/esm/commands/aws/iam/users/schema.d.ts +18 -0
  168. package/esm/commands/aws/iam/users/schema.js +16 -0
  169. package/esm/commands/aws/iam/users/utils.d.ts +119 -0
  170. package/esm/commands/aws/iam/users/utils.js +440 -0
  171. package/esm/commands/aws/index.d.ts +14 -0
  172. package/esm/commands/aws/index.js +142 -0
  173. package/esm/commands/aws/route53/add-record/handler.d.ts +36 -0
  174. package/esm/commands/aws/route53/add-record/handler.js +258 -0
  175. package/esm/commands/aws/route53/add-record/index.d.ts +3 -0
  176. package/esm/commands/aws/route53/add-record/index.js +4 -0
  177. package/esm/commands/aws/route53/add-record/schema.d.ts +45 -0
  178. package/esm/commands/aws/route53/add-record/schema.js +40 -0
  179. package/esm/commands/aws/route53/add-record/utils.d.ts +216 -0
  180. package/esm/commands/aws/route53/add-record/utils.js +389 -0
  181. package/esm/commands/aws/route53/remove-record/handler.d.ts +6 -0
  182. package/esm/commands/aws/route53/remove-record/handler.js +111 -0
  183. package/esm/commands/aws/route53/remove-record/index.d.ts +2 -0
  184. package/esm/commands/aws/route53/remove-record/index.js +3 -0
  185. package/esm/commands/aws/route53/remove-record/schema.d.ts +30 -0
  186. package/esm/commands/aws/route53/remove-record/schema.js +21 -0
  187. package/esm/commands/aws/schema.d.ts +13 -0
  188. package/esm/commands/aws/schema.js +16 -0
  189. package/esm/commands/aws/ses/send-email/handler.d.ts +5 -0
  190. package/esm/commands/aws/ses/send-email/handler.js +70 -0
  191. package/esm/commands/aws/ses/send-email/index.d.ts +3 -0
  192. package/esm/commands/aws/ses/send-email/index.js +4 -0
  193. package/esm/commands/aws/ses/send-email/schema.d.ts +39 -0
  194. package/esm/commands/aws/ses/send-email/schema.js +23 -0
  195. package/esm/commands/aws/ses/send-email/utils.d.ts +47 -0
  196. package/esm/commands/aws/ses/send-email/utils.js +84 -0
  197. package/esm/commands/aws/ses/smtp-password.d.ts +21 -0
  198. package/esm/commands/aws/ses/smtp-password.js +69 -0
  199. package/esm/commands/aws/utils/exec-aws.d.ts +79 -0
  200. package/esm/commands/aws/utils/exec-aws.js +137 -0
  201. package/esm/commands/aws/utils/resolve-policy-path.d.ts +8 -0
  202. package/esm/commands/aws/utils/resolve-policy-path.js +14 -0
  203. package/esm/commands/aws/utils/resolve-profile.d.ts +28 -0
  204. package/esm/commands/aws/utils/resolve-profile.js +88 -0
  205. package/esm/commands/aws/utils/tty.d.ts +24 -0
  206. package/esm/commands/aws/utils/tty.js +51 -0
  207. package/esm/commands/db/create-readonly-user/handler.d.ts +5 -0
  208. package/esm/commands/db/create-readonly-user/handler.js +251 -0
  209. package/esm/commands/db/create-readonly-user/index.d.ts +3 -0
  210. package/esm/commands/db/create-readonly-user/index.js +4 -0
  211. package/esm/commands/db/create-readonly-user/mysql.d.ts +33 -0
  212. package/esm/commands/db/create-readonly-user/mysql.js +98 -0
  213. package/esm/commands/db/create-readonly-user/postgres.d.ts +31 -0
  214. package/esm/commands/db/create-readonly-user/postgres.js +205 -0
  215. package/esm/commands/db/create-readonly-user/schema.d.ts +55 -0
  216. package/esm/commands/db/create-readonly-user/schema.js +35 -0
  217. package/esm/commands/db/create-readonly-user/utils.d.ts +112 -0
  218. package/esm/commands/db/create-readonly-user/utils.js +151 -0
  219. package/esm/commands/db/index.d.ts +6 -0
  220. package/esm/commands/db/index.js +31 -0
  221. package/esm/commands/doppler/handler.js +92 -9
  222. package/esm/commands/doppler/index.d.ts +1 -0
  223. package/esm/commands/doppler/index.js +6 -41
  224. package/esm/commands/doppler/schema.d.ts +233 -17
  225. package/esm/commands/doppler/schema.js +125 -7
  226. package/esm/commands/doppler/set-secret.d.ts +113 -0
  227. package/esm/commands/doppler/set-secret.js +370 -0
  228. package/esm/commands/doppler/utils/exec.js +100 -12
  229. package/esm/commands/doppler/utils.d.ts +32 -8
  230. package/esm/commands/doppler/utils.js +396 -30
  231. package/esm/commands/icons/handler.js +79 -8
  232. package/esm/commands/icons/index.js +4 -31
  233. package/esm/commands/icons/schema.d.ts +1 -1
  234. package/esm/commands/icons/schema.js +97 -15
  235. package/esm/commands/icons/utils.js +125 -13
  236. package/esm/commands/index.js +49 -78
  237. package/esm/commands/schema.js +22 -7
  238. package/esm/index.js +3 -4
  239. package/package.json +12 -2
  240. package/vitest.config.ts +11 -0
  241. package/cjs/__chunks/4GFJUCSP.cjs +0 -52
  242. package/cjs/__chunks/4SFWHCB3.cjs +0 -133
  243. package/cjs/__chunks/B2KFW7T7.cjs +0 -1
  244. package/cjs/__chunks/EMMC33QA.cjs +0 -401
  245. package/cjs/__chunks/INFOPAHN.cjs +0 -117
  246. package/cjs/__chunks/J36P6UNE.cjs +0 -75
  247. package/cjs/__chunks/NIMXXHJQ.cjs +0 -92
  248. package/cjs/__chunks/NSRFG4DF.cjs +0 -100
  249. package/cjs/__chunks/WNJ3ZYLI.cjs +0 -1
  250. package/cjs/__chunks/ZMDIOZPT.cjs +0 -22
  251. package/esm/__chunks/46HGXFME.js +0 -0
  252. package/esm/__chunks/6G4PXXKF.js +0 -75
  253. package/esm/__chunks/6L5RNR7G.js +0 -100
  254. package/esm/__chunks/FL7AILGH.js +0 -133
  255. package/esm/__chunks/HJSXC6HP.js +0 -117
  256. package/esm/__chunks/O262GK4B.js +0 -401
  257. package/esm/__chunks/O3CCA76Q.js +0 -22
  258. package/esm/__chunks/SJXQJ7RS.js +0 -92
  259. package/esm/__chunks/SNCKIAOR.js +0 -0
  260. package/esm/__chunks/X3R5PSWH.js +0 -52
@@ -0,0 +1,379 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_commands_aws_utils_exec_aws = require("../../utils/exec-aws.cjs");
3
+ const require_commands_aws_ec2_allow_ip_schema = require("./schema.cjs");
4
+ //#region src/commands/aws/ec2/allow-ip/utils.js
5
+ /**
6
+ * @typedef {Object} Ec2Instance
7
+ * @property {string} instanceId
8
+ * @property {string} name
9
+ * @property {string} state
10
+ * @property {string} instanceType
11
+ * @property {string | null} publicIp
12
+ * @property {string[]} securityGroupIds
13
+ */
14
+ /**
15
+ * @typedef {Object} SecurityGroup
16
+ * @property {string} groupId
17
+ * @property {string} groupName
18
+ * @property {string} description
19
+ */
20
+ /**
21
+ * @typedef {Object} SshIngressRule
22
+ * @property {string} cidrIp
23
+ * @property {string} description
24
+ * @property {number} fromPort
25
+ * @property {number} toPort
26
+ * @property {string} ipProtocol
27
+ */
28
+ /**
29
+ * Determine the caller's current public IPv4 address.
30
+ * @returns {Promise<string>}
31
+ */
32
+ async function getCurrentPublicIp() {
33
+ for (const url of ["https://checkip.amazonaws.com", "https://api.ipify.org"]) try {
34
+ const controller = new AbortController();
35
+ const timeout = setTimeout(() => controller.abort(), 8e3);
36
+ const response = await fetch(url, { signal: controller.signal });
37
+ clearTimeout(timeout);
38
+ if (!response.ok) continue;
39
+ const ip = (await response.text()).trim();
40
+ if (ip && ip.includes(".")) return ip;
41
+ } catch {
42
+ continue;
43
+ }
44
+ throw new Error("Could not determine your current public IP address");
45
+ }
46
+ /**
47
+ * List regions that are opted-in / enabled for the profile.
48
+ * @param {{ profile?: string; region: string; verbose?: boolean }} params
49
+ * @returns {string[]}
50
+ */
51
+ function listEnabledRegions(params) {
52
+ const { profile, region, verbose } = params;
53
+ const data = require_commands_aws_utils_exec_aws.runAws({
54
+ profile,
55
+ region,
56
+ args: [
57
+ "ec2",
58
+ "describe-regions",
59
+ "--query",
60
+ "Regions[?OptInStatus!=`not-opted-in`].RegionName"
61
+ ],
62
+ verbose
63
+ });
64
+ return (Array.isArray(data) ? data : []).map((value) => String(value)).sort();
65
+ }
66
+ /**
67
+ * List non-terminated EC2 instances in a region.
68
+ * @param {{ profile?: string; region: string; verbose?: boolean }} params
69
+ * @returns {Ec2Instance[]}
70
+ */
71
+ function listInstances(params) {
72
+ const { profile, region, verbose } = params;
73
+ const data = require_commands_aws_utils_exec_aws.runAws({
74
+ profile,
75
+ region,
76
+ args: ["ec2", "describe-instances"],
77
+ verbose
78
+ });
79
+ /** @type {Ec2Instance[]} */
80
+ const instances = [];
81
+ for (const reservation of data.Reservations ?? []) for (const raw of reservation.Instances ?? []) {
82
+ const state = raw.State?.Name ?? "unknown";
83
+ if (state === "terminated" || state === "shutting-down") continue;
84
+ let name = "";
85
+ for (const tag of raw.Tags ?? []) if (tag.Key === "Name") {
86
+ name = tag.Value ?? "";
87
+ break;
88
+ }
89
+ const securityGroupIds = (raw.SecurityGroups ?? []).map((group) => group.GroupId).filter((id) => Boolean(id));
90
+ instances.push({
91
+ instanceId: raw.InstanceId,
92
+ name,
93
+ state,
94
+ instanceType: raw.InstanceType ?? "unknown",
95
+ publicIp: raw.PublicIpAddress ?? null,
96
+ securityGroupIds
97
+ });
98
+ }
99
+ instances.sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()) || a.instanceId.localeCompare(b.instanceId));
100
+ return instances;
101
+ }
102
+ /**
103
+ * Describe security groups by id.
104
+ * @param {{ profile?: string; region: string; groupIds: string[]; verbose?: boolean }} params
105
+ * @returns {SecurityGroup[]}
106
+ */
107
+ function describeSecurityGroups(params) {
108
+ const { profile, region, groupIds, verbose } = params;
109
+ if (groupIds.length === 0) return [];
110
+ /** @type {SecurityGroup[]} */
111
+ const groups = (require_commands_aws_utils_exec_aws.runAws({
112
+ profile,
113
+ region,
114
+ args: [
115
+ "ec2",
116
+ "describe-security-groups",
117
+ "--group-ids",
118
+ ...groupIds
119
+ ],
120
+ verbose
121
+ }).SecurityGroups ?? []).map((raw) => ({
122
+ groupId: raw.GroupId,
123
+ groupName: raw.GroupName ?? "",
124
+ description: raw.Description ?? ""
125
+ }));
126
+ groups.sort((a, b) => a.groupName.localeCompare(b.groupName));
127
+ return groups;
128
+ }
129
+ /**
130
+ * Load full details for a single security group.
131
+ * @param {{ profile?: string; region: string; groupId: string; verbose?: boolean }} params
132
+ * @returns {any | null}
133
+ */
134
+ function getSecurityGroupDetails(params) {
135
+ const { profile, region, groupId, verbose } = params;
136
+ const securityGroups = require_commands_aws_utils_exec_aws.runAws({
137
+ profile,
138
+ region,
139
+ args: [
140
+ "ec2",
141
+ "describe-security-groups",
142
+ "--group-ids",
143
+ groupId
144
+ ],
145
+ verbose
146
+ }).SecurityGroups ?? [];
147
+ if (securityGroups.length === 0) return null;
148
+ return securityGroups[0];
149
+ }
150
+ /**
151
+ * @param {string} cidrIp
152
+ * @returns {boolean}
153
+ */
154
+ function isSingleHostCidr(cidrIp) {
155
+ return cidrIp.endsWith("/32") && cidrIp !== "0.0.0.0/0";
156
+ }
157
+ /**
158
+ * @param {any} permission
159
+ * @returns {boolean}
160
+ */
161
+ function portAllowsSsh(permission) {
162
+ const protocol = permission.IpProtocol;
163
+ if (protocol !== "tcp" && protocol !== "6") return false;
164
+ const fromPort = permission.FromPort;
165
+ const toPort = permission.ToPort;
166
+ if (fromPort === void 0 && toPort === void 0) return true;
167
+ if (fromPort === void 0 || toPort === void 0) return false;
168
+ return fromPort <= 22 && 22 <= toPort;
169
+ }
170
+ /**
171
+ * Extract single-host SSH ingress rules (port 22, /32) from a security group.
172
+ * @param {any} securityGroup
173
+ * @returns {SshIngressRule[]}
174
+ */
175
+ function listSshIngressRules(securityGroup) {
176
+ /** @type {SshIngressRule[]} */
177
+ const rules = [];
178
+ for (const permission of securityGroup.IpPermissions ?? []) {
179
+ if (!portAllowsSsh(permission)) continue;
180
+ const fromPort = permission.FromPort ?? 22;
181
+ const toPort = permission.ToPort ?? 22;
182
+ const ipProtocol = permission.IpProtocol ?? "tcp";
183
+ for (const ipRange of permission.IpRanges ?? []) {
184
+ const cidrIp = ipRange.CidrIp;
185
+ if (!cidrIp || !isSingleHostCidr(cidrIp)) continue;
186
+ rules.push({
187
+ cidrIp,
188
+ description: ipRange.Description ?? "",
189
+ fromPort,
190
+ toPort,
191
+ ipProtocol
192
+ });
193
+ }
194
+ }
195
+ return rules;
196
+ }
197
+ /**
198
+ * Derive a first name from the IAM ARN or profile (md-{name}-...).
199
+ * @param {{ profile?: string; identity: { Arn?: string } }} params
200
+ * @returns {string}
201
+ */
202
+ function extractRoamingFirstName(params) {
203
+ const { profile, identity } = params;
204
+ const arn = identity.Arn ?? "";
205
+ const username = arn.includes("/") ? arn.split("/").pop() ?? "" : "";
206
+ for (const candidate of [username, profile ?? ""]) {
207
+ if (!candidate) continue;
208
+ const match = /^md-([^-]+)-/.exec(candidate);
209
+ if (match && match[1]) return match[1].charAt(0).toUpperCase() + match[1].slice(1).toLowerCase();
210
+ }
211
+ return require_commands_aws_ec2_allow_ip_schema.DEFAULT_ROAMING_NAME;
212
+ }
213
+ /**
214
+ * @param {string} firstName
215
+ * @returns {string}
216
+ */
217
+ function roamingRuleDescription(firstName) {
218
+ return `${firstName} Roaming`;
219
+ }
220
+ /**
221
+ * Find an existing rule whose description matches the roaming rule name.
222
+ * @param {SshIngressRule[]} sshRules
223
+ * @param {string} ruleDescription
224
+ * @returns {SshIngressRule | null}
225
+ */
226
+ function resolveRoamingRule(sshRules, ruleDescription) {
227
+ const target = ruleDescription.toLowerCase();
228
+ for (const rule of sshRules) if (rule.description.trim().toLowerCase() === target) return rule;
229
+ return null;
230
+ }
231
+ /**
232
+ * Find an existing rule that already allows the given CIDR.
233
+ * @param {SshIngressRule[]} sshRules
234
+ * @param {string} newCidr
235
+ * @returns {SshIngressRule | null}
236
+ */
237
+ function ruleAlreadyAllowsIp(sshRules, newCidr) {
238
+ for (const rule of sshRules) if (rule.cidrIp === newCidr) return rule;
239
+ return null;
240
+ }
241
+ /**
242
+ * @param {{
243
+ * cidrIp: string;
244
+ * description: string;
245
+ * fromPort?: number;
246
+ * toPort?: number;
247
+ * ipProtocol?: string;
248
+ * }} params
249
+ * @returns {string} JSON string for the --ip-permissions argument
250
+ */
251
+ function buildIpPermissions(params) {
252
+ const { cidrIp, description, fromPort = 22, toPort = 22, ipProtocol = "tcp" } = params;
253
+ return JSON.stringify([{
254
+ IpProtocol: ipProtocol,
255
+ FromPort: fromPort,
256
+ ToPort: toPort,
257
+ IpRanges: [{
258
+ CidrIp: cidrIp,
259
+ Description: description
260
+ }]
261
+ }]);
262
+ }
263
+ /**
264
+ * Authorize a new SSH ingress rule.
265
+ * @param {{
266
+ * profile?: string;
267
+ * region: string;
268
+ * groupId: string;
269
+ * cidrIp: string;
270
+ * description: string;
271
+ * fromPort?: number;
272
+ * toPort?: number;
273
+ * ipProtocol?: string;
274
+ * verbose?: boolean;
275
+ * }} params
276
+ */
277
+ function authorizeRule(params) {
278
+ const { profile, region, groupId, verbose, ...rule } = params;
279
+ require_commands_aws_utils_exec_aws.runAws({
280
+ profile,
281
+ region,
282
+ args: [
283
+ "ec2",
284
+ "authorize-security-group-ingress",
285
+ "--group-id",
286
+ groupId,
287
+ "--ip-permissions",
288
+ buildIpPermissions(rule)
289
+ ],
290
+ expectJson: false,
291
+ verbose
292
+ });
293
+ }
294
+ /**
295
+ * Revoke an existing SSH ingress rule.
296
+ * @param {{
297
+ * profile?: string;
298
+ * region: string;
299
+ * groupId: string;
300
+ * rule: SshIngressRule;
301
+ * verbose?: boolean;
302
+ * }} params
303
+ */
304
+ function revokeRule(params) {
305
+ const { profile, region, groupId, rule, verbose } = params;
306
+ require_commands_aws_utils_exec_aws.runAws({
307
+ profile,
308
+ region,
309
+ args: [
310
+ "ec2",
311
+ "revoke-security-group-ingress",
312
+ "--group-id",
313
+ groupId,
314
+ "--ip-permissions",
315
+ buildIpPermissions({
316
+ cidrIp: rule.cidrIp,
317
+ description: rule.description,
318
+ fromPort: rule.fromPort,
319
+ toPort: rule.toPort,
320
+ ipProtocol: rule.ipProtocol
321
+ })
322
+ ],
323
+ expectJson: false,
324
+ verbose
325
+ });
326
+ }
327
+ /**
328
+ * @param {Ec2Instance} instance
329
+ * @returns {string}
330
+ */
331
+ function instanceLabel(instance) {
332
+ const publicIp = instance.publicIp || "no public IP";
333
+ const name = instance.name || "(no name)";
334
+ return `${instance.instanceId} ${name} ${instance.state} ${instance.instanceType} ${publicIp}`;
335
+ }
336
+ /**
337
+ * @param {SecurityGroup} group
338
+ * @returns {string}
339
+ */
340
+ function securityGroupLabel(group) {
341
+ return `${group.groupId} ${group.groupName} ${group.description}`;
342
+ }
343
+ /**
344
+ * @param {SshIngressRule} rule
345
+ * @returns {string}
346
+ */
347
+ function sshRuleLabel(rule) {
348
+ const description = rule.description || "(no description)";
349
+ return `${rule.cidrIp} ${description}`;
350
+ }
351
+ /**
352
+ * Print single-host SSH rules using the given logger.
353
+ * @param {SshIngressRule[]} sshRules
354
+ * @param {(message: string) => void} [log]
355
+ */
356
+ function printSshRules(sshRules, log = console.log) {
357
+ if (sshRules.length === 0) {
358
+ log(" (no single-host SSH rules on port 22)");
359
+ return;
360
+ }
361
+ for (const rule of sshRules) log(` - ${sshRuleLabel(rule)}`);
362
+ }
363
+ //#endregion
364
+ exports.authorizeRule = authorizeRule;
365
+ exports.describeSecurityGroups = describeSecurityGroups;
366
+ exports.extractRoamingFirstName = extractRoamingFirstName;
367
+ exports.getCurrentPublicIp = getCurrentPublicIp;
368
+ exports.getSecurityGroupDetails = getSecurityGroupDetails;
369
+ exports.instanceLabel = instanceLabel;
370
+ exports.listEnabledRegions = listEnabledRegions;
371
+ exports.listInstances = listInstances;
372
+ exports.listSshIngressRules = listSshIngressRules;
373
+ exports.printSshRules = printSshRules;
374
+ exports.resolveRoamingRule = resolveRoamingRule;
375
+ exports.revokeRule = revokeRule;
376
+ exports.roamingRuleDescription = roamingRuleDescription;
377
+ exports.ruleAlreadyAllowsIp = ruleAlreadyAllowsIp;
378
+ exports.securityGroupLabel = securityGroupLabel;
379
+ exports.sshRuleLabel = sshRuleLabel;
@@ -0,0 +1,189 @@
1
+ /**
2
+ * @typedef {Object} Ec2Instance
3
+ * @property {string} instanceId
4
+ * @property {string} name
5
+ * @property {string} state
6
+ * @property {string} instanceType
7
+ * @property {string | null} publicIp
8
+ * @property {string[]} securityGroupIds
9
+ */
10
+ /**
11
+ * @typedef {Object} SecurityGroup
12
+ * @property {string} groupId
13
+ * @property {string} groupName
14
+ * @property {string} description
15
+ */
16
+ /**
17
+ * @typedef {Object} SshIngressRule
18
+ * @property {string} cidrIp
19
+ * @property {string} description
20
+ * @property {number} fromPort
21
+ * @property {number} toPort
22
+ * @property {string} ipProtocol
23
+ */
24
+ /**
25
+ * Determine the caller's current public IPv4 address.
26
+ * @returns {Promise<string>}
27
+ */
28
+ export function getCurrentPublicIp(): Promise<string>;
29
+ /**
30
+ * List regions that are opted-in / enabled for the profile.
31
+ * @param {{ profile?: string; region: string; verbose?: boolean }} params
32
+ * @returns {string[]}
33
+ */
34
+ export function listEnabledRegions(params: {
35
+ profile?: string;
36
+ region: string;
37
+ verbose?: boolean;
38
+ }): string[];
39
+ /**
40
+ * List non-terminated EC2 instances in a region.
41
+ * @param {{ profile?: string; region: string; verbose?: boolean }} params
42
+ * @returns {Ec2Instance[]}
43
+ */
44
+ export function listInstances(params: {
45
+ profile?: string;
46
+ region: string;
47
+ verbose?: boolean;
48
+ }): Ec2Instance[];
49
+ /**
50
+ * Describe security groups by id.
51
+ * @param {{ profile?: string; region: string; groupIds: string[]; verbose?: boolean }} params
52
+ * @returns {SecurityGroup[]}
53
+ */
54
+ export function describeSecurityGroups(params: {
55
+ profile?: string;
56
+ region: string;
57
+ groupIds: string[];
58
+ verbose?: boolean;
59
+ }): SecurityGroup[];
60
+ /**
61
+ * Load full details for a single security group.
62
+ * @param {{ profile?: string; region: string; groupId: string; verbose?: boolean }} params
63
+ * @returns {any | null}
64
+ */
65
+ export function getSecurityGroupDetails(params: {
66
+ profile?: string;
67
+ region: string;
68
+ groupId: string;
69
+ verbose?: boolean;
70
+ }): any | null;
71
+ /**
72
+ * Extract single-host SSH ingress rules (port 22, /32) from a security group.
73
+ * @param {any} securityGroup
74
+ * @returns {SshIngressRule[]}
75
+ */
76
+ export function listSshIngressRules(securityGroup: any): SshIngressRule[];
77
+ /**
78
+ * Derive a first name from the IAM ARN or profile (md-{name}-...).
79
+ * @param {{ profile?: string; identity: { Arn?: string } }} params
80
+ * @returns {string}
81
+ */
82
+ export function extractRoamingFirstName(params: {
83
+ profile?: string;
84
+ identity: {
85
+ Arn?: string;
86
+ };
87
+ }): string;
88
+ /**
89
+ * @param {string} firstName
90
+ * @returns {string}
91
+ */
92
+ export function roamingRuleDescription(firstName: string): string;
93
+ /**
94
+ * Find an existing rule whose description matches the roaming rule name.
95
+ * @param {SshIngressRule[]} sshRules
96
+ * @param {string} ruleDescription
97
+ * @returns {SshIngressRule | null}
98
+ */
99
+ export function resolveRoamingRule(sshRules: SshIngressRule[], ruleDescription: string): SshIngressRule | null;
100
+ /**
101
+ * Find an existing rule that already allows the given CIDR.
102
+ * @param {SshIngressRule[]} sshRules
103
+ * @param {string} newCidr
104
+ * @returns {SshIngressRule | null}
105
+ */
106
+ export function ruleAlreadyAllowsIp(sshRules: SshIngressRule[], newCidr: string): SshIngressRule | null;
107
+ /**
108
+ * Authorize a new SSH ingress rule.
109
+ * @param {{
110
+ * profile?: string;
111
+ * region: string;
112
+ * groupId: string;
113
+ * cidrIp: string;
114
+ * description: string;
115
+ * fromPort?: number;
116
+ * toPort?: number;
117
+ * ipProtocol?: string;
118
+ * verbose?: boolean;
119
+ * }} params
120
+ */
121
+ export function authorizeRule(params: {
122
+ profile?: string;
123
+ region: string;
124
+ groupId: string;
125
+ cidrIp: string;
126
+ description: string;
127
+ fromPort?: number;
128
+ toPort?: number;
129
+ ipProtocol?: string;
130
+ verbose?: boolean;
131
+ }): void;
132
+ /**
133
+ * Revoke an existing SSH ingress rule.
134
+ * @param {{
135
+ * profile?: string;
136
+ * region: string;
137
+ * groupId: string;
138
+ * rule: SshIngressRule;
139
+ * verbose?: boolean;
140
+ * }} params
141
+ */
142
+ export function revokeRule(params: {
143
+ profile?: string;
144
+ region: string;
145
+ groupId: string;
146
+ rule: SshIngressRule;
147
+ verbose?: boolean;
148
+ }): void;
149
+ /**
150
+ * @param {Ec2Instance} instance
151
+ * @returns {string}
152
+ */
153
+ export function instanceLabel(instance: Ec2Instance): string;
154
+ /**
155
+ * @param {SecurityGroup} group
156
+ * @returns {string}
157
+ */
158
+ export function securityGroupLabel(group: SecurityGroup): string;
159
+ /**
160
+ * @param {SshIngressRule} rule
161
+ * @returns {string}
162
+ */
163
+ export function sshRuleLabel(rule: SshIngressRule): string;
164
+ /**
165
+ * Print single-host SSH rules using the given logger.
166
+ * @param {SshIngressRule[]} sshRules
167
+ * @param {(message: string) => void} [log]
168
+ */
169
+ export function printSshRules(sshRules: SshIngressRule[], log?: (message: string) => void): void;
170
+ export type Ec2Instance = {
171
+ instanceId: string;
172
+ name: string;
173
+ state: string;
174
+ instanceType: string;
175
+ publicIp: string | null;
176
+ securityGroupIds: string[];
177
+ };
178
+ export type SecurityGroup = {
179
+ groupId: string;
180
+ groupName: string;
181
+ description: string;
182
+ };
183
+ export type SshIngressRule = {
184
+ cidrIp: string;
185
+ description: string;
186
+ fromPort: number;
187
+ toPort: number;
188
+ ipProtocol: string;
189
+ };
@@ -0,0 +1,111 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_rolldown_runtime = require("../../../__chunks/VH7oDXx4.cjs");
3
+ const require_commands_aws_utils_exec_aws = require("../utils/exec-aws.cjs");
4
+ let chalk = require("chalk");
5
+ chalk = require_rolldown_runtime.__toESM(chalk, 1);
6
+ let child_process = require("child_process");
7
+ //#region src/commands/aws/iam/admin-group.js
8
+ /**
9
+ * The IAM group that grants break-glass admin access and should normally be empty.
10
+ */
11
+ const ADMIN_GROUP_NAME = "acl-admin-do-not-use";
12
+ const VAULT_DURATION = process.env.AWS_VAULT_DURATION ?? "15m";
13
+ /**
14
+ * A function bound to a profile's working credential mode (direct or aws-vault).
15
+ * @typedef {(args: string[], options?: { expectJson?: boolean }) => any} ProfileRunner
16
+ */
17
+ /**
18
+ * List aws-vault profiles that have stored credentials.
19
+ * @returns {string[]}
20
+ */
21
+ function listVaultProfiles() {
22
+ const result = (0, child_process.spawnSync)("aws-vault", ["list", "--credentials"], { encoding: "utf-8" });
23
+ if (result.status !== 0) return [];
24
+ return (result.stdout ?? "").split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
25
+ }
26
+ /**
27
+ * Resolve which profiles to scan for admin-group commands.
28
+ * Uses `--profile`, then `AWS_PROFILE`, for a single profile unless `--all` is set.
29
+ * @param {{ profile?: string; all?: boolean }} params
30
+ * @returns {string[]}
31
+ */
32
+ function resolveAdminScanProfiles({ profile, all = false }) {
33
+ const targetProfile = profile ?? process.env.AWS_PROFILE;
34
+ if (!all && targetProfile) return [targetProfile];
35
+ const profiles = listVaultProfiles();
36
+ if (profiles.length === 0) throw new Error("No aws-vault profiles with credentials found.");
37
+ return profiles;
38
+ }
39
+ /**
40
+ * @param {{ Users?: Array<{ UserName: string }> }} group
41
+ * @returns {string[]}
42
+ */
43
+ function groupUserNames(group) {
44
+ return (group.Users ?? []).map((user) => user.UserName);
45
+ }
46
+ /**
47
+ * Resolve a working credential runner for a profile and read the admin group.
48
+ * Tries stored credentials first, then falls back to `aws-vault exec`.
49
+ * The returned `run` reuses whichever mode worked, so callers can perform
50
+ * follow-up mutations (e.g. remove-user-from-group) with the same credentials.
51
+ * @param {{ profile: string; verbose?: boolean }} params
52
+ * @returns {{ accountId: string; arn: string; users: string[]; run: ProfileRunner } | null} Null when the profile is skipped
53
+ */
54
+ function resolveProfileScan(params) {
55
+ const { profile, verbose = false } = params;
56
+ const idArgs = ["sts", "get-caller-identity"];
57
+ const groupArgs = [
58
+ "iam",
59
+ "get-group",
60
+ "--group-name",
61
+ ADMIN_GROUP_NAME
62
+ ];
63
+ /** @type {ProfileRunner} */
64
+ const directRun = (args, options = {}) => require_commands_aws_utils_exec_aws.runAws({
65
+ profile,
66
+ args,
67
+ expectJson: options.expectJson ?? true,
68
+ verbose
69
+ });
70
+ /** @type {ProfileRunner} */
71
+ const vaultRun = (args, options = {}) => require_commands_aws_utils_exec_aws.runAwsVault({
72
+ profile,
73
+ args,
74
+ duration: VAULT_DURATION,
75
+ expectJson: options.expectJson ?? true,
76
+ verbose
77
+ });
78
+ try {
79
+ const identity = directRun(idArgs);
80
+ const group = directRun(groupArgs);
81
+ return {
82
+ accountId: identity.Account,
83
+ arn: identity.Arn,
84
+ users: groupUserNames(group),
85
+ run: directRun
86
+ };
87
+ } catch (directError) {
88
+ try {
89
+ const identity = vaultRun(idArgs);
90
+ const group = vaultRun(groupArgs);
91
+ return {
92
+ accountId: identity.Account,
93
+ arn: identity.Arn,
94
+ users: groupUserNames(group),
95
+ run: vaultRun
96
+ };
97
+ } catch {
98
+ if (verbose) {
99
+ const reason = directError instanceof Error ? directError.message.split("\n")[0] ?? "" : String(directError);
100
+ console.log(chalk.default.dim(`skip ${profile} — ${reason}`));
101
+ }
102
+ return null;
103
+ }
104
+ }
105
+ }
106
+ //#endregion
107
+ exports.ADMIN_GROUP_NAME = ADMIN_GROUP_NAME;
108
+ exports.groupUserNames = groupUserNames;
109
+ exports.listVaultProfiles = listVaultProfiles;
110
+ exports.resolveAdminScanProfiles = resolveAdminScanProfiles;
111
+ exports.resolveProfileScan = resolveProfileScan;