conjur-api 4.14.0 → 4.15.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|