cloud_storage/resources/bucket.rs
1use crate::resources::{
2 bucket_access_control::{BucketAccessControl, NewBucketAccessControl},
3 default_object_access_control::{DefaultObjectAccessControl, NewDefaultObjectAccessControl},
4};
5pub use crate::resources::{common::Entity, location::*};
6
7/// The Buckets resource represents a
8/// [bucket](https://cloud.google.com/storage/docs/key-terms#buckets) in Google Cloud Storage. There
9/// is a single global namespace shared by all buckets. For more information, see
10/// [Bucket Name Requirements](https://cloud.google.com/storage/docs/naming#requirements).
11///
12/// Buckets contain objects which can be accessed by their own methods. In addition to the
13/// [ACL property](https://cloud.google.com/storage/docs/access-control/lists), buckets contain
14/// `BucketAccessControls`, for use in fine-grained manipulation of an existing bucket's access
15/// controls.
16///
17/// A bucket is always owned by the project team owners group.
18#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
19#[serde(rename_all = "camelCase")]
20pub struct Bucket {
21 /// The kind of item this is. For buckets, this is always `storage#bucket`.
22 pub kind: String,
23 /// The ID of the bucket. For buckets, the `id` and `name` properties are the same.
24 pub id: String, // should be u64, mumble mumble
25 /// The URI of this bucket.
26 pub self_link: String,
27 /// The project number of the project the bucket belongs to.
28 #[serde(deserialize_with = "crate::from_str")]
29 pub project_number: u64,
30 /// The name of the bucket.
31 pub name: String,
32 /// The creation time of the bucket in RFC 3339 format.
33 pub time_created: chrono::DateTime<chrono::Utc>,
34 /// The modification time of the bucket in RFC 3339 format.
35 pub updated: chrono::DateTime<chrono::Utc>,
36 /// Whether or not to automatically apply an eventBasedHold to new objects added to the bucket.
37 pub default_event_based_hold: Option<bool>,
38 /// The bucket's retention policy, which defines the minimum age an object in the bucket must
39 /// reach before it can be deleted or overwritten.
40 pub retention_policy: Option<RetentionPolicy>,
41 /// The metadata generation of this bucket.
42 #[serde(deserialize_with = "crate::from_str")]
43 pub metageneration: i64,
44 /// Access controls on the bucket, containing one or more bucketAccessControls Resources. If
45 /// iamConfiguration.uniformBucketLevelAccess.enabled is set to true, this field is omitted in
46 /// responses, and requests that specify this field fail with a 400 Bad Request response.
47 pub acl: Option<Vec<BucketAccessControl>>,
48 /// Default access controls to apply to new objects when no ACL is provided. This list contains
49 /// one or more defaultObjectAccessControls Resources. If
50 /// iamConfiguration.uniformBucketLevelAccess.enabled is set to true, this field is omitted in
51 /// responses, and requests that specify this field fail.
52 pub default_object_acl: Option<Vec<DefaultObjectAccessControl>>,
53 /// The bucket's IAM configuration.
54 pub iam_configuration: Option<IamConfiguration>,
55 /// Encryption configuration for a bucket.
56 pub encryption: Option<Encryption>,
57 /// The owner of the bucket. This is always the project team's owner group.
58 pub owner: Option<Owner>,
59 /// The location of the bucket. Object data for objects in the bucket resides in physical
60 /// storage within this region. Defaults to US. See Cloud Storage bucket locations for the
61 /// authoritative list.
62 pub location: Location,
63 /// The type of location that the bucket resides in, as determined by the location property.
64 pub location_type: String,
65 /// The bucket's website configuration, controlling how the service behaves when accessing
66 /// bucket contents as a web site. See the Static Website Examples for more information.
67 pub website: Option<Website>,
68 /// The bucket's logging configuration, which defines the destination bucket and optional name
69 /// prefix for the current bucket's logs.
70 pub logging: Option<Logging>,
71 /// The bucket's versioning configuration.
72 pub versioning: Option<Versioning>,
73 /// The bucket's Cross-Origin Resource Sharing (CORS) configuration.
74 pub cors: Option<Vec<Cors>>,
75 /// The bucket's lifecycle configuration. See
76 /// [lifecycle management](https://cloud.google.com/storage/docs/lifecycle) for more
77 /// information.
78 pub lifecycle: Option<Lifecycle>,
79 /// User-provided bucket labels, in key/value pairs.
80 pub labels: Option<std::collections::HashMap<String, String>>,
81 /// The bucket's default storage class, used whenever no storageClass is specified for a
82 /// newly-created object. If storageClass is not specified when the bucket
83 /// is created, it defaults to STANDARD. For more information, see storage classes.
84 pub storage_class: StorageClass,
85 /// The bucket's billing configuration.
86 pub billing: Option<Billing>,
87 /// HTTP 1.1 [Entity tag](https://tools.ietf.org/html/rfc7232#section-2.3) for the bucket.
88 pub etag: String,
89}
90
91/// A model that can be used to insert new buckets into Google Cloud Storage.
92#[derive(Debug, PartialEq, Default, serde::Serialize)]
93#[serde(rename_all = "camelCase")]
94pub struct NewBucket {
95 /// The name of the bucket. See the bucket naming guidelines for more information.
96 pub name: String,
97 /// Whether or not to automatically apply an eventBasedHold to new objects added to the bucket.
98 pub default_event_based_hold: Option<bool>,
99 /// Access controls on the bucket, containing one or more `BucketAccessControls` resources. If
100 /// `iamConfiguration.uniformBucketLevelAccess.enabled` is set to true, this field is omitted in
101 /// responses, and requests that specify this field fail with a `400 Bad Request` response.
102 pub acl: Option<Vec<NewBucketAccessControl>>,
103 /// Default access controls to apply to new objects when no ACL is provided. This list defines
104 /// an entity and role for one or more `DefaultObjectAccessControls` resources. If
105 /// `iamConfiguration.uniformBucketLevelAccess.enabled` is set to true, this field is omitted in
106 /// responses, and requests that specify this field fail with a `400 Bad Request` response.
107 pub default_object_acl: Option<Vec<NewDefaultObjectAccessControl>>,
108 /// The bucket's IAM configuration.
109 pub iam_configuration: Option<IamConfiguration>,
110 /// Encryption configuration for a bucket.
111 pub encryption: Option<Encryption>,
112 /// The location of the bucket. Object data for objects in the bucket resides in physical
113 /// storage within this region. Defaults to US. See Cloud Storage bucket locations for the
114 /// authoritative list.
115 pub location: Location,
116 /// The bucket's website configuration, controlling how the service behaves when accessing
117 /// bucket contents as a web site. See the Static Website Examples for more information.
118 pub website: Option<Website>,
119 /// The bucket's logging configuration, which defines the destination bucket and optional name
120 /// prefix for the current bucket's logs.
121 pub logging: Option<Logging>,
122 /// The bucket's versioning configuration.
123 pub versioning: Option<Versioning>,
124 /// The bucket's Cross-Origin Resource Sharing (CORS) configuration.
125 pub cors: Option<Vec<Cors>>,
126 /// The bucket's lifecycle configuration. See
127 /// [lifecycle management](https://cloud.google.com/storage/docs/lifecycle) for more
128 /// information.
129 pub lifecycle: Option<Lifecycle>,
130 /// User-provided bucket labels, in key/value pairs.
131 pub labels: Option<std::collections::HashMap<String, String>>,
132 /// The bucket's default storage class, used whenever no storageClass is specified for a
133 /// newly-created object. If storageClass is not specified when the bucket
134 /// is created, it defaults to STANDARD. For more information, see storage classes.
135 pub storage_class: Option<StorageClass>,
136 /// The bucket's billing configuration.
137 pub billing: Option<Billing>,
138}
139
140/// Contains information about how files are kept after deletion.
141#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
142#[serde(rename_all = "camelCase")]
143pub struct RetentionPolicy {
144 /// The period of time, in seconds, that objects in the bucket must be retained and cannot be
145 /// deleted, overwritten, or made noncurrent. The value must be greater than 0 seconds and less
146 /// than 3,155,760,000 seconds.
147 #[serde(deserialize_with = "crate::from_str")]
148 pub retention_period: u64,
149 /// The time from which the retentionPolicy was effective, in RFC 3339 format.
150 pub effective_time: chrono::DateTime<chrono::Utc>,
151 /// Whether or not the retentionPolicy is locked. If true, the retentionPolicy cannot be removed
152 /// and the retention period cannot be reduced.
153 pub is_locked: Option<bool>,
154}
155
156/// Contains information about the Buckets IAM configuration.
157#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
158#[serde(rename_all = "camelCase")]
159pub struct IamConfiguration {
160 /// The bucket's uniform bucket-level access configuration.
161 ///
162 /// Note: iamConfiguration also includes the bucketPolicyOnly field, which uses a legacy name
163 /// but has the same functionality as the uniformBucketLevelAccess field. We recommend only
164 /// using uniformBucketLevelAccess, as specifying both fields may result in unreliable behavior.
165 pub uniform_bucket_level_access: UniformBucketLevelAccess,
166}
167
168/// Access that is configured for all objects in one go.
169#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
170#[serde(rename_all = "camelCase")]
171pub struct UniformBucketLevelAccess {
172 /// Whether or not the bucket uses uniform bucket-level access. If set, access checks only use
173 /// bucket-level IAM policies or above.
174 pub enabled: bool,
175 /// The deadline time for changing iamConfiguration.uniformBucketLevelAccess.enabled from true
176 /// to false, in RFC 3339 format.
177 ///
178 /// iamConfiguration.uniformBucketLevelAccess.enabled may be changed from true to false until
179 /// the locked time, after which the field is immutable.
180 pub locked_time: Option<chrono::DateTime<chrono::Utc>>,
181}
182
183/// Contains information about the encryption used for data in this Bucket.
184#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
185#[serde(rename_all = "camelCase")]
186pub struct Encryption {
187 /// A Cloud KMS key that will be used to encrypt objects inserted into this bucket, if no
188 /// encryption method is specified.
189 pub default_kms_key_name: String,
190}
191
192/// Contains information about an entity that is able to own a `Bucket`.
193#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
194#[serde(rename_all = "camelCase")]
195pub struct Owner {
196 /// The entity, in the form project-owner-projectId.
197 pub entity: Entity,
198 /// The ID for the entity.
199 pub entity_id: Option<String>,
200}
201
202/// Contains configuration about how to visit the website linked to this Bucket.
203#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
204#[serde(rename_all = "camelCase")]
205pub struct Website {
206 /// If the requested object path is missing, the service will ensure the path has a trailing
207 /// '/', append this suffix, and attempt to retrieve the resulting object. This allows the
208 /// creation of index.html objects to represent directory pages.
209 pub main_page_suffix: String,
210 /// If the requested object path is missing, and any mainPageSuffix object is missing, if
211 /// applicable, the service will return the named object from this bucket as the content for a
212 /// 404 Not Found result.
213 pub not_found_page: String,
214}
215
216/// Contains information of where and how access logs to this bucket are maintained.
217#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
218#[serde(rename_all = "camelCase")]
219pub struct Logging {
220 /// The destination bucket where the current bucket's logs should be placed.
221 pub log_bucket: String,
222 /// A prefix for log object names. The default prefix is the bucket name.
223 pub log_object_prefix: String,
224}
225
226/// Contains information about whether a Bucket keeps track of its version.
227#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
228#[serde(rename_all = "camelCase")]
229pub struct Versioning {
230 /// While set to true, versioning is fully enabled for this bucket.
231 pub enabled: bool,
232}
233
234/// Contains information about how OPTIONS requests for this Bucket are handled.
235#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
236#[serde(rename_all = "camelCase")]
237pub struct Cors {
238 /// The list of Origins eligible to receive CORS response headers. Note: "*" is permitted in the
239 /// list of origins, and means "any Origin".
240 pub origin: Vec<String>,
241 /// The list of HTTP methods on which to include CORS response headers, (GET, OPTIONS, POST,
242 /// etc) Note: "*" is permitted in the list of methods, and means "any method".
243 pub method: Vec<String>,
244 /// The list of HTTP headers other than the simple response headers to give permission for the
245 /// user-agent to share across domains.
246 pub response_header: Vec<String>,
247 /// The value, in seconds, to return in the Access-Control-Max-Age header used in preflight
248 /// responses.
249 pub max_age_seconds: i32,
250}
251
252/// Contains a set of `Rule` Objects which together describe the way this lifecycle behaves
253#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
254#[serde(rename_all = "camelCase")]
255pub struct Lifecycle {
256 /// A lifecycle management rule, which is made of an action to take and the condition(s) under
257 /// which the action will be taken.
258 pub rule: Vec<Rule>,
259}
260
261/// An element of the lifecyle list.
262#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
263#[serde(rename_all = "camelCase")]
264pub struct Rule {
265 /// The action to take.
266 pub action: Action,
267 /// The condition(s) under which the action will be taken.
268 pub condition: Condition,
269}
270
271/// Represents an action that might be undertaken due to a `Condition`.
272#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
273#[serde(rename_all = "camelCase")]
274pub struct Action {
275 /// Type of the action.
276 pub r#type: ActionType,
277 /// Target storage class. Required iff the type of the action is SetStorageClass.
278 pub storage_class: Option<StorageClass>,
279}
280
281/// Type of the action.
282#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
283pub enum ActionType {
284 /// Deletes a Bucket.
285 Delete,
286 /// Sets the `storage_class` of a Bucket.
287 SetStorageClass,
288}
289
290/// A rule that might induce an `Action` if met.
291#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
292#[serde(rename_all = "camelCase")]
293pub struct Condition {
294 /// Age of an object (in days). This condition is satisfied when an object reaches the specified
295 /// age.
296 pub age: Option<i32>,
297 /// A date in `RFC 3339` format with only the date part (for instance, "2013-01-15"). This
298 /// condition is satisfied when an object is created before midnight of the specified date in
299 /// UTC.
300 pub created_before: Option<chrono::NaiveDate>,
301 /// Relevant only for versioned objects. If the value is true, this condition matches the live
302 /// version of objects; if the value is `false`, it matches noncurrent versions of objects.
303 pub is_live: Option<bool>,
304 /// Objects having any of the storage classes specified by this condition will be matched.
305 /// Values include STANDARD, NEARLINE, COLDLINE, MULTI_REGIONAL, REGIONAL, and
306 /// DURABLE_REDUCED_AVAILABILITY.
307 pub matches_storage_class: Option<Vec<String>>,
308 /// Relevant only for versioned objects. If the value is N, this condition is satisfied when
309 /// there are at least N versions (including the live version) newer than this version of the
310 /// object.
311 #[serde(default, deserialize_with = "crate::from_str_opt")]
312 pub num_newer_versions: Option<i32>,
313}
314
315/// Contains information about the payment structure of this bucket
316#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
317#[serde(rename_all = "camelCase")]
318pub struct Billing {
319 /// When set to true, Requester Pays is enabled for this bucket.
320 pub requester_pays: bool,
321}
322
323/// The type of storage that is used. Pertains to availability, performance and cost.
324#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
325#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
326pub enum StorageClass {
327 /// Standard Storage is best for data that is frequently accessed ("hot" data) and/or stored for
328 /// only brief periods of time.
329 Standard,
330 /// Nearline Storage is a low-cost, highly durable storage service for storing infrequently
331 /// accessed data.
332 Nearline,
333 /// Coldline Storage is a very-low-cost, highly durable storage service for data archiving,
334 /// online backup, and disaster recovery.
335 Coldline,
336 /// Equivalent to Standard Storage, except Multi-Regional Storage can only be used for objects
337 /// stored in multi-regions or dual-regions.
338 MultiRegional,
339 /// Equivalent to Standard Storage, except Regional Storage can only be used for objects stored
340 /// in regions.
341 Regional,
342 /// Similar to Standard Storage except:
343 ///
344 /// DRA has higher pricing for operations.
345 /// DRA has lower performance, particularly in terms of availability (DRA has a 99% availability
346 /// SLA).
347 ///
348 /// You can move your data from DRA to other storage classes by performing a storage transfer.
349 DurableReducedAvailability,
350}
351
352/// A representation of the IAM Policiy for a certain bucket.
353#[derive(Debug, PartialEq, Default, serde::Deserialize, serde::Serialize)]
354#[serde(rename_all = "camelCase")]
355pub struct IamPolicy {
356 /// The [Cloud IAM policy](https://cloud.google.com/iam/docs/policies#versions) version.
357 pub version: i32,
358 /// The kind of item this is. For policies, this field is ignored in a request and is
359 /// `storage#policy` in a response.
360 pub kind: Option<String>,
361 /// The ID of the resource to which this policy belongs. The response for this field is of the
362 /// form `projects/_/buckets/bucket`. This field is ignored in a request.
363 pub resource_id: Option<String>,
364 /// A list of the bindings for this policy.
365 pub bindings: Vec<Binding>,
366 /// HTTP 1.1 [Entity tag](https://tools.ietf.org/html/rfc7232#section-2.3) for this policy.
367 pub etag: String,
368}
369
370/// An association between a role, which comes with a set of permissions, and members who may assume
371/// that role.
372#[derive(Debug, PartialEq, serde::Deserialize, serde::Serialize)]
373#[serde(rename_all = "camelCase")]
374pub struct Binding {
375 /// The role to which members belong. Two types of roles are supported: standard IAM roles,
376 /// which grant permissions that do not map directly to those provided by ACLs, and legacy IAM
377 /// roles, which do map directly to ACL permissions. All roles are of the format
378 /// `roles/storage.specificRole.`
379 ///
380 /// See
381 /// [Cloud Storage IAM Roles](https://cloud.google.com/storage/docs/access-control/iam-roles)
382 /// for a list of available roles.
383 pub role: IamRole,
384 /// A collection of identifiers for members who may assume the provided role. Recognized
385 /// identifiers are as follows:
386 ///
387 /// * `allUsers` — A special identifier that represents anyone on the internet; with or without
388 /// a Google account.
389 /// * `allAuthenticatedUsers` — A special identifier that represents anyone who is authenticated
390 /// with a Google account or a service account.
391 /// * `user:emailid` — An email address that represents a specific account. For example,
392 /// user:alice@gmail.com or user:joe@example.com.
393 /// * `serviceAccount:emailid` — An email address that represents a service account. For
394 /// example, serviceAccount:my-other-app@appspot.gserviceaccount.com .
395 /// * `group:emailid` — An email address that represents a Google group. For example,
396 /// group:admins@example.com.
397 /// * `domain:domain` — A G Suite domain name that represents all the users of that domain. For
398 /// example, domain:google.com or domain:example.com.
399 /// * `projectOwner:projectid` — Owners of the given project. For example,
400 /// projectOwner:my-example-project
401 /// * `projectEditor:projectid` — Editors of the given project. For example,
402 /// projectEditor:my-example-project
403 /// * `projectViewer:projectid` — Viewers of the given project. For example,
404 /// projectViewer:my-example-project
405 pub members: Vec<String>,
406 /// A condition object associated with this binding. Each role binding can only contain one
407 /// condition.
408 pub condition: Option<IamCondition>,
409}
410
411/// A condition object associated with a binding.
412#[derive(Debug, PartialEq, serde::Deserialize, serde::Serialize)]
413#[serde(rename_all = "camelCase")]
414pub struct IamCondition {
415 /// Title of the condition. For example, "expires_end_of_2018".
416 pub title: String,
417 /// Optional description of the condition. For example, "Expires at midnight on 2018-12-31".
418 pub description: Option<String>,
419 /// [Attribute-based](https://cloud.google.com/iam/docs/conditions-overview#attributes) logic
420 /// expression using a subset of the Common Expression Language (CEL). For example,
421 /// "request.time < timestamp('2019-01-01T00:00:00Z')".
422 pub expression: String,
423}
424
425/// All possible roles that can exist in the IAM system. For a more comprehensive version, check
426/// [Googles Documentation](https://cloud.google.com/storage/docs/access-control/iam-roles).
427#[derive(Debug, PartialEq, serde::Deserialize, serde::Serialize)]
428#[serde(untagged)]
429pub enum IamRole {
430 /// Standard roles can be applied to either buckets or projects.
431 Standard(StandardIamRole),
432 /// Primitive roles are roles that must be added on a per-project basis.
433 Primitive(PrimitiveIamRole),
434 /// Legacy roles are roles that can only be added to an individual bucket.
435 Legacy(LegacyIamRole),
436}
437
438/// The following enum contains Cloud Identity and Access Management (Cloud IAM) roles that are
439/// associated with Cloud Storage and lists the permissions that are contained in each role. Unless
440/// otherwise noted, these roles can be applied either to entire projects or specific buckets.
441#[derive(Debug, PartialEq, serde::Deserialize, serde::Serialize)]
442pub enum StandardIamRole {
443 /// Allows users to create objects. Does not give permission to view, delete, or overwrite
444 /// objects.
445 #[serde(rename = "roles/storage.objectCreator")]
446 ObjectCreator,
447 /// Grants access to view objects and their metadata, excluding ACLs.
448 ///
449 /// Can also list the objects in a bucket.
450 #[serde(rename = "roles/storage.objectViewer")]
451 ObjectViewer,
452 /// Grants full control over objects, including listing, creating, viewing, and deleting
453 /// objects.
454 #[serde(rename = "roles/storage.objectAdmin")]
455 ObjectAdmin,
456 /// Full control over HMAC keys in a project.
457 #[serde(rename = "roles/storage.hmacKeyAdmin")]
458 HmacKeyAdmin,
459 /// Grants full control of buckets and objects.
460 ///
461 /// When applied to an individual bucket, control applies only to the specified bucket and
462 /// objects within the bucket.
463 #[serde(rename = "roles/storage.admin")]
464 Admin,
465}
466
467/// The following enum contains primitive roles and the Cloud Storage permissions that these roles
468/// contain. Primitive roles cannot be added at the bucket-level.
469#[derive(Debug, PartialEq, serde::Deserialize, serde::Serialize)]
470pub enum PrimitiveIamRole {
471 /// Grants permission to list buckets as well as view bucket metadata, excluding ACLs, when
472 /// listing. Also grants permission to list and get HMAC keys in the project.
473 #[serde(rename = "role/viewer")]
474 Viewer,
475 /// Grants permission to create, list, and delete buckets. Grants permission to view bucket
476 /// metadata, excluding ACLs, when listing. Grants full control over HMAC keys in a project.
477 #[serde(rename = "role/editor")]
478 Editor,
479 /// Grants permission to create, list, and delete buckets. Also grants permission to view bucket
480 /// metadata, excluding ACLs, when listing. Grants full control over HMAC keys in a project.
481 #[serde(rename = "role/owner")]
482 Owner,
483}
484
485/// The following enum contains Cloud IAM roles that are equivalent to Access Control List (ACL)
486/// permissions. These Cloud IAM roles can only be applied to a bucket, not a project.
487#[derive(Debug, PartialEq, serde::Deserialize, serde::Serialize)]
488pub enum LegacyIamRole {
489 /// Grants permission to view objects and their metadata, excluding ACLs.
490 #[serde(rename = "roles/storage.legacyObjectReader")]
491 LegacyObjectReader,
492 /// Grants permission to view and edit objects and their metadata, including ACLs.
493 #[serde(rename = "roles/storage.legacyObjectOwner")]
494 LegacyObjectOwner,
495 /// Grants permission to list a bucket's contents and read bucket metadata, excluding Cloud IAM
496 /// policies. Also grants permission to read object metadata, excluding Cloud IAM policies, when
497 /// listing objects.
498 ///
499 /// Use of this role is also reflected in the bucket's ACLs. See
500 /// [Cloud IAM relation to ACLs](https://cloud.google.com/storage/docs/access-control/iam#acls)
501 /// for more information.
502 #[serde(rename = "roles/storage.legacyBucketReader")]
503 LegacyBucketReader,
504 /// Grants permission to create, overwrite, and delete objects; list objects in a bucket and
505 /// read object metadata, excluding Cloud IAM policies, when listing; and read bucket metadata,
506 /// excluding Cloud IAM policies.
507 ///
508 /// Use of this role is also reflected in the bucket's ACLs. See
509 /// [Cloud IAM relation to ACLs](https://cloud.google.com/storage/docs/access-control/iam#acls)
510 /// for more information.
511 #[serde(rename = "roles/storage.legacyBucketWriter")]
512 LegacyBucketWriter,
513 /// Grants permission to create, overwrite, and delete objects; list objects in a bucket and
514 /// read object metadata, excluding Cloud IAM policies, when listing; and read and edit bucket
515 /// metadata, including Cloud IAM policies.
516 ///
517 /// Use of this role is also reflected in the bucket's ACLs. See
518 /// [Cloud IAM relation to ACLs](https://cloud.google.com/storage/docs/access-control/iam#acls)
519 /// for more information.
520 #[serde(rename = "roles/storage.legacyBucketOwner")]
521 LegacyBucketOwner,
522}
523
524/// The request needed to perform the Object::test_iam_permission function.
525#[derive(Debug, PartialEq, serde::Deserialize)]
526#[serde(rename_all = "camelCase")]
527pub struct TestIamPermission {
528 /// The kind of item this is.
529 kind: String,
530 /// The permissions held by the caller. Permissions are always of the format
531 /// `storage.resource.capability`, where resource is one of buckets or objects. See
532 /// [Cloud Storage IAM Permissions]
533 /// (https://cloud.google.com/storage/docs/access-control/iam-permissions) for a list of
534 /// supported permissions.
535 permissions: Vec<String>,
536}
537
538impl Bucket {
539 /// Creates a new `Bucket`. There are many options that you can provide for creating a new
540 /// bucket, so the `NewBucket` resource contains all of them. Note that `NewBucket` implements
541 /// `Default`, so you don't have to specify the fields you're not using. And error is returned
542 /// if that bucket name is already taken.
543 /// ### Example
544 /// ```
545 /// # #[tokio::main]
546 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
547 /// use cloud_storage::bucket::{Bucket, NewBucket};
548 /// use cloud_storage::bucket::{Location, MultiRegion};
549 ///
550 /// let new_bucket = NewBucket {
551 /// name: "cloud-storage-rs-doc-1".to_string(), // this is the only mandatory field
552 /// location: Location::Multi(MultiRegion::Eu),
553 /// ..Default::default()
554 /// };
555 /// let bucket = Bucket::create(&new_bucket).await?;
556 /// # bucket.delete().await?;
557 /// # Ok(())
558 /// # }
559 /// ```
560 #[cfg(feature = "global-client")]
561 pub async fn create(new_bucket: &NewBucket) -> crate::Result<Self> {
562 crate::CLOUD_CLIENT.bucket().create(new_bucket).await
563 }
564
565 /// The synchronous equivalent of `Bucket::create`.
566 ///
567 /// ### Features
568 /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
569 #[cfg(all(feature = "global-client", feature = "sync"))]
570 pub fn create_sync(new_bucket: &NewBucket) -> crate::Result<Self> {
571 crate::runtime()?.block_on(Self::create(new_bucket))
572 }
573
574 /// Returns all `Bucket`s within this project.
575 ///
576 /// ### Note
577 /// When using incorrect permissions, this function fails silently and returns an empty list.
578 ///
579 /// ### Example
580 /// ```
581 /// # #[tokio::main]
582 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
583 /// use cloud_storage::Bucket;
584 ///
585 /// let buckets = Bucket::list().await?;
586 /// # Ok(())
587 /// # }
588 /// ```
589 #[cfg(feature = "global-client")]
590 pub async fn list() -> crate::Result<Vec<Self>> {
591 crate::CLOUD_CLIENT.bucket().list().await
592 }
593
594 /// The synchronous equivalent of `Bucket::list`.
595 ///
596 /// ### Features
597 /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
598 #[cfg(all(feature = "global-client", feature = "sync"))]
599 pub fn list_sync() -> crate::Result<Vec<Self>> {
600 crate::runtime()?.block_on(Self::list())
601 }
602
603 /// Returns a single `Bucket` by its name. If the Bucket does not exist, an error is returned.
604 /// ### Example
605 /// ```
606 /// # #[tokio::main]
607 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
608 /// use cloud_storage::Bucket;
609 /// # use cloud_storage::bucket::NewBucket;
610 /// # let new_bucket = NewBucket {
611 /// # name: "cloud-storage-rs-doc-2".to_string(),
612 /// # ..Default::default()
613 /// # };
614 /// # let _ = Bucket::create(&new_bucket).await?;
615 ///
616 /// let bucket = Bucket::read("cloud-storage-rs-doc-2").await?;
617 /// # bucket.delete().await?;
618 /// # Ok(())
619 /// # }
620 /// ```
621 #[cfg(feature = "global-client")]
622 pub async fn read(name: &str) -> crate::Result<Self> {
623 crate::CLOUD_CLIENT.bucket().read(name).await
624 }
625
626 /// The synchronous equivalent of `Bucket::read`.
627 ///
628 /// ### Features
629 /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
630 #[cfg(all(feature = "global-client", feature = "sync"))]
631 pub fn read_sync(name: &str) -> crate::Result<Self> {
632 crate::runtime()?.block_on(Self::read(name))
633 }
634
635 /// Update an existing `Bucket`. If you declare you bucket as mutable, you can edit its fields.
636 /// You can then flush your changes to Google Cloud Storage using this method.
637 /// ### Example
638 /// ```
639 /// # #[tokio::main]
640 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
641 /// use cloud_storage::bucket::{Bucket, RetentionPolicy};
642 /// # use cloud_storage::bucket::NewBucket;
643 /// # let new_bucket = NewBucket {
644 /// # name: "cloud-storage-rs-doc-3".to_string(),
645 /// # ..Default::default()
646 /// # };
647 /// # let _ = Bucket::create(&new_bucket).await?;
648 ///
649 /// let mut bucket = Bucket::read("cloud-storage-rs-doc-3").await?;
650 /// bucket.retention_policy = Some(RetentionPolicy {
651 /// retention_period: 50,
652 /// effective_time: chrono::Utc::now() + chrono::Duration::seconds(50),
653 /// is_locked: Some(false),
654 /// });
655 /// bucket.update().await?;
656 /// # bucket.delete().await?;
657 /// # Ok(())
658 /// # }
659 /// ```
660 #[cfg(feature = "global-client")]
661 pub async fn update(&self) -> crate::Result<Self> {
662 crate::CLOUD_CLIENT.bucket().update(self).await
663 }
664
665 /// The synchronous equivalent of `Bucket::update`.
666 ///
667 /// ### Features
668 /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
669 #[cfg(all(feature = "global-client", feature = "sync"))]
670 pub fn update_sync(&self) -> crate::Result<Self> {
671 crate::runtime()?.block_on(self.update())
672 }
673
674 /// Delete an existing `Bucket`. This permanently removes a bucket from Google Cloud Storage.
675 /// An error is returned when you don't have sufficient permissions, or when the
676 /// `retention_policy` prevents you from deleting your Bucket.
677 /// ### Example
678 /// ```no_run
679 /// # #[tokio::main]
680 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
681 /// use cloud_storage::Bucket;
682 /// # use cloud_storage::bucket::NewBucket;
683 /// # let new_bucket = NewBucket {
684 /// # name: "unnecessary-bucket".to_string(),
685 /// # ..Default::default()
686 /// # };
687 /// # let _ = Bucket::create(&new_bucket).await?;
688 ///
689 /// let bucket = Bucket::read("unnecessary-bucket").await?;
690 /// bucket.delete().await?;
691 /// # Ok(())
692 /// # }
693 /// ```
694 #[cfg(feature = "global-client")]
695 pub async fn delete(self) -> crate::Result<()> {
696 crate::CLOUD_CLIENT.bucket().delete(self).await
697 }
698
699 /// The synchronous equivalent of `Bucket::delete`.
700 ///
701 /// ### Features
702 /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
703 #[cfg(all(feature = "global-client", feature = "sync"))]
704 pub fn delete_sync(self) -> crate::Result<()> {
705 crate::runtime()?.block_on(self.delete())
706 }
707
708 /// Returns the [IAM Policy](https://cloud.google.com/iam/docs/) for this bucket.
709 /// ### Example
710 /// ```
711 /// # #[tokio::main]
712 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
713 /// use cloud_storage::Bucket;
714 /// # use cloud_storage::bucket::NewBucket;
715 /// # let new_bucket = NewBucket {
716 /// # name: "cloud-storage-rs-doc-4".to_string(),
717 /// # ..Default::default()
718 /// # };
719 /// # let _ = Bucket::create(&new_bucket).await?;
720 ///
721 /// let bucket = Bucket::read("cloud-storage-rs-doc-4").await?;
722 /// let policy = bucket.get_iam_policy().await?;
723 /// # bucket.delete().await?;
724 /// # Ok(())
725 /// # }
726 /// ```
727 #[cfg(feature = "global-client")]
728 pub async fn get_iam_policy(&self) -> crate::Result<IamPolicy> {
729 crate::CLOUD_CLIENT.bucket().get_iam_policy(self).await
730 }
731
732 /// The synchronous equivalent of `Bucket::get_iam_policy`.
733 ///
734 /// ### Features
735 /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
736 #[cfg(all(feature = "global-client", feature = "sync"))]
737 pub fn get_iam_policy_sync(&self) -> crate::Result<IamPolicy> {
738 crate::runtime()?.block_on(self.get_iam_policy())
739 }
740
741 /// Updates the [IAM Policy](https://cloud.google.com/iam/docs/) for this bucket.
742 /// ### Example
743 /// ```
744 /// # #[tokio::main]
745 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
746 /// use cloud_storage::Bucket;
747 /// use cloud_storage::bucket::{IamPolicy, Binding, IamRole, StandardIamRole, Entity};
748 /// # use cloud_storage::bucket::NewBucket;
749 /// # let new_bucket = NewBucket {
750 /// # name: "cloud-storage-rs-doc-5".to_string(),
751 /// # ..Default::default()
752 /// # };
753 /// # let _ = Bucket::create(&new_bucket).await?;
754 ///
755 /// let bucket = Bucket::read("cloud-storage-rs-doc-5").await?;
756 /// let iam_policy = IamPolicy {
757 /// version: 1,
758 /// bindings: vec![
759 /// Binding {
760 /// role: IamRole::Standard(StandardIamRole::ObjectViewer),
761 /// members: vec!["allUsers".to_string()],
762 /// condition: None,
763 /// }
764 /// ],
765 /// ..Default::default()
766 /// };
767 /// let policy = bucket.set_iam_policy(&iam_policy).await?;
768 /// # bucket.delete().await?;
769 /// # Ok(())
770 /// # }
771 /// ```
772 #[cfg(feature = "global-client")]
773 pub async fn set_iam_policy(&self, iam: &IamPolicy) -> crate::Result<IamPolicy> {
774 crate::CLOUD_CLIENT.bucket().set_iam_policy(self, iam).await
775 }
776
777 /// The synchronous equivalent of `Bucket::set_iam_policy`.
778 ///
779 /// ### Features
780 /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
781 #[cfg(all(feature = "global-client", feature = "sync"))]
782 pub fn set_iam_policy_sync(&self, iam: &IamPolicy) -> crate::Result<IamPolicy> {
783 crate::runtime()?.block_on(self.set_iam_policy(iam))
784 }
785
786 /// Checks whether the user provided in the service account has this permission.
787 /// ### Example
788 /// ```no_run
789 /// # #[tokio::main]
790 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
791 /// use cloud_storage::Bucket;
792 ///
793 /// let bucket = Bucket::read("my-bucket").await?;
794 /// bucket.test_iam_permission("storage.buckets.get").await?;
795 /// # Ok(())
796 /// # }
797 /// ```
798 #[cfg(feature = "global-client")]
799 pub async fn test_iam_permission(&self, permission: &str) -> crate::Result<TestIamPermission> {
800 crate::CLOUD_CLIENT
801 .bucket()
802 .test_iam_permission(self, permission)
803 .await
804 }
805
806 /// The synchronous equivalent of `Bucket::test_iam_policy`.
807 ///
808 /// ### Features
809 /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
810 #[cfg(all(feature = "global-client", feature = "sync"))]
811 pub fn test_iam_permission_sync(&self, permission: &str) -> crate::Result<TestIamPermission> {
812 crate::runtime()?.block_on(self.test_iam_permission(permission))
813 }
814
815 fn _lock_retention_policy() {
816 todo!()
817 }
818}
819
820#[cfg(all(test, feature = "global-client"))]
821mod tests {
822 use super::*;
823 use crate::resources::common::Role;
824
825 #[tokio::test]
826 async fn create() -> Result<(), Box<dyn std::error::Error>> {
827 dotenv::dotenv().ok();
828 let base_name = std::env::var("TEST_BUCKET")?;
829 // use a more complex bucket in this test.
830 let new_bucket = NewBucket {
831 name: format!("{}-test-create", base_name),
832 default_event_based_hold: Some(true),
833 acl: Some(vec![NewBucketAccessControl {
834 entity: Entity::AllUsers,
835 role: Role::Reader,
836 }]),
837 default_object_acl: Some(vec![NewDefaultObjectAccessControl {
838 entity: Entity::AllUsers,
839 role: Role::Reader,
840 }]),
841 iam_configuration: Some(IamConfiguration {
842 uniform_bucket_level_access: UniformBucketLevelAccess {
843 enabled: false,
844 locked_time: None,
845 },
846 }),
847 ..Default::default()
848 };
849 let bucket = Bucket::create(&new_bucket).await?;
850 bucket.delete().await?;
851 Ok(())
852 }
853
854 #[tokio::test]
855 async fn list() -> Result<(), Box<dyn std::error::Error>> {
856 Bucket::list().await?;
857 Ok(())
858 }
859
860 #[tokio::test]
861 async fn update() -> Result<(), Box<dyn std::error::Error>> {
862 let mut bucket = crate::create_test_bucket("test-update").await;
863 bucket.retention_policy = Some(RetentionPolicy {
864 retention_period: 50,
865 effective_time: chrono::Utc::now() + chrono::Duration::seconds(50),
866 is_locked: Some(false),
867 });
868 bucket.update().await?;
869 let updated = Bucket::read(&bucket.name).await?;
870 assert_eq!(updated.retention_policy.unwrap().retention_period, 50);
871 bucket.delete().await?;
872 Ok(())
873 }
874
875 // used a lot throughout the other tests, but included for completeness
876 #[tokio::test]
877 async fn delete() -> Result<(), Box<dyn std::error::Error>> {
878 let bucket = crate::create_test_bucket("test-delete").await;
879 bucket.delete().await?;
880 Ok(())
881 }
882
883 #[tokio::test]
884 async fn get_iam_policy() -> Result<(), Box<dyn std::error::Error>> {
885 let bucket = crate::create_test_bucket("test-get-iam-policy").await;
886 bucket.get_iam_policy().await?;
887 bucket.delete().await?;
888 Ok(())
889 }
890
891 #[tokio::test]
892 async fn set_iam_policy() -> Result<(), Box<dyn std::error::Error>> {
893 let bucket = crate::create_test_bucket("test-set-iam-policy").await;
894 let iam_policy = IamPolicy {
895 bindings: vec![Binding {
896 role: IamRole::Standard(StandardIamRole::ObjectViewer),
897 members: vec!["allUsers".to_string()],
898 condition: None,
899 }],
900 ..Default::default()
901 };
902 bucket.set_iam_policy(&iam_policy).await?;
903 assert_eq!(bucket.get_iam_policy().await?.bindings, iam_policy.bindings);
904 bucket.delete().await?;
905 Ok(())
906 }
907
908 #[tokio::test]
909 async fn test_iam_permission() -> Result<(), Box<dyn std::error::Error>> {
910 let bucket = crate::create_test_bucket("test-test-ia-permission").await;
911 bucket.test_iam_permission("storage.buckets.get").await?;
912 bucket.delete().await?;
913 Ok(())
914 }
915
916 #[cfg(all(feature = "global-client", feature = "sync"))]
917 mod sync {
918 use super::*;
919 use crate::resources::common::Role;
920
921 #[test]
922 fn create() -> Result<(), Box<dyn std::error::Error>> {
923 dotenv::dotenv().ok();
924 let base_name = std::env::var("TEST_BUCKET")?;
925 // use a more complex bucket in this test.
926 let new_bucket = NewBucket {
927 name: format!("{}-test-create", base_name),
928 default_event_based_hold: Some(true),
929 acl: Some(vec![NewBucketAccessControl {
930 entity: Entity::AllUsers,
931 role: Role::Reader,
932 }]),
933 default_object_acl: Some(vec![NewDefaultObjectAccessControl {
934 entity: Entity::AllUsers,
935 role: Role::Reader,
936 }]),
937 iam_configuration: Some(IamConfiguration {
938 uniform_bucket_level_access: UniformBucketLevelAccess {
939 enabled: false,
940 locked_time: None,
941 },
942 }),
943 ..Default::default()
944 };
945 let bucket = Bucket::create_sync(&new_bucket)?;
946 bucket.delete_sync()?;
947 Ok(())
948 }
949
950 #[test]
951 fn list() -> Result<(), Box<dyn std::error::Error>> {
952 Bucket::list_sync()?;
953 Ok(())
954 }
955
956 #[test]
957 fn read() -> Result<(), Box<dyn std::error::Error>> {
958 let bucket = crate::create_test_bucket_sync("test-read");
959 let also_bucket = Bucket::read_sync(&bucket.name)?;
960 assert_eq!(bucket, also_bucket);
961 bucket.delete_sync()?;
962 assert!(also_bucket.delete_sync().is_err());
963 Ok(())
964 }
965
966 #[test]
967 fn update() -> Result<(), Box<dyn std::error::Error>> {
968 let mut bucket = crate::create_test_bucket_sync("test-update");
969 bucket.retention_policy = Some(RetentionPolicy {
970 retention_period: 50,
971 effective_time: chrono::Utc::now() + chrono::Duration::seconds(50),
972 is_locked: Some(false),
973 });
974 bucket.update_sync()?;
975 let updated = Bucket::read_sync(&bucket.name)?;
976 assert_eq!(updated.retention_policy.unwrap().retention_period, 50);
977 bucket.delete_sync()?;
978 Ok(())
979 }
980
981 // used a lot throughout the other tests, but included for completeness
982 #[test]
983 fn delete() -> Result<(), Box<dyn std::error::Error>> {
984 let bucket = crate::create_test_bucket_sync("test-delete");
985 bucket.delete_sync()?;
986 Ok(())
987 }
988
989 #[test]
990 fn get_iam_policy() -> Result<(), Box<dyn std::error::Error>> {
991 let bucket = crate::create_test_bucket_sync("test-get-iam-policy");
992 bucket.get_iam_policy_sync()?;
993 bucket.delete_sync()?;
994 Ok(())
995 }
996
997 #[test]
998 fn set_iam_policy() -> Result<(), Box<dyn std::error::Error>> {
999 // use crate::resources::iam_policy::{Binding, IamRole, StandardIamRole};
1000
1001 let bucket = crate::create_test_bucket_sync("test-set-iam-policy");
1002 let iam_policy = IamPolicy {
1003 bindings: vec![Binding {
1004 role: IamRole::Standard(StandardIamRole::ObjectViewer),
1005 members: vec!["allUsers".to_string()],
1006 condition: None,
1007 }],
1008 ..Default::default()
1009 };
1010 bucket.set_iam_policy_sync(&iam_policy)?;
1011 assert_eq!(bucket.get_iam_policy_sync()?.bindings, iam_policy.bindings);
1012 bucket.delete_sync()?;
1013 Ok(())
1014 }
1015
1016 #[test]
1017 fn test_iam_permission() -> Result<(), Box<dyn std::error::Error>> {
1018 let bucket = crate::create_test_bucket_sync("test-test-ia-permission");
1019 bucket.test_iam_permission_sync("storage.buckets.get")?;
1020 bucket.delete_sync()?;
1021 Ok(())
1022 }
1023 }
1024}