kontena-cli 1.4.0 → 1.4.1.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +5 -5
  2. data/VERSION +1 -1
  3. data/bin/kontena +2 -1
  4. data/kontena-cli.gemspec +1 -1
  5. data/lib/kontena/cli/certificate/common.rb +16 -0
  6. data/lib/kontena/cli/certificate/export_command.rb +28 -0
  7. data/lib/kontena/cli/certificate/import_command.rb +61 -0
  8. data/lib/kontena/cli/certificate/show_command.rb +5 -2
  9. data/lib/kontena/cli/certificate_command.rb +3 -1
  10. data/lib/kontena/cli/common.rb +5 -1
  11. data/lib/kontena/cli/config.rb +23 -5
  12. data/lib/kontena/cli/external_registries/add_command.rb +2 -0
  13. data/lib/kontena/cli/external_registries/list_command.rb +1 -1
  14. data/lib/kontena/cli/helpers/exec_helper.rb +12 -4
  15. data/lib/kontena/cli/master/config/import_command.rb +1 -1
  16. data/lib/kontena/cli/master/login_command.rb +1 -1
  17. data/lib/kontena/cli/stacks/common.rb +2 -1
  18. data/lib/kontena/cli/stacks/registry/show_command.rb +1 -1
  19. data/lib/kontena/cli/stacks/service_generator.rb +1 -0
  20. data/lib/kontena/cli/stacks/yaml/opto.rb +1 -0
  21. data/lib/kontena/cli/stacks/yaml/opto/certificates_resolver.rb +37 -0
  22. data/lib/kontena/cli/stacks/yaml/opto/vault_cert_prompt_resolver.rb +1 -1
  23. data/lib/kontena/cli/stacks/yaml/reader.rb +5 -2
  24. data/lib/kontena/cli/stacks/yaml/validations.rb +2 -1
  25. data/lib/kontena/cli/vault/import_command.rb +1 -1
  26. data/lib/kontena/client.rb +1 -1
  27. data/lib/kontena/command.rb +7 -5
  28. data/lib/kontena/plugin_manager.rb +1 -1
  29. data/lib/kontena/plugin_manager/cleaner.rb +1 -1
  30. data/lib/kontena/scripts/completer.rb +1 -1
  31. data/lib/kontena/stacks_cache.rb +2 -2
  32. data/lib/kontena_cli.rb +6 -2
  33. data/spec/fixtures/certificates/test/ca-key.pem +10 -0
  34. data/spec/fixtures/certificates/test/ca.pem +10 -0
  35. data/spec/fixtures/certificates/test/ca.srl +1 -0
  36. data/spec/fixtures/certificates/test/cert.pem +8 -0
  37. data/spec/fixtures/certificates/test/csr.pem +7 -0
  38. data/spec/fixtures/certificates/test/key.pem +10 -0
  39. data/spec/fixtures/certificates/test/real-cert.pem +30 -0
  40. data/spec/fixtures/docker-compose_v2.yml +1 -0
  41. data/spec/fixtures/docker-compose_v2_with_variables.yml +12 -0
  42. data/spec/fixtures/kontena_v3_with_compose_variables.yml +11 -0
  43. data/spec/fixtures/stack-with-anchors.yml +13 -0
  44. data/spec/kontena/cli/certificates/export_command_spec.rb +49 -0
  45. data/spec/kontena/cli/certificates/import_command_spec.rb +70 -0
  46. data/spec/kontena/cli/certificates/show_command_spec.rb +57 -0
  47. data/spec/kontena/cli/cloud/login_command_spec.rb +7 -14
  48. data/spec/kontena/cli/helpers/exec_helper_spec.rb +38 -0
  49. data/spec/kontena/cli/master/login_command_spec.rb +12 -24
  50. data/spec/kontena/cli/master/use_command_spec.rb +1 -1
  51. data/spec/kontena/cli/nodes/remove_command_spec.rb +1 -1
  52. data/spec/kontena/cli/registry/{create_spec.rb → create_command_spec.rb} +0 -0
  53. data/spec/kontena/cli/stacks/upgrade_command_spec.rb +1 -1
  54. data/spec/kontena/cli/stacks/yaml/opto/certificates_resolver_spec.rb +81 -0
  55. data/spec/kontena/cli/stacks/yaml/reader_spec.rb +22 -2
  56. data/spec/kontena/cli/stacks/yaml/validator_v3_spec.rb +17 -0
  57. data/spec/kontena/command_spec.rb +54 -0
  58. data/spec/kontena/config_spec.rb +17 -2
  59. data/spec/kontena/main_command_spec.rb +13 -0
  60. data/spec/spec_helper.rb +10 -17
  61. metadata +43 -11
  62. data/spec/kontena/cli/main_command_spec.rb +0 -19
