central-cli 0.6.3

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 (259) hide show
  1. checksums.yaml +7 -0
  2. data/.dockerignore +3 -0
  3. data/.gitignore +15 -0
  4. data/.rspec +6 -0
  5. data/.rubocop.yml +5 -0
  6. data/Dockerfile +15 -0
  7. data/Gemfile +10 -0
  8. data/LICENSE +191 -0
  9. data/README.md +39 -0
  10. data/Rakefile +9 -0
  11. data/VERSION +1 -0
  12. data/bin/cm +85 -0
  13. data/central-cli.gemspec +35 -0
  14. data/central-docker.sh +6 -0
  15. data/lib/central/cli/app_command.rb +29 -0
  16. data/lib/central/cli/apps/build_command.rb +24 -0
  17. data/lib/central/cli/apps/central_yml_generator.rb +88 -0
  18. data/lib/central/cli/apps/common.rb +166 -0
  19. data/lib/central/cli/apps/deploy_command.rb +191 -0
  20. data/lib/central/cli/apps/docker_compose_generator.rb +48 -0
  21. data/lib/central/cli/apps/docker_helper.rb +85 -0
  22. data/lib/central/cli/apps/dockerfile_generator.rb +15 -0
  23. data/lib/central/cli/apps/init_command.rb +91 -0
  24. data/lib/central/cli/apps/list_command.rb +68 -0
  25. data/lib/central/cli/apps/logs_command.rb +76 -0
  26. data/lib/central/cli/apps/monitor_command.rb +93 -0
  27. data/lib/central/cli/apps/remove_command.rb +80 -0
  28. data/lib/central/cli/apps/restart_command.rb +38 -0
  29. data/lib/central/cli/apps/scale_command.rb +31 -0
  30. data/lib/central/cli/apps/show_command.rb +23 -0
  31. data/lib/central/cli/apps/start_command.rb +39 -0
  32. data/lib/central/cli/apps/stop_command.rb +39 -0
  33. data/lib/central/cli/auth/aws/create_command.rb +34 -0
  34. data/lib/central/cli/auth/aws_command.rb +7 -0
  35. data/lib/central/cli/auth/list_command.rb +28 -0
  36. data/lib/central/cli/auth_command.rb +9 -0
  37. data/lib/central/cli/bytes_helper.rb +38 -0
  38. data/lib/central/cli/common.rb +148 -0
  39. data/lib/central/cli/container_command.rb +10 -0
  40. data/lib/central/cli/containers/exec_command.rb +21 -0
  41. data/lib/central/cli/containers/inspect_command.rb +22 -0
  42. data/lib/central/cli/etcd/common.rb +7 -0
  43. data/lib/central/cli/etcd/get_command.rb +26 -0
  44. data/lib/central/cli/etcd/list_command.rb +31 -0
  45. data/lib/central/cli/etcd/mkdir_command.rb +21 -0
  46. data/lib/central/cli/etcd/remove_command.rb +25 -0
  47. data/lib/central/cli/etcd/set_command.rb +22 -0
  48. data/lib/central/cli/etcd_command.rb +16 -0
  49. data/lib/central/cli/external_registries/add_command.rb +21 -0
  50. data/lib/central/cli/external_registries/delete_command.rb +15 -0
  51. data/lib/central/cli/external_registries/list_command.rb +27 -0
  52. data/lib/central/cli/external_registries/remove_command.rb +13 -0
  53. data/lib/central/cli/external_registry_command.rb +14 -0
  54. data/lib/central/cli/login_command.rb +121 -0
  55. data/lib/central/cli/logout_command.rb +7 -0
  56. data/lib/central/cli/master/aws/create_command.rb +41 -0
  57. data/lib/central/cli/master/aws_command.rb +7 -0
  58. data/lib/central/cli/master/azure/create_command.rb +39 -0
  59. data/lib/central/cli/master/azure_command.rb +11 -0
  60. data/lib/central/cli/master/digital_ocean/create_command.rb +35 -0
  61. data/lib/central/cli/master/digital_ocean_command.rb +11 -0
  62. data/lib/central/cli/master/list_command.rb +28 -0
  63. data/lib/central/cli/master/use_command.rb +34 -0
  64. data/lib/central/cli/master/users/add_role_command.rb +26 -0
  65. data/lib/central/cli/master/users/invite_command.rb +24 -0
  66. data/lib/central/cli/master/users/list_command.rb +18 -0
  67. data/lib/central/cli/master/users/remove_command.rb +22 -0
  68. data/lib/central/cli/master/users/remove_role_command.rb +25 -0
  69. data/lib/central/cli/master/users_command.rb +15 -0
  70. data/lib/central/cli/master/vagrant/create_command.rb +25 -0
  71. data/lib/central/cli/master/vagrant/restart_command.rb +20 -0
  72. data/lib/central/cli/master/vagrant/ssh_command.rb +15 -0
  73. data/lib/central/cli/master/vagrant/start_command.rb +20 -0
  74. data/lib/central/cli/master/vagrant/stop_command.rb +20 -0
  75. data/lib/central/cli/master/vagrant/terminate_command.rb +13 -0
  76. data/lib/central/cli/master/vagrant_command.rb +21 -0
  77. data/lib/central/cli/master_command.rb +19 -0
  78. data/lib/central/cli/node_command.rb +30 -0
  79. data/lib/central/cli/nodes/add_label_command.rb +19 -0
  80. data/lib/central/cli/nodes/aws/create_command.rb +40 -0
  81. data/lib/central/cli/nodes/aws/restart_command.rb +29 -0
  82. data/lib/central/cli/nodes/aws/terminate_command.rb +21 -0
  83. data/lib/central/cli/nodes/aws_command.rb +14 -0
  84. data/lib/central/cli/nodes/azure/create_command.rb +40 -0
  85. data/lib/central/cli/nodes/azure/restart_command.rb +31 -0
  86. data/lib/central/cli/nodes/azure/terminate_command.rb +21 -0
  87. data/lib/central/cli/nodes/azure_command.rb +14 -0
  88. data/lib/central/cli/nodes/digital_ocean/create_command.rb +32 -0
  89. data/lib/central/cli/nodes/digital_ocean/restart_command.rb +27 -0
  90. data/lib/central/cli/nodes/digital_ocean/terminate_command.rb +19 -0
  91. data/lib/central/cli/nodes/digital_ocean_command.rb +14 -0
  92. data/lib/central/cli/nodes/label_command.rb +12 -0
  93. data/lib/central/cli/nodes/labels/add_command.rb +19 -0
  94. data/lib/central/cli/nodes/labels/remove_command.rb +23 -0
  95. data/lib/central/cli/nodes/list_command.rb +62 -0
  96. data/lib/central/cli/nodes/remove_command.rb +16 -0
  97. data/lib/central/cli/nodes/remove_label_command.rb +23 -0
  98. data/lib/central/cli/nodes/show_command.rb +49 -0
  99. data/lib/central/cli/nodes/ssh_command.rb +31 -0
  100. data/lib/central/cli/nodes/update_command.rb +20 -0
  101. data/lib/central/cli/nodes/vagrant/create_command.rb +27 -0
  102. data/lib/central/cli/nodes/vagrant/restart_command.rb +26 -0
  103. data/lib/central/cli/nodes/vagrant/ssh_command.rb +21 -0
  104. data/lib/central/cli/nodes/vagrant/start_command.rb +26 -0
  105. data/lib/central/cli/nodes/vagrant/stop_command.rb +26 -0
  106. data/lib/central/cli/nodes/vagrant/terminate_command.rb +17 -0
  107. data/lib/central/cli/nodes/vagrant_command.rb +20 -0
  108. data/lib/central/cli/register_command.rb +21 -0
  109. data/lib/central/cli/registry/create_command.rb +144 -0
  110. data/lib/central/cli/registry/delete_command.rb +22 -0
  111. data/lib/central/cli/registry/remove_command.rb +19 -0
  112. data/lib/central/cli/registry_command.rb +11 -0
  113. data/lib/central/cli/service_command.rb +49 -0
  114. data/lib/central/cli/services/add_env_command.rb +19 -0
  115. data/lib/central/cli/services/add_secret_command.rb +24 -0
  116. data/lib/central/cli/services/container_command.rb +8 -0
  117. data/lib/central/cli/services/containers_command.rb +32 -0
  118. data/lib/central/cli/services/create_command.rb +90 -0
  119. data/lib/central/cli/services/delete_command.rb +19 -0
  120. data/lib/central/cli/services/deploy_command.rb +21 -0
  121. data/lib/central/cli/services/env_command.rb +11 -0
  122. data/lib/central/cli/services/envs/add_command.rb +19 -0
  123. data/lib/central/cli/services/envs/list_command.rb +20 -0
  124. data/lib/central/cli/services/envs/remove_command.rb +18 -0
  125. data/lib/central/cli/services/envs_command.rb +20 -0
  126. data/lib/central/cli/services/link_command.rb +26 -0
  127. data/lib/central/cli/services/list_command.rb +42 -0
  128. data/lib/central/cli/services/logs_command.rb +57 -0
  129. data/lib/central/cli/services/monitor_command.rb +58 -0
  130. data/lib/central/cli/services/remove_command.rb +17 -0
  131. data/lib/central/cli/services/remove_env_command.rb +18 -0
  132. data/lib/central/cli/services/remove_secret_command.rb +28 -0
  133. data/lib/central/cli/services/restart_command.rb +17 -0
  134. data/lib/central/cli/services/scale_command.rb +17 -0
  135. data/lib/central/cli/services/secret_command.rb +9 -0
  136. data/lib/central/cli/services/secrets/link_command.rb +24 -0
  137. data/lib/central/cli/services/secrets/unlink_command.rb +28 -0
  138. data/lib/central/cli/services/services_helper.rb +360 -0
  139. data/lib/central/cli/services/show_command.rb +18 -0
  140. data/lib/central/cli/services/start_command.rb +17 -0
  141. data/lib/central/cli/services/stats_command.rb +74 -0
  142. data/lib/central/cli/services/stop_command.rb +17 -0
  143. data/lib/central/cli/services/unlink_command.rb +25 -0
  144. data/lib/central/cli/services/update_command.rb +78 -0
  145. data/lib/central/cli/stack_command.rb +32 -0
  146. data/lib/central/cli/stack_options.rb +11 -0
  147. data/lib/central/cli/stacks/add_user_command.rb +18 -0
  148. data/lib/central/cli/stacks/audit_log_command.rb +21 -0
  149. data/lib/central/cli/stacks/cloud_config_command.rb +41 -0
  150. data/lib/central/cli/stacks/common.rb +95 -0
  151. data/lib/central/cli/stacks/create_command.rb +26 -0
  152. data/lib/central/cli/stacks/current_command.rb +25 -0
  153. data/lib/central/cli/stacks/env_command.rb +32 -0
  154. data/lib/central/cli/stacks/list_command.rb +35 -0
  155. data/lib/central/cli/stacks/list_users_command.rb +26 -0
  156. data/lib/central/cli/stacks/logs_command.rb +81 -0
  157. data/lib/central/cli/stacks/remove_command.rb +26 -0
  158. data/lib/central/cli/stacks/remove_user_command.rb +17 -0
  159. data/lib/central/cli/stacks/show_command.rb +19 -0
  160. data/lib/central/cli/stacks/trusted_subnets/add_command.rb +16 -0
  161. data/lib/central/cli/stacks/trusted_subnets/list_command.rb +17 -0
  162. data/lib/central/cli/stacks/trusted_subnets/remove_command.rb +20 -0
  163. data/lib/central/cli/stacks/update_command.rb +27 -0
  164. data/lib/central/cli/stacks/use_command.rb +21 -0
  165. data/lib/central/cli/stacks/user_command.rb +11 -0
  166. data/lib/central/cli/stacks/users/add_command.rb +18 -0
  167. data/lib/central/cli/stacks/users/list_command.rb +18 -0
  168. data/lib/central/cli/stacks/users/remove_command.rb +17 -0
  169. data/lib/central/cli/user/forgot_password_command.rb +16 -0
  170. data/lib/central/cli/user/reset_password_command.rb +21 -0
  171. data/lib/central/cli/user/verify_command.rb +22 -0
  172. data/lib/central/cli/user_command.rb +12 -0
  173. data/lib/central/cli/vault/list_command.rb +25 -0
  174. data/lib/central/cli/vault/read_command.rb +17 -0
  175. data/lib/central/cli/vault/remove_command.rb +14 -0
  176. data/lib/central/cli/vault/update_command.rb +18 -0
  177. data/lib/central/cli/vault/write_command.rb +22 -0
  178. data/lib/central/cli/vault_command.rb +16 -0
  179. data/lib/central/cli/version.rb +5 -0
  180. data/lib/central/cli/version_command.rb +22 -0
  181. data/lib/central/cli/vpn/config_command.rb +25 -0
  182. data/lib/central/cli/vpn/create_command.rb +71 -0
  183. data/lib/central/cli/vpn/delete_command.rb +21 -0
  184. data/lib/central/cli/vpn/remove_command.rb +19 -0
  185. data/lib/central/cli/vpn_command.rb +13 -0
  186. data/lib/central/cli/whoami_command.rb +20 -0
  187. data/lib/central/client.rb +208 -0
  188. data/lib/central/errors.rb +10 -0
  189. data/lib/central/machine/aws.rb +14 -0
  190. data/lib/central/machine/aws/auth_provisioner.rb +161 -0
  191. data/lib/central/machine/aws/cloudinit.yml +71 -0
  192. data/lib/central/machine/aws/cloudinit_master.yml +118 -0
  193. data/lib/central/machine/aws/cloudinit_oauth.yml +76 -0
  194. data/lib/central/machine/aws/common.rb +31 -0
  195. data/lib/central/machine/aws/master_provisioner.rb +171 -0
  196. data/lib/central/machine/aws/node_destroyer.rb +46 -0
  197. data/lib/central/machine/aws/node_provisioner.rb +214 -0
  198. data/lib/central/machine/azure.rb +13 -0
  199. data/lib/central/machine/azure/cloudinit.yml +64 -0
  200. data/lib/central/machine/azure/cloudinit_master.yml +106 -0
  201. data/lib/central/machine/azure/logger.rb +26 -0
  202. data/lib/central/machine/azure/master_provisioner.rb +125 -0
  203. data/lib/central/machine/azure/node_destroyer.rb +52 -0
  204. data/lib/central/machine/azure/node_provisioner.rb +126 -0
  205. data/lib/central/machine/cert_helper.rb +39 -0
  206. data/lib/central/machine/cloud_config/cloudinit.yml +70 -0
  207. data/lib/central/machine/cloud_config/node_generator.rb +27 -0
  208. data/lib/central/machine/common.rb +16 -0
  209. data/lib/central/machine/digital_ocean.rb +13 -0
  210. data/lib/central/machine/digital_ocean/cloudinit.yml +64 -0
  211. data/lib/central/machine/digital_ocean/cloudinit_master.yml +118 -0
  212. data/lib/central/machine/digital_ocean/master_provisioner.rb +99 -0
  213. data/lib/central/machine/digital_ocean/node_destroyer.rb +40 -0
  214. data/lib/central/machine/digital_ocean/node_provisioner.rb +81 -0
  215. data/lib/central/machine/random_name.rb +39 -0
  216. data/lib/central/machine/vagrant.rb +12 -0
  217. data/lib/central/machine/vagrant/Vagrantfile.master.rb.erb +116 -0
  218. data/lib/central/machine/vagrant/Vagrantfile.node.rb.erb +32 -0
  219. data/lib/central/machine/vagrant/cloudinit.yml +73 -0
  220. data/lib/central/machine/vagrant/master_destroyer.rb +34 -0
  221. data/lib/central/machine/vagrant/master_provisioner.rb +79 -0
  222. data/lib/central/machine/vagrant/node_destroyer.rb +38 -0
  223. data/lib/central/machine/vagrant/node_provisioner.rb +68 -0
  224. data/lib/central/scripts/completer +157 -0
  225. data/lib/central/scripts/init +11 -0
  226. data/spec/central/cli/app/common_spec.rb +150 -0
  227. data/spec/central/cli/app/deploy_command_spec.rb +598 -0
  228. data/spec/central/cli/app/docker_helper_spec.rb +102 -0
  229. data/spec/central/cli/app/scale_spec.rb +49 -0
  230. data/spec/central/cli/common_spec.rb +117 -0
  231. data/spec/central/cli/login_command_spec.rb +31 -0
  232. data/spec/central/cli/master/current_command_spec.rb +55 -0
  233. data/spec/central/cli/master/use_command_spec.rb +37 -0
  234. data/spec/central/cli/master/users/invite_command_spec.rb +34 -0
  235. data/spec/central/cli/master/users/remove_command_spec.rb +26 -0
  236. data/spec/central/cli/master/users/roles/add_command_spec.rb +34 -0
  237. data/spec/central/cli/master/users/roles/remove_command_spec.rb +34 -0
  238. data/spec/central/cli/register_command_spec.rb +56 -0
  239. data/spec/central/cli/services/containers_command_spec.rb +40 -0
  240. data/spec/central/cli/services/link_command_spec.rb +38 -0
  241. data/spec/central/cli/services/restart_command_spec.rb +27 -0
  242. data/spec/central/cli/services/secrets/link_command_spec.rb +59 -0
  243. data/spec/central/cli/services/secrets/unlink_command_spec.rb +48 -0
  244. data/spec/central/cli/services/services_helper_spec.rb +170 -0
  245. data/spec/central/cli/services/unlink_command_spec.rb +38 -0
  246. data/spec/central/cli/stacks/trusted_subnets/add_command_spec.rb +37 -0
  247. data/spec/central/cli/stacks/trusted_subnets/list_command_spec.rb +30 -0
  248. data/spec/central/cli/stacks/trusted_subnets/remove_command_spec.rb +37 -0
  249. data/spec/central/cli/version_command_spec.rb +16 -0
  250. data/spec/fixtures/central.yml +17 -0
  251. data/spec/fixtures/docker-compose.yml +8 -0
  252. data/spec/fixtures/mysql.yml +3 -0
  253. data/spec/fixtures/wordpress-scaled.yml +3 -0
  254. data/spec/fixtures/wordpress.yml +2 -0
  255. data/spec/spec_helper.rb +27 -0
  256. data/spec/support/client_helpers.rb +30 -0
  257. data/spec/support/fixtures_helpers.rb +7 -0
  258. data/tasks/rspec.rake +5 -0
  259. metadata +463 -0
