1use crate::{CloudClient, Result};
44use serde::{Deserialize, Serialize};
45use serde_json::Value;
46use std::collections::HashMap;
47
48#[derive(Debug, Clone, Serialize, Deserialize)]
54#[serde(rename_all = "camelCase")]
55pub struct AclRoleCreateRequest {
56 pub name: String,
58
59 pub redis_rules: Vec<AclRoleRedisRuleSpec>,
61
62 #[serde(skip_serializing_if = "Option::is_none")]
63 pub command_type: Option<String>,
64
65 #[serde(flatten)]
67 pub extra: Value,
68}
69
70#[derive(Debug, Clone, Serialize, Deserialize)]
72#[serde(rename_all = "camelCase")]
73pub struct ProcessorResponse {
74 #[serde(skip_serializing_if = "Option::is_none")]
75 pub resource_id: Option<i32>,
76
77 #[serde(skip_serializing_if = "Option::is_none")]
78 pub additional_resource_id: Option<i32>,
79
80 #[serde(skip_serializing_if = "Option::is_none")]
81 pub resource: Option<HashMap<String, Value>>,
82
83 #[serde(skip_serializing_if = "Option::is_none")]
84 pub error: Option<String>,
85
86 #[serde(skip_serializing_if = "Option::is_none")]
87 pub additional_info: Option<String>,
88
89 #[serde(flatten)]
91 pub extra: Value,
92}
93
94#[derive(Debug, Clone, Serialize, Deserialize)]
96#[serde(rename_all = "camelCase")]
97pub struct AclUserUpdateRequest {
98 #[serde(skip_serializing_if = "Option::is_none")]
99 pub user_id: Option<i32>,
100
101 #[serde(skip_serializing_if = "Option::is_none")]
103 pub role: Option<String>,
104
105 #[serde(skip_serializing_if = "Option::is_none")]
107 pub password: Option<String>,
108
109 #[serde(skip_serializing_if = "Option::is_none")]
110 pub command_type: Option<String>,
111
112 #[serde(flatten)]
114 pub extra: Value,
115}
116
117#[derive(Debug, Clone, Serialize, Deserialize)]
119#[serde(rename_all = "camelCase")]
120pub struct AccountACLUsers {
121 #[serde(skip_serializing_if = "Option::is_none")]
122 pub account_id: Option<i32>,
123
124 #[serde(skip_serializing_if = "Option::is_none")]
126 pub links: Option<Vec<HashMap<String, Value>>>,
127
128 #[serde(flatten)]
130 pub extra: Value,
131}
132
133#[derive(Debug, Clone, Serialize, Deserialize)]
135#[serde(rename_all = "camelCase")]
136pub struct AccountACLRedisRules {
137 #[serde(skip_serializing_if = "Option::is_none")]
138 pub account_id: Option<i32>,
139
140 #[serde(skip_serializing_if = "Option::is_none")]
142 pub links: Option<Vec<HashMap<String, Value>>>,
143
144 #[serde(flatten)]
146 pub extra: Value,
147}
148
149#[derive(Debug, Clone, Serialize, Deserialize)]
151#[serde(rename_all = "camelCase")]
152pub struct AclRedisRuleCreateRequest {
153 pub name: String,
155
156 pub redis_rule: String,
158
159 #[serde(skip_serializing_if = "Option::is_none")]
160 pub command_type: Option<String>,
161
162 #[serde(flatten)]
164 pub extra: Value,
165}
166
167#[derive(Debug, Clone, Serialize, Deserialize)]
169#[serde(rename_all = "camelCase")]
170pub struct AccountACLRoles {
171 #[serde(skip_serializing_if = "Option::is_none")]
172 pub account_id: Option<i32>,
173
174 #[serde(skip_serializing_if = "Option::is_none")]
176 pub links: Option<Vec<HashMap<String, Value>>>,
177
178 #[serde(flatten)]
180 pub extra: Value,
181}
182
183#[derive(Debug, Clone, Serialize, Deserialize)]
185#[serde(rename_all = "camelCase")]
186pub struct AclRedisRuleUpdateRequest {
187 #[serde(skip_serializing_if = "Option::is_none")]
188 pub redis_rule_id: Option<i32>,
189
190 pub name: String,
192
193 pub redis_rule: String,
195
196 #[serde(skip_serializing_if = "Option::is_none")]
197 pub command_type: Option<String>,
198
199 #[serde(flatten)]
201 pub extra: Value,
202}
203
204#[derive(Debug, Clone, Serialize, Deserialize)]
206#[serde(rename_all = "camelCase")]
207pub struct AclRoleDatabaseSpec {
208 pub subscription_id: i32,
210
211 pub database_id: i32,
213
214 #[serde(skip_serializing_if = "Option::is_none")]
216 pub regions: Option<Vec<String>>,
217
218 #[serde(flatten)]
220 pub extra: Value,
221}
222
223#[derive(Debug, Clone, Serialize, Deserialize)]
225#[serde(rename_all = "camelCase")]
226pub struct AclUserCreateRequest {
227 pub name: String,
229
230 pub role: String,
232
233 pub password: String,
235
236 #[serde(skip_serializing_if = "Option::is_none")]
237 pub command_type: Option<String>,
238
239 #[serde(flatten)]
241 pub extra: Value,
242}
243
244#[derive(Debug, Clone, Serialize, Deserialize)]
246pub struct ACLUser {
247 #[serde(skip_serializing_if = "Option::is_none")]
248 pub id: Option<i32>,
249
250 #[serde(skip_serializing_if = "Option::is_none")]
251 pub name: Option<String>,
252
253 #[serde(skip_serializing_if = "Option::is_none")]
254 pub role: Option<String>,
255
256 #[serde(skip_serializing_if = "Option::is_none")]
257 pub status: Option<String>,
258
259 #[serde(skip_serializing_if = "Option::is_none")]
261 pub links: Option<Vec<HashMap<String, Value>>>,
262
263 #[serde(flatten)]
265 pub extra: Value,
266}
267
268#[derive(Debug, Clone, Serialize, Deserialize)]
270#[serde(rename_all = "camelCase")]
271pub struct AclRoleUpdateRequest {
272 #[serde(skip_serializing_if = "Option::is_none")]
274 pub name: Option<String>,
275
276 #[serde(skip_serializing_if = "Option::is_none")]
278 pub redis_rules: Option<Vec<AclRoleRedisRuleSpec>>,
279
280 #[serde(skip_serializing_if = "Option::is_none")]
281 pub role_id: Option<i32>,
282
283 #[serde(skip_serializing_if = "Option::is_none")]
284 pub command_type: Option<String>,
285
286 #[serde(flatten)]
288 pub extra: Value,
289}
290
291#[derive(Debug, Clone, Serialize, Deserialize)]
293#[serde(rename_all = "camelCase")]
294pub struct AclRoleRedisRuleSpec {
295 pub rule_name: String,
297
298 pub databases: Vec<AclRoleDatabaseSpec>,
300
301 #[serde(flatten)]
303 pub extra: Value,
304}
305
306#[derive(Debug, Clone, Serialize, Deserialize)]
308#[serde(rename_all = "camelCase")]
309pub struct TaskStateUpdate {
310 #[serde(skip_serializing_if = "Option::is_none")]
311 pub task_id: Option<String>,
312
313 #[serde(skip_serializing_if = "Option::is_none")]
314 pub command_type: Option<String>,
315
316 #[serde(skip_serializing_if = "Option::is_none")]
317 pub status: Option<String>,
318
319 #[serde(skip_serializing_if = "Option::is_none")]
320 pub description: Option<String>,
321
322 #[serde(skip_serializing_if = "Option::is_none")]
323 pub timestamp: Option<String>,
324
325 #[serde(skip_serializing_if = "Option::is_none")]
326 pub response: Option<ProcessorResponse>,
327
328 #[serde(skip_serializing_if = "Option::is_none")]
330 pub links: Option<Vec<HashMap<String, Value>>>,
331
332 #[serde(flatten)]
334 pub extra: Value,
335}
336
337pub struct AclHandler {
346 client: CloudClient,
347}
348
349impl AclHandler {
350 pub fn new(client: CloudClient) -> Self {
352 Self { client }
353 }
354
355 pub async fn get_all_redis_rules(&self) -> Result<AccountACLRedisRules> {
360 self.client.get("/acl/redisRules").await
361 }
362
363 pub async fn create_redis_rule(
368 &self,
369 request: &AclRedisRuleCreateRequest,
370 ) -> Result<TaskStateUpdate> {
371 self.client.post("/acl/redisRules", request).await
372 }
373
374 pub async fn delete_redis_rule(&self, acl_redis_rule_id: i32) -> Result<TaskStateUpdate> {
379 let response = self
380 .client
381 .delete_raw(&format!("/acl/redisRules/{}", acl_redis_rule_id))
382 .await?;
383 serde_json::from_value(response).map_err(Into::into)
384 }
385
386 pub async fn update_redis_rule(
391 &self,
392 acl_redis_rule_id: i32,
393 request: &AclRedisRuleUpdateRequest,
394 ) -> Result<TaskStateUpdate> {
395 self.client
396 .put(&format!("/acl/redisRules/{}", acl_redis_rule_id), request)
397 .await
398 }
399
400 pub async fn get_roles(&self) -> Result<AccountACLRoles> {
405 self.client.get("/acl/roles").await
406 }
407
408 pub async fn create_role(&self, request: &AclRoleCreateRequest) -> Result<TaskStateUpdate> {
413 self.client.post("/acl/roles", request).await
414 }
415
416 pub async fn delete_acl_role(&self, acl_role_id: i32) -> Result<TaskStateUpdate> {
421 let response = self
422 .client
423 .delete_raw(&format!("/acl/roles/{}", acl_role_id))
424 .await?;
425 serde_json::from_value(response).map_err(Into::into)
426 }
427
428 pub async fn update_role(
433 &self,
434 acl_role_id: i32,
435 request: &AclRoleUpdateRequest,
436 ) -> Result<TaskStateUpdate> {
437 self.client
438 .put(&format!("/acl/roles/{}", acl_role_id), request)
439 .await
440 }
441
442 pub async fn get_all_acl_users(&self) -> Result<AccountACLUsers> {
447 self.client.get("/acl/users").await
448 }
449
450 pub async fn create_user(&self, request: &AclUserCreateRequest) -> Result<TaskStateUpdate> {
455 self.client.post("/acl/users", request).await
456 }
457
458 pub async fn delete_user(&self, acl_user_id: i32) -> Result<TaskStateUpdate> {
463 let response = self
464 .client
465 .delete_raw(&format!("/acl/users/{}", acl_user_id))
466 .await?;
467 serde_json::from_value(response).map_err(Into::into)
468 }
469
470 pub async fn get_user_by_id(&self, acl_user_id: i32) -> Result<ACLUser> {
475 self.client
476 .get(&format!("/acl/users/{}", acl_user_id))
477 .await
478 }
479
480 pub async fn update_acl_user(
485 &self,
486 acl_user_id: i32,
487 request: &AclUserUpdateRequest,
488 ) -> Result<TaskStateUpdate> {
489 self.client
490 .put(&format!("/acl/users/{}", acl_user_id), request)
491 .await
492 }
493}