@@ -82,7 +82,8 @@ module Kontena::Cli::Stacks::YAML
82
82
  }),
83
83
  'stop_signal' => optional('string'),
84
84
  'stop_grace_period' => optional(/(\d+(?:\.\d+)?)([hms])/),
85
- 'read_only' => optional('boolean')
85
+ 'read_only' => optional('boolean'),
86
+ 'entrypoint' => optional('string')
86
87
  }
87
88
  end
88
89
 
@@ -16,7 +16,7 @@ module Kontena::Cli::Vault
16
16
 
17
17
  def parsed_input
18
18
  require "json"
19
- json? ? JSON.load(input) : YAML.safe_load(input)
19
+ json? ? JSON.load(input) : YAML.safe_load(input, [], [], true, path)
20
20
  end
21
21
 
22
22
  def input
@@ -55,7 +55,7 @@ module Kontena
55
55
  write_timeout: ENV["EXCON_WRITE_TIMEOUT"] ? ENV["EXCON_WRITE_TIMEOUT"].to_i : 10,
56
56
  ssl_verify_peer: ignore_ssl_errors? ? false : true
57
57
  }
58
- if ENV["DEBUG"]
58
+ if Kontena.debug?
59
59
  require 'kontena/debug_instrumentor'
60
60
  excon_opts[:instrumentor] = Kontena::DebugInstrumentor
61
61
  end
@@ -7,9 +7,11 @@ require 'excon/errors'
7
7
 
8
8
  class Kontena::Command < Clamp::Command
9
9
 
10
- option ['-D', '--debug'], :flag, "Enable debug", environment_variable: 'DEBUG' do
11
- ENV['DEBUG'] ||= 'true'
12
- Kontena.reset_logger
10
+ option ['-D', '--[no-]debug'], :flag, "Enable debug", environment_variable: 'DEBUG', attribute_name: :debug_option do |debug|
11
+ unless debug.kind_of?(String)
12
+ ENV['DEBUG'] = debug.to_s
13
+ Kontena.reset_logger
14
+ end
13
15
  end
14
16
 
15
17
  attr_accessor :arguments
@@ -230,7 +232,7 @@ class Kontena::Command < Clamp::Command
230
232
  abort(ex.message)
231
233
  end
232
234
  rescue Kontena::Errors::StandardError => ex
233
- raise ex if ENV['DEBUG']
235
+ raise ex if Kontena.debug?
234
236
  Kontena.logger.error(ex)
235
237
  abort(" [#{Kontena.pastel.red('error')}] #{ex.status} : #{ex.message}")
236
238
  rescue Errno::EPIPE
@@ -239,7 +241,7 @@ class Kontena::Command < Clamp::Command
239
241
  rescue Clamp::HelpWanted, Clamp::UsageError
240
242
  raise
241
243
  rescue => ex
242
- raise ex if ENV['DEBUG']
244
+ raise ex if Kontena.debug?
243
245
  Kontena.logger.error(ex)
244
246
  abort(" [#{Kontena.pastel.red('error')}] #{ex.class.name} : #{ex.message}\n See #{Kontena.log_target} or run the command again with environment DEBUG=true set to see the full exception")
245
247
  end
@@ -11,7 +11,7 @@ module Kontena
11
11
  def init
12
12
  ENV["GEM_HOME"] = Common.install_dir
13
13
  Gem.paths = ENV
14
- Common.use_dummy_ui unless ENV["DEBUG"]
14
+ Common.use_dummy_ui unless Kontena.debug?
15
15
  plugins
16
16
  true
17
17
  end
@@ -20,7 +20,7 @@ module Kontena
20
20
  # @param plugin_name [String]
21
21
  def cleanup
