google-cloud-storage 1.13.1 → 1.14.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.
@@ -16,10 +16,12 @@
16
16
  require "google/cloud/storage/bucket/acl"
17
17
  require "google/cloud/storage/bucket/list"
18
18
  require "google/cloud/storage/bucket/cors"
19
- require "google/cloud/storage/policy"
20
- require "google/cloud/storage/post_object"
19
+ require "google/cloud/storage/bucket/lifecycle"
20
+ require "google/cloud/storage/convert"
21
21
  require "google/cloud/storage/file"
22
22
  require "google/cloud/storage/notification"
23
+ require "google/cloud/storage/policy"
24
+ require "google/cloud/storage/post_object"
23
25
  require "pathname"
24
26
 
25
27
  module Google
@@ -39,6 +41,7 @@ module Google
39
41
  # file = bucket.file "path/to/my-file.ext"
40
42
  #
41
43
  class Bucket
44
+ include Convert
42
45
  ##
43
46
  # @private The Service object.
44
47
  attr_accessor :service
@@ -188,6 +191,73 @@ module Google
188
191
  cors_builder.freeze # always return frozen objects
189
192
  end
190
193
 
194
+ ##
195
+ # Returns the current Object Lifecycle Management rules configuration
196
+ # for the bucket.
197
+ #
198
+ # This method also accepts a block for updating the bucket's Object
199
+ # Lifecycle Management rules. See {Bucket::Lifecycle} for details.
200
+ #
201
+ # @see https://cloud.google.com/storage/docs/lifecycle Object
202
+ # Lifecycle Management
203
+ # @see https://cloud.google.com/storage/docs/managing-lifecycles
204
+ # Managing Object Lifecycles
205
+ #
206
+ # @yield [lifecycle] a block for setting Object Lifecycle Management
207
+ # rules
208
+ # @yieldparam [Bucket::Lifecycle] lifecycle the object accepting Object
209
+ # Lifecycle Management rules
210
+ #
211
+ # @return [Bucket::Lifecycle] The frozen builder object.
212
+ #
213
+ # @example Retrieving a bucket's lifecycle management rules.
214
+ # require "google/cloud/storage"
215
+ #
216
+ # storage = Google::Cloud::Storage.new
217
+ # bucket = storage.bucket "my-bucket"
218
+ #
219
+ # bucket.lifecycle.size #=> 2
220
+ # rule = bucket.lifecycle.first
221
+ # rule.action #=> "SetStorageClass"
222
+ # rule.storage_class #=> "COLDLINE"
223
+ # rule.age #=> 10
224
+ # rule.matches_storage_class #=> ["MULTI_REGIONAL", "REGIONAL"]
225
+ #
226
+ # @example Updating the bucket's lifecycle management rules in a block.
227
+ # require "google/cloud/storage"
228
+ #
229
+ # storage = Google::Cloud::Storage.new
230
+ # bucket = storage.bucket "my-bucket"
231
+ #
232
+ # bucket.update do |b|
233
+ # b.lifecycle do |l|
234
+ # # Remove the last rule from the array
235
+ # l.pop
236
+ # # Remove rules with the given condition
237
+ # l.delete_if do |r|
238
+ # r.matches_storage_class.include? "NEARLINE"
239
+ # end
240
+ # # Update rules
241
+ # l.each do |r|
242
+ # r.age = 90 if r.action == "Delete"
243
+ # end
244
+ # # Add a rule
245
+ # l.add_set_storage_class_rule "COLDLINE", age: 10
246
+ # end
247
+ # end
248
+ #
249
+ def lifecycle
250
+ lifecycle_builder = Bucket::Lifecycle.from_gapi @gapi.lifecycle
251
+ if block_given?
252
+ yield lifecycle_builder
253
+ if lifecycle_builder.changed?
254
+ @gapi.lifecycle = lifecycle_builder.to_gapi
255
+ patch_gapi! :lifecycle
256
+ end
257
+ end
258
+ lifecycle_builder.freeze # always return frozen objects
259
+ end
260
+
191
261
  ##
192
262
  # The location of the bucket.
193
263
  # Object data for objects in the bucket resides in physical
@@ -522,6 +592,7 @@ module Google
522
592
  # Add check for mutable cors
523
593
  updater.check_for_changed_labels!
524
594
  updater.check_for_mutable_cors!
595
+ updater.check_for_mutable_lifecycle!
525
596
  patch_gapi! updater.updates unless updater.updates.empty?
