Add endpoint to set role grants

This commit is contained in:
Jere Vaara
2024-10-14 20:01:02 +03:00
parent d92d36a315
commit 4e15a68ffd
5 changed files with 101 additions and 12 deletions

View File

@@ -19,6 +19,7 @@ use futures::future::join_all;
use futures::stream::FuturesUnordered;
use futures::StreamExt;
use nix::unistd::Pid;
use postgres::config::Config;
use postgres::error::SqlState;
use postgres::{Client, NoTls};
use tracing::{debug, error, info, instrument, warn};
@@ -1367,6 +1368,28 @@ LIMIT 100",
download_size
}
pub fn set_role_grants(
&self,
db_name: &str,
schema_name: &str,
privilege: &str,
role_name: &str,
) -> Result<()> {
let mut conf = Config::from_str(self.connstr.as_str()).unwrap();
conf.dbname(db_name);
let mut db_client = conf
.connect(NoTls)
.context("Failed to connect to the database")?;
let query = "GRANT $1 ON SCHEMA $2 TO $3";
db_client
.execute(query, &[&schema_name, &privilege, &role_name])
.context(format!("Failed to execute query: {}", query))?;
Ok(())
}
#[tokio::main]
pub async fn prepare_preload_libraries(
&self,

View File

@@ -9,8 +9,10 @@ use crate::catalog::SchemaDumpError;
use crate::catalog::{get_database_schema, get_dbs_and_roles};
use crate::compute::forward_termination_signal;
use crate::compute::{ComputeNode, ComputeState, ParsedSpec};
use compute_api::requests::ConfigurationRequest;
use compute_api::responses::{ComputeStatus, ComputeStatusResponse, GenericAPIError};
use compute_api::requests::{ConfigurationRequest, SetRoleGrantsRequest};
use compute_api::responses::{
ComputeStatus, ComputeStatusResponse, GenericAPIError, SetRoleGrantsResult,
};
use anyhow::Result;
use hyper::header::CONTENT_TYPE;
@@ -165,6 +167,35 @@ async fn routes(req: Request<Body>, compute: &Arc<ComputeNode>) -> Response<Body
}
}
(&Method::POST, "/grants") => {
info!("serving /grants POST request");
let status = compute.get_status();
if status != ComputeStatus::Running {
let msg = format!(
"invalid compute status for set_role_grants request: {:?}",
status
);
error!(msg);
return Response::new(Body::from(msg));
}
let request = hyper::body::to_bytes(req.into_body()).await.unwrap();
let request = serde_json::from_slice::<SetRoleGrantsRequest>(&request).unwrap();
let res = compute.set_role_grants(
&request.database,
&request.schema,
&request.privilege,
&request.role,
);
match res {
Ok(_) => Response::new(Body::from("true")),
Err(e) => {
error!("set_role_grants failed: {}", e);
Response::new(Body::from(e.to_string()))
}
}
}
// get the list of installed extensions
// currently only used in python tests
// TODO: call it from cplane

View File

@@ -10,7 +10,7 @@ paths:
/status:
get:
tags:
- Info
- Info
summary: Get compute node internal status.
description: ""
operationId: getComputeStatus
@@ -25,7 +25,7 @@ paths:
/metrics.json:
get:
tags:
- Info
- Info
summary: Get compute node startup metrics in JSON format.
description: ""
operationId: getComputeMetricsJSON
@@ -40,7 +40,7 @@ paths:
/insights:
get:
tags:
- Info
- Info
summary: Get current compute insights in JSON format.
description: |
Note, that this doesn't include any historical data.
@@ -56,7 +56,7 @@ paths:
/installed_extensions:
get:
tags:
- Info
- Info
summary: Get installed extensions.
description: ""
operationId: getInstalledExtensions
@@ -70,7 +70,7 @@ paths:
/info:
get:
tags:
- Info
- Info
summary: Get info about the compute pod / VM.
description: ""
operationId: getInfo
@@ -130,7 +130,7 @@ paths:
/check_writability:
post:
tags:
- Check
- Check
summary: Check that we can write new data on this compute.
description: ""
operationId: checkComputeWritability
@@ -147,7 +147,7 @@ paths:
/configure:
post:
tags:
- Configure
- Configure
summary: Perform compute node configuration.
description: |
This is a blocking API endpoint, i.e. it blocks waiting until
@@ -201,7 +201,7 @@ paths:
/extension_server:
post:
tags:
- Extension
- Extension
summary: Download extension from S3 to local folder.
description: ""
operationId: downloadExtension
@@ -230,7 +230,7 @@ paths:
/terminate:
post:
tags:
- Terminate
- Terminate
summary: Terminate Postgres and wait for it to exit
description: ""
operationId: terminate
@@ -369,7 +369,7 @@ components:
moment, when spec was received.
example: "2022-10-12T07:20:50.52Z"
status:
$ref: '#/components/schemas/ComputeStatus'
$ref: "#/components/schemas/ComputeStatus"
last_active:
type: string
description: |
@@ -427,6 +427,28 @@ components:
n_databases:
type: integer
SetRoleGrantsRequest:
type: object
required:
- database
- role
- grants
properties:
database:
type: string
description: Database name.
example: "neondb"
role:
type: string
description: Role name.
example: "neon"
grants:
type: array
items:
type: string
description: List of grants to set.
example: ["SELECT", "INSERT"]
#
# Errors
#

View File

@@ -12,3 +12,11 @@ use serde::Deserialize;
pub struct ConfigurationRequest {
pub spec: ComputeSpec,
}
#[derive(Deserialize, Debug)]
pub struct SetRoleGrantsRequest {
pub database: String,
pub schema: String,
pub privilege: String,
pub role: String,
}

View File

@@ -168,3 +168,8 @@ pub struct InstalledExtension {
pub struct InstalledExtensions {
pub extensions: Vec<InstalledExtension>,
}
#[derive(Clone, Debug, Default, Serialize)]
pub struct SetRoleGrantsResult {
pub extension: String,
}