Line data Source code
1 : //! Structs representing the JSON formats used in the compute_ctl's HTTP API.
2 :
3 : use std::fmt::Display;
4 :
5 : use chrono::{DateTime, Utc};
6 : use jsonwebtoken::jwk::JwkSet;
7 : use serde::{Deserialize, Serialize, Serializer};
8 :
9 : use crate::privilege::Privilege;
10 : use crate::spec::{ComputeSpec, Database, ExtVersion, PgIdent, Role};
11 :
12 0 : #[derive(Serialize, Debug, Deserialize)]
13 : pub struct GenericAPIError {
14 : pub error: String,
15 : }
16 :
17 : #[derive(Debug, Clone, Serialize)]
18 : pub struct ExtensionInstallResponse {
19 : pub extension: PgIdent,
20 : pub version: ExtVersion,
21 : }
22 :
23 : /// Response of the /status API
24 0 : #[derive(Serialize, Debug, Deserialize)]
25 : #[serde(rename_all = "snake_case")]
26 : pub struct ComputeStatusResponse {
27 : pub start_time: DateTime<Utc>,
28 : pub tenant: Option<String>,
29 : pub timeline: Option<String>,
30 : pub status: ComputeStatus,
31 : #[serde(serialize_with = "rfc3339_serialize")]
32 : pub last_active: Option<DateTime<Utc>>,
33 : pub error: Option<String>,
34 : }
35 :
36 0 : #[derive(Serialize, Clone, Copy, Debug, Deserialize, PartialEq, Eq)]
37 : #[serde(rename_all = "snake_case")]
38 : pub enum ComputeStatus {
39 : // Spec wasn't provided at start, waiting for it to be
40 : // provided by control-plane.
41 : Empty,
42 : // Compute configuration was requested.
43 : ConfigurationPending,
44 : // Compute node has spec and initial startup and
45 : // configuration is in progress.
46 : Init,
47 : // Compute is configured and running.
48 : Running,
49 : // New spec is being applied.
50 : Configuration,
51 : // Either startup or configuration failed,
52 : // compute will exit soon or is waiting for
53 : // control-plane to terminate it.
54 : Failed,
55 : // Termination requested
56 : TerminationPending,
57 : // Terminated Postgres
58 : Terminated,
59 : }
60 :
61 : impl Display for ComputeStatus {
62 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63 0 : match self {
64 0 : ComputeStatus::Empty => f.write_str("empty"),
65 0 : ComputeStatus::ConfigurationPending => f.write_str("configuration-pending"),
66 0 : ComputeStatus::Init => f.write_str("init"),
67 0 : ComputeStatus::Running => f.write_str("running"),
68 0 : ComputeStatus::Configuration => f.write_str("configuration"),
69 0 : ComputeStatus::Failed => f.write_str("failed"),
70 0 : ComputeStatus::TerminationPending => f.write_str("termination-pending"),
71 0 : ComputeStatus::Terminated => f.write_str("terminated"),
72 : }
73 0 : }
74 : }
75 :
76 0 : pub fn rfc3339_serialize<S>(x: &Option<DateTime<Utc>>, s: S) -> Result<S::Ok, S::Error>
77 0 : where
78 0 : S: Serializer,
79 0 : {
80 0 : if let Some(x) = x {
81 0 : x.to_rfc3339().serialize(s)
82 : } else {
83 0 : s.serialize_none()
84 : }
85 0 : }
86 :
87 : /// Response of the /metrics.json API
88 : #[derive(Clone, Debug, Default, Serialize)]
89 : pub struct ComputeMetrics {
90 : /// Time spent waiting in pool
91 : pub wait_for_spec_ms: u64,
92 :
93 : /// Time spent checking if safekeepers are synced
94 : pub sync_sk_check_ms: u64,
95 :
96 : /// Time spent syncing safekeepers (walproposer.c).
97 : /// In most cases this should be zero.
98 : pub sync_safekeepers_ms: u64,
99 :
100 : /// Time it took to establish a pg connection to the pageserver.
101 : /// This is two roundtrips, so it's a good proxy for compute-pageserver
102 : /// latency. The latency is usually 0.2ms, but it's not safe to assume
103 : /// that.
104 : pub pageserver_connect_micros: u64,
105 :
106 : /// Time to get basebackup from pageserver and write it to disk.
107 : pub basebackup_ms: u64,
108 :
109 : /// Compressed size of basebackup received.
110 : pub basebackup_bytes: u64,
111 :
112 : /// Time spent starting potgres. This includes initialization of shared
113 : /// buffers, preloading extensions, and other pg operations.
114 : pub start_postgres_ms: u64,
115 :
116 : /// Time spent applying pg catalog updates that were made in the console
117 : /// UI. This should be 0 when startup time matters, since cplane tries
118 : /// to do these updates eagerly, and passes the skip_pg_catalog_updates
119 : /// when it's safe to skip this step.
120 : pub config_ms: u64,
121 :
122 : /// Total time, from when we receive the spec to when we're ready to take
123 : /// pg connections.
124 : pub total_startup_ms: u64,
125 : pub load_ext_ms: u64,
126 : pub num_ext_downloaded: u64,
127 : pub largest_ext_size: u64, // these are measured in bytes
128 : pub total_ext_download_size: u64,
129 : }
130 :
131 : #[derive(Clone, Debug, Default, Serialize)]
132 : pub struct CatalogObjects {
133 : pub roles: Vec<Role>,
134 : pub databases: Vec<Database>,
135 : }
136 :
137 0 : #[derive(Clone, Debug, Deserialize, Serialize)]
138 : pub struct ComputeCtlConfig {
139 : /// Set of JSON web keys that the compute can use to authenticate
140 : /// communication from the control plane.
141 : pub jwks: JwkSet,
142 : pub tls: Option<TlsConfig>,
143 : }
144 :
145 : impl Default for ComputeCtlConfig {
146 0 : fn default() -> Self {
147 0 : Self {
148 0 : jwks: JwkSet {
149 0 : keys: Vec::default(),
150 0 : },
151 0 : tls: None,
152 0 : }
153 0 : }
154 : }
155 :
156 0 : #[derive(Clone, Debug, Deserialize, Serialize)]
157 : pub struct TlsConfig {
158 : pub key_path: String,
159 : pub cert_path: String,
160 : }
161 :
162 : /// Response of the `/computes/{compute_id}/spec` control-plane API.
163 0 : #[derive(Deserialize, Debug)]
164 : pub struct ControlPlaneSpecResponse {
165 : pub spec: Option<ComputeSpec>,
166 : pub status: ControlPlaneComputeStatus,
167 : pub compute_ctl_config: ComputeCtlConfig,
168 : }
169 :
170 0 : #[derive(Deserialize, Clone, Copy, Debug, PartialEq, Eq)]
171 : #[serde(rename_all = "snake_case")]
172 : pub enum ControlPlaneComputeStatus {
173 : // Compute is known to control-plane, but it's not
174 : // yet attached to any timeline / endpoint.
175 : Empty,
176 : // Compute is attached to some timeline / endpoint and
177 : // should be able to start with provided spec.
178 : Attached,
179 : }
180 :
181 : #[derive(Clone, Debug, Default, Serialize)]
182 : pub struct InstalledExtension {
183 : pub extname: String,
184 : pub version: String,
185 : pub n_databases: u32, // Number of databases using this extension
186 : pub owned_by_superuser: String,
187 : }
188 :
189 : #[derive(Clone, Debug, Default, Serialize)]
190 : pub struct InstalledExtensions {
191 : pub extensions: Vec<InstalledExtension>,
192 : }
193 :
194 : #[derive(Clone, Debug, Default, Serialize)]
195 : pub struct ExtensionInstallResult {
196 : pub extension: PgIdent,
197 : pub version: ExtVersion,
198 : }
199 : #[derive(Clone, Debug, Default, Serialize)]
200 : pub struct SetRoleGrantsResponse {
201 : pub database: PgIdent,
202 : pub schema: PgIdent,
203 : pub privileges: Vec<Privilege>,
204 : pub role: PgIdent,
205 : }
|