redis_cloud/fixed/databases.rs
1//! Database management operations for Essentials (Fixed) subscriptions
2//!
3//! This module provides database management functionality for Redis Cloud Essentials
4//! (formerly Fixed) subscriptions, which offer a simplified, cost-effective option
5//! for smaller workloads with predictable capacity requirements.
6//!
7//! # Overview
8//!
9//! Essentials databases are pre-configured Redis instances with fixed memory allocations
10//! and simplified pricing. They're ideal for development, testing, and production
11//! workloads that don't require auto-scaling or advanced clustering features.
12//!
13//! # Key Features
14//!
15//! - **Fixed Capacity**: Pre-defined memory sizes from 250MB to 12GB
16//! - **Simple Pricing**: Predictable monthly costs
17//! - **Essential Features**: Replication, persistence, and backup support
18//! - **Module Support**: Limited module availability based on plan
19//! - **Quick Setup**: Simplified configuration for faster deployment
20//!
21//! # Differences from Pro Databases
22//!
23//! - Fixed memory allocations (no auto-scaling)
24//! - Limited to single-region deployments
25//! - Simplified module selection
26//! - No clustering support
27//! - Predictable pricing model
28//!
29//! # Example Usage
30//!
31//! ```no_run
32//! use redis_cloud::{CloudClient, FixedDatabaseHandler};
33//!
34//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
35//! let client = CloudClient::builder()
36//! .api_key("your-api-key")
37//! .api_secret("your-api-secret")
38//! .build()?;
39//!
40//! let handler = FixedDatabaseHandler::new(client);
41//!
42//! // Example: List databases in a fixed subscription (ID 123)
43//! let databases = handler.list(123, None, None).await?;
44//! # Ok(())
45//! # }
46//! ```
47
48use crate::types::Link;
49pub use crate::types::{CloudTag, CloudTags, DatabaseTrafficStateResponse, Tag, TaskStateUpdate};
50use crate::{CloudClient, Result};
51use serde::{Deserialize, Serialize};
52use serde_json::Value;
53use std::collections::HashMap;
54use typed_builder::TypedBuilder;
55
56// ============================================================================
57// Models
58// ============================================================================
59
60/// `RedisLabs` Account Subscription Databases information
61///
62/// Response from `GET /fixed/subscriptions/{subscriptionId}/databases`.
63///
64/// Note: the OpenAPI schema lists only `accountId` and `links`, but real responses
65/// (and the spec's own example) include a `subscription` object containing the
66/// databases. See [`FixedSubscriptionDatabasesInfo`] for the inner shape.
67#[derive(Debug, Clone, Serialize, Deserialize)]
68#[serde(rename_all = "camelCase")]
69pub struct AccountFixedSubscriptionDatabases {
70 /// Account ID
71 #[serde(skip_serializing_if = "Option::is_none")]
72 pub account_id: Option<i32>,
73
74 /// Subscription information with the nested databases array.
75 ///
76 /// The Essentials response wraps databases under a single `subscription` object
77 /// (unlike the Pro response, which uses an array — see
78 /// [`crate::flexible::databases::AccountSubscriptionDatabases`]).
79 #[serde(skip_serializing_if = "Option::is_none")]
80 pub subscription: Option<FixedSubscriptionDatabasesInfo>,
81
82 /// HATEOAS links
83 #[serde(skip_serializing_if = "Option::is_none")]
84 pub links: Option<Vec<Link>>,
85}
86
87/// Subscription databases info returned within [`AccountFixedSubscriptionDatabases`].
88#[derive(Debug, Clone, Serialize, Deserialize)]
89#[serde(rename_all = "camelCase")]
90pub struct FixedSubscriptionDatabasesInfo {
91 /// Subscription ID
92 #[serde(skip_serializing_if = "Option::is_none")]
93 pub subscription_id: Option<i32>,
94
95 /// Number of databases reported by the API for this subscription
96 #[serde(skip_serializing_if = "Option::is_none")]
97 pub number_of_databases: Option<i32>,
98
99 /// List of databases in this subscription
100 #[serde(default)]
101 pub databases: Vec<FixedDatabase>,
102
103 /// HATEOAS links
104 #[serde(skip_serializing_if = "Option::is_none")]
105 pub links: Option<Vec<Link>>,
106}
107
108/// Database import request
109#[derive(Debug, Clone, Serialize, Deserialize)]
110#[serde(rename_all = "camelCase")]
111pub struct FixedDatabaseImportRequest {
112 /// Subscription ID being updated. Server-populated from the path.
113 #[serde(skip_serializing_if = "Option::is_none")]
114 pub subscription_id: Option<i32>,
115
116 /// Database ID being updated. Server-populated from the path.
117 #[serde(skip_serializing_if = "Option::is_none")]
118 pub database_id: Option<i32>,
119
120 /// Type of storage from which to import the database RDB file or Redis data.
121 pub source_type: String,
122
123 /// One or more paths to source data files or Redis databases, as appropriate to specified source type.
124 pub import_from_uri: Vec<String>,
125
126 /// Read-only on the response; populated by the server with the
127 /// operation type (e.g. `"IMPORT_DATABASE"`).
128 #[serde(skip_serializing_if = "Option::is_none")]
129 pub command_type: Option<String>,
130}
131
132/// Database tag update request message
133#[derive(Debug, Clone, Serialize, Deserialize)]
134#[serde(rename_all = "camelCase")]
135pub struct DatabaseTagUpdateRequest {
136 /// Subscription ID being updated. Server-populated from the path.
137 #[serde(skip_serializing_if = "Option::is_none")]
138 pub subscription_id: Option<i32>,
139
140 /// Database ID being updated. Server-populated from the path.
141 #[serde(skip_serializing_if = "Option::is_none")]
142 pub database_id: Option<i32>,
143
144 /// Tag key being updated. Server-populated from the path.
145 #[serde(skip_serializing_if = "Option::is_none")]
146 pub key: Option<String>,
147
148 /// Database tag value
149 pub value: String,
150
151 /// Read-only on the response; populated by the server with the
152 /// operation type (e.g. `"UPDATE_DATABASE_TAG"`).
153 #[serde(skip_serializing_if = "Option::is_none")]
154 pub command_type: Option<String>,
155}
156
157/// `DynamicEndpoints`
158#[derive(Debug, Clone, Serialize, Deserialize)]
159pub struct DynamicEndpoints {
160 /// Public endpoint for the database (if available).
161 #[serde(skip_serializing_if = "Option::is_none")]
162 pub public: Option<String>,
163
164 /// Private endpoint for the database (if available).
165 #[serde(skip_serializing_if = "Option::is_none")]
166 pub private: Option<String>,
167}
168
169/// Database tags update request message
170#[derive(Debug, Clone, Serialize, Deserialize)]
171#[serde(rename_all = "camelCase")]
172pub struct DatabaseTagsUpdateRequest {
173 /// Subscription ID being updated. Server-populated from the path.
174 #[serde(skip_serializing_if = "Option::is_none")]
175 pub subscription_id: Option<i32>,
176
177 /// Database ID being updated. Server-populated from the path.
178 #[serde(skip_serializing_if = "Option::is_none")]
179 pub database_id: Option<i32>,
180
181 /// List of database tags.
182 pub tags: Vec<Tag>,
183
184 /// Read-only on the response; populated by the server with the
185 /// operation type (e.g. `"UPDATE_DATABASE_TAGS"`).
186 #[serde(skip_serializing_if = "Option::is_none")]
187 pub command_type: Option<String>,
188}
189
190/// Optional. This database will be a replica of the specified Redis databases, provided as a list of objects with endpoint and certificate details.
191#[derive(Debug, Clone, Serialize, Deserialize)]
192#[serde(rename_all = "camelCase")]
193pub struct DatabaseSyncSourceSpec {
194 /// Redis URI of a source database. Example format: 'redis://user:password@host:port'. If the URI provided is a Redis Cloud database, only host and port should be provided. Example: '<redis://endpoint1:6379>'.
195 pub endpoint: String,
196
197 /// Defines if encryption should be used to connect to the sync source. If not set the source is a Redis Cloud database, it will automatically detect if the source uses encryption.
198 #[serde(skip_serializing_if = "Option::is_none")]
199 pub encryption: Option<bool>,
200
201 /// TLS/SSL certificate chain of the sync source. If not set and the source is a Redis Cloud database, it will automatically detect the certificate to use.
202 #[serde(skip_serializing_if = "Option::is_none")]
203 pub server_cert: Option<String>,
204}
205
206/// Optional. A list of client TLS/SSL certificates. If specified, mTLS authentication will be required to authenticate user connections. If set to an empty list, TLS client certificates will be removed and mTLS will not be required. TLS connection may still apply, depending on the value of 'enableTls'.
207#[derive(Debug, Clone, Serialize, Deserialize)]
208#[serde(rename_all = "camelCase")]
209pub struct DatabaseCertificateSpec {
210 /// Client certificate public key in PEM format, with new line characters replaced with '\n'.
211 pub public_certificate_pem_string: String,
212}
213
214/// Database slowlog entry
215#[derive(Debug, Clone, Serialize, Deserialize)]
216#[serde(rename_all = "camelCase")]
217pub struct DatabaseSlowLogEntry {
218 /// Slowlog entry identifier.
219 #[serde(skip_serializing_if = "Option::is_none")]
220 pub id: Option<i32>,
221
222 /// Timestamp when the command began executing.
223 #[serde(skip_serializing_if = "Option::is_none")]
224 pub start_time: Option<String>,
225
226 /// Execution duration in microseconds.
227 #[serde(skip_serializing_if = "Option::is_none")]
228 pub duration: Option<i32>,
229
230 /// Command arguments captured for this slowlog entry.
231 #[serde(skip_serializing_if = "Option::is_none")]
232 pub arguments: Option<String>,
233}
234
235/// Database tag
236#[derive(Debug, Clone, Serialize, Deserialize)]
237#[serde(rename_all = "camelCase")]
238pub struct DatabaseTagCreateRequest {
239 /// Database tag key.
240 pub key: String,
241
242 /// Database tag value.
243 pub value: String,
244
245 /// Subscription ID being updated. Server-populated from the path.
246 #[serde(skip_serializing_if = "Option::is_none")]
247 pub subscription_id: Option<i32>,
248
249 /// Database ID being updated. Server-populated from the path.
250 #[serde(skip_serializing_if = "Option::is_none")]
251 pub database_id: Option<i32>,
252
253 /// Read-only on the response; populated by the server with the
254 /// operation type (e.g. `"CREATE_DATABASE_TAG"`).
255 #[serde(skip_serializing_if = "Option::is_none")]
256 pub command_type: Option<String>,
257}
258
259/// Essentials database backup request message
260#[derive(Debug, Clone, Serialize, Deserialize)]
261#[serde(rename_all = "camelCase")]
262pub struct FixedDatabaseBackupRequest {
263 /// Subscription ID being updated. Server-populated from the path.
264 #[serde(skip_serializing_if = "Option::is_none")]
265 pub subscription_id: Option<i32>,
266
267 /// Database ID being updated. Server-populated from the path.
268 #[serde(skip_serializing_if = "Option::is_none")]
269 pub database_id: Option<i32>,
270
271 /// Optional. Manually backs up data to this location, instead of the set 'periodicBackupPath' location.
272 #[serde(skip_serializing_if = "Option::is_none")]
273 pub adhoc_backup_path: Option<String>,
274
275 /// Read-only on the response; populated by the server with the
276 /// operation type (e.g. `"BACKUP_DATABASE"`).
277 #[serde(skip_serializing_if = "Option::is_none")]
278 pub command_type: Option<String>,
279}
280
281/// Optional. Redis advanced capabilities (also known as modules) to be provisioned in the database. Use GET /database-modules to get a list of available advanced capabilities.
282#[derive(Debug, Clone, Serialize, Deserialize)]
283#[serde(rename_all = "camelCase")]
284pub struct DatabaseModuleSpec {
285 /// Redis advanced capability name. Use GET /database-modules for a list of available capabilities.
286 pub name: String,
287
288 /// Optional. Redis advanced capability parameters. Use GET /database-modules to get the available capabilities and their parameters.
289 ///
290 /// Kept as a [`Value`] because the wire shape is asymmetric: create
291 /// requests send an object (capability name → parameter map), while
292 /// database reads return an array. A typed map only matched the request
293 /// side and failed to deserialize real responses.
294 #[serde(skip_serializing_if = "Option::is_none")]
295 pub parameters: Option<Value>,
296
297 /// Module id (response only).
298 #[serde(skip_serializing_if = "Option::is_none")]
299 pub id: Option<i32>,
300
301 /// Human-readable capability name, e.g. `"Search and query"` (response only).
302 #[serde(skip_serializing_if = "Option::is_none")]
303 pub capability_name: Option<String>,
304
305 /// Module version (response only).
306 #[serde(skip_serializing_if = "Option::is_none")]
307 pub version: Option<String>,
308
309 /// Module description (response only).
310 #[serde(skip_serializing_if = "Option::is_none")]
311 pub description: Option<String>,
312}
313
314/// Optional. Changes Replica Of (also known as Active-Passive) configuration details.
315#[derive(Debug, Clone, Serialize, Deserialize)]
316#[serde(rename_all = "camelCase")]
317pub struct ReplicaOfSpec {
318 /// Description of the replica configuration
319 #[serde(skip_serializing_if = "Option::is_none")]
320 pub description: Option<String>,
321
322 /// Optional. This database will be a replica of the specified Redis databases, provided as a list of objects with endpoint and certificate details.
323 #[serde(default)]
324 pub sync_sources: Vec<DatabaseSyncSourceSpec>,
325}
326
327/// Database backup status and configuration
328#[derive(Debug, Clone, Serialize, Deserialize)]
329#[serde(rename_all = "camelCase")]
330pub struct DatabaseBackupStatus {
331 /// Whether backup is enabled
332 #[serde(skip_serializing_if = "Option::is_none")]
333 pub enabled: Option<bool>,
334
335 /// Current backup status
336 #[serde(skip_serializing_if = "Option::is_none")]
337 pub status: Option<String>,
338
339 /// Backup interval (e.g., "every-24-hours")
340 #[serde(skip_serializing_if = "Option::is_none")]
341 pub interval: Option<String>,
342
343 /// Backup destination path
344 #[serde(skip_serializing_if = "Option::is_none")]
345 pub destination: Option<String>,
346}
347
348/// Optional. Changes Redis database alert details.
349#[derive(Debug, Clone, Serialize, Deserialize)]
350#[serde(rename_all = "camelCase")]
351pub struct DatabaseAlertSpec {
352 /// Alert type. Available options depend on Plan type. See [Configure alerts](https://redis.io/docs/latest/operate/rc/databases/monitor-performance/#configure-metric-alerts) for more information.
353 pub name: String,
354
355 /// Value over which an alert will be sent. Default values and range depend on the alert type. See [Configure alerts](https://redis.io/docs/latest/operate/rc/databases/monitor-performance/#configure-metric-alerts) for more information.
356 pub value: i32,
357
358 /// Alert id (response only). A composite string such as `"<dbId>-<n>"`.
359 #[serde(skip_serializing_if = "Option::is_none")]
360 pub id: Option<String>,
361
362 /// Default threshold value for this alert type (response only).
363 #[serde(skip_serializing_if = "Option::is_none")]
364 pub default_value: Option<i32>,
365}
366
367/// Security configuration returned within a [`FixedDatabase`] read response
368/// (nested `security` object).
369#[derive(Debug, Clone, Serialize, Deserialize)]
370#[serde(rename_all = "camelCase")]
371pub struct FixedDatabaseSecurity {
372 /// Whether the default Redis user is enabled.
373 #[serde(skip_serializing_if = "Option::is_none")]
374 pub default_user_enabled: Option<bool>,
375
376 /// Whether SSL client authentication is enabled.
377 #[serde(skip_serializing_if = "Option::is_none")]
378 pub ssl_client_authentication: Option<bool>,
379
380 /// Whether TLS client authentication is enabled.
381 #[serde(skip_serializing_if = "Option::is_none")]
382 pub tls_client_authentication: Option<bool>,
383
384 /// Whether TLS is enabled for connections.
385 #[serde(skip_serializing_if = "Option::is_none")]
386 pub enable_tls: Option<bool>,
387
388 /// Source IP addresses / CIDR blocks allowed to connect.
389 #[serde(skip_serializing_if = "Option::is_none")]
390 pub source_ips: Option<Vec<String>>,
391
392 /// Database password (masked in responses).
393 #[serde(skip_serializing_if = "Option::is_none")]
394 pub password: Option<String>,
395}
396
397/// A single regex rule within a fixed database's clustering policy.
398#[derive(Debug, Clone, Serialize, Deserialize)]
399#[serde(rename_all = "camelCase")]
400pub struct FixedDatabaseRegexRule {
401 /// Order of this rule.
402 pub ordinal: i32,
403
404 /// Regex pattern.
405 pub pattern: String,
406}
407
408/// Clustering configuration returned within a [`FixedDatabase`] read response
409/// (nested `clustering` object).
410#[derive(Debug, Clone, Serialize, Deserialize)]
411#[serde(rename_all = "camelCase")]
412pub struct FixedDatabaseClustering {
413 /// Whether clustering is enabled.
414 #[serde(skip_serializing_if = "Option::is_none")]
415 pub enabled: Option<bool>,
416
417 /// Regex rules for the custom hashing policy.
418 #[serde(skip_serializing_if = "Option::is_none")]
419 pub regex_rules: Option<Vec<FixedDatabaseRegexRule>>,
420
421 /// Hashing policy (e.g. `"standard"`).
422 #[serde(skip_serializing_if = "Option::is_none")]
423 pub hashing_policy: Option<String>,
424}
425
426/// Backup configuration returned within a [`FixedDatabase`] read response
427/// (nested `backup` object).
428#[derive(Debug, Clone, Serialize, Deserialize)]
429#[serde(rename_all = "camelCase")]
430pub struct FixedDatabaseBackup {
431 /// Whether remote backup is enabled.
432 #[serde(skip_serializing_if = "Option::is_none")]
433 pub remote_backup_enabled: Option<bool>,
434}
435
436/// `FixedDatabase`
437#[derive(Debug, Clone, Serialize, Deserialize)]
438#[serde(rename_all = "camelCase")]
439pub struct FixedDatabase {
440 /// Database identifier.
441 #[serde(skip_serializing_if = "Option::is_none")]
442 pub database_id: Option<i32>,
443
444 /// Database name.
445 #[serde(skip_serializing_if = "Option::is_none")]
446 pub name: Option<String>,
447
448 /// Database protocol (e.g. `"redis"`, `"stack"`, `"memcached"`).
449 #[serde(skip_serializing_if = "Option::is_none")]
450 pub protocol: Option<String>,
451
452 /// Cloud provider (e.g. `"AWS"`, `"GCP"`, `"Azure"`).
453 #[serde(skip_serializing_if = "Option::is_none")]
454 pub provider: Option<String>,
455
456 /// Cloud region where the database is hosted.
457 #[serde(skip_serializing_if = "Option::is_none")]
458 pub region: Option<String>,
459
460 /// Redis version currently running on the database.
461 #[serde(skip_serializing_if = "Option::is_none")]
462 pub redis_version: Option<String>,
463
464 /// Redis version compliance level (e.g. `"latest"`).
465 #[serde(skip_serializing_if = "Option::is_none")]
466 pub redis_version_compliance: Option<String>,
467
468 /// Redis Serialization Protocol (RESP) version in use.
469 #[serde(skip_serializing_if = "Option::is_none")]
470 pub resp_version: Option<String>,
471
472 /// Current database status (e.g. `"active"`, `"pending"`).
473 #[serde(skip_serializing_if = "Option::is_none")]
474 pub status: Option<String>,
475
476 /// Memory limit from the plan, in the plan's measurement unit.
477 #[serde(skip_serializing_if = "Option::is_none")]
478 pub plan_memory_limit: Option<f64>,
479
480 /// Dataset size from the plan, in the plan's measurement unit.
481 #[serde(skip_serializing_if = "Option::is_none")]
482 pub plan_dataset_size: Option<f64>,
483
484 /// Measurement unit for memory limits (e.g. `"GB"`, `"MB"`).
485 #[serde(skip_serializing_if = "Option::is_none")]
486 pub memory_limit_measurement_unit: Option<String>,
487
488 /// Total memory limit in GB, including replication and other overhead.
489 #[serde(skip_serializing_if = "Option::is_none")]
490 pub memory_limit_in_gb: Option<f64>,
491
492 /// Maximum dataset size for this database in GB.
493 #[serde(skip_serializing_if = "Option::is_none")]
494 pub dataset_size_in_gb: Option<f64>,
495
496 /// Currently used memory, in MB.
497 #[serde(skip_serializing_if = "Option::is_none")]
498 pub memory_used_in_mb: Option<f64>,
499
500 /// Network usage so far this month, in bytes.
501 #[serde(skip_serializing_if = "Option::is_none")]
502 pub network_monthly_usage_in_byte: Option<f64>,
503
504 /// Memory storage type (e.g. `"ram"`, `"ram-and-flash"`).
505 #[serde(skip_serializing_if = "Option::is_none")]
506 pub memory_storage: Option<String>,
507
508 /// Whether Redis Flex (auto-tiering) is enabled.
509 #[serde(skip_serializing_if = "Option::is_none")]
510 pub redis_flex: Option<bool>,
511
512 /// Whether Redis OSS Cluster API support is enabled.
513 #[serde(
514 rename = "supportOSSClusterApi",
515 skip_serializing_if = "Option::is_none"
516 )]
517 pub support_oss_cluster_api: Option<bool>,
518
519 /// Whether the external endpoint is used for OSS Cluster API.
520 #[serde(
521 rename = "useExternalEndpointForOSSClusterApi",
522 skip_serializing_if = "Option::is_none"
523 )]
524 pub use_external_endpoint_for_oss_cluster_api: Option<bool>,
525
526 /// Data persistence type (e.g. `"none"`, `"aof-every-1-second"`, `"snapshot-every-1-hour"`).
527 #[serde(skip_serializing_if = "Option::is_none")]
528 pub data_persistence: Option<String>,
529
530 /// Whether replication is enabled.
531 #[serde(skip_serializing_if = "Option::is_none")]
532 pub replication: Option<bool>,
533
534 /// Data eviction policy (e.g. `"allkeys-lru"`, `"noeviction"`).
535 #[serde(skip_serializing_if = "Option::is_none")]
536 pub data_eviction_policy: Option<String>,
537
538 /// Timestamp when the database was activated.
539 #[serde(skip_serializing_if = "Option::is_none")]
540 pub activated_on: Option<String>,
541
542 /// Timestamp when the database was last modified.
543 #[serde(skip_serializing_if = "Option::is_none")]
544 pub last_modified: Option<String>,
545
546 /// Public endpoint hostname/port for connecting from the internet.
547 #[serde(skip_serializing_if = "Option::is_none")]
548 pub public_endpoint: Option<String>,
549
550 /// Private endpoint hostname/port for connecting from inside the VPC.
551 #[serde(skip_serializing_if = "Option::is_none")]
552 pub private_endpoint: Option<String>,
553
554 /// Additional dynamic endpoints. See [`DynamicEndpoints`].
555 #[serde(skip_serializing_if = "Option::is_none")]
556 pub dynamic_endpoints: Option<DynamicEndpoints>,
557
558 /// Replica-as-source endpoints (`public`/`private`), returned on reads.
559 #[serde(skip_serializing_if = "Option::is_none")]
560 pub replica_as_source_endpoints: Option<DynamicEndpoints>,
561
562 /// Security configuration (TLS, source IPs, authentication).
563 ///
564 /// Returned as a nested `security` object on reads. See
565 /// [`FixedDatabaseSecurity`].
566 #[serde(skip_serializing_if = "Option::is_none")]
567 pub security: Option<FixedDatabaseSecurity>,
568
569 /// Replica of configuration
570 #[serde(skip_serializing_if = "Option::is_none")]
571 pub replica: Option<ReplicaOfSpec>,
572
573 /// Clustering configuration (shard hashing).
574 ///
575 /// Returned as a nested `clustering` object on reads. See
576 /// [`FixedDatabaseClustering`].
577 #[serde(skip_serializing_if = "Option::is_none")]
578 pub clustering: Option<FixedDatabaseClustering>,
579
580 /// Redis modules/capabilities enabled on this database
581 #[serde(skip_serializing_if = "Option::is_none")]
582 pub modules: Option<Vec<DatabaseModuleSpec>>,
583
584 /// Database alert configurations
585 #[serde(skip_serializing_if = "Option::is_none")]
586 pub alerts: Option<Vec<DatabaseAlertSpec>>,
587
588 /// Backup configuration as returned on reads (nested `backup` object).
589 /// See [`FixedDatabaseBackup`].
590 #[serde(skip_serializing_if = "Option::is_none")]
591 pub backup: Option<FixedDatabaseBackup>,
592
593 /// HATEOAS links
594 #[serde(skip_serializing_if = "Option::is_none")]
595 pub links: Option<Vec<Link>>,
596}
597
598/// `DatabaseSlowLogEntries`
599#[derive(Debug, Clone, Serialize, Deserialize)]
600pub struct DatabaseSlowLogEntries {
601 /// Slowlog entries returned for the database.
602 #[serde(skip_serializing_if = "Option::is_none")]
603 pub entries: Option<Vec<DatabaseSlowLogEntry>>,
604
605 /// HATEOAS links
606 #[serde(skip_serializing_if = "Option::is_none")]
607 pub links: Option<Vec<Link>>,
608}
609
610/// Essentials database definition
611///
612/// # Example
613///
614/// ```
615/// use redis_cloud::fixed::databases::FixedDatabaseCreateRequest;
616///
617/// let request = FixedDatabaseCreateRequest::builder()
618/// .name("my-database")
619/// .replication(true)
620/// .build();
621/// ```
622#[derive(Debug, Clone, Serialize, Deserialize, TypedBuilder)]
623#[serde(rename_all = "camelCase")]
624pub struct FixedDatabaseCreateRequest {
625 /// Subscription ID being updated. Server-populated from the path.
626 #[serde(skip_serializing_if = "Option::is_none")]
627 #[builder(default, setter(strip_option))]
628 pub subscription_id: Option<i32>,
629
630 /// Name of the database. Database name is limited to 40 characters or less and must include only letters, digits, and hyphens ('-'). It must start with a letter and end with a letter or digit.
631 #[builder(setter(into))]
632 pub name: String,
633
634 /// Optional. Database protocol. Use 'stack' to get all of Redis' advanced capabilities. Only use 'redis' for Pay-as-you-go or Redis Flex subscriptions. Default: 'stack' for most subscriptions, 'redis' for Redis Flex subscriptions.
635 #[serde(skip_serializing_if = "Option::is_none")]
636 #[builder(default, setter(strip_option, into))]
637 pub protocol: Option<String>,
638
639 /// (Pay-as-you-go subscriptions only) Optional. Total memory in GB, including replication and other overhead. You cannot set both datasetSizeInGb and totalMemoryInGb.
640 #[serde(skip_serializing_if = "Option::is_none")]
641 #[builder(default, setter(strip_option))]
642 pub memory_limit_in_gb: Option<f64>,
643
644 /// (Pay-as-you-go subscriptions only) Optional. The maximum amount of data in the dataset for this database in GB. You cannot set both datasetSizeInGb and totalMemoryInGb. If 'replication' is 'true', the database's total memory will be twice as large as the datasetSizeInGb. If 'replication' is false, the database's total memory will be the datasetSizeInGb value.
645 #[serde(skip_serializing_if = "Option::is_none")]
646 #[builder(default, setter(strip_option))]
647 pub dataset_size_in_gb: Option<f64>,
648
649 /// (Pay-as-you-go subscriptions only) Optional. Support Redis [OSS Cluster API](https://redis.io/docs/latest/operate/rc/databases/configuration/clustering/#oss-cluster-api). Default: 'false'
650 #[serde(skip_serializing_if = "Option::is_none")]
651 #[builder(default, setter(strip_option))]
652 pub support_oss_cluster_api: Option<bool>,
653
654 /// Optional. If specified, redisVersion defines the Redis database version. If omitted, the Redis version will be set to the default version. (available in 'GET /fixed/redis-versions')
655 #[serde(skip_serializing_if = "Option::is_none")]
656 #[builder(default, setter(strip_option, into))]
657 pub redis_version: Option<String>,
658
659 /// Optional. Redis Serialization Protocol version. Must be compatible with Redis version.
660 #[serde(skip_serializing_if = "Option::is_none")]
661 #[builder(default, setter(strip_option, into))]
662 pub resp_version: Option<String>,
663
664 /// (Pay-as-you-go subscriptions only) Optional. If set to 'true', the database will use the external endpoint for OSS Cluster API. This setting blocks the database's private endpoint. Can only be set if 'supportOSSClusterAPI' is 'true'. Default: 'false'
665 #[serde(skip_serializing_if = "Option::is_none")]
666 #[builder(default, setter(strip_option))]
667 pub use_external_endpoint_for_oss_cluster_api: Option<bool>,
668
669 /// (Pay-as-you-go subscriptions only) Optional. Distributes database data to different cloud instances. Default: 'false'
670 #[serde(skip_serializing_if = "Option::is_none")]
671 #[builder(default, setter(strip_option))]
672 pub enable_database_clustering: Option<bool>,
673
674 /// (Pay-as-you-go subscriptions only) Optional. Specifies the number of master shards.
675 #[serde(skip_serializing_if = "Option::is_none")]
676 #[builder(default, setter(strip_option))]
677 pub number_of_shards: Option<i32>,
678
679 /// Optional. Type and rate of data persistence in persistent storage. Use GET /fixed/plans/{planId} to see if your plan supports data persistence.
680 #[serde(skip_serializing_if = "Option::is_none")]
681 #[builder(default, setter(strip_option, into))]
682 pub data_persistence: Option<String>,
683
684 /// Optional. Data eviction policy.
685 #[serde(skip_serializing_if = "Option::is_none")]
686 #[builder(default, setter(strip_option, into))]
687 pub data_eviction_policy: Option<String>,
688
689 /// Optional. Sets database replication. Use GET /fixed/plans/{planId} to see if your plan supports database replication.
690 #[serde(skip_serializing_if = "Option::is_none")]
691 #[builder(default, setter(strip_option))]
692 pub replication: Option<bool>,
693
694 /// Optional. The path to a backup storage location. If specified, the database will back up every 24 hours to this location, and you can manually back up the database to this location at any time. Use GET /fixed/plans/{planId} to see if your plan supports database backups.
695 #[serde(skip_serializing_if = "Option::is_none")]
696 #[builder(default, setter(strip_option, into))]
697 pub periodic_backup_path: Option<String>,
698
699 /// Optional. List of source IP addresses or subnet masks to allow. If specified, Redis clients will be able to connect to this database only from within the specified source IP addresses ranges. Use GET /fixed/plans/{planId} to see how many CIDR allow rules your plan supports. Example: '['192.168.10.0/32', '192.168.12.0/24']'
700 #[serde(skip_serializing_if = "Option::is_none")]
701 #[builder(default, setter(strip_option))]
702 pub source_ips: Option<Vec<String>>,
703
704 /// (Pay-as-you-go subscriptions only) Optional. Hashing policy Regex rules. Used only if 'enableDatabaseClustering' is set to 'true' and .
705 #[serde(skip_serializing_if = "Option::is_none")]
706 #[builder(default, setter(strip_option))]
707 pub regex_rules: Option<Vec<String>>,
708
709 /// Optional. This database will be a replica of the specified Redis databases provided as one or more URI(s). Example: 'redis://user:password@host:port'. If the URI provided is a Redis Cloud database, only host and port should be provided. Example: ['<redis://endpoint1:6379>', '<redis://endpoint2:6380>'].
710 #[serde(skip_serializing_if = "Option::is_none")]
711 #[builder(default, setter(strip_option))]
712 pub replica_of: Option<Vec<String>>,
713
714 /// Optional. Replica-of (Active-Passive) configuration. See [`ReplicaOfSpec`].
715 #[serde(skip_serializing_if = "Option::is_none")]
716 #[builder(default, setter(strip_option))]
717 pub replica: Option<ReplicaOfSpec>,
718
719 /// Optional. A public key client TLS/SSL certificate with new line characters replaced with '\n'. If specified, mTLS authentication will be required to authenticate user connections. Default: 'null'
720 #[serde(skip_serializing_if = "Option::is_none")]
721 #[builder(default, setter(strip_option, into))]
722 pub client_ssl_certificate: Option<String>,
723
724 /// Optional. A list of client TLS/SSL certificates. If specified, mTLS authentication will be required to authenticate user connections.
725 #[serde(skip_serializing_if = "Option::is_none")]
726 #[builder(default, setter(strip_option))]
727 pub client_tls_certificates: Option<Vec<DatabaseCertificateSpec>>,
728
729 /// Optional. When 'true', requires TLS authentication for all connections - mTLS with valid clientTlsCertificates, regular TLS when clientTlsCertificates is not provided. Default: 'false'
730 #[serde(skip_serializing_if = "Option::is_none")]
731 #[builder(default, setter(strip_option))]
732 pub enable_tls: Option<bool>,
733
734 /// Optional. Password to access the database. If not set, a random 32-character alphanumeric password will be automatically generated.
735 #[serde(skip_serializing_if = "Option::is_none")]
736 #[builder(default, setter(strip_option, into))]
737 pub password: Option<String>,
738
739 /// Optional. Redis database alert details.
740 #[serde(skip_serializing_if = "Option::is_none")]
741 #[builder(default, setter(strip_option))]
742 pub alerts: Option<Vec<DatabaseAlertSpec>>,
743
744 /// Optional. Redis advanced capabilities (also known as modules) to be provisioned in the database. Use GET /database-modules to get a list of available advanced capabilities. Can only be set if 'protocol' is 'redis'.
745 #[serde(skip_serializing_if = "Option::is_none")]
746 #[builder(default, setter(strip_option))]
747 pub modules: Option<Vec<DatabaseModuleSpec>>,
748
749 /// Read-only on the response; populated by the server with the
750 /// operation type (e.g. `"CREATE_FIXED_DATABASE"`).
751 #[serde(skip_serializing_if = "Option::is_none")]
752 #[builder(default, setter(strip_option, into))]
753 pub command_type: Option<String>,
754}
755
756/// Essentials database update request
757///
758/// # Example
759///
760/// ```
761/// use redis_cloud::fixed::databases::FixedDatabaseUpdateRequest;
762///
763/// let request = FixedDatabaseUpdateRequest::builder()
764/// .name("updated-name")
765/// .build();
766/// ```
767#[derive(Debug, Clone, Serialize, Deserialize, TypedBuilder)]
768#[serde(rename_all = "camelCase")]
769pub struct FixedDatabaseUpdateRequest {
770 /// Subscription ID being updated. Server-populated from the path.
771 #[serde(skip_serializing_if = "Option::is_none")]
772 #[builder(default, setter(strip_option))]
773 pub subscription_id: Option<i32>,
774
775 /// Database ID being updated. Server-populated from the path.
776 #[serde(skip_serializing_if = "Option::is_none")]
777 #[builder(default, setter(strip_option))]
778 pub database_id: Option<i32>,
779
780 /// Optional. Updated database name.
781 #[serde(skip_serializing_if = "Option::is_none")]
782 #[builder(default, setter(strip_option, into))]
783 pub name: Option<String>,
784
785 /// (Pay-as-you-go subscriptions only) Optional. Total memory in GB, including replication and other overhead. You cannot set both datasetSizeInGb and totalMemoryInGb.
786 #[serde(skip_serializing_if = "Option::is_none")]
787 #[builder(default, setter(strip_option))]
788 pub memory_limit_in_gb: Option<f64>,
789
790 /// (Pay-as-you-go subscriptions only) Optional. The maximum amount of data in the dataset for this database in GB. You cannot set both datasetSizeInGb and totalMemoryInGb. If 'replication' is 'true', the database's total memory will be twice as large as the datasetSizeInGb. If 'replication' is false, the database's total memory will be the datasetSizeInGb value.
791 #[serde(skip_serializing_if = "Option::is_none")]
792 #[builder(default, setter(strip_option))]
793 pub dataset_size_in_gb: Option<f64>,
794
795 /// (Pay-as-you-go subscriptions only) Optional. Support Redis [OSS Cluster API](https://redis.io/docs/latest/operate/rc/databases/configuration/clustering/#oss-cluster-api).
796 #[serde(skip_serializing_if = "Option::is_none")]
797 #[builder(default, setter(strip_option))]
798 pub support_oss_cluster_api: Option<bool>,
799
800 /// Optional. Redis Serialization Protocol version. Must be compatible with Redis version.
801 #[serde(skip_serializing_if = "Option::is_none")]
802 #[builder(default, setter(strip_option, into))]
803 pub resp_version: Option<String>,
804
805 /// (Pay-as-you-go subscriptions only) Optional. If set to 'true', the database will use the external endpoint for OSS Cluster API. This setting blocks the database's private endpoint. Can only be set if 'supportOSSClusterAPI' is 'true'. Default: 'false'
806 #[serde(skip_serializing_if = "Option::is_none")]
807 #[builder(default, setter(strip_option))]
808 pub use_external_endpoint_for_oss_cluster_api: Option<bool>,
809
810 /// (Pay-as-you-go subscriptions only) Optional. Distributes database data to different cloud instances.
811 #[serde(skip_serializing_if = "Option::is_none")]
812 #[builder(default, setter(strip_option))]
813 pub enable_database_clustering: Option<bool>,
814
815 /// (Pay-as-you-go subscriptions only) Optional. Changes the number of master shards.
816 #[serde(skip_serializing_if = "Option::is_none")]
817 #[builder(default, setter(strip_option))]
818 pub number_of_shards: Option<i32>,
819
820 /// Optional. Type and rate of data persistence in persistent storage. Use GET /fixed/plans/{planId} to see if your plan supports data persistence.
821 #[serde(skip_serializing_if = "Option::is_none")]
822 #[builder(default, setter(strip_option, into))]
823 pub data_persistence: Option<String>,
824
825 /// Optional. Turns database replication on or off.
826 #[serde(skip_serializing_if = "Option::is_none")]
827 #[builder(default, setter(strip_option, into))]
828 pub data_eviction_policy: Option<String>,
829
830 /// Optional. Sets database replication. Use GET /fixed/plans/{planId} to see if your plan supports database replication.
831 #[serde(skip_serializing_if = "Option::is_none")]
832 #[builder(default, setter(strip_option))]
833 pub replication: Option<bool>,
834
835 /// Optional. Changes the backup location path. If specified, the database will back up every 24 hours to this location, and you can manually back up the database to this location at any time. Use GET /fixed/plans/{planId} to see if your plan supports database backups. If set to an empty string, the backup path will be removed.
836 #[serde(skip_serializing_if = "Option::is_none")]
837 #[builder(default, setter(strip_option, into))]
838 pub periodic_backup_path: Option<String>,
839
840 /// Optional. List of source IP addresses or subnet masks to allow. If specified, Redis clients will be able to connect to this database only from within the specified source IP addresses ranges. Example: '['192.168.10.0/32', '192.168.12.0/24']'
841 #[serde(skip_serializing_if = "Option::is_none")]
842 #[builder(default, setter(strip_option))]
843 pub source_ips: Option<Vec<String>>,
844
845 /// Optional. This database will be a replica of the specified Redis databases provided as one or more URI (sample format: 'redis://user:password@host:port)'. If the URI provided is Redis Cloud instance, only host and port should be provided (using the format: ['<redis://endpoint1:6379>', '<redis://endpoint2:6380>'] ).
846 #[serde(skip_serializing_if = "Option::is_none")]
847 #[builder(default, setter(strip_option))]
848 pub replica_of: Option<Vec<String>>,
849
850 /// Optional. Replica-of (Active-Passive) configuration. See [`ReplicaOfSpec`].
851 #[serde(skip_serializing_if = "Option::is_none")]
852 #[builder(default, setter(strip_option))]
853 pub replica: Option<ReplicaOfSpec>,
854
855 /// (Pay-as-you-go subscriptions only) Optional. Hashing policy Regex rules. Used only if 'shardingType' is 'custom-regex-rules'.
856 #[serde(skip_serializing_if = "Option::is_none")]
857 #[builder(default, setter(strip_option))]
858 pub regex_rules: Option<Vec<String>>,
859
860 /// Optional. A public key client TLS/SSL certificate with new line characters replaced with '\n'. If specified, mTLS authentication will be required to authenticate user connections if it is not already required. If set to an empty string, TLS client certificates will be removed and mTLS will not be required. TLS connection may still apply, depending on the value of 'enableTls'.
861 #[serde(skip_serializing_if = "Option::is_none")]
862 #[builder(default, setter(strip_option, into))]
863 pub client_ssl_certificate: Option<String>,
864
865 /// Optional. A list of client TLS/SSL certificates. If specified, mTLS authentication will be required to authenticate user connections. If set to an empty list, TLS client certificates will be removed and mTLS will not be required. TLS connection may still apply, depending on the value of 'enableTls'.
866 #[serde(skip_serializing_if = "Option::is_none")]
867 #[builder(default, setter(strip_option))]
868 pub client_tls_certificates: Option<Vec<DatabaseCertificateSpec>>,
869
870 /// Optional. When 'true', requires TLS authentication for all connections - mTLS with valid clientTlsCertificates, regular TLS when clientTlsCertificates is not provided. If enableTls is set to 'false' while mTLS is required, it will remove the mTLS requirement and erase previously provided clientTlsCertificates.
871 #[serde(skip_serializing_if = "Option::is_none")]
872 #[builder(default, setter(strip_option))]
873 pub enable_tls: Option<bool>,
874
875 /// Optional. Changes the password used to access the database with the 'default' user.
876 #[serde(skip_serializing_if = "Option::is_none")]
877 #[builder(default, setter(strip_option, into))]
878 pub password: Option<String>,
879
880 /// Optional. When 'true', allows connecting to the database with the 'default' user. When 'false', only defined access control users can connect to the database.
881 #[serde(skip_serializing_if = "Option::is_none")]
882 #[builder(default, setter(strip_option))]
883 pub enable_default_user: Option<bool>,
884
885 /// Optional. Changes Redis database alert details.
886 #[serde(skip_serializing_if = "Option::is_none")]
887 #[builder(default, setter(strip_option))]
888 pub alerts: Option<Vec<DatabaseAlertSpec>>,
889
890 /// Read-only on the response; populated by the server with the
891 /// operation type (e.g. `"UPDATE_FIXED_DATABASE"`).
892 #[serde(skip_serializing_if = "Option::is_none")]
893 #[builder(default, setter(strip_option, into))]
894 pub command_type: Option<String>,
895}
896
897// ============================================================================
898// Handler
899// ============================================================================
900
901/// Handler for Essentials database operations
902///
903/// Manages fixed-capacity databases with simplified configuration
904/// and predictable pricing for Redis Cloud Essentials subscriptions.
905pub struct FixedDatabaseHandler {
906 client: CloudClient,
907}
908
909impl FixedDatabaseHandler {
910 /// Create a new handler
911 #[must_use]
912 pub fn new(client: CloudClient) -> Self {
913 Self { client }
914 }
915
916 /// Get all databases in an Essentials subscription
917 /// Gets a list of all databases in the specified Essentials subscription.
918 ///
919 /// GET /fixed/subscriptions/{subscriptionId}/databases
920 pub async fn list(
921 &self,
922 subscription_id: i32,
923 offset: Option<i32>,
924 limit: Option<i32>,
925 ) -> Result<AccountFixedSubscriptionDatabases> {
926 let mut query = Vec::new();
927 if let Some(v) = offset {
928 query.push(format!("offset={v}"));
929 }
930 if let Some(v) = limit {
931 query.push(format!("limit={v}"));
932 }
933 let query_string = if query.is_empty() {
934 String::new()
935 } else {
936 format!("?{}", query.join("&"))
937 };
938 self.client
939 .get(&format!(
940 "/fixed/subscriptions/{subscription_id}/databases{query_string}"
941 ))
942 .await
943 }
944
945 /// Create Essentials database
946 /// Creates a new database in the specified Essentials subscription.
947 ///
948 /// POST /fixed/subscriptions/{subscriptionId}/databases
949 pub async fn create(
950 &self,
951 subscription_id: i32,
952 request: &FixedDatabaseCreateRequest,
953 ) -> Result<TaskStateUpdate> {
954 self.client
955 .post(
956 &format!("/fixed/subscriptions/{subscription_id}/databases"),
957 request,
958 )
959 .await
960 }
961
962 /// Delete Essentials database
963 /// Deletes a database from an Essentials subscription.
964 ///
965 /// DELETE /fixed/subscriptions/{subscriptionId}/databases/{databaseId}
966 pub async fn delete_by_id(
967 &self,
968 subscription_id: i32,
969 database_id: i32,
970 ) -> Result<TaskStateUpdate> {
971 let response = self
972 .client
973 .delete_raw(&format!(
974 "/fixed/subscriptions/{subscription_id}/databases/{database_id}"
975 ))
976 .await?;
977 serde_json::from_value(response).map_err(Into::into)
978 }
979
980 /// Get a single Essentials database
981 /// Gets details and settings of a single database in an Essentials subscription.
982 ///
983 /// GET /fixed/subscriptions/{subscriptionId}/databases/{databaseId}
984 pub async fn get_by_id(&self, subscription_id: i32, database_id: i32) -> Result<FixedDatabase> {
985 self.client
986 .get(&format!(
987 "/fixed/subscriptions/{subscription_id}/databases/{database_id}"
988 ))
989 .await
990 }
991
992 /// Update Essentials database
993 /// Updates the specified Essentials database.
994 ///
995 /// PUT /fixed/subscriptions/{subscriptionId}/databases/{databaseId}
996 pub async fn update(
997 &self,
998 subscription_id: i32,
999 database_id: i32,
1000 request: &FixedDatabaseUpdateRequest,
1001 ) -> Result<TaskStateUpdate> {
1002 self.client
1003 .put(
1004 &format!("/fixed/subscriptions/{subscription_id}/databases/{database_id}"),
1005 request,
1006 )
1007 .await
1008 }
1009
1010 /// Backup Essentials database status
1011 /// Information on the latest database backup status identified by Essentials subscription Id and Essentials database Id
1012 ///
1013 /// GET /fixed/subscriptions/{subscriptionId}/databases/{databaseId}/backup
1014 pub async fn get_backup_status(
1015 &self,
1016 subscription_id: i32,
1017 database_id: i32,
1018 ) -> Result<TaskStateUpdate> {
1019 self.client
1020 .get(&format!(
1021 "/fixed/subscriptions/{subscription_id}/databases/{database_id}/backup"
1022 ))
1023 .await
1024 }
1025
1026 /// Back up Essentials database
1027 /// Manually back up the specified Essentials database to a backup path. By default, backups will be stored in the 'periodicBackupPath' location for this database.
1028 ///
1029 /// POST /fixed/subscriptions/{subscriptionId}/databases/{databaseId}/backup
1030 pub async fn backup(
1031 &self,
1032 subscription_id: i32,
1033 database_id: i32,
1034 request: &FixedDatabaseBackupRequest,
1035 ) -> Result<TaskStateUpdate> {
1036 self.client
1037 .post(
1038 &format!("/fixed/subscriptions/{subscription_id}/databases/{database_id}/backup"),
1039 request,
1040 )
1041 .await
1042 }
1043
1044 /// Get Essentials database import status
1045 /// Gets information on the latest import attempt for this Essentials database.
1046 ///
1047 /// GET /fixed/subscriptions/{subscriptionId}/databases/{databaseId}/import
1048 pub async fn get_import_status(
1049 &self,
1050 subscription_id: i32,
1051 database_id: i32,
1052 ) -> Result<TaskStateUpdate> {
1053 self.client
1054 .get(&format!(
1055 "/fixed/subscriptions/{subscription_id}/databases/{database_id}/import"
1056 ))
1057 .await
1058 }
1059
1060 /// Import data to an Essentials database
1061 /// Imports data from an RDB file or from a different Redis database into this Essentials database. WARNING: Importing data into a database removes all existing data from the database.
1062 ///
1063 /// POST /fixed/subscriptions/{subscriptionId}/databases/{databaseId}/import
1064 pub async fn import(
1065 &self,
1066 subscription_id: i32,
1067 database_id: i32,
1068 request: &FixedDatabaseImportRequest,
1069 ) -> Result<TaskStateUpdate> {
1070 self.client
1071 .post(
1072 &format!("/fixed/subscriptions/{subscription_id}/databases/{database_id}/import"),
1073 request,
1074 )
1075 .await
1076 }
1077
1078 /// Get Essentials database slow-log by database id
1079 /// Get slow-log for a specific database identified by Essentials subscription Id and database Id
1080 ///
1081 /// GET /fixed/subscriptions/{subscriptionId}/databases/{databaseId}/slow-log
1082 pub async fn get_slow_log(
1083 &self,
1084 subscription_id: i32,
1085 database_id: i32,
1086 ) -> Result<DatabaseSlowLogEntries> {
1087 self.client
1088 .get(&format!(
1089 "/fixed/subscriptions/{subscription_id}/databases/{database_id}/slow-log"
1090 ))
1091 .await
1092 }
1093
1094 /// Get database tags
1095 /// Gets a list of all database tags.
1096 ///
1097 /// GET /fixed/subscriptions/{subscriptionId}/databases/{databaseId}/tags
1098 pub async fn get_tags(&self, subscription_id: i32, database_id: i32) -> Result<CloudTags> {
1099 self.client
1100 .get(&format!(
1101 "/fixed/subscriptions/{subscription_id}/databases/{database_id}/tags"
1102 ))
1103 .await
1104 }
1105
1106 /// Add a database tag
1107 /// Adds a single database tag to a database.
1108 ///
1109 /// POST /fixed/subscriptions/{subscriptionId}/databases/{databaseId}/tags
1110 pub async fn create_tag(
1111 &self,
1112 subscription_id: i32,
1113 database_id: i32,
1114 request: &DatabaseTagCreateRequest,
1115 ) -> Result<CloudTag> {
1116 self.client
1117 .post(
1118 &format!("/fixed/subscriptions/{subscription_id}/databases/{database_id}/tags"),
1119 request,
1120 )
1121 .await
1122 }
1123
1124 /// Overwrite database tags
1125 /// Overwrites all tags on the database.
1126 ///
1127 /// PUT /fixed/subscriptions/{subscriptionId}/databases/{databaseId}/tags
1128 pub async fn update_tags(
1129 &self,
1130 subscription_id: i32,
1131 database_id: i32,
1132 request: &DatabaseTagsUpdateRequest,
1133 ) -> Result<CloudTags> {
1134 self.client
1135 .put(
1136 &format!("/fixed/subscriptions/{subscription_id}/databases/{database_id}/tags"),
1137 request,
1138 )
1139 .await
1140 }
1141
1142 /// Delete database tag
1143 /// Removes the specified tag from the database.
1144 ///
1145 /// DELETE /fixed/subscriptions/{subscriptionId}/databases/{databaseId}/tags/{tagKey}
1146 pub async fn delete_tag(
1147 &self,
1148 subscription_id: i32,
1149 database_id: i32,
1150 tag_key: String,
1151 ) -> Result<HashMap<String, Value>> {
1152 let response = self
1153 .client
1154 .delete_raw(&format!(
1155 "/fixed/subscriptions/{subscription_id}/databases/{database_id}/tags/{tag_key}"
1156 ))
1157 .await?;
1158 serde_json::from_value(response).map_err(Into::into)
1159 }
1160
1161 /// Update database tag value
1162 /// Updates the value of the specified database tag.
1163 ///
1164 /// PUT /fixed/subscriptions/{subscriptionId}/databases/{databaseId}/tags/{tagKey}
1165 pub async fn update_tag(
1166 &self,
1167 subscription_id: i32,
1168 database_id: i32,
1169 tag_key: String,
1170 request: &DatabaseTagUpdateRequest,
1171 ) -> Result<CloudTag> {
1172 self.client
1173 .put(
1174 &format!(
1175 "/fixed/subscriptions/{subscription_id}/databases/{database_id}/tags/{tag_key}"
1176 ),
1177 request,
1178 )
1179 .await
1180 }
1181
1182 // ========================================================================
1183 // Additional endpoints
1184 // ========================================================================
1185
1186 /// Get available target Redis versions for upgrade
1187 /// Gets a list of Redis versions that the Essentials database can be upgraded to.
1188 ///
1189 /// GET /fixed/subscriptions/{subscriptionId}/databases/{databaseId}/available-target-versions
1190 pub async fn get_available_target_versions(
1191 &self,
1192 subscription_id: i32,
1193 database_id: i32,
1194 ) -> Result<Value> {
1195 self.client
1196 .get_raw(&format!(
1197 "/fixed/subscriptions/{subscription_id}/databases/{database_id}/available-target-versions"
1198 ))
1199 .await
1200 }
1201
1202 /// Get Essentials database version upgrade status
1203 /// Gets information on the latest upgrade attempt for this Essentials database.
1204 ///
1205 /// GET /fixed/subscriptions/{subscriptionId}/databases/{databaseId}/upgrade
1206 pub async fn get_upgrade_status(
1207 &self,
1208 subscription_id: i32,
1209 database_id: i32,
1210 ) -> Result<Value> {
1211 self.client
1212 .get_raw(&format!(
1213 "/fixed/subscriptions/{subscription_id}/databases/{database_id}/upgrade"
1214 ))
1215 .await
1216 }
1217
1218 /// Upgrade Essentials database Redis version
1219 /// Upgrades the specified Essentials database to a later Redis version.
1220 ///
1221 /// POST /fixed/subscriptions/{subscriptionId}/databases/{databaseId}/upgrade
1222 pub async fn upgrade_redis_version(
1223 &self,
1224 subscription_id: i32,
1225 database_id: i32,
1226 target_version: &str,
1227 ) -> Result<Value> {
1228 let request = serde_json::json!({
1229 "targetVersion": target_version
1230 });
1231 self.client
1232 .post_raw(
1233 &format!("/fixed/subscriptions/{subscription_id}/databases/{database_id}/upgrade"),
1234 request,
1235 )
1236 .await
1237 }
1238
1239 /// Get Essentials database traffic state
1240 /// Gets the current traffic state for this Essentials database, including
1241 /// whether traffic is stopped and whether it can be resumed.
1242 ///
1243 /// GET /fixed/subscriptions/{subscriptionId}/databases/{databaseId}/traffic
1244 pub async fn get_traffic(
1245 &self,
1246 subscription_id: i32,
1247 database_id: i32,
1248 ) -> Result<DatabaseTrafficStateResponse> {
1249 self.client
1250 .get(&format!(
1251 "/fixed/subscriptions/{subscription_id}/databases/{database_id}/traffic"
1252 ))
1253 .await
1254 }
1255
1256 /// Resume Essentials database traffic
1257 /// Resumes traffic to this Essentials database after it has been stopped.
1258 ///
1259 /// POST /fixed/subscriptions/{subscriptionId}/databases/{databaseId}/traffic/resume
1260 pub async fn resume_traffic(&self, subscription_id: i32, database_id: i32) -> Result<()> {
1261 self.client
1262 .post(
1263 &format!(
1264 "/fixed/subscriptions/{subscription_id}/databases/{database_id}/traffic/resume"
1265 ),
1266 &serde_json::json!({}),
1267 )
1268 .await
1269 }
1270}