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}