1use crate::{
8 AwsHttpClient, Result,
9 ops::kms::KmsOps,
10 types::kms::{
11 DescribeKeyRequest, DescribeKeyResponse, EnableKeyRotationRequest,
12 GetKeyRotationStatusRequest, GetKeyRotationStatusResponse, ListKeysRequest,
13 ListKeysResponse,
14 },
15};
16
17pub struct KmsClient<'a> {
19 ops: KmsOps<'a>,
20}
21
22impl<'a> KmsClient<'a> {
23 pub(crate) fn new(client: &'a AwsHttpClient) -> Self {
25 Self {
26 ops: KmsOps::new(client),
27 }
28 }
29
30 pub async fn list_keys(&self, body: &ListKeysRequest) -> Result<ListKeysResponse> {
32 self.ops.list_keys(body).await
33 }
34
35 pub async fn describe_key(&self, body: &DescribeKeyRequest) -> Result<DescribeKeyResponse> {
37 self.ops.describe_key(body).await
38 }
39
40 pub async fn get_key_rotation_status(
42 &self,
43 body: &GetKeyRotationStatusRequest,
44 ) -> Result<GetKeyRotationStatusResponse> {
45 self.ops.get_key_rotation_status(body).await
46 }
47
48 pub async fn enable_key_rotation(&self, body: &EnableKeyRotationRequest) -> Result<()> {
50 self.ops.enable_key_rotation(body).await
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[tokio::test]
59 async fn list_keys_returns_key_entries() {
60 let mut mock = crate::MockClient::new();
61 mock.expect_post("/").returning_json(serde_json::json!({
62 "Keys": [
63 {
64 "KeyId": "abc-123",
65 "KeyArn": "arn:aws:kms:us-east-1:123456789012:key/abc-123"
66 },
67 {
68 "KeyId": "def-456",
69 "KeyArn": "arn:aws:kms:us-east-1:123456789012:key/def-456"
70 }
71 ],
72 "NextMarker": null,
73 "Truncated": false
74 }));
75 let client = crate::AwsHttpClient::from_mock(mock);
76 let result = client
77 .kms()
78 .list_keys(&ListKeysRequest::default())
79 .await
80 .unwrap();
81 assert_eq!(result.keys.len(), 2);
82 assert_eq!(result.keys[0].key_id.as_deref(), Some("abc-123"));
83 assert_eq!(
84 result.keys[0].key_arn.as_deref(),
85 Some("arn:aws:kms:us-east-1:123456789012:key/abc-123")
86 );
87 assert_eq!(result.truncated, Some(false));
88 }
89
90 #[tokio::test]
91 async fn describe_key_returns_metadata() {
92 let mut mock = crate::MockClient::new();
93 mock.expect_post("/").returning_json(serde_json::json!({
94 "KeyMetadata": {
95 "KeyId": "abc-123",
96 "Arn": "arn:aws:kms:us-east-1:123456789012:key/abc-123",
97 "CreationDate": 1700000000.0,
98 "Enabled": true,
99 "Description": "test key",
100 "KeyUsage": "ENCRYPT_DECRYPT",
101 "KeyState": "Enabled",
102 "KeyManager": "CUSTOMER",
103 "KeySpec": "SYMMETRIC_DEFAULT",
104 "MultiRegion": false
105 }
106 }));
107 let client = crate::AwsHttpClient::from_mock(mock);
108 let result = client
109 .kms()
110 .describe_key(&DescribeKeyRequest {
111 key_id: "abc-123".to_string(),
112 })
113 .await
114 .unwrap();
115 let meta = result.key_metadata.unwrap();
116 assert_eq!(meta.key_id.as_str(), "abc-123");
117 assert_eq!(
118 meta.arn.as_deref(),
119 Some("arn:aws:kms:us-east-1:123456789012:key/abc-123")
120 );
121 assert_eq!(meta.enabled, Some(true));
122 assert_eq!(meta.key_state.as_deref(), Some("Enabled"));
123 assert_eq!(meta.key_manager.as_deref(), Some("CUSTOMER"));
124 assert_eq!(meta.creation_date, Some(1700000000.0));
125 }
126
127 #[tokio::test]
128 async fn get_key_rotation_status_returns_enabled() {
129 let mut mock = crate::MockClient::new();
130 mock.expect_post("/").returning_json(serde_json::json!({
131 "KeyRotationEnabled": true,
132 "KeyId": "abc-123",
133 "RotationPeriodInDays": 365,
134 "NextRotationDate": 1731536000.0
135 }));
136 let client = crate::AwsHttpClient::from_mock(mock);
137 let result = client
138 .kms()
139 .get_key_rotation_status(&GetKeyRotationStatusRequest {
140 key_id: "abc-123".to_string(),
141 })
142 .await
143 .unwrap();
144 assert_eq!(result.key_rotation_enabled, Some(true));
145 assert_eq!(result.key_id.as_deref(), Some("abc-123"));
146 assert_eq!(result.rotation_period_in_days, Some(365));
147 assert_eq!(result.next_rotation_date, Some(1731536000.0));
148 }
149
150 #[tokio::test]
151 async fn enable_key_rotation_returns_unit() {
152 let mut mock = crate::MockClient::new();
153 mock.expect_post("/").returning_json(serde_json::json!({}));
154 let client = crate::AwsHttpClient::from_mock(mock);
155 let result = client
156 .kms()
157 .enable_key_rotation(&EnableKeyRotationRequest {
158 key_id: "abc-123".to_string(),
159 ..Default::default()
160 })
161 .await;
162 assert!(result.is_ok(), "EnableKeyRotation should return Ok(())");
163 }
164}