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,331 @@
1
+ require 'uri'
2
+
3
+ module Kontena::Cli::Master
4
+ class LoginCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+
7
+ parameter "[URL]", "Kontena Master URL or name"
8
+ option ['-j', '--join'], '[INVITE_CODE]', "Join master using an invitation code"
9
+ option ['-t', '--token'], '[TOKEN]', 'Use a pre-generated access token', environment_variable: 'KONTENA_TOKEN'
10
+ option ['-n', '--name'], '[NAME]', 'Set server name', environment_variable: 'KONTENA_MASTER'
11
+ option ['-c', '--code'], '[CODE]', 'Use authorization code generated during master install'
12
+ option ['-r', '--[no-]remote'], :flag, 'Login using a browser on another device', default: Kontena.browserless?
13
+ option ['-e', '--expires-in'], '[SECONDS]', 'Request token with expiration of X seconds. Use 0 to never expire', default: 7200
14
+ option ['-v', '--verbose'], :flag, 'Increase output verbosity'
15
+ option ['-f', '--force'], :flag, 'Force reauthentication'
16
+ option ['-s', '--silent'], :flag, 'Reduce output verbosity'
17
+ option ['--grid'], '[GRID]', 'Set grid'
18
+
19
+ option ['--no-login-info'], :flag, "Don't show login info", hidden: true
20
+
21
+ def execute
22
+ if self.code
23
+ exit_with_error "Can't use --token and --code together" if self.token
24
+ exit_with_error "Can't use --join and --code together" if self.join
25
+ end
26
+
27
+ if self.force?
28
+ exit_with_error "Can't use --code and --force together" if self.code
29
+ exit_with_error "Can't use --token and --force together" if self.token
30
+ end
31
+
32
+ server = select_a_server(self.name, self.url)
33
+
34
+ if self.token
35
+ # If a --token was given create a token with access_token set to --token value
36
+ server.token = Kontena::Cli::Config::Token.new(access_token: self.token, parent_type: :master, parent_name: server.name)
37
+ elsif server.token.nil? || self.force?
38
+ # Force reauth or no existing token, create a token with no access_token
39
+ server.token = Kontena::Cli::Config::Token.new(parent_type: :master, parent_name: server.name)
40
+ end
41
+
42
+ if self.grid
43
+ self.skip_grid_auto_select = true if self.respond_to?(:skip_grid_auto_select?)
44
+ server.grid = self.grid
45
+ end
46
+
47
+ # set server token by exchanging code if --code given
48
+ if self.code
49
+ use_authorization_code(server, self.code)
50
+ exit 0
51
+ end
52
+
53
+ # unless an invitation code was supplied, check auth and exit
54
+ # if existing auth works already.
55
+ unless self.join || self.force?
56
+ if auth_works?(server)
57
+ update_server_to_config(server)
58
+ display_login_info(only: :master) unless self.no_login_info?
59
+ exit 0
60
+ end
61
+ end
62
+
63
+ auth_params = {
64
+ remote: self.remote?,
65
+ invite_code: self.join,
66
+ expires_in: self.expires_in
67
+ }
68
+
69
+ if self.remote?
70
+ # no local browser? tell user to launch an external one
71
+ display_remote_message(server, auth_params)
72
+ auth_code = prompt.ask("Enter code displayed in browser:")
73
+ use_authorization_code(server, auth_code)
74
+ else
75
+ # local web flow
76
+ web_flow(server, auth_params)
77
+ end
78
+
79
+ display_login_info(only: :master) unless (running_silent? || self.no_login_info?)
80
+ end
81
+
82
+ def next_default_name
83
+ next_name('kontena-master')
84
+ end
85
+
86
+ def next_name(base)
87
+ if config.find_server(base)
88
+ new_name = base.dup
89
+ unless new_name =~ /\-\d+$/
90
+ new_name += "-2"
91
+ end
92
+ new_name.succ! until config.find_server(new_name).nil?
93
+ new_name
94
+ else
95
+ base
96
+ end
97
+ end
98
+
99
+ def master_account
100
+ @master_account ||= config.find_account('master')
101
+ end
102
+
103
+ def use_authorization_code(server, code)
104
+ response = vspinner "Exchanging authorization code for an access token from Kontena Master" do
105
+ Kontena::Client.new(server.url, server.token).exchange_code(code)
106
+ end
107
+ update_server(server, response)
108
+ update_server_to_config(server)
109
+ end
110
+
111
+ # Check if the existing (or --token) authentication works without reauthenticating
112
+ def auth_works?(server)
113
+ return false unless (server && server.token && server.token.access_token)
114
+ vspinner "Testing if authentication works using current access token" do
115
+ Kontena::Client.new(server.url, server.token).authentication_ok?(master_account.userinfo_endpoint)
116
+ end
117
+ end
118
+
119
+ # Build a path for master authentication
120
+ #
121
+ # @param local_port [Fixnum] tcp port where localhost webserver is listening
122
+ # @param invite_code [String] an invitation code generated when user was invited
123
+ # @param expires_in [Fixnum] expiration time for the requested access token
124
+ # @param remote [Boolean] true when performing a login where the code is displayed on the web page
125
+ # @return [String]
126
+ def authentication_path(local_port: nil, invite_code: nil, expires_in: nil, remote: false)
127
+ auth_url_params = {}
128
+ if remote
129
+ auth_url_params[:redirect_uri] = "/code"
130
+ elsif local_port
131
+ auth_url_params[:redirect_uri] = "http://localhost:#{local_port}/cb"
132
+ else
133
+ raise ArgumentError, "Local port not defined and not performing remote login"
134
+ end
135
+ auth_url_params[:invite_code] = invite_code if invite_code
136
+ auth_url_params[:expires_in] = expires_in if expires_in
137
+ "/authenticate?#{URI.encode_www_form(auth_url_params)}"
138
+ end
139
+
140
+ # Request a redirect to the authentication url from master
141
+ #
142
+ # @param master_url [String] master root url
143
+ # @param auth_params [Hash] auth parameters (keyword arguments of #authentication_path)
144
+ # @return [String] url to begin authentication web flow
145
+ def authentication_url_from_master(master_url, auth_params)
146
+ client = Kontena::Client.new(master_url)
147
+ vspinner "Sending authentication request to receive an authorization URL" do
148
+ response = client.request(
149
+ http_method: :get,
150
+ path: authentication_path(auth_params),
151
+ expects: [501, 400, 302, 403],
152
+ auth: false
153
+ )
154
+
155
+ if client.last_response.status == 302
156
+ client.last_response.headers['Location']
157
+ elsif response.kind_of?(Hash)
158
+ exit_with_error [response['error'], response['error_description']].compact.join(' : ')
159
+ elsif response.kind_of?(String) && response.length > 1
160
+ exit_with_error response
161
+ else
162
+ exit_with_error "Invalid response to authentication request : HTTP#{client.last_response.status} #{client.last_response.body if debug?}"
163
+ end
164
+ end
165
+ end
166
+
167
+ def display_remote_message(server, auth_params)
168
+ url = authentication_url_from_master(server.url, auth_params.merge(remote: true))
169
+ if running_silent?
170
+ sputs url
171
+ else
172
+ puts "Visit this URL in a browser:"
173
+ puts "#{url}"
174
+ end
175
+ end
176
+
177
+ def web_flow(server, auth_params)
178
+ require_relative '../localhost_web_server'
179
+ require 'kontena/cli/browser_launcher'
180
+
181
+
182
+ web_server = Kontena::LocalhostWebServer.new
183
+
184
+ url = authentication_url_from_master(server.url, auth_params.merge(local_port: web_server.port))
185
+ uri = URI.parse(url)
186
+
187
+ puts "Opening a browser to #{uri.scheme}://#{uri.host}"
188
+ puts
189
+ puts "If you are running this command over an ssh connection or it's"
190
+ puts "otherwise not possible to open a browser from this terminal"
191
+ puts "then you must use the --remote flag or use a pregenerated"
192
+ puts "access token using the --token option."
193
+ puts
194
+ puts "Once the authentication is complete you can close the browser"
195
+ puts "window or tab and return to this window to continue."
196
+ puts
197
+
198
+ any_key_to_continue(10)
199
+
200
+ puts "If the browser does not open, try visiting this URL manually:"
201
+ puts "#{uri.to_s}"
202
+ puts
203
+
204
+ server_thread = Thread.new { Thread.main['response'] = web_server.serve_one }
205
+ Kontena::Cli::BrowserLauncher.open(uri.to_s)
206
+
207
+ spinner "Waiting for browser authorization response" do
208
+ server_thread.join
209
+ end
210
+
211
+ update_server(server, Thread.main['response'])
212
+ update_server_to_config(server)
213
+ end
214
+
215
+ def update_server(server, response)
216
+ update_server_token(server, response)
217
+ update_server_name(server, response)
218
+ update_server_username(server, response)
219
+ end
220
+
221
+ def update_server_name(server, response)
222
+ return nil unless server.name.nil?
223
+ if response.kind_of?(Hash) && response['server'] && response['server']['name']
224
+ server.name = next_name(response['server']['name'])
225
+ else
226
+ server.name = next_default_name
227
+ end
228
+ end
229
+
230
+ def update_server_username(server, response)
231
+ return nil unless response.kind_of?(Hash)
232
+ return nil unless response['user']
233
+ server.token.username = response['user']['name'] || response['user']['email']
234
+ server.username = server.token.username
235
+ end
236
+
237
+ def update_server_token(server, response)
238
+ if !response.kind_of?(Hash)
239
+ raise TypeError, "Response type mismatch - expected Hash, got #{response.class}"
240
+ elsif response['code']
241
+ use_authorization_code(server, response['code'])
242
+ elsif response['error']
243
+ exit_with_error "Authentication failed: #{response['error']} #{response['error_description']}"
244
+ else
245
+ server.token = Kontena::Cli::Config::Token.new
246
+ server.token.access_token = response['access_token']
247
+ server.token.refresh_token = response['refresh_token']
248
+ server.token.expires_at = response['expires_at']
249
+ end
250
+ end
251
+
252
+ def update_server_to_config(server)
253
+ server.name ||= next_default_name
254
+ config.servers << server unless config.servers.include?(server)
255
+ config.current_master = server.name
256
+ config.write
257
+ config.reset_instance
258
+ end
259
+
260
+ # Figure out or create a server based on url or name.
261
+ #
262
+ # No name or url provided: try to use current_master
263
+ # A name provided with --name but no url defined: try to find a server by name from config
264
+ # An URL starting with 'http' provided: try to find a server by url from config
265
+ # An URL not starting with 'http' provided: try to find a server by name
266
+ # An URL and a name provided
267
+ # - If a server is found by name: use entry and update URL to the provided url
268
+ # - Else create a new entry with the url and name
269
+ #
270
+ # @param name [String] master name
271
+ # @param url [String] master url or name
272
+ # @return [Kontena::Cli::Config::Server]
273
+ def select_a_server(name, url)
274
+ # no url, no name, try to use current master
275
+ if url.nil? && name.nil?
276
+ if config.current_master
277
+ return config.current_master
278
+ else
279
+ exit_with_error 'URL not specified and current master not selected'
280
+ end
281
+ end
282
+
283
+ if name && url
284
+ exact_match = config.find_server_by(url: url, name: name)
285
+ return exact_match if exact_match # found an exact match, going to use that one.
286
+
287
+ name_match = config.find_server(name)
288
+
289
+ if name_match
290
+ #found a server with the provided name, set the provided url to it and return
291
+ name_match.url = url
292
+ return name_match
293
+ else
294
+ # nothing found, create new.
295
+ return Kontena::Cli::Config::Server.new(name: name, url: url)
296
+ end
297
+ elsif name
298
+ # only --name provided, try to find a server with that name
299
+ name_match = config.find_server(name)
300
+
301
+ if name_match && name_match.url
302
+ return name_match
303
+ else
304
+ exit_with_error "Master #{name} was found from config, but it does not have an URL and no URL was provided on command line"
305
+ end
306
+ elsif url
307
+ # only url provided
308
+ if url =~ /^https?:\/\//
309
+ # url is actually an url
310
+ url_match = config.find_server_by(url: url)
311
+ if url_match
312
+ return url_match
313
+ else
314
+ return Kontena::Cli::Config::Server.new(url: url, name: nil)
315
+ end
316
+ else
317
+ name_match = config.find_server(url)
318
+ if name_match
319
+ unless name_match.url
320
+ exit_with_error "Master #{url} was found from config, but it does not have an URL and no URL was provided on command line"
321
+ end
322
+ return name_match
323
+ else
324
+ exit_with_error "Can't find a master with name #{name} from configuration"
325
+ end
326
+ end
327
+ end
328
+ end
329
+
330
+ end
331
+ end
@@ -0,0 +1,25 @@
1
+ module Kontena::Cli::Master
2
+ class LogoutCommand < Kontena::Command
3
+ include Kontena::Cli::Common
4
+
5
+ option ['-A', '--all'], :flag, 'Log out from all masters. By default only log out from current master.'
6
+
7
+ def execute
8
+ if self.all?
9
+ config.servers.each do |server|
10
+ use_refresh_token(server)
11
+ server.token = nil
12
+ puts "Logged out of #{pastel.green(server.name)}"
13
+ end
14
+ elsif config.current_master
15
+ use_refresh_token(config.current_master)
16
+ config.current_master.token = nil
17
+ puts "Logged out of #{pastel.green(config.current_master.name)}"
18
+ else
19
+ warn "Current master has not been selected"
20
+ exit 0 # exiting with 0 not 1, it's not really an error situation (kontena logout && kontena master login...)
21
+ end
22
+ config.write
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,55 @@
1
+ module Kontena::Cli::Master
2
+ class RemoveCommand < Kontena::Command
3
+ include Kontena::Cli::Common
4
+
5
+ parameter '[NAME]', "Master name"
6
+
7
+ banner "Note: This command only removes the master from your local configuration file"
8
+
9
+ option '--force', :flag, "Don't ask for confirmation", attribute_name: :forced
10
+
11
+ def run_interactive
12
+ selections = prompt.multi_select("Select masters to remove from configuration file:") do |menu|
13
+ config.servers.each do |server|
14
+ menu.choice " #{pastel.green("* ") if config.current_server == server.name}#{server.name} (#{server.username || 'unknown'} @ #{server.url})", server
15
+ end
16
+ end
17
+ if selections.empty?
18
+ puts "No masters selected"
19
+ exit 0
20
+ end
21
+ delete_servers(selections)
22
+ end
23
+
24
+ def delete_servers(servers)
25
+ abort "Master not found in configuration" if servers.empty?
26
+
27
+ unless forced?
28
+ puts "Removing #{servers.size} master#{"s" if servers.size > 1} from configuration"
29
+ confirm
30
+ end
31
+
32
+ config.servers.delete_if {|s| servers.include?(s) }
33
+
34
+ unless config.find_server(config.current_server)
35
+ puts
36
+ puts "Current master was removed, to select a new current master use:"
37
+ puts " " + pastel.green.on_black(" kontena master use <master_name> ")
38
+ puts "Or log into another master by using:"
39
+ puts " " + pastel.green.on_black(" kontena master login <master_url> ")
40
+ config.current_server = nil
41
+ end
42
+
43
+ config.write
44
+ end
45
+
46
+ def execute
47
+ if self.name.nil?
48
+ run_interactive
49
+ else
50
+ delete_servers(config.servers.select {|s| s.name == self.name})
51
+ end
52
+ end
53
+ end
54
+ end
55
+
@@ -0,0 +1,72 @@
1
+ require 'kontena/plugin_manager'
2
+
3
+ module Kontena::Cli::Master
4
+ class SshCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+
7
+ usage "[OPTIONS] -- [COMMANDS] ..."
8
+
9
+ parameter "[COMMANDS] ...", "Run command on host"
10
+
11
+ option ["-i", "--identity-file"], "IDENTITY_FILE", "Path to ssh private key"
12
+ option ["-u", "--user"], "USER", "Login as a user", default: "core"
13
+
14
+ requires_current_master
15
+
16
+ def master_host
17
+ require 'uri'
18
+ URI.parse(current_master.url).host
19
+ end
20
+
21
+ def master_provider_vagrant?
22
+ require 'kontena/cli/master/config/get_command'
23
+ cmd = Kontena::Cli::Master::Config::GetCommand.new([])
24
+ cmd.parse(['server.provider'])
25
+ cmd.response['server.provider'] == 'vagrant'
26
+ rescue => ex
27
+ false
28
+ end
29
+
30
+ def vagrant_plugin_installed?
31
+ Kontena::PluginManager::Common.installed?('vagrant')
32
+ end
33
+
34
+ def master_is_vagrant?
35
+ if master_provider_vagrant?
36
+ unless vagrant_plugin_installed?
37
+ exit_with_error 'You need to install vagrant plugin to ssh into this master. Use: kontena plugin install vagrant'
38
+ end
39
+ logger.debug { "Master config server.provider is vagrant" }
40
+ true
41
+ elsif vagrant_plugin_installed? && current_master.url.include?('192.168.66.')
42
+ logger.debug { "Vagrant plugin installed and current_master url looks like vagrant" }
43
+ true
44
+ else
45
+ logger.debug { "Assuming non-vagrant master host" }
46
+ false
47
+ end
48
+ end
49
+
50
+ def run_ssh
51
+ cmd = ['ssh']
52
+ cmd << "#{user}@#{master_host}"
53
+ cmd += ["-i", identity_file] if identity_file
54
+ cmd += commands_list
55
+ logger.debug { "Executing #{cmd.inspect}" }
56
+ exec(*cmd)
57
+ end
58
+
59
+ def run_vagrant_ssh
60
+ cmd = %w(vagrant master ssh)
61
+ unless commands_list.empty?
62
+ cmd << '--'
63
+ cmd.concat commands_list
64
+ end
65
+ Kontena.run!(cmd)
66
+ end
67
+
68
+ def execute
69
+ master_is_vagrant? ? run_vagrant_ssh : run_ssh
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,29 @@
1
+ module Kontena::Cli::Master::Token
2
+ module Common
3
+
4
+ def token_data_to_hash(data)
5
+ output = {
6
+ id: data["id"],
7
+ token_type: data["token_type"] || data["grant_type"],
8
+ scopes: data["scopes"],
9
+ user_id: data["user"]["id"],
10
+ user_email: data["user"]["email"],
11
+ user_name: data["user"]["name"],
12
+ server_name: data["server"]["name"],
13
+ description: data['description']
14
+ }
15
+ if data["token_type"] == "bearer"
16
+ output[:access_token_last_four] = data["access_token_last_four"]
17
+ output[:refresh_token_last_four] = data["refresh_token_last_four"]
18
+ output[:token_type] = data["token_type"]
19
+ output[:access_token] = data["access_token"] if data["access_token"]
20
+ output[:refresh_token] = data["refresh_token"] if data["refresh_token"]
21
+ output[:expires_in] = data["expires_in"]
22
+ else
23
+ output[:code] = data["code"]
24
+ output[:token_type] = data["grant_type"]
25
+ end
26
+ output
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,50 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Master::Token
4
+ class CreateCommand < Kontena::Command
5
+
6
+ include Kontena::Cli::Common
7
+ include Common
8
+
9
+ requires_current_master
10
+ requires_current_master_token
11
+
12
+ option ['-s', '--scopes'], '[SCOPES]', "Comma separated list of access scopes for the generated token", default: 'user'
13
+ option ['-e', '--expires-in'], '[SECONDS]', "Access token expiration time. Use 0 for never.", default: '7200'
14
+ option ['-c', '--code'], :flag, "Generate an authorization code"
15
+ option ['-u', '--user'], '[EMAIL]', 'Generate a token for another user'
16
+ option ['--id'], :flag, "Only output the token ID"
17
+ option ['--token'], :flag, "Only output the access_token (or authorization code)"
18
+ option ['-d', '--description'], '[DESCRIPTION]', 'Token description'
19
+
20
+ option ['--return'], :flag, "Return the response hash", hidden: true
21
+
22
+ def execute
23
+ params = {
24
+ response_type: self.code? ? 'code' : 'token',
25
+ scope: self.scopes,
26
+ expires_in: self.expires_in,
27
+ }
28
+ params[:description] = self.description if self.description
29
+ params[:user] = self.user if self.user
30
+ data = token_data_to_hash(client.post("/oauth2/authorize", params))
31
+
32
+ return data if self.return?
33
+
34
+ if self.id?
35
+ puts data[:id]
36
+ exit 0
37
+ end
38
+
39
+ if self.token?
40
+ puts data[:access_token] || data[:code]
41
+ exit 0
42
+ end
43
+
44
+ puts '%s:' % data.delete(:id)
45
+ data.each do |key, value|
46
+ puts " %s: %s" % [key, value]
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,45 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Master::Token
4
+ class CurrentCommand < Kontena::Command
5
+
6
+ include Kontena::Cli::Common
7
+ include Common
8
+
9
+ requires_current_master
10
+ requires_current_master_token
11
+
12
+ option '--token', :flag, "Only output access token"
13
+ option '--refresh-token', :flag, "Only output refresh token"
14
+ option '--expires-in', :flag, "Only output expires in seconds"
15
+ option '--id', :flag, "Only output access token id"
16
+
17
+ def execute
18
+ if self.token?
19
+ puts current_master.token.access_token
20
+ return
21
+ end
22
+
23
+ if self.refresh_token?
24
+ if current_master.token.refresh_token
25
+ puts current_master.token.refresh_token
26
+ end
27
+ return
28
+ end
29
+
30
+ if self.expires_in?
31
+ if current_master.token.expires_at.to_i > 0
32
+ puts current_master.token.expires_at - Time.now.utc.to_i
33
+ end
34
+ return
35
+ end
36
+
37
+ if self.id?
38
+ Kontena.run!(['master', 'token', 'show', '--id', current_master.token.access_token])
39
+ else
40
+ Kontena.run!(['master', 'token', 'show', current_master.token.access_token])
41
+ end
42
+ end
43
+ end
44
+ end
45
+
@@ -0,0 +1,39 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Master::Token
4
+ class ListCommand < Kontena::Command
5
+ include Kontena::Util
6
+ include Kontena::Cli::Common
7
+ include Kontena::Cli::TableGenerator::Helper
8
+ include Common
9
+
10
+ requires_current_master
11
+ requires_current_master_token
12
+
13
+ def fields
14
+ return ['id'] if quiet?
15
+ { id: 'id', token_type: 'token_type', token_last4: 'access_token_last_four', expires_in: 'expires_in', scopes: 'scopes', description: 'description' }
16
+ end
17
+
18
+ def execute
19
+ data = Array(client.get("/oauth2/tokens")["tokens"])
20
+ print_table(data) do |row|
21
+ next if quiet?
22
+ row['expires_in'] = colorize(row['expires_in'].to_i)
23
+ row['token_type'] ||= row['grant_type']
24
+ end
25
+ end
26
+
27
+ def colorize(expires_in)
28
+ return expires_in.to_s unless $stdout.tty?
29
+ if expires_in.zero?
30
+ pastel.yellow('never')
31
+ elsif expires_in < 0
32
+ pastel.red(time_ago(Time.now.to_i + expires_in))
33
+ else
34
+ pastel.green(time_until(expires_in))
35
+ end
36
+ end
37
+ end
38
+ end
39
+
@@ -0,0 +1,19 @@
1
+ module Kontena::Cli::Master::Token
2
+ class RemoveCommand < Kontena::Command
3
+
4
+ parameter "TOKEN_OR_ID", "Access token or access token id"
5
+
6
+ option ['-f', '--force'], :flag, "Don't ask questions"
7
+
8
+ include Kontena::Cli::Common
9
+
10
+ requires_current_master
11
+ requires_current_master_token
12
+
13
+ def execute
14
+ confirm
15
+ client.delete("/oauth2/tokens/#{token_or_id}")
16
+ end
17
+ end
18
+ end
19
+