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}