Skip to main content

redis_cloud/
endpoint_redirections.rs

1//! Dynamic database endpoint redirection operations.
2//!
3//! Endpoint redirection moves a source database endpoint to a target database.
4//! The operation is asynchronous and exposes a redirection identifier that can
5//! be polled or reverted.
6
7use crate::{CloudClient, Result};
8use serde::{Deserialize, Serialize};
9use typed_builder::TypedBuilder;
10
11/// Endpoint type selected for a dynamic redirection.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
13#[serde(rename_all = "lowercase")]
14#[non_exhaustive]
15pub enum EndpointTargetType {
16    /// Redirect the public endpoint.
17    Public,
18    /// Redirect the private endpoint.
19    Private,
20    /// An endpoint type added by the API after this client release.
21    #[serde(other)]
22    Unknown,
23}
24
25/// Request to create a dynamic endpoint redirection.
26#[derive(Debug, Clone, Serialize, Deserialize, TypedBuilder)]
27#[serde(rename_all = "camelCase")]
28pub struct CreateEndpointsRedirectionRequest {
29    /// Source database whose endpoint will be redirected.
30    pub source_database_id: i32,
31
32    /// Target database that will receive the endpoint.
33    pub target_database_id: i32,
34
35    /// Public or private endpoint to redirect.
36    pub endpoint_target_type: EndpointTargetType,
37
38    /// Whether to duplicate source database ACLs on the target database.
39    #[serde(rename = "duplicateACLs", skip_serializing_if = "Option::is_none")]
40    #[builder(default, setter(strip_option))]
41    pub duplicate_acls: Option<bool>,
42
43    /// Explicit protection flag required by the API to start the migration.
44    pub migration_protection: bool,
45}
46
47/// Current status of a dynamic endpoint redirection.
48#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
49#[serde(rename_all = "kebab-case")]
50#[non_exhaustive]
51pub enum EndpointRedirectionStatus {
52    /// The request was accepted.
53    Initiated,
54    /// The request is waiting to run.
55    Pending,
56    /// Endpoint migration is in progress.
57    InProgress,
58    /// Endpoint migration completed successfully.
59    Completed,
60    /// Endpoint migration failed.
61    Failed,
62    /// A completed redirection was reverted.
63    Reverted,
64    /// A status added by the API after this client release.
65    #[serde(other)]
66    Unknown,
67}
68
69/// Details for one endpoint moved by a redirection operation.
70#[derive(Debug, Clone, Serialize, Deserialize)]
71#[serde(rename_all = "camelCase")]
72pub struct EndpointRedirection {
73    /// Source endpoint name.
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub source_endpoint_name: Option<String>,
76
77    /// Target endpoint name.
78    #[serde(skip_serializing_if = "Option::is_none")]
79    pub target_endpoint_name: Option<String>,
80
81    /// Source endpoint type.
82    #[serde(skip_serializing_if = "Option::is_none")]
83    pub source_endpoint_type: Option<EndpointTargetType>,
84
85    /// Target endpoint type.
86    #[serde(skip_serializing_if = "Option::is_none")]
87    pub target_endpoint_type: Option<EndpointTargetType>,
88
89    /// Endpoint-specific failure detail, when present.
90    #[serde(skip_serializing_if = "Option::is_none")]
91    pub error_message: Option<String>,
92}
93
94/// Dynamic endpoint redirection status response.
95#[derive(Debug, Clone, Serialize, Deserialize)]
96#[serde(rename_all = "camelCase")]
97pub struct EndpointsRedirectionResponse {
98    /// Redirection identifier used for polling and reversion.
99    #[serde(skip_serializing_if = "Option::is_none")]
100    pub redirection_id: Option<String>,
101
102    /// Current redirection state.
103    #[serde(skip_serializing_if = "Option::is_none")]
104    pub status: Option<EndpointRedirectionStatus>,
105
106    /// Source database ID.
107    #[serde(skip_serializing_if = "Option::is_none")]
108    pub source_database_id: Option<i32>,
109
110    /// Target database ID.
111    #[serde(skip_serializing_if = "Option::is_none")]
112    pub target_database_id: Option<i32>,
113
114    /// Whether this operation is reverting a prior redirection.
115    #[serde(skip_serializing_if = "Option::is_none")]
116    pub is_revert: Option<bool>,
117
118    /// Whether source ACLs were duplicated to the target.
119    #[serde(rename = "duplicateACLs", skip_serializing_if = "Option::is_none")]
120    pub duplicate_acls: Option<bool>,
121
122    /// Timestamp when the operation started.
123    #[serde(skip_serializing_if = "Option::is_none")]
124    pub started_at: Option<String>,
125
126    /// Timestamp when the operation completed.
127    #[serde(skip_serializing_if = "Option::is_none")]
128    pub completed_at: Option<String>,
129
130    /// Timestamp when the operation was reverted.
131    #[serde(skip_serializing_if = "Option::is_none")]
132    pub reverted_at: Option<String>,
133
134    /// Operation-level failure detail, when present.
135    #[serde(skip_serializing_if = "Option::is_none")]
136    pub error_message: Option<String>,
137
138    /// Individual endpoint movements performed by the operation.
139    #[serde(skip_serializing_if = "Option::is_none")]
140    pub endpoints: Option<Vec<EndpointRedirection>>,
141}
142
143/// Handler for dynamic endpoint redirection operations.
144pub struct EndpointRedirectionsHandler {
145    client: CloudClient,
146}
147
148impl EndpointRedirectionsHandler {
149    /// Create an endpoint redirections handler.
150    #[must_use]
151    pub fn new(client: CloudClient) -> Self {
152        Self { client }
153    }
154
155    /// Start a dynamic endpoint redirection.
156    pub async fn create(
157        &self,
158        request: &CreateEndpointsRedirectionRequest,
159    ) -> Result<EndpointsRedirectionResponse> {
160        self.client.post("/endpoint-redirections", request).await
161    }
162
163    /// Get the current state of a dynamic endpoint redirection.
164    pub async fn get(&self, redirection_id: &str) -> Result<EndpointsRedirectionResponse> {
165        self.client
166            .get(&format!("/endpoint-redirections/{redirection_id}"))
167            .await
168    }
169
170    /// Revert a completed dynamic endpoint redirection.
171    pub async fn revert(&self, redirection_id: &str) -> Result<EndpointsRedirectionResponse> {
172        self.client
173            .post_empty(&format!("/endpoint-redirections/{redirection_id}/revert"))
174            .await
175    }
176}