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,18 @@
1
+ require_relative 'services_helper'
2
+
3
+ module Central::Cli::Services
4
+ class ShowCommand < Clamp::Command
5
+ include Central::Cli::Common
6
+ include Central::Cli::StackOptions
7
+ include ServicesHelper
8
+
9
+ parameter 'NAME', 'Service name'
10
+
11
+ def execute
12
+ require_api_url
13
+ token = require_token
14
+
15
+ show_service(token, name)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'services_helper'
2
+
3
+ module Central::Cli::Services
4
+ class StartCommand < Clamp::Command
5
+ include Central::Cli::Common
6
+ include Central::Cli::StackOptions
7
+ include ServicesHelper
8
+
9
+ parameter 'NAME', 'Service name'
10
+
11
+ def execute
12
+ require_api_url
13
+ token = require_token
14
+ start_service(token, name)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,74 @@
1
+ require_relative 'services_helper'
2
+
3
+ module Central::Cli::Services
4
+ class StatsCommand < Clamp::Command
5
+ include Central::Cli::Common
6
+ include Central::Cli::StackOptions
7
+ include ServicesHelper
8
+
9
+ MEM_MAX_LIMITS = [
10
+ 1.8446744073709552e+19, 9.223372036854772e+18
11
+ ].freeze
12
+
13
+ parameter 'NAME', 'Service name'
14
+ option ['-t', '--tail'], :flag, 'Tail (follow) stats in real time', default: false
15
+
16
+ def execute
17
+ require_api_url
18
+ token = require_token
19
+ if tail?
20
+ system('clear')
21
+ render_header
22
+ end
23
+ loop do
24
+ fetch_stats(token, name, tail?)
25
+ break unless tail?
26
+ sleep(2)
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def fetch_stats(token, service_id, follow)
33
+ result = client(token).get("services/#{current_stack}/#{service_id}/stats")
34
+ system('clear') if follow
35
+ render_header
36
+ result['stats'].each do |stat|
37
+ render_stat_row(stat)
38
+ end
39
+ end
40
+
41
+ def render_header
42
+ puts '%-30.30s %-15s %-20s %-15s %-15s' % ['CONTAINER', 'CPU %', 'MEM USAGE/LIMIT', 'MEM %', 'NET I/O']
43
+ end
44
+
45
+ def render_stat_row(stat)
46
+ memory = stat['memory'].nil? ? 'N/A' : filesize_to_human(stat['memory']['usage'])
47
+ if !stat['memory'].nil? && (stat['memory']['limit'] && !MEM_MAX_LIMITS.include?(stat['memory']['limit']))
48
+ memory_limit = filesize_to_human(stat['memory']['limit'])
49
+ memory_pct = "#{(stat['memory']['usage'].to_f / stat['memory']['limit'].to_f * 100).round(2)}%"
50
+ else
51
+ memory_limit = 'N/A'
52
+ memory_pct = 'N/A'
53
+ end
54
+
55
+ cpu = stat['cpu'].nil? ? 'N/A' : stat['cpu']['usage']
56
+ network_in = stat['network'].nil? ? 'N/A' : filesize_to_human(stat['network']['rx_bytes'])
57
+ network_out = stat['network'].nil? ? 'N/A' : filesize_to_human(stat['network']['tx_bytes'])
58
+ puts '%-30.30s %-15s %-20s %-15s %-15s' % [stat['container_id'], "#{cpu}%", "#{memory} / #{memory_limit}", memory_pct.to_s, "#{network_in}/#{network_out}"]
59
+ end
60
+
61
+ ##
62
+ # @param [Integer] size
63
+ # @return [String]
64
+ def filesize_to_human(size)
65
+ return '0B' if size.to_f == 0.0
66
+ units = %w(B K M G T)
67
+ e = (Math.log(size) / Math.log(1000)).floor
68
+ s = '%.2f' % (size.to_f / 1000**e)
69
+ s.sub(/\.?0*$/, units[e])
70
+ rescue FloatDomainError
71
+ 'N/A'
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'services_helper'
2
+
3
+ module Central::Cli::Services
4
+ class StopCommand < Clamp::Command
5
+ include Central::Cli::Common
6
+ include Central::Cli::StackOptions
7
+ include ServicesHelper
8
+
9
+ parameter 'NAME', 'Service name'
10
+
11
+ def execute
12
+ require_api_url
13
+ token = require_token
14
+ stop_service(token, name)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,25 @@
1
+ require_relative '../stack_options'
2
+ require_relative 'services_helper'
3
+
4
+ module Central::Cli::Services
5
+ class UnlinkCommand < Clamp::Command
6
+ include Central::Cli::Common
7
+ include Central::Cli::StackOptions
8
+ include ServicesHelper
9
+
10
+ parameter 'NAME', 'Service name'
11
+ parameter 'TARGET', 'Link target service name'
12
+
13
+ def execute
14
+ require_api_url
15
+ token = require_token
16
+
17
+ service = client(token).get("services/#{parse_service_id(name)}")
18
+ links = service['links'].map { |l| { name: l['stack_service_id'].split('/')[1], alias: l['alias'] } }
19
+ abort("Service is not linked to #{target}") unless links.find { |l| l[:name] == target.to_s }
20
+ links.delete_if { |l| l[:name] == target.to_s }
21
+ data = { links: links }
22
+ update_service(token, name, data)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,78 @@
1
+ require_relative 'services_helper'
2
+
3
+ module Central::Cli::Services
4
+ class UpdateCommand < Clamp::Command
5
+ include Central::Cli::Common
6
+ include Central::Cli::StackOptions
7
+ include ServicesHelper
8
+
9
+ parameter 'NAME', 'Service name'
10
+
11
+ option '--image', 'IMAGE', 'Docker image to use'
12
+ option ['-p', '--ports'], 'PORT', "Publish a service's port to the host", multivalued: true
13
+ option ['-e', '--env'], 'ENV', 'Set environment variables', multivalued: true
14
+ option ['-l', '--link'], 'LINK', 'Add link to another service in the form of name:alias', multivalued: true
15
+ option ['-a', '--affinity'], 'AFFINITY', 'Set service affinity', multivalued: true
16
+ option ['-c', '--cpu-shares'], 'CPU_SHARES', 'CPU shares (relative weight)'
17
+ option ['-m', '--memory'], 'MEMORY', 'Memory limit (format: <number><optional unit>, where unit = b, k, m or g)'
18
+ option ['--memory-swap'], 'MEMORY_SWAP', "Total memory usage (memory + swap), set \'-1\' to disable swap (format: <number><optional unit>, where unit = b, k, m or g)"
19
+ option '--cmd', 'CMD', 'Command to execute'
20
+ option '--instances', 'INSTANCES', 'How many instances should be deployed'
21
+ option ['-u', '--user'], 'USER', 'Username who executes first process inside container'
22
+ option '--privileged', :flag, 'Give extended privileges to this service', default: false
23
+ option '--cap-add', 'CAP_ADD', 'Add capabitilies', multivalued: true
24
+ option '--cap-drop', 'CAP_DROP', 'Drop capabitilies', multivalued: true
25
+ option '--net', 'NET', 'Network mode'
26
+ option '--log-driver', 'LOG_DRIVER', 'Set logging driver'
27
+ option '--log-opt', 'LOG_OPT', 'Add logging options', multivalued: true
28
+ option '--deploy-strategy', 'STRATEGY', 'Deploy strategy to use (ha, daemon, random)'
29
+ option '--deploy-wait-for-port', 'PORT', 'Wait for port to respond when deploying'
30
+ option '--deploy-min-health', 'FLOAT', 'The minimum percentage (0.0 - 1.0) of healthy instances that do not sacrifice overall service availability while deploying'
31
+ option '--deploy-interval', 'TIME', 'Auto-deploy with given interval (format: <number><unit>, where unit = min, h, d)'
32
+ option '--pid', 'PID', 'Pid namespace to use'
33
+ option '--secret', 'SECRET', 'Import secret from Vault (format: <secret>:<name>:<type>)', multivalued: true
34
+
35
+ def execute
36
+ require_api_url
37
+ token = require_token
38
+
39
+ data = parse_service_data_from_options
40
+ update_service(token, name, data)
41
+ end
42
+
43
+ ##
44
+ # parse given options to hash
45
+ # @return [Hash]
46
+ def parse_service_data_from_options
47
+ data = {}
48
+ data[:strategy] = deploy_strategy if deploy_strategy
49
+ data[:ports] = parse_ports(ports_list) unless ports_list.empty?
50
+ data[:links] = parse_links(link_list) unless link_list.empty?
51
+ data[:memory] = parse_memory(memory) if memory
52
+ data[:memory_swap] = parse_memory(memory_swap) if memory_swap
53
+ data[:cpu_shares] = cpu_shares if cpu_shares
54
+ data[:affinity] = affinity_list unless affinity_list.empty?
55
+ data[:env] = env_list unless env_list.empty?
56
+ data[:secrets] = parse_secrets(secret_list) unless secret_list.empty?
57
+ data[:container_count] = instances if instances
58
+ data[:cmd] = cmd.split(' ') if cmd
59
+ data[:user] = user if user
60
+ data[:image] = parse_image(image) if image
61
+ data[:privileged] = privileged?
62
+ data[:cap_add] = cap_add_list unless cap_add_list.empty?
63
+ data[:cap_drop] = cap_drop_list unless cap_drop_list.empty?
64
+ data[:net] = net if net
65
+ data[:log_driver] = log_driver if log_driver
66
+ data[:log_opts] = parse_log_opts(log_opt_list)
67
+ data[:deploy_opts] = {}
68
+ data[:deploy_opts][:min_health] = deploy_min_health.to_f if deploy_min_health
69
+ data[:deploy_opts][:wait_for_port] = deploy_wait_for_port.to_i if deploy_wait_for_port
70
+ if deploy_interval
71
+ data[:deploy_opts][:interval] = parse_relative_time(deploy_interval)
72
+ end
73
+ data.delete(:deploy_opts) if data[:deploy_opts].empty?
74
+ data[:pid] = pid if pid
75
+ data
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,32 @@
1
+ require_relative 'stacks/list_command'
2
+ require_relative 'stacks/create_command'
3
+ require_relative 'stacks/update_command'
4
+ require_relative 'stacks/use_command'
5
+ require_relative 'stacks/show_command'
6
+ require_relative 'stacks/logs_command'
7
+ require_relative 'stacks/remove_command'
8
+ require_relative 'stacks/current_command'
9
+ require_relative 'stacks/env_command'
10
+ require_relative 'stacks/audit_log_command'
11
+ require_relative 'stacks/user_command'
12
+ require_relative 'stacks/cloud_config_command'
13
+ require_relative 'stacks/trusted_subnet_command'
14
+
15
+ class Central::Cli::StackCommand < Clamp::Command
16
+ subcommand %w(list ls), 'List all stacks', Central::Cli::Stacks::ListCommand
17
+ subcommand 'create', 'Create a new stack', Central::Cli::Stacks::CreateCommand
18
+ subcommand 'update', 'Update stack', Central::Cli::Stacks::UpdateCommand
19
+ subcommand 'use', 'Switch to use specific stack', Central::Cli::Stacks::UseCommand
20
+ subcommand 'show', 'Show stack details', Central::Cli::Stacks::ShowCommand
21
+ subcommand 'logs', 'Show logs from stack containers', Central::Cli::Stacks::LogsCommand
22
+ subcommand %w(remove rm), 'Remove a stack', Central::Cli::Stacks::RemoveCommand
23
+ subcommand 'current', 'Show current stack details', Central::Cli::Stacks::CurrentCommand
24
+ subcommand 'env', 'Show the current stack environment details', Central::Cli::Stacks::EnvCommand
25
+ subcommand 'audit-log', 'Show audit log of the current stack', Central::Cli::Stacks::AuditLogCommand
26
+ subcommand 'user', 'User specific commands', Central::Cli::Stacks::UserCommand
27
+ subcommand 'cloud-config', 'Generate cloud-config', Central::Cli::Stacks::CloudConfigCommand
28
+ subcommand 'trusted-subnet', 'Trusted subnet related commands', Central::Cli::Stacks::TrustedSubnetCommand
29
+
30
+ def execute
31
+ end
32
+ end
@@ -0,0 +1,11 @@
1
+ module Central
2
+ module Cli
3
+ module StackOptions
4
+ def self.included(base)
5
+ if base.respond_to?(:option)
6
+ base.option '--stack', 'STACK', 'Specify stack to use'
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,18 @@
1
+ require_relative 'common'
2
+
3
+ module Central::Cli::Stacks
4
+ class AddUserCommand < Clamp::Command
5
+ include Central::Cli::Common
6
+ include Central::Cli::StackOptions
7
+ include Common
8
+
9
+ parameter 'EMAIL', 'Email address'
10
+
11
+ def execute
12
+ require_api_url
13
+ token = require_token
14
+ data = { email: email }
15
+ client(token).post("stacks/#{current_stack}/users", data)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,21 @@
1
+ require_relative 'common'
2
+
3
+ module Central::Cli::Stacks
4
+ class AuditLogCommand < Clamp::Command
5
+ include Central::Cli::Common
6
+ include Common
7
+
8
+ option ['-l', '--lines'], 'LINES', 'Number of lines'
9
+
10
+ def execute
11
+ require_api_url
12
+ require_current_stack
13
+ token = require_token
14
+ audit_logs = client(token).get("stacks/#{current_stack}/audit_log", limit: lines)
15
+ puts '%-30.30s %-10s %-15s %-25s %-15s %-25s %-15s %-15s' % ['Time', 'Stack', 'Resource Type', 'Resource Name', 'Event Name', 'User', 'Source IP', 'User-Agent']
16
+ audit_logs['logs'].each do |log|
17
+ puts '%-30.30s %-10s %-15s %-25s %-15s %-25s %-15s %-15s' % [log['time'], log['stack'], log['resource_type'], log['resource_name'], log['event_name'], log['user_identity']['email'], log['source_ip'], log['user_agent']]
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,41 @@
1
+ require_relative 'common'
2
+
3
+ module Central::Cli::Stacks
4
+ class CloudConfigCommand < Clamp::Command
5
+ include Central::Cli::Common
6
+ include Common
7
+
8
+ parameter 'NAME', 'Stack name'
9
+ option '--dns', 'DNS', 'DNS server', multivalued: true
10
+ option '--peer-interface', 'IFACE', 'Peer (private) network interface', default: 'eth1'
11
+ option '--docker-bip', 'BIP', 'Docker bridge ip', default: '172.17.43.1/16'
12
+ option '--version', 'VERSION', 'Agent version', default: 'latest'
13
+
14
+ def execute
15
+ require_api_url
16
+ token = require_token
17
+
18
+ stack = find_stack_by_name(name)
19
+ abort('Stack not found'.colorize(:red)) unless stack
20
+
21
+ default_dns = docker_bip.split('/')[0]
22
+ dns_servers = if dns_list.size > 0
23
+ [default_dns] + dns_list
24
+ else
25
+ [default_dns, '8.8.8.8', '8.8.4.4']
26
+ end
27
+
28
+ require 'central/machine/cloud_config/node_generator'
29
+ generator = Central::Machine::CloudConfig::NodeGenerator.new
30
+ config = generator.generate(
31
+ master_uri: api_url,
32
+ stack_token: stack['token'],
33
+ peer_interface: peer_interface,
34
+ dns_servers: dns_servers,
35
+ docker_bip: docker_bip,
36
+ version: version
37
+ )
38
+ puts config
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,95 @@
1
+ module Central::Cli::Stacks
2
+ module Common
3
+ ##
4
+ # @param [Hash] stack
5
+ def print_stack(stack)
6
+ puts "#{stack['name']}:"
7
+ puts " uri: #{current_master['url'].sub('http', 'ws')}"
8
+ puts " token: #{stack['token']}"
9
+ root_dir = stack['engine_root_dir']
10
+ nodes = client(require_token).get("stacks/#{stack['name']}/nodes")
11
+ nodes = nodes['nodes'].select { |n| n['connected'] == true }
12
+ node_count = nodes.size
13
+ puts ' stats:'
14
+ puts " nodes: #{nodes.size} of #{stack['node_count']}"
15
+
16
+ cpu_total = nodes.map { |n| n['cpus'].to_i }.inject(:+)
17
+ puts " cpus: #{cpu_total || 0}"
18
+
19
+ loads = calculate_loads(nodes, node_count)
20
+ puts " load: #{(loads[:'1m'] || 0.0).round(2)} #{(loads[:'5m'] || 0.0).round(2)} #{(loads[:'15m'] || 0.0).round(2)}"
21
+
22
+ mem_total = nodes.map { |n| n['mem_total'].to_i }.inject(:+)
23
+ mem_used = calculate_mem_used(nodes)
24
+ puts " memory: #{to_gigabytes(mem_used)} of #{to_gigabytes(mem_total)} GB"
25
+
26
+ total_fs = calculate_filesystem_stats(nodes)
27
+ puts " filesystem: #{to_gigabytes(total_fs['used'])} of #{to_gigabytes(total_fs['total'])} GB"
28
+
29
+ puts " users: #{stack['user_count']}"
30
+ puts " services: #{stack['service_count']}"
31
+ puts " containers: #{stack['container_count']}"
32
+ if statsd = stack.dig('stats', 'statsd')
33
+ puts ' exports:'
34
+ puts " statsd: #{statsd['server']}:#{statsd['port']}"
35
+ end
36
+ end
37
+
38
+ def stacks
39
+ @stacks ||= client(require_token).get('stacks')
40
+ end
41
+
42
+ # @param [Array<Hash>] nodes
43
+ # @param [Fixnum] node_count
44
+ # @return [Hash]
45
+ def calculate_loads(nodes, node_count)
46
+ loads = { :'1m' => 0.0, :'5m' => 0.0, :'15m' => 0.0 }
47
+ return loads if node_count == 0
48
+
49
+ loads[:'1m'] = nodes.map { |n| n.dig('resource_usage', 'load', '1m').to_f }.inject(:+) / node_count
50
+ loads[:'5m'] = nodes.map { |n| n.dig('resource_usage', 'load', '5m').to_f }.inject(:+) / node_count
51
+ loads[:'15m'] = nodes.map { |n| n.dig('resource_usage', 'load', '15m').to_f }.inject(:+) / node_count
52
+ loads
53
+ end
54
+
55
+ # @param [Array<Hash>] nodes
56
+ # @return [Float]
57
+ def calculate_mem_used(nodes)
58
+ nodes.map do|n|
59
+ mem = n.dig('resource_usage', 'memory')
60
+ if mem
61
+ mem['used'] - (mem['cached'] + mem['buffers'])
62
+ else
63
+ 0.0
64
+ end
65
+ end.inject(:+)
66
+ end
67
+
68
+ # @param [Array<Hash>] nodes
69
+ # @return [Hash]
70
+ def calculate_filesystem_stats(nodes)
71
+ total_fs = {
72
+ 'used' => 0.0,
73
+ 'total' => 0.0
74
+ }
75
+ nodes.each do |node|
76
+ root_dir = node['engine_root_dir']
77
+ filesystems = node.dig('resource_usage', 'filesystem') || []
78
+ root_fs = filesystems.find { |fs| fs['name'] == root_dir }
79
+ total_fs['used'] += root_fs['used']
80
+ total_fs['total'] += root_fs['total']
81
+ end
82
+
83
+ total_fs
84
+ end
85
+
86
+ def find_stack_by_name(name)
87
+ stacks['stacks'].find { |stack| stack['name'] == name }
88
+ end
89
+
90
+ def to_gigabytes(amount)
91
+ return 0.0 if amount.nil?
92
+ (amount.to_f / 1024 / 1024 / 1024).to_f.round(2)
93
+ end
94
+ end
95
+ end