krates 1.6.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 (293) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +212 -0
  3. data/LOGO +10 -0
  4. data/VERSION +1 -0
  5. data/bin/krates +23 -0
  6. data/lib/kontena/autoload_core.rb +19 -0
  7. data/lib/kontena/callback.rb +60 -0
  8. data/lib/kontena/callbacks/.gitkeep +0 -0
  9. data/lib/kontena/callbacks/auth/01_list_and_select_grid_after_master_auth.rb +26 -0
  10. data/lib/kontena/callbacks/master/01_clear_current_master_after_terminate.rb +19 -0
  11. data/lib/kontena/callbacks/master/deploy/01_show_logo_before_deploy.rb +14 -0
  12. data/lib/kontena/callbacks/master/deploy/04_default_master_version.rb +18 -0
  13. data/lib/kontena/callbacks/master/deploy/05_before_deploy_configuration_wizard.rb +105 -0
  14. data/lib/kontena/callbacks/master/deploy/40_install_ssl_certificate_after_deploy.rb +32 -0
  15. data/lib/kontena/callbacks/master/deploy/50_authenticate_after_deploy.rb +66 -0
  16. data/lib/kontena/callbacks/master/deploy/55_create_initial_grid_after_deploy.rb +21 -0
  17. data/lib/kontena/callbacks/master/deploy/56_set_server_provider_after_deploy.rb +24 -0
  18. data/lib/kontena/callbacks/master/deploy/60_configure_auth_provider_after_deploy.rb +31 -0
  19. data/lib/kontena/callbacks/master/deploy/70_invite_self_after_deploy.rb +95 -0
  20. data/lib/kontena/callbacks/master/deploy/90_proptip_after_deploy.rb +33 -0
  21. data/lib/kontena/cli/browser_launcher.rb +61 -0
  22. data/lib/kontena/cli/bytes_helper.rb +40 -0
  23. data/lib/kontena/cli/certificate/authorize_command.rb +107 -0
  24. data/lib/kontena/cli/certificate/common.rb +16 -0
  25. data/lib/kontena/cli/certificate/domain_authorization/list_command.rb +24 -0
  26. data/lib/kontena/cli/certificate/domain_authorization/remove_authorization_command.rb +25 -0
  27. data/lib/kontena/cli/certificate/domain_authorize_command.rb +7 -0
  28. data/lib/kontena/cli/certificate/export_command.rb +28 -0
  29. data/lib/kontena/cli/certificate/get_command.rb +33 -0
  30. data/lib/kontena/cli/certificate/import_command.rb +61 -0
  31. data/lib/kontena/cli/certificate/list_command.rb +75 -0
  32. data/lib/kontena/cli/certificate/register_command.rb +30 -0
  33. data/lib/kontena/cli/certificate/remove_command.rb +23 -0
  34. data/lib/kontena/cli/certificate/request_command.rb +20 -0
  35. data/lib/kontena/cli/certificate/show_command.rb +22 -0
  36. data/lib/kontena/cli/certificate_command.rb +18 -0
  37. data/lib/kontena/cli/cloud/login_command.rb +186 -0
  38. data/lib/kontena/cli/cloud/logout_command.rb +14 -0
  39. data/lib/kontena/cli/cloud/master/add_command.rb +156 -0
  40. data/lib/kontena/cli/cloud/master/list_command.rb +35 -0
  41. data/lib/kontena/cli/cloud/master/remove_command.rb +68 -0
  42. data/lib/kontena/cli/cloud/master/show_command.rb +21 -0
  43. data/lib/kontena/cli/cloud/master/update_command.rb +52 -0
  44. data/lib/kontena/cli/cloud/master_command.rb +14 -0
  45. data/lib/kontena/cli/cloud_command.rb +13 -0
  46. data/lib/kontena/cli/common.rb +360 -0
  47. data/lib/kontena/cli/config.rb +662 -0
  48. data/lib/kontena/cli/container_command.rb +10 -0
  49. data/lib/kontena/cli/containers/exec_command.rb +31 -0
  50. data/lib/kontena/cli/containers/inspect_command.rb +16 -0
  51. data/lib/kontena/cli/containers/list_command.rb +51 -0
  52. data/lib/kontena/cli/containers/logs_command.rb +19 -0
  53. data/lib/kontena/cli/etcd/common.rb +8 -0
  54. data/lib/kontena/cli/etcd/get_command.rb +26 -0
  55. data/lib/kontena/cli/etcd/health_command.rb +53 -0
  56. data/lib/kontena/cli/etcd/list_command.rb +36 -0
  57. data/lib/kontena/cli/etcd/mkdir_command.rb +23 -0
  58. data/lib/kontena/cli/etcd/remove_command.rb +29 -0
  59. data/lib/kontena/cli/etcd/set_command.rb +24 -0
  60. data/lib/kontena/cli/etcd_command.rb +12 -0
  61. data/lib/kontena/cli/external_registries/add_command.rb +25 -0
  62. data/lib/kontena/cli/external_registries/list_command.rb +23 -0
  63. data/lib/kontena/cli/external_registries/remove_command.rb +17 -0
  64. data/lib/kontena/cli/external_registry_command.rb +9 -0
  65. data/lib/kontena/cli/grid_command.rb +21 -0
  66. data/lib/kontena/cli/grid_options.rb +12 -0
  67. data/lib/kontena/cli/grids/audit_log_command.rb +22 -0
  68. data/lib/kontena/cli/grids/cloud_config_command.rb +53 -0
  69. data/lib/kontena/cli/grids/common.rb +182 -0
  70. data/lib/kontena/cli/grids/create_command.rb +48 -0
  71. data/lib/kontena/cli/grids/current_command.rb +25 -0
  72. data/lib/kontena/cli/grids/env_command.rb +32 -0
  73. data/lib/kontena/cli/grids/events_command.rb +50 -0
  74. data/lib/kontena/cli/grids/health_command.rb +69 -0
  75. data/lib/kontena/cli/grids/list_command.rb +59 -0
  76. data/lib/kontena/cli/grids/logs_command.rb +35 -0
  77. data/lib/kontena/cli/grids/remove_command.rb +31 -0
  78. data/lib/kontena/cli/grids/show_command.rb +25 -0
  79. data/lib/kontena/cli/grids/trusted_subnet_command.rb +10 -0
  80. data/lib/kontena/cli/grids/trusted_subnets/add_command.rb +18 -0
  81. data/lib/kontena/cli/grids/trusted_subnets/list_command.rb +18 -0
  82. data/lib/kontena/cli/grids/trusted_subnets/remove_command.rb +26 -0
  83. data/lib/kontena/cli/grids/update_command.rb +35 -0
  84. data/lib/kontena/cli/grids/use_command.rb +26 -0
  85. data/lib/kontena/cli/grids/user_command.rb +9 -0
  86. data/lib/kontena/cli/grids/users/add_command.rb +18 -0
  87. data/lib/kontena/cli/grids/users/list_command.rb +20 -0
  88. data/lib/kontena/cli/grids/users/remove_command.rb +20 -0
  89. data/lib/kontena/cli/helpers/exec_helper.rb +209 -0
  90. data/lib/kontena/cli/helpers/health_helper.rb +65 -0
  91. data/lib/kontena/cli/helpers/log_helper.rb +113 -0
  92. data/lib/kontena/cli/helpers/time_helper.rb +29 -0
  93. data/lib/kontena/cli/localhost_web_server.rb +113 -0
  94. data/lib/kontena/cli/log_formatters/compact.rb +65 -0
  95. data/lib/kontena/cli/log_formatters/strip_color.rb +13 -0
  96. data/lib/kontena/cli/logout_command.rb +10 -0
  97. data/lib/kontena/cli/master/audit_log_command.rb +19 -0
  98. data/lib/kontena/cli/master/config/export_command.rb +46 -0
  99. data/lib/kontena/cli/master/config/get_command.rb +26 -0
  100. data/lib/kontena/cli/master/config/import_command.rb +67 -0
  101. data/lib/kontena/cli/master/config/set_command.rb +19 -0
  102. data/lib/kontena/cli/master/config/unset_command.rb +20 -0
  103. data/lib/kontena/cli/master/config_command.rb +17 -0
  104. data/lib/kontena/cli/master/create_command.rb +74 -0
  105. data/lib/kontena/cli/master/current_command.rb +25 -0
  106. data/lib/kontena/cli/master/init_cloud_command.rb +45 -0
  107. data/lib/kontena/cli/master/join_command.rb +22 -0
  108. data/lib/kontena/cli/master/list_command.rb +24 -0
  109. data/lib/kontena/cli/master/login_command.rb +331 -0
  110. data/lib/kontena/cli/master/logout_command.rb +25 -0
  111. data/lib/kontena/cli/master/remove_command.rb +55 -0
  112. data/lib/kontena/cli/master/ssh_command.rb +72 -0
  113. data/lib/kontena/cli/master/token/common.rb +29 -0
  114. data/lib/kontena/cli/master/token/create_command.rb +50 -0
  115. data/lib/kontena/cli/master/token/current_command.rb +45 -0
  116. data/lib/kontena/cli/master/token/list_command.rb +39 -0
  117. data/lib/kontena/cli/master/token/remove_command.rb +19 -0
  118. data/lib/kontena/cli/master/token/show_command.rb +34 -0
  119. data/lib/kontena/cli/master/token_command.rb +13 -0
  120. data/lib/kontena/cli/master/use_command.rb +31 -0
  121. data/lib/kontena/cli/master/user/invite_command.rb +51 -0
  122. data/lib/kontena/cli/master/user/list_command.rb +29 -0
  123. data/lib/kontena/cli/master/user/remove_command.rb +24 -0
  124. data/lib/kontena/cli/master/user/role/add_command.rb +29 -0
  125. data/lib/kontena/cli/master/user/role/remove_command.rb +27 -0
  126. data/lib/kontena/cli/master/user/role_command.rb +6 -0
  127. data/lib/kontena/cli/master/user_command.rb +9 -0
  128. data/lib/kontena/cli/master_command.rb +21 -0
  129. data/lib/kontena/cli/node_command.rb +17 -0
  130. data/lib/kontena/cli/nodes/create_command.rb +25 -0
  131. data/lib/kontena/cli/nodes/env_command.rb +37 -0
  132. data/lib/kontena/cli/nodes/health_command.rb +47 -0
  133. data/lib/kontena/cli/nodes/label_command.rb +10 -0
  134. data/lib/kontena/cli/nodes/labels/add_command.rb +18 -0
  135. data/lib/kontena/cli/nodes/labels/list_command.rb +19 -0
  136. data/lib/kontena/cli/nodes/labels/remove_command.rb +32 -0
  137. data/lib/kontena/cli/nodes/list_command.rb +97 -0
  138. data/lib/kontena/cli/nodes/remove_command.rb +34 -0
  139. data/lib/kontena/cli/nodes/reset_token_command.rb +34 -0
  140. data/lib/kontena/cli/nodes/show_command.rb +56 -0
  141. data/lib/kontena/cli/nodes/ssh_command.rb +63 -0
  142. data/lib/kontena/cli/nodes/update_command.rb +31 -0
  143. data/lib/kontena/cli/plugin_command.rb +12 -0
  144. data/lib/kontena/cli/plugins/common.rb +8 -0
  145. data/lib/kontena/cli/plugins/install_command.rb +42 -0
  146. data/lib/kontena/cli/plugins/list_command.rb +31 -0
  147. data/lib/kontena/cli/plugins/search_command.rb +25 -0
  148. data/lib/kontena/cli/plugins/show_command.rb +17 -0
  149. data/lib/kontena/cli/plugins/uninstall_command.rb +31 -0
  150. data/lib/kontena/cli/plugins/upgrade_command.rb +60 -0
  151. data/lib/kontena/cli/registry/create_command.rb +151 -0
  152. data/lib/kontena/cli/registry/remove_command.rb +21 -0
  153. data/lib/kontena/cli/registry_command.rb +8 -0
  154. data/lib/kontena/cli/service_command.rb +28 -0
  155. data/lib/kontena/cli/services/container_command.rb +8 -0
  156. data/lib/kontena/cli/services/containers_command.rb +39 -0
  157. data/lib/kontena/cli/services/create_command.rb +105 -0
  158. data/lib/kontena/cli/services/deploy_command.rb +25 -0
  159. data/lib/kontena/cli/services/env_command.rb +9 -0
  160. data/lib/kontena/cli/services/envs/add_command.rb +21 -0
  161. data/lib/kontena/cli/services/envs/list_command.rb +22 -0
  162. data/lib/kontena/cli/services/envs/remove_command.rb +22 -0
  163. data/lib/kontena/cli/services/events_command.rb +36 -0
  164. data/lib/kontena/cli/services/exec_command.rb +107 -0
  165. data/lib/kontena/cli/services/link_command.rb +35 -0
  166. data/lib/kontena/cli/services/list_command.rb +66 -0
  167. data/lib/kontena/cli/services/logs_command.rb +33 -0
  168. data/lib/kontena/cli/services/monitor_command.rb +58 -0
  169. data/lib/kontena/cli/services/remove_command.rb +60 -0
  170. data/lib/kontena/cli/services/restart_command.rb +19 -0
  171. data/lib/kontena/cli/services/scale_command.rb +21 -0
  172. data/lib/kontena/cli/services/secret_command.rb +8 -0
  173. data/lib/kontena/cli/services/secrets/link_command.rb +26 -0
  174. data/lib/kontena/cli/services/secrets/unlink_command.rb +28 -0
  175. data/lib/kontena/cli/services/services_helper.rb +579 -0
  176. data/lib/kontena/cli/services/show_command.rb +26 -0
  177. data/lib/kontena/cli/services/start_command.rb +21 -0
  178. data/lib/kontena/cli/services/stats_command.rb +87 -0
  179. data/lib/kontena/cli/services/stop_command.rb +21 -0
  180. data/lib/kontena/cli/services/unlink_command.rb +30 -0
  181. data/lib/kontena/cli/services/update_command.rb +94 -0
  182. data/lib/kontena/cli/spinner.rb +205 -0
  183. data/lib/kontena/cli/stack_command.rb +21 -0
  184. data/lib/kontena/cli/stacks/build_command.rb +125 -0
  185. data/lib/kontena/cli/stacks/common.rb +209 -0
  186. data/lib/kontena/cli/stacks/deploy_command.rb +37 -0
  187. data/lib/kontena/cli/stacks/events_command.rb +33 -0
  188. data/lib/kontena/cli/stacks/inspect_command.rb +17 -0
  189. data/lib/kontena/cli/stacks/install_command.rb +95 -0
  190. data/lib/kontena/cli/stacks/label_command.rb +10 -0
  191. data/lib/kontena/cli/stacks/labels/add_command.rb +21 -0
  192. data/lib/kontena/cli/stacks/labels/common.rb +19 -0
  193. data/lib/kontena/cli/stacks/labels/list_command.rb +21 -0
  194. data/lib/kontena/cli/stacks/labels/remove_command.rb +21 -0
  195. data/lib/kontena/cli/stacks/list_command.rb +154 -0
  196. data/lib/kontena/cli/stacks/logs_command.rb +35 -0
  197. data/lib/kontena/cli/stacks/monitor_command.rb +93 -0
  198. data/lib/kontena/cli/stacks/registry/create_command.rb +24 -0
  199. data/lib/kontena/cli/stacks/registry/make_private_command.rb +24 -0
  200. data/lib/kontena/cli/stacks/registry/make_public_command.rb +24 -0
  201. data/lib/kontena/cli/stacks/registry/pull_command.rb +28 -0
  202. data/lib/kontena/cli/stacks/registry/push_command.rb +40 -0
  203. data/lib/kontena/cli/stacks/registry/remove_command.rb +30 -0
  204. data/lib/kontena/cli/stacks/registry/search_command.rb +42 -0
  205. data/lib/kontena/cli/stacks/registry/show_command.rb +65 -0
  206. data/lib/kontena/cli/stacks/registry_command.rb +12 -0
  207. data/lib/kontena/cli/stacks/remove_command.rb +80 -0
  208. data/lib/kontena/cli/stacks/restart_command.rb +24 -0
  209. data/lib/kontena/cli/stacks/service_generator.rb +131 -0
  210. data/lib/kontena/cli/stacks/service_generator_v2.rb +27 -0
  211. data/lib/kontena/cli/stacks/show_command.rb +168 -0
  212. data/lib/kontena/cli/stacks/stack_name.rb +71 -0
  213. data/lib/kontena/cli/stacks/stacks_helper.rb +83 -0
  214. data/lib/kontena/cli/stacks/stop_command.rb +24 -0
  215. data/lib/kontena/cli/stacks/upgrade_command.rb +264 -0
  216. data/lib/kontena/cli/stacks/validate_command.rb +75 -0
  217. data/lib/kontena/cli/stacks/yaml/custom_validators/affinities_validator.rb +19 -0
  218. data/lib/kontena/cli/stacks/yaml/custom_validators/build_validator.rb +22 -0
  219. data/lib/kontena/cli/stacks/yaml/custom_validators/certificates_validator.rb +22 -0
  220. data/lib/kontena/cli/stacks/yaml/custom_validators/extends_validator.rb +22 -0
  221. data/lib/kontena/cli/stacks/yaml/custom_validators/hooks_validator.rb +102 -0
  222. data/lib/kontena/cli/stacks/yaml/custom_validators/secrets_validator.rb +22 -0
  223. data/lib/kontena/cli/stacks/yaml/opto/certificates_resolver.rb +37 -0
  224. data/lib/kontena/cli/stacks/yaml/opto/prompt_resolver.rb +78 -0
  225. data/lib/kontena/cli/stacks/yaml/opto/service_instances_resolver.rb +25 -0
  226. data/lib/kontena/cli/stacks/yaml/opto/service_link_resolver.rb +80 -0
  227. data/lib/kontena/cli/stacks/yaml/opto/vault_cert_prompt_resolver.rb +39 -0
  228. data/lib/kontena/cli/stacks/yaml/opto/vault_resolver.rb +13 -0
  229. data/lib/kontena/cli/stacks/yaml/opto/vault_setter.rb +12 -0
  230. data/lib/kontena/cli/stacks/yaml/opto.rb +16 -0
  231. data/lib/kontena/cli/stacks/yaml/reader.rb +525 -0
  232. data/lib/kontena/cli/stacks/yaml/service_extender.rb +65 -0
  233. data/lib/kontena/cli/stacks/yaml/stack_file_loader/file_loader.rb +41 -0
  234. data/lib/kontena/cli/stacks/yaml/stack_file_loader/registry_loader.rb +24 -0
  235. data/lib/kontena/cli/stacks/yaml/stack_file_loader/uri_loader.rb +23 -0
  236. data/lib/kontena/cli/stacks/yaml/stack_file_loader.rb +152 -0
  237. data/lib/kontena/cli/stacks/yaml/validations.rb +119 -0
  238. data/lib/kontena/cli/stacks/yaml/validator_v3.rb +164 -0
  239. data/lib/kontena/cli/subcommand_loader.rb +83 -0
  240. data/lib/kontena/cli/table_generator.rb +128 -0
  241. data/lib/kontena/cli/vault/export_command.rb +24 -0
  242. data/lib/kontena/cli/vault/import_command.rb +75 -0
  243. data/lib/kontena/cli/vault/list_command.rb +37 -0
  244. data/lib/kontena/cli/vault/read_command.rb +27 -0
  245. data/lib/kontena/cli/vault/remove_command.rb +23 -0
  246. data/lib/kontena/cli/vault/update_command.rb +24 -0
  247. data/lib/kontena/cli/vault/write_command.rb +23 -0
  248. data/lib/kontena/cli/vault_command.rb +13 -0
  249. data/lib/kontena/cli/version.rb +10 -0
  250. data/lib/kontena/cli/version_command.rb +20 -0
  251. data/lib/kontena/cli/volume_command.rb +9 -0
  252. data/lib/kontena/cli/volumes/create_command.rb +42 -0
  253. data/lib/kontena/cli/volumes/list_command.rb +29 -0
  254. data/lib/kontena/cli/volumes/remove_command.rb +29 -0
  255. data/lib/kontena/cli/volumes/show_command.rb +38 -0
  256. data/lib/kontena/cli/vpn/config_command.rb +27 -0
  257. data/lib/kontena/cli/vpn/create_command.rb +99 -0
  258. data/lib/kontena/cli/vpn/remove_command.rb +22 -0
  259. data/lib/kontena/cli/vpn_command.rb +9 -0
  260. data/lib/kontena/cli/whoami_command.rb +38 -0
  261. data/lib/kontena/client.rb +574 -0
  262. data/lib/kontena/command.rb +251 -0
  263. data/lib/kontena/debug_instrumentor.rb +80 -0
  264. data/lib/kontena/errors.rb +50 -0
  265. data/lib/kontena/light_prompt.rb +103 -0
  266. data/lib/kontena/machine/cert_helper.rb +43 -0
  267. data/lib/kontena/machine/cloud_config/cloudinit.yml +82 -0
  268. data/lib/kontena/machine/cloud_config/node_generator.rb +28 -0
  269. data/lib/kontena/machine/common.rb +17 -0
  270. data/lib/kontena/machine/random_name.rb +42 -0
  271. data/lib/kontena/main_command.rb +66 -0
  272. data/lib/kontena/plugin_manager/cleaner.rb +33 -0
  273. data/lib/kontena/plugin_manager/common.rb +89 -0
  274. data/lib/kontena/plugin_manager/installer.rb +78 -0
  275. data/lib/kontena/plugin_manager/loader.rb +93 -0
  276. data/lib/kontena/plugin_manager/rubygems_client.rb +59 -0
  277. data/lib/kontena/plugin_manager/uninstaller.rb +34 -0
  278. data/lib/kontena/plugin_manager.rb +26 -0
  279. data/lib/kontena/presets/github_auth_provider.yml +11 -0
  280. data/lib/kontena/presets/kontena_auth_provider.yml +11 -0
  281. data/lib/kontena/scripts/completer +9 -0
  282. data/lib/kontena/scripts/completer.rb +334 -0
  283. data/lib/kontena/scripts/init +18 -0
  284. data/lib/kontena/scripts/kontena.zsh +11 -0
  285. data/lib/kontena/scripts/krates.bash +8 -0
  286. data/lib/kontena/stacks/change_resolver.rb +118 -0
  287. data/lib/kontena/stacks/stack_data.rb +58 -0
  288. data/lib/kontena/stacks/stack_data_set.rb +51 -0
  289. data/lib/kontena/stacks_cache.rb +110 -0
  290. data/lib/kontena/stacks_client.rb +177 -0
  291. data/lib/kontena/util.rb +116 -0
  292. data/lib/kontena_cli.rb +190 -0
  293. metadata +518 -0
