clever-tools 4.4.1 → 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 (291) hide show
  1. package/bin/clever.js +208 -2125
  2. package/package.json +33 -25
  3. package/src/commands/README.md +65 -0
  4. package/src/commands/accesslogs/accesslogs.command.js +158 -0
  5. package/src/commands/accesslogs/accesslogs.docs.md +20 -0
  6. package/src/commands/{activity.js → activity/activity.command.js} +74 -44
  7. package/src/commands/activity/activity.docs.md +19 -0
  8. package/src/commands/addon/addon.args.js +14 -0
  9. package/src/commands/addon/addon.command.js +7 -0
  10. package/src/commands/addon/addon.create.command.js +236 -0
  11. package/src/commands/addon/addon.delete.command.js +32 -0
  12. package/src/commands/addon/addon.docs.md +156 -0
  13. package/src/commands/addon/addon.env.command.js +50 -0
  14. package/src/commands/addon/addon.list.command.js +55 -0
  15. package/src/commands/addon/addon.providers.command.js +45 -0
  16. package/src/commands/addon/addon.providers.show.command.js +99 -0
  17. package/src/commands/addon/addon.rename.command.js +24 -0
  18. package/src/commands/applications/applications.command.js +59 -0
  19. package/src/commands/applications/applications.docs.md +31 -0
  20. package/src/commands/applications/applications.list.command.js +100 -0
  21. package/src/commands/cancel-deploy/cancel-deploy.command.js +30 -0
  22. package/src/commands/cancel-deploy/cancel-deploy.docs.md +16 -0
  23. package/src/commands/config/config.args.js +10 -0
  24. package/src/commands/config/config.command.js +20 -0
  25. package/src/commands/config/config.docs.md +86 -0
  26. package/src/commands/config/config.get.command.js +21 -0
  27. package/src/commands/config/config.set.command.js +38 -0
  28. package/src/commands/config/config.update.command.js +88 -0
  29. package/src/commands/console/console.command.js +31 -0
  30. package/src/commands/console/console.docs.md +16 -0
  31. package/src/commands/create/create.command.js +173 -0
  32. package/src/commands/create/create.docs.md +27 -0
  33. package/src/commands/{curl.js → curl/curl.command.js} +10 -3
  34. package/src/commands/curl/curl.docs.md +9 -0
  35. package/src/commands/database/database.args.js +8 -0
  36. package/src/commands/database/database.backups.command.js +60 -0
  37. package/src/commands/database/database.backups.download.command.js +55 -0
  38. package/src/commands/database/database.command.js +10 -0
  39. package/src/commands/database/database.docs.md +52 -0
  40. package/src/commands/delete/delete.command.js +43 -0
  41. package/src/commands/delete/delete.docs.md +17 -0
  42. package/src/commands/deploy/deploy.command.js +166 -0
  43. package/src/commands/deploy/deploy.docs.md +22 -0
  44. package/src/commands/diag/diag.command.js +136 -0
  45. package/src/commands/diag/diag.docs.md +15 -0
  46. package/src/commands/domain/domain.add.command.js +25 -0
  47. package/src/commands/domain/domain.args.js +8 -0
  48. package/src/commands/domain/domain.command.js +38 -0
  49. package/src/commands/domain/domain.diag.command.js +204 -0
  50. package/src/commands/domain/domain.docs.md +143 -0
  51. package/src/commands/domain/domain.favourite.command.js +35 -0
  52. package/src/commands/domain/domain.favourite.set.command.js +24 -0
  53. package/src/commands/domain/domain.favourite.unset.command.js +23 -0
  54. package/src/commands/domain/domain.overview.command.js +157 -0
  55. package/src/commands/domain/domain.rm.command.js +25 -0
  56. package/src/commands/drain/drain.args.js +8 -0
  57. package/src/commands/drain/drain.command.js +56 -0
  58. package/src/commands/drain/drain.create.command.js +128 -0
  59. package/src/commands/drain/drain.disable.command.js +27 -0
  60. package/src/commands/drain/drain.docs.md +129 -0
  61. package/src/commands/drain/drain.enable.command.js +27 -0
  62. package/src/commands/drain/drain.get.command.js +38 -0
  63. package/src/commands/drain/drain.remove.command.js +26 -0
  64. package/src/commands/emails/emails.add.command.js +32 -0
  65. package/src/commands/emails/emails.args.js +8 -0
  66. package/src/commands/emails/emails.command.js +35 -0
  67. package/src/commands/emails/emails.docs.md +79 -0
  68. package/src/commands/emails/emails.open.command.js +15 -0
  69. package/src/commands/emails/emails.primary.command.js +29 -0
  70. package/src/commands/emails/emails.remove-all.command.js +54 -0
  71. package/src/commands/emails/emails.remove.command.js +25 -0
  72. package/src/commands/env/env.command.js +77 -0
  73. package/src/commands/env/env.docs.md +99 -0
  74. package/src/commands/env/env.import-vars.command.js +45 -0
  75. package/src/commands/env/env.import.command.js +29 -0
  76. package/src/commands/env/env.rm.command.js +25 -0
  77. package/src/commands/env/env.set.command.js +32 -0
  78. package/src/commands/features/features.args.js +9 -0
  79. package/src/commands/features/features.command.js +7 -0
  80. package/src/commands/features/features.disable.command.js +25 -0
  81. package/src/commands/features/features.docs.md +71 -0
  82. package/src/commands/features/features.enable.command.js +32 -0
  83. package/src/commands/features/features.info.command.js +27 -0
  84. package/src/commands/features/features.list.command.js +49 -0
  85. package/src/commands/global.args.js +45 -0
  86. package/src/commands/global.commands.js +461 -0
  87. package/src/commands/global.options.js +186 -0
  88. package/src/commands/help/help.command.js +9 -0
  89. package/src/commands/help/help.docs.md +9 -0
  90. package/src/commands/k8s/k8s.add-persistent-storage.command.js +39 -0
  91. package/src/commands/k8s/k8s.args.js +9 -0
  92. package/src/commands/k8s/k8s.command.js +12 -0
  93. package/src/commands/k8s/k8s.create.command.js +86 -0
  94. package/src/commands/k8s/k8s.delete.command.js +40 -0
  95. package/src/commands/k8s/k8s.docs.md +131 -0
  96. package/src/commands/k8s/k8s.get-kubeconfig.command.js +32 -0
  97. package/src/commands/k8s/k8s.get.command.js +43 -0
  98. package/src/commands/k8s/k8s.list.command.js +38 -0
  99. package/src/commands/keycloak/keycloak.command.js +17 -0
  100. package/src/commands/keycloak/keycloak.disable-ng.command.js +13 -0
  101. package/src/commands/keycloak/keycloak.docs.md +197 -0
  102. package/src/commands/keycloak/keycloak.enable-ng.command.js +13 -0
  103. package/src/commands/keycloak/keycloak.get.command.js +17 -0
  104. package/src/commands/keycloak/keycloak.open.command.js +13 -0
  105. package/src/commands/keycloak/keycloak.open.logs.command.js +13 -0
  106. package/src/commands/keycloak/keycloak.open.webui.command.js +13 -0
  107. package/src/commands/keycloak/keycloak.rebuild.command.js +13 -0
  108. package/src/commands/keycloak/keycloak.restart.command.js +13 -0
  109. package/src/commands/keycloak/keycloak.version.check.command.js +17 -0
  110. package/src/commands/keycloak/keycloak.version.command.js +17 -0
  111. package/src/commands/keycloak/keycloak.version.update.command.js +17 -0
  112. package/src/commands/kv/kv.command.js +99 -0
  113. package/src/commands/kv/kv.docs.md +27 -0
  114. package/src/commands/link/link.command.js +31 -0
  115. package/src/commands/link/link.docs.md +22 -0
  116. package/src/commands/{login.js → login/login.command.js} +44 -22
  117. package/src/commands/login/login.docs.md +16 -0
  118. package/src/commands/logout/logout.command.js +15 -0
  119. package/src/commands/logout/logout.docs.md +9 -0
  120. package/src/commands/logs/logs.command.js +81 -0
  121. package/src/commands/logs/logs.docs.md +22 -0
  122. package/src/commands/make-default/make-default.command.js +17 -0
  123. package/src/commands/make-default/make-default.docs.md +15 -0
  124. package/src/commands/matomo/matomo.command.js +17 -0
  125. package/src/commands/matomo/matomo.docs.md +109 -0
  126. package/src/commands/matomo/matomo.get.command.js +17 -0
  127. package/src/commands/matomo/matomo.open.command.js +13 -0
  128. package/src/commands/matomo/matomo.open.logs.command.js +13 -0
  129. package/src/commands/matomo/matomo.open.webui.command.js +13 -0
  130. package/src/commands/matomo/matomo.rebuild.command.js +13 -0
  131. package/src/commands/matomo/matomo.restart.command.js +13 -0
  132. package/src/commands/metabase/metabase.command.js +17 -0
  133. package/src/commands/metabase/metabase.docs.md +169 -0
  134. package/src/commands/metabase/metabase.get.command.js +17 -0
  135. package/src/commands/metabase/metabase.open.command.js +13 -0
  136. package/src/commands/metabase/metabase.open.logs.command.js +13 -0
  137. package/src/commands/metabase/metabase.open.webui.command.js +13 -0
  138. package/src/commands/metabase/metabase.rebuild.command.js +13 -0
  139. package/src/commands/metabase/metabase.restart.command.js +13 -0
  140. package/src/commands/metabase/metabase.version.check.command.js +17 -0
  141. package/src/commands/metabase/metabase.version.command.js +17 -0
  142. package/src/commands/metabase/metabase.version.update.command.js +17 -0
  143. package/src/commands/ng/ng.args.js +27 -0
  144. package/src/commands/ng/ng.command.js +45 -0
  145. package/src/commands/ng/ng.create.command.js +60 -0
  146. package/src/commands/ng/ng.create.external.command.js +44 -0
  147. package/src/commands/ng/ng.delete.command.js +22 -0
  148. package/src/commands/ng/ng.delete.external.command.js +25 -0
  149. package/src/commands/ng/ng.docs.md +214 -0
  150. package/src/commands/ng/ng.get-config.command.js +32 -0
  151. package/src/commands/ng/ng.get.command.js +22 -0
  152. package/src/commands/ng/ng.link.command.js +25 -0
  153. package/src/commands/ng/ng.options.js +9 -0
  154. package/src/commands/ng/ng.search.command.js +22 -0
  155. package/src/commands/ng/ng.unlink.command.js +25 -0
  156. package/src/commands/notify-email/notify-email.add.command.js +65 -0
  157. package/src/commands/notify-email/notify-email.command.js +61 -0
  158. package/src/commands/notify-email/notify-email.docs.md +60 -0
  159. package/src/commands/notify-email/notify-email.remove.command.js +24 -0
  160. package/src/commands/open/open.command.js +24 -0
  161. package/src/commands/open/open.docs.md +16 -0
  162. package/src/commands/otoroshi/otoroshi.command.js +17 -0
  163. package/src/commands/otoroshi/otoroshi.disable-ng.command.js +13 -0
  164. package/src/commands/otoroshi/otoroshi.docs.md +211 -0
  165. package/src/commands/otoroshi/otoroshi.enable-ng.command.js +13 -0
  166. package/src/commands/otoroshi/otoroshi.get-config.command.js +13 -0
  167. package/src/commands/otoroshi/otoroshi.get.command.js +17 -0
  168. package/src/commands/otoroshi/otoroshi.open.command.js +13 -0
  169. package/src/commands/otoroshi/otoroshi.open.logs.command.js +13 -0
  170. package/src/commands/otoroshi/otoroshi.open.webui.command.js +13 -0
  171. package/src/commands/otoroshi/otoroshi.rebuild.command.js +13 -0
  172. package/src/commands/otoroshi/otoroshi.restart.command.js +13 -0
  173. package/src/commands/otoroshi/otoroshi.version.check.command.js +17 -0
  174. package/src/commands/otoroshi/otoroshi.version.command.js +17 -0
  175. package/src/commands/otoroshi/otoroshi.version.update.command.js +17 -0
  176. package/src/commands/profile/profile.command.js +60 -0
  177. package/src/commands/profile/profile.docs.md +23 -0
  178. package/src/commands/profile/profile.open.command.js +12 -0
  179. package/src/commands/published-config/published-config.command.js +40 -0
  180. package/src/commands/published-config/published-config.docs.md +77 -0
  181. package/src/commands/published-config/published-config.import.command.js +29 -0
  182. package/src/commands/published-config/published-config.rm.command.js +27 -0
  183. package/src/commands/published-config/published-config.set.command.js +34 -0
  184. package/src/commands/restart/restart.command.js +77 -0
  185. package/src/commands/restart/restart.docs.md +21 -0
  186. package/src/commands/scale/scale.command.js +121 -0
  187. package/src/commands/scale/scale.docs.md +23 -0
  188. package/src/commands/service/service.command.js +91 -0
  189. package/src/commands/service/service.docs.md +104 -0
  190. package/src/commands/service/service.link-addon.command.js +24 -0
  191. package/src/commands/service/service.link-app.command.js +23 -0
  192. package/src/commands/service/service.unlink-addon.command.js +24 -0
  193. package/src/commands/service/service.unlink-app.command.js +23 -0
  194. package/src/commands/ssh/ssh.command.js +40 -0
  195. package/src/commands/ssh/ssh.docs.md +17 -0
  196. package/src/commands/ssh-keys/ssh-keys.add.command.js +41 -0
  197. package/src/commands/ssh-keys/ssh-keys.args.js +8 -0
  198. package/src/commands/ssh-keys/ssh-keys.command.js +50 -0
  199. package/src/commands/ssh-keys/ssh-keys.docs.md +66 -0
  200. package/src/commands/ssh-keys/ssh-keys.open.command.js +12 -0
  201. package/src/commands/ssh-keys/ssh-keys.remove-all.command.js +54 -0
  202. package/src/commands/ssh-keys/ssh-keys.remove.command.js +26 -0
  203. package/src/commands/status/status.command.js +122 -0
  204. package/src/commands/status/status.docs.md +17 -0
  205. package/src/commands/stop/stop.command.js +23 -0
  206. package/src/commands/stop/stop.docs.md +16 -0
  207. package/src/commands/tcp-redirs/tcp-redirs.add.command.js +24 -0
  208. package/src/commands/tcp-redirs/tcp-redirs.command.js +41 -0
  209. package/src/commands/tcp-redirs/tcp-redirs.docs.md +71 -0
  210. package/src/commands/tcp-redirs/tcp-redirs.list-namespaces.command.js +48 -0
  211. package/src/commands/tcp-redirs/tcp-redirs.options.js +11 -0
  212. package/src/commands/tcp-redirs/tcp-redirs.remove.command.js +34 -0
  213. package/src/commands/tokens/tokens.command.js +43 -0
  214. package/src/commands/tokens/tokens.create.command.js +108 -0
  215. package/src/commands/tokens/tokens.docs.md +50 -0
  216. package/src/commands/tokens/tokens.revoke.command.js +25 -0
  217. package/src/commands/unlink/unlink.command.js +21 -0
  218. package/src/commands/unlink/unlink.docs.md +15 -0
  219. package/src/commands/version/version.command.js +13 -0
  220. package/src/commands/version/version.docs.md +9 -0
  221. package/src/commands/webhooks/webhooks.add.command.js +51 -0
  222. package/src/commands/webhooks/webhooks.command.js +57 -0
  223. package/src/commands/webhooks/webhooks.docs.md +61 -0
  224. package/src/commands/webhooks/webhooks.remove.command.js +24 -0
  225. package/src/lib/cliparse-patched.js +192 -0
  226. package/src/lib/define-argument.js +7 -0
  227. package/src/lib/define-argument.types.d.ts +23 -0
  228. package/src/lib/define-command.js +7 -0
  229. package/src/lib/define-command.types.d.ts +85 -0
  230. package/src/lib/define-common.types.d.ts +18 -0
  231. package/src/lib/define-option.js +7 -0
  232. package/src/lib/define-option.types.d.ts +29 -0
  233. package/src/lib/get-command-info.js +86 -0
  234. package/src/lib/get-command-info.types.d.ts +42 -0
  235. package/src/lib/zod-utils.js +66 -0
  236. package/src/models/addon.js +2 -3
  237. package/src/models/application.js +4 -5
  238. package/src/models/application_configuration.js +5 -23
  239. package/src/models/domain.js +34 -2
  240. package/src/models/exit-strategy-option.js +0 -9
  241. package/src/models/git.js +1 -4
  242. package/src/models/log-v4.js +5 -0
  243. package/src/models/log.js +5 -0
  244. package/src/models/namespaces.js +1 -2
  245. package/src/models/notification.js +1 -7
  246. package/src/parsers.js +33 -92
  247. package/src/command-options.js +0 -55
  248. package/src/command-promise-handler.js +0 -16
  249. package/src/commands/accesslogs.js +0 -138
  250. package/src/commands/addon.js +0 -391
  251. package/src/commands/applications.js +0 -123
  252. package/src/commands/cancel-deploy.js +0 -19
  253. package/src/commands/config.js +0 -47
  254. package/src/commands/console.js +0 -20
  255. package/src/commands/create.js +0 -129
  256. package/src/commands/database.js +0 -73
  257. package/src/commands/delete.js +0 -24
  258. package/src/commands/deploy.js +0 -133
  259. package/src/commands/diag.js +0 -126
  260. package/src/commands/domain.js +0 -445
  261. package/src/commands/drain.js +0 -164
  262. package/src/commands/emails.js +0 -156
  263. package/src/commands/env.js +0 -124
  264. package/src/commands/features.js +0 -87
  265. package/src/commands/k8s.js +0 -193
  266. package/src/commands/keycloak.js +0 -138
  267. package/src/commands/kv.js +0 -93
  268. package/src/commands/link.js +0 -20
  269. package/src/commands/logout.js +0 -8
  270. package/src/commands/logs.js +0 -45
  271. package/src/commands/makeDefault.js +0 -11
  272. package/src/commands/matomo.js +0 -85
  273. package/src/commands/metabase.js +0 -112
  274. package/src/commands/ng.js +0 -202
  275. package/src/commands/notify-email.js +0 -99
  276. package/src/commands/open.js +0 -13
  277. package/src/commands/otoroshi.js +0 -149
  278. package/src/commands/profile.js +0 -55
  279. package/src/commands/published-config.js +0 -70
  280. package/src/commands/restart.js +0 -52
  281. package/src/commands/scale.js +0 -66
  282. package/src/commands/service.js +0 -105
  283. package/src/commands/ssh-keys.js +0 -144
  284. package/src/commands/ssh.js +0 -20
  285. package/src/commands/status.js +0 -115
  286. package/src/commands/stop.js +0 -12
  287. package/src/commands/tcp-redirs.js +0 -80
  288. package/src/commands/tokens.js +0 -144
  289. package/src/commands/unlink.js +0 -14
  290. package/src/commands/version.js +0 -6
  291. 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
+ });