kontena-cli 0.8.4 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/bin/kontena +4 -0
  4. data/lib/kontena/cli/app_command.rb +2 -0
  5. data/lib/kontena/cli/apps/build_command.rb +26 -0
  6. data/lib/kontena/cli/apps/common.rb +41 -12
  7. data/lib/kontena/cli/apps/deploy_command.rb +31 -13
  8. data/lib/kontena/cli/apps/docker_helper.rb +34 -0
  9. data/lib/kontena/cli/apps/init_command.rb +130 -10
  10. data/lib/kontena/cli/apps/list_command.rb +4 -2
  11. data/lib/kontena/cli/apps/logs_command.rb +4 -2
  12. data/lib/kontena/cli/apps/remove_command.rb +4 -2
  13. data/lib/kontena/cli/apps/start_command.rb +4 -2
  14. data/lib/kontena/cli/apps/stop_command.rb +4 -2
  15. data/lib/kontena/cli/common.rb +3 -3
  16. data/lib/kontena/cli/container_command.rb +3 -0
  17. data/lib/kontena/cli/containers/inspect_command.rb +16 -0
  18. data/lib/kontena/cli/deploy_command.rb +3 -0
  19. data/lib/kontena/cli/etcd/get_command.rb +21 -0
  20. data/lib/kontena/cli/etcd/list_command.rb +26 -0
  21. data/lib/kontena/cli/etcd/mkdir_command.rb +17 -0
  22. data/lib/kontena/cli/etcd/remove_command.rb +21 -0
  23. data/lib/kontena/cli/etcd/set_command.rb +18 -0
  24. data/lib/kontena/cli/etcd_command.rb +17 -0
  25. data/lib/kontena/cli/grid_command.rb +2 -0
  26. data/lib/kontena/cli/grids/logs_command.rb +71 -0
  27. data/lib/kontena/cli/master/aws/create_command.rb +33 -0
  28. data/lib/kontena/cli/master/aws_command.rb +8 -0
  29. data/lib/kontena/cli/master/azure/create_command.rb +33 -0
  30. data/lib/kontena/cli/master/azure_command.rb +13 -0
  31. data/lib/kontena/cli/master/digital_ocean/create_command.rb +30 -0
  32. data/lib/kontena/cli/master/digital_ocean_command.rb +13 -0
  33. data/lib/kontena/cli/master/vagrant/create_command.rb +19 -0
  34. data/lib/kontena/cli/master/vagrant/restart_command.rb +20 -0
  35. data/lib/kontena/cli/master/vagrant/ssh_command.rb +15 -0
  36. data/lib/kontena/cli/master/vagrant/start_command.rb +20 -0
  37. data/lib/kontena/cli/master/vagrant/stop_command.rb +20 -0
  38. data/lib/kontena/cli/master/vagrant/terminate_command.rb +13 -0
  39. data/lib/kontena/cli/master/vagrant_command.rb +23 -0
  40. data/lib/kontena/cli/master_command.rb +15 -0
  41. data/lib/kontena/cli/node_command.rb +4 -0
  42. data/lib/kontena/cli/nodes/aws/create_command.rb +39 -0
  43. data/lib/kontena/cli/nodes/aws/restart_command.rb +28 -0
  44. data/lib/kontena/cli/nodes/aws/terminate_command.rb +20 -0
  45. data/lib/kontena/cli/nodes/aws_command.rb +15 -0
  46. data/lib/kontena/cli/nodes/azure/create_command.rb +39 -0
  47. data/lib/kontena/cli/nodes/azure/restart_command.rb +31 -0
  48. data/lib/kontena/cli/nodes/azure/terminate_command.rb +20 -0
  49. data/lib/kontena/cli/nodes/azure_command.rb +15 -0
  50. data/lib/kontena/cli/nodes/digital_ocean/create_command.rb +1 -1
  51. data/lib/kontena/cli/nodes/vagrant/create_command.rb +1 -1
  52. data/lib/kontena/cli/service_command.rb +4 -0
  53. data/lib/kontena/cli/services/add_env_command.rb +18 -0
  54. data/lib/kontena/cli/services/create_command.rb +8 -0
  55. data/lib/kontena/cli/services/remove_env_command.rb +17 -0
  56. data/lib/kontena/cli/services/services_helper.rb +20 -1
  57. data/lib/kontena/cli/services/update_command.rb +10 -0
  58. data/lib/kontena/client.rb +22 -1
  59. data/lib/kontena/machine/aws.rb +13 -0
  60. data/lib/kontena/machine/aws/cloudinit.yml +66 -0
  61. data/lib/kontena/machine/aws/cloudinit_master.yml +105 -0
  62. data/lib/kontena/machine/aws/master_provisioner.rb +161 -0
  63. data/lib/kontena/machine/aws/node_destroyer.rb +39 -0
  64. data/lib/kontena/machine/aws/node_provisioner.rb +168 -0
  65. data/lib/kontena/machine/azure.rb +13 -0
  66. data/lib/kontena/machine/azure/cloudinit.yml +59 -0
  67. data/lib/kontena/machine/azure/cloudinit_master.yml +105 -0
  68. data/lib/kontena/machine/azure/logger.rb +27 -0
  69. data/lib/kontena/machine/azure/master_provisioner.rb +126 -0
  70. data/lib/kontena/machine/azure/node_destroyer.rb +53 -0
  71. data/lib/kontena/machine/azure/node_provisioner.rb +128 -0
  72. data/lib/kontena/machine/digital_ocean.rb +1 -0
  73. data/lib/kontena/machine/digital_ocean/cloudinit.yml +1 -0
  74. data/lib/kontena/machine/digital_ocean/cloudinit_master.yml +105 -0
  75. data/lib/kontena/machine/digital_ocean/master_provisioner.rb +94 -0
  76. data/lib/kontena/machine/digital_ocean/node_provisioner.rb +8 -1
  77. data/lib/kontena/machine/vagrant.rb +2 -0
  78. data/lib/kontena/machine/vagrant/Vagrantfile.master.rb.erb +101 -0
  79. data/lib/kontena/machine/vagrant/{Vagrantfile.coreos.rb.erb → Vagrantfile.node.rb.erb} +0 -0
  80. data/lib/kontena/machine/vagrant/cloudinit.yml +2 -1
  81. data/lib/kontena/machine/vagrant/master_destroyer.rb +37 -0
  82. data/lib/kontena/machine/vagrant/master_provisioner.rb +75 -0
  83. data/lib/kontena/machine/vagrant/node_destroyer.rb +4 -0
  84. data/lib/kontena/machine/vagrant/node_provisioner.rb +1 -1
  85. data/lib/kontena/scripts/completer +29 -3
  86. data/spec/kontena/cli/app/common_spec.rb +61 -0
  87. data/spec/kontena/cli/app/deploy_command_spec.rb +25 -6
  88. data/spec/kontena/cli/app/docker_helper_spec.rb +32 -0
  89. data/spec/kontena/cli/common_spec.rb +53 -0
  90. metadata +61 -3
@@ -0,0 +1,15 @@
1
+ require_relative 'azure/create_command'
2
+ require_relative 'azure/restart_command'
3
+ require_relative 'azure/terminate_command'
4
+
5
+ module Kontena::Cli::Nodes
6
+ class AzureCommand < Clamp::Command
7
+
8
+ subcommand "create", "Create a new Azure node", Azure::CreateCommand
9
+ subcommand "restart", "Restart Azure node", Azure::RestartCommand
10
+ subcommand "terminate", "Terminate Azure node", Azure::TerminateCommand
11
+
12
+ def execute
13
+ end
14
+ end
15
+ end
@@ -2,7 +2,7 @@ module Kontena::Cli::Nodes::DigitalOcean
2
2
  class CreateCommand < Clamp::Command
3
3
  include Kontena::Cli::Common
4
4
 
5
- option "--name", "NAME", "Node name"
5
+ parameter "[NAME]", "Node name"
6
6
  option "--token", "TOKEN", "DigitalOcean API token", required: true
7
7
  option "--ssh-key", "SSH_KEY", "Path to ssh public key", required: true
8
8
  option "--size", "SIZE", "Droplet size", default: '1gb'
@@ -2,7 +2,7 @@ module Kontena::Cli::Nodes::Vagrant
2
2
  class CreateCommand < Clamp::Command