@@ -0,0 +1,24 @@
1
+ module Kontena
2
+ module Callbacks
3
+ class SetServerProviderAfterDeploy < Kontena::Callback
4
+
5
+ matches_commands 'master create'
6
+
7
+ def after
8
+ extend Kontena::Cli::Common
9
+ return unless command.exit_code == 0
10
+ return unless config.current_master
11
+ return unless config.current_master.name == command.result[:name]
12
+ return unless command.result[:provider]
13
+
14
+ require 'shellwords'
15
+
16
+ cmd = ['master', 'config', 'set', "server.provider=#{command.result[:provider]}"]
17
+ spinner "Setting Master configuration server.provider to '#{command.result[:provider]}'" do |spin|
18
+ spin.fail! unless Kontena.run(cmd)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,31 @@
1
+ module Kontena
2
+ module Callbacks
3
+ class ConfigureAuthProviderAfterDeploy < Kontena::Callback
4
+
5
+ matches_commands 'master create'
6
+
7
+ def init_cloud_args
8
+ args = []
9
+ args << '--force'
10
+ args += ["--cloud-master-id", command.cloud_master_id] if command.cloud_master_id
11
+ args += ["--provider", command.result[:provider]] if command.result[:provider]
12
+ args += ["--version", command.result[:version]] if command.result[:version]
13
+ args
14
+ end
15
+
16
+ def after
17
+ extend Kontena::Cli::Common
18
+ return unless command.exit_code == 0
19
+ return unless command.result.kind_of?(Hash)
20
+ return unless command.result.has_key?(:name)
21
+ return unless config.current_master
22
+ return unless config.current_master.name == command.result[:name]
23
+
24
+ unless command.respond_to?(:skip_auth_provider?) && command.skip_auth_provider?
25
+ Kontena.run(['master', 'init-cloud'] + init_cloud_args)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,95 @@
1
+ module Kontena
2
+ module Callbacks
3
+ class InviteSelfAfterDeploy < Kontena::Callback
4
+
5
+ matches_commands 'master create', 'master init_cloud'
6
+
7
+ def cloud_user_data
8
+ return @cloud_user_data if @cloud_user_data
9
+ return nil unless cloud_auth?
10
+ user_data = {}
11
+ response = nil
12
+ spinner "Retrieving user information from Kontena Cloud" do
13
+ response = cloud_client.get(kontena_account.userinfo_endpoint)
14
+ end
15
+ if response && response.kind_of?(Hash) && response.has_key?('data') && response['data'].has_key?('attributes')
16
+ user_data[:email] = response['data']['attributes']['email']
17
+ user_data[:username] = response['data']['attributes']['username']
18
+ user_data[:id] = response['data']['id']
19
+ user_data[:verified] = response['data']['attributes']['verified']
20
+ @cloud_user_data = user_data
21
+ end
22
+ @cloud_user_data
23
+ end
24
+
25
+ def after
26
+ extend Kontena::Cli::Common
27
+ return unless current_master
28
+ return unless command.exit_code == 0
29
+ return nil if command.respond_to?(:skip_auth_provider?) && command.skip_auth_provider?
30
+ return nil unless cloud_user_data
31
+
32
+ invite_response = nil
33
+ spinner "Creating user #{cloud_user_data[:email]} into Kontena Master" do |spin|
34
+ invite_response = Kontena.run(["master", "user", "invite", "--external-id", cloud_user_data[:id], "--return", cloud_user_data[:email]])
35
+ spin.fail! unless invite_response.kind_of?(Hash) && invite_response.has_key?('invite_code')
36
+ end
37
+
38
+ return nil unless invite_response
39
+ logger.debug { "Got invite code: #{invite_response['invite_code']}" }
40
+
41
+ success = spinner "Adding master_admin role for #{cloud_user_data[:email]}" do |spin|
42
+ spin.fail! unless Kontena.run(["master", "user", "role", "add", "--silent", "master_admin", cloud_user_data[:email]])
43
+ true
44
+ end
45
+
46
+ return nil unless success
47
+
48
+ if current_master.grid
49
+ spinner "Adding #{cloud_user_data[:email]} to grid '#{current_master.grid}'" do |spin|
50
+ spin.fail! unless Kontena.run(["grid", "user", "add", "--grid", current_master.grid, cloud_user_data[:email]])
51
+ end
52
+ end
53
+
54
+ return nil unless current_master.username.to_s == 'admin'
55
+
56
+ new_user_token = spinner "Creating an access token for #{cloud_user_data[:email]}" do |spin|
57
+ Kontena.run!(["master", "token", "create", "-e", "0", "-s", "user", "--return", "-u", cloud_user_data[:email]])
58
+ end
59
+
60
+ master_name = current_master.name.dup
61
+ master_url = current_master.url
62
+ old_master = current_master
63
+
64
+ spinner "Copying server '#{current_master.name}' to '#{current_master.name}-admin' in configuration" do
65
+ config.servers << Kontena::Cli::Config::Server.new(
66
+ name: "#{current_master.name}-admin",
67
+ url: current_master.url,
68
+ username: 'admin',
69
+ grid: current_master.grid,
70
+ token: Kontena::Cli::Config::Token.new(
71
+ access_token: current_master.token.access_token,
72
+ refresh_token: current_master.token.refresh_token,
73
+ expires_at: current_master.token.expires_at,
74
+ parent_type: :master,
75
+ parent_name: "#{current_master.name}-admin"
76
+ ),
77
+ account: 'master'
78
+ )
79
+ end
80
+
81
+ spinner "Authenticating as #{cloud_user_data[:email]} to Kontena Master '#{current_master.name}'" do
82
+ current_master.token = Kontena::Cli::Config::Token.new(
83
+ access_token: new_user_token[:access_token],
84
+ refresh_token: new_user_token[:refresh_token],
85
+ expires_at: new_user_token[:expires_in].to_i > 0 ? Time.now.utc.to_i + new_user_token[:expires_in].to_i : nil,
86
+ parent_type: :master,
87
+ parent_name: "#{current_master.name}"
88
+ )
89
+ current_master.username = new_user_token[:user_name].to_s == "" ? new_user_token[:user_email] : new_user_token[:user_name]
90
+ config.write
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,33 @@
1
+ module Kontena
2
+ module Callbacks
3
+ class SuggestInvitingYourself < Kontena::Callback
4
+
5
+ matches_commands 'master create'
6
+
7
+ def after
8
+ extend Kontena::Cli::Common
9
+
10
+ return unless current_master
11
+ return unless command.exit_code == 0
12
+ return if current_master.username.to_s == 'admin'
13
+
14
+ puts
15
+ puts Kontena.pastel.green("Protip:")
16
+
17
+ if config.find_server("#{current_master.name}-admin")
18
+ puts " You are currently using the Kontena Master '#{Kontena.pastel.yellow(current_master.name)}' as"
19
+ puts " #{Kontena.pastel.yellow(current_master.username)}. To switch to the Kontena Master internal"
20
+ puts " administrator you can use:"
21
+ puts " #{Kontena.pastel.green.on_black(" kontena master use #{current_master.name}-admin ")}"
22
+ puts
23
+ end
24
+ puts " To invite more users you can use:"
25
+ puts " #{Kontena.pastel.green.on_black(" kontena master user invite email_address@example.com ")}"
26
+ puts
27
+ puts " The users can then join the master by using the invite code: "
28
+ puts " #{Kontena.pastel.green.on_black(" kontena master join #{current_master.url} <invite_code> ")}"
29
+ puts
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,61 @@
1
+ require 'kontena/util'
2
+
3
+ module Kontena
4
+ module Cli
5
+ class BrowserLauncher
6
+ def self.open(url)
7
+ Kontena::Cli::BrowserLauncher.new(url).launch
8
+ end
9
+
10
+ attr_reader :url
11
+
12
+ def initialize(url)
13
+ @url = url
14
+ end
15
+
16
+ def launch
17
+ system(*command)
18
+ end
19
+
20
+ def command
21
+ cmd = if Kontena.on_windows?
22
+ ['cmd', '/c', 'start', '/b', url.gsub(/&/, '^&')]
23
+ elsif RUBY_PLATFORM =~ /darwin/
24
+ ["open", url]
25
+ elsif Kontena.browserless?
26
+ raise RuntimeError, "Environment variable DISPLAY not set, assuming non-desktop session, unable to open browser. Try using '--remote' option."
27
+ else
28
+ [detect_unixlike_command, url]
29
+ end
30
+
31
+ Kontena.logger.debug { "Using %p to launch browser" % cmd }
32
+
33
+ cmd
34
+ end
35
+
36
+ def detect_unixlike_command
37
+ Kontena.logger.debug { "Assuming unix-like environment, looking for browser" }
38
+
39
+ cmd = %w(
40
+ xdg-open
41
+ sensible-browser
42
+ x-www-browser
43
+ ).find { |c| !which(c).nil? }
44
+
45
+ if cmd.nil?
46
+ if ENV['BROWSER']
47
+ cmd = which(ENV['BROWSER'])
48
+ return cmd unless cmd.nil?
49
+ end
50
+ raise RuntimeError, "Unable to launch a local browser. Try installing xdg-utils or sensible-utils package, setting BROWSER environment variable or using the --remote option"
51
+ end
52
+
53
+ cmd
54
+ end
55
+
56
+ def which(cmd)
57
+ Kontena::Util.which(cmd)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,40 @@
1
+ module Kontena
2
+ module Cli
3
+ module BytesHelper
4
+
5
+ KILOBYTE = 1024
6
+ MEGABYTE = KILOBYTE * 1024
7
+ GIGABYTE = MEGABYTE * 1024
8
+ TERABYTE = GIGABYTE * 1024
9
+
10
+ def to_kilobytes(bytes, ndigits=nil)
11
+ return 0.0 if bytes.nil?
12
+ round(bytes.to_f / KILOBYTE, ndigits)
13
+ end
14
+
15
+ def to_megabytes(bytes, ndigits=nil)
16
+ return 0.0 if bytes.nil?
17
+ round(bytes.to_f / MEGABYTE, ndigits)
18
+ end
19
+
20
+ def to_gigabytes(bytes, ndigits=nil)
21
+ return 0.0 if bytes.nil?
22
+ round(bytes.to_f / GIGABYTE, ndigits)
23
+ end
24
+
25
+ def to_terabytes(bytes, ndigits)
26
+ return 0.0 if bytes.nil?
27
+ round(bytes.to_f / TERABYTE, ndigits)
28
+ end
29
+
30
+ private
31
+ def round(value, ndigits=nil)
32
+ if ndigits.nil?
33
+ return value
34
+ end
35
+ value.round(ndigits)
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,107 @@
1
+ require_relative '../services/services_helper'
2
+
3
+ module Kontena::Cli::Certificate
4
+ class AuthorizeCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::GridOptions
7
+ include Kontena::Cli::Services::ServicesHelper
8
+
9
+ class DeployFailedError < StandardError; end
10
+
11
+ parameter "DOMAIN", "Domain to authorize"
12
+
13
+ option '--type', 'AUTHORIZATION_TYPE', 'Authorization type, either http-01, dns-01 or tls-sni-01 (renewals only)', default: 'http-01'
14
+ option '--linked-service', "LINKED_SERVICE", 'A service (usually LB) where the http-01/tls-sni-01 challenge is deployed to'
15
+
16
+ requires_current_master
17
+ requires_current_master_token
18
+ requires_current_grid
19
+
20
+ def requires_linked_service?
21
+ case type
22
+ when 'dns-01'
23
+ false
24
+ when 'http-01'
25
+ true
26
+ when 'tls-sni-01'
27
+ true
28
+ else
29
+ fail "Invalid authorization --type=#{type}"
30
+ end
31
+ end
32
+
33
+ def execute
34
+ exit_with_error "--linked-service is required with --type=#{type}" if requires_linked_service? && !self.linked_service
35
+
36
+ data = {
37
+ domain: domain,
38
+ authorization_type: self.type
39
+ }
40
+ data[:linked_service] = service_path(self.linked_service) if self.linked_service
41
+ retried = false
42
+
43
+ response = nil
44
+ retry_on_le_registration do
45
+ response = client.post("grids/#{current_grid}/domain_authorizations", data)
46
+ end
47
+
48
+ case self.type
49
+ when 'dns-01'
50
+ puts "Authorization successfully created. Use the following details to create necessary validations:"
51
+ puts "Record name: #{response.dig('challenge_opts', 'record_name')}.#{domain}"
52
+ puts "Record type: #{response.dig('challenge_opts', 'record_type')}"
53
+ puts "Record content: #{response.dig('challenge_opts', 'record_content')}"
54
+ when 'http-01'
55
+ domain_auth = spinner "Waiting for http-01 challenge to be deployed into #{response.dig('linked_service', 'id').colorize(:cyan)} " do
56
+ wait_for_domain_auth_deployed(response)
57
+ end
58
+ if domain_auth['state'] == 'deploy_error'
59
+ exit_with_error "Linked services deploy failed. Check service events for details"
60
+ else
61
+ puts "HTTP challenge is deployed, you can now request the actual certificate"
62
+ end
63
+ when 'tls-sni-01'
64
+ domain_auth = spinner "Waiting for tls-sni-01 challenge to be deployed into #{response.dig('linked_service', 'id').colorize(:cyan)} " do
65
+ wait_for_domain_auth_deployed(response)
66
+ end
67
+ if domain_auth['state'] == 'deploy_error'
68
+ exit_with_error "Linked services deploy failed. Check service events for details"
69
+ else
70
+ puts "TLS-SNI challenge certificate is deployed, you can now request the actual certificate"
71
+ end
72
+ else
73
+ exit_with_error "Unknown authorization type: #{self.type}"
74
+ end
75
+ end
76
+
77
+ def wait_for_domain_auth_deployed(domain_auth)
78
+ Timeout.timeout(300) {
79
+ while domain_auth['status'] == 'deploying' do
80
+ sleep 1
81
+
82
+ domain_auth = client.get("domain_authorizations/#{domain_auth['id']}")
83
+ end
84
+ return domain_auth
85
+ }
86
+ end
87
+
88
+ def service_path(linked_service)
89
+ unless linked_service.include?('/')
90
+ "null/#{linked_service}"
91
+ else
92
+ linked_service
93
+ end
94
+ end
95
+
96
+ def retry_on_le_registration
97
+ yield
98
+ rescue Kontena::Errors::StandardErrorHash => exc
99
+ raise unless exc.errors.has_key?('le_registration')
100
+ # Run through registration
101
+ puts "Let's Encrypt registration missing, creating one."
102
+ email = prompt.ask("Email for Let's Encrypt:")
103
+ Kontena.run!(['certificate', 'register', email])
104
+ yield
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,16 @@
1
+ module Kontena::Cli::Certificate
2
+ module Common
3
+ def show_certificate(cert)
4
+ puts "#{cert['id']}:"
5
+ puts " subject: #{cert['subject']}"
6
+ puts " valid until: #{Time.parse(cert['valid_until']).utc.strftime("%FT%TZ")}"
7
+ if cert['alt_names'] && !cert['alt_names'].empty?
8
+ puts " alt names:"
9
+ cert['alt_names'].each do |alt_name|
10
+ puts " - #{alt_name}"
11
+ end
12
+ end
13
+ puts " auto renewable: #{cert['auto_renewable']}"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+
2
+ module Kontena::Cli::Certificate::DomainAuthorization
3
+ class ListCommand < Kontena::Command
4
+ include Kontena::Cli::Common
5
+ include Kontena::Cli::GridOptions
6
+ include Kontena::Cli::TableGenerator::Helper
7
+ include Kontena::Util
8
+
9
+ requires_current_master
10
+ requires_current_master_token
11
+ requires_current_grid
12
+
13
+ def fields
14
+ quiet? ? ['domain'] : {domain: 'domain', authorization_type: 'authorization_type', status: 'status'}
15
+ end
16
+
17
+ def execute
18
+ authorizations = client.get("grids/#{current_grid}/domain_authorizations")['domain_authorizations']
19
+
20
+ print_table(authorizations)
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+
2
+ module Kontena::Cli::Certificate::DomainAuthorization
3
+ class RemoveAuthorizationCommand < Kontena::Command
4
+ include Kontena::Cli::Common
5
+ include Kontena::Cli::GridOptions
6
+
7
+ parameter "DOMAIN", "Domain authorization to remove"
8
+ option "--force", :flag, "Force remove", default: false, attribute_name: :forced
9
+
10
+
11
+ def execute
12
+ confirm_command(self.domain) unless forced?
13
+
14
+ require_api_url
15
+ token = require_token
16
+
17
+
18
+ spinner "Deleting domain authorization for #{self.domain.colorize(:cyan)}" do
19
+ client.delete("domain_authorizations/#{current_grid}/#{self.domain}")
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,7 @@
1
+
2
+ module Kontena::Cli::Certificate
3
+ class DomainAuthorizeCommand < Kontena::Command
4
+ subcommand ["rm", "remove"], "Remove domain authorization", load_subcommand('certificate/domain_authorization/remove_authorization_command')
5
+ subcommand ["ls", "list"], "List domain authorizations", load_subcommand('certificate/domain_authorization/list_command')
6
+ end
7
+ end
@@ -0,0 +1,28 @@
1
+ module Kontena::Cli::Certificate
2
+ class ExportCommand < Kontena::Command
3
+ include Kontena::Cli::Common
4
+ include Kontena::Cli::GridOptions
5
+
6
+ parameter "SUBJECT", "Certificate subject"
7
+
8
+ requires_current_master
9
+ requires_current_master_token
10
+ requires_current_grid
11
+
12
+ option ['--certificate', '--cert'], :flag, "Output certificate"
13
+ option ['--chain'], :flag, "Output chain"
14
+ option ['--private-key', '--key'], :flag, "Output private key"
15
+
16
+ def bundle?
17
+ ![certificate?, chain?, private_key?].any?
18
+ end
19
+
20
+ def execute
21
+ certificate = client.get("certificates/#{current_grid}/#{self.subject}/export")
22
+
23
+ puts certificate['certificate'] if certificate? || bundle?
24
+ puts certificate['chain'] if chain? || bundle?
25
+ puts certificate['private_key'] if private_key? || bundle?
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,33 @@
1
+
2
+ module Kontena::Cli::Certificate
3
+ class GetCommand < Kontena::Command
4
+ include Kontena::Cli::Common
5
+ include Kontena::Cli::GridOptions
6
+
7
+ BANNER = Kontena.pastel.yellow("[DEPRECATED] This command is now deprecated in favor of 'kontena certificate request' command")
8
+
9
+ banner BANNER
10
+
11
+ option '--secret-name', 'SECRET_NAME', 'The name for the secret to store the certificate in'
12
+ option '--cert-type', 'CERT_TYPE', 'The type of certificate to get: fullchain, chain or cert', default: 'fullchain'
13
+ parameter "DOMAIN ...", "Domain(s) to get certificate for"
14
+
15
+
16
+ def execute
17
+ warn BANNER
18
+
19
+ require_api_url
20
+ token = require_token
21
+ secret = secret_name || "LE_CERTIFICATE_#{domain_list[0].gsub('.', '_')}"
22
+ data = {domains: domain_list, secret_name: secret}
23
+
24
+ response = client(token).post("certificates/#{current_grid}/certificate", data)
25
+ puts "Certificate successfully received and stored into vault with keys:"
26
+ response.each do |secret|
27
+ puts pastel.green(secret)
28
+ end
29
+ puts "Use the #{secret}_BUNDLE with Kontena loadbalancer!"
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,61 @@
1
+ require 'openssl'
2
+ require_relative './common'
3
+
4
+ module Kontena::Cli::Certificate
5
+ class ImportCommand < Kontena::Command
6
+ include Kontena::Cli::Common
7
+ include Kontena::Cli::GridOptions
8
+ include Common
9
+
10
+ # @raise [ArgumentError]
11
+ def open_file(path)
12
+ File.open(path)
13
+ rescue Errno::ENOENT
14
+ raise ArgumentError, "File not found: #{path}"
15
+ end
16
+
17
+ parameter 'CERT_FILE', "Path to PEM-encoded X.509 certificate file" do |path|
18
+ open_file(path)
19
+ end
20
+ option '--subject', 'SUBJECT', "Import cert specific subject"
21
+ option ['--private-key', '--key'], 'KEY_FILE', "Path to private key file", :required => true, :attribute_name => :key_file do |path|
22
+ open_file(path)
23
+ end
24
+ option ['--chain'], 'CHAIN_FILE', "Path to CA cert chain file", :multivalued => true, :attribute_name => :chain_file_list do |path|
25
+ open_file(path)
26
+ end
27
+
28
+ requires_current_master
29
+ requires_current_master_token
30
+ requires_current_grid
31
+
32
+ def load_certificate
33
+ OpenSSL::X509::Certificate.new(self.cert_file)
34
+ rescue OpenSSL::OpenSSLError => exc
35
+ exit_with_error "Invalid certificate at #{self.cert_file.path}: #{exc.class}: #{exc.message}"
36
+ end
37
+
38
+ def certificate_subject(cert)
39
+ cert.subject.to_a.each do |name, data|
40
+ return data if name == 'CN'
41
+ end
42
+
43
+ exit_with_error "No CN in certificate subject: #{cert.subject}"
44
+ end
45
+
46
+ def execute
47
+ cert = load_certificate
48
+ subject = self.subject || self.certificate_subject(cert)
49
+
50
+ certificate = spinner "Importing certificate from #{cert_file.path}..." do
51
+ client.put("certificates/#{current_grid}/#{subject}",
52
+ certificate: cert.to_pem,
53
+ private_key: self.key_file.read(),
54
+ chain: chain_file_list.map{|chain_file| chain_file.read() },
55
+ )
56
+ end
57
+
58
+ show_certificate(certificate)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,75 @@
1
+ require_relative '../services/services_helper'
2
+
3
+ module Kontena::Cli::Certificate
4
+ class ListCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::GridOptions
7
+ include Kontena::Cli::TableGenerator::Helper
8
+ include Kontena::Util
9
+
10
+ requires_current_master
11
+ requires_current_master_token
12
+ requires_current_grid
13
+
14
+ SEVEN_DAYS = 7 * 24 * 60 * 60
15
+ THREE_DAYS = 3 * 24 * 60 * 60
16
+
17
+ def fields
18
+ quiet? ? ['subject'] : {subject: 'subject', "expiration" => 'expires_in', auto_renewable?: 'auto_renewable'}
19
+ end
20
+
21
+ def certificates
22
+ client.get("grids/#{current_grid}/certificates")['certificates']
23
+ end
24
+
25
+ def status_icon(expires_in)
26
+ icon = '⊛'.freeze
27
+
28
+ if expires_in < 0
29
+ icon.colorize(:red)
30
+ else
31
+ icon.colorize(:green)
32
+ end
33
+
34
+ end
35
+
36
+ def status_color(expires_in)
37
+
38
+ if expires_in < 0
39
+ :red
40
+ elsif expires_in < THREE_DAYS
41
+ :bright_yellow
42
+ elsif expires_in < SEVEN_DAYS
43
+ :yellow
44
+ else
45
+ :green
46
+ end
47
+
48
+ end
49
+
50
+ def expires_in(certificate)
51
+ valid_until = Time.parse(certificate['valid_until'])
52
+ (valid_until - Time.now).to_i
53
+ end
54
+
55
+ def expires_in_human(expires_in)
56
+ if expires_in > 0
57
+ text = seconds_to_human(expires_in)
58
+ else
59
+ text = seconds_to_human(-1 * expires_in) + ' ago'
60
+ end
61
+
62
+ text.colorize(status_color(expires_in))
63
+ end
64
+
65
+ def execute
66
+ print_table(certificates) do |certificate|
67
+ expires_in = expires_in(certificate)
68
+ certificate['subject'] = status_icon(expires_in) + " " + certificate['subject'] unless quiet?
69
+ next if quiet? # No need to fiddle with colors when they will not get printed
70
+ certificate['expires_in'] = expires_in_human(expires_in)
71
+ end
72
+ end
73
+
74
+ end
75
+ end