22
22
  options = []
23
- options += ['-q', '--no-verbose'] unless ENV["DEBUG"]
23
+ options += ['-q', '--no-verbose'] unless Kontena.debug?
24
24
  command.handle_options options
25
25
  command.execute
26
26
  true
@@ -90,7 +90,7 @@ class Helper
90
90
  def yml_services
91
91
  require 'yaml'
92
92
  if File.exist?('kontena.yml')
93
- yaml = YAML.safe_load(File.read('kontena.yml'))
93
+ yaml = YAML.safe_load(File.read('kontena.yml'), [], [], true, 'kontena.yml')
94
94
  services = yaml['services']
95
95
  services.keys
96
96
  end
@@ -20,7 +20,7 @@ module Kontena
20
20
  end
21
21
 
22
22
  def load
23
- YAML.safe_load(read)
23
+ ::YAML.safe_load(read, [], [], true, path)
24
24
  end
25
25
 
26
26
  def write(content)
@@ -77,7 +77,7 @@ module Kontena
77
77
  else
78
78
  dputs "Retrieving #{stack.stack}:#{stack.version} from registry"
79
79
  content = client.pull(stack.stack, stack.version)
80
- yaml = ::YAML.safe_load(content)
80
+ yaml = ::YAML.safe_load(content, [], [], true, stack.stack)
81
81
  new_stack = CachedStack.new(yaml['stack'], yaml['version'])
82
82
  if new_stack.cached?
83
83
  dputs "Already cached"
data/lib/kontena_cli.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'kontena/autoload_core'
2
+ require 'set'
2
3
 
3
4
  $KONTENA_START_TIME = Time.now.to_f
4
5
  at_exit do
@@ -67,7 +68,7 @@ module Kontena
67
68
 
68
69
  @log_target = ENV['LOG_TARGET']
69
70
 
70
- if ENV["DEBUG"]
71
+ if debug?
71
72
  @log_target ||= $stderr
72
73
  elsif @log_target.nil?
73
74
  @log_target = File.join(home, 'kontena.log')
@@ -158,11 +159,14 @@ module Kontena
158
159
  require 'kontena/cli/log_formatters/strip_color'
159
160
  logger.formatter = Kontena::Cli::LogFormatter::StripColor.new
160
161
  end
161
- logger.level = ENV["DEBUG"] ? Logger::DEBUG : Logger::INFO
162
+ logger.level = debug? ? Logger::DEBUG : Logger::INFO
162
163
  logger.progname = 'CLI'
163
164
  @logger = logger
164
165
  end
165
166
 
167
+ def self.debug?
168
+ !['', 'false'].include?(ENV['DEBUG'].to_s)
169
+ end
166
170
  end
167
171
 
168
172
  # Monkeypatching string to mimick 'colorize' gem
