Skip to main content

aws_lite_rs/api/
rds.rs

1//! Amazon Relational Database Service API client.
2//!
3//! Thin wrapper over generated ops. All URL construction and HTTP methods
4//! are in `ops::rds::RdsOps`. This layer adds:
5//! - Ergonomic method signatures
6
7use crate::{
8    AwsHttpClient, Result,
9    ops::rds::RdsOps,
10    types::rds::{
11        CreateDBSnapshotRequest, CreateDBSnapshotResponse, DeleteDBInstanceRequest,
12        DeleteDBInstanceResponse, DeleteDBSnapshotRequest, DeleteDBSnapshotResponse,
13        DescribeDBInstancesRequest, DescribeDBInstancesResponse,
14        DescribeDBSnapshotAttributesRequest, DescribeDBSnapshotAttributesResponse,
15        DescribeDBSnapshotsRequest, DescribeDBSnapshotsResponse, ModifyDBInstanceRequest,
16        ModifyDBInstanceResponse, ModifyDBSnapshotAttributeRequest,
17        ModifyDBSnapshotAttributeResponse, StartDBInstanceRequest, StartDBInstanceResponse,
18        StopDBInstanceRequest, StopDBInstanceResponse,
19    },
20};
21
22/// Client for the Amazon Relational Database Service API
23pub struct RdsClient<'a> {
24    ops: RdsOps<'a>,
25}
26
27impl<'a> RdsClient<'a> {
28    /// Create a new Amazon Relational Database Service API client
29    pub(crate) fn new(client: &'a AwsHttpClient) -> Self {
30        Self {
31            ops: RdsOps::new(client),
32        }
33    }
34
35    /// Describes provisioned RDS instances.
36    pub async fn describe_db_instances(
37        &self,
38        body: &DescribeDBInstancesRequest,
39    ) -> Result<DescribeDBInstancesResponse> {
40        self.ops.describe_db_instances(body).await
41    }
42
43    /// Returns information about DB snapshots.
44    pub async fn describe_db_snapshots(
45        &self,
46        body: &DescribeDBSnapshotsRequest,
47    ) -> Result<DescribeDBSnapshotsResponse> {
48        self.ops.describe_db_snapshots(body).await
49    }
50
51    /// Returns a list of DB snapshot attribute names and values for a manual DB snapshot.
52    pub async fn describe_db_snapshot_attributes(
53        &self,
54        body: &DescribeDBSnapshotAttributesRequest,
55    ) -> Result<DescribeDBSnapshotAttributesResponse> {
56        self.ops.describe_db_snapshot_attributes(body).await
57    }
58
59    /// Modifies settings for a DB instance.
60    pub async fn modify_db_instance(
61        &self,
62        body: &ModifyDBInstanceRequest,
63    ) -> Result<ModifyDBInstanceResponse> {
64        self.ops.modify_db_instance(body).await
65    }
66
67    /// Stops an Amazon RDS DB instance.
68    pub async fn stop_db_instance(
69        &self,
70        body: &StopDBInstanceRequest,
71    ) -> Result<StopDBInstanceResponse> {
72        self.ops.stop_db_instance(body).await
73    }
74
75    /// Starts an Amazon RDS DB instance that was stopped.
76    pub async fn start_db_instance(
77        &self,
78        body: &StartDBInstanceRequest,
79    ) -> Result<StartDBInstanceResponse> {
80        self.ops.start_db_instance(body).await
81    }
82
83    /// Deletes a previously provisioned DB instance.
84    pub async fn delete_db_instance(
85        &self,
86        body: &DeleteDBInstanceRequest,
87    ) -> Result<DeleteDBInstanceResponse> {
88        self.ops.delete_db_instance(body).await
89    }
90
91    /// Creates a snapshot of a DB instance.
92    pub async fn create_db_snapshot(
93        &self,
94        body: &CreateDBSnapshotRequest,
95    ) -> Result<CreateDBSnapshotResponse> {
96        self.ops.create_db_snapshot(body).await
97    }
98
99    /// Deletes a DB snapshot.
100    pub async fn delete_db_snapshot(
101        &self,
102        body: &DeleteDBSnapshotRequest,
103    ) -> Result<DeleteDBSnapshotResponse> {
104        self.ops.delete_db_snapshot(body).await
105    }
106
107    /// Adds an attribute and values to, or removes an attribute and values from, a manual DB snapshot.
108    pub async fn modify_db_snapshot_attribute(
109        &self,
110        body: &ModifyDBSnapshotAttributeRequest,
111    ) -> Result<ModifyDBSnapshotAttributeResponse> {
112        self.ops.modify_db_snapshot_attribute(body).await
113    }
114}
115
116#[cfg(test)]
117mod tests {
118    use crate::types::rds::*;
119
120    #[tokio::test]
121    async fn describe_db_instances_returns_parsed_response() {
122        let mut mock = crate::MockClient::new();
123        mock.expect_post("/").returning_bytes(
124            r#"<DescribeDBInstancesResponse><DescribeDBInstancesResult>
125                <DBInstances>
126                    <DBInstance>
127                        <DBInstanceIdentifier>my-db</DBInstanceIdentifier>
128                        <DBInstanceClass>db.t3.micro</DBInstanceClass>
129                        <Engine>mysql</Engine>
130                        <DBInstanceStatus>available</DBInstanceStatus>
131                        <AllocatedStorage>20</AllocatedStorage>
132                        <Endpoint>
133                            <Address>my-db.abc.us-east-1.rds.amazonaws.com</Address>
134                            <Port>3306</Port>
135                        </Endpoint>
136                    </DBInstance>
137                </DBInstances>
138            </DescribeDBInstancesResult></DescribeDBInstancesResponse>"#
139                .as_bytes()
140                .to_vec(),
141        );
142        let client = crate::AwsHttpClient::from_mock(mock);
143        let result = client
144            .rds()
145            .describe_db_instances(&DescribeDBInstancesRequest {
146                db_instance_identifier: Some("my-db".into()),
147                ..Default::default()
148            })
149            .await
150            .unwrap();
151        assert_eq!(result.db_instances.len(), 1);
152        let inst = &result.db_instances[0];
153        assert_eq!(inst.db_instance_identifier.as_deref(), Some("my-db"));
154        assert_eq!(inst.engine.as_deref(), Some("mysql"));
155        assert_eq!(inst.db_instance_status.as_deref(), Some("available"));
156        assert_eq!(inst.allocated_storage, Some(20));
157        let ep = inst.endpoint.as_ref().unwrap();
158        assert_eq!(
159            ep.address.as_deref(),
160            Some("my-db.abc.us-east-1.rds.amazonaws.com")
161        );
162        assert_eq!(ep.port, Some(3306));
163    }
164
165    #[tokio::test]
166    async fn describe_db_snapshots_returns_parsed_response() {
167        let mut mock = crate::MockClient::new();
168        mock.expect_post("/").returning_bytes(
169            r#"<DescribeDBSnapshotsResponse><DescribeDBSnapshotsResult>
170                <DBSnapshots>
171                    <DBSnapshot>
172                        <DBSnapshotIdentifier>my-snap</DBSnapshotIdentifier>
173                        <DBInstanceIdentifier>my-db</DBInstanceIdentifier>
174                        <Engine>mysql</Engine>
175                        <Status>available</Status>
176                        <AllocatedStorage>20</AllocatedStorage>
177                    </DBSnapshot>
178                </DBSnapshots>
179            </DescribeDBSnapshotsResult></DescribeDBSnapshotsResponse>"#
180                .as_bytes()
181                .to_vec(),
182        );
183        let client = crate::AwsHttpClient::from_mock(mock);
184        let result = client
185            .rds()
186            .describe_db_snapshots(&DescribeDBSnapshotsRequest {
187                db_snapshot_identifier: Some("my-snap".into()),
188                ..Default::default()
189            })
190            .await
191            .unwrap();
192        assert_eq!(result.db_snapshots.len(), 1);
193        let snap = &result.db_snapshots[0];
194        assert_eq!(snap.db_snapshot_identifier.as_deref(), Some("my-snap"));
195        assert_eq!(snap.db_instance_identifier.as_deref(), Some("my-db"));
196        assert_eq!(snap.engine.as_deref(), Some("mysql"));
197        assert_eq!(snap.status.as_deref(), Some("available"));
198    }
199
200    #[tokio::test]
201    async fn describe_db_snapshot_attributes_returns_parsed_response() {
202        let mut mock = crate::MockClient::new();
203        mock.expect_post("/").returning_bytes(
204            r#"<DescribeDBSnapshotAttributesResponse><DescribeDBSnapshotAttributesResult>
205                <DBSnapshotAttributesResult>
206                    <DBSnapshotIdentifier>my-snap</DBSnapshotIdentifier>
207                    <DBSnapshotAttributes>
208                        <DBSnapshotAttribute>
209                            <AttributeName>restore</AttributeName>
210                            <AttributeValues/>
211                        </DBSnapshotAttribute>
212                    </DBSnapshotAttributes>
213                </DBSnapshotAttributesResult>
214            </DescribeDBSnapshotAttributesResult></DescribeDBSnapshotAttributesResponse>"#
215                .as_bytes()
216                .to_vec(),
217        );
218        let client = crate::AwsHttpClient::from_mock(mock);
219        let result = client
220            .rds()
221            .describe_db_snapshot_attributes(&DescribeDBSnapshotAttributesRequest {
222                db_snapshot_identifier: "my-snap".into(),
223            })
224            .await
225            .unwrap();
226        let attrs = result.db_snapshot_attributes_result.as_ref().unwrap();
227        assert_eq!(attrs.db_snapshot_identifier.as_deref(), Some("my-snap"));
228        assert_eq!(attrs.db_snapshot_attributes.len(), 1);
229        assert_eq!(
230            attrs.db_snapshot_attributes[0].attribute_name.as_deref(),
231            Some("restore")
232        );
233    }
234
235    #[tokio::test]
236    async fn modify_db_instance_returns_parsed_response() {
237        let mut mock = crate::MockClient::new();
238        mock.expect_post("/").returning_bytes(
239            r#"<ModifyDBInstanceResponse><ModifyDBInstanceResult>
240                <DBInstance>
241                    <DBInstanceIdentifier>my-db</DBInstanceIdentifier>
242                    <DBInstanceClass>db.t3.micro</DBInstanceClass>
243                    <Engine>mysql</Engine>
244                    <DBInstanceStatus>available</DBInstanceStatus>
245                    <BackupRetentionPeriod>1</BackupRetentionPeriod>
246                </DBInstance>
247            </ModifyDBInstanceResult></ModifyDBInstanceResponse>"#
248                .as_bytes()
249                .to_vec(),
250        );
251        let client = crate::AwsHttpClient::from_mock(mock);
252        let result = client
253            .rds()
254            .modify_db_instance(&ModifyDBInstanceRequest {
255                db_instance_identifier: "my-db".into(),
256                backup_retention_period: Some(1),
257                apply_immediately: Some(true),
258                ..Default::default()
259            })
260            .await
261            .unwrap();
262        let inst = result.db_instance.as_ref().unwrap();
263        assert_eq!(inst.db_instance_identifier.as_deref(), Some("my-db"));
264        assert_eq!(inst.db_instance_status.as_deref(), Some("available"));
265        assert_eq!(inst.backup_retention_period, Some(1));
266    }
267
268    #[tokio::test]
269    async fn stop_db_instance_returns_parsed_response() {
270        let mut mock = crate::MockClient::new();
271        mock.expect_post("/").returning_bytes(
272            r#"<StopDBInstanceResponse><StopDBInstanceResult>
273                <DBInstance>
274                    <DBInstanceIdentifier>my-db</DBInstanceIdentifier>
275                    <DBInstanceStatus>stopping</DBInstanceStatus>
276                    <Engine>mysql</Engine>
277                </DBInstance>
278            </StopDBInstanceResult></StopDBInstanceResponse>"#
279                .as_bytes()
280                .to_vec(),
281        );
282        let client = crate::AwsHttpClient::from_mock(mock);
283        let result = client
284            .rds()
285            .stop_db_instance(&StopDBInstanceRequest {
286                db_instance_identifier: "my-db".into(),
287                ..Default::default()
288            })
289            .await
290            .unwrap();
291        let inst = result.db_instance.as_ref().unwrap();
292        assert_eq!(inst.db_instance_identifier.as_deref(), Some("my-db"));
293        assert_eq!(inst.db_instance_status.as_deref(), Some("stopping"));
294    }
295
296    #[tokio::test]
297    async fn start_db_instance_returns_parsed_response() {
298        let mut mock = crate::MockClient::new();
299        mock.expect_post("/").returning_bytes(
300            r#"<StartDBInstanceResponse><StartDBInstanceResult>
301                <DBInstance>
302                    <DBInstanceIdentifier>my-db</DBInstanceIdentifier>
303                    <DBInstanceStatus>starting</DBInstanceStatus>
304                    <Engine>mysql</Engine>
305                </DBInstance>
306            </StartDBInstanceResult></StartDBInstanceResponse>"#
307                .as_bytes()
308                .to_vec(),
309        );
310        let client = crate::AwsHttpClient::from_mock(mock);
311        let result = client
312            .rds()
313            .start_db_instance(&StartDBInstanceRequest {
314                db_instance_identifier: "my-db".into(),
315            })
316            .await
317            .unwrap();
318        let inst = result.db_instance.as_ref().unwrap();
319        assert_eq!(inst.db_instance_identifier.as_deref(), Some("my-db"));
320        assert_eq!(inst.db_instance_status.as_deref(), Some("starting"));
321    }
322
323    #[tokio::test]
324    async fn delete_db_instance_returns_parsed_response() {
325        let mut mock = crate::MockClient::new();
326        mock.expect_post("/").returning_bytes(
327            r#"<DeleteDBInstanceResponse><DeleteDBInstanceResult>
328                <DBInstance>
329                    <DBInstanceIdentifier>my-db</DBInstanceIdentifier>
330                    <DBInstanceStatus>deleting</DBInstanceStatus>
331                    <Engine>mysql</Engine>
332                </DBInstance>
333            </DeleteDBInstanceResult></DeleteDBInstanceResponse>"#
334                .as_bytes()
335                .to_vec(),
336        );
337        let client = crate::AwsHttpClient::from_mock(mock);
338        let result = client
339            .rds()
340            .delete_db_instance(&DeleteDBInstanceRequest {
341                db_instance_identifier: "my-db".into(),
342                skip_final_snapshot: Some(true),
343                delete_automated_backups: Some(true),
344                ..Default::default()
345            })
346            .await
347            .unwrap();
348        let inst = result.db_instance.as_ref().unwrap();
349        assert_eq!(inst.db_instance_identifier.as_deref(), Some("my-db"));
350        assert_eq!(inst.db_instance_status.as_deref(), Some("deleting"));
351    }
352
353    #[tokio::test]
354    async fn create_db_snapshot_returns_parsed_response() {
355        let mut mock = crate::MockClient::new();
356        mock.expect_post("/").returning_bytes(
357            r#"<CreateDBSnapshotResponse><CreateDBSnapshotResult>
358                <DBSnapshot>
359                    <DBSnapshotIdentifier>my-snap</DBSnapshotIdentifier>
360                    <DBInstanceIdentifier>my-db</DBInstanceIdentifier>
361                    <Engine>mysql</Engine>
362                    <Status>creating</Status>
363                    <AllocatedStorage>20</AllocatedStorage>
364                </DBSnapshot>
365            </CreateDBSnapshotResult></CreateDBSnapshotResponse>"#
366                .as_bytes()
367                .to_vec(),
368        );
369        let client = crate::AwsHttpClient::from_mock(mock);
370        let result = client
371            .rds()
372            .create_db_snapshot(&CreateDBSnapshotRequest {
373                db_snapshot_identifier: "my-snap".into(),
374                db_instance_identifier: "my-db".into(),
375                ..Default::default()
376            })
377            .await
378            .unwrap();
379        let snap = result.db_snapshot.as_ref().unwrap();
380        assert_eq!(snap.db_snapshot_identifier.as_deref(), Some("my-snap"));
381        assert_eq!(snap.db_instance_identifier.as_deref(), Some("my-db"));
382        assert_eq!(snap.status.as_deref(), Some("creating"));
383    }
384
385    #[tokio::test]
386    async fn delete_db_snapshot_returns_parsed_response() {
387        let mut mock = crate::MockClient::new();
388        mock.expect_post("/").returning_bytes(
389            r#"<DeleteDBSnapshotResponse><DeleteDBSnapshotResult>
390                <DBSnapshot>
391                    <DBSnapshotIdentifier>my-snap</DBSnapshotIdentifier>
392                    <DBInstanceIdentifier>my-db</DBInstanceIdentifier>
393                    <Status>deleted</Status>
394                </DBSnapshot>
395            </DeleteDBSnapshotResult></DeleteDBSnapshotResponse>"#
396                .as_bytes()
397                .to_vec(),
398        );
399        let client = crate::AwsHttpClient::from_mock(mock);
400        let result = client
401            .rds()
402            .delete_db_snapshot(&DeleteDBSnapshotRequest {
403                db_snapshot_identifier: "my-snap".into(),
404            })
405            .await
406            .unwrap();
407        let snap = result.db_snapshot.as_ref().unwrap();
408        assert_eq!(snap.db_snapshot_identifier.as_deref(), Some("my-snap"));
409        assert_eq!(snap.status.as_deref(), Some("deleted"));
410    }
411
412    #[tokio::test]
413    async fn modify_db_snapshot_attribute_returns_parsed_response() {
414        let mut mock = crate::MockClient::new();
415        mock.expect_post("/").returning_bytes(
416            r#"<ModifyDBSnapshotAttributeResponse><ModifyDBSnapshotAttributeResult>
417                <DBSnapshotAttributesResult>
418                    <DBSnapshotIdentifier>my-snap</DBSnapshotIdentifier>
419                    <DBSnapshotAttributes>
420                        <DBSnapshotAttribute>
421                            <AttributeName>restore</AttributeName>
422                            <AttributeValues>
423                                <AttributeValue>123456789012</AttributeValue>
424                            </AttributeValues>
425                        </DBSnapshotAttribute>
426                    </DBSnapshotAttributes>
427                </DBSnapshotAttributesResult>
428            </ModifyDBSnapshotAttributeResult></ModifyDBSnapshotAttributeResponse>"#
429                .as_bytes()
430                .to_vec(),
431        );
432        let client = crate::AwsHttpClient::from_mock(mock);
433        let result = client
434            .rds()
435            .modify_db_snapshot_attribute(&ModifyDBSnapshotAttributeRequest {
436                db_snapshot_identifier: "my-snap".into(),
437                attribute_name: "restore".into(),
438                values_to_add: vec!["123456789012".into()],
439                ..Default::default()
440            })
441            .await
442            .unwrap();
443        let attrs = result.db_snapshot_attributes_result.as_ref().unwrap();
444        assert_eq!(attrs.db_snapshot_identifier.as_deref(), Some("my-snap"));
445        assert_eq!(attrs.db_snapshot_attributes.len(), 1);
446        assert_eq!(
447            attrs.db_snapshot_attributes[0].attribute_name.as_deref(),
448            Some("restore")
449        );
450        assert!(
451            attrs.db_snapshot_attributes[0]
452                .attribute_values
453                .contains(&"123456789012".to_string())
454        );
455    }
456}