kontena-cli 1.4.2.pre1 → 1.4.2.rc1
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/config.rb +85 -36
- data/lib/kontena/cli/stacks/validate_command.rb +9 -10
- data/lib/kontena/cli/stacks/yaml/reader.rb +1 -0
- data/spec/kontena/cli/stacks/validate_command_spec.rb +50 -5
- data/spec/support/exit_with_error_helper.rb +1 -0
- data/spec/support/output_helpers.rb +38 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d80c5a60886f305951632390349ef6168fc24b69542c108309fa0119e912c79e
|
|
4
|
+
data.tar.gz: f8cfba36671e56f8262aa6e90a41547ee229434f96ca5409e48c79b4deca8b68
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b71ece37a3830283045dac25fb34d4f3f844df2954a83d3f0e6d88236477f334e9a65dc0fc74ac557eb75c0218f5dc691568ee96789f590479b76d43c02a525b
|
|
7
|
+
data.tar.gz: fdc0e18068f530dfc3fc06a403f4b002424cfb4d9c8cfc53e26b68570a8502ef5677c4959a90be85bf24f6d26c725596acf2c9be63d9ff8fa4fa064b15f23f1d
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.4.2.
|
|
1
|
+
1.4.2.rc1
|
data/lib/kontena/cli/config.rb
CHANGED
|
@@ -40,53 +40,94 @@ module Kontena
|
|
|
40
40
|
def initialize
|
|
41
41
|
super
|
|
42
42
|
@logger = Kontena.logger
|
|
43
|
-
load_settings_from_env || load_settings_from_config_file
|
|
44
43
|
|
|
45
|
-
|
|
44
|
+
load_settings_from_config_file
|
|
45
|
+
|
|
46
|
+
override_master_settings_from_env
|
|
47
|
+
override_cloud_settings_from_env
|
|
48
|
+
|
|
49
|
+
debug { "Configuration loaded with #{servers.count} servers and #{accounts.count} accounts." }
|
|
46
50
|
debug { "Current master: #{current_server || '(not selected)'}" }
|
|
47
51
|
debug { "Current grid: #{current_grid || '(not selected)'}" }
|
|
52
|
+
debug { "Current account: #{current_account.nil? ? '(not selected)' : current_account.name}" }
|
|
48
53
|
end
|
|
49
54
|
|
|
50
55
|
def debug(&block)
|
|
51
56
|
Kontena.logger.add(Logger::DEBUG, nil, 'CONFIG', &block)
|
|
52
57
|
end
|
|
53
58
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
+
def override_master_settings_from_env
|
|
60
|
+
if ENV['KONTENA_URL']
|
|
61
|
+
server = find_server_by(url: ENV['KONTENA_URL'])
|
|
62
|
+
if server.nil?
|
|
63
|
+
debug { 'Using new master url from env KONTENA_URL' }
|
|
64
|
+
server = Server.new(
|
|
65
|
+
url: ENV['KONTENA_URL'],
|
|
66
|
+
name: ENV['KONTENA_MASTER'] || 'default'
|
|
67
|
+
)
|
|
68
|
+
servers << server
|
|
69
|
+
else
|
|
70
|
+
debug { "Using master #{server.name} in config found via url in env KONTENA_URL" }
|
|
71
|
+
end
|
|
72
|
+
elsif ENV['KONTENA_MASTER']
|
|
73
|
+
server = find_server_by(name: ENV['KONTENA_MASTER'])
|
|
74
|
+
if server
|
|
75
|
+
debug { "Using master #{ENV['KONTENA_MASTER']} set via env KONTENA_MASTER" }
|
|
76
|
+
end
|
|
77
|
+
elsif current_master
|
|
78
|
+
server = current_master
|
|
79
|
+
end
|
|
59
80
|
|
|
60
|
-
|
|
61
|
-
|
|
81
|
+
if server.nil?
|
|
82
|
+
debug { 'Could not determine a master through config or env' }
|
|
83
|
+
self.current_master = nil
|
|
84
|
+
return
|
|
85
|
+
else
|
|
86
|
+
self.current_master = server.name
|
|
87
|
+
end
|
|
62
88
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
token: Token.new(
|
|
68
|
-
access_token: ENV['KONTENA_TOKEN'],
|
|
69
|
-
parent_type: :master, parent_name: 'default'
|
|
70
|
-
),
|
|
71
|
-
grid: ENV['KONTENA_GRID'],
|
|
72
|
-
parent_type: :master,
|
|
73
|
-
parent_name: 'default'
|
|
74
|
-
)
|
|
89
|
+
if ENV['KONTENA_GRID']
|
|
90
|
+
debug { "Using grid #{ENV['KONTENA_GRID']} from env KONTENA_GRID" }
|
|
91
|
+
server.grid = ENV['KONTENA_GRID']
|
|
92
|
+
end
|
|
75
93
|
|
|
76
|
-
|
|
94
|
+
if ENV['KONTENA_TOKEN']
|
|
95
|
+
debug { 'Using master token from env KONTENA_TOKEN' }
|
|
96
|
+
server.token ||= Token.new(parent_type: :master, parent_name: server.name)
|
|
97
|
+
server.token.access_token = ENV['KONTENA_TOKEN']
|
|
98
|
+
server.token.refresh_token = nil
|
|
99
|
+
server.token.expires_at = nil
|
|
100
|
+
end
|
|
77
101
|
end
|
|
78
102
|
|
|
79
|
-
def
|
|
80
|
-
|
|
103
|
+
def override_cloud_settings_from_env
|
|
104
|
+
if ENV['KONTENA_CLOUD']
|
|
105
|
+
account = find_account(ENV['KONTENA_CLOUD'])
|
|
106
|
+
if account
|
|
107
|
+
debug { "Using cloud account #{ENV['KONTENA_CLOUD']} from config selected by env KONTENA_CLOUD" }
|
|
108
|
+
self.current_account = account.name
|
|
109
|
+
else
|
|
110
|
+
debug { "Using new cloud account #{ENV['KONTENA_CLOUD']} from env" }
|
|
111
|
+
account = Accout.new(kontena_account_data.merge(name: ENV['KONTENA_CLOUD']))
|
|
112
|
+
accounts << account
|
|
113
|
+
end
|
|
114
|
+
elsif current_account
|
|
115
|
+
account = current_account
|
|
116
|
+
end
|
|
81
117
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
118
|
+
if account.nil?
|
|
119
|
+
debug { 'No account data from config or env' }
|
|
120
|
+
self.current_account = nil
|
|
121
|
+
return
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
if ENV['KONTENA_CLOUD_TOKEN']
|
|
125
|
+
debug { 'Using cloud token from env KONTENA_CLOUD_TOKEN' }
|
|
126
|
+
account.token ||= Token.new(parent_type: :account, parent_name: account.name)
|
|
127
|
+
account.token.access_token = ENV['KONTENA_CLOUD_TOKEN']
|
|
128
|
+
account.token.refresh_token = nil
|
|
129
|
+
account.token.expires_at = nil
|
|
130
|
+
end
|
|
90
131
|
end
|
|
91
132
|
|
|
92
133
|
def extract_token!(hash={})
|
|
@@ -120,7 +161,7 @@ module Kontena
|
|
|
120
161
|
servers << server
|
|
121
162
|
end
|
|
122
163
|
|
|
123
|
-
self.current_server =
|
|
164
|
+
self.current_server = settings['current_server']
|
|
124
165
|
|
|
125
166
|
Array(settings['accounts']).each do |account_data|
|
|
126
167
|
if account_data['token']
|
|
@@ -146,7 +187,7 @@ module Kontena
|
|
|
146
187
|
accounts.delete_at(master_index) if master_index
|
|
147
188
|
accounts << Account.new(master_account_data)
|
|
148
189
|
|
|
149
|
-
self.current_account =
|
|
190
|
+
self.current_account = settings['current_account'] || 'kontena'
|
|
150
191
|
end
|
|
151
192
|
|
|
152
193
|
def kontena_account_data
|
|
@@ -232,7 +273,13 @@ module Kontena
|
|
|
232
273
|
#
|
|
233
274
|
# @return [String] path
|
|
234
275
|
def config_filename
|
|
235
|
-
@config_filename
|
|
276
|
+
return @config_filename if @config_filename
|
|
277
|
+
if ENV['KONTENA_CONFIG']
|
|
278
|
+
debug { "Using #{ENV['KONTENA_CONFIG']} as config file set through env KONTENA_CONFIG"}
|
|
279
|
+
@config_filename = ENV['KONTENA_CONFIG']
|
|
280
|
+
else
|
|
281
|
+
@config_filename = default_config_filename
|
|
282
|
+
end
|
|
236
283
|
end
|
|
237
284
|
|
|
238
285
|
# Generate the default configuration filename
|
|
@@ -401,7 +448,9 @@ module Kontena
|
|
|
401
448
|
#
|
|
402
449
|
# @return [String, NilClass]
|
|
403
450
|
def current_grid
|
|
404
|
-
ENV['KONTENA_GRID']
|
|
451
|
+
return ENV['KONTENA_GRID'] unless ENV['KONTENA_GRID'].to_s.empty?
|
|
452
|
+
return nil unless current_master
|
|
453
|
+
current_master.grid
|
|
405
454
|
end
|
|
406
455
|
|
|
407
456
|
# Set the current grid name.
|
|
@@ -19,6 +19,7 @@ module Kontena::Cli::Stacks
|
|
|
19
19
|
option '--dependency-tree', :flag, "Show dependency tree"
|
|
20
20
|
option '--[no-]dependencies', :flag, "Validate dependencies", default: true
|
|
21
21
|
option '--parent-name', '[PARENT_NAME]', "Set parent name", hidden: true
|
|
22
|
+
option '--format', 'yaml|api-json', "Output Format", default: 'yaml'
|
|
22
23
|
|
|
23
24
|
def validate_dependencies
|
|
24
25
|
dependencies = loader.dependencies
|
|
@@ -59,18 +60,16 @@ module Kontena::Cli::Stacks
|
|
|
59
60
|
|
|
60
61
|
dump_variables if values_to
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
puts ::YAML.dump(result).sub(/\A---$/, "---\n# #{loader.source}")
|
|
63
|
+
case self.format
|
|
64
|
+
when 'api-json'
|
|
65
|
+
puts JSON.pretty_generate(stack)
|
|
66
|
+
when 'yaml'
|
|
67
|
+
result = ::YAML.dump(reader.fully_interpolated_yaml)
|
|
68
|
+
result = result.sub(/\A---$/, "---\n# #{loader.source}") if dependencies?
|
|
69
|
+
puts result
|
|
70
70
|
else
|
|
71
|
-
|
|
71
|
+
exit_with_error "Unknown --format=#{self.format}"
|
|
72
72
|
end
|
|
73
73
|
end
|
|
74
74
|
end
|
|
75
75
|
end
|
|
76
|
-
|
|
@@ -273,6 +273,7 @@ module Kontena::Cli::Stacks
|
|
|
273
273
|
# @param [String] service_name - optional service to parse
|
|
274
274
|
# @return [Hash]
|
|
275
275
|
def parse_services(service_name = nil)
|
|
276
|
+
services = self.services.dup # do not modify the fully_interpolated_yaml['services'] hash in-place
|
|
276
277
|
if service_name.nil?
|
|
277
278
|
services.each do |name, config|
|
|
278
279
|
services[name] = process_config(config, name)
|
|
@@ -5,26 +5,71 @@ describe Kontena::Cli::Stacks::UpgradeCommand do
|
|
|
5
5
|
include ClientHelpers
|
|
6
6
|
include RequirementsHelper
|
|
7
7
|
include FixturesHelpers
|
|
8
|
+
include OutputHelpers
|
|
8
9
|
|
|
9
10
|
context 'without dependencies' do
|
|
10
11
|
before do
|
|
11
12
|
[:read, :exist?].each do |meth|
|
|
12
13
|
allow(File).to receive(meth).with(fixture_path('kontena_v3.yml')).and_call_original
|
|
13
14
|
allow(File).to receive(meth).with(fixture_path('docker-compose_v2.yml')).and_call_original
|
|
15
|
+
allow(File).to receive(meth).with(fixture_path('stack-with-liquid.yml')).and_call_original
|
|
14
16
|
end
|
|
15
17
|
end
|
|
16
18
|
|
|
17
|
-
it '
|
|
18
|
-
expect{Kontena.run!('stack', 'validate', fixture_path('
|
|
19
|
-
|
|
19
|
+
it 'outputs interpolated YAML' do
|
|
20
|
+
expect{Kontena.run!('stack', 'validate', fixture_path('stack-with-liquid.yml'))}.to output_yaml(
|
|
21
|
+
'stack' => 'user/stackname',
|
|
22
|
+
'version' => '0.1.1',
|
|
23
|
+
'variables' => {
|
|
24
|
+
'grid_name' => hash_including(
|
|
25
|
+
'value' => 'validate stackname',
|
|
26
|
+
),
|
|
27
|
+
'copies' => {
|
|
28
|
+
'type' => 'integer',
|
|
29
|
+
'value' => 5,
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
'services' => hash_including(
|
|
33
|
+
'service-1' => hash_including(
|
|
34
|
+
'image' => 'foo:1',
|
|
35
|
+
),
|
|
36
|
+
),
|
|
37
|
+
)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'outputs API JSON' do
|
|
41
|
+
expect{Kontena.run!('stack', 'validate', '-v', 'copies=2', '--format=api-json', fixture_path('stack-with-liquid.yml'))}.to output_json(hash_including(
|
|
42
|
+
'stack' => 'user/stackname',
|
|
43
|
+
'version' => '0.1.1',
|
|
44
|
+
'name' => 'stackname',
|
|
45
|
+
'registry' => 'file://',
|
|
46
|
+
'expose' => nil,
|
|
47
|
+
'volumes' => [ ],
|
|
48
|
+
'dependencies' => nil,
|
|
49
|
+
'source' => a_string_matching(/.+/),
|
|
50
|
+
'parent_name' => nil,
|
|
51
|
+
'variables' => {
|
|
52
|
+
'grid_name' => '{{ GRID }} stackname',
|
|
53
|
+
'copies' => 2,
|
|
54
|
+
},
|
|
55
|
+
'services' => [
|
|
56
|
+
hash_including(
|
|
57
|
+
'name' => 'service-1',
|
|
58
|
+
'image' => 'foo:1',
|
|
59
|
+
),
|
|
60
|
+
hash_including(
|
|
61
|
+
'name' => 'service-2',
|
|
62
|
+
'image' => 'foo:2',
|
|
63
|
+
),
|
|
64
|
+
],
|
|
65
|
+
))
|
|
20
66
|
end
|
|
21
67
|
|
|
22
68
|
context '--online' do
|
|
23
69
|
it 'validates a yaml file' do
|
|
24
|
-
expect{Kontena.run!('stack', 'validate', '--online', fixture_path('kontena_v3.yml'))}.to output(/stack:.*version:.*services
|
|
70
|
+
expect{Kontena.run!('stack', 'validate', '--online', fixture_path('kontena_v3.yml'))}.to output(/stack:.*version:.*services:/m).to_stdout
|
|
25
71
|
end
|
|
26
72
|
end
|
|
27
|
-
|
|
28
73
|
end
|
|
29
74
|
|
|
30
75
|
context 'with dependencies' do
|
|
@@ -97,6 +97,44 @@ module OutputHelpers
|
|
|
97
97
|
end
|
|
98
98
|
end
|
|
99
99
|
|
|
100
|
+
matcher :output_yaml do |expected|
|
|
101
|
+
supports_block_expectations
|
|
102
|
+
|
|
103
|
+
match do |block|
|
|
104
|
+
output = CaptureStdout.capture(block)
|
|
105
|
+
actual = ::YAML.safe_load(output)
|
|
106
|
+
|
|
107
|
+
values_match?(expected, actual)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
matcher :output_json do |expected|
|
|
112
|
+
supports_block_expectations
|
|
113
|
+
|
|
114
|
+
match do |block|
|
|
115
|
+
output = CaptureStdout.capture(block)
|
|
116
|
+
@actual = JSON.parse(output)
|
|
117
|
+
|
|
118
|
+
values_match?(expected, @actual)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
failure_message do |block|
|
|
122
|
+
return "expected block to return #{expected}, but returned #{@actual}"
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
module CaptureStdout
|
|
127
|
+
def self.capture(block)
|
|
128
|
+
capture = StringIO.new
|
|
129
|
+
original = $stdout
|
|
130
|
+
$stdout = capture
|
|
131
|
+
block.call
|
|
132
|
+
capture.string
|
|
133
|
+
ensure
|
|
134
|
+
$stdout = original
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
100
138
|
module CaptureStdoutLines
|
|
101
139
|
def self.capture(block)
|
|
102
140
|
capture = StringIO.new
|
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.2.
|
|
4
|
+
version: 1.4.2.rc1
|
|
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-12-
|
|
11
|
+
date: 2017-12-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|