@@ -0,0 +1,10 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAz/Ee36KUY7l0tRFR
3
+ EO/XOSoOXqyv48Jcvz0TnV7d+n3yapzCZfvDtX0qMpdZqd4Gr7v2Zgr64PJJNELf
4
+ SE/vMQIDAQABAkAyvAviWJKH+lnFS+JRlZMXeXFkHBIWKffjGQ3OGbVjRiKubgj9
5
+ rzRe2qhNAIZtvlbpS2Yr3eq/nDsw9jX7uKd5AiEA9aXdMVpQpIfHg5WIpRuwBELN
6
+ KpkbuqP/9/5n/czHCLsCIQDYtHh9zljUWMrD+zcPQ4dd6Z0fINuMfDwDs+1nvlmv
7
+ AwIgbC9rVjP/diaycLonnwetooLFFvCtbKqTreWmaPmJ4scCIQCK0IhCpnTWiY5R
8
+ nlG10F8dNHG2p/ibdFWJVa+k/hU6+wIgYoZtco7QmR+0fdWDWgPym28sY3a+IXyM
9
+ VNIXoJoS8tU=
10
+ -----END PRIVATE KEY-----
@@ -0,0 +1,10 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIBYzCCAQ2gAwIBAgIJAIpNg6jylBQkMA0GCSqGSIb3DQEBCwUAMA0xCzAJBgNV
3
+ BAMMAkNBMB4XDTE3MTAzMTE3MDEyN1oXDTE4MTAzMTE3MDEyN1owDTELMAkGA1UE
4
+ AwwCQ0EwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAz/Ee36KUY7l0tRFREO/XOSoO
5
+ Xqyv48Jcvz0TnV7d+n3yapzCZfvDtX0qMpdZqd4Gr7v2Zgr64PJJNELfSE/vMQID
6
+ AQABo1AwTjAdBgNVHQ4EFgQUcLvPScr8TZMmeiGGtFQecMBrt+IwHwYDVR0jBBgw
7
+ FoAUcLvPScr8TZMmeiGGtFQecMBrt+IwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B
8
+ AQsFAANBAGjroEv8WBLeIbGbSDM6RMVHQjt8V5Pwd/RPI7pusWGsaJbOVXCwQSsd
9
+ wpUzwKt2lbtAZFmLIIJ53Pv0PZsgC6Q=
10
+ -----END CERTIFICATE-----
@@ -0,0 +1 @@
1
+ 02
@@ -0,0 +1,8 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIBBTCBsAIBAjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDDAJDQTAeFw0xNzEw
3
+ MzExNzA2MzJaFw0xNzExMzAxNzA2MzJaMA8xDTALBgNVBAMMBHRlc3QwXDANBgkq
4
+ hkiG9w0BAQEFAANLADBIAkEA+jOxPABMu7Kp4lfrlGXWm+kQWIj4FSi5pczK/ReE
5
+ w1Gxhq49CEt3bIC3Li8slJU4H1WZbhbz8VWyEUsmaYEfiQIDAQABMA0GCSqGSIb3
6
+ DQEBCwUAA0EAIHbczx/kmb/ji/5kDtAUldbicApY9vl75JbPxnAfU5yqyZjhsFiF
7
+ uH6nBTUEAXS4Ic89vJ+J9e14hXh7YLzq1w==
8
+ -----END CERTIFICATE-----
@@ -0,0 +1,7 @@
1
+ -----BEGIN CERTIFICATE REQUEST-----
2
+ MIHIMHQCAQAwDzENMAsGA1UEAwwEdGVzdDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgC
3
+ QQD6M7E8AEy7sqniV+uUZdab6RBYiPgVKLmlzMr9F4TDUbGGrj0IS3dsgLcuLyyU
4
+ lTgfVZluFvPxVbIRSyZpgR+JAgMBAAGgADANBgkqhkiG9w0BAQsFAANBAKBAbxJj
5
+ x3DNK2gL88PDH935+pD1TV5R/D2CllptYIn9at3NUb5/eN2iziqLUOPECpk+poj5
6
+ FL5XWsl7ktIHmEA=
7
+ -----END CERTIFICATE REQUEST-----
@@ -0,0 +1,10 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIIBVgIBADANBgkqhkiG9w0BAQEFAASCAUAwggE8AgEAAkEA+jOxPABMu7Kp4lfr
3
+ lGXWm+kQWIj4FSi5pczK/ReEw1Gxhq49CEt3bIC3Li8slJU4H1WZbhbz8VWyEUsm
4
+ aYEfiQIDAQABAkBb0uTU1HdU23klrIa067sbdSmelIYXnd6kTsigoiUDWRo9mccV
5
+ kPx4bL+L9bL2BX64+Sqjch2+EUYYqQSQLMzRAiEA/fpz9nR5feWi75URhS1oHi/0
6
+ vpYxvQlTyt6LNBG6LxsCIQD8MYs+tUhwCfuKHPSfqE9oizOwAcfTUp/PVgLGhWcC
7
+ KwIhAN3AQGGuHqmqx5GRwSNbmu3Ih1Okhbb8ntmhZz9GPx6DAiEAjPfApt+8Suw5
8
+ j30Z+/if0ock8Dg+k1A3BjVEveUprBsCIQCjel8oZuN/3zatvWMCgCQboYoQjw9M
9
+ U3GffGoMbo0kTw==
10
+ -----END PRIVATE KEY-----
@@ -0,0 +1,30 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIFFTCCA/2gAwIBAgITAPpXZfJpighg3wDd/LIHVlOS9zANBgkqhkiG9w0BAQsF
3
+ ADAiMSAwHgYDVQQDDBdGYWtlIExFIEludGVybWVkaWF0ZSBYMTAeFw0xNzA5MTUx
4
+ MzM0MDBaFw0xNzEyMTQxMzM0MDBaMCUxIzAhBgNVBAMTGnRlc3QuMTg4LjIyNi4x
5
+ MzEuMjMueGlwLmlvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvCi9
6
+ j76XlJ+v7hOHxPiY8eNN9zW3Y35i+AmL0V15kNkaMd7Kb5XoOgRJB4OwgrzCMXTR
7
+ ZpyJxvXrOgqxRfNTjKQuf2UK/fmtdbwMLQFyH3LYLTQDNJo7m/kpgRPb0ftfFw6b
8
+ ZtwPO7Ss0/c1EtdcD710vren+E4Fn697mFwwYu7iVGLwiIaZOC+NiGmfDVo2bVv8
9
+ TMChFznkODZJSWP5ke2YHAxK6S8p/64EyW+KHHem7xl8G4LVRU9bC/dzlFm5cUmo
10
+ LQ1Xy+4ShWpvx4pvLdh5aWsRZPiIRsIZrw0oy7MfrkYAmAqcVU5ZjZJ5wXk4GUvc
11
+ Nv9A8QU3/wT6XGeLRwIDAQABo4ICPzCCAjswDgYDVR0PAQH/BAQDAgWgMB0GA1Ud
12
+ JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQW
13
+ BBTSjrEQ/94c4lQf7uJFdAd/igat7DAfBgNVHSMEGDAWgBTAzANGuVggzFxycPPh
14
+ LssgpvVoOjB3BggrBgEFBQcBAQRrMGkwMgYIKwYBBQUHMAGGJmh0dHA6Ly9vY3Nw
15
+ LnN0Zy1pbnQteDEubGV0c2VuY3J5cHQub3JnMDMGCCsGAQUFBzAChidodHRwOi8v
16
+ Y2VydC5zdGctaW50LXgxLmxldHNlbmNyeXB0Lm9yZy8wQgYDVR0RBDswOYIadGVz
17
+ dC4xODguMjI2LjEzMS4yMy54aXAuaW+CG3Rlc3QzLjE4OC4yMjYuMTMxLjIzLnhp
18
+ cC5pbzCB/gYDVR0gBIH2MIHzMAgGBmeBDAECATCB5gYLKwYBBAGC3xMBAQEwgdYw
19
+ JgYIKwYBBQUHAgEWGmh0dHA6Ly9jcHMubGV0c2VuY3J5cHQub3JnMIGrBggrBgEF
20
+ BQcCAjCBngyBm1RoaXMgQ2VydGlmaWNhdGUgbWF5IG9ubHkgYmUgcmVsaWVkIHVw
21
+ b24gYnkgUmVseWluZyBQYXJ0aWVzIGFuZCBvbmx5IGluIGFjY29yZGFuY2Ugd2l0
22
+ aCB0aGUgQ2VydGlmaWNhdGUgUG9saWN5IGZvdW5kIGF0IGh0dHBzOi8vbGV0c2Vu
23
+ Y3J5cHQub3JnL3JlcG9zaXRvcnkvMA0GCSqGSIb3DQEBCwUAA4IBAQCeIwx50XNh
24
+ qfvTxWsw4c2Ke44BPDcok2b7IL+tpcFlNRtlZHhEzFOZXvzZG3Nl8TyMaMd4ou7p
25
+ tWlp4k1l9OBbl9CCV5k6NTMfnABHvddD6c0QmNBIWrSEK05BGtdLBoDcC3/3xNgr
26
+ 4EvoawdDeWe3qwVsBWlBpb24vF7zRUR70ZIV7aqDL0y9lpkZEMUbtBNUNu9mlfOw
27
+ 1GkBBmDq8iA4tsxM9VXz7l22jia5UYfYtkaN6cteqjJ25XE6+HRjsG0N9xmzHEFz
28
+ AI20JrncQZVLx/gYxkNdEa1cyKvEF7huHr/8XBLbAnA6cjUsPGxQWbujV6VsnmL+
29
+ E57k3WbO+RPO
30
+ -----END CERTIFICATE-----
@@ -8,3 +8,4 @@ services:
8
8
  - mysql
