1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
/*
* SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use std::borrow::Cow;
use prettytable::{format, Attr, Cell, Row, Table};
use reqwest::Method;
use serde_json::Value;
use crate::modules::List;
use super::cli::{Client, DomainCommands};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Clone)]
struct DnsRecord {
#[serde(rename = "type")]
typ: String,
name: String,
content: String,
}
impl DomainCommands {
pub async fn exec(self, client: Client) {
match self {
DomainCommands::Create { name } => {
client
.http_request::<Value, String>(
Method::POST,
&format!("/api/domain/{name}"),
None,
)
.await;
eprintln!("Successfully created domain {name:?}");
}
DomainCommands::Delete { name } => {
client
.http_request::<Value, String>(
Method::DELETE,
&format!("/api/domain/{name}"),
None,
)
.await;
eprintln!("Successfully deleted domain {name:?}");
}
DomainCommands::DNSRecords { name } => {
let records = client
.http_request::<Vec<DnsRecord>, String>(
Method::GET,
&format!("/api/domain/{name}"),
None,
)
.await;
if !records.is_empty() {
let mut table = Table::new();
// no borderline separator separator, as long values will mess it up
table.set_format(*format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR);
table.add_row(Row::new(vec![
Cell::new("Type").with_style(Attr::Bold),
Cell::new("Name").with_style(Attr::Bold),
Cell::new("Contents").with_style(Attr::Bold),
]));
for record in &records {
table.add_row(Row::new(vec![
Cell::new(&record.typ),
Cell::new(&record.name),
Cell::new(&record.content),
]));
}
eprintln!();
table.printstd();
eprintln!();
}
}
DomainCommands::List { from, limit } => {
let query = if from.is_none() && limit.is_none() {
Cow::Borrowed("/api/domain")
} else {
let mut query = "/api/domain?".to_string();
if let Some(from) = &from {
query.push_str(&format!("from={from}"));
}
if let Some(limit) = limit {
query.push_str(&format!(
"{}limit={limit}",
if from.is_some() { "&" } else { "" }
));
}
Cow::Owned(query)
};
let domains = client
.http_request::<List<String>, String>(Method::GET, query.as_ref(), None)
.await;
if !domains.items.is_empty() {
let mut table = Table::new();
table.add_row(Row::new(vec![
Cell::new("Domain Name").with_style(Attr::Bold)
]));
for domain in &domains.items {
table.add_row(Row::new(vec![Cell::new(domain)]));
}
eprintln!();
table.printstd();
eprintln!();
}
eprintln!(
"\n\n{} domain{} found.\n",
domains.total,
if domains.total == 1 { "" } else { "s" }
);
}
}
}
}
|