akeyless 2.20.1 → 2.20.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -3
  3. data/docs/AuthMethodRoleAssociation.md +2 -0
  4. data/docs/CreateAuthMethodOIDC.md +2 -0
  5. data/docs/CreateSecret.md +1 -1
  6. data/docs/DeleteItem.md +1 -1
  7. data/docs/ExportClassicKey.md +28 -0
  8. data/docs/ExportClassicKeyOutput.md +20 -0
  9. data/docs/GatewayCreateMigration.md +0 -8
  10. data/docs/GatewayUpdateMigration.md +0 -8
  11. data/docs/GetRotatedSecretValue.md +2 -0
  12. data/docs/GetSecretValue.md +2 -4
  13. data/docs/ListItems.md +2 -2
  14. data/docs/MigrationGeneral.md +3 -1
  15. data/docs/OIDCAccessRules.md +2 -0
  16. data/docs/ReverseRBACClient.md +0 -2
  17. data/docs/RotateSecret.md +1 -1
  18. data/docs/ShareItem.md +34 -0
  19. data/docs/SmInfo.md +3 -3
  20. data/docs/SraInfo.md +3 -3
  21. data/docs/UpdateAuthMethodOIDC.md +2 -0
  22. data/docs/UpdateItem.md +1 -1
  23. data/docs/UpdateSecretVal.md +1 -1
  24. data/docs/V2Api.md +125 -0
  25. data/docs/VaultlessTokenizerInfo.md +1 -1
  26. data/lib/akeyless/api/v2_api.rb +128 -0
  27. data/lib/akeyless/models/auth_method_role_association.rb +12 -1
  28. data/lib/akeyless/models/create_auth_method_oidc.rb +11 -1
  29. data/lib/akeyless/models/create_secret.rb +2 -0
  30. data/lib/akeyless/models/delete_item.rb +2 -0
  31. data/lib/akeyless/models/export_classic_key.rb +278 -0
  32. data/lib/akeyless/models/export_classic_key_output.rb +228 -0
  33. data/lib/akeyless/models/gateway_create_migration.rb +1 -39
  34. data/lib/akeyless/models/gateway_update_migration.rb +1 -39
  35. data/lib/akeyless/models/get_rotated_secret_value.rb +11 -1
  36. data/lib/akeyless/models/get_secret_value.rb +4 -11
  37. data/lib/akeyless/models/list_items.rb +3 -1
  38. data/lib/akeyless/models/migration_general.rb +13 -4
  39. data/lib/akeyless/models/oidc_access_rules.rb +11 -1
  40. data/lib/akeyless/models/reverse_rbac_client.rb +1 -12
  41. data/lib/akeyless/models/rotate_secret.rb +1 -1
  42. data/lib/akeyless/models/share_item.rb +316 -0
  43. data/lib/akeyless/models/sm_info.rb +8 -7
  44. data/lib/akeyless/models/sra_info.rb +8 -7
  45. data/lib/akeyless/models/update_auth_method_oidc.rb +11 -1
  46. data/lib/akeyless/models/update_item.rb +2 -0
  47. data/lib/akeyless/models/update_secret_val.rb +2 -0
  48. data/lib/akeyless/models/vaultless_tokenizer_info.rb +2 -4
  49. data/lib/akeyless/version.rb +1 -1
  50. data/lib/akeyless.rb +3 -2
  51. data/spec/models/export_classic_key_output_spec.rb +40 -0
  52. data/spec/models/export_classic_key_spec.rb +58 -0
  53. data/spec/models/share_item_spec.rb +82 -0
  54. metadata +531 -519
@@ -3987,6 +3987,70 @@ module Akeyless
3987
3987
  return data, status_code, headers
3988
3988
  end
3989
3989
 
