Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions backend/src/connector/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,20 @@ use crate::{config::EnvConfig, connector::docker::DockerConnector};

pub mod docker;

#[derive(Serialize, Deserialize, Clone, Debug)]
#[derive(Serialize, Deserialize, Clone, Debug, Copy)]
pub enum ConnectorType {
Docker,
}

#[derive(FromRequestParts, Clone)]
#[from_request(via(Extension))]
pub struct PlatformConnection(Arc<dyn Connector>);
pub struct PlatformConnection(Arc<dyn Connector>, ConnectorType);

impl PlatformConnection {
pub fn typ(&self) -> ConnectorType {
self.1
}
}

router_extension!(
async fn connector(self, config: &EnvConfig) -> Self {
Expand All @@ -43,7 +49,7 @@ impl ConnectorType {
ConnectorType::Docker => Arc::new(DockerConnector::new()?),
};

Ok(PlatformConnection(connector))
Ok(PlatformConnection(connector, *self))
}
}

Expand Down
115 changes: 111 additions & 4 deletions backend/src/deployment/postgres.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,135 @@
use std::collections::HashMap;

use axum::{
Json, Router,
extract::FromRequest,
routing::{delete, get, post},
};
use centaurus::error::Result;
use serde::Deserialize;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

use crate::connector::{
Deployment, DeploymentInfo, DeploymentType, PlatformConnection, StorageOptions,
ConnectorType, Deployment, DeploymentInfo, DeploymentType, PlatformConnection, StorageOptions,
};

pub fn router() -> Router {
Router::new()
.route("/info", get(system_info))
.route("/", post(create_deployment))
.route("/", get(list_deployments))
.route("/", delete(remove_deployment))
}

#[derive(Serialize)]
struct SystemInfo {
connector: ConnectorType,
namespaces: Vec<String>,
}

async fn system_info() -> Result<Json<SystemInfo>> {
let info = SystemInfo {
connector: ConnectorType::Docker,
namespaces: vec![],
};

Ok(Json(info))
}

#[derive(FromRequest, Deserialize)]
#[from_request(via(Json))]
struct CreateDeployment {

Check warning on line 41 in backend/src/deployment/postgres.rs

View workflow job for this annotation

GitHub Actions / clippy

backend/src/deployment/postgres.rs#L41

multiple fields are never read
name: String,
storage_mb: u64,
namespace: Option<String>,
version: PostgresVersion,
replicas: u32,
resources: DeploymentResources,
backup: DeploymentBackup,
connection: DeploymentConnection,
monitoring: DeploymentMonitoring,
advanced: DeploymentAdvanced,
}

#[derive(Deserialize)]
struct DeploymentResources {

Check warning on line 54 in backend/src/deployment/postgres.rs

View workflow job for this annotation

GitHub Actions / clippy

backend/src/deployment/postgres.rs#L54

fields `memory_request_mb`, `memory_limit_mb`, `cpu_request_millicores`, and `cpu_limit_millicores` are never read
storage_mb: Option<u64>,
memory_request_mb: u64,
memory_limit_mb: u64,
cpu_request_millicores: u64,
cpu_limit_millicores: u64,
}

#[derive(Deserialize)]
#[serde(rename_all = "snake_case", tag = "enabled")]
enum DeploymentBackup {
Disabled,
Enabled {

Check warning on line 66 in backend/src/deployment/postgres.rs

View workflow job for this annotation

GitHub Actions / clippy

backend/src/deployment/postgres.rs#L66

fields `location`, `schedule`, and `retention_days` are never read
location: String,
schedule: String,
retention_days: u32,
},
}

#[derive(Deserialize)]
#[serde(rename_all = "snake_case", tag = "ssl_enabled")]
enum DeploymentConnection {
Disabled {

Check warning on line 76 in backend/src/deployment/postgres.rs

View workflow job for this annotation

GitHub Actions / clippy

backend/src/deployment/postgres.rs#L76

field `external_access` is never read
external_access: bool,
},
Enabled {

Check warning on line 79 in backend/src/deployment/postgres.rs

View workflow job for this annotation

GitHub Actions / clippy

backend/src/deployment/postgres.rs#L79

fields `external_access`, `ssl_cert`, `ssl_key`, and `ssl_ca` are never read
external_access: bool,
ssl_cert: SslFile,
ssl_key: SslFile,
ssl_ca: SslCa,
},
}