@@ -0,0 +1,17 @@
1
+ require_relative '../common'
2
+
3
+ module Central::Cli::Stacks::Users
4
+ class RemoveCommand < Clamp::Command
5
+ include Central::Cli::Common
6
+ include Central::Cli::StackOptions
7
+ include Central::Cli::Stacks::Common
8
+
9
+ parameter 'EMAIL', 'Email address'
10
+
11
+ def execute
12
+ require_api_url
13
+ token = require_token
14
+ result = client(token).delete("stacks/#{current_stack}/users/#{email}")
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ module Central::Cli::User
2
+ class ForgotPasswordCommand < Clamp::Command
3
+ include Central::Cli::Common
4
+
5
+ parameter 'EMAIL', 'Email address'
6
+
7
+ option '--auth-provider-url', 'URL', 'Auth provider URL', default: 'https://auth.bluebeluga.io/'
8
+
9
+ def execute
10
+ params = { email: email }
11
+ auth_client = Central::Client.new(auth_provider_url)
12
+ auth_client.post('user/password_reset', params)
13
+ puts 'Email with password reset instructions is sent to your email address. Please follow the instructions to change your password.'
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,21 @@
1
+ module Central::Cli::User
2
+ class ResetPasswordCommand < Clamp::Command
3
+ include Central::Cli::Common
4
+
5
+ parameter 'TOKEN', 'Password reset token'
6
+
7
+ option '--auth-provider-url', 'URL', 'Auth provider URL', default: 'https://auth.bluebeluga.io/'
8
+
9
+ def execute
10
+ require 'highline/import'
11
+
12
+ password = ask('Password: ') { |q| q.echo = '*' }
13
+ password2 = ask('Password again: ') { |q| q.echo = '*' }
14
+ abort("Passwords don't match") if password != password2
15
+ params = { token: token, password: password }
16
+ auth_client = Central::Client.new(auth_provider_url)
17
+ auth_client.put('user/password_reset', params)
18
+ puts 'Password is now changed. To login with the new password, please run: cm login'
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,22 @@
1
+ module Central::Cli::User
2
+ class VerifyCommand < Clamp::Command
3
+ include Central::Cli::Common
4
+
5
+ parameter 'TOKEN', 'Central verify token'
6
+
7
+ option '--auth-provider-url', 'URL', 'Auth provider URL', default: 'https://auth.bluebeluga.io/'
8
+
9
+ def execute
10
+ require_api_url
11
+
12
+ params = { token: token }
13
+ begin
14
+ auth_client = Central::Client.new(auth_provider_url)
15
+ auth_client.post('user/email_confirm', params)
16
+ puts 'Account verified'.colorize(:green)
17
+ rescue Central::Errors::StandardError
18
+ abort 'Invalid verify token'.colorize(:red)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,12 @@
1
+ require_relative 'user/verify_command'
2
+ require_relative 'user/forgot_password_command'
3
+ require_relative 'user/reset_password_command'
4
+
5
+ class Central::Cli::UserCommand < Clamp::Command
6
+ subcommand 'verify', 'Verify user account', Central::Cli::User::VerifyCommand
7
+ subcommand 'forgot-password', 'Request password reset for Central account', Central::Cli::User::ForgotPasswordCommand
8
+ subcommand 'reset-password', 'Reset Central account password', Central::Cli::User::ResetPasswordCommand
9
+
10
+ def execute
11
+ end
12
+ end
@@ -0,0 +1,25 @@
1
+ require 'tty'
2
+
3
+ module Central::Cli::Vault
4
+ class ListCommand < Clamp::Command
5
+ include Central::Cli::Common
6
+ include Central::Cli::StackOptions
7
+
8
+ def execute
9
+ require_api_url
10
+ token = require_token
11
+ result = client(token).get("stacks/#{current_stack}/secrets")
12
+ header = ['Name', 'Created at']
13
+ rows = []
14
+ result['secrets'].sort_by { |s| s['name'] }.each do |secret|
15
+ rows << [secret['name'], secret['created_at']]
16
+ end
17
+
18
+ ttable = TTY::Table.new header: header, rows: Array.new(rows)
19
+ renderer = TTY::Table::Renderer::Unicode.new(ttable)
20
+ renderer.border.style = :cyan
21
+ renderer.padding = [0, 1, 0, 1]
22
+ puts renderer.render
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,17 @@
1
+ module Central::Cli::Vault
2
+ class ReadCommand < Clamp::Command
3
+ include Central::Cli::Common
4
+ include Central::Cli::StackOptions
5
+
6
+ parameter 'NAME', 'Secret name'
7
+
8
+ def execute
9
+ require_api_url
10
+ token = require_token
11
+ result = client(token).get("secrets/#{current_stack}/#{name}")
12
+ puts "#{result['name']}:"
13
+ puts " created_at: #{result['created_at']}"
14
+ puts " value: #{result['value']}"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ module Central::Cli::Vault
2
+ class RemoveCommand < Clamp::Command
3
+ include Central::Cli::Common
4
+ include Central::Cli::StackOptions
5
+
6
+ parameter 'NAME', 'Secret name'
7
+
8
+ def execute
9
+ require_api_url
10
+ token = require_token
11
+ client(token).delete("secrets/#{current_stack}/#{name}")
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,18 @@
1
+ module Central::Cli::Vault
2
+ class UpdateCommand < Clamp::Command
3
+ include Central::Cli::Common
4
+
5
+ parameter 'NAME', 'Secret name'
6
+ parameter '[VALUE]', 'Secret value'
7
+
8
+ def execute
9
+ require_api_url
10
+ token = require_token
11
+ secret = value
12
+ secret = STDIN.read if secret.to_s == ''
13
+ abort('No value provided') if secret.to_s == ''
14
+ data = { value: secret }
15
+ client(token).put("stacks/#{current_stack}/secrets/#{name}", data)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ module Central::Cli::Vault
2
+ class WriteCommand < Clamp::Command
3
+ include Central::Cli::Common
4
+ include Central::Cli::StackOptions
5
+
6
+ parameter 'NAME', 'Secret name'
7
+ parameter '[VALUE]', 'Secret value'
8
+
9
+ def execute
10
+ require_api_url
11
+ token = require_token
12
+ secret = value
13
+ secret = STDIN.read if secret.to_s == ''
14
+ abort('No value provided') if secret.to_s == ''
15
+ data = {
16
+ name: name,
17
+ value: secret
18
+ }
19
+ client(token).post("stacks/#{current_stack}/secrets", data)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ require_relative 'vault/write_command'
2
+ require_relative 'vault/list_command'
3
+ require_relative 'vault/read_command'
4
+ require_relative 'vault/remove_command'
5
+ require_relative 'vault/update_command'
6
+
7
+ class Central::Cli::VaultCommand < Clamp::Command
8
+ subcommand %w(list ls), 'List secrets', Central::Cli::Vault::ListCommand
9
+ subcommand 'write', 'Write a secret', Central::Cli::Vault::WriteCommand
10
+ subcommand 'read', 'Read secret', Central::Cli::Vault::ReadCommand
11
+ subcommand 'update', 'Update secret', Central::Cli::Vault::UpdateCommand
12
+ subcommand %w(remove rm), 'Remove secret', Central::Cli::Vault::RemoveCommand
13
+
14
+ def execute
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ module Central
2
+ module Cli
3
+ VERSION = File.read(File.realpath(File.join(__dir__, '../../../VERSION'))).strip
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ require_relative 'version'
2
+
3
+ class Central::Cli::VersionCommand < Clamp::Command
4
+ include Central::Cli::Common
5
+
6
+ def execute
7
+ url = begin
8
+ api_url
9
+ rescue
10
+ nil
11
+ end
12
+ puts "cli: #{Central::Cli::VERSION}"
13
+ if url
14
+ resp = begin
15
+ JSON.parse(client.http_client.get(path: '/').body)
16
+ rescue
17
+ nil
18
+ end
19
+ puts "master: #{resp['version']} (#{url})" if resp
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,25 @@
1
+ module Central::Cli::Vpn
2
+ class ConfigCommand < Clamp::Command
3
+ include Central::Cli::Common
4
+ include Central::Cli::StackOptions
5
+
6
+ def execute
7
+ require 'rbconfig'
8
+ require_api_url
9
+ payload = { cmd: ['/usr/local/bin/ovpn_getclient', 'CENTRAL_VPN_CLIENT'] }
10
+ stdout, stderr = client(require_token).post("containers/#{current_stack}/vpn/vpn-1/exec", payload)
11
+ if linux?
12
+ stdout << "\n"
13
+ stdout << "up /etc/openvpn/update-resolv-conf\n"
14
+ stdout << "down /etc/openvpn/update-resolv-conf\n"
15
+ end
16
+ puts stdout
17
+ end
18
+
19
+ # @return [Boolean]
20
+ def linux?
21
+ host_os = RbConfig::CONFIG['host_os']
22
+ host_os.include?('linux')
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,71 @@
1
+ require 'shell-spinner'
2
+
3
+ module Central::Cli::Vpn
4
+ class CreateCommand < Clamp::Command
5
+ include Central::Cli::Common
6
+ include Central::Cli::StackOptions
7
+
8
+ option '--node', 'NODE', 'Node name where VPN is deployed'
9
+ option '--ip', 'IP', 'Node ip-address'
10
+
11
+ def execute
12
+ require_api_url
13
+ token = require_token
14
+ preferred_node = node
15
+
16
+ vpn = begin
17
+ client(token).get("services/#{current_stack}/vpn")
18
+ rescue
19
+ nil
20
+ end
21
+ abort('VPN already exists') if vpn
22
+
23
+ nodes = client(token).get("stacks/#{current_stack}/nodes")
24
+ if preferred_node.nil?
25
+ node = nodes['nodes'].find { |n| n['connected'] }
26
+ abort('Cannot find any online nodes') if node.nil?
27
+ else
28
+ node = nodes['nodes'].find { |n| n['connected'] && n['name'] == preferred_node }
29
+ abort('Node not found') if node.nil?
30
+ end
31
+
32
+ vpn_ip = node_vpn_ip(node)
33
+ data = {
34
+ name: 'vpn',
35
+ stateful: true,
36
+ image: 'fishyard/openvpn:ethwe',
37
+ ports: [
38
+ {
39
+ container_port: '1194',
40
+ node_port: '1194',
41
+ protocol: 'udp'
42
+ }
43
+ ],
44
+ cap_add: ['NET_ADMIN'],
45
+ env: ["OVPN_SERVER_URL=udp://#{vpn_ip}:1194"],
46
+ affinity: ["node==#{node['name']}"]
47
+ }
48
+ client(token).post("stacks/#{current_stack}/services", data)
49
+ client(token).post("services/#{current_stack}/vpn/deploy", {})
50
+ ShellSpinner 'Deploying vpn service ' do
51
+ sleep 1 until client(token).get("services/#{current_stack}/vpn")['state'] != 'deploying'
52
+ end
53
+ puts "OpenVPN service is now started (udp://#{vpn_ip}:1194)."
54
+ puts "Use 'cm vpn config' to fetch OpenVPN client config to your machine "\
55
+ '(it takes a while until config is ready).'
56
+ end
57
+
58
+ # @param [Hash] node
59
+ # @return [String]
60
+ def node_vpn_ip(node)
61
+ return ip unless ip.nil?
62
+
63
+ # vagrant
64
+ if api_url == 'http://192.168.66.100:8080'
65
+ node['private_ip']
66
+ else
67
+ node['public_ip']
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,21 @@
1
+ module Central::Cli::Vpn
2
+ class DeleteCommand < Clamp::Command
3
+ include Central::Cli::Common
4
+ include Central::Cli::StackOptions
5
+
6
+ def execute
7
+ puts "DEPRECATION WARNING: Support for 'cm vpn delete' will be dropped. Use 'cm vpn remove' instead.".colorize(:red)
8
+ require_api_url
9
+ token = require_token
10
+
11
+ vpn = begin
12
+ client(token).get("services/#{current_stack}/vpn")
13
+ rescue
14
+ nil
15
+ end
16
+ abort('VPN service does not exist') if vpn.nil?
17
+
18
+ client(token).delete("services/#{current_stack}/vpn")
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ module Central::Cli::Vpn
2
+ class RemoveCommand < Clamp::Command
3
+ include Central::Cli::Common
4
+
5
+ def execute
6
+ require_api_url
7
+ token = require_token
8
+
9
+ vpn = begin
10
+ client(token).get("services/#{current_stack}/vpn")
11
+ rescue
12
+ nil
13
+ end
14
+ abort('VPN service does not exist') if vpn.nil?
15
+
16
+ client(token).delete("services/#{current_stack}/vpn")
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'vpn/create_command'
2
+ require_relative 'vpn/config_command'
3
+ require_relative 'vpn/remove_command'
4
+ require_relative 'vpn/delete_command'
5
+
6
+ class Central::Cli::VpnCommand < Clamp::Command
7
+ subcommand 'create', 'Create VPN service', Central::Cli::Vpn::CreateCommand
8
+ subcommand 'config', 'Show/Export VPN config', Central::Cli::Vpn::ConfigCommand
9
+ subcommand %w(remove rm), 'Remove VPN service', Central::Cli::Vpn::RemoveCommand
10
+
11
+ def execute
12
+ end
13
+ end
@@ -0,0 +1,20 @@
1
+ class Central::Cli::WhoamiCommand < Clamp::Command
2
+ include Central::Cli::Common
3
+
4
+ option '--bash-completion-path', :flag, 'Show bash completion path', hidden: true
5
+
6
+ def execute
7
+ if bash_completion_path?
8
+ puts File.realpath(File.join(__dir__, '../scripts/init'))
9
+ exit 0
10
+ end
11
+
12
+ require_api_url
13
+ puts "Master: #{current_master['name']}"
14
+ puts "URL: #{api_url}"
15
+ puts "Stack: #{current_stack}"
16
+ token = require_token
17
+ user = client(token).get('user')
18
+ puts "User: #{user['email']}"
19
+ end
20
+ end
@@ -0,0 +1,208 @@
1
+ require 'json'
2
+ require 'excon'
3
+ require_relative 'errors'
4
+ require 'central/cli/version'
5
+
6
+ module Central
7
+ class Client
8
+ attr_accessor :default_headers
9
+ attr_reader :http_client
10
+
11
+ # Initialize api client
12
+ #
13
+ # @param [String] api_url
14
+ # @param [Hash] default_headers
15
+ def initialize(api_url, default_headers = {})
16
+ Excon.defaults[:ssl_verify_peer] = false if ignore_ssl_errors?
17
+ @http_client = Excon.new(api_url)
18
+ @default_headers = {
19
+ 'Accept' => 'application/json',
20
+ 'Content-Type' => 'application/json',
21
+ 'User-Agent' => "central-cli/#{Central::Cli::VERSION}"
22
+ }.merge(default_headers)
23
+ @api_url = api_url
24
+ end
25
+
26
+ # Get request
27
+ #
28
+ # @param [String] path
29
+ # @param [Hash,NilClass] params
30
+ # @param [Hash] headers
31
+ # @return [Hash]
32
+ def get(path, params = nil, headers = {})
33
+ response = http_client.get(
34
+ path: request_uri(path),
35
+ query: params,
36
+ headers: request_headers(headers)
37
+ )
38
+ if response.status == 200
39
+ parse_response(response)
40
+ else
41
+ handle_error_response(response)
42
+ end
43
+ end
44
+
45
+ # Get request
46
+ #
47
+ # @param [String] path
48
+ # @param [Lambda] response_block
49
+ # @param [Hash,NilClass] params
50
+ # @param [Hash] headers
51
+ def get_stream(path, response_block, params = nil, headers = {})
52
+ http_client.get(
53
+ read_timeout: 360,
54
+ path: request_uri(path),
55
+ query: params,
56
+ headers: request_headers(headers),
57
+ response_block: response_block
58
+ )
59
+ end
60
+
61
+ # Post request
62
+ #
63
+ # @param [String] path
64
+ # @param [Object] obj
65
+ # @param [Hash] params
66
+ # @param [Hash] headers
67
+ # @return [Hash]
68
+ def post(path, obj, params = {}, headers = {})
69
+ request_headers = request_headers(headers)
70
+ request_options = {
71
+ path: request_uri(path),
72
+ headers: request_headers,
73
+ body: encode_body(obj, request_headers['Content-Type']),
74
+ query: params
75
+ }
76
+
77
+ response = http_client.post(request_options)
78
+ if [200, 201].include?(response.status)
79
+ parse_response(response)
80
+ else
81
+ handle_error_response(response)
82
+ end
83
+ end
84
+
85
+ # Put request
86
+ #
87
+ # @param [String] path
88
+ # @param [Object] obj
89
+ # @param [Hash] params
90
+ # @param [Hash] headers
91
+ # @return [Hash]
92
+ def put(path, obj, params = {}, headers = {})
93
+ request_headers = request_headers(headers)
94
+ request_options = {
95
+ path: request_uri(path),
96
+ headers: request_headers,
97
+ body: encode_body(obj, request_headers['Content-Type']),
98
+ query: params
99
+ }
100
+
101
+ response = http_client.put(request_options)
102
+ if [200, 201].include?(response.status)
103
+ parse_response(response)
104
+ else
105
+ handle_error_response(response)
106
+ end
107
+ end
108
+
109
+ # Delete request
110
+ #
111
+ # @param [String] path
112
+ # @param [Hash,String] body
113
+ # @param [Hash] params
114
+ # @param [Hash] headers
115
+ # @return [Hash]
116
+ def delete(path, body = nil, params = {}, headers = {})
117
+ request_headers = request_headers(headers)
118
+ request_options = {
119
+ path: request_uri(path),
120
+ headers: request_headers,
121
+ body: encode_body(body, request_headers['Content-Type']),
122
+ query: params
123
+ }
124
+ response = http_client.delete(request_options)
125
+ if response.status == 200
126
+ parse_response(response)
127
+ else
128
+ handle_error_response(response)
129
+ end
130
+ end
131
+
132
+ private
133
+
134
+ ##
135
+ # Get full request uri
136
+ #
137
+ # @param [String] path
138
+ # @return [String]
139
+ def request_uri(path)
140
+ "/v1/#{path}"
141
+ end
142
+
143
+ ##
144
+ # Get request headers
145
+ #
146
+ # @param [Hash] headers
147
+ # @return [Hash]
148
+ def request_headers(headers = {})
149
+ @default_headers.merge(headers)
150
+ end
151
+
152
+ ##
153
+ # Encode body based on content type
154
+ #
155
+ # @param [Object] body
156
+ # @param [String] content_type
157
+ def encode_body(body, content_type)
158
+ if content_type == 'application/json'
159
+ dump_json(body)
160
+ else
161
+ body
162
+ end
163
+ end
164
+
165
+ ##
166
+ # Parse response
167
+ #
168
+ # @param [HTTP::Message]
169
+ # @return [Object]
170
+ def parse_response(response)
171
+ if response.headers['Content-Type'].include?('application/json')
172
+ parse_json(response.body)
173
+ else
174
+ response.body
175
+ end
176
+ end
177
+
178
+ ##
179
+ # Parse json
180
+ #
181
+ # @param [String] json
182
+ # @return [Hash,Object,NilClass]
183
+ def parse_json(json)
184
+ JSON.parse(json)
185
+ rescue
186
+ nil
187
+ end
188
+
189
+ ##
190
+ # Dump json
191
+ #
192
+ # @param [Object] obj
193
+ # @return [String]
194
+ def dump_json(obj)
195
+ JSON.dump(obj)
196
+ end
197
+
198
+ def ignore_ssl_errors?
199
+ ENV['SSL_IGNORE_ERRORS'] == 'true'
200
+ end
201
+
202
+ def handle_error_response(response)
203
+ message = response.body
204
+ message = 'Not found' if response.status == 404 && message == ''
205
+ fail Central::Errors::StandardError.new(response.status, message)
206
+ end
207
+ end
208
+ end