autosign 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +73 -0
- data/README.rdoc +6 -0
- data/Rakefile +44 -0
- data/autosign.gemspec +29 -0
- data/autosign.rdoc +5 -0
- data/bin/autosign +169 -0
- data/bin/autosign-validator +41 -0
- data/features/autosign.feature +78 -0
- data/features/step_definitions/autosign_steps.rb +44 -0
- data/features/support/env.rb +17 -0
- data/features/validate.feature +20 -0
- data/fixtures/i-7672fe81.pem +34 -0
- data/lib/autosign.rb +9 -0
- data/lib/autosign/config.rb +131 -0
- data/lib/autosign/decoder.rb +32 -0
- data/lib/autosign/journal.rb +123 -0
- data/lib/autosign/logger.rb +7 -0
- data/lib/autosign/token.rb +143 -0
- data/lib/autosign/validator.rb +133 -0
- data/lib/autosign/validators/jwt.rb +63 -0
- data/lib/autosign/version.rb +3 -0
- metadata +213 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3d43769ea221d92c48e517138ec7a3c1ba16ed3a
|
4
|
+
data.tar.gz: 0a8454928712134b07dfaa5aa16c4451042086ac
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fd1b62abf9b19f6806a356a693c42eb91593ca9cad9bcc79240b7df3d01d1b72bc92c6b8cb14647f92cb92a59179831aa7a90e6d379274b536c977b65a844fd1
|
7
|
+
data.tar.gz: 4d5660957738acf9edd0413efab0c1fcc029ecc23ba049d75c26807a7e68f2310d5f5e22054a3c1469ab6e8609ec796ce1956968f6445bfb6e28ff3d990eda74
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
autosign (0.0.1)
|
5
|
+
deep_merge
|
6
|
+
gli (~> 2)
|
7
|
+
iniparse (~> 1)
|
8
|
+
jwt (~> 1)
|
9
|
+
logging
|
10
|
+
require_all
|
11
|
+
|
12
|
+
GEM
|
13
|
+
remote: https://rubygems.org/
|
14
|
+
specs:
|
15
|
+
CFPropertyList (2.2.8)
|
16
|
+
aruba (0.6.2)
|
17
|
+
childprocess (>= 0.3.6)
|
18
|
+
cucumber (>= 1.1.1)
|
19
|
+
rspec-expectations (>= 2.7.0)
|
20
|
+
builder (3.2.2)
|
21
|
+
childprocess (0.5.6)
|
22
|
+
ffi (~> 1.0, >= 1.0.11)
|
23
|
+
cucumber (2.0.0)
|
24
|
+
builder (>= 2.1.2)
|
25
|
+
cucumber-core (~> 1.1.3)
|
26
|
+
diff-lcs (>= 1.1.3)
|
27
|
+
gherkin (~> 2.12)
|
28
|
+
multi_json (>= 1.7.5, < 2.0)
|
29
|
+
multi_test (>= 0.1.2)
|
30
|
+
cucumber-core (1.1.3)
|
31
|
+
gherkin (~> 2.12.0)
|
32
|
+
deep_merge (1.0.1)
|
33
|
+
diff-lcs (1.2.5)
|
34
|
+
facter (2.2.0)
|
35
|
+
CFPropertyList (~> 2.2.6)
|
36
|
+
ffi (1.9.9)
|
37
|
+
gherkin (2.12.2)
|
38
|
+
multi_json (~> 1.3)
|
39
|
+
gli (2.13.1)
|
40
|
+
hiera (1.3.4)
|
41
|
+
json_pure
|
42
|
+
iniparse (1.4.0)
|
43
|
+
json (1.8.3)
|
44
|
+
json_pure (1.8.1)
|
45
|
+
jwt (1.5.1)
|
46
|
+
little-plugger (1.1.3)
|
47
|
+
logging (2.0.0)
|
48
|
+
little-plugger (~> 1.1)
|
49
|
+
multi_json (~> 1.10)
|
50
|
+
multi_json (1.11.1)
|
51
|
+
multi_test (0.1.2)
|
52
|
+
puppet (3.7.0)
|
53
|
+
facter (> 1.6, < 3)
|
54
|
+
hiera (~> 1.0)
|
55
|
+
json_pure
|
56
|
+
rake (10.4.2)
|
57
|
+
rdoc (4.2.0)
|
58
|
+
json (~> 1.4)
|
59
|
+
require_all (1.3.2)
|
60
|
+
rspec-expectations (3.3.0)
|
61
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
62
|
+
rspec-support (~> 3.3.0)
|
63
|
+
rspec-support (3.3.0)
|
64
|
+
|
65
|
+
PLATFORMS
|
66
|
+
ruby
|
67
|
+
|
68
|
+
DEPENDENCIES
|
69
|
+
aruba
|
70
|
+
autosign!
|
71
|
+
puppet
|
72
|
+
rake
|
73
|
+
rdoc
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rubygems/package_task'
|
4
|
+
require 'rdoc/task'
|
5
|
+
require 'cucumber'
|
6
|
+
require 'cucumber/rake/task'
|
7
|
+
Rake::RDocTask.new do |rd|
|
8
|
+
rd.main = "README.rdoc"
|
9
|
+
rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
|
10
|
+
rd.title = 'Your application title'
|
11
|
+
end
|
12
|
+
|
13
|
+
spec = eval(File.read('autosign.gemspec'))
|
14
|
+
|
15
|
+
Gem::PackageTask.new(spec) do |pkg|
|
16
|
+
end
|
17
|
+
CUKE_RESULTS = 'results.html'
|
18
|
+
CLEAN << CUKE_RESULTS
|
19
|
+
desc 'Run features'
|
20
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
21
|
+
opts = "features --format html -o #{CUKE_RESULTS} --format progress -x"
|
22
|
+
opts += " --tags #{ENV['TAGS']}" if ENV['TAGS']
|
23
|
+
t.cucumber_opts = opts
|
24
|
+
t.fork = false
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'Run features tagged as work-in-progress (@wip)'
|
28
|
+
Cucumber::Rake::Task.new('features:wip') do |t|
|
29
|
+
tag_opts = ' --tags ~@pending'
|
30
|
+
tag_opts = ' --tags @wip'
|
31
|
+
t.cucumber_opts = "features --format html -o #{CUKE_RESULTS} --format pretty -x -s#{tag_opts}"
|
32
|
+
t.fork = false
|
33
|
+
end
|
34
|
+
|
35
|
+
task :cucumber => :features
|
36
|
+
task 'cucumber:wip' => 'features:wip'
|
37
|
+
task :wip => 'features:wip'
|
38
|
+
require 'rake/testtask'
|
39
|
+
Rake::TestTask.new do |t|
|
40
|
+
t.libs << "test"
|
41
|
+
t.test_files = FileList['test/*_test.rb']
|
42
|
+
end
|
43
|
+
|
44
|
+
task :default => [:test,:features]
|
data/autosign.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Ensure we require the local version and not one we might have installed already
|
2
|
+
require File.join([File.dirname(__FILE__),'lib','autosign','version.rb'])
|
3
|
+
spec = Gem::Specification.new do |s|
|
4
|
+
s.name = 'autosign'
|
5
|
+
s.version = Autosign::VERSION
|
6
|
+
s.author = 'Your Name Here'
|
7
|
+
s.email = 'your@email.address.com'
|
8
|
+
s.homepage = 'http://your.website.com'
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.summary = 'A description of your project'
|
11
|
+
s.files = `git ls-files`.split("
|
12
|
+
")
|
13
|
+
s.require_paths << 'lib'
|
14
|
+
s.has_rdoc = true
|
15
|
+
s.extra_rdoc_files = ['README.rdoc','autosign.rdoc']
|
16
|
+
s.rdoc_options << '--title' << 'autosign' << '--main' << 'README.rdoc' << '-ri'
|
17
|
+
s.bindir = 'bin'
|
18
|
+
s.executables << 'autosign'
|
19
|
+
s.add_development_dependency('rake')
|
20
|
+
s.add_development_dependency('rdoc')
|
21
|
+
s.add_development_dependency('aruba')
|
22
|
+
s.add_development_dependency('puppet')
|
23
|
+
s.add_runtime_dependency('gli','~> 2')
|
24
|
+
s.add_runtime_dependency('jwt','~> 1')
|
25
|
+
s.add_runtime_dependency('iniparse','~> 1')
|
26
|
+
s.add_runtime_dependency('logging')
|
27
|
+
s.add_runtime_dependency('deep_merge')
|
28
|
+
s.add_runtime_dependency('require_all')
|
29
|
+
end
|
data/autosign.rdoc
ADDED
data/bin/autosign
ADDED
@@ -0,0 +1,169 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'gli'
|
3
|
+
require 'autosign'
|
4
|
+
require 'socket' # for determining the current hostname
|
5
|
+
include GLI::App
|
6
|
+
require 'logging'
|
7
|
+
|
8
|
+
@logger = Logging.logger['Autosign']
|
9
|
+
@logger.level = :warn
|
10
|
+
|
11
|
+
program_desc 'Easy Puppet Certificate Autosigning'
|
12
|
+
|
13
|
+
version Autosign::VERSION
|
14
|
+
|
15
|
+
subcommand_option_handling :normal
|
16
|
+
arguments :strict
|
17
|
+
|
18
|
+
desc 'Configuration file location'
|
19
|
+
arg_name 'path'
|
20
|
+
flag [:c,:config]
|
21
|
+
|
22
|
+
desc 'log file location'
|
23
|
+
arg_name 'path'
|
24
|
+
flag [:l,:logfile]
|
25
|
+
|
26
|
+
desc 'secret symmetric key'
|
27
|
+
arg_name 'secret'
|
28
|
+
flag [:s,:secret]
|
29
|
+
|
30
|
+
desc 'Enable verbose output'
|
31
|
+
switch [:v, :verbose]
|
32
|
+
|
33
|
+
desc 'Enable debug output'
|
34
|
+
switch [:d, :debug]
|
35
|
+
|
36
|
+
desc 'Quiet output - only log errors'
|
37
|
+
switch [:q, :quiet]
|
38
|
+
|
39
|
+
desc 'Generate an autosign token'
|
40
|
+
arg_name 'certname or regex the autosign token will be valid for'
|
41
|
+
command :generate do |c|
|
42
|
+
c.desc 'Generate a reusable token; default is to generate one-time tokens'
|
43
|
+
c.switch [:r, :reusable]
|
44
|
+
|
45
|
+
c.desc 'certname or regex of certnames the autosign token will be valid for'
|
46
|
+
c.arg_name 'certname'
|
47
|
+
c.flag [:n,:certname]
|
48
|
+
|
49
|
+
c.desc 'autosign token validity period'
|
50
|
+
c.default_value '7200'
|
51
|
+
c.arg_name 'seconds'
|
52
|
+
c.flag [:t,:validfor]
|
53
|
+
|
54
|
+
c.action do |global_options,options,args|
|
55
|
+
config = Autosign::Config.new({'config_file' => global_options['config']})
|
56
|
+
global_options['secret'] = config.settings['jwt_token']['secret'] if global_options['secret'].nil?
|
57
|
+
options['validfor'] = config.settings.to_hash['jwt_token']['validity'].to_s if options['validfor'] == '7200'
|
58
|
+
@logger.debug "validfor: " + options['validfor']
|
59
|
+
help_now!('no secret was defined via --secret or a config file') if global_options['secret'].nil?
|
60
|
+
help_now!('certname is required') if options['certname'].nil?
|
61
|
+
|
62
|
+
help_now!('validfor setting must be an positive integer number of seconds') if !/\A\d+\z/.match(options['validfor'].to_s)
|
63
|
+
token = Autosign::Token.new(options['certname'].to_s, options['reusable'], options['validfor'].to_i, Socket.gethostname.to_s, global_options['secret'])
|
64
|
+
@logger.info "generated token for: " + options['certname'].to_s
|
65
|
+
puts "Autosign token for: " + token.certname
|
66
|
+
puts "Valid until: " + Time.at(token.validto).to_s
|
67
|
+
puts ""
|
68
|
+
puts token.sign.to_s
|
69
|
+
puts ""
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
desc 'Validate a previously issued token'
|
74
|
+
arg_name 'path'
|
75
|
+
command :validate do |c|
|
76
|
+
c.desc 'display the contents of the token'
|
77
|
+
|
78
|
+
c.arg_name 'certname'
|
79
|
+
c.flag [:n,:certname]
|
80
|
+
|
81
|
+
c.action do |global_options,options,args|
|
82
|
+
config = Autosign::Config.new({'config_file' => global_options['config']})
|
83
|
+
puts config.settings.to_hash['jwt_token']
|
84
|
+
global_options['secret'] = config.settings['jwt_token']['secret'] if global_options['secret'].nil?
|
85
|
+
|
86
|
+
help_now!('no secret was defined via --secret or a config file') if global_options['secret'].nil?
|
87
|
+
help_now!('certname is required') if options['certname'].nil?
|
88
|
+
help_now!('a single token must be provided as an argument') if args.size != 1
|
89
|
+
token = Autosign::Token.validate(options['certname'].to_s, args[0], global_options['secret'])
|
90
|
+
if token == true
|
91
|
+
puts "token validated successfully"
|
92
|
+
@logger.info "token validated successfully"
|
93
|
+
else
|
94
|
+
@logger.error "Unable to validate token"
|
95
|
+
exit_now!("Unable to validate token", 1)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
desc 'Autosign configuration'
|
102
|
+
command :config do |c|
|
103
|
+
|
104
|
+
c.desc 'Configure a puppet server for autosigning'
|
105
|
+
c.command :setup do |setup|
|
106
|
+
setup.action do |global_options,options,args|
|
107
|
+
@logger.info "setup command ran with #{global_options} #{options} #{args}"
|
108
|
+
@logger.info "generated default config file" if Autosign::Config.generate_default
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
c.desc 'Print autosign configuration'
|
113
|
+
c.command :print do |print|
|
114
|
+
print.action do |global_options,options,args|
|
115
|
+
@logger.debug "print command ran with #{global_options} #{options} #{args}"
|
116
|
+
config = Autosign::Config.new({'config_file' => global_options['config']})
|
117
|
+
puts config.settings.to_s
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
desc 'Install an autosign token; run this prior to running puppet for the first time on an agent'
|
124
|
+
arg_name 'token'
|
125
|
+
command :use do |c|
|
126
|
+
c.action do |global_options,options,args|
|
127
|
+
puppet_confdir = %x[puppet config print confdir].chomp
|
128
|
+
@logger.debug "use command ran with #{global_options} #{options} #{args}"
|
129
|
+
puts "put the following in #{puppet_confdir}/csr_attributes.yaml prior to running puppet agent for the first time:
|
130
|
+
custom_attributes:
|
131
|
+
challengePassword: \"#{args[0]}\""
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
pre do |global,command,options,args|
|
136
|
+
# Pre logic here
|
137
|
+
# Return true to proceed; false to abort and not call the
|
138
|
+
# chosen command
|
139
|
+
# Use skips_pre before a command to skip this block
|
140
|
+
# on that command only
|
141
|
+
# config = Autosign::Config.new
|
142
|
+
# @logger.level = config.settings.to_hash['general']['loglevel'].to_sym unless config.settings.to_hash['general']['loglevel'].nil?
|
143
|
+
|
144
|
+
@logger.level = :error if global['quiet']
|
145
|
+
@logger.level = :info if global['verbose']
|
146
|
+
@logger.level = :debug if global['debug']
|
147
|
+
|
148
|
+
if global['logfile'].nil?
|
149
|
+
@logger.add_appenders Logging.appenders.stdout
|
150
|
+
else
|
151
|
+
@logger.add_appenders Logging.appenders.stdout, Logging.appenders.file(global['logfile'])
|
152
|
+
end
|
153
|
+
|
154
|
+
true
|
155
|
+
end
|
156
|
+
|
157
|
+
post do |global,command,options,args|
|
158
|
+
# Post logic here
|
159
|
+
# Use skips_post before a command to skip this
|
160
|
+
# block on that command only
|
161
|
+
end
|
162
|
+
|
163
|
+
on_error do |exception|
|
164
|
+
# Error logic here
|
165
|
+
# return false to skip default error handling
|
166
|
+
true
|
167
|
+
end
|
168
|
+
|
169
|
+
exit run(ARGV)
|
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'autosign'
|
3
|
+
require 'logging'
|
4
|
+
|
5
|
+
@logger = Logging.logger['Autosign']
|
6
|
+
@logger.level = :debug
|
7
|
+
@logger.add_appenders Logging.appenders.stdout
|
8
|
+
|
9
|
+
### Get Inputs
|
10
|
+
unless ARGV.count == 1
|
11
|
+
@logger.error "This executable must be called with a certname as the only parameter and with an X509 CSR piped into STDIN"
|
12
|
+
exit 1
|
13
|
+
end
|
14
|
+
|
15
|
+
certname = ARGV[0]
|
16
|
+
@logger.debug "certname is " + certname
|
17
|
+
|
18
|
+
@logger.debug "reading CSR from stdin"
|
19
|
+
csr = Autosign::Decoder.decode_csr($stdin.read)
|
20
|
+
exit 1 unless csr.is_a?(Hash)
|
21
|
+
|
22
|
+
@logger.debug "CSR: " + csr.to_s
|
23
|
+
### End Inputs
|
24
|
+
|
25
|
+
### validate token
|
26
|
+
token_validation = Autosign::Validator.any_validator(csr[:challenge_password].to_s, certname.to_s)
|
27
|
+
### end validation
|
28
|
+
|
29
|
+
### Exit with correct exit status
|
30
|
+
if token_validation == true
|
31
|
+
@logger.info "token validated successfully"
|
32
|
+
exit 0
|
33
|
+
else
|
34
|
+
STDERR.puts "failed to validate token"
|
35
|
+
@logger.error "Unable to validate token"
|
36
|
+
exit 1
|
37
|
+
end
|
38
|
+
### Done exiting
|
39
|
+
|
40
|
+
# end with an exit 1 just in case
|
41
|
+
exit 1
|
@@ -0,0 +1,78 @@
|
|
1
|
+
Feature: Generate autosign key
|
2
|
+
In order to sign puppet certificates automatically
|
3
|
+
I want to generate autosign keys programatically
|
4
|
+
So I don't have to use static strings as keys
|
5
|
+
|
6
|
+
Scenario: Generate new token
|
7
|
+
Given a pre-shared key of "secret"
|
8
|
+
And a hostname of "foo.example.com"
|
9
|
+
And a file named "autosign.conf" with:
|
10
|
+
"""
|
11
|
+
[jwt_token]
|
12
|
+
validity = 7200
|
13
|
+
secret = secret
|
14
|
+
"""
|
15
|
+
When I run `chmod 600 autosign.conf`
|
16
|
+
And I run `autosign --config autosign.conf generate --certname foo.example.com`
|
17
|
+
Then the output should contain "Autosign token for: foo.example.com"
|
18
|
+
And the output should contain "Valid until"
|
19
|
+
And the exit status should be 0
|
20
|
+
|
21
|
+
Scenario: Generate new reusable token
|
22
|
+
Given a pre-shared key of "secret"
|
23
|
+
And a hostname of "foo.example.com"
|
24
|
+
And a file named "autosign.conf" with:
|
25
|
+
"""
|
26
|
+
[jwt_token]
|
27
|
+
secret = secret
|
28
|
+
validity = 7200
|
29
|
+
"""
|
30
|
+
When I run `chmod 600 autosign.conf`
|
31
|
+
When I run `autosign --config autosign.conf generate --certname foo.example.com --reusable`
|
32
|
+
Then the output should contain "Autosign token for: foo.example.com"
|
33
|
+
And the output should contain "Valid until"
|
34
|
+
And the exit status should be 0
|
35
|
+
|
36
|
+
Scenario: Validate a token
|
37
|
+
Given a pre-shared key of "secret"
|
38
|
+
And a hostname of "foo.example.com"
|
39
|
+
And a file named "autosign.conf" with:
|
40
|
+
"""
|
41
|
+
[jwt_token]
|
42
|
+
secret = secret
|
43
|
+
"""
|
44
|
+
When I run `chmod 600 autosign.conf`
|
45
|
+
When I run `autosign --config autosign.conf validate --certname "foo.example.com" "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJkYXRhIjoie1wiY2VydG5hbWVcIjpcImZvby5leGFtcGxlLmNvbVwiLFwicmVxdWVzdGVyXCI6XCJEYW5pZWxzLU1hY0Jvb2stUHJvLTIubG9jYWxcIixcInJldXNhYmxlXCI6ZmFsc2UsXCJ2YWxpZGZvclwiOjI5OTk5OTk5OSxcInV1aWRcIjpcIjlkYTA0Yzc4LWQ5NjUtNDk2OC04MWNjLWVhM2RjZDllZjVjMFwifSIsImV4cCI6IjE3MzY0NjYxMzAifQ.PJwY8rIunVyWi_lw0ypFclME0jx3Vd9xJIQSyhN3VUmul3V8u4Tp9XwDgoAu9DVV0-WEG2Tfxs6F8R6Fn71Ndg"`
|
46
|
+
Then the output should contain "token validated successfully"
|
47
|
+
And the exit status should be 0
|
48
|
+
|
49
|
+
Scenario: Not validate a bad token
|
50
|
+
Given a pre-shared key of "secret"
|
51
|
+
And a hostname of "foo.example.com"
|
52
|
+
And a file named "autosign.conf" with:
|
53
|
+
"""
|
54
|
+
[jwt_token]
|
55
|
+
secret = secret
|
56
|
+
"""
|
57
|
+
When I run `chmod 600 autosign.conf`
|
58
|
+
When I run `autosign --config autosign.conf validate --certname "foo.example.com" "invalid_token"`
|
59
|
+
Then the exit status should be 1
|
60
|
+
|
61
|
+
Scenario: Not validate an expired token
|
62
|
+
Given a pre-shared key of "secret"
|
63
|
+
And a hostname of "foo.example.com"
|
64
|
+
And a file named "autosign.conf" with:
|
65
|
+
"""
|
66
|
+
[jwt_token]
|
67
|
+
secret = secret
|
68
|
+
"""
|
69
|
+
When I run `chmod 600 autosign.conf`
|
70
|
+
When I run `autosign --config autosign.conf validate --certname "foo.example.com" "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJkYXRhIjoie1wiY2VydG5hbWVcIjpcImZvby5leGFtcGxlLmNvbVwiLFwicmVxdWVzdGVyXCI6XCJEYW5pZWxzLU1hY0Jvb2stUHJvLTIubG9jYWxcIixcInJldXNhYmxlXCI6ZmFsc2UsXCJ2YWxpZGZvclwiOjEsXCJ1dWlkXCI6XCJlNjI1Y2I1Ny02NzY5LTQwMzQtODNiZS0zNzkxNmQ5YmMxMDRcIn0iLCJleHAiOiIxNDM2NDY2MzAyIn0.UXEDEbRqEWx5SdSpQjfowU56JubY5Yz2QN6cckby2es-g2P_n2lyAS6AwFeliBXyCDyVUelIT3g1QP4TdB9EEA"`
|
71
|
+
Then the exit status should be 1
|
72
|
+
|
73
|
+
Scenario: Generate a csr_attributes.yaml file
|
74
|
+
When I run `autosign use hunter2`
|
75
|
+
Then the output should contain "challengePassword: "
|
76
|
+
And the output should contain "csr_attributes.yaml"
|
77
|
+
And the output should contain "hunter2"
|
78
|
+
And the exit status should be 0
|