#[derive(Deserialize)]
#[serde(rename_all = "snake_case", tag = "ca_enabled")]
enum SslCa {
Disabled,
Enabled { ssl_ca: SslFile },

Check warning on line 91 in backend/src/deployment/postgres.rs

View workflow job for this annotation

GitHub Actions / clippy

backend/src/deployment/postgres.rs#L91

field `ssl_ca` is never read
}

#[derive(Deserialize)]
#[serde(tag = "type")]
enum SslFile {
Auto,
Text { content: String },

Check warning on line 98 in backend/src/deployment/postgres.rs

View workflow job for this annotation

GitHub Actions / clippy

backend/src/deployment/postgres.rs#L98

field `content` is never read
Reference { ref_name: String, ref_key: String },

Check warning on line 99 in backend/src/deployment/postgres.rs

View workflow job for this annotation

GitHub Actions / clippy

backend/src/deployment/postgres.rs#L99

fields `ref_name` and `ref_key` are never read
HostFilePath { host_file_path: String },

Check warning on line 100 in backend/src/deployment/postgres.rs

View workflow job for this annotation

GitHub Actions / clippy

backend/src/deployment/postgres.rs#L100

field `host_file_path` is never read
}

#[derive(Deserialize)]
#[serde(rename_all = "snake_case", tag = "enabled")]
enum DeploymentMonitoring {
Disabled,
Enabled {

Check warning on line 107 in backend/src/deployment/postgres.rs

View workflow job for this annotation

GitHub Actions / clippy

backend/src/deployment/postgres.rs#L107

fields `external_access` and `deploy_monitoring` are never read
external_access: bool,
deploy_monitoring: bool,
},
}

#[derive(Deserialize)]
struct DeploymentAdvanced {

Check warning on line 114 in backend/src/deployment/postgres.rs

View workflow job for this annotation

GitHub Actions / clippy

backend/src/deployment/postgres.rs#L114

fields `allow_alter_system` and `extra_params` are never read
allow_alter_system: bool,
extra_params: HashMap<String, String>,
}

#[derive(Deserialize)]
enum PostgresVersion {
#[serde(rename = "13")]
V13,
#[serde(rename = "14")]
V14,
#[serde(rename = "15")]
V15,
#[serde(rename = "16")]
V16,
#[serde(rename = "17")]
V17,
#[serde(rename = "18")]
V18,
}

async fn create_deployment(conn: PlatformConnection, payload: CreateDeployment) -> Result<()> {
Expand All @@ -31,7 +138,7 @@
uuid: Uuid::new_v4(),
typ: DeploymentType::Postgres,
storage: StorageOptions {
size_mb: payload.storage_mb,
size_mb: payload.resources.storage_mb.unwrap_or(1000),
},
};

Expand Down
81 changes: 81 additions & 0 deletions docs/deployment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Deployment

## Configuration Options

General Options:

- Name: The display name for the deployment.
- Namespace: The Kubernetes namespace where the deployment will be created. (only Kubernetes)
- Database Version: The version of postgres to deploy.
- Replicas: The number of instances to deploy.

Resource Options:

- Storage Size: The amount of storage allocated for the deployment per instance (in MB). (only Kubernetes)
- Storage Class: The storage class to use for the deployment. (only Kubernetes)
- CPU Requests: The amount of CPU requested for each instance (in millicores).
- CPU Limits: The maximum amount of CPU allowed for each instance (in millicores).
- Memory Requests: The amount of memory requested for each instance (in MB).
- Memory Limits: The maximum amount of memory allowed for each instance (in MB).

Backup Options:

- Backup Name: The name of the backup configuration.
- Backup Schedule: The cron schedule for automatic backups.
- Backup Retention: The number of backups to retain.
- Backup Location: The location where backups will be stored.

Connection Options:

- External Access: Enable or disable external access to the deployment.
- SSL Configuration: Configure SSL settings for secure connections.

Monitoring Options:

- Toggle: Enable or disable monitoring for the deployment.
- Allow external access: Enable or disable external access to the monitoring endpoints.
- Deploy monitoring resources: Choose whether to deploy monitoring resources alongside the database deployment. (only Kubernetes)

Advanced Options:

