rusoto_ebs/
generated.rs

1// =================================================================
2//
3//                           * WARNING *
4//
5//                    This file is generated!
6//
7//  Changes made to this file will be overwritten. If changes are
8//  required to the generated code, the service_crategen project
9//  must be updated to generate the changes.
10//
11// =================================================================
12
13use std::error::Error;
14use std::fmt;
15
16use async_trait::async_trait;
17use rusoto_core::credential::ProvideAwsCredentials;
18use rusoto_core::region;
19use rusoto_core::request::{BufferedHttpResponse, DispatchSignedRequest};
20use rusoto_core::{Client, RusotoError};
21
22use rusoto_core::param::{Params, ServiceParams};
23use rusoto_core::proto;
24use rusoto_core::signature::SignedRequest;
25#[allow(unused_imports)]
26use serde::{Deserialize, Serialize};
27use serde_json;
28/// <p>A block of data in an Amazon Elastic Block Store snapshot.</p>
29#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
30#[cfg_attr(any(test, feature = "serialize_structs"), derive(Serialize))]
31pub struct Block {
32    /// <p>The block index.</p>
33    #[serde(rename = "BlockIndex")]
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub block_index: Option<i64>,
36    /// <p>The block token for the block index.</p>
37    #[serde(rename = "BlockToken")]
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub block_token: Option<String>,
40}
41
42/// <p>A block of data in an Amazon Elastic Block Store snapshot that is different from another snapshot of the same volume/snapshot lineage.</p>
43#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
44#[cfg_attr(any(test, feature = "serialize_structs"), derive(Serialize))]
45pub struct ChangedBlock {
46    /// <p>The block index.</p>
47    #[serde(rename = "BlockIndex")]
48    #[serde(skip_serializing_if = "Option::is_none")]
49    pub block_index: Option<i64>,
50    /// <p>The block token for the block index of the <code>FirstSnapshotId</code> specified in the <code>ListChangedBlocks</code> operation. This value is absent if the first snapshot does not have the changed block that is on the second snapshot.</p>
51    #[serde(rename = "FirstBlockToken")]
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub first_block_token: Option<String>,
54    /// <p>The block token for the block index of the <code>SecondSnapshotId</code> specified in the <code>ListChangedBlocks</code> operation.</p>
55    #[serde(rename = "SecondBlockToken")]
56    #[serde(skip_serializing_if = "Option::is_none")]
57    pub second_block_token: Option<String>,
58}
59
60#[derive(Clone, Debug, Default, PartialEq, Serialize)]
61#[cfg_attr(feature = "deserialize_structs", derive(Deserialize))]
62pub struct CompleteSnapshotRequest {
63    /// <p>The number of blocks that were written to the snapshot.</p>
64    #[serde(rename = "ChangedBlocksCount")]
65    pub changed_blocks_count: i64,
66    /// <p>An aggregated Base-64 SHA256 checksum based on the checksums of each written block.</p> <p>To generate the aggregated checksum using the linear aggregation method, arrange the checksums for each written block in ascending order of their block index, concatenate them to form a single string, and then generate the checksum on the entire string using the SHA256 algorithm.</p>
67    #[serde(rename = "Checksum")]
68    #[serde(skip_serializing_if = "Option::is_none")]
69    pub checksum: Option<String>,
70    /// <p>The aggregation method used to generate the checksum. Currently, the only supported aggregation method is <code>LINEAR</code>.</p>
71    #[serde(rename = "ChecksumAggregationMethod")]
72    #[serde(skip_serializing_if = "Option::is_none")]
73    pub checksum_aggregation_method: Option<String>,
74    /// <p>The algorithm used to generate the checksum. Currently, the only supported algorithm is <code>SHA256</code>.</p>
75    #[serde(rename = "ChecksumAlgorithm")]
76    #[serde(skip_serializing_if = "Option::is_none")]
77    pub checksum_algorithm: Option<String>,
78    /// <p>The ID of the snapshot.</p>
79    #[serde(rename = "SnapshotId")]
80    pub snapshot_id: String,
81}
82
83#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
84#[cfg_attr(any(test, feature = "serialize_structs"), derive(Serialize))]
85pub struct CompleteSnapshotResponse {
86    /// <p>The status of the snapshot.</p>
87    #[serde(rename = "Status")]
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub status: Option<String>,
90}
91
92#[derive(Clone, Debug, Default, PartialEq, Serialize)]
93#[cfg_attr(feature = "deserialize_structs", derive(Deserialize))]
94pub struct GetSnapshotBlockRequest {
95    /// <p>The block index of the block from which to get data.</p> <p>Obtain the <code>BlockIndex</code> by running the <code>ListChangedBlocks</code> or <code>ListSnapshotBlocks</code> operations.</p>
96    #[serde(rename = "BlockIndex")]
97    pub block_index: i64,
98    /// <p>The block token of the block from which to get data.</p> <p>Obtain the <code>BlockToken</code> by running the <code>ListChangedBlocks</code> or <code>ListSnapshotBlocks</code> operations.</p>
99    #[serde(rename = "BlockToken")]
100    pub block_token: String,
101    /// <p>The ID of the snapshot containing the block from which to get data.</p>
102    #[serde(rename = "SnapshotId")]
103    pub snapshot_id: String,
104}
105
106#[derive(Clone, Debug, Default, PartialEq)]
107pub struct GetSnapshotBlockResponse {
108    /// <p>The data content of the block.</p>
109    pub block_data: Option<bytes::Bytes>,
110    /// <p>The checksum generated for the block, which is Base64 encoded.</p>
111    pub checksum: Option<String>,
112    /// <p>The algorithm used to generate the checksum for the block, such as SHA256.</p>
113    pub checksum_algorithm: Option<String>,
114    /// <p>The size of the data in the block.</p>
115    pub data_length: Option<i64>,
116}
117
118#[derive(Clone, Debug, Default, PartialEq, Serialize)]
119#[cfg_attr(feature = "deserialize_structs", derive(Deserialize))]
120pub struct ListChangedBlocksRequest {
121    /// <p><p>The ID of the first snapshot to use for the comparison.</p> <important> <p>The <code>FirstSnapshotID</code> parameter must be specified with a <code>SecondSnapshotId</code> parameter; otherwise, an error occurs.</p> </important></p>
122    #[serde(rename = "FirstSnapshotId")]
123    #[serde(skip_serializing_if = "Option::is_none")]
124    pub first_snapshot_id: Option<String>,
125    /// <p>The number of results to return.</p>
126    #[serde(rename = "MaxResults")]
127    #[serde(skip_serializing_if = "Option::is_none")]
128    pub max_results: Option<i64>,
129    /// <p>The token to request the next page of results.</p>
130    #[serde(rename = "NextToken")]
131    #[serde(skip_serializing_if = "Option::is_none")]
132    pub next_token: Option<String>,
133    /// <p><p>The ID of the second snapshot to use for the comparison.</p> <important> <p>The <code>SecondSnapshotId</code> parameter must be specified with a <code>FirstSnapshotID</code> parameter; otherwise, an error occurs.</p> </important></p>
134    #[serde(rename = "SecondSnapshotId")]
135    pub second_snapshot_id: String,
136    /// <p>The block index from which the comparison should start.</p> <p>The list in the response will start from this block index or the next valid block index in the snapshots.</p>
137    #[serde(rename = "StartingBlockIndex")]
138    #[serde(skip_serializing_if = "Option::is_none")]
139    pub starting_block_index: Option<i64>,
140}
141
142#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
143#[cfg_attr(any(test, feature = "serialize_structs"), derive(Serialize))]
144pub struct ListChangedBlocksResponse {
145    /// <p>The size of the block.</p>
146    #[serde(rename = "BlockSize")]
147    #[serde(skip_serializing_if = "Option::is_none")]
148    pub block_size: Option<i64>,
149    /// <p>An array of objects containing information about the changed blocks.</p>
150    #[serde(rename = "ChangedBlocks")]
151    #[serde(skip_serializing_if = "Option::is_none")]
152    pub changed_blocks: Option<Vec<ChangedBlock>>,
153    /// <p>The time when the <code>BlockToken</code> expires.</p>
154    #[serde(rename = "ExpiryTime")]
155    #[serde(skip_serializing_if = "Option::is_none")]
156    pub expiry_time: Option<f64>,
157    /// <p>The token to use to retrieve the next page of results. This value is null when there are no more results to return.</p>
158    #[serde(rename = "NextToken")]
159    #[serde(skip_serializing_if = "Option::is_none")]
160    pub next_token: Option<String>,
161    /// <p>The size of the volume in GB.</p>
162    #[serde(rename = "VolumeSize")]
163    #[serde(skip_serializing_if = "Option::is_none")]
164    pub volume_size: Option<i64>,
165}
166
167#[derive(Clone, Debug, Default, PartialEq, Serialize)]
168#[cfg_attr(feature = "deserialize_structs", derive(Deserialize))]
169pub struct ListSnapshotBlocksRequest {
170    /// <p>The number of results to return.</p>
171    #[serde(rename = "MaxResults")]
172    #[serde(skip_serializing_if = "Option::is_none")]
173    pub max_results: Option<i64>,
174    /// <p>The token to request the next page of results.</p>
175    #[serde(rename = "NextToken")]
176    #[serde(skip_serializing_if = "Option::is_none")]
177    pub next_token: Option<String>,
178    /// <p>The ID of the snapshot from which to get block indexes and block tokens.</p>
179    #[serde(rename = "SnapshotId")]
180    pub snapshot_id: String,
181    /// <p>The block index from which the list should start. The list in the response will start from this block index or the next valid block index in the snapshot.</p>
182    #[serde(rename = "StartingBlockIndex")]
183    #[serde(skip_serializing_if = "Option::is_none")]
184    pub starting_block_index: Option<i64>,
185}
186
187#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
188#[cfg_attr(any(test, feature = "serialize_structs"), derive(Serialize))]
189pub struct ListSnapshotBlocksResponse {
190    /// <p>The size of the block.</p>
191    #[serde(rename = "BlockSize")]
192    #[serde(skip_serializing_if = "Option::is_none")]
193    pub block_size: Option<i64>,
194    /// <p>An array of objects containing information about the blocks.</p>
195    #[serde(rename = "Blocks")]
196    #[serde(skip_serializing_if = "Option::is_none")]
197    pub blocks: Option<Vec<Block>>,
198    /// <p>The time when the <code>BlockToken</code> expires.</p>
199    #[serde(rename = "ExpiryTime")]
200    #[serde(skip_serializing_if = "Option::is_none")]
201    pub expiry_time: Option<f64>,
202    /// <p>The token to use to retrieve the next page of results. This value is null when there are no more results to return.</p>
203    #[serde(rename = "NextToken")]
204    #[serde(skip_serializing_if = "Option::is_none")]
205    pub next_token: Option<String>,
206    /// <p>The size of the volume in GB.</p>
207    #[serde(rename = "VolumeSize")]
208    #[serde(skip_serializing_if = "Option::is_none")]
209    pub volume_size: Option<i64>,
210}
211
212#[derive(Clone, Debug, Default, PartialEq, Serialize)]
213#[cfg_attr(feature = "deserialize_structs", derive(Deserialize))]
214pub struct PutSnapshotBlockRequest {
215    /// <p>The data to write to the block.</p> <p>The block data is not signed as part of the Signature Version 4 signing process. As a result, you must generate and provide a Base64-encoded SHA256 checksum for the block data using the <b>x-amz-Checksum</b> header. Also, you must specify the checksum algorithm using the <b>x-amz-Checksum-Algorithm</b> header. The checksum that you provide is part of the Signature Version 4 signing process. It is validated against a checksum generated by Amazon EBS to ensure the validity and authenticity of the data. If the checksums do not correspond, the request fails. For more information, see <a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-accessing-snapshot.html#ebsapis-using-checksums"> Using checksums with the EBS direct APIs</a> in the <i>Amazon Elastic Compute Cloud User Guide</i>.</p>
216    #[serde(rename = "BlockData")]
217    #[serde(
218        deserialize_with = "::rusoto_core::serialization::SerdeBlob::deserialize_blob",
219        serialize_with = "::rusoto_core::serialization::SerdeBlob::serialize_blob",
220        default
221    )]
222    pub block_data: bytes::Bytes,
223    /// <p>The block index of the block in which to write the data. A block index is the offset position of a block within a snapshot, and it is used to identify the block. To identify the logical offset of the data in the logical volume, multiply the block index with the block size (Block index * 512 bytes).</p>
224    #[serde(rename = "BlockIndex")]
225    pub block_index: i64,
226    /// <p>A Base64-encoded SHA256 checksum of the data. Only SHA256 checksums are supported.</p>
227    #[serde(rename = "Checksum")]
228    pub checksum: String,
229    /// <p>The algorithm used to generate the checksum. Currently, the only supported algorithm is <code>SHA256</code>.</p>
230    #[serde(rename = "ChecksumAlgorithm")]
231    pub checksum_algorithm: String,
232    /// <p>The size of the data to write to the block, in bytes. Currently, the only supported size is <code>524288</code>.</p> <p>Valid values: <code>524288</code> </p>
233    #[serde(rename = "DataLength")]
234    pub data_length: i64,
235    /// <p>The progress of the write process, as a percentage.</p>
236    #[serde(rename = "Progress")]
237    #[serde(skip_serializing_if = "Option::is_none")]
238    pub progress: Option<i64>,
239    /// <p>The ID of the snapshot.</p>
240    #[serde(rename = "SnapshotId")]
241    pub snapshot_id: String,
242}
243
244#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
245#[cfg_attr(any(test, feature = "serialize_structs"), derive(Serialize))]
246pub struct PutSnapshotBlockResponse {
247    /// <p>The SHA256 checksum generated for the block data by Amazon EBS.</p>
248    #[serde(rename = "Checksum")]
249    #[serde(skip_serializing_if = "Option::is_none")]
250    pub checksum: Option<String>,
251    /// <p>The algorithm used by Amazon EBS to generate the checksum.</p>
252    #[serde(rename = "ChecksumAlgorithm")]
253    #[serde(skip_serializing_if = "Option::is_none")]
254    pub checksum_algorithm: Option<String>,
255}
256
257#[derive(Clone, Debug, Default, PartialEq, Serialize)]
258#[cfg_attr(feature = "deserialize_structs", derive(Deserialize))]
259pub struct StartSnapshotRequest {
260    /// <p>A unique, case-sensitive identifier that you provide to ensure the idempotency of the request. Idempotency ensures that an API request completes only once. With an idempotent request, if the original request completes successfully. The subsequent retries with the same client token return the result from the original successful request and they have no additional effect.</p> <p>If you do not specify a client token, one is automatically generated by the AWS SDK.</p> <p>For more information, see <a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-direct-api-idempotency.html"> Idempotency for StartSnapshot API</a> in the <i>Amazon Elastic Compute Cloud User Guide</i>.</p>
261    #[serde(rename = "ClientToken")]
262    #[serde(skip_serializing_if = "Option::is_none")]
263    pub client_token: Option<String>,
264    /// <p>A description for the snapshot.</p>
265    #[serde(rename = "Description")]
266    #[serde(skip_serializing_if = "Option::is_none")]
267    pub description: Option<String>,
268    /// <p>Indicates whether to encrypt the snapshot. To create an encrypted snapshot, specify <code>true</code>. To create an unencrypted snapshot, omit this parameter.</p> <p>If you specify a value for <b>ParentSnapshotId</b>, omit this parameter.</p> <p>If you specify <code>true</code>, the snapshot is encrypted using the CMK specified using the <b>KmsKeyArn</b> parameter. If no value is specified for <b>KmsKeyArn</b>, the default CMK for your account is used. If no default CMK has been specified for your account, the AWS managed CMK is used. To set a default CMK for your account, use <a href="https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_ModifyEbsDefaultKmsKeyId.html"> ModifyEbsDefaultKmsKeyId</a>.</p> <p>If your account is enabled for encryption by default, you cannot set this parameter to <code>false</code>. In this case, you can omit this parameter.</p> <p>For more information, see <a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-accessing-snapshot.html#ebsapis-using-encryption"> Using encryption</a> in the <i>Amazon Elastic Compute Cloud User Guide</i>.</p>
269    #[serde(rename = "Encrypted")]
270    #[serde(skip_serializing_if = "Option::is_none")]
271    pub encrypted: Option<bool>,
272    /// <p>The Amazon Resource Name (ARN) of the AWS Key Management Service (AWS KMS) customer master key (CMK) to be used to encrypt the snapshot. If you do not specify a CMK, the default AWS managed CMK is used.</p> <p>If you specify a <b>ParentSnapshotId</b>, omit this parameter; the snapshot will be encrypted using the same CMK that was used to encrypt the parent snapshot.</p> <p>If <b>Encrypted</b> is set to <code>true</code>, you must specify a CMK ARN. </p>
273    #[serde(rename = "KmsKeyArn")]
274    #[serde(skip_serializing_if = "Option::is_none")]
275    pub kms_key_arn: Option<String>,
276    /// <p>The ID of the parent snapshot. If there is no parent snapshot, or if you are creating the first snapshot for an on-premises volume, omit this parameter.</p> <p>If your account is enabled for encryption by default, you cannot use an unencrypted snapshot as a parent snapshot. You must first create an encrypted copy of the parent snapshot using <a href="https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CopySnapshot.html">CopySnapshot</a>.</p>
277    #[serde(rename = "ParentSnapshotId")]
278    #[serde(skip_serializing_if = "Option::is_none")]
279    pub parent_snapshot_id: Option<String>,
280    /// <p>The tags to apply to the snapshot.</p>
281    #[serde(rename = "Tags")]
282    #[serde(skip_serializing_if = "Option::is_none")]
283    pub tags: Option<Vec<Tag>>,
284    /// <p>The amount of time (in minutes) after which the snapshot is automatically cancelled if:</p> <ul> <li> <p>No blocks are written to the snapshot.</p> </li> <li> <p>The snapshot is not completed after writing the last block of data.</p> </li> </ul> <p>If no value is specified, the timeout defaults to <code>60</code> minutes.</p>
285    #[serde(rename = "Timeout")]
286    #[serde(skip_serializing_if = "Option::is_none")]
287    pub timeout: Option<i64>,
288    /// <p>The size of the volume, in GiB. The maximum size is <code>16384</code> GiB (16 TiB).</p>
289    #[serde(rename = "VolumeSize")]
290    pub volume_size: i64,
291}
292
293#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
294#[cfg_attr(any(test, feature = "serialize_structs"), derive(Serialize))]
295pub struct StartSnapshotResponse {
296    /// <p>The size of the blocks in the snapshot, in bytes.</p>
297    #[serde(rename = "BlockSize")]
298    #[serde(skip_serializing_if = "Option::is_none")]
299    pub block_size: Option<i64>,
300    /// <p>The description of the snapshot.</p>
301    #[serde(rename = "Description")]
302    #[serde(skip_serializing_if = "Option::is_none")]
303    pub description: Option<String>,
304    /// <p>The Amazon Resource Name (ARN) of the AWS Key Management Service (AWS KMS) customer master key (CMK) used to encrypt the snapshot.</p>
305    #[serde(rename = "KmsKeyArn")]
306    #[serde(skip_serializing_if = "Option::is_none")]
307    pub kms_key_arn: Option<String>,
308    /// <p>The AWS account ID of the snapshot owner.</p>
309    #[serde(rename = "OwnerId")]
310    #[serde(skip_serializing_if = "Option::is_none")]
311    pub owner_id: Option<String>,
312    /// <p>The ID of the parent snapshot.</p>
313    #[serde(rename = "ParentSnapshotId")]
314    #[serde(skip_serializing_if = "Option::is_none")]
315    pub parent_snapshot_id: Option<String>,
316    /// <p>The ID of the snapshot.</p>
317    #[serde(rename = "SnapshotId")]
318    #[serde(skip_serializing_if = "Option::is_none")]
319    pub snapshot_id: Option<String>,
320    /// <p>The timestamp when the snapshot was created.</p>
321    #[serde(rename = "StartTime")]
322    #[serde(skip_serializing_if = "Option::is_none")]
323    pub start_time: Option<f64>,
324    /// <p>The status of the snapshot.</p>
325    #[serde(rename = "Status")]
326    #[serde(skip_serializing_if = "Option::is_none")]
327    pub status: Option<String>,
328    /// <p>The tags applied to the snapshot. You can specify up to 50 tags per snapshot. For more information, see <a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html"> Tagging your Amazon EC2 resources</a> in the <i>Amazon Elastic Compute Cloud User Guide</i>.</p>
329    #[serde(rename = "Tags")]
330    #[serde(skip_serializing_if = "Option::is_none")]
331    pub tags: Option<Vec<Tag>>,
332    /// <p>The size of the volume, in GiB.</p>
333    #[serde(rename = "VolumeSize")]
334    #[serde(skip_serializing_if = "Option::is_none")]
335    pub volume_size: Option<i64>,
336}
337
338/// <p>Describes a tag.</p>
339#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
340pub struct Tag {
341    /// <p>The key of the tag.</p>
342    #[serde(rename = "Key")]
343    #[serde(skip_serializing_if = "Option::is_none")]
344    pub key: Option<String>,
345    /// <p>The value of the tag.</p>
346    #[serde(rename = "Value")]
347    #[serde(skip_serializing_if = "Option::is_none")]
348    pub value: Option<String>,
349}
350
351/// Errors returned by CompleteSnapshot
352#[derive(Debug, PartialEq)]
353pub enum CompleteSnapshotError {
354    /// <p>You do not have sufficient access to perform this action.</p>
355    AccessDenied(String),
356    /// <p>An internal error has occurred.</p>
357    InternalServer(String),
358    /// <p>The number of API requests has exceed the maximum allowed API request throttling limit.</p>
359    RequestThrottled(String),
360    /// <p>The specified resource does not exist.</p>
361    ResourceNotFound(String),
362    /// <p>Your current service quotas do not allow you to perform this action.</p>
363    ServiceQuotaExceeded(String),
364}
365
366impl CompleteSnapshotError {
367    pub fn from_response(res: BufferedHttpResponse) -> RusotoError<CompleteSnapshotError> {
368        if let Some(err) = proto::json::Error::parse_rest(&res) {
369            match err.typ.as_str() {
370                "AccessDeniedException" => {
371                    return RusotoError::Service(CompleteSnapshotError::AccessDenied(err.msg))
372                }
373                "InternalServerException" => {
374                    return RusotoError::Service(CompleteSnapshotError::InternalServer(err.msg))
375                }
376                "RequestThrottledException" => {
377                    return RusotoError::Service(CompleteSnapshotError::RequestThrottled(err.msg))
378                }
379                "ResourceNotFoundException" => {
380                    return RusotoError::Service(CompleteSnapshotError::ResourceNotFound(err.msg))
381                }
382                "ServiceQuotaExceededException" => {
383                    return RusotoError::Service(CompleteSnapshotError::ServiceQuotaExceeded(
384                        err.msg,
385                    ))
386                }
387                "ValidationException" => return RusotoError::Validation(err.msg),
388                _ => {}
389            }
390        }
391        RusotoError::Unknown(res)
392    }
393}
394impl fmt::Display for CompleteSnapshotError {
395    #[allow(unused_variables)]
396    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
397        match *self {
398            CompleteSnapshotError::AccessDenied(ref cause) => write!(f, "{}", cause),
399            CompleteSnapshotError::InternalServer(ref cause) => write!(f, "{}", cause),
400            CompleteSnapshotError::RequestThrottled(ref cause) => write!(f, "{}", cause),
401            CompleteSnapshotError::ResourceNotFound(ref cause) => write!(f, "{}", cause),
402            CompleteSnapshotError::ServiceQuotaExceeded(ref cause) => write!(f, "{}", cause),
403        }
404    }
405}
406impl Error for CompleteSnapshotError {}
407/// Errors returned by GetSnapshotBlock
408#[derive(Debug, PartialEq)]
409pub enum GetSnapshotBlockError {
410    /// <p>You do not have sufficient access to perform this action.</p>
411    AccessDenied(String),
412    /// <p>An internal error has occurred.</p>
413    InternalServer(String),
414    /// <p>The number of API requests has exceed the maximum allowed API request throttling limit.</p>
415    RequestThrottled(String),
416    /// <p>The specified resource does not exist.</p>
417    ResourceNotFound(String),
418    /// <p>Your current service quotas do not allow you to perform this action.</p>
419    ServiceQuotaExceeded(String),
420}
421
422impl GetSnapshotBlockError {
423    pub fn from_response(res: BufferedHttpResponse) -> RusotoError<GetSnapshotBlockError> {
424        if let Some(err) = proto::json::Error::parse_rest(&res) {
425            match err.typ.as_str() {
426                "AccessDeniedException" => {
427                    return RusotoError::Service(GetSnapshotBlockError::AccessDenied(err.msg))
428                }
429                "InternalServerException" => {
430                    return RusotoError::Service(GetSnapshotBlockError::InternalServer(err.msg))
431                }
432                "RequestThrottledException" => {
433                    return RusotoError::Service(GetSnapshotBlockError::RequestThrottled(err.msg))
434                }
435                "ResourceNotFoundException" => {
436                    return RusotoError::Service(GetSnapshotBlockError::ResourceNotFound(err.msg))
437                }
438                "ServiceQuotaExceededException" => {
439                    return RusotoError::Service(GetSnapshotBlockError::ServiceQuotaExceeded(
440                        err.msg,
441                    ))
442                }
443                "ValidationException" => return RusotoError::Validation(err.msg),
444                _ => {}
445            }
446        }
447        RusotoError::Unknown(res)
448    }
449}
450impl fmt::Display for GetSnapshotBlockError {
451    #[allow(unused_variables)]
452    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
453        match *self {
454            GetSnapshotBlockError::AccessDenied(ref cause) => write!(f, "{}", cause),
455            GetSnapshotBlockError::InternalServer(ref cause) => write!(f, "{}", cause),
456            GetSnapshotBlockError::RequestThrottled(ref cause) => write!(f, "{}", cause),
457            GetSnapshotBlockError::ResourceNotFound(ref cause) => write!(f, "{}", cause),
458            GetSnapshotBlockError::ServiceQuotaExceeded(ref cause) => write!(f, "{}", cause),
459        }
460    }
461}
462impl Error for GetSnapshotBlockError {}
463/// Errors returned by ListChangedBlocks
464#[derive(Debug, PartialEq)]
465pub enum ListChangedBlocksError {
466    /// <p>You do not have sufficient access to perform this action.</p>
467    AccessDenied(String),
468    /// <p>An internal error has occurred.</p>
469    InternalServer(String),
470    /// <p>The number of API requests has exceed the maximum allowed API request throttling limit.</p>
471    RequestThrottled(String),
472    /// <p>The specified resource does not exist.</p>
473    ResourceNotFound(String),
474    /// <p>Your current service quotas do not allow you to perform this action.</p>
475    ServiceQuotaExceeded(String),
476}
477
478impl ListChangedBlocksError {
479    pub fn from_response(res: BufferedHttpResponse) -> RusotoError<ListChangedBlocksError> {
480        if let Some(err) = proto::json::Error::parse_rest(&res) {
481            match err.typ.as_str() {
482                "AccessDeniedException" => {
483                    return RusotoError::Service(ListChangedBlocksError::AccessDenied(err.msg))
484                }
485                "InternalServerException" => {
486                    return RusotoError::Service(ListChangedBlocksError::InternalServer(err.msg))
487                }
488                "RequestThrottledException" => {
489                    return RusotoError::Service(ListChangedBlocksError::RequestThrottled(err.msg))
490                }
491                "ResourceNotFoundException" => {
492                    return RusotoError::Service(ListChangedBlocksError::ResourceNotFound(err.msg))
493                }
494                "ServiceQuotaExceededException" => {
495                    return RusotoError::Service(ListChangedBlocksError::ServiceQuotaExceeded(
496                        err.msg,
497                    ))
498                }
499                "ValidationException" => return RusotoError::Validation(err.msg),
500                _ => {}
501            }
502        }
503        RusotoError::Unknown(res)
504    }
505}
506impl fmt::Display for ListChangedBlocksError {
507    #[allow(unused_variables)]
508    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
509        match *self {
510            ListChangedBlocksError::AccessDenied(ref cause) => write!(f, "{}", cause),
511            ListChangedBlocksError::InternalServer(ref cause) => write!(f, "{}", cause),
512            ListChangedBlocksError::RequestThrottled(ref cause) => write!(f, "{}", cause),
513            ListChangedBlocksError::ResourceNotFound(ref cause) => write!(f, "{}", cause),
514            ListChangedBlocksError::ServiceQuotaExceeded(ref cause) => write!(f, "{}", cause),
515        }
516    }
517}
518impl Error for ListChangedBlocksError {}
519/// Errors returned by ListSnapshotBlocks
520#[derive(Debug, PartialEq)]
521pub enum ListSnapshotBlocksError {
522    /// <p>You do not have sufficient access to perform this action.</p>
523    AccessDenied(String),
524    /// <p>An internal error has occurred.</p>
525    InternalServer(String),
526    /// <p>The number of API requests has exceed the maximum allowed API request throttling limit.</p>
527    RequestThrottled(String),
528    /// <p>The specified resource does not exist.</p>
529    ResourceNotFound(String),
530    /// <p>Your current service quotas do not allow you to perform this action.</p>
531    ServiceQuotaExceeded(String),
532}
533
534impl ListSnapshotBlocksError {
535    pub fn from_response(res: BufferedHttpResponse) -> RusotoError<ListSnapshotBlocksError> {
536        if let Some(err) = proto::json::Error::parse_rest(&res) {
537            match err.typ.as_str() {
538                "AccessDeniedException" => {
539                    return RusotoError::Service(ListSnapshotBlocksError::AccessDenied(err.msg))
540                }
541                "InternalServerException" => {
542                    return RusotoError::Service(ListSnapshotBlocksError::InternalServer(err.msg))
543                }
544                "RequestThrottledException" => {
545                    return RusotoError::Service(ListSnapshotBlocksError::RequestThrottled(err.msg))
546                }
547                "ResourceNotFoundException" => {
548                    return RusotoError::Service(ListSnapshotBlocksError::ResourceNotFound(err.msg))
549                }
550                "ServiceQuotaExceededException" => {
551                    return RusotoError::Service(ListSnapshotBlocksError::ServiceQuotaExceeded(
552                        err.msg,
553                    ))
554                }
555                "ValidationException" => return RusotoError::Validation(err.msg),
556                _ => {}
557            }
558        }
559        RusotoError::Unknown(res)
560    }
561}
562impl fmt::Display for ListSnapshotBlocksError {
563    #[allow(unused_variables)]
564    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
565        match *self {
566            ListSnapshotBlocksError::AccessDenied(ref cause) => write!(f, "{}", cause),
567            ListSnapshotBlocksError::InternalServer(ref cause) => write!(f, "{}", cause),
568            ListSnapshotBlocksError::RequestThrottled(ref cause) => write!(f, "{}", cause),
569            ListSnapshotBlocksError::ResourceNotFound(ref cause) => write!(f, "{}", cause),
570            ListSnapshotBlocksError::ServiceQuotaExceeded(ref cause) => write!(f, "{}", cause),
571        }
572    }
573}
574impl Error for ListSnapshotBlocksError {}
575/// Errors returned by PutSnapshotBlock
576#[derive(Debug, PartialEq)]
577pub enum PutSnapshotBlockError {
578    /// <p>You do not have sufficient access to perform this action.</p>
579    AccessDenied(String),
580    /// <p>An internal error has occurred.</p>
581    InternalServer(String),
582    /// <p>The number of API requests has exceed the maximum allowed API request throttling limit.</p>
583    RequestThrottled(String),
584    /// <p>The specified resource does not exist.</p>
585    ResourceNotFound(String),
586    /// <p>Your current service quotas do not allow you to perform this action.</p>
587    ServiceQuotaExceeded(String),
588}
589
590impl PutSnapshotBlockError {
591    pub fn from_response(res: BufferedHttpResponse) -> RusotoError<PutSnapshotBlockError> {
592        if let Some(err) = proto::json::Error::parse_rest(&res) {
593            match err.typ.as_str() {
594                "AccessDeniedException" => {
595                    return RusotoError::Service(PutSnapshotBlockError::AccessDenied(err.msg))
596                }
597                "InternalServerException" => {
598                    return RusotoError::Service(PutSnapshotBlockError::InternalServer(err.msg))
599                }
600                "RequestThrottledException" => {
601                    return RusotoError::Service(PutSnapshotBlockError::RequestThrottled(err.msg))
602                }
603                "ResourceNotFoundException" => {
604                    return RusotoError::Service(PutSnapshotBlockError::ResourceNotFound(err.msg))
605                }
606                "ServiceQuotaExceededException" => {
607                    return RusotoError::Service(PutSnapshotBlockError::ServiceQuotaExceeded(
608                        err.msg,
609                    ))
610                }
611                "ValidationException" => return RusotoError::Validation(err.msg),
612                _ => {}
613            }
614        }
615        RusotoError::Unknown(res)
616    }
617}
618impl fmt::Display for PutSnapshotBlockError {
619    #[allow(unused_variables)]
620    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
621        match *self {
622            PutSnapshotBlockError::AccessDenied(ref cause) => write!(f, "{}", cause),
623            PutSnapshotBlockError::InternalServer(ref cause) => write!(f, "{}", cause),
624            PutSnapshotBlockError::RequestThrottled(ref cause) => write!(f, "{}", cause),
625            PutSnapshotBlockError::ResourceNotFound(ref cause) => write!(f, "{}", cause),
626            PutSnapshotBlockError::ServiceQuotaExceeded(ref cause) => write!(f, "{}", cause),
627        }
628    }
629}
630impl Error for PutSnapshotBlockError {}
631/// Errors returned by StartSnapshot
632#[derive(Debug, PartialEq)]
633pub enum StartSnapshotError {
634    /// <p>You do not have sufficient access to perform this action.</p>
635    AccessDenied(String),
636    /// <p>You have reached the limit for concurrent API requests. For more information, see <a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-accessing-snapshot.html#ebsapi-performance">Optimizing performance of the EBS direct APIs</a> in the <i>Amazon Elastic Compute Cloud User Guide</i>.</p>
637    ConcurrentLimitExceeded(String),
638    /// <p>The request uses the same client token as a previous, but non-identical request.</p>
639    Conflict(String),
640    /// <p>An internal error has occurred.</p>
641    InternalServer(String),
642    /// <p>The number of API requests has exceed the maximum allowed API request throttling limit.</p>
643    RequestThrottled(String),
644    /// <p>The specified resource does not exist.</p>
645    ResourceNotFound(String),
646    /// <p>Your current service quotas do not allow you to perform this action.</p>
647    ServiceQuotaExceeded(String),
648}
649
650impl StartSnapshotError {
651    pub fn from_response(res: BufferedHttpResponse) -> RusotoError<StartSnapshotError> {
652        if let Some(err) = proto::json::Error::parse_rest(&res) {
653            match err.typ.as_str() {
654                "AccessDeniedException" => {
655                    return RusotoError::Service(StartSnapshotError::AccessDenied(err.msg))
656                }
657                "ConcurrentLimitExceededException" => {
658                    return RusotoError::Service(StartSnapshotError::ConcurrentLimitExceeded(
659                        err.msg,
660                    ))
661                }
662                "ConflictException" => {
663                    return RusotoError::Service(StartSnapshotError::Conflict(err.msg))
664                }
665                "InternalServerException" => {
666                    return RusotoError::Service(StartSnapshotError::InternalServer(err.msg))
667                }
668                "RequestThrottledException" => {
669                    return RusotoError::Service(StartSnapshotError::RequestThrottled(err.msg))
670                }
671                "ResourceNotFoundException" => {
672                    return RusotoError::Service(StartSnapshotError::ResourceNotFound(err.msg))
673                }
674                "ServiceQuotaExceededException" => {
675                    return RusotoError::Service(StartSnapshotError::ServiceQuotaExceeded(err.msg))
676                }
677                "ValidationException" => return RusotoError::Validation(err.msg),
678                _ => {}
679            }
680        }
681        RusotoError::Unknown(res)
682    }
683}
684impl fmt::Display for StartSnapshotError {
685    #[allow(unused_variables)]
686    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
687        match *self {
688            StartSnapshotError::AccessDenied(ref cause) => write!(f, "{}", cause),
689            StartSnapshotError::ConcurrentLimitExceeded(ref cause) => write!(f, "{}", cause),
690            StartSnapshotError::Conflict(ref cause) => write!(f, "{}", cause),
691            StartSnapshotError::InternalServer(ref cause) => write!(f, "{}", cause),
692            StartSnapshotError::RequestThrottled(ref cause) => write!(f, "{}", cause),
693            StartSnapshotError::ResourceNotFound(ref cause) => write!(f, "{}", cause),
694            StartSnapshotError::ServiceQuotaExceeded(ref cause) => write!(f, "{}", cause),
695        }
696    }
697}
698impl Error for StartSnapshotError {}
699/// Trait representing the capabilities of the Amazon EBS API. Amazon EBS clients implement this trait.
700#[async_trait]
701pub trait Ebs {
702    /// <p>Seals and completes the snapshot after all of the required blocks of data have been written to it. Completing the snapshot changes the status to <code>completed</code>. You cannot write new blocks to a snapshot after it has been completed.</p>
703    async fn complete_snapshot(
704        &self,
705        input: CompleteSnapshotRequest,
706    ) -> Result<CompleteSnapshotResponse, RusotoError<CompleteSnapshotError>>;
707
708    /// <p>Returns the data in a block in an Amazon Elastic Block Store snapshot.</p>
709    async fn get_snapshot_block(
710        &self,
711        input: GetSnapshotBlockRequest,
712    ) -> Result<GetSnapshotBlockResponse, RusotoError<GetSnapshotBlockError>>;
713
714    /// <p>Returns the block indexes and block tokens for blocks that are different between two Amazon Elastic Block Store snapshots of the same volume/snapshot lineage.</p>
715    async fn list_changed_blocks(
716        &self,
717        input: ListChangedBlocksRequest,
718    ) -> Result<ListChangedBlocksResponse, RusotoError<ListChangedBlocksError>>;
719
720    /// <p>Returns the block indexes and block tokens for blocks in an Amazon Elastic Block Store snapshot.</p>
721    async fn list_snapshot_blocks(
722        &self,
723        input: ListSnapshotBlocksRequest,
724    ) -> Result<ListSnapshotBlocksResponse, RusotoError<ListSnapshotBlocksError>>;
725
726    /// <p>Writes a block of data to a block in the snapshot. If the specified block contains data, the existing data is overwritten. The target snapshot must be in the <code>pending</code> state.</p> <p>Data written to a snapshot must be aligned with 512-byte sectors.</p>
727    async fn put_snapshot_block(
728        &self,
729        input: PutSnapshotBlockRequest,
730    ) -> Result<PutSnapshotBlockResponse, RusotoError<PutSnapshotBlockError>>;
731
732    /// <p>Creates a new Amazon EBS snapshot. The new snapshot enters the <code>pending</code> state after the request completes. </p> <p>After creating the snapshot, use <a href="https://docs.aws.amazon.com/ebs/latest/APIReference/API_PutSnapshotBlock.html"> PutSnapshotBlock</a> to write blocks of data to the snapshot.</p>
733    async fn start_snapshot(
734        &self,
735        input: StartSnapshotRequest,
736    ) -> Result<StartSnapshotResponse, RusotoError<StartSnapshotError>>;
737}
738/// A client for the Amazon EBS API.
739#[derive(Clone)]
740pub struct EbsClient {
741    client: Client,
742    region: region::Region,
743}
744
745impl EbsClient {
746    /// Creates a client backed by the default tokio event loop.
747    ///
748    /// The client will use the default credentials provider and tls client.
749    pub fn new(region: region::Region) -> EbsClient {
750        EbsClient {
751            client: Client::shared(),
752            region,
753        }
754    }
755
756    pub fn new_with<P, D>(
757        request_dispatcher: D,
758        credentials_provider: P,
759        region: region::Region,
760    ) -> EbsClient
761    where
762        P: ProvideAwsCredentials + Send + Sync + 'static,
763        D: DispatchSignedRequest + Send + Sync + 'static,
764    {
765        EbsClient {
766            client: Client::new_with(credentials_provider, request_dispatcher),
767            region,
768        }
769    }
770
771    pub fn new_with_client(client: Client, region: region::Region) -> EbsClient {
772        EbsClient { client, region }
773    }
774}
775
776#[async_trait]
777impl Ebs for EbsClient {
778    /// <p>Seals and completes the snapshot after all of the required blocks of data have been written to it. Completing the snapshot changes the status to <code>completed</code>. You cannot write new blocks to a snapshot after it has been completed.</p>
779    #[allow(unused_mut)]
780    async fn complete_snapshot(
781        &self,
782        input: CompleteSnapshotRequest,
783    ) -> Result<CompleteSnapshotResponse, RusotoError<CompleteSnapshotError>> {
784        let request_uri = format!(
785            "/snapshots/completion/{snapshot_id}",
786            snapshot_id = input.snapshot_id
787        );
788
789        let mut request = SignedRequest::new("POST", "ebs", &self.region, &request_uri);
790        request.set_content_type("application/x-amz-json-1.1".to_owned());
791
792        request.add_header(
793            "x-amz-ChangedBlocksCount",
794            &input.changed_blocks_count.to_string(),
795        );
796        request.add_optional_header("x-amz-Checksum", input.checksum.as_ref());
797        request.add_optional_header(
798            "x-amz-Checksum-Aggregation-Method",
799            input.checksum_aggregation_method.as_ref(),
800        );
801        request.add_optional_header(
802            "x-amz-Checksum-Algorithm",
803            input.checksum_algorithm.as_ref(),
804        );
805
806        let mut response = self
807            .client
808            .sign_and_dispatch(request)
809            .await
810            .map_err(RusotoError::from)?;
811        if response.status.as_u16() == 202 {
812            let mut response = response.buffer().await.map_err(RusotoError::HttpDispatch)?;
813            let result = proto::json::ResponsePayload::new(&response)
814                .deserialize::<CompleteSnapshotResponse, _>()?;
815
816            Ok(result)
817        } else {
818            let response = response.buffer().await.map_err(RusotoError::HttpDispatch)?;
819            Err(CompleteSnapshotError::from_response(response))
820        }
821    }
822
823    /// <p>Returns the data in a block in an Amazon Elastic Block Store snapshot.</p>
824    #[allow(unused_mut)]
825    async fn get_snapshot_block(
826        &self,
827        input: GetSnapshotBlockRequest,
828    ) -> Result<GetSnapshotBlockResponse, RusotoError<GetSnapshotBlockError>> {
829        let request_uri = format!(
830            "/snapshots/{snapshot_id}/blocks/{block_index}",
831            block_index = input.block_index,
832            snapshot_id = input.snapshot_id
833        );
834
835        let mut request = SignedRequest::new("GET", "ebs", &self.region, &request_uri);
836        request.set_content_type("application/x-amz-json-1.1".to_owned());
837
838        let mut params = Params::new();
839        params.put("blockToken", &input.block_token);
840        request.set_params(params);
841
842        let mut response = self
843            .client
844            .sign_and_dispatch(request)
845            .await
846            .map_err(RusotoError::from)?;
847        if response.status.is_success() {
848            let mut response = response.buffer().await.map_err(RusotoError::HttpDispatch)?;
849
850            let mut result = GetSnapshotBlockResponse::default();
851            result.block_data = Some(response.body);
852
853            result.checksum = response.headers.remove("x-amz-Checksum");
854            result.checksum_algorithm = response.headers.remove("x-amz-Checksum-Algorithm");
855            result.data_length = response
856                .headers
857                .remove("x-amz-Data-Length")
858                .map(|value| value.parse::<i64>().unwrap());
859
860            Ok(result)
861        } else {
862            let response = response.buffer().await.map_err(RusotoError::HttpDispatch)?;
863            Err(GetSnapshotBlockError::from_response(response))
864        }
865    }
866
867    /// <p>Returns the block indexes and block tokens for blocks that are different between two Amazon Elastic Block Store snapshots of the same volume/snapshot lineage.</p>
868    #[allow(unused_mut)]
869    async fn list_changed_blocks(
870        &self,
871        input: ListChangedBlocksRequest,
872    ) -> Result<ListChangedBlocksResponse, RusotoError<ListChangedBlocksError>> {
873        let request_uri = format!(
874            "/snapshots/{second_snapshot_id}/changedblocks",
875            second_snapshot_id = input.second_snapshot_id
876        );
877
878        let mut request = SignedRequest::new("GET", "ebs", &self.region, &request_uri);
879        request.set_content_type("application/x-amz-json-1.1".to_owned());
880
881        let mut params = Params::new();
882        if let Some(ref x) = input.first_snapshot_id {
883            params.put("firstSnapshotId", x);
884        }
885        if let Some(ref x) = input.max_results {
886            params.put("maxResults", x);
887        }
888        if let Some(ref x) = input.next_token {
889            params.put("pageToken", x);
890        }
891        if let Some(ref x) = input.starting_block_index {
892            params.put("startingBlockIndex", x);
893        }
894        request.set_params(params);
895
896        let mut response = self
897            .client
898            .sign_and_dispatch(request)
899            .await
900            .map_err(RusotoError::from)?;
901        if response.status.is_success() {
902            let mut response = response.buffer().await.map_err(RusotoError::HttpDispatch)?;
903            let result = proto::json::ResponsePayload::new(&response)
904                .deserialize::<ListChangedBlocksResponse, _>()?;
905
906            Ok(result)
907        } else {
908            let response = response.buffer().await.map_err(RusotoError::HttpDispatch)?;
909            Err(ListChangedBlocksError::from_response(response))
910        }
911    }
912
913    /// <p>Returns the block indexes and block tokens for blocks in an Amazon Elastic Block Store snapshot.</p>
914    #[allow(unused_mut)]
915    async fn list_snapshot_blocks(
916        &self,
917        input: ListSnapshotBlocksRequest,
918    ) -> Result<ListSnapshotBlocksResponse, RusotoError<ListSnapshotBlocksError>> {
919        let request_uri = format!(
920            "/snapshots/{snapshot_id}/blocks",
921            snapshot_id = input.snapshot_id
922        );
923
924        let mut request = SignedRequest::new("GET", "ebs", &self.region, &request_uri);
925        request.set_content_type("application/x-amz-json-1.1".to_owned());
926
927        let mut params = Params::new();
928        if let Some(ref x) = input.max_results {
929            params.put("maxResults", x);
930        }
931        if let Some(ref x) = input.next_token {
932            params.put("pageToken", x);
933        }
934        if let Some(ref x) = input.starting_block_index {
935            params.put("startingBlockIndex", x);
936        }
937        request.set_params(params);
938
939        let mut response = self
940            .client
941            .sign_and_dispatch(request)
942            .await
943            .map_err(RusotoError::from)?;
944        if response.status.is_success() {
945            let mut response = response.buffer().await.map_err(RusotoError::HttpDispatch)?;
946            let result = proto::json::ResponsePayload::new(&response)
947                .deserialize::<ListSnapshotBlocksResponse, _>()?;
948
949            Ok(result)
950        } else {
951            let response = response.buffer().await.map_err(RusotoError::HttpDispatch)?;
952            Err(ListSnapshotBlocksError::from_response(response))
953        }
954    }
955
956    /// <p>Writes a block of data to a block in the snapshot. If the specified block contains data, the existing data is overwritten. The target snapshot must be in the <code>pending</code> state.</p> <p>Data written to a snapshot must be aligned with 512-byte sectors.</p>
957    #[allow(unused_mut)]
958    async fn put_snapshot_block(
959        &self,
960        input: PutSnapshotBlockRequest,
961    ) -> Result<PutSnapshotBlockResponse, RusotoError<PutSnapshotBlockError>> {
962        let request_uri = format!(
963            "/snapshots/{snapshot_id}/blocks/{block_index}",
964            block_index = input.block_index,
965            snapshot_id = input.snapshot_id
966        );
967
968        let mut request = SignedRequest::new("PUT", "ebs", &self.region, &request_uri);
969        request.set_content_type("application/x-amz-json-1.1".to_owned());
970
971        let encoded = Some(input.block_data.to_owned());
972        request.set_payload(encoded);
973        request.add_header("x-amz-Checksum", &input.checksum.to_string());
974        request.add_header(
975            "x-amz-Checksum-Algorithm",
976            &input.checksum_algorithm.to_string(),
977        );
978        request.add_header("x-amz-Data-Length", &input.data_length.to_string());
979        request.add_optional_header("x-amz-Progress", input.progress.as_ref());
980
981        let mut response = self
982            .client
983            .sign_and_dispatch(request)
984            .await
985            .map_err(RusotoError::from)?;
986        if response.status.as_u16() == 201 {
987            let mut response = response.buffer().await.map_err(RusotoError::HttpDispatch)?;
988            let mut result = proto::json::ResponsePayload::new(&response)
989                .deserialize::<PutSnapshotBlockResponse, _>()?;
990            result.checksum = response.headers.remove("x-amz-Checksum");
991            result.checksum_algorithm = response.headers.remove("x-amz-Checksum-Algorithm");
992
993            Ok(result)
994        } else {
995            let response = response.buffer().await.map_err(RusotoError::HttpDispatch)?;
996            Err(PutSnapshotBlockError::from_response(response))
997        }
998    }
999
1000    /// <p>Creates a new Amazon EBS snapshot. The new snapshot enters the <code>pending</code> state after the request completes. </p> <p>After creating the snapshot, use <a href="https://docs.aws.amazon.com/ebs/latest/APIReference/API_PutSnapshotBlock.html"> PutSnapshotBlock</a> to write blocks of data to the snapshot.</p>
1001    #[allow(unused_mut)]
1002    async fn start_snapshot(
1003        &self,
1004        input: StartSnapshotRequest,
1005    ) -> Result<StartSnapshotResponse, RusotoError<StartSnapshotError>> {
1006        let request_uri = "/snapshots";
1007
1008        let mut request = SignedRequest::new("POST", "ebs", &self.region, &request_uri);
1009        request.set_content_type("application/x-amz-json-1.1".to_owned());
1010
1011        let encoded = Some(serde_json::to_vec(&input).unwrap());
1012        request.set_payload(encoded);
1013
1014        let mut response = self
1015            .client
1016            .sign_and_dispatch(request)
1017            .await
1018            .map_err(RusotoError::from)?;
1019        if response.status.as_u16() == 201 {
1020            let mut response = response.buffer().await.map_err(RusotoError::HttpDispatch)?;
1021            let result = proto::json::ResponsePayload::new(&response)
1022                .deserialize::<StartSnapshotResponse, _>()?;
1023
1024            Ok(result)
1025        } else {
1026            let response = response.buffer().await.map_err(RusotoError::HttpDispatch)?;
1027            Err(StartSnapshotError::from_response(response))
1028        }
1029    }
1030}