3
3
  include Kontena::Cli::Common
4
4
 
5
- option "--name", "NAME", "Node name"
5
+ parameter "[NAME]", "Node name"
6
6
  option "--memory", "MEMORY", "How much memory node has", default: '1024'
7
7
  option "--version", "VERSION", "Define installed Kontena version", default: 'latest'
8
8
 
@@ -11,6 +11,8 @@ require_relative 'services/delete_command'
11
11
  require_relative 'services/containers_command'
12
12
  require_relative 'services/logs_command'
13
13
  require_relative 'services/stats_command'
14
+ require_relative 'services/add_env_command'
15
+ require_relative 'services/remove_env_command'
14
16
 
15
17
  class Kontena::Cli::ServiceCommand < Clamp::Command
16
18
 
@@ -27,6 +29,8 @@ class Kontena::Cli::ServiceCommand < Clamp::Command
27
29
  subcommand "containers", "List service containers", Kontena::Cli::Services::ContainersCommand
28
30
  subcommand "logs", "Show service logs", Kontena::Cli::Services::LogsCommand
29
31
  subcommand "stats", "Show service statistics", Kontena::Cli::Services::StatsCommand
32
+ subcommand "add-env", "Add environment variable", Kontena::Cli::Services::AddEnvCommand
33
+ subcommand "remove-env", "Remove environment variable", Kontena::Cli::Services::RemoveEnvCommand
30
34
 
31
35
  def execute
32
36
  end
@@ -0,0 +1,18 @@
1
+ require_relative 'services_helper'
2
+
3
+ module Kontena::Cli::Services
4
+ class AddEnvCommand < Clamp::Command
5
+ include Kontena::Cli::Common
6
+ include ServicesHelper
7
+
8
+ parameter "NAME", "Service name"
9
+ parameter "ENV", "Environment variable"
10
+
11
+ def execute
12
+ require_api_url
13
+ token = require_token
14
+ data = {env: env}
15
+ result = client(token).post("services/#{parse_service_id(name)}/envs", data)
16
+ end
17
+ end
18
+ end
@@ -21,8 +21,12 @@ module Kontena::Cli::Services
21
21
  option "--instances", "INSTANCES", "How many instances should be deployed"
22
22
  option ["-u", "--user"], "USER", "Username who executes first process inside container"
23
23
  option "--stateful", :flag, "Set service as stateful", default: false
24
+ option "--privileged", :flag, "Give extended privileges to this service", default: false
24
25
  option "--cap-add", "CAP_ADD", "Add capabitilies", multivalued: true
25
26
  option "--cap-drop", "CAP_DROP", "Drop capabitilies", multivalued: true
27
+ option "--net", "NET", "Network mode"
28
+ option "--log-driver", "LOG_DRIVER", "Set logging driver"
29
+ option "--log-opt", "LOG_OPT", "Add logging options", multivalued: true
26
30
 
27
31
  def execute
28
32
  require_api_url
@@ -54,8 +58,12 @@ module Kontena::Cli::Services
54
58
  data[:cmd] = cmd.split(" ") if cmd
55
59
  data[:user] = user if user
56
60
  data[:image] = parse_image(image) if image
61
+ data[:privileged] = privileged?
57
62
  data[:cap_add] = cap_add_list unless cap_add_list.empty?
58
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)
59
67
  data
60
68
  end
61
69
  end
