Skip to main content

aws_lite_rs/api/
kms.rs

1//! AWS Key Management Service API client.
2//!
3//! Thin wrapper over generated ops. All URL construction and HTTP methods
4//! are in `ops::kms::KmsOps`. This layer adds:
5//! - Ergonomic method signatures
6
7use crate::{
8    AwsHttpClient, Result,
9    ops::kms::KmsOps,
10    types::kms::{
11        DescribeKeyRequest, DescribeKeyResponse, EnableKeyRotationRequest,
12        GetKeyRotationStatusRequest, GetKeyRotationStatusResponse, ListKeysRequest,
13        ListKeysResponse,
14    },
15};
16
17/// Client for the AWS Key Management Service API
18pub struct KmsClient<'a> {
19    ops: KmsOps<'a>,
20}
21
22impl<'a> KmsClient<'a> {
23    /// Create a new AWS Key Management Service API client
24    pub(crate) fn new(client: &'a AwsHttpClient) -> Self {
25        Self {
26            ops: KmsOps::new(client),
27        }
28    }
29
30    /// Lists the key ARNs of all KMS keys in the current account and region.
31    pub async fn list_keys(&self, body: &ListKeysRequest) -> Result<ListKeysResponse> {
32        self.ops.list_keys(body).await
33    }
34
35    /// Provides detailed information about a KMS key.
36    pub async fn describe_key(&self, body: &DescribeKeyRequest) -> Result<DescribeKeyResponse> {
37        self.ops.describe_key(body).await
38    }
39
40    /// Gets a Boolean value that indicates whether automatic rotation of the key material is enabled for the specified KMS key.
41    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    /// Enables automatic rotation of the key material for the specified symmetric encryption KMS key.
49    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}