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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/CHANGELOG.md +4 -0
  4. data/lib/conjur-api/version.rb +1 -1
  5. data/lib/conjur/acts_as_asset.rb +44 -3
  6. data/lib/conjur/acts_as_resource.rb +53 -4
  7. data/lib/conjur/acts_as_user.rb +17 -7
  8. data/lib/conjur/annotations.rb +49 -3
  9. data/lib/conjur/api.rb +30 -3
  10. data/lib/conjur/api/deputies.rb +25 -1
  11. data/lib/conjur/api/resources.rb +109 -5
  12. data/lib/conjur/api/roles.rb +103 -11
  13. data/lib/conjur/api/secrets.rb +16 -1
  14. data/lib/conjur/api/users.rb +65 -1
  15. data/lib/conjur/api/variables.rb +65 -1
  16. data/lib/conjur/audit-api.rb +3 -0
  17. data/lib/conjur/authn-api.rb +4 -0
  18. data/lib/conjur/authz-api.rb +4 -0
  19. data/lib/conjur/base.rb +31 -30
  20. data/lib/conjur/build_from_response.rb +11 -0
  21. data/lib/conjur/cast.rb +5 -1
  22. data/lib/conjur/core-api.rb +22 -2
  23. data/lib/conjur/deputy.rb +19 -2
  24. data/lib/conjur/env.rb +18 -3
  25. data/lib/conjur/escape.rb +65 -4
  26. data/lib/conjur/event_source.rb +15 -2
  27. data/lib/conjur/graph.rb +103 -12
  28. data/lib/conjur/has_id.rb +13 -1
  29. data/lib/conjur/has_identifier.rb +9 -6
  30. data/lib/conjur/has_owner.rb +21 -7
  31. data/lib/conjur/host.rb +8 -0
  32. data/lib/conjur/layer-api.rb +4 -0
  33. data/lib/conjur/layer.rb +50 -3
  34. data/lib/conjur/log.rb +22 -2
  35. data/lib/conjur/log_source.rb +27 -0
  36. data/lib/conjur/path_based.rb +47 -2
  37. data/lib/conjur/pubkeys-api.rb +12 -0
  38. data/lib/conjur/role.rb +220 -9
  39. data/lib/conjur/role_grant.rb +50 -2
  40. data/lib/conjur/secret.rb +9 -1
  41. data/lib/conjur/standard_methods.rb +31 -3
  42. data/lib/conjur/user.rb +55 -3
  43. data/spec/lib/role_spec.rb +1 -2
  44. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fa094471717dc9bb39477d76468d2663895d9fd4
4
- data.tar.gz: d688adf16203e25c50646994bc619170d5633b89
3
+ metadata.gz: 5364b2c4521be8b3f6b3fce20269873ac72a5ec8
4
+ data.tar.gz: e4e22c72cae8780bfe0263525156e5c57c0d5510
5
5
  SHA512:
6
- metadata.gz: 434da500b0bb392deb9f0e8380dab357394aa2b16f28bb5063f2619a484646c1a1912267ee48eed7e3cea4d9e88ac256e23c466f6bd25faf1123294cce68af58
7
- data.tar.gz: d9097541c2faff292c2f2c201a5b2d7dac162ca4c023b45d52093215acb310a17ce295762dc221d3a7c2952554c0efff59b911518853eea4282feca61648e330
6
+ metadata.gz: 982cbf720ebb14461e0868a0c8281d14a6561b5335004270780ff45e393fbe93f5ddd755b60c127ab90aedf9b3f051a01f16b1bcb2a733293cb7199ef4f1f766
7
+ data.tar.gz: 9fbb761715f485f823b20a4493a53a753bca25d1217632c126bc03ced49fab69bb81922bb132dbaebb49d2e81c901f8567c9c26683031448214101725e86aad1
data/.gitignore CHANGED
@@ -23,3 +23,6 @@ tmp
23
23
 
24
24
  # rspec
25
25
  .rspec
26
+
27
+ # Script to connect to jon's lxc appliances
28
+ lxcsh.rb
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ # v4.15.0
2
+ * Extensive documentation improvements
3
+ * A few additional methoods, for example `Conjur::API#public_key_names`.
4
+
1
5
  # v4.14.0
2
6
 
3
7
  * Bump rest-client version, remove the troublesome mime-types patch
@@ -19,6 +19,6 @@
19
19
 
20
20
  module Conjur
21
21
  class API
22
- VERSION = "4.14.0"
22
+ VERSION = "4.15.0"
23
23
  end
24
24
  end
@@ -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
@@ -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
- def self.included(base)
24
- base.instance_eval do
25
- include ActsAsRole
26
- end
27
- end
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
@@ -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{|k,v| self[k] = v }
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
@@ -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
@@ -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
- def resource resource
32
- Resource.new(Conjur::Authz::API.host, credentials)[self.class.parse_resource_id(resource).join('/')]
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
- # Return all visible resources.
36
- # In opts you should pass an account to filter by, and optionally a kind.
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