3990
+ # @param body [ExportClassicKey]
3991
+ # @param [Hash] opts the optional parameters
3992
+ # @return [ExportClassicKeyOutput]
3993
+ def export_classic_key(body, opts = {})
3994
+ data, _status_code, _headers = export_classic_key_with_http_info(body, opts)
3995
+ data
3996
+ end
3997
+
3998
+ # @param body [ExportClassicKey]
3999
+ # @param [Hash] opts the optional parameters
4000
+ # @return [Array<(ExportClassicKeyOutput, Integer, Hash)>] ExportClassicKeyOutput data, response status code and response headers
4001
+ def export_classic_key_with_http_info(body, opts = {})
4002
+ if @api_client.config.debugging
4003
+ @api_client.config.logger.debug 'Calling API: V2Api.export_classic_key ...'
4004
+ end
4005
+ # verify the required parameter 'body' is set
4006
+ if @api_client.config.client_side_validation && body.nil?
4007
+ fail ArgumentError, "Missing the required parameter 'body' when calling V2Api.export_classic_key"
4008
+ end
4009
+ # resource path
4010
+ local_var_path = '/export-classic-key'
4011
+
4012
+ # query parameters
4013
+ query_params = opts[:query_params] || {}
4014
+
4015
+ # header parameters
4016
+ header_params = opts[:header_params] || {}
4017
+ # HTTP header 'Accept' (if needed)
4018
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
4019
+ # HTTP header 'Content-Type'
4020
+ content_type = @api_client.select_header_content_type(['application/json'])
4021
+ if !content_type.nil?
4022
+ header_params['Content-Type'] = content_type
4023
+ end
4024
+
4025
+ # form parameters
4026
+ form_params = opts[:form_params] || {}
4027
+
4028
+ # http body (model)
4029
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(body)
4030
+
4031
+ # return_type
4032
+ return_type = opts[:debug_return_type] || 'ExportClassicKeyOutput'
4033
+
4034
+ # auth_names
4035
+ auth_names = opts[:debug_auth_names] || []
4036
+
4037
+ new_options = opts.merge(
4038
+ :operation => :"V2Api.export_classic_key",
4039
+ :header_params => header_params,
4040
+ :query_params => query_params,
4041
+ :form_params => form_params,
4042
+ :body => post_body,
4043
+ :auth_names => auth_names,
4044
+ :return_type => return_type
4045
+ )
4046
+
4047
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
4048
+ if @api_client.config.debugging
4049
+ @api_client.config.logger.debug "API called: V2Api#export_classic_key\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
4050
+ end
4051
+ return data, status_code, headers
4052
+ end
4053
+
3990
4054
  # @param body [GatewayAddAllowedManagementAccess]
3991
4055
  # @param [Hash] opts the optional parameters
3992
4056
  # @return [Object]
@@ -11321,6 +11385,70 @@ module Akeyless
11321
11385
  return data, status_code, headers
11322
11386
  end
11323
11387
 
11388
+ # @param body [ShareItem]
11389
+ # @param [Hash] opts the optional parameters
11390
+ # @return [nil]
11391
+ def share_item(body, opts = {})
11392
+ share_item_with_http_info(body, opts)
11393
+ nil
11394
+ end
11395
+
11396
+ # @param body [ShareItem]
11397
+ # @param [Hash] opts the optional parameters
11398
+ # @return [Array<(nil, Integer, Hash)>] nil, response status code and response headers
11399
+ def share_item_with_http_info(body, opts = {})
11400
+ if @api_client.config.debugging
11401
+ @api_client.config.logger.debug 'Calling API: V2Api.share_item ...'
11402
+ end
11403
+ # verify the required parameter 'body' is set
11404
+ if @api_client.config.client_side_validation && body.nil?
11405
+ fail ArgumentError, "Missing the required parameter 'body' when calling V2Api.share_item"
11406
+ end
11407
+ # resource path
11408
+ local_var_path = '/share-item'
11409
+
11410
+ # query parameters
11411
+ query_params = opts[:query_params] || {}
11412
+
11413
+ # header parameters
11414
+ header_params = opts[:header_params] || {}
11415
+ # HTTP header 'Accept' (if needed)
11416
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
11417
+ # HTTP header 'Content-Type'
11418
+ content_type = @api_client.select_header_content_type(['application/json'])
11419
+ if !content_type.nil?
11420
+ header_params['Content-Type'] = content_type
11421
+ end
11422
+
11423
+ # form parameters
11424
+ form_params = opts[:form_params] || {}
11425
+
11426
+ # http body (model)
11427
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(body)
11428
+
11429
+ # return_type
11430
+ return_type = opts[:debug_return_type]
11431
+
11432
+ # auth_names
11433
+ auth_names = opts[:debug_auth_names] || []
11434
+
11435
+ new_options = opts.merge(
11436
+ :operation => :"V2Api.share_item",
11437
+ :header_params => header_params,
11438
+ :query_params => query_params,
11439
+ :form_params => form_params,
11440
+ :body => post_body,
11441
+ :auth_names => auth_names,
11442
+ :return_type => return_type
11443
+ )
11444
+
11445
+ data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
11446
+ if @api_client.config.debugging
11447
+ @api_client.config.logger.debug "API called: V2Api#share_item\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
11448
+ end
11449
+ return data, status_code, headers
11450
+ end
11451
+
11324
11452
  # @param body [SignJWTWithClassicKey]
