clever-tools 4.4.1 → 4.5.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 (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
@@ -1,445 +0,0 @@
1
- import {
2
- addDomain,
3
- getAllDomains,
4
- get as getApp,
5
- getFavouriteDomain as getFavouriteDomainWithError,
6
- markFavouriteDomain,
7
- removeDomain,
8
- unmarkFavouriteDomain,
9
- } from '@clevercloud/client/esm/api/v2/application.js';
10
- import { getSummary } from '@clevercloud/client/esm/api/v2/user.js';
11
- import { getDefaultLoadBalancersDnsInfo } from '@clevercloud/client/esm/api/v4/load-balancers.js';
12
- import { diagDomainConfig } from '@clevercloud/client/esm/utils/diag-domain-config.js';
13
- import { sortDomains } from '@clevercloud/client/esm/utils/domains.js';
14
- import _ from 'lodash';
15
- import { parse as parseDomain } from 'tldts';
16
- import { styleText } from '../lib/style-text.js';
17
- import { Logger } from '../logger.js';
18
- import * as Application from '../models/application.js';
19
- import { DnsResolver } from '../models/node-dns-resolver.js';
20
- import { sendToApi } from '../models/send-to-api.js';
21
-
22
- /**
23
- * @typedef {import('@clevercloud/client/esm/utils/diag-domain-config.types.js').DomainInfo} DomainInfo
24
- * @typedef {import('@clevercloud/client/esm/utils/diag-domain-config.types.js').ResolveDnsResult} ResolveDnsResult
25
- * @typedef {import('@clevercloud/client/esm/utils/diag-domain-config.types.js').DomainDiag} DomainDiag
26
- */
27
-
28
- function getFavouriteDomain({ ownerId, appId }) {
29
- return getFavouriteDomainWithError({ id: ownerId, appId })
30
- .then(sendToApi)
31
- .then(({ fqdn }) => fqdn)
32
- .catch((error) => {
33
- if (error.id === 4021) {
34
- // No favourite vhost
35
- return null;
36
- }
37
- throw error;
38
- });
39
- }
40
-
41
- export async function list(params) {
42
- const { alias, app: appIdOrName, format } = params.options;
43
- const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
44
-
45
- const app = await getApp({ id: ownerId, appId }).then(sendToApi);
46
- const favouriteDomain = await getFavouriteDomain({ ownerId, appId });
47
-
48
- const domains = app.vhosts.map((vhost) => getDomainObject(vhost.fqdn, favouriteDomain));
49
-
50
- switch (format) {
51
- case 'json':
52
- Logger.printJson(domains);
53
- break;
54
- default:
55
- domains.forEach((domain) => {
56
- Logger.println(`${domain.isFavourite ? '* ' : ' '}${domain.domainWithPathPrefix}`);
57
- });
58
- break;
59
- }
60
- }
61
-
62
- export async function add(params) {
63
- const [fqdn] = params.args;
64
- const { alias, app: appIdOrName } = params.options;
65
- const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
66
- const encodedFqdn = encodeURIComponent(fqdn);
67
-
68
- await addDomain({ id: ownerId, appId, domain: encodedFqdn }).then(sendToApi);
69
- Logger.println('Your domain has been successfully saved');
70
- }
71
-
72
- export async function getFavourite(params) {
73
- const { alias, app: appIdOrName, format } = params.options;
74
- const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
75
-
76
- const favouriteDomain = await getFavouriteDomain({ ownerId, appId });
77
-
78
- switch (format) {
79
- case 'json':
80
- const domain = getDomainObject(favouriteDomain, favouriteDomain);
81
- Logger.printJson(domain);
82
- break;
83
- default:
84
- if (favouriteDomain == null) {
85
- return Logger.println('No favourite domain set');
86
- }
87
- Logger.println(favouriteDomain);
88
- break;
89
- }
90
- }
91
-
92
- export async function setFavourite(params) {
93
- const [fqdn] = params.args;
94
- const { alias, app: appIdOrName } = params.options;
95
- const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
96
-
97
- await markFavouriteDomain({ id: ownerId, appId }, { fqdn }).then(sendToApi);
98
- Logger.println('Your favourite domain has been successfully set');
99
- }
100
-
101
- export async function unsetFavourite(params) {
102
- const { alias, app: appIdOrName } = params.options;
103
- const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
104
-
105
- await unmarkFavouriteDomain({ id: ownerId, appId }).then(sendToApi);
106
- Logger.println('Favourite domain has been successfully unset');
107
- }
108
-
109
- export async function rm(params) {
110
- const [fqdn] = params.args;
111
- const { alias, app: appIdOrName } = params.options;
112
- const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
113
- const encodedFqdn = encodeURIComponent(fqdn);
114
-
115
- await removeDomain({ id: ownerId, appId, domain: encodedFqdn }).then(sendToApi);
116
- Logger.println('Your domain has been successfully removed');
117
- }
118
-
119
- export async function diagApplication(params) {
120
- const dnsResolver = new DnsResolver();
121
- const allDomainDiagnostics = [];
122
- const { alias, app: appIdOrName, format, filter } = params.options;
123
- const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
124
- const hasDomainFilter = filter.length > 0;
125
- let hasError = false;
126
-
127
- const app = await getApp({ id: ownerId, appId }).then(sendToApi);
128
- const expectedDnsForPublicLoadBalancer = await getDefaultLoadBalancersDnsInfo({ ownerId, appId }).then(sendToApi);
129
-
130
- const loadBalancerDnsConfig = {
131
- aRecords: expectedDnsForPublicLoadBalancer[0].dns.a,
132
- cnameRecord: expectedDnsForPublicLoadBalancer[0].dns.cname,
133
- };
134
-
135
- const filteredDomains = app.vhosts.filter(({ fqdn }) => fqdn.includes(filter));
136
- const domains = getParsedDomains(filteredDomains);
137
- const sortedDomains = domains.sort(sortDomains);
138
-
139
- for (const { hostname, pathPrefix, isApex } of sortedDomains) {
140
- const resolvedDnsConfig = {
141
- aRecords: await dnsResolver.resolveA(hostname),
142
- cnameRecords: (await dnsResolver.resolveCname(hostname)) ?? [],
143
- };
144
-
145
- const diagnosticResults = diagDomainConfig(
146
- {
147
- hostname,
148
- pathPrefix,
149
- isApex,
150
- },
151
- resolvedDnsConfig,
152
- loadBalancerDnsConfig,
153
- );
154
- allDomainDiagnostics.push({ ...diagnosticResults, resolvedDnsConfig });
155
-
156
- if (diagnosticResults.diagSummary === 'invalid' || diagnosticResults.diagSummary === 'no-config') {
157
- hasError = true;
158
- }
159
- }
160
-
161
- switch (format) {
162
- case 'json':
163
- Logger.printJson(allDomainDiagnostics);
164
- break;
165
- default: {
166
- allDomainDiagnostics.forEach((diag) => reportDomainDiagnostics(diag));
167
-
168
- if (allDomainDiagnostics.length === 0 && !hasDomainFilter) {
169
- Logger.println(`\nNo domain associated to the app "${app.name}" (${app.id})`);
170
- }
171
-
172
- if (allDomainDiagnostics.length === 0 && hasDomainFilter) {
173
- Logger.println(`\nNo domain matches "${filter}" for the app "${app.name}" (${app.id})`);
174
- }
175
- }
176
- }
177
-
178
- if (hasError) {
179
- throw new Error('At least one of the domains is misconfigured');
180
- }
181
- }
182
-
183
- export async function overview(params) {
184
- const { format, filter } = params.options;
185
-
186
- const summary = await getSummary().then(sendToApi);
187
- const consoleUrl = summary.user.partnerConsoleUrl;
188
-
189
- const applications = [
190
- ...summary.user.applications.map((app) => {
191
- return { ownerName: summary.user.name, ownerId: summary.user.id, ...app };
192
- }),
193
- ...summary.organisations.flatMap((o) => {
194
- return o.applications.map((app) => {
195
- return { ownerName: o.name, ownerId: o.id, ...app };
196
- });
197
- }),
198
- ];
199
-
200
- const applicationsWithDomains = await Promise.all(
201
- applications.map(async (app) => {
202
- const domains = await getAllDomains({ id: app.ownerId, appId: app.id })
203
- .then(sendToApi)
204
- .catch((error) => {
205
- // if the user cannot access application domains, we simply act as if there were no domains
206
- if (error?.response?.status === 403) {
207
- Logger.printErrorLine(`You cannot list domains for application ${app.name} (${app.id})`);
208
- return [];
209
- }
210
- throw error;
211
- });
212
- return { app, domains };
213
- }),
214
- );
215
-
216
- const applicationsWithParsedDomain = applicationsWithDomains.flatMap(({ app, domains }) => {
217
- return domains
218
- .filter((domain) => filter == null || domain.fqdn.includes(filter))
219
- .map((domain) => {
220
- // `validateHostname` is set to `false` so that wildcard domains may be parsed correctly
221
- const parsedDomain = parseDomain(domain.fqdn, { validateHostname: false });
222
- const pathname = new URL('https://' + domain.fqdn).pathname;
223
- const subdomains = parsedDomain.subdomain !== '' ? parsedDomain.subdomain.split('.') : [];
224
-
225
- // We're trying to create a propertyPath for lodash to create a tree structure object,
226
- // the propertyPath for `aaa.bbb.ccc.example.com/the-path` would be:
227
- // ["example.com", "example.com.ccc", "example.com.ccc.bbb", "example.com.ccc.bbb.aaa", "/path-aaa"]",
228
-
229
- const sortSegments = [parsedDomain.domain, ...subdomains.reverse()];
230
- const propertyPath = sortSegments.map((item, i, all) => {
231
- return all
232
- .slice(0, i + 1)
233
- .reverse()
234
- .join('.');
235
- });
236
- propertyPath.push(pathname);
237
-
238
- return {
239
- ownerId: app.ownerId,
240
- ownerName: app.ownerName,
241
- appId: app.id,
242
- appName: app.name,
243
- appConsoleUrl: `${consoleUrl}/goto/${app.id}`,
244
- appVariantSlug: app.variantSlug,
245
- domain: domain.fqdn,
246
- propetyPath: propertyPath,
247
- };
248
- });
249
- });
250
-
251
- const applicationsWithParsedDomainAsTree = {};
252
- for (const { propetyPath, ...appWithDomain } of applicationsWithParsedDomain) {
253
- _.set(applicationsWithParsedDomainAsTree, propetyPath, appWithDomain);
254
- }
255
-
256
- const applicationsWithParsedDomainAsSortedTree = recursiveSort(applicationsWithParsedDomainAsTree);
257
-
258
- switch (format) {
259
- case 'json':
260
- Logger.printJson(applicationsWithParsedDomainAsSortedTree);
261
- break;
262
- case 'human':
263
- default:
264
- if (Object.keys(applicationsWithParsedDomainAsSortedTree).length === 0) {
265
- if (filter?.length > 0) {
266
- Logger.println(`No matches for filter "${filter}"`);
267
- } else {
268
- Logger.println('No domains');
269
- }
270
- } else {
271
- recursiveDisplay(applicationsWithParsedDomainAsSortedTree);
272
- }
273
- break;
274
- }
275
- }
276
-
277
- function getDomainObject(domainWithPathPrefix, favouriteDomain) {
278
- const parsed = parseDomain(domainWithPathPrefix, { validateHostname: false });
279
- return {
280
- domainWithPathPrefix,
281
- domain: parsed.domain,
282
- domainWithoutSuffix: parsed.domainWithoutSuffix,
283
- hostname: parsed.hostname,
284
- publicSuffix: parsed.publicSuffix,
285
- subdomain: parsed.subdomain,
286
- isApex: parsed.subdomain === '',
287
- pathPrefix: new URL('https://' + domainWithPathPrefix).pathname,
288
- isFavourite: domainWithPathPrefix === favouriteDomain,
289
- };
290
- }
291
-
292
- /** @param {DomainDiag & { resolvedDnsConfig: ResolveDnsResult }} domainDiag */
293
- function reportDomainDiagnostics({ hostname, pathPrefix, resolvedDnsConfig, diagDetails, diagSummary }) {
294
- const validDiags = diagDetails.filter((diag) => diag.code === 'valid-a');
295
- const unknownDiags = diagDetails.filter((diag) => diag.code === 'unknown-a');
296
- const missingDiags = diagDetails.filter((diag) => diag.code === 'missing-a');
297
- const suggestedCname = diagDetails.find((diag) => diag.code === 'suggested-cname');
298
- const missingCname = diagDetails.find((diag) => diag.code === 'missing-cname');
299
- const unknownCname = diagDetails.find((diag) => diag.code === 'unknown-cname');
300
-
301
- const hasARecords = resolvedDnsConfig.aRecords.length > 0;
302
- const hasCnameRecord = resolvedDnsConfig.cnameRecords.length > 0;
303
-
304
- Logger.println('\n' + styleText('blue', hostname) + styleText('yellow', pathPrefix) + '\n');
305
-
306
- switch (diagSummary) {
307
- case 'managed':
308
- Logger.printlnWithIndent(styleText('green', '✔ Managed by Clever Cloud'), 2);
309
- Logger.printlnWithIndent('ⓘ cleverapps.io domains should only be used for testing purposes', 2);
310
- break;
311
- case 'no-config':
312
- Logger.printlnWithIndent(styleText('red', '✘ No DNS configuration found'), 2);
313
- break;
314
- case 'valid':
315
- Logger.printlnWithIndent(styleText('green', '✔ Your configuration is valid'), 2);
316
- break;
317
- case 'invalid':
318
- Logger.printlnWithIndent(styleText('red', '✘ Something is wrong with your configuration'), 2);
319
- break;
320
- case 'incomplete':
321
- Logger.printlnWithIndent(styleText('yellow', '⚠ Your configuration is incomplete'), 2);
322
- break;
323
- }
324
-
325
- // Valid records
326
- if (validDiags.length > 0) {
327
- Logger.println('');
328
- validDiags.forEach((diag) => {
329
- const source = hasCnameRecord ? `(from CNAME ${resolvedDnsConfig.cnameRecords[0]}.)` : '';
330
- Logger.printlnWithIndent(`${diag.record.value} ${styleText('green', '✔ A Record OK')} ${source}`, 2);
331
- });
332
- }
333
-
334
- // Replace A with CNAME
335
- if (diagSummary === 'valid' && suggestedCname != null) {
336
- Logger.println('');
337
- Logger.printlnWithIndent('ⓘ You can replace your A records with this CNAME:', 2);
338
- Logger.printlnWithIndent(suggestedCname.record.value, 6);
339
- }
340
-
341
- // Replace A Records with CNAME
342
- if (missingCname != null && unknownCname == null && (diagSummary === 'invalid' || diagSummary === 'incomplete')) {
343
- const cnameToUse = suggestedCname != null ? suggestedCname.record.value : missingCname.record.value;
344
-
345
- Logger.println('');
346
- Logger.printlnWithIndent('⇄ Replace your A records with this CNAME:', 2);
347
- Logger.printlnWithIndent(cnameToUse, 6);
348
- Logger.println('');
349
- Logger.printlnWithIndent('or:', 2);
350
- }
351
-
352
- // Replace unknown CNAME with missing CNAME
353
- if (diagSummary === 'invalid' && missingCname != null && unknownCname != null) {
354
- Logger.println('');
355
- Logger.printlnWithIndent('➖Remove this CNAME record:', 2);
356
- Logger.printlnWithIndent(unknownCname.record.value + '. ', 6);
357
- Logger.println('');
358
- Logger.printlnWithIndent('➕Add this CNAME record instead:', 2);
359
- Logger.printlnWithIndent(missingCname.record.value, 6);
360
-
361
- if (hasARecords) {
362
- Logger.println('');
363
- Logger.printlnWithIndent('or:', 2);
364
- }
365
- }
366
-
367
- // Add CNAME
368
- if (diagSummary === 'no-config' && missingCname != null) {
369
- Logger.println('');
370
- Logger.printlnWithIndent('➕Add this CNAME record:', 2);
371
- Logger.printlnWithIndent(missingCname.record.value, 6);
372
- }
373
-
374
- // Remove Unknown records
375
- if (unknownDiags.length > 0) {
376
- Logger.println('');
377
- Logger.printlnWithIndent('➖Remove these A records:', 2);
378
-
379
- unknownDiags.forEach((diag) => {
380
- const source = hasCnameRecord ? `(from CNAME ${resolvedDnsConfig.cnameRecords[0]}.)` : '';
381
- Logger.printlnWithIndent(`${diag.record.value} ${source}`, 6);
382
- });
383
- }
384
-
385
- // Add missing A records
386
- if (missingDiags.length > 0) {
387
- Logger.println('');
388
- Logger.printlnWithIndent('➕Add these A records:', 2);
389
-
390
- missingDiags.forEach((missingDiag) => Logger.printlnWithIndent(missingDiag.record.value, 6));
391
- }
392
- }
393
-
394
- /**
395
- * Parses domain information from vhosts array
396
- *
397
- * @param {Array<{ fqdn: string }>} vhosts
398
- * @returns {Array<Partial<DomainInfo>>} Array of parsed domain objects
399
- */
400
- function getParsedDomains(vhosts) {
401
- return vhosts.map(({ fqdn }) => {
402
- const { hostname, pathname } = new URL('https://' + fqdn);
403
- const { subdomain } = parseDomain(fqdn);
404
-
405
- return { hostname, pathPrefix: pathname, isApex: subdomain === '' };
406
- });
407
- }
408
-
409
- function recursiveSort(obj) {
410
- if (typeof obj === 'object' && obj.appId != null) {
411
- return obj;
412
- }
413
-
414
- const sortedObj = {};
415
- Object.keys(obj)
416
- .sort((a, b) => {
417
- // if the domain contains a wildcard, we want it to be the first of subdomains
418
- const aWithReplacedWildcard = a.replace(/^\*/, 'a');
419
- const bWithReplacedWildcard = b.replace(/^\*/, 'a');
420
- return aWithReplacedWildcard.localeCompare(bWithReplacedWildcard);
421
- })
422
- .forEach((key) => {
423
- sortedObj[key] = recursiveSort(obj[key]);
424
- });
425
-
426
- return sortedObj;
427
- }
428
-
429
- function recursiveDisplay(obj, indentLevel = 0) {
430
- if (typeof obj === 'object' && obj.appId != null) {
431
- Logger.printlnWithIndent(`${obj.ownerName} | ${obj.appName} (${obj.appVariantSlug})`, indentLevel);
432
- Logger.printlnWithIndent(styleText('blue', obj.appConsoleUrl), indentLevel);
433
- return;
434
- }
435
-
436
- for (const [propertyPath, subObj] of Object.entries(obj)) {
437
- if (propertyPath !== '/') {
438
- Logger.println('');
439
- Logger.printlnWithIndent(styleText('yellow', propertyPath), indentLevel);
440
- recursiveDisplay(subObj, indentLevel + 2);
441
- } else {
442
- recursiveDisplay(subObj, indentLevel);
443
- }
444
- }
445
- }
@@ -1,164 +0,0 @@
1
- import { createDrain, deleteDrain, disableDrain, enableDrain, getDrain, getDrains } from '../clever-client/drains.js';
2
- import { styleText } from '../lib/style-text.js';
3
- import { Logger } from '../logger.js';
4
- import * as Application from '../models/application.js';
5
- import { DRAIN_TYPE_CLI_CODES, DRAIN_TYPES, formatDrain } from '../models/drain.js';
6
- import { sendToApi } from '../models/send-to-api.js';
7
-
8
- export async function list(params) {
9
- const { alias, app: appIdOrName, format } = params.options;
10
-
11
- const { ownerId, appId: applicationId } = await Application.resolveId(appIdOrName, alias);
12
-
13
- const drains = await getDrains({ ownerId, applicationId }).then(sendToApi);
14
-
15
- switch (format) {
16
- case 'json': {
17
- Logger.printJson(drains);
18
- break;
19
- }
20
- case 'human':
21
- default: {
22
- if (drains.length === 0) {
23
- Logger.println(`There are no drains for ${applicationId}`);
24
- return;
25
- }
26
-
27
- if (drains.length === 1) {
28
- const formattedDrain = formatDrain(drains[0]);
29
- console.table(formattedDrain);
30
- return;
31
- }
32
-
33
- const formattedDrains = drains.map((drain) => {
34
- return {
35
- ID: drain.id,
36
- Status: drain.status.status,
37
- 'Execution status': drain.execution.status,
38
- URL: drain.recipient.url,
39
- };
40
- });
41
-
42
- console.table(formattedDrains);
43
- }
44
- }
45
- }
46
-
47
- export async function create(params) {
48
- const { alias, app: appIdOrName } = params.options;
49
- const {
50
- username,
51
- password,
52
- 'api-key': apiKey,
53
- 'index-prefix': indexPrefix,
54
- 'sd-params': rfc5424StructuredDataParameters,
55
- } = params.options;
56
- const [drainTypeCliCode, url] = params.args;
57
-
58
- const drainType = Object.values(DRAIN_TYPES).find((drainType) => drainType.cliCode === drainTypeCliCode);
59
- if (!drainType) {
60
- throw new Error(`Invalid drain type. Supported types are: ${DRAIN_TYPE_CLI_CODES.join(', ')}`);
61
- }
62
-
63
- const { ownerId, appId: applicationId } = await Application.resolveId(appIdOrName, alias);
64
-
65
- const body = {
66
- kind: 'LOG',
67
- recipient: {
68
- type: drainType.apiCode,
69
- url,
70
- },
71
- };
72
-
73
- if (drainTypeCliCode === DRAIN_TYPES.ELASTICSEARCH.cliCode) {
74
- if (!indexPrefix) {
75
- throw new Error(`${DRAIN_TYPES.ELASTICSEARCH.cliCode} drains require an index prefix (--index-prefix) to be set`);
76
- }
77
- if (!url.endsWith('/_bulk')) {
78
- throw new Error(`${DRAIN_TYPES.ELASTICSEARCH.cliCode} drain URL must end with '/_bulk'`);
79
- }
80
- body.recipient.index = indexPrefix;
81
- }
82
-
83
- if (drainTypeCliCode === DRAIN_TYPES.ELASTICSEARCH.cliCode || drainTypeCliCode === DRAIN_TYPES.RAW_HTTP.cliCode) {
84
- if (username) {
85
- body.recipient.username = username;
86
- }
87
- if (password) {
88
- body.recipient.password = password;
89
- }
90
- }
91
-
92
- if (drainTypeCliCode === DRAIN_TYPES.NEWRELIC.cliCode) {
93
- if (!apiKey) {
94
- throw new Error(`${DRAIN_TYPES.NEWRELIC.cliCode} drains require an API key (--api-key) to be set`);
95
- }
96
- body.recipient.apiKey = apiKey;
97
- }
98
-
99
- if (
100
- drainTypeCliCode === DRAIN_TYPES.OVH_TCP.cliCode ||
101
- drainTypeCliCode === DRAIN_TYPES.SYSLOG_TCP.cliCode ||
102
- drainTypeCliCode === DRAIN_TYPES.SYSLOG_UDP.cliCode
103
- ) {
104
- if (rfc5424StructuredDataParameters) {
105
- body.recipient.rfc5424StructuredDataParameters = rfc5424StructuredDataParameters;
106
- }
107
- }
108
-
109
- const drain = await createDrain({ ownerId, applicationId, body }).then(sendToApi);
110
- Logger.printSuccess(`Drain ${styleText(['bold', 'green'], drain.id)} has been successfully created and enabled!`);
111
- }
112
-
113
- export async function get(params) {
114
- const [drainId] = params.args;
115
- const { alias, app: appIdOrName, format } = params.options;
116
-
117
- const { ownerId, appId: applicationId } = await Application.resolveId(appIdOrName, alias);
118
-
119
- const drain = await getDrain({ ownerId, applicationId, drainId }).then(sendToApi);
120
-
121
- switch (format) {
122
- case 'json': {
123
- Logger.printJson(drain);
124
- break;
125
- }
126
- case 'human':
127
- default: {
128
- const formattedDrain = formatDrain(drain);
129
- console.table(formattedDrain);
130
- }
131
- }
132
- }
133
-
134
- export async function remove(params) {
135
- const [drainId] = params.args;
136
- const { alias, app: appIdOrName } = params.options;
137
-
138
- const { ownerId, appId: applicationId } = await Application.resolveId(appIdOrName, alias);
139
-
140
- await deleteDrain({ ownerId, applicationId, drainId }).then(sendToApi);
141
- Logger.printSuccess(`Drain ${styleText(['bold', 'green'], drainId)} has been successfully removed!`);
142
- }
143
-
144
- export async function enable(params) {
145
- const [drainId] = params.args;
146
- const { alias, app: appIdOrName } = params.options;
147
-
148
- const { ownerId, appId: applicationId } = await Application.resolveId(appIdOrName, alias);
149
-
150
- await enableDrain({ ownerId, applicationId, drainId }).then(sendToApi);
151
-
152
- Logger.printSuccess(`Drain ${styleText(['bold', 'green'], drainId)} has been successfully enabled!`);
153
- }
154
-
155
- export async function disable(params) {
156
- const [drainId] = params.args;
157
- const { alias, app: appIdOrName } = params.options;
158
-
159
- const { ownerId, appId: applicationId } = await Application.resolveId(appIdOrName, alias);
160
-
161
- await disableDrain({ ownerId, applicationId, drainId }).then(sendToApi);
162
-
163
- Logger.printSuccess(`Drain ${styleText(['bold', 'green'], drainId)} has been successfully disabled!`);
164
- }