@@ -0,0 +1,17 @@
1
+ require_relative 'services_helper'
2
+
3
+ module Kontena::Cli::Services
4
+ class RemoveEnvCommand < Clamp::Command
5
+ include Kontena::Cli::Common
6
+ include ServicesHelper
7
+
8
+ parameter "NAME", "Service name"
9
+ parameter "ENV", "Environment variable name"
10
+
11
+ def execute
12
+ require_api_url
13
+ token = require_token
14
+ client(token).delete("services/#{parse_service_id(name)}/envs/#{env}")
15
+ end
16
+ end
17
+ end
@@ -85,6 +85,13 @@ module Kontena
85
85
  puts " - #{c}"
86
86
  end
87
87
 
88
+ puts " log_driver: #{service['log_driver']}"
89
+
90
+ puts " log_opts:"
91
+ service['log_opts'].each do |opt, value|
92
+ puts " #{opt}: #{value}"
93
+ end
94
+
88
95
  puts " containers:"
89
96
  result = client(token).get("services/#{parse_service_id(service_id)}/containers")
90
97
  result['containers'].each do |container|
@@ -113,7 +120,7 @@ module Kontena
113
120
  print '.'
114
121
  sleep 1
115
122
  end
116
- puts ' done'
123
+ puts ' done'.colorize(:green)
117
124
  puts ''
118
125
  end
119
126
 
@@ -202,6 +209,18 @@ module Kontena
202
209
  end
203
210
  image
204
211
  end
212
+
213
+ ##
214
+ # @param [Array] log_opts
215
+ # @return [Hash]
216
+ def parse_log_opts(log_opts)
217
+ opts = {}
218
+ log_opts.each do |opt|
219
+ key, value = opt.split('=')
220
+ opts[key] = value
221
+ end
222
+ opts
223
+ end
205
224
  end
206
225
  end
207
226
  end
@@ -10,6 +10,7 @@ module Kontena::Cli::Services
10
10
  option "--image", "IMAGE", "Docker image to use"
11
11
  option ["-p", "--ports"], "PORTS", "Publish a service's port to the host", multivalued: true
12
12
  option ["-e", "--env"], "ENV", "Set environment variables", multivalued: true
13
+ option ["-l", "--link"], "LINK", "Add link to another service in the form of name:alias", multivalued: true
13
14
  option ["-a", "--affinity"], "AFFINITY", "Set service affinity", multivalued: true
14
15
  option ["-c", "--cpu-shares"], "CPU_SHARES", "CPU shares (relative weight)"
15
16
  option ["-m", "--memory"], "MEMORY", "Memory limit (format: <number><optional unit>, where unit = b, k, m or g)"
@@ -17,8 +18,12 @@ module Kontena::Cli::Services
17
18
  option "--cmd", "CMD", "Command to execute"
18
19
  option "--instances", "INSTANCES", "How many instances should be deployed"
19
20
  option ["-u", "--user"], "USER", "Username who executes first process inside container"
21
+ option "--privileged", :flag, "Give extended privileges to this service", default: false
20
22
  option "--cap-add", "CAP_ADD", "Add capabitilies", multivalued: true
21
23
  option "--cap-drop", "CAP_DROP", "Drop capabitilies", multivalued: true
24
+ option "--net", "NET", "Network mode"
25
+ option "--log-driver", "LOG_DRIVER", "Set logging driver"
26
+ option "--log-opt", "LOG_OPT", "Add logging options", multivalued: true
22
27
 
23
28
  def execute
24
29
  require_api_url
@@ -34,6 +39,7 @@ module Kontena::Cli::Services
34
39
  def parse_service_data_from_options
35
40
  data = {}
36
41
  data[:ports] = parse_ports(ports_list) unless ports_list.empty?
42
+ data[:links] = parse_links(link_list) unless link_list.empty?
37
43
  data[:memory] = parse_memory(memory) if memory
38
44
  data[:memory_swap] = parse_memory(memory_swap) if memory_swap
39
45
  data[:cpu_shares] = cpu_shares if cpu_shares
@@ -43,8 +49,12 @@ module Kontena::Cli::Services
43
49
  data[:cmd] = cmd.split(" ") if cmd
44
50
  data[:user] = user if user
45
51
  data[:image] = parse_image(image) if image
