Skip to main content

redis_cloud/connectivity/
private_link.rs

1//! AWS PrivateLink connectivity operations
2//!
3//! This module provides AWS PrivateLink connectivity functionality for Redis Cloud,
4//! enabling secure, private connections from AWS VPCs to Redis Cloud databases.
5//!
6//! # Overview
7//!
8//! AWS PrivateLink allows you to connect to Redis Cloud from your AWS VPC without
9//! traversing the public internet. This provides enhanced security and potentially
10//! lower latency.
11//!
12//! # Features
13//!
14//! - **PrivateLink Management**: Create and retrieve PrivateLink configurations
15//! - **Principal Management**: Control which AWS principals can access the service
16//! - **Endpoint Scripts**: Get scripts to create endpoints in your AWS account
17//! - **Active-Active Support**: PrivateLink for CRDB (Active-Active) databases
18//!
19//! # Example Usage
20//!
21//! ```no_run
22//! use redis_cloud::{CloudClient, PrivateLinkHandler};
23//! use serde_json::json;
24//!
25//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
26//! let client = CloudClient::builder()
27//!     .api_key("your-api-key")
28//!     .api_secret("your-api-secret")
29//!     .build()?;
30//!
31//! let handler = PrivateLinkHandler::new(client);
32//!
33//! // Create a PrivateLink
34//! let request = json!({
35//!     "shareName": "my-redis-share",
36//!     "principal": "123456789012",
37//!     "type": "aws_account",
38//!     "alias": "Production Account"
39//! });
40//! let result = handler.create(123, request).await?;
41//!
42//! // Get PrivateLink configuration
43//! let config = handler.get(123).await?;
44//! # Ok(())
45//! # }
46//! ```
47
48use crate::{CloudClient, Result};
49use serde_json::Value;
50
51/// AWS PrivateLink handler
52///
53/// Manages AWS PrivateLink connectivity for Redis Cloud subscriptions.
54pub struct PrivateLinkHandler {
55    client: CloudClient,
56}
57
58impl PrivateLinkHandler {
59    /// Create a new PrivateLink handler
60    pub fn new(client: CloudClient) -> Self {
61        Self { client }
62    }
63
64    /// Get PrivateLink configuration
65    ///
66    /// Gets the AWS PrivateLink configuration for a subscription.
67    ///
68    /// GET /subscriptions/{subscriptionId}/private-link
69    ///
70    /// # Arguments
71    ///
72    /// * `subscription_id` - The subscription ID
73    ///
74    /// # Returns
75    ///
76    /// Returns the PrivateLink configuration as JSON
77    pub async fn get(&self, subscription_id: i32) -> Result<Value> {
78        self.client
79            .get(&format!("/subscriptions/{}/private-link", subscription_id))
80            .await
81    }
82
83    /// Create a PrivateLink
84    ///
85    /// Creates a new AWS PrivateLink configuration for a subscription.
86    ///
87    /// POST /subscriptions/{subscriptionId}/private-link
88    ///
89    /// # Arguments
90    ///
91    /// * `subscription_id` - The subscription ID
92    /// * `request` - PrivateLink creation request (shareName, principal, type required)
93    ///
94    /// # Returns
95    ///
96    /// Returns a task response that can be tracked for completion
97    pub async fn create(&self, subscription_id: i32, request: Value) -> Result<Value> {
98        self.client
99            .post(
100                &format!("/subscriptions/{}/private-link", subscription_id),
101                &request,
102            )
103            .await
104    }
105
106    /// Add principals to PrivateLink
107    ///
108    /// Adds AWS principals (accounts, IAM roles, etc.) that can access the PrivateLink.
109    ///
110    /// POST /subscriptions/{subscriptionId}/private-link/principals
111    ///
112    /// # Arguments
113    ///
114    /// * `subscription_id` - The subscription ID
115    /// * `request` - Principal to add (principal required, type/alias optional)
116    ///
117    /// # Returns
118    ///
119    /// Returns the updated principal configuration
120    pub async fn add_principals(&self, subscription_id: i32, request: Value) -> Result<Value> {
121        self.client
122            .post(
123                &format!("/subscriptions/{}/private-link/principals", subscription_id),
124                &request,
125            )
126            .await
127    }
128
129    /// Remove principals from PrivateLink
130    ///
131    /// Removes AWS principals from the PrivateLink access list.
132    ///
133    /// DELETE /subscriptions/{subscriptionId}/private-link/principals
134    ///
135    /// # Arguments
136    ///
137    /// * `subscription_id` - The subscription ID
138    /// * `request` - Principal to remove (principal, type, alias)
139    ///
140    /// # Returns
141    ///
142    /// Returns confirmation of deletion
143    pub async fn remove_principals(&self, subscription_id: i32, request: Value) -> Result<Value> {
144        self.client
145            .delete_with_body(
146                &format!("/subscriptions/{}/private-link/principals", subscription_id),
147                request,
148            )
149            .await
150    }
151
152    /// Get endpoint creation script
153    ///
154    /// Gets a script to create the VPC endpoint in your AWS account.
155    ///
156    /// GET /subscriptions/{subscriptionId}/private-link/endpoint-script
157    ///
158    /// # Arguments
159    ///
160    /// * `subscription_id` - The subscription ID
161    ///
162    /// # Returns
163    ///
164    /// Returns the endpoint creation script
165    pub async fn get_endpoint_script(&self, subscription_id: i32) -> Result<Value> {
166        self.client
167            .get(&format!(
168                "/subscriptions/{}/private-link/endpoint-script",
169                subscription_id
170            ))
171            .await
172    }
173
174    /// Delete PrivateLink
175    ///
176    /// Deletes the AWS PrivateLink configuration for a subscription.
177    ///
178    /// DELETE /subscriptions/{subscriptionId}/private-link
179    ///
180    /// # Arguments
181    ///
182    /// * `subscription_id` - The subscription ID
183    ///
184    /// # Returns
185    ///
186    /// Returns task information for tracking the deletion
187    pub async fn delete(&self, subscription_id: i32) -> Result<Value> {
188        self.client
189            .delete_raw(&format!("/subscriptions/{}/private-link", subscription_id))
190            .await
191    }
192
193    /// Get Active-Active PrivateLink configuration
194    ///
195    /// Gets the AWS PrivateLink configuration for an Active-Active (CRDB) subscription region.
196    ///
197    /// GET /subscriptions/{subscriptionId}/regions/{regionId}/private-link
198    ///
199    /// # Arguments
200    ///
201    /// * `subscription_id` - The subscription ID
202    /// * `region_id` - The region ID
203    ///
204    /// # Returns
205    ///
206    /// Returns the PrivateLink configuration for the region
207    pub async fn get_active_active(&self, subscription_id: i32, region_id: i32) -> Result<Value> {
208        self.client
209            .get(&format!(
210                "/subscriptions/{}/regions/{}/private-link",
211                subscription_id, region_id
212            ))
213            .await
214    }
215
216    /// Create Active-Active PrivateLink
217    ///
218    /// Creates a new AWS PrivateLink for an Active-Active (CRDB) subscription region.
219    ///
220    /// POST /subscriptions/{subscriptionId}/regions/{regionId}/private-link
221    ///
222    /// # Arguments
223    ///
224    /// * `subscription_id` - The subscription ID
225    /// * `region_id` - The region ID
226    /// * `request` - PrivateLink creation request
227    ///
228    /// # Returns
229    ///
230    /// Returns a task response
231    pub async fn create_active_active(
232        &self,
233        subscription_id: i32,
234        region_id: i32,
235        request: Value,
236    ) -> Result<Value> {
237        self.client
238            .post(
239                &format!(
240                    "/subscriptions/{}/regions/{}/private-link",
241                    subscription_id, region_id
242                ),
243                &request,
244            )
245            .await
246    }
247
248    /// Add principals to Active-Active PrivateLink
249    ///
250    /// Adds AWS principals to an Active-Active PrivateLink.
251    ///
252    /// POST /subscriptions/{subscriptionId}/regions/{regionId}/private-link/principals
253    ///
254    /// # Arguments
255    ///
256    /// * `subscription_id` - The subscription ID
257    /// * `region_id` - The region ID
258    /// * `request` - Principal to add
259    ///
260    /// # Returns
261    ///
262    /// Returns the updated configuration
263    pub async fn add_principals_active_active(
264        &self,
265        subscription_id: i32,
266        region_id: i32,
267        request: Value,
268    ) -> Result<Value> {
269        self.client
270            .post(
271                &format!(
272                    "/subscriptions/{}/regions/{}/private-link/principals",
273                    subscription_id, region_id
274                ),
275                &request,
276            )
277            .await
278    }
279
280    /// Remove principals from Active-Active PrivateLink
281    ///
282    /// Removes AWS principals from an Active-Active PrivateLink.
283    ///
284    /// DELETE /subscriptions/{subscriptionId}/regions/{regionId}/private-link/principals
285    ///
286    /// # Arguments
287    ///
288    /// * `subscription_id` - The subscription ID
289    /// * `region_id` - The region ID
290    /// * `request` - Principal to remove
291    ///
292    /// # Returns
293    ///
294    /// Returns confirmation of deletion
295    pub async fn remove_principals_active_active(
296        &self,
297        subscription_id: i32,
298        region_id: i32,
299        request: Value,
300    ) -> Result<Value> {
301        self.client
302            .delete_with_body(
303                &format!(
304                    "/subscriptions/{}/regions/{}/private-link/principals",
305                    subscription_id, region_id
306                ),
307                request,
308            )
309            .await
310    }
311
312    /// Get Active-Active endpoint creation script
313    ///
314    /// Gets a script to create the VPC endpoint for an Active-Active region.
315    ///
316    /// GET /subscriptions/{subscriptionId}/regions/{regionId}/private-link/endpoint-script
317    ///
318    /// # Arguments
319    ///
320    /// * `subscription_id` - The subscription ID
321    /// * `region_id` - The region ID
322    ///
323    /// # Returns
324    ///
325    /// Returns the endpoint creation script
326    pub async fn get_endpoint_script_active_active(
327        &self,
328        subscription_id: i32,
329        region_id: i32,
330    ) -> Result<Value> {
331        self.client
332            .get(&format!(
333                "/subscriptions/{}/regions/{}/private-link/endpoint-script",
334                subscription_id, region_id
335            ))
336            .await
337    }
338}