Skip to main content

redis_cloud/connectivity/
vpc_peering.rs

1//! VPC Peering connectivity operations
2//!
3//! Manages VPC peering connections between Redis Cloud VPCs and customer VPCs
4//! for both standard and Active-Active subscriptions.
5
6use crate::{CloudClient, Result};
7use serde::{Deserialize, Serialize};
8
9/// VPC peering creation request
10#[derive(Debug, Clone, Default, Serialize, Deserialize)]
11#[serde(rename_all = "camelCase")]
12pub struct VpcPeeringCreateRequest {
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub provider: Option<String>,
15
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub command_type: Option<String>,
18
19    /// AWS VPC ID
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub vpc_id: Option<String>,
22
23    /// AWS region
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub aws_region: Option<String>,
26
27    /// AWS account ID
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub aws_account_id: Option<String>,
30
31    /// VPC CIDR
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub vpc_cidr: Option<String>,
34
35    /// List of VPC CIDRs
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub vpc_cidrs: Option<Vec<String>>,
38
39    /// GCP project ID
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub gcp_project_id: Option<String>,
42
43    /// GCP network name
44    #[serde(skip_serializing_if = "Option::is_none")]
45    pub network_name: Option<String>,
46}
47
48/// Base VPC peering creation request (for backward compatibility)
49pub type VpcPeeringCreateBaseRequest = VpcPeeringCreateRequest;
50
51/// VPC peering update request for AWS
52#[derive(Debug, Clone, Serialize, Deserialize)]
53#[serde(rename_all = "camelCase")]
54pub struct VpcPeeringUpdateAwsRequest {
55    #[serde(skip_serializing_if = "Option::is_none")]
56    pub subscription_id: Option<i32>,
57
58    /// VPC Peering ID to update.
59    #[serde(skip_serializing_if = "Option::is_none")]
60    pub vpc_peering_id: Option<i32>,
61
62    /// Optional. VPC CIDR.
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub vpc_cidr: Option<String>,
65
66    /// Optional. List of VPC CIDRs.
67    #[serde(skip_serializing_if = "Option::is_none")]
68    pub vpc_cidrs: Option<Vec<String>>,
69
70    #[serde(skip_serializing_if = "Option::is_none")]
71    pub command_type: Option<String>,
72}
73
74/// VPC peering update request (generic)
75pub type VpcPeeringUpdateRequest = VpcPeeringUpdateAwsRequest;
76
77/// Task state update response
78pub use crate::types::TaskStateUpdate;
79
80/// VPC CIDR with status
81#[derive(Debug, Clone, Serialize, Deserialize)]
82#[serde(rename_all = "camelCase")]
83pub struct VpcCidr {
84    /// VPC CIDR block
85    #[serde(skip_serializing_if = "Option::is_none")]
86    pub vpc_cidr: Option<String>,
87
88    /// CIDR status (active/inactive)
89    #[serde(rename = "active", skip_serializing_if = "Option::is_none")]
90    pub status: Option<String>,
91}
92
93/// VPC Peering information
94#[derive(Debug, Clone, Serialize, Deserialize)]
95#[serde(rename_all = "camelCase")]
96pub struct VpcPeering {
97    /// VPC Peering ID
98    #[serde(rename = "vpcPeeringId", skip_serializing_if = "Option::is_none")]
99    pub id: Option<i32>,
100
101    /// Peering status (e.g., "active", "pending-acceptance")
102    #[serde(skip_serializing_if = "Option::is_none")]
103    pub status: Option<String>,
104
105    /// AWS account ID
106    #[serde(skip_serializing_if = "Option::is_none")]
107    pub aws_account_id: Option<String>,
108
109    /// AWS VPC peering connection ID
110    #[serde(rename = "awsPeeringUid", skip_serializing_if = "Option::is_none")]
111    pub aws_peering_id: Option<String>,
112
113    /// VPC ID
114    #[serde(rename = "vpcUid", skip_serializing_if = "Option::is_none")]
115    pub vpc_id: Option<String>,
116
117    /// VPC CIDR
118    #[serde(skip_serializing_if = "Option::is_none")]
119    pub vpc_cidr: Option<String>,
120
121    /// List of VPC CIDRs with status
122    #[serde(skip_serializing_if = "Option::is_none")]
123    pub vpc_cidrs: Option<Vec<VpcCidr>>,
124
125    /// GCP project UID
126    #[serde(rename = "projectUid", skip_serializing_if = "Option::is_none")]
127    pub gcp_project_uid: Option<String>,
128
129    /// GCP network name
130    #[serde(skip_serializing_if = "Option::is_none")]
131    pub network_name: Option<String>,
132
133    /// Redis GCP project UID
134    #[serde(skip_serializing_if = "Option::is_none")]
135    pub redis_project_uid: Option<String>,
136
137    /// Redis GCP network name
138    #[serde(skip_serializing_if = "Option::is_none")]
139    pub redis_network_name: Option<String>,
140
141    /// Cloud peering ID (GCP)
142    #[serde(skip_serializing_if = "Option::is_none")]
143    pub cloud_peering_id: Option<String>,
144
145    /// Cloud provider region
146    #[serde(rename = "regionName", skip_serializing_if = "Option::is_none")]
147    pub region: Option<String>,
148
149    /// Cloud provider (AWS, GCP, Azure)
150    #[serde(skip_serializing_if = "Option::is_none")]
151    pub provider: Option<String>,
152}
153
154/// Active-Active VPC Peering information
155#[derive(Debug, Clone, Serialize, Deserialize)]
156#[serde(rename_all = "camelCase")]
157pub struct ActiveActiveVpcPeering {
158    /// VPC Peering ID
159    #[serde(skip_serializing_if = "Option::is_none")]
160    pub id: Option<i32>,
161
162    /// Peering status
163    #[serde(skip_serializing_if = "Option::is_none")]
164    pub status: Option<String>,
165
166    /// Region ID
167    #[serde(skip_serializing_if = "Option::is_none")]
168    pub region_id: Option<i32>,
169
170    /// Region name
171    #[serde(skip_serializing_if = "Option::is_none")]
172    pub region_name: Option<String>,
173
174    /// AWS account ID
175    #[serde(skip_serializing_if = "Option::is_none")]
176    pub aws_account_id: Option<String>,
177
178    /// AWS VPC peering UID
179    #[serde(rename = "awsPeeringUid", skip_serializing_if = "Option::is_none")]
180    pub aws_peering_id: Option<String>,
181
182    /// VPC UID
183    #[serde(rename = "vpcUid", skip_serializing_if = "Option::is_none")]
184    pub vpc_id: Option<String>,
185
186    /// VPC CIDR
187    #[serde(skip_serializing_if = "Option::is_none")]
188    pub vpc_cidr: Option<String>,
189
190    /// List of VPC CIDRs with status
191    #[serde(skip_serializing_if = "Option::is_none")]
192    pub vpc_cidrs: Option<Vec<VpcCidr>>,
193
194    /// GCP project UID
195    #[serde(rename = "vpcProjectUid", skip_serializing_if = "Option::is_none")]
196    pub gcp_project_uid: Option<String>,
197
198    /// GCP network name
199    #[serde(rename = "vpcNetworkName", skip_serializing_if = "Option::is_none")]
200    pub network_name: Option<String>,
201
202    /// Redis GCP project UID
203    #[serde(skip_serializing_if = "Option::is_none")]
204    pub redis_project_uid: Option<String>,
205
206    /// Redis GCP network name
207    #[serde(skip_serializing_if = "Option::is_none")]
208    pub redis_network_name: Option<String>,
209
210    /// Cloud peering ID
211    #[serde(skip_serializing_if = "Option::is_none")]
212    pub cloud_peering_id: Option<String>,
213
214    /// Source region
215    #[serde(skip_serializing_if = "Option::is_none")]
216    pub source_region: Option<String>,
217
218    /// Destination region
219    #[serde(skip_serializing_if = "Option::is_none")]
220    pub destination_region: Option<String>,
221}
222
223/// Active-Active VPC Peering region
224#[derive(Debug, Clone, Serialize, Deserialize)]
225#[serde(rename_all = "camelCase")]
226pub struct ActiveActiveVpcRegion {
227    /// Region ID
228    #[serde(skip_serializing_if = "Option::is_none")]
229    pub id: Option<i32>,
230
231    /// Source region name
232    #[serde(rename = "region", skip_serializing_if = "Option::is_none")]
233    pub source_region: Option<String>,
234
235    /// VPC Peerings in this region
236    #[serde(skip_serializing_if = "Option::is_none")]
237    pub vpc_peerings: Option<Vec<ActiveActiveVpcPeering>>,
238}
239
240/// Active-Active VPC Peering list response
241#[derive(Debug, Clone, Serialize, Deserialize)]
242#[serde(rename_all = "camelCase")]
243pub struct ActiveActiveVpcPeeringList {
244    /// Subscription ID
245    #[serde(skip_serializing_if = "Option::is_none")]
246    pub subscription_id: Option<i32>,
247
248    /// Regions with VPC peerings
249    #[serde(skip_serializing_if = "Option::is_none")]
250    pub regions: Option<Vec<ActiveActiveVpcRegion>>,
251}
252
253/// VPC Peering handler
254pub struct VpcPeeringHandler {
255    client: CloudClient,
256}
257
258impl VpcPeeringHandler {
259    /// Create a new VPC peering handler
260    #[must_use]
261    pub fn new(client: CloudClient) -> Self {
262        Self { client }
263    }
264
265    // ========================================================================
266    // Standard VPC Peering
267    // ========================================================================
268
269    /// Get VPC peering for subscription
270    pub async fn get(&self, subscription_id: i32) -> Result<TaskStateUpdate> {
271        self.client
272            .get(&format!("/subscriptions/{subscription_id}/peerings"))
273            .await
274    }
275
276    /// Create VPC peering
277    pub async fn create(
278        &self,
279        subscription_id: i32,
280        request: &VpcPeeringCreateRequest,
281    ) -> Result<TaskStateUpdate> {
282        self.client
283            .post(
284                &format!("/subscriptions/{subscription_id}/peerings"),
285                request,
286            )
287            .await
288    }
289
290    /// Delete VPC peering
291    pub async fn delete(&self, subscription_id: i32, peering_id: i32) -> Result<serde_json::Value> {
292        self.client
293            .delete(&format!(
294                "/subscriptions/{subscription_id}/peerings/{peering_id}"
295            ))
296            .await?;
297        Ok(serde_json::Value::Null)
298    }
299
300    /// Update VPC peering
301    pub async fn update(
302        &self,
303        subscription_id: i32,
304        peering_id: i32,
305        request: &VpcPeeringCreateRequest,
306    ) -> Result<TaskStateUpdate> {
307        self.client
308            .put(
309                &format!("/subscriptions/{subscription_id}/peerings/{peering_id}"),
310                request,
311            )
312            .await
313    }
314
315    // ========================================================================
316    // Active-Active VPC Peering
317    // ========================================================================
318    //
319    // Note: Active-Active VPC peering uses the same API endpoints as standard
320    // VPC peering. These methods are provided for API consistency and to match
321    // the naming convention used by other connectivity handlers.
322
323    /// Get Active-Active VPC peerings
324    ///
325    /// Note: Uses the same endpoint as standard VPC peering.
326    pub async fn get_active_active(&self, subscription_id: i32) -> Result<TaskStateUpdate> {
327        self.get(subscription_id).await
328    }
329
330    /// Create Active-Active VPC peering
331    ///
332    /// Note: Uses the same endpoint as standard VPC peering.
333    pub async fn create_active_active(
334        &self,
335        subscription_id: i32,
336        request: &VpcPeeringCreateRequest,
337    ) -> Result<TaskStateUpdate> {
338        self.create(subscription_id, request).await
339    }
340
341    /// Delete Active-Active VPC peering
342    ///
343    /// Note: Uses the same endpoint as standard VPC peering.
344    pub async fn delete_active_active(
345        &self,
346        subscription_id: i32,
347        peering_id: i32,
348    ) -> Result<serde_json::Value> {
349        self.delete(subscription_id, peering_id).await
350    }
351
352    /// Update Active-Active VPC peering
353    ///
354    /// Note: Uses the same endpoint as standard VPC peering.
355    pub async fn update_active_active(
356        &self,
357        subscription_id: i32,
358        peering_id: i32,
359        request: &VpcPeeringCreateRequest,
360    ) -> Result<TaskStateUpdate> {
361        self.update(subscription_id, peering_id, request).await
362    }
363}