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,182 @@
1
+ module Kontena::Cli::Grids
2
+ module Common
3
+
4
+ ##
5
+ # @param [Hash] grid
6
+ def print_grid(grid)
7
+ host = ENV['KONTENA_URL'] || self.current_master['url']
8
+ puts "#{grid['name']}:"
9
+ puts " uri: #{host.sub('http', 'ws')}"
10
+ puts " initial_size: #{grid['initial_size']}"
11
+ puts " default_affinity: "
12
+ grid['default_affinity'].to_a.each do |a|
13
+ puts " - #{a}"
14
+ end
15
+ puts " subnet: #{grid['subnet']}"
16
+ puts " supernet: #{grid['supernet']}"
17
+ root_dir = grid['engine_root_dir']
18
+ nodes = client(require_token).get("grids/#{grid['name']}/nodes")
19
+ nodes = nodes['nodes'].select{|n| n['connected'] == true }
20
+ node_count = nodes.size
21
+ puts " stats:"
22
+ puts " nodes: #{nodes.size} of #{grid['node_count']}"
23
+
24
+ cpu_total = nodes.map{|n| n['cpus'].to_i}.inject(:+)
25
+ puts " cpus: #{cpu_total || 0}"
26
+
27
+ loads = calculate_loads(nodes, node_count)
28
+ puts " load: #{(loads[:'1m'] || 0.0).round(2)} #{(loads[:'5m'] || 0.0).round(2)} #{(loads[:'15m'] || 0.0).round(2)}"
29
+
30
+ mem_total = nodes.map{|n| n['mem_total'].to_i}.inject(:+)
31
+ mem_used = calculate_mem_used(nodes)
32
+ puts " memory: #{to_gigabytes(mem_used)} of #{to_gigabytes(mem_total)} GB"
33
+
34
+ total_fs = calculate_filesystem_stats(nodes)
35
+ puts " filesystem: #{to_gigabytes(total_fs['used'])} of #{to_gigabytes(total_fs['total'])} GB"
36
+
37
+ puts " users: #{grid['user_count']}"
38
+ puts " services: #{grid['service_count']}"
39
+ puts " containers: #{grid['container_count']}"
40
+ if statsd = grid.dig('stats', 'statsd')
41
+ puts " exports:"
42
+ puts " statsd: #{statsd['server']}:#{statsd['port']}"
43
+ end
44
+ if logs = grid.dig('logs')
45
+ puts "logs:"
46
+ puts " forwarder: #{logs['forwarder']}"
47
+ logs['opts'].each do |k,v|
48
+ puts " #{k}: #{v}"
49
+ end
50
+ end
51
+ end
52
+
53
+ def grids
54
+ @grids ||= client.get('grids')
55
+ end
56
+
57
+ # @param [Array<Hash>] nodes
58
+ # @param [Fixnum] node_count
59
+ # @return [Hash]
60
+ def calculate_loads(nodes, node_count)
61
+ loads = {:'1m' => 0.0, :'5m' => 0.0, :'15m' => 0.0}
62
+ return loads if node_count == 0
63
+
64
+ loads[:'1m'] = nodes.map{|n| n.dig('resource_usage', 'load', '1m').to_f }.inject(:+) / node_count
65
+ loads[:'5m'] = nodes.map{|n| n.dig('resource_usage', 'load', '5m').to_f }.inject(:+) / node_count
66
+ loads[:'15m'] = nodes.map{|n| n.dig('resource_usage', 'load', '15m').to_f }.inject(:+) / node_count
67
+ loads
68
+ end
69
+
70
+ # @param [Array<Hash>] nodes
71
+ # @return [Float]
72
+ def calculate_mem_used(nodes)
73
+ nodes.map{|n|
74
+ mem = n.dig('resource_usage', 'memory')
75
+ if mem
76
+ mem['used'] - (mem['cached'] + mem['buffers'])
77
+ else
78
+ 0.0
79
+ end
80
+ }.inject(:+)
81
+ end
82
+
83
+ # @param [Array<Hash>] nodes
84
+ # @return [Hash]
85
+ def calculate_filesystem_stats(nodes)
86
+ total_fs = {
87
+ 'used' => 0.0,
88
+ 'total' => 0.0
89
+ }
90
+ nodes.each do |node|
91
+ root_dir = node['engine_root_dir']
92
+ filesystems = node.dig('resource_usage', 'filesystem') || []
93
+ root_fs = filesystems.find{|fs| fs['name'] == root_dir}
94
+ total_fs['used'] += root_fs['used']
95
+ total_fs['total'] += root_fs['total']
96
+ end
97
+
98
+ total_fs
99
+ end
100
+
101
+ def find_grid_by_name(name)
102
+ grids['grids'].find {|grid| grid['name'] == name }
103
+ end
104
+
105
+ def to_gigabytes(amount)
106
+ return 0.0 if amount.nil?
107
+ (amount.to_f / 1024 / 1024 / 1024).to_f.round(2)
108
+ end
109
+
110
+ # @return [Hash] /v1/grids/:grid JSON { ... }
111
+ def get_grid(name = nil)
112
+ if name
113
+ client(require_token).get("grids/#{name}")
114
+ elsif current_grid
115
+ client(require_token).get("grids/#{current_grid}")
116
+ else
117
+ exit_with_error "No grid given or selected"
118
+ end
119
+ end
120
+
121
+ module Parameters
122
+ def self.included(base)
123
+ base.option "--default-affinity", "[AFFINITY]", "Default affinity rule for the grid", multivalued: true
124
+ base.option "--statsd-server", "STATSD_SERVER", "Statsd server address (host:port)"
125
+ base.option "--log-forwarder", "LOG_FORWARDER", "Set grid wide log forwarder" do |log_forwarder|
126
+ if log_forwarder == 'none'
127
+ warn "[DEPRECATED] --log-forwarder none will be replaced with --no-log-forwarder"
128
+ end
129
+ log_forwarder
130
+ end
131
+ base.option "--no-log-forwarder", :flag, "Disable log forwarding"
132
+ base.option "--log-opt", "[LOG_OPT]", "Set log options (key=value)", multivalued: true
133
+ end
134
+
135
+ def validate_log_opts
136
+ if !log_opt_list.empty? && (log_forwarder.nil? || no_log_forwarder?)
137
+ raise Kontena::Errors::StandardError.new(1, "Need to specify --log-forwarder when using --log-opt")
138
+ end
139
+
140
+ if no_log_forwarder? && !log_forwarder.nil? && log_forwarder != "none"
141
+ exit_with_error "Can't use --log-forwarder and --no-log-forwarder together"
142
+ end
143
+ end
144
+
145
+ def parse_log_opts
146
+ opts = {}
147
+ log_opt_list.each do |opt|
148
+ key, value = opt.split('=')
149
+ opts[key.to_sym] = value
150
+ end
151
+ opts
152
+ end
153
+
154
+ def validate_grid_parameters
155
+ validate_log_opts
156
+ end
157
+
158
+ def build_grid_parameters(payload)
159
+ if statsd_server
160
+ server, port = statsd_server.split(':')
161
+ payload[:stats] = {
162
+ statsd: {
163
+ server: server,
164
+ port: port || 8125
165
+ }
166
+ }
167
+ end
168
+
169
+ if log_forwarder || no_log_forwarder?
170
+ payload[:logs] = {
171
+ forwarder: no_log_forwarder? ? 'none' : log_forwarder,
172
+ opts: parse_log_opts
173
+ }
174
+ end
175
+
176
+ unless default_affinity_list.empty?
177
+ payload[:default_affinity] = default_affinity_list
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,48 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Grids
4
+ class CreateCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Common
7
+
8
+ parameter "NAME", "Grid name"
9
+
10
+ option "--initial-size", "INITIAL_SIZE", "Initial grid size (number of nodes)", default: 1
11
+ option "--silent", :flag, "Reduce output verbosity"
12
+ option "--token", "[TOKEN]", "Set grid token"
13
+ option "--subnet", "[CIDR]", "Configure grid overlay subnet"
14
+ option "--supernet", "[CIDR]", "Configure grid IPAM supernet"
15
+
16
+ include Common::Parameters
17
+
18
+ requires_current_master_token
19
+
20
+ def execute
21
+ validate_grid_parameters
22
+
23
+ if initial_size == 1
24
+ warning "Option --initial-size=1 is only recommended for test/dev usage" unless running_silent?
25
+ end
26
+
27
+ payload = {
28
+ name: name
29
+ }
30
+ payload[:token] = self.token if self.token
31
+ payload[:initial_size] = self.initial_size if self.initial_size
32
+ payload[:subnet] = subnet if subnet
33
+ payload[:supernet] = supernet if supernet
34
+
35
+ build_grid_parameters(payload)
36
+
37
+ grid = spinner "Creating #{pastel.cyan(name)} grid " do
38
+ client.post('grids', payload)
39
+ end
40
+ if grid
41
+ spinner "Switching scope to #{pastel.cyan(name)} grid " do
42
+ config.current_grid = grid['name']
43
+ config.write
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,25 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Grids
4
+ class CurrentCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Common
7
+
8
+ option ["--name"], :flag, "Show name only", default: false
9
+
10
+ def execute
11
+ require_api_url
12
+ if current_grid.nil?
13
+ exit_with_error 'No grid selected. To select grid, please run: kontena grid use <grid name>'
14
+ else
15
+
16
+ grid = client(require_token).get("grids/#{current_grid}")
17
+ if name?
18
+ puts "#{grid['name']}"
19
+ else
20
+ print_grid(grid)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,32 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Grids
4
+ class EnvCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Common
7
+
8
+ parameter "[NAME]", "Grid name"
9
+ option ["-e", "--export"], :flag, "Add export", default: false
10
+
11
+ def execute
12
+ require_api_url
13
+
14
+ name_or_current = name.nil? ? current_grid : name
15
+
16
+ if name_or_current.nil?
17
+ exit_with_error "No grid selected. Use: kontena grid env <name>, or select a grid with: kontena grid use <name>"
18
+ else
19
+ grid = find_grid_by_name(name_or_current)
20
+ exit_with_error("Grid not found") unless grid
21
+
22
+ grid_uri = self.current_master['url'].sub('http', 'ws')
23
+
24
+
25
+ prefix = export? ? 'export ' : ''
26
+
27
+ puts "#{prefix}KONTENA_URI=#{grid_uri}"
28
+ puts "#{prefix}KONTENA_TOKEN=#{grid['token']}"
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,50 @@
1
+ require_relative '../helpers/log_helper'
2
+
3
+ module Kontena::Cli::Grids
4
+ class EventsCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::Helpers::LogHelper
7
+
8
+ SKIP_TYPES = ['grid']
9
+
10
+ option "--node", "NODE", "Filter by node name", multivalued: true
11
+ option "--service", "SERVICE", "Filter by service name", multivalued: true
12
+
13
+ def execute
14
+ require_api_url
15
+
16
+ query_params = {}
17
+ query_params[:nodes] = node_list.join(",") unless node_list.empty?
18
+ query_params[:services] = service_list.join(",") unless service_list.empty?
19
+
20
+ titles = ['TIME', 'TYPE', 'RELATIONSHIPS', 'MESSAGE']
21
+ puts "%-25s %-25s %-40s %s" % titles
22
+ show_logs("grids/#{current_grid}/event_logs", query_params) do |log|
23
+ show_log(log)
24
+ end
25
+ end
26
+
27
+ def show_log(log)
28
+ msg = log['message']
29
+ rels = log['relationships'].
30
+ delete_if { |r| SKIP_TYPES.include?(r['type']) }.
31
+ map { |r|
32
+ id = r['id'].split('/')[1..-1].delete_if{ |s| s == 'null'}.join('/')
33
+ unless id.empty?
34
+ "#{r['type']}=#{id}"
35
+ end
36
+ }.compact
37
+
38
+ time = log['created_at']
39
+ if log['severity'] == 2
40
+ time = pastel.yellow(time)
41
+ elsif log['severity'] >= 3
42
+ time = pastel.red(time)
43
+ end
44
+
45
+ puts '%-25s %-25s %-40s %s' % [
46
+ time, log['type'], rels.join(','), msg
47
+ ]
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,69 @@
1
+ require_relative 'common'
2
+ require "kontena/cli/helpers/health_helper"
3
+
4
+ module Kontena::Cli::Grids
5
+ class HealthCommand < Kontena::Command
6
+ include Kontena::Cli::Common
7
+ include Kontena::Cli::Helpers::HealthHelper
8
+ include Common
9
+
10
+ parameter "[NAME]", "Grid name"
11
+
12
+ def execute
13
+ require_api_url
14
+
15
+ grid = get_grid(name)
16
+ grid_nodes = client(require_token).get("grids/#{grid['name']}/nodes")
17
+
18
+ return show_grid_health(grid, grid_nodes['nodes'])
19
+ end
20
+
21
+ # Validate grid/nodes configuration for grid operation
22
+ #
23
+ # @return [Boolean] false if unhealthy
24
+ def show_grid_health(grid, nodes)
25
+ initial_size = grid['initial_size']
26
+ minimum_size = grid['initial_size'] / 2 + 1 # a majority is required for etcd quorum
27
+
28
+ grid_health = grid_health(grid, nodes)
29
+ initial_nodes = nodes.select{|node| node['initial_member']}
30
+ online_nodes = initial_nodes.select{|node| node['connected']}
31
+
32
+ # configuration and status
33
+ if initial_nodes.length == 0
34
+ puts "#{health_icon :error} Grid does not have any initial nodes, and requires at least #{minimum_size} of #{initial_size} initial nodes for operation"
35
+ elsif online_nodes.empty?
36
+ puts "#{health_icon :error} Grid does not have any initial nodes online, and requires at least #{minimum_size} of #{initial_size} initial nodes for operation"
37
+ elsif initial_nodes.length < minimum_size
38
+ puts "#{health_icon :error} Grid only has #{initial_nodes.length} initial nodes, and requires at least #{minimum_size} of #{initial_size} initial nodes for operation"
39
+ elsif online_nodes.length < minimum_size
40
+ puts "#{health_icon :error} Grid only has #{online_nodes.length} initial nodes online, and requires at least #{minimum_size} of #{initial_size} initial nodes for operation"
41
+ elsif initial_nodes.length < initial_size
42
+ puts "#{health_icon :warning} Grid only has #{initial_nodes.length} initial nodes of #{initial_size} required for high-availability"
43
+ elsif online_nodes.length < initial_size
44
+ puts "#{health_icon :warning} Grid only has #{online_nodes.length} initial nodes online of #{initial_size} required for high-availability"
45
+ elsif initial_nodes.length == 2
46
+ puts "#{health_icon :warning} Grid only has #{initial_nodes.length} initial nodes, and is not high-availability"
47
+ elsif initial_nodes.length == 1
48
+ puts "#{health_icon :warning} Grid only has #{initial_nodes.length} initial node, and is not high-availability"
49
+ else
50
+ puts "#{health_icon :ok} Grid has all #{online_nodes.length} of #{initial_size} initial nodes online"
51
+ end
52
+
53
+ nodes.each do |node|
54
+ node_health = node_health(node, grid_health)
55
+
56
+ if node['connected']
57
+
58
+ elsif node['initial_member']
59
+ puts "#{health_icon grid_health} Initial node #{node['name']} is offline"
60
+ else
61
+ puts "#{health_icon node_health} Grid node #{node['name']} is offline"
62
+ end
63
+ end
64
+
65
+ # operational if we have etcd quorum
66
+ return online_nodes.length >= minimum_size
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,59 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Grids
4
+ class ListCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::TableGenerator::Helper
7
+ include Common
8
+
9
+ option ['-u', '--use'], :flag, 'Automatically use first available grid sorted by user count', hidden: true
10
+ option ['-v', '--verbose'], :flag, 'Use a more verbose output', hidden: true
11
+
12
+ requires_current_master
13
+ requires_current_master_token
14
+
15
+ def fields
16
+ { name: 'name', nodes: 'node_count', services: 'service_count', users: 'user_count' }
17
+ end
18
+
19
+ def execute
20
+ if quiet?
21
+ puts grids['grids'].map { |grid| grid['name'] }.join("\n")
22
+ exit 0
23
+ end
24
+
25
+ vputs
26
+
27
+ gridlist = []
28
+
29
+ vspinner "Retrieving a list of available grids" do
30
+ gridlist = grids['grids'].sort_by{|grid| grid['user_count']}
31
+ end
32
+
33
+ if gridlist.size == 0
34
+ self.verbose? && puts
35
+ puts pastel.yellow("Kontena Master #{config.current_master.name} doesn't have any grids yet. Create one now using 'kontena grid create' command")
36
+ self.verbose? && puts
37
+ else
38
+ vputs
39
+ vputs "You have access to the following grids:"
40
+ vputs
41
+
42
+ if current_grid
43
+ current_grid_entry = gridlist.find { |grid| grid['name'] == current_grid }
44
+ current_grid_entry['name'] += pastel.yellow(' *') if current_grid_entry
45
+ end
46
+
47
+ print_table(gridlist)
48
+
49
+ if self.use?
50
+ vputs
51
+ vspinner "* Selecting '#{gridlist.first['name']}' as the current grid" do
52
+ config.current_master.grid = gridlist.first['name']
53
+ config.write
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,35 @@
1
+ require_relative '../helpers/log_helper'
2
+
3
+ module Kontena::Cli::Grids
4
+ class LogsCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::Helpers::LogHelper
7
+ option "--node", "NODE", "Filter by node name", multivalued: true
8
+ option "--service", "SERVICE", "Filter by service name", multivalued: true
9
+ option ["-c", "--container"], "CONTAINER", "Filter by container", multivalued: true
10
+
11
+ def execute
12
+ require_api_url
13
+
14
+ query_params = {}
15
+ query_params[:nodes] = node_list.join(",") unless node_list.empty?
16
+ query_params[:services] = service_list.join(",") unless service_list.empty?
17
+ query_params[:containers] = container_list.join(",") unless container_list.empty?
18
+
19
+ show_logs("grids/#{current_grid}/container_logs", query_params) do |log|
20
+ show_log(log)
21
+ end
22
+ end
23
+
24
+ def show_log(log)
25
+ color = color_for_container(log['name'])
26
+ if tail?
27
+ prefix = "#{log['name']} |"
28
+ else
29
+ prefix = "#{log['created_at']} #{log['name']}:"
30
+ end
31
+
32
+ puts "#{pastel.send(color, prefix)} #{log['data']}"
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,31 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Grids
4
+ class RemoveCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Common
7
+
8
+ parameter "NAME ...", "Grid name"
9
+ option "--force", :flag, "Force remove", default: false, attribute_name: :forced
10
+
11
+ def execute
12
+ require_api_url
13
+ token = require_token
14
+ name_list.each do |name|
15
+ confirm_command(name) unless forced?
16
+ grid = find_grid_by_name(name)
17
+
18
+ if !grid.nil?
19
+ spinner "removing #{pastel.cyan(name)} grid " do
20
+ response = client(token).delete("grids/#{grid['id']}")
21
+ if response
22
+ clear_current_grid if grid['id'] == current_grid
23
+ end
24
+ end
25
+ else
26
+ exit_with_error "Could not resolve grid by name [#{name}]. For a list of existing grids please run: kontena grid list"
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,25 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Grids
4
+ class ShowCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Common
7
+
8
+ parameter "NAME", "Grid name"
9
+
10
+ option '--token', :flag, 'Just output grid token'
11
+
12
+ def execute
13
+ require_api_url
14
+
15
+ grid = find_grid_by_name(name)
16
+ exit_with_error("Grid not found") unless grid
17
+
18
+ if self.token?
19
+ puts grid['token']
20
+ else
21
+ print_grid(grid)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,10 @@
1
+ module Kontena::Cli::Grids
2
+ class TrustedSubnetCommand < Kontena::Command
3
+ subcommand ["list", "ls"], "List trusted subnets", load_subcommand('grids/trusted_subnets/list_command')
4
+ subcommand "add", "Add trusted subnet", load_subcommand('grids/trusted_subnets/add_command')
5
+ subcommand ["remove", "rm"], "Remove trusted subnet", load_subcommand('grids/trusted_subnets/remove_command')
6
+
7
+ def execute
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,18 @@
1
+ module Kontena::Cli::Grids::TrustedSubnets
2
+ class AddCommand < Kontena::Command
3
+ include Kontena::Cli::Common
4
+ include Kontena::Cli::GridOptions
5
+
6
+ parameter "SUBNET", "Trusted subnet"
7
+
8
+ requires_current_master
9
+
10
+ def execute
11
+ grid = client.get("grids/#{current_grid}")
12
+ data = {trusted_subnets: grid['trusted_subnets'] + [self.subnet]}
13
+ spinner "Adding #{pastel.cyan(subnet)} as a trusted subnet in #{pastel.cyan(current_grid)} grid " do
14
+ client.put("grids/#{current_grid}", data)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require 'kontena/cli/grids/common'
2
+
3
+ module Kontena::Cli::Grids::TrustedSubnets
4
+ class ListCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::GridOptions
7
+ include Kontena::Cli::Grids::Common
8
+
9
+ # the command outputs id info only anyway, this is here strictly for ignoring purposes
10
+ option ['-q', '--quiet'], :flag, "Output the identifying column only", hidden: true
11
+
12
+ requires_current_master
13
+
14
+ def execute
15
+ Array(get_grid['trusted_subnets']).map(&method(:puts))
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,26 @@
1
+ module Kontena::Cli::Grids::TrustedSubnets
2
+ class RemoveCommand < Kontena::Command
3
+ include Kontena::Cli::Common
4
+ include Kontena::Cli::GridOptions
5
+
6
+ parameter "SUBNET ...", "Trusted subnet", attribute_name: :subnets
7
+ option "--force", :flag, "Force remove", default: false, attribute_name: :forced
8
+
9
+ requires_current_master
10
+
11
+ def execute
12
+ subnets.each do |subnet|
13
+ grid = client.get("grids/#{current_grid}")
14
+ confirm_command(subnet) unless forced?
15
+ trusted_subnets = grid['trusted_subnets'] || []
16
+ unless trusted_subnets.delete(subnet)
17
+ exit_with_error("Grid #{pastel.cyan(current_grid)} does not have trusted subnet #{pastel.cyan(subnet)}")
18
+ end
19
+ data = {trusted_subnets: trusted_subnets}
20
+ spinner "Removing trusted subnet #{pastel.cyan(subnet)} from #{pastel.cyan(current_grid)} grid " do
21
+ client.put("grids/#{current_grid}", data)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,35 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Grids
4
+ class UpdateCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Common
7
+
8
+ parameter "NAME", "Grid name"
9
+
10
+ include Common::Parameters
11
+
12
+ option "--no-default-affinity", :flag, "Unset grid default affinity"
13
+ option "--no-statsd-server", :flag, "Unset statsd server setting"
14
+
15
+ requires_current_master_token
16
+
17
+ def execute
18
+ validate_grid_parameters
19
+
20
+ payload = {}
21
+
22
+ build_grid_parameters(payload)
23
+
24
+ if no_statsd_server?
25
+ payload[:stats] = { statsd: nil }
26
+ end
27
+
28
+ if no_default_affinity?
29
+ payload[:default_affinity] = []
30
+ end
31
+
32
+ client.put("grids/#{name}", payload)
33
+ end
34
+ end
35
+ end