526
597
  end
527
598
 
@@ -1519,14 +1590,14 @@ module Google
1519
1590
  # require "google/cloud/storage"
1520
1591
  #
1521
1592
  # pubsub = Google::Cloud::Pubsub.new
1593
+ # storage = Google::Cloud::Storage.new
1594
+ #
1522
1595
  # topic = pubsub.create_topic "my-topic"
1523
1596
  # topic.policy do |p|
1524
1597
  # p.add "roles/pubsub.publisher",
1525
- # "serviceAccount:my-project" \
1526
- # "@gs-project-accounts.iam.gserviceaccount.com"
1598
+ # "serviceAccount:#{storage.service_account_email}"
1527
1599
  # end
1528
1600
  #
1529
- # storage = Google::Cloud::Storage.new
1530
1601
  # bucket = storage.bucket "my-bucket"
1531
1602
  #
1532
1603
  # notification = bucket.create_notification topic.name
@@ -1639,18 +1710,6 @@ module Google
1639
1710
  raise ArgumentError, "cannot find file #{file}"
1640
1711
  end
1641
1712
 
1642
- def storage_class_for str
1643
- return nil if str.nil?
1644
- { "durable_reduced_availability" => "DURABLE_REDUCED_AVAILABILITY",
1645
- "dra" => "DURABLE_REDUCED_AVAILABILITY",
1646
- "durable" => "DURABLE_REDUCED_AVAILABILITY",
1647
- "nearline" => "NEARLINE",
1648
- "coldline" => "COLDLINE",
1649
- "multi_regional" => "MULTI_REGIONAL",
1650
- "regional" => "REGIONAL",
1651
- "standard" => "STANDARD" }[str.to_s.downcase] || str.to_s
1652
- end
1653
-
1654
1713
  ##
1655
1714
  # Yielded to a block to accumulate changes for a patch request.
1656
1715
  class Updater < Bucket
@@ -1662,6 +1721,7 @@ module Google
1662
1721
  @gapi = gapi
1663
1722
  @labels = @gapi.labels.to_h.dup
1664
1723
  @cors_builder = nil
1724
+ @lifecycle_builder = nil
1665
1725
  end
1666
1726
 
1667
1727
  ##
@@ -1708,6 +1768,22 @@ module Google
1708
1768
  patch_gapi! :cors_configurations
1709
1769
  end
1710
1770
 
1771
+ def lifecycle
1772
+ # Same as Bucket#lifecycle, but not frozen
1773
+ @lifecycle_builder ||= Bucket::Lifecycle.from_gapi @gapi.lifecycle
1774
+ yield @lifecycle_builder if block_given?
1775
+ @lifecycle_builder
1776
+ end
1777
+
1778
+ ##
1779
+ # @private Make sure any lifecycle changes are saved
1780
+ def check_for_mutable_lifecycle!
1781
+ return if @lifecycle_builder.nil?
1782
+ return unless @lifecycle_builder.changed?
1783
+ @gapi.lifecycle = @lifecycle_builder.to_gapi
1784
+ patch_gapi! :lifecycle
1785
+ end
1786
+
1711
1787
  protected
1712
1788
 
1713
1789
  ##
@@ -46,6 +46,19 @@ module Google
46
46
  # max_age: 3600
47
47
  # end
48
48
  #
49
+ # @example Retrieving the bucket's CORS rules.
50
+ # require "google/cloud/storage"
51
+ #
52
+ # storage = Google::Cloud::Storage.new
53
+ #
54
+ # bucket = storage.bucket "my-bucket"
55
+ # bucket.cors.size #=> 2
56
+ # rule = bucket.cors.first
57
+ # rule.origin #=> ["http://example.org"]
58
+ # rule.methods #=> ["GET","POST","DELETE"]
59
+ # rule.headers #=> ["X-My-Custom-Header"]
60
+ # rule.max_age #=> 3600
61
+ #
49
62
  class Cors < DelegateClass(::Array)
50
63
  ##
51
64
  # @private Initialize a new CORS rules builder with existing CORS
@@ -118,9 +131,50 @@ module Google
118
131
  super
119
132
  end
120
133
 
