conjur-cli 5.6.6 → 6.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.dockerignore +1 -1
- data/.gitignore +2 -0
- data/.rubocop.yml +1 -1
- data/APPLIANCE_VERSION +1 -1
- data/CHANGELOG.md +3 -42
- data/Gemfile +4 -7
- data/Humanfile.md +31 -0
- data/Jenkinsfile +34 -63
- data/README.md +41 -55
- data/Rakefile +5 -1
- data/bin/conjur +0 -2
- data/build-deb.sh +1 -3
- data/ci/cli-test.sh +6 -0
- data/ci/package.sh +3 -1
- data/ci/publish.sh +2 -2
- data/ci/secrets/publish.yml +2 -2
- data/ci/wait_for_server.sh +10 -0
- data/conjur-cli.gemspec +7 -7
- data/dev/docker-compose.yml +24 -0
- data/dev/start.sh +15 -0
- data/dev/stop.sh +5 -0
- data/docker-compose.yml +30 -0
- data/features/authentication/authenticate.feature +34 -0
- data/features/authentication/login.feature +13 -0
- data/features/authentication/logout.feature +15 -0
- data/{acceptance-features → features}/authentication/whoami.feature +0 -0
- data/features/authorization/resource/annotate.feature +22 -0
- data/features/authorization/resource/check.feature +47 -0
- data/{acceptance-features → features}/authorization/resource/exists.feature +18 -6
- data/features/authorization/resource/permitted_roles.feature +35 -0
- data/features/authorization/resource/show.feature +34 -0
- data/features/authorization/role/exists.feature +28 -0
- data/features/authorization/role/members.feature +45 -0
- data/features/authorization/role/memberships.feature +43 -0
- data/features/conjurenv/check.feature +34 -0
- data/features/conjurenv/run.feature +15 -0
- data/{acceptance-features → features}/conjurenv/template.feature +8 -3
- data/{acceptance-features → features}/directory/user/update_password.feature +8 -2
- data/{acceptance-features → features}/directory/variable/value.feature +9 -5
- data/{acceptance-features → features}/directory/variable/values-add.feature +8 -3
- data/features/hostfactory/tokens.feature +22 -0
- data/features/pubkeys/show.feature +18 -0
- data/features/step_definitions/authn_steps.rb +22 -0
- data/features/step_definitions/cli_steps.rb +28 -0
- data/features/step_definitions/file_steps.rb +12 -0
- data/features/step_definitions/flow_control_steps.rb +7 -0
- data/features/step_definitions/graph_steps.rb +4 -3
- data/{acceptance-features → features}/step_definitions/http_steps.rb +0 -0
- data/features/step_definitions/overrides.rb +9 -0
- data/features/step_definitions/policy_steps.rb +11 -0
- data/{acceptance-features → features}/step_definitions/trusted_proxy_steps.rb +0 -0
- data/features/support/blank.yml +1 -0
- data/features/support/env.rb +21 -7
- data/features/support/hooks.rb +31 -116
- data/features/support/world.rb +16 -76
- data/jenkins.sh +33 -0
- data/lib/conjur/authenticator.rb +83 -0
- data/lib/conjur/authn.rb +5 -20
- data/lib/conjur/cli.rb +13 -6
- data/lib/conjur/command.rb +30 -350
- data/lib/conjur/command/authn.rb +23 -15
- data/lib/conjur/command/host_factories.rb +2 -74
- data/lib/conjur/command/hosts.rb +6 -113
- data/lib/conjur/command/init.rb +20 -35
- data/lib/conjur/command/{secrets.rb → policies.rb} +33 -22
- data/lib/conjur/command/pubkeys.rb +3 -63
- data/lib/conjur/command/resources.rb +45 -162
- data/lib/conjur/command/roles.rb +11 -181
- data/lib/conjur/command/rspec/helpers.rb +0 -1
- data/lib/conjur/command/rspec/mock_services.rb +4 -4
- data/lib/conjur/command/users.rb +2 -159
- data/lib/conjur/command/variables.rb +5 -218
- data/lib/conjur/complete.rb +2 -2
- data/lib/conjur/config.rb +1 -11
- data/lib/conjur/conjurenv.rb +12 -9
- data/lib/conjur/identifier_manipulation.rb +3 -5
- data/lib/conjur/version.rb +2 -2
- data/{publish-rubygem.sh → publish.sh} +0 -4
- data/spec/authn_spec.rb +4 -0
- data/spec/command/hosts_spec.rb +2 -69
- data/spec/command/init_spec.rb +16 -11
- data/spec/command/pubkeys_spec.rb +1 -46
- data/spec/command/resources_spec.rb +21 -170
- data/spec/command/roles_spec.rb +5 -181
- data/spec/command/users_spec.rb +3 -79
- data/spec/command_spec.rb +1 -20
- data/spec/complete_spec.rb +1 -23
- data/spec/config_spec.rb +1 -1
- data/spec/spec_helper.rb +4 -5
- data/test.sh +29 -25
- metadata +92 -212
- data/.githooks/pre_commit/run_specs.rb +0 -23
- data/Dockerfile +0 -15
- data/Dockerfile.fpm +0 -18
- data/Dockerfile.publish +0 -12
- data/Dockerfile.standalone +0 -33
- data/Dockerfile.validate-packaging +0 -9
- data/VERSION +0 -1
- data/acceptance-features/audit/audit_event_send.feature +0 -107
- data/acceptance-features/audit/fetch.feature +0 -16
- data/acceptance-features/audit/send.feature +0 -51
- data/acceptance-features/authentication/authenticate.feature +0 -10
- data/acceptance-features/authentication/login.feature +0 -12
- data/acceptance-features/authentication/logout.feature +0 -13
- data/acceptance-features/authorization/resource/annotate.feature +0 -35
- data/acceptance-features/authorization/resource/check.feature +0 -24
- data/acceptance-features/authorization/resource/create.feature +0 -21
- data/acceptance-features/authorization/resource/deny.feature +0 -12
- data/acceptance-features/authorization/resource/give.feature +0 -24
- data/acceptance-features/authorization/resource/permit.feature +0 -20
- data/acceptance-features/authorization/resource/permitted_roles.feature +0 -16
- data/acceptance-features/authorization/resource/show.feature +0 -28
- data/acceptance-features/authorization/role/create.feature +0 -13
- data/acceptance-features/authorization/role/exists.feature +0 -19
- data/acceptance-features/authorization/role/grant_to.feature +0 -21
- data/acceptance-features/authorization/role/graph.feature +0 -57
- data/acceptance-features/authorization/role/members.feature +0 -23
- data/acceptance-features/authorization/role/memberships.feature +0 -27
- data/acceptance-features/bootstrap.feature +0 -13
- data/acceptance-features/conjurenv/check.feature +0 -21
- data/acceptance-features/conjurenv/run.feature +0 -10
- data/acceptance-features/directory/group/create.feature +0 -20
- data/acceptance-features/directory/group/retire.feature +0 -54
- data/acceptance-features/directory/host/create.feature +0 -23
- data/acceptance-features/directory/host/retire.feature +0 -6
- data/acceptance-features/directory/hostfactory/create.feature +0 -28
- data/acceptance-features/directory/hostfactory/tokens.feature +0 -16
- data/acceptance-features/directory/layer/create.feature +0 -10
- data/acceptance-features/directory/layer/hosts-add.feature +0 -9
- data/acceptance-features/directory/layer/hosts-remove.feature +0 -10
- data/acceptance-features/directory/layer/retire.feature +0 -43
- data/acceptance-features/directory/user/create.feature +0 -23
- data/acceptance-features/directory/user/retire.feature +0 -6
- data/acceptance-features/directory/variable/create.feature +0 -14
- data/acceptance-features/directory/variable/retire.feature +0 -17
- data/acceptance-features/dsl/policy_owner.feature +0 -45
- data/acceptance-features/dsl/resource_owner.feature +0 -17
- data/acceptance-features/dsl/retire.feature +0 -15
- data/acceptance-features/global-privilege/elevate.feature +0 -20
- data/acceptance-features/global-privilege/reveal.privilege +0 -20
- data/acceptance-features/pubkeys/add.feature +0 -22
- data/acceptance-features/pubkeys/delete.feature +0 -9
- data/acceptance-features/pubkeys/names.feature +0 -26
- data/acceptance-features/pubkeys/show.feature +0 -27
- data/acceptance-features/step_definitions/cli_steps.rb +0 -57
- data/acceptance-features/step_definitions/graph_steps.rb +0 -22
- data/acceptance-features/step_definitions/user_steps.rb +0 -51
- data/acceptance-features/support/env.rb +0 -23
- data/acceptance-features/support/hooks.rb +0 -178
- data/acceptance-features/support/world.rb +0 -176
- data/acceptance-features/trusted_proxies.feature +0 -82
- data/bin/conjurize +0 -26
- data/bin/jsonfield +0 -70
- data/build-standalone +0 -6
- data/deprecations.sh +0 -38
- data/features/conjurize.feature +0 -134
- data/features/dsl_context.feature +0 -36
- data/features/dsl_host_create.feature +0 -11
- data/features/dsl_ownership.feature +0 -30
- data/features/dsl_permission.feature +0 -45
- data/features/dsl_resource_create.feature +0 -23
- data/features/dsl_role_create.feature +0 -11
- data/features/dsl_user_create.feature +0 -23
- data/features/jsonfield.feature +0 -49
- data/features/role_graph.feature +0 -58
- data/features/step_definitions/conjurize_steps.rb +0 -5
- data/features/step_definitions/dsl_steps.rb +0 -52
- data/features/support/conjur.conf +0 -6
- data/lib/conjur/command/assets.rb +0 -121
- data/lib/conjur/command/audit.rb +0 -155
- data/lib/conjur/command/bootstrap.rb +0 -129
- data/lib/conjur/command/dsl_command.rb +0 -75
- data/lib/conjur/command/elevate.rb +0 -76
- data/lib/conjur/command/field.rb +0 -45
- data/lib/conjur/command/groups.rb +0 -208
- data/lib/conjur/command/ids.rb +0 -34
- data/lib/conjur/command/layers.rb +0 -211
- data/lib/conjur/command/ldapsync.rb +0 -118
- data/lib/conjur/command/rspec/audit_helpers.rb +0 -68
- data/lib/conjur/command/rubydsl.rb +0 -93
- data/lib/conjur/command/script.rb +0 -48
- data/lib/conjur/command/server.rb +0 -67
- data/lib/conjur/conjurize.rb +0 -71
- data/lib/conjur/conjurize/script.rb +0 -150
- data/lib/conjur/dsl/runner.rb +0 -273
- data/publish-deb.sh +0 -6
- data/push-image +0 -29
- data/spec/command/assets_spec.rb +0 -115
- data/spec/command/audit_spec.rb +0 -376
- data/spec/command/elevate_spec.rb +0 -28
- data/spec/command/env_spec.rb +0 -168
- data/spec/command/groups_spec.rb +0 -77
- data/spec/command/host_factories_spec.rb +0 -38
- data/spec/command/layers_spec.rb +0 -35
- data/spec/command/ldapsync_spec.rb +0 -28
- data/spec/command/rubydsl_spec.rb +0 -63
- data/spec/command/variable_expiration_spec.rb +0 -164
- data/spec/command/variables_spec.rb +0 -192
- data/spec/conjurize/script_spec.rb +0 -62
- data/spec/conjurize_spec.rb +0 -70
- data/spec/dsl/runner_spec.rb +0 -93
- data/spec/env_spec.rb +0 -214
@@ -1,192 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Conjur::Command::Variables, logged_in: true do
|
4
|
-
let(:host) { 'https://core.example.com/api' }
|
5
|
-
let(:collection_url) { "#{host}/variables" }
|
6
|
-
let(:mime_type) { 'text/plain' }
|
7
|
-
let(:kind) { 'secret' }
|
8
|
-
let(:base_payload) do
|
9
|
-
{ id: id, value: value, mime_type: mime_type, kind: kind }.tap do |t|
|
10
|
-
group && t.merge(ownerid: group)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
let(:id) { 'the-id' }
|
14
|
-
let(:variable) { post_response(id) }
|
15
|
-
let(:group) { nil }
|
16
|
-
let(:annotation) { {} }
|
17
|
-
let(:value) { 'the-value' }
|
18
|
-
let(:full_payload) { base_payload }
|
19
|
-
|
20
|
-
context 'when there are command-line errors' do
|
21
|
-
describe_command "variable:create -v the-value-1 the-id the-value-2" do
|
22
|
-
it "complains about conflicting values" do
|
23
|
-
expect { invoke }.to raise_error("Received conflicting value arguments")
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
context "-a without -i" do
|
29
|
-
describe_command 'variable:create -a the-id' do
|
30
|
-
it "is an error" do
|
31
|
-
expect { invoke }.to raise_error("Received --annotate option without --interactive")
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
context 'non-interactive' do
|
37
|
-
describe_command "variable:create the-id" do
|
38
|
-
it "is non-interactive" do
|
39
|
-
allow(Conjur::Command::Variables).to receive(:prompt_for_id).and_raise("Unexpected prompt for id")
|
40
|
-
expect(RestClient::Request).to receive(:execute).and_return(variable)
|
41
|
-
invoke
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
context 'when there are no command-line errors' do
|
47
|
-
before do
|
48
|
-
allow(Conjur::Command::Variables).to receive(:prompt_to_confirm) { "yes"}
|
49
|
-
allow(Conjur::Command::Variables).to receive(:prompt_for_id) { id }
|
50
|
-
allow(Conjur::Command::Variables).to receive(:prompt_for_group) { group }
|
51
|
-
allow(Conjur::Command::Variables).to receive(:prompt_for_kind) { kind }
|
52
|
-
allow(Conjur::Command::Variables).to receive(:prompt_for_mime_type) { mime_type }
|
53
|
-
allow(Conjur::Command::Variables).to receive(:prompt_for_annotations) { annotation }
|
54
|
-
allow(Conjur::Command::Variables).to receive(:prompt_for_value) { value }
|
55
|
-
|
56
|
-
expect(RestClient::Request).to receive(:execute).with({
|
57
|
-
method: :post,
|
58
|
-
url: collection_url,
|
59
|
-
headers: {},
|
60
|
-
payload: full_payload
|
61
|
-
}).and_return(variable)
|
62
|
-
end
|
63
|
-
|
64
|
-
describe_command "variable:create the-id the-different-value" do
|
65
|
-
let (:value) { 'the-different-value' }
|
66
|
-
it "propagates the user-assigned id" do
|
67
|
-
expect { invoke }.to write({ id: 'the-id' }).to(:stdout)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
describe_command "variable:create the-id" do
|
72
|
-
let(:value) { "" }
|
73
|
-
let(:full_payload) {
|
74
|
-
base_payload.dup.tap do |m|
|
75
|
-
m.delete_if{|k,_| k == :value}
|
76
|
-
end
|
77
|
-
}
|
78
|
-
it "will propagate the user-assigned id without a value" do
|
79
|
-
expect { invoke }.to write({ id: 'the-id' }).to(:stdout)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
let(:base_payload) do
|
84
|
-
{ id: id, value: value, mime_type: mime_type, kind: kind }.tap do |t|
|
85
|
-
group && t.merge(ownerid: group)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
describe_command "variable:create -m application/json" do
|
90
|
-
let(:mime_type) { 'application/json' }
|
91
|
-
let(:payload) { valueless_payload }
|
92
|
-
it "propagates the user-assigned MIME type" do
|
93
|
-
expect { invoke }.to write({ id: 'the-id' }).to(:stdout)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
describe_command "variable:create -k password" do
|
98
|
-
let(:kind) { 'password' }
|
99
|
-
let(:payload) { valueless_payload }
|
100
|
-
it "propagates the user-assigned kind" do
|
101
|
-
expect { invoke }.to write({ id: 'the-id' }).to(:stdout)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
describe "in interactive mode" do
|
106
|
-
after do
|
107
|
-
expect { invoke }.to write({ id: 'the-id' }).to(:stdout)
|
108
|
-
end
|
109
|
-
|
110
|
-
subject { Conjur::Command::Variables }
|
111
|
-
|
112
|
-
context "when -i is omitted" do
|
113
|
-
describe_command 'variable:create' do
|
114
|
-
it { is_expected.to receive(:prompt_for_id) }
|
115
|
-
it { is_expected.to receive(:prompt_for_group) }
|
116
|
-
it { is_expected.to receive(:prompt_for_kind) }
|
117
|
-
it { is_expected.to receive(:prompt_for_mime_type) }
|
118
|
-
it { is_expected.not_to receive(:prompt_for_annotations) }
|
119
|
-
it { is_expected.to receive(:prompt_for_value) }
|
120
|
-
end
|
121
|
-
|
122
|
-
describe_command 'variable:create the-id the-value' do
|
123
|
-
it { is_expected.not_to receive(:prompt_for_id) }
|
124
|
-
it { is_expected.not_to receive(:prompt_for_value) }
|
125
|
-
end
|
126
|
-
|
127
|
-
describe_command 'variable:create -m application/json' do
|
128
|
-
let(:mime_type) { 'application/json' }
|
129
|
-
it { is_expected.not_to receive(:prompt_for_mime_type) }
|
130
|
-
end
|
131
|
-
|
132
|
-
describe_command 'variable:create -k password' do
|
133
|
-
let(:kind) { 'password' }
|
134
|
-
it { is_expected.not_to receive(:prompt_for_kind) }
|
135
|
-
end
|
136
|
-
|
137
|
-
describe_command 'variable:create -v the-value' do
|
138
|
-
it { is_expected.not_to receive(:prompt_for_value) }
|
139
|
-
end
|
140
|
-
|
141
|
-
describe_command 'variable:create --as-group the-group' do
|
142
|
-
before do
|
143
|
-
allow(RestClient::Request).to receive(:execute).with({
|
144
|
-
method: :head,
|
145
|
-
url: 'https://authz.example.com/the-account/roles/group/the-group',
|
146
|
-
headers: {}
|
147
|
-
}).and_return(OpenStruct.new(headers: {}, body: '{}'))
|
148
|
-
end
|
149
|
-
|
150
|
-
let(:full_payload) { base_payload.merge(ownerid: 'the-account:group:the-group') }
|
151
|
-
|
152
|
-
it { is_expected.not_to receive(:prompt_for_group) }
|
153
|
-
end
|
154
|
-
|
155
|
-
describe_command 'variable:create --as-role the-account:group:the-group' do
|
156
|
-
before do
|
157
|
-
allow(RestClient::Request).to receive(:execute).with({
|
158
|
-
method: :head,
|
159
|
-
url: 'https://authz.example.com/the-account/roles/group/the-group',
|
160
|
-
headers: {}
|
161
|
-
}).and_return(OpenStruct.new(headers: {}, body: '{}'))
|
162
|
-
end
|
163
|
-
|
164
|
-
let(:full_payload) { base_payload.merge(ownerid: 'the-account:group:the-group') }
|
165
|
-
|
166
|
-
it { is_expected.not_to receive(:prompt_for_group) }
|
167
|
-
end
|
168
|
-
|
169
|
-
end
|
170
|
-
|
171
|
-
context "explicit interactivity" do
|
172
|
-
describe_command 'variable:create -i the-id the-value' do
|
173
|
-
it { is_expected.not_to receive(:prompt_for_id) }
|
174
|
-
it { is_expected.not_to receive(:prompt_for_value) }
|
175
|
-
it { is_expected.to receive(:prompt_for_group) }
|
176
|
-
it { is_expected.to receive(:prompt_for_mime_type) }
|
177
|
-
it { is_expected.to receive(:prompt_for_kind) }
|
178
|
-
it { is_expected.not_to receive(:prompt_for_annotations) }
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
context "interactive annotations" do
|
183
|
-
describe_command 'variable:create -a' do
|
184
|
-
it { is_expected.to receive(:prompt_for_annotations) }
|
185
|
-
end
|
186
|
-
describe_command 'variable:create -ia the-id' do
|
187
|
-
it { is_expected.to receive(:prompt_for_annotations) }
|
188
|
-
end
|
189
|
-
end
|
190
|
-
end
|
191
|
-
end
|
192
|
-
end
|
@@ -1,62 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
require "conjur/conjurize/script"
|
3
|
-
|
4
|
-
describe Conjur::Conjurize::Script do
|
5
|
-
describe ".latest_conjur_cookbook_release" do
|
6
|
-
let(:releases_json) do
|
7
|
-
%([
|
8
|
-
{
|
9
|
-
"name": "v0.4.0",
|
10
|
-
"assets": [{
|
11
|
-
"name": "conjur-v0.4.0.tar.gz",
|
12
|
-
"browser_download_url": "http://example.com/conjur-v0.4.0.tar.gz"
|
13
|
-
}]
|
14
|
-
},
|
15
|
-
{
|
16
|
-
"name": "v0.3.0",
|
17
|
-
"assets": [{
|
18
|
-
"name": "conjur-v0.3.0.tar.gz",
|
19
|
-
"browser_download_url": "http://example.com/conjur-v0.3.0.tar.gz"
|
20
|
-
}]
|
21
|
-
}
|
22
|
-
])
|
23
|
-
end
|
24
|
-
|
25
|
-
before do
|
26
|
-
allow(Conjur::Conjurize::Script).to receive(:open)\
|
27
|
-
.with("https://api.github.com/repos/conjur-cookbooks/conjur/releases")\
|
28
|
-
.and_return double(read: releases_json)
|
29
|
-
end
|
30
|
-
|
31
|
-
it "looks up the latest release download url" do
|
32
|
-
expect(Conjur::Conjurize::Script.latest_conjur_cookbook_release).to \
|
33
|
-
eq "http://example.com/conjur-v0.4.0.tar.gz"
|
34
|
-
end
|
35
|
-
|
36
|
-
context "with latest release is without any tarballs" do
|
37
|
-
let(:releases_json) do
|
38
|
-
%([
|
39
|
-
{
|
40
|
-
"name": "v0.4.0",
|
41
|
-
"assets": []
|
42
|
-
},
|
43
|
-
{
|
44
|
-
"name": "v0.3.0",
|
45
|
-
"assets": [{
|
46
|
-
"name": "conjur-v0.3.0.tar.gz",
|
47
|
-
"browser_download_url": "http://example.com/conjur-v0.3.0.tar.gz"
|
48
|
-
}]
|
49
|
-
}
|
50
|
-
])
|
51
|
-
end
|
52
|
-
|
53
|
-
it "returns the previous one and warns" do
|
54
|
-
err = $stderr.grab do
|
55
|
-
expect(Conjur::Conjurize::Script.latest_conjur_cookbook_release).to \
|
56
|
-
eq "http://example.com/conjur-v0.3.0.tar.gz"
|
57
|
-
end
|
58
|
-
expect(err).to include "WARNING"
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
data/spec/conjurize_spec.rb
DELETED
@@ -1,70 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
require "conjur/conjurize"
|
3
|
-
|
4
|
-
describe Conjur::Conjurize do
|
5
|
-
let(:certificate) do
|
6
|
-
OpenSSL::X509::Certificate.new.tap do |cert|
|
7
|
-
key = OpenSSL::PKey::RSA.new 512
|
8
|
-
cert.public_key = key.public_key
|
9
|
-
cert.not_before = Time.now
|
10
|
-
cert.not_after = 1.minute.from_now
|
11
|
-
cert.sign key, OpenSSL::Digest::SHA256.new
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
let(:certfile) do
|
16
|
-
Tempfile.new("cert").tap do |file|
|
17
|
-
file.write certificate.to_pem
|
18
|
-
file.close
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
let(:host_id) { "somehostid" }
|
23
|
-
let(:api_key) { "very_secret_key" }
|
24
|
-
let(:account) { "testacct" }
|
25
|
-
let(:appliance_url) { "https://example.com" }
|
26
|
-
|
27
|
-
before do
|
28
|
-
allow(Conjur.config).to receive_messages \
|
29
|
-
account: account,
|
30
|
-
cert_file: certfile.path,
|
31
|
-
appliance_url: appliance_url
|
32
|
-
end
|
33
|
-
|
34
|
-
describe ".generate" do
|
35
|
-
it "puts all the relevant data in the script" do
|
36
|
-
script = Conjur::Conjurize.generate "id" => host_id, "api_key" => api_key
|
37
|
-
expect(script).to include host_id, api_key, account, certificate.to_pem
|
38
|
-
end
|
39
|
-
|
40
|
-
it "dumps JSON if required" do
|
41
|
-
allow(Conjur::Conjurize).to receive_messages options: { json: true }
|
42
|
-
expect(
|
43
|
-
JSON.load(
|
44
|
-
Conjur::Conjurize.generate(
|
45
|
-
"id" => host_id,
|
46
|
-
"api_key" => api_key
|
47
|
-
)
|
48
|
-
)
|
49
|
-
).to eq \
|
50
|
-
"id" => host_id,
|
51
|
-
"api_key" => api_key,
|
52
|
-
"account" => account,
|
53
|
-
"certificate" => certificate.to_pem.strip,
|
54
|
-
"appliance_url" => appliance_url
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
describe ".configuration" do
|
59
|
-
it "gathers all the configuration options" do
|
60
|
-
expect(
|
61
|
-
Conjur::Conjurize.configuration("id" => host_id, "api_key" => api_key)
|
62
|
-
).to eq \
|
63
|
-
"id" => host_id,
|
64
|
-
"api_key" => api_key,
|
65
|
-
"account" => account,
|
66
|
-
"certificate" => certificate.to_pem.strip,
|
67
|
-
"appliance_url" => appliance_url
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
data/spec/dsl/runner_spec.rb
DELETED
@@ -1,93 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'conjur/dsl/runner'
|
3
|
-
|
4
|
-
describe Conjur::DSL::Runner, logged_in: true do
|
5
|
-
include_context "fresh config"
|
6
|
-
|
7
|
-
let(:filename) { nil }
|
8
|
-
let(:runner) { Conjur::DSL::Runner.new script, filename }
|
9
|
-
before {
|
10
|
-
allow(Conjur).to receive(:account).and_return "the-account"
|
11
|
-
allow(runner).to receive(:api).and_return api
|
12
|
-
}
|
13
|
-
context "nil record ids" do
|
14
|
-
subject { runner.execute }
|
15
|
-
context "creating a user" do
|
16
|
-
let(:script) { "user" }
|
17
|
-
it "isn't allowed" do
|
18
|
-
expect{ subject }.to raise_error
|
19
|
-
end
|
20
|
-
end
|
21
|
-
context "creating a resource" do
|
22
|
-
let(:script) { "scope 'kitchen' do; resource 'food'; end" }
|
23
|
-
it "creates resource with id matching the scope" do
|
24
|
-
expect(api).to receive(:resource).with("the-account:food:kitchen").and_return double("kitchen-exists", :exists? => true)
|
25
|
-
subject
|
26
|
-
end
|
27
|
-
end
|
28
|
-
context "creating a layer" do
|
29
|
-
let(:script) { "scope 'kitchen' do; layer; end" }
|
30
|
-
it "creates layer with id matching the scope" do
|
31
|
-
expect(api).to receive(:layer).with("kitchen").and_return double("kitchen-exists", :exists? => true)
|
32
|
-
subject
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
context "creating user:alice" do
|
37
|
-
let(:script) { "user 'alice'" }
|
38
|
-
let(:alice) {
|
39
|
-
Conjur::User.new("alice").tap do |user|
|
40
|
-
user.attributes = { "api_key" => "the-api-key" }
|
41
|
-
end
|
42
|
-
}
|
43
|
-
it "should populate the root ownerid" do
|
44
|
-
expect(api).to receive(:user).with("alice").and_return double("alice-exists", exists?: false)
|
45
|
-
expect(api).to receive(:create_user).with(id: "alice", ownerid: "user:bob").and_return alice
|
46
|
-
|
47
|
-
runner.owner = "user:bob"
|
48
|
-
runner.execute
|
49
|
-
end
|
50
|
-
it "should store the api_key in the context keyed by roleid" do
|
51
|
-
expect(api).to receive(:user).with("alice").and_return double("alice-exists", exists?: false)
|
52
|
-
expect(api).to receive(:create_user).with(id: "alice").and_return alice
|
53
|
-
|
54
|
-
runner.execute
|
55
|
-
|
56
|
-
expect(runner.context['api_keys']).to eq({
|
57
|
-
"the-account:user:alice" => "the-api-key"
|
58
|
-
})
|
59
|
-
end
|
60
|
-
|
61
|
-
it "doesn't store default env and stack in context" do
|
62
|
-
expect(runner.context).to_not have_key 'env'
|
63
|
-
expect(runner.context).to_not have_key 'stack'
|
64
|
-
end
|
65
|
-
|
66
|
-
context "with non-default stack and env" do
|
67
|
-
let(:runner) do
|
68
|
-
Conjur::Config.merge env: 'baz', stack: 'bar'
|
69
|
-
Conjur::Config.apply
|
70
|
-
Conjur::DSL::Runner.new '', nil
|
71
|
-
end
|
72
|
-
|
73
|
-
it "stores them in context" do
|
74
|
-
expect(runner.context['env']).to eq 'baz'
|
75
|
-
expect(runner.context['stack']).to eq 'bar'
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
context "with appliance url" do
|
80
|
-
let(:appliance_url) { "https://conjur.example.com/api" }
|
81
|
-
let(:runner) do
|
82
|
-
Conjur::Config.merge appliance_url: appliance_url
|
83
|
-
Conjur::Config.apply
|
84
|
-
|
85
|
-
Conjur::DSL::Runner.new '', nil
|
86
|
-
end
|
87
|
-
|
88
|
-
it "stores appliance url in the context" do
|
89
|
-
expect(runner.context['appliance_url']).to eq appliance_url
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
data/spec/env_spec.rb
DELETED
@@ -1,214 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'conjur/conjurenv'
|
3
|
-
|
4
|
-
describe Conjur::Env do
|
5
|
-
describe Conjur::Env::ConjurVariable do
|
6
|
-
it "reports a missing value" do
|
7
|
-
var = Conjur::Env::ConjurVariable.new('the-id')
|
8
|
-
expect { var.evaluate nil }.to raise_error "variable the-id exists but doesn't have a value"
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
describe "#initialize" do
|
13
|
-
|
14
|
-
describe "requires either :file or :yaml parameter" do
|
15
|
-
before {
|
16
|
-
expect_any_instance_of(Conjur::Env).not_to receive(:parse)
|
17
|
-
}
|
18
|
-
it "fails if both options are provided" do
|
19
|
-
expect { Conjur::Env.new(file: 'f', yaml: 'y') }.to raise_error ":file and :yaml options can not be provided together"
|
20
|
-
end
|
21
|
-
it "fails if neither option is provided" do
|
22
|
-
expect { Conjur::Env.new() }.to raise_error "either :file or :yaml option is mandatory"
|
23
|
-
end
|
24
|
-
it "fails if :yaml option is empty or is not a string" do
|
25
|
-
expect { Conjur::Env.new(yaml: "") }.to raise_error ":yaml option should be non-empty string"
|
26
|
-
expect { Conjur::Env.new(yaml: nil) }.to raise_error ":yaml option should be non-empty string"
|
27
|
-
expect { Conjur::Env.new(yaml: 2) }.to raise_error ":yaml option should be non-empty string"
|
28
|
-
end
|
29
|
-
it "fails if :file option is empty or is not a string"do
|
30
|
-
expect { Conjur::Env.new(file: "") }.to raise_error ":file option should be non-empty string"
|
31
|
-
expect { Conjur::Env.new(file: nil) }.to raise_error ":file option should be non-empty string"
|
32
|
-
expect { Conjur::Env.new(file: 2) }.to raise_error ":file option should be non-empty string"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
describe "with correct parameters" do
|
37
|
-
|
38
|
-
let(:parsed) { :parsed_structure_stub }
|
39
|
-
|
40
|
-
describe "if :file parameter provided" do
|
41
|
-
it "does not catch any errors from File.read" do
|
42
|
-
expect_any_instance_of(Conjur::Env).not_to receive(:parse)
|
43
|
-
allow(File).to receive(:read).with('unexisting') { raise "Custom error" }
|
44
|
-
expect { Conjur::Env.new(file: 'unexisting') }.to raise_error "Custom error"
|
45
|
-
end
|
46
|
-
|
47
|
-
it "if file is readable, passes contents to #parse and stores result in @definition attribute" do
|
48
|
-
expect(File).to receive(:read).with("somefile").and_return(:file_contents)
|
49
|
-
expect_any_instance_of(Conjur::Env).to receive(:parse).with(:file_contents).and_return(:stub_parsed)
|
50
|
-
expect(Conjur::Env.new(file:"somefile").instance_variable_get("@definition")).to eq(:stub_parsed)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
it "if :yaml parameter provided, passes it to #parse and stores result in @definition attribute" do
|
54
|
-
expect_any_instance_of(Conjur::Env).to receive(:parse).with("custom yaml").and_return(:stub_parsed)
|
55
|
-
expect(Conjur::Env.new(yaml:"custom yaml").instance_variable_get("@definition")).to eq(:stub_parsed)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
describe "#parse (called from 'initialize')" do
|
61
|
-
|
62
|
-
it 'parses input as YAML and does not hide YAML errors' do
|
63
|
-
expect(YAML).to receive(:load).with("custom yaml") { raise "Custom error" }
|
64
|
-
expect { Conjur::Env.new(yaml: "custom yaml") }.to raise_error "Custom error"
|
65
|
-
end
|
66
|
-
|
67
|
-
it "fails unless YAML represents a Hash" do
|
68
|
-
expect { Conjur::Env.new(yaml: "[ 1,2,3 ]") }.to raise_error "Definition should be a Hash"
|
69
|
-
end
|
70
|
-
|
71
|
-
it "fails if values are not literal, number, !tmp or !var" do
|
72
|
-
expect { Conjur::Env.new(yaml: "{a: literal, b: !tmp tempfile, c: !var conjurvar, d: { x: another literal }}") }.to raise_error /^Definition can not include values of types/
|
73
|
-
expect { Conjur::Env.new(yaml: "{a: literal, b: 123, c: !tmp tempfile, d: !var conjurvar}") }.to_not raise_error
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'does not allow empty values for !tmp and !var' do
|
77
|
-
expect { Conjur::Env.new(yaml: "{a: literal, b: !tmp , c: !var conjurvar }") }.to raise_error "ConjurTempfile requires a parameter"
|
78
|
-
expect { Conjur::Env.new(yaml: "{a: literal, b: !tmp tempfile, c: !var }") }.to raise_error "ConjurVariable requires a parameter"
|
79
|
-
expect { Conjur::Env.new(yaml: "{a: literal, b: !tmp tempfile, c: !var conjurvar}") }.to_not raise_error
|
80
|
-
end
|
81
|
-
|
82
|
-
it "Returns hash consisting of literals, ConjurTempfile and ConjurVariable objects" do
|
83
|
-
result = Conjur::Env.new(yaml: "{a: literal, b: !tmp 'sometmp', c: !var 'somevar'}").instance_variable_get("@definition")
|
84
|
-
expect(result.keys.sort).to eq(["a","b","c"])
|
85
|
-
expect(result["a"]).to eq('literal')
|
86
|
-
expect(result["b"]).to be_a_kind_of(Conjur::Env::ConjurTempfile)
|
87
|
-
expect(result["b"].conjur_id).to eq('sometmp')
|
88
|
-
expect(result["c"]).to be_a_kind_of(Conjur::Env::ConjurVariable)
|
89
|
-
expect(result["c"].conjur_id).to eq('somevar')
|
90
|
-
end
|
91
|
-
|
92
|
-
it "Accepts empty string substitution" do
|
93
|
-
substitutions = {
|
94
|
-
}
|
95
|
-
result = Conjur::Env.new(yaml: "{a: $foo, b: !tmp '$foo$foo$bar', c: !var '$foo$bar'}", substitutions: substitutions).instance_variable_get("@definition")
|
96
|
-
expect(result["a"]).to eq('$foo')
|
97
|
-
expect(result["b"].conjur_id).to eq('$foo$foo$bar')
|
98
|
-
expect(result["c"].conjur_id).to eq('$foo$bar')
|
99
|
-
end
|
100
|
-
|
101
|
-
it "Performs requested string substitution" do
|
102
|
-
substitutions = {
|
103
|
-
"$foo" => "alice",
|
104
|
-
"$bar" => "bob"
|
105
|
-
}
|
106
|
-
result = Conjur::Env.new(yaml: "{a: $foo, b: !tmp '$foo$foo$bar', c: !var '$foo$bar'}", substitutions: substitutions).instance_variable_get("@definition")
|
107
|
-
expect(result["a"]).to eq('alice')
|
108
|
-
expect(result["b"].conjur_id).to eq('alicealicebob')
|
109
|
-
expect(result["c"].conjur_id).to eq('alicebob')
|
110
|
-
end
|
111
|
-
|
112
|
-
it "Converts numbers to string literals" do
|
113
|
-
result = Conjur::Env.new(yaml: "{a: 123}").instance_variable_get("@definition")
|
114
|
-
expect(result["a"]).to eq("123")
|
115
|
-
end
|
116
|
-
|
117
|
-
end
|
118
|
-
|
119
|
-
describe "#obtain", logged_in: true do
|
120
|
-
let(:subject) { Conjur::Env.new(yaml: "{a: literal, b: !tmp tempfile, c: !var conjurvar}") }
|
121
|
-
before {
|
122
|
-
allow(api).to receive(:variable_values).with(["tempfile","conjurvar"]).and_return({"tempfile" => "stubtemp", "conjurvar" => "stubvar" })
|
123
|
-
}
|
124
|
-
|
125
|
-
it "requests variable_values with list of !var and !tmp values" do
|
126
|
-
allow_any_instance_of(Conjur::Env::ConjurTempfile).to receive(:evaluate).and_return(:stub_value) # avoid tempfiles creation
|
127
|
-
expect(api).to receive(:variable_values).with(["tempfile","conjurvar"]).and_return({"tempfile" => "stub1", "conjurvar" => "stub2" })
|
128
|
-
subject.obtain(api)
|
129
|
-
end
|
130
|
-
|
131
|
-
it 'does not suppress api errors' do
|
132
|
-
allow(api).to receive(:variable_values) { raise "Custom API error" }
|
133
|
-
expect { subject.obtain(api) }.to raise_error "Custom API error"
|
134
|
-
end
|
135
|
-
|
136
|
-
describe "for !tmp creates temporary files with Conjur variable value" do
|
137
|
-
it "in /dev/shm if it exists" do
|
138
|
-
tempfile = double(path: '/dev/shm/newfile', close: true)
|
139
|
-
expect(File).to receive(:directory?).with("/dev/shm").and_return(true)
|
140
|
-
expect(File).to receive(:writable?).with("/dev/shm").and_return(true)
|
141
|
-
expect(Tempfile).to receive(:new).with("conjur","/dev/shm").and_return(tempfile)
|
142
|
-
expect(tempfile).to receive(:write).with("stubtemp")
|
143
|
-
subject.obtain(api)
|
144
|
-
end
|
145
|
-
it "otherwise uses Tempfile defaults" do
|
146
|
-
tempfile = double(path: '/tmp/newfile', close: true)
|
147
|
-
expect(File).to receive(:directory?).with("/dev/shm").and_return(false)
|
148
|
-
expect(Tempfile).to receive(:new).with("conjur").and_return(tempfile)
|
149
|
-
expect(tempfile).to receive(:write).with("stubtemp")
|
150
|
-
subject.obtain(api)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
describe "returns hash consisting of original keys and following values" do
|
155
|
-
before {
|
156
|
-
tempfile=double(path:"/stub/tempfile",write: true, close: true)
|
157
|
-
allow(File).to receive(:directory?).with("/dev/shm").and_return(true)
|
158
|
-
allow(File).to receive(:writable?).with("/dev/shm").and_return(true)
|
159
|
-
allow(Tempfile).to receive(:new).with("conjur","/dev/shm").and_return(tempfile)
|
160
|
-
}
|
161
|
-
let(:result) { subject.obtain(api) }
|
162
|
-
|
163
|
-
it 'literals' do
|
164
|
-
expect(result).to include("a"=>"literal")
|
165
|
-
end
|
166
|
-
it '!tmp: names of temp files' do
|
167
|
-
expect(result).to include("b"=>"/stub/tempfile")
|
168
|
-
end
|
169
|
-
it '!var: variable values' do
|
170
|
-
expect(result).to include("c"=>"stubvar")
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
describe "#check", logged_in: true do
|
176
|
-
|
177
|
-
let(:subject) { Conjur::Env.new(yaml: "{a: literal, b: !tmp tempfile_b, c: !var conjurvar_c, d: !tmp tempfile_d, e: !var conjurvar_e }") }
|
178
|
-
before {
|
179
|
-
expect(api).not_to receive(:variable_values)
|
180
|
-
expect(Tempfile).not_to receive(:new)
|
181
|
-
}
|
182
|
-
let(:permitted) { double(permitted?:true) }
|
183
|
-
let(:restricted) { double(permitted?:false) }
|
184
|
-
|
185
|
-
it "requests resource 'execute' permission for each !var and !tmp value" do
|
186
|
-
expect(api).to receive(:resource).with("variable:tempfile_b").and_return(permitted)
|
187
|
-
expect(api).to receive(:resource).with("variable:conjurvar_c").and_return(permitted)
|
188
|
-
expect(api).to receive(:resource).with("variable:tempfile_d").and_return(permitted)
|
189
|
-
expect(api).to receive(:resource).with("variable:conjurvar_e").and_return(permitted)
|
190
|
-
expect(permitted).to receive(:permitted?).exactly(4).times.with(:execute).and_return(true)
|
191
|
-
subject.check(api)
|
192
|
-
end
|
193
|
-
|
194
|
-
it 'does not rescue from unexpected api errors' do
|
195
|
-
expect(api).to receive(:resource).with("variable:tempfile_b") { raise "Custom error" }
|
196
|
-
expect { subject.check(api) }.to raise_error "Custom error"
|
197
|
-
end
|
198
|
-
|
199
|
-
it "returns Hash consisting of original keys and following statuses: :literal, :available, :unavailable" do
|
200
|
-
expect(api).to receive(:resource).with("variable:tempfile_b").and_return(permitted)
|
201
|
-
expect(api).to receive(:resource).with("variable:conjurvar_c").and_return(restricted)
|
202
|
-
expect(api).to receive(:resource).with("variable:tempfile_d").and_return(restricted)
|
203
|
-
expect(api).to receive(:resource).with("variable:conjurvar_e").and_return(permitted)
|
204
|
-
|
205
|
-
result = expect(subject.check(api)).to eq({ "a" => :literal,
|
206
|
-
"b" => :available,
|
207
|
-
"c" => :unavailable,
|
208
|
-
"d" => :unavailable,
|
209
|
-
"e" => :available
|
210
|
-
})
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
end
|