1use crate::types::{Link, ProcessorResponse};
44use crate::{CloudClient, Result};
45use serde::{Deserialize, Serialize};
46
47#[derive(Debug, Clone, Serialize, Deserialize)]
53#[serde(rename_all = "camelCase")]
54pub struct AclRoleCreateRequest {
55 pub name: String,
57
58 pub redis_rules: Vec<AclRoleRedisRuleSpec>,
60
61 #[serde(skip_serializing_if = "Option::is_none")]
62 pub command_type: Option<String>,
63}
64
65#[derive(Debug, Clone, Serialize, Deserialize)]
67#[serde(rename_all = "camelCase")]
68pub struct AclUserUpdateRequest {
69 #[serde(skip_serializing_if = "Option::is_none")]
70 pub user_id: Option<i32>,
71
72 #[serde(skip_serializing_if = "Option::is_none")]
74 pub role: Option<String>,
75
76 #[serde(skip_serializing_if = "Option::is_none")]
78 pub password: Option<String>,
79
80 #[serde(skip_serializing_if = "Option::is_none")]
81 pub command_type: Option<String>,
82}
83
84#[derive(Debug, Clone, Serialize, Deserialize)]
88#[serde(rename_all = "camelCase")]
89pub struct AccountACLUsers {
90 #[serde(skip_serializing_if = "Option::is_none")]
92 pub account_id: Option<i32>,
93
94 #[serde(skip_serializing_if = "Option::is_none")]
96 pub users: Option<Vec<ACLUser>>,
97
98 #[serde(skip_serializing_if = "Option::is_none")]
100 pub links: Option<Vec<Link>>,
101}
102
103#[derive(Debug, Clone, Serialize, Deserialize)]
107#[serde(rename_all = "camelCase")]
108pub struct AccountACLRedisRules {
109 #[serde(skip_serializing_if = "Option::is_none")]
111 pub account_id: Option<i32>,
112
113 #[serde(skip_serializing_if = "Option::is_none")]
115 pub redis_rules: Option<Vec<ACLRedisRule>>,
116
117 #[serde(skip_serializing_if = "Option::is_none")]
119 pub links: Option<Vec<Link>>,
120}
121
122#[derive(Debug, Clone, Serialize, Deserialize)]
124#[serde(rename_all = "camelCase")]
125pub struct ACLRedisRule {
126 #[serde(skip_serializing_if = "Option::is_none")]
128 pub id: Option<i32>,
129
130 #[serde(skip_serializing_if = "Option::is_none")]
132 pub name: Option<String>,
133
134 #[serde(skip_serializing_if = "Option::is_none")]
136 pub acl: Option<String>,
137
138 #[serde(skip_serializing_if = "Option::is_none")]
140 pub is_default: Option<bool>,
141
142 #[serde(skip_serializing_if = "Option::is_none")]
144 pub status: Option<String>,
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize)]
149#[serde(rename_all = "camelCase")]
150pub struct AclRedisRuleCreateRequest {
151 pub name: String,
153
154 pub redis_rule: String,
156
157 #[serde(skip_serializing_if = "Option::is_none")]
158 pub command_type: Option<String>,
159}
160
161#[derive(Debug, Clone, Serialize, Deserialize)]
165#[serde(rename_all = "camelCase")]
166pub struct AccountACLRoles {
167 #[serde(skip_serializing_if = "Option::is_none")]
169 pub account_id: Option<i32>,
170
171 #[serde(skip_serializing_if = "Option::is_none")]
173 pub roles: Option<Vec<ACLRole>>,
174
175 #[serde(skip_serializing_if = "Option::is_none")]
177 pub links: Option<Vec<Link>>,
178}
179
180#[derive(Debug, Clone, Serialize, Deserialize)]
182#[serde(rename_all = "camelCase")]
183pub struct ACLRole {
184 #[serde(skip_serializing_if = "Option::is_none")]
186 pub id: Option<i32>,
187
188 #[serde(skip_serializing_if = "Option::is_none")]
190 pub name: Option<String>,
191
192 #[serde(skip_serializing_if = "Option::is_none")]
196 pub redis_rules: Option<Vec<ACLRoleRedisRule>>,
197
198 #[serde(skip_serializing_if = "Option::is_none")]
200 pub users: Option<Vec<ACLRoleUser>>,
201
202 #[serde(skip_serializing_if = "Option::is_none")]
204 pub status: Option<String>,
205}
206
207#[derive(Debug, Clone, Serialize, Deserialize)]
209#[serde(rename_all = "camelCase")]
210pub struct ACLRoleUser {
211 #[serde(skip_serializing_if = "Option::is_none")]
213 pub id: Option<i32>,
214
215 #[serde(skip_serializing_if = "Option::is_none")]
217 pub name: Option<String>,
218}
219
220#[derive(Debug, Clone, Serialize, Deserialize)]
225#[serde(rename_all = "camelCase")]
226pub struct ACLRoleRedisRule {
227 #[serde(skip_serializing_if = "Option::is_none")]
229 pub rule_id: Option<i32>,
230
231 #[serde(skip_serializing_if = "Option::is_none")]
233 pub rule_name: Option<String>,
234
235 #[serde(skip_serializing_if = "Option::is_none")]
237 pub databases: Option<Vec<ACLRoleDatabase>>,
238}
239
240#[derive(Debug, Clone, Serialize, Deserialize)]
242#[serde(rename_all = "camelCase")]
243pub struct ACLRoleDatabase {
244 #[serde(skip_serializing_if = "Option::is_none")]
246 pub subscription_id: Option<i32>,
247
248 #[serde(skip_serializing_if = "Option::is_none")]
250 pub database_id: Option<i32>,
251
252 #[serde(skip_serializing_if = "Option::is_none")]
254 pub database_name: Option<String>,
255
256 #[serde(skip_serializing_if = "Option::is_none")]
258 pub regions: Option<Vec<String>>,
259}
260
261#[derive(Debug, Clone, Serialize, Deserialize)]
263#[serde(rename_all = "camelCase")]
264pub struct AclRedisRuleUpdateRequest {
265 #[serde(skip_serializing_if = "Option::is_none")]
266 pub redis_rule_id: Option<i32>,
267
268 pub name: String,
270
271 pub redis_rule: String,
273
274 #[serde(skip_serializing_if = "Option::is_none")]
275 pub command_type: Option<String>,
276}
277
278#[derive(Debug, Clone, Serialize, Deserialize)]
280#[serde(rename_all = "camelCase")]
281pub struct AclRoleDatabaseSpec {
282 pub subscription_id: i32,
284
285 pub database_id: i32,
287
288 #[serde(skip_serializing_if = "Option::is_none")]
290 pub regions: Option<Vec<String>>,
291}
292
293#[derive(Debug, Clone, Serialize, Deserialize)]
295#[serde(rename_all = "camelCase")]
296pub struct AclUserCreateRequest {
297 pub name: String,
299
300 pub role: String,
302
303 pub password: String,
305
306 #[serde(skip_serializing_if = "Option::is_none")]
307 pub command_type: Option<String>,
308}
309
310#[derive(Debug, Clone, Serialize, Deserialize)]
312pub struct ACLUser {
313 #[serde(skip_serializing_if = "Option::is_none")]
315 pub id: Option<i32>,
316
317 #[serde(skip_serializing_if = "Option::is_none")]
319 pub name: Option<String>,
320
321 #[serde(skip_serializing_if = "Option::is_none")]
323 pub role: Option<String>,
324
325 #[serde(skip_serializing_if = "Option::is_none")]
327 pub status: Option<String>,
328
329 #[serde(skip_serializing_if = "Option::is_none")]
331 pub links: Option<Vec<Link>>,
332}
333
334#[derive(Debug, Clone, Serialize, Deserialize)]
336#[serde(rename_all = "camelCase")]
337pub struct AclRoleUpdateRequest {
338 #[serde(skip_serializing_if = "Option::is_none")]
340 pub name: Option<String>,
341
342 #[serde(skip_serializing_if = "Option::is_none")]
344 pub redis_rules: Option<Vec<AclRoleRedisRuleSpec>>,
345
346 #[serde(skip_serializing_if = "Option::is_none")]
347 pub role_id: Option<i32>,
348
349 #[serde(skip_serializing_if = "Option::is_none")]
350 pub command_type: Option<String>,
351}
352
353#[derive(Debug, Clone, Serialize, Deserialize)]
355#[serde(rename_all = "camelCase")]
356pub struct AclRoleRedisRuleSpec {
357 pub rule_name: String,
359
360 pub databases: Vec<AclRoleDatabaseSpec>,
362}
363
364#[derive(Debug, Clone, Serialize, Deserialize)]
366#[serde(rename_all = "camelCase")]
367pub struct TaskStateUpdate {
368 #[serde(skip_serializing_if = "Option::is_none")]
370 pub task_id: Option<String>,
371
372 #[serde(skip_serializing_if = "Option::is_none")]
374 pub command_type: Option<String>,
375
376 #[serde(skip_serializing_if = "Option::is_none")]
378 pub status: Option<String>,
379
380 #[serde(skip_serializing_if = "Option::is_none")]
382 pub description: Option<String>,
383
384 #[serde(skip_serializing_if = "Option::is_none")]
386 pub timestamp: Option<String>,
387
388 #[serde(skip_serializing_if = "Option::is_none")]
390 pub response: Option<ProcessorResponse>,
391
392 #[serde(skip_serializing_if = "Option::is_none")]
394 pub links: Option<Vec<Link>>,
395}
396
397pub struct AclHandler {
406 client: CloudClient,
407}
408
409impl AclHandler {
410 #[must_use]
412 pub fn new(client: CloudClient) -> Self {
413 Self { client }
414 }
415
416 pub async fn get_all_redis_rules(&self) -> Result<AccountACLRedisRules> {
437 self.client.get("/acl/redisRules").await
438 }
439
440 pub async fn create_redis_rule(
445 &self,
446 request: &AclRedisRuleCreateRequest,
447 ) -> Result<TaskStateUpdate> {
448 self.client.post("/acl/redisRules", request).await
449 }
450
451 pub async fn delete_redis_rule(&self, acl_redis_rule_id: i32) -> Result<TaskStateUpdate> {
456 let response = self
457 .client
458 .delete_raw(&format!("/acl/redisRules/{acl_redis_rule_id}"))
459 .await?;
460 serde_json::from_value(response).map_err(Into::into)
461 }
462
463 pub async fn update_redis_rule(
468 &self,
469 acl_redis_rule_id: i32,
470 request: &AclRedisRuleUpdateRequest,
471 ) -> Result<TaskStateUpdate> {
472 self.client
473 .put(&format!("/acl/redisRules/{acl_redis_rule_id}"), request)
474 .await
475 }
476
477 pub async fn get_roles(&self) -> Result<AccountACLRoles> {
498 self.client.get("/acl/roles").await
499 }
500
501 pub async fn create_role(&self, request: &AclRoleCreateRequest) -> Result<TaskStateUpdate> {
506 self.client.post("/acl/roles", request).await
507 }
508
509 pub async fn delete_acl_role(&self, acl_role_id: i32) -> Result<TaskStateUpdate> {
514 let response = self
515 .client
516 .delete_raw(&format!("/acl/roles/{acl_role_id}"))
517 .await?;
518 serde_json::from_value(response).map_err(Into::into)
519 }
520
521 pub async fn update_role(
526 &self,
527 acl_role_id: i32,
528 request: &AclRoleUpdateRequest,
529 ) -> Result<TaskStateUpdate> {
530 self.client
531 .put(&format!("/acl/roles/{acl_role_id}"), request)
532 .await
533 }
534
535 pub async fn get_all_acl_users(&self) -> Result<AccountACLUsers> {
540 self.client.get("/acl/users").await
541 }
542
543 pub async fn create_user(&self, request: &AclUserCreateRequest) -> Result<TaskStateUpdate> {
548 self.client.post("/acl/users", request).await
549 }
550
551 pub async fn delete_user(&self, acl_user_id: i32) -> Result<TaskStateUpdate> {
556 let response = self
557 .client
558 .delete_raw(&format!("/acl/users/{acl_user_id}"))
559 .await?;
560 serde_json::from_value(response).map_err(Into::into)
561 }
562
563 pub async fn get_user_by_id(&self, acl_user_id: i32) -> Result<ACLUser> {
568 self.client.get(&format!("/acl/users/{acl_user_id}")).await
569 }
570
571 pub async fn update_acl_user(
576 &self,
577 acl_user_id: i32,
578 request: &AclUserUpdateRequest,
579 ) -> Result<TaskStateUpdate> {
580 self.client
581 .put(&format!("/acl/users/{acl_user_id}"), request)
582 .await
583 }
584}