kontena-cli 1.4.2.pre1 → 1.4.2.rc1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1d83ecd393990f31582a50935e3f654d2bb80d800f5b5d196aa3dd37fb8384fb
4
- data.tar.gz: '06882cc66e76fea42a919d1d8b3df32980f3f28bd20e5f72252f14ccb2537cb0'
3
+ metadata.gz: d80c5a60886f305951632390349ef6168fc24b69542c108309fa0119e912c79e
4
+ data.tar.gz: f8cfba36671e56f8262aa6e90a41547ee229434f96ca5409e48c79b4deca8b68
5
5
  SHA512:
6
- metadata.gz: 7cb24f24e500a85564e50180cdf1f846f168320aafb4c612df7c112dcf8b090e3d085d0933550d080629743f97988a8ece671d4d11ca1df89a3c8ca1d113a42c
7
- data.tar.gz: 4a3bd5066d50938bcd3dba051f4a61cfdf89e7cad81af0eb01a2297c3027db3aafd45ee773d9da33681cbffa6ab550ba2ef6bfcd650139337f83c25fac488043
6
+ metadata.gz: b71ece37a3830283045dac25fb34d4f3f844df2954a83d3f0e6d88236477f334e9a65dc0fc74ac557eb75c0218f5dc691568ee96789f590479b76d43c02a525b
7
+ data.tar.gz: fdc0e18068f530dfc3fc06a403f4b002424cfb4d9c8cfc53e26b68570a8502ef5677c4959a90be85bf24f6d26c725596acf2c9be63d9ff8fa4fa064b15f23f1d
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.2.pre1
1
+ 1.4.2.rc1
@@ -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
- debug { "Configuration loaded with #{servers.count} servers." }
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
- # Craft a regular looking configuration based on ENV variables
55
- def load_settings_from_env
56
- load_cloud_settings_from_env
57
- load_master_settings_from_env
58
- end
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
- def load_master_settings_from_env
61
- return nil unless ENV['KONTENA_URL']
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
- debug { 'Loading master configuration from ENV' }
64
- servers << Server.new(
65
- url: ENV['KONTENA_URL'],
66
- name: 'default',
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
- self.current_master = 'default'
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 load_cloud_settings_from_env
80
- return unless ENV['KONTENA_CLOUD_TOKEN']
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
- debug { 'Loading cloud configuration from ENV' }
83
- accounts << Account.new(kontena_account_data.merge(
84
- token: Token.new(
85
- access_token: ENV['KONTENA_CLOUD_TOKEN'],
86
- parent_type: :account, parent_name: 'default'
87
- )
88
- ))
89
- self.current_account = 'kontena'
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 = ENV['KONTENA_MASTER'] || settings['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 = ENV['KONTENA_CLOUD'] || settings['current_account'] || 'kontena'
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 ||= ENV['KONTENA_CONFIG'] || default_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'] || (current_master && current_master.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
- result = stack.reject { |k, _| k == 'source' }
63
- result.merge!(
64
- 'variables' => Kontena::Util.stringify_keys(
65
- reader.variable_values(without_defaults: true, without_vault: true, with_errors: true)
66
- )
67
- )
68
- if dependencies?
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
- puts ::YAML.dump(result)
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 'validates a yaml file' do
18
- expect{Kontena.run!('stack', 'validate', fixture_path('kontena_v3.yml'))}.not_to exit_with_error
19
- expect{Kontena.run!('stack', 'validate', fixture_path('kontena_v3.yml'))}.to output(/stack:.*version:.*services:.*variables:/m).to_stdout
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:.*variables:/m).to_stdout
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
@@ -1,3 +1,4 @@
1
+ RSpec::Matchers.define_negated_matcher :exit_without_error, :exit_with_error
1
2
  RSpec::Matchers.define :exit_with_error do
2
3
 
3
4
  def supports_block_expectations?
@@ -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.pre1
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-07 00:00:00.000000000 Z
11
+ date: 2017-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler