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,38 @@
1
+ require 'fileutils'
2
+
3
+ module Central
4
+ module Machine
5
+ module Vagrant
6
+ class NodeDestroyer
7
+ include RandomName
8
+
9
+ attr_reader :client, :api_client
10
+
11
+ # @param [Central::Client] api_client Central api client
12
+ def initialize(api_client)
13
+ @api_client = api_client
14
+ end
15
+
16
+ def run!(stack, name)
17
+ vagrant_path = "#{Dir.home}/.central/#{stack}/#{name}"
18
+ Dir.chdir(vagrant_path) do
19
+ ShellSpinner "Terminating Vagrant machine #{name.colorize(:cyan)} " do
20
+ Open3.popen2('vagrant destroy -f') do |_stdin, output, wait|
21
+ while o = output.gets
22
+ puts o if ENV['DEBUG']
23
+ end
24
+ FileUtils.remove_entry_secure(vagrant_path) if wait.value == 0
25
+ end
26
+ end
27
+ end
28
+ node = api_client.get("stacks/#{stack}/nodes")['nodes'].find { |n| n['name'] == name }
29
+ if node
30
+ ShellSpinner "Removing node #{name.colorize(:cyan)} from stack #{stack.colorize(:cyan)} " do
31
+ api_client.delete("stacks/#{stack}/nodes/#{name}")
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,68 @@
1
+ require 'fileutils'
2
+ require 'erb'
3
+ require 'open3'
4
+ require 'shell-spinner'
5
+
6
+ module Central
7
+ module Machine
8
+ module Vagrant
9
+ class NodeProvisioner
10
+ include RandomName
11
+
12
+ attr_reader :client, :api_client
13
+
14
+ # @param [Central::Client] api_client Central api client
15
+ def initialize(api_client)
16
+ @api_client = api_client
17
+ end
18
+
19
+ def run!(opts)
20
+ stack = opts[:stack]
21
+ name = opts[:name] || generate_name
22
+ version = opts[:version]
23
+ vagrant_path = "#{Dir.home}/.central/#{stack}/#{name}"
24
+ FileUtils.mkdir_p(vagrant_path)
25
+
26
+ template = File.join(__dir__, '/Vagrantfile.node.rb.erb')
27
+ cloudinit_template = File.join(__dir__, '/cloudinit.yml')
28
+ vars = {
29
+ name: name,
30
+ version: version,
31
+ memory: opts[:memory] || 1024,
32
+ master_uri: opts[:master_uri],
33
+ stack_token: opts[:stack_token],
34
+ cloudinit: "#{vagrant_path}/cloudinit.yml"
35
+ }
36
+ vagrant_data = erb(File.read(template), vars)
37
+ cloudinit = erb(File.read(cloudinit_template), vars)
38
+ File.write("#{vagrant_path}/Vagrantfile", vagrant_data)
39
+ File.write("#{vagrant_path}/cloudinit.yml", cloudinit)
40
+ Dir.chdir(vagrant_path) do
41
+ ShellSpinner "Creating Vagrant machine #{name.colorize(:cyan)} " do
42
+ Open3.popen2('vagrant box update && vagrant up') do |_stdin, output, _wait|
43
+ while o = output.gets
44
+ print o if ENV['DEBUG']
45
+ end
46
+ end
47
+ end
48
+ ShellSpinner "Waiting for node #{name.colorize(:cyan)} join to stack #{stack.colorize(:cyan)} " do
49
+ sleep 1 until node_exists_in_stack?(stack, name)
50
+ end
51
+ end
52
+ end
53
+
54
+ def generate_name
55
+ "#{super}-#{rand(1..99)}"
56
+ end
57
+
58
+ def erb(template, vars)
59
+ ERB.new(template).result(OpenStruct.new(vars).instance_eval { binding })
60
+ end
61
+
62
+ def node_exists_in_stack?(stack, name)
63
+ api_client.get("stacks/#{stack}/nodes")['nodes'].find { |n| n['name'] == name }
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ # resolve bin path, ignoring symlinks
5
+ require 'pathname'
6
+ require 'yaml'
7
+ bin_file = Pathname.new(__FILE__).realpath
8
+
9
+ # add self to libpath
10
+ $LOAD_PATH.unshift File.expand_path('../../lib', bin_file)
11
+
12
+ require_relative '../client'
13
+ require_relative '../cli/common'
14
+
15
+ class Helper
16
+ include Central::Cli::Common
17
+
18
+ def client
19
+ token = require_token
20
+ super(token)
21
+ end
22
+
23
+ def stacks
24
+ client.get('stacks')['stacks'].map { |stack| stack['id'] }
25
+ rescue
26
+ []
27
+ end
28
+
29
+ def nodes
30
+ client.get("stacks/#{current_stack}/nodes")['nodes'].map { |node| node['name'] }
31
+ rescue
32
+ []
33
+ end
34
+
35
+ def services
36
+ services = client.get("stacks/#{current_stack}/services")['services']
37
+ results = []
38
+ results.push services.map { |s| s['name'] }
39
+
40
+ results
41
+ rescue
42
+ []
43
+ end
44
+
45
+ def containers
46
+ results = []
47
+ client.get("stacks/#{current_stack}/services")['services'].each do |service|
48
+ containers = client.get("services/#{service['id']}/containers")['containers']
49
+ results.push(containers.map { |c| c['name'] })
50
+ results.push(containers.map { |c| c['id'] })
51
+ end
52
+ results
53
+ rescue
54
+ []
55
+ end
56
+
57
+ def yml_services
58
+ if File.exist?('central.yml')
59
+ services = YAML.load(File.read('central.yml'))
60
+ services.keys
61
+ end
62
+ rescue
63
+ []
64
+ end
65
+
66
+ def master_names
67
+ config_file = File.expand_path('~/.central_client.json')
68
+ if File.exist?(config_file)
69
+ config = JSON.parse(File.read(config_file))
70
+ return config['servers'].map { |s| s['name'] }
71
+ end
72
+ rescue
73
+ []
74
+ end
75
+ end
76
+
77
+ helper = Helper.new
78
+
79
+ words = ARGV
80
+ words.delete_at(0)
81
+
82
+ completion = []
83
+ completion.push %w(app deploy forgot-password master node stack service container vpn external-registry registry login logout whoami) if words.size < 2
84
+ if words.size > 0
85
+ case words[0]
86
+ when 'stack'
87
+ completion.clear
88
+ sub_commands = %w(add-user audit-log create current list user remove show use)
89
+ if words[1]
90
+ completion.push(sub_commands) unless sub_commands.include?(words[1])
91
+ completion.push helper.stacks
92
+ else
93
+ completion.push sub_commands
94
+ end
95
+ when 'node'
96
+ completion.clear
97
+ sub_commands = %w(list show remove vagrant digitalocean azure aws)
98
+ if words[1]
99
+ completion.push(sub_commands) unless sub_commands.include?(words[1])
100
+ completion.push helper.nodes
101
+ else
102
+ completion.push sub_commands
103
+ end
104
+ when 'master'
105
+ completion.clear
106
+ sub_commands = %w(list use vagrant digitalocean azure aws users)
107
+ if words[1] && words[1] == 'use'
108
+ completion.push helper.master_names
109
+ elsif words[1] && words[1] == 'users'
110
+ users_sub_commands = %(invite list role)
111
+ completion.push users_sub_commands
112
+ elsif words[1]
113
+ completion.push(sub_commands) unless sub_commands.include?(words[1])
114
+ completion.push %w(create)
115
+ else
116
+ completion.push sub_commands
117
+ end
118
+ when 'service'
119
+ completion.clear
120
+ sub_commands = %w(containers create delete deploy list logs restart
121
+ scale show start stats stop update monitor env
122
+ secret link unlink)
123
+ if words[1]
124
+ completion.push(sub_commands) unless sub_commands.include?(words[1])
125
+ completion.push helper.services
126
+ else
127
+ completion.push sub_commands
128
+ end
129
+ when 'container'
130
+ completion.clear
131
+ sub_commands = %w(exec)
132
+ if words[1]
133
+ completion.push(sub_commands) unless sub_commands.include?(words[1])
134
+ completion.push helper.containers
135
+ else
136
+ completion.push sub_commands
137
+ end
138
+ when 'vpn'
139
+ completion.clear
140
+ completion.push %w(config create delete)
141
+ when 'external-registry'
142
+ completion.clear
143
+ completion.push %w(add list delete)
144
+ when 'app'
145
+ completion.clear
146
+ sub_commands = %w(init build deploy start stop remove rm ps list
147
+ logs monitor show)
148
+ if words[1]
149
+ completion.push(sub_commands) unless sub_commands.include?(words[1])
150
+ completion.push helper.yml_services
151
+ else
152
+ completion.push sub_commands
153
+ end
154
+ end
155
+ end
156
+
157
+ puts completion
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env bash
2
+
3
+ _central_complete() {
4
+ COMPREPLY=()
5
+ DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
6
+ local word="${COMP_WORDS[COMP_CWORD]}"
7
+ local completions="$(${DIR}/completer ${COMP_WORDS[*]})"
8
+ COMPREPLY=( $(compgen -W "$completions" -- "$word") )
9
+ }
10
+
11
+ complete -F _central_complete central
@@ -0,0 +1,150 @@
1
+ require_relative '../../../spec_helper'
2
+ require 'central/cli/apps/common'
3
+
4
+ describe Central::Cli::Apps::Common do
5
+ include ClientHelpers
6
+ include FixturesHelpers
7
+
8
+ let(:subject) do
9
+ Class.new { include Central::Cli::Apps::Common }.new
10
+ end
11
+
12
+ let(:central_yml) do
13
+ fixture('central.yml')
14
+ end
15
+
16
+ let(:docker_compose_yml) do
17
+ fixture('docker-compose.yml')
18
+ end
19
+
20
+ let(:mysql_yml) do
21
+ fixture('mysql.yml')
22
+ end
23
+
24
+ let(:services) do
25
+ {
26
+ 'wordpress' => {
27
+ 'image' => 'wordpress:4.1',
28
+ 'ports' => ['80:80']
29
+ }
30
+ }
31
+ end
32
+
33
+ describe '#parse_services' do
34
+ it 'returns services from given YAML file' do
35
+ allow(File).to receive(:read).with("#{Dir.getwd}/central.yml").and_return(central_yml)
36
+ allow(File).to receive(:read).with("#{Dir.getwd}/docker-compose.yml").and_return(docker_compose_yml)
37
+ services = subject.parse_services('central.yml')
38
+ expect(services['wordpress']).not_to be_nil
39
+ end
40
+
41
+ it 'raises error if extended service is not found from base file' do
42
+ allow(File).to receive(:read).with("#{Dir.getwd}/central.yml").and_return(central_yml)
43
+ allow(File).to receive(:read).with("#{Dir.getwd}/docker-compose.yml").and_return(mysql_yml)
44
+
45
+ expect do
46
+ subject.parse_services('central.yml')
47
+ end.to raise_error(SystemExit)
48
+ end
49
+ end
50
+
51
+ describe '#normalize_env_vars' do
52
+ it 'converts env hash to array' do
53
+ opts = {
54
+ 'environment' => {
55
+ 'FOO' => 'bar',
56
+ 'BAR' => 'baz'
57
+ }
58
+ }
59
+ subject.normalize_env_vars(opts)
60
+ env = opts['environment']
61
+ expect(env).to include('FOO=bar')
62
+ expect(env).to include('BAR=baz')
63
+ end
64
+
65
+ it 'does nothing to env array' do
66
+ opts = {
67
+ 'environment' => [
68
+ 'FOO=bar', 'BAR=baz'
69
+ ]
70
+ }
71
+ subject.normalize_env_vars(opts)
72
+ env = opts['environment']
73
+ expect(env).to include('FOO=bar')
74
+ expect(env).to include('BAR=baz')
75
+ end
76
+ end
77
+
78
+ describe '#extend_env_vars' do
79
+ it 'inherites env vars from upper level' do
80
+ from = ['FOO=bar']
81
+ to = nil
82
+ env_vars = subject.extend_env_vars(from, to)
83
+ expect(env_vars).to eq(['FOO=bar'])
84
+ end
85
+
86
+ it 'overrides values' do
87
+ from = ['FOO=bar']
88
+ to = ['FOO=baz']
89
+ env_vars = subject.extend_env_vars(from, to)
90
+ expect(env_vars).to eq(['FOO=baz'])
91
+ end
92
+
93
+ it 'combines variables' do
94
+ from = ['FOO=bar']
95
+ to = ['BAR=baz']
96
+ env_vars = subject.extend_env_vars(from, to)
97
+ expect(env_vars).to eq(['BAR=baz', 'FOO=bar'])
98
+ end
99
+ end
100
+
101
+ describe '#extend_secrets' do
102
+ it 'inherites secrets from upper level' do
103
+ secret = {
104
+ 'secret' => 'CUSTOMER_DB_PASSWORD',
105
+ 'name' => 'MYSQL_PASSWORD',
106
+ 'type' => 'env'
107
+ }
108
+ from = [secret]
109
+ to = nil
110
+ secrets = subject.extend_secrets(from, to)
111
+ expect(secrets).to eq([secret])
112
+ end
113
+
114
+ it 'overrides secrets' do
115
+ from_secret = {
116
+ 'secret' => 'CUSTOMER_DB_PASSWORD',
117
+ 'name' => 'MYSQL_PASSWORD',
118
+ 'type' => 'env'
119
+ }
120
+
121
+ to_secret = {
122
+ 'secret' => 'CUSTOMER_DB_PASSWORD',
123
+ 'name' => 'MYSQL_ROOT_PASSWORD',
124
+ 'type' => 'env'
125
+ }
126
+ from = [from_secret]
127
+ to = [to_secret]
128
+ secrets = subject.extend_secrets(from, to)
129
+ expect(secrets).to eq([to_secret])
130
+ end
131
+
132
+ it 'combines secrets' do
133
+ from_secret = {
134
+ 'secret' => 'CUSTOMER_DB_PASSWORD',
135
+ 'name' => 'MYSQL_PASSWORD',
136
+ 'type' => 'env'
137
+ }
138
+
139
+ to_secret = {
140
+ 'secret' => 'CUSTOMER_API_TOKEN',
141
+ 'name' => 'API_TOKEN',
142
+ 'type' => 'env'
143
+ }
144
+ from = [from_secret]
145
+ to = [to_secret]
146
+ secrets = subject.extend_secrets(from, to)
147
+ expect(secrets).to eq([to_secret, from_secret])
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,598 @@
1
+ require_relative '../../../spec_helper'
2
+ require 'central/cli/stack_options'
3
+ require 'central/cli/apps/deploy_command'
4
+
5
+ describe Central::Cli::Apps::DeployCommand do
6
+ include FixturesHelpers
7
+
8
+ let(:subject) do
9
+ described_class.new(File.basename($PROGRAM_NAME))
10
+ end
11
+
12
+ let(:settings) do
13
+ { 'current_server' => 'alias',
14
+ 'servers' => [
15
+ { 'name' => 'some_master', 'url' => 'some_master' },
16
+ { 'name' => 'alias', 'url' => 'someurl', 'token' => token }
17
+ ]
18
+ }
19
+ end
20
+
21
+ let(:settings_without_api_url) do
22
+ { 'current_server' => 'alias',
23
+ 'servers' => [
24
+ { 'name' => 'alias', 'token' => token }
25
+ ]
26
+ }
27
+ end
28
+
29
+ let(:settings_without_token) do
30
+ { 'current_server' => 'alias',
31
+ 'servers' => [
32
+ { 'name' => 'alias', 'url' => 'url' }
33
+ ]
34
+ }
35
+ end
36
+
37
+ let(:token) do
38
+ '1234567'
39
+ end
40
+
41
+ let(:docker_compose_yml) do
42
+ fixture('docker-compose.yml')
43
+ end
44
+
45
+ let(:central_yml) do
46
+ fixture('central.yml')
47
+ end
48
+
49
+ let(:services) do
50
+ {
51
+ 'wordpress' => {
52
+ 'image' => 'wordpress:latest',
53
+ 'links' => ['mysql:db'],
54
+ 'ports' => ['80:80'],
55
+ 'instances' => 2,
56
+ 'deploy' => {
57
+ 'strategy' => 'ha'
58
+ }
59
+ },
60
+ 'mysql' => {
61
+ 'image' => 'mysql:5.6',
62
+ 'stateful' => true
63
+ }
64
+ }
65
+ end
66
+
67
+ let(:client) do
68
+ double
69
+ end
70
+
71
+ let(:options) do
72
+ double(prefix: false, file: false, service: nil)
73
+ end
74
+
75
+ let(:env_vars) do
76
+ ['#comment line', 'TEST_ENV_VAR=test', 'MYSQL_ADMIN_PASSWORD=abcdef']
77
+ end
78
+
79
+ let(:dot_env) do
80
+ ['TEST_ENV_VAR=test2', '', 'TEST_ENV_VAR2=test3']
81
+ end
82
+
83
+ describe '.run' do
84
+ before(:each) do
85
+ allow(subject).to receive(:wait_for_deploy_to_finish).and_return(true)
86
+ end
87
+
88
+ context 'when api_url is nil' do
89
+ it 'raises error' do
90
+ allow(subject).to receive(:settings).and_return(settings_without_api_url)
91
+ expect { subject.run([]) }.to raise_error(ArgumentError)
92
+ end
93
+ end
94
+
95
+ context 'when token is nil' do
96
+ it 'raises error' do
97
+ allow(subject).to receive(:settings).and_return(settings_without_token)
98
+ expect { subject.run([]) }.to raise_error(ArgumentError)
99
+ end
100
+ end
101
+
102
+ context 'when api url and token are valid' do
103
+ before(:each) do
104
+ allow(subject).to receive(:settings).and_return(settings)
105
+ allow(File).to receive(:exists?).and_return(true)
106
+ allow(File).to receive(:read).with("#{Dir.getwd}/central.yml").and_return(central_yml)
107
+ allow(File).to receive(:read).with("#{Dir.getwd}/docker-compose.yml").and_return(docker_compose_yml)
108
+ allow(subject).to receive(:get_service).and_raise(Central::Errors::StandardError.new(404, 'Not Found'))
109
+ allow(subject).to receive(:create_service).and_return({ 'id' => 'cli/central-test-mysql', 'name' => 'central-test-mysql' }, 'id' => 'cli/central-test-wordpress', 'name' => 'central-test-wordpress')
110
+ allow(subject).to receive(:current_stack).and_return('1')
111
+ allow(subject).to receive(:deploy_service).and_return(nil)
112
+ end
113
+
114
+ it 'reads ./central.yml file by default' do
115
+ allow(subject).to receive(:settings).and_return(settings)
116
+ expect(File).to receive(:read).with("#{Dir.getwd}/central.yml").and_return(central_yml)
117
+ subject.run([])
118
+ end
119
+
120
+ it 'reads given yml file' do
121
+ expect(File).to receive(:read).with("#{Dir.getwd}/custom.yml").and_return(central_yml)
122
+ subject.run(['--file', 'custom.yml'])
123
+ end
124
+
125
+ it 'uses current directory as service name prefix by default' do
126
+ current_dir = '/central/tests/stacks'
127
+ allow(Dir).to receive(:getwd).and_return(current_dir)
128
+ expect(File).to receive(:basename).with(current_dir).and_return('stacks')
129
+ subject.run([])
130
+ end
131
+
132
+ context 'when yml file has multiple env files' do
133
+ it 'merges environment variables correctly' do
134
+ allow(subject).to receive(:current_dir).and_return('central-test')
135
+ allow(YAML).to receive(:load).and_return(services)
136
+ services['wordpress']['environment'] = ['MYSQL_ADMIN_PASSWORD=password']
137
+ services['wordpress']['env_file'] = %w(/path/to/env_file .env)
138
+
139
+ expect(File).to receive(:readlines).with('/path/to/env_file').and_return(env_vars)
140
+ expect(File).to receive(:readlines).with('.env').and_return(dot_env)
141
+
142
+ data = {
143
+ name: 'central-test-wordpress',
144
+ image: 'wordpress:latest',
145
+ env: ['MYSQL_ADMIN_PASSWORD=password', 'TEST_ENV_VAR=test', 'TEST_ENV_VAR2=test3'],
146
+ container_count: 2,
147
+ stateful: false,
148
+ strategy: 'ha',
149
+ links: [{ name: 'central-test-mysql', alias: 'db' }],
150
+ ports: [{ container_port: '80', node_port: '80', protocol: 'tcp' }]
151
+ }
152
+
153
+ expect(subject).to receive(:create_service).with('1234567', '1', hash_including(data))
154
+ subject.run([])
155
+ end
156
+ end
157
+
158
+ context 'when yml file has one env file' do
159
+ it 'merges environment variables correctly' do
160
+ allow(subject).to receive(:current_dir).and_return('central-test')
161
+ allow(YAML).to receive(:load).and_return(services)
162
+ services['wordpress']['environment'] = ['MYSQL_ADMIN_PASSWORD=password']
163
+ services['wordpress']['env_file'] = '/path/to/env_file'
164
+
165
+ expect(File).to receive(:readlines).with('/path/to/env_file').and_return(env_vars)
166
+
167
+ data = {
168
+ name: 'central-test-wordpress',
169
+ image: 'wordpress:latest',
170
+ env: ['MYSQL_ADMIN_PASSWORD=password', 'TEST_ENV_VAR=test'],
171
+ container_count: 2,
172
+ stateful: false,
173
+ strategy: 'ha',
174
+ links: [{ name: 'central-test-mysql', alias: 'db' }],
175
+ ports: [{ container_port: '80', node_port: '80', protocol: 'tcp' }]
176
+ }
177
+
178
+ expect(subject).to receive(:create_service).with('1234567', '1', hash_including(data))
179
+ subject.run([])
180
+ end
181
+ end
182
+
183
+ it 'merges external links to links' do
184
+ allow(subject).to receive(:current_dir).and_return('central-test')
185
+ allow(YAML).to receive(:load).and_return(services)
186
+ services['wordpress']['external_links'] = ['loadbalancer:loadbalancer']
187
+ data = {
188
+ name: 'central-test-wordpress',
189
+ image: 'wordpress:latest',
190
+ env: nil,
191
+ container_count: 2,
192
+ stateful: false,
193
+ strategy: 'ha',
194
+ links: [{ name: 'central-test-mysql', alias: 'db' }, { name: 'loadbalancer', alias: 'loadbalancer' }],
195
+ ports: [{ container_port: '80', node_port: '80', protocol: 'tcp' }]
196
+ }
197
+
198
+ expect(subject).to receive(:create_service).with('1234567', '1', hash_including(data))
199
+ subject.run([])
200
+ end
201
+
202
+ it 'creates mysql service before wordpress' do
203
+ allow(subject).to receive(:current_dir).and_return('central-test')
204
+ data = {
205
+ name: 'central-test-mysql',
206
+ image: 'mysql:5.6',
207
+ env: ['MYSQL_ROOT_PASSWORD=central-test_secret'],
208
+ container_count: nil,
209
+ stateful: true
210
+ }
211
+ expect(subject).to receive(:create_service).with('1234567', '1', hash_including(data))
212
+
213
+ subject.run([])
214
+ end
215
+
216
+ it 'creates wordpress service' do
217
+ allow(subject).to receive(:current_dir).and_return('central-test')
218
+
219
+ data = {
220
+ name: 'central-test-wordpress',
221
+ image: 'wordpress:4.1',
222
+ env: ['WORDPRESS_DB_PASSWORD=central-test_secret'],
223
+ container_count: 2,
224
+ stateful: true,
225
+ strategy: 'ha',
226
+ links: [{ name: 'central-test-mysql', alias: 'mysql' }],
227
+ ports: [{ container_port: '80', node_port: '80', protocol: 'tcp' }]
228
+ }
229
+ expect(subject).to receive(:create_service).with('1234567', '1', hash_including(data))
230
+
231
+ subject.run([])
232
+ end
233
+
234
+ it 'deploys services' do
235
+ allow(subject).to receive(:current_dir).and_return('central-test')
236
+ expect(subject).to receive(:deploy_service).with('1234567', 'central-test-mysql', {})
237
+ expect(subject).to receive(:deploy_service).with('1234567', 'central-test-wordpress', {})
238
+ subject.run([])
239
+ end
240
+
241
+ context 'when giving service option' do
242
+ it 'deploys only given services' do
243
+ allow(subject).to receive(:current_dir).and_return('central-test')
244
+ allow(subject).to receive(:deploy_services).and_return({})
245
+ expect(subject).to receive(:create).once.with('wordpress', anything).and_return({})
246
+ expect(subject).not_to receive(:create).with('mysql', services['mysql'])
247
+
248
+ subject.run(['wordpress'])
249
+ end
250
+ end
251
+ end
252
+ end
253
+
254
+ describe '#parse_data' do
255
+ context 'volumes' do
256
+ it 'returns volumes if set' do
257
+ data = {
258
+ 'image' => 'foo/bar:latest',
259
+ 'volumes' => [
260
+ 'mongodb-1'
261
+ ]
262
+ }
263
+ result = subject.send(:parse_data, data)
264
+ expect(result[:volumes]).to eq(data['volumes'])
265
+ end
266
+
267
+ it 'returns empty volumes if not set' do
268
+ data = {
269
+ 'image' => 'foo/bar:latest'
270
+ }
271
+ result = subject.send(:parse_data, data)
272
+ expect(result[:volumes]).to eq([])
273
+ end
274
+ end
275
+
276
+ context 'volumes_from' do
277
+ it 'returns volumes_from if set' do
278
+ data = {
279
+ 'image' => 'foo/bar:latest',
280
+ 'volumes_from' => [
281
+ 'mongodb-1'
282
+ ]
283
+ }
284
+ result = subject.send(:parse_data, data)
285
+ expect(result[:volumes_from]).to eq(data['volumes_from'])
286
+ end
287
+
288
+ it 'returns empty volumes_from if not set' do
289
+ data = {
290
+ 'image' => 'foo/bar:latest'
291
+ }
292
+ result = subject.send(:parse_data, data)
293
+ expect(result[:volumes_from]).to eq([])
294
+ end
295
+ end
296
+
297
+ context 'command' do
298
+ it 'returns cmd array if set' do
299
+ data = {
300
+ 'image' => 'foo/bar:latest',
301
+ 'command' => 'ls -la'
302
+ }
303
+ result = subject.send(:parse_data, data)
304
+ expect(result[:cmd]).to eq(data['command'].split(' '))
305
+ end
306
+
307
+ it 'does not return cmd if not set' do
308
+ data = {
309
+ 'image' => 'foo/bar:latest'
310
+ }
311
+ result = subject.send(:parse_data, data)
312
+ expect(result.key?(:cmd)).to be_falsey
313
+ end
314
+ end
315
+
316
+ context 'affinity' do
317
+ it 'returns affinity if set' do
318
+ data = {
319
+ 'image' => 'foo/bar:latest',
320
+ 'affinity' => [
321
+ 'label==az=b'
322
+ ]
323
+ }
324
+ result = subject.send(:parse_data, data)
325
+ expect(result[:affinity]).to eq(data['affinity'])
326
+ end
327
+
328
+ it 'returns affinity as empty array if not set' do
329
+ data = {
330
+ 'image' => 'foo/bar:latest'
331
+ }
332
+ result = subject.send(:parse_data, data)
333
+ expect(result.key?(:affinity)).to be_truthy
334
+ expect(result[:affinity]).to eq([])
335
+ end
336
+ end
337
+
338
+ context 'user' do
339
+ it 'returns user if set' do
340
+ data = {
341
+ 'image' => 'foo/bar:latest',
342
+ 'user' => 'user'
343
+ }
344
+ result = subject.send(:parse_data, data)
345
+ expect(result[:user]).to eq('user')
346
+ end
347
+
348
+ it 'does not return user if not set' do
349
+ data = {
350
+ 'image' => 'foo/bar:latest'
351
+ }
352
+ result = subject.send(:parse_data, data)
353
+ expect(result.key?(:user)).to be_falsey
354
+ end
355
+ end
356
+
357
+ context 'stateful' do
358
+ it 'returns stateful if set' do
359
+ data = {
360
+ 'image' => 'foo/bar:latest',
361
+ 'stateful' => true
362
+ }
363
+ result = subject.send(:parse_data, data)
364
+ expect(result[:stateful]).to eq(true)
365
+ end
366
+
367
+ it 'returns stateful as false if not set' do
368
+ data = {
369
+ 'image' => 'foo/bar:latest'
370
+ }
371
+ result = subject.send(:parse_data, data)
372
+ expect(result[:stateful]).to eq(false)
373
+ end
374
+ end
375
+
376
+ context 'privileged' do
377
+ it 'returns privileged if set' do
378
+ data = {
379
+ 'image' => 'foo/bar:latest',
380
+ 'privileged' => false
381
+ }
382
+ result = subject.send(:parse_data, data)
383
+ expect(result[:privileged]).to eq(false)
384
+ end
385
+
386
+ it 'does not return privileged if not set' do
387
+ data = {
388
+ 'image' => 'foo/bar:latest'
389
+ }
390
+ result = subject.send(:parse_data, data)
391
+ expect(result[:privileged]).to be_nil
392
+ end
393
+ end
394
+
395
+ context 'cap_add' do
396
+ it 'returns cap_drop if set' do
397
+ data = {
398
+ 'image' => 'foo/bar:latest',
399
+ 'cap_add' => [
400
+ 'NET_ADMIN'
401
+ ]
402
+ }
403
+ result = subject.send(:parse_data, data)
404
+ expect(result[:cap_add]).to eq(data['cap_add'])
405
+ end
406
+
407
+ it 'does not return cap_add if not set' do
408
+ data = {
409
+ 'image' => 'foo/bar:latest'
410
+ }
411
+ result = subject.send(:parse_data, data)
412
+ expect(result[:cap_add]).to be_nil
413
+ end
414
+ end
415
+
416
+ context 'cap_drop' do
417
+ it 'returns cap_drop if set' do
418
+ data = {
419
+ 'image' => 'foo/bar:latest',
420
+ 'cap_drop' => [
421
+ 'NET_ADMIN'
422
+ ]
423
+ }
424
+ result = subject.send(:parse_data, data)
425
+ expect(result[:cap_drop]).to eq(data['cap_drop'])
426
+ end
427
+
428
+ it 'does not return cap_drop if not set' do
429
+ data = {
430
+ 'image' => 'foo/bar:latest'
431
+ }
432
+ result = subject.send(:parse_data, data)
433
+ expect(result[:cap_drop]).to be_nil
434
+ end
435
+ end
436
+
437
+ context 'net' do
438
+ it 'returns net if set' do
439
+ data = {
440
+ 'image' => 'foo/bar:latest',
441
+ 'net' => 'host'
442
+ }
443
+ result = subject.send(:parse_data, data)
444
+ expect(result[:net]).to eq('host')
445
+ end
446
+
447
+ it 'does not return pid if not set' do
448
+ data = {
449
+ 'image' => 'foo/bar:latest'
450
+ }
451
+ result = subject.send(:parse_data, data)
452
+ expect(result[:net]).to be_nil
453
+ end
454
+ end
455
+
456
+ context 'pid' do
457
+ it 'returns pid if set' do
458
+ data = {
459
+ 'image' => 'foo/bar:latest',
460
+ 'pid' => 'host'
461
+ }
462
+ result = subject.send(:parse_data, data)
463
+ expect(result[:pid]).to eq('host')
464
+ end
465
+
466
+ it 'does not return pid if not set' do
467
+ data = {
468
+ 'image' => 'foo/bar:latest'
469
+ }
470
+ result = subject.send(:parse_data, data)
471
+ expect(result[:pid]).to be_nil
472
+ end
473
+ end
474
+
475
+ context 'log_driver' do
476
+ it 'returns log_driver if set' do
477
+ data = {
478
+ 'image' => 'foo/bar:latest',
479
+ 'log_driver' => 'syslog'
480
+ }
481
+ result = subject.send(:parse_data, data)
482
+ expect(result[:log_driver]).to eq('syslog')
483
+ end
484
+
485
+ it 'does not return log_driver if not set' do
486
+ data = {
487
+ 'image' => 'foo/bar:latest'
488
+ }
489
+ result = subject.send(:parse_data, data)
490
+ expect(result[:log_driver]).to be_nil
491
+ end
492
+ end
493
+
494
+ context 'log_opt' do
495
+ it 'returns log_opts hash if log_opt is set' do
496
+ data = {
497
+ 'image' => 'foo/bar:latest',
498
+ 'log_driver' => 'fluentd',
499
+ 'log_opt' => {
500
+ 'fluentd-address' => '192.168.99.1:24224',
501
+ 'fluentd-tag' => 'docker.{{.Name}}'
502
+ }
503
+ }
504
+ result = subject.send(:parse_data, data)
505
+ expect(result[:log_opts]).to eq(data['log_opt'])
506
+ end
507
+
508
+ it 'does not return log_opts if log_opt is not set' do
509
+ data = {
510
+ 'image' => 'foo/bar:latest'
511
+ }
512
+ result = subject.send(:parse_data, data)
513
+ expect(result[:log_opts]).to be_nil
514
+ end
515
+ end
516
+
517
+ context 'deploy_opts' do
518
+ it 'returns deploy_opts if deploy.wait_for_port is defined' do
519
+ data = {
520
+ 'image' => 'foo/bar:latest',
521
+ 'deploy' => {
522
+ 'wait_for_port' => '8080'
523
+ }
524
+ }
525
+ result = subject.send(:parse_data, data)
526
+ expect(result[:deploy_opts][:wait_for_port]).to eq('8080')
527
+ end
528
+
529
+ it 'returns deploy_opts if deploy.min_health is defined' do
530
+ data = {
531
+ 'image' => 'foo/bar:latest',
532
+ 'deploy' => {
533
+ 'min_health' => '0.5'
534
+ }
535
+ }
536
+ result = subject.send(:parse_data, data)
537
+ expect(result[:deploy_opts][:min_health]).to eq('0.5')
538
+ end
539
+
540
+ it 'sets strategy if deploy.strategy is defined' do
541
+ data = {
542
+ 'image' => 'foo/bar:latest',
543
+ 'deploy' => {
544
+ 'strategy' => 'daemon'
545
+ }
546
+ }
547
+ result = subject.send(:parse_data, data)
548
+ expect(result[:strategy]).to eq('daemon')
549
+ end
550
+
551
+ it 'does not return deploy_opts if no deploy options are defined' do
552
+ data = {
553
+ 'image' => 'foo/bar:latest'
554
+ }
555
+ result = subject.send(:parse_data, data)
556
+ expect(result[:deploy_opts]).to be_nil
557
+ end
558
+ end
559
+
560
+ context 'hooks' do
561
+ it 'returns hooks hash if defined' do
562
+ data = {
563
+ 'image' => 'foo/bar:latest',
564
+ 'hooks' => {
565
+ 'post_start' => []
566
+ }
567
+ }
568
+ result = subject.send(:parse_data, data)
569
+ expect(result[:hooks]).to eq(data['hooks'])
570
+ end
571
+
572
+ it 'does returns empty hook hash if not defined' do
573
+ data = { 'image' => 'foo/bar:latest' }
574
+ result = subject.send(:parse_data, data)
575
+ expect(result[:hooks]).to eq({})
576
+ end
577
+ end
578
+
579
+ context 'secrets' do
580
+ it 'returns secrets array if defined' do
581
+ data = {
582
+ 'image' => 'foo/bar:latest',
583
+ 'secrets' => [
584
+ { 'secret' => 'MYSQL_ADMIN_PASSWORD', 'name' => 'WORDPRESS_DB_PASSWORD', 'type' => 'env' }
585
+ ]
586
+ }
587
+ result = subject.send(:parse_data, data)
588
+ expect(result[:secrets]).to eq(data['secrets'])
589
+ end
590
+
591
+ it 'does not return secrets if not defined' do
592
+ data = { 'image' => 'foo/bar:latest' }
593
+ result = subject.send(:parse_data, data)
594
+ expect(result[:secrets]).to be_nil
595
+ end
596
+ end
597
+ end
598
+ end