11325
11453
  # @param [Hash] opts the optional parameters
11326
11454
  # @return [SignJWTOutput]
@@ -16,6 +16,8 @@ require 'time'
16
16
  module Akeyless
17
17
  # AuthMethodRoleAssociation includes details of an association between an auth method and a role.
18
18
  class AuthMethodRoleAssociation
19
+ attr_accessor :allowed_ops
20
+
19
21
  attr_accessor :assoc_id
20
22
 
21
23
  attr_accessor :auth_method_sub_claims
@@ -27,6 +29,7 @@ module Akeyless
27
29
  # Attribute mapping from ruby-style variable name to JSON key.
28
30
  def self.attribute_map
29
31
  {
32
+ :'allowed_ops' => :'allowed_ops',
30
33
  :'assoc_id' => :'assoc_id',
31
34
  :'auth_method_sub_claims' => :'auth_method_sub_claims',
32
35
  :'role_name' => :'role_name',
@@ -42,6 +45,7 @@ module Akeyless
42
45
  # Attribute type mapping.
43
46
  def self.openapi_types
44
47
  {
48
+ :'allowed_ops' => :'Array<String>',
45
49
  :'assoc_id' => :'String',
46
50
  :'auth_method_sub_claims' => :'Hash<String, Array<String>>',
47
51
  :'role_name' => :'String',
@@ -70,6 +74,12 @@ module Akeyless
70
74
  h[k.to_sym] = v
71
75
  }
72
76
 
77
+ if attributes.key?(:'allowed_ops')
78
+ if (value = attributes[:'allowed_ops']).is_a?(Array)
79
+ self.allowed_ops = value
80
+ end
81
+ end
82
+
73
83
  if attributes.key?(:'assoc_id')
74
84
  self.assoc_id = attributes[:'assoc_id']
75
85
  end
@@ -107,6 +117,7 @@ module Akeyless
107
117
  def ==(o)
108
118
  return true if self.equal?(o)
109
119
  self.class == o.class &&
120
+ allowed_ops == o.allowed_ops &&
110
121
  assoc_id == o.assoc_id &&
111
122
  auth_method_sub_claims == o.auth_method_sub_claims &&
112
123
  role_name == o.role_name &&
@@ -122,7 +133,7 @@ module Akeyless
122
133
  # Calculates hash code according to all attributes.
123
134
  # @return [Integer] Hash code
124
135
  def hash
125
- [assoc_id, auth_method_sub_claims, role_name, rules].hash
136
+ [allowed_ops, assoc_id, auth_method_sub_claims, role_name, rules].hash
126
137
  end
127
138
 
128
139
  # Builds the object from hash
@@ -22,6 +22,9 @@ module Akeyless
22
22
  # Allowed redirect URIs after the authentication
23
23
  attr_accessor :allowed_redirect_uri
24
24
 
25
+ # Audience claim to be used as part of the authentication flow. In case set, it must match the one configured on the Identity Provider's Application
26
+ attr_accessor :audience
27
+
25
28
  # A CIDR whitelist with the IPs that the access is restricted to
26
29
  attr_accessor :bound_ips
27
30
 
@@ -69,6 +72,7 @@ module Akeyless
69
72
  {
70
73
  :'access_expires' => :'access-expires',
71
74
  :'allowed_redirect_uri' => :'allowed-redirect-uri',
75
+ :'audience' => :'audience',
72
76
  :'bound_ips' => :'bound-ips',
73
77
  :'client_id' => :'client-id',
74
78
  :'client_secret' => :'client-secret',
@@ -96,6 +100,7 @@ module Akeyless
96
100
  {
97
101
  :'access_expires' => :'Integer',
98
102
  :'allowed_redirect_uri' => :'Array<String>',
103
+ :'audience' => :'String',
99
104
  :'bound_ips' => :'Array<String>',
100
105
  :'client_id' => :'String',
101
106
  :'client_secret' => :'String',
@@ -146,6 +151,10 @@ module Akeyless
146
151
  end
147
152
  end
148
153
 
154
+ if attributes.key?(:'audience')
155
+ self.audience = attributes[:'audience']
156
+ end
157
+
149
158
  if attributes.key?(:'bound_ips')
150
159
  if (value = attributes[:'bound_ips']).is_a?(Array)
151
160
  self.bound_ips = value
@@ -239,6 +248,7 @@ module Akeyless
239
248
  self.class == o.class &&
240
249
  access_expires == o.access_expires &&
241
250
  allowed_redirect_uri == o.allowed_redirect_uri &&
251
+ audience == o.audience &&
242
252
  bound_ips == o.bound_ips &&
243
253
  client_id == o.client_id &&
244
254
  client_secret == o.client_secret &&
@@ -264,7 +274,7 @@ module Akeyless
264
274
  # Calculates hash code according to all attributes.
265
275
  # @return [Integer] Hash code
266
276
  def hash
267
- [access_expires, allowed_redirect_uri, bound_ips, client_id, client_secret, force_sub_claims, gw_bound_ips, issuer, json, jwt_ttl, name, required_scopes, required_scopes_prefix, token, uid_token, unique_identifier].hash
277
+ [access_expires, allowed_redirect_uri, audience, bound_ips, client_id, client_secret, force_sub_claims, gw_bound_ips, issuer, json, jwt_ttl, name, required_scopes, required_scopes_prefix, token, uid_token, unique_identifier].hash
268
278
  end
269
279
 
270
280
  # Builds the object from hash
@@ -167,6 +167,8 @@ module Akeyless
167
167
 
168
168
  if attributes.key?(:'accessibility')
169
169
  self.accessibility = attributes[:'accessibility']
170
+ else
171
+ self.accessibility = 'regular'
170
172
  end
171
173
 
172
174
  if attributes.key?(:'delete_protection')
@@ -95,6 +95,8 @@ module Akeyless
95
95
 
96
96
  if attributes.key?(:'accessibility')
97
97
  self.accessibility = attributes[:'accessibility']
98
+ else
99
+ self.accessibility = 'regular'
98
100
  end
99
101
 
100
102
  if attributes.key?(:'delete_immediately')
@@ -0,0 +1,278 @@
1
+ =begin
2
+ #Akeyless API
3
+
4
+ #The purpose of this application is to provide access to Akeyless API.
5
+
6
+ The version of the OpenAPI document: 2.0
7
+ Contact: support@akeyless.io
8
+ Generated by: https://openapi-generator.tech
9
+ OpenAPI Generator version: 6.3.0-SNAPSHOT
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'time'
15
+
16
+ module Akeyless
17
+ # ExportClassicKey is a command that returns the classic key material
18
+ class ExportClassicKey
19
+ # Ignore Cache Retrieve the Secret value without checking the Gateway's cache. This flag is only relevant when using the RestAPI
20
+ attr_accessor :ignore_cache
21
+
22
+ # Set output format to JSON
23
+ attr_accessor :json
24
+
25
+ # ClassicKey name
26
+ attr_accessor :name
27
+
28
+ # Authentication token (see `/auth` and `/configure`)
29
+ attr_accessor :token
30
+
31
+ # The universal identity token, Required only for universal_identity authentication
32
+ attr_accessor :uid_token
33
+
34
+ # Classic key version
35
+ attr_accessor :version
36
+
37
+ # Attribute mapping from ruby-style variable name to JSON key.
38
+ def self.attribute_map
39
+ {
40
+ :'ignore_cache' => :'ignore-cache',
41
+ :'json' => :'json',
42
+ :'name' => :'name',
43
+ :'token' => :'token',
44
+ :'uid_token' => :'uid-token',
45
+ :'version' => :'version'
46
+ }
47
+ end
48
+
49
+ # Returns all the JSON keys this model knows about
50
+ def self.acceptable_attributes
51
+ attribute_map.values
52
+ end
53
+
54
+ # Attribute type mapping.
55
+ def self.openapi_types
56
+ {
57
+ :'ignore_cache' => :'String',
58
+ :'json' => :'Boolean',
59
+ :'name' => :'String',
60
+ :'token' => :'String',
61
+ :'uid_token' => :'String',
62
+ :'version' => :'Integer'
63
+ }
64
+ end
65
+
66
+ # List of attributes with nullable: true
67
+ def self.openapi_nullable
68
+ Set.new([
69
+ ])
70
+ end
71
+
72
+ # Initializes the object
73
+ # @param [Hash] attributes Model attributes in the form of hash
74
+ def initialize(attributes = {})
75
+ if (!attributes.is_a?(Hash))
76
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Akeyless::ExportClassicKey` initialize method"
77
+ end
78
+
79
+ # check to see if the attribute exists and convert string to symbol for hash key
80
+ attributes = attributes.each_with_object({}) { |(k, v), h|
81
+ if (!self.class.attribute_map.key?(k.to_sym))
82
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Akeyless::ExportClassicKey`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
83
+ end
84
+ h[k.to_sym] = v
85
+ }
86
+
87
+ if attributes.key?(:'ignore_cache')
88
+ self.ignore_cache = attributes[:'ignore_cache']
89
+ else
90
+ self.ignore_cache = 'false'
91
+ end
92
+
93
+ if attributes.key?(:'json')
94
+ self.json = attributes[:'json']
95
+ end
96
+
97
+ if attributes.key?(:'name')
98
+ self.name = attributes[:'name']
99
+ end
100
+
101
+ if attributes.key?(:'token')
102
+ self.token = attributes[:'token']
103
+ end
104
+
105
+ if attributes.key?(:'uid_token')
106
+ self.uid_token = attributes[:'uid_token']
107
+ end
108
+
109
+ if attributes.key?(:'version')
110
+ self.version = attributes[:'version']
111
+ end
112
+ end
113
+
114
+ # Show invalid properties with the reasons. Usually used together with valid?
115
+ # @return Array for valid properties with the reasons
116
+ def list_invalid_properties
117
+ invalid_properties = Array.new
118
+ if @name.nil?
119
+ invalid_properties.push('invalid value for "name", name cannot be nil.')
120
+ end
121
+
122
+ invalid_properties
123
+ end
124
+
125
+ # Check to see if the all the properties in the model are valid
126
+ # @return true if the model is valid
127
+ def valid?
128
+ return false if @name.nil?
129
+ true
130
+ end
131
+
132
+ # Checks equality by comparing each attribute.
133
+ # @param [Object] Object to be compared
134
+ def ==(o)
135
+ return true if self.equal?(o)
136
+ self.class == o.class &&
137
+ ignore_cache == o.ignore_cache &&
138
+ json == o.json &&
139
+ name == o.name &&
140
+ token == o.token &&
141
+ uid_token == o.uid_token &&
142
+ version == o.version
143
+ end
144
+
145
+ # @see the `==` method
146
+ # @param [Object] Object to be compared
147
+ def eql?(o)
148
+ self == o
149
+ end
150
+
151
+ # Calculates hash code according to all attributes.
152
+ # @return [Integer] Hash code
153
+ def hash
154
+ [ignore_cache, json, name, token, uid_token, version].hash
155
+ end
156
+
157
+ # Builds the object from hash
158
+ # @param [Hash] attributes Model attributes in the form of hash
159
+ # @return [Object] Returns the model itself
160
+ def self.build_from_hash(attributes)
161
+ new.build_from_hash(attributes)
162
+ end
163
+
164
+ # Builds the object from hash
165
+ # @param [Hash] attributes Model attributes in the form of hash
166
+ # @return [Object] Returns the model itself
167
+ def build_from_hash(attributes)
168
+ return nil unless attributes.is_a?(Hash)
169
+ attributes = attributes.transform_keys(&:to_sym)
170
+ self.class.openapi_types.each_pair do |key, type|
171
+ if attributes[self.class.attribute_map[key]].nil? && self.class.openapi_nullable.include?(key)
172
+ self.send("#{key}=", nil)
173
+ elsif type =~ /\AArray<(.*)>/i
174
+ # check to ensure the input is an array given that the attribute
175
+ # is documented as an array but the input is not
176
+ if attributes[self.class.attribute_map[key]].is_a?(Array)
177
+ self.send("#{key}=", attributes[self.class.attribute_map[key]].map { |v| _deserialize($1, v) })
178
+ end
179
+ elsif !attributes[self.class.attribute_map[key]].nil?
180
+ self.send("#{key}=", _deserialize(type, attributes[self.class.attribute_map[key]]))
181
+ end
182
+ end
183
+
184
+ self
185
+ end
186
+
187
+ # Deserializes the data based on type
188
+ # @param string type Data type
189
+ # @param string value Value to be deserialized
190
+ # @return [Object] Deserialized data
191
+ def _deserialize(type, value)
192
+ case type.to_sym
193
+ when :Time
194
+ Time.parse(value)
195
+ when :Date
196
+ Date.parse(value)
197
+ when :String
198
+ value.to_s
199
+ when :Integer
200
+ value.to_i
201
+ when :Float
202
+ value.to_f
203
+ when :Boolean
204
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
205
+ true
206
+ else
207
+ false
208
+ end
209
+ when :Object
210
+ # generic object (usually a Hash), return directly
211
+ value
212
+ when /\AArray<(?<inner_type>.+)>\z/
213
+ inner_type = Regexp.last_match[:inner_type]
214
+ value.map { |v| _deserialize(inner_type, v) }
215
+ when /\AHash<(?<k_type>.+?), (?<v_type>.+)>\z/
216
+ k_type = Regexp.last_match[:k_type]
217
+ v_type = Regexp.last_match[:v_type]
218
+ {}.tap do |hash|
219
+ value.each do |k, v|
220
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
221
+ end
222
+ end
223
+ else # model
224
+ # models (e.g. Pet) or oneOf
225
+ klass = Akeyless.const_get(type)
226
+ klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
227
+ end
228
+ end
229
+
230
+ # Returns the string representation of the object
231
+ # @return [String] String presentation of the object
232
+ def to_s
233
+ to_hash.to_s
234
+ end
235
+
236
+ # to_body is an alias to to_hash (backward compatibility)
237
+ # @return [Hash] Returns the object in the form of hash
238
+ def to_body
239
+ to_hash
240
+ end
241
+
242
+ # Returns the object in the form of hash
243
+ # @return [Hash] Returns the object in the form of hash
244
+ def to_hash
245
+ hash = {}
246
+ self.class.attribute_map.each_pair do |attr, param|
247
+ value = self.send(attr)
248
+ if value.nil?
249
+ is_nullable = self.class.openapi_nullable.include?(attr)
250
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
251
+ end
252
+
253
+ hash[param] = _to_hash(value)
254
+ end
255
+ hash
256
+ end
257
+
258
+ # Outputs non-array value in the form of hash
259
+ # For object, use to_hash. Otherwise, just return the value
260
+ # @param [Object] value Any valid value
261
+ # @return [Hash] Returns the value in the form of hash
262
+ def _to_hash(value)
263
+ if value.is_a?(Array)
264
+ value.compact.map { |v| _to_hash(v) }
265
+ elsif value.is_a?(Hash)
266
+ {}.tap do |hash|
267
+ value.each { |k, v| hash[k] = _to_hash(v) }
268
+ end
269
+ elsif value.respond_to? :to_hash
270
+ value.to_hash
271
+ else
272
+ value
273
+ end
274
+ end
275
+
276
+ end
277
+
278
+ end