kontena-cli 0.13.4 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/kontena-cli.gemspec +2 -0
- data/lib/kontena/cli/app_command.rb +2 -0
- data/lib/kontena/cli/apps/common.rb +80 -74
- data/lib/kontena/cli/apps/config_command.rb +29 -0
- data/lib/kontena/cli/apps/deploy_command.rb +12 -81
- data/lib/kontena/cli/apps/docker_helper.rb +3 -3
- data/lib/kontena/cli/apps/init_command.rb +0 -3
- data/lib/kontena/cli/apps/list_command.rb +2 -3
- data/lib/kontena/cli/apps/logs_command.rb +2 -3
- data/lib/kontena/cli/apps/monitor_command.rb +3 -4
- data/lib/kontena/cli/apps/remove_command.rb +4 -4
- data/lib/kontena/cli/apps/restart_command.rb +2 -3
- data/lib/kontena/cli/apps/scale_command.rb +3 -5
- data/lib/kontena/cli/apps/service_generator.rb +123 -0
- data/lib/kontena/cli/apps/service_generator_v2.rb +26 -0
- data/lib/kontena/cli/apps/show_command.rb +1 -2
- data/lib/kontena/cli/apps/start_command.rb +2 -3
- data/lib/kontena/cli/apps/stop_command.rb +2 -3
- data/lib/kontena/cli/apps/yaml/reader.rb +150 -0
- data/lib/kontena/cli/apps/yaml/service_extender.rb +60 -0
- data/lib/kontena/cli/apps/yaml/validations.rb +79 -0
- data/lib/kontena/cli/apps/yaml/validator.rb +55 -0
- data/lib/kontena/cli/apps/yaml/validator_v2.rb +74 -0
- data/lib/kontena/cli/common.rb +23 -0
- data/lib/kontena/cli/etcd/remove_command.rb +2 -0
- data/lib/kontena/cli/grids/remove_command.rb +2 -0
- data/lib/kontena/cli/grids/users/remove_command.rb +3 -0
- data/lib/kontena/cli/master/azure/create_command.rb +0 -2
- data/lib/kontena/cli/master/packet/create_command.rb +42 -0
- data/lib/kontena/cli/master/packet_command.rb +14 -0
- data/lib/kontena/cli/master/upcloud/create_command.rb +39 -0
- data/lib/kontena/cli/master/upcloud_command.rb +13 -0
- data/lib/kontena/cli/master/users/remove_command.rb +3 -0
- data/lib/kontena/cli/master/users/roles/remove_command.rb +2 -0
- data/lib/kontena/cli/master_command.rb +4 -0
- data/lib/kontena/cli/node_command.rb +4 -0
- data/lib/kontena/cli/nodes/azure/create_command.rb +0 -2
- data/lib/kontena/cli/nodes/list_command.rb +4 -8
- data/lib/kontena/cli/nodes/packet/create_command.rb +35 -0
- data/lib/kontena/cli/nodes/packet/restart_command.rb +17 -0
- data/lib/kontena/cli/nodes/packet/terminate_command.rb +20 -0
- data/lib/kontena/cli/nodes/packet_command.rb +15 -0
- data/lib/kontena/cli/nodes/remove_command.rb +2 -0
- data/lib/kontena/cli/nodes/show_command.rb +3 -1
- data/lib/kontena/cli/nodes/upcloud/create_command.rb +33 -0
- data/lib/kontena/cli/nodes/upcloud/restart_command.rb +20 -0
- data/lib/kontena/cli/nodes/upcloud/terminate_command.rb +20 -0
- data/lib/kontena/cli/nodes/upcloud_command.rb +15 -0
- data/lib/kontena/cli/registry/remove_command.rb +3 -0
- data/lib/kontena/cli/services/remove_command.rb +2 -0
- data/lib/kontena/cli/services/services_helper.rb +1 -0
- data/lib/kontena/cli/vault/list_command.rb +2 -0
- data/lib/kontena/cli/vault/read_command.rb +2 -0
- data/lib/kontena/cli/vault/remove_command.rb +4 -0
- data/lib/kontena/cli/vault/update_command.rb +8 -1
- data/lib/kontena/cli/vault/write_command.rb +2 -0
- data/lib/kontena/cli/vpn/remove_command.rb +3 -0
- data/lib/kontena/machine/azure/master_provisioner.rb +2 -2
- data/lib/kontena/machine/azure/node_provisioner.rb +7 -4
- data/lib/kontena/machine/digital_ocean/node_provisioner.rb +1 -1
- data/lib/kontena/machine/packet.rb +17 -0
- data/lib/kontena/machine/packet/cloudinit.yml +66 -0
- data/lib/kontena/machine/packet/cloudinit_master.yml +118 -0
- data/lib/kontena/machine/packet/master_provisioner.rb +93 -0
- data/lib/kontena/machine/packet/node_destroyer.rb +42 -0
- data/lib/kontena/machine/packet/node_provisioner.rb +77 -0
- data/lib/kontena/machine/packet/node_restarter.rb +41 -0
- data/lib/kontena/machine/packet/packet_common.rb +89 -0
- data/lib/kontena/machine/upcloud.rb +9 -0
- data/lib/kontena/machine/upcloud/cloudinit.yml +64 -0
- data/lib/kontena/machine/upcloud/cloudinit_master.yml +118 -0
- data/lib/kontena/machine/upcloud/master_provisioner.rb +136 -0
- data/lib/kontena/machine/upcloud/node_destroyer.rb +82 -0
- data/lib/kontena/machine/upcloud/node_provisioner.rb +119 -0
- data/lib/kontena/machine/upcloud/node_restarter.rb +47 -0
- data/lib/kontena/machine/upcloud/upcloud_common.rb +70 -0
- data/lib/kontena/scripts/completer +8 -3
- data/spec/fixtures/docker-compose_v2.yml +10 -0
- data/spec/fixtures/kontena-invalid.yml +4 -0
- data/spec/fixtures/kontena-with-variables.yml +19 -0
- data/spec/fixtures/kontena.yml +2 -2
- data/spec/fixtures/kontena_v2.yml +35 -0
- data/spec/kontena/cli/app/common_spec.rb +39 -101
- data/spec/kontena/cli/app/deploy_command_spec.rb +37 -388
- data/spec/kontena/cli/app/docker_helper_spec.rb +4 -4
- data/spec/kontena/cli/app/service_generator_spec.rb +374 -0
- data/spec/kontena/cli/app/service_generator_v2_spec.rb +74 -0
- data/spec/kontena/cli/app/yaml/reader_spec.rb +249 -0
- data/spec/kontena/cli/app/yaml/service_extender_spec.rb +104 -0
- data/spec/kontena/cli/app/yaml/validator_spec.rb +263 -0
- data/spec/kontena/cli/app/yaml/validator_v2_spec.rb +309 -0
- data/spec/kontena/cli/common_spec.rb +39 -1
- data/spec/kontena/cli/master/users/remove_command_spec.rb +9 -0
- data/spec/kontena/cli/master/users/roles/remove_command_spec.rb +2 -0
- metadata +86 -2
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'shell-spinner'
|
2
|
+
|
3
|
+
module Kontena
|
4
|
+
module Machine
|
5
|
+
module Upcloud
|
6
|
+
class NodeDestroyer
|
7
|
+
include RandomName
|
8
|
+
include UpcloudCommon
|
9
|
+
|
10
|
+
attr_reader :api_client, :username, :password
|
11
|
+
|
12
|
+
# @param [Kontena::Client] api_client Kontena api client
|
13
|
+
# @param [String] token Upcloud token
|
14
|
+
def initialize(api_client, upcloud_username, upcloud_password)
|
15
|
+
@api_client = api_client
|
16
|
+
@username = upcloud_username
|
17
|
+
@password = upcloud_password
|
18
|
+
end
|
19
|
+
|
20
|
+
def run!(grid, name)
|
21
|
+
servers = get('server')
|
22
|
+
unless servers && servers.has_key?(:servers)
|
23
|
+
abort('Upcloud API error')
|
24
|
+
end
|
25
|
+
|
26
|
+
server = servers[:servers][:server].find{|s| s[:hostname] == name}
|
27
|
+
|
28
|
+
abort "Cannot find node #{name.colorize(:cyan)} in Upcloud" unless server
|
29
|
+
|
30
|
+
server_data = get("server/#{server[:uuid]}")
|
31
|
+
|
32
|
+
storage_devices = server_data.fetch(:server, {}).fetch(:storage_devices, {}).fetch(:storage_device, [])
|
33
|
+
storage_uuids = storage_devices.map{|s| s[:storage]}
|
34
|
+
|
35
|
+
abort('No storage devices found for Upcloud node') if storage_uuids.empty?
|
36
|
+
|
37
|
+
if server
|
38
|
+
unless server[:state].eql?('stopped')
|
39
|
+
ShellSpinner "Shutting down Upcloud node #{name.colorize(:cyan)} " do
|
40
|
+
device_data = post(
|
41
|
+
"server/#{server[:uuid]}/stop", body: {
|
42
|
+
stop_server: {
|
43
|
+
stop_type: 'soft',
|
44
|
+
timeout: 120
|
45
|
+
}
|
46
|
+
}.to_json
|
47
|
+
)
|
48
|
+
|
49
|
+
until device_data && device_data.fetch(:state, nil).to_s.eql?('stopped')
|
50
|
+
device_data = get("server/#{server[:uuid]}").fetch(:server, {}) rescue nil
|
51
|
+
sleep 5
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
ShellSpinner "Terminating Upcloud node #{name.colorize(:cyan)} " do
|
57
|
+
response = delete("server/#{server[:uuid]}")
|
58
|
+
abort "Cannot delete node #{name.colorize(:cyan)} in Upcloud" unless response[:success]
|
59
|
+
end
|
60
|
+
|
61
|
+
storage_uuids.each do |uuid|
|
62
|
+
ShellSpinner "Deleting Upcloud storage device '#{uuid.colorize(:cyan)}' " do
|
63
|
+
response = delete("storage/#{uuid}")
|
64
|
+
unless response[:success]
|
65
|
+
puts "#{"WARNING".colorize(:red)}: Couldn't delete Upcloud storage '#{uuid.colorize(:cyan)}', check manually."
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
else
|
70
|
+
abort "Cannot find node #{name.colorize(:cyan)} in Upcloud"
|
71
|
+
end
|
72
|
+
node = api_client.get("grids/#{grid['id']}/nodes")['nodes'].find{|n| n['name'] == name}
|
73
|
+
if node
|
74
|
+
ShellSpinner "Removing node #{name.colorize(:cyan)} from grid #{grid['name'].colorize(:cyan)} " do
|
75
|
+
api_client.delete("grids/#{grid['id']}/nodes/#{name}")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'erb'
|
3
|
+
require 'open3'
|
4
|
+
require 'shell-spinner'
|
5
|
+
|
6
|
+
module Kontena
|
7
|
+
module Machine
|
8
|
+
module Upcloud
|
9
|
+
class NodeProvisioner
|
10
|
+
include RandomName
|
11
|
+
include UpcloudCommon
|
12
|
+
|
13
|
+
attr_reader :api_client, :username, :password
|
14
|
+
|
15
|
+
# @param [Kontena::Client] api_client Kontena api client
|
16
|
+
# @param [String] upcloud_username Upcloud username
|
17
|
+
# @param [String] upcloud_password Upcloud password
|
18
|
+
def initialize(api_client, upcloud_username, upcloud_password)
|
19
|
+
@api_client = api_client
|
20
|
+
@username = upcloud_username
|
21
|
+
@password = upcloud_password
|
22
|
+
end
|
23
|
+
|
24
|
+
def run!(opts)
|
25
|
+
if File.readable?(File.expand_path(opts[:ssh_key]))
|
26
|
+
ssh_key = File.read(File.expand_path(opts[:ssh_key])).strip
|
27
|
+
end
|
28
|
+
|
29
|
+
abort('Invalid ssh key') unless ssh_key && ssh_key.start_with?('ssh-')
|
30
|
+
|
31
|
+
userdata_vars = {
|
32
|
+
version: opts[:version],
|
33
|
+
master_uri: opts[:master_uri],
|
34
|
+
grid_token: opts[:grid_token],
|
35
|
+
}
|
36
|
+
|
37
|
+
abort('CoreOS template not found on Upcloud') unless coreos_template = find_template('CoreOS Stable')
|
38
|
+
abort('Server plan not found on Upcloud') unless plan = find_plan(opts[:plan])
|
39
|
+
abort('Zone not found on Upcloud') unless zone_exist?(opts[:zone])
|
40
|
+
|
41
|
+
hostname = generate_name
|
42
|
+
|
43
|
+
device_data = {
|
44
|
+
server: {
|
45
|
+
zone: opts[:zone],
|
46
|
+
title: "Kontena Grid #{opts[:grid]} Node #{hostname}",
|
47
|
+
hostname: hostname,
|
48
|
+
plan: plan[:name],
|
49
|
+
vnc: 'off',
|
50
|
+
timezone: 'UTC',
|
51
|
+
user_data: user_data(userdata_vars),
|
52
|
+
firewall: 'off',
|
53
|
+
storage_devices: {
|
54
|
+
storage_device: [
|
55
|
+
{
|
56
|
+
action: 'clone',
|
57
|
+
storage: coreos_template[:uuid],
|
58
|
+
title: "From template #{coreos_template[:title]}",
|
59
|
+
size: plan[:storage_size],
|
60
|
+
tier: 'maxiops'
|
61
|
+
}
|
62
|
+
]
|
63
|
+
},
|
64
|
+
login_user: {
|
65
|
+
create_password: 'no',
|
66
|
+
username: 'root',
|
67
|
+
ssh_keys: {
|
68
|
+
ssh_key: [ssh_key]
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}.to_json
|
73
|
+
|
74
|
+
ShellSpinner "Creating Upcloud node #{hostname.colorize(:cyan)} " do
|
75
|
+
response = post('server', body: device_data)
|
76
|
+
|
77
|
+
if response.has_key?(:error)
|
78
|
+
abort("\nUpcloud server creation failed (#{response[:error].fetch(:error_message, '')})")
|
79
|
+
end
|
80
|
+
device_data = response[:server]
|
81
|
+
|
82
|
+
until device_data && device_data.fetch(:state, nil).to_s == 'maintenance'
|
83
|
+
device_data = get("server/#{device[:uuid]}").fetch(:server, {}) rescue nil
|
84
|
+
sleep 5
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
node = nil
|
89
|
+
ShellSpinner "Waiting for node #{hostname.colorize(:cyan)} join to grid #{opts[:grid].colorize(:cyan)} " do
|
90
|
+
sleep 2 until node = node_exists_in_grid?(opts[:grid], hostname)
|
91
|
+
end
|
92
|
+
set_labels(node, ["region=#{opts[:zone]}", "provider=upcloud"])
|
93
|
+
end
|
94
|
+
|
95
|
+
def user_data(vars)
|
96
|
+
cloudinit_template = File.join(__dir__ , '/cloudinit.yml')
|
97
|
+
erb(File.read(cloudinit_template), vars)
|
98
|
+
end
|
99
|
+
|
100
|
+
def generate_name
|
101
|
+
"#{super}-#{rand(1..99)}"
|
102
|
+
end
|
103
|
+
|
104
|
+
def node_exists_in_grid?(grid, hostname)
|
105
|
+
api_client.get("grids/#{grid}/nodes")['nodes'].find{|n| n['name'] == hostname}
|
106
|
+
end
|
107
|
+
|
108
|
+
def erb(template, vars)
|
109
|
+
ERB.new(template).result(OpenStruct.new(vars).instance_eval { binding })
|
110
|
+
end
|
111
|
+
|
112
|
+
def set_labels(node, labels)
|
113
|
+
data = {labels: labels}
|
114
|
+
api_client.put("nodes/#{node['id']}", data, {}, {'Kontena-Grid-Token' => node['grid']['token']})
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'shell-spinner'
|
2
|
+
|
3
|
+
module Kontena
|
4
|
+
module Machine
|
5
|
+
module Upcloud
|
6
|
+
class NodeRestarter
|
7
|
+
include RandomName
|
8
|
+
include UpcloudCommon
|
9
|
+
|
10
|
+
attr_reader :username, :password
|
11
|
+
|
12
|
+
# @param [String] upcloud_username Upcloud username
|
13
|
+
# @param [String] upcloud_password Upcloud password
|
14
|
+
def initialize(upcloud_username, upcloud_password)
|
15
|
+
@username = upcloud_username
|
16
|
+
@password = upcloud_password
|
17
|
+
end
|
18
|
+
|
19
|
+
def run!(name)
|
20
|
+
servers = get('server')
|
21
|
+
unless servers && servers.has_key?(:servers)
|
22
|
+
abort('Upcloud API error')
|
23
|
+
end
|
24
|
+
|
25
|
+
server = servers[:servers][:server].find{|s| s[:hostname] == name}
|
26
|
+
|
27
|
+
if server
|
28
|
+
ShellSpinner "Restarting Upcloud node #{name.colorize(:cyan)} " do
|
29
|
+
result = post(
|
30
|
+
"server/#{server[:uuid]}/restart", body: {
|
31
|
+
restart_server: {
|
32
|
+
stop_type: 'soft',
|
33
|
+
timeout: 600,
|
34
|
+
timeout_action: 'ignore'
|
35
|
+
}
|
36
|
+
}.to_json
|
37
|
+
)
|
38
|
+
end
|
39
|
+
else
|
40
|
+
abort "Cannot find node #{name.colorize(:cyan)} in Upcloud"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'excon'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Kontena
|
5
|
+
module Machine
|
6
|
+
module Upcloud
|
7
|
+
module UpcloudCommon
|
8
|
+
|
9
|
+
attr_reader :username
|
10
|
+
attr_reader :password
|
11
|
+
|
12
|
+
def client
|
13
|
+
@client ||= Excon.new(
|
14
|
+
'https://api.upcloud.com',
|
15
|
+
omit_default_port: true,
|
16
|
+
user: username,
|
17
|
+
password: password,
|
18
|
+
headers: { "Accept-Encoding" => 'application/json' }
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
def find_template(name)
|
23
|
+
get('storage/template')[:storages][:storage].find{|s| s[:title].downcase.start_with?(name.downcase)}
|
24
|
+
end
|
25
|
+
|
26
|
+
def find_plan(name)
|
27
|
+
get('plan')[:plans][:plan].find{|s| s[:name].downcase.eql?(name.downcase)}
|
28
|
+
end
|
29
|
+
|
30
|
+
def zone_exist?(name)
|
31
|
+
get('zone')[:zones][:zone].map{|p| p[:id]}.include?(name)
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_server(id)
|
35
|
+
get("server/#{id}").fetch(:server, nil)
|
36
|
+
end
|
37
|
+
|
38
|
+
[:get, :post, :delete].each do |http_method|
|
39
|
+
define_method http_method do |path, opts={}|
|
40
|
+
response = client.send(
|
41
|
+
http_method,
|
42
|
+
opts.merge(
|
43
|
+
path: File.join('/1.2', path),
|
44
|
+
headers: {
|
45
|
+
'Content-Type': 'application/json'
|
46
|
+
}
|
47
|
+
)
|
48
|
+
)
|
49
|
+
if response.body && response.body.start_with?('{')
|
50
|
+
JSON.parse(response.body, symbolize_names: true)
|
51
|
+
elsif response.status.to_s.start_with?('2')
|
52
|
+
{success: true}
|
53
|
+
else
|
54
|
+
{error: response.status}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class Testing
|
64
|
+
include Kontena::Machine::Upcloud::UpcloudCommon
|
65
|
+
def initialize(user, pass)
|
66
|
+
@username = user
|
67
|
+
@password = pass
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
@@ -55,8 +55,13 @@ class Helper
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def yml_services
|
58
|
-
if File.exist?('kontena.yml')
|
59
|
-
|
58
|
+
if File.exist?('kontena.yml')
|
59
|
+
yaml = YAML.load(File.read('kontena.yml'))
|
60
|
+
if yaml['version'] == '2'
|
61
|
+
services = yaml['services']
|
62
|
+
else
|
63
|
+
services = yaml
|
64
|
+
end
|
60
65
|
services.keys
|
61
66
|
end
|
62
67
|
rescue
|
@@ -144,7 +149,7 @@ if words.size > 0
|
|
144
149
|
completion.push %w(add list delete)
|
145
150
|
when 'app'
|
146
151
|
completion.clear
|
147
|
-
sub_commands = %w(init build deploy start stop remove rm ps list
|
152
|
+
sub_commands = %w(init build config deploy start stop remove rm ps list
|
148
153
|
logs monitor show)
|
149
154
|
if words[1]
|
150
155
|
completion.push(sub_commands) unless sub_commands.include?(words[1])
|
@@ -0,0 +1,19 @@
|
|
1
|
+
wordpress:
|
2
|
+
extends:
|
3
|
+
file: docker-compose.yml
|
4
|
+
service: wordpress
|
5
|
+
image: wordpress:$TAG
|
6
|
+
stateful: true
|
7
|
+
environment:
|
8
|
+
- WORDPRESS_DB_PASSWORD=%{project}_secret
|
9
|
+
instances: 2
|
10
|
+
deploy:
|
11
|
+
strategy: ha
|
12
|
+
mysql:
|
13
|
+
extends:
|
14
|
+
file: docker-compose.yml
|
15
|
+
service: mysql
|
16
|
+
image: ${MYSQL_IMAGE}
|
17
|
+
stateful: true
|
18
|
+
environment:
|
19
|
+
- INTERNAL_VAR=$$INTERNAL_VAR
|
data/spec/fixtures/kontena.yml
CHANGED
@@ -4,7 +4,7 @@ wordpress:
|
|
4
4
|
service: wordpress
|
5
5
|
stateful: true
|
6
6
|
environment:
|
7
|
-
|
7
|
+
WORDPRESS_DB_PASSWORD: %{project}_secret
|
8
8
|
instances: 2
|
9
9
|
deploy:
|
10
10
|
strategy: ha
|
@@ -14,4 +14,4 @@ mysql:
|
|
14
14
|
service: mysql
|
15
15
|
stateful: true
|
16
16
|
environment:
|
17
|
-
- MYSQL_ROOT_PASSWORD=%{project}_secret
|
17
|
+
- MYSQL_ROOT_PASSWORD=%{project}_secret
|
@@ -0,0 +1,35 @@
|
|
1
|
+
version: '2'
|
2
|
+
name: test-project
|
3
|
+
services:
|
4
|
+
wordpress:
|
5
|
+
extends:
|
6
|
+
file: docker-compose_v2.yml
|
7
|
+
service: wordpress
|
8
|
+
stateful: true
|
9
|
+
environment:
|
10
|
+
WORDPRESS_DB_PASSWORD: ${project}_secret
|
11
|
+
instances: 2
|
12
|
+
deploy:
|
13
|
+
strategy: ha
|
14
|
+
networks:
|
15
|
+
- front-tier
|
16
|
+
- back-tier
|
17
|
+
mysql:
|
18
|
+
extends:
|
19
|
+
file: docker-compose_v2.yml
|
20
|
+
service: mysql
|
21
|
+
stateful: true
|
22
|
+
environment:
|
23
|
+
- MYSQL_ROOT_PASSWORD=${project}_secret
|
24
|
+
volumes:
|
25
|
+
- mysql-data:/var/lib/mysql
|
26
|
+
networks:
|
27
|
+
- back-tier
|
28
|
+
volumes:
|
29
|
+
mysql-data:
|
30
|
+
driver: local
|
31
|
+
networks:
|
32
|
+
front-tier:
|
33
|
+
driver: bridge
|
34
|
+
back-tier:
|
35
|
+
driver: bridge
|
@@ -13,6 +13,10 @@ describe Kontena::Cli::Apps::Common do
|
|
13
13
|
fixture('kontena.yml')
|
14
14
|
end
|
15
15
|
|
16
|
+
let(:kontena_v2_yml) do
|
17
|
+
fixture('kontena_v2.yml')
|
18
|
+
end
|
19
|
+
|
16
20
|
let(:docker_compose_yml) do
|
17
21
|
fixture('docker-compose.yml')
|
18
22
|
end
|
@@ -30,122 +34,56 @@ describe Kontena::Cli::Apps::Common do
|
|
30
34
|
}
|
31
35
|
end
|
32
36
|
|
33
|
-
describe '#
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
allow(File).to receive(:read).with("#{Dir.getwd}/docker-compose.yml").and_return(docker_compose_yml)
|
38
|
-
services = subject.parse_services('kontena.yml')
|
39
|
-
expect(services['wordpress']).not_to be_nil
|
37
|
+
describe '#service_prefix' do
|
38
|
+
it 'returns given project name' do
|
39
|
+
allow(subject).to receive(:project_name).and_return('test')
|
40
|
+
expect(subject.service_prefix).to eq('test')
|
40
41
|
end
|
41
42
|
|
42
|
-
it '
|
43
|
-
allow(
|
44
|
-
allow(
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
}.to raise_error(SystemExit)
|
43
|
+
it 'returns app name from yaml if project name not given' do
|
44
|
+
allow(subject).to receive(:project_name).and_return(nil)
|
45
|
+
allow(subject).to receive(:filename).and_return('kontena.yml')
|
46
|
+
allow(File).to receive(:read).with("#{Dir.getwd}/docker-compose_v2.yml").and_return(docker_compose_yml)
|
47
|
+
allow(File).to receive(:read).with("#{Dir.getwd}/kontena.yml").and_return(kontena_v2_yml)
|
48
|
+
expect(subject.service_prefix).to eq('test-project')
|
49
49
|
end
|
50
|
-
end
|
51
50
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
}
|
59
|
-
}
|
60
|
-
subject.normalize_env_vars(opts)
|
61
|
-
env = opts['environment']
|
62
|
-
expect(env).to include('FOO=bar')
|
63
|
-
expect(env).to include('BAR=baz')
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'does nothing to env array' do
|
67
|
-
opts = {
|
68
|
-
'environment' => [
|
69
|
-
'FOO=bar', 'BAR=baz'
|
70
|
-
]
|
71
|
-
}
|
72
|
-
subject.normalize_env_vars(opts)
|
73
|
-
env = opts['environment']
|
74
|
-
expect(env).to include('FOO=bar')
|
75
|
-
expect(env).to include('BAR=baz')
|
51
|
+
it 'returns current dir as default' do
|
52
|
+
allow(subject).to receive(:project_name).and_return(nil)
|
53
|
+
allow(subject).to receive(:filename).and_return('kontena.yml')
|
54
|
+
allow(subject).to receive(:project_name_from_yaml).and_return(nil)
|
55
|
+
allow(subject).to receive(:current_dir).and_return('working_dir')
|
56
|
+
expect(subject.service_prefix).to eq('working_dir')
|
76
57
|
end
|
77
58
|
end
|
78
59
|
|
79
|
-
describe '#
|
80
|
-
|
81
|
-
|
82
|
-
to
|
83
|
-
env_vars = subject.extend_env_vars(from, to)
|
84
|
-
expect(env_vars).to eq(['FOO=bar'])
|
85
|
-
end
|
86
|
-
|
87
|
-
it 'overrides values' do
|
88
|
-
from = ['FOO=bar']
|
89
|
-
to = ['FOO=baz']
|
90
|
-
env_vars = subject.extend_env_vars(from, to)
|
91
|
-
expect(env_vars).to eq(['FOO=baz'])
|
60
|
+
describe '#load_from_yaml' do
|
61
|
+
before(:each) do
|
62
|
+
allow(File).to receive(:read).with("#{Dir.getwd}/kontena.yml").and_return(kontena_yml)
|
63
|
+
allow(File).to receive(:read).with("#{Dir.getwd}/docker-compose.yml").and_return(docker_compose_yml)
|
92
64
|
end
|
93
65
|
|
94
|
-
it '
|
95
|
-
|
96
|
-
to
|
97
|
-
|
98
|
-
expect(env_vars).to eq(['BAR=baz', 'FOO=bar'])
|
66
|
+
it 'populates env variables' do
|
67
|
+
services = subject.services_from_yaml('kontena.yml',[],'load-test')
|
68
|
+
expect(ENV['grid']).to eq('test-grid')
|
69
|
+
expect(ENV['project']).to eq('load-test')
|
99
70
|
end
|
100
|
-
end
|
101
71
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
'secret' => 'CUSTOMER_DB_PASSWORD',
|
106
|
-
'name' => 'MYSQL_PASSWORD',
|
107
|
-
'type' => 'env'
|
108
|
-
}
|
109
|
-
from = [secret]
|
110
|
-
to = nil
|
111
|
-
secrets = subject.extend_secrets(from, to)
|
112
|
-
expect(secrets).to eq([secret])
|
72
|
+
it 'returns services from given YAML file' do
|
73
|
+
services = subject.services_from_yaml('kontena.yml',[],'')
|
74
|
+
expect(services['wordpress']).not_to be_nil
|
113
75
|
end
|
114
76
|
|
115
|
-
it '
|
116
|
-
|
117
|
-
'
|
118
|
-
|
119
|
-
'type' => 'env'
|
120
|
-
}
|
121
|
-
|
122
|
-
to_secret = {
|
123
|
-
'secret' => 'CUSTOMER_DB_PASSWORD',
|
124
|
-
'name' => 'MYSQL_ROOT_PASSWORD',
|
125
|
-
'type' => 'env'
|
126
|
-
}
|
127
|
-
from = [from_secret]
|
128
|
-
to = [to_secret]
|
129
|
-
secrets = subject.extend_secrets(from, to)
|
130
|
-
expect(secrets).to eq([to_secret])
|
77
|
+
it 'aborts on validation failure' do
|
78
|
+
allow_any_instance_of(Kontena::Cli::Apps::YAML::Validator).to receive(:validate)
|
79
|
+
.and_return({ :errors => [{ 'wordress' => [] }], :notifications => [] })
|
80
|
+
expect { subject.services_from_yaml('kontena.yml',[],'') }.to raise_error(SystemExit)
|
131
81
|
end
|
132
82
|
|
133
|
-
it '
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
'type' => 'env'
|
138
|
-
}
|
139
|
-
|
140
|
-
to_secret = {
|
141
|
-
'secret' => 'CUSTOMER_API_TOKEN',
|
142
|
-
'name' => 'API_TOKEN',
|
143
|
-
'type' => 'env'
|
144
|
-
}
|
145
|
-
from = [from_secret]
|
146
|
-
to = [to_secret]
|
147
|
-
secrets = subject.extend_secrets(from, to)
|
148
|
-
expect(secrets).to eq([to_secret, from_secret])
|
83
|
+
it 'returns given service from given YAML file' do
|
84
|
+
services = subject.services_from_yaml('kontena.yml',['wordpress'],'')
|
85
|
+
expect(services['wordpress']).not_to be_nil
|
86
|
+
expect(services.size).to eq(1)
|
149
87
|
end
|
150
88
|
end
|
151
89
|
end
|