9
9
  mysql:
10
10
  image: mysql:5.6
11
+ entrypoint: test
@@ -0,0 +1,12 @@
1
+ version: '2'
2
+ services:
3
+ wordpress:
4
+ image: wordpress:4.1
5
+ ports:
6
+ - 80:80
7
+ depends_on:
8
+ - mysql
9
+ mysql:
10
+ image: mysql:5.6
11
+ environment:
12
+ - ENV_VAR=$ENV_VAR
@@ -0,0 +1,11 @@
1
+ stack: user/stackname
2
+ version: 0.1.1
3
+ variables:
4
+ ENV_VAR:
5
+ type: string
6
+ value: abcd
7
+ services:
8
+ mysql:
9
+ extends:
10
+ file: docker-compose_v2_with_variables.yml
11
+ service: mysql
@@ -0,0 +1,13 @@
1
+ stack: user/stackname
2
+ version: 0.1.1
3
+ data:
4
+ with_affinity: &with_affinity
5
+ affinity:
6
+ - abc==dfg
7
+ services:
8
+ wordpress:
9
+ <<: *with_affinity
10
+ image: wordpress
11
+ mysql:
12
+ <<: *with_affinity
13
+ image: mysql
@@ -0,0 +1,49 @@
1
+ require 'kontena/cli/certificate/export_command'
2
+
3
+ describe Kontena::Cli::Certificate::ExportCommand do
4
+ include ClientHelpers
5
+ include OutputHelpers
6
+ include FixturesHelpers
7
+
8
+ let(:subject) { described_class.new("kontena") }
9
+
10
+ let(:ca_pem) { fixture('certificates/test/ca.pem') }
11
+ let(:cert_pem) { fixture('certificates/test/cert.pem') }
12
+ let(:key_pem) { fixture('certificates/test/key.pem') }
13
+
14
+ let(:certificate) {
15
+ {
16
+ 'id' => 'test/test.example.com',
17
+ 'subject' => 'test.example.com',
18
+ 'certificate' => cert_pem,
19
+ 'chain' => ca_pem,
20
+ 'private_key' => key_pem,
21
+ }
22
+ }
23
+
24
+ before do
25
+ allow(client).to receive(:get).with('certificates/test-grid/test.example.com/export').and_return(certificate)
26
+ end
27
+
28
+ it "outputs the cert bundle" do
29
+ expect{subject.run(['test.example.com'])}.to output(cert_pem + ca_pem + key_pem).to_stdout
30
+ end
31
+
32
+ describe '--cert' do
33
+ it "outputs the cert bundle" do
34
+ expect{subject.run(['--cert', 'test.example.com'])}.to output(cert_pem).to_stdout
35
+ end
36
+ end
37
+
38
+ describe '--chain' do
39
+ it "outputs the cert bundle" do
40
+ expect{subject.run(['--chain', 'test.example.com'])}.to output(ca_pem).to_stdout
41
+ end
42
+ end
43
+
44
+ describe '--key' do
45
+ it "outputs the cert bundle" do
46
+ expect{subject.run(['--key', 'test.example.com'])}.to output(key_pem).to_stdout
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,70 @@
1
+ require 'kontena/cli/certificate/import_command'
2
+
3
+ describe Kontena::Cli::Certificate::ImportCommand do
4
+ include ClientHelpers
5
+ include OutputHelpers
6
+ include FixturesHelpers
7
+
8
+ let(:subject) { described_class.new("kontena") }
9
+
10
+ let(:csr_path) { fixture_path('certificates/test/csr.pem') }
11
+ let(:ca_path) { fixture_path('certificates/test/ca.pem') }
12
+ let(:cert_path) { fixture_path('certificates/test/cert.pem') }
13
+ let(:key_path) { fixture_path('certificates/test/key.pem') }
14
+
15
+ let(:ca_pem) { fixture('certificates/test/ca.pem') }
16
+ let(:cert_pem) { fixture('certificates/test/cert.pem') }
17
+ let(:key_pem) { fixture('certificates/test/key.pem') }
18
+
19
+ let(:certificate) {
20
+ {
21
+ 'id' => 'test/test',
22
+ 'subject' => 'test',
23
+ 'valid_until' => (Time.now.utc + 3600).xmlschema,
24
+ 'alt_names' => [],
25
+ 'certificate_pem' => cert_pem,
26
+ 'chain_pem' => ca_pem,
27
+ 'private_key_pem' => key_pem,
28
+ }
29
+ }
30
+
31
+ before do
32
+ allow(client).to receive(:put).with('certificates/test-grid/test',
33
+ certificate: cert_pem,
34
+ private_key: key_pem,
35
+ chain: [ca_pem],
36
+ ).and_return(certificate)
37
+ end
38
+
39
+ it "errors for an invalid cert file" do
40
+ expect{subject.run(["--private-key=#{key_path}", "--chain=#{ca_path}", csr_path])}.to exit_with_error.and output(/Invalid certificate at .*: OpenSSL::X509::CertificateError: .*/).to_stderr
41
+ end
42
+
43
+ it "imports the cert files" do
44
+ expect{subject.run(["--private-key=#{key_path}", "--chain=#{ca_path}", cert_path])}.to output(/subject: test/).to_stdout
45
+ end
46
+
47
+ describe '--subject' do
48
+ it 'overrides the subject' do
49
+ allow(client).to receive(:put).with('certificates/test-grid/example.com', Hash).and_return(certificate)
50
+
51
+ subject.run(["--subject=example.com", "--private-key=#{key_path}", "--chain=#{ca_path}", cert_path])
52
+ end
53
+ end
54
+
55
+ describe "with non-existant --private-key= path" do
56
+ it "fails with a usage error" do
57
+ expect{
58
+ described_class.run('kontena', ["--private-key=/missing/path", "--chain=#{ca_path}", cert_path])
59
+ }.to exit_with_error.and output(/ERROR: option '--private-key': File not found: /).to_stderr
60
+ end
61
+ end
62
+
63
+ describe "with non-existant CERT path" do
64
+ it "fails with a usage error" do
65
+ expect{
66
+ described_class.run('kontena', ["--private-key=#{key_path}", "--chain=#{ca_path}", '/nonexist'])
67
+ }.to exit_with_error.and output(/ERROR: parameter 'CERT_FILE': File not found: /).to_stderr
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,57 @@
1
+ require 'kontena/cli/certificate/show_command'
2
+
3
+ describe Kontena::Cli::Certificate::ShowCommand do
4
+ include ClientHelpers
5
+ include OutputHelpers
6
+ include FixturesHelpers
7
+
8
+ let(:subject) { described_class.new("") }
9
+
10
+ let(:certificate) {
11
+ {
12
+ 'id' => 'test-grid/test.example.com',
13
+ 'subject' => 'test.example.com',
14
+ 'valid_until' => '2017-12-14T13:34:00.000+00:00',
15
+ 'alt_names' => [],
16
+ 'auto_renewable' => true,
17
+ }
18
+ }
19
+
20
+ before do
21
+ allow(client).to receive(:get).with('certificates/test-grid/test.example.com').and_return(certificate)
22
+ end
23
+
24
+ it "outputs the certificate info" do
25
+ expect{subject.run(['test.example.com'])}.to output_lines([
26
+ 'test-grid/test.example.com:',
27
+ ' subject: test.example.com',
28
+ " valid until: 2017-12-14T13:34:00Z",
29
+ ' auto renewable: true',
30
+ ])
31
+ end
32
+
33
+ context 'with certificate alt_names' do
34
+ let(:certificate) {
35
+ {
36
+ 'id' => 'test-grid/test.example.com',
37
+ 'subject' => 'test.example.com',
38
+ 'valid_until' => '2017-12-14T13:34:00.000+00:00',
39
+ 'alt_names' => [
40
+ 'test2.example.com',
41
+ ],
42
+ 'auto_renewable' => true,
43
+ }
44
+ }
45
+
46
+ it "outputs the certificate info" do
47
+ expect{subject.run(['test.example.com'])}.to output_lines([
48
+ 'test-grid/test.example.com:',
49
+ ' subject: test.example.com',
50
+ " valid until: 2017-12-14T13:34:00Z",
51
+ ' alt names:',
52
+ ' - test2.example.com',
53
+ ' auto renewable: true',
54
+ ])
55
+ end
56
+ end
57
+ end