134
+ ##
135
+ # # Bucket Cors Rule
136
+ #
137
+ # Represents a website CORS rule for a bucket. Accessed via
138
+ # {Bucket#cors}.
139
+ #
140
+ # @see https://cloud.google.com/storage/docs/cross-origin Cross-Origin
141
+ # Resource Sharing (CORS)
142
+ #
143
+ # @attr [String] origin The [origin](http://tools.ietf.org/html/rfc6454)
144
+ # or origins permitted for cross origin resource sharing with the
145
+ # bucket. Note: "*" is permitted in the list of origins, and means
146
+ # "any Origin".
147
+ # @attr [String] methods The list of HTTP methods permitted in cross
148
+ # origin resource sharing with the bucket. (GET, OPTIONS, POST, etc)
149
+ # Note: "*" is permitted in the list of methods, and means
150
+ # "any method".
151
+ # @attr [String] headers The list of header field names to send in the
152
+ # Access-Control-Allow-Headers header in the preflight response.
153
+ # Indicates the custom request headers that may be used in the
154
+ # actual request.
155
+ # @attr [String] max_age The value to send in the
156
+ # Access-Control-Max-Age header in the preflight response. Indicates
157
+ # how many seconds the results of a preflight request can be cached
158
+ # in a preflight result cache. The default value is `1800` (30
159
+ # minutes.)
160
+ #
161
+ # @example Retrieving the bucket's CORS rules.
162
+ # require "google/cloud/storage"
163
+ #
164
+ # storage = Google::Cloud::Storage.new
165
+ #
166
+ # bucket = storage.bucket "my-bucket"
167
+ # bucket.cors.size #=> 2
168
+ # rule = bucket.cors.first
169
+ # rule.origin #=> ["http://example.org"]
170
+ # rule.methods #=> ["GET","POST","DELETE"]
171
+ # rule.headers #=> ["X-My-Custom-Header"]
172
+ # rule.max_age #=> 3600
173
+ #
121
174
  class Rule
122
175
  attr_accessor :origin, :methods, :headers, :max_age
123
176
 
177
+ # @private
124
178
  def initialize origin, methods, headers: nil, max_age: nil
125
179
  @origin = Array(origin)
126
180
  @methods = Array(methods)
@@ -128,6 +182,7 @@ module Google
128
182
  @max_age = (max_age || 1800)
129
183
  end
130
184
 
185
+ # @private
131
186
  def to_gapi
132
187
  Google::Apis::StorageV1::Bucket::CorsConfiguration.new(
133
188
  origin: Array(origin).dup, http_method: Array(methods).dup,
@@ -135,12 +190,14 @@ module Google
135
190
  )
136
191
  end
137
192
 
193
+ # @private
138
194
  def self.from_gapi gapi
139
195
  new gapi.origin.dup, gapi.http_method.dup, \
140
196
  headers: gapi.response_header.dup,
141
197
  max_age: gapi.max_age_seconds
142
198
  end
143
199
 
200
+ # @private
144
201
  def freeze
145
202
  @origin.freeze
146
203
  @methods.freeze
