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,251 @@
1
+ require 'clamp'
2
+ require 'kontena/cli/subcommand_loader'
3
+ require 'kontena/util'
4
+ require 'kontena/cli/bytes_helper'
5
+ require 'kontena/cli/grid_options'
6
+ require 'excon/error'
7
+
8
+ Clamp.allow_options_after_parameters = true
9
+
10
+ class Kontena::Command < Clamp::Command
11
+ option ['-D', '--[no-]debug'], :flag, "Enable debug", environment_variable: 'DEBUG', attribute_name: :debug_option do |debug|
12
+ unless debug.kind_of?(String)
13
+ ENV['DEBUG'] = debug.to_s
14
+ Kontena.reset_logger
15
+ end
16
+ end
17
+
18
+ attr_accessor :arguments
19
+ attr_reader :result
20
+ attr_reader :exit_code
21
+
22
+ module Finalizer
23
+ def self.extended(obj)
24
+ # Tracepoint is used to trigger finalize once the command is completely
25
+ # loaded. If done through def self.inherited the finalizer and
26
+ # after_load callbacks would run before the options are defined.
27
+ TracePoint.trace(:end) do |t|
28
+ if obj == t.self
29
+ obj.finalize
30
+ t.disable
31
+ end
32
+ end
33
+ end
34
+
35
+ def finalize
36
+ return if self.has_subcommands?
37
+ return if self.callback_matcher
38
+
39
+ name_parts = self.name.split('::')[-2, 2]
40
+
41
+ unless name_parts.compact.empty?
42
+ # 1: Remove trailing 'Command' from for example AuthCommand
43
+ # 2: Convert the string from CamelCase to under_score
44
+ # 3: Convert the string into a symbol
45
+ #
46
+ # In comes: ['ExternalRegistry', 'UseCommand']
47
+ # Out goes: [:external_registry, :use]
48
+ name_parts = name_parts.map { |np|
49
+ np.gsub(/Command$/, '').
50
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
51
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
52
+ tr("-", "_").
53
+ downcase.
54
+ to_sym
55
+ }
56
+ self.callback_matcher(*name_parts)
57
+ end
58
+
59
+ # Run all #after_load callbacks for this command.
60
+ [name_parts.last, :all].compact.uniq.each do |cmd_type|
61
+ [name_parts.first, :all].compact.uniq.each do |cmd_class|
62
+ if Kontena::Callback.callbacks.fetch(cmd_class, {}).fetch(cmd_type, nil)
63
+ Kontena::Callback.callbacks[cmd_class][cmd_type].each do |cb|
64
+ if cb.instance_methods.include?(:after_load)
65
+ cb.new(self).after_load
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ def self.load_subcommand(path)
75
+ Kontena::Cli::SubcommandLoader.new(path)
76
+ end
77
+
78
+ def self.inherited(where)
79
+ where.extend Finalizer
80
+ end
81
+
82
+ def self.callback_matcher(cmd_class = nil, cmd_type = nil)
83
+ unless cmd_class
84
+ if @command_class.nil?
85
+ return nil
86
+ else
87
+ return [@command_class, @command_type]
88
+ end
89
+ end
90
+ @command_class = cmd_class.to_sym
91
+ @command_type = cmd_type.to_sym
92
+ [@command_class, @command_type]
93
+ end
94
+
95
+ def run_callbacks(state)
96
+ if self.class.respond_to?(:callback_matcher) && !self.class.callback_matcher.nil? && !self.class.callback_matcher.compact.empty?
97
+ Kontena::Callback.run_callbacks(self.class.callback_matcher, state, self)
98
+ end
99
+ end
100
+
101
+ # Overwrite Clamp's banner command. Calling banner multiple times
102
+ # will now add lines to the banner message instead of overwriting
103
+ # the whole message. This is useful if callbacks add banner messages.
104
+ #
105
+ # @param [String] message
106
+ def self.banner(msg, extra_feed = true)
107
+ self.description = [self.description, extra_feed ? "\n#{msg}" : msg].compact.join("\n")
108
+ end
109
+
110
+ def self.requires_current_master
111
+ unless Kontena::Cli::Config.current_master
112
+ banner "#{Kontena.pastel.green("Requires current master")}: This command requires that you have selected a current master using 'kontena master login' or 'kontena master use'. You can also use the environment variable KONTENA_URL to specify the master address or KONTENA_MASTER=master_name to override the current_master setting."
113
+ end
114
+ @requires_current_master = true
115
+ end
116
+
117
+ def self.requires_current_grid
118
+ unless Kontena::Cli::Config.current_grid
119
+ banner "#{Kontena.pastel.green("Requires current grid")}: This command requires that you have selected a grid as the current grid using 'kontena grid use' or by setting KONTENA_GRID environment variable."
120
+ end
121
+ @requires_current_grid = true
122
+ end
123
+
124
+ def self.requires_current_account_token
125
+ unless Kontena::Cli::Config.current_account && Kontena::Cli::Config.current_account.token && Kontena::Cli::Config.current_account.token.access_token
126
+ banner "#{Kontena.pastel.green("Requires account authentication")}: This command requires that you have authenticated to Kontena Cloud using 'kontena cloud auth'"
127
+ end
128
+ @requires_current_account_token = true
129
+ end
130
+
131
+
132
+ def self.requires_current_master?
133
+ @requires_current_master ||= false
134
+ end
135
+
136
+ def verify_current_master
137
+ Kontena::Cli::Config.instance.require_current_master if self.class.requires_current_master?
138
+ end
139
+
140
+ def self.requires_current_grid?
141
+ @requires_current_grid ||= false
142
+ end
143
+
144
+ def verify_current_grid
145
+ Kontena::Cli::Config.instance.require_current_grid if self.class.requires_current_grid?
146
+ end
147
+
148
+ def self.requires_current_account_token?
149
+ @requires_current_account_token ||= false
150
+ end
151
+
152
+ def verify_current_account_token
153
+ retried ||= false
154
+ Kontena::Cli::Config.instance.require_current_account_token if self.class.requires_current_account_token?
155
+ end
156
+
157
+ def self.requires_current_master_token
158
+ @requires_current_master_token = true
159
+ end
160
+
161
+ def self.requires_current_master_token?
162
+ @requires_current_master_token ||= false
163
+ end
164
+
165
+ def verify_current_master_token
166
+ return nil unless self.class.requires_current_master_token?
167
+ retried ||= false
168
+ Kontena::Cli::Config.instance.require_current_master_token
169
+ rescue Kontena::Cli::Config::TokenExpiredError
170
+ server = Kontena::Cli::Config.instance.current_master
171
+ success = Kontena::Client.new(server.url, server.token,
172
+ ssl_cert_path: server.ssl_cert_path,
173
+ ssl_subject_cn: server.ssl_subject_cn,
174
+ ).refresh_token
175
+ if success && !retried
176
+ retried = true
177
+ retry
178
+ else
179
+ raise Kontena::Cli::Config::TokenExpiredError, "The access token has expired and refresh failed. Try authenticating again, use: kontena master login"
180
+ end
181
+ end
182
+
183
+ def help_requested?
184
+ return true if @arguments.include?('--help')
185
+ return true if @arguments.include?('-h')
186
+ false
187
+ end
188
+
189
+ # Returns an instance of the command, just like with Kontena.run! but before calling "execute"
190
+ # You can use it for specs or reuse of instancemethods.
191
+ # Example:
192
+ # cmd = Kontena::FooCommand.instance(['-n', 'foo'])
193
+ # cmd.fetch_stuff
194
+ def instance(arguments)
195
+ @arguments = arguments
196
+ parse @arguments
197
+ self
198
+ end
199
+
200
+ def run(arguments)
201
+ Kontena.logger.debug { "Running #{self.class.name} with #{arguments.inspect} -- callback matcher = '#{self.class.callback_matcher.nil? ? "nil" : self.class.callback_matcher.map(&:to_s).join(' ')}'" }
202
+ @arguments = arguments
203
+
204
+ run_callbacks :before_parse unless help_requested?
205
+
206
+ parse @arguments
207
+
208
+ unless help_requested?
209
+ verify_current_master
210
+ verify_current_master_token
211
+ verify_current_grid
212
+ run_callbacks :before
213
+ end
214
+
215
+ begin
216
+ @result = execute
217
+ @exit_code = @result.kind_of?(FalseClass) ? 1 : 0
218
+ rescue SystemExit => exc
219
+ @result = exc.status == 0
220
+ @exit_code = exc.status
221
+ end
222
+ run_callbacks :after unless help_requested?
223
+ exit(@exit_code) if @exit_code.to_i > 0
224
+ @result
225
+ rescue Excon::Error::Socket => ex
226
+ if ex.message.include?('Unable to verify certificate')
227
+ $stderr.puts " [#{Kontena.pastel.red('error')}] The server uses a certificate signed by an unknown authority."
228
+ $stderr.puts " You can trust this server by copying server CA pem file to: #{Kontena.pastel.yellow("~/.kontena/certs/<hostname>.pem")}"
229
+ $stderr.puts " If kontena cannot find your system ca bundle, you can set #{Kontena.pastel.yellow('SSL_CERT_DIR=/etc/ssl/certs')} env variable to load them from another location."
230
+ $stderr.puts " Protip: you can bypass the certificate check by setting #{Kontena.pastel.yellow('SSL_IGNORE_ERRORS=true')} env variable, but any data you send to the server could be intercepted by others."
231
+ abort
232
+ else
233
+ abort(ex.message)
234
+ end
235
+ rescue Kontena::Errors::StandardError => ex
236
+ raise ex if Kontena.debug?
237
+ Kontena.logger.error(ex)
238
+ abort(" [#{Kontena.pastel.red('error')}] #{ex.status} : #{ex.message}")
239
+ rescue Errno::EPIPE
240
+ # If user is piping the command outputs to some other command that might exit before CLI has outputted everything
241
+ abort
242
+ rescue Clamp::HelpWanted, Clamp::UsageError
243
+ raise
244
+ rescue => ex
245
+ raise ex if Kontena.debug?
246
+ Kontena.logger.error(ex)
247
+ abort(" [#{Kontena.pastel.red('error')}] #{ex.class.name} : #{ex.message}\n See #{Kontena.log_target} or run the command again with environment DEBUG=true set to see the full exception")
248
+ end
249
+ end
250
+
251
+ require 'kontena/callback'
@@ -0,0 +1,80 @@
1
+ require 'uri'
2
+ module Kontena
3
+ class DebugInstrumentor
4
+ def self.instrument(name, params = {}, &block)
5
+ result = []
6
+ params = params.dup
7
+
8
+ direction = name.split('.').last.capitalize
9
+
10
+ if direction == 'Request'
11
+ uri = URI.parse("#{params[:scheme]}://#{params[:host]}:#{params[:port]}")
12
+ uri.path = params[:path].nil? ? '/' : params[:path].split('?', 2).first
13
+ uri.query = URI.encode_www_form(params[:query]) if params[:query] && !params[:query].empty?
14
+ str = "#{params[:method].to_s.upcase} #{uri}"
15
+ str << " (ssl_verify: #{params[:ssl_verify_peer]}) " if params[:scheme] == 'https'
16
+ result << str
17
+ end
18
+
19
+ if params[:headers]
20
+ str = "Headers: {"
21
+ heads = []
22
+ heads << "Accept: #{params[:headers]['Accept']}" if params[:headers]['Accept']
23
+ heads << "Accept-Encoding: #{params[:headers]['Accept-Encoding']}" if params[:headers]['Accept-Encoding']
24
+ heads << "Content-Type: #{params[:headers]['Content-Type']}" if params[:headers]['Content-Type']
25
+ heads << "Content-Encoding: #{params[:headers]['Content-Encoding']}" if params[:headers]['Content-Encoding']
26
+ heads << "Authorization: #{params[:headers]['Authorization'].split(' ', 2).first}" if params[:headers]['Authorization']
27
+ heads << "X-Kontena-Version: #{params[:headers]['X-Kontena-Version']}" if params[:headers]['X-Kontena-Version']
28
+ str << heads.join(', ')
29
+ str << "} "
30
+ result << str
31
+ end
32
+
33
+ if params[:status]
34
+ str = "Status: "
35
+ if params[:status] < 299
36
+ str << Kontena.pastel.green(params[:status])
37
+ else
38
+ str << Kontena.pastel.red(params[:status])
39
+ end
40
+ result << str
41
+ end
42
+
43
+ if params[:body] && !params[:body].empty?
44
+ if params[:headers]['Content-Encoding'].to_s =~ /gzip/
45
+ body_content = Zlib::GzipReader.new(StringIO.new(params[:body])).read
46
+ body = "(GZIPPED 1:%d) %s" % [body_content.bytesize / params[:body].bytesize, body_content]
47
+ else
48
+ body = params[:body]
49
+ end
50
+
51
+ str = "Body: "
52
+ if ENV["DEBUG"] == "api"
53
+ str << "\n"
54
+ str << body
55
+ else
56
+ body = body.inspect.strip
57
+ str << body[0,80]
58
+ if body.length > 80
59
+ str << "...\""
60
+ end
61
+ end
62
+ result << str
63
+ elsif params[:error]
64
+ result << params[:error]
65
+ end
66
+
67
+ color = case direction
68
+ when 'Request' then :blue
69
+ when 'Response' then :magenta
70
+ else :red
71
+ end
72
+
73
+ Kontena.logger.debug("CLIENT") { Kontena.pastel.send(color, "[#{direction}]: #{result.join(" | ")}") }
74
+
75
+ if block_given?
76
+ yield
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,50 @@
1
+ module Kontena
2
+ module Errors
3
+ class StandardError < ::StandardError
4
+
5
+ attr_reader :status
6
+
7
+ # @param status [Fixnum] HTTP response status
8
+ # @param message [String] short error message
9
+ def initialize(status, message)
10
+ @status = status
11
+ super(message)
12
+ end
13
+ end
14
+
15
+ # The normal {error: {foo: "invalid foo"}} error response format used by the API
16
+ class StandardErrorHash < StandardError
17
+ attr_reader :errors
18
+
19
+ # @param errors [Hash]
20
+ def initialize(status, message, errors)
21
+ super(status, message)
22
+ @errors = errors
23
+ end
24
+
25
+ # Render as indented YAML
26
+ def errors_message(indent: "\t")
27
+ require 'yaml'
28
+ @errors.to_yaml.lines[1..-1].map{|line| "#{indent}#{line}" }.join
29
+ end
30
+
31
+ # Render the full multi-line message including YAML-formatted errors
32
+ def message
33
+ "#{super}:\n#{errors_message}"
34
+ end
35
+ end
36
+
37
+ # An error with an array of additional details
38
+ class StandardErrorArray < Kontena::Errors::StandardError
39
+ # @param details [Array<String>]
40
+ def initialize(status, message, details)
41
+ super(status, message)
42
+ @details = details
43
+ end
44
+
45
+ def message
46
+ "#{super}:\n#{@details.map{|msg| "\t" + msg}.join("\n")}"
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,103 @@
1
+ require 'tty-prompt'
2
+ require 'pastel'
3
+
4
+ module Kontena
5
+ class LightPrompt
6
+
7
+ attr_reader :prompt
8
+
9
+ extend Forwardable
10
+
11
+ class Menu
12
+ attr_reader :choices, :calls
13
+
14
+ def initialize
15
+ @choices = []
16
+ @calls = {}
17
+ end
18
+
19
+ def choice(text, label)
20
+ choices << [text, label]
21
+ end
22
+
23
+ def add_quit_choice
24
+ choice('(done)', :done)
25
+ end
26
+
27
+ def remove_choice(value)
28
+ choices.reject! { |c| c.last == value }
29
+ end
30
+
31
+ def remove_choices(values)
32
+ values.each { |v| remove_choice(v) }
33
+ end
34
+
35
+ def method_missing(meth, *args)
36
+ calls[meth] = args
37
+ end
38
+
39
+ def respond_to_missing?(meth, privates = false)
40
+ prompt.respond_to?(meth, privates)
41
+ end
42
+ end
43
+
44
+ def initialize(options={})
45
+ @prompt = TTY::Prompt.new(options)
46
+ end
47
+
48
+ def select(*args, &block)
49
+ choice_collector = Menu.new
50
+ yield choice_collector
51
+
52
+ prompt.enum_select(*args) do |menu|
53
+ choice_collector.calls.each do |meth, args|
54
+ if menu.respond_to?(meth)
55
+ menu.send(meth, *args)
56
+ end
57
+ end
58
+ choice_collector.choices.each do |choice|
59
+ menu.choice choice.first, choice.last
60
+ end
61
+ end
62
+ end
63
+
64
+ def multi_select(*args, &block)
65
+ choice_collector = Menu.new
66
+ yield choice_collector
67
+ choice_collector.add_quit_choice
68
+
69
+ selections = []
70
+
71
+ loop do
72
+ choice_collector.remove_choices(selections)
73
+
74
+ answer = prompt.enum_select(*args) do |menu|
75
+ choice_collector.calls.each do |meth, args|
76
+ if menu.respond_to?(meth)
77
+ menu.send(meth, *args)
78
+ end
79
+ end
80
+ choice_collector.choices.each do |choice|
81
+ menu.choice choice.first, choice.last
82
+ end
83
+ end
84
+
85
+ break if answer == :done
86
+ selections << answer
87
+ end
88
+
89
+ selections
90
+ end
91
+
92
+
93
+ def_delegators :prompt, :ask, :yes?, :error
94
+
95
+ def method_missing(meth, *args)
96
+ prompt.send(meth, *args)
97
+ end
98
+
99
+ def respond_to_missing?(meth, privates = false)
100
+ prompt.respond_to?(meth, privates)
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,43 @@
1
+ require 'openssl'
2
+
3
+ module Kontena
4
+ module Machine
5
+ module CertHelper
6
+
7
+ def certificate_public_key(cert)
8
+ cert[/(-----BEGIN CERTIFICATE-----.+?-----END CERTIFICATE-----)/m, 1]
9
+ end
10
+
11
+ def generate_self_signed_cert
12
+ key = OpenSSL::PKey::RSA.new(2048)
13
+ public_key = key.public_key
14
+
15
+ subject = "/C=FI/O=Test/OU=Test/CN=Test"
16
+
17
+ cert = OpenSSL::X509::Certificate.new
18
+ cert.subject = cert.issuer = OpenSSL::X509::Name.parse(subject)
19
+ cert.not_before = Time.now
20
+ cert.not_after = Time.now + (10 * 365 * 24 * 60 * 60)
21
+ cert.public_key = public_key
22
+ cert.serial = 0x0
23
+ cert.version = 2
24
+
25
+ ef = OpenSSL::X509::ExtensionFactory.new
26
+ ef.subject_certificate = cert
27
+ ef.issuer_certificate = cert
28
+ cert.extensions = [
29
+ ef.create_extension("basicConstraints","CA:TRUE", true),
30
+ ef.create_extension("subjectKeyIdentifier", "hash")
31
+ ]
32
+ cert.add_extension ef.create_extension("authorityKeyIdentifier",
33
+ "keyid:always,issuer:always")
34
+
35
+ cert.sign key, OpenSSL::Digest::SHA1.new
36
+
37
+ pem = cert.to_pem
38
+ pem << key.to_s
39
+ pem
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,82 @@
1
+ #cloud-config
2
+ write_files:
3
+ - path: /etc/kontena-agent.env
4
+ permissions: 0600
5
+ owner: root
6
+ content: |
7
+ KONTENA_URI="<%= master_uri %>"
8
+ KONTENA_TOKEN="<%= grid_token %>"
9
+ KONTENA_PEER_INTERFACE=<%= peer_interface %>
10
+ KONTENA_VERSION=<%= version %>
11
+ - path: /etc/systemd/system/docker.service.d/50-kontena.conf
12
+ content: |
13
+ [Service]
14
+ Environment='DOCKER_OPTS=--insecure-registry="<%= grid_subnet %>" --bip="<%= docker_bip %>"'
15
+ - path: /etc/sysctl.d/99-inotify.conf
16
+ owner: root
17
+ permissions: 0644
18
+ content: |
19
+ fs.inotify.max_user_instances = 8192
20
+ coreos:
21
+ units:
22
+ - name: 50-weave.network
23
+ content: |
24
+ [Match]
25
+ Name=weave datapath vxlan-6784
26
+
27
+ [Network]
28
+ Description=Network interfaces managed by weave
29
+
30
+ [Link]
31
+ Unmanaged=true
32
+ - name: 90-dummy.network
33
+ content: |
34
+ [Match]
35
+ Name=dummy0
36
+
37
+ [Link]
38
+ Unmanaged=true
39
+ - name: zz-default.network
40
+ content: |
41
+ # default should not match virtual Docker/weave bridge/veth network interfaces
42
+ [Match]
43
+ Name=<%= match_default_network_name %>
44
+
45
+ [Network]
46
+ DHCP=yes
47
+ <% dns_servers.each do |dns| %>DNS=<%= dns %>
48
+ <% end %>
49
+ Domains=kontena.local
50
+
51
+ [DHCP]
52
+ UseMTU=true
53
+ UseDNS=false
54
+
55
+ - name: kontena-agent.service
56
+ command: start
57
+ enable: true
58
+ content: |
59
+ [Unit]
60
+ Description=kontena-agent
61
+ After=network-online.target
62
+ After=docker.service
63
+ Description=Kontena Agent
64
+ Documentation=http://www.kontena.io/
65
+ Requires=network-online.target
66
+ Requires=docker.service
67
+
68
+ [Service]
69
+ Restart=always
70
+ RestartSec=5
71
+ EnvironmentFile=/etc/kontena-agent.env
72
+ ExecStartPre=-/usr/bin/docker stop kontena-agent
73
+ ExecStartPre=-/usr/bin/docker rm kontena-agent
74
+ ExecStartPre=/usr/bin/docker pull kontena/agent:${KONTENA_VERSION}
75
+ ExecStart=/usr/bin/docker run --name kontena-agent \
76
+ -e KONTENA_URI=${KONTENA_URI} \
77
+ -e KONTENA_TOKEN=${KONTENA_TOKEN} \
78
+ -e KONTENA_PEER_INTERFACE=${KONTENA_PEER_INTERFACE} \
79
+ -v=/var/run/docker.sock:/var/run/docker.sock \
80
+ -v=/etc/kontena-agent.env:/etc/kontena.env \
81
+ --net=host \
82
+ kontena/agent:${KONTENA_VERSION}
@@ -0,0 +1,28 @@
1
+ require 'fileutils'
2
+ require 'erb'
3
+
4
+ module Kontena
5
+ module Machine
6
+ module CloudConfig
7
+ class NodeGenerator
8
+
9
+ # @param [Hash] opts
10
+ def generate(opts)
11
+ user_data(opts)
12
+ end
13
+
14
+ # @param [Hash] vars
15
+ def user_data(vars)
16
+ cloudinit_template = File.join(__dir__ , '/cloudinit.yml')
17
+ erb(File.read(cloudinit_template), vars)
18
+ end
19
+
20
+ # @param [String] template
21
+ # @param [Hash] vars
22
+ def erb(template, vars)
23
+ ERB.new(template).result(OpenStruct.new(vars).instance_eval { binding })
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ module Kontena
2
+ module Machine
3
+ module Common
4
+
5
+ def which(cmd)
6
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
7
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
8
+ exts.each { |ext|
9
+ exe = File.join(path, "#{cmd}#{ext}")
10
+ return exe if File.executable?(exe) && !File.directory?(exe)
11
+ }
12
+ end
13
+ return nil
14
+ end
15
+ end
16
+ end
17
+ end