52
+ data[:privileged] = privileged?
46
53
  data[:cap_add] = cap_add_list unless cap_add_list.empty?
47
54
  data[:cap_drop] = cap_drop_list unless cap_drop_list.empty?
55
+ data[:net] = net if net
56
+ data[:log_driver] = log_driver if log_driver
57
+ data[:log_opts] = parse_log_opts(log_opt_list)
48
58
  data
49
59
  end
50
60
  end
@@ -24,9 +24,14 @@ module Kontena
24
24
  #
25
25
  # @param [String] path
26
26
  # @param [Hash,NilClass] params
27
+ # @param [Hash] headers
27
28
  # @return [Hash]
28
29
  def get(path, params = nil, headers = {})
29
- response = http_client.get(path: request_uri(path), query: params, headers: request_headers(headers))
30
+ response = http_client.get(
31
+ path: request_uri(path),
32
+ query: params,
33
+ headers: request_headers(headers)
34
+ )
30
35
  if response.status == 200
31
36
  parse_response(response)
32
37
  else
@@ -34,6 +39,22 @@ module Kontena
34
39
  end
35
40
  end
36
41
 
42
+ # Get request
43
+ #
44
+ # @param [String] path
45
+ # @param [Lambda] response_block
46
+ # @param [Hash,NilClass] params
47
+ # @param [Hash] headers
48
+ def get_stream(path, response_block, params = nil, headers = {})
49
+ http_client.get(
50
+ read_timeout: 360,
51
+ path: request_uri(path),
52
+ query: params,
53
+ headers: request_headers(headers),
54
+ response_block: response_block
55
+ )
56
+ end
57
+
37
58
  # Post request
38
59
  #
39
60
  # @param [String] path
