]> git.proxmox.com Git - proxmox-backup.git/blame - src/api2/node/subscription.rs
api: rustfmt
[proxmox-backup.git] / src / api2 / node / subscription.rs
CommitLineData
dc7a5b34 1use anyhow::{bail, format_err, Error};
7b22fb25 2use serde_json::Value;
7e13b2d6 3
dc7a5b34 4use proxmox_router::{Permission, Router, RpcEnvironment};
6ef1b649 5use proxmox_schema::api;
a2479cfa 6
8cc3760e 7use pbs_api_types::{
dc7a5b34 8 Authid, NODE_SCHEMA, PRIV_SYS_AUDIT, PRIV_SYS_MODIFY, SUBSCRIPTION_KEY_SCHEMA,
8cc3760e
DM
9};
10
a2479cfa 11use crate::tools;
dc7a5b34 12use crate::tools::subscription::{self, SubscriptionInfo, SubscriptionStatus};
ba3d7e19 13use pbs_config::CachedUserInfo;
7e13b2d6 14
1bfc1efa 15#[api(
113c9b59
SR
16 input: {
17 properties: {
18 node: {
19 schema: NODE_SCHEMA,
20 },
7b22fb25
TL
21 force: {
22 description: "Always connect to server, even if information in cache is up to date.",
23 type: bool,
24 optional: true,
25 default: false,
26 },
113c9b59
SR
27 },
28 },
7b22fb25
TL
29 protected: true,
30 access: {
31 permission: &Permission::Privilege(&["system"], PRIV_SYS_MODIFY, false),
32 },
33)]
34/// Check and update subscription status.
dc7a5b34 35pub fn check_subscription(force: bool) -> Result<(), Error> {
7b22fb25
TL
36 let info = match subscription::read_subscription() {
37 Err(err) => bail!("could not read subscription status: {}", err),
38 Ok(Some(info)) => info,
39 Ok(None) => return Ok(()),
40 };
41
42 let server_id = tools::get_hardware_address()?;
43 let key = if let Some(key) = info.key {
44 // always update apt auth if we have a key to ensure user can access enterprise repo
45 subscription::update_apt_auth(Some(key.to_owned()), Some(server_id.to_owned()))?;
46 key
47 } else {
48 String::new()
49 };
50
51 if !force && info.status == SubscriptionStatus::ACTIVE {
6ef1b649 52 let age = proxmox_time::epoch_i64() - info.checktime.unwrap_or(i64::MAX);
7b22fb25
TL
53 if age < subscription::MAX_LOCAL_KEY_AGE {
54 return Ok(());
55 }
56 }
57
58 let info = subscription::check_subscription(key, server_id)?;
59
60 subscription::write_subscription(info)
61 .map_err(|e| format_err!("Error writing updated subscription status - {}", e))?;
62
63 Ok(())
64}
65
66#[api(
67 input: {
1bfc1efa 68 properties: {
7b22fb25
TL
69 node: {
70 schema: NODE_SCHEMA,
1bfc1efa
DM
71 },
72 },
73 },
9b93c620 74 returns: { type: SubscriptionInfo },
1bfc1efa 75 access: {
9626c286 76 permission: &Permission::Anybody,
1bfc1efa
DM
77 },
78)]
79/// Read subscription info.
652506e6 80pub fn get_subscription(
9626c286
FG
81 _param: Value,
82 rpcenv: &mut dyn RpcEnvironment,
7b22fb25
TL
83) -> Result<SubscriptionInfo, Error> {
84 let url = "https://www.proxmox.com/en/proxmox-backup-server/pricing";
85
86 let info = match subscription::read_subscription() {
87 Err(err) => bail!("could not read subscription status: {}", err),
88 Ok(Some(info)) => info,
89 Ok(None) => SubscriptionInfo {
90 status: SubscriptionStatus::NOTFOUND,
91 message: Some("There is no subscription key".into()),
92 serverid: Some(tools::get_hardware_address()?),
dc7a5b34 93 url: Some(url.into()),
7b22fb25
TL
94 ..Default::default()
95 },
96 };
97
e6dc35ac 98 let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
9626c286 99 let user_info = CachedUserInfo::new()?;
e6dc35ac 100 let user_privs = user_info.lookup_privs(&auth_id, &[]);
7b22fb25
TL
101
102 if (user_privs & PRIV_SYS_AUDIT) == 0 {
103 // not enough privileges for full state
104 return Ok(SubscriptionInfo {
105 status: info.status,
106 message: info.message,
107 url: info.url,
108 ..Default::default()
109 });
9626c286 110 };
7e13b2d6 111
7b22fb25
TL
112 Ok(info)
113}
114
115#[api(
116 input: {
117 properties: {
118 node: {
119 schema: NODE_SCHEMA,
120 },
121 key: {
926d2531 122 schema: SUBSCRIPTION_KEY_SCHEMA,
7b22fb25
TL
123 },
124 },
125 },
126 protected: true,
127 access: {
128 permission: &Permission::Privilege(&["system"], PRIV_SYS_MODIFY, false),
129 },
130)]
131/// Set a subscription key and check it.
dc7a5b34 132pub fn set_subscription(key: String) -> Result<(), Error> {
7b22fb25
TL
133 let server_id = tools::get_hardware_address()?;
134
44288184 135 let info = subscription::check_subscription(key, server_id)?;
7b22fb25
TL
136
137 subscription::write_subscription(info)
138 .map_err(|e| format_err!("Error writing subscription status - {}", e))?;
139
140 Ok(())
141}
142
143#[api(
144 input: {
145 properties: {
146 node: {
147 schema: NODE_SCHEMA,
148 },
149 },
150 },
151 protected: true,
152 access: {
153 permission: &Permission::Privilege(&["system"], PRIV_SYS_MODIFY, false),
154 },
155)]
156/// Delete subscription info.
652506e6 157pub fn delete_subscription() -> Result<(), Error> {
7b22fb25
TL
158 subscription::delete_subscription()
159 .map_err(|err| format_err!("Deleting subscription failed: {}", err))?;
160
161 Ok(())
7e13b2d6
DM
162}
163
255f378a 164pub const ROUTER: Router = Router::new()
7b22fb25
TL
165 .post(&API_METHOD_CHECK_SUBSCRIPTION)
166 .put(&API_METHOD_SET_SUBSCRIPTION)
167 .delete(&API_METHOD_DELETE_SUBSCRIPTION)
1bfc1efa 168 .get(&API_METHOD_GET_SUBSCRIPTION);