kontena-cli 1.4.0.pre7 → 1.4.0.pre8
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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/kontena/cli/services/deploy_command.rb +2 -1
- data/lib/kontena/cli/services/services_helper.rb +2 -1
- data/lib/kontena/cli/stacks/common.rb +36 -3
- data/lib/kontena/cli/stacks/deploy_command.rb +1 -1
- data/lib/kontena/cli/stacks/install_command.rb +2 -0
- data/lib/kontena/cli/stacks/upgrade_command.rb +2 -0
- data/lib/kontena/cli/stacks/validate_command.rb +2 -0
- data/lib/kontena/cli/stacks/yaml/custom_validators/hooks_validator.rb +43 -1
- data/lib/kontena/cli/stacks/yaml/reader.rb +25 -22
- data/lib/kontena/cli/stacks/yaml/stack_file_loader/file_loader.rb +1 -1
- data/spec/kontena/cli/stacks/common_spec.rb +29 -5
- data/spec/kontena/cli/stacks/install_command_spec.rb +99 -1
- data/spec/kontena/cli/stacks/yaml/reader_spec.rb +21 -13
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e5fbe13d6c43974ce734828c192b42c582b56a04
|
4
|
+
data.tar.gz: a2de0cbe2555ea75327028a9f1f6417f839a876f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ed72921adf1a691ed03ea9ec1223800191136b686d89c0e1ca2af21306755e83cb9844c69db3831da566a1592d700d12c2126a99ae9f620c1817d0bf3ce6441
|
7
|
+
data.tar.gz: f1fd2b0a344552704f2e3c1de967daed63e9cf66532791af1040aea5f19262b7b123b2ee1f19d1799525cb02556784192fa9329b2e68a00636cfebc01c31463d
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.4.0.
|
1
|
+
1.4.0.pre8
|
@@ -7,6 +7,7 @@ module Kontena::Cli::Services
|
|
7
7
|
include ServicesHelper
|
8
8
|
|
9
9
|
parameter "NAME", "Service name"
|
10
|
+
option '--[no-]wait', :flag, 'Do not wait for service deployment', default: true
|
10
11
|
option '--force', :flag, 'Force deploy even if service does not have any changes'
|
11
12
|
|
12
13
|
def execute
|
@@ -17,7 +18,7 @@ module Kontena::Cli::Services
|
|
17
18
|
data[:force] = true if force?
|
18
19
|
spinner "Deploying service #{name.colorize(:cyan)} " do
|
19
20
|
deployment = deploy_service(token, name, data)
|
20
|
-
wait_for_deploy_to_finish(token, deployment)
|
21
|
+
wait_for_deploy_to_finish(token, deployment) if wait?
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
@@ -94,9 +94,17 @@ module Kontena::Cli::Stacks
|
|
94
94
|
def self.included(where)
|
95
95
|
where.prepend InstanceMethods
|
96
96
|
|
97
|
-
where.option '--values-from', '[FILE]', 'Read variable values from YAML' do |filename|
|
97
|
+
where.option '--values-from', '[FILE]', 'Read variable values from a YAML file', multivalued: true do |filename|
|
98
98
|
values_from_file.merge!(::YAML.safe_load(File.read(filename)))
|
99
|
-
|
99
|
+
filename
|
100
|
+
end
|
101
|
+
|
102
|
+
where.option '--values-from-stack', '[STACK_NAME]', 'Read variable values from an installed stack', multivalued: true do |stackname|
|
103
|
+
variables = read_values_from_stacks(stackname)
|
104
|
+
Kontena.logger.debug { "Received variables from stack #{stackname} on Master: #{variables.inspect}" }
|
105
|
+
warn "Stack #{stackname} does not have any values for variables" if variables.empty?
|
106
|
+
values_from_installed_stacks.merge!(variables)
|
107
|
+
stackname
|
100
108
|
end
|
101
109
|
|
102
110
|
where.option '-v', "VARIABLE=VALUE", "Set stack variable values, example: -v domain=example.com. Can be used multiple times.", multivalued: true, attribute_name: :var_option do |var_pair|
|
@@ -106,6 +114,27 @@ module Kontena::Cli::Stacks
|
|
106
114
|
end
|
107
115
|
|
108
116
|
module InstanceMethods
|
117
|
+
def read_values_from_stacks(stackname)
|
118
|
+
result = {}
|
119
|
+
response = client.get("stacks/#{current_grid}/#{stackname}")
|
120
|
+
result.merge!(response['variables']) if response['variables']
|
121
|
+
if response['children']
|
122
|
+
response['children'].each do |child_info|
|
123
|
+
result.merge!(
|
124
|
+
read_values_from_stacks(child_info['name']).tap do |child_result|
|
125
|
+
child_result.keys.each do |key|
|
126
|
+
new_key = child_info['name'].dup # foofoo-redis-monitor
|
127
|
+
new_key.sub!("#{stackname}-", '') # monitor
|
128
|
+
new_key.concat ".#{key}" # monitor.foovariable
|
129
|
+
child_result[new_key] = child_result.delete(key)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
result
|
136
|
+
end
|
137
|
+
|
109
138
|
def values_from_file
|
110
139
|
@values_from_file ||= {}
|
111
140
|
end
|
@@ -114,8 +143,12 @@ module Kontena::Cli::Stacks
|
|
114
143
|
@values_from_value_options ||= {}
|
115
144
|
end
|
116
145
|
|
146
|
+
def values_from_installed_stacks
|
147
|
+
@values_from_installed_stacks ||= {}
|
148
|
+
end
|
149
|
+
|
117
150
|
def values_from_options
|
118
|
-
@values_from_options ||= values_from_file.merge(values_from_value_options)
|
151
|
+
@values_from_options ||= values_from_installed_stacks.merge(values_from_file).merge(values_from_value_options)
|
119
152
|
end
|
120
153
|
|
121
154
|
# Transforms a hash
|
@@ -10,7 +10,7 @@ module Kontena::Cli::Stacks
|
|
10
10
|
|
11
11
|
parameter "NAME", "Stack name"
|
12
12
|
|
13
|
-
option '--[no-]wait', :flag, 'Do not wait service deployment', default: true
|
13
|
+
option '--[no-]wait', :flag, 'Do not wait for service deployment', default: true
|
14
14
|
|
15
15
|
requires_current_master
|
16
16
|
requires_current_master_token
|
@@ -139,9 +139,11 @@ module Kontena::Cli::Stacks
|
|
139
139
|
else
|
140
140
|
cmd = ['stack', 'install', '--name', stackname]
|
141
141
|
cmd.concat ['--parent-name', stack['parent_name']] if stack['parent_name']
|
142
|
+
|
142
143
|
stack['variables'].merge(dependency_values_from_options(stackname)).each do |k, v|
|
143
144
|
cmd.concat ['-v', "#{k}=#{v}"]
|
144
145
|
end
|
146
|
+
|
145
147
|
cmd << '--no-deploy'
|
146
148
|
cmd << data[:local][:loader].source
|
147
149
|
caret "Installing new dependency #{cmd.last} as #{stackname}"
|
@@ -51,6 +51,8 @@ module Kontena::Cli::Stacks
|
|
51
51
|
|
52
52
|
validate_dependencies if dependencies?
|
53
53
|
|
54
|
+
stack # runs validations
|
55
|
+
|
54
56
|
hint_on_validation_notifications(reader.notifications, dependencies? ? loader.source : nil)
|
55
57
|
abort_on_validation_errors(reader.errors, dependencies? ? loader.source : nil)
|
56
58
|
|
@@ -11,7 +11,7 @@ module Kontena::Cli::Stacks::YAML::Validations::CustomValidators
|
|
11
11
|
end
|
12
12
|
|
13
13
|
value.keys.each do |hook|
|
14
|
-
unless %w(pre_build post_start).include?(hook)
|
14
|
+
unless %w(pre_build pre_start post_start pre_stop).include?(hook)
|
15
15
|
errors[key] = "invalid hook #{hook}"
|
16
16
|
end
|
17
17
|
end
|
@@ -20,9 +20,17 @@ module Kontena::Cli::Stacks::YAML::Validations::CustomValidators
|
|
20
20
|
validate_pre_build_hooks(key, value['pre_build'], errors)
|
21
21
|
end
|
22
22
|
|
23
|
+
if value['pre_start']
|
24
|
+
validate_pre_start_hooks(key, value['pre_start'], errors)
|
25
|
+
end
|
26
|
+
|
23
27
|
if value['post_start']
|
24
28
|
validate_post_start_hooks(key, value['post_start'], errors)
|
25
29
|
end
|
30
|
+
|
31
|
+
if value['pre_stop']
|
32
|
+
validate_pre_stop_hooks(key, value['pre_stop'], errors)
|
33
|
+
end
|
26
34
|
end
|
27
35
|
|
28
36
|
def validate_pre_build_hooks(key, pre_build_hooks, errors)
|
@@ -40,6 +48,23 @@ module Kontena::Cli::Stacks::YAML::Validations::CustomValidators
|
|
40
48
|
end
|
41
49
|
end
|
42
50
|
|
51
|
+
def validate_pre_start_hooks(key, pre_start_hooks, errors)
|
52
|
+
unless pre_start_hooks.is_a?(Array)
|
53
|
+
errors[key] = { 'pre_start' => 'must be an array' }
|
54
|
+
return
|
55
|
+
end
|
56
|
+
pre_start_validation = {
|
57
|
+
'name' => 'string',
|
58
|
+
'instances' => (-> (value) { value.is_a?(Integer) || value == '*' }),
|
59
|
+
'cmd' => 'string',
|
60
|
+
'oneshot' => HashValidator.optional('boolean')
|
61
|
+
}
|
62
|
+
validator = HashValidator.validator_for(pre_start_validation)
|
63
|
+
pre_start_hooks.each do |pre_start|
|
64
|
+
validator.validate('hooks.pre_start', pre_start, pre_start_validation, errors)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
43
68
|
def validate_post_start_hooks(key, post_start_hooks, errors)
|
44
69
|
unless post_start_hooks.is_a?(Array)
|
45
70
|
errors[key] = { 'post_start' => 'must be an array' }
|
@@ -56,5 +81,22 @@ module Kontena::Cli::Stacks::YAML::Validations::CustomValidators
|
|
56
81
|
validator.validate('hooks.post_start', post_start, post_start_validation, errors)
|
57
82
|
end
|
58
83
|
end
|
84
|
+
|
85
|
+
def validate_pre_stop_hooks(key, pre_stop_hooks, errors)
|
86
|
+
unless pre_stop_hooks.is_a?(Array)
|
87
|
+
errors[key] = { 'pre_stop' => 'must be an array' }
|
88
|
+
return
|
89
|
+
end
|
90
|
+
pre_stop_validation = {
|
91
|
+
'name' => 'string',
|
92
|
+
'instances' => (-> (value) { value.is_a?(Integer) || value == '*' }),
|
93
|
+
'cmd' => 'string',
|
94
|
+
'oneshot' => HashValidator.optional('boolean')
|
95
|
+
}
|
96
|
+
validator = HashValidator.validator_for(pre_stop_validation)
|
97
|
+
pre_stop_hooks.each do |pre_stop|
|
98
|
+
validator.validate('hooks.pre_stop', pre_stop, pre_stop_validation, errors)
|
99
|
+
end
|
100
|
+
end
|
59
101
|
end
|
60
102
|
end
|
@@ -201,21 +201,26 @@ module Kontena::Cli::Stacks
|
|
201
201
|
|
202
202
|
validate unless skip_validation
|
203
203
|
|
204
|
-
{}
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
204
|
+
result = {}
|
205
|
+
Dir.chdir(from_file? ? File.dirname(File.expand_path(file)) : Dir.pwd) do
|
206
|
+
result['stack'] = raw_yaml['stack']
|
207
|
+
result['version'] = loader.stack_name.version || '0.0.1'
|
208
|
+
result['name'] = name
|
209
|
+
result['registry'] = loader.registry
|
210
|
+
result['expose'] = fully_interpolated_yaml['expose']
|
211
|
+
result['services'] = errors.empty? ? parse_services(service_name) : {}
|
212
|
+
result['volumes'] = errors.empty? ? parse_volumes : {}
|
213
|
+
result['dependencies'] = dependencies
|
214
|
+
result['source'] = raw_content
|
215
|
+
result['variables'] = variable_values(without_defaults: true, without_vault: true)
|
216
|
+
result['parent_name'] = parent_name
|
217
|
+
end
|
218
|
+
if service_name.nil?
|
219
|
+
result['services'].each do |service|
|
220
|
+
errors << { 'services' => { service['name'] => { 'image' => "image is missing" } } } if service['image'].to_s.empty?
|
217
221
|
end
|
218
222
|
end
|
223
|
+
result
|
219
224
|
end
|
220
225
|
|
221
226
|
# Returns an array of hashes containing the dependency tree starting from this file
|
@@ -317,7 +322,6 @@ module Kontena::Cli::Stacks
|
|
317
322
|
service_config.delete('extends')
|
318
323
|
end
|
319
324
|
if name
|
320
|
-
exit_with_error("Image is missing for #{name}. Aborting.") unless service_config['image'] # why isn't this a validation?
|
321
325
|
ServiceGeneratorV2.new(service_config).generate.merge('name' => name)
|
322
326
|
else
|
323
327
|
ServiceGeneratorV2.new(service_config).generate
|
@@ -345,10 +349,10 @@ module Kontena::Cli::Stacks
|
|
345
349
|
end
|
346
350
|
|
347
351
|
def from_external_file(filename, service_name)
|
348
|
-
external_reader =
|
352
|
+
external_reader = FileLoader.new(filename, loader).reader
|
349
353
|
outcome = external_reader.execute(service_name)
|
350
|
-
errors.concat external_reader.errors unless errors.
|
351
|
-
notifications.concat external_reader.notifications unless notifications.
|
354
|
+
errors.concat external_reader.errors unless external_reader.errors.empty? || errors.include?(external_reader.errors)
|
355
|
+
notifications.concat external_reader.notifications unless external_reader.notifications.empty? || notifications.include?(external_reader.notifications)
|
352
356
|
outcome['services']
|
353
357
|
end
|
354
358
|
|
@@ -445,13 +449,12 @@ module Kontena::Cli::Stacks
|
|
445
449
|
end
|
446
450
|
|
447
451
|
def store_failures(data)
|
448
|
-
data['errors']
|
449
|
-
data['notifications']
|
450
|
-
errors << { file => data['errors']
|
451
|
-
notifications << { file => data['notifications'] } unless data['notifications'].empty?
|
452
|
+
data['errors'] ||= data[:errors] || []
|
453
|
+
data['notifications'] ||= data[:notifications] || []
|
454
|
+
errors << { File.basename(file) => data['errors'] } unless data['errors'].empty?
|
455
|
+
notifications << { File.basename(file) => data['notifications'] } unless data['notifications'].empty?
|
452
456
|
end
|
453
457
|
|
454
|
-
|
455
458
|
# @param [Hash] options - service config
|
456
459
|
def normalize_env_vars(options)
|
457
460
|
if options['environment'].kind_of?(Hash)
|
@@ -3,6 +3,10 @@ require "kontena/cli/stacks/yaml/reader"
|
|
3
3
|
|
4
4
|
describe Kontena::Cli::Stacks::Common do
|
5
5
|
include FixturesHelpers
|
6
|
+
include RequirementsHelper
|
7
|
+
include ClientHelpers
|
8
|
+
|
9
|
+
mock_current_master
|
6
10
|
|
7
11
|
let(:klass) do
|
8
12
|
Class.new(Kontena::Command) do
|
@@ -12,10 +16,6 @@ describe Kontena::Cli::Stacks::Common do
|
|
12
16
|
include Kontena::Cli::Stacks::Common::StackNameOption
|
13
17
|
include Kontena::Cli::Stacks::Common::StackValuesToOption
|
14
18
|
include Kontena::Cli::Stacks::Common::StackValuesFromOption
|
15
|
-
|
16
|
-
def what
|
17
|
-
[source]
|
18
|
-
end
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -57,7 +57,7 @@ describe Kontena::Cli::Stacks::Common do
|
|
57
57
|
expect(subject.instance(['-v', 'foo=bar', '-v', 'bar=baz', fixture_path('kontena_v3.yml')]).values_from_options).to match hash_including('foo' => 'bar', 'bar' => 'baz')
|
58
58
|
end
|
59
59
|
|
60
|
-
|
60
|
+
describe '--values-from' do
|
61
61
|
before do
|
62
62
|
allow(File).to receive(:exist?).with('vars.yml').and_return(true)
|
63
63
|
expect(File).to receive(:read).with('vars.yml').and_return(::YAML.dump('baz' => 'bag', 'bar' => 'boo'))
|
@@ -71,5 +71,29 @@ describe Kontena::Cli::Stacks::Common do
|
|
71
71
|
expect(subject.instance(['-v', 'foo=bar', '-v', 'bar=baz', '--values-from', 'vars.yml', fixture_path('kontena_v3.yml')]).values_from_options).to match hash_including('foo' => 'bar', 'bar' => 'baz', 'baz' => 'bag')
|
72
72
|
end
|
73
73
|
end
|
74
|
+
|
75
|
+
describe '--values-from-stack' do
|
76
|
+
let(:instance) { subject.instance(['--values-from-stack', 'redisproxy', fixture_path('kontena_v3.yml')]) }
|
77
|
+
|
78
|
+
it 'reads all dependent stack variables' do
|
79
|
+
expect(client).to receive(:get).with('stacks/test-grid/redisproxy').and_return(
|
80
|
+
'variables' => { 'foo' => 'bar' },
|
81
|
+
'children' => [ { 'name' => 'redisproxy-redis1' } ]
|
82
|
+
)
|
83
|
+
|
84
|
+
expect(client).to receive(:get).with('stacks/test-grid/redisproxy-redis1').and_return(
|
85
|
+
'variables' => { 'redisvar' => 'test' },
|
86
|
+
'children' => [ { 'name' => 'redisproxy-redis1-monitor' } ]
|
87
|
+
)
|
88
|
+
|
89
|
+
expect(client).to receive(:get).with('stacks/test-grid/redisproxy-redis1-monitor').and_return(
|
90
|
+
'variables' => { 'monitorvar' => 'test2' },
|
91
|
+
'children' => []
|
92
|
+
)
|
93
|
+
|
94
|
+
expect(instance.values_from_options).to match hash_including('foo' => 'bar', 'redis1.redisvar' => 'test', 'redis1.monitor.monitorvar' => 'test2')
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
74
98
|
end
|
75
99
|
end
|
@@ -65,7 +65,7 @@ describe Kontena::Cli::Stacks::InstallCommand do
|
|
65
65
|
context '--[no-]deploy' do
|
66
66
|
it 'runs deploy for the stack after install by default' do
|
67
67
|
expect(client).to receive(:post).with(
|
68
|
-
|
68
|
+
'grids/test-grid/stacks', hash_including(stack_expectation)
|
69
69
|
)
|
70
70
|
expect(Kontena).to receive(:run!).with(['stack', 'deploy', 'stackname']).and_return(true)
|
71
71
|
subject.run([fixture_path('kontena_v3.yml')])
|
@@ -82,4 +82,102 @@ describe Kontena::Cli::Stacks::InstallCommand do
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
end
|
85
|
+
|
86
|
+
context 'variable value input' do
|
87
|
+
let(:expectation) do
|
88
|
+
{
|
89
|
+
'services' => array_including(
|
90
|
+
hash_including(
|
91
|
+
'name' => 'mysql',
|
92
|
+
'image' => 'mysqlimage:latest',
|
93
|
+
'env' => array_including(
|
94
|
+
'TEST_VAR=abc'
|
95
|
+
)
|
96
|
+
),
|
97
|
+
hash_including(
|
98
|
+
'name' => 'wordpress',
|
99
|
+
'image' => 'wordpress:def'
|
100
|
+
)
|
101
|
+
)
|
102
|
+
}
|
103
|
+
end
|
104
|
+
|
105
|
+
describe '--values-from' do
|
106
|
+
it 'sends stack to master, loading values from a file' do
|
107
|
+
allow(File).to receive(:exist?).with('values.yml').and_return(true)
|
108
|
+
expect(File).to receive(:read).with('values.yml').and_return(
|
109
|
+
YAML.dump('TEST_ENV_VAR' => 'abc', 'MYSQL_IMAGE' => 'mysqlimage', 'tag' => 'def')
|
110
|
+
)
|
111
|
+
expect(client).to receive(:post) do |path, data|
|
112
|
+
expect(path).to eq 'grids/test-grid/stacks'
|
113
|
+
expect(data).to match hash_including(expectation)
|
114
|
+
end.and_return({})
|
115
|
+
subject.run(['--no-deploy', '--values-from', 'values.yml', fixture_path('stack-with-variables.yml')])
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe '--values-from-stack' do
|
120
|
+
it 'sends stack to master, loading values from another stack on master' do
|
121
|
+
expect(client).to receive(:get).with('stacks/test-grid/otherdep').and_return(
|
122
|
+
'variables' => { 'foo' => 'bar' },
|
123
|
+
'children' => [
|
124
|
+
{ 'name' => 'otherdep-dep_1' } ,
|
125
|
+
{ 'name' => 'otherdep-dep_2' }
|
126
|
+
]
|
127
|
+
)
|
128
|
+
|
129
|
+
expect(client).to receive(:get).with('stacks/test-grid/otherdep-dep_1').and_return(
|
130
|
+
'variables' => { 'dep1var' => 'test' },
|
131
|
+
'children' => [
|
132
|
+
{ 'name' => 'otherdep-dep_1-dep_1' }
|
133
|
+
]
|
134
|
+
)
|
135
|
+
|
136
|
+
expect(client).to receive(:get).with('stacks/test-grid/otherdep-dep_1-dep_1').and_return(
|
137
|
+
'variables' => { 'dep1dep1var' => 'test11' },
|
138
|
+
'children' => []
|
139
|
+
)
|
140
|
+
|
141
|
+
expect(client).to receive(:get).with('stacks/test-grid/otherdep-dep_2').and_return(
|
142
|
+
'variables' => { 'dep2var' => 'test2' },
|
143
|
+
'children' => [ ]
|
144
|
+
)
|
145
|
+
|
146
|
+
expect(Kontena).to receive(:run!).with(["stack", "install", "-n", "deptest-dep_1", "--parent-name", "deptest", '-v', 'dep1var=test', '-v', 'dep_1.dep1dep1var=test11', '--no-deploy', fixture_path('stack-with-dependencies-dep-1.yml')]).and_return(true)
|
147
|
+
expect(Kontena).to receive(:run!).with(["stack", "install", "-n", "deptest-dep_2", "--parent-name", "deptest", '-v', 'dep_var=1', '-v', 'dep2var=test2', '--no-deploy', fixture_path('stack-with-dependencies-dep-2.yml')]).and_return(true)
|
148
|
+
|
149
|
+
allow(client).to receive(:post).and_return({})
|
150
|
+
|
151
|
+
subject.run(['--values-from-stack', 'otherdep', '-n', 'deptest', '--no-deploy', fixture_path('stack-with-dependencies.yml')])
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe '-v' do
|
156
|
+
it 'sends stack to master, loading values from command line' do
|
157
|
+
expect(client).to receive(:post) do |path, data|
|
158
|
+
expect(path).to eq 'grids/test-grid/stacks'
|
159
|
+
expect(data).to match hash_including(expectation)
|
160
|
+
end.and_return({})
|
161
|
+
YAML.dump('TEST_ENV_VAR' => 'abc', 'MYSQL_IMAGE' => 'mysqlimage', 'tag' => 'def')
|
162
|
+
subject.run(['--no-deploy', '-v', 'TEST_ENV_VAR=abc', '-v', 'MYSQL_IMAGE=mysqlimage', '-v', 'tag=def', fixture_path('stack-with-variables.yml')])
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe 'combination of value inputs' do
|
167
|
+
it 'can combine multiple inputs' do
|
168
|
+
allow(File).to receive(:exist?).with('values.yml').and_return(true)
|
169
|
+
expect(File).to receive(:read).with('values.yml').and_return(
|
170
|
+
YAML.dump('TEST_ENV_VAR' => 'abc')
|
171
|
+
)
|
172
|
+
allow(client).to receive(:get).with('stacks/test-grid/foostack').and_return(
|
173
|
+
'variables' => { 'MYSQL_IMAGE' => 'mysqlimage' }
|
174
|
+
)
|
175
|
+
expect(client).to receive(:post) do |path, data|
|
176
|
+
expect(path).to eq 'grids/test-grid/stacks'
|
177
|
+
expect(data).to match hash_including(expectation)
|
178
|
+
end.and_return({})
|
179
|
+
subject.run(['--no-deploy', '--values-from-stack', 'foostack', '--values-from', 'values.yml', '-v', 'tag=def', fixture_path('stack-with-variables.yml')])
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
85
183
|
end
|
@@ -120,17 +120,15 @@ describe Kontena::Cli::Stacks::YAML::Reader do
|
|
120
120
|
it 'merges validation errors' do
|
121
121
|
expect(File).to receive(:read).with(fixture_path('docker-compose_v2.yml')).and_return(fixture('docker-compose-invalid.yml'))
|
122
122
|
outcome = subject.execute
|
123
|
-
expect(
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
'wordpress' => {
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
]
|
133
|
-
}])
|
123
|
+
expect(subject.errors).to match array_including(
|
124
|
+
hash_including(
|
125
|
+
'docker-compose_v2.yml' => array_including(
|
126
|
+
hash_including(
|
127
|
+
'services' => { 'wordpress' => { 'networks' => 'key not expected' } }
|
128
|
+
)
|
129
|
+
)
|
130
|
+
)
|
131
|
+
)
|
134
132
|
end
|
135
133
|
end
|
136
134
|
|
@@ -324,7 +322,12 @@ describe Kontena::Cli::Stacks::YAML::Reader do
|
|
324
322
|
|
325
323
|
it 'expands build option to absolute path' do
|
326
324
|
outcome = subject.execute
|
327
|
-
expect(outcome['services']
|
325
|
+
expect(outcome['services']).to match array_including(
|
326
|
+
hash_including(
|
327
|
+
'name' => 'webapp',
|
328
|
+
'build' => hash_including('context' => fixture_path(''))
|
329
|
+
)
|
330
|
+
)
|
328
331
|
end
|
329
332
|
end
|
330
333
|
|
@@ -335,7 +338,12 @@ describe Kontena::Cli::Stacks::YAML::Reader do
|
|
335
338
|
|
336
339
|
it 'expands build context to absolute path' do
|
337
340
|
outcome = subject.execute
|
338
|
-
expect(outcome['services']
|
341
|
+
expect(outcome['services']).to match array_including(
|
342
|
+
hash_including(
|
343
|
+
'name' => 'webapp',
|
344
|
+
'build' => hash_including('context' => fixture_path(''))
|
345
|
+
)
|
346
|
+
)
|
339
347
|
end
|
340
348
|
end
|
341
349
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kontena-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.0.
|
4
|
+
version: 1.4.0.pre8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kontena, Inc
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-09-
|
11
|
+
date: 2017-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|