conjur-cli 4.8.0 → 4.9.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile +1 -8
- data/bin/conjur +1 -0
- data/conjur.gemspec +4 -2
- data/lib/conjur/authn.rb +2 -0
- data/lib/conjur/command/assets.rb +4 -0
- data/lib/conjur/command/dsl_command.rb +1 -0
- data/lib/conjur/command/env.rb +170 -0
- data/lib/conjur/command/field.rb +2 -0
- data/lib/conjur/command/hosts.rb +9 -0
- data/lib/conjur/command/init.rb +31 -12
- data/lib/conjur/command/policy.rb +6 -3
- data/lib/conjur/command/roles.rb +1 -1
- data/lib/conjur/command/secrets.rb +3 -0
- data/lib/conjur/command/variables.rb +1 -0
- data/lib/conjur/config.rb +1 -1
- data/lib/conjur/conjurenv.rb +121 -0
- data/lib/conjur/dsl/runner.rb +5 -0
- data/lib/conjur/version.rb +1 -1
- data/spec/command/env_spec.rb +152 -0
- data/spec/command/init_spec.rb +65 -11
- data/spec/command/policy_spec.rb +24 -5
- data/spec/command/roles_spec.rb +4 -4
- data/spec/command/variables_spec.rb +0 -1
- data/spec/config_spec.rb +21 -0
- data/spec/dsl/runner_spec.rb +13 -4
- data/spec/env_spec.rb +180 -0
- metadata +32 -4
data/lib/conjur/config.rb
CHANGED
@@ -31,7 +31,7 @@ module Conjur
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def default_config_files
|
34
|
-
[ File.join("/etc", "conjur.conf"), ( ENV['CONJURRC'] || File.
|
34
|
+
[ File.join("/etc", "conjur.conf"), ( ENV['CONJURRC'] || File.expand_path("~/.conjurrc") ), '.conjurrc' ]
|
35
35
|
end
|
36
36
|
|
37
37
|
def load(config_files = default_config_files)
|
@@ -0,0 +1,121 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2014 Conjur Inc
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
5
|
+
# this software and associated documentation files (the "Software"), to deal in
|
6
|
+
# the Software without restriction, including without limitation the rights to
|
7
|
+
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
8
|
+
# the Software, and to permit persons to whom the Software is furnished to do so,
|
9
|
+
# subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in all
|
12
|
+
# copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
16
|
+
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
17
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
18
|
+
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
19
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
+
#
|
21
|
+
require 'conjur/api'
|
22
|
+
require 'yaml'
|
23
|
+
|
24
|
+
module Conjur
|
25
|
+
class Env
|
26
|
+
|
27
|
+
class CustomTag
|
28
|
+
def initialize id
|
29
|
+
raise "#{self.class.name.split('::').last} requires a parameter" if id.to_s.empty?
|
30
|
+
@id=id
|
31
|
+
end
|
32
|
+
def init_with(coder)
|
33
|
+
initialize(coder.scalar)
|
34
|
+
end
|
35
|
+
def conjur_id
|
36
|
+
@id
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class ConjurVariable < CustomTag
|
41
|
+
def evaluate value
|
42
|
+
value.chomp
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class ConjurTempfile < CustomTag
|
47
|
+
def evaluate value
|
48
|
+
@tempfile = if File.directory?("/dev/shm") and File.writable?("/dev/shm")
|
49
|
+
Tempfile.new("conjur","/dev/shm")
|
50
|
+
else
|
51
|
+
Tempfile.new("conjur")
|
52
|
+
end
|
53
|
+
@tempfile.write(value)
|
54
|
+
@tempfile.close
|
55
|
+
@tempfile.path
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def initialize(options={})
|
60
|
+
raise ":file and :yaml options can not be provided together" if ( options.has_key?(:file) and options.has_key?(:yaml) )
|
61
|
+
|
62
|
+
yaml = if options.has_key?(:yaml)
|
63
|
+
raise ":yaml option should be non-empty string" unless options[:yaml].kind_of?(String)
|
64
|
+
raise ":yaml option should be non-empty string" if options[:yaml].empty?
|
65
|
+
options[:yaml]
|
66
|
+
elsif options.has_key?(:file)
|
67
|
+
raise ":file option should be non-empty string" unless options[:file].kind_of?(String)
|
68
|
+
raise ":file option should be non-empty string" if options[:file].empty?
|
69
|
+
File.read(options[:file])
|
70
|
+
else
|
71
|
+
raise "either :file or :yaml option is mandatory"
|
72
|
+
end
|
73
|
+
|
74
|
+
@definition = parse(yaml)
|
75
|
+
end
|
76
|
+
|
77
|
+
def parse(yaml)
|
78
|
+
YAML.add_tag("!var", ConjurVariable)
|
79
|
+
YAML.add_tag("!tmp", ConjurTempfile)
|
80
|
+
definition = YAML.load(yaml)
|
81
|
+
raise "Definition should be a Hash" unless definition.kind_of?(Hash)
|
82
|
+
bad_types = definition.values.select { |v| not (v.kind_of?(String) or v.kind_of?(CustomTag)) }.map {|v| v.class}.uniq
|
83
|
+
raise "Definition can not include values of types: #{bad_types}" unless bad_types.empty?
|
84
|
+
definition
|
85
|
+
end
|
86
|
+
|
87
|
+
def obtain(api)
|
88
|
+
runtime_environment={}
|
89
|
+
variable_ids= @definition.values.map { |v| v.conjur_id rescue nil }.compact
|
90
|
+
conjur_values=api.variable_values(variable_ids)
|
91
|
+
@definition.each { |environment_name, reference|
|
92
|
+
runtime_environment[environment_name]= if reference.respond_to?(:evaluate)
|
93
|
+
reference.evaluate( conjur_values[reference.conjur_id] )
|
94
|
+
else
|
95
|
+
reference # is a literal value
|
96
|
+
end
|
97
|
+
}
|
98
|
+
return runtime_environment
|
99
|
+
end
|
100
|
+
|
101
|
+
def check(api)
|
102
|
+
Hash[
|
103
|
+
@definition.map { |k,v|
|
104
|
+
|
105
|
+
status = if v.respond_to? :conjur_id
|
106
|
+
if api.resource("variable:"+v.conjur_id).permitted?(:execute)
|
107
|
+
:available
|
108
|
+
else
|
109
|
+
:unavailable
|
110
|
+
end
|
111
|
+
else
|
112
|
+
:literal
|
113
|
+
end
|
114
|
+
|
115
|
+
[ k, status ]
|
116
|
+
}
|
117
|
+
]
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
data/lib/conjur/dsl/runner.rb
CHANGED
@@ -25,6 +25,11 @@ module Conjur
|
|
25
25
|
@objects = Array.new
|
26
26
|
end
|
27
27
|
|
28
|
+
def owner=(owner)
|
29
|
+
raise "Owner should only be set once" unless @owners.empty?
|
30
|
+
@owners.push owner
|
31
|
+
end
|
32
|
+
|
28
33
|
# Provides a hash to export various application specific
|
29
34
|
# asset ids (or anything else you want)
|
30
35
|
def assets
|
data/lib/conjur/version.rb
CHANGED
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'conjur/conjurenv'
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
|
6
|
+
shared_examples_for "processes environment definition" do |cmd, options|
|
7
|
+
before { # suspend all interaction with the environment
|
8
|
+
Kernel.stub(:system).and_return(true)
|
9
|
+
}
|
10
|
+
let(:stub_object) { double(obtain:{}, check:{}) }
|
11
|
+
|
12
|
+
describe_command "env:#{cmd} #{options}" do
|
13
|
+
it "uses .conjurenv file by default" do
|
14
|
+
Conjur::Env.should_receive(:new).with(file:".conjurenv").and_return(stub_object)
|
15
|
+
invoke
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe_command "env:#{cmd} -c somefile #{options}" do
|
20
|
+
it "uses desired file" do
|
21
|
+
Conjur::Env.should_receive(:new).with(file:"somefile").and_return(stub_object)
|
22
|
+
invoke
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe_command "env:#{cmd} --yaml someyaml #{options}" do
|
27
|
+
it "uses inline yaml" do
|
28
|
+
Conjur::Env.should_receive(:new).with(yaml:"someyaml").and_return(stub_object)
|
29
|
+
invoke
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe_command "env:#{cmd} -c somefile --yaml someyaml #{options}" do
|
34
|
+
it "refuses to accept mutually exclusive options" do
|
35
|
+
Conjur::Env.should_not_receive(:new)
|
36
|
+
expect { invoke }.to raise_error /Options -c and --yaml can not be provided together/
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe Conjur::Command::Env, logged_in: true do
|
42
|
+
|
43
|
+
let(:stub_env) { double() }
|
44
|
+
describe ":check" do
|
45
|
+
it_behaves_like "processes environment definition", "check", ''
|
46
|
+
|
47
|
+
describe_command "env:check" do
|
48
|
+
before { Conjur::Env.should_receive(:new).and_return(stub_env) }
|
49
|
+
describe "without api errors" do
|
50
|
+
let(:stub_result) { { "a" => :available, "b"=> :available } }
|
51
|
+
before {
|
52
|
+
stub_env.should_receive(:check).with(an_instance_of(Conjur::API)).and_return(stub_result)
|
53
|
+
}
|
54
|
+
|
55
|
+
describe "if all variables are available" do
|
56
|
+
it "prints #check result to the output" do
|
57
|
+
expect { invoke }.to write "a: available\nb: available\n"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "does not crash" do
|
61
|
+
expect { invoke }.to_not raise_error
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "if some variables are unavailable" do
|
66
|
+
let(:stub_result) { { "a" => :unavailable, "b"=> :available } }
|
67
|
+
it "prints #check result to the output" do
|
68
|
+
expect { invoke rescue true }.to write "a: unavailable\nb: available\n"
|
69
|
+
end
|
70
|
+
it "crashes in the end" do
|
71
|
+
expect { invoke }.to raise_error "Some variables are not available"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
it 'does not rescue unexpected errors' do
|
76
|
+
stub_env.should_receive(:check).with(an_instance_of(Conjur::API)).and_return { raise "Custom error" }
|
77
|
+
expect { invoke }.to raise_error "Custom error"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe ":run" do
|
83
|
+
it_behaves_like "processes environment definition", "run","-- extcmd"
|
84
|
+
describe_command "env:run" do
|
85
|
+
it 'fails because of missing argument' do
|
86
|
+
Kernel.should_not_receive(:system)
|
87
|
+
expect { invoke }.to raise_error "External command with optional arguments should be provided"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
describe_command "env:run -- extcmd --arg1 arg2" do
|
91
|
+
before {
|
92
|
+
Conjur::Env.should_receive(:new).and_return(stub_env)
|
93
|
+
}
|
94
|
+
|
95
|
+
describe "if no errors are raised" do
|
96
|
+
let(:stub_result) { { "a" => "value_a", "b" => "value_b" } }
|
97
|
+
before {
|
98
|
+
stub_env.should_receive(:obtain).with(an_instance_of(Conjur::API)).and_return(stub_result)
|
99
|
+
}
|
100
|
+
it "performs #exec with environment (names in uppercase)" do
|
101
|
+
Kernel.should_receive(:system).with({"A"=>"value_a", "B"=>"value_b"}, "extcmd", "--arg1","arg2").and_return(true)
|
102
|
+
invoke
|
103
|
+
end
|
104
|
+
end
|
105
|
+
it "does not rescue unexpected errors" do
|
106
|
+
stub_env.should_receive(:obtain).with(an_instance_of(Conjur::API)).and_return { raise "Custom error" }
|
107
|
+
expect { invoke }.to raise_error "Custom error"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe ":template" do
|
113
|
+
context do
|
114
|
+
before { # prevent real operation
|
115
|
+
File.stub(:readable?).with("config.erb").and_return(true)
|
116
|
+
File.stub(:read).with("config.erb").and_return("template")
|
117
|
+
ERB.stub(:new).and_return(double(result:''))
|
118
|
+
Tempfile.stub(:new).and_return(double(write: true, close: true, path: 'somepath'))
|
119
|
+
FileUtils.stub(:copy).and_return(true)
|
120
|
+
}
|
121
|
+
it_behaves_like "processes environment definition", "template","config.erb"
|
122
|
+
end
|
123
|
+
describe_command "env:template" do
|
124
|
+
it 'fails because of missing argument' do
|
125
|
+
Tempfile.should_not_receive(:new)
|
126
|
+
expect { invoke }.to raise_error "Location of readable ERB template should be provided"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
describe_command "env:template config.erb" do
|
130
|
+
let(:erb_template) { """
|
131
|
+
variable <%= conjurenv['a'] %>
|
132
|
+
other variable <%= conjurenv['b'] %>
|
133
|
+
"""
|
134
|
+
}
|
135
|
+
before {
|
136
|
+
File.stub(:readable?).with("config.erb").and_return(true)
|
137
|
+
File.stub(:read).with("config.erb").and_return(erb_template)
|
138
|
+
Conjur::Env.should_receive(:new).and_return(stub_env)
|
139
|
+
stub_env.should_receive(:obtain).with(an_instance_of(Conjur::API)).and_return( {"a"=>"value_a","b"=>"value_b","c"=>"value_c"} )
|
140
|
+
}
|
141
|
+
|
142
|
+
it "creates persistent tempfile, saves rendered template into it, prints out name of the file" do
|
143
|
+
stubpath="/tmp/temp.file"
|
144
|
+
tempfile=double(close: true, path: stubpath)
|
145
|
+
Tempfile.should_receive(:new).and_return(tempfile)
|
146
|
+
tempfile.should_receive(:write).with("\nvariable value_a\nother variable value_b\n")
|
147
|
+
FileUtils.should_receive(:copy).with(stubpath,stubpath+'.saved') # avoid garbage collection
|
148
|
+
expect { invoke }.to write stubpath+".saved"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
data/spec/command/init_spec.rb
CHANGED
@@ -2,7 +2,57 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
tmpdir = Dir.mktmpdir
|
4
4
|
|
5
|
+
GITHUB_FP = "SHA1 Fingerprint=A0:C4:A7:46:00:ED:A7:2D:C0:BE:CB:9A:8C:B6:07:CA:58:EE:74:5E"
|
6
|
+
GITHUB_CERT = <<EOF
|
7
|
+
-----BEGIN CERTIFICATE-----
|
8
|
+
MIIF4DCCBMigAwIBAgIQDACTENIG2+M3VTWAEY3chzANBgkqhkiG9w0BAQsFADB1
|
9
|
+
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
10
|
+
d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVk
|
11
|
+
IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE0MDQwODAwMDAwMFoXDTE2MDQxMjEy
|
12
|
+
MDAwMFowgfAxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYB
|
13
|
+
BAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQITCERlbGF3YXJlMRAwDgYDVQQF
|
14
|
+
Ewc1MTU3NTUwMRcwFQYDVQQJEw41NDggNHRoIFN0cmVldDEOMAwGA1UEERMFOTQx
|
15
|
+
MDcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T
|
16
|
+
YW4gRnJhbmNpc2NvMRUwEwYDVQQKEwxHaXRIdWIsIEluYy4xEzARBgNVBAMTCmdp
|
17
|
+
dGh1Yi5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx1Nw8r/3z
|
18
|
+
Tu3BZ63myyLot+KrKPL33GJwCNEMr9YWaiGwNksXDTZjBK6/6iBRlWVm8r+5TaQM
|
19
|
+
Kev1FbHoNbNwEJTVG1m0Jg/Wg1dZneF8Cd3gE8pNb0Obzc+HOhWnhd1mg+2TDP4r
|
20
|
+
bTgceYiQz61YGC1R0cKj8keMbzgJubjvTJMLy4OUh+rgo7XZe5trD0P5yu6ADSin
|
21
|
+
dvEl9ME1PPZ0rd5qM4J73P1LdqfC7vJqv6kkpl/nLnwO28N0c/p+xtjPYOs2ViG2
|
22
|
+
wYq4JIJNeCS66R2hiqeHvmYlab++O3JuT+DkhSUIsZGJuNZ0ZXabLE9iH6H6Or6c
|
23
|
+
JL+fyrDFwGeNAgMBAAGjggHuMIIB6jAfBgNVHSMEGDAWgBQ901Cl1qCt7vNKYApl
|
24
|
+
0yHU+PjWDzAdBgNVHQ4EFgQUakOQfTuYFHJSlTqqKApD+FF+06YwJQYDVR0RBB4w
|
25
|
+
HIIKZ2l0aHViLmNvbYIOd3d3LmdpdGh1Yi5jb20wDgYDVR0PAQH/BAQDAgWgMB0G
|
26
|
+
A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB1BgNVHR8EbjBsMDSgMqAwhi5o
|
27
|
+
dHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1ldi1zZXJ2ZXItZzEuY3JsMDSg
|
28
|
+
MqAwhi5odHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1ldi1zZXJ2ZXItZzEu
|
29
|
+
Y3JsMEIGA1UdIAQ7MDkwNwYJYIZIAYb9bAIBMCowKAYIKwYBBQUHAgEWHGh0dHBz
|
30
|
+
Oi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgYgGCCsGAQUFBwEBBHwwejAkBggrBgEF
|
31
|
+
BQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMFIGCCsGAQUFBzAChkZodHRw
|
32
|
+
Oi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEyRXh0ZW5kZWRWYWxp
|
33
|
+
ZGF0aW9uU2VydmVyQ0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQAD
|
34
|
+
ggEBAG/nbcuC8++QhwnXDxUiLIz+06scipbbXRJd0XjAMbD/RciJ9wiYUhcfTEsg
|
35
|
+
ZGpt21DXEL5+q/4vgNipSlhBaYFyGQiDm5IQTmIte0ZwQ26jUxMf4pOmI1v3kj43
|
36
|
+
FHU7uUskQS6lPUgND5nqHkKXxv6V2qtHmssrA9YNQMEK93ga2rWDpK21mUkgLviT
|
37
|
+
PB5sPdE7IzprOCp+Ynpf3RcFddAkXb6NqJoQRPrStMrv19C1dqUmJRwIQdhkkqev
|
38
|
+
ff6IQDlhC8BIMKmCNK33cEYDfDWROtW7JNgBvBTwww8jO1gyug8SbGZ6bZ3k8OV8
|
39
|
+
XX4C2NesiZcLYbc2n7B9O+63M2k=
|
40
|
+
-----END CERTIFICATE-----
|
41
|
+
EOF
|
42
|
+
|
5
43
|
describe Conjur::Command::Init do
|
44
|
+
it "properly defaults to a file path" do
|
45
|
+
expect(Conjur::CLI.commands[:init].flags[:f].default_value).to eq("#{ENV['HOME']}/.conjurrc")
|
46
|
+
end
|
47
|
+
|
48
|
+
describe ".get_certificate" do
|
49
|
+
it "returns the right certificate from github" do
|
50
|
+
fingerprint, certificate = Conjur::Command::Init.get_certificate('github.com:443')
|
51
|
+
expect(fingerprint).to eq(GITHUB_FP)
|
52
|
+
expect(certificate.strip).to eq(GITHUB_CERT.strip)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
6
56
|
context logged_in: false do
|
7
57
|
before {
|
8
58
|
File.stub(:exists?).and_return false
|
@@ -10,7 +60,7 @@ describe Conjur::Command::Init do
|
|
10
60
|
context "auto-fetching fingerprint" do
|
11
61
|
before {
|
12
62
|
HighLine.any_instance.stub(:ask).with("Enter the hostname (and optional port) of your Conjur endpoint: ").and_return "the-host"
|
13
|
-
|
63
|
+
Conjur::Command::Init.stub get_certificate: ["the-fingerprint", nil]
|
14
64
|
HighLine.any_instance.stub(:ask).with(/^Trust this certificate/).and_return "yes"
|
15
65
|
}
|
16
66
|
describe_command 'init' do
|
@@ -40,6 +90,13 @@ describe Conjur::Command::Init do
|
|
40
90
|
invoke
|
41
91
|
end
|
42
92
|
end
|
93
|
+
describe_command 'init -a the-account -h https://google.com' do
|
94
|
+
it "writes the config and cert" do
|
95
|
+
HighLine.any_instance.stub(:ask).and_return "yes"
|
96
|
+
File.should_receive(:open).twice
|
97
|
+
invoke
|
98
|
+
end
|
99
|
+
end
|
43
100
|
describe_command 'init -a the-account -h localhost -c the-cert' do
|
44
101
|
it "writes config and cert files" do
|
45
102
|
File.should_receive(:open).twice
|
@@ -51,16 +108,13 @@ describe Conjur::Command::Init do
|
|
51
108
|
it "writes config and cert files" do
|
52
109
|
invoke
|
53
110
|
|
54
|
-
File.read(File.join(tmpdir, ".conjurrc")).
|
55
|
-
account: the-account
|
56
|
-
plugins:
|
57
|
-
|
58
|
-
-
|
59
|
-
|
60
|
-
|
61
|
-
appliance_url: https://localhost/api
|
62
|
-
cert_file: #{tmpdir}/conjur-the-account.pem
|
63
|
-
"""
|
111
|
+
expect(YAML.load(File.read(File.join(tmpdir, ".conjurrc")))).to eq({
|
112
|
+
account: 'the-account',
|
113
|
+
plugins: %w(environment layer key-pair pubkeys),
|
114
|
+
appliance_url: "https://localhost/api",
|
115
|
+
cert_file: "#{tmpdir}/conjur-the-account.pem"
|
116
|
+
}.stringify_keys)
|
117
|
+
|
64
118
|
File.read(File.join(tmpdir, "conjur-the-account.pem")).should == "the-cert\n"
|
65
119
|
end
|
66
120
|
end
|
data/spec/command/policy_spec.rb
CHANGED
@@ -2,6 +2,18 @@ require 'spec_helper'
|
|
2
2
|
require 'conjur/dsl/runner'
|
3
3
|
|
4
4
|
describe Conjur::Command::Policy do
|
5
|
+
describe ".default_collection_user" do
|
6
|
+
it "returns the current username" do
|
7
|
+
expect(Conjur::Command::Policy.default_collection_user).to eq(`whoami`.strip)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe ".default_collection_hostname" do
|
12
|
+
it "returns the current hostname" do
|
13
|
+
expect(Conjur::Command::Policy.default_collection_hostname).to eq(`hostname`.strip)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
5
17
|
context logged_in: true do
|
6
18
|
let(:role) do
|
7
19
|
double("role", exists?: true, api_key: "the-api-key", roleid: "the-role")
|
@@ -9,17 +21,15 @@ describe Conjur::Command::Policy do
|
|
9
21
|
let(:resource) do
|
10
22
|
double("resource", exists?: true).as_null_object
|
11
23
|
end
|
12
|
-
let(:name) { nil }
|
13
24
|
before {
|
14
25
|
File.stub(:read).with("policy-body").and_return "{}"
|
15
26
|
Conjur::DSL::Runner.any_instance.stub(:api).and_return api
|
16
27
|
}
|
17
28
|
before {
|
29
|
+
api.stub(:role).and_call_original
|
30
|
+
api.stub(:resource).and_call_original
|
18
31
|
api.stub(:role).with("the-account:policy:#{collection}/the-policy-1.0.0").and_return role
|
19
32
|
api.stub(:resource).with("the-account:policy:#{collection}/the-policy-1.0.0").and_return resource
|
20
|
-
if name
|
21
|
-
resource.should_receive(:[]).with(:name, name)
|
22
|
-
end
|
23
33
|
}
|
24
34
|
|
25
35
|
describe_command 'policy:load --collection the-collection policy-body' do
|
@@ -33,6 +43,15 @@ describe Conjur::Command::Policy do
|
|
33
43
|
before {
|
34
44
|
stub_const("ENV", "USER" => "alice", "HOSTNAME" => "localhost")
|
35
45
|
}
|
46
|
+
describe_command 'policy:load --as-group the-group policy-body' do
|
47
|
+
let(:group) { double(:group, exists?: true) }
|
48
|
+
it "creates the policy" do
|
49
|
+
Conjur::Command.api.stub(:role).with("the-account:group:the-group").and_return group
|
50
|
+
Conjur::DSL::Runner.any_instance.should_receive(:owner=).with("the-account:group:the-group")
|
51
|
+
|
52
|
+
invoke.should == 0
|
53
|
+
end
|
54
|
+
end
|
36
55
|
describe_command 'policy:load policy-body' do
|
37
56
|
it "creates the policy with default collection" do
|
38
57
|
invoke.should == 0
|
@@ -40,4 +59,4 @@ describe Conjur::Command::Policy do
|
|
40
59
|
end
|
41
60
|
end
|
42
61
|
end
|
43
|
-
end
|
62
|
+
end
|