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}