2 use ::serde
::{Deserialize, Serialize}
;
4 use proxmox
::api
::{api, const_regex, schema::*}
;
5 use proxmox
::tools
::*; // required to use IPRE!() macro ???
7 // File names: may not contain slashes, may not start with "."
8 pub const FILENAME_FORMAT
: ApiStringFormat
= ApiStringFormat
::VerifyFn(|name
| {
9 if name
.starts_with('
.'
) {
10 bail
!("file names may not start with '.'");
12 if name
.contains('
/'
) {
13 bail
!("file names may not contain slashes");
20 pub IP_FORMAT_REGEX
= IPRE
!();
21 pub SHA256_HEX_REGEX
= r
"^[a-f0-9]{64}$"; // fixme: define in common_regex ?
22 pub SYSTEMD_DATETIME_REGEX
= r
"^\d{4}-\d{2}-\d{2}( \d{2}:\d{2}(:\d{2})?)?$"; // fixme: define in common_regex ?
24 /// Regex for safe identifiers.
27 /// [article](https://dwheeler.com/essays/fixing-unix-linux-filenames.html)
28 /// contains further information why it is reasonable to restict
29 /// names this way. This is not only useful for filenames, but for
30 /// any identifier command line tools work with.
31 pub PROXMOX_SAFE_ID_REGEX
= r
"^[A-Za-z0-9_][A-Za-z0-9._\-]*";
34 pub const SYSTEMD_DATETIME_FORMAT
: ApiStringFormat
=
35 ApiStringFormat
::Pattern(&SYSTEMD_DATETIME_REGEX
);
37 pub const IP_FORMAT
: ApiStringFormat
=
38 ApiStringFormat
::Pattern(&IP_FORMAT_REGEX
);
40 pub const PVE_CONFIG_DIGEST_FORMAT
: ApiStringFormat
=
41 ApiStringFormat
::Pattern(&SHA256_HEX_REGEX
);
43 pub const PROXMOX_SAFE_ID_FORMAT
: ApiStringFormat
=
44 ApiStringFormat
::Pattern(&PROXMOX_SAFE_ID_REGEX
);
46 pub const PVE_CONFIG_DIGEST_SCHEMA
: Schema
= StringSchema
::new(r
#"\
47 Prevent changes if current configuration file has different SHA256 digest.
48 This can be used to prevent concurrent modifications.
51 .format(&PVE_CONFIG_DIGEST_FORMAT
)
55 pub const CHUNK_DIGEST_FORMAT
: ApiStringFormat
=
56 ApiStringFormat
::Pattern(&SHA256_HEX_REGEX
);
58 pub const CHUNK_DIGEST_SCHEMA
: Schema
= StringSchema
::new("Chunk digest (SHA256).")
59 .format(&CHUNK_DIGEST_FORMAT
)
62 pub const NODE_SCHEMA
: Schema
= StringSchema
::new("Node name (or 'localhost')")
63 .format(&ApiStringFormat
::VerifyFn(|node
| {
64 if node
== "localhost" || node
== proxmox
::tools
::nodename() {
67 bail
!("no such node '{}'", node
);
72 pub const SEARCH_DOMAIN_SCHEMA
: Schema
=
73 StringSchema
::new("Search domain for host-name lookup.").schema();
75 pub const FIRST_DNS_SERVER_SCHEMA
: Schema
=
76 StringSchema
::new("First name server IP address.")
80 pub const SECOND_DNS_SERVER_SCHEMA
: Schema
=
81 StringSchema
::new("Second name server IP address.")
85 pub const THIRD_DNS_SERVER_SCHEMA
: Schema
=
86 StringSchema
::new("Third name server IP address.")
90 pub const BACKUP_ARCHIVE_NAME_SCHEMA
: Schema
=
91 StringSchema
::new("Backup archive name.")
92 .format(&PROXMOX_SAFE_ID_FORMAT
)
95 pub const BACKUP_TYPE_SCHEMA
: Schema
=
96 StringSchema
::new("Backup type.")
97 .format(&ApiStringFormat
::Enum(&["vm", "ct", "host"]))
100 pub const BACKUP_ID_SCHEMA
: Schema
=
101 StringSchema
::new("Backup ID.")
102 .format(&PROXMOX_SAFE_ID_FORMAT
)
105 pub const BACKUP_TIME_SCHEMA
: Schema
=
106 IntegerSchema
::new("Backup time (Unix epoch.)")
107 .minimum(1_547_797_308)
110 pub const UPID_SCHEMA
: Schema
= StringSchema
::new("Unique Process/Task ID.")
114 pub const DATASTORE_SCHEMA
: Schema
= StringSchema
::new("Datastore name.")
115 .format(&PROXMOX_SAFE_ID_FORMAT
)
121 // Complex type definitions
124 description
: "Basic information about backup snapshot.",
127 schema
: BACKUP_TYPE_SCHEMA
,
130 schema
: BACKUP_ID_SCHEMA
,
133 schema
: BACKUP_TIME_SCHEMA
,
137 #[derive(Serialize, Deserialize)]
138 #[serde(rename_all="kebab-case")]
139 pub struct SnapshotListItem
{
140 pub backup_type
: String
, // enum
141 pub backup_id
: String
,
142 pub backup_time
: i64,
143 pub files
: Vec
<String
>,
144 #[serde(skip_serializing_if="Option::is_none")]
145 pub size
: Option
<u64>,