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,236 @@
1
+ import dedent from 'dedent';
2
+ import { z } from 'zod';
3
+ import { getOperator } from '../../clever-client/operators.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 Addon from '../../models/addon.js';
9
+ import { completePlan, completeRegion, parseAddonOptions } from '../../models/addon.js';
10
+ import * as AppConfig from '../../models/app_configuration.js';
11
+ import { listAvailableAliases } from '../../models/application.js';
12
+ import { conf } from '../../models/configuration.js';
13
+ import * as Organisation from '../../models/organisation.js';
14
+ import { sendToApi } from '../../models/send-to-api.js';
15
+ import * as User from '../../models/user.js';
16
+ import { addonOptions } from '../../parsers.js';
17
+ import { humanJsonOutputFormatOption, orgaIdOrNameOption } from '../global.options.js';
18
+ import { addonNameArg, addonProviderArg } from './addon.args.js';
19
+
20
+ const ADDON_PROVIDERS = {
21
+ keycloak: {
22
+ name: 'Keycloak',
23
+ isOperator: true,
24
+ postCreateInstructions: `Learn more about Keycloak on Clever Cloud: ${conf.DOC_URL}/addons/keycloak/`,
25
+ },
26
+ kv: {
27
+ name: 'Materia KV',
28
+ isOperator: false,
29
+ status: 'beta',
30
+ postCreateInstructions: (addonId) => dedent`
31
+ ${styleText('yellow', "You can easily use Materia KV with 'redis-cli', with such commands:")}
32
+ ${styleText('blue', `source <(clever addon env ${addonId} -F shell)`)}
33
+ ${styleText('blue', 'redis-cli -h $KV_HOST -p $KV_PORT --tls')}
34
+ Learn more about Materia KV on Clever Cloud: ${conf.DOC_URL}/addons/materia-kv/
35
+ `,
36
+ },
37
+ 'addon-matomo': {
38
+ name: 'Matomo',
39
+ isOperator: true,
40
+ postCreateInstructions: `Learn more about Matomo on Clever Cloud: ${conf.DOC_URL}/addons/matomo/`,
41
+ },
42
+ metabase: {
43
+ name: 'Metabase',
44
+ isOperator: true,
45
+ postCreateInstructions: `Learn more about Metabase on Clever Cloud: ${conf.DOC_URL}/addons/metabase/`,
46
+ },
47
+ otoroshi: {
48
+ name: 'Otoroshi with LLM',
49
+ isOperator: true,
50
+ postCreateInstructions: `Learn more about Otoroshi with LLM on Clever Cloud: ${conf.DOC_URL}/addons/otoroshi/`,
51
+ },
52
+ 'addon-pulsar': {
53
+ name: 'Pulsar',
54
+ isOperator: false,
55
+ postCreateInstructions: `Learn more about Pulsar on Clever Cloud: ${conf.DOC_URL}/addons/pulsar/`,
56
+ },
57
+ };
58
+
59
+ export const addonCreateCommand = defineCommand({
60
+ description: 'Create an add-on',
61
+ since: '0.2.3',
62
+ options: {
63
+ link: defineOption({
64
+ name: 'link',
65
+ schema: z.string().optional(),
66
+ description: 'Link the created add-on to the app with the specified alias',
67
+ aliases: ['l'],
68
+ placeholder: 'alias',
69
+ complete: listAvailableAliases,
70
+ }),
71
+ yes: defineOption({
72
+ name: 'yes',
73
+ schema: z.boolean().default(false),
74
+ description: 'Skip confirmation even if the add-on is not free',
75
+ aliases: ['y'],
76
+ }),
77
+ plan: defineOption({
78
+ name: 'plan',
79
+ schema: z.string().default(''),
80
+ description: 'Add-on plan, depends on the provider',
81
+ aliases: ['p'],
82
+ placeholder: 'plan',
83
+ complete: completePlan,
84
+ }),
85
+ region: defineOption({
86
+ name: 'region',
87
+ schema: z.string().default('par'),
88
+ description: 'Region to provision the add-on in, depends on the provider',
89
+ aliases: ['r'],
90
+ placeholder: 'region',
91
+ complete: completeRegion,
92
+ }),
93
+ version: defineOption({
94
+ name: 'addon-version',
95
+ schema: z.string().optional(),
96
+ description: 'The version to use for the add-on',
97
+ placeholder: 'addon-version',
98
+ }),
99
+ option: defineOption({
100
+ name: 'option',
101
+ schema: z.string().transform(addonOptions).optional(),
102
+ description:
103
+ 'Option to enable for the add-on. Multiple --option argument can be passed to enable multiple options',
104
+ placeholder: 'option',
105
+ }),
106
+ org: orgaIdOrNameOption,
107
+ format: humanJsonOutputFormatOption,
108
+ },
109
+ args: [addonProviderArg, addonNameArg],
110
+ async handler(options, providerName, name) {
111
+ const {
112
+ link: linkedAppAlias,
113
+ plan: planName,
114
+ region,
115
+ yes: skipConfirmation,
116
+ org: orgaIdOrName,
117
+ format,
118
+ version,
119
+ option: addonOptions,
120
+ } = options;
121
+
122
+ const addonToCreate = {
123
+ name,
124
+ providerName,
125
+ planName,
126
+ region,
127
+ skipConfirmation,
128
+ version: version,
129
+ addonOptions: parseAddonOptions(addonOptions),
130
+ };
131
+
132
+ const ownerId = orgaIdOrName != null ? await Organisation.getId(orgaIdOrName) : await User.getCurrentId();
133
+ if (linkedAppAlias != null) {
134
+ const linkedAppData = await AppConfig.getAppDetails({ alias: linkedAppAlias });
135
+ if (orgaIdOrName != null && linkedAppData.ownerId !== ownerId && format === 'human') {
136
+ Logger.warn(
137
+ 'The specified application does not belong to the specified organisation. Ignoring the `--org` option',
138
+ );
139
+ }
140
+ addonToCreate.ownerId = linkedAppData.ownerId;
141
+ } else {
142
+ addonToCreate.ownerId = ownerId;
143
+ }
144
+
145
+ const newAddon = await Addon.create(addonToCreate);
146
+
147
+ if (linkedAppAlias != null) {
148
+ const linkedAppData = await AppConfig.getAppDetails({ alias: linkedAppAlias });
149
+ await Addon.link(linkedAppData.ownerId, linkedAppData.appId, { addon_id: newAddon.id });
150
+ }
151
+
152
+ const provider = ADDON_PROVIDERS[providerName];
153
+ let statusMessage = '';
154
+ if (provider?.status) {
155
+ statusMessage = `The ${provider.name} provider is in ${provider.status} testing phase`;
156
+ if (provider.status === 'alpha') {
157
+ statusMessage += ". Don't store sensitive or production grade data.";
158
+ }
159
+ }
160
+
161
+ // JSON format
162
+ if (format === 'json') {
163
+ const jsonAddon = {
164
+ id: newAddon.id,
165
+ realId: newAddon.realId,
166
+ name: newAddon.name,
167
+ env: newAddon.env,
168
+ };
169
+
170
+ if (provider?.status) {
171
+ jsonAddon.availability = provider.status;
172
+ jsonAddon.message = statusMessage;
173
+ }
174
+
175
+ Logger.printJson(jsonAddon);
176
+ return;
177
+ }
178
+
179
+ // Human format
180
+ if (linkedAppAlias != null) {
181
+ Logger.println(`Add-on created and linked to application ${linkedAppAlias} successfully!`);
182
+ } else {
183
+ Logger.println('Add-on created successfully!');
184
+ }
185
+
186
+ Logger.println(`ID: ${newAddon.id}`);
187
+ Logger.println(`Real ID: ${newAddon.realId}`);
188
+ Logger.println(`Name: ${newAddon.name}`);
189
+
190
+ const operator = ADDON_PROVIDERS[providerName]?.isOperator
191
+ ? await getOperator({ provider: providerName, realId: newAddon.realId }).then(sendToApi)
192
+ : null;
193
+
194
+ if (operator) {
195
+ if (operator.accessUrl) {
196
+ Logger.println();
197
+ Logger.println(`Your ${ADDON_PROVIDERS[providerName].name} is starting:`);
198
+ Logger.println(` - Access it: ${operator.accessUrl}`);
199
+ Logger.println(` - Manage it: ${conf.GOTO_URL}/${newAddon.id}`);
200
+ }
201
+
202
+ if (operator.initialCredentials) {
203
+ if (providerName === 'keycloak') {
204
+ Logger.println();
205
+ Logger.println(
206
+ "An initial account has been created, you'll be invited to change the password at first login:",
207
+ );
208
+ Logger.println(` - Admin user name: ${operator.initialCredentials.user}`);
209
+ Logger.println(` - Temporary password: ${operator.initialCredentials.password}`);
210
+ }
211
+ if (providerName === 'otoroshi') {
212
+ Logger.println();
213
+ Logger.println(
214
+ 'An initial account has been created, change the password at first login (Security -> Administrators -> Edit user):',
215
+ );
216
+ Logger.println(` - Admin user name: ${operator.initialCredentials.user}`);
217
+ Logger.println(` - Password: ${operator.initialCredentials.password}`);
218
+ }
219
+ }
220
+ }
221
+
222
+ if (provider?.postCreateInstructions) {
223
+ Logger.println();
224
+
225
+ if (statusMessage !== '') {
226
+ Logger.println(styleText('yellow', `/!\\ ${statusMessage}`));
227
+ }
228
+
229
+ if (typeof provider.postCreateInstructions === 'function') {
230
+ Logger.println(provider.postCreateInstructions(newAddon.id));
231
+ } else {
232
+ Logger.println(provider.postCreateInstructions);
233
+ }
234
+ }
235
+ },
236
+ });
@@ -0,0 +1,32 @@
1
+ import { defineCommand } from '../../lib/define-command.js';
2
+ import { Logger } from '../../logger.js';
3
+ import * as Addon from '../../models/addon.js';
4
+ import * as Organisation from '../../models/organisation.js';
5
+ import { addonIdOrNameArg } from '../global.args.js';
6
+ import { confirmAddonDeletionOption, orgaIdOrNameOption } from '../global.options.js';
7
+
8
+ export const addonDeleteCommand = defineCommand({
9
+ description: 'Delete an add-on',
10
+ since: '0.2.3',
11
+ options: {
12
+ org: orgaIdOrNameOption,
13
+ yes: confirmAddonDeletionOption,
14
+ },
15
+ args: [addonIdOrNameArg],
16
+ async handler(options, addon) {
17
+ const { yes: skipConfirmation, org: orgaIdOrName } = options;
18
+
19
+ let ownerId = await Organisation.getId(orgaIdOrName);
20
+ if (ownerId == null && addon.addon_id != null) {
21
+ ownerId = await Addon.findOwnerId(ownerId, addon.addon_id);
22
+ }
23
+ if (ownerId == null && addon.addon_name != null) {
24
+ const foundAddon = await Addon.findByName(addon.addon_name);
25
+ ownerId = foundAddon.orgaId;
26
+ }
27
+
28
+ await Addon.deleteAddon(ownerId, addon, skipConfirmation);
29
+
30
+ Logger.println(`Addon ${addon.addon_id || addon.addon_name} successfully deleted`);
31
+ },
32
+ });
@@ -0,0 +1,156 @@
1
+ # 📖 `clever addon` command reference
2
+
3
+ ## ➡️ `clever addon` <kbd>Since 0.2.3</kbd>
4
+
5
+ Manage add-ons
6
+
7
+ ```bash
8
+ clever addon [options]
9
+ ```
10
+
11
+ ### ⚙️ Options
12
+
13
+ |Name|Description|
14
+ |---|---|
15
+ |`-F`, `--format` `<format>`|Output format (human, json) (default: human)|
16
+ |`-o`, `--org`, `--owner` `<org-id\|org-name>`|Organisation to target by its ID (or name, if unambiguous)|
17
+
18
+ ## ➡️ `clever addon create` <kbd>Since 0.2.3</kbd>
19
+
20
+ Create an add-on
21
+
22
+ ```bash
23
+ clever addon create <addon-provider> <addon-name> [options]
24
+ ```
25
+
26
+ ### 📥 Arguments
27
+
28
+ |Name|Description|
29
+ |---|---|
30
+ |`addon-provider`|Add-on provider|
31
+ |`addon-name`|Add-on name|
32
+
33
+ ### ⚙️ Options
34
+
35
+ |Name|Description|
36
+ |---|---|
37
+ |`--addon-version` `<addon-version>`|The version to use for the add-on|
38
+ |`-F`, `--format` `<format>`|Output format (human, json) (default: human)|
39
+ |`-l`, `--link` `<alias>`|Link the created add-on to the app with the specified alias|
40
+ |`--option` `<option>`|Option to enable for the add-on. Multiple --option argument can be passed to enable multiple options|
41
+ |`-o`, `--org`, `--owner` `<org-id\|org-name>`|Organisation to target by its ID (or name, if unambiguous)|
42
+ |`-p`, `--plan` `<plan>`|Add-on plan, depends on the provider|
43
+ |`-r`, `--region` `<region>`|Region to provision the add-on in, depends on the provider (default: par)|
44
+ |`-y`, `--yes`|Skip confirmation even if the add-on is not free|
45
+
46
+ ## ➡️ `clever addon delete` <kbd>Since 0.2.3</kbd>
47
+
48
+ Delete an add-on
49
+
50
+ ```bash
51
+ clever addon delete <addon-id|addon-name> [options]
52
+ ```
53
+
54
+ ### 📥 Arguments
55
+
56
+ |Name|Description|
57
+ |---|---|
58
+ |`addon-id|addon-name`|Add-on ID (or name, if unambiguous)|
59
+
60
+ ### ⚙️ Options
61
+
62
+ |Name|Description|
63
+ |---|---|
64
+ |`-o`, `--org`, `--owner` `<org-id\|org-name>`|Organisation to target by its ID (or name, if unambiguous)|
65
+ |`-y`, `--yes`|Skip confirmation and delete the add-on directly|
66
+
67
+ ## ➡️ `clever addon env` <kbd>Since 2.11.0</kbd>
68
+
69
+ List environment variables for an add-on
70
+
71
+ ```bash
72
+ clever addon env <addon-id> [options]
73
+ ```
74
+
75
+ ### 📥 Arguments
76
+
77
+ |Name|Description|
78
+ |---|---|
79
+ |`addon-id`|Add-on ID or real ID|
80
+
81
+ ### ⚙️ Options
82
+
83
+ |Name|Description|
84
+ |---|---|
85
+ |`-F`, `--format` `<format>`|Output format (human, json, shell) (default: human)|
86
+ |`-o`, `--org`, `--owner` `<org-id\|org-name>`|Organisation to target by its ID (or name, if unambiguous)|
87
+
88
+ ## ➡️ `clever addon list` <kbd>Since 0.2.3</kbd>
89
+
90
+ List available add-ons
91
+
92
+ ```bash
93
+ clever addon list [options]
94
+ ```
95
+
96
+ ### ⚙️ Options
97
+
98
+ |Name|Description|
99
+ |---|---|
100
+ |`-F`, `--format` `<format>`|Output format (human, json) (default: human)|
101
+ |`-o`, `--org`, `--owner` `<org-id\|org-name>`|Organisation to target by its ID (or name, if unambiguous)|
102
+
103
+ ## ➡️ `clever addon providers` <kbd>Since 0.2.3</kbd>
104
+
105
+ List available add-on providers
106
+
107
+ ```bash
108
+ clever addon providers [options]
109
+ ```
110
+
111
+ ### ⚙️ Options
112
+
113
+ |Name|Description|
114
+ |---|---|
115
+ |`-F`, `--format` `<format>`|Output format (human, json) (default: human)|
116
+
117
+ ## ➡️ `clever addon providers show` <kbd>Since 0.2.3</kbd>
118
+
119
+ Show information about an add-on provider
120
+
121
+ ```bash
122
+ clever addon providers show <addon-provider> [options]
123
+ ```
124
+
125
+ ### 📥 Arguments
126
+
127
+ |Name|Description|
128
+ |---|---|
129
+ |`addon-provider`|Add-on provider|
130
+
131
+ ### ⚙️ Options
132
+
133
+ |Name|Description|
134
+ |---|---|
135
+ |`-F`, `--format` `<format>`|Output format (human, json) (default: human)|
136
+
137
+ ## ➡️ `clever addon rename` <kbd>Since 0.3.0</kbd>
138
+
139
+ Rename an add-on
140
+
141
+ ```bash
142
+ clever addon rename <addon-id|addon-name> <addon-name> [options]
143
+ ```
144
+
145
+ ### 📥 Arguments
146
+
147
+ |Name|Description|
148
+ |---|---|
149
+ |`addon-id|addon-name`|Add-on ID (or name, if unambiguous)|
150
+ |`addon-name`|Add-on name|
151
+
152
+ ### ⚙️ Options
153
+
154
+ |Name|Description|
155
+ |---|---|
156
+ |`-o`, `--org`, `--owner` `<org-id\|org-name>`|Organisation to target by its ID (or name, if unambiguous)|
@@ -0,0 +1,50 @@
1
+ import { getAllEnvVars } from '@clevercloud/client/esm/api/v2/addon.js';
2
+ import { toNameEqualsValueString } from '@clevercloud/client/esm/utils/env-vars.js';
3
+ import { z } from 'zod';
4
+ import { defineArgument } from '../../lib/define-argument.js';
5
+ import { defineCommand } from '../../lib/define-command.js';
6
+ import { Logger } from '../../logger.js';
7
+ import { findOwnerId } from '../../models/addon.js';
8
+ import { resolveAddonId } from '../../models/ids-resolver.js';
9
+ import { sendToApi } from '../../models/send-to-api.js';
10
+ import { envFormatOption, orgaIdOrNameOption } from '../global.options.js';
11
+
12
+ export const addonEnvCommand = defineCommand({
13
+ description: 'List environment variables for an add-on',
14
+ since: '2.11.0',
15
+ options: {
16
+ org: orgaIdOrNameOption,
17
+ format: envFormatOption,
18
+ },
19
+ args: [
20
+ defineArgument({
21
+ schema: z.string(),
22
+ description: 'Add-on ID or real ID',
23
+ placeholder: 'addon-id',
24
+ }),
25
+ ],
26
+ async handler(options, addonIdOrRealId) {
27
+ const { org, format } = options;
28
+
29
+ const addonId = await resolveAddonId(addonIdOrRealId);
30
+ const ownerId = await findOwnerId(org, addonId);
31
+
32
+ const envFromAddon = await getAllEnvVars({ id: ownerId, addonId }).then(sendToApi);
33
+
34
+ switch (format) {
35
+ case 'json': {
36
+ const envFromAddonJson = Object.fromEntries(envFromAddon.map(({ name, value }) => [name, value]));
37
+ Logger.println(JSON.stringify(envFromAddonJson, null, 2));
38
+ break;
39
+ }
40
+
41
+ case 'shell':
42
+ Logger.println(toNameEqualsValueString(envFromAddon, { addExports: true }));
43
+ break;
44
+
45
+ case 'human':
46
+ default:
47
+ Logger.println(toNameEqualsValueString(envFromAddon, { addExports: false }));
48
+ }
49
+ },
50
+ });
@@ -0,0 +1,55 @@
1
+ import { formatTable } from '../../format-table.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 Addon from '../../models/addon.js';
6
+ import * as Organisation from '../../models/organisation.js';
7
+ import { humanJsonOutputFormatOption, orgaIdOrNameOption } from '../global.options.js';
8
+
9
+ export const addonListCommand = defineCommand({
10
+ description: 'List available add-ons',
11
+ since: '0.2.3',
12
+ options: {
13
+ org: orgaIdOrNameOption,
14
+ format: humanJsonOutputFormatOption,
15
+ },
16
+ args: [],
17
+ async handler(options) {
18
+ const { org: orgaIdOrName, format } = options;
19
+
20
+ const ownerId = await Organisation.getId(orgaIdOrName);
21
+ const addons = await Addon.list(ownerId);
22
+
23
+ switch (format) {
24
+ case 'json': {
25
+ const formattedAddons = addons.map((addon) => {
26
+ return {
27
+ addonId: addon.id,
28
+ creationDate: addon.creationDate,
29
+ name: addon.name,
30
+ planName: addon.plan.name,
31
+ planSlug: addon.plan.slug,
32
+ providerId: addon.provider.id,
33
+ realId: addon.realId,
34
+ region: addon.region,
35
+ type: addon.provider.name,
36
+ };
37
+ });
38
+ Logger.printJson(formattedAddons);
39
+ break;
40
+ }
41
+ case 'human':
42
+ default: {
43
+ const formattedAddons = addons.map((addon) => {
44
+ return [
45
+ addon.plan.name + ' ' + addon.provider.name,
46
+ addon.region,
47
+ styleText(['bold', 'green'], addon.name),
48
+ addon.id,
49
+ ];
50
+ });
51
+ Logger.println(formatTable(formattedAddons));
52
+ }
53
+ }
54
+ },
55
+ });
@@ -0,0 +1,45 @@
1
+ import { formatTable } from '../../format-table.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 Addon from '../../models/addon.js';
6
+ import { humanJsonOutputFormatOption } from '../global.options.js';
7
+
8
+ export const addonProvidersCommand = defineCommand({
9
+ description: 'List available add-on providers',
10
+ since: '0.2.3',
11
+ options: {
12
+ format: humanJsonOutputFormatOption,
13
+ },
14
+ args: [],
15
+ async handler(options) {
16
+ const { format } = options;
17
+
18
+ const providers = await Addon.listProviders();
19
+
20
+ switch (format) {
21
+ case 'json': {
22
+ const formattedProviders = providers.map((provider) => ({
23
+ id: provider.id,
24
+ name: provider.name,
25
+ shortDesc: provider.shortDesc,
26
+ regions: provider.regions,
27
+ plans: provider.plans.map((plan) => ({
28
+ id: plan.id,
29
+ name: plan.name,
30
+ slug: plan.slug,
31
+ })),
32
+ }));
33
+ Logger.printJson(formattedProviders);
34
+ break;
35
+ }
36
+ case 'human':
37
+ default: {
38
+ const formattedProviders = providers.map((provider) => {
39
+ return [styleText('bold', provider.id), provider.name, provider.shortDesc || ''];
40
+ });
41
+ Logger.println(formatTable(formattedProviders));
42
+ }
43
+ }
44
+ },
45
+ });
@@ -0,0 +1,99 @@
1
+ import { defineCommand } from '../../lib/define-command.js';
2
+ import { styleText } from '../../lib/style-text.js';
3
+ import { Logger } from '../../logger.js';
4
+ import * as Addon from '../../models/addon.js';
5
+ import { humanJsonOutputFormatOption } from '../global.options.js';
6
+ import { addonProviderArg } from './addon.args.js';
7
+
8
+ export const addonProvidersShowCommand = defineCommand({
9
+ description: 'Show information about an add-on provider',
10
+ since: '0.2.3',
11
+ options: {
12
+ format: humanJsonOutputFormatOption,
13
+ },
14
+ args: [addonProviderArg],
15
+ async handler(options, providerName) {
16
+ const { format } = options;
17
+
18
+ const provider = await Addon.getProvider(providerName);
19
+ const providerInfos = await Addon.getProviderInfos(providerName);
20
+
21
+ const formattedPlans = [...provider.plans]
22
+ .sort((a, b) => a.price - b.price)
23
+ .map((plan) => {
24
+ const formattedFeatures = plan.features
25
+ .map((feature) => ({
26
+ name: feature.name,
27
+ value: feature.value,
28
+ }))
29
+ .sort((a, b) => a.name.localeCompare(b.name));
30
+
31
+ const formattedPlan = {
32
+ id: plan.id,
33
+ name: plan.name,
34
+ slug: plan.slug,
35
+ features: formattedFeatures,
36
+ };
37
+
38
+ if (providerInfos != null) {
39
+ const planType = plan.features.find(({ name }) => name.toLowerCase() === 'type');
40
+ if (planType != null && planType.value.toLowerCase() === 'dedicated') {
41
+ const planVersions = Object.keys(providerInfos.dedicated);
42
+ formattedPlan.versions = planVersions.map((version) => {
43
+ return {
44
+ version,
45
+ isDefault: version === providerInfos.defaultDedicatedVersion,
46
+ features: providerInfos.dedicated[version].features.map((feature) => ({
47
+ name: feature.name,
48
+ enabledByDefault: feature.enabled,
49
+ })),
50
+ };
51
+ });
52
+ }
53
+ }
54
+
55
+ return formattedPlan;
56
+ });
57
+
58
+ const formattedProvider = {
59
+ id: provider.id,
60
+ name: provider.name,
61
+ shortDesc: provider.shortDesc,
62
+ regions: provider.regions,
63
+ plans: formattedPlans,
64
+ };
65
+
66
+ switch (format) {
67
+ case 'json': {
68
+ Logger.printJson(formattedProvider);
69
+ break;
70
+ }
71
+ case 'human':
72
+ default: {
73
+ Logger.println(styleText('bold', formattedProvider.id));
74
+ Logger.println(`${formattedProvider.name}: ${formattedProvider.shortDesc}`);
75
+ Logger.println();
76
+ Logger.println(`Available regions: ${formattedProvider.regions.join(', ')}`);
77
+ Logger.println();
78
+ Logger.println('Available plans');
79
+
80
+ formattedProvider.plans.forEach((plan) => {
81
+ Logger.println(`Plan ${styleText('bold', plan.slug)}`);
82
+ plan.features.forEach(({ name, value }) => Logger.println(` ${name}: ${value}`));
83
+
84
+ if (plan.versions != null) {
85
+ Logger.println(
86
+ ` Available versions: ${plan.versions.map(({ version, isDefault }) => (isDefault ? `${version} (default)` : version)).join(', ')}`,
87
+ );
88
+ plan.versions.forEach(({ version, features }) => {
89
+ Logger.println(` Options for version ${version}:`);
90
+ features.forEach(({ name, enabledByDefault }) => {
91
+ Logger.println(` ${name}: default=${enabledByDefault}`);
92
+ });
93
+ });
94
+ }
95
+ });
96
+ }
97
+ }
98
+ },
99
+ });
@@ -0,0 +1,24 @@
1
+ import { defineCommand } from '../../lib/define-command.js';
2
+ import { Logger } from '../../logger.js';
3
+ import * as Addon from '../../models/addon.js';
4
+ import * as Organisation from '../../models/organisation.js';
5
+ import { addonIdOrNameArg } from '../global.args.js';
6
+ import { orgaIdOrNameOption } from '../global.options.js';
7
+ import { addonNameArg } from './addon.args.js';
8
+
9
+ export const addonRenameCommand = defineCommand({
10
+ description: 'Rename an add-on',
11
+ since: '0.3.0',
12
+ options: {
13
+ org: orgaIdOrNameOption,
14
+ },
15
+ args: [addonIdOrNameArg, addonNameArg],
16
+ async handler(options, addon, newName) {
17
+ const { org: orgaIdOrName } = options;
18
+
19
+ const ownerId = await Organisation.getId(orgaIdOrName);
20
+ await Addon.rename(ownerId, addon, newName);
21
+
22
+ Logger.println(`Addon ${addon.addon_id || addon.addon_name} successfully renamed to ${newName}`);
23
+ },
24
+ });