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.
Files changed (203) hide show
  1. checksums.yaml +5 -5
  2. data/.dockerignore +1 -1
  3. data/.gitignore +2 -0
  4. data/.rubocop.yml +1 -1
  5. data/APPLIANCE_VERSION +1 -1
  6. data/CHANGELOG.md +3 -42
  7. data/Gemfile +4 -7
  8. data/Humanfile.md +31 -0
  9. data/Jenkinsfile +34 -63
  10. data/README.md +41 -55
  11. data/Rakefile +5 -1
  12. data/bin/conjur +0 -2
  13. data/build-deb.sh +1 -3
  14. data/ci/cli-test.sh +6 -0
  15. data/ci/package.sh +3 -1
  16. data/ci/publish.sh +2 -2
  17. data/ci/secrets/publish.yml +2 -2
  18. data/ci/wait_for_server.sh +10 -0
  19. data/conjur-cli.gemspec +7 -7
  20. data/dev/docker-compose.yml +24 -0
  21. data/dev/start.sh +15 -0
  22. data/dev/stop.sh +5 -0
  23. data/docker-compose.yml +30 -0
  24. data/features/authentication/authenticate.feature +34 -0
  25. data/features/authentication/login.feature +13 -0
  26. data/features/authentication/logout.feature +15 -0
  27. data/{acceptance-features → features}/authentication/whoami.feature +0 -0
  28. data/features/authorization/resource/annotate.feature +22 -0
  29. data/features/authorization/resource/check.feature +47 -0
  30. data/{acceptance-features → features}/authorization/resource/exists.feature +18 -6
  31. data/features/authorization/resource/permitted_roles.feature +35 -0
  32. data/features/authorization/resource/show.feature +34 -0
  33. data/features/authorization/role/exists.feature +28 -0
  34. data/features/authorization/role/members.feature +45 -0
  35. data/features/authorization/role/memberships.feature +43 -0
  36. data/features/conjurenv/check.feature +34 -0
  37. data/features/conjurenv/run.feature +15 -0
  38. data/{acceptance-features → features}/conjurenv/template.feature +8 -3
  39. data/{acceptance-features → features}/directory/user/update_password.feature +8 -2
  40. data/{acceptance-features → features}/directory/variable/value.feature +9 -5
  41. data/{acceptance-features → features}/directory/variable/values-add.feature +8 -3
  42. data/features/hostfactory/tokens.feature +22 -0
  43. data/features/pubkeys/show.feature +18 -0
  44. data/features/step_definitions/authn_steps.rb +22 -0
  45. data/features/step_definitions/cli_steps.rb +28 -0
  46. data/features/step_definitions/file_steps.rb +12 -0
  47. data/features/step_definitions/flow_control_steps.rb +7 -0
  48. data/features/step_definitions/graph_steps.rb +4 -3
  49. data/{acceptance-features → features}/step_definitions/http_steps.rb +0 -0
  50. data/features/step_definitions/overrides.rb +9 -0
  51. data/features/step_definitions/policy_steps.rb +11 -0
  52. data/{acceptance-features → features}/step_definitions/trusted_proxy_steps.rb +0 -0
  53. data/features/support/blank.yml +1 -0
  54. data/features/support/env.rb +21 -7
  55. data/features/support/hooks.rb +31 -116
  56. data/features/support/world.rb +16 -76
  57. data/jenkins.sh +33 -0
  58. data/lib/conjur/authenticator.rb +83 -0
  59. data/lib/conjur/authn.rb +5 -20
  60. data/lib/conjur/cli.rb +13 -6
  61. data/lib/conjur/command.rb +30 -350
  62. data/lib/conjur/command/authn.rb +23 -15
  63. data/lib/conjur/command/host_factories.rb +2 -74
  64. data/lib/conjur/command/hosts.rb +6 -113
  65. data/lib/conjur/command/init.rb +20 -35
  66. data/lib/conjur/command/{secrets.rb → policies.rb} +33 -22
  67. data/lib/conjur/command/pubkeys.rb +3 -63
  68. data/lib/conjur/command/resources.rb +45 -162
  69. data/lib/conjur/command/roles.rb +11 -181
  70. data/lib/conjur/command/rspec/helpers.rb +0 -1
  71. data/lib/conjur/command/rspec/mock_services.rb +4 -4
  72. data/lib/conjur/command/users.rb +2 -159
  73. data/lib/conjur/command/variables.rb +5 -218
  74. data/lib/conjur/complete.rb +2 -2
  75. data/lib/conjur/config.rb +1 -11
  76. data/lib/conjur/conjurenv.rb +12 -9
  77. data/lib/conjur/identifier_manipulation.rb +3 -5
  78. data/lib/conjur/version.rb +2 -2
  79. data/{publish-rubygem.sh → publish.sh} +0 -4
  80. data/spec/authn_spec.rb +4 -0
  81. data/spec/command/hosts_spec.rb +2 -69
  82. data/spec/command/init_spec.rb +16 -11
  83. data/spec/command/pubkeys_spec.rb +1 -46
  84. data/spec/command/resources_spec.rb +21 -170
  85. data/spec/command/roles_spec.rb +5 -181
  86. data/spec/command/users_spec.rb +3 -79
  87. data/spec/command_spec.rb +1 -20
  88. data/spec/complete_spec.rb +1 -23
  89. data/spec/config_spec.rb +1 -1
  90. data/spec/spec_helper.rb +4 -5
  91. data/test.sh +29 -25
  92. metadata +92 -212
  93. data/.githooks/pre_commit/run_specs.rb +0 -23
  94. data/Dockerfile +0 -15
  95. data/Dockerfile.fpm +0 -18
  96. data/Dockerfile.publish +0 -12
  97. data/Dockerfile.standalone +0 -33
  98. data/Dockerfile.validate-packaging +0 -9
  99. data/VERSION +0 -1
  100. data/acceptance-features/audit/audit_event_send.feature +0 -107
  101. data/acceptance-features/audit/fetch.feature +0 -16
  102. data/acceptance-features/audit/send.feature +0 -51
  103. data/acceptance-features/authentication/authenticate.feature +0 -10
  104. data/acceptance-features/authentication/login.feature +0 -12
  105. data/acceptance-features/authentication/logout.feature +0 -13
  106. data/acceptance-features/authorization/resource/annotate.feature +0 -35
  107. data/acceptance-features/authorization/resource/check.feature +0 -24
  108. data/acceptance-features/authorization/resource/create.feature +0 -21
  109. data/acceptance-features/authorization/resource/deny.feature +0 -12
  110. data/acceptance-features/authorization/resource/give.feature +0 -24
  111. data/acceptance-features/authorization/resource/permit.feature +0 -20
  112. data/acceptance-features/authorization/resource/permitted_roles.feature +0 -16
  113. data/acceptance-features/authorization/resource/show.feature +0 -28
  114. data/acceptance-features/authorization/role/create.feature +0 -13
  115. data/acceptance-features/authorization/role/exists.feature +0 -19
  116. data/acceptance-features/authorization/role/grant_to.feature +0 -21
  117. data/acceptance-features/authorization/role/graph.feature +0 -57
  118. data/acceptance-features/authorization/role/members.feature +0 -23
  119. data/acceptance-features/authorization/role/memberships.feature +0 -27
  120. data/acceptance-features/bootstrap.feature +0 -13
  121. data/acceptance-features/conjurenv/check.feature +0 -21
  122. data/acceptance-features/conjurenv/run.feature +0 -10
  123. data/acceptance-features/directory/group/create.feature +0 -20
  124. data/acceptance-features/directory/group/retire.feature +0 -54
  125. data/acceptance-features/directory/host/create.feature +0 -23
  126. data/acceptance-features/directory/host/retire.feature +0 -6
  127. data/acceptance-features/directory/hostfactory/create.feature +0 -28
  128. data/acceptance-features/directory/hostfactory/tokens.feature +0 -16
  129. data/acceptance-features/directory/layer/create.feature +0 -10
  130. data/acceptance-features/directory/layer/hosts-add.feature +0 -9
  131. data/acceptance-features/directory/layer/hosts-remove.feature +0 -10
  132. data/acceptance-features/directory/layer/retire.feature +0 -43
  133. data/acceptance-features/directory/user/create.feature +0 -23
  134. data/acceptance-features/directory/user/retire.feature +0 -6
  135. data/acceptance-features/directory/variable/create.feature +0 -14
  136. data/acceptance-features/directory/variable/retire.feature +0 -17
  137. data/acceptance-features/dsl/policy_owner.feature +0 -45
  138. data/acceptance-features/dsl/resource_owner.feature +0 -17
  139. data/acceptance-features/dsl/retire.feature +0 -15
  140. data/acceptance-features/global-privilege/elevate.feature +0 -20
  141. data/acceptance-features/global-privilege/reveal.privilege +0 -20
  142. data/acceptance-features/pubkeys/add.feature +0 -22
  143. data/acceptance-features/pubkeys/delete.feature +0 -9
  144. data/acceptance-features/pubkeys/names.feature +0 -26
  145. data/acceptance-features/pubkeys/show.feature +0 -27
  146. data/acceptance-features/step_definitions/cli_steps.rb +0 -57
  147. data/acceptance-features/step_definitions/graph_steps.rb +0 -22
  148. data/acceptance-features/step_definitions/user_steps.rb +0 -51
  149. data/acceptance-features/support/env.rb +0 -23
  150. data/acceptance-features/support/hooks.rb +0 -178
  151. data/acceptance-features/support/world.rb +0 -176
  152. data/acceptance-features/trusted_proxies.feature +0 -82
  153. data/bin/conjurize +0 -26
  154. data/bin/jsonfield +0 -70
  155. data/build-standalone +0 -6
  156. data/deprecations.sh +0 -38
  157. data/features/conjurize.feature +0 -134
  158. data/features/dsl_context.feature +0 -36
  159. data/features/dsl_host_create.feature +0 -11
  160. data/features/dsl_ownership.feature +0 -30
  161. data/features/dsl_permission.feature +0 -45
  162. data/features/dsl_resource_create.feature +0 -23
  163. data/features/dsl_role_create.feature +0 -11
  164. data/features/dsl_user_create.feature +0 -23
  165. data/features/jsonfield.feature +0 -49
  166. data/features/role_graph.feature +0 -58
  167. data/features/step_definitions/conjurize_steps.rb +0 -5
  168. data/features/step_definitions/dsl_steps.rb +0 -52
  169. data/features/support/conjur.conf +0 -6
  170. data/lib/conjur/command/assets.rb +0 -121
  171. data/lib/conjur/command/audit.rb +0 -155
  172. data/lib/conjur/command/bootstrap.rb +0 -129
  173. data/lib/conjur/command/dsl_command.rb +0 -75
  174. data/lib/conjur/command/elevate.rb +0 -76
  175. data/lib/conjur/command/field.rb +0 -45
  176. data/lib/conjur/command/groups.rb +0 -208
  177. data/lib/conjur/command/ids.rb +0 -34
  178. data/lib/conjur/command/layers.rb +0 -211
  179. data/lib/conjur/command/ldapsync.rb +0 -118
  180. data/lib/conjur/command/rspec/audit_helpers.rb +0 -68
  181. data/lib/conjur/command/rubydsl.rb +0 -93
  182. data/lib/conjur/command/script.rb +0 -48
  183. data/lib/conjur/command/server.rb +0 -67
  184. data/lib/conjur/conjurize.rb +0 -71
  185. data/lib/conjur/conjurize/script.rb +0 -150
  186. data/lib/conjur/dsl/runner.rb +0 -273
  187. data/publish-deb.sh +0 -6
  188. data/push-image +0 -29
  189. data/spec/command/assets_spec.rb +0 -115
  190. data/spec/command/audit_spec.rb +0 -376
  191. data/spec/command/elevate_spec.rb +0 -28
  192. data/spec/command/env_spec.rb +0 -168
  193. data/spec/command/groups_spec.rb +0 -77
  194. data/spec/command/host_factories_spec.rb +0 -38
  195. data/spec/command/layers_spec.rb +0 -35
  196. data/spec/command/ldapsync_spec.rb +0 -28
  197. data/spec/command/rubydsl_spec.rb +0 -63
  198. data/spec/command/variable_expiration_spec.rb +0 -164
  199. data/spec/command/variables_spec.rb +0 -192
  200. data/spec/conjurize/script_spec.rb +0 -62
  201. data/spec/conjurize_spec.rb +0 -70
  202. data/spec/dsl/runner_spec.rb +0 -93
  203. 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
@@ -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
@@ -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