@@ -0,0 +1,13 @@
1
+ begin
2
+ require "fog/aws"
3
+ rescue LoadError
4
+ puts "It seems that you don't have gem for AWS API installed."
5
+ puts "Install it using: gem install fog-aws"
6
+ exit 1
7
+ end
8
+
9
+ require_relative 'random_name'
10
+ require_relative 'aws/master_provisioner'
11
+ require_relative 'aws/node_provisioner'
12
+ require_relative 'aws/node_destroyer'
13
+
@@ -0,0 +1,66 @@
1
+ #cloud-config
2
+ hostname: <%= name %>
3
+ write_files:
4
+ - path: /etc/kontena-agent.env
5
+ permissions: 0600
6
+ owner: root
7
+ content: |
8
+ KONTENA_URI="<%= master_uri %>"
9
+ KONTENA_TOKEN="<%= grid_token %>"
10
+ KONTENA_PEER_INTERFACE=eth1
11
+ KONTENA_VERSION=<%= version %>
12
+ - path: /etc/systemd/system/docker.service.d/50-kontena.conf
13
+ content: |
14
+ [Service]
15
+ Environment='DOCKER_OPTS=--insecure-registry="10.81.0.0/19" --bip="172.17.42.1/16"'
16
+ coreos:
17
+ units:
18
+ - name: 00-eth.network
19
+ runtime: true
20
+ content: |
21
+ [Match]
22
+ Name=eth*
23
+ [Network]
24
+ DHCP=yes
25
+ DNS=172.17.42.1
26
+ DNS=<%= dns_server %>
27
+ DOMAINS=kontena.local
28
+ [DHCP]
29
+ UseDNS=false
30
+
31
+ - name: 10-weave.network
32
+ runtime: false
33
+ content: |
34
+ [Match]
35
+ Type=bridge
36
+ Name=weave*
37
+
38
+ [Network]
39
+ - name: kontena-agent.service
40
+ command: start
41
+ enable: true
42
+ content: |
43
+ [Unit]
44
+ Description=kontena-agent
45
+ After=network-online.target
46
+ After=docker.service
47
+ Description=Kontena Agent
48
+ Documentation=http://www.kontena.io/
49
+ Requires=network-online.target
50
+ Requires=docker.service
51
+
52
+ [Service]
53
+ Restart=always
54
+ RestartSec=5
55
+ EnvironmentFile=/etc/kontena-agent.env
56
+ ExecStartPre=-/usr/bin/docker stop kontena-agent
57
+ ExecStartPre=-/usr/bin/docker rm kontena-agent
58
+ ExecStartPre=/usr/bin/docker pull kontena/agent:${KONTENA_VERSION}
59
+ ExecStart=/usr/bin/docker run --name kontena-agent \
60
+ -e KONTENA_URI=${KONTENA_URI} \
61
+ -e KONTENA_TOKEN=${KONTENA_TOKEN} \
62
+ -e KONTENA_PEER_INTERFACE=${KONTENA_PEER_INTERFACE} \
63
+ -v=/var/run/docker.sock:/var/run/docker.sock \
64
+ -v=/etc/kontena-agent.env:/etc/kontena.env \
65
+ --net=host \
66
+ kontena/agent:${KONTENA_VERSION}
@@ -0,0 +1,105 @@
1
+ #cloud-config
2
+ write_files:
3
+ - path: /etc/kontena-server.env
4
+ permissions: 0600
5
+ owner: root
6
+ content: |
7
+ KONTENA_VERSION=<%= version %>
8
+ <% if ssl_cert %>SSL_CERT="/etc/kontena-server.pem"
9
+
10
+ - path: /etc/kontena-server.pem
11
+ permissions: 0600
12
+ owner: root
13
+ content: | <% ssl_cert.split(/\n/).each do |row| %>
14
+ <%= row %><% end %><% end %>
15
+ - path: /opt/bin/kontena-haproxy.sh
16
+ permissions: 0755
17
+ owner: root
18
+ content: |
19
+ #!/bin/sh
20
+ if [ -n "$SSL_CERT" ]; then
21
+ SSL_CERT=$(awk 1 ORS='\\n' $SSL_CERT)
22
+ else
23
+ SSL_CERT="**None**"
24
+ fi
25
+ /usr/bin/docker run --name=kontena-server-haproxy \
26
+ --link kontena-server-api:kontena-server-api \
27
+ -e SSL_CERT="$SSL_CERT" -e BACKEND_PORT=9292 \
28
+ -p 80:80 -p 443:443 kontena/haproxy:latest
29
+ coreos:
30
+ update:
31
+ reboot-strategy: off
32
+ units:
33
+ - name: kontena-server-mongo.service
34
+ command: start
35
+ enable: true
36
+ content: |
37
+ [Unit]
38
+ Description=kontena-server-mongo
39
+ After=network-online.target
40
+ After=docker.service
41
+ Description=Kontena Server MongoDB
42
+ Documentation=http://www.mongodb.org/
43
+ Requires=network-online.target
44
+ Requires=docker.service
45
+
46
+ [Service]
47
+ Restart=always
48
+ RestartSec=5
49
+ ExecStartPre=/usr/bin/docker pull mongo:3.0
50
+ ExecStartPre=-/usr/bin/docker create --name=kontena-server-mongo-data mongo:3.0
51
+ ExecStartPre=-/usr/bin/docker stop kontena-server-mongo
52
+ ExecStartPre=-/usr/bin/docker rm kontena-server-mongo
53
+ ExecStart=/usr/bin/docker run --name=kontena-server-mongo \
54
+ --volumes-from=kontena-server-mongo-data \
55
+ mongo:3.0 mongod --smallfiles
56
+
57
+ - name: kontena-server-api.service
58
+ command: start
59
+ enable: true
60
+ content: |
61
+ [Unit]
62
+ Description=kontena-server-api
63
+ After=network-online.target
64
+ After=docker.service
65
+ After=kontena-server-mongo.service
66
+ Description=Kontena Master
67
+ Documentation=http://www.kontena.io/
68
+ Requires=network-online.target
69
+ Requires=docker.service
70
+ Requires=kontena-server-mongo.service
71
+
72
+ [Service]
73
+ Restart=always
74
+ RestartSec=5
75
+ EnvironmentFile=/etc/kontena-server.env
76
+ ExecStartPre=-/usr/bin/docker stop kontena-server-api
77
+ ExecStartPre=-/usr/bin/docker rm kontena-server-api
78
+ ExecStartPre=/usr/bin/docker pull kontena/server:${KONTENA_VERSION}
79
+ ExecStart=/usr/bin/docker run --name kontena-server-api \
80
+ --link kontena-server-mongo:mongodb \
81
+ -e MONGODB_URI=mongodb://mongodb:27017/kontena_server \
82
+ <% if auth_server %>-e AUTH_API_URL=<%= auth_server %><% end %> \
83
+ kontena/server:${KONTENA_VERSION}
84
+
85
+ - name: kontena-server-haproxy.service
86
+ command: start
87
+ enable: true
88
+ content: |
89
+ [Unit]
90
+ Description=kontena-server-haproxy
91
+ After=network-online.target
92
+ After=docker.service
93
+ Description=Kontena Server HAProxy
94
+ Documentation=http://www.kontena.io/
95
+ Requires=network-online.target
96
+ Requires=docker.service
97
+
98
+ [Service]
99
+ Restart=always
100
+ RestartSec=5
101
+ EnvironmentFile=/etc/kontena-server.env
102
+ ExecStartPre=-/usr/bin/docker stop kontena-server-haproxy
103
+ ExecStartPre=-/usr/bin/docker rm kontena-server-haproxy
104
+ ExecStartPre=/usr/bin/docker pull kontena/haproxy:latest
105
+ ExecStart=/opt/bin/kontena-haproxy.sh
@@ -0,0 +1,161 @@
1
+ require 'fileutils'
2
+ require 'erb'
3
+ require 'open3'
4
+ require 'shell-spinner'
5
+
6
+ module Kontena
7
+ module Machine
8
+ module Aws
9
+ class MasterProvisioner
10
+ include RandomName
11
+ attr_reader :client, :http_client, :region
12
+
13
+ # @param [String] access_key_id aws_access_key_id
14
+ # @param [String] secret_key aws_secret_access_key
15
+ # @param [String] region
16
+ def initialize(access_key_id, secret_key, region)
17
+ @client = Fog::Compute.new(:provider => 'AWS', :aws_access_key_id => access_key_id, :aws_secret_access_key => secret_key, :region => region)
18
+
19
+ end
20
+
21
+ # @param [Hash] opts
22
+ def run!(opts)
23
+ if opts[:ssl_cert]
24
+ abort('Invalid ssl cert') unless File.exists?(File.expand_path(opts[:ssl_cert]))
25
+ ssl_cert = File.read(File.expand_path(opts[:ssl_cert]))
26
+ end
27
+
28
+ ami = resolve_ami(client.region)
29
+ abort('No valid AMI found for region') unless ami
30
+ opts[:vpc] = default_vpc.id unless opts[:vpc]
31
+ if opts[:subnet].nil?
32
+ subnet = default_subnet(opts[:vpc], client.region+opts[:zone])
33
+ opts[:subnet] = subnet.subnet_id
34
+ else
35
+ subnet = client.subnets.get(opts[:subnet])
36
+ end
37
+ userdata_vars = {
38
+ ssl_cert: ssl_cert,
39
+ auth_server: opts[:auth_server],
40
+ version: opts[:version]
41
+ }
42
+
43
+ security_group = ensure_security_group(opts[:vpc])
44
+ name = generate_name
45
+ response = client.run_instances(
46
+ ami,
47
+ 1,
48
+ 1,
49
+ 'InstanceType' => opts[:type],
50
+ 'SecurityGroupId' => security_group.group_id,
51
+ 'KeyName' => opts[:key_pair],
52
+ 'SubnetId' => opts[:subnet],
53
+ 'UserData' => user_data(userdata_vars),
54
+ 'BlockDeviceMapping' => [
55
+ {
56
+ 'DeviceName' => '/dev/xvda',
57
+ 'VirtualName' => 'Root',
58
+ 'Ebs.VolumeSize' => opts[:storage],
59
+ 'Ebs.VolumeType' => 'gp2'
60
+ }
61
+ ]
62
+
63
+ )
64
+ instance_id = response.body['instancesSet'].first['instanceId']
65
+
66
+ instance = client.servers.get(instance_id)
67
+ ShellSpinner "Creating AWS instance #{name.colorize(:cyan)} " do
68
+ instance.wait_for { ready? }
69
+ end
70
+ if opts[:ssl_cert]
71
+ master_url = "https://#{instance.public_ip_address}"
72
+ else
73
+ master_url = "http://#{instance.public_ip_address}"
74
+ end
75
+ Excon.defaults[:ssl_verify_peer] = false
76
+ @http_client = Excon.new("#{master_url}", :connect_timeout => 10)
77
+
78
+ ShellSpinner "Waiting for #{name.colorize(:cyan)} to start" do
79
+ sleep 5 until master_running?
80
+ end
81
+
82
+ puts "Kontena Master is now running at #{master_url}"
83
+ puts "Use #{"kontena login #{master_url}".colorize(:light_black)} to complete Kontena Master setup"
84
+ end
85
+
86
+ ##
87
+ # @param [String] grid
88
+ # @return Fog::Compute::AWS::SecurityGroup
89
+ def ensure_security_group(vpc_id)
90
+ group_name = "kontena_master"
91
+ if vpc_id
92
+ client.security_groups.all({'group-name' => group_name, 'vpc-id' => vpc_id}).first || create_security_group(group_name, vpc_id)
93
+ else
94
+ client.security_groups.get(group_name) || create_security_group(group_name)
95
+ end
96
+ end
97
+
98
+ ##
99
+ # creates security_group and authorizes default port ranges
100
+ #
101
+ # @param [String] name
102
+ # @return Fog::Compute::AWS::SecurityGroup
103
+ def create_security_group(name, vpc_id = nil)
104
+ security_group = client.security_groups.new(:name => name, :description => "Kontena Master", :vpc_id => vpc_id)
105
+ security_group.save
106
+
107
+ security_group.authorize_port_range(80..80)
108
+ security_group.authorize_port_range(443..443)
109
+ security_group.authorize_port_range(22..22)
110
+ security_group
111
+ end
112
+
113
+ # @param [String] region
114
+ # @return String
115
+ def resolve_ami(region)
116
+ images = {
117
+ 'eu-central-1' => 'ami-74bbba69',
118
+ 'ap-northeast-1' => 'ami-1e77ff1e',
119
+ 'us-gov-west-1' => 'ami-f1d1b2d2',
120
+ 'sa-east-1' => 'ami-632ba17e',
121
+ 'ap-southeast-2' => 'ami-83f8b4b9',
122
+ 'ap-southeast-1' => 'ami-12060c40',
123
+ 'us-east-1' => 'ami-f396fa96',
124
+ 'us-west-2' => 'ami-99bfada9',
125
+ 'us-west-1' => 'ami-dbe71d9f',
126
+ 'eu-west-1' => 'ami-83e9c8f4'
127
+ }
128
+ images[region]
129
+ end
130
+
131
+
132
+ def default_subnet(vpc, zone)
133
+ client.subnets.all('vpc-id' => vpc, 'availabilityZone' => zone).first
134
+ end
135
+
136
+ def default_vpc
137
+ client.vpcs.all('isDefault' => true).first
138
+ end
139
+
140
+ def user_data(vars)
141
+ cloudinit_template = File.join(__dir__ , '/cloudinit_master.yml')
142
+ erb(File.read(cloudinit_template), vars)
143
+ end
144
+
145
+ def generate_name
146
+ "kontena-master-#{super}-#{rand(1..99)}"
147
+ end
148
+
149
+ def master_running?
150
+ http_client.get(path: '/').status == 200
151
+ rescue
152
+ false
153
+ end
154
+
155
+ def erb(template, vars)
156
+ ERB.new(template).result(OpenStruct.new(vars).instance_eval { binding })
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end