kontena-cli 1.4.0 → 1.4.1.pre1

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.
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