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    /// Get Active-Active PrivateLink configuration
175    ///
176    /// Gets the AWS PrivateLink configuration for an Active-Active (CRDB) subscription region.
177    ///
178    /// GET /subscriptions/{subscriptionId}/regions/{regionId}/private-link
179    ///
180    /// # Arguments
181    ///
182    /// * `subscription_id` - The subscription ID
183    /// * `region_id` - The region ID
184    ///
185    /// # Returns
186    ///
187    /// Returns the PrivateLink configuration for the region
188    pub async fn get_active_active(&self, subscription_id: i32, region_id: i32) -> Result<Value> {
189        self.client
190            .get(&format!(
191                "/subscriptions/{}/regions/{}/private-link",
192                subscription_id, region_id
193            ))
194            .await
195    }
196
197    /// Create Active-Active PrivateLink
198    ///
199    /// Creates a new AWS PrivateLink for an Active-Active (CRDB) subscription region.
200    ///
201    /// POST /subscriptions/{subscriptionId}/regions/{regionId}/private-link
202    ///
203    /// # Arguments
204    ///
205    /// * `subscription_id` - The subscription ID
206    /// * `region_id` - The region ID
207    /// * `request` - PrivateLink creation request
208    ///
209    /// # Returns
210    ///
211    /// Returns a task response
212    pub async fn create_active_active(
213        &self,
214        subscription_id: i32,
215        region_id: i32,
216        request: Value,
217    ) -> Result<Value> {
218        self.client
219            .post(
220                &format!(
221                    "/subscriptions/{}/regions/{}/private-link",
222                    subscription_id, region_id
223                ),
224                &request,
225            )
226            .await
227    }
228
229    /// Add principals to Active-Active PrivateLink
230    ///
231    /// Adds AWS principals to an Active-Active PrivateLink.
232    ///
233    /// POST /subscriptions/{subscriptionId}/regions/{regionId}/private-link/principals
234    ///
235    /// # Arguments
236    ///
237    /// * `subscription_id` - The subscription ID
238    /// * `region_id` - The region ID
239    /// * `request` - Principal to add
240    ///
241    /// # Returns
242    ///
243    /// Returns the updated configuration
244    pub async fn add_principals_active_active(
245        &self,
246        subscription_id: i32,
247        region_id: i32,
248        request: Value,
249    ) -> Result<Value> {
250        self.client
251            .post(
252                &format!(
253                    "/subscriptions/{}/regions/{}/private-link/principals",
254                    subscription_id, region_id
255                ),
256                &request,
257            )
258            .await
259    }
260
261    /// Remove principals from Active-Active PrivateLink
262    ///
263    /// Removes AWS principals from an Active-Active PrivateLink.
264    ///
265    /// DELETE /subscriptions/{subscriptionId}/regions/{regionId}/private-link/principals
266    ///
267    /// # Arguments
268    ///
269    /// * `subscription_id` - The subscription ID
270    /// * `region_id` - The region ID
271    /// * `request` - Principal to remove
272    ///
273    /// # Returns
274    ///
275    /// Returns confirmation of deletion
276    pub async fn remove_principals_active_active(
277        &self,
278        subscription_id: i32,
279        region_id: i32,
280        request: Value,
281    ) -> Result<Value> {
282        self.client
283            .delete_with_body(
284                &format!(
285                    "/subscriptions/{}/regions/{}/private-link/principals",
286                    subscription_id, region_id
287                ),
288                request,
289            )
290            .await
291    }
292
293    /// Get Active-Active endpoint creation script
294    ///
295    /// Gets a script to create the VPC endpoint for an Active-Active region.
296    ///
297    /// GET /subscriptions/{subscriptionId}/regions/{regionId}/private-link/endpoint-script
298    ///
299    /// # Arguments
300    ///
301    /// * `subscription_id` - The subscription ID
302    /// * `region_id` - The region ID
303    ///
304    /// # Returns
305    ///
306    /// Returns the endpoint creation script
307    pub async fn get_endpoint_script_active_active(
308        &self,
309        subscription_id: i32,
310        region_id: i32,
311    ) -> Result<Value> {
312        self.client
313            .get(&format!(
314                "/subscriptions/{}/regions/{}/private-link/endpoint-script",
315                subscription_id, region_id
316            ))
317            .await
318    }
319}