clever-tools 4.4.0 → 4.5.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 (296) hide show
  1. package/bin/clever.js +208 -2128
  2. package/package.json +33 -25
  3. package/src/clever-client/auth-bridge.js +0 -9
  4. package/src/clever-client/drains.js +0 -17
  5. package/src/clever-client/operators.js +1 -1
  6. package/src/commands/README.md +65 -0
  7. package/src/commands/accesslogs/accesslogs.command.js +158 -0
  8. package/src/commands/accesslogs/accesslogs.docs.md +20 -0
  9. package/src/commands/{activity.js → activity/activity.command.js} +74 -44
  10. package/src/commands/activity/activity.docs.md +19 -0
  11. package/src/commands/addon/addon.args.js +14 -0
  12. package/src/commands/addon/addon.command.js +7 -0
  13. package/src/commands/addon/addon.create.command.js +236 -0
  14. package/src/commands/addon/addon.delete.command.js +32 -0
  15. package/src/commands/addon/addon.docs.md +156 -0
  16. package/src/commands/addon/addon.env.command.js +50 -0
  17. package/src/commands/addon/addon.list.command.js +55 -0
  18. package/src/commands/addon/addon.providers.command.js +45 -0
  19. package/src/commands/addon/addon.providers.show.command.js +99 -0
  20. package/src/commands/addon/addon.rename.command.js +24 -0
  21. package/src/commands/applications/applications.command.js +59 -0
  22. package/src/commands/applications/applications.docs.md +31 -0
  23. package/src/commands/applications/applications.list.command.js +100 -0
  24. package/src/commands/cancel-deploy/cancel-deploy.command.js +30 -0
  25. package/src/commands/cancel-deploy/cancel-deploy.docs.md +16 -0
  26. package/src/commands/config/config.args.js +10 -0
  27. package/src/commands/config/config.command.js +20 -0
  28. package/src/commands/config/config.docs.md +86 -0
  29. package/src/commands/config/config.get.command.js +21 -0
  30. package/src/commands/config/config.set.command.js +38 -0
  31. package/src/commands/config/config.update.command.js +88 -0
  32. package/src/commands/console/console.command.js +31 -0
  33. package/src/commands/console/console.docs.md +16 -0
  34. package/src/commands/create/create.command.js +173 -0
  35. package/src/commands/create/create.docs.md +27 -0
  36. package/src/commands/{curl.js → curl/curl.command.js} +10 -3
  37. package/src/commands/curl/curl.docs.md +9 -0
  38. package/src/commands/database/database.args.js +8 -0
  39. package/src/commands/database/database.backups.command.js +60 -0
  40. package/src/commands/database/database.backups.download.command.js +55 -0
  41. package/src/commands/database/database.command.js +10 -0
  42. package/src/commands/database/database.docs.md +52 -0
  43. package/src/commands/delete/delete.command.js +43 -0
  44. package/src/commands/delete/delete.docs.md +17 -0
  45. package/src/commands/deploy/deploy.command.js +166 -0
  46. package/src/commands/deploy/deploy.docs.md +22 -0
  47. package/src/commands/diag/diag.command.js +136 -0
  48. package/src/commands/diag/diag.docs.md +15 -0
  49. package/src/commands/domain/domain.add.command.js +25 -0
  50. package/src/commands/domain/domain.args.js +8 -0
  51. package/src/commands/domain/domain.command.js +38 -0
  52. package/src/commands/domain/domain.diag.command.js +204 -0
  53. package/src/commands/domain/domain.docs.md +143 -0
  54. package/src/commands/domain/domain.favourite.command.js +35 -0
  55. package/src/commands/domain/domain.favourite.set.command.js +24 -0
  56. package/src/commands/domain/domain.favourite.unset.command.js +23 -0
  57. package/src/commands/domain/domain.overview.command.js +157 -0
  58. package/src/commands/domain/domain.rm.command.js +25 -0
  59. package/src/commands/drain/drain.args.js +8 -0
  60. package/src/commands/drain/drain.command.js +56 -0
  61. package/src/commands/drain/drain.create.command.js +128 -0
  62. package/src/commands/drain/drain.disable.command.js +27 -0
  63. package/src/commands/drain/drain.docs.md +129 -0
  64. package/src/commands/drain/drain.enable.command.js +27 -0
  65. package/src/commands/drain/drain.get.command.js +38 -0
  66. package/src/commands/drain/drain.remove.command.js +26 -0
  67. package/src/commands/emails/emails.add.command.js +32 -0
  68. package/src/commands/emails/emails.args.js +8 -0
  69. package/src/commands/emails/emails.command.js +35 -0
  70. package/src/commands/emails/emails.docs.md +79 -0
  71. package/src/commands/emails/emails.open.command.js +15 -0
  72. package/src/commands/emails/emails.primary.command.js +29 -0
  73. package/src/commands/emails/emails.remove-all.command.js +54 -0
  74. package/src/commands/emails/emails.remove.command.js +25 -0
  75. package/src/commands/env/env.command.js +77 -0
  76. package/src/commands/env/env.docs.md +99 -0
  77. package/src/commands/env/env.import-vars.command.js +45 -0
  78. package/src/commands/env/env.import.command.js +29 -0
  79. package/src/commands/env/env.rm.command.js +25 -0
  80. package/src/commands/env/env.set.command.js +32 -0
  81. package/src/commands/features/features.args.js +9 -0
  82. package/src/commands/features/features.command.js +7 -0
  83. package/src/commands/features/features.disable.command.js +25 -0
  84. package/src/commands/features/features.docs.md +71 -0
  85. package/src/commands/features/features.enable.command.js +32 -0
  86. package/src/commands/features/features.info.command.js +27 -0
  87. package/src/commands/features/features.list.command.js +49 -0
  88. package/src/commands/global.args.js +45 -0
  89. package/src/commands/global.commands.js +461 -0
  90. package/src/commands/global.options.js +186 -0
  91. package/src/commands/help/help.command.js +9 -0
  92. package/src/commands/help/help.docs.md +9 -0
  93. package/src/commands/k8s/k8s.add-persistent-storage.command.js +39 -0
  94. package/src/commands/k8s/k8s.args.js +9 -0
  95. package/src/commands/k8s/k8s.command.js +12 -0
  96. package/src/commands/k8s/k8s.create.command.js +86 -0
  97. package/src/commands/k8s/k8s.delete.command.js +40 -0
  98. package/src/commands/k8s/k8s.docs.md +131 -0
  99. package/src/commands/k8s/k8s.get-kubeconfig.command.js +32 -0
  100. package/src/commands/k8s/k8s.get.command.js +43 -0
  101. package/src/commands/k8s/k8s.list.command.js +38 -0
  102. package/src/commands/keycloak/keycloak.command.js +17 -0
  103. package/src/commands/keycloak/keycloak.disable-ng.command.js +13 -0
  104. package/src/commands/keycloak/keycloak.docs.md +197 -0
  105. package/src/commands/keycloak/keycloak.enable-ng.command.js +13 -0
  106. package/src/commands/keycloak/keycloak.get.command.js +17 -0
  107. package/src/commands/keycloak/keycloak.open.command.js +13 -0
  108. package/src/commands/keycloak/keycloak.open.logs.command.js +13 -0
  109. package/src/commands/keycloak/keycloak.open.webui.command.js +13 -0
  110. package/src/commands/keycloak/keycloak.rebuild.command.js +13 -0
  111. package/src/commands/keycloak/keycloak.restart.command.js +13 -0
  112. package/src/commands/keycloak/keycloak.version.check.command.js +17 -0
  113. package/src/commands/keycloak/keycloak.version.command.js +17 -0
  114. package/src/commands/keycloak/keycloak.version.update.command.js +17 -0
  115. package/src/commands/kv/kv.command.js +99 -0
  116. package/src/commands/kv/kv.docs.md +27 -0
  117. package/src/commands/link/link.command.js +31 -0
  118. package/src/commands/link/link.docs.md +22 -0
  119. package/src/commands/{login.js → login/login.command.js} +44 -22
  120. package/src/commands/login/login.docs.md +16 -0
  121. package/src/commands/logout/logout.command.js +15 -0
  122. package/src/commands/logout/logout.docs.md +9 -0
  123. package/src/commands/logs/logs.command.js +81 -0
  124. package/src/commands/logs/logs.docs.md +22 -0
  125. package/src/commands/make-default/make-default.command.js +17 -0
  126. package/src/commands/make-default/make-default.docs.md +15 -0
  127. package/src/commands/matomo/matomo.command.js +17 -0
  128. package/src/commands/matomo/matomo.docs.md +109 -0
  129. package/src/commands/matomo/matomo.get.command.js +17 -0
  130. package/src/commands/matomo/matomo.open.command.js +13 -0
  131. package/src/commands/matomo/matomo.open.logs.command.js +13 -0
  132. package/src/commands/matomo/matomo.open.webui.command.js +13 -0
  133. package/src/commands/matomo/matomo.rebuild.command.js +13 -0
  134. package/src/commands/matomo/matomo.restart.command.js +13 -0
  135. package/src/commands/metabase/metabase.command.js +17 -0
  136. package/src/commands/metabase/metabase.docs.md +169 -0
  137. package/src/commands/metabase/metabase.get.command.js +17 -0
  138. package/src/commands/metabase/metabase.open.command.js +13 -0
  139. package/src/commands/metabase/metabase.open.logs.command.js +13 -0
  140. package/src/commands/metabase/metabase.open.webui.command.js +13 -0
  141. package/src/commands/metabase/metabase.rebuild.command.js +13 -0
  142. package/src/commands/metabase/metabase.restart.command.js +13 -0
  143. package/src/commands/metabase/metabase.version.check.command.js +17 -0
  144. package/src/commands/metabase/metabase.version.command.js +17 -0
  145. package/src/commands/metabase/metabase.version.update.command.js +17 -0
  146. package/src/commands/ng/ng.args.js +27 -0
  147. package/src/commands/ng/ng.command.js +45 -0
  148. package/src/commands/ng/ng.create.command.js +60 -0
  149. package/src/commands/ng/ng.create.external.command.js +44 -0
  150. package/src/commands/ng/ng.delete.command.js +22 -0
  151. package/src/commands/ng/ng.delete.external.command.js +25 -0
  152. package/src/commands/ng/ng.docs.md +214 -0
  153. package/src/commands/ng/ng.get-config.command.js +32 -0
  154. package/src/commands/ng/ng.get.command.js +22 -0
  155. package/src/commands/ng/ng.link.command.js +25 -0
  156. package/src/commands/ng/ng.options.js +9 -0
  157. package/src/commands/ng/ng.search.command.js +22 -0
  158. package/src/commands/ng/ng.unlink.command.js +25 -0
  159. package/src/commands/notify-email/notify-email.add.command.js +65 -0
  160. package/src/commands/notify-email/notify-email.command.js +61 -0
  161. package/src/commands/notify-email/notify-email.docs.md +60 -0
  162. package/src/commands/notify-email/notify-email.remove.command.js +24 -0
  163. package/src/commands/open/open.command.js +24 -0
  164. package/src/commands/open/open.docs.md +16 -0
  165. package/src/commands/otoroshi/otoroshi.command.js +17 -0
  166. package/src/commands/otoroshi/otoroshi.disable-ng.command.js +13 -0
  167. package/src/commands/otoroshi/otoroshi.docs.md +211 -0
  168. package/src/commands/otoroshi/otoroshi.enable-ng.command.js +13 -0
  169. package/src/commands/otoroshi/otoroshi.get-config.command.js +13 -0
  170. package/src/commands/otoroshi/otoroshi.get.command.js +17 -0
  171. package/src/commands/otoroshi/otoroshi.open.command.js +13 -0
  172. package/src/commands/otoroshi/otoroshi.open.logs.command.js +13 -0
  173. package/src/commands/otoroshi/otoroshi.open.webui.command.js +13 -0
  174. package/src/commands/otoroshi/otoroshi.rebuild.command.js +13 -0
  175. package/src/commands/otoroshi/otoroshi.restart.command.js +13 -0
  176. package/src/commands/otoroshi/otoroshi.version.check.command.js +17 -0
  177. package/src/commands/otoroshi/otoroshi.version.command.js +17 -0
  178. package/src/commands/otoroshi/otoroshi.version.update.command.js +17 -0
  179. package/src/commands/profile/profile.command.js +60 -0
  180. package/src/commands/profile/profile.docs.md +23 -0
  181. package/src/commands/profile/profile.open.command.js +12 -0
  182. package/src/commands/published-config/published-config.command.js +40 -0
  183. package/src/commands/published-config/published-config.docs.md +77 -0
  184. package/src/commands/published-config/published-config.import.command.js +29 -0
  185. package/src/commands/published-config/published-config.rm.command.js +27 -0
  186. package/src/commands/published-config/published-config.set.command.js +34 -0
  187. package/src/commands/restart/restart.command.js +77 -0
  188. package/src/commands/restart/restart.docs.md +21 -0
  189. package/src/commands/scale/scale.command.js +121 -0
  190. package/src/commands/scale/scale.docs.md +23 -0
  191. package/src/commands/service/service.command.js +91 -0
  192. package/src/commands/service/service.docs.md +104 -0
  193. package/src/commands/service/service.link-addon.command.js +24 -0
  194. package/src/commands/service/service.link-app.command.js +23 -0
  195. package/src/commands/service/service.unlink-addon.command.js +24 -0
  196. package/src/commands/service/service.unlink-app.command.js +23 -0
  197. package/src/commands/ssh/ssh.command.js +40 -0
  198. package/src/commands/ssh/ssh.docs.md +17 -0
  199. package/src/commands/ssh-keys/ssh-keys.add.command.js +41 -0
  200. package/src/commands/ssh-keys/ssh-keys.args.js +8 -0
  201. package/src/commands/ssh-keys/ssh-keys.command.js +50 -0
  202. package/src/commands/ssh-keys/ssh-keys.docs.md +66 -0
  203. package/src/commands/ssh-keys/ssh-keys.open.command.js +12 -0
  204. package/src/commands/ssh-keys/ssh-keys.remove-all.command.js +54 -0
  205. package/src/commands/ssh-keys/ssh-keys.remove.command.js +26 -0
  206. package/src/commands/status/status.command.js +122 -0
  207. package/src/commands/status/status.docs.md +17 -0
  208. package/src/commands/stop/stop.command.js +23 -0
  209. package/src/commands/stop/stop.docs.md +16 -0
  210. package/src/commands/tcp-redirs/tcp-redirs.add.command.js +24 -0
  211. package/src/commands/tcp-redirs/tcp-redirs.command.js +41 -0
  212. package/src/commands/tcp-redirs/tcp-redirs.docs.md +71 -0
  213. package/src/commands/tcp-redirs/tcp-redirs.list-namespaces.command.js +48 -0
  214. package/src/commands/tcp-redirs/tcp-redirs.options.js +11 -0
  215. package/src/commands/tcp-redirs/tcp-redirs.remove.command.js +34 -0
  216. package/src/commands/tokens/tokens.command.js +43 -0
  217. package/src/commands/tokens/tokens.create.command.js +108 -0
  218. package/src/commands/tokens/tokens.docs.md +50 -0
  219. package/src/commands/tokens/tokens.revoke.command.js +25 -0
  220. package/src/commands/unlink/unlink.command.js +21 -0
  221. package/src/commands/unlink/unlink.docs.md +15 -0
  222. package/src/commands/version/version.command.js +13 -0
  223. package/src/commands/version/version.docs.md +9 -0
  224. package/src/commands/webhooks/webhooks.add.command.js +51 -0
  225. package/src/commands/webhooks/webhooks.command.js +57 -0
  226. package/src/commands/webhooks/webhooks.docs.md +61 -0
  227. package/src/commands/webhooks/webhooks.remove.command.js +24 -0
  228. package/src/lib/cliparse-patched.js +192 -0
  229. package/src/lib/define-argument.js +7 -0
  230. package/src/lib/define-argument.types.d.ts +23 -0
  231. package/src/lib/define-command.js +7 -0
  232. package/src/lib/define-command.types.d.ts +85 -0
  233. package/src/lib/define-common.types.d.ts +18 -0
  234. package/src/lib/define-option.js +7 -0
  235. package/src/lib/define-option.types.d.ts +29 -0
  236. package/src/lib/get-command-info.js +86 -0
  237. package/src/lib/get-command-info.types.d.ts +42 -0
  238. package/src/lib/k8s.js +1 -1
  239. package/src/lib/zod-utils.js +66 -0
  240. package/src/models/addon.js +2 -19
  241. package/src/models/app_configuration.js +0 -30
  242. package/src/models/application.js +4 -5
  243. package/src/models/application_configuration.js +5 -23
  244. package/src/models/domain.js +34 -2
  245. package/src/models/exit-strategy-option.js +0 -9
  246. package/src/models/git.js +1 -4
  247. package/src/models/log-v4.js +15 -4
  248. package/src/models/log.js +5 -0
  249. package/src/models/namespaces.js +1 -2
  250. package/src/models/notification.js +1 -7
  251. package/src/parsers.js +33 -111
  252. package/src/command-options.js +0 -55
  253. package/src/command-promise-handler.js +0 -16
  254. package/src/commands/accesslogs.js +0 -138
  255. package/src/commands/addon.js +0 -391
  256. package/src/commands/applications.js +0 -123
  257. package/src/commands/cancel-deploy.js +0 -19
  258. package/src/commands/config.js +0 -47
  259. package/src/commands/console.js +0 -20
  260. package/src/commands/create.js +0 -129
  261. package/src/commands/database.js +0 -73
  262. package/src/commands/delete.js +0 -24
  263. package/src/commands/deploy.js +0 -133
  264. package/src/commands/diag.js +0 -126
  265. package/src/commands/domain.js +0 -445
  266. package/src/commands/drain.js +0 -164
  267. package/src/commands/emails.js +0 -156
  268. package/src/commands/env.js +0 -124
  269. package/src/commands/features.js +0 -87
  270. package/src/commands/k8s.js +0 -193
  271. package/src/commands/keycloak.js +0 -138
  272. package/src/commands/kv.js +0 -93
  273. package/src/commands/link.js +0 -20
  274. package/src/commands/logout.js +0 -8
  275. package/src/commands/logs.js +0 -45
  276. package/src/commands/makeDefault.js +0 -11
  277. package/src/commands/matomo.js +0 -85
  278. package/src/commands/metabase.js +0 -112
  279. package/src/commands/ng.js +0 -202
  280. package/src/commands/notify-email.js +0 -99
  281. package/src/commands/open.js +0 -13
  282. package/src/commands/otoroshi.js +0 -150
  283. package/src/commands/profile.js +0 -55
  284. package/src/commands/published-config.js +0 -70
  285. package/src/commands/restart.js +0 -52
  286. package/src/commands/scale.js +0 -66
  287. package/src/commands/service.js +0 -105
  288. package/src/commands/ssh-keys.js +0 -144
  289. package/src/commands/ssh.js +0 -20
  290. package/src/commands/status.js +0 -115
  291. package/src/commands/stop.js +0 -12
  292. package/src/commands/tcp-redirs.js +0 -80
  293. package/src/commands/tokens.js +0 -144
  294. package/src/commands/unlink.js +0 -14
  295. package/src/commands/version.js +0 -6
  296. package/src/commands/webhooks.js +0 -74