@@ -0,0 +1,355 @@
1
+ # Copyright 2018 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require "delegate"
17
+ require "google/cloud/storage/convert"
18
+
19
+ module Google
20
+ module Cloud
21
+ module Storage
22
+ class Bucket
23
+ ##
24
+ # # Bucket Lifecycle
25
+ #
26
+ # A special-case Array for managing the Object Lifecycle Management
27
+ # rules for a bucket. Accessed via {Bucket#lifecycle}.
28
+ #
29
+ # @see https://cloud.google.com/storage/docs/lifecycle Object
30
+ # Lifecycle Management
31
+ # @see https://cloud.google.com/storage/docs/managing-lifecycles
32
+ # Managing Object Lifecycles
33
+ #
34
+ # @example Specifying the lifecycle management rules for a new bucket.
35
+ # require "google/cloud/storage"
36
+ #
37
+ # storage = Google::Cloud::Storage.new
38
+ #
39
+ # bucket = storage.create_bucket "my-bucket" do |b|
40
+ # b.lifecycle.add_set_storage_class_rule "COLDLINE", age: 10
41
+ # b.lifecycle.add_delete_rule age: 30, is_live: false
42
+ # end
43
+ #
44
+ # @example Retrieving a bucket's lifecycle management rules.
45
+ # require "google/cloud/storage"
46
+ #
47
+ # storage = Google::Cloud::Storage.new
48
+ # bucket = storage.bucket "my-bucket"
49
+ #
50
+ # bucket.lifecycle.size #=> 2
51
+ # rule = bucket.lifecycle.first
52
+ # rule.action #=> "SetStorageClass"
53
+ # rule.storage_class #=> "COLDLINE"
54
+ # rule.age #=> 10
55
+ # rule.matches_storage_class #=> ["MULTI_REGIONAL", "REGIONAL"]
56
+ #
57
+ # @example Updating the bucket's lifecycle management rules in a block.
58
+ # require "google/cloud/storage"
59
+ #
60
+ # storage = Google::Cloud::Storage.new
61
+ # bucket = storage.bucket "my-bucket"
62
+ #
63
+ # bucket.lifecycle do |l|
64
+ # # Remove the last rule from the array
65
+ # l.pop
66
+ # # Remove all rules with the given condition
67
+ # l.delete_if do |r|
68
+ # r.matches_storage_class.include? "NEARLINE"
69
+ # end
70
+ # l.add_set_storage_class_rule "COLDLINE", age: 10, is_live: true
71
+ # l.add_delete_rule age: 30, is_live: false
72
+ # end
73
+ #
74
+ class Lifecycle < DelegateClass(::Array)
75
+ include Convert
76
+ ##
77
+ # @private Initialize a new lifecycle rules builder with existing
78
+ # lifecycle rules, if any.
79
+ def initialize rules = []
80
+ super rules
81
+ @original = to_gapi.rule.map(&:to_json)
82
+ end
83
+
84
+ # @private
85
+ def changed?
86
+ @original != to_gapi.rule.map(&:to_json)
87
+ end
88
+
89
+ ##
90
+ # Adds a SetStorageClass lifecycle rule to the Object Lifecycle
91
+ # Management rules for a bucket.
92
+ #
93
+ # @see https://cloud.google.com/storage/docs/lifecycle Object
94
+ # Lifecycle Management
95
+ # @see https://cloud.google.com/storage/docs/managing-lifecycles
96
+ # Managing Object Lifecycles
97
+ #
98
+ # @param [String,Symbol] storage_class The target storage class.
99
+ # Required if the type of the action is `SetStorageClass`. The
100
+ # argument will be converted from symbols and lower-case to
101
+ # upper-case strings.
102
+ # @param [Integer] age The age of a file (in days). This condition is
103
+ # satisfied when a file reaches the specified age.
104
+ # @param [String,Date] created_before A date in RFC 3339 format with
105
+ # only the date part (for instance, "2013-01-15"). This condition is
106
+ # satisfied when a file is created before midnight of the specified
107
+ # date in UTC.
108
+ # @param [Boolean] is_live Relevant only for versioned files. If the
109
+ # value is `true`, this condition matches live files; if the value
110
+ # is `false`, it matches archived files.
111
+ # @param [String,Symbol,Array<String,Symbol>] matches_storage_class
112
+ # Files having any of the storage classes specified by this
113
+ # condition will be matched. Values include `MULTI_REGIONAL`,
114
+ # `REGIONAL`, `NEARLINE`, `COLDLINE`, `STANDARD`, and
115
+ # `DURABLE_REDUCED_AVAILABILITY`. Arguments will be converted from
116
+ # symbols and lower-case to upper-case strings.
117
+ # @param [Integer] num_newer_versions Relevant only for versioned
118
+ # files. If the value is N, this condition is satisfied when there
119
+ # are at least N versions (including the live version) newer than
120
+ # this version of the file.
121
+ #
122
+ # @example
123
+ # require "google/cloud/storage"
124
+ #
125
+ # storage = Google::Cloud::Storage.new
126
+ #
127
+ # bucket = storage.create_bucket "my-bucket" do |b|
128
+ # b.lifecycle.add_set_storage_class_rule "COLDLINE", age: 10
129
+ # end
130
+ #
131
+ def add_set_storage_class_rule storage_class, age: nil,
132
+ created_before: nil, is_live: nil,
133
+ matches_storage_class: nil,
134
+ num_newer_versions: nil
135
+ push Rule.new \
136
+ "SetStorageClass",
137
+ storage_class: storage_class_for(storage_class),
138
+ age: age, created_before: created_before, is_live: is_live,
139
+ matches_storage_class: storage_class_for(matches_storage_class),
140
+ num_newer_versions: num_newer_versions
141
+ end
142
+
143
+ ##
144
+ # Adds a SetStorageClass lifecycle rule to the Object Lifecycle
145
+ # Management rules for a bucket.
146
+ #
147
+ # @see https://cloud.google.com/storage/docs/lifecycle Object
148
+ # Lifecycle Management
149
+ # @see https://cloud.google.com/storage/docs/managing-lifecycles
150
+ # Managing Object Lifecycles
151
+ #
152
+ # @param [Integer] age The age of a file (in days). This condition is
153
+ # satisfied when a file reaches the specified age.
154
+ # @param [String,Date] created_before A date in RFC 3339 format with
155
+ # only the date part (for instance, "2013-01-15"). This condition is
156
+ # satisfied when a file is created before midnight of the specified
157
+ # date in UTC.
158
+ # @param [Boolean] is_live Relevant only for versioned files. If the
159
+ # value is `true`, this condition matches live files; if the value
160
+ # is `false`, it matches archived files.
161
+ # @param [String,Symbol,Array<String,Symbol>] matches_storage_class
162
+ # Files having any of the storage classes specified by this
163
+ # condition will be matched. Values include `MULTI_REGIONAL`,
164
+ # `REGIONAL`, `NEARLINE`, `COLDLINE`, `STANDARD`, and
165
+ # `DURABLE_REDUCED_AVAILABILITY`. Arguments will be converted from
166
+ # symbols and lower-case to upper-case strings.
167
+ # @param [Integer] num_newer_versions Relevant only for versioned
168
+ # files. If the value is N, this condition is satisfied when there
169
+ # are at least N versions (including the live version) newer than
170
+ # this version of the file.
171
+ #
172
+ # @example
173
+ # require "google/cloud/storage"
174
+ #
175
+ # storage = Google::Cloud::Storage.new
176
+ #
177
+ # bucket = storage.create_bucket "my-bucket" do |b|
178
+ # b.lifecycle.add_delete_rule age: 30, is_live: false
179
+ # end
180
+ #
181
+ def add_delete_rule age: nil, created_before: nil, is_live: nil,
182
+ matches_storage_class: nil,
183
+ num_newer_versions: nil
184
+ push Rule.new \
185
+ "Delete",
186
+ age: age, created_before: created_before, is_live: is_live,
187
+ matches_storage_class: storage_class_for(matches_storage_class),
188
+ num_newer_versions: num_newer_versions
189
+ end
190
+
191
+ # @private
192
+ def to_gapi
193
+ Google::Apis::StorageV1::Bucket::Lifecycle.new(
194
+ rule: map(&:to_gapi)
195
+ )
196
+ end
197
+
198
+ # @private
199
+ def self.from_gapi gapi
200
+ gapi_list = gapi.rule if gapi
201
+ rules = Array(gapi_list).map do |rule_gapi|
202
+ Rule.from_gapi rule_gapi
203
+ end
204
+ new rules
205
+ end
206
+
207
+ # @private
208
+ def freeze
209
+ each(&:freeze)
210
+ super
211
+ end
212
+
213
+ ##
214
+ # # Bucket Lifecycle Rule
215
+ #
216
+ # Represents an Object Lifecycle Management rule for a bucket. The
217
+ # action for the rule will be taken when its conditions are met.
218
+ # Accessed via {Bucket#lifecycle}.
219
+ #
220
+ # @see https://cloud.google.com/storage/docs/lifecycle Object
221
+ # Lifecycle Management
222
+ # @see https://cloud.google.com/storage/docs/managing-lifecycles
223
+ # Managing Object Lifecycles
224
+ #
225
+ # @attr [String] action The type of action taken when the rule's
226
+ # conditions are met. Currently, only `Delete` and `SetStorageClass`
227
+ # are supported.
228
+ # @attr [String] storage_class The target storage class for the
229
+ # action. Required only if the action is `SetStorageClass`.
230
+ # @attr [Integer] age The age of a file (in days). This condition is
231
+ # satisfied when a file reaches the specified age.
232
+ # @attr [String,Date] created_before A date in RFC 3339 format with
233
+ # only the date part (for instance, "2013-01-15"). This condition is
234
+ # satisfied when a file is created before midnight of the specified
235
+ # date in UTC.
236
+ # @attr [Boolean] is_live Relevant only for versioned files. If the
237
+ # value is `true`, this condition matches live files; if the value
238
+ # is `false`, it matches archived files.
239
+ # @attr [Array<String>] matches_storage_class Files having any of the
240
+ # storage classes specified by this condition will be matched.
241
+ # Values include `MULTI_REGIONAL`, `REGIONAL`, `NEARLINE`,
242
+ # `COLDLINE`, `STANDARD`, and `DURABLE_REDUCED_AVAILABILITY`.
243
+ # @attr [Integer] num_newer_versions Relevant only for versioned
244
+ # files. If the value is N, this condition is satisfied when there
245
+ # are at least N versions (including the live version) newer than
246
+ # this version of the file.
247
+ #
248
+ # @example Retrieving a bucket's lifecycle management rules.
249
+ # require "google/cloud/storage"
250
+ #
251
+ # storage = Google::Cloud::Storage.new
252
+ # bucket = storage.bucket "my-bucket"
253
+ #
254
+ # bucket.lifecycle.size #=> 2
255
+ # rule = bucket.lifecycle.first
256
+ # rule.action #=> "SetStorageClass"
257
+ # rule.storage_class #=> "COLDLINE"
258
+ # rule.age #=> 10
259
+ # rule.matches_storage_class #=> ["MULTI_REGIONAL", "REGIONAL"]
260
+ #
261
+ # @example Updating the bucket's lifecycle rules in a block.
262
+ # require "google/cloud/storage"
263
+ #
264
+ # storage = Google::Cloud::Storage.new
265
+ # bucket = storage.bucket "my-bucket"
266
+ #
267
+ # bucket.update do |b|
268
+ # b.lifecycle do |l|
269
+ # # Remove the last rule from the array
270
+ # l.pop
271
+ # # Remove rules with the given condition
272
+ # l.delete_if do |r|
273
+ # r.matches_storage_class.include? "NEARLINE"
274
+ # end
275
+ # # Update rules
276
+ # l.each do |r|
277
+ # r.age = 90 if r.action == "Delete"
278
+ # end
279
+ # # Add a rule
280
+ # l.add_set_storage_class_rule "COLDLINE", age: 10
281
+ # end
282
+ # end
283
+ #
284
+ class Rule
285
+ attr_accessor :action, :storage_class, :age, :created_before,
286
+ :is_live, :matches_storage_class, :num_newer_versions
287
+
288
+ # @private
289
+ def initialize action, storage_class: nil, age: nil,
290
+ created_before: nil, is_live: nil,
291
+ matches_storage_class: nil, num_newer_versions: nil
292
+ @action = action
293
+ @storage_class = storage_class
294
+ @age = age
295
+ @created_before = created_before
296
+ @is_live = is_live
297
+ @matches_storage_class = Array(matches_storage_class)
298
+ @num_newer_versions = num_newer_versions
299
+ end
300
+
301
+ # @private
302
+ # @return [Google::Apis::StorageV1::Bucket::Lifecycle]
303
+ def to_gapi
304
+ condition = condition_gapi(age, created_before, is_live,
305
+ matches_storage_class,
306
+ num_newer_versions)
307
+ Google::Apis::StorageV1::Bucket::Lifecycle::Rule.new(
308
+ action: action_gapi(action, storage_class),
309
+ condition: condition
310
+ )
311
+ end
312
+
313
+ # @private
314
+ def action_gapi action, storage_class
315
+ Google::Apis::StorageV1::Bucket::Lifecycle::Rule::Action.new(
316
+ type: action, storage_class: storage_class
317
+ )
318
+ end
319
+
320
+ # @private
321
+ def condition_gapi age, created_before, is_live,
322
+ matches_storage_class, num_newer_versions
323
+ Google::Apis::StorageV1::Bucket::Lifecycle::Rule::Condition.new(
324
+ age: age,
325
+ created_before: created_before,
326
+ is_live: is_live,
327
+ matches_storage_class: Array(matches_storage_class),
328
+ num_newer_versions: num_newer_versions
329
+ )
330
+ end
331
+
332
+ # @private
333
+ # @param [Google::Apis::StorageV1::Bucket::Rule] gapi
334
+ def self.from_gapi gapi
335
+ action = gapi.action
336
+ c = gapi.condition
337
+ new action.type, storage_class: action.storage_class,
338
+ age: c.age,
339
+ created_before: c.created_before,
340
+ is_live: c.is_live,
341
+ matches_storage_class: c.matches_storage_class,
342
+ num_newer_versions: c.num_newer_versions
343
+ end
344
+
345
+ # @private
346
+ def freeze
347
+ @matches_storage_class.freeze
348
+ super
349
+ end
350
+ end
351
+ end
352
+ end
353
+ end
354
+ end
355
+ end