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,23 +0,0 @@
1
- @dsl
2
- Feature: Creating a User
3
-
4
- Background:
5
-
6
- Scenario: Users don't incorporate the namespace as a path prefix
7
- When I run script:
8
- """
9
- namespace do
10
- user "bob"
11
- end
12
- """
13
- Then the model should contain "user" /bob@.+/
14
-
15
- Scenario: Namespace can be used as a no-arg method
16
- When I run script:
17
- """
18
- namespace "foobar" do
19
- user "bob"
20
- end
21
- """
22
- Then the model should contain "user" "bob@foobar"
23
-
@@ -1,49 +0,0 @@
1
- Feature: Extracting JSON fields
2
-
3
- In order to use conjur output in shell scripts
4
- As a Conjur user
5
- I want to extract fields from JSON data
6
-
7
- Scenario: An array element
8
- When I successfully run `jsonfield 2 '[1, 2, 3]'`
9
- Then the output should contain "3"
10
-
11
- Scenario: An out of bounds array element
12
- When I run `jsonfield 3 '[1, 2, 3]'`
13
- Then the output should contain "No field 3"
14
- And the exit status should be 2
15
-
16
- Scenario: A hash element
17
- When I successfully run `jsonfield a '{"a": 4}'`
18
- Then the output should contain "4"
19
-
20
- Scenario: A non-existent hash element
21
- When I run `jsonfield b '{"a": 4}'`
22
- Then the output should contain "No field b"
23
- And the exit status should be 2
24
-
25
- Scenario: Nested elements
26
- When I successfully run `jsonfield 0.a.1.b '[{"a": [42, {"b": "foo", "d": null}, 33], "bar": true}]'`
27
- Then the output should contain "foo"
28
-
29
- Scenario: Standard input
30
- Given a file named "test.json" with:
31
- """
32
- {
33
- "a": [
34
- 42,
35
- {
36
- "b": "foo",
37
- "d": null
38
- },
39
- 33
40
- ],
41
- "bar": true
42
- }
43
- """
44
- When I run `cat test.json | jsonfield 0.a.1.b`
45
- Then the output should contain "foo"
46
-
47
- Scenario: An element with hyphen in key
48
- When I successfully run `jsonfield variables.db-password '{"variables": {"db-password": "foo"}}'`
49
- Then the output should contain "foo"
@@ -1,58 +0,0 @@
1
- @real-api
2
- Feature: Retrieving role graphs
3
- As a Conjur user
4
- In order to understand the role hierarchy
5
- I want to retrieve role graphs and present them in a useful format
6
-
7
- Background:
8
- Given a graph with edges
9
- | Tywin | Jamie |
10
- | Tywin | Cersei |
11
- | Cersei | Joffrey |
12
- | Jamie | Joffrey |
13
- | Aerys | Tyrion |
14
- | Joanna | Tyrion |
15
-
16
- Scenario: Showing the graph as JSON
17
- When I successfully run with role expansion "conjur role graph --as-role Joffrey Joffrey"
18
- Then the graph JSON should be:
19
- """
20
- {
21
- "graph": [
22
- { "parent": "Tywin", "child": "Jamie" },
23
- { "parent": "Tywin", "child": "Cersei"},
24
- { "parent": "Cersei", "child": "Joffrey"},
25
- { "parent": "Jamie", "child": "Joffrey" }
26
- ]
27
- }
28
- """
29
-
30
- Scenario: Short JSON output
31
- When I successfully run with role expansion "conjur role graph --short --as-role Joffrey Joffrey"
32
- Then the graph JSON should be:
33
- """
34
- [
35
- [ "Tywin", "Jamie" ],
36
- [ "Tywin", "Cersei" ],
37
- [ "Jamie", "Joffrey" ],
38
- [ "Cersei", "Joffrey"]
39
- ]
40
- """
41
-
42
- Scenario: I can restrict the output to show only ancestors or descendants
43
- When I successfully run with role expansion "conjur role graph --short --no-ancestors --as-role Cersei Cersei"
44
- Then the graph JSON should be:
45
- """
46
- [
47
- [ "Cersei", "Joffrey" ]
48
- ]
49
- """
50
- When I successfully run with role expansion "conjur role graph --short --no-descendants --as-role Cersei Cersei Jamie"
51
- Then the graph JSON should be:
52
- """
53
- [
54
- [ "Tywin", "Cersei" ],
55
- [ "Tywin", "Jamie" ]
56
- ]
57
- """
58
-
@@ -1,5 +0,0 @@
1
- When(/^I conjurize "(.*?)"$/) do |args|
2
- cmd = "conjurize -f ../../features/support/host.json -c ../../features/support/conjur.conf"
3
- step %Q(I run `#{[ cmd, args ].compact.join(' ')}`)
4
- end
5
-
@@ -1,52 +0,0 @@
1
- When(/^I use script context:$/) do |context|
2
- @context = JSON.parse context
3
- end
4
-
5
- When(/^I run script:$/) do |script|
6
- require 'conjur/dsl/runner'
7
- @runner = Conjur::DSL::Runner.new(script)
8
- @runner.context = @context if @context
9
- @runner.execute
10
- end
11
-
12
- Then(/^the model should contain "(.*?)" "(.*?)"$/) do |kind, id|
13
- @mock_api.thing(kind, id).should_not be_nil
14
- end
15
- Then(/^the model should contain "(.*?)" \/(.*?)\/$/) do |kind, id|
16
- @mock_api.thing_like(kind, Regexp.new(id)).should_not be_nil
17
- end
18
- Then(/^the "(.*?)" "(.*?)" should be owned by "(.*?)"$/) do |kind, id, owner|
19
- step "the model should contain \"#{kind}\" \"#{id}\""
20
- if kind == 'role' || kind == 'resource'
21
- @mock_api.thing(kind, id).acting_as.should == owner
22
- else
23
- @mock_api.thing(kind, id).ownerid.should == owner
24
- end
25
- end
26
-
27
- Then(/^the "(.*?)" "(.*?)" should not have an owner$/) do |kind, id|
28
- step "the model should contain \"#{kind}\" \"#{id}\""
29
- @mock_api.thing(kind, id).ownerid.should be_nil
30
- end
31
-
32
- Then(/^"(.*?)" can "(.*?)" "(.*?)"( with grant option)?$/) do |role, privilege, resource, grant_option|
33
- resource = @mock_api.thing(:resource, resource)
34
- permission = resource.permissions.find do |p|
35
- p.privilege == privilege && p.role == role && p.grant_option == !grant_option.nil?
36
- end
37
- raise "#{role} cannot #{privilege} #{resource.id} with#{grant_option ? "" : "out"} grant_option" unless permission
38
- end
39
-
40
- Then(/^the context should contain "(.*?)"$/) do |key|
41
- @runner.context.should have_key(key.to_s)
42
- end
43
-
44
- Then(/^the context "(.*?)" should be "(.*?)"$/) do |key, value|
45
- @runner.context[key].should == value
46
- end
47
-
48
- Then(/^the context "(.*?)" should contain "(.*?)" item$/) do |key, key_count|
49
- step "the context should contain \"#{key}\""
50
- expect(@runner.context[key].length).to eq key_count.to_i
51
- end
52
-
@@ -1,6 +0,0 @@
1
- ---
2
- account: test
3
- plugins:
4
- - ui
5
- appliance_url: https://conjur/api
6
- cert_file: ../../features/support/conjur-test.pem
@@ -1,121 +0,0 @@
1
- #
2
- # Copyright (C) 2013 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
- class Conjur::Command::Assets < Conjur::Command
22
- # Toplevel command
23
- desc "Manage assets"
24
- command :asset do |asset|
25
- hide_docs(asset)
26
- asset.desc "Create an asset"
27
- asset.arg_name "kind:id"
28
- asset.command :create do |create|
29
- hide_docs(create)
30
- acting_as_option(create)
31
- create.action do |global_options, options, args|
32
- # NOTE: no generic functions there, as :id is optional
33
- kind, id = require_arg(args, 'kind:id').split(':')
34
- id = nil if id.blank?
35
- kind.gsub!('-', '_')
36
-
37
- m = "create_#{kind}"
38
- record = if [ 1, -1 ].member?(api.method(m).arity)
39
- if id
40
- options[:id] = id
41
- end
42
- api.send(m, options)
43
- else
44
- unless id
45
- raise "for kind #{kind} id should be specified explicitly after colon"
46
- end
47
- api.send(m, id, options)
48
- end
49
- display(record, options)
50
- end
51
- end
52
-
53
- asset.desc "Show an asset"
54
- asset.arg_name "id"
55
- asset.command :show do |c|
56
- c.action do |global_options,options,args|
57
- kind, id = get_kind_and_id_from_args(args, 'id')
58
- display api.send(kind, id).attributes
59
- end
60
- end
61
-
62
- asset.desc "Checks for the exisistance of an asset"
63
- asset.arg_name "id"
64
- asset.command :exists do |c|
65
- c.action do |global_options,options,args|
66
- kind, id = get_kind_and_id_from_args(args, 'id')
67
- puts api.send(kind, id).exists?
68
- end
69
- end
70
-
71
- asset.desc "List assets of a given kind"
72
- asset.arg_name "kind"
73
- asset.command :list do |c|
74
- hide_docs c
75
- c.action do |global_options,options,args|
76
- kind = require_arg(args, "kind").gsub('-', '_')
77
- if api.respond_to?(kind.pluralize)
78
- api.send(kind.pluralize)
79
- else
80
- api.resources(kind: kind)
81
- end.each do |e|
82
- display(e, options)
83
- end
84
- end
85
- end
86
-
87
- asset.desc "Manage asset membership"
88
- asset.command :members do |members|
89
- members.desc "Add a member to an asset"
90
- members.arg_name "id role-name member"
91
- members.command :add do |c|
92
- hide_docs(c)
93
- c.desc "Grant with admin option"
94
- c.flag [:a, :admin]
95
-
96
- c.action do |global_options, options, args|
97
- kind, id = get_kind_and_id_from_args(args, 'id')
98
- role_name = require_arg(args, 'role-name')
99
- member = require_arg(args, 'member')
100
- admin_option = !options.delete(:admin).nil?
101
-
102
- api.send(kind, id).add_member role_name, member, admin_option: admin_option
103
- puts "Membership granted"
104
- end
105
- end
106
-
107
- members.desc "Remove a member from an asset"
108
- members.arg_name "id role-name member"
109
- members.command :remove do |c|
110
- hide_docs c
111
- c.action do |global_options, options, args|
112
- kind, id = get_kind_and_id_from_args(args, 'id')
113
- role_name = require_arg(args, 'role-name')
114
- member = require_arg(args, 'member')
115
- api.send(kind, id).remove_member role_name, member
116
- puts "Membership revoked"
117
- end
118
- end
119
- end
120
- end
121
- end
@@ -1,155 +0,0 @@
1
- class Conjur::Command
2
- class Audit < self
3
- class << self
4
- private
5
- SHORT_FORMATS = {
6
- 'resource:check' => lambda{|e| "checked that they can #{e[:privilege]} #{e[:resource]} (#{e[:allowed]})" },
7
- 'resource:create' => lambda{|e| "created resource #{e[:resource]} owned by #{e[:owner]}" },
8
- 'resource:update' => lambda{|e| "gave #{e[:resource]} to #{e[:owner]}" },
9
- 'resource:destroy' => lambda{|e| "destroyed resource #{e[:resource]}" },
10
- 'resource:permit' => lambda{|e| "permitted #{e[:grantee]} to #{e[:privilege]} #{e[:resource]} (grant option: #{!!e[:grant_option]})" },
11
- 'resource:deny' => lambda{|e| "denied #{e[:privilege]} from #{e[:grantee]} on #{e[:resource]}" },
12
- 'resource:permitted_roles' => lambda{|e| "listed roles permitted to #{e[:privilege]} on #{e[:resource]}" },
13
- 'role:check' => lambda{|e| "checked that #{e[:role] == e[:user] ? 'they' : e[:role]} can #{e[:privilege]} #{e[:resource]} (#{e[:allowed]})" },
14
- 'role:grant' => lambda{|e| "granted role #{e[:role]} to #{e[:member]} #{e[:admin_option] ? 'with' : 'without'} admin" },
15
- 'role:revoke' => lambda{|e| "revoked role #{e[:role]} from #{e[:member]}" },
16
- 'role:create' => lambda{|e| "created role #{e[:role]}" },
17
- 'audit' => lambda{ |e|
18
- action_part = [ e[:facility], e[:action] ].compact.join(":")
19
- actor_part = e[:role] ? "by #{e[:role]}" : nil
20
- resource_part = e[:resource_id] ? "on #{e[:resource_id]}" : nil
21
- allowed_part = e.has_key?(:allowed) ? "(allowed: #{e[:allowed]})" : nil
22
- message_part = e[:audit_message] ? "; message: #{e[:audit_message]}" : ""
23
- statement = [ action_part, actor_part, resource_part, allowed_part ].compact.join(" ")
24
- "reported #{statement}"+ message_part
25
- },
26
- 'conjur:use_extra_privilege' => lambda{|e| "requested extra privilege #{e[:privilege]}"}
27
- }
28
-
29
- def ssh_sudo_message(e)
30
- s = "#{e[:system_user]}"
31
- s << " " << (e[:allowed] ? "ran" : "attempted to run")
32
- s << " '" << e[:command] << "' as " << e[:target_user]
33
- s
34
- end
35
-
36
- def short_event_format e
37
- e.symbolize_keys!
38
- s = "[#{Time.parse(e[:timestamp])}]"
39
- s << " #{e[:user]}"
40
- s << " (as #{e[:acting_as]})" if e[:acting_as] != e[:user]
41
- if e[:facility] == 'ssh' && e[:action] == 'sudo'
42
- e[:audit_message] = ssh_sudo_message(e)
43
- end
44
- formatter = SHORT_FORMATS["#{e[:kind]}:#{e[:action]}"] || SHORT_FORMATS[e[:kind]]
45
- if formatter
46
- s << " " << formatter.call(e)
47
- else
48
- s << " unknown event: #{e[:kind]}:#{e[:action]}!"
49
- end
50
- s << " (failed with #{e[:error]})" if e[:error]
51
- s
52
- end
53
-
54
- def extract_int_option(source, name, dest=nil)
55
- if val = source[name]
56
- raise "Expected an integer for #{name}, but got #{val}" unless /\d+/ =~ val
57
- val.to_i.tap{ |i| dest[name] = i if dest }
58
- end
59
- end
60
-
61
- def extract_audit_options options
62
- # Do a little song and dance to simplify testing
63
- extracted = options.slice :follow, :short
64
- [:limit, :offset].each do |name|
65
- extract_int_option(options, name, extracted)
66
- end
67
- if extracted[:follow] && extracted[:offset]
68
- exit_now! "--offset option not allowed for --follow", 1
69
- end
70
- extracted
71
- end
72
-
73
- def show_audit_events events, options
74
- @count ||= 0
75
-
76
- events = [events] unless events.kind_of?(Array)
77
- # offset and limit options seem to be broken. this is a temporary workaround (should be applied on server-side eventually)
78
- events = events.drop(options[:offset]) if options[:offset]
79
- events = events.take(options[:limit]) if options[:limit]
80
-
81
- if options[:short]
82
- events.each do |e|
83
- puts short_event_format(e)
84
-
85
- # Undocumented, but for the sake of testing.... Allow
86
- # --limit with --follow. When we hit the limit, bail out
87
- # immediately: don't raise any exceptions, don't print any
88
- # messages, just exit with status 0.
89
- @count += 1
90
- if options[:follow] && @count == options[:limit]
91
- exit_now! 0
92
- end
93
- end
94
- else
95
- events.each{|e| puts JSON.pretty_generate(e) }
96
- end
97
- end
98
-
99
- def audit_feed_command parent, kind, &block
100
- parent.command kind do |c|
101
- c.desc "Maximum number of events to fetch"
102
- c.flag [:l, :limit]
103
-
104
- c.desc "Offset of the first event to return"
105
- c.flag [:o, :offset]
106
-
107
- c.desc "Short output format"
108
- c.switch [:s, :short]
109
-
110
- c.desc "Follow events as they are generated"
111
- c.switch [:f, :follow]
112
-
113
- c.action do |global_options, options, args|
114
- options = extract_audit_options options
115
- instance_exec(args, options, &block)
116
- end
117
- end
118
- end
119
- end
120
-
121
- desc "Fetch audit events"
122
- command :audit do |audit|
123
- audit.desc "Show all audit events visible to the current user"
124
- audit_feed_command audit, :all do |args, options|
125
- api.audit(options){ |es| show_audit_events es, options }
126
- end
127
-
128
- audit.desc "Show audit events related to a role"
129
- audit.arg_name 'role'
130
- audit_feed_command audit, :role do |args, options|
131
- id = full_resource_id(require_arg(args, "role"))
132
- api.audit_role(id, options){ |es| show_audit_events es, options }
133
- end
134
-
135
- audit.desc "Show audit events related to a resource"
136
- audit.arg_name 'resource'
137
- audit_feed_command audit, :resource do |args, options|
138
- id = full_resource_id(require_arg args, "resource")
139
- api.audit_resource(id, options){|es| show_audit_events es, options}
140
- end
141
-
142
- audit.desc "Send custom event(s) to audit system"
143
- audit.long_desc "Send custom event(s) to audit system. Events should be provided in JSON format, describing either single hash or array of hashes."
144
- audit.arg_name "( json_string | STDIN )"
145
- audit.command :send do |c|
146
- c.action do |global_options, options, args|
147
- json = ( args.shift || STDIN.read )
148
- api.audit_send json
149
- puts "Events sent successfully"
150
- end
151
- end
152
-
153
- end
154
- end
155
- end