conjur-api 4.14.0 → 4.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/CHANGELOG.md +4 -0
- data/lib/conjur-api/version.rb +1 -1
- data/lib/conjur/acts_as_asset.rb +44 -3
- data/lib/conjur/acts_as_resource.rb +53 -4
- data/lib/conjur/acts_as_user.rb +17 -7
- data/lib/conjur/annotations.rb +49 -3
- data/lib/conjur/api.rb +30 -3
- data/lib/conjur/api/deputies.rb +25 -1
- data/lib/conjur/api/resources.rb +109 -5
- data/lib/conjur/api/roles.rb +103 -11
- data/lib/conjur/api/secrets.rb +16 -1
- data/lib/conjur/api/users.rb +65 -1
- data/lib/conjur/api/variables.rb +65 -1
- data/lib/conjur/audit-api.rb +3 -0
- data/lib/conjur/authn-api.rb +4 -0
- data/lib/conjur/authz-api.rb +4 -0
- data/lib/conjur/base.rb +31 -30
- data/lib/conjur/build_from_response.rb +11 -0
- data/lib/conjur/cast.rb +5 -1
- data/lib/conjur/core-api.rb +22 -2
- data/lib/conjur/deputy.rb +19 -2
- data/lib/conjur/env.rb +18 -3
- data/lib/conjur/escape.rb +65 -4
- data/lib/conjur/event_source.rb +15 -2
- data/lib/conjur/graph.rb +103 -12
- data/lib/conjur/has_id.rb +13 -1
- data/lib/conjur/has_identifier.rb +9 -6
- data/lib/conjur/has_owner.rb +21 -7
- data/lib/conjur/host.rb +8 -0
- data/lib/conjur/layer-api.rb +4 -0
- data/lib/conjur/layer.rb +50 -3
- data/lib/conjur/log.rb +22 -2
- data/lib/conjur/log_source.rb +27 -0
- data/lib/conjur/path_based.rb +47 -2
- data/lib/conjur/pubkeys-api.rb +12 -0
- data/lib/conjur/role.rb +220 -9
- data/lib/conjur/role_grant.rb +50 -2
- data/lib/conjur/secret.rb +9 -1
- data/lib/conjur/standard_methods.rb +31 -3
- data/lib/conjur/user.rb +55 -3
- data/spec/lib/role_spec.rb +1 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5364b2c4521be8b3f6b3fce20269873ac72a5ec8
|
4
|
+
data.tar.gz: e4e22c72cae8780bfe0263525156e5c57c0d5510
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 982cbf720ebb14461e0868a0c8281d14a6561b5335004270780ff45e393fbe93f5ddd755b60c127ab90aedf9b3f051a01f16b1bcb2a733293cb7199ef4f1f766
|
7
|
+
data.tar.gz: 9fbb761715f485f823b20a4493a53a753bca25d1217632c126bc03ced49fab69bb81922bb132dbaebb49d2e81c901f8567c9c26683031448214101725e86aad1
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
data/lib/conjur-api/version.rb
CHANGED
data/lib/conjur/acts_as_asset.rb
CHANGED
@@ -19,6 +19,7 @@
|
|
19
19
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
20
|
#
|
21
21
|
module Conjur
|
22
|
+
# A mixin used by Conjur asset classes such as {Conjur::User} and {Conjur::Group}.
|
22
23
|
module ActsAsAsset
|
23
24
|
include HasId
|
24
25
|
include Exists
|
@@ -26,17 +27,57 @@ module Conjur
|
|
26
27
|
include ActsAsResource
|
27
28
|
include HasAttributes
|
28
29
|
|
29
|
-
|
30
|
+
# Add an internal grant on this asset's resource. This method allows you to grant permissions on all members of
|
31
|
+
# a container asset (for example, all hosts in a layer) to the given role. Currently this method
|
32
|
+
# is only useful for `layer` assets, and corresponds to the
|
33
|
+
# {http://developer.conjur.net/reference/services/directory/layer/hosts-permit.html `hosts permit`} CLI
|
34
|
+
# command. In particular, to permit `'update'` on all hosts in a layer, `role_name` should be
|
35
|
+
# `'admin_host'`, and to permit `'execute'` it should be `'use_host'`.
|
36
|
+
#
|
37
|
+
# @example Allow group 'ops' to admin hosts in the 'dev/database' layer
|
38
|
+
# ops = api.create_group 'ops'
|
39
|
+
# dev_database = api.create_layer 'dev/database'
|
40
|
+
#
|
41
|
+
# # Create and add a host to the databasees layer
|
42
|
+
# host = api.create_host 'ec2/i-123ab23f'
|
43
|
+
# dev_databases.add_host host
|
44
|
+
#
|
45
|
+
# # Ops can't update the hosts
|
46
|
+
# host.resource.permitted? 'update', acting_as: 'conjur:group:ops'
|
47
|
+
# # => false
|
48
|
+
#
|
49
|
+
# # Allow 'group:ops' to admin all hosts in the layer
|
50
|
+
# layer.add_member 'admin_host', ops
|
51
|
+
#
|
52
|
+
# # Now 'group:ops' is allowed to `'update'` the role.`
|
53
|
+
# host.resource.permitted? 'update', acting_as: 'group:ops'
|
54
|
+
# # => true
|
55
|
+
#
|
56
|
+
# @param [String] role_name name of the internal role to grant (for layers, it must be `'use_host'` or `'admin_host'`)
|
57
|
+
# @param [String, #roleid] member the role to receive the grant
|
58
|
+
# @param [Hash] options Unused, included for backwards compatibility
|
59
|
+
# @return [void]
|
30
60
|
def add_member(role_name, member, options = {})
|
31
61
|
owned_role(role_name).grant_to member, options
|
32
62
|
end
|
33
|
-
|
63
|
+
|
64
|
+
# Remove a grant created with {#add_member}. When an internal grant has been created on this asset's resource
|
65
|
+
# with {#add_member}, you can remove it with this method.
|
66
|
+
#
|
67
|
+
# @see #add_member
|
68
|
+
# @param [String] role_name name of the internal grant role (for layers, it must be `'use_host'` or `'admin_host'`).
|
69
|
+
# @param [String, #roleid] member the role to remove
|
70
|
+
# @return [void]
|
34
71
|
def remove_member(role_name, member)
|
35
72
|
owned_role(role_name).revoke_from member
|
36
73
|
end
|
37
74
|
|
38
75
|
protected
|
39
|
-
|
76
|
+
|
77
|
+
# Return the internal role for an add/remove member grant.
|
78
|
+
#
|
79
|
+
# @param [String] role_name the name of the internal role
|
80
|
+
# @return [Conjur::Role] the internal role
|
40
81
|
def owned_role(role_name)
|
41
82
|
tokens = [ resource_kind, resource_id, role_name ]
|
42
83
|
grant_role = [ core_conjur_account, '@', tokens.join('/') ].join(':')
|
@@ -23,34 +23,83 @@ require 'active_support/dependencies/autoload'
|
|
23
23
|
require 'active_support/core_ext'
|
24
24
|
|
25
25
|
module Conjur
|
26
|
+
|
27
|
+
# This module is included in asset classes that have an associated resource.
|
26
28
|
module ActsAsResource
|
29
|
+
# Return the {Conjur::Resource} associated with this asset.
|
30
|
+
#
|
31
|
+
# @return [Conjur::Resource] the resource associated with this asset
|
27
32
|
def resource
|
28
33
|
require 'conjur/resource'
|
29
34
|
# NOTE: should we use specific class to build sub-url below?
|
30
35
|
Conjur::Resource.new(Conjur::Authz::API.host, self.options)[[ core_conjur_account, 'resources', path_escape(resource_kind), path_escape(resource_id) ].join('/')]
|
31
36
|
end
|
32
|
-
|
37
|
+
|
38
|
+
# Return the *qualified* id of the resource associated with this asset.
|
39
|
+
#
|
40
|
+
# @return [String] the qualified id of the resource associated with this asset.
|
33
41
|
def resourceid
|
34
42
|
[ core_conjur_account, resource_kind, resource_id ].join(':')
|
35
43
|
end
|
36
|
-
|
44
|
+
|
45
|
+
# The kind of resource underlying the asset. The kind is the second token in
|
46
|
+
# a Conjur id like `"account:kind:id"`.
|
47
|
+
#
|
48
|
+
# @see Conjur:Resource#kind
|
49
|
+
# @return [String] the resource kind for the underlying resource
|
37
50
|
def resource_kind
|
38
51
|
self.class.name.split("::")[-1].underscore.split('/').join('-')
|
39
52
|
end
|
40
53
|
|
54
|
+
# @api private
|
55
|
+
#
|
56
|
+
# Confusingly, this method returns the *unqualified* resource id, as opposed to the *qualified*
|
57
|
+
# resource id returned by {#resourceid}.
|
58
|
+
#
|
59
|
+
# @return [String] the *unqualified* resource id.
|
41
60
|
def resource_id
|
42
61
|
id
|
43
62
|
end
|
44
63
|
|
64
|
+
# @api private
|
65
|
+
# Delete a resource
|
66
|
+
# This doesn't typically work ;-)
|
67
|
+
# @return [void]
|
45
68
|
def delete
|
46
69
|
resource.delete
|
47
70
|
super
|
48
71
|
end
|
49
|
-
|
72
|
+
|
73
|
+
# Permit `role` to perform `privilege` on this resource. A
|
74
|
+
# {http://developer.conjur.net/reference/services/authorization/permission.html permission} represents an ability
|
75
|
+
# to perform certain (application defined) actions on this resource.
|
76
|
+
#
|
77
|
+
# This method is equivalent to calling `resource.permit`.
|
78
|
+
#
|
79
|
+
# @example Allow a group and its members to get the value of a Conjur variable
|
80
|
+
# group = api.group 'some-project/developers'
|
81
|
+
# variable = api.variable 'some-project/development/postgres-uri'
|
82
|
+
# variable.permit 'execute', group
|
83
|
+
#
|
84
|
+
# @see Conjur::Resource#permit
|
85
|
+
# @param [String] privilege the privilege to grant
|
86
|
+
# @param [String, #roleid] role the role to which the privilege is granted
|
87
|
+
# @param options [Hash, nil] options to pass through to `RestClient::Resource#post`
|
88
|
+
# @return [void]
|
89
|
+
# @raise [RestClient::Forbidden] if you don't have permission to perform this operation.
|
50
90
|
def permit(privilege, role, options = {})
|
51
91
|
resource.permit privilege, role, options
|
52
92
|
end
|
53
|
-
|
93
|
+
|
94
|
+
|
95
|
+
# Deny `role` permission to perform actions corresponding to `privilege` on the underlying resource.
|
96
|
+
#
|
97
|
+
# @see Conjur::Resource#deny
|
98
|
+
# @param privilege [String, #each] A permission name or an `Enumerable` of permissions to deny. In the
|
99
|
+
# later, all permissions will be denied.
|
100
|
+
# @param role [String, :roleid] A full role id or a role-ish object whose permissions we will deny.
|
101
|
+
#
|
102
|
+
# @return [void]
|
54
103
|
def deny(privilege, role)
|
55
104
|
resource.deny privilege, role
|
56
105
|
end
|
data/lib/conjur/acts_as_user.rb
CHANGED
@@ -19,17 +19,27 @@
|
|
19
19
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
20
|
#
|
21
21
|
module Conjur
|
22
|
+
# This module provides methods for things that are like users (specifically, those that have
|
23
|
+
# api keys).
|
22
24
|
module ActsAsUser
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
include ActsAsRole
|
26
|
+
|
27
|
+
# Returns a newly created user's api_key.
|
28
|
+
#
|
29
|
+
# @note this method can only be called on newly created user-like things (those returned from, for example,)
|
30
|
+
# {Conjur::API#create_user}.
|
31
|
+
#
|
32
|
+
# @return [String] the api key
|
33
|
+
# @raise [Exception] when the object isn't newly created.
|
29
34
|
def api_key
|
30
35
|
attributes['api_key'] or raise "api_key is only available on a newly created #{self.class.name.downcase}"
|
31
36
|
end
|
32
|
-
|
37
|
+
|
38
|
+
# Create an api logged in as this user-like thing.
|
39
|
+
#
|
40
|
+
# @note As with {#api_key}, this method only works on newly created instances.
|
41
|
+
# @see #api_key
|
42
|
+
# @return [Conjur::API] an api logged in as this user-like thing.
|
33
43
|
def api
|
34
44
|
Conjur::API.new_from_key login, api_key
|
35
45
|
end
|
data/lib/conjur/annotations.rb
CHANGED
@@ -17,7 +17,9 @@
|
|
17
17
|
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
18
18
|
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
19
19
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
-
|
20
|
+
|
21
|
+
require 'forwardable'
|
22
|
+
|
21
23
|
module Conjur
|
22
24
|
# Conjur allows {http://developer.conjur.net/reference/services/authorization/resource Resource}
|
23
25
|
# instances to be {http://developer.conjur.net/reference/services/authorization/resource/annotate.html annotated}
|
@@ -69,6 +71,49 @@ module Conjur
|
|
69
71
|
self
|
70
72
|
end
|
71
73
|
|
74
|
+
# Return a *copy* of the annotation values
|
75
|
+
#
|
76
|
+
# @example Changing values has no effectannotations_hash
|
77
|
+
# resource.annotations.values ["Some Value"]
|
78
|
+
# resource.annotations.values.each do |v|
|
79
|
+
# v << "HI"
|
80
|
+
# end
|
81
|
+
# resource.annotations.values # => ["Some Value"]
|
82
|
+
#
|
83
|
+
# # Notice that this is different from ordinary Hash behavior
|
84
|
+
# h = {"Some Key" => "Some Value"}
|
85
|
+
# h.values.each do |v|
|
86
|
+
# v << "HI"
|
87
|
+
# end
|
88
|
+
# h.values # "Some ValueHI"
|
89
|
+
#
|
90
|
+
# @example Show the values of a resources annotations
|
91
|
+
# resource.annotations # => {'Name' => 'The Best Resource EVAR',
|
92
|
+
# # 'Story' => 'The Coolest!' }
|
93
|
+
# resource.annotations.values # => ['The Best Resource EVAR', 'The Coolest!']
|
94
|
+
#
|
95
|
+
# @return [Array<String>] the annotation values
|
96
|
+
def values
|
97
|
+
annotations_hash.values.map(&:dup)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Return the annotation names.
|
101
|
+
#
|
102
|
+
# This has exactly the same behavior as {Hash#keys}, in that the
|
103
|
+
# returned keys are immutable, and modifications to the array have no
|
104
|
+
# effect.
|
105
|
+
#
|
106
|
+
# @return [Array<String, Symbol>] the annotation names
|
107
|
+
def keys
|
108
|
+
annotations_hash.keys
|
109
|
+
end
|
110
|
+
alias names keys
|
111
|
+
|
112
|
+
def to_a
|
113
|
+
to_h.to_a
|
114
|
+
end
|
115
|
+
|
116
|
+
|
72
117
|
# Set annotations from key,value pairs in `hash`.
|
73
118
|
#
|
74
119
|
# @note this is currently no more efficient than setting each
|
@@ -77,7 +122,9 @@ module Conjur
|
|
77
122
|
# @param [Hash, #each] hash
|
78
123
|
# @return [Conjur::Annotations] self
|
79
124
|
def merge! hash
|
80
|
-
hash.each
|
125
|
+
hash.each do |k, v|
|
126
|
+
self[k] = v unless self[k] == v
|
127
|
+
end
|
81
128
|
self
|
82
129
|
end
|
83
130
|
|
@@ -118,7 +165,6 @@ module Conjur
|
|
118
165
|
RestClient::Resource.new(Conjur::Authz::API.host, @resource.options)[path].put name: name, value: value
|
119
166
|
end
|
120
167
|
end
|
121
|
-
|
122
168
|
# @api private
|
123
169
|
# Our internal {Hash} of annotations. Lazily loaded.
|
124
170
|
def annotations_hash
|
data/lib/conjur/api.rb
CHANGED
@@ -60,18 +60,42 @@ class RestClient::Resource
|
|
60
60
|
}
|
61
61
|
end
|
62
62
|
|
63
|
+
# @api private
|
64
|
+
# @deprecated
|
65
|
+
# The account used by the core service. This is deprecated in favor of {Conjur.account} and
|
66
|
+
# {Conjur::Configuration#account}.
|
67
|
+
# @return [String] the core account
|
63
68
|
def core_conjur_account
|
64
69
|
Conjur::Core::API.conjur_account
|
65
70
|
end
|
66
|
-
|
71
|
+
|
72
|
+
# @api private
|
73
|
+
# This method exists so that all {RestClient::Resource}s support JSON serialization. It returns an
|
74
|
+
# empty hash.
|
75
|
+
# @return [Hash] the empty hash
|
67
76
|
def to_json(options = {})
|
68
77
|
{}
|
69
78
|
end
|
70
|
-
|
79
|
+
|
80
|
+
# Creates a Conjur API from this resource's authorization header.
|
81
|
+
#
|
82
|
+
# The new API is created using the token, so it will not be able to refresh
|
83
|
+
# when the token expires (after about 8 minutes). This is equivalent to creating
|
84
|
+
# an {Conjur::API} instance with {Conjur::API.new_from_token}.
|
85
|
+
#
|
86
|
+
# @return {Conjur::API} the new api
|
71
87
|
def conjur_api
|
72
88
|
Conjur::API.new_from_token token
|
73
89
|
end
|
74
|
-
|
90
|
+
|
91
|
+
# Get an authentication token from the clients Authorization header.
|
92
|
+
#
|
93
|
+
# Useful fields in the token include `"data"`, which holds the username for which the
|
94
|
+
# token was issued, and `"timestamp"`, which contains the time at which the token was issued.
|
95
|
+
# The token will expire 8 minutes after timestamp, but we recommend you treat the lifespan as
|
96
|
+
# about 5 minutes to account for time differences.
|
97
|
+
#
|
98
|
+
# @return [Hash] the parsed authentication token
|
75
99
|
def token
|
76
100
|
authorization = options[:headers][:authorization]
|
77
101
|
if authorization && authorization.to_s[/^Token token="(.*)"/]
|
@@ -81,6 +105,9 @@ class RestClient::Resource
|
|
81
105
|
end
|
82
106
|
end
|
83
107
|
|
108
|
+
# The username this resource authenticates as.
|
109
|
+
#
|
110
|
+
# @return [String] the username
|
84
111
|
def username
|
85
112
|
options[:user] || options[:username]
|
86
113
|
end
|
data/lib/conjur/api/deputies.rb
CHANGED
@@ -22,10 +22,34 @@ require 'conjur/deputy'
|
|
22
22
|
|
23
23
|
module Conjur
|
24
24
|
class API
|
25
|
+
#@!group Directory: Deputies
|
26
|
+
|
27
|
+
# @api internal
|
28
|
+
#
|
29
|
+
# Create a Conjur deputy.
|
30
|
+
#
|
31
|
+
# Deputies are used internally by Conjur services that need to perform
|
32
|
+
# actions as a particular role. While the deputies API is stable,
|
33
|
+
# it isn't intended for use by end users.
|
34
|
+
#
|
35
|
+
# @param [Hash] options options for deputy creation
|
36
|
+
# @option options [String] :id the *unqualified* id for the new deputy. If not present,
|
37
|
+
# the deputy will be given a randomly generated id.
|
38
|
+
# @return [Conjur::Deputy] the new deputy
|
39
|
+
# @raise [RestClient::Conflict] if a deputy already exists with the given id.
|
25
40
|
def create_deputy options = {}
|
26
41
|
standard_create Conjur::Core::API.host, :deputy, nil, options
|
27
42
|
end
|
28
|
-
|
43
|
+
|
44
|
+
# @api internal
|
45
|
+
#
|
46
|
+
# Find a Conjur deputy by id.
|
47
|
+
# Deputies are used internally by Conjur services that need to perform
|
48
|
+
# actions as a particular role. While the deputies API is stable,
|
49
|
+
# it isn't intended for use by end users.
|
50
|
+
#
|
51
|
+
# @param [String] id the deputy's *unqualified* id
|
52
|
+
# @return [Conjur::Deputy] the deputy, which may or may not exist.
|
29
53
|
def deputy id
|
30
54
|
standard_show Conjur::Core::API.host, :deputy, id
|
31
55
|
end
|
data/lib/conjur/api/resources.rb
CHANGED
@@ -22,18 +22,122 @@ require 'conjur/resource'
|
|
22
22
|
|
23
23
|
module Conjur
|
24
24
|
class API
|
25
|
+
|
26
|
+
#@!group Authorization: Resources
|
27
|
+
|
28
|
+
# Create a {http://developer.conjur.net/reference/services/authorization/resource Conjur Resource}.
|
29
|
+
# Resources are entities on which roles have permissions. A resource might represent a secret, a
|
30
|
+
# web service route, or be part of a higher level construct such as a user or group.
|
31
|
+
#
|
32
|
+
# If `:acting_as` is not present in `options`, you will be the owner of the new role. If it is present,
|
33
|
+
# your role must be a member of the given role (see {Conjur::Role#member_of?}).
|
34
|
+
#
|
35
|
+
# @example Create an abstract resource to represent a web service route
|
36
|
+
# # Notice that we can omit the account in the identifier
|
37
|
+
# service_resource = api.create_resource 'web-service:list-gadgets'
|
38
|
+
# service_resource.resource_id # => 'conjur:web-service:list-gadgets'
|
39
|
+
#
|
40
|
+
# # In a gatekeeper for the web service, we can use the resource to control access
|
41
|
+
# get '/gadgets' do
|
42
|
+
# # We'll assume that we've verified the Conjur authn token in the request, and stored the
|
43
|
+
# # corresponding identifier in `request_role_id`
|
44
|
+
# halt(403) unless api.resource('conjur:web-service:list-gadgets').permitted? 'read', request_role_id
|
45
|
+
# render_json find_gadgets
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# @example Create a role owned by another role
|
49
|
+
# alice = api.role('user:alice')
|
50
|
+
# api.current_role.member_of? alice # true, the operation will fail if this is false
|
51
|
+
# res = api.create_resource 'example:owned', acting_as: 'user:alice'
|
52
|
+
# res.owner # "conjur:user:alice"
|
53
|
+
#
|
54
|
+
# @param [String] identifier an id of the form `"<account>:<kind>:<id>"` or `"<kind>:<id>"`
|
55
|
+
# @param options [Hash] options for the request
|
56
|
+
# @option options [String, #role_id] :acting_as the role-ish thing or role id that will own the new resource
|
57
|
+
# @return [Conjur::Role] the new role
|
25
58
|
def create_resource(identifier, options = {})
|
26
59
|
resource(identifier).tap do |r|
|
27
60
|
r.create(options)
|
28
61
|
end
|
29
62
|
end
|
30
|
-
|
31
|
-
|
32
|
-
|
63
|
+
|
64
|
+
# Find a resource by it's id. The id given to this method must be qualified by a kind, but the account is
|
65
|
+
# optional.
|
66
|
+
#
|
67
|
+
# ### Permissions
|
68
|
+
#
|
69
|
+
# The resource **must** be visible to the current role. This is the case if the current role is the owner of
|
70
|
+
# the resource, or has any privilege on it.
|
71
|
+
#
|
72
|
+
# @example Find or create a resource
|
73
|
+
# def find_or_create_resource resource_id
|
74
|
+
# resource = api.resource resource_id
|
75
|
+
# unless resource.exists?
|
76
|
+
# resource = api.create_resource resource_id
|
77
|
+
# end
|
78
|
+
# resource
|
79
|
+
# end
|
80
|
+
#
|
81
|
+
# # ...
|
82
|
+
# example_resource = find_or_create_resource 'example:find-or-create'
|
83
|
+
# example_resource.exists? # always true
|
84
|
+
#
|
85
|
+
# @param identifier [String] a qualified resource identifier, optionally including an account
|
86
|
+
# @return [Conjur::Resource] the resource, which may or may not exist
|
87
|
+
def resource identifier
|
88
|
+
Resource.new(Conjur::Authz::API.host, credentials)[self.class.parse_resource_id(identifier).join('/')]
|
33
89
|
end
|
34
90
|
|
35
|
-
#
|
36
|
-
#
|
91
|
+
# Find all resources visible to the current role that match the given search criteria.
|
92
|
+
#
|
93
|
+
# ## Full Text Search
|
94
|
+
# Conjur supports full text search over the identifiers and annotation *values*
|
95
|
+
# of resources. For example, if `opts[:search]` is `"pubkeys"`, any resource with
|
96
|
+
# an id containing `"pubkeys"` or an annotation whose value contains `"pubkeys"` will match.
|
97
|
+
#
|
98
|
+
# **Notes**
|
99
|
+
# * Annotation *keys* are *not* indexed for full text search.
|
100
|
+
# * Conjur indexes the content of ids and annotation values by word.
|
101
|
+
# * Only resources visible to the current role (either owned by that role or
|
102
|
+
# having a privilege on it) are returned.
|
103
|
+
# * If you do not provide `:offset` or `:limit`, all records will be returned. For systems
|
104
|
+
# with a huge number of resources, you may want to paginate as shown in the example below.
|
105
|
+
# * If `:offset` is provided and `:limit` is not, 10 records starting at `:offset` will be
|
106
|
+
# returned. You may choose an arbitrarily large number for `:limit`, but the same performance
|
107
|
+
# considerations apply as when omitting `:offset` and `:limit`.
|
108
|
+
#
|
109
|
+
# @example Search for resources annotated with the text "WebService Route"
|
110
|
+
# webservice_routes = api.resources search: "WebService Route"
|
111
|
+
#
|
112
|
+
# # Check that it worked:
|
113
|
+
# webservice_routes.each do |resource|
|
114
|
+
# searchable = [resource.annotations.to_h.values, resource.resource_id]
|
115
|
+
# raise "FAILED" unless searchable.flatten.any?{|s| s.include? "WebService Route"}
|
116
|
+
# end
|
117
|
+
#
|
118
|
+
# @example Restrict the search to 'group' resources
|
119
|
+
# groups = api.resources kind: 'group'
|
120
|
+
#
|
121
|
+
# # Correct behavior:
|
122
|
+
# expect(groups.all?{|g| g.kind == 'group'}).to be_true
|
123
|
+
#
|
124
|
+
#
|
125
|
+
# @example Get every single resource in a performant way
|
126
|
+
# resources = []
|
127
|
+
# limit = 25
|
128
|
+
# offset = 0
|
129
|
+
# until (batch = api.resources limit: limit, offset: offset).empty?
|
130
|
+
# offset += batch.length
|
131
|
+
# resources.concat results
|
132
|
+
# end
|
133
|
+
# # do something with your resources
|
134
|
+
#
|
135
|
+
# @param opts [Hash] search criteria
|
136
|
+
# @option opts [String] :search find resources whose ids or annotations contain this string
|
137
|
+
# @option opts [String] :kind find resources whose `kind` matches this string
|
138
|
+
# @option opts [Integer] :limit the maximum number of records to return (Conjur may return fewer)
|
139
|
+
# @option opts [Integer] :offset offset of the first record to return
|
140
|
+
# @return [Array<Conjur::Resource>] the resources matching the criteria given
|
37
141
|
def resources opts = {}
|
38
142
|
opts = { host: Conjur::Authz::API.host, credentials: credentials }.merge opts
|
39
143
|
opts[:account] ||= Conjur.account
|