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.
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