1use crate::{
10 AwsHttpClient, Result,
11 ops::efs::EfsOps,
12 types::efs::{DescribeFileSystemsResponse, FileSystemDescription},
13};
14
15pub struct EfsClient<'a> {
17 ops: EfsOps<'a>,
18}
19
20impl<'a> EfsClient<'a> {
21 pub(crate) fn new(client: &'a AwsHttpClient) -> Self {
23 Self {
24 ops: EfsOps::new(client),
25 }
26 }
27
28 pub async fn describe_file_systems(
34 &self,
35 marker: Option<&str>,
36 ) -> Result<DescribeFileSystemsResponse> {
37 self.ops
38 .describe_file_systems("", marker.unwrap_or(""), "", "")
39 .await
40 }
41
42 pub async fn list_all_file_systems(&self) -> Result<Vec<FileSystemDescription>> {
46 let mut all = Vec::new();
47 let mut marker: Option<String> = None;
48
49 loop {
50 let resp = self
51 .ops
52 .describe_file_systems("", marker.as_deref().unwrap_or(""), "", "")
53 .await?;
54 all.extend(resp.file_systems);
55 match resp.next_marker {
56 Some(m) if !m.is_empty() => marker = Some(m),
57 _ => break,
58 }
59 }
60
61 Ok(all)
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use serde_json::json;
68
69 #[tokio::test]
70 async fn test_describe_file_systems_returns_list() {
71 let mut mock = crate::MockClient::new();
72 mock.expect_get("/2015-02-01/file-systems")
73 .returning_json(json!({
74 "FileSystems": [
75 {
76 "OwnerId": "123456789012",
77 "FileSystemId": "fs-0123456789abcdef0",
78 "FileSystemArn": "arn:aws:elasticfilesystem:us-east-1:123456789012:file-system/fs-0123456789abcdef0",
79 "CreationTime": "2024-01-15T10:00:00Z",
80 "LifeCycleState": "available",
81 "Name": "my-efs",
82 "NumberOfMountTargets": 2,
83 "PerformanceMode": "generalPurpose",
84 "Encrypted": true,
85 "KmsKeyId": "arn:aws:kms:us-east-1:123456789012:key/mrk-abc123",
86 "ThroughputMode": "bursting",
87 "Tags": [{"Key": "Name", "Value": "my-efs"}]
88 }
89 ]
90 }))
91 .times(1);
92
93 let client = crate::AwsHttpClient::from_mock(mock);
94 let efs = client.efs();
95 let resp = efs.describe_file_systems(None).await.unwrap();
96 assert_eq!(resp.file_systems.len(), 1);
97 let fs = &resp.file_systems[0];
98 assert_eq!(fs.file_system_id, "fs-0123456789abcdef0");
99 assert_eq!(fs.encrypted, Some(true));
100 assert_eq!(fs.life_cycle_state, "available");
101 assert_eq!(fs.tags.len(), 1);
102 assert_eq!(fs.tags[0].key, "Name");
103 }
104
105 #[tokio::test]
106 async fn test_list_all_file_systems_paginates() {
107 let mut mock = crate::MockClient::new();
108 mock.expect_get("/2015-02-01/file-systems")
111 .returning_json_sequence(vec![
112 json!({
113 "FileSystems": [{
114 "OwnerId": "123456789012",
115 "FileSystemId": "fs-aaa",
116 "CreationTime": "2024-01-15T10:00:00Z",
117 "LifeCycleState": "available",
118 "NumberOfMountTargets": 0,
119 "PerformanceMode": "generalPurpose",
120 "Encrypted": false,
121 "Tags": []
122 }],
123 "NextMarker": "page2"
124 }),
125 json!({
126 "FileSystems": [{
127 "OwnerId": "123456789012",
128 "FileSystemId": "fs-bbb",
129 "CreationTime": "2024-01-15T11:00:00Z",
130 "LifeCycleState": "available",
131 "NumberOfMountTargets": 1,
132 "PerformanceMode": "generalPurpose",
133 "Encrypted": true,
134 "Tags": []
135 }]
136 }),
137 ])
138 .times(2);
139
140 let client = crate::AwsHttpClient::from_mock(mock);
141 let all = client.efs().list_all_file_systems().await.unwrap();
142 assert_eq!(all.len(), 2);
143 assert_eq!(all[0].file_system_id, "fs-aaa");
144 assert_eq!(all[0].encrypted, Some(false));
145 assert_eq!(all[1].file_system_id, "fs-bbb");
146 assert_eq!(all[1].encrypted, Some(true));
147 }
148
149 #[tokio::test]
150 async fn test_describe_file_systems_empty() {
151 let mut mock = crate::MockClient::new();
152 mock.expect_get("/2015-02-01/file-systems")
153 .returning_json(json!({"FileSystems": []}))
154 .times(1);
155
156 let client = crate::AwsHttpClient::from_mock(mock);
157 let resp = client.efs().describe_file_systems(None).await.unwrap();
158 assert!(resp.file_systems.is_empty());
159 }
160}