- Allow Alter System: Enable or disable the ability to use ALTER SYSTEM commands.
- Extra Database Engine Parameters: Additional parameters to configure the database engine.

Hardcoded Parameters (required for replication):

- wal_level = replica
- hot_standby = on
- max_wal_senders = replica count \* 1.1 (primary only)
- max_replication_slots = replica count \* 1.1 (primary only)
- primary_conninfo = use environment variables (replica only)
- primary_slot_name = some name (replica only)
- sync_replication_slots = true (replica only)

storage ref:
docker: - host file path (must exist) - file upload
kubernetes: - file upload - config map ref - secret ref

!
ssl
ssl_ca_file (storage ref)
ssl_cert_file (storage ref)
ssl_key_file (storage ref)
wal_level = replica (restart)
allow_alter_system (default to off)

primary:
hot_standby = on (restart)

sending:
max_wal_senders = replica count + small number like 10% (restart)
max_replication_slots = replica count + small number like 10% (restart)

standby:
primary_conninfo (use env)
primary_slot_name (just some name)
sync_replication_slots = true
hot_standby = on (restart)

stats TODO (replication lag monitoring)
archiving for replication TODO
failover TODO
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"@types/d3-scale": "^4.0.9",
"@types/d3-shape": "^3.1.7",
"bits-ui": "^2.11.0",
"positron-components": "1.10.0",
"positron-components": "1.12.1",
"svelte": "5.39.9",
"svelte-check": "4.3.2",
"tailwind-merge": "^3.3.1",
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

@custom-variant dark (&:is(.dark *));

@source '../../node_modules/positron-components';
@source '../node_modules/positron-components';

/*
The default border color has changed to `currentColor` in Tailwind CSS v4,
Expand Down
108 changes: 107 additions & 1 deletion frontend/src/lib/backend/postgres.svelte.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,92 @@
import { delete_, get, post, ResponseType } from 'positron-components/backend';
import type {
CertSource,
PostgresVersion
} from '../../routes/deployments/postgres/create/schema.svelte';

export interface CreateDeployment {
name: string;
storage_mb: number;
namespace?: string;
version: PostgresVersion;
replicas: number;
resources: CreateDeploymentResources;
backup: CreateDeploymentBackup;
connection: CreateDeploymentConnection;
monitoring: CreateDeploymentMonitoring;
advanced: CreateDeploymentAdvanced;
}

export interface CreateDeploymentResources {
storage_mb?: number;
memory_request_mb: number;
memory_limit_mb: number;
cpu_request_millicores: number;
cpu_limit_millicores: number;
}

export type CreateDeploymentBackup =
| {
enabled: 'disabled';
}
| {
enabled: 'enabled';
schedule: string;
retention_days: number;
storage_location: string;
};

export type CreateDeploymentConnection = {
external_access: boolean;
} & (
| {
ssl_enabled: 'disabled';
}
| {
ssl_enabled: 'enabled';
ssl_cert: SslFile;
ssl_key: SslFile;
ssl_ca:
| {
ca_enabled: 'disabled';
}
| {
ca_enabled: 'enabled';
ssl_ca: SslFile;
};
}
);

export type SslFile =
| {
type: CertSource.Auto;
}
| {
type: CertSource.Text;
content: string;
}
| {
type: CertSource.Reference;
ref_name: string;
ref_key: string;
}
| {
type: CertSource.HostFilePath;
host_file_path: string;
};

export type CreateDeploymentMonitoring =
| {
enabled: 'disabled';
}
| {
enabled: 'enabled';
external_access: boolean;
deploy_monitoring: boolean;
};

export interface CreateDeploymentAdvanced {
allow_alter_system: boolean;
extra_params: Record<string, string>;
}

export const create_deployment = async (payload: CreateDeployment) => {
Expand Down Expand Up @@ -40,3 +124,25 @@ export const delete_deployment = async (uuid: string) => {

return res;
};

export enum ConnectorType {
Docker = 'Docker',
Kubernetes = 'Kubernetes'
}

export interface SystemInfo {
connector: ConnectorType;
namespaces: string[];
backup_locations: string[];
}

export const system_info = async () => {
let res = await get<SystemInfo>(
'/api/deployment/postgres/info',
ResponseType.Json
);

if (typeof res === 'object') {
return res;
}
};
Loading
Loading