@@ -0,0 +1,157 @@
1
+ import { getAllDomains } from '@clevercloud/client/esm/api/v2/application.js';
2
+ import { getSummary } from '@clevercloud/client/esm/api/v2/user.js';
3
+ import _ from 'lodash';
4
+ import { parse as parseDomain } from 'tldts';
5
+ import { z } from 'zod';
6
+ import { defineCommand } from '../../lib/define-command.js';
7
+ import { defineOption } from '../../lib/define-option.js';
8
+ import { styleText } from '../../lib/style-text.js';
9
+ import { Logger } from '../../logger.js';
10
+ import { sendToApi } from '../../models/send-to-api.js';
11
+ import { humanJsonOutputFormatOption } from '../global.options.js';
12
+
13
+ function recursiveSort(obj) {
14
+ if (typeof obj === 'object' && obj.appId != null) {
15
+ return obj;
16
+ }
17
+
18
+ const sortedObj = {};
19
+ Object.keys(obj)
20
+ .sort((a, b) => {
21
+ // if the domain contains a wildcard, we want it to be the first of subdomains
22
+ const aWithReplacedWildcard = a.replace(/^\*/, 'a');
23
+ const bWithReplacedWildcard = b.replace(/^\*/, 'a');
24
+ return aWithReplacedWildcard.localeCompare(bWithReplacedWildcard);
25
+ })
26
+ .forEach((key) => {
27
+ sortedObj[key] = recursiveSort(obj[key]);
28
+ });
29
+
30
+ return sortedObj;
31
+ }
32
+
33
+ function recursiveDisplay(obj, indentLevel = 0) {
34
+ if (typeof obj === 'object' && obj.appId != null) {
35
+ Logger.printlnWithIndent(`${obj.ownerName} | ${obj.appName} (${obj.appVariantSlug})`, indentLevel);
36
+ Logger.printlnWithIndent(styleText('blue', obj.appConsoleUrl), indentLevel);
37
+ return;
38
+ }
39
+
40
+ for (const [propertyPath, subObj] of Object.entries(obj)) {
41
+ if (propertyPath !== '/') {
42
+ Logger.println('');
43
+ Logger.printlnWithIndent(styleText('yellow', propertyPath), indentLevel);
44
+ recursiveDisplay(subObj, indentLevel + 2);
45
+ } else {
46
+ recursiveDisplay(subObj, indentLevel);
47
+ }
48
+ }
49
+ }
50
+
51
+ export const domainOverviewCommand = defineCommand({
52
+ description: 'Get an overview of all your domains (all orgas, all apps)',
53
+ since: '3.9.0',
54
+ options: {
55
+ filter: defineOption({
56
+ name: 'filter',
57
+ schema: z.string().default(''),
58
+ description: 'Get only domains containing the provided text',
59
+ placeholder: 'text',
60
+ }),
61
+ format: humanJsonOutputFormatOption,
62
+ },
63
+ args: [],
64
+ async handler(options) {
65
+ const { format, filter } = options;
66
+
67
+ const summary = await getSummary().then(sendToApi);
68
+ const consoleUrl = summary.user.partnerConsoleUrl;
69
+
70
+ const applications = [
71
+ ...summary.user.applications.map((app) => {
72
+ return { ownerName: summary.user.name, ownerId: summary.user.id, ...app };
73
+ }),
74
+ ...summary.organisations.flatMap((o) => {
75
+ return o.applications.map((app) => {
76
+ return { ownerName: o.name, ownerId: o.id, ...app };
77
+ });
78
+ }),
79
+ ];
80
+
81
+ const applicationsWithDomains = await Promise.all(
82
+ applications.map(async (app) => {
83
+ const domains = await getAllDomains({ id: app.ownerId, appId: app.id })
84
+ .then(sendToApi)
85
+ .catch((error) => {
86
+ // if the user cannot access application domains, we simply act as if there were no domains
87
+ if (error?.response?.status === 403) {
88
+ Logger.printErrorLine(`You cannot list domains for application ${app.name} (${app.id})`);
89
+ return [];
90
+ }
91
+ throw error;
92
+ });
93
+ return { app, domains };
94
+ }),
95
+ );
96
+
97
+ const applicationsWithParsedDomain = applicationsWithDomains.flatMap(({ app, domains }) => {
98
+ return domains
99
+ .filter((domain) => filter == null || domain.fqdn.includes(filter))
100
+ .map((domain) => {
101
+ // `validateHostname` is set to `false` so that wildcard domains may be parsed correctly
102
+ const parsedDomain = parseDomain(domain.fqdn, { validateHostname: false });
103
+ const pathname = new URL('https://' + domain.fqdn).pathname;
104
+ const subdomains = parsedDomain.subdomain !== '' ? parsedDomain.subdomain.split('.') : [];
105
+
106
+ // We're trying to create a propertyPath for lodash to create a tree structure object,
107
+ // the propertyPath for `aaa.bbb.ccc.example.com/the-path` would be:
108
+ // ["example.com", "example.com.ccc", "example.com.ccc.bbb", "example.com.ccc.bbb.aaa", "/path-aaa"]",
109
+
110
+ const sortSegments = [parsedDomain.domain, ...subdomains.reverse()];
111
+ const propertyPath = sortSegments.map((item, i, all) => {
112
+ return all
113
+ .slice(0, i + 1)
114
+ .reverse()
115
+ .join('.');
116
+ });
117
+ propertyPath.push(pathname);
118
+
119
+ return {
120
+ ownerId: app.ownerId,
121
+ ownerName: app.ownerName,
122
+ appId: app.id,
123
+ appName: app.name,
124
+ appConsoleUrl: `${consoleUrl}/goto/${app.id}`,
125
+ appVariantSlug: app.variantSlug,
126
+ domain: domain.fqdn,
127
+ propetyPath: propertyPath,
128
+ };
129
+ });
130
+ });
131
+
132
+ const applicationsWithParsedDomainAsTree = {};
133
+ for (const { propetyPath, ...appWithDomain } of applicationsWithParsedDomain) {
134
+ _.set(applicationsWithParsedDomainAsTree, propetyPath, appWithDomain);
135
+ }
136
+
137
+ const applicationsWithParsedDomainAsSortedTree = recursiveSort(applicationsWithParsedDomainAsTree);
138
+
139
+ switch (format) {
140
+ case 'json':
141
+ Logger.printJson(applicationsWithParsedDomainAsSortedTree);
142
+ break;
143
+ case 'human':
144
+ default:
145
+ if (Object.keys(applicationsWithParsedDomainAsSortedTree).length === 0) {
146
+ if (filter?.length > 0) {
147
+ Logger.println(`No matches for filter "${filter}"`);
148
+ } else {
149
+ Logger.println('No domains');
150
+ }
151
+ } else {
152
+ recursiveDisplay(applicationsWithParsedDomainAsSortedTree);
153
+ }
154
+ break;
155
+ }
156
+ },
157
+ });
@@ -0,0 +1,25 @@
1
+ import { removeDomain } from '@clevercloud/client/esm/api/v2/application.js';
2
+ import { defineCommand } from '../../lib/define-command.js';
3
+ import { Logger } from '../../logger.js';
4
+ import * as Application from '../../models/application.js';
5
+ import { sendToApi } from '../../models/send-to-api.js';
6
+ import { aliasOption, appIdOrNameOption } from '../global.options.js';
7
+ import { fqdnArg } from './domain.args.js';
8
+
9
+ export const domainRmCommand = defineCommand({
10
+ description: 'Remove a domain name from an application',
11
+ since: '0.2.0',
12
+ options: {
13
+ alias: aliasOption,
14
+ app: appIdOrNameOption,
15
+ },
16
+ args: [fqdnArg],
17
+ async handler(options, fqdn) {
18
+ const { alias, app: appIdOrName } = options;
19
+ const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
20
+ const encodedFqdn = encodeURIComponent(fqdn);
21
+
22
+ await removeDomain({ id: ownerId, appId, domain: encodedFqdn }).then(sendToApi);
23
+ Logger.println('Your domain has been successfully removed');
24
+ },
25
+ });
@@ -0,0 +1,8 @@
1
+ import { z } from 'zod';
2
+ import { defineArgument } from '../../lib/define-argument.js';
3
+
4
+ export const drainIdArg = defineArgument({
5
+ schema: z.string(),
6
+ description: 'Drain ID',
7
+ placeholder: 'drain-id',
8
+ });
@@ -0,0 +1,56 @@
1
+ import { getDrains } from '../../clever-client/drains.js';
2
+ import { defineCommand } from '../../lib/define-command.js';
3
+ import { Logger } from '../../logger.js';
4
+ import * as Application from '../../models/application.js';
5
+ import { formatDrain } from '../../models/drain.js';
6
+ import { sendToApi } from '../../models/send-to-api.js';
7
+ import { aliasOption, appIdOrNameOption, humanJsonOutputFormatOption } from '../global.options.js';
8
+
9
+ export const drainCommand = defineCommand({
10
+ description: 'Manage drains',
11
+ since: '0.9.0',
12
+ options: {
13
+ alias: aliasOption,
14
+ app: appIdOrNameOption,
15
+ format: humanJsonOutputFormatOption,
16
+ },
17
+ args: [],
18
+ async handler(options) {
19
+ const { alias, app: appIdOrName, format } = options;
20
+
21
+ const { ownerId, appId: applicationId } = await Application.resolveId(appIdOrName, alias);
22
+
23
+ const drains = await getDrains({ ownerId, applicationId }).then(sendToApi);
24
+
25
+ switch (format) {
26
+ case 'json': {
27
+ Logger.printJson(drains);
28
+ break;
29
+ }
30
+ case 'human':
31
+ default: {
32
+ if (drains.length === 0) {
33
+ Logger.println(`There are no drains for ${applicationId}`);
34
+ return;
35
+ }
36
+
37
+ if (drains.length === 1) {
38
+ const formattedDrain = formatDrain(drains[0]);
39
+ console.table(formattedDrain);
40
+ return;
41
+ }
42
+
43
+ const formattedDrains = drains.map((drain) => {
44
+ return {
45
+ ID: drain.id,
46
+ Status: drain.status.status,
47
+ 'Execution status': drain.execution.status,
48
+ URL: drain.recipient.url,
49
+ };
50
+ });
51
+
52
+ console.table(formattedDrains);
53
+ }
54
+ }
55
+ },
56
+ });
@@ -0,0 +1,128 @@
1
+ import { z } from 'zod';
2
+ import { createDrain } from '../../clever-client/drains.js';
3
+ import { defineArgument } from '../../lib/define-argument.js';
4
+ import { defineCommand } from '../../lib/define-command.js';
5
+ import { defineOption } from '../../lib/define-option.js';
6
+ import { styleText } from '../../lib/style-text.js';
7
+ import { Logger } from '../../logger.js';
8
+ import * as Application from '../../models/application.js';
9
+ import { DRAIN_TYPE_CLI_CODES, DRAIN_TYPES } from '../../models/drain.js';
10
+ import { sendToApi } from '../../models/send-to-api.js';
11
+ import { aliasOption, appIdOrNameOption } from '../global.options.js';
12
+
13
+ export const drainCreateCommand = defineCommand({
14
+ description: 'Create a drain',
15
+ since: '0.9.0',
16
+ options: {
17
+ username: defineOption({
18
+ name: 'username',
19
+ schema: z.string().optional(),
20
+ description: 'Basic auth username (for elasticsearch or raw-http)',
21
+ aliases: ['u'],
22
+ placeholder: 'username',
23
+ }),
24
+ password: defineOption({
25
+ name: 'password',
26
+ schema: z.string().optional(),
27
+ description: 'Basic auth password (for elasticsearch or raw-http)',
28
+ aliases: ['p'],
29
+ placeholder: 'password',
30
+ }),
31
+ apiKey: defineOption({
32
+ name: 'api-key',
33
+ schema: z.string().optional(),
34
+ description: 'API key (for newrelic)',
35
+ aliases: ['k'],
36
+ placeholder: 'api-key',
37
+ }),
38
+ indexPrefix: defineOption({
39
+ name: 'index-prefix',
40
+ schema: z.string().optional(),
41
+ description: 'Optional index prefix (for elasticsearch), `logstash` value is used if not set',
42
+ aliases: ['i'],
43
+ placeholder: 'index-prefix',
44
+ }),
45
+ rfc5424StructuredDataParameters: defineOption({
46
+ name: 'sd-params',
47
+ schema: z.string().optional(),
48
+ description: 'RFC5424 structured data parameters (for ovh-tcp), e.g.: `X-OVH-TOKEN=\\\"REDACTED\\\"`',
49
+ aliases: ['s'],
50
+ placeholder: 'sd-params',
51
+ }),
52
+ alias: aliasOption,
53
+ app: appIdOrNameOption,
54
+ },
55
+ args: [
56
+ defineArgument({
57
+ schema: z.string(),
58
+ description: 'No description available',
59
+ placeholder: 'drain-type',
60
+ complete: DRAIN_TYPE_CLI_CODES,
61
+ }),
62
+ defineArgument({
63
+ schema: z.string(),
64
+ description: 'Drain URL',
65
+ placeholder: 'drain-url',
66
+ }),
67
+ ],
68
+ async handler(options, drainTypeCliCode, url) {
69
+ const { alias, app: appIdOrName } = options;
70
+ const { username, password, apiKey, indexPrefix, rfc5424StructuredDataParameters } = options;
71
+
72
+ const drainType = Object.values(DRAIN_TYPES).find((drainType) => drainType.cliCode === drainTypeCliCode);
73
+ if (!drainType) {
74
+ throw new Error(`Invalid drain type. Supported types are: ${DRAIN_TYPE_CLI_CODES.join(', ')}`);
75
+ }
76
+
77
+ const { ownerId, appId: applicationId } = await Application.resolveId(appIdOrName, alias);
78
+
79
+ const body = {
80
+ kind: 'LOG',
81
+ recipient: {
82
+ type: drainType.apiCode,
83
+ url,
84
+ },
85
+ };
86
+
87
+ if (drainTypeCliCode === DRAIN_TYPES.ELASTICSEARCH.cliCode) {
88
+ if (!indexPrefix) {
89
+ throw new Error(
90
+ `${DRAIN_TYPES.ELASTICSEARCH.cliCode} drains require an index prefix (--index-prefix) to be set`,
91
+ );
92
+ }
93
+ if (!url.endsWith('/_bulk')) {
94
+ throw new Error(`${DRAIN_TYPES.ELASTICSEARCH.cliCode} drain URL must end with '/_bulk'`);
95
+ }
96
+ body.recipient.index = indexPrefix;
97
+ }
98
+
99
+ if (drainTypeCliCode === DRAIN_TYPES.ELASTICSEARCH.cliCode || drainTypeCliCode === DRAIN_TYPES.RAW_HTTP.cliCode) {
100
+ if (username) {
101
+ body.recipient.username = username;
102
+ }
103
+ if (password) {
104
+ body.recipient.password = password;
105
+ }
106
+ }
107
+
108
+ if (drainTypeCliCode === DRAIN_TYPES.NEWRELIC.cliCode) {
109
+ if (!apiKey) {
110
+ throw new Error(`${DRAIN_TYPES.NEWRELIC.cliCode} drains require an API key (--api-key) to be set`);
111
+ }
112
+ body.recipient.apiKey = apiKey;
113
+ }
114
+
115
+ if (
116
+ drainTypeCliCode === DRAIN_TYPES.OVH_TCP.cliCode ||
117
+ drainTypeCliCode === DRAIN_TYPES.SYSLOG_TCP.cliCode ||
118
+ drainTypeCliCode === DRAIN_TYPES.SYSLOG_UDP.cliCode
119
+ ) {
120
+ if (rfc5424StructuredDataParameters) {
121
+ body.recipient.rfc5424StructuredDataParameters = rfc5424StructuredDataParameters;
122
+ }
123
+ }
124
+
125
+ const drain = await createDrain({ ownerId, applicationId, body }).then(sendToApi);
126
+ Logger.printSuccess(`Drain ${styleText(['bold', 'green'], drain.id)} has been successfully created and enabled!`);
127
+ },
128
+ });
@@ -0,0 +1,27 @@
1
+ import { disableDrain } from '../../clever-client/drains.js';
2
+ import { defineCommand } from '../../lib/define-command.js';
3
+ import { styleText } from '../../lib/style-text.js';
4
+ import { Logger } from '../../logger.js';
5
+ import * as Application from '../../models/application.js';
6
+ import { sendToApi } from '../../models/send-to-api.js';
7
+ import { aliasOption, appIdOrNameOption } from '../global.options.js';
8
+ import { drainIdArg } from './drain.args.js';
9
+
10
+ export const drainDisableCommand = defineCommand({
11
+ description: 'Disable a drain',
12
+ since: '0.9.0',
13
+ options: {
14
+ alias: aliasOption,
15
+ app: appIdOrNameOption,
16
+ },
17
+ args: [drainIdArg],
18
+ async handler(options, drainId) {
19
+ const { alias, app: appIdOrName } = options;
20
+
21
+ const { ownerId, appId: applicationId } = await Application.resolveId(appIdOrName, alias);
22
+
23
+ await disableDrain({ ownerId, applicationId, drainId }).then(sendToApi);
24
+
25
+ Logger.printSuccess(`Drain ${styleText(['bold', 'green'], drainId)} has been successfully disabled!`);
26
+ },
27
+ });
@@ -0,0 +1,129 @@
1
+ # 📖 `clever drain` command reference
2
+
3
+ ## ➡️ `clever drain` <kbd>Since 0.9.0</kbd>
4
+
5
+ Manage drains
6
+
7
+ ```bash
8
+ clever drain [options]
9
+ ```
10
+
11
+ ### ⚙️ Options
12
+
13
+ |Name|Description|
14
+ |---|---|
15
+ |`-a`, `--alias` `<alias>`|Short name for the application|
16
+ |`--app` `<app-id\|app-name>`|Application to manage by its ID (or name, if unambiguous)|
17
+ |`-F`, `--format` `<format>`|Output format (human, json) (default: human)|
18
+
19
+ ## ➡️ `clever drain create` <kbd>Since 0.9.0</kbd>
20
+
21
+ Create a drain
22
+
23
+ ```bash
24
+ clever drain create <drain-type> <drain-url> [options]
25
+ ```
26
+
27
+ ### 📥 Arguments
28
+
29
+ |Name|Description|
30
+ |---|---|
31
+ |`drain-type`|No description available|
32
+ |`drain-url`|Drain URL|
33
+
34
+ ### ⚙️ Options
35
+
36
+ |Name|Description|
37
+ |---|---|
38
+ |`-a`, `--alias` `<alias>`|Short name for the application|
39
+ |`-k`, `--api-key` `<api-key>`|API key (for newrelic)|
40
+ |`--app` `<app-id\|app-name>`|Application to manage by its ID (or name, if unambiguous)|
41
+ |`-i`, `--index-prefix` `<index-prefix>`|Optional index prefix (for elasticsearch), `logstash` value is used if not set|
42
+ |`-p`, `--password` `<password>`|Basic auth password (for elasticsearch or raw-http)|
43
+ |`-s`, `--sd-params` `<sd-params>`|RFC5424 structured data parameters (for ovh-tcp), e.g.: `X-OVH-TOKEN=\"REDACTED\"`|
44
+ |`-u`, `--username` `<username>`|Basic auth username (for elasticsearch or raw-http)|
45
+
46
+ ## ➡️ `clever drain disable` <kbd>Since 0.9.0</kbd>
47
+
48
+ Disable a drain
49
+
50
+ ```bash
51
+ clever drain disable <drain-id> [options]
52
+ ```
53
+
54
+ ### 📥 Arguments
55
+
56
+ |Name|Description|
57
+ |---|---|
58
+ |`drain-id`|Drain ID|
59
+
60
+ ### ⚙️ Options
61
+
62
+ |Name|Description|
63
+ |---|---|
64
+ |`-a`, `--alias` `<alias>`|Short name for the application|
65
+ |`--app` `<app-id\|app-name>`|Application to manage by its ID (or name, if unambiguous)|
66
+
67
+ ## ➡️ `clever drain enable` <kbd>Since 0.9.0</kbd>
68
+
69
+ Enable a drain
70
+
71
+ ```bash
72
+ clever drain enable <drain-id> [options]
73
+ ```
74
+
75
+ ### 📥 Arguments
76
+
77
+ |Name|Description|
78
+ |---|---|
79
+ |`drain-id`|Drain ID|
80
+
81
+ ### ⚙️ Options
82
+
83
+ |Name|Description|
84
+ |---|---|
85
+ |`-a`, `--alias` `<alias>`|Short name for the application|
86
+ |`--app` `<app-id\|app-name>`|Application to manage by its ID (or name, if unambiguous)|
87
+
88
+ ## ➡️ `clever drain get` <kbd>Since 0.9.0</kbd>
89
+
90
+ Get drain info
91
+
92
+ ```bash
93
+ clever drain get <drain-id> [options]
94
+ ```
95
+
96
+ ### 📥 Arguments
97
+
98
+ |Name|Description|
99
+ |---|---|
100
+ |`drain-id`|Drain ID|
101
+
102
+ ### ⚙️ Options
103
+
104
+ |Name|Description|
105
+ |---|---|
106
+ |`-a`, `--alias` `<alias>`|Short name for the application|
107
+ |`--app` `<app-id\|app-name>`|Application to manage by its ID (or name, if unambiguous)|
108
+ |`-F`, `--format` `<format>`|Output format (human, json) (default: human)|
109
+
110
+ ## ➡️ `clever drain remove` <kbd>Since 0.9.0</kbd>
111
+
112
+ Remove a drain
113
+
114
+ ```bash
115
+ clever drain remove <drain-id> [options]
116
+ ```
117
+
118
+ ### 📥 Arguments
119
+
120
+ |Name|Description|
121
+ |---|---|
122
+ |`drain-id`|Drain ID|
123
+
124
+ ### ⚙️ Options
125
+
126
+ |Name|Description|
127
+ |---|---|
128
+ |`-a`, `--alias` `<alias>`|Short name for the application|
129
+ |`--app` `<app-id\|app-name>`|Application to manage by its ID (or name, if unambiguous)|
@@ -0,0 +1,27 @@
1
+ import { enableDrain } from '../../clever-client/drains.js';
2
+ import { defineCommand } from '../../lib/define-command.js';
3
+ import { styleText } from '../../lib/style-text.js';
4
+ import { Logger } from '../../logger.js';
5
+ import * as Application from '../../models/application.js';
6
+ import { sendToApi } from '../../models/send-to-api.js';
7
+ import { aliasOption, appIdOrNameOption } from '../global.options.js';
8
+ import { drainIdArg } from './drain.args.js';
9
+
10
+ export const drainEnableCommand = defineCommand({
11
+ description: 'Enable a drain',
12
+ since: '0.9.0',
13
+ options: {
14
+ alias: aliasOption,
15
+ app: appIdOrNameOption,
16
+ },
17
+ args: [drainIdArg],
18
+ async handler(options, drainId) {
19
+ const { alias, app: appIdOrName } = options;
20
+
21
+ const { ownerId, appId: applicationId } = await Application.resolveId(appIdOrName, alias);
22
+
23
+ await enableDrain({ ownerId, applicationId, drainId }).then(sendToApi);
24
+
25
+ Logger.printSuccess(`Drain ${styleText(['bold', 'green'], drainId)} has been successfully enabled!`);
26
+ },
27
+ });
@@ -0,0 +1,38 @@
1
+ import { getDrain } from '../../clever-client/drains.js';
2
+ import { defineCommand } from '../../lib/define-command.js';
3
+ import { Logger } from '../../logger.js';
4
+ import * as Application from '../../models/application.js';
5
+ import { formatDrain } from '../../models/drain.js';
6
+ import { sendToApi } from '../../models/send-to-api.js';
7
+ import { aliasOption, appIdOrNameOption, humanJsonOutputFormatOption } from '../global.options.js';
8
+ import { drainIdArg } from './drain.args.js';
9
+
10
+ export const drainGetCommand = defineCommand({
11
+ description: 'Get drain info',
12
+ since: '0.9.0',
13
+ options: {
14
+ alias: aliasOption,
15
+ app: appIdOrNameOption,
16
+ format: humanJsonOutputFormatOption,
17
+ },
18
+ args: [drainIdArg],
19
+ async handler(options, drainId) {
20
+ const { alias, app: appIdOrName, format } = options;
21
+
22
+ const { ownerId, appId: applicationId } = await Application.resolveId(appIdOrName, alias);
23
+
24
+ const drain = await getDrain({ ownerId, applicationId, drainId }).then(sendToApi);
25
+
26
+ switch (format) {
27
+ case 'json': {
28
+ Logger.printJson(drain);
29
+ break;
30
+ }
31
+ case 'human':
32
+ default: {
33
+ const formattedDrain = formatDrain(drain);
34
+ console.table(formattedDrain);
35
+ }
36
+ }
37
+ },
38
+ });
@@ -0,0 +1,26 @@
1
+ import { deleteDrain } from '../../clever-client/drains.js';
2
+ import { defineCommand } from '../../lib/define-command.js';
3
+ import { styleText } from '../../lib/style-text.js';
4
+ import { Logger } from '../../logger.js';
5
+ import * as Application from '../../models/application.js';
6
+ import { sendToApi } from '../../models/send-to-api.js';
7
+ import { aliasOption, appIdOrNameOption } from '../global.options.js';
8
+ import { drainIdArg } from './drain.args.js';
9
+
10
+ export const drainRemoveCommand = defineCommand({
11
+ description: 'Remove a drain',
12
+ since: '0.9.0',
13
+ options: {
14
+ alias: aliasOption,
15
+ app: appIdOrNameOption,
16
+ },
17
+ args: [drainIdArg],
18
+ async handler(options, drainId) {
19
+ const { alias, app: appIdOrName } = options;
20
+
21
+ const { ownerId, appId: applicationId } = await Application.resolveId(appIdOrName, alias);
22
+
23
+ await deleteDrain({ ownerId, applicationId, drainId }).then(sendToApi);
24
+ Logger.printSuccess(`Drain ${styleText(['bold', 'green'], drainId)} has been successfully removed!`);
25
+ },
26
+ });
@@ -0,0 +1,32 @@
1
+ import { todo_addEmailAddress as addEmailAddress } from '@clevercloud/client/esm/api/v2/user.js';
2
+ import { defineCommand } from '../../lib/define-command.js';
3
+ import { Logger } from '../../logger.js';
4
+ import { sendToApi } from '../../models/send-to-api.js';
5
+ import { emailArg } from './emails.args.js';
6
+
7
+ export const emailsAddCommand = defineCommand({
8
+ description: 'Add a new secondary email address to the current user',
9
+ since: '3.13.0',
10
+ options: {},
11
+ args: [emailArg],
12
+ async handler(_options, secondaryAddress) {
13
+ const secondaryAddressEncoded = encodeURIComponent(secondaryAddress);
14
+ try {
15
+ await addEmailAddress({ email: secondaryAddressEncoded }).then(sendToApi);
16
+ Logger.printSuccess(
17
+ `The server sent a confirmation email to ${secondaryAddress} to validate your secondary address`,
18
+ );
19
+ } catch (e) {
20
+ switch (e?.responseBody?.id) {
21
+ case 101:
22
+ throw new Error('This address already belongs to your account');
23
+ case 550:
24
+ throw new Error('The format of this address is invalid');
25
+ case 1004:
26
+ throw new Error('This address belongs to another account');
27
+ default:
28
+ throw e;
29
+ }
30
+ }
31
+ },
32
+ });
@@ -0,0 +1,8 @@
1
+ import { z } from 'zod';
2
+ import { defineArgument } from '../../lib/define-argument.js';
3
+
4
+ export const emailArg = defineArgument({
5
+ schema: z.string().email(),
6
+ description: 'Email address',
7
+ placeholder: 'email',
8
+ });